|
@@ -33,6 +33,7 @@
|
|
|
#include "clock.h"
|
|
|
#include "generic.h"
|
|
|
|
|
|
+void __iomem *at91_pmc_base;
|
|
|
|
|
|
/*
|
|
|
* There's a lot more which can be done with clocks, including cpufreq
|
|
@@ -125,11 +126,11 @@ static void pllb_mode(struct clk *clk, int is_on)
|
|
|
value = 0;
|
|
|
|
|
|
// REVISIT: Add work-around for AT91RM9200 Errata #26 ?
|
|
|
- at91_sys_write(AT91_CKGR_PLLBR, value);
|
|
|
+ at91_pmc_write(AT91_CKGR_PLLBR, value);
|
|
|
|
|
|
do {
|
|
|
cpu_relax();
|
|
|
- } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
|
|
|
+ } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
|
|
|
}
|
|
|
|
|
|
static struct clk pllb = {
|
|
@@ -144,24 +145,24 @@ static struct clk pllb = {
|
|
|
static void pmc_sys_mode(struct clk *clk, int is_on)
|
|
|
{
|
|
|
if (is_on)
|
|
|
- at91_sys_write(AT91_PMC_SCER, clk->pmc_mask);
|
|
|
+ at91_pmc_write(AT91_PMC_SCER, clk->pmc_mask);
|
|
|
else
|
|
|
- at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
|
|
|
+ at91_pmc_write(AT91_PMC_SCDR, clk->pmc_mask);
|
|
|
}
|
|
|
|
|
|
static void pmc_uckr_mode(struct clk *clk, int is_on)
|
|
|
{
|
|
|
- unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
|
|
|
+ unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
|
|
|
|
|
|
if (is_on) {
|
|
|
is_on = AT91_PMC_LOCKU;
|
|
|
- at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
|
|
|
+ at91_pmc_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
|
|
|
} else
|
|
|
- at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
|
|
|
+ at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
|
|
|
|
|
|
do {
|
|
|
cpu_relax();
|
|
|
- } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
|
|
|
+ } while ((at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
|
|
|
}
|
|
|
|
|
|
/* USB function clocks (PLLB must be 48 MHz) */
|
|
@@ -197,9 +198,9 @@ struct clk mck = {
|
|
|
static void pmc_periph_mode(struct clk *clk, int is_on)
|
|
|
{
|
|
|
if (is_on)
|
|
|
- at91_sys_write(AT91_PMC_PCER, clk->pmc_mask);
|
|
|
+ at91_pmc_write(AT91_PMC_PCER, clk->pmc_mask);
|
|
|
else
|
|
|
- at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
|
|
|
+ at91_pmc_write(AT91_PMC_PCDR, clk->pmc_mask);
|
|
|
}
|
|
|
|
|
|
static struct clk __init *at91_css_to_clk(unsigned long css)
|
|
@@ -359,10 +360,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
|
|
if (actual && actual <= rate) {
|
|
|
u32 pckr;
|
|
|
|
|
|
- pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
|
|
|
+ pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id));
|
|
|
pckr &= css_mask; /* keep clock selection */
|
|
|
pckr |= prescale << prescale_offset;
|
|
|
- at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
|
|
|
+ at91_pmc_write(AT91_PMC_PCKR(clk->id), pckr);
|
|
|
clk->rate_hz = actual;
|
|
|
break;
|
|
|
}
|
|
@@ -396,7 +397,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
|
|
|
|
|
|
clk->rate_hz = parent->rate_hz;
|
|
|
clk->parent = parent;
|
|
|
- at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id);
|
|
|
+ at91_pmc_write(AT91_PMC_PCKR(clk->id), parent->id);
|
|
|
|
|
|
spin_unlock_irqrestore(&clk_lock, flags);
|
|
|
return 0;
|
|
@@ -415,7 +416,7 @@ static void __init init_programmable_clock(struct clk *clk)
|
|
|
else
|
|
|
css_mask = AT91_PMC_CSS;
|
|
|
|
|
|
- pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
|
|
|
+ pckr = at91_pmc_read(AT91_PMC_PCKR(clk->id));
|
|
|
parent = at91_css_to_clk(pckr & css_mask);
|
|
|
clk->parent = parent;
|
|
|
clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
|
|
@@ -432,23 +433,23 @@ static int at91_clk_show(struct seq_file *s, void *unused)
|
|
|
u32 scsr, pcsr, uckr = 0, sr;
|
|
|
struct clk *clk;
|
|
|
|
|
|
- scsr = at91_sys_read(AT91_PMC_SCSR);
|
|
|
- pcsr = at91_sys_read(AT91_PMC_PCSR);
|
|
|
- sr = at91_sys_read(AT91_PMC_SR);
|
|
|
+ scsr = at91_pmc_read(AT91_PMC_SCSR);
|
|
|
+ pcsr = at91_pmc_read(AT91_PMC_PCSR);
|
|
|
+ sr = at91_pmc_read(AT91_PMC_SR);
|
|
|
seq_printf(s, "SCSR = %8x\n", scsr);
|
|
|
seq_printf(s, "PCSR = %8x\n", pcsr);
|
|
|
- seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR));
|
|
|
- seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
|
|
|
- seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
|
|
|
+ seq_printf(s, "MOR = %8x\n", at91_pmc_read(AT91_CKGR_MOR));
|
|
|
+ seq_printf(s, "MCFR = %8x\n", at91_pmc_read(AT91_CKGR_MCFR));
|
|
|
+ seq_printf(s, "PLLA = %8x\n", at91_pmc_read(AT91_CKGR_PLLAR));
|
|
|
if (cpu_has_pllb())
|
|
|
- seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
|
|
|
+ seq_printf(s, "PLLB = %8x\n", at91_pmc_read(AT91_CKGR_PLLBR));
|
|
|
if (cpu_has_utmi()) {
|
|
|
- uckr = at91_sys_read(AT91_CKGR_UCKR);
|
|
|
+ uckr = at91_pmc_read(AT91_CKGR_UCKR);
|
|
|
seq_printf(s, "UCKR = %8x\n", uckr);
|
|
|
}
|
|
|
- seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
|
|
|
+ seq_printf(s, "MCKR = %8x\n", at91_pmc_read(AT91_PMC_MCKR));
|
|
|
if (cpu_has_upll())
|
|
|
- seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB));
|
|
|
+ seq_printf(s, "USB = %8x\n", at91_pmc_read(AT91_PMC_USB));
|
|
|
seq_printf(s, "SR = %8x\n", sr);
|
|
|
|
|
|
seq_printf(s, "\n");
|
|
@@ -637,14 +638,14 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
|
|
|
if (cpu_is_at91rm9200()) {
|
|
|
uhpck.pmc_mask = AT91RM9200_PMC_UHP;
|
|
|
udpck.pmc_mask = AT91RM9200_PMC_UDP;
|
|
|
- at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
|
|
|
+ at91_pmc_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
|
|
|
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
|
|
|
cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
|
|
|
cpu_is_at91sam9g10()) {
|
|
|
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
|
|
|
udpck.pmc_mask = AT91SAM926x_PMC_UDP;
|
|
|
}
|
|
|
- at91_sys_write(AT91_CKGR_PLLBR, 0);
|
|
|
+ at91_pmc_write(AT91_CKGR_PLLBR, 0);
|
|
|
|
|
|
udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
|
|
|
uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
|
|
@@ -661,13 +662,13 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
|
|
|
/* Setup divider by 10 to reach 48 MHz */
|
|
|
usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV;
|
|
|
|
|
|
- at91_sys_write(AT91_PMC_USB, usbr);
|
|
|
+ at91_pmc_write(AT91_PMC_USB, usbr);
|
|
|
|
|
|
/* Now set uhpck values */
|
|
|
uhpck.parent = &utmi_clk;
|
|
|
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
|
|
|
uhpck.rate_hz = utmi_clk.rate_hz;
|
|
|
- uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
|
|
|
+ uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
|
|
|
}
|
|
|
|
|
|
int __init at91_clock_init(unsigned long main_clock)
|
|
@@ -676,6 +677,10 @@ int __init at91_clock_init(unsigned long main_clock)
|
|
|
int i;
|
|
|
int pll_overclock = false;
|
|
|
|
|
|
+ at91_pmc_base = ioremap(AT91_PMC, 256);
|
|
|
+ if (!at91_pmc_base)
|
|
|
+ panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC);
|
|
|
+
|
|
|
/*
|
|
|
* When the bootloader initialized the main oscillator correctly,
|
|
|
* there's no problem using the cycle counter. But if it didn't,
|
|
@@ -684,14 +689,14 @@ int __init at91_clock_init(unsigned long main_clock)
|
|
|
*/
|
|
|
if (!main_clock) {
|
|
|
do {
|
|
|
- tmp = at91_sys_read(AT91_CKGR_MCFR);
|
|
|
+ tmp = at91_pmc_read(AT91_CKGR_MCFR);
|
|
|
} while (!(tmp & AT91_PMC_MAINRDY));
|
|
|
main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
|
|
|
}
|
|
|
main_clk.rate_hz = main_clock;
|
|
|
|
|
|
/* report if PLLA is more than mildly overclocked */
|
|
|
- plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
|
|
|
+ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_pmc_read(AT91_CKGR_PLLAR));
|
|
|
if (cpu_has_300M_plla()) {
|
|
|
if (plla.rate_hz > 300000000)
|
|
|
pll_overclock = true;
|
|
@@ -706,7 +711,7 @@ int __init at91_clock_init(unsigned long main_clock)
|
|
|
pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
|
|
|
|
|
|
if (cpu_has_plladiv2()) {
|
|
|
- mckr = at91_sys_read(AT91_PMC_MCKR);
|
|
|
+ mckr = at91_pmc_read(AT91_PMC_MCKR);
|
|
|
plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
|
|
|
}
|
|
|
|
|
@@ -746,7 +751,7 @@ int __init at91_clock_init(unsigned long main_clock)
|
|
|
* MCK and CPU derive from one of those primary clocks.
|
|
|
* For now, assume this parentage won't change.
|
|
|
*/
|
|
|
- mckr = at91_sys_read(AT91_PMC_MCKR);
|
|
|
+ mckr = at91_pmc_read(AT91_PMC_MCKR);
|
|
|
mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
|
|
|
freq = mck.parent->rate_hz;
|
|
|
freq /= pmc_prescaler_divider(mckr); /* prescale */
|
|
@@ -819,8 +824,8 @@ static int __init at91_clock_reset(void)
|
|
|
pr_debug("Clocks: disable unused %s\n", clk->name);
|
|
|
}
|
|
|
|
|
|
- at91_sys_write(AT91_PMC_PCDR, pcdr);
|
|
|
- at91_sys_write(AT91_PMC_SCDR, scdr);
|
|
|
+ at91_pmc_write(AT91_PMC_PCDR, pcdr);
|
|
|
+ at91_pmc_write(AT91_PMC_SCDR, scdr);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -828,6 +833,6 @@ late_initcall(at91_clock_reset);
|
|
|
|
|
|
void at91sam9_idle(void)
|
|
|
{
|
|
|
- at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
|
|
|
+ at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
|
|
|
cpu_do_idle();
|
|
|
}
|