153 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * UFS PHY driver for Samsung EXYNOS SoC4 *5 * Copyright (C) 2020 Samsung Electronics Co., Ltd.6 * Author: Seungwon Jeon <essuuj@gmail.com>7 * Author: Alim Akhtar <alim.akhtar@samsung.com>8 *9 */10#ifndef _PHY_SAMSUNG_UFS_11#define _PHY_SAMSUNG_UFS_12 13#include <linux/phy/phy.h>14#include <linux/regmap.h>15 16#define PHY_COMN_BLK 117#define PHY_TRSV_BLK 218#define END_UFS_PHY_CFG { 0 }19#define PHY_TRSV_CH_OFFSET 0x3020#define PHY_APB_ADDR(off) ((off) << 2)21 22#define PHY_COMN_REG_CFG(o, v, d) { \23 .off_0 = PHY_APB_ADDR((o)), \24 .off_1 = 0, \25 .val = (v), \26 .desc = (d), \27 .id = PHY_COMN_BLK, \28}29 30#define PHY_TRSV_REG_CFG_OFFSET(o, v, d, c) { \31 .off_0 = PHY_APB_ADDR((o)), \32 .off_1 = PHY_APB_ADDR((o) + (c)), \33 .val = (v), \34 .desc = (d), \35 .id = PHY_TRSV_BLK, \36}37 38#define PHY_TRSV_REG_CFG(o, v, d) \39 PHY_TRSV_REG_CFG_OFFSET(o, v, d, PHY_TRSV_CH_OFFSET)40 41/* UFS PHY registers */42#define PHY_PLL_LOCK_STATUS 0x1e43 44#define PHY_PLL_LOCK_BIT BIT(5)45#define PHY_CDR_LOCK_BIT BIT(4)46 47/* description for PHY calibration */48enum {49 /* applicable to any */50 PWR_DESC_ANY = 0,51 /* mode */52 PWR_DESC_PWM = 1,53 PWR_DESC_HS = 2,54 /* series */55 PWR_DESC_SER_A = 1,56 PWR_DESC_SER_B = 2,57 /* gear */58 PWR_DESC_G1 = 1,59 PWR_DESC_G2 = 2,60 PWR_DESC_G3 = 3,61 /* field mask */62 MD_MASK = 0x3,63 SR_MASK = 0x3,64 GR_MASK = 0x7,65};66 67#define PWR_MODE_HS_G1_ANY PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_ANY)68#define PWR_MODE_HS_G1_SER_A PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_A)69#define PWR_MODE_HS_G1_SER_B PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_B)70#define PWR_MODE_HS_G2_ANY PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_ANY)71#define PWR_MODE_HS_G2_SER_A PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_A)72#define PWR_MODE_HS_G2_SER_B PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_B)73#define PWR_MODE_HS_G3_ANY PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_ANY)74#define PWR_MODE_HS_G3_SER_A PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_A)75#define PWR_MODE_HS_G3_SER_B PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_B)76#define PWR_MODE(g, s, m) ((((g) & GR_MASK) << 4) |\77 (((s) & SR_MASK) << 2) | ((m) & MD_MASK))78#define PWR_MODE_PWM_ANY PWR_MODE(PWR_DESC_ANY,\79 PWR_DESC_ANY, PWR_DESC_PWM)80#define PWR_MODE_HS(g, s) ((((g) & GR_MASK) << 4) |\81 (((s) & SR_MASK) << 2) | PWR_DESC_HS)82#define PWR_MODE_HS_ANY PWR_MODE(PWR_DESC_ANY,\83 PWR_DESC_ANY, PWR_DESC_HS)84#define PWR_MODE_ANY PWR_MODE(PWR_DESC_ANY,\85 PWR_DESC_ANY, PWR_DESC_ANY)86/* PHY calibration point/state */87enum {88 CFG_PRE_INIT,89 CFG_POST_INIT,90 CFG_PRE_PWR_HS,91 CFG_POST_PWR_HS,92 CFG_TAG_MAX,93};94 95struct samsung_ufs_phy_cfg {96 u32 off_0;97 u32 off_1;98 u32 val;99 u8 desc;100 u8 id;101};102 103struct samsung_ufs_phy_pmu_isol {104 u32 offset;105 u32 mask;106 u32 en;107};108 109struct samsung_ufs_phy_drvdata {110 const struct samsung_ufs_phy_cfg **cfgs;111 struct samsung_ufs_phy_pmu_isol isol;112 const char * const *clk_list;113 int num_clks;114 u32 cdr_lock_status_offset;115 /* SoC's specific operations */116 int (*wait_for_cal)(struct phy *phy, u8 lane);117 int (*wait_for_cdr)(struct phy *phy, u8 lane);118};119 120struct samsung_ufs_phy {121 struct device *dev;122 void __iomem *reg_pma;123 struct regmap *reg_pmu;124 struct clk_bulk_data *clks;125 const struct samsung_ufs_phy_drvdata *drvdata;126 const struct samsung_ufs_phy_cfg * const *cfgs;127 struct samsung_ufs_phy_pmu_isol isol;128 u8 lane_cnt;129 int ufs_phy_state;130 enum phy_mode mode;131};132 133static inline struct samsung_ufs_phy *get_samsung_ufs_phy(struct phy *phy)134{135 return (struct samsung_ufs_phy *)phy_get_drvdata(phy);136}137 138static inline void samsung_ufs_phy_ctrl_isol(139 struct samsung_ufs_phy *phy, u32 isol)140{141 regmap_update_bits(phy->reg_pmu, phy->isol.offset,142 phy->isol.mask, isol ? 0 : phy->isol.en);143}144 145int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy, u8 lane);146 147extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy;148extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy;149extern const struct samsung_ufs_phy_drvdata fsd_ufs_phy;150extern const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy;151 152#endif /* _PHY_SAMSUNG_UFS_ */153