xref: /openbmc/linux/drivers/gpu/drm/omapdrm/dss/dpi.c (revision d236d361)
1 /*
2  * linux/drivers/video/omap2/dss/dpi.c
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6  *
7  * Some code and ideas taken from drivers/video/omap/ driver
8  * by Imre Deak.
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published by
12  * the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #define DSS_SUBSYS_NAME "DPI"
24 
25 #include <linux/kernel.h>
26 #include <linux/delay.h>
27 #include <linux/export.h>
28 #include <linux/err.h>
29 #include <linux/errno.h>
30 #include <linux/platform_device.h>
31 #include <linux/regulator/consumer.h>
32 #include <linux/string.h>
33 #include <linux/of.h>
34 #include <linux/clk.h>
35 #include <linux/component.h>
36 
37 #include "omapdss.h"
38 #include "dss.h"
39 #include "dss_features.h"
40 
41 struct dpi_data {
42 	struct platform_device *pdev;
43 
44 	struct regulator *vdds_dsi_reg;
45 	enum dss_clk_source clk_src;
46 	struct dss_pll *pll;
47 
48 	struct mutex lock;
49 
50 	struct videomode vm;
51 	struct dss_lcd_mgr_config mgr_config;
52 	int data_lines;
53 
54 	struct omap_dss_device output;
55 
56 	bool port_initialized;
57 };
58 
59 static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
60 {
61 	return container_of(dssdev, struct dpi_data, output);
62 }
63 
64 /* only used in non-DT mode */
65 static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
66 {
67 	return dev_get_drvdata(&pdev->dev);
68 }
69 
70 static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
71 {
72 	/*
73 	 * Possible clock sources:
74 	 * LCD1: FCK/PLL1_1/HDMI_PLL
75 	 * LCD2: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_3)
76 	 * LCD3: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_1)
77 	 */
78 
79 	switch (channel) {
80 	case OMAP_DSS_CHANNEL_LCD:
81 	{
82 		if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1))
83 			return DSS_CLK_SRC_PLL1_1;
84 		break;
85 	}
86 	case OMAP_DSS_CHANNEL_LCD2:
87 	{
88 		if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
89 			return DSS_CLK_SRC_PLL1_3;
90 		if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3))
91 			return DSS_CLK_SRC_PLL2_3;
92 		break;
93 	}
94 	case OMAP_DSS_CHANNEL_LCD3:
95 	{
96 		if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1))
97 			return DSS_CLK_SRC_PLL2_1;
98 		if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3))
99 			return DSS_CLK_SRC_PLL1_3;
100 		break;
101 	}
102 	default:
103 		break;
104 	}
105 
106 	return DSS_CLK_SRC_FCK;
107 }
108 
109 static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
110 {
111 	/*
112 	 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
113 	 * would also be used for DISPC fclk. Meaning, when the DPI output is
114 	 * disabled, DISPC clock will be disabled, and TV out will stop.
115 	 */
116 	switch (omapdss_get_version()) {
117 	case OMAPDSS_VER_OMAP24xx:
118 	case OMAPDSS_VER_OMAP34xx_ES1:
119 	case OMAPDSS_VER_OMAP34xx_ES3:
120 	case OMAPDSS_VER_OMAP3630:
121 	case OMAPDSS_VER_AM35xx:
122 	case OMAPDSS_VER_AM43xx:
123 		return DSS_CLK_SRC_FCK;
124 
125 	case OMAPDSS_VER_OMAP4430_ES1:
126 	case OMAPDSS_VER_OMAP4430_ES2:
127 	case OMAPDSS_VER_OMAP4:
128 		switch (channel) {
129 		case OMAP_DSS_CHANNEL_LCD:
130 			return DSS_CLK_SRC_PLL1_1;
131 		case OMAP_DSS_CHANNEL_LCD2:
132 			return DSS_CLK_SRC_PLL2_1;
133 		default:
134 			return DSS_CLK_SRC_FCK;
135 		}
136 
137 	case OMAPDSS_VER_OMAP5:
138 		switch (channel) {
139 		case OMAP_DSS_CHANNEL_LCD:
140 			return DSS_CLK_SRC_PLL1_1;
141 		case OMAP_DSS_CHANNEL_LCD3:
142 			return DSS_CLK_SRC_PLL2_1;
143 		case OMAP_DSS_CHANNEL_LCD2:
144 		default:
145 			return DSS_CLK_SRC_FCK;
146 		}
147 
148 	case OMAPDSS_VER_DRA7xx:
149 		return dpi_get_clk_src_dra7xx(channel);
150 
151 	default:
152 		return DSS_CLK_SRC_FCK;
153 	}
154 }
155 
156 struct dpi_clk_calc_ctx {
157 	struct dss_pll *pll;
158 	unsigned clkout_idx;
159 
160 	/* inputs */
161 
162 	unsigned long pck_min, pck_max;
163 
164 	/* outputs */
165 
166 	struct dss_pll_clock_info pll_cinfo;
167 	unsigned long fck;
168 	struct dispc_clock_info dispc_cinfo;
169 };
170 
171 static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
172 		unsigned long pck, void *data)
173 {
174 	struct dpi_clk_calc_ctx *ctx = data;
175 
176 	/*
177 	 * Odd dividers give us uneven duty cycle, causing problem when level
178 	 * shifted. So skip all odd dividers when the pixel clock is on the
179 	 * higher side.
180 	 */
181 	if (ctx->pck_min >= 100000000) {
182 		if (lckd > 1 && lckd % 2 != 0)
183 			return false;
184 
185 		if (pckd > 1 && pckd % 2 != 0)
186 			return false;
187 	}
188 
189 	ctx->dispc_cinfo.lck_div = lckd;
190 	ctx->dispc_cinfo.pck_div = pckd;
191 	ctx->dispc_cinfo.lck = lck;
192 	ctx->dispc_cinfo.pck = pck;
193 
194 	return true;
195 }
196 
197 
198 static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
199 		void *data)
200 {
201 	struct dpi_clk_calc_ctx *ctx = data;
202 
203 	ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
204 	ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
205 
206 	return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
207 			dpi_calc_dispc_cb, ctx);
208 }
209 
210 
211 static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
212 		unsigned long clkdco,
213 		void *data)
214 {
215 	struct dpi_clk_calc_ctx *ctx = data;
216 
217 	ctx->pll_cinfo.n = n;
218 	ctx->pll_cinfo.m = m;
219 	ctx->pll_cinfo.fint = fint;
220 	ctx->pll_cinfo.clkdco = clkdco;
221 
222 	return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
223 		ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
224 		dpi_calc_hsdiv_cb, ctx);
225 }
226 
227 static bool dpi_calc_dss_cb(unsigned long fck, void *data)
228 {
229 	struct dpi_clk_calc_ctx *ctx = data;
230 
231 	ctx->fck = fck;
232 
233 	return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
234 			dpi_calc_dispc_cb, ctx);
235 }
236 
237 static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
238 		struct dpi_clk_calc_ctx *ctx)
239 {
240 	unsigned long clkin;
241 
242 	memset(ctx, 0, sizeof(*ctx));
243 	ctx->pll = dpi->pll;
244 	ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);
245 
246 	clkin = clk_get_rate(dpi->pll->clkin);
247 
248 	if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
249 		unsigned long pll_min, pll_max;
250 
251 		ctx->pck_min = pck - 1000;
252 		ctx->pck_max = pck + 1000;
253 
254 		pll_min = 0;
255 		pll_max = 0;
256 
257 		return dss_pll_calc_a(ctx->pll, clkin,
258 				pll_min, pll_max,
259 				dpi_calc_pll_cb, ctx);
260 	} else { /* DSS_PLL_TYPE_B */
261 		dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);
262 
263 		ctx->dispc_cinfo.lck_div = 1;
264 		ctx->dispc_cinfo.pck_div = 1;
265 		ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
266 		ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;
267 
268 		return true;
269 	}
270 }
271 
272 static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
273 {
274 	int i;
275 
276 	/*
277 	 * DSS fck gives us very few possibilities, so finding a good pixel
278 	 * clock may not be possible. We try multiple times to find the clock,
279 	 * each time widening the pixel clock range we look for, up to
280 	 * +/- ~15MHz.
281 	 */
282 
283 	for (i = 0; i < 25; ++i) {
284 		bool ok;
285 
286 		memset(ctx, 0, sizeof(*ctx));
287 		if (pck > 1000 * i * i * i)
288 			ctx->pck_min = max(pck - 1000 * i * i * i, 0lu);
289 		else
290 			ctx->pck_min = 0;
291 		ctx->pck_max = pck + 1000 * i * i * i;
292 
293 		ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx);
294 		if (ok)
295 			return ok;
296 	}
297 
298 	return false;
299 }
300 
301 
302 
303 static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
304 		unsigned long pck_req, unsigned long *fck, int *lck_div,
305 		int *pck_div)
306 {
307 	struct dpi_clk_calc_ctx ctx;
308 	int r;
309 	bool ok;
310 
311 	ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
312 	if (!ok)
313 		return -EINVAL;
314 
315 	r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
316 	if (r)
317 		return r;
318 
319 	dss_select_lcd_clk_source(channel, dpi->clk_src);
320 
321 	dpi->mgr_config.clock_info = ctx.dispc_cinfo;
322 
323 	*fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
324 	*lck_div = ctx.dispc_cinfo.lck_div;
325 	*pck_div = ctx.dispc_cinfo.pck_div;
326 
327 	return 0;
328 }
329 
330 static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
331 		unsigned long *fck, int *lck_div, int *pck_div)
332 {
333 	struct dpi_clk_calc_ctx ctx;
334 	int r;
335 	bool ok;
336 
337 	ok = dpi_dss_clk_calc(pck_req, &ctx);
338 	if (!ok)
339 		return -EINVAL;
340 
341 	r = dss_set_fck_rate(ctx.fck);
342 	if (r)
343 		return r;
344 
345 	dpi->mgr_config.clock_info = ctx.dispc_cinfo;
346 
347 	*fck = ctx.fck;
348 	*lck_div = ctx.dispc_cinfo.lck_div;
349 	*pck_div = ctx.dispc_cinfo.pck_div;
350 
351 	return 0;
352 }
353 
354 static int dpi_set_mode(struct dpi_data *dpi)
355 {
356 	struct omap_dss_device *out = &dpi->output;
357 	enum omap_channel channel = out->dispc_channel;
358 	struct videomode *vm = &dpi->vm;
359 	int lck_div = 0, pck_div = 0;
360 	unsigned long fck = 0;
361 	unsigned long pck;
362 	int r = 0;
363 
364 	if (dpi->pll)
365 		r = dpi_set_pll_clk(dpi, channel, vm->pixelclock, &fck,
366 				&lck_div, &pck_div);
367 	else
368 		r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck,
369 				&lck_div, &pck_div);
370 	if (r)
371 		return r;
372 
373 	pck = fck / lck_div / pck_div;
374 
375 	if (pck != vm->pixelclock) {
376 		DSSWARN("Could not find exact pixel clock. Requested %lu Hz, got %lu Hz\n",
377 			vm->pixelclock, pck);
378 
379 		vm->pixelclock = pck;
380 	}
381 
382 	dss_mgr_set_timings(channel, vm);
383 
384 	return 0;
385 }
386 
387 static void dpi_config_lcd_manager(struct dpi_data *dpi)
388 {
389 	struct omap_dss_device *out = &dpi->output;
390 	enum omap_channel channel = out->dispc_channel;
391 
392 	dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
393 
394 	dpi->mgr_config.stallmode = false;
395 	dpi->mgr_config.fifohandcheck = false;
396 
397 	dpi->mgr_config.video_port_width = dpi->data_lines;
398 
399 	dpi->mgr_config.lcden_sig_polarity = 0;
400 
401 	dss_mgr_set_lcd_config(channel, &dpi->mgr_config);
402 }
403 
404 static int dpi_display_enable(struct omap_dss_device *dssdev)
405 {
406 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
407 	struct omap_dss_device *out = &dpi->output;
408 	enum omap_channel channel = out->dispc_channel;
409 	int r;
410 
411 	mutex_lock(&dpi->lock);
412 
413 	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) {
414 		DSSERR("no VDSS_DSI regulator\n");
415 		r = -ENODEV;
416 		goto err_no_reg;
417 	}
418 
419 	if (!out->dispc_channel_connected) {
420 		DSSERR("failed to enable display: no output/manager\n");
421 		r = -ENODEV;
422 		goto err_no_out_mgr;
423 	}
424 
425 	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
426 		r = regulator_enable(dpi->vdds_dsi_reg);
427 		if (r)
428 			goto err_reg_enable;
429 	}
430 
431 	r = dispc_runtime_get();
432 	if (r)
433 		goto err_get_dispc;
434 
435 	r = dss_dpi_select_source(out->port_num, channel);
436 	if (r)
437 		goto err_src_sel;
438 
439 	if (dpi->pll) {
440 		r = dss_pll_enable(dpi->pll);
441 		if (r)
442 			goto err_pll_init;
443 	}
444 
445 	r = dpi_set_mode(dpi);
446 	if (r)
447 		goto err_set_mode;
448 
449 	dpi_config_lcd_manager(dpi);
450 
451 	mdelay(2);
452 
453 	r = dss_mgr_enable(channel);
454 	if (r)
455 		goto err_mgr_enable;
456 
457 	mutex_unlock(&dpi->lock);
458 
459 	return 0;
460 
461 err_mgr_enable:
462 err_set_mode:
463 	if (dpi->pll)
464 		dss_pll_disable(dpi->pll);
465 err_pll_init:
466 err_src_sel:
467 	dispc_runtime_put();
468 err_get_dispc:
469 	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
470 		regulator_disable(dpi->vdds_dsi_reg);
471 err_reg_enable:
472 err_no_out_mgr:
473 err_no_reg:
474 	mutex_unlock(&dpi->lock);
475 	return r;
476 }
477 
478 static void dpi_display_disable(struct omap_dss_device *dssdev)
479 {
480 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
481 	enum omap_channel channel = dpi->output.dispc_channel;
482 
483 	mutex_lock(&dpi->lock);
484 
485 	dss_mgr_disable(channel);
486 
487 	if (dpi->pll) {
488 		dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK);
489 		dss_pll_disable(dpi->pll);
490 	}
491 
492 	dispc_runtime_put();
493 
494 	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
495 		regulator_disable(dpi->vdds_dsi_reg);
496 
497 	mutex_unlock(&dpi->lock);
498 }
499 
500 static void dpi_set_timings(struct omap_dss_device *dssdev,
501 			    struct videomode *vm)
502 {
503 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
504 
505 	DSSDBG("dpi_set_timings\n");
506 
507 	mutex_lock(&dpi->lock);
508 
509 	dpi->vm = *vm;
510 
511 	mutex_unlock(&dpi->lock);
512 }
513 
514 static void dpi_get_timings(struct omap_dss_device *dssdev,
515 			    struct videomode *vm)
516 {
517 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
518 
519 	mutex_lock(&dpi->lock);
520 
521 	*vm = dpi->vm;
522 
523 	mutex_unlock(&dpi->lock);
524 }
525 
526 static int dpi_check_timings(struct omap_dss_device *dssdev,
527 			     struct videomode *vm)
528 {
529 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
530 	enum omap_channel channel = dpi->output.dispc_channel;
531 	int lck_div, pck_div;
532 	unsigned long fck;
533 	unsigned long pck;
534 	struct dpi_clk_calc_ctx ctx;
535 	bool ok;
536 
537 	if (vm->hactive % 8 != 0)
538 		return -EINVAL;
539 
540 	if (!dispc_mgr_timings_ok(channel, vm))
541 		return -EINVAL;
542 
543 	if (vm->pixelclock == 0)
544 		return -EINVAL;
545 
546 	if (dpi->pll) {
547 		ok = dpi_pll_clk_calc(dpi, vm->pixelclock, &ctx);
548 		if (!ok)
549 			return -EINVAL;
550 
551 		fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
552 	} else {
553 		ok = dpi_dss_clk_calc(vm->pixelclock, &ctx);
554 		if (!ok)
555 			return -EINVAL;
556 
557 		fck = ctx.fck;
558 	}
559 
560 	lck_div = ctx.dispc_cinfo.lck_div;
561 	pck_div = ctx.dispc_cinfo.pck_div;
562 
563 	pck = fck / lck_div / pck_div;
564 
565 	vm->pixelclock = pck;
566 
567 	return 0;
568 }
569 
570 static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
571 {
572 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
573 
574 	mutex_lock(&dpi->lock);
575 
576 	dpi->data_lines = data_lines;
577 
578 	mutex_unlock(&dpi->lock);
579 }
580 
581 static int dpi_verify_pll(struct dss_pll *pll)
582 {
583 	int r;
584 
585 	/* do initial setup with the PLL to see if it is operational */
586 
587 	r = dss_pll_enable(pll);
588 	if (r)
589 		return r;
590 
591 	dss_pll_disable(pll);
592 
593 	return 0;
594 }
595 
596 static int dpi_init_regulator(struct dpi_data *dpi)
597 {
598 	struct regulator *vdds_dsi;
599 
600 	if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
601 		return 0;
602 
603 	if (dpi->vdds_dsi_reg)
604 		return 0;
605 
606 	vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
607 	if (IS_ERR(vdds_dsi)) {
608 		if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
609 			DSSERR("can't get VDDS_DSI regulator\n");
610 		return PTR_ERR(vdds_dsi);
611 	}
612 
613 	dpi->vdds_dsi_reg = vdds_dsi;
614 
615 	return 0;
616 }
617 
618 static void dpi_init_pll(struct dpi_data *dpi)
619 {
620 	struct dss_pll *pll;
621 
622 	if (dpi->pll)
623 		return;
624 
625 	dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel);
626 
627 	pll = dss_pll_find_by_src(dpi->clk_src);
628 	if (!pll)
629 		return;
630 
631 	if (dpi_verify_pll(pll)) {
632 		DSSWARN("PLL not operational\n");
633 		return;
634 	}
635 
636 	dpi->pll = pll;
637 }
638 
639 /*
640  * Return a hardcoded channel for the DPI output. This should work for
641  * current use cases, but this can be later expanded to either resolve
642  * the channel in some more dynamic manner, or get the channel as a user
643  * parameter.
644  */
645 static enum omap_channel dpi_get_channel(int port_num)
646 {
647 	switch (omapdss_get_version()) {
648 	case OMAPDSS_VER_OMAP24xx:
649 	case OMAPDSS_VER_OMAP34xx_ES1:
650 	case OMAPDSS_VER_OMAP34xx_ES3:
651 	case OMAPDSS_VER_OMAP3630:
652 	case OMAPDSS_VER_AM35xx:
653 	case OMAPDSS_VER_AM43xx:
654 		return OMAP_DSS_CHANNEL_LCD;
655 
656 	case OMAPDSS_VER_DRA7xx:
657 		switch (port_num) {
658 		case 2:
659 			return OMAP_DSS_CHANNEL_LCD3;
660 		case 1:
661 			return OMAP_DSS_CHANNEL_LCD2;
662 		case 0:
663 		default:
664 			return OMAP_DSS_CHANNEL_LCD;
665 		}
666 
667 	case OMAPDSS_VER_OMAP4430_ES1:
668 	case OMAPDSS_VER_OMAP4430_ES2:
669 	case OMAPDSS_VER_OMAP4:
670 		return OMAP_DSS_CHANNEL_LCD2;
671 
672 	case OMAPDSS_VER_OMAP5:
673 		return OMAP_DSS_CHANNEL_LCD3;
674 
675 	default:
676 		DSSWARN("unsupported DSS version\n");
677 		return OMAP_DSS_CHANNEL_LCD;
678 	}
679 }
680 
681 static int dpi_connect(struct omap_dss_device *dssdev,
682 		struct omap_dss_device *dst)
683 {
684 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
685 	enum omap_channel channel = dpi->output.dispc_channel;
686 	int r;
687 
688 	r = dpi_init_regulator(dpi);
689 	if (r)
690 		return r;
691 
692 	dpi_init_pll(dpi);
693 
694 	r = dss_mgr_connect(channel, dssdev);
695 	if (r)
696 		return r;
697 
698 	r = omapdss_output_set_device(dssdev, dst);
699 	if (r) {
700 		DSSERR("failed to connect output to new device: %s\n",
701 				dst->name);
702 		dss_mgr_disconnect(channel, dssdev);
703 		return r;
704 	}
705 
706 	return 0;
707 }
708 
709 static void dpi_disconnect(struct omap_dss_device *dssdev,
710 		struct omap_dss_device *dst)
711 {
712 	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
713 	enum omap_channel channel = dpi->output.dispc_channel;
714 
715 	WARN_ON(dst != dssdev->dst);
716 
717 	if (dst != dssdev->dst)
718 		return;
719 
720 	omapdss_output_unset_device(dssdev);
721 
722 	dss_mgr_disconnect(channel, dssdev);
723 }
724 
725 static const struct omapdss_dpi_ops dpi_ops = {
726 	.connect = dpi_connect,
727 	.disconnect = dpi_disconnect,
728 
729 	.enable = dpi_display_enable,
730 	.disable = dpi_display_disable,
731 
732 	.check_timings = dpi_check_timings,
733 	.set_timings = dpi_set_timings,
734 	.get_timings = dpi_get_timings,
735 
736 	.set_data_lines = dpi_set_data_lines,
737 };
738 
739 static void dpi_init_output(struct platform_device *pdev)
740 {
741 	struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
742 	struct omap_dss_device *out = &dpi->output;
743 
744 	out->dev = &pdev->dev;
745 	out->id = OMAP_DSS_OUTPUT_DPI;
746 	out->output_type = OMAP_DISPLAY_TYPE_DPI;
747 	out->name = "dpi.0";
748 	out->dispc_channel = dpi_get_channel(0);
749 	out->ops.dpi = &dpi_ops;
750 	out->owner = THIS_MODULE;
751 
752 	omapdss_register_output(out);
753 }
754 
755 static void dpi_uninit_output(struct platform_device *pdev)
756 {
757 	struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
758 	struct omap_dss_device *out = &dpi->output;
759 
760 	omapdss_unregister_output(out);
761 }
762 
763 static void dpi_init_output_port(struct platform_device *pdev,
764 	struct device_node *port)
765 {
766 	struct dpi_data *dpi = port->data;
767 	struct omap_dss_device *out = &dpi->output;
768 	int r;
769 	u32 port_num;
770 
771 	r = of_property_read_u32(port, "reg", &port_num);
772 	if (r)
773 		port_num = 0;
774 
775 	switch (port_num) {
776 	case 2:
777 		out->name = "dpi.2";
778 		break;
779 	case 1:
780 		out->name = "dpi.1";
781 		break;
782 	case 0:
783 	default:
784 		out->name = "dpi.0";
785 		break;
786 	}
787 
788 	out->dev = &pdev->dev;
789 	out->id = OMAP_DSS_OUTPUT_DPI;
790 	out->output_type = OMAP_DISPLAY_TYPE_DPI;
791 	out->dispc_channel = dpi_get_channel(port_num);
792 	out->port_num = port_num;
793 	out->ops.dpi = &dpi_ops;
794 	out->owner = THIS_MODULE;
795 
796 	omapdss_register_output(out);
797 }
798 
799 static void dpi_uninit_output_port(struct device_node *port)
800 {
801 	struct dpi_data *dpi = port->data;
802 	struct omap_dss_device *out = &dpi->output;
803 
804 	omapdss_unregister_output(out);
805 }
806 
807 static int dpi_bind(struct device *dev, struct device *master, void *data)
808 {
809 	struct platform_device *pdev = to_platform_device(dev);
810 	struct dpi_data *dpi;
811 
812 	dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
813 	if (!dpi)
814 		return -ENOMEM;
815 
816 	dpi->pdev = pdev;
817 
818 	dev_set_drvdata(&pdev->dev, dpi);
819 
820 	mutex_init(&dpi->lock);
821 
822 	dpi_init_output(pdev);
823 
824 	return 0;
825 }
826 
827 static void dpi_unbind(struct device *dev, struct device *master, void *data)
828 {
829 	struct platform_device *pdev = to_platform_device(dev);
830 
831 	dpi_uninit_output(pdev);
832 }
833 
834 static const struct component_ops dpi_component_ops = {
835 	.bind	= dpi_bind,
836 	.unbind	= dpi_unbind,
837 };
838 
839 static int dpi_probe(struct platform_device *pdev)
840 {
841 	return component_add(&pdev->dev, &dpi_component_ops);
842 }
843 
844 static int dpi_remove(struct platform_device *pdev)
845 {
846 	component_del(&pdev->dev, &dpi_component_ops);
847 	return 0;
848 }
849 
850 static struct platform_driver omap_dpi_driver = {
851 	.probe		= dpi_probe,
852 	.remove		= dpi_remove,
853 	.driver         = {
854 		.name   = "omapdss_dpi",
855 		.suppress_bind_attrs = true,
856 	},
857 };
858 
859 int __init dpi_init_platform_driver(void)
860 {
861 	return platform_driver_register(&omap_dpi_driver);
862 }
863 
864 void dpi_uninit_platform_driver(void)
865 {
866 	platform_driver_unregister(&omap_dpi_driver);
867 }
868 
869 int dpi_init_port(struct platform_device *pdev, struct device_node *port)
870 {
871 	struct dpi_data *dpi;
872 	struct device_node *ep;
873 	u32 datalines;
874 	int r;
875 
876 	dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
877 	if (!dpi)
878 		return -ENOMEM;
879 
880 	ep = of_get_next_child(port, NULL);
881 	if (!ep)
882 		return 0;
883 
884 	r = of_property_read_u32(ep, "data-lines", &datalines);
885 	if (r) {
886 		DSSERR("failed to parse datalines\n");
887 		goto err_datalines;
888 	}
889 
890 	dpi->data_lines = datalines;
891 
892 	of_node_put(ep);
893 
894 	dpi->pdev = pdev;
895 	port->data = dpi;
896 
897 	mutex_init(&dpi->lock);
898 
899 	dpi_init_output_port(pdev, port);
900 
901 	dpi->port_initialized = true;
902 
903 	return 0;
904 
905 err_datalines:
906 	of_node_put(ep);
907 
908 	return r;
909 }
910 
911 void dpi_uninit_port(struct device_node *port)
912 {
913 	struct dpi_data *dpi = port->data;
914 
915 	if (!dpi->port_initialized)
916 		return;
917 
918 	dpi_uninit_output_port(port);
919 }
920