diff options
Diffstat (limited to 'drivers/firmware')
| -rw-r--r-- | drivers/firmware/firmware-zynqmp.c | 104 | ||||
| -rw-r--r-- | drivers/firmware/scmi/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/firmware/scmi/scmi_agent-uclass.c | 10 |
3 files changed, 104 insertions, 13 deletions
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 6052a31b5b4..fae66ccb3d8 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -19,10 +19,10 @@ #include <asm/ptrace.h> #include <asm/system.h> #include <linux/bitfield.h> +#include <linux/delay.h> #if defined(CONFIG_ZYNQMP_IPI) #include <mailbox.h> -#include <asm/arch/sys_proto.h> #define PMUFW_PAYLOAD_ARG_CNT 8 @@ -176,28 +176,106 @@ unsigned int zynqmp_firmware_version(void) }; #if defined(CONFIG_ARCH_VERSAL2) -int zynqmp_pm_ufs_get_txrx_cfgrdy(u32 *value) +/* + * Poll the M-PHY TX/RX config-ready status until it settles or @timeout_us + * elapses. Legacy EEMI firmware only offers the per-read status primitive, so + * the poll loop lives here rather than in the UFS driver; the timeout budget is + * owned by the caller. + */ +int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us) { - *value = readl(PMXC_SLCR_BASE_ADDRESS + PMXC_TX_RX_CFG_RDY); - return 0; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + while (timeout_us--) { + ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR, + IOCTL_READ_REG, TXRX_CFGRDY_OFFSET, 0, 0, + 0, ret_payload); + if (ret) + return ret; + + if (!(ret_payload[1] & TX_RX_CFG_RDY_MASK)) + return 0; + + udelay(1); + } + + return -ETIMEDOUT; } -int zynqmp_pm_ufs_sram_csr_read(u32 *value) +int zynqmp_pm_wait_sram_init_done(u32 timeout_us) { - *value = readl(PMXC_SLCR_BASE_ADDRESS + PMXC_SRAM_CSR); - return 0; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + while (timeout_us--) { + ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR, + IOCTL_READ_REG, SRAM_CSR_OFFSET, 0, 0, + 0, ret_payload); + if (ret) + return ret; + + if (ret_payload[1] & SRAM_CSR_INIT_DONE_MASK) + return 0; + + udelay(1); + } + + return -ETIMEDOUT; } -int zynqmp_pm_ufs_sram_csr_write(u32 *value) +int zynqmp_pm_set_sram_bypass(void) { - writel(*value, PMXC_SLCR_BASE_ADDRESS + PMXC_SRAM_CSR); - return 0; + u32 ret_payload[PAYLOAD_ARG_CNT]; + u32 sram_csr; + int ret; + + ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_MASK_WRITE_REG); + if (ret) { + printf("%s: IOCTL_MASK_WRITE_REG is not supported : %d\n" + , __func__, ret); + return 0; + } + + ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR, + IOCTL_READ_REG, SRAM_CSR_OFFSET, 0, 0, + 0, ret_payload); + if (ret) + return ret; + + sram_csr = ret_payload[1]; + sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK; + sram_csr |= SRAM_CSR_BYPASS_MASK; + + return xilinx_pm_request(PM_IOCTL, PM_REGNODE_PMC_IOU_SLCR, + IOCTL_MASK_WRITE_REG, SRAM_CSR_OFFSET, + GENMASK(2, 1), sram_csr, 0, NULL); } -int zynqmp_pm_ufs_cal_reg(u32 *value) +int zynqmp_pm_get_ufs_calibration_values(u32 *value) { - *value = readl(PMXC_EFUSE_CACHE_BASE_ADDRESS + PMXC_UFS_CAL_1_OFFSET); - return 0; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_READ_REG); + if (ret) { + printf("%s: IOCTL_READ_REG is not supported : %d\n" + , __func__, ret); + return 0; + } + + ret = xilinx_pm_request(PM_IOCTL, PM_REGNODE_EFUSE_CACHE, + IOCTL_READ_REG, UFS_CAL_1_OFFSET, 0, 0, + 0, ret_payload); + if (ret) + return ret; + + *value = ret_payload[1]; + + return ret; } #endif /* CONFIG_ARCH_VERSAL2 */ diff --git a/drivers/firmware/scmi/Kconfig b/drivers/firmware/scmi/Kconfig index cd912ebe409..64bc9aef5af 100644 --- a/drivers/firmware/scmi/Kconfig +++ b/drivers/firmware/scmi/Kconfig @@ -46,6 +46,9 @@ config SCMI_AGENT_OPTEE config SCMI_ID_VENDOR_80 bool +config SCMI_ID_VENDOR_81 + bool + config SCMI_ID_VENDOR_82 bool diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index cd458a7f458..9159e59385b 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -116,6 +116,11 @@ struct udevice *scmi_get_protocol(struct udevice *dev, proto = priv->vendor_dev_80; break; #endif +#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_81) + case SCMI_PROTOCOL_ID_VENDOR_81: + proto = priv->vendor_dev_81; + break; +#endif #if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_82) case SCMI_PROTOCOL_ID_VENDOR_82: proto = priv->vendor_dev_82; @@ -189,6 +194,11 @@ static int scmi_add_protocol(struct udevice *dev, priv->vendor_dev_80 = proto; break; #endif +#if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_81) + case SCMI_PROTOCOL_ID_VENDOR_81: + priv->vendor_dev_81 = proto; + break; +#endif #if IS_ENABLED(CONFIG_SCMI_ID_VENDOR_82) case SCMI_PROTOCOL_ID_VENDOR_82: priv->vendor_dev_82 = proto; |
