2 * SoC-specific lowlevel code for tms320dm365 and similar chips
3 * Actually used for booting from NAND with nand_spl.
6 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
8 * SPDX-License-Identifier: GPL-2.0+
14 #include <asm/ti-common/davinci_nand.h>
15 #include <asm/arch/dm365_lowlevel.h>
16 #include <asm/arch/hardware.h>
18 void dm365_waitloop(unsigned long loopcnt
)
22 for (i
= 0; i
< loopcnt
; i
++)
26 int dm365_pll1_init(unsigned long pllmult
, unsigned long prediv
)
28 unsigned int clksrc
= 0x0;
30 /* Power up the PLL */
31 clrbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_PLLPWRDN
);
33 clrbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_RES_9
);
34 setbits_le32(&dv_pll0_regs
->pllctl
,
35 clksrc
<< PLLCTL_CLOCK_MODE_SHIFT
);
38 * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled
41 clrbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_PLLENSRC
);
43 /* Set PLLEN=0 => PLL BYPASS MODE */
44 clrbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_PLLEN
);
48 /* PLLRST=1(reset assert) */
49 setbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_PLLRST
);
53 /*Bring PLL out of Reset*/
54 clrbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_PLLRST
);
56 /* Program the Multiper and Pre-Divider for PLL1 */
57 writel(pllmult
, &dv_pll0_regs
->pllm
);
58 writel(prediv
, &dv_pll0_regs
->prediv
);
60 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */
61 writel(PLLSECCTL_STOPMODE
| PLLSECCTL_TENABLEDIV
| PLLSECCTL_TENABLE
|
62 PLLSECCTL_TINITZ
, &dv_pll0_regs
->secctl
);
63 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */
64 writel(PLLSECCTL_STOPMODE
| PLLSECCTL_TENABLEDIV
| PLLSECCTL_TENABLE
,
65 &dv_pll0_regs
->secctl
);
66 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */
67 writel(PLLSECCTL_STOPMODE
, &dv_pll0_regs
->secctl
);
68 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */
69 writel(PLLSECCTL_STOPMODE
| PLLSECCTL_TINITZ
, &dv_pll0_regs
->secctl
);
71 /* Program the PostDiv for PLL1 */
72 writel(PLL_POSTDEN
, &dv_pll0_regs
->postdiv
);
74 /* Post divider setting for PLL1 */
75 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV1
, &dv_pll0_regs
->plldiv1
);
76 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV2
, &dv_pll0_regs
->plldiv2
);
77 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV3
, &dv_pll0_regs
->plldiv3
);
78 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV4
, &dv_pll0_regs
->plldiv4
);
79 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV5
, &dv_pll0_regs
->plldiv5
);
80 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV6
, &dv_pll0_regs
->plldiv6
);
81 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV7
, &dv_pll0_regs
->plldiv7
);
82 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV8
, &dv_pll0_regs
->plldiv8
);
83 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV9
, &dv_pll0_regs
->plldiv9
);
87 /* Set the GOSET bit */
88 writel(PLLCMD_GOSET
, &dv_pll0_regs
->pllcmd
); /* Go */
92 /* Wait for PLL to LOCK */
93 while (!((readl(&dv_sys_module_regs
->pll0_config
) & PLL0_LOCK
)
97 /* Enable the PLL Bit of PLLCTL*/
98 setbits_le32(&dv_pll0_regs
->pllctl
, PLLCTL_PLLEN
);
103 int dm365_pll2_init(unsigned long pllm
, unsigned long prediv
)
105 unsigned int clksrc
= 0x0;
107 /* Power up the PLL*/
108 clrbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_PLLPWRDN
);
111 * Select the Clock Mode as Onchip Oscilator or External Clock on
113 * VDB has input on MXI pin
115 clrbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_RES_9
);
116 setbits_le32(&dv_pll1_regs
->pllctl
,
117 clksrc
<< PLLCTL_CLOCK_MODE_SHIFT
);
120 * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled
123 clrbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_PLLENSRC
);
125 /* Set PLLEN=0 => PLL BYPASS MODE */
126 clrbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_PLLEN
);
130 /* PLLRST=1(reset assert) */
131 setbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_PLLRST
);
135 /* Bring PLL out of Reset */
136 clrbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_PLLRST
);
138 /* Program the Multiper and Pre-Divider for PLL2 */
139 writel(pllm
, &dv_pll1_regs
->pllm
);
140 writel(prediv
, &dv_pll1_regs
->prediv
);
142 writel(PLL_POSTDEN
, &dv_pll1_regs
->postdiv
);
144 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */
145 writel(PLLSECCTL_STOPMODE
| PLLSECCTL_TENABLEDIV
| PLLSECCTL_TENABLE
|
146 PLLSECCTL_TINITZ
, &dv_pll1_regs
->secctl
);
147 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */
148 writel(PLLSECCTL_STOPMODE
| PLLSECCTL_TENABLEDIV
| PLLSECCTL_TENABLE
,
149 &dv_pll1_regs
->secctl
);
150 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */
151 writel(PLLSECCTL_STOPMODE
, &dv_pll1_regs
->secctl
);
152 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */
153 writel(PLLSECCTL_STOPMODE
| PLLSECCTL_TINITZ
, &dv_pll1_regs
->secctl
);
155 /* Post divider setting for PLL2 */
156 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV1
, &dv_pll1_regs
->plldiv1
);
157 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV2
, &dv_pll1_regs
->plldiv2
);
158 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV3
, &dv_pll1_regs
->plldiv3
);
159 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV4
, &dv_pll1_regs
->plldiv4
);
160 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV5
, &dv_pll1_regs
->plldiv5
);
162 /* GoCmd for PostDivider to take effect */
163 writel(PLLCMD_GOSET
, &dv_pll1_regs
->pllcmd
);
167 /* Wait for PLL to LOCK */
168 while (!((readl(&dv_sys_module_regs
->pll1_config
) & PLL1_LOCK
)
172 dm365_waitloop(4100);
174 /* Enable the PLL2 */
175 setbits_le32(&dv_pll1_regs
->pllctl
, PLLCTL_PLLEN
);
177 /* do this after PLL's have been set up */
178 writel(CONFIG_SYS_DM36x_PERI_CLK_CTRL
,
179 &dv_sys_module_regs
->peri_clkctl
);
184 int dm365_ddr_setup(void)
186 lpsc_on(DAVINCI_LPSC_DDR_EMIF
);
187 clrbits_le32(&dv_sys_module_regs
->vtpiocr
,
188 VPTIO_IOPWRDN
| VPTIO_CLRZ
| VPTIO_LOCK
| VPTIO_PWRDN
);
190 /* Set bit CLRZ (bit 13) */
191 setbits_le32(&dv_sys_module_regs
->vtpiocr
, VPTIO_CLRZ
);
193 /* Check VTP READY Status */
194 while (!(readl(&dv_sys_module_regs
->vtpiocr
) & VPTIO_RDY
))
197 /* Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) */
198 setbits_le32(&dv_sys_module_regs
->vtpiocr
, VPTIO_IOPWRDN
);
200 /* Set bit LOCK(bit7) */
201 setbits_le32(&dv_sys_module_regs
->vtpiocr
, VPTIO_LOCK
);
204 * Powerdown VTP as it is locked (bit 6)
205 * Set bit VTP_IOPWRDWN bit 14 for DDR input buffers)
207 setbits_le32(&dv_sys_module_regs
->vtpiocr
,
208 VPTIO_IOPWRDN
| VPTIO_PWRDN
);
210 /* Wait for calibration to complete */
213 /* Set the DDR2 to synreset, then enable it again */
214 lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF
);
215 lpsc_on(DAVINCI_LPSC_DDR_EMIF
);
217 writel(CONFIG_SYS_DM36x_DDR2_DDRPHYCR
, &dv_ddr2_regs_ctrl
->ddrphycr
);
219 /* Program SDRAM Bank Config Register */
220 writel((CONFIG_SYS_DM36x_DDR2_SDBCR
| DV_DDR_BOOTUNLOCK
),
221 &dv_ddr2_regs_ctrl
->sdbcr
);
222 writel((CONFIG_SYS_DM36x_DDR2_SDBCR
| DV_DDR_TIMUNLOCK
),
223 &dv_ddr2_regs_ctrl
->sdbcr
);
225 /* Program SDRAM Timing Control Register1 */
226 writel(CONFIG_SYS_DM36x_DDR2_SDTIMR
, &dv_ddr2_regs_ctrl
->sdtimr
);
227 /* Program SDRAM Timing Control Register2 */
228 writel(CONFIG_SYS_DM36x_DDR2_SDTIMR2
, &dv_ddr2_regs_ctrl
->sdtimr2
);
230 writel(CONFIG_SYS_DM36x_DDR2_PBBPR
, &dv_ddr2_regs_ctrl
->pbbpr
);
232 writel(CONFIG_SYS_DM36x_DDR2_SDBCR
, &dv_ddr2_regs_ctrl
->sdbcr
);
234 /* Program SDRAM Refresh Control Register */
235 writel(CONFIG_SYS_DM36x_DDR2_SDRCR
, &dv_ddr2_regs_ctrl
->sdrcr
);
237 lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF
);
238 lpsc_on(DAVINCI_LPSC_DDR_EMIF
);
243 static void dm365_vpss_sync_reset(void)
245 unsigned int PdNum
= 0;
248 setbits_le32(&dv_sys_module_regs
->vpss_clkctl
,
249 VPSS_CLK_CTL_VPSS_CLKMD
);
251 /* LPSC SyncReset DDR Clock Enable */
252 writel(((readl(&dv_psc_regs
->mdctl
[DAVINCI_LPSC_VPSSMASTER
]) &
253 ~PSC_MD_STATE_MSK
) | PSC_SYNCRESET
),
254 &dv_psc_regs
->mdctl
[DAVINCI_LPSC_VPSSMASTER
]);
256 writel((1 << PdNum
), &dv_psc_regs
->ptcmd
);
258 while (!(((readl(&dv_psc_regs
->ptstat
) >> PdNum
) & PSC_GOSTAT
) == 0))
260 while (!((readl(&dv_psc_regs
->mdstat
[DAVINCI_LPSC_VPSSMASTER
]) &
261 PSC_MD_STATE_MSK
) == PSC_SYNCRESET
))
265 static void dm365_por_reset(void)
267 struct davinci_timer
*wdog
=
268 (struct davinci_timer
*)DAVINCI_WDOG_BASE
;
270 if (readl(&dv_pll0_regs
->rstype
) &
271 (PLL_RSTYPE_POR
| PLL_RSTYPE_XWRST
)) {
272 dm365_vpss_sync_reset();
274 writel(DV_TMPBUF_VAL
, TMPBUF
);
275 setbits_le32(TMPSTATUS
, FLAG_PORRST
);
276 writel(DV_WDT_ENABLE_SYS_RESET
, &wdog
->na1
);
277 writel(DV_WDT_TRIGGER_SYS_RESET
, &wdog
->na2
);
283 static void dm365_wdt_reset(void)
285 struct davinci_timer
*wdog
=
286 (struct davinci_timer
*)DAVINCI_WDOG_BASE
;
288 if (readl(TMPBUF
) != DV_TMPBUF_VAL
) {
289 writel(DV_TMPBUF_VAL
, TMPBUF
);
290 setbits_le32(TMPSTATUS
, FLAG_PORRST
);
291 setbits_le32(TMPSTATUS
, FLAG_FLGOFF
);
295 dm365_vpss_sync_reset();
297 writel(DV_WDT_ENABLE_SYS_RESET
, &wdog
->na1
);
298 writel(DV_WDT_TRIGGER_SYS_RESET
, &wdog
->na2
);
304 static void dm365_wdt_flag_on(void)
307 clrbits_le32(&dv_sys_module_regs
->vpss_clkctl
,
308 VPSS_CLK_CTL_VPSS_CLKMD
);
310 setbits_le32(TMPSTATUS
, FLAG_FLGON
);
313 void dm365_psc_init(void)
316 unsigned char lpsc_start
;
317 unsigned char lpsc_end
, lpscgroup
, lpscmin
, lpscmax
;
318 unsigned int PdNum
= 0;
323 for (lpscgroup
= lpscmin
; lpscgroup
<= lpscmax
; lpscgroup
++) {
324 if (lpscgroup
== 0) {
325 /* Enabling LPSC 3 to 28 SCR first */
326 lpsc_start
= DAVINCI_LPSC_VPSSMSTR
;
327 lpsc_end
= DAVINCI_LPSC_TIMER1
;
328 } else if (lpscgroup
== 1) { /* Skip locked LPSCs [29-37] */
329 lpsc_start
= DAVINCI_LPSC_CFG5
;
330 lpsc_end
= DAVINCI_LPSC_VPSSMASTER
;
332 lpsc_start
= DAVINCI_LPSC_MJCP
;
333 lpsc_end
= DAVINCI_LPSC_HDVICP
;
336 /* NEXT=0x3, Enable LPSC's */
337 for (i
= lpsc_start
; i
<= lpsc_end
; i
++)
338 setbits_le32(&dv_psc_regs
->mdctl
[i
], PSC_ENABLE
);
341 * Program goctl to start transition sequence for LPSCs
342 * CSL_PSC_0_REGS->PTCMD = (1<<PdNum); Kick off Power
345 writel((1 << PdNum
), &dv_psc_regs
->ptcmd
);
348 * Wait for GOSTAT = NO TRANSITION from PSC for Powerdomain 0
350 while (!(((readl(&dv_psc_regs
->ptstat
) >> PdNum
) & PSC_GOSTAT
)
354 /* Wait for MODSTAT = ENABLE from LPSC's */
355 for (i
= lpsc_start
; i
<= lpsc_end
; i
++)
356 while (!((readl(&dv_psc_regs
->mdstat
[i
]) &
357 PSC_MD_STATE_MSK
) == PSC_ENABLE
))
362 static void dm365_emif_init(void)
364 writel(CONFIG_SYS_DM36x_AWCCR
, &davinci_emif_regs
->awccr
);
365 writel(CONFIG_SYS_DM36x_AB1CR
, &davinci_emif_regs
->ab1cr
);
367 setbits_le32(&davinci_emif_regs
->nandfcr
, DAVINCI_NANDFCR_CS2NAND
);
369 writel(CONFIG_SYS_DM36x_AB2CR
, &davinci_emif_regs
->ab2cr
);
374 void dm365_pinmux_ctl(unsigned long offset
, unsigned long mask
,
377 clrbits_le32(&dv_sys_module_regs
->pinmux
[offset
], mask
);
378 setbits_le32(&dv_sys_module_regs
->pinmux
[offset
], (mask
& value
));
381 __attribute__((weak
))
382 void board_gpio_init(void)
387 #if defined(CONFIG_POST)
388 int post_log(char *format
, ...)
394 void dm36x_lowlevel_init(ulong bootflag
)
396 struct davinci_uart_ctrl_regs
*davinci_uart_ctrl_regs
=
397 (struct davinci_uart_ctrl_regs
*)(CONFIG_SYS_NS16550_COM1
+
398 DAVINCI_UART_CTRL_BASE
);
400 /* Mask all interrupts */
401 writel(DV_AINTC_INTCTL_IDMODE
, &dv_aintc_regs
->intctl
);
402 writel(0x0, &dv_aintc_regs
->eabase
);
403 writel(0x0, &dv_aintc_regs
->eint0
);
404 writel(0x0, &dv_aintc_regs
->eint1
);
406 /* Clear all interrupts */
407 writel(0xffffffff, &dv_aintc_regs
->fiq0
);
408 writel(0xffffffff, &dv_aintc_regs
->fiq1
);
409 writel(0xffffffff, &dv_aintc_regs
->irq0
);
410 writel(0xffffffff, &dv_aintc_regs
->irq1
);
415 /* System PSC setup - enable all */
419 dm365_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX0
);
420 dm365_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX1
);
421 dm365_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX2
);
422 dm365_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX3
);
423 dm365_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX4
);
426 dm365_pll1_init(CONFIG_SYS_DM36x_PLL1_PLLM
,
427 CONFIG_SYS_DM36x_PLL1_PREDIV
);
428 dm365_pll2_init(CONFIG_SYS_DM36x_PLL2_PLLM
,
429 CONFIG_SYS_DM36x_PLL2_PREDIV
);
434 NS16550_init((NS16550_t
)(CONFIG_SYS_NS16550_COM1
),
435 CONFIG_SYS_NS16550_CLK
/ 16 / CONFIG_BAUDRATE
);
438 * Fix Power and Emulation Management Register
439 * see sprufh2.pdf page 38 Table 22
441 writel((DAVINCI_UART_PWREMU_MGMT_FREE
| DAVINCI_UART_PWREMU_MGMT_URRST
|
442 DAVINCI_UART_PWREMU_MGMT_UTRST
),
443 &davinci_uart_ctrl_regs
->pwremu_mgmt
);
453 #if defined(CONFIG_POST)
455 * Do memory tests, calls arch_memory_failure_handle()