CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/27088

- Add support for the i.MX95 B0 version.
- Enable standard boot for phycore-imx8mp.
- Kconfig fixes for i.MX MMC and FSL_SEC_MON.
- Support 4Gb single die variant of the i.MX8MM Venice board.
This commit is contained in:
Tom Rini
2025-07-17 11:42:46 -06:00
29 changed files with 296 additions and 830 deletions

View File

@@ -84,6 +84,28 @@ config SYS_FSL_SFP_VER_3_4
endchoice
config FSL_SEC_MON
bool
help
Freescale Security Monitor block is responsible for monitoring
system states.
Security Monitor can be transitioned on any security failures,
like software violations or hardware security violations.
choice
prompt "Security monitor interaction endianess"
depends on FSL_SEC_MON
default SYS_FSL_SEC_MON_BE if PPC
default SYS_FSL_SEC_MON_LE
config SYS_FSL_SEC_MON_LE
bool "Security monitor interactions are little endian"
config SYS_FSL_SEC_MON_BE
bool "Security monitor interactions are big endian"
endchoice
config SPL_UBOOT_KEY_HASH
string "Non-SRK key hash for U-Boot public/private key pair"
depends on SPL

View File

@@ -77,11 +77,11 @@ config ARCH_LS1043A
select SYS_FSL_DDR_BE
select SYS_FSL_DDR_VER_50
select SYS_FSL_ERRATUM_A008850 if !TFABOOT
select SYS_FSL_ERRATUM_A008997
select SYS_FSL_ERRATUM_A009008
select SYS_FSL_ERRATUM_A008997 if USB
select SYS_FSL_ERRATUM_A009008 if USB
select SYS_FSL_ERRATUM_A009660 if !TFABOOT
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
select SYS_FSL_ERRATUM_A009798
select SYS_FSL_ERRATUM_A009798 if USB
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
select SYS_FSL_ERRATUM_A010315 if PCIE_LAYERSCAPE
select SYS_FSL_ERRATUM_A010539

View File

@@ -22,12 +22,12 @@
type = "nxp-header-ddrfw";
imx-lpddr-imem {
filename = "lpddr5_imem_v202311.bin";
filename = "lpddr5_imem_v202409.bin";
type = "blob-ext";
};
imx-lpddr-dmem {
filename = "lpddr5_dmem_v202311.bin";
filename = "lpddr5_dmem_v202409.bin";
type = "blob-ext";
};
};
@@ -36,12 +36,12 @@
type = "nxp-header-ddrfw";
imx-lpddr-imem-qb {
filename = "lpddr5_imem_qb_v202311.bin";
filename = "lpddr5_imem_qb_v202409.bin";
type = "blob-ext";
};
imx-lpddr-dmem-qb {
filename = "lpddr5_dmem_qb_v202311.bin";
filename = "lpddr5_dmem_qb_v202409.bin";
type = "blob-ext";
};
};

View File

@@ -21,11 +21,6 @@ extern void mx27_uart1_init_pins(void);
extern void mx27_fec_init_pins(void);
#endif /* CONFIG_FEC_MXC */
#ifdef CONFIG_MMC_MXC
extern void mx27_sd1_init_pins(void);
extern void mx27_sd2_init_pins(void);
#endif /* CONFIG_MMC_MXC */
/* AIPI */
struct aipi_regs {
u32 psr0;

View File

@@ -134,6 +134,8 @@ struct ele_get_info_data {
u32 sha_fw[8];
u32 oem_srkh[16];
u32 state;
u32 oem_pqc_srkh[16];
u32 reserved[8];
};
int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response);

View File

@@ -66,7 +66,7 @@ static bool is_v2x_fw_container(ulong addr)
struct boot_img_t *img_entry;
phdr = (struct container_hdr *)addr;
if (phdr->tag != 0x87 || phdr->version != 0x0) {
if ((phdr->tag != 0x87 && phdr->tag != 0x82) || phdr->version != 0x0) {
debug("Wrong container header\n");
return false;
}

View File

@@ -279,7 +279,7 @@ int print_cpuinfo(void)
if (!ret) {
ret = thermal_get_temp(udev, &temp);
if (!ret)
printf("CPU current temperature: %d\n", temp);
printf("CPU current temperature: %dC\n", temp);
else
debug(" - failed to get CPU current temperature\n");
} else {

View File

@@ -33,6 +33,7 @@ config IMX95
select DM_MAILBOX
select SCMI_FIRMWARE
select SPL_IMX_CONTAINER_USE_TRAMPOLINE
select IMX_PQC_SUPPORT
config SYS_SOC
default "imx9"

View File

@@ -3,6 +3,7 @@
* Copyright 2025 NXP
*/
CNTR_VERSION 2
BOOT_FROM SD
SOC_TYPE IMX9
CONTAINER

View File

@@ -3,13 +3,14 @@
* Copyright 2025 NXP
*/
CNTR_VERSION 2
BOOT_FROM SD
SOC_TYPE IMX9
APPEND mx95a0-ahab-container.img
APPEND mx95b0-ahab-container.img
CONTAINER
DUMMY_DDR
IMAGE OEI m33-oei-ddrfw.bin 0x1ffc0000
HOLD 0x10000
IMAGE OEI oei-m33-tcm.bin 0x1ffc0000
IMAGE M33 m33_image.bin 0x1ffc0000
IMAGE A55 spl/u-boot-spl.bin 0x20480000
DUMMY_V2X 0x8b000000

View File

@@ -356,7 +356,7 @@ static int eeprom_info(bool verbose)
return 0;
}
int venice_eeprom_init(int quiet)
struct venice_board_info *venice_eeprom_init(int quiet)
{
char rev_pcb;
int rev_bom;
@@ -466,10 +466,10 @@ int venice_eeprom_init(int quiet)
if (!strncmp(venice_model, "GW7901-SP486", 12) &&
strcmp(venice_model, "GW7901-SP486-C")) {
return 2048;
som_info.sdram_size++;
}
return (16 << som_info.sdram_size);
return &som_info;
}
void board_gsc_info(void)

View File

@@ -18,13 +18,14 @@ struct venice_board_info {
u8 sdram_size; /* 0x2B: (16 << n) MB */
u8 sdram_speed; /* 0x2C: (33.333 * n) MHz */
u8 sdram_width; /* 0x2D: (8 << n) bit */
u8 res3[2]; /* 0x2E */
u8 sdram_variant; /* 0x2E */
u8 res3[1]; /* 0x2D */
char model[16]; /* 0x30: model string */
u8 config[14]; /* 0x40: model config */
u8 chksum[2]; /* 0x4E */
};
int venice_eeprom_init(int quiet);
struct venice_board_info *venice_eeprom_init(int quiet);
const char *eeprom_get_model(void);
const char *eeprom_get_som_model(void);
const char *eeprom_get_baseboard_model(void);

View File

@@ -6,6 +6,7 @@
#ifndef __LPDDR4_TIMING_H__
#define __LPDDR4_TIMING_H__
extern struct dram_timing_info *spl_dram_init(const char *model, int sizemb);
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
char *dram_desc, size_t sz_desc);
#endif /* __LPDDR4_TIMING_H__ */

View File

