diff options
author | Hans de Goede <hdegoede@redhat.com> | 2015-08-08 12:05:35 (GMT) |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2015-08-14 06:37:39 (GMT) |
commit | 55ea98d8b1a1aacd3af5978a504d956d7a85ffed (patch) | |
tree | 2213b315237b9d347c0bb675b8559289df3aee28 /arch/arm/cpu/armv7 | |
parent | 49043cbad1db2e97daffe54d5ee32103c11dd4fd (diff) | |
download | u-boot-55ea98d8b1a1aacd3af5978a504d956d7a85ffed.tar.xz |
sun6i: clock: Add support for the mipi pll
Add support for the mipi pll, this is necessary for getting higher dotclocks
with lcd panels.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 1d6f839..3ab3b31 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -170,6 +170,47 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) udelay(5500); } +#ifdef CONFIG_MACH_SUN6I +void clock_set_mipi_pll(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + unsigned int k, m, n, value, diff; + unsigned best_k = 0, best_m = 0, best_n = 0, best_diff = 0xffffffff; + unsigned int src = clock_get_pll3(); + + /* All calculations are in KHz to avoid overflows */ + clk /= 1000; + src /= 1000; + + /* Pick the closest lower clock */ + for (k = 1; k <= 4; k++) { + for (m = 1; m <= 16; m++) { + for (n = 1; n <= 16; n++) { + value = src * n * k / m; + if (value > clk) + continue; + + diff = clk - value; + if (diff < best_diff) { + best_diff = diff; + best_k = k; + best_m = m; + best_n = n; + } + if (diff == 0) + goto done; + } + } + } + +done: + writel(CCM_MIPI_PLL_CTRL_EN | CCM_MIPI_PLL_CTRL_LDO_EN | + CCM_MIPI_PLL_CTRL_N(best_n) | CCM_MIPI_PLL_CTRL_K(best_k) | + CCM_MIPI_PLL_CTRL_M(best_m), &ccm->mipi_pll_cfg); +} +#endif + #ifdef CONFIG_MACH_SUN8I_A33 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) { @@ -210,6 +251,20 @@ unsigned int clock_get_pll6(void) return 24000000 * n * k / 2; } +unsigned int clock_get_mipi_pll(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + uint32_t rval = readl(&ccm->mipi_pll_cfg); + unsigned int n = ((rval & CCM_MIPI_PLL_CTRL_N_MASK) >> CCM_MIPI_PLL_CTRL_N_SHIFT) + 1; + unsigned int k = ((rval & CCM_MIPI_PLL_CTRL_K_MASK) >> CCM_MIPI_PLL_CTRL_K_SHIFT) + 1; + unsigned int m = ((rval & CCM_MIPI_PLL_CTRL_M_MASK) >> CCM_MIPI_PLL_CTRL_M_SHIFT) + 1; + unsigned int src = clock_get_pll3(); + + /* Multiply by 1000 after dividing by m to avoid integer overflows */ + return ((src / 1000) * n * k / m) * 1000; +} + void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz) { int pll = clock_get_pll6() * 2; |