162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. 362306a36Sopenharmony_ci */ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#ifndef UFS_QCOM_H_ 662306a36Sopenharmony_ci#define UFS_QCOM_H_ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/reset-controller.h> 962306a36Sopenharmony_ci#include <linux/reset.h> 1062306a36Sopenharmony_ci#include <soc/qcom/ice.h> 1162306a36Sopenharmony_ci#include <ufs/ufshcd.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define MAX_UFS_QCOM_HOSTS 1 1462306a36Sopenharmony_ci#define MAX_U32 (~(u32)0) 1562306a36Sopenharmony_ci#define MPHY_TX_FSM_STATE 0x41 1662306a36Sopenharmony_ci#define TX_FSM_HIBERN8 0x1 1762306a36Sopenharmony_ci#define HBRN8_POLL_TOUT_MS 100 1862306a36Sopenharmony_ci#define DEFAULT_CLK_RATE_HZ 1000000 1962306a36Sopenharmony_ci#define BUS_VECTOR_NAME_LEN 32 2062306a36Sopenharmony_ci#define MAX_SUPP_MAC 64 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define UFS_HW_VER_MAJOR_MASK GENMASK(31, 28) 2362306a36Sopenharmony_ci#define UFS_HW_VER_MINOR_MASK GENMASK(27, 16) 2462306a36Sopenharmony_ci#define UFS_HW_VER_STEP_MASK GENMASK(15, 0) 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/* vendor specific pre-defined parameters */ 2762306a36Sopenharmony_ci#define SLOW 1 2862306a36Sopenharmony_ci#define FAST 2 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define UFS_QCOM_LIMIT_HS_RATE PA_HS_MODE_B 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* QCOM UFS host controller vendor specific registers */ 3362306a36Sopenharmony_cienum { 3462306a36Sopenharmony_ci REG_UFS_SYS1CLK_1US = 0xC0, 3562306a36Sopenharmony_ci REG_UFS_TX_SYMBOL_CLK_NS_US = 0xC4, 3662306a36Sopenharmony_ci REG_UFS_LOCAL_PORT_ID_REG = 0xC8, 3762306a36Sopenharmony_ci REG_UFS_PA_ERR_CODE = 0xCC, 3862306a36Sopenharmony_ci /* On older UFS revisions, this register is called "RETRY_TIMER_REG" */ 3962306a36Sopenharmony_ci REG_UFS_PARAM0 = 0xD0, 4062306a36Sopenharmony_ci /* On older UFS revisions, this register is called "REG_UFS_PA_LINK_STARTUP_TIMER" */ 4162306a36Sopenharmony_ci REG_UFS_CFG0 = 0xD8, 4262306a36Sopenharmony_ci REG_UFS_CFG1 = 0xDC, 4362306a36Sopenharmony_ci REG_UFS_CFG2 = 0xE0, 4462306a36Sopenharmony_ci REG_UFS_HW_VERSION = 0xE4, 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci UFS_TEST_BUS = 0xE8, 4762306a36Sopenharmony_ci UFS_TEST_BUS_CTRL_0 = 0xEC, 4862306a36Sopenharmony_ci UFS_TEST_BUS_CTRL_1 = 0xF0, 4962306a36Sopenharmony_ci UFS_TEST_BUS_CTRL_2 = 0xF4, 5062306a36Sopenharmony_ci UFS_UNIPRO_CFG = 0xF8, 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* 5362306a36Sopenharmony_ci * QCOM UFS host controller vendor specific registers 5462306a36Sopenharmony_ci * added in HW Version 3.0.0 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_ci UFS_AH8_CFG = 0xFC, 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci REG_UFS_CFG3 = 0x271C, 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* QCOM UFS host controller vendor specific debug registers */ 6262306a36Sopenharmony_cienum { 6362306a36Sopenharmony_ci UFS_DBG_RD_REG_UAWM = 0x100, 6462306a36Sopenharmony_ci UFS_DBG_RD_REG_UARM = 0x200, 6562306a36Sopenharmony_ci UFS_DBG_RD_REG_TXUC = 0x300, 6662306a36Sopenharmony_ci UFS_DBG_RD_REG_RXUC = 0x400, 6762306a36Sopenharmony_ci UFS_DBG_RD_REG_DFC = 0x500, 6862306a36Sopenharmony_ci UFS_DBG_RD_REG_TRLUT = 0x600, 6962306a36Sopenharmony_ci UFS_DBG_RD_REG_TMRLUT = 0x700, 7062306a36Sopenharmony_ci UFS_UFS_DBG_RD_REG_OCSC = 0x800, 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci UFS_UFS_DBG_RD_DESC_RAM = 0x1500, 7362306a36Sopenharmony_ci UFS_UFS_DBG_RD_PRDT_RAM = 0x1700, 7462306a36Sopenharmony_ci UFS_UFS_DBG_RD_RESP_RAM = 0x1800, 7562306a36Sopenharmony_ci UFS_UFS_DBG_RD_EDTL_RAM = 0x1900, 7662306a36Sopenharmony_ci}; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cienum { 7962306a36Sopenharmony_ci UFS_MEM_CQIS_VS = 0x8, 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#define UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(x) (0x000 + x) 8362306a36Sopenharmony_ci#define UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(x) (0x400 + x) 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/* bit definitions for REG_UFS_CFG0 register */ 8662306a36Sopenharmony_ci#define QUNIPRO_G4_SEL BIT(5) 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci/* bit definitions for REG_UFS_CFG1 register */ 8962306a36Sopenharmony_ci#define QUNIPRO_SEL BIT(0) 9062306a36Sopenharmony_ci#define UFS_PHY_SOFT_RESET BIT(1) 9162306a36Sopenharmony_ci#define UTP_DBG_RAMS_EN BIT(17) 9262306a36Sopenharmony_ci#define TEST_BUS_EN BIT(18) 9362306a36Sopenharmony_ci#define TEST_BUS_SEL GENMASK(22, 19) 9462306a36Sopenharmony_ci#define UFS_REG_TEST_BUS_EN BIT(30) 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#define UFS_PHY_RESET_ENABLE 1 9762306a36Sopenharmony_ci#define UFS_PHY_RESET_DISABLE 0 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* bit definitions for REG_UFS_CFG2 register */ 10062306a36Sopenharmony_ci#define UAWM_HW_CGC_EN BIT(0) 10162306a36Sopenharmony_ci#define UARM_HW_CGC_EN BIT(1) 10262306a36Sopenharmony_ci#define TXUC_HW_CGC_EN BIT(2) 10362306a36Sopenharmony_ci#define RXUC_HW_CGC_EN BIT(3) 10462306a36Sopenharmony_ci#define DFC_HW_CGC_EN BIT(4) 10562306a36Sopenharmony_ci#define TRLUT_HW_CGC_EN BIT(5) 10662306a36Sopenharmony_ci#define TMRLUT_HW_CGC_EN BIT(6) 10762306a36Sopenharmony_ci#define OCSC_HW_CGC_EN BIT(7) 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* bit definitions for REG_UFS_PARAM0 */ 11062306a36Sopenharmony_ci#define MAX_HS_GEAR_MASK GENMASK(6, 4) 11162306a36Sopenharmony_ci#define UFS_QCOM_MAX_GEAR(x) FIELD_GET(MAX_HS_GEAR_MASK, (x)) 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/* bit definition for UFS_UFS_TEST_BUS_CTRL_n */ 11462306a36Sopenharmony_ci#define TEST_BUS_SUB_SEL_MASK GENMASK(4, 0) /* All XXX_SEL fields are 5 bits wide */ 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci#define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\ 11762306a36Sopenharmony_ci TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\ 11862306a36Sopenharmony_ci DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\ 11962306a36Sopenharmony_ci TMRLUT_HW_CGC_EN | OCSC_HW_CGC_EN) 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* bit offset */ 12262306a36Sopenharmony_ci#define OFFSET_CLK_NS_REG 0xa 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci/* bit masks */ 12562306a36Sopenharmony_ci#define MASK_TX_SYMBOL_CLK_1US_REG GENMASK(9, 0) 12662306a36Sopenharmony_ci#define MASK_CLK_NS_REG GENMASK(23, 10) 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/* QUniPro Vendor specific attributes */ 12962306a36Sopenharmony_ci#define PA_VS_CONFIG_REG1 0x9000 13062306a36Sopenharmony_ci#define DME_VS_CORE_CLK_CTRL 0xD002 13162306a36Sopenharmony_ci/* bit and mask definitions for DME_VS_CORE_CLK_CTRL attribute */ 13262306a36Sopenharmony_ci#define DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT BIT(8) 13362306a36Sopenharmony_ci#define DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK 0xFF 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic inline void 13662306a36Sopenharmony_ciufs_qcom_get_controller_revision(struct ufs_hba *hba, 13762306a36Sopenharmony_ci u8 *major, u16 *minor, u16 *step) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci u32 ver = ufshcd_readl(hba, REG_UFS_HW_VERSION); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci *major = FIELD_GET(UFS_HW_VER_MAJOR_MASK, ver); 14262306a36Sopenharmony_ci *minor = FIELD_GET(UFS_HW_VER_MINOR_MASK, ver); 14362306a36Sopenharmony_ci *step = FIELD_GET(UFS_HW_VER_STEP_MASK, ver); 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic inline void ufs_qcom_assert_reset(struct ufs_hba *hba) 14762306a36Sopenharmony_ci{ 14862306a36Sopenharmony_ci ufshcd_rmwl(hba, UFS_PHY_SOFT_RESET, FIELD_PREP(UFS_PHY_SOFT_RESET, UFS_PHY_RESET_ENABLE), 14962306a36Sopenharmony_ci REG_UFS_CFG1); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci /* 15262306a36Sopenharmony_ci * Make sure assertion of ufs phy reset is written to 15362306a36Sopenharmony_ci * register before returning 15462306a36Sopenharmony_ci */ 15562306a36Sopenharmony_ci mb(); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci ufshcd_rmwl(hba, UFS_PHY_SOFT_RESET, FIELD_PREP(UFS_PHY_SOFT_RESET, UFS_PHY_RESET_DISABLE), 16162306a36Sopenharmony_ci REG_UFS_CFG1); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* 16462306a36Sopenharmony_ci * Make sure de-assertion of ufs phy reset is written to 16562306a36Sopenharmony_ci * register before returning 16662306a36Sopenharmony_ci */ 16762306a36Sopenharmony_ci mb(); 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci/* Host controller hardware version: major.minor.step */ 17162306a36Sopenharmony_cistruct ufs_hw_version { 17262306a36Sopenharmony_ci u16 step; 17362306a36Sopenharmony_ci u16 minor; 17462306a36Sopenharmony_ci u8 major; 17562306a36Sopenharmony_ci}; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistruct ufs_qcom_testbus { 17862306a36Sopenharmony_ci u8 select_major; 17962306a36Sopenharmony_ci u8 select_minor; 18062306a36Sopenharmony_ci}; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistruct gpio_desc; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistruct ufs_qcom_host { 18562306a36Sopenharmony_ci /* 18662306a36Sopenharmony_ci * Set this capability if host controller supports the QUniPro mode 18762306a36Sopenharmony_ci * and if driver wants the Host controller to operate in QUniPro mode. 18862306a36Sopenharmony_ci * Note: By default this capability will be kept enabled if host 18962306a36Sopenharmony_ci * controller supports the QUniPro mode. 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_ci #define UFS_QCOM_CAP_QUNIPRO 0x1 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* 19462306a36Sopenharmony_ci * Set this capability if host controller can retain the secure 19562306a36Sopenharmony_ci * configuration even after UFS controller core power collapse. 19662306a36Sopenharmony_ci */ 19762306a36Sopenharmony_ci #define UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE 0x2 19862306a36Sopenharmony_ci u32 caps; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci struct phy *generic_phy; 20162306a36Sopenharmony_ci struct ufs_hba *hba; 20262306a36Sopenharmony_ci struct ufs_pa_layer_attr dev_req_params; 20362306a36Sopenharmony_ci struct clk *rx_l0_sync_clk; 20462306a36Sopenharmony_ci struct clk *tx_l0_sync_clk; 20562306a36Sopenharmony_ci struct clk *rx_l1_sync_clk; 20662306a36Sopenharmony_ci struct clk *tx_l1_sync_clk; 20762306a36Sopenharmony_ci bool is_lane_clks_enabled; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci struct icc_path *icc_ddr; 21062306a36Sopenharmony_ci struct icc_path *icc_cpu; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci#ifdef CONFIG_SCSI_UFS_CRYPTO 21362306a36Sopenharmony_ci struct qcom_ice *ice; 21462306a36Sopenharmony_ci#endif 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci void __iomem *dev_ref_clk_ctrl_mmio; 21762306a36Sopenharmony_ci bool is_dev_ref_clk_enabled; 21862306a36Sopenharmony_ci struct ufs_hw_version hw_ver; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci u32 dev_ref_clk_en_mask; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci struct ufs_qcom_testbus testbus; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci /* Reset control of HCI */ 22562306a36Sopenharmony_ci struct reset_control *core_reset; 22662306a36Sopenharmony_ci struct reset_controller_dev rcdev; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci struct gpio_desc *device_reset; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci u32 hs_gear; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci bool esi_enabled; 23362306a36Sopenharmony_ci}; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic inline u32 23662306a36Sopenharmony_ciufs_qcom_get_debug_reg_offset(struct ufs_qcom_host *host, u32 reg) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci if (host->hw_ver.major <= 0x02) 23962306a36Sopenharmony_ci return UFS_CNTLR_2_x_x_VEN_REGS_OFFSET(reg); 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci return UFS_CNTLR_3_x_x_VEN_REGS_OFFSET(reg); 24262306a36Sopenharmony_ci}; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba) 24562306a36Sopenharmony_ci#define ufs_qcom_is_link_active(hba) ufshcd_is_link_active(hba) 24662306a36Sopenharmony_ci#define ufs_qcom_is_link_hibern8(hba) ufshcd_is_link_hibern8(hba) 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ciint ufs_qcom_testbus_config(struct ufs_qcom_host *host); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci return host->caps & UFS_QCOM_CAP_QUNIPRO; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci#endif /* UFS_QCOM_H_ */ 256