1*4882a593Smuzhiyun 2*4882a593Smuzhiyun* Marvell MBus 3*4882a593Smuzhiyun 4*4882a593SmuzhiyunRequired properties: 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun- compatible: Should be set to one of the following: 7*4882a593Smuzhiyun marvell,armada370-mbus 8*4882a593Smuzhiyun marvell,armadaxp-mbus 9*4882a593Smuzhiyun marvell,armada375-mbus 10*4882a593Smuzhiyun marvell,armada380-mbus 11*4882a593Smuzhiyun marvell,kirkwood-mbus 12*4882a593Smuzhiyun marvell,dove-mbus 13*4882a593Smuzhiyun marvell,orion5x-88f5281-mbus 14*4882a593Smuzhiyun marvell,orion5x-88f5182-mbus 15*4882a593Smuzhiyun marvell,orion5x-88f5181-mbus 16*4882a593Smuzhiyun marvell,orion5x-88f6183-mbus 17*4882a593Smuzhiyun marvell,mv78xx0-mbus 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun- address-cells: Must be '2'. The first cell for the MBus ID encoding, 20*4882a593Smuzhiyun the second cell for the address offset within the window. 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun- size-cells: Must be '1'. 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun- ranges: Must be set up to provide a proper translation for each child. 25*4882a593Smuzhiyun See the examples below. 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun- controller: Contains a single phandle referring to the MBus controller 28*4882a593Smuzhiyun node. This allows to specify the node that contains the 29*4882a593Smuzhiyun registers that control the MBus, which is typically contained 30*4882a593Smuzhiyun within the internal register window (see below). 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunOptional properties: 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun- pcie-mem-aperture: This optional property contains the aperture for 35*4882a593Smuzhiyun the memory region of the PCIe driver. 36*4882a593Smuzhiyun If it's defined, it must encode the base address and 37*4882a593Smuzhiyun size for the address decoding windows allocated for 38*4882a593Smuzhiyun the PCIe memory region. 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun- pcie-io-aperture: Just as explained for the above property, this 41*4882a593Smuzhiyun optional property contains the aperture for the 42*4882a593Smuzhiyun I/O region of the PCIe driver. 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun* Marvell MBus controller 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunRequired properties: 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun- compatible: Should be set to "marvell,mbus-controller". 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun- reg: Device's register space. 51*4882a593Smuzhiyun Two or three entries are expected (see the examples below): 52*4882a593Smuzhiyun the first one controls the devices decoding window, 53*4882a593Smuzhiyun the second one controls the SDRAM decoding window and 54*4882a593Smuzhiyun the third controls the MBus bridge (only with the 55*4882a593Smuzhiyun marvell,armada370-mbus and marvell,armadaxp-mbus 56*4882a593Smuzhiyun compatible strings) 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunExample: 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun soc { 61*4882a593Smuzhiyun compatible = "marvell,armada370-mbus", "simple-bus"; 62*4882a593Smuzhiyun #address-cells = <2>; 63*4882a593Smuzhiyun #size-cells = <1>; 64*4882a593Smuzhiyun controller = <&mbusc>; 65*4882a593Smuzhiyun pcie-mem-aperture = <0xe0000000 0x8000000>; 66*4882a593Smuzhiyun pcie-io-aperture = <0xe8000000 0x100000>; 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun internal-regs { 69*4882a593Smuzhiyun compatible = "simple-bus"; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun mbusc: mbus-controller@20000 { 72*4882a593Smuzhiyun compatible = "marvell,mbus-controller"; 73*4882a593Smuzhiyun reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; 74*4882a593Smuzhiyun }; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun /* more children ...*/ 77*4882a593Smuzhiyun }; 78*4882a593Smuzhiyun }; 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun** MBus address decoding window specification 81*4882a593Smuzhiyun 82*4882a593SmuzhiyunThe MBus children address space is comprised of two cells: the first one for 83*4882a593Smuzhiyunthe window ID and the second one for the offset within the window. 84*4882a593SmuzhiyunIn order to allow to describe valid and non-valid window entries, the 85*4882a593Smuzhiyunfollowing encoding is used: 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun 0xSIAA0000 0x00oooooo 88*4882a593Smuzhiyun 89*4882a593SmuzhiyunWhere: 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun S = 0x0 for a MBus valid window 92*4882a593Smuzhiyun S = 0xf for a non-valid window (see below) 93*4882a593Smuzhiyun 94*4882a593SmuzhiyunIf S = 0x0, then: 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun I = 4-bit window target ID 97*4882a593Smuzhiyun AA = windpw attribute 98*4882a593Smuzhiyun 99*4882a593SmuzhiyunIf S = 0xf, then: 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun I = don't care 102*4882a593Smuzhiyun AA = 1 for internal register 103*4882a593Smuzhiyun 104*4882a593SmuzhiyunFollowing the above encoding, for each ranges entry for a MBus valid window 105*4882a593Smuzhiyun(S = 0x0), an address decoding window is allocated. On the other side, 106*4882a593Smuzhiyunentries for translation that do not correspond to valid windows (S = 0xf) 107*4882a593Smuzhiyunare skipped. 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun soc { 110*4882a593Smuzhiyun compatible = "marvell,armada370-mbus", "simple-bus"; 111*4882a593Smuzhiyun #address-cells = <2>; 112*4882a593Smuzhiyun #size-cells = <1>; 113*4882a593Smuzhiyun controller = <&mbusc>; 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun ranges = <0xf0010000 0 0 0xd0000000 0x100000 116*4882a593Smuzhiyun 0x01e00000 0 0 0xfff00000 0x100000>; 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun bootrom { 119*4882a593Smuzhiyun compatible = "marvell,bootrom"; 120*4882a593Smuzhiyun reg = <0x01e00000 0 0x100000>; 121*4882a593Smuzhiyun }; 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun /* other children */ 124*4882a593Smuzhiyun ... 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun internal-regs { 127*4882a593Smuzhiyun compatible = "simple-bus"; 128*4882a593Smuzhiyun ranges = <0 0xf0010000 0 0x100000>; 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun mbusc: mbus-controller@20000 { 131*4882a593Smuzhiyun compatible = "marvell,mbus-controller"; 132*4882a593Smuzhiyun reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; 133*4882a593Smuzhiyun }; 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun /* more children ...*/ 136*4882a593Smuzhiyun }; 137*4882a593Smuzhiyun }; 138*4882a593Smuzhiyun 139*4882a593SmuzhiyunIn the shown example, the translation entry in the 'ranges' property is what 140*4882a593Smuzhiyunmakes the MBus driver create a static decoding window for the corresponding 141*4882a593Smuzhiyungiven child device. Note that the binding does not require child nodes to be 142*4882a593Smuzhiyunpresent. Of course, child nodes are needed to probe the devices. 143*4882a593Smuzhiyun 144*4882a593SmuzhiyunSince each window is identified by its target ID and attribute ID there's 145*4882a593Smuzhiyuna special macro that can be use to simplify the translation entries: 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun#define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) 148*4882a593Smuzhiyun 149*4882a593SmuzhiyunUsing this macro, the above example would be: 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun soc { 152*4882a593Smuzhiyun compatible = "marvell,armada370-mbus", "simple-bus"; 153*4882a593Smuzhiyun #address-cells = <2>; 154*4882a593Smuzhiyun #size-cells = <1>; 155*4882a593Smuzhiyun controller = <&mbusc>; 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun ranges = < MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000 158*4882a593Smuzhiyun MBUS_ID(0x01, 0xe0) 0 0 0xfff00000 0x100000>; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun bootrom { 161*4882a593Smuzhiyun compatible = "marvell,bootrom"; 162*4882a593Smuzhiyun reg = <MBUS_ID(0x01, 0xe0) 0 0x100000>; 163*4882a593Smuzhiyun }; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun /* other children */ 166*4882a593Smuzhiyun ... 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun internal-regs { 169*4882a593Smuzhiyun compatible = "simple-bus"; 170*4882a593Smuzhiyun #address-cells = <1>; 171*4882a593Smuzhiyun #size-cells = <1>; 172*4882a593Smuzhiyun ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun mbusc: mbus-controller@20000 { 175*4882a593Smuzhiyun compatible = "marvell,mbus-controller"; 176*4882a593Smuzhiyun reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; 177*4882a593Smuzhiyun }; 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun /* other children */ 180*4882a593Smuzhiyun ... 181*4882a593Smuzhiyun }; 182*4882a593Smuzhiyun }; 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun** About the window base address 186*4882a593Smuzhiyun 187*4882a593SmuzhiyunRemember the MBus controller allows a great deal of flexibility for choosing 188*4882a593Smuzhiyunthe decoding window base address. When planning the device tree layout it's 189*4882a593Smuzhiyunpossible to choose any address as the base address, provided of course there's 190*4882a593Smuzhiyuna region large enough available, and with the required alignment. 191*4882a593Smuzhiyun 192*4882a593SmuzhiyunYet in other words: there's nothing preventing us from setting a base address 193*4882a593Smuzhiyunof 0xf0000000, or 0xd0000000 for the NOR device shown above, if such region is 194*4882a593Smuzhiyununused. 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun** Window allocation policy 197*4882a593Smuzhiyun 198*4882a593SmuzhiyunThe mbus-node ranges property defines a set of mbus windows that are expected 199*4882a593Smuzhiyunto be set by the operating system and that are guaranteed to be free of overlaps 200*4882a593Smuzhiyunwith one another or with the system memory ranges. 201*4882a593Smuzhiyun 202*4882a593SmuzhiyunEach entry in the property refers to exactly one window. If the operating system 203*4882a593Smuzhiyunchooses to use a different set of mbus windows, it must ensure that any address 204*4882a593Smuzhiyuntranslations performed from downstream devices are adapted accordingly. 205*4882a593Smuzhiyun 206*4882a593SmuzhiyunThe operating system may insert additional mbus windows that do not conflict 207*4882a593Smuzhiyunwith the ones listed in the ranges, e.g. for mapping PCIe devices. 208*4882a593SmuzhiyunAs a special case, the internal register window must be set up by the boot 209*4882a593Smuzhiyunloader at the address listed in the ranges property, since access to that region 210*4882a593Smuzhiyunis needed to set up the other windows. 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun** Example 213*4882a593Smuzhiyun 214*4882a593SmuzhiyunSee the example below, where a more complete device tree is shown: 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun soc { 217*4882a593Smuzhiyun compatible = "marvell,armadaxp-mbus", "simple-bus"; 218*4882a593Smuzhiyun controller = <&mbusc>; 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000 /* internal-regs */ 221*4882a593Smuzhiyun MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 222*4882a593Smuzhiyun MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000>; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun bootrom { 225*4882a593Smuzhiyun compatible = "marvell,bootrom"; 226*4882a593Smuzhiyun reg = <MBUS_ID(0x01, 0x1d) 0 0x100000>; 227*4882a593Smuzhiyun }; 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun devbus-bootcs { 230*4882a593Smuzhiyun ranges = <0 MBUS_ID(0x01, 0x2f) 0 0x8000000>; 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun /* NOR */ 233*4882a593Smuzhiyun nor { 234*4882a593Smuzhiyun compatible = "cfi-flash"; 235*4882a593Smuzhiyun reg = <0 0x8000000>; 236*4882a593Smuzhiyun bank-width = <2>; 237*4882a593Smuzhiyun }; 238*4882a593Smuzhiyun }; 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun pcie-controller { 241*4882a593Smuzhiyun compatible = "marvell,armada-xp-pcie"; 242*4882a593Smuzhiyun device_type = "pci"; 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun #address-cells = <3>; 245*4882a593Smuzhiyun #size-cells = <2>; 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun ranges = 248*4882a593Smuzhiyun <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */ 249*4882a593Smuzhiyun 0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */ 250*4882a593Smuzhiyun 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */ 251*4882a593Smuzhiyun 0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */ 252*4882a593Smuzhiyun 0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */ 253*4882a593Smuzhiyun 0x82000800 0 0xe0000000 MBUS_ID(0x04, 0xe8) 0xe0000000 0 0x08000000 /* Port 0.0 MEM */ 254*4882a593Smuzhiyun 0x81000800 0 0 MBUS_ID(0x04, 0xe0) 0xe8000000 0 0x00100000 /* Port 0.0 IO */>; 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun pcie@1,0 { 258*4882a593Smuzhiyun /* Port 0, Lane 0 */ 259*4882a593Smuzhiyun }; 260*4882a593Smuzhiyun }; 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun internal-regs { 263*4882a593Smuzhiyun compatible = "simple-bus"; 264*4882a593Smuzhiyun #address-cells = <1>; 265*4882a593Smuzhiyun #size-cells = <1>; 266*4882a593Smuzhiyun ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun mbusc: mbus-controller@20000 { 269*4882a593Smuzhiyun reg = <0x20000 0x100>, <0x20180 0x20>, <0x20250 0x8>; 270*4882a593Smuzhiyun }; 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun interrupt-controller@20000 { 273*4882a593Smuzhiyun reg = <0x20a00 0x2d0>, <0x21070 0x58>; 274*4882a593Smuzhiyun }; 275*4882a593Smuzhiyun }; 276*4882a593Smuzhiyun }; 277