diff options
| author | Tom Rini <[email protected]> | 2022-09-19 08:38:32 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2022-09-19 08:38:32 -0400 |
| commit | c1db6be55da2fd157118425cb95145c4e737a908 (patch) | |
| tree | d33d29bb29c638b14d46a7f2e1dafff015c3acc9 /drivers | |
| parent | a0759684e015bd7252be3af508c0fcfdbb8ec5dc (diff) | |
| parent | cc74cab86a5f32db93a9f0dc7bc46fa5e83f4f3e (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/Kconfig | 16 | ||||
| -rw-r--r-- | drivers/clk/imx/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clk/imx/clk-imxrt1170.c | 221 | ||||
| -rw-r--r-- | drivers/clk/imx/clk-pllv3.c | 56 | ||||
| -rw-r--r-- | drivers/clk/imx/clk.h | 1 | ||||
| -rw-r--r-- | drivers/crypto/fsl/fsl_hash.c | 22 | ||||
| -rw-r--r-- | drivers/ddr/imx/imx8m/ddrphy_utils.c | 369 | ||||
| -rw-r--r-- | drivers/ram/imxrt_sdram.c | 9 | ||||
| -rw-r--r-- | drivers/serial/serial_mxc.c | 15 |
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); |
