| 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 |  |