diff options
| author | Paul Gerber <[email protected]> | 2026-03-23 14:47:40 +0100 |
|---|---|---|
| committer | Fabio Estevam <[email protected]> | 2026-04-02 09:05:46 -0300 |
| commit | 1e7250ce94dabd7a9d43429b8a5fd2b6efa71a9a (patch) | |
| tree | 2a59e5d764b300d02e63af13b99e6c0d01539b6e /board/tq | |
| parent | af6b413435934cbc4361800a0e2260d1824560d0 (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]>
Diffstat (limited to 'board/tq')
| -rw-r--r-- | board/tq/tqma6/Makefile | 1 | ||||
| -rw-r--r-- | board/tq/tqma6/tqma6.c | 24 | ||||
| -rw-r--r-- | board/tq/tqma6/tqma6_emmc.c | 88 | ||||
| -rw-r--r-- | board/tq/tqma6/tqma6_emmc.h | 19 |
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__ */ |
