1327Sjkh/***************************************************************************** 2327Sjkh * 3327Sjkh * Author: Xilinx, Inc. 4327Sjkh * 5327Sjkh * This program is free software; you can redistribute it and/or modify it 6327Sjkh * under the terms of the GNU General Public License as published by the 7327Sjkh * Free Software Foundation; either version 2 of the License, or (at your 8327Sjkh * option) any later version. 9327Sjkh * 10327Sjkh * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11327Sjkh * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 1293520Sobrien * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 1393520Sobrien * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 1493520Sobrien * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 1530221Scharnier * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16327Sjkh * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17327Sjkh * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18327Sjkh * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 1995161Sobrien * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20327Sjkh * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21327Sjkh * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22327Sjkh * FOR A PARTICULAR PURPOSE. 23327Sjkh * 2426473Sjkh * (c) Copyright 2003-2008 Xilinx Inc. 254996Sjkh * All rights reserved. 26327Sjkh * 2741866Sjkh * You should have received a copy of the GNU General Public License along 28327Sjkh * with this program; if not, write to the Free Software Foundation, Inc., 2941866Sjkh * 675 Mass Ave, Cambridge, MA 02139, USA. 30327Sjkh * 31327Sjkh *****************************************************************************/ 32445Sjkh 334996Sjkh#include "buffer_icap.h" 347713Sjkh 3567454Ssobomax/* Indicates how many bytes will fit in a buffer. (1 BRAM) */ 3684670Ssobomax#define XHI_MAX_BUFFER_BYTES 2048 3726473Sjkh#define XHI_MAX_BUFFER_INTS (XHI_MAX_BUFFER_BYTES >> 2) 3871095Ssobomax 3971095Ssobomax/* File access and error constants */ 4095161Sobrien#define XHI_DEVICE_READ_ERROR -1 41327Sjkh#define XHI_DEVICE_WRITE_ERROR -2 4230221Scharnier#define XHI_BUFFER_OVERFLOW_ERROR -3 4330221Scharnier 44327Sjkh#define XHI_DEVICE_READ 0x1 45327Sjkh#define XHI_DEVICE_WRITE 0x0 46327Sjkh 47327Sjkh/* Constants for checking transfer status */ 4884670Ssobomax#define XHI_CYCLE_DONE 0 49327Sjkh#define XHI_CYCLE_EXECUTING 1 50327Sjkh 5124428Simp/* buffer_icap register offsets */ 52327Sjkh 53327Sjkh/* Size of transfer, read & write */ 54327Sjkh#define XHI_SIZE_REG_OFFSET 0x800L 55327Sjkh/* offset into bram, read & write */ 56327Sjkh#define XHI_BRAM_OFFSET_REG_OFFSET 0x804L 571337Sjkh/* Read not Configure, direction of transfer. Write only */ 581337Sjkh#define XHI_RNC_REG_OFFSET 0x808L 591337Sjkh/* Indicates transfer complete. Read only */ 601337Sjkh#define XHI_STATUS_REG_OFFSET 0x80CL 611337Sjkh 621337Sjkh/* Constants for setting the RNC register */ 631337Sjkh#define XHI_CONFIGURE 0x0UL 641337Sjkh#define XHI_READBACK 0x1UL 657986Sjkh 6671095Ssobomax/* Constants for the Done register */ 677986Sjkh#define XHI_NOT_FINISHED 0x0UL 687986Sjkh#define XHI_FINISHED 0x1UL 69327Sjkh 70327Sjkh#define XHI_BUFFER_START 0 71327Sjkh 72327Sjkh/** 7326473Sjkh * buffer_icap_get_status - Get the contents of the status register. 7426473Sjkh * @drvdata: a pointer to the drvdata. 7526473Sjkh * 7626473Sjkh * The status register contains the ICAP status and the done bit. 77327Sjkh * 78327Sjkh * D8 - cfgerr 79327Sjkh * D7 - dalign 80327Sjkh * D6 - rip 81327Sjkh * D5 - in_abort_l 82327Sjkh * D4 - Always 1 83327Sjkh * D3 - Always 1 84327Sjkh * D2 - Always 1 85327Sjkh * D1 - Always 1 86327Sjkh * D0 - Done bit 87327Sjkh **/ 88327Sjkhu32 buffer_icap_get_status(struct hwicap_drvdata *drvdata) 89327Sjkh{ 90327Sjkh return in_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET); 91327Sjkh} 92327Sjkh 9341866Sjkh/** 9441866Sjkh * buffer_icap_get_bram - Reads data from the storage buffer bram. 9541866Sjkh * @base_address: contains the base address of the component. 9641866Sjkh * @offset: The word offset from which the data should be read. 97327Sjkh * 98327Sjkh * A bram is used as a configuration memory cache. One frame of data can 99327Sjkh * be stored in this "storage buffer". 100327Sjkh **/ 10141866Sjkhstatic inline u32 buffer_icap_get_bram(void __iomem *base_address, 10241866Sjkh u32 offset) 10341866Sjkh{ 10441866Sjkh return in_be32(base_address + (offset << 2)); 105327Sjkh} 106327Sjkh 107327Sjkh/** 108327Sjkh * buffer_icap_busy - Return true if the icap device is busy 109383Sjkh * @base_address: is the base address of the device 11085019Ssobomax * 111383Sjkh * The queries the low order bit of the status register, which 112383Sjkh * indicates whether the current configuration or readback operation 113445Sjkh * has completed. 114445Sjkh **/ 115445Sjkhstatic inline bool buffer_icap_busy(void __iomem *base_address) 116445Sjkh{ 117327Sjkh u32 status = in_be32(base_address + XHI_STATUS_REG_OFFSET); 11871095Ssobomax return (status & 1) == XHI_NOT_FINISHED; 1191520Salm} 1201520Salm 1214996Sjkh/** 1224996Sjkh * buffer_icap_set_size - Set the size register. 1234996Sjkh * @base_address: is the base address of the device 1244996Sjkh * @data: The size in bytes. 1254996Sjkh * 1264996Sjkh * The size register holds the number of 8 bit bytes to transfer between 1274996Sjkh * bram and the icap (or icap to bram). 1284996Sjkh **/ 1297713Sjkhstatic inline void buffer_icap_set_size(void __iomem *base_address, 1307713Sjkh u32 data) 1317713Sjkh{ 1327713Sjkh out_be32(base_address + XHI_SIZE_REG_OFFSET, data); 13367454Ssobomax} 13467454Ssobomax 13567454Ssobomax/** 13667454Ssobomax * buffer_icap_set_offset - Set the bram offset register. 13771373Ssobomax * @base_address: contains the base address of the device. 13895161Sobrien * @data: is the value to be written to the data register. 13995161Sobrien * 14071373Ssobomax * The bram offset register holds the starting bram address to transfer 14171373Ssobomax * data from during configuration or write data to during readback. 14295161Sobrien **/ 14395161Sobrienstatic inline void buffer_icap_set_offset(void __iomem *base_address, 14495161Sobrien u32 data) 14595161Sobrien{ 14684670Ssobomax out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data); 14785470Ssobomax} 14884670Ssobomax 14984670Ssobomax/** 15084670Ssobomax * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register. 15184670Ssobomax * @base_address: contains the base address of the device. 15284670Ssobomax * @data: is the value to be written to the data register. 15384670Ssobomax * 15484670Ssobomax * The RNC register determines the direction of the data transfer. It 15584670Ssobomax * controls whether a configuration or readback take place. Writing to 15684670Ssobomax * this register initiates the transfer. A value of 1 initiates a 15784670Ssobomax * readback while writing a value of 0 initiates a configuration. 15884670Ssobomax **/ 15984670Ssobomaxstatic inline void buffer_icap_set_rnc(void __iomem *base_address, 16084670Ssobomax u32 data) 16184670Ssobomax{ 162327Sjkh out_be32(base_address + XHI_RNC_REG_OFFSET, data); 163327Sjkh} 16430221Scharnier 165327Sjkh/** 166327Sjkh * buffer_icap_set_bram - Write data to the storage buffer bram. 167327Sjkh * @base_address: contains the base address of the component. 1688857Srgrimes * @offset: The word offset at which the data should be written. 169327Sjkh * @data: The value to be written to the bram offset. 170327Sjkh * 171327Sjkh * A bram is used as a configuration memory cache. One frame of data can 172327Sjkh * be stored in this "storage buffer". 173327Sjkh **/ 174327Sjkhstatic inline void buffer_icap_set_bram(void __iomem *base_address, 175327Sjkh u32 offset, u32 data) 17684670Ssobomax{ 17730221Scharnier out_be32(base_address + (offset << 2), data); 178327Sjkh} 17984670Ssobomax 18084670Ssobomax/** 18130221Scharnier * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer. 18284670Ssobomax * @drvdata: a pointer to the drvdata. 18384670Ssobomax * @offset: The storage buffer start address. 18484670Ssobomax * @count: The number of words (32 bit) to read from the 185327Sjkh * device (ICAP). 186327Sjkh **/ 18730221Scharnierstatic int buffer_icap_device_read(struct hwicap_drvdata *drvdata, 188327Sjkh u32 offset, u32 count) 189327Sjkh{ 190327Sjkh 191327Sjkh s32 retries = 0; 192327Sjkh void __iomem *base_address = drvdata->base_address; 193327Sjkh 19430221Scharnier if (buffer_icap_busy(base_address)) 19530221Scharnier return -EBUSY; 196327Sjkh 19784670Ssobomax if ((offset + count) > XHI_MAX_BUFFER_INTS) 19871373Ssobomax return -EINVAL; 19941866Sjkh 20041866Sjkh /* setSize count*4 to get bytes. */ 20167454Ssobomax buffer_icap_set_size(base_address, (count << 2)); 20284670Ssobomax buffer_icap_set_offset(base_address, offset); 20384670Ssobomax buffer_icap_set_rnc(base_address, XHI_READBACK); 204327Sjkh 205327Sjkh while (buffer_icap_busy(base_address)) { 206 retries++; 207 if (retries > XHI_MAX_RETRIES) 208 return -EBUSY; 209 } 210 return 0; 211 212}; 213 214/** 215 * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer. 216 * @drvdata: a pointer to the drvdata. 217 * @offset: The storage buffer start address. 218 * @count: The number of words (32 bit) to read from the 219 * device (ICAP). 220 **/ 221static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, 222 u32 offset, u32 count) 223{ 224 225 s32 retries = 0; 226 void __iomem *base_address = drvdata->base_address; 227 228 if (buffer_icap_busy(base_address)) 229 return -EBUSY; 230 231 if ((offset + count) > XHI_MAX_BUFFER_INTS) 232 return -EINVAL; 233 234 /* setSize count*4 to get bytes. */ 235 buffer_icap_set_size(base_address, count << 2); 236 buffer_icap_set_offset(base_address, offset); 237 buffer_icap_set_rnc(base_address, XHI_CONFIGURE); 238 239 while (buffer_icap_busy(base_address)) { 240 retries++; 241 if (retries > XHI_MAX_RETRIES) 242 return -EBUSY; 243 } 244 return 0; 245 246}; 247 248/** 249 * buffer_icap_reset - Reset the logic of the icap device. 250 * @drvdata: a pointer to the drvdata. 251 * 252 * Writing to the status register resets the ICAP logic in an internal 253 * version of the core. For the version of the core published in EDK, 254 * this is a noop. 255 **/ 256void buffer_icap_reset(struct hwicap_drvdata *drvdata) 257{ 258 out_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET, 0xFEFE); 259} 260 261/** 262 * buffer_icap_set_configuration - Load a partial bitstream from system memory. 263 * @drvdata: a pointer to the drvdata. 264 * @data: Kernel address of the partial bitstream. 265 * @size: the size of the partial bitstream in 32 bit words. 266 **/ 267int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, 268 u32 size) 269{ 270 int status; 271 s32 buffer_count = 0; 272 bool dirty = false; 273 u32 i; 274 void __iomem *base_address = drvdata->base_address; 275 276 /* Loop through all the data */ 277 for (i = 0, buffer_count = 0; i < size; i++) { 278 279 /* Copy data to bram */ 280 buffer_icap_set_bram(base_address, buffer_count, data[i]); 281 dirty = true; 282 283 if (buffer_count < XHI_MAX_BUFFER_INTS - 1) { 284 buffer_count++; 285 continue; 286 } 287 288 /* Write data to ICAP */ 289 status = buffer_icap_device_write( 290 drvdata, 291 XHI_BUFFER_START, 292 XHI_MAX_BUFFER_INTS); 293 if (status != 0) { 294 /* abort. */ 295 buffer_icap_reset(drvdata); 296 return status; 297 } 298 299 buffer_count = 0; 300 dirty = false; 301 } 302 303 /* Write unwritten data to ICAP */ 304 if (dirty) { 305 /* Write data to ICAP */ 306 status = buffer_icap_device_write(drvdata, XHI_BUFFER_START, 307 buffer_count); 308 if (status != 0) { 309 /* abort. */ 310 buffer_icap_reset(drvdata); 311 } 312 return status; 313 } 314 315 return 0; 316}; 317 318/** 319 * buffer_icap_get_configuration - Read configuration data from the device. 320 * @drvdata: a pointer to the drvdata. 321 * @data: Address of the data representing the partial bitstream 322 * @size: the size of the partial bitstream in 32 bit words. 323 **/ 324int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, 325 u32 size) 326{ 327 int status; 328 s32 buffer_count = 0; 329 u32 i; 330 void __iomem *base_address = drvdata->base_address; 331 332 /* Loop through all the data */ 333 for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i < size; i++) { 334 if (buffer_count == XHI_MAX_BUFFER_INTS) { 335 u32 words_remaining = size - i; 336 u32 words_to_read = 337 words_remaining < 338 XHI_MAX_BUFFER_INTS ? words_remaining : 339 XHI_MAX_BUFFER_INTS; 340 341 /* Read data from ICAP */ 342 status = buffer_icap_device_read( 343 drvdata, 344 XHI_BUFFER_START, 345 words_to_read); 346 if (status != 0) { 347 /* abort. */ 348 buffer_icap_reset(drvdata); 349 return status; 350 } 351 352 buffer_count = 0; 353 } 354 355 /* Copy data from bram */ 356 data[i] = buffer_icap_get_bram(base_address, buffer_count); 357 buffer_count++; 358 } 359 360 return 0; 361}; 362