1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd |
4 | * Author: |
5 | * Chris Zhong <zyw@rock-chips.com> |
6 | * Nickey Yang <nickey.yang@rock-chips.com> |
7 | */ |
8 | |
9 | #include <linux/clk.h> |
10 | #include <linux/iopoll.h> |
11 | #include <linux/math64.h> |
12 | #include <linux/mfd/syscon.h> |
13 | #include <linux/module.h> |
14 | #include <linux/of_device.h> |
15 | #include <linux/of_platform.h> |
16 | #include <linux/phy/phy.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/pm_runtime.h> |
19 | #include <linux/regmap.h> |
20 | |
21 | #include <video/mipi_display.h> |
22 | |
23 | #include <drm/bridge/dw_mipi_dsi.h> |
24 | #include <drm/drm_mipi_dsi.h> |
25 | #include <drm/drm_of.h> |
26 | #include <drm/drm_simple_kms_helper.h> |
27 | |
28 | #include "rockchip_drm_drv.h" |
29 | |
30 | #define DSI_PHY_RSTZ 0xa0 |
31 | #define PHY_DISFORCEPLL 0 |
32 | #define PHY_ENFORCEPLL BIT(3) |
33 | #define PHY_DISABLECLK 0 |
34 | #define PHY_ENABLECLK BIT(2) |
35 | #define PHY_RSTZ 0 |
36 | #define PHY_UNRSTZ BIT(1) |
37 | #define PHY_SHUTDOWNZ 0 |
38 | #define PHY_UNSHUTDOWNZ BIT(0) |
39 | |
40 | #define DSI_PHY_IF_CFG 0xa4 |
41 | #define N_LANES(n) ((((n) - 1) & 0x3) << 0) |
42 | #define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8) |
43 | |
44 | #define DSI_PHY_STATUS 0xb0 |
45 | #define LOCK BIT(0) |
46 | #define STOP_STATE_CLK_LANE BIT(2) |
47 | |
48 | #define DSI_PHY_TST_CTRL0 0xb4 |
49 | #define PHY_TESTCLK BIT(1) |
50 | #define PHY_UNTESTCLK 0 |
51 | #define PHY_TESTCLR BIT(0) |
52 | #define PHY_UNTESTCLR 0 |
53 | |
54 | #define DSI_PHY_TST_CTRL1 0xb8 |
55 | #define PHY_TESTEN BIT(16) |
56 | #define PHY_UNTESTEN 0 |
57 | #define PHY_TESTDOUT(n) (((n) & 0xff) << 8) |
58 | #define PHY_TESTDIN(n) (((n) & 0xff) << 0) |
59 | |
60 | #define DSI_INT_ST0 0xbc |
61 | #define DSI_INT_ST1 0xc0 |
62 | #define DSI_INT_MSK0 0xc4 |
63 | #define DSI_INT_MSK1 0xc8 |
64 | |
65 | #define PHY_STATUS_TIMEOUT_US 10000 |
66 | #define CMD_PKT_STATUS_TIMEOUT_US 20000 |
67 | |
68 | #define BYPASS_VCO_RANGE BIT(7) |
69 | #define VCO_RANGE_CON_SEL(val) (((val) & 0x7) << 3) |
70 | #define VCO_IN_CAP_CON_DEFAULT (0x0 << 1) |
71 | #define VCO_IN_CAP_CON_LOW (0x1 << 1) |
72 | #define VCO_IN_CAP_CON_HIGH (0x2 << 1) |
73 | #define REF_BIAS_CUR_SEL BIT(0) |
74 | |
75 | #define CP_CURRENT_3UA 0x1 |
76 | #define CP_CURRENT_4_5UA 0x2 |
77 | #define CP_CURRENT_7_5UA 0x6 |
78 | #define CP_CURRENT_6UA 0x9 |
79 | #define CP_CURRENT_12UA 0xb |
80 | #define CP_CURRENT_SEL(val) ((val) & 0xf) |
81 | #define CP_PROGRAM_EN BIT(7) |
82 | |
83 | #define LPF_RESISTORS_15_5KOHM 0x1 |
84 | #define LPF_RESISTORS_13KOHM 0x2 |
85 | #define LPF_RESISTORS_11_5KOHM 0x4 |
86 | #define LPF_RESISTORS_10_5KOHM 0x8 |
87 | #define LPF_RESISTORS_8KOHM 0x10 |
88 | #define LPF_PROGRAM_EN BIT(6) |
89 | #define LPF_RESISTORS_SEL(val) ((val) & 0x3f) |
90 | |
91 | #define HSFREQRANGE_SEL(val) (((val) & 0x3f) << 1) |
92 | |
93 | #define INPUT_DIVIDER(val) (((val) - 1) & 0x7f) |
94 | #define LOW_PROGRAM_EN 0 |
95 | #define HIGH_PROGRAM_EN BIT(7) |
96 | #define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f) |
97 | #define LOOP_DIV_HIGH_SEL(val) ((((val) - 1) >> 5) & 0xf) |
98 | #define PLL_LOOP_DIV_EN BIT(5) |
99 | #define PLL_INPUT_DIV_EN BIT(4) |
100 | |
101 | #define POWER_CONTROL BIT(6) |
102 | #define INTERNAL_REG_CURRENT BIT(3) |
103 | #define BIAS_BLOCK_ON BIT(2) |
104 | #define BANDGAP_ON BIT(0) |
105 | |
106 | #define TER_RESISTOR_HIGH BIT(7) |
107 | #define TER_RESISTOR_LOW 0 |
108 | #define LEVEL_SHIFTERS_ON BIT(6) |
109 | #define TER_CAL_DONE BIT(5) |
110 | #define SETRD_MAX (0x7 << 2) |
111 | #define POWER_MANAGE BIT(1) |
112 | #define TER_RESISTORS_ON BIT(0) |
113 | |
114 | #define BIASEXTR_SEL(val) ((val) & 0x7) |
115 | #define BANDGAP_SEL(val) ((val) & 0x7) |
116 | #define TLP_PROGRAM_EN BIT(7) |
117 | #define THS_PRE_PROGRAM_EN BIT(7) |
118 | #define THS_ZERO_PROGRAM_EN BIT(6) |
119 | |
120 | #define PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL 0x10 |
121 | #define PLL_CP_CONTROL_PLL_LOCK_BYPASS 0x11 |
122 | #define PLL_LPF_AND_CP_CONTROL 0x12 |
123 | #define PLL_INPUT_DIVIDER_RATIO 0x17 |
124 | #define PLL_LOOP_DIVIDER_RATIO 0x18 |
125 | #define PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL 0x19 |
126 | #define BANDGAP_AND_BIAS_CONTROL 0x20 |
127 | #define TERMINATION_RESISTER_CONTROL 0x21 |
128 | #define AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY 0x22 |
129 | #define HS_RX_CONTROL_OF_LANE_CLK 0x34 |
130 | #define HS_RX_CONTROL_OF_LANE_0 0x44 |
131 | #define HS_RX_CONTROL_OF_LANE_1 0x54 |
132 | #define HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL 0x60 |
133 | #define HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL 0x61 |
134 | #define HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL 0x62 |
135 | #define HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL 0x63 |
136 | #define HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL 0x64 |
137 | #define HS_TX_CLOCK_LANE_POST_TIME_CONTROL 0x65 |
138 | #define HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL 0x70 |
139 | #define HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL 0x71 |
140 | #define HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL 0x72 |
141 | #define HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL 0x73 |
142 | #define HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL 0x74 |
143 | #define HS_RX_DATA_LANE_THS_SETTLE_CONTROL 0x75 |
144 | #define HS_RX_CONTROL_OF_LANE_2 0x84 |
145 | #define HS_RX_CONTROL_OF_LANE_3 0x94 |
146 | |
147 | #define DW_MIPI_NEEDS_PHY_CFG_CLK BIT(0) |
148 | #define DW_MIPI_NEEDS_GRF_CLK BIT(1) |
149 | |
150 | #define PX30_GRF_PD_VO_CON1 0x0438 |
151 | #define PX30_DSI_FORCETXSTOPMODE (0xf << 7) |
152 | #define PX30_DSI_FORCERXMODE BIT(6) |
153 | #define PX30_DSI_TURNDISABLE BIT(5) |
154 | #define PX30_DSI_LCDC_SEL BIT(0) |
155 | |
156 | #define RK3288_GRF_SOC_CON6 0x025c |
157 | #define RK3288_DSI0_LCDC_SEL BIT(6) |
158 | #define RK3288_DSI1_LCDC_SEL BIT(9) |
159 | |
160 | #define RK3399_GRF_SOC_CON20 0x6250 |
161 | #define RK3399_DSI0_LCDC_SEL BIT(0) |
162 | #define RK3399_DSI1_LCDC_SEL BIT(4) |
163 | |
164 | #define RK3399_GRF_SOC_CON22 0x6258 |
165 | #define RK3399_DSI0_TURNREQUEST (0xf << 12) |
166 | #define RK3399_DSI0_TURNDISABLE (0xf << 8) |
167 | #define RK3399_DSI0_FORCETXSTOPMODE (0xf << 4) |
168 | #define RK3399_DSI0_FORCERXMODE (0xf << 0) |
169 | |
170 | #define RK3399_GRF_SOC_CON23 0x625c |
171 | #define RK3399_DSI1_TURNDISABLE (0xf << 12) |
172 | #define RK3399_DSI1_FORCETXSTOPMODE (0xf << 8) |
173 | #define RK3399_DSI1_FORCERXMODE (0xf << 4) |
174 | #define RK3399_DSI1_ENABLE (0xf << 0) |
175 | |
176 | #define RK3399_GRF_SOC_CON24 0x6260 |
177 | #define RK3399_TXRX_MASTERSLAVEZ BIT(7) |
178 | #define RK3399_TXRX_ENABLECLK BIT(6) |
179 | #define RK3399_TXRX_BASEDIR BIT(5) |
180 | #define RK3399_TXRX_SRC_SEL_ISP0 BIT(4) |
181 | #define RK3399_TXRX_TURNREQUEST GENMASK(3, 0) |
182 | |
183 | #define RK3568_GRF_VO_CON2 0x0368 |
184 | #define RK3568_DSI0_SKEWCALHS (0x1f << 11) |
185 | #define RK3568_DSI0_FORCETXSTOPMODE (0xf << 4) |
186 | #define RK3568_DSI0_TURNDISABLE BIT(2) |
187 | #define RK3568_DSI0_FORCERXMODE BIT(0) |
188 | |
189 | /* |
190 | * Note these registers do not appear in the datasheet, they are |
191 | * however present in the BSP driver which is where these values |
192 | * come from. Name GRF_VO_CON3 is assumed. |
193 | */ |
194 | #define RK3568_GRF_VO_CON3 0x36c |
195 | #define RK3568_DSI1_SKEWCALHS (0x1f << 11) |
196 | #define RK3568_DSI1_FORCETXSTOPMODE (0xf << 4) |
197 | #define RK3568_DSI1_TURNDISABLE BIT(2) |
198 | #define RK3568_DSI1_FORCERXMODE BIT(0) |
199 | |
200 | #define RV1126_GRF_DSIPHY_CON 0x10220 |
201 | #define RV1126_DSI_FORCETXSTOPMODE (0xf << 4) |
202 | #define RV1126_DSI_TURNDISABLE BIT(2) |
203 | #define RV1126_DSI_FORCERXMODE BIT(0) |
204 | |
205 | #define HIWORD_UPDATE(val, mask) (val | (mask) << 16) |
206 | |
207 | enum { |
208 | DW_DSI_USAGE_IDLE, |
209 | DW_DSI_USAGE_DSI, |
210 | DW_DSI_USAGE_PHY, |
211 | }; |
212 | |
213 | enum { |
214 | BANDGAP_97_07, |
215 | BANDGAP_98_05, |
216 | BANDGAP_99_02, |
217 | BANDGAP_100_00, |
218 | BANDGAP_93_17, |
219 | BANDGAP_94_15, |
220 | BANDGAP_95_12, |
221 | BANDGAP_96_10, |
222 | }; |
223 | |
224 | enum { |
225 | BIASEXTR_87_1, |
226 | BIASEXTR_91_5, |
227 | BIASEXTR_95_9, |
228 | BIASEXTR_100, |
229 | BIASEXTR_105_94, |
230 | BIASEXTR_111_88, |
231 | BIASEXTR_118_8, |
232 | BIASEXTR_127_7, |
233 | }; |
234 | |
235 | struct rockchip_dw_dsi_chip_data { |
236 | u32 reg; |
237 | |
238 | u32 lcdsel_grf_reg; |
239 | u32 lcdsel_big; |
240 | u32 lcdsel_lit; |
241 | |
242 | u32 enable_grf_reg; |
243 | u32 enable; |
244 | |
245 | u32 lanecfg1_grf_reg; |
246 | u32 lanecfg1; |
247 | u32 lanecfg2_grf_reg; |
248 | u32 lanecfg2; |
249 | |
250 | int (*dphy_rx_init)(struct phy *phy); |
251 | int (*dphy_rx_power_on)(struct phy *phy); |
252 | int (*dphy_rx_power_off)(struct phy *phy); |
253 | |
254 | unsigned int flags; |
255 | unsigned int max_data_lanes; |
256 | }; |
257 | |
258 | struct dw_mipi_dsi_rockchip { |
259 | struct device *dev; |
260 | struct rockchip_encoder encoder; |
261 | void __iomem *base; |
262 | |
263 | struct regmap *grf_regmap; |
264 | struct clk *pclk; |
265 | struct clk *pllref_clk; |
266 | struct clk *grf_clk; |
267 | struct clk *phy_cfg_clk; |
268 | |
269 | /* dual-channel */ |
270 | bool is_slave; |
271 | struct dw_mipi_dsi_rockchip *slave; |
272 | |
273 | /* optional external dphy */ |
274 | struct phy *phy; |
275 | union phy_configure_opts phy_opts; |
276 | |
277 | /* being a phy for other mipi hosts */ |
278 | unsigned int usage_mode; |
279 | struct mutex usage_mutex; |
280 | struct phy *dphy; |
281 | struct phy_configure_opts_mipi_dphy dphy_config; |
282 | |
283 | unsigned int lane_mbps; /* per lane */ |
284 | u16 input_div; |
285 | u16 feedback_div; |
286 | u32 format; |
287 | |
288 | struct dw_mipi_dsi *dmd; |
289 | const struct rockchip_dw_dsi_chip_data *cdata; |
290 | struct dw_mipi_dsi_plat_data pdata; |
291 | |
292 | bool dsi_bound; |
293 | }; |
294 | |
295 | static struct dw_mipi_dsi_rockchip *to_dsi(struct drm_encoder *encoder) |
296 | { |
297 | struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); |
298 | |
299 | return container_of(rkencoder, struct dw_mipi_dsi_rockchip, encoder); |
300 | } |
301 | |
302 | struct dphy_pll_parameter_map { |
303 | unsigned int max_mbps; |
304 | u8 hsfreqrange; |
305 | u8 icpctrl; |
306 | u8 lpfctrl; |
307 | }; |
308 | |
309 | /* The table is based on 27MHz DPHY pll reference clock. */ |
310 | static const struct dphy_pll_parameter_map dppa_map[] = { |
311 | { 89, 0x00, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM }, |
312 | { 99, 0x10, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM }, |
313 | { 109, 0x20, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM }, |
314 | { 129, 0x01, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM }, |
315 | { 139, 0x11, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM }, |
316 | { 149, 0x21, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM }, |
317 | { 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM }, |
318 | { 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM }, |
319 | { 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM }, |
320 | { 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM }, |
321 | { 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM }, |
322 | { 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM }, |
323 | { 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM }, |
324 | { 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM }, |
325 | { 329, 0x05, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM }, |
326 | { 359, 0x15, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM }, |
327 | { 399, 0x25, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM }, |
328 | { 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
329 | { 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
330 | { 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM }, |
331 | { 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM }, |
332 | { 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
333 | { 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
334 | { 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
335 | { 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
336 | { 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
337 | { 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM }, |
338 | { 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM }, |
339 | { 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM }, |
340 | {1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM }, |
341 | {1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM }, |
342 | {1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
343 | {1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
344 | {1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
345 | {1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
346 | {1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
347 | {1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
348 | {1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }, |
349 | {1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM } |
350 | }; |
351 | |
352 | static int max_mbps_to_parameter(unsigned int max_mbps) |
353 | { |
354 | int i; |
355 | |
356 | for (i = 0; i < ARRAY_SIZE(dppa_map); i++) |
357 | if (dppa_map[i].max_mbps >= max_mbps) |
358 | return i; |
359 | |
360 | return -EINVAL; |
361 | } |
362 | |
363 | static inline void dsi_write(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 val) |
364 | { |
365 | writel(val, addr: dsi->base + reg); |
366 | } |
367 | |
368 | static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi_rockchip *dsi, |
369 | u8 test_code, |
370 | u8 test_data) |
371 | { |
372 | /* |
373 | * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content |
374 | * is latched internally as the current test code. Test data is |
375 | * programmed internally by rising edge on TESTCLK. |
376 | */ |
377 | dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR); |
378 | |
379 | dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN | PHY_TESTDOUT(0) | |
380 | PHY_TESTDIN(test_code)); |
381 | |
382 | dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK | PHY_UNTESTCLR); |
383 | |
384 | dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_UNTESTEN | PHY_TESTDOUT(0) | |
385 | PHY_TESTDIN(test_data)); |
386 | |
387 | dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR); |
388 | } |
389 | |
390 | /* |
391 | * ns2bc - Nanoseconds to byte clock cycles |
392 | */ |
393 | static inline unsigned int ns2bc(struct dw_mipi_dsi_rockchip *dsi, int ns) |
394 | { |
395 | return DIV_ROUND_UP(ns * dsi->lane_mbps / 8, 1000); |
396 | } |
397 | |
398 | /* |
399 | * ns2ui - Nanoseconds to UI time periods |
400 | */ |
401 | static inline unsigned int ns2ui(struct dw_mipi_dsi_rockchip *dsi, int ns) |
402 | { |
403 | return DIV_ROUND_UP(ns * dsi->lane_mbps, 1000); |
404 | } |
405 | |
406 | static int dw_mipi_dsi_phy_init(void *priv_data) |
407 | { |
408 | struct dw_mipi_dsi_rockchip *dsi = priv_data; |
409 | int ret, i, vco; |
410 | |
411 | if (dsi->phy) |
412 | return 0; |
413 | |
414 | /* |
415 | * Get vco from frequency(lane_mbps) |
416 | * vco frequency table |
417 | * 000 - between 80 and 200 MHz |
418 | * 001 - between 200 and 300 MHz |
419 | * 010 - between 300 and 500 MHz |
420 | * 011 - between 500 and 700 MHz |
421 | * 100 - between 700 and 900 MHz |
422 | * 101 - between 900 and 1100 MHz |
423 | * 110 - between 1100 and 1300 MHz |
424 | * 111 - between 1300 and 1500 MHz |
425 | */ |
426 | vco = (dsi->lane_mbps < 200) ? 0 : (dsi->lane_mbps + 100) / 200; |
427 | |
428 | i = max_mbps_to_parameter(max_mbps: dsi->lane_mbps); |
429 | if (i < 0) { |
430 | DRM_DEV_ERROR(dsi->dev, |
431 | "failed to get parameter for %dmbps clock\n" , |
432 | dsi->lane_mbps); |
433 | return i; |
434 | } |
435 | |
436 | ret = clk_prepare_enable(clk: dsi->phy_cfg_clk); |
437 | if (ret) { |
438 | DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n" ); |
439 | return ret; |
440 | } |
441 | |
442 | dw_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL, |
443 | BYPASS_VCO_RANGE | |
444 | VCO_RANGE_CON_SEL(vco) | |
445 | VCO_IN_CAP_CON_LOW | |
446 | REF_BIAS_CUR_SEL); |
447 | |
448 | dw_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS, |
449 | CP_CURRENT_SEL(dppa_map[i].icpctrl)); |
450 | dw_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL, |
451 | CP_PROGRAM_EN | LPF_PROGRAM_EN | |
452 | LPF_RESISTORS_SEL(dppa_map[i].lpfctrl)); |
453 | |
454 | dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0, |
455 | HSFREQRANGE_SEL(dppa_map[i].hsfreqrange)); |
456 | |
457 | dw_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO, |
458 | INPUT_DIVIDER(dsi->input_div)); |
459 | dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO, |
460 | LOOP_DIV_LOW_SEL(dsi->feedback_div) | |
461 | LOW_PROGRAM_EN); |
462 | /* |
463 | * We need set PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL immediately |
464 | * to make the configured LSB effective according to IP simulation |
465 | * and lab test results. |
466 | * Only in this way can we get correct mipi phy pll frequency. |
467 | */ |
468 | dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL, |
469 | PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN); |
470 | dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO, |
471 | LOOP_DIV_HIGH_SEL(dsi->feedback_div) | |
472 | HIGH_PROGRAM_EN); |
473 | dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL, |
474 | PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN); |
475 | |
476 | dw_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY, |
477 | LOW_PROGRAM_EN | BIASEXTR_SEL(BIASEXTR_127_7)); |
478 | dw_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY, |
479 | HIGH_PROGRAM_EN | BANDGAP_SEL(BANDGAP_96_10)); |
480 | |
481 | dw_mipi_dsi_phy_write(dsi, BANDGAP_AND_BIAS_CONTROL, |
482 | POWER_CONTROL | INTERNAL_REG_CURRENT | |
483 | BIAS_BLOCK_ON | BANDGAP_ON); |
484 | |
485 | dw_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL, |
486 | TER_RESISTOR_LOW | TER_CAL_DONE | |
487 | SETRD_MAX | TER_RESISTORS_ON); |
488 | dw_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL, |
489 | TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON | |
490 | SETRD_MAX | POWER_MANAGE | |
491 | TER_RESISTORS_ON); |
492 | |
493 | dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL, |
494 | TLP_PROGRAM_EN | ns2bc(dsi, ns: 500)); |
495 | dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL, |
496 | THS_PRE_PROGRAM_EN | ns2ui(dsi, ns: 40)); |
497 | dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL, |
498 | THS_ZERO_PROGRAM_EN | ns2bc(dsi, ns: 300)); |
499 | dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL, |
500 | THS_PRE_PROGRAM_EN | ns2ui(dsi, ns: 100)); |
501 | dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL, |
502 | BIT(5) | ns2bc(dsi, ns: 100)); |
503 | dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_POST_TIME_CONTROL, |
504 | BIT(5) | (ns2bc(dsi, ns: 60) + 7)); |
505 | |
506 | dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL, |
507 | TLP_PROGRAM_EN | ns2bc(dsi, ns: 500)); |
508 | dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL, |
509 | THS_PRE_PROGRAM_EN | (ns2ui(dsi, ns: 50) + 20)); |
510 | dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL, |
511 | THS_ZERO_PROGRAM_EN | (ns2bc(dsi, ns: 140) + 2)); |
512 | dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL, |
513 | THS_PRE_PROGRAM_EN | (ns2ui(dsi, ns: 60) + 8)); |
514 | dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL, |
515 | BIT(5) | ns2bc(dsi, ns: 100)); |
516 | |
517 | clk_disable_unprepare(clk: dsi->phy_cfg_clk); |
518 | |
519 | return ret; |
520 | } |
521 | |
522 | static void dw_mipi_dsi_phy_power_on(void *priv_data) |
523 | { |
524 | struct dw_mipi_dsi_rockchip *dsi = priv_data; |
525 | int ret; |
526 | |
527 | ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY); |
528 | if (ret) { |
529 | DRM_DEV_ERROR(dsi->dev, "failed to set phy mode: %d\n" , ret); |
530 | return; |
531 | } |
532 | |
533 | phy_configure(phy: dsi->phy, opts: &dsi->phy_opts); |
534 | phy_power_on(phy: dsi->phy); |
535 | } |
536 | |
537 | static void dw_mipi_dsi_phy_power_off(void *priv_data) |
538 | { |
539 | struct dw_mipi_dsi_rockchip *dsi = priv_data; |
540 | |
541 | phy_power_off(phy: dsi->phy); |
542 | } |
543 | |
544 | static int |
545 | dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, |
546 | unsigned long mode_flags, u32 lanes, u32 format, |
547 | unsigned int *lane_mbps) |
548 | { |
549 | struct dw_mipi_dsi_rockchip *dsi = priv_data; |
550 | int bpp; |
551 | unsigned long mpclk, tmp; |
552 | unsigned int target_mbps = 1000; |
553 | unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps; |
554 | unsigned long best_freq = 0; |
555 | unsigned long fvco_min, fvco_max, fin, fout; |
556 | unsigned int min_prediv, max_prediv; |
557 | unsigned int _prediv, best_prediv; |
558 | unsigned long _fbdiv, best_fbdiv; |
559 | unsigned long min_delta = ULONG_MAX; |
560 | |
561 | dsi->format = format; |
562 | bpp = mipi_dsi_pixel_format_to_bpp(fmt: dsi->format); |
563 | if (bpp < 0) { |
564 | DRM_DEV_ERROR(dsi->dev, |
565 | "failed to get bpp for pixel format %d\n" , |
566 | dsi->format); |
567 | return bpp; |
568 | } |
569 | |
570 | mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC); |
571 | if (mpclk) { |
572 | /* take 1 / 0.8, since mbps must big than bandwidth of RGB */ |
573 | tmp = mpclk * (bpp / lanes) * 10 / 8; |
574 | if (tmp < max_mbps) |
575 | target_mbps = tmp; |
576 | else |
577 | DRM_DEV_ERROR(dsi->dev, |
578 | "DPHY clock frequency is out of range\n" ); |
579 | } |
580 | |
581 | /* for external phy only a the mipi_dphy_config is necessary */ |
582 | if (dsi->phy) { |
583 | phy_mipi_dphy_get_default_config(pixel_clock: mode->clock * 1000 * 10 / 8, |
584 | bpp, lanes, |
585 | cfg: &dsi->phy_opts.mipi_dphy); |
586 | dsi->lane_mbps = target_mbps; |
587 | *lane_mbps = dsi->lane_mbps; |
588 | |
589 | return 0; |
590 | } |
591 | |
592 | fin = clk_get_rate(clk: dsi->pllref_clk); |
593 | fout = target_mbps * USEC_PER_SEC; |
594 | |
595 | /* constraint: 5Mhz <= Fref / N <= 40MHz */ |
596 | min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC); |
597 | max_prediv = fin / (5 * USEC_PER_SEC); |
598 | |
599 | /* constraint: 80MHz <= Fvco <= 1500Mhz */ |
600 | fvco_min = 80 * USEC_PER_SEC; |
601 | fvco_max = 1500 * USEC_PER_SEC; |
602 | |
603 | for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { |
604 | u64 tmp; |
605 | u32 delta; |
606 | /* Fvco = Fref * M / N */ |
607 | tmp = (u64)fout * _prediv; |
608 | do_div(tmp, fin); |
609 | _fbdiv = tmp; |
610 | /* |
611 | * Due to the use of a "by 2 pre-scaler," the range of the |
612 | * feedback multiplication value M is limited to even division |
613 | * numbers, and m must be greater than 6, not bigger than 512. |
614 | */ |
615 | if (_fbdiv < 6 || _fbdiv > 512) |
616 | continue; |
617 | |
618 | _fbdiv += _fbdiv % 2; |
619 | |
620 | tmp = (u64)_fbdiv * fin; |
621 | do_div(tmp, _prediv); |
622 | if (tmp < fvco_min || tmp > fvco_max) |
623 | continue; |
624 | |
625 | delta = abs(fout - tmp); |
626 | if (delta < min_delta) { |
627 | best_prediv = _prediv; |
628 | best_fbdiv = _fbdiv; |
629 | min_delta = delta; |
630 | best_freq = tmp; |
631 | } |
632 | } |
633 | |
634 | if (best_freq) { |
635 | dsi->lane_mbps = DIV_ROUND_UP(best_freq, USEC_PER_SEC); |
636 | *lane_mbps = dsi->lane_mbps; |
637 | dsi->input_div = best_prediv; |
638 | dsi->feedback_div = best_fbdiv; |
639 | } else { |
640 | DRM_DEV_ERROR(dsi->dev, "Can not find best_freq for DPHY\n" ); |
641 | return -EINVAL; |
642 | } |
643 | |
644 | return 0; |
645 | } |
646 | |
647 | struct hstt { |
648 | unsigned int maxfreq; |
649 | struct dw_mipi_dsi_dphy_timing timing; |
650 | }; |
651 | |
652 | #define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \ |
653 | { \ |
654 | .maxfreq = _maxfreq, \ |
655 | .timing = { \ |
656 | .clk_lp2hs = _c_lp2hs, \ |
657 | .clk_hs2lp = _c_hs2lp, \ |
658 | .data_lp2hs = _d_lp2hs, \ |
659 | .data_hs2lp = _d_hs2lp, \ |
660 | } \ |
661 | } |
662 | |
663 | /* Table A-3 High-Speed Transition Times */ |
664 | static struct hstt hstt_table[] = { |
665 | HSTT( 90, 32, 20, 26, 13), |
666 | HSTT( 100, 35, 23, 28, 14), |
667 | HSTT( 110, 32, 22, 26, 13), |
668 | HSTT( 130, 31, 20, 27, 13), |
669 | HSTT( 140, 33, 22, 26, 14), |
670 | HSTT( 150, 33, 21, 26, 14), |
671 | HSTT( 170, 32, 20, 27, 13), |
672 | HSTT( 180, 36, 23, 30, 15), |
673 | HSTT( 200, 40, 22, 33, 15), |
674 | HSTT( 220, 40, 22, 33, 15), |
675 | HSTT( 240, 44, 24, 36, 16), |
676 | HSTT( 250, 48, 24, 38, 17), |
677 | HSTT( 270, 48, 24, 38, 17), |
678 | HSTT( 300, 50, 27, 41, 18), |
679 | HSTT( 330, 56, 28, 45, 18), |
680 | HSTT( 360, 59, 28, 48, 19), |
681 | HSTT( 400, 61, 30, 50, 20), |
682 | HSTT( 450, 67, 31, 55, 21), |
683 | HSTT( 500, 73, 31, 59, 22), |
684 | HSTT( 550, 79, 36, 63, 24), |
685 | HSTT( 600, 83, 37, 68, 25), |
686 | HSTT( 650, 90, 38, 73, 27), |
687 | HSTT( 700, 95, 40, 77, 28), |
688 | HSTT( 750, 102, 40, 84, 28), |
689 | HSTT( 800, 106, 42, 87, 30), |
690 | HSTT( 850, 113, 44, 93, 31), |
691 | HSTT( 900, 118, 47, 98, 32), |
692 | HSTT( 950, 124, 47, 102, 34), |
693 | HSTT(1000, 130, 49, 107, 35), |
694 | HSTT(1050, 135, 51, 111, 37), |
695 | HSTT(1100, 139, 51, 114, 38), |
696 | HSTT(1150, 146, 54, 120, 40), |
697 | HSTT(1200, 153, 57, 125, 41), |
698 | HSTT(1250, 158, 58, 130, 42), |
699 | HSTT(1300, 163, 58, 135, 44), |
700 | HSTT(1350, 168, 60, 140, 45), |
701 | HSTT(1400, 172, 64, 144, 47), |
702 | HSTT(1450, 176, 65, 148, 48), |
703 | HSTT(1500, 181, 66, 153, 50) |
704 | }; |
705 | |
706 | static int |
707 | dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps, |
708 | struct dw_mipi_dsi_dphy_timing *timing) |
709 | { |
710 | int i; |
711 | |
712 | for (i = 0; i < ARRAY_SIZE(hstt_table); i++) |
713 | if (lane_mbps < hstt_table[i].maxfreq) |
714 | break; |
715 | |
716 | if (i == ARRAY_SIZE(hstt_table)) |
717 | i--; |
718 | |
719 | *timing = hstt_table[i].timing; |
720 | |
721 | return 0; |
722 | } |
723 | |
724 | static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = { |
725 | .init = dw_mipi_dsi_phy_init, |
726 | .power_on = dw_mipi_dsi_phy_power_on, |
727 | .power_off = dw_mipi_dsi_phy_power_off, |
728 | .get_lane_mbps = dw_mipi_dsi_get_lane_mbps, |
729 | .get_timing = dw_mipi_dsi_phy_get_timing, |
730 | }; |
731 | |
732 | static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi) |
733 | { |
734 | if (dsi->cdata->lanecfg1_grf_reg) |
735 | regmap_write(map: dsi->grf_regmap, reg: dsi->cdata->lanecfg1_grf_reg, |
736 | val: dsi->cdata->lanecfg1); |
737 | |
738 | if (dsi->cdata->lanecfg2_grf_reg) |
739 | regmap_write(map: dsi->grf_regmap, reg: dsi->cdata->lanecfg2_grf_reg, |
740 | val: dsi->cdata->lanecfg2); |
741 | |
742 | if (dsi->cdata->enable_grf_reg) |
743 | regmap_write(map: dsi->grf_regmap, reg: dsi->cdata->enable_grf_reg, |
744 | val: dsi->cdata->enable); |
745 | } |
746 | |
747 | static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi, |
748 | int mux) |
749 | { |
750 | if (dsi->cdata->lcdsel_grf_reg) |
751 | regmap_write(map: dsi->grf_regmap, reg: dsi->cdata->lcdsel_grf_reg, |
752 | val: mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); |
753 | } |
754 | |
755 | static int |
756 | dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, |
757 | struct drm_crtc_state *crtc_state, |
758 | struct drm_connector_state *conn_state) |
759 | { |
760 | struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); |
761 | struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder); |
762 | |
763 | switch (dsi->format) { |
764 | case MIPI_DSI_FMT_RGB888: |
765 | s->output_mode = ROCKCHIP_OUT_MODE_P888; |
766 | break; |
767 | case MIPI_DSI_FMT_RGB666: |
768 | s->output_mode = ROCKCHIP_OUT_MODE_P666; |
769 | break; |
770 | case MIPI_DSI_FMT_RGB565: |
771 | s->output_mode = ROCKCHIP_OUT_MODE_P565; |
772 | break; |
773 | default: |
774 | WARN_ON(1); |
775 | return -EINVAL; |
776 | } |
777 | |
778 | s->output_type = DRM_MODE_CONNECTOR_DSI; |
779 | if (dsi->slave) |
780 | s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL; |
781 | |
782 | return 0; |
783 | } |
784 | |
785 | static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) |
786 | { |
787 | struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder); |
788 | int ret, mux; |
789 | |
790 | mux = drm_of_encoder_active_endpoint_id(node: dsi->dev->of_node, |
791 | encoder: &dsi->encoder.encoder); |
792 | if (mux < 0) |
793 | return; |
794 | |
795 | /* |
796 | * For the RK3399, the clk of grf must be enabled before writing grf |
797 | * register. And for RK3288 or other soc, this grf_clk must be NULL, |
798 | * the clk_prepare_enable return true directly. |
799 | */ |
800 | ret = clk_prepare_enable(clk: dsi->grf_clk); |
801 | if (ret) { |
802 | DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n" , ret); |
803 | return; |
804 | } |
805 | |
806 | dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux); |
807 | if (dsi->slave) |
808 | dw_mipi_dsi_rockchip_set_lcdsel(dsi: dsi->slave, mux); |
809 | |
810 | clk_disable_unprepare(clk: dsi->grf_clk); |
811 | } |
812 | |
813 | static const struct drm_encoder_helper_funcs |
814 | dw_mipi_dsi_encoder_helper_funcs = { |
815 | .atomic_check = dw_mipi_dsi_encoder_atomic_check, |
816 | .enable = dw_mipi_dsi_encoder_enable, |
817 | }; |
818 | |
819 | static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi, |
820 | struct drm_device *drm_dev) |
821 | { |
822 | struct drm_encoder *encoder = &dsi->encoder.encoder; |
823 | int ret; |
824 | |
825 | encoder->possible_crtcs = drm_of_find_possible_crtcs(dev: drm_dev, |
826 | port: dsi->dev->of_node); |
827 | |
828 | ret = drm_simple_encoder_init(dev: drm_dev, encoder, DRM_MODE_ENCODER_DSI); |
829 | if (ret) { |
830 | DRM_ERROR("Failed to initialize encoder with drm\n" ); |
831 | return ret; |
832 | } |
833 | |
834 | drm_encoder_helper_add(encoder, funcs: &dw_mipi_dsi_encoder_helper_funcs); |
835 | |
836 | return 0; |
837 | } |
838 | |
839 | static struct device |
840 | *dw_mipi_dsi_rockchip_find_second(struct dw_mipi_dsi_rockchip *dsi) |
841 | { |
842 | const struct of_device_id *match; |
843 | struct device_node *node = NULL, *local; |
844 | |
845 | match = of_match_device(matches: dsi->dev->driver->of_match_table, dev: dsi->dev); |
846 | |
847 | local = of_graph_get_remote_node(node: dsi->dev->of_node, port: 1, endpoint: 0); |
848 | if (!local) |
849 | return NULL; |
850 | |
851 | while ((node = of_find_compatible_node(from: node, NULL, |
852 | compat: match->compatible))) { |
853 | struct device_node *remote; |
854 | |
855 | /* found ourself */ |
856 | if (node == dsi->dev->of_node) |
857 | continue; |
858 | |
859 | remote = of_graph_get_remote_node(node, port: 1, endpoint: 0); |
860 | if (!remote) |
861 | continue; |
862 | |
863 | /* same display device in port1-ep0 for both */ |
864 | if (remote == local) { |
865 | struct dw_mipi_dsi_rockchip *dsi2; |
866 | struct platform_device *pdev; |
867 | |
868 | pdev = of_find_device_by_node(np: node); |
869 | |
870 | /* |
871 | * we have found the second, so will either return it |
872 | * or return with an error. In any case won't need the |
873 | * nodes anymore nor continue the loop. |
874 | */ |
875 | of_node_put(node: remote); |
876 | of_node_put(node); |
877 | of_node_put(node: local); |
878 | |
879 | if (!pdev) |
880 | return ERR_PTR(error: -EPROBE_DEFER); |
881 | |
882 | dsi2 = platform_get_drvdata(pdev); |
883 | if (!dsi2) { |
884 | platform_device_put(pdev); |
885 | return ERR_PTR(error: -EPROBE_DEFER); |
886 | } |
887 | |
888 | return &pdev->dev; |
889 | } |
890 | |
891 | of_node_put(node: remote); |
892 | } |
893 | |
894 | of_node_put(node: local); |
895 | |
896 | return NULL; |
897 | } |
898 | |
899 | static int dw_mipi_dsi_rockchip_bind(struct device *dev, |
900 | struct device *master, |
901 | void *data) |
902 | { |
903 | struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev); |
904 | struct drm_device *drm_dev = data; |
905 | struct device *second; |
906 | bool master1, master2; |
907 | int ret; |
908 | |
909 | second = dw_mipi_dsi_rockchip_find_second(dsi); |
910 | if (IS_ERR(ptr: second)) |
911 | return PTR_ERR(ptr: second); |
912 | |
913 | if (second) { |
914 | master1 = of_property_read_bool(np: dsi->dev->of_node, |
915 | propname: "clock-master" ); |
916 | master2 = of_property_read_bool(np: second->of_node, |
917 | propname: "clock-master" ); |
918 | |
919 | if (master1 && master2) { |
920 | DRM_DEV_ERROR(dsi->dev, "only one clock-master allowed\n" ); |
921 | return -EINVAL; |
922 | } |
923 | |
924 | if (!master1 && !master2) { |
925 | DRM_DEV_ERROR(dsi->dev, "no clock-master defined\n" ); |
926 | return -EINVAL; |
927 | } |
928 | |
929 | /* we are the slave in dual-DSI */ |
930 | if (!master1) { |
931 | dsi->is_slave = true; |
932 | return 0; |
933 | } |
934 | |
935 | dsi->slave = dev_get_drvdata(dev: second); |
936 | if (!dsi->slave) { |
937 | DRM_DEV_ERROR(dev, "could not get slaves data\n" ); |
938 | return -ENODEV; |
939 | } |
940 | |
941 | dsi->slave->is_slave = true; |
942 | dw_mipi_dsi_set_slave(dsi: dsi->dmd, slave: dsi->slave->dmd); |
943 | put_device(dev: second); |
944 | } |
945 | |
946 | pm_runtime_get_sync(dev: dsi->dev); |
947 | if (dsi->slave) |
948 | pm_runtime_get_sync(dev: dsi->slave->dev); |
949 | |
950 | ret = clk_prepare_enable(clk: dsi->pllref_clk); |
951 | if (ret) { |
952 | DRM_DEV_ERROR(dev, "Failed to enable pllref_clk: %d\n" , ret); |
953 | goto out_pm_runtime; |
954 | } |
955 | |
956 | /* |
957 | * With the GRF clock running, write lane and dual-mode configurations |
958 | * that won't change immediately. If we waited until enable() to do |
959 | * this, things like panel preparation would not be able to send |
960 | * commands over DSI. |
961 | */ |
962 | ret = clk_prepare_enable(clk: dsi->grf_clk); |
963 | if (ret) { |
964 | DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n" , ret); |
965 | goto out_pll_clk; |
966 | } |
967 | |
968 | dw_mipi_dsi_rockchip_config(dsi); |
969 | if (dsi->slave) |
970 | dw_mipi_dsi_rockchip_config(dsi: dsi->slave); |
971 | |
972 | clk_disable_unprepare(clk: dsi->grf_clk); |
973 | |
974 | ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev); |
975 | if (ret) { |
976 | DRM_DEV_ERROR(dev, "Failed to create drm encoder\n" ); |
977 | goto out_pll_clk; |
978 | } |
979 | rockchip_drm_encoder_set_crtc_endpoint_id(rencoder: &dsi->encoder, |
980 | np: dev->of_node, port: 0, reg: 0); |
981 | |
982 | ret = dw_mipi_dsi_bind(dsi: dsi->dmd, encoder: &dsi->encoder.encoder); |
983 | if (ret) { |
984 | DRM_DEV_ERROR(dev, "Failed to bind: %d\n" , ret); |
985 | goto out_pll_clk; |
986 | } |
987 | |
988 | dsi->dsi_bound = true; |
989 | |
990 | return 0; |
991 | |
992 | out_pll_clk: |
993 | clk_disable_unprepare(clk: dsi->pllref_clk); |
994 | out_pm_runtime: |
995 | pm_runtime_put(dev: dsi->dev); |
996 | if (dsi->slave) |
997 | pm_runtime_put(dev: dsi->slave->dev); |
998 | |
999 | return ret; |
1000 | } |
1001 | |
1002 | static void dw_mipi_dsi_rockchip_unbind(struct device *dev, |
1003 | struct device *master, |
1004 | void *data) |
1005 | { |
1006 | struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev); |
1007 | |
1008 | if (dsi->is_slave) |
1009 | return; |
1010 | |
1011 | dsi->dsi_bound = false; |
1012 | |
1013 | dw_mipi_dsi_unbind(dsi: dsi->dmd); |
1014 | |
1015 | clk_disable_unprepare(clk: dsi->pllref_clk); |
1016 | |
1017 | pm_runtime_put(dev: dsi->dev); |
1018 | if (dsi->slave) |
1019 | pm_runtime_put(dev: dsi->slave->dev); |
1020 | } |
1021 | |
1022 | static const struct component_ops dw_mipi_dsi_rockchip_ops = { |
1023 | .bind = dw_mipi_dsi_rockchip_bind, |
1024 | .unbind = dw_mipi_dsi_rockchip_unbind, |
1025 | }; |
1026 | |
1027 | static int dw_mipi_dsi_rockchip_host_attach(void *priv_data, |
1028 | struct mipi_dsi_device *device) |
1029 | { |
1030 | struct dw_mipi_dsi_rockchip *dsi = priv_data; |
1031 | struct device *second; |
1032 | int ret; |
1033 | |
1034 | mutex_lock(&dsi->usage_mutex); |
1035 | |
1036 | if (dsi->usage_mode != DW_DSI_USAGE_IDLE) { |
1037 | DRM_DEV_ERROR(dsi->dev, "dsi controller already in use\n" ); |
1038 | mutex_unlock(lock: &dsi->usage_mutex); |
1039 | return -EBUSY; |
1040 | } |
1041 | |
1042 | dsi->usage_mode = DW_DSI_USAGE_DSI; |
1043 | mutex_unlock(lock: &dsi->usage_mutex); |
1044 | |
1045 | ret = component_add(dsi->dev, &dw_mipi_dsi_rockchip_ops); |
1046 | if (ret) { |
1047 | DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n" , |
1048 | ret); |
1049 | goto out; |
1050 | } |
1051 | |
1052 | second = dw_mipi_dsi_rockchip_find_second(dsi); |
1053 | if (IS_ERR(ptr: second)) { |
1054 | ret = PTR_ERR(ptr: second); |
1055 | goto out; |
1056 | } |
1057 | if (second) { |
1058 | ret = component_add(second, &dw_mipi_dsi_rockchip_ops); |
1059 | if (ret) { |
1060 | DRM_DEV_ERROR(second, |
1061 | "Failed to register component: %d\n" , |
1062 | ret); |
1063 | goto out; |
1064 | } |
1065 | } |
1066 | |
1067 | return 0; |
1068 | |
1069 | out: |
1070 | mutex_lock(&dsi->usage_mutex); |
1071 | dsi->usage_mode = DW_DSI_USAGE_IDLE; |
1072 | mutex_unlock(lock: &dsi->usage_mutex); |
1073 | return ret; |
1074 | } |
1075 | |
1076 | static int dw_mipi_dsi_rockchip_host_detach(void *priv_data, |
1077 | struct mipi_dsi_device *device) |
1078 | { |
1079 | struct dw_mipi_dsi_rockchip *dsi = priv_data; |
1080 | struct device *second; |
1081 | |
1082 | second = dw_mipi_dsi_rockchip_find_second(dsi); |
1083 | if (second && !IS_ERR(ptr: second)) |
1084 | component_del(second, &dw_mipi_dsi_rockchip_ops); |
1085 | |
1086 | component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops); |
1087 | |
1088 | mutex_lock(&dsi->usage_mutex); |
1089 | dsi->usage_mode = DW_DSI_USAGE_IDLE; |
1090 | mutex_unlock(lock: &dsi->usage_mutex); |
1091 | |
1092 | return 0; |
1093 | } |
1094 | |
1095 | static const struct dw_mipi_dsi_host_ops dw_mipi_dsi_rockchip_host_ops = { |
1096 | .attach = dw_mipi_dsi_rockchip_host_attach, |
1097 | .detach = dw_mipi_dsi_rockchip_host_detach, |
1098 | }; |
1099 | |
1100 | static int dw_mipi_dsi_rockchip_dphy_bind(struct device *dev, |
1101 | struct device *master, |
1102 | void *data) |
1103 | { |
1104 | /* |
1105 | * Nothing to do when used as a dphy. |
1106 | * Just make the rest of Rockchip-DRM happy |
1107 | * by being here. |
1108 | */ |
1109 | |
1110 | return 0; |
1111 | } |
1112 | |
1113 | static void dw_mipi_dsi_rockchip_dphy_unbind(struct device *dev, |
1114 | struct device *master, |
1115 | void *data) |
1116 | { |
1117 | /* Nothing to do when used as a dphy. */ |
1118 | } |
1119 | |
1120 | static const struct component_ops dw_mipi_dsi_rockchip_dphy_ops = { |
1121 | .bind = dw_mipi_dsi_rockchip_dphy_bind, |
1122 | .unbind = dw_mipi_dsi_rockchip_dphy_unbind, |
1123 | }; |
1124 | |
1125 | static int dw_mipi_dsi_dphy_init(struct phy *phy) |
1126 | { |
1127 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1128 | int ret; |
1129 | |
1130 | mutex_lock(&dsi->usage_mutex); |
1131 | |
1132 | if (dsi->usage_mode != DW_DSI_USAGE_IDLE) { |
1133 | DRM_DEV_ERROR(dsi->dev, "dsi controller already in use\n" ); |
1134 | mutex_unlock(lock: &dsi->usage_mutex); |
1135 | return -EBUSY; |
1136 | } |
1137 | |
1138 | dsi->usage_mode = DW_DSI_USAGE_PHY; |
1139 | mutex_unlock(lock: &dsi->usage_mutex); |
1140 | |
1141 | ret = component_add(dsi->dev, &dw_mipi_dsi_rockchip_dphy_ops); |
1142 | if (ret < 0) |
1143 | goto err_graph; |
1144 | |
1145 | if (dsi->cdata->dphy_rx_init) { |
1146 | ret = clk_prepare_enable(clk: dsi->pclk); |
1147 | if (ret < 0) |
1148 | goto err_init; |
1149 | |
1150 | ret = clk_prepare_enable(clk: dsi->grf_clk); |
1151 | if (ret) { |
1152 | clk_disable_unprepare(clk: dsi->pclk); |
1153 | goto err_init; |
1154 | } |
1155 | |
1156 | ret = dsi->cdata->dphy_rx_init(phy); |
1157 | clk_disable_unprepare(clk: dsi->grf_clk); |
1158 | clk_disable_unprepare(clk: dsi->pclk); |
1159 | if (ret < 0) |
1160 | goto err_init; |
1161 | } |
1162 | |
1163 | return 0; |
1164 | |
1165 | err_init: |
1166 | component_del(dsi->dev, &dw_mipi_dsi_rockchip_dphy_ops); |
1167 | err_graph: |
1168 | mutex_lock(&dsi->usage_mutex); |
1169 | dsi->usage_mode = DW_DSI_USAGE_IDLE; |
1170 | mutex_unlock(lock: &dsi->usage_mutex); |
1171 | |
1172 | return ret; |
1173 | } |
1174 | |
1175 | static int dw_mipi_dsi_dphy_exit(struct phy *phy) |
1176 | { |
1177 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1178 | |
1179 | component_del(dsi->dev, &dw_mipi_dsi_rockchip_dphy_ops); |
1180 | |
1181 | mutex_lock(&dsi->usage_mutex); |
1182 | dsi->usage_mode = DW_DSI_USAGE_IDLE; |
1183 | mutex_unlock(lock: &dsi->usage_mutex); |
1184 | |
1185 | return 0; |
1186 | } |
1187 | |
1188 | static int dw_mipi_dsi_dphy_configure(struct phy *phy, union phy_configure_opts *opts) |
1189 | { |
1190 | struct phy_configure_opts_mipi_dphy *config = &opts->mipi_dphy; |
1191 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1192 | int ret; |
1193 | |
1194 | ret = phy_mipi_dphy_config_validate(cfg: &opts->mipi_dphy); |
1195 | if (ret) |
1196 | return ret; |
1197 | |
1198 | dsi->dphy_config = *config; |
1199 | dsi->lane_mbps = div_u64(dividend: config->hs_clk_rate, divisor: 1000 * 1000 * 1); |
1200 | |
1201 | return 0; |
1202 | } |
1203 | |
1204 | static int dw_mipi_dsi_dphy_power_on(struct phy *phy) |
1205 | { |
1206 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1207 | int i, ret; |
1208 | |
1209 | DRM_DEV_DEBUG(dsi->dev, "lanes %d - data_rate_mbps %u\n" , |
1210 | dsi->dphy_config.lanes, dsi->lane_mbps); |
1211 | |
1212 | i = max_mbps_to_parameter(max_mbps: dsi->lane_mbps); |
1213 | if (i < 0) { |
1214 | DRM_DEV_ERROR(dsi->dev, "failed to get parameter for %dmbps clock\n" , |
1215 | dsi->lane_mbps); |
1216 | return i; |
1217 | } |
1218 | |
1219 | ret = pm_runtime_resume_and_get(dev: dsi->dev); |
1220 | if (ret < 0) { |
1221 | DRM_DEV_ERROR(dsi->dev, "failed to enable device: %d\n" , ret); |
1222 | return ret; |
1223 | } |
1224 | |
1225 | ret = clk_prepare_enable(clk: dsi->pclk); |
1226 | if (ret) { |
1227 | DRM_DEV_ERROR(dsi->dev, "Failed to enable pclk: %d\n" , ret); |
1228 | goto err_pclk; |
1229 | } |
1230 | |
1231 | ret = clk_prepare_enable(clk: dsi->grf_clk); |
1232 | if (ret) { |
1233 | DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n" , ret); |
1234 | goto err_grf_clk; |
1235 | } |
1236 | |
1237 | ret = clk_prepare_enable(clk: dsi->phy_cfg_clk); |
1238 | if (ret) { |
1239 | DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk: %d\n" , ret); |
1240 | goto err_phy_cfg_clk; |
1241 | } |
1242 | |
1243 | /* do soc-variant specific init */ |
1244 | if (dsi->cdata->dphy_rx_power_on) { |
1245 | ret = dsi->cdata->dphy_rx_power_on(phy); |
1246 | if (ret < 0) { |
1247 | DRM_DEV_ERROR(dsi->dev, "hardware-specific phy bringup failed: %d\n" , ret); |
1248 | goto err_pwr_on; |
1249 | } |
1250 | } |
1251 | |
1252 | /* |
1253 | * Configure hsfreqrange according to frequency values |
1254 | * Set clock lane and hsfreqrange by lane0(test code 0x44) |
1255 | */ |
1256 | dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_CLK, test_data: 0); |
1257 | dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0, |
1258 | HSFREQRANGE_SEL(dppa_map[i].hsfreqrange)); |
1259 | dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_1, test_data: 0); |
1260 | dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_2, test_data: 0); |
1261 | dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_3, test_data: 0); |
1262 | |
1263 | /* Normal operation */ |
1264 | dw_mipi_dsi_phy_write(dsi, test_code: 0x0, test_data: 0); |
1265 | |
1266 | clk_disable_unprepare(clk: dsi->phy_cfg_clk); |
1267 | clk_disable_unprepare(clk: dsi->grf_clk); |
1268 | |
1269 | return ret; |
1270 | |
1271 | err_pwr_on: |
1272 | clk_disable_unprepare(clk: dsi->phy_cfg_clk); |
1273 | err_phy_cfg_clk: |
1274 | clk_disable_unprepare(clk: dsi->grf_clk); |
1275 | err_grf_clk: |
1276 | clk_disable_unprepare(clk: dsi->pclk); |
1277 | err_pclk: |
1278 | pm_runtime_put(dev: dsi->dev); |
1279 | return ret; |
1280 | } |
1281 | |
1282 | static int dw_mipi_dsi_dphy_power_off(struct phy *phy) |
1283 | { |
1284 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1285 | int ret; |
1286 | |
1287 | ret = clk_prepare_enable(clk: dsi->grf_clk); |
1288 | if (ret) { |
1289 | DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n" , ret); |
1290 | return ret; |
1291 | } |
1292 | |
1293 | if (dsi->cdata->dphy_rx_power_off) { |
1294 | ret = dsi->cdata->dphy_rx_power_off(phy); |
1295 | if (ret < 0) |
1296 | DRM_DEV_ERROR(dsi->dev, "hardware-specific phy shutdown failed: %d\n" , ret); |
1297 | } |
1298 | |
1299 | clk_disable_unprepare(clk: dsi->grf_clk); |
1300 | clk_disable_unprepare(clk: dsi->pclk); |
1301 | |
1302 | pm_runtime_put(dev: dsi->dev); |
1303 | |
1304 | return ret; |
1305 | } |
1306 | |
1307 | static const struct phy_ops dw_mipi_dsi_dphy_ops = { |
1308 | .configure = dw_mipi_dsi_dphy_configure, |
1309 | .power_on = dw_mipi_dsi_dphy_power_on, |
1310 | .power_off = dw_mipi_dsi_dphy_power_off, |
1311 | .init = dw_mipi_dsi_dphy_init, |
1312 | .exit = dw_mipi_dsi_dphy_exit, |
1313 | }; |
1314 | |
1315 | static int __maybe_unused dw_mipi_dsi_rockchip_resume(struct device *dev) |
1316 | { |
1317 | struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev); |
1318 | int ret; |
1319 | |
1320 | /* |
1321 | * Re-configure DSI state, if we were previously initialized. We need |
1322 | * to do this before rockchip_drm_drv tries to re-enable() any panels. |
1323 | */ |
1324 | if (dsi->dsi_bound) { |
1325 | ret = clk_prepare_enable(clk: dsi->grf_clk); |
1326 | if (ret) { |
1327 | DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n" , ret); |
1328 | return ret; |
1329 | } |
1330 | |
1331 | dw_mipi_dsi_rockchip_config(dsi); |
1332 | if (dsi->slave) |
1333 | dw_mipi_dsi_rockchip_config(dsi: dsi->slave); |
1334 | |
1335 | clk_disable_unprepare(clk: dsi->grf_clk); |
1336 | } |
1337 | |
1338 | return 0; |
1339 | } |
1340 | |
1341 | static const struct dev_pm_ops dw_mipi_dsi_rockchip_pm_ops = { |
1342 | SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, dw_mipi_dsi_rockchip_resume) |
1343 | }; |
1344 | |
1345 | static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) |
1346 | { |
1347 | struct device *dev = &pdev->dev; |
1348 | struct device_node *np = dev->of_node; |
1349 | struct dw_mipi_dsi_rockchip *dsi; |
1350 | struct phy_provider *phy_provider; |
1351 | struct resource *res; |
1352 | const struct rockchip_dw_dsi_chip_data *cdata = |
1353 | of_device_get_match_data(dev); |
1354 | int ret, i; |
1355 | |
1356 | dsi = devm_kzalloc(dev, size: sizeof(*dsi), GFP_KERNEL); |
1357 | if (!dsi) |
1358 | return -ENOMEM; |
1359 | |
1360 | dsi->base = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &res); |
1361 | if (IS_ERR(ptr: dsi->base)) { |
1362 | DRM_DEV_ERROR(dev, "Unable to get dsi registers\n" ); |
1363 | return PTR_ERR(ptr: dsi->base); |
1364 | } |
1365 | |
1366 | i = 0; |
1367 | while (cdata[i].reg) { |
1368 | if (cdata[i].reg == res->start) { |
1369 | dsi->cdata = &cdata[i]; |
1370 | break; |
1371 | } |
1372 | |
1373 | i++; |
1374 | } |
1375 | |
1376 | if (!dsi->cdata) { |
1377 | DRM_DEV_ERROR(dev, "no dsi-config for %s node\n" , np->name); |
1378 | return -EINVAL; |
1379 | } |
1380 | |
1381 | /* try to get a possible external dphy */ |
1382 | dsi->phy = devm_phy_optional_get(dev, string: "dphy" ); |
1383 | if (IS_ERR(ptr: dsi->phy)) { |
1384 | ret = PTR_ERR(ptr: dsi->phy); |
1385 | DRM_DEV_ERROR(dev, "failed to get mipi dphy: %d\n" , ret); |
1386 | return ret; |
1387 | } |
1388 | |
1389 | dsi->pclk = devm_clk_get(dev, id: "pclk" ); |
1390 | if (IS_ERR(ptr: dsi->pclk)) { |
1391 | ret = PTR_ERR(ptr: dsi->pclk); |
1392 | DRM_DEV_ERROR(dev, "Unable to get pclk: %d\n" , ret); |
1393 | return ret; |
1394 | } |
1395 | |
1396 | dsi->pllref_clk = devm_clk_get(dev, id: "ref" ); |
1397 | if (IS_ERR(ptr: dsi->pllref_clk)) { |
1398 | if (dsi->phy) { |
1399 | /* |
1400 | * if external phy is present, pll will be |
1401 | * generated there. |
1402 | */ |
1403 | dsi->pllref_clk = NULL; |
1404 | } else { |
1405 | ret = PTR_ERR(ptr: dsi->pllref_clk); |
1406 | DRM_DEV_ERROR(dev, |
1407 | "Unable to get pll reference clock: %d\n" , |
1408 | ret); |
1409 | return ret; |
1410 | } |
1411 | } |
1412 | |
1413 | if (dsi->cdata->flags & DW_MIPI_NEEDS_PHY_CFG_CLK) { |
1414 | dsi->phy_cfg_clk = devm_clk_get(dev, id: "phy_cfg" ); |
1415 | if (IS_ERR(ptr: dsi->phy_cfg_clk)) { |
1416 | ret = PTR_ERR(ptr: dsi->phy_cfg_clk); |
1417 | DRM_DEV_ERROR(dev, |
1418 | "Unable to get phy_cfg_clk: %d\n" , ret); |
1419 | return ret; |
1420 | } |
1421 | } |
1422 | |
1423 | if (dsi->cdata->flags & DW_MIPI_NEEDS_GRF_CLK) { |
1424 | dsi->grf_clk = devm_clk_get(dev, id: "grf" ); |
1425 | if (IS_ERR(ptr: dsi->grf_clk)) { |
1426 | ret = PTR_ERR(ptr: dsi->grf_clk); |
1427 | DRM_DEV_ERROR(dev, "Unable to get grf_clk: %d\n" , ret); |
1428 | return ret; |
1429 | } |
1430 | } |
1431 | |
1432 | dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, property: "rockchip,grf" ); |
1433 | if (IS_ERR(ptr: dsi->grf_regmap)) { |
1434 | DRM_DEV_ERROR(dev, "Unable to get rockchip,grf\n" ); |
1435 | return PTR_ERR(ptr: dsi->grf_regmap); |
1436 | } |
1437 | |
1438 | dsi->dev = dev; |
1439 | dsi->pdata.base = dsi->base; |
1440 | dsi->pdata.max_data_lanes = dsi->cdata->max_data_lanes; |
1441 | dsi->pdata.phy_ops = &dw_mipi_dsi_rockchip_phy_ops; |
1442 | dsi->pdata.host_ops = &dw_mipi_dsi_rockchip_host_ops; |
1443 | dsi->pdata.priv_data = dsi; |
1444 | platform_set_drvdata(pdev, data: dsi); |
1445 | |
1446 | mutex_init(&dsi->usage_mutex); |
1447 | |
1448 | dsi->dphy = devm_phy_create(dev, NULL, ops: &dw_mipi_dsi_dphy_ops); |
1449 | if (IS_ERR(ptr: dsi->dphy)) { |
1450 | DRM_DEV_ERROR(&pdev->dev, "failed to create PHY\n" ); |
1451 | return PTR_ERR(ptr: dsi->dphy); |
1452 | } |
1453 | |
1454 | phy_set_drvdata(phy: dsi->dphy, data: dsi); |
1455 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); |
1456 | if (IS_ERR(ptr: phy_provider)) |
1457 | return PTR_ERR(ptr: phy_provider); |
1458 | |
1459 | dsi->dmd = dw_mipi_dsi_probe(pdev, plat_data: &dsi->pdata); |
1460 | if (IS_ERR(ptr: dsi->dmd)) { |
1461 | ret = PTR_ERR(ptr: dsi->dmd); |
1462 | if (ret != -EPROBE_DEFER) |
1463 | DRM_DEV_ERROR(dev, |
1464 | "Failed to probe dw_mipi_dsi: %d\n" , ret); |
1465 | return ret; |
1466 | } |
1467 | |
1468 | return 0; |
1469 | } |
1470 | |
1471 | static void dw_mipi_dsi_rockchip_remove(struct platform_device *pdev) |
1472 | { |
1473 | struct dw_mipi_dsi_rockchip *dsi = platform_get_drvdata(pdev); |
1474 | |
1475 | dw_mipi_dsi_remove(dsi: dsi->dmd); |
1476 | } |
1477 | |
1478 | static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = { |
1479 | { |
1480 | .reg = 0xff450000, |
1481 | .lcdsel_grf_reg = PX30_GRF_PD_VO_CON1, |
1482 | .lcdsel_big = HIWORD_UPDATE(0, PX30_DSI_LCDC_SEL), |
1483 | .lcdsel_lit = HIWORD_UPDATE(PX30_DSI_LCDC_SEL, |
1484 | PX30_DSI_LCDC_SEL), |
1485 | |
1486 | .lanecfg1_grf_reg = PX30_GRF_PD_VO_CON1, |
1487 | .lanecfg1 = HIWORD_UPDATE(0, PX30_DSI_TURNDISABLE | |
1488 | PX30_DSI_FORCERXMODE | |
1489 | PX30_DSI_FORCETXSTOPMODE), |
1490 | |
1491 | .max_data_lanes = 4, |
1492 | }, |
1493 | { /* sentinel */ } |
1494 | }; |
1495 | |
1496 | static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = { |
1497 | { |
1498 | .reg = 0xff960000, |
1499 | .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, |
1500 | .lcdsel_big = HIWORD_UPDATE(0, RK3288_DSI0_LCDC_SEL), |
1501 | .lcdsel_lit = HIWORD_UPDATE(RK3288_DSI0_LCDC_SEL, RK3288_DSI0_LCDC_SEL), |
1502 | |
1503 | .max_data_lanes = 4, |
1504 | }, |
1505 | { |
1506 | .reg = 0xff964000, |
1507 | .lcdsel_grf_reg = RK3288_GRF_SOC_CON6, |
1508 | .lcdsel_big = HIWORD_UPDATE(0, RK3288_DSI1_LCDC_SEL), |
1509 | .lcdsel_lit = HIWORD_UPDATE(RK3288_DSI1_LCDC_SEL, RK3288_DSI1_LCDC_SEL), |
1510 | |
1511 | .max_data_lanes = 4, |
1512 | }, |
1513 | { /* sentinel */ } |
1514 | }; |
1515 | |
1516 | static int rk3399_dphy_tx1rx1_init(struct phy *phy) |
1517 | { |
1518 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1519 | |
1520 | /* |
1521 | * Set TX1RX1 source to isp1. |
1522 | * Assume ISP0 is supplied by the RX0 dphy. |
1523 | */ |
1524 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON24, |
1525 | HIWORD_UPDATE(0, RK3399_TXRX_SRC_SEL_ISP0)); |
1526 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON24, |
1527 | HIWORD_UPDATE(0, RK3399_TXRX_MASTERSLAVEZ)); |
1528 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON24, |
1529 | HIWORD_UPDATE(0, RK3399_TXRX_BASEDIR)); |
1530 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON23, |
1531 | HIWORD_UPDATE(0, RK3399_DSI1_ENABLE)); |
1532 | |
1533 | return 0; |
1534 | } |
1535 | |
1536 | static int rk3399_dphy_tx1rx1_power_on(struct phy *phy) |
1537 | { |
1538 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1539 | |
1540 | /* tester reset pulse */ |
1541 | dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_TESTCLR); |
1542 | usleep_range(min: 100, max: 150); |
1543 | |
1544 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON24, |
1545 | HIWORD_UPDATE(0, RK3399_TXRX_MASTERSLAVEZ)); |
1546 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON24, |
1547 | HIWORD_UPDATE(RK3399_TXRX_BASEDIR, RK3399_TXRX_BASEDIR)); |
1548 | |
1549 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON23, |
1550 | HIWORD_UPDATE(0, RK3399_DSI1_FORCERXMODE)); |
1551 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON23, |
1552 | HIWORD_UPDATE(0, RK3399_DSI1_FORCETXSTOPMODE)); |
1553 | |
1554 | /* Disable lane turn around, which is ignored in receive mode */ |
1555 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON24, |
1556 | HIWORD_UPDATE(0, RK3399_TXRX_TURNREQUEST)); |
1557 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON23, |
1558 | HIWORD_UPDATE(RK3399_DSI1_TURNDISABLE, |
1559 | RK3399_DSI1_TURNDISABLE)); |
1560 | usleep_range(min: 100, max: 150); |
1561 | |
1562 | dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR); |
1563 | usleep_range(min: 100, max: 150); |
1564 | |
1565 | /* Enable dphy lanes */ |
1566 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON23, |
1567 | HIWORD_UPDATE(GENMASK(dsi->dphy_config.lanes - 1, 0), |
1568 | RK3399_DSI1_ENABLE)); |
1569 | |
1570 | usleep_range(min: 100, max: 150); |
1571 | |
1572 | return 0; |
1573 | } |
1574 | |
1575 | static int rk3399_dphy_tx1rx1_power_off(struct phy *phy) |
1576 | { |
1577 | struct dw_mipi_dsi_rockchip *dsi = phy_get_drvdata(phy); |
1578 | |
1579 | regmap_write(map: dsi->grf_regmap, RK3399_GRF_SOC_CON23, |
1580 | HIWORD_UPDATE(0, RK3399_DSI1_ENABLE)); |
1581 | |
1582 | return 0; |
1583 | } |
1584 | |
1585 | static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = { |
1586 | { |
1587 | .reg = 0xff960000, |
1588 | .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, |
1589 | .lcdsel_big = HIWORD_UPDATE(0, RK3399_DSI0_LCDC_SEL), |
1590 | .lcdsel_lit = HIWORD_UPDATE(RK3399_DSI0_LCDC_SEL, |
1591 | RK3399_DSI0_LCDC_SEL), |
1592 | |
1593 | .lanecfg1_grf_reg = RK3399_GRF_SOC_CON22, |
1594 | .lanecfg1 = HIWORD_UPDATE(0, RK3399_DSI0_TURNREQUEST | |
1595 | RK3399_DSI0_TURNDISABLE | |
1596 | RK3399_DSI0_FORCETXSTOPMODE | |
1597 | RK3399_DSI0_FORCERXMODE), |
1598 | |
1599 | .flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK, |
1600 | .max_data_lanes = 4, |
1601 | }, |
1602 | { |
1603 | .reg = 0xff968000, |
1604 | .lcdsel_grf_reg = RK3399_GRF_SOC_CON20, |
1605 | .lcdsel_big = HIWORD_UPDATE(0, RK3399_DSI1_LCDC_SEL), |
1606 | .lcdsel_lit = HIWORD_UPDATE(RK3399_DSI1_LCDC_SEL, |
1607 | RK3399_DSI1_LCDC_SEL), |
1608 | |
1609 | .lanecfg1_grf_reg = RK3399_GRF_SOC_CON23, |
1610 | .lanecfg1 = HIWORD_UPDATE(0, RK3399_DSI1_TURNDISABLE | |
1611 | RK3399_DSI1_FORCETXSTOPMODE | |
1612 | RK3399_DSI1_FORCERXMODE | |
1613 | RK3399_DSI1_ENABLE), |
1614 | |
1615 | .lanecfg2_grf_reg = RK3399_GRF_SOC_CON24, |
1616 | .lanecfg2 = HIWORD_UPDATE(RK3399_TXRX_MASTERSLAVEZ | |
1617 | RK3399_TXRX_ENABLECLK, |
1618 | RK3399_TXRX_MASTERSLAVEZ | |
1619 | RK3399_TXRX_ENABLECLK | |
1620 | RK3399_TXRX_BASEDIR), |
1621 | |
1622 | .enable_grf_reg = RK3399_GRF_SOC_CON23, |
1623 | .enable = HIWORD_UPDATE(RK3399_DSI1_ENABLE, RK3399_DSI1_ENABLE), |
1624 | |
1625 | .flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK, |
1626 | .max_data_lanes = 4, |
1627 | |
1628 | .dphy_rx_init = rk3399_dphy_tx1rx1_init, |
1629 | .dphy_rx_power_on = rk3399_dphy_tx1rx1_power_on, |
1630 | .dphy_rx_power_off = rk3399_dphy_tx1rx1_power_off, |
1631 | }, |
1632 | { /* sentinel */ } |
1633 | }; |
1634 | |
1635 | static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = { |
1636 | { |
1637 | .reg = 0xfe060000, |
1638 | .lanecfg1_grf_reg = RK3568_GRF_VO_CON2, |
1639 | .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI0_SKEWCALHS | |
1640 | RK3568_DSI0_FORCETXSTOPMODE | |
1641 | RK3568_DSI0_TURNDISABLE | |
1642 | RK3568_DSI0_FORCERXMODE), |
1643 | .max_data_lanes = 4, |
1644 | }, |
1645 | { |
1646 | .reg = 0xfe070000, |
1647 | .lanecfg1_grf_reg = RK3568_GRF_VO_CON3, |
1648 | .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI1_SKEWCALHS | |
1649 | RK3568_DSI1_FORCETXSTOPMODE | |
1650 | RK3568_DSI1_TURNDISABLE | |
1651 | RK3568_DSI1_FORCERXMODE), |
1652 | .max_data_lanes = 4, |
1653 | }, |
1654 | { /* sentinel */ } |
1655 | }; |
1656 | |
1657 | static const struct rockchip_dw_dsi_chip_data rv1126_chip_data[] = { |
1658 | { |
1659 | .reg = 0xffb30000, |
1660 | .lanecfg1_grf_reg = RV1126_GRF_DSIPHY_CON, |
1661 | .lanecfg1 = HIWORD_UPDATE(0, RV1126_DSI_TURNDISABLE | |
1662 | RV1126_DSI_FORCERXMODE | |
1663 | RV1126_DSI_FORCETXSTOPMODE), |
1664 | .max_data_lanes = 4, |
1665 | }, |
1666 | { /* sentinel */ } |
1667 | }; |
1668 | |
1669 | static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = { |
1670 | { |
1671 | .compatible = "rockchip,px30-mipi-dsi" , |
1672 | .data = &px30_chip_data, |
1673 | }, { |
1674 | .compatible = "rockchip,rk3288-mipi-dsi" , |
1675 | .data = &rk3288_chip_data, |
1676 | }, { |
1677 | .compatible = "rockchip,rk3399-mipi-dsi" , |
1678 | .data = &rk3399_chip_data, |
1679 | }, { |
1680 | .compatible = "rockchip,rk3568-mipi-dsi" , |
1681 | .data = &rk3568_chip_data, |
1682 | }, { |
1683 | .compatible = "rockchip,rv1126-mipi-dsi" , |
1684 | .data = &rv1126_chip_data, |
1685 | }, |
1686 | { /* sentinel */ } |
1687 | }; |
1688 | MODULE_DEVICE_TABLE(of, dw_mipi_dsi_rockchip_dt_ids); |
1689 | |
1690 | struct platform_driver dw_mipi_dsi_rockchip_driver = { |
1691 | .probe = dw_mipi_dsi_rockchip_probe, |
1692 | .remove_new = dw_mipi_dsi_rockchip_remove, |
1693 | .driver = { |
1694 | .of_match_table = dw_mipi_dsi_rockchip_dt_ids, |
1695 | .pm = &dw_mipi_dsi_rockchip_pm_ops, |
1696 | .name = "dw-mipi-dsi-rockchip" , |
1697 | /* |
1698 | * For dual-DSI display, one DSI pokes at the other DSI's |
1699 | * drvdata in dw_mipi_dsi_rockchip_find_second(). This is not |
1700 | * safe for asynchronous probe. |
1701 | */ |
1702 | .probe_type = PROBE_FORCE_SYNCHRONOUS, |
1703 | }, |
1704 | }; |
1705 | |