* [PATCH v6 1/5] MIPS: Octeon: Add device tree source files.
2012-03-01 0:56 [PATCH v6 0/5] MIPS: Octeon: Use Device Tree David Daney
@ 2012-03-01 0:56 ` David Daney
[not found] ` <1330563422-14078-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
` (3 subsequent siblings)
4 siblings, 0 replies; 20+ messages in thread
From: David Daney @ 2012-03-01 0:56 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, Grant Likely, Rob Herring
Cc: linux-kernel, David Daney
From: David Daney <david.daney@cavium.com>
The two device tree files octeon_3xxx.dts and octeon_68xx.dts are
trimmed by code in a subsequent patch to reflect the hardware actually
present on the board. To this end several properties that are not
part of the declared bindings are added to aid in trimming off
unwanted nodes. Since the device tree and the code that trims it are
bound into the kernel binary, these 'marker' properties never escape
into the wild, and are purely an implementation detail of the kernel
early boot process. This is done for backwards compatibility with
existing boards (identified by a board type enumeration value by their
bootloaders). New boards will always pass a device tree from the
bootloader, the built-in trees are ignored in this case.
Signed-off-by: David Daney <david.daney@cavium.com>
---
.../bindings/ata/cavium-compact-flash.txt | 30 +
.../bindings/gpio/cavium-octeon-gpio.txt | 48 ++
.../devicetree/bindings/i2c/cavium-i2c.txt | 34 ++
.../devicetree/bindings/mips/cavium/bootbus.txt | 126 ++++
.../devicetree/bindings/mips/cavium/ciu.txt | 26 +
.../devicetree/bindings/mips/cavium/ciu2.txt | 27 +
.../devicetree/bindings/mips/cavium/dma-engine.txt | 21 +
.../devicetree/bindings/mips/cavium/uctl.txt | 47 ++
.../devicetree/bindings/net/cavium-mdio.txt | 27 +
.../devicetree/bindings/net/cavium-mix.txt | 40 ++
.../devicetree/bindings/net/cavium-pip.txt | 98 +++
.../devicetree/bindings/serial/cavium-uart.txt | 19 +
arch/mips/cavium-octeon/.gitignore | 2 +
arch/mips/cavium-octeon/Makefile | 13 +
arch/mips/cavium-octeon/octeon_3xxx.dts | 571 ++++++++++++++++++
arch/mips/cavium-octeon/octeon_68xx.dts | 625 ++++++++++++++++++++
16 files changed, 1754 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/ata/cavium-compact-flash.txt
create mode 100644 Documentation/devicetree/bindings/gpio/cavium-octeon-gpio.txt
create mode 100644 Documentation/devicetree/bindings/i2c/cavium-i2c.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/bootbus.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu2.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/dma-engine.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/uctl.txt
create mode 100644 Documentation/devicetree/bindings/net/cavium-mdio.txt
create mode 100644 Documentation/devicetree/bindings/net/cavium-mix.txt
create mode 100644 Documentation/devicetree/bindings/net/cavium-pip.txt
create mode 100644 Documentation/devicetree/bindings/serial/cavium-uart.txt
create mode 100644 arch/mips/cavium-octeon/.gitignore
create mode 100644 arch/mips/cavium-octeon/octeon_3xxx.dts
create mode 100644 arch/mips/cavium-octeon/octeon_68xx.dts
diff --git a/Documentation/devicetree/bindings/ata/cavium-compact-flash.txt b/Documentation/devicetree/bindings/ata/cavium-compact-flash.txt
new file mode 100644
index 0000000..93986a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/cavium-compact-flash.txt
@@ -0,0 +1,30 @@
+* Compact Flash
+
+The Cavium Compact Flash device is connected to the Octeon Boot Bus,
+and is thus a child of the Boot Bus device. It can read and write
+industry standard compact flash devices.
+
+Properties:
+- compatible: "cavium,ebt3000-compact-flash";
+
+ Compatibility with many Cavium evaluation boards.
+
+- reg: The base address of the the CF chip select banks. Depending on
+ the device configuration, there may be one or two banks.
+
+- cavium,bus-width: The width of the connection to the CF devices. Valid
+ values are 8 and 16.
+
+- cavium,true-ide: Optional, if present the CF connection is in True IDE mode.
+
+- cavium,dma-engine-handle: Optional, a phandle for the DMA Engine connected
+ to this device.
+
+Example:
+ compact-flash@5,0 {
+ compatible = "cavium,ebt3000-compact-flash";
+ reg = <5 0 0x10000>, <6 0 0x10000>;
+ cavium,bus-width = <16>;
+ cavium,true-ide;
+ cavium,dma-engine-handle = <&dma0>;
+ };
diff --git a/Documentation/devicetree/bindings/gpio/cavium-octeon-gpio.txt b/Documentation/devicetree/bindings/gpio/cavium-octeon-gpio.txt
new file mode 100644
index 0000000..21b989a
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/cavium-octeon-gpio.txt
@@ -0,0 +1,48 @@
+* General Purpose Input Output (GPIO) bus.
+
+Properties:
+- compatible: "cavium,octeon-3860-gpio"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the GPIO unit's register bank.
+
+- gpio-controller: This is a GPIO controller.
+
+- #gpio-cells: Must be <2>. The first cell is the GPIO pin.
+
+- interrupt-controller: The GPIO controller is also an interrupt
+ controller, any of its pins may be configured as an interrupt
+ source.
+
+- #interrupt-cells: Must be <2>. The first cell is the GPIO pin
+ connected to the interrupt source. The second cell is the interrupt
+ triggering protocol and may have one of four values:
+ 1 - edge triggered on the rising edge.
+ 2 - edge triggered on the falling edge
+ 4 - level triggered active high.
+ 8 - level triggered active low.
+
+- interrupts: Interrupt routing for pin 0. The remaining pins are
+ also routed, but in a manner that can be derived from the pin0
+ routing, so they are not specified.
+
+Example:
+
+ gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (1 - edge rising
+ * 2 - edge falling
+ * 4 - level active high
+ * 8 - level active low)
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pin connect to 16 consecutive CUI bits */
+ interrupts = <0 16>;
+ };
diff --git a/Documentation/devicetree/bindings/i2c/cavium-i2c.txt b/Documentation/devicetree/bindings/i2c/cavium-i2c.txt
new file mode 100644
index 0000000..dced82e
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/cavium-i2c.txt
@@ -0,0 +1,34 @@
+* Two Wire Serial Interface (TWSI) / I2C
+
+- compatible: "cavium,octeon-3860-twsi"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the TWSI/I2C bus controller register bank.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>. I2C addresses have no size component.
+
+- interrupts: A single interrupt specifier.
+
+- clock-frequency: The I2C bus clock rate in Hz.
+
+Example:
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <0 45>;
+ clock-frequency = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/bootbus.txt b/Documentation/devicetree/bindings/mips/cavium/bootbus.txt
new file mode 100644
index 0000000..6581478
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/bootbus.txt
@@ -0,0 +1,126 @@
+* Boot Bus
+
+The Octeon Boot Bus is a configurable parallel bus with 8 chip
+selects. Each chip select is independently configurable.
+
+Properties:
+- compatible: "cavium,octeon-3860-bootbus"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the Boot Bus' register bank.
+
+- #address-cells: Must be <2>. The first cell is the chip select
+ within the bootbus. The second cell is the offset from the chip select.
+
+- #size-cells: Must be <1>.
+
+- ranges: There must be one one triplet of (child-bus-address,
+ parent-bus-address, length) for each active chip select. If the
+ length element for any triplet is zero, the chip select is disabled,
+ making it inactive.
+
+The configuration parameters for each chip select are stored in child
+nodes.
+
+Configuration Properties:
+- compatible: "cavium,octeon-3860-bootbus-config"
+
+- cavium,cs-index: A single cell indicating the chip select that
+ corresponds to this configuration.
+
+- cavium,t-adr: A cell specifying the ADR timing (in nS).
+
+- cavium,t-ce: A cell specifying the CE timing (in nS).
+
+- cavium,t-oe: A cell specifying the OE timing (in nS).
+
+- cavium,t-we: A cell specifying the WE timing (in nS).
+
+- cavium,t-rd-hld: A cell specifying the RD_HLD timing (in nS).
+
+- cavium,t-wr-hld: A cell specifying the WR_HLD timing (in nS).
+
+- cavium,t-pause: A cell specifying the PAUSE timing (in nS).
+
+- cavium,t-wait: A cell specifying the WAIT timing (in nS).
+
+- cavium,t-page: A cell specifying the PAGE timing (in nS).
+
+- cavium,t-rd-dly: A cell specifying the RD_DLY timing (in nS).
+
+- cavium,pages: A cell specifying the PAGES parameter (0 = 8 bytes, 1
+ = 2 bytes, 2 = 4 bytes, 3 = 8 bytes).
+
+- cavium,wait-mode: Optional. If present, wait mode (WAITM) is selected.
+
+- cavium,page-mode: Optional. If present, page mode (PAGEM) is selected.
+
+- cavium,bus-width: A cell specifying the WIDTH parameter (in bits) of
+ the bus for this chip select.
+
+- cavium,ale-mode: Optional. If present, ALE mode is selected.
+
+- cavium,sam-mode: Optional. If present, SAM mode is selected.
+
+- cavium,or-mode: Optional. If present, OR mode is selected.
+
+Example:
+ bootbus: bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0x0 0x1f400000 0xc00000>,
+ <1 0 0x10000 0x30000000 0>,
+ <2 0 0x10000 0x40000000 0>,
+ <3 0 0x10000 0x50000000 0>,
+ <4 0 0x0 0x1d020000 0x10000>,
+ <5 0 0x0 0x1d040000 0x10000>,
+ <6 0 0x0 0x1d050000 0x10000>,
+ <7 0 0x10000 0x90000000 0>;
+
+ cavium,cs-config@0 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <0>;
+ cavium,t-adr = <20>;
+ cavium,t-ce = <60>;
+ cavium,t-oe = <60>;
+ cavium,t-we = <45>;
+ cavium,t-rd-hld = <35>;
+ cavium,t-wr-hld = <45>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <0>;
+ cavium,t-page = <35>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ .
+ .
+ .
+ cavium,cs-config@6 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <6>;
+ cavium,t-adr = <5>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <270>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <70>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <0>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,wait-mode;
+ cavium,bus-width = <16>;
+ };
+ .
+ .
+ .
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/ciu.txt b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
new file mode 100644
index 0000000..2c2d074
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/ciu.txt
@@ -0,0 +1,26 @@
+* Central Interrupt Unit
+
+Properties:
+- compatible: "cavium,octeon-3860-ciu"
+
+ Compatibility with all cn3XXX, cn5XXX and cn63XX SOCs.
+
+- interrupt-controller: This is an interrupt controller.
+
+- reg: The base address of the CIU's register bank.
+
+- #interrupt-cells: Must be <2>. The first cell is the bank within
+ the CIU and may have a value of 0 or 1. The second cell is the bit
+ within the bank and may have a value between 0 and 63.
+
+Example:
+ interrupt-controller@1070000000000 {
+ compatible = "cavium,octeon-3860-ciu";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 1)
+ * 2) Bit within the register (0..63)
+ */
+ #interrupt-cells = <2>;
+ reg = <0x10700 0x00000000 0x0 0x7000>;
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/ciu2.txt b/Documentation/devicetree/bindings/mips/cavium/ciu2.txt
new file mode 100644
index 0000000..0ec7ba8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/ciu2.txt
@@ -0,0 +1,27 @@
+* Central Interrupt Unit
+
+Properties:
+- compatible: "cavium,octeon-6880-ciu2"
+
+ Compatibility with 68XX SOCs.
+
+- interrupt-controller: This is an interrupt controller.
+
+- reg: The base address of the CIU's register bank.
+
+- #interrupt-cells: Must be <2>. The first cell is the bank within
+ the CIU and may have a value between 0 and 63. The second cell is
+ the bit within the bank and may also have a value between 0 and 63.
+
+Example:
+ interrupt-controller@1070100000000 {
+ compatible = "cavium,octeon-6880-ciu2";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0..63)
+ * 2) Bit within the register (0..63)
+ */
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x10701 0x00000000 0x0 0x4000000>;
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/dma-engine.txt b/Documentation/devicetree/bindings/mips/cavium/dma-engine.txt
new file mode 100644
index 0000000..cb4291e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/dma-engine.txt
@@ -0,0 +1,21 @@
+* DMA Engine.
+
+The Octeon DMA Engine transfers between the Boot Bus and main memory.
+The DMA Engine will be refered to by phandle by any device that is
+connected to it.
+
+Properties:
+- compatible: "cavium,octeon-5750-bootbus-dma"
+
+ Compatibility with all cn52XX, cn56XX and cn6XXX SOCs.
+
+- reg: The base address of the DMA Engine's register bank.
+
+- interrupts: A single interrupt specifier.
+
+Example:
+ dma0: dma-engine@1180000000100 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000100 0x0 0x8>;
+ interrupts = <0 63>;
+ };
diff --git a/Documentation/devicetree/bindings/mips/cavium/uctl.txt b/Documentation/devicetree/bindings/mips/cavium/uctl.txt
new file mode 100644
index 0000000..5dabe02
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cavium/uctl.txt
@@ -0,0 +1,47 @@
+* UCTL USB controller glue
+
+Properties:
+- compatible: "cavium,octeon-6335-uctl"
+
+ Compatibility with all cn6XXX SOCs.
+
+- reg: The base address of the UCTL register bank.
+
+- #address-cells: Must be <2>.
+
+- #size-cells: Must be <2>.
+
+- ranges: Empty to signify direct mapping of the children.
+
+- refclk-frequency: A single cell containing the reference clock
+ frequency in Hz.
+
+- refclk-type: A string describing the reference clock connection
+ either "crystal" or "external".
+
+Example:
+ uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <24000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/net/cavium-mdio.txt b/Documentation/devicetree/bindings/net/cavium-mdio.txt
new file mode 100644
index 0000000..04cb749
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/cavium-mdio.txt
@@ -0,0 +1,27 @@
+* System Management Interface (SMI) / MDIO
+
+Properties:
+- compatible: "cavium,octeon-3860-mdio"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the MDIO bus controller register bank.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>. MDIO addresses have no size component.
+
+Typically an MDIO bus might have several children.
+
+Example:
+ mdio@1180000001800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001800 0x0 0x40>;
+
+ ethernet-phy@0 {
+ ...
+ reg = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/net/cavium-mix.txt b/Documentation/devicetree/bindings/net/cavium-mix.txt
new file mode 100644
index 0000000..e4f9d3c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/cavium-mix.txt
@@ -0,0 +1,40 @@
+* MIX Ethernet controller.
+
+Properties:
+- compatible: "cavium,octeon-5750-mix"
+
+ Compatibility with all cn5XXX and cn6XXX SOCs populated with MIX
+ devices.
+
+- reg: The base addresses of four separate register banks. The first
+ bank contains the MIX registers. The second bank the corresponding
+ AGL registers. The third bank are the AGL registers shared by all
+ MIX devices present. The fourth bank is the AGL_PRT_CTL shared by
+ all MIX devices present.
+
+- cell-index: A single cell specifying which portion of the shared
+ register banks corresponds to this MIX device.
+
+- interrupts: Two interrupt specifiers. The first is the MIX
+ interrupt routing and the second the routing for the AGL interrupts.
+
+- mac-address: Optional, the MAC address to assign to the device.
+
+- local-mac-address: Optional, the MAC address to assign to the device
+ if mac-address is not specified.
+
+- phy-handle: Optional, a phandle for the PHY device connected to this device.
+
+Example:
+ ethernet@1070000100800 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000800 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <1>;
+ interrupts = <1 18>, < 1 46>;
+ local-mac-address = [ 00 0f b7 10 63 54 ];
+ phy-handle = <&phy1>;
+ };
+
diff --git a/Documentation/devicetree/bindings/net/cavium-pip.txt b/Documentation/devicetree/bindings/net/cavium-pip.txt
new file mode 100644
index 0000000..d4c53ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/cavium-pip.txt
@@ -0,0 +1,98 @@
+* PIP Ethernet nexus.
+
+The PIP Ethernet nexus can control several data packet input/output
+devices. The devices have a two level grouping scheme. There may be
+several interfaces, and each interface may have several ports. These
+ports might be an individual Ethernet PHY.
+
+
+Properties for the PIP nexus:
+- compatible: "cavium,octeon-3860-pip"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the PIP's register bank.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>.
+
+Properties for PIP interfaces which is a child the PIP nexus:
+- compatible: "cavium,octeon-3860-pip-interface"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The interface number.
+
+- #address-cells: Must be <1>.
+
+- #size-cells: Must be <0>.
+
+Properties for PIP port which is a child the PIP interface:
+- compatible: "cavium,octeon-3860-pip-port"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The port number within the interface group.
+
+- mac-address: Optional, the MAC address to assign to the device.
+
+- local-mac-address: Optional, the MAC address to assign to the device
+ if mac-address is not specified.
+
+- phy-handle: Optional, a phandle for the PHY device connected to this device.
+
+Example:
+
+ pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 60 ];
+ phy-handle = <&phy2>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 61 ];
+ phy-handle = <&phy3>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 62 ];
+ phy-handle = <&phy4>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 63 ];
+ phy-handle = <&phy5>;
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 0f b7 10 63 64 ];
+ phy-handle = <&phy6>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/serial/cavium-uart.txt b/Documentation/devicetree/bindings/serial/cavium-uart.txt
new file mode 100644
index 0000000..87a6c37
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/cavium-uart.txt
@@ -0,0 +1,19 @@
+* Universal Asynchronous Receiver/Transmitter (UART)
+
+- compatible: "cavium,octeon-3860-uart"
+
+ Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs.
+
+- reg: The base address of the UART register bank.
+
+- interrupts: A single interrupt specifier.
+
+- current-speed: Optional, the current bit rate in bits per second.
+
+Example:
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ current-speed = <115200>;
+ interrupts = <0 35>;
+ };
diff --git a/arch/mips/cavium-octeon/.gitignore b/arch/mips/cavium-octeon/.gitignore
new file mode 100644
index 0000000..39c9686
--- /dev/null
+++ b/arch/mips/cavium-octeon/.gitignore
@@ -0,0 +1,2 @@
+*.dtb.S
+*.dtb
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 19eb043..1e37522 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -15,3 +15,16 @@ obj-y += octeon-memcpy.o
obj-y += executive/
obj-$(CONFIG_SMP) += smp.o
+
+DTS_FILES = octeon_3xxx.dts octeon_68xx.dts
+DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES))
+
+obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES))
+
+$(obj)/%.dtb: $(src)/%.dts FORCE
+ $(call if_changed_dep,dtc)
+
+# Let's keep the .dtb files around in case we want to look at them.
+.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES))
+
+clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES))
diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
new file mode 100644
index 0000000..e0fb0e3
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
@@ -0,0 +1,571 @@
+/dts-v1/;
+/*
+ * OCTEON 3XXX, 5XXX, 63XX device tree skeleton.
+ *
+ * This device tree is pruned and patched by early boot code before
+ * use. Because of this, it contains a super-set of the available
+ * devices and properties.
+ */
+/ {
+ compatible = "cavium,octeon-3860";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&ciu>;
+
+ soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges; /* Direct mapping */
+
+ ciu: interrupt-controller@1070000000000 {
+ compatible = "cavium,octeon-3860-ciu";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 1)
+ * 2) Bit within the register (0..63)
+ */
+ #interrupt-cells = <2>;
+ reg = <0x10700 0x00000000 0x0 0x7000>;
+ };
+
+ gpio: gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (1 - edge rising
+ * 2 - edge falling
+ * 4 - level active high
+ * 8 - level active low)
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pin connect to 16 consecutive CUI bits */
+ interrupts = <0 16>; /* <0 17> <0 18> <0 19>
+ <0 20> <0 21> <0 22> <0 23>
+ <0 24> <0 25> <0 26> <0 27>
+ <0 28> <0 29> <0 30> <0 31>; */
+ };
+
+ smi0: mdio@1180000001800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001800 0x0 0x40>;
+
+ phy0: ethernet-phy@0 {
+ compatible = "marvell,88e1118";
+ marvell,reg-init =
+ /* Fix rx and tx clock transition timing */
+ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */
+ /* Adjust LED drive. */
+ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */
+ /* irq, blink-activity, blink-link */
+ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ compatible = "marvell,88e1118";
+ marvell,reg-init =
+ /* Fix rx and tx clock transition timing */
+ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */
+ /* Adjust LED drive. */
+ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */
+ /* irq, blink-activity, blink-link */
+ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+
+ phy6: ethernet-phy@6 {
+ reg = <6>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy7: ethernet-phy@7 {
+ reg = <7>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy8: ethernet-phy@8 {
+ reg = <8>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy9: ethernet-phy@9 {
+ reg = <9>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi1: mdio@1180000001900 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001900 0x0 0x40>;
+
+ phy100: ethernet-phy@1 {
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ phy101: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ phy102: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ phy103: ethernet-phy@4 {
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ };
+
+ mix0: ethernet@1070000100000 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000000 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <0>;
+ interrupts = <0 62>, <1 46>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy0>;
+ };
+
+ mix1: ethernet@1070000100800 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000800 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <1>;
+ interrupts = <1 18>, < 1 46>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy1>;
+ };
+
+ pip: pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy2>;
+ cavium,alt-phy-handle = <&phy100>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy3>;
+ cavium,alt-phy-handle = <&phy101>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy4>;
+ cavium,alt-phy-handle = <&phy102>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy5>;
+ cavium,alt-phy-handle = <&phy103>;
+ };
+ ethernet@4 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x4>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@5 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x5>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@6 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x6>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@7 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x7>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@8 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x8>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@9 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x9>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@a {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xa>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@b {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xb>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@c {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xc>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@d {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xd>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@e {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xe>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@f {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xf>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy6>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy7>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy8>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy9>;
+ };
+ };
+ };
+
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <0 45>;
+ clock-frequency = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
+
+ twsi1: i2c@1180000001200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001200 0x0 0x200>;
+ interrupts = <0 59>;
+ clock-frequency = <100000>;
+ };
+
+ uart0: serial@1180000000800 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000800 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <0 34>;
+ };
+
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <0 35>;
+ };
+
+ uart2: serial@1180000000400 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000400 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <1 16>;
+ };
+
+ bootbus: bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0x0 0x1f400000 0xc00000>,
+ <1 0 0x10000 0x30000000 0>,
+ <2 0 0x10000 0x40000000 0>,
+ <3 0 0x10000 0x50000000 0>,
+ <4 0 0x0 0x1d020000 0x10000>,
+ <5 0 0x0 0x1d040000 0x10000>,
+ <6 0 0x0 0x1d050000 0x10000>,
+ <7 0 0x10000 0x90000000 0>;
+
+ cavium,cs-config@0 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <0>;
+ cavium,t-adr = <20>;
+ cavium,t-ce = <60>;
+ cavium,t-oe = <60>;
+ cavium,t-we = <45>;
+ cavium,t-rd-hld = <35>;
+ cavium,t-wr-hld = <45>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <0>;
+ cavium,t-page = <35>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@4 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <4>;
+ cavium,t-adr = <320>;
+ cavium,t-ce = <320>;
+ cavium,t-oe = <320>;
+ cavium,t-we = <320>;
+ cavium,t-rd-hld = <320>;
+ cavium,t-wr-hld = <320>;
+ cavium,t-pause = <320>;
+ cavium,t-wait = <320>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@5 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <5>;
+ cavium,t-adr = <5>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <125>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <30>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <30>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <16>;
+ };
+ cavium,cs-config@6 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <6>;
+ cavium,t-adr = <5>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <270>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <70>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <0>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,wait-mode;
+ cavium,bus-width = <16>;
+ };
+
+ flash0: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ led0: led-display@4,0 {
+ compatible = "avago,hdsp-253x";
+ reg = <4 0x20 0x20>, <4 0 0x20>;
+ };
+
+ cf0: compact-flash@5,0 {
+ compatible = "cavium,ebt3000-compact-flash";
+ reg = <5 0 0x10000>, <6 0 0x10000>;
+ cavium,bus-width = <16>;
+ cavium,true-ide;
+ cavium,dma-engine-handle = <&dma0>;
+ };
+ };
+
+ dma0: dma-engine@1180000000100 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000100 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+ dma1: dma-engine@1180000000108 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000108 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+
+ uctl: uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <12000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ };
+ };
+
+ aliases {
+ mix0 = &mix0;
+ mix1 = &mix1;
+ pip = &pip;
+ smi0 = &smi0;
+ smi1 = &smi1;
+ twsi0 = &twsi0;
+ twsi1 = &twsi1;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uart2 = &uart2;
+ flash0 = &flash0;
+ cf0 = &cf0;
+ uctl = &uctl;
+ led0 = &led0;
+ };
+ };
diff --git a/arch/mips/cavium-octeon/octeon_68xx.dts b/arch/mips/cavium-octeon/octeon_68xx.dts
new file mode 100644
index 0000000..bde6b23
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_68xx.dts
@@ -0,0 +1,625 @@
+/dts-v1/;
+/*
+ * OCTEON 68XX device tree skeleton.
+ *
+ * This device tree is pruned and patched by early boot code before
+ * use. Because of this, it contains a super-set of the available
+ * devices and properties.
+ */
+/ {
+ compatible = "cavium,octeon-6880";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&ciu2>;
+
+ soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges; /* Direct mapping */
+
+ ciu2: interrupt-controller@1070100000000 {
+ compatible = "cavium,octeon-6880-ciu2";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 7)
+ * 2) Bit within the register (0..63)
+ */
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x10701 0x00000000 0x0 0x4000000>;
+ };
+
+ gpio: gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (1 - edge rising
+ * 2 - edge falling
+ * 4 - level active high
+ * 8 - level active low)
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pins connect to 16 consecutive CUI bits */
+ interrupts = <7 0>; /* <7 1> <7 2> <7 3>
+ <7 4> <7 5> <7 6> <7 7>
+ <7 8> <7 9> <7 10> <7 11>
+ <7 12> <7 13> <7 14> <7 15>; */
+ };
+
+ smi0: mdio@1180000003800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003800 0x0 0x40>;
+
+ phy0: ethernet-phy@6 {
+ compatible = "marvell,88e1118";
+ marvell,reg-init =
+ /* Fix rx and tx clock transition timing */
+ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */
+ /* Adjust LED drive. */
+ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */
+ /* irq, blink-activity, blink-link */
+ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */
+ reg = <6>;
+ };
+
+ phy1: ethernet-phy@1 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy2: ethernet-phy@2 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy3: ethernet-phy@3 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy4: ethernet-phy@4 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi1: mdio@1180000003880 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003880 0x0 0x40>;
+
+ phy41: ethernet-phy@1 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy42: ethernet-phy@2 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy43: ethernet-phy@3 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy44: ethernet-phy@4 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi2: mdio@1180000003900 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003900 0x0 0x40>;
+
+ phy21: ethernet-phy@1 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy22: ethernet-phy@2 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy23: ethernet-phy@3 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy24: ethernet-phy@4 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi3: mdio@1180000003980 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003980 0x0 0x40>;
+
+ phy11: ethernet-phy@1 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy12: ethernet-phy@2 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy13: ethernet-phy@3 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy14: ethernet-phy@4 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ mix0: ethernet@1070000100000 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000000 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <0>;
+ interrupts = <6 40>, <6 32>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy0>;
+ };
+
+ pip: pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@4 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy1>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy2>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy3>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy4>;
+ };
+ };
+
+ interface@3 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy11>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy12>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy13>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy14>;
+ };
+ };
+
+ interface@2 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy21>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy22>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy23>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy24>;
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy41>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy42>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy43>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy44>;
+ };
+ };
+ };
+
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <3 32>;
+ clock-frequency = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
+
+ twsi1: i2c@1180000001200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001200 0x0 0x200>;
+ interrupts = <3 33>;
+ clock-frequency = <100000>;
+ };
+
+ uart0: serial@1180000000800 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000800 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <3 36>;
+ };
+
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <3 37>;
+ };
+
+ bootbus: bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0 0x1f400000 0xc00000>,
+ <1 0 0x10000 0x30000000 0>,
+ <2 0 0x10000 0x40000000 0>,
+ <3 0 0x10000 0x50000000 0>,
+ <4 0 0 0x1d020000 0x10000>,
+ <5 0 0 0x1d040000 0x10000>,
+ <6 0 0 0x1d050000 0x10000>,
+ <7 0 0x10000 0x90000000 0>;
+
+ cavium,cs-config@0 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <0>;
+ cavium,t-adr = <10>;
+ cavium,t-ce = <50>;
+ cavium,t-oe = <50>;
+ cavium,t-we = <35>;
+ cavium,t-rd-hld = <25>;
+ cavium,t-wr-hld = <35>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <300>;
+ cavium,t-page = <25>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@4 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <4>;
+ cavium,t-adr = <320>;
+ cavium,t-ce = <320>;
+ cavium,t-oe = <320>;
+ cavium,t-we = <320>;
+ cavium,t-rd-hld = <320>;
+ cavium,t-wr-hld = <320>;
+ cavium,t-pause = <320>;
+ cavium,t-wait = <320>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@5 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <5>;
+ cavium,t-adr = <0>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <125>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <300>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <300>;
+ cavium,t-page = <310>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <16>;
+ };
+ cavium,cs-config@6 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <6>;
+ cavium,t-adr = <0>;
+ cavium,t-ce = <30>;
+ cavium,t-oe = <125>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <30>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <30>;
+ cavium,t-page = <310>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,wait-mode;
+ cavium,bus-width = <16>;
+ };
+
+ flash0: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0 0x200000>;
+ read-only;
+ };
+ partition@200000 {
+ label = "kernel";
+ reg = <0x200000 0x200000>;
+ };
+ partition@400000 {
+ label = "cramfs";
+ reg = <0x400000 0x3fe000>;
+ };
+ partition@7fe000 {
+ label = "environment";
+ reg = <0x7fe000 0x2000>;
+ read-only;
+ };
+ };
+
+ led0: led-display@4,0 {
+ compatible = "avago,hdsp-253x";
+ reg = <4 0x20 0x20>, <4 0 0x20>;
+ };
+
+ compact-flash@5,0 {
+ compatible = "cavium,ebt3000-compact-flash";
+ reg = <5 0 0x10000>, <6 0 0x10000>;
+ cavium,bus-width = <16>;
+ cavium,true-ide;
+ cavium,dma-engine-handle = <&dma0>;
+ };
+ };
+
+ dma0: dma-engine@1180000000100 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000100 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+ dma1: dma-engine@1180000000108 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000108 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+
+ uctl: uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <12000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <3 44>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <3 44>;
+ big-endian-regs;
+ };
+ };
+ };
+
+ aliases {
+ mix0 = &mix0;
+ pip = &pip;
+ smi0 = &smi0;
+ smi1 = &smi1;
+ smi2 = &smi2;
+ smi3 = &smi3;
+ twsi0 = &twsi0;
+ twsi1 = &twsi1;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uctl = &uctl;
+ led0 = &led0;
+ flash0 = &flash0;
+ };
+ };
--
1.7.2.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
[parent not found: <1330563422-14078-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* [PATCH v6 2/5] MIPS: Don't define early_init_devtree() and device_tree_init() in prom.c for CPU_CAVIUM_OCTEON
[not found] ` <1330563422-14078-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2012-03-01 0:56 ` David Daney
0 siblings, 0 replies; 20+ messages in thread
From: David Daney @ 2012-03-01 0:56 UTC (permalink / raw)
To: linux-mips-6z/3iImG2C8G8FEW9MqTrA, ralf-6z/3iImG2C8G8FEW9MqTrA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Grant Likely,
Rob Herring
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, David Daney
From: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
This code is not common enough to be in a shared file, so OCTEON defines
it's own versions.
When the last of this target specific code is moved out, we can remove
all of this.
Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
arch/mips/kernel/prom.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 558b539..4aaa5c0 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -60,6 +60,7 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start,
}
#endif
+#ifndef CONFIG_CPU_CAVIUM_OCTEON
void __init early_init_devtree(void *params)
{
/* Setup flat device-tree pointer */
@@ -95,3 +96,4 @@ void __init device_tree_init(void)
/* free the space reserved for the dt blob */
free_mem_mach(base, size);
}
+#endif /* !CONFIG_CPU_CAVIUM_OCTEON */
--
1.7.2.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 3/5] MIPS: Octeon: Add irq handlers for GPIO interrupts.
2012-03-01 0:56 [PATCH v6 0/5] MIPS: Octeon: Use Device Tree David Daney
2012-03-01 0:56 ` [PATCH v6 1/5] MIPS: Octeon: Add device tree source files David Daney
[not found] ` <1330563422-14078-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2012-03-01 0:57 ` David Daney
2012-03-01 0:57 ` [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts David Daney
2012-03-01 0:57 ` [PATCH v6 5/5] MIPS: Octeon: Initialize and fixup device tree David Daney
4 siblings, 0 replies; 20+ messages in thread
From: David Daney @ 2012-03-01 0:57 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, Grant Likely, Rob Herring
Cc: linux-kernel, David Daney
From: David Daney <david.daney@cavium.com>
This is needed for follow-on on patches for Octeon to use the Device
Tree to configure GPIO interrupts.
Signed-off-by: David Daney <david.daney@cavium.com>
---
arch/mips/cavium-octeon/octeon-irq.c | 96 +++++++++++++++++++++++++++++++++-
1 files changed, 95 insertions(+), 1 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ffd4ae6..bdcedd3 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -505,6 +505,72 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
}
}
+static void octeon_irq_gpio_setup(struct irq_data *data)
+{
+ union cvmx_gpio_bit_cfgx cfg;
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ u32 t = irqd_get_trigger_type(data);
+
+ cfg.u64 = 0;
+ cfg.s.int_en = 1;
+ cfg.s.int_type = (t & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) != 0;
+ cfg.s.rx_xor = (t & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) != 0;
+
+ /* 1 uS glitch filter*/
+ cfg.s.fil_cnt = 7;
+ cfg.s.fil_sel = 3;
+
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(bit), cfg.u64);
+}
+
+static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu_enable_v2(data);
+}
+
+static void octeon_irq_ciu_enable_gpio(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu_enable(data);
+}
+
+static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t)
+{
+ u32 current_type = irqd_get_trigger_type(data);
+
+ /* If the type has been set, don't change it */
+ if (current_type && current_type != t)
+ return -EINVAL;
+
+ irqd_set_trigger_type(data, t);
+ return IRQ_SET_MASK_OK;
+}
+
+static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data)
+{
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(bit), 0);
+
+ octeon_irq_ciu_disable_all_v2(data);
+}
+
+static void octeon_irq_ciu_disable_gpio(struct irq_data *data)
+{
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(bit), 0);
+
+ octeon_irq_ciu_disable_all(data);
+}
+
+static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
+{
+ int bit = data->irq - OCTEON_IRQ_GPIO0;
+ u64 mask = 1ull << bit;
+
+ cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
+}
+
#ifdef CONFIG_SMP
static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
@@ -717,6 +783,31 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = {
.flags = IRQCHIP_ONOFFLINE_ENABLED,
};
+static struct irq_chip octeon_irq_chip_ciu_gpio_v2 = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu_enable_gpio_v2,
+ .irq_disable = octeon_irq_ciu_disable_gpio_v2,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu_gpio = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu_enable_gpio,
+ .irq_disable = octeon_irq_ciu_disable_gpio,
+ .irq_mask = octeon_irq_dummy_mask,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+#endif
+};
+
/*
* Watchdog interrupts are special. They are associated with a single
* core, so we hardwire the affinity to that core.
@@ -890,6 +981,7 @@ static void __init octeon_irq_init_ciu(void)
struct irq_chip *chip_edge;
struct irq_chip *chip_mbox;
struct irq_chip *chip_wd;
+ struct irq_chip *chip_gpio;
octeon_irq_init_ciu_percpu();
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
@@ -904,6 +996,7 @@ static void __init octeon_irq_init_ciu(void)
chip_edge = &octeon_irq_chip_ciu_edge_v2;
chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
chip_wd = &octeon_irq_chip_ciu_wd_v2;
+ chip_gpio = &octeon_irq_chip_ciu_gpio_v2;
} else {
octeon_irq_ip2 = octeon_irq_ip2_v1;
octeon_irq_ip3 = octeon_irq_ip3_v1;
@@ -911,6 +1004,7 @@ static void __init octeon_irq_init_ciu(void)
chip_edge = &octeon_irq_chip_ciu_edge;
chip_mbox = &octeon_irq_chip_ciu_mbox;
chip_wd = &octeon_irq_chip_ciu_wd;
+ chip_gpio = &octeon_irq_chip_ciu_gpio;
}
octeon_irq_ip4 = octeon_irq_ip4_mask;
@@ -921,7 +1015,7 @@ static void __init octeon_irq_init_ciu(void)
for (i = 0; i < 16; i++)
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip_gpio, handle_level_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-01 0:56 [PATCH v6 0/5] MIPS: Octeon: Use Device Tree David Daney
` (2 preceding siblings ...)
2012-03-01 0:57 ` [PATCH v6 3/5] MIPS: Octeon: Add irq handlers for GPIO interrupts David Daney
@ 2012-03-01 0:57 ` David Daney
2012-03-02 14:22 ` Rob Herring
2012-03-02 19:02 ` Grant Likely
2012-03-01 0:57 ` [PATCH v6 5/5] MIPS: Octeon: Initialize and fixup device tree David Daney
4 siblings, 2 replies; 20+ messages in thread
From: David Daney @ 2012-03-01 0:57 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, Grant Likely, Rob Herring
Cc: linux-kernel, David Daney
From: David Daney <david.daney@cavium.com>
Select IRQ_DOMAIN so the core irq_domain code and supply
irq_create_of_mapping().
Signed-off-by: David Daney <david.daney@cavium.com>
---
arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/octeon-irq.c | 301 +++++++++++++++++++++++++++-------
2 files changed, 239 insertions(+), 63 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ce30e2f..01344ae 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
+ select IRQ_DOMAIN
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index bdcedd3..e9f2f6c 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -3,14 +3,16 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
+ * Copyright (C) 2004-2008, 2009, 2010, 2011, 2012 Cavium Networks
*/
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/bitops.h>
#include <linux/percpu.h>
#include <linux/irq.h>
#include <linux/smp.h>
+#include <linux/of.h>
#include <asm/octeon/octeon.h>
@@ -42,20 +44,27 @@ struct octeon_core_chip_data {
static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
-static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
+static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
+ unsigned int line,
+ unsigned int bit,
+ struct irq_domain *domain,
struct irq_chip *chip,
irq_flow_handler_t handler)
{
+ struct irq_data *irqd;
union octeon_ciu_chip_data cd;
irq_set_chip_and_handler(irq, chip, handler);
-
cd.l = 0;
cd.s.line = line;
cd.s.bit = bit;
irq_set_chip_data(irq, cd.p);
octeon_irq_ciu_to_irq[line][bit] = irq;
+
+ irqd = irq_get_irq_data(irq);
+ irqd->hwirq = line << 6 | bit;
+ irqd->domain = domain;
}
static int octeon_coreid_for_cpu(int cpu)
@@ -855,6 +864,107 @@ static struct irq_chip octeon_irq_chip_ciu_wd = {
.irq_mask = octeon_irq_dummy_mask,
};
+static int octeon_irq_gpio_xlat(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ unsigned int irq;
+ unsigned int type;
+ unsigned int ciu = 0, bit = 0;
+ unsigned int pin;
+ unsigned int trigger;
+ bool set_edge_handler = false;
+
+ if (d->of_node != node)
+ return -EINVAL;
+
+ if (intsize < 2)
+ return -EINVAL;
+
+ pin = intspec[0];
+ if (pin >= 16)
+ return -EINVAL;
+
+ trigger = intspec[1];
+
+ switch (trigger) {
+ case 1:
+ type = IRQ_TYPE_EDGE_RISING;
+ set_edge_handler = true;
+ break;
+ case 2:
+ type = IRQ_TYPE_EDGE_FALLING;
+ set_edge_handler = true;
+ break;
+ case 4:
+ type = IRQ_TYPE_LEVEL_HIGH;
+ break;
+ case 8:
+ type = IRQ_TYPE_LEVEL_LOW;
+ break;
+ default:
+ pr_err("Error: (%s) Invalid irq trigger specification: %x\n",
+ node->name,
+ trigger);
+ type = IRQ_TYPE_LEVEL_LOW;
+ break;
+ }
+ *out_type = type;
+ *out_hwirq = ((unsigned long)d->host_data) + pin;
+
+ ciu = *out_hwirq >> 6;
+ bit = *out_hwirq & 0x3f;
+
+ irq = octeon_irq_ciu_to_irq[ciu][bit];
+
+ if (set_edge_handler)
+ __irq_set_handler(irq, handle_edge_irq, 0, NULL);
+
+ return 0;
+}
+
+static int octeon_irq_ciu_xlat(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ unsigned int ciu, bit;
+
+ ciu = intspec[0];
+ bit = intspec[1];
+
+ if (ciu > 1 || bit > 63)
+ return -EINVAL;
+
+ if (octeon_irq_ciu_to_irq[ciu][bit] == 0)
+ return -EINVAL;
+
+ *out_hwirq = (ciu << 6) | bit;
+ *out_type = 0;
+
+ return 0;
+}
+static int octeon_irq_dummy_map(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ return 0;
+}
+
+static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
+ .map = octeon_irq_dummy_map,
+ .xlate = octeon_irq_ciu_xlat,
+};
+
+static struct irq_domain_ops octeon_irq_domain_gpio_ops = {
+ .map = octeon_irq_dummy_map,
+ .xlate = octeon_irq_gpio_xlat,
+};
+
static void octeon_irq_ip2_v1(void)
{
const unsigned long core_id = cvmx_get_core_num();
@@ -982,6 +1092,10 @@ static void __init octeon_irq_init_ciu(void)
struct irq_chip *chip_mbox;
struct irq_chip *chip_wd;
struct irq_chip *chip_gpio;
+ struct device_node *gpio_node;
+ struct device_node *ciu_node;
+ struct irq_domain *gpio_domain;
+ struct irq_domain *ciu_domain;
octeon_irq_init_ciu_percpu();
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
@@ -1011,83 +1125,144 @@ static void __init octeon_irq_init_ciu(void)
/* Mips internal */
octeon_irq_init_core();
+ gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
+ ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
+ /* gpio domain host_data is the base hwirq number. */
+ gpio_domain = irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_gpio_ops, (void *)16);
+ ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
+
/* CIU_0 */
for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0,
+ ciu_domain, chip, handle_level_irq);
+
for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip_gpio, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16,
+ gpio_domain, chip_gpio, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32,
+ ciu_domain, chip_mbox, handle_percpu_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33,
+ ciu_domain, chip_mbox, handle_percpu_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35,
+ ciu_domain, chip, handle_level_irq);
for (i = 0; i < 4; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36,
+ ciu_domain, chip, handle_level_irq);
for (i = 0; i < 4; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40,
+ ciu_domain, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47,
+ ciu_domain, chip, handle_level_irq);
for (i = 0; i < 2; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48,
+ ciu_domain, chip_edge, handle_edge_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50,
+ ciu_domain, chip_edge, handle_edge_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51,
+ ciu_domain, chip_edge, handle_edge_irq);
for (i = 0; i < 4; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52,
+ ciu_domain, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63,
+ ciu_domain, chip, handle_level_irq);
/* CIU_1 */
for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0,
+ ciu_domain, chip_wd, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35,
+ ciu_domain, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36,
+ ciu_domain, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46,
+ ciu_domain, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47,
+ ciu_domain, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56,
+ ciu_domain, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63,
+ ciu_domain, chip, handle_level_irq);
/* Enable the CIU lines */
set_c0_status(STATUSF_IP3 | STATUSF_IP2);
--
1.7.2.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-01 0:57 ` [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts David Daney
@ 2012-03-02 14:22 ` Rob Herring
2012-03-02 18:03 ` David Daney
2012-03-02 19:02 ` Grant Likely
1 sibling, 1 reply; 20+ messages in thread
From: Rob Herring @ 2012-03-02 14:22 UTC (permalink / raw)
To: David Daney
Cc: linux-mips, ralf, devicetree-discuss, Grant Likely, Rob Herring,
linux-kernel, David Daney
David,
On 02/29/2012 06:57 PM, David Daney wrote:
> From: David Daney <david.daney@cavium.com>
>
> Select IRQ_DOMAIN so the core irq_domain code and supply
> irq_create_of_mapping().
>
> Signed-off-by: David Daney <david.daney@cavium.com>
> ---
> arch/mips/Kconfig | 1 +
> arch/mips/cavium-octeon/octeon-irq.c | 301 +++++++++++++++++++++++++++-------
> 2 files changed, 239 insertions(+), 63 deletions(-)
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index ce30e2f..01344ae 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
> select WEAK_ORDERING
> select CPU_SUPPORTS_HIGHMEM
> select CPU_SUPPORTS_HUGEPAGES
> + select IRQ_DOMAIN
IIRC, Grant has a patch cued up that enables IRQ_DOMAIN for all of MIPS.
> help
> The Cavium Octeon processor is a highly integrated chip containing
> many ethernet hardware widgets for networking tasks. The processor
> diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
> index bdcedd3..e9f2f6c 100644
> --- a/arch/mips/cavium-octeon/octeon-irq.c
> +++ b/arch/mips/cavium-octeon/octeon-irq.c
> @@ -3,14 +3,16 @@
> * License. See the file "COPYING" in the main directory of this archive
> * for more details.
> *
> - * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
> + * Copyright (C) 2004-2008, 2009, 2010, 2011, 2012 Cavium Networks
> */.
>
> #include <linux/interrupt.h>
> +#include <linux/irqdomain.h>
> #include <linux/bitops.h>
> #include <linux/percpu.h>
> #include <linux/irq.h>
> #include <linux/smp.h>
> +#include <linux/of.h>
>
> #include <asm/octeon/octeon.h>
>
> @@ -42,20 +44,27 @@ struct octeon_core_chip_data {
>
> static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
>
> -static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
> +static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
> + unsigned int line,
> + unsigned int bit,
> + struct irq_domain *domain,
> struct irq_chip *chip,
> irq_flow_handler_t handler)
> {
> + struct irq_data *irqd;
> union octeon_ciu_chip_data cd;
>
> irq_set_chip_and_handler(irq, chip, handler);
> -
> cd.l = 0;
> cd.s.line = line;
> cd.s.bit = bit;
>
> irq_set_chip_data(irq, cd.p);
> octeon_irq_ciu_to_irq[line][bit] = irq;
> +
> + irqd = irq_get_irq_data(irq);
> + irqd->hwirq = line << 6 | bit;
> + irqd->domain = domain;
I think the domain code will set these.
> }
>
> static int octeon_coreid_for_cpu(int cpu)
> @@ -855,6 +864,107 @@ static struct irq_chip octeon_irq_chip_ciu_wd = {
> .irq_mask = octeon_irq_dummy_mask,
> };
>
> +static int octeon_irq_gpio_xlat(struct irq_domain *d,
> + struct device_node *node,
> + const u32 *intspec,
> + unsigned int intsize,
> + unsigned long *out_hwirq,
> + unsigned int *out_type)
> +{
> + unsigned int irq;
> + unsigned int type;
> + unsigned int ciu = 0, bit = 0;
> + unsigned int pin;
> + unsigned int trigger;
> + bool set_edge_handler = false;
> +
> + if (d->of_node != node)
> + return -EINVAL;
> +
> + if (intsize < 2)
> + return -EINVAL;
> +
> + pin = intspec[0];
> + if (pin >= 16)
> + return -EINVAL;
> +
> + trigger = intspec[1];
> +
> + switch (trigger) {
> + case 1:
> + type = IRQ_TYPE_EDGE_RISING;
> + set_edge_handler = true;
> + break;
> + case 2:
> + type = IRQ_TYPE_EDGE_FALLING;
> + set_edge_handler = true;
> + break;
> + case 4:
> + type = IRQ_TYPE_LEVEL_HIGH;
> + break;
> + case 8:
> + type = IRQ_TYPE_LEVEL_LOW;
> + break;
> + default:
> + pr_err("Error: (%s) Invalid irq trigger specification: %x\n",
> + node->name,
> + trigger);
> + type = IRQ_TYPE_LEVEL_LOW;
> + break;
> + }
> + *out_type = type;
> + *out_hwirq = ((unsigned long)d->host_data) + pin;
> +
> + ciu = *out_hwirq >> 6;
> + bit = *out_hwirq & 0x3f;
> +
> + irq = octeon_irq_ciu_to_irq[ciu][bit];
> +
> + if (set_edge_handler)
> + __irq_set_handler(irq, handle_edge_irq, 0, NULL);
> +
> + return 0;
> +}
> +
> +static int octeon_irq_ciu_xlat(struct irq_domain *d,
> + struct device_node *node,
> + const u32 *intspec,
> + unsigned int intsize,
> + unsigned long *out_hwirq,
> + unsigned int *out_type)
> +{
> + unsigned int ciu, bit;
> +
> + ciu = intspec[0];
> + bit = intspec[1];
> +
> + if (ciu > 1 || bit > 63)
> + return -EINVAL;
> +
> + if (octeon_irq_ciu_to_irq[ciu][bit] == 0)
> + return -EINVAL;
> +
> + *out_hwirq = (ciu << 6) | bit;
> + *out_type = 0;
> +
> + return 0;
> +}
> +static int octeon_irq_dummy_map(struct irq_domain *d,
> + unsigned int virq, irq_hw_number_t hw)
> +{
> + return 0;
> +}
> +
> +static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
> + .map = octeon_irq_dummy_map,
> + .xlate = octeon_irq_ciu_xlat,
> +};
> +
> +static struct irq_domain_ops octeon_irq_domain_gpio_ops = {
> + .map = octeon_irq_dummy_map,
> + .xlate = octeon_irq_gpio_xlat,
> +};
> +
> static void octeon_irq_ip2_v1(void)
> {
> const unsigned long core_id = cvmx_get_core_num();
> @@ -982,6 +1092,10 @@ static void __init octeon_irq_init_ciu(void)
> struct irq_chip *chip_mbox;
> struct irq_chip *chip_wd;
> struct irq_chip *chip_gpio;
> + struct device_node *gpio_node;
> + struct device_node *ciu_node;
> + struct irq_domain *gpio_domain;
> + struct irq_domain *ciu_domain;
>
> octeon_irq_init_ciu_percpu();
> octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
> @@ -1011,83 +1125,144 @@ static void __init octeon_irq_init_ciu(void)
> /* Mips internal */
> octeon_irq_init_core();
>
> + gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
> + ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
> + /* gpio domain host_data is the base hwirq number. */
> + gpio_domain = irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_gpio_ops, (void *)16);
It would be better to define a struct here rather than casting a data
value to a ptr.
> + ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
> +
> /* CIU_0 */
> for (i = 0; i < 16; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0,
> + ciu_domain, chip, handle_level_irq);
> +
> for (i = 0; i < 16; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip_gpio, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16,
> + gpio_domain, chip_gpio, handle_level_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32,
> + ciu_domain, chip_mbox, handle_percpu_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33,
> + ciu_domain, chip_mbox, handle_percpu_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35,
> + ciu_domain, chip, handle_level_irq);
>
> for (i = 0; i < 4; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36,
> + ciu_domain, chip, handle_level_irq);
> for (i = 0; i < 4; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40,
> + ciu_domain, chip, handle_level_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47,
> + ciu_domain, chip, handle_level_irq);
>
> for (i = 0; i < 2; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48,
> + ciu_domain, chip_edge, handle_edge_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50,
> + ciu_domain, chip_edge, handle_edge_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51,
> + ciu_domain, chip_edge, handle_edge_irq);
>
> for (i = 0; i < 4; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52,
> + ciu_domain, chip_edge, handle_edge_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63,
> + ciu_domain, chip, handle_level_irq);
>
> /* CIU_1 */
> for (i = 0; i < 16; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0,
> + ciu_domain, chip_wd, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35,
> + ciu_domain, chip, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36,
> + ciu_domain, chip, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46,
> + ciu_domain, chip, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47,
> + ciu_domain, chip_edge, handle_edge_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63,
> + ciu_domain, chip, handle_level_irq);
>
Can all these calls be moved into the .map function somehow?
edge vs. level should be driven by dts.
Rob
> /* Enable the CIU lines */
> set_c0_status(STATUSF_IP3 | STATUSF_IP2);
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-02 14:22 ` Rob Herring
@ 2012-03-02 18:03 ` David Daney
2012-03-02 19:07 ` Grant Likely
2012-03-03 19:38 ` Rob Herring
0 siblings, 2 replies; 20+ messages in thread
From: David Daney @ 2012-03-02 18:03 UTC (permalink / raw)
To: Rob Herring
Cc: David Daney, linux-mips, ralf, devicetree-discuss, Grant Likely,
Rob Herring, linux-kernel
On 03/02/2012 06:22 AM, Rob Herring wrote:
[...]
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index ce30e2f..01344ae 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
>> select WEAK_ORDERING
>> select CPU_SUPPORTS_HIGHMEM
>> select CPU_SUPPORTS_HUGEPAGES
>> + select IRQ_DOMAIN
>
> IIRC, Grant has a patch cued up that enables IRQ_DOMAIN for all of MIPS.
>
Indeed, I now see it in linux-next. I will remove this one.
>> help
>> The Cavium Octeon processor is a highly integrated chip containing
>> many ethernet hardware widgets for networking tasks. The processor
>> diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
>> index bdcedd3..e9f2f6c 100644
>> --- a/arch/mips/cavium-octeon/octeon-irq.c
>> +++ b/arch/mips/cavium-octeon/octeon-irq.c
[...]
>> +static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
>> + unsigned int line,
>> + unsigned int bit,
>> + struct irq_domain *domain,
>> struct irq_chip *chip,
>> irq_flow_handler_t handler)
>> {
>> + struct irq_data *irqd;
>> union octeon_ciu_chip_data cd;
>>
>> irq_set_chip_and_handler(irq, chip, handler);
>> -
>> cd.l = 0;
>> cd.s.line = line;
>> cd.s.bit = bit;
>>
>> irq_set_chip_data(irq, cd.p);
>> octeon_irq_ciu_to_irq[line][bit] = irq;
>> +
>> + irqd = irq_get_irq_data(irq);
>> + irqd->hwirq = line<< 6 | bit;
>> + irqd->domain = domain;
>
> I think the domain code will set these.
It is my understanding that the domain code only does this for:
o irq_domain_add_legacy()
o irq_create_direct_mapping()
o irq_create_mapping()
We use none of those. So I do it here.
If there is a better way, I am open to suggestions.
[...]
>> @@ -982,6 +1092,10 @@ static void __init octeon_irq_init_ciu(void)
>> struct irq_chip *chip_mbox;
>> struct irq_chip *chip_wd;
>> struct irq_chip *chip_gpio;
>> + struct device_node *gpio_node;
>> + struct device_node *ciu_node;
>> + struct irq_domain *gpio_domain;
>> + struct irq_domain *ciu_domain;
>>
>> octeon_irq_init_ciu_percpu();
>> octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
>> @@ -1011,83 +1125,144 @@ static void __init octeon_irq_init_ciu(void)
>> /* Mips internal */
>> octeon_irq_init_core();
>>
>> + gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
>> + ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
>> + /* gpio domain host_data is the base hwirq number. */
>> + gpio_domain = irq_domain_add_linear(gpio_node, 16,&octeon_irq_domain_gpio_ops, (void *)16);
>
> It would be better to define a struct here rather than casting a data
> value to a ptr.
You mean allocate storage for the data somewhere and then pass a pointer
to it?
If so, I could, but it would just be adding code and data size just to
satisfy some coding style thing...
Or do you want a union of the pointer and my int? That would use the
same amount of storage, but add more source code to gain what?
[...]
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48,
>> + ciu_domain, chip, handle_level_irq);
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49,
>> + ciu_domain, chip, handle_level_irq);
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50,
>> + ciu_domain, chip, handle_level_irq);
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51,
>> + ciu_domain, chip, handle_level_irq);
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52,
>> + ciu_domain, chip, handle_level_irq);
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56,
>> + ciu_domain, chip, handle_level_irq);
>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63,
>> + ciu_domain, chip, handle_level_irq);
>>
>
> Can all these calls be moved into the .map function somehow?
>
No, the non-OF code using the OCTEON_IRQ_* symbols doesn't use
irq_domain, so the .map function would never be used.
> edge vs. level should be driven by dts.
>
We may have to disagree on this point. Because:
1) edge vs. level can be accurately probed, as we do here.
2) The dts doesnt contain the information.
David Daney
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-02 18:03 ` David Daney
@ 2012-03-02 19:07 ` Grant Likely
2012-03-02 19:29 ` David Daney
2012-03-03 19:38 ` Rob Herring
1 sibling, 1 reply; 20+ messages in thread
From: Grant Likely @ 2012-03-02 19:07 UTC (permalink / raw)
To: David Daney, Rob Herring
Cc: David Daney, linux-mips, ralf, devicetree-discuss, Rob Herring,
linux-kernel
On Fri, 02 Mar 2012 10:03:58 -0800, David Daney <david.daney@cavium.com> wrote:
> On 03/02/2012 06:22 AM, Rob Herring wrote:
> [...]
> >> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> >> index ce30e2f..01344ae 100644
> >> --- a/arch/mips/Kconfig
> >> +++ b/arch/mips/Kconfig
> >> @@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
> >> select WEAK_ORDERING
> >> select CPU_SUPPORTS_HIGHMEM
> >> select CPU_SUPPORTS_HUGEPAGES
> >> + select IRQ_DOMAIN
> >
> > IIRC, Grant has a patch cued up that enables IRQ_DOMAIN for all of MIPS.
> >
>
> Indeed, I now see it in linux-next. I will remove this one.
>
> >> help
> >> The Cavium Octeon processor is a highly integrated chip containing
> >> many ethernet hardware widgets for networking tasks. The processor
> >> diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
> >> index bdcedd3..e9f2f6c 100644
> >> --- a/arch/mips/cavium-octeon/octeon-irq.c
> >> +++ b/arch/mips/cavium-octeon/octeon-irq.c
> [...]
> >> +static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
> >> + unsigned int line,
> >> + unsigned int bit,
> >> + struct irq_domain *domain,
> >> struct irq_chip *chip,
> >> irq_flow_handler_t handler)
> >> {
> >> + struct irq_data *irqd;
> >> union octeon_ciu_chip_data cd;
> >>
> >> irq_set_chip_and_handler(irq, chip, handler);
> >> -
> >> cd.l = 0;
> >> cd.s.line = line;
> >> cd.s.bit = bit;
> >>
> >> irq_set_chip_data(irq, cd.p);
> >> octeon_irq_ciu_to_irq[line][bit] = irq;
> >> +
> >> + irqd = irq_get_irq_data(irq);
> >> + irqd->hwirq = line<< 6 | bit;
> >> + irqd->domain = domain;
> >
> > I think the domain code will set these.
>
> It is my understanding that the domain code only does this for:
>
> o irq_domain_add_legacy()
>
> o irq_create_direct_mapping()
>
> o irq_create_mapping()
>
> We use none of those. So I do it here.
>
> If there is a better way, I am open to suggestions.
irq_create_mapping is called by irq_create_of_mapping() which is
in turn called by irq_of_parse_and-map(). irq_domain always
manages the hwirq and domain values. Driver code cannot manipulate
them manually.
g.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-02 19:07 ` Grant Likely
@ 2012-03-02 19:29 ` David Daney
[not found] ` <4F511FB0.5070901-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 20+ messages in thread
From: David Daney @ 2012-03-02 19:29 UTC (permalink / raw)
To: Grant Likely
Cc: Rob Herring, David Daney, linux-mips@linux-mips.org,
ralf@linux-mips.org, devicetree-discuss@lists.ozlabs.org,
Rob Herring, linux-kernel@vger.kernel.org
On 03/02/2012 11:07 AM, Grant Likely wrote:
> On Fri, 02 Mar 2012 10:03:58 -0800, David Daney<david.daney@cavium.com> wrote:
>> On 03/02/2012 06:22 AM, Rob Herring wrote:
>> [...]
>>>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>>>> index ce30e2f..01344ae 100644
>>>> --- a/arch/mips/Kconfig
>>>> +++ b/arch/mips/Kconfig
>>>> @@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
>>>> select WEAK_ORDERING
>>>> select CPU_SUPPORTS_HIGHMEM
>>>> select CPU_SUPPORTS_HUGEPAGES
>>>> + select IRQ_DOMAIN
>>>
>>> IIRC, Grant has a patch cued up that enables IRQ_DOMAIN for all of MIPS.
>>>
>>
>> Indeed, I now see it in linux-next. I will remove this one.
>>
>>>> help
>>>> The Cavium Octeon processor is a highly integrated chip containing
>>>> many ethernet hardware widgets for networking tasks. The processor
>>>> diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
>>>> index bdcedd3..e9f2f6c 100644
>>>> --- a/arch/mips/cavium-octeon/octeon-irq.c
>>>> +++ b/arch/mips/cavium-octeon/octeon-irq.c
>> [...]
>>>> +static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
>>>> + unsigned int line,
>>>> + unsigned int bit,
>>>> + struct irq_domain *domain,
>>>> struct irq_chip *chip,
>>>> irq_flow_handler_t handler)
>>>> {
>>>> + struct irq_data *irqd;
>>>> union octeon_ciu_chip_data cd;
>>>>
>>>> irq_set_chip_and_handler(irq, chip, handler);
>>>> -
>>>> cd.l = 0;
>>>> cd.s.line = line;
>>>> cd.s.bit = bit;
>>>>
>>>> irq_set_chip_data(irq, cd.p);
>>>> octeon_irq_ciu_to_irq[line][bit] = irq;
>>>> +
>>>> + irqd = irq_get_irq_data(irq);
>>>> + irqd->hwirq = line<< 6 | bit;
>>>> + irqd->domain = domain;
>>>
>>> I think the domain code will set these.
>>
>> It is my understanding that the domain code only does this for:
>>
>> o irq_domain_add_legacy()
>>
>> o irq_create_direct_mapping()
>>
>> o irq_create_mapping()
>>
>> We use none of those. So I do it here.
>>
>> If there is a better way, I am open to suggestions.
>
> irq_create_mapping is called by irq_create_of_mapping() which is
> in turn called by irq_of_parse_and-map(). irq_domain always
> manages the hwirq and domain values. Driver code cannot manipulate
> them manually.
>
I really must be missing something.
Given:
1) I must have a mapping between hwirq and irq that I control so that
non-OF code using the OCTEON_IRQ_* constants continues to work.
2) irq_create_mapping() will allocate a random irq value if none is
already assigned to the hwirq.
Therefore: To avoid having random irq values assigned, I must manually
assign them.
David Daney
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-02 18:03 ` David Daney
2012-03-02 19:07 ` Grant Likely
@ 2012-03-03 19:38 ` Rob Herring
2012-03-04 5:41 ` David Daney
1 sibling, 1 reply; 20+ messages in thread
From: Rob Herring @ 2012-03-03 19:38 UTC (permalink / raw)
To: David Daney
Cc: David Daney, linux-mips, ralf, devicetree-discuss, Grant Likely,
Rob Herring, linux-kernel
On 03/02/2012 12:03 PM, David Daney wrote:
> On 03/02/2012 06:22 AM, Rob Herring wrote:
> [...]
>>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>>> index ce30e2f..01344ae 100644
>>> --- a/arch/mips/Kconfig
>>> +++ b/arch/mips/Kconfig
>>> @@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
>>> select WEAK_ORDERING
>>> select CPU_SUPPORTS_HIGHMEM
>>> select CPU_SUPPORTS_HUGEPAGES
>>> + select IRQ_DOMAIN
>>
>> IIRC, Grant has a patch cued up that enables IRQ_DOMAIN for all of MIPS.
>>
>
> Indeed, I now see it in linux-next. I will remove this one.
>
>>> help
>>> The Cavium Octeon processor is a highly integrated chip
>>> containing
>>> many ethernet hardware widgets for networking tasks. The
>>> processor
>>> diff --git a/arch/mips/cavium-octeon/octeon-irq.c
>>> b/arch/mips/cavium-octeon/octeon-irq.c
>>> index bdcedd3..e9f2f6c 100644
>>> --- a/arch/mips/cavium-octeon/octeon-irq.c
>>> +++ b/arch/mips/cavium-octeon/octeon-irq.c
> [...]
>>> +static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
>>> + unsigned int line,
>>> + unsigned int bit,
>>> + struct irq_domain *domain,
>>> struct irq_chip *chip,
>>> irq_flow_handler_t handler)
>>> {
>>> + struct irq_data *irqd;
>>> union octeon_ciu_chip_data cd;
>>>
>>> irq_set_chip_and_handler(irq, chip, handler);
>>> -
>>> cd.l = 0;
>>> cd.s.line = line;
>>> cd.s.bit = bit;
>>>
>>> irq_set_chip_data(irq, cd.p);
>>> octeon_irq_ciu_to_irq[line][bit] = irq;
>>> +
>>> + irqd = irq_get_irq_data(irq);
>>> + irqd->hwirq = line<< 6 | bit;
>>> + irqd->domain = domain;
>>
>> I think the domain code will set these.
>
> It is my understanding that the domain code only does this for:
>
> o irq_domain_add_legacy()
>
> o irq_create_direct_mapping()
>
> o irq_create_mapping()
>
> We use none of those. So I do it here.
>
> If there is a better way, I am open to suggestions.
How do you convert local h/w irq controller numbers in the dts to linux
irq #'s?
>
> [...]
>>> @@ -982,6 +1092,10 @@ static void __init octeon_irq_init_ciu(void)
>>> struct irq_chip *chip_mbox;
>>> struct irq_chip *chip_wd;
>>> struct irq_chip *chip_gpio;
>>> + struct device_node *gpio_node;
>>> + struct device_node *ciu_node;
>>> + struct irq_domain *gpio_domain;
>>> + struct irq_domain *ciu_domain;
>>>
>>> octeon_irq_init_ciu_percpu();
>>> octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
>>> @@ -1011,83 +1125,144 @@ static void __init octeon_irq_init_ciu(void)
>>> /* Mips internal */
>>> octeon_irq_init_core();
>>>
>>> + gpio_node = of_find_compatible_node(NULL, NULL,
>>> "cavium,octeon-3860-gpio");
>>> + ciu_node = of_find_compatible_node(NULL, NULL,
>>> "cavium,octeon-3860-ciu");
>>> + /* gpio domain host_data is the base hwirq number. */
>>> + gpio_domain = irq_domain_add_linear(gpio_node,
>>> 16,&octeon_irq_domain_gpio_ops, (void *)16);
>>
>> It would be better to define a struct here rather than casting a data
>> value to a ptr.
>
> You mean allocate storage for the data somewhere and then pass a pointer
> to it?
>
> If so, I could, but it would just be adding code and data size just to
> satisfy some coding style thing...
>
> Or do you want a union of the pointer and my int? That would use the
> same amount of storage, but add more source code to gain what?
The former. It's better style, less error prone and easily expanded if
more data is needed in the future.
>
> [...]
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48,
>>> + ciu_domain, chip, handle_level_irq);
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49,
>>> + ciu_domain, chip, handle_level_irq);
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50,
>>> + ciu_domain, chip, handle_level_irq);
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51,
>>> + ciu_domain, chip, handle_level_irq);
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52,
>>> + ciu_domain, chip, handle_level_irq);
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56,
>>> + ciu_domain, chip, handle_level_irq);
>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63,
>>> + ciu_domain, chip, handle_level_irq);
>>>
>>
>> Can all these calls be moved into the .map function somehow?
>>
>
> No, the non-OF code using the OCTEON_IRQ_* symbols doesn't use
> irq_domain, so the .map function would never be used.
>
.map is called for legacy domains during domain add.
>
>> edge vs. level should be driven by dts.
>>
>
> We may have to disagree on this point. Because:
>
> 1) edge vs. level can be accurately probed, as we do here.
Looks like you are just hard coding it here. Where do you read something
that tells you the interrupt is level or edge?
Rob
>
> 2) The dts doesnt contain the information.
>
>
> David Daney
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-03 19:38 ` Rob Herring
@ 2012-03-04 5:41 ` David Daney
0 siblings, 0 replies; 20+ messages in thread
From: David Daney @ 2012-03-04 5:41 UTC (permalink / raw)
To: Rob Herring
Cc: David Daney, David Daney, linux-mips, ralf, devicetree-discuss,
Grant Likely, Rob Herring, linux-kernel
On 03/03/2012 11:38 AM, Rob Herring wrote:
> On 03/02/2012 12:03 PM, David Daney wrote:
>> +
>> + irqd = irq_get_irq_data(irq);
>> + irqd->hwirq = line<< 6 | bit;
>> + irqd->domain = domain;
>>> I think the domain code will set these.
>> It is my understanding that the domain code only does this for:
>>
>> o irq_domain_add_legacy()
>>
>> o irq_create_direct_mapping()
>>
>> o irq_create_mapping()
>>
>> We use none of those. So I do it here.
>>
>> If there is a better way, I am open to suggestions.
> How do you convert local h/w irq controller numbers in the dts to linux
> irq #'s?
With the calls to octeon_irq_set_ciu_mapping() ...
[...]
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48,
>>>> + ciu_domain, chip, handle_level_irq);
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49,
>>>> + ciu_domain, chip, handle_level_irq);
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50,
>>>> + ciu_domain, chip, handle_level_irq);
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51,
>>>> + ciu_domain, chip, handle_level_irq);
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52,
>>>> + ciu_domain, chip, handle_level_irq);
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56,
>>>> + ciu_domain, chip, handle_level_irq);
>>>> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63,
>>>> + ciu_domain, chip, handle_level_irq);
>>>>
>>>> [...]
>>> edge vs. level should be driven by dts.
>>>
>> We may have to disagree on this point. Because:
>>
>> 1) edge vs. level can be accurately probed, as we do here.
> Looks like you are just hard coding it here. Where do you read something
> that tells you the interrupt is level or edge?
We probe for the type of interrupt controller by reading the SOC
identifier number, although we can get the same information from the dts.
Once we know the type of interrupt controller, the level vs. edge is
known a priori, and that knowlege is encoded in all these
octeon_irq_set_ciu_mapping() calls.
And on top of this...
>> 2) The dts doesn't contain the information.
>>
So it is kind of a moot point.
It is not some sort of generic interrupt controller that can be
configured in different ways, each line has certain properties endowed
upon it by the chip designers, and once a line is assigned a particular
configuration, it is never changed in future generations.
For external devices attached to the GPIO interrupt lines, things are
different, we can only know the triggering via the dts, and lo and
behold... it is there and we use it.
David Daney
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts.
2012-03-01 0:57 ` [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts David Daney
2012-03-02 14:22 ` Rob Herring
@ 2012-03-02 19:02 ` Grant Likely
1 sibling, 0 replies; 20+ messages in thread
From: Grant Likely @ 2012-03-02 19:02 UTC (permalink / raw)
To: David Daney, linux-mips, ralf, devicetree-discuss, Rob Herring
Cc: linux-kernel, David Daney
On Wed, 29 Feb 2012 16:57:01 -0800, David Daney <ddaney.cavm@gmail.com> wrote:
> From: David Daney <david.daney@cavium.com>
>
> Select IRQ_DOMAIN so the core irq_domain code and supply
> irq_create_of_mapping().
>
> Signed-off-by: David Daney <david.daney@cavium.com>
> ---
> arch/mips/Kconfig | 1 +
> arch/mips/cavium-octeon/octeon-irq.c | 301 +++++++++++++++++++++++++++-------
> 2 files changed, 239 insertions(+), 63 deletions(-)
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index ce30e2f..01344ae 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -1432,6 +1432,7 @@ config CPU_CAVIUM_OCTEON
> select WEAK_ORDERING
> select CPU_SUPPORTS_HIGHMEM
> select CPU_SUPPORTS_HUGEPAGES
> + select IRQ_DOMAIN
> help
> The Cavium Octeon processor is a highly integrated chip containing
> many ethernet hardware widgets for networking tasks. The processor
> diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
> index bdcedd3..e9f2f6c 100644
> --- a/arch/mips/cavium-octeon/octeon-irq.c
> +++ b/arch/mips/cavium-octeon/octeon-irq.c
> @@ -3,14 +3,16 @@
> * License. See the file "COPYING" in the main directory of this archive
> * for more details.
> *
> - * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
> + * Copyright (C) 2004-2008, 2009, 2010, 2011, 2012 Cavium Networks
> */
>
> #include <linux/interrupt.h>
> +#include <linux/irqdomain.h>
> #include <linux/bitops.h>
> #include <linux/percpu.h>
> #include <linux/irq.h>
> #include <linux/smp.h>
> +#include <linux/of.h>
>
> #include <asm/octeon/octeon.h>
>
> @@ -42,20 +44,27 @@ struct octeon_core_chip_data {
>
> static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
>
> -static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
> +static void __init octeon_irq_set_ciu_mapping(unsigned int irq,
> + unsigned int line,
> + unsigned int bit,
> + struct irq_domain *domain,
> struct irq_chip *chip,
> irq_flow_handler_t handler)
> {
> + struct irq_data *irqd;
> union octeon_ciu_chip_data cd;
>
> irq_set_chip_and_handler(irq, chip, handler);
> -
> cd.l = 0;
> cd.s.line = line;
> cd.s.bit = bit;
>
> irq_set_chip_data(irq, cd.p);
> octeon_irq_ciu_to_irq[line][bit] = irq;
> +
> + irqd = irq_get_irq_data(irq);
> + irqd->hwirq = line << 6 | bit;
irqdomain sets up hwirq for you. Don't set it manually because it will
mess up irqdomain mappings.
> + irqd->domain = domain;
Ditto here; irqdomain manages the domain pointer internally.
> }
>
> static int octeon_coreid_for_cpu(int cpu)
> @@ -855,6 +864,107 @@ static struct irq_chip octeon_irq_chip_ciu_wd = {
> .irq_mask = octeon_irq_dummy_mask,
> };
>
> +static int octeon_irq_gpio_xlat(struct irq_domain *d,
> + struct device_node *node,
> + const u32 *intspec,
> + unsigned int intsize,
> + unsigned long *out_hwirq,
> + unsigned int *out_type)
> +{
> + unsigned int irq;
> + unsigned int type;
> + unsigned int ciu = 0, bit = 0;
> + unsigned int pin;
> + unsigned int trigger;
> + bool set_edge_handler = false;
> +
> + if (d->of_node != node)
> + return -EINVAL;
> +
> + if (intsize < 2)
> + return -EINVAL;
> +
> + pin = intspec[0];
> + if (pin >= 16)
> + return -EINVAL;
> +
> + trigger = intspec[1];
> +
> + switch (trigger) {
> + case 1:
> + type = IRQ_TYPE_EDGE_RISING;
> + set_edge_handler = true;
> + break;
> + case 2:
> + type = IRQ_TYPE_EDGE_FALLING;
> + set_edge_handler = true;
> + break;
> + case 4:
> + type = IRQ_TYPE_LEVEL_HIGH;
> + break;
> + case 8:
> + type = IRQ_TYPE_LEVEL_LOW;
> + break;
> + default:
> + pr_err("Error: (%s) Invalid irq trigger specification: %x\n",
> + node->name,
> + trigger);
> + type = IRQ_TYPE_LEVEL_LOW;
> + break;
> + }
> + *out_type = type;
> + *out_hwirq = ((unsigned long)d->host_data) + pin;
> +
> + ciu = *out_hwirq >> 6;
> + bit = *out_hwirq & 0x3f;
> +
> + irq = octeon_irq_ciu_to_irq[ciu][bit];
Again; this is overstepping onto irqdomain responsibility. Don't set
up the irq in the xlate routine; only parse the date and if you need to
store extra data like 'set_edge_handler' (using the hwirq number as the
key). The irq setup must be done in the .map callback which will be
passed the actual irq number to be used.
> +
> + if (set_edge_handler)
> + __irq_set_handler(irq, handle_edge_irq, 0, NULL);
> +
> + return 0;
> +}
> +
> +static int octeon_irq_ciu_xlat(struct irq_domain *d,
> + struct device_node *node,
> + const u32 *intspec,
> + unsigned int intsize,
> + unsigned long *out_hwirq,
> + unsigned int *out_type)
> +{
> + unsigned int ciu, bit;
> +
> + ciu = intspec[0];
> + bit = intspec[1];
> +
> + if (ciu > 1 || bit > 63)
> + return -EINVAL;
> +
> + if (octeon_irq_ciu_to_irq[ciu][bit] == 0)
> + return -EINVAL;
> +
> + *out_hwirq = (ciu << 6) | bit;
> + *out_type = 0;
> +
> + return 0;
> +}
> +static int octeon_irq_dummy_map(struct irq_domain *d,
> + unsigned int virq, irq_hw_number_t hw)
> +{
> + return 0;
> +}
> +
> +static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
> + .map = octeon_irq_dummy_map,
> + .xlate = octeon_irq_ciu_xlat,
> +};
> +
> +static struct irq_domain_ops octeon_irq_domain_gpio_ops = {
> + .map = octeon_irq_dummy_map,
> + .xlate = octeon_irq_gpio_xlat,
> +};
> +
> static void octeon_irq_ip2_v1(void)
> {
> const unsigned long core_id = cvmx_get_core_num();
> @@ -982,6 +1092,10 @@ static void __init octeon_irq_init_ciu(void)
> struct irq_chip *chip_mbox;
> struct irq_chip *chip_wd;
> struct irq_chip *chip_gpio;
> + struct device_node *gpio_node;
> + struct device_node *ciu_node;
> + struct irq_domain *gpio_domain;
> + struct irq_domain *ciu_domain;
>
> octeon_irq_init_ciu_percpu();
> octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
> @@ -1011,83 +1125,144 @@ static void __init octeon_irq_init_ciu(void)
> /* Mips internal */
> octeon_irq_init_core();
>
> + gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
> + ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
> + /* gpio domain host_data is the base hwirq number. */
> + gpio_domain = irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_gpio_ops, (void *)16);
> + ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
> +
> /* CIU_0 */
> for (i = 0; i < 16; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0,
> + ciu_domain, chip, handle_level_irq);
> +
> for (i = 0; i < 16; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip_gpio, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16,
> + gpio_domain, chip_gpio, handle_level_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32,
> + ciu_domain, chip_mbox, handle_percpu_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33,
> + ciu_domain, chip_mbox, handle_percpu_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35,
> + ciu_domain, chip, handle_level_irq);
>
> for (i = 0; i < 4; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36,
> + ciu_domain, chip, handle_level_irq);
> for (i = 0; i < 4; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40,
> + ciu_domain, chip, handle_level_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47,
> + ciu_domain, chip, handle_level_irq);
>
> for (i = 0; i < 2; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48,
> + ciu_domain, chip_edge, handle_edge_irq);
>
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50,
> + ciu_domain, chip_edge, handle_edge_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51,
> + ciu_domain, chip_edge, handle_edge_irq);
>
> for (i = 0; i < 4; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52,
> + ciu_domain, chip_edge, handle_edge_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63,
> + ciu_domain, chip, handle_level_irq);
>
> /* CIU_1 */
> for (i = 0; i < 16; i++)
> - octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
> -
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
> - octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0,
> + ciu_domain, chip_wd, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35,
> + ciu_domain, chip, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36,
> + ciu_domain, chip, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46,
> + ciu_domain, chip, handle_level_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47,
> + ciu_domain, chip_edge, handle_edge_irq);
> +
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56,
> + ciu_domain, chip, handle_level_irq);
> + octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63,
> + ciu_domain, chip, handle_level_irq);
>
> /* Enable the CIU lines */
> set_c0_status(STATUSF_IP3 | STATUSF_IP2);
> --
> 1.7.2.3
>
--
email sent from notmuch.vim plugin
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v6 5/5] MIPS: Octeon: Initialize and fixup device tree.
2012-03-01 0:56 [PATCH v6 0/5] MIPS: Octeon: Use Device Tree David Daney
` (3 preceding siblings ...)
2012-03-01 0:57 ` [PATCH v6 4/5] MIPS: Octeon: Setup irq_domains for interrupts David Daney
@ 2012-03-01 0:57 ` David Daney
4 siblings, 0 replies; 20+ messages in thread
From: David Daney @ 2012-03-01 0:57 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, Grant Likely, Rob Herring
Cc: linux-kernel, David Daney
From: David Daney <david.daney@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
arch/mips/Kconfig | 2 +
arch/mips/cavium-octeon/Makefile | 3 +
arch/mips/cavium-octeon/octeon-platform.c | 523 ++++++++++++++++++++++++++++-
arch/mips/cavium-octeon/setup.c | 45 +++
4 files changed, 572 insertions(+), 1 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 01344ae..f694bdd 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1433,6 +1433,8 @@ config CPU_CAVIUM_OCTEON
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select IRQ_DOMAIN
+ select USE_OF
+ select LIBFDT
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 1e37522..bc96e29 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -9,6 +9,9 @@
# Copyright (C) 2005-2009 Cavium Networks
#
+CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index cd61d72..2754bc2 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2010 Cavium Networks
+ * Copyright (C) 2004-2011 Cavium Networks
* Copyright (C) 2008 Wind River Systems
*/
@@ -13,10 +13,16 @@
#include <linux/usb.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-rnm-defs.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-board.h>
static struct octeon_cf_data octeon_cf_data;
@@ -440,6 +446,521 @@ device_initcall(octeon_ohci_device_init);
#endif /* CONFIG_USB */
+static struct of_device_id __initdata octeon_ids[] = {
+ { .compatible = "simple-bus", },
+ { .compatible = "cavium,octeon-6335-uctl", },
+ { .compatible = "cavium,octeon-3860-bootbus", },
+ { .compatible = "cavium,mdio-mux", },
+ { .compatible = "gpio-leds", },
+ {},
+};
+
+static bool __init octeon_has_88e1145(void)
+{
+ return !OCTEON_IS_MODEL(OCTEON_CN52XX) &&
+ !OCTEON_IS_MODEL(OCTEON_CN6XXX) &&
+ !OCTEON_IS_MODEL(OCTEON_CN56XX);
+}
+
+static void __init octeon_fdt_set_phy(int eth, int phy_addr)
+{
+ const __be32 *phy_handle;
+ const __be32 *alt_phy_handle;
+ const __be32 *reg;
+ u32 phandle;
+ int phy;
+ int alt_phy;
+ const char *p;
+ int current_len;
+ char new_name[20];
+
+ phy_handle = fdt_getprop(initial_boot_params, eth, "phy-handle", NULL);
+ if (!phy_handle)
+ return;
+
+ phandle = be32_to_cpup(phy_handle);
+ phy = fdt_node_offset_by_phandle(initial_boot_params, phandle);
+
+ alt_phy_handle = fdt_getprop(initial_boot_params, eth, "cavium,alt-phy-handle", NULL);
+ if (alt_phy_handle) {
+ u32 alt_phandle = be32_to_cpup(alt_phy_handle);
+ alt_phy = fdt_node_offset_by_phandle(initial_boot_params, alt_phandle);
+ } else {
+ alt_phy = -1;
+ }
+
+ if (phy_addr < 0 || phy < 0) {
+ /* Delete the PHY things */
+ fdt_nop_property(initial_boot_params, eth, "phy-handle");
+ /* This one may fail */
+ fdt_nop_property(initial_boot_params, eth, "cavium,alt-phy-handle");
+ if (phy >= 0)
+ fdt_nop_node(initial_boot_params, phy);
+ if (alt_phy >= 0)
+ fdt_nop_node(initial_boot_params, alt_phy);
+ return;
+ }
+
+ if (phy_addr >= 256 && alt_phy > 0) {
+ const struct fdt_property *phy_prop;
+ struct fdt_property *alt_prop;
+ u32 phy_handle_name;
+
+ /* Use the alt phy node instead.*/
+ phy_prop = fdt_get_property(initial_boot_params, eth, "phy-handle", NULL);
+ phy_handle_name = phy_prop->nameoff;
+ fdt_nop_node(initial_boot_params, phy);
+ fdt_nop_property(initial_boot_params, eth, "phy-handle");
+ alt_prop = fdt_get_property_w(initial_boot_params, eth, "cavium,alt-phy-handle", NULL);
+ alt_prop->nameoff = phy_handle_name;
+ phy = alt_phy;
+ }
+
+ phy_addr &= 0xff;
+
+ if (octeon_has_88e1145()) {
+ fdt_nop_property(initial_boot_params, phy, "marvell,reg-init");
+ memset(new_name, 0, sizeof(new_name));
+ strcpy(new_name, "marvell,88e1145");
+ p = fdt_getprop(initial_boot_params, phy, "compatible",
+ ¤t_len);
+ if (p && current_len >= strlen(new_name))
+ fdt_setprop_inplace(initial_boot_params, phy,
+ "compatible", new_name, current_len);
+ }
+
+ reg = fdt_getprop(initial_boot_params, phy, "reg", NULL);
+ if (phy_addr == be32_to_cpup(reg))
+ return;
+
+ fdt_setprop_inplace_cell(initial_boot_params, phy, "reg", phy_addr);
+
+ snprintf(new_name, sizeof(new_name), "ethernet-phy@%x", phy_addr);
+
+ p = fdt_get_name(initial_boot_params, phy, ¤t_len);
+ if (p && current_len == strlen(new_name))
+ fdt_set_name(initial_boot_params, phy, new_name);
+ else
+ pr_err("Error: could not rename ethernet phy: <%s>", p);
+}
+
+static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac)
+{
+ u8 new_mac[6];
+ u64 mac = *pmac;
+ int r;
+
+ new_mac[0] = (mac >> 40) & 0xff;
+ new_mac[1] = (mac >> 32) & 0xff;
+ new_mac[2] = (mac >> 24) & 0xff;
+ new_mac[3] = (mac >> 16) & 0xff;
+ new_mac[4] = (mac >> 8) & 0xff;
+ new_mac[5] = mac & 0xff;
+
+ r = fdt_setprop_inplace(initial_boot_params, n, "local-mac-address",
+ new_mac, sizeof(new_mac));
+
+ if (r) {
+ pr_err("Setting \"local-mac-address\" failed %d", r);
+ return;
+ }
+ *pmac = mac + 1;
+}
+
+static void __init octeon_fdt_rm_ethernet(int node)
+{
+ const __be32 *phy_handle;
+
+ phy_handle = fdt_getprop(initial_boot_params, node, "phy-handle", NULL);
+ if (phy_handle) {
+ u32 ph = be32_to_cpup(phy_handle);
+ int p = fdt_node_offset_by_phandle(initial_boot_params, ph);
+ if (p >= 0)
+ fdt_nop_node(initial_boot_params, p);
+ }
+ fdt_nop_node(initial_boot_params, node);
+}
+
+static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pmac)
+{
+ char name_buffer[20];
+ int eth;
+ int phy_addr;
+ int ipd_port;
+
+ snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p);
+ eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer);
+ if (eth < 0)
+ return;
+ if (p > max) {
+ pr_debug("Deleting port %x:%x\n", i, p);
+ octeon_fdt_rm_ethernet(eth);
+ return;
+ }
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ ipd_port = (0x100 * i) + (0x10 * p) + 0x800;
+ else
+ ipd_port = 16 * i + p;
+
+ phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
+ octeon_fdt_set_phy(eth, phy_addr);
+ octeon_fdt_set_mac_addr(eth, pmac);
+}
+
+static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
+{
+ char name_buffer[20];
+ int iface;
+ int p;
+ int count;
+
+ count = cvmx_helper_interface_enumerate(idx);
+
+ snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
+ iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
+ if (iface < 0)
+ return;
+
+ for (p = 0; p < 16; p++)
+ octeon_fdt_pip_port(iface, idx, p, count - 1, pmac);
+}
+
+int __init octeon_prune_device_tree(void)
+{
+ int i, max_port, uart_mask;
+ const char *pip_path;
+ const char *alias_prop;
+ char name_buffer[20];
+ int aliases;
+ u64 mac_addr_base;
+
+ if (fdt_check_header(initial_boot_params))
+ panic("Corrupt Device Tree.");
+
+ aliases = fdt_path_offset(initial_boot_params, "/aliases");
+ if (aliases < 0) {
+ pr_err("Error: No /aliases node in device tree.");
+ return -EINVAL;
+ }
+
+
+ mac_addr_base =
+ ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 |
+ ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 |
+ ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 |
+ ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 |
+ ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 |
+ (octeon_bootinfo->mac_addr_base[5] & 0xffull);
+
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
+ max_port = 2;
+ else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX))
+ max_port = 1;
+ else
+ max_port = 0;
+
+ if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E)
+ max_port = 0;
+
+ for (i = 0; i < 2; i++) {
+ int mgmt;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "mix%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+ if (alias_prop) {
+ mgmt = fdt_path_offset(initial_boot_params, alias_prop);
+ if (mgmt < 0)
+ continue;
+ if (i >= max_port) {
+ pr_debug("Deleting mix%d\n", i);
+ octeon_fdt_rm_ethernet(mgmt);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ } else {
+ int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i);
+ octeon_fdt_set_phy(mgmt, phy_addr);
+ octeon_fdt_set_mac_addr(mgmt, &mac_addr_base);
+ }
+ }
+ }
+
+ pip_path = fdt_getprop(initial_boot_params, aliases, "pip", NULL);
+ if (pip_path) {
+ int pip = fdt_path_offset(initial_boot_params, pip_path);
+ if (pip >= 0)
+ for (i = 0; i <= 4; i++)
+ octeon_fdt_pip_iface(pip, i, &mac_addr_base);
+ }
+
+ /* I2C */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN68XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX))
+ max_port = 2;
+ else
+ max_port = 1;
+
+ for (i = 0; i < 2; i++) {
+ int i2c;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "twsi%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ i2c = fdt_path_offset(initial_boot_params, alias_prop);
+ if (i2c < 0)
+ continue;
+ if (i >= max_port) {
+ pr_debug("Deleting twsi%d\n", i);
+ fdt_nop_node(initial_boot_params, i2c);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+ }
+
+ /* SMI/MDIO */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ max_port = 4;
+ else if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX))
+ max_port = 2;
+ else
+ max_port = 1;
+
+ for (i = 0; i < 2; i++) {
+ int i2c;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "smi%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ i2c = fdt_path_offset(initial_boot_params, alias_prop);
+ if (i2c < 0)
+ continue;
+ if (i >= max_port) {
+ pr_debug("Deleting smi%d\n", i);
+ fdt_nop_node(initial_boot_params, i2c);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+ }
+
+ /* Serial */
+ uart_mask = 3;
+
+ /* Right now CN52XX is the only chip with a third uart */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+ uart_mask |= 4; /* uart2 */
+
+ for (i = 0; i < 3; i++) {
+ int uart;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "uart%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ uart = fdt_path_offset(initial_boot_params, alias_prop);
+ if (uart_mask & (1 << i))
+ continue;
+ pr_debug("Deleting uart%d\n", i);
+ fdt_nop_node(initial_boot_params, uart);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+
+ /* Compact Flash */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "cf0", NULL);
+ if (alias_prop) {
+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+ unsigned long base_ptr, region_base, region_size;
+ unsigned long region1_base = 0;
+ unsigned long region1_size = 0;
+ int cs, bootbus;
+ bool is_16bit = false;
+ bool is_true_ide = false;
+ __be32 new_reg[6];
+ __be32 *ranges;
+ int len;
+
+ int cf = fdt_path_offset(initial_boot_params, alias_prop);
+ base_ptr = 0;
+ if (octeon_bootinfo->major_version == 1
+ && octeon_bootinfo->minor_version >= 1) {
+ if (octeon_bootinfo->compact_flash_common_base_addr)
+ base_ptr = octeon_bootinfo->compact_flash_common_base_addr;
+ } else {
+ base_ptr = 0x1d000800;
+ }
+
+ if (!base_ptr)
+ goto no_cf;
+
+ /* Find CS0 region. */
+ for (cs = 0; cs < 8; cs++) {
+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
+ region_base = mio_boot_reg_cfg.s.base << 16;
+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
+ && base_ptr < region_base + region_size) {
+ is_16bit = mio_boot_reg_cfg.s.width;
+ break;
+ }
+ }
+ if (cs >= 7) {
+ /* cs and cs + 1 are CS0 and CS1, both must be less than 8. */
+ goto no_cf;
+ }
+
+ if (!(base_ptr & 0xfffful)) {
+ /*
+ * Boot loader signals availability of DMA (true_ide
+ * mode) by setting low order bits of base_ptr to
+ * zero.
+ */
+
+ /* Asume that CS1 immediately follows. */
+ mio_boot_reg_cfg.u64 =
+ cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs + 1));
+ region1_base = mio_boot_reg_cfg.s.base << 16;
+ region1_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (!mio_boot_reg_cfg.s.en)
+ goto no_cf;
+ is_true_ide = true;
+
+ } else {
+ fdt_nop_property(initial_boot_params, cf, "cavium,true-ide");
+ fdt_nop_property(initial_boot_params, cf, "cavium,dma-engine-handle");
+ if (!is_16bit) {
+ __be32 width = cpu_to_be32(8);
+ fdt_setprop_inplace(initial_boot_params, cf,
+ "cavium,bus-width", &width, sizeof(width));
+ }
+ }
+ new_reg[0] = cpu_to_be32(cs);
+ new_reg[1] = cpu_to_be32(0);
+ new_reg[2] = cpu_to_be32(0x10000);
+ new_reg[3] = cpu_to_be32(cs + 1);
+ new_reg[4] = cpu_to_be32(0);
+ new_reg[5] = cpu_to_be32(0x10000);
+ fdt_setprop_inplace(initial_boot_params, cf,
+ "reg", new_reg, sizeof(new_reg));
+
+ bootbus = fdt_parent_offset(initial_boot_params, cf);
+ if (bootbus < 0)
+ goto no_cf;
+ ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len);
+ if (!ranges || len < (5 * 8 * sizeof(__be32)))
+ goto no_cf;
+
+ ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32);
+ ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff);
+ ranges[(cs * 5) + 4] = cpu_to_be32(region_size);
+ if (is_true_ide) {
+ cs++;
+ ranges[(cs * 5) + 2] = cpu_to_be32(region1_base >> 32);
+ ranges[(cs * 5) + 3] = cpu_to_be32(region1_base & 0xffffffff);
+ ranges[(cs * 5) + 4] = cpu_to_be32(region1_size);
+ }
+ goto end_cf;
+no_cf:
+ fdt_nop_node(initial_boot_params, cf);
+
+end_cf:
+ ;
+ }
+
+ /* 8 char LED */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "led0", NULL);
+ if (alias_prop) {
+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+ unsigned long base_ptr, region_base, region_size;
+ int cs, bootbus;
+ __be32 new_reg[6];
+ __be32 *ranges;
+ int len;
+ int led = fdt_path_offset(initial_boot_params, alias_prop);
+
+ base_ptr = octeon_bootinfo->led_display_base_addr;
+ if (base_ptr == 0)
+ goto no_led;
+ /* Find CS0 region. */
+ for (cs = 0; cs < 8; cs++) {
+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
+ region_base = mio_boot_reg_cfg.s.base << 16;
+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
+ && base_ptr < region_base + region_size)
+ break;
+ }
+
+ if (cs > 7)
+ goto no_led;
+
+ new_reg[0] = cpu_to_be32(cs);
+ new_reg[1] = cpu_to_be32(0x20);
+ new_reg[2] = cpu_to_be32(0x20);
+ new_reg[3] = cpu_to_be32(cs);
+ new_reg[4] = cpu_to_be32(0);
+ new_reg[5] = cpu_to_be32(0x20);
+ fdt_setprop_inplace(initial_boot_params, led,
+ "reg", new_reg, sizeof(new_reg));
+
+ bootbus = fdt_parent_offset(initial_boot_params, led);
+ if (bootbus < 0)
+ goto no_led;
+ ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len);
+ if (!ranges || len < (5 * 8 * sizeof(__be32)))
+ goto no_led;
+
+ ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32);
+ ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff);
+ ranges[(cs * 5) + 4] = cpu_to_be32(region_size);
+ goto end_led;
+
+no_led:
+ fdt_nop_node(initial_boot_params, led);
+end_led:
+ ;
+ }
+
+ /* OHCI/UHCI USB */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "uctl", NULL);
+ if (alias_prop) {
+ int uctl = fdt_path_offset(initial_boot_params, alias_prop);
+
+ if (uctl >= 0 && (!OCTEON_IS_MODEL(OCTEON_CN6XXX) ||
+ octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC2E)) {
+ pr_debug("Deleting uctl\n");
+ fdt_nop_node(initial_boot_params, uctl);
+ fdt_nop_property(initial_boot_params, aliases, "uctl");
+ } else if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E ||
+ octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC4E) {
+ /* Missing "refclk-type" defaults to crystal. */
+ fdt_nop_property(initial_boot_params, uctl, "refclk-type");
+ }
+ }
+
+ return 0;
+}
+
+static int __init octeon_publish_devices(void)
+{
+ return of_platform_bus_probe(NULL, octeon_ids, NULL);
+}
+device_initcall(octeon_publish_devices);
+
MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 260b273..03e8be0 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -20,6 +20,8 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#include <asm/processor.h>
#include <asm/reboot.h>
@@ -775,3 +777,46 @@ void prom_free_prom_memory(void)
}
#endif
}
+
+int octeon_prune_device_tree(void);
+
+extern const char __dtb_octeon_3xxx_begin;
+extern const char __dtb_octeon_3xxx_end;
+extern const char __dtb_octeon_68xx_begin;
+extern const char __dtb_octeon_68xx_end;
+void __init device_tree_init(void)
+{
+ int dt_size;
+ struct boot_param_header *fdt;
+ bool do_prune;
+
+ if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
+ fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
+ if (fdt_check_header(fdt))
+ panic("Corrupt Device Tree passed to kernel.");
+ dt_size = be32_to_cpu(fdt->totalsize);
+ do_prune = false;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
+ fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin;
+ dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin;
+ do_prune = true;
+ } else {
+ fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin;
+ dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
+ do_prune = true;
+ }
+
+ /* Copy the default tree from init memory. */
+ initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
+ if (initial_boot_params == NULL)
+ panic("Could not allocate initial_boot_params\n");
+ memcpy(initial_boot_params, fdt, dt_size);
+
+ if (do_prune) {
+ octeon_prune_device_tree();
+ pr_info("Using internal Device Tree.\n");
+ } else {
+ pr_info("Using passed Device Tree.\n");
+ }
+ unflatten_device_tree();
+}
--
1.7.2.3
^ permalink raw reply related [flat|nested] 20+ messages in thread