summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/firmware-zynqmp.c104
-rw-r--r--drivers/firmware/scmi/Kconfig3
-rw-r--r--drivers/firmware/scmi/scmi_agent-uclass.c10
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;