MLK-13929-5 mx7ulp: Update clock and SoC functions for video
authorYe Li <ye.li@nxp.com>
Wed, 15 Feb 2017 09:38:55 +0000 (17:38 +0800)
committerYe Li <ye.li@nxp.com>
Fri, 24 May 2019 11:28:39 +0000 (04:28 -0700)
Add the clocks functions for enabling LCDIF and DSI clocks.
Also add the arch_preboot_os to disable the video before enter into
the kernel.

Signed-off-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit a783799017a929f9918c9c5981fe3a7a25cd8125)
(cherry picked from commit fce3f6e59f6ae5a171bbb6581420712c4aaa14c3)
(cherry picked from commit 60d57156df1bbbd35c06ec3c9dfcf753c4280e39)

arch/arm/include/asm/arch-mx7ulp/clock.h
arch/arm/mach-imx/mx7ulp/clock.c
arch/arm/mach-imx/mx7ulp/soc.c

index eb02a20..13fc06c 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
  */
 
 #ifndef _ASM_ARCH_CLOCK_H
@@ -36,6 +37,8 @@ void enable_ocotp_clk(unsigned char enable);
 #ifdef CONFIG_USB_EHCI_HCD
 void enable_usboh3_clk(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);
 void hab_caam_clock_enable(unsigned char enable);
index 0a0165c..31eb5da 100644 (file)
@@ -322,6 +322,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);
+}
+
 #ifndef CONFIG_SPL_BUILD
 /*
  * Dump some core clockes.
index bcd7e45..019aa87 100644 (file)
@@ -280,6 +280,13 @@ static char *get_reset_cause(char *ret)
        return ret;
 }
 
+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)
 {