xref: /linux/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
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 *
55 base_to_imx8qxp_ldb_channel(struct ldb_channel *base)
56 {
57 	return container_of(base, struct imx8qxp_ldb_channel, base);
58 }
59 
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 
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 
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
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
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 
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 
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 
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 
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 *
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 *
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
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 
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
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 
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 
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 
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 
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