xref: /linux/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * shmob_drm_crtc.c  --  SH Mobile DRM CRTCs
4  *
5  * Copyright (C) 2012 Renesas Electronics Corporation
6  *
7  * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8  */
9 
10 #include <linux/clk.h>
11 #include <linux/media-bus-format.h>
12 #include <linux/of.h>
13 #include <linux/of_graph.h>
14 #include <linux/pm_runtime.h>
15 
16 #include <drm/drm_atomic.h>
17 #include <drm/drm_atomic_helper.h>
18 #include <drm/drm_atomic_state_helper.h>
19 #include <drm/drm_atomic_uapi.h>
20 #include <drm/drm_bridge.h>
21 #include <drm/drm_bridge_connector.h>
22 #include <drm/drm_crtc.h>
23 #include <drm/drm_crtc_helper.h>
24 #include <drm/drm_fb_dma_helper.h>
25 #include <drm/drm_fourcc.h>
26 #include <drm/drm_framebuffer.h>
27 #include <drm/drm_gem_dma_helper.h>
28 #include <drm/drm_modeset_helper.h>
29 #include <drm/drm_modeset_helper_vtables.h>
30 #include <drm/drm_panel.h>
31 #include <drm/drm_probe_helper.h>
32 #include <drm/drm_simple_kms_helper.h>
33 #include <drm/drm_vblank.h>
34 
35 #include <video/videomode.h>
36 
37 #include "shmob_drm_crtc.h"
38 #include "shmob_drm_drv.h"
39 #include "shmob_drm_kms.h"
40 #include "shmob_drm_plane.h"
41 #include "shmob_drm_regs.h"
42 
43 /* -----------------------------------------------------------------------------
44  * Page Flip
45  */
46 
shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc * scrtc)47 void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
48 {
49 	struct drm_pending_vblank_event *event;
50 	struct drm_device *dev = scrtc->base.dev;
51 	unsigned long flags;
52 
53 	spin_lock_irqsave(&dev->event_lock, flags);
54 	event = scrtc->event;
55 	scrtc->event = NULL;
56 	if (event) {
57 		drm_crtc_send_vblank_event(&scrtc->base, event);
58 		wake_up(&scrtc->flip_wait);
59 		drm_crtc_vblank_put(&scrtc->base);
60 	}
61 	spin_unlock_irqrestore(&dev->event_lock, flags);
62 }
63 
shmob_drm_crtc_page_flip_pending(struct shmob_drm_crtc * scrtc)64 static bool shmob_drm_crtc_page_flip_pending(struct shmob_drm_crtc *scrtc)
65 {
66 	struct drm_device *dev = scrtc->base.dev;
67 	unsigned long flags;
68 	bool pending;
69 
70 	spin_lock_irqsave(&dev->event_lock, flags);
71 	pending = scrtc->event != NULL;
72 	spin_unlock_irqrestore(&dev->event_lock, flags);
73 
74 	return pending;
75 }
76 
shmob_drm_crtc_wait_page_flip(struct shmob_drm_crtc * scrtc)77 static void shmob_drm_crtc_wait_page_flip(struct shmob_drm_crtc *scrtc)
78 {
79 	struct drm_crtc *crtc = &scrtc->base;
80 	struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
81 
82 	if (wait_event_timeout(scrtc->flip_wait,
83 			       !shmob_drm_crtc_page_flip_pending(scrtc),
84 			       msecs_to_jiffies(50)))
85 		return;
86 
87 	dev_warn(sdev->dev, "page flip timeout\n");
88 
89 	shmob_drm_crtc_finish_page_flip(scrtc);
90 }
91 
92 /* -----------------------------------------------------------------------------
93  * CRTC
94  */
95 
96 static const struct {
97 	u32 fmt;
98 	u32 ldmt1r;
99 } shmob_drm_bus_fmts[] = {
100 	{ MEDIA_BUS_FMT_RGB888_3X8,	 LDMT1R_MIFTYP_RGB8 },
101 	{ MEDIA_BUS_FMT_RGB666_2X9_BE,	 LDMT1R_MIFTYP_RGB9 },
102 	{ MEDIA_BUS_FMT_RGB888_2X12_BE,	 LDMT1R_MIFTYP_RGB12A },
103 	{ MEDIA_BUS_FMT_RGB444_1X12,	 LDMT1R_MIFTYP_RGB12B },
104 	{ MEDIA_BUS_FMT_RGB565_1X16,	 LDMT1R_MIFTYP_RGB16 },
105 	{ MEDIA_BUS_FMT_RGB666_1X18,	 LDMT1R_MIFTYP_RGB18 },
106 	{ MEDIA_BUS_FMT_RGB888_1X24,	 LDMT1R_MIFTYP_RGB24 },
107 	{ MEDIA_BUS_FMT_UYVY8_1X16,	 LDMT1R_MIFTYP_YCBCR },
108 };
109 
shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc * scrtc)110 static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc)
111 {
112 	struct drm_crtc *crtc = &scrtc->base;
113 	struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
114 	const struct drm_display_info *info = &sdev->connector->display_info;
115 	const struct drm_display_mode *mode = &crtc->mode;
116 	unsigned int i;
117 	u32 value;
118 
119 	if (!info->num_bus_formats || !info->bus_formats) {
120 		dev_warn(sdev->dev, "No bus format reported, using RGB888\n");
121 		value = LDMT1R_MIFTYP_RGB24;
122 	} else {
123 		for (i = 0; i < ARRAY_SIZE(shmob_drm_bus_fmts); i++) {
124 			if (shmob_drm_bus_fmts[i].fmt == info->bus_formats[0])
125 				break;
126 		}
127 		if (i < ARRAY_SIZE(shmob_drm_bus_fmts)) {
128 			value = shmob_drm_bus_fmts[i].ldmt1r;
129 		} else {
130 			dev_warn(sdev->dev,
131 				 "unsupported bus format 0x%x, using RGB888\n",
132 				 info->bus_formats[0]);
133 			value = LDMT1R_MIFTYP_RGB24;
134 		}
135 	}
136 
137 	if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
138 		value |= LDMT1R_DWPOL;
139 	if (info->bus_flags & DRM_BUS_FLAG_DE_LOW)
140 		value |= LDMT1R_DIPOL;
141 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
142 		value |= LDMT1R_VPOL;
143 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
144 		value |= LDMT1R_HPOL;
145 	lcdc_write(sdev, LDMT1R, value);
146 
147 	value = ((mode->hdisplay / 8) << 16)			/* HDCN */
148 	      | (mode->htotal / 8);				/* HTCN */
149 	lcdc_write(sdev, LDHCNR, value);
150 
151 	value = (((mode->hsync_end - mode->hsync_start) / 8) << 16) /* HSYNW */
152 	      | (mode->hsync_start / 8);			/* HSYNP */
153 	lcdc_write(sdev, LDHSYNR, value);
154 
155 	value = ((mode->hdisplay & 7) << 24) | ((mode->htotal & 7) << 16)
156 	      | (((mode->hsync_end - mode->hsync_start) & 7) << 8)
157 	      | (mode->hsync_start & 7);
158 	lcdc_write(sdev, LDHAJR, value);
159 
160 	value = ((mode->vdisplay) << 16)			/* VDLN */
161 	      | mode->vtotal;					/* VTLN */
162 	lcdc_write(sdev, LDVLNR, value);
163 
164 	value = ((mode->vsync_end - mode->vsync_start) << 16)	/* VSYNW */
165 	      | mode->vsync_start;				/* VSYNP */
166 	lcdc_write(sdev, LDVSYNR, value);
167 }
168 
shmob_drm_crtc_start_stop(struct shmob_drm_crtc * scrtc,bool start)169 static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool start)
170 {
171 	struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev);
172 	u32 value;
173 
174 	value = lcdc_read(sdev, LDCNT2R);
175 	if (start)
176 		lcdc_write(sdev, LDCNT2R, value | LDCNT2R_DO);
177 	else
178 		lcdc_write(sdev, LDCNT2R, value & ~LDCNT2R_DO);
179 
180 	/* Wait until power is applied/stopped. */
181 	while (1) {
182 		value = lcdc_read(sdev, LDPMR) & LDPMR_LPS;
183 		if ((start && value) || (!start && !value))
184 			break;
185 
186 		cpu_relax();
187 	}
188 
189 	if (!start) {
190 		/* Stop the dot clock. */
191 		lcdc_write(sdev, LDDCKSTPR, LDDCKSTPR_DCKSTP);
192 	}
193 }
194 
to_shmob_crtc(struct drm_crtc * crtc)195 static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc)
196 {
197 	return container_of(crtc, struct shmob_drm_crtc, base);
198 }
199 
shmob_drm_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_atomic_state * state)200 static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc,
201 					 struct drm_atomic_state *state)
202 {
203 	struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
204 	struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
205 	unsigned int clk_div = sdev->config.clk_div;
206 	struct device *dev = sdev->dev;
207 	u32 value;
208 	int ret;
209 
210 	ret = pm_runtime_resume_and_get(dev);
211 	if (ret)
212 		return;
213 
214 	/* Reset and enable the LCDC. */
215 	lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR);
216 	lcdc_wait_bit(sdev, LDCNT2R, LDCNT2R_BR, 0);
217 	lcdc_write(sdev, LDCNT2R, LDCNT2R_ME);
218 
219 	/* Stop the LCDC first and disable all interrupts. */
220 	shmob_drm_crtc_start_stop(scrtc, false);
221 	lcdc_write(sdev, LDINTR, 0);
222 
223 	/* Configure power supply, dot clocks and start them. */
224 	lcdc_write(sdev, LDPMR, 0);
225 
226 	value = sdev->lddckr;
227 	if (clk_div) {
228 		/* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
229 		 * denominator.
230 		 */
231 		lcdc_write(sdev, LDDCKPAT1R, 0);
232 		lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1);
233 
234 		if (clk_div == 1)
235 			value |= LDDCKR_MOSEL;
236 		else
237 			value |= clk_div;
238 	}
239 
240 	lcdc_write(sdev, LDDCKR, value);
241 	lcdc_write(sdev, LDDCKSTPR, 0);
242 	lcdc_wait_bit(sdev, LDDCKSTPR, ~0, 0);
243 
244 	/* Setup geometry, format, frame buffer memory and operation mode. */
245 	shmob_drm_crtc_setup_geometry(scrtc);
246 
247 	lcdc_write(sdev, LDSM1R, 0);
248 
249 	/* Enable the display output. */
250 	lcdc_write(sdev, LDCNT1R, LDCNT1R_DE);
251 
252 	shmob_drm_crtc_start_stop(scrtc, true);
253 
254 	/* Turn vertical blank interrupt reporting back on. */
255 	drm_crtc_vblank_on(crtc);
256 }
257 
shmob_drm_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_atomic_state * state)258 static void shmob_drm_crtc_atomic_disable(struct drm_crtc *crtc,
259 					  struct drm_atomic_state *state)
260 {
261 	struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
262 	struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
263 
264 	/*
265 	 * Disable vertical blank interrupt reporting.  We first need to wait
266 	 * for page flip completion before stopping the CRTC as userspace
267 	 * expects page flips to eventually complete.
268 	 */
269 	shmob_drm_crtc_wait_page_flip(scrtc);
270 	drm_crtc_vblank_off(crtc);
271 
272 	/* Stop the LCDC. */
273 	shmob_drm_crtc_start_stop(scrtc, false);
274 
275 	/* Disable the display output. */
276 	lcdc_write(sdev, LDCNT1R, 0);
277 
278 	pm_runtime_put(sdev->dev);
279 }
280 
shmob_drm_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_atomic_state * state)281 static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc,
282 					struct drm_atomic_state *state)
283 {
284 	struct drm_pending_vblank_event *event;
285 	struct drm_device *dev = crtc->dev;
286 	unsigned long flags;
287 
288 	if (crtc->state->event) {
289 		spin_lock_irqsave(&dev->event_lock, flags);
290 		event = crtc->state->event;
291 		crtc->state->event = NULL;
292 		drm_crtc_send_vblank_event(crtc, event);
293 		spin_unlock_irqrestore(&dev->event_lock, flags);
294 	}
295 }
296 
297 static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
298 	.atomic_flush = shmob_drm_crtc_atomic_flush,
299 	.atomic_enable = shmob_drm_crtc_atomic_enable,
300 	.atomic_disable = shmob_drm_crtc_atomic_disable,
301 };
302 
shmob_drm_crtc_page_flip(struct drm_crtc * crtc,struct drm_framebuffer * fb,struct drm_pending_vblank_event * event,uint32_t page_flip_flags,struct drm_modeset_acquire_ctx * ctx)303 static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
304 				    struct drm_framebuffer *fb,
305 				    struct drm_pending_vblank_event *event,
306 				    uint32_t page_flip_flags,
307 				    struct drm_modeset_acquire_ctx *ctx)
308 {
309 	struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
310 	struct drm_device *dev = scrtc->base.dev;
311 	unsigned long flags;
312 
313 	spin_lock_irqsave(&dev->event_lock, flags);
314 	if (scrtc->event != NULL) {
315 		spin_unlock_irqrestore(&dev->event_lock, flags);
316 		return -EBUSY;
317 	}
318 	spin_unlock_irqrestore(&dev->event_lock, flags);
319 
320 	drm_atomic_set_fb_for_plane(crtc->primary->state, fb);
321 
322 	if (event) {
323 		event->pipe = 0;
324 		drm_crtc_vblank_get(&scrtc->base);
325 		spin_lock_irqsave(&dev->event_lock, flags);
326 		scrtc->event = event;
327 		spin_unlock_irqrestore(&dev->event_lock, flags);
328 	}
329 
330 	return 0;
331 }
332 
shmob_drm_crtc_enable_vblank(struct shmob_drm_device * sdev,bool enable)333 static void shmob_drm_crtc_enable_vblank(struct shmob_drm_device *sdev,
334 					 bool enable)
335 {
336 	unsigned long flags;
337 	u32 ldintr;
338 
339 	/* Be careful not to acknowledge any pending interrupt. */
340 	spin_lock_irqsave(&sdev->irq_lock, flags);
341 	ldintr = lcdc_read(sdev, LDINTR) | LDINTR_STATUS_MASK;
342 	if (enable)
343 		ldintr |= LDINTR_VEE;
344 	else
345 		ldintr &= ~LDINTR_VEE;
346 	lcdc_write(sdev, LDINTR, ldintr);
347 	spin_unlock_irqrestore(&sdev->irq_lock, flags);
348 }
349 
shmob_drm_enable_vblank(struct drm_crtc * crtc)350 static int shmob_drm_enable_vblank(struct drm_crtc *crtc)
351 {
352 	struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
353 
354 	shmob_drm_crtc_enable_vblank(sdev, true);
355 
356 	return 0;
357 }
358 
shmob_drm_disable_vblank(struct drm_crtc * crtc)359 static void shmob_drm_disable_vblank(struct drm_crtc *crtc)
360 {
361 	struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
362 
363 	shmob_drm_crtc_enable_vblank(sdev, false);
364 }
365 
366 static const struct drm_crtc_funcs crtc_funcs = {
367 	.reset = drm_atomic_helper_crtc_reset,
368 	.destroy = drm_crtc_cleanup,
369 	.set_config = drm_atomic_helper_set_config,
370 	.page_flip = shmob_drm_crtc_page_flip,
371 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
372 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
373 	.enable_vblank = shmob_drm_enable_vblank,
374 	.disable_vblank = shmob_drm_disable_vblank,
375 };
376 
shmob_drm_crtc_create(struct shmob_drm_device * sdev)377 int shmob_drm_crtc_create(struct shmob_drm_device *sdev)
378 {
379 	struct drm_crtc *crtc = &sdev->crtc.base;
380 	struct drm_plane *primary, *plane;
381 	unsigned int i;
382 	int ret;
383 
384 	init_waitqueue_head(&sdev->crtc.flip_wait);
385 
386 	primary = shmob_drm_plane_create(sdev, DRM_PLANE_TYPE_PRIMARY, 0);
387 	if (IS_ERR(primary))
388 		return PTR_ERR(primary);
389 
390 	for (i = 1; i < 5; ++i) {
391 		plane = shmob_drm_plane_create(sdev, DRM_PLANE_TYPE_OVERLAY, i);
392 		if (IS_ERR(plane))
393 			return PTR_ERR(plane);
394 	}
395 
396 	ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL,
397 					&crtc_funcs, NULL);
398 	if (ret < 0)
399 		return ret;
400 
401 	drm_crtc_helper_add(crtc, &crtc_helper_funcs);
402 
403 	/* Start with vertical blank interrupt reporting disabled. */
404 	drm_crtc_vblank_off(crtc);
405 
406 	return 0;
407 }
408 
409 /* -----------------------------------------------------------------------------
410  * Legacy Encoder
411  */
412 
shmob_drm_encoder_mode_fixup(struct drm_encoder * encoder,const struct drm_display_mode * mode,struct drm_display_mode * adjusted_mode)413 static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
414 					 const struct drm_display_mode *mode,
415 					 struct drm_display_mode *adjusted_mode)
416 {
417 	struct drm_device *dev = encoder->dev;
418 	struct shmob_drm_device *sdev = to_shmob_device(dev);
419 	struct drm_connector *connector = sdev->connector;
420 	const struct drm_display_mode *panel_mode;
421 
422 	if (list_empty(&connector->modes)) {
423 		dev_dbg(dev->dev, "mode_fixup: empty modes list\n");
424 		return false;
425 	}
426 
427 	/* The flat panel mode is fixed, just copy it to the adjusted mode. */
428 	panel_mode = list_first_entry(&connector->modes,
429 				      struct drm_display_mode, head);
430 	drm_mode_copy(adjusted_mode, panel_mode);
431 
432 	return true;
433 }
434 
435 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
436 	.mode_fixup = shmob_drm_encoder_mode_fixup,
437 };
438 
439 /* -----------------------------------------------------------------------------
440  * Encoder
441  */
442 
shmob_drm_encoder_create(struct shmob_drm_device * sdev)443 int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
444 {
445 	struct drm_encoder *encoder = &sdev->encoder;
446 	struct drm_bridge *bridge;
447 	int ret;
448 
449 	encoder->possible_crtcs = 1;
450 
451 	ret = drm_simple_encoder_init(&sdev->ddev, encoder,
452 				      DRM_MODE_ENCODER_DPI);
453 	if (ret < 0)
454 		return ret;
455 
456 	if (sdev->pdata) {
457 		drm_encoder_helper_add(encoder, &encoder_helper_funcs);
458 		return 0;
459 	}
460 
461 	/* Create a panel bridge */
462 	bridge = devm_drm_of_get_bridge(sdev->dev, sdev->dev->of_node, 0, 0);
463 	if (IS_ERR(bridge))
464 		return PTR_ERR(bridge);
465 
466 	/* Attach the bridge to the encoder */
467 	ret = drm_bridge_attach(encoder, bridge, NULL,
468 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
469 	if (ret) {
470 		dev_err(sdev->dev, "failed to attach bridge: %pe\n",
471 			ERR_PTR(ret));
472 		return ret;
473 	}
474 
475 	return 0;
476 }
477 
478 /* -----------------------------------------------------------------------------
479  * Legacy Connector
480  */
481 
to_shmob_connector(struct drm_connector * connector)482 static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
483 {
484 	return container_of(connector, struct shmob_drm_connector, base);
485 }
486 
shmob_drm_connector_get_modes(struct drm_connector * connector)487 static int shmob_drm_connector_get_modes(struct drm_connector *connector)
488 {
489 	struct shmob_drm_connector *scon = to_shmob_connector(connector);
490 	struct drm_display_mode *mode;
491 
492 	mode = drm_mode_create(connector->dev);
493 	if (mode == NULL)
494 		return 0;
495 
496 	mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
497 
498 	drm_display_mode_from_videomode(scon->mode, mode);
499 
500 	drm_mode_probed_add(connector, mode);
501 
502 	return 1;
503 }
504 
505 static struct drm_encoder *
shmob_drm_connector_best_encoder(struct drm_connector * connector)506 shmob_drm_connector_best_encoder(struct drm_connector *connector)
507 {
508 	struct shmob_drm_connector *scon = to_shmob_connector(connector);
509 
510 	return scon->encoder;
511 }
512 
513 static const struct drm_connector_helper_funcs connector_helper_funcs = {
514 	.get_modes = shmob_drm_connector_get_modes,
515 	.best_encoder = shmob_drm_connector_best_encoder,
516 };
517 
shmob_drm_connector_destroy(struct drm_connector * connector)518 static void shmob_drm_connector_destroy(struct drm_connector *connector)
519 {
520 	drm_connector_unregister(connector);
521 	drm_connector_cleanup(connector);
522 
523 	kfree(connector);
524 }
525 
526 static const struct drm_connector_funcs connector_funcs = {
527 	.reset = drm_atomic_helper_connector_reset,
528 	.fill_modes = drm_helper_probe_single_connector_modes,
529 	.destroy = shmob_drm_connector_destroy,
530 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
531 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
532 };
533 
534 static struct drm_connector *
shmob_drm_connector_init(struct shmob_drm_device * sdev,struct drm_encoder * encoder)535 shmob_drm_connector_init(struct shmob_drm_device *sdev,
536 			 struct drm_encoder *encoder)
537 {
538 	u32 bus_fmt = sdev->pdata->iface.bus_fmt;
539 	struct shmob_drm_connector *scon;
540 	struct drm_connector *connector;
541 	struct drm_display_info *info;
542 	unsigned int i;
543 	int ret;
544 
545 	for (i = 0; i < ARRAY_SIZE(shmob_drm_bus_fmts); i++) {
546 		if (shmob_drm_bus_fmts[i].fmt == bus_fmt)
547 			break;
548 	}
549 	if (i == ARRAY_SIZE(shmob_drm_bus_fmts)) {
550 		dev_err(sdev->dev, "unsupported bus format 0x%x\n", bus_fmt);
551 		return ERR_PTR(-EINVAL);
552 	}
553 
554 	scon = kzalloc(sizeof(*scon), GFP_KERNEL);
555 	if (!scon)
556 		return ERR_PTR(-ENOMEM);
557 
558 	connector = &scon->base;
559 	scon->encoder = encoder;
560 	scon->mode = &sdev->pdata->panel.mode;
561 
562 	info = &connector->display_info;
563 	info->width_mm = sdev->pdata->panel.width_mm;
564 	info->height_mm = sdev->pdata->panel.height_mm;
565 
566 	if (scon->mode->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
567 		info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
568 	if (scon->mode->flags & DISPLAY_FLAGS_DE_LOW)
569 		info->bus_flags |= DRM_BUS_FLAG_DE_LOW;
570 
571 	ret = drm_display_info_set_bus_formats(info, &bus_fmt, 1);
572 	if (ret < 0) {
573 		kfree(scon);
574 		return ERR_PTR(ret);
575 	}
576 
577 	ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs,
578 				 DRM_MODE_CONNECTOR_DPI);
579 	if (ret < 0) {
580 		kfree(scon);
581 		return ERR_PTR(ret);
582 	}
583 
584 	drm_connector_helper_add(connector, &connector_helper_funcs);
585 
586 	return connector;
587 }
588 
589 /* -----------------------------------------------------------------------------
590  * Connector
591  */
592 
shmob_drm_connector_create(struct shmob_drm_device * sdev,struct drm_encoder * encoder)593 int shmob_drm_connector_create(struct shmob_drm_device *sdev,
594 			       struct drm_encoder *encoder)
595 {
596 	struct drm_connector *connector;
597 	int ret;
598 
599 	if (sdev->pdata)
600 		connector = shmob_drm_connector_init(sdev, encoder);
601 	else
602 		connector = drm_bridge_connector_init(&sdev->ddev, encoder);
603 	if (IS_ERR(connector)) {
604 		dev_err(sdev->dev, "failed to created connector: %pe\n",
605 			connector);
606 		return PTR_ERR(connector);
607 	}
608 
609 	ret = drm_connector_attach_encoder(connector, encoder);
610 	if (ret < 0)
611 		goto error;
612 
613 	connector->dpms = DRM_MODE_DPMS_OFF;
614 
615 	sdev->connector = connector;
616 
617 	return 0;
618 
619 error:
620 	drm_connector_cleanup(connector);
621 	return ret;
622 }
623