ARM: realview: basic device tree implementation
Subsystems (6)
PATCH 1/1 ARM: realview: basic device tree implementation
This implements basic device tree boot support for the RealView platforms, with a basic device tree for ARM PB1176 as an example.
The implementation is done with a new DT-specific board file using only pre-existing bindings for the basic IRQ, timer and serial port drivers. A new compatible type is added to the GIC for the ARM1176.
This implementation uses the MFD syscon handle from day one to access the system controller registers, and register the devices using the SoC bus.
--- Documentation/devicetree/bindings/arm/arm-boards | 53 ++++++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/arm-realview-pb1176.dts | 165 ++++++++++++++++ arch/arm/mach-realview/Kconfig | 10 + arch/arm/mach-realview/Makefile | 1 + arch/arm/mach-realview/realview-dt.c | 231 +++++++++++++++++++++++ arch/arm/mm/Kconfig | 2 +- drivers/irqchip/irq-gic.c | 1 + 8 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/arm-realview-pb1176.dts create mode 100644 arch/arm/mach-realview/realview-dt.c
Documentation/devicetree/bindings/arm/arm-boards +53 -0
@@ -86,3 +86,56 @@ Interrupt controllers: compatible = "arm,versatile-sic"; interrupt-controller; #interrupt-cells = <1>; + + +ARM RealView Boards +------------------- +The RealView boards cover tailored evaluation boards that are used to explore +the ARM11 and Cortex A-8 and Cortex A-9 processors. + +Required properties (in root node): + /* RealView Emulation Baseboard */ + compatible = "arm,realview-eb"; + /* RealView Platform Baseboard for ARM1176JZF-S */ + compatible = "arm,realview-pb1176"; + /* RealView Platform Baseboard for ARM11 MPCore */ + compatible = "arm,realview-pb11mp"; + /* RealView Platform Baseboard for Cortex A-8 */ + compatible = "arm,realview-pba8"; + /* RealView Platform Baseboard Explore for Cortex A-9 */ + compatible = "arm,realview-pbx"; + +Required nodes: + +- syscon: the root node of the Integrator platforms must have a + system controller node pointing to the control registers, + with the compatible string + "arm,realview-syscon", "syscon" + + Required properties for the system controller: + - regs: the location and size of the system controller registers, + one range of 0x1000 bytes. + +Example: + +/dts-v1/; +#include <dt-bindings/interrupt-controller/irq.h> +#include "skeleton.dtsi" + +/ { + model = "ARM RealView PB1176 with device tree"; + compatible = "arm,realview-pb1176"; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + syscon: syscon at 10000000 { + compatible = "arm,realview-syscon", "syscon"; + reg = <0x10000000 0x1000>; + }; + + }; +};
arch/arm/boot/dts/Makefile +1 -0
@@ -234,6 +234,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ dra7-evm.dtb dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb +dtb-$(CONFIG_ARCH_REALVIEW) += arm-realview-pb1176.dtb dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ ste-hrefprev60-stuib.dtb \ ste-hrefprev60-tvk.dtb \
arch/arm/boot/dts/arm-realview-pb1176.dts new file +165 -0
165 lines not on this page · raw message
arch/arm/mach-realview/Kconfig +10 -0
@@ -1,6 +1,16 @@ menu "RealView platform type" depends on ARCH_REALVIEW +config REALVIEW_DT + bool "Support RealView(R) Device Tree based boot" + select ARM_GIC + select USE_OF + select SOC_BUS + select MFD_SYSCON + help + Include support for booting the ARM(R) RealView(R) evaluation + boards using a device tree machine description. + config MACH_REALVIEW_EB bool "Support RealView(R) Emulation Baseboard" select ARM_GIC
arch/arm/mach-realview/Makefile +1 -0
@@ -3,6 +3,7 @@ # obj-y := core.o +obj-$(CONFIG_REALVIEW_DT) += realview-dt.o obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o
arch/arm/mach-realview/realview-dt.c new file +231 -0
231 lines not on this page · raw message
arch/arm/mm/Kconfig +1 -1
@@ -929,7 +929,7 @@ config ARM_L1_CACHE_SHIFT config ARM_DMA_MEM_BUFFERABLE bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7 depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \ - MACH_REALVIEW_PB11MP) + MACH_REALVIEW_PB11MP || REALVIEW_DT) default y if CPU_V6 || CPU_V6K || CPU_V7 help Historically, the kernel has used strongly ordered mappings to
drivers/irqchip/irq-gic.c +1 -0
@@ -1006,6 +1006,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) }IRQCHIP_DECLARE (cortex_a15_gic,"arm,cortex-a15-gic" , gic_of_init);IRQCHIP_DECLARE (cortex_a9_gic,"arm,cortex-a9-gic" , gic_of_init); +IRQCHIP_DECLARE (arm1176jzf_gic,"arm,arm1176jzf-gic" , gic_of_init);IRQCHIP_DECLARE (msm_8660_qgic,"qcom,msm-8660-qgic" , gic_of_init);IRQCHIP_DECLARE (msm_qgic2,"qcom,msm-qgic2" , gic_of_init);
Signature · 1 line
1.8.5.3
Arnd Bergmann
maintainerPATCH 1/1 ARM: realview: basic device tree implementation
Quoted 8 lines · On Wednesday 26 March 2014 10:27:40 Linus Walleij wrote:
This implements basic device tree boot support for the RealView platforms, with a basic device tree for ARM PB1176 as an example.
The implementation is done with a new DT-specific board file using only pre-existing bindings for the basic IRQ, timer and serial port drivers. A new compatible type is added to the GIC for the ARM1176.
Quoted 5 lines
This implementation uses the MFD syscon handle from day one to access the system controller registers, and register the devices using the SoC bus.
Signed-off-by Linus Walleij <[email protected]>
Ah, very nice!
Quoted 11 lines
Documentation/devicetree/bindings/arm/arm-boards +11
-0+ +ARM RealView Boards +------------------- +The RealView boards cover tailored evaluation boards that are used to explore +the ARM11 and Cortex A-8 and Cortex A-9 processors. + +Required properties (in root node): + /* RealView Emulation Baseboard */ + compatible = "arm,realview-eb"; + /* RealView Platform Baseboard for ARM1176JZF-S */ + compatible = "arm,realview-pb1176";
Documentation/devicetree/bindings/arm/arm-boards Interrupt controllers: · line 110
Quoted 10 lines
Documentation/devicetree/bindings/arm/arm-boards +10
-0+ /* RealView Platform Baseboard for ARM11 MPCore */ + compatible = "arm,realview-pb11mp"; + /* RealView Platform Baseboard for Cortex A-8 */ + compatible = "arm,realview-pba8"; + /* RealView Platform Baseboard Explore for Cortex A-9 */ + compatible = "arm,realview-pbx"; + +Required nodes: + +- syscon: the root node of the Integrator platforms must have a
Realview
arch/arm/boot/dts/arm-realview-pb1176.dts line 117
Quoted 8 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +8
-0+ timer01: timer at 10104000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x10104000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>, <0 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&timclk>, <&timclk>, <&pclk>; + clock-names = "timclk1", "timclk2", "apb_pclk"; + };
In the binding, the clock names are "timer1", "timer2", "apb_pclk". What is going on here?
arch/arm/boot/dts/arm-realview-pb1176.dts line 163
Quoted 9 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +9
-0+ + pb1176_serial3: uart at 1010f000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1010f000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uartclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + };
Here, the binding says:
- clocks: When present, must refer to exactly one clock named
"apb_pclk"
Quoted 28 lines
arch/arm/mach-realview/realview-dt.c new file +28
-0+static void __init realview_dt_init_machine (void ) +{ +struct device_node *root; +struct device_node *syscon; +struct soc_device *soc_dev; +struct soc_device_attribute *soc_dev_attr; +struct device *parent; +u32 coreid; +int ret; + +#ifdef CONFIG_CACHE_L2X0 +if (of_machine_is_compatible ("arm,realview-eb" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled +* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00790000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb1176" )) +/* +* 128Kb (16Kb/way) 8-way associativity. +* evmon/parity/share enabled. +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb11mp" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled
arch/arm/mach-realview/realview-dt.c line 93
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); + else if (of_machine_is_compatible("arm,realview-pbx")) +/* +* 16KB way size, 8-way associativity, parity disabled +* Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... +*/ +l2x0_of_init (0x02520000 ,0xc0000fff ); +#endif
Russell just posted a long series of l2x0 cleanup patches. One of the things coming out of that was that we should never need to pass values like this here. The registers are typically initialized to a hardwired default that should be ok, and if not, the boot loader should set them up correctly. Can you print out the boot-time values to see if realview gets this wrong?
If Linux has to override the register, we should have the correct setting in DT and make l2x0_of_init do the right thing itself.
Quoted 33 lines
arch/arm/mach-realview/realview-dt.c new file +33
-0+/* Here we create an SoC device for the root node */ + root =of_find_node_by_path ("/" ); +if (!root) +return ; + syscon =of_find_matching_node (root, realview_syscon_match); +if (!syscon) +return ; + + soc_dev_attr =kzalloc (sizeof (*soc_dev_attr),GFP_KERNEL ); +if (!soc_dev_attr) +return ; + ret =of_property_read_string (root,"compatible" , + &soc_dev_attr->soc_id); +if (ret) +return ; + ret =of_property_read_string (root,"model" , &soc_dev_attr->machine); +if (ret) +return ; + soc_dev_attr->family ="RealView" ; + soc_dev =soc_device_register (soc_dev_attr); +if (IS_ERR (soc_dev)) { +kfree (soc_dev_attr); +return ; + } + parent =soc_device_to_device (soc_dev); + ret =of_platform_populate (root, of_default_bus_match_table, +NULL , parent); +if (ret) { +pr_crit ("could not populate device tree\n" ); +return ; + } + + syscon_regmap =syscon_node_to_regmap (syscon);
arch/arm/mach-realview/realview-dt.c line 137
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+if (IS_ERR (syscon_regmap)) { +pr_crit ("could not locate syscon regmap\n" ); +return ; + } + ret =regmap_read (syscon_regmap,REALVIEW_SYS_ID_OFFSET , &coreid); +if (ret) +return ; +pr_info ("RealView Syscon Core ID: 0x%08x\n" , coreid); +/* FIXME: add attributes for SoC to sysfs */ +}
I would not register a "soc" device for the root node, but rather reorganize the DT to put all soc specific nodes under a combined soc node. I suppose that could actually be the syscon node itself.
arch/arm/mach-realview/realview-dt.c line 149
Quoted 11 lines
arch/arm/mach-realview/realview-dt.c new file +11
-0+static void realview_dt_fixup (struct tag *tags,char **from, +struct meminfo *meminfo) +{ +/* +* RealView PB1176 only has 128MB of RAM mapped at 0. +*/ +if (of_machine_is_compatible ("arm,realview-pb1176" )) { + meminfo->bank[0 ].start =0 ; + meminfo->bank[0 ].size =SZ_128M ; + meminfo->nr_banks =1 ; + }
This one should come right from DT I think.
Quoted 5 lines
arch/arm/mach-realview/realview-dt.c new file +5
-0+#ifdef CONFIG_SPARSEMEM +/* +* Memory configuration with SPARSEMEM enabled on RealView PBX (see +* asm/mach/memory.h for more information). +*/
arch/arm/mach-realview/realview-dt.c line 164
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+ else if (of_machine_is_compatible("arm,realview-pbx")) { + meminfo->bank[0 ].start =0 ; + meminfo->bank[0 ].size =SZ_256M ; + meminfo->bank[1 ].start =0x20000000 ; + meminfo->bank[1 ].size =SZ_512M ; + meminfo->bank[2 ].start =0x80000000 ; + meminfo->bank[2 ].size =SZ_256M ; + meminfo->nr_banks =3 ; + } +#endif
This one too, but I'm not completely sure about it. Do you see a reason for the kernel to override the memory location on PBX?
Quoted 7 lines
arch/arm/mach-realview/realview-dt.c new file +7
-0+/* +* Generic RealView fixup +* Most RealView platforms have 512MB contiguous RAM at 0x70000000. +* Half of this is mirrored at 0. +*/ + else { +#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
arch/arm/mach-realview/realview-dt.c line 181
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+ meminfo->bank[0 ].start =0x70000000 ; + meminfo->bank[0 ].size =SZ_512M ; + meminfo->nr_banks =1 ; +#else + meminfo->bank[0 ].start =0 ; + meminfo->bank[0 ].size =SZ_256M ; + meminfo->nr_banks =1 ; +#endif + } +}
And this one is where it gets tricky. We don't have a good way to describe memory aliases in DT, but we need the start of memory to match PHYS_OFFSET if CONFIG_SPARSEMEM is set (which implies !CONFIG_REALVIEW_HIGH_PHYS_OFFSET), or if we are running a no-MMU kernel. I have to think about this some more.
Quoted 19 lines
arch/arm/mach-realview/realview-dt.c new file +19
-0+static void realview_dt_restart (enum reboot_mode mode,const char *cmd) +{ +if (IS_ERR (syscon_regmap)) +return ; + +/* Unlock the reset register */ +regmap_write (syscon_regmap,REALVIEW_SYS_LOCK_OFFSET , +REALVIEW_SYS_LOCK_VAL ); +/* Then hit reset on the different machines */ +if (of_machine_is_compatible ("arm,realview-eb" )) { +regmap_write (syscon_regmap, +REALVIEW_SYS_RESETCTL_OFFSET ,0x0008 ); + }else if (of_machine_is_compatible ("arm,realview-pb1176" )) { +regmap_write (syscon_regmap, +REALVIEW_SYS_RESETCTL_OFFSET ,0x0100 ); + }else if (of_machine_is_compatible ("arm,realview-pb11mp" ) || +of_machine_is_compatible ("arm,realview-pba8" )) { +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x0000 );
arch/arm/mach-realview/realview-dt.c line 211
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x0004 ); + }else if (of_machine_is_compatible ("arm,realview-pbx" )) { +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x00f0 ); +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x00f4 ); + } +dsb (); +}
I'd be much happier if we had a separate device node to match against, rather than using of_machine_is_compatible(). That would allow us to later move this code out into a separate driver. Note that I'd still hope to one day have an empty directory for all the ARM reference platforms.
arch/arm/mach-realview/realview-dt.c line 230
Quoted 9 lines
arch/arm/mach-realview/realview-dt.c new file +9
-0+DT_MACHINE_START (REALVIEW_DT ,"ARM RealView Machine (Device Tree Support)" ) + .fixup = realview_dt_fixup, + .map_io = realview_dt_map_io, + .init_machine = realview_dt_init_machine, +#ifdef CONFIG_ZONE_DMA + .dma_zone_size = SZ_256M, +#endif + .dt_compat = realview_dt_platform_compat, + .restart = realview_dt_restart,
This isn't specific to the DT version of realview, but what happens if CONFIG_ZONE_DMA is disabled?
Arnd
Arnd Bergmann
maintainerPATCH 1/1 ARM: realview: basic device tree implementation
Quoted 15 lines · On Wednesday 26 March 2014 11:56:30 Arnd Bergmann wrote:
Quoted 15 lines
(quoted diff) +15
-0+ /* + * Generic RealView fixup + * Most RealView platforms have 512MB contiguous RAM at 0x70000000. + * Half of this is mirrored at 0. + */ + else { +#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET + meminfo->bank[0].start = 0x70000000; + meminfo->bank[0].size = SZ_512M; + meminfo->nr_banks = 1; +#else + meminfo->bank[0].start = 0; + meminfo->bank[0].size = SZ_256M; + meminfo->nr_banks = 1; +#endif
Quoted 9 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ } +}And this one is where it gets tricky. We don't have a good way to describe memory aliases in DT, but we need the start of memory to match
PHYS_OFFSETifCONFIG_SPARSEMEMis set (which implies !CONFIG_REALVIEW_HIGH_PHYS_OFFSET), or if we are running a no-MMU kernel. I have to think about this some more.
I've thought about it some more. We can actually get rid of the CONFIG_REALVIEW_HIGH_PHYS_OFFSET option entirely for any case except CONFIG_XIP_KERNEL by using ARM_PATCH_PHYS_VIRT and relying on the ATAGS or DT to pass the correct memory location. Unfortunately, I don't know if the ATAGS are actually correct in common boot loaders, since the kernel has been overriding them for ages.
With SPARSEMEM enabled, we already depend on REALVIEW_HIGH_PHYS_OFFSET being disabled, and we also use ARM_PATCH_PHYS_VIRT by default (it is not disabled in realview_defconfig).
The dependencies are really:
* The value of PHYS_OFFSET must match the address to which the kernel is loaded at boot time (currently enforced using 'make uImage').
* We could use SPARSEMEM in order to use all 512MB of RAM on realview-eb/pb11mp/pb-a8, but this is prevented by the definition of __phys_to_virt/__virt_to_phys, since it puts the 0x20000000 physical memory segment into the middle! This is in theory fixable, but I'd rather not add more hacks on top. I don't see anything that prevents us from using SPARSEMEM on older realview machines with PHYS_OFFSET=0.
* The board files always ignore the memory passed in the ATAGS and set what they think is correct. I consider this a bad idea, in particular because it prevents us from using the -m option in qemu. We should not do this with DT. If we just trust the DT to contain correct data, we don't actually need the REALVIEW_HIGH_PHYS_OFFSET setting,
Catalin originally added the sparsemem hack. I asked him today about it, and he also thinks that sparsemem without the hack should work, as long as there is highmem support. I think we can either do away with it entirely, or use the patch below to keep it alive.
I'd prefer not to add any memory location fixup to the realview-dt implementation, but it seems hard to kill it off for the ATAGS based board files, in particular because the information passed by qemu seems to be wrong more often than not (at least if I read the qemu right), and we never relied on it in the past. We might be able to make that a compile-time or boot-time option though.
Arnd
arch/arm/Kconfig +0 -1
@@ -236,7 +236,6 @@ config ARM_PATCH_PHYS_VIRT bool "Patch physical to virtual translations at runtime" if BROKEN_MULTIPLATFORM default y depends on !XIP_KERNEL && MMU - depends on !ARCH_REALVIEW || !SPARSEMEM help Patch phys-to-virt and virt-to-phys translation functions at boot and module load time according to the position of the
arch/arm/mach-realview/Kconfig +19 -2
@@ -121,7 +121,7 @@ config MACH_REALVIEW_PBA8 config MACH_REALVIEW_PBX bool "Support RealView(R) Platform Baseboard Explore" - select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET + select ARCH_SPARSEMEM_ENABLE if CPU_V7 select ARM_GIC select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP
@@ -165,7 +165,7 @@ config MACH_REALVIEW_AUTO config REALVIEW_HIGH_PHYS_OFFSET bool "High physical base address for the RealView platform" - depends on MMU && !MACH_REALVIEW_PB1176 + depends on MMU && !MACH_REALVIEW_PB1176 && !ARM_PATCH_PHYS_VIRT default y help RealView boards other than PB1176 have the RAM available at
@@ -175,4 +175,21 @@ config REALVIEW_HIGH_PHYS_OFFSET offset. On the PBX board, disabling this option allows 1GB of RAM to be used with SPARSEMEM. +config REALVIEW_PBX_SPARSEMEM_HACK + bool "Hack to avoid highmem on Realview-PBX" + depends on SPARSEMEM && MMU + depends on MACH_REALVIEW_PBX + depends on !(MACH_REALVIEW_EB || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBA8 || MACH_REALVIEW_DT) + depends on !REALVIEW_HIGH_PHYS_OFFSET + depends on !ARM_PATCH_PHYS_VIRT + help + Realview-PBX uses noncontiguous memory that is spread over + more than 2GB of physical address space, which means that in + order to access it, we have to either enable HIGHMEM or + VMSPLIT_1G, both of which come with a performance impact. + As a third alternative, this rearranges the kernel virtual + memory space to cover all the discontiguous memory on + Realview PBX, with the main cost of breaking support for + any other hardware. + endmenu
arch/arm/mach-realview/include/mach/memory.h +7 -7
@@ -31,6 +31,11 @@#ifdef CONFIG_SPARSEMEM +/* these can be moved to arm/memory.h when we get to support multiplatform */ +#define MAX_PHYSMEM_BITS 32 +#define SECTION_SIZE_BITS 28 + +#ifdef CONFIG_REALVIEW_PBX_SPARSEMEM_HACK /* * Sparsemem definitions for RealView PBX. *
@@ -45,13 +50,6 @@* 512MB @ 0x20000000 -> PAGE_OFFSET + 0x10000000 * 256MB @ 0x80000000 -> PAGE_OFFSET + 0x30000000 */ -#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET -#error "SPARSEMEM not available with REALVIEW_HIGH_PHYS_OFFSET" -#endif - -#define MAX_PHYSMEM_BITS 32 -#define SECTION_SIZE_BITS 28 -/* bank page offsets */ #define PAGE_OFFSET1 (PAGE_OFFSET + 0x10000000)#define PAGE_OFFSET2 (PAGE_OFFSET + 0x30000000)
@@ -68,6 +66,8 @@ (virt) >= PAGE_OFFSET1 ? (virt) - PAGE_OFFSET1 + 0x20000000 : \ (virt) - PAGE_OFFSET) +#endif +#endif /* CONFIG_SPARSEMEM */ #endif
PATCH 1/1 ARM: realview: basic device tree implementation
Quoted 2 lines · Arnd Bergmann
I don't know if the ATAGS are actually correct in common boot loaders, since the kernel has been overriding them for ages.
The RealView U-Boot has not seen a commit since 2010 when Peter Pearse retired but appears to pass incorrect ATAGs, 128MiB @ 0x0 for all RealView variants.
But we need not worry about that for the DT boot path so much as we can fix that up, just for legacy boots.
Yours,
Linus Walleij
PATCH 1/1 ARM: realview: basic device tree implementation
In reply to Arnd BergmannQuoted 4 lines · Arnd Bergmann
Catalin originally added the sparsemem hack. I asked him today about it, and he also thinks that sparsemem without the hack should work, as long as there is highmem support. I think we can either do away with it entirely, or use the patch below to keep it alive.
IMO the patch make things worse. I'd just say we switch it to use highmem and get rid of the madness.
Anyone claiming to be running performance-critical loads on the PBX is either insane or a liar.
Yours,
Linus Walleij
Arnd Bergmann
maintainerPATCH 1/1 ARM: realview: basic device tree implementation
Quoted 7 lines · On Thursday 08 May 2014 13:20:19 Linus Walleij wrote:
Quoted 4 lines · Arnd Bergmann
Catalin originally added the sparsemem hack. I asked him today about it, and he also thinks that sparsemem without the hack should work, as long as there is highmem support. I think we can either do away with it entirely, or use the patch below to keep it alive.
Quoted 5 lines
IMO the patch make things worse. I'd just say we switch it to use highmem and get rid of the madness.
Anyone claiming to be running performance-critical loads on the PBX is either insane or a liar.
Ok, definitely fine with me.
Arnd
PATCH 1/1 ARM: realview: basic device tree implementation
In reply to Arnd BergmannQuoted 11 lines · Arnd Bergmann
arch/arm/boot/dts/arm-realview-pb1176.dts line 117
Quoted 8 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +8
-0+ timer01: timer at 10104000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x10104000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>, <0 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&timclk>, <&timclk>, <&pclk>; + clock-names = "timclk1", "timclk2", "apb_pclk"; + };In the binding, the clock names are "timer1", "timer2", "
apb_pclk". What is going on here?
What is going on is actually pretty confusing. The code just looks for clocks at index 0 and 1:
clk1 = of_clk_get(np, 0);
clk2 = of_clk_get(np, 1);
The binding says two things:
" 3 clocks, the order is timer0 clock, timer1 clock, apb_pclk"
Then the example is:
clock-names = "timer1", "timer2", "apb_pclk";
One is indexed from zero, the other from 1.
Then the precursive examples in arch/arm/boot/dts:
vexpress-v2m.dtsi:
clock-names = "timclken1", "timclken2", "apb_pclk";
hi3620.dtsi:
clocks = <&clock HI3620_TIMER2_MUX>, <&clock HI3620_TIMER3_MUX>; clock-names = "apb_pclk";
(This latter thing is especially weird, it's probably one gate for each timer, but the apb_pclk is jammed together with the first of them for unclear reasons.)
I don't really know what to do here. I have followed the example binding and use timer1, timer2 for v2.
Quoted 10 lines
arch/arm/boot/dts/arm-realview-pb1176.dts line 163
Quoted 9 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +9
-0+ + pb1176_serial3: uart at 1010f000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1010f000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uartclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + };
Quoted 4 lines
Here, the binding says:
- clocks: When present, must refer to exactly one clock named
"apb_pclk"
That is a flat out lie, as can be seen from the implementation and all device trees. I'll send a patch fixing up the binding doc. I sent a separate patch to fix up this mess.
Quoted 34 lines
Quoted 34 lines
arch/arm/mach-realview/realview-dt.c new file +34
-0+static void __init realview_dt_init_machine (void ) +{ +struct device_node *root; +struct device_node *syscon; +struct soc_device *soc_dev; +struct soc_device_attribute *soc_dev_attr; +struct device *parent; +u32 coreid; +int ret; + +#ifdef CONFIG_CACHE_L2X0 +if (of_machine_is_compatible ("arm,realview-eb" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled +* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00790000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb1176" )) +/* +* 128Kb (16Kb/way) 8-way associativity. +* evmon/parity/share enabled. +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb11mp" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled +* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pbx" )) +/* +* 16KB way size, 8-way associativity, parity disabled
Quoted 8 lines
arch/arm/mach-realview/realview-dt.c line 93
Quoted 4 lines
arch/arm/mach-realview/realview-dt.c new file +4
-0+* Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... +*/ +l2x0_of_init (0x02520000 ,0xc0000fff ); +#endif Russell just posted a long series of l2x0 cleanup patches. One of the things coming out of that was that we should never need to pass values like this here.
Yeah I knew this would be an area of contention...
Quoted 4 lines
The registers are typically initialized
to a hardwired default that should be ok, and if not, the boot loader should set them up correctly. Can you print out the boot-time values to see if realview gets this wrong?
I can do that for the PB1176, but I have no access to the other physical platforms :-/
This was just copied from the present mach code as it stands.
Quoted 40 lines
Quoted 40 lines
arch/arm/mach-realview/realview-dt.c new file +40
-0+/* Here we create an SoC device for the root node */ + root =of_find_node_by_path ("/" ); +if (!root) +return ; + syscon =of_find_matching_node (root, realview_syscon_match); +if (!syscon) +return ; + + soc_dev_attr =kzalloc (sizeof (*soc_dev_attr),GFP_KERNEL ); +if (!soc_dev_attr) +return ; + ret =of_property_read_string (root,"compatible" , + &soc_dev_attr->soc_id); +if (ret) +return ; + ret =of_property_read_string (root,"model" , &soc_dev_attr->machine); +if (ret) +return ; + soc_dev_attr->family ="RealView" ; + soc_dev =soc_device_register (soc_dev_attr); +if (IS_ERR (soc_dev)) { +kfree (soc_dev_attr); +return ; + } + parent =soc_device_to_device (soc_dev); + ret =of_platform_populate (root, of_default_bus_match_table, +NULL , parent); +if (ret) { +pr_crit ("could not populate device tree\n" ); +return ; + } + + syscon_regmap =syscon_node_to_regmap (syscon); +if (IS_ERR (syscon_regmap)) { +pr_crit ("could not locate syscon regmap\n" ); +return ; + } + ret =regmap_read (syscon_regmap,REALVIEW_SYS_ID_OFFSET , &coreid); +if (ret) +return ;
Quoted 8 lines
arch/arm/mach-realview/realview-dt.c line 137
Quoted 3 lines
arch/arm/mach-realview/realview-dt.c new file +3
-0+pr_info ("RealView Syscon Core ID: 0x%08x\n" , coreid); +/* FIXME: add attributes for SoC to sysfs */ +}I would not register a "soc" device for the root node, but rather reorganize the DT to put all soc specific nodes under a combined soc node. I suppose that could actually be the syscon node itself.
I'm not following this comment. The device tree is already organized around a soc {} top-level node. The SoC device is a bus, the idea is to group the devices underneath this bus as discussed between Greg and Lee in the past, and thus make it a natural point to tie in the sysfs entries for SoC information as is done for example in arch/arm/mach-integrator/core.c
(Paul Walmsley recently brought up the question whether such "drivers" should live under drivers/soc but that is still an open question.)
Quoted 5 lines
Quoted 5 lines
arch/arm/mach-realview/realview-dt.c new file +5
-0+static void realview_dt_fixup (struct tag *tags,char **from, +struct meminfo *meminfo) +{ +/* +* RealView PB1176 only has 128MB of RAM mapped at 0.
Quoted 8 lines
arch/arm/mach-realview/realview-dt.c line 149
Quoted 6 lines
arch/arm/mach-realview/realview-dt.c new file +6
-0+*/ +if (of_machine_is_compatible ("arm,realview-pb1176" )) { + meminfo->bank[0 ].start =0 ; + meminfo->bank[0 ].size =SZ_128M ; + meminfo->nr_banks =1 ; + }This one should come right from DT I think.
OK this seems to work.
Quoted 10 lines
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+#ifdef CONFIG_SPARSEMEM +/* +* Memory configuration with SPARSEMEM enabled on RealView PBX (see +* asm/mach/memory.h for more information). +*/ + else if (of_machine_is_compatible("arm,realview-pbx")) { + meminfo->bank[0 ].start =0 ; + meminfo->bank[0 ].size =SZ_256M ; + meminfo->bank[1 ].start =0x20000000 ; + meminfo->bank[1 ].size =SZ_512M ;
Quoted 8 lines
arch/arm/mach-realview/realview-dt.c line 164
Quoted 5 lines
arch/arm/mach-realview/realview-dt.c new file +5
-0+ meminfo->bank[2 ].start =0x80000000 ; + meminfo->bank[2 ].size =SZ_256M ; + meminfo->nr_banks = 3; + } +#endif This one too, but I'm not completely sure about it. Do you see a reason for the kernel to override the memory location on PBX?
No other reason than that it is sparse. Removed this too in favor of using device tree memory specs.
Quoted 15 lines
Quoted 15 lines
arch/arm/mach-realview/realview-dt.c new file +15
-0+/* +* Generic RealView fixup +* Most RealView platforms have 512MB contiguous RAM at 0x70000000. +* Half of this is mirrored at 0. +*/ + else { +#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET + meminfo->bank[0 ].start =0x70000000 ; + meminfo->bank[0 ].size =SZ_512M ; + meminfo->nr_banks =1 ; +#else + meminfo->bank[0 ].start =0 ; + meminfo->bank[0 ].size =SZ_256M ; + meminfo->nr_banks =1 ; +#endif
Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ } +}And this one is where it gets tricky. We don't have a good way to describe memory aliases in DT, but we need the start of memory to match
PHYS_OFFSETifCONFIG_SPARSEMEMis set (which implies !CONFIG_REALVIEW_HIGH_PHYS_OFFSET), or if we are running a no-MMU kernel. I have to think about this some more.
Yeah I'm completely clueless here actually. :-/
This is the point of contention we've identified earlier, the patch only take it to the front forcing us to think about what to do with this.
I'll look at your patch and see if I can get to test it on QEMU.
Quoted 27 lines
Quoted 27 lines
arch/arm/mach-realview/realview-dt.c new file +27
-0+static void realview_dt_restart (enum reboot_mode mode,const char *cmd) +{ +if (IS_ERR (syscon_regmap)) +return ; + +/* Unlock the reset register */ +regmap_write (syscon_regmap,REALVIEW_SYS_LOCK_OFFSET , +REALVIEW_SYS_LOCK_VAL ); +/* Then hit reset on the different machines */ +if (of_machine_is_compatible ("arm,realview-eb" )) { +regmap_write (syscon_regmap, +REALVIEW_SYS_RESETCTL_OFFSET ,0x0008 ); + }else if (of_machine_is_compatible ("arm,realview-pb1176" )) { +regmap_write (syscon_regmap, +REALVIEW_SYS_RESETCTL_OFFSET ,0x0100 ); + }else if (of_machine_is_compatible ("arm,realview-pb11mp" ) || +of_machine_is_compatible ("arm,realview-pba8" )) { +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x0000 ); +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x0004 ); + }else if (of_machine_is_compatible ("arm,realview-pbx" )) { +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x00f0 ); +regmap_write (syscon_regmap,REALVIEW_SYS_RESETCTL_OFFSET , +0x00f4 ); + }
Quoted 8 lines
arch/arm/mach-realview/realview-dt.c line 211
Quoted 2 lines
arch/arm/mach-realview/realview-dt.c new file +2
-0+dsb (); +}I'd be much happier if we had a separate device node to match against, rather than using
of_machine_is_compatible(). That would allow us to later move this code out into a separate driver. Note that I'd still hope to one day have an empty directory for all the ARM reference platforms.
Another case for drivers/soc I think.
The thing is that all these registers are in the pretty opaque "syscon" which has different behaviour depending on which machine's syscon it is.
I will experiment with adding individual compatible strings for each syscon variant, that is essentially just duplicating the same information as the board variant, but I don't mind...
Quoted 4 lines
Quoted 4 lines
arch/arm/mach-realview/realview-dt.c new file +4
-0+DT_MACHINE_START (REALVIEW_DT ,"ARM RealView Machine (Device Tree Support)" ) + .fixup = realview_dt_fixup, + .map_io = realview_dt_map_io, + .init_machine = realview_dt_init_machine,
Quoted 8 lines
arch/arm/mach-realview/realview-dt.c line 230
Quoted 5 lines
arch/arm/mach-realview/realview-dt.c new file +5
-0+#ifdef CONFIG_ZONE_DMA + .dma_zone_size = SZ_256M, +#endif + .dt_compat = realview_dt_platform_compat, + .restart = realview_dt_restart,This isn't specific to the DT version of realview, but what happens if
CONFIG_ZONE_DMAis disabled?
I am uncertain actually, I think DMA is only used with the PCI bus found on some RealViews.
Yours,
Linus Walleij
Rob Herring
maintainerPATCH 1/1 ARM: realview: basic device tree implementation
In reply to Linus WalleijQuoted 46 lines · Linus Walleij
This implements basic device tree boot support for the RealView platforms, with a basic device tree for ARM PB1176 as an example.
The implementation is done with a new DT-specific board file using only pre-existing bindings for the basic IRQ, timer and serial port drivers. A new compatible type is added to the GIC for the ARM1176.
This implementation uses the MFD syscon handle from day one to access the system controller registers, and register the devices using the SoC bus.
Signed-off-by Linus Walleij <[email protected]>--- Documentation/devicetree/bindings/arm/arm-boards | 53 ++++++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/arm-realview-pb1176.dts | 165 ++++++++++++++++ arch/arm/mach-realview/Kconfig | 10 + arch/arm/mach-realview/Makefile | 1 + arch/arm/mach-realview/realview-dt.c | 231 +++++++++++++++++++++++ arch/arm/mm/Kconfig | 2 +- drivers/irqchip/irq-gic.c | 1 + 8 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/arm-realview-pb1176.dts create mode 100644 arch/arm/mach-realview/realview-dt.cDocumentation/devicetree/bindings/arm/arm-boards +12
-0@@ -86,3 +86,56 @@ Interrupt controllers: compatible = "arm,versatile-sic"; interrupt-controller; #interrupt-cells = <1>; + + +ARM RealView Boards +------------------- +The RealView boards cover tailored evaluation boards that are used to explore +the ARM11 and Cortex A-8 and Cortex A-9 processors. + +Required properties (in root node): + /* RealView Emulation Baseboard */ + compatible = "arm,realview-eb"; + /* RealView Platform Baseboard for ARM1176JZF-S */ + compatible = "arm,realview-pb1176";
Documentation/devicetree/bindings/arm/arm-boards Interrupt controllers: · line 110
Quoted 10 lines
Documentation/devicetree/bindings/arm/arm-boards +10
-0+ /* RealView Platform Baseboard for ARM11 MPCore */ + compatible = "arm,realview-pb11mp"; + /* RealView Platform Baseboard for Cortex A-8 */ + compatible = "arm,realview-pba8"; + /* RealView Platform Baseboard Explore for Cortex A-9 */ + compatible = "arm,realview-pbx"; + +Required nodes: + +- syscon: the root node of the Integrator platforms must have a
It should not be the root node, but under some bus node. It seems the example and actual dts's are correct.
Documentation/devicetree/bindings/arm/arm-boards Interrupt controllers: · line 113
Quoted 3 lines
Documentation/devicetree/bindings/arm/arm-boards +3
-0+ system controller node pointing to the control registers, + with the compatible string + "arm,realview-syscon", "syscon"
As Arnd pointed out, this needs to be more specific. Versatile probably needs this too, right? I've left it hard coded so far.
Quoted 46 lines
Documentation/devicetree/bindings/arm/arm-boards +28
-0+ + Required properties for the system controller: + - regs: the location and size of the system controller registers, + one range of 0x1000 bytes. + +Example: + +/dts-v1/; +#include <dt-bindings/interrupt-controller/irq.h> +#include "skeleton.dtsi" + +/ { + model = "ARM RealView PB1176 with device tree"; + compatible = "arm,realview-pb1176"; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + syscon: syscon at 10000000 { + compatible = "arm,realview-syscon", "syscon"; + reg = <0x10000000 0x1000>; + }; + + }; +};arch/arm/boot/dts/Makefile +1
-0@@ -234,6 +234,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ dra7-evm.dtb dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb +dtb-$(CONFIG_ARCH_REALVIEW) += arm-realview-pb1176.dtb dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ ste-hrefprev60-stuib.dtb \ ste-hrefprev60-tvk.dtb \arch/arm/boot/dts/arm-realview-pb1176.dts new file +0
-0
arch/arm/boot/dts/arm-realview-pb1176.dts line 6
Quoted 6 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +6
-0@@ -0,0 +1,165 @@ +/* + * Copyright 2014 Linaro Ltd + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations:
We really need to start making dts files BSD licensed. GPL does not make sense really if the dtb is part of the firmware.
Quoted 55 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +55
-0+ * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include <dt-bindings/interrupt-controller/irq.h> +#include "skeleton.dtsi" + +/ { + model = "ARM RealView PB1176 with device tree"; + compatible = "arm,realview-pb1176"; + + chosen { }; + + aliases { + serial0 = &pb1176_serial0; + serial1 = &pb1176_serial1; + serial2 = &pb1176_serial2; + serial3 = &pb1176_serial3; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + + syscon: syscon at 10000000 { + compatible = "arm,realview-syscon", "syscon"; + reg = <0x10000000 0x1000>; + }; + + xtal24mhz: xtal24mhz at 24M { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + + timclk: timclk at 1M { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <24>; + clock-mult = <1>; + clocks = <&xtal24mhz>; + }; + + uartclk: uartclk at 24M { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <1>;
arch/arm/boot/dts/arm-realview-pb1176.dts line 71
Quoted 10 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +10
-0+ clock-mult = <1>; + clocks = <&xtal24mhz>; + }; + + /* FIXME: this actually hangs off the PLL clocks */ + pclk: pclk at 0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + };
I would move the clocks out of the soc node.
arch/arm/boot/dts/arm-realview-pb1176.dts line 75
Quoted 4 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +4
-0+ + /* Primary DevChip GIC synthesized with the CPU */ + intc_dc1176: interrupt-controller at 10120000 { + compatible = "arm,arm1176jzf-gic";
This needs to be documented.
Quoted 95 lines
arch/arm/boot/dts/arm-realview-pb1176.dts new file +90
-0+ #interrupt-cells = <3>; + #address-cells = <1>; + interrupt-controller; + reg = <0x10121000 0x1000>, + <0x10120000 0x100>; + }; + + /* This GIC on the board is cascaded off the DevChip GIC */ + intc_pb1176: interrupt-controller at 10040000 { + compatible = "arm,arm1176jzf-gic"; + #interrupt-cells = <3>; + #address-cells = <1>; + interrupt-controller; + reg = <0x10041000 0x1000>, + <0x10040000 0x100>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + }; + + L2: l2-cache { + compatible = "arm,l220-cache"; + reg = <0x10110000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>; + cache-unified; + cache-level = <2>; + }; + + pmu { + compatible = "arm,arm1176-pmu"; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + }; + + timer01: timer at 10104000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x10104000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>, <0 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&timclk>, <&timclk>, <&pclk>; + clock-names = "timclk1", "timclk2", "apb_pclk"; + }; + + timer23: timer at 10105000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x10105000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + arm,sp804-has-irq = <1>; + clocks = <&timclk>, <&timclk>, <&pclk>; + clock-names = "timclk1", "timclk2", "apb_pclk"; + }; + + pb1176_serial0: uart at 1010c000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1010c000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uartclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + pb1176_serial1: uart at 1010d000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1010d000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uartclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + pb1176_serial2: uart at 1010e000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1010e000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uartclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + pb1176_serial3: uart at 1010f000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x1010f000 0x1000>; + interrupt-parent = <&intc_dc1176>; + interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&uartclk>, <&pclk>; + clock-names = "uartclk", "apb_pclk"; + }; + }; +};arch/arm/mach-realview/Kconfig +0
-0
arch/arm/mach-realview/Kconfig line 9
Quoted 9 lines
arch/arm/mach-realview/Kconfig +6
-0@@ -1,6 +1,16 @@ menu "RealView platform type" depends on ARCH_REALVIEW +config REALVIEW_DT + bool "Support RealView(R) Device Tree based boot" + select ARM_GIC + select USE_OF + select SOC_BUS + select MFD_SYSCON
Sort.
This will probably need to be coordinated with Arnd's cpu selection rework.
Quoted 81 lines
arch/arm/mach-realview/Kconfig +4
-0+ help + Include support for booting the ARM(R) RealView(R) evaluation + boards using a device tree machine description. + config MACH_REALVIEW_EB bool "Support RealView(R) Emulation Baseboard" select ARM_GICarch/arm/mach-realview/Makefile +1
-0@@ -3,6 +3,7 @@ # obj-y := core.o +obj-$(CONFIG_REALVIEW_DT) += realview-dt.o obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.oarch/arm/mach-realview/realview-dt.c new file +56
-0@@ -0,0 +1,231 @@ +/* +* Copyright (C) 2014 Linaro Ltd. +* +* Author: Linus Walleij <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2, as +* published by the Free Software Foundation. +* +*/ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/irqchip.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> +#include <linux/sys_soc.h> +#include <linux/slab.h> +#include <asm/mach/map.h> +#include <asm/mach/arch.h> +#include <asm/hardware/cache-l2x0.h> +#include <mach/hardware.h> +#include <mach/platform.h> +#include <mach/board-eb.h> +#include <mach/board-pb1176.h> +#include <mach/board-pb11mp.h> +#include <mach/board-pbx.h> +#include "core.h" + +/* Pointer to the system controller */ +struct regmap *syscon_regmap; + +static struct map_desc realview_dt_io_desc[]__initdata = { + { +/* FIXME: static map needed for LED driver */ + .virtual =IO_ADDRESS (REALVIEW_SYS_BASE ), + .pfn =__phys_to_pfn (REALVIEW_SYS_BASE ), + .length =SZ_4K , + .type =MT_DEVICE , + }, +}; + +static void __init realview_dt_map_io (void ) +{ +iotable_init (realview_dt_io_desc,ARRAY_SIZE (realview_dt_io_desc)); +} + +static const struct of_device_id realview_syscon_match[] = { + { .compatible ="arm,realview-syscon" }, + { }, +}; + +static void __init realview_dt_init_machine (void )
arch/arm/mach-realview/realview-dt.c line 66
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+{ +struct device_node *root; +struct device_node *syscon; +struct soc_device *soc_dev; +struct soc_device_attribute *soc_dev_attr; +struct device *parent; +u32 coreid; +int ret; + +#ifdef CONFIG_CACHE_L2X0
Use IS_ENABLED
Quoted 17 lines
arch/arm/mach-realview/realview-dt.c new file +17
-0+if (of_machine_is_compatible ("arm,realview-eb" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled +* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00790000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb1176" )) +/* +* 128Kb (16Kb/way) 8-way associativity. +* evmon/parity/share enabled. +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb11mp" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled
arch/arm/mach-realview/realview-dt.c line 93
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); + else if (of_machine_is_compatible("arm,realview-pbx")) +/* +* 16KB way size, 8-way associativity, parity disabled +* Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... +*/ +l2x0_of_init (0x02520000 ,0xc0000fff ); +#endif
As Arnd pointed out, see Russell's recent L2x0 emails. Since these are L220s, you do need the way size and associativity to be initialized at least. There are standard ePAPR definitions for these which should be used.
Documenting the initial and final aux ctrl values on these platforms would be helpful for Russell's clean-up.
[snip]
arch/arm/mm/Kconfig config ARM_L1_CACHE_SHIFT · line 932
Quoted 10 lines
arch/arm/mm/Kconfig +1
-1@@ -929,7 +929,7 @@ config ARM_L1_CACHE_SHIFT config ARM_DMA_MEM_BUFFERABLE bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7 depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \ - MACH_REALVIEW_PB11MP) + MACH_REALVIEW_PB11MP || REALVIEW_DT)
Couldn't this be simplified to: depends on !(ARCH_REALVIEW && (CPU_V6 || CPU_V6K))
However, we probably will want some way to build a v6+v7 multi-platform kernel and select this option. Perhaps we need a kconfig option for "support broken v6 Realview platforms."
Rob
Arnd Bergmann
maintainerPATCH 1/1 ARM: realview: basic device tree implementation
Quoted 11 lines · On Wednesday 26 March 2014 08:59:32 Rob Herring wrote:
arch/arm/mach-realview/Kconfig line 9
Quoted 9 lines · Linus Walleij
menu "RealView platform type"
depends onARCH_REALVIEWarch/arm/mach-realview/Kconfig +6
-0+config REALVIEW_DT + bool "Support RealView(R) Device Tree based boot" + select ARM_GIC + select USE_OF + select SOC_BUS + select MFD_SYSCON
Quoted 3 lines
Sort.
This will probably need to be coordinated with Arnd's cpu selection rework.
Ignore my cpu selection patches here, we'll do those later.
Arnd
PATCH 1/1 ARM: realview: basic device tree implementation
In reply to Rob HerringQuoted 30 lines · Rob Herring
Quoted 17 lines · Linus Walleij
arch/arm/mach-realview/realview-dt.c new file +17
-0+if (of_machine_is_compatible ("arm,realview-eb" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled +* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00790000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb1176" )) +/* +* 128Kb (16Kb/way) 8-way associativity. +* evmon/parity/share enabled. +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); +else if (of_machine_is_compatible ("arm,realview-pb11mp" )) +/* +* 1MB (128KB/way), 8-way associativity, +* evmon/parity/share enabled arch/arm/mach-realview/realview-dt.c line 93
Quoted 10 lines
arch/arm/mach-realview/realview-dt.c new file +10
-0+* Bits: .... ...0 0111 1001 0000 .... .... .... +*/ +l2x0_of_init (0x00730000 ,0xfe000fff ); + else if (of_machine_is_compatible("arm,realview-pbx")) +/* +* 16KB way size, 8-way associativity, parity disabled +* Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... +*/ +l2x0_of_init (0x02520000 ,0xc0000fff ); +#endif
Quoted 7 lines
As Arnd pointed out, see Russell's recent L2x0 emails. Since these are L220s, you do need the way size and associativity to be initialized at least. There are standard ePAPR definitions for these which should be used.
Documenting the initial and final aux ctrl values on these platforms would be helpful for Russell's clean-up.
The PB1176 board has the initial value:L2X0_AUX_CTRL = 0x02020fff
I don't know how I can help out best here unfortunately, it's a little bit of a moving target I guess and admittedly my understanding of l2x0 is pretty shallow. :-/
Yours,
Linus Walleij