| Kumar Gala | b053dc5 | 2009-06-19 08:31:05 -0500 | [diff] [blame] | 1 | d) Xilinx IP cores | 
|  | 2 |  | 
|  | 3 | The Xilinx EDK toolchain ships with a set of IP cores (devices) for use | 
|  | 4 | in Xilinx Spartan and Virtex FPGAs.  The devices cover the whole range | 
|  | 5 | of standard device types (network, serial, etc.) and miscellaneous | 
|  | 6 | devices (gpio, LCD, spi, etc).  Also, since these devices are | 
|  | 7 | implemented within the fpga fabric every instance of the device can be | 
|  | 8 | synthesised with different options that change the behaviour. | 
|  | 9 |  | 
|  | 10 | Each IP-core has a set of parameters which the FPGA designer can use to | 
|  | 11 | control how the core is synthesized.  Historically, the EDK tool would | 
|  | 12 | extract the device parameters relevant to device drivers and copy them | 
|  | 13 | into an 'xparameters.h' in the form of #define symbols.  This tells the | 
|  | 14 | device drivers how the IP cores are configured, but it requres the kernel | 
|  | 15 | to be recompiled every time the FPGA bitstream is resynthesized. | 
|  | 16 |  | 
|  | 17 | The new approach is to export the parameters into the device tree and | 
|  | 18 | generate a new device tree each time the FPGA bitstream changes.  The | 
|  | 19 | parameters which used to be exported as #defines will now become | 
|  | 20 | properties of the device node.  In general, device nodes for IP-cores | 
|  | 21 | will take the following form: | 
|  | 22 |  | 
|  | 23 | (name): (generic-name)@(base-address) { | 
|  | 24 | compatible = "xlnx,(ip-core-name)-(HW_VER)" | 
|  | 25 | [, (list of compatible devices), ...]; | 
|  | 26 | reg = <(baseaddr) (size)>; | 
|  | 27 | interrupt-parent = <&interrupt-controller-phandle>; | 
|  | 28 | interrupts = < ... >; | 
|  | 29 | xlnx,(parameter1) = "(string-value)"; | 
|  | 30 | xlnx,(parameter2) = <(int-value)>; | 
|  | 31 | }; | 
|  | 32 |  | 
|  | 33 | (generic-name):   an open firmware-style name that describes the | 
|  | 34 | generic class of device.  Preferably, this is one word, such | 
|  | 35 | as 'serial' or 'ethernet'. | 
|  | 36 | (ip-core-name):	the name of the ip block (given after the BEGIN | 
|  | 37 | directive in system.mhs).  Should be in lowercase | 
|  | 38 | and all underscores '_' converted to dashes '-'. | 
|  | 39 | (name):		is derived from the "PARAMETER INSTANCE" value. | 
|  | 40 | (parameter#):	C_* parameters from system.mhs.  The C_ prefix is | 
|  | 41 | dropped from the parameter name, the name is converted | 
|  | 42 | to lowercase and all underscore '_' characters are | 
|  | 43 | converted to dashes '-'. | 
|  | 44 | (baseaddr):	the baseaddr parameter value (often named C_BASEADDR). | 
|  | 45 | (HW_VER):	from the HW_VER parameter. | 
|  | 46 | (size):		the address range size (often C_HIGHADDR - C_BASEADDR + 1). | 
|  | 47 |  | 
|  | 48 | Typically, the compatible list will include the exact IP core version | 
|  | 49 | followed by an older IP core version which implements the same | 
|  | 50 | interface or any other device with the same interface. | 
|  | 51 |  | 
|  | 52 | 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. | 
|  | 53 |  | 
|  | 54 | For example, the following block from system.mhs: | 
|  | 55 |  | 
|  | 56 | BEGIN opb_uartlite | 
|  | 57 | PARAMETER INSTANCE = opb_uartlite_0 | 
|  | 58 | PARAMETER HW_VER = 1.00.b | 
|  | 59 | PARAMETER C_BAUDRATE = 115200 | 
|  | 60 | PARAMETER C_DATA_BITS = 8 | 
|  | 61 | PARAMETER C_ODD_PARITY = 0 | 
|  | 62 | PARAMETER C_USE_PARITY = 0 | 
|  | 63 | PARAMETER C_CLK_FREQ = 50000000 | 
|  | 64 | PARAMETER C_BASEADDR = 0xEC100000 | 
|  | 65 | PARAMETER C_HIGHADDR = 0xEC10FFFF | 
|  | 66 | BUS_INTERFACE SOPB = opb_7 | 
|  | 67 | PORT OPB_Clk = CLK_50MHz | 
|  | 68 | PORT Interrupt = opb_uartlite_0_Interrupt | 
|  | 69 | PORT RX = opb_uartlite_0_RX | 
|  | 70 | PORT TX = opb_uartlite_0_TX | 
|  | 71 | PORT OPB_Rst = sys_bus_reset_0 | 
|  | 72 | END | 
|  | 73 |  | 
|  | 74 | becomes the following device tree node: | 
|  | 75 |  | 
|  | 76 | opb_uartlite_0: serial@ec100000 { | 
|  | 77 | device_type = "serial"; | 
|  | 78 | compatible = "xlnx,opb-uartlite-1.00.b"; | 
|  | 79 | reg = <ec100000 10000>; | 
|  | 80 | interrupt-parent = <&opb_intc_0>; | 
|  | 81 | interrupts = <1 0>; // got this from the opb_intc parameters | 
|  | 82 | current-speed = <d#115200>;	// standard serial device prop | 
|  | 83 | clock-frequency = <d#50000000>;	// standard serial device prop | 
|  | 84 | xlnx,data-bits = <8>; | 
|  | 85 | xlnx,odd-parity = <0>; | 
|  | 86 | xlnx,use-parity = <0>; | 
|  | 87 | }; | 
|  | 88 |  | 
|  | 89 | Some IP cores actually implement 2 or more logical devices.  In | 
|  | 90 | this case, the device should still describe the whole IP core with | 
|  | 91 | a single node and add a child node for each logical device.  The | 
|  | 92 | ranges property can be used to translate from parent IP-core to the | 
|  | 93 | registers of each device.  In addition, the parent node should be | 
|  | 94 | compatible with the bus type 'xlnx,compound', and should contain | 
|  | 95 | #address-cells and #size-cells, as with any other bus.  (Note: this | 
|  | 96 | makes the assumption that both logical devices have the same bus | 
|  | 97 | binding.  If this is not true, then separate nodes should be used | 
|  | 98 | for each logical device).  The 'cell-index' property can be used to | 
|  | 99 | enumerate logical devices within an IP core.  For example, the | 
|  | 100 | following is the system.mhs entry for the dual ps2 controller found | 
|  | 101 | on the ml403 reference design. | 
|  | 102 |  | 
|  | 103 | BEGIN opb_ps2_dual_ref | 
|  | 104 | PARAMETER INSTANCE = opb_ps2_dual_ref_0 | 
|  | 105 | PARAMETER HW_VER = 1.00.a | 
|  | 106 | PARAMETER C_BASEADDR = 0xA9000000 | 
|  | 107 | PARAMETER C_HIGHADDR = 0xA9001FFF | 
|  | 108 | BUS_INTERFACE SOPB = opb_v20_0 | 
|  | 109 | PORT Sys_Intr1 = ps2_1_intr | 
|  | 110 | PORT Sys_Intr2 = ps2_2_intr | 
|  | 111 | PORT Clkin1 = ps2_clk_rx_1 | 
|  | 112 | PORT Clkin2 = ps2_clk_rx_2 | 
|  | 113 | PORT Clkpd1 = ps2_clk_tx_1 | 
|  | 114 | PORT Clkpd2 = ps2_clk_tx_2 | 
|  | 115 | PORT Rx1 = ps2_d_rx_1 | 
|  | 116 | PORT Rx2 = ps2_d_rx_2 | 
|  | 117 | PORT Txpd1 = ps2_d_tx_1 | 
|  | 118 | PORT Txpd2 = ps2_d_tx_2 | 
|  | 119 | END | 
|  | 120 |  | 
|  | 121 | It would result in the following device tree nodes: | 
|  | 122 |  | 
|  | 123 | opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { | 
|  | 124 | #address-cells = <1>; | 
|  | 125 | #size-cells = <1>; | 
|  | 126 | compatible = "xlnx,compound"; | 
|  | 127 | ranges = <0 a9000000 2000>; | 
|  | 128 | // If this device had extra parameters, then they would | 
|  | 129 | // go here. | 
|  | 130 | ps2@0 { | 
|  | 131 | compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; | 
|  | 132 | reg = <0 40>; | 
|  | 133 | interrupt-parent = <&opb_intc_0>; | 
|  | 134 | interrupts = <3 0>; | 
|  | 135 | cell-index = <0>; | 
|  | 136 | }; | 
|  | 137 | ps2@1000 { | 
|  | 138 | compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; | 
|  | 139 | reg = <1000 40>; | 
|  | 140 | interrupt-parent = <&opb_intc_0>; | 
|  | 141 | interrupts = <3 0>; | 
|  | 142 | cell-index = <0>; | 
|  | 143 | }; | 
|  | 144 | }; | 
|  | 145 |  | 
|  | 146 | Also, the system.mhs file defines bus attachments from the processor | 
|  | 147 | to the devices.  The device tree structure should reflect the bus | 
|  | 148 | attachments.  Again an example; this system.mhs fragment: | 
|  | 149 |  | 
|  | 150 | BEGIN ppc405_virtex4 | 
|  | 151 | PARAMETER INSTANCE = ppc405_0 | 
|  | 152 | PARAMETER HW_VER = 1.01.a | 
|  | 153 | BUS_INTERFACE DPLB = plb_v34_0 | 
|  | 154 | BUS_INTERFACE IPLB = plb_v34_0 | 
|  | 155 | END | 
|  | 156 |  | 
|  | 157 | BEGIN opb_intc | 
|  | 158 | PARAMETER INSTANCE = opb_intc_0 | 
|  | 159 | PARAMETER HW_VER = 1.00.c | 
|  | 160 | PARAMETER C_BASEADDR = 0xD1000FC0 | 
|  | 161 | PARAMETER C_HIGHADDR = 0xD1000FDF | 
|  | 162 | BUS_INTERFACE SOPB = opb_v20_0 | 
|  | 163 | END | 
|  | 164 |  | 
|  | 165 | BEGIN opb_uart16550 | 
|  | 166 | PARAMETER INSTANCE = opb_uart16550_0 | 
|  | 167 | PARAMETER HW_VER = 1.00.d | 
|  | 168 | PARAMETER C_BASEADDR = 0xa0000000 | 
|  | 169 | PARAMETER C_HIGHADDR = 0xa0001FFF | 
|  | 170 | BUS_INTERFACE SOPB = opb_v20_0 | 
|  | 171 | END | 
|  | 172 |  | 
|  | 173 | BEGIN plb_v34 | 
|  | 174 | PARAMETER INSTANCE = plb_v34_0 | 
|  | 175 | PARAMETER HW_VER = 1.02.a | 
|  | 176 | END | 
|  | 177 |  | 
|  | 178 | BEGIN plb_bram_if_cntlr | 
|  | 179 | PARAMETER INSTANCE = plb_bram_if_cntlr_0 | 
|  | 180 | PARAMETER HW_VER = 1.00.b | 
|  | 181 | PARAMETER C_BASEADDR = 0xFFFF0000 | 
|  | 182 | PARAMETER C_HIGHADDR = 0xFFFFFFFF | 
|  | 183 | BUS_INTERFACE SPLB = plb_v34_0 | 
|  | 184 | END | 
|  | 185 |  | 
|  | 186 | BEGIN plb2opb_bridge | 
|  | 187 | PARAMETER INSTANCE = plb2opb_bridge_0 | 
|  | 188 | PARAMETER HW_VER = 1.01.a | 
|  | 189 | PARAMETER C_RNG0_BASEADDR = 0x20000000 | 
|  | 190 | PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF | 
|  | 191 | PARAMETER C_RNG1_BASEADDR = 0x60000000 | 
|  | 192 | PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF | 
|  | 193 | PARAMETER C_RNG2_BASEADDR = 0x80000000 | 
|  | 194 | PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF | 
|  | 195 | PARAMETER C_RNG3_BASEADDR = 0xC0000000 | 
|  | 196 | PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF | 
|  | 197 | BUS_INTERFACE SPLB = plb_v34_0 | 
|  | 198 | BUS_INTERFACE MOPB = opb_v20_0 | 
|  | 199 | END | 
|  | 200 |  | 
|  | 201 | Gives this device tree (some properties removed for clarity): | 
|  | 202 |  | 
|  | 203 | plb@0 { | 
|  | 204 | #address-cells = <1>; | 
|  | 205 | #size-cells = <1>; | 
|  | 206 | compatible = "xlnx,plb-v34-1.02.a"; | 
|  | 207 | device_type = "ibm,plb"; | 
|  | 208 | ranges; // 1:1 translation | 
|  | 209 |  | 
|  | 210 | plb_bram_if_cntrl_0: bram@ffff0000 { | 
|  | 211 | reg = <ffff0000 10000>; | 
|  | 212 | } | 
|  | 213 |  | 
|  | 214 | opb@20000000 { | 
|  | 215 | #address-cells = <1>; | 
|  | 216 | #size-cells = <1>; | 
|  | 217 | ranges = <20000000 20000000 20000000 | 
|  | 218 | 60000000 60000000 20000000 | 
|  | 219 | 80000000 80000000 40000000 | 
|  | 220 | c0000000 c0000000 20000000>; | 
|  | 221 |  | 
|  | 222 | opb_uart16550_0: serial@a0000000 { | 
|  | 223 | reg = <a00000000 2000>; | 
|  | 224 | }; | 
|  | 225 |  | 
|  | 226 | opb_intc_0: interrupt-controller@d1000fc0 { | 
|  | 227 | reg = <d1000fc0 20>; | 
|  | 228 | }; | 
|  | 229 | }; | 
|  | 230 | }; | 
|  | 231 |  | 
|  | 232 | That covers the general approach to binding xilinx IP cores into the | 
|  | 233 | device tree.  The following are bindings for specific devices: | 
|  | 234 |  | 
|  | 235 | i) Xilinx ML300 Framebuffer | 
|  | 236 |  | 
|  | 237 | Simple framebuffer device from the ML300 reference design (also on the | 
|  | 238 | ML403 reference design as well as others). | 
|  | 239 |  | 
|  | 240 | Optional properties: | 
|  | 241 | - resolution = <xres yres> : pixel resolution of framebuffer.  Some | 
|  | 242 | implementations use a different resolution. | 
|  | 243 | Default is <d#640 d#480> | 
|  | 244 | - virt-resolution = <xvirt yvirt> : Size of framebuffer in memory. | 
|  | 245 | Default is <d#1024 d#480>. | 
|  | 246 | - rotate-display (empty) : rotate display 180 degrees. | 
|  | 247 |  | 
|  | 248 | ii) Xilinx SystemACE | 
|  | 249 |  | 
|  | 250 | The Xilinx SystemACE device is used to program FPGAs from an FPGA | 
|  | 251 | bitstream stored on a CF card.  It can also be used as a generic CF | 
|  | 252 | interface device. | 
|  | 253 |  | 
|  | 254 | Optional properties: | 
|  | 255 | - 8-bit (empty) : Set this property for SystemACE in 8 bit mode | 
|  | 256 |  | 
|  | 257 | iii) Xilinx EMAC and Xilinx TEMAC | 
|  | 258 |  | 
|  | 259 | Xilinx Ethernet devices.  In addition to general xilinx properties | 
|  | 260 | listed above, nodes for these devices should include a phy-handle | 
|  | 261 | property, and may include other common network device properties | 
|  | 262 | like local-mac-address. | 
|  | 263 |  | 
|  | 264 | iv) Xilinx Uartlite | 
|  | 265 |  | 
|  | 266 | Xilinx uartlite devices are simple fixed speed serial ports. | 
|  | 267 |  | 
|  | 268 | Required properties: | 
|  | 269 | - current-speed : Baud rate of uartlite | 
|  | 270 |  | 
|  | 271 | v) Xilinx hwicap | 
|  | 272 |  | 
|  | 273 | Xilinx hwicap devices provide access to the configuration logic | 
|  | 274 | of the FPGA through the Internal Configuration Access Port | 
|  | 275 | (ICAP).  The ICAP enables partial reconfiguration of the FPGA, | 
|  | 276 | readback of the configuration information, and some control over | 
|  | 277 | 'warm boots' of the FPGA fabric. | 
|  | 278 |  | 
|  | 279 | Required properties: | 
|  | 280 | - xlnx,family : The family of the FPGA, necessary since the | 
|  | 281 | capabilities of the underlying ICAP hardware | 
|  | 282 | differ between different families.  May be | 
|  | 283 | 'virtex2p', 'virtex4', or 'virtex5'. | 
|  | 284 |  | 
|  | 285 | vi) Xilinx Uart 16550 | 
|  | 286 |  | 
|  | 287 | Xilinx UART 16550 devices are very similar to the NS16550 but with | 
|  | 288 | different register spacing and an offset from the base address. | 
|  | 289 |  | 
|  | 290 | Required properties: | 
|  | 291 | - clock-frequency : Frequency of the clock input | 
|  | 292 | - reg-offset : A value of 3 is required | 
|  | 293 | - reg-shift : A value of 2 is required | 
|  | 294 |  | 
|  | 295 |  |