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 * @drvdata: a pointer to the drvdata. 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 u32 buffer_icap_get_status(struct hwicap_drvdata *drvdata) 92 { 93 return in_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET); 94 } 95 96 /** 97 * buffer_icap_get_bram - Reads data from the storage buffer bram. 98 * @base_address: contains the base address of the component. 99 * @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 * @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 u32 status = in_be32(base_address + XHI_STATUS_REG_OFFSET); 121 return (status & 1) == XHI_NOT_FINISHED; 122 } 123 124 /** 125 * buffer_icap_set_size - Set the size register. 126 * @base_address: is the base address of the device 127 * @data: The size in bytes. 128 * 129 * The size register holds the number of 8 bit bytes to transfer between 130 * bram and the icap (or icap to bram). 131 **/ 132 static inline void buffer_icap_set_size(void __iomem *base_address, 133 u32 data) 134 { 135 out_be32(base_address + XHI_SIZE_REG_OFFSET, data); 136 } 137 138 /** 139 * buffer_icap_set_offset - Set the bram offset register. 140 * @base_address: contains the base address of the device. 141 * @data: is the value to be written to the data register. 142 * 143 * The bram offset register holds the starting bram address to transfer 144 * data from during configuration or write data to during readback. 145 **/ 146 static inline void buffer_icap_set_offset(void __iomem *base_address, 147 u32 data) 148 { 149 out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data); 150 } 151 152 /** 153 * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register. 154 * @base_address: contains the base address of the device. 155 * @data: is the value to be written to the data register. 156 * 157 * The RNC register determines the direction of the data transfer. It 158 * controls whether a configuration or readback take place. Writing to 159 * this register initiates the transfer. A value of 1 initiates a 160 * readback while writing a value of 0 initiates a configuration. 161 **/ 162 static inline void buffer_icap_set_rnc(void __iomem *base_address, 163 u32 data) 164 { 165 out_be32(base_address + XHI_RNC_REG_OFFSET, data); 166 } 167 168 /** 169 * buffer_icap_set_bram - Write data to the storage buffer bram. 170 * @base_address: contains the base address of the component. 171 * @offset: The word offset at which the data should be written. 172 * @data: The value to be written to the bram offset. 173 * 174 * A bram is used as a configuration memory cache. One frame of data can 175 * be stored in this "storage buffer". 176 **/ 177 static inline void buffer_icap_set_bram(void __iomem *base_address, 178 u32 offset, u32 data) 179 { 180 out_be32(base_address + (offset << 2), data); 181 } 182 183 /** 184 * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer. 185 * @drvdata: a pointer to the drvdata. 186 * @offset: The storage buffer start address. 187 * @count: The number of words (32 bit) to read from the 188 * device (ICAP). 189 **/ 190 static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, 191 u32 offset, u32 count) 192 { 193 194 s32 retries = 0; 195 void __iomem *base_address = drvdata->base_address; 196 197 if (buffer_icap_busy(base_address)) 198 return -EBUSY; 199 200 if ((offset + count) > XHI_MAX_BUFFER_INTS) 201 return -EINVAL; 202 203 /* setSize count*4 to get bytes. */ 204 buffer_icap_set_size(base_address, (count << 2)); 205 buffer_icap_set_offset(base_address, offset); 206 buffer_icap_set_rnc(base_address, XHI_READBACK); 207 208 while (buffer_icap_busy(base_address)) { 209 retries++; 210 if (retries > XHI_MAX_RETRIES) 211 return -EBUSY; 212 } 213 return 0; 214 215 }; 216 217 /** 218 * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer. 219 * @drvdata: a pointer to the drvdata. 220 * @offset: The storage buffer start address. 221 * @count: The number of words (32 bit) to read from the 222 * device (ICAP). 223 **/ 224 static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, 225 u32 offset, u32 count) 226 { 227 228 s32 retries = 0; 229 void __iomem *base_address = drvdata->base_address; 230 231 if (buffer_icap_busy(base_address)) 232 return -EBUSY; 233 234 if ((offset + count) > XHI_MAX_BUFFER_INTS) 235 return -EINVAL; 236 237 /* setSize count*4 to get bytes. */ 238 buffer_icap_set_size(base_address, count << 2); 239 buffer_icap_set_offset(base_address, offset); 240 buffer_icap_set_rnc(base_address, XHI_CONFIGURE); 241 242 while (buffer_icap_busy(base_address)) { 243 retries++; 244 if (retries > XHI_MAX_RETRIES) 245 return -EBUSY; 246 } 247 return 0; 248 249 }; 250 251 /** 252 * buffer_icap_reset - Reset the logic of the icap device. 253 * @drvdata: a pointer to the drvdata. 254 * 255 * Writing to the status register resets the ICAP logic in an internal 256 * version of the core. For the version of the core published in EDK, 257 * this is a noop. 258 **/ 259 void buffer_icap_reset(struct hwicap_drvdata *drvdata) 260 { 261 out_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET, 0xFEFE); 262 } 263 264 /** 265 * buffer_icap_set_configuration - Load a partial bitstream from system memory. 266 * @drvdata: a pointer to the drvdata. 267 * @data: Kernel address of the partial bitstream. 268 * @size: the size of the partial bitstream in 32 bit words. 269 **/ 270 int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, 271 u32 size) 272 { 273 int status; 274 s32 buffer_count = 0; 275 s32 num_writes = 0; 276 bool dirty = 0; 277 u32 i; 278 void __iomem *base_address = drvdata->base_address; 279 280 /* Loop through all the data */ 281 for (i = 0, buffer_count = 0; i < size; i++) { 282 283 /* Copy data to bram */ 284 buffer_icap_set_bram(base_address, buffer_count, data[i]); 285 dirty = 1; 286 287 if (buffer_count < XHI_MAX_BUFFER_INTS - 1) { 288 buffer_count++; 289 continue; 290 } 291 292 /* Write data to ICAP */ 293 status = buffer_icap_device_write( 294 drvdata, 295 XHI_BUFFER_START, 296 XHI_MAX_BUFFER_INTS); 297 if (status != 0) { 298 /* abort. */ 299 buffer_icap_reset(drvdata); 300 return status; 301 } 302 303 buffer_count = 0; 304 num_writes++; 305 dirty = 0; 306 } 307 308 /* Write unwritten data to ICAP */ 309 if (dirty) { 310 /* Write data to ICAP */ 311 status = buffer_icap_device_write(drvdata, XHI_BUFFER_START, 312 buffer_count); 313 if (status != 0) { 314 /* abort. */ 315 buffer_icap_reset(drvdata); 316 } 317 return status; 318 } 319 320 return 0; 321 }; 322 323 /** 324 * buffer_icap_get_configuration - Read configuration data from the device. 325 * @drvdata: a pointer to the drvdata. 326 * @data: Address of the data representing the partial bitstream 327 * @size: the size of the partial bitstream in 32 bit words. 328 **/ 329 int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, 330 u32 size) 331 { 332 int status; 333 s32 buffer_count = 0; 334 s32 read_count = 0; 335 u32 i; 336 void __iomem *base_address = drvdata->base_address; 337 338 /* Loop through all the data */ 339 for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i < size; i++) { 340 if (buffer_count == XHI_MAX_BUFFER_INTS) { 341 u32 words_remaining = size - i; 342 u32 words_to_read = 343 words_remaining < 344 XHI_MAX_BUFFER_INTS ? words_remaining : 345 XHI_MAX_BUFFER_INTS; 346 347 /* Read data from ICAP */ 348 status = buffer_icap_device_read( 349 drvdata, 350 XHI_BUFFER_START, 351 words_to_read); 352 if (status != 0) { 353 /* abort. */ 354 buffer_icap_reset(drvdata); 355 return status; 356 } 357 358 buffer_count = 0; 359 read_count++; 360 } 361 362 /* Copy data from bram */ 363 data[i] = buffer_icap_get_bram(base_address, buffer_count); 364 buffer_count++; 365 } 366 367 return 0; 368 }; 369