aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-09-19 13:19:39 -0400
committerTom Rini <trini@konsulko.com>2022-09-19 16:07:12 -0400
commite9a1ff9724348408144c7f1c5b5cc26130ba46e5 (patch)
tree68b56f117206d121b4a7e567b0209c02283c98e6 /drivers
parentb6c50e5831f6ce3800d4b3cf3c7aa35dde8c48d9 (diff)
parentf76f3e3b44328fe6229650540109af93750fd5f0 (diff)
downloadu-boot-e9a1ff9724348408144c7f1c5b5cc26130ba46e5.zip
u-boot-e9a1ff9724348408144c7f1c5b5cc26130ba46e5.tar.gz
u-boot-e9a1ff9724348408144c7f1c5b5cc26130ba46e5.tar.bz2
Merge branch 'master' into next
Signed-off-by: Tom Rini <trini@konsulko.com>
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/clk/rockchip/clk_rk3399.c66
-rw-r--r--drivers/clk/sifive/fu740-prci.c18
-rw-r--r--drivers/clk/sifive/sifive-prci.c4
-rw-r--r--drivers/clk/stm32/clk-stm32mp1.c35
-rw-r--r--drivers/crypto/fsl/fsl_hash.c22
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c2
-rw-r--r--drivers/ddr/fsl/ddr4_dimm_params.c2
-rw-r--r--drivers/ddr/fsl/interactive.c6
-rw-r--r--drivers/ddr/imx/imx8m/ddrphy_utils.c369
-rw-r--r--drivers/i2c/stm32f7_i2c.c33
-rw-r--r--drivers/mmc/fsl_esdhc_spl.c43
-rw-r--r--drivers/mtd/renesas_rpc_hf.c3
-rw-r--r--drivers/net/fm/fm.c18
-rw-r--r--drivers/net/fsl-mc/mc.c30
-rw-r--r--drivers/net/fsl_enetc.c8
-rw-r--r--drivers/net/pfe_eth/pfe_firmware.c40
-rw-r--r--drivers/nvme/nvme.c25
-rw-r--r--drivers/pci/pci-uclass.c10
-rw-r--r--drivers/phy/phy-stm32-usbphyc.c155
-rw-r--r--drivers/ram/imxrt_sdram.c9
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c42
-rw-r--r--drivers/serial/serial_mxc.c15
-rw-r--r--drivers/spi/renesas_rpc_spi.c9
-rw-r--r--drivers/sysreset/Kconfig1
-rw-r--r--drivers/timer/orion-timer.c2
-rw-r--r--drivers/tpm/cr50_i2c.c163
-rw-r--r--drivers/tpm/tpm-uclass.c10
-rw-r--r--drivers/tpm/tpm2_tis_sandbox.c17
-rw-r--r--drivers/usb/gadget/f_fastboot.c1
34 files changed, 865 insertions, 588 deletions
diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index 04d252a..abcb19c 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 c576690..b9c197f 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 0000000..077dd1b
--- /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 <Mr.Bossman075@gmail.com>
+ */
+
+#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 077757e..fad306a 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 0e1eaf0..46dee35 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/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 7d31a9f..97bf1c6 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -728,6 +728,12 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id)
u32 div, con;
switch (clk_id) {
+ case HCLK_SDIO:
+ case SCLK_SDIO:
+ con = readl(&cru->clksel_con[15]);
+ /* dwmmc controller have internal div 2 */
+ div = 2;
+ break;
case HCLK_SDMMC:
case SCLK_SDMMC:
con = readl(&cru->clksel_con[16]);
@@ -750,37 +756,46 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id)
return DIV_TO_RATE(GPLL_HZ, div);
}
+static void rk3399_dwmmc_set_clk(struct rockchip_cru *cru,
+ unsigned int con, ulong set_rate)
+{
+ /* Select clk_sdmmc source from GPLL by default */
+ /* mmc clock defaulg div 2 internal, provide double in cru */
+ int src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
+
+ if (src_clk_div > 128) {
+ /* use 24MHz source for 400KHz clock */
+ src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
+ assert(src_clk_div - 1 < 128);
+ rk_clrsetreg(&cru->clksel_con[con],
+ CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+ CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ } else {
+ rk_clrsetreg(&cru->clksel_con[con],
+ CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
+ CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
+ }
+}
+
static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru,
ulong clk_id, ulong set_rate)
{
- int src_clk_div;
- int aclk_emmc = 198 * MHz;
-
switch (clk_id) {
+ case HCLK_SDIO:
+ case SCLK_SDIO:
+ rk3399_dwmmc_set_clk(cru, 15, set_rate);
+ break;
case HCLK_SDMMC:
case SCLK_SDMMC:
- /* Select clk_sdmmc source from GPLL by default */
- /* mmc clock defaulg div 2 internal, provide double in cru */
- src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate);
-
- if (src_clk_div > 128) {
- /* use 24MHz source for 400KHz clock */
- src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
- assert(src_clk_div - 1 < 128);
- rk_clrsetreg(&cru->clksel_con[16],
- CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
- CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
- (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
- } else {
- rk_clrsetreg(&cru->clksel_con[16],
- CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
- CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
- (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
- }
+ rk3399_dwmmc_set_clk(cru, 16, set_rate);
break;
- case SCLK_EMMC:
+ case SCLK_EMMC: {
+ int aclk_emmc = 198 * MHz;
/* Select aclk_emmc source from GPLL */
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
+ int src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc);
+
assert(src_clk_div - 1 < 32);
rk_clrsetreg(&cru->clksel_con[21],
@@ -797,6 +812,7 @@ static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru,
CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
(src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
break;
+ }
default:
return -EINVAL;
}
@@ -918,6 +934,8 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
switch (clk->id) {
case 0 ... 63:
return 0;
+ case HCLK_SDIO:
+ case SCLK_SDIO:
case HCLK_SDMMC:
case SCLK_SDMMC:
case SCLK_EMMC:
@@ -992,6 +1010,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
case PCLK_PERILP1:
return 0;
+ case HCLK_SDIO:
+ case SCLK_SDIO:
case HCLK_SDMMC:
case SCLK_SDMMC:
case SCLK_EMMC:
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index b025050..5edc864 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -103,53 +103,53 @@ static const struct __prci_clock_ops sifive_fu740_prci_pcieaux_clk_ops = {
/* List of clock controls provided by the PRCI */
struct __prci_clock __prci_init_clocks_fu740[] = {
- [PRCI_CLK_COREPLL] = {
+ [FU740_PRCI_CLK_COREPLL] = {
.name = "corepll",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_wrpll_clk_ops,
.pwd = &__prci_corepll_data,
},
- [PRCI_CLK_DDRPLL] = {
+ [FU740_PRCI_CLK_DDRPLL] = {
.name = "ddrpll",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_wrpll_clk_ops,
.pwd = &__prci_ddrpll_data,
},
- [PRCI_CLK_GEMGXLPLL] = {
+ [FU740_PRCI_CLK_GEMGXLPLL] = {
.name = "gemgxlpll",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_wrpll_clk_ops,
.pwd = &__prci_gemgxlpll_data,
},
- [PRCI_CLK_DVFSCOREPLL] = {
+ [FU740_PRCI_CLK_DVFSCOREPLL] = {
.name = "dvfscorepll",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_wrpll_clk_ops,
.pwd = &__prci_dvfscorepll_data,
},
- [PRCI_CLK_HFPCLKPLL] = {
+ [FU740_PRCI_CLK_HFPCLKPLL] = {
.name = "hfpclkpll",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_wrpll_clk_ops,
.pwd = &__prci_hfpclkpll_data,
},
- [PRCI_CLK_CLTXPLL] = {
+ [FU740_PRCI_CLK_CLTXPLL] = {
.name = "cltxpll",
.parent_name = "hfclk",
.ops = &sifive_fu740_prci_wrpll_clk_ops,
.pwd = &__prci_cltxpll_data,
},
- [PRCI_CLK_TLCLK] = {
+ [FU740_PRCI_CLK_TLCLK] = {
.name = "tlclk",
.parent_name = "corepll",
.ops = &sifive_fu740_prci_tlclksel_clk_ops,
},
- [PRCI_CLK_PCLK] = {
+ [FU740_PRCI_CLK_PCLK] = {
.name = "pclk",
.parent_name = "hfpclkpll",
.ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
},
- [PRCI_CLK_PCIEAUX] {
+ [FU740_PRCI_CLK_PCIE_AUX] {
.name = "pcieaux",
.parent_name = "",
.ops = &sifive_fu740_prci_pcieaux_clk_ops,
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index 52ae268..c8fb600 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -685,14 +685,14 @@ static int sifive_prci_probe(struct udevice *dev)
* case the design uses hfpclk to drive
* Chiplink
*/
- pc = &data->clks[PRCI_CLK_HFPCLKPLL];
+ pc = &data->clks[FU740_PRCI_CLK_HFPCLKPLL];
parent_rate = sifive_prci_parent_rate(pc, data);
sifive_prci_wrpll_set_rate(pc, 260000000,
parent_rate);
pc->ops->enable_clk(pc, 1);
} else if (prci_pll_reg & PRCI_PRCIPLL_CLTXPLL) {
/* CLTX pll init */
- pc = &data->clks[PRCI_CLK_CLTXPLL];
+ pc = &data->clks[FU740_PRCI_CLK_CLTXPLL];
parent_rate = sifive_prci_parent_rate(pc, data);
sifive_prci_wrpll_set_rate(pc, 260000000,
parent_rate);
diff --git a/drivers/clk/stm32/clk-stm32mp1.c b/drivers/clk/stm32/clk-stm32mp1.c
index 4525500..4f4524f 100644
--- a/drivers/clk/stm32/clk-stm32mp1.c
+++ b/drivers/clk/stm32/clk-stm32mp1.c
@@ -962,6 +962,24 @@ static ulong stm32mp1_read_pll_freq(struct stm32mp1_clk_priv *priv,
return dfout;
}
+static ulong stm32mp1_clk_get_by_name(const char *name)
+{
+ struct clk clk;
+ struct udevice *dev = NULL;
+ ulong clock = 0;
+
+ if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) {
+ if (clk_request(dev, &clk)) {
+ log_err("%s request", name);
+ } else {
+ clk.id = 0;
+ clock = clk_get_rate(&clk);
+ }
+ }
+
+ return clock;
+}
+
static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p)
{
u32 reg;
@@ -1127,24 +1145,11 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p)
break;
/* other */
case _USB_PHY_48:
- clock = 48000000;
+ clock = stm32mp1_clk_get_by_name("ck_usbo_48m");
break;
case _DSI_PHY:
- {
- struct clk clk;
- struct udevice *dev = NULL;
-
- if (!uclass_get_device_by_name(UCLASS_CLK, "ck_dsi_phy",
- &dev)) {
- if (clk_request(dev, &clk)) {
- log_err("ck_dsi_phy request");
- } else {
- clk.id = 0;
- clock = clk_get_rate(&clk);
- }
- }
+ clock = stm32mp1_clk_get_by_name("ck_dsi_phy");
break;
- }
default:
break;
}
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
index 5751967..f22f24b 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/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index b5122d1..0b0b4e5 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -214,7 +214,7 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr,
odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;
odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;
#ifdef CONFIG_SYS_FSL_DDR4
- ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits;
+ ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits - 2;
bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits;
#else
n_banks_per_sdram_device
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index e2bdc12..ea79162 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -246,7 +246,7 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
/* SDRAM device parameters */
pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12;
pdimm->n_col_addr = (spd->addressing & 0x7) + 9;
- pdimm->bank_addr_bits = (spd->density_banks >> 4) & 0x3;
+ pdimm->bank_addr_bits = ((spd->density_banks >> 4) & 0x3) + 2;
pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3;
/*
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 2f76beb..eb2f06e 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -27,9 +27,9 @@
/* Option parameter Structures */
struct options_string {
const char *option_name;
- size_t offset;
- unsigned int size;
- const char printhex;
+ u32 offset : 9;
+ u32 size : 4;
+ u32 printhex : 1;
};
static unsigned int picos_to_mhz(unsigned int picos)
diff --git a/drivers/ddr/imx/imx8m/ddrphy_utils.c b/drivers/ddr/imx/imx8m/ddrphy_utils.c
deleted file mode 100644
index 975d553..0000000
--- 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/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index bf2a6c9..836148e 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -57,7 +57,6 @@ struct stm32_i2c_regs {
#define STM32_I2C_CR1_PE BIT(0)
/* STM32 I2C control 2 */
-#define STM32_I2C_CR2_AUTOEND BIT(25)
#define STM32_I2C_CR2_RELOAD BIT(24)
#define STM32_I2C_CR2_NBYTES_MASK GENMASK(23, 16)
#define STM32_I2C_CR2_NBYTES(n) ((n & 0xff) << 16)
@@ -283,7 +282,7 @@ static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv)
}
static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv,
- struct i2c_msg *msg, bool stop)
+ struct i2c_msg *msg)
{
struct stm32_i2c_regs *regs = i2c_priv->regs;
u32 cr2 = readl(&regs->cr2);
@@ -304,9 +303,8 @@ static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv,
cr2 |= STM32_I2C_CR2_SADD7(msg->addr);
}
- /* Set nb bytes to transfer and reload or autoend bits */
- cr2 &= ~(STM32_I2C_CR2_NBYTES_MASK | STM32_I2C_CR2_RELOAD |
- STM32_I2C_CR2_AUTOEND);
+ /* Set nb bytes to transfer and reload (if needed) */
+ cr2 &= ~(STM32_I2C_CR2_NBYTES_MASK | STM32_I2C_CR2_RELOAD);
if (msg->len > STM32_I2C_MAX_LEN) {
cr2 |= STM32_I2C_CR2_NBYTES(STM32_I2C_MAX_LEN);
cr2 |= STM32_I2C_CR2_RELOAD;
@@ -327,7 +325,7 @@ static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv,
*/
static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv,
- struct i2c_msg *msg, bool stop)
+ struct i2c_msg *msg)
{
struct stm32_i2c_regs *regs = i2c_priv->regs;
u32 cr2 = readl(&regs->cr2);
@@ -413,7 +411,7 @@ static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv)
setbits_le32(&regs->icr, STM32_I2C_ICR_STOPCF);
/* Clear control register 2 */
- setbits_le32(&regs->cr2, STM32_I2C_CR2_RESET_MASK);
+ clrbits_le32(&regs->cr2, STM32_I2C_CR2_RESET_MASK);
}
return ret;
@@ -433,7 +431,7 @@ static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv,
/* Add errors */
mask |= STM32_I2C_ISR_ERRORS;
- stm32_i2c_message_start(i2c_priv, msg, stop);
+ stm32_i2c_message_start(i2c_priv, msg);
while (msg->len) {
/*
@@ -471,7 +469,7 @@ static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv,
mask = msg->flags & I2C_M_RD ? STM32_I2C_ISR_RXNE :
STM32_I2C_ISR_TXIS | STM32_I2C_ISR_NACKF;
- stm32_i2c_handle_reload(i2c_priv, msg, stop);
+ stm32_i2c_handle_reload(i2c_priv, msg);
} else if (!bytes_to_rw) {
/* Wait until TC flag is set */
mask = STM32_I2C_ISR_TC;
@@ -485,9 +483,9 @@ static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv,
}
}
- /* End of transfer, send stop condition */
- mask = STM32_I2C_CR2_STOP;
- setbits_le32(&regs->cr2, mask);
+ /* End of transfer, send stop condition if appropriate */
+ if (!ret && !(status & (STM32_I2C_ISR_NACKF | STM32_I2C_ISR_ERRORS)))
+ setbits_le32(&regs->cr2, STM32_I2C_CR2_STOP);
return stm32_i2c_check_end_of_message(i2c_priv);
}
@@ -916,18 +914,19 @@ static int stm32_of_to_plat(struct udevice *dev)
{
const struct stm32_i2c_data *data;
struct stm32_i2c_priv *i2c_priv = dev_get_priv(dev);
- u32 rise_time, fall_time;
int ret;
data = (const struct stm32_i2c_data *)dev_get_driver_data(dev);
if (!data)
return -EINVAL;
- rise_time = dev_read_u32_default(dev, "i2c-scl-rising-time-ns",
- STM32_I2C_RISE_TIME_DEFAULT);
+ i2c_priv->setup.rise_time = dev_read_u32_default(dev,
+ "i2c-scl-rising-time-ns",
+ STM32_I2C_RISE_TIME_DEFAULT);
- fall_time = dev_read_u32_default(dev, "i2c-scl-falling-time-ns",
- STM32_I2C_FALL_TIME_DEFAULT);
+ i2c_priv->setup.fall_time = dev_read_u32_default(dev,
+ "i2c-scl-falling-time-ns",
+ STM32_I2C_FALL_TIME_DEFAULT);
i2c_priv->dnf_dt = dev_read_u32_default(dev, "i2c-digital-filter-width-ns", 0);
if (!dev_read_bool(dev, "i2c-digital-filter"))
diff --git a/drivers/mmc/fsl_esdhc_spl.c b/drivers/mmc/fsl_esdhc_spl.c
index 760f13d..aa00d7e 100644
--- a/drivers/mmc/fsl_esdhc_spl.c
+++ b/drivers/mmc/fsl_esdhc_spl.c
@@ -9,6 +9,10 @@
#include <mmc.h>
#include <malloc.h>
+#ifndef CONFIG_SYS_MMC_U_BOOT_OFFS
+extern uchar mmc_u_boot_offs[];
+#endif
+
/*
* The environment variables are written to just after the u-boot image
* on SDCard, so we must read the MBR to get the start address and code
@@ -58,10 +62,10 @@ void __noreturn mmc_boot(void)
{
__attribute__((noreturn)) void (*uboot)(void);
uint blk_start, blk_cnt, err;
-#ifndef CONFIG_FSL_CORENET
uchar *tmp_buf;
u32 blklen;
u32 blk_off;
+#ifndef CONFIG_FSL_CORENET
uchar val;
#ifndef CONFIG_SPL_FSL_PBL
u32 val32;
@@ -83,9 +87,6 @@ void __noreturn mmc_boot(void)
hang();
}
-#ifdef CONFIG_FSL_CORENET
- offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
-#else
blklen = mmc->read_bl_len;
if (blklen < 512)
blklen = 512;
@@ -95,6 +96,9 @@ void __noreturn mmc_boot(void)
hang();
}
+#ifdef CONFIG_FSL_CORENET
+ offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
+#else
sector = 0;
again:
memset(tmp_buf, 0, blklen);
@@ -149,23 +153,44 @@ again:
val = *(tmp_buf + blk_off + ESDHC_BOOT_IMAGE_ADDR + i);
offset = (offset << 8) + val;
}
+#ifndef CONFIG_SYS_MMC_U_BOOT_OFFS
+ offset += (ulong)&mmc_u_boot_offs - CONFIG_SPL_TEXT_BASE;
+#else
offset += CONFIG_SYS_MMC_U_BOOT_OFFS;
#endif
+#endif
/*
* Load U-Boot image from mmc into RAM
*/
code_len = CONFIG_SYS_MMC_U_BOOT_SIZE;
- blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
- blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;
+ blk_start = offset / mmc->read_bl_len;
+ blk_off = offset % mmc->read_bl_len;
+ blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len + 1;
+ if (blk_off) {
+ err = mmc->block_dev.block_read(&mmc->block_dev,
+ blk_start, 1, tmp_buf);
+ if (err != 1) {
+ puts("spl: mmc read failed!!\n");
+ hang();
+ }
+ blk_start++;
+ }
err = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
- (uchar *)CONFIG_SYS_MMC_U_BOOT_DST);
+ (uchar *)CONFIG_SYS_MMC_U_BOOT_DST +
+ (blk_off ? (mmc->read_bl_len - blk_off) : 0));
if (err != blk_cnt) {
puts("spl: mmc read failed!!\n");
-#ifndef CONFIG_FSL_CORENET
free(tmp_buf);
-#endif
hang();
}
+ /*
+ * SDHC DMA may erase bytes at dst + bl_len - blk_off - 8
+ * due to unaligned access. So copy leading bytes from tmp_buf
+ * after SDHC DMA transfer.
+ */
+ if (blk_off)
+ memcpy((uchar *)CONFIG_SYS_MMC_U_BOOT_DST,
+ tmp_buf + blk_off, mmc->read_bl_len - blk_off);
/*
* Clean d-cache and invalidate i-cache, to
diff --git a/drivers/mtd/renesas_rpc_hf.c b/drivers/mtd/renesas_rpc_hf.c
index 2c61ce7..aca7a6c 100644
--- a/drivers/mtd/renesas_rpc_hf.c
+++ b/drivers/mtd/renesas_rpc_hf.c
@@ -388,7 +388,8 @@ static int rpc_hf_probe(struct udevice *dev)
}
static const struct udevice_id rpc_hf_ids[] = {
- { .compatible = "renesas,rpc" },
+ { .compatible = "renesas,r7s72100-rpc-if" },
+ { .compatible = "renesas,rcar-gen3-rpc-if" },
{}
};
diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c
index d0b492b..ee96abb 100644
--- a/drivers/net/fm/fm.c
+++ b/drivers/net/fm/fm.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
#include <env.h>
+#include <image.h>
#include <malloc.h>
#include <asm/io.h>
#include <linux/errno.h>
@@ -513,6 +514,23 @@ int fm_init_common(int index, struct ccsr_fman *reg)
void *addr = NULL;
#endif
+ rc = fit_check_format(addr, CONFIG_SYS_QE_FMAN_FW_LENGTH);
+ if (!rc) {
+ size_t unused;
+ const void *new_addr;
+
+ rc = fit_get_data_conf_prop(addr, "fman", &new_addr, &unused);
+ if (rc)
+ return rc;
+ addr = (void *)new_addr;
+ } else if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
+ /*
+ * Using a (signed) FIT wrapper is mandatory if we are
+ * doing verified boot.
+ */
+ return rc;
+ }
+
/* Upload the Fman microcode if it's present */
rc = fman_upload_firmware(index, &reg->fm_imem, addr);
if (rc)
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index bc1c31d..68833f9 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -137,13 +137,7 @@ int parse_mc_firmware_fit_image(u64 mc_fw_addr,
size_t *raw_image_size)
{
int format;
- void *fit_hdr;
- int node_offset;
- const void *data;
- size_t size;
- const char *uname = "firmware";
-
- fit_hdr = (void *)mc_fw_addr;
+ void *fit_hdr = (void *)mc_fw_addr;
/* Check if Image is in FIT format */
format = genimg_get_format(fit_hdr);
@@ -158,26 +152,8 @@ int parse_mc_firmware_fit_image(u64 mc_fw_addr,
return -EINVAL;
}
- node_offset = fit_image_get_node(fit_hdr, uname);
-
- if (node_offset < 0) {
- printf("fsl-mc: ERR: Bad firmware image (missing subimage)\n");
- return -ENOENT;
- }
-
- /* Verify MC firmware image */
- if (!(fit_image_verify(fit_hdr, node_offset))) {
- printf("fsl-mc: ERR: Bad firmware image (bad CRC)\n");
- return -EINVAL;
- }
-
- /* Get address and size of raw image */
- fit_image_get_data(fit_hdr, node_offset, &data, &size);
-
- *raw_image_addr = data;
- *raw_image_size = size;
-
- return 0;
+ return fit_get_data_node(fit_hdr, "firmware", raw_image_addr,
+ raw_image_size);
}
#endif
diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c
index cd4c2c2..835e5bd 100644
--- a/drivers/net/fsl_enetc.c
+++ b/drivers/net/fsl_enetc.c
@@ -22,6 +22,8 @@
#define ENETC_DRIVER_NAME "enetc_eth"
+static int enetc_remove(struct udevice *dev);
+
/*
* sets the MAC address in IERB registers, this setting is persistent and
* carried over to Linux.
@@ -319,6 +321,7 @@ static int enetc_config_phy(struct udevice *dev)
static int enetc_probe(struct udevice *dev)
{
struct enetc_priv *priv = dev_get_priv(dev);
+ int res;
if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_available(dev_ofnode(dev))) {
enetc_dbg(dev, "interface disabled\n");
@@ -350,7 +353,10 @@ static int enetc_probe(struct udevice *dev)
enetc_start_pcs(dev);
- return enetc_config_phy(dev);
+ res = enetc_config_phy(dev);
+ if(res)
+ enetc_remove(dev);
+ return res;
}
/*
diff --git a/drivers/net/pfe_eth/pfe_firmware.c b/drivers/net/pfe_eth/pfe_firmware.c
index 82a4aa8..da4f2ca 100644
--- a/drivers/net/pfe_eth/pfe_firmware.c
+++ b/drivers/net/pfe_eth/pfe_firmware.c
@@ -104,45 +104,7 @@ err:
static int pfe_get_fw(const void **data,
size_t *size, char *fw_name)
{
- int conf_node_off, fw_node_off;
- char *conf_node_name = NULL;
- char *desc;
- int ret = 0;
-
- conf_node_name = PFE_FIRMWARE_FIT_CNF_NAME;
-
- conf_node_off = fit_conf_get_node(pfe_fit_addr, conf_node_name);
- if (conf_node_off < 0) {
- printf("PFE Firmware: %s: no such config\n", conf_node_name);
- return -ENOENT;
- }
-
- fw_node_off = fit_conf_get_prop_node(pfe_fit_addr, conf_node_off,
- fw_name);
- if (fw_node_off < 0) {
- printf("PFE Firmware: No '%s' in config\n",
- fw_name);
- return -ENOLINK;
- }
-
- if (!(fit_image_verify(pfe_fit_addr, fw_node_off))) {
- printf("PFE Firmware: Bad firmware image (bad CRC)\n");
- return -EINVAL;
- }
-
- if (fit_image_get_data(pfe_fit_addr, fw_node_off, data, size)) {
- printf("PFE Firmware: Can't get %s subimage data/size",
- fw_name);
- return -ENOENT;
- }
-
- ret = fit_get_desc(pfe_fit_addr, fw_node_off, &desc);
- if (ret)
- printf("PFE Firmware: Can't get description\n");
- else
- printf("%s\n", desc);
-
- return ret;
+ return fit_get_data_conf_prop(pfe_fit_addr, fw_name, data, size);
}
/*
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 3510f79..6d0d3f3 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -27,9 +27,8 @@
#define IO_TIMEOUT 30
#define MAX_PRP_POOL 512
-static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
+static int nvme_wait_csts(struct nvme_dev *dev, u32 mask, u32 val)
{
- u32 bit = enabled ? NVME_CSTS_RDY : 0;
int timeout;
ulong start;
@@ -38,7 +37,7 @@ static int nvme_wait_ready(struct nvme_dev *dev, bool enabled)
start = get_timer(0);
while (get_timer(start) < timeout) {
- if ((readl(&dev->bar->csts) & NVME_CSTS_RDY) == bit)
+ if ((readl(&dev->bar->csts) & mask) == val)
return 0;
}
@@ -295,7 +294,7 @@ static int nvme_enable_ctrl(struct nvme_dev *dev)
dev->ctrl_config |= NVME_CC_ENABLE;
writel(dev->ctrl_config, &dev->bar->cc);
- return nvme_wait_ready(dev, true);
+ return nvme_wait_csts(dev, NVME_CSTS_RDY, NVME_CSTS_RDY);
}
static int nvme_disable_ctrl(struct nvme_dev *dev)
@@ -304,7 +303,16 @@ static int nvme_disable_ctrl(struct nvme_dev *dev)
dev->ctrl_config &= ~NVME_CC_ENABLE;
writel(dev->ctrl_config, &dev->bar->cc);
- return nvme_wait_ready(dev, false);
+ return nvme_wait_csts(dev, NVME_CSTS_RDY, 0);
+}
+
+static int nvme_shutdown_ctrl(struct nvme_dev *dev)
+{
+ dev->ctrl_config &= ~NVME_CC_SHN_MASK;
+ dev->ctrl_config |= NVME_CC_SHN_NORMAL;
+ writel(dev->ctrl_config, &dev->bar->cc);
+
+ return nvme_wait_csts(dev, NVME_CSTS_SHST_MASK, NVME_CSTS_SHST_CMPLT);
}
static void nvme_free_queue(struct nvme_queue *nvmeq)
@@ -904,6 +912,13 @@ free_nvme:
int nvme_shutdown(struct udevice *udev)
{
struct nvme_dev *ndev = dev_get_priv(udev);
+ int ret;
+
+ ret = nvme_shutdown_ctrl(ndev);
+ if (ret < 0) {
+ printf("Error: %s: Shutdown timed out!\n", udev->name);
+ return ret;
+ }
return nvme_disable_ctrl(ndev);
}
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 2c85e78..16a6a69 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -286,6 +286,8 @@ int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
ops = pci_get_ops(bus);
if (!ops->write_config)
return -ENOSYS;
+ if (offset < 0 || offset >= 4096)
+ return -EINVAL;
return ops->write_config(bus, bdf, offset, value, size);
}
@@ -364,8 +366,14 @@ int pci_bus_read_config(const struct udevice *bus, pci_dev_t bdf, int offset,
struct dm_pci_ops *ops;
ops = pci_get_ops(bus);
- if (!ops->read_config)
+ if (!ops->read_config) {
+ *valuep = pci_conv_32_to_size(~0, offset, size);
return -ENOSYS;
+ }
+ if (offset < 0 || offset >= 4096) {
+ *valuep = pci_conv_32_to_size(0, offset, size);
+ return -EINVAL;
+ }
return ops->read_config(bus, bdf, offset, valuep, size);
}
diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c
index d7f7c37..9f0b7d7 100644
--- a/drivers/phy/phy-stm32-usbphyc.c
+++ b/drivers/phy/phy-stm32-usbphyc.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <clk.h>
+#include <clk-uclass.h>
#include <div64.h>
#include <dm.h>
#include <fdtdec.h>
@@ -17,6 +18,7 @@
#include <usb.h>
#include <asm/io.h>
#include <dm/device_compat.h>
+#include <dm/lists.h>
#include <dm/of_access.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
@@ -72,6 +74,9 @@
#define PLL_INFF_MIN_RATE 19200000 /* in Hz */
#define PLL_INFF_MAX_RATE 38400000 /* in Hz */
+/* USBPHYC_CLK48 */
+#define USBPHYC_CLK48_FREQ 48000000 /* in Hz */
+
enum boosting_vals {
BOOST_1000_UA = 1000,
BOOST_2000_UA = 2000,
@@ -144,6 +149,7 @@ struct stm32_usbphyc {
bool init;
bool powered;
} phys[MAX_PHYS];
+ int n_pll_cons;
};
static void stm32_usbphyc_get_pll_params(u32 clk_rate,
@@ -203,18 +209,6 @@ static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
return 0;
}
-static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc)
-{
- int i;
-
- for (i = 0; i < MAX_PHYS; i++) {
- if (usbphyc->phys[i].init)
- return true;
- }
-
- return false;
-}
-
static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc)
{
int i;
@@ -227,18 +221,17 @@ static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc)
return false;
}
-static int stm32_usbphyc_phy_init(struct phy *phy)
+static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
{
- struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ?
true : false;
int ret;
- dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
- /* Check if one phy port has already configured the pll */
- if (pllen && stm32_usbphyc_is_init(usbphyc))
- goto initialized;
+ /* Check if one consumer has already configured the pll */
+ if (pllen && usbphyc->n_pll_cons) {
+ usbphyc->n_pll_cons++;
+ return 0;
+ }
if (usbphyc->vdda1v1) {
ret = regulator_set_enable(usbphyc->vdda1v1, true);
@@ -269,23 +262,19 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
return -EIO;
-initialized:
- usbphyc_phy->init = true;
+ usbphyc->n_pll_cons++;
return 0;
}
-static int stm32_usbphyc_phy_exit(struct phy *phy)
+static int stm32_usbphyc_pll_disable(struct stm32_usbphyc *usbphyc)
{
- struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
- struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
int ret;
- dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
- usbphyc_phy->init = false;
+ usbphyc->n_pll_cons--;
- /* Check if other phy port requires pllen */
- if (stm32_usbphyc_is_init(usbphyc))
+ /* Check if other consumer requires pllen */
+ if (usbphyc->n_pll_cons)
return 0;
clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
@@ -314,6 +303,42 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
return 0;
}
+static int stm32_usbphyc_phy_init(struct phy *phy)
+{
+ struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
+ struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
+ int ret;
+
+ dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
+ if (usbphyc_phy->init)
+ return 0;
+
+ ret = stm32_usbphyc_pll_enable(usbphyc);
+ if (ret)
+ return log_ret(ret);
+
+ usbphyc_phy->init = true;
+
+ return 0;
+}
+
+static int stm32_usbphyc_phy_exit(struct phy *phy)
+{
+ struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
+ struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
+ int ret;
+
+ dev_dbg(phy->dev, "phy ID = %lu\n", phy->id);
+ if (!usbphyc_phy->init)
+ return 0;
+
+ ret = stm32_usbphyc_pll_disable(usbphyc);
+
+ usbphyc_phy->init = false;
+
+ return log_ret(ret);
+}
+
static int stm32_usbphyc_phy_power_on(struct phy *phy)
{
struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
@@ -498,6 +523,16 @@ static const struct phy_ops stm32_usbphyc_phy_ops = {
.of_xlate = stm32_usbphyc_of_xlate,
};
+static int stm32_usbphyc_bind(struct udevice *dev)
+{
+ int ret;
+
+ ret = device_bind_driver_to_node(dev, "stm32-usbphyc-clk", "ck_usbo_48m",
+ dev_ofnode(dev), NULL);
+
+ return log_ret(ret);
+}
+
static int stm32_usbphyc_probe(struct udevice *dev)
{
struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
@@ -591,6 +626,70 @@ U_BOOT_DRIVER(stm32_usb_phyc) = {
.id = UCLASS_PHY,
.of_match = stm32_usbphyc_of_match,
.ops = &stm32_usbphyc_phy_ops,
+ .bind = stm32_usbphyc_bind,
.probe = stm32_usbphyc_probe,
.priv_auto = sizeof(struct stm32_usbphyc),
};
+
+struct stm32_usbphyc_clk {
+ bool enable;
+};
+
+static ulong stm32_usbphyc_clk48_get_rate(struct clk *clk)
+{
+ return USBPHYC_CLK48_FREQ;
+}
+
+static int stm32_usbphyc_clk48_enable(struct clk *clk)
+{
+ struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev);
+ struct stm32_usbphyc *usbphyc;
+ int ret;
+
+ if (usbphyc_clk->enable)
+ return 0;
+
+ usbphyc = dev_get_priv(clk->dev->parent);
+
+ /* ck_usbo_48m is generated by usbphyc PLL */
+ ret = stm32_usbphyc_pll_enable(usbphyc);
+ if (ret)
+ return ret;
+
+ usbphyc_clk->enable = true;
+
+ return 0;
+}
+
+static int stm32_usbphyc_clk48_disable(struct clk *clk)
+{
+ struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev);
+ struct stm32_usbphyc *usbphyc;
+ int ret;
+
+ if (!usbphyc_clk->enable)
+ return 0;
+
+ usbphyc = dev_get_priv(clk->dev->parent);
+
+ ret = stm32_usbphyc_pll_disable(usbphyc);
+ if (ret)
+ return ret;
+
+ usbphyc_clk->enable = false;
+
+ return 0;
+}
+
+const struct clk_ops usbphyc_clk48_ops = {
+ .get_rate = stm32_usbphyc_clk48_get_rate,
+ .enable = stm32_usbphyc_clk48_enable,
+ .disable = stm32_usbphyc_clk48_disable,
+};
+
+U_BOOT_DRIVER(stm32_usb_phyc_clk) = {
+ .name = "stm32-usbphyc-clk",
+ .id = UCLASS_CLK,
+ .ops = &usbphyc_clk48_ops,
+ .priv_auto = sizeof(struct stm32_usbphyc_clk),
+};
diff --git a/drivers/ram/imxrt_sdram.c b/drivers/ram/imxrt_sdram.c
index ca2eec7..d0a8884 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/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index c0a06dc..cbf502b 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -85,7 +85,7 @@ struct sdram_rk3399_ops {
int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
struct rk3399_sdram_params *sdram);
int (*set_rate_index)(struct dram_info *dram,
- struct rk3399_sdram_params *params);
+ struct rk3399_sdram_params *params, u32 ctl_fn);
void (*modify_param)(const struct chan_info *chan,
struct rk3399_sdram_params *params);
struct rk3399_sdram_params *
@@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
}
static int switch_to_phy_index1(struct dram_info *dram,
- struct rk3399_sdram_params *params)
+ struct rk3399_sdram_params *params,
+ u32 unused)
{
u32 channel;
u32 *denali_phy;
@@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram,
}
static int lpddr4_set_rate(struct dram_info *dram,
- struct rk3399_sdram_params *params)
+ struct rk3399_sdram_params *params,
+ u32 ctl_fn)
{
- u32 ctl_fn;
u32 phy_fn;
- for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
- phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
+ phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
- lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
- lpddr4_set_ctl(dram, params, ctl_fn,
- dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
+ lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
+ lpddr4_set_ctl(dram, params, ctl_fn,
+ dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
- if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
- printf("%s: change freq to %d mhz %d, %d\n", __func__,
- dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq,
- ctl_fn, phy_fn);
- }
+ if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
+ printf("%s: change freq to %dMHz %d, %d\n", __func__,
+ dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
+ ctl_fn, phy_fn);
return 0;
}
+
#endif /* CONFIG_RAM_RK3399_LPDDR4 */
/* CS0,n=1
@@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram,
params->ch[ch].cap_info.rank = rank;
}
+#if defined(CONFIG_RAM_RK3399_LPDDR4)
+ /* LPDDR4 needs to be trained at 400MHz */
+ lpddr4_set_rate(dram, params, 0);
+ params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
+#endif
+
params->base.num_channels = 0;
for (channel = 0; channel < 2; channel++) {
const struct chan_info *chan = &dram->chan[channel];
@@ -2964,8 +2970,6 @@ static int sdram_init(struct dram_info *dram,
if (cap_info->rank == 0) {
clear_channel_params(params, 1);
continue;
- } else {
- params->base.num_channels++;
}
if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) {
@@ -2991,6 +2995,8 @@ static int sdram_init(struct dram_info *dram,
printf("no ddrconfig find, Cap not support!\n");
continue;
}
+
+ params->base.num_channels++;
set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
set_cap_relate_config(chan, params, channel);
}
@@ -3005,7 +3011,9 @@ static int sdram_init(struct dram_info *dram,
params->base.stride = calculate_stride(params);
dram_all_config(dram, params);
- dram->ops->set_rate_index(dram, params);
+ ret = dram->ops->set_rate_index(dram, params, 1);
+ if (ret)
+ return ret;
debug("Finish SDRAM initialization...\n");
return 0;
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 315c136..4cf79c1 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);
diff --git a/drivers/spi/renesas_rpc_spi.c b/drivers/spi/renesas_rpc_spi.c
index 26b6aa8..cb2b8fb 100644
--- a/drivers/spi/renesas_rpc_spi.c
+++ b/drivers/spi/renesas_rpc_spi.c
@@ -449,13 +449,8 @@ static const struct dm_spi_ops rpc_spi_ops = {
};
static const struct udevice_id rpc_spi_ids[] = {
- { .compatible = "renesas,rpc-r7s72100" },
- { .compatible = "renesas,rpc-r8a7795" },
- { .compatible = "renesas,rpc-r8a7796" },
- { .compatible = "renesas,rpc-r8a77965" },
- { .compatible = "renesas,rpc-r8a77970" },
- { .compatible = "renesas,rpc-r8a77995" },
- { .compatible = "renesas,rcar-gen3-rpc" },
+ { .compatible = "renesas,r7s72100-rpc-if" },
+ { .compatible = "renesas,rcar-gen3-rpc-if" },
{ }
};
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index a0acffa..03f7fdd 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -113,6 +113,7 @@ config SYSRESET_PSCI
config SYSRESET_SBI
bool "Enable support for SBI System Reset"
depends on RISCV_SMODE && SBI_V02
+ default y
select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
help
Enable system reset and poweroff via the SBI system reset extension.
diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c
index fd30e1b..d7d1a1b 100644
--- a/drivers/timer/orion-timer.c
+++ b/drivers/timer/orion-timer.c
@@ -19,7 +19,7 @@ static uint64_t orion_timer_get_count(struct udevice *dev)
{
struct orion_timer_priv *priv = dev_get_priv(dev);
- return ~readl(priv->base + TIMER0_VAL);
+ return timer_conv_64(~readl(priv->base + TIMER0_VAL));
}
static int orion_timer_probe(struct udevice *dev)
diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c
index f8c3087..acf4c78 100644
--- a/drivers/tpm/cr50_i2c.c
+++ b/drivers/tpm/cr50_i2c.c
@@ -13,11 +13,13 @@
#include <irq.h>
#include <log.h>
#include <spl.h>
+#include <tpm-common.h>
#include <tpm-v2.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include <asm/unaligned.h>
#include <linux/delay.h>
#include <dm/acpi.h>
@@ -37,6 +39,50 @@ enum {
CR50_MAX_BUF_SIZE = 63,
};
+/*
+ * Operations specific to the Cr50 TPM used on Chromium OS and Android devices
+ *
+ * FIXME: below is not enough to differentiate between vendors commands
+ * of numerous devices. However, the current tpm2 APIs aren't very amenable
+ * to extending generically because the marshaling code is assuming all
+ * knowledge of all commands.
+ */
+#define TPM2_CC_VENDOR_BIT_MASK 0x20000000
+
+#define TPM2_CR50_VENDOR_COMMAND (TPM2_CC_VENDOR_BIT_MASK | 0)
+#define TPM2_CR50_SUB_CMD_IMMEDIATE_RESET 19
+#define TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS 21
+#define TPM2_CR50_SUB_CMD_REPORT_TPM_STATE 23
+#define TPM2_CR50_SUB_CMD_TURN_UPDATE_ON 24
+#define TPM2_CR50_SUB_CMD_GET_REC_BTN 29
+#define TPM2_CR50_SUB_CMD_TPM_MODE 40
+#define TPM2_CR50_SUB_CMD_GET_BOOT_MODE 52
+#define TPM2_CR50_SUB_CMD_RESET_EC 53
+
+/* Cr50 vendor-specific error codes. */
+#define VENDOR_RC_ERR 0x00000500
+enum cr50_vendor_rc {
+ VENDOR_RC_INTERNAL_ERROR = (VENDOR_RC_ERR | 6),
+ VENDOR_RC_NO_SUCH_SUBCOMMAND = (VENDOR_RC_ERR | 8),
+ VENDOR_RC_NO_SUCH_COMMAND = (VENDOR_RC_ERR | 127),
+};
+
+enum cr50_tpm_mode {
+ /*
+ * Default state: TPM is enabled, and may be set to either
+ * TPM_MODE_ENABLED or TPM_MODE_DISABLED.
+ */
+ TPM_MODE_ENABLED_TENTATIVE = 0,
+
+ /* TPM is enabled, and mode may not be changed. */
+ TPM_MODE_ENABLED = 1,
+
+ /* TPM is disabled, and mode may not be changed. */
+ TPM_MODE_DISABLED = 2,
+
+ TPM_MODE_INVALID,
+};
+
/**
* struct cr50_priv - Private driver data
*
@@ -54,6 +100,41 @@ struct cr50_priv {
bool use_irq;
};
+/*
+ * The below structure represents the body of the response to the 'report tpm
+ * state' vendor command.
+ *
+ * It is transferred over the wire, so it needs to be serialized/deserialized,
+ * and it is likely to change, so its contents must be versioned.
+ */
+#define TPM_STATE_VERSION 1
+struct tpm_vendor_state {
+ u32 version;
+ /*
+ * The following three fields are set by the TPM in case of an assert.
+ * There is no other processing than setting the source code line
+ * number, error code and the first 4 characters of the function name.
+ *
+ * We don't expect this happening, but it is included in the report
+ * just in case.
+ */
+ u32 fail_line; /* s_failLIne */
+ u32 fail_code; /* s_failCode */
+ char func_name[4]; /* s_failFunction, limited to 4 chars */
+
+ /*
+ * The following two fields are the current time filtered value of the
+ * 'failed tries' TPM counter, and the maximum allowed value of the
+ * counter.
+ *
+ * failed_tries == max_tries is the definition of the TPM lockout
+ * condition.
+ */
+ u32 failed_tries; /* gp.failedTries */
+ u32 max_tries; /* gp.maxTries */
+ /* The below fields are present in version 2 and above */
+};
+
/* Wait for interrupt to indicate TPM is ready */
static int cr50_i2c_wait_tpm_ready(struct udevice *dev)
{
@@ -573,6 +654,87 @@ static int cr50_i2c_get_desc(struct udevice *dev, char *buf, int size)
return len;
}
+static int stringify_state(char *buf, int len, char *str, size_t max_size)
+{
+ struct tpm_vendor_state state;
+ size_t text_size = 0;
+
+ state.version = get_unaligned_be32(buf +
+ offsetof(struct tpm_vendor_state, version));
+ state.fail_line = get_unaligned_be32(buf +
+ offsetof(struct tpm_vendor_state, fail_line));
+ state.fail_code = get_unaligned_be32(buf +
+ offsetof(struct tpm_vendor_state, fail_code));
+ memcpy(state.func_name,
+ buf + offsetof(struct tpm_vendor_state, func_name),
+ sizeof(state.func_name));
+ state.failed_tries = get_unaligned_be32(buf +
+ offsetof(struct tpm_vendor_state, failed_tries));
+ state.max_tries = get_unaligned_be32(buf +
+ offsetof(struct tpm_vendor_state, max_tries));
+
+ text_size += snprintf(str + text_size, max_size - text_size,
+ "v=%d", state.version);
+ if (text_size >= max_size)
+ return -ENOSPC;
+
+ if (state.version > TPM_STATE_VERSION)
+ text_size += snprintf(str + text_size,
+ max_size - text_size,
+ " not fully supported\n");
+ if (text_size >= max_size)
+ return -ENOSPC;
+
+ if (state.version == 0)
+ return -EINVAL; /* This should never happen */
+
+ text_size += snprintf(str + text_size,
+ max_size - text_size,
+ " failed_tries=%d max_tries=%d\n",
+ state.failed_tries, state.max_tries);
+ if (text_size >= max_size)
+ return -ENOSPC;
+
+ if (state.fail_line) {
+ /* make sure function name is zero terminated. */
+ char func_name[sizeof(state.func_name) + 1];
+
+ memcpy(func_name, state.func_name, sizeof(state.func_name));
+ func_name[sizeof(state.func_name)] = '\0';
+
+ text_size += snprintf(str + text_size,
+ max_size - text_size,
+ "tpm failed: f %s line %d code %d",
+ func_name,
+ state.fail_line,
+ state.fail_code);
+ if (text_size >= max_size)
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+static int cr50_i2c_report_state(struct udevice *dev, char *str, int str_max)
+{
+ char buf[50];
+ size_t buf_size = sizeof(buf);
+ int ret;
+
+ ret = tpm2_report_state(dev, TPM2_CR50_VENDOR_COMMAND,
+ TPM2_CR50_SUB_CMD_REPORT_TPM_STATE,
+ buf, &buf_size);
+ if (ret)
+ return ret;
+
+ /* TPM responded as expected */
+ ret = stringify_state(buf, buf_size, str, str_max);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int cr50_i2c_open(struct udevice *dev)
{
char buf[80];
@@ -730,6 +892,7 @@ struct acpi_ops cr50_acpi_ops = {
static const struct tpm_ops cr50_i2c_ops = {
.open = cr50_i2c_open,
.get_desc = cr50_i2c_get_desc,
+ .report_state = cr50_i2c_report_state,
.send = cr50_i2c_send,
.recv = cr50_i2c_recv,
.cleanup = cr50_i2c_cleanup,
diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index 0eb35f5..5ff0cd3 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -49,6 +49,16 @@ int tpm_get_desc(struct udevice *dev, char *buf, int size)
return ops->get_desc(dev, buf, size);
}
+int tpm_report_state(struct udevice *dev, char *buf, int size)
+{
+ struct tpm_ops *ops = tpm_get_ops(dev);
+
+ if (!ops->report_state)
+ return -ENOSYS;
+
+ return ops->report_state(dev, buf, size);
+}
+
/* Returns max number of milliseconds to wait */
static ulong tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip_priv *priv,
u32 ordinal)
diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index ac6eb14..dd94bdc 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -366,8 +366,10 @@ static int sandbox_tpm2_check_readyness(struct udevice *dev, int command)
break;
default:
- if (!tpm->tests_done)
- return TPM2_RC_NEEDS_TEST;
+ /* Skip this, since the startup may have happened in SPL
+ * if (!tpm->tests_done)
+ * return TPM2_RC_NEEDS_TEST;
+ */
break;
}
@@ -793,6 +795,16 @@ static int sandbox_tpm2_get_desc(struct udevice *dev, char *buf, int size)
return snprintf(buf, size, "Sandbox TPM2.x");
}
+static int sandbox_tpm2_report_state(struct udevice *dev, char *buf, int size)
+{
+ struct sandbox_tpm2 *priv = dev_get_priv(dev);
+
+ if (size < 40)
+ return -ENOSPC;
+
+ return snprintf(buf, size, "init_done=%d", priv->init_done);
+}
+
static int sandbox_tpm2_open(struct udevice *dev)
{
struct sandbox_tpm2 *tpm = dev_get_priv(dev);
@@ -832,6 +844,7 @@ static const struct tpm_ops sandbox_tpm2_ops = {
.open = sandbox_tpm2_open,
.close = sandbox_tpm2_close,
.get_desc = sandbox_tpm2_get_desc,
+ .report_state = sandbox_tpm2_report_state,
.xfer = sandbox_tpm2_xfer,
};
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 8ba55aa..d0e92c7 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -119,6 +119,7 @@ static struct usb_descriptor_header *fb_fs_function[] = {
(struct usb_descriptor_header *)&interface_desc,
(struct usb_descriptor_header *)&fs_ep_in,
(struct usb_descriptor_header *)&fs_ep_out,
+ NULL,
};
static struct usb_descriptor_header *fb_hs_function[] = {