summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gerber <[email protected]>2026-03-23 14:47:40 +0100
committerFabio Estevam <[email protected]>2026-04-02 09:05:46 -0300
commit1e7250ce94dabd7a9d43429b8a5fd2b6efa71a9a (patch)
tree2a59e5d764b300d02e63af13b99e6c0d01539b6e
parentaf6b413435934cbc4361800a0e2260d1824560d0 (diff)
board: tqma6: update eMMC DSR handling
New SoM revision use series termination for eMMC signals while older do not. To prevent signal overshot on older revisions, DSR must be set and limited. The eMMC type is used to differentiate between revisions. Keep a table with all types, that are known to require DSR. Signed-off-by: Paul Gerber <[email protected]> Signed-off-by: Max Merchel <[email protected]>
-rw-r--r--board/tq/tqma6/Makefile1
-rw-r--r--board/tq/tqma6/tqma6.c24
-rw-r--r--board/tq/tqma6/tqma6_emmc.c88
-rw-r--r--board/tq/tqma6/tqma6_emmc.h19
4 files changed, 125 insertions, 7 deletions
diff --git a/board/tq/tqma6/Makefile b/board/tq/tqma6/Makefile
index f1b39844ac6..ecebc28315d 100644
--- a/board/tq/tqma6/Makefile
+++ b/board/tq/tqma6/Makefile
@@ -6,6 +6,7 @@
#
obj-y := tqma6.o
+obj-y += tqma6_emmc.o
obj-$(CONFIG_MBA6) += tqma6_mba6.o
obj-$(CONFIG_WRU4) += tqma6_wru4.o
diff --git a/board/tq/tqma6/tqma6.c b/board/tq/tqma6/tqma6.c
index a3a0a11c42b..005f08c4e5f 100644
--- a/board/tq/tqma6/tqma6.c
+++ b/board/tq/tqma6/tqma6.c
@@ -26,6 +26,7 @@
#include <power/pfuze100_pmic.h>
#include <power/pmic.h>
+#include "tqma6_emmc.h"
#include "../common/tq_bb.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -37,8 +38,6 @@ int dram_init(void)
return 0;
}
-static const uint16_t tqma6_emmc_dsr = 0x0100;
-
int board_early_init_f(void)
{
return tq_bb_board_early_init_f();
@@ -46,9 +45,13 @@ int board_early_init_f(void)
int board_init(void)
{
+ struct mmc *mmc = find_mmc_device(0);
+
/* address of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+ tqma6_mmc_detect_card_type(mmc);
+
tq_bb_board_init();
return 0;
@@ -111,17 +114,24 @@ int board_late_init(void)
#define MODELSTRLEN 32u
int ft_board_setup(void *blob, struct bd_info *bd)
{
+ struct mmc *mmc = find_mmc_device(0);
char modelstr[MODELSTRLEN];
snprintf(modelstr, MODELSTRLEN, "TQ %s on %s", tqma6_get_boardname(),
tq_bb_get_boardname());
do_fixup_by_path_string(blob, "/", "model", modelstr);
fdt_fixup_memory(blob, (u64)PHYS_SDRAM, (u64)gd->ram_size);
- /* bring in eMMC dsr settings */
- do_fixup_by_path_u32(blob,
- "/soc/aips-bus@02100000/usdhc@02198000",
- "dsr", tqma6_emmc_dsr, 2);
- tq_bb_ft_board_setup(blob, bd);
+
+ /* bring in eMMC dsr settings if needed */
+ if (mmc && (!mmc_init(mmc))) {
+ if (tqma6_emmc_need_dsr(mmc) > 0) {
+ tqma6_ft_fixup_emmc_dsr(blob,
+ "/soc/bus@2100000/mmc@2198000",
+ TQMA6_EMMC_DSR);
+ }
+ } else {
+ puts("eMMC: not present?\n");
+ }
return 0;
}
diff --git a/board/tq/tqma6/tqma6_emmc.c b/board/tq/tqma6/tqma6_emmc.c
new file mode 100644
index 00000000000..dd7c4d45c5c
--- /dev/null
+++ b/board/tq/tqma6/tqma6_emmc.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2017-2026 TQ-Systems GmbH <[email protected]>,
+ * D-82229 Seefeld, Germany.
+ * Author: Markus Niebel
+ */
+
+#include <fdt_support.h>
+#include <mmc.h>
+
+#include "tqma6_emmc.h"
+
+struct emmc_dsr_lookup {
+ uint mfgid;
+ char *pnm;
+ int dsr_needed;
+};
+
+static const struct emmc_dsr_lookup dsr_tbl[] = {
+ /* Micron, eMMC 4.41 */
+ { 0xfe, "MMC02G", 1 },
+ { 0xfe, "MMC04G", 1 },
+ { 0xfe, "MMC08G", 1 },
+ /* Micron, eMMC 5.0 4 GB*/
+ { 0x13, "Q1J54A", 1 },
+ { 0x13, "Q2J54A", 1 },
+ /* Micron, eMMC 5.0 8 GB*/
+ { 0x13, "Q2J55L", 0 },
+ /* Samsung, eMMC 5.0 */
+ { 0x15, "8GSD3R", 0 },
+ { 0x15, "AGSD3R", 0 },
+ { 0x15, "BGSD3R", 0 },
+ { 0x15, "CGSD3R", 0 },
+ /* SanDisk, iNAND 7250 5.1 */
+ { 0x45, "DG4008", 0 },
+ { 0x45, "DG4016", 0 },
+ { 0x45, "DG4032", 0 },
+ { 0x45, "DG4064", 0 },
+ /* Kingston */
+ { 0x100, "?????", 0 },
+};
+
+int tqma6_emmc_need_dsr(const struct mmc *mmc)
+{
+ uint mfgid = mmc->cid[0] >> 24;
+ char name[7];
+ int ret = -1;
+ size_t i;
+
+ if (IS_SD(mmc))
+ return 0;
+
+ sprintf(name, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, (mmc->cid[1] >> 24),
+ (mmc->cid[1] >> 16) & 0xff, (mmc->cid[1] >> 8) & 0xff,
+ mmc->cid[1] & 0xff, (mmc->cid[2] >> 24));
+
+ for (i = 0; i < ARRAY_SIZE(dsr_tbl) && (ret < 0); ++i) {
+ if (dsr_tbl[i].mfgid == mfgid &&
+ (!strncmp(name, dsr_tbl[i].pnm, 6))) {
+ ret = dsr_tbl[i].dsr_needed;
+ debug("MFG: %x PNM: %s\n", mfgid, name);
+ }
+ }
+
+ if (ret < 0) {
+ printf("eMMC unknown: MFG: %x PNM: %s\n", mfgid, name);
+ /* request DSR, even if not known if supported to be safe */
+ ret = 1;
+ }
+
+ return ret;
+}
+
+void tqma6_ft_fixup_emmc_dsr(void *blob, const char *path, u32 value)
+{
+ do_fixup_by_path_u32(blob, path, "dsr", value, 1);
+}
+
+void tqma6_mmc_detect_card_type(struct mmc *mmc)
+{
+ struct mmc *emmc = find_mmc_device(0);
+
+ if (emmc != mmc)
+ return;
+
+ if (tqma6_emmc_need_dsr(mmc) > 0)
+ mmc_set_dsr(mmc, TQMA6_EMMC_DSR);
+}
diff --git a/board/tq/tqma6/tqma6_emmc.h b/board/tq/tqma6/tqma6_emmc.h
new file mode 100644
index 00000000000..5ab6c3ac11d
--- /dev/null
+++ b/board/tq/tqma6/tqma6_emmc.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2017-2026 TQ-Systems GmbH <[email protected]>,
+ * D-82229 Seefeld, Germany.
+ * Author: Markus Niebel
+ */
+
+#ifndef __TQMA6_EMMC_H__
+#define __TQMA6_EMMC_H__
+
+#define TQMA6_EMMC_DSR 0x0100
+
+struct mmc;
+
+int tqma6_emmc_need_dsr(const struct mmc *mmc);
+void tqma6_ft_fixup_emmc_dsr(void *blob, const char *path, u32 value);
+void tqma6_mmc_detect_card_type(struct mmc *mmc);
+
+#endif /* __TQMA6_EMMC_H__ */