diff options
author | Dolev Raviv <draviv@codeaurora.org> | 2014-10-30 10:37:04 +0200 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 10:57:55 -0700 |
commit | 2ea3c6c0fa2444b1aee0b524069c97b04cfcb5c8 (patch) | |
tree | fae14e6d4ad138d95e50ced14721b06b90c77386 | |
parent | 3c0960d0f11f70d22d155e30ebdfdd7805a1d43d (diff) |
scsi: ufs-qcom: implement ufs dbg_register_dump cb
Errors such as UIC errors, illegal OCS values, and others may require
information kept in non standard UFS registers but controller debug
registers.
Implementing dbg_register_dump cb gives access to such register while
debugging those issues.
Change-Id: I259c3d691b95f72ea62ed162492f9081d472de80
Signed-off-by: Dolev Raviv <draviv@codeaurora.org>
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
-rw-r--r-- | drivers/scsi/ufs/ufs-qcom.c | 55 | ||||
-rw-r--r-- | include/linux/scsi/ufs/ufs-qcom.h | 14 |
2 files changed, 68 insertions, 1 deletions
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 482b8bdf3639..4cf845341006 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -41,6 +41,14 @@ static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host, static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote); static int ufs_qcom_update_sec_cfg(struct ufs_hba *hba, bool restore_sec_cfg); +static void ufs_qcom_dump_regs(struct ufs_hba *hba, int offset, int len, + char *prefix) +{ + print_hex_dump(KERN_ERR, prefix, + len > 4 ? DUMP_PREFIX_OFFSET : DUMP_PREFIX_NONE, + 16, 4, hba->mmio_base + offset, len * 4, false); +} + static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes) { int err = 0; @@ -1265,11 +1273,55 @@ out: return ret; } +static void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba) +{ + u32 reg; + + ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_REG_OCSC, 44, + "UFS_UFS_DBG_RD_REG_OCSC "); + + reg = ufshcd_readl(hba, REG_UFS_CFG1); + reg |= UFS_BIT(17); + ufshcd_writel(hba, reg, REG_UFS_CFG1); + + ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_EDTL_RAM, 32, + "UFS_UFS_DBG_RD_EDTL_RAM "); + ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_DESC_RAM, 128, + "UFS_UFS_DBG_RD_DESC_RAM "); + ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_PRDT_RAM, 64, + "UFS_UFS_DBG_RD_PRDT_RAM "); + + ufshcd_writel(hba, (reg & ~UFS_BIT(17)), REG_UFS_CFG1); + + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_UAWM, 4, + "UFS_DBG_RD_REG_UAWM "); + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_UARM, 4, + "UFS_DBG_RD_REG_UARM "); + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TXUC, 48, + "UFS_DBG_RD_REG_TXUC "); + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_RXUC, 27, + "UFS_DBG_RD_REG_RXUC "); + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_DFC, 19, + "UFS_DBG_RD_REG_DFC "); + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TRLUT, 34, + "UFS_DBG_RD_REG_TRLUT "); + ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TMRLUT, 9, + "UFS_DBG_RD_REG_TMRLUT "); +} + +static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba) +{ + ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 5, + "REG_UFS_SYS1CLK_1US "); + + ufs_qcom_print_hw_debug_reg_all(hba); +} + /** * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations * * The variant operations configure the necessary controller and PHY - * handshake during initializaiton. + * handshake during initialization. */ const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { .name = "qcom", @@ -1288,6 +1340,7 @@ const struct ufs_hba_variant_ops ufs_hba_qcom_vops = { .crypto_engine_eh = ufs_qcom_crypto_engine_eh, .crypto_engine_get_err = ufs_qcom_crypto_engine_get_err, .crypto_engine_reset_err = ufs_qcom_crypto_engine_reset_err, + .dbg_register_dump = ufs_qcom_dump_dbg_regs, }; /** diff --git a/include/linux/scsi/ufs/ufs-qcom.h b/include/linux/scsi/ufs/ufs-qcom.h index d48ca998cc2c..9f4471f43eb2 100644 --- a/include/linux/scsi/ufs/ufs-qcom.h +++ b/include/linux/scsi/ufs/ufs-qcom.h @@ -58,6 +58,20 @@ enum { REG_UFS_CFG1 = 0xDC, REG_UFS_CFG2 = 0xE0, REG_UFS_HW_VERSION = 0xE4, + + UFS_DBG_RD_REG_UAWM = 0x100, + UFS_DBG_RD_REG_UARM = 0x200, + UFS_DBG_RD_REG_TXUC = 0x300, + UFS_DBG_RD_REG_RXUC = 0x400, + UFS_DBG_RD_REG_DFC = 0x500, + UFS_DBG_RD_REG_TRLUT = 0x600, + UFS_DBG_RD_REG_TMRLUT = 0x700, + UFS_UFS_DBG_RD_REG_OCSC = 0x800, + + UFS_UFS_DBG_RD_DESC_RAM = 0x1500, + UFS_UFS_DBG_RD_PRDT_RAM = 0x1700, + UFS_UFS_DBG_RD_RESP_RAM = 0x1800, + UFS_UFS_DBG_RD_EDTL_RAM = 0x1900, }; /* bit definitions for REG_UFS_CFG2 register */ |