From 0543a1ed2787805dbbf5f32b5bfae323452b4bd9 Mon Sep 17 00:00:00 2001 From: Andrejs Cainikovs Date: Fri, 27 May 2022 15:20:42 +0200 Subject: [PATCH 1/8] imx8m: fixup thermal trips Fixup thermal trips in Linux device tree according to SoC thermal grade. Signed-off-by: Andrejs Cainikovs Reviewed-by: Francesco Dolcini Tested-by: Adam Ford --- arch/arm/mach-imx/imx8m/soc.c | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 59335356b5..e4e56079cf 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -1203,6 +1203,48 @@ static int cleanup_nodes_for_efi(void *blob) return 0; } +static int fixup_thermal_trips(void *blob, const char *name) +{ + int minc, maxc; + int node, trip; + + node = fdt_path_offset(blob, "/thermal-zones"); + if (node < 0) + return node; + + node = fdt_subnode_offset(blob, node, name); + if (node < 0) + return node; + + node = fdt_subnode_offset(blob, node, "trips"); + if (node < 0) + return node; + + get_cpu_temp_grade(&minc, &maxc); + + fdt_for_each_subnode(trip, blob, node) { + const char *type; + int temp, ret; + + type = fdt_getprop(blob, trip, "type", NULL); + if (!type) + continue; + + temp = 0; + if (!strcmp(type, "critical")) + temp = 1000 * maxc; + else if (!strcmp(type, "passive")) + temp = 1000 * (maxc - 10); + if (temp) { + ret = fdt_setprop_u32(blob, trip, "temperature", temp); + if (ret) + return ret; + } + } + + return 0; +} + int ft_system_setup(void *blob, struct bd_info *bd) { #ifdef CONFIG_IMX8MQ @@ -1345,6 +1387,13 @@ usb_modify_speed: #endif cleanup_nodes_for_efi(blob); + + if (fixup_thermal_trips(blob, "cpu-thermal")) + printf("Failed to update cpu-thermal trip(s)"); + if (IS_ENABLED(CONFIG_IMX8MP) && + fixup_thermal_trips(blob, "soc-thermal")) + printf("Failed to update soc-thermal trip(s)"); + return 0; } #endif From b70c34224e5a2af3c145bacca460806c293621a0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 15 Jun 2022 13:07:39 +0200 Subject: [PATCH 2/8] ARM: imx: Switch Data Modul i.MX8M Mini eDM SBC to USB251x Hub driver Replace the ad-hoc I2C register programming scripted in board environment with U-Boot DM driver. Signed-off-by: Marek Vasut Cc: Fabio Estevam Cc: Peng Fan Cc: Stefano Babic Reviewed-by: Fabio Estevam --- .../imx8mm_data_modul_edm_sbc.c | 9 +++++++++ configs/imx8mm_data_modul_edm_sbc_defconfig | 1 + include/configs/imx8mm_data_modul_edm_sbc.h | 20 ------------------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c b/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c index 46cb6f77b5..6dc4e6a9a2 100644 --- a/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c +++ b/board/data_modul/imx8mm_edm_sbc/imx8mm_data_modul_edm_sbc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -104,7 +105,15 @@ int board_init(void) int board_late_init(void) { + struct udevice *dev; + int ret; + setup_boot_device(); setup_mac_address(); + + ret = uclass_get_device_by_name(UCLASS_MISC, "usb-hub@2c", &dev); + if (ret) + printf("Error bringing up USB hub (%d)\n", ret); + return 0; } diff --git a/configs/imx8mm_data_modul_edm_sbc_defconfig b/configs/imx8mm_data_modul_edm_sbc_defconfig index d55efa6d00..99a1f86220 100644 --- a/configs/imx8mm_data_modul_edm_sbc_defconfig +++ b/configs/imx8mm_data_modul_edm_sbc_defconfig @@ -156,6 +156,7 @@ CONFIG_MXC_GPIO=y CONFIG_DM_I2C=y # CONFIG_INPUT is not set CONFIG_MISC=y +CONFIG_USB_HUB_USB251XB=y CONFIG_I2C_EEPROM=y CONFIG_SYS_I2C_EEPROM_ADDR=0x50 CONFIG_SUPPORT_EMMC_BOOT=y diff --git a/include/configs/imx8mm_data_modul_edm_sbc.h b/include/configs/imx8mm_data_modul_edm_sbc.h index 67667dd523..419258f949 100644 --- a/include/configs/imx8mm_data_modul_edm_sbc.h +++ b/include/configs/imx8mm_data_modul_edm_sbc.h @@ -71,7 +71,6 @@ "mtd nor0=sf raw 0x0 0x1000000\0" \ "dmo_preboot=" \ "sf probe ; " /* Scan for SPI NOR, needed by DFU */ \ - "run dmo_usb_start_hub ; " \ /* Attempt to start USB and Network console */ \ "run dmo_usb_cdc_acm_start ; " \ "run dmo_netconsole_start\0" \ @@ -91,25 +90,6 @@ "setenv stdin ${stdin},usbacm ; " \ "fi ; " \ "fi\0" \ - "dmo_usb_start_hub=" \ - "i2c dev 1 ; " \ - /* Reset the USB USB */ \ - "gpio clear GPIO5_2 ; sleep 0.01 ; " /* t1 > 1us */ \ - "gpio set GPIO5_2 ; sleep 0.01 ; " /* t5 > 3us */ \ - /* Write chunks of descriptor into the USB HUB */ \ - "mw.l 0x7e1000 0x14042417 ; mw.l 0x7e1004 0x9b0bb325 ; "\ - "mw.l 0x7e1008 0x00000220 ; mw.l 0x7e100c 0x01320100 ; "\ - "mw.l 0x7e1010 0x00003232 ; mw.l 0x7e1014 0x4d000909 ; "\ - "i2c write 0x7e1000 0x2c 0x00 0x18 -s ; " \ - "mw.l 0x7e1000 0x6300690f ; mw.l 0x7e1004 0x6f007200 ; "\ - "mw.l 0x7e1008 0x68006300 ; mw.l 0x7e100c 0x70006900 ; "\ - "i2c write 0x7e1000 0x2c 0x18 0x10 -s ; " \ - "mw.l 0x7e1000 0x53005511 ; mw.l 0x7e1004 0x32004200 ; "\ - "mw.l 0x7e1008 0x31003500 ; mw.l 0x7e100c 0x42003400 ; "\ - "mw.l 0x7e1010 0x00006900 ; " \ - "i2c write 0x7e1000 0x2c 0x54 0x12 -s ; " \ - "mw.l 0x7e1000 0x00000101 ; " \ - "i2c write 0x7e1000 0x2c 0xff 0x2 -s\0" \ "dmo_netconsole_start=" \ "if test \"${dmo_netconsole_enabled}\" = \"true\" ; then "\ "setenv autoload false && " \ From d4cd19ded8a23fdc0d9c6499f82b3f7a596bc29d Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Fri, 24 Jun 2022 11:52:19 +0200 Subject: [PATCH 3/8] toradex: apalis/colibri_imx6: Fix CLKO1/CLKO2 output Set CLK01 and CLK02 to 24MHz and enable it in CCM_CCOSR register. This clock is used by both the audio codec (CLKO1) and by the CSI camera (CLKO2) and is expected to be 24MHz. Despite the wrong 16.5MHz there was no real issue because of the wrong frequency since Linux reconfigures the clocks afterward, however this was triggering an issue with noise coming from the SGTL5000 audio codec. The problem is that the SGTL5000 does not have a reset pin and after it is configured if the input MCLK clock is disabled it produces a constant noise on its output, this was happening on software reboot. Forcing the clock to be enabled in U-Boot prevent the problem by making sure that the clock is always available, without this change as soon as Linux was changing the clock tree (setting clk_out_sel=1 without setting clko2_en=1) the noise would start till the actual clock was enabled (clko2_en=1) during the SGTL5000 driver probe. Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam --- board/toradex/apalis_imx6/apalis_imx6.c | 14 +++++++++----- board/toradex/colibri_imx6/colibri_imx6.c | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c index 5604c4646c..ea20de6b57 100644 --- a/board/toradex/apalis_imx6/apalis_imx6.c +++ b/board/toradex/apalis_imx6/apalis_imx6.c @@ -1024,13 +1024,17 @@ static void ccgr_init(void) /* * Setup CCM_CCOSR register as follows: * - * cko1_en = 1 --> CKO1 enabled - * cko1_div = 111 --> divide by 8 - * cko1_sel = 1011 --> ahb_clk_root + * clko2_en = 1 --> CKO2 enabled + * clko2_div = 000 --> divide by 1 + * clko2_sel = 01110 --> osc_clk (24MHz) * - * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz + * clk_out_sel = 1 --> Output CKO2 to CKO1 + * + * This sets both CLKO2/CLKO1 output to 24MHz, + * CLKO1 configuration not relevant because of clk_out_sel + * (CLKO1 set to default) */ - writel(0x000000FB, &ccm->ccosr); + writel(0x010E0101, &ccm->ccosr); } static void ddr_init(int *table, int size) diff --git a/board/toradex/colibri_imx6/colibri_imx6.c b/board/toradex/colibri_imx6/colibri_imx6.c index 38ff637054..ab2ab587ff 100644 --- a/board/toradex/colibri_imx6/colibri_imx6.c +++ b/board/toradex/colibri_imx6/colibri_imx6.c @@ -980,13 +980,17 @@ static void ccgr_init(void) /* * Setup CCM_CCOSR register as follows: * - * cko1_en = 1 --> CKO1 enabled - * cko1_div = 111 --> divide by 8 - * cko1_sel = 1011 --> ahb_clk_root + * clko2_en = 1 --> CKO2 enabled + * clko2_div = 000 --> divide by 1 + * clko2_sel = 01110 --> osc_clk (24MHz) * - * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz + * clk_out_sel = 1 --> Output CKO2 to CKO1 + * + * This sets both CLKO2/CLKO1 output to 24MHz, + * CLKO1 configuration not relevant because of clk_out_sel + * (CLKO1 set to default) */ - writel(0x000000FB, &ccm->ccosr); + writel(0x010E0101, &ccm->ccosr); } static void ddr_init(int *table, int size) From 6b5ecb829391331bc1125c2b2033344b870ea5c3 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Fri, 24 Jun 2022 12:33:35 +0200 Subject: [PATCH 4/8] mx6: ddr: Fix disabling on-die termination In case rtt_nom is set to 0 keep ODT disabled (MMDC MPODTCTRL = 0). No changes required for DDR MR1 Rtt_Nom impedance register, 0 value is already handled correctly. No board is currently affected by this change (rtt_nom != 0 on all i.MX6 ddr3 boards), this will be used by a follow-up change. Fixes: fe0f7f7842e1 ("mx6: add mmdc configuration for MX6Q/MX6DL") Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam Acked-by: Marcel Ziswiler --- arch/arm/mach-imx/mx6/ddr.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/mx6/ddr.c b/arch/arm/mach-imx/mx6/ddr.c index 73a637c42d..3c87c57773 100644 --- a/arch/arm/mach-imx/mx6/ddr.c +++ b/arch/arm/mach-imx/mx6/ddr.c @@ -1469,8 +1469,17 @@ void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo, MMDC1(mprddqby3dl, 0x33333333); } - /* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */ - val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227; + /* + * MMDC Termination: rtt_nom:2 RZQ/2(120ohm), + * rtt_nom:1 RZQ/4(60ohm), + * rtt_nom:0 Disabled + */ + if (sysinfo->rtt_nom == 0) + val = 0x00000000; + else if (sysinfo->rtt_nom == 2) + val = 0x00011117; + else + val = 0x00022227; mmdc0->mpodtctrl = val; if (sysinfo->dsize > 1) MMDC1(mpodtctrl, val); From 2add0511757e2c5897a88b57c5ea8c912140e60f Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Mon, 27 Jun 2022 13:00:58 +0200 Subject: [PATCH 5/8] pmic: pca9450: Add optional SD_VSEL GPIO for LDO5 LDO5 has two separate control registers. LDO5CTRL_L is used if the input signal SD_VSEL is low and LDO5CTRL_H if it is high. The current driver implementation only uses LDO5CTRL_H. To make this work on boards that have SD_VSEL connected to a GPIO, we add support for specifying an optional GPIO and setting it to high at probe time. In the future we might also want to add support for boards that have SD_VSEL set to a fixed low level. In this case we need to change the driver to be able to use the LDO5CTRL_L register. This is a port of the same change in the Linux kernel: 8c67a11bae88 ("regulator: pca9450: Add SD_VSEL GPIO for LDO5") Signed-off-by: Frieder Schrempf Reviewed-by: Fabio Estevam Tested-by: Fabio Estevam --- drivers/power/pmic/pca9450.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/power/pmic/pca9450.c b/drivers/power/pmic/pca9450.c index 116ac49a8d..a186edc08d 100644 --- a/drivers/power/pmic/pca9450.c +++ b/drivers/power/pmic/pca9450.c @@ -7,9 +7,12 @@ #include #include #include +#include #include +#include #include #include +#include #include #include #include @@ -26,6 +29,10 @@ static const struct pmic_child_info pmic_children_info[] = { { }, }; +struct pca9450_priv { + struct gpio_desc *sd_vsel_gpio; +}; + static int pca9450_reg_count(struct udevice *dev) { return PCA9450_REG_NUM; @@ -76,6 +83,24 @@ static int pca9450_bind(struct udevice *dev) return 0; } +static int pca9450_probe(struct udevice *dev) +{ + struct pca9450_priv *priv = dev_get_priv(dev); + int ret = 0; + + if (CONFIG_IS_ENABLED(DM_GPIO) && CONFIG_IS_ENABLED(DM_REGULATOR_PCA9450)) { + priv->sd_vsel_gpio = devm_gpiod_get_optional(dev, "sd-vsel", + GPIOD_IS_OUT | + GPIOD_IS_OUT_ACTIVE); + if (IS_ERR(priv->sd_vsel_gpio)) { + ret = PTR_ERR(priv->sd_vsel_gpio); + dev_err(dev, "Failed to request SD_VSEL GPIO: %d\n", ret); + } + } + + return ret; +} + static struct dm_pmic_ops pca9450_ops = { .reg_count = pca9450_reg_count, .read = pca9450_read, @@ -94,5 +119,7 @@ U_BOOT_DRIVER(pmic_pca9450) = { .id = UCLASS_PMIC, .of_match = pca9450_ids, .bind = pca9450_bind, + .probe = pca9450_probe, .ops = &pca9450_ops, + .priv_auto = sizeof(struct pca9450_priv), }; From 1af2d4697a3b229e84901d2bdd4ffba0eb2217de Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Mon, 27 Jun 2022 13:00:59 +0200 Subject: [PATCH 6/8] imx: kontron-sl-mx8mm: Enable PCA9450 regulator driver and fix SD card access Currently accessing the SD card on USDHC2 fails with: => mmc dev 1 Card did not respond to voltage select! : -110 This is due to the fact that UHS modes are enabled in the defconfig and the devicetree, but the referenced LDO5 regulator (reg_nvcc_sd) is not available to switch the data lines from 3.3V to 1.8V mode. By enabling the regulator driver the vqmmc-supply is now available and the SD card works also in high speed modes: => mmc dev 1 switch to partitions #0, OK mmc1 is current device Please note that the board has a GPIO connected to the SD_VSEL signal of the PMIC. As the driver uses the LDO5CTRL_H register to set the voltage, we need to make sure that this GPIO (GPIO01_IO4) is set to a high level. Signed-off-by: Frieder Schrempf Reviewed-by: Fabio Estevam Tested-by: Fabio Estevam --- configs/kontron-sl-mx8mm_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/kontron-sl-mx8mm_defconfig b/configs/kontron-sl-mx8mm_defconfig index 2e9d52522b..727f99f006 100644 --- a/configs/kontron-sl-mx8mm_defconfig +++ b/configs/kontron-sl-mx8mm_defconfig @@ -99,6 +99,7 @@ CONFIG_DM_PMIC=y CONFIG_DM_PMIC_PCA9450=y CONFIG_SPL_DM_PMIC_PCA9450=y CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_PCA9450=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y CONFIG_CONS_INDEX=2 From 66af2c3e95bec055c29f139ad200e4bb4f9756f7 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Fri, 24 Jun 2022 12:33:36 +0200 Subject: [PATCH 7/8] board: apalis_imx6: DDR init using mx6_dram_cfg() Do DDR initialization using the procedural mx6_dram_cfg() instead of programming the MMDC using a raw list of register/value pairs, this solves some rare boot failures on specific "bad" modules. Calibration values, DDR geometry are unchanged, memory timings are updated according to the relevant memory datasheet, no changes on the power consumption. For IT temperature range SKUs CL is decreased from 8 to 7 and tFAW value is increased, for commercial temperature range SKUs some changes on ODT parameters. This change was validated over a range of different apalis-imx6 SoM, on the whole working temperature range with weeks of continuous testing. Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam Acked-by: Marcel Ziswiler --- board/toradex/apalis_imx6/apalis_imx6.c | 442 ++++++++++-------------- 1 file changed, 187 insertions(+), 255 deletions(-) diff --git a/board/toradex/apalis_imx6/apalis_imx6.c b/board/toradex/apalis_imx6/apalis_imx6.c index ea20de6b57..8d2642f25d 100644 --- a/board/toradex/apalis_imx6/apalis_imx6.c +++ b/board/toradex/apalis_imx6/apalis_imx6.c @@ -771,244 +771,6 @@ void ldo_mode_set(int ldo_bypass) #include "asm/arch/iomux.h" #include "asm/arch/crm_regs.h" -static int mx6_com_dcd_table[] = { -/* ddr-setup.cfg */ -MX6_IOM_DRAM_SDQS0, 0x00000030, -MX6_IOM_DRAM_SDQS1, 0x00000030, -MX6_IOM_DRAM_SDQS2, 0x00000030, -MX6_IOM_DRAM_SDQS3, 0x00000030, -MX6_IOM_DRAM_SDQS4, 0x00000030, -MX6_IOM_DRAM_SDQS5, 0x00000030, -MX6_IOM_DRAM_SDQS6, 0x00000030, -MX6_IOM_DRAM_SDQS7, 0x00000030, - -MX6_IOM_GRP_B0DS, 0x00000030, -MX6_IOM_GRP_B1DS, 0x00000030, -MX6_IOM_GRP_B2DS, 0x00000030, -MX6_IOM_GRP_B3DS, 0x00000030, -MX6_IOM_GRP_B4DS, 0x00000030, -MX6_IOM_GRP_B5DS, 0x00000030, -MX6_IOM_GRP_B6DS, 0x00000030, -MX6_IOM_GRP_B7DS, 0x00000030, -MX6_IOM_GRP_ADDDS, 0x00000030, -/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ -MX6_IOM_GRP_CTLDS, 0x00000030, - -MX6_IOM_DRAM_DQM0, 0x00020030, -MX6_IOM_DRAM_DQM1, 0x00020030, -MX6_IOM_DRAM_DQM2, 0x00020030, -MX6_IOM_DRAM_DQM3, 0x00020030, -MX6_IOM_DRAM_DQM4, 0x00020030, -MX6_IOM_DRAM_DQM5, 0x00020030, -MX6_IOM_DRAM_DQM6, 0x00020030, -MX6_IOM_DRAM_DQM7, 0x00020030, - -MX6_IOM_DRAM_CAS, 0x00020030, -MX6_IOM_DRAM_RAS, 0x00020030, -MX6_IOM_DRAM_SDCLK_0, 0x00020030, -MX6_IOM_DRAM_SDCLK_1, 0x00020030, - -MX6_IOM_DRAM_RESET, 0x00020030, -MX6_IOM_DRAM_SDCKE0, 0x00003000, -MX6_IOM_DRAM_SDCKE1, 0x00003000, - -MX6_IOM_DRAM_SDODT0, 0x00003030, -MX6_IOM_DRAM_SDODT1, 0x00003030, - -/* (differential input) */ -MX6_IOM_DDRMODE_CTL, 0x00020000, -/* (differential input) */ -MX6_IOM_GRP_DDRMODE, 0x00020000, -/* disable ddr pullups */ -MX6_IOM_GRP_DDRPKE, 0x00000000, -MX6_IOM_DRAM_SDBA2, 0x00000000, -/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ -MX6_IOM_GRP_DDR_TYPE, 0x000C0000, - -/* Read data DQ Byte0-3 delay */ -MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, -MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, -MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, -MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333, - -/* - * MDMISC mirroring interleaved (row/bank/col) - */ -MX6_MMDC_P0_MDMISC, 0x00081740, - -/* - * MDSCR con_req - */ -MX6_MMDC_P0_MDSCR, 0x00008000, - -/* 1066mhz_4x128mx16.cfg */ - -MX6_MMDC_P0_MDPDC, 0x00020036, -MX6_MMDC_P0_MDCFG0, 0x555A7954, -MX6_MMDC_P0_MDCFG1, 0xDB328F64, -MX6_MMDC_P0_MDCFG2, 0x01FF00DB, -MX6_MMDC_P0_MDRWD, 0x000026D2, -MX6_MMDC_P0_MDOR, 0x005A1023, -MX6_MMDC_P0_MDOTC, 0x09555050, -MX6_MMDC_P0_MDPDC, 0x00025576, -MX6_MMDC_P0_MDASP, 0x00000027, -MX6_MMDC_P0_MDCTL, 0x831A0000, -MX6_MMDC_P0_MDSCR, 0x04088032, -MX6_MMDC_P0_MDSCR, 0x00008033, -MX6_MMDC_P0_MDSCR, 0x00428031, -MX6_MMDC_P0_MDSCR, 0x19308030, -MX6_MMDC_P0_MDSCR, 0x04008040, -MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, -MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003, -MX6_MMDC_P0_MDREF, 0x00005800, -MX6_MMDC_P0_MPODTCTRL, 0x00000000, -MX6_MMDC_P1_MPODTCTRL, 0x00000000, - -MX6_MMDC_P0_MPDGCTRL0, 0x432A0338, -MX6_MMDC_P0_MPDGCTRL1, 0x03260324, -MX6_MMDC_P1_MPDGCTRL0, 0x43340344, -MX6_MMDC_P1_MPDGCTRL1, 0x031E027C, - -MX6_MMDC_P0_MPRDDLCTL, 0x33272D2E, -MX6_MMDC_P1_MPRDDLCTL, 0x2F312B37, - -MX6_MMDC_P0_MPWRDLCTL, 0x3A35433C, -MX6_MMDC_P1_MPWRDLCTL, 0x4336453F, - -MX6_MMDC_P0_MPWLDECTRL0, 0x0009000E, -MX6_MMDC_P0_MPWLDECTRL1, 0x0018000B, -MX6_MMDC_P1_MPWLDECTRL0, 0x00060015, -MX6_MMDC_P1_MPWLDECTRL1, 0x0006000E, - -MX6_MMDC_P0_MPMUR0, 0x00000800, -MX6_MMDC_P1_MPMUR0, 0x00000800, -MX6_MMDC_P0_MDSCR, 0x00000000, -MX6_MMDC_P0_MAPSR, 0x00011006, -}; - -static int mx6_it_dcd_table[] = { -/* ddr-setup.cfg */ -MX6_IOM_DRAM_SDQS0, 0x00000030, -MX6_IOM_DRAM_SDQS1, 0x00000030, -MX6_IOM_DRAM_SDQS2, 0x00000030, -MX6_IOM_DRAM_SDQS3, 0x00000030, -MX6_IOM_DRAM_SDQS4, 0x00000030, -MX6_IOM_DRAM_SDQS5, 0x00000030, -MX6_IOM_DRAM_SDQS6, 0x00000030, -MX6_IOM_DRAM_SDQS7, 0x00000030, - -MX6_IOM_GRP_B0DS, 0x00000030, -MX6_IOM_GRP_B1DS, 0x00000030, -MX6_IOM_GRP_B2DS, 0x00000030, -MX6_IOM_GRP_B3DS, 0x00000030, -MX6_IOM_GRP_B4DS, 0x00000030, -MX6_IOM_GRP_B5DS, 0x00000030, -MX6_IOM_GRP_B6DS, 0x00000030, -MX6_IOM_GRP_B7DS, 0x00000030, -MX6_IOM_GRP_ADDDS, 0x00000030, -/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ -MX6_IOM_GRP_CTLDS, 0x00000030, - -MX6_IOM_DRAM_DQM0, 0x00020030, -MX6_IOM_DRAM_DQM1, 0x00020030, -MX6_IOM_DRAM_DQM2, 0x00020030, -MX6_IOM_DRAM_DQM3, 0x00020030, -MX6_IOM_DRAM_DQM4, 0x00020030, -MX6_IOM_DRAM_DQM5, 0x00020030, -MX6_IOM_DRAM_DQM6, 0x00020030, -MX6_IOM_DRAM_DQM7, 0x00020030, - -MX6_IOM_DRAM_CAS, 0x00020030, -MX6_IOM_DRAM_RAS, 0x00020030, -MX6_IOM_DRAM_SDCLK_0, 0x00020030, -MX6_IOM_DRAM_SDCLK_1, 0x00020030, - -MX6_IOM_DRAM_RESET, 0x00020030, -MX6_IOM_DRAM_SDCKE0, 0x00003000, -MX6_IOM_DRAM_SDCKE1, 0x00003000, - -MX6_IOM_DRAM_SDODT0, 0x00003030, -MX6_IOM_DRAM_SDODT1, 0x00003030, - -/* (differential input) */ -MX6_IOM_DDRMODE_CTL, 0x00020000, -/* (differential input) */ -MX6_IOM_GRP_DDRMODE, 0x00020000, -/* disable ddr pullups */ -MX6_IOM_GRP_DDRPKE, 0x00000000, -MX6_IOM_DRAM_SDBA2, 0x00000000, -/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */ -MX6_IOM_GRP_DDR_TYPE, 0x000C0000, - -/* Read data DQ Byte0-3 delay */ -MX6_MMDC_P0_MPRDDQBY0DL, 0x33333333, -MX6_MMDC_P0_MPRDDQBY1DL, 0x33333333, -MX6_MMDC_P0_MPRDDQBY2DL, 0x33333333, -MX6_MMDC_P0_MPRDDQBY3DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY0DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY1DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY2DL, 0x33333333, -MX6_MMDC_P1_MPRDDQBY3DL, 0x33333333, - -/* - * MDMISC mirroring interleaved (row/bank/col) - */ -MX6_MMDC_P0_MDMISC, 0x00081740, - -/* - * MDSCR con_req - */ -MX6_MMDC_P0_MDSCR, 0x00008000, - -/* 1066mhz_4x256mx16.cfg */ - -MX6_MMDC_P0_MDPDC, 0x00020036, -MX6_MMDC_P0_MDCFG0, 0x898E78f5, -MX6_MMDC_P0_MDCFG1, 0xff328f64, -MX6_MMDC_P0_MDCFG2, 0x01FF00DB, -MX6_MMDC_P0_MDRWD, 0x000026D2, -MX6_MMDC_P0_MDOR, 0x008E1023, -MX6_MMDC_P0_MDOTC, 0x09444040, -MX6_MMDC_P0_MDPDC, 0x00025576, -MX6_MMDC_P0_MDASP, 0x00000047, -MX6_MMDC_P0_MDCTL, 0x841A0000, -MX6_MMDC_P0_MDSCR, 0x02888032, -MX6_MMDC_P0_MDSCR, 0x00008033, -MX6_MMDC_P0_MDSCR, 0x00048031, -MX6_MMDC_P0_MDSCR, 0x19408030, -MX6_MMDC_P0_MDSCR, 0x04008040, -MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003, -MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003, -MX6_MMDC_P0_MDREF, 0x00007800, -MX6_MMDC_P0_MPODTCTRL, 0x00022227, -MX6_MMDC_P1_MPODTCTRL, 0x00022227, - -MX6_MMDC_P0_MPDGCTRL0, 0x03300338, -MX6_MMDC_P0_MPDGCTRL1, 0x03240324, -MX6_MMDC_P1_MPDGCTRL0, 0x03440350, -MX6_MMDC_P1_MPDGCTRL1, 0x032C0308, - -MX6_MMDC_P0_MPRDDLCTL, 0x40363C3E, -MX6_MMDC_P1_MPRDDLCTL, 0x3C3E3C46, - -MX6_MMDC_P0_MPWRDLCTL, 0x403E463E, -MX6_MMDC_P1_MPWRDLCTL, 0x4A384C46, - -MX6_MMDC_P0_MPWLDECTRL0, 0x0009000E, -MX6_MMDC_P0_MPWLDECTRL1, 0x0018000B, -MX6_MMDC_P1_MPWLDECTRL0, 0x00060015, -MX6_MMDC_P1_MPWLDECTRL1, 0x0006000E, - -MX6_MMDC_P0_MPMUR0, 0x00000800, -MX6_MMDC_P1_MPMUR0, 0x00000800, -MX6_MMDC_P0_MDSCR, 0x00000000, -MX6_MMDC_P0_MAPSR, 0x00011006, -}; - static void ccgr_init(void) { struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; @@ -1037,27 +799,185 @@ static void ccgr_init(void) writel(0x010E0101, &ccm->ccosr); } -static void ddr_init(int *table, int size) -{ - int i; - for (i = 0; i < size / 2 ; i++) - writel(table[2 * i + 1], table[2 * i]); -} +#define PAD_CTL_INPUT_DDR BIT(17) + +struct mx6dq_iomux_ddr_regs mx6_ddr_ioregs = { + /* Differential input, 40 ohm DSE */ + .dram_sdclk_0 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_sdclk_1 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_cas = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_ras = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_reset = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + + /* SDKE[0:1]: BIT(12) and BIT(13) are reserved and set at reset */ + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + + .dram_sdba2 = 0x00000000, + + /* ODT[0:1]: 40 ohm DSE, BIT(12) and BIT(13) are reserved and set at reset */ + .dram_sdodt0 = PAD_CTL_DSE_40ohm | 0x00003000, + .dram_sdodt1 = PAD_CTL_DSE_40ohm | 0x00003000, + + /* SDQS[0:7]: 40 ohm DSE, Pull/Keeper Disabled, ODT Disabled */ + .dram_sdqs0 = PAD_CTL_DSE_40ohm, + .dram_sdqs1 = PAD_CTL_DSE_40ohm, + .dram_sdqs2 = PAD_CTL_DSE_40ohm, + .dram_sdqs3 = PAD_CTL_DSE_40ohm, + .dram_sdqs4 = PAD_CTL_DSE_40ohm, + .dram_sdqs5 = PAD_CTL_DSE_40ohm, + .dram_sdqs6 = PAD_CTL_DSE_40ohm, + .dram_sdqs7 = PAD_CTL_DSE_40ohm, + + /* DQM[0:7]: Differential input, 40 ohm DSE, Pull/Keeper Disabled, ODT Disabled */ + .dram_dqm0 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm1 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm2 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm3 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm4 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm5 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm6 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, + .dram_dqm7 = PAD_CTL_DSE_40ohm | PAD_CTL_INPUT_DDR, +}; + +struct mx6dq_iomux_grp_regs mx6_grp_ioregs = { + /* DDR3 */ + .grp_ddr_type = 0x000C0000, + + /* SDQS[0:7]: Differential input */ + .grp_ddrmode_ctl = PAD_CTL_INPUT_DDR, + + /* DATA[0:63]: Pull/Keeper disabled */ + .grp_ddrpke = 0, + + /* ADDR[0:16], SDBA[0:1]: 40 ohm DSE */ + .grp_addds = PAD_CTL_DSE_40ohm, + + /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm DSE */ + .grp_ctlds = PAD_CTL_DSE_40ohm, + + /* DATA[0:63]: Differential input */ + .grp_ddrmode = PAD_CTL_INPUT_DDR, + + /* DATA[0:63]: 40 ohm DSE */ + .grp_b0ds = PAD_CTL_DSE_40ohm, + .grp_b1ds = PAD_CTL_DSE_40ohm, + .grp_b2ds = PAD_CTL_DSE_40ohm, + .grp_b3ds = PAD_CTL_DSE_40ohm, + .grp_b4ds = PAD_CTL_DSE_40ohm, + .grp_b5ds = PAD_CTL_DSE_40ohm, + .grp_b6ds = PAD_CTL_DSE_40ohm, + .grp_b7ds = PAD_CTL_DSE_40ohm, +}; + +struct mx6_ddr_sysinfo sysinfo = { + .dsize = 2, /* width of data bus: 2=64 */ + .cs_density = 32, /* full range so that get_mem_size() works, 32Gb per CS */ + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 2, /* Dynamic ODT, RZQ/2 */ + .rtt_nom = 0, /* Disabled */ + .walat = 0, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .pd_fast_exit = 1, /* enable precharge power-down fast exit */ + .ddr_type = DDR_TYPE_DDR3, + .refsel = 1, /* Refresh cycles at 32KHz */ + .refr = 3, /* 4 refresh commands per refresh cycle */ +}; + +static const struct mx6_mmdc_calibration mx6_mmdc_calib = { + .p0_mpwldectrl0 = 0x0009000E, + .p0_mpwldectrl1 = 0x0018000B, + .p1_mpwldectrl0 = 0x00060015, + .p1_mpwldectrl1 = 0x0006000E, + .p0_mpdgctrl0 = 0x432A0338, + .p0_mpdgctrl1 = 0x03260324, + .p1_mpdgctrl0 = 0x43340344, + .p1_mpdgctrl1 = 0x031E027C, + .p0_mprddlctl = 0x33272D2E, + .p1_mprddlctl = 0x2F312B37, + .p0_mpwrdlctl = 0x3A35433C, + .p1_mpwrdlctl = 0x4336453F, +}; + +static const struct mx6_ddr3_cfg ddr3_cfg = { + .mem_speed = 1066, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1312, + .trcmin = 4812, + .trasmin = 3500, + .SRT = 0, +}; + +struct mx6_ddr_sysinfo sysinfo_it = { + .dsize = 2, /* width of data bus: 2=64 */ + .cs_density = 32, /* full range so that get_mem_size() works, 32Gb per CS */ + .ncs = 1, + .cs1_mirror = 0, + .rtt_wr = 1, /* Dynamic ODT, RZQ/4 */ + .rtt_nom = 1, /* RZQ/4 */ + .walat = 0, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .pd_fast_exit = 1, /* enable precharge power-down fast exit */ + .ddr_type = DDR_TYPE_DDR3, + .refsel = 1, /* Refresh cycles at 32KHz */ + .refr = 7, /* 8 refresh commands per refresh cycle */ +}; + +static const struct mx6_mmdc_calibration mx6_mmdc_calib_it = { + .p0_mpwldectrl0 = 0x0009000E, + .p0_mpwldectrl1 = 0x0018000B, + .p1_mpwldectrl0 = 0x00060015, + .p1_mpwldectrl1 = 0x0006000E, + .p0_mpdgctrl0 = 0x03300338, + .p0_mpdgctrl1 = 0x03240324, + .p1_mpdgctrl0 = 0x03440350, + .p1_mpdgctrl1 = 0x032C0308, + .p0_mprddlctl = 0x40363C3E, + .p1_mprddlctl = 0x3C3E3C46, + .p0_mpwrdlctl = 0x403E463E, + .p1_mpwrdlctl = 0x4A384C46, +}; + +static const struct mx6_ddr3_cfg ddr3_cfg_it = { + .mem_speed = 1066, + .density = 4, + .width = 16, + .banks = 8, + .rowaddr = 15, + .coladdr = 10, + .pagesz = 2, + .trcd = 1312, + .trcmin = 4812, + .trasmin = 3500, + .SRT = 1, +}; + /* Perform DDR DRAM calibration */ -static void spl_dram_perform_cal(void) +static void spl_dram_perform_cal(const struct mx6_ddr_sysinfo *ddr_sysinfo) { #ifdef CONFIG_MX6_DDRCAL int err; - struct mx6_ddr_sysinfo ddr_sysinfo = { - .dsize = 2, - }; - err = mmdc_do_write_level_calibration(&ddr_sysinfo); + err = mmdc_do_write_level_calibration(ddr_sysinfo); if (err) printf("error %d from write level calibration\n", err); - err = mmdc_do_dqs_calibration(&ddr_sysinfo); + err = mmdc_do_dqs_calibration(ddr_sysinfo); if (err) printf("error %d from dqs calibration\n", err); #endif @@ -1065,23 +985,35 @@ static void spl_dram_perform_cal(void) static void spl_dram_init(void) { - int minc, maxc; + bool temp_grade_it; - switch (get_cpu_temp_grade(&minc, &maxc)) { + switch (get_cpu_temp_grade(NULL, NULL)) { case TEMP_COMMERCIAL: case TEMP_EXTCOMMERCIAL: puts("Commercial temperature grade DDR3 timings.\n"); - ddr_init(mx6_com_dcd_table, ARRAY_SIZE(mx6_com_dcd_table)); + temp_grade_it = false; break; case TEMP_INDUSTRIAL: case TEMP_AUTOMOTIVE: default: puts("Industrial temperature grade DDR3 timings.\n"); - ddr_init(mx6_it_dcd_table, ARRAY_SIZE(mx6_it_dcd_table)); + temp_grade_it = true; break; }; + + mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs); + + if (temp_grade_it) + mx6_dram_cfg(&sysinfo_it, &mx6_mmdc_calib_it, &ddr3_cfg_it); + else + mx6_dram_cfg(&sysinfo, &mx6_mmdc_calib, &ddr3_cfg); + udelay(100); - spl_dram_perform_cal(); + + if (temp_grade_it) + spl_dram_perform_cal(&sysinfo_it); + else + spl_dram_perform_cal(&sysinfo); } void board_init_f(ulong dummy) From b5023254b88a67fcbca913e212e3401dea521fc9 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 9 Jun 2022 17:13:31 -0300 Subject: [PATCH 8/8] kontron-sl-mx8mm: Add CAAM support Add CAAM support, which is required when enabling HAB secure boot. Select CONFIG_SPL_DRIVERS_MISC so that CONFIG_IMX_HAB could build successfully, if selected. Signed-off-by: Fabio Estevam Acked-by: Frieder Schrempf Tested-by: Frieder Schrempf --- arch/arm/dts/imx8mm-kontron-n801x-u-boot.dtsi | 17 +++++++++++++++++ arch/arm/mach-imx/imx8m/Kconfig | 3 +++ board/kontron/sl-mx8mm/spl.c | 9 +++++++++ configs/kontron-sl-mx8mm_defconfig | 1 + 4 files changed, 30 insertions(+) diff --git a/arch/arm/dts/imx8mm-kontron-n801x-u-boot.dtsi b/arch/arm/dts/imx8mm-kontron-n801x-u-boot.dtsi index 4eadcc9899..8cd3b23793 100644 --- a/arch/arm/dts/imx8mm-kontron-n801x-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-kontron-n801x-u-boot.dtsi @@ -25,6 +25,23 @@ }; }; +&crypto { + u-boot,dm-spl; +}; + +&sec_jr0 { + u-boot,dm-spl; +}; + +&sec_jr1 { + u-boot,dm-spl; +}; + +&sec_jr2 { + u-boot,dm-spl; +}; + + &i2c1 { u-boot,dm-spl; u-boot,dm-pre-reloc; diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index ef8518c06b..09b9d5603d 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -107,6 +107,9 @@ config TARGET_KONTRON_MX8MM select IMX8MM select SUPPORT_SPL select IMX8M_LPDDR4 + select FSL_CAAM + select ARCH_MISC_INIT + select SPL_CRYPTO if SPL config TARGET_IMX8MN_BSH_SMM_S2 bool "imx8mn-bsh-smm-s2" diff --git a/board/kontron/sl-mx8mm/spl.c b/board/kontron/sl-mx8mm/spl.c index 4ef03c8c17..5a513722c5 100644 --- a/board/kontron/sl-mx8mm/spl.c +++ b/board/kontron/sl-mx8mm/spl.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -213,6 +216,12 @@ void spl_board_init(void) struct udevice *dev; int ret; + if (IS_ENABLED(CONFIG_FSL_CAAM)) { + ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev); + if (ret) + printf("Failed to initialize %s: %d\n", dev->name, ret); + } + puts("Normal Boot\n"); ret = uclass_get_device_by_name(UCLASS_CLK, diff --git a/configs/kontron-sl-mx8mm_defconfig b/configs/kontron-sl-mx8mm_defconfig index 727f99f006..f453ace625 100644 --- a/configs/kontron-sl-mx8mm_defconfig +++ b/configs/kontron-sl-mx8mm_defconfig @@ -16,6 +16,7 @@ CONFIG_SPL_TEXT_BASE=0x7E1000 CONFIG_TARGET_KONTRON_MX8MM=y CONFIG_SPL_MMC=y CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y CONFIG_BOOTCOUNT_BOOTLIMIT=3 CONFIG_SPL=y CONFIG_SYS_LOAD_ADDR=0x42000000