1 /*
2  * Rockchip PCIe PHY driver
3  *
4  * Copyright (C) 2016 Shawn Lin <shawn.lin@rock-chips.com>
5  * Copyright (C) 2016 ROCKCHIP, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 
17 #include <linux/clk.h>
18 #include <linux/delay.h>
19 #include <linux/io.h>
20 #include <linux/mfd/syscon.h>
21 #include <linux/module.h>
22 #include <linux/of.h>
23 #include <linux/of_address.h>
24 #include <linux/of_platform.h>
25 #include <linux/phy/phy.h>
26 #include <linux/platform_device.h>
27 #include <linux/regmap.h>
28 #include <linux/reset.h>
29 
30 /*
31  * The higher 16-bit of this register is used for write protection
32  * only if BIT(x + 16) set to 1 the BIT(x) can be written.
33  */
34 #define HIWORD_UPDATE(val, mask, shift) \
35 		((val) << (shift) | (mask) << ((shift) + 16))
36 
37 #define PHY_MAX_LANE_NUM      4
38 #define PHY_CFG_DATA_SHIFT    7
39 #define PHY_CFG_ADDR_SHIFT    1
40 #define PHY_CFG_DATA_MASK     0xf
41 #define PHY_CFG_ADDR_MASK     0x3f
42 #define PHY_CFG_RD_MASK       0x3ff
43 #define PHY_CFG_WR_ENABLE     1
44 #define PHY_CFG_WR_DISABLE    1
45 #define PHY_CFG_WR_SHIFT      0
46 #define PHY_CFG_WR_MASK       1
47 #define PHY_CFG_PLL_LOCK      0x10
48 #define PHY_CFG_CLK_TEST      0x10
49 #define PHY_CFG_CLK_SCC       0x12
50 #define PHY_CFG_SEPE_RATE     BIT(3)
51 #define PHY_CFG_PLL_100M      BIT(3)
52 #define PHY_PLL_LOCKED        BIT(9)
53 #define PHY_PLL_OUTPUT        BIT(10)
54 #define PHY_LANE_A_STATUS     0x30
55 #define PHY_LANE_B_STATUS     0x31
56 #define PHY_LANE_C_STATUS     0x32
57 #define PHY_LANE_D_STATUS     0x33
58 #define PHY_LANE_RX_DET_SHIFT 11
59 #define PHY_LANE_RX_DET_TH    0x1
60 #define PHY_LANE_IDLE_OFF     0x1
61 #define PHY_LANE_IDLE_MASK    0x1
62 #define PHY_LANE_IDLE_A_SHIFT 3
63 #define PHY_LANE_IDLE_B_SHIFT 4
64 #define PHY_LANE_IDLE_C_SHIFT 5
65 #define PHY_LANE_IDLE_D_SHIFT 6
66 
67 struct rockchip_pcie_data {
68 	unsigned int pcie_conf;
69 	unsigned int pcie_status;
70 	unsigned int pcie_laneoff;
71 };
72 
73 struct rockchip_pcie_phy {
74 	struct rockchip_pcie_data *phy_data;
75 	struct regmap *reg_base;
76 	struct reset_control *phy_rst;
77 	struct clk *clk_pciephy_ref;
78 };
79 
80 static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy,
81 			      u32 addr, u32 data)
82 {
83 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
84 		     HIWORD_UPDATE(data,
85 				   PHY_CFG_DATA_MASK,
86 				   PHY_CFG_DATA_SHIFT) |
87 		     HIWORD_UPDATE(addr,
88 				   PHY_CFG_ADDR_MASK,
89 				   PHY_CFG_ADDR_SHIFT));
90 	udelay(1);
91 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
92 		     HIWORD_UPDATE(PHY_CFG_WR_ENABLE,
93 				   PHY_CFG_WR_MASK,
94 				   PHY_CFG_WR_SHIFT));
95 	udelay(1);
96 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
97 		     HIWORD_UPDATE(PHY_CFG_WR_DISABLE,
98 				   PHY_CFG_WR_MASK,
99 				   PHY_CFG_WR_SHIFT));
100 }
101 
102 static inline u32 phy_rd_cfg(struct rockchip_pcie_phy *rk_phy,
103 			     u32 addr)
104 {
105 	u32 val;
106 
107 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
108 		     HIWORD_UPDATE(addr,
109 				   PHY_CFG_RD_MASK,
110 				   PHY_CFG_ADDR_SHIFT));
111 	regmap_read(rk_phy->reg_base,
112 		    rk_phy->phy_data->pcie_status,
113 		    &val);
114 	return val;
115 }
116 
117 static int rockchip_pcie_phy_power_off(struct phy *phy)
118 {
119 	struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy);
120 	int err = 0;
121 
122 	err = reset_control_assert(rk_phy->phy_rst);
123 	if (err) {
124 		dev_err(&phy->dev, "assert phy_rst err %d\n", err);
125 		return err;
126 	}
127 
128 	return 0;
129 }
130 
131 static int rockchip_pcie_phy_power_on(struct phy *phy)
132 {
133 	struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy);
134 	int err = 0;
135 	u32 status;
136 	unsigned long timeout;
137 
138 	err = reset_control_deassert(rk_phy->phy_rst);
139 	if (err) {
140 		dev_err(&phy->dev, "deassert phy_rst err %d\n", err);
141 		return err;
142 	}
143 
144 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
145 		     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
146 				   PHY_CFG_ADDR_MASK,
147 				   PHY_CFG_ADDR_SHIFT));
148 
149 	/*
150 	 * No documented timeout value for phy operation below,
151 	 * so we make it large enough here. And we use loop-break
152 	 * method which should not be harmful.
153 	 */
154 	timeout = jiffies + msecs_to_jiffies(1000);
155 
156 	err = -EINVAL;
157 	while (time_before(jiffies, timeout)) {
158 		regmap_read(rk_phy->reg_base,
159 			    rk_phy->phy_data->pcie_status,
160 			    &status);
161 		if (status & PHY_PLL_LOCKED) {
162 			dev_dbg(&phy->dev, "pll locked!\n");
163 			err = 0;
164 			break;
165 		}
166 		msleep(20);
167 	}
168 
169 	if (err) {
170 		dev_err(&phy->dev, "pll lock timeout!\n");
171 		goto err_pll_lock;
172 	}
173 
174 	phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE);
175 	phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M);
176 
177 	err = -ETIMEDOUT;
178 	while (time_before(jiffies, timeout)) {
179 		regmap_read(rk_phy->reg_base,
180 			    rk_phy->phy_data->pcie_status,
181 			    &status);
182 		if (!(status & PHY_PLL_OUTPUT)) {
183 			dev_dbg(&phy->dev, "pll output enable done!\n");
184 			err = 0;
185 			break;
186 		}
187 		msleep(20);
188 	}
189 
190 	if (err) {
191 		dev_err(&phy->dev, "pll output enable timeout!\n");
192 		goto err_pll_lock;
193 	}
194 
195 	regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
196 		     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
197 				   PHY_CFG_ADDR_MASK,
198 				   PHY_CFG_ADDR_SHIFT));
199 	err = -EINVAL;
200 	while (time_before(jiffies, timeout)) {
201 		regmap_read(rk_phy->reg_base,
202 			    rk_phy->phy_data->pcie_status,
203 			    &status);
204 		if (status & PHY_PLL_LOCKED) {
205 			dev_dbg(&phy->dev, "pll relocked!\n");
206 			err = 0;
207 			break;
208 		}
209 		msleep(20);
210 	}
211 
212 	if (err) {
213 		dev_err(&phy->dev, "pll relock timeout!\n");
214 		goto err_pll_lock;
215 	}
216 
217 	return 0;
218 
219 err_pll_lock:
220 	reset_control_assert(rk_phy->phy_rst);
221 	return err;
222 }
223 
224 static int rockchip_pcie_phy_init(struct phy *phy)
225 {
226 	struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy);
227 	int err = 0;
228 
229 	err = clk_prepare_enable(rk_phy->clk_pciephy_ref);
230 	if (err) {
231 		dev_err(&phy->dev, "Fail to enable pcie ref clock.\n");
232 		goto err_refclk;
233 	}
234 
235 	err = reset_control_assert(rk_phy->phy_rst);
236 	if (err) {
237 		dev_err(&phy->dev, "assert phy_rst err %d\n", err);
238 		goto err_reset;
239 	}
240 
241 	return err;
242 
243 err_reset:
244 	clk_disable_unprepare(rk_phy->clk_pciephy_ref);
245 err_refclk:
246 	return err;
247 }
248 
249 static int rockchip_pcie_phy_exit(struct phy *phy)
250 {
251 	struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy);
252 
253 	clk_disable_unprepare(rk_phy->clk_pciephy_ref);
254 
255 	return 0;
256 }
257 
258 static const struct phy_ops ops = {
259 	.init		= rockchip_pcie_phy_init,
260 	.exit		= rockchip_pcie_phy_exit,
261 	.power_on	= rockchip_pcie_phy_power_on,
262 	.power_off	= rockchip_pcie_phy_power_off,
263 	.owner		= THIS_MODULE,
264 };
265 
266 static const struct rockchip_pcie_data rk3399_pcie_data = {
267 	.pcie_conf = 0xe220,
268 	.pcie_status = 0xe2a4,
269 	.pcie_laneoff = 0xe214,
270 };
271 
272 static const struct of_device_id rockchip_pcie_phy_dt_ids[] = {
273 	{
274 		.compatible = "rockchip,rk3399-pcie-phy",
275 		.data = &rk3399_pcie_data,
276 	},
277 	{}
278 };
279 
280 MODULE_DEVICE_TABLE(of, rockchip_pcie_phy_dt_ids);
281 
282 static int rockchip_pcie_phy_probe(struct platform_device *pdev)
283 {
284 	struct device *dev = &pdev->dev;
285 	struct rockchip_pcie_phy *rk_phy;
286 	struct phy *generic_phy;
287 	struct phy_provider *phy_provider;
288 	struct regmap *grf;
289 	const struct of_device_id *of_id;
290 
291 	grf = syscon_node_to_regmap(dev->parent->of_node);
292 	if (IS_ERR(grf)) {
293 		dev_err(dev, "Cannot find GRF syscon\n");
294 		return PTR_ERR(grf);
295 	}
296 
297 	rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL);
298 	if (!rk_phy)
299 		return -ENOMEM;
300 
301 	of_id = of_match_device(rockchip_pcie_phy_dt_ids, &pdev->dev);
302 	if (!of_id)
303 		return -EINVAL;
304 
305 	rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data;
306 	rk_phy->reg_base = grf;
307 
308 	rk_phy->phy_rst = devm_reset_control_get(dev, "phy");
309 	if (IS_ERR(rk_phy->phy_rst)) {
310 		if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER)
311 			dev_err(dev,
312 				"missing phy property for reset controller\n");
313 		return PTR_ERR(rk_phy->phy_rst);
314 	}
315 
316 	rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
317 	if (IS_ERR(rk_phy->clk_pciephy_ref)) {
318 		dev_err(dev, "refclk not found.\n");
319 		return PTR_ERR(rk_phy->clk_pciephy_ref);
320 	}
321 
322 	generic_phy = devm_phy_create(dev, dev->of_node, &ops);
323 	if (IS_ERR(generic_phy)) {
324 		dev_err(dev, "failed to create PHY\n");
325 		return PTR_ERR(generic_phy);
326 	}
327 
328 	phy_set_drvdata(generic_phy, rk_phy);
329 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
330 
331 	return PTR_ERR_OR_ZERO(phy_provider);
332 }
333 
334 static struct platform_driver rockchip_pcie_driver = {
335 	.probe		= rockchip_pcie_phy_probe,
336 	.driver		= {
337 		.name	= "rockchip-pcie-phy",
338 		.of_match_table = rockchip_pcie_phy_dt_ids,
339 	},
340 };
341 
342 module_platform_driver(rockchip_pcie_driver);
343 
344 MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>");
345 MODULE_DESCRIPTION("Rockchip PCIe PHY driver");
346 MODULE_LICENSE("GPL v2");
347