162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * UFS Host Controller driver for Exynos specific extensions 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2014-2015 Samsung Electronics Co., Ltd. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef _UFS_EXYNOS_H_ 1062306a36Sopenharmony_ci#define _UFS_EXYNOS_H_ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci/* 1362306a36Sopenharmony_ci * UNIPRO registers 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci#define UNIPRO_DBG_FORCE_DME_CTRL_STATE 0x150 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * MIBs for PA debug registers 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci#define PA_DBG_CLK_PERIOD 0x9514 2162306a36Sopenharmony_ci#define PA_DBG_TXPHY_CFGUPDT 0x9518 2262306a36Sopenharmony_ci#define PA_DBG_RXPHY_CFGUPDT 0x9519 2362306a36Sopenharmony_ci#define PA_DBG_MODE 0x9529 2462306a36Sopenharmony_ci#define PA_DBG_SKIP_RESET_PHY 0x9539 2562306a36Sopenharmony_ci#define PA_DBG_AUTOMODE_THLD 0x9536 2662306a36Sopenharmony_ci#define PA_DBG_OV_TM 0x9540 2762306a36Sopenharmony_ci#define PA_DBG_SKIP_LINE_RESET 0x9541 2862306a36Sopenharmony_ci#define PA_DBG_LINE_RESET_REQ 0x9543 2962306a36Sopenharmony_ci#define PA_DBG_OPTION_SUITE 0x9564 3062306a36Sopenharmony_ci#define PA_DBG_OPTION_SUITE_DYN 0x9565 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * MIBs for Transport Layer debug registers 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci#define T_DBG_SKIP_INIT_HIBERN8_EXIT 0xc001 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * Exynos MPHY attributes 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_ci#define TX_LINERESET_N_VAL 0x0277 4162306a36Sopenharmony_ci#define TX_LINERESET_N(v) (((v) >> 10) & 0xFF) 4262306a36Sopenharmony_ci#define TX_LINERESET_P_VAL 0x027D 4362306a36Sopenharmony_ci#define TX_LINERESET_P(v) (((v) >> 12) & 0xFF) 4462306a36Sopenharmony_ci#define TX_OV_SLEEP_CNT_TIMER 0x028E 4562306a36Sopenharmony_ci#define TX_OV_H8_ENTER_EN (1 << 7) 4662306a36Sopenharmony_ci#define TX_OV_SLEEP_CNT(v) (((v) >> 5) & 0x7F) 4762306a36Sopenharmony_ci#define TX_HIGH_Z_CNT_11_08 0x028C 4862306a36Sopenharmony_ci#define TX_HIGH_Z_CNT_H(v) (((v) >> 8) & 0xF) 4962306a36Sopenharmony_ci#define TX_HIGH_Z_CNT_07_00 0x028D 5062306a36Sopenharmony_ci#define TX_HIGH_Z_CNT_L(v) ((v) & 0xFF) 5162306a36Sopenharmony_ci#define TX_BASE_NVAL_07_00 0x0293 5262306a36Sopenharmony_ci#define TX_BASE_NVAL_L(v) ((v) & 0xFF) 5362306a36Sopenharmony_ci#define TX_BASE_NVAL_15_08 0x0294 5462306a36Sopenharmony_ci#define TX_BASE_NVAL_H(v) (((v) >> 8) & 0xFF) 5562306a36Sopenharmony_ci#define TX_GRAN_NVAL_07_00 0x0295 5662306a36Sopenharmony_ci#define TX_GRAN_NVAL_L(v) ((v) & 0xFF) 5762306a36Sopenharmony_ci#define TX_GRAN_NVAL_10_08 0x0296 5862306a36Sopenharmony_ci#define TX_GRAN_NVAL_H(v) (((v) >> 8) & 0x3) 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define VND_TX_CLK_PRD 0xAA 6162306a36Sopenharmony_ci#define VND_TX_CLK_PRD_EN 0xA9 6262306a36Sopenharmony_ci#define VND_TX_LINERESET_PVALUE0 0xAD 6362306a36Sopenharmony_ci#define VND_TX_LINERESET_PVALUE1 0xAC 6462306a36Sopenharmony_ci#define VND_TX_LINERESET_PVALUE2 0xAB 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define TX_LINE_RESET_TIME 3200 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#define VND_RX_CLK_PRD 0x12 6962306a36Sopenharmony_ci#define VND_RX_CLK_PRD_EN 0x11 7062306a36Sopenharmony_ci#define VND_RX_LINERESET_VALUE0 0x1D 7162306a36Sopenharmony_ci#define VND_RX_LINERESET_VALUE1 0x1C 7262306a36Sopenharmony_ci#define VND_RX_LINERESET_VALUE2 0x1B 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci#define RX_LINE_RESET_TIME 1000 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci#define RX_FILLER_ENABLE 0x0316 7762306a36Sopenharmony_ci#define RX_FILLER_EN (1 << 1) 7862306a36Sopenharmony_ci#define RX_LINERESET_VAL 0x0317 7962306a36Sopenharmony_ci#define RX_LINERESET(v) (((v) >> 12) & 0xFF) 8062306a36Sopenharmony_ci#define RX_LCC_IGNORE 0x0318 8162306a36Sopenharmony_ci#define RX_SYNC_MASK_LENGTH 0x0321 8262306a36Sopenharmony_ci#define RX_HIBERN8_WAIT_VAL_BIT_20_16 0x0331 8362306a36Sopenharmony_ci#define RX_HIBERN8_WAIT_VAL_BIT_15_08 0x0332 8462306a36Sopenharmony_ci#define RX_HIBERN8_WAIT_VAL_BIT_07_00 0x0333 8562306a36Sopenharmony_ci#define RX_OV_SLEEP_CNT_TIMER 0x0340 8662306a36Sopenharmony_ci#define RX_OV_SLEEP_CNT(v) (((v) >> 6) & 0x1F) 8762306a36Sopenharmony_ci#define RX_OV_STALL_CNT_TIMER 0x0341 8862306a36Sopenharmony_ci#define RX_OV_STALL_CNT(v) (((v) >> 4) & 0xFF) 8962306a36Sopenharmony_ci#define RX_BASE_NVAL_07_00 0x0355 9062306a36Sopenharmony_ci#define RX_BASE_NVAL_L(v) ((v) & 0xFF) 9162306a36Sopenharmony_ci#define RX_BASE_NVAL_15_08 0x0354 9262306a36Sopenharmony_ci#define RX_BASE_NVAL_H(v) (((v) >> 8) & 0xFF) 9362306a36Sopenharmony_ci#define RX_GRAN_NVAL_07_00 0x0353 9462306a36Sopenharmony_ci#define RX_GRAN_NVAL_L(v) ((v) & 0xFF) 9562306a36Sopenharmony_ci#define RX_GRAN_NVAL_10_08 0x0352 9662306a36Sopenharmony_ci#define RX_GRAN_NVAL_H(v) (((v) >> 8) & 0x3) 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#define CMN_PWM_CLK_CTRL 0x0402 9962306a36Sopenharmony_ci#define PWM_CLK_CTRL_MASK 0x3 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#define IATOVAL_NSEC 20000 /* unit: ns */ 10262306a36Sopenharmony_ci#define UNIPRO_PCLK_PERIOD(ufs) (NSEC_PER_SEC / ufs->pclk_rate) 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistruct exynos_ufs; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* vendor specific pre-defined parameters */ 10762306a36Sopenharmony_ci#define SLOW 1 10862306a36Sopenharmony_ci#define FAST 2 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#define RX_ADV_FINE_GRAN_SUP_EN 0x1 11162306a36Sopenharmony_ci#define RX_ADV_FINE_GRAN_STEP_VAL 0x3 11262306a36Sopenharmony_ci#define RX_ADV_MIN_ACTV_TIME_CAP 0x9 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#define PA_GRANULARITY_VAL 0x6 11562306a36Sopenharmony_ci#define PA_TACTIVATE_VAL 0x3 11662306a36Sopenharmony_ci#define PA_HIBERN8TIME_VAL 0x20 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci#define PCLK_AVAIL_MIN 70000000 11962306a36Sopenharmony_ci#define PCLK_AVAIL_MAX 167000000 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistruct exynos_ufs_uic_attr { 12262306a36Sopenharmony_ci /* TX Attributes */ 12362306a36Sopenharmony_ci unsigned int tx_trailingclks; 12462306a36Sopenharmony_ci unsigned int tx_dif_p_nsec; 12562306a36Sopenharmony_ci unsigned int tx_dif_n_nsec; 12662306a36Sopenharmony_ci unsigned int tx_high_z_cnt_nsec; 12762306a36Sopenharmony_ci unsigned int tx_base_unit_nsec; 12862306a36Sopenharmony_ci unsigned int tx_gran_unit_nsec; 12962306a36Sopenharmony_ci unsigned int tx_sleep_cnt; 13062306a36Sopenharmony_ci unsigned int tx_min_activatetime; 13162306a36Sopenharmony_ci /* RX Attributes */ 13262306a36Sopenharmony_ci unsigned int rx_filler_enable; 13362306a36Sopenharmony_ci unsigned int rx_dif_p_nsec; 13462306a36Sopenharmony_ci unsigned int rx_hibern8_wait_nsec; 13562306a36Sopenharmony_ci unsigned int rx_base_unit_nsec; 13662306a36Sopenharmony_ci unsigned int rx_gran_unit_nsec; 13762306a36Sopenharmony_ci unsigned int rx_sleep_cnt; 13862306a36Sopenharmony_ci unsigned int rx_stall_cnt; 13962306a36Sopenharmony_ci unsigned int rx_hs_g1_sync_len_cap; 14062306a36Sopenharmony_ci unsigned int rx_hs_g2_sync_len_cap; 14162306a36Sopenharmony_ci unsigned int rx_hs_g3_sync_len_cap; 14262306a36Sopenharmony_ci unsigned int rx_hs_g1_prep_sync_len_cap; 14362306a36Sopenharmony_ci unsigned int rx_hs_g2_prep_sync_len_cap; 14462306a36Sopenharmony_ci unsigned int rx_hs_g3_prep_sync_len_cap; 14562306a36Sopenharmony_ci /* Common Attributes */ 14662306a36Sopenharmony_ci unsigned int cmn_pwm_clk_ctrl; 14762306a36Sopenharmony_ci /* Internal Attributes */ 14862306a36Sopenharmony_ci unsigned int pa_dbg_option_suite; 14962306a36Sopenharmony_ci /* Changeable Attributes */ 15062306a36Sopenharmony_ci unsigned int rx_adv_fine_gran_sup_en; 15162306a36Sopenharmony_ci unsigned int rx_adv_fine_gran_step; 15262306a36Sopenharmony_ci unsigned int rx_min_actv_time_cap; 15362306a36Sopenharmony_ci unsigned int rx_hibern8_time_cap; 15462306a36Sopenharmony_ci unsigned int rx_adv_min_actv_time_cap; 15562306a36Sopenharmony_ci unsigned int rx_adv_hibern8_time_cap; 15662306a36Sopenharmony_ci unsigned int pa_granularity; 15762306a36Sopenharmony_ci unsigned int pa_tactivate; 15862306a36Sopenharmony_ci unsigned int pa_hibern8time; 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistruct exynos_ufs_drv_data { 16262306a36Sopenharmony_ci const struct ufs_hba_variant_ops *vops; 16362306a36Sopenharmony_ci struct exynos_ufs_uic_attr *uic_attr; 16462306a36Sopenharmony_ci unsigned int quirks; 16562306a36Sopenharmony_ci unsigned int opts; 16662306a36Sopenharmony_ci /* SoC's specific operations */ 16762306a36Sopenharmony_ci int (*drv_init)(struct device *dev, struct exynos_ufs *ufs); 16862306a36Sopenharmony_ci int (*pre_link)(struct exynos_ufs *ufs); 16962306a36Sopenharmony_ci int (*post_link)(struct exynos_ufs *ufs); 17062306a36Sopenharmony_ci int (*pre_pwr_change)(struct exynos_ufs *ufs, 17162306a36Sopenharmony_ci struct ufs_pa_layer_attr *pwr); 17262306a36Sopenharmony_ci int (*post_pwr_change)(struct exynos_ufs *ufs, 17362306a36Sopenharmony_ci struct ufs_pa_layer_attr *pwr); 17462306a36Sopenharmony_ci int (*pre_hce_enable)(struct exynos_ufs *ufs); 17562306a36Sopenharmony_ci int (*post_hce_enable)(struct exynos_ufs *ufs); 17662306a36Sopenharmony_ci}; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistruct ufs_phy_time_cfg { 17962306a36Sopenharmony_ci u32 tx_linereset_p; 18062306a36Sopenharmony_ci u32 tx_linereset_n; 18162306a36Sopenharmony_ci u32 tx_high_z_cnt; 18262306a36Sopenharmony_ci u32 tx_base_n_val; 18362306a36Sopenharmony_ci u32 tx_gran_n_val; 18462306a36Sopenharmony_ci u32 tx_sleep_cnt; 18562306a36Sopenharmony_ci u32 rx_linereset; 18662306a36Sopenharmony_ci u32 rx_hibern8_wait; 18762306a36Sopenharmony_ci u32 rx_base_n_val; 18862306a36Sopenharmony_ci u32 rx_gran_n_val; 18962306a36Sopenharmony_ci u32 rx_sleep_cnt; 19062306a36Sopenharmony_ci u32 rx_stall_cnt; 19162306a36Sopenharmony_ci}; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistruct exynos_ufs { 19462306a36Sopenharmony_ci struct ufs_hba *hba; 19562306a36Sopenharmony_ci struct phy *phy; 19662306a36Sopenharmony_ci void __iomem *reg_hci; 19762306a36Sopenharmony_ci void __iomem *reg_unipro; 19862306a36Sopenharmony_ci void __iomem *reg_ufsp; 19962306a36Sopenharmony_ci struct clk *clk_hci_core; 20062306a36Sopenharmony_ci struct clk *clk_unipro_main; 20162306a36Sopenharmony_ci struct clk *clk_apb; 20262306a36Sopenharmony_ci u32 pclk_rate; 20362306a36Sopenharmony_ci u32 pclk_div; 20462306a36Sopenharmony_ci u32 pclk_avail_min; 20562306a36Sopenharmony_ci u32 pclk_avail_max; 20662306a36Sopenharmony_ci unsigned long mclk_rate; 20762306a36Sopenharmony_ci int avail_ln_rx; 20862306a36Sopenharmony_ci int avail_ln_tx; 20962306a36Sopenharmony_ci int rx_sel_idx; 21062306a36Sopenharmony_ci struct ufs_pa_layer_attr dev_req_params; 21162306a36Sopenharmony_ci struct ufs_phy_time_cfg t_cfg; 21262306a36Sopenharmony_ci ktime_t entry_hibern8_t; 21362306a36Sopenharmony_ci const struct exynos_ufs_drv_data *drv_data; 21462306a36Sopenharmony_ci struct regmap *sysreg; 21562306a36Sopenharmony_ci u32 shareability_reg_offset; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci u32 opts; 21862306a36Sopenharmony_ci#define EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL BIT(0) 21962306a36Sopenharmony_ci#define EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB BIT(1) 22062306a36Sopenharmony_ci#define EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL BIT(2) 22162306a36Sopenharmony_ci#define EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX BIT(3) 22262306a36Sopenharmony_ci#define EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER BIT(4) 22362306a36Sopenharmony_ci#define EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR BIT(5) 22462306a36Sopenharmony_ci}; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci#define for_each_ufs_rx_lane(ufs, i) \ 22762306a36Sopenharmony_ci for (i = (ufs)->rx_sel_idx; \ 22862306a36Sopenharmony_ci i < (ufs)->rx_sel_idx + (ufs)->avail_ln_rx; i++) 22962306a36Sopenharmony_ci#define for_each_ufs_tx_lane(ufs, i) \ 23062306a36Sopenharmony_ci for (i = 0; i < (ufs)->avail_ln_tx; i++) 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci#define EXYNOS_UFS_MMIO_FUNC(name) \ 23362306a36Sopenharmony_cistatic inline void name##_writel(struct exynos_ufs *ufs, u32 val, u32 reg)\ 23462306a36Sopenharmony_ci{ \ 23562306a36Sopenharmony_ci writel(val, ufs->reg_##name + reg); \ 23662306a36Sopenharmony_ci} \ 23762306a36Sopenharmony_ci \ 23862306a36Sopenharmony_cistatic inline u32 name##_readl(struct exynos_ufs *ufs, u32 reg) \ 23962306a36Sopenharmony_ci{ \ 24062306a36Sopenharmony_ci return readl(ufs->reg_##name + reg); \ 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ciEXYNOS_UFS_MMIO_FUNC(hci); 24462306a36Sopenharmony_ciEXYNOS_UFS_MMIO_FUNC(unipro); 24562306a36Sopenharmony_ciEXYNOS_UFS_MMIO_FUNC(ufsp); 24662306a36Sopenharmony_ci#undef EXYNOS_UFS_MMIO_FUNC 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_cilong exynos_ufs_calc_time_cntr(struct exynos_ufs *, long); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_cistatic inline void exynos_ufs_enable_ov_tm(struct ufs_hba *hba) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OV_TM), true); 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic inline void exynos_ufs_disable_ov_tm(struct ufs_hba *hba) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OV_TM), false); 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic inline void exynos_ufs_enable_dbg_mode(struct ufs_hba *hba) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), true); 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic inline void exynos_ufs_disable_dbg_mode(struct ufs_hba *hba) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), false); 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci#endif /* _UFS_EXYNOS_H_ */ 271