mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 09:54:35 +00:00
ufs: ufs-amd-versal2: Add support for AMD UFS controller
Add UFS AMD platform support on top of the UFS DWC and UFS platform driver. UFS AMD platform requires some platform specific configurations like M-PHY/RMMI/UniPro and vendor specific registers programming before doing the LINKSTARTUP. Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Link: https://lore.kernel.org/r/20240920041651.18173-3-venkatesh.abbarapu@amd.com Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
This commit is contained in:
parent
4b0ea24b42
commit
b5ac5f0307
5 changed files with 557 additions and 0 deletions
|
@ -41,4 +41,12 @@ config UFS_RENESAS
|
|||
UFS host on Renesas needs some vendor specific configuration before
|
||||
accessing the hardware.
|
||||
|
||||
config UFS_AMD_VERSAL2
|
||||
bool "AMD Versal Gen 2 UFS controller platform driver"
|
||||
depends on UFS && ZYNQMP_FIRMWARE
|
||||
help
|
||||
This selects the AMD specific additions to UFSHCD platform driver.
|
||||
UFS host on AMD needs some vendor specific configuration before accessing
|
||||
the hardware.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -8,3 +8,4 @@ obj-$(CONFIG_CADENCE_UFS) += cdns-platform.o
|
|||
obj-$(CONFIG_TI_J721E_UFS) += ti-j721e-ufs.o
|
||||
obj-$(CONFIG_UFS_PCI) += ufs-pci.o
|
||||
obj-$(CONFIG_UFS_RENESAS) += ufs-renesas.o
|
||||
obj-$(CONFIG_UFS_AMD_VERSAL2) += ufs-amd-versal2.o ufshcd-dwc.o
|
||||
|
|
501
drivers/ufs/ufs-amd-versal2.c
Normal file
501
drivers/ufs/ufs-amd-versal2.c
Normal file
|
@ -0,0 +1,501 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <ufs.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <zynqmp_firmware.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/time.h>
|
||||
#include <reset.h>
|
||||
|
||||
#include "ufs.h"
|
||||
#include "ufshcd-dwc.h"
|
||||
#include "ufshci-dwc.h"
|
||||
|
||||
#define VERSAL2_UFS_DEVICE_ID 4
|
||||
|
||||
#define SRAM_CSR_INIT_DONE_MASK BIT(0)
|
||||
#define SRAM_CSR_EXT_LD_DONE_MASK BIT(1)
|
||||
#define SRAM_CSR_BYPASS_MASK BIT(2)
|
||||
|
||||
#define MPHY_FAST_RX_AFE_CAL BIT(2)
|
||||
#define MPHY_FW_CALIB_CFG_VAL BIT(8)
|
||||
|
||||
#define TX_RX_CFG_RDY_MASK GENMASK(3, 0)
|
||||
|
||||
#define TIMEOUT_MICROSEC 1000000L
|
||||
|
||||
#define IOCTL_UFS_TXRX_CFGRDY_GET 40
|
||||
#define IOCTL_UFS_SRAM_CSR_SEL 41
|
||||
|
||||
#define PM_UFS_SRAM_CSR_WRITE 0
|
||||
#define PM_UFS_SRAM_CSR_READ 1
|
||||
|
||||
struct ufs_versal2_priv {
|
||||
struct ufs_hba *hba;
|
||||
struct reset_ctl *rstc;
|
||||
struct reset_ctl *rstphy;
|
||||
u32 phy_mode;
|
||||
u32 host_clk;
|
||||
u32 pd_dev_id;
|
||||
u8 attcompval0;
|
||||
u8 attcompval1;
|
||||
u8 ctlecompval0;
|
||||
u8 ctlecompval1;
|
||||
};
|
||||
|
||||
static int ufs_versal2_phy_reg_write(struct ufs_hba *hba, u32 addr, u32 val)
|
||||
{
|
||||
static struct ufshcd_dme_attr_val phy_write_attrs[] = {
|
||||
{ UIC_ARG_MIB(CBCREGADDRLSB), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCREGADDRMSB), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCREGWRLSB), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCREGWRMSB), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCREGRDWRSEL), 1, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
|
||||
};
|
||||
|
||||
phy_write_attrs[0].mib_val = (u8)addr;
|
||||
phy_write_attrs[1].mib_val = (u8)(addr >> 8);
|
||||
phy_write_attrs[2].mib_val = (u8)val;
|
||||
phy_write_attrs[3].mib_val = (u8)(val >> 8);
|
||||
|
||||
return ufshcd_dwc_dme_set_attrs(hba, phy_write_attrs, ARRAY_SIZE(phy_write_attrs));
|
||||
}
|
||||
|
||||
static int ufs_versal2_phy_reg_read(struct ufs_hba *hba, u32 addr, u32 *val)
|
||||
{
|
||||
u32 mib_val;
|
||||
int ret;
|
||||
static struct ufshcd_dme_attr_val phy_read_attrs[] = {
|
||||
{ UIC_ARG_MIB(CBCREGADDRLSB), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCREGADDRMSB), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCREGRDWRSEL), 0, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
|
||||
};
|
||||
|
||||
phy_read_attrs[0].mib_val = (u8)addr;
|
||||
phy_read_attrs[1].mib_val = (u8)(addr >> 8);
|
||||
|
||||
ret = ufshcd_dwc_dme_set_attrs(hba, phy_read_attrs, ARRAY_SIZE(phy_read_attrs));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ufshcd_dme_get(hba, UIC_ARG_MIB(CBCREGRDLSB), &mib_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = mib_val;
|
||||
ret = ufshcd_dme_get(hba, UIC_ARG_MIB(CBCREGRDMSB), &mib_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val |= (mib_val << 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int versal2_pm_ufs_get_txrx_cfgrdy(u32 node_id, u32 *value)
|
||||
{
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
ret = xilinx_pm_request(PM_IOCTL, node_id, IOCTL_UFS_TXRX_CFGRDY_GET,
|
||||
0, 0, ret_payload);
|
||||
*value = ret_payload[1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int versal2_pm_ufs_sram_csr_sel(u32 node_id, u32 type, u32 *value)
|
||||
{
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
int ret;
|
||||
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
if (type == PM_UFS_SRAM_CSR_READ) {
|
||||
ret = xilinx_pm_request(PM_IOCTL, node_id, IOCTL_UFS_SRAM_CSR_SEL,
|
||||
type, 0, ret_payload);
|
||||
*value = ret_payload[1];
|
||||
} else {
|
||||
ret = xilinx_pm_request(PM_IOCTL, node_id, IOCTL_UFS_SRAM_CSR_SEL,
|
||||
type, *value, 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_versal2_enable_phy(struct ufs_hba *hba)
|
||||
{
|
||||
u32 offset, reg;
|
||||
int ret;
|
||||
|
||||
ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYDISABLE), 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ufshcd_dme_set(hba, UIC_ARG_MIB(VS_MPHYCFGUPDT), 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check Tx/Rx FSM states */
|
||||
for (offset = 0; offset < 2; offset++) {
|
||||
u32 time_left, mibsel;
|
||||
|
||||
time_left = TIMEOUT_MICROSEC;
|
||||
mibsel = UIC_ARG_MIB_SEL(MTX_FSM_STATE, UIC_ARG_MPHY_TX_GEN_SEL_INDEX(offset));
|
||||
do {
|
||||
ret = ufshcd_dme_get(hba, mibsel, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (reg == TX_STATE_HIBERN8 || reg == TX_STATE_SLEEP ||
|
||||
reg == TX_STATE_LSBURST)
|
||||
break;
|
||||
|
||||
time_left--;
|
||||
mdelay(5);
|
||||
} while (time_left);
|
||||
|
||||
if (!time_left) {
|
||||
dev_err(hba->dev, "Invalid Tx FSM state.\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
time_left = TIMEOUT_MICROSEC;
|
||||
mibsel = UIC_ARG_MIB_SEL(MRX_FSM_STATE, UIC_ARG_MPHY_RX_GEN_SEL_INDEX(offset));
|
||||
do {
|
||||
ret = ufshcd_dme_get(hba, mibsel, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (reg == RX_STATE_HIBERN8 || reg == RX_STATE_SLEEP ||
|
||||
reg == RX_STATE_LSBURST)
|
||||
break;
|
||||
|
||||
time_left--;
|
||||
mdelay(5);
|
||||
} while (time_left);
|
||||
|
||||
if (!time_left) {
|
||||
dev_err(hba->dev, "Invalid Rx FSM state.\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ufs_versal2_setup_phy(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
/* Bypass RX-AFE offset calibrations (ATT/CTLE) */
|
||||
ret = ufs_versal2_phy_reg_read(hba, FAST_FLAGS(0), ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg |= MPHY_FAST_RX_AFE_CAL;
|
||||
ret = ufs_versal2_phy_reg_write(hba, FAST_FLAGS(0), reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ufs_versal2_phy_reg_read(hba, FAST_FLAGS(1), ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg |= MPHY_FAST_RX_AFE_CAL;
|
||||
ret = ufs_versal2_phy_reg_write(hba, FAST_FLAGS(1), reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Program ATT and CTLE compensation values */
|
||||
if (priv->attcompval0) {
|
||||
ret = ufs_versal2_phy_reg_write(hba, RX_AFE_ATT_IDAC(0), priv->attcompval0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->attcompval1) {
|
||||
ret = ufs_versal2_phy_reg_write(hba, RX_AFE_ATT_IDAC(1), priv->attcompval1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->ctlecompval0) {
|
||||
ret = ufs_versal2_phy_reg_write(hba, RX_AFE_CTLE_IDAC(0), priv->ctlecompval0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->ctlecompval1) {
|
||||
ret = ufs_versal2_phy_reg_write(hba, RX_AFE_CTLE_IDAC(1), priv->ctlecompval1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ufs_versal2_phy_reg_read(hba, FW_CALIB_CCFG(0), ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg |= MPHY_FW_CALIB_CFG_VAL;
|
||||
ret = ufs_versal2_phy_reg_write(hba, FW_CALIB_CCFG(0), reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ufs_versal2_phy_reg_read(hba, FW_CALIB_CCFG(1), ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg |= MPHY_FW_CALIB_CFG_VAL;
|
||||
return ufs_versal2_phy_reg_write(hba, FW_CALIB_CCFG(1), reg);
|
||||
}
|
||||
|
||||
static int ufs_versal2_phy_init(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
|
||||
u32 reg, time_left;
|
||||
int ret;
|
||||
static const struct ufshcd_dme_attr_val rmmi_attrs[] = {
|
||||
{ UIC_ARG_MIB(CBREFCLKCTRL2), CBREFREFCLK_GATE_OVR_EN, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBCRCTRL), 1, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(CBC10DIRECTCONF2), 1, DME_LOCAL },
|
||||
{ UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL }
|
||||
};
|
||||
|
||||
/* Wait for Tx/Rx config_rdy */
|
||||
time_left = TIMEOUT_MICROSEC;
|
||||
do {
|
||||
time_left--;
|
||||
ret = versal2_pm_ufs_get_txrx_cfgrdy(priv->pd_dev_id, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg &= TX_RX_CFG_RDY_MASK;
|
||||
if (!reg)
|
||||
break;
|
||||
|
||||
mdelay(5);
|
||||
} while (time_left);
|
||||
|
||||
if (!time_left) {
|
||||
dev_err(hba->dev, "Tx/Rx configuration signal busy.\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
ret = ufshcd_dwc_dme_set_attrs(hba, rmmi_attrs, ARRAY_SIZE(rmmi_attrs));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* DeAssert PHY reset */
|
||||
ret = reset_deassert(priv->rstphy);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "ufsphy reset deassert failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait for SRAM init done */
|
||||
time_left = TIMEOUT_MICROSEC;
|
||||
do {
|
||||
time_left--;
|
||||
ret = versal2_pm_ufs_sram_csr_sel(priv->pd_dev_id,
|
||||
PM_UFS_SRAM_CSR_READ, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg &= SRAM_CSR_INIT_DONE_MASK;
|
||||
if (reg)
|
||||
break;
|
||||
|
||||
mdelay(5);
|
||||
} while (time_left);
|
||||
|
||||
if (!time_left) {
|
||||
dev_err(hba->dev, "SRAM initialization failed.\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
ret = ufs_versal2_setup_phy(hba);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ufs_versal2_enable_phy(hba);
|
||||
}
|
||||
|
||||
static int ufs_versal2_init(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
|
||||
struct clk clk;
|
||||
unsigned long core_clk_rate = 0;
|
||||
int ret = 0;
|
||||
|
||||
priv->phy_mode = UFSHCD_DWC_PHY_MODE_ROM;
|
||||
priv->pd_dev_id = VERSAL2_UFS_DEVICE_ID;
|
||||
|
||||
ret = clk_get_by_name(hba->dev, "core_clk", &clk);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "failed to get core_clk clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
core_clk_rate = clk_get_rate(&clk);
|
||||
if (IS_ERR_VALUE(core_clk_rate)) {
|
||||
dev_err(hba->dev, "%s: unable to find core_clk rate\n",
|
||||
__func__);
|
||||
return core_clk_rate;
|
||||
}
|
||||
priv->host_clk = core_clk_rate;
|
||||
|
||||
priv->rstc = devm_reset_control_get(hba->dev, "ufshc-rst");
|
||||
if (IS_ERR(priv->rstc)) {
|
||||
dev_err(hba->dev, "failed to get reset ctl: ufshc-rst\n");
|
||||
return PTR_ERR(priv->rstc);
|
||||
}
|
||||
priv->rstphy = devm_reset_control_get(hba->dev, "ufsphy-rst");
|
||||
if (IS_ERR(priv->rstphy)) {
|
||||
dev_err(hba->dev, "failed to get reset ctl: ufsphy-rst\n");
|
||||
return PTR_ERR(priv->rstphy);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_versal2_hce_enable_notify(struct ufs_hba *hba,
|
||||
enum ufs_notify_change_status status)
|
||||
{
|
||||
struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
|
||||
u32 sram_csr;
|
||||
int ret;
|
||||
|
||||
switch (status) {
|
||||
case PRE_CHANGE:
|
||||
/* Assert RST_UFS Reset for UFS block in PMX_IOU */
|
||||
ret = reset_assert(priv->rstc);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "ufshc reset assert failed, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Assert PHY reset */
|
||||
ret = reset_assert(priv->rstphy);
|
||||
if (ret) {
|
||||
dev_err(hba->dev, "ufsphy reset assert failed, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = versal2_pm_ufs_sram_csr_sel(priv->pd_dev_id,
|
||||
PM_UFS_SRAM_CSR_READ, &sram_csr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!priv->phy_mode) {
|
||||
sram_csr &= ~SRAM_CSR_EXT_LD_DONE_MASK;
|
||||
sram_csr |= SRAM_CSR_BYPASS_MASK;
|
||||
} else {
|
||||
dev_err(hba->dev, "Invalid phy-mode %d.\n", priv->phy_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = versal2_pm_ufs_sram_csr_sel(priv->pd_dev_id,
|
||||
PM_UFS_SRAM_CSR_WRITE, &sram_csr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* De Assert RST_UFS Reset for UFS block in PMX_IOU */
|
||||
ret = reset_deassert(priv->rstc);
|
||||
if (ret)
|
||||
dev_err(hba->dev, "ufshc reset deassert failed, err = %d\n", ret);
|
||||
|
||||
break;
|
||||
case POST_CHANGE:
|
||||
ret = ufs_versal2_phy_init(hba);
|
||||
if (ret)
|
||||
dev_err(hba->dev, "Phy init failed (%d)\n", ret);
|
||||
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_versal2_link_startup_notify(struct ufs_hba *hba,
|
||||
enum ufs_notify_change_status status)
|
||||
{
|
||||
struct ufs_versal2_priv *priv = dev_get_priv(hba->dev);
|
||||
int ret = 0;
|
||||
|
||||
switch (status) {
|
||||
case PRE_CHANGE:
|
||||
if (priv->host_clk) {
|
||||
u32 core_clk_div = priv->host_clk / TIMEOUT_MICROSEC;
|
||||
|
||||
ufshcd_writel(hba, core_clk_div, DWC_UFS_REG_HCLKDIV);
|
||||
}
|
||||
break;
|
||||
case POST_CHANGE:
|
||||
ret = ufshcd_dwc_link_startup_notify(hba, status);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ufs_hba_ops ufs_versal2_hba_ops = {
|
||||
.init = ufs_versal2_init,
|
||||
.link_startup_notify = ufs_versal2_link_startup_notify,
|
||||
.hce_enable_notify = ufs_versal2_hce_enable_notify,
|
||||
};
|
||||
|
||||
static int ufs_versal2_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Perform generic probe */
|
||||
ret = ufshcd_probe(dev, &ufs_versal2_hba_ops);
|
||||
if (ret)
|
||||
dev_err(dev, "ufshcd_probe() failed %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ufs_versal2_bind(struct udevice *dev)
|
||||
{
|
||||
struct udevice *scsi_dev;
|
||||
|
||||
return ufs_scsi_bind(dev, &scsi_dev);
|
||||
}
|
||||
|
||||
static const struct udevice_id ufs_versal2_ids[] = {
|
||||
{
|
||||
.compatible = "amd,versal2-ufs",
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(ufs_versal2_pltfm) = {
|
||||
.name = "ufs-versal2-pltfm",
|
||||
.id = UCLASS_UFS,
|
||||
.of_match = ufs_versal2_ids,
|
||||
.probe = ufs_versal2_probe,
|
||||
.bind = ufs_versal2_bind,
|
||||
};
|
|
@ -10,6 +10,52 @@
|
|||
#ifndef _UFSHCD_DWC_H
|
||||
#define _UFSHCD_DWC_H
|
||||
|
||||
/* PHY modes */
|
||||
#define UFSHCD_DWC_PHY_MODE_ROM 0
|
||||
|
||||
/* RMMI Attributes */
|
||||
#define CBREFCLKCTRL2 0x8132
|
||||
#define CBCRCTRL 0x811F
|
||||
#define CBC10DIRECTCONF2 0x810E
|
||||
#define CBCREGADDRLSB 0x8116
|
||||
#define CBCREGADDRMSB 0x8117
|
||||
#define CBCREGWRLSB 0x8118
|
||||
#define CBCREGWRMSB 0x8119
|
||||
#define CBCREGRDLSB 0x811A
|
||||
#define CBCREGRDMSB 0x811B
|
||||
#define CBCREGRDWRSEL 0x811C
|
||||
|
||||
#define CBREFREFCLK_GATE_OVR_EN BIT(7)
|
||||
|
||||
/* M-PHY Attributes */
|
||||
#define MTX_FSM_STATE 0x41
|
||||
#define MRX_FSM_STATE 0xC1
|
||||
|
||||
/* M-PHY registers */
|
||||
#define FAST_FLAGS(n) (0x401C + ((n) * 0x100))
|
||||
#define RX_AFE_ATT_IDAC(n) (0x4000 + ((n) * 0x100))
|
||||
#define RX_AFE_CTLE_IDAC(n) (0x4001 + ((n) * 0x100))
|
||||
#define FW_CALIB_CCFG(n) (0x404D + ((n) * 0x100))
|
||||
|
||||
/* Tx/Rx FSM state */
|
||||
enum rx_fsm_state {
|
||||
RX_STATE_DISABLED = 0,
|
||||
RX_STATE_HIBERN8 = 1,
|
||||
RX_STATE_SLEEP = 2,
|
||||
RX_STATE_STALL = 3,
|
||||
RX_STATE_LSBURST = 4,
|
||||
RX_STATE_HSBURST = 5,
|
||||
};
|
||||
|
||||
enum tx_fsm_state {
|
||||
TX_STATE_DISABLED = 0,
|
||||
TX_STATE_HIBERN8 = 1,
|
||||
TX_STATE_SLEEP = 2,
|
||||
TX_STATE_STALL = 3,
|
||||
TX_STATE_LSBURST = 4,
|
||||
TX_STATE_HSBURST = 5,
|
||||
};
|
||||
|
||||
struct ufshcd_dme_attr_val {
|
||||
u32 attr_sel;
|
||||
u32 mib_val;
|
||||
|
|
|
@ -148,6 +148,7 @@
|
|||
#define VS_MPHYCFGUPDT 0xD085
|
||||
#define VS_DEBUGOMC 0xD09E
|
||||
#define VS_POWERSTATE 0xD083
|
||||
#define VS_MPHYDISABLE 0xD0C1
|
||||
|
||||
#define PA_GRANULARITY_MIN_VAL 1
|
||||
#define PA_GRANULARITY_MAX_VAL 6
|
||||
|
|
Loading…
Add table
Reference in a new issue