1 // SPDX-License-Identifier: GPL-2.0+
2
3 /*
4 * Copyright 2020 NXP
5 */
6
7 #include <linux/clk.h>
8 #include <linux/media-bus-format.h>
9 #include <linux/mfd/syscon.h>
10 #include <linux/module.h>
11 #include <linux/of.h>
12 #include <linux/of_device.h>
13 #include <linux/of_graph.h>
14 #include <linux/phy/phy.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18
19 #include <drm/drm_atomic_state_helper.h>
20 #include <drm/drm_bridge.h>
21 #include <drm/drm_connector.h>
22 #include <drm/drm_fourcc.h>
23 #include <drm/drm_of.h>
24 #include <drm/drm_print.h>
25
26 #include "imx-ldb-helper.h"
27
28 #define LDB_CH_SEL BIT(28)
29
30 #define SS_CTRL 0x20
31 #define CH_HSYNC_M(id) BIT(0 + ((id) * 2))
32 #define CH_VSYNC_M(id) BIT(1 + ((id) * 2))
33 #define CH_PHSYNC(id) BIT(0 + ((id) * 2))
34 #define CH_PVSYNC(id) BIT(1 + ((id) * 2))
35
36 #define DRIVER_NAME "imx8qxp-ldb"
37
38 struct imx8qxp_ldb_channel {
39 struct ldb_channel base;
40 struct phy *phy;
41 unsigned int di_id;
42 };
43
44 struct imx8qxp_ldb {
45 struct ldb base;
46 struct device *dev;
47 struct imx8qxp_ldb_channel *channel[MAX_LDB_CHAN_NUM];
48 struct clk *clk_pixel;
49 struct clk *clk_bypass;
50 struct drm_bridge *companion;
51 int active_chno;
52 };
53
54 static inline struct imx8qxp_ldb_channel *
base_to_imx8qxp_ldb_channel(struct ldb_channel * base)55 base_to_imx8qxp_ldb_channel(struct ldb_channel *base)
56 {
57 return container_of(base, struct imx8qxp_ldb_channel, base);
58 }
59
base_to_imx8qxp_ldb(struct ldb * base)60 static inline struct imx8qxp_ldb *base_to_imx8qxp_ldb(struct ldb *base)
61 {
62 return container_of(base, struct imx8qxp_ldb, base);
63 }
64
imx8qxp_ldb_bridge_destroy(struct drm_bridge * bridge)65 static void imx8qxp_ldb_bridge_destroy(struct drm_bridge *bridge)
66 {
67 struct ldb_channel *ldb_ch = bridge->driver_private;
68 struct imx8qxp_ldb *imx8qxp_ldb;
69
70 if (!ldb_ch)
71 return;
72
73 imx8qxp_ldb = base_to_imx8qxp_ldb(ldb_ch->ldb);
74 drm_bridge_put(imx8qxp_ldb->companion);
75 }
76
imx8qxp_ldb_set_phy_cfg(struct imx8qxp_ldb * imx8qxp_ldb,unsigned long di_clk,bool is_split,struct phy_configure_opts_lvds * phy_cfg)77 static void imx8qxp_ldb_set_phy_cfg(struct imx8qxp_ldb *imx8qxp_ldb,
78 unsigned long di_clk, bool is_split,
79 struct phy_configure_opts_lvds *phy_cfg)
80 {
81 phy_cfg->bits_per_lane_and_dclk_cycle = 7;
82 phy_cfg->lanes = 4;
83
84 if (is_split) {
85 phy_cfg->differential_clk_rate = di_clk / 2;
86 phy_cfg->is_slave = !imx8qxp_ldb->companion;
87 } else {
88 phy_cfg->differential_clk_rate = di_clk;
89 phy_cfg->is_slave = false;
90 }
91 }
92
93 static int
imx8qxp_ldb_bridge_atomic_check(struct drm_bridge * bridge,struct drm_bridge_state * bridge_state,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state)94 imx8qxp_ldb_bridge_atomic_check(struct drm_bridge *bridge,
95 struct drm_bridge_state *bridge_state,
96 struct drm_crtc_state *crtc_state,
97 struct drm_connector_state *conn_state)
98 {
99 struct ldb_channel *ldb_ch = bridge->driver_private;
100 struct ldb *ldb = ldb_ch->ldb;
101 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
102 base_to_imx8qxp_ldb_channel(ldb_ch);
103 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb);
104 struct drm_bridge *companion = imx8qxp_ldb->companion;
105 struct drm_display_mode *adj = &crtc_state->adjusted_mode;
106 unsigned long di_clk = adj->clock * 1000;
107 bool is_split = ldb_channel_is_split_link(ldb_ch);
108 union phy_configure_opts opts = { };
109 struct phy_configure_opts_lvds *phy_cfg = &opts.lvds;
110 int ret;
111
112 ret = ldb_bridge_atomic_check_helper(bridge, bridge_state,
113 crtc_state, conn_state);
114 if (ret)
115 return ret;
116
117 imx8qxp_ldb_set_phy_cfg(imx8qxp_ldb, di_clk, is_split, phy_cfg);
118 ret = phy_validate(imx8qxp_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts);
119 if (ret < 0) {
120 DRM_DEV_DEBUG_DRIVER(imx8qxp_ldb->dev,
121 "failed to validate PHY: %d\n", ret);
122 return ret;
123 }
124
125 if (is_split && companion) {
126 ret = companion->funcs->atomic_check(companion,
127 bridge_state, crtc_state, conn_state);
128 if (ret)
129 return ret;
130 }
131
132 return ret;
133 }
134
135 static void
imx8qxp_ldb_bridge_mode_set(struct drm_bridge * bridge,const struct drm_display_mode * mode,const struct drm_display_mode * adjusted_mode)136 imx8qxp_ldb_bridge_mode_set(struct drm_bridge *bridge,
137 const struct drm_display_mode *mode,
138 const struct drm_display_mode *adjusted_mode)
139 {
140 struct ldb_channel *ldb_ch = bridge->driver_private;
141 struct ldb_channel *companion_ldb_ch;
142 struct ldb *ldb = ldb_ch->ldb;
143 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
144 base_to_imx8qxp_ldb_channel(ldb_ch);
145 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb);
146 struct drm_bridge *companion = imx8qxp_ldb->companion;
147 struct device *dev = imx8qxp_ldb->dev;
148 unsigned long di_clk = adjusted_mode->clock * 1000;
149 bool is_split = ldb_channel_is_split_link(ldb_ch);
150 union phy_configure_opts opts = { };
151 struct phy_configure_opts_lvds *phy_cfg = &opts.lvds;
152 u32 chno = ldb_ch->chno;
153 int ret;
154
155 ret = pm_runtime_get_sync(dev);
156 if (ret < 0)
157 DRM_DEV_ERROR(dev, "failed to get runtime PM sync: %d\n", ret);
158
159 ret = phy_init(imx8qxp_ldb_ch->phy);
160 if (ret < 0)
161 DRM_DEV_ERROR(dev, "failed to initialize PHY: %d\n", ret);
162
163 ret = phy_set_mode(imx8qxp_ldb_ch->phy, PHY_MODE_LVDS);
164 if (ret < 0)
165 DRM_DEV_ERROR(dev, "failed to set PHY mode: %d\n", ret);
166
167 if (is_split && companion) {
168 companion_ldb_ch = bridge_to_ldb_ch(companion);
169
170 companion_ldb_ch->in_bus_format = ldb_ch->in_bus_format;
171 companion_ldb_ch->out_bus_format = ldb_ch->out_bus_format;
172 }
173
174 clk_set_rate(imx8qxp_ldb->clk_bypass, di_clk);
175 clk_set_rate(imx8qxp_ldb->clk_pixel, di_clk);
176
177 imx8qxp_ldb_set_phy_cfg(imx8qxp_ldb, di_clk, is_split, phy_cfg);
178 ret = phy_configure(imx8qxp_ldb_ch->phy, &opts);
179 if (ret < 0)
180 DRM_DEV_ERROR(dev, "failed to configure PHY: %d\n", ret);
181
182 if (chno == 0)
183 ldb->ldb_ctrl &= ~LDB_CH_SEL;
184 else
185 ldb->ldb_ctrl |= LDB_CH_SEL;
186
187 /* input VSYNC signal from pixel link is active low */
188 if (imx8qxp_ldb_ch->di_id == 0)
189 ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW;
190 else
191 ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW;
192
193 /*
194 * For split mode, settle input VSYNC signal polarity and
195 * channel selection down early.
196 */
197 if (is_split)
198 regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ldb_ctrl);
199
200 ldb_bridge_mode_set_helper(bridge, mode, adjusted_mode);
201
202 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
203 regmap_update_bits(ldb->regmap, SS_CTRL, CH_VSYNC_M(chno), 0);
204 else if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
205 regmap_update_bits(ldb->regmap, SS_CTRL,
206 CH_VSYNC_M(chno), CH_PVSYNC(chno));
207
208 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
209 regmap_update_bits(ldb->regmap, SS_CTRL, CH_HSYNC_M(chno), 0);
210 else if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
211 regmap_update_bits(ldb->regmap, SS_CTRL,
212 CH_HSYNC_M(chno), CH_PHSYNC(chno));
213
214 if (is_split && companion)
215 companion->funcs->mode_set(companion, mode, adjusted_mode);
216 }
217
imx8qxp_ldb_bridge_atomic_pre_enable(struct drm_bridge * bridge,struct drm_atomic_state * state)218 static void imx8qxp_ldb_bridge_atomic_pre_enable(struct drm_bridge *bridge,
219 struct drm_atomic_state *state)
220 {
221 struct ldb_channel *ldb_ch = bridge->driver_private;
222 struct ldb *ldb = ldb_ch->ldb;
223 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb);
224 struct drm_bridge *companion = imx8qxp_ldb->companion;
225 bool is_split = ldb_channel_is_split_link(ldb_ch);
226
227 clk_prepare_enable(imx8qxp_ldb->clk_pixel);
228 clk_prepare_enable(imx8qxp_ldb->clk_bypass);
229
230 if (is_split && companion)
231 companion->funcs->atomic_pre_enable(companion, state);
232 }
233
imx8qxp_ldb_bridge_atomic_enable(struct drm_bridge * bridge,struct drm_atomic_state * state)234 static void imx8qxp_ldb_bridge_atomic_enable(struct drm_bridge *bridge,
235 struct drm_atomic_state *state)
236 {
237 struct ldb_channel *ldb_ch = bridge->driver_private;
238 struct ldb *ldb = ldb_ch->ldb;
239 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
240 base_to_imx8qxp_ldb_channel(ldb_ch);
241 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb);
242 struct drm_bridge *companion = imx8qxp_ldb->companion;
243 struct device *dev = imx8qxp_ldb->dev;
244 bool is_split = ldb_channel_is_split_link(ldb_ch);
245 int ret;
246
247 if (ldb_ch->chno == 0 || is_split) {
248 ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
249 ldb->ldb_ctrl |= imx8qxp_ldb_ch->di_id == 0 ?
250 LDB_CH0_MODE_EN_TO_DI0 : LDB_CH0_MODE_EN_TO_DI1;
251 }
252 if (ldb_ch->chno == 1 || is_split) {
253 ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
254 ldb->ldb_ctrl |= imx8qxp_ldb_ch->di_id == 0 ?
255 LDB_CH1_MODE_EN_TO_DI0 : LDB_CH1_MODE_EN_TO_DI1;
256 }
257
258 ldb_bridge_enable_helper(bridge);
259
260 ret = phy_power_on(imx8qxp_ldb_ch->phy);
261 if (ret)
262 DRM_DEV_ERROR(dev, "failed to power on PHY: %d\n", ret);
263
264 if (is_split && companion)
265 companion->funcs->atomic_enable(companion, state);
266 }
267
imx8qxp_ldb_bridge_atomic_disable(struct drm_bridge * bridge,struct drm_atomic_state * state)268 static void imx8qxp_ldb_bridge_atomic_disable(struct drm_bridge *bridge,
269 struct drm_atomic_state *state)
270 {
271 struct ldb_channel *ldb_ch = bridge->driver_private;
272 struct ldb *ldb = ldb_ch->ldb;
273 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
274 base_to_imx8qxp_ldb_channel(ldb_ch);
275 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb);
276 struct drm_bridge *companion = imx8qxp_ldb->companion;
277 struct device *dev = imx8qxp_ldb->dev;
278 bool is_split = ldb_channel_is_split_link(ldb_ch);
279 int ret;
280
281 ret = phy_power_off(imx8qxp_ldb_ch->phy);
282 if (ret)
283 DRM_DEV_ERROR(dev, "failed to power off PHY: %d\n", ret);
284
285 ret = phy_exit(imx8qxp_ldb_ch->phy);
286 if (ret < 0)
287 DRM_DEV_ERROR(dev, "failed to teardown PHY: %d\n", ret);
288
289 ldb_bridge_disable_helper(bridge);
290
291 clk_disable_unprepare(imx8qxp_ldb->clk_bypass);
292 clk_disable_unprepare(imx8qxp_ldb->clk_pixel);
293
294 if (is_split && companion)
295 companion->funcs->atomic_disable(companion, state);
296
297 pm_runtime_put(dev);
298 }
299
300 static const u32 imx8qxp_ldb_bus_output_fmts[] = {
301 MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
302 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
303 MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
304 MEDIA_BUS_FMT_FIXED,
305 };
306
imx8qxp_ldb_bus_output_fmt_supported(u32 fmt)307 static bool imx8qxp_ldb_bus_output_fmt_supported(u32 fmt)
308 {
309 int i;
310
311 for (i = 0; i < ARRAY_SIZE(imx8qxp_ldb_bus_output_fmts); i++) {
312 if (imx8qxp_ldb_bus_output_fmts[i] == fmt)
313 return true;
314 }
315
316 return false;
317 }
318
319 static u32 *
imx8qxp_ldb_bridge_atomic_get_input_bus_fmts(struct drm_bridge * bridge,struct drm_bridge_state * bridge_state,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state,u32 output_fmt,unsigned int * num_input_fmts)320 imx8qxp_ldb_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
321 struct drm_bridge_state *bridge_state,
322 struct drm_crtc_state *crtc_state,
323 struct drm_connector_state *conn_state,
324 u32 output_fmt,
325 unsigned int *num_input_fmts)
326 {
327 struct drm_display_info *di;
328 const struct drm_format_info *finfo;
329 u32 *input_fmts;
330
331 if (!imx8qxp_ldb_bus_output_fmt_supported(output_fmt))
332 return NULL;
333
334 *num_input_fmts = 1;
335
336 input_fmts = kmalloc_obj(*input_fmts);
337 if (!input_fmts)
338 return NULL;
339
340 switch (output_fmt) {
341 case MEDIA_BUS_FMT_FIXED:
342 di = &conn_state->connector->display_info;
343
344 /*
345 * Look at the first bus format to determine input format.
346 * Default to MEDIA_BUS_FMT_RGB888_1X24, if no match.
347 */
348 if (di->num_bus_formats) {
349 finfo = drm_format_info(di->bus_formats[0]);
350
351 input_fmts[0] = finfo->depth == 18 ?
352 MEDIA_BUS_FMT_RGB666_1X24_CPADHI :
353 MEDIA_BUS_FMT_RGB888_1X24;
354 } else {
355 input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
356 }
357 break;
358 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
359 input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
360 break;
361 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
362 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
363 input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
364 break;
365 default:
366 kfree(input_fmts);
367 input_fmts = NULL;
368 break;
369 }
370
371 return input_fmts;
372 }
373
374 static u32 *
imx8qxp_ldb_bridge_atomic_get_output_bus_fmts(struct drm_bridge * bridge,struct drm_bridge_state * bridge_state,struct drm_crtc_state * crtc_state,struct drm_connector_state * conn_state,unsigned int * num_output_fmts)375 imx8qxp_ldb_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
376 struct drm_bridge_state *bridge_state,
377 struct drm_crtc_state *crtc_state,
378 struct drm_connector_state *conn_state,
379 unsigned int *num_output_fmts)
380 {
381 *num_output_fmts = ARRAY_SIZE(imx8qxp_ldb_bus_output_fmts);
382 return kmemdup(imx8qxp_ldb_bus_output_fmts,
383 sizeof(imx8qxp_ldb_bus_output_fmts), GFP_KERNEL);
384 }
385
386 static enum drm_mode_status
imx8qxp_ldb_bridge_mode_valid(struct drm_bridge * bridge,const struct drm_display_info * info,const struct drm_display_mode * mode)387 imx8qxp_ldb_bridge_mode_valid(struct drm_bridge *bridge,
388 const struct drm_display_info *info,
389 const struct drm_display_mode *mode)
390 {
391 struct ldb_channel *ldb_ch = bridge->driver_private;
392 bool is_single = ldb_channel_is_single_link(ldb_ch);
393
394 if (mode->clock > 170000)
395 return MODE_CLOCK_HIGH;
396
397 if (mode->clock > 150000 && is_single)
398 return MODE_CLOCK_HIGH;
399
400 return MODE_OK;
401 }
402
403 static const struct drm_bridge_funcs imx8qxp_ldb_bridge_funcs = {
404 .destroy = imx8qxp_ldb_bridge_destroy,
405 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
406 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
407 .atomic_reset = drm_atomic_helper_bridge_reset,
408 .mode_valid = imx8qxp_ldb_bridge_mode_valid,
409 .attach = ldb_bridge_attach_helper,
410 .atomic_check = imx8qxp_ldb_bridge_atomic_check,
411 .mode_set = imx8qxp_ldb_bridge_mode_set,
412 .atomic_pre_enable = imx8qxp_ldb_bridge_atomic_pre_enable,
413 .atomic_enable = imx8qxp_ldb_bridge_atomic_enable,
414 .atomic_disable = imx8qxp_ldb_bridge_atomic_disable,
415 .atomic_get_input_bus_fmts =
416 imx8qxp_ldb_bridge_atomic_get_input_bus_fmts,
417 .atomic_get_output_bus_fmts =
418 imx8qxp_ldb_bridge_atomic_get_output_bus_fmts,
419 };
420
imx8qxp_ldb_set_di_id(struct imx8qxp_ldb * imx8qxp_ldb)421 static int imx8qxp_ldb_set_di_id(struct imx8qxp_ldb *imx8qxp_ldb)
422 {
423 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
424 imx8qxp_ldb->channel[imx8qxp_ldb->active_chno];
425 struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base;
426 struct device_node *ep, *remote;
427 struct device *dev = imx8qxp_ldb->dev;
428 struct of_endpoint endpoint;
429 int ret;
430
431 ep = of_graph_get_endpoint_by_regs(ldb_ch->np, 0, -1);
432 if (!ep) {
433 DRM_DEV_ERROR(dev, "failed to get port0 endpoint\n");
434 return -EINVAL;
435 }
436
437 remote = of_graph_get_remote_endpoint(ep);
438 of_node_put(ep);
439 if (!remote) {
440 DRM_DEV_ERROR(dev, "failed to get port0 remote endpoint\n");
441 return -EINVAL;
442 }
443
444 ret = of_graph_parse_endpoint(remote, &endpoint);
445 of_node_put(remote);
446 if (ret) {
447 DRM_DEV_ERROR(dev, "failed to parse port0 remote endpoint: %d\n",
448 ret);
449 return ret;
450 }
451
452 imx8qxp_ldb_ch->di_id = endpoint.id;
453
454 return 0;
455 }
456
457 static int
imx8qxp_ldb_check_chno_and_dual_link(struct ldb_channel * ldb_ch,int link)458 imx8qxp_ldb_check_chno_and_dual_link(struct ldb_channel *ldb_ch, int link)
459 {
460 if ((link == DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS && ldb_ch->chno != 0) ||
461 (link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS && ldb_ch->chno != 1))
462 return -EINVAL;
463
464 return 0;
465 }
466
imx8qxp_ldb_parse_dt_companion(struct imx8qxp_ldb * imx8qxp_ldb)467 static int imx8qxp_ldb_parse_dt_companion(struct imx8qxp_ldb *imx8qxp_ldb)
468 {
469 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
470 imx8qxp_ldb->channel[imx8qxp_ldb->active_chno];
471 struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base;
472 struct ldb_channel *companion_ldb_ch;
473 struct device_node *companion;
474 struct device_node *child;
475 struct device_node *companion_port = NULL;
476 struct device_node *port1, *port2;
477 struct device *dev = imx8qxp_ldb->dev;
478 const struct of_device_id *match;
479 u32 i;
480 int dual_link;
481 int ret;
482
483 /* Locate the companion LDB for dual-link operation, if any. */
484 companion = of_parse_phandle(dev->of_node, "fsl,companion-ldb", 0);
485 if (!companion)
486 return 0;
487
488 if (!of_device_is_available(companion)) {
489 DRM_DEV_ERROR(dev, "companion LDB is not available\n");
490 ret = -ENODEV;
491 goto out;
492 }
493
494 /*
495 * Sanity check: the companion bridge must have the same compatible
496 * string.
497 */
498 match = of_match_device(dev->driver->of_match_table, dev);
499 if (!of_device_is_compatible(companion, match->compatible)) {
500 DRM_DEV_ERROR(dev, "companion LDB is incompatible\n");
501 ret = -ENXIO;
502 goto out;
503 }
504
505 for_each_available_child_of_node(companion, child) {
506 ret = of_property_read_u32(child, "reg", &i);
507 if (ret || i > MAX_LDB_CHAN_NUM - 1) {
508 DRM_DEV_ERROR(dev,
509 "invalid channel node address: %u\n", i);
510 ret = -EINVAL;
511 of_node_put(child);
512 goto out;
513 }
514
515 /*
516 * Channel numbers have to be different, because channel0
517 * transmits odd pixels and channel1 transmits even pixels.
518 */
519 if (i == (ldb_ch->chno ^ 0x1)) {
520 companion_port = child;
521 break;
522 }
523 }
524
525 if (!companion_port) {
526 DRM_DEV_ERROR(dev,
527 "failed to find companion LDB channel port\n");
528 ret = -EINVAL;
529 goto out;
530 }
531
532 /*
533 * We need to work out if the sink is expecting us to function in
534 * dual-link mode. We do this by looking at the DT port nodes we are
535 * connected to. If they are marked as expecting odd pixels and
536 * even pixels than we need to enable LDB split mode.
537 */
538 port1 = of_graph_get_port_by_id(ldb_ch->np, 1);
539 port2 = of_graph_get_port_by_id(companion_port, 1);
540 dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);
541 of_node_put(port1);
542 of_node_put(port2);
543
544 switch (dual_link) {
545 case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
546 ldb_ch->link_type = LDB_CH_DUAL_LINK_ODD_EVEN_PIXELS;
547 break;
548 case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
549 ldb_ch->link_type = LDB_CH_DUAL_LINK_EVEN_ODD_PIXELS;
550 break;
551 default:
552 ret = dual_link;
553 DRM_DEV_ERROR(dev,
554 "failed to get dual link pixel order: %d\n", ret);
555 goto out;
556 }
557
558 ret = imx8qxp_ldb_check_chno_and_dual_link(ldb_ch, dual_link);
559 if (ret < 0) {
560 DRM_DEV_ERROR(dev,
561 "unmatched channel number(%u) vs dual link(%d)\n",
562 ldb_ch->chno, dual_link);
563 goto out;
564 }
565
566 imx8qxp_ldb->companion = of_drm_find_and_get_bridge(companion_port);
567 if (!imx8qxp_ldb->companion) {
568 ret = -EPROBE_DEFER;
569 DRM_DEV_DEBUG_DRIVER(dev,
570 "failed to find bridge for companion bridge: %d\n",
571 ret);
572 goto out;
573 }
574
575 DRM_DEV_DEBUG_DRIVER(dev,
576 "dual-link configuration detected (companion bridge %pOF)\n",
577 companion);
578
579 companion_ldb_ch = bridge_to_ldb_ch(imx8qxp_ldb->companion);
580 companion_ldb_ch->link_type = ldb_ch->link_type;
581 out:
582 of_node_put(companion_port);
583 of_node_put(companion);
584 return ret;
585 }
586
imx8qxp_ldb_probe(struct platform_device * pdev)587 static int imx8qxp_ldb_probe(struct platform_device *pdev)
588 {
589 struct device *dev = &pdev->dev;
590 struct imx8qxp_ldb *imx8qxp_ldb;
591 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch;
592 struct ldb *ldb;
593 struct ldb_channel *ldb_ch;
594 int ret, i;
595
596 imx8qxp_ldb = devm_kzalloc(dev, sizeof(*imx8qxp_ldb), GFP_KERNEL);
597 if (!imx8qxp_ldb)
598 return -ENOMEM;
599
600 for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
601 imx8qxp_ldb->channel[i] =
602 devm_drm_bridge_alloc(dev, struct imx8qxp_ldb_channel, base.bridge,
603 &imx8qxp_ldb_bridge_funcs);
604 if (IS_ERR(imx8qxp_ldb->channel[i]))
605 return PTR_ERR(imx8qxp_ldb->channel[i]);
606 }
607
608 imx8qxp_ldb->clk_pixel = devm_clk_get(dev, "pixel");
609 if (IS_ERR(imx8qxp_ldb->clk_pixel)) {
610 ret = PTR_ERR(imx8qxp_ldb->clk_pixel);
611 if (ret != -EPROBE_DEFER)
612 DRM_DEV_ERROR(dev,
613 "failed to get pixel clock: %d\n", ret);
614 return ret;
615 }
616
617 imx8qxp_ldb->clk_bypass = devm_clk_get(dev, "bypass");
618 if (IS_ERR(imx8qxp_ldb->clk_bypass)) {
619 ret = PTR_ERR(imx8qxp_ldb->clk_bypass);
620 if (ret != -EPROBE_DEFER)
621 DRM_DEV_ERROR(dev,
622 "failed to get bypass clock: %d\n", ret);
623 return ret;
624 }
625
626 imx8qxp_ldb->dev = dev;
627
628 ldb = &imx8qxp_ldb->base;
629 ldb->dev = dev;
630 ldb->ctrl_reg = 0xe0;
631
632 for (i = 0; i < MAX_LDB_CHAN_NUM; i++)
633 ldb->channel[i] = &imx8qxp_ldb->channel[i]->base;
634
635 ret = ldb_init_helper(ldb);
636 if (ret)
637 return ret;
638
639 if (ldb->available_ch_cnt == 0) {
640 DRM_DEV_DEBUG_DRIVER(dev, "no available channel\n");
641 return 0;
642 } else if (ldb->available_ch_cnt > 1) {
643 DRM_DEV_ERROR(dev, "invalid available channel number(%u)\n",
644 ldb->available_ch_cnt);
645 return -EINVAL;
646 }
647
648 for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
649 imx8qxp_ldb_ch = imx8qxp_ldb->channel[i];
650 ldb_ch = &imx8qxp_ldb_ch->base;
651
652 if (ldb_ch->is_available) {
653 imx8qxp_ldb->active_chno = ldb_ch->chno;
654 break;
655 }
656 }
657
658 imx8qxp_ldb_ch->phy = devm_of_phy_get(dev, ldb_ch->np, "lvds_phy");
659 if (IS_ERR(imx8qxp_ldb_ch->phy)) {
660 ret = PTR_ERR(imx8qxp_ldb_ch->phy);
661 if (ret != -EPROBE_DEFER)
662 DRM_DEV_ERROR(dev, "failed to get channel%d PHY: %d\n",
663 imx8qxp_ldb->active_chno, ret);
664 return ret;
665 }
666
667 ret = ldb_find_next_bridge_helper(ldb);
668 if (ret)
669 return ret;
670
671 ret = imx8qxp_ldb_set_di_id(imx8qxp_ldb);
672 if (ret)
673 return ret;
674
675 ret = imx8qxp_ldb_parse_dt_companion(imx8qxp_ldb);
676 if (ret)
677 return ret;
678
679 platform_set_drvdata(pdev, imx8qxp_ldb);
680 pm_runtime_enable(dev);
681
682 ldb_add_bridge_helper(ldb);
683
684 return 0;
685 }
686
imx8qxp_ldb_remove(struct platform_device * pdev)687 static void imx8qxp_ldb_remove(struct platform_device *pdev)
688 {
689 struct imx8qxp_ldb *imx8qxp_ldb = platform_get_drvdata(pdev);
690 struct ldb *ldb = &imx8qxp_ldb->base;
691
692 ldb_remove_bridge_helper(ldb);
693
694 pm_runtime_disable(&pdev->dev);
695 }
696
imx8qxp_ldb_runtime_resume(struct device * dev)697 static int imx8qxp_ldb_runtime_resume(struct device *dev)
698 {
699 struct imx8qxp_ldb *imx8qxp_ldb = dev_get_drvdata(dev);
700 struct ldb *ldb = &imx8qxp_ldb->base;
701
702 /* disable LDB by resetting the control register to POR default */
703 regmap_write(ldb->regmap, ldb->ctrl_reg, 0);
704
705 return 0;
706 }
707
708 static const struct dev_pm_ops imx8qxp_ldb_pm_ops = {
709 RUNTIME_PM_OPS(NULL, imx8qxp_ldb_runtime_resume, NULL)
710 };
711
712 static const struct of_device_id imx8qxp_ldb_dt_ids[] = {
713 { .compatible = "fsl,imx8qxp-ldb" },
714 { /* sentinel */ }
715 };
716 MODULE_DEVICE_TABLE(of, imx8qxp_ldb_dt_ids);
717
718 static struct platform_driver imx8qxp_ldb_driver = {
719 .probe = imx8qxp_ldb_probe,
720 .remove = imx8qxp_ldb_remove,
721 .driver = {
722 .pm = pm_ptr(&imx8qxp_ldb_pm_ops),
723 .name = DRIVER_NAME,
724 .of_match_table = imx8qxp_ldb_dt_ids,
725 },
726 };
727 module_platform_driver(imx8qxp_ldb_driver);
728
729 MODULE_DESCRIPTION("i.MX8QXP LVDS Display Bridge(LDB)/Pixel Mapper bridge driver");
730 MODULE_AUTHOR("Liu Ying <victor.liu@nxp.com>");
731 MODULE_LICENSE("GPL v2");
732 MODULE_ALIAS("platform:" DRIVER_NAME);
733