[1/4] soc: qcom: add an EBI2 device tree bindings

Message ID 1470691445-27571-2-git-send-email-linus.walleij@linaro.org
State New
Headers show

Commit Message

Linus Walleij Aug. 8, 2016, 9:24 p.m.
This adds device tree bindings for the External Bus Interface 2, EBI2
to the Qualcomm SoC drivers.

Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

---
 .../devicetree/bindings/soc/qcom/qcom,ebi2.txt     | 134 +++++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,ebi2.txt

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Arnd Bergmann Aug. 8, 2016, 9:32 p.m. | #1
On Monday, August 8, 2016 11:24:02 PM CEST Linus Walleij wrote:
> +

> +Required subnode properties:

> +- chipselect: <N> where N is the chipselect configured in this node

> +- address-cells: should be <1>

> +- size-cells: should be <1>

> +- ranges: bool should be present

> 


I think this should use a proper ranges property that translates
the address space of the external bus into the parent bus.

Just use #address-cells=<2> and make the first cell the cs number,
as the other similar drivers do, and get rid of the chipselect
property.

	Arnd

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring Aug. 10, 2016, 8:31 p.m. | #2
On Mon, Aug 08, 2016 at 11:24:02PM +0200, Linus Walleij wrote:
> This adds device tree bindings for the External Bus Interface 2, EBI2

> to the Qualcomm SoC drivers.

> 

> Cc: devicetree@vger.kernel.org

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

> ---

>  .../devicetree/bindings/soc/qcom/qcom,ebi2.txt     | 134 +++++++++++++++++++++

>  1 file changed, 134 insertions(+)

>  create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,ebi2.txt


Please address my previous comments:

http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/443826.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Aug. 18, 2016, 8:14 a.m. | #3
On Mon, Aug 8, 2016 at 11:32 PM, Arnd Bergmann <arnd@arndb.de> wrote:

> On Monday, August 8, 2016 11:24:02 PM CEST Linus Walleij wrote:

>> +

>> +Required subnode properties:

>> +- chipselect: <N> where N is the chipselect configured in this node

>> +- address-cells: should be <1>

>> +- size-cells: should be <1>

>> +- ranges: bool should be present

>>

>

> I think this should use a proper ranges property that translates

> the address space of the external bus into the parent bus.

>

> Just use #address-cells=<2> and make the first cell the cs number,

> as the other similar drivers do, and get rid of the chipselect

> property.


Rob Herring also wrote:

>> +Required subnode properties:

>> +- chipselect: <N> where N is the chipselect configured in this node

>

> Follow the other external buses that put the CS# in the reg property.


Also the same comment from Mark Rutland on IRC.

The following discussion is only about the CS-in-reg property problem.
The ranges issue is not fixed but that is an orthogonal thing I'm working
on.

There is a problem. Look at this cut-down example where I just have
the "qcom,xmem-recovery-cycles" set up for the CS2 chip select:

ebi2@1a100000 {
       compatible = "qcom,msm8660-ebi2";
       #address-cells = <1>;
       #size-cells = <1>;
       (...)
       cs2@1b800000 {
               chipselect = <2>;
               #address-cells = <1>;
               #size-cells = <1>;
               qcom,xmem-recovery-cycles = <5>;
               foo-ebi2@1b800000 {
                       compatible = "foo";
                       reg = <0x1b800000 0x100>;
                       (...)
               };
               bar-ebi2@1b800000 {
                       compatible = "bar";
                       reg = <0x1ba00000 0x100>;
                       (...)
               };
       };
};

So two devices "foo" and "bar" on the EBI2 bus, in the old
scheme.

So I need to encode the CS in the first cell of the reg for
foo-ebi2, and get rid of chipselect = <2> fine:

