root/drivers/char/xilinx_hwicap/fifo_icap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fifo_icap_fifo_write
  2. fifo_icap_fifo_read
  3. fifo_icap_set_read_size
  4. fifo_icap_start_config
  5. fifo_icap_start_readback
  6. fifo_icap_get_status
  7. fifo_icap_busy
  8. fifo_icap_write_fifo_vacancy
  9. fifo_icap_read_fifo_occupancy
  10. fifo_icap_set_configuration
  11. fifo_icap_get_configuration
  12. fifo_icap_reset
  13. fifo_icap_flush_fifo

   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  *     (c) Copyright 2007-2008 Xilinx Inc.
  25  *     All rights reserved.
  26  *
  27  *     You should have received a copy of the GNU General Public License along
  28  *     with this program; if not, write to the Free Software Foundation, Inc.,
  29  *     675 Mass Ave, Cambridge, MA 02139, USA.
  30  *
  31  *****************************************************************************/
  32 
  33 #include "fifo_icap.h"
  34 
  35 /* Register offsets for the XHwIcap device. */
  36 #define XHI_GIER_OFFSET 0x1C  /* Device Global Interrupt Enable Reg */
  37 #define XHI_IPISR_OFFSET 0x20  /* Interrupt Status Register */
  38 #define XHI_IPIER_OFFSET 0x28  /* Interrupt Enable Register */
  39 #define XHI_WF_OFFSET 0x100 /* Write FIFO */
  40 #define XHI_RF_OFFSET 0x104 /* Read FIFO */
  41 #define XHI_SZ_OFFSET 0x108 /* Size Register */
  42 #define XHI_CR_OFFSET 0x10C /* Control Register */
  43 #define XHI_SR_OFFSET 0x110 /* Status Register */
  44 #define XHI_WFV_OFFSET 0x114 /* Write FIFO Vacancy Register */
  45 #define XHI_RFO_OFFSET 0x118 /* Read FIFO Occupancy Register */
  46 
  47 /* Device Global Interrupt Enable Register (GIER) bit definitions */
  48 
  49 #define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */
  50 
  51 /**
  52  * HwIcap Device Interrupt Status/Enable Registers
  53  *
  54  * Interrupt Status Register (IPISR) : This register holds the
  55  * interrupt status flags for the device. These bits are toggle on
  56  * write.
  57  *
  58  * Interrupt Enable Register (IPIER) : This register is used to enable
  59  * interrupt sources for the device.
  60  * Writing a '1' to a bit enables the corresponding interrupt.
  61  * Writing a '0' to a bit disables the corresponding interrupt.
  62  *
  63  * IPISR/IPIER registers have the same bit definitions and are only defined
  64  * once.
  65  */
  66 #define XHI_IPIXR_RFULL_MASK 0x00000008 /* Read FIFO Full */
  67 #define XHI_IPIXR_WEMPTY_MASK 0x00000004 /* Write FIFO Empty */
  68 #define XHI_IPIXR_RDP_MASK 0x00000002 /* Read FIFO half full */
  69 #define XHI_IPIXR_WRP_MASK 0x00000001 /* Write FIFO half full */
  70 #define XHI_IPIXR_ALL_MASK 0x0000000F /* Mask of all interrupts */
  71 
  72 /* Control Register (CR) */
  73 #define XHI_CR_SW_RESET_MASK 0x00000008 /* SW Reset Mask */
  74 #define XHI_CR_FIFO_CLR_MASK 0x00000004 /* FIFO Clear Mask */
  75 #define XHI_CR_READ_MASK 0x00000002 /* Read from ICAP to FIFO */
  76 #define XHI_CR_WRITE_MASK 0x00000001 /* Write from FIFO to ICAP */
  77 
  78 
  79 #define XHI_WFO_MAX_VACANCY 1024 /* Max Write FIFO Vacancy, in words */
  80 #define XHI_RFO_MAX_OCCUPANCY 256 /* Max Read FIFO Occupancy, in words */
  81 /* The maximum amount we can request from fifo_icap_get_configuration
  82    at once, in bytes. */
  83 #define XHI_MAX_READ_TRANSACTION_WORDS 0xFFF
  84 
  85 
  86 /**
  87  * fifo_icap_fifo_write - Write data to the write FIFO.
  88  * @drvdata: a pointer to the drvdata.
  89  * @data: the 32-bit value to be written to the FIFO.
  90  *
  91  * This function will silently fail if the fifo is full.
  92  **/
  93 static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
  94                 u32 data)
  95 {
  96         dev_dbg(drvdata->dev, "fifo_write: %x\n", data);
  97         out_be32(drvdata->base_address + XHI_WF_OFFSET, data);
  98 }
  99 
 100 /**
 101  * fifo_icap_fifo_read - Read data from the Read FIFO.
 102  * @drvdata: a pointer to the drvdata.
 103  *
 104  * This function will silently fail if the fifo is empty.
 105  **/
 106 static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
 107 {
 108         u32 data = in_be32(drvdata->base_address + XHI_RF_OFFSET);
 109         dev_dbg(drvdata->dev, "fifo_read: %x\n", data);
 110         return data;
 111 }
 112 
 113 /**
 114  * fifo_icap_set_read_size - Set the the size register.
 115  * @drvdata: a pointer to the drvdata.
 116  * @data: the size of the following read transaction, in words.
 117  **/
 118 static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
 119                 u32 data)
 120 {
 121         out_be32(drvdata->base_address + XHI_SZ_OFFSET, data);
 122 }
 123 
 124 /**
 125  * fifo_icap_start_config - Initiate a configuration (write) to the device.
 126  * @drvdata: a pointer to the drvdata.
 127  **/
 128 static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
 129 {
 130         out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_WRITE_MASK);
 131         dev_dbg(drvdata->dev, "configuration started\n");
 132 }
 133 
 134 /**
 135  * fifo_icap_start_readback - Initiate a readback from the device.
 136  * @drvdata: a pointer to the drvdata.
 137  **/
 138 static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
 139 {
 140         out_be32(drvdata->base_address + XHI_CR_OFFSET, XHI_CR_READ_MASK);
 141         dev_dbg(drvdata->dev, "readback started\n");
 142 }
 143 
 144 /**
 145  * fifo_icap_get_status - Get the contents of the status register.
 146  * @drvdata: a pointer to the drvdata.
 147  *
 148  * The status register contains the ICAP status and the done bit.
 149  *
 150  * D8 - cfgerr
 151  * D7 - dalign
 152  * D6 - rip
 153  * D5 - in_abort_l
 154  * D4 - Always 1
 155  * D3 - Always 1
 156  * D2 - Always 1
 157  * D1 - Always 1
 158  * D0 - Done bit
 159  **/
 160 u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata)
 161 {
 162         u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET);
 163         dev_dbg(drvdata->dev, "Getting status = %x\n", status);
 164         return status;
 165 }
 166 
 167 /**
 168  * fifo_icap_busy - Return true if the ICAP is still processing a transaction.
 169  * @drvdata: a pointer to the drvdata.
 170  **/
 171 static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
 172 {
 173         u32 status = in_be32(drvdata->base_address + XHI_SR_OFFSET);
 174         return (status & XHI_SR_DONE_MASK) ? 0 : 1;
 175 }
 176 
 177 /**
 178  * fifo_icap_write_fifo_vacancy - Query the write fifo available space.
 179  * @drvdata: a pointer to the drvdata.
 180  *
 181  * Return the number of words that can be safely pushed into the write fifo.
 182  **/
 183 static inline u32 fifo_icap_write_fifo_vacancy(
 184                 struct hwicap_drvdata *drvdata)
 185 {
 186         return in_be32(drvdata->base_address + XHI_WFV_OFFSET);
 187 }
 188 
 189 /**
 190  * fifo_icap_read_fifo_occupancy - Query the read fifo available data.
 191  * @drvdata: a pointer to the drvdata.
 192  *
 193  * Return the number of words that can be safely read from the read fifo.
 194  **/
 195 static inline u32 fifo_icap_read_fifo_occupancy(
 196                 struct hwicap_drvdata *drvdata)
 197 {
 198         return in_be32(drvdata->base_address + XHI_RFO_OFFSET);
 199 }
 200 
 201 /**
 202  * fifo_icap_set_configuration - Send configuration data to the ICAP.
 203  * @drvdata: a pointer to the drvdata.
 204  * @frame_buffer: a pointer to the data to be written to the
 205  *              ICAP device.
 206  * @num_words: the number of words (32 bit) to write to the ICAP
 207  *              device.
 208 
 209  * This function writes the given user data to the Write FIFO in
 210  * polled mode and starts the transfer of the data to
 211  * the ICAP device.
 212  **/
 213 int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
 214                 u32 *frame_buffer, u32 num_words)
 215 {
 216 
 217         u32 write_fifo_vacancy = 0;
 218         u32 retries = 0;
 219         u32 remaining_words;
 220 
 221         dev_dbg(drvdata->dev, "fifo_set_configuration\n");
 222 
 223         /*
 224          * Check if the ICAP device is Busy with the last Read/Write
 225          */
 226         if (fifo_icap_busy(drvdata))
 227                 return -EBUSY;
 228 
 229         /*
 230          * Set up the buffer pointer and the words to be transferred.
 231          */
 232         remaining_words = num_words;
 233 
 234         while (remaining_words > 0) {
 235                 /*
 236                  * Wait until we have some data in the fifo.
 237                  */
 238                 while (write_fifo_vacancy == 0) {
 239                         write_fifo_vacancy =
 240                                 fifo_icap_write_fifo_vacancy(drvdata);
 241                         retries++;
 242                         if (retries > XHI_MAX_RETRIES)
 243                                 return -EIO;
 244                 }
 245 
 246                 /*
 247                  * Write data into the Write FIFO.
 248                  */
 249                 while ((write_fifo_vacancy != 0) &&
 250                                 (remaining_words > 0)) {
 251                         fifo_icap_fifo_write(drvdata, *frame_buffer);
 252 
 253                         remaining_words--;
 254                         write_fifo_vacancy--;
 255                         frame_buffer++;
 256                 }
 257                 /* Start pushing whatever is in the FIFO into the ICAP. */
 258                 fifo_icap_start_config(drvdata);
 259         }
 260 
 261         /* Wait until the write has finished. */
 262         while (fifo_icap_busy(drvdata)) {
 263                 retries++;
 264                 if (retries > XHI_MAX_RETRIES)
 265                         break;
 266         }
 267 
 268         dev_dbg(drvdata->dev, "done fifo_set_configuration\n");
 269 
 270         /*
 271          * If the requested number of words have not been read from
 272          * the device then indicate failure.
 273          */
 274         if (remaining_words != 0)
 275                 return -EIO;
 276 
 277         return 0;
 278 }
 279 
 280 /**
 281  * fifo_icap_get_configuration - Read configuration data from the device.
 282  * @drvdata: a pointer to the drvdata.
 283  * @data: Address of the data representing the partial bitstream
 284  * @size: the size of the partial bitstream in 32 bit words.
 285  *
 286  * This function reads the specified number of words from the ICAP device in
 287  * the polled mode.
 288  */
 289 int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
 290                 u32 *frame_buffer, u32 num_words)
 291 {
 292 
 293         u32 read_fifo_occupancy = 0;
 294         u32 retries = 0;
 295         u32 *data = frame_buffer;
 296         u32 remaining_words;
 297         u32 words_to_read;
 298 
 299         dev_dbg(drvdata->dev, "fifo_get_configuration\n");
 300 
 301         /*
 302          * Check if the ICAP device is Busy with the last Write/Read
 303          */
 304         if (fifo_icap_busy(drvdata))
 305                 return -EBUSY;
 306 
 307         remaining_words = num_words;
 308 
 309         while (remaining_words > 0) {
 310                 words_to_read = remaining_words;
 311                 /* The hardware has a limit on the number of words
 312                    that can be read at one time.  */
 313                 if (words_to_read > XHI_MAX_READ_TRANSACTION_WORDS)
 314                         words_to_read = XHI_MAX_READ_TRANSACTION_WORDS;
 315 
 316                 remaining_words -= words_to_read;
 317 
 318                 fifo_icap_set_read_size(drvdata, words_to_read);
 319                 fifo_icap_start_readback(drvdata);
 320 
 321                 while (words_to_read > 0) {
 322                         /* Wait until we have some data in the fifo. */
 323                         while (read_fifo_occupancy == 0) {
 324                                 read_fifo_occupancy =
 325                                         fifo_icap_read_fifo_occupancy(drvdata);
 326                                 retries++;
 327                                 if (retries > XHI_MAX_RETRIES)
 328                                         return -EIO;
 329                         }
 330 
 331                         if (read_fifo_occupancy > words_to_read)
 332                                 read_fifo_occupancy = words_to_read;
 333 
 334                         words_to_read -= read_fifo_occupancy;
 335 
 336                         /* Read the data from the Read FIFO. */
 337                         while (read_fifo_occupancy != 0) {
 338                                 *data++ = fifo_icap_fifo_read(drvdata);
 339                                 read_fifo_occupancy--;
 340                         }
 341                 }
 342         }
 343 
 344         dev_dbg(drvdata->dev, "done fifo_get_configuration\n");
 345 
 346         return 0;
 347 }
 348 
 349 /**
 350  * buffer_icap_reset - Reset the logic of the icap device.
 351  * @drvdata: a pointer to the drvdata.
 352  *
 353  * This function forces the software reset of the complete HWICAP device.
 354  * All the registers will return to the default value and the FIFO is also
 355  * flushed as a part of this software reset.
 356  */
 357 void fifo_icap_reset(struct hwicap_drvdata *drvdata)
 358 {
 359         u32 reg_data;
 360         /*
 361          * Reset the device by setting/clearing the RESET bit in the
 362          * Control Register.
 363          */
 364         reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET);
 365 
 366         out_be32(drvdata->base_address + XHI_CR_OFFSET,
 367                                 reg_data | XHI_CR_SW_RESET_MASK);
 368 
 369         out_be32(drvdata->base_address + XHI_CR_OFFSET,
 370                                 reg_data & (~XHI_CR_SW_RESET_MASK));
 371 
 372 }
 373 
 374 /**
 375  * fifo_icap_flush_fifo - This function flushes the FIFOs in the device.
 376  * @drvdata: a pointer to the drvdata.
 377  */
 378 void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
 379 {
 380         u32 reg_data;
 381         /*
 382          * Flush the FIFO by setting/clearing the FIFO Clear bit in the
 383          * Control Register.
 384          */
 385         reg_data = in_be32(drvdata->base_address + XHI_CR_OFFSET);
 386 
 387         out_be32(drvdata->base_address + XHI_CR_OFFSET,
 388                                 reg_data | XHI_CR_FIFO_CLR_MASK);
 389 
 390         out_be32(drvdata->base_address + XHI_CR_OFFSET,
 391                                 reg_data & (~XHI_CR_FIFO_CLR_MASK));
 392 }
 393 

/* [<][>][^][v][top][bottom][index][help] */