18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. 38c2ecf20Sopenharmony_ci */ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#ifndef UFS_QCOM_H_ 68c2ecf20Sopenharmony_ci#define UFS_QCOM_H_ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/reset-controller.h> 98c2ecf20Sopenharmony_ci#include <linux/reset.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define MAX_UFS_QCOM_HOSTS 1 128c2ecf20Sopenharmony_ci#define MAX_U32 (~(u32)0) 138c2ecf20Sopenharmony_ci#define MPHY_TX_FSM_STATE 0x41 148c2ecf20Sopenharmony_ci#define TX_FSM_HIBERN8 0x1 158c2ecf20Sopenharmony_ci#define HBRN8_POLL_TOUT_MS 100 168c2ecf20Sopenharmony_ci#define DEFAULT_CLK_RATE_HZ 1000000 178c2ecf20Sopenharmony_ci#define BUS_VECTOR_NAME_LEN 32 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define UFS_HW_VER_MAJOR_SHFT (28) 208c2ecf20Sopenharmony_ci#define UFS_HW_VER_MAJOR_MASK (0x000F << UFS_HW_VER_MAJOR_SHFT) 218c2ecf20Sopenharmony_ci#define UFS_HW_VER_MINOR_SHFT (16) 228c2ecf20Sopenharmony_ci#define UFS_HW_VER_MINOR_MASK (0x0FFF << UFS_HW_VER_MINOR_SHFT) 238c2ecf20Sopenharmony_ci#define UFS_HW_VER_STEP_SHFT (0) 248c2ecf20Sopenharmony_ci#define UFS_HW_VER_STEP_MASK (0xFFFF << UFS_HW_VER_STEP_SHFT) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* vendor specific pre-defined parameters */ 278c2ecf20Sopenharmony_ci#define SLOW 1 288c2ecf20Sopenharmony_ci#define FAST 2 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_NUM_LANES_RX 2 318c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_NUM_LANES_TX 2 328c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_HSGEAR_RX UFS_HS_G3 338c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_HSGEAR_TX UFS_HS_G3 348c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_PWMGEAR_RX UFS_PWM_G4 358c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_PWMGEAR_TX UFS_PWM_G4 368c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_RX_PWR_PWM SLOW_MODE 378c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_TX_PWR_PWM SLOW_MODE 388c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_RX_PWR_HS FAST_MODE 398c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_TX_PWR_HS FAST_MODE 408c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_HS_RATE PA_HS_MODE_B 418c2ecf20Sopenharmony_ci#define UFS_QCOM_LIMIT_DESIRED_MODE FAST 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* QCOM UFS host controller vendor specific registers */ 448c2ecf20Sopenharmony_cienum { 458c2ecf20Sopenharmony_ci REG_UFS_SYS1CLK_1US = 0xC0, 468c2ecf20Sopenharmony_ci REG_UFS_TX_SYMBOL_CLK_NS_US = 0xC4, 478c2ecf20Sopenharmony_ci REG_UFS_LOCAL_PORT_ID_REG = 0xC8, 488c2ecf20Sopenharmony_ci REG_UFS_PA_ERR_CODE = 0xCC, 498c2ecf20Sopenharmony_ci REG_UFS_RETRY_TIMER_REG = 0xD0, 508c2ecf20Sopenharmony_ci REG_UFS_PA_LINK_STARTUP_TIMER = 0xD8, 518c2ecf20Sopenharmony_ci REG_UFS_CFG1 = 0xDC, 528c2ecf20Sopenharmony_ci REG_UFS_CFG2 = 0xE0, 538c2ecf20Sopenharmony_ci REG_UFS_HW_VERSION = 0xE4, 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci UFS_TEST_BUS = 0xE8, 568c2ecf20Sopenharmony_ci UFS_TEST_BUS_CTRL_0 = 0xEC, 578c2ecf20Sopenharmony_ci UFS_TEST_BUS_CTRL_1 = 0xF0, 588c2ecf20Sopenharmony_ci UFS_TEST_BUS_CTRL_2 = 0xF4, 598c2ecf20Sopenharmony_ci UFS_UNIPRO_CFG = 0xF8, 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* 628c2ecf20Sopenharmony_ci * QCOM UFS host controller vendor specific registers 638c2ecf20Sopenharmony_ci * added in HW Version 3.0.0 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci UFS_AH8_CFG = 0xFC, 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* QCOM UFS host controller vendor specific debug registers */ 698c2ecf20Sopenharmony_cienum { 708c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_UAWM = 0x100, 718c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_UARM = 0x200, 728c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_TXUC = 0x300, 738c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_RXUC = 0x400, 748c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_DFC = 0x500, 758c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_TRLUT = 0x600, 768c2ecf20Sopenharmony_ci UFS_DBG_RD_REG_TMRLUT = 0x700, 778c2ecf20Sopenharmony_ci UFS_UFS_DBG_RD_REG_OCSC = 0x800, 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci UFS_UFS_DBG_RD_DESC_RAM = 0x1500, 808c2ecf20Sopenharmony_ci UFS_UFS_DBG_RD_PRDT_RAM = 0x1700, 818c2ecf20Sopenharmony_ci UFS_UFS_DBG_RD_RESP_RAM = 0x1800, 828c2ecf20Sopenharmony_ci UFS_UFS_DBG_RD_EDTL_RAM = 0x1900, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci#define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x) (0x000 + x) 868c2ecf20Sopenharmony_ci#define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x) (0x400 + x) 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* bit definitions for REG_UFS_CFG1 register */ 898c2ecf20Sopenharmony_ci#define QUNIPRO_SEL 0x1 908c2ecf20Sopenharmony_ci#define UTP_DBG_RAMS_EN 0x20000 918c2ecf20Sopenharmony_ci#define TEST_BUS_EN BIT(18) 928c2ecf20Sopenharmony_ci#define TEST_BUS_SEL GENMASK(22, 19) 938c2ecf20Sopenharmony_ci#define UFS_REG_TEST_BUS_EN BIT(30) 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* bit definitions for REG_UFS_CFG2 register */ 968c2ecf20Sopenharmony_ci#define UAWM_HW_CGC_EN (1 << 0) 978c2ecf20Sopenharmony_ci#define UARM_HW_CGC_EN (1 << 1) 988c2ecf20Sopenharmony_ci#define TXUC_HW_CGC_EN (1 << 2) 998c2ecf20Sopenharmony_ci#define RXUC_HW_CGC_EN (1 << 3) 1008c2ecf20Sopenharmony_ci#define DFC_HW_CGC_EN (1 << 4) 1018c2ecf20Sopenharmony_ci#define TRLUT_HW_CGC_EN (1 << 5) 1028c2ecf20Sopenharmony_ci#define TMRLUT_HW_CGC_EN (1 << 6) 1038c2ecf20Sopenharmony_ci#define OCSC_HW_CGC_EN (1 << 7) 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* bit definition for UFS_UFS_TEST_BUS_CTRL_n */ 1068c2ecf20Sopenharmony_ci#define TEST_BUS_SUB_SEL_MASK 0x1F /* All XXX_SEL fields are 5 bits wide */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci#define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\ 1098c2ecf20Sopenharmony_ci TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\ 1108c2ecf20Sopenharmony_ci DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\ 1118c2ecf20Sopenharmony_ci TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN) 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci/* bit offset */ 1148c2ecf20Sopenharmony_cienum { 1158c2ecf20Sopenharmony_ci OFFSET_UFS_PHY_SOFT_RESET = 1, 1168c2ecf20Sopenharmony_ci OFFSET_CLK_NS_REG = 10, 1178c2ecf20Sopenharmony_ci}; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* bit masks */ 1208c2ecf20Sopenharmony_cienum { 1218c2ecf20Sopenharmony_ci MASK_UFS_PHY_SOFT_RESET = 0x2, 1228c2ecf20Sopenharmony_ci MASK_TX_SYMBOL_CLK_1US_REG = 0x3FF, 1238c2ecf20Sopenharmony_ci MASK_CLK_NS_REG = 0xFFFC00, 1248c2ecf20Sopenharmony_ci}; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci/* QCOM UFS debug print bit mask */ 1278c2ecf20Sopenharmony_ci#define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0) 1288c2ecf20Sopenharmony_ci#define UFS_QCOM_DBG_PRINT_ICE_REGS_EN BIT(1) 1298c2ecf20Sopenharmony_ci#define UFS_QCOM_DBG_PRINT_TEST_BUS_EN BIT(2) 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci#define UFS_QCOM_DBG_PRINT_ALL \ 1328c2ecf20Sopenharmony_ci (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_ICE_REGS_EN | \ 1338c2ecf20Sopenharmony_ci UFS_QCOM_DBG_PRINT_TEST_BUS_EN) 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/* QUniPro Vendor specific attributes */ 1368c2ecf20Sopenharmony_ci#define PA_VS_CONFIG_REG1 0x9000 1378c2ecf20Sopenharmony_ci#define DME_VS_CORE_CLK_CTRL 0xD002 1388c2ecf20Sopenharmony_ci/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */ 1398c2ecf20Sopenharmony_ci#define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8) 1408c2ecf20Sopenharmony_ci#define DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK 0xFF 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic inline void 1438c2ecf20Sopenharmony_ciufs_qcom_get_controller_revision(struct ufs_hba *hba, 1448c2ecf20Sopenharmony_ci u8 *major, u16 *minor, u16 *step) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci u32 ver = ufshcd_readl(hba, REG_UFS_HW_VERSION); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci *major = (ver & UFS_HW_VER_MAJOR_MASK) >> UFS_HW_VER_MAJOR_SHFT; 1498c2ecf20Sopenharmony_ci *minor = (ver & UFS_HW_VER_MINOR_MASK) >> UFS_HW_VER_MINOR_SHFT; 1508c2ecf20Sopenharmony_ci *step = (ver & UFS_HW_VER_STEP_MASK) >> UFS_HW_VER_STEP_SHFT; 1518c2ecf20Sopenharmony_ci}; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistatic inline void ufs_qcom_assert_reset(struct ufs_hba *hba) 1548c2ecf20Sopenharmony_ci{ 1558c2ecf20Sopenharmony_ci ufshcd_rmwl(hba, MASK_UFS_PHY_SOFT_RESET, 1568c2ecf20Sopenharmony_ci 1 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci /* 1598c2ecf20Sopenharmony_ci * Make sure assertion of ufs phy reset is written to 1608c2ecf20Sopenharmony_ci * register before returning 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci mb(); 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci ufshcd_rmwl(hba, MASK_UFS_PHY_SOFT_RESET, 1688c2ecf20Sopenharmony_ci 0 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* 1718c2ecf20Sopenharmony_ci * Make sure de-assertion of ufs phy reset is written to 1728c2ecf20Sopenharmony_ci * register before returning 1738c2ecf20Sopenharmony_ci */ 1748c2ecf20Sopenharmony_ci mb(); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci/* Host controller hardware version: major.minor.step */ 1788c2ecf20Sopenharmony_cistruct ufs_hw_version { 1798c2ecf20Sopenharmony_ci u16 step; 1808c2ecf20Sopenharmony_ci u16 minor; 1818c2ecf20Sopenharmony_ci u8 major; 1828c2ecf20Sopenharmony_ci}; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistruct ufs_qcom_testbus { 1858c2ecf20Sopenharmony_ci u8 select_major; 1868c2ecf20Sopenharmony_ci u8 select_minor; 1878c2ecf20Sopenharmony_ci}; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistruct gpio_desc; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistruct ufs_qcom_host { 1928c2ecf20Sopenharmony_ci /* 1938c2ecf20Sopenharmony_ci * Set this capability if host controller supports the QUniPro mode 1948c2ecf20Sopenharmony_ci * and if driver wants the Host controller to operate in QUniPro mode. 1958c2ecf20Sopenharmony_ci * Note: By default this capability will be kept enabled if host 1968c2ecf20Sopenharmony_ci * controller supports the QUniPro mode. 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ci #define UFS_QCOM_CAP_QUNIPRO 0x1 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* 2018c2ecf20Sopenharmony_ci * Set this capability if host controller can retain the secure 2028c2ecf20Sopenharmony_ci * configuration even after UFS controller core power collapse. 2038c2ecf20Sopenharmony_ci */ 2048c2ecf20Sopenharmony_ci #define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE 0x2 2058c2ecf20Sopenharmony_ci u32 caps; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci struct phy *generic_phy; 2088c2ecf20Sopenharmony_ci struct ufs_hba *hba; 2098c2ecf20Sopenharmony_ci struct ufs_pa_layer_attr dev_req_params; 2108c2ecf20Sopenharmony_ci struct clk *rx_l0_sync_clk; 2118c2ecf20Sopenharmony_ci struct clk *tx_l0_sync_clk; 2128c2ecf20Sopenharmony_ci struct clk *rx_l1_sync_clk; 2138c2ecf20Sopenharmony_ci struct clk *tx_l1_sync_clk; 2148c2ecf20Sopenharmony_ci bool is_lane_clks_enabled; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci void __iomem *dev_ref_clk_ctrl_mmio; 2178c2ecf20Sopenharmony_ci bool is_dev_ref_clk_enabled; 2188c2ecf20Sopenharmony_ci struct ufs_hw_version hw_ver; 2198c2ecf20Sopenharmony_ci#ifdef CONFIG_SCSI_UFS_CRYPTO 2208c2ecf20Sopenharmony_ci void __iomem *ice_mmio; 2218c2ecf20Sopenharmony_ci#endif 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci u32 dev_ref_clk_en_mask; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci /* Bitmask for enabling debug prints */ 2268c2ecf20Sopenharmony_ci u32 dbg_print_en; 2278c2ecf20Sopenharmony_ci struct ufs_qcom_testbus testbus; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci /* Reset control of HCI */ 2308c2ecf20Sopenharmony_ci struct reset_control *core_reset; 2318c2ecf20Sopenharmony_ci struct reset_controller_dev rcdev; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci struct gpio_desc *device_reset; 2348c2ecf20Sopenharmony_ci}; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic inline u32 2378c2ecf20Sopenharmony_ciufs_qcom_get_debug_reg_offset(struct ufs_qcom_host *host, u32 reg) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci if (host->hw_ver.major <= 0x02) 2408c2ecf20Sopenharmony_ci return UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(reg); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci return UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(reg); 2438c2ecf20Sopenharmony_ci}; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba) 2468c2ecf20Sopenharmony_ci#define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba) 2478c2ecf20Sopenharmony_ci#define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba) 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ciint ufs_qcom_testbus_config(struct ufs_qcom_host *host); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci if (host->caps & UFS_QCOM_CAP_QUNIPRO) 2548c2ecf20Sopenharmony_ci return true; 2558c2ecf20Sopenharmony_ci else 2568c2ecf20Sopenharmony_ci return false; 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci/* ufs-qcom-ice.c */ 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci#ifdef CONFIG_SCSI_UFS_CRYPTO 2628c2ecf20Sopenharmony_ciint ufs_qcom_ice_init(struct ufs_qcom_host *host); 2638c2ecf20Sopenharmony_ciint ufs_qcom_ice_enable(struct ufs_qcom_host *host); 2648c2ecf20Sopenharmony_ciint ufs_qcom_ice_resume(struct ufs_qcom_host *host); 2658c2ecf20Sopenharmony_ciint ufs_qcom_ice_program_key(struct ufs_hba *hba, 2668c2ecf20Sopenharmony_ci const union ufs_crypto_cfg_entry *cfg, int slot); 2678c2ecf20Sopenharmony_ci#else 2688c2ecf20Sopenharmony_cistatic inline int ufs_qcom_ice_init(struct ufs_qcom_host *host) 2698c2ecf20Sopenharmony_ci{ 2708c2ecf20Sopenharmony_ci return 0; 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_cistatic inline int ufs_qcom_ice_enable(struct ufs_qcom_host *host) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci return 0; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_cistatic inline int ufs_qcom_ice_resume(struct ufs_qcom_host *host) 2778c2ecf20Sopenharmony_ci{ 2788c2ecf20Sopenharmony_ci return 0; 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_ci#define ufs_qcom_ice_program_key NULL 2818c2ecf20Sopenharmony_ci#endif /* !CONFIG_SCSI_UFS_CRYPTO */ 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci#endif /* UFS_QCOM_H_ */ 284