1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
3 * Rockchip MIPI Synopsys DPHY RX0 driver
5 * Copyright (C) 2019 Collabora, Ltd.
9 * drivers/media/platform/rockchip/isp1/mipi_dphy_sy.c
10 * in https://chromium.googlesource.com/chromiumos/third_party/kernel,
11 * chromeos-4.4 branch.
13 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.
14 * Jacob Chen <jacob2.chen@rock-chips.com>
15 * Shunqian Zheng <zhengsq@rock-chips.com>
18 #include <linux/clk.h>
19 #include <linux/delay.h>
21 #include <linux/mfd/syscon.h>
22 #include <linux/module.h>
24 #include <linux/of_device.h>
25 #include <linux/phy/phy.h>
26 #include <linux/phy/phy-mipi-dphy.h>
27 #include <linux/platform_device.h>
28 #include <linux/regmap.h>
29 #include<linux/reset.h>
31 #include <linux/regulator/consumer.h>
32 #include "7110-m31-dphy.h"
35 #define SCFG_DSI_CSI_SEL 0x2c
36 #define SCFG_PHY_RESETB 0x30
37 #define SCFG_REFCLK_SEL 0x34
38 #define SCFG_DBUS_PW_PLL_SSC_LD0 0x38
39 #define SCFG_GRS_CDTX_PLL 0x3c
41 #define SCFG_RG_CDTX_PLL_FBK_PRE 0x44
42 #define SCFG_RG_CLANE_DLANE_TIME 0x58
43 #define SCFG_RG_CLANE_HS_TIME 0x58
45 #define SCFG_RG_EXTD_CYCLE_SEL 0x5c
47 #define SCFG_L0N_L0P_HSTX 0x60
48 #define SCFG_L1N_L1P_HSTX 0x64
49 #define SCFG_L2N_L2P_HSTX 0x68
50 #define SCFG_L3N_L3P_HSTX 0x6c
51 #define SCFG_L4N_L4P_HSTX 0x70
52 #define SCFG_LX_SWAP_SEL 0x78
54 #define SCFG_HS_PRE_ZERO_T_D 0xc4
55 #define SCFG_TXREADY_SRC_SEL_D 0xc8
56 #define SCFG_HS_PRE_ZERO_T_C 0xd4
57 #define SCFG_TXREADY_SRC_SEL_C 0xd8
59 //reg SCFG_LX_SWAP_SEL
60 #define OFFSET_CFG_L0_SWAP_SEL 0
61 #define OFFSET_CFG_L1_SWAP_SEL 3
62 #define OFFSET_CFG_L2_SWAP_SEL 6
63 #define OFFSET_CFG_L3_SWAP_SEL 9
64 #define OFFSET_CFG_L4_SWAP_SEL 12
66 //reg SCFG_DBUS_PW_PLL_SSC_LD0
67 #define OFFSET_SCFG_CFG_DATABUD16_SEL 0
68 #define OFFSET_SCFG_PWRON_READY_N 1
69 #define OFFSET_RG_CDTX_PLL_FM_EN 2
70 #define OFFSET_SCFG_PLLSSC_EN 3
71 #define OFFSET_RG_CDTX_PLL_LDO_STB_X2_EN 4
73 //reg SCFG_RG_CLANE_DLANE_TIME
74 #define OFFSET_DHS_PRE_TIME 8
75 #define OFFSET_DHS_TRIAL_TIME 16
76 #define OFFSET_DHS_ZERO_TIME 24
78 //reg SCFG_RG_CLANE_HS_TIME
79 #define OFFSET_CHS_PRE_TIME 8
80 #define OFFSET_CHS_TRIAL_TIME 16
81 #define OFFSET_CHS_ZERO_TIME 24
84 #define VID_MCTL_MAIN_DATA_CTL 0x04
85 #define VID_MCTL_MAIN_PHY_CTL 0x08
86 #define VID_MCTL_MAIN_EN 0x0c
87 #define VID_MAIN_CTRL_ADDR 0xb0
88 #define VID_VSIZE1_ADDR 0xb4
89 #define VID_VSIZE2_ADDR 0xb8
90 #define VID_HSIZE1_ADDR 0xc0
91 #define VID_HSIZE2_ADDR 0xc4
92 #define VID_BLKSIZE1_ADDR 0xCC
93 #define VID_BLKSIZE2_ADDR 0xd0
94 #define VID_PCK_TIME_ADDR 0xd8
95 #define VID_DPHY_TIME_ADDR 0xdc
96 #define VID_ERR_COLOR1_ADDR 0xe0
97 #define VID_ERR_COLOR2_ADDR 0xe4
98 #define VID_VPOS_ADDR 0xe8
99 #define VID_HPOS_ADDR 0xec
100 #define VID_MODE_STAT_ADDR 0xf0
101 #define VID_VCA_SET1_ADDR 0xf4
102 #define VID_VCA_SET2_ADDR 0xf8
105 #define VID_MODE_STAT_CLR_ADDR 0x160
106 #define VID_MODE_STAT_FLAG_ADDR 0x180
108 #define TVG_CTRL_ADDR 0x0fc
109 #define TVG_IMG_SIZE_ADDR 0x100
110 #define TVG_COLOR1_ADDR 0x104
111 #define TVG_COLOR1BIT_ADDR 0x108
112 #define TVG_COLOR2_ADDR 0x10c
113 #define TVG_COLOR2BIT_ADDR 0x110
114 #define TVG_STAT_ADDR 0x114
115 #define TVG_STAT_CTRL_ADDR 0x144
116 #define TVG_STAT_CLR_ADDR 0x164
117 #define TVG_STAT_FLAG_ADDR 0x184
119 #define DPI_IRQ_EN_ADDR 0x1a0
120 #define DPI_IRQ_CLR_ADDR 0x1a4
121 #define DPI_IRQ_STAT_ADDR 0x1a4
122 #define DPI_CFG_ADDR 0x1ac
126 #define SRST_ASSERT0 0x00
127 #define SRST_STATUS0 0x04
128 /* Definition controller bit for syd rst registers */
129 #define BIT_RST_DSI_DPI_PIX 17
133 void __iomem *topsys;
135 struct clk_bulk_data *clks;
137 struct clk * txesc_clk;
138 struct reset_control *sys_rst;
139 struct reset_control *txbytehs_rst;
141 void __iomem *aonsys;//7110 aonsys con
143 struct phy_configure_opts_mipi_dphy config;
147 struct regulator *mipitx_1p8;
148 struct regulator *mipitx_0p9;
153 static int sf_dphy_clkrst_get(struct device *dev, struct sf_dphy *dphy)
155 dphy->txesc_clk = devm_clk_get(dev, "dphy_txesc");
156 if (IS_ERR(dphy->txesc_clk)){
157 dev_err(dev, "===txesc_clk get error\n");
158 return PTR_ERR(dphy->txesc_clk);
160 dphy->sys_rst = reset_control_get_exclusive(dev, "dphy_sys");
161 if (IS_ERR(dphy->sys_rst)){
162 dev_err(dev, "===sys_rst get error\n");
163 return PTR_ERR(dphy->sys_rst);
168 static int sf_dphy_clkrst_ena_deas(struct device *dev, struct sf_dphy *dphy)
172 ret = clk_prepare_enable(dphy->txesc_clk);
174 dev_err(dev, "failed to prepare/enable txesc_clk\n");
177 ret = reset_control_deassert(dphy->sys_rst);
179 dev_err(dev, "failed to deassert sys_rst\n");
186 static int sf_dphy_clkrst_disa_assert(struct device *dev, struct sf_dphy *dphy)
189 ret = reset_control_assert(dphy->sys_rst);
191 dev_err(dev, "failed to assert sys_rst\n");
195 clk_disable_unprepare(dphy->txesc_clk);
201 *static int sf_dphy_remove(struct platform_device *pdev)
203 * struct sf_dphy *dphy = dev_get_drvdata(&pdev->dev);
204 * reset_control_assert(dphy->sys_rst);
205 * //reset_control_assert(dphy->txbytehs_rst);
206 * clk_disable_unprepare(dphy->txesc_clk);
212 static u32 top_sys_read32(struct sf_dphy *priv, u32 reg)
214 return ioread32(priv->topsys + reg);
218 static inline void top_sys_write32(struct sf_dphy *priv, u32 reg, u32 val)
220 iowrite32(val, priv->topsys + reg);
223 static void dsi_csi2tx_sel(struct sf_dphy *priv, int sel)
226 temp = top_sys_read32(priv, SCFG_DSI_CSI_SEL);
229 top_sys_write32(priv, SCFG_DSI_CSI_SEL, temp);
232 static void dphy_clane_hs_txready_sel(struct sf_dphy *priv, u32 ready_sel)
234 top_sys_write32(priv, SCFG_TXREADY_SRC_SEL_D, ready_sel);
235 top_sys_write32(priv, SCFG_TXREADY_SRC_SEL_C, ready_sel);
236 top_sys_write32(priv, SCFG_HS_PRE_ZERO_T_D, 0x30);
237 top_sys_write32(priv, SCFG_HS_PRE_ZERO_T_C, 0x30);
240 static void mipi_tx_lxn_set(struct sf_dphy *priv, u32 reg, u32 n_hstx, u32 p_hstx)
246 top_sys_write32(priv, reg, temp);
249 static void dphy_config(struct sf_dphy *priv, int bit_rate)
251 int pre_div, fbk_int, extd_cycle_sel;
252 int dhs_pre_time, dhs_zero_time, dhs_trial_time;
253 int chs_pre_time, chs_zero_time, chs_trial_time;
254 int chs_clk_pre_time, chs_clk_post_time;
257 mipi_tx_lxn_set(priv, SCFG_L0N_L0P_HSTX, 0x10, 0x10);
258 mipi_tx_lxn_set(priv, SCFG_L1N_L1P_HSTX, 0x10, 0x10);
259 mipi_tx_lxn_set(priv, SCFG_L2N_L2P_HSTX, 0x10, 0x10);
260 mipi_tx_lxn_set(priv, SCFG_L3N_L3P_HSTX, 0x10, 0x10);
261 mipi_tx_lxn_set(priv, SCFG_L4N_L4P_HSTX, 0x10, 0x10);
264 pre_div=0x1, fbk_int=2*0x33, extd_cycle_sel=0x4,
265 dhs_pre_time=0xe, dhs_zero_time=0x1d, dhs_trial_time=0x15,
266 chs_pre_time=0x5, chs_zero_time=0x2b, chs_trial_time=0xd,
267 chs_clk_pre_time=0xf,
268 chs_clk_post_time=0x71;
269 } else if (bit_rate == 100) {
270 pre_div=0x1, fbk_int=2*0x40, extd_cycle_sel=0x4,
271 dhs_pre_time=0x10, dhs_zero_time=0x21, dhs_trial_time=0x17,
272 chs_pre_time=0x7, chs_zero_time=0x35, chs_trial_time=0xf,
273 chs_clk_pre_time=0xf,
274 chs_clk_post_time=0x73;
275 } else if (bit_rate == 200) {
276 pre_div=0x1, fbk_int=2*0x40, extd_cycle_sel=0x3;
277 dhs_pre_time=0xc, dhs_zero_time=0x1b, dhs_trial_time=0x13;
278 chs_pre_time=0x7, chs_zero_time=0x35, chs_trial_time=0xf,
279 chs_clk_pre_time=0x7,
280 chs_clk_post_time=0x3f;
281 } else if(bit_rate == 300) {
282 pre_div=0x1, fbk_int=2*0x60, extd_cycle_sel=0x3,
283 dhs_pre_time=0x11, dhs_zero_time=0x25, dhs_trial_time=0x19,
284 chs_pre_time=0xa, chs_zero_time=0x50, chs_trial_time=0x15,
285 chs_clk_pre_time=0x7,
286 chs_clk_post_time=0x45;
287 } else if(bit_rate == 400) {
288 pre_div=0x1, fbk_int=2*0x40, extd_cycle_sel=0x2,
289 dhs_pre_time=0xa, dhs_zero_time=0x18, dhs_trial_time=0x11,
290 chs_pre_time=0x7, chs_zero_time=0x35, chs_trial_time=0xf,
291 chs_clk_pre_time=0x3,
292 chs_clk_post_time=0x25;
293 } else if(bit_rate == 500 ) {
294 pre_div=0x1, fbk_int=2*0x50, extd_cycle_sel=0x2,
295 dhs_pre_time=0xc, dhs_zero_time=0x1d, dhs_trial_time=0x14,
296 chs_pre_time=0x9, chs_zero_time=0x42, chs_trial_time=0x12,
297 chs_clk_pre_time=0x3,
298 chs_clk_post_time=0x28;
299 } else if(bit_rate == 600 ) {
300 pre_div=0x1, fbk_int=2*0x60, extd_cycle_sel=0x2,
301 dhs_pre_time=0xe, dhs_zero_time=0x23, dhs_trial_time=0x17,
302 chs_pre_time=0xa, chs_zero_time=0x50, chs_trial_time=0x15,
303 chs_clk_pre_time=0x3,
304 chs_clk_post_time=0x2b;
305 } else if(bit_rate == 700) {
306 pre_div=0x1, fbk_int=2*0x38, extd_cycle_sel=0x1,
307 dhs_pre_time=0x8, dhs_zero_time=0x14, dhs_trial_time=0xf,
308 chs_pre_time=0x6, chs_zero_time=0x2f, chs_trial_time=0xe,
309 chs_clk_pre_time=0x1,
310 chs_clk_post_time=0x16;
311 } else if(bit_rate == 800 ) {
312 pre_div=0x1, fbk_int=2*0x40, extd_cycle_sel=0x1,
313 dhs_pre_time=0x9, dhs_zero_time=0x17, dhs_trial_time=0x10,
314 chs_pre_time=0x7, chs_zero_time=0x35, chs_trial_time=0xf,
315 chs_clk_pre_time=0x1,
316 chs_clk_post_time=0x18;
317 } else if(bit_rate == 900 ) {
318 pre_div=0x1, fbk_int=2*0x48, extd_cycle_sel=0x1,
319 dhs_pre_time=0xa, dhs_zero_time=0x19, dhs_trial_time=0x12,
320 chs_pre_time=0x8, chs_zero_time=0x3c, chs_trial_time=0x10,
321 chs_clk_pre_time=0x1,
322 chs_clk_post_time=0x19;
323 } else if(bit_rate == 1000) {
324 pre_div=0x1, fbk_int=2*0x50, extd_cycle_sel=0x1,
325 dhs_pre_time=0xb, dhs_zero_time=0x1c, dhs_trial_time=0x13,
326 chs_pre_time=0x9, chs_zero_time=0x42, chs_trial_time=0x12,
327 chs_clk_pre_time=0x1,
328 chs_clk_post_time=0x1b;
329 } else if(bit_rate == 1100) {
330 pre_div=0x1, fbk_int=2*0x58, extd_cycle_sel=0x1,
331 dhs_pre_time=0xc, dhs_zero_time=0x1e, dhs_trial_time=0x15,
332 chs_pre_time=0x9, chs_zero_time=0x4a, chs_trial_time=0x14,
333 chs_clk_pre_time=0x1,
334 chs_clk_post_time=0x1d;
335 } else if(bit_rate == 1200) {
336 pre_div=0x1, fbk_int=2*0x60, extd_cycle_sel=0x1,
337 dhs_pre_time=0xe, dhs_zero_time=0x20, dhs_trial_time=0x16,
338 chs_pre_time=0xa, chs_zero_time=0x50, chs_trial_time=0x15,
339 chs_clk_pre_time=0x1,
340 chs_clk_post_time=0x1e;
341 } else if(bit_rate == 1300) {
342 pre_div=0x1, fbk_int=2*0x34, extd_cycle_sel=0x0,
343 dhs_pre_time=0x7, dhs_zero_time=0x12, dhs_trial_time=0xd,
344 chs_pre_time=0x5, chs_zero_time=0x2c, chs_trial_time=0xd,
345 chs_clk_pre_time=0x0,
346 chs_clk_post_time=0xf;
347 } else if(bit_rate == 1400) {
348 pre_div=0x1, fbk_int=2*0x38, extd_cycle_sel=0x0,
349 dhs_pre_time=0x7, dhs_zero_time=0x14, dhs_trial_time=0xe,
350 chs_pre_time=0x6, chs_zero_time=0x2f, chs_trial_time=0xe,
351 chs_clk_pre_time=0x0,
352 chs_clk_post_time=0x10;
353 } else if(bit_rate == 1500) {
354 pre_div=0x1, fbk_int=2*0x3c, extd_cycle_sel=0x0,
355 dhs_pre_time=0x8, dhs_zero_time=0x14, dhs_trial_time=0xf,
356 chs_pre_time=0x6, chs_zero_time=0x32, chs_trial_time=0xe,
357 chs_clk_pre_time=0x0,
358 chs_clk_post_time=0x11;
359 } else if(bit_rate == 1600) {
360 pre_div=0x1, fbk_int=2*0x40, extd_cycle_sel=0x0,
361 dhs_pre_time=0x9, dhs_zero_time=0x15, dhs_trial_time=0x10,
362 chs_pre_time=0x7, chs_zero_time=0x35, chs_trial_time=0xf,
363 chs_clk_pre_time=0x0,
364 chs_clk_post_time=0x12;
365 } else if(bit_rate == 1700) {
366 pre_div=0x1, fbk_int=2*0x44, extd_cycle_sel=0x0,
367 dhs_pre_time=0x9, dhs_zero_time=0x17, dhs_trial_time=0x10,
368 chs_pre_time=0x7, chs_zero_time=0x39, chs_trial_time=0x10,
369 chs_clk_pre_time=0x0,
370 chs_clk_post_time=0x12;
371 } else if(bit_rate == 1800) {
372 pre_div=0x1, fbk_int=2*0x48, extd_cycle_sel=0x0,
373 dhs_pre_time=0xa, dhs_zero_time=0x18, dhs_trial_time=0x11,
374 chs_pre_time=0x8, chs_zero_time=0x3c, chs_trial_time=0x10,
375 chs_clk_pre_time=0x0,
376 chs_clk_post_time=0x13;
377 } else if(bit_rate == 1900) {
378 pre_div=0x1, fbk_int=2*0x4c, extd_cycle_sel=0x0,
379 dhs_pre_time=0xa, dhs_zero_time=0x1a, dhs_trial_time=0x12,
380 chs_pre_time=0x8, chs_zero_time=0x3f, chs_trial_time=0x11,
381 chs_clk_pre_time=0x0,
382 chs_clk_post_time=0x14;
383 } else if(bit_rate == 2000) {
384 pre_div=0x1, fbk_int=2*0x50, extd_cycle_sel=0x0,
385 dhs_pre_time=0xb, dhs_zero_time=0x1b, dhs_trial_time=0x13,
386 chs_pre_time=0x9, chs_zero_time=0x42, chs_trial_time=0x12,
387 chs_clk_pre_time=0x0,
388 chs_clk_post_time=0x15;
389 } else if(bit_rate == 2100) {
390 pre_div=0x1, fbk_int=2*0x54, extd_cycle_sel=0x0,
391 dhs_pre_time=0xb, dhs_zero_time=0x1c, dhs_trial_time=0x13,
392 chs_pre_time=0x9, chs_zero_time=0x46, chs_trial_time=0x13,
393 chs_clk_pre_time=0x0,
394 chs_clk_post_time=0x15;
395 } else if(bit_rate == 2200) {
396 pre_div=0x1, fbk_int=2*0x5b, extd_cycle_sel=0x0,
397 dhs_pre_time=0xc, dhs_zero_time=0x1d, dhs_trial_time=0x14,
398 chs_pre_time=0x9, chs_zero_time=0x4a, chs_trial_time=0x14,
399 chs_clk_pre_time=0x0,
400 chs_clk_post_time=0x16;
401 } else if(bit_rate == 2300) {
402 pre_div=0x1, fbk_int=2*0x5c, extd_cycle_sel=0x0,
403 dhs_pre_time=0xc, dhs_zero_time=0x1f, dhs_trial_time=0x15,
404 chs_pre_time=0xa, chs_zero_time=0x4c, chs_trial_time=0x14,
405 chs_clk_pre_time=0x0,
406 chs_clk_post_time=0x17;
407 } else if(bit_rate == 2400) {
408 pre_div=0x1, fbk_int=2*0x60, extd_cycle_sel=0x0,
409 dhs_pre_time=0xd, dhs_zero_time=0x20, dhs_trial_time=0x16,
410 chs_pre_time=0xa, chs_zero_time=0x50, chs_trial_time=0x15,
411 chs_clk_pre_time=0x0,
412 chs_clk_post_time=0x18;
413 } else if(bit_rate == 2500) {
414 pre_div=0x1, fbk_int=2*0x64, extd_cycle_sel=0x0,
415 dhs_pre_time=0xe, dhs_zero_time=0x21, dhs_trial_time=0x16,
416 chs_pre_time=0xb, chs_zero_time=0x53, chs_trial_time=0x16,
417 chs_clk_pre_time=0x0,
418 chs_clk_post_time=0x18;
420 //default bit_rate == 700
421 pre_div=0x1, fbk_int=2*0x38, extd_cycle_sel=0x1,
422 dhs_pre_time=0x8, dhs_zero_time=0x14, dhs_trial_time=0xf,
423 chs_pre_time=0x6, chs_zero_time=0x2f, chs_trial_time=0xe,
424 chs_clk_pre_time=0x1,
425 chs_clk_post_time=0x16;
427 top_sys_write32(priv, SCFG_REFCLK_SEL, 0x3);
430 | (1 << OFFSET_CFG_L1_SWAP_SEL)
431 | (4 << OFFSET_CFG_L2_SWAP_SEL)
432 | (2 << OFFSET_CFG_L3_SWAP_SEL)
433 | (3 << OFFSET_CFG_L4_SWAP_SEL);
434 top_sys_write32(priv, SCFG_LX_SWAP_SEL, set_val);
437 | (0 << OFFSET_SCFG_PWRON_READY_N)
438 | (1 << OFFSET_RG_CDTX_PLL_FM_EN)
439 | (0 << OFFSET_SCFG_PLLSSC_EN)
440 | (1 << OFFSET_RG_CDTX_PLL_LDO_STB_X2_EN);
441 top_sys_write32(priv, SCFG_DBUS_PW_PLL_SSC_LD0, set_val);
445 top_sys_write32(priv, SCFG_RG_CDTX_PLL_FBK_PRE, set_val);
447 top_sys_write32(priv, SCFG_RG_EXTD_CYCLE_SEL, extd_cycle_sel);
449 set_val = chs_zero_time
450 | (dhs_pre_time << OFFSET_DHS_PRE_TIME)
451 | (dhs_trial_time << OFFSET_DHS_TRIAL_TIME)
452 | (dhs_zero_time << OFFSET_DHS_ZERO_TIME);
453 top_sys_write32(priv, SCFG_RG_CLANE_DLANE_TIME, set_val);
455 set_val = chs_clk_post_time
456 | (chs_clk_pre_time << OFFSET_CHS_PRE_TIME)
457 | (chs_pre_time << OFFSET_CHS_TRIAL_TIME)
458 | (chs_trial_time << OFFSET_CHS_ZERO_TIME);
459 top_sys_write32(priv, SCFG_RG_CLANE_HS_TIME, set_val);
463 static void reset_dphy(struct sf_dphy *priv, int resetb)
465 u32 cfg_dsc_enable = 0x01;//bit0
467 u32 precfg = top_sys_read32(priv, SCFG_PHY_RESETB);
468 precfg &= ~(cfg_dsc_enable);
469 precfg |= (resetb&cfg_dsc_enable);
470 top_sys_write32(priv, SCFG_PHY_RESETB, precfg);
473 static void polling_dphy_lock(struct sf_dphy *priv)
480 pll_unlock = top_sys_read32(priv, SCFG_GRS_CDTX_PLL) >> 3;
482 } while(pll_unlock == 0x1);
485 static int sf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
486 { //dev_info(dphy->dev,"--->sf_dphy_configure\n");
487 struct sf_dphy *dphy = phy_get_drvdata(phy);
488 uint32_t bit_rate = 800000000/1000000UL;//new mipi panel clock setting
489 //uint32_t bit_rate = 500000000/1000000UL;//7110 mipi panel clock setting
492 dphy_config(dphy, bit_rate);
495 polling_dphy_lock(dphy);
497 //dev_info(dphy->dev,"--->sf_dphy_configure\n");
502 static int is_pll_locked(struct sf_dphy *dphy)
504 int tmp = sf_dphy_get_reg(dphy->topsys + 0x8,
505 RGS_CDTX_PLL_UNLOCK_SHIFT, RGS_CDTX_PLL_UNLOCK_MASK);
508 static void reset(int assert, struct sf_dphy *dphy)
510 dev_info(dphy->dev, "1 SET_U0_MIPITX_DPHY_RESETB\n");
511 sf_dphy_set_reg(dphy->topsys + 0x64, (!assert), RESETB_SHIFT, RESETB_MASK);
512 dev_info(dphy->dev, "2 SET_U0_MIPITX_DPHY_RESETB\n");
515 while(!is_pll_locked(dphy));
516 dev_info(dphy->dev, "MIPI dphy-tx # PLL Locked\n");
520 static int sys_m31_dphy_tx_configure(struct phy *phy, union phy_configure_opts *opts)
522 struct sf_dphy *dphy;
524 unsigned long alignment;
526 const struct m31_dphy_config *p;
527 const uint32_t AON_POWER_READY_N_active = 0;
528 dphy = phy_get_drvdata(phy);
531 sf_dphy_set_reg(dphy->topsys + 0x8, 0x10,
532 RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK);
533 sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
534 RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK);
535 sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
536 RG_CDTX_L2N_HSTX_RES_SHIFT, RG_CDTX_L2N_HSTX_RES_MASK);
537 sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
538 RG_CDTX_L3N_HSTX_RES_SHIFT, RG_CDTX_L3N_HSTX_RES_MASK);
539 sf_dphy_set_reg(dphy->topsys + 0x10, 0x10,
540 RG_CDTX_L4N_HSTX_RES_SHIFT, RG_CDTX_L4N_HSTX_RES_MASK);
541 sf_dphy_set_reg(dphy->topsys + 0x8, 0x10,
542 RG_CDTX_L0P_HSTX_RES_SHIFT, RG_CDTX_L0P_HSTX_RES_MASK);
543 sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
544 RG_CDTX_L1P_HSTX_RES_SHIFT, RG_CDTX_L1P_HSTX_RES_MASK);
545 sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
546 RG_CDTX_L2P_HSTX_RES_SHIFT, RG_CDTX_L2P_HSTX_RES_MASK);
547 sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
548 RG_CDTX_L3P_HSTX_RES_SHIFT, RG_CDTX_L3P_HSTX_RES_MASK);
549 sf_dphy_set_reg(dphy->topsys + 0x10, 0x10,
550 RG_CDTX_L4P_HSTX_RES_SHIFT, RG_CDTX_L4P_HSTX_RES_MASK);
552 dev_info(dphy->dev,"request dphy hs_rate %dMbps\n", bitrate/1000000);
553 if (is_pll_locked(dphy))
554 dev_info(dphy->dev, "Error: MIPI dphy-tx # PLL is not supposed to be LOCKED\n");
556 dev_info(dphy->dev, "MIPI dphy-tx # PLL is not LOCKED\n");
558 alignment = M31_DPHY_BITRATE_ALIGN;
559 if (bitrate % alignment) {
560 bitrate += alignment - (bitrate % alignment);
563 dev_info(dphy->dev, "want dphy hs_rate %dMbps\n", bitrate/1000000);
565 p = m31_dphy_configs;
566 for (i = 0; i < ARRAY_SIZE(m31_dphy_configs); i++, p++) {
567 if (p->bitrate == bitrate) {
568 dev_info(dphy->dev, "config dphy hs_rate %dMbps\n", bitrate/1000000);
570 sf_dphy_set_reg(dphy->topsys + 0x64, M31_DPHY_REFCLK, REFCLK_IN_SEL_SHIFT, REFCLK_IN_SEL_MASK);
572 dev_info(dphy->dev, "MIPI dphy-tx # AON_POWER_READY_N active(%d)\n", AON_POWER_READY_N_active);
575 sf_dphy_set_reg(dphy->topsys, AON_POWER_READY_N_active,
576 AON_POWER_READY_N_SHIFT, AON_POWER_READY_N_MASK);
578 sf_dphy_set_reg(dphy->topsys, 0x0,
579 CFG_L0_SWAP_SEL_SHIFT, CFG_L0_SWAP_SEL_MASK);//Lane setting
580 sf_dphy_set_reg(dphy->topsys, 0x1,
581 CFG_L1_SWAP_SEL_SHIFT, CFG_L1_SWAP_SEL_MASK);
582 sf_dphy_set_reg(dphy->topsys, 0x4,
583 CFG_L2_SWAP_SEL_SHIFT, CFG_L2_SWAP_SEL_MASK);
584 sf_dphy_set_reg(dphy->topsys, 0x2,
585 CFG_L3_SWAP_SEL_SHIFT, CFG_L3_SWAP_SEL_MASK);
586 sf_dphy_set_reg(dphy->topsys, 0x3,
587 CFG_L4_SWAP_SEL_SHIFT, CFG_L4_SWAP_SEL_MASK);
589 sf_dphy_set_reg(dphy->topsys + 0x1c, 0x0,
590 RG_CDTX_PLL_SSC_EN_SHIFT, RG_CDTX_PLL_SSC_EN_MASK);
591 sf_dphy_set_reg(dphy->topsys + 0x18, 0x1,
592 RG_CDTX_PLL_LDO_STB_X2_EN_SHIFT, RG_CDTX_PLL_LDO_STB_X2_EN_MASK);
593 sf_dphy_set_reg(dphy->topsys + 0x18, 0x1,
594 RG_CDTX_PLL_FM_EN_SHIFT, RG_CDTX_PLL_FM_EN_MASK);
596 sf_dphy_set_reg(dphy->topsys + 0x18, p->pll_prev_div,
597 RG_CDTX_PLL_PRE_DIV_SHIFT, RG_CDTX_PLL_PRE_DIV_MASK);
598 sf_dphy_set_reg(dphy->topsys + 0x18, p->pll_fbk_int,
599 RG_CDTX_PLL_FBK_INT_SHIFT, RG_CDTX_PLL_FBK_INT_MASK);
600 sf_dphy_set_reg(dphy->topsys + 0x14, p->pll_fbk_fra,
601 RG_CDTX_PLL_FBK_FRA_SHIFT, RG_CDTX_PLL_FBK_FRA_MASK);
602 sf_dphy_set_reg(dphy->topsys + 0x28, p->extd_cycle_sel,
603 RG_EXTD_CYCLE_SEL_SHIFT, RG_EXTD_CYCLE_SEL_MASK);
604 sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_pre_time,
605 RG_DLANE_HS_PRE_TIME_SHIFT, RG_DLANE_HS_PRE_TIME_MASK);
606 sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_pre_time,
607 RG_DLANE_HS_PRE_TIME_SHIFT, RG_DLANE_HS_PRE_TIME_MASK);
608 sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_zero_time,
609 RG_DLANE_HS_ZERO_TIME_SHIFT, RG_DLANE_HS_ZERO_TIME_MASK);
610 sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_trail_time,
611 RG_DLANE_HS_TRAIL_TIME_SHIFT, RG_DLANE_HS_TRAIL_TIME_MASK);
612 sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_pre_time,
613 RG_CLANE_HS_PRE_TIME_SHIFT, RG_CLANE_HS_PRE_TIME_MASK);
614 sf_dphy_set_reg(dphy->topsys + 0x24, p->clane_hs_zero_time,
615 RG_CLANE_HS_ZERO_TIME_SHIFT, RG_CLANE_HS_ZERO_TIME_MASK);
616 sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_trail_time,
617 RG_CLANE_HS_TRAIL_TIME_SHIFT, RG_CLANE_HS_TRAIL_TIME_MASK);
618 sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_clk_pre_time,
619 RG_CLANE_HS_CLK_PRE_TIME_SHIFT, RG_CLANE_HS_CLK_PRE_TIME_MASK);
620 sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_clk_post_time,
621 RG_CLANE_HS_CLK_POST_TIME_SHIFT, RG_CLANE_HS_CLK_POST_TIME_MASK);
630 static int sf_dphy_power_on(struct phy *phy)
633 struct sf_dphy *dphy = phy_get_drvdata(phy);
637 sf_dphy_set_reg(dphy->topsys + 0x30, 0,
638 SCFG_PPI_C_READY_SEL_SHIFT, SCFG_PPI_C_READY_SEL_MASK);
639 sf_dphy_set_reg(dphy->topsys + 0x30, 0,
640 SCFG_DSI_TXREADY_ESC_SEL_SHIFT, SCFG_DSI_TXREADY_ESC_SEL_MASK);
641 sf_dphy_set_reg(dphy->topsys + 0x2c, 0x30,
642 SCFG_C_HS_PRE_ZERO_TIME_SHIFT, SCFG_C_HS_PRE_ZERO_TIME_MASK);
644 ret = sf_dphy_clkrst_ena_deas(dphy->dev, dphy);//clk rst interface enable and deassert
649 static int sf_dphy_power_off(struct phy *phy)
651 struct sf_dphy *dphy = phy_get_drvdata(phy);
653 sf_dphy_clkrst_disa_assert(dphy->dev, dphy);
658 static int sf_dphy_init(struct phy *phy)
663 static int sf_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
664 union phy_configure_opts *opts)
669 static int sf_dphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
675 static int sf_dphy_exit(struct phy *phy)
680 static const struct phy_ops sf_dphy_ops = {
681 .power_on = sf_dphy_power_on,
682 .power_off = sf_dphy_power_off,
683 .init = sf_dphy_init,
684 .exit = sf_dphy_exit,
685 //.configure = sf_dphy_configure,
686 .configure = sys_m31_dphy_tx_configure,
687 .validate = sf_dphy_validate,
688 .set_mode = sf_dphy_set_mode,
689 .owner = THIS_MODULE,
692 static const struct of_device_id sf_dphy_dt_ids[] = {
694 .compatible = "starfive,jh7100-mipi-dphy-tx",
698 MODULE_DEVICE_TABLE(of, sf_dphy_dt_ids);
700 static int sf_dphy_probe(struct platform_device *pdev)
702 struct phy_provider *phy_provider;
703 struct sf_dphy *dphy;
704 struct resource *res;
708 dev_info(&pdev->dev, "sf_dphy_probe begin\n");
709 dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
712 dev_set_drvdata(&pdev->dev, dphy);
714 dev_info(&pdev->dev, "===> %s enter, %d \n", __func__, __LINE__);
716 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
717 dphy->topsys = devm_ioremap_resource(&pdev->dev, res);
718 if (IS_ERR(dphy->topsys))
719 return PTR_ERR(dphy->topsys);
722 dphy->phy = devm_phy_create(&pdev->dev, NULL, &sf_dphy_ops);
723 if (IS_ERR(dphy->phy)) {
724 dev_err(&pdev->dev, "failed to create phy\n");
725 return PTR_ERR(dphy->phy);
727 phy_set_drvdata(dphy->phy, dphy);
729 dphy->dev = &pdev->dev;
730 // this power switch control bit was added in ECO, check ECO item "aon psw_en" for detail
731 dev_info(dphy->dev, "control ECO\n");
732 dphy->aonsys = ioremap(0x17010000, 0x10000);
734 temp = sf_dphy_get_reg(dphy->aonsys, AON_GP_REG_SHIFT,AON_GP_REG_MASK);
735 dev_info(dphy->dev, "GET_AON_GP_REG\n");
737 if (!(temp & DPHY_TX_PSW_EN_MASK)) {
738 temp |= DPHY_TX_PSW_EN_MASK;
739 sf_dphy_set_reg(dphy->aonsys, temp,AON_GP_REG_SHIFT,AON_GP_REG_MASK);
741 dev_info(dphy->dev, "control ECO\n");
744 dphy->mipitx_1p8 = devm_regulator_get(&pdev->dev, "mipitx_1p8");
745 if (IS_ERR(dphy->mipitx_1p8))
746 return PTR_ERR(dphy->mipitx_1p8);
748 dphy->mipitx_0p9 = devm_regulator_get(&pdev->dev, "mipitx_0p9");
749 if (IS_ERR(dphy->mipitx_0p9))
750 return PTR_ERR(dphy->mipitx_0p9);
753 ret = regulator_enable(dphy->mipitx_0p9);
755 dev_err(&pdev->dev, "Cannot enable mipitx_0p9 regulator\n");
759 ret = regulator_enable(dphy->mipitx_1p8);
761 dev_err(&pdev->dev, "Cannot enable mipitx_1p8 regulator\n");
767 ret = sf_dphy_clkrst_get(&pdev->dev, dphy);
769 phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
771 dev_info(&pdev->dev, "sf_dphy_probe end\n");
773 return PTR_ERR_OR_ZERO(phy_provider);
776 static struct platform_driver sf_dphy_driver = {
777 .probe = sf_dphy_probe,
779 .name = "sf-mipi-dphy-tx",
780 .of_match_table = sf_dphy_dt_ids,
783 module_platform_driver(sf_dphy_driver);
785 MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
786 MODULE_DESCRIPTION("sf MIPI DPHY TX0 driver");
787 MODULE_LICENSE("Dual MIT/GPL");