Skip to content

Commit

Permalink
ARM: at91: add pmc DT support
Browse files Browse the repository at this point in the history
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: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
  • Loading branch information
Jean-Christophe PLAGNIOL-VILLARD committed Mar 15, 2012
1 parent 2b11ea5 commit eb5e76f
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 7 deletions.
11 changes: 11 additions & 0 deletions Documentation/devicetree/bindings/arm/atmel-pmc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
* 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>;
};
5 changes: 5 additions & 0 deletions arch/arm/boot/dts/at91sam9g20.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
reg = <0xfffff000 0x200>;
};

pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};

pit: timer@fffffd30 {
compatible = "atmel,at91sam9260-pit";
reg = <0xfffffd30 0xf>;
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/boot/dts/at91sam9g45.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
reg = <0xfffff000 0x200>;
};

pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};

pit: timer@fffffd30 {
compatible = "atmel,at91sam9260-pit";
reg = <0xfffffd30 0xf>;
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/boot/dts/at91sam9m10g45ek.dts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@
reg = <0x70000000 0x4000000>;
};

clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;

main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};

ahb {
apb {
dbgu: serial@ffffee00 {
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/boot/dts/at91sam9x5.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
reg = <0xfffff000 0x200>;
};

pmc: pmc@fffffc00 {
compatible = "atmel,at91rm9200-pmc";
reg = <0xfffffc00 0x100>;
};

pit: timer@fffffe30 {
compatible = "atmel,at91sam9260-pit";
reg = <0xfffffe30 0xf>;
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/boot/dts/at91sam9x5cm.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@
reg = <0x20000000 0x8000000>;
};

clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;

main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};

ahb {
nand0: nand@40000000 {
nand-bus-width = <8>;
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/boot/dts/usb_a9g20.dts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
reg = <0x20000000 0x4000000>;
};

clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;

main_clock: clock@0 {
compatible = "atmel,osc", "fixed-clock";
clock-frequency = <12000000>;
};
};

ahb {
apb {
dbgu: serial@fffff200 {
Expand Down
56 changes: 51 additions & 5 deletions arch/arm/mach-at91/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of_address.h>

#include <mach/hardware.h>
#include <mach/at91_pmc.h>
Expand Down Expand Up @@ -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);
}

int __init at91_clock_init(unsigned long main_clock)
static int __init at91_pmc_init(unsigned long main_clock)
{
unsigned tmp, freq, mckr;
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,
Expand Down Expand Up @@ -802,6 +799,55 @@ int __init at91_clock_init(unsigned long main_clock)
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.
*/
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-at91/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern void __init at91sam9rl_set_console_clock(int id);
extern void __init at91sam9g45_set_console_clock(int id);
#ifdef CONFIG_AT91_PMC_UNIT
extern int __init at91_clock_init(unsigned long main_clock);
extern int __init at91_dt_clock_init(void);
#else
static int inline at91_clock_init(unsigned long main_clock) { return 0; }
#endif
Expand Down
3 changes: 1 addition & 2 deletions arch/arm/mach-at91/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,8 @@ void __init at91_dt_initialize(void)
/* temporary until have the ramc binding*/
at91_boot_soc.ioremap_registers();

/* temporary until have the pmc binding */
/* Init clock subsystem */
at91_clock_init(12000000);
at91_dt_clock_init();

/* Register the processor-specific clocks */
at91_boot_soc.register_clocks();
Expand Down

0 comments on commit eb5e76f

Please sign in to comment.