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 82 #define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */ 83 #define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */ 84 /* The maximum amount we can request from fifo_icap_get_configuration 85 at once, in bytes. */ 86 #define XHI_MAX_READ_TRANSACTION_WORDS 0xFFF 87 88 89 /** 90 * fifo_icap_fifo_write - Write data to the write FIFO. 91 * @drvdata: a pointer to the drvdata. 92 * @data: the 32-bit value to be written to the FIFO. 93 * 94 * This function will silently fail if the fifo is full. 95 **/ 96 static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata, 97 u32 data) 98 { 99 dev_dbg(drvdata->dev, "fifo_write: %x\n", data); 100 out_be32(drvdata->base_address + XHI_WF_OFFSET, data); 101 } 102 103 /** 104 * fifo_icap_fifo_read - Read data from the Read FIFO. 105 * @drvdata: a pointer to the drvdata. 106 * 107 * This function will silently fail if the fifo is empty. 108 **/ 109 static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata) 110 { 111 u32 data = in_be32(drvdata->base_address + XHI_RF_OFFSET); 112 dev_dbg(drvdata->dev, "fifo_read: %x\n", data); 113 return data; 114 } 115 116 /** 117 * fifo_icap_set_read_size - Set the the size register. 118 * @drvdata: a pointer to the drvdata. 119 * @data: the size of the following read transaction, in words. 120 **/ 121 static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, 122 u32 data) 123 { 124 out_be32(drvdata->base_address + XHI_SZ_OFFSET, data); 125 } 126 127 /** 128 * fifo_icap_start_config - Initiate a configuration (write) to the device. 129 * @drvdata: a pointer to the drvdata. 130 **/ 131 static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) 132 { 133 out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_WRITE_MASK); 134 dev_dbg(drvdata->dev, "configuration started\n"); 135 } 136 137 /** 138 * fifo_icap_start_readback - Initiate a readback from the device. 139 * @drvdata: a pointer to the drvdata. 140 **/ 141 static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) 142 { 143 out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_READ_MASK); 144 dev_dbg(drvdata->dev, "readback started\n"); 145 } 146 147 /** 148 * fifo_icap_get_status - Get the contents of the status register. 149 * @drvdata: a pointer to the drvdata. 150 * 151 * The status register contains the ICAP status and the done bit. 152 * 153 * D8 - cfgerr 154 * D7 - dalign 155 * D6 - rip 156 * D5 - in_abort_l 157 * D4 - Always 1 158 * D3 - Always 1 159 * D2 - Always 1 160 * D1 - Always 1 161 * D0 - Done bit 162 **/ 163 u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata) 164 { 165 u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET); 166 dev_dbg(drvdata->dev, "Getting status = %x\n", status); 167 return status; 168 } 169 170 /** 171 * fifo_icap_busy - Return true if the ICAP is still processing a transaction. 172 * @drvdata: a pointer to the drvdata. 173 **/ 174 static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) 175 { 176 u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET); 177 return (status & XHI_SR_DONE_MASK) ? 0 : 1; 178 } 179 180 /** 181 * fifo_icap_write_fifo_vacancy - Query the write fifo available space. 182 * @drvdata: a pointer to the drvdata. 183 * 184 * Return the number of words that can be safely pushed into the write fifo. 185 **/ 186 static inline u32 fifo_icap_write_fifo_vacancy( 187 struct hwicap_drvdata *drvdata) 188 { 189 return in_be32(drvdata->base_address + XHI_WFV_OFFSET); 190 } 191 192 /** 193 * fifo_icap_read_fifo_occupancy - Query the read fifo available data. 194 * @drvdata: a pointer to the drvdata. 195 * 196 * Return the number of words that can be safely read from the read fifo. 197 **/ 198 static inline u32 fifo_icap_read_fifo_occupancy( 199 struct hwicap_drvdata *drvdata) 200 { 201 return in_be32(drvdata->base_address + XHI_RFO_OFFSET); 202 } 203 204 /** 205 * fifo_icap_set_configuration - Send configuration data to the ICAP. 206 * @drvdata: a pointer to the drvdata. 207 * @frame_buffer: a pointer to the data to be written to the 208 * ICAP device. 209 * @num_words: the number of words (32 bit) to write to the ICAP 210 * device. 211 212 * This function writes the given user data to the Write FIFO in 213 * polled mode and starts the transfer of the data to 214 * the ICAP device. 215 **/ 216 int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, 217 u32 *frame_buffer, u32 num_words) 218 { 219 220 u32 write_fifo_vacancy = 0; 221 u32 retries = 0; 222 u32 remaining_words; 223 224 dev_dbg(drvdata->dev, "fifo_set_configuration\n"); 225 226 /* 227 * Check if the ICAP device is Busy with the last Read/Write 228 */ 229 if (fifo_icap_busy(drvdata)) 230 return -EBUSY; 231 232 /* 233 * Set up the buffer pointer and the words to be transferred. 234 */ 235 remaining_words = num_words; 236 237 while (remaining_words > 0) { 238 /* 239 * Wait until we have some data in the fifo. 240 */ 241 while (write_fifo_vacancy == 0) { 242 write_fifo_vacancy = 243 fifo_icap_write_fifo_vacancy(drvdata); 244 retries++; 245 if (retries > XHI_MAX_RETRIES) 246 return -EIO; 247 } 248 249 /* 250 * Write data into the Write FIFO. 251 */ 252 while ((write_fifo_vacancy != 0) && 253 (remaining_words > 0)) { 254 fifo_icap_fifo_write(drvdata, *frame_buffer); 255 256 remaining_words--; 257 write_fifo_vacancy--; 258 frame_buffer++; 259 } 260 /* Start pushing whatever is in the FIFO into the ICAP. */ 261 fifo_icap_start_config(drvdata); 262 } 263 264 /* Wait until the write has finished. */ 265 while (fifo_icap_busy(drvdata)) { 266 retries++; 267 if (retries > XHI_MAX_RETRIES) 268 break; 269 } 270 271 dev_dbg(drvdata->dev, "done fifo_set_configuration\n"); 272 273 /* 274 * If the requested number of words have not been read from 275 * the device then indicate failure. 276 */ 277 if (remaining_words != 0) 278 return -EIO; 279 280 return 0; 281 } 282 283 /** 284 * fifo_icap_get_configuration - Read configuration data from the device. 285 * @drvdata: a pointer to the drvdata. 286 * @data: Address of the data representing the partial bitstream 287 * @size: the size of the partial bitstream in 32 bit words. 288 * 289 * This function reads the specified number of words from the ICAP device in 290 * the polled mode. 291 */ 292 int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, 293 u32 *frame_buffer, u32 num_words) 294 { 295 296 u32 read_fifo_occupancy = 0; 297 u32 retries = 0; 298 u32 *data = frame_buffer; 299 u32 remaining_words; 300 u32 words_to_read; 301 302 dev_dbg(drvdata->dev, "fifo_get_configuration\n"); 303 304 /* 305 * Check if the ICAP device is Busy with the last Write/Read 306 */ 307 if (fifo_icap_busy(drvdata)) 308 return -EBUSY; 309 310 remaining_words = num_words; 311 312 while (remaining_words > 0) { 313 words_to_read = remaining_words; 314 /* The hardware has a limit on the number of words 315 that can be read at one time. */ 316 if (words_to_read > XHI_MAX_READ_TRANSACTION_WORDS) 317 words_to_read = XHI_MAX_READ_TRANSACTION_WORDS; 318 319 remaining_words -= words_to_read; 320 321 fifo_icap_set_read_size(drvdata, words_to_read); 322 fifo_icap_start_readback(drvdata); 323 324 while (words_to_read > 0) { 325 /* Wait until we have some data in the fifo. */ 326 while (read_fifo_occupancy == 0) { 327 read_fifo_occupancy = 328 fifo_icap_read_fifo_occupancy(drvdata); 329 retries++; 330 if (retries > XHI_MAX_RETRIES) 331 return -EIO; 332 } 333 334 if (read_fifo_occupancy > words_to_read) 335 read_fifo_occupancy = words_to_read; 336 337 words_to_read -= read_fifo_occupancy; 338 339 /* Read the data from the Read FIFO. */ 340 while (read_fifo_occupancy != 0) { 341 *data++ = fifo_icap_fifo_read(drvdata); 342 read_fifo_occupancy--; 343 } 344 } 345 } 346 347 dev_dbg(drvdata->dev, "done fifo_get_configuration\n"); 348 349 return 0; 350 } 351 352 /** 353 * buffer_icap_reset - Reset the logic of the icap device. 354 * @drvdata: a pointer to the drvdata. 355 * 356 * This function forces the software reset of the complete HWICAP device. 357 * All the registers will return to the default value and the FIFO is also 358 * flushed as a part of this software reset. 359 */ 360 void fifo_icap_reset(struct hwicap_drvdata *drvdata) 361 { 362 u32 reg_data; 363 /* 364 * Reset the device by setting/clearing the RESET bit in the 365 * Control Register. 366 */ 367 reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET); 368 369 out_be32(drvdata->base_address + XHI_CR_OFFSET, 370 reg_data | XHI_CR_SW_RESET_MASK); 371 372 out_be32(drvdata->base_address + XHI_CR_OFFSET, 373 reg_data & (~XHI_CR_SW_RESET_MASK)); 374 375 } 376 377 /** 378 * fifo_icap_flush_fifo - This function flushes the FIFOs in the device. 379 * @drvdata: a pointer to the drvdata. 380 */ 381 void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata) 382 { 383 u32 reg_data; 384 /* 385 * Flush the FIFO by setting/clearing the FIFO Clear bit in the 386 * Control Register. 387 */ 388 reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET); 389 390 out_be32(drvdata->base_address + XHI_CR_OFFSET, 391 reg_data | XHI_CR_FIFO_CLR_MASK); 392 393 out_be32(drvdata->base_address + XHI_CR_OFFSET, 394 reg_data & (~XHI_CR_FIFO_CLR_MASK)); 395 } 396 397