138
138
#define QSPI_WPSR_WPVSRC_MASK GENMASK(15, 8)
139
139
#define QSPI_WPSR_WPVSRC (src ) (((src) << 8) & QSPI_WPSR_WPVSRC)
140
140
141
+ #define ATMEL_QSPI_TIMEOUT 1000 /* ms */
142
+
141
143
struct atmel_qspi_caps {
142
144
bool has_qspick ;
143
145
bool has_ricr ;
144
146
};
145
147
148
+ struct atmel_qspi_ops ;
149
+
146
150
struct atmel_qspi {
147
151
void __iomem * regs ;
148
152
void __iomem * mem ;
149
153
struct clk * pclk ;
150
154
struct clk * qspick ;
151
155
struct platform_device * pdev ;
152
156
const struct atmel_qspi_caps * caps ;
157
+ const struct atmel_qspi_ops * ops ;
153
158
resource_size_t mmap_size ;
154
159
u32 pending ;
160
+ u32 irq_mask ;
155
161
u32 mr ;
156
162
u32 scr ;
157
163
struct completion cmd_completion ;
158
164
};
159
165
166
+ struct atmel_qspi_ops {
167
+ int (* set_cfg )(struct atmel_qspi * aq , const struct spi_mem_op * op ,
168
+ u32 * offset );
169
+ int (* transfer )(struct spi_mem * mem , const struct spi_mem_op * op ,
170
+ u32 offset );
171
+ };
172
+
160
173
struct atmel_qspi_mode {
161
174
u8 cmd_buswidth ;
162
175
u8 addr_buswidth ;
@@ -404,10 +417,60 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq,
404
417
return 0 ;
405
418
}
406
419
420
+ static int atmel_qspi_wait_for_completion (struct atmel_qspi * aq , u32 irq_mask )
421
+ {
422
+ int err = 0 ;
423
+ u32 sr ;
424
+
425
+ /* Poll INSTRuction End status */
426
+ sr = atmel_qspi_read (aq , QSPI_SR );
427
+ if ((sr & irq_mask ) == irq_mask )
428
+ return 0 ;
429
+
430
+ /* Wait for INSTRuction End interrupt */
431
+ reinit_completion (& aq -> cmd_completion );
432
+ aq -> pending = sr & irq_mask ;
433
+ aq -> irq_mask = irq_mask ;
434
+ atmel_qspi_write (irq_mask , aq , QSPI_IER );
435
+ if (!wait_for_completion_timeout (& aq -> cmd_completion ,
436
+ msecs_to_jiffies (ATMEL_QSPI_TIMEOUT )))
437
+ err = - ETIMEDOUT ;
438
+ atmel_qspi_write (irq_mask , aq , QSPI_IDR );
439
+
440
+ return err ;
441
+ }
442
+
443
+ static int atmel_qspi_transfer (struct spi_mem * mem ,
444
+ const struct spi_mem_op * op , u32 offset )
445
+ {
446
+ struct atmel_qspi * aq = spi_controller_get_devdata (mem -> spi -> controller );
447
+
448
+ /* Skip to the final steps if there is no data */
449
+ if (!op -> data .nbytes )
450
+ return atmel_qspi_wait_for_completion (aq ,
451
+ QSPI_SR_CMD_COMPLETED );
452
+
453
+ /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
454
+ (void )atmel_qspi_read (aq , QSPI_IFR );
455
+
456
+ /* Send/Receive data */
457
+ if (op -> data .dir == SPI_MEM_DATA_IN )
458
+ memcpy_fromio (op -> data .buf .in , aq -> mem + offset ,
459
+ op -> data .nbytes );
460
+ else
461
+ memcpy_toio (aq -> mem + offset , op -> data .buf .out ,
462
+ op -> data .nbytes );
463
+
464
+ /* Release the chip-select */
465
+ atmel_qspi_write (QSPI_CR_LASTXFER , aq , QSPI_CR );
466
+
467
+ return atmel_qspi_wait_for_completion (aq , QSPI_SR_CMD_COMPLETED );
468
+ }
469
+
407
470
static int atmel_qspi_exec_op (struct spi_mem * mem , const struct spi_mem_op * op )
408
471
{
409
472
struct atmel_qspi * aq = spi_controller_get_devdata (mem -> spi -> controller );
410
- u32 sr , offset ;
473
+ u32 offset ;
411
474
int err ;
412
475
413
476
/*
@@ -416,46 +479,20 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
416
479
* when the flash memories overrun the controller's memory space.
417
480
*/
418
481
if (op -> addr .val + op -> data .nbytes > aq -> mmap_size )
419
- return - ENOTSUPP ;
482
+ return - EOPNOTSUPP ;
483
+
484
+ if (op -> addr .nbytes > 4 )
485
+ return - EOPNOTSUPP ;
420
486
421
487
err = pm_runtime_resume_and_get (& aq -> pdev -> dev );
422
488
if (err < 0 )
423
489
return err ;
424
490
425
- err = atmel_qspi_set_cfg (aq , op , & offset );
491
+ err = aq -> ops -> set_cfg (aq , op , & offset );
426
492
if (err )
427
493
goto pm_runtime_put ;
428
494
429
- /* Skip to the final steps if there is no data */
430
- if (op -> data .nbytes ) {
431
- /* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
432
- (void )atmel_qspi_read (aq , QSPI_IFR );
433
-
434
- /* Send/Receive data */
435
- if (op -> data .dir == SPI_MEM_DATA_IN )
436
- memcpy_fromio (op -> data .buf .in , aq -> mem + offset ,
437
- op -> data .nbytes );
438
- else
439
- memcpy_toio (aq -> mem + offset , op -> data .buf .out ,
440
- op -> data .nbytes );
441
-
442
- /* Release the chip-select */
443
- atmel_qspi_write (QSPI_CR_LASTXFER , aq , QSPI_CR );
444
- }
445
-
446
- /* Poll INSTRuction End status */
447
- sr = atmel_qspi_read (aq , QSPI_SR );
448
- if ((sr & QSPI_SR_CMD_COMPLETED ) == QSPI_SR_CMD_COMPLETED )
449
- goto pm_runtime_put ;
450
-
451
- /* Wait for INSTRuction End interrupt */
452
- reinit_completion (& aq -> cmd_completion );
453
- aq -> pending = sr & QSPI_SR_CMD_COMPLETED ;
454
- atmel_qspi_write (QSPI_SR_CMD_COMPLETED , aq , QSPI_IER );
455
- if (!wait_for_completion_timeout (& aq -> cmd_completion ,
456
- msecs_to_jiffies (1000 )))
457
- err = - ETIMEDOUT ;
458
- atmel_qspi_write (QSPI_SR_CMD_COMPLETED , aq , QSPI_IDR );
495
+ err = aq -> ops -> transfer (mem , op , offset );
459
496
460
497
pm_runtime_put :
461
498
pm_runtime_mark_last_busy (& aq -> pdev -> dev );
@@ -599,12 +636,17 @@ static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)
599
636
return IRQ_NONE ;
600
637
601
638
aq -> pending |= pending ;
602
- if ((aq -> pending & QSPI_SR_CMD_COMPLETED ) == QSPI_SR_CMD_COMPLETED )
639
+ if ((aq -> pending & aq -> irq_mask ) == aq -> irq_mask )
603
640
complete (& aq -> cmd_completion );
604
641
605
642
return IRQ_HANDLED ;
606
643
}
607
644
645
+ static const struct atmel_qspi_ops atmel_qspi_ops = {
646
+ .set_cfg = atmel_qspi_set_cfg ,
647
+ .transfer = atmel_qspi_transfer ,
648
+ };
649
+
608
650
static int atmel_qspi_probe (struct platform_device * pdev )
609
651
{
610
652
struct spi_controller * ctrl ;
@@ -629,6 +671,7 @@ static int atmel_qspi_probe(struct platform_device *pdev)
629
671
630
672
init_completion (& aq -> cmd_completion );
631
673
aq -> pdev = pdev ;
674
+ aq -> ops = & atmel_qspi_ops ;
632
675
633
676
/* Map the registers */
634
677
aq -> regs = devm_platform_ioremap_resource_byname (pdev , "qspi_base" );
0 commit comments