Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'virtex-for-2.6.25' of git://git.secretlab.ca/git/linux-2.6-virtex into for-2.6.25

+2031 -43
+14
Documentation/powerpc/booting-without-of.txt
··· 2578 2578 Requred properties: 2579 2579 - current-speed : Baud rate of uartlite 2580 2580 2581 + v) Xilinx hwicap 2582 + 2583 + Xilinx hwicap devices provide access to the configuration logic 2584 + of the FPGA through the Internal Configuration Access Port 2585 + (ICAP). The ICAP enables partial reconfiguration of the FPGA, 2586 + readback of the configuration information, and some control over 2587 + 'warm boots' of the FPGA fabric. 2588 + 2589 + Required properties: 2590 + - xlnx,family : The family of the FPGA, necessary since the 2591 + capabilities of the underlying ICAP hardware 2592 + differ between different families. May be 2593 + 'virtex2p', 'virtex4', or 'virtex5'. 2594 + 2581 2595 p) Freescale Synchronous Serial Interface 2582 2596 2583 2597 The SSI is a serial device that communicates with audio codecs. It can
+1 -1
arch/powerpc/platforms/40x/virtex.c
··· 37 37 { 38 38 unsigned long root = of_get_flat_dt_root(); 39 39 40 - if (!of_flat_dt_is_compatible(root, "xilinx,virtex")) 40 + if (!of_flat_dt_is_compatible(root, "xlnx,virtex")) 41 41 return 0; 42 42 43 43 return 1;
+4 -2
drivers/block/xsysace.c
··· 1202 1202 } 1203 1203 1204 1204 /* Match table for of_platform binding */ 1205 - static struct of_device_id __devinit ace_of_match[] = { 1206 - { .compatible = "xilinx,xsysace", }, 1205 + static struct of_device_id ace_of_match[] __devinitdata = { 1206 + { .compatible = "xlnx,opb-sysace-1.00.b", }, 1207 + { .compatible = "xlnx,opb-sysace-1.00.c", }, 1208 + { .compatible = "xlnx,xps-sysace-1.00.a", }, 1207 1209 {}, 1208 1210 }; 1209 1211 MODULE_DEVICE_TABLE(of, ace_of_match);
+10
drivers/char/Kconfig
··· 841 841 To compile this driver as a module, choose M here: the 842 842 module will be called dtlk. 843 843 844 + config XILINX_HWICAP 845 + tristate "Xilinx HWICAP Support" 846 + depends on XILINX_VIRTEX 847 + help 848 + This option enables support for Xilinx Internal Configuration 849 + Access Port (ICAP) driver. The ICAP is used on Xilinx Virtex 850 + FPGA platforms to partially reconfigure the FPGA at runtime. 851 + 852 + If unsure, say N. 853 + 844 854 config R3964 845 855 tristate "Siemens R3964 line discipline" 846 856 ---help---
+1
drivers/char/Makefile
··· 77 77 obj-$(CONFIG_SGI_DS1286) += ds1286.o 78 78 obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o 79 79 obj-$(CONFIG_DS1302) += ds1302.o 80 + obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap/ 80 81 ifeq ($(CONFIG_GENERIC_NVRAM),y) 81 82 obj-$(CONFIG_NVRAM) += generic_nvram.o 82 83 else
+7
drivers/char/xilinx_hwicap/Makefile
··· 1 + # 2 + # Makefile for the Xilinx OPB hwicap driver 3 + # 4 + 5 + obj-$(CONFIG_XILINX_HWICAP) += xilinx_hwicap_m.o 6 + 7 + xilinx_hwicap_m-y := xilinx_hwicap.o fifo_icap.o buffer_icap.o
+380
drivers/char/xilinx_hwicap/buffer_icap.c
··· 1 + /***************************************************************************** 2 + * 3 + * Author: Xilinx, Inc. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 10 + * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 + * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 + * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 + * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 + * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 + * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 + * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 + * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 + * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 + * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 + * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 + * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 + * FOR A PARTICULAR PURPOSE. 23 + * 24 + * Xilinx products are not intended for use in life support appliances, 25 + * devices, or systems. Use in such applications is expressly prohibited. 26 + * 27 + * (c) Copyright 2003-2008 Xilinx Inc. 28 + * All rights reserved. 29 + * 30 + * You should have received a copy of the GNU General Public License along 31 + * with this program; if not, write to the Free Software Foundation, Inc., 32 + * 675 Mass Ave, Cambridge, MA 02139, USA. 33 + * 34 + *****************************************************************************/ 35 + 36 + #include "buffer_icap.h" 37 + 38 + /* Indicates how many bytes will fit in a buffer. (1 BRAM) */ 39 + #define XHI_MAX_BUFFER_BYTES 2048 40 + #define XHI_MAX_BUFFER_INTS (XHI_MAX_BUFFER_BYTES >> 2) 41 + 42 + /* File access and error constants */ 43 + #define XHI_DEVICE_READ_ERROR -1 44 + #define XHI_DEVICE_WRITE_ERROR -2 45 + #define XHI_BUFFER_OVERFLOW_ERROR -3 46 + 47 + #define XHI_DEVICE_READ 0x1 48 + #define XHI_DEVICE_WRITE 0x0 49 + 50 + /* Constants for checking transfer status */ 51 + #define XHI_CYCLE_DONE 0 52 + #define XHI_CYCLE_EXECUTING 1 53 + 54 + /* buffer_icap register offsets */ 55 + 56 + /* Size of transfer, read & write */ 57 + #define XHI_SIZE_REG_OFFSET 0x800L 58 + /* offset into bram, read & write */ 59 + #define XHI_BRAM_OFFSET_REG_OFFSET 0x804L 60 + /* Read not Configure, direction of transfer. Write only */ 61 + #define XHI_RNC_REG_OFFSET 0x808L 62 + /* Indicates transfer complete. Read only */ 63 + #define XHI_STATUS_REG_OFFSET 0x80CL 64 + 65 + /* Constants for setting the RNC register */ 66 + #define XHI_CONFIGURE 0x0UL 67 + #define XHI_READBACK 0x1UL 68 + 69 + /* Constants for the Done register */ 70 + #define XHI_NOT_FINISHED 0x0UL 71 + #define XHI_FINISHED 0x1UL 72 + 73 + #define XHI_BUFFER_START 0 74 + 75 + /** 76 + * buffer_icap_get_status: Get the contents of the status register. 77 + * @parameter base_address: is the base address of the device 78 + * 79 + * The status register contains the ICAP status and the done bit. 80 + * 81 + * D8 - cfgerr 82 + * D7 - dalign 83 + * D6 - rip 84 + * D5 - in_abort_l 85 + * D4 - Always 1 86 + * D3 - Always 1 87 + * D2 - Always 1 88 + * D1 - Always 1 89 + * D0 - Done bit 90 + **/ 91 + static inline u32 buffer_icap_get_status(void __iomem *base_address) 92 + { 93 + return in_be32(base_address + XHI_STATUS_REG_OFFSET); 94 + } 95 + 96 + /** 97 + * buffer_icap_get_bram: Reads data from the storage buffer bram. 98 + * @parameter base_address: contains the base address of the component. 99 + * @parameter offset: The word offset from which the data should be read. 100 + * 101 + * A bram is used as a configuration memory cache. One frame of data can 102 + * be stored in this "storage buffer". 103 + **/ 104 + static inline u32 buffer_icap_get_bram(void __iomem *base_address, 105 + u32 offset) 106 + { 107 + return in_be32(base_address + (offset << 2)); 108 + } 109 + 110 + /** 111 + * buffer_icap_busy: Return true if the icap device is busy 112 + * @parameter base_address: is the base address of the device 113 + * 114 + * The queries the low order bit of the status register, which 115 + * indicates whether the current configuration or readback operation 116 + * has completed. 117 + **/ 118 + static inline bool buffer_icap_busy(void __iomem *base_address) 119 + { 120 + return (buffer_icap_get_status(base_address) & 1) == XHI_NOT_FINISHED; 121 + } 122 + 123 + /** 124 + * buffer_icap_busy: Return true if the icap device is not busy 125 + * @parameter base_address: is the base address of the device 126 + * 127 + * The queries the low order bit of the status register, which 128 + * indicates whether the current configuration or readback operation 129 + * has completed. 130 + **/ 131 + static inline bool buffer_icap_done(void __iomem *base_address) 132 + { 133 + return (buffer_icap_get_status(base_address) & 1) == XHI_FINISHED; 134 + } 135 + 136 + /** 137 + * buffer_icap_set_size: Set the size register. 138 + * @parameter base_address: is the base address of the device 139 + * @parameter data: The size in bytes. 140 + * 141 + * The size register holds the number of 8 bit bytes to transfer between 142 + * bram and the icap (or icap to bram). 143 + **/ 144 + static inline void buffer_icap_set_size(void __iomem *base_address, 145 + u32 data) 146 + { 147 + out_be32(base_address + XHI_SIZE_REG_OFFSET, data); 148 + } 149 + 150 + /** 151 + * buffer_icap_mSetoffsetReg: Set the bram offset register. 152 + * @parameter base_address: contains the base address of the device. 153 + * @parameter data: is the value to be written to the data register. 154 + * 155 + * The bram offset register holds the starting bram address to transfer 156 + * data from during configuration or write data to during readback. 157 + **/ 158 + static inline void buffer_icap_set_offset(void __iomem *base_address, 159 + u32 data) 160 + { 161 + out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data); 162 + } 163 + 164 + /** 165 + * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register. 166 + * @parameter base_address: contains the base address of the device. 167 + * @parameter data: is the value to be written to the data register. 168 + * 169 + * The RNC register determines the direction of the data transfer. It 170 + * controls whether a configuration or readback take place. Writing to 171 + * this register initiates the transfer. A value of 1 initiates a 172 + * readback while writing a value of 0 initiates a configuration. 173 + **/ 174 + static inline void buffer_icap_set_rnc(void __iomem *base_address, 175 + u32 data) 176 + { 177 + out_be32(base_address + XHI_RNC_REG_OFFSET, data); 178 + } 179 + 180 + /** 181 + * buffer_icap_set_bram: Write data to the storage buffer bram. 182 + * @parameter base_address: contains the base address of the component. 183 + * @parameter offset: The word offset at which the data should be written. 184 + * @parameter data: The value to be written to the bram offset. 185 + * 186 + * A bram is used as a configuration memory cache. One frame of data can 187 + * be stored in this "storage buffer". 188 + **/ 189 + static inline void buffer_icap_set_bram(void __iomem *base_address, 190 + u32 offset, u32 data) 191 + { 192 + out_be32(base_address + (offset << 2), data); 193 + } 194 + 195 + /** 196 + * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer. 197 + * @parameter drvdata: a pointer to the drvdata. 198 + * @parameter offset: The storage buffer start address. 199 + * @parameter count: The number of words (32 bit) to read from the 200 + * device (ICAP). 201 + **/ 202 + static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, 203 + u32 offset, u32 count) 204 + { 205 + 206 + s32 retries = 0; 207 + void __iomem *base_address = drvdata->base_address; 208 + 209 + if (buffer_icap_busy(base_address)) 210 + return -EBUSY; 211 + 212 + if ((offset + count) > XHI_MAX_BUFFER_INTS) 213 + return -EINVAL; 214 + 215 + /* setSize count*4 to get bytes. */ 216 + buffer_icap_set_size(base_address, (count << 2)); 217 + buffer_icap_set_offset(base_address, offset); 218 + buffer_icap_set_rnc(base_address, XHI_READBACK); 219 + 220 + while (buffer_icap_busy(base_address)) { 221 + retries++; 222 + if (retries > XHI_MAX_RETRIES) 223 + return -EBUSY; 224 + } 225 + return 0; 226 + 227 + }; 228 + 229 + /** 230 + * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer. 231 + * @parameter drvdata: a pointer to the drvdata. 232 + * @parameter offset: The storage buffer start address. 233 + * @parameter count: The number of words (32 bit) to read from the 234 + * device (ICAP). 235 + **/ 236 + static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, 237 + u32 offset, u32 count) 238 + { 239 + 240 + s32 retries = 0; 241 + void __iomem *base_address = drvdata->base_address; 242 + 243 + if (buffer_icap_busy(base_address)) 244 + return -EBUSY; 245 + 246 + if ((offset + count) > XHI_MAX_BUFFER_INTS) 247 + return -EINVAL; 248 + 249 + /* setSize count*4 to get bytes. */ 250 + buffer_icap_set_size(base_address, count << 2); 251 + buffer_icap_set_offset(base_address, offset); 252 + buffer_icap_set_rnc(base_address, XHI_CONFIGURE); 253 + 254 + while (buffer_icap_busy(base_address)) { 255 + retries++; 256 + if (retries > XHI_MAX_RETRIES) 257 + return -EBUSY; 258 + } 259 + return 0; 260 + 261 + }; 262 + 263 + /** 264 + * buffer_icap_reset: Reset the logic of the icap device. 265 + * @parameter drvdata: a pointer to the drvdata. 266 + * 267 + * Writing to the status register resets the ICAP logic in an internal 268 + * version of the core. For the version of the core published in EDK, 269 + * this is a noop. 270 + **/ 271 + void buffer_icap_reset(struct hwicap_drvdata *drvdata) 272 + { 273 + out_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET, 0xFEFE); 274 + } 275 + 276 + /** 277 + * buffer_icap_set_configuration: Load a partial bitstream from system memory. 278 + * @parameter drvdata: a pointer to the drvdata. 279 + * @parameter data: Kernel address of the partial bitstream. 280 + * @parameter size: the size of the partial bitstream in 32 bit words. 281 + **/ 282 + int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, 283 + u32 size) 284 + { 285 + int status; 286 + s32 buffer_count = 0; 287 + s32 num_writes = 0; 288 + bool dirty = 0; 289 + u32 i; 290 + void __iomem *base_address = drvdata->base_address; 291 + 292 + /* Loop through all the data */ 293 + for (i = 0, buffer_count = 0; i < size; i++) { 294 + 295 + /* Copy data to bram */ 296 + buffer_icap_set_bram(base_address, buffer_count, data[i]); 297 + dirty = 1; 298 + 299 + if (buffer_count < XHI_MAX_BUFFER_INTS - 1) { 300 + buffer_count++; 301 + continue; 302 + } 303 + 304 + /* Write data to ICAP */ 305 + status = buffer_icap_device_write( 306 + drvdata, 307 + XHI_BUFFER_START, 308 + XHI_MAX_BUFFER_INTS); 309 + if (status != 0) { 310 + /* abort. */ 311 + buffer_icap_reset(drvdata); 312 + return status; 313 + } 314 + 315 + buffer_count = 0; 316 + num_writes++; 317 + dirty = 0; 318 + } 319 + 320 + /* Write unwritten data to ICAP */ 321 + if (dirty) { 322 + /* Write data to ICAP */ 323 + status = buffer_icap_device_write(drvdata, XHI_BUFFER_START, 324 + buffer_count); 325 + if (status != 0) { 326 + /* abort. */ 327 + buffer_icap_reset(drvdata); 328 + } 329 + return status; 330 + } 331 + 332 + return 0; 333 + }; 334 + 335 + /** 336 + * buffer_icap_get_configuration: Read configuration data from the device. 337 + * @parameter drvdata: a pointer to the drvdata. 338 + * @parameter data: Address of the data representing the partial bitstream 339 + * @parameter size: the size of the partial bitstream in 32 bit words. 340 + **/ 341 + int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, 342 + u32 size) 343 + { 344 + int status; 345 + s32 buffer_count = 0; 346 + s32 read_count = 0; 347 + u32 i; 348 + void __iomem *base_address = drvdata->base_address; 349 + 350 + /* Loop through all the data */ 351 + for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i < size; i++) { 352 + if (buffer_count == XHI_MAX_BUFFER_INTS) { 353 + u32 words_remaining = size - i; 354 + u32 words_to_read = 355 + words_remaining < 356 + XHI_MAX_BUFFER_INTS ? words_remaining : 357 + XHI_MAX_BUFFER_INTS; 358 + 359 + /* Read data from ICAP */ 360 + status = buffer_icap_device_read( 361 + drvdata, 362 + XHI_BUFFER_START, 363 + words_to_read); 364 + if (status != 0) { 365 + /* abort. */ 366 + buffer_icap_reset(drvdata); 367 + return status; 368 + } 369 + 370 + buffer_count = 0; 371 + read_count++; 372 + } 373 + 374 + /* Copy data from bram */ 375 + data[i] = buffer_icap_get_bram(base_address, buffer_count); 376 + buffer_count++; 377 + } 378 + 379 + return 0; 380 + };
+57
drivers/char/xilinx_hwicap/buffer_icap.h
··· 1 + /***************************************************************************** 2 + * 3 + * Author: Xilinx, Inc. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 10 + * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 + * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 + * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 + * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 + * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 + * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 + * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 + * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 + * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 + * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 + * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 + * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 + * FOR A PARTICULAR PURPOSE. 23 + * 24 + * Xilinx products are not intended for use in life support appliances, 25 + * devices, or systems. Use in such applications is expressly prohibited. 26 + * 27 + * (c) Copyright 2003-2008 Xilinx Inc. 28 + * All rights reserved. 29 + * 30 + * You should have received a copy of the GNU General Public License along 31 + * with this program; if not, write to the Free Software Foundation, Inc., 32 + * 675 Mass Ave, Cambridge, MA 02139, USA. 33 + * 34 + *****************************************************************************/ 35 + 36 + #ifndef XILINX_BUFFER_ICAP_H_ /* prevent circular inclusions */ 37 + #define XILINX_BUFFER_ICAP_H_ /* by using protection macros */ 38 + 39 + #include <linux/types.h> 40 + #include <linux/cdev.h> 41 + #include <linux/version.h> 42 + #include <linux/platform_device.h> 43 + 44 + #include <asm/io.h> 45 + #include "xilinx_hwicap.h" 46 + 47 + void buffer_icap_reset(struct hwicap_drvdata *drvdata); 48 + 49 + /* Loads a partial bitstream from system memory. */ 50 + int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, 51 + u32 Size); 52 + 53 + /* Loads a partial bitstream from system memory. */ 54 + int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, 55 + u32 Size); 56 + 57 + #endif
+381
drivers/char/xilinx_hwicap/fifo_icap.c
··· 1 + /***************************************************************************** 2 + * 3 + * Author: Xilinx, Inc. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 10 + * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 + * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 + * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 + * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 + * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 + * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 + * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 + * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 + * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 + * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 + * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 + * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 + * FOR A PARTICULAR PURPOSE. 23 + * 24 + * Xilinx products are not intended for use in life support appliances, 25 + * devices, or systems. Use in such applications is expressly prohibited. 26 + * 27 + * (c) Copyright 2007-2008 Xilinx Inc. 28 + * All rights reserved. 29 + * 30 + * You should have received a copy of the GNU General Public License along 31 + * with this program; if not, write to the Free Software Foundation, Inc., 32 + * 675 Mass Ave, Cambridge, MA 02139, USA. 33 + * 34 + *****************************************************************************/ 35 + 36 + #include "fifo_icap.h" 37 + 38 + /* Register offsets for the XHwIcap device. */ 39 + #define XHI_GIER_OFFSET 0x1C /* Device Global Interrupt Enable Reg */ 40 + #define XHI_IPISR_OFFSET 0x20 /* Interrupt Status Register */ 41 + #define XHI_IPIER_OFFSET 0x28 /* Interrupt Enable Register */ 42 + #define XHI_WF_OFFSET 0x100 /* Write FIFO */ 43 + #define XHI_RF_OFFSET 0x104 /* Read FIFO */ 44 + #define XHI_SZ_OFFSET 0x108 /* Size Register */ 45 + #define XHI_CR_OFFSET 0x10C /* Control Register */ 46 + #define XHI_SR_OFFSET 0x110 /* Status Register */ 47 + #define XHI_WFV_OFFSET 0x114 /* Write FIFO Vacancy Register */ 48 + #define XHI_RFO_OFFSET 0x118 /* Read FIFO Occupancy Register */ 49 + 50 + /* Device Global Interrupt Enable Register (GIER) bit definitions */ 51 + 52 + #define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */ 53 + 54 + /** 55 + * HwIcap Device Interrupt Status/Enable Registers 56 + * 57 + * Interrupt Status Register (IPISR) : This register holds the 58 + * interrupt status flags for the device. These bits are toggle on 59 + * write. 60 + * 61 + * Interrupt Enable Register (IPIER) : This register is used to enable 62 + * interrupt sources for the device. 63 + * Writing a '1' to a bit enables the corresponding interrupt. 64 + * Writing a '0' to a bit disables the corresponding interrupt. 65 + * 66 + * IPISR/IPIER registers have the same bit definitions and are only defined 67 + * once. 68 + */ 69 + #define XHI_IPIXR_RFULL_MASK 0x00000008 /* Read FIFO Full */ 70 + #define XHI_IPIXR_WEMPTY_MASK 0x00000004 /* Write FIFO Empty */ 71 + #define XHI_IPIXR_RDP_MASK 0x00000002 /* Read FIFO half full */ 72 + #define XHI_IPIXR_WRP_MASK 0x00000001 /* Write FIFO half full */ 73 + #define XHI_IPIXR_ALL_MASK 0x0000000F /* Mask of all interrupts */ 74 + 75 + /* Control Register (CR) */ 76 + #define XHI_CR_SW_RESET_MASK 0x00000008 /* SW Reset Mask */ 77 + #define XHI_CR_FIFO_CLR_MASK 0x00000004 /* FIFO Clear Mask */ 78 + #define XHI_CR_READ_MASK 0x00000002 /* Read from ICAP to FIFO */ 79 + #define XHI_CR_WRITE_MASK 0x00000001 /* Write from FIFO to ICAP */ 80 + 81 + /* Status Register (SR) */ 82 + #define XHI_SR_CFGERR_N_MASK 0x00000100 /* Config Error Mask */ 83 + #define XHI_SR_DALIGN_MASK 0x00000080 /* Data Alignment Mask */ 84 + #define XHI_SR_RIP_MASK 0x00000040 /* Read back Mask */ 85 + #define XHI_SR_IN_ABORT_N_MASK 0x00000020 /* Select Map Abort Mask */ 86 + #define XHI_SR_DONE_MASK 0x00000001 /* Done bit Mask */ 87 + 88 + 89 + #define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */ 90 + #define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */ 91 + /* The maximum amount we can request from fifo_icap_get_configuration 92 + at once, in bytes. */ 93 + #define XHI_MAX_READ_TRANSACTION_WORDS 0xFFF 94 + 95 + 96 + /** 97 + * fifo_icap_fifo_write: Write data to the write FIFO. 98 + * @parameter drvdata: a pointer to the drvdata. 99 + * @parameter data: the 32-bit value to be written to the FIFO. 100 + * 101 + * This function will silently fail if the fifo is full. 102 + **/ 103 + static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata, 104 + u32 data) 105 + { 106 + dev_dbg(drvdata->dev, "fifo_write: %x\n", data); 107 + out_be32(drvdata->base_address + XHI_WF_OFFSET, data); 108 + } 109 + 110 + /** 111 + * fifo_icap_fifo_read: Read data from the Read FIFO. 112 + * @parameter drvdata: a pointer to the drvdata. 113 + * 114 + * This function will silently fail if the fifo is empty. 115 + **/ 116 + static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata) 117 + { 118 + u32 data = in_be32(drvdata->base_address + XHI_RF_OFFSET); 119 + dev_dbg(drvdata->dev, "fifo_read: %x\n", data); 120 + return data; 121 + } 122 + 123 + /** 124 + * fifo_icap_set_read_size: Set the the size register. 125 + * @parameter drvdata: a pointer to the drvdata. 126 + * @parameter data: the size of the following read transaction, in words. 127 + **/ 128 + static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, 129 + u32 data) 130 + { 131 + out_be32(drvdata->base_address + XHI_SZ_OFFSET, data); 132 + } 133 + 134 + /** 135 + * fifo_icap_start_config: Initiate a configuration (write) to the device. 136 + * @parameter drvdata: a pointer to the drvdata. 137 + **/ 138 + static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) 139 + { 140 + out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_WRITE_MASK); 141 + dev_dbg(drvdata->dev, "configuration started\n"); 142 + } 143 + 144 + /** 145 + * fifo_icap_start_readback: Initiate a readback from the device. 146 + * @parameter drvdata: a pointer to the drvdata. 147 + **/ 148 + static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) 149 + { 150 + out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_READ_MASK); 151 + dev_dbg(drvdata->dev, "readback started\n"); 152 + } 153 + 154 + /** 155 + * fifo_icap_busy: Return true if the ICAP is still processing a transaction. 156 + * @parameter drvdata: a pointer to the drvdata. 157 + **/ 158 + static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) 159 + { 160 + u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET); 161 + dev_dbg(drvdata->dev, "Getting status = %x\n", status); 162 + return (status & XHI_SR_DONE_MASK) ? 0 : 1; 163 + } 164 + 165 + /** 166 + * fifo_icap_write_fifo_vacancy: Query the write fifo available space. 167 + * @parameter drvdata: a pointer to the drvdata. 168 + * 169 + * Return the number of words that can be safely pushed into the write fifo. 170 + **/ 171 + static inline u32 fifo_icap_write_fifo_vacancy( 172 + struct hwicap_drvdata *drvdata) 173 + { 174 + return in_be32(drvdata->base_address + XHI_WFV_OFFSET); 175 + } 176 + 177 + /** 178 + * fifo_icap_read_fifo_occupancy: Query the read fifo available data. 179 + * @parameter drvdata: a pointer to the drvdata. 180 + * 181 + * Return the number of words that can be safely read from the read fifo. 182 + **/ 183 + static inline u32 fifo_icap_read_fifo_occupancy( 184 + struct hwicap_drvdata *drvdata) 185 + { 186 + return in_be32(drvdata->base_address + XHI_RFO_OFFSET); 187 + } 188 + 189 + /** 190 + * fifo_icap_set_configuration: Send configuration data to the ICAP. 191 + * @parameter drvdata: a pointer to the drvdata. 192 + * @parameter frame_buffer: a pointer to the data to be written to the 193 + * ICAP device. 194 + * @parameter num_words: the number of words (32 bit) to write to the ICAP 195 + * device. 196 + 197 + * This function writes the given user data to the Write FIFO in 198 + * polled mode and starts the transfer of the data to 199 + * the ICAP device. 200 + **/ 201 + int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, 202 + u32 *frame_buffer, u32 num_words) 203 + { 204 + 205 + u32 write_fifo_vacancy = 0; 206 + u32 retries = 0; 207 + u32 remaining_words; 208 + 209 + dev_dbg(drvdata->dev, "fifo_set_configuration\n"); 210 + 211 + /* 212 + * Check if the ICAP device is Busy with the last Read/Write 213 + */ 214 + if (fifo_icap_busy(drvdata)) 215 + return -EBUSY; 216 + 217 + /* 218 + * Set up the buffer pointer and the words to be transferred. 219 + */ 220 + remaining_words = num_words; 221 + 222 + while (remaining_words > 0) { 223 + /* 224 + * Wait until we have some data in the fifo. 225 + */ 226 + while (write_fifo_vacancy == 0) { 227 + write_fifo_vacancy = 228 + fifo_icap_write_fifo_vacancy(drvdata); 229 + retries++; 230 + if (retries > XHI_MAX_RETRIES) 231 + return -EIO; 232 + } 233 + 234 + /* 235 + * Write data into the Write FIFO. 236 + */ 237 + while ((write_fifo_vacancy != 0) && 238 + (remaining_words > 0)) { 239 + fifo_icap_fifo_write(drvdata, *frame_buffer); 240 + 241 + remaining_words--; 242 + write_fifo_vacancy--; 243 + frame_buffer++; 244 + } 245 + /* Start pushing whatever is in the FIFO into the ICAP. */ 246 + fifo_icap_start_config(drvdata); 247 + } 248 + 249 + /* Wait until the write has finished. */ 250 + while (fifo_icap_busy(drvdata)) { 251 + retries++; 252 + if (retries > XHI_MAX_RETRIES) 253 + break; 254 + } 255 + 256 + dev_dbg(drvdata->dev, "done fifo_set_configuration\n"); 257 + 258 + /* 259 + * If the requested number of words have not been read from 260 + * the device then indicate failure. 261 + */ 262 + if (remaining_words != 0) 263 + return -EIO; 264 + 265 + return 0; 266 + } 267 + 268 + /** 269 + * fifo_icap_get_configuration: Read configuration data from the device. 270 + * @parameter drvdata: a pointer to the drvdata. 271 + * @parameter data: Address of the data representing the partial bitstream 272 + * @parameter size: the size of the partial bitstream in 32 bit words. 273 + * 274 + * This function reads the specified number of words from the ICAP device in 275 + * the polled mode. 276 + */ 277 + int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, 278 + u32 *frame_buffer, u32 num_words) 279 + { 280 + 281 + u32 read_fifo_occupancy = 0; 282 + u32 retries = 0; 283 + u32 *data = frame_buffer; 284 + u32 remaining_words; 285 + u32 words_to_read; 286 + 287 + dev_dbg(drvdata->dev, "fifo_get_configuration\n"); 288 + 289 + /* 290 + * Check if the ICAP device is Busy with the last Write/Read 291 + */ 292 + if (fifo_icap_busy(drvdata)) 293 + return -EBUSY; 294 + 295 + remaining_words = num_words; 296 + 297 + while (remaining_words > 0) { 298 + words_to_read = remaining_words; 299 + /* The hardware has a limit on the number of words 300 + that can be read at one time. */ 301 + if (words_to_read > XHI_MAX_READ_TRANSACTION_WORDS) 302 + words_to_read = XHI_MAX_READ_TRANSACTION_WORDS; 303 + 304 + remaining_words -= words_to_read; 305 + 306 + fifo_icap_set_read_size(drvdata, words_to_read); 307 + fifo_icap_start_readback(drvdata); 308 + 309 + while (words_to_read > 0) { 310 + /* Wait until we have some data in the fifo. */ 311 + while (read_fifo_occupancy == 0) { 312 + read_fifo_occupancy = 313 + fifo_icap_read_fifo_occupancy(drvdata); 314 + retries++; 315 + if (retries > XHI_MAX_RETRIES) 316 + return -EIO; 317 + } 318 + 319 + if (read_fifo_occupancy > words_to_read) 320 + read_fifo_occupancy = words_to_read; 321 + 322 + words_to_read -= read_fifo_occupancy; 323 + 324 + /* Read the data from the Read FIFO. */ 325 + while (read_fifo_occupancy != 0) { 326 + *data++ = fifo_icap_fifo_read(drvdata); 327 + read_fifo_occupancy--; 328 + } 329 + } 330 + } 331 + 332 + dev_dbg(drvdata->dev, "done fifo_get_configuration\n"); 333 + 334 + return 0; 335 + } 336 + 337 + /** 338 + * buffer_icap_reset: Reset the logic of the icap device. 339 + * @parameter drvdata: a pointer to the drvdata. 340 + * 341 + * This function forces the software reset of the complete HWICAP device. 342 + * All the registers will return to the default value and the FIFO is also 343 + * flushed as a part of this software reset. 344 + */ 345 + void fifo_icap_reset(struct hwicap_drvdata *drvdata) 346 + { 347 + u32 reg_data; 348 + /* 349 + * Reset the device by setting/clearing the RESET bit in the 350 + * Control Register. 351 + */ 352 + reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET); 353 + 354 + out_be32(drvdata->base_address + XHI_CR_OFFSET, 355 + reg_data | XHI_CR_SW_RESET_MASK); 356 + 357 + out_be32(drvdata->base_address + XHI_CR_OFFSET, 358 + reg_data & (~XHI_CR_SW_RESET_MASK)); 359 + 360 + } 361 + 362 + /** 363 + * fifo_icap_flush_fifo: This function flushes the FIFOs in the device. 364 + * @parameter drvdata: a pointer to the drvdata. 365 + */ 366 + void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata) 367 + { 368 + u32 reg_data; 369 + /* 370 + * Flush the FIFO by setting/clearing the FIFO Clear bit in the 371 + * Control Register. 372 + */ 373 + reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET); 374 + 375 + out_be32(drvdata->base_address + XHI_CR_OFFSET, 376 + reg_data | XHI_CR_FIFO_CLR_MASK); 377 + 378 + out_be32(drvdata->base_address + XHI_CR_OFFSET, 379 + reg_data & (~XHI_CR_FIFO_CLR_MASK)); 380 + } 381 +
+62
drivers/char/xilinx_hwicap/fifo_icap.h
··· 1 + /***************************************************************************** 2 + * 3 + * Author: Xilinx, Inc. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 10 + * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 + * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 + * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 + * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 + * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 + * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 + * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 + * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 + * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 + * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 + * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 + * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 + * FOR A PARTICULAR PURPOSE. 23 + * 24 + * Xilinx products are not intended for use in life support appliances, 25 + * devices, or systems. Use in such applications is expressly prohibited. 26 + * 27 + * (c) Copyright 2007-2008 Xilinx Inc. 28 + * All rights reserved. 29 + * 30 + * You should have received a copy of the GNU General Public License along 31 + * with this program; if not, write to the Free Software Foundation, Inc., 32 + * 675 Mass Ave, Cambridge, MA 02139, USA. 33 + * 34 + *****************************************************************************/ 35 + 36 + #ifndef XILINX_FIFO_ICAP_H_ /* prevent circular inclusions */ 37 + #define XILINX_FIFO_ICAP_H_ /* by using protection macros */ 38 + 39 + #include <linux/types.h> 40 + #include <linux/cdev.h> 41 + #include <linux/version.h> 42 + #include <linux/platform_device.h> 43 + 44 + #include <asm/io.h> 45 + #include "xilinx_hwicap.h" 46 + 47 + /* Reads integers from the device into the storage buffer. */ 48 + int fifo_icap_get_configuration( 49 + struct hwicap_drvdata *drvdata, 50 + u32 *FrameBuffer, 51 + u32 NumWords); 52 + 53 + /* Writes integers to the device from the storage buffer. */ 54 + int fifo_icap_set_configuration( 55 + struct hwicap_drvdata *drvdata, 56 + u32 *FrameBuffer, 57 + u32 NumWords); 58 + 59 + void fifo_icap_reset(struct hwicap_drvdata *drvdata); 60 + void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata); 61 + 62 + #endif
+904
drivers/char/xilinx_hwicap/xilinx_hwicap.c
··· 1 + /***************************************************************************** 2 + * 3 + * Author: Xilinx, Inc. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 10 + * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 + * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 + * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 + * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 + * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 + * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 + * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 + * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 + * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 + * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 + * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 + * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 + * FOR A PARTICULAR PURPOSE. 23 + * 24 + * Xilinx products are not intended for use in life support appliances, 25 + * devices, or systems. Use in such applications is expressly prohibited. 26 + * 27 + * (c) Copyright 2002 Xilinx Inc., Systems Engineering Group 28 + * (c) Copyright 2004 Xilinx Inc., Systems Engineering Group 29 + * (c) Copyright 2007-2008 Xilinx Inc. 30 + * All rights reserved. 31 + * 32 + * You should have received a copy of the GNU General Public License along 33 + * with this program; if not, write to the Free Software Foundation, Inc., 34 + * 675 Mass Ave, Cambridge, MA 02139, USA. 35 + * 36 + *****************************************************************************/ 37 + 38 + /* 39 + * This is the code behind /dev/xilinx_icap -- it allows a user-space 40 + * application to use the Xilinx ICAP subsystem. 41 + * 42 + * The following operations are possible: 43 + * 44 + * open open the port and initialize for access. 45 + * release release port 46 + * write Write a bitstream to the configuration processor. 47 + * read Read a data stream from the configuration processor. 48 + * 49 + * After being opened, the port is initialized and accessed to avoid a 50 + * corrupted first read which may occur with some hardware. The port 51 + * is left in a desynched state, requiring that a synch sequence be 52 + * transmitted before any valid configuration data. A user will have 53 + * exclusive access to the device while it remains open, and the state 54 + * of the ICAP cannot be guaranteed after the device is closed. Note 55 + * that a complete reset of the core and the state of the ICAP cannot 56 + * be performed on many versions of the cores, hence users of this 57 + * device should avoid making inconsistent accesses to the device. In 58 + * particular, accessing the read interface, without first generating 59 + * a write containing a readback packet can leave the ICAP in an 60 + * inaccessible state. 61 + * 62 + * Note that in order to use the read interface, it is first necessary 63 + * to write a request packet to the write interface. i.e., it is not 64 + * possible to simply readback the bitstream (or any configuration 65 + * bits) from a device without specifically requesting them first. 66 + * The code to craft such packets is intended to be part of the 67 + * user-space application code that uses this device. The simplest 68 + * way to use this interface is simply: 69 + * 70 + * cp foo.bit /dev/xilinx_icap 71 + * 72 + * Note that unless foo.bit is an appropriately constructed partial 73 + * bitstream, this has a high likelyhood of overwriting the design 74 + * currently programmed in the FPGA. 75 + */ 76 + 77 + #include <linux/version.h> 78 + #include <linux/module.h> 79 + #include <linux/kernel.h> 80 + #include <linux/types.h> 81 + #include <linux/ioport.h> 82 + #include <linux/interrupt.h> 83 + #include <linux/fcntl.h> 84 + #include <linux/init.h> 85 + #include <linux/poll.h> 86 + #include <linux/proc_fs.h> 87 + #include <asm/semaphore.h> 88 + #include <linux/sysctl.h> 89 + #include <linux/version.h> 90 + #include <linux/fs.h> 91 + #include <linux/cdev.h> 92 + #include <linux/platform_device.h> 93 + 94 + #include <asm/io.h> 95 + #include <asm/uaccess.h> 96 + #include <asm/system.h> 97 + 98 + #ifdef CONFIG_OF 99 + /* For open firmware. */ 100 + #include <linux/of_device.h> 101 + #include <linux/of_platform.h> 102 + #endif 103 + 104 + #include "xilinx_hwicap.h" 105 + #include "buffer_icap.h" 106 + #include "fifo_icap.h" 107 + 108 + #define DRIVER_NAME "xilinx_icap" 109 + 110 + #define HWICAP_REGS (0x10000) 111 + 112 + /* dynamically allocate device number */ 113 + static int xhwicap_major; 114 + static int xhwicap_minor; 115 + #define HWICAP_DEVICES 1 116 + 117 + module_param(xhwicap_major, int, S_IRUGO); 118 + module_param(xhwicap_minor, int, S_IRUGO); 119 + 120 + /* An array, which is set to true when the device is registered. */ 121 + static bool probed_devices[HWICAP_DEVICES]; 122 + 123 + static struct class *icap_class; 124 + 125 + #define UNIMPLEMENTED 0xFFFF 126 + 127 + static const struct config_registers v2_config_registers = { 128 + .CRC = 0, 129 + .FAR = 1, 130 + .FDRI = 2, 131 + .FDRO = 3, 132 + .CMD = 4, 133 + .CTL = 5, 134 + .MASK = 6, 135 + .STAT = 7, 136 + .LOUT = 8, 137 + .COR = 9, 138 + .MFWR = 10, 139 + .FLR = 11, 140 + .KEY = 12, 141 + .CBC = 13, 142 + .IDCODE = 14, 143 + .AXSS = UNIMPLEMENTED, 144 + .C0R_1 = UNIMPLEMENTED, 145 + .CSOB = UNIMPLEMENTED, 146 + .WBSTAR = UNIMPLEMENTED, 147 + .TIMER = UNIMPLEMENTED, 148 + .BOOTSTS = UNIMPLEMENTED, 149 + .CTL_1 = UNIMPLEMENTED, 150 + }; 151 + 152 + static const struct config_registers v4_config_registers = { 153 + .CRC = 0, 154 + .FAR = 1, 155 + .FDRI = 2, 156 + .FDRO = 3, 157 + .CMD = 4, 158 + .CTL = 5, 159 + .MASK = 6, 160 + .STAT = 7, 161 + .LOUT = 8, 162 + .COR = 9, 163 + .MFWR = 10, 164 + .FLR = UNIMPLEMENTED, 165 + .KEY = UNIMPLEMENTED, 166 + .CBC = 11, 167 + .IDCODE = 12, 168 + .AXSS = 13, 169 + .C0R_1 = UNIMPLEMENTED, 170 + .CSOB = UNIMPLEMENTED, 171 + .WBSTAR = UNIMPLEMENTED, 172 + .TIMER = UNIMPLEMENTED, 173 + .BOOTSTS = UNIMPLEMENTED, 174 + .CTL_1 = UNIMPLEMENTED, 175 + }; 176 + static const struct config_registers v5_config_registers = { 177 + .CRC = 0, 178 + .FAR = 1, 179 + .FDRI = 2, 180 + .FDRO = 3, 181 + .CMD = 4, 182 + .CTL = 5, 183 + .MASK = 6, 184 + .STAT = 7, 185 + .LOUT = 8, 186 + .COR = 9, 187 + .MFWR = 10, 188 + .FLR = UNIMPLEMENTED, 189 + .KEY = UNIMPLEMENTED, 190 + .CBC = 11, 191 + .IDCODE = 12, 192 + .AXSS = 13, 193 + .C0R_1 = 14, 194 + .CSOB = 15, 195 + .WBSTAR = 16, 196 + .TIMER = 17, 197 + .BOOTSTS = 18, 198 + .CTL_1 = 19, 199 + }; 200 + 201 + /** 202 + * hwicap_command_desync: Send a DESYNC command to the ICAP port. 203 + * @parameter drvdata: a pointer to the drvdata. 204 + * 205 + * This command desynchronizes the ICAP After this command, a 206 + * bitstream containing a NULL packet, followed by a SYNCH packet is 207 + * required before the ICAP will recognize commands. 208 + */ 209 + int hwicap_command_desync(struct hwicap_drvdata *drvdata) 210 + { 211 + u32 buffer[4]; 212 + u32 index = 0; 213 + 214 + /* 215 + * Create the data to be written to the ICAP. 216 + */ 217 + buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1; 218 + buffer[index++] = XHI_CMD_DESYNCH; 219 + buffer[index++] = XHI_NOOP_PACKET; 220 + buffer[index++] = XHI_NOOP_PACKET; 221 + 222 + /* 223 + * Write the data to the FIFO and intiate the transfer of data present 224 + * in the FIFO to the ICAP device. 225 + */ 226 + return drvdata->config->set_configuration(drvdata, 227 + &buffer[0], index); 228 + } 229 + 230 + /** 231 + * hwicap_command_capture: Send a CAPTURE command to the ICAP port. 232 + * @parameter drvdata: a pointer to the drvdata. 233 + * 234 + * This command captures all of the flip flop states so they will be 235 + * available during readback. One can use this command instead of 236 + * enabling the CAPTURE block in the design. 237 + */ 238 + int hwicap_command_capture(struct hwicap_drvdata *drvdata) 239 + { 240 + u32 buffer[7]; 241 + u32 index = 0; 242 + 243 + /* 244 + * Create the data to be written to the ICAP. 245 + */ 246 + buffer[index++] = XHI_DUMMY_PACKET; 247 + buffer[index++] = XHI_SYNC_PACKET; 248 + buffer[index++] = XHI_NOOP_PACKET; 249 + buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1; 250 + buffer[index++] = XHI_CMD_GCAPTURE; 251 + buffer[index++] = XHI_DUMMY_PACKET; 252 + buffer[index++] = XHI_DUMMY_PACKET; 253 + 254 + /* 255 + * Write the data to the FIFO and intiate the transfer of data 256 + * present in the FIFO to the ICAP device. 257 + */ 258 + return drvdata->config->set_configuration(drvdata, 259 + &buffer[0], index); 260 + 261 + } 262 + 263 + /** 264 + * hwicap_get_configuration_register: Query a configuration register. 265 + * @parameter drvdata: a pointer to the drvdata. 266 + * @parameter reg: a constant which represents the configuration 267 + * register value to be returned. 268 + * Examples: XHI_IDCODE, XHI_FLR. 269 + * @parameter RegData: returns the value of the register. 270 + * 271 + * Sends a query packet to the ICAP and then receives the response. 272 + * The icap is left in Synched state. 273 + */ 274 + int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, 275 + u32 reg, u32 *RegData) 276 + { 277 + int status; 278 + u32 buffer[6]; 279 + u32 index = 0; 280 + 281 + /* 282 + * Create the data to be written to the ICAP. 283 + */ 284 + buffer[index++] = XHI_DUMMY_PACKET; 285 + buffer[index++] = XHI_SYNC_PACKET; 286 + buffer[index++] = XHI_NOOP_PACKET; 287 + buffer[index++] = hwicap_type_1_read(reg) | 1; 288 + buffer[index++] = XHI_NOOP_PACKET; 289 + buffer[index++] = XHI_NOOP_PACKET; 290 + 291 + /* 292 + * Write the data to the FIFO and intiate the transfer of data present 293 + * in the FIFO to the ICAP device. 294 + */ 295 + status = drvdata->config->set_configuration(drvdata, 296 + &buffer[0], index); 297 + if (status) 298 + return status; 299 + 300 + /* 301 + * Read the configuration register 302 + */ 303 + status = drvdata->config->get_configuration(drvdata, RegData, 1); 304 + if (status) 305 + return status; 306 + 307 + return 0; 308 + } 309 + 310 + int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) 311 + { 312 + int status; 313 + u32 idcode; 314 + 315 + dev_dbg(drvdata->dev, "initializing\n"); 316 + 317 + /* Abort any current transaction, to make sure we have the 318 + * ICAP in a good state. */ 319 + dev_dbg(drvdata->dev, "Reset...\n"); 320 + drvdata->config->reset(drvdata); 321 + 322 + dev_dbg(drvdata->dev, "Desync...\n"); 323 + status = hwicap_command_desync(drvdata); 324 + if (status) 325 + return status; 326 + 327 + /* Attempt to read the IDCODE from ICAP. This 328 + * may not be returned correctly, due to the design of the 329 + * hardware. 330 + */ 331 + dev_dbg(drvdata->dev, "Reading IDCODE...\n"); 332 + status = hwicap_get_configuration_register( 333 + drvdata, drvdata->config_regs->IDCODE, &idcode); 334 + dev_dbg(drvdata->dev, "IDCODE = %x\n", idcode); 335 + if (status) 336 + return status; 337 + 338 + dev_dbg(drvdata->dev, "Desync...\n"); 339 + status = hwicap_command_desync(drvdata); 340 + if (status) 341 + return status; 342 + 343 + return 0; 344 + } 345 + 346 + static ssize_t 347 + hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) 348 + { 349 + struct hwicap_drvdata *drvdata = file->private_data; 350 + ssize_t bytes_to_read = 0; 351 + u32 *kbuf; 352 + u32 words; 353 + u32 bytes_remaining; 354 + int status; 355 + 356 + if (down_interruptible(&drvdata->sem)) 357 + return -ERESTARTSYS; 358 + 359 + if (drvdata->read_buffer_in_use) { 360 + /* If there are leftover bytes in the buffer, just */ 361 + /* return them and don't try to read more from the */ 362 + /* ICAP device. */ 363 + bytes_to_read = 364 + (count < drvdata->read_buffer_in_use) ? count : 365 + drvdata->read_buffer_in_use; 366 + 367 + /* Return the data currently in the read buffer. */ 368 + if (copy_to_user(buf, drvdata->read_buffer, bytes_to_read)) { 369 + status = -EFAULT; 370 + goto error; 371 + } 372 + drvdata->read_buffer_in_use -= bytes_to_read; 373 + memcpy(drvdata->read_buffer + bytes_to_read, 374 + drvdata->read_buffer, 4 - bytes_to_read); 375 + } else { 376 + /* Get new data from the ICAP, and return was was requested. */ 377 + kbuf = (u32 *) get_zeroed_page(GFP_KERNEL); 378 + if (!kbuf) { 379 + status = -ENOMEM; 380 + goto error; 381 + } 382 + 383 + /* The ICAP device is only able to read complete */ 384 + /* words. If a number of bytes that do not correspond */ 385 + /* to complete words is requested, then we read enough */ 386 + /* words to get the required number of bytes, and then */ 387 + /* save the remaining bytes for the next read. */ 388 + 389 + /* Determine the number of words to read, rounding up */ 390 + /* if necessary. */ 391 + words = ((count + 3) >> 2); 392 + bytes_to_read = words << 2; 393 + 394 + if (bytes_to_read > PAGE_SIZE) 395 + bytes_to_read = PAGE_SIZE; 396 + 397 + /* Ensure we only read a complete number of words. */ 398 + bytes_remaining = bytes_to_read & 3; 399 + bytes_to_read &= ~3; 400 + words = bytes_to_read >> 2; 401 + 402 + status = drvdata->config->get_configuration(drvdata, 403 + kbuf, words); 404 + 405 + /* If we didn't read correctly, then bail out. */ 406 + if (status) { 407 + free_page((unsigned long)kbuf); 408 + goto error; 409 + } 410 + 411 + /* If we fail to return the data to the user, then bail out. */ 412 + if (copy_to_user(buf, kbuf, bytes_to_read)) { 413 + free_page((unsigned long)kbuf); 414 + status = -EFAULT; 415 + goto error; 416 + } 417 + memcpy(kbuf, drvdata->read_buffer, bytes_remaining); 418 + drvdata->read_buffer_in_use = bytes_remaining; 419 + free_page((unsigned long)kbuf); 420 + } 421 + status = bytes_to_read; 422 + error: 423 + up(&drvdata->sem); 424 + return status; 425 + } 426 + 427 + static ssize_t 428 + hwicap_write(struct file *file, const char *buf, 429 + size_t count, loff_t *ppos) 430 + { 431 + struct hwicap_drvdata *drvdata = file->private_data; 432 + ssize_t written = 0; 433 + ssize_t left = count; 434 + u32 *kbuf; 435 + ssize_t len; 436 + ssize_t status; 437 + 438 + if (down_interruptible(&drvdata->sem)) 439 + return -ERESTARTSYS; 440 + 441 + left += drvdata->write_buffer_in_use; 442 + 443 + /* Only write multiples of 4 bytes. */ 444 + if (left < 4) { 445 + status = 0; 446 + goto error; 447 + } 448 + 449 + kbuf = (u32 *) __get_free_page(GFP_KERNEL); 450 + if (!kbuf) { 451 + status = -ENOMEM; 452 + goto error; 453 + } 454 + 455 + while (left > 3) { 456 + /* only write multiples of 4 bytes, so there might */ 457 + /* be as many as 3 bytes left (at the end). */ 458 + len = left; 459 + 460 + if (len > PAGE_SIZE) 461 + len = PAGE_SIZE; 462 + len &= ~3; 463 + 464 + if (drvdata->write_buffer_in_use) { 465 + memcpy(kbuf, drvdata->write_buffer, 466 + drvdata->write_buffer_in_use); 467 + if (copy_from_user( 468 + (((char *)kbuf) + (drvdata->write_buffer_in_use)), 469 + buf + written, 470 + len - (drvdata->write_buffer_in_use))) { 471 + free_page((unsigned long)kbuf); 472 + status = -EFAULT; 473 + goto error; 474 + } 475 + } else { 476 + if (copy_from_user(kbuf, buf + written, len)) { 477 + free_page((unsigned long)kbuf); 478 + status = -EFAULT; 479 + goto error; 480 + } 481 + } 482 + 483 + status = drvdata->config->set_configuration(drvdata, 484 + kbuf, len >> 2); 485 + 486 + if (status) { 487 + free_page((unsigned long)kbuf); 488 + status = -EFAULT; 489 + goto error; 490 + } 491 + if (drvdata->write_buffer_in_use) { 492 + len -= drvdata->write_buffer_in_use; 493 + left -= drvdata->write_buffer_in_use; 494 + drvdata->write_buffer_in_use = 0; 495 + } 496 + written += len; 497 + left -= len; 498 + } 499 + if ((left > 0) && (left < 4)) { 500 + if (!copy_from_user(drvdata->write_buffer, 501 + buf + written, left)) { 502 + drvdata->write_buffer_in_use = left; 503 + written += left; 504 + left = 0; 505 + } 506 + } 507 + 508 + free_page((unsigned long)kbuf); 509 + status = written; 510 + error: 511 + up(&drvdata->sem); 512 + return status; 513 + } 514 + 515 + static int hwicap_open(struct inode *inode, struct file *file) 516 + { 517 + struct hwicap_drvdata *drvdata; 518 + int status; 519 + 520 + drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); 521 + 522 + if (down_interruptible(&drvdata->sem)) 523 + return -ERESTARTSYS; 524 + 525 + if (drvdata->is_open) { 526 + status = -EBUSY; 527 + goto error; 528 + } 529 + 530 + status = hwicap_initialize_hwicap(drvdata); 531 + if (status) { 532 + dev_err(drvdata->dev, "Failed to open file"); 533 + goto error; 534 + } 535 + 536 + file->private_data = drvdata; 537 + drvdata->write_buffer_in_use = 0; 538 + drvdata->read_buffer_in_use = 0; 539 + drvdata->is_open = 1; 540 + 541 + error: 542 + up(&drvdata->sem); 543 + return status; 544 + } 545 + 546 + static int hwicap_release(struct inode *inode, struct file *file) 547 + { 548 + struct hwicap_drvdata *drvdata = file->private_data; 549 + int i; 550 + int status = 0; 551 + 552 + if (down_interruptible(&drvdata->sem)) 553 + return -ERESTARTSYS; 554 + 555 + if (drvdata->write_buffer_in_use) { 556 + /* Flush write buffer. */ 557 + for (i = drvdata->write_buffer_in_use; i < 4; i++) 558 + drvdata->write_buffer[i] = 0; 559 + 560 + status = drvdata->config->set_configuration(drvdata, 561 + (u32 *) drvdata->write_buffer, 1); 562 + if (status) 563 + goto error; 564 + } 565 + 566 + status = hwicap_command_desync(drvdata); 567 + if (status) 568 + goto error; 569 + 570 + error: 571 + drvdata->is_open = 0; 572 + up(&drvdata->sem); 573 + return status; 574 + } 575 + 576 + static struct file_operations hwicap_fops = { 577 + .owner = THIS_MODULE, 578 + .write = hwicap_write, 579 + .read = hwicap_read, 580 + .open = hwicap_open, 581 + .release = hwicap_release, 582 + }; 583 + 584 + static int __devinit hwicap_setup(struct device *dev, int id, 585 + const struct resource *regs_res, 586 + const struct hwicap_driver_config *config, 587 + const struct config_registers *config_regs) 588 + { 589 + dev_t devt; 590 + struct hwicap_drvdata *drvdata = NULL; 591 + int retval = 0; 592 + 593 + dev_info(dev, "Xilinx icap port driver\n"); 594 + 595 + if (id < 0) { 596 + for (id = 0; id < HWICAP_DEVICES; id++) 597 + if (!probed_devices[id]) 598 + break; 599 + } 600 + if (id < 0 || id >= HWICAP_DEVICES) { 601 + dev_err(dev, "%s%i too large\n", DRIVER_NAME, id); 602 + return -EINVAL; 603 + } 604 + if (probed_devices[id]) { 605 + dev_err(dev, "cannot assign to %s%i; it is already in use\n", 606 + DRIVER_NAME, id); 607 + return -EBUSY; 608 + } 609 + 610 + probed_devices[id] = 1; 611 + 612 + devt = MKDEV(xhwicap_major, xhwicap_minor + id); 613 + 614 + drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); 615 + if (!drvdata) { 616 + dev_err(dev, "Couldn't allocate device private record\n"); 617 + return -ENOMEM; 618 + } 619 + memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata)); 620 + dev_set_drvdata(dev, (void *)drvdata); 621 + 622 + if (!regs_res) { 623 + dev_err(dev, "Couldn't get registers resource\n"); 624 + retval = -EFAULT; 625 + goto failed1; 626 + } 627 + 628 + drvdata->mem_start = regs_res->start; 629 + drvdata->mem_end = regs_res->end; 630 + drvdata->mem_size = regs_res->end - regs_res->start + 1; 631 + 632 + if (!request_mem_region(drvdata->mem_start, 633 + drvdata->mem_size, DRIVER_NAME)) { 634 + dev_err(dev, "Couldn't lock memory region at %p\n", 635 + (void *)regs_res->start); 636 + retval = -EBUSY; 637 + goto failed1; 638 + } 639 + 640 + drvdata->devt = devt; 641 + drvdata->dev = dev; 642 + drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size); 643 + if (!drvdata->base_address) { 644 + dev_err(dev, "ioremap() failed\n"); 645 + goto failed2; 646 + } 647 + 648 + drvdata->config = config; 649 + drvdata->config_regs = config_regs; 650 + 651 + init_MUTEX(&drvdata->sem); 652 + drvdata->is_open = 0; 653 + 654 + dev_info(dev, "ioremap %lx to %p with size %x\n", 655 + (unsigned long int)drvdata->mem_start, 656 + drvdata->base_address, drvdata->mem_size); 657 + 658 + cdev_init(&drvdata->cdev, &hwicap_fops); 659 + drvdata->cdev.owner = THIS_MODULE; 660 + retval = cdev_add(&drvdata->cdev, devt, 1); 661 + if (retval) { 662 + dev_err(dev, "cdev_add() failed\n"); 663 + goto failed3; 664 + } 665 + /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */ 666 + class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME); 667 + return 0; /* success */ 668 + 669 + failed3: 670 + iounmap(drvdata->base_address); 671 + 672 + failed2: 673 + release_mem_region(regs_res->start, drvdata->mem_size); 674 + 675 + failed1: 676 + kfree(drvdata); 677 + 678 + return retval; 679 + } 680 + 681 + static struct hwicap_driver_config buffer_icap_config = { 682 + .get_configuration = buffer_icap_get_configuration, 683 + .set_configuration = buffer_icap_set_configuration, 684 + .reset = buffer_icap_reset, 685 + }; 686 + 687 + static struct hwicap_driver_config fifo_icap_config = { 688 + .get_configuration = fifo_icap_get_configuration, 689 + .set_configuration = fifo_icap_set_configuration, 690 + .reset = fifo_icap_reset, 691 + }; 692 + 693 + static int __devexit hwicap_remove(struct device *dev) 694 + { 695 + struct hwicap_drvdata *drvdata; 696 + 697 + drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev); 698 + 699 + if (!drvdata) 700 + return 0; 701 + 702 + class_device_destroy(icap_class, drvdata->devt); 703 + cdev_del(&drvdata->cdev); 704 + iounmap(drvdata->base_address); 705 + release_mem_region(drvdata->mem_start, drvdata->mem_size); 706 + kfree(drvdata); 707 + dev_set_drvdata(dev, NULL); 708 + probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0; 709 + 710 + return 0; /* success */ 711 + } 712 + 713 + static int __devinit hwicap_drv_probe(struct platform_device *pdev) 714 + { 715 + struct resource *res; 716 + const struct config_registers *regs; 717 + const char *family; 718 + 719 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 720 + if (!res) 721 + return -ENODEV; 722 + 723 + /* It's most likely that we're using V4, if the family is not 724 + specified */ 725 + regs = &v4_config_registers; 726 + family = pdev->dev.platform_data; 727 + 728 + if (family) { 729 + if (!strcmp(family, "virtex2p")) { 730 + regs = &v2_config_registers; 731 + } else if (!strcmp(family, "virtex4")) { 732 + regs = &v4_config_registers; 733 + } else if (!strcmp(family, "virtex5")) { 734 + regs = &v5_config_registers; 735 + } 736 + } 737 + 738 + return hwicap_setup(&pdev->dev, pdev->id, res, 739 + &buffer_icap_config, regs); 740 + } 741 + 742 + static int __devexit hwicap_drv_remove(struct platform_device *pdev) 743 + { 744 + return hwicap_remove(&pdev->dev); 745 + } 746 + 747 + static struct platform_driver hwicap_platform_driver = { 748 + .probe = hwicap_drv_probe, 749 + .remove = hwicap_drv_remove, 750 + .driver = { 751 + .owner = THIS_MODULE, 752 + .name = DRIVER_NAME, 753 + }, 754 + }; 755 + 756 + /* --------------------------------------------------------------------- 757 + * OF bus binding 758 + */ 759 + 760 + #if defined(CONFIG_OF) 761 + static int __devinit 762 + hwicap_of_probe(struct of_device *op, const struct of_device_id *match) 763 + { 764 + struct resource res; 765 + const unsigned int *id; 766 + const char *family; 767 + int rc; 768 + const struct hwicap_driver_config *config = match->data; 769 + const struct config_registers *regs; 770 + 771 + dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match); 772 + 773 + rc = of_address_to_resource(op->node, 0, &res); 774 + if (rc) { 775 + dev_err(&op->dev, "invalid address\n"); 776 + return rc; 777 + } 778 + 779 + id = of_get_property(op->node, "port-number", NULL); 780 + 781 + /* It's most likely that we're using V4, if the family is not 782 + specified */ 783 + regs = &v4_config_registers; 784 + family = of_get_property(op->node, "xlnx,family", NULL); 785 + 786 + if (family) { 787 + if (!strcmp(family, "virtex2p")) { 788 + regs = &v2_config_registers; 789 + } else if (!strcmp(family, "virtex4")) { 790 + regs = &v4_config_registers; 791 + } else if (!strcmp(family, "virtex5")) { 792 + regs = &v5_config_registers; 793 + } 794 + } 795 + return hwicap_setup(&op->dev, id ? *id : -1, &res, config, 796 + regs); 797 + } 798 + 799 + static int __devexit hwicap_of_remove(struct of_device *op) 800 + { 801 + return hwicap_remove(&op->dev); 802 + } 803 + 804 + /* Match table for of_platform binding */ 805 + static const struct of_device_id __devinit hwicap_of_match[] = { 806 + { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, 807 + { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, 808 + {}, 809 + }; 810 + MODULE_DEVICE_TABLE(of, hwicap_of_match); 811 + 812 + static struct of_platform_driver hwicap_of_driver = { 813 + .owner = THIS_MODULE, 814 + .name = DRIVER_NAME, 815 + .match_table = hwicap_of_match, 816 + .probe = hwicap_of_probe, 817 + .remove = __devexit_p(hwicap_of_remove), 818 + .driver = { 819 + .name = DRIVER_NAME, 820 + }, 821 + }; 822 + 823 + /* Registration helpers to keep the number of #ifdefs to a minimum */ 824 + static inline int __devinit hwicap_of_register(void) 825 + { 826 + pr_debug("hwicap: calling of_register_platform_driver()\n"); 827 + return of_register_platform_driver(&hwicap_of_driver); 828 + } 829 + 830 + static inline void __devexit hwicap_of_unregister(void) 831 + { 832 + of_unregister_platform_driver(&hwicap_of_driver); 833 + } 834 + #else /* CONFIG_OF */ 835 + /* CONFIG_OF not enabled; do nothing helpers */ 836 + static inline int __devinit hwicap_of_register(void) { return 0; } 837 + static inline void __devexit hwicap_of_unregister(void) { } 838 + #endif /* CONFIG_OF */ 839 + 840 + static int __devinit hwicap_module_init(void) 841 + { 842 + dev_t devt; 843 + int retval; 844 + 845 + icap_class = class_create(THIS_MODULE, "xilinx_config"); 846 + 847 + if (xhwicap_major) { 848 + devt = MKDEV(xhwicap_major, xhwicap_minor); 849 + retval = register_chrdev_region( 850 + devt, 851 + HWICAP_DEVICES, 852 + DRIVER_NAME); 853 + if (retval < 0) 854 + return retval; 855 + } else { 856 + retval = alloc_chrdev_region(&devt, 857 + xhwicap_minor, 858 + HWICAP_DEVICES, 859 + DRIVER_NAME); 860 + if (retval < 0) 861 + return retval; 862 + xhwicap_major = MAJOR(devt); 863 + } 864 + 865 + retval = platform_driver_register(&hwicap_platform_driver); 866 + 867 + if (retval) 868 + goto failed1; 869 + 870 + retval = hwicap_of_register(); 871 + 872 + if (retval) 873 + goto failed2; 874 + 875 + return retval; 876 + 877 + failed2: 878 + platform_driver_unregister(&hwicap_platform_driver); 879 + 880 + failed1: 881 + unregister_chrdev_region(devt, HWICAP_DEVICES); 882 + 883 + return retval; 884 + } 885 + 886 + static void __devexit hwicap_module_cleanup(void) 887 + { 888 + dev_t devt = MKDEV(xhwicap_major, xhwicap_minor); 889 + 890 + class_destroy(icap_class); 891 + 892 + platform_driver_unregister(&hwicap_platform_driver); 893 + 894 + hwicap_of_unregister(); 895 + 896 + unregister_chrdev_region(devt, HWICAP_DEVICES); 897 + } 898 + 899 + module_init(hwicap_module_init); 900 + module_exit(hwicap_module_cleanup); 901 + 902 + MODULE_AUTHOR("Xilinx, Inc; Xilinx Research Labs Group"); 903 + MODULE_DESCRIPTION("Xilinx ICAP Port Driver"); 904 + MODULE_LICENSE("GPL");
+193
drivers/char/xilinx_hwicap/xilinx_hwicap.h
··· 1 + /***************************************************************************** 2 + * 3 + * Author: Xilinx, Inc. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + * 10 + * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 + * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 + * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 + * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 + * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 + * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 + * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 + * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 + * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 + * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 + * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 + * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 + * FOR A PARTICULAR PURPOSE. 23 + * 24 + * Xilinx products are not intended for use in life support appliances, 25 + * devices, or systems. Use in such applications is expressly prohibited. 26 + * 27 + * (c) Copyright 2003-2007 Xilinx Inc. 28 + * All rights reserved. 29 + * 30 + * You should have received a copy of the GNU General Public License along 31 + * with this program; if not, write to the Free Software Foundation, Inc., 32 + * 675 Mass Ave, Cambridge, MA 02139, USA. 33 + * 34 + *****************************************************************************/ 35 + 36 + #ifndef XILINX_HWICAP_H_ /* prevent circular inclusions */ 37 + #define XILINX_HWICAP_H_ /* by using protection macros */ 38 + 39 + #include <linux/types.h> 40 + #include <linux/cdev.h> 41 + #include <linux/version.h> 42 + #include <linux/platform_device.h> 43 + 44 + #include <asm/io.h> 45 + 46 + struct hwicap_drvdata { 47 + u32 write_buffer_in_use; /* Always in [0,3] */ 48 + u8 write_buffer[4]; 49 + u32 read_buffer_in_use; /* Always in [0,3] */ 50 + u8 read_buffer[4]; 51 + u32 mem_start; /* phys. address of the control registers */ 52 + u32 mem_end; /* phys. address of the control registers */ 53 + u32 mem_size; 54 + void __iomem *base_address;/* virt. address of the control registers */ 55 + 56 + struct device *dev; 57 + struct cdev cdev; /* Char device structure */ 58 + dev_t devt; 59 + 60 + const struct hwicap_driver_config *config; 61 + const struct config_registers *config_regs; 62 + void *private_data; 63 + bool is_open; 64 + struct semaphore sem; 65 + }; 66 + 67 + struct hwicap_driver_config { 68 + int (*get_configuration)(struct hwicap_drvdata *drvdata, u32 *data, 69 + u32 size); 70 + int (*set_configuration)(struct hwicap_drvdata *drvdata, u32 *data, 71 + u32 size); 72 + void (*reset)(struct hwicap_drvdata *drvdata); 73 + }; 74 + 75 + /* Number of times to poll the done regsiter */ 76 + #define XHI_MAX_RETRIES 10 77 + 78 + /************ Constant Definitions *************/ 79 + 80 + #define XHI_PAD_FRAMES 0x1 81 + 82 + /* Mask for calculating configuration packet headers */ 83 + #define XHI_WORD_COUNT_MASK_TYPE_1 0x7FFUL 84 + #define XHI_WORD_COUNT_MASK_TYPE_2 0x1FFFFFUL 85 + #define XHI_TYPE_MASK 0x7 86 + #define XHI_REGISTER_MASK 0xF 87 + #define XHI_OP_MASK 0x3 88 + 89 + #define XHI_TYPE_SHIFT 29 90 + #define XHI_REGISTER_SHIFT 13 91 + #define XHI_OP_SHIFT 27 92 + 93 + #define XHI_TYPE_1 1 94 + #define XHI_TYPE_2 2 95 + #define XHI_OP_WRITE 2 96 + #define XHI_OP_READ 1 97 + 98 + /* Address Block Types */ 99 + #define XHI_FAR_CLB_BLOCK 0 100 + #define XHI_FAR_BRAM_BLOCK 1 101 + #define XHI_FAR_BRAM_INT_BLOCK 2 102 + 103 + struct config_registers { 104 + u32 CRC; 105 + u32 FAR; 106 + u32 FDRI; 107 + u32 FDRO; 108 + u32 CMD; 109 + u32 CTL; 110 + u32 MASK; 111 + u32 STAT; 112 + u32 LOUT; 113 + u32 COR; 114 + u32 MFWR; 115 + u32 FLR; 116 + u32 KEY; 117 + u32 CBC; 118 + u32 IDCODE; 119 + u32 AXSS; 120 + u32 C0R_1; 121 + u32 CSOB; 122 + u32 WBSTAR; 123 + u32 TIMER; 124 + u32 BOOTSTS; 125 + u32 CTL_1; 126 + }; 127 + 128 + /* Configuration Commands */ 129 + #define XHI_CMD_NULL 0 130 + #define XHI_CMD_WCFG 1 131 + #define XHI_CMD_MFW 2 132 + #define XHI_CMD_DGHIGH 3 133 + #define XHI_CMD_RCFG 4 134 + #define XHI_CMD_START 5 135 + #define XHI_CMD_RCAP 6 136 + #define XHI_CMD_RCRC 7 137 + #define XHI_CMD_AGHIGH 8 138 + #define XHI_CMD_SWITCH 9 139 + #define XHI_CMD_GRESTORE 10 140 + #define XHI_CMD_SHUTDOWN 11 141 + #define XHI_CMD_GCAPTURE 12 142 + #define XHI_CMD_DESYNCH 13 143 + #define XHI_CMD_IPROG 15 /* Only in Virtex5 */ 144 + #define XHI_CMD_CRCC 16 /* Only in Virtex5 */ 145 + #define XHI_CMD_LTIMER 17 /* Only in Virtex5 */ 146 + 147 + /* Packet constants */ 148 + #define XHI_SYNC_PACKET 0xAA995566UL 149 + #define XHI_DUMMY_PACKET 0xFFFFFFFFUL 150 + #define XHI_NOOP_PACKET (XHI_TYPE_1 << XHI_TYPE_SHIFT) 151 + #define XHI_TYPE_2_READ ((XHI_TYPE_2 << XHI_TYPE_SHIFT) | \ 152 + (XHI_OP_READ << XHI_OP_SHIFT)) 153 + 154 + #define XHI_TYPE_2_WRITE ((XHI_TYPE_2 << XHI_TYPE_SHIFT) | \ 155 + (XHI_OP_WRITE << XHI_OP_SHIFT)) 156 + 157 + #define XHI_TYPE2_CNT_MASK 0x07FFFFFF 158 + 159 + #define XHI_TYPE_1_PACKET_MAX_WORDS 2047UL 160 + #define XHI_TYPE_1_HEADER_BYTES 4 161 + #define XHI_TYPE_2_HEADER_BYTES 8 162 + 163 + /* Constant to use for CRC check when CRC has been disabled */ 164 + #define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL 165 + 166 + /** 167 + * hwicap_type_1_read: Generates a Type 1 read packet header. 168 + * @parameter: Register is the address of the register to be read back. 169 + * 170 + * Generates a Type 1 read packet header, which is used to indirectly 171 + * read registers in the configuration logic. This packet must then 172 + * be sent through the icap device, and a return packet received with 173 + * the information. 174 + **/ 175 + static inline u32 hwicap_type_1_read(u32 Register) 176 + { 177 + return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | 178 + (Register << XHI_REGISTER_SHIFT) | 179 + (XHI_OP_READ << XHI_OP_SHIFT); 180 + } 181 + 182 + /** 183 + * hwicap_type_1_write: Generates a Type 1 write packet header 184 + * @parameter: Register is the address of the register to be read back. 185 + **/ 186 + static inline u32 hwicap_type_1_write(u32 Register) 187 + { 188 + return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | 189 + (Register << XHI_REGISTER_SHIFT) | 190 + (XHI_OP_WRITE << XHI_OP_SHIFT); 191 + } 192 + 193 + #endif
+15 -38
drivers/serial/uartlite.c
··· 17 17 #include <linux/tty.h> 18 18 #include <linux/delay.h> 19 19 #include <linux/interrupt.h> 20 + #include <linux/init.h> 20 21 #include <asm/io.h> 21 22 #if defined(CONFIG_OF) 23 + #include <linux/of.h> 22 24 #include <linux/of_device.h> 23 25 #include <linux/of_platform.h> 26 + 27 + /* Match table for of_platform binding */ 28 + static struct of_device_id ulite_of_match[] __devinitdata = { 29 + { .compatible = "xlnx,opb-uartlite-1.00.b", }, 30 + { .compatible = "xlnx,xps-uartlite-1.00.a", }, 31 + {} 32 + }; 33 + MODULE_DEVICE_TABLE(of, ulite_of_match); 34 + 24 35 #endif 25 36 26 37 #define ULITE_NAME "ttyUL" ··· 286 275 287 276 static int ulite_request_port(struct uart_port *port) 288 277 { 278 + pr_debug("ulite console: port=%p; port->mapbase=%x\n", 279 + port, port->mapbase); 280 + 289 281 if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) { 290 282 dev_err(port->dev, "Memory region busy\n"); 291 283 return -EBUSY; ··· 389 375 spin_unlock_irqrestore(&port->lock, flags); 390 376 } 391 377 392 - #if defined(CONFIG_OF) 393 - static inline void __init ulite_console_of_find_device(int id) 394 - { 395 - struct device_node *np; 396 - struct resource res; 397 - const unsigned int *of_id; 398 - int rc; 399 - 400 - for_each_compatible_node(np, NULL, "xilinx,uartlite") { 401 - of_id = of_get_property(np, "port-number", NULL); 402 - if ((!of_id) || (*of_id != id)) 403 - continue; 404 - 405 - rc = of_address_to_resource(np, 0, &res); 406 - if (rc) 407 - continue; 408 - 409 - ulite_ports[id].mapbase = res.start; 410 - of_node_put(np); 411 - return; 412 - } 413 - } 414 - #else /* CONFIG_OF */ 415 - static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ } 416 - #endif /* CONFIG_OF */ 417 - 418 378 static int __init ulite_console_setup(struct console *co, char *options) 419 379 { 420 380 struct uart_port *port; ··· 402 414 403 415 port = &ulite_ports[co->index]; 404 416 405 - /* Check if it is an OF device */ 406 - if (!port->mapbase) 407 - ulite_console_of_find_device(co->index); 408 - 409 - /* Do we have a device now? */ 417 + /* Has the device been initialized yet? */ 410 418 if (!port->mapbase) { 411 419 pr_debug("console on ttyUL%i not present\n", co->index); 412 420 return -ENODEV; ··· 600 616 { 601 617 return ulite_release(&op->dev); 602 618 } 603 - 604 - /* Match table for of_platform binding */ 605 - static struct of_device_id __devinit ulite_of_match[] = { 606 - { .type = "serial", .compatible = "xilinx,uartlite", }, 607 - {}, 608 - }; 609 - MODULE_DEVICE_TABLE(of, ulite_of_match); 610 619 611 620 static struct of_platform_driver ulite_of_driver = { 612 621 .owner = THIS_MODULE,
+2 -2
drivers/video/xilinxfb.c
··· 459 459 } 460 460 461 461 /* Match table for of_platform binding */ 462 - static struct of_device_id __devinit xilinxfb_of_match[] = { 463 - { .compatible = "xilinx,ml300-fb", }, 462 + static struct of_device_id xilinxfb_of_match[] __devinitdata = { 463 + { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, 464 464 {}, 465 465 }; 466 466 MODULE_DEVICE_TABLE(of, xilinxfb_of_match);