@@ -80,6 +80,9 @@ static int qspi_wait_we(QspiDev_t* dev);
8080static int test_ext_flash (QspiDev_t * dev );
8181#endif
8282
83+ /* asm function */
84+ extern void flush_dcache_range (unsigned long start , unsigned long stop );
85+
8386#ifdef DEBUG_UART
8487void uart_init (void )
8588{
@@ -293,9 +296,23 @@ static inline int qspi_isr_wait(uint32_t wait_mask, uint32_t wait_val)
293296 }
294297 return 0 ;
295298}
299+ #ifdef GQSPI_DMA
300+ static inline int qspi_dmaisr_wait (uint32_t wait_mask , uint32_t wait_val )
301+ {
302+ uint32_t timeout = 0 ;
303+ while ((GQSPIDMA_ISR & wait_mask ) == wait_val &&
304+ ++ timeout < GQSPI_TIMEOUT_TRIES );
305+ if (timeout == GQSPI_TIMEOUT_TRIES ) {
306+ return -1 ;
307+ }
308+ return 0 ;
309+ }
310+ #endif
296311
297312static int qspi_gen_fifo_write (uint32_t reg_genfifo )
298313{
314+ uint32_t reg_cfg ;
315+
299316 /* wait until the gen FIFO is not full to write */
300317 if (qspi_isr_wait (GQSPI_IXR_GEN_FIFO_NOT_FULL , 0 )) {
301318 return GQSPI_CODE_TIMEOUT ;
@@ -317,6 +334,17 @@ static int gspi_fifo_tx(const uint8_t* data, uint32_t sz)
317334 return GQSPI_CODE_TIMEOUT ;
318335 }
319336
337+ #if defined(DEBUG_ZYNQ ) && DEBUG_ZYNQ >= 3
338+ uint32_t txSz = sz ;
339+ if (txSz > GQSPI_FIFO_WORD_SZ )
340+ txSz = GQSPI_FIFO_WORD_SZ ;
341+ memcpy (& tmp32 , data , txSz );
342+ GQSPI_TXD = tmp32 ;
343+ wolfBoot_printf ("TXD=%08x\n" , tmp32 );
344+
345+ sz -= txSz ;
346+ data += txSz ;
347+ #else
320348 /* Write data */
321349 if (sz >= 4 ) {
322350 GQSPI_TXD = * (uint32_t * )data ;
@@ -329,23 +357,32 @@ static int gspi_fifo_tx(const uint8_t* data, uint32_t sz)
329357 GQSPI_TXD = tmp32 ;
330358 sz = 0 ;
331359 }
360+ #endif
332361 }
333362 return GQSPI_CODE_SUCCESS ;
334363}
335364
336- static int gspi_fifo_rx (uint8_t * data , uint32_t sz , uint32_t discardSz )
365+ #ifndef GQSPI_DMA
366+ static int gspi_fifo_rx (uint8_t * data , uint32_t sz )
337367{
338368 uint32_t tmp32 ;
369+
339370 while (sz > 0 ) {
340371 /* Wait for RX FIFO not empty */
341372 if (qspi_isr_wait (GQSPI_IXR_RX_FIFO_NOT_EMPTY , 0 )) {
342373 return GQSPI_CODE_TIMEOUT ;
343374 }
344- if (discardSz >= GQSPI_FIFO_WORD_SZ ) {
345- tmp32 = GQSPI_RXD ; /* discard */
346- discardSz -= GQSPI_FIFO_WORD_SZ ;
347- continue ;
348- }
375+
376+ #if defined(DEBUG_ZYNQ ) && DEBUG_ZYNQ >= 3
377+ uint32_t rxSz = sz ;
378+ if (rxSz > GQSPI_FIFO_WORD_SZ )
379+ rxSz = GQSPI_FIFO_WORD_SZ ;
380+ tmp32 = GQSPI_RXD ;
381+ memcpy (data , & tmp32 , rxSz );
382+ wolfBoot_printf ("RXD=%08x\n" , tmp32 );
383+ sz -= rxSz ;
384+ data += rxSz ;
385+ #else
349386 if (sz >= 4 ) {
350387 * (uint32_t * )data = GQSPI_RXD ;
351388 data += 4 ;
@@ -356,9 +393,11 @@ static int gspi_fifo_rx(uint8_t* data, uint32_t sz, uint32_t discardSz)
356393 memcpy (data , & tmp32 , sz );
357394 sz = 0 ;
358395 }
396+ #endif
359397 }
360398 return GQSPI_CODE_SUCCESS ;
361399}
400+ #endif
362401
363402static int qspi_cs (QspiDev_t * pDev , int csAssert )
364403{
@@ -374,6 +413,33 @@ static int qspi_cs(QspiDev_t* pDev, int csAssert)
374413 return qspi_gen_fifo_write (reg_genfifo );
375414}
376415
416+ static uint32_t qspi_calc_exp (uint32_t xferSz , uint32_t * reg_genfifo )
417+ {
418+ uint32_t expval = 8 ;
419+ * reg_genfifo &= ~(GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK );
420+ if (xferSz > GQSPI_GEN_FIFO_IMM_MASK ) {
421+ /* Use exponent mode */
422+ while (1 ) {
423+ if (xferSz & (1 << expval )) {
424+ * reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK ;
425+ * reg_genfifo |= GQSPI_GEN_FIFO_IMM (expval ); /* IMM is exponent */
426+ xferSz = (1 << expval );
427+ break ;
428+ }
429+ expval ++ ;
430+ }
431+ }
432+ else {
433+ /* Use length mode */
434+ * reg_genfifo |= GQSPI_GEN_FIFO_IMM (xferSz ); /* IMM is length */
435+ }
436+ return xferSz ;
437+ }
438+
439+ #ifdef GQSPI_DMA
440+ static uint8_t XALIGNED (QQSPI_DMA_ALIGN ) dmatmp [GQSPI_DMA_TMPSZ ];
441+ #endif
442+
377443static int qspi_transfer (QspiDev_t * pDev ,
378444 const uint8_t * cmdData , uint32_t cmdSz ,
379445 const uint8_t * txData , uint32_t txSz ,
@@ -382,7 +448,9 @@ static int qspi_transfer(QspiDev_t* pDev,
382448{
383449 int ret = GQSPI_CODE_SUCCESS ;
384450 uint32_t reg_genfifo , xferSz ;
385-
451+ #ifdef GQSPI_DMA
452+ uint8_t * dmarxptr = NULL ;
453+ #endif
386454 GQSPI_EN = 1 ; /* Enable device */
387455 qspi_cs (pDev , 1 ); /* Select slave */
388456
@@ -395,14 +463,14 @@ static int qspi_transfer(QspiDev_t* pDev,
395463 xferSz = cmdSz ;
396464 while (ret == GQSPI_CODE_SUCCESS && cmdData && xferSz > 0 ) {
397465 /* Enable TX and send command inline */
398- reg_genfifo |= GQSPI_GEN_FIFO_TX ;
399466 reg_genfifo &= ~(GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_IMM_MASK );
467+ reg_genfifo |= GQSPI_GEN_FIFO_TX ;
400468 reg_genfifo |= GQSPI_GEN_FIFO_IMM (* cmdData ); /* IMM is data */
401469
402470 /* Submit general FIFO operation */
403471 ret = qspi_gen_fifo_write (reg_genfifo );
404472 if (ret != GQSPI_CODE_SUCCESS ) {
405- wolfBoot_printf ("on line %d: error %d\n" , __LINE__ , ret );
473+ wolfBoot_printf ("zynq.c:%d ( error %d) \n" , __LINE__ , ret );
406474 break ;
407475 }
408476
@@ -411,39 +479,28 @@ static int qspi_transfer(QspiDev_t* pDev,
411479 cmdData ++ ;
412480 }
413481
414- /* Set desired data mode and stripe */
482+ /* Set desired data mode */
415483 reg_genfifo |= (mode & GQSPI_GEN_FIFO_MODE_MASK );
416- reg_genfifo |= (pDev -> stripe & GQSPI_GEN_FIFO_STRIPE );
417484
418485 /* TX Data */
419486 while (ret == GQSPI_CODE_SUCCESS && txData && txSz > 0 ) {
420- xferSz = txSz ;
421-
422487 /* Enable TX */
423488 reg_genfifo &= ~(GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_IMM_MASK |
424489 GQSPI_GEN_FIFO_EXP_MASK );
425490 reg_genfifo |= (GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_DATA_XFER );
426-
427- if (xferSz > GQSPI_GEN_FIFO_IMM_MASK ) {
428- /* Use exponent mode */
429- xferSz = 256 ; /* 2 ^ 8 = 256 */
430- reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK ;
431- reg_genfifo |= GQSPI_GEN_FIFO_IMM (8 ); /* IMM is exponent */
432- }
433- else {
434- reg_genfifo |= GQSPI_GEN_FIFO_IMM (xferSz ); /* IMM is length */
435- }
491+ reg_genfifo |= (pDev -> stripe & GQSPI_GEN_FIFO_STRIPE );
492+ xferSz = qspi_calc_exp (txSz , & reg_genfifo );
436493
437494 /* Submit general FIFO operation */
438495 ret = qspi_gen_fifo_write (reg_genfifo );
439496 if (ret != GQSPI_CODE_SUCCESS ) {
440- wolfBoot_printf ("on line %d: error %d\n" , __LINE__ , ret );
497+ wolfBoot_printf ("zynq.c:%d ( error %d) \n" , __LINE__ , ret );
441498 }
442499
443500 /* Fill FIFO */
444501 ret = gspi_fifo_tx (txData , xferSz );
445502 if (ret != GQSPI_CODE_SUCCESS ) {
446- wolfBoot_printf ("on line %d: error %d\n" , __LINE__ , ret );
503+ wolfBoot_printf ("zynq.c:%d ( error %d) \n" , __LINE__ , ret );
447504 break ;
448505 }
449506
@@ -454,60 +511,77 @@ static int qspi_transfer(QspiDev_t* pDev,
454511
455512 /* Dummy operations */
456513 if (ret == GQSPI_CODE_SUCCESS && dummySz ) {
457- /* Send dummy clocks (Disable TX & RX) */
514+ /* Send dummy clocks (Disable TX & RX), do not set stripe */
458515 reg_genfifo &= ~(GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_RX |
459- GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK );
516+ GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK |
517+ GQSPI_GEN_FIFO_STRIPE );
518+ reg_genfifo |= GQSPI_GEN_FIFO_DATA_XFER ;
460519 /* IMM is number of dummy clock cycles */
461520 reg_genfifo |= GQSPI_GEN_FIFO_IMM (dummySz );
462521 ret = qspi_gen_fifo_write (reg_genfifo ); /* Submit FIFO Dummy Op */
463-
464- if (rxSz > 0 ) {
465- /* Convert dummy bits to bytes */
466- dummySz = (dummySz + 7 ) / 8 ;
467- /* Adjust rxSz for dummy bytes */
468- rxSz += dummySz ;
469- /* round up by FIFO Word Size */
470- rxSz = (((rxSz + GQSPI_FIFO_WORD_SZ - 1 ) / GQSPI_FIFO_WORD_SZ ) *
471- GQSPI_FIFO_WORD_SZ );
472- }
473522 }
474523
475524 /* RX Data */
476525 while (ret == GQSPI_CODE_SUCCESS && rxData && rxSz > 0 ) {
477- xferSz = rxSz ;
478-
479526 /* Enable RX */
480527 reg_genfifo &= ~(GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_IMM_MASK |
481528 GQSPI_GEN_FIFO_EXP_MASK );
482529 reg_genfifo |= (GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_DATA_XFER );
530+ reg_genfifo |= (pDev -> stripe & GQSPI_GEN_FIFO_STRIPE );
483531
484- if (xferSz > GQSPI_GEN_FIFO_IMM_MASK ) {
485- /* Use exponent mode */
486- xferSz = 256 ; /* 2 ^ 8 = 256 */
487- reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK ;
488- reg_genfifo |= GQSPI_GEN_FIFO_IMM (8 ); /* IMM is exponent */
489- }
490- else {
491- reg_genfifo |= GQSPI_GEN_FIFO_IMM (xferSz ); /* IMM is length */
532+ xferSz = rxSz ;
533+ #ifdef GQSPI_DMA
534+ /* if xferSz or rxData is not QQSPI_DMA_ALIGN aligned use tmp */
535+ dmarxptr = rxData ;
536+ if ((rxSz & (QQSPI_DMA_ALIGN - 1 )) ||
537+ (((size_t )rxData ) & (QQSPI_DMA_ALIGN - 1 ))) {
538+ dmarxptr = (uint8_t * )dmatmp ;
539+ /* round up */
540+ xferSz = ((xferSz + (QQSPI_DMA_ALIGN - 1 )) & ~(QQSPI_DMA_ALIGN - 1 ));
541+ if (xferSz > (uint32_t )sizeof (dmatmp )) {
542+ xferSz = (uint32_t )sizeof (dmatmp );
543+ }
492544 }
493545
546+ GQSPIDMA_DST = (unsigned long )dmarxptr ;
547+ GQSPIDMA_SIZE = xferSz ;
548+ GQSPIDMA_IER = GQSPIDMA_ISR_ALL_MASK ;
549+ flush_dcache_range ((unsigned long )dmarxptr ,
550+ (unsigned long )dmarxptr + xferSz );
551+ #endif
552+ xferSz = qspi_calc_exp (xferSz , & reg_genfifo );
553+
494554 /* Submit general FIFO operation */
495555 ret = qspi_gen_fifo_write (reg_genfifo );
496556 if (ret != GQSPI_CODE_SUCCESS ) {
497- wolfBoot_printf ("on line %d: error %d\n" , __LINE__ , ret );
557+ wolfBoot_printf ("zynq.c:%d ( error %d) \n" , __LINE__ , ret );
498558 break ;
499559 }
500560
561+ #ifndef GQSPI_DMA
501562 /* Read FIFO */
502- ret = gspi_fifo_rx (rxData , xferSz - dummySz , dummySz );
563+ ret = gspi_fifo_rx (rxData , xferSz );
503564 if (ret != GQSPI_CODE_SUCCESS ) {
504- wolfBoot_printf ("on line %d: error %d\n" , __LINE__ , ret );
565+ wolfBoot_printf ("zynq.c:%d ( error %d) \n" , __LINE__ , ret );
505566 }
567+ #else
568+ /* Wait for DMA done */
569+ if (qspi_dmaisr_wait (GQSPIDMA_ISR_DONE , 0 )) {
570+ return GQSPI_CODE_TIMEOUT ;
571+ }
572+ GQSPIDMA_ISR = GQSPIDMA_ISR_DONE ;
573+ /* adjust xfer sz */
574+ if (xferSz > rxSz )
575+ xferSz = rxSz ;
576+ /* copy result if not aligned */
577+ if (dmarxptr != rxData ) {
578+ memcpy (rxData , dmarxptr , xferSz );
579+ }
580+ #endif
506581
507582 /* offset size and buffer */
508583 rxSz -= xferSz ;
509- rxData += (xferSz - dummySz );
510- dummySz = 0 ; /* only first RX */
584+ rxData += xferSz ;
511585 }
512586
513587 qspi_cs (pDev , 0 ); /* Deselect Slave */
@@ -524,7 +598,7 @@ static int qspi_flash_read_id(QspiDev_t* dev, uint8_t* id, uint32_t idSz)
524598 uint8_t status = 0 ;
525599
526600 memset (cmd , 0 , sizeof (cmd ));
527- cmd [0 ] = MULTI_IO_READ_ID_CMD ;
601+ cmd [0 ] = READ_ID_CMD ;
528602 ret = qspi_transfer (& mDev , cmd , 1 , NULL , 0 , cmd , sizeof (cmd ), 0 ,
529603 GQSPI_GEN_FIFO_MODE_SPI );
530604
@@ -775,11 +849,11 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq)
775849 /* Clear and disable interrupts */
776850 reg_isr = GQSPI_ISR ;
777851 GQSPI_ISR |= GQSPI_ISR_WR_TO_CLR_MASK ; /* Clear poll timeout counter interrupt */
778- reg_cfg = QSPIDMA_DST_I_STS ;
779- QSPIDMA_DST_I_STS = reg_cfg ; /* clear all active interrupts */
780- QSPIDMA_DST_STS |= QSPIDMA_DST_STS_WTC ; /* mark outstanding DMA's done */
852+ reg_cfg = GQSPIDMA_ISR ;
853+ GQSPIDMA_ISR = reg_cfg ; /* clear all active interrupts */
854+ GQSPIDMA_STS |= GQSPIDMA_STS_WTC ; /* mark outstanding DMA's done */
781855 GQSPI_IDR = GQSPI_IXR_ALL_MASK ; /* disable interrupts */
782- QSPIDMA_DST_I_STS = QSPIDMA_DST_I_STS_ALL_MASK ; /* disable interrupts */
856+ GQSPIDMA_ISR = GQSPIDMA_ISR_ALL_MASK ; /* disable interrupts */
783857 /* Reset FIFOs */
784858 if (GQSPI_ISR & GQSPI_IXR_RX_FIFO_EMPTY ) {
785859 GQSPI_FIFO_CTRL |= (GQSPI_FIFO_CTRL_RST_TX_FIFO | GQSPI_FIFO_CTRL_RST_RX_FIFO );
@@ -791,10 +865,14 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq)
791865 GQSPI_EN = 0 ; /* Disable device */
792866
793867 /* Initialize clock divisor, write protect hold and start mode */
868+ #ifdef GQSPI_DMA
869+ reg_cfg = GQSPI_CFG_MODE_EN_DMA ; /* Use DMA Transfer Mode */
870+ #else
794871 reg_cfg = GQSPI_CFG_MODE_EN_IO ; /* Use I/O Transfer Mode */
872+ reg_cfg |= GQSPI_CFG_START_GEN_FIFO ; /* Auto start GFIFO cmd execution */
873+ #endif
795874 reg_cfg |= GQSPI_CFG_BAUD_RATE_DIV (GQSPI_CLK_DIV ); /* Clock Divider */
796875 reg_cfg |= GQSPI_CFG_WP_HOLD ; /* Use WP Hold */
797- reg_cfg |= GQSPI_CFG_START_GEN_FIFO ; /* Start GFIFO command execution */
798876 reg_cfg &= ~(GQSPI_CFG_CLK_POL | GQSPI_CFG_CLK_PH ); /* Use POL=0,PH=0 */
799877 GQSPI_CFG = reg_cfg ;
800878
@@ -803,30 +881,31 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq)
803881 * the clock and data tap delays bypassed. */
804882 IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX ;
805883 GQSPI_LPBK_DLY_ADJ = 0 ;
806- QSPI_DATA_DLY_ADJ = 0 ;
884+ GQSPI_DATA_DLY_ADJ = 0 ;
807885#elif GQSPI_CLK_DIV >= 1 /* 300/4=75MHz */
808886 /* At 100 MHz, the Quad-SPI controller should be in clock loopback mode
809887 * with the clock tap delay bypassed, but the data tap delay enabled. */
810888 IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX ;
811889 GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK ;
812- QSPI_DATA_DLY_ADJ = QSPI_DATA_DLY_ADJ_USE_DATA_DLY | QSPI_DATA_DLY_ADJ_DATA_DLY_ADJ (2 );
890+ GQSPI_DATA_DLY_ADJ = (GQSPI_DATA_DLY_ADJ_USE_DATA_DLY |
891+ GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ (2 ));
813892#else
814893 /* At 150 MHz, only the generic controller can be used.
815894 * The generic controller should be in clock loopback mode and the clock
816895 * tap delay enabled, but the data tap delay disabled. */
817896 IOU_TAPDLY_BYPASS = 0 ;
818897 GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK ;
819- QSPI_DATA_DLY_ADJ = 0 ;
898+ GQSPI_DATA_DLY_ADJ = 0 ;
820899#endif
821900
822901 /* Initialize hardware parameters for Threshold and Interrupts */
823902 GQSPI_TX_THRESH = 1 ;
824903 GQSPI_RX_THRESH = 1 ;
825- GQSPI_GF_THRESH = 16 ;
904+ GQSPI_GF_THRESH = 31 ;
826905
827906 /* Reset DMA */
828- QSPIDMA_DST_CTRL = QSPIDMA_DST_CTRL_DEF ;
829- QSPIDMA_DST_CTRL2 = QSPIDMA_DST_CTRL2_DEF ;
907+ GQSPIDMA_CTRL = GQSPIDMA_CTRL_DEF ;
908+ GQSPIDMA_CTRL2 = GQSPIDMA_CTRL2_DEF ;
830909
831910 /* Interrupts unmask and enable */
832911 GQSPI_IMR = GQSPI_IXR_ALL_MASK ;
0 commit comments