static u32 scg_nic_get_rate(enum scg_clk clk)
{
- u32 reg, val, rate;
+ u32 reg, val, rate, nic0_rate;
u32 shift, mask;
reg = readl(&scg1_regs->niccsr);
val = (reg & SCG_NICCSR_NIC0DIV_MASK) >> SCG_NICCSR_NIC0DIV_SHIFT;
rate = rate / (val + 1);
+ nic0_rate = rate;
clk_debug("scg_nic_get_rate NIC0 rate %u\n", rate);
return 0;
}
+ /*
+ * On RevB, the nic_bus and nic_ext dividers are parallel
+ * not chained with nic div
+ */
+ if (soc_rev() >= CHIP_REV_2_0)
+ rate = nic0_rate;
+
val = (reg & mask) >> shift;
rate = rate / (val + 1);
case SCG_SCS_SLOW_IRC:
case SCG_SCS_FAST_IRC:
case SCG_SCS_RTC_OSC:
- rate = scg_src_get_rate(scg_scs_array[val]);
+ rate = scg_src_get_rate(scg_scs_array[val - 1]);
break;
case 5:
rate = scg_apll_get_rate();
infreq = infreq / pre_div;
- return infreq * mult + infreq * num / denom;
+ if (denom)
+ return infreq * mult + infreq * num / denom;
+ else
+ return infreq * mult;
case PLL_A7_APLL:
reg = readl(&scg1_regs->apllcsr);
infreq = infreq / pre_div;
- return infreq * mult + infreq * num / denom;
+ if (denom)
+ return infreq * mult + infreq * num / denom;
+ else
+ return infreq * mult;
case PLL_USB:
reg = readl(&scg1_regs->upllcsr);
/* Clock source is System OSC <<0 */
#define SCG1_APLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
-/*
- * A7 APLL = 24MHz / 1 * 22 / 1 / 1 = 528MHz,
- * system PLL is sourced from APLL,
- * APLL clock source is system OSC (24MHz)
- */
-#define SCG1_APLL_CFG_NUM_24M_OSC (SCG1_APLL_CFG_POSTDIV2_NUM | \
- SCG1_APLL_CFG_POSTDIV1_NUM | \
- (22 << SCG_PLL_CFG_MULT_SHIFT) | \
- SCG1_APLL_CFG_PFDSEL_NUM | \
- SCG1_APLL_CFG_PREDIV_NUM | \
- SCG1_APLL_CFG_BYPASS_NUM | \
- SCG1_APLL_CFG_PLLSEL_NUM | \
- SCG1_APLL_CFG_CLKSRC_NUM)
-
-/* PFD0 Freq = A7 APLL(528MHz) * 18 / 27 = 352MHz */
-#define SCG1_APLL_PFD0_FRAC_NUM (27)
-
-
-void scg_a7_apll_init(void)
-{
- u32 val = 0;
-
- /* Disable A7 Auxiliary PLL */
- val = readl(&scg1_regs->apllcsr);
- val &= ~SCG_APLL_CSR_APLLEN_MASK;
- writel(val, &scg1_regs->apllcsr);
-
- /* Gate off A7 APLL PFD0 ~ PDF4 */
- val = readl(&scg1_regs->apllpfd);
- val |= 0x80808080;
- writel(val, &scg1_regs->apllpfd);
-
- /* ================ A7 APLL Configuration Start ============== */
- /* Configure A7 Auxiliary PLL */
- writel(SCG1_APLL_CFG_NUM_24M_OSC, &scg1_regs->apllcfg);
-
- /* Enable A7 Auxiliary PLL */
- val = readl(&scg1_regs->apllcsr);
- val |= SCG_APLL_CSR_APLLEN_MASK;
- writel(val, &scg1_regs->apllcsr);
-
- /* Wait for A7 APLL clock ready */
- while (!(readl(&scg1_regs->apllcsr) & SCG_APLL_CSR_APLLVLD_MASK))
- ;
-
- /* Configure A7 APLL PFD0 */
- val = readl(&scg1_regs->apllpfd);
- val &= ~SCG_PLL_PFD0_FRAC_MASK;
- val |= SCG1_APLL_PFD0_FRAC_NUM;
- writel(val, &scg1_regs->apllpfd);
-
- /* Un-gate A7 APLL PFD0 */
- val = readl(&scg1_regs->apllpfd);
- val &= ~SCG_PLL_PFD0_GATE_MASK;
- writel(val, &scg1_regs->apllpfd);
-
- /* Wait for A7 APLL PFD0 clock being valid */
- while (!(readl(&scg1_regs->apllpfd) & SCG_PLL_PFD0_VALID_MASK))
- ;
-}
-
/* SCG1(A7) FIRC DIV configurations */
/* Disable FIRC DIV3 */
#define SCG1_FIRCDIV_DIV3_NUM ((0x0) << SCG_FIRCDIV_DIV3_SHIFT)
debug("SCG RCCR Value: 0x%x\n", readl(&scg1_regs->rccr));
debug("SCG Clock Status: 0x%x\n", readl(&scg1_regs->csr));
}
+
+void scg_a7_init_core_clk(void)
+{
+ u32 val = 0;
+
+ /*
+ * The normal target frequency for ULP B0 is 500Mhz,
+ * but ROM set it to 413Mhz, need to change SPLL PFD0 FRAC
+ */
+ if (soc_rev() >= CHIP_REV_2_0) {
+ /* Switch RCCR SCG to SOSC, firstly check the SOSC is valid */
+ if ((readl(&scg1_regs->sosccsr) & SCG_SOSC_CSR_SOSCVLD_MASK)) {
+ val = readl(&scg1_regs->rccr);
+ val &= (~SCG_CCR_SCS_MASK);
+ val |= ((SCG_SCS_SYS_OSC) << SCG_CCR_SCS_SHIFT);
+ writel(val, &scg1_regs->rccr);
+
+ /* Switch the PLLS to SPLL clk */
+ val = readl(&scg1_regs->spllcfg);
+ val &= ~SCG_PLL_CFG_PLLSEL_MASK;
+ writel(val, &scg1_regs->spllcfg);
+
+ /*
+ * Re-configure PFD0 to 19,
+ * A7 SPLL(528MHz) * 18 / 19 = 500MHz
+ */
+ scg_enable_pll_pfd(SCG_SPLL_PFD0_CLK, 19);
+
+ /* Switch the PLLS to SPLL PFD0 */
+ val = readl(&scg1_regs->spllcfg);
+ val |= SCG_PLL_CFG_PLLSEL_MASK;
+ writel(val, &scg1_regs->spllcfg);
+
+ /* Set RCCR SCG to SPLL clk out */
+ val = readl(&scg1_regs->rccr);
+ val &= (~SCG_CCR_SCS_MASK);
+ val |= ((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT);
+ writel(val, &scg1_regs->rccr);
+ }
+ }
+}