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 * @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 * @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 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 * @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 * @base_address: is the base address of the device 139 * @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_set_offset - Set the bram offset register. 152 * @base_address: contains the base address of the device. 153 * @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 * @base_address: contains the base address of the device. 167 * @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 * @base_address: contains the base address of the component. 183 * @offset: The word offset at which the data should be written. 184 * @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 * @drvdata: a pointer to the drvdata. 198 * @offset: The storage buffer start address. 199 * @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 * @drvdata: a pointer to the drvdata. 232 * @offset: The storage buffer start address. 233 * @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 * @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 * @drvdata: a pointer to the drvdata. 279 * @data: Kernel address of the partial bitstream. 280 * @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 * @drvdata: a pointer to the drvdata. 338 * @data: Address of the data representing the partial bitstream 339 * @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 }; 381