ebi2@1a100000 {
       compatible = "qcom,msm8660-ebi2";
       #address-cells = <1>;
       #size-cells = <1>;
       (...)
       cs2@1b800000 {
               #address-cells = <2>;
               #size-cells = <1>;
               qcom,xmem-recovery-cycles = <5>;
               foo-ebi2@1b800000 {
                       compatible = "foo";
                       reg = <2 0x1b800000 0x100>;
                       (...)
               };
               bar-ebi2@1ba00000 {
                       compatible = "bar";
                       reg = <2 0x1ba00000 0x100>;
                       (...)
               };
       };
};

This is not looking good at all. First: the configuration settings for
the chipselect (i.e. all devices below it, both "foo" and "bar" are
just floating in space. When parsing the tree how should you know
what chipselect to set up the stuff on? Shall I check the child nodes
first value in the reg property and then make a majority vote on what
chipselect they apply to or what? That doesn't make sense.

So I assume doing away with the chipselect node altogether would
be prefered. But then: where do I put stuff like "qcom,xmem-recovery-cycles"
that apply to the whole chipselect, not just a single subdevice on that
chipselect? I certainly cannot encode it in the reg since it needs
to be the same for all devices and it's not about addressing.

The only thing I can reasonably come up with would be this:

ebi2@1a100000 {
       compatible = "qcom,msm8660-ebi2";
       #address-cells = <2>;
       #size-cells = <1>;
       qcom,xmem-recovery-cycles = <0>, <0>, <5>, <0>, <0>, <0>;

       (...)
       foo-ebi2@1b800000 {
              compatible = "foo";
               reg = <2 0x1b800000 0x100>;
               (...)
       };
       bar-ebi2@1ba00000 {
               compatible = "bar";
               reg = <2 0x1ba00000 0x100>;
               (...)
       };
};

So the chip select settings are shoehorned into an array in the top
node that is then indexed to find the settings for cs0, cs1 etc.

There will be 6 such arrays for the different per-cs settings.

Is this what you want? I kind of thought the hierarchical model
was nice since each device was below its chipselect node, but
I understand that it breaks the pattern of other similar bus drivers.

So are you fine with the array solution?

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring Aug. 29, 2016, 12:24 p.m. | #4
On Mon, Aug 29, 2016 at 6:51 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 18 August 2016, Linus Walleij wrote:

>> On Mon, Aug 8, 2016 at 11:32 PM, Arnd Bergmann <arnd@arndb.de> wrote:

>> > On Monday, August 8, 2016 11:24:02 PM CEST Linus Walleij wrote:

>

>>

>> So two devices "foo" and "bar" on the EBI2 bus, in the old

>> scheme.

>>

>> So I need to encode the CS in the first cell of the reg for

>> foo-ebi2, and get rid of chipselect = <2> fine:

>>

>> ebi2@1a100000 {

>>        compatible = "qcom,msm8660-ebi2";

>>        #address-cells = <1>;

>>        #size-cells = <1>;

>>        (...)

>>        cs2@1b800000 {

>>                #address-cells = <2>;

>>                #size-cells = <1>;

>>                qcom,xmem-recovery-cycles = <5>;

>>                foo-ebi2@1b800000 {

>>                        compatible = "foo";

>>                        reg = <2 0x1b800000 0x100>;

>>                        (...)

>>                };

>>                bar-ebi2@1ba00000 {

>>                        compatible = "bar";

>>                        reg = <2 0x1ba00000 0x100>;

>>                        (...)

>>                };

>>        };

>> };

>>

>> This is not looking good at all. First: the configuration settings for

>> the chipselect (i.e. all devices below it, both "foo" and "bar" are

>> just floating in space. When parsing the tree how should you know

>> what chipselect to set up the stuff on? Shall I check the child nodes

>> first value in the reg property and then make a majority vote on what

>> chipselect they apply to or what? That doesn't make sense.

>

> I would have one node per chip-select and then put the devices on

> that CS below it, with #address-cells=1 again.


Actually, how I've been guiding folks is 2 levels of nodes.

eim {
  #address-cells = <3>;
  cs@0,0 {
    compatible = "bar,some-device";
    foo,eim-timing-prop = <0>;
  };

This is how most bindings have been done. There's not really any point
to 3 levels other than keeping CS properties separate, but they don't
need to be if they are properly prefixed. The timing for a device is a
property of the device even though we express them in terms of the
controller.

>> So I assume doing away with the chipselect node altogether would

>> be prefered. But then: where do I put stuff like "qcom,xmem-recovery-cycles"

>> that apply to the whole chipselect, not just a single subdevice on that

>> chipselect? I certainly cannot encode it in the reg since it needs

>> to be the same for all devices and it's not about addressing.

>>

>> The only thing I can reasonably come up with would be this:

>>

>> ebi2@1a100000 {

>>        compatible = "qcom,msm8660-ebi2";

>>        #address-cells = <2>;

>>        #size-cells = <1>;

>>        qcom,xmem-recovery-cycles = <0>, <0>, <5>, <0>, <0>, <0>;

>

> No, better put the settings into one device per cs.


Yes.

>

>> So the chip select settings are shoehorned into an array in the top

>> node that is then indexed to find the settings for cs0, cs1 etc.

>>

>> There will be 6 such arrays for the different per-cs settings.

>>

>> Is this what you want? I kind of thought the hierarchical model

>> was nice since each device was below its chipselect node, but

>> I understand that it breaks the pattern of other similar bus drivers.

>

> Nothing wrong with having a hierarchy here, what I'm interested

> in is making the addressing reflect what the hardware actually

> does. With the empty "ranges", it looks like the entire 32-bit

> address is getting exposed to the external bus, which is usually

> not how things work: instead, each "cs" line gets raised by an I/O

> operation on a particular CPU address range, and that range should

> be part of the "ranges" propert of the main bus node, and the

> externally visible addresses should be the translated addresses

> in the child bus representation in DT.


Yes.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij Aug. 29, 2016, 12:45 p.m. | #5
On Mon, Aug 29, 2016 at 1:51 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 18 August 2016, Linus Walleij wrote:


>> This is not looking good at all. First: the configuration settings for

>> the chipselect (i.e. all devices below it, both "foo" and "bar" are

>> just floating in space. When parsing the tree how should you know

>> what chipselect to set up the stuff on? Shall I check the child nodes

>> first value in the reg property and then make a majority vote on what

>> chipselect they apply to or what? That doesn't make sense.

>

> I would have one node per chip-select and then put the devices on

> that CS below it, with #address-cells=1 again.


Hm I already sent out a new version I think...
http://marc.info/?l=linux-arm-kernel&m=147202889722541&w=2
http://marc.info/?l=linux-arm-kernel&m=147202889622540&w=2
http://marc.info/?l=linux-arm-kernel&m=147202890622543&w=2
http://marc.info/?l=linux-arm-kernel&m=147202894222555&w=2
http://marc.info/?l=linux-arm-kernel&m=147202898022571&w=2

(OK I know, no patience this guy...)

Check it and see what you think.

>> ebi2@1a100000 {

>>        compatible = "qcom,msm8660-ebi2";

>>        #address-cells = <2>;

>>        #size-cells = <1>;

>>        qcom,xmem-recovery-cycles = <0>, <0>, <5>, <0>, <0>, <0>;

>

> No, better put the settings into one device per cs.


Yeah sigh I already made a version like this...

> Nothing wrong with having a hierarchy here, what I'm interested

> in is making the addressing reflect what the hardware actually

> does. With the empty "ranges", it looks like the entire 32-bit

> address is getting exposed to the external bus, which is usually

> not how things work: instead, each "cs" line gets raised by an I/O

> operation on a particular CPU address range, and that range should

> be part of the "ranges" propert of the main bus node, and the

> externally visible addresses should be the translated addresses

> in the child bus representation in DT.


I have fixed the ranges too in the new version.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rob Herring Aug. 29, 2016, 2:06 p.m. | #6
On Mon, Aug 29, 2016 at 8:13 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Mon, Aug 29, 2016 at 2:24 PM, Rob Herring <robh+dt@kernel.org> wrote:

>> On Mon, Aug 29, 2016 at 6:51 AM, Arnd Bergmann <arnd@arndb.de> wrote:

>

>>> I would have one node per chip-select and then put the devices on

>>> that CS below it, with #address-cells=1 again.

>>

>> Actually, how I've been guiding folks is 2 levels of nodes.

>>

>> eim {

>>   #address-cells = <3>;

>>   cs@0,0 {

>>     compatible = "bar,some-device";

>>     foo,eim-timing-prop = <0>;

>>   };

>>

>> This is how most bindings have been done. There's not really any point

>> to 3 levels other than keeping CS properties separate, but they don't

>> need to be if they are properly prefixed. The timing for a device is a

>> property of the device even though we express them in terms of the

>> controller.

>

> This is what I'm doing in the most recent version from aug 24 I think.

> http://marc.info/?l=linux-arm-kernel&m=147202889622540&w=2

>

>>>> ebi2@1a100000 {

>>>>        compatible = "qcom,msm8660-ebi2";

>>>>        #address-cells = <2>;

>>>>        #size-cells = <1>;

>>>>        qcom,xmem-recovery-cycles = <0>, <0>, <5>, <0>, <0>, <0>;

>>>

>>> No, better put the settings into one device per cs.

>>

>> Yes.

>

> Gnah. Each chipselect can (in theory) house several memory-mapped

> devices at different offsets. Like two ethernet controllers. It gets a bit

> weird.


Then perhaps that is a case for a middle CS node. Or you can have 2
nodes on same CS with different offsets:

dev@0,0 {};
dev@0,10000 {};
dev@1,0 {};

I guess either timing props get duplicated or you designate the first
node has them (2 devices on the same CS need to have the same timing
or have s/w setup per access).

> This is how it currently looks (v2):

>

> ebi2@1a100000 {

>     compatible = "qcom,apq8060-ebi2";

>     #address-cells = <2>;

>     #size-cells = <1>;

>     ranges = <0 0x0 0x1a800000 0x00800000>,

>         <1 0x0 0x1b000000 0x00800000>,

>         <2 0x0 0x1b800000 0x00800000>,

>         <3 0x0 0x1d000000 0x00800000>,

>         <4 0x0 0x1c800000 0x00800000>,

>         <5 0x0 0x1c000000 0x00800000>;

>     reg = <0x1a100000 0x1000>, <0x1a110000 0x1000>;

>     reg-names = "ebi2", "xmem";

>     qcom,xmem-recovery-cycles = <0>, <0>, <0>, <0>, <0>, <0>;

>     qcom,xmem-write-hold-cycles = <0>, <0>, <3>, <0>, <0>, <0>;

>     qcom,xmem-write-delta-cycles = <0>, <0>, <31>, <0>, <0>, <0>;

>     qcom,xmem-read-delta-cycles = <0>, <0>, <28>, <0>, <0>, <0>;

>     qcom,xmem-write-wait-cycles = <0>, <0>, <9>, <0>, <0>, <0>;

>     qcom,xmem-read-wait-cycles = <0>, <0>, <9>, <0>, <0>, <0>;

>

>     foo-ebi2@1b800000 {

>         compatible = "foo";

>         reg = <2 0x0 0x100>;

>         (...)

>     };

> };

>

> That is very close to how

> Documentation/devicetree/bindings/bus/imx-weim.txt

> drivers/bus/imx-weim.c

> does things, just with the additional property arrays.


Maybe so, but I'm trying to bring some consistency here, so I'd
suggest looking at newer ones like atmel IIRC.

> By looping over the subnodes and inspecting the first address cell of

> them I can figure out what chipselects need to be turned on, and

> the settings for those chipselects I need to activate are taken from

> those 6 qcom,xmem* arrays of timings.

>

> So if I reintroduce the cs nodes how do you imagine it'd look? Like this?


Between the 3 choices, what I've said is obviously my 1st choice. This
one would be 2nd (though chipselect should be part of the address
translation as Arnd suggested). The one above would be last.

> ebi2@1a100000 {

>     compatible = "qcom,apq8060-ebi2";

>     #address-cells = <1>;

>     #size-cells = <1>;

>     reg = <0x1a100000 0x1000>, <0x1a110000 0x1000>;

>     reg-names = "ebi2", "xmem";

>

>    cs@2 {

>        compatible = "bar,some-device";

>        #address-cells = <1>;

>        #size-cells = <1>;

>        ranges = <0x0 0x1b800000 0x00800000>;

>        chipselect = <2>;

>        foo,eim-timing-prop = <0>;

>        qcom,xmem-recovery-cycles = <0>;

>        qcom,xmem-write-hold-cycles = <3>;

>        qcom,xmem-write-delta-cycles = <31>;

>        qcom,xmem-read-delta-cycles = <28>;

>        qcom,xmem-write-wait-cycles = <9>;

>        qcom,xmem-read-wait-cycles = <9>;

>

>        foo-ebi2@0 {

>            compatible = "foo";

>            reg = <0x0 0x100>;

>            (...)

>        };

>

>        bar-ebi2@100 {

>            compatible = "bar";

>            reg = <0x100 0x100>;

>            (...)

>        };

>

>     };

> };

>

> Note: the chipselect goes out of the address cell, into the old

> chipselect = <n> property, because we have no other way to know

> which chipselect the settings apply to! (It's not like we can parse

> the subnodes and make a majority decision...)

>

> I kind of think both are non-perfect but the first one is the lesser

> evil.

>

> Yours,

> Linus Walleij

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,ebi2.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,ebi2.txt
new file mode 100644
index 000000000000..b848a60352ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,ebi2.txt
@@ -0,0 +1,134 @@ 
+Qualcomm External Bus Interface 2 (EBI2)
+
+The EBI2 contains two peripheral blocks: XMEM and LCDC. The XMEM handles any
+external memory (such as NAND or other memory-mapped peripherals) whereas
+LCDC handles LCD displays.
+
+As it says it connects devices to an external bus interface, meaning address
+lines (up to 9 address lines so can only address 1KiB external memory space),
+data lines (16 bits), OE (output enable), ADV (address valid, used on some
+NOR flash memories), WE (write enable). This on top of 6 different chip selects
+(CS0 thru CS5) so that in theory 6 different devices can be connected.
+
+Apparently this bus is clocked at 64MHz. It has dedicated pins on the package
+and the bus can only come out on these pins, however if some of the pins are
+unused they can be left unconnected or remuxed to be used as GPIO or in some
+cases other orthogonal functions as well.
+
+Also CS1 and CS2 has -A and -B signals. Why they have that is unclear to me.
+
+The chip selects have the following memory range assignments. This region of
+memory is referred to as "Chip Peripheral SS FPB0" and is 168MB big.
+
+Chip Select                     Physical address base
+CS0 GPIO134                     0x1a800000-0x1b000000 (8MB)
+CS1 GPIO39 (A) / GPIO123 (B)    0x1b000000-0x1b800000 (8MB)
+CS2 GPIO40 (A) / GPIO124 (B)    0x1b800000-0x1c000000 (8MB)
+CS3 GPIO133                     0x1d000000-0x25000000 (128 MB)
+CS4 GPIO132                     0x1c800000-0x1d000000 (8MB)
+CS5 GPIO131                     0x1c000000-0x1c800000 (8MB)
+
+The APQ8060 Qualcomm Application Processor User Guide, 80-N7150-14 Rev. A,
+August 6, 2012 contains some incomplete documentation of the EBI2.
+
+FIXME: the manual mentions "write precharge cycles" and "precharge cycles".
+We have not been able to figure out which bit fields these correspond to
+in the hardware, or what valid values exist. The current hypothesis is that
+this is something just used on the FAST chip selects and that the SLOW
+chip selects are understood fully. There is also a "byte device enable"
+flag somewhere for 8bit memories.
+
+FIXME: The chipselects have SLOW and FAST configuration registers. It's a bit
+unclear what this means, if they are mutually exclusive or can be used
+together, or if some chip selects are hardwired to be FAST and others are SLOW
+by design.
+
+The XMEM registers are totally undocumented but could be partially decoded
+because the Cypress AN49576 Antioch Westbridge apparently has suspiciously
+similar register layout, see: http://www.cypress.com/file/105771/download
+
+Required properties:
+- compatible: should be "qcom,ebi2"
+- #address-cells: shoule be <1>
+- #size-cells: should be <1>
+- ranges: boolean should be present
+- reg: two ranges of registers: EBI2 config and XMEM config areas
+- reg-names: should be "ebi2", "xmem"
+- clocks: two clocks, EBI_2X and EBI
+- clock-names: shoule be "ebi2x", "ebi2"
+
+Optional subnodes:
+- Nodes inside the EBI2 will be considered chipselect nodes. For each
+  chipselect under the EBI2 node you should have the following required
+  properties:
+
+Required subnode properties:
+- chipselect: <N> where N is the chipselect configured in this node
+- address-cells: should be <1>
+- size-cells: should be <1>
+- ranges: bool should be present
+
+Optional subnode properties for SLOW chip selects:
+- xmem-recovery-cycles: recovery cycles is the time the memory continues to
+  drive the data bus after OE is de-asserted, in order to avoid contention on
+  the data bus. They are inserted when reading one CS and switching to another
+  CS or read followed by write on the same CS. Valid values 0 thru 15. Minimum
+  value is actually 1, so a value of 0 will still yield 1 recovery cycle.
+- xmem-write-hold-cycles: write hold cycles, these are extra cycles inserted
+  after every write minimum 1. The data out is driven from the time WE is
+  asserted until CS is asserted. With a hold of 1 (value = 0), the CS stays
+  active for 1 extra cycle etc. Valid values 0 thru 15.
+- xmem-write-delta-cycles: initial latency for write cycles inserted for the
+  first write to a page or burst memory. Valid values 0 thru 255.
+- xmem-read-delta-cycles: initial latency for read cycles inserted for the
+  first read to a page or burst memory. Valid values 0 thru 255.
+- xmem-write-wait-cycles: number of wait cycles for every write access, 0=1
+  cycle. Valid values 0 thru 15.
+- xmem-read-wait-cycles: number of wait cycles for every read access, 0=1
+  cycle. Valid values 0 thru 15.
+
+Optional subnode properties for FAST chip selects:
+- xmem-address-hold-enable: this is a boolean property stating that we shall
+  holde the address for an extra cycle to meet hold time requirements with ADV
+  assertion.
+- xmem-adv-to-oe-recovery-cycles: the number of cycles elapsed before an OE
+  assertion, with respect to the cycle where ADV (address valid) is asserted.
+  2 means 2 cycles between ADV and OE. Valid values 0, 1, 2 or 3.
+- xmem-read-hold-cycles: the length in cycles of the first segment of a read
+  transfer. For a single read trandfer this will be the time from CS assertion
+  to OE assertion. Valid values 0 thru 15.
+
+Example:
+
+ebi2@1a100000 {
+	compatible = "qcom,ebi2";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges;
+	reg = <0x1a100000 0x1000>, <0x1a110000 0x1000>;
+	reg-names = "ebi2", "xmem";
+	clocks = <&gcc EBI2_2X_CLK>, <&gcc EBI2_CLK>;
+	clock-names = "ebi2x", "ebi2";
+	/* Make sure to set up the pin control for the EBI2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&foo_ebi2_pins>;
+
+	cs2@1b800000 {
+		chipselect = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		xmem-recovery-cycles = <0>;
+		xmem-write-hold-cycles = <3>;
+		xmem-write-delta-cycles = <31>;
+		xmem-read-delta-cycles = <28>;
+		xmem-write-wait-cycles = <9>;
+		xmem-read-wait-cycles = <9>;
+
+		foo-ebi2@1b800000 {
+			compatible = "foo";
+			reg = <0x1b800000 0x100>;
+			(...)
+		};
+	};
+};