mirror of https://github.com/wolfSSL/wolfBoot.git
Added QSPI DMA support.
parent
acb9d832eb
commit
7205820afa
207
hal/zynq.c
207
hal/zynq.c
|
@ -80,6 +80,9 @@ static int qspi_wait_we(QspiDev_t* dev);
|
|||
static int test_ext_flash(QspiDev_t* dev);
|
||||
#endif
|
||||
|
||||
/* asm function */
|
||||
extern void flush_dcache_range(unsigned long start, unsigned long stop);
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
void uart_init(void)
|
||||
{
|
||||
|
@ -293,9 +296,23 @@ static inline int qspi_isr_wait(uint32_t wait_mask, uint32_t wait_val)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#ifdef GQSPI_DMA
|
||||
static inline int qspi_dmaisr_wait(uint32_t wait_mask, uint32_t wait_val)
|
||||
{
|
||||
uint32_t timeout = 0;
|
||||
while ((GQSPIDMA_ISR & wait_mask) == wait_val &&
|
||||
++timeout < GQSPI_TIMEOUT_TRIES);
|
||||
if (timeout == GQSPI_TIMEOUT_TRIES) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int qspi_gen_fifo_write(uint32_t reg_genfifo)
|
||||
{
|
||||
uint32_t reg_cfg;
|
||||
|
||||
/* wait until the gen FIFO is not full to write */
|
||||
if (qspi_isr_wait(GQSPI_IXR_GEN_FIFO_NOT_FULL, 0)) {
|
||||
return GQSPI_CODE_TIMEOUT;
|
||||
|
@ -317,6 +334,17 @@ static int gspi_fifo_tx(const uint8_t* data, uint32_t sz)
|
|||
return GQSPI_CODE_TIMEOUT;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_ZYNQ) && DEBUG_ZYNQ >= 3
|
||||
uint32_t txSz = sz;
|
||||
if (txSz > GQSPI_FIFO_WORD_SZ)
|
||||
txSz = GQSPI_FIFO_WORD_SZ;
|
||||
memcpy(&tmp32, data, txSz);
|
||||
GQSPI_TXD = tmp32;
|
||||
wolfBoot_printf("TXD=%08x\n", tmp32);
|
||||
|
||||
sz -= txSz;
|
||||
data += txSz;
|
||||
#else
|
||||
/* Write data */
|
||||
if (sz >= 4) {
|
||||
GQSPI_TXD = *(uint32_t*)data;
|
||||
|
@ -329,23 +357,32 @@ static int gspi_fifo_tx(const uint8_t* data, uint32_t sz)
|
|||
GQSPI_TXD = tmp32;
|
||||
sz = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return GQSPI_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int gspi_fifo_rx(uint8_t* data, uint32_t sz, uint32_t discardSz)
|
||||
#ifndef GQSPI_DMA
|
||||
static int gspi_fifo_rx(uint8_t* data, uint32_t sz)
|
||||
{
|
||||
uint32_t tmp32;
|
||||
|
||||
while (sz > 0) {
|
||||
/* Wait for RX FIFO not empty */
|
||||
if (qspi_isr_wait(GQSPI_IXR_RX_FIFO_NOT_EMPTY, 0)) {
|
||||
return GQSPI_CODE_TIMEOUT;
|
||||
}
|
||||
if (discardSz >= GQSPI_FIFO_WORD_SZ) {
|
||||
tmp32 = GQSPI_RXD; /* discard */
|
||||
discardSz -= GQSPI_FIFO_WORD_SZ;
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(DEBUG_ZYNQ) && DEBUG_ZYNQ >= 3
|
||||
uint32_t rxSz = sz;
|
||||
if (rxSz > GQSPI_FIFO_WORD_SZ)
|
||||
rxSz = GQSPI_FIFO_WORD_SZ;
|
||||
tmp32 = GQSPI_RXD;
|
||||
memcpy(data, &tmp32, rxSz);
|
||||
wolfBoot_printf("RXD=%08x\n", tmp32);
|
||||
sz -= rxSz;
|
||||
data += rxSz;
|
||||
#else
|
||||
if (sz >= 4) {
|
||||
*(uint32_t*)data = GQSPI_RXD;
|
||||
data += 4;
|
||||
|
@ -356,9 +393,11 @@ static int gspi_fifo_rx(uint8_t* data, uint32_t sz, uint32_t discardSz)
|
|||
memcpy(data, &tmp32, sz);
|
||||
sz = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return GQSPI_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int qspi_cs(QspiDev_t* pDev, int csAssert)
|
||||
{
|
||||
|
@ -374,6 +413,33 @@ static int qspi_cs(QspiDev_t* pDev, int csAssert)
|
|||
return qspi_gen_fifo_write(reg_genfifo);
|
||||
}
|
||||
|
||||
static uint32_t qspi_calc_exp(uint32_t xferSz, uint32_t* reg_genfifo)
|
||||
{
|
||||
uint32_t expval = 8;
|
||||
*reg_genfifo &= ~(GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK);
|
||||
if (xferSz > GQSPI_GEN_FIFO_IMM_MASK) {
|
||||
/* Use exponent mode */
|
||||
while (1) {
|
||||
if (xferSz & (1 << expval)) {
|
||||
*reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK;
|
||||
*reg_genfifo |= GQSPI_GEN_FIFO_IMM(expval); /* IMM is exponent */
|
||||
xferSz = (1 << expval);
|
||||
break;
|
||||
}
|
||||
expval++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use length mode */
|
||||
*reg_genfifo |= GQSPI_GEN_FIFO_IMM(xferSz); /* IMM is length */
|
||||
}
|
||||
return xferSz;
|
||||
}
|
||||
|
||||
#ifdef GQSPI_DMA
|
||||
static uint8_t XALIGNED(QQSPI_DMA_ALIGN) dmatmp[GQSPI_DMA_TMPSZ];
|
||||
#endif
|
||||
|
||||
static int qspi_transfer(QspiDev_t* pDev,
|
||||
const uint8_t* cmdData, uint32_t cmdSz,
|
||||
const uint8_t* txData, uint32_t txSz,
|
||||
|
@ -382,7 +448,9 @@ static int qspi_transfer(QspiDev_t* pDev,
|
|||
{
|
||||
int ret = GQSPI_CODE_SUCCESS;
|
||||
uint32_t reg_genfifo, xferSz;
|
||||
|
||||
#ifdef GQSPI_DMA
|
||||
uint8_t* dmarxptr = NULL;
|
||||
#endif
|
||||
GQSPI_EN = 1; /* Enable device */
|
||||
qspi_cs(pDev, 1); /* Select slave */
|
||||
|
||||
|
@ -395,14 +463,14 @@ static int qspi_transfer(QspiDev_t* pDev,
|
|||
xferSz = cmdSz;
|
||||
while (ret == GQSPI_CODE_SUCCESS && cmdData && xferSz > 0) {
|
||||
/* Enable TX and send command inline */
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_TX;
|
||||
reg_genfifo &= ~(GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_IMM_MASK);
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_TX;
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_IMM(*cmdData); /* IMM is data */
|
||||
|
||||
/* Submit general FIFO operation */
|
||||
ret = qspi_gen_fifo_write(reg_genfifo);
|
||||
if (ret != GQSPI_CODE_SUCCESS) {
|
||||
wolfBoot_printf("on line %d: error %d\n", __LINE__, ret);
|
||||
wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -411,39 +479,28 @@ static int qspi_transfer(QspiDev_t* pDev,
|
|||
cmdData++;
|
||||
}
|
||||
|
||||
/* Set desired data mode and stripe */
|
||||
/* Set desired data mode */
|
||||
reg_genfifo |= (mode & GQSPI_GEN_FIFO_MODE_MASK);
|
||||
reg_genfifo |= (pDev->stripe & GQSPI_GEN_FIFO_STRIPE);
|
||||
|
||||
/* TX Data */
|
||||
while (ret == GQSPI_CODE_SUCCESS && txData && txSz > 0) {
|
||||
xferSz = txSz;
|
||||
|
||||
/* Enable TX */
|
||||
reg_genfifo &= ~(GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_IMM_MASK |
|
||||
GQSPI_GEN_FIFO_EXP_MASK);
|
||||
reg_genfifo |= (GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_DATA_XFER);
|
||||
|
||||
if (xferSz > GQSPI_GEN_FIFO_IMM_MASK) {
|
||||
/* Use exponent mode */
|
||||
xferSz = 256; /* 2 ^ 8 = 256 */
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK;
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_IMM(8); /* IMM is exponent */
|
||||
}
|
||||
else {
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_IMM(xferSz); /* IMM is length */
|
||||
}
|
||||
reg_genfifo |= (pDev->stripe & GQSPI_GEN_FIFO_STRIPE);
|
||||
xferSz = qspi_calc_exp(txSz, ®_genfifo);
|
||||
|
||||
/* Submit general FIFO operation */
|
||||
ret = qspi_gen_fifo_write(reg_genfifo);
|
||||
if (ret != GQSPI_CODE_SUCCESS) {
|
||||
wolfBoot_printf("on line %d: error %d\n", __LINE__, ret);
|
||||
wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret);
|
||||
}
|
||||
|
||||
/* Fill FIFO */
|
||||
ret = gspi_fifo_tx(txData, xferSz);
|
||||
if (ret != GQSPI_CODE_SUCCESS) {
|
||||
wolfBoot_printf("on line %d: error %d\n", __LINE__, ret);
|
||||
wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -454,60 +511,77 @@ static int qspi_transfer(QspiDev_t* pDev,
|
|||
|
||||
/* Dummy operations */
|
||||
if (ret == GQSPI_CODE_SUCCESS && dummySz) {
|
||||
/* Send dummy clocks (Disable TX & RX) */
|
||||
/* Send dummy clocks (Disable TX & RX), do not set stripe */
|
||||
reg_genfifo &= ~(GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_RX |
|
||||
GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK);
|
||||
GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK |
|
||||
GQSPI_GEN_FIFO_STRIPE);
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_DATA_XFER;
|
||||
/* IMM is number of dummy clock cycles */
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_IMM(dummySz);
|
||||
ret = qspi_gen_fifo_write(reg_genfifo); /* Submit FIFO Dummy Op */
|
||||
|
||||
if (rxSz > 0) {
|
||||
/* Convert dummy bits to bytes */
|
||||
dummySz = (dummySz + 7) / 8;
|
||||
/* Adjust rxSz for dummy bytes */
|
||||
rxSz += dummySz;
|
||||
/* round up by FIFO Word Size */
|
||||
rxSz = (((rxSz + GQSPI_FIFO_WORD_SZ - 1) / GQSPI_FIFO_WORD_SZ) *
|
||||
GQSPI_FIFO_WORD_SZ);
|
||||
}
|
||||
}
|
||||
|
||||
/* RX Data */
|
||||
while (ret == GQSPI_CODE_SUCCESS && rxData && rxSz > 0) {
|
||||
xferSz = rxSz;
|
||||
|
||||
/* Enable RX */
|
||||
reg_genfifo &= ~(GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_IMM_MASK |
|
||||
GQSPI_GEN_FIFO_EXP_MASK);
|
||||
reg_genfifo |= (GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_DATA_XFER);
|
||||
reg_genfifo |= (pDev->stripe & GQSPI_GEN_FIFO_STRIPE);
|
||||
|
||||
if (xferSz > GQSPI_GEN_FIFO_IMM_MASK) {
|
||||
/* Use exponent mode */
|
||||
xferSz = 256; /* 2 ^ 8 = 256 */
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK;
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_IMM(8); /* IMM is exponent */
|
||||
}
|
||||
else {
|
||||
reg_genfifo |= GQSPI_GEN_FIFO_IMM(xferSz); /* IMM is length */
|
||||
xferSz = rxSz;
|
||||
#ifdef GQSPI_DMA
|
||||
/* if xferSz or rxData is not QQSPI_DMA_ALIGN aligned use tmp */
|
||||
dmarxptr = rxData;
|
||||
if ((rxSz & (QQSPI_DMA_ALIGN-1)) ||
|
||||
(((size_t)rxData) & (QQSPI_DMA_ALIGN-1))) {
|
||||
dmarxptr = (uint8_t*)dmatmp;
|
||||
/* round up */
|
||||
xferSz = ((xferSz + (QQSPI_DMA_ALIGN-1)) & ~(QQSPI_DMA_ALIGN-1));
|
||||
if (xferSz > (uint32_t)sizeof(dmatmp)) {
|
||||
xferSz = (uint32_t)sizeof(dmatmp);
|
||||
}
|
||||
}
|
||||
|
||||
GQSPIDMA_DST = (unsigned long)dmarxptr;
|
||||
GQSPIDMA_SIZE = xferSz;
|
||||
GQSPIDMA_IER = GQSPIDMA_ISR_ALL_MASK;
|
||||
flush_dcache_range((unsigned long)dmarxptr,
|
||||
(unsigned long)dmarxptr + xferSz);
|
||||
#endif
|
||||
xferSz = qspi_calc_exp(xferSz, ®_genfifo);
|
||||
|
||||
/* Submit general FIFO operation */
|
||||
ret = qspi_gen_fifo_write(reg_genfifo);
|
||||
if (ret != GQSPI_CODE_SUCCESS) {
|
||||
wolfBoot_printf("on line %d: error %d\n", __LINE__, ret);
|
||||
wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef GQSPI_DMA
|
||||
/* Read FIFO */
|
||||
ret = gspi_fifo_rx(rxData, xferSz-dummySz, dummySz);
|
||||
ret = gspi_fifo_rx(rxData, xferSz);
|
||||
if (ret != GQSPI_CODE_SUCCESS) {
|
||||
wolfBoot_printf("on line %d: error %d\n", __LINE__, ret);
|
||||
wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret);
|
||||
}
|
||||
#else
|
||||
/* Wait for DMA done */
|
||||
if (qspi_dmaisr_wait(GQSPIDMA_ISR_DONE, 0)) {
|
||||
return GQSPI_CODE_TIMEOUT;
|
||||
}
|
||||
GQSPIDMA_ISR = GQSPIDMA_ISR_DONE;
|
||||
/* adjust xfer sz */
|
||||
if (xferSz > rxSz)
|
||||
xferSz = rxSz;
|
||||
/* copy result if not aligned */
|
||||
if (dmarxptr != rxData) {
|
||||
memcpy(rxData, dmarxptr, xferSz);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* offset size and buffer */
|
||||
rxSz -= xferSz;
|
||||
rxData += (xferSz - dummySz);
|
||||
dummySz = 0; /* only first RX */
|
||||
rxData += xferSz;
|
||||
}
|
||||
|
||||
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)
|
|||
uint8_t status = 0;
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
cmd[0] = MULTI_IO_READ_ID_CMD;
|
||||
cmd[0] = READ_ID_CMD;
|
||||
ret = qspi_transfer(&mDev, cmd, 1, NULL, 0, cmd, sizeof(cmd), 0,
|
||||
GQSPI_GEN_FIFO_MODE_SPI);
|
||||
|
||||
|
@ -775,11 +849,11 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq)
|
|||
/* Clear and disable interrupts */
|
||||
reg_isr = GQSPI_ISR;
|
||||
GQSPI_ISR |= GQSPI_ISR_WR_TO_CLR_MASK; /* Clear poll timeout counter interrupt */
|
||||
reg_cfg = QSPIDMA_DST_I_STS;
|
||||
QSPIDMA_DST_I_STS = reg_cfg; /* clear all active interrupts */
|
||||
QSPIDMA_DST_STS |= QSPIDMA_DST_STS_WTC; /* mark outstanding DMA's done */
|
||||
reg_cfg = GQSPIDMA_ISR;
|
||||
GQSPIDMA_ISR = reg_cfg; /* clear all active interrupts */
|
||||
GQSPIDMA_STS |= GQSPIDMA_STS_WTC; /* mark outstanding DMA's done */
|
||||
GQSPI_IDR = GQSPI_IXR_ALL_MASK; /* disable interrupts */
|
||||
QSPIDMA_DST_I_STS = QSPIDMA_DST_I_STS_ALL_MASK; /* disable interrupts */
|
||||
GQSPIDMA_ISR = GQSPIDMA_ISR_ALL_MASK; /* disable interrupts */
|
||||
/* Reset FIFOs */
|
||||
if (GQSPI_ISR & GQSPI_IXR_RX_FIFO_EMPTY) {
|
||||
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)
|
|||
GQSPI_EN = 0; /* Disable device */
|
||||
|
||||
/* Initialize clock divisor, write protect hold and start mode */
|
||||
#ifdef GQSPI_DMA
|
||||
reg_cfg = GQSPI_CFG_MODE_EN_DMA; /* Use DMA Transfer Mode */
|
||||
#else
|
||||
reg_cfg = GQSPI_CFG_MODE_EN_IO; /* Use I/O Transfer Mode */
|
||||
reg_cfg |= GQSPI_CFG_START_GEN_FIFO; /* Auto start GFIFO cmd execution */
|
||||
#endif
|
||||
reg_cfg |= GQSPI_CFG_BAUD_RATE_DIV(GQSPI_CLK_DIV); /* Clock Divider */
|
||||
reg_cfg |= GQSPI_CFG_WP_HOLD; /* Use WP Hold */
|
||||
reg_cfg |= GQSPI_CFG_START_GEN_FIFO; /* Start GFIFO command execution */
|
||||
reg_cfg &= ~(GQSPI_CFG_CLK_POL | GQSPI_CFG_CLK_PH); /* Use POL=0,PH=0 */
|
||||
GQSPI_CFG = reg_cfg;
|
||||
|
||||
|
@ -803,30 +881,31 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq)
|
|||
* the clock and data tap delays bypassed. */
|
||||
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
|
||||
GQSPI_LPBK_DLY_ADJ = 0;
|
||||
QSPI_DATA_DLY_ADJ = 0;
|
||||
GQSPI_DATA_DLY_ADJ = 0;
|
||||
#elif GQSPI_CLK_DIV >= 1 /* 300/4=75MHz */
|
||||
/* At 100 MHz, the Quad-SPI controller should be in clock loopback mode
|
||||
* with the clock tap delay bypassed, but the data tap delay enabled. */
|
||||
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
|
||||
GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK;
|
||||
QSPI_DATA_DLY_ADJ = QSPI_DATA_DLY_ADJ_USE_DATA_DLY | QSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(2);
|
||||
GQSPI_DATA_DLY_ADJ = (GQSPI_DATA_DLY_ADJ_USE_DATA_DLY |
|
||||
GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(2));
|
||||
#else
|
||||
/* At 150 MHz, only the generic controller can be used.
|
||||
* The generic controller should be in clock loopback mode and the clock
|
||||
* tap delay enabled, but the data tap delay disabled. */
|
||||
IOU_TAPDLY_BYPASS = 0;
|
||||
GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK;
|
||||
QSPI_DATA_DLY_ADJ = 0;
|
||||
GQSPI_DATA_DLY_ADJ = 0;
|
||||
#endif
|
||||
|
||||
/* Initialize hardware parameters for Threshold and Interrupts */
|
||||
GQSPI_TX_THRESH = 1;
|
||||
GQSPI_RX_THRESH = 1;
|
||||
GQSPI_GF_THRESH = 16;
|
||||
GQSPI_GF_THRESH = 31;
|
||||
|
||||
/* Reset DMA */
|
||||
QSPIDMA_DST_CTRL = QSPIDMA_DST_CTRL_DEF;
|
||||
QSPIDMA_DST_CTRL2 = QSPIDMA_DST_CTRL2_DEF;
|
||||
GQSPIDMA_CTRL = GQSPIDMA_CTRL_DEF;
|
||||
GQSPIDMA_CTRL2 = GQSPIDMA_CTRL2_DEF;
|
||||
|
||||
/* Interrupts unmask and enable */
|
||||
GQSPI_IMR = GQSPI_IXR_ALL_MASK;
|
||||
|
|
48
hal/zynq.h
48
hal/zynq.h
|
@ -85,18 +85,25 @@
|
|||
#define GQSPI_POLL_CFG (*((volatile uint32_t*)(QSPI_BASE + 0x154))) /* poll configuration register */
|
||||
#define GQSPI_P_TIMEOUT (*((volatile uint32_t*)(QSPI_BASE + 0x158))) /* poll timeout register. */
|
||||
#define GQSPI_XFER_STS (*((volatile uint32_t*)(QSPI_BASE + 0x15C))) /* transfer status register. */
|
||||
#define QSPI_DATA_DLY_ADJ (*((volatile uint32_t*)(QSPI_BASE + 0x1F8))) /* adjusting the internal receive data delay for read data capturing */
|
||||
#define GQSPI_DATA_DLY_ADJ (*((volatile uint32_t*)(QSPI_BASE + 0x1F8))) /* adjusting the internal receive data delay for read data capturing */
|
||||
#define GQSPI_MOD_ID (*((volatile uint32_t*)(QSPI_BASE + 0x1FC)))
|
||||
#define QSPIDMA_DST_STS (*((volatile uint32_t*)(QSPI_BASE + 0x808)))
|
||||
#define QSPIDMA_DST_CTRL (*((volatile uint32_t*)(QSPI_BASE + 0x80C)))
|
||||
#define QSPIDMA_DST_I_STS (*((volatile uint32_t*)(QSPI_BASE + 0x814)))
|
||||
#define QSPIDMA_DST_CTRL2 (*((volatile uint32_t*)(QSPI_BASE + 0x824)))
|
||||
/* DMA Registers */
|
||||
#define GQSPIDMA_DST (*((volatile uint32_t*)(QSPI_BASE + 0x800))) /* Destination memory address for DMA stream -> memory data transfer */
|
||||
#define GQSPIDMA_DST_MSB (*((volatile uint32_t*)(QSPI_BASE + 0x828))) /* Destination memory address (MSBs) for DMA stream -> memory data transfer */
|
||||
#define GQSPIDMA_SIZE (*((volatile uint32_t*)(QSPI_BASE + 0x804))) /* DMA transfer payload for DMA stream -> memory data transfer */
|
||||
#define GQSPIDMA_STS (*((volatile uint32_t*)(QSPI_BASE + 0x808))) /* General DST DMA status */
|
||||
#define GQSPIDMA_CTRL (*((volatile uint32_t*)(QSPI_BASE + 0x80C))) /* General DST DMA control */
|
||||
#define GQSPIDMA_ISR (*((volatile uint32_t*)(QSPI_BASE + 0x814))) /* DST DMA interrupt status register */
|
||||
#define GQSPIDMA_IER (*((volatile uint32_t*)(QSPI_BASE + 0x818))) /* DST DMA interrupt enable */
|
||||
#define GQSPIDMA_IDR (*((volatile uint32_t*)(QSPI_BASE + 0x81C))) /* DST DMA interrupt disable */
|
||||
#define GQSPIDMA_IMR (*((volatile uint32_t*)(QSPI_BASE + 0x820))) /* DST DMA interrupt mask */
|
||||
#define GQSPIDMA_CTRL2 (*((volatile uint32_t*)(QSPI_BASE + 0x824))) /* General DST DMA control register 2 */
|
||||
|
||||
#define GQSPI_LPBK_DLY_ADJ_USE_LPBK (1UL << 5)
|
||||
#define GQSPI_LPBK_DLY_ADJ_DIV0(x) (((x) & 0x7) << 0)
|
||||
#define GQSPI_LPBK_DLY_ADJ_DLY1(x) (((x) & 0x3) << 3)
|
||||
#define QSPI_DATA_DLY_ADJ_USE_DATA_DLY (1UL << 31)
|
||||
#define QSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(x) (((x) & 0x7) << 28)
|
||||
#define GQSPI_DATA_DLY_ADJ_USE_DATA_DLY (1UL << 31)
|
||||
#define GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(x) (((x) & 0x7) << 28)
|
||||
|
||||
/* GQSPI Registers */
|
||||
/* GQSPI_CFG: Configuration registers */
|
||||
|
@ -166,15 +173,16 @@
|
|||
#define GQSPI_FIFO_CTRL_RST_TX_FIFO (1UL << 1)
|
||||
#define GQSPI_FIFO_CTRL_RST_RX_FIFO (1UL << 2)
|
||||
|
||||
/* QSPIDMA_DST_CTRL */
|
||||
#define QSPIDMA_DST_CTRL_DEF 0x403FFA00UL
|
||||
#define QSPIDMA_DST_CTRL2_DEF 0x081BFFF8UL
|
||||
/* GQSPIDMA_CTRL */
|
||||
#define GQSPIDMA_CTRL_DEF 0x403FFA00UL
|
||||
#define GQSPIDMA_CTRL2_DEF 0x081BFFF8UL
|
||||
|
||||
/* QSPIDMA_DST_STS */
|
||||
#define QSPIDMA_DST_STS_WTC 0xE000U
|
||||
/* GQSPIDMA_STS */
|
||||
#define GQSPIDMA_STS_WTC 0xE000U
|
||||
|
||||
/* QSPIDMA_DST_I_STS */
|
||||
#define QSPIDMA_DST_I_STS_ALL_MASK 0xFEU
|
||||
/* GQSPIDMA_ISR */
|
||||
#define GQSPIDMA_ISR_DONE 0x02
|
||||
#define GQSPIDMA_ISR_ALL_MASK 0xFEU
|
||||
|
||||
/* QSPI Configuration (bare-metal only) */
|
||||
#ifndef GQSPI_CLK_DIV
|
||||
|
@ -182,6 +190,16 @@
|
|||
#endif
|
||||
#define GQSPI_CS_ASSERT_CLOCKS 5 /* CS Setup Time (tCSS) - num of clock cycles foes in IMM */
|
||||
#define GQSPI_FIFO_WORD_SZ 4
|
||||
#define QQSPI_DMA_ALIGN 64 /* L1 cache size */
|
||||
#ifndef GQSPI_DMA_TMPSZ
|
||||
/* Use larger of WOLFBOOT_SHA_BLOCK_SIZE or IMAGE_HEADER_SIZE */
|
||||
#if defined(WOLFBOOT_SHA_BLOCK_SIZE) && \
|
||||
WOLFBOOT_SHA_BLOCK_SIZE > IMAGE_HEADER_SIZE
|
||||
#define GQSPI_DMA_TMPSZ WOLFBOOT_SHA_BLOCK_SIZE
|
||||
#else
|
||||
#define GQSPI_DMA_TMPSZ IMAGE_HEADER_SIZE
|
||||
#endif
|
||||
#endif
|
||||
#define GQSPI_TIMEOUT_TRIES 100000
|
||||
#define QSPI_FLASH_READY_TRIES 1000
|
||||
|
||||
|
@ -196,7 +214,7 @@
|
|||
#define GQPI_USE_4BYTE_ADDR 1
|
||||
#endif
|
||||
#ifndef GQSPI_DUMMY_READ
|
||||
#define GQSPI_DUMMY_READ (8*8) /* Number of dummy clock cycles for reads */
|
||||
#define GQSPI_DUMMY_READ (8) /* Number of dummy clock cycles for reads */
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -74,6 +74,22 @@ int wolfBot_get_dts_size(void *dts_addr);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Helpers for memory alignment */
|
||||
#ifndef XALIGNED
|
||||
#if defined(__GNUC__) || defined(__llvm__) || \
|
||||
defined(__IAR_SYSTEMS_ICC__)
|
||||
#define XALIGNED(x) __attribute__ ( (aligned (x)))
|
||||
#elif defined(__KEIL__)
|
||||
#define XALIGNED(x) __align(x)
|
||||
#elif defined(_MSC_VER)
|
||||
/* disable align warning, we want alignment ! */
|
||||
#pragma warning(disable: 4324)
|
||||
#define XALIGNED(x) __declspec (align (x))
|
||||
#else
|
||||
#define XALIGNED(x) /* null expansion */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WOLFBOOT_FLAGS_INVERT
|
||||
#define SECT_FLAG_NEW 0x0F
|
||||
|
|
|
@ -69,7 +69,7 @@ void boot_entry_C(void)
|
|||
|
||||
|
||||
#ifdef MMU
|
||||
int __attribute((weak)) hal_dts_fixup(void* dts_addr)
|
||||
int WEAKFUNCTION hal_dts_fixup(void* dts_addr)
|
||||
{
|
||||
(void)dts_addr;
|
||||
return 0;
|
||||
|
|
|
@ -461,6 +461,34 @@ invalidatecaches_next_level:
|
|||
invalidatecaches_end:
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* void flush_dcache_range(start, end)
|
||||
*
|
||||
* clean & invalidate data cache in the range
|
||||
*
|
||||
* x0: start address
|
||||
* x1: end address
|
||||
*/
|
||||
.global flush_dcache_range
|
||||
flush_dcache_range:
|
||||
mrs x3, ctr_el0
|
||||
lsr x3, x3, #16
|
||||
and x3, x3, #0xf
|
||||
mov x2, #4
|
||||
lsl x2, x2, x3 /* cache line size */
|
||||
|
||||
/* x2 <- minimal cache line size in cache system */
|
||||
sub x3, x2, #1
|
||||
bic x0, x0, x3
|
||||
1: dc civac, x0 /* clean & invalidate data or unified cache */
|
||||
add x0, x0, x2
|
||||
cmp x0, x1
|
||||
b.lo 1b
|
||||
dsb sy
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* Below is the static translation page table required by MMU for Cortex-A53.
|
||||
* The translation table is flat mapped (input address = output address) with
|
||||
|
|
|
@ -101,12 +101,12 @@ void set_law(uint8_t idx, uint32_t addr_h, uint32_t addr_l, uint32_t trgt_id,
|
|||
(void)get32(LAWAR(idx));
|
||||
}
|
||||
|
||||
void __attribute((weak)) hal_early_init(void)
|
||||
void WEAKFUNCTION hal_early_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
#ifdef MMU
|
||||
int __attribute((weak)) hal_dts_fixup(void* dts_addr)
|
||||
int WEAKFUNCTION hal_dts_fixup(void* dts_addr)
|
||||
{
|
||||
(void)dts_addr;
|
||||
return 0;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "wolfboot/wolfboot.h"
|
||||
#include "keystore.h"
|
||||
#include "target.h"
|
||||
#include "image.h"
|
||||
|
||||
#ifdef SECURE_PKCS11
|
||||
#include "wcs/user_settings.h"
|
||||
|
@ -797,7 +798,7 @@ void _exit (int status)
|
|||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
int WEAKFUNCTION _read(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
|
Loading…
Reference in New Issue