119 lines
2.9 KiB
C
119 lines
2.9 KiB
C
// 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);
|