Merge tag 'writeback_for_v5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / phy / samsung / phy-samsung-ufs.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * UFS PHY driver for Samsung EXYNOS SoC
4  *
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 #define PHY_COMN_BLK    1
14 #define PHY_TRSV_BLK    2
15 #define END_UFS_PHY_CFG { 0 }
16 #define PHY_TRSV_CH_OFFSET      0x30
17 #define PHY_APB_ADDR(off)       ((off) << 2)
18
19 #define PHY_COMN_REG_CFG(o, v, d) {     \
20         .off_0 = PHY_APB_ADDR((o)),     \
21         .off_1 = 0,             \
22         .val = (v),             \
23         .desc = (d),            \
24         .id = PHY_COMN_BLK,     \
25 }
26
27 #define PHY_TRSV_REG_CFG(o, v, d) {     \
28         .off_0 = PHY_APB_ADDR((o)),     \
29         .off_1 = PHY_APB_ADDR((o) + PHY_TRSV_CH_OFFSET),        \
30         .val = (v),             \
31         .desc = (d),            \
32         .id = PHY_TRSV_BLK,     \
33 }
34
35 /* UFS PHY registers */
36 #define PHY_PLL_LOCK_STATUS     0x1e
37 #define PHY_CDR_LOCK_STATUS     0x5e
38
39 #define PHY_PLL_LOCK_BIT        BIT(5)
40 #define PHY_CDR_LOCK_BIT        BIT(4)
41
42 /* description for PHY calibration */
43 enum {
44         /* applicable to any */
45         PWR_DESC_ANY    = 0,
46         /* mode */
47         PWR_DESC_PWM    = 1,
48         PWR_DESC_HS     = 2,
49         /* series */
50         PWR_DESC_SER_A  = 1,
51         PWR_DESC_SER_B  = 2,
52         /* gear */
53         PWR_DESC_G1     = 1,
54         PWR_DESC_G2     = 2,
55         PWR_DESC_G3     = 3,
56         /* field mask */
57         MD_MASK         = 0x3,
58         SR_MASK         = 0x3,
59         GR_MASK         = 0x7,
60 };
61
62 #define PWR_MODE_HS_G1_ANY      PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_ANY)
63 #define PWR_MODE_HS_G1_SER_A    PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_A)
64 #define PWR_MODE_HS_G1_SER_B    PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_B)
65 #define PWR_MODE_HS_G2_ANY      PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_ANY)
66 #define PWR_MODE_HS_G2_SER_A    PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_A)
67 #define PWR_MODE_HS_G2_SER_B    PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_B)
68 #define PWR_MODE_HS_G3_ANY      PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_ANY)
69 #define PWR_MODE_HS_G3_SER_A    PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_A)
70 #define PWR_MODE_HS_G3_SER_B    PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_B)
71 #define PWR_MODE(g, s, m)       ((((g) & GR_MASK) << 4) |\
72                                  (((s) & SR_MASK) << 2) | ((m) & MD_MASK))
73 #define PWR_MODE_PWM_ANY        PWR_MODE(PWR_DESC_ANY,\
74                                          PWR_DESC_ANY, PWR_DESC_PWM)
75 #define PWR_MODE_HS(g, s)       ((((g) & GR_MASK) << 4) |\
76                                  (((s) & SR_MASK) << 2) | PWR_DESC_HS)
77 #define PWR_MODE_HS_ANY         PWR_MODE(PWR_DESC_ANY,\
78                                          PWR_DESC_ANY, PWR_DESC_HS)
79 #define PWR_MODE_ANY            PWR_MODE(PWR_DESC_ANY,\
80                                          PWR_DESC_ANY, PWR_DESC_ANY)
81 /* PHY calibration point/state */
82 enum {
83         CFG_PRE_INIT,
84         CFG_POST_INIT,
85         CFG_PRE_PWR_HS,
86         CFG_POST_PWR_HS,
87         CFG_TAG_MAX,
88 };
89
90 struct samsung_ufs_phy_cfg {
91         u32 off_0;
92         u32 off_1;
93         u32 val;
94         u8 desc;
95         u8 id;
96 };
97
98 struct samsung_ufs_phy_drvdata {
99         const struct samsung_ufs_phy_cfg **cfg;
100         struct pmu_isol {
101                 u32 offset;
102                 u32 mask;
103                 u32 en;
104         } isol;
105         bool has_symbol_clk;
106 };
107
108 struct samsung_ufs_phy {
109         struct device *dev;
110         void __iomem *reg_pma;
111         struct regmap *reg_pmu;
112         struct clk *ref_clk;
113         struct clk *ref_clk_parent;
114         struct clk *tx0_symbol_clk;
115         struct clk *rx0_symbol_clk;
116         struct clk *rx1_symbol_clk;
117         const struct samsung_ufs_phy_drvdata *drvdata;
118         struct samsung_ufs_phy_cfg **cfg;
119         const struct pmu_isol *isol;
120         u8 lane_cnt;
121         int ufs_phy_state;
122         enum phy_mode mode;
123 };
124
125 static inline struct samsung_ufs_phy *get_samsung_ufs_phy(struct phy *phy)
126 {
127         return (struct samsung_ufs_phy *)phy_get_drvdata(phy);
128 }
129
130 static inline void samsung_ufs_phy_ctrl_isol(
131                 struct samsung_ufs_phy *phy, u32 isol)
132 {
133         regmap_update_bits(phy->reg_pmu, phy->isol->offset,
134                            phy->isol->mask, isol ? 0 : phy->isol->en);
135 }
136
137 #include "phy-exynos7-ufs.h"
138
139 #endif /* _PHY_SAMSUNG_UFS_ */