@ -634,6 +634,8 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
{
{
unsigned int remaining = n_rx ;
unsigned int remaining = n_rx ;
unsigned int bytes_to_read = 0 ;
unsigned int bytes_to_read = 0 ;
struct bounce_buffer bb ;
u8 * bb_rxbuf ;
int ret ;
int ret ;
writel ( n_rx , plat - > regbase + CQSPI_REG_INDIRECTRDBYTES ) ;
writel ( n_rx , plat - > regbase + CQSPI_REG_INDIRECTRDBYTES ) ;
@ -642,6 +644,11 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
writel ( CQSPI_REG_INDIRECTRD_START ,
writel ( CQSPI_REG_INDIRECTRD_START ,
plat - > regbase + CQSPI_REG_INDIRECTRD ) ;
plat - > regbase + CQSPI_REG_INDIRECTRD ) ;
ret = bounce_buffer_start ( & bb , ( void * ) rxbuf , n_rx , GEN_BB_WRITE ) ;
if ( ret )
return ret ;
bb_rxbuf = bb . bounce_buffer ;
while ( remaining > 0 ) {
while ( remaining > 0 ) {
ret = cadence_qspi_wait_for_data ( plat ) ;
ret = cadence_qspi_wait_for_data ( plat ) ;
if ( ret < 0 ) {
if ( ret < 0 ) {
@ -655,12 +662,13 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
bytes_to_read * = CQSPI_FIFO_WIDTH ;
bytes_to_read * = CQSPI_FIFO_WIDTH ;
bytes_to_read = bytes_to_read > remaining ?
bytes_to_read = bytes_to_read > remaining ?
remaining : bytes_to_read ;
remaining : bytes_to_read ;
/* Handle non-4-byte aligned access to avoid data abort. */
readsl ( plat - > ahbbase , bb_rxbuf , bytes_to_read > > 2 ) ;
if ( ( ( uintptr_t ) rxbuf % 4 ) | | ( bytes_to_read % 4 ) )
if ( bytes_to_read % 4 )
readsb ( plat - > ahbbase , rxbuf , bytes_to_read ) ;
readsb ( plat - > ahbbase ,
else
bb_rxbuf + rounddown ( bytes_to_read , 4 ) ,
readsl ( plat - > ahbbase , rxbuf , bytes_to_read > > 2 ) ;
bytes_to_read % 4 ) ;
rxbuf + = bytes_to_read ;
bb_rxbuf + = bytes_to_read ;
remaining - = bytes_to_read ;
remaining - = bytes_to_read ;
bytes_to_read = cadence_qspi_get_rd_sram_level ( plat ) ;
bytes_to_read = cadence_qspi_get_rd_sram_level ( plat ) ;
}
}
@ -677,6 +685,7 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
/* Clear indirect completion status */
/* Clear indirect completion status */
writel ( CQSPI_REG_INDIRECTRD_DONE ,
writel ( CQSPI_REG_INDIRECTRD_DONE ,
plat - > regbase + CQSPI_REG_INDIRECTRD ) ;
plat - > regbase + CQSPI_REG_INDIRECTRD ) ;
bounce_buffer_stop ( & bb ) ;
return 0 ;
return 0 ;
@ -684,6 +693,7 @@ failrd:
/* Cancel the indirect read */
/* Cancel the indirect read */
writel ( CQSPI_REG_INDIRECTRD_CANCEL ,
writel ( CQSPI_REG_INDIRECTRD_CANCEL ,
plat - > regbase + CQSPI_REG_INDIRECTRD ) ;
plat - > regbase + CQSPI_REG_INDIRECTRD ) ;
bounce_buffer_stop ( & bb ) ;
return ret ;
return ret ;
}
}