Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>

+112 -7
+11
Documentation/devicetree/bindings/arm/atmel-pmc.txt
··· 1 + * Power Management Controller (PMC) 2 + 3 + Required properties: 4 + - compatible: Should be "atmel,at91rm9200-pmc" 5 + - reg: Should contain PMC registers location and length 6 + 7 + Examples: 8 + pmc: pmc@fffffc00 { 9 + compatible = "atmel,at91rm9200-pmc"; 10 + reg = <0xfffffc00 0x100>; 11 + };
+5
arch/arm/boot/dts/at91sam9g20.dtsi
··· 59 59 reg = <0xfffff000 0x200>; 60 60 }; 61 61 62 + pmc: pmc@fffffc00 { 63 + compatible = "atmel,at91rm9200-pmc"; 64 + reg = <0xfffffc00 0x100>; 65 + }; 66 + 62 67 pit: timer@fffffd30 { 63 68 compatible = "atmel,at91sam9260-pit"; 64 69 reg = <0xfffffd30 0xf>;
+5
arch/arm/boot/dts/at91sam9g45.dtsi
··· 60 60 reg = <0xfffff000 0x200>; 61 61 }; 62 62 63 + pmc: pmc@fffffc00 { 64 + compatible = "atmel,at91rm9200-pmc"; 65 + reg = <0xfffffc00 0x100>; 66 + }; 67 + 63 68 pit: timer@fffffd30 { 64 69 compatible = "atmel,at91sam9260-pit"; 65 70 reg = <0xfffffd30 0xf>;
+11
arch/arm/boot/dts/at91sam9m10g45ek.dts
··· 21 21 reg = <0x70000000 0x4000000>; 22 22 }; 23 23 24 + clocks { 25 + #address-cells = <1>; 26 + #size-cells = <1>; 27 + ranges; 28 + 29 + main_clock: clock@0 { 30 + compatible = "atmel,osc", "fixed-clock"; 31 + clock-frequency = <12000000>; 32 + }; 33 + }; 34 + 24 35 ahb { 25 36 apb { 26 37 dbgu: serial@ffffee00 {
+5
arch/arm/boot/dts/at91sam9x5.dtsi
··· 58 58 reg = <0xfffff000 0x200>; 59 59 }; 60 60 61 + pmc: pmc@fffffc00 { 62 + compatible = "atmel,at91rm9200-pmc"; 63 + reg = <0xfffffc00 0x100>; 64 + }; 65 + 61 66 pit: timer@fffffe30 { 62 67 compatible = "atmel,at91sam9260-pit"; 63 68 reg = <0xfffffe30 0xf>;
+11
arch/arm/boot/dts/at91sam9x5cm.dtsi
··· 12 12 reg = <0x20000000 0x8000000>; 13 13 }; 14 14 15 + clocks { 16 + #address-cells = <1>; 17 + #size-cells = <1>; 18 + ranges; 19 + 20 + main_clock: clock@0 { 21 + compatible = "atmel,osc", "fixed-clock"; 22 + clock-frequency = <12000000>; 23 + }; 24 + }; 25 + 15 26 ahb { 16 27 nand0: nand@40000000 { 17 28 nand-bus-width = <8>;
+11
arch/arm/boot/dts/usb_a9g20.dts
··· 20 20 reg = <0x20000000 0x4000000>; 21 21 }; 22 22 23 + clocks { 24 + #address-cells = <1>; 25 + #size-cells = <1>; 26 + ranges; 27 + 28 + main_clock: clock@0 { 29 + compatible = "atmel,osc", "fixed-clock"; 30 + clock-frequency = <12000000>; 31 + }; 32 + }; 33 + 23 34 ahb { 24 35 apb { 25 36 dbgu: serial@fffff200 {
+51 -5
arch/arm/mach-at91/clock.c
··· 23 23 #include <linux/delay.h> 24 24 #include <linux/clk.h> 25 25 #include <linux/io.h> 26 + #include <linux/of_address.h> 26 27 27 28 #include <mach/hardware.h> 28 29 #include <mach/at91_pmc.h> ··· 672 671 uhpck.rate_hz /= 1 + ((at91_pmc_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); 673 672 } 674 673 675 - int __init at91_clock_init(unsigned long main_clock) 674 + static int __init at91_pmc_init(unsigned long main_clock) 676 675 { 677 676 unsigned tmp, freq, mckr; 678 677 int i; 679 678 int pll_overclock = false; 680 - 681 - at91_pmc_base = ioremap(AT91_PMC, 256); 682 - if (!at91_pmc_base) 683 - panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC); 684 679 685 680 /* 686 681 * When the bootloader initialized the main oscillator correctly, ··· 797 800 ((unsigned) main_clock % 1000000) / 1000); 798 801 799 802 return 0; 803 + } 804 + 805 + #if defined(CONFIG_OF) 806 + static struct of_device_id pmc_ids[] = { 807 + { .compatible = "atmel,at91rm9200-pmc" }, 808 + { /*sentinel*/ } 809 + }; 810 + 811 + static struct of_device_id osc_ids[] = { 812 + { .compatible = "atmel,osc" }, 813 + { /*sentinel*/ } 814 + }; 815 + 816 + int __init at91_dt_clock_init(void) 817 + { 818 + struct device_node *np; 819 + u32 main_clock = 0; 820 + 821 + np = of_find_matching_node(NULL, pmc_ids); 822 + if (!np) 823 + panic("unable to find compatible pmc node in dtb\n"); 824 + 825 + at91_pmc_base = of_iomap(np, 0); 826 + if (!at91_pmc_base) 827 + panic("unable to map pmc cpu registers\n"); 828 + 829 + of_node_put(np); 830 + 831 + /* retrieve the freqency of fixed clocks from device tree */ 832 + np = of_find_matching_node(NULL, osc_ids); 833 + if (np) { 834 + u32 rate; 835 + if (!of_property_read_u32(np, "clock-frequency", &rate)) 836 + main_clock = rate; 837 + } 838 + 839 + of_node_put(np); 840 + 841 + return at91_pmc_init(main_clock); 842 + } 843 + #endif 844 + 845 + int __init at91_clock_init(unsigned long main_clock) 846 + { 847 + at91_pmc_base = ioremap(AT91_PMC, 256); 848 + if (!at91_pmc_base) 849 + panic("Impossible to ioremap AT91_PMC 0x%x\n", AT91_PMC); 850 + 851 + return at91_pmc_init(main_clock); 800 852 } 801 853 802 854 /*
+1
arch/arm/mach-at91/generic.h
··· 53 53 extern void __init at91sam9g45_set_console_clock(int id); 54 54 #ifdef CONFIG_AT91_PMC_UNIT 55 55 extern int __init at91_clock_init(unsigned long main_clock); 56 + extern int __init at91_dt_clock_init(void); 56 57 #else 57 58 static int inline at91_clock_init(unsigned long main_clock) { return 0; } 58 59 #endif
+1 -2
arch/arm/mach-at91/setup.c
··· 292 292 /* temporary until have the ramc binding*/ 293 293 at91_boot_soc.ioremap_registers(); 294 294 295 - /* temporary until have the pmc binding */ 296 295 /* Init clock subsystem */ 297 - at91_clock_init(12000000); 296 + at91_dt_clock_init(); 298 297 299 298 /* Register the processor-specific clocks */ 300 299 at91_boot_soc.register_clocks();