blob: f38607cf5b37c4a6af6a48e2d96010b48f4f3b20 [file] [log] [blame]
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -07001/*
Ionela Voinescu49aad6b2014-09-09 20:18:55 +01002 * This file is part of the coreboot project.
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -07003 *
Ionela Voinescu49aad6b2014-09-09 20:18:55 +01004 * Copyright (C) 2014 Imagination Technologies
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -07009 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
Julius Werner08125682014-10-20 13:22:00 -070016#include <soc/cpu.h>
17#include <soc/spi.h>
Ionela Voinescu49aad6b2014-09-09 20:18:55 +010018#include <spi_flash.h>
Ionela Voinescu1d4c3052015-06-07 23:22:34 +010019#include <spi-generic.h>
20#include <stdlib.h>
21#include <string.h>
22#include <timer.h>
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -070023
Ionela Voinescu49aad6b2014-09-09 20:18:55 +010024#if !CONFIG_SPI_ATOMIC_SEQUENCING
25#error "Unsupported SPI driver API"
26#endif
27
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -080028/* Imgtec controller uses 16 bit packet length. */
29#define IMGTEC_SPI_MAX_TRANSFER_SIZE ((1 << 16) - 1)
30
Ionela Voinescu49aad6b2014-09-09 20:18:55 +010031struct img_spi_slave {
32 struct spi_slave slave;
33 /* SPIM instance device parameters */
34 struct spim_device_parameters device_parameters;
35 /* SPIM instance base address */
36 u32 base;
37 /* Boolean property that is TRUE if API has been initialised */
38 int initialised;
39};
40
41/* Allocate memory for the maximum number of devices */
42static struct
43img_spi_slave img_spi_slaves[SPIM_NUM_BLOCKS*SPIM_NUM_PORTS_PER_BLOCK];
44
45/*
46 * Wait for the bit at the shift position to be set in reg
47 * If the bit is not set in SPI_TIMEOUT_VALUE_US return with error
48 */
49static int wait_status(u32 reg, u32 shift)
50{
51 struct stopwatch sw;
52
53 stopwatch_init_usecs_expire(&sw, SPI_TIMEOUT_VALUE_US);
54 while (!(read32(reg) & (1 << shift))) {
55 if (stopwatch_expired(&sw))
56 return -SPIM_TIMEOUT;
57 }
58 return SPIM_OK;
59}
60
61/* Transmitter function. Fills TX FIFO with data before enabling SPIM */
62static int transmitdata(struct spi_slave *slave, u8 *buffer, u32 size)
63{
64 u32 blocksize, base, write_data;
65 int ret;
66
67 base = container_of(slave, struct img_spi_slave, slave)->base;
68 while (size) {
69 /* Wait until FIFO empty */
70 write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_SDE_MASK);
71 ret = wait_status(base + SPFI_INT_STATUS_REG_OFFSET,
72 SPFI_SDE_SHIFT);
73 if (ret)
74 return ret;
75
76 /*
77 * Write to FIFO in blocks of 16 words (64 bytes)
78 * Do 32bit writes first.
79 */
80 blocksize = SPIM_MAX_BLOCK_BYTES;
81 while ((size >= sizeof(u32)) && blocksize) {
82 memcpy(&write_data, buffer, sizeof(u32));
83 write32(base + SPFI_SEND_LONG_REG_OFFSET, write_data);
84 buffer += sizeof(u32);
85 size -= sizeof(u32);
86 blocksize -= sizeof(u32);
87 }
88 while (size && blocksize) {
89 write32(base + SPFI_SEND_BYTE_REG_OFFSET, *buffer);
90 buffer++;
91 size--;
92 blocksize--;
93 }
94 }
95 return SPIM_OK;
96}
97
98/* Receiver function */
99static int receivedata(struct spi_slave *slave, u8 *buffer, u32 size)
100{
101 u32 read_data, base;
102 int ret;
103
104 base = container_of(slave, struct img_spi_slave, slave)->base;
105 /*
106 * Do 32bit reads first. Clear status GDEX32BIT here so that the first
107 * status reg. read gets the actual bit state
108 */
109 write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_GDEX32BIT_MASK);
110 while (size >= sizeof(u32)) {
111 ret = wait_status(base + SPFI_INT_STATUS_REG_OFFSET,
112 SPFI_GDEX32BIT_SHIFT);
113 if (ret)
114 return ret;
115 read_data = read32(base + SPFI_GET_LONG_REG_OFFSET);
116 memcpy(buffer, &read_data, sizeof(u32));
117 buffer += sizeof(u32);
118 size -= sizeof(u32);
119 /* Clear interrupt status on GDEX32BITL */
120 write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_GDEX32BIT_MASK);
121 }
122
123 /*
124 * Do the remaining 8bit reads. Clear status GDEX8BIT here so that
125 * the first status reg. read gets the actual bit state
126 */
127 write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_GDEX8BIT_MASK);
128 while (size) {
129 ret = wait_status(base + SPFI_INT_STATUS_REG_OFFSET,
130 SPFI_GDEX8BIT_SHIFT);
131 if (ret)
132 return ret;
133 *buffer = read32(base + SPFI_GET_BYTE_REG_OFFSET);
134 buffer++;
135 size--;
136 /* Clear interrupt status on SPFI_GDEX8BIT */
137 write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_GDEX8BIT_MASK);
138 }
139 return SPIM_OK;
140}
141
142/* Sets port parameters in port state register. */
143static void setparams(struct spi_slave *slave, u32 port,
144 struct spim_device_parameters *params)
145{
146 u32 spim_parameters, port_state, base;
147
148 spim_parameters = 0;
149
150 base = container_of(slave, struct img_spi_slave, slave)->base;
151 port_state = read32(base + SPFI_PORT_STATE_REG_OFFSET);
152 port_state &= ~((SPIM_PORT0_MASK>>port)|SPFI_PORT_SELECT_MASK);
153 port_state |= params->cs_idle_level<<(SPIM_CS0_IDLE_SHIFT-port);
154 port_state |=
155 params->data_idle_level<<(SPIM_DATA0_IDLE_SHIFT-port);
156
157 /* Clock idle level and phase */
158 switch (params->spi_mode) {
159 case SPIM_MODE_0:
160 break;
161 case SPIM_MODE_1:
162 port_state |= (1 << (SPIM_CLOCK0_PHASE_SHIFT - port));
163 break;
164 case SPIM_MODE_2:
165 port_state |= (1 << (SPIM_CLOCK0_IDLE_SHIFT - port));
166 break;
167 case SPIM_MODE_3:
168 port_state |= (1 << (SPIM_CLOCK0_IDLE_SHIFT - port)) |
169 (1 << (SPIM_CLOCK0_PHASE_SHIFT - port));
170 break;
171 }
172 /* Set port state register */
173 write32(base + SPFI_PORT_STATE_REG_OFFSET, port_state);
174
175 /* Set up values to be written to device parameter register */
176 spim_parameters |= params->bitrate << SPIM_CLK_DIVIDE_SHIFT;
177 spim_parameters |= params->cs_setup << SPIM_CS_SETUP_SHIFT;
178 spim_parameters |= params->cs_hold << SPIM_CS_HOLD_SHIFT;
179 spim_parameters |= params->cs_delay << SPIM_CS_DELAY_SHIFT;
180
181 write32(base + SPFI_PORT_0_PARAM_REG_OFFSET + 4 * port,
182 spim_parameters);
183}
184
185/* Sets up transaction register */
186static u32 transaction_reg_setup(struct spim_buffer *first,
187 struct spim_buffer *second)
188{
189 u32 reg = 0;
190
191 /* 2nd transfer exists? */
192 if (second) {
193 /*
194 * If second transfer exists, it's a "command followed by data"
195 * type of transfer and first transfer is defined by
196 * CMD_LENGTH, ADDR_LENGTH, DUMMY_LENGTH... fields of
197 * transaction register
198 */
199 reg = spi_write_reg_field(reg, SPFI_CMD_LENGTH, 1);
200 reg = spi_write_reg_field(reg, SPFI_ADDR_LENGTH,
201 first->size - 1);
202 reg = spi_write_reg_field(reg, SPFI_DUMMY_LENGTH, 0);
203 /* Set data size (size of the second transfer) */
204 reg = spi_write_reg_field(reg, SPFI_TSIZE, second->size);
205 } else {
206 /* Set data size, in this case size of the 1st transfer */
207 reg = spi_write_reg_field(reg, SPFI_TSIZE, first->size);
208 }
209 return reg;
210}
211
212/* Sets up control register */
213static u32 control_reg_setup(struct spim_buffer *first,
214 struct spim_buffer *second)
215{
216 u32 reg;
217
218 /* Enable SPFI */
219 reg = SPFI_EN_MASK;
220 reg |= first->inter_byte_delay ? SPIM_BYTE_DELAY_MASK : 0;
221
222 /* Set up the transfer mode */
223 reg = spi_write_reg_field(reg, SPFI_TRNSFR_MODE_DQ, SPIM_CMD_MODE_0);
224 reg = spi_write_reg_field(reg, SPFI_TRNSFR_MODE, SPIM_DMODE_SINGLE);
Ionela Voinescu1c0d0c02015-01-19 01:05:16 +0000225 reg = spi_write_reg_field(reg, SPIM_EDGE_TX_RX, 1);
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100226
227 if (second) {
228 /* Set TX bit if the 2nd transaction is 'send' */
229 reg = spi_write_reg_field(reg, SPFI_TX_RX,
230 second->isread ? 0 : 1);
231 /*
232 * Set send/get DMA for both transactions
233 * (first is always 'send')
234 */
235 reg = spi_write_reg_field(reg, SPIM_SEND_DMA, 1);
236 if (second->isread)
237 reg = spi_write_reg_field(reg, SPIM_GET_DMA, 1);
238
239 } else {
240 /* Set TX bit if the 1st transaction is 'send' */
241 reg |= first->isread ? 0 : SPFI_TX_RX_MASK;
242 /* Set send/get DMA */
243 reg |= first->isread ? SPIM_GET_DMA_MASK : SPIM_SEND_DMA_MASK;
244 }
245 return reg;
246}
247
248/* Checks the given buffer information */
249static int check_buffers(struct spi_slave *slave, struct spim_buffer *first,
250 struct spim_buffer *second){
251
252 if (!(container_of(slave, struct img_spi_slave, slave)->initialised))
253 return -SPIM_API_NOT_INITIALISED;
254 /*
255 * First operation must always be defined
256 * It can be either a read or a write and its size cannot be bigge
257 * than SPIM_MAX_TANSFER_BYTES = 64KB - 1 (0xFFFF)
258 */
259 if (!first)
260 return -SPIM_INVALID_READ_WRITE;
261 if (first->size > SPIM_MAX_TRANSFER_BYTES)
262 return -SPIM_INVALID_SIZE;
263 if (first->isread > 1)
264 return -SPIM_INVALID_READ_WRITE;
265 /* Check operation parameters for 'second' */
266 if (second) {
267 /*
268 * If the second operation is defined it must be a read
269 * operation and its size must not be bigger than
270 * SPIM_MAX_TANSFER_BYTES = 64KB - 1 (0xFFFF)
271 */
272 if (second->size > SPIM_MAX_TRANSFER_BYTES)
273 return -SPIM_INVALID_SIZE;
274 if (!second->isread)
275 return -SPIM_INVALID_READ_WRITE;
276 /*
277 * If the second operations is defined, the first operation
278 * must be a write and its size cannot be bigger than
279 * SPIM_MAX_FLASH_COMMAND_BYTES(8): command size (1) +
280 * address size (7).
281 */
282 if (first->isread)
283 return -SPIM_INVALID_READ_WRITE;
284 if (first->size > SPIM_MAX_FLASH_COMMAND_BYTES)
285 return -SPIM_INVALID_SIZE;
286
287 }
288 return SPIM_OK;
289}
290
291/* Checks the set bitrate */
292static int check_bitrate(u32 rate)
293{
294 /* Bitrate must be 1, 2, 4, 8, 16, 32, 64, or 128 */
295 switch (rate) {
296 case 1:
297 case 2:
298 case 4:
299 case 8:
300 case 16:
301 case 32:
302 case 64:
303 case 128:
304 return SPIM_OK;
305 default:
306 return -SPIM_INVALID_BIT_RATE;
307 }
308 return -SPIM_INVALID_BIT_RATE;
309}
310
311/* Checks device parameters for errors */
312static int check_device_params(struct spim_device_parameters *pdev_param)
313{
314 if (pdev_param->spi_mode < SPIM_MODE_0 ||
315 pdev_param->spi_mode > SPIM_MODE_3)
316 return -SPIM_INVALID_SPI_MODE;
317 if (check_bitrate(pdev_param->bitrate) != SPIM_OK)
318 return -SPIM_INVALID_BIT_RATE;
319 if (pdev_param->cs_idle_level > 1)
320 return -SPIM_INVALID_CS_IDLE_LEVEL;
321 if (pdev_param->data_idle_level > 1)
322 return -SPIM_INVALID_DATA_IDLE_LEVEL;
323 return SPIM_OK;
324}
325
326/* Function that carries out read/write operations */
327static int spim_io(struct spi_slave *slave, struct spim_buffer *first,
328 struct spim_buffer *second)
329{
330 u32 reg, base;
331 int i, trans_count, ret;
332 struct spim_buffer *transaction[2];
333
334 base = container_of(slave, struct img_spi_slave, slave)->base;
335
336 ret = check_buffers(slave, first, second);
337 if (ret)
338 return ret;
339
340 /*
341 * Soft reset peripheral internals, this will terminate any
342 * pending transactions
343 */
344 write32(base + SPFI_CONTROL_REG_OFFSET, SPIM_SOFT_RESET_MASK);
345 write32(base + SPFI_CONTROL_REG_OFFSET, 0);
346 /* Port state register */
347 reg = read32(base + SPFI_PORT_STATE_REG_OFFSET);
348 reg = spi_write_reg_field(reg, SPFI_PORT_SELECT, slave->cs);
349 write32(base + SPFI_PORT_STATE_REG_OFFSET, reg);
350 /* Set transaction register */
351 reg = transaction_reg_setup(first, second);
352 write32(base + SPFI_TRANSACTION_REG_OFFSET, reg);
353 /* Clear status */
354 write32(base + SPFI_INT_CLEAR_REG_OFFSET, 0xffffffff);
355 /* Set control register */
356 reg = control_reg_setup(first, second);
357 write32(base + SPFI_CONTROL_REG_OFFSET, reg);
358 /* First transaction always exists */
359 transaction[0] = first;
360 trans_count = 1;
361 /* Is there a second transaction? */
362 if (second) {
363 transaction[1] = second;
364 trans_count++;
365 }
366 /* Now write/read FIFO's */
367 for (i = 0; i < trans_count; i++)
368 /* Which transaction to execute, "Send" or "Get"? */
369 if (transaction[i]->isread) {
370 /* Get */
371 ret = receivedata(slave, transaction[i]->buffer,
372 transaction[i]->size);
373 if (ret) {
374 printk(BIOS_ERR,
375 "%s: Error: receive data failed.\n",
376 __func__);
377 return ret;
378 }
379 } else {
380 /* Send */
381 ret = transmitdata(slave, transaction[i]->buffer,
382 transaction[i]->size);
383 if (ret) {
384 printk(BIOS_ERR,
385 "%s: Error: transmit data failed.\n",
386 __func__);
387 return ret;
388 }
389 }
390
391 /* Wait for end of the transaction */
392 ret = wait_status(base + SPFI_INT_STATUS_REG_OFFSET,
393 SPFI_ALLDONE_SHIFT);
394 if (ret)
395 return ret;
396 /*
397 * Soft reset peripheral internals, this will terminate any
398 * pending transactions
399 */
400 write32(base + SPFI_CONTROL_REG_OFFSET, SPIM_SOFT_RESET_MASK);
401 write32(base + SPFI_CONTROL_REG_OFFSET, 0);
402
403 return SPIM_OK;
404}
405
406/* Initialization, must be called once on start up */
407void spi_init(void)
408{
409 /* Clear everything just in case */
410 memset(img_spi_slaves, 0, sizeof(img_spi_slaves));
411}
412
413/* Set up communications parameters for a SPI slave. */
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700414struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
415{
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100416
417 struct img_spi_slave *img_slave = NULL;
418 struct spi_slave *slave;
419 struct spim_device_parameters *device_parameters;
420 u32 base;
421
422 switch (bus) {
423 case 0:
424 base = IMG_SPIM0_BASE_ADDRESS;
425 break;
426 case 1:
427 base = IMG_SPIM1_BASE_ADDRESS;
428 break;
429 default:
430 printk(BIOS_ERR, "%s: Error: unsupported bus.\n",
431 __func__);
432 return NULL;
433 }
434 if (cs > SPIM_DEVICE4) {
435 printk(BIOS_ERR, "%s: Error: unsupported chipselect.\n",
436 __func__);
437 return NULL;
438 }
439
440 img_slave = img_spi_slaves + bus * SPIM_NUM_PORTS_PER_BLOCK + cs;
441 slave = &(img_slave->slave);
442 device_parameters = &(img_slave->device_parameters);
443
444 img_slave->base = base;
445 slave->bus = bus;
446 slave->cs = cs;
447 slave->rw = SPI_READ_FLAG | SPI_WRITE_FLAG;
Vadim Bendeburyf9ff3532014-11-29 15:06:26 -0800448 slave->max_transfer_size = IMGTEC_SPI_MAX_TRANSFER_SIZE;
449
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100450 device_parameters->bitrate = 64;
451 device_parameters->cs_setup = 0;
452 device_parameters->cs_hold = 0;
453 device_parameters->cs_delay = 0;
454 device_parameters->spi_mode = SPIM_MODE_0;
455 device_parameters->cs_idle_level = 1;
456 device_parameters->data_idle_level = 0;
457 img_slave->initialised = IMG_FALSE;
458
459 return slave;
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700460}
461
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100462/* Claim the bus and prepare it for communication */
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700463int spi_claim_bus(struct spi_slave *slave)
464{
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100465 int ret;
466 struct img_spi_slave *img_slave;
467
468 if (!slave) {
469 printk(BIOS_ERR, "%s: Error: slave was not set up.\n",
470 __func__);
471 return -SPIM_API_NOT_INITIALISED;
472 }
473 img_slave = container_of(slave, struct img_spi_slave, slave);
474 if (img_slave->initialised)
475 return SPIM_OK;
476 /* Check device parameters */
477 ret = check_device_params(&(img_slave->device_parameters));
478 if (ret) {
479 printk(BIOS_ERR, "%s: Error: incorrect device parameters.\n",
480 __func__);
481 return ret;
482 }
483 /* Set device parameters */
484 setparams(slave, slave->cs, &(img_slave->device_parameters));
485 /* Soft reset peripheral internals */
486 write32(img_slave->base + SPFI_CONTROL_REG_OFFSET,
487 SPIM_SOFT_RESET_MASK);
488 write32(img_slave->base + SPFI_CONTROL_REG_OFFSET, 0);
489 img_slave->initialised = IMG_TRUE;
490 return SPIM_OK;
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700491}
492
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100493/* Release the SPI bus */
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700494void spi_release_bus(struct spi_slave *slave)
495{
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100496 struct img_spi_slave *img_slave;
497
498 if (!slave) {
499 printk(BIOS_ERR, "%s: Error: slave was not set up.\n",
500 __func__);
501 return;
502 }
503 img_slave = container_of(slave, struct img_spi_slave, slave);
504 img_slave->initialised = IMG_FALSE;
505 /* Soft reset peripheral internals */
506 write32(img_slave->base + SPFI_CONTROL_REG_OFFSET,
507 SPIM_SOFT_RESET_MASK);
508 write32(img_slave->base + SPFI_CONTROL_REG_OFFSET, 0);
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700509}
510
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100511/* SPI transfer */
512int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout,
513 void *din, unsigned int bytesin)
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700514{
Ionela Voinescu49aad6b2014-09-09 20:18:55 +0100515 struct spim_buffer buff_0;
516 struct spim_buffer buff_1;
517
518 if (!slave) {
519 printk(BIOS_ERR, "%s: Error: slave was not set up.\n",
520 __func__);
521 return -SPIM_API_NOT_INITIALISED;
522 }
523 if (!dout && !din) {
524 printk(BIOS_ERR, "%s: Error: both buffers are NULL.\n",
525 __func__);
526 return -SPIM_INVALID_TRANSFER_DESC;
527 }
528 /* If we only have a read or a write operation
529 * the parameters for it will be put in the first buffer
530 */
531 buff_0.buffer = (dout) ? (void *)dout : (void *)din;
532 buff_0.size = (dout) ? bytesout : bytesin;
533 buff_0.isread = (dout) ? IMG_FALSE : IMG_TRUE;
534 buff_0.inter_byte_delay = 0;
535
536 if (dout && din) {
537 /* Set up the read buffer to receive our data */
538 buff_1.buffer = din;
539 buff_1.size = bytesin;
540 buff_1.isread = IMG_TRUE;
541 buff_1.inter_byte_delay = 0;
542 }
543 return spim_io(slave, &buff_0, (dout && din) ? &buff_1 : NULL);
Vadim Bendeburyb2e465d2014-08-29 16:34:46 -0700544}
Patrick Georgi85497972015-04-20 10:14:19 +0200545
546unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
547{
548 return min(IMGTEC_SPI_MAX_TRANSFER_SIZE, buf_len);
549}