summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7/omap3/clock.c
diff options
context:
space:
mode:
authorNaumann Andreas <ANaumann@ultratronik.de>2013-07-09 09:43:17 +0200
committerTom Rini <trini@ti.com>2013-08-15 09:09:29 -0400
commita704a6d615179a25f556c99d31cbc4ee366ffb54 (patch)
treef3711d3ae6ca2da11162de7b10b93c8efec43602 /arch/arm/cpu/armv7/omap3/clock.c
parent802b3c7c1826018530acc8a7b8fe83f11614c937 (diff)
downloadu-boot-imx-a704a6d615179a25f556c99d31cbc4ee366ffb54.zip
u-boot-imx-a704a6d615179a25f556c99d31cbc4ee366ffb54.tar.gz
u-boot-imx-a704a6d615179a25f556c99d31cbc4ee366ffb54.tar.bz2
ARM: omap3: Implement dpll5 (HSUSB clk) workaround for OMAP36xx/AM/DM37xx according to errata sprz318e.
In chapter 'Advisory 2.1 USB Host Clock Drift Causes USB Spec Non-compliance in Certain Configurations' of the TI Errata it is recommended to use certain div/mult values for the DPLL5 clock setup. So far u-boot used the old 34xx values, so I added the errata recommended values specificly for 36xx init only. Also, the FSEL registers exist no longer, so removed them from init. Tested this on a AM3703 board with 19.2MHz oscillator, which previously couldnt lock the dpll5 (kernel complained). As a consequence the EHCI USB port wasnt usable in U-Boot and kernel. With this patch, kernel panics disappear and USB working fine in u-boot and kernel. Signed-off-by: Andreas Naumann <anaumann@ultratronik.de> [trini: Add extern to <asm/arch-omap3/clock.h> Signed-off-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'arch/arm/cpu/armv7/omap3/clock.c')
-rw-r--r--arch/arm/cpu/armv7/omap3/clock.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv7/omap3/clock.c b/arch/arm/cpu/armv7/omap3/clock.c
index 3acbc9c..e903ed9 100644
--- a/arch/arm/cpu/armv7/omap3/clock.c
+++ b/arch/arm/cpu/armv7/omap3/clock.c
@@ -478,6 +478,24 @@ static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
}
+static void dpll5_init_36xx(u32 sil_index, u32 clk_index)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ dpll_param *ptr = (dpll_param *) get_36x_per2_dpll_param();
+
+ /* Moving it to the right sysclk base */
+ ptr = ptr + clk_index;
+
+ /* PER2 DPLL (DPLL5) */
+ sr32(&prcm_base->clken2_pll, 0, 3, PLL_STOP);
+ wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
+ sr32(&prcm_base->clksel5_pll, 0, 5, ptr->m2); /* set M2 (usbtll_fck) */
+ sr32(&prcm_base->clksel4_pll, 8, 11, ptr->m); /* set m (11-bit multiplier) */
+ sr32(&prcm_base->clksel4_pll, 0, 7, ptr->n); /* set n (7-bit divider)*/
+ sr32(&prcm_base->clken2_pll, 0, 3, PLL_LOCK); /* lock mode */
+ wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
+}
+
static void mpu_init_36xx(u32 sil_index, u32 clk_index)
{
struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
@@ -582,7 +600,7 @@ void prcm_init(void)
dpll3_init_36xx(0, clk_index);
dpll4_init_36xx(0, clk_index);
- dpll5_init_34xx(0, clk_index);
+ dpll5_init_36xx(0, clk_index);
iva_init_36xx(0, clk_index);
mpu_init_36xx(0, clk_index);