From 355c620666c205b55164aeb16f86b775f8c5d1fd Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Wed, 5 Jun 2019 11:26:12 +0800 Subject: [PATCH 01/51] driver: ddr: imx: skip ddr_ss_gpr config on imx8mn There is no DDR_SS_GPR0 exits on i.MX8MN, so skip setting this register on i.MX8MN. Signed-off-by: Jacky Bai Signed-off-by: Peng Fan --- drivers/ddr/imx/imx8m/ddr_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index bbddee6ca89..1c5c7f99cff 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -74,7 +74,7 @@ int ddr_init(struct dram_timing_info *dram_timing) /* if ddr type is LPDDR4, do it */ tmp = reg32_read(DDRC_MSTR(0)); - if (tmp & (0x1 << 5)) + if (tmp & (0x1 << 5) && !is_imx8mn()) reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */ /* determine the initial boot frequency */ From 1eb325af16e2a6987f4aa91e563ad6c160f64a5a Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Mon, 10 Feb 2020 18:02:00 +0800 Subject: [PATCH 02/51] driver: ddr: imx: correct the pwrctl setting of selfref_en on imx8m The 'selfref_en' should be bit'0', so correct the setting to enable the auto self-refresh. Reviewed-by: Jian Li Reviewed-by: Ye Li Signed-off-by: Jacky Bai Signed-off-by: Peng Fan --- drivers/ddr/imx/imx8m/ddr_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index 1c5c7f99cff..de302937d08 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -163,7 +163,7 @@ int ddr_init(struct dram_timing_info *dram_timing) /* Step26: Set back register in Step4 to the original values if desired */ reg32_write(DDRC_RFSHCTL3(0), 0x0000000); /* enable selfref_en by default */ - setbits_le32(DDRC_PWRCTL(0), 0x1 << 3); + setbits_le32(DDRC_PWRCTL(0), 0x1); /* enable port 0 */ reg32_write(DDRC_PCTRL_0(0), 0x00000001); From f3acb02386f4d5df6e5b5eb96302f169c28933db Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Mon, 20 Jan 2020 11:13:14 +0800 Subject: [PATCH 03/51] drivers: ddr: imx8mp: Add inline ECC feature support the DRAM Controller in i.MX8MP will support a feature called "Inline ECC". This is supported for all 3 supported DRAM technologies (LPDDR4, DDR4 and DDR3L). When this feature is enabled by software, the DRAM Controller reserves 12.5% of DRAM capacity for ECC information, and presents only the non-ECC portion (lower 87.5% of the installed capacity of DRAM) to the rest of the SoC. The DRAM memory can be divided into 8 regions so that if a use case only requires ECC protection on a subset of memory, then only that subset of memory need support inline ECC. If this occurs, then there is no performance penalty accessing the non-ECC-protected memory (no need to access ECC for this portion of the memory map). This is all configured with the DRAM Controller. Signed-off-by: Sherry Sun Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/ddr.h | 7 +++ drivers/ddr/imx/imx8m/Kconfig | 7 +++ drivers/ddr/imx/imx8m/ddr_init.c | 72 +++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8m/ddr.h b/arch/arm/include/asm/arch-imx8m/ddr.h index 7a2a2d8edce..04c9c962cf2 100644 --- a/arch/arm/include/asm/arch-imx8m/ddr.h +++ b/arch/arm/include/asm/arch-imx8m/ddr.h @@ -529,6 +529,8 @@ enum msg_response { #define DDRC_SBRWDATA0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf2c) #define DDRC_SBRWDATA1(X) (DDRC_IPS_BASE_ADDR(X) + 0xf30) #define DDRC_PDCH(X) (DDRC_IPS_BASE_ADDR(X) + 0xf34) +#define DDRC_SBRSTART0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf38) +#define DDRC_SBRRANGE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf40) #define DDRC_FREQ1_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x2020) #define DDRC_FREQ1_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x2024) @@ -708,6 +710,11 @@ int ddr_cfg_phy(struct dram_timing_info *timing_info); void load_lpddr4_phy_pie(void); void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num); void dram_config_save(struct dram_timing_info *info, unsigned long base); +void board_dram_ecc_scrub(void); +void ddrc_inline_ecc_scrub(unsigned int start_address, + unsigned int range_address); +void ddrc_inline_ecc_scrub_end(unsigned int start_address, + unsigned int range_address); /* utils function for ddr phy training */ int wait_ddrphy_training_complete(void); diff --git a/drivers/ddr/imx/imx8m/Kconfig b/drivers/ddr/imx/imx8m/Kconfig index 5bf61eb2587..a5f5524fbec 100644 --- a/drivers/ddr/imx/imx8m/Kconfig +++ b/drivers/ddr/imx/imx8m/Kconfig @@ -29,4 +29,11 @@ config SAVED_DRAM_TIMING_BASE info into memory for low power use. OCRAM_S is used for this purpose on i.MX8MM. default 0x180000 + +config IMX8M_DRAM_INLINE_ECC + bool "imx8mp inline ECC" + depends on IMX8MP && IMX8M_LPDDR4 + help + Select this config if you want to use inline ecc feature for + imx8mp-evk board. endmenu diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index de302937d08..664966c41bf 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -21,6 +21,76 @@ void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num) } } +#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC +void ddrc_inline_ecc_scrub(unsigned int start_address, + unsigned int range_address) +{ + unsigned int tmp; + + /* Step1: Enable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000000); + /* Step2: Set ECCCFG1.ecc_parity_region_lock to 1 */ + reg32setbit(DDRC_ECCCFG1(0), 0x4); + /* Step3: Block the AXI ports from taking the transaction */ + reg32_write(DDRC_PCTRL_0(0), 0x0); + /* Step4: Set scrub start address */ + reg32_write(DDRC_SBRSTART0(0), start_address); + /* Step5: Set scrub range address */ + reg32_write(DDRC_SBRRANGE0(0), range_address); + /* Step6: Set scrub_mode to write */ + reg32_write(DDRC_SBRCTL(0), 0x00000014); + /* Step7: Set the desired pattern through SBRWDATA0 registers */ + reg32_write(DDRC_SBRWDATA0(0), 0x55aa55aa); + /* Step8: Enable the SBR by programming SBRCTL.scrub_en=1 */ + reg32setbit(DDRC_SBRCTL(0), 0x0); + /* Step9: Poll SBRSTAT.scrub_done=1 */ + tmp = reg32_read(DDRC_SBRSTAT(0)); + while (tmp != 0x00000002) + tmp = reg32_read(DDRC_SBRSTAT(0)) & 0x2; + /* Step10: Poll SBRSTAT.scrub_busy=0 */ + tmp = reg32_read(DDRC_SBRSTAT(0)); + while (tmp != 0x0) + tmp = reg32_read(DDRC_SBRSTAT(0)) & 0x1; + /* Step11: Disable SBR by programming SBRCTL.scrub_en=0 */ + clrbits_le32(DDRC_SBRCTL(0), 0x1); + /* Step12: Prepare for normal scrub operation(Read) and set scrub_interval*/ + reg32_write(DDRC_SBRCTL(0), 0x100); + /* Step13: Enable the SBR by programming SBRCTL.scrub_en=1 */ + reg32_write(DDRC_SBRCTL(0), 0x101); + /* Step14: Enable AXI ports by programming */ + reg32_write(DDRC_PCTRL_0(0), 0x1); + /* Step15: Disable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000001); +} + +void ddrc_inline_ecc_scrub_end(unsigned int start_address, + unsigned int range_address) +{ + /* Step1: Enable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000000); + /* Step2: Block the AXI ports from taking the transaction */ + reg32_write(DDRC_PCTRL_0(0), 0x0); + /* Step3: Set scrub start address */ + reg32_write(DDRC_SBRSTART0(0), start_address); + /* Step4: Set scrub range address */ + reg32_write(DDRC_SBRRANGE0(0), range_address); + /* Step5: Disable SBR by programming SBRCTL.scrub_en=0 */ + clrbits_le32(DDRC_SBRCTL(0), 0x1); + /* Step6: Prepare for normal scrub operation(Read) and set scrub_interval */ + reg32_write(DDRC_SBRCTL(0), 0x100); + /* Step7: Enable the SBR by programming SBRCTL.scrub_en=1 */ + reg32_write(DDRC_SBRCTL(0), 0x101); + /* Step8: Enable AXI ports by programming */ + reg32_write(DDRC_PCTRL_0(0), 0x1); + /* Step9: Disable quasi-dynamic programming */ + reg32_write(DDRC_SWCTL(0), 0x00000001); +} +#endif + +void __weak board_dram_ecc_scrub(void) +{ +} + int ddr_init(struct dram_timing_info *dram_timing) { unsigned int tmp, initial_drate, target_freq; @@ -169,6 +239,8 @@ int ddr_init(struct dram_timing_info *dram_timing) reg32_write(DDRC_PCTRL_0(0), 0x00000001); debug("DDRINFO: ddrmix config done\n"); + board_dram_ecc_scrub(); + /* save the dram timing config into memory */ dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE); From dd2f41370d8320f40944e80b2c87734a5ee1dc44 Mon Sep 17 00:00:00 2001 From: Jian Li Date: Wed, 8 Jan 2020 10:14:16 +0800 Subject: [PATCH 04/51] imx8mp: enable rd_port_urgent Need to enable read urgent for NoC panic signal Signed-off-by: Jian Li --- board/freescale/imx8mp_evk/lpddr4_timing.c | 1 + 1 file changed, 1 insertion(+) diff --git a/board/freescale/imx8mp_evk/lpddr4_timing.c b/board/freescale/imx8mp_evk/lpddr4_timing.c index 14542490bce..6b17b3f1413 100644 --- a/board/freescale/imx8mp_evk/lpddr4_timing.c +++ b/board/freescale/imx8mp_evk/lpddr4_timing.c @@ -58,6 +58,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400264, 0x900093e7 }, { 0x3d40026c, 0x2005574 }, { 0x3d400400, 0x111 }, + { 0x3d400404, 0x72ff }, { 0x3d400408, 0x72ff }, { 0x3d400494, 0x2100e07 }, { 0x3d400498, 0x620096 }, From 5865d14dde8f60f678e144e432a5e5ad223915d0 Mon Sep 17 00:00:00 2001 From: Jian Li Date: Mon, 20 Jan 2020 15:14:42 +0800 Subject: [PATCH 05/51] imx8mp: DDR performance tunning 1. set SCHED.rdwr_idle_gap=0 2. set SCHED.pageclose=1 Reviewed-by: Jacky Bai Signed-off-by: Jian Li Signed-off-by: Peng Fan --- board/freescale/imx8mp_evk/lpddr4_timing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale/imx8mp_evk/lpddr4_timing.c b/board/freescale/imx8mp_evk/lpddr4_timing.c index 6b17b3f1413..75d6b530d25 100644 --- a/board/freescale/imx8mp_evk/lpddr4_timing.c +++ b/board/freescale/imx8mp_evk/lpddr4_timing.c @@ -52,7 +52,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400214, 0x7070707 }, { 0x3d400218, 0x68070707 }, { 0x3d40021c, 0xf08 }, - { 0x3d400250, 0x29001701 }, + { 0x3d400250, 0x00001705 }, { 0x3d400254, 0x2c }, { 0x3d40025c, 0x4000030 }, { 0x3d400264, 0x900093e7 }, From 3f63d27c177a84dd97f77fb843ff4e4c6d7d45eb Mon Sep 17 00:00:00 2001 From: Jian Li Date: Thu, 27 Feb 2020 09:40:10 +0800 Subject: [PATCH 06/51] imx8mp: Disables use of MR4 TUF flag (MR4[7]) bit In uMCTL2 Databook, for LPDDR4, it is recommended to set this register to 1. This can avoid ddr bandwidth is lower after booting with running for a while. Reviewed-by: Ye Li Signed-off-by: Jian Li Signed-off-by: Peng Fan --- board/freescale/imx8mp_evk/lpddr4_timing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/freescale/imx8mp_evk/lpddr4_timing.c b/board/freescale/imx8mp_evk/lpddr4_timing.c index 75d6b530d25..7658262b37d 100644 --- a/board/freescale/imx8mp_evk/lpddr4_timing.c +++ b/board/freescale/imx8mp_evk/lpddr4_timing.c @@ -11,7 +11,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = { { 0x3d400304, 0x1 }, { 0x3d400030, 0x1 }, { 0x3d400000, 0xa3080020 }, - { 0x3d400020, 0x323 }, + { 0x3d400020, 0x1323 }, { 0x3d400024, 0x1e84800 }, { 0x3d400064, 0x7a0118 }, { 0x3d4000d0, 0xc00307a3 }, From b335966958a93e49439bf248adadce89e7e2bee3 Mon Sep 17 00:00:00 2001 From: Oliver Chen Date: Tue, 21 Apr 2020 14:48:09 +0800 Subject: [PATCH 07/51] drivers: ddr: imx Workaround for i.MX8M DDRPHY rank to rank issue Add logic to automatically update umctl2's setting based on phy training CDD value for rank to rank space issue Acked-by: Ye Li Signed-off-by: Oliver Chen Signed-off-by: Jacky Bai Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/ddr.h | 3 + drivers/ddr/imx/imx8m/ddr_init.c | 3 + drivers/ddr/imx/imx8m/ddrphy_train.c | 7 ++ drivers/ddr/imx/imx8m/ddrphy_utils.c | 164 ++++++++++++++++++++++++++ 4 files changed, 177 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8m/ddr.h b/arch/arm/include/asm/arch-imx8m/ddr.h index 04c9c962cf2..0f1e832c038 100644 --- a/arch/arm/include/asm/arch-imx8m/ddr.h +++ b/arch/arm/include/asm/arch-imx8m/ddr.h @@ -721,6 +721,9 @@ int wait_ddrphy_training_complete(void); void ddrphy_init_set_dfi_clk(unsigned int drate); void ddrphy_init_read_msg_block(enum fw_type type); +void update_umctl2_rank_space_setting(unsigned int pstat_num); +void get_trained_CDD(unsigned int fsp); + static inline void reg32_write(unsigned long addr, u32 val) { writel(val, addr); diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index 664966c41bf..99a67edfb0a 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -190,6 +190,9 @@ int ddr_init(struct dram_timing_info *dram_timing) /* Step15: Set SWCTL.sw_done to 0 */ reg32_write(DDRC_SWCTL(0), 0x00000000); + /* Apply rank-to-rank workaround */ + update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1); + /* Step16: Set DFIMISC.dfi_init_start to 1 */ setbits_le32(DDRC_DFIMISC(0), (0x1 << 5)); diff --git a/drivers/ddr/imx/imx8m/ddrphy_train.c b/drivers/ddr/imx/imx8m/ddrphy_train.c index f2a997b50a6..08fed6178f3 100644 --- a/drivers/ddr/imx/imx8m/ddrphy_train.c +++ b/drivers/ddr/imx/imx8m/ddrphy_train.c @@ -8,6 +8,7 @@ #include #include #include +#include int ddr_cfg_phy(struct dram_timing_info *dram_timing) { @@ -71,9 +72,15 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing) /* Read the Message Block results */ dwc_ddrphy_apb_wr(0xd0000, 0x0); + ddrphy_init_read_msg_block(fsp_msg->fw_type); + + if(fsp_msg->fw_type != FW_2D_IMAGE) + get_trained_CDD(i); + dwc_ddrphy_apb_wr(0xd0000, 0x1); + fsp_msg++; } diff --git a/drivers/ddr/imx/imx8m/ddrphy_utils.c b/drivers/ddr/imx/imx8m/ddrphy_utils.c index d5eef535739..20ae47bfb52 100644 --- a/drivers/ddr/imx/imx8m/ddrphy_utils.c +++ b/drivers/ddr/imx/imx8m/ddrphy_utils.c @@ -11,6 +11,12 @@ #include #include #include +#include + +static unsigned int g_cdd_rr_max[4]; +static unsigned int g_cdd_rw_max[4]; +static unsigned int g_cdd_wr_max[4]; +static unsigned int g_cdd_ww_max[4]; static inline void poll_pmu_message_ready(void) { @@ -193,3 +199,161 @@ unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr) return tmp; } + +unsigned int look_for_max(unsigned int data[], + unsigned int addr_start, unsigned int addr_end) +{ + unsigned int i, imax = 0; + + for (i = addr_start; i <= addr_end; i++) { + if (((data[i] >> 7) == 0) && (data[i] > imax)) + imax = data[i]; + } + + return imax; +} + +void get_trained_CDD(u32 fsp) +{ + unsigned int i, ddr_type, tmp; + unsigned int cdd_cha[12], cdd_chb[12]; + unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max; + unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max; + + ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f; + if (ddr_type == 0x20) { + for (i = 0; i < 6; i++) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54013 + i) * 4); + cdd_cha[i * 2] = tmp & 0xff; + cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff; + } + + for (i = 0; i < 7; i++) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x5402c + i) * 4); + if (i == 0) { + cdd_cha[0] = (tmp >> 8) & 0xff; + } else if (i == 6) { + cdd_cha[11]=tmp & 0xff; + } else { + cdd_chb[ i * 2 - 1] = tmp & 0xff; + cdd_chb[i * 2] = (tmp >> 8) & 0xff; + } + } + + cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1); + cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5); + cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9); + cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11); + cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1); + cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5); + cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9); + cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11); + g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max; + g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max; + g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max; + g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max; + } else { + unsigned int ddr4_cdd[64]; + for( i = 0; i < 29; i++) { + tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54012 + i) * 4); + ddr4_cdd[i * 2] = tmp & 0xff; + ddr4_cdd[i * 2 + 1] = (tmp >> 8) & 0xff; + } + + g_cdd_rr_max[fsp] = look_for_max(ddr4_cdd, 1, 12); + g_cdd_ww_max[fsp] = look_for_max(ddr4_cdd, 13, 24); + g_cdd_rw_max[fsp] = look_for_max(ddr4_cdd, 25, 40); + g_cdd_wr_max[fsp] = look_for_max(ddr4_cdd, 41, 56); + } +} + +void update_umctl2_rank_space_setting(unsigned int pstat_num) +{ + unsigned int i,ddr_type; + unsigned int addr_slot, rdata, tmp, tmp_t; + unsigned int ddrc_w2r,ddrc_r2w,ddrc_wr_gap,ddrc_rd_gap; + + ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f; + for (i = 0; i < pstat_num; i++) { + addr_slot = i ? (i + 1) * 0x1000 : 0; + if (ddr_type == 0x20) { + /* update r2w:[13:8], w2r:[5:0] */ + rdata=reg32_read(DDRC_DRAMTMG2(0) + addr_slot); + ddrc_w2r = rdata & 0x3f; + if(is_imx8mp()) + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1); + else + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1; + ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp; + + ddrc_r2w = (rdata >> 8) & 0x3f; + if (is_imx8mp()) + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1); + else + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1; + ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp; + + tmp_t = (rdata & 0xffffc0c0) | (ddrc_r2w << 8) | ddrc_w2r; + reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t); + } else { + /* update w2r:[5:0] */ + rdata=reg32_read(DDRC_DRAMTMG9(0) + addr_slot); + ddrc_w2r = rdata & 0x3f; + if (is_imx8mp()) + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1); + else + tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1; + ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp; + tmp_t = (rdata & 0xffffffc0) | ddrc_w2r; + reg32_write((DDRC_DRAMTMG9(0) + addr_slot), tmp_t); + + /* update r2w:[13:8] */ + rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot); + ddrc_r2w = (rdata >> 8) & 0x3f; + if(is_imx8mp()) + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1); + else + tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1; + ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp; + + tmp_t = (rdata & 0xffffc0ff) | (ddrc_r2w << 8); + reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t); + } + + if (!is_imx8mq()) { + /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */ + rdata = reg32_read(DDRC_RANKCTL(0) + addr_slot); + ddrc_wr_gap = (rdata >> 8) & 0xf; + if(is_imx8mp()) + tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1); + else + tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1) + 1; + ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp; + + ddrc_rd_gap = (rdata >> 4) & 0xf; + if (is_imx8mp()) + tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1); + else + tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1) + 1; + ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp; + + tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4); + reg32_write((DDRC_RANKCTL(0) + addr_slot), tmp_t); + } + } + + if(is_imx8mq()) { + /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */ + rdata = reg32_read(DDRC_RANKCTL(0)); + ddrc_wr_gap = (rdata >> 8) & 0xf; + tmp = ddrc_wr_gap + (g_cdd_ww_max[0] >> 1) + 1; + ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp; + + ddrc_rd_gap = (rdata >> 4) & 0xf; + tmp = ddrc_rd_gap + (g_cdd_rr_max[0] >> 1) + 1; + ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp; + + tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4); + reg32_write(DDRC_RANKCTL(0), tmp_t); + } +} From 58db844fc87749db08224fd536d5b95453f8b456 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 30 May 2020 16:37:39 +0800 Subject: [PATCH 08/51] pinctrl: imx7: move soc info to data section The soc info without initialization value should be put into data section. The driver could be used before relocation, with it in BSS section could cause issue, since BSS section is not initializated and it might overwrite other areas that used by others, such as dtb. Signed-off-by: Peng Fan --- drivers/pinctrl/nxp/pinctrl-imx7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/nxp/pinctrl-imx7.c b/drivers/pinctrl/nxp/pinctrl-imx7.c index 769d428ddad..66b58ba472c 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx7.c +++ b/drivers/pinctrl/nxp/pinctrl-imx7.c @@ -9,7 +9,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info __attribute__((section(".data"))); static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = { .flags = ZERO_OFFSET_VALID, From 4b8c6030daa982775c03de26d8cd24310961b618 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 30 May 2020 16:39:14 +0800 Subject: [PATCH 09/51] pinctrl: imx8m: move soc info to data section The soc info without initialization value should be put into data section. The driver could be used before relocation, with it in BSS section could cause issue, since BSS section is not initializated and it might overwrite other areas that used by others, such as dtb. Signed-off-by: Peng Fan --- drivers/pinctrl/nxp/pinctrl-imx8m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/nxp/pinctrl-imx8m.c b/drivers/pinctrl/nxp/pinctrl-imx8m.c index 5b7cbb69ae8..0626fde58f1 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx8m.c +++ b/drivers/pinctrl/nxp/pinctrl-imx8m.c @@ -8,7 +8,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __attribute__((section(".data"))); static int imx8mq_pinctrl_probe(struct udevice *dev) { From 683a91cdbd2b0f6c8676717d28f8a3879beb082a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 30 May 2020 16:43:20 +0800 Subject: [PATCH 10/51] pinctrl: imx5: move soc info to data section The soc info without initialization value should be put into data section. The driver could be used before relocation, with it in BSS section could cause issue, since BSS section is not initializated and it might overwrite other areas that used by others, such as dtb. Signed-off-by: Peng Fan --- drivers/pinctrl/nxp/pinctrl-imx5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/nxp/pinctrl-imx5.c b/drivers/pinctrl/nxp/pinctrl-imx5.c index 5d173809198..9c3423bef37 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx5.c +++ b/drivers/pinctrl/nxp/pinctrl-imx5.c @@ -10,7 +10,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info; +static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info __attribute__((section(".data"))); static int imx5_pinctrl_probe(struct udevice *dev) { From dc575201c849b3cc6782e6933417f7b2ccc3599a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 11 May 2020 15:13:34 +0800 Subject: [PATCH 11/51] imx8: misc: use arm_smccc_smc Use arm_smccc_smc to replace call_imx_sip Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/misc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c index 2cd794d54a3..de19955e2f7 100644 --- a/arch/arm/mach-imx/imx8/misc.c +++ b/arch/arm/mach-imx/imx8/misc.c @@ -4,6 +4,7 @@ #include #include #include +#include int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) { @@ -30,6 +31,7 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) void build_info(void) { + struct arm_smccc_res res; u32 seco_build = 0, seco_commit = 0; u32 sc_build = 0, sc_commit = 0; ulong atf_commit = 0; @@ -50,8 +52,9 @@ void build_info(void) } /* Get ARM Trusted Firmware commit id */ - atf_commit = call_imx_sip(IMX_SIP_BUILDINFO, - IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); + arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH, + 0, 0, 0, 0, 0, 0, &res); + atf_commit = res.a0; if (atf_commit == 0xffffffff) { debug("ATF does not support build info\n"); atf_commit = 0x30; /* Display 0 */ From a2f143eaacb35621725c2d2e4c861cab651feafc Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 11 May 2020 15:14:04 +0800 Subject: [PATCH 12/51] imx8m: soc: use arm_smccc_smc Use arm_smccc_smc to replace call_imx_sip Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 1d2c8e6db28..fae69be1c7a 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -432,10 +433,12 @@ void reset_cpu(ulong addr) static void acquire_buildinfo(void) { u64 atf_commit = 0; + struct arm_smccc_res res; /* Get ARM Trusted Firmware commit id */ - atf_commit = call_imx_sip(IMX_SIP_BUILDINFO, - IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); + arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH, + 0, 0 , 0, 0, 0, 0, &res); + atf_commit = res.a0; if (atf_commit == 0xffffffff) { debug("ATF does not support build info\n"); atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ From bf26b9421eb78c7ff3ecf42a8b5bcde0315343b5 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 11 May 2020 15:15:21 +0800 Subject: [PATCH 13/51] imx: bootaux: use arm_smccc_smc Use arm_smccc_smc to replace call_imx_sip Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx_bootaux.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index 868633cf8a4..e1fc4b3e19a 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -55,7 +56,8 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) /* Enable M4 */ #ifdef CONFIG_IMX8M - call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0); + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, + 0, 0, 0, 0, NULL); #else clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET, SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK); @@ -67,7 +69,12 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr) int arch_auxiliary_core_check_up(u32 core_id) { #ifdef CONFIG_IMX8M - return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0); + struct arm_smccc_res res; + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, + 0, 0, 0, 0, &res); + + return res.a0; #else unsigned int val; From c2eaa6eb09f474c4af51443256fe072d2e137719 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 11 May 2020 15:16:07 +0800 Subject: [PATCH 14/51] imx8: fuse: use arm_smccc_smc Use arm_smccc_smc to replace call_imx_sip Signed-off-by: Peng Fan --- drivers/misc/imx8/fuse.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c index 4d7f2f524d0..be181229370 100644 --- a/drivers/misc/imx8/fuse.c +++ b/drivers/misc/imx8/fuse.c @@ -9,6 +9,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -36,22 +37,24 @@ int fuse_read(u32 bank, u32 word, u32 *val) int fuse_sense(u32 bank, u32 word, u32 *val) { - unsigned long ret = 0, value = 0; + struct arm_smccc_res res; if (bank != 0) { printf("Invalid bank argument, ONLY bank 0 is supported\n"); return -EINVAL; } - ret = call_imx_sip_ret2(FSL_SIP_OTP_READ, (unsigned long)word, &value, - 0, 0); - *val = (u32)value; + arm_smccc_smc(FSL_SIP_OTP_READ, (unsigned long)word, 0, 0, + 0, 0, 0, 0, &res); + *val = (u32)res.a1; - return ret; + return res.a0; } int fuse_prog(u32 bank, u32 word, u32 val) { + struct arm_smccc_res res; + if (bank != 0) { printf("Invalid bank argument, ONLY bank 0 is supported\n"); return -EINVAL; @@ -78,8 +81,10 @@ int fuse_prog(u32 bank, u32 word, u32 val) } } - return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word, - (unsigned long)val, 0, 0); + arm_smccc_smc(FSL_SIP_OTP_WRITE, (unsigned long)word, + (unsigned long)val, 0, 0, 0, 0, 0, &res); + + return res.a0; } int fuse_override(u32 bank, u32 word, u32 val) From 4b8f22de160edfa25fd95cad807471ceeabb1783 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 11 May 2020 15:16:37 +0800 Subject: [PATCH 15/51] imx: power-domain: use arm_smccc_smc Use arm_smccc_smc to replace call_imx_sip Signed-off-by: Peng Fan --- drivers/power/domain/imx8m-power-domain.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c index 5b6467cda70..0ef460df8c2 100644 --- a/drivers/power/domain/imx8m-power-domain.c +++ b/drivers/power/domain/imx8m-power-domain.c @@ -13,6 +13,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -30,6 +31,7 @@ static int imx8m_power_domain_on(struct power_domain *power_domain) { struct udevice *dev = power_domain->dev; struct imx8m_power_domain_platdata *pdata; + pdata = dev_get_platdata(dev); if (pdata->resource_id < 0) @@ -38,8 +40,8 @@ static int imx8m_power_domain_on(struct power_domain *power_domain) if (pdata->has_pd) power_domain_on(&pdata->pd); - call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, - pdata->resource_id, 1, 0); + arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, + pdata->resource_id, 1, 0, 0, 0, 0, NULL); return 0; } @@ -53,8 +55,8 @@ static int imx8m_power_domain_off(struct power_domain *power_domain) if (pdata->resource_id < 0) return -EINVAL; - call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, - pdata->resource_id, 0, 0); + arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, + pdata->resource_id, 0, 0, 0, 0, 0, NULL); if (pdata->has_pd) power_domain_off(&pdata->pd); From d6498bc4594c8042a2fb221e8876cb8bba4b7105 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 11 May 2020 15:19:53 +0800 Subject: [PATCH 16/51] imx: remove imx sip file We have switch to use arm_smccc_smc, no need to keep i.MX specific sip wrapper. Signed-off-by: Peng Fan --- arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/sip.c | 48 -------------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 arch/arm/mach-imx/sip.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index a70d51b5cf1..1aa26a50ad8 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -218,7 +218,7 @@ endif targets += $(addprefix ../../../,SPL spl/u-boot-spl.cfgout u-boot-dtb.cfgout u-boot.cfgout u-boot.uim spl/u-boot-nand-spl.imx) -obj-$(CONFIG_ARM64) += lowlevel.o sip.o +obj-$(CONFIG_ARM64) += lowlevel.o obj-$(CONFIG_MX5) += mx5/ obj-$(CONFIG_MX6) += mx6/ diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c deleted file mode 100644 index 6cb8179ee8c..00000000000 --- a/arch/arm/mach-imx/sip.c +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2017 NXP - */ - -#include -#include -#include -#include - -unsigned long call_imx_sip(unsigned long id, unsigned long reg0, - unsigned long reg1, unsigned long reg2, - unsigned long reg3) -{ - struct pt_regs regs; - - regs.regs[0] = id; - regs.regs[1] = reg0; - regs.regs[2] = reg1; - regs.regs[3] = reg2; - regs.regs[4] = reg3; - - smc_call(®s); - - return regs.regs[0]; -} - -/* - * Do an SMC call to return 2 registers by having reg1 passed in by reference - */ -unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0, - unsigned long *reg1, unsigned long reg2, - unsigned long reg3) -{ - struct pt_regs regs; - - regs.regs[0] = id; - regs.regs[1] = reg0; - regs.regs[2] = *reg1; - regs.regs[3] = reg2; - regs.regs[4] = reg3; - - smc_call(®s); - - *reg1 = regs.regs[1]; - - return regs.regs[0]; -} From 7ddb4ef3e178ddea1ad117b9a14357b13afb6e92 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 27 Jun 2020 15:48:04 +0800 Subject: [PATCH 17/51] clk: imx8mm: fix clk set parent Fix clk set parent, so we could still have correct clocks after parent changing. Signed-off-by: Peng Fan --- drivers/clk/imx/clk-imx8mm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 66c9601b0c1..d609fad7acf 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -191,7 +191,10 @@ static int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent) if (ret) return ret; - return clk_set_parent(c, cp); + ret = clk_set_parent(c, cp); + c->dev->parent = cp->dev; + + return ret; } static struct clk_ops imx8mm_clk_ops = { From a65409420d428f46311c5782a62b18e0904f64c9 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 27 Jun 2020 15:49:28 +0800 Subject: [PATCH 18/51] clk: imx8mm: Add qspi clock Add qspi clock Signed-off-by: Peng Fan --- drivers/clk/imx/clk-imx8mm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index d609fad7acf..4743394069e 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -119,6 +119,9 @@ static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ static const char *imx8mm_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; +static const char *imx8mm_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", + "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; + static ulong imx8mm_clk_get_rate(struct clk *clk) { struct clk *c; @@ -373,6 +376,8 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80)); + clk_dm(IMX8MM_CLK_QSPI, + imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); clk_dm(IMX8MM_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); @@ -396,6 +401,8 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); clk_dm(IMX8MM_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); + clk_dm(IMX8MM_CLK_QSPI_ROOT, + imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); /* clks not needed in SPL stage */ #ifndef CONFIG_SPL_BUILD From ee1f8b226f1e6e3fdb0dd5fe0f41d1d92bccc690 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sat, 18 Apr 2020 08:19:12 -0700 Subject: [PATCH 19/51] clk: clk-imx8mn: Update clock tree and support set parent Add set clock parent support. Add ENET and flexspi related clocks to support assigned clocks Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/clk/imx/clk-imx8mn.c | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 2d8e373131b..a11b17f1672 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -81,6 +81,17 @@ static const char *imx8mn_ahb_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_p static const char *imx8mn_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; +#ifndef CONFIG_SPL_BUILD +static const char *imx8mn_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m", + "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; + +static const char *imx8mn_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4", "video_pll1_out", }; + +static const char *imx8mn_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m", + "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", }; +#endif + static const char *imx8mn_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; @@ -108,6 +119,9 @@ static const char *imx8mn_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ static const char *imx8mn_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; +static const char *imx8mn_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", + "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; + static ulong imx8mn_clk_get_rate(struct clk *clk) { struct clk *c; @@ -165,11 +179,33 @@ static int imx8mn_clk_enable(struct clk *clk) return __imx8mn_clk_enable(clk, 1); } +static int imx8mn_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *cp; + int ret; + + debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id); + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + ret = clk_get_by_id(parent->id, &cp); + if (ret) + return ret; + + ret = clk_set_parent(c, cp); + c->dev->parent = cp->dev; + + return ret; +} + static struct clk_ops imx8mn_clk_ops = { .set_rate = imx8mn_clk_set_rate, .get_rate = imx8mn_clk_get_rate, .enable = imx8mn_clk_enable, .disable = imx8mn_clk_disable, + .set_parent = imx8mn_clk_set_parent, }; static int imx8mn_clk_probe(struct udevice *dev) @@ -340,6 +376,8 @@ static int imx8mn_clk_probe(struct udevice *dev) clk_dm(IMX8MN_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80)); + clk_dm(IMX8MN_CLK_QSPI, + imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80)); clk_dm(IMX8MN_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); @@ -363,6 +401,24 @@ static int imx8mn_clk_probe(struct udevice *dev) imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); clk_dm(IMX8MN_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); + clk_dm(IMX8MN_CLK_QSPI_ROOT, + imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); + + /* clks not needed in SPL stage */ +#ifndef CONFIG_SPL_BUILD + clk_dm(IMX8MN_CLK_ENET_REF, + imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, + base + 0xa980)); + clk_dm(IMX8MN_CLK_ENET_TIMER, + imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, + base + 0xaa00)); + clk_dm(IMX8MN_CLK_ENET_PHY_REF, + imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, + base + 0xaa80)); + clk_dm(IMX8MN_CLK_ENET1_ROOT, + imx_clk_gate4("enet1_root_clk", "enet_axi", + base + 0x40a0, 0)); +#endif #ifdef CONFIG_SPL_BUILD struct clk *clkp, *clkp1; From 4b6548d17d065de9c31ce4fc3e476ca16beaa8db Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 19 Apr 2020 02:22:09 -0700 Subject: [PATCH 20/51] clk: imx8mm/8mn: Add USB clocks Add USB relevant clocks to support usb clock settings for both DM USB host and gadget drivers Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/clk/imx/clk-imx8mm.c | 17 +++++++++++++++++ drivers/clk/imx/clk-imx8mn.c | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 4743394069e..85d17575364 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -95,6 +95,9 @@ static const char *imx8mm_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "s static const char *imx8mm_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; +static const char *imx8mm_usb_bus_sels[] = {"clock-osc-24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", }; + static const char *imx8mm_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; @@ -122,6 +125,12 @@ static const char *imx8mm_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sy static const char *imx8mm_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; +static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + static ulong imx8mm_clk_get_rate(struct clk *clk) { struct clk *c; @@ -355,6 +364,8 @@ static int imx8mm_clk_probe(struct udevice *dev) imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900)); + clk_dm(IMX8MM_CLK_USB_BUS, + imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80)); /* IP */ clk_dm(IMX8MM_CLK_USDHC1, @@ -378,6 +389,10 @@ static int imx8mm_clk_probe(struct udevice *dev) base + 0xbc80)); clk_dm(IMX8MM_CLK_QSPI, imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); + clk_dm(IMX8MM_CLK_USB_CORE_REF, + imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100)); + clk_dm(IMX8MM_CLK_USB_PHY_REF, + imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180)); clk_dm(IMX8MM_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); @@ -403,6 +418,8 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); clk_dm(IMX8MM_CLK_QSPI_ROOT, imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); + clk_dm(IMX8MM_CLK_USB1_CTRL_ROOT, + imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); /* clks not needed in SPL stage */ #ifndef CONFIG_SPL_BUILD diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index a11b17f1672..8bf6061a327 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -95,6 +95,10 @@ static const char *imx8mn_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "s static const char *imx8mn_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; +static const char * const imx8mn_usb_bus_sels[] = {"clock-osc-24m", "sys_pll2_500m", "sys_pll1_800m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext4", "audio_pll2_out", }; + static const char *imx8mn_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; @@ -122,6 +126,14 @@ static const char *imx8mn_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sy static const char *imx8mn_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; +static const char * const imx8mn_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + +static const char * const imx8mn_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", + "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", + "clk_ext3", "audio_pll2_out", }; + static ulong imx8mn_clk_get_rate(struct clk *clk) { struct clk *c; @@ -355,6 +367,8 @@ static int imx8mn_clk_probe(struct udevice *dev) imx8m_clk_composite_critical("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900)); + clk_dm(IMX8MN_CLK_USB_BUS, + imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80)); /* IP */ clk_dm(IMX8MN_CLK_USDHC1, @@ -378,6 +392,10 @@ static int imx8mn_clk_probe(struct udevice *dev) base + 0xbc80)); clk_dm(IMX8MN_CLK_QSPI, imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80)); + clk_dm(IMX8MN_CLK_USB_CORE_REF, + imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100)); + clk_dm(IMX8MN_CLK_USB_PHY_REF, + imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180)); clk_dm(IMX8MN_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); @@ -403,6 +421,8 @@ static int imx8mn_clk_probe(struct udevice *dev) imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); clk_dm(IMX8MN_CLK_QSPI_ROOT, imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); + clk_dm(IMX8MN_CLK_USB1_CTRL_ROOT, + imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); /* clks not needed in SPL stage */ #ifndef CONFIG_SPL_BUILD From ac9a45182816a34a8996c896f7c8ee81be7ea4d6 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 21 Apr 2020 20:19:24 -0700 Subject: [PATCH 21/51] clk: imx8mp: Update imx8mp ccf clock driver Add clocks for FEC and flexspi, and add set parent clock callback, so DTS can assign clocks Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/clk/imx/clk-imx8mp.c | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 124138cf512..c77500bcce0 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -80,6 +80,10 @@ static const char *imx8mp_main_axi_sels[] = {"clock-osc-24m", "sys_pll2_333m", " "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",}; +static const char *imx8mp_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", + "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", + "video_pll1_out", "sys_pll3_out", }; + static const char *imx8mp_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; @@ -160,10 +164,26 @@ static const char *imx8mp_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m" }; +static const char *imx8mp_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", + "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", + "sys_pll3_out", "sys_pll1_100m", }; + static const char *imx8mp_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; +static const char *imx8mp_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", + "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", + "video_pll1_out", "clk_ext4", }; + +static const char *imx8mp_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", + "clk_ext1", "clk_ext2", "clk_ext3", + "clk_ext4", "video_pll1_out", }; + +static const char *imx8mp_enet_phy_ref_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", + "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", }; + static const char *imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; @@ -224,11 +244,34 @@ static int imx8mp_clk_enable(struct clk *clk) return __imx8mp_clk_enable(clk, 1); } +static int imx8mp_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *cp; + int ret; + + debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id); + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + ret = clk_get_by_id(parent->id, &cp); + if (ret) + return ret; + + ret = clk_set_parent(c, cp); + + c->dev->parent = cp->dev; + + return ret; +} + static struct clk_ops imx8mp_clk_ops = { .set_rate = imx8mp_clk_set_rate, .get_rate = imx8mp_clk_get_rate, .enable = imx8mp_clk_enable, .disable = imx8mp_clk_disable, + .set_parent = imx8mp_clk_set_parent, }; static int imx8mp_clk_probe(struct udevice *dev) @@ -290,6 +333,7 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_A53_DIV, imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3)); clk_dm(IMX8MP_CLK_MAIN_AXI, imx8m_clk_composite_critical("main_axi", imx8mp_main_axi_sels, base + 0x8800)); + clk_dm(IMX8MP_CLK_ENET_AXI, imx8m_clk_composite_critical("enet_axi", imx8mp_enet_axi_sels, base + 0x8880)); clk_dm(IMX8MP_CLK_NAND_USDHC_BUS, imx8m_clk_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, base + 0x8900)); clk_dm(IMX8MP_CLK_NOC, imx8m_clk_composite_critical("noc", imx8mp_noc_sels, base + 0x8d00)); clk_dm(IMX8MP_CLK_NOC_IO, imx8m_clk_composite_critical("noc_io", imx8mp_noc_io_sels, base + 0x8d80)); @@ -302,6 +346,10 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_DRAM_APB, imx8m_clk_composite_critical("dram_apb", imx8mp_dram_apb_sels, base + 0xa080)); clk_dm(IMX8MP_CLK_I2C5, imx8m_clk_composite("i2c5", imx8mp_i2c5_sels, base + 0xa480)); clk_dm(IMX8MP_CLK_I2C6, imx8m_clk_composite("i2c6", imx8mp_i2c6_sels, base + 0xa500)); + clk_dm(IMX8MP_CLK_ENET_REF, imx8m_clk_composite("enet_ref", imx8mp_enet_ref_sels, base + 0xa980)); + clk_dm(IMX8MP_CLK_ENET_TIMER, imx8m_clk_composite("enet_timer", imx8mp_enet_timer_sels, base + 0xaa00)); + clk_dm(IMX8MP_CLK_ENET_PHY_REF, imx8m_clk_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, base + 0xaa80)); + clk_dm(IMX8MP_CLK_QSPI, imx8m_clk_composite("qspi", imx8mp_qspi_sels, base + 0xab80)); clk_dm(IMX8MP_CLK_USDHC1, imx8m_clk_composite("usdhc1", imx8mp_usdhc1_sels, base + 0xac00)); clk_dm(IMX8MP_CLK_USDHC2, imx8m_clk_composite("usdhc2", imx8mp_usdhc2_sels, base + 0xac80)); clk_dm(IMX8MP_CLK_I2C1, imx8m_clk_composite("i2c1", imx8mp_i2c1_sels, base + 0xad00)); @@ -322,6 +370,8 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_DRAM_CORE, imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL)); clk_dm(IMX8MP_CLK_DRAM1_ROOT, imx_clk_gate4_flags("dram1_root_clk", "dram_core_clk", base + 0x4050, 0, CLK_IS_CRITICAL)); + + clk_dm(IMX8MP_CLK_ENET1_ROOT, imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0)); clk_dm(IMX8MP_CLK_GPIO1_ROOT, imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0)); clk_dm(IMX8MP_CLK_GPIO2_ROOT, imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0)); clk_dm(IMX8MP_CLK_GPIO3_ROOT, imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0)); @@ -331,8 +381,10 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_CLK_I2C2_ROOT, imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0)); clk_dm(IMX8MP_CLK_I2C3_ROOT, imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0)); clk_dm(IMX8MP_CLK_I2C4_ROOT, imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0)); + clk_dm(IMX8MP_CLK_QSPI_ROOT, imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); clk_dm(IMX8MP_CLK_I2C5_ROOT, imx_clk_gate2("i2c5_root_clk", "i2c5", base + 0x4330, 0)); clk_dm(IMX8MP_CLK_I2C6_ROOT, imx_clk_gate2("i2c6_root_clk", "i2c6", base + 0x4340, 0)); + clk_dm(IMX8MP_CLK_SIM_ENET_ROOT, imx_clk_gate4("sim_enet_root_clk", "enet_axi", base + 0x4400, 0)); clk_dm(IMX8MP_CLK_UART1_ROOT, imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0)); clk_dm(IMX8MP_CLK_UART2_ROOT, imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0)); clk_dm(IMX8MP_CLK_UART3_ROOT, imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0)); From 46a8a28bf60bde07e6c3b5c44a77af2544d8aee9 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 11:06:24 +0800 Subject: [PATCH 22/51] imx8m: configure arm clk sources from PLL A53 CCM root max support 1GHz, to support high freq, we need to switch ARM clk sources from ARM PLL directly. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/clock_imx8mm.c | 130 ++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index aafe2ed084e..6ab75f0e2c4 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -19,6 +19,7 @@ DECLARE_GLOBAL_DATA_PTR; static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR; +static u32 get_root_clk(enum clk_root_index clock_id); void enable_ocotp_clk(unsigned char enable) { clock_enable(CCGR_OCOTP, !!enable); @@ -164,6 +165,109 @@ void dram_disable_bypass(void) } #endif +int intpll_configure(enum pll_clocks pll, ulong freq) +{ + void __iomem *pll_gnrl_ctl, __iomem *pll_div_ctl; + u32 pll_div_ctl_val, pll_clke_masks; + + switch (pll) { + case ANATOP_SYSTEM_PLL1: + pll_gnrl_ctl = &ana_pll->sys_pll1_gnrl_ctl; + pll_div_ctl = &ana_pll->sys_pll1_div_ctl; + pll_clke_masks = INTPLL_DIV20_CLKE_MASK | + INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK | + INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK | + INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK | + INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK; + break; + case ANATOP_SYSTEM_PLL2: + pll_gnrl_ctl = &ana_pll->sys_pll2_gnrl_ctl; + pll_div_ctl = &ana_pll->sys_pll2_div_ctl; + pll_clke_masks = INTPLL_DIV20_CLKE_MASK | + INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK | + INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK | + INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK | + INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK; + break; + case ANATOP_SYSTEM_PLL3: + pll_gnrl_ctl = &ana_pll->sys_pll3_gnrl_ctl; + pll_div_ctl = &ana_pll->sys_pll3_div_ctl; + pll_clke_masks = INTPLL_CLKE_MASK; + break; + case ANATOP_ARM_PLL: + pll_gnrl_ctl = &ana_pll->arm_pll_gnrl_ctl; + pll_div_ctl = &ana_pll->arm_pll_div_ctl; + pll_clke_masks = INTPLL_CLKE_MASK; + break; + case ANATOP_GPU_PLL: + pll_gnrl_ctl = &ana_pll->gpu_pll_gnrl_ctl; + pll_div_ctl = &ana_pll->gpu_pll_div_ctl; + pll_clke_masks = INTPLL_CLKE_MASK; + break; + case ANATOP_VPU_PLL: + pll_gnrl_ctl = &ana_pll->vpu_pll_gnrl_ctl; + pll_div_ctl = &ana_pll->vpu_pll_div_ctl; + pll_clke_masks = INTPLL_CLKE_MASK; + break; + default: + return -EINVAL; + }; + + switch (freq) { + case MHZ(600): + /* 24 * 0x12c / 3 / 2 ^ 2 */ + pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x12c) | + INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2); + break; + case MHZ(750): + /* 24 * 0xfa / 2 / 2 ^ 2 */ + pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) | + INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(2); + break; + case MHZ(800): + /* 24 * 0x190 / 3 / 2 ^ 2 */ + pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x190) | + INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2); + break; + case MHZ(1000): + /* 24 * 0xfa / 3 / 2 ^ 1 */ + pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) | + INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(1); + break; + case MHZ(1200): + /* 24 * 0xc8 / 2 / 2 ^ 1 */ + pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xc8) | + INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(1); + break; + case MHZ(2000): + /* 24 * 0xfa / 3 / 2 ^ 0 */ + pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) | + INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(0); + break; + default: + return -EINVAL; + }; + /* Bypass clock and set lock to pll output lock */ + setbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK | INTPLL_LOCK_SEL_MASK); + /* Enable reset */ + clrbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK); + /* Configure */ + writel(pll_div_ctl_val, pll_div_ctl); + + __udelay(100); + + /* Disable reset */ + setbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK); + /* Wait Lock */ + while (!(readl(pll_gnrl_ctl) & INTPLL_LOCK_MASK)) + ; + /* Clear bypass */ + clrbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK); + setbits_le32(pll_gnrl_ctl, pll_clke_masks); + + return 0; +} + void init_uart_clk(u32 index) { /* @@ -240,6 +344,15 @@ int clock_init(void) INTPLL_DIV20_CLKE_MASK; writel(val_cfg0, &ana_pll->sys_pll2_gnrl_ctl); + /* Configure ARM at 1.2GHz */ + clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(2)); + + intpll_configure(ANATOP_ARM_PLL, MHZ(1200)); + + /* Bypass CCM A53 ROOT, Switch to ARM PLL -> MUX-> CPU */ + clock_set_target_val(CORE_SEL_CFG, CLK_ROOT_SOURCE_SEL(1)); + /* config GIC to sys_pll2_100m */ clock_enable(CCGR_GIC, 0); clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | @@ -519,6 +632,8 @@ static u32 get_root_src_clk(enum clk_root_src root_src) case AUDIO_PLL2_CLK: case VIDEO_PLL_CLK: return decode_fracpll(root_src); + case ARM_A53_ALT_CLK: + return get_root_clk(ARM_A53_CLK_ROOT); default: return 0; } @@ -548,13 +663,26 @@ static u32 get_root_clk(enum clk_root_index clock_id) return root_src_clk / (post_podf + 1) / (pre_podf + 1); } +u32 get_arm_core_clk(void) +{ + enum clk_root_src root_src; + u32 root_src_clk; + + if (clock_get_src(CORE_SEL_CFG, &root_src) < 0) + return 0; + + root_src_clk = get_root_src_clk(root_src); + + return root_src_clk; +} + u32 mxc_get_clock(enum mxc_clock clk) { u32 val; switch (clk) { case MXC_ARM_CLK: - return get_root_clk(ARM_A53_CLK_ROOT); + return get_arm_core_clk(); case MXC_IPG_CLK: clock_get_target_val(IPG_CLK_ROOT, &val); val = val & 0x3; From 14254e646d7415bbdaa21cf606dda6143eb51f87 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 11:18:50 +0800 Subject: [PATCH 23/51] imx8m: configure NoC clk Configure NoC clk for better system performance Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/clock_imx8mm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 6ab75f0e2c4..0a8208606d1 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -353,11 +353,24 @@ int clock_init(void) /* Bypass CCM A53 ROOT, Switch to ARM PLL -> MUX-> CPU */ clock_set_target_val(CORE_SEL_CFG, CLK_ROOT_SOURCE_SEL(1)); + if (is_imx8mn() || is_imx8mp()) + intpll_configure(ANATOP_SYSTEM_PLL3, MHZ(600)); + else + intpll_configure(ANATOP_SYSTEM_PLL3, MHZ(750)); + +#ifdef CONFIG_IMX8MP + /* 8MP ROM already set NOC to 800Mhz, only need to configure NOC_IO clk to 600Mhz */ + /* 8MP ROM already set GIC to 400Mhz, system_pll1_800m with div = 2 */ + clock_set_target_val(NOC_IO_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2)); +#else + clock_set_target_val(NOC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2)); + /* config GIC to sys_pll2_100m */ clock_enable(CCGR_GIC, 0); clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(3)); clock_enable(CCGR_GIC, 1); +#endif clock_set_target_val(NAND_USDHC_BUS_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(1)); From 3c1c28d4e032d33697b95fc88152df8a679f44be Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 11:35:15 +0800 Subject: [PATCH 24/51] imx8m: add sdhc/nand/ecspi clk api Current DM CLK is a bit complicated, for simplity, let DM clk only support enable/disable/get_rate. For the expected rate settings, we use non-DM clk to do that. Then we could have simple DM clk for i.MX and could also share between SPL/U-Boot proper. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/clock_imx8mm.c | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 0a8208606d1..68effbd54f5 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -317,6 +317,72 @@ void init_wdog_clk(void) clock_enable(CCGR_WDOG3, 1); } +void init_clk_usdhc(u32 index) +{ + /* + * set usdhc clock root + * sys pll1 400M + */ + switch (index) { + case 0: + clock_enable(CCGR_USDHC1, 0); + clock_set_target_val(USDHC1_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_USDHC1, 1); + return; + case 1: + clock_enable(CCGR_USDHC2, 0); + clock_set_target_val(USDHC2_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_USDHC2, 1); + return; + case 2: + clock_enable(CCGR_USDHC3, 0); + clock_set_target_val(USDHC3_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_USDHC3, 1); + return; + default: + printf("Invalid usdhc index\n"); + return; + } +} + +void init_clk_ecspi(u32 index) +{ + switch (index) { + case 0: + clock_enable(CCGR_ECSPI1, 0); + clock_set_target_val(ECSPI1_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_ECSPI1, 1); + return; + case 1: + clock_enable(CCGR_ECSPI2, 0); + clock_set_target_val(ECSPI2_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_ECSPI2, 1); + case 2: + clock_enable(CCGR_ECSPI3, 0); + clock_set_target_val(ECSPI3_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_ECSPI3, 1); + return; + default: + printf("Invalid ecspi index\n"); + return; + } +} + +void init_nand_clk(void) +{ + /* + * set rawnand root + * sys pll1 400M + */ + clock_enable(CCGR_RAWNAND, 0); + clock_set_target_val(NAND_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(3) | CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4)); /* 100M */ + clock_enable(CCGR_RAWNAND, 1); +} + int clock_init(void) { u32 val_cfg0; From 3c9221ad27b10d649ff46e5ee89d0d54f86745eb Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 13:14:20 +0800 Subject: [PATCH 25/51] imx8m: add eqos clk Add imx_eqos_txclk_set_rate/imx_get_eqos_csr_clk to override the weak function in driver Add set_clk_eqos to configure eQoS clk Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/clock_imx8mm.c | 90 ++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 68effbd54f5..3610f5b2fca 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -788,6 +788,96 @@ u32 mxc_get_clock(enum mxc_clock clk) return 0; } +#ifdef CONFIG_DWC_ETH_QOS +int set_clk_eqos(enum enet_freq type) +{ + u32 target; + u32 enet1_ref; + + switch (type) { + case ENET_125MHZ: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK; + break; + case ENET_50MHZ: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK; + break; + case ENET_25MHZ: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK; + break; + default: + return -EINVAL; + } + + /* disable the clock first */ + clock_enable(CCGR_QOS_ETHENET, 0); + clock_enable(CCGR_SDMA2, 0); + + /* set enet axi clock 266Mhz */ + target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_SYS1_PLL_266M | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(ENET_AXI_CLK_ROOT, target); + + target = CLK_ROOT_ON | enet1_ref | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + clock_set_target_val(ENET_QOS_CLK_ROOT, target); + + target = CLK_ROOT_ON | + ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); + clock_set_target_val(ENET_QOS_TIMER_CLK_ROOT, target); + + /* enable clock */ + clock_enable(CCGR_QOS_ETHENET, 1); + clock_enable(CCGR_SDMA2, 1); + + return 0; +} + +int imx_eqos_txclk_set_rate(u32 rate) +{ + u32 val; + u32 eqos_post_div; + + /* disable the clock first */ + clock_enable(CCGR_QOS_ETHENET, 0); + clock_enable(CCGR_SDMA2, 0); + + switch (rate) { + case 125000000: + eqos_post_div = 1; + break; + case 25000000: + eqos_post_div = 125000000 / 25000000; + break; + case 2500000: + eqos_post_div = 125000000 / 2500000; + break; + default: + return -EINVAL; + } + + clock_get_target_val(ENET_QOS_CLK_ROOT, &val); + val &= ~(CLK_ROOT_PRE_DIV_MASK | CLK_ROOT_POST_DIV_MASK); + val |= CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(eqos_post_div - 1); + clock_set_target_val(ENET_QOS_CLK_ROOT, val); + + /* enable clock */ + clock_enable(CCGR_QOS_ETHENET, 1); + clock_enable(CCGR_SDMA2, 1); + + return 0; +} + +u32 imx_get_eqos_csr_clk(void) +{ + return get_root_clk(ENET_AXI_CLK_ROOT); +} +#endif + #ifdef CONFIG_FEC_MXC int set_clk_enet(enum enet_freq type) { From 2f3c92060dcd6bc9cfd3e2e344a3e1745ca39f09 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 13:39:26 +0800 Subject: [PATCH 26/51] imx8m: workaround ROM serror ROM SError happens on two cases: 1. ERR050342, on iMX8MQ HDCP enabled parts ROM writes to GPV1 register, but when ROM patch lock is fused, this write will cause SError. 2. ERR050350, on iMX8MQ/MM/MN, when the field return fuse is burned, HAB is field return mode, but the last 4K of ROM is still protected and cause SError. Since ROM mask SError until ATF unmask it, so then ATF always meets the exception. This patch works around the issue in SPL by enabling SPL Exception vectors table and the SError exception, take the exception to eret immediately to clear the SError. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index fae69be1c7a..9caf08e86cf 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -16,8 +16,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -527,3 +529,39 @@ void imx_tmu_arch_init(void *reg_base) writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38); #endif } + +#if defined(CONFIG_SPL_BUILD) +#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN) +bool serror_need_skip = true; + +void do_error(struct pt_regs *pt_regs, unsigned int esr) +{ + /* + * If stack is still in ROM reserved OCRAM not switch to SPL, + * it is the ROM SError + */ + ulong sp; + + asm volatile("mov %0, sp" : "=r"(sp) : ); + + if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) { + /* Check for ERR050342, imx8mq HDCP enabled parts */ + if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) { + serror_need_skip = false; + return; /* Do nothing skip the SError in ROM */ + } + + /* Check for ERR050350, field return mode for imx8mq, mm and mn */ + if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) { + serror_need_skip = false; + return; /* Do nothing skip the SError in ROM */ + } + } + + efi_restore_gd(); + printf("\"Error\" handler, esr 0x%08x\n", esr); + show_regs(pt_regs); + panic("Resetting CPU ...\n"); +} +#endif +#endif From d1eee7eed90b8dc3053ddbe223cf4b3e75567b41 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 20 Apr 2020 20:12:54 -0700 Subject: [PATCH 27/51] imx8mp: Add fused parts support iMX8MP has 6 fused parts in each qualification tier, with core, VPU, ISP, NPU or DSP fused respectively. The configuration tables for enabled modules: MIMX8ML8DVNLZAA Quad Core, VPU, NPU, ISP, DSP MIMX8ML7DVNLZAA Quad Core, NPU, ISP MIMX8ML6DVNLZAA Quad Core, VPU, ISP MIMX8ML5DVNLZAA Quad Core, VPU MIMX8ML4DVNLZAA Quad Lite MIMX8ML3DVNLZAA Dual Core, VPU, NPU, ISP, DSP Add the support in U-Boot Reviewed-by: Peng Fan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx/cpu.h | 5 ++++ arch/arm/include/asm/mach-imx/sys_proto.h | 9 +++++- arch/arm/mach-imx/cpu.c | 12 +++++++- arch/arm/mach-imx/imx8m/soc.c | 34 ++++++++++++++++++++++- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index e9c00789226..75ff991248c 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -41,6 +41,11 @@ #define MXC_CPU_IMX8MNDL 0x8f /* dummy ID */ #define MXC_CPU_IMX8MNSL 0x181 /* dummy ID */ #define MXC_CPU_IMX8MP 0x182/* dummy ID */ +#define MXC_CPU_IMX8MP7 0x183 /* dummy ID */ +#define MXC_CPU_IMX8MP6 0x184 /* dummy ID */ +#define MXC_CPU_IMX8MP5 0x185 /* dummy ID */ +#define MXC_CPU_IMX8MPL 0x186 /* dummy ID */ +#define MXC_CPU_IMX8MPD 0x187 /* dummy ID */ #define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */ #define MXC_CPU_IMX8QM 0x91 /* dummy ID */ #define MXC_CPU_IMX8QXP 0x92 /* dummy ID */ diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 0bc705df172..ab94024c9b8 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -66,7 +66,14 @@ struct bd_info; #define is_imx8mnl() (is_cpu_type(MXC_CPU_IMX8MNL)) #define is_imx8mndl() (is_cpu_type(MXC_CPU_IMX8MNDL)) #define is_imx8mnsl() (is_cpu_type(MXC_CPU_IMX8MNSL)) -#define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP)) +#define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP) || is_cpu_type(MXC_CPU_IMX8MPD) || \ + is_cpu_type(MXC_CPU_IMX8MPL) || is_cpu_type(MXC_CPU_IMX8MP7) || \ + is_cpu_type(MXC_CPU_IMX8MP6) || is_cpu_type(MXC_CPU_IMX8MP5)) +#define is_imx8mpd() (is_cpu_type(MXC_CPU_IMX8MPD)) +#define is_imx8mpl() (is_cpu_type(MXC_CPU_IMX8MPL)) +#define is_imx8mp7() (is_cpu_type(MXC_CPU_IMX8MP7)) +#define is_imx8mp6() (is_cpu_type(MXC_CPU_IMX8MP6)) +#define is_imx8mp5() (is_cpu_type(MXC_CPU_IMX8MP5)) #define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP)) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index f2070c97143..b89d27ffd23 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -96,7 +96,17 @@ const char *get_imx_type(u32 imxtype) { switch (imxtype) { case MXC_CPU_IMX8MP: - return "8MP"; /* Quad-core version of the imx8mp */ + return "8MP[8]"; /* Quad-core version of the imx8mp */ + case MXC_CPU_IMX8MPD: + return "8MP Dual[3]"; /* Dual-core version of the imx8mp */ + case MXC_CPU_IMX8MPL: + return "8MP Lite[4]"; /* Quad-core Lite version of the imx8mp */ + case MXC_CPU_IMX8MP7: + return "8MP[7]"; /* Quad-core version of the imx8mp, VPU fused */ + case MXC_CPU_IMX8MP6: + return "8MP[6]"; /* Quad-core version of the imx8mp, NPU fused */ + case MXC_CPU_IMX8MP5: + return "8MP[5]"; /* Quad-core version of the imx8mp, ISP fused */ case MXC_CPU_IMX8MN: return "8MNano Quad"; /* Quad-core version */ case MXC_CPU_IMX8MND: diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 9caf08e86cf..c103bc3ad10 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -211,6 +211,38 @@ static u32 get_cpu_variant_type(u32 type) return MXC_CPU_IMX8MNL; break; } + } else if (type == MXC_CPU_IMX8MP) { + u32 value0 = readl(&fuse->tester3); + u32 flag = 0; + + if ((value0 & 0xc0000) == 0x80000) + return MXC_CPU_IMX8MPD; + + /* vpu disabled */ + if ((value0 & 0x43000000) == 0x43000000) + flag = 1; + + /* npu disabled*/ + if ((value & 0x8) == 0x8) + flag |= (1 << 1); + + /* isp disabled */ + if ((value & 0x3) == 0x3) + flag |= (1 << 2); + + switch (flag) { + case 7: + return MXC_CPU_IMX8MPL; + case 6: + return MXC_CPU_IMX8MP5; + case 2: + return MXC_CPU_IMX8MP6; + case 1: + return MXC_CPU_IMX8MP7; + default: + break; + } + } return type; @@ -228,7 +260,7 @@ u32 get_cpu_rev(void) /* iMX8MP */ if (major_low == 0x43) { - return (MXC_CPU_IMX8MP << 12) | reg; + type = get_cpu_variant_type(MXC_CPU_IMX8MP); } else if (major_low == 0x42) { /* iMX8MN */ type = get_cpu_variant_type(MXC_CPU_IMX8MN); From 7a42bf048932af61e9f095a90edc96da394dee37 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 13:52:41 +0800 Subject: [PATCH 28/51] imx8m: power down fused cores For non-Quad SoCs, the fused cpu cores could be powered down in SPL to save power. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/imx-regs.h | 158 +++++++++++++++++++++ arch/arm/mach-imx/imx8m/soc.c | 19 +++ 2 files changed, 177 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h index 3cfa169c971..f1c410ec78a 100644 --- a/arch/arm/include/asm/arch-imx8m/imx-regs.h +++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h @@ -331,5 +331,163 @@ struct bootrom_sw_info { #define ROM_SW_INFO_ADDR is_soc_rev(CHIP_REV_1_0) ? \ (struct bootrom_sw_info **)ROM_SW_INFO_ADDR_A0 : \ (struct bootrom_sw_info **)ROM_SW_INFO_ADDR_B0 + +struct gpc_reg { + u32 lpcr_bsc; + u32 lpcr_ad; + u32 lpcr_cpu1; + u32 lpcr_cpu2; + u32 lpcr_cpu3; + u32 slpcr; + u32 mst_cpu_mapping; + u32 mmdc_cpu_mapping; + u32 mlpcr; + u32 pgc_ack_sel; + u32 pgc_ack_sel_m4; + u32 gpc_misc; + u32 imr1_core0; + u32 imr2_core0; + u32 imr3_core0; + u32 imr4_core0; + u32 imr1_core1; + u32 imr2_core1; + u32 imr3_core1; + u32 imr4_core1; + u32 imr1_cpu1; + u32 imr2_cpu1; + u32 imr3_cpu1; + u32 imr4_cpu1; + u32 imr1_cpu3; + u32 imr2_cpu3; + u32 imr3_cpu3; + u32 imr4_cpu3; + u32 isr1_cpu0; + u32 isr2_cpu0; + u32 isr3_cpu0; + u32 isr4_cpu0; + u32 isr1_cpu1; + u32 isr2_cpu1; + u32 isr3_cpu1; + u32 isr4_cpu1; + u32 isr1_cpu2; + u32 isr2_cpu2; + u32 isr3_cpu2; + u32 isr4_cpu2; + u32 isr1_cpu3; + u32 isr2_cpu3; + u32 isr3_cpu3; + u32 isr4_cpu3; + u32 slt0_cfg; + u32 slt1_cfg; + u32 slt2_cfg; + u32 slt3_cfg; + u32 slt4_cfg; + u32 slt5_cfg; + u32 slt6_cfg; + u32 slt7_cfg; + u32 slt8_cfg; + u32 slt9_cfg; + u32 slt10_cfg; + u32 slt11_cfg; + u32 slt12_cfg; + u32 slt13_cfg; + u32 slt14_cfg; + u32 pgc_cpu_0_1_mapping; + u32 cpu_pgc_up_trg; + u32 mix_pgc_up_trg; + u32 pu_pgc_up_trg; + u32 cpu_pgc_dn_trg; + u32 mix_pgc_dn_trg; + u32 pu_pgc_dn_trg; + u32 lpcr_bsc2; + u32 pgc_cpu_2_3_mapping; + u32 lps_cpu0; + u32 lps_cpu1; + u32 lps_cpu2; + u32 lps_cpu3; + u32 gpc_gpr; + u32 gtor; + u32 debug_addr1; + u32 debug_addr2; + u32 cpu_pgc_up_status1; + u32 mix_pgc_up_status0; + u32 mix_pgc_up_status1; + u32 mix_pgc_up_status2; + u32 m4_mix_pgc_up_status0; + u32 m4_mix_pgc_up_status1; + u32 m4_mix_pgc_up_status2; + u32 pu_pgc_up_status0; + u32 pu_pgc_up_status1; + u32 pu_pgc_up_status2; + u32 m4_pu_pgc_up_status0; + u32 m4_pu_pgc_up_status1; + u32 m4_pu_pgc_up_status2; + u32 a53_lp_io_0; + u32 a53_lp_io_1; + u32 a53_lp_io_2; + u32 cpu_pgc_dn_status1; + u32 mix_pgc_dn_status0; + u32 mix_pgc_dn_status1; + u32 mix_pgc_dn_status2; + u32 m4_mix_pgc_dn_status0; + u32 m4_mix_pgc_dn_status1; + u32 m4_mix_pgc_dn_status2; + u32 pu_pgc_dn_status0; + u32 pu_pgc_dn_status1; + u32 pu_pgc_dn_status2; + u32 m4_pu_pgc_dn_status0; + u32 m4_pu_pgc_dn_status1; + u32 m4_pu_pgc_dn_status2; + u32 res[3]; + u32 mix_pdn_flg; + u32 pu_pdn_flg; + u32 m4_mix_pdn_flg; + u32 m4_pu_pdn_flg; + u32 imr1_core2; + u32 imr2_core2; + u32 imr3_core2; + u32 imr4_core2; + u32 imr1_core3; + u32 imr2_core3; + u32 imr3_core3; + u32 imr4_core3; + u32 pgc_ack_sel_pu; + u32 pgc_ack_sel_m4_pu; + u32 slt15_cfg; + u32 slt16_cfg; + u32 slt17_cfg; + u32 slt18_cfg; + u32 slt19_cfg; + u32 gpc_pu_pwrhsk; + u32 slt0_cfg_pu; + u32 slt1_cfg_pu; + u32 slt2_cfg_pu; + u32 slt3_cfg_pu; + u32 slt4_cfg_pu; + u32 slt5_cfg_pu; + u32 slt6_cfg_pu; + u32 slt7_cfg_pu; + u32 slt8_cfg_pu; + u32 slt9_cfg_pu; + u32 slt10_cfg_pu; + u32 slt11_cfg_pu; + u32 slt12_cfg_pu; + u32 slt13_cfg_pu; + u32 slt14_cfg_pu; + u32 slt15_cfg_pu; + u32 slt16_cfg_pu; + u32 slt17_cfg_pu; + u32 slt18_cfg_pu; + u32 slt19_cfg_pu; +}; + +struct pgc_reg { + u32 pgcr; + u32 pgpupscr; + u32 pgpdnscr; + u32 pgsr; + u32 pgauxsw; + u32 pgdr; +}; #endif #endif diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index c103bc3ad10..f74a343ed8a 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -342,6 +342,25 @@ int arch_cpu_init(void) if (IS_ENABLED(CONFIG_SPL_BUILD)) { clock_init(); imx_set_wdog_powerdown(false); + + if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || + is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() || + is_imx8mnsl() || is_imx8mpd()) { + /* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */ + struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840); + struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880); + struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0); + struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR; + + writel(0x1, &pgc_core2->pgcr); + writel(0x1, &pgc_core3->pgcr); + if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl()) { + writel(0x1, &pgc_core1->pgcr); + writel(0xE, &gpc->cpu_pgc_dn_trg); + } else { + writel(0xC, &gpc->cpu_pgc_dn_trg); + } + } } if (is_imx8mq()) { From 2707faf01f04ee24b297e9da8988f4d05e971735 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 15 Jul 2019 01:16:46 -0700 Subject: [PATCH 29/51] imx8mn/imx8mp: override env_get_offset and env_get_location To use one defconfig for all boot device, we have to runtime set env offset and return env medium according to the boot device. This patch overrides the env_get_offset and env_get_location to implement the feature. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 59 +++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index f74a343ed8a..9517a7cfcf1 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -616,3 +618,60 @@ void do_error(struct pt_regs *pt_regs, unsigned int esr) } #endif #endif + +#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP) +enum env_location env_get_location(enum env_operation op, int prio) +{ + enum boot_device dev = get_boot_device(); + enum env_location env_loc = ENVL_UNKNOWN; + + if (prio) + return env_loc; + + switch (dev) { +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + case QSPI_BOOT: + env_loc = ENVL_SPI_FLASH; + break; +#endif +#ifdef CONFIG_ENV_IS_IN_NAND + case NAND_BOOT: + env_loc = ENVL_NAND; + break; +#endif +#ifdef CONFIG_ENV_IS_IN_MMC + case SD1_BOOT: + case SD2_BOOT: + case SD3_BOOT: + case MMC1_BOOT: + case MMC2_BOOT: + case MMC3_BOOT: + env_loc = ENVL_MMC; + break; +#endif + default: +#if defined(CONFIG_ENV_IS_NOWHERE) + env_loc = ENVL_NOWHERE; +#endif + break; + } + + return env_loc; +} + +#ifndef ENV_IS_EMBEDDED +long long env_get_offset(long long defautl_offset) +{ + enum boot_device dev = get_boot_device(); + + switch (dev) { + case NAND_BOOT: + return (60 << 20); /* 60MB offset for NAND */ + default: + break; + } + + return defautl_offset; +} +#endif +#endif From 6036dba1c82b751fbea3ac2e1ddcd0e70729c402 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 14:06:49 +0800 Subject: [PATCH 30/51] imx8m: disable nodes before kernel/mfgtool boot for fused part To fused part, we need to disable nodes of dtb to let kernel boot. To mfgtool, USB issue when using super-speed for mfgtool, temporally work around the problem to use high-speed only. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 335 +++++++++++++++++++++++++++++++++- 1 file changed, 334 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 9517a7cfcf1..bb2f112af69 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -428,11 +428,297 @@ bool is_usb_boot(void) } #ifdef CONFIG_OF_SYSTEM_SETUP -int ft_system_setup(void *blob, bd_t *bd) +bool check_fdt_new_path(void *blob) +{ + const char *soc_path = "/soc@0"; + int nodeoff; + + nodeoff = fdt_path_offset(blob, soc_path); + if (nodeoff < 0) + return false; + + return true; +} + +static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array) { int i = 0; int rc; int nodeoff; + const char *status = "disabled"; + + for (i = 0; i < size_array; i++) { + nodeoff = fdt_path_offset(blob, nodes_path[i]); + if (nodeoff < 0) + continue; /* Not found, skip it */ + + printf("Found %s node\n", nodes_path[i]); + +add_status: + rc = fdt_setprop(blob, nodeoff, "status", status, strlen(status) + 1); + if (rc) { + if (rc == -FDT_ERR_NOSPACE) { + rc = fdt_increase_size(blob, 512); + if (!rc) + goto add_status; + } + printf("Unable to update property %s:%s, err=%s\n", + nodes_path[i], "status", fdt_strerror(rc)); + } else { + printf("Modify %s:%s disabled\n", + nodes_path[i], "status"); + } + } + + return 0; +} + +#ifdef CONFIG_IMX8MQ +bool check_dcss_fused(void) +{ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[1]; + struct fuse_bank1_regs *fuse = + (struct fuse_bank1_regs *)bank->fuse_regs; + u32 value = readl(&fuse->tester4); + + if (value & 0x4000000) + return true; + + return false; +} + +static int disable_mipi_dsi_nodes(void *blob) +{ + static const char * const nodes_path[] = { + "/mipi_dsi@30A00000", + "/mipi_dsi_bridge@30A00000", + "/dsi_phy@30A00300", + "/soc@0/bus@30800000/mipi_dsi@30a00000", + "/soc@0/bus@30800000/dphy@30a00300" + }; + + return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path)); +} + +static int disable_dcss_nodes(void *blob) +{ + static const char * const nodes_path[] = { + "/dcss@0x32e00000", + "/dcss@32e00000", + "/hdmi@32c00000", + "/hdmi_cec@32c33800", + "/hdmi_drm@32c00000", + "/display-subsystem", + "/sound-hdmi", + "/sound-hdmi-arc", + "/soc@0/bus@32c00000/display-controller@32e00000", + "/soc@0/bus@32c00000/hdmi@32c00000", + }; + + return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path)); +} + +static int check_mipi_dsi_nodes(void *blob) +{ + static const char * const lcdif_path[] = { + "/lcdif@30320000", + "/soc@0/bus@30000000/lcdif@30320000" + }; + static const char * const mipi_dsi_path[] = { + "/mipi_dsi@30A00000", + "/soc@0/bus@30800000/mipi_dsi@30a00000" + }; + static const char * const lcdif_ep_path[] = { + "/lcdif@30320000/port@0/mipi-dsi-endpoint", + "/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint" + }; + static const char * const mipi_dsi_ep_path[] = { + "/mipi_dsi@30A00000/port@1/endpoint", + "/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint" + }; + + int lookup_node; + int nodeoff; + bool new_path = check_fdt_new_path(blob); + int i = new_path ? 1 : 0; + + nodeoff = fdt_path_offset(blob, lcdif_path[i]); + if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) { + /* + * If can't find lcdif node or lcdif node is disabled, + * then disable all mipi dsi, since they only can input + * from DCSS + */ + return disable_mipi_dsi_nodes(blob); + } + + nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]); + if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) + return 0; + + nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]); + if (nodeoff < 0) { + /* + * If can't find lcdif endpoint, then disable all mipi dsi, + * since they only can input from DCSS + */ + return disable_mipi_dsi_nodes(blob); + } + + lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint"); + nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]); + + if (nodeoff > 0 && nodeoff == lookup_node) + return 0; + + return disable_mipi_dsi_nodes(blob); +} +#endif + +int disable_vpu_nodes(void *blob) +{ + static const char * const nodes_path_8mq[] = { + "/vpu@38300000", + "/soc@0/vpu@38300000" + }; + + static const char * const nodes_path_8mm[] = { + "/vpu_g1@38300000", + "/vpu_g2@38310000", + "/vpu_h1@38320000" + }; + + static const char * const nodes_path_8mp[] = { + "/vpu_g1@38300000", + "/vpu_g2@38310000", + "/vpu_vc8000e@38320000" + }; + + if (is_imx8mq()) + return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq)); + else if (is_imx8mm()) + return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm)); + else if (is_imx8mp()) + return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); + else + return -EPERM; +} + +int disable_gpu_nodes(void *blob) +{ + static const char * const nodes_path_8mn[] = { + "/gpu@38000000" + }; + + return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn)); +} + +int disable_npu_nodes(void *blob) +{ + static const char * const nodes_path_8mp[] = { + "/vipsi@38500000" + }; + + return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); +} + +int disable_isp_nodes(void *blob) +{ + static const char * const nodes_path_8mp[] = { + "/soc@0/bus@32c00000/camera/isp@32e10000", + "/soc@0/bus@32c00000/camera/isp@32e20000" + }; + + return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); +} + +int disable_dsp_nodes(void *blob) +{ + static const char * const nodes_path_8mp[] = { + "/dsp@3b6e8000" + }; + + return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp)); +} + +static int disable_cpu_nodes(void *blob, u32 disabled_cores) +{ + static const char * const nodes_path[] = { + "/cpus/cpu@1", + "/cpus/cpu@2", + "/cpus/cpu@3", + }; + u32 i = 0; + int rc; + int nodeoff; + + if (disabled_cores > 3) + return -EINVAL; + + i = 3 - disabled_cores; + + for (; i < 3; i++) { + nodeoff = fdt_path_offset(blob, nodes_path[i]); + if (nodeoff < 0) + continue; /* Not found, skip it */ + + debug("Found %s node\n", nodes_path[i]); + + rc = fdt_del_node(blob, nodeoff); + if (rc < 0) { + printf("Unable to delete node %s, err=%s\n", + nodes_path[i], fdt_strerror(rc)); + } else { + printf("Delete node %s\n", nodes_path[i]); + } + } + + return 0; +} + +int ft_system_setup(void *blob, bd_t *bd) +{ +#ifdef CONFIG_IMX8MQ + int i = 0; + int rc; + int nodeoff; + + if (get_boot_device() == USB_BOOT) { + disable_dcss_nodes(blob); + + bool new_path = check_fdt_new_path(blob); + int v = new_path ? 1 : 0; + static const char * const usb_dwc3_path[] = { + "/usb@38100000/dwc3", + "/soc@0/usb@38100000" + }; + + nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]); + if (nodeoff >= 0) { + const char *speed = "high-speed"; + + printf("Found %s node\n", usb_dwc3_path[v]); + +usb_modify_speed: + + rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1); + if (rc) { + if (rc == -FDT_ERR_NOSPACE) { + rc = fdt_increase_size(blob, 512); + if (!rc) + goto usb_modify_speed; + } + printf("Unable to set property %s:%s, err=%s\n", + usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc)); + } else { + printf("Modify %s:%s = %s\n", + usb_dwc3_path[v], "maximum-speed", speed); + } + } else { + printf("Can't found %s node\n", usb_dwc3_path[v]); + } + } /* Disable the CPU idle for A0 chip since the HW does not support it */ if (is_soc_rev(CHIP_REV_1_0)) { @@ -464,6 +750,53 @@ int ft_system_setup(void *blob, bd_t *bd) } } + if (is_imx8mql()) { + disable_vpu_nodes(blob); + if (check_dcss_fused()) { + printf("DCSS is fused\n"); + disable_dcss_nodes(blob); + check_mipi_dsi_nodes(blob); + } + } + + if (is_imx8md()) + disable_cpu_nodes(blob, 2); + +#elif defined(CONFIG_IMX8MM) + if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl()) + disable_vpu_nodes(blob); + + if (is_imx8mmd() || is_imx8mmdl()) + disable_cpu_nodes(blob, 2); + else if (is_imx8mms() || is_imx8mmsl()) + disable_cpu_nodes(blob, 3); + +#elif defined(CONFIG_IMX8MN) + if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl()) + disable_gpu_nodes(blob); + + if (is_imx8mnd() || is_imx8mndl()) + disable_cpu_nodes(blob, 2); + else if (is_imx8mns() || is_imx8mnsl()) + disable_cpu_nodes(blob, 3); + +#elif defined(CONFIG_IMX8MP) + if (is_imx8mpl() || is_imx8mp7()) + disable_vpu_nodes(blob); + + if (is_imx8mpl() || is_imx8mp6() || is_imx8mp5()) + disable_npu_nodes(blob); + + if (is_imx8mpl() || is_imx8mp5()) + disable_isp_nodes(blob); + + if (is_imx8mpl() || is_imx8mp7() || is_imx8mp6() || is_imx8mp5()) + disable_dsp_nodes(blob); + + if (is_imx8mpd()) + disable_cpu_nodes(blob, 2); +#endif + return 0; } #endif From ec04ae4217e6f68ad7ccd7740e540d79a3f4e1c1 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 15:36:22 +0800 Subject: [PATCH 31/51] clk: imx8m: drop clk settings We use non-dm code to configure the clk settings in order to simplify dm clk driver in future, so remove the duplicated code from clk driver Signed-off-by: Peng Fan --- drivers/clk/imx/clk-imx8mm.c | 34 ---------------------------------- drivers/clk/imx/clk-imx8mn.c | 34 ---------------------------------- 2 files changed, 68 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 85d17575364..d32ff8409aa 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -437,40 +437,6 @@ static int imx8mm_clk_probe(struct udevice *dev) base + 0x40a0, 0)); #endif -#ifdef CONFIG_SPL_BUILD - struct clk *clkp, *clkp1; - - clk_get_by_id(IMX8MM_CLK_WDOG1_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MM_CLK_WDOG2_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MM_CLK_WDOG3_ROOT, &clkp); - clk_enable(clkp); - - /* Configure SYS_PLL3 to 750MHz */ - clk_get_by_id(IMX8MM_SYS_PLL3, &clkp); - clk_set_rate(clkp, 750000000UL); - clk_enable(clkp); - - /* Configure ARM to sys_pll2_500m */ - clk_get_by_id(IMX8MM_CLK_A53_SRC, &clkp); - clk_get_by_id(IMX8MM_SYS_PLL2_OUT, &clkp1); - clk_enable(clkp1); - clk_get_by_id(IMX8MM_SYS_PLL2_500M, &clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure ARM PLL to 1.2GHz */ - clk_get_by_id(IMX8MM_ARM_PLL, &clkp1); - clk_set_rate(clkp1, 1200000000UL); - clk_get_by_id(IMX8MM_ARM_PLL_OUT, &clkp1); - clk_enable(clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure DIV to 1.2GHz */ - clk_get_by_id(IMX8MM_CLK_A53_DIV, &clkp1); - clk_set_rate(clkp1, 1200000000UL); -#endif - return 0; } diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 8bf6061a327..e29d902544c 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -440,40 +440,6 @@ static int imx8mn_clk_probe(struct udevice *dev) base + 0x40a0, 0)); #endif -#ifdef CONFIG_SPL_BUILD - struct clk *clkp, *clkp1; - - clk_get_by_id(IMX8MN_CLK_WDOG1_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MN_CLK_WDOG2_ROOT, &clkp); - clk_enable(clkp); - clk_get_by_id(IMX8MN_CLK_WDOG3_ROOT, &clkp); - clk_enable(clkp); - - /* Configure SYS_PLL3 to 600MHz */ - clk_get_by_id(IMX8MN_SYS_PLL3, &clkp); - clk_set_rate(clkp, 600000000UL); - clk_enable(clkp); - - /* Configure ARM to sys_pll2_500m */ - clk_get_by_id(IMX8MN_CLK_A53_SRC, &clkp); - clk_get_by_id(IMX8MN_SYS_PLL2_OUT, &clkp1); - clk_enable(clkp1); - clk_get_by_id(IMX8MN_SYS_PLL2_500M, &clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure ARM PLL to 1.2GHz */ - clk_get_by_id(IMX8MN_ARM_PLL, &clkp1); - clk_set_rate(clkp1, 1200000000UL); - clk_get_by_id(IMX8MN_ARM_PLL_OUT, &clkp1); - clk_enable(clkp1); - clk_set_parent(clkp, clkp1); - - /* Configure DIV to 1.2GHz */ - clk_get_by_id(IMX8MN_CLK_A53_DIV, &clkp1); - clk_set_rate(clkp1, 1200000000UL); -#endif - return 0; } From 3c41728d80f7a6178dd4ec91c28347d9768ab200 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Thu, 9 Jul 2020 15:26:06 +0800 Subject: [PATCH 32/51] imx8m: Refactor the OPTEE memory removal Current codes assume the OPTEE address is at the end of first DRAM bank. Adjust the process to allow OPTEE in the middle of first bank. When OPTEE memory is removed from first bank, it may split the first bank to two banks, adjust the MMU table for the split case, Since the default CONFIG_NR_DRAM_BANKS is 4, it is enough, just enlarge i.MX8MP evk to default to avoid issue. Signed-off-by: Ye Li Signed-off-by: Silvano di Ninno Tested-by: Silvano di Ninno Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 122 +++++++++++++++++- board/beacon/imx8mm/imx8mm_beacon.c | 11 -- board/freescale/imx8mm_evk/imx8mm_evk.c | 11 -- board/freescale/imx8mn_evk/imx8mn_evk.c | 7 - board/freescale/imx8mp_evk/imx8mp_evk.c | 40 ------ board/freescale/imx8mq_evk/imx8mq_evk.c | 11 -- .../google/imx8mq_phanbell/imx8mq_phanbell.c | 11 -- board/technexion/pico-imx8mq/pico-imx8mq.c | 26 ++-- board/toradex/verdin-imx8mm/verdin-imx8mm.c | 11 -- configs/imx8mp_evk_defconfig | 1 - 10 files changed, 127 insertions(+), 124 deletions(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index bb2f112af69..b3c08271e60 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -142,6 +142,9 @@ static struct mm_region imx8m_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE #endif + }, { + /* empty entrie to split table entry 5 if needed when TEEs are used */ + 0, }, { /* List terminator */ 0, @@ -152,18 +155,123 @@ struct mm_region *mem_map = imx8m_mem_map; void enable_caches(void) { - /* - * If OPTEE runs, remove OPTEE memory from MMU table to - * avoid speculative prefetch. OPTEE runs at the top of - * the first memory bank - */ - if (rom_pointer[1]) - imx8m_mem_map[5].size -= rom_pointer[1]; + /* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */ + if (rom_pointer[1]) { + /* + * TEE are loaded, So the ddr bank structures + * have been modified update mmu table accordingly + */ + int i = 0; + /* + * please make sure that entry initial value matches + * imx8m_mem_map for DRAM1 + */ + int entry = 5; + u64 attrs = imx8m_mem_map[entry].attrs; + + while (i < CONFIG_NR_DRAM_BANKS && entry < 8) { + if (gd->bd->bi_dram[i].start == 0) + break; + imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start; + imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start; + imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size; + imx8m_mem_map[entry].attrs = attrs; + debug("Added memory mapping (%d): %llx %llx\n", entry, + imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size); + i++; entry++; + } + } icache_enable(); dcache_enable(); } +__weak int board_phys_sdram_size(phys_size_t *size) +{ + if (!size) + return -EINVAL; + + *size = PHYS_SDRAM_SIZE; + return 0; +} + +int dram_init(void) +{ + phys_size_t sdram_size; + int ret; + + ret = board_phys_sdram_size(&sdram_size); + if (ret) + return ret; + + /* rom_pointer[1] contains the size of TEE occupies */ + if (rom_pointer[1]) + gd->ram_size = sdram_size - rom_pointer[1]; + else + gd->ram_size = sdram_size; + +#ifdef PHYS_SDRAM_2_SIZE + gd->ram_size += PHYS_SDRAM_2_SIZE; +#endif + + return 0; +} + +int dram_init_banksize(void) +{ + int bank = 0; + int ret; + phys_size_t sdram_size; + + ret = board_phys_sdram_size(&sdram_size); + if (ret) + return ret; + + gd->bd->bi_dram[bank].start = PHYS_SDRAM; + if (rom_pointer[1]) { + phys_addr_t optee_start = (phys_addr_t)rom_pointer[0]; + phys_size_t optee_size = (size_t)rom_pointer[1]; + + gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start; + if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) { + if (++bank >= CONFIG_NR_DRAM_BANKS) { + puts("CONFIG_NR_DRAM_BANKS is not enough\n"); + return -1; + } + + gd->bd->bi_dram[bank].start = optee_start + optee_size; + gd->bd->bi_dram[bank].size = PHYS_SDRAM + + sdram_size - gd->bd->bi_dram[bank].start; + } + } else { + gd->bd->bi_dram[bank].size = sdram_size; + } + +#ifdef PHYS_SDRAM_2_SIZE + if (++bank >= CONFIG_NR_DRAM_BANKS) { + puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n"); + return -1; + } + gd->bd->bi_dram[bank].start = PHYS_SDRAM_2; + gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE; +#endif + + return 0; +} + +phys_size_t get_effective_memsize(void) +{ + /* return the first bank as effective memory */ + if (rom_pointer[1]) + return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM); + +#ifdef PHYS_SDRAM_2_SIZE + return gd->ram_size - PHYS_SDRAM_2_SIZE; +#else + return gd->ram_size; +#endif +} + static u32 get_cpu_variant_type(u32 type) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; diff --git a/board/beacon/imx8mm/imx8mm_beacon.c b/board/beacon/imx8mm/imx8mm_beacon.c index e82e8b78d80..c61d25fbead 100644 --- a/board/beacon/imx8mm/imx8mm_beacon.c +++ b/board/beacon/imx8mm/imx8mm_beacon.c @@ -13,17 +13,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c index c43af9bc484..6af71006966 100644 --- a/board/freescale/imx8mm_evk/imx8mm_evk.c +++ b/board/freescale/imx8mm_evk/imx8mm_evk.c @@ -15,17 +15,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/board/freescale/imx8mn_evk/imx8mn_evk.c b/board/freescale/imx8mn_evk/imx8mn_evk.c index ea02bb75f41..e5ca54f9ae7 100644 --- a/board/freescale/imx8mn_evk/imx8mn_evk.c +++ b/board/freescale/imx8mn_evk/imx8mn_evk.c @@ -9,13 +9,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - int board_init(void) { return 0; diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c index 97ba15645a2..034a349236e 100644 --- a/board/freescale/imx8mp_evk/imx8mp_evk.c +++ b/board/freescale/imx8mp_evk/imx8mp_evk.c @@ -40,46 +40,6 @@ int board_early_init_f(void) return 0; } -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - -#if CONFIG_NR_DRAM_BANKS > 1 - gd->ram_size += PHYS_SDRAM_2_SIZE; -#endif - - return 0; -} - -int dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = PHYS_SDRAM; - if (rom_pointer[1]) - - gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE; - -#if CONFIG_NR_DRAM_BANKS > 1 - gd->bd->bi_dram[1].start = PHYS_SDRAM_2; - gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; -#endif - - return 0; -} - -phys_size_t get_effective_memsize(void) -{ - if (rom_pointer[1]) - return (PHYS_SDRAM_SIZE - rom_pointer[1]); - else - return PHYS_SDRAM_SIZE; -} - int board_init(void) { return 0; diff --git a/board/freescale/imx8mq_evk/imx8mq_evk.c b/board/freescale/imx8mq_evk/imx8mq_evk.c index ae3be5785c9..1ad670b8ccf 100644 --- a/board/freescale/imx8mq_evk/imx8mq_evk.c +++ b/board/freescale/imx8mq_evk/imx8mq_evk.c @@ -53,17 +53,6 @@ int board_early_init_f(void) return 0; } -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #ifdef CONFIG_FEC_MXC static int setup_fec(void) { diff --git a/board/google/imx8mq_phanbell/imx8mq_phanbell.c b/board/google/imx8mq_phanbell/imx8mq_phanbell.c index c0cc3e9b71d..746071b4150 100644 --- a/board/google/imx8mq_phanbell/imx8mq_phanbell.c +++ b/board/google/imx8mq_phanbell/imx8mq_phanbell.c @@ -48,17 +48,6 @@ int board_early_init_f(void) return 0; } -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #ifdef CONFIG_FEC_MXC static int setup_fec(void) { diff --git a/board/technexion/pico-imx8mq/pico-imx8mq.c b/board/technexion/pico-imx8mq/pico-imx8mq.c index 2a3e6e7e265..330de7137c3 100644 --- a/board/technexion/pico-imx8mq/pico-imx8mq.c +++ b/board/technexion/pico-imx8mq/pico-imx8mq.c @@ -51,24 +51,22 @@ int board_early_init_f(void) return 0; } -int dram_init(void) +int board_phys_sdram_size(phys_size_t *size) { int ddr_size = readl(M4_BOOTROM_BASE_ADDR); - if (ddr_size == 0x4) - gd->ram_size = 0x100000000; - else if (ddr_size == 0x3) - gd->ram_size = 0xc0000000; - else if (ddr_size == 0x2) - gd->ram_size = 0x80000000; - else if (ddr_size == 0x1) - gd->ram_size = 0x40000000; - else + if (ddr_size == 0x4) { + *size = 0x100000000; + } else if (ddr_size == 0x3) { + *size = 0xc0000000; + } else if (ddr_size == 0x2) { + *size = 0x80000000; + } else if (ddr_size == 0x1) { + *size = 0x40000000; + } else { printf("Unknown DDR type!!!\n"); - - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size -= rom_pointer[1]; + return -1; + } return 0; } diff --git a/board/toradex/verdin-imx8mm/verdin-imx8mm.c b/board/toradex/verdin-imx8mm/verdin-imx8mm.c index ff05c7d5523..fa51b776abc 100644 --- a/board/toradex/verdin-imx8mm/verdin-imx8mm.c +++ b/board/toradex/verdin-imx8mm/verdin-imx8mm.c @@ -14,17 +14,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - /* rom_pointer[1] contains the size of TEE occupies */ - if (rom_pointer[1]) - gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; - else - gd->ram_size = PHYS_SDRAM_SIZE; - - return 0; -} - #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig index dcfc336634d..f49116c9c55 100644 --- a/configs/imx8mp_evk_defconfig +++ b/configs/imx8mp_evk_defconfig @@ -16,7 +16,6 @@ CONFIG_TARGET_IMX8MP_EVK=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_DRIVERS_MISC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL=y CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 CONFIG_FIT=y From eb3967388e7707edb21dd537b77a30f57e706fac Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 10 Jul 2020 11:22:20 +0800 Subject: [PATCH 33/51] imx8m: implement armv8_el2_to_aarch32 Add iMX8M specific armv8_el2_to_aarch32 to let AArch64 mode U-Boot could boot aarch32 mode linux with FIT image as below: /dts-v1/; / { description = "Configuration to load ARM32 Linux"; images { kernel@1 { description = "ARM32 Linux kernel"; data = /incbin/("./Image"); type = "kernel"; arch = "arm"; os = "linux"; compression = "none"; load = <0x40008000>; entry = <0x40008000>; hash@1 { algo = "md5"; }; }; fdt@1 { description = "Flattened Device Tree blob"; data = /incbin/("./imx8mm-evk.dtb"); type = "flat_dt"; arch = "arm"; compression = "none"; load = <0x43000000>; hash@1 { algo = "md5"; }; }; }; configurations { default = "config@1"; config@1 { description = "fsl-imx8mm-evk"; kernel = "kernel@1"; fdt = "fdt@1"; }; }; }; Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/lowlevel_init.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/lowlevel_init.S b/arch/arm/mach-imx/imx8m/lowlevel_init.S index a4c6466ca94..a49a9cdb35c 100644 --- a/arch/arm/mach-imx/imx8m/lowlevel_init.S +++ b/arch/arm/mach-imx/imx8m/lowlevel_init.S @@ -60,3 +60,15 @@ restore_boot_params: ldr x0, [x0] mov sp, x0 ret + +.global armv8_el2_to_aarch32 +armv8_el2_to_aarch32: + cmp x0, #0 + bne 0f + mov x3, x2 + mov x2, x1 + mov x1, x4 + ldr x0, =0xc20000fd +0: + smc #0 + ret From 86e9d7e8143eab4cfe4b74628153af9006bb1ad2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 10 Jul 2020 11:24:42 +0800 Subject: [PATCH 34/51] imx8mm_evk: enlarge CONFIG_SYS_BOOTM_LEN Enlarge CONFIG_SYS_BOOTM_LEN when booting FIT image with kernel. Signed-off-by: Peng Fan --- include/configs/imx8mm_evk.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h index 382ba620ccf..d1c0e0ec2ed 100644 --- a/include/configs/imx8mm_evk.h +++ b/include/configs/imx8mm_evk.h @@ -10,6 +10,7 @@ #include #include +#define CONFIG_SYS_BOOTM_LEN (32 * SZ_1M) #define CONFIG_SPL_MAX_SIZE (148 * 1024) #define CONFIG_SYS_MONITOR_LEN SZ_512K #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR From 3e218107437ca84aa27f401158a6c5a202f8e4fb Mon Sep 17 00:00:00 2001 From: Niel Fourie Date: Tue, 19 May 2020 14:01:40 +0200 Subject: [PATCH 35/51] dts-bindings: regulator: Add dlg,da9063-regulator Add da9063-regulator bindings from Linux 5.6: commit 7111951b8d49 upstream Signed-off-by: Niel Fourie Cc: Stefano Babic --- .../dt-bindings/regulator/dlg,da9063-regulator.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 include/dt-bindings/regulator/dlg,da9063-regulator.h diff --git a/include/dt-bindings/regulator/dlg,da9063-regulator.h b/include/dt-bindings/regulator/dlg,da9063-regulator.h new file mode 100644 index 00000000000..1de710dd089 --- /dev/null +++ b/include/dt-bindings/regulator/dlg,da9063-regulator.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DT_BINDINGS_REGULATOR_DLG_DA9063_H +#define _DT_BINDINGS_REGULATOR_DLG_DA9063_H + +/* + * These buck mode constants may be used to specify values in device tree + * properties (e.g. regulator-initial-mode). + * A description of the following modes is in the manufacturers datasheet. + */ + +#define DA9063_BUCK_MODE_SLEEP 1 +#define DA9063_BUCK_MODE_SYNC 2 +#define DA9063_BUCK_MODE_AUTO 3 + +#endif From 08310cf96e334d86ff68def3a7ada84d262c94a8 Mon Sep 17 00:00:00 2001 From: Niel Fourie Date: Tue, 19 May 2020 14:01:41 +0200 Subject: [PATCH 36/51] arm: dts: imx6q: Add Linux dts files for Phytec Mira Add Phytec Mira device tree files, for use with pcm058. >From Linux 5.6, commit 7111951b8d49 upstream Signed-off-by: Niel Fourie Cc: Stefano Babic --- arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts | 72 ++++ arch/arm/dts/imx6qdl-phytec-mira.dtsi | 390 +++++++++++++++++++ arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi | 287 ++++++++++++++ 3 files changed, 749 insertions(+) create mode 100644 arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts create mode 100644 arch/arm/dts/imx6qdl-phytec-mira.dtsi create mode 100644 arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi diff --git a/arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts b/arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts new file mode 100644 index 00000000000..65d2e483c13 --- /dev/null +++ b/arch/arm/dts/imx6q-phytec-mira-rdk-nand.dts @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 PHYTEC Messtechnik GmbH + * Author: Christian Hemp + */ + +/dts-v1/; +#include "imx6q.dtsi" +#include "imx6qdl-phytec-phycore-som.dtsi" +#include "imx6qdl-phytec-mira.dtsi" + +/ { + model = "PHYTEC phyBOARD-Mira Quad Carrier-Board with NAND"; + compatible = "phytec,imx6q-pbac06-nand", "phytec,imx6q-pbac06", + "phytec,imx6qdl-pcm058", "fsl,imx6q"; + + chosen { + stdout-path = &uart2; + }; +}; + +&can1 { + status = "okay"; +}; + +&fec { + status = "okay"; +}; + +&gpmi { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c_rtc { + status = "okay"; +}; + +&m25p80 { + status = "okay"; +}; + +&pcie { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&usbh1 { + status = "okay"; +}; + +&usbotg { + status = "okay"; +}; + +&usdhc1 { + status = "okay"; +}; diff --git a/arch/arm/dts/imx6qdl-phytec-mira.dtsi b/arch/arm/dts/imx6qdl-phytec-mira.dtsi new file mode 100644 index 00000000000..9ebd438dce7 --- /dev/null +++ b/arch/arm/dts/imx6qdl-phytec-mira.dtsi @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 PHYTEC Messtechnik GmbH + * Author: Christian Hemp + */ + + +/ { + aliases { + rtc0 = &i2c_rtc; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <7>; + power-supply = <®_backlight>; + pwms = <&pwm1 0 5000000>; + status = "okay"; + }; + + gpio_leds: leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpioleds>; + status = "disabled"; + + red { + label = "phyboard-mira:red"; + gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>; + }; + + green { + label = "phyboard-mira:green"; + gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>; + }; + + blue { + label = "phyboard-mira:blue"; + gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + }; + }; + + reg_backlight: regulator-backlight { + compatible = "regulator-fixed"; + regulator-name = "backlight_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_en_switch: regulator-en-switch { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_en_switch>; + regulator-name = "Enable Switch"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&gpio3 4 GPIO_ACTIVE_HIGH>; + regulator-always-on; + }; + + reg_flexcan1: regulator-flexcan1 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1_en>; + regulator-name = "flexcan1-reg"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_panel: regulator-panel { + compatible = "regulator-fixed"; + regulator-name = "panel-power-supply"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + + reg_pcie: regulator-pcie { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_reg>; + regulator-name = "mPCIe_1V5"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + gpio = <&gpio3 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_h1_vbus: usb-h1-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1_vbus>; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usbotg_vbus: usbotg-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg_vbus>; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + panel { + compatible = "auo,g104sn02"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_panel_en>; + power-supply = <®_panel>; + enable-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + backlight = <&backlight>; + + port { + panel_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + xceiver-supply = <®_flexcan1>; + status = "disabled"; +}; + +&hdmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmicec>; + ddc-i2c-bus = <&i2c2>; + status = "disabled"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + clock-frequency = <400000>; + status = "disabled"; + + stmpe: touchctrl@44 { + compatible = "st,stmpe811"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_stmpe>; + reg = <0x44>; + interrupt-parent = <&gpio7>; + interrupts = <12 IRQ_TYPE_NONE>; + status = "disabled"; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <1>; + }; + }; + + i2c_rtc: rtc@68 { + compatible = "microcrystal,rv4162"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rtc_int>; + reg = <0x68>; + interrupt-parent = <&gpio7>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; + status = "disabled"; +}; + +&ldb { + status = "okay"; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + status = "disabled"; + + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>; + vpcie-supply = <®_pcie>; + status = "disabled"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; + status = "disabled"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + disable-over-current; + status = "disabled"; +}; + +&usbotg { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + vbus-supply = <®_usbotg_vbus>; + disable-over-current; + status = "disabled"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + cd-gpios = <&gpio6 31 GPIO_ACTIVE_LOW>; + no-1-8-v; + status = "disabled"; +}; + +&iomuxc { + pinctrl_panel_en: panelen1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0xb0b1 + >; + }; + + pinctrl_en_switch: enswitchgrp { + fsl,pins = < + MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0xb0b1 + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0 + MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0 + >; + }; + + pinctrl_flexcan1_en: flexcan1engrp { + fsl,pins = < + MX6QDL_PAD_EIM_A18__GPIO2_IO20 0xb0b1 + >; + }; + + pinctrl_gpioleds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x1b0b0 + MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x1b0b0 + MX6QDL_PAD_CSI0_DAT6__GPIO5_IO24 0x1b0b0 + >; + }; + + pinctrl_hdmicec: hdmicecgrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_EIM_OE__GPIO2_IO25 0xb0b1 + >; + }; + + pinctrl_pcie_reg: pciereggrp { + fsl,pins = < + MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0xb0b1 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1 + >; + }; + + pinctrl_rtc_int: rtcintgrp { + fsl,pins = < + MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x1b0b0 + >; + }; + + pinctrl_stmpe: stmpegrp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB3__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D23__UART3_RTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbh1_vbus: usbh1vbusgrp { + fsl,pins = < + MX6QDL_PAD_EIM_A20__GPIO2_IO18 0xb0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + >; + }; + + pinctrl_usbotg_vbus: usbotgvbusgrp { + fsl,pins = < + MX6QDL_PAD_EIM_A19__GPIO2_IO19 0xb0b1 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9 + MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0xb0b1 /* CD */ + >; + }; +}; diff --git a/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi new file mode 100644 index 00000000000..77d871340eb --- /dev/null +++ b/arch/arm/dts/imx6qdl-phytec-phycore-som.dtsi @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 PHYTEC Messtechnik GmbH + * Author: Christian Hemp + */ + +#include +#include + +/ { + aliases { + rtc1 = &da9062_rtc; + rtc2 = &snvs_rtc; + }; + + /* + * Set the minimum memory size here and + * let the bootloader set the real size. + */ + memory@10000000 { + device_type = "memory"; + reg = <0x10000000 0x8000000>; + }; + + gpio_leds_som: somleds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpioleds_som>; + + som-led-green { + label = "phycore:green"; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; +}; + +&ecspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; + status = "okay"; + + m25p80: flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <20000000>; + reg = <0>; + status = "disabled"; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-handle = <ðphy>; + phy-mode = "rgmii"; + phy-supply = <&vdd_eth_io>; + phy-reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + status = "disabled"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@3 { + reg = <3>; + txc-skew-ps = <1680>; + rxc-skew-ps = <1860>; + }; + }; +}; + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + nand-on-flash-bbt; + status = "disabled"; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <400000>; + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + }; + + pmic@58 { + compatible = "dlg,da9062"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + reg = <0x58>; + interrupt-parent = <&gpio1>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + + da9062_rtc: rtc { + compatible = "dlg,da9062-rtc"; + }; + + da9062_onkey: onkey { + compatible = "dlg,da9062-onkey"; + }; + + watchdog { + compatible = "dlg,da9062-watchdog"; + }; + + regulators { + vdd_arm: buck1 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <1380000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vdd_soc: buck2 { + regulator-name = "vdd_soc"; + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1380000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vdd_ddr3_1p5: buck3 { + regulator-name = "vdd_ddr3"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vdd_eth_1p2: buck4 { + regulator-name = "vdd_eth"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-always-on; + }; + + vdd_snvs: ldo1 { + regulator-name = "vdd_snvs"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + vdd_high: ldo2 { + regulator-name = "vdd_high"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + vdd_eth_io: ldo3 { + regulator-name = "vdd_eth_io"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + }; + + vdd_emmc_1p8: ldo4 { + regulator-name = "vdd_emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + }; + }; +}; + +®_arm { + vin-supply = <&vdd_arm>; +}; + +®_pu { + vin-supply = <&vdd_soc>; +}; + +®_soc { + vin-supply = <&vdd_soc>; +}; + +&snvs_poweroff { + status = "okay"; +}; + +&usdhc4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc4>; + bus-width = <8>; + non-removable; + status = "disabled"; +}; + +&iomuxc { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0 + >; + }; + + pinctrl_gpioleds_som: gpioledssomgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 + >; + }; + + pinctrl_gpmi_nand: gpminandgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1 + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1 + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000 + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1 + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1 + MX6QDL_PAD_NANDF_CS2__NAND_CE2_B 0xb0b1 + MX6QDL_PAD_NANDF_CS3__NAND_CE3_B 0xb0b1 + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1 + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1 + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1 + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1 + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1 + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1 + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1 + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1 + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1 + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1 + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1 + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0 + >; + }; + + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 + >; + }; +}; From 7e64182ef402f5e74c1a1c0a39ef88d52cbd0d65 Mon Sep 17 00:00:00 2001 From: Niel Fourie Date: Tue, 19 May 2020 14:01:42 +0200 Subject: [PATCH 37/51] arm: imx6q: pcm058: change MAINTAINER Change the MAINTAINER of pcm058. Signed-off-by: Niel Fourie Cc: Stefano Babic --- board/phytec/pcm058/MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/board/phytec/pcm058/MAINTAINERS b/board/phytec/pcm058/MAINTAINERS index b0ca40277f0..909dfc44af0 100644 --- a/board/phytec/pcm058/MAINTAINERS +++ b/board/phytec/pcm058/MAINTAINERS @@ -1,6 +1,7 @@ PHYTEC PHYBOARD MIRA -M: Stefano Babic +M: Niel Fourie S: Maintained F: board/phytec/pcm058/ F: include/configs/pcm058.h F: configs/pcm058_defconfig +F: arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi From 26a6ed1b2e0d07c263d19bd48706a7be05f8c18d Mon Sep 17 00:00:00 2001 From: Niel Fourie Date: Tue, 19 May 2020 14:01:43 +0200 Subject: [PATCH 38/51] arm: imx6q: pcm058: Convert pcm058 to use DM with DTs Convert pcm058 support to use device trees and the driver model. Add rudimentary boot scripts to the environment, expand README. Signed-off-by: Niel Fourie Cc: Stefano Babic --- arch/arm/dts/Makefile | 1 + .../imx6q-phytec-mira-rdk-nand-u-boot.dtsi | 42 +++ arch/arm/mach-imx/mx6/Kconfig | 4 + board/phytec/pcm058/README | 51 +++ board/phytec/pcm058/pcm058.c | 325 ++---------------- configs/pcm058_defconfig | 42 ++- include/configs/pcm058.h | 67 ++-- 7 files changed, 177 insertions(+), 355 deletions(-) create mode 100644 arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d839cb49b33..cee10f533f5 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -678,6 +678,7 @@ dtb-y += \ imx6q-nitrogen6x.dtb \ imx6q-novena.dtb \ imx6q-pico.dtb \ + imx6q-phytec-mira-rdk-nand.dtb \ imx6q-sabreauto.dtb \ imx6q-sabrelite.dtb \ imx6q-sabresd.dtb \ diff --git a/arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi b/arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi new file mode 100644 index 00000000000..8555be16966 --- /dev/null +++ b/arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 + * Niel Fourie, DENX Software Engineering, lusus@denx.de. + */ +#include "imx6qdl-u-boot.dtsi" + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&pinctrl_uart2 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&usdhc1 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc1 { + u-boot,dm-spl; +}; + +&ecspi1 { + u-boot,dm-spl; +}; + +&pinctrl_ecspi1 { + u-boot,dm-spl; +}; + +&m25p80 { + u-boot,dm-spl; +}; diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index fa6e1112e62..fdee0d4f641 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -511,6 +511,10 @@ config TARGET_PCM058 bool "Phytec PCM058 i.MX6 Quad" select BOARD_LATE_INIT select SUPPORT_SPL + select MX6Q + select DM + select OF_CONTROL + imply CMD_DM config TARGET_PFLA02 bool "Phytec PFLA02 (PhyFlex) i.MX6 Quad" diff --git a/board/phytec/pcm058/README b/board/phytec/pcm058/README index 33271356451..02be0994fcd 100644 --- a/board/phytec/pcm058/README +++ b/board/phytec/pcm058/README @@ -33,3 +33,54 @@ is present, then the RBL tries to load SPL from the SD Card, if not, RBL loads from SPI-NOR. The SPL tries then to load from the same device where SPL was loaded (SD or SPI). Booting from NAND is not supported. + +Flashing U-Boot onto an SD card +------------------------------- + +After a successful build, the generated SPL and U-boot binaries can be copied +to an SD card. Adjust the SD card device as necessary: + +$ sudo dd if=u-boot-with-spl.imx of=/dev/mmcblk0 bs=1k seek=1 + +This is equivalent to separately copying the SPL and U-boot using: + +$ sudo dd if=SPL of=/dev/mmcblk0 bs=1k seek=1 +$ sudo dd if=u-boot-dtb.img of=/dev/mmcblk0 bs=1k seek=197 + +The default bootscripts expect a kernel fit-image file named "fitImage" in the +first partition and Linux ext4 rootfs in the second partition. + +Flashing U-boot to the SPI Flash, for booting Linux from NAND +------------------------------------------------------------- + +The SD card created above can also be used to install the SPL and U-boot into +the SPI flash. Boot U-boot from the SD card as above, and stop at the autoboot. + +Then, clear the SPI flash: + +=> sf probe +=> sf erase 0x0 0x1000000 + +Load the SPL from raw MMC into memory and copy to the SPI. The SPL is maximum +392*512-byte blocks in size therefore 0x188 blocks, totaling 0x31000 bytes: + +=> mmc read ${loadaddr} 0x2 0x188 +=> sf write ${loadaddr} 0x400 0x31000 + +Load the U-boot binary into memory and copy to the SPI. U-boot should fit into +640KiB, so 0x500 512-byte blocks, totalling 0xA0000 bytes: + +=> mmc read ${loadaddr} 0x18a 0x500 +=> sf write ${loadaddr} 0x40000 0xA0000 + +The default NAND bootscripts expect a single MTD partition named "rootfs", +which in turn contains the UBI volumes "fit" (which contains the kernel fit- +image) and "root" (which contains a ubifs root filesystem). + +The "bootm_size" variable in the environment +-------------------------------------------- + +By default, U-boot relocates the device tree towards the upper end of the RAM, +which kernels using CONFIG_HIGHMEM=y may not be able to access during early +boot. With the bootm_size variable set to 0x30000000, U-boot relocates the +device tree to below this address instead. diff --git a/board/phytec/pcm058/pcm058.c b/board/phytec/pcm058/pcm058.c index 096425c5dfe..79c666588f4 100644 --- a/board/phytec/pcm058/pcm058.c +++ b/board/phytec/pcm058/pcm058.c @@ -12,60 +12,14 @@ #include #include #include -#include -#include -#include #include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; -#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ - PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ - PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ - PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) - -#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ - PAD_CTL_ODE | PAD_CTL_SRE_FAST) - -#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL) - -#define ASRC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define NAND_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 14) -#define USDHC1_CD_GPIO IMX_GPIO_NR(6, 31) -#define USER_LED IMX_GPIO_NR(1, 4) #define IMX6Q_DRIVE_STRENGTH 0x30 int dram_init(void) @@ -74,229 +28,16 @@ int dram_init(void) return 0; } -void board_turn_off_led(void) -{ - gpio_direction_output(USER_LED, 0); -} - -static iomux_v3_cfg_t const uart1_pads[] = { - MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), - MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL), -}; - -static iomux_v3_cfg_t const enet_pads[] = { - MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL), - MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -static iomux_v3_cfg_t const ecspi1_pads[] = { - MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL), - MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL), - MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL), - MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -#ifdef CONFIG_CMD_NAND -/* NAND */ -static iomux_v3_cfg_t const nfc_pads[] = { - MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL), - MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NAND_PAD_CTRL), -}; -#endif - -static struct i2c_pads_info i2c_pad_info2 = { - .scl = { - .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD, - .gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD, - .gp = IMX_GPIO_NR(1, 5) - }, - .sda = { - .i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | I2C_PAD, - .gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | I2C_PAD, - .gp = IMX_GPIO_NR(1, 6) - } -}; - -static struct fsl_esdhc_cfg usdhc_cfg[] = { - {.esdhc_base = USDHC1_BASE_ADDR, - .max_bus_width = 4}, -#ifndef CONFIG_CMD_NAND - {USDHC4_BASE_ADDR}, -#endif -}; - -static iomux_v3_cfg_t const usdhc1_pads[] = { - MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */ -}; - -#if !defined(CONFIG_CMD_NAND) && !defined(CONFIG_SPL_BUILD) -static iomux_v3_cfg_t const usdhc4_pads[] = { - MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), -}; -#endif - int board_mmc_get_env_dev(int devno) { return devno - 1; } -int board_mmc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; - int ret = 0; - - switch (cfg->esdhc_base) { - case USDHC1_BASE_ADDR: - ret = !gpio_get_value(USDHC1_CD_GPIO); - break; - case USDHC4_BASE_ADDR: - ret = 1; /* eMMC/uSDHC4 is always present */ - break; - } - - return ret; -} - -int board_mmc_init(bd_t *bis) -{ -#ifndef CONFIG_SPL_BUILD - int ret; - int i; - - for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { - switch (i) { - case 0: - imx_iomux_v3_setup_multiple_pads( - usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); - gpio_direction_input(USDHC1_CD_GPIO); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); - break; -#ifndef CONFIG_CMD_NAND - case 1: - imx_iomux_v3_setup_multiple_pads( - usdhc4_pads, ARRAY_SIZE(usdhc4_pads)); - usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); - break; -#endif - default: - printf("Warning: you configured more USDHC controllers" - "(%d) then supported by the board (%d)\n", - i + 1, CONFIG_SYS_FSL_USDHC_NUM); - return -EINVAL; - } - - ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); - if (ret) - return ret; - } - - return 0; -#else - struct src *psrc = (struct src *)SRC_BASE_ADDR; - unsigned reg = readl(&psrc->sbmr1) >> 11; - /* - * Upon reading BOOT_CFG register the following map is done: - * Bit 11 and 12 of BOOT_CFG register can determine the current - * mmc port - * 0x1 SD1 - * 0x2 SD2 - * 0x3 SD4 - */ - - switch (reg & 0x3) { - case 0x0: - imx_iomux_v3_setup_multiple_pads( - usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); - gpio_direction_input(USDHC1_CD_GPIO); - usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR; - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); - usdhc_cfg[0].max_bus_width = 4; - gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk; - break; - } - return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); -#endif -} - -static void setup_iomux_uart(void) -{ - imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads)); -} - -static void setup_iomux_enet(void) -{ - imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads)); - - gpio_direction_output(ENET_PHY_RESET_GPIO, 0); - mdelay(10); - gpio_set_value(ENET_PHY_RESET_GPIO, 1); - mdelay(30); -} - -static void setup_spi(void) -{ - gpio_request(IMX_GPIO_NR(3, 19), "spi_cs0"); - gpio_direction_output(IMX_GPIO_NR(3, 19), 1); - - imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads)); - - enable_spi_clk(true, 0); -} - #ifdef CONFIG_CMD_NAND static void setup_gpmi_nand(void) { struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - /* config gpmi nand iomux */ - imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads)); - /* gate ENFC_CLK_ROOT clock first,before clk source switch */ clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); @@ -325,48 +66,17 @@ static void setup_gpmi_nand(void) } #endif -int board_spi_cs_gpio(unsigned bus, unsigned cs) -{ - if (bus != 0 || (cs != 0)) - return -EINVAL; - - return IMX_GPIO_NR(3, 19); -} - -int board_eth_init(bd_t *bis) -{ - setup_iomux_enet(); - - return cpu_eth_init(bis); -} - -int board_early_init_f(void) -{ - setup_iomux_uart(); - - return 0; -} - int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; -#ifdef CONFIG_SYS_I2C_MXC - setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); -#endif - -#ifdef CONFIG_MXC_SPI - setup_spi(); -#endif - #ifdef CONFIG_CMD_NAND setup_gpmi_nand(); #endif return 0; } - #ifdef CONFIG_CMD_BMODE /* * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4 @@ -535,11 +245,6 @@ void board_boot_order(u32 *spl_boot_list) void board_init_f(ulong dummy) { -#ifdef CONFIG_CMD_NAND - /* Enable NAND */ - setup_gpmi_nand(); -#endif - /* setup clock gating */ ccgr_init(); @@ -549,23 +254,33 @@ void board_init_f(ulong dummy) /* setup AXI */ gpr_init(); - board_early_init_f(); - /* setup GP timer */ timer_init(); - setup_spi(); - - /* UART clocks enabled and gd valid - init serial console */ - preloader_console_init(); - /* DDR initialization */ spl_dram_init(); /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - /* load/boot image from boot device */ - board_init_r(NULL, 0); + /* Enable device tree and early DM support*/ + spl_early_init(); + + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); +} + +/* + * Manually probe the SPI bus devices, as this does not happen when the + * SPI Flash is probed, which then fails to find the bus. + */ +void spl_board_init(void) +{ + struct udevice *udev; + int ret = uclass_get_device_by_name(UCLASS_SPI, "spi@2008000", &udev); + + if (ret) { + printf("SPI bus probe failed, err = %d\n", ret); + }; } #endif diff --git a/configs/pcm058_defconfig b/configs/pcm058_defconfig index 64947e8355d..c491cbf9a0c 100644 --- a/configs/pcm058_defconfig +++ b/configs/pcm058_defconfig @@ -7,9 +7,12 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_OFFSET=0x100000 CONFIG_ENV_SECT_SIZE=0x10000 -CONFIG_SYS_SPI_U_BOOT_OFFS=0x10000 +CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 +CONFIG_MX6_OCRAM_256KB=y CONFIG_TARGET_PCM058=y CONFIG_SPL_TEXT_BASE=0x00908000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 @@ -26,10 +29,11 @@ CONFIG_BOOTDELAY=3 # CONFIG_USE_BOOTCOMMAND is not set CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_BOUNCE_BUFFER=y -CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x18a CONFIG_SPL_DMA=y CONFIG_SPL_FS_EXT4=y -CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_SPL_YMODEM_SUPPORT=y @@ -38,33 +42,51 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_NAND_TRIMFFS=y -CONFIG_CMD_SF=y +# CONFIG_CMD_PINMUX is not set CONFIG_CMD_CACHE=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_MTDPARTS=y -CONFIG_MTDIDS_DEFAULT="nand0=nand" -CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:16m(uboot),1m(env),-(rootfs)" +CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand" +CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:-(rootfs)" CONFIG_CMD_UBI=y # CONFIG_SPL_PARTITION_UUIDS is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx6q-phytec-mira-rdk-nand" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y -CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MXC=y +CONFIG_DM_MMC=y CONFIG_FSL_USDHC=y CONFIG_MTD=y CONFIG_DM_MTD=y CONFIG_MTD_RAW_NAND=y CONFIG_SYS_NAND_USE_FLASH_BBT=y CONFIG_NAND_MXS=y -CONFIG_SPI_FLASH=y +CONFIG_NAND_MXS_DT=y +CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y +CONFIG_FEC_MXC=y CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +# CONFIG_PINCONF_RECURSIVE is not set +CONFIG_SPL_PINCTRL=y +CONFIG_SPL_PINCONF=y +# CONFIG_SPL_PINCONF_RECURSIVE is not set +CONFIG_PINCTRL_IMX6=y +CONFIG_DM_SERIAL=y +CONFIG_MXC_UART=y CONFIG_SPI=y +CONFIG_DM_SPI=y CONFIG_MXC_SPI=y -CONFIG_DM_THERMAL=y -CONFIG_OF_LIBFDT=y +# CONFIG_SPL_WDT is not set diff --git a/include/configs/pcm058.h b/include/configs/pcm058.h index 7c27ebb811d..4f03699117b 100644 --- a/include/configs/pcm058.h +++ b/include/configs/pcm058.h @@ -3,7 +3,6 @@ * Copyright (C) Stefano Babic */ - #ifndef __PCM058_CONFIG_H #define __PCM058_CONFIG_H @@ -13,48 +12,13 @@ #include "mx6_common.h" -/* Thermal */ -#define CONFIG_IMX_THERMAL - -/* Serial */ -#define CONFIG_MXC_UART -#define CONFIG_MXC_UART_BASE UART2_BASE -#define CONSOLE_DEV "ttymxc1" - #define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024) -/* Early setup */ - - /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (8 * SZ_1M) -/* Ethernet */ -#define CONFIG_FEC_MXC -#define IMX_FEC_BASE ENET_BASE_ADDR -#define CONFIG_FEC_XCV_TYPE RGMII -#define CONFIG_ETHPRIME "FEC" -#define CONFIG_FEC_MXC_PHYADDR 3 - -/* SPI Flash */ - -/* I2C Configs */ -#define CONFIG_SYS_I2C -#define CONFIG_SYS_I2C_MXC -#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 2 */ -#define CONFIG_SYS_I2C_SPEED 100000 - -#ifndef CONFIG_SPL_BUILD /* Enable NAND support */ #define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define CONFIG_SYS_NAND_BASE 0x40000000 -#define CONFIG_SYS_NAND_5_ADDR_CYCLE -#define CONFIG_SYS_NAND_ONFI_DETECTION -#endif - -/* DMA stuff, needed for GPMI/MXS NAND support */ - -/* Filesystem support */ /* Physical Memory Map */ #define PHYS_SDRAM MMDC0_ARB_BASE_ADDR @@ -68,10 +32,33 @@ #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) -/* MMC Configs */ -#define CONFIG_SYS_FSL_ESDHC_ADDR 0 -#define CONFIG_SYS_FSL_USDHC_NUM 1 - /* Environment organization */ +#define ENV_MMC \ + "mmcdev=0\0" \ + "mmcpart=2\0" \ + "fitpart=1\0" \ + "mmcrootfstype=ext4\0" \ + "fitname=fitImage\0" \ + "mmcloadfit=load mmc ${mmcdev}:${fitpart} ${loadaddr} ${fitname}\0" \ + "mmcargs=setenv bootargs root=/dev/mmcblk${mmcdev}p${mmcpart} " \ + "rootfstype=${mmcrootfstype} ${optargs}\0" \ + "mmcboot=run mmcloadfit;run mmcargs;bootm ${loadaddr}\0" +#define ENV_NAND \ + "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \ + "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ + "nandroot=ubi0:root ubi.mtd=rootfs\0" \ + "nandrootfstype=ubifs\0" \ + "nandargs=setenv bootargs root=${nandroot} " \ + "rootfstype=${nandrootfstype} ${mtdparts} ${optargs}\0" \ + "nandloadfit=ubi part rootfs;ubi readvol ${loadaddr} fit\0" \ + "nandboot=run nandloadfit;run nandargs;bootm ${loadaddr}\0" + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootm_size=0x30000000\0" \ + "optargs=rw rootwait\0" \ + ENV_MMC \ + ENV_NAND + +#define CONFIG_BOOTCOMMAND "run mmcboot;run nandboot" #endif From 93d6c8f7b79786878f186b7e30676a52bba52860 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 9 Jun 2020 00:59:05 -0700 Subject: [PATCH 39/51] spi: fsl_qspi: Add support for i.MX7ULP Add compatible string and driver data for i.MX7ULP. Meanwhile, the address set to SFA1AD/SFA2AD/SFB1AD/SFB2AD should align with 1KB, because the lowest 10 bits are reserved by the registers definition. For i.MX7ULP which has only 128Bytes AHB buffer, must align it when setting the registers and selecting cs. Signed-off-by: Ye Li Reviewed-by: Ashish Kumar Reviewed-by: Kuldeep Singh --- drivers/spi/fsl_qspi.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index e715f9838f1..d9f531a2a54 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -231,6 +231,15 @@ static const struct fsl_qspi_devtype_data imx6ul_data = { .little_endian = true, }; +static const struct fsl_qspi_devtype_data imx7ulp_data = { + .rxfifo = SZ_64, + .txfifo = SZ_64, + .ahb_buf_size = SZ_128, + .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | + QUADSPI_QUIRK_USE_TDH_SETTING, + .little_endian = true, +}; + static const struct fsl_qspi_devtype_data ls1021a_data = { .rxfifo = SZ_128, .txfifo = SZ_64, @@ -485,7 +494,7 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_slave *slave) static void fsl_qspi_read_ahb(struct fsl_qspi *q, const struct spi_mem_op *op) { memcpy_fromio(op->data.buf.in, - q->ahb_addr + q->selected * q->devtype_data->ahb_buf_size, + q->ahb_addr + q->selected * ALIGN(q->devtype_data->ahb_buf_size, 0x400), op->data.nbytes); } @@ -589,7 +598,7 @@ static int fsl_qspi_exec_op(struct spi_slave *slave, addr_offset = q->memmap_phy; qspi_writel(q, - q->selected * q->devtype_data->ahb_buf_size + addr_offset, + q->selected * ALIGN(q->devtype_data->ahb_buf_size, 0x400) + addr_offset, base + QUADSPI_SFAR); qspi_writel(q, qspi_readl(q, base + QUADSPI_MCR) | @@ -695,13 +704,13 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) * We use ahb_buf_size for each chip and set SFA1AD, SFA2AD, SFB1AD, * SFB2AD accordingly. */ - qspi_writel(q, q->devtype_data->ahb_buf_size + addr_offset, + qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) + addr_offset, base + QUADSPI_SFA1AD); - qspi_writel(q, q->devtype_data->ahb_buf_size * 2 + addr_offset, + qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 2 + addr_offset, base + QUADSPI_SFA2AD); - qspi_writel(q, q->devtype_data->ahb_buf_size * 3 + addr_offset, + qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 3 + addr_offset, base + QUADSPI_SFB1AD); - qspi_writel(q, q->devtype_data->ahb_buf_size * 4 + addr_offset, + qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 4 + addr_offset, base + QUADSPI_SFB2AD); q->selected = -1; @@ -799,6 +808,7 @@ static const struct udevice_id fsl_qspi_ids[] = { { .compatible = "fsl,imx6sx-qspi", .data = (ulong)&imx6sx_data, }, { .compatible = "fsl,imx6ul-qspi", .data = (ulong)&imx6ul_data, }, { .compatible = "fsl,imx7d-qspi", .data = (ulong)&imx7d_data, }, + { .compatible = "fsl,imx7ulp-qspi", .data = (ulong)&imx7ulp_data, }, { .compatible = "fsl,ls1021a-qspi", .data = (ulong)&ls1021a_data, }, { .compatible = "fsl,ls1088a-qspi", .data = (ulong)&ls1088a_data, }, { .compatible = "fsl,ls2080a-qspi", .data = (ulong)&ls2080a_data, }, From def88bce094e95939abf1e5d02a9b413b3627f6f Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 9 Jun 2020 00:59:06 -0700 Subject: [PATCH 40/51] spi: fsl_qspi: Support to use full AHB space on i.MX i.MX platforms provide large AHB mapped space for QSPI, each controller has 256MB. However, current driver only maps small size (AHB buffer size) of AHB space, this implementation causes i.MX failed to boot M4 with QSPI XIP image. Add config CONFIG_FSL_QSPI_AHB_FULL_MAP (default enabled for i.MX) to address above problem. When the config is set: 1. Full AHB space is divided to each CS. 2. A dedicated LUT entry is used for AHB read only. 3. The MODE instruction in LUT is replaced to standard ADDR instruction 4. The address in spi_mem_op is used to SFAR and AHB read Signed-off-by: Ye Li Reviewed-by: Ashish Kumar Reviewed-by: Kuldeep Singh --- drivers/spi/Kconfig | 8 +++ drivers/spi/fsl_qspi.c | 112 ++++++++++++++++++++++++++++++++--------- 2 files changed, 97 insertions(+), 23 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 3a8add98f76..30d808d7bb2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -155,6 +155,14 @@ config FSL_QSPI used to access the SPI NOR flash on platforms embedding this Freescale IP core. +config FSL_QSPI_AHB_FULL_MAP + bool "Use full AHB memory map space" + depends on FSL_QSPI + default y if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_IMX8M + help + Enable the Freescale QSPI driver to use full AHB memory map space for + flash access. + config ICH_SPI bool "Intel ICH SPI driver" help diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index d9f531a2a54..eec968e5ec1 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -46,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR; * read operation, so let's use the last entry (15). */ #define SEQID_LUT 15 +#define SEQID_LUT_AHB 14 /* Registers used by the driver */ #define QUADSPI_MCR 0x00 @@ -122,6 +123,10 @@ DECLARE_GLOBAL_DATA_PTR; #define QUADSPI_LUT_REG(idx) \ (QUADSPI_LUT_BASE + QUADSPI_LUT_OFFSET + (idx) * 4) +#define QUADSPI_AHB_LUT_OFFSET (SEQID_LUT_AHB * 4 * 4) +#define QUADSPI_AHB_LUT_REG(idx) \ + (QUADSPI_LUT_BASE + QUADSPI_AHB_LUT_OFFSET + (idx) * 4) + /* Instruction set for the LUT register */ #define LUT_STOP 0 #define LUT_CMD 1 @@ -189,6 +194,11 @@ DECLARE_GLOBAL_DATA_PTR; */ #define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5) +/* + * Controller only has Two CS on flash A, no flash B port + */ +#define QUADSPI_QUIRK_SINGLE_BUS BIT(6) + struct fsl_qspi_devtype_data { unsigned int rxfifo; unsigned int txfifo; @@ -236,7 +246,7 @@ static const struct fsl_qspi_devtype_data imx7ulp_data = { .txfifo = SZ_64, .ahb_buf_size = SZ_128, .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | - QUADSPI_QUIRK_USE_TDH_SETTING, + QUADSPI_QUIRK_USE_TDH_SETTING | QUADSPI_QUIRK_SINGLE_BUS, .little_endian = true, }; @@ -269,6 +279,7 @@ struct fsl_qspi { void __iomem *iobase; void __iomem *ahb_addr; u32 memmap_phy; + u32 memmap_size; const struct fsl_qspi_devtype_data *devtype_data; int selected; }; @@ -303,6 +314,11 @@ static inline int needs_tdh_setting(struct fsl_qspi *q) return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING; } +static inline int needs_single_bus(struct fsl_qspi *q) +{ + return q->devtype_data->quirks & QUADSPI_QUIRK_SINGLE_BUS; +} + /* * An IC bug makes it necessary to rearrange the 32-bit data. * Later chips, such as IMX6SLX, have fixed this bug. @@ -405,18 +421,27 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q, lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth), op->cmd.opcode); - /* - * For some unknown reason, using LUT_ADDR doesn't work in some - * cases (at least with only one byte long addresses), so - * let's use LUT_MODE to write the address bytes one by one - */ - for (i = 0; i < op->addr.nbytes; i++) { - u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->addr.nbytes) { + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR, + LUT_PAD(op->addr.buswidth), + (op->addr.nbytes == 4) ? 0x20 : 0x18); + lutidx++; + } + } else { + /* + * For some unknown reason, using LUT_ADDR doesn't work in some + * cases (at least with only one byte long addresses), so + * let's use LUT_MODE to write the address bytes one by one + */ + for (i = 0; i < op->addr.nbytes; i++) { + u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); - lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE, - LUT_PAD(op->addr.buswidth), - addrbyte); - lutidx++; + lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE, + LUT_PAD(op->addr.buswidth), + addrbyte); + lutidx++; + } } if (op->dummy.nbytes) { @@ -449,6 +474,14 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q, for (i = 0; i < ARRAY_SIZE(lutval); i++) qspi_writel(q, lutval[i], base + QUADSPI_LUT_REG(i)); + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN && + op->addr.nbytes) { + for (i = 0; i < ARRAY_SIZE(lutval); i++) + qspi_writel(q, lutval[i], base + QUADSPI_AHB_LUT_REG(i)); + } + } + /* lock LUT */ qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); @@ -491,10 +524,29 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_slave *slave) fsl_qspi_invalidate(q); } +static u32 fsl_qspi_memsize_per_cs(struct fsl_qspi *q) +{ + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (needs_single_bus(q)) + return q->memmap_size / 2; + else + return q->memmap_size / 4; + } else { + return ALIGN(q->devtype_data->ahb_buf_size, 0x400); + } +} + static void fsl_qspi_read_ahb(struct fsl_qspi *q, const struct spi_mem_op *op) { + void __iomem *ahb_read_addr = q->ahb_addr; + + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->addr.nbytes) + ahb_read_addr += op->addr.val; + } + memcpy_fromio(op->data.buf.in, - q->ahb_addr + q->selected * ALIGN(q->devtype_data->ahb_buf_size, 0x400), + ahb_read_addr + q->selected * fsl_qspi_memsize_per_cs(q), op->data.nbytes); } @@ -597,8 +649,13 @@ static int fsl_qspi_exec_op(struct spi_slave *slave, if (needs_amba_base_offset(q)) addr_offset = q->memmap_phy; + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) { + if (op->addr.nbytes) + addr_offset += op->addr.val; + } + qspi_writel(q, - q->selected * ALIGN(q->devtype_data->ahb_buf_size, 0x400) + addr_offset, + q->selected * fsl_qspi_memsize_per_cs(q) + addr_offset, base + QUADSPI_SFAR); qspi_writel(q, qspi_readl(q, base + QUADSPI_MCR) | @@ -655,7 +712,7 @@ static int fsl_qspi_adjust_op_size(struct spi_slave *slave, static int fsl_qspi_default_setup(struct fsl_qspi *q) { void __iomem *base = q->iobase; - u32 reg, addr_offset = 0; + u32 reg, addr_offset = 0, memsize_cs; /* Reset the module */ qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK, @@ -687,8 +744,13 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) qspi_writel(q, 0, base + QUADSPI_BUF1IND); qspi_writel(q, 0, base + QUADSPI_BUF2IND); - qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT), - q->iobase + QUADSPI_BFGENCR); + if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) + qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT_AHB), + q->iobase + QUADSPI_BFGENCR); + else + qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT), + q->iobase + QUADSPI_BFGENCR); + qspi_writel(q, QUADSPI_RBCT_WMRK_MASK, base + QUADSPI_RBCT); qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | QUADSPI_BUF3CR_ADATSZ(q->devtype_data->ahb_buf_size / 8), @@ -704,14 +766,17 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) * We use ahb_buf_size for each chip and set SFA1AD, SFA2AD, SFB1AD, * SFB2AD accordingly. */ - qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) + addr_offset, + memsize_cs = fsl_qspi_memsize_per_cs(q); + qspi_writel(q, memsize_cs + addr_offset, base + QUADSPI_SFA1AD); - qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 2 + addr_offset, + qspi_writel(q, memsize_cs * 2 + addr_offset, base + QUADSPI_SFA2AD); - qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 3 + addr_offset, - base + QUADSPI_SFB1AD); - qspi_writel(q, ALIGN(q->devtype_data->ahb_buf_size, 0x400) * 4 + addr_offset, - base + QUADSPI_SFB2AD); + if (!needs_single_bus(q)) { + qspi_writel(q, memsize_cs * 3 + addr_offset, + base + QUADSPI_SFB1AD); + qspi_writel(q, memsize_cs * 4 + addr_offset, + base + QUADSPI_SFB2AD); + } q->selected = -1; @@ -759,6 +824,7 @@ static int fsl_qspi_probe(struct udevice *bus) q->ahb_addr = map_physmem(res.start, res.end - res.start, MAP_NOCACHE); q->memmap_phy = res.start; + q->memmap_size = res.end - res.start; dm_bus->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 66000000); From dfbdaa66b7fbc60efb48e228733f7e98b3e6fed5 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 9 Jun 2020 03:34:42 -0700 Subject: [PATCH 41/51] misc: scu_api: Add SCFW API to get the index of boot container set Add SCFW API sc_misc_get_boot_container to get current boot container set index. The index value returns 1 for primary container set, 2 for secondary container set. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sci/rpc.h | 1 + arch/arm/include/asm/arch-imx8/sci/sci.h | 1 + drivers/misc/imx8/scu_api.c | 25 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/sci/rpc.h b/arch/arm/include/asm/arch-imx8/sci/rpc.h index c1a9c353ba0..9f55904f442 100644 --- a/arch/arm/include/asm/arch-imx8/sci/rpc.h +++ b/arch/arm/include/asm/arch-imx8/sci/rpc.h @@ -115,6 +115,7 @@ struct sc_rpc_msg_s { #define MISC_FUNC_GET_TEMP 13U #define MISC_FUNC_GET_BOOT_DEV 16U #define MISC_FUNC_GET_BUTTON_STATUS 18U +#define MISC_FUNC_GET_BOOT_CONTAINER 36U /* PAD RPC */ #define PAD_FUNC_UNKNOWN 0 diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h index f91f7cc5876..1c29209b399 100644 --- a/arch/arm/include/asm/arch-imx8/sci/sci.h +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h @@ -82,6 +82,7 @@ int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl, u32 *val); void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev); void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status); +int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx); void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit); int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val); int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp, diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index 3e38edbf5dc..20b74fbb18d 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -374,6 +374,31 @@ void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status) __func__, status, RPC_R8(&msg)); } +int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx) +{ + struct udevice *dev = gd->arch.scu_dev; + int size = sizeof(struct sc_rpc_msg_s); + struct sc_rpc_msg_s msg; + int ret; + + if (!dev) + hang(); + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 1U; + RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC; + RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_CONTAINER; + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret < 0) + return ret; + + if (idx) + *idx = (u8)RPC_U8(&msg, 0U); + + return 0; +} + void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit) { struct udevice *dev = gd->arch.scu_dev; From 6103e570cdd0d0e854b071ee17b14589356a82bd Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 9 Jun 2020 20:29:51 -0700 Subject: [PATCH 42/51] gpio: mxc_gpio: Improve to use ofdata_to_platdata Current mxc_gpio DM driver allocates the platdata in bind function to handle both OF_CONTROL enabled case and disabled case. This implementation puts the devfdt_get_addr in bind, which introduces much overhead especially in board_f phase. Change the driver to a common way for handling the cases by using ofdata_to_platdata and using DM framework to allocate platdata. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- drivers/gpio/mxc_gpio.c | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 316dcc757b2..90d36fb87bb 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -295,46 +295,26 @@ static int mxc_gpio_probe(struct udevice *dev) return 0; } -static int mxc_gpio_bind(struct udevice *dev) +static int mxc_gpio_ofdata_to_platdata(struct udevice *dev) { - struct mxc_gpio_plat *plat = dev->platdata; fdt_addr_t addr; - - /* - * If platdata already exsits, directly return. - * Actually only when DT is not supported, platdata - * is statically initialized in U_BOOT_DEVICES.Here - * will return. - */ - if (plat) - return 0; + struct mxc_gpio_plat *plat = dev_get_platdata(dev); addr = devfdt_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; - /* - * TODO: - * When every board is converted to driver model and DT is supported, - * this can be done by auto-alloc feature, but not using calloc - * to alloc memory for platdata. - * - * For example mxc_plat below uses platform data rather than device - * tree. - * - * NOTE: DO NOT COPY this code if you are using device tree. - */ - plat = calloc(1, sizeof(*plat)); - if (!plat) - return -ENOMEM; - plat->regs = (struct gpio_regs *)addr; plat->bank_index = dev->req_seq; - dev->platdata = plat; return 0; } +static int mxc_gpio_bind(struct udevice *dev) +{ + return 0; +} + static const struct udevice_id mxc_gpio_ids[] = { { .compatible = "fsl,imx35-gpio" }, { } @@ -345,6 +325,8 @@ U_BOOT_DRIVER(gpio_mxc) = { .id = UCLASS_GPIO, .ops = &gpio_mxc_ops, .probe = mxc_gpio_probe, + .ofdata_to_platdata = mxc_gpio_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct mxc_gpio_plat), .priv_auto_alloc_size = sizeof(struct mxc_bank_info), .of_match = mxc_gpio_ids, .bind = mxc_gpio_bind, From 496cb1f274059471422e4f6a815d3599924334be Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 21 Jun 2020 21:32:26 -0300 Subject: [PATCH 43/51] pico-imx6ul: Fix Quick Start Guide URL The current URL for the pico imx6ul board is not valid anymore. Change to a different URL that works. Signed-off-by: Fabio Estevam --- board/technexion/pico-imx6ul/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/technexion/pico-imx6ul/README b/board/technexion/pico-imx6ul/README index 40d43441429..e58640c55ec 100644 --- a/board/technexion/pico-imx6ul/README +++ b/board/technexion/pico-imx6ul/README @@ -22,8 +22,8 @@ If the eMMC has already a U-Boot flashed with DFU support then the user can go to step 2 below in order to update U-Boot. Put pico board in USB download mode (refer to the document -http://www.wandboard.org/images/hobbit/hobbitboard-imx6ul-reva1.pdf -page 15). +https://www.nxp.com/files-static/32bit/doc/quick_start_guide/PICO-IMX6UL-QSG.pdf +Figure 6a at page 7). Connect a USB to serial adapter between the host PC and pico. From 90865614b4e6243a100cde69ef08e9b55e4fa5fc Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 26 Jun 2020 19:57:55 +0200 Subject: [PATCH 44/51] ARM: mx6: make CAAM usable on the i.MX6 boards Even if the HAB fuse is not set we want to be able to use the Cryptographic Accelerator and Assurance Module (CAAM) for generating random numbers. So SYS_FSL_HAS_SEC should be selected even if IMX_HAB is not set. arch_misc_init() has to be called to initialize the CAAM. Signed-off-by: Heinrich Schuchardt --- arch/arm/Kconfig | 2 +- arch/arm/mach-imx/mx6/soc.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 86238524f75..e16fe038872 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -888,7 +888,7 @@ config ARCH_MX7 config ARCH_MX6 bool "Freescale MX6" select CPU_V7A - select SYS_FSL_HAS_SEC if IMX_HAB + select SYS_FSL_HAS_SEC select SYS_FSL_SEC_COMPAT_4 select SYS_FSL_SEC_LE imply MXC_GPIO diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index 19ca3826495..e1292860656 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -691,6 +692,15 @@ void imx_setup_hdmi(void) } #endif +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif + return 0; +} +#endif /* * gpr_init() function is common for boards using MX6S, MX6DL, MX6D, From eefd93e7f88ec919cc335dbf934320fec949bce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Szymanski?= Date: Tue, 30 Jun 2020 15:03:13 +0200 Subject: [PATCH 45/51] power: pmic_pca9450: fix PCA9450A I2C address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quoting Ye Li from NXP: "We have confirmed with PMIC team, 0x35 is used only on early chips and not used any more. 0x25 is the final address." Fix it by merging power_pca9450a_init and power_pca9450b_init into one function power_pca9450_init. Signed-off-by: Sébastien Szymanski Reviewed-by: Fabio Estevam Reviewed-by: Ye Li --- board/freescale/imx8mp_evk/spl.c | 2 +- drivers/power/pmic/pmic_pca9450.c | 21 +-------------------- include/power/pca9450.h | 3 +-- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/board/freescale/imx8mp_evk/spl.c b/board/freescale/imx8mp_evk/spl.c index 3b3a854e29b..3214718e62b 100644 --- a/board/freescale/imx8mp_evk/spl.c +++ b/board/freescale/imx8mp_evk/spl.c @@ -68,7 +68,7 @@ int power_init_board(void) struct pmic *p; int ret; - ret = power_pca9450b_init(I2C_PMIC); + ret = power_pca9450_init(I2C_PMIC); if (ret) printf("power init failed"); p = pmic_get("PCA9450"); diff --git a/drivers/power/pmic/pmic_pca9450.c b/drivers/power/pmic/pmic_pca9450.c index 67a90902006..d4f27428bd1 100644 --- a/drivers/power/pmic/pmic_pca9450.c +++ b/drivers/power/pmic/pmic_pca9450.c @@ -11,26 +11,7 @@ static const char pca9450_name[] = "PCA9450"; -int power_pca9450a_init(unsigned char bus) -{ - struct pmic *p = pmic_alloc(); - - if (!p) { - printf("%s: POWER allocation error!\n", __func__); - return -ENOMEM; - } - - p->name = pca9450_name; - p->interface = PMIC_I2C; - p->number_of_regs = PCA9450_REG_NUM; - p->hw.i2c.addr = 0x35; - p->hw.i2c.tx_num = 1; - p->bus = bus; - - return 0; -} - -int power_pca9450b_init(unsigned char bus) +int power_pca9450_init(unsigned char bus) { struct pmic *p = pmic_alloc(); diff --git a/include/power/pca9450.h b/include/power/pca9450.h index 5d4f58ca44e..5a9a697d626 100644 --- a/include/power/pca9450.h +++ b/include/power/pca9450.h @@ -54,7 +54,6 @@ enum { PCA9450_REG_NUM, }; -int power_pca9450a_init(unsigned char bus); -int power_pca9450b_init(unsigned char bus); +int power_pca9450_init(unsigned char bus); #endif From ee6866e6c773341ad4058d46ff898ad258db1292 Mon Sep 17 00:00:00 2001 From: "Mo, Yuezhang" Date: Wed, 1 Jul 2020 09:15:28 +0000 Subject: [PATCH 46/51] watchdog: imx: Support set timeout by wdt command After "4b969deac0 watchdog: imx: Add DM support", the imx watchdog can be started by wdt command. But the imx watchdog driver only support start with the default timeout. This commit adds the support for setting the timeout which pass from the wdt command into the imx watchdog. If the timeout out of the valid range(0.5~128s), start the watchdog with a timeout within the valid range and the timeout is the one which closest to the passed timeout. Signed-off-by: Yuezhang.Mo Reviewed-by: Andy.Wu Reviewed-by: stefano Babic --- drivers/watchdog/imx_watchdog.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c index 01762df019b..b90c2daecee 100644 --- a/drivers/watchdog/imx_watchdog.c +++ b/drivers/watchdog/imx_watchdog.c @@ -16,6 +16,10 @@ #include #endif #include +#include + +#define TIMEOUT_MAX 128000 +#define TIMEOUT_MIN 500 static void imx_watchdog_expire_now(struct watchdog_regs *wdog, bool ext_reset) { @@ -57,9 +61,9 @@ static void imx_watchdog_reset(struct watchdog_regs *wdog) #endif /* CONFIG_WATCHDOG_RESET_DISABLE*/ } -static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset) +static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset, + u64 timeout) { - u16 timeout; u16 wcr; /* @@ -70,7 +74,11 @@ static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset) #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000 #endif - timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1; + + timeout = max_t(u64, timeout, TIMEOUT_MIN); + timeout = min_t(u64, timeout, TIMEOUT_MAX); + timeout = lldiv(timeout, 500) - 1; + #ifdef CONFIG_FSL_LSCH2 wcr = (WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout; #else @@ -95,7 +103,7 @@ void hw_watchdog_init(void) { struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; - imx_watchdog_init(wdog, true); + imx_watchdog_init(wdog, true, CONFIG_WATCHDOG_TIMEOUT_MSECS); } #else struct imx_wdt_priv { @@ -126,7 +134,7 @@ static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags) { struct imx_wdt_priv *priv = dev_get_priv(dev); - imx_watchdog_init(priv->base, priv->ext_reset); + imx_watchdog_init(priv->base, priv->ext_reset, timeout); return 0; } From 08556f829f48225388c2bb6d7b9d02ab60cc9e56 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Wed, 8 Jul 2020 07:39:59 +0200 Subject: [PATCH 47/51] imx6: aristainetos: sync defconfig with 2020.10 as patch gpio: search for gpio label if gpio is not found through bank name is now in mainline, but functionality is disabled, we need to enable CONFIG_DM_GPIO_LOOKUP_LABEL for the aristainetos boards. Signed-off-by: Heiko Schocher --- configs/aristainetos2_defconfig | 3 ++- configs/aristainetos2b_defconfig | 3 ++- configs/aristainetos2bcsl_defconfig | 3 ++- configs/aristainetos2c_defconfig | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/configs/aristainetos2_defconfig b/configs/aristainetos2_defconfig index 01990bd9704..7e902127e1a 100644 --- a/configs/aristainetos2_defconfig +++ b/configs/aristainetos2_defconfig @@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set # CONFIG_CMD_NANDBCB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -53,7 +54,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2_4" CONFIG_OF_LIST="imx6dl-aristainetos2_4 imx6dl-aristainetos2_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -61,6 +61,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/aristainetos2b_defconfig b/configs/aristainetos2b_defconfig index 318b81e331c..3c605c2121b 100644 --- a/configs/aristainetos2b_defconfig +++ b/configs/aristainetos2b_defconfig @@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_4" CONFIG_OF_LIST="imx6dl-aristainetos2b_4 imx6dl-aristainetos2b_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -59,6 +59,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/aristainetos2bcsl_defconfig b/configs/aristainetos2bcsl_defconfig index 0ff67a44cbe..6cd095fb852 100644 --- a/configs/aristainetos2bcsl_defconfig +++ b/configs/aristainetos2bcsl_defconfig @@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_csl_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_csl_4" CONFIG_OF_LIST="imx6dl-aristainetos2b_csl_4 imx6dl-aristainetos2b_csl_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -59,6 +59,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y diff --git a/configs/aristainetos2c_defconfig b/configs/aristainetos2c_defconfig index ffd4360159f..4f6b9b94019 100644 --- a/configs/aristainetos2c_defconfig +++ b/configs/aristainetos2c_defconfig @@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_OFFSET_REDUND=0xE0000 CONFIG_IMX_HAB=y # CONFIG_CMD_DEKBLOB is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2c_4" CONFIG_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg" CONFIG_BOOTDELAY=3 @@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_CMD_MTDPARTS=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2c_4" CONFIG_OF_LIST="imx6dl-aristainetos2c_4 imx6dl-aristainetos2c_7" CONFIG_DTB_RESELECT=y CONFIG_MULTI_DTB_FIT=y @@ -62,6 +62,7 @@ CONFIG_APBH_DMA=y CONFIG_APBH_DMA_BURST=y CONFIG_APBH_DMA_BURST8=y CONFIG_GPIO_HOG=y +CONFIG_DM_GPIO_LOOKUP_LABEL=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y From 949feef062f21d19ecc76b48fdeb8f3099e16df6 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Fri, 10 Jul 2020 09:49:32 +0200 Subject: [PATCH 48/51] arm: Add extra boot device (UART) to run Ymodem u-boot.img boot on XEA (imx28) This commit enables imx28 based XEA board's u-boot.sb (SPL) to download u-boot proper (u-boot.img) via Ymodem protocol. This is extremely useful in the recovery scenario where u-boot.sb is downloaded via uuu utility to SDRAM [*], and then one can upload u-boot proper via serial console to fully debrick the device. Note - debricking procedure of imx28 devices: - NXP's original USB based tools (like mxsldr or uuu) expect single u-boot.sb which is a relic of the old U-Boot (~2013) without SPL and U-Boot proper distinction. [*] On Host: ------------ cat << EOF > imx28_xea.lst uuu_version 1.3.0 SDPS: boot -f /srv/tftp/xea/u-boot.sb SDPU: done EOF Please start picocom: sudo picocom -b 115200 -s "sz -vv" /dev/ttyUSB1 sudo ./uuu/uuu -V imx28_xea.lst On the U-boot console one shall see: Trying to boot from UART CCC Then please press CTRL+A, S and type u-boot.img Signed-off-by: Lukasz Majewski Acked-by: Peng Fan --- board/liebherr/xea/xea.c | 1 + configs/imx28_xea_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/board/liebherr/xea/xea.c b/board/liebherr/xea/xea.c index 8159f3a2d9e..4062c6fb82b 100644 --- a/board/liebherr/xea/xea.c +++ b/board/liebherr/xea/xea.c @@ -116,6 +116,7 @@ void board_boot_order(u32 *spl_boot_list) { spl_boot_list[0] = BOOT_DEVICE_MMC1; spl_boot_list[1] = BOOT_DEVICE_SPI; + spl_boot_list[2] = BOOT_DEVICE_UART; } int spl_start_uboot(void) diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig index b879de5042d..38f3fa6871c 100644 --- a/configs/imx28_xea_defconfig +++ b/configs/imx28_xea_defconfig @@ -36,6 +36,7 @@ CONFIG_SPL_MMC_TINY=y CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_SPI_LOAD=y +CONFIG_SPL_YMODEM_SUPPORT=y CONFIG_HUSH_PARSER=y CONFIG_CMD_SPL=y CONFIG_CMD_ASKENV=y From 8794cb543fad8994074f327da39f52f3db5b283c Mon Sep 17 00:00:00 2001 From: Ilko Iliev Date: Mon, 13 Jul 2020 15:25:10 +0200 Subject: [PATCH 49/51] arm: dts: imx7: Fix error in coresight TPIU graph connection OF graph endpoint connections must be bidirectional and dtc warn if they are not. i.MX7 based DTs have an error and generate warnings: arch/arm/dts/imx7d-sdb.dtb: Warning (graph_endpoint): /replicator/ports/port@0/endpoint: graph connection to node '/soc/tpiu@30087000/port/endpoint' is not bidirectional arch/arm/dts/imx7d-sdb.dtb: Warning (graph_endpoint): /soc/tpiu@30087000/port/endpoint: graph connection to node '/replicator/ports/port@1/endpoint' is not bidirectional Signed-off-by: Ilko Iliev --- arch/arm/dts/imx7s.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/imx7s.dtsi b/arch/arm/dts/imx7s.dtsi index 5c2e98be063..967023fde19 100644 --- a/arch/arm/dts/imx7s.dtsi +++ b/arch/arm/dts/imx7s.dtsi @@ -323,7 +323,7 @@ port { tpiu_in_port: endpoint { slave-mode; - remote-endpoint = <&replicator_out_port1>; + remote-endpoint = <&replicator_out_port0>; }; }; }; From 45032991194239991726cafe4dfa6a72ddf45956 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 13 Jul 2020 11:59:36 -0300 Subject: [PATCH 50/51] imx6: Remove unneeded CONFIG_DM_MDIO As explained in the CONFIG_DM_MDIO text inside drivers/net/Kconfig: "Useful in particular for systems that support DM_ETH and have a stand-alone MDIO hardware block shared by multiple Ethernet interfaces." i.MX6 has a single FEC instance, so there is no need to select CONFIG_DM_MDIO. Remove it from the i.MX6 defconfig files. Signed-off-by: Fabio Estevam --- configs/apalis_imx6_defconfig | 1 - configs/colibri_imx6_defconfig | 1 - configs/dh_imx6_defconfig | 1 - configs/mx6sabreauto_defconfig | 1 - configs/mx6sabresd_defconfig | 1 - 5 files changed, 5 deletions(-) diff --git a/configs/apalis_imx6_defconfig b/configs/apalis_imx6_defconfig index 34d939a0e91..e162f0a5e85 100644 --- a/configs/apalis_imx6_defconfig +++ b/configs/apalis_imx6_defconfig @@ -74,7 +74,6 @@ CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y diff --git a/configs/colibri_imx6_defconfig b/configs/colibri_imx6_defconfig index 11cd1da26e2..ffa773b581c 100644 --- a/configs/colibri_imx6_defconfig +++ b/configs/colibri_imx6_defconfig @@ -73,7 +73,6 @@ CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ8XXX=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index d91ff77a4a6..e643ade2e6c 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -77,7 +77,6 @@ CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y diff --git a/configs/mx6sabreauto_defconfig b/configs/mx6sabreauto_defconfig index 56fe307e638..106c967652b 100644 --- a/configs/mx6sabreauto_defconfig +++ b/configs/mx6sabreauto_defconfig @@ -76,7 +76,6 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y CONFIG_PHY_ATHEROS=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_RGMII=y CONFIG_MII=y diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig index 24bc8630f10..f88c629fbfa 100644 --- a/configs/mx6sabresd_defconfig +++ b/configs/mx6sabresd_defconfig @@ -83,7 +83,6 @@ CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y CONFIG_PHY_ATHEROS=y CONFIG_DM_ETH=y -CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_RGMII=y CONFIG_MII=y From ab8b4e818cbc3846672c13b12f1d75daccfac519 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Thu, 16 Jul 2020 15:11:18 +0200 Subject: [PATCH 51/51] mx6memcal: fix build Commit 4503299 has a side effect on this board, and build is broken. Adjust mx6memcal_defconfig to build it again. Signed-off-by: Stefano Babic --- configs/mx6memcal_defconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/mx6memcal_defconfig b/configs/mx6memcal_defconfig index 57e44a14bac..01a0fff6e0f 100644 --- a/configs/mx6memcal_defconfig +++ b/configs/mx6memcal_defconfig @@ -39,6 +39,7 @@ CONFIG_SYS_MEMTEST_END=0x20000000 CONFIG_CMD_CACHE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set +CONFIG_DM=y # CONFIG_MMC is not set CONFIG_FSL_USDHC=y CONFIG_USB=y @@ -47,4 +48,5 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y -CONFIG_REGEX=y +CONFIG_OF_LIBFDT=y +# CONFIG_EFI_LOADER is not set