ARM: at91: add pmc DT support

Specified the main Oscillator via clock binding.
This will allow to do not hardcode it anymore in the DT board at 12MHz.
Signed-off-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: default avatarRob Herring <rob.herring@calxeda.com>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
parent 2b11ea5b
* Power Management Controller (PMC)
Required properties:
- compatible: Should be "atmel,at91rm9200-pmc"
- reg: Should contain PMC registers location and length
Examples:
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
...@@ -59,6 +59,11 @@ aic: interrupt-controller@fffff000 { ...@@ -59,6 +59,11 @@ aic: interrupt-controller@fffff000 {
reg = <0xfffff000 0x200>; reg = <0xfffff000 0x200>;
}; };
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
pit: timer@fffffd30 { pit: timer@fffffd30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffd30 0xf>; reg = <0xfffffd30 0xf>;
......
...@@ -60,6 +60,11 @@ aic: interrupt-controller@fffff000 { ...@@ -60,6 +60,11 @@ aic: interrupt-controller@fffff000 {
reg = <0xfffff000 0x200>; reg = <0xfffff000 0x200>;
}; };
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
pit: timer@fffffd30 { pit: timer@fffffd30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffd30 0xf>; reg = <0xfffffd30 0xf>;
......
...@@ -21,6 +21,17 @@ memory@70000000 { ...@@ -21,6 +21,17 @@ memory@70000000 {
reg = <0x70000000 0x4000000>; reg = <0x70000000 0x4000000>;
}; };
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};
ahb { ahb {
apb { apb {
dbgu: serial@ffffee00 { dbgu: serial@ffffee00 {
......
...@@ -58,6 +58,11 @@ aic: interrupt-controller@fffff000 { ...@@ -58,6 +58,11 @@ aic: interrupt-controller@fffff000 {
reg = <0xfffff000 0x200>; reg = <0xfffff000 0x200>;
}; };
pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};
pit: timer@fffffe30 { pit: timer@fffffe30 {
compatible = "atmel,at91sam9260-pit"; compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe30 0xf>; reg = <0xfffffe30 0xf>;
......
...@@ -12,6 +12,17 @@ memory@20000000 { ...@@ -12,6 +12,17 @@ memory@20000000 {
reg = <0x20000000 0x8000000>; reg = <0x20000000 0x8000000>;
}; };
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};
ahb { ahb {
nand0: nand@40000000 { nand0: nand@40000000 {
nand-bus-width = <8>; nand-bus-width = <8>;
......
...@@ -20,6 +20,17 @@ memory@20000000 { ...@@ -20,6 +20,17 @@ memory@20000000 {
reg = <0x20000000 0x4000000>; reg = <0x20000000 0x4000000>;
}; };
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};
ahb { ahb {
apb { apb {
dbgu: serial@fffff200 { dbgu: serial@fffff200 {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of_address.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/at91_pmc.h> #include <mach/at91_pmc.h>
...@@ -671,16 +672,12 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) ...@@ -671,16 +672,12 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
uhpck.rate_hz /= 1 + ((at91_pmc_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) static int __init at91_pmc_init(unsigned long main_clock)
{ {
unsigned tmp, freq, mckr; unsigned tmp, freq, mckr;
int i; int i;
int pll_overclock = false; 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, * When the bootloader initialized the main oscillator correctly,
* there's no problem using the cycle counter. But if it didn't, * there's no problem using the cycle counter. But if it didn't,
...@@ -802,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock) ...@@ -802,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock)
return 0; return 0;
} }
#if defined(CONFIG_OF)
static struct of_device_id pmc_ids[] = {
{ .compatible = "atmel,at91rm9200-pmc" },
{ /*sentinel*/ }
};
static struct of_device_id osc_ids[] = {
{ .compatible = "atmel,osc" },
{ /*sentinel*/ }
};
int __init at91_dt_clock_init(void)
{
struct device_node *np;
u32 main_clock = 0;
np = of_find_matching_node(NULL, pmc_ids);
if (!np)
panic("unable to find compatible pmc node in dtb\n");
at91_pmc_base = of_iomap(np, 0);
if (!at91_pmc_base)
panic("unable to map pmc cpu registers\n");
of_node_put(np);
/* retrieve the freqency of fixed clocks from device tree */
np = of_find_matching_node(NULL, osc_ids);
if (np) {
u32 rate;
if (!of_property_read_u32(np, "clock-frequency", &rate))
main_clock = rate;
}
of_node_put(np);
return at91_pmc_init(main_clock);
}
#endif
int __init at91_clock_init(unsigned long main_clock)
{
at91_pmc_base = ioremap(AT91_PMC, 256);
if (!at91_pmc_base)
panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC);
return at91_pmc_init(main_clock);
}
/* /*
* Several unused clocks may be active. Turn them off. * Several unused clocks may be active. Turn them off.
*/ */
......
...@@ -53,6 +53,7 @@ extern void __init at91sam9rl_set_console_clock(int id); ...@@ -53,6 +53,7 @@ extern void __init at91sam9rl_set_console_clock(int id);
extern void __init at91sam9g45_set_console_clock(int id); extern void __init at91sam9g45_set_console_clock(int id);
#ifdef CONFIG_AT91_PMC_UNIT #ifdef CONFIG_AT91_PMC_UNIT
extern int __init at91_clock_init(unsigned long main_clock); extern int __init at91_clock_init(unsigned long main_clock);
extern int __init at91_dt_clock_init(void);
#else #else
static int inline at91_clock_init(unsigned long main_clock) { return 0; } static int inline at91_clock_init(unsigned long main_clock) { return 0; }
#endif #endif
......
...@@ -292,9 +292,8 @@ void __init at91_dt_initialize(void) ...@@ -292,9 +292,8 @@ void __init at91_dt_initialize(void)
/* temporary until have the ramc binding*/ /* temporary until have the ramc binding*/
at91_boot_soc.ioremap_registers(); at91_boot_soc.ioremap_registers();
/* temporary until have the pmc binding */
/* Init clock subsystem */ /* Init clock subsystem */
at91_clock_init(12000000); at91_dt_clock_init();
/* Register the processor-specific clocks */ /* Register the processor-specific clocks */
at91_boot_soc.register_clocks(); at91_boot_soc.register_clocks();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment