Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-riscv into next
CI: https://source.denx.de/u-boot/custodians/u-boot-riscv/-/pipelines/23926
- Board: Support LicheeRV Nano
- Board: Support bananapi-f3
- Board: Switch to OF_UPSTREAM for StarFive JH7110
- Board: Add sdhci driver for TH1520 SoC
diff --git a/arch/arm/mach-imx/imx8/fdt.c b/arch/arm/mach-imx/imx8/fdt.c
index 6d0585f..ce78c8c 100644
--- a/arch/arm/mach-imx/imx8/fdt.c
+++ b/arch/arm/mach-imx/imx8/fdt.c
@@ -11,6 +11,8 @@
#include <fdt_support.h>
#include <linux/libfdt.h>
#include <linux/printk.h>
+#include <cpu.h>
+#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -279,6 +281,134 @@
return 0;
}
+static int delete_node(void *blob, const char *node)
+{
+ int nodeoffset;
+ int err;
+
+ nodeoffset = fdt_path_offset(blob, node);
+ if (nodeoffset < 0)
+ return -ENXIO;
+
+ err = fdt_del_node(blob, nodeoffset);
+ if (err)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int change_property(void *blob, const char *node, const char *property,
+ const void *value, int len)
+{
+ int nodeoffset;
+ int err;
+
+ nodeoffset = fdt_path_offset(blob, node);
+ if (nodeoffset < 0)
+ return -ENXIO;
+
+ err = fdt_setprop(blob, nodeoffset, property, value, len);
+ if (err)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void update_fdt_gpu_industrial_frequencies(void *blob)
+{
+ u32 gpu_opp_table[6];
+ u32 gpu_assigned_clocks[2];
+ int err;
+
+ gpu_opp_table[0] = cpu_to_fdt32(625000); /* Normal Core Clock */
+ gpu_opp_table[1] = cpu_to_fdt32(0);
+ gpu_opp_table[2] = cpu_to_fdt32(625000); /* Normal Shader Clock */
+ gpu_opp_table[3] = cpu_to_fdt32(0);
+ gpu_opp_table[4] = cpu_to_fdt32(400000); /* Low Shader and Core Clock */
+ gpu_opp_table[5] = cpu_to_fdt32(0);
+
+ gpu_assigned_clocks[0] = cpu_to_fdt32(625000000); /* Core Clock */
+ gpu_assigned_clocks[1] = cpu_to_fdt32(625000000); /* Shader Clock */
+
+ err = change_property(blob, "/bus@53100000/gpu@53100000",
+ "assigned-clock-rates", gpu_assigned_clocks,
+ sizeof(gpu_assigned_clocks));
+ if (err && err != ENXIO)
+ printf("Failed to set assigned-clock-rates for GPU0: %s\n",
+ fdt_strerror(err));
+
+ err = change_property(blob, "/bus@54100000/gpu@54100000",
+ "assigned-clock-rates", gpu_assigned_clocks,
+ sizeof(gpu_assigned_clocks));
+ if (err && err != ENXIO)
+ printf("Failed to set assigned-clock-rates for GPU1: %s\n",
+ fdt_strerror(err));
+
+ err = change_property(blob, "/bus@54100000/imx8_gpu1_ss@80000000",
+ "operating-points", &gpu_opp_table,
+ sizeof(gpu_opp_table));
+ if (err && err != ENXIO)
+ printf("Failed to set operating-points for GPU: %s\n",
+ fdt_strerror(err));
+}
+
+static void update_fdt_cpu_industrial_frequencies(void *blob)
+{
+ int err;
+
+ err = delete_node(blob, "/opp-table-0/opp-1200000000");
+ if (err && err != -ENXIO)
+ printf("Failed to delete 1.2 GHz node on A53: %s\n",
+ fdt_strerror(err));
+
+ err = delete_node(blob, "/opp-table-1/opp-1596000000");
+ if (err && err != -ENXIO)
+ printf("Failed to delete 1.596 GHz node on A72: %s\n",
+ fdt_strerror(err));
+}
+
+static void update_fdt_frequencies(void *blob)
+{
+ struct cpu_info cpu;
+ struct udevice *dev;
+ int err;
+
+ uclass_first_device(UCLASS_CPU, &dev);
+
+ err = cpu_get_info(dev, &cpu);
+ if (err) {
+ printf("Failed to get CPU info\n");
+ return;
+ }
+
+ /*
+ * Differentiate between the automotive and industrial variants of the
+ * i.MX8. The difference of these two CPUs is the maximum frequencies
+ * for the CPU and GPU.
+ * Core Automotive [max. MHz] Industrial [max. MHz]
+ * A53 1200 1104
+ * A72 1596 1296
+ * GPU Core 800 625
+ * GPU Shader 1000 625
+ *
+ * While the SCFW enforces these limits for the CPU, the OS cpufreq
+ * driver remains unaware, causing a mismatch between reported and
+ * actual frequencies. This is resolved by removing the unsupprted
+ * frequencies from the device tree.
+ *
+ * The GPU frequencies are not enforced by the SCFW, therefore without
+ * updating the device tree we overclock the GPU.
+ *
+ * Using the cpu_freq variable is the only know way to differentiate
+ * between the automotive and industrial variants of the i.MX8.
+ */
+ if (cpu.cpu_freq != 1104000000)
+ return;
+
+ update_fdt_cpu_industrial_frequencies(blob);
+ update_fdt_gpu_industrial_frequencies(blob);
+}
+
int ft_system_setup(void *blob, struct bd_info *bd)
{
int ret;
@@ -294,6 +424,8 @@
update_fdt_with_owned_resources(blob);
+ update_fdt_frequencies(blob);
+
if (is_imx8qm()) {
ret = config_smmu_fdt(blob);
if (ret)
diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c
index 570bf2a..a8c3820 100644
--- a/board/toradex/apalis-imx8/apalis-imx8.c
+++ b/board/toradex/apalis-imx8/apalis-imx8.c
@@ -243,25 +243,22 @@
static void select_dt_from_module_version(void)
{
- env_set("soc", "imx8qm");
- env_set("variant", "-v1.1");
+ if (get_pcb_revision() == PCB_VERSION_1_0)
+ env_set("variant", "");
+ else
+ env_set("variant", "-v1.1");
switch (tdx_hw_tag.prodid) {
- /* Select Apalis iMX8QM device trees */
- case APALIS_IMX8QM_IT:
- case APALIS_IMX8QM_WIFI_BT_IT:
- case APALIS_IMX8QM_8GB_WIFI_BT_IT:
- if (get_pcb_revision() == PCB_VERSION_1_0)
- env_set("variant", "");
- break;
/* Select Apalis iMX8QP device trees */
case APALIS_IMX8QP_WIFI_BT:
case APALIS_IMX8QP:
+ case APALIS_IMX8QP_WIFI_BT_1300MHZ:
+ case APALIS_IMX8QP_1300MHZ:
env_set("soc", "imx8qp");
break;
default:
- printf("Unknown Apalis iMX8 module\n");
- return;
+ env_set("soc", "imx8qm");
+ break;
}
}
diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c
index 0fb49fc..3855e15 100644
--- a/board/toradex/common/tdx-cfg-block.c
+++ b/board/toradex/common/tdx-cfg-block.c
@@ -70,95 +70,100 @@
#define TARGET_IS_ENABLED(x) IS_ENABLED(CONFIG_TARGET_ ## x)
const struct toradex_som toradex_modules[] = {
- { 0, "UNKNOWN MODULE", 0 },
- { COLIBRI_PXA270_V1_312MHZ, "Colibri PXA270 312MHz", 0 },
- { COLIBRI_PXA270_V1_520MHZ, "Colibri PXA270 520MHz", 0 },
- { COLIBRI_PXA320, "Colibri PXA320 806MHz", 0 },
- { COLIBRI_PXA300, "Colibri PXA300 208MHz", 0 },
- { COLIBRI_PXA310, "Colibri PXA310 624MHz", 0 },
- { COLIBRI_PXA320_IT, "Colibri PXA320IT 806MHz", 0 },
- { COLIBRI_PXA300_XT, "Colibri PXA300 208MHz XT", 0 },
- { COLIBRI_PXA270_312MHZ, "Colibri PXA270 312MHz", 0 },
- { COLIBRI_PXA270_520MHZ, "Colibri PXA270 520MHz", 0 },
- { COLIBRI_VF50, "Colibri VF50 128MB", TARGET_IS_ENABLED(COLIBRI_VF) },
- { COLIBRI_VF61, "Colibri VF61 256MB", TARGET_IS_ENABLED(COLIBRI_VF) },
- { COLIBRI_VF61_IT, "Colibri VF61 256MB IT", TARGET_IS_ENABLED(COLIBRI_VF) },
- { COLIBRI_VF50_IT, "Colibri VF50 128MB IT", TARGET_IS_ENABLED(COLIBRI_VF) },
- { COLIBRI_IMX6S, "Colibri iMX6S 256MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX6DL, "Colibri iMX6DL 512MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX6S_IT, "Colibri iMX6S 256MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX6DL_IT, "Colibri iMX6DL 512MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_T20_256MB, "Colibri T20 256MB", TARGET_IS_ENABLED(COLIBRI_T20) },
- { COLIBRI_T20_512MB, "Colibri T20 512MB", TARGET_IS_ENABLED(COLIBRI_T20) },
- { COLIBRI_T20_512MB_IT, "Colibri T20 512MB IT", TARGET_IS_ENABLED(COLIBRI_T20) },
- { COLIBRI_T30, "Colibri T30 1GB", TARGET_IS_ENABLED(COLIBRI_T30) },
- { COLIBRI_T20_256MB_IT, "Colibri T20 256MB IT", TARGET_IS_ENABLED(COLIBRI_T20) },
- { APALIS_T30_2GB, "Apalis T30 2GB", TARGET_IS_ENABLED(APALIS_T30) },
- { APALIS_T30_1GB, "Apalis T30 1GB", TARGET_IS_ENABLED(APALIS_T30) },
- { APALIS_IMX6Q, "Apalis iMX6Q 1GB", TARGET_IS_ENABLED(APALIS_IMX6) },
- { APALIS_IMX6Q_IT, "Apalis iMX6Q 2GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
- { APALIS_IMX6D, "Apalis iMX6D 512MB", TARGET_IS_ENABLED(APALIS_IMX6) },
- { COLIBRI_T30_IT, "Colibri T30 1GB IT", TARGET_IS_ENABLED(COLIBRI_T30) },
- { APALIS_T30_IT, "Apalis T30 1GB IT", TARGET_IS_ENABLED(APALIS_T30) },
- { COLIBRI_IMX7S, "Colibri iMX7S 256MB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
- { COLIBRI_IMX7D, "Colibri iMX7D 512MB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
- { APALIS_TK1_2GB, "Apalis TK1 2GB", TARGET_IS_ENABLED(APALIS_TK1) },
- { APALIS_IMX6D_IT, "Apalis iMX6D 1GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
- { COLIBRI_IMX6ULL, "Colibri iMX6ULL 256MB", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
- { APALIS_IMX8QM_WIFI_BT_IT, "Apalis iMX8QM 4GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
- { COLIBRI_IMX8QXP_WIFI_BT_IT, "Colibri iMX8QXP 2GB WB IT", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
- { COLIBRI_IMX7D_EMMC, "Colibri iMX7D 1GB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
- { COLIBRI_IMX6ULL_WIFI_BT_IT, "Colibri iMX6ULL 512MB WB IT", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
- { COLIBRI_IMX7D_EPDC, "Colibri iMX7D 512MB EPDC", TARGET_IS_ENABLED(COLIBRI_IMX7) },
- { APALIS_TK1_4GB, "Apalis TK1 4GB", TARGET_IS_ENABLED(APALIS_TK1) },
- { COLIBRI_T20_512MB_IT_SETEK, "Colibri T20 512MB IT SETEK", TARGET_IS_ENABLED(COLIBRI_T20) },
- { COLIBRI_IMX6ULL_IT, "Colibri iMX6ULL 512MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
- { COLIBRI_IMX6ULL_WIFI_BT, "Colibri iMX6ULL 512MB WB", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
- { APALIS_IMX8QXP_WIFI_BT_IT, "Apalis iMX8QXP 2GB WB IT", 0 },
- { APALIS_IMX8QM_IT, "Apalis iMX8QM 4GB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
- { APALIS_IMX8QP_WIFI_BT, "Apalis iMX8QP 2GB WB", TARGET_IS_ENABLED(APALIS_IMX8) },
- { APALIS_IMX8QP, "Apalis iMX8QP 2GB", TARGET_IS_ENABLED(APALIS_IMX8) },
- { COLIBRI_IMX8QXP_IT, "Colibri iMX8QXP 2GB IT", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
- { COLIBRI_IMX8DX_WIFI_BT, "Colibri iMX8DX 1GB WB", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
- { COLIBRI_IMX8DX, "Colibri iMX8DX 1GB", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
- { APALIS_IMX8QXP, "Apalis iMX8QXP 2GB ECC IT", 0 },
- { APALIS_IMX8DXP, "Apalis iMX8DXP 1GB", TARGET_IS_ENABLED(APALIS_IMX8) },
- { VERDIN_IMX8MMQ_WIFI_BT_IT, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { VERDIN_IMX8MNQ_WIFI_BT, "Verdin iMX8M Nano Quad 1GB WB", 0 },
- { VERDIN_IMX8MMDL, "Verdin iMX8M Mini DualLite 1GB", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { VERDIN_IMX8MPQ_WIFI_BT_IT, "Verdin iMX8M Plus Quad 4GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { VERDIN_IMX8MMQ_IT, "Verdin iMX8M Mini Quad 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { VERDIN_IMX8MMDL_WIFI_BT_IT, "Verdin iMX8M Mini DualLite 1GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { VERDIN_IMX8MPQ, "Verdin iMX8M Plus Quad 2GB", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { COLIBRI_IMX6ULL_IT_EMMC, "Colibri iMX6ULL 1GB IT", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
- { VERDIN_IMX8MPQ_IT, "Verdin iMX8M Plus Quad 4GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { VERDIN_IMX8MPQ_2GB_WIFI_BT_IT, "Verdin iMX8M Plus Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { VERDIN_IMX8MPQL_IT, "Verdin iMX8M Plus QuadLite 1GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { VERDIN_IMX8MPQ_8GB_WIFI_BT, "Verdin iMX8M Plus Quad 8GB WB", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { APALIS_IMX8QM_8GB_WIFI_BT_IT, "Apalis iMX8QM 8GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
- { VERDIN_IMX8MMQ_WIFI_BT_IT_NO_CAN, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { VERDIN_AM62Q_WIFI_BT_IT, "Verdin AM62 Quad 1GB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT, "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
- { VERDIN_AM62S_512MB, "Verdin AM62 Solo 512MB", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { VERDIN_AM62S_512MB_WIFI_BT_IT, "Verdin AM62 Solo 512MB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { VERDIN_AM62D_1G_ET, "Verdin AM62 Dual 1GB ET", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { VERDIN_AM62D_1G_IT, "Verdin AM62 Dual 1GB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { VERDIN_AM62D_1G_WIFI_BT_IT, "Verdin AM62 Dual 1GB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { VERDIN_AM62Q_2G_WIFI_BT_IT, "Verdin AM62 Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
- { COLIBRI_IMX6S_NOWINCE, "Colibri iMX6S 256MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX6S_IT_NOWINCE, "Colibri iMX6S 256MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX6DL_NOWINCE, "Colibri iMX6DL 512MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX6DL_IT_NOWINCE, "Colibri iMX6DL 512MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
- { COLIBRI_IMX7D_NOWINCE, "Colibri iMX7D 512MB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
- { APALIS_IMX6D_NOWINCE, "Apalis iMX6D 512MB", TARGET_IS_ENABLED(APALIS_IMX6) },
- { APALIS_IMX6Q_NOWINCE, "Apalis iMX6Q 1GB", TARGET_IS_ENABLED(APALIS_IMX6) },
- { APALIS_IMX6D_IT_NOWINCE, "Apalis iMX6D 1GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
- { APALIS_IMX6Q_IT_NOWINCE, "Apalis iMX6Q 2GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
- { VERDIN_IMX8MMDL_2G_IT, "Verdin iMX8M Mini DualLite 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { VERDIN_IMX8MMQ_2G_IT_NO_CAN, "Verdin iMX8M Mini Quad 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
- { AQUILA_AM69O_32G_WIFI_BT_IT, "Aquila AM69 Octa 32GB WB IT", TARGET_IS_ENABLED(AQUILA_AM69_A72) },
- { VERDIN_IMX95H_16G_WIFI_BT_IT, "Verdin iMX95 Hexa 16GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX95) },
- { VERDIN_IMX8MMQ_4G_WIFI_BT_ET, "Verdin iMX8M Mini Quad 4GB WB ET", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { 0, "UNKNOWN MODULE", 0 },
+ { COLIBRI_PXA270_V1_312MHZ, "Colibri PXA270 312MHz", 0 },
+ { COLIBRI_PXA270_V1_520MHZ, "Colibri PXA270 520MHz", 0 },
+ { COLIBRI_PXA320, "Colibri PXA320 806MHz", 0 },
+ { COLIBRI_PXA300, "Colibri PXA300 208MHz", 0 },
+ { COLIBRI_PXA310, "Colibri PXA310 624MHz", 0 },
+ { COLIBRI_PXA320_IT, "Colibri PXA320IT 806MHz", 0 },
+ { COLIBRI_PXA300_XT, "Colibri PXA300 208MHz XT", 0 },
+ { COLIBRI_PXA270_312MHZ, "Colibri PXA270 312MHz", 0 },
+ { COLIBRI_PXA270_520MHZ, "Colibri PXA270 520MHz", 0 },
+ { COLIBRI_VF50, "Colibri VF50 128MB", TARGET_IS_ENABLED(COLIBRI_VF) },
+ { COLIBRI_VF61, "Colibri VF61 256MB", TARGET_IS_ENABLED(COLIBRI_VF) },
+ { COLIBRI_VF61_IT, "Colibri VF61 256MB IT", TARGET_IS_ENABLED(COLIBRI_VF) },
+ { COLIBRI_VF50_IT, "Colibri VF50 128MB IT", TARGET_IS_ENABLED(COLIBRI_VF) },
+ { COLIBRI_IMX6S, "Colibri iMX6S 256MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX6DL, "Colibri iMX6DL 512MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX6S_IT, "Colibri iMX6S 256MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX6DL_IT, "Colibri iMX6DL 512MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_T20_256MB, "Colibri T20 256MB", TARGET_IS_ENABLED(COLIBRI_T20) },
+ { COLIBRI_T20_512MB, "Colibri T20 512MB", TARGET_IS_ENABLED(COLIBRI_T20) },
+ { COLIBRI_T20_512MB_IT, "Colibri T20 512MB IT", TARGET_IS_ENABLED(COLIBRI_T20) },
+ { COLIBRI_T30, "Colibri T30 1GB", TARGET_IS_ENABLED(COLIBRI_T30) },
+ { COLIBRI_T20_256MB_IT, "Colibri T20 256MB IT", TARGET_IS_ENABLED(COLIBRI_T20) },
+ { APALIS_T30_2GB, "Apalis T30 2GB", TARGET_IS_ENABLED(APALIS_T30) },
+ { APALIS_T30_1GB, "Apalis T30 1GB", TARGET_IS_ENABLED(APALIS_T30) },
+ { APALIS_IMX6Q, "Apalis iMX6Q 1GB", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { APALIS_IMX6Q_IT, "Apalis iMX6Q 2GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { APALIS_IMX6D, "Apalis iMX6D 512MB", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { COLIBRI_T30_IT, "Colibri T30 1GB IT", TARGET_IS_ENABLED(COLIBRI_T30) },
+ { APALIS_T30_IT, "Apalis T30 1GB IT", TARGET_IS_ENABLED(APALIS_T30) },
+ { COLIBRI_IMX7S, "Colibri iMX7S 256MB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
+ { COLIBRI_IMX7D, "Colibri iMX7D 512MB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
+ { APALIS_TK1_2GB, "Apalis TK1 2GB", TARGET_IS_ENABLED(APALIS_TK1) },
+ { APALIS_IMX6D_IT, "Apalis iMX6D 1GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { COLIBRI_IMX6ULL, "Colibri iMX6ULL 256MB", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
+ { APALIS_IMX8QM_WIFI_BT_IT, "Apalis iMX8QM 4GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { COLIBRI_IMX8QXP_WIFI_BT_IT, "Colibri iMX8QXP 2GB WB IT", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
+ { COLIBRI_IMX7D_EMMC, "Colibri iMX7D 1GB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
+ { COLIBRI_IMX6ULL_WIFI_BT_IT, "Colibri iMX6ULL 512MB WB IT", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
+ { COLIBRI_IMX7D_EPDC, "Colibri iMX7D 512MB EPDC", TARGET_IS_ENABLED(COLIBRI_IMX7) },
+ { APALIS_TK1_4GB, "Apalis TK1 4GB", TARGET_IS_ENABLED(APALIS_TK1) },
+ { COLIBRI_T20_512MB_IT_SETEK, "Colibri T20 512MB IT SETEK", TARGET_IS_ENABLED(COLIBRI_T20) },
+ { COLIBRI_IMX6ULL_IT, "Colibri iMX6ULL 512MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
+ { COLIBRI_IMX6ULL_WIFI_BT, "Colibri iMX6ULL 512MB WB", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
+ { APALIS_IMX8QXP_WIFI_BT_IT, "Apalis iMX8QXP 2GB WB IT", 0 },
+ { APALIS_IMX8QM_IT, "Apalis iMX8QM 4GB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { APALIS_IMX8QP_WIFI_BT, "Apalis iMX8QP 2GB WB", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { APALIS_IMX8QP, "Apalis iMX8QP 2GB", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { COLIBRI_IMX8QXP_IT, "Colibri iMX8QXP 2GB IT", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
+ { COLIBRI_IMX8DX_WIFI_BT, "Colibri iMX8DX 1GB WB", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
+ { COLIBRI_IMX8DX, "Colibri iMX8DX 1GB", TARGET_IS_ENABLED(COLIBRI_IMX8X) },
+ { APALIS_IMX8QXP, "Apalis iMX8QXP 2GB ECC IT", 0 },
+ { APALIS_IMX8DXP, "Apalis iMX8DXP 1GB", 0 },
+ { VERDIN_IMX8MMQ_WIFI_BT_IT, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { VERDIN_IMX8MNQ_WIFI_BT, "Verdin iMX8M Nano Quad 1GB WB", 0 },
+ { VERDIN_IMX8MMDL, "Verdin iMX8M Mini DualLite 1GB", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { VERDIN_IMX8MPQ_WIFI_BT_IT, "Verdin iMX8M Plus Quad 4GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { VERDIN_IMX8MMQ_IT, "Verdin iMX8M Mini Quad 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { VERDIN_IMX8MMDL_WIFI_BT_IT, "Verdin iMX8M Mini DualLite 1GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { VERDIN_IMX8MPQ, "Verdin iMX8M Plus Quad 2GB", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { COLIBRI_IMX6ULL_IT_EMMC, "Colibri iMX6ULL 1GB IT", TARGET_IS_ENABLED(COLIBRI_IMX6ULL) },
+ { VERDIN_IMX8MPQ_IT, "Verdin iMX8M Plus Quad 4GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { VERDIN_IMX8MPQ_2GB_WIFI_BT_IT, "Verdin iMX8M Plus Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { VERDIN_IMX8MPQL_IT, "Verdin iMX8M Plus QuadLite 1GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { VERDIN_IMX8MPQ_8GB_WIFI_BT, "Verdin iMX8M Plus Quad 8GB WB", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { APALIS_IMX8QM_8GB_WIFI_BT_IT, "Apalis iMX8QM 8GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { VERDIN_IMX8MMQ_WIFI_BT_IT_NO_CAN, "Verdin iMX8M Mini Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { VERDIN_AM62Q_WIFI_BT_IT, "Verdin AM62 Quad 1GB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { VERDIN_IMX8MPQ_8GB_WIFI_BT_IT, "Verdin iMX8M Plus Quad 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX8MP) },
+ { VERDIN_AM62S_512MB, "Verdin AM62 Solo 512MB", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { VERDIN_AM62S_512MB_WIFI_BT_IT, "Verdin AM62 Solo 512MB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { VERDIN_AM62D_1G_ET, "Verdin AM62 Dual 1GB ET", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { VERDIN_AM62D_1G_IT, "Verdin AM62 Dual 1GB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { VERDIN_AM62D_1G_WIFI_BT_IT, "Verdin AM62 Dual 1GB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { VERDIN_AM62Q_2G_WIFI_BT_IT, "Verdin AM62 Quad 2GB WB IT", TARGET_IS_ENABLED(VERDIN_AM62_A53) },
+ { COLIBRI_IMX6S_NOWINCE, "Colibri iMX6S 256MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX6S_IT_NOWINCE, "Colibri iMX6S 256MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX6DL_NOWINCE, "Colibri iMX6DL 512MB", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX6DL_IT_NOWINCE, "Colibri iMX6DL 512MB IT", TARGET_IS_ENABLED(COLIBRI_IMX6) },
+ { COLIBRI_IMX7D_NOWINCE, "Colibri iMX7D 512MB", TARGET_IS_ENABLED(COLIBRI_IMX7) },
+ { APALIS_IMX6D_NOWINCE, "Apalis iMX6D 512MB", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { APALIS_IMX6Q_NOWINCE, "Apalis iMX6Q 1GB", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { APALIS_IMX6D_IT_NOWINCE, "Apalis iMX6D 1GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { APALIS_IMX6Q_IT_NOWINCE, "Apalis iMX6Q 2GB IT", TARGET_IS_ENABLED(APALIS_IMX6) },
+ { VERDIN_IMX8MMDL_2G_IT, "Verdin iMX8M Mini DualLite 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { VERDIN_IMX8MMQ_2G_IT_NO_CAN, "Verdin iMX8M Mini Quad 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { AQUILA_AM69O_32G_WIFI_BT_IT, "Aquila AM69 Octa 32GB WB IT", TARGET_IS_ENABLED(AQUILA_AM69_A72) },
+ { VERDIN_IMX95H_16G_WIFI_BT_IT, "Verdin iMX95 Hexa 16GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX95) },
+ { VERDIN_IMX8MMQ_4G_WIFI_BT_ET, "Verdin iMX8M Mini Quad 4GB WB ET", TARGET_IS_ENABLED(VERDIN_IMX8MM) },
+ { APALIS_IMX8QM_WIFI_BT_IT_1300MHZ, "Apalis iMX8QM 4GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { APALIS_IMX8QM_IT_1300MHZ, "Apalis iMX8QM 4GB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { APALIS_IMX8QP_WIFI_BT_1300MHZ, "Apalis iMX8QP 2GB WB", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { APALIS_IMX8QP_1300MHZ, "Apalis iMX8QP 2GB", TARGET_IS_ENABLED(APALIS_IMX8) },
+ { APALIS_IMX8QM_8GB_WIFI_BT_IT_1300MHZ, "Apalis iMX8QM 8GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) },
};
struct pid4list {
diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h
index 937e84c..eaa52ed 100644
--- a/board/toradex/common/tdx-cfg-block.h
+++ b/board/toradex/common/tdx-cfg-block.h
@@ -117,6 +117,11 @@
AQUILA_AM69O_32G_WIFI_BT_IT,
VERDIN_IMX95H_16G_WIFI_BT_IT,
VERDIN_IMX8MMQ_4G_WIFI_BT_ET, /* 90 */
+ APALIS_IMX8QM_WIFI_BT_IT_1300MHZ,
+ APALIS_IMX8QM_IT_1300MHZ,
+ APALIS_IMX8QP_WIFI_BT_1300MHZ,
+ APALIS_IMX8QP_1300MHZ,
+ APALIS_IMX8QM_8GB_WIFI_BT_IT_1300MHZ, /* 95 */
};
enum {
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 4936a70..93efeae 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1497,6 +1497,11 @@
help
NAND torture support.
+config CMD_NAND_WATCH
+ bool "nand watch"
+ help
+ NAND watch bitflip support.
+
endif # CMD_NAND
config CMD_NVME
diff --git a/cmd/mtd.c b/cmd/mtd.c
index f178d7b..c25997c 100644
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -122,13 +122,11 @@
{
/* Device */
printf("* %s\n", mtd->name);
-#if defined(CONFIG_DM)
if (mtd->dev) {
printf(" - device: %s\n", mtd->dev->name);
printf(" - parent: %s\n", mtd->dev->parent->name);
printf(" - driver: %s\n", mtd->dev->driver->name);
}
-#endif
if (IS_ENABLED(CONFIG_OF_CONTROL) && mtd->dev) {
char buf[256];
int res;
diff --git a/cmd/nand.c b/cmd/nand.c
index 5a328e0..2f785de 100644
--- a/cmd/nand.c
+++ b/cmd/nand.c
@@ -231,6 +231,54 @@
return ret;
}
+#ifdef CONFIG_CMD_NAND_WATCH
+static int nand_watch_bf(struct mtd_info *mtd, ulong off, ulong size, bool quiet)
+{
+ unsigned int max_bf = 0, pages_wbf = 0;
+ unsigned int first_page, pages, i;
+ struct mtd_oob_ops ops = {};
+ u_char *buf;
+ int ret;
+
+ buf = memalign(ARCH_DMA_MINALIGN, mtd->writesize);
+ if (!buf) {
+ puts("No memory for page buffer\n");
+ return 1;
+ }
+
+ first_page = off / mtd->writesize;
+ pages = size / mtd->writesize;
+
+ ops.datbuf = buf;
+ ops.len = mtd->writesize;
+ for (i = first_page; i < first_page + pages; i++) {
+ ulong addr = mtd->writesize * i;
+ ret = mtd_read_oob_bf(mtd, addr, &ops);
+ if (ret < 0) {
+ if (quiet)
+ continue;
+
+ printf("Page %7d (0x%08lx) -> error %d\n",
+ i, addr, ret);
+ } else if (ret) {
+ max_bf = max(max_bf, (unsigned int)ret);
+ pages_wbf++;
+ if (quiet)
+ continue;
+ printf("Page %7d (0x%08lx) -> up to %2d bf/chunk\n",
+ i, addr, ret);
+ }
+ }
+
+ printf("Maximum number of bitflips: %u\n", max_bf);
+ printf("Pages with bitflips: %u/%u\n", pages_wbf, pages);
+
+ free(buf);
+
+ return 0;
+}
+#endif
+
/* ------------------------------------------------------------------------- */
static int set_dev(int dev)
@@ -780,6 +828,55 @@
return ret == 0 ? 0 : 1;
}
+
+#ifdef CONFIG_CMD_NAND_WATCH
+ if (strncmp(cmd, "watch", 5) == 0) {
+ int args = 2;
+
+ if (cmd[5]) {
+ if (!strncmp(&cmd[5], ".part", 5)) {
+ args = 1;
+ } else if (!strncmp(&cmd[5], ".chip", 5)) {
+ args = 0;
+ } else {
+ goto usage;
+ }
+ }
+
+ if (cmd[10])
+ if (!strncmp(&cmd[10], ".quiet", 6))
+ quiet = true;
+
+ if (argc != 2 + args)
+ goto usage;
+
+ ret = mtd_arg_off_size(argc - 2, argv + 2, &dev, &off, &size,
+ &maxsize, MTD_DEV_TYPE_NAND, mtd->size);
+ if (ret)
+ return ret;
+
+ /* size is unspecified */
+ if (argc < 4)
+ adjust_size_for_badblocks(&size, off, dev);
+
+ if ((off & (mtd->writesize - 1)) ||
+ (size & (mtd->writesize - 1))) {
+ printf("Attempt to read non page-aligned data\n");
+ return -EINVAL;
+ }
+
+ ret = set_dev(dev);
+ if (ret)
+ return ret;
+
+ mtd = get_nand_dev_by_index(dev);
+
+ printf("\nNAND watch for bitflips in area 0x%llx-0x%llx:\n",
+ off, off + size);
+
+ return nand_watch_bf(mtd, off, size, quiet);
+ }
+#endif
#ifdef CONFIG_CMD_NAND_TORTURE
if (strcmp(cmd, "torture") == 0) {
@@ -946,6 +1043,12 @@
"nand erase.chip [clean] - erase entire chip'\n"
"nand bad - show bad blocks\n"
"nand dump[.oob] off - dump page\n"
+#ifdef CONFIG_CMD_NAND_WATCH
+ "nand watch <off> <size> - check an area for bitflips\n"
+ "nand watch.part <part> - check a partition for bitflips\n"
+ "nand watch.chip - check the whole device for bitflips\n"
+ "\t\t.quiet - Query only the summary, not the details\n"
+#endif
#ifdef CONFIG_CMD_NAND_TORTURE
"nand torture off - torture one block at offset\n"
"nand torture off [size] - torture blocks from off to off+size\n"
diff --git a/doc/imx/habv4/introduction_habv4.txt b/doc/imx/habv4/introduction_habv4.txt
index 25711bb..a2f2d83 100644
--- a/doc/imx/habv4/introduction_habv4.txt
+++ b/doc/imx/habv4/introduction_habv4.txt
@@ -240,16 +240,14 @@
authentication.
The srktool can be used for generating the SRK Table and its respective SRK
-Table Hash.
+Table Hash (certificate filenames must be separated by ',' without spaces).
- Generating SRK Table and SRK Hash in Linux 64-bit machines:
+ $ CA_CRT="sha256_2048_65537_v3_ca_crt.pem"
$ ../linux64/bin/srktool -h 4 -t SRK_1_2_3_4_table.bin -e \
SRK_1_2_3_4_fuse.bin -d sha256 -c \
- SRK1_sha256_2048_65537_v3_ca_crt.pem,\
- SRK2_sha256_2048_65537_v3_ca_crt.pem,\
- SRK3_sha256_2048_65537_v3_ca_crt.pem,\
- SRK4_sha256_2048_65537_v3_ca_crt.pem
+ SRK1_"$CA_CRT",SRK2_"$CA_CRT",SRK3_"$CA_CRT",SRK4_"$CA_CRT"
The SRK_1_2_3_4_table.bin and SRK_1_2_3_4_fuse.bin files can be used in further
steps as explained in HAB guides available under doc/imx/habv4/guides/
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 5bd64bd..3bfa5ae 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1124,6 +1124,28 @@
}
EXPORT_SYMBOL_GPL(mtd_read_oob);
+/* This is a bare copy of mtd_read_oob returning the actual number of bitflips */
+int mtd_read_oob_bf(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
+{
+ int ret_code;
+ ops->retlen = ops->oobretlen = 0;
+ if (!mtd->_read_oob)
+ return -EOPNOTSUPP;
+ /*
+ * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
+ * similar to mtd->_read(), returning a non-negative integer
+ * representing max bitflips. In other cases, mtd->_read_oob() may
+ * return -EUCLEAN. In all cases, perform similar logic to mtd_read().
+ */
+ ret_code = mtd->_read_oob(mtd, from, ops);
+ if (unlikely(ret_code < 0))
+ return ret_code;
+ if (mtd->ecc_strength == 0)
+ return 0; /* device lacks ecc */
+ return ret_code;
+}
+EXPORT_SYMBOL_GPL(mtd_read_oob_bf);
+
int mtd_write_oob(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 25f187a..56fbd64 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -568,12 +568,9 @@
struct mtd_info *mtd = nand_to_mtd(chip);
struct atmel_nand *nand = to_atmel_nand(chip);
struct atmel_hsmc_nand_controller *nc;
- int ret = -EIO;
nc = to_hsmc_nand_controller(nand->controller);
-
- if (ret)
- memcpy_toio(nc->sram.virt, buf, mtd->writesize);
+ memcpy_toio(nc->sram.virt, buf, mtd->writesize);
if (oob_required)
memcpy_toio(nc->sram.virt + mtd->writesize, chip->oob_poi,
@@ -586,12 +583,9 @@
struct mtd_info *mtd = nand_to_mtd(chip);
struct atmel_nand *nand = to_atmel_nand(chip);
struct atmel_hsmc_nand_controller *nc;
- int ret = -EIO;
nc = to_hsmc_nand_controller(nand->controller);
-
- if (ret)
- memcpy_fromio(buf, nc->sram.virt, mtd->writesize);
+ memcpy_fromio(buf, nc->sram.virt, mtd->writesize);
if (oob_required)
memcpy_fromio(chip->oob_poi, nc->sram.virt + mtd->writesize,
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index eca681b..7d2170a 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -1162,6 +1162,7 @@
{
struct phy_device *phydev = NULL;
int addr;
+ int ret;
addr = device_get_phy_addr(priv, dev);
#ifdef CFG_FEC_MXC_PHYADDR
@@ -1175,6 +1176,17 @@
if (!phydev)
return -ENODEV;
+ switch (priv->interface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_RMII:
+ ret = phy_set_supported(phydev, SPEED_100);
+ if (ret)
+ return ret;
+ break;
+ default:
+ break;
+ }
+
priv->phydev = phydev;
priv->phydev->node = priv->phy_of_node;
phy_config(phydev);