diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-05 19:56:50 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-05 19:56:50 -0800 |
| commit | 7eb7f5723df50a7d5564aa609e4c147f669a5cb4 (patch) | |
| tree | 495927c82f799fad6bafa9069773db94c454cbd7 /drivers/firmware/xilinx/zynqmp-ufs.c | |
| parent | 3af870aedbff10bfed220e280b57a405e972229f (diff) | |
| parent | 82f78acd5a9270370ef4aa3f032ede25f3dc91ee (diff) | |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"Usual driver updates (ufs, lpfc, target, qla2xxx) plus assorted
cleanups and fixes including the WQ_PERCPU series.
The biggest core change is the new allocation of pseudo-devices which
allow the sending of internal commands to a given SCSI target"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (147 commits)
scsi: MAINTAINERS: Add the UFS include directory
scsi: scsi_debug: Support injecting unaligned write errors
scsi: qla2xxx: Fix improper freeing of purex item
scsi: ufs: rockchip: Fix compile error without CONFIG_GPIOLIB
scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable notify
scsi: ufs: core: Use scsi_device_busy()
scsi: ufs: core: Fix single doorbell mode support
scsi: pm80xx: Add WQ_PERCPU to alloc_workqueue() users
scsi: target: Add WQ_PERCPU to alloc_workqueue() users
scsi: qedi: Add WQ_PERCPU to alloc_workqueue() users
scsi: target: ibmvscsi: Add WQ_PERCPU to alloc_workqueue() users
scsi: qedf: Add WQ_PERCPU to alloc_workqueue() users
scsi: bnx2fc: Add WQ_PERCPU to alloc_workqueue() users
scsi: be2iscsi: Add WQ_PERCPU to alloc_workqueue() users
scsi: message: fusion: Add WQ_PERCPU to alloc_workqueue() users
scsi: lpfc: WQ_PERCPU added to alloc_workqueue() users
scsi: scsi_transport_fc: WQ_PERCPU added to alloc_workqueue users()
scsi: scsi_dh_alua: WQ_PERCPU added to alloc_workqueue() users
scsi: qla2xxx: WQ_PERCPU added to alloc_workqueue() users
scsi: target: sbp: Replace use of system_unbound_wq with system_dfl_wq
...
Diffstat (limited to 'drivers/firmware/xilinx/zynqmp-ufs.c')
| -rw-r--r-- | drivers/firmware/xilinx/zynqmp-ufs.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/drivers/firmware/xilinx/zynqmp-ufs.c b/drivers/firmware/xilinx/zynqmp-ufs.c new file mode 100644 index 000000000000..85da8a822f3a --- /dev/null +++ b/drivers/firmware/xilinx/zynqmp-ufs.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Firmware Layer for UFS APIs + * + * Copyright (C) 2025 Advanced Micro Devices, Inc. + */ + +#include <linux/firmware/xlnx-zynqmp.h> +#include <linux/module.h> + +/* Register Node IDs */ +#define PM_REGNODE_PMC_IOU_SLCR 0x30000002 /* PMC IOU SLCR */ +#define PM_REGNODE_EFUSE_CACHE 0x30000003 /* EFUSE Cache */ + +/* Register Offsets for PMC IOU SLCR */ +#define SRAM_CSR_OFFSET 0x104C /* SRAM Control and Status */ +#define TXRX_CFGRDY_OFFSET 0x1054 /* M-PHY TX-RX Config ready */ + +/* Masks for SRAM Control and Status Register */ +#define SRAM_CSR_INIT_DONE_MASK BIT(0) /* SRAM initialization done */ +#define SRAM_CSR_EXT_LD_DONE_MASK BIT(1) /* SRAM External load done */ +#define SRAM_CSR_BYPASS_MASK BIT(2) /* Bypass SRAM interface */ + +/* Mask to check M-PHY TX-RX configuration readiness */ +#define TX_RX_CFG_RDY_MASK GENMASK(3, 0) + +/* Register Offsets for EFUSE Cache */ +#define UFS_CAL_1_OFFSET 0xBE8 /* UFS Calibration Value */ + +/** + * zynqmp_pm_is_mphy_tx_rx_config_ready - check M-PHY TX-RX config readiness + * @is_ready: Store output status (true/false) + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready) +{ + u32 regval; + int ret; + + if (!is_ready) + return -EINVAL; + + ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, TXRX_CFGRDY_OFFSET, ®val); + if (ret) + return ret; + + regval &= TX_RX_CFG_RDY_MASK; + if (regval) + *is_ready = true; + else + *is_ready = false; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready); + +/** + * zynqmp_pm_is_sram_init_done - check SRAM initialization + * @is_done: Store output status (true/false) + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_is_sram_init_done(bool *is_done) +{ + u32 regval; + int ret; + + if (!is_done) + return -EINVAL; + + ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, ®val); + if (ret) + return ret; + + regval &= SRAM_CSR_INIT_DONE_MASK; + if (regval) + *is_done = true; + else + *is_done = false; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_is_sram_init_done); + +/** + * zynqmp_pm_set_sram_bypass - Set SRAM bypass Control + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_set_sram_bypass(void) +{ + u32 sram_csr; + int ret; + + ret = zynqmp_pm_sec_read_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, &sram_csr); + if (ret) + return ret; + + sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK; + sram_csr |= SRAM_CSR_BYPASS_MASK; + + return zynqmp_pm_sec_mask_write_reg(PM_REGNODE_PMC_IOU_SLCR, SRAM_CSR_OFFSET, + GENMASK(2, 1), sram_csr); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_set_sram_bypass); + +/** + * zynqmp_pm_get_ufs_calibration_values - Read UFS calibration values + * @val: Store the calibration value + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_get_ufs_calibration_values(u32 *val) +{ + return zynqmp_pm_sec_read_reg(PM_REGNODE_EFUSE_CACHE, UFS_CAL_1_OFFSET, val); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_ufs_calibration_values); |