#define CLK_DIV_MASK 0x1f
#define CLK_DIV2_MASK 0x7f
#define CLK_SEL_SHIFT 0x8
+#define CLK_MODE_MASK 0x7
#define CLK_MODE_SEL 0x7
-#define CLK_MODE_MASK 0xfffffff8
-#define CLK_DIV_SEL 0xFFFFFFE0
-#define CPGMAC0_IDLE 0x30000
-#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
+#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
+
const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
const struct cm_rtc *cmrtc = (struct cm_rtc *)CM_RTC;
+#ifdef CONFIG_SPL_BUILD
+#define enable_clk(reg, val) __enable_clk(#reg, ®, val)
+
+static void __enable_clk(const char *name, const void *reg, u32 mask)
+{
+ unsigned long timeout = 10000000;
+
+ writel(mask, reg);
+ while (readl(reg) != mask)
+ /* poor man's timeout, since timers not initialized */
+ if (timeout-- == 0)
+ /* no error message, since console not yet available */
+ break;
+}
+
static void enable_interface_clocks(void)
{
/* Enable all the Interconnect Modules */
- writel(PRCM_MOD_EN, &cmper->l3clkctrl);
- while (readl(&cmper->l3clkctrl) != PRCM_MOD_EN)
- ;
-
- writel(PRCM_MOD_EN, &cmper->l4lsclkctrl);
- while (readl(&cmper->l4lsclkctrl) != PRCM_MOD_EN)
- ;
-
- writel(PRCM_MOD_EN, &cmper->l4fwclkctrl);
- while (readl(&cmper->l4fwclkctrl) != PRCM_MOD_EN)
- ;
-
- writel(PRCM_MOD_EN, &cmwkup->wkl4wkclkctrl);
- while (readl(&cmwkup->wkl4wkclkctrl) != PRCM_MOD_EN)
- ;
-
- writel(PRCM_MOD_EN, &cmper->l3instrclkctrl);
- while (readl(&cmper->l3instrclkctrl) != PRCM_MOD_EN)
- ;
-
- writel(PRCM_MOD_EN, &cmper->l4hsclkctrl);
- while (readl(&cmper->l4hsclkctrl) != PRCM_MOD_EN)
- ;
-
- writel(PRCM_MOD_EN, &cmwkup->wkgpio0clkctrl);
- while (readl(&cmwkup->wkgpio0clkctrl) != PRCM_MOD_EN)
- ;
+ enable_clk(cmper->l3clkctrl, PRCM_MOD_EN);
+ enable_clk(cmper->l4lsclkctrl, PRCM_MOD_EN);
+ enable_clk(cmper->l4fwclkctrl, PRCM_MOD_EN);
+ enable_clk(cmwkup->wkl4wkclkctrl, PRCM_MOD_EN);
+ enable_clk(cmper->l3instrclkctrl, PRCM_MOD_EN);
+ enable_clk(cmper->l4hsclkctrl, PRCM_MOD_EN);
+#ifdef CONFIG_HW_WATCHDOG
+ enable_clk(cmwkup->wdtimer1ctrl, PRCM_MOD_EN);
+#endif
+ /* GPIO0 */
+ enable_clk(cmwkup->wkgpio0clkctrl, PRCM_MOD_EN);
}
/*
static void enable_per_clocks(void)
{
/* Enable the control module though RBL would have done it*/
- writel(PRCM_MOD_EN, &cmwkup->wkctrlclkctrl);
- while (readl(&cmwkup->wkctrlclkctrl) != PRCM_MOD_EN)
- ;
-
- /* Enable the module clock */
- writel(PRCM_MOD_EN, &cmper->timer2clkctrl);
- while (readl(&cmper->timer2clkctrl) != PRCM_MOD_EN)
- ;
-
+ enable_clk(cmwkup->wkctrlclkctrl, PRCM_MOD_EN);
+ /* Enable the timer2 clock */
+ enable_clk(cmper->timer2clkctrl, PRCM_MOD_EN);
/* Select the Master osc 24 MHZ as Timer2 clock source */
writel(0x1, &cmdpll->clktimer2clk);
+#ifdef CONFIG_SYS_NS16550_COM1
/* UART0 */
- writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl);
- while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN)
- ;
-
- /* UART1 */
-#ifdef CONFIG_SERIAL2
- writel(PRCM_MOD_EN, &cmper->uart1clkctrl);
- while (readl(&cmper->uart1clkctrl) != PRCM_MOD_EN)
- ;
-#endif /* CONFIG_SERIAL2 */
-
- /* UART2 */
-#ifdef CONFIG_SERIAL3
- writel(PRCM_MOD_EN, &cmper->uart2clkctrl);
- while (readl(&cmper->uart2clkctrl) != PRCM_MOD_EN)
- ;
-#endif /* CONFIG_SERIAL3 */
-
- /* UART3 */
-#ifdef CONFIG_SERIAL4
- writel(PRCM_MOD_EN, &cmper->uart3clkctrl);
- while (readl(&cmper->uart3clkctrl) != PRCM_MOD_EN)
- ;
-#endif /* CONFIG_SERIAL4 */
-
- /* UART4 */
-#ifdef CONFIG_SERIAL5
- writel(PRCM_MOD_EN, &cmper->uart4clkctrl);
- while (readl(&cmper->uart4clkctrl) != PRCM_MOD_EN)
- ;
-#endif /* CONFIG_SERIAL5 */
-
- /* UART5 */
-#ifdef CONFIG_SERIAL6
- writel(PRCM_MOD_EN, &cmper->uart5clkctrl);
- while (readl(&cmper->uart5clkctrl) != PRCM_MOD_EN)
- ;
-#endif /* CONFIG_SERIAL6 */
-
+ enable_clk(cmwkup->wkup_uart0ctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM2
+ enable_clk(cmper->uart1clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM3
+ enable_clk(cmper->uart2clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM4
+ enable_clk(cmper->uart3clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM5
+ enable_clk(cmper->uart4clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM6
+ enable_clk(cmper->uart5clkctrl, PRCM_MOD_EN);
+#endif
/* GPMC */
- writel(PRCM_MOD_EN, &cmper->gpmcclkctrl);
- while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
- ;
+ enable_clk(cmper->gpmcclkctrl, PRCM_MOD_EN);
/* ELM */
- writel(PRCM_MOD_EN, &cmper->elmclkctrl);
- while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN)
- ;
+ enable_clk(cmper->elmclkctrl, PRCM_MOD_EN);
- /* MMC0*/
- writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
- while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
- ;
+ /* Ethernet */
+ enable_clk(cmper->cpswclkstctrl, PRCM_MOD_EN);
+ enable_clk(cmper->cpgmac0clkctrl, PRCM_MOD_EN);
+
+ /* MMC */
+#ifndef CONFIG_OMAP_MMC_DEV_0
+ enable_clk(cmper->mmc0clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_OMAP_MMC_DEV_1
+ enable_clk(cmper->mmc1clkctrl, PRCM_MOD_EN);
+#endif
+ /* LCD */
+ enable_clk(cmper->lcdclkctrl, PRCM_MOD_EN);
/* i2c0 */
- writel(PRCM_MOD_EN, &cmwkup->wkup_i2c0ctrl);
- while (readl(&cmwkup->wkup_i2c0ctrl) != PRCM_MOD_EN)
- ;
+ enable_clk(cmwkup->wkup_i2c0ctrl, PRCM_MOD_EN);
- /* gpio1 module */
- writel(PRCM_MOD_EN, &cmper->gpio1clkctrl);
- while (readl(&cmper->gpio1clkctrl) != PRCM_MOD_EN)
- ;
-
- /* gpio2 module */
- writel(PRCM_MOD_EN, &cmper->gpio2clkctrl);
- while (readl(&cmper->gpio2clkctrl) != PRCM_MOD_EN)
- ;
-
- /* gpio3 module */
- writel(PRCM_MOD_EN, &cmper->gpio3clkctrl);
- while (readl(&cmper->gpio3clkctrl) != PRCM_MOD_EN)
- ;
+ /* GPIO1-3 */
+ enable_clk(cmper->gpio1clkctrl, PRCM_MOD_EN);
+ enable_clk(cmper->gpio2clkctrl, PRCM_MOD_EN);
+ enable_clk(cmper->gpio3clkctrl, PRCM_MOD_EN);
/* i2c1 */
- writel(PRCM_MOD_EN, &cmper->i2c1clkctrl);
- while (readl(&cmper->i2c1clkctrl) != PRCM_MOD_EN)
- ;
-
- /* Ethernet */
- writel(PRCM_MOD_EN, &cmper->cpgmac0clkctrl);
- while ((readl(&cmper->cpgmac0clkctrl) & CPGMAC0_IDLE) != PRCM_FUNCTL)
- ;
+ enable_clk(cmper->i2c1clkctrl, PRCM_MOD_EN);
/* spi0 */
- writel(PRCM_MOD_EN, &cmper->spi0clkctrl);
- while (readl(&cmper->spi0clkctrl) != PRCM_MOD_EN)
- ;
+ enable_clk(cmper->spi0clkctrl, PRCM_MOD_EN);
- /* RTC */
- writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
- while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
- ;
+ /* rtc */
+ enable_clk(cmrtc->rtcclkctrl, PRCM_MOD_EN);
- /* MUSB */
- writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
- while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
- ;
+ /* usb0 */
+ enable_clk(cmper->usb0clkctrl, PRCM_MOD_EN);
}
static void mpu_pll_config(void)
while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS)
;
- clksel = clksel & (~CLK_SEL_MASK);
- clksel = clksel | ((MPUPLL_M << CLK_SEL_SHIFT) | MPUPLL_N);
+ clksel &= ~CLK_SEL_MASK;
+ clksel |= (MPUPLL_M << CLK_SEL_SHIFT) | MPUPLL_N;
writel(clksel, &cmwkup->clkseldpllmpu);
- div_m2 = div_m2 & ~CLK_DIV_MASK;
- div_m2 = div_m2 | MPUPLL_M2;
+ div_m2 &= ~CLK_DIV_MASK;
+ div_m2 |= MPUPLL_M2;
writel(div_m2, &cmwkup->divm2dpllmpu);
- clkmode = clkmode | CLK_MODE_SEL;
+ clkmode &= ~CLK_MODE_MASK;
+ clkmode |= CLK_MODE_SEL;
writel(clkmode, &cmwkup->clkmoddpllmpu);
while (readl(&cmwkup->idlestdpllmpu) != ST_DPLL_CLK)
while (readl(&cmwkup->idlestdpllcore) != ST_MN_BYPASS)
;
- clksel = clksel & (~CLK_SEL_MASK);
- clksel = clksel | ((COREPLL_M << CLK_SEL_SHIFT) | COREPLL_N);
+ clksel &= ~CLK_SEL_MASK;
+ clksel |= ((COREPLL_M << CLK_SEL_SHIFT) | COREPLL_N);
writel(clksel, &cmwkup->clkseldpllcore);
- div_m4 = div_m4 & ~CLK_DIV_MASK;
- div_m4 = div_m4 | COREPLL_M4;
+ div_m4 &= ~CLK_DIV_MASK;
+ div_m4 |= COREPLL_M4;
writel(div_m4, &cmwkup->divm4dpllcore);
- div_m5 = div_m5 & ~CLK_DIV_MASK;
- div_m5 = div_m5 | COREPLL_M5;
+ div_m5 &= ~CLK_DIV_MASK;
+ div_m5 |= COREPLL_M5;
writel(div_m5, &cmwkup->divm5dpllcore);
- div_m6 = div_m6 & ~CLK_DIV_MASK;
- div_m6 = div_m6 | COREPLL_M6;
+ div_m6 &= ~CLK_DIV_MASK;
+ div_m6 |= COREPLL_M6;
writel(div_m6, &cmwkup->divm6dpllcore);
- clkmode = clkmode | CLK_MODE_SEL;
+ clkmode &= ~CLK_MODE_MASK;
+ clkmode |= CLK_MODE_SEL;
writel(clkmode, &cmwkup->clkmoddpllcore);
while (readl(&cmwkup->idlestdpllcore) != ST_DPLL_CLK)
while (readl(&cmwkup->idlestdpllper) != ST_MN_BYPASS)
;
- clksel = clksel & (~CLK_SEL_MASK);
- clksel = clksel | ((PERPLL_M << CLK_SEL_SHIFT) | PERPLL_N);
+ clksel &= ~CLK_SEL_MASK;
+ clksel |= (PERPLL_M << CLK_SEL_SHIFT) | PERPLL_N;
writel(clksel, &cmwkup->clkseldpllper);
- div_m2 = div_m2 & ~CLK_DIV2_MASK;
- div_m2 = div_m2 | PERPLL_M2;
+ div_m2 &= ~CLK_DIV2_MASK;
+ div_m2 |= PERPLL_M2;
writel(div_m2, &cmwkup->divm2dpllper);
- clkmode = clkmode | CLK_MODE_SEL;
+ clkmode &= ~CLK_MODE_MASK;
+ clkmode |= CLK_MODE_SEL;
writel(clkmode, &cmwkup->clkmoddpllper);
while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
}
+static void disp_pll_config(void)
+{
+ u32 clkmode, clksel, div_m2;
+
+ clkmode = readl(&cmwkup->clkmoddplldisp);
+ clksel = readl(&cmwkup->clkseldplldisp);
+ div_m2 = readl(&cmwkup->divm2dplldisp);
+
+ /* Set the PLL to bypass Mode */
+ writel(PLL_BYPASS_MODE, &cmwkup->clkmoddplldisp);
+
+ while (!(readl(&cmwkup->idlestdplldisp) & ST_MN_BYPASS))
+ ;
+
+ clksel &= ~CLK_SEL_MASK;
+ clksel |= (DISPPLL_M << CLK_SEL_SHIFT) | DISPPLL_N;
+ writel(clksel, &cmwkup->clkseldplldisp);
+
+ div_m2 &= ~CLK_DIV2_MASK;
+ div_m2 |= DISPPLL_M2;
+ writel(div_m2, &cmwkup->divm2dplldisp);
+
+ clkmode &= ~CLK_MODE_MASK;
+ clkmode |= CLK_MODE_SEL;
+ writel(clkmode, &cmwkup->clkmoddplldisp);
+
+ while (!(readl(&cmwkup->idlestdplldisp) & ST_DPLL_CLK))
+ ;
+}
+
void ddr_pll_config(unsigned int ddrpll_m)
{
u32 clkmode, clksel, div_m2;
div_m2 = readl(&cmwkup->divm2dpllddr);
/* Set the PLL to bypass Mode */
- clkmode = (clkmode & CLK_MODE_MASK) | PLL_BYPASS_MODE;
+ clkmode &= ~CLK_MODE_MASK;
+ clkmode |= PLL_BYPASS_MODE;
writel(clkmode, &cmwkup->clkmoddpllddr);
/* Wait till bypass mode is enabled */
- while ((readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS)
- != ST_MN_BYPASS)
+ while (!(readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS))
;
- clksel = clksel & (~CLK_SEL_MASK);
- clksel = clksel | ((ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N);
+ clksel &= ~CLK_SEL_MASK;
+ clksel |= (ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N;
writel(clksel, &cmwkup->clkseldpllddr);
- div_m2 = div_m2 & CLK_DIV_SEL;
- div_m2 = div_m2 | DDRPLL_M2;
+ div_m2 &= ~CLK_DIV_MASK;
+ div_m2 |= DDRPLL_M2;
writel(div_m2, &cmwkup->divm2dpllddr);
- clkmode = (clkmode & CLK_MODE_MASK) | CLK_MODE_SEL;
+ clkmode &= ~CLK_MODE_MASK;
+ clkmode |= CLK_MODE_SEL;
writel(clkmode, &cmwkup->clkmoddpllddr);
/* Wait till dpll is locked */
mpu_pll_config();
core_pll_config();
per_pll_config();
+ disp_pll_config();
/* Enable the required interconnect clocks */
enable_interface_clocks();
/* Enable the required peripherals */
enable_per_clocks();
}
+#endif
+
+#define M(mn) (((mn) & CLK_SEL_MASK) >> CLK_SEL_SHIFT)
+#define N(mn) ((mn) & CLK_DIV2_MASK)
+
+unsigned long __clk_get_rate(u32 m_n, u32 div_m2)
+{
+ unsigned long rate;
+
+ div_m2 &= CLK_DIV_MASK;
+ debug("M=%u N=%u M2=%u\n", M(m_n), N(m_n), div_m2);
+ rate = V_OSCK / 1000 * M(m_n) / (N(m_n) + 1) / div_m2;
+ debug("CLK = %lu.%03luMHz\n", rate / 1000, rate % 1000);
+ return rate * 1000;
+}
+
+unsigned long lcdc_clk_rate(void)
+{
+ return clk_get_rate(cmwkup, disp);
+}