From 62597d25514e3e36e891c626620624755d8cb56d Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 29 Apr 2020 10:35:10 +0800 Subject: [PATCH 01/82] spl: sdp: call board_usb_init at spl_sdp_load_image Need initialize UDC before run sdp download Signed-off-by: Frank Li Signed-off-by: Peng Fan --- common/spl/spl_sdp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/spl/spl_sdp.c b/common/spl/spl_sdp.c index 806bf1327ef..a54c7479d0b 100644 --- a/common/spl/spl_sdp.c +++ b/common/spl/spl_sdp.c @@ -16,6 +16,8 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image, int ret; const int controller_index = 0; + board_usb_init(0, USB_INIT_DEVICE); + g_dnl_clear_detach(); ret = g_dnl_register("usb_dnl_sdp"); if (ret) { From 8f95c0105f77dfc4f42babcdb725a55902a371f8 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 29 Apr 2020 10:35:11 +0800 Subject: [PATCH 02/82] usb: gadget: sdp: use CONFIG_SDP_LOADADDR as default load address If SDP_WRITE and SDP_JUMP addr is zero, use CONFIG_SDP_LOADADDR as default address Signed-off-by: Frank Li Signed-off-by: Peng Fan --- drivers/usb/gadget/Kconfig | 4 ++++ drivers/usb/gadget/f_sdp.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 58ca82d4de6..46aa3fe9543 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -122,6 +122,10 @@ config USB_GADGET_VBUS_DRAW This value will be used except for system-specific gadget drivers that have more specific information. +config SDP_LOADADDR + hex "Default load address at SDP_WRITE and SDP_JUMP" + default 0 + # Selected by UDC drivers that support high-speed operation. config USB_GADGET_DUALSPEED bool diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 50836db4a04..1732a3acf10 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -276,7 +276,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req) sdp->error_status = SDP_WRITE_FILE_COMPLETE; sdp->state = SDP_STATE_RX_FILE_DATA; - sdp->dnl_address = be32_to_cpu(cmd->addr); + sdp->dnl_address = cmd->addr ? be32_to_cpu(cmd->addr) : CONFIG_SDP_LOADADDR; sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt); sdp->dnl_bytes = sdp->dnl_bytes_remaining; sdp->next_state = SDP_STATE_IDLE; @@ -304,7 +304,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req) sdp->always_send_status = false; sdp->error_status = 0; - sdp->jmp_address = be32_to_cpu(cmd->addr); + sdp->jmp_address = cmd->addr ? be32_to_cpu(cmd->addr) : CONFIG_SDP_LOADADDR; sdp->state = SDP_STATE_TX_SEC_CONF; sdp->next_state = SDP_STATE_JUMP; break; From 407e3844fc8bafb5a648180ec33c2ca806c1a126 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 29 Apr 2020 10:35:12 +0800 Subject: [PATCH 03/82] spl: sdp: Add CONFIG_SPL_SDP_USB_DEV for USB device Add a new configuration CONFIG_SPL_SDP_USB_DEV to specify the usb index for spl sdp driver, so that we change use different device. The default value is 0. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- common/spl/Kconfig | 8 ++++++++ common/spl/spl_sdp.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 9feadb5e43e..6f37f756501 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1172,6 +1172,14 @@ config SPL_USB_SDP_SUPPORT Enable Serial Download Protocol (SDP) device support in SPL. This allows to download images into memory and execute (jump to) them using the same protocol as implemented by the i.MX family's boot ROM. + +config SPL_SDP_USB_DEV + int "SDP USB controller index" + default 0 + depends on SPL_USB_SDP_SUPPORT + help + Some boards have USB controller other than 0. Define this option + so it can be used in compiled environment. endif config SPL_WATCHDOG_SUPPORT diff --git a/common/spl/spl_sdp.c b/common/spl/spl_sdp.c index a54c7479d0b..82bce0bd2e7 100644 --- a/common/spl/spl_sdp.c +++ b/common/spl/spl_sdp.c @@ -14,9 +14,9 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret; - const int controller_index = 0; + const int controller_index = CONFIG_SPL_SDP_USB_DEV; - board_usb_init(0, USB_INIT_DEVICE); + board_usb_init(controller_index, USB_INIT_DEVICE); g_dnl_clear_detach(); ret = g_dnl_register("usb_dnl_sdp"); From 932c1ed328f7965e430dde98cd3403c39b22a4bc Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 29 Apr 2020 10:35:13 +0800 Subject: [PATCH 04/82] spl: sdp: Add a callback to clean up USB driver Because SDP directly jumps to next level boot image, we'd better clean up the USB driver before it. Implement a weak callback function, that spl sdp can use it to clean up USB driver. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- common/spl/spl_sdp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/spl/spl_sdp.c b/common/spl/spl_sdp.c index 82bce0bd2e7..d150951b86b 100644 --- a/common/spl/spl_sdp.c +++ b/common/spl/spl_sdp.c @@ -39,6 +39,7 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image, ret = spl_sdp_handle(controller_index, spl_image); debug("SDP ended\n"); + board_usb_cleanup(controller_index, USB_INIT_DEVICE); return ret; } SPL_LOAD_IMAGE_METHOD("USB SDP", 0, BOOT_DEVICE_BOARD, spl_sdp_load_image); From d8e775539e6d69a2bf9d4de721f6ad1560de7823 Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Wed, 29 Apr 2020 10:35:14 +0800 Subject: [PATCH 05/82] spl: sdp: Add DM gadget support for sdp When enable CONFG_SPL_DM_USB_GADGET, sdp should use usb_gadget_initialize() and usb_gadget_release() to support DM gadget driver. Signed-off-by: Sherry Sun Signed-off-by: Peng Fan --- common/spl/spl_sdp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/spl/spl_sdp.c b/common/spl/spl_sdp.c index d150951b86b..644dfa8cc3e 100644 --- a/common/spl/spl_sdp.c +++ b/common/spl/spl_sdp.c @@ -16,7 +16,7 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image, int ret; const int controller_index = CONFIG_SPL_SDP_USB_DEV; - board_usb_init(controller_index, USB_INIT_DEVICE); + usb_gadget_initialize(controller_index); g_dnl_clear_detach(); ret = g_dnl_register("usb_dnl_sdp"); @@ -39,7 +39,7 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image, ret = spl_sdp_handle(controller_index, spl_image); debug("SDP ended\n"); - board_usb_cleanup(controller_index, USB_INIT_DEVICE); + usb_gadget_release(controller_index); return ret; } SPL_LOAD_IMAGE_METHOD("USB SDP", 0, BOOT_DEVICE_BOARD, spl_sdp_load_image); From 4c809aee50f5128f815a7f272cdf2d30a1e1e76e Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 21:58:47 +0800 Subject: [PATCH 06/82] uclass: cpu: Add new API to get udevice for current CPU When running on SoC with multiple clusters, the boot CPU may not be fixed, saying booting from cluster A or cluster B. Add a API that can return the udevice for current boot CPU. Cpu driver needs to implement is_current_cpu interface for this feature, otherwise the API only returns the first udevice in cpu uclass. Reviewed-by: Simon Glass Signed-off-by: Peng Fan Signed-off-by: Ye Li --- drivers/cpu/cpu-uclass.c | 34 ++++++++++++++++++++++++++++++++++ include/cpu.h | 23 +++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c index 457f77b7c89..8352e2eb0bc 100644 --- a/drivers/cpu/cpu-uclass.c +++ b/drivers/cpu/cpu-uclass.c @@ -10,6 +10,7 @@ #include #include #include +#include int cpu_probe_all(void) { @@ -34,6 +35,39 @@ int cpu_probe_all(void) return 0; } +int cpu_is_current(struct udevice *cpu) +{ + struct cpu_ops *ops = cpu_get_ops(cpu); + + if (ops->is_current) { + if (ops->is_current(cpu)) + return 1; + } + + return -ENOSYS; +} + +struct udevice *cpu_get_current_dev(void) +{ + struct udevice *cpu; + int ret; + + uclass_foreach_dev_probe(UCLASS_CPU, cpu) { + if (cpu_is_current(cpu) > 0) + return cpu; + } + + /* If can't find current cpu device, use the first dev instead */ + ret = uclass_first_device_err(UCLASS_CPU, &cpu); + if (ret) { + debug("%s: Could not get CPU device (err = %d)\n", + __func__, ret); + return NULL; + } + + return cpu; +} + int cpu_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_ops *ops = cpu_get_ops(dev); diff --git a/include/cpu.h b/include/cpu.h index 6b1b6b37b3b..2f283fe2449 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -89,6 +89,15 @@ struct cpu_ops { * @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error */ int (*get_vendor)(struct udevice *dev, char *buf, int size); + + /** + * is_current() - Check if the CPU that U-Boot is currently running from + * + * @dev: Device to check (UCLASS_CPU) + * @return 1 if the CPU that U-Boot is currently running from, 0 + * if not. + */ + int (*is_current)(struct udevice *dev); }; #define cpu_get_ops(dev) ((struct cpu_ops *)(dev)->driver->ops) @@ -137,4 +146,18 @@ int cpu_get_vendor(struct udevice *dev, char *buf, int size); */ int cpu_probe_all(void); +/** + * cpu_is_current() - Check if the CPU that U-Boot is currently running from + * + * Return: 1 if yes, - 0 if not + */ +int cpu_is_current(struct udevice *cpu); + +/** + * cpu_get_current_dev() - Get CPU udevice for current CPU + * + * Return: udevice if OK, - NULL on error + */ +struct udevice *cpu_get_current_dev(void); + #endif From b1e894ff500819654cea82ab2f20cd4d91b4c5c2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 21:58:48 +0800 Subject: [PATCH 07/82] cpu: sandbox: support is_current Support querying whether U-Boot is running on current cpu Reviewed-by: Simon Glass Signed-off-by: Peng Fan --- drivers/cpu/cpu_sandbox.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c index 05b384f6a45..30a12e5a535 100644 --- a/drivers/cpu/cpu_sandbox.c +++ b/drivers/cpu/cpu_sandbox.c @@ -36,11 +36,20 @@ int cpu_sandbox_get_vendor(struct udevice *dev, char *buf, int size) return 0; } +int cpu_sandbox_is_current(struct udevice *dev) +{ + if (!strcmp(dev->name, "cpu-test1")) + return 1; + + return 0; +} + static const struct cpu_ops cpu_sandbox_ops = { .get_desc = cpu_sandbox_get_desc, .get_info = cpu_sandbox_get_info, .get_count = cpu_sandbox_get_count, .get_vendor = cpu_sandbox_get_vendor, + .is_current = cpu_sandbox_is_current, }; int cpu_sandbox_probe(struct udevice *dev) From 143f0eeddda915bfbd6c8024a667c37084d4bdc2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 21:58:49 +0800 Subject: [PATCH 08/82] test: cpu: test current cpu Add test whether the CPU is U-Boot is running from. Reviewed-by: Simon Glass Signed-off-by: Peng Fan --- test/dm/cpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/dm/cpu.c b/test/dm/cpu.c index e6dc576ea3c..def9b64a282 100644 --- a/test/dm/cpu.c +++ b/test/dm/cpu.c @@ -26,6 +26,8 @@ static int dm_test_cpu(struct unit_test_state *uts) ut_assert(dev->flags & DM_FLAG_ACTIVATED); ut_assertok(uclass_get_device_by_name(UCLASS_CPU, "cpu-test1", &dev)); + ut_asserteq_ptr(cpu_get_current_dev(), dev); + ut_asserteq(cpu_is_current(dev), 1); ut_assertok(cpu_get_desc(dev, text, sizeof(text))); ut_assertok(strcmp(text, "LEG Inc. SuperMegaUltraTurbo CPU No. 1")); From f5b66af2cb18b1577b2898413e98df7dcd9bc67f Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 21:58:50 +0800 Subject: [PATCH 09/82] common: board_f: Use cpu_get_current_dev in print_cpuinfo Current print_cpuinfo gets the first udevice in CPU class to return the cpu info. This has problem if the boot CPU is not fixed. Changing to use new API cpu_get_current_dev to fix the issue. Reviewed-by: Simon Glass Signed-off-by: Ye Li Signed-off-by: Peng Fan --- common/board_f.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/board_f.c b/common/board_f.c index 5c650f046cf..52234535112 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -183,11 +183,11 @@ static int print_cpuinfo(void) char desc[512]; int ret; - ret = uclass_first_device_err(UCLASS_CPU, &dev); - if (ret) { - debug("%s: Could not get CPU device (err = %d)\n", - __func__, ret); - return ret; + dev = cpu_get_current_dev(); + if (!dev) { + debug("%s: Could not get CPU device\n", + __func__); + return -ENODEV; } ret = cpu_get_desc(dev, desc, sizeof(desc)); From adb3bd7654467765ecb271a21953739679638f01 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 21:58:51 +0800 Subject: [PATCH 10/82] cpu: imx8: reimplement get cpu count Return 4 is not correct on i.MX8DX/DXL/8QM and etc. we need to count available cpu node with device_type "cpu". Reviewed-by: Simon Glass Signed-off-by: Peng Fan --- drivers/cpu/imx8_cpu.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 95653683ac2..7c54c290b88 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -118,7 +118,24 @@ static int cpu_imx_get_info(struct udevice *dev, struct cpu_info *info) static int cpu_imx_get_count(struct udevice *dev) { - return 4; + ofnode node; + int num = 0; + + ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { + const char *device_type; + + if (!ofnode_is_available(node)) + continue; + + device_type = ofnode_read_string(node, "device_type"); + if (!device_type) + continue; + + if (!strcmp(device_type, "cpu")) + num++; + } + + return num; } static int cpu_imx_get_vendor(struct udevice *dev, char *buf, int size) From 177f9996d3cdf04a592bc0fece640cf4d492d1cb Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 21:58:52 +0800 Subject: [PATCH 11/82] cpu: imx8: support a72 as boot cpu Support booting i.MX8QM with A72 as boot cpu Reviewed-by: Simon Glass Signed-off-by: Peng Fan --- drivers/cpu/imx8_cpu.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 7c54c290b88..c4679e1642c 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -20,6 +20,7 @@ struct cpu_imx_platdata { const char *type; u32 cpurev; u32 freq_mhz; + u32 mpidr; }; const char *get_imx8_type(u32 imxtype) @@ -144,16 +145,28 @@ static int cpu_imx_get_vendor(struct udevice *dev, char *buf, int size) return 0; } +static int cpu_imx_is_current(struct udevice *dev) +{ + struct cpu_imx_platdata *plat = dev_get_platdata(dev); + + if (plat->mpidr == (read_mpidr() & 0xffff)) + return 1; + + return 0; +} + static const struct cpu_ops cpu_imx8_ops = { .get_desc = cpu_imx_get_desc, .get_info = cpu_imx_get_info, .get_count = cpu_imx_get_count, .get_vendor = cpu_imx_get_vendor, + .is_current = cpu_imx_is_current, }; static const struct udevice_id cpu_imx8_ids[] = { { .compatible = "arm,cortex-a35" }, { .compatible = "arm,cortex-a53" }, + { .compatible = "arm,cortex-a72" }, { } }; @@ -185,6 +198,12 @@ static int imx8_cpu_probe(struct udevice *dev) plat->rev = get_imx8_rev(cpurev & 0xFFF); plat->type = get_imx8_type((cpurev & 0xFF000) >> 12); plat->freq_mhz = imx8_get_cpu_rate() / 1000000; + plat->mpidr = dev_read_addr(dev); + if (plat->mpidr == FDT_ADDR_T_NONE) { + printf("%s: Failed to get CPU reg property\n", __func__); + return -EINVAL; + } + return 0; } From 55bc96f3b675d719a473a8985636e76381b18cb8 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 21:58:53 +0800 Subject: [PATCH 12/82] cpu: imx8: fix get core name and rate When current cpu is A53, using is_cortex_a53 could not detect A72 information, so check cpu device compatible property to get the correct information. Reviewed-by: Simon Glass Signed-off-by: Peng Fan --- drivers/cpu/imx8_cpu.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index c4679e1642c..cd11b78d061 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -48,13 +48,13 @@ const char *get_imx8_rev(u32 rev) } } -const char *get_core_name(void) +const char *get_core_name(struct udevice *dev) { - if (is_cortex_a35()) + if (!device_is_compatible(dev, "arm,cortex-a35")) return "A35"; - else if (is_cortex_a53()) + else if (!device_is_compatible(dev, "arm,cortex-a53")) return "A53"; - else if (is_cortex_a72()) + else if (!device_is_compatible(dev, "arm,cortex-a72")) return "A72"; else return "?"; @@ -170,12 +170,19 @@ static const struct udevice_id cpu_imx8_ids[] = { { } }; -static ulong imx8_get_cpu_rate(void) +static ulong imx8_get_cpu_rate(struct udevice *dev) { ulong rate; - int ret; - int type = is_cortex_a35() ? SC_R_A35 : is_cortex_a53() ? - SC_R_A53 : SC_R_A72; + int ret, type; + + if (!device_is_compatible(dev, "arm,cortex-a35")) + type = SC_R_A35; + else if (!device_is_compatible(dev, "arm,cortex-a53")) + type = SC_R_A53; + else if (!device_is_compatible(dev, "arm,cortex-a72")) + type = SC_R_A72; + else + return 0; ret = sc_pm_get_clock_rate(-1, type, SC_PM_CLK_CPU, (sc_pm_clock_rate_t *)&rate); @@ -194,10 +201,10 @@ static int imx8_cpu_probe(struct udevice *dev) cpurev = get_cpu_rev(); plat->cpurev = cpurev; - plat->name = get_core_name(); + plat->name = get_core_name(dev); plat->rev = get_imx8_rev(cpurev & 0xFFF); plat->type = get_imx8_type((cpurev & 0xFF000) >> 12); - plat->freq_mhz = imx8_get_cpu_rate() / 1000000; + plat->freq_mhz = imx8_get_cpu_rate(dev) / 1000000; plat->mpidr = dev_read_addr(dev); if (plat->mpidr == FDT_ADDR_T_NONE) { printf("%s: Failed to get CPU reg property\n", __func__); From 3ee6ea443eb466399ab325a58b377326ac5c57b5 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 21:58:54 +0800 Subject: [PATCH 13/82] cpu: imx_cpu: Print the CPU temperature for iMX8QM A72 iMX8QM registers two thermal devices for CPUs, get the temperature from "cpu-thermal1" device for A72 Reviewed-by: Simon Glass Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/cpu/imx8_cpu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index cd11b78d061..85ba7b7df2c 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -61,13 +61,15 @@ const char *get_core_name(struct udevice *dev) } #if IS_ENABLED(CONFIG_IMX_SCU_THERMAL) -static int cpu_imx_get_temp(void) +static int cpu_imx_get_temp(struct cpu_imx_platdata *plat) { struct udevice *thermal_dev; int cpu_tmp, ret; - ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0", - &thermal_dev); + if (!strcmp(plat->name, "A72")) + ret = uclass_get_device(UCLASS_THERMAL, 1, &thermal_dev); + else + ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev); if (!ret) { ret = thermal_get_temp(thermal_dev, &cpu_tmp); @@ -80,7 +82,7 @@ static int cpu_imx_get_temp(void) return cpu_tmp; } #else -static int cpu_imx_get_temp(void) +static int cpu_imx_get_temp(struct cpu_imx_platdata *plat) { return 0; } @@ -89,7 +91,7 @@ static int cpu_imx_get_temp(void) int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_imx_platdata *plat = dev_get_platdata(dev); - int ret; + int ret, temp; if (size < 100) return -ENOSPC; @@ -98,9 +100,13 @@ int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) plat->type, plat->rev, plat->name, plat->freq_mhz); if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) { + temp = cpu_imx_get_temp(plat); buf = buf + ret; size = size - ret; - ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp()); + if (temp != 0xdeadbeef) + ret = snprintf(buf, size, " at %dC", temp); + else + ret = snprintf(buf, size, " - invalid sensor data"); } snprintf(buf + ret, size - ret, "\n"); From 8142a97d541ef1473925b3677d6bf86bcddb69ac Mon Sep 17 00:00:00 2001 From: Frank Li Date: Sun, 3 May 2020 21:58:55 +0800 Subject: [PATCH 14/82] cpu: imx8: show RevC instead of Rev? at boot log Add REVC informaiton. Reviewed-by: Simon Glass Signed-off-by: Frank Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx/cpu.h | 1 + drivers/cpu/imx8_cpu.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index b52565473d5..e9c00789226 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -64,6 +64,7 @@ #define CHIP_REV_A 0x0 #define CHIP_REV_B 0x1 +#define CHIP_REV_C 0x2 #define BOARD_REV_1_0 0x0 #define BOARD_REV_2_0 0x1 diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 85ba7b7df2c..95c14c98d86 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -43,6 +43,8 @@ const char *get_imx8_rev(u32 rev) return "A"; case CHIP_REV_B: return "B"; + case CHIP_REV_C: + return "C"; default: return "?"; } From b52fb0b0b5da80a059ba982139401e57ac4e9a2e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 29 Apr 2020 20:09:08 +0200 Subject: [PATCH 15/82] ARM: imx: pico-imx8mq: Add support for Technexion Pico-iMX8MQ Add initial support for Technexion Pico-iMX8MQ SoM on PicoPI carrier board. Currently working is ethernet, serial, eMMC. DT is imported from Linux 5.4.28 ("462afcd6e7ea") . Signed-off-by: Marek Vasut Cc: Stefano Babic Cc: Fabio Estevam Cc: "NXP i.MX U-Boot Team" Cc: Peng Fan Reviewed-by: Stefano Babic --- arch/arm/dts/Makefile | 3 +- arch/arm/dts/imx8mq-pico-pi.dts | 420 ++++ arch/arm/mach-imx/imx8m/Kconfig | 6 + board/technexion/pico-imx8mq/Kconfig | 12 + board/technexion/pico-imx8mq/MAINTAINERS | 6 + board/technexion/pico-imx8mq/Makefile | 12 + board/technexion/pico-imx8mq/README | 52 + board/technexion/pico-imx8mq/lpddr4_timing.h | 14 + .../pico-imx8mq/lpddr4_timing_1gb.c | 1734 +++++++++++++++++ .../pico-imx8mq/lpddr4_timing_2gb.c | 1734 +++++++++++++++++ .../pico-imx8mq/lpddr4_timing_3gb.c | 1734 +++++++++++++++++ .../pico-imx8mq/lpddr4_timing_4gb.c | 1734 +++++++++++++++++ board/technexion/pico-imx8mq/pico-imx8mq.c | 146 ++ board/technexion/pico-imx8mq/spl.c | 223 +++ configs/pico-imx8mq_defconfig | 47 + include/configs/pico-imx8mq.h | 199 ++ 16 files changed, 8075 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx8mq-pico-pi.dts create mode 100644 board/technexion/pico-imx8mq/Kconfig create mode 100644 board/technexion/pico-imx8mq/MAINTAINERS create mode 100644 board/technexion/pico-imx8mq/Makefile create mode 100644 board/technexion/pico-imx8mq/README create mode 100644 board/technexion/pico-imx8mq/lpddr4_timing.h create mode 100644 board/technexion/pico-imx8mq/lpddr4_timing_1gb.c create mode 100644 board/technexion/pico-imx8mq/lpddr4_timing_2gb.c create mode 100644 board/technexion/pico-imx8mq/lpddr4_timing_3gb.c create mode 100644 board/technexion/pico-imx8mq/lpddr4_timing_4gb.c create mode 100644 board/technexion/pico-imx8mq/pico-imx8mq.c create mode 100644 board/technexion/pico-imx8mq/spl.c create mode 100644 configs/pico-imx8mq_defconfig create mode 100644 include/configs/pico-imx8mq.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 559d3ab6a7a..121597756ea 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -737,7 +737,8 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mn-ddr4-evk.dtb \ imx8mq-evk.dtb \ imx8mq-phanbell.dtb \ - imx8mp-evk.dtb + imx8mp-evk.dtb \ + imx8mq-pico-pi.dtb dtb-$(CONFIG_ARCH_IMXRT) += imxrt1050-evk.dtb \ imxrt1020-evk.dtb diff --git a/arch/arm/dts/imx8mq-pico-pi.dts b/arch/arm/dts/imx8mq-pico-pi.dts new file mode 100644 index 00000000000..d2af18ad0e1 --- /dev/null +++ b/arch/arm/dts/imx8mq-pico-pi.dts @@ -0,0 +1,420 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Wandboard, Org. + * Copyright 2017 NXP + * + * Author: Richard Hu + */ + +/dts-v1/; + +#include "imx8mq.dtsi" + +/ { + model = "TechNexion PICO-PI-8M"; + compatible = "technexion,pico-pi-imx8m", "fsl,imx8mq"; + + chosen { + stdout-path = &uart1; + }; + + pmic_osc: clock-pmic { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "pmic_osc"; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_otg_vbus>; + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 14 GPIO_ACTIVE_LOW>; + }; + + reg_eth_phy: eth_phy { + compatible = "regulator-fixed"; + regulator-name = "eth_phy_pwr"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + phy-supply = <®_eth_phy>; + phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + phy-reset-duration = <100>; + phy-reset-post-delay = <100>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic: pmic@4b { + reg = <0x4b>; + compatible = "rohm,bd71837"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + clocks = <&pmic_osc>; + clock-names = "osc"; + clock-output-names = "pmic_clk"; + interrupt-parent = <&gpio1>; + interrupts = <3 GPIO_ACTIVE_LOW>; + interrupt-names = "irq"; + + regulators { + buck1: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <900000>; + rohm,dvs-idle-voltage = <850000>; + rohm,dvs-suspend-voltage = <800000>; + }; + + buck2: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + buck3: BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + rohm,dvs-run-voltage = <1000000>; + }; + + buck4: BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + rohm,dvs-run-voltage = <1000000>; + }; + + buck5: BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + }; + + buck6: BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + buck7: BUCK7 { + regulator-name = "buck7"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + }; + + buck8: BUCK8 { + regulator-name = "buck8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + }; + + ldo1: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + ldo4: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + ldo5: LDO5 { + regulator-name = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + ldo6: LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + ldo7: LDO7 { + regulator-name = "ldo7"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + }; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&uart1 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + bus-width = <4>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usb_dwc3_1 { + dr_mode = "host"; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 + MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x19 + MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f + MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f + >; + }; + + pinctrl_otg_vbus: otgvbusgrp { + fsl,pins = < + MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14 0x19 /* USB OTG VBUS Enable */ + >; + }; + + pinctrl_pmic: pmicirq { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49 + MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49 + MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49 + MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B 0x49 + MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B 0x49 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc5 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc5 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc5 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc5 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc5 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc5 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc5 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc5 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x85 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc7 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc7 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc7 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc7 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc7 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc7 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc7 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc7 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x87 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2grpgpio { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; +}; diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 895f9037809..7d1fe758e66 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -55,6 +55,11 @@ config TARGET_IMX8MP_EVK select SUPPORT_SPL select IMX8M_LPDDR4 +config TARGET_PICO_IMX8MQ + bool "Support Technexion Pico iMX8MQ" + select IMX8MQ + select IMX8M_LPDDR4 + config TARGET_VERDIN_IMX8MM bool "Support Toradex Verdin iMX8M Mini module" select IMX8MM @@ -68,6 +73,7 @@ source "board/freescale/imx8mm_evk/Kconfig" source "board/freescale/imx8mn_evk/Kconfig" source "board/freescale/imx8mp_evk/Kconfig" source "board/google/imx8mq_phanbell/Kconfig" +source "board/technexion/pico-imx8mq/Kconfig" source "board/toradex/verdin-imx8mm/Kconfig" endif diff --git a/board/technexion/pico-imx8mq/Kconfig b/board/technexion/pico-imx8mq/Kconfig new file mode 100644 index 00000000000..031fc1d5636 --- /dev/null +++ b/board/technexion/pico-imx8mq/Kconfig @@ -0,0 +1,12 @@ +if TARGET_PICO_IMX8MQ + +config SYS_BOARD + default "pico-imx8mq" + +config SYS_VENDOR + default "technexion" + +config SYS_CONFIG_NAME + default "pico-imx8mq" + +endif diff --git a/board/technexion/pico-imx8mq/MAINTAINERS b/board/technexion/pico-imx8mq/MAINTAINERS new file mode 100644 index 00000000000..626e7337a1e --- /dev/null +++ b/board/technexion/pico-imx8mq/MAINTAINERS @@ -0,0 +1,6 @@ +PICOPI IMX8MQ BOARD +M: Marek Vasut +S: Maintained +F: board/technexion/pico-imx8mq/ +F: include/configs/pico-imx8mq.h +F: configs/pico-imx8mq_defconfig diff --git a/board/technexion/pico-imx8mq/Makefile b/board/technexion/pico-imx8mq/Makefile new file mode 100644 index 00000000000..7cfe1e02ef9 --- /dev/null +++ b/board/technexion/pico-imx8mq/Makefile @@ -0,0 +1,12 @@ +# +# Copyright 2017 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += pico-imx8mq.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing_1gb.o lpddr4_timing_2gb.o lpddr4_timing_3gb.o lpddr4_timing_4gb.o +endif diff --git a/board/technexion/pico-imx8mq/README b/board/technexion/pico-imx8mq/README new file mode 100644 index 00000000000..99fa332872e --- /dev/null +++ b/board/technexion/pico-imx8mq/README @@ -0,0 +1,52 @@ +U-Boot for the Technexion Pico i.MX8MQ + +Quick Start +=========== +- Build the TFA binary +- Get DDR and HDMI firmware +- Build U-Boot +- Boot + +Get and Build the TFA blob +========================== +Note: srctree is U-Boot source directory +Get ATF from: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git +branch: master +$ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=imx8mq bl31 +$ cp build/imx8mq/release/bl31.bin $(builddir) + +Get the DDR and HDMI firmware +============================= +$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.9.bin +$ chmod +x firmware-imx-7.9.bin +$ ./firmware-imx-7.9.bin +# Or use this to avoid running random scripts from the internet, +# but note that you must agree to the license the script displays: +# $ dd if=firmware-imx-7.9.bin of=firmware-imx-7.9.tar.bz2 bs=38868 skip=1 +# $ tar -xf firmware-imx-7.9.tar.bz2 +$ cp firmware-imx-7.9/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(builddir) +$ cp firmware-imx-7.9/firmware/ddr/synopsys/lpddr4*.bin $(builddir) + +Build U-Boot +============ +$ export CROSS_COMPILE=aarch64-poky-linux- +$ make pico-imx8mq_defconfig +$ make flash.bin + +Burn the flash.bin to MicroSD card offset 33KB +$ dd if=flash.bin of=/dev/mmcblkX bs=1024 seek=33 +Or into eMMC from a running system +$ dhcp flash.bin && mmc write $loadaddr 0x42 0x800 + +Boot +==== +"o" denotes a pin +"[]" denotes two pins bridged by a jumper + +eMMC boot: +J1 o[] []o J2 + []o o[] + +USB upload via USB-C connector: +J1 ooo ooo J2 + o[] []o diff --git a/board/technexion/pico-imx8mq/lpddr4_timing.h b/board/technexion/pico-imx8mq/lpddr4_timing.h new file mode 100644 index 00000000000..89b0b927bcb --- /dev/null +++ b/board/technexion/pico-imx8mq/lpddr4_timing.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Marek Vasut + */ + +#ifndef __LPDDR4_TIMING_H__ +#define __LPDDR4_TIMING_H__ + +extern struct dram_timing_info dram_timing_1gb; +extern struct dram_timing_info dram_timing_2gb; +extern struct dram_timing_info dram_timing_3gb; +extern struct dram_timing_info dram_timing_4gb; + +#endif /* __LPDDR4_TIMING_H__ */ diff --git a/board/technexion/pico-imx8mq/lpddr4_timing_1gb.c b/board/technexion/pico-imx8mq/lpddr4_timing_1gb.c new file mode 100644 index 00000000000..bcb852668ca --- /dev/null +++ b/board/technexion/pico-imx8mq/lpddr4_timing_1gb.c @@ -0,0 +1,1734 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + * Generated code from MX8M_DDR_tool + * Align with uboot-imx_v2018.03_4.14.78_1.0.0_ga + */ + +#include +#include +#include +#include + +static struct dram_cfg_param ddr_ddrc_cfg[] = { + /** Initialize DDRC registers **/ + {0x3d400304, 0x1}, + {0x3d400030, 0x1}, + {0x3d400000, 0xa1080020}, + {0x3d400028, 0x0}, + {0x3d400020, 0x203}, + {0x3d400024, 0x3e800}, + {0x3d400064, 0x610090}, + {0x3d4000d0, 0xc003061c}, + {0x3d4000d4, 0x9e0000}, + {0x3d4000dc, 0xd4002d}, + {0x3d4000e0, 0x310008}, + {0x3d4000e8, 0x66004a}, + {0x3d4000ec, 0x16004a}, + {0x3d400100, 0x1a201b22}, + {0x3d400104, 0x60633}, + {0x3d40010c, 0xc0c000}, + {0x3d400110, 0xf04080f}, + {0x3d400114, 0x2040c0c}, + {0x3d400118, 0x1010007}, + {0x3d40011c, 0x401}, + {0x3d400130, 0x20600}, + {0x3d400134, 0xc100002}, + {0x3d400138, 0x96}, + {0x3d400144, 0xa00050}, + {0x3d400180, 0xc3200018}, + {0x3d400184, 0x28061a8}, + {0x3d400188, 0x0}, + {0x3d400190, 0x497820a}, + {0x3d400194, 0x80303}, + {0x3d4001a0, 0xe0400018}, + {0x3d4001a4, 0xdf00e4}, + {0x3d4001a8, 0x80000000}, + {0x3d4001b0, 0x11}, + {0x3d4001b4, 0x170a}, + {0x3d4001c0, 0x1}, + {0x3d4001c4, 0x1}, + {0x3d4000f4, 0x639}, + {0x3d400108, 0x70e1617}, + {0x3d400200, 0x1f}, + {0x3d40020c, 0x0}, + {0x3d400210, 0x1f1f}, + {0x3d400204, 0x80808}, + {0x3d400214, 0x7070707}, + {0x3d400218, 0xf070707}, + {0x3d402020, 0x1}, + {0x3d402024, 0xd0c0}, + {0x3d402050, 0x20d040}, + {0x3d402064, 0x14001f}, + {0x3d4020dc, 0x940009}, + {0x3d4020e0, 0x310000}, + {0x3d4020e8, 0x66004a}, + {0x3d4020ec, 0x16004a}, + {0x3d402100, 0xb070508}, + {0x3d402104, 0x3040b}, + {0x3d402108, 0x305090c}, + {0x3d40210c, 0x505000}, + {0x3d402110, 0x4040204}, + {0x3d402114, 0x2030303}, + {0x3d402118, 0x1010004}, + {0x3d40211c, 0x301}, + {0x3d402130, 0x20300}, + {0x3d402134, 0xa100002}, + {0x3d402138, 0x20}, + {0x3d402144, 0x220011}, + {0x3d402180, 0xc0a70006}, + {0x3d402190, 0x3858202}, + {0x3d402194, 0x80303}, + {0x3d4021b4, 0x502}, + {0x3d400244, 0x0}, + {0x3d400250, 0x29001505}, + {0x3d400254, 0x2c}, + {0x3d40025c, 0x5900575b}, + {0x3d400264, 0x90000096}, + {0x3d40026c, 0x1000012c}, + {0x3d400300, 0x16}, + {0x3d400304, 0x0}, + {0x3d40030c, 0x0}, + {0x3d400320, 0x1}, + {0x3d40036c, 0x11}, + {0x3d400400, 0x111}, + {0x3d400404, 0x10f3}, + {0x3d400408, 0x72ff}, + {0x3d400490, 0x1}, + {0x3d400494, 0xe00}, + {0x3d400498, 0x62ffff}, + {0x3d40049c, 0xe00}, + {0x3d4004a0, 0xffff}, +}; + +/* PHY Initialize Configuration */ +static struct dram_cfg_param ddr_ddrphy_cfg[] = { + {0x100a0, 0x0}, + {0x100a1, 0x1}, + {0x100a2, 0x2}, + {0x100a3, 0x3}, + {0x100a4, 0x4}, + {0x100a5, 0x5}, + {0x100a6, 0x6}, + {0x100a7, 0x7}, + {0x110a0, 0x0}, + {0x110a1, 0x1}, + {0x110a2, 0x2}, + {0x110a3, 0x3}, + {0x110a4, 0x4}, + {0x110a5, 0x5}, + {0x110a6, 0x6}, + {0x110a7, 0x7}, + {0x120a0, 0x0}, + {0x120a1, 0x1}, + {0x120a2, 0x2}, + {0x120a3, 0x3}, + {0x120a4, 0x4}, + {0x120a5, 0x5}, + {0x120a6, 0x6}, + {0x120a7, 0x7}, + {0x130a0, 0x0}, + {0x130a1, 0x1}, + {0x130a2, 0x2}, + {0x130a3, 0x3}, + {0x130a4, 0x4}, + {0x130a5, 0x5}, + {0x130a6, 0x6}, + {0x130a7, 0x7}, + {0x20110, 0x2}, + {0x20111, 0x3}, + {0x20112, 0x4}, + {0x20113, 0x5}, + {0x20114, 0x0}, + {0x20115, 0x1}, + {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}, + {0x55, 0x1ff}, + {0x1055, 0x1ff}, + {0x2055, 0x1ff}, + {0x3055, 0x1ff}, + {0x4055, 0x1ff}, + {0x5055, 0x1ff}, + {0x6055, 0x1ff}, + {0x7055, 0x1ff}, + {0x8055, 0x1ff}, + {0x9055, 0x1ff}, + {0x200c5, 0x19}, + {0x1200c5, 0x7}, + {0x2002e, 0x2}, + {0x12002e, 0x1}, + {0x90204, 0x0}, + {0x190204, 0x0}, + {0x20024, 0x1ab}, + {0x2003a, 0x0}, + {0x120024, 0x1ab}, + {0x2003a, 0x0}, + {0x20056, 0x3}, + {0x120056, 0xa}, + {0x1004d, 0xe00}, + {0x1014d, 0xe00}, + {0x1104d, 0xe00}, + {0x1114d, 0xe00}, + {0x1204d, 0xe00}, + {0x1214d, 0xe00}, + {0x1304d, 0xe00}, + {0x1314d, 0xe00}, + {0x11004d, 0xe00}, + {0x11014d, 0xe00}, + {0x11104d, 0xe00}, + {0x11114d, 0xe00}, + {0x11204d, 0xe00}, + {0x11214d, 0xe00}, + {0x11304d, 0xe00}, + {0x11314d, 0xe00}, + {0x10049, 0xeba}, + {0x10149, 0xeba}, + {0x11049, 0xeba}, + {0x11149, 0xeba}, + {0x12049, 0xeba}, + {0x12149, 0xeba}, + {0x13049, 0xeba}, + {0x13149, 0xeba}, + {0x110049, 0xeba}, + {0x110149, 0xeba}, + {0x111049, 0xeba}, + {0x111149, 0xeba}, + {0x112049, 0xeba}, + {0x112149, 0xeba}, + {0x113049, 0xeba}, + {0x113149, 0xeba}, + {0x43, 0x63}, + {0x1043, 0x63}, + {0x2043, 0x63}, + {0x3043, 0x63}, + {0x4043, 0x63}, + {0x5043, 0x63}, + {0x6043, 0x63}, + {0x7043, 0x63}, + {0x8043, 0x63}, + {0x9043, 0x63}, + {0x20018, 0x3}, + {0x20075, 0x4}, + {0x20050, 0x0}, + {0x20008, 0x320}, + {0x120008, 0xa7}, + {0x20088, 0x9}, + {0x200b2, 0xdc}, + {0x10043, 0x5a1}, + {0x10143, 0x5a1}, + {0x11043, 0x5a1}, + {0x11143, 0x5a1}, + {0x12043, 0x5a1}, + {0x12143, 0x5a1}, + {0x13043, 0x5a1}, + {0x13143, 0x5a1}, + {0x1200b2, 0xdc}, + {0x110043, 0x5a1}, + {0x110143, 0x5a1}, + {0x111043, 0x5a1}, + {0x111143, 0x5a1}, + {0x112043, 0x5a1}, + {0x112143, 0x5a1}, + {0x113043, 0x5a1}, + {0x113143, 0x5a1}, + {0x200fa, 0x1}, + {0x1200fa, 0x1}, + {0x20019, 0x1}, + {0x120019, 0x1}, + {0x200f0, 0x0}, + {0x200f1, 0x0}, + {0x200f2, 0x4444}, + {0x200f3, 0x8888}, + {0x200f4, 0x5555}, + {0x200f5, 0x0}, + {0x200f6, 0x0}, + {0x200f7, 0xf000}, + {0x20025, 0x0}, + {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x200c7, 0x80}, + {0x1200c7, 0x80}, + {0x200ca, 0x106}, + {0x1200ca, 0x106}, +}; + +/* 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, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x131f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P1 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x1}, + {0x54003, 0x29c}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x994}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x994}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0x9400}, + {0x54033, 0x3109}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0x9400}, + {0x54039, 0x3109}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P0 2D message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { + {0xd0000, 0x0}, + {0x54003, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x61}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400f, 0x100}, + {0x54010, 0x1f7f}, + {0x54012, 0x110}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + { 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, 0xf}, + {0x90039, 0x7c0}, + {0x9003a, 0x139}, + {0x9003b, 0x44}, + {0x9003c, 0x630}, + {0x9003d, 0x159}, + {0x9003e, 0x14f}, + {0x9003f, 0x630}, + {0x90040, 0x159}, + {0x90041, 0x47}, + {0x90042, 0x630}, + {0x90043, 0x149}, + {0x90044, 0x4f}, + {0x90045, 0x630}, + {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, 0x630}, + {0x90058, 0x179}, + {0x90059, 0x1}, + {0x9005a, 0x618}, + {0x9005b, 0x109}, + {0x9005c, 0x40c0}, + {0x9005d, 0x630}, + {0x9005e, 0x149}, + {0x9005f, 0x8}, + {0x90060, 0x4}, + {0x90061, 0x48}, + {0x90062, 0x4040}, + {0x90063, 0x630}, + {0x90064, 0x149}, + {0x90065, 0x0}, + {0x90066, 0x4}, + {0x90067, 0x48}, + {0x90068, 0x40}, + {0x90069, 0x630}, + {0x9006a, 0x149}, + {0x9006b, 0x10}, + {0x9006c, 0x4}, + {0x9006d, 0x18}, + {0x9006e, 0x0}, + {0x9006f, 0x4}, + {0x90070, 0x78}, + {0x90071, 0x549}, + {0x90072, 0x630}, + {0x90073, 0x159}, + {0x90074, 0xd49}, + {0x90075, 0x630}, + {0x90076, 0x159}, + {0x90077, 0x94a}, + {0x90078, 0x630}, + {0x90079, 0x159}, + {0x9007a, 0x441}, + {0x9007b, 0x630}, + {0x9007c, 0x149}, + {0x9007d, 0x42}, + {0x9007e, 0x630}, + {0x9007f, 0x149}, + {0x90080, 0x1}, + {0x90081, 0x630}, + {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, 0xa}, + {0x9009c, 0x10}, + {0x9009d, 0x109}, + {0x9009e, 0x2}, + {0x9009f, 0x10}, + {0x900a0, 0x109}, + {0x900a1, 0x5}, + {0x900a2, 0x7c0}, + {0x900a3, 0x109}, + {0x900a4, 0x10}, + {0x900a5, 0x10}, + {0x900a6, 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, 0x623}, + {0x4002b, 0x15}, + {0x4004b, 0x0}, + {0x4006b, 0x0}, + {0x4000c, 0x4028}, + {0x4002c, 0x80}, + {0x4004c, 0x0}, + {0x4006c, 0x0}, + {0x4000d, 0xe08}, + {0x4002d, 0xc1a}, + {0x4004d, 0x0}, + {0x4006d, 0x0}, + {0x4000e, 0x623}, + {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}, + {0x900a7, 0x0}, + {0x900a8, 0x790}, + {0x900a9, 0x11a}, + {0x900aa, 0x8}, + {0x900ab, 0x7aa}, + {0x900ac, 0x2a}, + {0x900ad, 0x10}, + {0x900ae, 0x7b2}, + {0x900af, 0x2a}, + {0x900b0, 0x0}, + {0x900b1, 0x7c8}, + {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, 0x0}, + {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, 0xc}, + {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, 0x0}, + {0x90159, 0x400}, + {0x9015a, 0x10e}, + {0x9015b, 0x8}, + {0x9015c, 0xe8}, + {0x9015d, 0x109}, + {0x9015e, 0x0}, + {0x9015f, 0x8140}, + {0x90160, 0x10c}, + {0x90161, 0x10}, + {0x90162, 0x8138}, + {0x90163, 0x10c}, + {0x90164, 0x8}, + {0x90165, 0x7c8}, + {0x90166, 0x101}, + {0x90167, 0x8}, + {0x90168, 0x0}, + {0x90169, 0x8}, + {0x9016a, 0x8}, + {0x9016b, 0x448}, + {0x9016c, 0x109}, + {0x9016d, 0xf}, + {0x9016e, 0x7c0}, + {0x9016f, 0x109}, + {0x90170, 0x0}, + {0x90171, 0xe8}, + {0x90172, 0x109}, + {0x90173, 0x47}, + {0x90174, 0x630}, + {0x90175, 0x109}, + {0x90176, 0x8}, + {0x90177, 0x618}, + {0x90178, 0x109}, + {0x90179, 0x8}, + {0x9017a, 0xe0}, + {0x9017b, 0x109}, + {0x9017c, 0x0}, + {0x9017d, 0x7c8}, + {0x9017e, 0x109}, + {0x9017f, 0x8}, + {0x90180, 0x8140}, + {0x90181, 0x10c}, + {0x90182, 0x0}, + {0x90183, 0x1}, + {0x90184, 0x8}, + {0x90185, 0x8}, + {0x90186, 0x4}, + {0x90187, 0x8}, + {0x90188, 0x8}, + {0x90189, 0x7c8}, + {0x9018a, 0x101}, + {0x90006, 0x0}, + {0x90007, 0x0}, + {0x90008, 0x8}, + {0x90009, 0x0}, + {0x9000a, 0x0}, + {0x9000b, 0x0}, + {0xd00e7, 0x400}, + {0x90017, 0x0}, + {0x9001f, 0x2a}, + {0x90026, 0x6a}, + {0x400d0, 0x0}, + {0x400d1, 0x101}, + {0x400d2, 0x105}, + {0x400d3, 0x107}, + {0x400d4, 0x10f}, + {0x400d5, 0x202}, + {0x400d6, 0x20a}, + {0x400d7, 0x20b}, + {0x2003a, 0x2}, + {0x2000b, 0x64}, + {0x2000c, 0xc8}, + {0x2000d, 0x7d0}, + {0x2000e, 0x2c}, + {0x12000b, 0x14}, + {0x12000c, 0x29}, + {0x12000d, 0x1a1}, + {0x12000e, 0x10}, + {0x9000c, 0x0}, + {0x9000d, 0x173}, + {0x9000e, 0x60}, + {0x9000f, 0x6110}, + {0x90010, 0x2152}, + {0x90011, 0xdfbd}, + {0x90012, 0x60}, + {0x90013, 0x6152}, + {0x20010, 0x5a}, + {0x20011, 0x3}, + {0x120010, 0x5a}, + {0x120011, 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}, + {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}, + {0x2003a, 0x2}, + {0xc0080, 0x2}, + {0xd0000, 0x1} +}; + +static struct dram_fsp_msg ddr_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), + }, + { + /* P1 667mts 1D */ + .drate = 667, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .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_1gb = { + .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 = { 3200, 667, }, +}; + diff --git a/board/technexion/pico-imx8mq/lpddr4_timing_2gb.c b/board/technexion/pico-imx8mq/lpddr4_timing_2gb.c new file mode 100644 index 00000000000..9a8a323d63e --- /dev/null +++ b/board/technexion/pico-imx8mq/lpddr4_timing_2gb.c @@ -0,0 +1,1734 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + * Generated code from MX8M_DDR_tool + * Align with uboot-imx_v2018.03_4.14.78_1.0.0_ga + */ + +#include +#include +#include +#include + +static struct dram_cfg_param ddr_ddrc_cfg[] = { + /** Initialize DDRC registers **/ + {0x3d400304, 0x1}, + {0x3d400030, 0x1}, + {0x3d400000, 0xa1080020}, + {0x3d400028, 0x0}, + {0x3d400020, 0x203}, + {0x3d400024, 0x3e800}, + {0x3d400064, 0x6100e0}, + {0x3d4000d0, 0xc003061c}, + {0x3d4000d4, 0x9e0000}, + {0x3d4000dc, 0xd4002d}, + {0x3d4000e0, 0x310008}, + {0x3d4000e8, 0x66004a}, + {0x3d4000ec, 0x16004a}, + {0x3d400100, 0x1a201b22}, + {0x3d400104, 0x60633}, + {0x3d40010c, 0xc0c000}, + {0x3d400110, 0xf04080f}, + {0x3d400114, 0x2040c0c}, + {0x3d400118, 0x1010007}, + {0x3d40011c, 0x401}, + {0x3d400130, 0x20600}, + {0x3d400134, 0xc100002}, + {0x3d400138, 0xe6}, + {0x3d400144, 0xa00050}, + {0x3d400180, 0xc3200018}, + {0x3d400184, 0x28061a8}, + {0x3d400188, 0x0}, + {0x3d400190, 0x497820a}, + {0x3d400194, 0x80303}, + {0x3d4001a0, 0xe0400018}, + {0x3d4001a4, 0xdf00e4}, + {0x3d4001a8, 0x80000000}, + {0x3d4001b0, 0x11}, + {0x3d4001b4, 0x170a}, + {0x3d4001c0, 0x1}, + {0x3d4001c4, 0x1}, + {0x3d4000f4, 0x639}, + {0x3d400108, 0x70e1617}, + {0x3d400200, 0x1f}, + {0x3d40020c, 0x0}, + {0x3d400210, 0x1f1f}, + {0x3d400204, 0x80808}, + {0x3d400214, 0x7070707}, + {0x3d400218, 0x7070707}, + {0x3d402020, 0x1}, + {0x3d402024, 0xd0c0}, + {0x3d402050, 0x20d040}, + {0x3d402064, 0x14002f}, + {0x3d4020dc, 0x940009}, + {0x3d4020e0, 0x310000}, + {0x3d4020e8, 0x66004a}, + {0x3d4020ec, 0x16004a}, + {0x3d402100, 0xb070508}, + {0x3d402104, 0x3040b}, + {0x3d402108, 0x305090c}, + {0x3d40210c, 0x505000}, + {0x3d402110, 0x4040204}, + {0x3d402114, 0x2030303}, + {0x3d402118, 0x1010004}, + {0x3d40211c, 0x301}, + {0x3d402130, 0x20300}, + {0x3d402134, 0xa100002}, + {0x3d402138, 0x31}, + {0x3d402144, 0x220011}, + {0x3d402180, 0xc0a70006}, + {0x3d402190, 0x3858202}, + {0x3d402194, 0x80303}, + {0x3d4021b4, 0x502}, + {0x3d400244, 0x0}, + {0x3d400250, 0x29001505}, + {0x3d400254, 0x2c}, + {0x3d40025c, 0x5900575b}, + {0x3d400264, 0x90000096}, + {0x3d40026c, 0x1000012c}, + {0x3d400300, 0x16}, + {0x3d400304, 0x0}, + {0x3d40030c, 0x0}, + {0x3d400320, 0x1}, + {0x3d40036c, 0x11}, + {0x3d400400, 0x111}, + {0x3d400404, 0x10f3}, + {0x3d400408, 0x72ff}, + {0x3d400490, 0x1}, + {0x3d400494, 0xe00}, + {0x3d400498, 0x62ffff}, + {0x3d40049c, 0xe00}, + {0x3d4004a0, 0xffff}, +}; + +/* PHY Initialize Configuration */ +static struct dram_cfg_param ddr_ddrphy_cfg[] = { + {0x100a0, 0x0}, + {0x100a1, 0x1}, + {0x100a2, 0x2}, + {0x100a3, 0x3}, + {0x100a4, 0x4}, + {0x100a5, 0x5}, + {0x100a6, 0x6}, + {0x100a7, 0x7}, + {0x110a0, 0x0}, + {0x110a1, 0x1}, + {0x110a2, 0x2}, + {0x110a3, 0x3}, + {0x110a4, 0x4}, + {0x110a5, 0x5}, + {0x110a6, 0x6}, + {0x110a7, 0x7}, + {0x120a0, 0x0}, + {0x120a1, 0x1}, + {0x120a2, 0x2}, + {0x120a3, 0x3}, + {0x120a4, 0x4}, + {0x120a5, 0x5}, + {0x120a6, 0x6}, + {0x120a7, 0x7}, + {0x130a0, 0x0}, + {0x130a1, 0x1}, + {0x130a2, 0x2}, + {0x130a3, 0x3}, + {0x130a4, 0x4}, + {0x130a5, 0x5}, + {0x130a6, 0x6}, + {0x130a7, 0x7}, + {0x20110, 0x2}, + {0x20111, 0x3}, + {0x20112, 0x4}, + {0x20113, 0x5}, + {0x20114, 0x0}, + {0x20115, 0x1}, + {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}, + {0x55, 0x1ff}, + {0x1055, 0x1ff}, + {0x2055, 0x1ff}, + {0x3055, 0x1ff}, + {0x4055, 0x1ff}, + {0x5055, 0x1ff}, + {0x6055, 0x1ff}, + {0x7055, 0x1ff}, + {0x8055, 0x1ff}, + {0x9055, 0x1ff}, + {0x200c5, 0x19}, + {0x1200c5, 0x7}, + {0x2002e, 0x2}, + {0x12002e, 0x1}, + {0x90204, 0x0}, + {0x190204, 0x0}, + {0x20024, 0x1ab}, + {0x2003a, 0x0}, + {0x120024, 0x1ab}, + {0x2003a, 0x0}, + {0x20056, 0x3}, + {0x120056, 0xa}, + {0x1004d, 0xe00}, + {0x1014d, 0xe00}, + {0x1104d, 0xe00}, + {0x1114d, 0xe00}, + {0x1204d, 0xe00}, + {0x1214d, 0xe00}, + {0x1304d, 0xe00}, + {0x1314d, 0xe00}, + {0x11004d, 0xe00}, + {0x11014d, 0xe00}, + {0x11104d, 0xe00}, + {0x11114d, 0xe00}, + {0x11204d, 0xe00}, + {0x11214d, 0xe00}, + {0x11304d, 0xe00}, + {0x11314d, 0xe00}, + {0x10049, 0xeba}, + {0x10149, 0xeba}, + {0x11049, 0xeba}, + {0x11149, 0xeba}, + {0x12049, 0xeba}, + {0x12149, 0xeba}, + {0x13049, 0xeba}, + {0x13149, 0xeba}, + {0x110049, 0xeba}, + {0x110149, 0xeba}, + {0x111049, 0xeba}, + {0x111149, 0xeba}, + {0x112049, 0xeba}, + {0x112149, 0xeba}, + {0x113049, 0xeba}, + {0x113149, 0xeba}, + {0x43, 0x63}, + {0x1043, 0x63}, + {0x2043, 0x63}, + {0x3043, 0x63}, + {0x4043, 0x63}, + {0x5043, 0x63}, + {0x6043, 0x63}, + {0x7043, 0x63}, + {0x8043, 0x63}, + {0x9043, 0x63}, + {0x20018, 0x3}, + {0x20075, 0x4}, + {0x20050, 0x0}, + {0x20008, 0x320}, + {0x120008, 0xa7}, + {0x20088, 0x9}, + {0x200b2, 0xdc}, + {0x10043, 0x5a1}, + {0x10143, 0x5a1}, + {0x11043, 0x5a1}, + {0x11143, 0x5a1}, + {0x12043, 0x5a1}, + {0x12143, 0x5a1}, + {0x13043, 0x5a1}, + {0x13143, 0x5a1}, + {0x1200b2, 0xdc}, + {0x110043, 0x5a1}, + {0x110143, 0x5a1}, + {0x111043, 0x5a1}, + {0x111143, 0x5a1}, + {0x112043, 0x5a1}, + {0x112143, 0x5a1}, + {0x113043, 0x5a1}, + {0x113143, 0x5a1}, + {0x200fa, 0x1}, + {0x1200fa, 0x1}, + {0x20019, 0x1}, + {0x120019, 0x1}, + {0x200f0, 0x0}, + {0x200f1, 0x0}, + {0x200f2, 0x4444}, + {0x200f3, 0x8888}, + {0x200f4, 0x5555}, + {0x200f5, 0x0}, + {0x200f6, 0x0}, + {0x200f7, 0xf000}, + {0x20025, 0x0}, + {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x200c7, 0x80}, + {0x1200c7, 0x80}, + {0x200ca, 0x106}, + {0x1200ca, 0x106}, +}; + +/* 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, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x131f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P1 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x1}, + {0x54003, 0x29c}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x994}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x994}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0x9400}, + {0x54033, 0x3109}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0x9400}, + {0x54039, 0x3109}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P0 2D message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { + {0xd0000, 0x0}, + {0x54003, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x61}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400f, 0x100}, + {0x54010, 0x1f7f}, + {0x54012, 0x110}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x1}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + { 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, 0xf}, + {0x90039, 0x7c0}, + {0x9003a, 0x139}, + {0x9003b, 0x44}, + {0x9003c, 0x630}, + {0x9003d, 0x159}, + {0x9003e, 0x14f}, + {0x9003f, 0x630}, + {0x90040, 0x159}, + {0x90041, 0x47}, + {0x90042, 0x630}, + {0x90043, 0x149}, + {0x90044, 0x4f}, + {0x90045, 0x630}, + {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, 0x630}, + {0x90058, 0x179}, + {0x90059, 0x1}, + {0x9005a, 0x618}, + {0x9005b, 0x109}, + {0x9005c, 0x40c0}, + {0x9005d, 0x630}, + {0x9005e, 0x149}, + {0x9005f, 0x8}, + {0x90060, 0x4}, + {0x90061, 0x48}, + {0x90062, 0x4040}, + {0x90063, 0x630}, + {0x90064, 0x149}, + {0x90065, 0x0}, + {0x90066, 0x4}, + {0x90067, 0x48}, + {0x90068, 0x40}, + {0x90069, 0x630}, + {0x9006a, 0x149}, + {0x9006b, 0x10}, + {0x9006c, 0x4}, + {0x9006d, 0x18}, + {0x9006e, 0x0}, + {0x9006f, 0x4}, + {0x90070, 0x78}, + {0x90071, 0x549}, + {0x90072, 0x630}, + {0x90073, 0x159}, + {0x90074, 0xd49}, + {0x90075, 0x630}, + {0x90076, 0x159}, + {0x90077, 0x94a}, + {0x90078, 0x630}, + {0x90079, 0x159}, + {0x9007a, 0x441}, + {0x9007b, 0x630}, + {0x9007c, 0x149}, + {0x9007d, 0x42}, + {0x9007e, 0x630}, + {0x9007f, 0x149}, + {0x90080, 0x1}, + {0x90081, 0x630}, + {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, 0xa}, + {0x9009c, 0x10}, + {0x9009d, 0x109}, + {0x9009e, 0x2}, + {0x9009f, 0x10}, + {0x900a0, 0x109}, + {0x900a1, 0x5}, + {0x900a2, 0x7c0}, + {0x900a3, 0x109}, + {0x900a4, 0x10}, + {0x900a5, 0x10}, + {0x900a6, 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, 0x623}, + {0x4002b, 0x15}, + {0x4004b, 0x0}, + {0x4006b, 0x0}, + {0x4000c, 0x4028}, + {0x4002c, 0x80}, + {0x4004c, 0x0}, + {0x4006c, 0x0}, + {0x4000d, 0xe08}, + {0x4002d, 0xc1a}, + {0x4004d, 0x0}, + {0x4006d, 0x0}, + {0x4000e, 0x623}, + {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}, + {0x900a7, 0x0}, + {0x900a8, 0x790}, + {0x900a9, 0x11a}, + {0x900aa, 0x8}, + {0x900ab, 0x7aa}, + {0x900ac, 0x2a}, + {0x900ad, 0x10}, + {0x900ae, 0x7b2}, + {0x900af, 0x2a}, + {0x900b0, 0x0}, + {0x900b1, 0x7c8}, + {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, 0x0}, + {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, 0xc}, + {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, 0x0}, + {0x90159, 0x400}, + {0x9015a, 0x10e}, + {0x9015b, 0x8}, + {0x9015c, 0xe8}, + {0x9015d, 0x109}, + {0x9015e, 0x0}, + {0x9015f, 0x8140}, + {0x90160, 0x10c}, + {0x90161, 0x10}, + {0x90162, 0x8138}, + {0x90163, 0x10c}, + {0x90164, 0x8}, + {0x90165, 0x7c8}, + {0x90166, 0x101}, + {0x90167, 0x8}, + {0x90168, 0x0}, + {0x90169, 0x8}, + {0x9016a, 0x8}, + {0x9016b, 0x448}, + {0x9016c, 0x109}, + {0x9016d, 0xf}, + {0x9016e, 0x7c0}, + {0x9016f, 0x109}, + {0x90170, 0x0}, + {0x90171, 0xe8}, + {0x90172, 0x109}, + {0x90173, 0x47}, + {0x90174, 0x630}, + {0x90175, 0x109}, + {0x90176, 0x8}, + {0x90177, 0x618}, + {0x90178, 0x109}, + {0x90179, 0x8}, + {0x9017a, 0xe0}, + {0x9017b, 0x109}, + {0x9017c, 0x0}, + {0x9017d, 0x7c8}, + {0x9017e, 0x109}, + {0x9017f, 0x8}, + {0x90180, 0x8140}, + {0x90181, 0x10c}, + {0x90182, 0x0}, + {0x90183, 0x1}, + {0x90184, 0x8}, + {0x90185, 0x8}, + {0x90186, 0x4}, + {0x90187, 0x8}, + {0x90188, 0x8}, + {0x90189, 0x7c8}, + {0x9018a, 0x101}, + {0x90006, 0x0}, + {0x90007, 0x0}, + {0x90008, 0x8}, + {0x90009, 0x0}, + {0x9000a, 0x0}, + {0x9000b, 0x0}, + {0xd00e7, 0x400}, + {0x90017, 0x0}, + {0x9001f, 0x2a}, + {0x90026, 0x6a}, + {0x400d0, 0x0}, + {0x400d1, 0x101}, + {0x400d2, 0x105}, + {0x400d3, 0x107}, + {0x400d4, 0x10f}, + {0x400d5, 0x202}, + {0x400d6, 0x20a}, + {0x400d7, 0x20b}, + {0x2003a, 0x2}, + {0x2000b, 0x64}, + {0x2000c, 0xc8}, + {0x2000d, 0x7d0}, + {0x2000e, 0x2c}, + {0x12000b, 0x14}, + {0x12000c, 0x29}, + {0x12000d, 0x1a1}, + {0x12000e, 0x10}, + {0x9000c, 0x0}, + {0x9000d, 0x173}, + {0x9000e, 0x60}, + {0x9000f, 0x6110}, + {0x90010, 0x2152}, + {0x90011, 0xdfbd}, + {0x90012, 0x60}, + {0x90013, 0x6152}, + {0x20010, 0x5a}, + {0x20011, 0x3}, + {0x120010, 0x5a}, + {0x120011, 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}, + {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}, + {0x2003a, 0x2}, + {0xc0080, 0x2}, + {0xd0000, 0x1} +}; + +static struct dram_fsp_msg ddr_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), + }, + { + /* P1 667mts 1D */ + .drate = 667, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .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 = { + .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 = { 3200, 667, }, +}; + diff --git a/board/technexion/pico-imx8mq/lpddr4_timing_3gb.c b/board/technexion/pico-imx8mq/lpddr4_timing_3gb.c new file mode 100644 index 00000000000..0f74ce581c3 --- /dev/null +++ b/board/technexion/pico-imx8mq/lpddr4_timing_3gb.c @@ -0,0 +1,1734 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + * Generated code from MX8M_DDR_tool + * Align with uboot-imx_v2018.03_4.14.78_1.0.0_ga + */ + +#include +#include +#include +#include + +static struct dram_cfg_param ddr_ddrc_cfg[] = { + /** Initialize DDRC registers **/ + {0x3d400304, 0x1}, + {0x3d400030, 0x1}, + {0x3d400000, 0xa3080020}, + {0x3d400028, 0x0}, + {0x3d400020, 0x203}, + {0x3d400024, 0x3e800}, + {0x3d400064, 0x6100e0}, + {0x3d4000d0, 0xc003061c}, + {0x3d4000d4, 0x9e0000}, + {0x3d4000dc, 0xd4002d}, + {0x3d4000e0, 0x310008}, + {0x3d4000e8, 0x66004a}, + {0x3d4000ec, 0x16004a}, + {0x3d400100, 0x1a201b22}, + {0x3d400104, 0x60633}, + {0x3d40010c, 0xc0c000}, + {0x3d400110, 0xf04080f}, + {0x3d400114, 0x2040c0c}, + {0x3d400118, 0x1010007}, + {0x3d40011c, 0x401}, + {0x3d400130, 0x20600}, + {0x3d400134, 0xc100002}, + {0x3d400138, 0xe6}, + {0x3d400144, 0xa00050}, + {0x3d400180, 0xc3200018}, + {0x3d400184, 0x28061a8}, + {0x3d400188, 0x0}, + {0x3d400190, 0x497820a}, + {0x3d400194, 0x80303}, + {0x3d4001a0, 0xe0400018}, + {0x3d4001a4, 0xdf00e4}, + {0x3d4001a8, 0x80000000}, + {0x3d4001b0, 0x11}, + {0x3d4001b4, 0x170a}, + {0x3d4001c0, 0x1}, + {0x3d4001c4, 0x1}, + {0x3d4000f4, 0x639}, + {0x3d400108, 0x70e1617}, + {0x3d400200, 0x15}, + {0x3d40020c, 0x0}, + {0x3d400210, 0x1f1f}, + {0x3d400204, 0x80808}, + {0x3d400214, 0x7070707}, + {0x3d400218, 0x48080707}, + {0x3d402020, 0x1}, + {0x3d402024, 0xd0c0}, + {0x3d402050, 0x20d040}, + {0x3d402064, 0x14002f}, + {0x3d4020dc, 0x940009}, + {0x3d4020e0, 0x310000}, + {0x3d4020e8, 0x66004a}, + {0x3d4020ec, 0x16004a}, + {0x3d402100, 0xb070508}, + {0x3d402104, 0x3040b}, + {0x3d402108, 0x305090c}, + {0x3d40210c, 0x505000}, + {0x3d402110, 0x4040204}, + {0x3d402114, 0x2030303}, + {0x3d402118, 0x1010004}, + {0x3d40211c, 0x301}, + {0x3d402130, 0x20300}, + {0x3d402134, 0xa100002}, + {0x3d402138, 0x31}, + {0x3d402144, 0x220011}, + {0x3d402180, 0xc0a70006}, + {0x3d402190, 0x3858202}, + {0x3d402194, 0x80303}, + {0x3d4021b4, 0x502}, + {0x3d400244, 0x0}, + {0x3d400250, 0x29001505}, + {0x3d400254, 0x2c}, + {0x3d40025c, 0x5900575b}, + {0x3d400264, 0x90000096}, + {0x3d40026c, 0x1000012c}, + {0x3d400300, 0x16}, + {0x3d400304, 0x0}, + {0x3d40030c, 0x0}, + {0x3d400320, 0x1}, + {0x3d40036c, 0x11}, + {0x3d400400, 0x111}, + {0x3d400404, 0x10f3}, + {0x3d400408, 0x72ff}, + {0x3d400490, 0x1}, + {0x3d400494, 0xe00}, + {0x3d400498, 0x62ffff}, + {0x3d40049c, 0xe00}, + {0x3d4004a0, 0xffff}, +}; + +/* PHY Initialize Configuration */ +static struct dram_cfg_param ddr_ddrphy_cfg[] = { + {0x100a0, 0x0}, + {0x100a1, 0x1}, + {0x100a2, 0x2}, + {0x100a3, 0x3}, + {0x100a4, 0x4}, + {0x100a5, 0x5}, + {0x100a6, 0x6}, + {0x100a7, 0x7}, + {0x110a0, 0x0}, + {0x110a1, 0x1}, + {0x110a2, 0x2}, + {0x110a3, 0x3}, + {0x110a4, 0x4}, + {0x110a5, 0x5}, + {0x110a6, 0x6}, + {0x110a7, 0x7}, + {0x120a0, 0x0}, + {0x120a1, 0x1}, + {0x120a2, 0x2}, + {0x120a3, 0x3}, + {0x120a4, 0x4}, + {0x120a5, 0x5}, + {0x120a6, 0x6}, + {0x120a7, 0x7}, + {0x130a0, 0x0}, + {0x130a1, 0x1}, + {0x130a2, 0x2}, + {0x130a3, 0x3}, + {0x130a4, 0x4}, + {0x130a5, 0x5}, + {0x130a6, 0x6}, + {0x130a7, 0x7}, + {0x20110, 0x2}, + {0x20111, 0x3}, + {0x20112, 0x4}, + {0x20113, 0x5}, + {0x20114, 0x0}, + {0x20115, 0x1}, + {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}, + {0x55, 0x1ff}, + {0x1055, 0x1ff}, + {0x2055, 0x1ff}, + {0x3055, 0x1ff}, + {0x4055, 0x1ff}, + {0x5055, 0x1ff}, + {0x6055, 0x1ff}, + {0x7055, 0x1ff}, + {0x8055, 0x1ff}, + {0x9055, 0x1ff}, + {0x200c5, 0x19}, + {0x1200c5, 0x7}, + {0x2002e, 0x2}, + {0x12002e, 0x1}, + {0x90204, 0x0}, + {0x190204, 0x0}, + {0x20024, 0x1ab}, + {0x2003a, 0x0}, + {0x120024, 0x1ab}, + {0x2003a, 0x0}, + {0x20056, 0x3}, + {0x120056, 0xa}, + {0x1004d, 0xe00}, + {0x1014d, 0xe00}, + {0x1104d, 0xe00}, + {0x1114d, 0xe00}, + {0x1204d, 0xe00}, + {0x1214d, 0xe00}, + {0x1304d, 0xe00}, + {0x1314d, 0xe00}, + {0x11004d, 0xe00}, + {0x11014d, 0xe00}, + {0x11104d, 0xe00}, + {0x11114d, 0xe00}, + {0x11204d, 0xe00}, + {0x11214d, 0xe00}, + {0x11304d, 0xe00}, + {0x11314d, 0xe00}, + {0x10049, 0xeba}, + {0x10149, 0xeba}, + {0x11049, 0xeba}, + {0x11149, 0xeba}, + {0x12049, 0xeba}, + {0x12149, 0xeba}, + {0x13049, 0xeba}, + {0x13149, 0xeba}, + {0x110049, 0xeba}, + {0x110149, 0xeba}, + {0x111049, 0xeba}, + {0x111149, 0xeba}, + {0x112049, 0xeba}, + {0x112149, 0xeba}, + {0x113049, 0xeba}, + {0x113149, 0xeba}, + {0x43, 0x63}, + {0x1043, 0x63}, + {0x2043, 0x63}, + {0x3043, 0x63}, + {0x4043, 0x63}, + {0x5043, 0x63}, + {0x6043, 0x63}, + {0x7043, 0x63}, + {0x8043, 0x63}, + {0x9043, 0x63}, + {0x20018, 0x3}, + {0x20075, 0x4}, + {0x20050, 0x0}, + {0x20008, 0x320}, + {0x120008, 0xa7}, + {0x20088, 0x9}, + {0x200b2, 0xdc}, + {0x10043, 0x5a1}, + {0x10143, 0x5a1}, + {0x11043, 0x5a1}, + {0x11143, 0x5a1}, + {0x12043, 0x5a1}, + {0x12143, 0x5a1}, + {0x13043, 0x5a1}, + {0x13143, 0x5a1}, + {0x1200b2, 0xdc}, + {0x110043, 0x5a1}, + {0x110143, 0x5a1}, + {0x111043, 0x5a1}, + {0x111143, 0x5a1}, + {0x112043, 0x5a1}, + {0x112143, 0x5a1}, + {0x113043, 0x5a1}, + {0x113143, 0x5a1}, + {0x200fa, 0x1}, + {0x1200fa, 0x1}, + {0x20019, 0x1}, + {0x120019, 0x1}, + {0x200f0, 0x0}, + {0x200f1, 0x0}, + {0x200f2, 0x4444}, + {0x200f3, 0x8888}, + {0x200f4, 0x5555}, + {0x200f5, 0x0}, + {0x200f6, 0x0}, + {0x200f7, 0xf000}, + {0x20025, 0x0}, + {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x200c7, 0x80}, + {0x1200c7, 0x80}, + {0x200ca, 0x106}, + {0x1200ca, 0x106}, +}; + +/* 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, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x131f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x310}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x3}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P1 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x1}, + {0x54003, 0x29c}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x310}, + {0x54019, 0x994}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x994}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x3}, + {0x54032, 0x9400}, + {0x54033, 0x3109}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0x9400}, + {0x54039, 0x3109}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P0 2D message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { + {0xd0000, 0x0}, + {0x54003, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x61}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400f, 0x100}, + {0x54010, 0x1f7f}, + {0x54012, 0x310}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x3}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + { 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, 0xf}, + {0x90039, 0x7c0}, + {0x9003a, 0x139}, + {0x9003b, 0x44}, + {0x9003c, 0x630}, + {0x9003d, 0x159}, + {0x9003e, 0x14f}, + {0x9003f, 0x630}, + {0x90040, 0x159}, + {0x90041, 0x47}, + {0x90042, 0x630}, + {0x90043, 0x149}, + {0x90044, 0x4f}, + {0x90045, 0x630}, + {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, 0x630}, + {0x90058, 0x179}, + {0x90059, 0x1}, + {0x9005a, 0x618}, + {0x9005b, 0x109}, + {0x9005c, 0x40c0}, + {0x9005d, 0x630}, + {0x9005e, 0x149}, + {0x9005f, 0x8}, + {0x90060, 0x4}, + {0x90061, 0x48}, + {0x90062, 0x4040}, + {0x90063, 0x630}, + {0x90064, 0x149}, + {0x90065, 0x0}, + {0x90066, 0x4}, + {0x90067, 0x48}, + {0x90068, 0x40}, + {0x90069, 0x630}, + {0x9006a, 0x149}, + {0x9006b, 0x10}, + {0x9006c, 0x4}, + {0x9006d, 0x18}, + {0x9006e, 0x0}, + {0x9006f, 0x4}, + {0x90070, 0x78}, + {0x90071, 0x549}, + {0x90072, 0x630}, + {0x90073, 0x159}, + {0x90074, 0xd49}, + {0x90075, 0x630}, + {0x90076, 0x159}, + {0x90077, 0x94a}, + {0x90078, 0x630}, + {0x90079, 0x159}, + {0x9007a, 0x441}, + {0x9007b, 0x630}, + {0x9007c, 0x149}, + {0x9007d, 0x42}, + {0x9007e, 0x630}, + {0x9007f, 0x149}, + {0x90080, 0x1}, + {0x90081, 0x630}, + {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, 0xa}, + {0x9009c, 0x10}, + {0x9009d, 0x109}, + {0x9009e, 0x2}, + {0x9009f, 0x10}, + {0x900a0, 0x109}, + {0x900a1, 0x5}, + {0x900a2, 0x7c0}, + {0x900a3, 0x109}, + {0x900a4, 0x10}, + {0x900a5, 0x10}, + {0x900a6, 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, 0x623}, + {0x4002b, 0x15}, + {0x4004b, 0x0}, + {0x4006b, 0x0}, + {0x4000c, 0x4028}, + {0x4002c, 0x80}, + {0x4004c, 0x0}, + {0x4006c, 0x0}, + {0x4000d, 0xe08}, + {0x4002d, 0xc1a}, + {0x4004d, 0x0}, + {0x4006d, 0x0}, + {0x4000e, 0x623}, + {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}, + {0x900a7, 0x0}, + {0x900a8, 0x790}, + {0x900a9, 0x11a}, + {0x900aa, 0x8}, + {0x900ab, 0x7aa}, + {0x900ac, 0x2a}, + {0x900ad, 0x10}, + {0x900ae, 0x7b2}, + {0x900af, 0x2a}, + {0x900b0, 0x0}, + {0x900b1, 0x7c8}, + {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, 0x0}, + {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, 0xc}, + {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, 0x0}, + {0x90159, 0x400}, + {0x9015a, 0x10e}, + {0x9015b, 0x8}, + {0x9015c, 0xe8}, + {0x9015d, 0x109}, + {0x9015e, 0x0}, + {0x9015f, 0x8140}, + {0x90160, 0x10c}, + {0x90161, 0x10}, + {0x90162, 0x8138}, + {0x90163, 0x10c}, + {0x90164, 0x8}, + {0x90165, 0x7c8}, + {0x90166, 0x101}, + {0x90167, 0x8}, + {0x90168, 0x0}, + {0x90169, 0x8}, + {0x9016a, 0x8}, + {0x9016b, 0x448}, + {0x9016c, 0x109}, + {0x9016d, 0xf}, + {0x9016e, 0x7c0}, + {0x9016f, 0x109}, + {0x90170, 0x0}, + {0x90171, 0xe8}, + {0x90172, 0x109}, + {0x90173, 0x47}, + {0x90174, 0x630}, + {0x90175, 0x109}, + {0x90176, 0x8}, + {0x90177, 0x618}, + {0x90178, 0x109}, + {0x90179, 0x8}, + {0x9017a, 0xe0}, + {0x9017b, 0x109}, + {0x9017c, 0x0}, + {0x9017d, 0x7c8}, + {0x9017e, 0x109}, + {0x9017f, 0x8}, + {0x90180, 0x8140}, + {0x90181, 0x10c}, + {0x90182, 0x0}, + {0x90183, 0x1}, + {0x90184, 0x8}, + {0x90185, 0x8}, + {0x90186, 0x4}, + {0x90187, 0x8}, + {0x90188, 0x8}, + {0x90189, 0x7c8}, + {0x9018a, 0x101}, + {0x90006, 0x0}, + {0x90007, 0x0}, + {0x90008, 0x8}, + {0x90009, 0x0}, + {0x9000a, 0x0}, + {0x9000b, 0x0}, + {0xd00e7, 0x400}, + {0x90017, 0x0}, + {0x9001f, 0x2a}, + {0x90026, 0x6a}, + {0x400d0, 0x0}, + {0x400d1, 0x101}, + {0x400d2, 0x105}, + {0x400d3, 0x107}, + {0x400d4, 0x10f}, + {0x400d5, 0x202}, + {0x400d6, 0x20a}, + {0x400d7, 0x20b}, + {0x2003a, 0x2}, + {0x2000b, 0x64}, + {0x2000c, 0xc8}, + {0x2000d, 0x7d0}, + {0x2000e, 0x2c}, + {0x12000b, 0x14}, + {0x12000c, 0x29}, + {0x12000d, 0x1a1}, + {0x12000e, 0x10}, + {0x9000c, 0x0}, + {0x9000d, 0x173}, + {0x9000e, 0x60}, + {0x9000f, 0x6110}, + {0x90010, 0x2152}, + {0x90011, 0xdfbd}, + {0x90012, 0x60}, + {0x90013, 0x6152}, + {0x20010, 0x5a}, + {0x20011, 0x3}, + {0x120010, 0x5a}, + {0x120011, 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}, + {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}, + {0x2003a, 0x2}, + {0xc0080, 0x2}, + {0xd0000, 0x1} +}; + +static struct dram_fsp_msg ddr_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), + }, + { + /* P1 667mts 1D */ + .drate = 667, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .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_3gb = { + .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 = { 3200, 667, }, +}; + diff --git a/board/technexion/pico-imx8mq/lpddr4_timing_4gb.c b/board/technexion/pico-imx8mq/lpddr4_timing_4gb.c new file mode 100644 index 00000000000..b1d1c5223ec --- /dev/null +++ b/board/technexion/pico-imx8mq/lpddr4_timing_4gb.c @@ -0,0 +1,1734 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * + * Generated code from MX8M_DDR_tool + * Align with uboot-imx_v2018.03_4.14.78_1.0.0_ga + */ + +#include +#include +#include +#include + +static struct dram_cfg_param ddr_ddrc_cfg[] = { + /** Initialize DDRC registers **/ + {0x3d400304, 0x1}, + {0x3d400030, 0x1}, + {0x3d400000, 0xa3080020}, + {0x3d400028, 0x0}, + {0x3d400020, 0x203}, + {0x3d400024, 0x3e800}, + {0x3d400064, 0x6100e0}, + {0x3d4000d0, 0xc003061c}, + {0x3d4000d4, 0x9e0000}, + {0x3d4000dc, 0xd4002d}, + {0x3d4000e0, 0x310008}, + {0x3d4000e8, 0x66004a}, + {0x3d4000ec, 0x16004a}, + {0x3d400100, 0x1a201b22}, + {0x3d400104, 0x60633}, + {0x3d40010c, 0xc0c000}, + {0x3d400110, 0xf04080f}, + {0x3d400114, 0x2040c0c}, + {0x3d400118, 0x1010007}, + {0x3d40011c, 0x401}, + {0x3d400130, 0x20600}, + {0x3d400134, 0xc100002}, + {0x3d400138, 0xe6}, + {0x3d400144, 0xa00050}, + {0x3d400180, 0xc3200018}, + {0x3d400184, 0x28061a8}, + {0x3d400188, 0x0}, + {0x3d400190, 0x497820a}, + {0x3d400194, 0x80303}, + {0x3d4001a0, 0xe0400018}, + {0x3d4001a4, 0xdf00e4}, + {0x3d4001a8, 0x80000000}, + {0x3d4001b0, 0x11}, + {0x3d4001b4, 0x170a}, + {0x3d4001c0, 0x1}, + {0x3d4001c4, 0x1}, + {0x3d4000f4, 0x639}, + {0x3d400108, 0x70e1617}, + {0x3d400200, 0x17}, + {0x3d40020c, 0x0}, + {0x3d400210, 0x1f1f}, + {0x3d400204, 0x80808}, + {0x3d400214, 0x7070707}, + {0x3d400218, 0x7070707}, + {0x3d402020, 0x1}, + {0x3d402024, 0xd0c0}, + {0x3d402050, 0x20d040}, + {0x3d402064, 0x14002f}, + {0x3d4020dc, 0x940009}, + {0x3d4020e0, 0x310000}, + {0x3d4020e8, 0x66004a}, + {0x3d4020ec, 0x16004a}, + {0x3d402100, 0xb070508}, + {0x3d402104, 0x3040b}, + {0x3d402108, 0x305090c}, + {0x3d40210c, 0x505000}, + {0x3d402110, 0x4040204}, + {0x3d402114, 0x2030303}, + {0x3d402118, 0x1010004}, + {0x3d40211c, 0x301}, + {0x3d402130, 0x20300}, + {0x3d402134, 0xa100002}, + {0x3d402138, 0x31}, + {0x3d402144, 0x220011}, + {0x3d402180, 0xc0a70006}, + {0x3d402190, 0x3858202}, + {0x3d402194, 0x80303}, + {0x3d4021b4, 0x502}, + {0x3d400244, 0x0}, + {0x3d400250, 0x29001505}, + {0x3d400254, 0x2c}, + {0x3d40025c, 0x5900575b}, + {0x3d400264, 0x90000096}, + {0x3d40026c, 0x1000012c}, + {0x3d400300, 0x16}, + {0x3d400304, 0x0}, + {0x3d40030c, 0x0}, + {0x3d400320, 0x1}, + {0x3d40036c, 0x11}, + {0x3d400400, 0x111}, + {0x3d400404, 0x10f3}, + {0x3d400408, 0x72ff}, + {0x3d400490, 0x1}, + {0x3d400494, 0xe00}, + {0x3d400498, 0x62ffff}, + {0x3d40049c, 0xe00}, + {0x3d4004a0, 0xffff}, +}; + +/* PHY Initialize Configuration */ +static struct dram_cfg_param ddr_ddrphy_cfg[] = { + {0x100a0, 0x0}, + {0x100a1, 0x1}, + {0x100a2, 0x2}, + {0x100a3, 0x3}, + {0x100a4, 0x4}, + {0x100a5, 0x5}, + {0x100a6, 0x6}, + {0x100a7, 0x7}, + {0x110a0, 0x0}, + {0x110a1, 0x1}, + {0x110a2, 0x2}, + {0x110a3, 0x3}, + {0x110a4, 0x4}, + {0x110a5, 0x5}, + {0x110a6, 0x6}, + {0x110a7, 0x7}, + {0x120a0, 0x0}, + {0x120a1, 0x1}, + {0x120a2, 0x2}, + {0x120a3, 0x3}, + {0x120a4, 0x4}, + {0x120a5, 0x5}, + {0x120a6, 0x6}, + {0x120a7, 0x7}, + {0x130a0, 0x0}, + {0x130a1, 0x1}, + {0x130a2, 0x2}, + {0x130a3, 0x3}, + {0x130a4, 0x4}, + {0x130a5, 0x5}, + {0x130a6, 0x6}, + {0x130a7, 0x7}, + {0x20110, 0x2}, + {0x20111, 0x3}, + {0x20112, 0x4}, + {0x20113, 0x5}, + {0x20114, 0x0}, + {0x20115, 0x1}, + {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}, + {0x55, 0x1ff}, + {0x1055, 0x1ff}, + {0x2055, 0x1ff}, + {0x3055, 0x1ff}, + {0x4055, 0x1ff}, + {0x5055, 0x1ff}, + {0x6055, 0x1ff}, + {0x7055, 0x1ff}, + {0x8055, 0x1ff}, + {0x9055, 0x1ff}, + {0x200c5, 0x19}, + {0x1200c5, 0x7}, + {0x2002e, 0x2}, + {0x12002e, 0x1}, + {0x90204, 0x0}, + {0x190204, 0x0}, + {0x20024, 0x1ab}, + {0x2003a, 0x0}, + {0x120024, 0x1ab}, + {0x2003a, 0x0}, + {0x20056, 0x3}, + {0x120056, 0xa}, + {0x1004d, 0xe00}, + {0x1014d, 0xe00}, + {0x1104d, 0xe00}, + {0x1114d, 0xe00}, + {0x1204d, 0xe00}, + {0x1214d, 0xe00}, + {0x1304d, 0xe00}, + {0x1314d, 0xe00}, + {0x11004d, 0xe00}, + {0x11014d, 0xe00}, + {0x11104d, 0xe00}, + {0x11114d, 0xe00}, + {0x11204d, 0xe00}, + {0x11214d, 0xe00}, + {0x11304d, 0xe00}, + {0x11314d, 0xe00}, + {0x10049, 0xeba}, + {0x10149, 0xeba}, + {0x11049, 0xeba}, + {0x11149, 0xeba}, + {0x12049, 0xeba}, + {0x12149, 0xeba}, + {0x13049, 0xeba}, + {0x13149, 0xeba}, + {0x110049, 0xeba}, + {0x110149, 0xeba}, + {0x111049, 0xeba}, + {0x111149, 0xeba}, + {0x112049, 0xeba}, + {0x112149, 0xeba}, + {0x113049, 0xeba}, + {0x113149, 0xeba}, + {0x43, 0x63}, + {0x1043, 0x63}, + {0x2043, 0x63}, + {0x3043, 0x63}, + {0x4043, 0x63}, + {0x5043, 0x63}, + {0x6043, 0x63}, + {0x7043, 0x63}, + {0x8043, 0x63}, + {0x9043, 0x63}, + {0x20018, 0x3}, + {0x20075, 0x4}, + {0x20050, 0x0}, + {0x20008, 0x320}, + {0x120008, 0xa7}, + {0x20088, 0x9}, + {0x200b2, 0xdc}, + {0x10043, 0x5a1}, + {0x10143, 0x5a1}, + {0x11043, 0x5a1}, + {0x11143, 0x5a1}, + {0x12043, 0x5a1}, + {0x12143, 0x5a1}, + {0x13043, 0x5a1}, + {0x13143, 0x5a1}, + {0x1200b2, 0xdc}, + {0x110043, 0x5a1}, + {0x110143, 0x5a1}, + {0x111043, 0x5a1}, + {0x111143, 0x5a1}, + {0x112043, 0x5a1}, + {0x112143, 0x5a1}, + {0x113043, 0x5a1}, + {0x113143, 0x5a1}, + {0x200fa, 0x1}, + {0x1200fa, 0x1}, + {0x20019, 0x1}, + {0x120019, 0x1}, + {0x200f0, 0x0}, + {0x200f1, 0x0}, + {0x200f2, 0x4444}, + {0x200f3, 0x8888}, + {0x200f4, 0x5555}, + {0x200f5, 0x0}, + {0x200f6, 0x0}, + {0x200f7, 0xf000}, + {0x20025, 0x0}, + {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x200c7, 0x80}, + {0x1200c7, 0x80}, + {0x200ca, 0x106}, + {0x1200ca, 0x106}, +}; + +/* 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, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x131f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x310}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x3}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P1 message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x1}, + {0x54003, 0x29c}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400d, 0x100}, + {0x54012, 0x310}, + {0x54019, 0x994}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x994}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x3}, + {0x54032, 0x9400}, + {0x54033, 0x3109}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0x9400}, + {0x54039, 0x3109}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + {0xd0000, 0x1}, +}; + +/* P0 2D message block paremeter for training firmware */ +static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { + {0xd0000, 0x0}, + {0x54003, 0xc80}, + {0x54004, 0x2}, + {0x54005, 0x2228}, + {0x54006, 0x11}, + {0x54008, 0x61}, + {0x54009, 0xc8}, + {0x5400b, 0x2}, + {0x5400f, 0x100}, + {0x54010, 0x1f7f}, + {0x54012, 0x310}, + {0x54019, 0x2dd4}, + {0x5401a, 0x31}, + {0x5401b, 0x4a66}, + {0x5401c, 0x4a08}, + {0x5401e, 0x16}, + {0x5401f, 0x2dd4}, + {0x54020, 0x31}, + {0x54021, 0x4a66}, + {0x54022, 0x4a08}, + {0x54024, 0x16}, + {0x5402b, 0x1000}, + {0x5402c, 0x3}, + {0x54032, 0xd400}, + {0x54033, 0x312d}, + {0x54034, 0x6600}, + {0x54035, 0x84a}, + {0x54036, 0x4a}, + {0x54037, 0x1600}, + {0x54038, 0xd400}, + {0x54039, 0x312d}, + {0x5403a, 0x6600}, + {0x5403b, 0x84a}, + {0x5403c, 0x4a}, + {0x5403d, 0x1600}, + { 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, 0xf}, + {0x90039, 0x7c0}, + {0x9003a, 0x139}, + {0x9003b, 0x44}, + {0x9003c, 0x630}, + {0x9003d, 0x159}, + {0x9003e, 0x14f}, + {0x9003f, 0x630}, + {0x90040, 0x159}, + {0x90041, 0x47}, + {0x90042, 0x630}, + {0x90043, 0x149}, + {0x90044, 0x4f}, + {0x90045, 0x630}, + {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, 0x630}, + {0x90058, 0x179}, + {0x90059, 0x1}, + {0x9005a, 0x618}, + {0x9005b, 0x109}, + {0x9005c, 0x40c0}, + {0x9005d, 0x630}, + {0x9005e, 0x149}, + {0x9005f, 0x8}, + {0x90060, 0x4}, + {0x90061, 0x48}, + {0x90062, 0x4040}, + {0x90063, 0x630}, + {0x90064, 0x149}, + {0x90065, 0x0}, + {0x90066, 0x4}, + {0x90067, 0x48}, + {0x90068, 0x40}, + {0x90069, 0x630}, + {0x9006a, 0x149}, + {0x9006b, 0x10}, + {0x9006c, 0x4}, + {0x9006d, 0x18}, + {0x9006e, 0x0}, + {0x9006f, 0x4}, + {0x90070, 0x78}, + {0x90071, 0x549}, + {0x90072, 0x630}, + {0x90073, 0x159}, + {0x90074, 0xd49}, + {0x90075, 0x630}, + {0x90076, 0x159}, + {0x90077, 0x94a}, + {0x90078, 0x630}, + {0x90079, 0x159}, + {0x9007a, 0x441}, + {0x9007b, 0x630}, + {0x9007c, 0x149}, + {0x9007d, 0x42}, + {0x9007e, 0x630}, + {0x9007f, 0x149}, + {0x90080, 0x1}, + {0x90081, 0x630}, + {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, 0xa}, + {0x9009c, 0x10}, + {0x9009d, 0x109}, + {0x9009e, 0x2}, + {0x9009f, 0x10}, + {0x900a0, 0x109}, + {0x900a1, 0x5}, + {0x900a2, 0x7c0}, + {0x900a3, 0x109}, + {0x900a4, 0x10}, + {0x900a5, 0x10}, + {0x900a6, 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, 0x623}, + {0x4002b, 0x15}, + {0x4004b, 0x0}, + {0x4006b, 0x0}, + {0x4000c, 0x4028}, + {0x4002c, 0x80}, + {0x4004c, 0x0}, + {0x4006c, 0x0}, + {0x4000d, 0xe08}, + {0x4002d, 0xc1a}, + {0x4004d, 0x0}, + {0x4006d, 0x0}, + {0x4000e, 0x623}, + {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}, + {0x900a7, 0x0}, + {0x900a8, 0x790}, + {0x900a9, 0x11a}, + {0x900aa, 0x8}, + {0x900ab, 0x7aa}, + {0x900ac, 0x2a}, + {0x900ad, 0x10}, + {0x900ae, 0x7b2}, + {0x900af, 0x2a}, + {0x900b0, 0x0}, + {0x900b1, 0x7c8}, + {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, 0x0}, + {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, 0xc}, + {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, 0x0}, + {0x90159, 0x400}, + {0x9015a, 0x10e}, + {0x9015b, 0x8}, + {0x9015c, 0xe8}, + {0x9015d, 0x109}, + {0x9015e, 0x0}, + {0x9015f, 0x8140}, + {0x90160, 0x10c}, + {0x90161, 0x10}, + {0x90162, 0x8138}, + {0x90163, 0x10c}, + {0x90164, 0x8}, + {0x90165, 0x7c8}, + {0x90166, 0x101}, + {0x90167, 0x8}, + {0x90168, 0x0}, + {0x90169, 0x8}, + {0x9016a, 0x8}, + {0x9016b, 0x448}, + {0x9016c, 0x109}, + {0x9016d, 0xf}, + {0x9016e, 0x7c0}, + {0x9016f, 0x109}, + {0x90170, 0x0}, + {0x90171, 0xe8}, + {0x90172, 0x109}, + {0x90173, 0x47}, + {0x90174, 0x630}, + {0x90175, 0x109}, + {0x90176, 0x8}, + {0x90177, 0x618}, + {0x90178, 0x109}, + {0x90179, 0x8}, + {0x9017a, 0xe0}, + {0x9017b, 0x109}, + {0x9017c, 0x0}, + {0x9017d, 0x7c8}, + {0x9017e, 0x109}, + {0x9017f, 0x8}, + {0x90180, 0x8140}, + {0x90181, 0x10c}, + {0x90182, 0x0}, + {0x90183, 0x1}, + {0x90184, 0x8}, + {0x90185, 0x8}, + {0x90186, 0x4}, + {0x90187, 0x8}, + {0x90188, 0x8}, + {0x90189, 0x7c8}, + {0x9018a, 0x101}, + {0x90006, 0x0}, + {0x90007, 0x0}, + {0x90008, 0x8}, + {0x90009, 0x0}, + {0x9000a, 0x0}, + {0x9000b, 0x0}, + {0xd00e7, 0x400}, + {0x90017, 0x0}, + {0x9001f, 0x2a}, + {0x90026, 0x6a}, + {0x400d0, 0x0}, + {0x400d1, 0x101}, + {0x400d2, 0x105}, + {0x400d3, 0x107}, + {0x400d4, 0x10f}, + {0x400d5, 0x202}, + {0x400d6, 0x20a}, + {0x400d7, 0x20b}, + {0x2003a, 0x2}, + {0x2000b, 0x64}, + {0x2000c, 0xc8}, + {0x2000d, 0x7d0}, + {0x2000e, 0x2c}, + {0x12000b, 0x14}, + {0x12000c, 0x29}, + {0x12000d, 0x1a1}, + {0x12000e, 0x10}, + {0x9000c, 0x0}, + {0x9000d, 0x173}, + {0x9000e, 0x60}, + {0x9000f, 0x6110}, + {0x90010, 0x2152}, + {0x90011, 0xdfbd}, + {0x90012, 0x60}, + {0x90013, 0x6152}, + {0x20010, 0x5a}, + {0x20011, 0x3}, + {0x120010, 0x5a}, + {0x120011, 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}, + {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}, + {0x2003a, 0x2}, + {0xc0080, 0x2}, + {0xd0000, 0x1} +}; + +static struct dram_fsp_msg ddr_dram_fsp_msg[] = { + { + /* P0 3200mts 1D */ + .drate = 3200, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), + }, + { + /* P1 667mts 1D */ + .drate = 667, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P0 3200mts 2D */ + .drate = 3200, + .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_4gb = { + .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 = { 3200, 667, }, +}; + diff --git a/board/technexion/pico-imx8mq/pico-imx8mq.c b/board/technexion/pico-imx8mq/pico-imx8mq.c new file mode 100644 index 00000000000..822357bb12c --- /dev/null +++ b/board/technexion/pico-imx8mq/pico-imx8mq.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) + +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE) + +static iomux_v3_cfg_t const wdog_pads[] = { + IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +static iomux_v3_cfg_t const uart_pads[] = { + IMX8MQ_PAD_UART1_RXD__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +int board_early_init_f(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + set_wdog_reset(wdog); + + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); + + return 0; +} + +int dram_init(void) +{ + int ddr_size = readl(M4_BOOTROM_BASE_ADDR); + + if (ddr_size == 0x4) + gd->ram_size = 0x100000000; + else if (ddr_size == 0x3) + gd->ram_size = 0xc0000000; + else if (ddr_size == 0x2) + gd->ram_size = 0x80000000; + else if (ddr_size == 0x1) + gd->ram_size = 0x40000000; + else + printf("Unknown DDR type!!!\n"); + + /* rom_pointer[1] contains the size of TEE occupies */ + if (rom_pointer[1]) + gd->ram_size -= rom_pointer[1]; + + return 0; +} + +#ifdef CONFIG_FEC_MXC +#define FEC_RST_PAD IMX_GPIO_NR(1, 9) +#define FEC_PWR_PAD IMX_GPIO_NR(1, 0) +static iomux_v3_cfg_t const fec1_pads[] = { + /* Reset */ + IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL), + /* Power */ + IMX8MQ_PAD_GPIO1_IO00__GPIO1_IO0 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static void setup_iomux_fec(void) +{ + imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); + + gpio_request(IMX_GPIO_NR(1, 0), "fec1_pwr"); + gpio_direction_output(IMX_GPIO_NR(1, 0), 1); + udelay(500); + + gpio_request(IMX_GPIO_NR(1, 9), "fec1_rst"); + gpio_direction_output(IMX_GPIO_NR(1, 9), 0); + udelay(500); + gpio_direction_output(IMX_GPIO_NR(1, 9), 1); +} + +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + setup_iomux_fec(); + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(&gpr->gpr[1], BIT(13) | BIT(17), 0); + return set_clk_enet(ENET_125MHZ); +} + +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +int board_init(void) +{ +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + + return 0; +} + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + env_set("board_rev", "iMX8MQ"); +#endif + return 0; +} diff --git a/board/technexion/pico-imx8mq/spl.c b/board/technexion/pico-imx8mq/spl.c new file mode 100644 index 00000000000..1588f17821b --- /dev/null +++ b/board/technexion/pico-imx8mq/spl.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lpddr4_timing.h" + +DECLARE_GLOBAL_DATA_PTR; + +#define DDR_DET_1 IMX_GPIO_NR(3, 11) +#define DDR_DET_2 IMX_GPIO_NR(3, 12) +#define DDR_DET_3 IMX_GPIO_NR(3, 13) + +static iomux_v3_cfg_t const verdet_pads[] = { + IMX8MQ_PAD_NAND_DATA01__GPIO3_IO7 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA02__GPIO3_IO8 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA03__GPIO3_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA04__GPIO3_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA05__GPIO3_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA06__GPIO3_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL), + IMX8MQ_PAD_NAND_DATA07__GPIO3_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +/* + * DDR_DET_1 DDR_DET_2 DDR_DET_3 + * 0 0 1 4G LPDDR4 + * 1 1 1 3G LPDDR4 + * 1 1 0 2G LPDDR4 + * 1 0 1 1G LPDDR4 + */ +static void spl_dram_init(void) +{ + struct dram_timing_info *dram_timing; + u8 ddr = 0, size; + + imx_iomux_v3_setup_multiple_pads(verdet_pads, ARRAY_SIZE(verdet_pads)); + + gpio_request(DDR_DET_1, "ddr_det_1"); + gpio_direction_input(DDR_DET_1); + gpio_request(DDR_DET_2, "ddr_det_2"); + gpio_direction_input(DDR_DET_2); + gpio_request(DDR_DET_3, "ddr_det_3"); + gpio_direction_input(DDR_DET_3); + + ddr |= !!gpio_get_value(DDR_DET_3) << 0; + ddr |= !!gpio_get_value(DDR_DET_2) << 1; + ddr |= !!gpio_get_value(DDR_DET_1) << 2; + + switch (ddr) { + case 0x1: + size = 4; + dram_timing = &dram_timing_4gb; + break; + case 0x7: + size = 3; + dram_timing = &dram_timing_3gb; + break; + case 0x6: + size = 2; + dram_timing = &dram_timing_2gb; + break; + case 0x5: + size = 1; + dram_timing = &dram_timing_1gb; + break; + default: + puts("Unknown DDR type!!!\n"); + return; + } + + printf("%s: LPDDR4 %d GiB\n", __func__, size); + ddr_init(dram_timing); + writel(size, M4_BOOTROM_BASE_ADDR); +} + +#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12) +#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10) +#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19) + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + ret = 1; + break; + case USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + return ret; + } + + return 1; +} + +#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \ + PAD_CTL_FSEL2) +#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1) + +static iomux_v3_cfg_t const usdhc1_pads[] = { + IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), + IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), + IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL), +}; + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC1_BASE_ADDR, 0, 8}, + {USDHC2_BASE_ADDR, 0, 4}, +}; + +int board_mmc_init(bd_t *bis) +{ + int ret; + /* + * According to the board_mmc_init() the following map is done: + * (U-Boot device node) (Physical Port) + * mmc0 USDHC1 + * mmc1 USDHC2 + */ + init_clk_usdhc(0); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT); + imx_iomux_v3_setup_multiple_pads(usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); + gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset"); + gpio_direction_output(USDHC1_PWR_GPIO, 0); + udelay(500); + gpio_direction_output(USDHC1_PWR_GPIO, 1); + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[0]); + if (ret) + return ret; + + init_clk_usdhc(1); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT); + imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads)); + gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset"); + gpio_direction_output(USDHC2_PWR_GPIO, 0); + udelay(500); + gpio_direction_output(USDHC2_PWR_GPIO, 1); + return fsl_esdhc_initialize(bis, &usdhc_cfg[1]); +} + +void spl_board_init(void) +{ + puts("Normal Boot\n"); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif + +void board_init_f(ulong dummy) +{ + int ret; + + /* Clear global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + arch_cpu_init(); + + init_uart_clk(0); + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_init(); + if (ret) { + debug("spl_init() failed: %d\n", ret); + hang(); + } + + enable_tzc380(); + + /* DDR initialization */ + spl_dram_init(); + + board_init_r(NULL, 0); +} diff --git a/configs/pico-imx8mq_defconfig b/configs/pico-imx8mq_defconfig new file mode 100644 index 00000000000..2d68fe152c7 --- /dev/null +++ b/configs/pico-imx8mq_defconfig @@ -0,0 +1,47 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8M=y +CONFIG_SYS_TEXT_BASE=0x40200000 +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0x400000 +CONFIG_DM_GPIO=y +CONFIG_TARGET_PICO_IMX8MQ=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL=y +CONFIG_CSF_SIZE=0x2000 +CONFIG_SPL_TEXT_BASE=0x7E1000 +CONFIG_FIT=y +CONFIG_FIT_EXTERNAL_OFFSET=0x3000 +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh" +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage.cfg" +CONFIG_SPL_BOARD_INIT=y +CONFIG_HUSH_PARSER=y +# CONFIG_BOOTM_NETBSD is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx8mq-pico-pi" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000 +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MXC=y +CONFIG_DM_MMC=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_FSL_USDHC=y +CONFIG_DM_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX8M=y +CONFIG_POWER_DOMAIN=y +CONFIG_IMX8M_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_RESET=y +CONFIG_DM_THERMAL=y diff --git a/include/configs/pico-imx8mq.h b/include/configs/pico-imx8mq.h new file mode 100644 index 00000000000..a2f80cdd671 --- /dev/null +++ b/include/configs/pico-imx8mq.h @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 NXP + */ + +#ifndef __IMX8M_PICOPI_H +#define __IMX8M_PICOPI_H + +#include +#include + +#define CONFIG_SPL_MAX_SIZE (124 * 1024) +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 + +#ifdef CONFIG_SPL_BUILD +/*#define CONFIG_ENABLE_DDR_TRAINING_DEBUG*/ +#define CONFIG_SPL_WATCHDOG_SUPPORT +#define CONFIG_SPL_DRIVERS_MISC_SUPPORT +#define CONFIG_SPL_POWER_SUPPORT +#define CONFIG_SPL_I2C_SUPPORT +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds" +#define CONFIG_SPL_STACK 0x187FF0 +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SPL_BSS_START_ADDR 0x00180000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */ +#define CONFIG_SYS_SPL_MALLOC_START 0x42200000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 /* 512 KB */ +#define CONFIG_SYS_SPL_PTE_RAM_BASE 0x41580000 + +/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */ +#define CONFIG_MALLOC_F_ADDR 0x182000 +/* For RAW image gives a error info not panic */ +#define CONFIG_SPL_ABORT_ON_RAW_IMAGE + +#undef CONFIG_DM_MMC +#undef CONFIG_DM_PMIC + +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ +#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */ + +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + +#define CONFIG_POWER +#define CONFIG_POWER_I2C +#endif + +#define CONFIG_REMAKE_ELF + +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_BOARD_LATE_INIT + +#undef CONFIG_CMD_EXPORTENV +#undef CONFIG_CMD_IMPORTENV +#undef CONFIG_CMD_IMLS + +#undef CONFIG_CMD_CRC32 + +/* ENET Config */ +/* ENET1 */ +#if defined(CONFIG_CMD_NET) +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MII +#define CONFIG_MII +#define CONFIG_ETHPRIME "FEC" + +#define CONFIG_FEC_MXC +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_MXC_PHYADDR 1 +#define FEC_QUIRK_ENET_MAC + +#define CONFIG_PHY_GIGE +#define IMX_FEC_BASE 0x30BE0000 + +#define CONFIG_PHYLIB +#define CONFIG_PHY_ATHEROS +#endif + +/* Initial environment variables */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "script=boot.scr\0" \ + "image=Image\0" \ + "console=ttymxc0,115200\0" \ + "fdt_addr=0x43000000\0" \ + "fdt_high=0xffffffffffffffff\0" \ + "fdt_file=imx8mq-pico-pi.dtb\0" \ + "initrd_addr=0x43800000\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ + "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \ + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ + "mmcautodetect=yes\0" \ + "mmcargs=setenv bootargs console=${console} root=${mmcroot}\0 " \ + "loadbootscript=" \ + "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ + "bootscript=echo Running bootscript from mmc ...; source\0" \ + "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ + "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "echo wait for boot; " \ + "fi;\0" \ + "netargs=setenv bootargs console=${console} " \ + "root=/dev/nfs " \ + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ + "netboot=echo Booting from net ...; " \ + "run netargs; " \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "${get_cmd} ${loadaddr} ${image}; " \ + "booti; " + +#define CONFIG_BOOTCOMMAND \ + "mmc dev ${mmcdev}; if mmc rescan; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "fi; " \ + "else booti ${loadaddr} - ${fdt_addr}; fi" + +/* Link Definitions */ +#define CONFIG_LOADADDR 0x40480000 + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 +#define CONFIG_SYS_INIT_RAM_SIZE 0x80000 +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_ENV_OVERWRITE +#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */ +#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */ + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (2 * 1024)) * 1024) + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define PHYS_SDRAM 0x40000000 +#define PHYS_SDRAM_SIZE 0x80000000 /* 2 GiB DDR */ + +#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \ + (PHYS_SDRAM_SIZE >> 1)) + +#define CONFIG_BAUDRATE 115200 + +#define CONFIG_MXC_UART +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR + +/* Monitor Command Prompt */ +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_MAXARGS 64 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +#define CONFIG_IMX_BOOTAUX + +#define CONFIG_CMD_MMC + +#define CONFIG_SYS_FSL_USDHC_NUM 2 +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 + +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 + +#define CONFIG_MXC_GPIO + +#define CONFIG_CMD_FUSE + +/* I2C Configs */ +#define CONFIG_SYS_I2C_SPEED 100000 + +#define CONFIG_OF_SYSTEM_SETUP + +#ifndef CONFIG_SPL_BUILD +#define CONFIG_DM_PMIC +#endif + +#define CONFIG_SYS_BOOTM_LEN SZ_128M + +#endif From 3c42c0f6734601540bd2be5e83ca12e05079222a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 1 May 2020 22:08:34 +0800 Subject: [PATCH 16/82] imx: add module fuse support There are different parts from one SoC. Take i.MX6ULL for example, some part might not have ENET, some might have; some might not have USB, some might have. The information could be got from OCOTP, to make one image support the different parts, we need runtime disable linux kernel dts node and uboot driver probe if the corresponding module not exists in the part. Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/module_fuse.h | 127 ++++++++ arch/arm/include/asm/mach-imx/sys_proto.h | 1 + arch/arm/mach-imx/Kconfig | 7 + arch/arm/mach-imx/mx6/Makefile | 1 + arch/arm/mach-imx/mx6/module_fuse.c | 322 ++++++++++++++++++++ 5 files changed, 458 insertions(+) create mode 100644 arch/arm/include/asm/mach-imx/module_fuse.h create mode 100644 arch/arm/mach-imx/mx6/module_fuse.c diff --git a/arch/arm/include/asm/mach-imx/module_fuse.h b/arch/arm/include/asm/mach-imx/module_fuse.h new file mode 100644 index 00000000000..a46fc3f1f8e --- /dev/null +++ b/arch/arm/include/asm/mach-imx/module_fuse.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 NXP + */ + +#ifndef __MODULE_FUSE_H__ +#define __MODULE_FUSE_H__ + +enum fuse_module_type { + MODULE_TSC, + MODULE_ADC1, + MODULE_ADC2, + MODULE_SIM1, + MODULE_SIM2, + MODULE_FLEXCAN1, + MODULE_FLEXCAN2, + MODULE_SPDIF, + MODULE_EIM, + MODULE_SD1, + MODULE_SD2, + MODULE_SD3, + MODULE_SD4, + MODULE_QSPI1, + MODULE_QSPI2, + MODULE_GPMI, + MODULE_APBHDMA, + MODULE_LCDIF, + MODULE_PXP, + MODULE_CSI, + MODULE_ENET1, + MODULE_ENET2, + MODULE_CAAM, + MODULE_USB_OTG1, + MODULE_USB_OTG2, + MODULE_SAI2, + MODULE_SAI3, + MODULE_BEE, + MODULE_UART1, + MODULE_UART2, + MODULE_UART3, + MODULE_UART4, + MODULE_UART5, + MODULE_UART6, + MODULE_UART7, + MODULE_UART8, + MODULE_PWM5, + MODULE_PWM6, + MODULE_PWM7, + MODULE_PWM8, + MODULE_ECSPI1, + MODULE_ECSPI2, + MODULE_ECSPI3, + MODULE_ECSPI4, + MODULE_ECSPI5, + MODULE_I2C1, + MODULE_I2C2, + MODULE_I2C3, + MODULE_I2C4, + MODULE_GPT1, + MODULE_GPT2, + MODULE_EPIT1, + MODULE_EPIT2, + MODULE_EPDC, + MODULE_ESAI, + MODULE_DCP, + MODULE_DCP_CRYPTO, +}; + +struct fuse_entry_desc { + enum fuse_module_type module; + const char *node_path; + u32 fuse_word_offset; + u32 fuse_bit_offset; + u32 status; +}; + +#if !CONFIG_IS_ENABLED(IMX_MODULE_FUSE) +static inline u32 check_module_fused(enum fuse_module_type module) +{ + return 0; +}; + +static inline u32 esdhc_fused(ulong base_addr) +{ + return 0; +}; + +static inline u32 ecspi_fused(ulong base_addr) +{ + return 0; +}; + +static inline u32 uart_fused(ulong base_addr) +{ + return 0; +}; + +static inline u32 usb_fused(ulong base_addr) +{ + return 0; +}; + +static inline u32 qspi_fused(ulong base_addr) +{ + return 0; +}; + +static inline u32 i2c_fused(ulong base_addr) +{ + return 0; +}; + +static inline u32 enet_fused(ulong base_addr) +{ + return 0; +}; +#else +u32 check_module_fused(enum fuse_module_type module); +u32 esdhc_fused(ulong base_addr); +u32 ecspi_fused(ulong base_addr); +u32 uart_fused(ulong base_addr); +u32 usb_fused(ulong base_addr); +u32 qspi_fused(ulong base_addr); +u32 i2c_fused(ulong base_addr); +u32 enet_fused(ulong base_addr); +#endif +#endif /* __MODULE_FUSE_H__ */ diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 2a997f280d7..b91b2137745 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -9,6 +9,7 @@ #include #include +#include #include #include "../arch-imx/cpu.h" diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 329149900a5..396f7c92887 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -27,6 +27,13 @@ config IMX_BOOTAUX help bootaux [addr] to boot auxiliary core. +config IMX_MODULE_FUSE + bool "i.MX Module Fuse" + depends on ARCH_MX6 + help + i.MX module fuse to runtime disable some driver, including + Linux OS device node. + config USE_IMXIMG_PLUGIN bool "Use imximage plugin code" depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX7ULP diff --git a/arch/arm/mach-imx/mx6/Makefile b/arch/arm/mach-imx/mx6/Makefile index 81e2913d140..7ea8f91e4f0 100644 --- a/arch/arm/mach-imx/mx6/Makefile +++ b/arch/arm/mach-imx/mx6/Makefile @@ -6,6 +6,7 @@ # (C) Copyright 2011 Freescale Semiconductor, Inc. obj-y := soc.o clock.o +obj-$(CONFIG_IMX_MODULE_FUSE) += module_fuse.o obj-$(CONFIG_SPL_BUILD) += ddr.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_MX6UL_LITESOM) += litesom.o diff --git a/arch/arm/mach-imx/mx6/module_fuse.c b/arch/arm/mach-imx/mx6/module_fuse.c new file mode 100644 index 00000000000..3e944160657 --- /dev/null +++ b/arch/arm/mach-imx/mx6/module_fuse.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 NXP + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct fuse_entry_desc mx6_fuse_descs[] = { +#if defined(CONFIG_MX6ULL) + {MODULE_TSC, "/soc/aips-bus@2000000/tsc@2040000", 0x430, 22}, + {MODULE_ADC2, "/soc/aips-bus@2100000/adc@219c000", 0x430, 23}, + {MODULE_EPDC, "/soc/aips-bus@2200000/epdc@228c000", 0x430, 24}, + {MODULE_ESAI, "/soc/aips-bus@2000000/spba-bus@2000000/esai@2024000", 0x430, 25}, + {MODULE_FLEXCAN1, "/soc/aips-bus@2000000/can@2090000", 0x430, 26}, + {MODULE_FLEXCAN2, "/soc/aips-bus@2000000/can@2094000", 0x430, 27}, + {MODULE_SPDIF, "/soc/aips-bus@2000000/spba-bus@2000000/spdif@2004000", 0x440, 2}, + {MODULE_EIM, "/soc/aips-bus@2100000/weim@21b8000", 0x440, 3}, + {MODULE_SD1, "/soc/aips-bus@2100000/usdhc@2190000", 0x440, 4}, + {MODULE_SD2, "/soc/aips-bus@2100000/usdhc@2194000", 0x440, 5}, + {MODULE_QSPI1, "/soc/aips-bus@2100000/qspi@21e0000", 0x440, 6}, + {MODULE_GPMI, "/soc/gpmi-nand@1806000", 0x440, 7}, + {MODULE_APBHDMA, "/soc/dma-apbh@1804000", 0x440, 7}, + {MODULE_LCDIF, "/soc/aips-bus@2100000/lcdif@21c8000", 0x440, 8}, + {MODULE_PXP, "/soc/aips-bus@2100000/pxp@21cc000", 0x440, 9}, + {MODULE_CSI, "/soc/aips-bus@2100000/csi@21c4000", 0x440, 10}, + {MODULE_ADC1, "/soc/aips-bus@2100000/adc@2198000", 0x440, 11}, + {MODULE_ENET1, "/soc/aips-bus@2100000/ethernet@2188000", 0x440, 12}, + {MODULE_ENET2, "/soc/aips-bus@2000000/ethernet@20b4000", 0x440, 13}, + {MODULE_DCP, "/soc/aips-bus@2200000/dcp@2280000", 0x440, 14}, + {MODULE_USB_OTG2, "/soc/aips-bus@2100000/usb@2184200", 0x440, 15}, + {MODULE_SAI2, "/soc/aips-bus@2000000/spba-bus@2000000/sai@202c000", 0x440, 24}, + {MODULE_SAI3, "/soc/aips-bus@2000000/spba-bus@2000000/sai@2030000", 0x440, 24}, + {MODULE_DCP_CRYPTO, "/soc/aips-bus@2200000/dcp@2280000", 0x440, 25}, + {MODULE_UART5, "/soc/aips-bus@2100000/serial@21f4000", 0x440, 26}, + {MODULE_UART6, "/soc/aips-bus@2100000/serial@21fc000", 0x440, 26}, + {MODULE_UART7, "/soc/aips-bus@2000000/spba-bus@2000000/serial@2018000", 0x440, 26}, + {MODULE_UART8, "/soc/aips-bus@2200000/serial@2288000", 0x440, 26}, + {MODULE_PWM5, "/soc/aips-bus@2000000/pwm@20f0000", 0x440, 27}, + {MODULE_PWM6, "/soc/aips-bus@2000000/pwm@20f4000", 0x440, 27}, + {MODULE_PWM7, "/soc/aips-bus@2000000/pwm@20f8000", 0x440, 27}, + {MODULE_PWM8, "/soc/aips-bus@2000000/pwm@20fc000", 0x440, 27}, + {MODULE_ECSPI3, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2010000", 0x440, 28}, + {MODULE_ECSPI4, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2014000", 0x440, 28}, + {MODULE_I2C3, "/soc/aips-bus@2100000/i2c@21a8000", 0x440, 29}, + {MODULE_I2C4, "/soc/aips-bus@2100000/i2c@21f8000", 0x440, 29}, + {MODULE_GPT2, "/soc/aips-bus@2000000/gpt@20e8000", 0x440, 30}, + {MODULE_EPIT2, "/soc/aips-bus@2000000/epit@20d4000", 0x440, 31}, + /* Paths for older imx tree: */ + {MODULE_TSC, "/soc/aips-bus@02000000/tsc@02040000", 0x430, 22}, + {MODULE_ADC2, "/soc/aips-bus@02100000/adc@0219c000", 0x430, 23}, + {MODULE_EPDC, "/soc/aips-bus@02200000/epdc@0228c000", 0x430, 24}, + {MODULE_ESAI, "/soc/aips-bus@02000000/spba-bus@02000000/esai@02024000", 0x430, 25}, + {MODULE_FLEXCAN1, "/soc/aips-bus@02000000/can@02090000", 0x430, 26}, + {MODULE_FLEXCAN2, "/soc/aips-bus@02000000/can@02094000", 0x430, 27}, + {MODULE_SPDIF, "/soc/aips-bus@02000000/spba-bus@02000000/spdif@02004000", 0x440, 2}, + {MODULE_EIM, "/soc/aips-bus@02100000/weim@021b8000", 0x440, 3}, + {MODULE_SD1, "/soc/aips-bus@02100000/usdhc@02190000", 0x440, 4}, + {MODULE_SD2, "/soc/aips-bus@02100000/usdhc@02194000", 0x440, 5}, + {MODULE_QSPI1, "/soc/aips-bus@02100000/qspi@021e0000", 0x440, 6}, + {MODULE_GPMI, "/soc/gpmi-nand@01806000", 0x440, 7}, + {MODULE_APBHDMA, "/soc/dma-apbh@01804000", 0x440, 7}, + {MODULE_LCDIF, "/soc/aips-bus@02100000/lcdif@021c8000", 0x440, 8}, + {MODULE_PXP, "/soc/aips-bus@02100000/pxp@021cc000", 0x440, 9}, + {MODULE_CSI, "/soc/aips-bus@02100000/csi@021c4000", 0x440, 10}, + {MODULE_ADC1, "/soc/aips-bus@02100000/adc@02198000", 0x440, 11}, + {MODULE_ENET1, "/soc/aips-bus@02100000/ethernet@02188000", 0x440, 12}, + {MODULE_ENET2, "/soc/aips-bus@02000000/ethernet@020b4000", 0x440, 13}, + {MODULE_DCP, "/soc/aips-bus@02200000/dcp@02280000", 0x440, 14}, + {MODULE_USB_OTG2, "/soc/aips-bus@02100000/usb@02184200", 0x440, 15}, + {MODULE_SAI2, "/soc/aips-bus@02000000/spba-bus@02000000/sai@0202c000", 0x440, 24}, + {MODULE_SAI3, "/soc/aips-bus@02000000/spba-bus@02000000/sai@02030000", 0x440, 24}, + {MODULE_DCP_CRYPTO, "/soc/aips-bus@02200000/dcp@02280000", 0x440, 25}, + {MODULE_UART5, "/soc/aips-bus@02100000/serial@021f4000", 0x440, 26}, + {MODULE_UART6, "/soc/aips-bus@02100000/serial@021fc000", 0x440, 26}, + {MODULE_UART7, "/soc/aips-bus@02000000/spba-bus@02000000/serial@02018000", 0x440, 26}, + {MODULE_UART8, "/soc/aips-bus@02200000/serial@02288000", 0x440, 26}, + {MODULE_PWM5, "/soc/aips-bus@02000000/pwm@020f0000", 0x440, 27}, + {MODULE_PWM6, "/soc/aips-bus@02000000/pwm@020f4000", 0x440, 27}, + {MODULE_PWM7, "/soc/aips-bus@02000000/pwm@020f8000", 0x440, 27}, + {MODULE_PWM8, "/soc/aips-bus@02000000/pwm@020fc000", 0x440, 27}, + {MODULE_ECSPI3, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02010000", 0x440, 28}, + {MODULE_ECSPI4, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02014000", 0x440, 28}, + {MODULE_I2C3, "/soc/aips-bus@02100000/i2c@021a8000", 0x440, 29}, + {MODULE_I2C4, "/soc/aips-bus@02100000/i2c@021f8000", 0x440, 29}, + {MODULE_GPT2, "/soc/aips-bus@02000000/gpt@020e8000", 0x440, 30}, + {MODULE_EPIT2, "/soc/aips-bus@02000000/epit@020d4000", 0x440, 31}, +#elif defined(CONFIG_MX6UL) + {MODULE_TSC, "/soc/aips-bus@2000000/tsc@2040000", 0x430, 22}, + {MODULE_ADC2, "/soc/aips-bus@2100000/adc@219c000", 0x430, 23}, + {MODULE_SIM1, "/soc/aips-bus@2100000/sim@218c000", 0x430, 24}, + {MODULE_SIM2, "/soc/aips-bus@2100000/sim@21b4000", 0x430, 25}, + {MODULE_FLEXCAN1, "/soc/aips-bus@2000000/can@2090000", 0x430, 26}, + {MODULE_FLEXCAN2, "/soc/aips-bus@2000000/can@2094000", 0x430, 27}, + {MODULE_SPDIF, "/soc/aips-bus@2000000/spba-bus@2000000/spdif@2004000", 0x440, 2}, + {MODULE_EIM, "/soc/aips-bus@2100000/weim@21b8000", 0x440, 3}, + {MODULE_SD1, "/soc/aips-bus@2100000/usdhc@2190000", 0x440, 4}, + {MODULE_SD2, "/soc/aips-bus@2100000/usdhc@2194000", 0x440, 5}, + {MODULE_QSPI1, "/soc/aips-bus@2100000/qspi@21e0000", 0x440, 6}, + {MODULE_GPMI, "/soc/gpmi-nand@1806000", 0x440, 7}, + {MODULE_APBHDMA, "/soc/dma-apbh@1804000", 0x440, 7}, + {MODULE_LCDIF, "/soc/aips-bus@2100000/lcdif@21c8000", 0x440, 8}, + {MODULE_PXP, "/soc/aips-bus@2100000/pxp@21cc000", 0x440, 9}, + {MODULE_CSI, "/soc/aips-bus@2100000/csi@21c4000", 0x440, 10}, + {MODULE_ADC1, "/soc/aips-bus@2100000/adc@2198000", 0x440, 11}, + {MODULE_ENET1, "/soc/aips-bus@2100000/ethernet@2188000", 0x440, 12}, + {MODULE_ENET2, "/soc/aips-bus@2000000/ethernet@20b4000", 0x440, 13}, + {MODULE_CAAM, "/soc/aips-bus@2100000/caam@2140000", 0x440, 14}, + {MODULE_USB_OTG2, "/soc/aips-bus@2100000/usb@2184200", 0x440, 15}, + {MODULE_SAI2, "/soc/aips-bus@2000000/spba-bus@2000000/sai@202c000", 0x440, 24}, + {MODULE_SAI3, "/soc/aips-bus@2000000/spba-bus@2000000/sai@2030000", 0x440, 24}, + {MODULE_BEE, "/soc/aips-bus@2000000/bee@2044000", 0x440, 25}, + {MODULE_UART5, "/soc/aips-bus@2100000/serial@21f4000", 0x440, 26}, + {MODULE_UART6, "/soc/aips-bus@2100000/serial@21fc000", 0x440, 26}, + {MODULE_UART7, "/soc/aips-bus@2000000/spba-bus@2000000/serial@2018000", 0x440, 26}, + {MODULE_UART8, "/soc/aips-bus@2000000/spba-bus@2000000/serial@2024000", 0x440, 26}, + {MODULE_PWM5, "/soc/aips-bus@2000000/pwm@20f0000", 0x440, 27}, + {MODULE_PWM6, "/soc/aips-bus@2000000/pwm@20f4000", 0x440, 27}, + {MODULE_PWM7, "/soc/aips-bus@2000000/pwm@20f8000", 0x440, 27}, + {MODULE_PWM8, "/soc/aips-bus@2000000/pwm@20fc000", 0x440, 27}, + {MODULE_ECSPI3, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2010000", 0x440, 28}, + {MODULE_ECSPI4, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2014000", 0x440, 28}, + {MODULE_I2C3, "/soc/aips-bus@2100000/i2c@21a8000", 0x440, 29}, + {MODULE_I2C4, "/soc/aips-bus@2100000/i2c@21f8000", 0x440, 29}, + {MODULE_GPT2, "/soc/aips-bus@2000000/gpt@20e8000", 0x440, 30}, + {MODULE_EPIT2, "/soc/aips-bus@2000000/epit@20d4000", 0x440, 31}, + /* Paths for older imx tree: */ + {MODULE_TSC, "/soc/aips-bus@02000000/tsc@02040000", 0x430, 22}, + {MODULE_ADC2, "/soc/aips-bus@02100000/adc@0219c000", 0x430, 23}, + {MODULE_SIM1, "/soc/aips-bus@02100000/sim@0218c000", 0x430, 24}, + {MODULE_SIM2, "/soc/aips-bus@02100000/sim@021b4000", 0x430, 25}, + {MODULE_FLEXCAN1, "/soc/aips-bus@02000000/can@02090000", 0x430, 26}, + {MODULE_FLEXCAN2, "/soc/aips-bus@02000000/can@02094000", 0x430, 27}, + {MODULE_SPDIF, "/soc/aips-bus@02000000/spba-bus@02000000/spdif@02004000", 0x440, 2}, + {MODULE_EIM, "/soc/aips-bus@02100000/weim@021b8000", 0x440, 3}, + {MODULE_SD1, "/soc/aips-bus@02100000/usdhc@02190000", 0x440, 4}, + {MODULE_SD2, "/soc/aips-bus@02100000/usdhc@02194000", 0x440, 5}, + {MODULE_QSPI1, "/soc/aips-bus@02100000/qspi@021e0000", 0x440, 6}, + {MODULE_GPMI, "/soc/gpmi-nand@01806000", 0x440, 7}, + {MODULE_APBHDMA, "/soc/dma-apbh@01804000", 0x440, 7}, + {MODULE_LCDIF, "/soc/aips-bus@02100000/lcdif@021c8000", 0x440, 8}, + {MODULE_PXP, "/soc/aips-bus@02100000/pxp@021cc000", 0x440, 9}, + {MODULE_CSI, "/soc/aips-bus@02100000/csi@021c4000", 0x440, 10}, + {MODULE_ADC1, "/soc/aips-bus@02100000/adc@02198000", 0x440, 11}, + {MODULE_ENET1, "/soc/aips-bus@02100000/ethernet@02188000", 0x440, 12}, + {MODULE_ENET2, "/soc/aips-bus@02000000/ethernet@020b4000", 0x440, 13}, + {MODULE_CAAM, "/soc/aips-bus@02100000/caam@2140000", 0x440, 14}, + {MODULE_USB_OTG2, "/soc/aips-bus@02100000/usb@02184200", 0x440, 15}, + {MODULE_SAI2, "/soc/aips-bus@02000000/spba-bus@02000000/sai@0202c000", 0x440, 24}, + {MODULE_SAI3, "/soc/aips-bus@02000000/spba-bus@02000000/sai@02030000", 0x440, 24}, + {MODULE_BEE, "/soc/aips-bus@02000000/bee@02044000", 0x440, 25}, + {MODULE_UART5, "/soc/aips-bus@02100000/serial@021f4000", 0x440, 26}, + {MODULE_UART6, "/soc/aips-bus@02100000/serial@021fc000", 0x440, 26}, + {MODULE_UART7, "/soc/aips-bus@02000000/spba-bus@02000000/serial@02018000", 0x440, 26}, + {MODULE_UART8, "/soc/aips-bus@02000000/spba-bus@02000000/serial@02024000", 0x440, 26}, + {MODULE_PWM5, "/soc/aips-bus@02000000/pwm@020f0000", 0x440, 27}, + {MODULE_PWM6, "/soc/aips-bus@02000000/pwm@020f4000", 0x440, 27}, + {MODULE_PWM7, "/soc/aips-bus@02000000/pwm@020f8000", 0x440, 27}, + {MODULE_PWM8, "/soc/aips-bus@02000000/pwm@020fc000", 0x440, 27}, + {MODULE_ECSPI3, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02010000", 0x440, 28}, + {MODULE_ECSPI4, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02014000", 0x440, 28}, + {MODULE_I2C3, "/soc/aips-bus@02100000/i2c@021a8000", 0x440, 29}, + {MODULE_I2C4, "/soc/aips-bus@02100000/i2c@021f8000", 0x440, 29}, + {MODULE_GPT2, "/soc/aips-bus@02000000/gpt@020e8000", 0x440, 30}, + {MODULE_EPIT2, "/soc/aips-bus@02000000/epit@020d4000", 0x440, 31}, +#endif +}; + +u32 check_module_fused(enum fuse_module_type module) +{ + u32 i, reg; + + for (i = 0; i < ARRAY_SIZE(mx6_fuse_descs); i++) { + if (mx6_fuse_descs[i].module == module) { + reg = readl(OCOTP_BASE_ADDR + + mx6_fuse_descs[i].fuse_word_offset); + if (reg & BIT(mx6_fuse_descs[i].fuse_bit_offset)) + return 1; /* disabled */ + else + return 0; /* enabled */ + } + } + + return 0; /* Not has a fuse, always enabled */ +} + +#ifdef CONFIG_OF_SYSTEM_SETUP +int ft_system_setup(void *blob, bd_t *bd) +{ + const char *status = "disabled"; + u32 i, reg; + int rc, off; + + for (i = 0; i < ARRAY_SIZE(mx6_fuse_descs); i++) { + reg = readl(OCOTP_BASE_ADDR + + mx6_fuse_descs[i].fuse_word_offset); + if (reg & BIT(mx6_fuse_descs[i].fuse_bit_offset)) { + off = fdt_path_offset(blob, + mx6_fuse_descs[i].node_path); + + if (off < 0) + continue; /* Not found, skip it */ +add_status: + rc = fdt_setprop(blob, nodeoff, "status", status, + strlen(status) + 1); + if (rc) { + if (rc == -FDT_ERR_NOSPACE) { + rc = fdt_increase_size(blob, 512); + if (!rc) + goto add_status; + } + printf("Unable to update property %s:%s, err=%s\n", mx6_fuse_descs[i].node_path, "status", fdt_strerror(rc)); + } else { + printf("Modify %s disabled\n", mx6_fuse_descs[i].node_path); + } + } + } + + return 0; +} +#endif + +u32 esdhc_fused(ulong base_addr) +{ + switch (base_addr) { + case USDHC1_BASE_ADDR: + return check_module_fused(MODULE_SD1); + case USDHC2_BASE_ADDR: + return check_module_fused(MODULE_SD2); +#ifdef USDHC3_BASE_ADDR + case USDHC3_BASE_ADDR: + return check_module_fused(MODULE_SD3); +#endif +#ifdef USDHC4_BASE_ADDR + case USDHC4_BASE_ADDR: + return check_module_fused(MODULE_SD4); +#endif + default: + return 0; + } +} + +u32 ecspi_fused(ulong base_addr) +{ + switch (base_addr) { + case ECSPI1_BASE_ADDR: + return check_module_fused(MODULE_ECSPI1); + case ECSPI2_BASE_ADDR: + return check_module_fused(MODULE_ECSPI2); + case ECSPI3_BASE_ADDR: + return check_module_fused(MODULE_ECSPI3); + case ECSPI4_BASE_ADDR: + return check_module_fused(MODULE_ECSPI4); +#ifdef ECSPI5_BASE_ADDR + case ECSPI5_BASE_ADDR: + return check_module_fused(MODULE_ECSPI5); +#endif + default: + return 0; + } +} + +u32 usb_fused(ulong base_addr) +{ + int i = (base_addr - USB_BASE_ADDR) / 0x200; + + return check_module_fused(MODULE_USB_OTG1 + i); +} + +u32 qspi_fused(ulong base_addr) +{ + switch (base_addr) { +#ifdef QSPI1_BASE_ADDR + case QSPI1_BASE_ADDR: + return check_module_fused(MODULE_QSPI1); +#endif + +#ifdef QSPI2_BASE_ADDR + case QSPI2_BASE_ADDR: + return check_module_fused(MODULE_QSPI2); +#endif + default: + return 0; + } +} + +u32 i2c_fused(ulong base_addr) +{ + switch (base_addr) { + case I2C1_BASE_ADDR: + return check_module_fused(MODULE_I2C1); + case I2C2_BASE_ADDR: + return check_module_fused(MODULE_I2C2); + case I2C3_BASE_ADDR: + return check_module_fused(MODULE_I2C3); +#ifdef I2C4_BASE_ADDR + case I2C4_BASE_ADDR: + return check_module_fused(MODULE_I2C4); +#endif + } + + return 0; +} + +u32 enet_fused(ulong base_addr) +{ + switch (base_addr) { + case ENET_BASE_ADDR: + return check_module_fused(MODULE_ENET1); +#ifdef ENET2_BASE_ADDR + case ENET2_BASE_ADDR: + return check_module_fused(MODULE_ENET2); +#endif + default: + return 0; + } +} From 7d1ee741d1367172eaf92c554ebf56b9cba13504 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 1 May 2020 22:08:35 +0800 Subject: [PATCH 17/82] i2c: mxc: add fuse check Add fuse check for I2C. If the fuse indicates the module will not work in the SoC, let's fail the initialization. Signed-off-by: Peng Fan --- drivers/i2c/mxc_i2c.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index a03c465c8f3..4d6e0e3e759 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -747,6 +748,14 @@ void bus_i2c_init(int index, int speed, int unused, return; } + if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) { + if (i2c_fused((ulong)mxc_i2c_buses[index].base)) { + printf("SoC fuse indicates I2C@0x%lx is unavailable.\n", + (ulong)mxc_i2c_buses[index].base); + return; + } + } + /* * Warning: Be careful to allow the assignment to a static * variable here. This function could be called while U-Boot is @@ -892,6 +901,14 @@ static int mxc_i2c_probe(struct udevice *bus) if (addr == FDT_ADDR_T_NONE) return -EINVAL; + if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) { + if (i2c_fused((ulong)addr)) { + printf("SoC fuse indicates I2C@0x%lx is unavailable.\n", + (ulong)addr); + return -ENODEV; + } + } + i2c_bus->base = addr; i2c_bus->index = bus->seq; i2c_bus->bus = bus; From 0bd3d911df12816ab8e32d9245449aeca484b539 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 1 May 2020 22:08:36 +0800 Subject: [PATCH 18/82] usb: mx6: add fuse check Add fuse check for USB. If the fuse indicates the module will not work in the SoC, let's fail the initialization. Signed-off-by: Peng Fan --- drivers/usb/host/ehci-mx6.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index f2ceb513101..04eb3c006d4 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -380,6 +380,14 @@ int ehci_hcd_init(int index, enum usb_init_type init, if (index > 3) return -EINVAL; + if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) { + if (usb_fused((ulong)ehci)) { + printf("SoC fuse indicates USB@0x%lx is unavailable.\n", + (ulong)ehci); + return -ENODEV; + } + } + ret = ehci_mx6_common_init(ehci, index); if (ret) return ret; @@ -577,6 +585,14 @@ static int ehci_usb_probe(struct udevice *dev) struct ehci_hcor *hcor; int ret; + if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) { + if (usb_fused((ulong)ehci)) { + printf("SoC fuse indicates USB@0x%lx is unavailable.\n", + (ulong)ehci); + return -ENODEV; + } + } + priv->ehci = ehci; priv->portnr = dev->seq; priv->init_type = type; From 3b26d527d355c00eb9a0b2b0c11536e4e62c10aa Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 1 May 2020 22:08:37 +0800 Subject: [PATCH 19/82] net: fec: add fuse check Add fuse check for fec. If the fuse indicates the module will not work in the SoC, let's fail the initialization. Signed-off-by: Peng Fan Acked-by: Joe Hershberger --- drivers/net/fec_mxc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 345d37be4e8..3046305cfb6 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1204,6 +1204,13 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) #endif int ret; + if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) { + if (enet_fused((ulong)addr)) { + printf("SoC fuse indicates Ethernet@0x%x is unavailable.\n", addr); + return -ENODEV; + } + } + #ifdef CONFIG_FEC_MXC_MDIO_BASE /* * The i.MX28 has two ethernet interfaces, but they are not equal. @@ -1342,6 +1349,13 @@ static int fecmxc_probe(struct udevice *dev) uint32_t start; int ret; + if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) { + if (enet_fused((ulong)priv->eth)) { + printf("SoC fuse indicates Ethernet@0x%lx is unavailable.\n", (ulong)priv->eth); + return -ENODEV; + } + } + if (IS_ENABLED(CONFIG_IMX8)) { ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk); if (ret < 0) { From d19c1cb525eddfbdf719356b750189a77cefc020 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 1 May 2020 17:46:36 -0300 Subject: [PATCH 20/82] imx8mq_phanbell: Run SPL with caches enabled It is safe to run SPL with caches enabled on i.MX8M, so remove such restriction. Signed-off-by: Fabio Estevam --- configs/imx8mq_phanbell_defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/configs/imx8mq_phanbell_defconfig b/configs/imx8mq_phanbell_defconfig index d1e9cc40177..651940ccf69 100644 --- a/configs/imx8mq_phanbell_defconfig +++ b/configs/imx8mq_phanbell_defconfig @@ -1,6 +1,4 @@ CONFIG_ARM=y -CONFIG_SPL_SYS_ICACHE_OFF=y -CONFIG_SPL_SYS_DCACHE_OFF=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_TEXT_BASE=0x40200000 CONFIG_SYS_MALLOC_F_LEN=0x4000 From a6979f78bcba76611e5e3fd6226b5b79c8021c2e Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 21:01:27 +0800 Subject: [PATCH 21/82] pinctrl: nxp: scu: Check the pad partition before set pinmux If a pad is not owned by current partition we should not set its pinmux. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/pinctrl/nxp/pinctrl-scu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/nxp/pinctrl-scu.c b/drivers/pinctrl/nxp/pinctrl-scu.c index aa11075e0a7..c032be782a1 100644 --- a/drivers/pinctrl/nxp/pinctrl-scu.c +++ b/drivers/pinctrl/nxp/pinctrl-scu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2018 NXP + * Copyright 2018-2019 NXP */ #include @@ -29,6 +29,11 @@ static int imx_pinconf_scu_set(struct imx_pinctrl_soc_info *info, u32 pad, * to handle that in scfw, so config it in pad conf func */ + if (!sc_rm_is_pad_owned(-1, pad)) { + debug("Pad[%u] is not owned by curr partition\n", pad); + return -EPERM; + } + val |= PADRING_IFMUX_EN_MASK; val |= PADRING_GP_EN_MASK; val |= (mux << PADRING_IFMUX_SHIFT) & PADRING_IFMUX_MASK; @@ -57,7 +62,7 @@ int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, u32 *pin_data, config_val = pin_data[j++]; ret = imx_pinconf_scu_set(info, pin_id, mux, config_val); - if (ret) + if (ret && ret != -EPERM) printf("Set pin %d, mux %d, val %d, error\n", pin_id, mux, config_val); } From d2b70205dd67f32427dde4f1a7a8966f4924dfad Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:41:13 +0800 Subject: [PATCH 22/82] net: eth-uclass: add return value check Add return value check Signed-off-by: Peng Fan --- net/eth-uclass.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 8bf2eabe902..950a48d520d 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -40,8 +40,12 @@ static int eth_errno; static struct eth_uclass_priv *eth_get_uclass_priv(void) { struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_ETH, &uc); + if (ret) + return NULL; - uclass_get(UCLASS_ETH, &uc); assert(uc); return uc->priv; } @@ -102,6 +106,7 @@ struct udevice *eth_get_dev_by_name(const char *devname) struct udevice *it; struct uclass *uc; int len = strlen("eth"); + int ret; /* Must be longer than 3 to be an alias */ if (!strncmp(devname, "eth", len) && strlen(devname) > len) { @@ -109,7 +114,10 @@ struct udevice *eth_get_dev_by_name(const char *devname) seq = simple_strtoul(startp, &endp, 10); } - uclass_get(UCLASS_ETH, &uc); + ret = uclass_get(UCLASS_ETH, &uc); + if (ret) + return NULL; + uclass_foreach_dev(it, uc) { /* * We need the seq to be valid, so try to probe it. From 5fe419ef2a6154e83aab04c65ec906fef96eb5be Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:41:14 +0800 Subject: [PATCH 23/82] net: Add eth phy generic driver for shared MDIO For dual ethernet controllers, the HW design may connect ETH phys to one MDIO ports. So two different ethernet drivers have to share MDIO bus. Since two ethernet drivers are independent, we can't ensure their probe order. To resolve this problem, introduce an eth phy generic driver and uclass. After eth-uclass binds, we search the mdio node and binds the phy node with the eth-phy-generic driver. When one eth driver get its phy device, the parent of phy device will probe prior than phy device. So this ensure the eth driver ownes the MDIO bus will be probed before using its MDIO. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/net/Kconfig | 6 ++ drivers/net/Makefile | 1 + drivers/net/eth-phy-uclass.c | 122 +++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/eth_phy.h | 17 +++++ net/eth-uclass.c | 5 ++ 6 files changed, 152 insertions(+) create mode 100644 drivers/net/eth-phy-uclass.c create mode 100644 include/eth_phy.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a2587a29e16..38f2bd6637d 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -57,6 +57,12 @@ config MDIO_MUX_SANDBOX This driver is used for testing in test/dm/mdio.c +config DM_ETH_PHY + bool "Enable Driver Model for Ethernet Generic PHY drivers" + depends on DM + help + Enable driver model for Ethernet Generic PHY . + menuconfig NETDEVICES bool "Network device support" depends on NET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 6d9b8772b1a..383ed1c64f7 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_ETH_DESIGNWARE) += designware.o obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DNET) += dnet.o +obj-$(CONFIG_DM_ETH_PHY) += eth-phy-uclass.o obj-$(CONFIG_E1000) += e1000.o obj-$(CONFIG_E1000_SPI) += e1000_spi.o obj-$(CONFIG_EEPRO100) += eepro100.o diff --git a/drivers/net/eth-phy-uclass.c b/drivers/net/eth-phy-uclass.c new file mode 100644 index 00000000000..b383f455276 --- /dev/null +++ b/drivers/net/eth-phy-uclass.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 NXP + */ + +#include +#include +#include +#include +#include +#include + +struct eth_phy_device_priv { + struct mii_dev *mdio_bus; +}; + +int eth_phy_binds_nodes(struct udevice *eth_dev) +{ + ofnode mdio_node, phy_node; + const char *node_name; + int ret; + + mdio_node = dev_read_subnode(eth_dev, "mdio"); + if (!ofnode_valid(mdio_node)) { + debug("%s: %s mdio subnode not found!", __func__, + eth_dev->name); + return -ENXIO; + } + + ofnode_for_each_subnode(phy_node, mdio_node) { + node_name = ofnode_get_name(phy_node); + + debug("* Found child node: '%s'\n", node_name); + + ret = device_bind_driver_to_node(eth_dev, + "eth_phy_generic_drv", + node_name, phy_node, NULL); + if (ret) { + debug(" - Eth phy binding error: %d\n", ret); + continue; + } + + debug(" - bound phy device: '%s'\n", node_name); + } + + return 0; +} + +int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus) +{ + struct udevice *dev; + struct eth_phy_device_priv *uc_priv; + + for (uclass_first_device(UCLASS_ETH_PHY, &dev); dev; + uclass_next_device(&dev)) { + if (dev->parent == eth_dev) { + uc_priv = (struct eth_phy_device_priv *)(dev->uclass_priv); + + if (!uc_priv->mdio_bus) + uc_priv->mdio_bus = mdio_bus; + } + } + + return 0; +} + +struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev) +{ + int ret; + struct udevice *phy_dev; + struct eth_phy_device_priv *uc_priv; + + /* Will probe the parent of phy device, then phy device */ + ret = uclass_get_device_by_phandle(UCLASS_ETH_PHY, eth_dev, + "phy-handle", &phy_dev); + if (!ret) { + if (eth_dev != phy_dev->parent) { + /* + * phy_dev is shared and controlled by + * other eth controller + */ + uc_priv = (struct eth_phy_device_priv *)(phy_dev->uclass_priv); + if (uc_priv->mdio_bus) + printf("Get shared mii bus on %s\n", eth_dev->name); + else + printf("Can't get shared mii bus on %s\n", eth_dev->name); + + return uc_priv->mdio_bus; + } + } else { + printf("FEC: can't find phy-handle\n"); + } + + return NULL; +} + +int eth_phy_get_addr(struct udevice *dev) +{ + struct ofnode_phandle_args phandle_args; + int reg; + + if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, + &phandle_args)) { + debug("Failed to find phy-handle"); + return -ENODEV; + } + + reg = ofnode_read_u32_default(phandle_args.node, "reg", 0); + + return reg; +} + +UCLASS_DRIVER(eth_phy_generic) = { + .id = UCLASS_ETH_PHY, + .name = "eth_phy_generic", + .per_device_auto_alloc_size = sizeof(struct eth_phy_device_priv), +}; + +U_BOOT_DRIVER(eth_phy_generic_drv) = { + .name = "eth_phy_generic_drv", + .id = UCLASS_ETH_PHY, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 37ada51f9f7..7837d459f18 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -47,6 +47,7 @@ enum uclass_id { UCLASS_DMA, /* Direct Memory Access */ UCLASS_EFI, /* EFI managed devices */ UCLASS_ETH, /* Ethernet device */ + UCLASS_ETH_PHY, /* Ethernet PHY device */ UCLASS_FIRMWARE, /* Firmware */ UCLASS_FS_FIRMWARE_LOADER, /* Generic loader */ UCLASS_GPIO, /* Bank of general-purpose I/O pins */ diff --git a/include/eth_phy.h b/include/eth_phy.h new file mode 100644 index 00000000000..19c496551b4 --- /dev/null +++ b/include/eth_phy.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 NXP + */ + +#ifndef _eth_phy_h_ +#define _eth_phy_h_ + +#include +#include + +int eth_phy_binds_nodes(struct udevice *eth_dev); +int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus); +struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev); +int eth_phy_get_addr(struct udevice *dev); + +#endif diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 950a48d520d..48560d59f66 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -13,6 +13,7 @@ #include #include #include "eth_internal.h" +#include DECLARE_GLOBAL_DATA_PTR; @@ -461,6 +462,10 @@ static int eth_post_bind(struct udevice *dev) return -EINVAL; } +#ifdef CONFIG_DM_ETH_PHY + eth_phy_binds_nodes(dev); +#endif + return 0; } From 6a895d039ba7ddcff3d49836b6642573792d7067 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:41:15 +0800 Subject: [PATCH 24/82] net: Update eQos driver and FEC driver to use eth phy interfaces Update eQoS and fec ethernet drivers to support shared MDIO framework Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 45 +++++++++++++++++++++++++++------------ drivers/net/fec_mxc.c | 20 +++++++++++++---- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 60dfd17a74d..bdddbdef7f0 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -41,6 +41,7 @@ #include #include #include +#include /* Core registers */ @@ -1083,7 +1084,14 @@ static int eqos_start(struct udevice *dev) * don't need to reconnect/reconfigure again */ if (!eqos->phy) { - eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev, + int addr = -1; +#ifdef CONFIG_DM_ETH_PHY + addr = eth_phy_get_addr(dev); +#endif +#ifdef DWC_NET_PHYADDR + addr = DWC_NET_PHYADDR; +#endif + eqos->phy = phy_connect(eqos->mii, addr, dev, eqos->config->interface(dev)); if (!eqos->phy) { pr_err("phy_connect() failed"); @@ -1820,23 +1828,32 @@ static int eqos_probe(struct udevice *dev) goto err_remove_resources_core; } - eqos->mii = mdio_alloc(); +#ifdef CONFIG_DM_ETH_PHY + eqos->mii = eth_phy_get_mdio_bus(dev); +#endif if (!eqos->mii) { - pr_err("mdio_alloc() failed"); - ret = -ENOMEM; - goto err_remove_resources_tegra; - } - eqos->mii->read = eqos_mdio_read; - eqos->mii->write = eqos_mdio_write; - eqos->mii->priv = eqos; - strcpy(eqos->mii->name, dev->name); + eqos->mii = mdio_alloc(); + if (!eqos->mii) { + pr_err("mdio_alloc() failed"); + ret = -ENOMEM; + goto err_remove_resources_tegra; + } + eqos->mii->read = eqos_mdio_read; + eqos->mii->write = eqos_mdio_write; + eqos->mii->priv = eqos; + strcpy(eqos->mii->name, dev->name); - ret = mdio_register(eqos->mii); - if (ret < 0) { - pr_err("mdio_register() failed: %d", ret); - goto err_free_mdio; + ret = mdio_register(eqos->mii); + if (ret < 0) { + pr_err("mdio_register() failed: %d", ret); + goto err_free_mdio; + } } +#ifdef CONFIG_DM_ETH_PHY + eth_phy_set_mdio_bus(dev, eqos->mii); +#endif + debug("%s: OK\n", __func__); return 0; diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 3046305cfb6..910c961a60e 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -28,6 +28,7 @@ #include #include "fec_mxc.h" +#include DECLARE_GLOBAL_DATA_PTR; @@ -1444,16 +1445,27 @@ static int fecmxc_probe(struct udevice *dev) fec_reg_setup(priv); priv->dev_id = dev->seq; -#ifdef CONFIG_FEC_MXC_MDIO_BASE - bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, dev->seq); -#else - bus = fec_get_miibus((ulong)priv->eth, dev->seq); + +#ifdef CONFIG_DM_ETH_PHY + bus = eth_phy_get_mdio_bus(dev); #endif + + if (!bus) { +#ifdef CONFIG_FEC_MXC_MDIO_BASE + bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, dev->seq); +#else + bus = fec_get_miibus((ulong)priv->eth, dev->seq); +#endif + } if (!bus) { ret = -ENOMEM; goto err_mii; } +#ifdef CONFIG_DM_ETH_PHY + eth_phy_set_mdio_bus(dev, bus); +#endif + priv->bus = bus; priv->interface = pdata->phy_interface; switch (priv->interface) { From e32e4d0f58cb0ca5fc77aa3f5745c1910b13c68b Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Sun, 3 May 2020 22:41:16 +0800 Subject: [PATCH 25/82] net: phy: realtek: add rx delay support for RTL8211F Add RX delay enable support for RTL8211F PHY. Reviewed-by: Ye Li Signed-off-by: Fugang Duan Signed-off-by: Peng Fan --- drivers/net/phy/realtek.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 8f1d7596325..8f0a897a46d 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -56,6 +56,7 @@ #define MIIM_RTL8211F_PAGE_SELECT 0x1f #define MIIM_RTL8211F_TX_DELAY 0x100 +#define MIIM_RTL8211F_RX_DELAY 0x8 #define MIIM_RTL8211F_LCR 0x10 static int rtl8211f_phy_extread(struct phy_device *phydev, int addr, @@ -183,6 +184,16 @@ static int rtl8211f_config(struct phy_device *phydev) reg &= ~MIIM_RTL8211F_TX_DELAY; phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg); + + /* enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it */ + reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x15); + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || + phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + reg |= MIIM_RTL8211F_RX_DELAY; + else + reg &= ~MIIM_RTL8211F_RX_DELAY; + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, reg); + /* restore to default page 0 */ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0x0); From 3a97da12ee7bfa132d4ffb1ed1b224213cf81056 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Sun, 3 May 2020 22:41:17 +0800 Subject: [PATCH 26/82] net: dwc_eth_qos: add dwc eqos for imx support Add dwc eqos for imx support. Reviewed-by: Ye Li Signed-off-by: Fugang Duan Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 185 +++++++++++++++++++++++++++++++++++--- 1 file changed, 171 insertions(+), 14 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index bdddbdef7f0..75c70663c9e 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -81,6 +81,7 @@ struct eqos_mac_regs { #define EQOS_MAC_CONFIGURATION_PS BIT(15) #define EQOS_MAC_CONFIGURATION_FES BIT(14) #define EQOS_MAC_CONFIGURATION_DM BIT(13) +#define EQOS_MAC_CONFIGURATION_LM BIT(12) #define EQOS_MAC_CONFIGURATION_TE BIT(1) #define EQOS_MAC_CONFIGURATION_RE BIT(0) @@ -102,11 +103,19 @@ struct eqos_mac_regs { #define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff +#define EQOS_MAC_HW_FEATURE0_MMCSEL_SHIFT 8 +#define EQOS_MAC_HW_FEATURE0_HDSEL_SHIFT 2 +#define EQOS_MAC_HW_FEATURE0_GMIISEL_SHIFT 1 +#define EQOS_MAC_HW_FEATURE0_MIISEL_SHIFT 0 + #define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT 6 #define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_MASK 0x1f #define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT 0 #define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_MASK 0x1f +#define EQOS_MAC_HW_FEATURE3_ASP_SHIFT 28 +#define EQOS_MAC_HW_FEATURE3_ASP_MASK 0x3 + #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 @@ -154,6 +163,8 @@ struct eqos_mtl_regs { #define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK 0x3f #define EQOS_MTL_RXQ0_OPERATION_MODE_EHFC BIT(7) #define EQOS_MTL_RXQ0_OPERATION_MODE_RSF BIT(5) +#define EQOS_MTL_RXQ0_OPERATION_MODE_FEP BIT(4) +#define EQOS_MTL_RXQ0_OPERATION_MODE_FUP BIT(3) #define EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16 #define EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK 0x7fff @@ -368,7 +379,7 @@ static void eqos_inval_desc_tegra186(void *desc) #endif } -static void eqos_inval_desc_stm32(void *desc) +static void eqos_inval_desc_generic(void *desc) { #ifndef CONFIG_SYS_NONCACHED_MEMORY unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); @@ -386,7 +397,7 @@ static void eqos_flush_desc_tegra186(void *desc) #endif } -static void eqos_flush_desc_stm32(void *desc) +static void eqos_flush_desc_generic(void *desc) { #ifndef CONFIG_SYS_NONCACHED_MEMORY unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); @@ -405,7 +416,7 @@ static void eqos_inval_buffer_tegra186(void *buf, size_t size) invalidate_dcache_range(start, end); } -static void eqos_inval_buffer_stm32(void *buf, size_t size) +static void eqos_inval_buffer_generic(void *buf, size_t size) { unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN); unsigned long end = roundup((unsigned long)buf + size, @@ -419,7 +430,7 @@ static void eqos_flush_buffer_tegra186(void *buf, size_t size) flush_cache((unsigned long)buf, size); } -static void eqos_flush_buffer_stm32(void *buf, size_t size) +static void eqos_flush_buffer_generic(void *buf, size_t size) { unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN); unsigned long end = roundup((unsigned long)buf + size, @@ -522,6 +533,7 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, static int eqos_start_clks_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -562,10 +574,12 @@ static int eqos_start_clks_tegra186(struct udevice *dev) pr_err("clk_enable(clk_tx) failed: %d", ret); goto err_disable_clk_ptp_ref; } +#endif debug("%s: OK\n", __func__); return 0; +#ifdef CONFIG_CLK err_disable_clk_ptp_ref: clk_disable(&eqos->clk_ptp_ref); err_disable_clk_rx: @@ -577,10 +591,12 @@ err_disable_clk_slave_bus: err: debug("%s: FAILED: %d\n", __func__, ret); return ret; +#endif } static int eqos_start_clks_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -611,10 +627,12 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err_disable_clk_tx; } } +#endif debug("%s: OK\n", __func__); return 0; +#ifdef CONFIG_CLK err_disable_clk_tx: clk_disable(&eqos->clk_tx); err_disable_clk_rx: @@ -624,10 +642,17 @@ err_disable_clk_master_bus: err: debug("%s: FAILED: %d\n", __func__, ret); return ret; +#endif +} + +static int eqos_start_clks_imx(struct udevice *dev) +{ + return 0; } static void eqos_stop_clks_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); @@ -637,12 +662,14 @@ static void eqos_stop_clks_tegra186(struct udevice *dev) clk_disable(&eqos->clk_rx); clk_disable(&eqos->clk_master_bus); clk_disable(&eqos->clk_slave_bus); +#endif debug("%s: OK\n", __func__); } static void eqos_stop_clks_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); @@ -652,10 +679,16 @@ static void eqos_stop_clks_stm32(struct udevice *dev) clk_disable(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_disable(&eqos->clk_ck); +#endif debug("%s: OK\n", __func__); } +static void eqos_stop_clks_imx(struct udevice *dev) +{ + /* empty */ +} + static int eqos_start_resets_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -723,6 +756,11 @@ static int eqos_start_resets_stm32(struct udevice *dev) return 0; } +static int eqos_start_resets_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_stop_resets_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -750,6 +788,11 @@ static int eqos_stop_resets_stm32(struct udevice *dev) return 0; } +static int eqos_stop_resets_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_calibrate_pads_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -804,16 +847,30 @@ static int eqos_disable_calibration_tegra186(struct udevice *dev) static ulong eqos_get_tick_clk_rate_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); return clk_get_rate(&eqos->clk_slave_bus); +#else + return 0; +#endif } static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); return clk_get_rate(&eqos->clk_master_bus); +#else + return 0; +#endif +} + +static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev) +{ + /* TODO: retrieve from CSR clock */ + return 100 * 1000000; } static int eqos_calibrate_pads_stm32(struct udevice *dev) @@ -821,11 +878,21 @@ static int eqos_calibrate_pads_stm32(struct udevice *dev) return 0; } +static int eqos_calibrate_pads_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_disable_calibration_stm32(struct udevice *dev) { return 0; } +static int eqos_disable_calibration_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_set_full_duplex(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -890,6 +957,7 @@ static int eqos_set_mii_speed_10(struct udevice *dev) static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); ulong rate; int ret; @@ -916,6 +984,7 @@ static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev) pr_err("clk_set_rate(tx_clk, %lu) failed: %d", rate, ret); return ret; } +#endif return 0; } @@ -925,6 +994,11 @@ static int eqos_set_tx_clk_speed_stm32(struct udevice *dev) return 0; } +static int eqos_set_tx_clk_speed_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_adjust_link(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1131,6 +1205,7 @@ static int eqos_start(struct udevice *dev) } /* Configure MTL */ + writel(0x60, &eqos->mtl_regs->txq0_quantum_weight - 0x100); /* Enable Store and Forward mode for TX */ /* Program Tx operating mode */ @@ -1144,7 +1219,9 @@ static int eqos_start(struct udevice *dev) /* Enable Store and Forward mode for RX, since no jumbo frame */ setbits_le32(&eqos->mtl_regs->rxq0_operation_mode, - EQOS_MTL_RXQ0_OPERATION_MODE_RSF); + EQOS_MTL_RXQ0_OPERATION_MODE_RSF | + EQOS_MTL_RXQ0_OPERATION_MODE_FEP | + EQOS_MTL_RXQ0_OPERATION_MODE_FUP); /* Transmit/Receive queue fifo size; use all RAM for 1 queue */ val = readl(&eqos->mac_regs->hw_feature1); @@ -1220,6 +1297,19 @@ static int eqos_start(struct udevice *dev) eqos->config->config_mac << EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT); + clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0, + EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK << + EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT, + 0x2 << + EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT); + + /* Multicast and Broadcast Queue Enable */ + setbits_le32(&eqos->mac_regs->unused_0a4, + 0x00100000); + /* enable promise mode */ + setbits_le32(&eqos->mac_regs->unused_004[1], + 0x1); + /* Set TX flow control parameters */ /* Set Pause Time */ setbits_le32(&eqos->mac_regs->q0_tx_flow_ctrl, @@ -1297,7 +1387,11 @@ static int eqos_start(struct udevice *dev) rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf + (i * EQOS_MAX_PACKET_SIZE)); rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; + mb(); eqos->config->ops->eqos_flush_desc(rx_desc); + eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf + + (i * EQOS_MAX_PACKET_SIZE), + EQOS_MAX_PACKET_SIZE); } writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress); @@ -1311,14 +1405,12 @@ static int eqos_start(struct udevice *dev) &eqos->dma_regs->ch0_rxdesc_ring_length); /* Enable everything */ - - setbits_le32(&eqos->mac_regs->configuration, - EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE); - setbits_le32(&eqos->dma_regs->ch0_tx_control, EQOS_DMA_CH0_TX_CONTROL_ST); setbits_le32(&eqos->dma_regs->ch0_rx_control, EQOS_DMA_CH0_RX_CONTROL_SR); + setbits_le32(&eqos->mac_regs->configuration, + EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE); /* TX tail pointer not written until we need to TX a packet */ /* @@ -1483,6 +1575,8 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) return -EINVAL; } + eqos->config->ops->eqos_inval_buffer(packet, length); + rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); rx_desc->des0 = 0; @@ -1759,17 +1853,42 @@ static phy_interface_t eqos_get_interface_tegra186(struct udevice *dev) return PHY_INTERFACE_MODE_MII; } +static int eqos_probe_resources_imx(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + phy_interface_t interface; + + debug("%s(dev=%p):\n", __func__, dev); + + interface = eqos->config->interface(dev); + + if (interface == PHY_INTERFACE_MODE_NONE) { + pr_err("Invalid PHY interface\n"); + return -EINVAL; + } + + debug("%s: OK\n", __func__); + return 0; +} + +static phy_interface_t eqos_get_interface_imx(struct udevice *dev) +{ + return PHY_INTERFACE_MODE_RGMII; +} + static int eqos_remove_resources_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); +#ifdef CONFIG_CLK clk_free(&eqos->clk_tx); clk_free(&eqos->clk_ptp_ref); clk_free(&eqos->clk_rx); clk_free(&eqos->clk_slave_bus); clk_free(&eqos->clk_master_bus); +#endif dm_gpio_free(dev, &eqos->phy_reset_gpio); reset_free(&eqos->reset_ctl); @@ -1779,6 +1898,7 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) static int eqos_remove_resources_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); @@ -1788,6 +1908,7 @@ static int eqos_remove_resources_stm32(struct udevice *dev) clk_free(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_free(&eqos->clk_ck); +#endif if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) dm_gpio_free(dev, &eqos->phy_reset_gpio); @@ -1796,6 +1917,11 @@ static int eqos_remove_resources_stm32(struct udevice *dev) return 0; } +static int eqos_remove_resources_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1921,10 +2047,10 @@ static const struct eqos_config eqos_tegra186_config = { }; static struct eqos_ops eqos_stm32_ops = { - .eqos_inval_desc = eqos_inval_desc_stm32, - .eqos_flush_desc = eqos_flush_desc_stm32, - .eqos_inval_buffer = eqos_inval_buffer_stm32, - .eqos_flush_buffer = eqos_flush_buffer_stm32, + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_stm32, .eqos_remove_resources = eqos_remove_resources_stm32, .eqos_stop_resets = eqos_stop_resets_stm32, @@ -1947,6 +2073,33 @@ static const struct eqos_config eqos_stm32_config = { .ops = &eqos_stm32_ops }; +static struct eqos_ops eqos_imx_ops = { + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, + .eqos_probe_resources = eqos_probe_resources_imx, + .eqos_remove_resources = eqos_remove_resources_imx, + .eqos_stop_resets = eqos_stop_resets_imx, + .eqos_start_resets = eqos_start_resets_imx, + .eqos_stop_clks = eqos_stop_clks_imx, + .eqos_start_clks = eqos_start_clks_imx, + .eqos_calibrate_pads = eqos_calibrate_pads_imx, + .eqos_disable_calibration = eqos_disable_calibration_imx, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx +}; + +struct eqos_config eqos_imx_config = { + .reg_access_always_ok = false, + .mdio_wait = 10000, + .swr_wait = 50, + .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, + .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, + .interface = eqos_get_interface_imx, + .ops = &eqos_imx_ops +}; + static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", @@ -1956,6 +2109,10 @@ static const struct udevice_id eqos_ids[] = { .compatible = "snps,dwmac-4.20a", .data = (ulong)&eqos_stm32_config }, + { + .compatible = "fsl,imx-eqos", + .data = (ulong)&eqos_imx_config + }, { } }; @@ -1963,7 +2120,7 @@ static const struct udevice_id eqos_ids[] = { U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, - .of_match = eqos_ids, + .of_match = of_match_ptr(eqos_ids), .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, From 0e9d23945ce0b739a6ac13c11b0fdaba09a8dacc Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Sun, 3 May 2020 22:41:18 +0800 Subject: [PATCH 27/82] net: eqos: implement callbaks to get interface and set txclk rate Implement the callbacks to get phy mode interface and txclk rate configuration. Reviewed-by: Ye Li Signed-off-by: Fugang Duan Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 55 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 75c70663c9e..e4fc76cc068 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -42,6 +42,10 @@ #include #include #include +#ifdef CONFIG_ARCH_IMX8M +#include +#include +#endif /* Core registers */ @@ -867,10 +871,18 @@ static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) #endif } +__weak u32 imx_get_eqos_csr_clk(void) +{ + return 100 * 1000000; +} +__weak int imx_eqos_txclk_set_rate(unsigned long rate) +{ + return 0; +} + static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev) { - /* TODO: retrieve from CSR clock */ - return 100 * 1000000; + return imx_get_eqos_csr_clk(); } static int eqos_calibrate_pads_stm32(struct udevice *dev) @@ -996,6 +1008,33 @@ static int eqos_set_tx_clk_speed_stm32(struct udevice *dev) static int eqos_set_tx_clk_speed_imx(struct udevice *dev) { + struct eqos_priv *eqos = dev_get_priv(dev); + ulong rate; + int ret; + + debug("%s(dev=%p):\n", __func__, dev); + + switch (eqos->phy->speed) { + case SPEED_1000: + rate = 125 * 1000 * 1000; + break; + case SPEED_100: + rate = 25 * 1000 * 1000; + break; + case SPEED_10: + rate = 2.5 * 1000 * 1000; + break; + default: + pr_err("invalid speed %d", eqos->phy->speed); + return -EINVAL; + } + + ret = imx_eqos_txclk_set_rate(rate); + if (ret < 0) { + pr_err("imx (tx_clk, %lu) failed: %d", rate, ret); + return ret; + } + return 0; } @@ -1873,7 +1912,17 @@ static int eqos_probe_resources_imx(struct udevice *dev) static phy_interface_t eqos_get_interface_imx(struct udevice *dev) { - return PHY_INTERFACE_MODE_RGMII; + const char *phy_mode; + phy_interface_t interface = PHY_INTERFACE_MODE_NONE; + + debug("%s(dev=%p):\n", __func__, dev); + + phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", + NULL); + if (phy_mode) + interface = phy_get_interface_by_name(phy_mode); + + return interface; } static int eqos_remove_resources_tegra186(struct udevice *dev) From 9d4194f179b2c19c6732b9e2794a3d5153144492 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:41:19 +0800 Subject: [PATCH 28/82] fec: Move imx_get_mac_from_fuse declare to imx file imx_get_mac_from_fuse is used to load MAC address from fuse. On imx8mp, we have two different ENET controllers and both need to call this function. So decouple its declare from fec driver. Reviewed-by: Fugang Duan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/sys_proto.h | 2 ++ drivers/net/fec_mxc.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index b91b2137745..927195f87ac 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -198,4 +198,6 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0, unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0, unsigned long *reg1, unsigned long reg2, unsigned long reg3); + +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac); #endif diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 3c8fdda2638..0e8f08a51a1 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -273,8 +273,6 @@ struct fec_priv { u32 clk_rate; }; -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac); - /** * @brief Numbers of buffer descriptors for receiving * From 580fab4a821d50021f251452a6a3c056f0280941 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:41:20 +0800 Subject: [PATCH 29/82] eQos: Implement the read_rom_hwaddr callback Implement the read_rom_hwaddr callback to load MAC address from fuse for imx8m platforms. Reviewed-by: Fugang Duan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e4fc76cc068..f67c5f45707 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1145,6 +1145,16 @@ static int eqos_write_hwaddr(struct udevice *dev) return 0; } +static int eqos_read_rom_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + +#ifdef CONFIG_ARCH_IMX8M + imx_get_mac_from_fuse(dev->req_seq, pdata->enetaddr); +#endif + return !is_valid_ethaddr(pdata->enetaddr); +} + static int eqos_start(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -2066,6 +2076,7 @@ static const struct eth_ops eqos_ops = { .recv = eqos_recv, .free_pkt = eqos_free_pkt, .write_hwaddr = eqos_write_hwaddr, + .read_rom_hwaddr = eqos_read_rom_hwaddr, }; static struct eqos_ops eqos_tegra186_ops = { From 6039d669f4eaf9f2b7442bafb89efaa32a8ee567 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:19:45 +0800 Subject: [PATCH 30/82] thermal: imx_scu_thermal: Update driver for i.MX8QM thermal sensor Add iMX8QM thermal compatible string and its driver data. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/thermal/imx_scu_thermal.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/thermal/imx_scu_thermal.c b/drivers/thermal/imx_scu_thermal.c index 7e17377b696..da13121a090 100644 --- a/drivers/thermal/imx_scu_thermal.c +++ b/drivers/thermal/imx_scu_thermal.c @@ -179,12 +179,20 @@ static int imx_sc_thermal_ofdata_to_platdata(struct udevice *dev) return 0; } +static const sc_rsrc_t imx8qm_sensor_rsrc[] = { + SC_R_A53, SC_R_A72, SC_R_GPU_0_PID0, SC_R_GPU_1_PID0, + SC_R_DRC_0, SC_R_DRC_1, SC_R_VPU_PID0, SC_R_PMIC_0, + SC_R_PMIC_1, SC_R_PMIC_2, +}; + static const sc_rsrc_t imx8qxp_sensor_rsrc[] = { SC_R_SYSTEM, SC_R_DRC_0, SC_R_PMIC_0, SC_R_PMIC_1, SC_R_PMIC_2, }; static const struct udevice_id imx_sc_thermal_ids[] = { + { .compatible = "nxp,imx8qm-sc-tsens", .data = + (ulong)&imx8qm_sensor_rsrc, }, { .compatible = "nxp,imx8qxp-sc-tsens", .data = (ulong)&imx8qxp_sensor_rsrc, }, { } From 2cd7f47983a38397c32bdf4fefeb35cd13600edb Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:46 +0800 Subject: [PATCH 31/82] thermal: Add thermal driver for i.MX8M The driver is ported form Linux Kernel and support driver model. Users need to provide the tmu node and sensors nodes in DTB. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/thermal/Kconfig | 9 ++ drivers/thermal/Makefile | 1 + drivers/thermal/imx_tmu.c | 325 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 335 insertions(+) create mode 100644 drivers/thermal/imx_tmu.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index bdf8dc6fef5..97d4163e8ed 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -26,6 +26,15 @@ config IMX_SCU_THERMAL boot is hold to the cool device to throttle CPUs when the passive trip is crossed +config IMX_TMU + bool "Thermal Management Unit driver for NXP i.MX8M" + depends on ARCH_IMX8M + help + Support for Temperature sensors on NXP i.MX8M. + It supports one critical trip point and one passive trip point. + The boot is hold to the cool device to throttle CPUs when the + passive trip is crossed + config TI_DRA7_THERMAL bool "Temperature sensor driver for TI dra7xx SOCs" help diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index ef2929d1808..15fe847d9f7 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o obj-$(CONFIG_IMX_SCU_THERMAL) += imx_scu_thermal.o obj-$(CONFIG_TI_DRA7_THERMAL) += ti-bandgap.o +obj-$(CONFIG_IMX_TMU) += imx_tmu.o diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c new file mode 100644 index 00000000000..f496ce03b65 --- /dev/null +++ b/drivers/thermal/imx_tmu.c @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017~2020 NXP + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define SITES_MAX 16 + +#define TMR_DISABLE 0x0 +#define TMR_ME 0x80000000 +#define TMR_ALPF 0x0c000000 +#define TMTMIR_DEFAULT 0x00000002 +#define TIER_DISABLE 0x0 + +/* + * i.MX TMU Registers + */ +struct imx_tmu_site_regs { + u32 tritsr; /* Immediate Temperature Site Register */ + u32 tratsr; /* Average Temperature Site Register */ + u8 res0[0x8]; +}; + +struct imx_tmu_regs { + u32 tmr; /* Mode Register */ + u32 tsr; /* Status Register */ + u32 tmtmir; /* Temperature measurement interval Register */ + u8 res0[0x14]; + u32 tier; /* Interrupt Enable Register */ + u32 tidr; /* Interrupt Detect Register */ + u32 tiscr; /* Interrupt Site Capture Register */ + u32 ticscr; /* Interrupt Critical Site Capture Register */ + u8 res1[0x10]; + u32 tmhtcrh; /* High Temperature Capture Register */ + u32 tmhtcrl; /* Low Temperature Capture Register */ + u8 res2[0x8]; + u32 tmhtitr; /* High Temperature Immediate Threshold */ + u32 tmhtatr; /* High Temperature Average Threshold */ + u32 tmhtactr; /* High Temperature Average Crit Threshold */ + u8 res3[0x24]; + u32 ttcfgr; /* Temperature Configuration Register */ + u32 tscfgr; /* Sensor Configuration Register */ + u8 res4[0x78]; + struct imx_tmu_site_regs site[SITES_MAX]; + u8 res5[0x9f8]; + u32 ipbrr0; /* IP Block Revision Register 0 */ + u32 ipbrr1; /* IP Block Revision Register 1 */ + u8 res6[0x310]; + u32 ttr0cr; /* Temperature Range 0 Control Register */ + u32 ttr1cr; /* Temperature Range 1 Control Register */ + u32 ttr2cr; /* Temperature Range 2 Control Register */ + u32 ttr3cr; /* Temperature Range 3 Control Register */ +}; + +struct imx_tmu_plat { + int critical; + int alert; + int polling_delay; + int id; + bool zone_node; + struct imx_tmu_regs *regs; +}; + +static int read_temperature(struct udevice *dev, int *temp) +{ + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + u32 val; + + do { + val = readl(&pdata->regs->site[pdata->id].tritsr); + } while (!(val & 0x80000000)); + + *temp = (val & 0xff) * 1000; + + return 0; +} + +int imx_tmu_get_temp(struct udevice *dev, int *temp) +{ + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + int cpu_tmp = 0; + int ret; + + ret = read_temperature(dev, &cpu_tmp); + if (ret) + return ret; + + while (cpu_tmp >= pdata->alert) { + printf("CPU Temperature (%dC) has beyond alert (%dC), close to critical (%dC)", cpu_tmp, pdata->alert, pdata->critical); + puts(" waiting...\n"); + mdelay(pdata->polling_delay); + ret = read_temperature(dev, &cpu_tmp); + if (ret) + return ret; + } + + *temp = cpu_tmp / 1000; + + return 0; +} + +static const struct dm_thermal_ops imx_tmu_ops = { + .get_temp = imx_tmu_get_temp, +}; + +static int imx_tmu_calibration(struct udevice *dev) +{ + int i, val, len, ret; + u32 range[4]; + const fdt32_t *calibration; + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + + debug("%s\n", __func__); + + ret = dev_read_u32_array(dev, "fsl,tmu-range", range, 4); + if (ret) { + printf("TMU: missing calibration range, ret = %d.\n", ret); + return ret; + } + + /* Init temperature range registers */ + writel(range[0], &pdata->regs->ttr0cr); + writel(range[1], &pdata->regs->ttr1cr); + writel(range[2], &pdata->regs->ttr2cr); + writel(range[3], &pdata->regs->ttr3cr); + + calibration = dev_read_prop(dev, "fsl,tmu-calibration", &len); + if (!calibration || len % 8) { + printf("TMU: invalid calibration data.\n"); + return -ENODEV; + } + + for (i = 0; i < len; i += 8, calibration += 2) { + val = fdt32_to_cpu(*calibration); + writel(val, &pdata->regs->ttcfgr); + val = fdt32_to_cpu(*(calibration + 1)); + writel(val, &pdata->regs->tscfgr); + } + + return 0; +} + +static void imx_tmu_init(struct imx_tmu_plat *pdata) +{ + debug("%s\n", __func__); + + /* Disable monitoring */ + writel(TMR_DISABLE, &pdata->regs->tmr); + + /* Disable interrupt, using polling instead */ + writel(TIER_DISABLE, &pdata->regs->tier); + + /* Set update_interval */ + writel(TMTMIR_DEFAULT, &pdata->regs->tmtmir); +} + +static int imx_tmu_enable_msite(struct udevice *dev) +{ + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + u32 reg; + + debug("%s\n", __func__); + + if (!pdata->regs) + return -EIO; + + /* Clear the ME before setting MSITE and ALPF*/ + reg = readl(&pdata->regs->tmr); + reg &= ~TMR_ME; + writel(reg, &pdata->regs->tmr); + + reg |= 1 << (15 - pdata->id); + reg |= TMR_ALPF; + writel(reg, &pdata->regs->tmr); + + /* Enable ME */ + reg |= TMR_ME; + writel(reg, &pdata->regs->tmr); + + return 0; +} + +static int imx_tmu_bind(struct udevice *dev) +{ + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + int ret; + ofnode node, offset; + const char *name; + const void *prop; + + debug("%s dev name %s\n", __func__, dev->name); + + prop = dev_read_prop(dev, "compatible", NULL); + if (!prop) + return 0; + + pdata->zone_node = 1; + + node = ofnode_path("/thermal-zones"); + ofnode_for_each_subnode(offset, node) { + /* Bind the subnode to this driver */ + name = ofnode_get_name(offset); + + ret = device_bind_with_driver_data(dev, dev->driver, name, + dev->driver_data, offset, + NULL); + if (ret) + printf("Error binding driver '%s': %d\n", + dev->driver->name, ret); + } + + return 0; +} + +static int imx_tmu_parse_fdt(struct udevice *dev) +{ + struct imx_tmu_plat *pdata = dev_get_platdata(dev), *p_parent_data; + struct ofnode_phandle_args args; + ofnode trips_np; + int ret; + + debug("%s dev name %s\n", __func__, dev->name); + + if (pdata->zone_node) { + pdata->regs = (struct imx_tmu_regs *)dev_read_addr_ptr(dev); + + if (!pdata->regs) + return -EINVAL; + return 0; + } + + p_parent_data = dev_get_platdata(dev->parent); + if (p_parent_data->zone_node) + pdata->regs = p_parent_data->regs; + + ret = dev_read_phandle_with_args(dev, "thermal-sensors", + "#thermal-sensor-cells", + 0, 0, &args); + if (ret) + return ret; + + if (!ofnode_equal(args.node, dev_ofnode(dev->parent))) + return -EFAULT; + + if (args.args_count >= 1) + pdata->id = args.args[0]; + else + pdata->id = 0; + + debug("args.args_count %d, id %d\n", args.args_count, pdata->id); + + pdata->polling_delay = dev_read_u32_default(dev, "polling-delay", 1000); + + trips_np = ofnode_path("/thermal-zones/cpu-thermal/trips"); + ofnode_for_each_subnode(trips_np, trips_np) { + const char *type; + + type = ofnode_get_property(trips_np, "type", NULL); + if (!type) + continue; + if (!strcmp(type, "critical")) + pdata->critical = ofnode_read_u32_default(trips_np, "temperature", 85); + else if (strcmp(type, "passive") == 0) + pdata->alert = ofnode_read_u32_default(trips_np, "temperature", 80); + else + continue; + } + + debug("id %d polling_delay %d, critical %d, alert %d\n", + pdata->id, pdata->polling_delay, pdata->critical, pdata->alert); + + return 0; +} + +static int imx_tmu_probe(struct udevice *dev) +{ + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + int ret; + + ret = imx_tmu_parse_fdt(dev); + if (ret) { + printf("Error in parsing TMU FDT %d\n", ret); + return ret; + } + + if (pdata->zone_node) { + imx_tmu_init(pdata); + imx_tmu_calibration(dev); + } else { + imx_tmu_enable_msite(dev); + } + + return 0; +} + +static const struct udevice_id imx_tmu_ids[] = { + { .compatible = "fsl,imx8mq-tmu", }, + { } +}; + +U_BOOT_DRIVER(imx_tmu) = { + .name = "imx_tmu", + .id = UCLASS_THERMAL, + .ops = &imx_tmu_ops, + .of_match = imx_tmu_ids, + .bind = imx_tmu_bind, + .probe = imx_tmu_probe, + .platdata_auto_alloc_size = sizeof(struct imx_tmu_plat), + .flags = DM_FLAG_PRE_RELOC, +}; From fc8657b7fb526b253c9d97f1fe34e40ceadc7c35 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:47 +0800 Subject: [PATCH 32/82] thermal: imx_tmu: Add support for thermal sensor on iMX8MM The analog sensors on iMX8MM are new, used for 14LPP process. So the Temperature Sensor Monitoring Unit (TMU) has some change accordingly. We use version 2 in TMU driver to represent the new TMU, so the one driver can service for both i.MX8MQ/M. Signed-off-by: Peng Fan --- drivers/thermal/imx_tmu.c | 113 +++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 27 deletions(-) diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c index f496ce03b65..df0b35b7ba3 100644 --- a/drivers/thermal/imx_tmu.c +++ b/drivers/thermal/imx_tmu.c @@ -20,6 +20,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SITES_MAX 16 +#define FLAGS_VER2 0x1 #define TMR_DISABLE 0x0 #define TMR_ME 0x80000000 @@ -27,6 +28,8 @@ DECLARE_GLOBAL_DATA_PTR; #define TMTMIR_DEFAULT 0x00000002 #define TIER_DISABLE 0x0 +#define TER_EN 0x80000000 +#define TER_ADC_PD 0x40000000 /* * i.MX TMU Registers */ @@ -67,22 +70,47 @@ struct imx_tmu_regs { u32 ttr3cr; /* Temperature Range 3 Control Register */ }; +struct imx_tmu_regs_v2 { + u32 ter; /* TMU enable Register */ + u32 tsr; /* Status Register */ + u32 tier; /* Interrupt enable register */ + u32 tidr; /* Interrupt detect register */ + u32 tmhtitr; /* Monitor high temperature immediate threshold register */ + u32 tmhtatr; /* Monitor high temperature average threshold register */ + u32 tmhtactr; /* TMU monitor high temperature average critical threshold register */ + u32 tscr; /* Sensor value capture register */ + u32 tritsr; /* Report immediate temperature site register 0 */ + u32 tratsr; /* Report average temperature site register 0 */ + u32 tasr; /* Amplifier setting register */ + u32 ttmc; /* Test MUX control */ + u32 tcaliv; +}; + +union tmu_regs { + struct imx_tmu_regs regs_v1; + struct imx_tmu_regs_v2 regs_v2; +}; + struct imx_tmu_plat { int critical; int alert; int polling_delay; int id; bool zone_node; - struct imx_tmu_regs *regs; + union tmu_regs *regs; }; static int read_temperature(struct udevice *dev, int *temp) { struct imx_tmu_plat *pdata = dev_get_platdata(dev); + ulong drv_data = dev_get_driver_data(dev); u32 val; do { - val = readl(&pdata->regs->site[pdata->id].tritsr); + if (drv_data & FLAGS_VER2) { + val = readl(&pdata->regs->regs_v2.tritsr); + else + val = readl(&pdata->regs->regs_v1.site[pdata->id].tritsr); } while (!(val & 0x80000000)); *temp = (val & 0xff) * 1000; @@ -124,9 +152,13 @@ static int imx_tmu_calibration(struct udevice *dev) u32 range[4]; const fdt32_t *calibration; struct imx_tmu_plat *pdata = dev_get_platdata(dev); + ulong drv_data = dev_get_driver_data(dev); debug("%s\n", __func__); + if (drv_data & FLAGS_VER2) + return 0; + ret = dev_read_u32_array(dev, "fsl,tmu-range", range, 4); if (ret) { printf("TMU: missing calibration range, ret = %d.\n", ret); @@ -134,10 +166,10 @@ static int imx_tmu_calibration(struct udevice *dev) } /* Init temperature range registers */ - writel(range[0], &pdata->regs->ttr0cr); - writel(range[1], &pdata->regs->ttr1cr); - writel(range[2], &pdata->regs->ttr2cr); - writel(range[3], &pdata->regs->ttr3cr); + writel(range[0], &pdata->regs->regs_v1.ttr0cr); + writel(range[1], &pdata->regs->regs_v1.ttr1cr); + writel(range[2], &pdata->regs->regs_v1.ttr2cr); + writel(range[3], &pdata->regs->regs_v1.ttr3cr); calibration = dev_read_prop(dev, "fsl,tmu-calibration", &len); if (!calibration || len % 8) { @@ -147,31 +179,43 @@ static int imx_tmu_calibration(struct udevice *dev) for (i = 0; i < len; i += 8, calibration += 2) { val = fdt32_to_cpu(*calibration); - writel(val, &pdata->regs->ttcfgr); + writel(val, &pdata->regs->regs_v1.ttcfgr); val = fdt32_to_cpu(*(calibration + 1)); - writel(val, &pdata->regs->tscfgr); + writel(val, &pdata->regs->regs_v1.tscfgr); } return 0; } -static void imx_tmu_init(struct imx_tmu_plat *pdata) +static void imx_tmu_init(struct udevice *dev) { + struct imx_tmu_plat *pdata = dev_get_platdata(dev); + ulong drv_data = dev_get_driver_data(dev); + debug("%s\n", __func__); - /* Disable monitoring */ - writel(TMR_DISABLE, &pdata->regs->tmr); + if (drv_data & FLAGS_VER2) { + /* Disable monitoring */ + writel(0x0, &pdata->regs->regs_v2.ter); - /* Disable interrupt, using polling instead */ - writel(TIER_DISABLE, &pdata->regs->tier); + /* Disable interrupt, using polling instead */ + writel(0x0, &pdata->regs->regs_v2.tier); + } else { + /* Disable monitoring */ + writel(TMR_DISABLE, &pdata->regs->regs_v1.tmr); - /* Set update_interval */ - writel(TMTMIR_DEFAULT, &pdata->regs->tmtmir); + /* Disable interrupt, using polling instead */ + writel(TIER_DISABLE, &pdata->regs->regs_v1.tier); + + /* Set update_interval */ + writel(TMTMIR_DEFAULT, &pdata->regs->regs_v1.tmtmir); + } } static int imx_tmu_enable_msite(struct udevice *dev) { struct imx_tmu_plat *pdata = dev_get_platdata(dev); + ulong drv_data = dev_get_driver_data(dev); u32 reg; debug("%s\n", __func__); @@ -179,18 +223,32 @@ static int imx_tmu_enable_msite(struct udevice *dev) if (!pdata->regs) return -EIO; - /* Clear the ME before setting MSITE and ALPF*/ - reg = readl(&pdata->regs->tmr); - reg &= ~TMR_ME; - writel(reg, &pdata->regs->tmr); + if (drv_data & FLAGS_VER2) { + reg = readl(&pdata->regs->regs_v2.ter); + reg &= ~TER_EN; + writel(reg, &pdata->regs->regs_v2.ter); - reg |= 1 << (15 - pdata->id); - reg |= TMR_ALPF; - writel(reg, &pdata->regs->tmr); + reg &= ~TER_ALPF; + reg |= 0x1; + writel(reg, &pdata->regs->regs_v2.ter); - /* Enable ME */ - reg |= TMR_ME; - writel(reg, &pdata->regs->tmr); + /* Enable monitor */ + reg |= TER_EN; + writel(reg, &pdata->regs->regs_v2.ter); + } else { + /* Clear the ME before setting MSITE and ALPF*/ + reg = readl(&pdata->regs->regs_v1.tmr); + reg &= ~TMR_ME; + writel(reg, &pdata->regs->regs_v1.tmr); + + reg |= 1 << (15 - pdata->id); + reg |= TMR_ALPF; + writel(reg, &pdata->regs->regs_v1.tmr); + + /* Enable ME */ + reg |= TMR_ME; + writel(reg, &pdata->regs->regs_v1.tmr); + } return 0; } @@ -237,7 +295,7 @@ static int imx_tmu_parse_fdt(struct udevice *dev) debug("%s dev name %s\n", __func__, dev->name); if (pdata->zone_node) { - pdata->regs = (struct imx_tmu_regs *)dev_read_addr_ptr(dev); + pdata->regs = (union tmu_regs *)dev_read_addr_ptr(dev); if (!pdata->regs) return -EINVAL; @@ -299,7 +357,7 @@ static int imx_tmu_probe(struct udevice *dev) } if (pdata->zone_node) { - imx_tmu_init(pdata); + imx_tmu_init(dev); imx_tmu_calibration(dev); } else { imx_tmu_enable_msite(dev); @@ -310,6 +368,7 @@ static int imx_tmu_probe(struct udevice *dev) static const struct udevice_id imx_tmu_ids[] = { { .compatible = "fsl,imx8mq-tmu", }, + { .compatible = "fsl,imx8mm-tmu", .data = FLAGS_VER2, }, { } }; From 84897408c688e3d3962e8cd7e92f3ad99c17005d Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:48 +0800 Subject: [PATCH 33/82] thermal: imx_tmu: support TMU arch level initialization i.MX8MM TMU needs to load some registers from fuse, this is arch dependent operation and may vary on different platforms. So add a interface for arch level initialization. Signed-off-by: Peng Fan --- drivers/thermal/imx_tmu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c index df0b35b7ba3..049f32c39ea 100644 --- a/drivers/thermal/imx_tmu.c +++ b/drivers/thermal/imx_tmu.c @@ -187,6 +187,10 @@ static int imx_tmu_calibration(struct udevice *dev) return 0; } +void __weak imx_tmu_arch_init(void *reg_base) +{ +} + static void imx_tmu_init(struct udevice *dev) { struct imx_tmu_plat *pdata = dev_get_platdata(dev); @@ -210,6 +214,8 @@ static void imx_tmu_init(struct udevice *dev) /* Set update_interval */ writel(TMTMIR_DEFAULT, &pdata->regs->regs_v1.tmtmir); } + + imx_tmu_arch_init((void *)pdata->regs); } static int imx_tmu_enable_msite(struct udevice *dev) From b5447b98f24784459225ea0cc2729b1cdb1e3136 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:49 +0800 Subject: [PATCH 34/82] thermal: imx_tmu: Fix for temperature out of range When the temperature is out of sensor's range, the Valid bit won't be set in TRITSR register. So the polling loop won't go out. Change the codes to retry 10 times with 100ms interval for the Valid bit. If the timeout, we give a warning for the invalid data. Modifed from Ye's NXP patch Signed-off-by: Peng Fan --- drivers/thermal/imx_tmu.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c index 049f32c39ea..2a08d5085cf 100644 --- a/drivers/thermal/imx_tmu.c +++ b/drivers/thermal/imx_tmu.c @@ -105,15 +105,22 @@ static int read_temperature(struct udevice *dev, int *temp) struct imx_tmu_plat *pdata = dev_get_platdata(dev); ulong drv_data = dev_get_driver_data(dev); u32 val; + u32 retry = 10; do { - if (drv_data & FLAGS_VER2) { + mdelay(100); + retry--; + + if (drv_data & FLAGS_VER2) val = readl(&pdata->regs->regs_v2.tritsr); else val = readl(&pdata->regs->regs_v1.site[pdata->id].tritsr); - } while (!(val & 0x80000000)); + } while (!(val & 0x80000000) && retry > 0); - *temp = (val & 0xff) * 1000; + if (retry > 0) + *temp = (val & 0xff) * 1000; + else + return -EINVAL; return 0; } From 951bf19dae2198c7684e4bb3f1eae10ba60d3677 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:50 +0800 Subject: [PATCH 35/82] thermal: imx_tmu: Check the TEMP range for iMX8MM On iMX8MM, the V flag in TRISTR register only reflect the state of SNSR value, not the calibrated TEMP value. So checking this flag is not reliable. Per IC suggestion, change to read the TEMP/AVG_TEMP directly and check whether it in valid range 10-125C. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/thermal/imx_tmu.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c index 2a08d5085cf..c577b0bd6cd 100644 --- a/drivers/thermal/imx_tmu.c +++ b/drivers/thermal/imx_tmu.c @@ -106,16 +106,24 @@ static int read_temperature(struct udevice *dev, int *temp) ulong drv_data = dev_get_driver_data(dev); u32 val; u32 retry = 10; + u32 valid = 0; do { mdelay(100); retry--; - if (drv_data & FLAGS_VER2) + if (drv_data & FLAGS_VER2) { val = readl(&pdata->regs->regs_v2.tritsr); - else + /* + * Check if TEMP is in valid range, the V bit in TRITSR + * only reflects the RAW uncalibrated data + */ + valid = ((val & 0xff) < 10 || (val & 0xff) > 125) ? 0 : 1; + } else { val = readl(&pdata->regs->regs_v1.site[pdata->id].tritsr); - } while (!(val & 0x80000000) && retry > 0); + valid = val & 0x80000000; + } + } while (!valid && retry > 0); if (retry > 0) *temp = (val & 0xff) * 1000; From 634fe73eedb9551a13296f356afae67539583f17 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:51 +0800 Subject: [PATCH 36/82] thermal: imx_tmu: support i.MX8MP Support i.MX8MP thermal which has two probes and supports temperature range from -40 to 125. Still uses default 1p HW calibration at 25C and loads calibration parameters from fuse. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/thermal/imx_tmu.c | 76 +++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/imx_tmu.c b/drivers/thermal/imx_tmu.c index c577b0bd6cd..4ca22089b8b 100644 --- a/drivers/thermal/imx_tmu.c +++ b/drivers/thermal/imx_tmu.c @@ -21,6 +21,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SITES_MAX 16 #define FLAGS_VER2 0x1 +#define FLAGS_VER3 0x2 #define TMR_DISABLE 0x0 #define TMR_ME 0x80000000 @@ -30,6 +31,8 @@ DECLARE_GLOBAL_DATA_PTR; #define TER_EN 0x80000000 #define TER_ADC_PD 0x40000000 +#define TER_ALPF 0x3 + /* * i.MX TMU Registers */ @@ -86,9 +89,29 @@ struct imx_tmu_regs_v2 { u32 tcaliv; }; +struct imx_tmu_regs_v3 { + u32 ter; /* TMU enable Register */ + u32 tps; /* Status Register */ + u32 tier; /* Interrupt enable register */ + u32 tidr; /* Interrupt detect register */ + u32 tmhtitr; /* Monitor high temperature immediate threshold register */ + u32 tmhtatr; /* Monitor high temperature average threshold register */ + u32 tmhtactr; /* TMU monitor high temperature average critical threshold register */ + u32 tscr; /* Sensor value capture register */ + u32 tritsr; /* Report immediate temperature site register 0 */ + u32 tratsr; /* Report average temperature site register 0 */ + u32 tasr; /* Amplifier setting register */ + u32 ttmc; /* Test MUX control */ + u32 tcaliv0; + u32 tcaliv1; + u32 tcaliv_m40; + u32 trim; +}; + union tmu_regs { struct imx_tmu_regs regs_v1; struct imx_tmu_regs_v2 regs_v2; + struct imx_tmu_regs_v3 regs_v3; }; struct imx_tmu_plat { @@ -112,7 +135,10 @@ static int read_temperature(struct udevice *dev, int *temp) mdelay(100); retry--; - if (drv_data & FLAGS_VER2) { + if (drv_data & FLAGS_VER3) { + val = readl(&pdata->regs->regs_v3.tritsr); + valid = val & (1 << (30 + pdata->id)); + } else if (drv_data & FLAGS_VER2) { val = readl(&pdata->regs->regs_v2.tritsr); /* * Check if TEMP is in valid range, the V bit in TRITSR @@ -125,10 +151,23 @@ static int read_temperature(struct udevice *dev, int *temp) } } while (!valid && retry > 0); - if (retry > 0) - *temp = (val & 0xff) * 1000; - else + if (retry > 0) { + if (drv_data & FLAGS_VER3) { + val = (val >> (pdata->id * 16)) & 0xff; + if (val & 0x80) /* Negative */ + val = (~(val & 0x7f) + 1); + + *temp = val; + if (*temp < -40 || *temp > 125) /* Check the range */ + return -EINVAL; + + *temp *= 1000; + } else { + *temp = (val & 0xff) * 1000; + } + } else { return -EINVAL; + } return 0; } @@ -171,7 +210,7 @@ static int imx_tmu_calibration(struct udevice *dev) debug("%s\n", __func__); - if (drv_data & FLAGS_VER2) + if (drv_data & (FLAGS_VER2 | FLAGS_VER3)) return 0; ret = dev_read_u32_array(dev, "fsl,tmu-range", range, 4); @@ -213,7 +252,14 @@ static void imx_tmu_init(struct udevice *dev) debug("%s\n", __func__); - if (drv_data & FLAGS_VER2) { + if (drv_data & FLAGS_VER3) { + /* Disable monitoring */ + writel(0x0, &pdata->regs->regs_v3.ter); + + /* Disable interrupt, using polling instead */ + writel(0x0, &pdata->regs->regs_v3.tier); + + } else if (drv_data & FLAGS_VER2) { /* Disable monitoring */ writel(0x0, &pdata->regs->regs_v2.ter); @@ -244,7 +290,22 @@ static int imx_tmu_enable_msite(struct udevice *dev) if (!pdata->regs) return -EIO; - if (drv_data & FLAGS_VER2) { + if (drv_data & FLAGS_VER3) { + reg = readl(&pdata->regs->regs_v3.ter); + reg &= ~TER_EN; + writel(reg, &pdata->regs->regs_v3.ter); + + writel(pdata->id << 30, &pdata->regs->regs_v3.tps); + + reg &= ~TER_ALPF; + reg |= 0x1; + reg &= ~TER_ADC_PD; + writel(reg, &pdata->regs->regs_v3.ter); + + /* Enable monitor */ + reg |= TER_EN; + writel(reg, &pdata->regs->regs_v3.ter); + } else if (drv_data & FLAGS_VER2) { reg = readl(&pdata->regs->regs_v2.ter); reg &= ~TER_EN; writel(reg, &pdata->regs->regs_v2.ter); @@ -390,6 +451,7 @@ static int imx_tmu_probe(struct udevice *dev) static const struct udevice_id imx_tmu_ids[] = { { .compatible = "fsl,imx8mq-tmu", }, { .compatible = "fsl,imx8mm-tmu", .data = FLAGS_VER2, }, + { .compatible = "fsl,imx8mp-tmu", .data = FLAGS_VER3, }, { } }; From 70487ff386c0b7ee40b83aff219f8b36829e8b13 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:19:52 +0800 Subject: [PATCH 37/82] imx8mm: Load fuse for TMU TCALIV and TASR On iMX8MM, the default value of TMU registers TCALIV and TASR need be loaded from fuse. HW won't do this, it expect SW loads them before using TMU. Reviewed-by: Bai Ping Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 89229da3b62..dcec83e6248 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2017 NXP + * Copyright 2017-2019 NXP * * Peng Fan */ @@ -448,3 +448,29 @@ int arch_misc_init(void) return 0; } #endif + +void imx_tmu_arch_init(void *reg_base) +{ + if (is_imx8mm()) { + /* Load TCALIV and TASR from fuses */ + struct ocotp_regs *ocotp = + (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[3]; + struct fuse_bank3_regs *fuse = + (struct fuse_bank3_regs *)bank->fuse_regs; + + u32 tca_rt, tca_hr, tca_en; + u32 buf_vref, buf_slope; + + tca_rt = fuse->ana0 & 0xFF; + tca_hr = (fuse->ana0 & 0xFF00) >> 8; + tca_en = (fuse->ana0 & 0x2000000) >> 25; + + buf_vref = (fuse->ana0 & 0x1F00000) >> 20; + buf_slope = (fuse->ana0 & 0xF0000) >> 16; + + writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28); + writel((tca_en << 31) | (tca_hr << 16) | tca_rt, + (ulong)reg_base + 0x30); + } +} From 94c693d782fd7df7ff3f54b54ef29a422a938f83 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:19:53 +0800 Subject: [PATCH 38/82] imx: i.MX8MN: Enable loading TASR and TCALIV from fuse Like iMX8MM, iMX8MN also needs SW to load TMU TASR and TCALIV registers value from fuse before enabling TMU calibration. Otherwise the calibration is not exact. Reviewed-by: Anson Huang Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index dcec83e6248..a1d9470f3d9 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -451,7 +451,7 @@ int arch_misc_init(void) void imx_tmu_arch_init(void *reg_base) { - if (is_imx8mm()) { + if (is_imx8mm() || is_imx8mn()) { /* Load TCALIV and TASR from fuses */ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; From ebb9aab318b6e338bfb9d3459f1c3be4ebe48361 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:19:54 +0800 Subject: [PATCH 39/82] imx: load calibration parameters from fuse for i.MX8MP i.MX8MP thermal which has two probes and supports temperature range from -40 to 125. The driver still uses default 1p HW calibration at 25C and loads calibration parameters from fuse. Reviewed-by: Peng Fan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index a1d9470f3d9..ea0430c207f 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -473,4 +473,49 @@ void imx_tmu_arch_init(void *reg_base) writel((tca_en << 31) | (tca_hr << 16) | tca_rt, (ulong)reg_base + 0x30); } +#ifdef CONFIG_IMX8MP + /* Load TCALIV0/1/m40 and TRIM from fuses */ + struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; + struct fuse_bank *bank = &ocotp->bank[38]; + struct fuse_bank38_regs *fuse = + (struct fuse_bank38_regs *)bank->fuse_regs; + struct fuse_bank *bank2 = &ocotp->bank[39]; + struct fuse_bank39_regs *fuse2 = + (struct fuse_bank39_regs *)bank2->fuse_regs; + u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr; + u32 reg; + u32 tca40[2], tca25[2], tca105[2]; + + /* For blank sample */ + if (!fuse->ana_trim2 && !fuse->ana_trim3 && + !fuse->ana_trim4 && !fuse2->ana_trim5) { + /* Use a default 25C binary codes */ + tca25[0] = 1596; + writel(tca25[0], (ulong)reg_base + 0x30); + return; + } + + buf_vref = (fuse->ana_trim2 & 0xc0) >> 6; + buf_slope = (fuse->ana_trim2 & 0xF00) >> 8; + bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12; + bgr = (fuse->ana_trim2 & 0xF0000) >> 16; + vlsb = (fuse->ana_trim2 & 0xF00000) >> 20; + writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28); + + reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7); + writel(reg, (ulong)reg_base + 0x3c); + + tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16; + tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28; + tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4); + tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8; + tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20; + tca25[1] = fuse2->ana_trim5 & 0xFFF; + tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12; + + /* use 25c for 1p calibration */ + writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30); + writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34); + writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38); +#endif } From 3462b55d177b8e195df4920493b88406dbdb8843 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:19:55 +0800 Subject: [PATCH 40/82] imx8mp: Set default SNSR25C for TMU probe1 So far u-boot only load SNSR25C for TMU main probe (probe 0). However, kernel enables two probes. So it also needs to set default SNSR25C of TCALIV1 for blank samples. Reviewed-by: Peng Fan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index ea0430c207f..347fd6d0ade 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -491,7 +491,9 @@ void imx_tmu_arch_init(void *reg_base) !fuse->ana_trim4 && !fuse2->ana_trim5) { /* Use a default 25C binary codes */ tca25[0] = 1596; + tca25[1] = 1596; writel(tca25[0], (ulong)reg_base + 0x30); + writel(tca25[1], (ulong)reg_base + 0x34); return; } From ef56281cf3c9e2d5db65b70efcdb44737068b885 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:56 +0800 Subject: [PATCH 41/82] imx: regs: add more fuse bank structure Add more fuse bank structure for use. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/imx-regs.h | 41 ++++++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h index 62640d996e4..3cfa169c971 100644 --- a/arch/arm/include/asm/arch-imx8m/imx-regs.h +++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h @@ -137,6 +137,40 @@ struct fuse_bank1_regs { u32 rsvd3[3]; }; +struct fuse_bank3_regs { + u32 mem_trim0; + u32 rsvd0[3]; + u32 mem_trim1; + u32 rsvd1[3]; + u32 mem_trim2; + u32 rsvd2[3]; + u32 ana0; + u32 rsvd3[3]; +}; + +struct fuse_bank9_regs { + u32 mac_addr0; + u32 rsvd0[3]; + u32 mac_addr1; + u32 rsvd1[11]; +}; + +struct fuse_bank38_regs { + u32 ana_trim1; /* trim0 is at 0xD70, bank 37*/ + u32 rsvd0[3]; + u32 ana_trim2; + u32 rsvd1[3]; + u32 ana_trim3; + u32 rsvd2[3]; + u32 ana_trim4; + u32 rsvd3[3]; +}; + +struct fuse_bank39_regs { + u32 ana_trim5; + u32 rsvd[15]; +}; + #ifdef CONFIG_IMX8MQ struct anamix_pll { u32 audio_pll1_cfg0; @@ -227,13 +261,6 @@ struct anamix_pll { }; #endif -struct fuse_bank9_regs { - u32 mac_addr0; - u32 rsvd0[3]; - u32 mac_addr1; - u32 rsvd1[11]; -}; - /* System Reset Controller (SRC) */ struct src { u32 scr; From dc597d1d408422e3c5d1adc43297f927bb7ca4c9 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sun, 3 May 2020 22:19:57 +0800 Subject: [PATCH 42/82] imx: cpu: support tmu Support tmu when print cpu info Signed-off-by: peng Fan --- arch/arm/mach-imx/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index e83f6934cd2..515c1fea405 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -168,7 +168,7 @@ int print_cpuinfo(void) cpurev = get_cpu_rev(); -#if defined(CONFIG_IMX_THERMAL) +#if defined(CONFIG_IMX_THERMAL) || defined(CONFIG_IMX_TMU) struct udevice *thermal_dev; int cpu_tmp, minc, maxc, ret; @@ -191,7 +191,7 @@ int print_cpuinfo(void) mxc_get_clock(MXC_ARM_CLK) / 1000000); #endif -#if defined(CONFIG_IMX_THERMAL) +#if defined(CONFIG_IMX_THERMAL) || defined(CONFIG_IMX_TMU) puts("CPU: "); switch (get_cpu_temp_grade(&minc, &maxc)) { case TEMP_AUTOMOTIVE: From e5e95ecf1e32ab9433f2bd987c4f6cba6cf84376 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:31:46 +0800 Subject: [PATCH 43/82] misc: fuse: Update imx8 fuse driver for 8QM Add the second ECC fuse area for 8QM which is different with 8QXP Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/misc/imx8/fuse.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c index 1309215d4d7..4d7f2f524d0 100644 --- a/drivers/misc/imx8/fuse.c +++ b/drivers/misc/imx8/fuse.c @@ -15,8 +15,13 @@ DECLARE_GLOBAL_DATA_PTR; #define FSL_ECC_WORD_START_1 0x10 #define FSL_ECC_WORD_END_1 0x10F +#ifdef CONFIG_IMX8QM +#define FSL_ECC_WORD_START_2 0x1A0 +#define FSL_ECC_WORD_END_2 0x1FF +#elif defined(CONFIG_IMX8QXP) #define FSL_ECC_WORD_START_2 0x220 #define FSL_ECC_WORD_END_2 0x31F +#endif #define FSL_QXP_FUSE_GAP_START 0x110 #define FSL_QXP_FUSE_GAP_END 0x21F From 77ed80c9ec415ac8b77336215c1cf2fa26d00689 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:31:47 +0800 Subject: [PATCH 44/82] misc: scu: Increase the timeout for MU communication When power on some sources in Video system, current timeout 10ms is too short and returns before SCU response. So increase the timeout to 1s. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/misc/imx8/scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c index a7654a78173..6916b754f6c 100644 --- a/drivers/misc/imx8/scu.c +++ b/drivers/misc/imx8/scu.c @@ -74,7 +74,7 @@ static int mu_hal_receivemsg(struct mu_type *base, u32 reg_index, u32 *msg) assert(reg_index < MU_TR_COUNT); /* Wait RX register to be full. */ - ret = readl_poll_timeout(&base->sr, val, val & mask, 10000); + ret = readl_poll_timeout(&base->sr, val, val & mask, 1000000); if (ret < 0) { printf("%s timeout\n", __func__); return -ETIMEDOUT; From 616f03dabacb6c500e8a7ceb920cd08554c9fcae Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 22:08:50 +0800 Subject: [PATCH 45/82] mtd: gpmi: change the BCH layout setting for large oob NAND MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code change updated the NAND driver BCH ECC layout algorithm to support large oob size NAND chips(oob > 1024 bytes) and proposed a new way to set ECC layout. Current implementation requires each chunk size larger than oob size so the bad block marker (BBM) can be guaranteed located in data chunk. The ECC layout always using the unbalanced layout(Ecc for both meta and Data0 chunk), but for the NAND chips with oob larger than 1k, the driver cannot support because BCH doesn’t support GF 15 for 2K chunk. The change keeps the data chunk no larger than 1k and adjust the ECC strength or ECC layout to locate the BBM in data chunk. General idea for large oob NAND chips is 1.Try all ECC strength from the minimum value required by NAND spec to the maximum one that works, any ECC makes the BBM locate in data chunk can be chosen. 2.If none of them works, using separate ECC for meta, which will add one extra ecc with the same ECC strength as other data chunks. This extra ECC can guarantee BBM located in data chunk, of course, we need to check if oob can afford it. Previous code has two methods for ECC layout setting, the legacy_calc_ecc_layout and calc_ecc_layout_by_info, the difference between these two methods is, legacy_calc_ecc_layout set the chunk size larger chan oob size and then set the maximum ECC strength that oob can afford. While the calc_ecc_layout_by_info set chunk size and ECC strength according to NAND spec. It has been proved that the first method cannot provide safe ECC strength for some modern NAND chips, so in current code, 1. Driver read NAND parameters first and then chose the proper ECC layout setting method. 2. If the oob is large or NAND required data chunk larger than oob size, chose calc_ecc_for_large_oob, otherwise use calc_ecc_layout_by_info 3. legacy_calc_ecc_layout only used for some NAND chips does not contains necessary information. So this is only a backup plan, it is NOT recommended to use these NAND chips. Signed-off-by: Han Xu Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 209 +++++++++++++++++++++----------- include/mxs_nand.h | 12 +- 2 files changed, 146 insertions(+), 75 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index fe8097c1460..8da59e39c01 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -112,53 +112,32 @@ static uint32_t mxs_nand_aux_status_offset(void) return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3; } -static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo, - uint32_t page_data_size) +static inline bool mxs_nand_bbm_in_data_chunk(struct bch_geometry *geo, struct mtd_info *mtd, + unsigned int *chunk_num) { - uint32_t chunk_data_size_in_bits = geo->ecc_chunk_size * 8; - uint32_t chunk_ecc_size_in_bits = geo->ecc_strength * geo->gf_len; - uint32_t chunk_total_size_in_bits; - uint32_t block_mark_chunk_number; - uint32_t block_mark_chunk_bit_offset; - uint32_t block_mark_bit_offset; + unsigned int i, j; - chunk_total_size_in_bits = - chunk_data_size_in_bits + chunk_ecc_size_in_bits; + if (geo->ecc_chunk0_size != geo->ecc_chunkn_size) { + dev_err(this->dev, "The size of chunk0 must equal to chunkn\n"); + return false; + } - /* Compute the bit offset of the block mark within the physical page. */ - block_mark_bit_offset = page_data_size * 8; + i = (mtd->writesize * 8 - MXS_NAND_METADATA_SIZE * 8) / + (geo->gf_len * geo->ecc_strength + + geo->ecc_chunkn_size * 8); - /* Subtract the metadata bits. */ - block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8; + j = (mtd->writesize * 8 - MXS_NAND_METADATA_SIZE * 8) - + (geo->gf_len * geo->ecc_strength + + geo->ecc_chunkn_size * 8) * i; - /* - * Compute the chunk number (starting at zero) in which the block mark - * appears. - */ - block_mark_chunk_number = - block_mark_bit_offset / chunk_total_size_in_bits; + if (j < geo->ecc_chunkn_size * 8) { + *chunk_num = i + 1; + dev_dbg(this->dev, "Set ecc to %d and bbm in chunk %d\n", + geo->ecc_strength, *chunk_num); + return true; + } - /* - * Compute the bit offset of the block mark within its chunk, and - * validate it. - */ - block_mark_chunk_bit_offset = block_mark_bit_offset - - (block_mark_chunk_number * chunk_total_size_in_bits); - - if (block_mark_chunk_bit_offset > chunk_data_size_in_bits) - return -EINVAL; - - /* - * Now that we know the chunk number in which the block mark appears, - * we can subtract all the ECC bits that appear before it. - */ - block_mark_bit_offset -= - block_mark_chunk_number * chunk_ecc_size_in_bits; - - geo->block_mark_byte_offset = block_mark_bit_offset >> 3; - geo->block_mark_bit_offset = block_mark_bit_offset & 0x7; - - return 0; + return false; } static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, @@ -168,6 +147,7 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + unsigned int block_mark_bit_offset; switch (ecc_step) { case SZ_512: @@ -180,45 +160,51 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo, return -EINVAL; } - geo->ecc_chunk_size = ecc_step; + geo->ecc_chunk0_size = ecc_step; + geo->ecc_chunkn_size = ecc_step; geo->ecc_strength = round_up(ecc_strength, 2); /* Keep the C >= O */ - if (geo->ecc_chunk_size < mtd->oobsize) + if (geo->ecc_chunkn_size < mtd->oobsize) return -EINVAL; if (geo->ecc_strength > nand_info->max_ecc_strength_supported) return -EINVAL; - geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; + geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size; + + /* For bit swap. */ + block_mark_bit_offset = mtd->writesize * 8 - + (geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1) + + MXS_NAND_METADATA_SIZE * 8); + + geo->block_mark_byte_offset = block_mark_bit_offset / 8; + geo->block_mark_bit_offset = block_mark_bit_offset % 8; return 0; } -static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, +static inline int mxs_nand_legacy_calc_ecc_layout(struct bch_geometry *geo, struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + unsigned int block_mark_bit_offset; /* The default for the length of Galois Field. */ geo->gf_len = 13; /* The default for chunk size. */ - geo->ecc_chunk_size = 512; + geo->ecc_chunk0_size = 512; + geo->ecc_chunkn_size = 512; - if (geo->ecc_chunk_size < mtd->oobsize) { + if (geo->ecc_chunkn_size < mtd->oobsize) { geo->gf_len = 14; - geo->ecc_chunk_size *= 2; + geo->ecc_chunk0_size *= 2; + geo->ecc_chunkn_size *= 2; } - if (mtd->oobsize > geo->ecc_chunk_size) { - printf("Not support the NAND chips whose oob size is larger then %d bytes!\n", - geo->ecc_chunk_size); - return -EINVAL; - } - - geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size; + geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size; /* * Determine the ECC layout with the formula: @@ -234,6 +220,84 @@ static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo, geo->ecc_strength = min(round_down(geo->ecc_strength, 2), nand_info->max_ecc_strength_supported); + block_mark_bit_offset = mtd->writesize * 8 - + (geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1) + + MXS_NAND_METADATA_SIZE * 8); + + geo->block_mark_byte_offset = block_mark_bit_offset / 8; + geo->block_mark_bit_offset = block_mark_bit_offset % 8; + + return 0; +} + +static inline int mxs_nand_calc_ecc_for_large_oob(struct bch_geometry *geo, + struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + unsigned int block_mark_bit_offset; + unsigned int max_ecc; + unsigned int bbm_chunk; + unsigned int i; + + /* sanity check for the minimum ecc nand required */ + if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) + return -EINVAL; + geo->ecc_strength = chip->ecc_strength_ds; + + /* calculate the maximum ecc platform can support*/ + geo->gf_len = 14; + geo->ecc_chunk0_size = 1024; + geo->ecc_chunkn_size = 1024; + geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size; + max_ecc = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8) + / (geo->gf_len * geo->ecc_chunk_count); + max_ecc = min(round_down(max_ecc, 2), + nand_info->max_ecc_strength_supported); + + + /* search a supported ecc strength that makes bbm */ + /* located in data chunk */ + geo->ecc_strength = chip->ecc_strength_ds; + while (!(geo->ecc_strength > max_ecc)) { + if (mxs_nand_bbm_in_data_chunk(geo, mtd, &bbm_chunk)) + break; + geo->ecc_strength += 2; + } + + /* if none of them works, keep using the minimum ecc */ + /* nand required but changing ecc page layout */ + if (geo->ecc_strength > max_ecc) { + geo->ecc_strength = chip->ecc_strength_ds; + /* add extra ecc for meta data */ + geo->ecc_chunk0_size = 0; + geo->ecc_chunk_count = (mtd->writesize / geo->ecc_chunkn_size) + 1; + geo->ecc_for_meta = 1; + /* check if oob can afford this extra ecc chunk */ + if (mtd->oobsize * 8 < MXS_NAND_METADATA_SIZE * 8 + + geo->gf_len * geo->ecc_strength + * geo->ecc_chunk_count) { + printf("unsupported NAND chip with new layout\n"); + return -EINVAL; + } + + /* calculate in which chunk bbm located */ + bbm_chunk = (mtd->writesize * 8 - MXS_NAND_METADATA_SIZE * 8 - + geo->gf_len * geo->ecc_strength) / + (geo->gf_len * geo->ecc_strength + + geo->ecc_chunkn_size * 8) + 1; + } + + /* calculate the number of ecc chunk behind the bbm */ + i = (mtd->writesize / geo->ecc_chunkn_size) - bbm_chunk + 1; + + block_mark_bit_offset = mtd->writesize * 8 - + (geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - i) + + MXS_NAND_METADATA_SIZE * 8); + + geo->block_mark_byte_offset = block_mark_bit_offset / 8; + geo->block_mark_bit_offset = block_mark_bit_offset % 8; + return 0; } @@ -983,19 +1047,24 @@ static int mxs_nand_set_geometry(struct mtd_info *mtd, struct bch_geometry *geo) struct nand_chip *nand = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(nand); - if (chip->ecc.strength > 0 && chip->ecc.size > 0) - return mxs_nand_calc_ecc_layout_by_info(geo, mtd, - chip->ecc.strength, chip->ecc.size); - - if (nand_info->use_minimum_ecc || - mxs_nand_calc_ecc_layout(geo, mtd)) { - if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) - return -EINVAL; - - return mxs_nand_calc_ecc_layout_by_info(geo, mtd, - chip->ecc_strength_ds, chip->ecc_step_ds); + if (chip->ecc_strength_ds > nand_info->max_ecc_strength_supported) { + printf("unsupported NAND chip, minimum ecc required %d\n" + , chip->ecc_strength_ds); + return -EINVAL; } + if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) && + (mtd->oobsize < 1024)) { + dev_warn(this->dev, "use legacy bch geometry\n"); + return mxs_nand_legacy_calc_ecc_layout(geo, mtd); + } + + if (mtd->oobsize > 1024 || chip->ecc_step_ds < mtd->oobsize) + return mxs_nand_calc_ecc_for_large_oob(geo, mtd); + + return mxs_nand_calc_ecc_layout_by_info(geo, mtd, + chip->ecc_strength_ds, chip->ecc_step_ds); + return 0; } @@ -1025,8 +1094,6 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) if (ret) return ret; - mxs_nand_calc_mark_offset(geo, mtd->writesize); - /* Configure BCH and set NFC geometry */ mxs_reset_block(&bch_regs->hw_bch_ctrl_reg); @@ -1034,7 +1101,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) tmp = (geo->ecc_chunk_count - 1) << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT0_ECC0_OFFSET; - tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= geo->ecc_chunk0_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout0); @@ -1043,7 +1110,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) tmp = (mtd->writesize + mtd->oobsize) << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT1_ECCN_OFFSET; - tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= geo->ecc_chunkn_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout1); @@ -1268,7 +1335,7 @@ int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info) nand->ecc.layout = &fake_ecc_layout; nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = nand_info->bch_geometry.ecc_chunk_size; + nand->ecc.size = nand_info->bch_geometry.ecc_chunkn_size; nand->ecc.strength = nand_info->bch_geometry.ecc_strength; /* second phase scan */ diff --git a/include/mxs_nand.h b/include/mxs_nand.h index ada20483d06..497da77a16d 100644 --- a/include/mxs_nand.h +++ b/include/mxs_nand.h @@ -16,22 +16,26 @@ * @gf_len: The length of Galois Field. (e.g., 13 or 14) * @ecc_strength: A number that describes the strength of the ECC * algorithm. - * @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note - * the first chunk in the page includes both data and - * metadata, so it's a bit larger than this value. + * @ecc_chunk0_size: The size, in bytes, of a first ECC chunk. + * @ecc_chunkn_size: The size, in bytes, of a single ECC chunk after + * the first chunk in the page. * @ecc_chunk_count: The number of ECC chunks in the page, * @block_mark_byte_offset: The byte offset in the ECC-based page view at * which the underlying physical block mark appears. * @block_mark_bit_offset: The bit offset into the ECC-based page view at * which the underlying physical block mark appears. + * @ecc_for_meta: The flag to indicate if there is a dedicate ecc + * for meta. */ struct bch_geometry { unsigned int gf_len; unsigned int ecc_strength; - unsigned int ecc_chunk_size; + unsigned int ecc_chunk0_size; + unsigned int ecc_chunkn_size; unsigned int ecc_chunk_count; unsigned int block_mark_byte_offset; unsigned int block_mark_bit_offset; + unsigned int ecc_for_meta; /* ECC for meta data */ }; struct mxs_nand_info { From 51cdf83eea45861f9932019db2a1b3a0a6a3af52 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 22:08:51 +0800 Subject: [PATCH 46/82] mtd: gpmi: provide the option to use legacy bch geometry Provide an option in DT to use legacy bch geometry, which compatible with the 3.10 kernel bch setting. To enable the feature, adding "fsl,legacy-bch-geometry" under gpmi-nand node. NOTICE: The feature must be enabled/disabled in both u-boot and kernel. Signed-off-by: Han Xu Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 4 ++-- drivers/mtd/nand/raw/mxs_nand_dt.c | 2 ++ include/mxs_nand.h | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 8da59e39c01..3247064c3f7 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -1053,8 +1053,8 @@ static int mxs_nand_set_geometry(struct mtd_info *mtd, struct bch_geometry *geo) return -EINVAL; } - if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) && - (mtd->oobsize < 1024)) { + if ((!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) && + mtd->oobsize < 1024) || nand_info->legacy_bch_geometry) { dev_warn(this->dev, "use legacy bch geometry\n"); return mxs_nand_legacy_calc_ecc_layout(geo, mtd); } diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index 8ad7d618c64..7a32b284f7f 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -69,6 +69,8 @@ static int mxs_nand_dt_probe(struct udevice *dev) info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc"); + info->legacy_bch_geometry = dev_read_bool(dev, "fsl,legacy-bch-geometry"); + return mxs_nand_init_ctrl(info); } diff --git a/include/mxs_nand.h b/include/mxs_nand.h index 497da77a16d..1ac628d0647 100644 --- a/include/mxs_nand.h +++ b/include/mxs_nand.h @@ -43,6 +43,8 @@ struct mxs_nand_info { struct udevice *dev; unsigned int max_ecc_strength_supported; bool use_minimum_ecc; + /* legacy bch geometry flag */ + bool legacy_bch_geometry; int cur_chip; uint32_t cmd_queue_len; From 552c88273ef9c5ebe269d47e7610a39ef5bfa5cc Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 22:08:52 +0800 Subject: [PATCH 47/82] nand: mxs: fix the bitflips for erased page when uncorrectable error This patch is porting from linux: http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/commit/ ?h=imx_4.1.15_1.0.0_ga&id=3d42fcece496224fde59f9343763fb2dfc5b0768 " We may meet the bitflips in reading an erased page(contains all 0xFF), this may causes the UBIFS corrupt, please see the log from Elie: ----------------------------------------------------------------- [ 3.831323] UBI warning: ubi_io_read: error -74 (ECC error) while reading 16384 bytes from PEB 443:245760, read only 16384 bytes, retry [ 3.845026] UBI warning: ubi_io_read: error -74 (ECC error) while reading 16384 bytes from PEB 443:245760, read only 16384 bytes, retry [ 3.858710] UBI warning: ubi_io_read: error -74 (ECC error) while reading 16384 bytes from PEB 443:245760, read only 16384 bytes, retry [ 3.872408] UBI error: ubi_io_read: error -74 (ECC error) while reading 16384 bytes from PEB 443:245760, read 16384 bytes ... [ 4.011529] UBIFS error (pid 36): ubifs_recover_leb: corrupt empty space LEB 27:237568, corruption starts at 9815 [ 4.021897] UBIFS error (pid 36): ubifs_scanned_corruption: corruption at LEB 27:247383 [ 4.030000] UBIFS error (pid 36): ubifs_scanned_corruption: first 6569 bytes from LEB 27:247383 ----------------------------------------------------------------- This patch does a check for the uncorrectable failure in the following steps: [0] set the threshold. The threshold is set based on the truth: "A single 0 bit will lead to gf_len(13 or 14) bits 0 after the BCH do the ECC." For the sake of safe, we will set the threshold with half the gf_len, and do not make it bigger the ECC strength. [1] count the bitflips of the current ECC chunk, assume it is N. [2] if the (N <= threshold) is true, we continue to read out the page with ECC disabled. and we count the bitflips again, assume it is N2. (We read out the whole page, not just a chunk, this makes the check more strictly, and make the code more simple.) [3] if the (N2 <= threshold) is true again, we can regard this is a erased page. This is because a real erased page is full of 0xFF(maybe also has several bitflips), while a page contains the 0xFF data will definitely has many bitflips in the ECC parity areas. [4] if the [3] fails, we can regard this is a page filled with the '0xFF' data. " Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 3247064c3f7..55d24cd0620 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -612,6 +612,45 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd) return buf; } +static bool mxs_nand_erased_page(struct mtd_info *mtd, struct nand_chip *nand, + u8 *buf, int chunk, int page) +{ + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + struct bch_geometry *geo = &nand_info->bch_geometry; + unsigned int flip_bits = 0, flip_bits_noecc = 0; + unsigned int threshold; + unsigned int base = geo->ecc_chunkn_size * chunk; + u32 *dma_buf = (u32 *)buf; + int i; + + threshold = geo->gf_len / 2; + if (threshold > geo->ecc_strength) + threshold = geo->ecc_strength; + + for (i = 0; i < geo->ecc_chunkn_size; i++) { + flip_bits += hweight8(~buf[base + i]); + if (flip_bits > threshold) + return false; + } + + nand->cmdfunc(mtd, NAND_CMD_READ0, 0, page); + nand->read_buf(mtd, buf, mtd->writesize); + + for (i = 0; i < mtd->writesize / 4; i++) { + flip_bits_noecc += hweight32(~dma_buf[i]); + if (flip_bits_noecc > threshold) + return false; + } + + mtd->ecc_stats.corrected += flip_bits; + + memset(buf, 0xff, mtd->writesize); + + printf("The page(%d) is an erased page(%d,%d,%d,%d).\n", page, chunk, threshold, flip_bits, flip_bits_noecc); + + return true; +} + /* * Read a page from NAND. */ @@ -715,6 +754,8 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, goto rtn; } + mxs_nand_return_dma_descs(nand_info); + /* Invalidate caches */ mxs_nand_inval_data_buf(nand_info); @@ -731,6 +772,9 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, continue; if (status[i] == 0xfe) { + if (mxs_nand_erased_page(mtd, nand, + nand_info->data_buf, i, page)) + break; failed++; continue; } From 29f40c07e7a649c6fc44a3a44449dce1ee733816 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 22:08:53 +0800 Subject: [PATCH 48/82] nand: mxs: correct bitflip for erased NAND page This patch is a porting of http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/ commit/?h=imx_4.1.15_1.0.0_ga&id=e4dacc44d22e9474ec456cb330df525cd805ea38 " i.MX6QP and i.MX7D BCH module integrated a new feature to detect the bitflip number for erased NAND page. So for these two platform, set the erase threshold to gf/2 and if bitflip detected, GPMI driver will correct the data to all 0xFF. Also updated the imx6qp dts file to ditinguish the GPMI module for i.MX6Q with the one for i.MX6QP. " In this patch, i.MX6UL is added and threshold changed to use ecc_strength. Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/regs-bch.h | 7 ++++++- drivers/mtd/nand/raw/mxs_nand.c | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/regs-bch.h b/arch/arm/include/asm/mach-imx/regs-bch.h index 39ac5f4d450..3c1abb7221c 100644 --- a/arch/arm/include/asm/mach-imx/regs-bch.h +++ b/arch/arm/include/asm/mach-imx/regs-bch.h @@ -6,7 +6,8 @@ * on behalf of DENX Software Engineering GmbH * * Based on code from LTIB: - * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008-2010, 2016 Freescale Semiconductor, Inc. All Rights Reserved. + * */ #ifndef __MX28_REGS_BCH_H__ @@ -40,6 +41,7 @@ struct mxs_bch_regs { mxs_reg_32(hw_bch_dbgahbmread) mxs_reg_32(hw_bch_blockname) mxs_reg_32(hw_bch_version) + mxs_reg_32(hw_bch_debug1) }; #endif @@ -75,6 +77,9 @@ struct mxs_bch_regs { #define BCH_MODE_ERASE_THRESHOLD_MASK 0xff #define BCH_MODE_ERASE_THRESHOLD_OFFSET 0 +#define BCH_MODE_ERASE_THRESHOLD(v) \ + (((v) << BCH_MODE_ERASE_THRESHOLD_OFFSET) & \ + BCH_MODE_ERASE_THRESHOLD_MASK) #define BCH_ENCODEPTR_ADDR_MASK 0xffffffff #define BCH_ENCODEPTR_ADDR_OFFSET 0 diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 55d24cd0620..2ac06a57306 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -10,6 +10,7 @@ * * Copyright (C) 2010 Freescale Semiconductor, Inc. * Copyright (C) 2008 Embedded Alley Solutions, Inc. + * Copyright 2017-2019 NXP */ #include @@ -660,11 +661,13 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, { struct mxs_nand_info *nand_info = nand_get_controller_data(nand); struct bch_geometry *geo = &nand_info->bch_geometry; + struct mxs_bch_regs *bch_regs = nand_info->bch_regs; struct mxs_dma_desc *d; uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip; uint32_t corrected = 0, failed = 0; uint8_t *status; int i, ret; + int flag = 0; /* Compile the DMA descriptor - wait for ready. */ d = mxs_nand_get_dma_desc(nand_info); @@ -768,8 +771,13 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, if (status[i] == 0x00) continue; - if (status[i] == 0xff) + if (status[i] == 0xff) { + if (is_mx6dqp() || is_mx7() || + is_mx6ul()) + if (readl(&bch_regs->hw_bch_debug1)) + flag = 1; continue; + } if (status[i] == 0xfe) { if (mxs_nand_erased_page(mtd, nand, @@ -801,6 +809,8 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, memcpy(buf, nand_info->data_buf, mtd->writesize); + if (flag) + memset(buf, 0xff, mtd->writesize); rtn: mxs_nand_return_dma_descs(nand_info); @@ -1160,6 +1170,12 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) writel(tmp, &bch_regs->hw_bch_flash0layout1); nand_info->bch_flash0layout1 = tmp; + /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */ + if (is_mx6dqp() || is_mx7() || + is_mx6ul()) + writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength), + &bch_regs->hw_bch_mode); + /* Set *all* chip selects to use layout 0 */ writel(0, &bch_regs->hw_bch_layoutselect); From ff99041b3b6dccc1649d0c8512303a5240fb8785 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 22:08:54 +0800 Subject: [PATCH 49/82] mxs_nand: Add support for i.MX8M Update the gpmi/apbh_dma/bch drivers and relevant registers for i.MX8M. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/dma.h | 2 +- arch/arm/include/asm/mach-imx/regs-apbh.h | 6 +++--- arch/arm/include/asm/mach-imx/regs-bch.h | 4 ++-- drivers/dma/Kconfig | 2 +- drivers/dma/apbh_dma.c | 2 +- drivers/mtd/nand/raw/Kconfig | 6 +++--- drivers/mtd/nand/raw/mxs_nand.c | 8 ++++---- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/dma.h b/arch/arm/include/asm/mach-imx/dma.h index ca70731b9eb..cb73aaeeb55 100644 --- a/arch/arm/include/asm/mach-imx/dma.h +++ b/arch/arm/include/asm/mach-imx/dma.h @@ -53,7 +53,7 @@ enum { MXS_DMA_CHANNEL_AHB_APBH_RESERVED1, MXS_MAX_DMA_CHANNELS, }; -#elif defined(CONFIG_MX6) || defined(CONFIG_MX7) +#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) enum { MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0, MXS_DMA_CHANNEL_AHB_APBH_GPMI1, diff --git a/arch/arm/include/asm/mach-imx/regs-apbh.h b/arch/arm/include/asm/mach-imx/regs-apbh.h index d7baf133434..d68953efd27 100644 --- a/arch/arm/include/asm/mach-imx/regs-apbh.h +++ b/arch/arm/include/asm/mach-imx/regs-apbh.h @@ -95,7 +95,7 @@ struct mxs_apbh_regs { mxs_reg_32(hw_apbh_version) }; -#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) struct mxs_apbh_regs { mxs_reg_32(hw_apbh_ctrl0) mxs_reg_32(hw_apbh_ctrl1) @@ -274,7 +274,7 @@ struct mxs_apbh_regs { #define APBH_CTRL0_CLKGATE_CHANNEL_NAND7 0x0800 #define APBH_CTRL0_CLKGATE_CHANNEL_HSADC 0x1000 #define APBH_CTRL0_CLKGATE_CHANNEL_LCDIF 0x2000 -#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #define APBH_CTRL0_CLKGATE_CHANNEL_OFFSET 0 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND0 0x0001 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND1 0x0002 @@ -390,7 +390,7 @@ struct mxs_apbh_regs { #define APBH_CHANNEL_CTRL_FREEZE_CHANNEL_LCDIF 0x2000 #endif -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16 #endif diff --git a/arch/arm/include/asm/mach-imx/regs-bch.h b/arch/arm/include/asm/mach-imx/regs-bch.h index 3c1abb7221c..4b99edbb3df 100644 --- a/arch/arm/include/asm/mach-imx/regs-bch.h +++ b/arch/arm/include/asm/mach-imx/regs-bch.h @@ -127,7 +127,7 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24 #define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16) #define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16 -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #define BCH_FLASHLAYOUT0_ECC0_MASK (0x1f << 11) #define BCH_FLASHLAYOUT0_ECC0_OFFSET 11 #else @@ -158,7 +158,7 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16) #define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16 -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #define BCH_FLASHLAYOUT1_ECCN_MASK (0x1f << 11) #define BCH_FLASHLAYOUT1_ECCN_OFFSET 11 #else diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 4f37ba7d35e..655e79fbafc 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -44,7 +44,7 @@ config TI_EDMA3 config APBH_DMA bool "Support APBH DMA" - depends on MX23 || MX28 || MX6 || MX7 + depends on MX23 || MX28 || MX6 || MX7 || IMX8M help Enable APBH DMA driver. diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index 15133128bef..8d17f8f01dd 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -215,7 +215,7 @@ static int mxs_dma_reset(int channel) #if defined(CONFIG_MX23) uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set); uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET; -#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set); uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; #endif diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 23201ca7204..c46fec3d325 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -259,12 +259,12 @@ config NAND_MXC config NAND_MXS bool "MXS NAND support" - depends on MX23 || MX28 || MX6 || MX7 + depends on MX23 || MX28 || MX6 || MX7 || IMX8M select SYS_NAND_SELF_INIT imply CMD_NAND select APBH_DMA - select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 - select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 + select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M + select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M help This enables NAND driver for the NAND flash controller on the MXS processors. diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 2ac06a57306..facedf92c5c 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -31,7 +31,7 @@ #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7)) +#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2 #else #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 0 @@ -773,7 +773,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, if (status[i] == 0xff) { if (is_mx6dqp() || is_mx7() || - is_mx6ul()) + is_mx6ul() || is_imx8m()) if (readl(&bch_regs->hw_bch_debug1)) flag = 1; continue; @@ -1172,7 +1172,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */ if (is_mx6dqp() || is_mx7() || - is_mx6ul()) + is_mx6ul() || is_imx8m()) writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength), &bch_regs->hw_bch_mode); @@ -1311,7 +1311,7 @@ int mxs_nand_init_spl(struct nand_chip *nand) nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; - if (is_mx6sx() || is_mx7()) + if (is_mx6sx() || is_mx7() || is_imx8m()) nand_info->max_ecc_strength_supported = 62; else nand_info->max_ecc_strength_supported = 40; From b209635c7a7f66e97d23de3b8c7f87d08c26b1ee Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 22:08:55 +0800 Subject: [PATCH 50/82] nand: Update SPL MXS NAND mini driver Update the mini driver to add support for getting ecc info from ONFI and support read image data from page unaligned NAND address. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand_spl.c | 41 ++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index a653dfa5edf..ae50cc37b52 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2014 Gateworks Corporation + * Copyright 2019 NXP * Author: Tim Harvey */ #include @@ -38,6 +39,12 @@ static void mxs_nand_command(struct mtd_info *mtd, unsigned int command, if (command == NAND_CMD_READ0) { chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE); chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0); + } else if (command == NAND_CMD_RNDOUT) { + /* No ready / busy check necessary */ + chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART, + NAND_NCE | NAND_CLE); + chip->cmd_ctrl(mtd, NAND_CMD_NONE, + NAND_NCE); } /* wait for nand ready */ @@ -212,23 +219,39 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf) unsigned int page; unsigned int nand_page_per_block; unsigned int sz = 0; + u8 *page_buf = NULL; + u32 page_off; chip = mtd_to_nand(mtd); if (!chip->numchips) return -ENODEV; + + page_buf = malloc(mtd->writesize); + if (!page_buf) + return -ENOMEM; + page = offs >> chip->page_shift; + page_off = offs & (mtd->writesize - 1); nand_page_per_block = mtd->erasesize / mtd->writesize; - debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page); + debug("%s offset:0x%08x len:%d page:%x\n", __func__, offs, size, page); - size = roundup(size, mtd->writesize); - while (sz < size) { - if (mxs_read_page_ecc(mtd, buf, page) < 0) + while (size) { + if (mxs_read_page_ecc(mtd, page_buf, page) < 0) return -1; - sz += mtd->writesize; + + if (size > (mtd->writesize - page_off)) + sz = (mtd->writesize - page_off); + else + sz = size; + + memcpy(buf, page_buf + page_off, sz); + offs += mtd->writesize; page++; - buf += mtd->writesize; + buf += (mtd->writesize - page_off); + page_off = 0; + size -= sz; /* * Check if we have crossed a block boundary, and if so @@ -242,12 +265,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf) while (is_badblock(mtd, offs, 1)) { page = page + nand_page_per_block; /* Check i we've reached the end of flash. */ - if (page >= mtd->size >> chip->page_shift) + if (page >= mtd->size >> chip->page_shift) { + free(page_buf); return -ENOMEM; + } } } } + free(page_buf); + return 0; } From e551ee2deac2f63bc5f84ea0dc3ad3a3b74a107f Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 22:08:56 +0800 Subject: [PATCH 51/82] mxs_nand: Update compatible string for i.MX6SX The iMX6SX uses compatible string "fsl,imx6sx-gpmi-nand" for gpmi node in DTS, so update the driver for the string Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand_dt.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index 7a32b284f7f..7efc9684db8 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -25,6 +25,10 @@ static const struct mxs_nand_dt_data mxs_nand_imx6q_data = { .max_ecc_strength_supported = 40, }; +static const struct mxs_nand_dt_data mxs_nand_imx6sx_data = { + .max_ecc_strength_supported = 62, +}; + static const struct mxs_nand_dt_data mxs_nand_imx7d_data = { .max_ecc_strength_supported = 62, }; @@ -34,6 +38,10 @@ static const struct udevice_id mxs_nand_dt_ids[] = { .compatible = "fsl,imx6q-gpmi-nand", .data = (unsigned long)&mxs_nand_imx6q_data, }, + { + .compatible = "fsl,imx6sx-gpmi-nand", + .data = (unsigned long)&mxs_nand_imx6sx_data, + }, { .compatible = "fsl,imx7d-gpmi-nand", .data = (unsigned long)&mxs_nand_imx7d_data, From 9fdb5f0a0c3af60375831eeb1988c6934698ad22 Mon Sep 17 00:00:00 2001 From: Han Xu Date: Mon, 4 May 2020 22:08:57 +0800 Subject: [PATCH 52/82] mtd: nand: mxs_nand: add i.MX6QP compatible string add the dedicate compatible string for i.MX6QP Signed-off-by: Han Xu Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand_dt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index 7efc9684db8..bd429e0d626 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -38,6 +38,10 @@ static const struct udevice_id mxs_nand_dt_ids[] = { .compatible = "fsl,imx6q-gpmi-nand", .data = (unsigned long)&mxs_nand_imx6q_data, }, + { + .compatible = "fsl,imx6qp-gpmi-nand", + .data = (unsigned long)&mxs_nand_imx6q_data, + }, { .compatible = "fsl,imx6sx-gpmi-nand", .data = (unsigned long)&mxs_nand_imx6sx_data, From 17282f45abba6f10842adafdd47c0f24cae6b0ef Mon Sep 17 00:00:00 2001 From: Han Xu Date: Mon, 4 May 2020 22:08:58 +0800 Subject: [PATCH 53/82] mtd: mxs_nand: fix the gf_13/14 definition issue gf_13/14 mask was not set correctly in register definition. Signed-off-by: Han Xu Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/regs-bch.h | 8 ++++---- drivers/mtd/nand/raw/mxs_nand.c | 2 ++ include/mxs_nand.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/regs-bch.h b/arch/arm/include/asm/mach-imx/regs-bch.h index 4b99edbb3df..664fb9fd4dc 100644 --- a/arch/arm/include/asm/mach-imx/regs-bch.h +++ b/arch/arm/include/asm/mach-imx/regs-bch.h @@ -151,9 +151,9 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT0_ECC0_ECC28 (0xe << 12) #define BCH_FLASHLAYOUT0_ECC0_ECC30 (0xf << 12) #define BCH_FLASHLAYOUT0_ECC0_ECC32 (0x10 << 12) -#define BCH_FLASHLAYOUT0_GF13_0_GF14_1 (1 << 10) +#define BCH_FLASHLAYOUT0_GF13_0_GF14_1_MASK BIT(10) #define BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET 10 -#define BCH_FLASHLAYOUT0_DATA0_SIZE_MASK 0xfff +#define BCH_FLASHLAYOUT0_DATA0_SIZE_MASK 0x3ff #define BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET 0 #define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16) @@ -182,9 +182,9 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT1_ECCN_ECC28 (0xe << 12) #define BCH_FLASHLAYOUT1_ECCN_ECC30 (0xf << 12) #define BCH_FLASHLAYOUT1_ECCN_ECC32 (0x10 << 12) -#define BCH_FLASHLAYOUT1_GF13_0_GF14_1 (1 << 10) +#define BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK BIT(10) #define BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET 10 -#define BCH_FLASHLAYOUT1_DATAN_SIZE_MASK 0xfff +#define BCH_FLASHLAYOUT1_DATAN_SIZE_MASK 0x3ff #define BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET 0 #define BCH_DEBUG0_RSVD1_MASK (0x1f << 27) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index facedf92c5c..1b66636a4f4 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -1474,6 +1474,8 @@ void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l) BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET); l->eccn = (tmp & BCH_FLASHLAYOUT1_ECCN_MASK) >> BCH_FLASHLAYOUT1_ECCN_OFFSET; + l->gf_len = (tmp & BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK) >> + BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; } /* diff --git a/include/mxs_nand.h b/include/mxs_nand.h index 1ac628d0647..21d68a909d7 100644 --- a/include/mxs_nand.h +++ b/include/mxs_nand.h @@ -88,6 +88,7 @@ struct mxs_nand_layout { u32 ecc0; u32 datan_size; u32 eccn; + u32 gf_len; }; int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info); From f290fe0a4291a6251358aaca7a3f25964f0e12da Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Mon, 4 May 2020 22:08:59 +0800 Subject: [PATCH 54/82] nand: mxs_nand: make imx8mm can use hardware BCH and randomizer imx8mm needs to BCH encode and set NAND page number needed to be randomized modify conditional compilation Use CONFIG_IMX8M, so it apply to imx8mq/mm/mn Signed-off-by: Alice Guo Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 1b66636a4f4..3bf5ab2d8c6 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -859,7 +859,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; - if (is_mx7() && nand_info->en_randomizer) { + if ((is_mx7() || is_imx8m()) && nand_info->en_randomizer) { d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | GPMI_ECCCTRL_RANDOMIZER_TYPE2; /* From 39320e7256412ed4b6eee9fc09f7d30f0e4ddee4 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 22:09:00 +0800 Subject: [PATCH 55/82] mtd: nand: support GPMI NAND driver for i.MX8 enable the GPMI NAND driver for i.MX8, i.MX8 use similar controller as i.MX8M - register definition for i.mx8 - DMA structure must be 32bit address Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/dma.h | 15 ++++++++------- arch/arm/include/asm/mach-imx/regs-apbh.h | 9 ++++----- arch/arm/include/asm/mach-imx/regs-bch.h | 5 +++-- drivers/dma/Kconfig | 2 +- drivers/dma/apbh_dma.c | 13 ++++++++----- drivers/mtd/nand/raw/Kconfig | 6 +++--- drivers/mtd/nand/raw/mxs_nand.c | 15 ++++++++------- drivers/mtd/nand/raw/mxs_nand_dt.c | 8 ++++++++ 8 files changed, 43 insertions(+), 30 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/dma.h b/arch/arm/include/asm/mach-imx/dma.h index cb73aaeeb55..247a91afb06 100644 --- a/arch/arm/include/asm/mach-imx/dma.h +++ b/arch/arm/include/asm/mach-imx/dma.h @@ -7,6 +7,7 @@ * * Based on code from LTIB: * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2020 NXP */ #ifndef __DMA_H__ @@ -53,7 +54,7 @@ enum { MXS_DMA_CHANNEL_AHB_APBH_RESERVED1, MXS_MAX_DMA_CHANNELS, }; -#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#else enum { MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0, MXS_DMA_CHANNEL_AHB_APBH_GPMI1, @@ -95,13 +96,13 @@ enum { #define MXS_DMA_DESC_BYTES_OFFSET 16 struct mxs_dma_cmd { - unsigned long next; - unsigned long data; + u32 next; + u32 data; union { - dma_addr_t address; - unsigned long alternate; + u32 address; + u32 alternate; }; - unsigned long pio_words[DMA_PIO_WORDS]; + u32 pio_words[DMA_PIO_WORDS]; }; /* @@ -117,7 +118,7 @@ struct mxs_dma_cmd { struct mxs_dma_desc { struct mxs_dma_cmd cmd; unsigned int flags; - dma_addr_t address; + u32 address; void *buffer; struct list_head node; } __aligned(MXS_DMA_ALIGNMENT); diff --git a/arch/arm/include/asm/mach-imx/regs-apbh.h b/arch/arm/include/asm/mach-imx/regs-apbh.h index d68953efd27..94c330c7f92 100644 --- a/arch/arm/include/asm/mach-imx/regs-apbh.h +++ b/arch/arm/include/asm/mach-imx/regs-apbh.h @@ -7,6 +7,7 @@ * * Based on code from LTIB: * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2020 NXP */ #ifndef __REGS_APBH_H__ @@ -95,7 +96,7 @@ struct mxs_apbh_regs { mxs_reg_32(hw_apbh_version) }; -#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#else struct mxs_apbh_regs { mxs_reg_32(hw_apbh_ctrl0) mxs_reg_32(hw_apbh_ctrl1) @@ -274,7 +275,7 @@ struct mxs_apbh_regs { #define APBH_CTRL0_CLKGATE_CHANNEL_NAND7 0x0800 #define APBH_CTRL0_CLKGATE_CHANNEL_HSADC 0x1000 #define APBH_CTRL0_CLKGATE_CHANNEL_LCDIF 0x2000 -#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)) #define APBH_CTRL0_CLKGATE_CHANNEL_OFFSET 0 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND0 0x0001 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND1 0x0002 @@ -357,7 +358,6 @@ struct mxs_apbh_regs { #if defined(CONFIG_MX28) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_MASK (0xffff << 16) -#define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16 #define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP0 (0x0001 << 16) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP1 (0x0002 << 16) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP2 (0x0004 << 16) @@ -390,9 +390,8 @@ struct mxs_apbh_regs { #define APBH_CHANNEL_CTRL_FREEZE_CHANNEL_LCDIF 0x2000 #endif -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +/* Not on i.MX23 */ #define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16 -#endif #if defined(CONFIG_MX23) #define APBH_DEVSEL_CH7_MASK (0xf << 28) diff --git a/arch/arm/include/asm/mach-imx/regs-bch.h b/arch/arm/include/asm/mach-imx/regs-bch.h index 664fb9fd4dc..5a149002e2a 100644 --- a/arch/arm/include/asm/mach-imx/regs-bch.h +++ b/arch/arm/include/asm/mach-imx/regs-bch.h @@ -7,6 +7,7 @@ * * Based on code from LTIB: * Copyright 2008-2010, 2016 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2020 NXP * */ @@ -127,7 +128,7 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24 #define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16) #define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16 -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)) #define BCH_FLASHLAYOUT0_ECC0_MASK (0x1f << 11) #define BCH_FLASHLAYOUT0_ECC0_OFFSET 11 #else @@ -158,7 +159,7 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16) #define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16 -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)) #define BCH_FLASHLAYOUT1_ECCN_MASK (0x1f << 11) #define BCH_FLASHLAYOUT1_ECCN_OFFSET 11 #else diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 655e79fbafc..1993c1d31df 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -44,7 +44,7 @@ config TI_EDMA3 config APBH_DMA bool "Support APBH DMA" - depends on MX23 || MX28 || MX6 || MX7 || IMX8M + depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M help Enable APBH DMA driver. diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index 8d17f8f01dd..69eb040d324 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -7,6 +7,8 @@ * * Based on code from LTIB: * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2017 NXP + * */ #include @@ -88,7 +90,7 @@ void mxs_dma_flush_desc(struct mxs_dma_desc *desc) uint32_t addr; uint32_t size; - addr = (uint32_t)desc; + addr = (uintptr_t)desc; size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); flush_dcache_range(addr, addr + size); @@ -215,16 +217,17 @@ static int mxs_dma_reset(int channel) #if defined(CONFIG_MX23) uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set); uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET; -#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) - uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set); - uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; +#elif defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || \ + defined(CONFIG_IMX8) || defined(CONFIG_IMX8M) + u32 setreg = (uintptr_t)(&apbh_regs->hw_apbh_channel_ctrl_set); + u32 offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; #endif ret = mxs_dma_validate_chan(channel); if (ret) return ret; - writel(1 << (channel + offset), setreg); + writel(1 << (channel + offset), (uintptr_t)setreg); return 0; } diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index c46fec3d325..c4d9d313883 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -259,12 +259,12 @@ config NAND_MXC config NAND_MXS bool "MXS NAND support" - depends on MX23 || MX28 || MX6 || MX7 || IMX8M + depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M select SYS_NAND_SELF_INIT imply CMD_NAND select APBH_DMA - select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M - select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M + select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M + select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M help This enables NAND driver for the NAND flash controller on the MXS processors. diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 3bf5ab2d8c6..b6e65c616d3 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -31,7 +31,8 @@ #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || \ + defined(CONFIG_IMX8M) #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2 #else #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 0 @@ -55,21 +56,21 @@ struct nand_ecclayout fake_ecc_layout; #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) static void mxs_nand_flush_data_buf(struct mxs_nand_info *info) { - uint32_t addr = (uint32_t)info->data_buf; + uint32_t addr = (uintptr_t)info->data_buf; flush_dcache_range(addr, addr + info->data_buf_size); } static void mxs_nand_inval_data_buf(struct mxs_nand_info *info) { - uint32_t addr = (uint32_t)info->data_buf; + uint32_t addr = (uintptr_t)info->data_buf; invalidate_dcache_range(addr, addr + info->data_buf_size); } static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) { - uint32_t addr = (uint32_t)info->cmd_buf; + uint32_t addr = (uintptr_t)info->cmd_buf; flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE); } @@ -773,7 +774,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, if (status[i] == 0xff) { if (is_mx6dqp() || is_mx7() || - is_mx6ul() || is_imx8m()) + is_mx6ul() || is_imx8() || is_imx8m()) if (readl(&bch_regs->hw_bch_debug1)) flag = 1; continue; @@ -1172,7 +1173,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */ if (is_mx6dqp() || is_mx7() || - is_mx6ul() || is_imx8m()) + is_mx6ul() || is_imx8() || is_imx8m()) writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength), &bch_regs->hw_bch_mode); @@ -1311,7 +1312,7 @@ int mxs_nand_init_spl(struct nand_chip *nand) nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; - if (is_mx6sx() || is_mx7() || is_imx8m()) + if (is_mx6sx() || is_mx7() || is_imx8() || is_imx8m()) nand_info->max_ecc_strength_supported = 62; else nand_info->max_ecc_strength_supported = 40; diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index bd429e0d626..c4dc0bb1ddf 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -33,6 +33,10 @@ static const struct mxs_nand_dt_data mxs_nand_imx7d_data = { .max_ecc_strength_supported = 62, }; +static const struct mxs_nand_dt_data mxs_nand_imx8qxp_data = { + .max_ecc_strength_supported = 62, +}; + static const struct udevice_id mxs_nand_dt_ids[] = { { .compatible = "fsl,imx6q-gpmi-nand", @@ -50,6 +54,10 @@ static const struct udevice_id mxs_nand_dt_ids[] = { .compatible = "fsl,imx7d-gpmi-nand", .data = (unsigned long)&mxs_nand_imx7d_data, }, + { + .compatible = "fsl,imx8qxp-gpmi-nand", + .data = (unsigned long)&mxs_nand_imx8qxp_data, + }, { /* sentinel */ } }; From a59691280dacae478183c95a93c5f00f4717d49c Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 22:09:01 +0800 Subject: [PATCH 56/82] MXS_NAND: Add clock support for iMX8 Since iMX8 has enabled clock uclass, we can parse the clocks from DTB and enable them in GPMI driver. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand_dt.c | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index c4dc0bb1ddf..43dbe9e66ec 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -2,6 +2,8 @@ * NXP GPMI NAND flash driver (DT initialization) * * Copyright (C) 2018 Toradex + * Copyright 2019 NXP + * * Authors: * Stefan Agner * @@ -14,6 +16,7 @@ #include #include #include +#include #include @@ -91,6 +94,72 @@ static int mxs_nand_dt_probe(struct udevice *dev) info->legacy_bch_geometry = dev_read_bool(dev, "fsl,legacy-bch-geometry"); + if (IS_ENABLED(CONFIG_CLK) && IS_ENABLED(CONFIG_IMX8)) { + /* Assigned clock already set clock */ + struct clk gpmi_clk; + + ret = clk_get_by_name(dev, "gpmi_io", &gpmi_clk); + if (ret < 0) { + debug("Can't get gpmi io clk: %d\n", ret); + return ret; + } + + ret = clk_enable(&gpmi_clk); + if (ret < 0) { + debug("Can't enable gpmi io clk: %d\n", ret); + return ret; + } + + ret = clk_get_by_name(dev, "gpmi_apb", &gpmi_clk); + if (ret < 0) { + debug("Can't get gpmi_apb clk: %d\n", ret); + return ret; + } + + ret = clk_enable(&gpmi_clk); + if (ret < 0) { + debug("Can't enable gpmi_apb clk: %d\n", ret); + return ret; + } + + ret = clk_get_by_name(dev, "gpmi_bch", &gpmi_clk); + if (ret < 0) { + debug("Can't get gpmi_bch clk: %d\n", ret); + return ret; + } + + ret = clk_enable(&gpmi_clk); + if (ret < 0) { + debug("Can't enable gpmi_bch clk: %d\n", ret); + return ret; + } + + ret = clk_get_by_name(dev, "gpmi_apb_bch", &gpmi_clk); + if (ret < 0) { + debug("Can't get gpmi_apb_bch clk: %d\n", ret); + return ret; + } + + ret = clk_enable(&gpmi_clk); + if (ret < 0) { + debug("Can't enable gpmi_apb_bch clk: %d\n", ret); + return ret; + } + + /* this clock is used for apbh_dma, since the apbh dma does not support DM, + * we optionally enable it here + */ + ret = clk_get_by_name(dev, "gpmi_apbh_dma", &gpmi_clk); + if (ret < 0) { + debug("Can't get gpmi_apbh_dma clk: %d\n", ret); + } else { + ret = clk_enable(&gpmi_clk); + if (ret < 0) { + debug("Can't enable gpmi_apbh_dma clk: %d\n", ret); + } + } + } + return mxs_nand_init_ctrl(info); } From f7bb012ab7e19d3ede6c0e9a39edd6a37bd598ff Mon Sep 17 00:00:00 2001 From: Han Xu Date: Mon, 4 May 2020 22:09:02 +0800 Subject: [PATCH 57/82] mxs_nand: don't check zero count when ECC reading with randomizer When enabled randomizer during ECC reading, the controller reported it's erased page. Checking zero count will cause data get modified to all 0xFF. Stop checking during randomizer to workaround this issue. Signed-off-by: Han Xu Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index b6e65c616d3..3fd21e51f2a 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -773,8 +773,9 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, continue; if (status[i] == 0xff) { - if (is_mx6dqp() || is_mx7() || - is_mx6ul() || is_imx8() || is_imx8m()) + if (!nand_info->en_randomizer && + (is_mx6dqp() || is_mx7() || is_mx6ul() || + is_imx8() || is_imx8m())) if (readl(&bch_regs->hw_bch_debug1)) flag = 1; continue; From fe04bcd7e86ba2b9ccbcf83b5afc278e69115756 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Mon, 4 May 2020 22:09:03 +0800 Subject: [PATCH 58/82] nand: enable the Randomizer module for i.mx7 and i.mx8 To enable the Randomizer module, set GPMI_ECCCTRL[RANDOMIZER_ENABLE] to 1, then set GPMI_ECCCOUNT[RANDOMIZER_PAGE] to select randomizer page number needed to be randomized. Signed-off-by: Alice Guo Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 3fd21e51f2a..c3191feca8e 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -710,6 +710,12 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; + if ((is_mx7() || is_imx8m()) && nand_info->en_randomizer) { + d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | + GPMI_ECCCTRL_RANDOMIZER_TYPE2; + d->cmd.pio_words[3] |= (page % 256) << 16; + } + mxs_dma_desc_append(channel, d); /* Compile the DMA descriptor - disable the BCH block. */ @@ -871,7 +877,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, * The value is between 0-255. For additional details * check 9.6.6.4 of i.MX7D Applications Processor reference */ - d->cmd.pio_words[3] |= (page % 255) << 16; + d->cmd.pio_words[3] |= (page % 256) << 16; } mxs_dma_desc_append(channel, d); From f36f8bc627379ef6b732dc2be4f10e972089a744 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sun, 3 May 2020 08:11:33 -0500 Subject: [PATCH 59/82] imx: Add support for i.MX8MM Beacon EmbeddedWorks devkit. Beacon EmbeddedWorks, formerly known as Logic PD, is releasing a devkit based on the i.MX8M Mini SoC consisting of baseboard + SOM. It supports eMMC on the SOM, microSD on the baseboard, various GPIO, the PINCTRL, and UART. Signed-off-by: Adam Ford --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx8mm-beacon-baseboard.dtsi | 285 +++ arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi | 131 ++ arch/arm/dts/imx8mm-beacon-kit.dts | 19 + arch/arm/dts/imx8mm-beacon-som.dtsi | 390 ++++ arch/arm/mach-imx/imx8m/Kconfig | 7 + board/beacon/imx8mm/Kconfig | 14 + board/beacon/imx8mm/MAINTAINERS | 7 + board/beacon/imx8mm/Makefile | 13 + board/beacon/imx8mm/README | 37 + board/beacon/imx8mm/imx8mm_beacon.c | 67 + board/beacon/imx8mm/lpddr4_timing.c | 1980 ++++++++++++++++++++ board/beacon/imx8mm/spl.c | 155 ++ configs/imx8mm_beacon_defconfig | 104 + include/configs/imx8mm_beacon.h | 152 ++ 15 files changed, 3362 insertions(+) create mode 100644 arch/arm/dts/imx8mm-beacon-baseboard.dtsi create mode 100644 arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi create mode 100644 arch/arm/dts/imx8mm-beacon-kit.dts create mode 100644 arch/arm/dts/imx8mm-beacon-som.dtsi create mode 100644 board/beacon/imx8mm/Kconfig create mode 100644 board/beacon/imx8mm/MAINTAINERS create mode 100644 board/beacon/imx8mm/Makefile create mode 100644 board/beacon/imx8mm/README create mode 100644 board/beacon/imx8mm/imx8mm_beacon.c create mode 100644 board/beacon/imx8mm/lpddr4_timing.c create mode 100644 board/beacon/imx8mm/spl.c create mode 100644 configs/imx8mm_beacon_defconfig create mode 100644 include/configs/imx8mm_beacon.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 121597756ea..1325134bd41 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -736,6 +736,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \ imx8mm-verdin.dtb \ imx8mn-ddr4-evk.dtb \ imx8mq-evk.dtb \ + imx8mm-beacon-kit.dtb \ imx8mq-phanbell.dtb \ imx8mp-evk.dtb \ imx8mq-pico-pi.dtb diff --git a/arch/arm/dts/imx8mm-beacon-baseboard.dtsi b/arch/arm/dts/imx8mm-beacon-baseboard.dtsi new file mode 100644 index 00000000000..baa5f997d01 --- /dev/null +++ b/arch/arm/dts/imx8mm-beacon-baseboard.dtsi @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2020 Compass Electronics Group, LLC + */ + +/ { + leds { + compatible = "gpio-leds"; + + led0 { + label = "gen_led0"; + gpios = <&pca6416_1 4 GPIO_ACTIVE_HIGH>; + default-state = "none"; + }; + + led1 { + label = "gen_led1"; + gpios = <&pca6416_1 5 GPIO_ACTIVE_HIGH>; + default-state = "none"; + }; + + led2 { + label = "gen_led2"; + gpios = <&pca6416_1 6 GPIO_ACTIVE_HIGH>; + default-state = "none"; + }; + + led3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led3>; + label = "heartbeat"; + gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + reg_audio: regulator-audio { + compatible = "regulator-fixed"; + regulator-name = "3v3_aud"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pca6416_1 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + sound { + compatible = "fsl,imx-audio-wm8962"; + model = "wm8962-audio"; + audio-cpu = <&sai3>; + audio-codec = <&wm8962>; + audio-routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "Ext Spk", "SPKOUTL", + "Ext Spk", "SPKOUTR", + "AMIC", "MICBIAS", + "IN3R", "AMIC"; + }; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_espi2>; + cs-gpios = <&gpio5 9 0>; + status = "okay"; + + eeprom@0 { + compatible = "microchip,at25160bn", "atmel,at25"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-cpha; + spi-cpol; + pagesize = <32>; + size = <2048>; + address-width = <16>; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&i2c4 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4>; + status = "okay"; + + wm8962: audio-codec@1a { + compatible = "wlf,wm8962"; + reg = <0x1a>; + clocks = <&clk IMX8MM_CLK_SAI3_ROOT>; + clock-names = "xclk"; + DCVDD-supply = <®_audio>; + DBVDD-supply = <®_audio>; + AVDD-supply = <®_audio>; + CPVDD-supply = <®_audio>; + MICVDD-supply = <®_audio>; + PLLVDD-supply = <®_audio>; + SPKVDD1-supply = <®_audio>; + SPKVDD2-supply = <®_audio>; + gpio-cfg = < + 0x0000 /* 0:Default */ + 0x0000 /* 1:Default */ + 0x0000 /* 2:FN_DMICCLK */ + 0x0000 /* 3:Default */ + 0x0000 /* 4:FN_DMICCDAT */ + 0x0000 /* 5:Default */ + >; + }; + + pca6416_0: gpio@20 { + compatible = "nxp,pcal6416"; + reg = <0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcal6414>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio4>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + }; + + pca6416_1: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio4>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3>; + assigned-clocks = <&clk IMX8MM_CLK_SAI3>; + assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&uart2 { /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + assigned-clocks = <&clk IMX8MM_CLK_UART3>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + bus-width = <4>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&iomuxc { + pinctrl_espi2: espi2grp { + fsl,pins = < + MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 + MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 + MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 + MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x41 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 + MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 + MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 + >; + }; + + pinctrl_led3: led3grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x41 + >; + }; + + pinctrl_pcal6414: pcal6414-gpio { + fsl,pins = < + MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x19 + >; + }; + + pinctrl_sai3: sai3grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6 + MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6 + MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6 + MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6 + MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140 + MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x40 + MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x40 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2grpgpio { + fsl,pins = < + MX8MM_IOMUXC_SD2_CD_B_USDHC2_CD_B 0x41 + MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 + MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 + MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 + MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 + MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + >; + }; +}; diff --git a/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi b/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi new file mode 100644 index 00000000000..fc1aebb2feb --- /dev/null +++ b/arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Compass Electronics Group, LLC + */ + +/ { + wdt-reboot { + compatible = "wdt-reboot"; + wdt = <&wdog1>; + u-boot,dm-spl; + }; +}; + +&{/soc@0} { + u-boot,dm-pre-reloc; + u-boot,dm-spl; +}; + +&aips1 { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&aips2 { + u-boot,dm-spl; +}; + +&aips3 { + u-boot,dm-spl; +}; + +&clk { + u-boot,dm-spl; + u-boot,dm-pre-reloc; + /delete-property/ assigned-clocks; + /delete-property/ assigned-clock-parents; + /delete-property/ assigned-clock-rates; +}; + +&fec1 { + phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&iomuxc { + u-boot,dm-spl; +}; + +&osc_24m { + u-boot,dm-spl; + u-boot,dm-pre-reloc; +}; + +&pca6416_0 { + compatible = "ti,tca6416"; +}; + +&pca6416_1 { + compatible = "ti,tca6416"; +}; + +&pinctrl_i2c1 { + u-boot,dm-spl; +}; + +&pinctrl_pmic { + u-boot,dm-spl; +}; + +&pinctrl_uart2 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc2_gpio { + u-boot,dm-spl; +}; + +&pinctrl_usdhc2 { + u-boot,dm-spl; +}; + +&pinctrl_usdhc3 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&usdhc3 { + u-boot,dm-spl; +}; + +&i2c1 { + u-boot,dm-spl; +}; + +&{/soc@0/bus@30800000/i2c@30a20000/pmic@4b} { + u-boot,dm-spl; +}; + +&{/soc@0/bus@30800000/i2c@30a20000/pmic@4b/regulators} { + u-boot,dm-spl; +}; + +&wdog1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx8mm-beacon-kit.dts b/arch/arm/dts/imx8mm-beacon-kit.dts new file mode 100644 index 00000000000..74a7b0cc10c --- /dev/null +++ b/arch/arm/dts/imx8mm-beacon-kit.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2020 Compass Electronics Group, LLC + */ + +/dts-v1/; + +#include "imx8mm.dtsi" +#include "imx8mm-beacon-som.dtsi" +#include "imx8mm-beacon-baseboard.dtsi" + +/ { + model = "Beacon EmbeddedWorks i.MX8M Mini Development Kit"; + compatible = "beacon,imx8mm-beacon-kit", "fsl,imx8mm"; + + chosen { + stdout-path = &uart2; + }; +}; diff --git a/arch/arm/dts/imx8mm-beacon-som.dtsi b/arch/arm/dts/imx8mm-beacon-som.dtsi new file mode 100644 index 00000000000..801bd02eaed --- /dev/null +++ b/arch/arm/dts/imx8mm-beacon-som.dtsi @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2020 Compass Electronics Group, LLC + */ + +/ { + usdhc1_pwrseq: usdhc1_pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1_gpio>; + reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; + clocks = <&osc_32k>; + clock-names = "ext_clock"; + post-power-on-delay-ms = <80>; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x0 0x40000000 0 0x80000000>; + }; +}; + +&A53_0 { + cpu-supply = <&buck2_reg>; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic@4b { + compatible = "rohm,bd71847"; + reg = <0x4b>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + interrupts = <3 GPIO_ACTIVE_LOW>; + rohm,reset-snvs-powered; + + regulators { + buck1_reg: BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + }; + + buck2_reg: BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + buck3_reg: BUCK3 { + // BUCK5 in datasheet + regulator-name = "buck3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + // BUCK6 in datasheet + regulator-name = "buck4"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5_reg: BUCK5 { + // BUCK7 in datasheet + regulator-name = "buck5"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + // BUCK8 in datasheet + regulator-name = "buck6"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + eeprom@50 { + compatible = "microchip, at24c64d", "atmel,24c64"; + pagesize = <32>; + read-only; /* Manufacturing EEPROM programmed at factory */ + reg = <0x50>; + }; + + rtc@51 { + compatible = "nxp,pcf85263"; + reg = <0x51>; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + assigned-clocks = <&clk IMX8MM_CLK_UART1>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + shutdown-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; + host-wakeup-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; + device-wakeup-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; + clocks = <&osc_32k>; + clock-names = "extclk"; + }; +}; + +&usdhc1 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + bus-width = <4>; + non-removable; + cap-power-off-card; + pm-ignore-notify; + keep-power-in-suspend; + mmc-pwrseq = <&usdhc1_pwrseq>; + status = "okay"; + + brcmf: bcrmf@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wlan>; + interrupt-parent = <&gpio2>; + interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + }; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3 + MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 + MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 + >; + }; + + pinctrl_pmic: pmicirq { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140 + MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140 + MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140 + MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140 + MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19 + MX8MM_IOMUXC_SD1_DATA5_GPIO2_IO7 0x19 + MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x19 + MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x141 + >; + }; + + pinctrl_usdhc1_gpio: usdhc1grpgpio { + fsl,pins = < + MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196 + MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6 + MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6 + MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6 + MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6 + MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp100mhz { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp200mhz { + fsl,pins = < + MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196 + MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6 + MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6 + MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6 + MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6 + MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6 + MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6 + MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6 + MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6 + MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6 + MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; + + pinctrl_wlan: wlangrp { + fsl,pins = < + MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x111 + >; + }; +}; diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig index 7d1fe758e66..7771fc88afe 100644 --- a/arch/arm/mach-imx/imx8m/Kconfig +++ b/arch/arm/mach-imx/imx8m/Kconfig @@ -66,6 +66,12 @@ config TARGET_VERDIN_IMX8MM select SUPPORT_SPL select IMX8M_LPDDR4 +config TARGET_IMX8MM_BEACON + bool "imx8mm Beacon Embedded devkit" + select IMX8MM + select SUPPORT_SPL + select IMX8M_LPDDR4 + endchoice source "board/freescale/imx8mq_evk/Kconfig" @@ -75,5 +81,6 @@ source "board/freescale/imx8mp_evk/Kconfig" source "board/google/imx8mq_phanbell/Kconfig" source "board/technexion/pico-imx8mq/Kconfig" source "board/toradex/verdin-imx8mm/Kconfig" +source "board/beacon/imx8mm/Kconfig" endif diff --git a/board/beacon/imx8mm/Kconfig b/board/beacon/imx8mm/Kconfig new file mode 100644 index 00000000000..df3125eae9a --- /dev/null +++ b/board/beacon/imx8mm/Kconfig @@ -0,0 +1,14 @@ +if TARGET_IMX8MM_BEACON + +config SYS_BOARD + default "imx8mm" + +config SYS_VENDOR + default "beacon" + +config SYS_CONFIG_NAME + default "imx8mm_beacon" + +source "board/freescale/common/Kconfig" + +endif diff --git a/board/beacon/imx8mm/MAINTAINERS b/board/beacon/imx8mm/MAINTAINERS new file mode 100644 index 00000000000..e887db20a21 --- /dev/null +++ b/board/beacon/imx8mm/MAINTAINERS @@ -0,0 +1,7 @@ +i.MX8MM Beacon EmbeddedWorks Devkit + +M: Adam Ford +S: Maintained +F: board/beacon/imx8mm/ +F: include/configs/imx8mm_beacon.h +F: configs/imx8mm_beacon_defconfig diff --git a/board/beacon/imx8mm/Makefile b/board/beacon/imx8mm/Makefile new file mode 100644 index 00000000000..7d3bd3112cb --- /dev/null +++ b/board/beacon/imx8mm/Makefile @@ -0,0 +1,13 @@ +# +# Copyright 2020 Compass Electronics Group, LLC +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += imx8mm_beacon.o +obj-y += ../../freescale/common/ + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +obj-y += lpddr4_timing.o +endif diff --git a/board/beacon/imx8mm/README b/board/beacon/imx8mm/README new file mode 100644 index 00000000000..4223fbd15dd --- /dev/null +++ b/board/beacon/imx8mm/README @@ -0,0 +1,37 @@ +U-Boot for the Beacon EmbeddedWorks Devkit + +Quick Start +=========== +- Build the ARM Trusted firmware binary +- Get ddr firmware +- Build U-Boot +- Boot + +Get and Build the ARM Trusted firmware +====================================== +Note: $(srctree) is U-Boot source directory + +$ git clone https://source.codeaurora.org/external/imx/imx-atf +$ git checkout imx_4.19.35_1.0.0 +$ make PLAT=imx8mm bl31 ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- +$ cp build/imx8mm/release/bl31.bin $(srctree) + +Get the DDR firmware +==================== +$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.5.bin +$ chmod +x firmware-imx-8.5.bin +$ ./firmware-imx-8.5 +$ cp firmware-imx-8.5/firmware/ddr/synopsys/lpddr4*.bin $(srctree) + +Build U-Boot +============ +$ make imx8mm_beacon_defconfig +$ make flash.bin ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF_LOAD_ADDR=0x920000 + +Burn U-Boot to microSD Card +=========================== +$ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33 + +Boot +==== +Set Boot switch to SD boot diff --git a/board/beacon/imx8mm/imx8mm_beacon.c b/board/beacon/imx8mm/imx8mm_beacon.c new file mode 100644 index 00000000000..e82e8b78d80 --- /dev/null +++ b/board/beacon/imx8mm/imx8mm_beacon.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 Compass Electronics Group, LLC + */ + +#include +#include +#include + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + /* rom_pointer[1] contains the size of TEE occupies */ + if (rom_pointer[1]) + gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1]; + else + gd->ram_size = PHYS_SDRAM_SIZE; + + return 0; +} + +#if IS_ENABLED(CONFIG_FEC_MXC) +static int setup_fec(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + /* Use 125M anatop REF_CLK1 for ENET1, not from external */ + clrsetbits_le32(&gpr->gpr[1], 0x2000, 0); + + return 0; +} + +int board_phy_config(struct phy_device *phydev) +{ + /* enable rgmii rxc skew and phy mode select to RGMII copper */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + return 0; +} +#endif + +int board_init(void) +{ + if (IS_ENABLED(CONFIG_FEC_MXC)) + setup_fec(); + + return 0; +} + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} diff --git a/board/beacon/imx8mm/lpddr4_timing.c b/board/beacon/imx8mm/lpddr4_timing.c new file mode 100644 index 00000000000..8e48b9d81b7 --- /dev/null +++ b/board/beacon/imx8mm/lpddr4_timing.c @@ -0,0 +1,1980 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 NXP + */ + +#include +#include +#include +#include + +struct dram_cfg_param lpddr4_ddrc_cfg[] = { + /* Start to config, default 3200mbps */ + { DDRC_DBG1(0), 0x00000001 }, + { DDRC_PWRCTL(0), 0x00000001 }, + { DDRC_MSTR(0), 0xa1080020 }, + { DDRC_RFSHTMG(0), 0x005b00d2 }, + { DDRC_INIT0(0), 0xC003061B }, + { DDRC_INIT1(0), 0x009D0000 }, + { DDRC_INIT3(0), 0x00D4002D }, + { DDRC_INIT4(0), (LPDDR4_MR3 << 16) | 0x0000 }, + { DDRC_INIT6(0), 0x0066004a }, + { DDRC_INIT7(0), 0x0006004a }, + + { DDRC_DRAMTMG0(0), 0x1A201B22 }, + { DDRC_DRAMTMG1(0), 0x00060633 }, + { DDRC_DRAMTMG3(0), 0x00C0C000 }, + { DDRC_DRAMTMG4(0), 0x0F04080F }, + { DDRC_DRAMTMG5(0), 0x02040C0C }, + { DDRC_DRAMTMG6(0), 0x01010007 }, + { DDRC_DRAMTMG7(0), 0x00000401 }, + { DDRC_DRAMTMG12(0), 0x00020600 }, + { DDRC_DRAMTMG13(0), 0x0C100002 }, + { DDRC_DRAMTMG14(0), 0x000000E6 }, + { DDRC_DRAMTMG17(0), 0x00A00050 }, + + { DDRC_ZQCTL0(0), 0x03200018 }, + { DDRC_ZQCTL1(0), 0x028061A8 }, + { DDRC_ZQCTL2(0), 0x00000000 }, + + { DDRC_DFITMG0(0), 0x0497820A }, + { DDRC_DFITMG2(0), 0x0000170A }, + { DDRC_DRAMTMG2(0), 0x070E171a }, + { DDRC_DBICTL(0), 0x00000001 }, + + { DDRC_DFITMG1(0), 0x00080303 }, + { DDRC_DFIUPD0(0), 0xE0400018 }, + { DDRC_DFIUPD1(0), 0x00DF00E4 }, + { DDRC_DFIUPD2(0), 0x80000000 }, + { DDRC_DFIMISC(0), 0x00000011 }, + + { DDRC_DFIPHYMSTR(0), 0x00000000 }, + { DDRC_RANKCTL(0), 0x00000c99 }, + + /* address mapping */ + { DDRC_ADDRMAP0(0), 0x0000001f }, + { DDRC_ADDRMAP1(0), 0x00080808 }, + { DDRC_ADDRMAP2(0), 0x00000000 }, + { DDRC_ADDRMAP3(0), 0x00000000 }, + { DDRC_ADDRMAP4(0), 0x00001f1f }, + { DDRC_ADDRMAP5(0), 0x07070707 }, + { DDRC_ADDRMAP6(0), 0x07070707 }, + { DDRC_ADDRMAP7(0), 0x00000f0f }, + + /* performance setting */ + { DDRC_SCHED(0), 0x29001701 }, + { DDRC_SCHED1(0), 0x0000002c }, + { DDRC_PERFHPR1(0), 0x04000030 }, + { DDRC_PERFLPR1(0), 0x900093e7 }, + { DDRC_PERFWR1(0), 0x20005574 }, + { DDRC_PCCFG(0), 0x00000111 }, + { DDRC_PCFGW_0(0), 0x000072ff }, + { DDRC_PCFGQOS0_0(0), 0x02100e07 }, + { DDRC_PCFGQOS1_0(0), 0x00620096 }, + { DDRC_PCFGWQOS0_0(0), 0x01100e07 }, + { DDRC_PCFGWQOS1_0(0), 0x00c8012c }, + + /* frequency P1&P2 */ + /* Frequency 1: 400mbps */ + { DDRC_FREQ1_DRAMTMG0(0), 0x0d0b010c }, + { DDRC_FREQ1_DRAMTMG1(0), 0x00030410 }, + { DDRC_FREQ1_DRAMTMG2(0), 0x0203090c }, + { DDRC_FREQ1_DRAMTMG3(0), 0x00505006 }, + { DDRC_FREQ1_DRAMTMG4(0), 0x05040305 }, + { DDRC_FREQ1_DRAMTMG5(0), 0x0d0e0504 }, + { DDRC_FREQ1_DRAMTMG6(0), 0x0a060004 }, + { DDRC_FREQ1_DRAMTMG7(0), 0x0000090e }, + { DDRC_FREQ1_DRAMTMG14(0), 0x00000032 }, + { DDRC_FREQ1_DRAMTMG15(0), 0x00000000 }, + { DDRC_FREQ1_DRAMTMG17(0), 0x0036001b }, + { DDRC_FREQ1_DERATEINT(0), 0x7e9fbeb1 }, + { DDRC_FREQ1_DFITMG0(0), 0x03818200 }, + { DDRC_FREQ1_DFITMG2(0), 0x00000000 }, + { DDRC_FREQ1_RFSHTMG(0), 0x000C001c }, + { DDRC_FREQ1_INIT3(0), 0x00840000 }, + { DDRC_FREQ1_INIT4(0), 0x00310000 }, + { DDRC_FREQ1_INIT6(0), 0x0066004a }, + { DDRC_FREQ1_INIT7(0), 0x0006004a }, + + /* Frequency 2: 100mbps */ + { DDRC_FREQ2_DRAMTMG0(0), 0x0d0b010c }, + { DDRC_FREQ2_DRAMTMG1(0), 0x00030410 }, + { DDRC_FREQ2_DRAMTMG2(0), 0x0203090c }, + { DDRC_FREQ2_DRAMTMG3(0), 0x00505006 }, + { DDRC_FREQ2_DRAMTMG4(0), 0x05040305 }, + { DDRC_FREQ2_DRAMTMG5(0), 0x0d0e0504 }, + { DDRC_FREQ2_DRAMTMG6(0), 0x0a060004 }, + { DDRC_FREQ2_DRAMTMG7(0), 0x0000090e }, + { DDRC_FREQ2_DRAMTMG14(0), 0x00000032 }, + { DDRC_FREQ2_DRAMTMG17(0), 0x0036001b }, + { DDRC_FREQ2_DERATEINT(0), 0x7e9fbeb1 }, + { DDRC_FREQ2_DFITMG0(0), 0x03818200 }, + { DDRC_FREQ2_DFITMG2(0), 0x00000000 }, + { DDRC_FREQ2_RFSHTMG(0), 0x0003800c }, + { DDRC_FREQ2_RFSHTMG(0), 0x00030007 }, + { DDRC_FREQ2_INIT3(0), 0x00840000 }, + { DDRC_FREQ2_INIT4(0), 0x00310008 }, + { DDRC_FREQ2_INIT4(0), (LPDDR4_MR3 << 16) | 0x0000 }, + { DDRC_FREQ2_INIT6(0), 0x0066004a }, + { DDRC_FREQ2_INIT7(0), 0x0006004a }, + + /* boot start point */ + { DDRC_MSTR2(0), 0x2 }, //DDRC_MSTR2 +}; + +/* PHY Initialize Configuration */ +struct dram_cfg_param lpddr4_ddrphy_cfg[] = { + { 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, 0x19 }, + { 0x1200c5, 0x7 }, + { 0x2200c5, 0x7 }, + + { 0x2002e, 0x2 }, + { 0x12002e, 0x2 }, + { 0x22002e, 0x2 }, + + { 0x90204, 0x0 }, + { 0x190204, 0x0 }, + { 0x290204, 0x0 }, + + { 0x20024, 0xab }, + { 0x2003a, 0x0 }, + + { 0x120024, 0xab }, + { 0x2003a, 0x0 }, + + { 0x220024, 0xab }, + { 0x2003a, 0x0 }, + + { 0x20056, 0x3 }, + { 0x120056, 0xa }, + { 0x220056, 0xa }, + + { 0x1004d, 0xe00 }, + { 0x1014d, 0xe00 }, + { 0x1104d, 0xe00 }, + { 0x1114d, 0xe00 }, + { 0x1204d, 0xe00 }, + { 0x1214d, 0xe00 }, + { 0x1304d, 0xe00 }, + { 0x1314d, 0xe00 }, + + { 0x11004d, 0xe00 }, + { 0x11014d, 0xe00 }, + { 0x11104d, 0xe00 }, + { 0x11114d, 0xe00 }, + { 0x11204d, 0xe00 }, + { 0x11214d, 0xe00 }, + { 0x11304d, 0xe00 }, + { 0x11314d, 0xe00 }, + + { 0x21004d, 0xe00 }, + { 0x21014d, 0xe00 }, + { 0x21104d, 0xe00 }, + { 0x21114d, 0xe00 }, + { 0x21204d, 0xe00 }, + { 0x21214d, 0xe00 }, + { 0x21304d, 0xe00 }, + { 0x21314d, 0xe00 }, + + { 0x10049, 0xfbe }, + { 0x10149, 0xfbe }, + { 0x11049, 0xfbe }, + { 0x11149, 0xfbe }, + { 0x12049, 0xfbe }, + { 0x12149, 0xfbe }, + { 0x13049, 0xfbe }, + { 0x13149, 0xfbe }, + + { 0x110049, 0xfbe }, + { 0x110149, 0xfbe }, + { 0x111049, 0xfbe }, + { 0x111149, 0xfbe }, + { 0x112049, 0xfbe }, + { 0x112149, 0xfbe }, + { 0x113049, 0xfbe }, + { 0x113149, 0xfbe }, + + { 0x210049, 0xfbe }, + { 0x210149, 0xfbe }, + { 0x211049, 0xfbe }, + { 0x211149, 0xfbe }, + { 0x212049, 0xfbe }, + { 0x212149, 0xfbe }, + { 0x213049, 0xfbe }, + { 0x213149, 0xfbe }, + + { 0x43, 0x63 }, + { 0x1043, 0x63 }, + { 0x2043, 0x63 }, + { 0x3043, 0x63 }, + { 0x4043, 0x63 }, + { 0x5043, 0x63 }, + { 0x6043, 0x63 }, + { 0x7043, 0x63 }, + { 0x8043, 0x63 }, + { 0x9043, 0x63 }, + + { 0x20018, 0x3 }, + { 0x20075, 0x4 }, + { 0x20050, 0x0 }, + { 0x20008, 0x2ee }, + { 0x120008, 0x64 }, + { 0x220008, 0x19 }, + { 0x20088, 0x9 }, + + { 0x200b2, 0x1d4 }, + { 0x10043, 0x5a1 }, + { 0x10143, 0x5a1 }, + { 0x11043, 0x5a1 }, + { 0x11143, 0x5a1 }, + { 0x12043, 0x5a1 }, + { 0x12143, 0x5a1 }, + { 0x13043, 0x5a1 }, + { 0x13143, 0x5a1 }, + + { 0x1200b2, 0xdc }, + { 0x110043, 0x5a1 }, + { 0x110143, 0x5a1 }, + { 0x111043, 0x5a1 }, + { 0x111143, 0x5a1 }, + { 0x112043, 0x5a1 }, + { 0x112143, 0x5a1 }, + { 0x113043, 0x5a1 }, + { 0x113143, 0x5a1 }, + + { 0x2200b2, 0xdc }, + { 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, LPDDR4_PHY_DMIPinPresent }, + { 0x12002d, LPDDR4_PHY_DMIPinPresent }, + { 0x22002d, LPDDR4_PHY_DMIPinPresent }, + { 0x200c7, 0x21 }, + { 0x200ca, 0x24 }, + { 0x1200c7, 0x21 }, + { 0x1200ca, 0x24 }, + { 0x2200c7, 0x21 }, + { 0x2200ca, 0x24 }, +}; + +/* ddr phy trained csr */ +struct dram_cfg_param lpddr4_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 */ +struct dram_cfg_param lpddr4_fsp0_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xbb8 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) },//PHY Ron/Rtt + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x131f }, + { 0x54009, 0xc8 }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, 0x0 }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, (LPDDR4_CS << 8) | (0x110 & 0xff) }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x2dd4 }, + { 0x5401a, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x5401b, 0x4d66 }, + { 0x5401c, 0x4d08 }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0/*0x16*/ }, + { 0x5401f, 0x2dd4 }, + { 0x54020, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x54021, 0x4d66 }, + { 0x54022, 0x4d08 }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1/*0x16*/ }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, LPDDR4_CS }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0xd400 }, + { 0x54033, (LPDDR4_MR3 << 8) | (0x312d & 0xff) }, + { 0x54034, 0x6600 }, + { 0x54035, 0x84d }, + { 0x54036, 0x4d }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8)/*0x1600*/ }, + { 0x54038, 0xd400 }, + { 0x54039, (LPDDR4_MR3 << 8) | (0x312d & 0xff) }, + { 0x5403a, 0x6600 }, + { 0x5403b, 0x84d }, + { 0x5403c, 0x4d }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8)/*0x1600*/ }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P1 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp1_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x101 }, + { 0x54003, 0x190 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) },/* PHY Ron/Rtt */ + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x121f }, + { 0x54009, 0xc8 }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, 0x0 }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, (LPDDR4_CS << 8) | (0x110 & 0xff) }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x84 }, + { 0x5401a, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x5401b, 0x4d66 }, + { 0x5401c, 0x4d08 }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0/*0x16*/ }, + { 0x5401f, 0x84 }, + { 0x54020, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x54021, 0x4d66 }, + { 0x54022, 0x4d08 }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1/*0x16*/ }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, LPDDR4_CS }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0x8400 }, + { 0x54033, (LPDDR4_MR3 << 8) | (0x3100 & 0xff) }, + { 0x54034, 0x6600 }, + { 0x54035, 0x84d }, + { 0x54036, 0x4d }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8)/*0x1600*/ }, + { 0x54038, 0x8400 }, + { 0x54039, (LPDDR4_MR3 << 8) | (0x3100 & 0xff) }, + { 0x5403a, 0x6600 }, + { 0x5403b, 0x84d }, + { 0x5403c, 0x4d }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8)/*0x1600*/ }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P1 message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp2_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x102 }, + { 0x54003, 0x64 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) },//PHY Ron/Rtt + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x121f }, + { 0x54009, 0xc8 }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, 0x0 }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x0 }, + { 0x54010, 0x0 }, + { 0x54011, 0x0 }, + { 0x54012, (LPDDR4_CS << 8) | (0x110 & 0xff) }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x84 }, + { 0x5401a, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x5401b, 0x4d66 }, + { 0x5401c, 0x4d08 }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0/*0x16*/ }, + { 0x5401f, 0x84 }, + { 0x54020, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x54021, 0x4d66 }, + { 0x54022, 0x4d08 }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1/*0x16*/ }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, LPDDR4_CS }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0x8400 }, + { 0x54033, (LPDDR4_MR3 << 8) | (0x3100 & 0xff) }, + { 0x54034, 0x6600 }, + { 0x54035, 0x84d }, + { 0x54036, 0x4d }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8)/*0x1600*/ }, + { 0x54038, 0x8400 }, + { 0x54039, (LPDDR4_MR3 << 8) | (0x3100 & 0xff) }, + { 0x5403a, 0x6600 }, + { 0x5403b, 0x84d }, + { 0x5403c, 0x4d }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8)/*0x1600*/ }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* P0 2D message block paremeter for training firmware */ +struct dram_cfg_param lpddr4_fsp0_2d_cfg[] = { + { 0xd0000, 0x0 }, + { 0x54000, 0x0 }, + { 0x54001, 0x0 }, + { 0x54002, 0x0 }, + { 0x54003, 0xbb8 }, + { 0x54004, 0x2 }, + { 0x54005, ((LPDDR4_PHY_RON << 8) | LPDDR4_PHY_RTT) },//PHY Ron/Rtt + { 0x54006, LPDDR4_PHY_VREF_VALUE }, + { 0x54007, 0x0 }, + { 0x54008, 0x61 }, + { 0x54009, 0xc8 }, + { 0x5400a, 0x0 }, + { 0x5400b, 0x2 }, + { 0x5400c, 0x0 }, + { 0x5400d, 0x0 }, + { 0x5400e, 0x0 }, + { 0x5400f, 0x100 }, + { 0x54010, 0x1f7f }, + { 0x54011, 0x0 }, + { 0x54012, (LPDDR4_CS << 8) | (0x110 & 0xff) }, + { 0x54013, 0x0 }, + { 0x54014, 0x0 }, + { 0x54015, 0x0 }, + { 0x54016, 0x0 }, + { 0x54017, 0x0 }, + { 0x54018, 0x0 }, + { 0x54019, 0x2dd4 }, + { 0x5401a, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x5401b, 0x4d66 }, + { 0x5401c, 0x4d08 }, + { 0x5401d, 0x0 }, + { 0x5401e, LPDDR4_MR22_RANK0/*0x16*/ }, + { 0x5401f, 0x2dd4 }, + { 0x54020, (0x31 & 0xff00) | LPDDR4_MR3 }, + { 0x54021, 0x4d66 }, + { 0x54022, 0x4d08 }, + { 0x54023, 0x0 }, + { 0x54024, LPDDR4_MR22_RANK1/*0x16*/ }, + { 0x54025, 0x0 }, + { 0x54026, 0x0 }, + { 0x54027, 0x0 }, + { 0x54028, 0x0 }, + { 0x54029, 0x0 }, + { 0x5402a, 0x0 }, + { 0x5402b, 0x1000 }, + { 0x5402c, LPDDR4_CS }, + { 0x5402d, 0x0 }, + { 0x5402e, 0x0 }, + { 0x5402f, 0x0 }, + { 0x54030, 0x0 }, + { 0x54031, 0x0 }, + { 0x54032, 0xd400 }, + { 0x54033, (LPDDR4_MR3 << 8) | (0x312d & 0xff) }, + { 0x54034, 0x6600 }, + { 0x54035, 0x84d }, + { 0x54036, 0x4d }, + { 0x54037, (LPDDR4_MR22_RANK0 << 8)/*0x1600*/ }, + { 0x54038, 0xd400 }, + { 0x54039, (LPDDR4_MR3 << 8) | (0x312d & 0xff) }, + { 0x5403a, 0x6600 }, + { 0x5403b, 0x84d }, + { 0x5403c, 0x4d }, + { 0x5403d, (LPDDR4_MR22_RANK1 << 8)/*0x1600*/ }, + { 0x5403e, 0x0 }, + { 0x5403f, 0x0 }, + { 0x54040, 0x0 }, + { 0x54041, 0x0 }, + { 0x54042, 0x0 }, + { 0x54043, 0x0 }, + { 0x54044, 0x0 }, + { 0xd0000, 0x1 }, +}; + +/* DRAM PHY init engine image */ +struct dram_cfg_param lpddr4_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, 0xf }, + { 0x90039, 0x7c0 }, + { 0x9003a, 0x139 }, + { 0x9003b, 0x44 }, + { 0x9003c, 0x630 }, + { 0x9003d, 0x159 }, + { 0x9003e, 0x14f }, + { 0x9003f, 0x630 }, + { 0x90040, 0x159 }, + { 0x90041, 0x47 }, + { 0x90042, 0x630 }, + { 0x90043, 0x149 }, + { 0x90044, 0x4f }, + { 0x90045, 0x630 }, + { 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, 0x630 }, + { 0x90058, 0x179 }, + { 0x90059, 0x1 }, + { 0x9005a, 0x618 }, + { 0x9005b, 0x109 }, + { 0x9005c, 0x40c0 }, + { 0x9005d, 0x630 }, + { 0x9005e, 0x149 }, + { 0x9005f, 0x8 }, + { 0x90060, 0x4 }, + { 0x90061, 0x48 }, + { 0x90062, 0x4040 }, + { 0x90063, 0x630 }, + { 0x90064, 0x149 }, + { 0x90065, 0x0 }, + { 0x90066, 0x4 }, + { 0x90067, 0x48 }, + { 0x90068, 0x40 }, + { 0x90069, 0x630 }, + { 0x9006a, 0x149 }, + { 0x9006b, 0x10 }, + { 0x9006c, 0x4 }, + { 0x9006d, 0x18 }, + { 0x9006e, 0x0 }, + { 0x9006f, 0x4 }, + { 0x90070, 0x78 }, + { 0x90071, 0x549 }, + { 0x90072, 0x630 }, + { 0x90073, 0x159 }, + { 0x90074, 0xd49 }, + { 0x90075, 0x630 }, + { 0x90076, 0x159 }, + { 0x90077, 0x94a }, + { 0x90078, 0x630 }, + { 0x90079, 0x159 }, + { 0x9007a, 0x441 }, + { 0x9007b, 0x630 }, + { 0x9007c, 0x149 }, + { 0x9007d, 0x42 }, + { 0x9007e, 0x630 }, + { 0x9007f, 0x149 }, + { 0x90080, 0x1 }, + { 0x90081, 0x630 }, + { 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, 0xa }, + { 0x9009c, 0x10 }, + { 0x9009d, 0x109 }, + { 0x9009e, 0x2 }, + { 0x9009f, 0x10 }, + { 0x900a0, 0x109 }, + { 0x900a1, 0x5 }, + { 0x900a2, 0x7c0 }, + { 0x900a3, 0x109 }, + { 0x900a4, 0x10 }, + { 0x900a5, 0x10 }, + { 0x900a6, 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, 0x623 }, + { 0x4002b, 0x15 }, + { 0x4004b, 0x0 }, + { 0x4006b, 0x0 }, + { 0x4000c, 0x4028 }, + { 0x4002c, 0x80 }, + { 0x4004c, 0x0 }, + { 0x4006c, 0x0 }, + { 0x4000d, 0xe08 }, + { 0x4002d, 0xc1a }, + { 0x4004d, 0x0 }, + { 0x4006d, 0x0 }, + { 0x4000e, 0x623 }, + { 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 }, + { 0x900a7, 0x0 }, + { 0x900a8, 0x790 }, + { 0x900a9, 0x11a }, + { 0x900aa, 0x8 }, + { 0x900ab, 0x7aa }, + { 0x900ac, 0x2a }, + { 0x900ad, 0x10 }, + { 0x900ae, 0x7b2 }, + { 0x900af, 0x2a }, + { 0x900b0, 0x0 }, + { 0x900b1, 0x7c8 }, + { 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, 0x0 }, + { 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, 0xc }, + { 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, 0x0 }, + { 0x90159, 0x400 }, + { 0x9015a, 0x10e }, + { 0x9015b, 0x8 }, + { 0x9015c, 0xe8 }, + { 0x9015d, 0x109 }, + { 0x9015e, 0x0 }, + { 0x9015f, 0x8140 }, + { 0x90160, 0x10c }, + { 0x90161, 0x10 }, + { 0x90162, 0x8138 }, + { 0x90163, 0x10c }, + { 0x90164, 0x8 }, + { 0x90165, 0x7c8 }, + { 0x90166, 0x101 }, + { 0x90167, 0x8 }, + { 0x90168, 0x0 }, + { 0x90169, 0x8 }, + { 0x9016a, 0x8 }, + { 0x9016b, 0x448 }, + { 0x9016c, 0x109 }, + { 0x9016d, 0xf }, + { 0x9016e, 0x7c0 }, + { 0x9016f, 0x109 }, + { 0x90170, 0x0 }, + { 0x90171, 0xe8 }, + { 0x90172, 0x109 }, + { 0x90173, 0x47 }, + { 0x90174, 0x630 }, + { 0x90175, 0x109 }, + { 0x90176, 0x8 }, + { 0x90177, 0x618 }, + { 0x90178, 0x109 }, + { 0x90179, 0x8 }, + { 0x9017a, 0xe0 }, + { 0x9017b, 0x109 }, + { 0x9017c, 0x0 }, + { 0x9017d, 0x7c8 }, + { 0x9017e, 0x109 }, + { 0x9017f, 0x8 }, + { 0x90180, 0x8140 }, + { 0x90181, 0x10c }, + { 0x90182, 0x0 }, + { 0x90183, 0x1 }, + { 0x90184, 0x8 }, + { 0x90185, 0x8 }, + { 0x90186, 0x4 }, + { 0x90187, 0x8 }, + { 0x90188, 0x8 }, + { 0x90189, 0x7c8 }, + { 0x9018a, 0x101 }, + { 0x90006, 0x0 }, + { 0x90007, 0x0 }, + { 0x90008, 0x8 }, + { 0x90009, 0x0 }, + { 0x9000a, 0x0 }, + { 0x9000b, 0x0 }, + { 0xd00e7, 0x400 }, + { 0x90017, 0x0 }, + { 0x9001f, 0x2a }, + { 0x90026, 0x6a }, + { 0x400d0, 0x0 }, + { 0x400d1, 0x101 }, + { 0x400d2, 0x105 }, + { 0x400d3, 0x107 }, + { 0x400d4, 0x10f }, + { 0x400d5, 0x202 }, + { 0x400d6, 0x20a }, + { 0x400d7, 0x20b }, + { 0x2003a, 0x2 }, + { 0x2000b, 0x5d }, + { 0x2000c, 0xbb }, + { 0x2000d, 0x753 }, + { 0x2000e, 0x2c }, + { 0x12000b, 0xc }, + { 0x12000c, 0x19 }, + { 0x12000d, 0xfa }, + { 0x12000e, 0x10 }, + { 0x22000b, 0x3 }, + { 0x22000c, 0x6 }, + { 0x22000d, 0x3e }, + { 0x22000e, 0x10 }, + { 0x9000c, 0x0 }, + { 0x9000d, 0x173 }, + { 0x9000e, 0x60 }, + { 0x9000f, 0x6110 }, + { 0x90010, 0x2152 }, + { 0x90011, 0xdfbd }, + { 0x90012, 0x60 }, + { 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 }, + { 0x2003a, 0x2 }, + { 0xc0080, 0x2 }, + { 0xd0000, 0x1 }, +}; + +struct dram_fsp_msg lpddr4_dram_fsp_msg[] = { + { + /* P0 3000mts 1D */ + .drate = 3000, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp0_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_cfg), + }, + { + /* P0 3000mts 2D */ + .drate = 3000, + .fw_type = FW_2D_IMAGE, + .fsp_cfg = lpddr4_fsp0_2d_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp0_2d_cfg), + }, + { + /* P1 400mts 1D */ + .drate = 400, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp1_cfg), + }, + { + /* P1 100mts 1D */ + .drate = 100, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = lpddr4_fsp2_cfg, + .fsp_cfg_num = ARRAY_SIZE(lpddr4_fsp2_cfg), + }, +}; + +/* lpddr4 timing config params on EVK board */ +struct dram_timing_info dram_timing = { + .ddrc_cfg = lpddr4_ddrc_cfg, + .ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg), + .ddrphy_cfg = lpddr4_ddrphy_cfg, + .ddrphy_cfg_num = ARRAY_SIZE(lpddr4_ddrphy_cfg), + .fsp_msg = lpddr4_dram_fsp_msg, + .fsp_msg_num = ARRAY_SIZE(lpddr4_dram_fsp_msg), + .ddrphy_trained_csr = lpddr4_ddrphy_trained_csr, + .ddrphy_trained_csr_num = ARRAY_SIZE(lpddr4_ddrphy_trained_csr), + .ddrphy_pie = lpddr4_phy_pie, + .ddrphy_pie_num = ARRAY_SIZE(lpddr4_phy_pie), +}; diff --git a/board/beacon/imx8mm/spl.c b/board/beacon/imx8mm/spl.c new file mode 100644 index 00000000000..35be2e89a9d --- /dev/null +++ b/board/beacon/imx8mm/spl.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int spl_board_boot_device(enum boot_device boot_dev_spl) +{ + switch (boot_dev_spl) { + case SD2_BOOT: + case MMC2_BOOT: + return BOOT_DEVICE_MMC1; + case SD3_BOOT: + case MMC3_BOOT: + return BOOT_DEVICE_MMC2; + default: + return BOOT_DEVICE_NONE; + } +} + +static void spl_dram_init(void) +{ + ddr_init(&dram_timing); +} + +void spl_board_init(void) +{ + debug("Normal Boot\n"); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif + +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) + +static iomux_v3_cfg_t const uart_pads[] = { + IMX8MM_PAD_UART2_RXD_UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + IMX8MM_PAD_UART2_TXD_UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static iomux_v3_cfg_t const wdog_pads[] = { + IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL), +}; + +int board_early_init_f(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads)); + + set_wdog_reset(wdog); + + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); + + return 0; +} + +static int power_init_board(void) +{ + struct udevice *dev; + int ret; + + ret = pmic_get("pmic@4b", &dev); + if (ret == -ENODEV) { + puts("No pmic\n"); + return 0; + } + if (ret != 0) + return ret; + + /* decrease RESET key long push time from the default 10s to 10ms */ + pmic_reg_write(dev, BD718XX_PWRONCONFIG1, 0x0); + + /* unlock the PMIC regs */ + pmic_reg_write(dev, BD718XX_REGLOCK, 0x1); + + /* increase VDD_SOC to typical value 0.85v before first DRAM access */ + pmic_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f); + + /* increase VDD_DRAM to 0.975v for 3Ghz DDR */ + pmic_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83); + + /* lock the PMIC regs */ + pmic_reg_write(dev, BD718XX_REGLOCK, 0x11); + + return 0; +} + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + arch_cpu_init(); + + init_uart_clk(1); + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + + ret = uclass_get_device_by_name(UCLASS_CLK, + "clock-controller@30380000", + &dev); + if (ret < 0) { + printf("Failed to find clock node. Check device tree\n"); + hang(); + } + + enable_tzc380(); + + power_init_board(); + + /* DDR initialization */ + spl_dram_init(); + + board_init_r(NULL, 0); +} diff --git a/configs/imx8mm_beacon_defconfig b/configs/imx8mm_beacon_defconfig new file mode 100644 index 00000000000..b935d723606 --- /dev/null +++ b/configs/imx8mm_beacon_defconfig @@ -0,0 +1,104 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8M=y +CONFIG_SYS_TEXT_BASE=0x40200000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0x400000 +CONFIG_SYS_I2C_MXC_I2C1=y +CONFIG_SYS_I2C_MXC_I2C2=y +CONFIG_SYS_I2C_MXC_I2C3=y +CONFIG_DM_GPIO=y +CONFIG_TARGET_IMX8MM_BEACON=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL=y +CONFIG_SPL_TEXT_BASE=0x7E1000 +CONFIG_FIT=y +CONFIG_FIT_EXTERNAL_OFFSET=0x3000 +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh" +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mm-lpddr4.cfg" +CONFIG_DEFAULT_FDT_FILE="imx8mm-beacon-kit.dtb" +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_WATCHDOG_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="u-boot=> " +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_CLK=y +CONFIG_CMD_FUSE=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx8mm-beacon-kit" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM=y +CONFIG_SPL_CLK_COMPOSITE_CCF=y +CONFIG_CLK_COMPOSITE_CCF=y +CONFIG_SPL_CLK_IMX8MM=y +CONFIG_CLK_IMX8MM=y +CONFIG_MXC_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_MXC=y +CONFIG_DM_MMC=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_FSL_USDHC=y +CONFIG_PHYLIB=y +CONFIG_PHY_ATHEROS=y +CONFIG_DM_ETH=y +CONFIG_PHY_GIGE=y +CONFIG_FEC_MXC=y +CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_PINCTRL_IMX8M=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_BD71837=y +CONFIG_SPL_DM_PMIC_BD71837=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_BD71837=y +CONFIG_SPL_DM_REGULATOR_BD71837=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_CONS_INDEX=2 +CONFIG_DM_SERIAL=y +# CONFIG_SPL_DM_SERIAL is not set +CONFIG_MXC_UART=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SPI_MEM=y +CONFIG_NXP_FSPI=y +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_SYSRESET_WATCHDOG=y +CONFIG_DM_THERMAL=y +# CONFIG_WATCHDOG is not set +CONFIG_IMX_WATCHDOG=y diff --git a/include/configs/imx8mm_beacon.h b/include/configs/imx8mm_beacon.h new file mode 100644 index 00000000000..21102d3c14d --- /dev/null +++ b/include/configs/imx8mm_beacon.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2020 Compass Electronics Group, LLC + */ + +#ifndef __IMX8MM_BEACON_H +#define __IMX8MM_BEACON_H + +#include +#include + +#ifdef CONFIG_SECURE_BOOT +#define CONFIG_CSF_SIZE SZ_8K +#endif + +#define CONFIG_SPL_MAX_SIZE (148 * 1024) +#define CONFIG_SYS_MONITOR_LEN SZ_512K +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 +#define CONFIG_SYS_UBOOT_BASE \ + (QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512) + +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SPL_STACK 0x920000 +#define CONFIG_SPL_BSS_START_ADDR 0x910000 +#define CONFIG_SPL_BSS_MAX_SIZE SZ_8K /* 8 KB */ +#define CONFIG_SYS_SPL_MALLOC_START 0x42200000 +#define CONFIG_SYS_SPL_MALLOC_SIZE SZ_512K /* 512 KB */ + +/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */ +#define CONFIG_MALLOC_F_ADDR 0x930000 +/* For RAW image gives a error info not panic */ +#define CONFIG_SPL_ABORT_ON_RAW_IMAGE + +#endif + +/* Initial environment variables */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "script=boot.scr\0" \ + "image=Image\0" \ + "console=ttymxc1,115200\0" \ + "fdt_addr=0x43000000\0" \ + "fdt_high=0xffffffffffffffff\0" \ + "boot_fit=try\0" \ + "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ + "initrd_addr=0x43800000\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \ + "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \ + "finduuid=part uuid mmc ${mmcdev}:2 uuid\0" \ + "mmcautodetect=yes\0" \ + "mmcargs=setenv bootargs console=${console},${baudrate}" \ + " root=PARTUUID=${uuid} rootwait rw ${mtdparts} ${optargs}\0" \ + "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr}" \ + " ${script};\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source\0" \ + "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ + "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run finduuid; " \ + "run mmcargs; " \ + "if run loadfdt; then " \ + "booti ${loadaddr} - ${fdt_addr}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "netargs=setenv bootargs console=${console} " \ + "root=/dev/nfs " \ + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \ + "netboot=echo Booting from net ...; " \ + "run netargs; " \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "${get_cmd} ${loadaddr} ${image}; " \ + "if test ${boot_fit} = yes || test ${boot_fit} = try; then " \ + "bootm ${loadaddr}; " \ + "else " \ + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ + "booti ${loadaddr} - ${fdt_addr}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "fi;\0" + +#define CONFIG_BOOTCOMMAND \ + "mmc dev ${mmcdev}; if mmc rescan; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "fi; " \ + "fi;" + +/* Link Definitions */ +#define CONFIG_LOADADDR 0x40480000 + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 +#define CONFIG_SYS_INIT_RAM_SIZE 0x200000 +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_ENV_OVERWRITE +#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */ + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN SZ_32M + +#define CONFIG_SYS_SDRAM_BASE 0x40000000 +#define PHYS_SDRAM 0x40000000 +#define PHYS_SDRAM_SIZE 0x80000000 /* 2GB DDR */ + +#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + (PHYS_SDRAM_SIZE >> 1)) + +#define CONFIG_MXC_UART_BASE UART2_BASE_ADDR + +/* Monitor Command Prompt */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_CBSIZE 2048 +#define CONFIG_SYS_MAXARGS 64 +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + +/* USDHC */ +#define CONFIG_SYS_FSL_USDHC_NUM 2 +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 + +/* I2C */ +#define CONFIG_SYS_I2C_SPEED 100000 + +/* FEC*/ +#define CONFIG_ETHPRIME "FEC" +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_MXC_PHYADDR 0 +#define FEC_QUIRK_ENET_MAC +#define IMX_FEC_BASE 0x30BE0000 + +#endif From e6405713d88eeed90c9428552dfc87bfb4b05ca0 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 21:16:49 +0800 Subject: [PATCH 60/82] dt-bindings: imx_rsrc: add SC_R_NONE Add SC_R_NONE entry Signed-off-by: Peng Fan --- include/dt-bindings/soc/imx_rsrc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/soc/imx_rsrc.h b/include/dt-bindings/soc/imx_rsrc.h index 4870eb985b4..fb6878f6e24 100644 --- a/include/dt-bindings/soc/imx_rsrc.h +++ b/include/dt-bindings/soc/imx_rsrc.h @@ -553,5 +553,6 @@ #define SC_R_VPU_ENC_1 539 #define SC_R_VPU 540 #define SC_R_LAST 541 +#define SC_R_NONE 0xFFF0 #endif /* DT_BINDINGS_RSCRC_IMX_H */ From 8c0a1c6de84387ad6264d4ea6fa03e2214908960 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 21:16:50 +0800 Subject: [PATCH 61/82] imx8: power: Add PD device lookup interface to power domain uclass Add power_domain_lookup_name interface to power domain uclass to find a power domain device by its DTB node name, not using its associated client device. Through this interface, we can operate the power domain devices directly. This is needed for non-DM drivers. Modified from Ye's NXP downstream patch only for legacy imx8 power domain driver, since we have not migrated to use new power domain driver. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sys_proto.h | 7 +++++ .../power/domain/imx8-power-domain-legacy.c | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h index 0e981ae950e..fc33e6ed184 100644 --- a/arch/arm/include/asm/arch-imx8/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8/sys_proto.h @@ -5,6 +5,11 @@ #include #include +#include +#include +#include +#include +#include #include struct pass_over_info_t { @@ -21,3 +26,5 @@ void build_info(void); enum boot_device get_boot_device(void); int print_bootinfo(void); int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate); +int imx8_power_domain_lookup_name(const char *name, + struct power_domain *power_domain); diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index 6f01a60b346..2c479744d3f 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -19,6 +19,34 @@ struct imx8_power_domain_priv { bool state_on; }; +int imx8_power_domain_lookup_name(const char *name, + struct power_domain *power_domain) +{ + struct udevice *dev; + struct power_domain_ops *ops; + int ret; + + debug("%s(power_domain=%p name=%s)\n", __func__, power_domain, name); + + ret = uclass_get_device_by_name(UCLASS_POWER_DOMAIN, name, &dev); + if (ret) { + printf("%s fail: %s, ret = %d\n", __func__, name, ret); + return ret; + } + + ops = (struct power_domain_ops *)dev->driver->ops; + power_domain->dev = dev; + ret = ops->request(power_domain); + if (ret) { + debug("ops->request() failed: %d\n", ret); + return ret; + } + + debug("%s ok: %s\n", __func__, dev->name); + + return 0; +} + static int imx8_power_domain_request(struct power_domain *power_domain) { debug("%s(power_domain=%p)\n", __func__, power_domain); From ca0c52710c14e9d38f8e493625a3a51147ebddcc Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 21:16:51 +0800 Subject: [PATCH 62/82] power: imx8-power-domain: Set DM_FLAG_DEFAULT_PD_CTRL_OFF flag If without this flag, calling dev_power_domain_ctrl will iteratively remove the power domain device will causes iteratively power off parent PD. This is not expected by imx8-power-domain-legacy driver. Power off parent PD is controlled by the driver internally. So set DM_FLAG_DEFAULT_PD_CTRL_OFF to avoid such issue Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/power/domain/imx8-power-domain-legacy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index 2c479744d3f..e6e619358c3 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -341,4 +341,5 @@ U_BOOT_DRIVER(imx8_power_domain) = { .platdata_auto_alloc_size = sizeof(struct imx8_power_domain_platdata), .priv_auto_alloc_size = sizeof(struct imx8_power_domain_priv), .ops = &imx8_power_domain_ops, + .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; From e8f8b5ccf2b1b02f1614941d025c31cfbf78ab2b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 21:16:52 +0800 Subject: [PATCH 63/82] power: imx8: remove the resource owned check before power off For all the devices used and set ACTIVE in U-Boot, U-Boot needs to power off all of them without the check of resource owner. When we create software partition before booting Linux, the resource own checkw will return false, and cause the power domain not powered off. If without the check of resource owner, the power domain in the other software partition could be powered off with parent partition could access child partition resources. Signed-off-by: Peng Fan --- drivers/power/domain/imx8-power-domain-legacy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index e6e619358c3..b68be40766d 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -137,13 +137,13 @@ static int imx8_power_domain_off_node(struct power_domain *power_domain) } if (pdata->resource_id != SC_R_LAST) { - if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) { - printf("%s not owned by curr partition\n", dev->name); - return 0; - } ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id, SC_PM_PW_MODE_OFF); if (ret) { + if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) { + printf("%s not owned by curr partition %d\n", dev->name, pdata->resource_id); + return 0; + } printf("Error: %s Power off failed! (error = %d)\n", dev->name, ret); return -EIO; From 1074af51ec04c17a755c76fe0f76b0d53ca47af9 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Mon, 4 May 2020 21:16:53 +0800 Subject: [PATCH 64/82] power: imx8: Check owned resource in power on When fspi is assigned to M4, we have to let the fspi probe failed when its power domain is failed to power up. Because not all devices have power domain (for example, external devices on the board). Current checking resource owner in power domain probe is not good, change to check it in power on. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/power/domain/imx8-power-domain-legacy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index b68be40766d..a5f2f8a4457 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -91,6 +91,9 @@ static int imx8_power_domain_on(struct power_domain *power_domain) return 0; if (pdata->resource_id != SC_R_LAST) { + if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) + printf("%s [%d] not owned by curr partition\n", dev->name, pdata->resource_id); + ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id, SC_PM_PW_MODE_ON); if (ret) { From 6fcb2ee78337b7d8201baf23c398f5061110dd1d Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Mon, 4 May 2020 21:16:54 +0800 Subject: [PATCH 65/82] imx8: Replace SC_R_LAST with SC_R_NONE in DTB We are currently using SC_R_LAST as a marker for imx8 power domain tree nodes without a resource attached. This value is compiled into dtb as part of the linux build and used by uboot. The SC_R_LAST constant changes frequently as SCFW resources are added (by design) and every time we need to update linux and uboot headers together or boot can fail. Fix this by replacing SC_R_LAST usage with a new constant SC_R_NONE defined to be 0xFFF0. Reviewed-by: Peng Fan Signed-off-by: Leonard Crestez Signed-off-by: Peng Fan --- arch/arm/dts/fsl-imx8dx.dtsi | 6 +++--- arch/arm/dts/fsl-imx8qm.dtsi | 6 +++--- arch/arm/mach-imx/imx8/cpu.c | 1 - drivers/power/domain/imx8-power-domain-legacy.c | 6 +++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/arch/arm/dts/fsl-imx8dx.dtsi b/arch/arm/dts/fsl-imx8dx.dtsi index ae1d1f460b5..7d95cf0b7dc 100644 --- a/arch/arm/dts/fsl-imx8dx.dtsi +++ b/arch/arm/dts/fsl-imx8dx.dtsi @@ -131,7 +131,7 @@ pd_lsio: PD_LSIO { compatible = "nxp,imx8-pd"; - reg = ; + reg = ; #power-domain-cells = <0>; #address-cells = <1>; #size-cells = <0>; @@ -180,7 +180,7 @@ pd_conn: PD_CONN { compatible = "nxp,imx8-pd"; - reg = ; + reg = ; #power-domain-cells = <0>; #address-cells = <1>; #size-cells = <0>; @@ -214,7 +214,7 @@ pd_dma: PD_DMA { compatible = "nxp,imx8-pd"; - reg = ; + reg = ; #power-domain-cells = <0>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/dts/fsl-imx8qm.dtsi b/arch/arm/dts/fsl-imx8qm.dtsi index 6808f68f9d4..2e887add792 100644 --- a/arch/arm/dts/fsl-imx8qm.dtsi +++ b/arch/arm/dts/fsl-imx8qm.dtsi @@ -88,7 +88,7 @@ pd_lsio: PD_LSIO { compatible = "nxp,imx8-pd"; - reg = ; + reg = ; #power-domain-cells = <0>; #address-cells = <1>; #size-cells = <0>; @@ -137,7 +137,7 @@ pd_conn: PD_CONN { compatible = "nxp,imx8-pd"; - reg = ; + reg = ; #power-domain-cells = <0>; #address-cells = <1>; #size-cells = <0>; @@ -173,7 +173,7 @@ pd_dma: PD_DMA { compatible = "nxp,imx8-pd"; - reg = ; + reg = ; #power-domain-cells = <0>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 21103809577..f87276e8eab 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -536,4 +536,3 @@ u32 get_cpu_rev(void) return (id << 12) | rev; } - diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index a5f2f8a4457..f679df9e5d1 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -90,7 +90,7 @@ static int imx8_power_domain_on(struct power_domain *power_domain) if (ppriv->state_on) return 0; - if (pdata->resource_id != SC_R_LAST) { + if (pdata->resource_id != SC_R_NONE) { if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) printf("%s [%d] not owned by curr partition\n", dev->name, pdata->resource_id); @@ -139,7 +139,7 @@ static int imx8_power_domain_off_node(struct power_domain *power_domain) } } - if (pdata->resource_id != SC_R_LAST) { + if (pdata->resource_id != SC_R_NONE) { ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id, SC_PM_PW_MODE_OFF); if (ret) { @@ -202,7 +202,7 @@ static int imx8_power_domain_off_parentnodes(struct power_domain *power_domain) } /* power off parent */ - if (pdata->resource_id != SC_R_LAST) { + if (pdata->resource_id != SC_R_NONE) { ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id, SC_PM_PW_MODE_OFF); From c6ed3508bda58ab4a750eb11956f7779cc27e84d Mon Sep 17 00:00:00 2001 From: Han Xu Date: Tue, 5 May 2020 22:03:59 +0800 Subject: [PATCH 66/82] nandbcb: fix the issue cannot support gf_14 NAND boot bchtype in FCB should be associated to the gf_13/14 settings in BCH, fix the issue and test on Micron 29F64G08CBABB, it can boot after the change. Signed-off-by: Han Xu Signed-off-by: Peng Fan --- arch/arm/mach-imx/cmd_nandbcb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index b3e59b1b003..103c3d6a087 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -154,6 +154,7 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, fcb->ecc_level = l.ecc0; fcb->ecc_size = l.datan_size; fcb->ecc_type = l.eccn; + fcb->bchtype = l.gf_len; /* Also hardcoded in kobs-ng */ if (is_mx6()) { From 66dbd9c9ede2a1b109b008b7063e9901d2cea07f Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Tue, 5 May 2020 22:04:00 +0800 Subject: [PATCH 67/82] nandbcb: support i.MX8M Tested on i.MX8MM EVK, imx8mm evk uses BCH encoding and randomizer modify macro and print size_t with %zx use CONFIG_IMX8M because it should apply to imx8mq/mm/mn Signed-off-by: Alice Guo Signed-off-by: Peng Fan --- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/cmd_nandbcb.c | 88 +++++++++++++++++++++++++-------- 2 files changed, 68 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 396f7c92887..bed8cc7e886 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -89,7 +89,7 @@ config CMD_NANDBCB bool "i.MX6 NAND Boot Control Block(BCB) command" depends on MTD_RAW_NAND && CMD_MTDPARTS select BCH if MX6UL || MX6ULL - default y if (ARCH_MX6 && NAND_MXS) || (ARCH_MX7 && NAND_MXS) + default y if ((ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M) && NAND_MXS) help Unlike normal 'nand write/erase' commands, this command update Boot Control Block(BCB) for i.MX6 platform NAND IP's. diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 103c3d6a087..682f5064e6d 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -30,6 +30,8 @@ #define BF_VAL(v, bf) (((v) & bf##_MASK) >> bf##_OFFSET) #define GETBIT(v, n) (((v) >> (n)) & 0x1) +#define IMX8MQ_SPL_SZ 0x3e000 +#define IMX8MQ_HDMI_FW_SZ 0x19c00 #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) static uint8_t reverse_bit(uint8_t b) @@ -157,7 +159,7 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, fcb->bchtype = l.gf_len; /* Also hardcoded in kobs-ng */ - if (is_mx6()) { + if (is_mx6() || is_imx8m()) { fcb->datasetup = 80; fcb->datahold = 60; fcb->addr_setup = 25; @@ -260,11 +262,11 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, /* * User BCH ECC hardware module for i.MX7 */ - if (is_mx7()) { + if (is_mx7() || is_imx8m()) { u32 off = i * mtd->erasesize; size_t rwsize = sizeof(*fcb); - printf("Writing %d bytes to 0x%x: ", rwsize, off); + printf("Writing %zd bytes to 0x%x: ", rwsize, off); /* switch nand BCH to FCB compatible settings */ mxs_nand_mode_fcb(mtd); @@ -287,7 +289,7 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); if (ret) goto fcb_raw_page_err; - debug("NAND fcb write: 0x%x offset 0x%x written: %s\n", + debug("NAND fcb write: 0x%x offset 0x%zx written: %s\n", mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK"); } @@ -296,7 +298,7 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, mtd->writesize, &dummy, (void *)dbbt); if (ret) goto fcb_raw_page_err; - debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", + debug("NAND dbbt write: 0x%x offset, 0x%zx bytes written: %s\n", mtd->erasesize * i + mtd->writesize, dummy, ret ? "ERROR" : "OK"); @@ -330,6 +332,9 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, int nr_blks, nr_blks_fcb, fw1_blk; size_t fwsize; int ret; + size_t extra_fwsize; + void *extra_fwbuf; + loff_t extra_fw1_off; /* erase */ memset(&opts, 0, sizeof(opts)); @@ -366,23 +371,62 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, fw1_blk = nr_blks_fcb; /* write fw */ - fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize, - mtd->writesize); - fwbuf = kzalloc(fwsize, GFP_KERNEL); - if (!fwbuf) { - debug("failed to allocate fwbuf\n"); - ret = -ENOMEM; - goto err; - } + fwbuf = NULL; + if (is_mx6() || is_mx7()) { + fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize, + mtd->writesize); + fwbuf = kzalloc(fwsize, GFP_KERNEL); + if (!fwbuf) { + debug("failed to allocate fwbuf\n"); + ret = -ENOMEM; + goto err; + } - memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size); - fw1_off = fw1_blk * mtd->erasesize; - ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize, - (u_char *)fwbuf, WITH_WR_VERIFY); - printf("NAND fw write: 0x%llx offset, 0x%x bytes written: %s\n", - fw1_off, fwsize, ret ? "ERROR" : "OK"); - if (ret) - goto fwbuf_err; + memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size); + fw1_off = fw1_blk * mtd->erasesize; + ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize, + (u_char *)fwbuf, WITH_WR_VERIFY); + printf("NAND fw write: 0x%llx offset, 0x%zx bytes written: %s\n", + fw1_off, fwsize, ret ? "ERROR" : "OK"); + if (ret) + goto fwbuf_err; + } else if (is_imx8m()) { + fwsize = ALIGN(IMX8MQ_SPL_SZ + FLASH_OFFSET_STANDARD + mtd->writesize, mtd->writesize); + fwbuf = kzalloc(fwsize, GFP_KERNEL); + if (!fwbuf) { + printf("failed to allocate fwbuf\n"); + ret = -ENOMEM; + goto err; + } + + memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, IMX8MQ_SPL_SZ); + fw1_off = fw1_blk * mtd->erasesize; + ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize, + (u_char *)fwbuf, WITH_WR_VERIFY); + printf("NAND fw write: 0x%llx offset, 0x%zx bytes written: %s\n", + fw1_off, fwsize, ret ? "ERROR" : "OK"); + if (ret) + goto fwbuf_err; + + extra_fwsize = ALIGN(IMX8MQ_SPL_SZ + mtd->writesize, mtd->writesize); + extra_fwbuf = kzalloc(extra_fwsize, GFP_KERNEL); + extra_fw1_off = fw1_off + mtd->erasesize * ((IMX8MQ_SPL_SZ + mtd->erasesize - 1) / mtd->erasesize); + if (!extra_fwbuf) { + printf("failed to allocate fwbuf\n"); + ret = -ENOMEM; + goto fwbuf_err; + } + + memcpy(extra_fwbuf, buf + IMX8MQ_HDMI_FW_SZ, IMX8MQ_SPL_SZ); + ret = nand_write_skip_bad(mtd, extra_fw1_off, &extra_fwsize, NULL, maxsize, + (u_char *)extra_fwbuf, WITH_WR_VERIFY); + printf("NAND extra_fw write: 0x%llx offset, 0x%zx bytes written: %s\n", + extra_fw1_off, extra_fwsize, ret ? "ERROR" : "OK"); + if (ret) { + kfree(extra_fwbuf); + goto fwbuf_err; + } + } /* fill fcb */ fcb = kzalloc(sizeof(*fcb), GFP_KERNEL); @@ -394,6 +438,8 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; fw1_pages = size / mtd->writesize + 1; + if (is_imx8m()) + fw1_pages = (IMX8MQ_SPL_SZ + (mtd->writesize - 1)) / mtd->writesize; fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages); /* fill dbbt */ From 0b10337b219a2cac47a4a021c4739f6e8c48e692 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Tue, 5 May 2020 22:04:01 +0800 Subject: [PATCH 68/82] nandbcb: add nandbcb dump command for i.MX8MM Verify/dump boot structures written to NAND Flash chip. Signed-off-by: Alice Guo Signed-off-by: Peng Fan --- arch/arm/mach-imx/cmd_nandbcb.c | 266 +++++++++++++++++++++++++++++++- 1 file changed, 258 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 682f5064e6d..02a65ffd438 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "../../../cmd/legacy-mtd-utils.h" @@ -32,6 +33,16 @@ #define GETBIT(v, n) (((v) >> (n)) & 0x1) #define IMX8MQ_SPL_SZ 0x3e000 #define IMX8MQ_HDMI_FW_SZ 0x19c00 +#define BOOT_SEARCH_COUNT 2 + +struct mtd_info *dump_mtd; +static loff_t dump_nandboot_size; +static struct fcb_block dump_fill_fcb; +static struct dbbt_block dump_fill_dbbt; +static struct fcb_block dump_nand_fcb[BOOT_SEARCH_COUNT]; +static struct dbbt_block dump_nand_dbbt[BOOT_SEARCH_COUNT]; +static u32 dump_fcb_off[BOOT_SEARCH_COUNT]; +static u32 dump_dbbt_off[BOOT_SEARCH_COUNT]; #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) static uint8_t reverse_bit(uint8_t b) @@ -212,9 +223,10 @@ static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks) return n_bad_blocks; } -static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, - struct dbbt_block *dbbt, void *dbbt_data_page, - loff_t off) +static int write_fcb_dbbt_and_readback(struct mtd_info *mtd, + struct fcb_block *fcb, + struct dbbt_block *dbbt, + void *dbbt_data_page, loff_t off) { void *fcb_raw_page = 0; int i, ret; @@ -272,6 +284,11 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, mxs_nand_mode_fcb(mtd); ret = nand_write(mtd, off, &rwsize, (unsigned char *)fcb); + + dump_fcb_off[i] = off; + nand_read(mtd, off, &rwsize, + (unsigned char *)(dump_nand_fcb + i)); + mxs_nand_mode_normal(mtd); printf("%s\n", ret ? "ERROR" : "OK"); @@ -302,6 +319,12 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, mtd->erasesize * i + mtd->writesize, dummy, ret ? "ERROR" : "OK"); + dump_dbbt_off[i] = mtd->erasesize * i + mtd->writesize; + size_t rwsize = sizeof(*dbbt); + + nand_read(mtd, dump_dbbt_off[i], &rwsize, + (unsigned char *)(dump_nand_dbbt + i)); + /* dbbtpages == 0 if no bad blocks */ if (dbbt->dbbtpages > 0) { loff_t to = (mtd->erasesize * i + mtd->writesize * 5); @@ -366,7 +389,7 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, * - rest split in half for primary and secondary firmware * - same firmware will write two times */ - nr_blks_fcb = 2; + nr_blks_fcb = BOOT_SEARCH_COUNT; nr_blks = maxsize / mtd->erasesize; fw1_blk = nr_blks_fcb; @@ -442,6 +465,8 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, fw1_pages = (IMX8MQ_SPL_SZ + (mtd->writesize - 1)) / mtd->writesize; fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages); + dump_fill_fcb = *fcb; + /* fill dbbt */ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); if (!dbbt_page) { @@ -467,8 +492,10 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, else if (ret > 0) dbbt->dbbtpages = 1; + dump_fill_dbbt = *dbbt; + /* write fcb and dbbt to nand */ - ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, off); + ret = write_fcb_dbbt_and_readback(mtd, fcb, dbbt, dbbt_data_page, off); if (ret < 0) printf("failed to write FCB/DBBT\n"); @@ -550,7 +577,7 @@ static int do_nandbcb_bcbonly(int argc, char * const argv[]) dbbt->dbbtpages = 1; /* write fcb and dbbt to nand */ - ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, 0); + ret = write_fcb_dbbt_and_readback(mtd, fcb, dbbt, dbbt_data_page, 0); dbbt_data_page_err: kfree(dbbt_data_page); dbbt_page_err: @@ -566,6 +593,218 @@ fcb_err: return CMD_RET_SUCCESS; } +/* dump data which is planned to be encoded and written to NAND chip */ +void mtd_cfg_dump(void) +{ + u64 blocks; + + printf("MTD CONFIG:\n"); + printf(" %s = %d\n", "data_setup_time", dump_fill_fcb.datasetup); + printf(" %s = %d\n", "data_hold_time", dump_fill_fcb.datahold); + printf(" %s = %d\n", "address_setup_time", dump_fill_fcb.addr_setup); + printf(" %s = %d\n", "data_sample_time", dump_fill_fcb.dsample_time); + + printf("NFC geometry :\n"); + printf("\tECC Strength : %d\n", dump_mtd->ecc_strength); + printf("\tPage Size in Bytes : %d\n", dump_fill_fcb.oob_pagesize); + printf("\tMetadata size : %d\n", dump_fill_fcb.meta_size); + printf("\tECC Chunk Size in byte : %d\n", dump_fill_fcb.ecc_size); + printf("\tECC Chunk count : %d\n", dump_fill_fcb.nr_blocks + 1); + printf("\tBlock Mark Byte Offset : %d\n", dump_fill_fcb.bb_byte); + printf("\tBlock Mark Bit Offset : %d\n", dump_fill_fcb.bb_start_bit); + printf("====================================================\n"); + + printf("mtd: partition #0\n"); + printf(" %s = %d\n", "type", dump_mtd->type); + printf(" %s = %d\n", "flags", dump_mtd->flags); + printf(" %s = %llu\n", "size", dump_nandboot_size); + printf(" %s = %d\n", "erasesize", dump_mtd->erasesize); + printf(" %s = %d\n", "writesize", dump_mtd->writesize); + printf(" %s = %d\n", "oobsize", dump_mtd->oobsize); + blocks = dump_nandboot_size; + do_div(blocks, dump_mtd->erasesize); + printf(" %s = %llu\n", "blocks", blocks); +} + +/* dump data which is read from NAND chip */ +void mtd_dump_structure(int i) +{ + #define P1(x) printf(" %s = 0x%08x\n", #x, dump_nand_fcb[i].x) + printf("FCB %d:\n", i); + P1(checksum); + P1(fingerprint); + P1(version); + #undef P1 + #define P1(x) printf(" %s = %d\n", #x, dump_nand_fcb[i].x) + P1(datasetup); + P1(datahold); + P1(addr_setup); + P1(dsample_time); + P1(pagesize); + P1(oob_pagesize); + P1(sectors); + P1(nr_nand); + P1(nr_die); + P1(celltype); + P1(ecc_type); + P1(ecc_nr); + P1(ecc_size); + P1(ecc_level); + P1(meta_size); + P1(nr_blocks); + P1(ecc_type_sdk); + P1(ecc_nr_sdk); + P1(ecc_size_sdk); + P1(ecc_level_sdk); + P1(nr_blocks_sdk); + P1(meta_size_sdk); + P1(erase_th); + P1(bootpatch); + P1(patch_size); + P1(fw1_start); + P1(fw2_start); + P1(fw1_pages); + P1(fw2_pages); + P1(dbbt_start); + P1(bb_byte); + P1(bb_start_bit); + P1(phy_offset); + P1(bchtype); + P1(readlatency); + P1(predelay); + P1(cedelay); + P1(postdelay); + P1(cmdaddpause); + P1(datapause); + P1(tmspeed); + P1(busytimeout); + P1(disbbm); + P1(spare_offset); + P1(onfi_sync_enable); + P1(onfi_sync_speed); + P1(onfi_sync_nand_data); + P1(disbbm_search); + P1(disbbm_search_limit); + P1(read_retry_enable); + #undef P1 + #define P1(x) printf(" %s = 0x%08x\n", #x, dump_nand_dbbt[i].x) + printf("DBBT %d:\n", i); + P1(checksum); + P1(fingerprint); + P1(version); + #undef P1 + #define P1(x) printf(" %s = %d\n", #x, dump_nand_dbbt[i].x) + P1(numberbb); + #undef P1 + + printf("Firmware: image #0 @ 0x%x size 0x%x - available 0x%llx\n", + dump_nand_fcb[i].fw1_start * dump_nand_fcb[i].pagesize, + dump_nand_fcb[i].fw1_pages * dump_nand_fcb[i].pagesize, + dump_nandboot_size - dump_nand_fcb[i].fw1_start * + dump_nand_fcb[i].pagesize); + if (is_imx8m()) { + printf("Extra Firmware: image #0 @ 0x%x size 0x%x - available 0x%llx\n", + dump_nand_fcb[i].fw1_start * + dump_nand_fcb[i].pagesize + dump_mtd->erasesize * + ((IMX8MQ_SPL_SZ + dump_mtd->erasesize - 1) / + dump_mtd->erasesize), + dump_nand_fcb[i].fw1_pages * dump_nand_fcb[i].pagesize, + dump_nandboot_size - + (dump_nand_fcb[i].fw1_start * + dump_nand_fcb[i].pagesize + dump_mtd->erasesize * + ((IMX8MQ_SPL_SZ + dump_mtd->erasesize - 1) / + dump_mtd->erasesize))); + } +} + +static int do_nandbcb_dump(int argc, char * const argv[]) +{ + int num; + int stride; + int search_area_sz; + bool bab_block_table[BOOT_SEARCH_COUNT]; + int bab_block_flag; + + if (argc != 2) + return CMD_RET_USAGE; + + switch (argv[1][0]) { + case '0': + num = 0; + break; + case '1': + num = 1; + break; + default: + return CMD_RET_USAGE; + } + + /* dump data which is planned to be encoded and written to NAND chip */ + mtd_cfg_dump(); + + stride = dump_mtd->erasesize; + search_area_sz = BOOT_SEARCH_COUNT * stride; + printf("stride: %x, search_area_sz: %x\n", stride, search_area_sz); + + bab_block_flag = 0; + for (int i = 0; i < BOOT_SEARCH_COUNT; i++) { + if (mtd_block_isbad(dump_mtd, + (loff_t)(dump_mtd->erasesize * i))) { + bab_block_table[i] = 1; + bab_block_flag = 1; + continue; + } + bab_block_table[i] = 0; + if (!memcmp(dump_nand_fcb + i, &dump_fill_fcb, + sizeof(dump_fill_fcb))) { + printf("mtd: found FCB%d candidate version %08x @%d:0x%x\n", + i, dump_nand_fcb[i].version, i, dump_fcb_off[i]); + } else { + printf("mtd: FCB%d not found\n", i); + } + } + + for (int i = 0; i < BOOT_SEARCH_COUNT; i++) { + if (mtd_block_isbad(dump_mtd, + (loff_t)(dump_mtd->erasesize * i))) + continue; + + if (!memcmp(dump_nand_dbbt + i, &dump_fill_dbbt, + sizeof(dump_fill_dbbt))) { + printf("mtd: DBBT%d found\n", i); + printf("mtd: Valid DBBT%d found @%d:0x%x\n", + i, i, dump_dbbt_off[i]); + + } else { + printf("mtd: DBBT%d not found\n", i); + } + } + if (bab_block_flag == 0) { + printf("no bad block found, dbbt: %08x\n", + dump_fill_dbbt.fingerprint); + } else { + for (int i = 0; i < BOOT_SEARCH_COUNT; i++) { + if (bab_block_table[i] == 1) + printf("mtd: bad block @ 0x%llx\n", + (loff_t)(dump_mtd->erasesize * i)); + } + } + + /* dump data which is read from NAND chip */ + if (num > (BOOT_SEARCH_COUNT - 1)) + return CMD_RET_USAGE; + + if (bab_block_table[num] == 1) { + printf("mtd: bad block @ 0x%llx (FCB - DBBT)\n", + (loff_t)(dump_mtd->erasesize * num)); + return CMD_RET_USAGE; + } + + mtd_dump_structure(num); + + return 0; +} + static int do_nandbcb_update(int argc, char * const argv[]) { struct mtd_info *mtd; @@ -593,6 +832,10 @@ static int do_nandbcb_update(int argc, char * const argv[]) &maxsize, MTD_DEV_TYPE_NAND, mtd->size)) return CMD_RET_FAILURE; + /* dump_mtd and dump_nandboot_size are used for "nandbcb dump [-v]" */ + dump_mtd = mtd; + dump_nandboot_size = maxsize; + buf = map_physmem(addr, size, MAP_WRBACK); if (!buf) { puts("failed to map physical memory\n"); @@ -610,7 +853,7 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, const char *cmd; int ret = 0; - if (argc < 5) + if (argc < 3) goto usage; cmd = argv[1]; @@ -622,6 +865,11 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, goto done; } + if (strcmp(cmd, "dump") == 0) { + ret = do_nandbcb_dump(argc, argv); + goto done; + } + if (strcmp(cmd, "bcbonly") == 0) { ret = do_nandbcb_bcbonly(argc, argv); goto done; @@ -643,7 +891,9 @@ static char nandbcb_help_text[] = " and `fw2-off` - firmware offsets\n" " FIY, BCB isn't erased automatically, so mtd erase should\n" " be called in advance before writing new BCB:\n" - " > mtd erase mx7-bcb"; + " > mtd erase mx7-bcb\n" + "nandbcb dump num - verify/dump boot structures\n" + " 'num' can be set to 0 and 1"; #endif U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb, From 49f84547057f4c4c268c0567a11052a8975450e2 Mon Sep 17 00:00:00 2001 From: Alice Guo Date: Tue, 5 May 2020 22:04:02 +0800 Subject: [PATCH 69/82] nandbcb: add nandbcb dump command for i.MX6 Verify/dump boot structures. Signed-off-by: Alice Guo Signed-off-by: Peng Fan --- arch/arm/mach-imx/cmd_nandbcb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 02a65ffd438..a8531def35b 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -309,6 +309,10 @@ static int write_fcb_dbbt_and_readback(struct mtd_info *mtd, debug("NAND fcb write: 0x%x offset 0x%zx written: %s\n", mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK"); + + ops.datbuf = (u8 *)(dump_nand_fcb + i); + ops.oobbuf = ((u8 *)(dump_nand_fcb + i)) + mtd->writesize; + mtd_read_oob(mtd, mtd->erasesize * i, &ops); } ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, From 214b7d534d420e9377d7f9e4c364123e33b0233d Mon Sep 17 00:00:00 2001 From: Han Xu Date: Tue, 5 May 2020 22:04:03 +0800 Subject: [PATCH 70/82] cmd: nandbcb: Reconstruct the nandbcb tool for all platforms The original nandbcb tool was designed for imx6 only, when trying to leverage it to replace the kobs-ng tool, we found the design is not friendly for supporting all platforms. To support all iMX6/7/8 platforms and for easy further maintain, I reconstruct the structure of the tool. The main changes including: 1. Use platform_data to determine the logic branches rather than simply use SOC name. 2. More data structures as parameter for functions. 3. Global variables to define the FCB/DBBT/FW locations. 4. Implement the kobs-ng default 4 FCB/4 DBBT/2 FW layout. 5. Support Hamming coding/ 40bit BCH/ 62bit BCH coding FCB. 6. Dump and compare all written FCB/DBBT to verify data integrity. The tool has been verified on iMX6Q/DL, 6SX, 7D, 6ULL, iMX8QX, iMX8MM. Signed-off-by: Han Xu Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/imx-nandbcb.h | 4 +- arch/arm/mach-imx/cmd_nandbcb.c | 1333 ++++++++++++++----- 2 files changed, 970 insertions(+), 367 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/imx-nandbcb.h b/arch/arm/include/asm/mach-imx/imx-nandbcb.h index 907e7ed8f94..74c9031d4e7 100644 --- a/arch/arm/include/asm/mach-imx/imx-nandbcb.h +++ b/arch/arm/include/asm/mach-imx/imx-nandbcb.h @@ -9,9 +9,11 @@ #define FCB_FINGERPRINT 0x20424346 /* 'FCB' */ #define FCB_VERSION_1 0x01000000 +#define FCB_FINGERPRINT_OFF 0x4 /* FCB fingerprint offset*/ -#define DBBT_FINGERPRINT2 0x54424244 /* 'DBBT' */ +#define DBBT_FINGERPRINT 0x54424244 /* 'DBBT' */ #define DBBT_VERSION_1 0x01000000 +#define DBBT_FINGERPRINT_OFF 0x4 /* DBBT fingerprint offset*/ struct dbbt_block { u32 checksum; /* reserved on i.MX6 */ diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index a8531def35b..ab12b1f1cf2 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -1,11 +1,13 @@ /* - * i.MX6 nand boot control block(bcb). + * i.MX nand boot control block(bcb). * * Based on the common/imx-bbu-nand-fcb.c from barebox and imx kobs-ng * * Copyright (C) 2017 Jagan Teki * Copyright (C) 2016 Sergey Kubushyn * + * Reconstucted by Han Xu + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -25,24 +27,295 @@ #include #include #include -#include #include "../../../cmd/legacy-mtd-utils.h" -#define BF_VAL(v, bf) (((v) & bf##_MASK) >> bf##_OFFSET) +/* FCB related flags */ +/* FCB layout with leading 12B reserved */ +#define FCB_LAYOUT_RESV_12B BIT(0) +/* FCB layout with leading 32B meta data */ +#define FCB_LAYOUT_META_32B BIT(1) +/* FCB encrypted by Hamming code */ +#define FCB_ENCODE_HAMMING BIT(2) +/* FCB encrypted by 40bit BCH */ +#define FCB_ENCODE_BCH_40b BIT(3) +/* FCB encrypted by 62bit BCH */ +#define FCB_ENCODE_BCH_62b BIT(4) +/* FCB encrypted by BCH */ +#define FCB_ENCODE_BCH (FCB_ENCODE_BCH_40b | FCB_ENCODE_BCH_62b) +/* FCB data was randomized */ +#define FCB_RANDON_ENABLED BIT(5) + +/* Firmware related flags */ +/* No 1K padding */ +#define FIRMWARE_NEED_PADDING BIT(8) +/* Extra firmware*/ +#define FIRMWARE_EXTRA_ONE BIT(9) +/* Secondary firmware on fixed address */ +#define FIRMWARE_SECONDARY_FIXED_ADDR BIT(10) + +/* Boot search related flags */ +#define BT_SEARCH_CNT_FROM_FUSE BIT(16) + +struct platform_config { + int misc_flags; +}; + +static struct platform_config plat_config; + +/* imx6q/dl/solo */ +static struct platform_config imx6qdl_plat_config = { + .misc_flags = FCB_LAYOUT_RESV_12B | + FCB_ENCODE_HAMMING | + FIRMWARE_NEED_PADDING, +}; + +static struct platform_config imx6sx_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_62b | + FIRMWARE_NEED_PADDING | + FCB_RANDON_ENABLED, +}; + +static struct platform_config imx7d_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_62b | + FIRMWARE_NEED_PADDING | + FCB_RANDON_ENABLED, +}; + +/* imx6ul/ull/ulz */ +static struct platform_config imx6ul_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_40b | + FIRMWARE_NEED_PADDING, +}; + +static struct platform_config imx8mq_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_62b | + FIRMWARE_NEED_PADDING | + FCB_RANDON_ENABLED | + FIRMWARE_EXTRA_ONE, +}; + +/* all other imx8mm */ +static struct platform_config imx8mm_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_62b | + FIRMWARE_NEED_PADDING | + FCB_RANDON_ENABLED, +}; + +/* imx8mn */ +static struct platform_config imx8mn_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_62b | + FCB_RANDON_ENABLED | + FIRMWARE_SECONDARY_FIXED_ADDR | + BT_SEARCH_CNT_FROM_FUSE, +}; + +/* imx8qx/qm */ +static struct platform_config imx8q_plat_config = { + .misc_flags = FCB_LAYOUT_META_32B | + FCB_ENCODE_BCH_62b | + FCB_RANDON_ENABLED | + FIRMWARE_SECONDARY_FIXED_ADDR | + BT_SEARCH_CNT_FROM_FUSE, +}; + +/* boot search related variables and definitions */ +static int g_boot_search_count = 4; +static int g_boot_search_stride; +static int g_pages_per_stride; + +/* mtd config structure */ +struct boot_config { + int dev; + struct mtd_info *mtd; + loff_t maxsize; + loff_t input_size; + loff_t offset; + loff_t boot_stream1_address; + loff_t boot_stream2_address; + size_t boot_stream1_size; + size_t boot_stream2_size; + size_t max_boot_stream_size; + int stride_size_in_byte; + int search_area_size_in_bytes; + int search_area_size_in_pages; + int secondary_boot_stream_off_in_MB; +}; + +/* boot_stream config structure */ +struct boot_stream_config { + char bs_label[32]; + loff_t bs_addr; + size_t bs_size; + void *bs_buf; + loff_t next_bs_addr; + bool need_padding; +}; + +/* FW index */ +#define FW1_ONLY 1 +#define FW2_ONLY 2 +#define FW_ALL FW1_ONLY | FW2_ONLY +#define FW_INX(x) (1 << (x)) + +/* NAND convert macros */ +#define CONV_TO_PAGES(x) ((u32)(x) / (u32)(mtd->writesize)) +#define CONV_TO_BLOCKS(x) ((u32)(x) / (u32)(mtd->erasesize)) + #define GETBIT(v, n) (((v) >> (n)) & 0x1) #define IMX8MQ_SPL_SZ 0x3e000 #define IMX8MQ_HDMI_FW_SZ 0x19c00 -#define BOOT_SEARCH_COUNT 2 -struct mtd_info *dump_mtd; -static loff_t dump_nandboot_size; -static struct fcb_block dump_fill_fcb; -static struct dbbt_block dump_fill_dbbt; -static struct fcb_block dump_nand_fcb[BOOT_SEARCH_COUNT]; -static struct dbbt_block dump_nand_dbbt[BOOT_SEARCH_COUNT]; -static u32 dump_fcb_off[BOOT_SEARCH_COUNT]; -static u32 dump_dbbt_off[BOOT_SEARCH_COUNT]; +static int nandbcb_get_info(int argc, char * const argv[], + struct boot_config *boot_cfg) +{ + int dev; + struct mtd_info *mtd; + + dev = nand_curr_device; + if (dev < 0) { + printf("failed to get nand_curr_device, run nand device\n"); + return CMD_RET_FAILURE; + } + + mtd = get_nand_dev_by_index(dev); + if (!mtd) { + printf("failed to get mtd info\n"); + return CMD_RET_FAILURE; + } + + boot_cfg->dev = dev; + boot_cfg->mtd = mtd; + + return CMD_RET_SUCCESS; +} + +static int nandbcb_get_size(int argc, char * const argv[], int num, + struct boot_config *boot_cfg) +{ + int dev; + loff_t offset, size, maxsize; + struct mtd_info *mtd; + + dev = boot_cfg->dev; + mtd = boot_cfg->mtd; + size = 0; + + if (mtd_arg_off_size(argc - num, argv + num, &dev, &offset, &size, + &maxsize, MTD_DEV_TYPE_NAND, mtd->size)) + return CMD_RET_FAILURE; + + boot_cfg->maxsize = maxsize; + boot_cfg->offset = offset; + + debug("max: %llx, offset: %llx\n", maxsize, offset); + + if (size && size != maxsize) + boot_cfg->input_size = size; + + return CMD_RET_SUCCESS; +} + +static int nandbcb_set_boot_config(int argc, char * const argv[], + struct boot_config *boot_cfg) +{ + struct mtd_info *mtd; + loff_t maxsize; + loff_t boot_stream1_address, boot_stream2_address, max_boot_stream_size; + + if (!boot_cfg->mtd) { + printf("Didn't get the mtd info, quit\n"); + return CMD_RET_FAILURE; + } + mtd = boot_cfg->mtd; + + /* + * By default + * set the search count as 4 + * set each FCB/DBBT/Firmware offset at the beginning of blocks + * customers may change the value as needed + */ + + /* if need more compact layout, change these values */ + /* g_boot_search_count was set as 4 at the definition*/ + /* g_pages_per_stride was set as block size */ + + g_pages_per_stride = mtd->erasesize / mtd->writesize; + + g_boot_search_stride = mtd->writesize * g_pages_per_stride; + + boot_cfg->stride_size_in_byte = g_boot_search_stride * mtd->writesize; + boot_cfg->search_area_size_in_bytes = + g_boot_search_count * g_boot_search_stride; + boot_cfg->search_area_size_in_pages = + boot_cfg->search_area_size_in_bytes / mtd->writesize; + + /* after FCB/DBBT, split the rest of area for two Firmwares */ + if (!boot_cfg->maxsize) { + printf("Didn't get the maxsize, quit\n"); + return CMD_RET_FAILURE; + } + maxsize = boot_cfg->maxsize; + /* align to page boundary */ + maxsize = ((u32)(maxsize + mtd->writesize - 1)) / (u32)mtd->writesize + * mtd->writesize; + + boot_stream1_address = 2 * boot_cfg->search_area_size_in_bytes; + boot_stream2_address = ((maxsize - boot_stream1_address) / 2 + + boot_stream1_address); + + if (boot_cfg->secondary_boot_stream_off_in_MB) + boot_stream2_address = boot_cfg->secondary_boot_stream_off_in_MB * 1024 * 1024; + + max_boot_stream_size = boot_stream2_address - boot_stream1_address; + + /* sanity check */ + if (max_boot_stream_size <= 0) { + debug("st1_addr: %llx, st2_addr: %llx, max: %llx\n", + boot_stream1_address, boot_stream2_address, + max_boot_stream_size); + printf("something wrong with firmware address settings\n"); + return CMD_RET_FAILURE; + } + boot_cfg->boot_stream1_address = boot_stream1_address; + boot_cfg->boot_stream2_address = boot_stream2_address; + boot_cfg->max_boot_stream_size = max_boot_stream_size; + + /* set the boot_stream size as the input size now */ + if (boot_cfg->input_size) { + boot_cfg->boot_stream1_size = boot_cfg->input_size; + boot_cfg->boot_stream2_size = boot_cfg->input_size; + } + + return CMD_RET_SUCCESS; +} + +static int nandbcb_check_space(struct boot_config *boot_cfg) +{ + size_t maxsize = boot_cfg->maxsize; + size_t max_boot_stream_size = boot_cfg->max_boot_stream_size; + loff_t boot_stream2_address = boot_cfg->boot_stream2_address; + + if (boot_cfg->boot_stream1_size && + boot_cfg->boot_stream1_size > max_boot_stream_size) { + printf("boot stream1 doesn't fit, check partition size or settings\n"); + return CMD_RET_FAILURE; + } + + if (boot_cfg->boot_stream2_size && + boot_cfg->boot_stream2_size > maxsize - boot_stream2_address) { + printf("boot stream2 doesn't fit, check partition size or settings\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) static uint8_t reverse_bit(uint8_t b) @@ -145,9 +418,9 @@ static u32 calc_chksum(void *buf, size_t size) return ~chksum; } -static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, - u32 fw1_start, u32 fw2_start, u32 fw_pages) +static void fill_fcb(struct fcb_block *fcb, struct boot_config *boot_cfg) { + struct mtd_info *mtd = boot_cfg->mtd; struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); struct mxs_nand_layout l; @@ -157,6 +430,11 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, fcb->fingerprint = FCB_FINGERPRINT; fcb->version = FCB_VERSION_1; + fcb->datasetup = 80; + fcb->datahold = 60; + fcb->addr_setup = 25; + fcb->dsample_time = 6; + fcb->pagesize = mtd->writesize; fcb->oob_pagesize = mtd->writesize + mtd->oobsize; fcb->sectors = mtd->erasesize / mtd->writesize; @@ -169,41 +447,25 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, fcb->ecc_type = l.eccn; fcb->bchtype = l.gf_len; - /* Also hardcoded in kobs-ng */ - if (is_mx6() || is_imx8m()) { - fcb->datasetup = 80; - fcb->datahold = 60; - fcb->addr_setup = 25; - fcb->dsample_time = 6; - } else if (is_mx7()) { - fcb->datasetup = 10; - fcb->datahold = 7; - fcb->addr_setup = 15; - fcb->dsample_time = 6; - } - - /* DBBT search area starts at second page on first block */ - fcb->dbbt_start = 1; + /* DBBT search area starts from the next block after all FCB */ + fcb->dbbt_start = boot_cfg->search_area_size_in_pages; fcb->bb_byte = nand_info->bch_geometry.block_mark_byte_offset; fcb->bb_start_bit = nand_info->bch_geometry.block_mark_bit_offset; fcb->phy_offset = mtd->writesize; - fcb->nr_blocks = mtd->writesize / fcb->ecc_nr - 1; - fcb->disbbm = 0; - fcb->disbbm_search = 0; - fcb->fw1_start = fw1_start; /* Firmware image starts on this sector */ - fcb->fw2_start = fw2_start; /* Secondary FW Image starting Sector */ - fcb->fw1_pages = fw_pages; /* Number of sectors in firmware image */ - fcb->fw2_pages = fw_pages; /* Number of sector in secondary FW image */ + fcb->fw1_start = CONV_TO_PAGES(boot_cfg->boot_stream1_address); + fcb->fw2_start = CONV_TO_PAGES(boot_cfg->boot_stream2_address); + fcb->fw1_pages = CONV_TO_PAGES(boot_cfg->boot_stream1_size); + fcb->fw2_pages = CONV_TO_PAGES(boot_cfg->boot_stream2_size); fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); } -static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks) +static int fill_dbbt_data(struct mtd_info *mtd, void *buf, int num_blocks) { int n, n_bad_blocks = 0; u32 *bb = buf + 0x8; @@ -223,21 +485,92 @@ static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks) return n_bad_blocks; } -static int write_fcb_dbbt_and_readback(struct mtd_info *mtd, - struct fcb_block *fcb, - struct dbbt_block *dbbt, - void *dbbt_data_page, loff_t off) +/* + * return 1 - bad block + * return 0 - read successfully + * return < 0 - read failed + */ +static int read_fcb(struct boot_config *boot_cfg, struct fcb_block *fcb, + loff_t off) { - void *fcb_raw_page = 0; + struct mtd_info *mtd; + void *fcb_raw_page; + size_t size; + int ret = 0; + + mtd = boot_cfg->mtd; + fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); + + if (mtd_block_isbad(mtd, off)) { + printf("Block %d is bad, skipped\n", (int)CONV_TO_BLOCKS(off)); + return 1; + } + + /* + * User BCH hardware to decode ECC for FCB + */ + if (plat_config.misc_flags & FCB_ENCODE_BCH) { + size = sizeof(struct fcb_block); + + /* switch nand BCH to FCB compatible settings */ + if (plat_config.misc_flags & FCB_ENCODE_BCH_62b) + mxs_nand_mode_fcb_62bit(mtd); + else if (plat_config.misc_flags & FCB_ENCODE_BCH_40b) + mxs_nand_mode_fcb_40bit(mtd); + + ret = nand_read(mtd, off, &size, (u_char *)fcb); + + /* switch BCH back */ + mxs_nand_mode_normal(mtd); + printf("NAND FCB read from 0x%llx offset 0x%zx read: %s\n", + off, size, ret ? "ERROR" : "OK"); + + } else if (plat_config.misc_flags & FCB_ENCODE_HAMMING) { + /* raw read*/ + mtd_oob_ops_t ops = { + .datbuf = (u8 *)fcb_raw_page, + .oobbuf = ((u8 *)fcb_raw_page) + mtd->writesize, + .len = mtd->writesize, + .ooblen = mtd->oobsize, + .mode = MTD_OPS_RAW + }; + + ret = mtd_read_oob(mtd, off, &ops); + printf("NAND FCB read from 0x%llx offset 0x%zx read: %s\n", + off, ops.len, ret ? "ERROR" : "OK"); + } + + if (ret) + goto fcb_raw_page_err; + + if ((plat_config.misc_flags & FCB_ENCODE_HAMMING) && + (plat_config.misc_flags & FCB_LAYOUT_RESV_12B)) + memcpy(fcb, fcb_raw_page + 12, sizeof(struct fcb_block)); + +/* TODO: check if it can pass Hamming check */ + +fcb_raw_page_err: + kfree(fcb_raw_page); + + return ret; +} + +static int write_fcb(struct boot_config *boot_cfg, struct fcb_block *fcb) +{ + struct mtd_info *mtd; + void *fcb_raw_page = NULL; int i, ret; - size_t dummy; + loff_t off; + size_t size; + + mtd = boot_cfg->mtd; /* * We prepare raw page only for i.MX6, for i.MX7 we * leverage BCH hw module instead */ - if (is_mx6()) { - /* write fcb/dbbt */ + if ((plat_config.misc_flags & FCB_ENCODE_HAMMING) && + (plat_config.misc_flags & FCB_LAYOUT_RESV_12B)) { fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); if (!fcb_raw_page) { @@ -265,34 +598,36 @@ static int write_fcb_dbbt_and_readback(struct mtd_info *mtd, */ memset(fcb_raw_page + mtd->writesize, 0xFF, 2); } - for (i = 0; i < 2; i++) { + + /* start writing FCB from the very beginning */ + off = 0; + + for (i = 0; i < g_boot_search_count; i++) { if (mtd_block_isbad(mtd, off)) { printf("Block %d is bad, skipped\n", i); continue; } /* - * User BCH ECC hardware module for i.MX7 + * User BCH hardware module to generate ECC for FCB */ - if (is_mx7() || is_imx8m()) { - u32 off = i * mtd->erasesize; - size_t rwsize = sizeof(*fcb); - - printf("Writing %zd bytes to 0x%x: ", rwsize, off); + if (plat_config.misc_flags & FCB_ENCODE_BCH) { + size = sizeof(struct fcb_block); /* switch nand BCH to FCB compatible settings */ - mxs_nand_mode_fcb(mtd); - ret = nand_write(mtd, off, &rwsize, - (unsigned char *)fcb); + if (plat_config.misc_flags & FCB_ENCODE_BCH_62b) + mxs_nand_mode_fcb_62bit(mtd); + else if (plat_config.misc_flags & FCB_ENCODE_BCH_40b) + mxs_nand_mode_fcb_40bit(mtd); - dump_fcb_off[i] = off; - nand_read(mtd, off, &rwsize, - (unsigned char *)(dump_nand_fcb + i)); + ret = nand_write(mtd, off, &size, (u_char *)fcb); + /* switch BCH back */ mxs_nand_mode_normal(mtd); + printf("NAND FCB write to 0x%zx offset 0x%llx written: %s\n", + size, off, ret ? "ERROR" : "OK"); - printf("%s\n", ret ? "ERROR" : "OK"); - } else if (is_mx6()) { + } else if (plat_config.misc_flags & FCB_ENCODE_HAMMING) { /* raw write */ mtd_oob_ops_t ops = { .datbuf = (u8 *)fcb_raw_page, @@ -303,65 +638,327 @@ static int write_fcb_dbbt_and_readback(struct mtd_info *mtd, .mode = MTD_OPS_RAW }; - ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); - if (ret) - goto fcb_raw_page_err; - debug("NAND fcb write: 0x%x offset 0x%zx written: %s\n", - mtd->erasesize * i, ops.len, ret ? - "ERROR" : "OK"); - - ops.datbuf = (u8 *)(dump_nand_fcb + i); - ops.oobbuf = ((u8 *)(dump_nand_fcb + i)) + mtd->writesize; - mtd_read_oob(mtd, mtd->erasesize * i, &ops); + ret = mtd_write_oob(mtd, off, &ops); + printf("NAND FCB write to 0x%llxx offset 0x%zx written: %s\n", off, ops.len, ret ? "ERROR" : "OK"); } - ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, - mtd->writesize, &dummy, (void *)dbbt); if (ret) goto fcb_raw_page_err; - debug("NAND dbbt write: 0x%x offset, 0x%zx bytes written: %s\n", - mtd->erasesize * i + mtd->writesize, dummy, - ret ? "ERROR" : "OK"); - dump_dbbt_off[i] = mtd->erasesize * i + mtd->writesize; - size_t rwsize = sizeof(*dbbt); - - nand_read(mtd, dump_dbbt_off[i], &rwsize, - (unsigned char *)(dump_nand_dbbt + i)); - - /* dbbtpages == 0 if no bad blocks */ - if (dbbt->dbbtpages > 0) { - loff_t to = (mtd->erasesize * i + mtd->writesize * 5); - - ret = mtd_write(mtd, to, mtd->writesize, &dummy, - dbbt_data_page); - if (ret) - goto fcb_raw_page_err; - } + /* next writing location */ + off += g_boot_search_stride; } + return 0; + fcb_raw_page_err: - if (is_mx6()) - kfree(fcb_raw_page); + kfree(fcb_raw_page); return ret; } -static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, - size_t maxsize, const u_char *buf) +/* + * return 1 - bad block + * return 0 - read successfully + * return < 0 - read failed + */ +static int read_dbbt(struct boot_config *boot_cfg, struct dbbt_block *dbbt, + void *dbbt_data_page, loff_t off) { + size_t size; + struct mtd_info *mtd; + loff_t to; + int ret; + + mtd = boot_cfg->mtd; + + if (mtd_block_isbad(mtd, off)) { + printf("Block %d is bad, skipped\n", + (int)CONV_TO_BLOCKS(off)); + return 1; + } + + size = sizeof(struct dbbt_block); + ret = nand_read(mtd, off, &size, (u_char *)dbbt); + printf("NAND DBBT read from 0x%llx offset 0x%zx read: %s\n", + off, size, ret ? "ERROR" : "OK"); + if (ret) + return ret; + + /* dbbtpages == 0 if no bad blocks */ + if (dbbt->dbbtpages > 0) { + to = off + 4 * mtd->writesize; + size = mtd->writesize; + ret = nand_read(mtd, to, &size, dbbt_data_page); + printf("DBBT data read from 0x%llx offset 0x%zx read: %s\n", + to, size, ret ? "ERROR" : "OK"); + + if (ret) + return ret; + } + + return 0; +} + +static int write_dbbt(struct boot_config *boot_cfg, struct dbbt_block *dbbt, + void *dbbt_data_page) +{ + int i; + loff_t off, to; + size_t size; + struct mtd_info *mtd; + int ret; + + mtd = boot_cfg->mtd; + + /* start writing DBBT after all FCBs */ + off = boot_cfg->search_area_size_in_bytes; + size = mtd->writesize; + + for (i = 0; i < g_boot_search_count; i++) { + if (mtd_block_isbad(mtd, off)) { + printf("Block %d is bad, skipped\n", + (int)(i + CONV_TO_BLOCKS(off))); + continue; + } + + ret = nand_write(mtd, off, &size, (u_char *)dbbt); + printf("NAND DBBT write to 0x%llx offset 0x%zx written: %s\n", + off, size, ret ? "ERROR" : "OK"); + if (ret) + return ret; + + /* dbbtpages == 0 if no bad blocks */ + if (dbbt->dbbtpages > 0) { + to = off + 4 * mtd->writesize; + ret = nand_write(mtd, to, &size, dbbt_data_page); + printf("DBBT data write to 0x%llx offset 0x%zx written: %s\n", + to, size, ret ? "ERROR" : "OK"); + + if (ret) + return ret; + } + + /* next writing location */ + off += g_boot_search_stride; + } + + return 0; +} + +/* reuse the check_skip_len from nand_util.c with minor change*/ +static int check_skip_length(struct boot_config *boot_cfg, loff_t offset, + size_t length, size_t *used) +{ + struct mtd_info *mtd = boot_cfg->mtd; + size_t maxsize = boot_cfg->maxsize; + size_t len_excl_bad = 0; + int ret = 0; + + while (len_excl_bad < length) { + size_t block_len, block_off; + loff_t block_start; + + if (offset >= maxsize) + return -1; + + block_start = offset & ~(loff_t)(mtd->erasesize - 1); + block_off = offset & (mtd->erasesize - 1); + block_len = mtd->erasesize - block_off; + + if (!nand_block_isbad(mtd, block_start)) + len_excl_bad += block_len; + else + ret = 1; + + offset += block_len; + *used += block_len; + } + + /* If the length is not a multiple of block_len, adjust. */ + if (len_excl_bad > length) + *used -= (len_excl_bad - length); + + return ret; +} + +static int nandbcb_get_next_good_blk_addr(struct boot_config *boot_cfg, + struct boot_stream_config *bs_cfg) +{ + struct mtd_info *mtd = boot_cfg->mtd; + loff_t offset = bs_cfg->bs_addr; + size_t length = bs_cfg->bs_size; + size_t used = 0; + int ret; + + ret = check_skip_length(boot_cfg, offset, length, &used); + + if (ret < 0) + return ret; + + /* get next image address */ + bs_cfg->next_bs_addr = (u32)(offset + used + mtd->erasesize - 1) + / (u32)mtd->erasesize * mtd->erasesize; + + return ret; +} + +static int nandbcb_write_bs_skip_bad(struct boot_config *boot_cfg, + struct boot_stream_config *bs_cfg) +{ + struct mtd_info *mtd; + void *buf; + loff_t offset, maxsize; + size_t size; + size_t length; + int ret; + bool padding_flag = false; + + mtd = boot_cfg->mtd; + offset = bs_cfg->bs_addr; + maxsize = boot_cfg->maxsize; + size = bs_cfg->bs_size; + + /* some boot images may need leading offset */ + if (bs_cfg->need_padding && + (plat_config.misc_flags & FIRMWARE_NEED_PADDING)) + padding_flag = 1; + + if (padding_flag) + length = ALIGN(size + FLASH_OFFSET_STANDARD, mtd->writesize); + else + length = ALIGN(size, mtd->writesize); + + buf = kzalloc(length, GFP_KERNEL); + if (!buf) { + printf("failed to allocate buffer for firmware\n"); + ret = -ENOMEM; + return ret; + } + + if (padding_flag) + memcpy(buf + FLASH_OFFSET_STANDARD, bs_cfg->bs_buf, size); + else + memcpy(buf, bs_cfg->bs_buf, size); + + ret = nand_write_skip_bad(mtd, offset, &length, NULL, maxsize, + (u_char *)buf, WITH_WR_VERIFY); + printf("Write %s @0x%llx offset, 0x%zx bytes written: %s\n", + bs_cfg->bs_label, offset, length, ret ? "ERROR" : "OK"); + + if (ret) + /* write image failed, quit */ + goto err; + + /* get next good blk address if needed */ + if (bs_cfg->need_padding) { + ret = nandbcb_get_next_good_blk_addr(boot_cfg, bs_cfg); + if (ret < 0) { + printf("Next image cannot fit in NAND partition\n"); + goto err; + } + } + + /* now we know how the exact image size written to NAND */ + bs_cfg->bs_size = length; + return 0; +err: + kfree(buf); + return ret; +} + +static int nandbcb_write_fw(struct boot_config *boot_cfg, u_char *buf, + int index) +{ + int i; + loff_t offset; + size_t size; + loff_t next_bs_addr; + struct boot_stream_config bs_cfg; + int ret; + + for (i = 0; i < 2; ++i) { + if (!(FW_INX(i) & index)) + continue; + + if (i == 0) { + offset = boot_cfg->boot_stream1_address; + size = boot_cfg->boot_stream1_size; + } else { + offset = boot_cfg->boot_stream2_address; + size = boot_cfg->boot_stream2_size; + } + + /* write Firmware*/ + if (!(plat_config.misc_flags & FIRMWARE_EXTRA_ONE)) { + memset(&bs_cfg, 0, sizeof(struct boot_stream_config)); + sprintf(bs_cfg.bs_label, "firmware%d", i); + bs_cfg.bs_addr = offset; + bs_cfg.bs_size = size; + bs_cfg.bs_buf = buf; + bs_cfg.need_padding = 1; + + ret = nandbcb_write_bs_skip_bad(boot_cfg, &bs_cfg); + if (ret) + return ret; + + /* update the boot stream size */ + if (i == 0) + boot_cfg->boot_stream1_size = bs_cfg.bs_size; + else + boot_cfg->boot_stream2_size = bs_cfg.bs_size; + + } else { + /* some platforms need extra firmware */ + memset(&bs_cfg, 0, sizeof(struct boot_stream_config)); + sprintf(bs_cfg.bs_label, "fw%d_part%d", i, 1); + bs_cfg.bs_addr = offset; + bs_cfg.bs_size = IMX8MQ_HDMI_FW_SZ; + bs_cfg.bs_buf = buf; + bs_cfg.need_padding = 1; + + ret = nandbcb_write_bs_skip_bad(boot_cfg, &bs_cfg); + if (ret) + return ret; + + /* update the boot stream size */ + if (i == 0) + boot_cfg->boot_stream1_size = bs_cfg.bs_size; + else + boot_cfg->boot_stream2_size = bs_cfg.bs_size; + + /* get next image address */ + next_bs_addr = bs_cfg.next_bs_addr; + + memset(&bs_cfg, 0, sizeof(struct boot_stream_config)); + sprintf(bs_cfg.bs_label, "fw%d_part%d", i, 2); + bs_cfg.bs_addr = next_bs_addr; + bs_cfg.bs_size = IMX8MQ_SPL_SZ; + bs_cfg.bs_buf = (u_char *)(buf + IMX8MQ_HDMI_FW_SZ); + bs_cfg.need_padding = 0; + + ret = nandbcb_write_bs_skip_bad(boot_cfg, &bs_cfg); + if (ret) + return ret; + } + } + + return 0; +} + +static int nandbcb_init(struct boot_config *boot_cfg, u_char *buf) +{ + struct mtd_info *mtd; nand_erase_options_t opts; struct fcb_block *fcb; struct dbbt_block *dbbt; - loff_t fw1_off; - void *fwbuf, *dbbt_page, *dbbt_data_page; - u32 fw1_start, fw1_pages; - int nr_blks, nr_blks_fcb, fw1_blk; - size_t fwsize; + void *dbbt_page, *dbbt_data_page; int ret; - size_t extra_fwsize; - void *extra_fwbuf; - loff_t extra_fw1_off; + loff_t maxsize, off; + + mtd = boot_cfg->mtd; + maxsize = boot_cfg->maxsize; + off = boot_cfg->offset; /* erase */ memset(&opts, 0, sizeof(opts)); @@ -391,85 +988,24 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, * - two firmware blocks, primary and secondary * - first 4 block for FCB/DBBT * - rest split in half for primary and secondary firmware - * - same firmware will write two times + * - same firmware write twice */ - nr_blks_fcb = BOOT_SEARCH_COUNT; - nr_blks = maxsize / mtd->erasesize; - fw1_blk = nr_blks_fcb; - /* write fw */ - fwbuf = NULL; - if (is_mx6() || is_mx7()) { - fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize, - mtd->writesize); - fwbuf = kzalloc(fwsize, GFP_KERNEL); - if (!fwbuf) { - debug("failed to allocate fwbuf\n"); - ret = -ENOMEM; - goto err; - } - - memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size); - fw1_off = fw1_blk * mtd->erasesize; - ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize, - (u_char *)fwbuf, WITH_WR_VERIFY); - printf("NAND fw write: 0x%llx offset, 0x%zx bytes written: %s\n", - fw1_off, fwsize, ret ? "ERROR" : "OK"); - if (ret) - goto fwbuf_err; - } else if (is_imx8m()) { - fwsize = ALIGN(IMX8MQ_SPL_SZ + FLASH_OFFSET_STANDARD + mtd->writesize, mtd->writesize); - fwbuf = kzalloc(fwsize, GFP_KERNEL); - if (!fwbuf) { - printf("failed to allocate fwbuf\n"); - ret = -ENOMEM; - goto err; - } - - memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, IMX8MQ_SPL_SZ); - fw1_off = fw1_blk * mtd->erasesize; - ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize, - (u_char *)fwbuf, WITH_WR_VERIFY); - printf("NAND fw write: 0x%llx offset, 0x%zx bytes written: %s\n", - fw1_off, fwsize, ret ? "ERROR" : "OK"); - if (ret) - goto fwbuf_err; - - extra_fwsize = ALIGN(IMX8MQ_SPL_SZ + mtd->writesize, mtd->writesize); - extra_fwbuf = kzalloc(extra_fwsize, GFP_KERNEL); - extra_fw1_off = fw1_off + mtd->erasesize * ((IMX8MQ_SPL_SZ + mtd->erasesize - 1) / mtd->erasesize); - if (!extra_fwbuf) { - printf("failed to allocate fwbuf\n"); - ret = -ENOMEM; - goto fwbuf_err; - } - - memcpy(extra_fwbuf, buf + IMX8MQ_HDMI_FW_SZ, IMX8MQ_SPL_SZ); - ret = nand_write_skip_bad(mtd, extra_fw1_off, &extra_fwsize, NULL, maxsize, - (u_char *)extra_fwbuf, WITH_WR_VERIFY); - printf("NAND extra_fw write: 0x%llx offset, 0x%zx bytes written: %s\n", - extra_fw1_off, extra_fwsize, ret ? "ERROR" : "OK"); - if (ret) { - kfree(extra_fwbuf); - goto fwbuf_err; - } - } + /* write Firmware*/ + ret = nandbcb_write_fw(boot_cfg, buf, FW_ALL); + if (ret) + goto err; /* fill fcb */ fcb = kzalloc(sizeof(*fcb), GFP_KERNEL); if (!fcb) { debug("failed to allocate fcb\n"); ret = -ENOMEM; - goto fwbuf_err; + return ret; } + fill_fcb(fcb, boot_cfg); - fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; - fw1_pages = size / mtd->writesize + 1; - if (is_imx8m()) - fw1_pages = (IMX8MQ_SPL_SZ + (mtd->writesize - 1)) / mtd->writesize; - fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages); - - dump_fill_fcb = *fcb; + ret = write_fcb(boot_cfg, fcb); /* fill dbbt */ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); @@ -488,18 +1024,16 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, dbbt = dbbt_page; dbbt->checksum = 0; - dbbt->fingerprint = DBBT_FINGERPRINT2; + dbbt->fingerprint = DBBT_FINGERPRINT; dbbt->version = DBBT_VERSION_1; - ret = dbbt_fill_data(mtd, dbbt_data_page, nr_blks); + ret = fill_dbbt_data(mtd, dbbt_data_page, CONV_TO_BLOCKS(maxsize)); if (ret < 0) goto dbbt_data_page_err; else if (ret > 0) dbbt->dbbtpages = 1; - dump_fill_dbbt = *dbbt; - - /* write fcb and dbbt to nand */ - ret = write_fcb_dbbt_and_readback(mtd, fcb, dbbt, dbbt_data_page, off); + /* write dbbt */ + ret = write_dbbt(boot_cfg, dbbt, dbbt_data_page); if (ret < 0) printf("failed to write FCB/DBBT\n"); @@ -509,8 +1043,6 @@ dbbt_page_err: kfree(dbbt_page); fcb_err: kfree(fcb); -fwbuf_err: - kfree(fwbuf); err: return ret; } @@ -519,69 +1051,98 @@ static int do_nandbcb_bcbonly(int argc, char * const argv[]) { struct fcb_block *fcb; struct dbbt_block *dbbt; - u32 fw_len, fw1_off, fw2_off; struct mtd_info *mtd; + nand_erase_options_t opts; + size_t maxsize; + loff_t off; void *dbbt_page, *dbbt_data_page; - int dev, ret; + int ret; + struct boot_config cfg; - dev = nand_curr_device; - if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) || - (!get_nand_dev_by_index(dev))) { - puts("No devices available\n"); + if (argc < 4) + return CMD_RET_USAGE; + + memset(&cfg, 0, sizeof(struct boot_config)); + if (nandbcb_get_info(argc, argv, &cfg)) return CMD_RET_FAILURE; + + /* only get the partition info */ + if (nandbcb_get_size(2, argv, 1, &cfg)) + return CMD_RET_FAILURE; + + if (nandbcb_set_boot_config(argc, argv, &cfg)) + return CMD_RET_FAILURE; + + mtd = cfg.mtd; + + cfg.boot_stream1_address = simple_strtoul(argv[2], NULL, 16); + cfg.boot_stream1_size = simple_strtoul(argv[3], NULL, 16); + cfg.boot_stream1_size = ALIGN(cfg.boot_stream1_size, mtd->writesize); + + if (argc > 5) { + cfg.boot_stream2_address = simple_strtoul(argv[4], NULL, 16); + cfg.boot_stream2_size = simple_strtoul(argv[5], NULL, 16); + cfg.boot_stream2_size = ALIGN(cfg.boot_stream2_size, + mtd->writesize); } - mtd = get_nand_dev_by_index(dev); + /* sanity check */ + nandbcb_check_space(&cfg); - if (argc < 3) + maxsize = cfg.maxsize; + off = cfg.offset; + + /* erase the previous FCB/DBBT */ + memset(&opts, 0, sizeof(opts)); + opts.offset = off; + opts.length = g_boot_search_stride * 2; + ret = nand_erase_opts(mtd, &opts); + if (ret) { + printf("%s: erase failed (ret = %d)\n", __func__, ret); return CMD_RET_FAILURE; - - fw_len = simple_strtoul(argv[1], NULL, 16); - fw1_off = simple_strtoul(argv[2], NULL, 16); - - if (argc > 3) - fw2_off = simple_strtoul(argv[3], NULL, 16); - else - fw2_off = fw1_off; + } /* fill fcb */ fcb = kzalloc(sizeof(*fcb), GFP_KERNEL); if (!fcb) { - debug("failed to allocate fcb\n"); + printf("failed to allocate fcb\n"); ret = -ENOMEM; return CMD_RET_FAILURE; } - fill_fcb(fcb, mtd, fw1_off / mtd->writesize, - fw2_off / mtd->writesize, fw_len / mtd->writesize); + fill_fcb(fcb, &cfg); + + /* write fcb */ + ret = write_fcb(&cfg, fcb); /* fill dbbt */ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); if (!dbbt_page) { - debug("failed to allocate dbbt_page\n"); + printf("failed to allocate dbbt_page\n"); ret = -ENOMEM; goto fcb_err; } dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL); if (!dbbt_data_page) { - debug("failed to allocate dbbt_data_page\n"); + printf("failed to allocate dbbt_data_page\n"); ret = -ENOMEM; goto dbbt_page_err; } dbbt = dbbt_page; dbbt->checksum = 0; - dbbt->fingerprint = DBBT_FINGERPRINT2; + dbbt->fingerprint = DBBT_FINGERPRINT; dbbt->version = DBBT_VERSION_1; - ret = dbbt_fill_data(mtd, dbbt_data_page, 0); + ret = fill_dbbt_data(mtd, dbbt_data_page, CONV_TO_BLOCKS(maxsize)); if (ret < 0) goto dbbt_data_page_err; else if (ret > 0) dbbt->dbbtpages = 1; - /* write fcb and dbbt to nand */ - ret = write_fcb_dbbt_and_readback(mtd, fcb, dbbt, dbbt_data_page, 0); + /* write dbbt */ + ret = write_dbbt(&cfg, dbbt, dbbt_data_page); + dbbt_data_page_err: kfree(dbbt_data_page); dbbt_page_err: @@ -597,49 +1158,20 @@ fcb_err: return CMD_RET_SUCCESS; } -/* dump data which is planned to be encoded and written to NAND chip */ -void mtd_cfg_dump(void) -{ - u64 blocks; - - printf("MTD CONFIG:\n"); - printf(" %s = %d\n", "data_setup_time", dump_fill_fcb.datasetup); - printf(" %s = %d\n", "data_hold_time", dump_fill_fcb.datahold); - printf(" %s = %d\n", "address_setup_time", dump_fill_fcb.addr_setup); - printf(" %s = %d\n", "data_sample_time", dump_fill_fcb.dsample_time); - - printf("NFC geometry :\n"); - printf("\tECC Strength : %d\n", dump_mtd->ecc_strength); - printf("\tPage Size in Bytes : %d\n", dump_fill_fcb.oob_pagesize); - printf("\tMetadata size : %d\n", dump_fill_fcb.meta_size); - printf("\tECC Chunk Size in byte : %d\n", dump_fill_fcb.ecc_size); - printf("\tECC Chunk count : %d\n", dump_fill_fcb.nr_blocks + 1); - printf("\tBlock Mark Byte Offset : %d\n", dump_fill_fcb.bb_byte); - printf("\tBlock Mark Bit Offset : %d\n", dump_fill_fcb.bb_start_bit); - printf("====================================================\n"); - - printf("mtd: partition #0\n"); - printf(" %s = %d\n", "type", dump_mtd->type); - printf(" %s = %d\n", "flags", dump_mtd->flags); - printf(" %s = %llu\n", "size", dump_nandboot_size); - printf(" %s = %d\n", "erasesize", dump_mtd->erasesize); - printf(" %s = %d\n", "writesize", dump_mtd->writesize); - printf(" %s = %d\n", "oobsize", dump_mtd->oobsize); - blocks = dump_nandboot_size; - do_div(blocks, dump_mtd->erasesize); - printf(" %s = %llu\n", "blocks", blocks); -} - /* dump data which is read from NAND chip */ -void mtd_dump_structure(int i) +void dump_structure(struct boot_config *boot_cfg, struct fcb_block *fcb, + struct dbbt_block *dbbt, void *dbbt_data_page) { - #define P1(x) printf(" %s = 0x%08x\n", #x, dump_nand_fcb[i].x) - printf("FCB %d:\n", i); + int i; + struct mtd_info *mtd = boot_cfg->mtd; + + #define P1(x) printf(" %s = 0x%08x\n", #x, fcb->x) + printf("FCB\n"); P1(checksum); P1(fingerprint); P1(version); #undef P1 - #define P1(x) printf(" %s = %d\n", #x, dump_nand_fcb[i].x) + #define P1(x) printf(" %s = %d\n", #x, fcb->x) P1(datasetup); P1(datahold); P1(addr_setup); @@ -684,169 +1216,214 @@ void mtd_dump_structure(int i) P1(busytimeout); P1(disbbm); P1(spare_offset); +#if !defined(CONFIG_MX6) || defined(CONFIG_MX6SX) || \ + defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) P1(onfi_sync_enable); P1(onfi_sync_speed); P1(onfi_sync_nand_data); P1(disbbm_search); P1(disbbm_search_limit); P1(read_retry_enable); +#endif #undef P1 - #define P1(x) printf(" %s = 0x%08x\n", #x, dump_nand_dbbt[i].x) - printf("DBBT %d:\n", i); + #define P1(x) printf(" %s = 0x%08x\n", #x, dbbt->x) + printf("DBBT :\n"); P1(checksum); P1(fingerprint); P1(version); #undef P1 - #define P1(x) printf(" %s = %d\n", #x, dump_nand_dbbt[i].x) - P1(numberbb); + #define P1(x) printf(" %s = %d\n", #x, dbbt->x) + P1(dbbtpages); #undef P1 - printf("Firmware: image #0 @ 0x%x size 0x%x - available 0x%llx\n", - dump_nand_fcb[i].fw1_start * dump_nand_fcb[i].pagesize, - dump_nand_fcb[i].fw1_pages * dump_nand_fcb[i].pagesize, - dump_nandboot_size - dump_nand_fcb[i].fw1_start * - dump_nand_fcb[i].pagesize); - if (is_imx8m()) { - printf("Extra Firmware: image #0 @ 0x%x size 0x%x - available 0x%llx\n", - dump_nand_fcb[i].fw1_start * - dump_nand_fcb[i].pagesize + dump_mtd->erasesize * - ((IMX8MQ_SPL_SZ + dump_mtd->erasesize - 1) / - dump_mtd->erasesize), - dump_nand_fcb[i].fw1_pages * dump_nand_fcb[i].pagesize, - dump_nandboot_size - - (dump_nand_fcb[i].fw1_start * - dump_nand_fcb[i].pagesize + dump_mtd->erasesize * - ((IMX8MQ_SPL_SZ + dump_mtd->erasesize - 1) / - dump_mtd->erasesize))); + for (i = 0; i < dbbt->dbbtpages; ++i) + printf("%d ", *((u32 *)(dbbt_data_page + i))); + + if (!(plat_config.misc_flags & FIRMWARE_EXTRA_ONE)) { + printf("Firmware: image #0 @ 0x%x size 0x%x\n", + fcb->fw1_start, fcb->fw1_pages * mtd->writesize); + printf("Firmware: image #1 @ 0x%x size 0x%x\n", + fcb->fw2_start, fcb->fw2_pages * mtd->writesize); + } else { + printf("Firmware: image #0 @ 0x%x size 0x%x\n", + fcb->fw1_start, fcb->fw1_pages * mtd->writesize); + printf("Firmware: image #1 @ 0x%x size 0x%x\n", + fcb->fw2_start, fcb->fw2_pages * mtd->writesize); + /* TODO: Add extra image information */ } } +static bool check_fingerprint(void *data, int fingerprint) +{ + int off = 4; + + return (*(int *)(data + off) == fingerprint); +} + +static int nandbcb_dump(struct boot_config *boot_cfg) +{ + int i; + loff_t off; + struct mtd_info *mtd = boot_cfg->mtd; + struct fcb_block fcb, fcb_copy; + struct dbbt_block dbbt, dbbt_copy; + void *dbbt_data_page, *dbbt_data_page_copy; + bool fcb_not_found, dbbt_not_found; + int ret = 0; + + dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_data_page) { + printf("failed to allocate dbbt_data_page\n"); + ret = -ENOMEM; + return ret; + } + + dbbt_data_page_copy = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_data_page_copy) { + printf("failed to allocate dbbt_data_page\n"); + ret = -ENOMEM; + goto dbbt_page_err; + } + + /* read fcb */ + fcb_not_found = 1; + off = 0; + for (i = 0; i < g_boot_search_count; ++i) { + if (fcb_not_found) { + ret = read_fcb(boot_cfg, &fcb, off); + + if (ret < 0) + goto dbbt_page_copy_err; + else if (ret == 1) + continue; + else if (ret == 0) + if (check_fingerprint(&fcb, FCB_FINGERPRINT)) + fcb_not_found = 0; + } else { + ret = read_fcb(boot_cfg, &fcb_copy, off); + + if (ret < 0) + goto dbbt_page_copy_err; + if (memcmp(&fcb, &fcb_copy, + sizeof(struct fcb_block))) { + printf("FCB copies are not identical\n"); + ret = -EINVAL; + goto dbbt_page_copy_err; + } + } + + /* next read location */ + off += g_boot_search_stride; + } + + /* read dbbt*/ + dbbt_not_found = 1; + off = boot_cfg->search_area_size_in_bytes; + for (i = 0; i < g_boot_search_count; ++i) { + if (dbbt_not_found) { + ret = read_dbbt(boot_cfg, &dbbt, dbbt_data_page, off); + + if (ret < 0) + goto dbbt_page_copy_err; + else if (ret == 1) + continue; + else if (ret == 0) + if (check_fingerprint(&dbbt, DBBT_FINGERPRINT)) + dbbt_not_found = 0; + } else { + ret = read_dbbt(boot_cfg, &dbbt_copy, + dbbt_data_page_copy, off); + + if (ret < 0) + goto dbbt_page_copy_err; + if (memcmp(&dbbt, &dbbt_copy, + sizeof(struct dbbt_block))) { + printf("DBBT copies are not identical\n"); + ret = -EINVAL; + goto dbbt_page_copy_err; + } + if (dbbt.dbbtpages > 0 && + memcmp(dbbt_data_page, dbbt_data_page_copy, + mtd->writesize)) { + printf("DBBT data copies are not identical\n"); + ret = -EINVAL; + goto dbbt_page_copy_err; + } + } + + /* next read location */ + off += g_boot_search_stride; + } + + dump_structure(boot_cfg, &fcb, &dbbt, dbbt_data_page); + +dbbt_page_copy_err: + kfree(dbbt_data_page_copy); +dbbt_page_err: + kfree(dbbt_data_page); + + return ret; +} + static int do_nandbcb_dump(int argc, char * const argv[]) { - int num; - int stride; - int search_area_sz; - bool bab_block_table[BOOT_SEARCH_COUNT]; - int bab_block_flag; + struct boot_config cfg; + int ret; if (argc != 2) return CMD_RET_USAGE; - switch (argv[1][0]) { - case '0': - num = 0; - break; - case '1': - num = 1; - break; - default: - return CMD_RET_USAGE; - } + memset(&cfg, 0, sizeof(struct boot_config)); + if (nandbcb_get_info(argc, argv, &cfg)) + return CMD_RET_FAILURE; - /* dump data which is planned to be encoded and written to NAND chip */ - mtd_cfg_dump(); + if (nandbcb_get_size(argc, argv, 1, &cfg)) + return CMD_RET_FAILURE; - stride = dump_mtd->erasesize; - search_area_sz = BOOT_SEARCH_COUNT * stride; - printf("stride: %x, search_area_sz: %x\n", stride, search_area_sz); + if (nandbcb_set_boot_config(argc, argv, &cfg)) + return CMD_RET_FAILURE; - bab_block_flag = 0; - for (int i = 0; i < BOOT_SEARCH_COUNT; i++) { - if (mtd_block_isbad(dump_mtd, - (loff_t)(dump_mtd->erasesize * i))) { - bab_block_table[i] = 1; - bab_block_flag = 1; - continue; - } - bab_block_table[i] = 0; - if (!memcmp(dump_nand_fcb + i, &dump_fill_fcb, - sizeof(dump_fill_fcb))) { - printf("mtd: found FCB%d candidate version %08x @%d:0x%x\n", - i, dump_nand_fcb[i].version, i, dump_fcb_off[i]); - } else { - printf("mtd: FCB%d not found\n", i); - } - } + ret = nandbcb_dump(&cfg); + if (ret) + return ret; - for (int i = 0; i < BOOT_SEARCH_COUNT; i++) { - if (mtd_block_isbad(dump_mtd, - (loff_t)(dump_mtd->erasesize * i))) - continue; - - if (!memcmp(dump_nand_dbbt + i, &dump_fill_dbbt, - sizeof(dump_fill_dbbt))) { - printf("mtd: DBBT%d found\n", i); - printf("mtd: Valid DBBT%d found @%d:0x%x\n", - i, i, dump_dbbt_off[i]); - - } else { - printf("mtd: DBBT%d not found\n", i); - } - } - if (bab_block_flag == 0) { - printf("no bad block found, dbbt: %08x\n", - dump_fill_dbbt.fingerprint); - } else { - for (int i = 0; i < BOOT_SEARCH_COUNT; i++) { - if (bab_block_table[i] == 1) - printf("mtd: bad block @ 0x%llx\n", - (loff_t)(dump_mtd->erasesize * i)); - } - } - - /* dump data which is read from NAND chip */ - if (num > (BOOT_SEARCH_COUNT - 1)) - return CMD_RET_USAGE; - - if (bab_block_table[num] == 1) { - printf("mtd: bad block @ 0x%llx (FCB - DBBT)\n", - (loff_t)(dump_mtd->erasesize * num)); - return CMD_RET_USAGE; - } - - mtd_dump_structure(num); - - return 0; + return ret; } -static int do_nandbcb_update(int argc, char * const argv[]) +static int do_nandbcb_init(int argc, char * const argv[]) { - struct mtd_info *mtd; - loff_t addr, offset, size, maxsize; - char *endp; u_char *buf; - int dev; + size_t size; + loff_t addr; + char *endp; int ret; + struct boot_config cfg; if (argc != 4) return CMD_RET_USAGE; - dev = nand_curr_device; - if (dev < 0) { - printf("failed to get nand_curr_device, run nand device\n"); + memset(&cfg, 0, sizeof(struct boot_config)); + if (nandbcb_get_info(argc, argv, &cfg)) + return CMD_RET_FAILURE; + + if (nandbcb_get_size(argc, argv, 2, &cfg)) + return CMD_RET_FAILURE; + size = cfg.boot_stream1_size; + + if (nandbcb_set_boot_config(argc, argv, &cfg)) return CMD_RET_FAILURE; - } addr = simple_strtoul(argv[1], &endp, 16); if (*argv[1] == 0 || *endp != 0) return CMD_RET_FAILURE; - mtd = get_nand_dev_by_index(dev); - if (mtd_arg_off_size(argc - 2, argv + 2, &dev, &offset, &size, - &maxsize, MTD_DEV_TYPE_NAND, mtd->size)) - return CMD_RET_FAILURE; - - /* dump_mtd and dump_nandboot_size are used for "nandbcb dump [-v]" */ - dump_mtd = mtd; - dump_nandboot_size = maxsize; - buf = map_physmem(addr, size, MAP_WRBACK); if (!buf) { puts("failed to map physical memory\n"); return CMD_RET_FAILURE; } - ret = nandbcb_update(mtd, offset, size, maxsize, buf); + ret = nandbcb_init(&cfg, buf); return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE; } @@ -860,12 +1437,36 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, if (argc < 3) goto usage; + /* check the platform config first */ + if (is_mx6sx()) { + plat_config = imx6sx_plat_config; + } else if (is_mx7()) { + plat_config = imx7d_plat_config; + } else if (is_mx6ul() || is_mx6ull()) { + plat_config = imx6ul_plat_config; + } else if (is_mx6() && !is_mx6sx() && !is_mx6ul() && !is_mx6ull()) { + plat_config = imx6qdl_plat_config; + } else if (is_imx8mq()) { + plat_config = imx8mq_plat_config; + } else if (is_imx8mm()) { + plat_config = imx8mm_plat_config; + } else if (is_imx8mn()) { + plat_config = imx8mn_plat_config; + } else if (is_imx8qm() || is_imx8qxp()) { + plat_config = imx8q_plat_config; + } else { + printf("ERROR: Unknown platform\n"); + return CMD_RET_FAILURE; + } + + /* TODO: set the boot search count if need to read from fuse */ + cmd = argv[1]; --argc; ++argv; - if (strcmp(cmd, "update") == 0) { - ret = do_nandbcb_update(argc, argv); + if (strcmp(cmd, "init") == 0) { + ret = do_nandbcb_init(argc, argv); goto done; } @@ -888,19 +1489,19 @@ usage: #ifdef CONFIG_SYS_LONGHELP static char nandbcb_help_text[] = - "update addr off|partition len - update 'len' bytes starting at\n" + "init addr off|partition len - update 'len' bytes starting at\n" " 'off|part' to memory address 'addr', skipping bad blocks\n" - "bcbonly fw-size fw1-off [fw2-off] - write only BCB (FCB and DBBT)\n" - " where `fw-size` is fw sizes in bytes, `fw1-off`\n" + "nandbcb bcbonly off|partition fw1-off fw1-size [fw2-off fw2-size]\n" + " - write BCB only (FCB and DBBT)\n" + " where `fwx-size` is fw sizes in bytes, `fw1-off`\n" " and `fw2-off` - firmware offsets\n" " FIY, BCB isn't erased automatically, so mtd erase should\n" " be called in advance before writing new BCB:\n" " > mtd erase mx7-bcb\n" - "nandbcb dump num - verify/dump boot structures\n" - " 'num' can be set to 0 and 1"; + "nandbcb dump off|partition - dump/verify boot structures\n"; #endif -U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb, - "i.MX6/i.MX7 NAND Boot Control Blocks write", +U_BOOT_CMD(nandbcb, 7, 1, do_nandbcb, + "i.MX NAND Boot Control Blocks write", nandbcb_help_text ); From f797fe84fc8e609443a1352bd816ee9cf328416d Mon Sep 17 00:00:00 2001 From: Han Xu Date: Tue, 5 May 2020 22:04:04 +0800 Subject: [PATCH 71/82] nandbcb: read boot search count from fuse for imx8qxp add support for imx8qxp to read boot search count from fuse in nandbcb Signed-off-by: Han Xu Signed-off-by: Peng Fan --- arch/arm/mach-imx/cmd_nandbcb.c | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index ab12b1f1cf2..94cae146ced 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "../../../cmd/legacy-mtd-utils.h" @@ -1260,6 +1261,35 @@ static bool check_fingerprint(void *data, int fingerprint) return (*(int *)(data + off) == fingerprint); } +static int fuse_to_search_count(u32 bank, u32 word, u32 mask, u32 off) +{ + int err; + u32 val; + int ret; + + /* by default, the boot search count from fuse should be 2 */ + err = fuse_read(bank, word, &val); + if (err) + return 2; + + val = (val & mask) >> off; + + switch (val) { + case 0: + ret = 2; + break; + case 1: + case 2: + case 3: + ret = 1 << val; + break; + default: + ret = 2; + } + + return ret; +} + static int nandbcb_dump(struct boot_config *boot_cfg) { int i; @@ -1459,7 +1489,14 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - /* TODO: set the boot search count if need to read from fuse */ + if (plat_config.misc_flags & BT_SEARCH_CNT_FROM_FUSE) { + if (is_imx8qxp()) { + g_boot_search_count = fuse_to_search_count(0, 720, + 0xc0, 6); + printf("search count set to %d from fuse\n", + g_boot_search_count); + } + } cmd = argv[1]; --argc; From bf9382addf94c9b90033a1eac5522afae9b7a0d7 Mon Sep 17 00:00:00 2001 From: Han Xu Date: Wed, 6 May 2020 20:59:19 +0800 Subject: [PATCH 72/82] mtd: nand: raw: mxs_nand changes for nandbcb Add more BCH setting mode and remove the unnecessary platform constrain Signed-off-by: Han Xu Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 43 ++++++++++++++++++++++++++++++--- include/mxs_nand.h | 3 ++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index c3191feca8e..e3516cd141c 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -710,7 +710,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; - if ((is_mx7() || is_imx8m()) && nand_info->en_randomizer) { + if (nand_info->en_randomizer) { d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | GPMI_ECCCTRL_RANDOMIZER_TYPE2; d->cmd.pio_words[3] |= (page % 256) << 16; @@ -867,7 +867,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; - if ((is_mx7() || is_imx8m()) && nand_info->en_randomizer) { + if (nand_info->en_randomizer) { d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | GPMI_ECCCTRL_RANDOMIZER_TYPE2; /* @@ -1489,7 +1489,7 @@ void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l) /* * Set BCH to specific layout used by ROM bootloader to read FCB. */ -void mxs_nand_mode_fcb(struct mtd_info *mtd) +void mxs_nand_mode_fcb_62bit(struct mtd_info *mtd) { u32 tmp; struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; @@ -1522,6 +1522,43 @@ void mxs_nand_mode_fcb(struct mtd_info *mtd) writel(tmp, &bch_regs->hw_bch_flash0layout1); } +/* + * Set BCH to specific layout used by ROM bootloader to read FCB. + */ +void mxs_nand_mode_fcb_40bit(struct mtd_info *mtd) +{ + u32 tmp; + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + struct nand_chip *nand = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + + /* no randomizer in this setting*/ + nand_info->en_randomizer = 0; + + mtd->writesize = 1024; + mtd->oobsize = 1576 - 1024; + + /* 8 ecc_chunks_*/ + tmp = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; + /* 32 bytes for metadata */ + tmp |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; + /* using ECC40 level to be performed */ + tmp |= 0x14 << BCH_FLASHLAYOUT0_ECC0_OFFSET; + /* 0x20 * 4 bytes of the data0 block */ + tmp |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET; + tmp |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; + writel(tmp, &bch_regs->hw_bch_flash0layout0); + + /* 1024 for data + 552 for OOB */ + tmp = 1576 << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; + /* using ECC40 level to be performed */ + tmp |= 0x14 << BCH_FLASHLAYOUT1_ECCN_OFFSET; + /* 0x20 * 4 bytes of the data0 block */ + tmp |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET; + tmp |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; + writel(tmp, &bch_regs->hw_bch_flash0layout1); +} + /* * Restore BCH to normal settings. */ diff --git a/include/mxs_nand.h b/include/mxs_nand.h index 21d68a909d7..c0cefaca90b 100644 --- a/include/mxs_nand.h +++ b/include/mxs_nand.h @@ -95,7 +95,8 @@ int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info); int mxs_nand_init_spl(struct nand_chip *nand); int mxs_nand_setup_ecc(struct mtd_info *mtd); -void mxs_nand_mode_fcb(struct mtd_info *mtd); +void mxs_nand_mode_fcb_62bit(struct mtd_info *mtd); +void mxs_nand_mode_fcb_40bit(struct mtd_info *mtd); void mxs_nand_mode_normal(struct mtd_info *mtd); u32 mxs_nand_mark_byte_offset(struct mtd_info *mtd); u32 mxs_nand_mark_bit_offset(struct mtd_info *mtd); From f44afd546f6236479581469e1fb969c9ce9f9eac Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:37 +0800 Subject: [PATCH 73/82] imx: imx8qm/qxp: reserving DDR memory for M4 The DDR memory from 0x88000000 to 0x8FFFFFFF is assigned to M4 on QM and QXP. The M4 can allocate this memory by two ways, in SCD or u-boot. In this patch, u-boot addes the memory reserve node to DTB to pass the info to kernel, no matter the M4 memory is reserved in SCD or u-boot. So kernel won't access M4 reserved memory. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/Kconfig | 8 ++++++++ arch/arm/mach-imx/imx8/fdt.c | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index 1f8add015f4..69149d3cd51 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -41,6 +41,14 @@ config IMX_CONTAINER_CFG This is to specific the cfg file for generating container image which will be loaded by SPL. +config BOOTAUX_RESERVED_MEM_BASE + hex "i.MX auxiliary core dram memory base" + default 0 + +config BOOTAUX_RESERVED_MEM_SIZE + hex "i.MX auxiliary core dram memory size" + default 0 + choice prompt "i.MX8 board select" optional diff --git a/arch/arm/mach-imx/imx8/fdt.c b/arch/arm/mach-imx/imx8/fdt.c index 65c8ac1a7e2..59936453786 100644 --- a/arch/arm/mach-imx/imx8/fdt.c +++ b/arch/arm/mach-imx/imx8/fdt.c @@ -8,6 +8,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -279,6 +280,15 @@ static int ft_add_optee_node(void *fdt, bd_t *bd) int ft_system_setup(void *blob, bd_t *bd) { int ret; + int off; + + if (CONFIG_BOOTAUX_RESERVED_MEM_BASE) { + off = fdt_add_mem_rsv(blob, CONFIG_BOOTAUX_RESERVED_MEM_BASE, + CONFIG_BOOTAUX_RESERVED_MEM_SIZE); + if (off < 0) + printf("Failed to reserve memory for bootaux: %s\n", + fdt_strerror(off)); + } update_fdt_with_owned_resources(blob); From 7c351ff5e0e50359d9feb49272650bd01417f721 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 5 May 2020 20:28:38 +0800 Subject: [PATCH 74/82] imx: imx8qm/qxp: Fix issue in get_effective_memsize When Trusty OS allocates the mem region from 0xfe0000000-0xffffffff, the get_effective_memsize does not return correct memory size. There is a check in get_effective_memsize to find the memreg where the u-boot is running, and return the size of that memreg as the result of get_effective_memsize. When using aligned start, the value is 0x80200000 since it is 2MB aligned. Thus the finding of memreg will fail and return the PHYS_SDRAM_1_SIZE because u-boot text base is 0x80020000. This cause u-boot is relocated to the high memory where has been occupied by Trusty OS. Reviewed-by: Peng Fan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index f87276e8eab..2c79bd00915 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -223,7 +223,7 @@ static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, phys_size_t get_effective_memsize(void) { sc_rm_mr_t mr; - sc_faddr_t start, end, end1; + sc_faddr_t start, end, end1, start_aligned; int err; end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE; @@ -231,9 +231,9 @@ phys_size_t get_effective_memsize(void) for (mr = 0; mr < 64; mr++) { err = get_owned_memreg(mr, &start, &end); if (!err) { - start = roundup(start, MEMSTART_ALIGNMENT); + start_aligned = roundup(start, MEMSTART_ALIGNMENT); /* Too small memory region, not use it */ - if (start > end) + if (start_aligned > end) continue; /* Find the memory region runs the U-Boot */ From 8103767256dde5e0ca949790f0896268ae0832d3 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:39 +0800 Subject: [PATCH 75/82] imx: imx8qm/qxp: add get_board_serial Add get_board_serial support, the info could be got from fuse. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/cpu.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 2c79bd00915..3bd0dee0251 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -19,6 +19,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -162,6 +163,37 @@ enum boot_device get_boot_device(void) return boot_dev; } +#ifdef CONFIG_SERIAL_TAG +#define FUSE_UNIQUE_ID_WORD0 16 +#define FUSE_UNIQUE_ID_WORD1 17 +void get_board_serial(struct tag_serialnr *serialnr) +{ + sc_err_t err; + u32 val1 = 0, val2 = 0; + u32 word1, word2; + + if (!serialnr) + return; + + word1 = FUSE_UNIQUE_ID_WORD0; + word2 = FUSE_UNIQUE_ID_WORD1; + + err = sc_misc_otp_fuse_read(-1, word1, &val1); + if (err != SC_ERR_NONE) { + printf("%s fuse %d read error: %d\n", __func__, word1, err); + return; + } + + err = sc_misc_otp_fuse_read(-1, word2, &val2); + if (err != SC_ERR_NONE) { + printf("%s fuse %d read error: %d\n", __func__, word2, err); + return; + } + serialnr->low = val1; + serialnr->high = val2; +} +#endif /*CONFIG_SERIAL_TAG*/ + #ifdef CONFIG_ENV_IS_IN_MMC __weak int board_mmc_get_env_dev(int devno) { From 231401de2eab8b8e503eb21afb6579ec24f872c6 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:40 +0800 Subject: [PATCH 76/82] imx: imx8qm/imx8qxp: Power down the resources before SPL jump to u-boot Make sure that all devices that are powered up by SPL are powered down before entering into the u-boot. Otherwise the subsystem/device will never be powered down by SCFW, due to SPL and u-boot are in different partitions. Benefiting from power domain driver, this patch implements the function "imx8_power_off_pd_devices" to power off all active devices. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sys_proto.h | 1 + board/freescale/imx8qm_mek/spl.c | 6 ++++ board/freescale/imx8qxp_mek/spl.c | 6 ++++ .../power/domain/imx8-power-domain-legacy.c | 35 +++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h index fc33e6ed184..2a08ef939d3 100644 --- a/arch/arm/include/asm/arch-imx8/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8/sys_proto.h @@ -28,3 +28,4 @@ int print_bootinfo(void); int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate); int imx8_power_domain_lookup_name(const char *name, struct power_domain *power_domain); +void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size); diff --git a/board/freescale/imx8qm_mek/spl.c b/board/freescale/imx8qm_mek/spl.c index cb4006eb2a4..ba99002cf29 100644 --- a/board/freescale/imx8qm_mek/spl.c +++ b/board/freescale/imx8qm_mek/spl.c @@ -12,6 +12,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -37,6 +38,11 @@ void spl_board_init(void) puts("Normal Boot\n"); } +void spl_board_prepare_for_boot(void) +{ + imx8_power_off_pd_devices(NULL, 0); +} + #ifdef CONFIG_SPL_LOAD_FIT int board_fit_config_name_match(const char *name) { diff --git a/board/freescale/imx8qxp_mek/spl.c b/board/freescale/imx8qxp_mek/spl.c index e4e4cbe7163..32b61095b06 100644 --- a/board/freescale/imx8qxp_mek/spl.c +++ b/board/freescale/imx8qxp_mek/spl.c @@ -17,6 +17,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -55,6 +56,11 @@ void spl_board_init(void) puts("Normal Boot\n"); } +void spl_board_prepare_for_boot(void) +{ + imx_power_off_pd_devices(NULL, 0); +} + #ifdef CONFIG_SPL_LOAD_FIT int board_fit_config_name_match(const char *name) { diff --git a/drivers/power/domain/imx8-power-domain-legacy.c b/drivers/power/domain/imx8-power-domain-legacy.c index f679df9e5d1..7ba4056e2d5 100644 --- a/drivers/power/domain/imx8-power-domain-legacy.c +++ b/drivers/power/domain/imx8-power-domain-legacy.c @@ -11,6 +11,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -19,6 +20,40 @@ struct imx8_power_domain_priv { bool state_on; }; +static bool check_device_power_off(struct udevice *dev, + const char *permanent_on_devices[], + int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (!strcmp(dev->name, permanent_on_devices[i])) + return false; + } + + return true; +} + +void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size) +{ + struct udevice *dev; + struct power_domain pd; + + for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev; + uclass_find_next_device(&dev)) { + if (!device_active(dev)) + continue; + /* + * Power off active pd devices except the permanent + * power on devices + */ + if (check_device_power_off(dev, permanent_on_devices, size)) { + pd.dev = dev; + power_domain_off(&pd); + } + } +} + int imx8_power_domain_lookup_name(const char *name, struct power_domain *power_domain) { From 6aead23323bee1d780fd0b9696f512194458e379 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:41 +0800 Subject: [PATCH 77/82] imx: imx8qm/qxp: Recover SPL data section for partition reboot When doing partition reboot, the boot image won't be reloaded by ROM, it is just CPU reset to boot entry. The SW has to keep the boot image inside the RAM unchanged. It includes both the TEXT section and DATA section. For SPL, the problem is DATA section will be updated at runtime, so in next partition reboot the data is not same as the initial value from cold boot. If any code depends on the initial value, then it will have problem. This patch introduces a mechanism to recover the data section for partition reboot. It adds a new section in image for saving data section. When from cold boot, the data section will be saved to that new section at SPL early phase. When from partition reboot, the data section will be restored from the new section. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/cpu/armv8/Kconfig | 6 ++++++ arch/arm/cpu/armv8/Makefile | 4 ++++ arch/arm/cpu/armv8/spl_data.c | 29 +++++++++++++++++++++++++++++ arch/arm/cpu/armv8/u-boot-spl.lds | 8 ++++++++ arch/arm/mach-imx/imx8/Kconfig | 2 ++ arch/arm/mach-imx/imx8/cpu.c | 5 +++++ include/spl.h | 1 + 7 files changed, 55 insertions(+) create mode 100644 arch/arm/cpu/armv8/spl_data.c diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index 16c83e86149..3655990772c 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -76,6 +76,12 @@ config SPL_ARMV8_SEC_FIRMWARE_SUPPORT help Say Y here to support this framework in SPL phase. +config SPL_RECOVER_DATA_SECTION + bool "save/restore SPL data section" + help + Say Y here to save SPL data section for cold boot, and restore + at warm boot in SPL phase. + config SEC_FIRMWARE_ARMV8_PSCI bool "PSCI implementation in secure monitor firmware" depends on ARMV8_SEC_FIRMWARE_SUPPORT || SPL_ARMV8_SEC_FIRMWARE_SUPPORT diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index b349b13f497..2e48df0eb98 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -30,6 +30,10 @@ obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o endif obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o +ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SPL_RECOVER_DATA_SECTION) += spl_data.o +endif + obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/ obj-$(CONFIG_S32V234) += s32v234/ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/ diff --git a/arch/arm/cpu/armv8/spl_data.c b/arch/arm/cpu/armv8/spl_data.c new file mode 100644 index 00000000000..8fd986a67a2 --- /dev/null +++ b/arch/arm/cpu/armv8/spl_data.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 NXP + */ + +#include +#include + +char __data_save_start[0] __section(.__data_save_start); +char __data_save_end[0] __section(.__data_save_end); + +u32 cold_reboot_flag = 1; + +void spl_save_restore_data(void) +{ + u32 data_size = __data_save_end - __data_save_start; + + if (cold_reboot_flag == 1) { + /* Save data section to data_save section */ + memcpy(__data_save_start, __data_save_start - data_size, + data_size); + } else { + /* Restore the data_save section to data section */ + memcpy(__data_save_start - data_size, __data_save_start, + data_size); + } + + cold_reboot_flag++; +} diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds index ccbf359bd11..0e67ab09d77 100644 --- a/arch/arm/cpu/armv8/u-boot-spl.lds +++ b/arch/arm/cpu/armv8/u-boot-spl.lds @@ -38,6 +38,14 @@ SECTIONS *(.data*) } >.sram +#ifdef CONFIG_SPL_RECOVER_DATA_SECTION + .data_save : { + *(.__data_save_start) + . = SIZEOF(.data); + *(.__data_save_end) + } >.sram +#endif + .u_boot_list : { . = ALIGN(8); KEEP(*(SORT(.u_boot_list*))); diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index 69149d3cd51..9d1f73dfc70 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -18,11 +18,13 @@ config MU_BASE_SPL config IMX8QM select IMX8 select SUPPORT_SPL + select SPL_RECOVER_DATA_SECTION bool config IMX8QXP select IMX8 select SUPPORT_SPL + select SPL_RECOVER_DATA_SECTION bool config SYS_SOC diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 3bd0dee0251..e03193cb4ca 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,10 @@ struct pass_over_info_t *get_pass_over_info(void) int arch_cpu_init(void) { +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION) + spl_save_restore_data(); +#endif + #ifdef CONFIG_SPL_BUILD struct pass_over_info_t *pass_over; diff --git a/include/spl.h b/include/spl.h index 6bf9fd8bebb..90395fedb0f 100644 --- a/include/spl.h +++ b/include/spl.h @@ -582,4 +582,5 @@ void spl_perform_fixups(struct spl_image_info *spl_image); */ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size); +void spl_save_restore_data(void); #endif From 42b26ddc80266cbe9d56526b198afed0b433bfb2 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 5 May 2020 20:28:42 +0800 Subject: [PATCH 78/82] imx8: Select boot device dynamically For fspi build, we will enable both SPL NOR support and SPL SPI support. SPL will dynamically check the resource owner then select corresponding boot device. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/cpu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index e03193cb4ca..103a29746a6 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -22,6 +22,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -573,3 +574,14 @@ u32 get_cpu_rev(void) return (id << 12) | rev; } + +void board_boot_order(u32 *spl_boot_list) +{ + spl_boot_list[0] = spl_boot_device(); + + if (spl_boot_list[0] == BOOT_DEVICE_SPI) { + /* Check whether we own the flexspi0, if not, use NOR boot */ + if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0)) + spl_boot_list[0] = BOOT_DEVICE_NOR; + } +} From ed5b253d0e3e6290e63afdb37b71ce9503b6bd5f Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:43 +0800 Subject: [PATCH 79/82] imx: imx8qm/qxp: check whether m4 partition booted Add code to check m4 partition booted or not, we will use this to runtime set device tree file that passed to Linux Kernel. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sys_proto.h | 1 + arch/arm/mach-imx/imx8/cpu.c | 30 ++++++++++++++++++++++ board/freescale/imx8qxp_mek/spl.c | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-imx8/sys_proto.h b/arch/arm/include/asm/arch-imx8/sys_proto.h index 2a08ef939d3..6f1fc8f999d 100644 --- a/arch/arm/include/asm/arch-imx8/sys_proto.h +++ b/arch/arm/include/asm/arch-imx8/sys_proto.h @@ -29,3 +29,4 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate); int imx8_power_domain_lookup_name(const char *name, struct power_domain *power_domain); void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size); +bool m4_parts_booted(void); diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 103a29746a6..6d7b17b4647 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -585,3 +585,33 @@ void board_boot_order(u32 *spl_boot_list) spl_boot_list[0] = BOOT_DEVICE_NOR; } } + +bool m4_parts_booted(void) +{ + sc_rm_pt_t m4_parts[2]; + int err; + + err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]); + if (err) { + printf("%s get resource [%d] owner error: %d\n", __func__, + SC_R_M4_0_PID0, err); + return false; + } + + if (sc_pm_is_partition_started(-1, m4_parts[0])) + return true; + + if (is_imx8qm()) { + err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]); + if (err) { + printf("%s get resource [%d] owner error: %d\n", + __func__, SC_R_M4_1_PID0, err); + return false; + } + + if (sc_pm_is_partition_started(-1, m4_parts[1])) + return true; + } + + return false; +} diff --git a/board/freescale/imx8qxp_mek/spl.c b/board/freescale/imx8qxp_mek/spl.c index 32b61095b06..eefee64ab18 100644 --- a/board/freescale/imx8qxp_mek/spl.c +++ b/board/freescale/imx8qxp_mek/spl.c @@ -58,7 +58,7 @@ void spl_board_init(void) void spl_board_prepare_for_boot(void) { - imx_power_off_pd_devices(NULL, 0); + imx8_power_off_pd_devices(NULL, 0); } #ifdef CONFIG_SPL_LOAD_FIT From e825d3089abbca850d8370bcbeaa8dc6e5d4a69a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:44 +0800 Subject: [PATCH 80/82] imx: imx8qm: update fdt_file according to m4 state Update fdt_file according to m4 parts state Signed-off-by: Peng Fan --- board/freescale/imx8qm_mek/imx8qm_mek.c | 13 +++++++++++++ include/configs/imx8qm_mek.h | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/board/freescale/imx8qm_mek/imx8qm_mek.c b/board/freescale/imx8qm_mek/imx8qm_mek.c index c9b9b2547ea..c0cae3540fb 100644 --- a/board/freescale/imx8qm_mek/imx8qm_mek.c +++ b/board/freescale/imx8qm_mek/imx8qm_mek.c @@ -123,10 +123,23 @@ int board_mmc_get_env_dev(int devno) int board_late_init(void) { + char *fdt_file; + bool m4_booted; + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG env_set("board_name", "MEK"); env_set("board_rev", "iMX8QM"); #endif + fdt_file = env_get("fdt_file"); + m4_booted = m4_parts_booted(); + + if (fdt_file && !strcmp(fdt_file, "undefined")) { + if (m4_booted) + env_set("fdt_file", "imx8qm-mek-rpmsg.dtb"); + else + env_set("fdt_file", "imx8qm-mek.dtb"); + } + return 0; } diff --git a/include/configs/imx8qm_mek.h b/include/configs/imx8qm_mek.h index 97170dc9494..22d80f1747b 100644 --- a/include/configs/imx8qm_mek.h +++ b/include/configs/imx8qm_mek.h @@ -70,7 +70,7 @@ "fdt_addr=0x83000000\0" \ "fdt_high=0xffffffffffffffff\0" \ "boot_fdt=try\0" \ - "fdt_file=imx8qm-mek.dtb\0" \ + "fdt_file=undefined\0" \ "initrd_addr=0x83800000\0" \ "initrd_high=0xffffffffffffffff\0" \ "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ From a6c36f15ebc5e004c5914bb55ef93bb453e640db Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:45 +0800 Subject: [PATCH 81/82] imx: imx8qxp: update fdt_file according to m4 state Update fdt_file according to m4 parts state Signed-off-by: Peng Fan --- board/freescale/imx8qxp_mek/imx8qxp_mek.c | 13 +++++++++++++ include/configs/imx8qxp_mek.h | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c index 93f0cd827c3..dc9ffaabf20 100644 --- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c +++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c @@ -146,10 +146,23 @@ int board_mmc_get_env_dev(int devno) int board_late_init(void) { + char *fdt_file; + bool m4_booted; + #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG env_set("board_name", "MEK"); env_set("board_rev", "iMX8QXP"); #endif + fdt_file = env_get("fdt_file"); + m4_booted = m4_parts_booted(); + + if (fdt_file && !strcmp(fdt_file, "undefined")) { + if (m4_booted) + env_set("fdt_file", "imx8qxp-mek-rpmsg.dtb"); + else + env_set("fdt_file", "imx8qxp-mek.dtb"); + } + return 0; } diff --git a/include/configs/imx8qxp_mek.h b/include/configs/imx8qxp_mek.h index 0aaca3325bd..341e93e61e7 100644 --- a/include/configs/imx8qxp_mek.h +++ b/include/configs/imx8qxp_mek.h @@ -69,7 +69,7 @@ "fdt_addr=0x83000000\0" \ "fdt_high=0xffffffffffffffff\0" \ "boot_fdt=try\0" \ - "fdt_file=imx8qxp-mek.dtb\0" \ + "fdt_file=undefined\0" \ "initrd_addr=0x83800000\0" \ "initrd_high=0xffffffffffffffff\0" \ "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ From d52a03b130565e6b01dcbe656ebeb611d5ee1aa1 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 5 May 2020 20:28:46 +0800 Subject: [PATCH 82/82] imx8: cpu: check resource owned after sid fail When we create software partition, we still need let parent partition to configure sid, so move the check after sid failed. Acked-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/fdt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/imx8/fdt.c b/arch/arm/mach-imx/imx8/fdt.c index 59936453786..9a6822a9291 100644 --- a/arch/arm/mach-imx/imx8/fdt.c +++ b/arch/arm/mach-imx/imx8/fdt.c @@ -106,13 +106,13 @@ static int config_smmu_resource_sid(int rsrc, int sid) { int err; - if (!check_owned_resource(rsrc)) { - printf("%s rsrc[%d] not owned\n", __func__, rsrc); - return -1; - } err = sc_rm_set_master_sid(-1, rsrc, sid); debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err); if (err != SC_ERR_NONE) { + if (!check_owned_resource(rsrc)) { + printf("%s rsrc[%d] not owned\n", __func__, rsrc); + return -1; + } pr_err("fail set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err); return -EINVAL; }