* [PATCH v2 02/19] OpenRISC: Device tree
[not found] <1309641352-18714-1-git-send-email-jonas@southpole.se>
@ 2011-07-02 21:15 ` Jonas Bonn
2011-07-03 18:07 ` Segher Boessenkool
2011-07-03 20:51 ` Grant Likely
0 siblings, 2 replies; 6+ messages in thread
From: Jonas Bonn @ 2011-07-02 21:15 UTC (permalink / raw)
To: linux-kernel, linux-arch; +Cc: Jonas Bonn, devicetree-discuss
The OpenRISC architecture uses the device tree infrastructure for the
platform description. This is currently limited to having a device tree
built into the kernel, but work is underway within the OpenRISC project
to define how this device tree blob should be passed into the kernel from
an external resource.
Signed-off-by: Jonas Bonn <jonas@southpole.se>
Cc: devicetree-discuss@lists.ozlabs.org
---
arch/openrisc/boot/dts/atlys.dts | 78 +++++++++++++++++++++++++
arch/openrisc/boot/dts/or1ksim.dts | 73 ++++++++++++++++++++++++
arch/openrisc/include/asm/prom.h | 92 ++++++++++++++++++++++++++++++
arch/openrisc/kernel/prom.c | 109 ++++++++++++++++++++++++++++++++++++
arch/openrisc/kernel/setup.c | 3 +-
5 files changed, 353 insertions(+), 2 deletions(-)
create mode 100644 arch/openrisc/boot/dts/atlys.dts
create mode 100644 arch/openrisc/boot/dts/or1ksim.dts
create mode 100644 arch/openrisc/include/asm/prom.h
create mode 100644 arch/openrisc/kernel/prom.c
diff --git a/arch/openrisc/boot/dts/atlys.dts b/arch/openrisc/boot/dts/atlys.dts
new file mode 100644
index 0000000..cd028b9
--- /dev/null
+++ b/arch/openrisc/boot/dts/atlys.dts
@@ -0,0 +1,78 @@
+/dts-v1/;
+/ {
+ compatible = "digilent,atlys";
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ chosen {
+ bootargs = "console=tty0 console=uart,mmio,0x90000000,115200 debug video=ocfb:640x480-16@60";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x8000000>;
+ };
+
+ cpus {
+ cpu@0 {
+ compatible = "opencores,openrisc-1200";
+ clock-frequency = <50000000>;
+ };
+ };
+
+ /* The "soc" node */
+
+ soc {
+ /* Every node with children must specify address-cells and
+ size-cells; they are not inherited */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+
+ /* This is also a 1:1 mapping but limits size of mappable
+ region to 0x40000000 */
+ ranges = <0x80000000 0x80000000 0x40000000>;
+
+ /* An alternative is to specify an empty ranges here to
+ indicates 1:1 mapping of SOC addresses (device addresses)
+ to CPU addresses */
+ /*ranges;*/
+
+ /* This SOC has only a single, implicit PIC, so define it
+ early and put the interrupt-parent property in the 'soc'
+ node so that it's inherited by all the children using
+ interrupts.
+ */
+ interrupt-parent = <&pic>;
+
+ /* Devices with interrupts need a 'parent', so we need to
+ define a controller */
+ pic: pic@0 {
+ compatible = "opencores,or1k-pic";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+
+ serial0: serial@90000000 {
+ /* FIXME: device_type is still needed here...
+ should remove requirement from of_serial driver */
+ device_type = "serial";
+ compatible = "opencores,uart", "ns16550a";
+ reg = <0x90000000 0x100>;
+ interrupts = <2>;
+ clock-frequency = <50000000>;
+ };
+
+ enet0: ethoc@92000000 {
+ compatible = "opencores,ethoc", "ethoc";
+ reg = <0x92000000 0x53>;
+ interrupts = <4>;
+ local-mac-address = [02 de ad be ef 02];
+ };
+
+ fb0: ocfb@97000000 {
+ compatible = "opencores,ocfb", "ocfb";
+ reg = <0x97000000 0x1000>;
+ };
+ };
+};
diff --git a/arch/openrisc/boot/dts/or1ksim.dts b/arch/openrisc/boot/dts/or1ksim.dts
new file mode 100644
index 0000000..6a025ea
--- /dev/null
+++ b/arch/openrisc/boot/dts/or1ksim.dts
@@ -0,0 +1,73 @@
+/dts-v1/;
+/ {
+ compatible = "opencores,or1ksim";
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ chosen {
+ bootargs = "console=uart,mmio,0x90000000,115200 debug";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x2000000>;
+ };
+
+ cpus {
+ cpu@0 {
+ compatible = "opencores,openrisc-1200";
+ clock-frequency = <20000000>;
+ };
+ };
+
+ /* The "soc" node */
+
+ soc {
+ /* Every node with children must specify address-cells and
+ size-cells; they are not inherited */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+
+ /* This is also a 1:1 mapping but limits size of mappable
+ region to 0x40000000 */
+ ranges = <0x80000000 0x80000000 0x40000000>;
+
+ /* An alternative is to specify an empty ranges here to
+ indicates 1:1 mapping of SOC addresses (device addresses)
+ to CPU addresses */
+ /*ranges;*/
+
+ /* This SOC has only a single, implicit PIC, so define it
+ early and put the interrupt-parent property in the 'soc'
+ node so that it's inherited by all the children using
+ interrupts.
+ */
+ interrupt-parent = <&pic>;
+
+ /* Devices with interrupts need a 'parent', so we need to
+ define a controller */
+ pic: pic@0 {
+ compatible = "opencores,or1k-pic";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+
+ serial0: serial@90000000 {
+ /* FIXME: device_type is still needed here...
+ should remove requirement from of_serial driver */
+ device_type = "serial";
+ compatible = "opencores,uart", "ns16550a";
+ reg = <0x90000000 0x100>;
+ interrupts = <2>;
+ clock-frequency = <20000000>;
+ };
+
+ enet0: ethoc@92000000 {
+ compatible = "opencores,ethoc", "ethoc";
+ reg = <0x92000000 0x53>;
+ interrupts = <4>;
+ local-mac-address = [02 de ad be ef 02];
+ };
+ };
+};
diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
new file mode 100644
index 0000000..3818902
--- /dev/null
+++ b/arch/openrisc/include/asm/prom.h
@@ -0,0 +1,92 @@
+/*
+ * OpenRISC Linux
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others. All original copyrights apply as per the original source
+ * declaration.
+ *
+ * OpenRISC implementation:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ * et al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/of.h> /* linux/of.h gets to determine #include ordering */
+
+#ifndef _ASM_OPENRISC_PROM_H
+#define _ASM_OPENRISC_PROM_H
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <linux/of_irq.h>
+#include <linux/of_fdt.h>
+#include <linux/of_address.h>
+#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
+/* Other Prototypes */
+extern int early_uartlite_console(void);
+
+#ifdef CONFIG_PCI
+/*
+ * PCI <-> OF matching functions
+ * (XXX should these be here?)
+ */
+struct pci_bus;
+struct pci_dev;
+extern int pci_device_from_OF_node(struct device_node *node,
+ u8 *bus, u8 *devfn);
+extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus,
+ int devfn);
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
+extern void pci_create_OF_bus_map(void);
+#endif
+
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+ unsigned long *busno, unsigned long *phys, unsigned long *size);
+
+extern void kdump_move_device_tree(void);
+
+/* CPU OF node matching */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
+
+/* Get the MAC address */
+extern const void *of_get_mac_address(struct device_node *np);
+
+/**
+ * of_irq_map_pci - Resolve the interrupt for a PCI device
+ * @pdev: the device whose interrupt is to be resolved
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+struct pci_dev;
+extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
+
+/* This routine is here to provide compatibility with how powerpc
+ * handles IRQ mapping for OF device nodes. We precompute and permanently
+ * register them in the platform_device objects, whereas powerpc computes them
+ * on request.
+ */
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_OPENRISC_PROM_H */
diff --git a/arch/openrisc/kernel/prom.c b/arch/openrisc/kernel/prom.c
new file mode 100644
index 0000000..2bb5a8c
--- /dev/null
+++ b/arch/openrisc/kernel/prom.c
@@ -0,0 +1,109 @@
+/*
+ * OpenRISC prom.c
+ *
+ * Linux architectural port borrowing liberally from similar works of
+ * others. All original copyrights apply as per the original source
+ * declaration.
+ *
+ * Modifications for the OpenRISC architecture:
+ * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Architecture specific procedures for creating, accessing and
+ * interpreting the device tree.
+ *
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/initrd.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/debugfs.h>
+#include <linux/irq.h>
+#include <linux/memblock.h>
+#include <linux/of_fdt.h>
+
+#include <asm/prom.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+extern char cmd_line[COMMAND_LINE_SIZE];
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+ size &= PAGE_MASK;
+ memblock_add(base, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return __va(memblock_alloc(size, align));
+}
+
+void __init early_init_devtree(void *params)
+{
+ u8 *alloc;
+
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, TCE reserve, and more ...
+ */
+ of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
+
+ /* Scan memory nodes and rebuild MEMBLOCKs */
+ memblock_init();
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+ /* Save command line for /proc/cmdline and then parse parameters */
+ strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+// parse_early_param();
+
+ memblock_analyze();
+
+ /* We must copy the flattend device tree from init memory to regular
+ * memory because the device tree references the strings in it
+ * directly.
+ */
+
+ alloc = __va(memblock_alloc(initial_boot_params->totalsize, PAGE_SIZE));
+
+ memcpy(alloc, initial_boot_params, initial_boot_params->totalsize);
+
+ initial_boot_params = (void *) alloc;
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init early_init_dt_setup_initrd_arch(unsigned long start,
+ unsigned long end)
+{
+ initrd_start = (unsigned long)__va(start);
+ initrd_end = (unsigned long)__va(end);
+ initrd_below_start_ok = 1;
+}
+#endif
diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
index 49342e9..6ce6583 100644
--- a/arch/openrisc/kernel/setup.c
+++ b/arch/openrisc/kernel/setup.c
@@ -173,8 +173,7 @@ void __init setup_cpuinfo(void)
unsigned long iccfgr,dccfgr;
unsigned long cache_set_size, cache_ways;;
- cpu = (struct device_node *) of_find_compatible_node(NULL,
- NULL, "opencores,openrisc-1200");
+ cpu = of_find_compatible_node(NULL, NULL, "opencores,openrisc-1200");
if (!cpu) {
panic("No compatible CPU found in device tree...\n");
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 02/19] OpenRISC: Device tree
2011-07-02 21:15 ` [PATCH v2 02/19] OpenRISC: Device tree Jonas Bonn
@ 2011-07-03 18:07 ` Segher Boessenkool
2011-07-03 20:51 ` Grant Likely
1 sibling, 0 replies; 6+ messages in thread
From: Segher Boessenkool @ 2011-07-03 18:07 UTC (permalink / raw)
To: Jonas Bonn; +Cc: linux-kernel, linux-arch, devicetree-discuss
> The OpenRISC architecture uses the device tree infrastructure for the
> platform description.
Hurray, world domination is one step closer ;-)
> + memory {
> + device_type = "memory";
> + reg = <0x00000000 0x8000000>;
> + };
Might want to write this as 0x08000000 (easier to read).
> + cpus {
> + cpu@0 {
Any node with a textual unit address (@0) needs to have a "reg" property
with the same address (and then the parent node, "cpus", should have
#address-cells and #size-cells defined, probably to 1 and 0 resp. in
this
case).
You can just name the node "cpu" here.
> + pic: pic@0 {
> + compatible = "opencores,or1k-pic";
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + };
Same thing here. Although, does your interrupt controller have any
registers?
You should describe them then.
> +
> + serial0: serial@90000000 {
> + /* FIXME: device_type is still needed here...
> + should remove requirement from of_serial driver */
> + device_type = "serial";
> + compatible = "opencores,uart", "ns16550a";
Opencores has and always will have only one UART implementation? You
should
make the "compatible" name more specific ("opencores,uart-16550a"
perhaps).
> + enet0: ethoc@92000000 {
> + compatible = "opencores,ethoc", "ethoc";
Probably shouldn't have the "ethoc" there, way too generic a name.
> + reg = <0x92000000 0x53>;
0x53? Usually you write the size of the register block that is decoded,
not just the size of the defined registers; so it would be 0x100 or
something
like that.
Segher
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 02/19] OpenRISC: Device tree
2011-07-02 21:15 ` [PATCH v2 02/19] OpenRISC: Device tree Jonas Bonn
2011-07-03 18:07 ` Segher Boessenkool
@ 2011-07-03 20:51 ` Grant Likely
[not found] ` <CACxGe6tFX=EQjaL-4EjSXquY5eh+bca29=d=cE5-YAVCUVRCvA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-04 4:58 ` Jonas Bonn
1 sibling, 2 replies; 6+ messages in thread
From: Grant Likely @ 2011-07-03 20:51 UTC (permalink / raw)
To: Jonas Bonn; +Cc: linux-kernel, linux-arch, devicetree-discuss
On Sat, Jul 2, 2011 at 3:15 PM, Jonas Bonn <jonas@southpole.se> wrote:
>
> The OpenRISC architecture uses the device tree infrastructure for the
> platform description. This is currently limited to having a device tree
> built into the kernel, but work is underway within the OpenRISC project
> to define how this device tree blob should be passed into the kernel from
> an external resource.
>
> Signed-off-by: Jonas Bonn <jonas@southpole.se>
> Cc: devicetree-discuss@lists.ozlabs.org
> ---
> arch/openrisc/boot/dts/atlys.dts | 78 +++++++++++++++++++++++++
> arch/openrisc/boot/dts/or1ksim.dts | 73 ++++++++++++++++++++++++
> arch/openrisc/include/asm/prom.h | 92 ++++++++++++++++++++++++++++++
> arch/openrisc/kernel/prom.c | 109 ++++++++++++++++++++++++++++++++++++
> arch/openrisc/kernel/setup.c | 3 +-
> 5 files changed, 353 insertions(+), 2 deletions(-)
> create mode 100644 arch/openrisc/boot/dts/atlys.dts
> create mode 100644 arch/openrisc/boot/dts/or1ksim.dts
> create mode 100644 arch/openrisc/include/asm/prom.h
> create mode 100644 arch/openrisc/kernel/prom.c
>
> diff --git a/arch/openrisc/boot/dts/atlys.dts b/arch/openrisc/boot/dts/atlys.dts
> new file mode 100644
> index 0000000..cd028b9
> --- /dev/null
> +++ b/arch/openrisc/boot/dts/atlys.dts
> @@ -0,0 +1,78 @@
> +/dts-v1/;
> +/ {
> + compatible = "digilent,atlys";
> + #size-cells = <1>;
> + #address-cells = <1>;
> +
> + chosen {
> + bootargs = "console=tty0 console=uart,mmio,0x90000000,115200 debug video=ocfb:640x480-16@60";
> + };
> +
> + memory {
memory@0
> + device_type = "memory";
> + reg = <0x00000000 0x8000000>;
> + };
> +
> + cpus {
> + cpu@0 {
> + compatible = "opencores,openrisc-1200";
> + clock-frequency = <50000000>;
As Segher metioned, the cpus node should have #address/size-cells and
the cpu@0 node should have "reg = <0>;".
> + };
> + };
> +
> + /* The "soc" node */
> +
> + soc {
> + /* Every node with children must specify address-cells and
> + size-cells; they are not inherited */
> + #address-cells = <1>;
> + #size-cells = <1>;
> + device_type = "soc";
Drop device type. device_type only makes sense for systems with real
OpenFirmware. Always use a 'compatible' property to identify a
device. In this case you probably want the compatible list to include
the name of the bus bridge plus "simple-bus".
Does it really make sense to have an SoC node for this board? I
assume this is for a soft CPU system on a Diligent FPGA board. It is
best if the device tree structure matches the actual bus layout of the
chip and/or FPGA design. If the devices are directly on the CPU bus,
then it is better to do without an soc node entirely and just put
everything at the root.
> +
> + /* This is also a 1:1 mapping but limits size of mappable
> + region to 0x40000000 */
> + ranges = <0x80000000 0x80000000 0x40000000>;
> +
> + /* An alternative is to specify an empty ranges here to
> + indicates 1:1 mapping of SOC addresses (device addresses)
> + to CPU addresses */
> + /*ranges;*/
ranges is a well documented property. You can drop the commented out
empty ranges, and the comments attached to it.
> + /* This SOC has only a single, implicit PIC, so define it
> + early and put the interrupt-parent property in the 'soc'
> + node so that it's inherited by all the children using
> + interrupts.
> + */
> + interrupt-parent = <&pic>;
Put this at the root of the tree so that every node inherits it
(unless explicitly overridden). You may very well end up with devices
at the root of the tree which are not children of the SoC node.
> +
> + /* Devices with interrupts need a 'parent', so we need to
> + define a controller */
> + pic: pic@0 {
> + compatible = "opencores,or1k-pic";
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + };
> +
> + serial0: serial@90000000 {
> + /* FIXME: device_type is still needed here...
> + should remove requirement from of_serial driver */
> + device_type = "serial";
device_type should not be necessary at all any more in the current
kernel. You can remove this now.
> + compatible = "opencores,uart", "ns16550a";
> + reg = <0x90000000 0x100>;
> + interrupts = <2>;
> + clock-frequency = <50000000>;
> + };
> +
> + enet0: ethoc@92000000 {
> + compatible = "opencores,ethoc", "ethoc";
"ethoc" is too generic. Drop it. Also, since this represents a soft
IP core, "opencores,ethoc" should probably include some indication of
which version of the core is instantiated (same goes for the other
"opencores,..." values in this file.
Finally, every new "compatible" value that is used in this device tree
needs to be documented. Look in Documentation/devicetree/bindings.
The documentation is used to guard against "binding drift" where the
meaning of a compatible property is interpreted differently by
different people.
> + reg = <0x92000000 0x53>;
> + interrupts = <4>;
> + local-mac-address = [02 de ad be ef 02];
Don't do this. If you don't have a valid Ethernet address, it is
probably better to leave the property out entirely, and let the kernel
randomly generate one.
> + };
> +
> + fb0: ocfb@97000000 {
> + compatible = "opencores,ocfb", "ocfb";
"ocfb" too generic.
> + reg = <0x97000000 0x1000>;
> + };
> + };
> +};
> diff --git a/arch/openrisc/boot/dts/or1ksim.dts b/arch/openrisc/boot/dts/or1ksim.dts
> new file mode 100644
> index 0000000..6a025ea
> --- /dev/null
> +++ b/arch/openrisc/boot/dts/or1ksim.dts
> @@ -0,0 +1,73 @@
> +/dts-v1/;
> +/ {
> + compatible = "opencores,or1ksim";
> + #size-cells = <1>;
> + #address-cells = <1>;
> +
> + chosen {
> + bootargs = "console=uart,mmio,0x90000000,115200 debug";
> + };
> +
> + memory {
> + device_type = "memory";
> + reg = <0x00000000 0x2000000>;
> + };
> +
> + cpus {
> + cpu@0 {
> + compatible = "opencores,openrisc-1200";
> + clock-frequency = <20000000>;
> + };
> + };
> +
> + /* The "soc" node */
> +
> + soc {
> + /* Every node with children must specify address-cells and
> + size-cells; they are not inherited */
> + #address-cells = <1>;
> + #size-cells = <1>;
> + device_type = "soc";
Drop device_type, blah blah blah... Most of my comments on the
previous file apply here too.
> +
> + /* This is also a 1:1 mapping but limits size of mappable
> + region to 0x40000000 */
> + ranges = <0x80000000 0x80000000 0x40000000>;
> +
> + /* An alternative is to specify an empty ranges here to
> + indicates 1:1 mapping of SOC addresses (device addresses)
> + to CPU addresses */
> + /*ranges;*/
> +
> + /* This SOC has only a single, implicit PIC, so define it
> + early and put the interrupt-parent property in the 'soc'
> + node so that it's inherited by all the children using
> + interrupts.
> + */
> + interrupt-parent = <&pic>;
> +
> + /* Devices with interrupts need a 'parent', so we need to
> + define a controller */
> + pic: pic@0 {
> + compatible = "opencores,or1k-pic";
> + #interrupt-cells = <1>;
> + interrupt-controller;
> + };
> +
> + serial0: serial@90000000 {
> + /* FIXME: device_type is still needed here...
> + should remove requirement from of_serial driver */
> + device_type = "serial";
> + compatible = "opencores,uart", "ns16550a";
> + reg = <0x90000000 0x100>;
> + interrupts = <2>;
> + clock-frequency = <20000000>;
> + };
> +
> + enet0: ethoc@92000000 {
> + compatible = "opencores,ethoc", "ethoc";
> + reg = <0x92000000 0x53>;
> + interrupts = <4>;
> + local-mac-address = [02 de ad be ef 02];
> + };
> + };
> +};
> diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
> new file mode 100644
> index 0000000..3818902
> --- /dev/null
> +++ b/arch/openrisc/include/asm/prom.h
> @@ -0,0 +1,92 @@
> +/*
> + * OpenRISC Linux
> + *
> + * Linux architectural port borrowing liberally from similar works of
> + * others. All original copyrights apply as per the original source
> + * declaration.
> + *
> + * OpenRISC implementation:
> + * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
> + * et al.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/of.h> /* linux/of.h gets to determine #include ordering */
> +
> +#ifndef _ASM_OPENRISC_PROM_H
> +#define _ASM_OPENRISC_PROM_H
> +#ifdef __KERNEL__
> +#ifndef __ASSEMBLY__
> +
> +#include <linux/types.h>
> +#include <asm/irq.h>
> +#include <asm/atomic.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_address.h>
> +#include <linux/proc_fs.h>
> +#include <linux/platform_device.h>
> +#define HAVE_ARCH_DEVTREE_FIXUPS
> +
> +/* Other Prototypes */
> +extern int early_uartlite_console(void);
> +
> +#ifdef CONFIG_PCI
> +/*
> + * PCI <-> OF matching functions
> + * (XXX should these be here?)
> + */
> +struct pci_bus;
> +struct pci_dev;
> +extern int pci_device_from_OF_node(struct device_node *node,
> + u8 *bus, u8 *devfn);
> +extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus,
> + int devfn);
> +extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
> +extern void pci_create_OF_bus_map(void);
> +#endif
> +
> +/* Parse the ibm,dma-window property of an OF node into the busno, phys and
> + * size parameters.
> + */
> +void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
> + unsigned long *busno, unsigned long *phys, unsigned long *size);
> +
> +extern void kdump_move_device_tree(void);
> +
> +/* CPU OF node matching */
> +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
> +
> +/* Get the MAC address */
> +extern const void *of_get_mac_address(struct device_node *np);
> +
> +/**
> + * of_irq_map_pci - Resolve the interrupt for a PCI device
> + * @pdev: the device whose interrupt is to be resolved
> + * @out_irq: structure of_irq filled by this function
> + *
> + * This function resolves the PCI interrupt for a given PCI device. If a
> + * device-node exists for a given pci_dev, it will use normal OF tree
> + * walking. If not, it will implement standard swizzling and walk up the
> + * PCI tree until an device-node is found, at which point it will finish
> + * resolving using the OF tree walking.
> + */
> +struct pci_dev;
> +extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
> +
> +/* This routine is here to provide compatibility with how powerpc
> + * handles IRQ mapping for OF device nodes. We precompute and permanently
> + * register them in the platform_device objects, whereas powerpc computes them
> + * on request.
> + */
> +static inline void irq_dispose_mapping(unsigned int virq)
> +{
> +}
The need for this should hopefully go away in Linux v3.1 when I get
the irq_domain stuff merged.
> +
> +#endif /* __ASSEMBLY__ */
> +#endif /* __KERNEL__ */
> +#endif /* _ASM_OPENRISC_PROM_H */
> diff --git a/arch/openrisc/kernel/prom.c b/arch/openrisc/kernel/prom.c
> new file mode 100644
> index 0000000..2bb5a8c
> --- /dev/null
> +++ b/arch/openrisc/kernel/prom.c
> @@ -0,0 +1,109 @@
> +/*
> + * OpenRISC prom.c
> + *
> + * Linux architectural port borrowing liberally from similar works of
> + * others. All original copyrights apply as per the original source
> + * declaration.
> + *
> + * Modifications for the OpenRISC architecture:
> + * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * Architecture specific procedures for creating, accessing and
> + * interpreting the device tree.
> + *
> + */
> +
> +#include <stdarg.h>
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +#include <linux/init.h>
> +#include <linux/threads.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
> +#include <linux/pci.h>
> +#include <linux/stringify.h>
> +#include <linux/delay.h>
> +#include <linux/initrd.h>
> +#include <linux/bitops.h>
> +#include <linux/module.h>
> +#include <linux/kexec.h>
> +#include <linux/debugfs.h>
> +#include <linux/irq.h>
> +#include <linux/memblock.h>
> +#include <linux/of_fdt.h>
> +
> +#include <asm/prom.h>
> +#include <asm/page.h>
> +#include <asm/processor.h>
> +#include <asm/irq.h>
> +#include <linux/io.h>
> +#include <asm/system.h>
> +#include <asm/mmu.h>
> +#include <asm/pgtable.h>
> +#include <asm/sections.h>
> +#include <asm/setup.h>
> +
> +extern char cmd_line[COMMAND_LINE_SIZE];
> +
> +void __init early_init_dt_add_memory_arch(u64 base, u64 size)
> +{
> + size &= PAGE_MASK;
> + memblock_add(base, size);
> +}
> +
> +void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> +{
> + return __va(memblock_alloc(size, align));
> +}
> +
> +void __init early_init_devtree(void *params)
> +{
> + u8 *alloc;
> +
> + /* Setup flat device-tree pointer */
> + initial_boot_params = params;
> +
> +
> + /* Retrieve various informations from the /chosen node of the
> + * device-tree, including the platform type, initrd location and
> + * size, TCE reserve, and more ...
> + */
> + of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
> +
> + /* Scan memory nodes and rebuild MEMBLOCKs */
> + memblock_init();
> + of_scan_flat_dt(early_init_dt_scan_root, NULL);
> + of_scan_flat_dt(early_init_dt_scan_memory, NULL);
> +
> + /* Save command line for /proc/cmdline and then parse parameters */
> + strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
> +// parse_early_param();
This should just be removed?
> +
> + memblock_analyze();
> +
> + /* We must copy the flattend device tree from init memory to regular
> + * memory because the device tree references the strings in it
> + * directly.
> + */
> +
> + alloc = __va(memblock_alloc(initial_boot_params->totalsize, PAGE_SIZE));
> +
> + memcpy(alloc, initial_boot_params, initial_boot_params->totalsize);
> +
> + initial_boot_params = (void *) alloc;
If alloc gets declared as a 'void*', then this cast can be removed.
> +}
> +
> +#ifdef CONFIG_BLK_DEV_INITRD
> +void __init early_init_dt_setup_initrd_arch(unsigned long start,
> + unsigned long end)
> +{
> + initrd_start = (unsigned long)__va(start);
> + initrd_end = (unsigned long)__va(end);
> + initrd_below_start_ok = 1;
> +}
> +#endif
> diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
> index 49342e9..6ce6583 100644
> --- a/arch/openrisc/kernel/setup.c
> +++ b/arch/openrisc/kernel/setup.c
> @@ -173,8 +173,7 @@ void __init setup_cpuinfo(void)
> unsigned long iccfgr,dccfgr;
> unsigned long cache_set_size, cache_ways;;
>
> - cpu = (struct device_node *) of_find_compatible_node(NULL,
> - NULL, "opencores,openrisc-1200");
> + cpu = of_find_compatible_node(NULL, NULL, "opencores,openrisc-1200");
This looks odd. Is it a stale hunk from a previous patch version?
> if (!cpu) {
> panic("No compatible CPU found in device tree...\n");
> }
> --
> 1.7.4.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 02/19] OpenRISC: Device tree
[not found] ` <CACxGe6tFX=EQjaL-4EjSXquY5eh+bca29=d=cE5-YAVCUVRCvA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-07-03 21:39 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 6+ messages in thread
From: Benjamin Herrenschmidt @ 2011-07-03 21:39 UTC (permalink / raw)
To: Grant Likely
Cc: linux-arch-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
On Sun, 2011-07-03 at 14:51 -0600, Grant Likely wrote:
> > +
> > +#ifdef CONFIG_PCI
> > +/*
> > + * PCI <-> OF matching functions
> > + * (XXX should these be here?)
> > + */
> > +struct pci_bus;
> > +struct pci_dev;
> > +extern int pci_device_from_OF_node(struct device_node *node,
> > + u8 *bus, u8 *devfn);
> > +extern struct device_node *pci_busdev_to_OF_node(struct pci_bus
> *bus,
> > + int devfn);
> > +extern struct device_node *pci_device_to_OF_node(struct pci_dev
> *dev);
> > +extern void pci_create_OF_bus_map(void);
> > +#endif
Don't copy these from powermac or microblaze. the OF_bus_map is
something that should not spread :-)
You get all you need of the above from generic code with my patches to
PCI <-> OF matching, which should be in linux-next and are going to be
merged in the next merge window.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 02/19] OpenRISC: Device tree
2011-07-03 20:51 ` Grant Likely
[not found] ` <CACxGe6tFX=EQjaL-4EjSXquY5eh+bca29=d=cE5-YAVCUVRCvA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2011-07-04 4:58 ` Jonas Bonn
2011-07-04 5:35 ` Grant Likely
1 sibling, 1 reply; 6+ messages in thread
From: Jonas Bonn @ 2011-07-04 4:58 UTC (permalink / raw)
To: Grant Likely; +Cc: linux-kernel, linux-arch, devicetree-discuss
On Sun, 2011-07-03 at 14:51 -0600, Grant Likely wrote:
> On Sat, Jul 2, 2011 at 3:15 PM, Jonas Bonn <jonas@southpole.se> wrote:
> Does it really make sense to have an SoC node for this board? I
> assume this is for a soft CPU system on a Diligent FPGA board. It is
> best if the device tree structure matches the actual bus layout of the
> chip and/or FPGA design. If the devices are directly on the CPU bus,
> then it is better to do without an soc node entirely and just put
> everything at the root.
Not sure I quite understand the distinction here. Yes, it's a soft CPU,
but conceptually it has an internal bus (Wishbone) comparable to the
Avalon bus that the peripherals sit on. I'd say it's an SoC; but I need
to ask: what constitutes a valid use of the "soc" node?
> > diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
> > index 49342e9..6ce6583 100644
> > --- a/arch/openrisc/kernel/setup.c
> > +++ b/arch/openrisc/kernel/setup.c
> > @@ -173,8 +173,7 @@ void __init setup_cpuinfo(void)
> > unsigned long iccfgr,dccfgr;
> > unsigned long cache_set_size, cache_ways;;
> >
> > - cpu = (struct device_node *) of_find_compatible_node(NULL,
> > - NULL, "opencores,openrisc-1200");
> > + cpu = of_find_compatible_node(NULL, NULL, "opencores,openrisc-1200");
>
> This looks odd. Is it a stale hunk from a previous patch version?
>
Hmmm... no, it's a hunk that should have been in patch 01/19 of the
series. That said, there's a bit of devicetree code in that patch too.
Can I just say, "please have a look there, too", or do I need to pull
those bits out into the devicetree patch?
I've pasted in just the relevant parts from patch 01/19 below for ease
of review.
/Jonas
>From arch/openrisc/kernel/setup.c:
+static inline unsigned int fcpu(struct device_node *cpu, char *n)
+{
+ const int *val;
+ return (val = of_get_property(cpu, n, NULL)) ? *val : 0;
+}
+
+void __init setup_cpuinfo(void)
+{
+ struct device_node *cpu = NULL;
+ unsigned long iccfgr,dccfgr;
+ unsigned long cache_set_size, cache_ways;;
+
+ cpu = (struct device_node *) of_find_compatible_node(NULL,
+ NULL,
"opencores,openrisc-1200");
+ if (!cpu) {
+ panic("No compatible CPU found in device tree...\n");
+ }
+
+ iccfgr = mfspr(SPR_ICCFGR);
+ cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
+ cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
+ cpuinfo.icache_block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >>
7);
+ cpuinfo.icache_size = cache_set_size * cache_ways *
cpuinfo.icache_block_size;
+
+ dccfgr = mfspr(SPR_DCCFGR);
+ cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
+ cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
+ cpuinfo.dcache_block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >>
7);
+ cpuinfo.dcache_size = cache_set_size * cache_ways *
cpuinfo.dcache_block_size;
+
+ cpuinfo.clock_frequency = fcpu(cpu, "clock-frequency");
+
+ of_node_put(cpu);
+
+ print_cpuinfo();
+}
+
+/**
+ * or32_early_setup
+ *
+ * Handles the pointer to the device tree that this kernel is to use
+ * for establishing the available platform devices.
+ *
+ * For now, this is limited to using the built-in device tree. In the
future,
+ * it is intended that this function will take a pointer to the device
tree
+ * that is potentially built-in, but potentially also passed in by the
+ * bootloader, or discovered by some equally clever means...
+ */
+
+void __init or32_early_setup(void) {
+
+ early_init_devtree((void *) __dtb_start);
+
+ printk(KERN_INFO "Compiled-in FDT at 0x%08x\n",
+ (unsigned int) __dtb_start);
+}
+
+const struct of_device_id openrisc_bus_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ {},
+};
+
+static int __init openrisc_device_probe(void)
+{
+ of_platform_bus_probe(NULL, openrisc_bus_ids, NULL);
+ return 0;
+}
+device_initcall(openrisc_device_probe);
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 02/19] OpenRISC: Device tree
2011-07-04 4:58 ` Jonas Bonn
@ 2011-07-04 5:35 ` Grant Likely
0 siblings, 0 replies; 6+ messages in thread
From: Grant Likely @ 2011-07-04 5:35 UTC (permalink / raw)
To: Jonas Bonn; +Cc: linux-kernel, linux-arch, devicetree-discuss
On Mon, Jul 04, 2011 at 06:58:28AM +0200, Jonas Bonn wrote:
>
> On Sun, 2011-07-03 at 14:51 -0600, Grant Likely wrote:
> > On Sat, Jul 2, 2011 at 3:15 PM, Jonas Bonn <jonas@southpole.se> wrote:
> > Does it really make sense to have an SoC node for this board? I
> > assume this is for a soft CPU system on a Diligent FPGA board. It is
> > best if the device tree structure matches the actual bus layout of the
> > chip and/or FPGA design. If the devices are directly on the CPU bus,
> > then it is better to do without an soc node entirely and just put
> > everything at the root.
>
> Not sure I quite understand the distinction here. Yes, it's a soft CPU,
> but conceptually it has an internal bus (Wishbone) comparable to the
> Avalon bus that the peripherals sit on. I'd say it's an SoC; but I need
> to ask: what constitutes a valid use of the "soc" node?
An soc node is really just a convenient collection node for devices on
an SoC. It can be used, or not, depending on the SoC and whoever is
writing the bindings for it.
Regardless, the device tree hierarchy should reflect the actual layout
of the buses, and devices on the same bus segment should be siblings
in the tree. Often when I work on an FPGA system, I don't even bother
with an soc node because it is kind of meaningless, and I just start
with knowing that the root of the tree represents the CPU local bus,
and then creating nodes for each bridge to another bus. If all the
devices are on the same bus segment, then it looks pretty much like
what you wrote except that the node name for the bridge would probably
be something like "wishbone-bus".
Basically, I'm suggesting to make the DT model as representative of
the FPGA design as possible.
> > > diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
> > > index 49342e9..6ce6583 100644
> > > --- a/arch/openrisc/kernel/setup.c
> > > +++ b/arch/openrisc/kernel/setup.c
> > > @@ -173,8 +173,7 @@ void __init setup_cpuinfo(void)
> > > unsigned long iccfgr,dccfgr;
> > > unsigned long cache_set_size, cache_ways;;
> > >
> > > - cpu = (struct device_node *) of_find_compatible_node(NULL,
> > > - NULL, "opencores,openrisc-1200");
> > > + cpu = of_find_compatible_node(NULL, NULL, "opencores,openrisc-1200");
> >
> > This looks odd. Is it a stale hunk from a previous patch version?
> >
>
> Hmmm... no, it's a hunk that should have been in patch 01/19 of the
> series. That said, there's a bit of devicetree code in that patch too.
> Can I just say, "please have a look there, too", or do I need to pull
> those bits out into the devicetree patch?
No, you don't need to pull it out into this patch, but when you respin
you should fix the series to not include this hunk in patch 2.
>
> I've pasted in just the relevant parts from patch 01/19 below for ease
> of review.
>
> /Jonas
>
> From arch/openrisc/kernel/setup.c:
>
> +static inline unsigned int fcpu(struct device_node *cpu, char *n)
> +{
> + const int *val;
> + return (val = of_get_property(cpu, n, NULL)) ? *val : 0;
be32_to_cpup(val) should be used here.
However, of_property_read_u32() is now available to be used with the
correct data size checking.
> +}
> +
> +void __init setup_cpuinfo(void)
> +{
> + struct device_node *cpu = NULL;
No need to initialize this to NULL, it is immediately set at the start
of the function.
> + unsigned long iccfgr,dccfgr;
> + unsigned long cache_set_size, cache_ways;;
> +
> + cpu = (struct device_node *) of_find_compatible_node(NULL,
> + NULL,
> "opencores,openrisc-1200");
Why the cast? I looks like it can be dropped.
> + if (!cpu) {
> + panic("No compatible CPU found in device tree...\n");
> + }
> +
> + iccfgr = mfspr(SPR_ICCFGR);
> + cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
> + cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
> + cpuinfo.icache_block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >>
> 7);
> + cpuinfo.icache_size = cache_set_size * cache_ways *
> cpuinfo.icache_block_size;
> +
> + dccfgr = mfspr(SPR_DCCFGR);
> + cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
> + cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
> + cpuinfo.dcache_block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >>
> 7);
> + cpuinfo.dcache_size = cache_set_size * cache_ways *
> cpuinfo.dcache_block_size;
> +
> + cpuinfo.clock_frequency = fcpu(cpu, "clock-frequency");
> +
> + of_node_put(cpu);
> +
> + print_cpuinfo();
> +}
> +
> +/**
> + * or32_early_setup
> + *
> + * Handles the pointer to the device tree that this kernel is to use
> + * for establishing the available platform devices.
> + *
> + * For now, this is limited to using the built-in device tree. In the
> future,
> + * it is intended that this function will take a pointer to the device
> tree
> + * that is potentially built-in, but potentially also passed in by the
> + * bootloader, or discovered by some equally clever means...
> + */
> +
> +void __init or32_early_setup(void) {
> +
> + early_init_devtree((void *) __dtb_start);
Isn't __dtb_start already a void*?
> +
> + printk(KERN_INFO "Compiled-in FDT at 0x%08x\n",
pr_info()
use %p for pointers.
> + (unsigned int) __dtb_start);
> +}
> +
> +const struct of_device_id openrisc_bus_ids[] = {
> + { .type = "soc", },
Never use .type for new code. Only .compatible should be checked.
> + { .compatible = "soc", },
Use "simple-bus". "soc" isn't defined to mean anything (see the ePAPR
spec).
> + {},
> +};
> +
> +static int __init openrisc_device_probe(void)
> +{
> + of_platform_bus_probe(NULL, openrisc_bus_ids, NULL);
Use of_platform_populate() instead (in linux-next, or the
devicetree/next branch at git://git.secretlab.ca/git/linux-2.6).
of_platform_populate() is better at handling devices at the root of
the device tree, and it properly ignores nodes that don't have a
compatible property.
g.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-07-04 5:35 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1309641352-18714-1-git-send-email-jonas@southpole.se>
2011-07-02 21:15 ` [PATCH v2 02/19] OpenRISC: Device tree Jonas Bonn
2011-07-03 18:07 ` Segher Boessenkool
2011-07-03 20:51 ` Grant Likely
[not found] ` <CACxGe6tFX=EQjaL-4EjSXquY5eh+bca29=d=cE5-YAVCUVRCvA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2011-07-03 21:39 ` Benjamin Herrenschmidt
2011-07-04 4:58 ` Jonas Bonn
2011-07-04 5:35 ` Grant Likely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).