1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Firmware Layer for UFS APIs 4 * 5 * Copyright (C) 2025 Advanced Micro Devices, Inc. 6 */ 7 8 #include <linux/firmware/xlnx-zynqmp.h> 9 #include <linux/module.h> 10 11 /* Register Node IDs */ 12 #define PM_REGNODE_PMC_IOU_SLCR 0x30000002 /* PMC IOU SLCR */ 13 #define PM_REGNODE_EFUSE_CACHE 0x30000003 /* EFUSE Cache */ 14 15 /* Register Offsets for PMC IOU SLCR */ 16 #define SRAM_CSR_OFFSET 0x104C /* SRAM Control and Status */ 17 #define TXRX_CFGRDY_OFFSET 0x1054 /* M-PHY TX-RX Config ready */ 18 19 /* Masks for SRAM Control and Status Register */ 20 #define SRAM_CSR_INIT_DONE_MASK BIT(0) /* SRAM initialization done */ 21 #define SRAM_CSR_EXT_LD_DONE_MASK BIT(1) /* SRAM External load done */ 22 #define SRAM_CSR_BYPASS_MASK BIT(2) /* Bypass SRAM interface */ 23 24 /* Mask to check M-PHY TX-RX configuration readiness */ 25 #define TX_RX_CFG_RDY_MASK GENMASK(3, 0) 26 27 /* Register Offsets for EFUSE Cache */ 28 #define UFS_CAL_1_OFFSET 0xBE8 /* UFS Calibration Value */ 29 30 /** 31 * zynqmp_pm_is_mphy_tx_rx_config_ready - check M-PHY TX-RX config readiness 32 * @is_ready: Store output status (true/false) 33 * 34 * Return: Returns 0 on success or error value on failure. 35 */ 36 int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready) 37 { 38 u32 regval; 39 int ret; 40 41 if (!is_ready) 42 return -EINVAL; 43 44 ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, TXRX_CFGRDY_OFFSET, ®val); 45 if (ret) 46 return ret; 47 48 regval &= TX_RX_CFG_RDY_MASK; 49 if (regval) 50 *is_ready = true; 51 else 52 *is_ready = false; 53 54 return ret; 55 } 56 EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready); 57 58 /** 59 * zynqmp_pm_is_sram_init_done - check SRAM initialization 60 * @is_done: Store output status (true/false) 61 * 62 * Return: Returns 0 on success or error value on failure. 63 */ 64 int zynqmp_pm_is_sram_init_done(bool *is_done) 65 { 66 u32 regval; 67 int ret; 68 69 if (!is_done) 70 return -EINVAL; 71 72 ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, ®val); 73 if (ret) 74 return ret; 75 76 regval &= SRAM_CSR_INIT_DONE_MASK; 77 if (regval) 78 *is_done = true; 79 else 80 *is_done = false; 81 82 return ret; 83 } 84 EXPORT_SYMBOL_GPL(zynqmp_pm_is_sram_init_done); 85 86 /** 87 * zynqmp_pm_set_sram_bypass - Set SRAM bypass Control 88 * 89 * Return: Returns 0 on success or error value on failure. 90 */ 91 int zynqmp_pm_set_sram_bypass(void) 92 { 93 u32 sram_csr; 94 int ret; 95 96 ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, &sram_csr); 97 if (ret) 98 return ret; 99 100 sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK; 101 sram_csr |= SRAM_CSR_BYPASS_MASK; 102 103 return zynqmp_pm_sec_mask_write_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, 104 GENMASK(2, 1), sram_csr); 105 } 106 EXPORT_SYMBOL_GPL(zynqmp_pm_set_sram_bypass); 107 108 /** 109 * zynqmp_pm_get_ufs_calibration_values - Read UFS calibration values 110 * @val: Store the calibration value 111 * 112 * Return: Returns 0 on success or error value on failure. 113 */ 114 int zynqmp_pm_get_ufs_calibration_values(u32 *val) 115 { 116 return zynqmp_pm_sec_read_reg(PM_REGNODE_EFUSE_CACHE, UFS_CAL_1_OFFSET, val); 117 } 118 EXPORT_SYMBOL_GPL(zynqmp_pm_get_ufs_calibration_values); 119