Hello,
I'd like to implement cpufreq scaling to my kernel on dm365. Some work has been done before for DA8xx and it should be similar to this case. Unfortunately I have problems with changing PLL's dividers and multipliers in kernel. I followed exactly the method described in reference manual, but after reenablig the PLL everything hangs and cpu goes to some undefined address.
Here is my simlified code:
ctrl = __raw_readl(pll->base + PLLCTL);
/* Switch the PLL to bypass mode */
ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
__raw_writel(ctrl, pll->base + PLLCTL);
udelay(PLL_BYPASS_TIME);
/* Reset and enable PLL */
ctrl &= ~(PLLCTL_PLLRST);
__raw_writel(ctrl, pll->base + PLLCTL);
__raw_writel(prediv, pll->base + PREDIV);
__raw_writel(mult, pll->base + PLLM);
__raw_writel(postdiv, pll->base + POSTDIV);
unsigned int *pllxc;
pllxc = ioremap_nocache(DAVINCI_SYSTEM_MODULE_BASE
+ 0x84 + (pll->num - 1) * 4, 4);
/* sequence for mult and div to take effect */
__raw_writel(0x00470000, pll->base + PLLSECCTL);
__raw_writel(0x00460000, pll->base + PLLSECCTL);
__raw_writel(0x00400000, pll->base + PLLSECCTL);
__raw_writel(0x00410000, pll->base + PLLSECCTL);
__raw_writel(0x00000000, pll->base + PLLCMD);
udelay(10);
// Wait for PLL to LOCK
while ((__raw_readl(pllxc) & 0x07000000) != 0x07000000);
udelay(500);
/* Remove PLL from bypass mode */
ctrl |= PLLCTL_PLLEN;
__raw_writel(ctrl, pll->base + PLLCTL);
After the last command the dm365 fails. Could please someone give me some hint what could be wrong?
I have also a question regarding the peripheral clocking. Are there any constraints to the frequency of the arm core and the peripherals? I have not found it in documentations but with trial error method I found that PLL1->SYSCLK4 (EDMA, SPI, GPIO, ...) clock has to be significantly slower than arm core. Is it documented somewhere?
best regards
Jan