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>
master
Naumann Andreas 12 years ago committed by Tom Rini
parent 802b3c7c18
commit a704a6d615
  1. 20
      arch/arm/cpu/armv7/omap3/clock.c
  2. 18
      arch/arm/cpu/armv7/omap3/lowlevel_init.S
  3. 1
      arch/arm/include/asm/arch-omap3/clock.h
  4. 22
      arch/arm/include/asm/arch-omap3/clocks_omap3.h

@ -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);

@ -464,6 +464,19 @@ per_36x_dpll_param:
.word 26000, 432, 12, 9, 16, 9, 4, 3, 1
.word 38400, 360, 15, 9, 16, 5, 4, 3, 1
per2_36x_dpll_param:
/* 12MHz */
.word PER2_36XX_M_12, PER2_36XX_N_12, 0, PER2_36XX_M2_12
/* 13MHz */
.word PER2_36XX_M_13, PER2_36XX_N_13, 0, PER2_36XX_M2_13
/* 19.2MHz */
.word PER2_36XX_M_19P2, PER2_36XX_N_19P2, 0, PER2_36XX_M2_19P2
/* 26MHz */
.word PER2_36XX_M_26, PER2_36XX_N_26, 0, PER2_36XX_M2_26
/* 38.4MHz */
.word PER2_36XX_M_38P4, PER2_36XX_N_38P4, 0, PER2_36XX_M2_38P4
ENTRY(get_36x_mpu_dpll_param)
adr r0, mpu_36x_dpll_param
mov pc, lr
@ -483,3 +496,8 @@ ENTRY(get_36x_per_dpll_param)
adr r0, per_36x_dpll_param
mov pc, lr
ENDPROC(get_36x_per_dpll_param)
ENTRY(get_36x_per2_dpll_param)
adr r0, per2_36x_dpll_param
mov pc, lr
ENDPROC(get_36x_per2_dpll_param)

@ -61,6 +61,7 @@ extern dpll_param *get_36x_mpu_dpll_param(void);
extern dpll_param *get_36x_iva_dpll_param(void);
extern dpll_param *get_36x_core_dpll_param(void);
extern dpll_param *get_36x_per_dpll_param(void);
extern dpll_param *get_36x_per2_dpll_param(void);
extern void *_end_vect, *_start;

@ -323,4 +323,26 @@
#define PER_36XX_FSEL_38P4 0x07
#define PER_36XX_M2_38P4 0x09
/* 36XX PER2 DPLL */
#define PER2_36XX_M_12 0x50
#define PER2_36XX_N_12 0x00
#define PER2_36XX_M2_12 0x08
#define PER2_36XX_M_13 0x1BB
#define PER2_36XX_N_13 0x05
#define PER2_36XX_M2_13 0x08
#define PER2_36XX_M_19P2 0x32
#define PER2_36XX_N_19P2 0x00
#define PER2_36XX_M2_19P2 0x08
#define PER2_36XX_M_26 0x1BB
#define PER2_36XX_N_26 0x0B
#define PER2_36XX_M2_26 0x08
#define PER2_36XX_M_38P4 0x19
#define PER2_36XX_N_38P4 0x00
#define PER2_36XX_M2_38P4 0x08
#endif /* endif _CLOCKS_OMAP3_H_ */

Loading…
Cancel
Save