From 967eebcd85865b795351bfe4e77399b9f414c6c5 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Fri, 16 May 2025 14:53:14 +0530 Subject: pci: zynqmp: Fix the pcireg base The pcireg base is not assigned to any address, reading the pcireg base with PS_LINKUP_OFFSET which is incorrect and giving random values. So update the pcireg base from devicetree so that we can read the valid PCIE link status and PHY ready status. Signed-off-by: Venkatesh Yadav Abbarapu Reviewed-by: Stefan Roese Link: https://lore.kernel.org/r/20250516092314.939424-1-venkatesh.abbarapu@amd.com Signed-off-by: Michal Simek --- drivers/pci/pcie-xilinx-nwl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pcie-xilinx-nwl.c b/drivers/pci/pcie-xilinx-nwl.c index 7ef2bdf57b5..e03ab3be912 100644 --- a/drivers/pci/pcie-xilinx-nwl.c +++ b/drivers/pci/pcie-xilinx-nwl.c @@ -303,6 +303,13 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie) return PTR_ERR(pcie->breg_base); pcie->phys_breg_base = res.start; + ret = dev_read_resource_byname(dev, "pcireg", &res); + if (ret) + return ret; + pcie->pcireg_base = devm_ioremap(dev, res.start, resource_size(&res)); + if (IS_ERR(pcie->pcireg_base)) + return PTR_ERR(pcie->pcireg_base); + ret = dev_read_resource_byname(dev, "cfg", &res); if (ret) return ret; -- cgit v1.2.3 From 85f181b194c7d3810db4a0df8ea2386287b26be0 Mon Sep 17 00:00:00 2001 From: Naresh Kumar Ravulapalli Date: Mon, 5 May 2025 18:28:51 -0700 Subject: drivers: fpga: intel_sdm_mb: Flush cache before FPGA configuration FPGA configuration encounters failure when the cache is not flushed. Add cache flushing to the memory region that holds the FPGA configuration bitstream. Signed-off-by: Naresh Kumar Ravulapalli Link: https://lore.kernel.org/r/20250506012851.30039-1-nareshkumar.ravulapalli@altera.com Signed-off-by: Michal Simek --- drivers/fpga/intel_sdm_mb.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c index 5fe4dbdfd32..a2f3b160a73 100644 --- a/drivers/fpga/intel_sdm_mb.c +++ b/drivers/fpga/intel_sdm_mb.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2018 Intel Corporation + * Copyright (C) 2025 Altera Corporation */ #include @@ -9,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -738,6 +741,8 @@ int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) debug("Invoking FPGA_CONFIG_START...\n"); + flush_dcache_range((unsigned long)rbf_data, (unsigned long)(rbf_data + rbf_size)); + ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, &arg, 1, NULL, 0); if (ret) { @@ -1023,6 +1028,8 @@ int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size) u32 resp_len = 2; u32 resp_buf[2]; + flush_dcache_range((unsigned long)rbf_data, (unsigned long)(rbf_data + rbf_size)); + debug("Sending MBOX_RECONFIG...\n"); ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RECONFIG, MBOX_CMD_DIRECT, 0, NULL, 0, &resp_len, resp_buf); -- cgit v1.2.3 From 90df44fb4f0e1cbe18b02080ef8bf9e365f867b8 Mon Sep 17 00:00:00 2001 From: Frantisek Bohacek Date: Thu, 22 May 2025 08:07:03 +0200 Subject: phy: zynqmp: Fix sgmii clk ctrl GTR lane bit shift The bitshift in GEM_CLK_CTRL register is five bits, not two. There are four bits for each GEM, and one bit reserved in between. This has caused that using more than one GEM is impossible, additionally corrupting the GEM0's configuration, leaving GEM0 unusable as well (ie. if GEM0 and GEM1 are used, GEM1 configuration is going to write to GEM0's registers wrong value, leaving GEM0 unusable) Signed-off-by: Frantisek Bohacek Link: https://lore.kernel.org/r/20250522060703.4863-1-rutherther@ditigal.xyz Signed-off-by: Michal Simek --- drivers/phy/phy-zynqmp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/phy-zynqmp.c b/drivers/phy/phy-zynqmp.c index 7049e740d56..9649e660220 100644 --- a/drivers/phy/phy-zynqmp.c +++ b/drivers/phy/phy-zynqmp.c @@ -138,6 +138,7 @@ #define PROT_BUS_WIDTH_40 0x2 #define PROT_BUS_WIDTH_MASK 0x3 #define PROT_BUS_WIDTH_SHIFT 2 +#define GEM_CLK_CTRL_WIDTH_SHIFT 5 /* Number of GT lanes */ #define NUM_LANES 4 @@ -400,6 +401,7 @@ static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy) { struct xpsgtr_dev *gtr_dev = gtr_phy->dev; u32 shift = gtr_phy->lane * PROT_BUS_WIDTH_SHIFT; + u32 clk_ctrl_shift = gtr_phy->lane * GEM_CLK_CTRL_WIDTH_SHIFT; /* Set SGMII protocol TX and RX bus width to 10 bits. */ xpsgtr_clr_set(gtr_dev, TX_PROT_BUS_WIDTH, PROT_BUS_WIDTH_MASK << shift, @@ -417,9 +419,9 @@ static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy) */ /* GEM I/O Clock Control */ clrsetbits_le32(ZYNQMP_IOU_SLCR_BASEADDR + IOU_SLCR_GEM_CLK_CTRL, - 0xf << shift, + 0xf << clk_ctrl_shift, (GEM_CTRL_GEM_SGMII_MODE | GEM_CTRL_GEM_REF_SRC_SEL) << - shift); + clk_ctrl_shift); /* Setup signal detect */ clrsetbits_le32(ZYNQMP_IOU_SLCR_BASEADDR + IOU_SLCR_GEM_CTRL, -- cgit v1.2.3 From 6759bd73e9cf491c5049f87b84e627920efb5824 Mon Sep 17 00:00:00 2001 From: Martin Kaistra Date: Tue, 15 Apr 2025 17:04:00 +0200 Subject: net: gem: ignore tx_clk if MII is used If the MII interface is used, the PHY is the clock master, thus don't set the clock rate. On Zynq-7000, this will prevent the following error: zynq_gem ethernet@e000b000: failed to set tx clock rate 25000000 Signed-off-by: Martin Kaistra Link: https://lore.kernel.org/r/20250415150400.136723-1-martin.kaistra@linutronix.de Signed-off-by: Michal Simek --- drivers/net/zynq_gem.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 461805ae53f..703e22479d2 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -567,12 +567,14 @@ static int zynq_gem_init(struct udevice *dev) } #endif - ret = clk_get_rate(&priv->tx_clk); - if (ret != clk_rate) { - ret = clk_set_rate(&priv->tx_clk, clk_rate); - if (IS_ERR_VALUE(ret)) { - dev_err(dev, "failed to set tx clock rate %ld\n", clk_rate); - return ret; + if (priv->interface != PHY_INTERFACE_MODE_MII) { + ret = clk_get_rate(&priv->tx_clk); + if (ret != clk_rate) { + ret = clk_set_rate(&priv->tx_clk, clk_rate); + if (IS_ERR_VALUE(ret)) { + dev_err(dev, "failed to set tx clock rate %ld\n", clk_rate); + return ret; + } } } -- cgit v1.2.3 From ec7b49c4108afdca3864da45b5444efb327ce75c Mon Sep 17 00:00:00 2001 From: Wojciech Szamocki Date: Fri, 23 May 2025 12:57:07 +0200 Subject: i2c: designware_i2c Return -ETIMEDOUT for timeout errors Change the return value for timeout errors in i2c-designware from 1 to -ETIMEDOUT. Returning errors as negative values is standard practice in the u-boot, which enhances error handling consistency across the codebase. The current behavior can lead to silent errors when functions check for negative return values to identify errors. For example, in `dm_i2c_reg_read` from i2c-uclass.c, a timeout results in an uninitialized value being returned, potentially causing unexpected behavior. Cc: Heiko Schocher Cc: Tom Rini Cc: Wojciech Szamocki Signed-off-by: Wojciech Szamocki Reviewed-by: Heiko Schocher --- drivers/i2c/designware_i2c.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index e8c1623d41f..a54976e7889 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -404,7 +404,7 @@ static int i2c_wait_for_bb(struct i2c_regs *i2c_base) /* Evaluate timeout */ if (get_timer(start_time_bb) > (unsigned long)(I2C_BYTE_TO_BB)) - return 1; + return -ETIMEDOUT; } return 0; @@ -413,8 +413,10 @@ static int i2c_wait_for_bb(struct i2c_regs *i2c_base) static int i2c_xfer_init(struct i2c_regs *i2c_base, uchar chip, uint addr, int alen) { - if (i2c_wait_for_bb(i2c_base)) - return 1; + int ret = i2c_wait_for_bb(i2c_base); + + if (ret) + return ret; i2c_setaddress(i2c_base, chip); while (alen) { @@ -429,6 +431,7 @@ static int i2c_xfer_init(struct i2c_regs *i2c_base, uchar chip, uint addr, static int i2c_xfer_finish(struct i2c_regs *i2c_base) { ulong start_stop_det = get_timer(0); + int ret; while (1) { if ((readl(&i2c_base->ic_raw_intr_stat) & IC_STOP_DET)) { @@ -439,9 +442,10 @@ static int i2c_xfer_finish(struct i2c_regs *i2c_base) } } - if (i2c_wait_for_bb(i2c_base)) { + ret = i2c_wait_for_bb(i2c_base); + if (ret) { printf("Timed out waiting for bus\n"); - return 1; + return ret; } i2c_flush_rxfifo(i2c_base); @@ -464,6 +468,7 @@ static int __dw_i2c_read(struct i2c_regs *i2c_base, u8 dev, uint addr, { unsigned long start_time_rx; unsigned int active = 0; + int ret; #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW /* @@ -484,8 +489,9 @@ static int __dw_i2c_read(struct i2c_regs *i2c_base, u8 dev, uint addr, addr); #endif - if (i2c_xfer_init(i2c_base, dev, addr, alen)) - return 1; + ret = i2c_xfer_init(i2c_base, dev, addr, alen); + if (ret) + return ret; start_time_rx = get_timer(0); while (len) { @@ -510,7 +516,7 @@ static int __dw_i2c_read(struct i2c_regs *i2c_base, u8 dev, uint addr, start_time_rx = get_timer(0); active = 0; } else if (get_timer(start_time_rx) > I2C_BYTE_TO) { - return 1; + return -ETIMEDOUT; } } @@ -532,6 +538,7 @@ static int __dw_i2c_write(struct i2c_regs *i2c_base, u8 dev, uint addr, { int nb = len; unsigned long start_time_tx; + int ret; #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW /* @@ -552,8 +559,9 @@ static int __dw_i2c_write(struct i2c_regs *i2c_base, u8 dev, uint addr, addr); #endif - if (i2c_xfer_init(i2c_base, dev, addr, alen)) - return 1; + ret = i2c_xfer_init(i2c_base, dev, addr, alen); + if (ret) + return ret; start_time_tx = get_timer(0); while (len) { @@ -569,7 +577,7 @@ static int __dw_i2c_write(struct i2c_regs *i2c_base, u8 dev, uint addr, } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) { printf("Timed out. i2c write Failed\n"); - return 1; + return -ETIMEDOUT; } } -- cgit v1.2.3 From eb2c63ddccb94b134846f890fcada84554ba2896 Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Sat, 12 Apr 2025 18:41:31 +0100 Subject: power: qcom_vbus_regulator: add and fix support for pmic variants Fix and add support for different pmic variants pm8x50b to handle the vbus regulator. Signed-off-by: Rui Miguel Silva Link: https://lore.kernel.org/r/20250412174157.104419-1-rui.silva@linaro.org Signed-off-by: Casey Connolly --- drivers/power/regulator/qcom_usb_vbus_regulator.c | 37 ++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/power/regulator/qcom_usb_vbus_regulator.c b/drivers/power/regulator/qcom_usb_vbus_regulator.c index 2d58ef5e111..07f118d4797 100644 --- a/drivers/power/regulator/qcom_usb_vbus_regulator.c +++ b/drivers/power/regulator/qcom_usb_vbus_regulator.c @@ -15,14 +15,33 @@ #include #include -#define CMD_OTG 0x50 +enum pm8x50b_vbus { + PM8150B, + PM8550B, +}; + #define OTG_EN BIT(0) -// The 0 bit in this register's bit field is undocumented -#define OTG_CFG 0x56 + #define OTG_EN_SRC_CFG BIT(1) +struct qcom_otg_regs { + u32 otg_cmd; + u32 otg_cfg; +}; struct qcom_usb_vbus_priv { phys_addr_t base; + struct qcom_otg_regs *regs; +}; + +static const struct qcom_otg_regs qcom_otg[] = { + [PM8150B] = { + .otg_cmd = 0x40, + .otg_cfg = 0x53, + }, + [PM8550B] = { + .otg_cmd = 0x50, + .otg_cfg = 0x56, + }, }; static int qcom_usb_vbus_regulator_of_to_plat(struct udevice *dev) @@ -38,8 +57,9 @@ static int qcom_usb_vbus_regulator_of_to_plat(struct udevice *dev) static int qcom_usb_vbus_regulator_get_enable(struct udevice *dev) { + const struct qcom_otg_regs *regs = &qcom_otg[dev_get_driver_data(dev)]; struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); - int otg_en_reg = priv->base + CMD_OTG; + int otg_en_reg = priv->base + regs->otg_cmd; int ret; ret = pmic_reg_read(dev->parent, otg_en_reg); @@ -53,8 +73,9 @@ static int qcom_usb_vbus_regulator_get_enable(struct udevice *dev) static int qcom_usb_vbus_regulator_set_enable(struct udevice *dev, bool enable) { + const struct qcom_otg_regs *regs = &qcom_otg[dev_get_driver_data(dev)]; struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); - int otg_en_reg = priv->base + CMD_OTG; + int otg_en_reg = priv->base + regs->otg_cmd; int ret; if (enable) { @@ -76,8 +97,9 @@ static int qcom_usb_vbus_regulator_set_enable(struct udevice *dev, bool enable) static int qcom_usb_vbus_regulator_probe(struct udevice *dev) { + const struct qcom_otg_regs *regs = &qcom_otg[dev_get_driver_data(dev)]; struct qcom_usb_vbus_priv *priv = dev_get_priv(dev); - int otg_cfg_reg = priv->base + OTG_CFG; + int otg_cfg_reg = priv->base + regs->otg_cfg; int ret; /* Disable HW logic for VBUS enable */ @@ -96,7 +118,8 @@ static const struct dm_regulator_ops qcom_usb_vbus_regulator_ops = { }; static const struct udevice_id qcom_usb_vbus_regulator_ids[] = { - { .compatible = "qcom,pm8150b-vbus-reg"}, + { .compatible = "qcom,pm8150b-vbus-reg", .data = PM8150B }, + { .compatible = "qcom,pm8550b-vbus-reg", .data = PM8550B }, { }, }; -- cgit v1.2.3 From 3d9e6d42ca1433c6dd478bf6c0f73e2b9484c94c Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 24 Apr 2025 11:16:41 +0200 Subject: clk: qcom: apq8016: Fix SDCC clock addresses The SDCC_...(n) macros in clock-apq8016.c result in the wrong addresses: - SDCC1: SDCC_APPS_CBCR(0) = ((0 * 0x1000) + 0x41018) = 0x41018 Should be 0x42018, this is an invalid register close to the USB clocks. - SDCC2: SDCC_APPS_CBCR(1) = ((1 * 0x1000) + 0x41018) = 0x42018 Should be 0x43018, this is the SDCC1 clock. When we try to enable SDCC2, we actually end up enabling SDCC1. When we try to enable SDCC1, we just issue some broken register writes. This hasn't caused any trouble so far, because the boot firmware is keeping both SDCC clocks running. However, if these clocks are disabled when entering U-Boot, MMC initialization is failing. Fix this by using the proper offset for the macros. The SDCC_CMD_RCGR() was already correct, but change it the same way for consistency. Fixes: 085921368b7d ("arm: Add support for Qualcomm Snapdragon family") Reviewed-by: Neil Armstrong Signed-off-by: Stephan Gerhold Reviewed-by: Sumit Garg Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424-apq8016-clock-fixes2-v2-1-fcc371c9e45f@linaro.org Signed-off-by: Casey Connolly --- drivers/clk/qcom/clock-apq8016.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index 6a53f900a9e..274c71c53ff 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -23,10 +23,10 @@ #define APCS_GPLL_ENA_VOTE (0x45000) #define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004) -#define SDCC_BCR(n) ((n * 0x1000) + 0x41000) -#define SDCC_CMD_RCGR(n) (((n + 1) * 0x1000) + 0x41004) -#define SDCC_APPS_CBCR(n) ((n * 0x1000) + 0x41018) -#define SDCC_AHB_CBCR(n) ((n * 0x1000) + 0x4101C) +#define SDCC_BCR(n) (((n) * 0x1000) + 0x42000) +#define SDCC_CMD_RCGR(n) (((n) * 0x1000) + 0x42004) +#define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x42018) +#define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4201C) /* BLSP1 AHB clock (root clock for BLSP) */ #define BLSP1_AHB_CBCR 0x1008 -- cgit v1.2.3 From 409da8c4935338743b054e7c82f463c4a1c538e0 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 24 Apr 2025 11:16:42 +0200 Subject: clk: qcom: Move qcom_gate_clk_en() to C file This avoids having to inline it separately into every single clock driver, when U-Boot is built with support for multiple SoCs. Reviewed-by: Neil Armstrong Signed-off-by: Stephan Gerhold Reviewed-by: Sumit Garg Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424-apq8016-clock-fixes2-v2-2-fcc371c9e45f@linaro.org Signed-off-by: Casey Connolly --- drivers/clk/qcom/clock-qcom.c | 15 +++++++++++++++ drivers/clk/qcom/clock-qcom.h | 15 +-------------- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 7687bbe6a23..5018851725b 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -74,6 +74,21 @@ void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk) } while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL)); } +int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) +{ + u32 val; + if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) { + log_err("gcc@%#08llx: unknown clock ID %lu!\n", + priv->base, id); + return -ENOENT; + } + + val = readl(priv->base + priv->data->clks[id].reg); + writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg); + + return 0; +} + #define APPS_CMD_RCGR_UPDATE BIT(0) /* Update clock command via CMD_RCGR */ diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index f43edea2525..ee0347d9d86 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -107,19 +107,6 @@ void clk_rcg_set_rate(phys_addr_t base, uint32_t cmd_rcgr, int div, int source); void clk_phy_mux_enable(phys_addr_t base, uint32_t cmd_rcgr, bool enabled); -static inline int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) -{ - u32 val; - if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) { - log_err("gcc@%#08llx: unknown clock ID %lu!\n", - priv->base, id); - return -ENOENT; - } - - val = readl(priv->base + priv->data->clks[id].reg); - writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg); - - return 0; -} +int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id); #endif -- cgit v1.2.3 From 94e57ba2011b4bb96c0714e02a5056bc0c7f87d0 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 24 Apr 2025 11:16:43 +0200 Subject: clk: qcom: Use setbits_le32() for qcom_gate_clk_en() The other clock enable functions in clock-qcom.c use setbits_le32() to read/modify/write the enable registers. Use the same for qcom_gate_clk_en() to simplify the code a bit. Reviewed-by: Neil Armstrong Signed-off-by: Stephan Gerhold Reviewed-by: Sumit Garg Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424-apq8016-clock-fixes2-v2-3-fcc371c9e45f@linaro.org Signed-off-by: Casey Connolly --- drivers/clk/qcom/clock-qcom.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 5018851725b..7a259db7934 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -76,16 +76,13 @@ void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk) int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) { - u32 val; if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) { log_err("gcc@%#08llx: unknown clock ID %lu!\n", priv->base, id); return -ENOENT; } - val = readl(priv->base + priv->data->clks[id].reg); - writel(val | priv->data->clks[id].en_val, priv->base + priv->data->clks[id].reg); - + setbits_le32(priv->base + priv->data->clks[id].reg, priv->data->clks[id].en_val); return 0; } -- cgit v1.2.3 From 6c049ed99392353bcda24f708e1cfa5c21f2a0f9 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 24 Apr 2025 11:16:44 +0200 Subject: clk: qcom: Allow polling for clock status in qcom_gate_clk_en() GATE_CLK() in its current state is unsafe: A simple write to the clock enable register does not guarantee that the clock is immediately running. Without polling the clock status, we may issue writes to registers before the necessary clocks start running. This doesn't seem to cause issues in U-Boot at the moment, but for example removing the CLK_OFF polling in TF-A for the SMMU clocks on DB410c reliably triggers an exception during boot. Make it possible to poll the branch clock status register, by adding a new GATE_CLK_POLLED() macro that takes the extra register address. Existing usages work just as before, without polling the clock status. Ideally all usages should be updated to specify the correct poll address in the future. The Qualcomm naming for these clocks is "branch" and not "gate", but let's keep the existing naming for now to avoid confusion until all others drivers have been converted. Reviewed-by: Neil Armstrong Signed-off-by: Stephan Gerhold Reviewed-by: Sumit Garg Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424-apq8016-clock-fixes2-v2-4-fcc371c9e45f@linaro.org Signed-off-by: Casey Connolly --- drivers/clk/qcom/clock-qcom.c | 15 +++++++++++++++ drivers/clk/qcom/clock-qcom.h | 11 +++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/clock-qcom.c b/drivers/clk/qcom/clock-qcom.c index 7a259db7934..6b46d9db744 100644 --- a/drivers/clk/qcom/clock-qcom.c +++ b/drivers/clk/qcom/clock-qcom.c @@ -83,6 +83,21 @@ int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id) } setbits_le32(priv->base + priv->data->clks[id].reg, priv->data->clks[id].en_val); + if (priv->data->clks[id].cbcr_reg) { + unsigned int count; + u32 val; + + for (count = 0; count < 200; count++) { + val = readl(priv->base + priv->data->clks[id].cbcr_reg); + val &= BRANCH_CHECK_MASK; + if (val == BRANCH_ON_VAL || val == BRANCH_NOC_FSM_ON_VAL) + break; + udelay(1); + } + if (WARN(count == 200, "WARNING: Clock @ %#lx [%#010x] stuck at off\n", + priv->data->clks[id].cbcr_reg, val)) + return -EBUSY; + } return 0; } diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index ee0347d9d86..1b60882dae4 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -52,13 +52,20 @@ struct freq_tbl { struct gate_clk { uintptr_t reg; u32 en_val; + uintptr_t cbcr_reg; const char *name; }; +/* + * GATE_CLK() is deprecated: Use GATE_CLK_POLLED() instead to ensure the clock + * is running before we start making use of devices or registers. + */ #ifdef DEBUG -#define GATE_CLK(clk, reg, val) [clk] = { reg, val, #clk } +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, 0, #clk } +#define GATE_CLK_POLLED(clk, en_reg, val, cbcr_reg) [clk] = { en_reg, val, cbcr_reg, #clk } #else -#define GATE_CLK(clk, reg, val) [clk] = { reg, val, NULL } +#define GATE_CLK(clk, reg, val) [clk] = { reg, val, 0, NULL } +#define GATE_CLK_POLLED(clk, en_reg, val, cbcr_reg) [clk] = { en_reg, val, cbcr_reg, NULL } #endif struct qcom_reset_map { -- cgit v1.2.3 From 9d9bac00bc071deaeac1428c9d7dfe0afa1939a7 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 24 Apr 2025 11:16:45 +0200 Subject: clk: qcom: apq8016: Convert GATE_CLK() to GATE_CLK_POLLED() Convert the usages of GATE_CLK() in clock-apq8016 to GATE_CLK_POLLED() to make sure that we poll the status when enabling clocks: - PRNG_AHB_CLK is a vote clock, so we poll a different register address. - The USB clocks are simple branches, so enable/poll is the same register. Reviewed-by: Neil Armstrong Signed-off-by: Stephan Gerhold Reviewed-by: Sumit Garg Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424-apq8016-clock-fixes2-v2-5-fcc371c9e45f@linaro.org Signed-off-by: Casey Connolly --- drivers/clk/qcom/clock-apq8016.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index 274c71c53ff..e3a9807f580 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -54,9 +54,9 @@ static struct vote_clk gcc_blsp1_ahb_clk = { }; static const struct gate_clk apq8016_clks[] = { - GATE_CLK(GCC_PRNG_AHB_CLK, 0x45004, BIT(8)), - GATE_CLK(GCC_USB_HS_AHB_CLK, 0x41008, BIT(0)), - GATE_CLK(GCC_USB_HS_SYSTEM_CLK, 0x41004, BIT(0)), + GATE_CLK_POLLED(GCC_PRNG_AHB_CLK, 0x45004, BIT(8), 0x13004), + GATE_CLK_POLLED(GCC_USB_HS_AHB_CLK, 0x41008, BIT(0), 0x41008), + GATE_CLK_POLLED(GCC_USB_HS_SYSTEM_CLK, 0x41004, BIT(0), 0x41004), }; /* SDHCI */ -- cgit v1.2.3 From 1079d4bf2ed88e7e34a56152a63eb16fca7f7811 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 24 Apr 2025 11:16:46 +0200 Subject: clk: qcom: apq8016: Fix SDCC clock warnings As of commit dc8754e8e408 ("clk/qcom: apq8016: improve clk_enable logging") there are now warnings in the U-Boot console on DragonBoard 410c: apq8016_clk_enable: unknown clk id 122 apq8016_clk_enable: unknown clk id 123 apq8016_clk_enable: unknown clk id 124 apq8016_clk_enable: unknown clk id 125 This is because we don't implement enable() properly for the SDCC clocks. Currently they are being enabled as part of set_rate(). Fix this by moving the enable calls out of the apq8016_clk_init_sdc() function and convert them to the equivalent GATE_CLK_POLLED() definitions. Reviewed-by: Neil Armstrong Signed-off-by: Stephan Gerhold Reviewed-by: Sumit Garg Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424-apq8016-clock-fixes2-v2-6-fcc371c9e45f@linaro.org Signed-off-by: Casey Connolly --- drivers/clk/qcom/clock-apq8016.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/qcom/clock-apq8016.c b/drivers/clk/qcom/clock-apq8016.c index e3a9807f580..b7bd9c9a342 100644 --- a/drivers/clk/qcom/clock-apq8016.c +++ b/drivers/clk/qcom/clock-apq8016.c @@ -23,10 +23,7 @@ #define APCS_GPLL_ENA_VOTE (0x45000) #define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004) -#define SDCC_BCR(n) (((n) * 0x1000) + 0x42000) #define SDCC_CMD_RCGR(n) (((n) * 0x1000) + 0x42004) -#define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x42018) -#define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4201C) /* BLSP1 AHB clock (root clock for BLSP) */ #define BLSP1_AHB_CBCR 0x1008 @@ -55,6 +52,10 @@ static struct vote_clk gcc_blsp1_ahb_clk = { static const struct gate_clk apq8016_clks[] = { GATE_CLK_POLLED(GCC_PRNG_AHB_CLK, 0x45004, BIT(8), 0x13004), + GATE_CLK_POLLED(GCC_SDCC1_AHB_CLK, 0x4201c, BIT(0), 0x4201c), + GATE_CLK_POLLED(GCC_SDCC1_APPS_CLK, 0x42018, BIT(0), 0x42018), + GATE_CLK_POLLED(GCC_SDCC2_AHB_CLK, 0x4301c, BIT(0), 0x4301c), + GATE_CLK_POLLED(GCC_SDCC2_APPS_CLK, 0x43018, BIT(0), 0x43018), GATE_CLK_POLLED(GCC_USB_HS_AHB_CLK, 0x41008, BIT(0), 0x41008), GATE_CLK_POLLED(GCC_USB_HS_SYSTEM_CLK, 0x41004, BIT(0), 0x41004), }; @@ -67,12 +68,10 @@ static int apq8016_clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate) if (rate == 200000000) div = 4; - clk_enable_cbc(priv->base + SDCC_AHB_CBCR(slot)); /* 800Mhz/div, gpll0 */ clk_rcg_set_rate_mnd(priv->base, SDCC_CMD_RCGR(slot), div, 0, 0, CFG_CLK_SRC_GPLL0, 8); clk_enable_gpll0(priv->base, &gpll0_vote_clk); - clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot)); return rate; } -- cgit v1.2.3 From c92bf21e731a20d7de6acacd6487e98c69fd2a83 Mon Sep 17 00:00:00 2001 From: Alexey Minnekhanov Date: Thu, 24 Apr 2025 04:48:11 +0300 Subject: button: qcom-pmic: allow to specify code in devicetree Most device vendors put "Volume Down" button onto PMIC RESIN. But Sony is special: see dts/upstream/src/arm64/qcom/sdm630-sony-xperia-nile.dtsi or [1]. They put "Volume Down" on PMIC GPIO 7 where others usually put "Volume Up", and KEY_VOLUMEUP is inside &pon_resin. Currently if you boot U-Boot on such Sony device, you end up with 2 "Volume Down" buttons, and no "Volume Up", which makes navigating menu problematic. Support reading devicetree "linux,code" property and override statically defined button code & label based on that. [1] https://elixir.bootlin.com/linux/v6.15-rc3/source/arch/ arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi#L263 Signed-off-by: Alexey Minnekhanov Signed-off-by: Alexey Minnekhanov Reviewed-by: Casey Connolly Link: https://lore.kernel.org/r/20250424014811.3809818-1-alexeymin@minlexx.ru Signed-off-by: Casey Connolly --- drivers/button/button-qcom-pmic.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/button/button-qcom-pmic.c b/drivers/button/button-qcom-pmic.c index e3bb9bd758a..85addfe32a2 100644 --- a/drivers/button/button-qcom-pmic.c +++ b/drivers/button/button-qcom-pmic.c @@ -143,6 +143,21 @@ static int qcom_pwrkey_probe(struct udevice *dev) priv->base = base; + ret = dev_read_u32(dev, "linux,code", &priv->code); + if (ret == 0) { + /* convert key, if read OK */ + switch (priv->code) { + case KEY_VOLUMEDOWN: + priv->code = KEY_DOWN; + uc_plat->label = "Volume Down"; + break; + case KEY_VOLUMEUP: + priv->code = KEY_UP; + uc_plat->label = "Volume Up"; + break; + } + } + /* Do a sanity check */ ret = pmic_reg_read(priv->pmic, priv->base + REG_TYPE); if (ret != 0x1 && ret != 0xb) { -- cgit v1.2.3 From 2782ce5fce883554c968b8852a5ecfde0f2b9a95 Mon Sep 17 00:00:00 2001 From: Judith Mendez Date: Thu, 22 May 2025 10:05:50 -0500 Subject: mmc: am654_sdhci: Clear UHS_MODE_SELECT when <= MMC_HS_52 This clears UHS_MODE_SELECT for timing modes <= MMC_HS_52. When initializing to HS400 mode, the host controller downgrades to non-uhs modes so clear UHS_MODE_SELECT at modes <= MMC_HS_52. This fixes eMMC writes on j7200 EVM. Fixes: 6067aa66b3bb ("mmc: am654_sdhci: Add am654_sdhci_set_control_reg") Signed-off-by: Judith Mendez Reviewed-by: Peng Fan --- drivers/mmc/am654_sdhci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c index 0df3568f073..d3c8f94dd0c 100644 --- a/drivers/mmc/am654_sdhci.c +++ b/drivers/mmc/am654_sdhci.c @@ -527,11 +527,16 @@ static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) void am654_sdhci_set_control_reg(struct sdhci_host *host) { struct mmc *mmc = host->mmc; + u32 reg; + reg = sdhci_readw(host, SDHCI_HOST_CONTROL2); + reg &= ~SDHCI_CTRL_UHS_MASK; sdhci_set_voltage(host); if (mmc->selected_mode > MMC_HS_52) sdhci_set_uhs_timing(host); + else + sdhci_writew(host, reg, SDHCI_HOST_CONTROL2); } const struct sdhci_ops am654_sdhci_ops = { -- cgit v1.2.3 From 6773a46f1131fe95bcddb7472635e07a5fd249f8 Mon Sep 17 00:00:00 2001 From: Lukasz Czechowski Date: Tue, 20 May 2025 13:36:41 +0200 Subject: ram: rockchip: Fix dependency of RAM_ROCKCHIP_DEBUG The RAM_ROCKCHIP_DEBUG can be used only if DEBUG_UART is available. The next commit introduces changes in definition of debug uart functions, so that DEBUG_UART is required to be defined in order to initialize uart and use print functions. Signed-off-by: Lukasz Czechowski Reviewed-by: Kever Yang Reviewed-by: Quentin Schulz --- drivers/ram/rockchip/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig index 67c63ecba04..d707d09c1c8 100644 --- a/drivers/ram/rockchip/Kconfig +++ b/drivers/ram/rockchip/Kconfig @@ -15,6 +15,7 @@ if RAM_ROCKCHIP config RAM_ROCKCHIP_DEBUG bool "Rockchip ram drivers debugging" + depends on DEBUG_UART default y help This enables debugging ram driver API's for the platforms -- cgit v1.2.3 From 81a26131bdf5d094c9d2cda89a06dca90f9084a1 Mon Sep 17 00:00:00 2001 From: Justin Klaassen Date: Fri, 23 May 2025 16:53:37 +0000 Subject: rockchip: io-domain: Add debug logging for regulators during probe Log the value of the regulators during initialization of the IO-domain driver to aid in debugging GPIO voltage configuration problems. Signed-off-by: Justin Klaassen Reviewed-by: Quentin Schulz Reviewed-by: Kever Yang --- drivers/misc/rockchip-io-domain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/rockchip-io-domain.c b/drivers/misc/rockchip-io-domain.c index 025b6049a9f..a0573c52193 100644 --- a/drivers/misc/rockchip-io-domain.c +++ b/drivers/misc/rockchip-io-domain.c @@ -344,8 +344,10 @@ static int rockchip_iodomain_probe(struct udevice *dev) continue; ret = device_get_supply_regulator(dev, supply_name, ®); - if (ret) + if (ret) { + dev_dbg(dev, "%s: Regulator not found\n", supply_name); continue; + } ret = regulator_autoset(reg); if (ret && ret != -EALREADY && ret != -EMEDIUMTYPE && @@ -353,6 +355,7 @@ static int rockchip_iodomain_probe(struct udevice *dev) continue; uV = regulator_get_value(reg); + dev_dbg(dev, "%s: Regulator %s at %d uV\n", supply_name, reg->name, uV); if (uV <= 0) continue; -- cgit v1.2.3 From 83b1d04765de8aa9cfaa76d2db37b493a46cf504 Mon Sep 17 00:00:00 2001 From: Justin Klaassen Date: Fri, 23 May 2025 16:53:38 +0000 Subject: rockchip: io-domain: Add CONFIG_SPL_ROCKCHIP_IODOMAIN Allows use of the Rockchip IO-domain driver in SPL to configure the GPIO to match the voltage supplied by specific regulators (e.g. "vcc_sdio"). Signed-off-by: Justin Klaassen Reviewed-by: Quentin Schulz Reviewed-by: Kever Yang --- drivers/misc/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index ffc5868c0dd..8b8f6309ada 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -114,6 +114,14 @@ config ROCKCHIP_IODOMAIN for the IO-domain setting of the SoC to match the voltage supplied by the regulators. +config SPL_ROCKCHIP_IODOMAIN + bool "Rockchip IO-domain driver support in SPL" + depends on SPL_MISC && SPL_DM_REGULATOR && ARCH_ROCKCHIP + help + Enable support for IO-domains in Rockchip SoCs in SPL. It is necessary + for the IO-domain setting of the SoC to match the voltage supplied + by the regulators. + config SIFIVE_OTP bool "SiFive eMemory OTP driver" depends on MISC -- cgit v1.2.3 From f8f865ec0b17d756e10d4088bff1814744044dd3 Mon Sep 17 00:00:00 2001 From: Justin Klaassen Date: Fri, 23 May 2025 16:53:39 +0000 Subject: regulator: rk8xx: Add CONFIG_SPL_REGULATOR_RK8XX Allows use of the regulator functions of the RK8XX PMIC in SPL, which is necessary to support the functionality of the Rockchip IO-domain driver on relevant platforms. Signed-off-by: Justin Klaassen Reviewed-by: Quentin Schulz Reviewed-by: Kever Yang --- drivers/power/regulator/Kconfig | 9 +++++++++ drivers/power/regulator/rk8xx.c | 8 ++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 7ed435f0202..65b99e89656 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -264,6 +264,15 @@ config REGULATOR_RK8XX by the PMIC device. This driver is controlled by a device tree node which includes voltage limits. +config SPL_REGULATOR_RK8XX + bool "Enable driver for RK8XX regulators in SPL" + depends on SPL_DM_REGULATOR && SPL_PMIC_RK8XX + help + Enable support for the regulator functions of the RK8XX PMIC in SPL. The + driver implements get/set api for the various BUCKS and LDOs supported + by the PMIC device. This driver is controlled by a device tree node + which includes voltage limits. + config DM_REGULATOR_S2MPS11 bool "Enable driver for S2MPS11 regulator" depends on DM_REGULATOR && PMIC_S2MPS11 diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c index 368675ebb9f..88453bb7bdb 100644 --- a/drivers/power/regulator/rk8xx.c +++ b/drivers/power/regulator/rk8xx.c @@ -16,10 +16,6 @@ #include #include -#ifndef CONFIG_XPL_BUILD -#define ENABLE_DRIVER -#endif - /* Not used or exisit register and configure */ #define NA 0xff @@ -202,7 +198,7 @@ static const struct rk8xx_reg_info rk818_buck[] = { { 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, 0x00, 0x1f }, }; -#ifdef ENABLE_DRIVER +#if CONFIG_IS_ENABLED(REGULATOR_RK8XX) static const struct rk8xx_reg_info rk806_nldo[] = { /* nldo 1 */ { 500000, 12500, RK806_NLDO_ON_VSEL(1), RK806_NLDO_SLP_VSEL(1), NA, RK806_NLDO_VSEL_MASK, 0x00, 0xe7}, @@ -454,7 +450,7 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) return ret; } -#ifdef ENABLE_DRIVER +#if CONFIG_IS_ENABLED(REGULATOR_RK8XX) static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt) { const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt); -- cgit v1.2.3 From b8101af3ce56a547f373d273d9ea37aefb74dc5a Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 28 May 2025 14:07:27 +0200 Subject: power: rk8xx: fix swapped mask and value in init registers for RK806 The val (the bits to set) is the second member of the reg_data structure and mask the third one. We obviously want to clear bits 6 and 7 in order to only set bit 7 in there instead of only clearing bit 7 in order to write bits 6 and 7 (which makes no sense). Fortunately, according to the datasheet, bit 6 value doesn't matter when bit 7 is set so this is essentially just a cosmetic change, no intended change in behavior. Fixes: f172575d92cd ("power: rk8xx: add support for RK806") Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang --- drivers/power/pmic/rk8xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c index a14555cf472..3bc696d4caa 100644 --- a/drivers/power/pmic/rk8xx.c +++ b/drivers/power/pmic/rk8xx.c @@ -91,7 +91,7 @@ void rk8xx_off_for_plugin(struct udevice *dev) static struct reg_data rk806_init_reg[] = { /* RST_FUN */ - { RK806_REG_SYS_CFG3, GENMASK(7, 6), BIT(7)}, + { RK806_REG_SYS_CFG3, BIT(7), GENMASK(7, 6)}, }; static struct reg_data rk817_init_reg[] = { -- cgit v1.2.3 From b492f9520c04b1c581f57735e224612155f66780 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 5 Jun 2025 07:52:44 -0300 Subject: Revert "caam: Fix CAAM error on startup" This reverts commit 159b6f0e119962ce5da645f548cefe9196c8778e. Since commit 159b6f0e1199 ("caam: Fix CAAM error on startup") the following regression was reported by Tim Harvey: "I've found that this patch causes a regression on an imx8mm board (imx8mm_venice_defconfig) where the first call to caam_rng_read fails here in jr_dequeue but if you call it again it works. With some debugging added: SEC0: RNG instantiated ... Hit any key to stop autoboot: 0 u-boot=> rng list RNG #0 - caam-rng u-boot=> rng 0 10 caam_rng_read caam-rng len=16 run_descriptor_jr_idx idx=0 Error in SEC deq: -1 caam_rng_read_one run_descriptor_jr failed: -1 caam_rng_read caam-rng caam_rng_read_one failed: -5 Reading RNG failed u-boot=> rng 0 10 caam_rng_read caam-rng len=16 run_descriptor_jr_idx idx=0 00000000: ad 2e ad c0 2a 12 27 c4 65 82 66 19 be ef f6 07 ....*.'.e.f..... If I revert your patch caam_rng_read works initially and on subsequent calls." " I ran into this when I was testing lwIP HTTPS as it causes anything that uses dm_rng to fail the first time (such as HTTPS)." Revert it for now to avoid the regression. Reported-by: Tim Harvey Signed-off-by: Fabio Estevam Acked-by: Peng Fan --- drivers/crypto/fsl/jr.c | 25 +++++++++++-------------- drivers/crypto/fsl/jr.h | 4 ++++ 2 files changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 1d95d2bff27..8f7a821ebf3 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -217,6 +217,13 @@ static int jr_enqueue(uint32_t *desc_addr, jr->head = (head + 1) & (jr->size - 1); + /* Invalidate output ring */ + start = (unsigned long)jr->output_ring & + ~(ARCH_DMA_MINALIGN - 1); + end = ALIGN((unsigned long)jr->output_ring + jr->op_size, + ARCH_DMA_MINALIGN); + invalidate_dcache_range(start, end); + sec_out32(®s->irja, 1); return 0; @@ -236,7 +243,6 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) #else uint32_t *addr; #endif - unsigned long start, end; while (sec_in32(®s->orsf) && CIRC_CNT(jr->head, jr->tail, jr->size)) { @@ -244,11 +250,6 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) found = 0; caam_dma_addr_t op_desc; - - /* Invalidate output ring */ - start = (unsigned long)jr->output_ring & ~(ARCH_DMA_MINALIGN - 1); - end = ALIGN((unsigned long)jr->output_ring + jr->op_size, ARCH_DMA_MINALIGN); - invalidate_dcache_range(start, end); #ifdef CONFIG_CAAM_64BIT /* Read the 64 bit Descriptor address from Output Ring. * The 32 bit hign and low part of the address will @@ -282,13 +283,8 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) } /* Error condition if match not found */ - if (!found) { - int slots_full = sec_in32(®s->orsf); - - jr->tail = (jr->tail + slots_full) & (jr->size - 1); - sec_out32(®s->orjr, slots_full); + if (!found) return -1; - } jr->info[idx].op_done = 1; callback = (void *)jr->info[idx].callback; @@ -300,14 +296,14 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam) */ if (idx == tail) do { - jr->info[tail].op_done = 0; tail = (tail + 1) & (jr->size - 1); } while (jr->info[tail].op_done); jr->tail = tail; - + jr->read_idx = (jr->read_idx + 1) & (jr->size - 1); sec_out32(®s->orjr, 1); + jr->info[idx].op_done = 0; callback(status, arg); } @@ -382,6 +378,7 @@ static int jr_sw_cleanup(uint8_t sec_idx, struct caam_regs *caam) jr->head = 0; jr->tail = 0; + jr->read_idx = 0; jr->write_idx = 0; memset(jr->info, 0, sizeof(jr->info)); memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t)); diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h index 8d5ca03e501..b136cd8d05a 100644 --- a/drivers/crypto/fsl/jr.h +++ b/drivers/crypto/fsl/jr.h @@ -83,6 +83,10 @@ struct jobring { * in-order job completion */ int tail; + /* Read index of the output ring. It may not match with tail in case + * of out of order completetion + */ + int read_idx; /* Write index to input ring. Would be always equal to head */ int write_idx; /* Size of the rings. */ -- cgit v1.2.3