From b9c20e5d144347ca28e17df080b7ee9bf0dd9377 Mon Sep 17 00:00:00 2001 From: Amit Nagal Date: Sun, 28 Jul 2024 20:32:58 -1200 Subject: [PATCH] fix(versal2): add ufs specific features support Following IOCTL IDs are required for UFS specific functionalities. IOCTL ID - 40(IOCTL_UFS_TXRX_CFGRDY_GET) This gives the Tx_Rx_config_rdy_signal_mon(0xF1061054) register value which contains the Tx and Rx lanes configuration ready signal information. IOCTL ID - 41(IOCTL_UFS_SRAM_CSR_SEL) Select - 0(IOCTL_UFS_SRAM_CSR_SET) This will allow to set sram control and status register (0xF106104C) with the value provided by driver. Select - 1(IOCTL_UFS_SRAM_CSR_GET) This should return the sram control and status register (0xF106104C) value to the driver. UFS Host reset assert/de-assert(using SCMI) support is added. register address : 0xF1260340 UFS PHY reset assert/de-assert(using SCMI) support is added. register address : 0xF1061050 Change-Id: I5368cc7251350946bd5ddb3a4c817b75e1d4a43e Signed-off-by: Amit Nagal --- plat/amd/versal2/include/def.h | 4 ++++ plat/amd/versal2/include/versal2-scmi.h | 1 + plat/amd/versal2/plat_psci.c | 31 +++++++++++++++++++++---- plat/amd/versal2/scmi.c | 24 +++++++++++++++++++ plat/xilinx/common/include/pm_defs.h | 2 ++ 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/plat/amd/versal2/include/def.h b/plat/amd/versal2/include/def.h index a8cbaafb8..67244a44d 100644 --- a/plat/amd/versal2/include/def.h +++ b/plat/amd/versal2/include/def.h @@ -125,6 +125,10 @@ #define APU_CLUSTER_STEP U(0x100000) #define SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL U(0xF1060504) +#define PMXC_IOU_SLCR_SRAM_CSR U(0xF106104C) +#define PMXC_IOU_SLCR_PHY_RESET U(0xF1061050) +#define PMXC_IOU_SLCR_TX_RX_CONFIG_RDY U(0xF1061054) +#define PMXC_CRP_RST_UFS U(0xF1260340) /******************************************************************************* * IRQ constants diff --git a/plat/amd/versal2/include/versal2-scmi.h b/plat/amd/versal2/include/versal2-scmi.h index 4d581e498..68b181a5f 100644 --- a/plat/amd/versal2/include/versal2-scmi.h +++ b/plat/amd/versal2/include/versal2-scmi.h @@ -136,5 +136,6 @@ #define RESET_I3C6_0 32 #define RESET_I3C7_0 33 #define RESET_I3C8_0 34 +#define RESET_UFSPHY_0 35 #endif /* _VERSAL2_SCMI_H */ diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c index 4faa434ce..6f0cbcbaf 100644 --- a/plat/amd/versal2/plat_psci.c +++ b/plat/amd/versal2/plat_psci.c @@ -161,12 +161,29 @@ int sip_svc_setup_init(void) static int32_t no_pm_ioctl(uint32_t device_id, uint32_t ioctl_id, uint32_t arg1, uint32_t arg2) { + int32_t ret = 0; VERBOSE("%s: ioctl_id: %x, arg1: %x\n", __func__, ioctl_id, arg1); - if (ioctl_id == IOCTL_OSPI_MUX_SELECT) { + + switch (ioctl_id) { + case IOCTL_OSPI_MUX_SELECT: mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1); - return 0; + break; + case IOCTL_UFS_TXRX_CFGRDY_GET: + ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_TX_RX_CONFIG_RDY); + break; + case IOCTL_UFS_SRAM_CSR_SEL: + if (arg1 == 1) { + ret = (int32_t) mmio_read_32(PMXC_IOU_SLCR_SRAM_CSR); + } else if (arg1 == 0) { + mmio_write_32(PMXC_IOU_SLCR_SRAM_CSR, arg2); + } + break; + default: + ret = PM_RET_ERROR_NOFEATURE; + break; } - return PM_RET_ERROR_NOFEATURE; + + return ret; } static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, @@ -187,7 +204,13 @@ static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64 case PM_IOCTL: { ret = no_pm_ioctl(arg[0], arg[1], arg[2], arg[3]); - SMC_RET1(handle, (uint64_t)ret); + /* Firmware driver expects return code in upper 32 bits and + * status in lower 32 bits. + * status is always SUCCESS(0) for mmio low level register + * r/w calls and return value is the value returned from + * no_pm_ioctl + */ + SMC_RET1(handle, ((uint64_t)ret << 32)); } case PM_GET_CHIPID: { diff --git a/plat/amd/versal2/scmi.c b/plat/amd/versal2/scmi.c index c3c517a9c..03a64adfb 100644 --- a/plat/amd/versal2/scmi.c +++ b/plat/amd/versal2/scmi.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -179,6 +180,7 @@ static struct scmi_reset scmi0_reset[] = { RESET_CELL(RESET_I3C6_0, RESET_I3C6_0, "i3c6"), RESET_CELL(RESET_I3C7_0, RESET_I3C7_0, "i3c7"), RESET_CELL(RESET_I3C8_0, RESET_I3C8_0, "i3c8"), + RESET_CELL(RESET_UFSPHY_0, RESET_UFSPHY_0, "ufsphy0"), }; struct scmi_resources { @@ -433,9 +435,31 @@ int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, if (assert_not_deassert) { NOTICE("SCMI reset %lu/%s set\n", reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id)); + + switch (scmi_id) { + case RESET_UFS0_0: + mmio_write_32(PMXC_CRP_RST_UFS, 1); + break; + case RESET_UFSPHY_0: + mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 1); + break; + default: + break; + } } else { NOTICE("SCMI reset %lu/%s release\n", reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id)); + + switch (scmi_id) { + case RESET_UFS0_0: + mmio_write_32(PMXC_CRP_RST_UFS, 0); + break; + case RESET_UFSPHY_0: + mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 0); + break; + default: + break; + } } return SCMI_SUCCESS; diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h index 055fa3d1e..c6e825db9 100644 --- a/plat/xilinx/common/include/pm_defs.h +++ b/plat/xilinx/common/include/pm_defs.h @@ -95,6 +95,8 @@ enum { IOCTL_GET_LAST_RESET_REASON = 23, /* AI engine NPI ISR clear */ IOCTL_AIE_ISR_CLEAR = 24, + IOCTL_UFS_TXRX_CFGRDY_GET = 40, + IOCTL_UFS_SRAM_CSR_SEL = 41, }; /**