diff options
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/clock.c | 77 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/soc.c | 8 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx7ulp/clock.h | 3 |
3 files changed, 88 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/mx7ulp/clock.c b/arch/arm/cpu/armv7/mx7ulp/clock.c index 0f3e2b3..6246ef5 100644 --- a/arch/arm/cpu/armv7/mx7ulp/clock.c +++ b/arch/arm/cpu/armv7/mx7ulp/clock.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -308,6 +309,82 @@ void hab_caam_clock_enable(unsigned char enable) } #endif +void enable_mipi_dsi_clk(unsigned char enable) +{ + if (enable) { + pcc_clock_enable(PER_CLK_DSI, false); + + /* mipi dsi escape clock range is 40-80Mhz, we expect to set it to about 60 Mhz + * To avoid PCD issue, we select parent clock with lowest frequency + * NIC1_CLK = 1584000khz, frac = 1, div = 5, output = 63.360Mhz + */ + pcc_clock_sel(PER_CLK_DSI, SCG_NIC1_CLK); + pcc_clock_div_config(PER_CLK_DSI, 1, 5); + + pcc_clock_enable(PER_CLK_DSI, true); + } else { + pcc_clock_enable(PER_CLK_DSI, false); + } +} + +void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq_in_khz) +{ + /* Scan the parent clock to find best fit clock, which should generate actual frequence >= freq */ + u8 pcd, best_pcd = 0; + u32 parent, frac, rate, parent_rate; + u32 best_parent = 0, best_frac = 0, best = 0; + + static enum scg_clk clksrc_plat[] = { + SCG_NIC1_BUS_CLK, + SCG_NIC1_CLK, + SCG_DDR_CLK, + SCG_APLL_PFD2_CLK, + SCG_APLL_PFD1_CLK, + SCG_APLL_PFD0_CLK, + USB_PLL_OUT, + }; + + pcc_clock_enable(PER_CLK_LCDIF, false); + + for (parent = 0; parent < ARRAY_SIZE(clksrc_plat); parent++) { + parent_rate = scg_clk_get_rate(clksrc_plat[parent]); + if (!parent_rate) + continue; + + parent_rate = parent_rate / 1000; /* Change to khz*/ + + for (pcd = 0; pcd < 8; pcd++) { + for (frac = 0; frac < 2; frac++) { + if (pcd == 0 && frac == 1) + continue; + + rate = parent_rate * (frac + 1) / (pcd + 1); + if (rate < freq_in_khz) + continue; + + if (best == 0 || rate < best) { + best = rate; + best_parent = parent; + best_frac = frac; + best_pcd = pcd; + } + } + } + } + + if (best == 0) { + printf("Can't find parent clock for LCDIF, target freq: %u\n", freq_in_khz); + return; + } + + debug("LCD target rate %ukhz, best rate %ukhz, frac %u, pcd %u, best_parent %u\n", + freq_in_khz, best, best_frac, best_pcd, best_parent); + + pcc_clock_sel(PER_CLK_LCDIF, clksrc_plat[best_parent]); + pcc_clock_div_config(PER_CLK_LCDIF, best_frac, best_pcd + 1); + pcc_clock_enable(PER_CLK_LCDIF, true); +} + /* * Dump some core clockes. */ diff --git a/arch/arm/cpu/armv7/mx7ulp/soc.c b/arch/arm/cpu/armv7/mx7ulp/soc.c index 711fc75..cdd4d42 100644 --- a/arch/arm/cpu/armv7/mx7ulp/soc.c +++ b/arch/arm/cpu/armv7/mx7ulp/soc.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -327,6 +328,13 @@ u32 get_imx_reset_cause(void) return reset_cause; } +void arch_preboot_os(void) +{ +#if defined(CONFIG_VIDEO_MXS) + lcdif_power_down(); +#endif +} + #ifdef CONFIG_ENV_IS_IN_MMC __weak int board_mmc_get_env_dev(int devno) { diff --git a/arch/arm/include/asm/arch-mx7ulp/clock.h b/arch/arm/include/asm/arch-mx7ulp/clock.h index 92d8b21..7a2cb78 100644 --- a/arch/arm/include/asm/arch-mx7ulp/clock.h +++ b/arch/arm/include/asm/arch-mx7ulp/clock.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0+ */ @@ -40,6 +41,8 @@ void enable_usboh3_clk(unsigned char enable); #ifdef CONFIG_SECURE_BOOT void hab_caam_clock_enable(unsigned char enable); #endif +void enable_mipi_dsi_clk(unsigned char enable); +void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq_in_khz); void init_clk_usdhc(u32 index); void clock_init(void); #endif |