]> Git Repo - linux.git/blob - drivers/phy/samsung/phy-gs101-ufs.c
crypto: akcipher - Drop sign/verify operations
[linux.git] / drivers / phy / samsung / phy-gs101-ufs.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * UFS PHY driver data for Google Tensor gs101 SoC
4  *
5  * Copyright (C) 2024 Linaro Ltd
6  * Author: Peter Griffin <[email protected]>
7  */
8
9 #include "phy-samsung-ufs.h"
10
11 #define TENSOR_GS101_PHY_CTRL           0x3ec8
12 #define TENSOR_GS101_PHY_CTRL_MASK      0x1
13 #define TENSOR_GS101_PHY_CTRL_EN        BIT(0)
14 #define PHY_GS101_LANE_OFFSET           0x200
15 #define TRSV_REG338                     0x338
16 #define LN0_MON_RX_CAL_DONE             BIT(3)
17 #define TRSV_REG339                     0x339
18 #define LN0_MON_RX_CDR_FLD_CK_MODE_DONE BIT(3)
19 #define TRSV_REG222                     0x222
20 #define LN0_OVRD_RX_CDR_EN              BIT(4)
21 #define LN0_RX_CDR_EN                   BIT(3)
22
23 #define PHY_PMA_TRSV_ADDR(reg, lane)    (PHY_APB_ADDR((reg) + \
24                                         ((lane) * PHY_GS101_LANE_OFFSET)))
25
26 #define PHY_TRSV_REG_CFG_GS101(o, v, d) \
27         PHY_TRSV_REG_CFG_OFFSET(o, v, d, PHY_GS101_LANE_OFFSET)
28
29 /* Calibration for phy initialization */
30 static const struct samsung_ufs_phy_cfg tensor_gs101_pre_init_cfg[] = {
31         PHY_COMN_REG_CFG(0x43, 0x10,  PWR_MODE_ANY),
32         PHY_COMN_REG_CFG(0x3C, 0x14,  PWR_MODE_ANY),
33         PHY_COMN_REG_CFG(0x46, 0x48,  PWR_MODE_ANY),
34         PHY_TRSV_REG_CFG_GS101(0x200, 0x00, PWR_MODE_ANY),
35         PHY_TRSV_REG_CFG_GS101(0x201, 0x06, PWR_MODE_ANY),
36         PHY_TRSV_REG_CFG_GS101(0x202, 0x06, PWR_MODE_ANY),
37         PHY_TRSV_REG_CFG_GS101(0x203, 0x0a, PWR_MODE_ANY),
38         PHY_TRSV_REG_CFG_GS101(0x204, 0x00, PWR_MODE_ANY),
39         PHY_TRSV_REG_CFG_GS101(0x205, 0x11, PWR_MODE_ANY),
40         PHY_TRSV_REG_CFG_GS101(0x207, 0x0c, PWR_MODE_ANY),
41         PHY_TRSV_REG_CFG_GS101(0x2E1, 0xc0, PWR_MODE_ANY),
42         PHY_TRSV_REG_CFG_GS101(0x22D, 0xb8, PWR_MODE_ANY),
43         PHY_TRSV_REG_CFG_GS101(0x234, 0x60, PWR_MODE_ANY),
44         PHY_TRSV_REG_CFG_GS101(0x238, 0x13, PWR_MODE_ANY),
45         PHY_TRSV_REG_CFG_GS101(0x239, 0x48, PWR_MODE_ANY),
46         PHY_TRSV_REG_CFG_GS101(0x23A, 0x01, PWR_MODE_ANY),
47         PHY_TRSV_REG_CFG_GS101(0x23B, 0x25, PWR_MODE_ANY),
48         PHY_TRSV_REG_CFG_GS101(0x23C, 0x2a, PWR_MODE_ANY),
49         PHY_TRSV_REG_CFG_GS101(0x23D, 0x01, PWR_MODE_ANY),
50         PHY_TRSV_REG_CFG_GS101(0x23E, 0x13, PWR_MODE_ANY),
51         PHY_TRSV_REG_CFG_GS101(0x23F, 0x13, PWR_MODE_ANY),
52         PHY_TRSV_REG_CFG_GS101(0x240, 0x4a, PWR_MODE_ANY),
53         PHY_TRSV_REG_CFG_GS101(0x243, 0x40, PWR_MODE_ANY),
54         PHY_TRSV_REG_CFG_GS101(0x244, 0x02, PWR_MODE_ANY),
55         PHY_TRSV_REG_CFG_GS101(0x25D, 0x00, PWR_MODE_ANY),
56         PHY_TRSV_REG_CFG_GS101(0x25E, 0x3f, PWR_MODE_ANY),
57         PHY_TRSV_REG_CFG_GS101(0x25F, 0xff, PWR_MODE_ANY),
58         PHY_TRSV_REG_CFG_GS101(0x273, 0x33, PWR_MODE_ANY),
59         PHY_TRSV_REG_CFG_GS101(0x274, 0x50, PWR_MODE_ANY),
60         PHY_TRSV_REG_CFG_GS101(0x284, 0x02, PWR_MODE_ANY),
61         PHY_TRSV_REG_CFG_GS101(0x285, 0x02, PWR_MODE_ANY),
62         PHY_TRSV_REG_CFG_GS101(0x2A2, 0x04, PWR_MODE_ANY),
63         PHY_TRSV_REG_CFG_GS101(0x25D, 0x01, PWR_MODE_ANY),
64         PHY_TRSV_REG_CFG_GS101(0x2FA, 0x01, PWR_MODE_ANY),
65         PHY_TRSV_REG_CFG_GS101(0x286, 0x03, PWR_MODE_ANY),
66         PHY_TRSV_REG_CFG_GS101(0x287, 0x03, PWR_MODE_ANY),
67         PHY_TRSV_REG_CFG_GS101(0x288, 0x03, PWR_MODE_ANY),
68         PHY_TRSV_REG_CFG_GS101(0x289, 0x03, PWR_MODE_ANY),
69         PHY_TRSV_REG_CFG_GS101(0x2B3, 0x04, PWR_MODE_ANY),
70         PHY_TRSV_REG_CFG_GS101(0x2B6, 0x0b, PWR_MODE_ANY),
71         PHY_TRSV_REG_CFG_GS101(0x2B7, 0x0b, PWR_MODE_ANY),
72         PHY_TRSV_REG_CFG_GS101(0x2B8, 0x0b, PWR_MODE_ANY),
73         PHY_TRSV_REG_CFG_GS101(0x2B9, 0x0b, PWR_MODE_ANY),
74         PHY_TRSV_REG_CFG_GS101(0x2BA, 0x0b, PWR_MODE_ANY),
75         PHY_TRSV_REG_CFG_GS101(0x2BB, 0x06, PWR_MODE_ANY),
76         PHY_TRSV_REG_CFG_GS101(0x2BC, 0x06, PWR_MODE_ANY),
77         PHY_TRSV_REG_CFG_GS101(0x2BD, 0x06, PWR_MODE_ANY),
78         PHY_TRSV_REG_CFG_GS101(0x29E, 0x06, PWR_MODE_ANY),
79         PHY_TRSV_REG_CFG_GS101(0x2E4, 0x1a, PWR_MODE_ANY),
80         PHY_TRSV_REG_CFG_GS101(0x2ED, 0x25, PWR_MODE_ANY),
81         PHY_TRSV_REG_CFG_GS101(0x269, 0x1a, PWR_MODE_ANY),
82         PHY_TRSV_REG_CFG_GS101(0x2F4, 0x2f, PWR_MODE_ANY),
83         PHY_TRSV_REG_CFG_GS101(0x34B, 0x01, PWR_MODE_ANY),
84         PHY_TRSV_REG_CFG_GS101(0x34C, 0x23, PWR_MODE_ANY),
85         PHY_TRSV_REG_CFG_GS101(0x34D, 0x23, PWR_MODE_ANY),
86         PHY_TRSV_REG_CFG_GS101(0x34E, 0x45, PWR_MODE_ANY),
87         PHY_TRSV_REG_CFG_GS101(0x34F, 0x00, PWR_MODE_ANY),
88         PHY_TRSV_REG_CFG_GS101(0x350, 0x31, PWR_MODE_ANY),
89         PHY_TRSV_REG_CFG_GS101(0x351, 0x00, PWR_MODE_ANY),
90         PHY_TRSV_REG_CFG_GS101(0x352, 0x02, PWR_MODE_ANY),
91         PHY_TRSV_REG_CFG_GS101(0x353, 0x00, PWR_MODE_ANY),
92         PHY_TRSV_REG_CFG_GS101(0x354, 0x01, PWR_MODE_ANY),
93         PHY_COMN_REG_CFG(0x43, 0x18, PWR_MODE_ANY),
94         PHY_COMN_REG_CFG(0x43, 0x00, PWR_MODE_ANY),
95         END_UFS_PHY_CFG,
96 };
97
98 static const struct samsung_ufs_phy_cfg tensor_gs101_pre_pwr_hs_config[] = {
99         PHY_TRSV_REG_CFG_GS101(0x369, 0x11, PWR_MODE_ANY),
100         PHY_TRSV_REG_CFG_GS101(0x246, 0x03, PWR_MODE_ANY),
101 };
102
103 /* Calibration for HS mode series A/B */
104 static const struct samsung_ufs_phy_cfg tensor_gs101_post_pwr_hs_config[] = {
105         PHY_COMN_REG_CFG(0x8, 0x60, PWR_MODE_PWM_ANY),
106         PHY_TRSV_REG_CFG_GS101(0x222, 0x08, PWR_MODE_PWM_ANY),
107         PHY_TRSV_REG_CFG_GS101(0x246, 0x01, PWR_MODE_ANY),
108         END_UFS_PHY_CFG,
109 };
110
111 static const struct samsung_ufs_phy_cfg *tensor_gs101_ufs_phy_cfgs[CFG_TAG_MAX] = {
112         [CFG_PRE_INIT]          = tensor_gs101_pre_init_cfg,
113         [CFG_PRE_PWR_HS]        = tensor_gs101_pre_pwr_hs_config,
114         [CFG_POST_PWR_HS]       = tensor_gs101_post_pwr_hs_config,
115 };
116
117 static const char * const tensor_gs101_ufs_phy_clks[] = {
118         "ref_clk",
119 };
120
121 static int gs101_phy_wait_for_calibration(struct phy *phy, u8 lane)
122 {
123         struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
124         const unsigned int timeout_us = 40000;
125         const unsigned int sleep_us = 40;
126         u32 val;
127         u32 off;
128         int err;
129
130         off = PHY_PMA_TRSV_ADDR(TRSV_REG338, lane);
131
132         err = readl_poll_timeout(ufs_phy->reg_pma + off,
133                                  val, (val & LN0_MON_RX_CAL_DONE),
134                                  sleep_us, timeout_us);
135
136         if (err) {
137                 dev_err(ufs_phy->dev,
138                         "failed to get phy cal done %d\n", err);
139         }
140
141         return err;
142 }
143
144 #define DELAY_IN_US     40
145 #define RETRY_CNT       100
146 static int gs101_phy_wait_for_cdr_lock(struct phy *phy, u8 lane)
147 {
148         struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
149         u32 val;
150         int i;
151
152         for (i = 0; i < RETRY_CNT; i++) {
153                 udelay(DELAY_IN_US);
154                 val = readl(ufs_phy->reg_pma +
155                             PHY_PMA_TRSV_ADDR(TRSV_REG339, lane));
156
157                 if (val & LN0_MON_RX_CDR_FLD_CK_MODE_DONE)
158                         return 0;
159
160                 udelay(DELAY_IN_US);
161                 /* Override and enable clock data recovery */
162                 writel(LN0_OVRD_RX_CDR_EN, ufs_phy->reg_pma +
163                        PHY_PMA_TRSV_ADDR(TRSV_REG222, lane));
164                 writel(LN0_OVRD_RX_CDR_EN | LN0_RX_CDR_EN,
165                        ufs_phy->reg_pma + PHY_PMA_TRSV_ADDR(TRSV_REG222, lane));
166         }
167         dev_err(ufs_phy->dev, "failed to get cdr lock\n");
168         return -ETIMEDOUT;
169 }
170
171 const struct samsung_ufs_phy_drvdata tensor_gs101_ufs_phy = {
172         .cfgs = tensor_gs101_ufs_phy_cfgs,
173         .isol = {
174                 .offset = TENSOR_GS101_PHY_CTRL,
175                 .mask = TENSOR_GS101_PHY_CTRL_MASK,
176                 .en = TENSOR_GS101_PHY_CTRL_EN,
177         },
178         .clk_list = tensor_gs101_ufs_phy_clks,
179         .num_clks = ARRAY_SIZE(tensor_gs101_ufs_phy_clks),
180         .wait_for_cal = gs101_phy_wait_for_calibration,
181         .wait_for_cdr = gs101_phy_wait_for_cdr_lock,
182 };
This page took 0.04055 seconds and 4 git commands to generate.