Skip to content

Commit

Permalink
Fixes and improvements for NXP QorIQ:
Browse files Browse the repository at this point in the history
* Fix and refactor the L2SRAM support and use it for stage 1 loader stack.
* Fix NXP eSPI driver to support all sizes and properly handle keeping CS active.
  • Loading branch information
dgarske authored and danielinux committed Aug 4, 2023
1 parent 3797238 commit 0f4675f
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 171 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,5 @@ CMakeCache.txt

# Stage 1
stage1/loader_stage1.ld

debug/lauterbach
2 changes: 1 addition & 1 deletion arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -613,5 +613,5 @@ ifeq ($(DEBUG_UART),1)
CFLAGS+=-DDEBUG_UART
endif

CFLAGS+=-DWOLFBOOT_ARCH=$(ARCH)
CFLAGS+=-DWOLFBOOT_ARCH_$(ARCH)
CFLAGS+=-DTARGET_$(TARGET)
185 changes: 93 additions & 92 deletions hal/nxp_p1021.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,30 @@

#include "nxp_ppc.h"

#define ENABLE_ELBC
/* Debugging */
/* #define DEBUG_EXT_FLASH */
/* #define DEBUG_ESPI 1 */

/* Tests */
/* #define TEST_DDR */
/* #define TEST_FLASH */
/* #define TEST_TPM */

#define ENABLE_ELBC /* Flash Controller */
#define ENABLE_BUS_CLK_CALC
#ifndef BUILD_LOADER_STAGE1
#define ENABLE_PCIE
#define ENABLE_CPLD /* Board Configuration and Status Registers (BCSR) */
#define ENABLE_CONF_IO
#define ENABLE_QE /* QUICC Engine */
#define ENABLE_ESPI /* SPI for TPM */
#if defined(WOLFBOOT_TPM) || defined(TEST_TPM)
#define ENABLE_ESPI /* SPI for TPM */
#endif
#define ENABLE_MP /* multi-core support */
#define ENABLE_IRQ
/* #define ENABLE_QE_CRC32 */ /* CRC32 check on QE disabled by default */
#endif

/* Debugging */
/* #define DEBUG_EXT_FLASH */

/* Tests */
/* #define TEST_DDR */
/* #define TEST_FLASH */
/* #define TEST_TPM */

#if defined(ENABLE_DDR) && defined(TEST_DDR)
static int test_ddr(void);
#endif
Expand All @@ -57,6 +60,9 @@ static int test_flash(void);
static int test_tpm(void);
#endif

#ifdef ENABLE_ESPI
#include "spi_drv.h" /* for transfer flags */
#endif

/* P1021 Platform */
/* System input clock */
Expand Down Expand Up @@ -92,17 +98,6 @@ static int test_tpm(void);
#define GUTS_DEVDISR_TB1 0x00001000


/* L2 Cache */
#define L2_BASE (CCSRBAR + 0x20000)
#define L2CTL (volatile uint32_t*)(L2_BASE + 0x000) /* 0xFFE20000 - L2 control register */
#define L2SRBAR0 (volatile uint32_t*)(L2_BASE + 0x100) /* 0xFFE20100 - L2 SRAM base address register */

#define L2CTL_EN (1 << 31) /* L2 enable */
#define L2CTL_INV (1 << 30) /* L2 invalidate */
#define L2CTL_SIZ(n) (((n) & 0x3) << 28) /* 2=256KB (always) */
#define L2CTL_L2SRAM(n) (((n) & 0x7) << 16) /* 1=all 256KB, 2=128KB */


