From 8b6338227e06a0ca2b31a974a99e81bae084ffe4 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:10:36 +0200 Subject: usb: gadget: fsl_udc: add imx7_barebox_(load/start)_usb These can be called from barebox PBL when booted from USB to continue USB boot. This isn't necessary in the general case when RAM setup is done via DCD, but for cases where setup is done in PBL, these helpers come in handy. Tested on i.MX7D revision 1.2. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071036.1458761-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/usb/gadget/fsl_udc_pbl.c | 11 +++++++++++ include/soc/fsl/fsl_udc.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/drivers/usb/gadget/fsl_udc_pbl.c b/drivers/usb/gadget/fsl_udc_pbl.c index 8b714d4c8b..d2f2b9e195 100644 --- a/drivers/usb/gadget/fsl_udc_pbl.c +++ b/drivers/usb/gadget/fsl_udc_pbl.c @@ -5,6 +5,7 @@ #include #include #include +#include static void fsl_queue_td(struct usb_dr_device *dr, struct ep_td_struct *dtd, int ep_is_in) @@ -210,6 +211,16 @@ int imx6_barebox_start_usb(void *dest) return imx_barebox_start_usb(IOMEM(MX6_OTG_BASE_ADDR), dest); } +int imx7_barebox_load_usb(void *dest) +{ + return imx_barebox_load_usb(IOMEM(MX7_OTG1_BASE_ADDR), dest); +} + +int imx7_barebox_start_usb(void *dest) +{ + return imx_barebox_start_usb(IOMEM(MX7_OTG1_BASE_ADDR), dest); +} + int imx8mm_barebox_load_usb(void *dest) { return imx_barebox_load_usb(IOMEM(MX8MM_USB1_BASE_ADDR), dest); diff --git a/include/soc/fsl/fsl_udc.h b/include/soc/fsl/fsl_udc.h index aa1db2fb38..c1abe222ba 100644 --- a/include/soc/fsl/fsl_udc.h +++ b/include/soc/fsl/fsl_udc.h @@ -385,6 +385,9 @@ int imx_barebox_start_usb(void __iomem *dr, void *dest); int imx6_barebox_load_usb(void *dest); int imx6_barebox_start_usb(void *dest); +int imx7_barebox_load_usb(void *dest); +int imx7_barebox_start_usb(void *dest); + int imx8mm_barebox_load_usb(void *dest); int imx8mm_barebox_start_usb(void *dest); -- cgit v1.2.3 From 1c32f4eb396c20af8031df10b3239b32d3b64005 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:53 +0200 Subject: restart: make restart.h header self-contained Code may fail compile depending on include order. Fix this. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-2-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- include/restart.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/restart.h b/include/restart.h index 2d15c7598a..27fab1b80d 100644 --- a/include/restart.h +++ b/include/restart.h @@ -2,6 +2,11 @@ #ifndef __INCLUDE_RESTART_H #define __INCLUDE_RESTART_H +#include +#include + +struct device_node; + void restart_handlers_print(void); void __noreturn restart_machine(void); struct restart_handler *restart_handler_get_by_name(const char *name); -- cgit v1.2.3 From 21dda946e7aa86246bf7ca22fb1a1609407c4bb9 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:54 +0200 Subject: restart: do restart-priority OF parsing in restart_handler_register The restart-priority OF property is parsed for a number of MFDs, but there is no reason really not to parse it for every restart handler that has a device tree node like we already do for watchdogs. Add a new struct restart_handler::of_node field and look into it if populated. With this of_get_restart_priority, is no longer used, so drop it. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-3-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- Documentation/devicetree/bindings/power/restart.rst | 10 ++++++++++ common/restart.c | 20 +++++--------------- drivers/mfd/da9053.c | 2 +- drivers/mfd/da9063.c | 2 +- drivers/mfd/rn5t568.c | 2 +- include/restart.h | 5 +++-- 6 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 Documentation/devicetree/bindings/power/restart.rst diff --git a/Documentation/devicetree/bindings/power/restart.rst b/Documentation/devicetree/bindings/power/restart.rst new file mode 100644 index 0000000000..8c866f6e0d --- /dev/null +++ b/Documentation/devicetree/bindings/power/restart.rst @@ -0,0 +1,10 @@ +System Restart Controllers +========================== + +In addition to upstream bindings, following properties are understood: + +Optional properties: + +- ``restart-priority`` : Overrides the priority set by the driver. Normally, + the device with the biggest reach should reset the system. + See :ref:`_system_reset` for more information. diff --git a/common/restart.c b/common/restart.c index b6f2bbf25b..9e988838bc 100644 --- a/common/restart.c +++ b/common/restart.c @@ -27,6 +27,11 @@ int restart_handler_register(struct restart_handler *rst) if (!rst->priority) rst->priority = RESTART_DEFAULT_PRIORITY; + if (rst->of_node) { + of_property_read_u32(rst->of_node, "restart-priority", + &rst->priority); + } + list_add_tail(&rst->list, &restart_handler_list); pr_debug("registering restart handler \"%s\" with priority %d\n", @@ -102,21 +107,6 @@ void __noreturn restart_machine(void) hang(); } -/** - * of_get_restart_priority() - get the desired restart priority from device tree - * @node: The device_node to read the property from - * - * return: The priority - */ -unsigned int of_get_restart_priority(struct device_node *node) -{ - unsigned int priority = RESTART_DEFAULT_PRIORITY; - - of_property_read_u32(node, "restart-priority", &priority); - - return priority; -} - /* * restart_handlers_print - print informations about all restart handlers */ diff --git a/drivers/mfd/da9053.c b/drivers/mfd/da9053.c index 99827c9689..693c0ca606 100644 --- a/drivers/mfd/da9053.c +++ b/drivers/mfd/da9053.c @@ -272,7 +272,7 @@ static int da9053_probe(struct device_d *dev) da9053_detect_reset_source(da9053); - da9053->restart.priority = of_get_restart_priority(dev->device_node); + da9053->restart.of_node = dev->device_node; da9053->restart.name = "da9063"; da9053->restart.restart = &da9053_force_system_reset; diff --git a/drivers/mfd/da9063.c b/drivers/mfd/da9063.c index a4e5226f3c..4627dd1aa5 100644 --- a/drivers/mfd/da9063.c +++ b/drivers/mfd/da9063.c @@ -383,7 +383,7 @@ static int da9063_probe(struct device_d *dev) da9063_detect_reset_source(priv); - priv->restart.priority = of_get_restart_priority(dev->device_node); + priv->restart.of_node = dev->device_node; priv->restart.name = "da9063"; priv->restart.restart = &da9063_restart; diff --git a/drivers/mfd/rn5t568.c b/drivers/mfd/rn5t568.c index c1c792cbec..4bbab54fe4 100644 --- a/drivers/mfd/rn5t568.c +++ b/drivers/mfd/rn5t568.c @@ -138,7 +138,7 @@ static int __init rn5t568_i2c_probe(struct device_d *dev) regmap_write(pmic_instance->regmap, RN5T568_REPCNT, RN5T568_REPCNT_OFF_RESETO_16MS | RN5T568_REPCNT_OFF_REPWRTIM_1000MS | RN5T568_REPCNT_OFF_REPWRON); - pmic_instance->restart.priority = of_get_restart_priority(dev->device_node); + pmic_instance->restart.of_node = dev->device_node; pmic_instance->restart.name = "RN5T568"; pmic_instance->restart.restart = &rn5t568_restart; restart_handler_register(&pmic_instance->restart); diff --git a/include/restart.h b/include/restart.h index 27fab1b80d..330b50a53a 100644 --- a/include/restart.h +++ b/include/restart.h @@ -11,9 +11,12 @@ void restart_handlers_print(void); void __noreturn restart_machine(void); struct restart_handler *restart_handler_get_by_name(const char *name); +struct device_node; + struct restart_handler { void (*restart)(struct restart_handler *); int priority; + struct device_node *of_node; const char *name; struct list_head list; }; @@ -24,6 +27,4 @@ int restart_handler_register_fn(const char *name, #define RESTART_DEFAULT_PRIORITY 100 -unsigned int of_get_restart_priority(struct device_node *node); - #endif /* __INCLUDE_RESTART_H */ -- cgit v1.2.3 From 1c33083a1542db3ea596481781170123f0d0510f Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:55 +0200 Subject: restart: add reset -w for warm bootrom reset We currently support reboot mode communication with BootROMs of the i.MX6Q/DL, i.MX8MM and STM32MP15x. For each of these, the user must take care to use the correct reset as the highest priority reset often clears the non-volatile register mapped by the syscon holding the reboot mode. As we only have one BootROM, we can improve usability by adding a global flag that describes whether a restart handler is suitable for use after a bootrom reboot mode write. Add a flag bit describing this and allow populating it from the device tree as well as from drivers. Existing i.MX/STM32 drivers will be moved onto this in follow-up commits. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-4-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- Documentation/boards/imx.rst | 2 +- Documentation/devicetree/bindings/power/restart.rst | 5 +++++ Documentation/user/reboot-mode.rst | 7 ++++++- commands/reset.c | 16 ++++++++++------ common/restart.c | 17 +++++++++++++---- include/restart.h | 5 ++++- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst index 4ce9d9808c..6c16923340 100644 --- a/Documentation/boards/imx.rst +++ b/Documentation/boards/imx.rst @@ -105,7 +105,7 @@ that BootROM should select after a warm reset:: mode-serial = <0x10 0x40000000>; }; - barebox@FSL i.MX8MM EVK board:/ gpr.reboot_mode.next=serial reset -r imxwd-warm + barebox@FSL i.MX8MM EVK board:/ gpr.reboot_mode.next=serial reset -w This will cause barebox to fall into serial download mode on an i.MX8MM. diff --git a/Documentation/devicetree/bindings/power/restart.rst b/Documentation/devicetree/bindings/power/restart.rst index 8c866f6e0d..42b87f7e9c 100644 --- a/Documentation/devicetree/bindings/power/restart.rst +++ b/Documentation/devicetree/bindings/power/restart.rst @@ -8,3 +8,8 @@ Optional properties: - ``restart-priority`` : Overrides the priority set by the driver. Normally, the device with the biggest reach should reset the system. See :ref:`_system_reset` for more information. + +- ``barebox,restart-warm-bootrom`` : Restart will not cause loss to non-volatile + registers sampled by the bootrom at startup. This is a necessary precondition + for working :ref:`reboot_mode` communication between barebox and the SoC's + BootROM. diff --git a/Documentation/user/reboot-mode.rst b/Documentation/user/reboot-mode.rst index 83d4136b85..1929a67e0b 100644 --- a/Documentation/user/reboot-mode.rst +++ b/Documentation/user/reboot-mode.rst @@ -47,7 +47,9 @@ Reboot mode providers have priorities. The provider with the highest priority has its parameters aliased as ``$global.system.reboot_mode.prev`` and ``$global.system.reboot_mode.next``. After executing the init scripts, barebox startup will ``source /env/bmode/${global.system.reboot_mode.prev}`` -if available. +if available. Example usage:: + + gpr.reboot_mode=serial reset -w Reset ===== @@ -60,6 +62,9 @@ If such reboot mode storage is used, users must take care to use the correct reset provider. In barebox, multiple reset providers may co-exist. The ``reset`` command allows listing and choosing a specific reboot mode. +For communication with the SoC's BootROM, a warm reset can be triggered +with ``reset -w`` if a suitable reset handler has been registered. + Disambiguation ============== diff --git a/commands/reset.c b/commands/reset.c index fe54e2f9b4..88e677afab 100644 --- a/commands/reset.c +++ b/commands/reset.c @@ -12,12 +12,12 @@ static int cmd_reset(int argc, char *argv[]) { struct restart_handler *rst; - int opt, shutdown_flag; + int opt, shutdown_flag, flags = 0; const char *name = NULL; shutdown_flag = 1; - while ((opt = getopt(argc, argv, "flr:")) > 0) { + while ((opt = getopt(argc, argv, "flwr:")) > 0) { switch (opt) { case 'f': shutdown_flag = 0; @@ -25,6 +25,9 @@ static int cmd_reset(int argc, char *argv[]) case 'l': restart_handlers_print(); return 0; + case 'w': + flags |= RESTART_FLAG_WARM_BOOTROM; + break; case 'r': name = optarg; break; @@ -33,9 +36,9 @@ static int cmd_reset(int argc, char *argv[]) } } - rst = restart_handler_get_by_name(name); - if (!rst && name) { - printf("reset '%s' does not exist\n", name); + rst = restart_handler_get_by_name(name, flags); + if (!rst && (name || flags)) { + printf("No matching restart handler found\n"); return COMMAND_ERROR; } @@ -57,13 +60,14 @@ BAREBOX_CMD_HELP_START(reset) BAREBOX_CMD_HELP_TEXT("Options:") BAREBOX_CMD_HELP_OPT("-f", "force RESET, don't call shutdown") BAREBOX_CMD_HELP_OPT("-l", "list reset handlers") +BAREBOX_CMD_HELP_OPT("-w", "only consider warm BootROM reboot-mode-preserving resets") BAREBOX_CMD_HELP_OPT("-r RESET", "use reset handler named RESET") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(reset) .cmd = cmd_reset, BAREBOX_CMD_DESC("perform RESET of the CPU") - BAREBOX_CMD_OPTS("[-flr]") + BAREBOX_CMD_OPTS("[-flrw]") BAREBOX_CMD_GROUP(CMD_GRP_BOOT) BAREBOX_CMD_HELP(cmd_reset_help) BAREBOX_CMD_COMPLETE(empty_complete) diff --git a/common/restart.c b/common/restart.c index 9e988838bc..0294b36ecc 100644 --- a/common/restart.c +++ b/common/restart.c @@ -30,6 +30,9 @@ int restart_handler_register(struct restart_handler *rst) if (rst->of_node) { of_property_read_u32(rst->of_node, "restart-priority", &rst->priority); + if (of_property_read_bool(rst->of_node, + "barebox,restart-warm-bootrom")) + rst->flags |= RESTART_FLAG_WARM_BOOTROM; } list_add_tail(&rst->list, &restart_handler_list); @@ -73,7 +76,7 @@ int restart_handler_register_fn(const char *name, /** * restart_handler_get_by_name() - reset the whole system */ -struct restart_handler *restart_handler_get_by_name(const char *name) +struct restart_handler *restart_handler_get_by_name(const char *name, int flags) { struct restart_handler *rst = NULL, *tmp; unsigned int priority = 0; @@ -81,6 +84,8 @@ struct restart_handler *restart_handler_get_by_name(const char *name) list_for_each_entry(tmp, &restart_handler_list, list) { if (name && tmp->name && strcmp(name, tmp->name)) continue; + if (flags && (tmp->flags & flags) != flags) + continue; if (tmp->priority > priority) { priority = tmp->priority; rst = tmp; @@ -97,7 +102,7 @@ void __noreturn restart_machine(void) { struct restart_handler *rst; - rst = restart_handler_get_by_name(NULL); + rst = restart_handler_get_by_name(NULL, 0); if (rst) { pr_debug("%s: using restart handler %s\n", __func__, rst->name); console_flush(); @@ -114,6 +119,10 @@ void restart_handlers_print(void) { struct restart_handler *tmp; - list_for_each_entry(tmp, &restart_handler_list, list) - printf("%-20s %6d\n", tmp->name, tmp->priority); + list_for_each_entry(tmp, &restart_handler_list, list) { + printf("%-20s %6d ", tmp->name, tmp->priority); + if (tmp->flags & RESTART_FLAG_WARM_BOOTROM) + putchar('W'); + putchar('\n'); + } } diff --git a/include/restart.h b/include/restart.h index 330b50a53a..15f30bb7ad 100644 --- a/include/restart.h +++ b/include/restart.h @@ -4,18 +4,21 @@ #include #include +#include struct device_node; void restart_handlers_print(void); void __noreturn restart_machine(void); -struct restart_handler *restart_handler_get_by_name(const char *name); +struct restart_handler *restart_handler_get_by_name(const char *name, int flags); struct device_node; struct restart_handler { void (*restart)(struct restart_handler *); int priority; +#define RESTART_FLAG_WARM_BOOTROM BIT(0) + int flags; struct device_node *of_node; const char *name; struct list_head list; -- cgit v1.2.3 From c84795430d58b67e95f01e754bcc2920e52b1b07 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:56 +0200 Subject: watchdog: imxwd: don't register broken imxwd-warm for i.MX7 Due to erratum e10574 "Watchdog: A watchdog timeout or software trigger will not reset the SOC", any use of the watchdog reset must trigger an external PMIC or reset circuit. Registering imxwd-warm thus serves no purpose, so don't register it for i.MX7. We'll need an alternative for reboot mode, which will follow in a later commit. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-5-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/watchdog/imxwd.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c index dba92cb46a..b669f6702d 100644 --- a/drivers/watchdog/imxwd.c +++ b/drivers/watchdog/imxwd.c @@ -213,7 +213,7 @@ static void imx_watchdog_detect_reset_source(struct imx_wd *priv) /* else keep the default 'unknown' state */ } -static int imx21_wd_init(struct imx_wd *priv) +static int imx21_wd_init_no_warm_reset(struct imx_wd *priv) { imx_watchdog_detect_reset_source(priv); @@ -225,6 +225,17 @@ static int imx21_wd_init(struct imx_wd *priv) return 0; } +static int imx21_wd_init(struct imx_wd *priv) +{ + priv->restart_warm.name = "imxwd-warm"; + priv->restart_warm.restart = imxwd_force_soc_reset_internal; + priv->restart_warm.priority = RESTART_DEFAULT_PRIORITY - 10; + + restart_handler_register(&priv->restart_warm); + + return imx21_wd_init_no_warm_reset(priv); +} + static int imx_wd_probe(struct device_d *dev) { struct resource *iores; @@ -294,12 +305,6 @@ static int imx_wd_probe(struct device_d *dev) restart_handler_register(&priv->restart); - priv->restart_warm.name = "imxwd-warm"; - priv->restart_warm.restart = imxwd_force_soc_reset_internal; - priv->restart_warm.priority = RESTART_DEFAULT_PRIORITY - 10; - - restart_handler_register(&priv->restart_warm); - return 0; error_unregister: @@ -310,6 +315,14 @@ on_error: return ret; } +static const struct imx_wd_ops imx7d_wd_ops = { + .set_timeout = imx21_watchdog_set_timeout, + .soc_reset = imx21_soc_reset, + .init = imx21_wd_init_no_warm_reset, + .is_running = imx21_watchdog_is_running, + .timeout_max = 128, +}; + static const struct imx_wd_ops imx21_wd_ops = { .set_timeout = imx21_watchdog_set_timeout, .soc_reset = imx21_soc_reset, @@ -331,6 +344,9 @@ static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = { }, { .compatible = "fsl,imx21-wdt", .data = &imx21_wd_ops, + }, { + .compatible = "fsl,imx7d-wdt", + .data = &imx7d_wd_ops, }, { /* sentinel */ } -- cgit v1.2.3 From 0e3902ca5bd8f1fe58bb27cea3142d8ed0b21646 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:57 +0200 Subject: watchdog: imxwd: set imxwd-warm as reboot mode default handler Set RESTART_FLAG_WARM_BOOTROM for imxwd-warm, so reset -w directly selects this handler. i.MX6QDL/8MM Users now can just do gpr.reboot_mode.next=serial reset -w and it should behave as expected. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-6-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/watchdog/imxwd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c index b669f6702d..5e9962866f 100644 --- a/drivers/watchdog/imxwd.c +++ b/drivers/watchdog/imxwd.c @@ -230,6 +230,7 @@ static int imx21_wd_init(struct imx_wd *priv) priv->restart_warm.name = "imxwd-warm"; priv->restart_warm.restart = imxwd_force_soc_reset_internal; priv->restart_warm.priority = RESTART_DEFAULT_PRIORITY - 10; + priv->restart_warm.flags = RESTART_FLAG_WARM_BOOTROM; restart_handler_register(&priv->restart_warm); -- cgit v1.2.3 From 594d5d58afcdb717620ca526ab390cef91e8ba21 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:58 +0200 Subject: Documentations: devicetree: bindings: document watchdog-priority We parse watchdog-priority for every OF-enabled watchdog device, but failed to document it. Remedy this. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-7-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- Documentation/devicetree/bindings/watchdog/watchdog.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/watchdog.rst diff --git a/Documentation/devicetree/bindings/watchdog/watchdog.rst b/Documentation/devicetree/bindings/watchdog/watchdog.rst new file mode 100644 index 0000000000..415a4520f4 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/watchdog.rst @@ -0,0 +1,10 @@ +Watchdogs +========= + +In addition to the upstream bindings, following properties are understood: + +Optional properties: + +- ``watchdog-priority`` : Overrides the priority set by the driver. Normally, + the watchdog device with the biggest reach should reset the system. + See :ref:`_system_reset` for more information. -- cgit v1.2.3 From 7f8f629c50dce14bb83e7d4e2614bdd518ca3952 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:09:59 +0200 Subject: ARM: i.MX7: describe USB serial download boot mode Due to i.MX7 erratum e10574: "Watchdog: A watchdog timeout or software trigger will not reset the SOC", we can't do warm reset via imxwd-warm for BootROM reboot mode as we do on other i.MX SoCs. What we can do instead though, is use the SoC's reset controller to toggle the Cortex-A7's reset. This will have us reenter BootROM with GPR registers intact. Forcing serial download on the i.MX7 now possible with: gpr.reboot_mode.next=serial reset -w Note that the new restart handler is not fit for general purpose. Depending on boot medium, it may hang, because the BootROM may not reinitialize the peripheral properly. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-8-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/configs/imx_v7_defconfig | 2 ++ arch/arm/dts/imx7.dtsi | 37 +++++++++++++++++++++++++++++++++++++ drivers/power/reset/syscon-reboot.c | 1 + 3 files changed, 40 insertions(+) create mode 100644 arch/arm/dts/imx7.dtsi diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig index d07abe28ae..3cbec267fc 100644 --- a/arch/arm/configs/imx_v7_defconfig +++ b/arch/arm/configs/imx_v7_defconfig @@ -208,6 +208,8 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED=y CONFIG_GENERIC_PHY=y CONFIG_USB_NOP_XCEIV=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_RESET_SYSCON=y CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y CONFIG_FS_TFTP_MAX_WINDOW_SIZE=8 diff --git a/arch/arm/dts/imx7.dtsi b/arch/arm/dts/imx7.dtsi new file mode 100644 index 0000000000..1c67bdc546 --- /dev/null +++ b/arch/arm/dts/imx7.dtsi @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include "imx7d-ddrc.dtsi" + +/ { + aliases { + gpr.reboot_mode = &reboot_mode_gpr; + }; +}; + +&src { + compatible = "fsl,imx7d-src", "syscon", "simple-mfd"; + + reboot_mode_gpr: reboot-mode { + compatible = "barebox,syscon-reboot-mode"; + offset = <0x94>, <0x98>; /* SRC_GPR{9,10} */ + mask = <0xffffffff>, <0x40000000>; + mode-normal = <0>, <0>; + mode-serial = <0x00000010>, <0x40000000>; + }; + + ca7_reset: cortex-a7-reboot { + compatible = "syscon-reboot"; + regmap = <&src>; + offset = <0x4>; + mask = <1>; + value = <1>; + /* This is not fit for use as general purpose reset */ + restart-priority = <5>; + /* + * Can't use imxwd-warm due to errata e10574: + * Watchdog: A watchdog timeout or software trigger will + * not reset the SOC + */ + barebox,restart-warm-bootrom; + }; +}; diff --git a/drivers/power/reset/syscon-reboot.c b/drivers/power/reset/syscon-reboot.c index 2dbb6c1ddc..b6b8db75ca 100644 --- a/drivers/power/reset/syscon-reboot.c +++ b/drivers/power/reset/syscon-reboot.c @@ -71,6 +71,7 @@ static int syscon_reboot_probe(struct device_d *dev) ctx->restart_handler.name = "syscon-reboot"; ctx->restart_handler.restart = syscon_restart_handle; ctx->restart_handler.priority = 192; + ctx->restart_handler.of_node = dev->device_node; err = restart_handler_register(&ctx->restart_handler); if (err) -- cgit v1.2.3 From 8130fc34366e123dbd459ed085fea280a575c0dc Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:10:00 +0200 Subject: ARM: stm32mp: mark iwdg2 with barebox,restart-warm-bootrom All STM32MP1 DTs already include their respective barebox SoC header, so set barebox,restart-warm-bootrom there, so users can portably run: tamp.reboot_mode.next=serial reset -w To get into DFU mode. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017071000.1458292-9-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- Documentation/boards/stm32mp.rst | 6 +++++- arch/arm/dts/stm32mp131.dtsi | 4 ++++ arch/arm/dts/stm32mp151.dtsi | 4 ++++ drivers/clk/clk-stm32mp1.c | 2 +- drivers/power/reset/stm32-reboot.c | 7 +++++-- include/soc/stm32/reboot.h | 6 ++++-- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Documentation/boards/stm32mp.rst b/Documentation/boards/stm32mp.rst index 4cdd281a9e..813117a04f 100644 --- a/Documentation/boards/stm32mp.rst +++ b/Documentation/boards/stm32mp.rst @@ -164,9 +164,13 @@ normal barebox functionality like creating a DFU-gadget in barebox, Fastboot/USB mass storage ... etc. The FIP image containing barebox can be generated as described in -137::ref:`stm32mp_fip`. Upstream TF-A doesn't support DFU for +:ref:`stm32mp_fip`. Upstream TF-A doesn't support DFU for SSBLs using the legacy stm32image format. +DFU mode can be forced via :ref:`reboot_mode` from a booted system with:: + + tamp.reboot_mode.next=serial reset -w + Boot source selection --------------------- diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi index 2ecad85f08..89a7ffcb81 100644 --- a/arch/arm/dts/stm32mp131.dtsi +++ b/arch/arm/dts/stm32mp131.dtsi @@ -12,3 +12,7 @@ reg = <0x5a003000 0x1000>; }; }; + +&iwdg2 { + barebox,restart-warm-bootrom; +}; diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi index ac6536a556..d3e924dc00 100644 --- a/arch/arm/dts/stm32mp151.dtsi +++ b/arch/arm/dts/stm32mp151.dtsi @@ -37,6 +37,10 @@ barebox,provide-mac-address = <ðernet0 0x39>; }; +&iwdg2 { + barebox,restart-warm-bootrom; +}; + &tamp { reboot_mode_tamp: reboot-mode { compatible = "syscon-reboot-mode"; diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index c4b03e9f6d..6753a36890 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -2280,7 +2280,7 @@ static int stm32mp1_rcc_init(struct device_d *dev) if (ret) return ret; - stm32mp_system_restart_init(base); + stm32mp_system_restart_init(dev); return 0; } diff --git a/drivers/power/reset/stm32-reboot.c b/drivers/power/reset/stm32-reboot.c index 809531e713..6789b52d57 100644 --- a/drivers/power/reset/stm32-reboot.c +++ b/drivers/power/reset/stm32-reboot.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -108,17 +109,19 @@ static void stm32_set_reset_reason(struct stm32_reset *priv, reset_source_to_string(type), reg); } -void stm32mp_system_restart_init(void __iomem *base) +void stm32mp_system_restart_init(struct device_d *dev) { struct stm32_reset *priv; + struct device_node *np = dev_of_node(dev); priv = xzalloc(sizeof(*priv)); - priv->base = base; + priv->base = of_iomap(np, 0); priv->restart.name = "stm32-rcc"; priv->restart.restart = stm32mp_rcc_restart_handler; priv->restart.priority = 200; + priv->restart.of_node = np; restart_handler_register(&priv->restart); diff --git a/include/soc/stm32/reboot.h b/include/soc/stm32/reboot.h index d6c731f59f..cf0d0286e7 100644 --- a/include/soc/stm32/reboot.h +++ b/include/soc/stm32/reboot.h @@ -5,10 +5,12 @@ #include +struct device_d; + #ifdef CONFIG_RESET_STM32 -void stm32mp_system_restart_init(void __iomem *rcc); +void stm32mp_system_restart_init(struct device_d *rcc); #else -static inline void stm32mp_system_restart_init(void __iomem *rcc) +static inline void stm32mp_system_restart_init(struct device_d *rcc) { } #endif -- cgit v1.2.3 From 6f216e784ae9fe87860b48dfc886ff9f07dd14ce Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:07:01 +0200 Subject: ARM: i.MX7: replace hardcoded UART clocking defines We currently have the clock defines for 1-3, but lack 4-6. Add generic defines that can be used for all of 1-6 and start using them in the header. The old defines are not used outside the file, so drop them. Out-of-tree users can just move the number into the parenthesis: IMX7_CCM_CCGR_UART1 -> IMX7_CCM_CCGR_UART(1) IMX7_UART1_CLK_ROOT -> IMX7_UART_CLK_ROOT(1) Consulting the data sheet also showed that IMX7_UART_CLK_ROOT__OSC_24M is the same value for all UARTs, so we omit the argument there. No functional change. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017070702.1457936-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imx7-ccm-regs.h | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h b/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h index aecf9a26d0..89a41156cd 100644 --- a/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h +++ b/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h @@ -3,24 +3,17 @@ #ifndef __MACH_IMX7_CCM_REGS_H__ #define __MACH_IMX7_CCM_REGS_H__ -#define IMX7_CCM_CCGR_UART1 148 -#define IMX7_CCM_CCGR_UART2 149 -#define IMX7_CCM_CCGR_UART3 150 - #define IMX7_CLOCK_ROOT_INDEX(x) (((x) - 0x8000) / 128) /* * Taken from "Table 5-11. Clock Root Table" from i.MX7 Dual Processor * Reference Manual */ -#define IMX7_UART1_CLK_ROOT IMX7_CLOCK_ROOT_INDEX(0xaf80) -#define IMX7_UART1_CLK_ROOT__OSC_24M IMX7_CCM_TARGET_ROOTn_MUX(0b000) - -#define IMX7_UART2_CLK_ROOT IMX7_CLOCK_ROOT_INDEX(0xb000) -#define IMX7_UART2_CLK_ROOT__OSC_24M IMX7_CCM_TARGET_ROOTn_MUX(0b000) -#define IMX7_UART3_CLK_ROOT IMX7_CLOCK_ROOT_INDEX(0xb080) -#define IMX7_UART3_CLK_ROOT__OSC_24M IMX7_CCM_TARGET_ROOTn_MUX(0b000) +/* 1 <= n <= 6 */ +#define IMX7_CCM_CCGR_UART(n) (148 + (n) - 1) +#define IMX7_UART_CLK_ROOT(n) IMX7_CLOCK_ROOT_INDEX(0xaf80 + (n - 1) * 0x80) +#define IMX7_UART_CLK_ROOT__OSC_24M IMX7_CCM_TARGET_ROOTn_MUX(0b000) /* 0 <= n <= 190 */ #define IMX7_CCM_CCGRn_SET(n) (0x4004 + 16 * (n)) @@ -39,16 +32,18 @@ #define IMX7_CCM_CCGR_SETTINGn_NEEDED_RUN_WAIT(n) IMX7_CCM_CCGR_SETTINGn(n, 0b10) #define IMX7_CCM_CCGR_SETTINGn_NEEDED(n) IMX7_CCM_CCGR_SETTINGn(n, 0b11) +/* UART counting starts for 1, like in the datasheet/dt-bindings */ + static inline void imx7_early_setup_uart_clock(void) { void __iomem *ccm = IOMEM(MX7_CCM_BASE_ADDR); writel(IMX7_CCM_CCGR_SETTINGn_NEEDED(0), - ccm + IMX7_CCM_CCGRn_CLR(IMX7_CCM_CCGR_UART1)); - writel(IMX7_CCM_TARGET_ROOTn_ENABLE | IMX7_UART1_CLK_ROOT__OSC_24M, - ccm + IMX7_CCM_TARGET_ROOTn(IMX7_UART1_CLK_ROOT)); + ccm + IMX7_CCM_CCGRn_CLR(IMX7_CCM_CCGR_UART(1))); + writel(IMX7_CCM_TARGET_ROOTn_ENABLE | IMX7_UART_CLK_ROOT__OSC_24M, + ccm + IMX7_CCM_TARGET_ROOTn(IMX7_UART_CLK_ROOT(1))); writel(IMX7_CCM_CCGR_SETTINGn_NEEDED(0), - ccm + IMX7_CCM_CCGRn_SET(IMX7_CCM_CCGR_UART1)); + ccm + IMX7_CCM_CCGRn_SET(IMX7_CCM_CCGR_UART(1))); } #endif -- cgit v1.2.3 From 37dc0b61669f120c5dc3c04b4dbe253797e329df Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 17 Oct 2022 09:07:02 +0200 Subject: ARM: i.MX7: don't hardcode UART1 in imx7_early_setup_uart_clock imx7_early_setup_uart_clock() has a very generic sounding name, but so far only set up clocks for UART1. This can lead board code authors astray that intend to user a different UART for DEBUG_LL. This issue affects board code for kamstrup-mx7-concentrator, meerkat96 and zii-imx7d-dev, which use UART4, UART6 and UART2 respectively. As I don't have this boards available to test and clock changes may have adverse effect elsewhere, we have all existing users setup UART1 as before, but note with a comment that this may not be the original author's intention. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221017070702.1457936-2-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/boards/ac-sxb/lowlevel.c | 2 +- arch/arm/boards/freescale-mx7-sabresd/lowlevel.c | 2 +- arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c | 3 ++- arch/arm/boards/meerkat96/lowlevel.c | 3 ++- arch/arm/boards/zii-imx7d-dev/lowlevel.c | 3 ++- arch/arm/mach-imx/include/mach/imx7-ccm-regs.h | 16 ++++++++++++---- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/arch/arm/boards/ac-sxb/lowlevel.c b/arch/arm/boards/ac-sxb/lowlevel.c index a910555f9b..a264549683 100644 --- a/arch/arm/boards/ac-sxb/lowlevel.c +++ b/arch/arm/boards/ac-sxb/lowlevel.c @@ -93,7 +93,7 @@ extern char __dtb_z_ac_sxb_start[]; static inline void setup_uart(void) { - imx7_early_setup_uart_clock(); + imx7_early_setup_uart_clock(1); imx7_setup_pad(MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX); diff --git a/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c b/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c index a8733d6209..6d393bf2b1 100644 --- a/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c +++ b/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c @@ -17,7 +17,7 @@ extern char __dtb_imx7d_sdb_start[]; static inline void setup_uart(void) { - imx7_early_setup_uart_clock(); + imx7_early_setup_uart_clock(1); imx7_setup_pad(MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX); diff --git a/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c b/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c index 4a9eae80d1..511f01757c 100644 --- a/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c +++ b/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c @@ -17,7 +17,8 @@ extern char __dtb_z_imx7d_flex_concentrator_mfg_start[]; static inline void setup_uart(void) { - imx7_early_setup_uart_clock(); + /* FIXME: Below UART4 is muxed, not UART1 */ + imx7_early_setup_uart_clock(1); imx7_setup_pad(MX7D_PAD_SAI2_TX_BCLK__UART4_DCE_TX); diff --git a/arch/arm/boards/meerkat96/lowlevel.c b/arch/arm/boards/meerkat96/lowlevel.c index 1c9baeacfb..e65726ef1c 100644 --- a/arch/arm/boards/meerkat96/lowlevel.c +++ b/arch/arm/boards/meerkat96/lowlevel.c @@ -14,7 +14,8 @@ extern char __dtb_z_imx7d_meerkat96_start[]; static void setup_uart(void) { - imx7_early_setup_uart_clock(); + /* FIXME: Below UART6 is muxed, not UART1 */ + imx7_early_setup_uart_clock(1); imx7_setup_pad(MX7D_PAD_SD1_WP__UART6_DCE_TX); imx7_uart_setup_ll(); putc_ll('>'); diff --git a/arch/arm/boards/zii-imx7d-dev/lowlevel.c b/arch/arm/boards/zii-imx7d-dev/lowlevel.c index 7579a2a8a0..0e316b6024 100644 --- a/arch/arm/boards/zii-imx7d-dev/lowlevel.c +++ b/arch/arm/boards/zii-imx7d-dev/lowlevel.c @@ -23,7 +23,8 @@ extern char __dtb_z_imx7d_zii_rmu2_start[]; static inline void setup_uart(void) { - imx7_early_setup_uart_clock(); + /* FIXME: Below UART2 is muxed, not UART1 */ + imx7_early_setup_uart_clock(1); imx7_setup_pad(MX7D_PAD_UART2_TX_DATA__UART2_DCE_TX); diff --git a/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h b/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h index 89a41156cd..96fad868fa 100644 --- a/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h +++ b/arch/arm/mach-imx/include/mach/imx7-ccm-regs.h @@ -3,6 +3,9 @@ #ifndef __MACH_IMX7_CCM_REGS_H__ #define __MACH_IMX7_CCM_REGS_H__ +#include +#include + #define IMX7_CLOCK_ROOT_INDEX(x) (((x) - 0x8000) / 128) /* @@ -34,16 +37,21 @@ /* UART counting starts for 1, like in the datasheet/dt-bindings */ -static inline void imx7_early_setup_uart_clock(void) +static inline void __imx7_early_setup_uart_clock(int uart) { void __iomem *ccm = IOMEM(MX7_CCM_BASE_ADDR); writel(IMX7_CCM_CCGR_SETTINGn_NEEDED(0), - ccm + IMX7_CCM_CCGRn_CLR(IMX7_CCM_CCGR_UART(1))); + ccm + IMX7_CCM_CCGRn_CLR(IMX7_CCM_CCGR_UART(uart))); writel(IMX7_CCM_TARGET_ROOTn_ENABLE | IMX7_UART_CLK_ROOT__OSC_24M, - ccm + IMX7_CCM_TARGET_ROOTn(IMX7_UART_CLK_ROOT(1))); + ccm + IMX7_CCM_TARGET_ROOTn(IMX7_UART_CLK_ROOT(uart))); writel(IMX7_CCM_CCGR_SETTINGn_NEEDED(0), - ccm + IMX7_CCM_CCGRn_SET(IMX7_CCM_CCGR_UART(1))); + ccm + IMX7_CCM_CCGRn_SET(IMX7_CCM_CCGR_UART(uart))); } +#define imx7_early_setup_uart_clock(uart) do { \ + static_assert(1 <= (uart) && (uart) <= 6, "ID out of UART1-6 range"); \ + __imx7_early_setup_uart_clock(uart); \ +} while (0) + #endif -- cgit v1.2.3 From ee1da5686dec6a13c8654800dcabc81f2868f4eb Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Oct 2022 09:26:48 +0200 Subject: ARM: i.MX8M bootsource: alias i.MX8MN functions as i.MX8MP functions Until now imx8mp_get_boot_source() and imx8mm_get_boot_source() are both the same. There are subtle differences between the SoCs though implemented in subsequent patches. i.MX8MN will be the same as i.MX8MP then, so alias imx8mn_get_boot_source() to imx8mp_get_boot_source() instead of imx8mm_get_boot_source(). Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/boot.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c index 8c9febb50a..999bd3ab91 100644 --- a/arch/arm/mach-imx/boot.c +++ b/arch/arm/mach-imx/boot.c @@ -678,12 +678,6 @@ void imx8mm_boot_save_loc(void) imx_boot_save_loc(imx8mm_get_boot_source); } -void imx8mn_get_boot_source(enum bootsource *src, int *instance) - __alias(imx8mm_get_boot_source); - -void imx8mn_boot_save_loc(void) - __alias(imx8mm_boot_save_loc); - void imx8mp_get_boot_source(enum bootsource *src, int *instance) { unsigned long addr; @@ -699,3 +693,9 @@ void imx8mp_boot_save_loc(void) { imx_boot_save_loc(imx8mp_get_boot_source); } + +void imx8mn_get_boot_source(enum bootsource *src, int *instance) + __alias(imx8mp_get_boot_source); + +void imx8mn_boot_save_loc(void) + __alias(imx8mp_boot_save_loc); -- cgit v1.2.3 From 0e96cc9e8a11fd0ecff541f77b76020d7f69fa1b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Oct 2022 09:30:09 +0200 Subject: ARM: i.MX8M bootsource: pull imx6_bootsource_serial() out of __imx7_get_boot_source() i.MX8MP and i.MX8MN will need a special variant of imx6_bootsource_serial(), so pull the call to that function out of __imx7_get_boot_source(). Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/boot.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c index 999bd3ab91..7b3334d5e2 100644 --- a/arch/arm/mach-imx/boot.c +++ b/arch/arm/mach-imx/boot.c @@ -497,11 +497,6 @@ static void __imx7_get_boot_source(enum bootsource *src, int *instance, { const struct imx_boot_sw_info *info; - if (imx6_bootsource_serial(sbmr2)) { - *src = BOOTSOURCE_SERIAL; - return; - } - info = (const void *)(unsigned long) readl(boot_sw_info_pointer_addr); @@ -539,6 +534,11 @@ void imx7_get_boot_source(enum bootsource *src, int *instance) void __iomem *src_base = IOMEM(MX7_SRC_BASE_ADDR); uint32_t sbmr2 = readl(src_base + 0x70); + if (imx6_bootsource_serial(sbmr2)) { + *src = BOOTSOURCE_SERIAL; + return; + } + __imx7_get_boot_source(src, instance, IMX7_BOOT_SW_INFO_POINTER_ADDR, sbmr2); } @@ -654,6 +654,11 @@ void imx8mq_get_boot_source(enum bootsource *src, int *instance) IMX8M_BOOT_SW_INFO_POINTER_ADDR_A0 : IMX8M_BOOT_SW_INFO_POINTER_ADDR_B0; + if (imx6_bootsource_serial(sbmr2)) { + *src = BOOTSOURCE_SERIAL; + return; + } + __imx7_get_boot_source(src, instance, addr, sbmr2); } @@ -668,6 +673,11 @@ void imx8mm_get_boot_source(enum bootsource *src, int *instance) void __iomem *src_base = IOMEM(MX8MM_SRC_BASE_ADDR); uint32_t sbmr2 = readl(src_base + 0x70); + if (imx6_bootsource_serial(sbmr2)) { + *src = BOOTSOURCE_SERIAL; + return; + } + addr = IMX8M_BOOT_SW_INFO_POINTER_ADDR_A0; __imx7_get_boot_source(src, instance, addr, sbmr2); @@ -684,6 +694,11 @@ void imx8mp_get_boot_source(enum bootsource *src, int *instance) void __iomem *src_base = IOMEM(MX8MP_SRC_BASE_ADDR); uint32_t sbmr2 = readl(src_base + 0x70); + if (imx6_bootsource_serial(sbmr2)) { + *src = BOOTSOURCE_SERIAL; + return; + } + addr = IMX8M_BOOT_SW_INFO_POINTER_ADDR_A0; __imx7_get_boot_source(src, instance, addr, sbmr2); -- cgit v1.2.3 From 8b9f1325bedb2f364907b6b7f9a91a8c37e176af Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 19 Oct 2022 16:00:53 +0200 Subject: ARM: imx8mm-evk: Switch to deep-probe Signed-off-by: Sascha Hauer --- arch/arm/boards/nxp-imx8mm-evk/board.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/arm/boards/nxp-imx8mm-evk/board.c b/arch/arm/boards/nxp-imx8mm-evk/board.c index 6e4df60065..db694943e5 100644 --- a/arch/arm/boards/nxp-imx8mm-evk/board.c +++ b/arch/arm/boards/nxp-imx8mm-evk/board.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -30,14 +31,11 @@ static int ar8031_phy_fixup(struct phy_device *phydev) return 0; } -static int nxp_imx8mm_evk_init(void) +static int imx8mm_evk_probe(struct device_d *dev) { int emmc_bbu_flag = 0; int sd_bbu_flag = 0; - if (!of_machine_is_compatible("fsl,imx8mm-evk")) - return 0; - barebox_set_hostname("imx8mm-evk"); if (bootsource_get() == BOOTSOURCE_MMC) { @@ -60,4 +58,19 @@ static int nxp_imx8mm_evk_init(void) ar8031_phy_fixup); return 0; } -device_initcall(nxp_imx8mm_evk_init); + +static const struct of_device_id imx8mm_evk_of_match[] = { + { + .compatible = "fsl,imx8mm-evk", + }, + { /* sentinel */ } +}; + +static struct driver_d imx8mm_evk_board_driver = { + .name = "board-imx8mm-evk", + .probe = imx8mm_evk_probe, + .of_compatible = imx8mm_evk_of_match, +}; +coredevice_platform_driver(imx8mm_evk_board_driver); + +BAREBOX_DEEP_PROBE_ENABLE(imx8mm_evk_of_match); -- cgit v1.2.3 From 8fbeaa3b30d68d39add6b0fb1e2ae6b01af950b7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 19 Oct 2022 16:54:53 +0200 Subject: ARM: imx8mm-evk: Add missing fsp_table The fsp_table is needed for TF-A binaries that support DDR frequency changing. On upstream TF-A this was introduced for i.MX8MM with: | commit 9c336f6118a94970f4045641a971fd1e24dba462 | Author: Jacky Bai | Date: Mon Nov 25 13:19:37 2019 +0800 | | feat(imx8m): add the ddr frequency change support for imx8m family | | Add the DDR frequency change support. | | Signed-off-by: Jacky Bai | Change-Id: If1167785796b8678c351569b83d2922c66f6e530 Signed-off-by: Sascha Hauer --- arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c index e7c01f9cc9..4b31d2803c 100644 --- a/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c +++ b/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c @@ -1975,4 +1975,5 @@ struct dram_timing_info imx8mm_evk_dram_timing = { .ddrphy_trained_csr_num = ARRAY_SIZE(lpddr4_ddrphy_trained_csr), .ddrphy_pie = lpddr4_phy_pie, .ddrphy_pie_num = ARRAY_SIZE(lpddr4_phy_pie), + .fsp_table = { 4000, 400, 100, }, }; -- cgit v1.2.3 From ede287e8b0e37526c2d944aac3dec957f22f300b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 20 Oct 2022 09:58:26 +0200 Subject: ARM: i.MX bootsource: adapt boot device detection for imx8mp imx8mp uses sbmr2[27..24] for encoding the bootmode while existing code reads only sbmr2[25..24]. This can detect BOOTSOURCE_SERIAL for the wrong mode. Based on: https://lore.barebox.org/barebox/20221014115354.4072202-1-enrico.scholz@sigma-chemnitz.de/T/#u Signed-off-by: Sascha Hauer Link: https://lore.barebox.org/20221020075826.3385137-3-s.hauer@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/boot.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c index 7b3334d5e2..c0193cfa43 100644 --- a/arch/arm/mach-imx/boot.c +++ b/arch/arm/mach-imx/boot.c @@ -202,7 +202,8 @@ void imx51_boot_save_loc(void) } #define IMX53_SRC_SBMR 0x4 -#define SRC_SBMR_BMOD GENMASK(25, 24) +#define IMX53_SRC_SBMR_BMOD GENMASK(25, 24) +#define IMX8MP_SRC_SBMR_BMOD GENMASK(27, 24) #define IMX53_BMOD_SERIAL 0b11 #define __BOOT_CFG(n, m, l) GENMASK((m) + ((n) - 1) * 8, \ @@ -234,7 +235,12 @@ __MAKE_BOOT_CFG_BITS(4) static unsigned int imx53_get_bmod(uint32_t r) { - return FIELD_GET(SRC_SBMR_BMOD, r); + return FIELD_GET(IMX53_SRC_SBMR_BMOD, r); +} + +static unsigned int imx8mp_get_bmod(uint32_t r) +{ + return FIELD_GET(IMX8MP_SRC_SBMR_BMOD, r); } static int imx53_bootsource_internal(uint32_t r) @@ -317,6 +323,8 @@ void imx53_boot_save_loc(void) #define IMX6_SRC_GPR10 0x44 #define IMX6_BMOD_SERIAL 0b01 #define IMX6_BMOD_RESERVED 0b11 +#define IMX8MP_BMOD_FUSES 0b0000 +#define IMX8MP_BMOD_SERIAL 0b0001 #define IMX6_BMOD_FUSES 0b00 #define BT_FUSE_SEL BIT(4) #define GPR10_BOOT_FROM_GPR9 BIT(28) @@ -338,6 +346,18 @@ static bool imx6_bootsource_serial(uint32_t sbmr2) !(sbmr2 & BT_FUSE_SEL)); } +static bool imx8mp_bootsource_serial(uint32_t sbmr2) +{ + return imx8mp_get_bmod(sbmr2) == IMX8MP_BMOD_SERIAL || + /* + * If boot from fuses is selected and fuses are not + * programmed by setting BT_FUSE_SEL, ROM code will + * fallback to serial mode + */ + (imx8mp_get_bmod(sbmr2) == IMX8MP_BMOD_FUSES && + !(sbmr2 & BT_FUSE_SEL)); +} + static bool imx6_bootsource_serial_forced(uint32_t bootmode) { if (cpu_mx6_is_mx6ul() || cpu_mx6_is_mx6ull()) @@ -694,7 +714,7 @@ void imx8mp_get_boot_source(enum bootsource *src, int *instance) void __iomem *src_base = IOMEM(MX8MP_SRC_BASE_ADDR); uint32_t sbmr2 = readl(src_base + 0x70); - if (imx6_bootsource_serial(sbmr2)) { + if (imx8mp_bootsource_serial(sbmr2)) { *src = BOOTSOURCE_SERIAL; return; } -- cgit v1.2.3 From d5c901e105581d4b2110c2efbd54dd5fba29aaa8 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Fri, 21 Oct 2022 07:22:40 +0200 Subject: spi: imx_spi: match fsl,imx6ul-ecspi compatible Anticipate imx8mp.dtsi device tree change suggested upstream[1] and add the new compatible to our match list. [1]: https://lore.kernel.org/all/20221020103158.2273874-2-peng.fan@oss.nxp.com/ Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221021052240.2125785-1-ahmad@a3f.at Signed-off-by: Sascha Hauer --- drivers/spi/imx_spi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c index ad3e79d54c..3e0ad2db00 100644 --- a/drivers/spi/imx_spi.c +++ b/drivers/spi/imx_spi.c @@ -662,6 +662,10 @@ static __maybe_unused struct of_device_id imx_spi_dt_ids[] = { .compatible = "fsl,imx51-ecspi", .data = &spi_imx_devtype_data_2_3, }, + { + .compatible = "fsl,imx6ul-ecspi", + .data = &spi_imx_devtype_data_2_3, + }, #endif { /* sentinel */ -- cgit v1.2.3 From 87e3c6492e8f3c16060cd90059df4d579d87c065 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 24 Oct 2022 16:12:03 +0200 Subject: ARM: i.MX8MM: innocomm-wb15: imply AT803X_PHY for EVK EVK has Atheros 8035 Ethernet PHY and DHCP times out when using the generic PHY driver instead of the at803x driver. Link is detected with both though. Make user lives easier by adding an imply to the PHY driver when the board is selected. This is chosen instead of a select to allow users to disable the driver if they use a different base board for the SoM. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221024141203.2473619-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c78c950357..fd4f68627d 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -371,6 +371,7 @@ config MACH_INNOCOMM_WB15 select IMX8M_DRAM select I2C_IMX_EARLY select USB_GADGET_DRIVER_ARC_PBL + imply AT803X_PHY config MACH_KONTRON_SAMX6I bool "Kontron sAMX6i" -- cgit v1.2.3 From d9db4ac446fa601125b1dbafd9d6c280b429edaa Mon Sep 17 00:00:00 2001 From: Holger Assmann Date: Wed, 26 Oct 2022 11:38:45 +0200 Subject: ARM: i.MX8MP: add TQ mba8mpxl board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for the TQ MBa8MPxL with TQMa8MPxL module with i.MX8M Plus Quad/Dual SoC. This very combination results in configuration symbol "MACH_TQ_MBA8MPXL". A possible variant based on i.MX8M Plus Dual would be supported transparently, once barebox deleted the CPU nodes when it detects that they were fused away. It already does so for i.MX8MM and i.MX8MN. We use the respective Linux upstream device trees and their implications regarding hardware support. Known to be unsupported for now is the second Ethernet interface around the eqos dwmac IP. This has to be resolved by porting over the fitting wrapper from Linux. Signed-off-by: Leonard Göhrs Signed-off-by: Holger Assmann Reviewed-by: Ahmad Fatoum Link: https://lore.barebox.org/20221026093845.304181-1-h.assmann@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/boards/Makefile | 1 + arch/arm/boards/tqma8mpxl/Makefile | 4 + arch/arm/boards/tqma8mpxl/board.c | 49 + .../boards/tqma8mpxl/flash-header-tqma8mpxl.imxcfg | 7 + arch/arm/boards/tqma8mpxl/lowlevel.c | 111 ++ arch/arm/boards/tqma8mpxl/lpddr4-timing.c | 1856 ++++++++++++++++++++ arch/arm/configs/imx_v8_defconfig | 1 + arch/arm/dts/Makefile | 1 + arch/arm/dts/imx8mp-tqma8mpql-mba8mpxl.dts | 59 + arch/arm/mach-imx/Kconfig | 10 + images/Makefile.imx | 5 + 11 files changed, 2104 insertions(+) create mode 100644 arch/arm/boards/tqma8mpxl/Makefile create mode 100644 arch/arm/boards/tqma8mpxl/board.c create mode 100644 arch/arm/boards/tqma8mpxl/flash-header-tqma8mpxl.imxcfg create mode 100644 arch/arm/boards/tqma8mpxl/lowlevel.c create mode 100644 arch/arm/boards/tqma8mpxl/lpddr4-timing.c create mode 100644 arch/arm/dts/imx8mp-tqma8mpql-mba8mpxl.dts diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index a0e84c24d7..0f4339ebed 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += nxp-imx8mq-evk/ obj-$(CONFIG_MACH_NXP_IMX8MM_EVK) += nxp-imx8mm-evk/ obj-$(CONFIG_MACH_NXP_IMX8MN_EVK) += nxp-imx8mn-evk/ obj-$(CONFIG_MACH_NXP_IMX8MP_EVK) += nxp-imx8mp-evk/ +obj-$(CONFIG_MACH_TQ_MBA8MPXL) += tqma8mpxl/ obj-$(CONFIG_MACH_OMAP343xSDP) += omap343xdsp/ obj-$(CONFIG_MACH_OMAP3EVM) += omap3evm/ obj-$(CONFIG_MACH_PANDA) += panda/ diff --git a/arch/arm/boards/tqma8mpxl/Makefile b/arch/arm/boards/tqma8mpxl/Makefile new file mode 100644 index 0000000000..35d8640087 --- /dev/null +++ b/arch/arm/boards/tqma8mpxl/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-y += board.o +lwl-y += lowlevel.o lpddr4-timing.o diff --git a/arch/arm/boards/tqma8mpxl/board.c b/arch/arm/boards/tqma8mpxl/board.c new file mode 100644 index 0000000000..648286d3b2 --- /dev/null +++ b/arch/arm/boards/tqma8mpxl/board.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Holger Assmann + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int tqma8mpxl_probe(struct device_d *dev) +{ + int emmc_bbu_flag = 0; + int sd_bbu_flag = 0; + + if (bootsource_get() == BOOTSOURCE_MMC && bootsource_get_instance() == 1) { + of_device_enable_path("/chosen/environment-sd"); + sd_bbu_flag = BBU_HANDLER_FLAG_DEFAULT; + } else { + of_device_enable_path("/chosen/environment-emmc"); + emmc_bbu_flag = BBU_HANDLER_FLAG_DEFAULT; + } + + imx8m_bbu_internal_mmc_register_handler("SD", "/dev/mmc1.barebox", sd_bbu_flag); + imx8m_bbu_internal_mmcboot_register_handler("eMMC", "/dev/mmc2", emmc_bbu_flag); + + return 0; +} + +static const struct of_device_id tqma8mpxl_of_match[] = { + { .compatible = "tq,imx8mp-tqma8mpdl-mba8mpxl"}, + { .compatible = "tq,imx8mp-tqma8mpql-mba8mpxl"}, + { /* sentinel */ }, +}; +BAREBOX_DEEP_PROBE_ENABLE(tqma8mpxl_of_match); + +static struct driver_d tqma8mpxl_board_driver = { + .name = "board-tqma8mpxl", + .probe = tqma8mpxl_probe, + .of_compatible = DRV_OF_COMPAT(tqma8mpxl_of_match), +}; +device_platform_driver(tqma8mpxl_board_driver); diff --git a/arch/arm/boards/tqma8mpxl/flash-header-tqma8mpxl.imxcfg b/arch/arm/boards/tqma8mpxl/flash-header-tqma8mpxl.imxcfg new file mode 100644 index 0000000000..663bd102e9 --- /dev/null +++ b/arch/arm/boards/tqma8mpxl/flash-header-tqma8mpxl.imxcfg @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only + +soc imx8mp + +loadaddr 0x920000 +max_load_size 0x3f000 +ivtofs 0x0 diff --git a/arch/arm/boards/tqma8mpxl/lowlevel.c b/arch/arm/boards/tqma8mpxl/lowlevel.c new file mode 100644 index 0000000000..0ce0e7a73b --- /dev/null +++ b/arch/arm/boards/tqma8mpxl/lowlevel.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define UART_PAD_CTRL MUX_PAD_CTRL(MX8MP_PAD_CTL_DSE6 | \ + MX8MP_PAD_CTL_FSEL) + +#define I2C_PAD_CTRL MUX_PAD_CTRL(MX8MP_PAD_CTL_DSE6 | \ + MX8MP_PAD_CTL_HYS | \ + MX8MP_PAD_CTL_PUE | \ + MX8MP_PAD_CTL_PE) + +static void setup_uart(void) +{ + void __iomem *uart = IOMEM(MX8M_UART4_BASE_ADDR); + + imx8m_early_setup_uart_clock(); + + imx8mp_setup_pad(MX8MP_PAD_UART4_TXD__UART4_DCE_TX | UART_PAD_CTRL); + imx8mp_setup_pad(MX8MP_PAD_UART4_RXD__UART4_DCE_RX | UART_PAD_CTRL); + imx8m_uart_setup(uart); + + pbl_set_putc(imx_uart_putc, uart); + + putc_ll('>'); +} + +static struct pmic_config pca9450_cfg[] = { + /* BUCKxOUT_DVS0/1 control BUCK123 output */ + { PCA9450_BUCK123_DVS, 0x29 }, + /* + * increase VDD_SOC to typical value 0.95V before first + * DRAM access, set DVS1 to 0.85v for suspend. + * Enable DVS control through PMIC_STBY_REQ and + * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) + */ + { PCA9450_BUCK1OUT_DVS0, 0x1C }, + { PCA9450_BUCK1OUT_DVS1, 0x14 }, + { PCA9450_BUCK1CTRL, 0x59 }, + /* + * Kernel uses OD/OD freq for SOC + * To avoid timing risk from SOC to ARM,increase VDD_ARM to OD + * voltage 0.95v + */ + { PCA9450_BUCK2OUT_DVS0, 0x1C }, + /* set WDOG_B_CFG to cold reset */ + { PCA9450_RESET_CTRL, 0xA1 }, +}; + +static void power_init_board(void) +{ + struct pbl_i2c *i2c; + + imx8mp_setup_pad(MX8MP_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL); + imx8mp_setup_pad(MX8MP_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL); + + imx8mm_early_clock_init(); + imx8m_ccgr_clock_enable(IMX8M_CCM_CCGR_I2C1); + + i2c = imx8m_i2c_early_init(IOMEM(MX8MP_I2C1_BASE_ADDR)); + + pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg)); +} + +static __noreturn noinline void tqma8mpxl_start(void) +{ + extern char __dtb_z_imx8mp_tqma8mpql_mba8mpxl_start[]; + + setup_uart(); + + if (current_el() == 3) { + extern struct dram_timing_info dram_timing_2gb_no_ecc; + + power_init_board(); + + imx8mp_ddr_init(&dram_timing_2gb_no_ecc, DRAM_TYPE_LPDDR4); + + imx8mp_load_and_start_image_via_tfa(); + } + + imx8mp_barebox_entry(__dtb_z_imx8mp_tqma8mpql_mba8mpxl_start); +} + +ENTRY_FUNCTION(start_tqma8mpxl, x0, x1, x2) +{ + imx8mp_cpu_lowlevel_init(); + + relocate_to_current_adr(); + setup_c(); + + tqma8mpxl_start(); +} diff --git a/arch/arm/boards/tqma8mpxl/lpddr4-timing.c b/arch/arm/boards/tqma8mpxl/lpddr4-timing.c new file mode 100644 index 0000000000..ef14c4cf46 --- /dev/null +++ b/arch/arm/boards/tqma8mpxl/lpddr4-timing.c @@ -0,0 +1,1856 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2019 NXP + * + * Generated code from MX8M_DDR_tool + * + * Align with uboot version: + * imx_v2019.04_5.4.x and above version + * For imx_v2018.03_4.14.78_1.0.0_ga ~ imx_v2018.04_4.19.35_1.1.0_ga: + * please replace #include with #include + * + * TQMa8MPxL.2GByte.RAM-Timing.0004.xlsx / 2.0 GHz + */ + +#include +#include +#include + +static struct dram_cfg_param ddr_ddrc_cfg[] = { + /** Initialize DDRC registers **/ + { 0x3d400304, 0x1 }, + { 0x3d400030, 0x1 }, + { 0x3d400000, 0xa1080020 }, + { 0x3d400020, 0x1303 }, + { 0x3d400024, 0x1e84800 }, + { 0x3d400064, 0x7a0118 }, + { 0x3d400070, 0x7027f90 }, + { 0x3d400074, 0x790 }, + { 0x3d4000d0, 0xc00307a3 }, + { 0x3d4000d4, 0xc50000 }, + { 0x3d4000dc, 0xf4003f }, + { 0x3d4000e0, 0x2b0000 }, + { 0x3d4000e8, 0x550048 }, + { 0x3d4000ec, 0x150048 }, + { 0x3d400100, 0x201e222a }, + { 0x3d400104, 0x8083f }, + { 0x3d40010c, 0xe0e000 }, + { 0x3d400110, 0x12040a12 }, + { 0x3d400114, 0x2050f0f }, + { 0x3d400118, 0x1010009 }, + { 0x3d40011c, 0x501 }, + { 0x3d400130, 0x20800 }, + { 0x3d400134, 0xe100002 }, + { 0x3d400138, 0x120 }, + { 0x3d400144, 0xc80064 }, + { 0x3d400180, 0x3e8001e }, + { 0x3d400184, 0x3207a12 }, + { 0x3d400188, 0x0 }, + { 0x3d400190, 0x49f820e }, + { 0x3d400194, 0x80303 }, + { 0x3d4001b4, 0x1f0e }, + { 0x3d4001a0, 0xe0400018 }, + { 0x3d4001a4, 0xdf00e4 }, + { 0x3d4001a8, 0x80000000 }, + { 0x3d4001b0, 0x11 }, + { 0x3d4001c0, 0x1 }, + { 0x3d4001c4, 0x1 }, + { 0x3d4000f4, 0xc99 }, + { 0x3d400108, 0x9121c1c }, + { 0x3d400200, 0x1f }, + { 0x3d40020c, 0x0 }, + { 0x3d400210, 0x1f1f }, + { 0x3d400204, 0x80808 }, + { 0x3d400214, 0x7070707 }, + { 0x3d400218, 0x7070707 }, + { 0x3d40021c, 0xf0f }, + { 0x3d400250, 0x1705 }, + { 0x3d400254, 0x2c }, + { 0x3d40025c, 0x4000030 }, + { 0x3d400264, 0x900093e7 }, + { 0x3d40026c, 0x2005574 }, + { 0x3d400400, 0x111 }, + { 0x3d400404, 0x72ff }, + { 0x3d400408, 0x72ff }, + { 0x3d400494, 0x2100e07 }, + { 0x3d400498, 0x620096 }, + { 0x3d40049c, 0x1100e07 }, + { 0x3d4004a0, 0xc8012c }, + { 0x3d402020, 0x1001 }, + { 0x3d402024, 0x30d400 }, + { 0x3d402050, 0x20d000 }, + { 0x3d402064, 0xc001c }, + { 0x3d4020dc, 0x840000 }, + { 0x3d4020e0, 0x2b0000 }, + { 0x3d4020e8, 0x550048 }, + { 0x3d4020ec, 0x150048 }, + { 0x3d402100, 0xa030305 }, + { 0x3d402104, 0x30407 }, + { 0x3d402108, 0x203060b }, + { 0x3d40210c, 0x505000 }, + { 0x3d402110, 0x2040202 }, + { 0x3d402114, 0x2030202 }, + { 0x3d402118, 0x1010004 }, + { 0x3d40211c, 0x301 }, + { 0x3d402130, 0x20300 }, + { 0x3d402134, 0xa100002 }, + { 0x3d402138, 0x1d }, + { 0x3d402144, 0x14000a }, + { 0x3d402180, 0x640004 }, + { 0x3d402190, 0x3818200 }, + { 0x3d402194, 0x80303 }, + { 0x3d4021b4, 0x100 }, + { 0x3d4020f4, 0xc99 }, + { 0x3d403020, 0x1001 }, + { 0x3d403024, 0xc3500 }, + { 0x3d403050, 0x20d000 }, + { 0x3d403064, 0x30007 }, + { 0x3d4030dc, 0x840000 }, + { 0x3d4030e0, 0x2b0000 }, + { 0x3d4030e8, 0x550048 }, + { 0x3d4030ec, 0x150048 }, + { 0x3d403100, 0xa010102 }, + { 0x3d403104, 0x30404 }, + { 0x3d403108, 0x203060b }, + { 0x3d40310c, 0x505000 }, + { 0x3d403110, 0x2040202 }, + { 0x3d403114, 0x2030202 }, + { 0x3d403118, 0x1010004 }, + { 0x3d40311c, 0x301 }, + { 0x3d403130, 0x20300 }, + { 0x3d403134, 0xa100002 }, + { 0x3d403138, 0x8 }, + { 0x3d403144, 0x50003 }, + { 0x3d403180, 0x190004 }, + { 0x3d403190, 0x3818200 }, + { 0x3d403194, 0x80303 }, + { 0x3d4031b4, 0x100 }, + { 0x3d4030f4, 0xc99 }, + { 0x3d400028, 0x0 }, +}; + +/* PHY Initialize Configuration */ +static struct dram_cfg_param ddr_ddrphy_cfg[] = { + { 0x100a0, 0x0 }, + { 0x100a1, 0x1 }, + { 0x100a2, 0x2 }, + { 0x100a3, 0x3 }, + { 0x100a4, 0x4 }, + { 0x100a5, 0x6 }, + { 0x100a6, 0x7 }, + { 0x100a7, 0x5 }, + { 0x110a0, 0x6 }, + { 0x110a1, 0x0 }, + { 0x110a2, 0x2 }, + { 0x110a3, 0x3 }, + { 0x110a4, 0x4 }, + { 0x110a5, 0x5 }, + { 0x110a6, 0x1 }, + { 0x110a7, 0x7 }, + { 0x120a0, 0x0 }, + { 0x120a1, 0x6 }, + { 0x120a2, 0x4 }, + { 0x120a3, 0x3 }, + { 0x120a4, 0x5 }, + { 0x120a5, 0x2 }, + { 0x120a6, 0x1 }, + { 0x120a7, 0x7 }, + { 0x130a0, 0x0 }, + { 0x130a1, 0x1 }, + { 0x130a2, 0x5 }, + { 0x130a3, 0x4 }, + { 0x130a4, 0x3 }, + { 0x130a5, 0x2 }, + { 0x130a6, 0x6 }, + { 0x130a7, 0x7 }, + { 0x1005f, 0x1ff }, + { 0x1015f, 0x1ff }, + { 0x1105f, 0x1ff }, + { 0x1115f, 0x1ff }, + { 0x1205f, 0x1ff }, + { 0x1215f, 0x1ff }, + { 0x1305f, 0x1ff }, + { 0x1315f, 0x1ff }, + { 0x11005f, 0x1ff }, + { 0x11015f, 0x1ff }, + { 0x11105f, 0x1ff }, + { 0x11115f, 0x1ff }, + { 0x11205f, 0x1ff }, + { 0x11215f, 0x1ff }, + { 0x11305f, 0x1ff }, + { 0x11315f, 0x1ff }, + { 0x21005f, 0x1ff }, + { 0x21015f, 0x1ff }, + { 0x21105f, 0x1ff }, + { 0x21115f, 0x1ff }, + { 0x21205f, 0x1ff }, + { 0x21215f, 0x1ff }, + { 0x21305f, 0x1ff }, + { 0x21315f, 0x1ff }, + { 0x55, 0x1ff }, + { 0x1055, 0x1ff }, + { 0x2055, 0x1ff }, + { 0x3055, 0x1ff }, + { 0x4055, 0x1ff }, + { 0x5055, 0x1ff }, + { 0x6055, 0x1ff }, + { 0x7055, 0x1ff }, + { 0x8055, 0x1ff }, + { 0x9055, 0x1ff }, + { 0x200c5, 0x18 }, + { 0x1200c5, 0x7 }, + { 0x2200c5, 0x7 }, + { 0x2002e, 0x2 }, + { 0x12002e, 0x2 }, + { 0x22002e, 0x2 }, + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + { 0x290204, 0x0 }, + { 0x20024, 0x1e3 }, + { 0x2003a, 0x2 }, + { 0x120024, 0x1e3 }, + { 0x2003a, 0x2 }, + { 0x220024, 0x1e3 }, + { 0x2003a, 0x2 }, + { 0x20056, 0x3 }, + { 0x120056, 0x3 }, + { 0x220056, 0x3 }, + { 0x1004d, 0x600 }, + { 0x1014d, 0x600 }, + { 0x1104d, 0x600 }, + { 0x1114d, 0x600 }, + { 0x1204d, 0x600 }, + { 0x1214d, 0x600 }, + { 0x1304d, 0x600 }, + { 0x1314d, 0x600 }, + { 0x11004d, 0x600 }, + { 0x11014d, 0x600 }, + { 0x11104d, 0x600 }, + { 0x11114d, 0x600 }, + { 0x11204d, 0x600 }, + { 0x11214d, 0x600 }, + { 0x11304d, 0x600 }, + { 0x11314d, 0x600 }, + { 0x21004d, 0x600 }, + { 0x21014d, 0x600 }, + { 0x21104d, 0x600 }, + { 0x21114d, 0x600 }, + { 0x21204d, 0x600 }, + { 0x21214d, 0x600 }, + { 0x21304d, 0x600 }, + { 0x21314d, 0x600 }, + { 0x10049, 0x69a }, + { 0x10149, 0x69a }, + { 0x11049, 0x69a }, + { 0x11149, 0x69a }, + { 0x12049, 0x69a }, + { 0x12149, 0x69a }, + { 0x13049, 0x69a }, + { 0x13149, 0x69a }, + { 0x110049, 0x69a }, + { 0x110149, 0x69a }, + { 0x111049, 0x69a }, + { 0x111149, 0x69a }, + { 0x112049, 0x69a }, + { 0x112149, 0x69a }, + { 0x113049, 0x69a }, + { 0x113149, 0x69a }, + { 0x210049, 0x69a }, + { 0x210149, 0x69a }, + { 0x211049, 0x69a }, + { 0x211149, 0x69a }, + { 0x212049, 0x69a }, + { 0x212149, 0x69a }, + { 0x213049, 0x69a }, + { 0x213149, 0x69a }, + { 0x43, 0x21 }, + { 0x1043, 0x21 }, + { 0x2043, 0x21 }, + { 0x3043, 0x21 }, + { 0x4043, 0x21 }, + { 0x5043, 0x21 }, + { 0x6043, 0x21 }, + { 0x7043, 0x21 }, + { 0x8043, 0x21 }, + { 0x9043, 0x21 }, + { 0x20018, 0x3 }, + { 0x20075, 0x4 }, + { 0x20050, 0x0 }, + { 0x20008, 0x3e8 }, + { 0x120008, 0x64 }, + { 0x220008, 0x19 }, + { 0x20088, 0x9 }, + { 0x200b2, 0x104 }, + { 0x10043, 0x5a1 }, + { 0x10143, 0x5a1 }, + { 0x11043, 0x5a1 }, + { 0x11143, 0x5a1 }, + { 0x12043, 0x5a1 }, + { 0x12143, 0x5a1 }, + { 0x13043, 0x5a1 }, + { 0x13143, 0x5a1 }, + { 0x1200b2, 0x104 }, + { 0x110043, 0x5a1 }, + { 0x110143, 0x5a1 }, + { 0x111043, 0x5a1 }, + { 0x111143, 0x5a1 }, + { 0x112043, 0x5a1 }, + { 0x112143, 0x5a1 }, + { 0x113043, 0x5a1 }, + { 0x113143, 0x5a1 }, + { 0x2200b2, 0x104 }, + { 0x210043, 0x5a1 }, + { 0x210143, 0x5a1 }, + { 0x211043, 0x5a1 }, + { 0x211143, 0x5a1 }, + { 0x212043, 0x5a1 }, + { 0x212143, 0x5a1 }, + { 0x213043, 0x5a1 }, + { 0x213143, 0x5a1 }, + { 0x200fa, 0x1 }, + { 0x1200fa, 0x1 }, + { 0x2200fa, 0x1 }, + { 0x20019, 0x1 }, + { 0x120019, 0x1 }, + { 0x220019, 0x1 }, + { 0x200f0, 0x660 }, + { 0x200f1, 0x0 }, + { 0x200f2, 0x4444 }, + { 0x200f3, 0x8888 }, + { 0x200f4, 0x5665 }, + { 0x200f5, 0x0 }, + { 0x200f6, 0x0 }, + { 0x200f7, 0xf000 }, + { 0x20025, 0x0 }, + { 0x2002d, 0x0 }, + { 0x12002d, 0x0 }, + { 0x22002d, 0x0 }, + { 0x2007d, 0x212 }, + { 0x12007d, 0x212 }, + { 0x22007d, 0x212 }, + { 0x2007c, 0x61 }, + { 0x12007c, 0x61 }, + { 0x22007c, 0x61 }, + { 0x1004a, 0x500 }, + { 0x1104a, 0x500 }, + { 0x1204a, 0x500 }, + { 0x1304a, 0x500 }, + { 0x2002c, 0x0 }, +}; + +/* ddr phy trained csr */ +static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { + { 0x200b2, 0x0 }, + { 0x1200b2, 0x0 }, + { 0x2200b2, 0x0 }, + { 0x200cb, 0x0 }, + { 0x10043, 0x0 }, + { 0x110043, 0x0 }, + { 0x210043, 0x0 }, + { 0x10143, 0x0 }, + { 0x110143, 0x0 }, + { 0x210143, 0x0 }, + { 0x11043, 0x0 }, + { 0x111043, 0x0 }, + { 0x211043, 0x0 }, + { 0x11143, 0x0 }, + { 0x111143, 0x0 }, + { 0x211143, 0x0 }, + { 0x12043, 0x0 }, + { 0x112043, 0x0 }, + { 0x212043, 0x0 }, + { 0x12143, 0x0 }, + { 0x112143, 0x0 }, + { 0x212143, 0x0 }, + { 0x13043, 0x0 }, + { 0x113043, 0x0 }, + { 0x213043, 0x0 }, + { 0x13143, 0x0 }, + { 0x113143, 0x0 }, + { 0x213143, 0x0 }, + { 0x80, 0x0 }, + { 0x100080, 0x0 }, + { 0x200080, 0x0 }, + { 0x1080, 0x0 }, + { 0x101080, 0x0 }, + { 0x201080, 0x0 }, + { 0x2080, 0x0 }, + { 0x102080, 0x0 }, + { 0x202080, 0x0 }, + { 0x3080, 0x0 }, + { 0x103080, 0x0 }, + { 0x203080, 0x0 }, + { 0x4080, 0x0 }, + { 0x104080, 0x0 }, + { 0x204080, 0x0 }, + { 0x5080, 0x0 }, + { 0x105080, 0x0 }, + { 0x205080, 0x0 }, + { 0x6080, 0x0 }, + { 0x106080, 0x0 }, + { 0x206080, 0x0 }, + { 0x7080, 0x0 }, + { 0x107080, 0x0 }, + { 0x207080, 0x0 }, + { 0x8080, 0x0 }, + { 0x108080, 0x0 }, + { 0x208080, 0x0 }, + { 0x9080, 0x0 }, + { 0x109080, 0x0 }, + { 0x209080, 0x0 }, + { 0x10080, 0x0 }, + { 0x110080, 0x0 }, + { 0x210080, 0x0 }, + { 0x10180, 0x0 }, + { 0x110180, 0x0 }, + { 0x210180, 0x0 }, + { 0x11080, 0x0 }, + { 0x111080, 0x0 }, + { 0x211080, 0x0 }, + { 0x11180, 0x0 }, + { 0x111180, 0x0 }, + { 0x211180, 0x0 }, + { 0x12080, 0x0 }, + { 0x112080, 0x0 }, + { 0x212080, 0x0 }, + { 0x12180, 0x0 }, + { 0x112180, 0x0 }, + { 0x212180, 0x0 }, + { 0x13080, 0x0 }, + { 0x113080, 0x0 }, + { 0x213080, 0x0 }, + { 0x13180, 0x0 }, + { 0x113180, 0x0 }, + { 0x213180, 0x0 }, + { 0x10081, 0x0 }, + { 0x110081, 0x0 }, + { 0x210081, 0x0 }, + { 0x10181, 0x0 }, + { 0x110181, 0x0 }, + { 0x210181, 0x0 }, + { 0x11081, 0x0 }, + { 0x111081, 0x0 }, + { 0x211081, 0x0 }, + { 0x11181, 0x0 }, + { 0x111181, 0x0 }, + { 0x211181, 0x0 }, + { 0x12081, 0x0 }, + { 0x112081, 0x0 }, + { 0x212081, 0x0 }, + { 0x12181, 0x0 }, + { 0x112181, 0x0 }, + { 0x212181, 0x0 }, + { 0x13081, 0x0 }, + { 0x113081, 0x0 }, + { 0x213081, 0x0 }, + { 0x13181, 0x0 }, + { 0x113181, 0x0 }, + { 0x213181, 0x0 }, + { 0x100d0, 0x0 }, + { 0x1100d0, 0x0 }, + { 0x2100d0, 0x0 }, + { 0x101d0, 0x0 }, + { 0x1101d0, 0x0 }, + { 0x2101d0, 0x0 }, + { 0x110d0, 0x0 }, + { 0x1110d0, 0x0 }, + { 0x2110d0, 0x0 }, + { 0x111d0, 0x0 }, + { 0x1111d0, 0x0 }, + { 0x2111d0, 0x0 }, + { 0x120d0, 0x0 }, + { 0x1120d0, 0x0 }, + { 0x2120d0, 0x0 }, + { 0x121d0, 0x0 }, + { 0x1121d0, 0x0 }, + { 0x2121d0, 0x0 }, + { 0x130d0, 0x0 }, + { 0x1130d0, 0x0 }, + { 0x2130d0, 0x0 }, + { 0x131d0, 0x0 }, + { 0x1131d0, 0x0 }, + { 0x2131d0, 0x0 }, + { 0x100d1, 0x0 }, + { 0x1100d1, 0x0 }, + { 0x2100d1, 0x0 }, + { 0x101d1, 0x0 }, + { 0x1101d1, 0x0 }, + { 0x2101d1, 0x0 }, + { 0x110d1, 0x0 }, + { 0x1110d1, 0x0 }, + { 0x2110d1, 0x0 }, + { 0x111d1, 0x0 }, + { 0x1111d1, 0x0 }, + { 0x2111d1, 0x0 }, + { 0x120d1, 0x0 }, + { 0x1120d1, 0x0 }, + { 0x2120d1, 0x0 }, + { 0x121d1, 0x0 }, + { 0x1121d1, 0x0 }, + { 0x2121d1, 0x0 }, + { 0x130d1, 0x0 }, + { 0x1130d1, 0x0 }, + { 0x2130d1, 0x0 }, + { 0x131d1, 0x0 }, + { 0x1131d1, 0x0 }, + { 0x2131d1, 0x0 }, + { 0x10068, 0x0 }, + { 0x10168, 0x0 }, + { 0x10268, 0x0 }, + { 0x10368, 0x0 }, + { 0x10468, 0x0 }, + { 0x10568, 0x0 }, + { 0x10668, 0x0 }, + { 0x10768, 0x0 }, + { 0x10868, 0x0 }, + { 0x11068, 0x0 }, + { 0x11168, 0x0 }, + { 0x11268, 0x0 }, + { 0x11368, 0x0 }, + { 0x11468, 0x0 }, + { 0x11568, 0x0 }, + { 0x11668, 0x0 }, + { 0x11768, 0x0 }, + { 0x11868, 0x0 }, + { 0x12068, 0x0 }, + { 0x12168, 0x0 }, + { 0x12268, 0x0 }, + { 0x12368, 0x0 }, + { 0x12468, 0x0 }, + { 0x12568, 0x0 }, + { 0x12668, 0x0 }, + { 0x12768, 0x0 }, + { 0x12868, 0x0 }, + { 0x13068, 0x0 }, + { 0x13168, 0x0 }, + { 0x13268, 0x0 }, + { 0x13368, 0x0 }, + { 0x13468, 0x0 }, + { 0x13568, 0x0 }, + { 0x13668, 0x0 }, + { 0x13768, 0x0 }, + { 0x13868, 0x0 }, + { 0x10069, 0x0 }, + { 0x10169, 0x0 }, + { 0x10269, 0x0 }, + { 0x10369, 0x0 }, + { 0x10469, 0x0 }, + { 0x10569, 0x0 }, + { 0x10669, 0x0 }, + { 0x10769, 0x0 }, + { 0x10869, 0x0 }, + { 0x11069, 0x0 }, + { 0x11169, 0x0 }, + { 0x11269, 0x0 }, + { 0x11369, 0x0 }, + { 0x11469, 0x0 }, + { 0x11569, 0x0 }, + { 0x11669, 0x0 }, + { 0x11769, 0x0 }, + { 0x11869, 0x0 }, + { 0x12069, 0x0 }, + { 0x12169, 0x0 }, + { 0x12269, 0x0 }, + { 0x12369, 0x0 }, + { 0x12469, 0x0 }, + { 0x12569, 0x0 }, + { 0x12669, 0x0 }, + { 0x12769, 0x0 }, + { 0x12869, 0x0 }, + { 0x13069, 0x0 }, + { 0x13169, 0x0 }, + { 0x13269, 0x0 }, + { 0x13369, 0x0 }, + { 0x13469, 0x0 }, + { 0x13569, 0x0 }, + { 0x13669, 0x0 }, + { 0x13769, 0x0 }, + { 0x13869, 0x0 }, + { 0x1008c, 0x0 }, + { 0x11008c, 0x0 }, + { 0x21008c, 0x0 }, + { 0x1018c, 0x0 }, + { 0x11018c, 0x0 }, + { 0x21018c, 0x0 }, + { 0x1108c, 0x0 }, + { 0x11108c, 0x0 }, + { 0x21108c, 0x0 }, + { 0x1118c, 0x0 }, + { 0x11118c, 0x0 }, + { 0x21118c, 0x0 }, + { 0x1208c, 0x0 }, + { 0x11208c, 0x0 }, + { 0x21208c, 0x0 }, + { 0x1218c, 0x0 }, + { 0x11218c, 0x0 }, + { 0x21218c, 0x0 }, + { 0x1308c, 0x0 }, + { 0x11308c, 0x0 }, + { 0x21308c, 0x0 }, + { 0x1318c, 0x0 }, + { 0x11318c, 0x0 }, + { 0x21318c, 0x0 }, + { 0x1008d, 0x0 }, + { 0x11008d, 0x0 }, + { 0x21008d, 0x0 }, + { 0x1018d, 0x0 }, + { 0x11018d, 0x0 }, + { 0x21018d, 0x0 }, + { 0x1108d, 0x0 }, + { 0x11108d, 0x0 }, + { 0x21108d, 0x0 }, + { 0x1118d, 0x0 }, + { 0x11118d, 0x0 }, + { 0x21118d, 0x0 }, + { 0x1208d, 0x0 }, + { 0x11208d, 0x0 }, + { 0x21208d, 0x0 }, + { 0x1218d, 0x0 }, + { 0x11218d, 0x0 }, + { 0x21218d, 0x0 }, + { 0x1308d, 0x0 }, + { 0x11308d, 0x0 }, + { 0x21308d, 0x0 }, + { 0x1318d, 0x0 }, + { 0x11318d, 0x0 }, + { 0x21318d, 0x0 }, + { 0x100c0, 0x0 }, + { 0x1100c0, 0x0 }, + { 0x2100c0, 0x0 }, + { 0x101c0, 0x0 }, + { 0x1101c0, 0x0 }, + { 0x2101c0, 0x0 }, + { 0x102c0, 0x0 }, + { 0x1102c0, 0x0 }, + { 0x2102c0, 0x0 }, + { 0x103c0, 0x0 }, + { 0x1103c0, 0x0 }, + { 0x2103c0, 0x0 }, + { 0x104c0, 0x0 }, + { 0x1104c0, 0x0 }, + { 0x2104c0, 0x0 }, + { 0x105c0, 0x0 }, + { 0x1105c0, 0x0 }, + { 0x2105c0, 0x0 }, + { 0x106c0, 0x0 }, + { 0x1106c0, 0x0 }, + { 0x2106c0, 0x0 }, + { 0x107c0, 0x0 }, + { 0x1107c0, 0x0 }, + { 0x2107c0, 0x0 }, + { 0x108c0, 0x0 }, + { 0x1108c0, 0x0 }, + { 0x2108c0, 0x0 }, + { 0x110c0, 0x0 }, + { 0x1110c0, 0x0 }, + { 0x2110c0, 0x0 }, + { 0x111c0, 0x0 }, + { 0x1111c0, 0x0 }, + { 0x2111c0, 0x0 }, + { 0x112c0, 0x0 }, + { 0x1112c0, 0x0 }, + { 0x2112c0, 0x0 }, + { 0x113c0, 0x0 }, + { 0x1113c0, 0x0 }, + { 0x2113c0, 0x0 }, + { 0x114c0, 0x0 }, + { 0x1114c0, 0x0 }, + { 0x2114c0, 0x0 }, + { 0x115c0, 0x0 }, + { 0x1115c0, 0x0 }, + { 0x2115c0, 0x0 }, + { 0x116c0, 0x0 }, + { 0x1116c0, 0x0 }, + { 0x2116c0, 0x0 }, + { 0x117c0, 0x0 }, + { 0x1117c0, 0x0 }, + { 0x2117c0, 0x0 }, + { 0x118c0, 0x0 }, + { 0x1118c0, 0x0 }, + { 0x2118c0, 0x0 }, + { 0x120c0, 0x0 }, + { 0x1120c0, 0x0 }, + { 0x2120c0, 0x0 }, + { 0x121c0, 0x0 }, + { 0x1121c0, 0x0 }, + { 0x2121c0, 0x0 }, + { 0x122c0, 0x0 }, + { 0x1122c0, 0x0 }, + { 0x2122c0, 0x0 }, + { 0x123c0, 0x0 }, + { 0x1123c0, 0x0 }, + { 0x2123c0, 0x0 }, + { 0x124c0, 0x0 }, + { 0x1124c0, 0x0 }, + { 0x2124c0, 0x0 }, + { 0x125c0, 0x0 }, + { 0x1125c0, 0x0 }, + { 0x2125c0, 0x0 }, + { 0x126c0, 0x0 }, + { 0x1126c0, 0x0 }, + { 0x2126c0, 0x0 }, + { 0x127c0, 0x0 }, + { 0x1127c0, 0x0 }, + { 0x2127c0, 0x0 }, + { 0x128c0, 0x0 }, + { 0x1128c0, 0x0 }, + { 0x2128c0, 0x0 }, + { 0x130c0, 0x0 }, + { 0x1130c0, 0x0 }, + { 0x2130c0, 0x0 }, + { 0x131c0, 0x0 }, + { 0x1131c0, 0x0 }, + { 0x2131c0, 0x0 }, + { 0x132c0, 0x0 }, + { 0x1132c0, 0x0 }, + { 0x2132c0, 0x0 }, + { 0x133c0, 0x0 }, + { 0x1133c0, 0x0 }, + { 0x2133c0, 0x0 }, + { 0x134c0, 0x0 }, + { 0x1134c0, 0x0 }, + { 0x2134c0, 0x0 }, + { 0x135c0, 0x0 }, + { 0x1135c0, 0x0 }, + { 0x2135c0, 0x0 }, + { 0x136c0, 0x0 }, + { 0x1136c0, 0x0 }, + { 0x2136c0, 0x0 }, + { 0x137c0, 0x0 }, + { 0x1137c0, 0x0 }, + { 0x2137c0, 0x0 }, + { 0x138c0, 0x0 }, + { 0x1138c0, 0x0 }, + { 0x2138c0, 0x0 }, + { 0x100c1, 0x0 }, + { 0x1100c1, 0x0 }, + { 0x2100c1, 0x0 }, + { 0x101c1, 0x0 }, + { 0x1101c1, 0x0 }, + { 0x2101c1, 0x0 }, + { 0x102c1, 0x0 }, + { 0x1102c1, 0x0 }, + { 0x2102c1, 0x0 }, + { 0x103c1, 0x0 }, + { 0x1103c1, 0x0 }, + { 0x2103c1, 0x0 }, + { 0x104c1, 0x0 }, + { 0x1104c1, 0x0 }, + { 0x2104c1, 0x0 }, + { 0x105c1, 0x0 }, + { 0x1105c1, 0x0 }, + { 0x2105c1, 0x0 }, + { 0x106c1, 0x0 }, + { 0x1106c1, 0x0 }, + { 0x2106c1, 0x0 }, + { 0x107c1, 0x0 }, + { 0x1107c1, 0x0 }, + { 0x2107c1, 0x0 }, + { 0x108c1, 0x0 }, + { 0x1108c1, 0x0 }, + { 0x2108c1, 0x0 }, + { 0x110c1, 0x0 }, + { 0x1110c1, 0x0 }, + { 0x2110c1, 0x0 }, + { 0x111c1, 0x0 }, + { 0x1111c1, 0x0 }, + { 0x2111c1, 0x0 }, + { 0x112c1, 0x0 }, + { 0x1112c1, 0x0 }, + { 0x2112c1, 0x0 }, + { 0x113c1, 0x0 }, + { 0x1113c1, 0x0 }, + { 0x2113c1, 0x0 }, + { 0x114c1, 0x0 }, + { 0x1114c1, 0x0 }, + { 0x2114c1, 0x0 }, + { 0x115c1, 0x0 }, + { 0x1115c1, 0x0 }, + { 0x2115c1, 0x0 }, + { 0x116c1, 0x0 }, + { 0x1116c1, 0x0 }, + { 0x2116c1, 0x0 }, + { 0x117c1, 0x0 }, + { 0x1117c1, 0x0 }, + { 0x2117c1, 0x0 }, + { 0x118c1, 0x0 }, + { 0x1118c1, 0x0 }, + { 0x2118c1, 0x0 }, + { 0x120c1, 0x0 }, + { 0x1120c1, 0x0 }, + { 0x2120c1, 0x0 }, + { 0x121c1, 0x0 }, + { 0x1121c1, 0x0 }, + { 0x2121c1, 0x0 }, + { 0x122c1, 0x0 }, + { 0x1122c1, 0x0 }, + { 0x2122c1, 0x0 }, + { 0x123c1, 0x0 }, + { 0x1123c1, 0x0 }, + { 0x2123c1, 0x0 }, + { 0x124c1, 0x0 }, + { 0x1124c1, 0x0 }, + { 0x2124c1, 0x0 }, + { 0x125c1, 0x0 }, + { 0x1125c1, 0x0 }, + { 0x2125c1, 0x0 }, + { 0x126c1, 0x0 }, + { 0x1126c1, 0x0 }, + { 0x2126c1, 0x0 }, + { 0x127c1, 0x0 }, + { 0x1127c1, 0x0 }, + { 0x2127c1, 0x0 }, + { 0x128c1, 0x0 }, + { 0x1128c1, 0x0 }, + { 0x2128c1, 0x0 }, + { 0x130c1, 0x0 }, + { 0x1130c1, 0x0 }, + { 0x2130c1, 0x0 }, + { 0x131c1, 0x0 }, + { 0x1131c1, 0x0 }, + { 0x2131c1, 0x0 }, + { 0x132c1, 0x0 }, + { 0x1132c1, 0x0 }, + { 0x2132c1, 0x0 }, + { 0x133c1, 0x0 }, + { 0x1133c1, 0x0 }, + { 0x2133c1, 0x0 }, + { 0x134c1, 0x0 }, + { 0x1134c1, 0x0 }, + { 0x2134c1, 0x0 }, + { 0x135c1, 0x0 }, + { 0x1135c1, 0x0 }, + { 0x2135c1, 0x0 }, + { 0x136c1, 0x0 }, + { 0x1136c1, 0x0 }, + { 0x2136c1, 0x0 }, + { 0x137c1, 0x0 }, + { 0x1137c1, 0x0 }, + { 0x2137c1, 0x0 }, + { 0x138c1, 0x0 }, + { 0x1138c1, 0x0 }, + { 0x2138c1, 0x0 }, + { 0x10020, 0x0 }, + { 0x110020, 0x0 }, + { 0x210020, 0x0 }, + { 0x11020, 0x0 }, + { 0x111020, 0x0 }, + { 0x211020, 0x0 }, + { 0x12020, 0x0 }, + { 0x112020, 0x0 }, + { 0x212020, 0x0 }, + { 0x13020, 0x0 }, + { 0x113020, 0x0 }, + { 0x213020, 0x0 }, + { 0x20072, 0x0 }, + { 0x20073, 0x0 }, + { 0x20074, 0x0 }, + { 0x100aa, 0x0 }, + { 0x110aa, 0x0 }, + { 0x120aa, 0x0 }, + { 0x130aa, 0x0 }, + { 0x20010, 0x0 }, + { 0x120010, 0x0 }, + { 0x220010, 0x0 }, + { 0x20011, 0x0 }, + { 0x120011, 0x0 }, + { 0x220011, 0x0 }, + { 0x100ae, 0x0 }, + { 0x1100ae, 0x0 }, + { 0x2100ae, 0x0 }, + { 0x100af, 0x0 }, + { 0x1100af, 0x0 }, + { 0x2100af, 0x0 }, + { 0x110ae, 0x0 }, + { 0x1110ae, 0x0 }, + { 0x2110ae, 0x0 }, + { 0x110af, 0x0 }, + { 0x1110af, 0x0 }, + { 0x2110af, 0x0 }, + { 0x120ae, 0x0 }, + { 0x1120ae, 0x0 }, + { 0x2120ae, 0x0 }, + { 0x120af, 0x0 }, + { 0x1120af, 0x0 }, + { 0x2120af, 0x0 }, + { 0x130ae, 0x0 }, + { 0x1130ae, 0x0 }, + { 0x2130ae, 0x0 }, + { 0x130af, 0x0 }, + { 0x1130af, 0x0 }, + { 0x2130af, 0x0 }, + { 0x20020, 0x0 }, + { 0x120020, 0x0 }, + { 0x220020, 0x0 }, + { 0x100a0, 0x0 }, + { 0x100a1, 0x0 }, + { 0x100a2, 0x0 }, + { 0x100a3, 0x0 }, + { 0x100a4, 0x0 }, + { 0x100a5, 0x0 }, + { 0x100a6, 0x0 }, + { 0x100a7, 0x0 }, + { 0x110a0, 0x0 }, + { 0x110a1, 0x0 }, + { 0x110a2, 0x0 }, + { 0x110a3, 0x0 }, + { 0x110a4, 0x0 }, + { 0x110a5, 0x0 }, + { 0x110a6, 0x0 }, + { 0x110a7, 0x0 }, + { 0x120a0, 0x0 }, + { 0x120a1, 0x0 }, + { 0x120a2, 0x0 }, + { 0x120a3, 0x0 }, + { 0x120a4, 0x0 }, + { 0x120a5, 0x0 }, + { 0x120a6, 0x0 }, + { 0x120a7, 0x0 }, + { 0x130a0, 0x0 }, + { 0x130a1, 0x0 }, + { 0x130a2, 0x0 }, + { 0x130a3, 0x0 }, + { 0x130a4, 0x0 }, + { 0x130a5, 0x0 }, + { 0x130a6, 0x0 }, + { 0x130a7, 0x0 }, + { 0x2007c, 0x0 }, + { 0x12007c, 0x0 }, + { 0x22007c, 0x0 }, + { 0x2007d, 0x0 }, + { 0x12007d, 0x0 }, + { 0x22007d, 0x0 }, + { 0x400fd, 0x0 }, + { 0x400c0, 0x0 }, + { 0x90201, 0x0 }, + { 0x190201, 0x0 }, + { 0x290201, 0x0 }, + { 0x90202, 0x0 }, + { 0x190202, 0x0 }, + { 0x290202, 0x0 }, + { 0x90203, 0x0 }, + { 0x190203, 0x0 }, + { 0x290203, 0x0 }, + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + { 0x290204, 0x0 }, + { 0x90205, 0x0 }, + { 0x190205, 0x0 }, + { 0x290205, 0x0 }, + { 0x90206, 0x0 }, + { 0x190206, 0x0 }, + { 0x290206, 0x0 }, + { 0x90207, 0x0 }, + { 0x190207, 0x0 }, + { 0x290207, 0x0 }, + { 0x90208, 0x0 }, + { 0x190208, 0x0 }, + { 0x290208, 0x0 }, + { 0x10062, 0x0 }, + { 0x10162, 0x0 }, + { 0x10262, 0x0 }, + { 0x10362, 0x0 }, + { 0x10462, 0x0 }, + { 0x10562, 0x0 }, + { 0x10662, 0x0 }, + { 0x10762, 0x0 }, + { 0x10862, 0x0 }, + { 0x11062, 0x0 }, + { 0x11162, 0x0 }, + { 0x11262, 0x0 }, + { 0x11362, 0x0 }, + { 0x11462, 0x0 }, + { 0x11562, 0x0 }, + { 0x11662, 0x0 }, + { 0x11762, 0x0 }, + { 0x11862, 0x0 }, + { 0x12062, 0x0 }, + { 0x12162, 0x0 }, + { 0x12262, 0x0 }, + { 0x12362, 0x0 }, + { 0x12462, 0x0 }, + { 0x12562, 0x0 }, + { 0x12662, 0x0 }, + { 0x12762, 0x0 }, + { 0x12862, 0x0 }, + { 0x13062, 0x0 }, + { 0x13162, 0x0 }, + { 0x13262, 0x0 }, + { 0x13362, 0x0 }, + { 0x13462, 0x0 }, + { 0x13562, 0x0 }, + { 0x13662, 0x0 }, + { 0x13762, 0x0 }, + { 0x13862, 0x0 }, + { 0x20077, 0x0 }, + { 0x10001, 0x0 }, + { 0x11001, 0x0 }, + { 0x12001, 0x0 }, + { 0x13001, 0x0 }, + { 0x10040, 0x0 }, + { 0x10140, 0x0 }, + { 0x10240, 0x0 }, + { 0x10340, 0x0 }, + { 0x10440, 0x0 }, + { 0x10540, 0x0 }, + { 0x10640, 0x0 }, + { 0x10740, 0x0 }, + { 0x10840, 0x0 }, + { 0x10030, 0x0 }, + { 0x10130, 0x0 }, + { 0x10230, 0x0 }, + { 0x10330, 0x0 }, + { 0x10430, 0x0 }, + { 0x10530, 0x0 }, + { 0x10630, 0x0 }, + { 0x10730, 0x0 }, + { 0x10830, 0x0 }, + { 0x11040, 0x0 }, + { 0x11140, 0x0 }, + { 0x11240, 0x0 }, + { 0x11340, 0x0 }, + { 0x11440, 0x0 }, + { 0x11540, 0x0 }, + { 0x11640, 0x0 }, + { 0x11740, 0x0 }, + { 0x11840, 0x0 }, + { 0x11030, 0x0 }, + { 0x11130, 0x0 }, + { 0x11230, 0x0 }, + { 0x11330, 0x0 }, + { 0x11430, 0x0 }, + { 0x11530, 0x0 }, + { 0x11630, 0x0 }, + { 0x11730, 0x0 }, + { 0x11830, 0x0 }, + { 0x12040, 0x0 }, + { 0x12140, 0x0 }, + { 0x12240, 0x0 }, + { 0x12340, 0x0 }, + { 0x12440, 0x0 }, + { 0x12540, 0x0 }, + { 0x12640, 0x0 }, + { 0x12740, 0x0 }, + { 0x12840, 0x0 }, + { 0x12030, 0x0 }, + { 0x12130, 0x0 }, + { 0x12230, 0x0 }, + { 0x12330, 0x0 }, + { 0x12430, 0x0 }, + { 0x12530, 0x0 }, + { 0x12630, 0x0 }, + { 0x12730, 0x0 }, + { 0x12830, 0x0 }, + { 0x13040, 0x0 }, + { 0x13140, 0x0 }, + { 0x13240, 0x0 }, + { 0x13340, 0x0 }, + { 0x13440, 0x0 }, + { 0x13540, 0x0 }, + { 0x13640, 0x0 }, + { 0x13740, 0x0 }, + { 0x13840, 0x0 }, + { 0x13030, 0x0 }, + { 0x13130, 0x0 }, + { 0x13230, 0x0 }, + { 0x13330, 0x0 }, + { 0x13430, 0x0 }, + { 0x13530, 0x0 }, + { 0x13630, 0x0 }, + { 0x13730, 0x0 }, + { 0x13830, 0x0 }, +}; + +/* P0 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp0_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54003, 0xfa0 }, + { 0x54004, 0x2 }, + { 0x54005, 0x303c }, + { 0x54006, 0x14 }, + { 0x54008, 0x131f }, + { 0x54009, 0xc8 }, + { 0x5400b, 0x2 }, + { 0x5400f, 0x100 }, + { 0x54012, 0x110 }, + { 0x54019, 0x3ff4 }, + { 0x5401a, 0x2b }, + { 0x5401b, 0x4855 }, + { 0x5401c, 0x4800 }, + { 0x5401e, 0x15 }, + { 0x5401f, 0x3ff4 }, + { 0x54020, 0x2b }, + { 0x54021, 0x4855 }, + { 0x54022, 0x4800 }, + { 0x54024, 0x15 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x1 }, + { 0x54032, 0xf400 }, + { 0x54033, 0x2b3f }, + { 0x54034, 0x5500 }, + { 0x54035, 0x48 }, + { 0x54036, 0x48 }, + { 0x54037, 0x1500 }, + { 0x54038, 0xf400 }, + { 0x54039, 0x2b3f }, + { 0x5403a, 0x5500 }, + { 0x5403b, 0x48 }, + { 0x5403c, 0x48 }, + { 0x5403d, 0x1500 }, + { 0xd0000, 0x1 }, +}; + +/* P1 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54002, 0x101 }, + { 0x54003, 0x190 }, + { 0x54004, 0x2 }, + { 0x54005, 0x303c }, + { 0x54006, 0x14 }, + { 0x54008, 0x121f }, + { 0x54009, 0xc8 }, + { 0x5400b, 0x2 }, + { 0x5400f, 0x100 }, + { 0x54012, 0x110 }, + { 0x54019, 0x84 }, + { 0x5401a, 0x2b }, + { 0x5401b, 0x4855 }, + { 0x5401c, 0x4800 }, + { 0x5401e, 0x15 }, + { 0x5401f, 0x84 }, + { 0x54020, 0x2b }, + { 0x54021, 0x4855 }, + { 0x54022, 0x4800 }, + { 0x54024, 0x15 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x1 }, + { 0x54032, 0x8400 }, + { 0x54033, 0x2b00 }, + { 0x54034, 0x5500 }, + { 0x54035, 0x48 }, + { 0x54036, 0x48 }, + { 0x54037, 0x1500 }, + { 0x54038, 0x8400 }, + { 0x54039, 0x2b00 }, + { 0x5403a, 0x5500 }, + { 0x5403b, 0x48 }, + { 0x5403c, 0x48 }, + { 0x5403d, 0x1500 }, + { 0xd0000, 0x1 }, +}; + +/* P2 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp2_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54002, 0x102 }, + { 0x54003, 0x64 }, + { 0x54004, 0x2 }, + { 0x54005, 0x303c }, + { 0x54006, 0x14 }, + { 0x54008, 0x121f }, + { 0x54009, 0xc8 }, + { 0x5400b, 0x2 }, + { 0x5400f, 0x100 }, + { 0x54012, 0x110 }, + { 0x54019, 0x84 }, + { 0x5401a, 0x2b }, + { 0x5401b, 0x4855 }, + { 0x5401c, 0x4800 }, + { 0x5401e, 0x15 }, + { 0x5401f, 0x84 }, + { 0x54020, 0x2b }, + { 0x54021, 0x4855 }, + { 0x54022, 0x4800 }, + { 0x54024, 0x15 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x1 }, + { 0x54032, 0x8400 }, + { 0x54033, 0x2b00 }, + { 0x54034, 0x5500 }, + { 0x54035, 0x48 }, + { 0x54036, 0x48 }, + { 0x54037, 0x1500 }, + { 0x54038, 0x8400 }, + { 0x54039, 0x2b00 }, + { 0x5403a, 0x5500 }, + { 0x5403b, 0x48 }, + { 0x5403c, 0x48 }, + { 0x5403d, 0x1500 }, + { 0xd0000, 0x1 }, +}; + +/* P0 2D message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54003, 0xfa0 }, + { 0x54004, 0x2 }, + { 0x54005, 0x303c }, + { 0x54006, 0x14 }, + { 0x54008, 0x61 }, + { 0x54009, 0xc8 }, + { 0x5400b, 0x2 }, + { 0x5400f, 0x100 }, + { 0x54010, 0x1f7f }, + { 0x54012, 0x110 }, + { 0x54019, 0x3ff4 }, + { 0x5401a, 0x2b }, + { 0x5401b, 0x4855 }, + { 0x5401c, 0x4800 }, + { 0x5401e, 0x15 }, + { 0x5401f, 0x3ff4 }, + { 0x54020, 0x2b }, + { 0x54021, 0x4855 }, + { 0x54022, 0x4800 }, + { 0x54024, 0x15 }, + { 0x5402b, 0x1000 }, + { 0x5402c, 0x1 }, + { 0x54032, 0xf400 }, + { 0x54033, 0x2b3f }, + { 0x54034, 0x5500 }, + { 0x54035, 0x48 }, + { 0x54036, 0x48 }, + { 0x54037, 0x1500 }, + { 0x54038, 0xf400 }, + { 0x54039, 0x2b3f }, + { 0x5403a, 0x5500 }, + { 0x5403b, 0x48 }, + { 0x5403c, 0x48 }, + { 0x5403d, 0x1500 }, + { 0xd0000, 0x1 }, +}; + +/* DRAM PHY init engine image */ +static struct dram_cfg_param ddr_phy_pie[] = { + { 0xd0000, 0x0 }, + { 0x90000, 0x10 }, + { 0x90001, 0x400 }, + { 0x90002, 0x10e }, + { 0x90003, 0x0 }, + { 0x90004, 0x0 }, + { 0x90005, 0x8 }, + { 0x90029, 0xb }, + { 0x9002a, 0x480 }, + { 0x9002b, 0x109 }, + { 0x9002c, 0x8 }, + { 0x9002d, 0x448 }, + { 0x9002e, 0x139 }, + { 0x9002f, 0x8 }, + { 0x90030, 0x478 }, + { 0x90031, 0x109 }, + { 0x90032, 0x0 }, + { 0x90033, 0xe8 }, + { 0x90034, 0x109 }, + { 0x90035, 0x2 }, + { 0x90036, 0x10 }, + { 0x90037, 0x139 }, + { 0x90038, 0xb }, + { 0x90039, 0x7c0 }, + { 0x9003a, 0x139 }, + { 0x9003b, 0x44 }, + { 0x9003c, 0x633 }, + { 0x9003d, 0x159 }, + { 0x9003e, 0x14f }, + { 0x9003f, 0x630 }, + { 0x90040, 0x159 }, + { 0x90041, 0x47 }, + { 0x90042, 0x633 }, + { 0x90043, 0x149 }, + { 0x90044, 0x4f }, + { 0x90045, 0x633 }, + { 0x90046, 0x179 }, + { 0x90047, 0x8 }, + { 0x90048, 0xe0 }, + { 0x90049, 0x109 }, + { 0x9004a, 0x0 }, + { 0x9004b, 0x7c8 }, + { 0x9004c, 0x109 }, + { 0x9004d, 0x0 }, + { 0x9004e, 0x1 }, + { 0x9004f, 0x8 }, + { 0x90050, 0x0 }, + { 0x90051, 0x45a }, + { 0x90052, 0x9 }, + { 0x90053, 0x0 }, + { 0x90054, 0x448 }, + { 0x90055, 0x109 }, + { 0x90056, 0x40 }, + { 0x90057, 0x633 }, + { 0x90058, 0x179 }, + { 0x90059, 0x1 }, + { 0x9005a, 0x618 }, + { 0x9005b, 0x109 }, + { 0x9005c, 0x40c0 }, + { 0x9005d, 0x633 }, + { 0x9005e, 0x149 }, + { 0x9005f, 0x8 }, + { 0x90060, 0x4 }, + { 0x90061, 0x48 }, + { 0x90062, 0x4040 }, + { 0x90063, 0x633 }, + { 0x90064, 0x149 }, + { 0x90065, 0x0 }, + { 0x90066, 0x4 }, + { 0x90067, 0x48 }, + { 0x90068, 0x40 }, + { 0x90069, 0x633 }, + { 0x9006a, 0x149 }, + { 0x9006b, 0x10 }, + { 0x9006c, 0x4 }, + { 0x9006d, 0x18 }, + { 0x9006e, 0x0 }, + { 0x9006f, 0x4 }, + { 0x90070, 0x78 }, + { 0x90071, 0x549 }, + { 0x90072, 0x633 }, + { 0x90073, 0x159 }, + { 0x90074, 0xd49 }, + { 0x90075, 0x633 }, + { 0x90076, 0x159 }, + { 0x90077, 0x94a }, + { 0x90078, 0x633 }, + { 0x90079, 0x159 }, + { 0x9007a, 0x441 }, + { 0x9007b, 0x633 }, + { 0x9007c, 0x149 }, + { 0x9007d, 0x42 }, + { 0x9007e, 0x633 }, + { 0x9007f, 0x149 }, + { 0x90080, 0x1 }, + { 0x90081, 0x633 }, + { 0x90082, 0x149 }, + { 0x90083, 0x0 }, + { 0x90084, 0xe0 }, + { 0x90085, 0x109 }, + { 0x90086, 0xa }, + { 0x90087, 0x10 }, + { 0x90088, 0x109 }, + { 0x90089, 0x9 }, + { 0x9008a, 0x3c0 }, + { 0x9008b, 0x149 }, + { 0x9008c, 0x9 }, + { 0x9008d, 0x3c0 }, + { 0x9008e, 0x159 }, + { 0x9008f, 0x18 }, + { 0x90090, 0x10 }, + { 0x90091, 0x109 }, + { 0x90092, 0x0 }, + { 0x90093, 0x3c0 }, + { 0x90094, 0x109 }, + { 0x90095, 0x18 }, + { 0x90096, 0x4 }, + { 0x90097, 0x48 }, + { 0x90098, 0x18 }, + { 0x90099, 0x4 }, + { 0x9009a, 0x58 }, + { 0x9009b, 0xb }, + { 0x9009c, 0x10 }, + { 0x9009d, 0x109 }, + { 0x9009e, 0x1 }, + { 0x9009f, 0x10 }, + { 0x900a0, 0x109 }, + { 0x900a1, 0x5 }, + { 0x900a2, 0x7c0 }, + { 0x900a3, 0x109 }, + { 0x40000, 0x811 }, + { 0x40020, 0x880 }, + { 0x40040, 0x0 }, + { 0x40060, 0x0 }, + { 0x40001, 0x4008 }, + { 0x40021, 0x83 }, + { 0x40041, 0x4f }, + { 0x40061, 0x0 }, + { 0x40002, 0x4040 }, + { 0x40022, 0x83 }, + { 0x40042, 0x51 }, + { 0x40062, 0x0 }, + { 0x40003, 0x811 }, + { 0x40023, 0x880 }, + { 0x40043, 0x0 }, + { 0x40063, 0x0 }, + { 0x40004, 0x720 }, + { 0x40024, 0xf }, + { 0x40044, 0x1740 }, + { 0x40064, 0x0 }, + { 0x40005, 0x16 }, + { 0x40025, 0x83 }, + { 0x40045, 0x4b }, + { 0x40065, 0x0 }, + { 0x40006, 0x716 }, + { 0x40026, 0xf }, + { 0x40046, 0x2001 }, + { 0x40066, 0x0 }, + { 0x40007, 0x716 }, + { 0x40027, 0xf }, + { 0x40047, 0x2800 }, + { 0x40067, 0x0 }, + { 0x40008, 0x716 }, + { 0x40028, 0xf }, + { 0x40048, 0xf00 }, + { 0x40068, 0x0 }, + { 0x40009, 0x720 }, + { 0x40029, 0xf }, + { 0x40049, 0x1400 }, + { 0x40069, 0x0 }, + { 0x4000a, 0xe08 }, + { 0x4002a, 0xc15 }, + { 0x4004a, 0x0 }, + { 0x4006a, 0x0 }, + { 0x4000b, 0x625 }, + { 0x4002b, 0x15 }, + { 0x4004b, 0x0 }, + { 0x4006b, 0x0 }, + { 0x4000c, 0x4028 }, + { 0x4002c, 0x80 }, + { 0x4004c, 0x0 }, + { 0x4006c, 0x0 }, + { 0x4000d, 0xe08 }, + { 0x4002d, 0xc1a }, + { 0x4004d, 0x0 }, + { 0x4006d, 0x0 }, + { 0x4000e, 0x625 }, + { 0x4002e, 0x1a }, + { 0x4004e, 0x0 }, + { 0x4006e, 0x0 }, + { 0x4000f, 0x4040 }, + { 0x4002f, 0x80 }, + { 0x4004f, 0x0 }, + { 0x4006f, 0x0 }, + { 0x40010, 0x2604 }, + { 0x40030, 0x15 }, + { 0x40050, 0x0 }, + { 0x40070, 0x0 }, + { 0x40011, 0x708 }, + { 0x40031, 0x5 }, + { 0x40051, 0x0 }, + { 0x40071, 0x2002 }, + { 0x40012, 0x8 }, + { 0x40032, 0x80 }, + { 0x40052, 0x0 }, + { 0x40072, 0x0 }, + { 0x40013, 0x2604 }, + { 0x40033, 0x1a }, + { 0x40053, 0x0 }, + { 0x40073, 0x0 }, + { 0x40014, 0x708 }, + { 0x40034, 0xa }, + { 0x40054, 0x0 }, + { 0x40074, 0x2002 }, + { 0x40015, 0x4040 }, + { 0x40035, 0x80 }, + { 0x40055, 0x0 }, + { 0x40075, 0x0 }, + { 0x40016, 0x60a }, + { 0x40036, 0x15 }, + { 0x40056, 0x1200 }, + { 0x40076, 0x0 }, + { 0x40017, 0x61a }, + { 0x40037, 0x15 }, + { 0x40057, 0x1300 }, + { 0x40077, 0x0 }, + { 0x40018, 0x60a }, + { 0x40038, 0x1a }, + { 0x40058, 0x1200 }, + { 0x40078, 0x0 }, + { 0x40019, 0x642 }, + { 0x40039, 0x1a }, + { 0x40059, 0x1300 }, + { 0x40079, 0x0 }, + { 0x4001a, 0x4808 }, + { 0x4003a, 0x880 }, + { 0x4005a, 0x0 }, + { 0x4007a, 0x0 }, + { 0x900a4, 0x0 }, + { 0x900a5, 0x790 }, + { 0x900a6, 0x11a }, + { 0x900a7, 0x8 }, + { 0x900a8, 0x7aa }, + { 0x900a9, 0x2a }, + { 0x900aa, 0x10 }, + { 0x900ab, 0x7b2 }, + { 0x900ac, 0x2a }, + { 0x900ad, 0x0 }, + { 0x900ae, 0x7c8 }, + { 0x900af, 0x109 }, + { 0x900b0, 0x10 }, + { 0x900b1, 0x10 }, + { 0x900b2, 0x109 }, + { 0x900b3, 0x10 }, + { 0x900b4, 0x2a8 }, + { 0x900b5, 0x129 }, + { 0x900b6, 0x8 }, + { 0x900b7, 0x370 }, + { 0x900b8, 0x129 }, + { 0x900b9, 0xa }, + { 0x900ba, 0x3c8 }, + { 0x900bb, 0x1a9 }, + { 0x900bc, 0xc }, + { 0x900bd, 0x408 }, + { 0x900be, 0x199 }, + { 0x900bf, 0x14 }, + { 0x900c0, 0x790 }, + { 0x900c1, 0x11a }, + { 0x900c2, 0x8 }, + { 0x900c3, 0x4 }, + { 0x900c4, 0x18 }, + { 0x900c5, 0xe }, + { 0x900c6, 0x408 }, + { 0x900c7, 0x199 }, + { 0x900c8, 0x8 }, + { 0x900c9, 0x8568 }, + { 0x900ca, 0x108 }, + { 0x900cb, 0x18 }, + { 0x900cc, 0x790 }, + { 0x900cd, 0x16a }, + { 0x900ce, 0x8 }, + { 0x900cf, 0x1d8 }, + { 0x900d0, 0x169 }, + { 0x900d1, 0x10 }, + { 0x900d2, 0x8558 }, + { 0x900d3, 0x168 }, + { 0x900d4, 0x70 }, + { 0x900d5, 0x788 }, + { 0x900d6, 0x16a }, + { 0x900d7, 0x1ff8 }, + { 0x900d8, 0x85a8 }, + { 0x900d9, 0x1e8 }, + { 0x900da, 0x50 }, + { 0x900db, 0x798 }, + { 0x900dc, 0x16a }, + { 0x900dd, 0x60 }, + { 0x900de, 0x7a0 }, + { 0x900df, 0x16a }, + { 0x900e0, 0x8 }, + { 0x900e1, 0x8310 }, + { 0x900e2, 0x168 }, + { 0x900e3, 0x8 }, + { 0x900e4, 0xa310 }, + { 0x900e5, 0x168 }, + { 0x900e6, 0xa }, + { 0x900e7, 0x408 }, + { 0x900e8, 0x169 }, + { 0x900e9, 0x6e }, + { 0x900ea, 0x0 }, + { 0x900eb, 0x68 }, + { 0x900ec, 0x0 }, + { 0x900ed, 0x408 }, + { 0x900ee, 0x169 }, + { 0x900ef, 0x0 }, + { 0x900f0, 0x8310 }, + { 0x900f1, 0x168 }, + { 0x900f2, 0x0 }, + { 0x900f3, 0xa310 }, + { 0x900f4, 0x168 }, + { 0x900f5, 0x1ff8 }, + { 0x900f6, 0x85a8 }, + { 0x900f7, 0x1e8 }, + { 0x900f8, 0x68 }, + { 0x900f9, 0x798 }, + { 0x900fa, 0x16a }, + { 0x900fb, 0x78 }, + { 0x900fc, 0x7a0 }, + { 0x900fd, 0x16a }, + { 0x900fe, 0x68 }, + { 0x900ff, 0x790 }, + { 0x90100, 0x16a }, + { 0x90101, 0x8 }, + { 0x90102, 0x8b10 }, + { 0x90103, 0x168 }, + { 0x90104, 0x8 }, + { 0x90105, 0xab10 }, + { 0x90106, 0x168 }, + { 0x90107, 0xa }, + { 0x90108, 0x408 }, + { 0x90109, 0x169 }, + { 0x9010a, 0x58 }, + { 0x9010b, 0x0 }, + { 0x9010c, 0x68 }, + { 0x9010d, 0x0 }, + { 0x9010e, 0x408 }, + { 0x9010f, 0x169 }, + { 0x90110, 0x0 }, + { 0x90111, 0x8b10 }, + { 0x90112, 0x168 }, + { 0x90113, 0x1 }, + { 0x90114, 0xab10 }, + { 0x90115, 0x168 }, + { 0x90116, 0x0 }, + { 0x90117, 0x1d8 }, + { 0x90118, 0x169 }, + { 0x90119, 0x80 }, + { 0x9011a, 0x790 }, + { 0x9011b, 0x16a }, + { 0x9011c, 0x18 }, + { 0x9011d, 0x7aa }, + { 0x9011e, 0x6a }, + { 0x9011f, 0xa }, + { 0x90120, 0x0 }, + { 0x90121, 0x1e9 }, + { 0x90122, 0x8 }, + { 0x90123, 0x8080 }, + { 0x90124, 0x108 }, + { 0x90125, 0xf }, + { 0x90126, 0x408 }, + { 0x90127, 0x169 }, + { 0x90128, 0xc }, + { 0x90129, 0x0 }, + { 0x9012a, 0x68 }, + { 0x9012b, 0x9 }, + { 0x9012c, 0x0 }, + { 0x9012d, 0x1a9 }, + { 0x9012e, 0x0 }, + { 0x9012f, 0x408 }, + { 0x90130, 0x169 }, + { 0x90131, 0x0 }, + { 0x90132, 0x8080 }, + { 0x90133, 0x108 }, + { 0x90134, 0x8 }, + { 0x90135, 0x7aa }, + { 0x90136, 0x6a }, + { 0x90137, 0x0 }, + { 0x90138, 0x8568 }, + { 0x90139, 0x108 }, + { 0x9013a, 0xb7 }, + { 0x9013b, 0x790 }, + { 0x9013c, 0x16a }, + { 0x9013d, 0x1f }, + { 0x9013e, 0x0 }, + { 0x9013f, 0x68 }, + { 0x90140, 0x8 }, + { 0x90141, 0x8558 }, + { 0x90142, 0x168 }, + { 0x90143, 0xf }, + { 0x90144, 0x408 }, + { 0x90145, 0x169 }, + { 0x90146, 0xd }, + { 0x90147, 0x0 }, + { 0x90148, 0x68 }, + { 0x90149, 0x0 }, + { 0x9014a, 0x408 }, + { 0x9014b, 0x169 }, + { 0x9014c, 0x0 }, + { 0x9014d, 0x8558 }, + { 0x9014e, 0x168 }, + { 0x9014f, 0x8 }, + { 0x90150, 0x3c8 }, + { 0x90151, 0x1a9 }, + { 0x90152, 0x3 }, + { 0x90153, 0x370 }, + { 0x90154, 0x129 }, + { 0x90155, 0x20 }, + { 0x90156, 0x2aa }, + { 0x90157, 0x9 }, + { 0x90158, 0x8 }, + { 0x90159, 0xe8 }, + { 0x9015a, 0x109 }, + { 0x9015b, 0x0 }, + { 0x9015c, 0x8140 }, + { 0x9015d, 0x10c }, + { 0x9015e, 0x10 }, + { 0x9015f, 0x8138 }, + { 0x90160, 0x104 }, + { 0x90161, 0x8 }, + { 0x90162, 0x448 }, + { 0x90163, 0x109 }, + { 0x90164, 0xf }, + { 0x90165, 0x7c0 }, + { 0x90166, 0x109 }, + { 0x90167, 0x0 }, + { 0x90168, 0xe8 }, + { 0x90169, 0x109 }, + { 0x9016a, 0x47 }, + { 0x9016b, 0x630 }, + { 0x9016c, 0x109 }, + { 0x9016d, 0x8 }, + { 0x9016e, 0x618 }, + { 0x9016f, 0x109 }, + { 0x90170, 0x8 }, + { 0x90171, 0xe0 }, + { 0x90172, 0x109 }, + { 0x90173, 0x0 }, + { 0x90174, 0x7c8 }, + { 0x90175, 0x109 }, + { 0x90176, 0x8 }, + { 0x90177, 0x8140 }, + { 0x90178, 0x10c }, + { 0x90179, 0x0 }, + { 0x9017a, 0x478 }, + { 0x9017b, 0x109 }, + { 0x9017c, 0x0 }, + { 0x9017d, 0x1 }, + { 0x9017e, 0x8 }, + { 0x9017f, 0x8 }, + { 0x90180, 0x4 }, + { 0x90181, 0x0 }, + { 0x90006, 0x8 }, + { 0x90007, 0x7c8 }, + { 0x90008, 0x109 }, + { 0x90009, 0x0 }, + { 0x9000a, 0x400 }, + { 0x9000b, 0x106 }, + { 0xd00e7, 0x400 }, + { 0x90017, 0x0 }, + { 0x9001f, 0x29 }, + { 0x90026, 0x68 }, + { 0x400d0, 0x0 }, + { 0x400d1, 0x101 }, + { 0x400d2, 0x105 }, + { 0x400d3, 0x107 }, + { 0x400d4, 0x10f }, + { 0x400d5, 0x202 }, + { 0x400d6, 0x20a }, + { 0x400d7, 0x20b }, + { 0x2003a, 0x2 }, + { 0x200be, 0x3 }, + { 0x2000b, 0x465 }, + { 0x2000c, 0xfa }, + { 0x2000d, 0x9c4 }, + { 0x2000e, 0x2c }, + { 0x12000b, 0x70 }, + { 0x12000c, 0x19 }, + { 0x12000d, 0xfa }, + { 0x12000e, 0x10 }, + { 0x22000b, 0x1c }, + { 0x22000c, 0x6 }, + { 0x22000d, 0x3e }, + { 0x22000e, 0x10 }, + { 0x9000c, 0x0 }, + { 0x9000d, 0x173 }, + { 0x9000e, 0x60 }, + { 0x9000f, 0x6110 }, + { 0x90010, 0x2152 }, + { 0x90011, 0xdfbd }, + { 0x90012, 0x2060 }, + { 0x90013, 0x6152 }, + { 0x20010, 0x5a }, + { 0x20011, 0x3 }, + { 0x40080, 0xe0 }, + { 0x40081, 0x12 }, + { 0x40082, 0xe0 }, + { 0x40083, 0x12 }, + { 0x40084, 0xe0 }, + { 0x40085, 0x12 }, + { 0x140080, 0xe0 }, + { 0x140081, 0x12 }, + { 0x140082, 0xe0 }, + { 0x140083, 0x12 }, + { 0x140084, 0xe0 }, + { 0x140085, 0x12 }, + { 0x240080, 0xe0 }, + { 0x240081, 0x12 }, + { 0x240082, 0xe0 }, + { 0x240083, 0x12 }, + { 0x240084, 0xe0 }, + { 0x240085, 0x12 }, + { 0x400fd, 0xf }, + { 0x10011, 0x1 }, + { 0x10012, 0x1 }, + { 0x10013, 0x180 }, + { 0x10018, 0x1 }, + { 0x10002, 0x6209 }, + { 0x100b2, 0x1 }, + { 0x101b4, 0x1 }, + { 0x102b4, 0x1 }, + { 0x103b4, 0x1 }, + { 0x104b4, 0x1 }, + { 0x105b4, 0x1 }, + { 0x106b4, 0x1 }, + { 0x107b4, 0x1 }, + { 0x108b4, 0x1 }, + { 0x11011, 0x1 }, + { 0x11012, 0x1 }, + { 0x11013, 0x180 }, + { 0x11018, 0x1 }, + { 0x11002, 0x6209 }, + { 0x110b2, 0x1 }, + { 0x111b4, 0x1 }, + { 0x112b4, 0x1 }, + { 0x113b4, 0x1 }, + { 0x114b4, 0x1 }, + { 0x115b4, 0x1 }, + { 0x116b4, 0x1 }, + { 0x117b4, 0x1 }, + { 0x118b4, 0x1 }, + { 0x12011, 0x1 }, + { 0x12012, 0x1 }, + { 0x12013, 0x180 }, + { 0x12018, 0x1 }, + { 0x12002, 0x6209 }, + { 0x120b2, 0x1 }, + { 0x121b4, 0x1 }, + { 0x122b4, 0x1 }, + { 0x123b4, 0x1 }, + { 0x124b4, 0x1 }, + { 0x125b4, 0x1 }, + { 0x126b4, 0x1 }, + { 0x127b4, 0x1 }, + { 0x128b4, 0x1 }, + { 0x13011, 0x1 }, + { 0x13012, 0x1 }, + { 0x13013, 0x180 }, + { 0x13018, 0x1 }, + { 0x13002, 0x6209 }, + { 0x130b2, 0x1 }, + { 0x131b4, 0x1 }, + { 0x132b4, 0x1 }, + { 0x133b4, 0x1 }, + { 0x134b4, 0x1 }, + { 0x135b4, 0x1 }, + { 0x136b4, 0x1 }, + { 0x137b4, 0x1 }, + { 0x138b4, 0x1 }, + { 0x20089, 0x1 }, + { 0x20088, 0x19 }, + { 0xc0080, 0x2 }, + { 0xd0000, 0x1 } +}; + +static struct dram_fsp_msg ddr_dram_fsp_msg[] = { + { + /* P0 4000mts 1D */ + .drate = 4000, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), + }, + { + /* P1 400mts 1D */ + .drate = 400, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P2 100mts 1D */ + .drate = 100, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp2_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg), + }, + { + /* P0 4000mts 2D */ + .drate = 4000, + .fw_type = FW_2D_IMAGE, + .fsp_cfg = ddr_fsp0_2d_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), + }, +}; + +/* ddr timing config params */ +struct dram_timing_info dram_timing_2gb_no_ecc = { + .ddrc_cfg = ddr_ddrc_cfg, + .ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg), + .ddrphy_cfg = ddr_ddrphy_cfg, + .ddrphy_cfg_num = ARRAY_SIZE(ddr_ddrphy_cfg), + .fsp_msg = ddr_dram_fsp_msg, + .fsp_msg_num = ARRAY_SIZE(ddr_dram_fsp_msg), + .ddrphy_trained_csr = ddr_ddrphy_trained_csr, + .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr), + .ddrphy_pie = ddr_phy_pie, + .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie), + .fsp_table = { 4000, 400, 100, }, +}; + +#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC +#error +#endif diff --git a/arch/arm/configs/imx_v8_defconfig b/arch/arm/configs/imx_v8_defconfig index d1d67514cf..ea6428d7e2 100644 --- a/arch/arm/configs/imx_v8_defconfig +++ b/arch/arm/configs/imx_v8_defconfig @@ -8,6 +8,7 @@ CONFIG_MACH_NXP_IMX8MN_EVK=y CONFIG_MACH_NXP_IMX8MP_EVK=y CONFIG_MACH_NXP_IMX8MQ_EVK=y CONFIG_MACH_PHYTEC_SOM_IMX8MQ=y +CONFIG_MACH_TQ_MBA8MPXL=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_MMU=y CONFIG_MALLOC_SIZE=0x0 diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 99f44e7b04..5ceb97129f 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -146,6 +146,7 @@ lwl-$(CONFIG_MACH_NXP_IMX8MN_EVK) += imx8mn-evk.dtb.o imx8mn-ddr4-evk.dtb.o lwl-$(CONFIG_MACH_NXP_IMX8MP_EVK) += imx8mp-evk.dtb.o lwl-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += imx8mq-evk.dtb.o lwl-$(CONFIG_MACH_INNOCOMM_WB15) += imx8mm-innocomm-wb15-evk.dtb.o +lwl-$(CONFIG_MACH_TQ_MBA8MPXL) += imx8mp-tqma8mpql-mba8mpxl.dtb.o lwl-$(CONFIG_MACH_TORADEX_COLIBRI_T20) += tegra20-colibri-iris.dtb.o lwl-$(CONFIG_MACH_TOSHIBA_AC100) += tegra20-paz00.dtb.o lwl-$(CONFIG_MACH_TQMA53) += imx53-mba53.dtb.o diff --git a/arch/arm/dts/imx8mp-tqma8mpql-mba8mpxl.dts b/arch/arm/dts/imx8mp-tqma8mpql-mba8mpxl.dts new file mode 100644 index 0000000000..c47e7285a7 --- /dev/null +++ b/arch/arm/dts/imx8mp-tqma8mpql-mba8mpxl.dts @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017 NXP + * Copyright (C) 2017 Pengutronix, Oleksij Rempel + */ + +/dts-v1/; + +#include +#include "imx8mp.dtsi" + +/ { + chosen { + environment-sd { + compatible = "barebox,environment"; + device-path = &env_sd2; + status = "disabled"; + }; + environment-emmc { + compatible = "barebox,environment"; + device-path = &env_sd3; + status = "disabled"; + }; + }; +}; + +&usdhc2 { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0xe0000>; + }; + + env_sd2: partition@e0000 { + label = "barebox-environment"; + reg = <0xe0000 0x20000>; + }; +}; + +&usdhc3 { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0xe0000>; + }; + + env_sd3: partition@e0000 { + label = "barebox-environment"; + reg = <0xe0000 0x20000>; + }; +}; + +&ocotp { + barebox,provide-mac-address = <&fec 0x640>; +}; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index fd4f68627d..d6c6c720d4 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -618,6 +618,16 @@ config MACH_PHYTEC_SOM_IMX8MQ select ARM_SMCCC select MCI_IMX_ESDHC_PBL +config MACH_TQ_MBA8MPXL + bool "TQ i.MX8MP Dual/Quad on MBa8MPxL Board" + select ARCH_IMX8MP + select FIRMWARE_IMX_LPDDR4_PMU_TRAIN + select FIRMWARE_IMX8MP_ATF + select ARM_SMCCC + select MCI_IMX_ESDHC_PBL + select IMX8M_DRAM + select I2C_IMX_EARLY + config MACH_GRINN_LITEBOARD bool "Grinn liteboard" select ARCH_IMX6UL diff --git a/images/Makefile.imx b/images/Makefile.imx index 20bbc48eaa..e9f4ba64e4 100644 --- a/images/Makefile.imx +++ b/images/Makefile.imx @@ -456,6 +456,11 @@ CFG_start_nxp_imx8mp_evk.pblb.imximg = $(board)/nxp-imx8mp-evk/flash-header-imx8 FILE_barebox-nxp-imx8mp-evk.img = start_nxp_imx8mp_evk.pblb.pimximg image-$(CONFIG_MACH_NXP_IMX8MP_EVK) += barebox-nxp-imx8mp-evk.img +pblb-$(CONFIG_MACH_TQ_MBA8MPXL) += start_tqma8mpxl +CFG_start_tqma8mpxl.pblb.imximg = $(board)/tqma8mpxl/flash-header-tqma8mpxl.imxcfg +FILE_barebox-tqma8mpxl.img = start_tqma8mpxl.pblb.pimximg +image-$(CONFIG_MACH_TQ_MBA8MPXL) += barebox-tqma8mpxl.img + # ----------------------- i.MX8mq based boards -------------------------- pblb-$(CONFIG_MACH_NXP_IMX8MQ_EVK) += start_nxp_imx8mq_evk CFG_start_nxp_imx8mq_evk.pblb.imximg = $(board)/nxp-imx8mq-evk/flash-header-imx8mq-evk.imxcfg -- cgit v1.2.3 From 94729ba85abb3deb77d7ba67c6ded2217cc436c8 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Mon, 24 Oct 2022 11:56:12 +0200 Subject: aiodev: port Linux imx7d-adc driver The i.MX7 has two ADCs of 4 logical channels each. Port the Linux v6.0 driver of the peripheral to make them usable in barebox. This can be useful for board type/revision detection that employs voltage dividers. Signed-off-by: Ahmad Fatoum Link: https://lore.barebox.org/20221024095612.1537704-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/aiodev/Kconfig | 8 + drivers/aiodev/Makefile | 1 + drivers/aiodev/imx7d_adc.c | 431 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 440 insertions(+) create mode 100644 drivers/aiodev/imx7d_adc.c diff --git a/drivers/aiodev/Kconfig b/drivers/aiodev/Kconfig index 6bd697702e..5c8706ffef 100644 --- a/drivers/aiodev/Kconfig +++ b/drivers/aiodev/Kconfig @@ -65,4 +65,12 @@ config ROCKCHIP_SARADC help Support for Successive Approximation Register (SAR) ADC in Rockchip SoCs. + +config IMX7D_ADC + tristate "Freescale IMX7D ADC driver" + depends on ARCH_IMX7 || COMPILE_TEST + depends on OFDEVICE + help + Say yes here to build support for IMX7D ADC. + endif diff --git a/drivers/aiodev/Makefile b/drivers/aiodev/Makefile index 06a63b0d2d..9cb11605ed 100644 --- a/drivers/aiodev/Makefile +++ b/drivers/aiodev/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_QORIQ_THERMAL) += qoriq_thermal.o obj-$(CONFIG_AM335X_ADC) += am335x_adc.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o stm32-adc-core.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o +obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o diff --git a/drivers/aiodev/imx7d_adc.c b/drivers/aiodev/imx7d_adc.c new file mode 100644 index 0000000000..21cb063686 --- /dev/null +++ b/drivers/aiodev/imx7d_adc.c @@ -0,0 +1,431 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Freescale i.MX7D ADC driver + * + * Copyright (C) 2015 Freescale Semiconductor, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* ADC register */ +#define IMX7D_REG_ADC_TIMER_UNIT 0x90 +#define IMX7D_REG_ADC_INT_STATUS 0xe0 +#define IMX7D_REG_ADC_CHA_B_CNV_RSLT 0xf0 +#define IMX7D_REG_ADC_CHC_D_CNV_RSLT 0x100 +#define IMX7D_REG_ADC_ADC_CFG 0x130 + +#define IMX7D_REG_ADC_CFG1(ch) ((ch) * 0x20) +#define IMX7D_REG_ADC_CFG2(ch) ((ch) * 0x20 + 0x10) + +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN (0x1 << 31) +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE BIT(30) +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN BIT(29) +#define IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(x) ((x) << 24) + +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4 (0x0 << 12) +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8 (0x1 << 12) +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16 (0x2 << 12) +#define IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32 (0x3 << 12) + +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4 (0x0 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8 (0x1 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16 (0x2 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32 (0x3 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64 (0x4 << 29) +#define IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128 (0x5 << 29) + +#define IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN BIT(31) +#define IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN BIT(1) +#define IMX7D_REG_ADC_ADC_CFG_ADC_EN BIT(0) + +#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS 0xf00 +#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000 + +#define IMX7D_ADC_TIMEOUT_NSEC (100 * NSEC_PER_MSEC) +#define IMX7D_ADC_INPUT_CLK 24000000 + +enum imx7d_adc_clk_pre_div { + IMX7D_ADC_ANALOG_CLK_PRE_DIV_4, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_8, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_16, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_32, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_64, + IMX7D_ADC_ANALOG_CLK_PRE_DIV_128, +}; + +enum imx7d_adc_average_num { + IMX7D_ADC_AVERAGE_NUM_4, + IMX7D_ADC_AVERAGE_NUM_8, + IMX7D_ADC_AVERAGE_NUM_16, + IMX7D_ADC_AVERAGE_NUM_32, +}; + +struct imx7d_adc_feature { + enum imx7d_adc_clk_pre_div clk_pre_div; + enum imx7d_adc_average_num avg_num; + + u32 core_time_unit; /* impact the sample rate */ +}; + +struct imx7d_adc { + struct device_d *dev; + void __iomem *regs; + struct clk *clk; + struct aiodevice aiodev; + void (*aiodev_info)(struct device_d *); + + u32 vref_uv; + u32 pre_div_num; + + struct regulator *vref; + struct imx7d_adc_feature adc_feature; + + struct aiochannel aiochan[16]; +}; + +struct imx7d_adc_analogue_core_clk { + u32 pre_div; + u32 reg_config; +}; + +#define IMX7D_ADC_ANALOGUE_CLK_CONFIG(_pre_div, _reg_conf) { \ + .pre_div = (_pre_div), \ + .reg_config = (_reg_conf), \ +} + +static const struct imx7d_adc_analogue_core_clk imx7d_adc_analogue_clk[] = { + IMX7D_ADC_ANALOGUE_CLK_CONFIG(4, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_4), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(8, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_8), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(16, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_16), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(32, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_32), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(64, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_64), + IMX7D_ADC_ANALOGUE_CLK_CONFIG(128, IMX7D_REG_ADC_TIMER_UNIT_PRE_DIV_128), +}; + +static const u32 imx7d_adc_average_num[] = { + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_4, + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_8, + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_16, + IMX7D_REG_ADC_CH_CFG2_AVG_NUM_32, +}; + +static void imx7d_adc_feature_config(struct imx7d_adc *info) +{ + info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4; + info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32; + info->adc_feature.core_time_unit = 1; +} + +static void imx7d_adc_sample_rate_set(struct imx7d_adc *info) +{ + struct imx7d_adc_feature *adc_feature = &info->adc_feature; + struct imx7d_adc_analogue_core_clk adc_analogue_clk; + unsigned i; + u32 tmp_cfg1; + u32 sample_rate = 0; + + /* + * Before sample set, disable channel A,B,C,D. Here we + * clear the bit 31 of register REG_ADC_CH_A\B\C\D_CFG1. + */ + for (i = 0; i < 4; i++) { + tmp_cfg1 = readl(info->regs + IMX7D_REG_ADC_CFG1(i)); + tmp_cfg1 &= ~IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN; + writel(tmp_cfg1, info->regs + IMX7D_REG_ADC_CFG1(i)); + } + + adc_analogue_clk = imx7d_adc_analogue_clk[adc_feature->clk_pre_div]; + sample_rate |= adc_analogue_clk.reg_config; + info->pre_div_num = adc_analogue_clk.pre_div; + + sample_rate |= adc_feature->core_time_unit; + writel(sample_rate, info->regs + IMX7D_REG_ADC_TIMER_UNIT); +} + +static void imx7d_adc_hw_init(struct imx7d_adc *info) +{ + u32 cfg; + + /* power up and enable adc analogue core */ + cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG); + cfg &= ~(IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN | + IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN); + cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_EN; + writel(cfg, info->regs + IMX7D_REG_ADC_ADC_CFG); + + imx7d_adc_sample_rate_set(info); +} + +static void imx7d_adc_channel_set(struct imx7d_adc *info, u32 channel) +{ + u32 cfg1 = 0; + u32 cfg2; + + /* the channel choose single conversion, and enable average mode */ + cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN | + IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE | + IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN); + + /* + * physical channel 0 chose logical channel A + * physical channel 1 chose logical channel B + * physical channel 2 chose logical channel C + * physical channel 3 chose logical channel D + */ + cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_SEL(channel); + + /* + * read register REG_ADC_CH_A\B\C\D_CFG2, according to the + * channel chosen + */ + cfg2 = readl(info->regs + IMX7D_REG_ADC_CFG2(channel)); + + cfg2 |= imx7d_adc_average_num[info->adc_feature.avg_num]; + + /* + * write the register REG_ADC_CH_A\B\C\D_CFG2, according to + * the channel chosen + */ + writel(cfg2, info->regs + IMX7D_REG_ADC_CFG2(channel)); + writel(cfg1, info->regs + IMX7D_REG_ADC_CFG1(channel)); +} + +static u16 __imx7d_adc_read_data(struct imx7d_adc *info, u32 channel) +{ + u32 value; + + /* + * channel A and B conversion result share one register, + * bit[27~16] is the channel B conversion result, + * bit[11~0] is the channel A conversion result. + * channel C and D is the same. + */ + if (channel < 2) + value = readl(info->regs + IMX7D_REG_ADC_CHA_B_CNV_RSLT); + else + value = readl(info->regs + IMX7D_REG_ADC_CHC_D_CNV_RSLT); + if (channel & 0x1) /* channel B or D */ + value = (value >> 16) & 0xFFF; + else /* channel A or C */ + value &= 0xFFF; + + return value; +} + +static int imx7d_adc_read_data(struct imx7d_adc *info, u32 channel) +{ + int ret = -EAGAIN; + int status; + + status = readl(info->regs + IMX7D_REG_ADC_INT_STATUS); + if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS) { + ret = __imx7d_adc_read_data(info, channel); + + /* + * The register IMX7D_REG_ADC_INT_STATUS can't clear + * itself after read operation, need software to write + * 0 to the related bit. Here we clear the channel A/B/C/D + * conversion finished flag. + */ + status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_INT_STATUS; + writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS); + } + + /* + * If the channel A/B/C/D conversion timeout, report it and clear these + * timeout flags. + */ + if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT) { + dev_err(info->dev, + "ADC got conversion time out interrupt: 0x%08x\n", + status); + status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT; + writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS); + ret = -ETIMEDOUT; + } + + return ret; +} + + +static int imx7d_adc_read_raw(struct aiochannel *chan, int *data) +{ + struct imx7d_adc *info = container_of(chan->aiodev, struct imx7d_adc, aiodev); + u64 raw64, start; + u32 channel; + int ret; + + channel = chan->index & 0x03; + imx7d_adc_channel_set(info, channel); + + start = get_time_ns(); + do { + if (is_timeout(start, IMX7D_ADC_TIMEOUT_NSEC)) { + ret = -ETIMEDOUT; + break; + } + + ret = imx7d_adc_read_data(info, channel); + } while (ret == -EAGAIN); + + if (ret < 0) + return ret; + + raw64 = ret; + raw64 *= info->vref_uv; + raw64 = div_u64(raw64, 1000); + *data = div_u64(raw64, (1 << 12)); + + return 0; +} + +static const struct of_device_id imx7d_adc_match[] = { + { .compatible = "fsl,imx7d-adc", }, + { /* sentinel */ } +}; + +static void imx7d_adc_power_down(struct imx7d_adc *info) +{ + u32 adc_cfg; + + adc_cfg = readl(info->regs + IMX7D_REG_ADC_ADC_CFG); + adc_cfg |= IMX7D_REG_ADC_ADC_CFG_ADC_CLK_DOWN | + IMX7D_REG_ADC_ADC_CFG_ADC_POWER_DOWN; + adc_cfg &= ~IMX7D_REG_ADC_ADC_CFG_ADC_EN; + writel(adc_cfg, info->regs + IMX7D_REG_ADC_ADC_CFG); +} + +static int imx7d_adc_enable(struct imx7d_adc *info) +{ + struct device_d *dev = info->dev; + int ret; + + ret = regulator_enable(info->vref); + if (ret) + return dev_err_probe(dev, ret, + "Can't enable adc reference top voltage\n"); + + ret = clk_enable(info->clk); + if (ret) { + regulator_disable(info->vref); + return dev_err_probe(dev, ret, "Could not enable clock.\n"); + } + + imx7d_adc_hw_init(info); + + ret = regulator_get_voltage(info->vref); + if (ret < 0) + return dev_err_probe(dev, ret, "can't get vref-supply value\n"); + + info->vref_uv = ret; + return 0; +} + +static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info) +{ + u32 analogue_core_clk; + u32 core_time_unit = info->adc_feature.core_time_unit; + u32 tmp; + + analogue_core_clk = IMX7D_ADC_INPUT_CLK / info->pre_div_num; + tmp = (core_time_unit + 1) * 6; + + return analogue_core_clk / tmp; +} + +static void imx7d_adc_devinfo(struct device_d *dev) +{ + struct imx7d_adc *info = dev->parent->priv; + + if (info->aiodev_info) + info->aiodev_info(dev); + + printf("Sample Rate: %u\n", imx7d_adc_get_sample_rate(info)); +} + +static int imx7d_adc_probe(struct device_d *dev) +{ + struct aiodevice *aiodev; + struct imx7d_adc *info; + int ret, i; + + info = xzalloc(sizeof(*info)); + + info->dev = dev; + + info->clk = clk_get(dev, "adc"); + if (IS_ERR(info->clk)) + return dev_err_probe(dev, PTR_ERR(info->clk), "Failed getting clock\n"); + + info->vref = regulator_get(dev, "vref"); + if (IS_ERR(info->vref)) + return dev_err_probe(dev, PTR_ERR(info->vref), + "Failed getting reference voltage\n"); + + info->regs = dev_request_mem_region(dev, 0); + if (IS_ERR(info->regs)) + return dev_err_probe(dev, PTR_ERR(info->regs), + "Failed to get memory region\n"); + + dev->priv = info; + aiodev = &info->aiodev; + + aiodev->num_channels = 4; + aiodev->hwdev = dev; + aiodev->read = imx7d_adc_read_raw; + aiodev->channels = xzalloc(aiodev->num_channels * sizeof(aiodev->channels[0])); + + for (i = 0; i < aiodev->num_channels; i++) { + aiodev->channels[i] = &info->aiochan[i]; + info->aiochan[i].unit = "mV"; + } + + imx7d_adc_feature_config(info); + + ret = imx7d_adc_enable(info); + if (ret) + return ret; + + ret = aiodevice_register(aiodev); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to register aiodev\n"); + + info->aiodev_info = aiodev->dev.info; + aiodev->dev.info = imx7d_adc_devinfo; + + return 0; +} + +static void imx7d_adc_disable(struct device_d *dev) +{ + struct imx7d_adc *info = dev->priv; + + imx7d_adc_power_down(info); + + clk_disable(info->clk); + regulator_disable(info->vref); +} + +static struct driver_d imx7d_adc_driver = { + .probe = imx7d_adc_probe, + .name = "imx7d_adc", + .of_compatible = imx7d_adc_match, + .remove = imx7d_adc_disable, +}; +device_platform_driver(imx7d_adc_driver); + +MODULE_AUTHOR("Haibo Chen "); +MODULE_DESCRIPTION("Freescale IMX7D ADC driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 2b8cc2682d60a1da1101b393b7f8884eab685860 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 2 Nov 2022 09:20:24 +0100 Subject: ARM: kamstrup-mx7-concentrator: Setup UART4 UART4 is used as console, so initialize that UART and not UART1 as noted by Bruno Thomsen: https://lore.barebox.org/barebox/CAH+2xPCAE2eEiyAJnq=pDOxy6EY71h3tDr4tjm2PQ-wtTN8brA@mail.gmail.com/T/#t Signed-off-by: Sascha Hauer --- arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c b/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c index 511f01757c..58240d22f7 100644 --- a/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c +++ b/arch/arm/boards/kamstrup-mx7-concentrator/lowlevel.c @@ -17,8 +17,7 @@ extern char __dtb_z_imx7d_flex_concentrator_mfg_start[]; static inline void setup_uart(void) { - /* FIXME: Below UART4 is muxed, not UART1 */ - imx7_early_setup_uart_clock(1); + imx7_early_setup_uart_clock(4); imx7_setup_pad(MX7D_PAD_SAI2_TX_BCLK__UART4_DCE_TX); -- cgit v1.2.3 From d78e72d86a0adb717f10755e0ff318064b7d2e81 Mon Sep 17 00:00:00 2001 From: Robin van der Gracht Date: Wed, 2 Nov 2022 14:53:14 +0100 Subject: ARM: mach-imx: Add missing ocotp dependency to protonic-imx6 platform The protonic-imx6 board code calls imx_ocotp_read/write_field functions. Compiling without IMX_OCOTP results in a build failure. Signed-off-by: Robin van der Gracht Link: https://lore.barebox.org/20221102135314.123789-1-robin@protonic.nl Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index d6c6c720d4..dd9aaf8041 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -350,6 +350,7 @@ config MACH_PROTONIC_IMX6 select ARCH_IMX6 select ARCH_IMX6UL select ARM_USE_COMPRESSED_DTB + select IMX_OCOTP config MACH_PROTONIC_IMX8M bool "Protonic-Holland i.MX8Mx based boards" -- cgit v1.2.3