blob: d8c47ee3cad3774777e03c5c157d222b0b79b49a [file] [log] [blame]
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001// 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
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02009#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>
Heiko Stuebner94bedc42019-12-09 15:31:28 +010015#include <linux/phy/phy.h>
Nickey Yang2d4f7bd2018-10-01 14:38:43 +020016#include <linux/pm_runtime.h>
17#include <linux/regmap.h>
Sam Ravnborgc2156cc2019-07-16 08:42:19 +020018
Nickey Yang2d4f7bd2018-10-01 14:38:43 +020019#include <video/mipi_display.h>
20
Sam Ravnborgc2156cc2019-07-16 08:42:19 +020021#include <drm/bridge/dw_mipi_dsi.h>
22#include <drm/drm_mipi_dsi.h>
23#include <drm/drm_of.h>
Thomas Zimmermann0dbd7352020-03-05 16:59:40 +010024#include <drm/drm_simple_kms_helper.h>
Sam Ravnborgc2156cc2019-07-16 08:42:19 +020025
Nickey Yang2d4f7bd2018-10-01 14:38:43 +020026#include "rockchip_drm_drv.h"
27#include "rockchip_drm_vop.h"
28
29#define DSI_PHY_RSTZ 0xa0
30#define PHY_DISFORCEPLL 0
31#define PHY_ENFORCEPLL BIT(3)
32#define PHY_DISABLECLK 0
33#define PHY_ENABLECLK BIT(2)
34#define PHY_RSTZ 0
35#define PHY_UNRSTZ BIT(1)
36#define PHY_SHUTDOWNZ 0
37#define PHY_UNSHUTDOWNZ BIT(0)
38
39#define DSI_PHY_IF_CFG 0xa4
40#define N_LANES(n) ((((n) - 1) & 0x3) << 0)
41#define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8)
42
43#define DSI_PHY_STATUS 0xb0
44#define LOCK BIT(0)
45#define STOP_STATE_CLK_LANE BIT(2)
46
47#define DSI_PHY_TST_CTRL0 0xb4
48#define PHY_TESTCLK BIT(1)
49#define PHY_UNTESTCLK 0
50#define PHY_TESTCLR BIT(0)
51#define PHY_UNTESTCLR 0
52
53#define DSI_PHY_TST_CTRL1 0xb8
54#define PHY_TESTEN BIT(16)
55#define PHY_UNTESTEN 0
56#define PHY_TESTDOUT(n) (((n) & 0xff) << 8)
57#define PHY_TESTDIN(n) (((n) & 0xff) << 0)
58
59#define DSI_INT_ST0 0xbc
60#define DSI_INT_ST1 0xc0
61#define DSI_INT_MSK0 0xc4
62#define DSI_INT_MSK1 0xc8
63
64#define PHY_STATUS_TIMEOUT_US 10000
65#define CMD_PKT_STATUS_TIMEOUT_US 20000
66
67#define BYPASS_VCO_RANGE BIT(7)
68#define VCO_RANGE_CON_SEL(val) (((val) & 0x7) << 3)
69#define VCO_IN_CAP_CON_DEFAULT (0x0 << 1)
70#define VCO_IN_CAP_CON_LOW (0x1 << 1)
71#define VCO_IN_CAP_CON_HIGH (0x2 << 1)
72#define REF_BIAS_CUR_SEL BIT(0)
73
74#define CP_CURRENT_3UA 0x1
75#define CP_CURRENT_4_5UA 0x2
76#define CP_CURRENT_7_5UA 0x6
77#define CP_CURRENT_6UA 0x9
78#define CP_CURRENT_12UA 0xb
79#define CP_CURRENT_SEL(val) ((val) & 0xf)
80#define CP_PROGRAM_EN BIT(7)
81
82#define LPF_RESISTORS_15_5KOHM 0x1
83#define LPF_RESISTORS_13KOHM 0x2
84#define LPF_RESISTORS_11_5KOHM 0x4
85#define LPF_RESISTORS_10_5KOHM 0x8
86#define LPF_RESISTORS_8KOHM 0x10
87#define LPF_PROGRAM_EN BIT(6)
88#define LPF_RESISTORS_SEL(val) ((val) & 0x3f)
89
90#define HSFREQRANGE_SEL(val) (((val) & 0x3f) << 1)
91
92#define INPUT_DIVIDER(val) (((val) - 1) & 0x7f)
93#define LOW_PROGRAM_EN 0
94#define HIGH_PROGRAM_EN BIT(7)
95#define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f)
96#define LOOP_DIV_HIGH_SEL(val) ((((val) - 1) >> 5) & 0xf)
97#define PLL_LOOP_DIV_EN BIT(5)
98#define PLL_INPUT_DIV_EN BIT(4)
99
100#define POWER_CONTROL BIT(6)
101#define INTERNAL_REG_CURRENT BIT(3)
102#define BIAS_BLOCK_ON BIT(2)
103#define BANDGAP_ON BIT(0)
104
105#define TER_RESISTOR_HIGH BIT(7)
106#define TER_RESISTOR_LOW 0
107#define LEVEL_SHIFTERS_ON BIT(6)
108#define TER_CAL_DONE BIT(5)
109#define SETRD_MAX (0x7 << 2)
110#define POWER_MANAGE BIT(1)
111#define TER_RESISTORS_ON BIT(0)
112
113#define BIASEXTR_SEL(val) ((val) & 0x7)
114#define BANDGAP_SEL(val) ((val) & 0x7)
115#define TLP_PROGRAM_EN BIT(7)
116#define THS_PRE_PROGRAM_EN BIT(7)
117#define THS_ZERO_PROGRAM_EN BIT(6)
118
119#define PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL 0x10
120#define PLL_CP_CONTROL_PLL_LOCK_BYPASS 0x11
121#define PLL_LPF_AND_CP_CONTROL 0x12
122#define PLL_INPUT_DIVIDER_RATIO 0x17
123#define PLL_LOOP_DIVIDER_RATIO 0x18
124#define PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL 0x19
125#define BANDGAP_AND_BIAS_CONTROL 0x20
126#define TERMINATION_RESISTER_CONTROL 0x21
127#define AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY 0x22
128#define HS_RX_CONTROL_OF_LANE_0 0x44
129#define HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL 0x60
130#define HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL 0x61
131#define HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL 0x62
132#define HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL 0x63
133#define HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL 0x64
134#define HS_TX_CLOCK_LANE_POST_TIME_CONTROL 0x65
135#define HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL 0x70
136#define HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL 0x71
137#define HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL 0x72
138#define HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL 0x73
139#define HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL 0x74
140
141#define DW_MIPI_NEEDS_PHY_CFG_CLK BIT(0)
142#define DW_MIPI_NEEDS_GRF_CLK BIT(1)
143
Heiko Stuebner49a37dc2019-12-09 15:31:30 +0100144#define PX30_GRF_PD_VO_CON1 0x0438
145#define PX30_DSI_FORCETXSTOPMODE (0xf << 7)
146#define PX30_DSI_FORCERXMODE BIT(6)
147#define PX30_DSI_TURNDISABLE BIT(5)
148#define PX30_DSI_LCDC_SEL BIT(0)
149
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200150#define RK3288_GRF_SOC_CON6 0x025c
151#define RK3288_DSI0_LCDC_SEL BIT(6)
152#define RK3288_DSI1_LCDC_SEL BIT(9)
153
154#define RK3399_GRF_SOC_CON20 0x6250
155#define RK3399_DSI0_LCDC_SEL BIT(0)
156#define RK3399_DSI1_LCDC_SEL BIT(4)
157
158#define RK3399_GRF_SOC_CON22 0x6258
159#define RK3399_DSI0_TURNREQUEST (0xf << 12)
160#define RK3399_DSI0_TURNDISABLE (0xf << 8)
161#define RK3399_DSI0_FORCETXSTOPMODE (0xf << 4)
162#define RK3399_DSI0_FORCERXMODE (0xf << 0)
163
164#define RK3399_GRF_SOC_CON23 0x625c
165#define RK3399_DSI1_TURNDISABLE (0xf << 12)
166#define RK3399_DSI1_FORCETXSTOPMODE (0xf << 8)
167#define RK3399_DSI1_FORCERXMODE (0xf << 4)
168#define RK3399_DSI1_ENABLE (0xf << 0)
169
170#define RK3399_GRF_SOC_CON24 0x6260
171#define RK3399_TXRX_MASTERSLAVEZ BIT(7)
172#define RK3399_TXRX_ENABLECLK BIT(6)
173#define RK3399_TXRX_BASEDIR BIT(5)
174
175#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
176
177#define to_dsi(nm) container_of(nm, struct dw_mipi_dsi_rockchip, nm)
178
179enum {
180 BANDGAP_97_07,
181 BANDGAP_98_05,
182 BANDGAP_99_02,
183 BANDGAP_100_00,
184 BANDGAP_93_17,
185 BANDGAP_94_15,
186 BANDGAP_95_12,
187 BANDGAP_96_10,
188};
189
190enum {
191 BIASEXTR_87_1,
192 BIASEXTR_91_5,
193 BIASEXTR_95_9,
194 BIASEXTR_100,
195 BIASEXTR_105_94,
196 BIASEXTR_111_88,
197 BIASEXTR_118_8,
198 BIASEXTR_127_7,
199};
200
201struct rockchip_dw_dsi_chip_data {
202 u32 reg;
203
204 u32 lcdsel_grf_reg;
205 u32 lcdsel_big;
206 u32 lcdsel_lit;
207
208 u32 enable_grf_reg;
209 u32 enable;
210
211 u32 lanecfg1_grf_reg;
212 u32 lanecfg1;
213 u32 lanecfg2_grf_reg;
214 u32 lanecfg2;
215
216 unsigned int flags;
217 unsigned int max_data_lanes;
218};
219
220struct dw_mipi_dsi_rockchip {
221 struct device *dev;
222 struct drm_encoder encoder;
223 void __iomem *base;
224
225 struct regmap *grf_regmap;
226 struct clk *pllref_clk;
227 struct clk *grf_clk;
228 struct clk *phy_cfg_clk;
229
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200230 /* dual-channel */
231 bool is_slave;
232 struct dw_mipi_dsi_rockchip *slave;
233
Heiko Stuebner94bedc42019-12-09 15:31:28 +0100234 /* optional external dphy */
235 struct phy *phy;
236 union phy_configure_opts phy_opts;
237
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200238 unsigned int lane_mbps; /* per lane */
239 u16 input_div;
240 u16 feedback_div;
241 u32 format;
242
243 struct dw_mipi_dsi *dmd;
244 const struct rockchip_dw_dsi_chip_data *cdata;
245 struct dw_mipi_dsi_plat_data pdata;
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200246 int devcnt;
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200247};
248
249struct dphy_pll_parameter_map {
250 unsigned int max_mbps;
251 u8 hsfreqrange;
252 u8 icpctrl;
253 u8 lpfctrl;
254};
255
256/* The table is based on 27MHz DPHY pll reference clock. */
257static const struct dphy_pll_parameter_map dppa_map[] = {
258 { 89, 0x00, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM },
259 { 99, 0x10, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM },
260 { 109, 0x20, CP_CURRENT_3UA, LPF_RESISTORS_13KOHM },
261 { 129, 0x01, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
262 { 139, 0x11, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
263 { 149, 0x21, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
264 { 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM },
265 { 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM },
266 { 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM },
267 { 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM },
268 { 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM },
269 { 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM },
270 { 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM },
271 { 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM },
272 { 329, 0x05, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
273 { 359, 0x15, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
274 { 399, 0x25, CP_CURRENT_3UA, LPF_RESISTORS_15_5KOHM },
275 { 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
276 { 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
277 { 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM },
278 { 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM },
279 { 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
280 { 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
281 { 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
282 { 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
283 { 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
284 { 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM },
285 { 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
286 { 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
287 {1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
288 {1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM },
289 {1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
290 {1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
291 {1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
292 {1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
293 {1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
294 {1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
295 {1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM },
296 {1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM }
297};
298
299static int max_mbps_to_parameter(unsigned int max_mbps)
300{
301 int i;
302
303 for (i = 0; i < ARRAY_SIZE(dppa_map); i++)
304 if (dppa_map[i].max_mbps >= max_mbps)
305 return i;
306
307 return -EINVAL;
308}
309
310static inline void dsi_write(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 val)
311{
312 writel(val, dsi->base + reg);
313}
314
315static inline u32 dsi_read(struct dw_mipi_dsi_rockchip *dsi, u32 reg)
316{
317 return readl(dsi->base + reg);
318}
319
320static inline void dsi_set(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 mask)
321{
322 dsi_write(dsi, reg, dsi_read(dsi, reg) | mask);
323}
324
325static inline void dsi_update_bits(struct dw_mipi_dsi_rockchip *dsi, u32 reg,
326 u32 mask, u32 val)
327{
328 dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
329}
330
331static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi_rockchip *dsi,
332 u8 test_code,
333 u8 test_data)
334{
335 /*
336 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
337 * is latched internally as the current test code. Test data is
338 * programmed internally by rising edge on TESTCLK.
339 */
340 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR);
341
342 dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN | PHY_TESTDOUT(0) |
343 PHY_TESTDIN(test_code));
344
345 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLK | PHY_UNTESTCLR);
346
347 dsi_write(dsi, DSI_PHY_TST_CTRL1, PHY_UNTESTEN | PHY_TESTDOUT(0) |
348 PHY_TESTDIN(test_data));
349
350 dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR);
351}
352
Lee Jones6fbd4122020-11-16 17:40:54 +0000353/*
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200354 * ns2bc - Nanoseconds to byte clock cycles
355 */
356static inline unsigned int ns2bc(struct dw_mipi_dsi_rockchip *dsi, int ns)
357{
358 return DIV_ROUND_UP(ns * dsi->lane_mbps / 8, 1000);
359}
360
Lee Jones6fbd4122020-11-16 17:40:54 +0000361/*
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200362 * ns2ui - Nanoseconds to UI time periods
363 */
364static inline unsigned int ns2ui(struct dw_mipi_dsi_rockchip *dsi, int ns)
365{
366 return DIV_ROUND_UP(ns * dsi->lane_mbps, 1000);
367}
368
369static int dw_mipi_dsi_phy_init(void *priv_data)
370{
371 struct dw_mipi_dsi_rockchip *dsi = priv_data;
372 int ret, i, vco;
373
Heiko Stuebner94bedc42019-12-09 15:31:28 +0100374 if (dsi->phy)
375 return 0;
376
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200377 /*
378 * Get vco from frequency(lane_mbps)
379 * vco frequency table
380 * 000 - between 80 and 200 MHz
381 * 001 - between 200 and 300 MHz
382 * 010 - between 300 and 500 MHz
383 * 011 - between 500 and 700 MHz
384 * 100 - between 700 and 900 MHz
385 * 101 - between 900 and 1100 MHz
386 * 110 - between 1100 and 1300 MHz
387 * 111 - between 1300 and 1500 MHz
388 */
389 vco = (dsi->lane_mbps < 200) ? 0 : (dsi->lane_mbps + 100) / 200;
390
391 i = max_mbps_to_parameter(dsi->lane_mbps);
392 if (i < 0) {
393 DRM_DEV_ERROR(dsi->dev,
394 "failed to get parameter for %dmbps clock\n",
395 dsi->lane_mbps);
396 return i;
397 }
398
399 ret = clk_prepare_enable(dsi->phy_cfg_clk);
400 if (ret) {
401 DRM_DEV_ERROR(dsi->dev, "Failed to enable phy_cfg_clk\n");
402 return ret;
403 }
404
405 dw_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
406 BYPASS_VCO_RANGE |
407 VCO_RANGE_CON_SEL(vco) |
408 VCO_IN_CAP_CON_LOW |
409 REF_BIAS_CUR_SEL);
410
411 dw_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS,
412 CP_CURRENT_SEL(dppa_map[i].icpctrl));
413 dw_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL,
414 CP_PROGRAM_EN | LPF_PROGRAM_EN |
415 LPF_RESISTORS_SEL(dppa_map[i].lpfctrl));
416
417 dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0,
418 HSFREQRANGE_SEL(dppa_map[i].hsfreqrange));
419
420 dw_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO,
421 INPUT_DIVIDER(dsi->input_div));
422 dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
423 LOOP_DIV_LOW_SEL(dsi->feedback_div) |
424 LOW_PROGRAM_EN);
425 /*
426 * We need set PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL immediately
427 * to make the configured LSB effective according to IP simulation
428 * and lab test results.
429 * Only in this way can we get correct mipi phy pll frequency.
430 */
431 dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
432 PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
433 dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
434 LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
435 HIGH_PROGRAM_EN);
436 dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
437 PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
438
439 dw_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
440 LOW_PROGRAM_EN | BIASEXTR_SEL(BIASEXTR_127_7));
441 dw_mipi_dsi_phy_write(dsi, AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY,
442 HIGH_PROGRAM_EN | BANDGAP_SEL(BANDGAP_96_10));
443
444 dw_mipi_dsi_phy_write(dsi, BANDGAP_AND_BIAS_CONTROL,
445 POWER_CONTROL | INTERNAL_REG_CURRENT |
446 BIAS_BLOCK_ON | BANDGAP_ON);
447
448 dw_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
449 TER_RESISTOR_LOW | TER_CAL_DONE |
450 SETRD_MAX | TER_RESISTORS_ON);
451 dw_mipi_dsi_phy_write(dsi, TERMINATION_RESISTER_CONTROL,
452 TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
453 SETRD_MAX | POWER_MANAGE |
454 TER_RESISTORS_ON);
455
456 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL,
457 TLP_PROGRAM_EN | ns2bc(dsi, 500));
458 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL,
459 THS_PRE_PROGRAM_EN | ns2ui(dsi, 40));
460 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL,
461 THS_ZERO_PROGRAM_EN | ns2bc(dsi, 300));
462 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL,
463 THS_PRE_PROGRAM_EN | ns2ui(dsi, 100));
464 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL,
465 BIT(5) | ns2bc(dsi, 100));
466 dw_mipi_dsi_phy_write(dsi, HS_TX_CLOCK_LANE_POST_TIME_CONTROL,
467 BIT(5) | (ns2bc(dsi, 60) + 7));
468
469 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL,
470 TLP_PROGRAM_EN | ns2bc(dsi, 500));
471 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL,
472 THS_PRE_PROGRAM_EN | (ns2ui(dsi, 50) + 20));
473 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL,
474 THS_ZERO_PROGRAM_EN | (ns2bc(dsi, 140) + 2));
475 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL,
476 THS_PRE_PROGRAM_EN | (ns2ui(dsi, 60) + 8));
477 dw_mipi_dsi_phy_write(dsi, HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL,
478 BIT(5) | ns2bc(dsi, 100));
479
480 clk_disable_unprepare(dsi->phy_cfg_clk);
481
482 return ret;
483}
484
Heiko Stuebner94bedc42019-12-09 15:31:28 +0100485static void dw_mipi_dsi_phy_power_on(void *priv_data)
486{
487 struct dw_mipi_dsi_rockchip *dsi = priv_data;
488 int ret;
489
490 ret = phy_set_mode(dsi->phy, PHY_MODE_MIPI_DPHY);
491 if (ret) {
492 DRM_DEV_ERROR(dsi->dev, "failed to set phy mode: %d\n", ret);
493 return;
494 }
495
496 phy_configure(dsi->phy, &dsi->phy_opts);
497 phy_power_on(dsi->phy);
498}
499
500static void dw_mipi_dsi_phy_power_off(void *priv_data)
501{
502 struct dw_mipi_dsi_rockchip *dsi = priv_data;
503
504 phy_power_off(dsi->phy);
505}
506
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200507static int
Laurent Pinchart63f8f3b2018-04-06 17:39:01 +0300508dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200509 unsigned long mode_flags, u32 lanes, u32 format,
510 unsigned int *lane_mbps)
511{
512 struct dw_mipi_dsi_rockchip *dsi = priv_data;
513 int bpp;
514 unsigned long mpclk, tmp;
515 unsigned int target_mbps = 1000;
516 unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
517 unsigned long best_freq = 0;
518 unsigned long fvco_min, fvco_max, fin, fout;
519 unsigned int min_prediv, max_prediv;
Kees Cook3f649ab2020-06-03 13:09:38 -0700520 unsigned int _prediv, best_prediv;
521 unsigned long _fbdiv, best_fbdiv;
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200522 unsigned long min_delta = ULONG_MAX;
523
524 dsi->format = format;
525 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
526 if (bpp < 0) {
527 DRM_DEV_ERROR(dsi->dev,
528 "failed to get bpp for pixel format %d\n",
529 dsi->format);
530 return bpp;
531 }
532
533 mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
534 if (mpclk) {
535 /* take 1 / 0.8, since mbps must big than bandwidth of RGB */
536 tmp = mpclk * (bpp / lanes) * 10 / 8;
537 if (tmp < max_mbps)
538 target_mbps = tmp;
539 else
540 DRM_DEV_ERROR(dsi->dev,
541 "DPHY clock frequency is out of range\n");
542 }
543
Heiko Stuebner94bedc42019-12-09 15:31:28 +0100544 /* for external phy only a the mipi_dphy_config is necessary */
545 if (dsi->phy) {
546 phy_mipi_dphy_get_default_config(mode->clock * 1000 * 10 / 8,
547 bpp, lanes,
548 &dsi->phy_opts.mipi_dphy);
549 dsi->lane_mbps = target_mbps;
550 *lane_mbps = dsi->lane_mbps;
551
552 return 0;
553 }
554
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200555 fin = clk_get_rate(dsi->pllref_clk);
556 fout = target_mbps * USEC_PER_SEC;
557
558 /* constraint: 5Mhz <= Fref / N <= 40MHz */
559 min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC);
560 max_prediv = fin / (5 * USEC_PER_SEC);
561
562 /* constraint: 80MHz <= Fvco <= 1500Mhz */
563 fvco_min = 80 * USEC_PER_SEC;
564 fvco_max = 1500 * USEC_PER_SEC;
565
566 for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
567 u64 tmp;
568 u32 delta;
569 /* Fvco = Fref * M / N */
570 tmp = (u64)fout * _prediv;
571 do_div(tmp, fin);
572 _fbdiv = tmp;
573 /*
574 * Due to the use of a "by 2 pre-scaler," the range of the
575 * feedback multiplication value M is limited to even division
576 * numbers, and m must be greater than 6, not bigger than 512.
577 */
578 if (_fbdiv < 6 || _fbdiv > 512)
579 continue;
580
581 _fbdiv += _fbdiv % 2;
582
583 tmp = (u64)_fbdiv * fin;
584 do_div(tmp, _prediv);
585 if (tmp < fvco_min || tmp > fvco_max)
586 continue;
587
588 delta = abs(fout - tmp);
589 if (delta < min_delta) {
590 best_prediv = _prediv;
591 best_fbdiv = _fbdiv;
592 min_delta = delta;
593 best_freq = tmp;
594 }
595 }
596
597 if (best_freq) {
598 dsi->lane_mbps = DIV_ROUND_UP(best_freq, USEC_PER_SEC);
599 *lane_mbps = dsi->lane_mbps;
600 dsi->input_div = best_prediv;
601 dsi->feedback_div = best_fbdiv;
602 } else {
603 DRM_DEV_ERROR(dsi->dev, "Can not find best_freq for DPHY\n");
604 return -EINVAL;
605 }
606
607 return 0;
608}
609
Heiko Stuebner25ed8ae2019-12-09 15:31:25 +0100610struct hstt {
611 unsigned int maxfreq;
612 struct dw_mipi_dsi_dphy_timing timing;
613};
614
615#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \
616{ \
617 .maxfreq = _maxfreq, \
618 .timing = { \
619 .clk_lp2hs = _c_lp2hs, \
620 .clk_hs2lp = _c_hs2lp, \
621 .data_lp2hs = _d_lp2hs, \
622 .data_hs2lp = _d_hs2lp, \
623 } \
624}
625
626/* Table A-3 High-Speed Transition Times */
627struct hstt hstt_table[] = {
628 HSTT( 90, 32, 20, 26, 13),
629 HSTT( 100, 35, 23, 28, 14),
630 HSTT( 110, 32, 22, 26, 13),
631 HSTT( 130, 31, 20, 27, 13),
632 HSTT( 140, 33, 22, 26, 14),
633 HSTT( 150, 33, 21, 26, 14),
634 HSTT( 170, 32, 20, 27, 13),
635 HSTT( 180, 36, 23, 30, 15),
636 HSTT( 200, 40, 22, 33, 15),
637 HSTT( 220, 40, 22, 33, 15),
638 HSTT( 240, 44, 24, 36, 16),
639 HSTT( 250, 48, 24, 38, 17),
640 HSTT( 270, 48, 24, 38, 17),
641 HSTT( 300, 50, 27, 41, 18),
642 HSTT( 330, 56, 28, 45, 18),
643 HSTT( 360, 59, 28, 48, 19),
644 HSTT( 400, 61, 30, 50, 20),
645 HSTT( 450, 67, 31, 55, 21),
646 HSTT( 500, 73, 31, 59, 22),
647 HSTT( 550, 79, 36, 63, 24),
648 HSTT( 600, 83, 37, 68, 25),
649 HSTT( 650, 90, 38, 73, 27),
650 HSTT( 700, 95, 40, 77, 28),
651 HSTT( 750, 102, 40, 84, 28),
652 HSTT( 800, 106, 42, 87, 30),
653 HSTT( 850, 113, 44, 93, 31),
654 HSTT( 900, 118, 47, 98, 32),
655 HSTT( 950, 124, 47, 102, 34),
656 HSTT(1000, 130, 49, 107, 35),
657 HSTT(1050, 135, 51, 111, 37),
658 HSTT(1100, 139, 51, 114, 38),
659 HSTT(1150, 146, 54, 120, 40),
660 HSTT(1200, 153, 57, 125, 41),
661 HSTT(1250, 158, 58, 130, 42),
662 HSTT(1300, 163, 58, 135, 44),
663 HSTT(1350, 168, 60, 140, 45),
664 HSTT(1400, 172, 64, 144, 47),
665 HSTT(1450, 176, 65, 148, 48),
666 HSTT(1500, 181, 66, 153, 50)
667};
668
669static int
670dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
671 struct dw_mipi_dsi_dphy_timing *timing)
672{
673 int i;
674
675 for (i = 0; i < ARRAY_SIZE(hstt_table); i++)
676 if (lane_mbps < hstt_table[i].maxfreq)
677 break;
678
679 if (i == ARRAY_SIZE(hstt_table))
680 i--;
681
682 *timing = hstt_table[i].timing;
683
684 return 0;
685}
686
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200687static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
688 .init = dw_mipi_dsi_phy_init,
Heiko Stuebner94bedc42019-12-09 15:31:28 +0100689 .power_on = dw_mipi_dsi_phy_power_on,
690 .power_off = dw_mipi_dsi_phy_power_off,
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200691 .get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
Heiko Stuebner25ed8ae2019-12-09 15:31:25 +0100692 .get_timing = dw_mipi_dsi_phy_get_timing,
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200693};
694
Thomas Hebb43c2de12021-04-18 19:04:10 -0700695static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200696{
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200697 if (dsi->cdata->lanecfg1_grf_reg)
698 regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
699 dsi->cdata->lanecfg1);
700
701 if (dsi->cdata->lanecfg2_grf_reg)
702 regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg2_grf_reg,
703 dsi->cdata->lanecfg2);
704
705 if (dsi->cdata->enable_grf_reg)
706 regmap_write(dsi->grf_regmap, dsi->cdata->enable_grf_reg,
707 dsi->cdata->enable);
708}
709
Thomas Hebb43c2de12021-04-18 19:04:10 -0700710static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
711 int mux)
712{
713 regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
714 mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
715}
716
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200717static int
718dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
719 struct drm_crtc_state *crtc_state,
720 struct drm_connector_state *conn_state)
721{
722 struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
723 struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
724
725 switch (dsi->format) {
726 case MIPI_DSI_FMT_RGB888:
727 s->output_mode = ROCKCHIP_OUT_MODE_P888;
728 break;
729 case MIPI_DSI_FMT_RGB666:
730 s->output_mode = ROCKCHIP_OUT_MODE_P666;
731 break;
732 case MIPI_DSI_FMT_RGB565:
733 s->output_mode = ROCKCHIP_OUT_MODE_P565;
734 break;
735 default:
736 WARN_ON(1);
737 return -EINVAL;
738 }
739
740 s->output_type = DRM_MODE_CONNECTOR_DSI;
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200741 if (dsi->slave)
742 s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL;
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200743
744 return 0;
745}
746
747static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
748{
749 struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
750 int ret, mux;
751
752 mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node,
753 &dsi->encoder);
754 if (mux < 0)
755 return;
756
757 pm_runtime_get_sync(dsi->dev);
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200758 if (dsi->slave)
759 pm_runtime_get_sync(dsi->slave->dev);
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200760
761 /*
762 * For the RK3399, the clk of grf must be enabled before writing grf
763 * register. And for RK3288 or other soc, this grf_clk must be NULL,
764 * the clk_prepare_enable return true directly.
765 */
766 ret = clk_prepare_enable(dsi->grf_clk);
767 if (ret) {
768 DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
769 return;
770 }
771
Thomas Hebb43c2de12021-04-18 19:04:10 -0700772 dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux);
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200773 if (dsi->slave)
Thomas Hebb43c2de12021-04-18 19:04:10 -0700774 dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux);
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200775
776 clk_disable_unprepare(dsi->grf_clk);
777}
778
779static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
780{
781 struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
782
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200783 if (dsi->slave)
784 pm_runtime_put(dsi->slave->dev);
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200785 pm_runtime_put(dsi->dev);
786}
787
788static const struct drm_encoder_helper_funcs
789dw_mipi_dsi_encoder_helper_funcs = {
790 .atomic_check = dw_mipi_dsi_encoder_atomic_check,
791 .enable = dw_mipi_dsi_encoder_enable,
792 .disable = dw_mipi_dsi_encoder_disable,
793};
794
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200795static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
796 struct drm_device *drm_dev)
797{
798 struct drm_encoder *encoder = &dsi->encoder;
799 int ret;
800
801 encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
802 dsi->dev->of_node);
803
Thomas Zimmermann0dbd7352020-03-05 16:59:40 +0100804 ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_DSI);
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200805 if (ret) {
806 DRM_ERROR("Failed to initialize encoder with drm\n");
807 return ret;
808 }
809
810 drm_encoder_helper_add(encoder, &dw_mipi_dsi_encoder_helper_funcs);
811
812 return 0;
813}
814
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200815static struct device
816*dw_mipi_dsi_rockchip_find_second(struct dw_mipi_dsi_rockchip *dsi)
817{
818 const struct of_device_id *match;
819 struct device_node *node = NULL, *local;
820
821 match = of_match_device(dsi->dev->driver->of_match_table, dsi->dev);
822
823 local = of_graph_get_remote_node(dsi->dev->of_node, 1, 0);
824 if (!local)
825 return NULL;
826
827 while ((node = of_find_compatible_node(node, NULL,
828 match->compatible))) {
829 struct device_node *remote;
830
831 /* found ourself */
832 if (node == dsi->dev->of_node)
833 continue;
834
835 remote = of_graph_get_remote_node(node, 1, 0);
836 if (!remote)
837 continue;
838
839 /* same display device in port1-ep0 for both */
840 if (remote == local) {
841 struct dw_mipi_dsi_rockchip *dsi2;
842 struct platform_device *pdev;
843
844 pdev = of_find_device_by_node(node);
845
846 /*
847 * we have found the second, so will either return it
848 * or return with an error. In any case won't need the
849 * nodes anymore nor continue the loop.
850 */
851 of_node_put(remote);
852 of_node_put(node);
853 of_node_put(local);
854
855 if (!pdev)
856 return ERR_PTR(-EPROBE_DEFER);
857
858 dsi2 = platform_get_drvdata(pdev);
859 if (!dsi2) {
860 platform_device_put(pdev);
861 return ERR_PTR(-EPROBE_DEFER);
862 }
863
864 return &pdev->dev;
865 }
866
867 of_node_put(remote);
868 }
869
870 of_node_put(local);
871
872 return NULL;
873}
874
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200875static int dw_mipi_dsi_rockchip_bind(struct device *dev,
876 struct device *master,
877 void *data)
878{
879 struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
880 struct drm_device *drm_dev = data;
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200881 struct device *second;
882 bool master1, master2;
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200883 int ret;
884
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200885 second = dw_mipi_dsi_rockchip_find_second(dsi);
886 if (IS_ERR(second))
887 return PTR_ERR(second);
888
889 if (second) {
890 master1 = of_property_read_bool(dsi->dev->of_node,
891 "clock-master");
892 master2 = of_property_read_bool(second->of_node,
893 "clock-master");
894
895 if (master1 && master2) {
896 DRM_DEV_ERROR(dsi->dev, "only one clock-master allowed\n");
897 return -EINVAL;
898 }
899
900 if (!master1 && !master2) {
901 DRM_DEV_ERROR(dsi->dev, "no clock-master defined\n");
902 return -EINVAL;
903 }
904
905 /* we are the slave in dual-DSI */
906 if (!master1) {
907 dsi->is_slave = true;
908 return 0;
909 }
910
911 dsi->slave = dev_get_drvdata(second);
912 if (!dsi->slave) {
913 DRM_DEV_ERROR(dev, "could not get slaves data\n");
914 return -ENODEV;
915 }
916
917 dsi->slave->is_slave = true;
918 dw_mipi_dsi_set_slave(dsi->dmd, dsi->slave->dmd);
919 put_device(second);
920 }
921
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200922 ret = clk_prepare_enable(dsi->pllref_clk);
923 if (ret) {
924 DRM_DEV_ERROR(dev, "Failed to enable pllref_clk: %d\n", ret);
925 return ret;
926 }
927
Thomas Hebb43c2de12021-04-18 19:04:10 -0700928 /*
929 * With the GRF clock running, write lane and dual-mode configurations
930 * that won't change immediately. If we waited until enable() to do
931 * this, things like panel preparation would not be able to send
932 * commands over DSI.
933 */
934 ret = clk_prepare_enable(dsi->grf_clk);
935 if (ret) {
936 DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
937 return ret;
938 }
939
940 dw_mipi_dsi_rockchip_config(dsi);
941 if (dsi->slave)
942 dw_mipi_dsi_rockchip_config(dsi->slave);
943
944 clk_disable_unprepare(dsi->grf_clk);
945
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200946 ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev);
947 if (ret) {
948 DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
949 return ret;
950 }
951
952 ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder);
953 if (ret) {
954 DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret);
955 return ret;
956 }
957
958 return 0;
959}
960
961static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
962 struct device *master,
963 void *data)
964{
965 struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
966
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200967 if (dsi->is_slave)
968 return;
969
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200970 dw_mipi_dsi_unbind(dsi->dmd);
971
972 clk_disable_unprepare(dsi->pllref_clk);
973}
974
975static const struct component_ops dw_mipi_dsi_rockchip_ops = {
976 .bind = dw_mipi_dsi_rockchip_bind,
977 .unbind = dw_mipi_dsi_rockchip_unbind,
978};
979
980static int dw_mipi_dsi_rockchip_host_attach(void *priv_data,
981 struct mipi_dsi_device *device)
982{
983 struct dw_mipi_dsi_rockchip *dsi = priv_data;
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200984 struct device *second;
Nickey Yang2d4f7bd2018-10-01 14:38:43 +0200985 int ret;
986
987 ret = component_add(dsi->dev, &dw_mipi_dsi_rockchip_ops);
988 if (ret) {
989 DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n",
990 ret);
991 return ret;
992 }
993
Heiko Stuebnercf6d1002018-10-01 14:38:45 +0200994 second = dw_mipi_dsi_rockchip_find_second(dsi);
995 if (IS_ERR(second))
996 return PTR_ERR(second);
997 if (second) {
998 ret = component_add(second, &dw_mipi_dsi_rockchip_ops);
999 if (ret) {
1000 DRM_DEV_ERROR(second,
1001 "Failed to register component: %d\n",
1002 ret);
1003 return ret;
1004 }
1005 }
1006
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001007 return 0;
1008}
1009
1010static int dw_mipi_dsi_rockchip_host_detach(void *priv_data,
1011 struct mipi_dsi_device *device)
1012{
1013 struct dw_mipi_dsi_rockchip *dsi = priv_data;
Heiko Stuebnercf6d1002018-10-01 14:38:45 +02001014 struct device *second;
1015
1016 second = dw_mipi_dsi_rockchip_find_second(dsi);
1017 if (second && !IS_ERR(second))
1018 component_del(second, &dw_mipi_dsi_rockchip_ops);
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001019
1020 component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops);
1021
1022 return 0;
1023}
1024
1025static const struct dw_mipi_dsi_host_ops dw_mipi_dsi_rockchip_host_ops = {
1026 .attach = dw_mipi_dsi_rockchip_host_attach,
1027 .detach = dw_mipi_dsi_rockchip_host_detach,
1028};
1029
1030static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
1031{
1032 struct device *dev = &pdev->dev;
1033 struct device_node *np = dev->of_node;
1034 struct dw_mipi_dsi_rockchip *dsi;
1035 struct resource *res;
1036 const struct rockchip_dw_dsi_chip_data *cdata =
1037 of_device_get_match_data(dev);
1038 int ret, i;
1039
1040 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
1041 if (!dsi)
1042 return -ENOMEM;
1043
1044 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1045 dsi->base = devm_ioremap_resource(dev, res);
1046 if (IS_ERR(dsi->base)) {
1047 DRM_DEV_ERROR(dev, "Unable to get dsi registers\n");
1048 return PTR_ERR(dsi->base);
1049 }
1050
1051 i = 0;
1052 while (cdata[i].reg) {
1053 if (cdata[i].reg == res->start) {
1054 dsi->cdata = &cdata[i];
1055 break;
1056 }
1057
1058 i++;
1059 }
1060
1061 if (!dsi->cdata) {
Wambui Karugaf4563f32019-11-07 12:29:45 +03001062 DRM_DEV_ERROR(dev, "no dsi-config for %s node\n", np->name);
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001063 return -EINVAL;
1064 }
1065
Heiko Stuebner94bedc42019-12-09 15:31:28 +01001066 /* try to get a possible external dphy */
1067 dsi->phy = devm_phy_optional_get(dev, "dphy");
1068 if (IS_ERR(dsi->phy)) {
1069 ret = PTR_ERR(dsi->phy);
1070 DRM_DEV_ERROR(dev, "failed to get mipi dphy: %d\n", ret);
1071 return ret;
1072 }
1073
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001074 dsi->pllref_clk = devm_clk_get(dev, "ref");
1075 if (IS_ERR(dsi->pllref_clk)) {
Heiko Stuebner94bedc42019-12-09 15:31:28 +01001076 if (dsi->phy) {
1077 /*
1078 * if external phy is present, pll will be
1079 * generated there.
1080 */
1081 dsi->pllref_clk = NULL;
1082 } else {
1083 ret = PTR_ERR(dsi->pllref_clk);
1084 DRM_DEV_ERROR(dev,
1085 "Unable to get pll reference clock: %d\n",
1086 ret);
1087 return ret;
1088 }
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001089 }
1090
1091 if (dsi->cdata->flags & DW_MIPI_NEEDS_PHY_CFG_CLK) {
1092 dsi->phy_cfg_clk = devm_clk_get(dev, "phy_cfg");
1093 if (IS_ERR(dsi->phy_cfg_clk)) {
1094 ret = PTR_ERR(dsi->phy_cfg_clk);
1095 DRM_DEV_ERROR(dev,
1096 "Unable to get phy_cfg_clk: %d\n", ret);
1097 return ret;
1098 }
1099 }
1100
1101 if (dsi->cdata->flags & DW_MIPI_NEEDS_GRF_CLK) {
1102 dsi->grf_clk = devm_clk_get(dev, "grf");
1103 if (IS_ERR(dsi->grf_clk)) {
1104 ret = PTR_ERR(dsi->grf_clk);
1105 DRM_DEV_ERROR(dev, "Unable to get grf_clk: %d\n", ret);
1106 return ret;
1107 }
1108 }
1109
1110 dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
1111 if (IS_ERR(dsi->grf_regmap)) {
Dafna Hirschfeldf8c8c7d82020-11-16 15:16:09 +01001112 DRM_DEV_ERROR(dev, "Unable to get rockchip,grf\n");
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001113 return PTR_ERR(dsi->grf_regmap);
1114 }
1115
1116 dsi->dev = dev;
1117 dsi->pdata.base = dsi->base;
1118 dsi->pdata.max_data_lanes = dsi->cdata->max_data_lanes;
1119 dsi->pdata.phy_ops = &dw_mipi_dsi_rockchip_phy_ops;
1120 dsi->pdata.host_ops = &dw_mipi_dsi_rockchip_host_ops;
1121 dsi->pdata.priv_data = dsi;
1122 platform_set_drvdata(pdev, dsi);
1123
1124 dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata);
1125 if (IS_ERR(dsi->dmd)) {
1126 ret = PTR_ERR(dsi->dmd);
1127 if (ret != -EPROBE_DEFER)
1128 DRM_DEV_ERROR(dev,
1129 "Failed to probe dw_mipi_dsi: %d\n", ret);
1130 goto err_clkdisable;
1131 }
1132
1133 return 0;
1134
1135err_clkdisable:
1136 clk_disable_unprepare(dsi->pllref_clk);
1137 return ret;
1138}
1139
1140static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev)
1141{
1142 struct dw_mipi_dsi_rockchip *dsi = platform_get_drvdata(pdev);
1143
Heiko Stuebnercf6d1002018-10-01 14:38:45 +02001144 if (dsi->devcnt == 0)
1145 component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops);
1146
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001147 dw_mipi_dsi_remove(dsi->dmd);
1148
1149 return 0;
1150}
1151
Heiko Stuebner49a37dc2019-12-09 15:31:30 +01001152static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
1153 {
1154 .reg = 0xff450000,
1155 .lcdsel_grf_reg = PX30_GRF_PD_VO_CON1,
1156 .lcdsel_big = HIWORD_UPDATE(0, PX30_DSI_LCDC_SEL),
1157 .lcdsel_lit = HIWORD_UPDATE(PX30_DSI_LCDC_SEL,
1158 PX30_DSI_LCDC_SEL),
1159
1160 .lanecfg1_grf_reg = PX30_GRF_PD_VO_CON1,
1161 .lanecfg1 = HIWORD_UPDATE(0, PX30_DSI_TURNDISABLE |
1162 PX30_DSI_FORCERXMODE |
1163 PX30_DSI_FORCETXSTOPMODE),
1164
1165 .max_data_lanes = 4,
1166 },
1167 { /* sentinel */ }
1168};
1169
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001170static const struct rockchip_dw_dsi_chip_data rk3288_chip_data[] = {
1171 {
1172 .reg = 0xff960000,
1173 .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
1174 .lcdsel_big = HIWORD_UPDATE(0, RK3288_DSI0_LCDC_SEL),
1175 .lcdsel_lit = HIWORD_UPDATE(RK3288_DSI0_LCDC_SEL, RK3288_DSI0_LCDC_SEL),
1176
1177 .max_data_lanes = 4,
1178 },
1179 {
1180 .reg = 0xff964000,
1181 .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
1182 .lcdsel_big = HIWORD_UPDATE(0, RK3288_DSI1_LCDC_SEL),
1183 .lcdsel_lit = HIWORD_UPDATE(RK3288_DSI1_LCDC_SEL, RK3288_DSI1_LCDC_SEL),
1184
1185 .max_data_lanes = 4,
1186 },
1187 { /* sentinel */ }
1188};
1189
1190static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
1191 {
1192 .reg = 0xff960000,
1193 .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
1194 .lcdsel_big = HIWORD_UPDATE(0, RK3399_DSI0_LCDC_SEL),
1195 .lcdsel_lit = HIWORD_UPDATE(RK3399_DSI0_LCDC_SEL,
1196 RK3399_DSI0_LCDC_SEL),
1197
1198 .lanecfg1_grf_reg = RK3399_GRF_SOC_CON22,
1199 .lanecfg1 = HIWORD_UPDATE(0, RK3399_DSI0_TURNREQUEST |
1200 RK3399_DSI0_TURNDISABLE |
1201 RK3399_DSI0_FORCETXSTOPMODE |
1202 RK3399_DSI0_FORCERXMODE),
1203
1204 .flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
1205 .max_data_lanes = 4,
1206 },
1207 {
1208 .reg = 0xff968000,
1209 .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
1210 .lcdsel_big = HIWORD_UPDATE(0, RK3399_DSI1_LCDC_SEL),
1211 .lcdsel_lit = HIWORD_UPDATE(RK3399_DSI1_LCDC_SEL,
1212 RK3399_DSI1_LCDC_SEL),
1213
1214 .lanecfg1_grf_reg = RK3399_GRF_SOC_CON23,
1215 .lanecfg1 = HIWORD_UPDATE(0, RK3399_DSI1_TURNDISABLE |
1216 RK3399_DSI1_FORCETXSTOPMODE |
1217 RK3399_DSI1_FORCERXMODE |
1218 RK3399_DSI1_ENABLE),
1219
1220 .lanecfg2_grf_reg = RK3399_GRF_SOC_CON24,
1221 .lanecfg2 = HIWORD_UPDATE(RK3399_TXRX_MASTERSLAVEZ |
1222 RK3399_TXRX_ENABLECLK,
1223 RK3399_TXRX_MASTERSLAVEZ |
1224 RK3399_TXRX_ENABLECLK |
1225 RK3399_TXRX_BASEDIR),
1226
1227 .enable_grf_reg = RK3399_GRF_SOC_CON23,
1228 .enable = HIWORD_UPDATE(RK3399_DSI1_ENABLE, RK3399_DSI1_ENABLE),
1229
1230 .flags = DW_MIPI_NEEDS_PHY_CFG_CLK | DW_MIPI_NEEDS_GRF_CLK,
1231 .max_data_lanes = 4,
1232 },
1233 { /* sentinel */ }
1234};
1235
1236static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
1237 {
Heiko Stuebner49a37dc2019-12-09 15:31:30 +01001238 .compatible = "rockchip,px30-mipi-dsi",
1239 .data = &px30_chip_data,
1240 }, {
Nickey Yang2d4f7bd2018-10-01 14:38:43 +02001241 .compatible = "rockchip,rk3288-mipi-dsi",
1242 .data = &rk3288_chip_data,
1243 }, {
1244 .compatible = "rockchip,rk3399-mipi-dsi",
1245 .data = &rk3399_chip_data,
1246 },
1247 { /* sentinel */ }
1248};
1249MODULE_DEVICE_TABLE(of, dw_mipi_dsi_rockchip_dt_ids);
1250
1251struct platform_driver dw_mipi_dsi_rockchip_driver = {
1252 .probe = dw_mipi_dsi_rockchip_probe,
1253 .remove = dw_mipi_dsi_rockchip_remove,
1254 .driver = {
1255 .of_match_table = dw_mipi_dsi_rockchip_dt_ids,
1256 .name = "dw-mipi-dsi-rockchip",
1257 },
1258};