xref: /linux/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c (revision 16e6a1a3cb3fa5fa11cd76a9d71235d927923329)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip MIPI RX Innosilicon DPHY driver
4  *
5  * Copyright (C) 2021 Fuzhou Rockchip Electronics Co., Ltd.
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/clk.h>
10 #include <linux/delay.h>
11 #include <linux/io.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_platform.h>
16 #include <linux/phy/phy.h>
17 #include <linux/phy/phy-mipi-dphy.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
21 #include <linux/reset.h>
22 
23 /* GRF */
24 #define RK1808_GRF_PD_VI_CON_OFFSET	0x0430
25 
26 #define RK3326_GRF_PD_VI_CON_OFFSET	0x0430
27 
28 #define RK3368_GRF_SOC_CON6_OFFSET	0x0418
29 
30 #define RK3568_GRF_VI_CON0		0x0340
31 #define RK3568_GRF_VI_CON1		0x0344
32 
33 #define RK3588_CSIDPHY_GRF_CON0		0x0000
34 
35 /* PHY */
36 #define CSIDPHY_CTRL_LANE_ENABLE		0x00
37 #define CSIDPHY_CTRL_LANE_ENABLE_CK		BIT(6)
38 #define CSIDPHY_CTRL_LANE_ENABLE_MASK		GENMASK(5, 2)
39 #define CSIDPHY_CTRL_LANE_ENABLE_UNDEFINED	BIT(0)
40 
41 /* not present on all variants */
42 #define CSIDPHY_CTRL_PWRCTL			0x04
43 #define CSIDPHY_CTRL_PWRCTL_UNDEFINED		GENMASK(7, 5)
44 #define CSIDPHY_CTRL_PWRCTL_SYNCRST		BIT(2)
45 #define CSIDPHY_CTRL_PWRCTL_LDO_PD		BIT(1)
46 #define CSIDPHY_CTRL_PWRCTL_PLL_PD		BIT(0)
47 
48 #define CSIDPHY_CTRL_DIG_RST			0x80
49 #define CSIDPHY_CTRL_DIG_RST_UNDEFINED		0x1e
50 #define CSIDPHY_CTRL_DIG_RST_RESET		BIT(0)
51 
52 /* offset after ths_settle_offset */
53 #define CSIDPHY_CLK_THS_SETTLE			0
54 #define CSIDPHY_LANE_THS_SETTLE(n)		(((n) + 1) * 0x80)
55 #define CSIDPHY_THS_SETTLE_MASK			GENMASK(6, 0)
56 
57 /* offset after calib_offset */
58 #define CSIDPHY_CLK_CALIB_EN			0
59 #define CSIDPHY_LANE_CALIB_EN(n)		(((n) + 1) * 0x80)
60 #define CSIDPHY_CALIB_EN			BIT(7)
61 
62 /* Configure the count time of the THS-SETTLE by protocol. */
63 #define RK1808_CSIDPHY_CLK_WR_THS_SETTLE	0x160
64 #define RK3326_CSIDPHY_CLK_WR_THS_SETTLE	0x100
65 #define RK3368_CSIDPHY_CLK_WR_THS_SETTLE	0x100
66 #define RK3568_CSIDPHY_CLK_WR_THS_SETTLE	0x160
67 
68 /* Calibration reception enable */
69 #define RK1808_CSIDPHY_CLK_CALIB_EN		0x168
70 #define RK3568_CSIDPHY_CLK_CALIB_EN		0x168
71 
72 #define CSIDPHY_LANE_CLK_3_PHASE		0x38
73 #define CSIDPHY_CLK_PHASE_MASK			GENMASK(6, 4)
74 #define CSIDPHY_CLK_PHASE_DEFAULT		3
75 
76 #define RESETS_MAX				2
77 
78 /*
79  * The higher 16-bit of this register is used for write protection
80  * only if BIT(x + 16) set to 1 the BIT(x) can be written.
81  */
82 #define HIWORD_UPDATE(val, mask, shift) \
83 		((val) << (shift) | (mask) << ((shift) + 16))
84 
85 #define HZ_TO_MHZ(freq)				div_u64(freq, 1000 * 1000)
86 
87 enum dphy_reg_id {
88 	/* rk1808 & rk3326 */
89 	GRF_DPHY_CSIPHY_FORCERXMODE,
90 	GRF_DPHY_CSIPHY_CLKLANE_EN,
91 	GRF_DPHY_CSIPHY_DATALANE_EN,
92 };
93 
94 struct dphy_reg {
95 	u32 offset;
96 	u32 mask;
97 	u32 shift;
98 	u8 valid;
99 };
100 
101 #define PHY_REG(_offset, _width, _shift) \
102 	{ .offset = _offset, .mask = BIT(_width) - 1, .shift = _shift, .valid = 1, }
103 
104 static const struct dphy_reg rk1808_grf_dphy_regs[] = {
105 	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 0),
106 	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 1, 8),
107 	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK1808_GRF_PD_VI_CON_OFFSET, 4, 4),
108 };
109 
110 static const struct dphy_reg rk3326_grf_dphy_regs[] = {
111 	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 4, 0),
112 	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 1, 8),
113 	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3326_GRF_PD_VI_CON_OFFSET, 4, 4),
114 };
115 
116 static const struct dphy_reg rk3368_grf_dphy_regs[] = {
117 	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3368_GRF_SOC_CON6_OFFSET, 4, 8),
118 };
119 
120 static const struct dphy_reg rk3568_grf_dphy_regs[] = {
121 	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3568_GRF_VI_CON0, 4, 0),
122 	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 4, 4),
123 	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3568_GRF_VI_CON0, 1, 8),
124 };
125 
126 static const struct dphy_reg rk3588_grf_dphy_regs[] = {
127 	[GRF_DPHY_CSIPHY_FORCERXMODE] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 0),
128 	[GRF_DPHY_CSIPHY_DATALANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 4, 4),
129 	[GRF_DPHY_CSIPHY_CLKLANE_EN] = PHY_REG(RK3588_CSIDPHY_GRF_CON0, 1, 8),
130 };
131 
132 struct hsfreq_range {
133 	u32 range_h;
134 	u8 cfg_bit;
135 };
136 
137 struct dphy_drv_data {
138 	int pwrctl_offset;
139 	int ths_settle_offset;
140 	int calib_offset;
141 	const struct hsfreq_range *hsfreq_ranges;
142 	int num_hsfreq_ranges;
143 	const struct dphy_reg *grf_regs;
144 	const char *const *resets;
145 	unsigned int resets_num;
146 };
147 
148 struct rockchip_inno_csidphy {
149 	struct device *dev;
150 	void __iomem *phy_base;
151 	struct clk *pclk;
152 	struct regmap *grf;
153 	struct reset_control_bulk_data resets[RESETS_MAX];
154 	unsigned int resets_num;
155 	const struct dphy_drv_data *drv_data;
156 	struct phy_configure_opts_mipi_dphy config;
157 	u8 hsfreq;
158 	int clk_phase;
159 };
160 
write_grf_reg(struct rockchip_inno_csidphy * priv,int index,u8 value)161 static inline void write_grf_reg(struct rockchip_inno_csidphy *priv,
162 				 int index, u8 value)
163 {
164 	const struct dphy_drv_data *drv_data = priv->drv_data;
165 	const struct dphy_reg *reg = &drv_data->grf_regs[index];
166 
167 	if (reg->valid)
168 		regmap_write(priv->grf, reg->offset,
169 			     HIWORD_UPDATE(value, reg->mask, reg->shift));
170 }
171 
172 /* These tables must be sorted by .range_h ascending. */
173 static const struct hsfreq_range rk1808_mipidphy_hsfreq_ranges[] = {
174 	{ 109, 0x02}, { 149, 0x03}, { 199, 0x06}, { 249, 0x06},
175 	{ 299, 0x06}, { 399, 0x08}, { 499, 0x0b}, { 599, 0x0e},
176 	{ 699, 0x10}, { 799, 0x12}, { 999, 0x16}, {1199, 0x1e},
177 	{1399, 0x23}, {1599, 0x2d}, {1799, 0x32}, {1999, 0x37},
178 	{2199, 0x3c}, {2399, 0x41}, {2500, 0x46}
179 };
180 
181 static const struct hsfreq_range rk3326_mipidphy_hsfreq_ranges[] = {
182 	{ 109, 0x00}, { 149, 0x01}, { 199, 0x02}, { 249, 0x03},
183 	{ 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07},
184 	{ 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b},
185 	{1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e}
186 };
187 
188 static const struct hsfreq_range rk3368_mipidphy_hsfreq_ranges[] = {
189 	{ 109, 0x00}, { 149, 0x01}, { 199, 0x02}, { 249, 0x03},
190 	{ 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07},
191 	{ 699, 0x08}, { 799, 0x09}, { 899, 0x0a}, {1099, 0x0b},
192 	{1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e}
193 };
194 
195 static const char *const rk3368_reset_names[] = {
196 	"apb"
197 };
198 
199 static const char *const rk3588_reset_names[] = {
200 	"apb",
201 	"phy"
202 };
203 
rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy * priv,int hsfreq,int offset)204 static void rockchip_inno_csidphy_ths_settle(struct rockchip_inno_csidphy *priv,
205 					     int hsfreq, int offset)
206 {
207 	const struct dphy_drv_data *drv_data = priv->drv_data;
208 	u32 val;
209 
210 	val = readl(priv->phy_base + drv_data->ths_settle_offset + offset);
211 	val &= ~CSIDPHY_THS_SETTLE_MASK;
212 	val |= hsfreq;
213 	writel(val, priv->phy_base + drv_data->ths_settle_offset + offset);
214 }
215 
rockchip_inno_csidphy_configure(struct phy * phy,union phy_configure_opts * opts)216 static int rockchip_inno_csidphy_configure(struct phy *phy,
217 					   union phy_configure_opts *opts)
218 {
219 	struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
220 	const struct dphy_drv_data *drv_data = priv->drv_data;
221 	struct phy_configure_opts_mipi_dphy *config = &opts->mipi_dphy;
222 	unsigned int hsfreq = 0;
223 	unsigned int i;
224 	u64 data_rate_mbps;
225 	int ret;
226 
227 	/* pass with phy_mipi_dphy_get_default_config (with pixel rate?) */
228 	ret = phy_mipi_dphy_config_validate(config);
229 	if (ret)
230 		return ret;
231 
232 	data_rate_mbps = HZ_TO_MHZ(config->hs_clk_rate);
233 
234 	dev_dbg(priv->dev, "lanes %d - data_rate_mbps %llu\n",
235 		config->lanes, data_rate_mbps);
236 	for (i = 0; i < drv_data->num_hsfreq_ranges; i++) {
237 		if (drv_data->hsfreq_ranges[i].range_h >= data_rate_mbps) {
238 			hsfreq = drv_data->hsfreq_ranges[i].cfg_bit;
239 			break;
240 		}
241 	}
242 	if (!hsfreq)
243 		return -EINVAL;
244 
245 	priv->hsfreq = hsfreq;
246 	priv->config = *config;
247 	return 0;
248 }
249 
rockchip_inno_csidphy_power_on(struct phy * phy)250 static int rockchip_inno_csidphy_power_on(struct phy *phy)
251 {
252 	struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
253 	const struct dphy_drv_data *drv_data = priv->drv_data;
254 	u64 data_rate_mbps = HZ_TO_MHZ(priv->config.hs_clk_rate);
255 	u32 val;
256 	int ret, i;
257 
258 	ret = clk_enable(priv->pclk);
259 	if (ret < 0)
260 		return ret;
261 
262 	ret = pm_runtime_resume_and_get(priv->dev);
263 	if (ret < 0) {
264 		clk_disable(priv->pclk);
265 		return ret;
266 	}
267 
268 	/* phy start */
269 	if (drv_data->pwrctl_offset >= 0)
270 		writel(CSIDPHY_CTRL_PWRCTL_UNDEFINED |
271 		       CSIDPHY_CTRL_PWRCTL_SYNCRST,
272 		       priv->phy_base + drv_data->pwrctl_offset);
273 
274 	/* set data lane num and enable clock lane */
275 	val = FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_MASK, GENMASK(priv->config.lanes - 1, 0)) |
276 	      FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_CK, 1) |
277 	      FIELD_PREP(CSIDPHY_CTRL_LANE_ENABLE_UNDEFINED, 1);
278 	writel(val, priv->phy_base + CSIDPHY_CTRL_LANE_ENABLE);
279 
280 	/* Reset dphy analog part */
281 	if (drv_data->pwrctl_offset >= 0)
282 		writel(CSIDPHY_CTRL_PWRCTL_UNDEFINED,
283 		       priv->phy_base + drv_data->pwrctl_offset);
284 	usleep_range(500, 1000);
285 
286 	/* Reset dphy digital part */
287 	writel(CSIDPHY_CTRL_DIG_RST_UNDEFINED,
288 	       priv->phy_base + CSIDPHY_CTRL_DIG_RST);
289 	writel(CSIDPHY_CTRL_DIG_RST_UNDEFINED + CSIDPHY_CTRL_DIG_RST_RESET,
290 	       priv->phy_base + CSIDPHY_CTRL_DIG_RST);
291 
292 	/* not into receive mode/wait stopstate */
293 	write_grf_reg(priv, GRF_DPHY_CSIPHY_FORCERXMODE, 0x0);
294 
295 	/* enable calibration */
296 	if (data_rate_mbps > 1500 && drv_data->calib_offset >= 0) {
297 		writel(CSIDPHY_CALIB_EN,
298 		       priv->phy_base + drv_data->calib_offset +
299 					CSIDPHY_CLK_CALIB_EN);
300 		for (i = 0; i < priv->config.lanes; i++)
301 			writel(CSIDPHY_CALIB_EN,
302 			       priv->phy_base + drv_data->calib_offset +
303 						CSIDPHY_LANE_CALIB_EN(i));
304 	}
305 
306 	rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq,
307 					 CSIDPHY_CLK_THS_SETTLE);
308 	for (i = 0; i < priv->config.lanes; i++)
309 		rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq,
310 						 CSIDPHY_LANE_THS_SETTLE(i));
311 
312 	if (priv->clk_phase >= 0) {
313 		val = readl(priv->phy_base + CSIDPHY_LANE_CLK_3_PHASE);
314 		val &= ~CSIDPHY_CLK_PHASE_MASK;
315 		val |= FIELD_PREP(CSIDPHY_CLK_PHASE_MASK, priv->clk_phase);
316 		writel(val, priv->phy_base + CSIDPHY_LANE_CLK_3_PHASE);
317 	}
318 
319 	write_grf_reg(priv, GRF_DPHY_CSIPHY_CLKLANE_EN, 0x1);
320 	write_grf_reg(priv, GRF_DPHY_CSIPHY_DATALANE_EN,
321 		      GENMASK(priv->config.lanes - 1, 0));
322 
323 	return 0;
324 }
325 
rockchip_inno_csidphy_power_off(struct phy * phy)326 static int rockchip_inno_csidphy_power_off(struct phy *phy)
327 {
328 	struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
329 	const struct dphy_drv_data *drv_data = priv->drv_data;
330 
331 	/* disable all lanes */
332 	writel(CSIDPHY_CTRL_LANE_ENABLE_UNDEFINED,
333 	       priv->phy_base + CSIDPHY_CTRL_LANE_ENABLE);
334 
335 	/* disable pll and ldo */
336 	if (drv_data->pwrctl_offset >= 0)
337 		writel(CSIDPHY_CTRL_PWRCTL_UNDEFINED |
338 		       CSIDPHY_CTRL_PWRCTL_LDO_PD |
339 		       CSIDPHY_CTRL_PWRCTL_PLL_PD,
340 		       priv->phy_base + drv_data->pwrctl_offset);
341 	usleep_range(500, 1000);
342 
343 	pm_runtime_put(priv->dev);
344 	clk_disable(priv->pclk);
345 
346 	return 0;
347 }
348 
rockchip_inno_csidphy_init(struct phy * phy)349 static int rockchip_inno_csidphy_init(struct phy *phy)
350 {
351 	struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
352 
353 	return clk_prepare(priv->pclk);
354 }
355 
rockchip_inno_csidphy_exit(struct phy * phy)356 static int rockchip_inno_csidphy_exit(struct phy *phy)
357 {
358 	struct rockchip_inno_csidphy *priv = phy_get_drvdata(phy);
359 
360 	clk_unprepare(priv->pclk);
361 
362 	return 0;
363 }
364 
365 static const struct phy_ops rockchip_inno_csidphy_ops = {
366 	.power_on	= rockchip_inno_csidphy_power_on,
367 	.power_off	= rockchip_inno_csidphy_power_off,
368 	.init		= rockchip_inno_csidphy_init,
369 	.exit		= rockchip_inno_csidphy_exit,
370 	.configure	= rockchip_inno_csidphy_configure,
371 	.owner		= THIS_MODULE,
372 };
373 
374 static const struct dphy_drv_data rk1808_mipidphy_drv_data = {
375 	.pwrctl_offset = -1,
376 	.ths_settle_offset = RK1808_CSIDPHY_CLK_WR_THS_SETTLE,
377 	.calib_offset = RK1808_CSIDPHY_CLK_CALIB_EN,
378 	.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
379 	.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
380 	.grf_regs = rk1808_grf_dphy_regs,
381 	.resets = rk3368_reset_names,
382 	.resets_num = ARRAY_SIZE(rk3368_reset_names),
383 };
384 
385 static const struct dphy_drv_data rk3326_mipidphy_drv_data = {
386 	.pwrctl_offset = CSIDPHY_CTRL_PWRCTL,
387 	.ths_settle_offset = RK3326_CSIDPHY_CLK_WR_THS_SETTLE,
388 	.calib_offset = -1,
389 	.hsfreq_ranges = rk3326_mipidphy_hsfreq_ranges,
390 	.num_hsfreq_ranges = ARRAY_SIZE(rk3326_mipidphy_hsfreq_ranges),
391 	.grf_regs = rk3326_grf_dphy_regs,
392 	.resets = rk3368_reset_names,
393 	.resets_num = ARRAY_SIZE(rk3368_reset_names),
394 };
395 
396 static const struct dphy_drv_data rk3368_mipidphy_drv_data = {
397 	.pwrctl_offset = CSIDPHY_CTRL_PWRCTL,
398 	.ths_settle_offset = RK3368_CSIDPHY_CLK_WR_THS_SETTLE,
399 	.calib_offset = -1,
400 	.hsfreq_ranges = rk3368_mipidphy_hsfreq_ranges,
401 	.num_hsfreq_ranges = ARRAY_SIZE(rk3368_mipidphy_hsfreq_ranges),
402 	.grf_regs = rk3368_grf_dphy_regs,
403 	.resets = rk3368_reset_names,
404 	.resets_num = ARRAY_SIZE(rk3368_reset_names),
405 };
406 
407 static const struct dphy_drv_data rk3568_mipidphy_drv_data = {
408 	.pwrctl_offset = -1,
409 	.ths_settle_offset = RK3568_CSIDPHY_CLK_WR_THS_SETTLE,
410 	.calib_offset = RK3568_CSIDPHY_CLK_CALIB_EN,
411 	.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
412 	.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
413 	.grf_regs = rk3568_grf_dphy_regs,
414 	.resets = rk3368_reset_names,
415 	.resets_num = ARRAY_SIZE(rk3368_reset_names),
416 };
417 
418 static const struct dphy_drv_data rk3588_mipidphy_drv_data = {
419 	.pwrctl_offset = -1,
420 	.ths_settle_offset = RK3568_CSIDPHY_CLK_WR_THS_SETTLE,
421 	.calib_offset = RK3568_CSIDPHY_CLK_CALIB_EN,
422 	.hsfreq_ranges = rk1808_mipidphy_hsfreq_ranges,
423 	.num_hsfreq_ranges = ARRAY_SIZE(rk1808_mipidphy_hsfreq_ranges),
424 	.grf_regs = rk3588_grf_dphy_regs,
425 	.resets = rk3588_reset_names,
426 	.resets_num = ARRAY_SIZE(rk3588_reset_names),
427 };
428 
429 static const struct of_device_id rockchip_inno_csidphy_match_id[] = {
430 	{
431 		.compatible = "rockchip,px30-csi-dphy",
432 		.data = &rk3326_mipidphy_drv_data,
433 	},
434 	{
435 		.compatible = "rockchip,rk1808-csi-dphy",
436 		.data = &rk1808_mipidphy_drv_data,
437 	},
438 	{
439 		.compatible = "rockchip,rk3326-csi-dphy",
440 		.data = &rk3326_mipidphy_drv_data,
441 	},
442 	{
443 		.compatible = "rockchip,rk3368-csi-dphy",
444 		.data = &rk3368_mipidphy_drv_data,
445 	},
446 	{
447 		.compatible = "rockchip,rk3568-csi-dphy",
448 		.data = &rk3568_mipidphy_drv_data,
449 	},
450 	{
451 		.compatible = "rockchip,rk3588-csi-dphy",
452 		.data = &rk3588_mipidphy_drv_data,
453 	},
454 	{}
455 };
456 MODULE_DEVICE_TABLE(of, rockchip_inno_csidphy_match_id);
457 
rockchip_inno_csidphy_probe(struct platform_device * pdev)458 static int rockchip_inno_csidphy_probe(struct platform_device *pdev)
459 {
460 	struct rockchip_inno_csidphy *priv;
461 	struct device *dev = &pdev->dev;
462 	struct phy_provider *phy_provider;
463 	struct phy *phy;
464 	u32 phase;
465 	int ret;
466 
467 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
468 	if (!priv)
469 		return -ENOMEM;
470 
471 	priv->dev = dev;
472 	platform_set_drvdata(pdev, priv);
473 
474 	priv->drv_data = of_device_get_match_data(dev);
475 	if (!priv->drv_data) {
476 		dev_err(dev, "Can't find device data\n");
477 		return -ENODEV;
478 	}
479 
480 	priv->clk_phase = -1;
481 	if (device_property_read_u32(dev, "rockchip,clk-lane-phase",
482 				     &phase) == 0) {
483 		if (phase > 7) {
484 			dev_warn(dev,
485 				 "invalid rockchip,clk-lane-phase %u, using default %u\n",
486 				 phase, CSIDPHY_CLK_PHASE_DEFAULT);
487 			phase = CSIDPHY_CLK_PHASE_DEFAULT;
488 		}
489 		priv->clk_phase = phase;
490 	}
491 
492 	priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
493 						    "rockchip,grf");
494 	if (IS_ERR(priv->grf)) {
495 		dev_err(dev, "Can't find GRF syscon\n");
496 		return PTR_ERR(priv->grf);
497 	}
498 
499 	priv->phy_base = devm_platform_ioremap_resource(pdev, 0);
500 	if (IS_ERR(priv->phy_base))
501 		return PTR_ERR(priv->phy_base);
502 
503 	priv->pclk = devm_clk_get(dev, "pclk");
504 	if (IS_ERR(priv->pclk)) {
505 		dev_err(dev, "failed to get pclk\n");
506 		return PTR_ERR(priv->pclk);
507 	}
508 
509 	if (priv->drv_data->resets_num > RESETS_MAX) {
510 		dev_err(dev, "invalid number of resets\n");
511 		return -EINVAL;
512 	}
513 	priv->resets_num = priv->drv_data->resets_num;
514 	for (unsigned int i = 0; i < priv->resets_num; i++)
515 		priv->resets[i].id = priv->drv_data->resets[i];
516 	ret = devm_reset_control_bulk_get_exclusive(dev, priv->resets_num,
517 						    priv->resets);
518 	if (ret) {
519 		dev_err(dev, "failed to get system reset control\n");
520 		return ret;
521 	}
522 
523 	phy = devm_phy_create(dev, NULL, &rockchip_inno_csidphy_ops);
524 	if (IS_ERR(phy)) {
525 		dev_err(dev, "failed to create phy\n");
526 		return PTR_ERR(phy);
527 	}
528 
529 	phy_set_drvdata(phy, priv);
530 
531 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
532 	if (IS_ERR(phy_provider)) {
533 		dev_err(dev, "failed to register phy provider\n");
534 		return PTR_ERR(phy_provider);
535 	}
536 
537 	pm_runtime_enable(dev);
538 
539 	return 0;
540 }
541 
rockchip_inno_csidphy_remove(struct platform_device * pdev)542 static void rockchip_inno_csidphy_remove(struct platform_device *pdev)
543 {
544 	struct rockchip_inno_csidphy *priv = platform_get_drvdata(pdev);
545 
546 	pm_runtime_disable(priv->dev);
547 }
548 
549 static struct platform_driver rockchip_inno_csidphy_driver = {
550 	.driver = {
551 		.name = "rockchip-inno-csidphy",
552 		.of_match_table = rockchip_inno_csidphy_match_id,
553 	},
554 	.probe = rockchip_inno_csidphy_probe,
555 	.remove = rockchip_inno_csidphy_remove,
556 };
557 
558 module_platform_driver(rockchip_inno_csidphy_driver);
559 MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@theobroma-systems.com>");
560 MODULE_DESCRIPTION("Rockchip MIPI Innosilicon CSI-DPHY driver");
561 MODULE_LICENSE("GPL v2");
562