/* PIC */
#define PIC_BASE (CCSRBAR + 0x40000)
#define PIC_WHOAMI ((volatile uint32_t*)(PIC_BASE + 0x0090UL)) /* Returns the ID of the processor core reading this register */
Expand Down Expand Up @@ -448,14 +443,17 @@ enum elbc_amask_sizes {
/* eSPI */
#define ESPI_MAX_CS_NUM 4
#define ESPI_MAX_RX_LEN (1 << 16)
#define ESPI_FIFO_WORD 4

#define ESPI_BASE (CCSRBAR + 0x7000)
#define ESPI_SPMODE ((volatile uint32_t*)(ESPI_BASE + 0x00)) /* controls eSPI general operation mode */
#define ESPI_SPIE ((volatile uint32_t*)(ESPI_BASE + 0x04)) /* controls interrupts and report events */
#define ESPI_SPIM ((volatile uint32_t*)(ESPI_BASE + 0x08)) /* enables/masks interrupts */
#define ESPI_SPCOM ((volatile uint32_t*)(ESPI_BASE + 0x0C)) /* command frame information */
#define ESPI_SPITF ((volatile uint32_t*)(ESPI_BASE + 0x10)) /* transmit FIFO access register */
#define ESPI_SPIRF ((volatile uint32_t*)(ESPI_BASE + 0x14)) /* 32-bit read-only receive data register */
#define ESPI_SPITF ((volatile uint32_t*)(ESPI_BASE + 0x10)) /* transmit FIFO access register (32-bit) */
#define ESPI_SPIRF ((volatile uint32_t*)(ESPI_BASE + 0x14)) /* read-only receive data register (32-bit) */
#define ESPI_SPITF8 ((volatile uint8_t*)( ESPI_BASE + 0x10)) /* transmit FIFO access register (8-bit) */
#define ESPI_SPIRF8 ((volatile uint8_t*)( ESPI_BASE + 0x14)) /* read-only receive data register (8-bit) */
#define ESPI_SPCSMODE(x) ((volatile uint32_t*)(ESPI_BASE + 0x20 + ((cs) * 4))) /* controls master operation with chip select 0-3 */

#define ESPI_SPMODE_EN (0x80000000) /* Enable eSPI */
Expand All @@ -466,9 +464,12 @@ enum elbc_amask_sizes {
#define ESPI_SPCOM_RXSKIP(x) ((x) << 16) /* Number of characters skipped for reception from frame start */
#define ESPI_SPCOM_TRANLEN(x) (((x) - 1) << 0) /* Transaction length */

#define ESPI_SPIE_TXE (1 << 15) /* transmit empty */
#define ESPI_SPIE_DON (1 << 14) /* Last character was transmitted */
#define ESPI_SPIE_RNE (1 << 9) /* receive not empty */
#define ESPI_SPIE_TNF (1 << 8) /* transmit not full */
#define ESPI_SPIE_RXT (1 << 13) /* Rx FIFO has more than RXTHR bytes */
#define ESPI_SPIE_RNE (1 << 9) /* receive not empty */
#define ESPI_SPIE_TNF (1 << 8) /* transmit not full */
#define ESPI_SPIE_RXCNT(n) (((n) >> 24) & 0x3F) /* The current number of full Rx FIFO bytes */

#define ESPI_CSMODE_CI 0x80000000 /* Inactive high */
#define ESPI_CSMODE_CP 0x40000000 /* Begin edge clock */
Expand Down Expand Up @@ -509,7 +510,10 @@ static uint32_t hal_get_bus_clk(void)
}

#if defined(ENABLE_ESPI) || defined(ENABLE_DDR)
static void udelay(unsigned long delay_us)
#ifdef BUILD_LOADER_STAGE1
static
#endif
void udelay(unsigned long delay_us)
{
delay_us *= (hal_get_bus_clk() / 1000000);
wait_ticks(delay_us);
Expand All @@ -522,7 +526,7 @@ void hal_espi_init(uint32_t cs, uint32_t clock_hz, uint32_t mode)
{
uint32_t spibrg = hal_get_bus_clk() / 2, pm, csmode;

/* Enable eSPI with TX threadshold 4 and TX threshold 3 */
/* Enable eSPI with TX threadshold 4 and RX threshold 3 */
set32(ESPI_SPMODE, (ESPI_SPMODE_EN | ESPI_SPMODE_TXTHR(4) |
ESPI_SPMODE_RXTHR(3)));

Expand Down Expand Up @@ -554,41 +558,75 @@ void hal_espi_init(uint32_t cs, uint32_t clock_hz, uint32_t mode)
set32(ESPI_SPCSMODE(cs), csmode);
}

/* Note: This code assumes all input buffers are multiple of 4 */
int hal_espi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, int cont)
int hal_espi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz,
int flags)
{
uint32_t reg, blks;
uint32_t mosi, miso, xfer, event;

/* assert CS */
set32(ESPI_SPCOM, ESPI_SPCOM_CS(cs) | ESPI_SPCOM_TRANLEN(sz));
#ifdef DEBUG_ESPI
wolfBoot_printf("CS %d, Sz %d, Flags %x\n", cs, sz, flags);
#endif

set32(ESPI_SPIE, 0xffffffff); /* Clear all eSPI events */
if (sz > 0) {
/* assert CS - use max length and control CS with mode enable toggle */
set32(ESPI_SPCOM, ESPI_SPCOM_CS(cs) | ESPI_SPCOM_TRANLEN(0x10000));
set32(ESPI_SPIE, 0xffffffff); /* Clear all eSPI events */
}
while (sz > 0) {
xfer = ESPI_FIFO_WORD;
if (xfer > sz)
xfer = sz;

/* Transfer 4 or 1 */
if (xfer == ESPI_FIFO_WORD) {
set32(ESPI_SPITF, *((uint32_t*)tx));
}
else {
xfer = 1;
set8(ESPI_SPITF8, *((uint8_t*)tx));
}

/* wait till TX fifo is empty or done */
while (1) {
event = get32(ESPI_SPIE);
if (event & (ESPI_SPIE_TXE | ESPI_SPIE_DON)) {
/* clear events */
set32(ESPI_SPIE, (ESPI_SPIE_TXE | ESPI_SPIE_DON));
break;
}
}

/* wait till RX has enough data */
while (1) {
event = get32(ESPI_SPIE);
if ((event & ESPI_SPIE_RNE) == 0)
continue;
#if defined(DEBUG_ESPI) && DEBUG_ESPI > 1
wolfBoot_printf("event %x\n", event);
#endif
if (ESPI_SPIE_RXCNT(event) >= xfer)
break;
}
if (xfer == ESPI_FIFO_WORD) {
*((uint32_t*)rx) = get32(ESPI_SPIRF);
}
else {
*((uint8_t*)rx) = get8(ESPI_SPIRF8);
}

/* calculate the number of 4 byte blocks rounded up */
blks = (sz + 3) / 4;
while (blks--) {
/* wait till TX fifo has room */
while ((get32(ESPI_SPIE) & ESPI_SPIE_TNF) == 0);
reg = *((uint32_t*)tx);
set32(ESPI_SPITF, reg);
tx += 4;
set32(ESPI_SPIE, ESPI_SPIE_TNF); /* clear event */

udelay(5);

/* wait till RX has data */
while ((get32(ESPI_SPIE) & ESPI_SPIE_RNE) == 0);
reg = get32(ESPI_SPIRF);
*((uint32_t*)rx) = reg;
rx += 4;
set32(ESPI_SPIE, ESPI_SPIE_RNE); /* clear event */
#ifdef DEBUG_ESPI
wolfBoot_printf("MOSI %x, MISO %x\n",
*((uint32_t*)tx), *((uint32_t*)rx));
#endif
tx += xfer;
rx += xfer;
sz -= xfer;
}

if (!cont) {
if (!(flags & SPI_XFER_FLAG_CONTINUE)) {
/* toggle ESPI_SPMODE_EN - to deassert CS */
reg = get32(ESPI_SPMODE);
set32(ESPI_SPMODE, reg & ~ESPI_SPMODE_EN);
set32(ESPI_SPMODE, reg);
set32(ESPI_SPMODE, get32(ESPI_SPMODE) & ~ESPI_SPMODE_EN);
set32(ESPI_SPMODE, get32(ESPI_SPMODE) | ESPI_SPMODE_EN);
}

return 0;
Expand Down Expand Up @@ -1497,40 +1535,6 @@ static void hal_irq_init(void)
}
#endif

#ifdef ENABLE_L2_CACHE
static void hal_l2_init(void)
{
uint32_t reg;

/* e500v2 L2 Cache */
#ifdef L2SRAM_ADDR
/* L2 L2SRAM_ADDR: TLB 1, Entry 9, Supervisor X/R/W, G, TS=0, 256KB, IPROT */
set_tlb(1, 9,
L2SRAM_ADDR, L2SRAM_ADDR, 0,
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_G, 0,
BOOKE_PAGESZ_256K, 1, r3);
#endif

/* Configure the L2 Cache */
asm volatile("mbar; isync");
#ifdef L2SRAM_ADDR /* as SRAM (1=256KB) */
set32(L2CTL, (L2CTL_EN | L2CTL_INV | L2CTL_L2SRAM(1)));
#else
set32(L2CTL, (L2CTL_EN | L2CTL_INV | L2CTL_SIZ(2)));
#endif
reg = get32(L2CTL); /* read back (per P1021 RM) */
asm volatile("mbar");

#ifdef L2SRAM_ADDR
/* Set the L2SRAM base address */
asm volatile("mbar; isync");
set32(L2SRBAR0, L2SRAM_ADDR);
reg = get32(L2SRBAR0);
asm volatile("mbar");
#endif
}
#endif /* ENABLE_L2_CACHE */

void hal_init(void)
{
#ifdef DEBUG_UART
Expand All @@ -1539,9 +1543,6 @@ void hal_init(void)
uart_write("wolfBoot HAL Init\n", 19);
#endif
#endif
#ifdef ENABLE_L2_CACHE
hal_l2_init();
#endif
#ifdef ENABLE_PCIE
hal_pcie_init();
#endif
Expand Down
Binary file modified hal/nxp_p1021_stage1.bin
Binary file not shown.
4 changes: 2 additions & 2 deletions hal/nxp_p1021_stage1.ld
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,5 @@ SECTIONS
} > DRAM
}

PROVIDE(_start_heap = _end);
PROVIDE(_end_stack = ORIGIN(L1RAM) + (LENGTH(L1RAM)) );
PROVIDE(_start_heap = ORIGIN(L2RAM));
PROVIDE(_end_stack = ORIGIN(L2RAM) + (LENGTH(L2RAM)) );
33 changes: 13 additions & 20 deletions hal/nxp_ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,23 @@
#define CCSRBAR_DEF (0xFF700000) /* P1021RM 4.3 default base */
#define CCSRBAR_SIZE BOOKE_PAGESZ_1M

#define ENABLE_L1_CACHE

#define ENABLE_DDR

/* Memory used for transferring blocks to/from NAND.
* Maps to eLBC FCM internal 8KB region (by hardware) */
#define FLASH_BASE_ADDR 0xFC000000

#ifdef BUILD_LOADER_STAGE1
/* First stage loader features */

/* For Boot ROM FCM buffer */
#define FLASH_BASE_ADDR 0xFFF00000

/* L2 is not available while FMR[BOOT]=1 */
#define L1_CACHE_ADDR 0xFFD00000
#define ENABLE_L2_CACHE
#define L2SRAM_ADDR (0xF8F80000) /* L2 as SRAM */
#define L2SRAM_SIZE (256 * 1024)
#else
/* For wolfBoot features */
#define ENABLE_L1_CACHE
#define ENABLE_L2_CACHE

/* Memory used for transferring blocks to/from NAND.
* Maps to eLBC FCM internal 8KB region (by hardware) */
#define FLASH_BASE_ADDR 0xFC000000

/* Relocate CCSRBAR */
#define CCSRBAR 0xFFE00000

Expand Down Expand Up @@ -117,14 +114,10 @@
#endif

/* L1 */
#ifndef L1_CACHE_ADDR
#define L1_CACHE_ADDR 0xFFD00000
#endif
#ifndef L1_CACHE_SZ
#define L1_CACHE_SZ (32 * 1024)
#endif


#ifdef CORE_E500
/* PowerPC e500 */
/* EREF: 7.5.3.2 - TLB Entry Page Size */
Expand All @@ -143,7 +136,7 @@
#define MAS1_TSIZE_MASK 0x00000F00
#define MAS1_TSIZE(x) (((x) << 8) & MAS1_TSIZE_MASK)

#define L1_CACHE_LINE_SHIFT 5 /* 32 bytes per L1 cache line */
#define CACHE_LINE_SHIFT 5 /* 32 bytes per L1 cache line */

/* P1021 LAW - Local Access Window (Memory Map) - RM 2.4 */
#define LAWBAR_BASE(n) (0xC08 + (n * 0x20))
Expand All @@ -157,7 +150,7 @@
#define LAW_TRGT_PCIE2 0x01
#define LAW_TRGT_PCIE1 0x02
#define LAW_TRGT_ELBC 0x04 /* eLBC (Enhanced Local Bus Controller) */
#define LAW_TRGT_DDR 0x0F /* DDR Memory Controller */
#define LAW_TRGT_DDR 0x0F /* DDR Memory Controller */

/* P1021 2.4.2 - size is equal to 2^(enum + 1) */
#define LAW_SIZE_4KB 0x0B
Expand Down Expand Up @@ -218,7 +211,7 @@
#define MAS1_TSIZE_MASK 0x00000F80
#define MAS1_TSIZE(x) (((x) << 7) & MAS1_TSIZE_MASK)

#define L1_CACHE_LINE_SHIFT 6 /* 64 bytes per L1 cache line */
#define CACHE_LINE_SHIFT 6 /* 64 bytes per L1 cache line */

/* CoreNet Platform Cache Base */
#define CPC_BASE (CCSRBAR + 0x10000)
Expand Down Expand Up @@ -271,8 +264,8 @@

#endif

#ifndef L1_CACHE_LINE_SIZE
#define L1_CACHE_LINE_SIZE (1 << L1_CACHE_LINE_SHIFT)
#ifndef CACHE_LINE_SIZE
#define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT)
#endif


Expand Down
Loading

0 comments on commit 0f4675f

Please sign in to comment.