diff options
author | Tom Rini <trini@konsulko.com> | 2025-07-08 09:40:39 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-07-08 09:40:39 -0600 |
commit | 72582405a695f90a977931f15486a9a4be3de455 (patch) | |
tree | 7bc87eac423c600fb96d49b2371acfb71e87b908 /drivers | |
parent | f75eaf7356933661ae13b1f5c815ac6ed475eab3 (diff) | |
parent | a00f312e745db563e5c992e461dc4d24ed949370 (diff) |
Merge tag 'xilinx-for-v2025.10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze
AMD/Xilinx changes for v2025.10-rc1
cmd:
- Introduce CMD_HELP Kconfig option
fpga:
- Fix in intel_smd_mb
mini:
- Remove simple-bus driver and description
- Disable CMD_HELP
firmware:
- Fix dependencies
- Switch to new SMC firmware format
cadence qspi:
- Fix read/write STIG mode
- Set tshsl_ns to at least one sclk_ns
sdhci:
- Call sdhci reset if wired
zynqmp-clk:
- Add support for DPLL clock source
zynqmp:
- Sync clock ID bindings with Linux
- defconfig updates
- Enable rng-seed generation
versal:
- Fix clock dependency
versal2:
- defconfig updates
- Enable sysreset
# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYIAB0WIQSXAixArPbWpRanWW+rB/7wTvUR9QUCaG0Z7AAKCRCrB/7wTvUR
# 9YyCAQCseYDzYZbdh4e2g6LirVovzPv2LUNRFInYSKleegOjiwEAgQ0p9wZ0hNNj
# TpWf6sOKa/0ad3bZBtvbuV0G9WpqWAA=
# =2pbC
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 08 Jul 2025 07:15:24 AM CST
# gpg: using EDDSA key 97022C40ACF6D6A516A7596FAB07FEF04EF511F5
# gpg: Can't check signature: No public key
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/Kconfig | 2 | ||||
-rw-r--r-- | drivers/clk/clk_zynqmp.c | 20 | ||||
-rw-r--r-- | drivers/firmware/Kconfig | 1 | ||||
-rw-r--r-- | drivers/firmware/firmware-zynqmp.c | 60 | ||||
-rw-r--r-- | drivers/fpga/intel_sdm_mb.c | 3 | ||||
-rw-r--r-- | drivers/mmc/zynq_sdhci.c | 22 | ||||
-rw-r--r-- | drivers/spi/cadence_ospi_versal.c | 12 | ||||
-rw-r--r-- | drivers/spi/cadence_qspi.h | 4 | ||||
-rw-r--r-- | drivers/spi/cadence_qspi_apb.c | 13 |
9 files changed, 105 insertions, 32 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index ef1e5355be8..e6483ddc88b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -225,7 +225,7 @@ config CLK_VERSACLOCK config CLK_VERSAL bool "Enable clock driver support for Versal" depends on (ARCH_VERSAL || ARCH_VERSAL_NET) - imply ZYNQMP_FIRMWARE + depends on ZYNQMP_FIRMWARE help This clock driver adds support for clock realted settings for Versal platform. diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index a8239e228cf..4f67c958d0f 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -108,6 +108,8 @@ static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020; #define PLLCTRL_POST_SRC_MASK (0x7 << PLLCTRL_POST_SRC_SHFT) #define PLLCTRL_PRE_SRC_SHFT 20 #define PLLCTRL_PRE_SRC_MASK (0x7 << PLLCTRL_PRE_SRC_SHFT) +#define PLL_TO_LPD_DIV_SHIFT 8 +#define PLL_TO_LPD_DIV_MASK (0x3f << PLL_TO_LPD_DIV_SHIFT) #define NUM_MIO_PINS 77 @@ -334,6 +336,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id) return CRF_APB_TOPSW_LSBUS_CTRL; case iopll_to_fpd: return CRL_APB_IOPLL_TO_FPD_CTRL; + case dpll_to_lpd: + return CRF_APB_DPLL_TO_LPD_CTRL; default: debug("Invalid clk id%d\n", id); } @@ -397,6 +401,22 @@ static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv, if (clk_ctrl & (1 << 16)) freq /= 2; + if (id == dpll) { + u32 dpll_lpd_reg, cross_div; + + dpll_lpd_reg = zynqmp_clk_get_register(dpll_to_lpd); + + ret = zynqmp_mmio_read(dpll_lpd_reg, &cross_div); + if (ret) { + printf("%s mio read fail\n", __func__); + return -EIO; + } + + cross_div = (cross_div & PLL_TO_LPD_DIV_MASK) >> + PLL_TO_LPD_DIV_SHIFT; + freq /= cross_div; + } + return freq; } diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 8789b1ea141..a094e6c3afe 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -29,6 +29,7 @@ config TI_SCI_PROTOCOL config ZYNQMP_FIRMWARE bool "ZynqMP Firmware interface" + depends on ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2 select FIRMWARE help Firmware interface driver is used by different diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 2940181e83e..d18ae523b6b 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -422,6 +422,30 @@ U_BOOT_DRIVER(zynqmp_power) = { }; #endif +smc_call_handler_t __data smc_call_handler; + +static int smc_call_legacy(u32 api_id, u32 arg0, u32 arg1, u32 arg2, + u32 arg3, u32 *ret_payload) +{ + struct pt_regs regs; + + regs.regs[0] = PM_SIP_SVC | api_id; + regs.regs[1] = ((u64)arg1 << 32) | arg0; + regs.regs[2] = ((u64)arg3 << 32) | arg2; + + smc_call(®s); + + if (ret_payload) { + ret_payload[0] = (u32)regs.regs[0]; + ret_payload[1] = upper_32_bits(regs.regs[0]); + ret_payload[2] = (u32)regs.regs[1]; + ret_payload[3] = upper_32_bits(regs.regs[1]); + ret_payload[4] = (u32)regs.regs[2]; + } + + return (ret_payload) ? ret_payload[0] : 0; +} + int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 *ret_payload) { @@ -450,38 +474,20 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, PAYLOAD_ARG_CNT); if (ret) return ret; + + return (ret_payload) ? ret_payload[0] : 0; #else return -EPERM; #endif - } else { - /* - * Added SIP service call Function Identifier - * Make sure to stay in x0 register - */ - struct pt_regs regs; - - regs.regs[0] = PM_SIP_SVC | api_id; - regs.regs[1] = ((u64)arg1 << 32) | arg0; - regs.regs[2] = ((u64)arg3 << 32) | arg2; - - smc_call(®s); - - if (ret_payload) { - ret_payload[0] = (u32)regs.regs[0]; - ret_payload[1] = upper_32_bits(regs.regs[0]); - ret_payload[2] = (u32)regs.regs[1]; - ret_payload[3] = upper_32_bits(regs.regs[1]); - ret_payload[4] = (u32)regs.regs[2]; - } - } - return (ret_payload) ? ret_payload[0] : 0; + + return smc_call_handler(api_id, arg0, arg1, arg2, arg3, ret_payload); } static const struct udevice_id zynqmp_firmware_ids[] = { - { .compatible = "xlnx,zynqmp-firmware" }, - { .compatible = "xlnx,versal-firmware"}, - { .compatible = "xlnx,versal-net-firmware"}, + { .compatible = "xlnx,zynqmp-firmware", .data = (ulong)smc_call_legacy }, + { .compatible = "xlnx,versal-firmware", .data = (ulong)smc_call_legacy}, + { .compatible = "xlnx,versal-net-firmware", .data = (ulong)smc_call_legacy }, { } }; @@ -490,6 +496,10 @@ static int zynqmp_firmware_bind(struct udevice *dev) int ret; struct udevice *child; + smc_call_handler = (smc_call_handler_t)dev_get_driver_data(dev); + if (!smc_call_handler) + return -EINVAL; + if ((IS_ENABLED(CONFIG_XPL_BUILD) && IS_ENABLED(CONFIG_SPL_POWER_DOMAIN) && IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) || diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c index a2f3b160a73..5f4aae47d6d 100644 --- a/drivers/fpga/intel_sdm_mb.c +++ b/drivers/fpga/intel_sdm_mb.c @@ -687,7 +687,8 @@ static int send_bitstream(const void *rbf_data, size_t rbf_size) debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n", wr_ret, rbf_data, buf_size); - if (wr_ret) + if (wr_ret != INTEL_SIP_SMC_STATUS_OK && + wr_ret != INTEL_SIP_SMC_STATUS_BUSY) continue; rbf_size -= buf_size; diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 2375b15539b..3b682918b03 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -1127,6 +1127,28 @@ static int arasan_sdhci_probe(struct udevice *dev) if (arasan_sdhci_is_compatible(dev, SDHCI_COMPATIBLE_VERSAL_NET_EMMC)) priv->internal_phy_reg = true; + ret = reset_get_bulk(dev, &priv->resets); + if (ret == -ENOTSUPP || ret == -ENOENT) { + dev_warn(dev, "Reset not found\n"); + } else if (ret) { + dev_err(dev, "Reset failed\n"); + return ret; + } + + if (!ret) { + ret = reset_assert_bulk(&priv->resets); + if (ret) { + dev_err(dev, "Reset assert failed\n"); + return ret; + } + + ret = reset_deassert_bulk(&priv->resets); + if (ret) { + dev_err(dev, "Reset release failed\n"); + return ret; + } + } + ret = clk_get_by_index(dev, 0, &clk); if (ret < 0) { dev_err(dev, "failed to get clock\n"); diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index fbeb0c6a85c..6dc6fbe5a5b 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -20,7 +20,7 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { - u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data; + u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data, status; u8 opcode, addr_bytes, *rxbuf, dummy_cycles; n_rx = op->data.nbytes; @@ -87,6 +87,16 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, CQSPI_REG_SIZE_ADDRESS_MASK; opcode = CMD_4BYTE_FAST_READ; + + /* Set up command opcode extension. */ + status = readl(priv->regbase + CQSPI_REG_CONFIG); + if (status & CQSPI_REG_CONFIG_DTR_PROTO) { + ret = cadence_qspi_setup_opcode_ext(priv, op, + CQSPI_REG_OP_EXT_STIG_LSB); + if (ret) + return ret; + } + dummy_cycles = 8; writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode, priv->regbase + CQSPI_REG_RD_INSTR); diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 80510f2542b..879e7f8dbfb 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -320,5 +320,7 @@ int cadence_qspi_flash_reset(struct udevice *dev); ofnode cadence_qspi_get_subnode(struct udevice *dev); void cadence_qspi_apb_enable_linear_mode(bool enable); int cadence_device_reset(struct udevice *dev); - +int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, + const struct spi_mem_op *op, + unsigned int shift); #endif /* __CADENCE_QSPI_H__ */ diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index b579699d2eb..6f89d3add5d 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -303,6 +303,10 @@ void cadence_qspi_apb_delay(void *reg_base, tshsl_ns -= sclk_ns + ref_clk_ns; if (tchsh_ns >= sclk_ns + 3 * ref_clk_ns) tchsh_ns -= sclk_ns + 3 * ref_clk_ns; + + if (tshsl_ns < sclk_ns) + tshsl_ns = sclk_ns; + tshsl = DIV_ROUND_UP(tshsl_ns, ref_clk_ns); tchsh = DIV_ROUND_UP(tchsh_ns, ref_clk_ns); tslch = DIV_ROUND_UP(tslch_ns, ref_clk_ns); @@ -380,9 +384,9 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg) return 0; } -static int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, - const struct spi_mem_op *op, - unsigned int shift) +int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, + const struct spi_mem_op *op, + unsigned int shift) { unsigned int reg; u8 ext; @@ -555,6 +559,9 @@ int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv, u8 opcode; if (priv->dtr) + txlen += txlen & 1; + + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; |