mirror of https://github.com/wolfSSL/wolfBoot.git
Add LS1028A eSDHC SD card disk boot support
parent
8eafe1ef76
commit
a8c8c19fe8
|
|
@ -274,6 +274,14 @@ jobs:
|
|||
config-file: ./config/examples/nxp-ls1028a-tpm.config
|
||||
make-args: CROSS_COMPILE=aarch64-linux-gnu-
|
||||
|
||||
# SD card disk boot via the Freescale eSDHC driver (hal/nxp_esdhc.o)
|
||||
nxp_ls1028a_sdcard_test:
|
||||
uses: ./.github/workflows/test-build.yml
|
||||
with:
|
||||
arch: aarch64
|
||||
config-file: ./config/examples/nxp-ls1028a-sdcard.config
|
||||
make-args: CROSS_COMPILE=aarch64-linux-gnu-
|
||||
|
||||
nxp_mcxa_test:
|
||||
uses: ./.github/workflows/test-build-mcux-sdk-manifests.yml
|
||||
with:
|
||||
|
|
|
|||
20
arch.mk
20
arch.mk
|
|
@ -181,6 +181,18 @@ ifeq ($(ARCH),AARCH64)
|
|||
CFLAGS+=-fno-builtin-printf
|
||||
endif
|
||||
|
||||
# SD card disk boot uses the Freescale eSDHC driver, not the Cadence
|
||||
# SDHCI one (the shared AARCH64 block below wires update_disk.o).
|
||||
# hal/nxp_esdhc.c is SD card only, so DISK_EMMC has no driver here:
|
||||
# reject it rather than silently link the wrong controller driver.
|
||||
ifeq ($(DISK_EMMC),1)
|
||||
$(error DISK_EMMC is not supported on nxp_ls1028a (hal/nxp_esdhc.c is SD card only))
|
||||
endif
|
||||
ifeq ($(DISK_SDCARD),1)
|
||||
override DISK_DRIVER=esdhc
|
||||
OBJS+=hal/nxp_esdhc.o
|
||||
endif
|
||||
|
||||
SPI_TARGET=nxp
|
||||
endif
|
||||
|
||||
|
|
@ -1598,10 +1610,16 @@ ifneq ($(filter nxp_t1024 nxp_t1040,$(TARGET)),)
|
|||
# Disk boot from SD card (eSDHC controller, driver hal/nxp_esdhc.c).
|
||||
# src/gpt.o is already linked for all PPC targets above. The driver is
|
||||
# kept out of the size-constrained stage1 loader.
|
||||
ifneq ($(filter 1,$(DISK_SDCARD) $(DISK_EMMC)),)
|
||||
# hal/nxp_esdhc.c drives SD cards only: it has no eMMC (CMD1/EXT_CSD)
|
||||
# initialization, so DISK_EMMC has no driver on this arch.
|
||||
ifeq ($(DISK_EMMC),1)
|
||||
$(error DISK_EMMC is not supported on PPC (hal/nxp_esdhc.c is SD card only))
|
||||
endif
|
||||
ifeq ($(DISK_SDCARD),1)
|
||||
CFLAGS+=-D"WOLFBOOT_UPDATE_DISK" -D"MAX_DISKS=1"
|
||||
UPDATE_OBJS:=src/update_disk.o
|
||||
OBJS+=src/disk.o
|
||||
override DISK_DRIVER=esdhc
|
||||
ifneq ($(STAGE1),1)
|
||||
OBJS+=hal/nxp_esdhc.o
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
# NXP LS1028A with SD card disk boot
|
||||
#
|
||||
# Same as nxp-ls1028a.config, but the signed application image is loaded
|
||||
# from the SD card slot (eSDHC1 at 0x02140000) instead of XSPI NOR. The
|
||||
# card is GPT (or MBR) partitioned; the signed image sits at offset 0 of
|
||||
# the first two partitions (BOOT_PART_A / BOOT_PART_B, 0-based indexes
|
||||
# into the partition table - same card layout as the T1040 eSDHC target).
|
||||
# wolfBoot picks the slot with the higher version, verifies it and boots
|
||||
# it from DDR (src/update_disk.c).
|
||||
|
||||
ARCH=AARCH64
|
||||
TARGET=nxp_ls1028a
|
||||
SIGN?=ECC256
|
||||
HASH?=SHA256
|
||||
DEBUG?=0
|
||||
DEBUG_UART?=1
|
||||
VTOR?=0
|
||||
CORTEX_M0?=0
|
||||
NO_ASM?=0
|
||||
EXT_FLASH?=1
|
||||
SPI_FLASH?=0
|
||||
## Force app to be copied into ram
|
||||
NO_XIP?=1
|
||||
UART_FLASH?=0
|
||||
ALLOW_DOWNGRADE?=0
|
||||
NVM_FLASH_WRITEONCE?=0
|
||||
WOLFBOOT_VERSION?=0
|
||||
V?=0
|
||||
NO_MPU?=0
|
||||
SPMATH?=1
|
||||
RAM_CODE?=0
|
||||
DUALBANK_SWAP?=0
|
||||
PKA?=0
|
||||
ELF?=1
|
||||
|
||||
# SD card disk boot (Freescale eSDHC driver, hal/nxp_esdhc.c)
|
||||
DISK_SDCARD=1
|
||||
# Upper bound for the unauthenticated image size read from disk
|
||||
WOLFBOOT_RAMBOOT_MAX_SIZE?=0x1000000
|
||||
# Boot slots: partition table indexes (0-based) and read chunk size
|
||||
CFLAGS_EXTRA+=-DBOOT_PART_A=0 -DBOOT_PART_B=1
|
||||
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x8000
|
||||
# do_boot keeps the MMU and caches on (ENETC coherency) and cleans from the
|
||||
# entry point before the jump. Pin the clean length to the RAMBOOT window so
|
||||
# it covers the area images are loaded into regardless of what
|
||||
# WOLFBOOT_PARTITION_SIZE is set to. Note this cleans one span from the
|
||||
# entry point: an ELF or FIT payload that relocates a segment outside this
|
||||
# window would need its own cache maintenance.
|
||||
CFLAGS_EXTRA+=-DWOLFBOOT_MMU_FLUSH_APP_SIZE=0x1000000
|
||||
# eSDHC bring-up trace on the DUART console
|
||||
#CFLAGS_EXTRA+=-DDEBUG_ESDHC
|
||||
|
||||
# NOR Base Address
|
||||
ARCH_FLASH_OFFSET?=0x20000000
|
||||
|
||||
# Flash Sector Size (128 KB)
|
||||
WOLFBOOT_SECTOR_SIZE=0x20000
|
||||
|
||||
# wolfBoot start address
|
||||
WOLFBOOT_ORIGIN=0x20020000
|
||||
|
||||
# wolfBoot partition size
|
||||
BOOTLOADER_PARTITION_SIZE=0x20000
|
||||
|
||||
# Application Partition size. Matches the 16MB SD card slots; the sign
|
||||
# tool bounds the image against this even though disk boot does not use
|
||||
# the NOR partitions.
|
||||
WOLFBOOT_PARTITION_SIZE?=0x1000000
|
||||
|
||||
# Location in Flash for Application Partition (unused for disk boot,
|
||||
# kept for target.h consistency)
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20100000
|
||||
|
||||
# Load the image to DDR, not the default OCRAM: OCRAM also holds
|
||||
# wolfBoot's own .data/.bss/.stack and cannot hold a disk-sized image.
|
||||
WOLFBOOT_LOAD_ADDRESS?=0x80100000
|
||||
|
||||
# Location in Flash for Update Partition
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x21100000
|
||||
|
||||
# Location of temporary sector used during updates
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x22100000
|
||||
|
||||
# DTS (Device Tree). The load address must sit above
|
||||
# WOLFBOOT_LOAD_ADDRESS + WOLFBOOT_RAMBOOT_MAX_SIZE.
|
||||
WOLFBOOT_LOAD_DTS_ADDRESS?=0x82000000
|
||||
WOLFBOOT_DTS_BOOT_ADDRESS?=0x20F00000
|
||||
WOLFBOOT_DTS_UPDATE_ADDRESS?=0x20F00000
|
||||
|
|
@ -3698,6 +3698,11 @@ The LS1028A is a AARCH64 armv8-a Cortex-A72 processor. Support has been tested w
|
|||
Example configurations for this target are provided in:
|
||||
* NXP LS1028A: [/config/examples/nxp-ls1028a.config](/config/examples/nxp-ls1028a.config).
|
||||
* NXP LS1028A with TPM: [/config/examples/nxp-ls1028a-tpm.config](/config/examples/nxp-ls1028a-tpm.config).
|
||||
* NXP LS1028A with SD card boot: [/config/examples/nxp-ls1028a-sdcard.config](/config/examples/nxp-ls1028a-sdcard.config).
|
||||
|
||||
### LS1028A SD Card Boot (eSDHC)
|
||||
|
||||
The LS1028A can load the signed application image from the SD card slot (eSDHC1) using the same Freescale eSDHC driver as the T1040 (`hal/nxp_esdhc.c`, built as its own object). The card layout is identical to the T1040 SD target: GPT (or MBR) partitioned, with the signed image at offset 0 of the first two partitions (`BOOT_PART_A`/`BOOT_PART_B`, 0-based). wolfBoot reads both headers, picks the higher version, loads it to DDR (`WOLFBOOT_LOAD_ADDRESS=0x80100000`), verifies the signature and boots it. The driver reprograms the eSDHC source clock (HWA2) at init, because the NOR-boot RCW leaves it on a source too fast for card identification. Define `DEBUG_ESDHC` (see the config) for controller bring-up trace on the DUART console. Validated on the LS1028ARDB booting a signed image from SD.
|
||||
|
||||
### Building wolfBoot for NXP LS1028A
|
||||
|
||||
|
|
|
|||
131
hal/nxp_esdhc.c
131
hal/nxp_esdhc.c
|
|
@ -19,7 +19,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/* Freescale/NXP eSDHC block driver for QorIQ (T1040, T1024, T2080).
|
||||
/* Freescale/NXP eSDHC block driver for QorIQ PPC (T1040, T1024, T2080)
|
||||
* and Layerscape (LS1028A).
|
||||
*
|
||||
* Provides the four entry points src/disk.c expects (disk_init, disk_read,
|
||||
* disk_write, disk_close) so the disk boot path, and therefore DISK_FS, can
|
||||
|
|
@ -30,9 +31,9 @@
|
|||
* one XFERTYP register, combines block size and count into BLKATTR, and has
|
||||
* a watermark register with no standard-SDHCI equivalent.
|
||||
*
|
||||
* Compiled as its own object (arch.mk adds hal/nxp_esdhc.o when
|
||||
* DISK_SDCARD or DISK_EMMC is set); the clock helpers it needs are
|
||||
* exported by nxp_ppc.h.
|
||||
* Compiled as its own object (the target's arch.mk block adds
|
||||
* hal/nxp_esdhc.o and sets DISK_DRIVER=esdhc when DISK_SDCARD is set);
|
||||
* per-target base address, clocks and byte order are selected below.
|
||||
*
|
||||
* Transfers use PIO through DATPORT rather than DMA. On e5500 with the MMU
|
||||
* enabled a DMA descriptor would need cache maintenance on the destination,
|
||||
|
|
@ -47,7 +48,38 @@
|
|||
|
||||
#include "disk.h"
|
||||
#include "printf.h"
|
||||
|
||||
/* Per-target selection. The eSDHC block is the same IP on big-endian QorIQ
|
||||
* PPC and little-endian Layerscape; the register file follows the
|
||||
* integration, so a native 32-bit access reads it correctly on both. Only
|
||||
* the base address, source clock and DATPORT byte order move per target. */
|
||||
#if defined(TARGET_nxp_ls1028a)
|
||||
|
||||
#include "nxp_ls1028a.h"
|
||||
/* eSDHC1 is the SD card slot; eSDHC2 is eMMC, not supported by this driver. */
|
||||
#define ESDHC_CTRL_BASE ESDHC_BASE(0)
|
||||
#define ESDHC_EMODE_SEL ESDHC_PROCTL_EMODE_LE
|
||||
#ifndef ESDHC_REF_CLK
|
||||
#define ESDHC_REF_CLK 400000000UL
|
||||
#endif
|
||||
/* The block is clocked by hardware-accelerator mux HWA2 (the device tree
|
||||
* binds mmc@2140000 to QORIQ_CLK_HWACCEL index 1). The NOR-boot RCW leaves
|
||||
* it on CGA_PLL2 (1.2 GHz), which overruns the card during identification;
|
||||
* CLKSEL=7 selects CGA_PLL1/3. Set at runtime so SD works whichever RCW
|
||||
* booted us. hwaccel[idx] = clockgen + 0x20*idx + 0x10, eSDHC is idx 1. */
|
||||
#define LS1028A_HWA2CSR (CGUCGA_BASE + 0x30)
|
||||
#define HWA_CLKSEL_MASK 0x78000000U
|
||||
#define HWA_CLKSEL_SHIFT 27
|
||||
#define HWA_CLKSEL_ESDHC 7U
|
||||
|
||||
#else
|
||||
|
||||
/* QorIQ PPC T-series: big-endian core and registers. */
|
||||
#include "nxp_ppc.h"
|
||||
#define ESDHC_CTRL_BASE (CCSRBAR + 0x114000)
|
||||
#define ESDHC_EMODE_SEL ESDHC_PROCTL_EMODE_BE
|
||||
|
||||
#endif /* target selection */
|
||||
|
||||
#ifdef DEBUG_ESDHC
|
||||
#define ESDHC_DBG(_f_, ...) wolfBoot_printf(_f_, ##__VA_ARGS__)
|
||||
|
|
@ -55,18 +87,7 @@
|
|||
#define ESDHC_DBG(_f_, ...) do{}while(0)
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Register map. CCSRBAR comes from nxp_ppc.h for the selected target.
|
||||
*
|
||||
* The block presents its registers big-endian and the e5500 is big-endian,
|
||||
* so a native 32-bit access reads them correctly with no swapping. The one
|
||||
* exception is DATPORT, whose byte order is selected by PROCTL[EMODE] and is
|
||||
* configured below.
|
||||
* --------------------------------------------------------------------- */
|
||||
#ifndef ESDHC_BASE
|
||||
#define ESDHC_BASE (CCSRBAR + 0x114000)
|
||||
#endif
|
||||
#define ESDHC_REG(off) ((volatile uint32_t*)(ESDHC_BASE + (off)))
|
||||
#define ESDHC_REG(off) ((volatile uint32_t*)(ESDHC_CTRL_BASE + (off)))
|
||||
|
||||
#define ESDHC_DSADDR 0x00
|
||||
#define ESDHC_BLKATTR 0x04
|
||||
|
|
@ -117,11 +138,11 @@
|
|||
#define ESDHC_PROCTL_DTW_1BIT (0U << 1)
|
||||
#define ESDHC_PROCTL_DTW_4BIT (1U << 1)
|
||||
#define ESDHC_PROCTL_DTW_MASK (3U << 1)
|
||||
/* EMODE selects the byte order of DATPORT. Big-endian mode delivers bytes
|
||||
* in media order when the word is stored natively by this big-endian core.
|
||||
* Verified on T1040D4RDB silicon: little-endian mode read every aligned
|
||||
* 4-byte group byte-reversed (MBR signature came back AA55). */
|
||||
/* EMODE sets DATPORT byte order; ESDHC_EMODE_SEL picks the mode giving
|
||||
* media order for a native word store. Silicon-verified: BE on the T1040
|
||||
* (LE there returned every aligned 4-byte group reversed). */
|
||||
#define ESDHC_PROCTL_EMODE_BE (0U << 4)
|
||||
#define ESDHC_PROCTL_EMODE_LE (2U << 4)
|
||||
#define ESDHC_PROCTL_EMODE_MASK (3U << 4)
|
||||
|
||||
/* SYSCTL */
|
||||
|
|
@ -186,6 +207,27 @@ static int g_esdhc_ready;
|
|||
* 37500000 Hz (600 MHz / 16).
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
#if defined(TARGET_nxp_ls1028a)
|
||||
|
||||
/* ARM generic timer; hal_init() enables the system counter first. */
|
||||
static uint64_t esdhc_timebase(void)
|
||||
{
|
||||
uint64_t cnt;
|
||||
|
||||
__asm__ __volatile__("isb; mrs %0, cntpct_el0" : "=r"(cnt));
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static uint32_t esdhc_read_tb_hz(void)
|
||||
{
|
||||
uint64_t frq;
|
||||
|
||||
__asm__ __volatile__("mrs %0, cntfrq_el0" : "=r"(frq));
|
||||
return (uint32_t)frq;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static uint64_t esdhc_timebase(void)
|
||||
{
|
||||
uint32_t hi, lo, hi2;
|
||||
|
|
@ -201,6 +243,13 @@ static uint64_t esdhc_timebase(void)
|
|||
return ((uint64_t)hi << 32) | (uint64_t)lo;
|
||||
}
|
||||
|
||||
static uint32_t esdhc_read_tb_hz(void)
|
||||
{
|
||||
return TIMEBASE_HZ;
|
||||
}
|
||||
|
||||
#endif /* target timebase */
|
||||
|
||||
/* Timebase frequency, cached by disk_init(). TIMEBASE_HZ reads clock
|
||||
* registers and divides on every use; the value cannot change at runtime,
|
||||
* and disk_init() rejects a zero reading before any other driver path can
|
||||
|
|
@ -311,7 +360,11 @@ static int esdhc_send_cmd(uint32_t idx, uint32_t arg, uint32_t xfertyp,
|
|||
/* Set the SD clock. The divider is SDCLKFS (base 2 prescaler) times DVS. */
|
||||
static void esdhc_set_clock(uint32_t target_hz)
|
||||
{
|
||||
#if defined(TARGET_nxp_ls1028a)
|
||||
uint32_t base = ESDHC_REF_CLK;
|
||||
#else
|
||||
uint32_t base = hal_get_bus_clk();
|
||||
#endif
|
||||
uint32_t pre = 2, div = 1, sysctl;
|
||||
|
||||
if (target_hz == 0U) {
|
||||
|
|
@ -341,8 +394,9 @@ static void esdhc_set_clock(uint32_t target_hz)
|
|||
ESDHC_SYSCTL_SDCLKEN;
|
||||
esdhc_udelay(100);
|
||||
|
||||
ESDHC_DBG("esdhc: clock %u Hz (pre %u, div %u)\r\n",
|
||||
(base / pre) / div, pre, div);
|
||||
ESDHC_DBG("esdhc: clock %u Hz (pre %u, div %u) SYSCTL %x PROCTL %x\r\n",
|
||||
(base / pre) / div, pre, div,
|
||||
*ESDHC_REG(ESDHC_SYSCTL), *ESDHC_REG(ESDHC_PROCTL));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -376,7 +430,7 @@ static int esdhc_host_init(void)
|
|||
/* 1-bit bus for identification, and set the data-port byte order. */
|
||||
proctl = *ESDHC_REG(ESDHC_PROCTL);
|
||||
proctl &= ~(ESDHC_PROCTL_DTW_MASK | ESDHC_PROCTL_EMODE_MASK);
|
||||
proctl |= ESDHC_PROCTL_DTW_1BIT | ESDHC_PROCTL_EMODE_BE;
|
||||
proctl |= ESDHC_PROCTL_DTW_1BIT | ESDHC_EMODE_SEL;
|
||||
*ESDHC_REG(ESDHC_PROCTL) = proctl;
|
||||
|
||||
esdhc_set_clock(400000U);
|
||||
|
|
@ -403,6 +457,7 @@ static int esdhc_send_acmd(uint32_t idx, uint32_t arg, uint32_t xfertyp,
|
|||
ESDHC_XFERTYP_RSPTYP_48 | ESDHC_XFERTYP_CICEN | ESDHC_XFERTYP_CCCEN,
|
||||
NULL);
|
||||
if (ret != 0) {
|
||||
ESDHC_DBG("esdhc: CMD55 (for ACMD%u) failed\r\n", idx);
|
||||
return ret;
|
||||
}
|
||||
return esdhc_send_cmd(idx, arg, xfertyp, resp);
|
||||
|
|
@ -442,8 +497,10 @@ static int esdhc_card_init(void)
|
|||
return -1;
|
||||
}
|
||||
v2 = 1;
|
||||
ESDHC_DBG("esdhc: CMD8 ok resp %x\r\n", resp[0]);
|
||||
}
|
||||
else {
|
||||
ESDHC_DBG("esdhc: CMD8 no response (v1 or signalling)\r\n");
|
||||
/* CMD8 leaves the command line in error state on a v1 card. */
|
||||
*ESDHC_REG(ESDHC_SYSCTL) = *ESDHC_REG(ESDHC_SYSCTL) |
|
||||
ESDHC_SYSCTL_RSTC;
|
||||
|
|
@ -529,10 +586,12 @@ static int esdhc_card_init(void)
|
|||
|
||||
/* Drain one block from the data port.
|
||||
*
|
||||
* PROCTL[EMODE] is set to big-endian above, so a native 32-bit read of
|
||||
* DATPORT returns the four media bytes already in order and they can be
|
||||
* stored as-is. Silicon-verified: little-endian mode returned every
|
||||
* aligned 4-byte group byte-reversed. */
|
||||
* ESDHC_EMODE_SEL (set per target above) makes a native 32-bit read of
|
||||
* DATPORT return the four media bytes already in order, so they are
|
||||
* stored as-is. The correct mode differs by integration and both are
|
||||
* silicon-verified: big-endian on the big-endian T1040, where
|
||||
* little-endian returned every aligned 4-byte group reversed, and
|
||||
* little-endian on the little-endian LS1028A. */
|
||||
static int esdhc_read_block(uint8_t *buf)
|
||||
{
|
||||
uint32_t i, word;
|
||||
|
|
@ -662,6 +721,19 @@ static int esdhc_read_blocks(uint64_t lba, uint32_t count, uint8_t *buf)
|
|||
* disk.c interface
|
||||
* --------------------------------------------------------------------- */
|
||||
|
||||
#if defined(TARGET_nxp_ls1028a)
|
||||
/* Route a usable source clock to the eSDHC block (see HWA2CSR above). */
|
||||
static void esdhc_clock_src_init(void)
|
||||
{
|
||||
volatile uint32_t *hwa2 = (volatile uint32_t*)LS1028A_HWA2CSR;
|
||||
uint32_t val = (*hwa2 & ~HWA_CLKSEL_MASK) |
|
||||
(HWA_CLKSEL_ESDHC << HWA_CLKSEL_SHIFT);
|
||||
|
||||
*hwa2 = val;
|
||||
ESDHC_DBG("esdhc: HWA2CSR %x\r\n", *hwa2);
|
||||
}
|
||||
#endif
|
||||
|
||||
int disk_init(int drv)
|
||||
{
|
||||
if (drv != 0) {
|
||||
|
|
@ -673,7 +745,10 @@ int disk_init(int drv)
|
|||
/* Cache the timebase frequency for every delay and timeout below. A
|
||||
* zero reading means no timeout in this driver could ever expire, so
|
||||
* fail here and let the caller panic instead of spinning forever. */
|
||||
g_esdhc_tb_hz = TIMEBASE_HZ;
|
||||
#if defined(TARGET_nxp_ls1028a)
|
||||
esdhc_clock_src_init();
|
||||
#endif
|
||||
g_esdhc_tb_hz = esdhc_read_tb_hz();
|
||||
if (g_esdhc_tb_hz == 0U) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
12
options.mk
12
options.mk
|
|
@ -801,12 +801,14 @@ ifeq ($(DISK_EMMC),1)
|
|||
CFLAGS+=-D"DISK_EMMC=1"
|
||||
endif
|
||||
|
||||
# Add SDHCI driver if SD card or eMMC is enabled (only add once).
|
||||
# PPC targets provide their own eSDHC driver (hal/nxp_esdhc.o, added in
|
||||
# arch.mk), so the Cadence SDHCI driver must not be linked there (its
|
||||
# disk_* entry points would collide).
|
||||
# Add the SD/eMMC block driver if SD card or eMMC is enabled (only once).
|
||||
# DISK_DRIVER selects which one: the Cadence SDHCI driver (src/sdhci.c,
|
||||
# the default) or the Freescale eSDHC driver (hal/nxp_esdhc.o, added by
|
||||
# the target's arch.mk block, which also sets DISK_DRIVER=esdhc). Exactly
|
||||
# one may link: both define the disk_* entry points.
|
||||
DISK_DRIVER?=cadence
|
||||
ifneq ($(filter 1,$(DISK_SDCARD) $(DISK_EMMC)),)
|
||||
ifneq ($(ARCH),PPC)
|
||||
ifeq ($(DISK_DRIVER),cadence)
|
||||
OBJS+= src/sdhci.o
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue