summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2022-09-19 08:38:32 -0400
committerTom Rini <[email protected]>2022-09-19 08:38:32 -0400
commitc1db6be55da2fd157118425cb95145c4e737a908 (patch)
treed33d29bb29c638b14d46a7f2e1dafff015c3acc9 /drivers
parenta0759684e015bd7252be3af508c0fcfdbb8ec5dc (diff)
parentcc74cab86a5f32db93a9f0dc7bc46fa5e83f4f3e (diff)
Merge tag 'u-boot-imx-20220919' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20220919 ------------------- CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/13500 - Fix imx8mn-beacon-kit-u-boot - Merged Purism - imxrt1170 (already merged in u-boot-imx) - Fixes in crypto FSL - Toradex : fixes Verdin - Serial Driver: fixes when not used as console - DH Boards : fixes + USB - Fix CONFIG_SYS_MALLOC_F_LEN (Kconfig) - Add imx6ulz_smm_m2
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/imx/Kconfig16
-rw-r--r--drivers/clk/imx/Makefile1
-rw-r--r--drivers/clk/imx/clk-imxrt1170.c221
-rw-r--r--drivers/clk/imx/clk-pllv3.c56
-rw-r--r--drivers/clk/imx/clk.h1
-rw-r--r--drivers/crypto/fsl/fsl_hash.c22
-rw-r--r--drivers/ddr/imx/imx8m/ddrphy_utils.c369
-rw-r--r--drivers/ram/imxrt_sdram.c9
-rw-r--r--drivers/serial/serial_mxc.c15
9 files changed, 331 insertions, 379 deletions
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 04d252a1e03..abcb19ce6d5 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -124,3 +124,19 @@ config CLK_IMXRT1050
select CLK_COMPOSITE_CCF
help
This enables support clock driver for i.MXRT1050 platforms.
+
+config SPL_CLK_IMXRT1170
+ bool "SPL clock support for i.MXRT1170"
+ depends on ARCH_IMXRT && SPL
+ select SPL_CLK
+ select SPL_CLK_CCF
+ help
+ This enables SPL DM/DTS support for clock driver in i.MXRT1170.
+
+config CLK_IMXRT1170
+ bool "Clock support for i.MXRT1170"
+ depends on ARCH_IMXRT
+ select CLK
+ select CLK_CCF
+ help
+ This enables support clock driver for i.MXRT1170 platforms.
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index c5766901f2b..b9c197f952e 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1170) += clk-imxrt1170.o
diff --git a/drivers/clk/imx/clk-imxrt1170.c b/drivers/clk/imx/clk-imxrt1170.c
new file mode 100644
index 00000000000..077dd1bf02d
--- /dev/null
+++ b/drivers/clk/imx/clk-imxrt1170.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022
+ * Author(s): Jesse Taube <[email protected]>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <log.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <dt-bindings/clock/imxrt1170-clock.h>
+
+#include "clk.h"
+
+static ulong imxrt1170_clk_get_rate(struct clk *clk)
+{
+ struct clk *c;
+ int ret;
+
+ debug("%s(#%lu)\n", __func__, clk->id);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ return clk_get_rate(c);
+}
+
+static ulong imxrt1170_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct clk *c;
+ int ret;
+
+ debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ return clk_set_rate(c, rate);
+}
+
+static int __imxrt1170_clk_enable(struct clk *clk, bool enable)
+{
+ struct clk *c;
+ int ret;
+
+ debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ if (enable)
+ ret = clk_enable(c);
+ else
+ ret = clk_disable(c);
+
+ return ret;
+}
+
+static int imxrt1170_clk_disable(struct clk *clk)
+{
+ return __imxrt1170_clk_enable(clk, 0);
+}
+
+static int imxrt1170_clk_enable(struct clk *clk)
+{
+ return __imxrt1170_clk_enable(clk, 1);
+}
+
+static int imxrt1170_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk *c, *cp;
+ int ret;
+
+ debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
+
+ ret = clk_get_by_id(clk->id, &c);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_id(parent->id, &cp);
+ if (ret)
+ return ret;
+
+ return clk_set_parent(c, cp);
+}
+
+static struct clk_ops imxrt1170_clk_ops = {
+ .set_rate = imxrt1170_clk_set_rate,
+ .get_rate = imxrt1170_clk_get_rate,
+ .enable = imxrt1170_clk_enable,
+ .disable = imxrt1170_clk_disable,
+ .set_parent = imxrt1170_clk_set_parent,
+};
+
+static const char * const lpuart1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
+"pll3_div2", "pll1_div5", "pll2_sys", "pll2_pfd3"};
+static const char * const gpt1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
+"pll3_div2", "pll1_div5", "pll3_pfd2", "pll3_pfd3"};
+static const char * const usdhc1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
+"pll2_pfd2", "pll2_pfd0", "pll1_div5", "pll_arm"};
+static const char * const semc_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
+"pll1_div5", "pll2_sys", "pll2_pfd2", "pll3_pfd0"};
+
+static int imxrt1170_clk_probe(struct udevice *dev)
+{
+ void *base;
+
+ /* Anatop clocks */
+ base = (void *)ofnode_get_addr(ofnode_by_compatible(ofnode_null(), "fsl,imxrt-anatop"));
+
+
+
+ clk_dm(IMXRT1170_CLK_RCOSC_48M,
+ imx_clk_fixed_factor("rcosc48M", "rcosc16M", 3, 1));
+ clk_dm(IMXRT1170_CLK_RCOSC_400M,
+ imx_clk_fixed_factor("rcosc400M", "rcosc16M", 25, 1));
+ clk_dm(IMXRT1170_CLK_RCOSC_48M_DIV2,
+ imx_clk_fixed_factor("rcosc48M_div2", "rcosc48M", 1, 2));
+
+
+ clk_dm(IMXRT1170_CLK_PLL_ARM,
+ imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm", "osc",
+ base + 0x200, 0xff));
+ clk_dm(IMXRT1170_CLK_PLL3,
+ imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll3_sys", "osc",
+ base + 0x210, 1));
+ clk_dm(IMXRT1170_CLK_PLL2,
+ imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll2_sys", "osc",
+ base + 0x240, 1));
+
+ clk_dm(IMXRT1170_CLK_PLL3_PFD0,
+ imx_clk_pfd("pll3_pfd0", "pll3_sys", base + 0x230, 0));
+ clk_dm(IMXRT1170_CLK_PLL3_PFD1,
+ imx_clk_pfd("pll3_pfd1", "pll3_sys", base + 0x230, 1));
+ clk_dm(IMXRT1170_CLK_PLL3_PFD2,
+ imx_clk_pfd("pll3_pfd2", "pll3_sys", base + 0x230, 2));
+ clk_dm(IMXRT1170_CLK_PLL3_PFD3,
+ imx_clk_pfd("pll3_pfd3", "pll3_sys", base + 0x230, 3));
+
+ clk_dm(IMXRT1170_CLK_PLL2_PFD0,
+ imx_clk_pfd("pll2_pfd0", "pll2_sys", base + 0x270, 0));
+ clk_dm(IMXRT1170_CLK_PLL2_PFD1,
+ imx_clk_pfd("pll2_pfd1", "pll2_sys", base + 0x270, 1));
+ clk_dm(IMXRT1170_CLK_PLL2_PFD2,
+ imx_clk_pfd("pll2_pfd2", "pll2_sys", base + 0x270, 2));
+ clk_dm(IMXRT1170_CLK_PLL2_PFD3,
+ imx_clk_pfd("pll2_pfd3", "pll2_sys", base + 0x270, 3));
+
+ clk_dm(IMXRT1170_CLK_PLL3_DIV2,
+ imx_clk_fixed_factor("pll3_div2", "pll3_sys", 1, 2));
+
+ /* CCM clocks */
+ base = dev_read_addr_ptr(dev);
+ if (base == (void *)FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ clk_dm(IMXRT1170_CLK_LPUART1_SEL,
+ imx_clk_mux("lpuart1_sel", base + (25 * 0x80), 8, 3,
+ lpuart1_sels, ARRAY_SIZE(lpuart1_sels)));
+ clk_dm(IMXRT1170_CLK_LPUART1,
+ imx_clk_divider("lpuart1", "lpuart1_sel",
+ base + (25 * 0x80), 0, 8));
+
+ clk_dm(IMXRT1170_CLK_USDHC1_SEL,
+ imx_clk_mux("usdhc1_sel", base + (58 * 0x80), 8, 3,
+ usdhc1_sels, ARRAY_SIZE(usdhc1_sels)));
+ clk_dm(IMXRT1170_CLK_USDHC1,
+ imx_clk_divider("usdhc1", "usdhc1_sel",
+ base + (58 * 0x80), 0, 8));
+
+ clk_dm(IMXRT1170_CLK_GPT1_SEL,
+ imx_clk_mux("gpt1_sel", base + (14 * 0x80), 8, 3,
+ gpt1_sels, ARRAY_SIZE(gpt1_sels)));
+ clk_dm(IMXRT1170_CLK_GPT1,
+ imx_clk_divider("gpt1", "gpt1_sel",
+ base + (14 * 0x80), 0, 8));
+
+ clk_dm(IMXRT1170_CLK_SEMC_SEL,
+ imx_clk_mux("semc_sel", base + (4 * 0x80), 8, 3,
+ semc_sels, ARRAY_SIZE(semc_sels)));
+ clk_dm(IMXRT1170_CLK_SEMC,
+ imx_clk_divider("semc", "semc_sel",
+ base + (4 * 0x80), 0, 8));
+ struct clk *clk, *clk1;
+
+ clk_get_by_id(IMXRT1170_CLK_PLL2_PFD2, &clk);
+
+ clk_get_by_id(IMXRT1170_CLK_SEMC_SEL, &clk1);
+ clk_enable(clk1);
+ clk_set_parent(clk1, clk);
+
+ clk_get_by_id(IMXRT1170_CLK_SEMC, &clk);
+ clk_enable(clk);
+ clk_set_rate(clk, 132000000UL);
+
+ clk_get_by_id(IMXRT1170_CLK_GPT1, &clk);
+ clk_enable(clk);
+ clk_set_rate(clk, 32000000UL);
+
+ return 0;
+}
+
+static const struct udevice_id imxrt1170_clk_ids[] = {
+ { .compatible = "fsl,imxrt1170-ccm" },
+ { },
+};
+
+U_BOOT_DRIVER(imxrt1170_clk) = {
+ .name = "clk_imxrt1170",
+ .id = UCLASS_CLK,
+ .of_match = imxrt1170_clk_ids,
+ .ops = &imxrt1170_clk_ops,
+ .probe = imxrt1170_clk_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 077757efcb8..fad306aeed2 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -21,19 +21,23 @@
#define UBOOT_DM_CLK_IMX_PLLV3_USB "imx_clk_pllv3_usb"
#define UBOOT_DM_CLK_IMX_PLLV3_AV "imx_clk_pllv3_av"
#define UBOOT_DM_CLK_IMX_PLLV3_ENET "imx_clk_pllv3_enet"
+#define UBOOT_DM_CLK_IMX_PLLV3_GENV2 "imx_clk_pllv3_genericv2"
#define PLL_NUM_OFFSET 0x10
#define PLL_DENOM_OFFSET 0x20
#define BM_PLL_POWER (0x1 << 12)
+#define BM_PLL_POWER_V2 (0x1 << 21)
#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_LOCK (0x1 << 31)
+#define BM_PLL_LOCK_V2 (0x1 << 29)
struct clk_pllv3 {
struct clk clk;
void __iomem *base;
u32 power_bit;
bool powerup_set;
+ u32 lock_bit;
u32 enable_bit;
u32 div_mask;
u32 div_shift;
@@ -42,6 +46,30 @@ struct clk_pllv3 {
#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
+static ulong clk_pllv3_genericv2_get_rate(struct clk *clk)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
+ unsigned long parent_rate = clk_get_parent_rate(clk);
+
+ u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+
+ return (div == 0) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static ulong clk_pllv3_genericv2_set_rate(struct clk *clk, ulong rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(clk);
+ unsigned long parent_rate = clk_get_parent_rate(clk);
+
+ u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
+ u32 val = (div == 0) ? parent_rate * 22 : parent_rate * 20;
+
+ if (rate == val)
+ return 0;
+
+ return -EINVAL;
+}
+
static ulong clk_pllv3_generic_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
@@ -71,7 +99,7 @@ static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate)
writel(val, pll->base);
/* Wait for PLL to lock */
- while (!(readl(pll->base) & BM_PLL_LOCK))
+ while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@@ -120,6 +148,13 @@ static const struct clk_ops clk_pllv3_generic_ops = {
.set_rate = clk_pllv3_generic_set_rate,
};
+static const struct clk_ops clk_pllv3_genericv2_ops = {
+ .get_rate = clk_pllv3_genericv2_get_rate,
+ .enable = clk_pllv3_generic_enable,
+ .disable = clk_pllv3_generic_disable,
+ .set_rate = clk_pllv3_genericv2_set_rate,
+};
+
static ulong clk_pllv3_sys_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
@@ -153,7 +188,7 @@ static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
writel(val, pll->base);
/* Wait for PLL to lock */
- while (!(readl(pll->base) & BM_PLL_LOCK))
+ while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@@ -221,7 +256,7 @@ static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
writel(mfd, pll->base + PLL_DENOM_OFFSET);
/* Wait for PLL to lock */
- while (!(readl(pll->base) & BM_PLL_LOCK))
+ while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@@ -262,6 +297,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll->power_bit = BM_PLL_POWER;
pll->enable_bit = BM_PLL_ENABLE;
+ pll->lock_bit = BM_PLL_LOCK;
switch (type) {
case IMX_PLLV3_GENERIC:
@@ -269,6 +305,13 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll->div_shift = 0;
pll->powerup_set = false;
break;
+ case IMX_PLLV3_GENERICV2:
+ pll->power_bit = BM_PLL_POWER_V2;
+ pll->lock_bit = BM_PLL_LOCK_V2;
+ drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENV2;
+ pll->div_shift = 0;
+ pll->powerup_set = false;
+ break;
case IMX_PLLV3_SYS:
drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS;
pll->div_shift = 0;
@@ -313,6 +356,13 @@ U_BOOT_DRIVER(clk_pllv3_generic) = {
.flags = DM_FLAG_PRE_RELOC,
};
+U_BOOT_DRIVER(clk_pllv3_genericv2) = {
+ .name = UBOOT_DM_CLK_IMX_PLLV3_GENV2,
+ .id = UCLASS_CLK,
+ .ops = &clk_pllv3_genericv2_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
U_BOOT_DRIVER(clk_pllv3_sys) = {
.name = UBOOT_DM_CLK_IMX_PLLV3_SYS,
.id = UCLASS_CLK,
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 0e1eaf03d41..46dee35a673 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -10,6 +10,7 @@
enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
+ IMX_PLLV3_GENERICV2,
IMX_PLLV3_SYS,
IMX_PLLV3_USB,
IMX_PLLV3_USB_VF610,
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
index 575196778cc..f22f24b6077 100644
--- a/drivers/crypto/fsl/fsl_hash.c
+++ b/drivers/crypto/fsl/fsl_hash.c
@@ -131,25 +131,35 @@ static int caam_hash_update(void *hash_ctx, const void *buf,
static int caam_hash_finish(void *hash_ctx, void *dest_buf,
int size, enum caam_hash_algos caam_algo)
{
- uint32_t len = 0;
+ uint32_t len = 0, sg_entry_len;
struct sha_ctx *ctx = hash_ctx;
int i = 0, ret = 0;
+ caam_dma_addr_t addr;
if (size < driver_hash[caam_algo].digestsize) {
return -EINVAL;
}
- for (i = 0; i < ctx->sg_num; i++)
- len += (sec_in32(&ctx->sg_tbl[i].len_flag) &
- SG_ENTRY_LENGTH_MASK);
-
+ flush_dcache_range((ulong)ctx->sg_tbl,
+ (ulong)(ctx->sg_tbl) + (ctx->sg_num * sizeof(struct sg_entry)));
+ for (i = 0; i < ctx->sg_num; i++) {
+ sg_entry_len = (sec_in32(&ctx->sg_tbl[i].len_flag) &
+ SG_ENTRY_LENGTH_MASK);
+ len += sg_entry_len;
+#ifdef CONFIG_CAAM_64BIT
+ addr = sec_in32(&ctx->sg_tbl[i].addr_hi);
+ addr = (addr << 32) | sec_in32(&ctx->sg_tbl[i].addr_lo);
+#else
+ addr = sec_in32(&ctx->sg_tbl[i].addr_lo);
+#endif
+ flush_dcache_range(addr, addr + sg_entry_len);
+ }
inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len,
ctx->hash,
driver_hash[caam_algo].alg_type,
driver_hash[caam_algo].digestsize,
1);
- flush_dcache_range((ulong)ctx->sg_tbl, (ulong)(ctx->sg_tbl) + len);
flush_dcache_range((ulong)ctx->sha_desc,
(ulong)(ctx->sha_desc) + (sizeof(uint32_t) * MAX_CAAM_DESCSIZE));
flush_dcache_range((ulong)ctx->hash,
diff --git a/drivers/ddr/imx/imx8m/ddrphy_utils.c b/drivers/ddr/imx/imx8m/ddrphy_utils.c
deleted file mode 100644
index 975d553674a..00000000000
--- a/drivers/ddr/imx/imx8m/ddrphy_utils.c
+++ /dev/null
@@ -1,369 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2018 NXP
- */
-
-#include <common.h>
-#include <errno.h>
-#include <log.h>
-#include <asm/io.h>
-#include <asm/arch/ddr.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/ddr.h>
-#include <asm/arch/lpddr4_define.h>
-#include <asm/arch/sys_proto.h>
-
-static unsigned int g_cdd_rr_max[4];
-static unsigned int g_cdd_rw_max[4];
-static unsigned int g_cdd_wr_max[4];
-static unsigned int g_cdd_ww_max[4];
-
-static inline void poll_pmu_message_ready(void)
-{
- unsigned int reg;
-
- do {
- reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
- } while (reg & 0x1);
-}
-
-static inline void ack_pmu_message_receive(void)
-{
- unsigned int reg;
-
- reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x0);
-
- do {
- reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
- } while (!(reg & 0x1));
-
- reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x1);
-}
-
-static inline unsigned int get_mail(void)
-{
- unsigned int reg;
-
- poll_pmu_message_ready();
-
- reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
-
- ack_pmu_message_receive();
-
- return reg;
-}
-
-static inline unsigned int get_stream_message(void)
-{
- unsigned int reg, reg2;
-
- poll_pmu_message_ready();
-
- reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
-
- reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0034);
-
- reg2 = (reg2 << 16) | reg;
-
- ack_pmu_message_receive();
-
- return reg2;
-}
-
-static inline void decode_major_message(unsigned int mail)
-{
- debug("[PMU Major message = 0x%08x]\n", mail);
-}
-
-static inline void decode_streaming_message(void)
-{
- unsigned int string_index, arg __maybe_unused;
- int i = 0;
-
- string_index = get_stream_message();
- debug("PMU String index = 0x%08x\n", string_index);
- while (i < (string_index & 0xffff)) {
- arg = get_stream_message();
- debug("arg[%d] = 0x%08x\n", i, arg);
- i++;
- }
-
- debug("\n");
-}
-
-int wait_ddrphy_training_complete(void)
-{
- unsigned int mail;
-
- while (1) {
- mail = get_mail();
- decode_major_message(mail);
- if (mail == 0x08) {
- decode_streaming_message();
- } else if (mail == 0x07) {
- debug("Training PASS\n");
- return 0;
- } else if (mail == 0xff) {
- debug("Training FAILED\n");
- return -1;
- }
- }
-}
-
-void ddrphy_init_set_dfi_clk(unsigned int drate)
-{
- switch (drate) {
- case 4000:
- dram_pll_init(MHZ(1000));
- dram_disable_bypass();
- break;
- case 3732:
- dram_pll_init(MHZ(933));
- dram_disable_bypass();
- break;
- case 3200:
- dram_pll_init(MHZ(800));
- dram_disable_bypass();
- break;
- case 3000:
- dram_pll_init(MHZ(750));
- dram_disable_bypass();
- break;
- case 2400:
- dram_pll_init(MHZ(600));
- dram_disable_bypass();
- break;
- case 1600:
- dram_pll_init(MHZ(400));
- dram_disable_bypass();
- break;
- case 1066:
- dram_pll_init(MHZ(266));
- dram_disable_bypass();
- break;
- case 667:
- dram_pll_init(MHZ(167));
- dram_disable_bypass();
- break;
- case 400:
- dram_enable_bypass(MHZ(400));
- break;
- case 100:
- dram_enable_bypass(MHZ(100));
- break;
- default:
- return;
- }
-}
-
-void ddrphy_init_read_msg_block(enum fw_type type)
-{
-}
-
-void lpddr4_mr_write(unsigned int mr_rank, unsigned int mr_addr,
- unsigned int mr_data)
-{
- unsigned int tmp;
- /*
- * 1. Poll MRSTAT.mr_wr_busy until it is 0.
- * This checks that there is no outstanding MR transaction.
- * No writes should be performed to MRCTRL0 and MRCTRL1 if
- * MRSTAT.mr_wr_busy = 1.
- */
- do {
- tmp = reg32_read(DDRC_MRSTAT(0));
- } while (tmp & 0x1);
- /*
- * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank and
- * (for MRWs) MRCTRL1.mr_data to define the MR transaction.
- */
- reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4));
- reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8) | mr_data);
- reg32setbit(DDRC_MRCTRL0(0), 31);
-}
-
-unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
-{
- unsigned int tmp;
-
- reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x1);
- do {
- tmp = reg32_read(DDRC_MRSTAT(0));
- } while (tmp & 0x1);
-
- reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4) | 0x1);
- reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8));
- reg32setbit(DDRC_MRCTRL0(0), 31);
- do {
- tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0));
- } while ((tmp & 0x8) == 0);
- tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0));
- reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4);
- while (tmp) { //try to find a significant byte in the word
- if (tmp & 0xff) {
- tmp &= 0xff;
- break;
- }
- tmp >>= 8;
- }
- return tmp;
-}
-
-unsigned int look_for_max(unsigned int data[],
- unsigned int addr_start, unsigned int addr_end)
-{
- unsigned int i, imax = 0;
-
- for (i = addr_start; i <= addr_end; i++) {
- if (((data[i] >> 7) == 0) && (data[i] > imax))
- imax = data[i];
- }
-
- return imax;
-}
-
-void get_trained_CDD(u32 fsp)
-{
- unsigned int i, ddr_type, tmp;
- unsigned int cdd_cha[12], cdd_chb[12];
- unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max;
- unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max;
-
- ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f;
- if (ddr_type == 0x20) {
- for (i = 0; i < 6; i++) {
- tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54013 + i) * 4);
- cdd_cha[i * 2] = tmp & 0xff;
- cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff;
- }
-
- for (i = 0; i < 7; i++) {
- tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x5402c + i) * 4);
- if (i == 0) {
- cdd_cha[0] = (tmp >> 8) & 0xff;
- } else if (i == 6) {
- cdd_cha[11] = tmp & 0xff;
- } else {
- cdd_chb[i * 2 - 1] = tmp & 0xff;
- cdd_chb[i * 2] = (tmp >> 8) & 0xff;
- }
- }
-
- cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1);
- cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5);
- cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9);
- cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11);
- cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1);
- cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5);
- cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9);
- cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11);
- g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max;
- g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max;
- g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max;
- g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max;
- } else {
- unsigned int ddr4_cdd[64];
-
- for (i = 0; i < 29; i++) {
- tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54012 + i) * 4);
- ddr4_cdd[i * 2] = tmp & 0xff;
- ddr4_cdd[i * 2 + 1] = (tmp >> 8) & 0xff;
- }
-
- g_cdd_rr_max[fsp] = look_for_max(ddr4_cdd, 1, 12);
- g_cdd_ww_max[fsp] = look_for_max(ddr4_cdd, 13, 24);
- g_cdd_rw_max[fsp] = look_for_max(ddr4_cdd, 25, 40);
- g_cdd_wr_max[fsp] = look_for_max(ddr4_cdd, 41, 56);
- }
-}
-
-void update_umctl2_rank_space_setting(unsigned int pstat_num)
-{
- unsigned int i, ddr_type;
- unsigned int addr_slot, rdata, tmp, tmp_t;
- unsigned int ddrc_w2r, ddrc_r2w, ddrc_wr_gap, ddrc_rd_gap;
-
- ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f;
- for (i = 0; i < pstat_num; i++) {
- addr_slot = i ? (i + 1) * 0x1000 : 0;
- if (ddr_type == 0x20) {
- /* update r2w:[13:8], w2r:[5:0] */
- rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot);
- ddrc_w2r = rdata & 0x3f;
- if (is_imx8mp())
- tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1);
- else
- tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1;
- ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp;
-
- ddrc_r2w = (rdata >> 8) & 0x3f;
- if (is_imx8mp())
- tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1);
- else
- tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1;
- ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp;
-
- tmp_t = (rdata & 0xffffc0c0) | (ddrc_r2w << 8) | ddrc_w2r;
- reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t);
- } else {
- /* update w2r:[5:0] */
- rdata = reg32_read(DDRC_DRAMTMG9(0) + addr_slot);
- ddrc_w2r = rdata & 0x3f;
- if (is_imx8mp())
- tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1);
- else
- tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1;
- ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp;
- tmp_t = (rdata & 0xffffffc0) | ddrc_w2r;
- reg32_write((DDRC_DRAMTMG9(0) + addr_slot), tmp_t);
-
- /* update r2w:[13:8] */
- rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot);
- ddrc_r2w = (rdata >> 8) & 0x3f;
- if (is_imx8mp())
- tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1);
- else
- tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1;
- ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp;
-
- tmp_t = (rdata & 0xffffc0ff) | (ddrc_r2w << 8);
- reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t);
- }
-
- if (!is_imx8mq()) {
- /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */
- rdata = reg32_read(DDRC_RANKCTL(0) + addr_slot);
- ddrc_wr_gap = (rdata >> 8) & 0xf;
- if (is_imx8mp())
- tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1);
- else
- tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1) + 1;
- ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp;
-
- ddrc_rd_gap = (rdata >> 4) & 0xf;
- if (is_imx8mp())
- tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1);
- else
- tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1) + 1;
- ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp;
-
- tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4);
- reg32_write((DDRC_RANKCTL(0) + addr_slot), tmp_t);
- }
- }
-
- if (is_imx8mq()) {
- /* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */
- rdata = reg32_read(DDRC_RANKCTL(0));
- ddrc_wr_gap = (rdata >> 8) & 0xf;
- tmp = ddrc_wr_gap + (g_cdd_ww_max[0] >> 1) + 1;
- ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp;
-
- ddrc_rd_gap = (rdata >> 4) & 0xf;
- tmp = ddrc_rd_gap + (g_cdd_rr_max[0] >> 1) + 1;
- ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp;
-
- tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4);
- reg32_write(DDRC_RANKCTL(0), tmp_t);
- }
-}
diff --git a/drivers/ram/imxrt_sdram.c b/drivers/ram/imxrt_sdram.c
index ca2eec767d7..d0a88845cf9 100644
--- a/drivers/ram/imxrt_sdram.c
+++ b/drivers/ram/imxrt_sdram.c
@@ -87,12 +87,21 @@ struct imxrt_semc_regs {
u32 sts[16];
};
+#if !defined(TARGET_IMXRT1170_EVK)
#define SEMC_IOCR_MUX_A8_SHIFT 0
#define SEMC_IOCR_MUX_CSX0_SHIFT 3
#define SEMC_IOCR_MUX_CSX1_SHIFT 6
#define SEMC_IOCR_MUX_CSX2_SHIFT 9
#define SEMC_IOCR_MUX_CSX3_SHIFT 12
#define SEMC_IOCR_MUX_RDY_SHIFT 15
+#else
+#define SEMC_IOCR_MUX_A8_SHIFT 0
+#define SEMC_IOCR_MUX_CSX0_SHIFT 4
+#define SEMC_IOCR_MUX_CSX1_SHIFT 8
+#define SEMC_IOCR_MUX_CSX2_SHIFT 12
+#define SEMC_IOCR_MUX_CSX3_SHIFT 16
+#define SEMC_IOCR_MUX_RDY_SHIFT 20
+#endif
struct imxrt_sdram_mux {
u8 a8;
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 70a0e5e9197..af1fd1ea9bc 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -61,6 +61,11 @@
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
+
+/* imx8 names these bitsfields instead: */
+#define UCR3_DTRDEN BIT(3) /* bit not used in this chip */
+#define UCR3_RXDMUXSEL BIT(2) /* RXD muxed input selected; 'should always be set' */
+
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
#define UCR3_BPEN (1<<0) /* Preset registers enable */
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
@@ -176,6 +181,14 @@ static void _mxc_serial_setbrg(struct mxc_uart *base, unsigned long clk,
writel(UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST,
&base->cr2);
+
+ /*
+ * setting the baudrate triggers a reset, returning cr3 to its
+ * reset value but UCR3_RXDMUXSEL "should always be set."
+ * according to the imx8 reference-manual
+ */
+ writel(readl(&base->cr3) | UCR3_RXDMUXSEL, &base->cr3);
+
writel(UCR1_UARTEN, &base->cr1);
}
@@ -298,7 +311,7 @@ static int mxc_serial_putc(struct udevice *dev, const char ch)
struct mxc_serial_plat *plat = dev_get_plat(dev);
struct mxc_uart *const uart = plat->reg;
- if (!(readl(&uart->ts) & UTS_TXEMPTY))
+ if (readl(&uart->ts) & UTS_TXFULL)
return -EAGAIN;
writel(ch, &uart->txd);