@@ -10,6 +10,8 @@
#include <asm/arch/ddr.h>
#include <asm/arch/lpddr4_define.h>
#include "eeprom.h"
/* ddr phy trained csr */
static struct dram_cfg_param lpddr4_ddrphy_trained_csr[] = {
{ 0x200b2, 0x0 },
@@ -1890,6 +1892,7 @@ static struct dram_cfg_param lpddr4_ddrc_cfg_1gb[] = {
{ 0x3d400204, 0x80808 },
{ 0x3d400214, 0x7070707 },
{ 0x3d400218, 0xf070707 },
{ 0x3d40021c, 0xf0f },
{ 0x3d400250, 0x29001701 },
{ 0x3d400254, 0x2c },
{ 0x3d40025c, 0x4000030 },
@@ -2161,56 +2164,26 @@ static struct dram_cfg_param lpddr4_ddrphy_cfg_1gb[] = {
/* P0 message block paremeter for training firmware */
static struct dram_cfg_param lpddr4_fsp0_cfg_1gb[] = {
{ 0xd0000, 0x0 },
{ 0x54000, 0x0 },
{ 0x54001, 0x0 },
{ 0x54002, 0x0 },
{ 0x54003, 0xbb8 },
{ 0x54004, 0x2 },
{ 0x54005, 0x2228 },
{ 0x54006, 0x11 },
{ 0x54007, 0x0 },
{ 0x54008, 0x131f },
{ 0x54009, 0xc8 },
{ 0x5400a, 0x0 },
{ 0x5400b, 0x2 },
{ 0x5400c, 0x0 },
{ 0x5400d, 0x0 },
{ 0x5400e, 0x0 },
{ 0x5400f, 0x0 },
{ 0x54010, 0x0 },
{ 0x54011, 0x0 },
{ 0x54012, 0x110 },
{ 0x54013, 0x0 },
{ 0x54014, 0x0 },
{ 0x54015, 0x0 },
{ 0x54016, 0x0 },
{ 0x54017, 0x0 },
{ 0x54018, 0x0 },
{ 0x54019, 0x2dd4 },
{ 0x5401a, 0x31 },
{ 0x5401b, 0x4d66 },
{ 0x5401c, 0x4d00 },
{ 0x5401d, 0x0 },
{ 0x5401e, 0x16 },
{ 0x5401f, 0x2dd4 },
{ 0x54020, 0x31 },
{ 0x54021, 0x4d66 },
{ 0x54022, 0x4d00 },
{ 0x54023, 0x0 },
{ 0x54024, 0x16 },
{ 0x54025, 0x0 },
{ 0x54026, 0x0 },
{ 0x54027, 0x0 },
{ 0x54028, 0x0 },
{ 0x54029, 0x0 },
{ 0x5402a, 0x0 },
{ 0x5402b, 0x1000 },
{ 0x5402c, 0x1 },
{ 0x5402d, 0x0 },
{ 0x5402e, 0x0 },
{ 0x5402f, 0x0 },
{ 0x54030, 0x0 },
{ 0x54031, 0x0 },
{ 0x54032, 0xd400 },
{ 0x54033, 0x312d },
{ 0x54034, 0x6600 },
@@ -2223,69 +2196,33 @@ static struct dram_cfg_param lpddr4_fsp0_cfg_1gb[] = {
{ 0x5403b, 0x4d },
{ 0x5403c, 0x4d },
{ 0x5403d, 0x1600 },
{ 0x5403e, 0x0 },
{ 0x5403f, 0x0 },
{ 0x54040, 0x0 },
{ 0x54041, 0x0 },
{ 0x54042, 0x0 },
{ 0x54043, 0x0 },
{ 0x54044, 0x0 },
{ 0xd0000, 0x1 },
};
/* P1 message block paremeter for training firmware */
static struct dram_cfg_param lpddr4_fsp1_cfg_1gb[] = {
{ 0xd0000, 0x0 },
{ 0x54000, 0x0 },
{ 0x54001, 0x0 },
{ 0x54002, 0x101 },
{ 0x54003, 0x190 },
{ 0x54004, 0x2 },
{ 0x54005, 0x2228 },
{ 0x54006, 0x11 },
{ 0x54007, 0x0 },
{ 0x54008, 0x121f },
{ 0x54009, 0xc8 },
{ 0x5400a, 0x0 },
{ 0x5400b, 0x2 },
{ 0x5400c, 0x0 },
{ 0x5400d, 0x0 },
{ 0x5400e, 0x0 },
{ 0x5400f, 0x0 },
{ 0x54010, 0x0 },
{ 0x54011, 0x0 },
{ 0x54012, 0x110 },
{ 0x54013, 0x0 },
{ 0x54014, 0x0 },
{ 0x54015, 0x0 },
{ 0x54016, 0x0 },
{ 0x54017, 0x0 },
{ 0x54018, 0x0 },
{ 0x54019, 0x84 },
{ 0x5401a, 0x31 },
{ 0x5401b, 0x4d66 },
{ 0x5401c, 0x4d00 },
{ 0x5401d, 0x0 },
{ 0x5401e, 0x16 },
{ 0x5401f, 0x84 },
{ 0x54020, 0x31 },
{ 0x54021, 0x4d66 },
{ 0x54022, 0x4d00 },
{ 0x54023, 0x0 },
{ 0x54024, 0x16 },
{ 0x54025, 0x0 },
{ 0x54026, 0x0 },
{ 0x54027, 0x0 },
{ 0x54028, 0x0 },
{ 0x54029, 0x0 },
{ 0x5402a, 0x0 },
{ 0x5402b, 0x1000 },
{ 0x5402c, 0x1 },
{ 0x5402d, 0x0 },
{ 0x5402e, 0x0 },
{ 0x5402f, 0x0 },
{ 0x54030, 0x0 },
{ 0x54031, 0x0 },
{ 0x54032, 0x8400 },
{ 0x54033, 0x3100 },
{ 0x54034, 0x6600 },
@@ -2298,69 +2235,33 @@ static struct dram_cfg_param lpddr4_fsp1_cfg_1gb[] = {
{ 0x5403b, 0x4d },
{ 0x5403c, 0x4d },
{ 0x5403d, 0x1600 },
{ 0x5403e, 0x0 },
{ 0x5403f, 0x0 },
{ 0x54040, 0x0 },
{ 0x54041, 0x0 },
{ 0x54042, 0x0 },
{ 0x54043, 0x0 },
{ 0x54044, 0x0 },
{ 0xd0000, 0x1 },
};
/* P2 message block paremeter for training firmware */
static struct dram_cfg_param lpddr4_fsp2_cfg_1gb[] = {
{ 0xd0000, 0x0 },
{ 0x54000, 0x0 },
{ 0x54001, 0x0 },
{ 0x54002, 0x102 },
{ 0x54003, 0x64 },
{ 0x54004, 0x2 },
{ 0x54005, 0x2228 },
{ 0x54006, 0x11 },
{ 0x54007, 0x0 },
{ 0x54008, 0x121f },
{ 0x54009, 0xc8 },
{ 0x5400a, 0x0 },
{ 0x5400b, 0x2 },
{ 0x5400c, 0x0 },
{ 0x5400d, 0x0 },
{ 0x5400e, 0x0 },
{ 0x5400f, 0x0 },
{ 0x54010, 0x0 },
{ 0x54011, 0x0 },
{ 0x54012, 0x110 },
{ 0x54013, 0x0 },
{ 0x54014, 0x0 },
{ 0x54015, 0x0 },
{ 0x54016, 0x0 },
{ 0x54017, 0x0 },
{ 0x54018, 0x0 },
{ 0x54019, 0x84 },
{ 0x5401a, 0x31 },
{ 0x5401b, 0x4d66 },
{ 0x5401c, 0x4d00 },
{ 0x5401d, 0x0 },
{ 0x5401e, 0x16 },
{ 0x5401f, 0x84 },
{ 0x54020, 0x31 },
{ 0x54021, 0x4d66 },
{ 0x54022, 0x4d00 },
{ 0x54023, 0x0 },
{ 0x54024, 0x16 },
{ 0x54025, 0x0 },
{ 0x54026, 0x0 },
{ 0x54027, 0x0 },
{ 0x54028, 0x0 },
{ 0x54029, 0x0 },
{ 0x5402a, 0x0 },
{ 0x5402b, 0x1000 },
{ 0x5402c, 0x1 },
{ 0x5402d, 0x0 },
{ 0x5402e, 0x0 },
{ 0x5402f, 0x0 },
{ 0x54030, 0x0 },
{ 0x54031, 0x0 },
{ 0x54032, 0x8400 },
{ 0x54033, 0x3100 },
{ 0x54034, 0x6600 },
@@ -2373,69 +2274,35 @@ static struct dram_cfg_param lpddr4_fsp2_cfg_1gb[] = {
{ 0x5403b, 0x4d },
{ 0x5403c, 0x4d },
{ 0x5403d, 0x1600 },
{ 0x5403e, 0x0 },
{ 0x5403f, 0x0 },
{ 0x54040, 0x0 },
{ 0x54041, 0x0 },
{ 0x54042, 0x0 },
{ 0x54043, 0x0 },
{ 0x54044, 0x0 },
{ 0xd0000, 0x1 },
};
/* P0 2D message block paremeter for training firmware */
static struct dram_cfg_param lpddr4_fsp0_2d_cfg_1gb[] = {
{ 0xd0000, 0x0 },
{ 0x54000, 0x0 },
{ 0x54001, 0x0 },
{ 0x54002, 0x0 },
{ 0x54003, 0xbb8 },
{ 0x54004, 0x2 },
{ 0x54005, 0x2228 },
{ 0x54006, 0x11 },
{ 0x54007, 0x0 },
{ 0x54008, 0x61 },
{ 0x54009, 0xc8 },
{ 0x5400a, 0x0 },
{ 0x5400b, 0x2 },
{ 0x5400c, 0x0 },
{ 0x5400d, 0x100 },
{ 0x5400e, 0x0 },
{ 0x5400f, 0x100 },
{ 0x54010, 0x1f7f },
{ 0x54011, 0x0 },
{ 0x54012, 0x110 },
{ 0x54013, 0x0 },
{ 0x54014, 0x0 },
{ 0x54015, 0x0 },
{ 0x54016, 0x0 },
{ 0x54017, 0x0 },
{ 0x54018, 0x0 },
{ 0x54019, 0x2dd4 },
{ 0x5401a, 0x31 },
{ 0x5401b, 0x4d66 },
{ 0x5401c, 0x4d00 },
{ 0x5401d, 0x0 },
{ 0x5401e, 0x16 },
{ 0x5401f, 0x2dd4 },
{ 0x54020, 0x31 },
{ 0x54021, 0x4d66 },
{ 0x54022, 0x4d00 },
{ 0x54023, 0x0 },
{ 0x54024, 0x16 },
{ 0x54025, 0x0 },
{ 0x54026, 0x0 },
{ 0x54027, 0x0 },
{ 0x54028, 0x0 },
{ 0x54029, 0x0 },
{ 0x5402a, 0x0 },
{ 0x5402b, 0x1000 },
{ 0x5402c, 0x1 },
{ 0x5402d, 0x0 },
{ 0x5402e, 0x0 },
{ 0x5402f, 0x0 },
{ 0x54030, 0x0 },
{ 0x54031, 0x0 },
{ 0x54032, 0xd400 },
{ 0x54033, 0x312d },
{ 0x54034, 0x6600 },
@@ -2448,13 +2315,6 @@ static struct dram_cfg_param lpddr4_fsp0_2d_cfg_1gb[] = {
{ 0x5403b, 0x4d },
{ 0x5403c, 0x4d },
{ 0x5403d, 0x1600 },
{ 0x5403e, 0x0 },
{ 0x5403f, 0x0 },
{ 0x54040, 0x0 },
{ 0x54041, 0x0 },
{ 0x54042, 0x0 },
{ 0x54043, 0x0 },
{ 0x54044, 0x0 },
{ 0xd0000, 0x1 },
};
@@ -2549,6 +2409,7 @@ static struct dram_cfg_param lpddr4_ddrc_cfg_4gb[] = {
{ 0x3d400204, 0x80808 },
{ 0x3d400214, 0x7070707 },
{ 0x3d400218, 0x7070707 },
{ 0x3d40021c, 0xf0f },
{ 0x3d400250, 0x29001701 },
{ 0x3d400254, 0x2c },
{ 0x3d40025c, 0x4000030 },
@@ -3065,6 +2926,7 @@ static struct dram_cfg_param lpddr4_ddrc_cfg_2gb[] = {
{ 0x3d400204, 0x80808 },
{ 0x3d400214, 0x7070707 },
{ 0x3d400218, 0x7070707 },
{ 0x3d40021c, 0xf0f },
{ 0x3d400250, 0x29001701 },
{ 0x3d400254, 0x2c },
{ 0x3d40025c, 0x4000030 },
@@ -3558,9 +3420,36 @@ static struct dram_cfg_param ddr_ddrphy_cfg_alt_patch[] = {
{ 0x120a5, 0x2 },
};
struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
/* 4GB single Die patch (MT53E1G32D2FW-046 revC) */
static struct dram_cfg_param ddr_ddrc_cfg_4gb_single_die_patch[] = {
{ 0x3d400000, 0xa1080020 },
{ 0x3d400064, 0x5b011d },
{ 0x3d40011c, 0x402 },
{ 0x3d400138, 0x123 },
{ 0x3d4000f4, 0x699 },
{ 0x3d400200, 0x1f },
{ 0x3d40021c, 0xf07 },
{ 0x3d402064, 0xc0026 },
{ 0x3d40211c, 0x302 },
{ 0x3d402138, 0x27 },
{ 0x3d4020f4, 0x599 },
{ 0x3d403064, 0x3000a },
{ 0x3d40311c, 0x302 },
{ 0x3d403138, 0xa },
{ 0x3d4030f4, 0x599 }
};
static struct dram_cfg_param fsp_msg_4gb_single_die_patch[] = {
{ 0x00054012, 0x110 },
{ 0x0005402c, 0x1 },
};
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
char *dram_desc, size_t sz_desc)
{
struct dram_timing_info *dram_timing;
int sizemb = (16 << info->sdram_size);
int i;
switch (sizemb) {
case 512:
@@ -3574,6 +3463,21 @@ struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
break;
case 4096:
dram_timing = &dram_timing_4gb;
if (info->sdram_variant == 1) {
if (dram_desc)
strlcpy(dram_desc, "single-die", sz_desc);
apply_cfg_patch(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num,
ddr_ddrc_cfg_4gb_single_die_patch,
ARRAY_SIZE(ddr_ddrc_cfg_4gb_single_die_patch));
for (i = 0; i < 4; i++) {
apply_cfg_patch(dram_timing->fsp_msg[i].fsp_cfg,
dram_timing->fsp_msg[i].fsp_cfg_num,
fsp_msg_4gb_single_die_patch,
ARRAY_SIZE(fsp_msg_4gb_single_die_patch));
}
} else if (dram_desc) {
strlcpy(dram_desc, "dual-die", sz_desc);
}
break;
default:
printf("unsupported");
@@ -3593,5 +3497,8 @@ struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
ARRAY_SIZE(ddr_ddrphy_cfg_alt_patch));
}
if (ddr_init(dram_timing))
return NULL;
return dram_timing;
}

View File

@@ -4,6 +4,8 @@
#include <string.h>
#include <asm/arch/ddr.h>
#include "eeprom.h"
/*
* Generated code from MX8M_DDR_tool v3.20 using RPAv15
*/
@@ -2369,26 +2371,36 @@ static struct dram_timing_info dram_timing_2gb_dual_die = {
.fsp_table = { 3200, 400, 100, },
};
struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
char *dram_desc, size_t sz_desc)
{
struct dram_timing_info *dram_timing;
int sizemb = (16 << info->sdram_size);
switch (sizemb) {
case 1024:
dram_timing = &dram_timing_1gb_single_die;
if (dram_desc)
strlcpy(dram_desc, "single-die", sz_desc);
break;
case 2048:
if (!strcmp(model, "GW7902-SP466-A") ||
!strcmp(model, "GW7902-SP466-B")) {
dram_timing = &dram_timing_2gb_dual_die;
if (dram_desc)
strlcpy(dram_desc, "dual-die", sz_desc);
} else {
dram_timing = &dram_timing_2gb_single_die;
if (dram_desc)
strlcpy(dram_desc, "single-die", sz_desc);
}
break;
default:
printf("unsupported");
dram_timing = &dram_timing_2gb_dual_die;
}
if (ddr_init(dram_timing))
return NULL;
return dram_timing;
}

View File

@@ -1,8 +1,11 @@
// SPDX-License-Identifier: GPL-2.0+
#include <linux/kernel.h>
#include <string.h>
#include <asm/arch/ddr.h>
#include "eeprom.h"
/*
* Generated code from MX8M_DDR_tool v3.30 using MX8M_Plus RPAv7
*/
@@ -2378,21 +2381,29 @@ static struct dram_timing_info dram_timing_4gb_dual_die = {
.fsp_table = { 4000, 400, 100, },
};
struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
char *dram_desc, size_t sz_desc)
{
struct dram_timing_info *dram_timing;
int sizemb = (16 << info->sdram_size);
switch (sizemb) {
case 1024:
dram_timing = &dram_timing_1gb_single_die;
if (dram_desc)
strlcpy(dram_desc, "single-die", sz_desc);
break;
case 4096:
dram_timing = &dram_timing_4gb_dual_die;
if (dram_desc)
strlcpy(dram_desc, "dual-die", sz_desc);
break;
default:
printf("unsupported");
dram_timing = &dram_timing_4gb_dual_die;
}
if (ddr_init(dram_timing))
return NULL;
return dram_timing;
}

View File

@@ -188,9 +188,10 @@ static int power_init_board(const char *model, struct udevice *gsc)
void board_init_f(ulong dummy)
{
struct dram_timing_info *dram_timing;
struct venice_board_info *eeprom;
struct udevice *bus, *dev;
const char *model;
int dram_szmb;
char dram_desc[32];
int i, ret;
arch_cpu_init();
@@ -249,23 +250,89 @@ void board_init_f(ulong dummy)
break;
mdelay(1);
}
dram_szmb = venice_eeprom_init(0);
eeprom = venice_eeprom_init(0);
model = eeprom_get_model();
/* PMIC */
power_init_board(model, dev);
/* DDR initialization */
printf("DRAM : LPDDR4 ");
if (dram_szmb > 512)
printf("%d GiB", dram_szmb / 1024);
else
printf("%d MiB", dram_szmb);
dram_timing = spl_dram_init(model, dram_szmb);
printf(" %dMT/s %dMHz\n",
dram_timing->fsp_msg[0].drate,
dram_timing->fsp_msg[0].drate / 2);
ddr_init(dram_timing);
dram_desc[0] = 0;
dram_timing = spl_dram_init(model, eeprom, dram_desc, sizeof(dram_desc));
if (dram_timing) {
int dram_szmb = (16 << eeprom->sdram_size);
printf("DRAM : LPDDR4 ");
if (dram_szmb > 512)
printf("%d GiB", dram_szmb / 1024);
else
printf("%d MiB", dram_szmb);
printf(" %dMT/s %dMHz %s",
dram_timing->fsp_msg[0].drate,
dram_timing->fsp_msg[0].drate / 2,
dram_desc[0] ? dram_desc : "");
#ifdef DEBUG
u8 mr[9] = { 0 };
/* Read MR5-MR8 to obtain details about DRAM part (and verify DRAM working) */
for (i = 5; i < 9; i++)
mr[i] = lpddr4_mr_read(0xf, i) & 0xff;
printf(" (0x%02x%02x%02x%02x", mr[5], mr[6], mr[7], mr[8]);
/* MR5 MFG_ID */
switch (mr[5]) {
case 0xff:
printf(" Micron");
break;
default:
break;
}
/* MR8 OP[7:6] Width */
i = 0;
switch ((mr[8] >> 6) & 0x3) {
case 0:
i = 16;
break;
case 1:
i = 8;
break;
}
if (i)
printf(" x%d", i);
/* MR8 OP[5:2] Density */
i = 0;
switch ((mr[8] >> 2) & 0xf) {
case 0:
i = 4;
break;
case 1:
i = 6;
break;
case 2:
i = 8;
break;
case 3:
i = 12;
break;
case 4:
i = 16;
break;
case 5:
i = 24;
break;
case 6:
i = 32;
break;
default:
break;
}
if (i)
printf(" %dGb per die", i);
#endif
puts(")\n");
} else {
hang();
}
board_init_r(NULL, 0);
}

View File

@@ -1,82 +1,28 @@
#include <env/phytec/rauc.env>
#include <env/phytec/overlays.env>
bootcmd=
if test ${dofastboot} = 1; then
fastboot 0;
fi;
mmc dev ${mmcdev};
if mmc rescan; then
run spiprobe;
if test ${doraucboot} = 1; then
run raucinit;
fi;
if run loadimage; then
run mmcboot;
else
run netboot;
fi;
fi;
console=ttymxc0,115200
bootflow scan -lb;
bootmeths=script efi
boot_targets=mmc2 mmc1 usb ethernet
bootenv_addr_r=0x49100000
fdtoverlay_addr_r=0x49000000
boot_script_dhcp=boot.scr.uimg
console=ttymxc0,115200
dofastboot=0
emmc_dev=2
fastboot_raw_partition_all=0 4194304
fastboot_raw_partition_bootloader=64 8128
fdt_addr_r=0x48000000
fdtfile=CONFIG_DEFAULT_FDT_FILE
image=Image
fdtoverlay_addr_r=0x49000000
ip_dyn=yes
kernel_addr_r=0x5A080000
kernel_comp_addr_r=0x60000000
kernel_comp_size=0x2000000
mtdparts=30bb0000.spi:3840k(u-boot),128k(env),128k(env_redund),-(none)
mtdids=nor0=30bb0000.spi
spiprobe=true
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
mmcargs=
setenv bootargs ${mcore_clk} console=${console}
root=/dev/mmcblk${mmcdev}p${mmcroot} ${raucargs} rootwait rw
mmcautodetect=yes
mmcboot=
echo Booting from mmc ...;
if test ${no_bootenv} = 0; then
if run mmc_load_bootenv; then
env import -t ${bootenv_addr_r} ${filesize};
fi;
fi;
run mmcargs;
if run loadfdt; then
run mmc_apply_overlays;
booti ${loadaddr} - ${fdt_addr_r};
else
echo WARN: Cannot load the DT;
fi;
mmcdev=CONFIG_ENV_MMC_DEVICE_INDEX
mmcpart=1
mmcroot=2
netargs=
setenv bootargs ${mcore_clk} console=${console} root=/dev/nfs ip=dhcp
nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=
echo Booting from net ...;
if test ${ip_dyn} = yes; then
setenv get_cmd dhcp;
else
setenv get_cmd tftp;
fi;
if test ${no_bootenv} = 0; then
if run net_load_bootenv; then
env import -t ${bootenv_addr_r} ${filesize};
fi;
fi;
${get_cmd} ${loadaddr} ${image};
run netargs;
if ${get_cmd} ${fdt_addr_r} ${fdtfile}; then
run net_apply_overlays;
booti ${loadaddr} - ${fdt_addr_r};
else
echo WARN: Cannot load the DT;
fi;
nfsroot=/srv/nfs
prepare_mcore=setenv mcore_clk clk-imx8mp.mcore_booted
sd_dev=1
pxefile_addr_r=0x58600000
ramdisk_addr_r=0x5E000000
scriptaddr=0x40000000

View File

@@ -371,6 +371,13 @@ config SPL_IMX_CONTAINER_USE_TRAMPOLINE
help
Enable SPL load reader to load data to a trampoline buffer.
config IMX_PQC_SUPPORT
bool "Enable to support i.MX ROM PQC Container"
depends on SPL && SPL_LOAD_IMX_CONTAINER
help
Support i.MX ROM new PQC container format. If your chip does not use
PQC container, say 'n'.
config IMX_CONTAINER_CFG
string "i.MX8 Container config file"
depends on SPL && SPL_LOAD_IMX_CONTAINER

View File

@@ -80,7 +80,7 @@ CONFIG_BOOTCOUNT_ALTBOOTCMD="setenv b_mode 0; run b_default;"
CONFIG_SYS_I2C_MXC=y
CONFIG_MMC_BROKEN_CD=y
# CONFIG_SPL_DM_MMC is not set
CONFIG_FSL_ESDHC=y
CONFIG_FSL_ESDHC_IMX=y
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y

View File

@@ -31,10 +31,13 @@ CONFIG_IMX_BOOTAUX=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_FIT_SIGNATURE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_BOOTSTD_FULL=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_FDT_FIXUP_PARTITIONS=y
# CONFIG_USE_BOOTCOMMAND is not set
CONFIG_DEFAULT_FDT_FILE="oftree"
CONFIG_SYS_CBSIZE=2048
CONFIG_SYS_PBSIZE=2074
@@ -57,9 +60,11 @@ CONFIG_SPL_NOR_SUPPORT=y
CONFIG_SPL_POWER=y
CONFIG_SPL_SPI_FLASH_MTD=y
CONFIG_SPL_WATCHDOG=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="u-boot=> "
# CONFIG_CMD_VBE is not set
CONFIG_CMD_BOOTEFI_SELFTEST=y
CONFIG_CMD_ERASEENV=y
CONFIG_CMD_NVEDIT_EFI=y
# CONFIG_CMD_CRC32 is not set
CONFIG_CMD_EEPROM=y
CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
@@ -76,17 +81,12 @@ CONFIG_CMD_SF_TEST=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_MTDPARTS=y
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
@@ -172,7 +172,6 @@ CONFIG_USB_XHCI_DWC3_OF_SIMPLE=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="PHYTEC"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525

View File

@@ -23,9 +23,9 @@ Note: srctree is U-Boot source directory
.. code-block:: bash
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-1.3.0-17945fc.bin
$ sh firmware-ele-imx-1.3.0-17945fc.bin --auto-accept
$ cp firmware-ele-imx-1.3.0-17945fc/mx95a0-ahab-container.img $(srctree)
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-2.0.2-89161a8.bin
$ sh firmware-ele-imx-2.0.2-89161a8.bin --auto-accept
$ cp firmware-ele-imx-2.0.2-89161a8/mx95b0-ahab-container.img $(srctree)
Get DDR PHY Firmware Images
--------------------------------------
@@ -34,9 +34,9 @@ Note: srctree is U-Boot source directory
.. code-block:: bash
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.26-d4c33ab.bin
$ sh firmware-imx-8.26-d4c33ab.bin --auto-accept
$ cp firmware-imx-8.26-d4c33ab/firmware/ddr/synopsys/lpddr5*v202311.bin $(srctree)
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.28-994fa14.bin
$ sh firmware-imx-8.28-994fa14.bin --auto-accept
$ cp firmware-imx-8.28-994fa14/firmware/ddr/synopsys/lpddr5*v202409.bin $(srctree)
Get and Build OEI Images
--------------------------------------

View File

@@ -302,28 +302,6 @@ config FSL_IIM
bool "Enable FSL IC Identification Module (IIM) driver"
depends on ARCH_MX5
config FSL_SEC_MON
bool "Enable FSL SEC_MON Driver"
help
Freescale Security Monitor block is responsible for monitoring
system states.
Security Monitor can be transitioned on any security failures,
like software violations or hardware security violations.
choice
prompt "Security monitor interaction endianess"
depends on FSL_SEC_MON
default SYS_FSL_SEC_MON_BE if PPC
default SYS_FSL_SEC_MON_LE
config SYS_FSL_SEC_MON_LE
bool "Security monitor interactions are little endian"
config SYS_FSL_SEC_MON_BE
bool "Security monitor interactions are big endian"
endchoice
config IRQ
bool "Interrupt controller"
help

View File

@@ -333,15 +333,6 @@ config MMC_MESON_GX
help
Support for EMMC host controller on Meson GX ARM SoCs platform (S905)
config MMC_MXC
bool "Freescale i.MX21/27/31 or MPC512x Multimedia Card support"
help
This selects the Freescale i.MX21, i.MX27, i.MX31 or MPC512x
Multimedia Card Interface. If you have an i.MX or MPC512x platform
with a Multimedia Card slot, say Y here.
If unsure, say N.
config MMC_OWL
bool "Actions OWL Multimedia Card Interface support"
depends on ARCH_OWL

View File

@@ -41,7 +41,6 @@ obj-$(CONFIG_MMC_MESON_GX) += meson_gx_mmc.o
obj-$(CONFIG_MMC_SPI) += mmc_spi.o
obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o
obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_MXS) += mxsmmc.o
obj-$(CONFIG_MMC_OCTEONTX) += octeontx_hsmmc.o
obj-$(CONFIG_MMC_OWL) += owl_mmc.o

View File

@@ -1,523 +0,0 @@
/*
* This is a driver for the SDHC controller found in Freescale MX2/MX3
* SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
* Unlike the hardware found on MX1, this hardware just works and does
* not need all the quirks found in imxmmc.c, hence the seperate driver.
*
* Copyright (C) 2009 Ilya Yanok, <yanok@emcraft.com>
* Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
* Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
*
* derived from pxamci.c by Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <config.h>
#include <command.h>
#include <mmc.h>
#include <part.h>
#include <malloc.h>
#include <mmc.h>
#include <time.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#define DRIVER_NAME "mxc-mmc"
struct mxcmci_regs {
u32 str_stp_clk;
u32 status;
u32 clk_rate;
u32 cmd_dat_cont;
u32 res_to;
u32 read_to;
u32 blk_len;
u32 nob;
u32 rev_no;
u32 int_cntr;
u32 cmd;
u32 arg;
u32 pad;
u32 res_fifo;
u32 buffer_access;
};
#define STR_STP_CLK_RESET (1 << 3)
#define STR_STP_CLK_START_CLK (1 << 1)
#define STR_STP_CLK_STOP_CLK (1 << 0)
#define STATUS_CARD_INSERTION (1 << 31)
#define STATUS_CARD_REMOVAL (1 << 30)
#define STATUS_YBUF_EMPTY (1 << 29)
#define STATUS_XBUF_EMPTY (1 << 28)
#define STATUS_YBUF_FULL (1 << 27)
#define STATUS_XBUF_FULL (1 << 26)
#define STATUS_BUF_UND_RUN (1 << 25)
#define STATUS_BUF_OVFL (1 << 24)
#define STATUS_SDIO_INT_ACTIVE (1 << 14)
#define STATUS_END_CMD_RESP (1 << 13)
#define STATUS_WRITE_OP_DONE (1 << 12)
#define STATUS_DATA_TRANS_DONE (1 << 11)
#define STATUS_READ_OP_DONE (1 << 11)
#define STATUS_WR_CRC_ERROR_CODE_MASK (3 << 10)
#define STATUS_CARD_BUS_CLK_RUN (1 << 8)
#define STATUS_BUF_READ_RDY (1 << 7)
#define STATUS_BUF_WRITE_RDY (1 << 6)
#define STATUS_RESP_CRC_ERR (1 << 5)
#define STATUS_CRC_READ_ERR (1 << 3)
#define STATUS_CRC_WRITE_ERR (1 << 2)
#define STATUS_TIME_OUT_RESP (1 << 1)
#define STATUS_TIME_OUT_READ (1 << 0)
#define STATUS_ERR_MASK 0x2f
#define CMD_DAT_CONT_CMD_RESP_LONG_OFF (1 << 12)
#define CMD_DAT_CONT_STOP_READWAIT (1 << 11)
#define CMD_DAT_CONT_START_READWAIT (1 << 10)
#define CMD_DAT_CONT_BUS_WIDTH_4 (2 << 8)
#define CMD_DAT_CONT_INIT (1 << 7)
#define CMD_DAT_CONT_WRITE (1 << 4)
#define CMD_DAT_CONT_DATA_ENABLE (1 << 3)
#define CMD_DAT_CONT_RESPONSE_48BIT_CRC (1 << 0)
#define CMD_DAT_CONT_RESPONSE_136BIT (2 << 0)
#define CMD_DAT_CONT_RESPONSE_48BIT (3 << 0)
#define INT_SDIO_INT_WKP_EN (1 << 18)
#define INT_CARD_INSERTION_WKP_EN (1 << 17)
#define INT_CARD_REMOVAL_WKP_EN (1 << 16)
#define INT_CARD_INSERTION_EN (1 << 15)
#define INT_CARD_REMOVAL_EN (1 << 14)
#define INT_SDIO_IRQ_EN (1 << 13)
#define INT_DAT0_EN (1 << 12)
#define INT_BUF_READ_EN (1 << 4)
#define INT_BUF_WRITE_EN (1 << 3)
#define INT_END_CMD_RES_EN (1 << 2)
#define INT_WRITE_OP_DONE_EN (1 << 1)
#define INT_READ_OP_EN (1 << 0)
struct mxcmci_host {
struct mmc *mmc;
struct mxcmci_regs *base;
int irq;
int detect_irq;
int dma;
int do_dma;
unsigned int power_mode;
struct mmc_cmd *cmd;
struct mmc_data *data;
unsigned int dma_nents;
unsigned int datasize;
unsigned int dma_dir;
u16 rev_no;
unsigned int cmdat;
int clock;
};
static struct mxcmci_host mxcmci_host;
/* maintainer note: do we really want to have a global host pointer? */
static struct mxcmci_host *host = &mxcmci_host;
static inline int mxcmci_use_dma(struct mxcmci_host *host)
{
return host->do_dma;
}
static void mxcmci_softreset(struct mxcmci_host *host)
{
int i;
/* reset sequence */
writel(STR_STP_CLK_RESET, &host->base->str_stp_clk);
writel(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
&host->base->str_stp_clk);
for (i = 0; i < 8; i++)
writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
writel(0xff, &host->base->res_to);
}
static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
{
unsigned int nob = data->blocks;
unsigned int blksz = data->blocksize;
unsigned int datasize = nob * blksz;
host->data = data;
writel(nob, &host->base->nob);
writel(blksz, &host->base->blk_len);
host->datasize = datasize;
}
static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_cmd *cmd,
unsigned int cmdat)
{
if (host->cmd != NULL)
printf("mxcmci: error!\n");
host->cmd = cmd;
switch (cmd->resp_type) {
case MMC_RSP_R1: /* short CRC, OPCODE */
case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */
cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
break;
case MMC_RSP_R2: /* long 136 bit + CRC */
cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
break;
case MMC_RSP_R3: /* short */
cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
break;
case MMC_RSP_NONE:
break;
default:
printf("mxcmci: unhandled response type 0x%x\n",
cmd->resp_type);
return -EINVAL;
}
writel(cmd->cmdidx, &host->base->cmd);
writel(cmd->cmdarg, &host->base->arg);
writel(cmdat, &host->base->cmd_dat_cont);
return 0;
}
static void mxcmci_finish_request(struct mxcmci_host *host,
struct mmc_cmd *cmd, struct mmc_data *data)
{
host->cmd = NULL;
host->data = NULL;
}
static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
{
int data_error = 0;
if (stat & STATUS_ERR_MASK) {
printf("request failed. status: 0x%08x\n",
stat);
if (stat & STATUS_CRC_READ_ERR) {
data_error = -EILSEQ;
} else if (stat & STATUS_CRC_WRITE_ERR) {
u32 err_code = (stat >> 9) & 0x3;
if (err_code == 2) /* No CRC response */
data_error = -ETIMEDOUT;
else
data_error = -EILSEQ;
} else if (stat & STATUS_TIME_OUT_READ) {
data_error = -ETIMEDOUT;
} else {
data_error = -EIO;
}
}
host->data = NULL;
return data_error;
}
static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
{
struct mmc_cmd *cmd = host->cmd;
int i;
u32 a, b, c;
u32 *resp = (u32 *)cmd->response;
if (!cmd)
return 0;
if (stat & STATUS_TIME_OUT_RESP) {
printf("CMD TIMEOUT\n");
return -ETIMEDOUT;
} else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) {
printf("cmd crc error\n");
return -EILSEQ;
}
if (cmd->resp_type & MMC_RSP_PRESENT) {
if (cmd->resp_type & MMC_RSP_136) {
for (i = 0; i < 4; i++) {
a = readl(&host->base->res_fifo) & 0xFFFF;
b = readl(&host->base->res_fifo) & 0xFFFF;
resp[i] = a << 16 | b;
}
} else {
a = readl(&host->base->res_fifo) & 0xFFFF;
b = readl(&host->base->res_fifo) & 0xFFFF;
c = readl(&host->base->res_fifo) & 0xFFFF;
resp[0] = a << 24 | b << 8 | c >> 8;
}
}
return 0;
}
static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
{
u32 stat;
unsigned long timeout = get_ticks() + CONFIG_SYS_HZ;
do {
stat = readl(&host->base->status);
if (stat & STATUS_ERR_MASK)
return stat;
if (timeout < get_ticks())
return STATUS_TIME_OUT_READ;
if (stat & mask)
return 0;
} while (1);
}
static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
{
unsigned int stat;
u32 *buf = _buf;
while (bytes > 3) {
stat = mxcmci_poll_status(host,
STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
if (stat)
return stat;
*buf++ = readl(&host->base->buffer_access);
bytes -= 4;
}
if (bytes) {
u8 *b = (u8 *)buf;
u32 tmp;
stat = mxcmci_poll_status(host,
STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
if (stat)
return stat;
tmp = readl(&host->base->buffer_access);
memcpy(b, &tmp, bytes);
}
return 0;
}
static int mxcmci_push(struct mxcmci_host *host, const void *_buf, int bytes)
{
unsigned int stat;
const u32 *buf = _buf;
while (bytes > 3) {
stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
if (stat)
return stat;
writel(*buf++, &host->base->buffer_access);
bytes -= 4;
}
if (bytes) {
const u8 *b = (u8 *)buf;
u32 tmp;
stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
if (stat)
return stat;
memcpy(&tmp, b, bytes);
writel(tmp, &host->base->buffer_access);
}
stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
if (stat)
return stat;
return 0;
}
static int mxcmci_transfer_data(struct mxcmci_host *host)
{
struct mmc_data *data = host->data;
int stat;
unsigned long length;
length = data->blocks * data->blocksize;
host->datasize = 0;
if (data->flags & MMC_DATA_READ) {
stat = mxcmci_pull(host, data->dest, length);
if (stat)
return stat;
host->datasize += length;
} else {
stat = mxcmci_push(host, (const void *)(data->src), length);
if (stat)
return stat;
host->datasize += length;
stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
if (stat)
return stat;
}
return 0;
}
static int mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
{
int datastat;
int ret;
ret = mxcmci_read_response(host, stat);
if (ret) {
mxcmci_finish_request(host, host->cmd, host->data);
return ret;
}
if (!host->data) {
mxcmci_finish_request(host, host->cmd, host->data);
return 0;
}
datastat = mxcmci_transfer_data(host);
ret = mxcmci_finish_data(host, datastat);
mxcmci_finish_request(host, host->cmd, host->data);
return ret;
}
static int mxcmci_request(struct mmc *mmc, struct mmc_cmd *cmd,
struct mmc_data *data)
{
struct mxcmci_host *host = mmc->priv;
unsigned int cmdat = host->cmdat;
u32 stat;
int ret;
host->cmdat &= ~CMD_DAT_CONT_INIT;
if (data) {
mxcmci_setup_data(host, data);
cmdat |= CMD_DAT_CONT_DATA_ENABLE;
if (data->flags & MMC_DATA_WRITE)
cmdat |= CMD_DAT_CONT_WRITE;
}
if ((ret = mxcmci_start_cmd(host, cmd, cmdat))) {
mxcmci_finish_request(host, cmd, data);
return ret;
}
do {
stat = readl(&host->base->status);
writel(stat, &host->base->status);
} while (!(stat & STATUS_END_CMD_RESP));
return mxcmci_cmd_done(host, stat);
}
static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
{
unsigned int divider;
int prescaler = 0;
unsigned long clk_in = mxc_get_clock(MXC_ESDHC_CLK);
while (prescaler <= 0x800) {
for (divider = 1; divider <= 0xF; divider++) {
int x;
x = (clk_in / (divider + 1));
if (prescaler)
x /= (prescaler * 2);
if (x <= clk_ios)
break;
}
if (divider < 0x10)
break;
if (prescaler == 0)
prescaler = 1;
else
prescaler <<= 1;
}
writel((prescaler << 4) | divider, &host->base->clk_rate);
}
static int mxcmci_set_ios(struct mmc *mmc)
{
struct mxcmci_host *host = mmc->priv;
if (mmc->bus_width == 4)
host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
else
host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
if (mmc->clock) {
mxcmci_set_clk_rate(host, mmc->clock);
writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
} else {
writel(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk);
}
host->clock = mmc->clock;
return 0;
}
static int mxcmci_init(struct mmc *mmc)
{
struct mxcmci_host *host = mmc->priv;
mxcmci_softreset(host);
host->rev_no = readl(&host->base->rev_no);
if (host->rev_no != 0x400) {
printf("wrong rev.no. 0x%08x. aborting.\n",
host->rev_no);
return -ENODEV;
}
/* recommended in data sheet */
writel(0x2db4, &host->base->read_to);
writel(0, &host->base->int_cntr);
return 0;
}
static const struct mmc_ops mxcmci_ops = {
.send_cmd = mxcmci_request,
.set_ios = mxcmci_set_ios,
.init = mxcmci_init,
};
static struct mmc_config mxcmci_cfg = {
.name = "MXC MCI",
.ops = &mxcmci_ops,
.host_caps = MMC_MODE_4BIT,
.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
};
static int mxcmci_initialize(struct bd_info *bis)
{
host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
mxcmci_cfg.f_min = mxc_get_clock(MXC_ESDHC_CLK) >> 7;
mxcmci_cfg.f_max = mxc_get_clock(MXC_ESDHC_CLK) >> 1;
host->mmc = mmc_create(&mxcmci_cfg, host);
if (host->mmc == NULL)
return -1;
return 0;
}
int mxc_mmc_init(struct bd_info *bis)
{
return mxcmci_initialize(bis);
}

View File

@@ -45,6 +45,7 @@
#define DCD_ENTRY_ADDR_IN_SCFW 0x240
#define CONTAINER_ALIGNMENT 0x400
#define CONTAINER_PQC_ALIGNMENT 0x4000
#define CONTAINER_FLAGS_DEFAULT 0x10
#define CONTAINER_FUSE_DEFAULT 0x0
@@ -160,6 +161,8 @@ enum imx8image_cmd {
CMD_DATA,
CMD_DUMMY_V2X,
CMD_HOLD,
CMD_CNTR_VERSION,
CMD_DUMMY_DDR,
};
enum imx8image_core_type {
@@ -216,6 +219,8 @@ typedef enum option_type {
OEI,
DUMMY_V2X,
HOLD,
CNTR_VERSION,
DUMMY_DDR,
} option_type_t;
typedef struct {
@@ -262,6 +267,7 @@ typedef struct {
#define IMG_TYPE_SENTINEL 0x06 /* SENTINEL image type */
#define IMG_TYPE_PROV 0x07 /* Provisioning image type */
#define IMG_TYPE_DEK 0x08 /* DEK validation type */
#define IMG_TYPE_DDR_DUMMY 0x0D /* DDR training data dummy entry */
#define IMG_TYPE_V2X_DUMMY 0x0E /* V2X Dummy image */
#define IMG_TYPE_SHIFT 0

View File

@@ -12,7 +12,11 @@
#define IV_MAX_LEN 32
#define HASH_MAX_LEN 64
#if IS_ENABLED(CONFIG_IMX_PQC_SUPPORT)
#define CONTAINER_HDR_ALIGNMENT 0x4000
#else
#define CONTAINER_HDR_ALIGNMENT 0x400
#endif
#define CONTAINER_HDR_EMMC_OFFSET 0
#define CONTAINER_HDR_MMCSD_OFFSET SZ_32K
#define CONTAINER_HDR_QSPI_OFFSET SZ_4K
@@ -72,7 +76,14 @@ int get_container_size(ulong addr, u16 *header_length);
static inline bool valid_container_hdr(struct container_hdr *container)
{
#if IS_ENABLED(CONFIG_IMX_PQC_SUPPORT)
return (container->tag == CONTAINER_HDR_TAG ||
container->tag == 0x82) &&
(container->version == CONTAINER_HDR_VERSION ||
container->version == 0x2);
#else
return container->tag == CONTAINER_HDR_TAG &&
container->version == CONTAINER_HDR_VERSION;
#endif
}
#endif

View File

@@ -19,6 +19,7 @@ static bool dcd_skip;
static image_t param_stack[IMG_STACK_SIZE];
static uint8_t fuse_version;
static uint16_t sw_version;
static uint8_t cntr_version;
static uint32_t custom_partition;
static uint32_t scfw_flags;
@@ -57,6 +58,8 @@ static table_entry_t imx8image_cmds[] = {
{CMD_DATA, "DATA", "new data", },
{CMD_DUMMY_V2X, "DUMMY_V2X", "v2x", },
{CMD_HOLD, "HOLD", "hold", },
{CMD_CNTR_VERSION, "CNTR_VERSION", "cntr version", },
{CMD_DUMMY_DDR, "DUMMY_DDR", "ddr", },
{-1, "", "", }
};
@@ -157,6 +160,10 @@ static void parse_cfg_cmd(image_t *param_stack, int32_t cmd, char *token,
param_stack[p_idx].option = HOLD;
param_stack[p_idx].entry = (uint32_t)strtoll(token, NULL, 0);
param_stack[p_idx++].filename = NULL;
break;
case CMD_CNTR_VERSION:
cntr_version = (uint8_t)(strtoll(token, NULL, 0) & 0xFF);
break;
default:
break;
}
@@ -177,6 +184,8 @@ static void parse_cfg_fld(image_t *param_stack, int32_t *cmd, char *token,
if (*cmd == CMD_CONTAINER) {
fprintf(stdout, "New Container: \t%d\n", ++container);
param_stack[p_idx++].option = NEW_CONTAINER;
} else if (*cmd == CMD_DUMMY_DDR) {
param_stack[p_idx++].option = DUMMY_DDR;
}
break;
case CFG_CORE_TYPE:
@@ -588,7 +597,8 @@ static void set_image_array_entry(flash_header_v3_t *container,
img->offset = offset; /* Is re-adjusted later */
img->size = size;
if (type != DUMMY_V2X) {
/* skip hash generation here if dummy image */
if (type != DUMMY_V2X && type != DUMMY_DDR) {
set_image_hash(img, tmp_filename, IMAGE_HASH_ALGO_DEFAULT);
}
@@ -632,6 +642,15 @@ static void set_image_array_entry(flash_header_v3_t *container,
img->entry = entry;
img->meta = meta;
custom_partition = 0;
if (container->num_images) {
/* if at least 2 images in container, [0] and [1] */
boot_img_t *ddr_dummy = &container->img[container->num_images - 1];
if ((ddr_dummy->hab_flags & 0x0F) == IMG_TYPE_DDR_DUMMY) {
ddr_dummy->offset = img->offset + img->size;
set_image_hash(ddr_dummy, "/dev/null", IMAGE_HASH_ALGO_DEFAULT);
}
}
break;
case AP:
if (soc == QX && core == CORE_CA35) {
@@ -751,6 +770,11 @@ static void set_image_array_entry(flash_header_v3_t *container,
img->entry = entry;
img->size = 0; /* dummy image has no size */
break;
case DUMMY_DDR:
img->hab_flags |= IMG_TYPE_DDR_DUMMY;
tmp_name = "DDR Dummy";
img->size = 0; /* dummy image has no size */
break;
default:
fprintf(stderr, "unrecognized image type (%d)\n", type);
exit(EXIT_FAILURE);
@@ -776,22 +800,27 @@ void set_container(flash_header_v3_t *container, uint16_t sw_version,
static int get_container_image_start_pos(image_t *image_stack, uint32_t align, uint32_t *v2x)
{
image_t *img_sp = image_stack;
/*8K total container header*/
int file_off = CONTAINER_IMAGE_ARRAY_START_OFFSET;
/*
* 8K total container header for legacy container, for version 2
* container, the total container header is 0x4000 * 3 = 0xC000.
*/
int file_off = cntr_version ? 0xC000 : CONTAINER_IMAGE_ARRAY_START_OFFSET;
size_t size = cntr_version ? SZ_32K : SZ_4K;
uint32_t cntr_header_len = cntr_version ? CONTAINER_PQC_ALIGNMENT : FIRST_CONTAINER_HEADER_LENGTH;
FILE *fd = NULL;
flash_header_v3_t *header;
flash_header_v3_t *header2;
void *p;
int ret;
p = calloc(1, SZ_4K);
p = calloc(1, size);
if (!p) {
fprintf(stderr, "Fail to alloc 4K memory\n");
fprintf(stderr, "Fail to alloc %lx memory\n", size);
exit(EXIT_FAILURE);
}
header = p;
header2 = p + FIRST_CONTAINER_HEADER_LENGTH;
header2 = p + cntr_header_len;
while (img_sp->option != NO_IMG) {
if (img_sp->option == APPEND) {
@@ -801,7 +830,7 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align, u
exit(EXIT_FAILURE);
}
ret = fread(header, SZ_4K, 1, fd);
ret = fread(header, size, 1, fd);
if (ret != 1) {
printf("Failure Read header %d\n", ret);
exit(EXIT_FAILURE);
@@ -813,11 +842,11 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align, u
fprintf(stderr, "header tag mismatched \n");
exit(EXIT_FAILURE);
} else {
if (header2->tag != IVT_HEADER_TAG_B0) {
if ((header2->tag != IVT_HEADER_TAG_B0) && (header2->tag != 0x82)) {
file_off += header->img[header->num_images - 1].size;
file_off = ALIGN(file_off, align);
} else {
file_off = header2->img[header2->num_images - 1].offset + FIRST_CONTAINER_HEADER_LENGTH;
file_off = header2->img[header2->num_images - 1].offset + cntr_header_len;
file_off += header2->img[header2->num_images - 1].size;
file_off = ALIGN(file_off, align);
fprintf(stderr, "Has 2nd container %x\n", file_off);
@@ -839,7 +868,7 @@ static void set_imx_hdr_v3(imx_header_v3_t *imxhdr, uint32_t cont_id)
/* Set magic number, Only >= B0 supported */
fhdr_v3->tag = IVT_HEADER_TAG_B0;
fhdr_v3->version = IVT_VERSION_B0;
fhdr_v3->version = cntr_version ? 0x2 : IVT_VERSION_B0;
}
static uint8_t *flatten_container_header(imx_header_v3_t *imx_header,
@@ -921,6 +950,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
char *tmp_filename = NULL;
uint32_t size = 0;
uint32_t file_padding = 0;
uint32_t cntr_header_len = cntr_version ? CONTAINER_PQC_ALIGNMENT : FIRST_CONTAINER_HEADER_LENGTH;
uint32_t v2x = false;
int ret;
@@ -978,6 +1008,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
break;
case DUMMY_V2X:
case DUMMY_DDR:
if (container < 0) {
fprintf(stderr, "No container found\n");
exit(EXIT_FAILURE);
@@ -1023,7 +1054,7 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
case NEW_CONTAINER:
container++;
set_container(&imx_header.fhdr[container], sw_version,
CONTAINER_ALIGNMENT,
cntr_version ? CONTAINER_PQC_ALIGNMENT : CONTAINER_ALIGNMENT,
CONTAINER_FLAGS_DEFAULT,
fuse_version);
scfw_flags = 0;
@@ -1073,9 +1104,9 @@ static int build_container(soc_type_t soc, uint32_t sector_size,
if (img_sp->option == APPEND) {
copy_file(ofd, img_sp->filename, 0, 0);
if (v2x)
file_padding += FIRST_CONTAINER_HEADER_LENGTH * 2;
file_padding += cntr_header_len * 2;
else
file_padding += FIRST_CONTAINER_HEADER_LENGTH;
file_padding += cntr_header_len;
}
img_sp++;
} while (img_sp->option != NO_IMG);