armada_crtc.c revision 178e561f514fca4863c06a4af3501172e5627eb1
1/*
2 * Copyright (C) 2012 Russell King
3 *  Rewritten from the dovefb driver, and Armada510 manuals.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/clk.h>
10#include <linux/component.h>
11#include <linux/of_device.h>
12#include <linux/platform_device.h>
13#include <drm/drmP.h>
14#include <drm/drm_crtc_helper.h>
15#include "armada_crtc.h"
16#include "armada_drm.h"
17#include "armada_fb.h"
18#include "armada_gem.h"
19#include "armada_hw.h"
20
21struct armada_frame_work {
22	struct drm_pending_vblank_event *event;
23	struct armada_regs regs[4];
24	struct drm_framebuffer *old_fb;
25};
26
27enum csc_mode {
28	CSC_AUTO = 0,
29	CSC_YUV_CCIR601 = 1,
30	CSC_YUV_CCIR709 = 2,
31	CSC_RGB_COMPUTER = 1,
32	CSC_RGB_STUDIO = 2,
33};
34
35/*
36 * A note about interlacing.  Let's consider HDMI 1920x1080i.
37 * The timing parameters we have from X are:
38 *  Hact HsyA HsyI Htot  Vact VsyA VsyI Vtot
39 *  1920 2448 2492 2640  1080 1084 1094 1125
40 * Which get translated to:
41 *  Hact HsyA HsyI Htot  Vact VsyA VsyI Vtot
42 *  1920 2448 2492 2640   540  542  547  562
43 *
44 * This is how it is defined by CEA-861-D - line and pixel numbers are
45 * referenced to the rising edge of VSYNC and HSYNC.  Total clocks per
46 * line: 2640.  The odd frame, the first active line is at line 21, and
47 * the even frame, the first active line is 584.
48 *
49 * LN:    560     561     562     563             567     568    569
50 * DE:    ~~~|____________________________//__________________________
51 * HSYNC: ____|~|_____|~|_____|~|_____|~|_//__|~|_____|~|_____|~|_____
52 * VSYNC: _________________________|~~~~~~//~~~~~~~~~~~~~~~|__________
53 *  22 blanking lines.  VSYNC at 1320 (referenced to the HSYNC rising edge).
54 *
55 * LN:    1123   1124    1125      1               5       6      7
56 * DE:    ~~~|____________________________//__________________________
57 * HSYNC: ____|~|_____|~|_____|~|_____|~|_//__|~|_____|~|_____|~|_____
58 * VSYNC: ____________________|~~~~~~~~~~~//~~~~~~~~~~|_______________
59 *  23 blanking lines
60 *
61 * The Armada LCD Controller line and pixel numbers are, like X timings,
62 * referenced to the top left of the active frame.
63 *
64 * So, translating these to our LCD controller:
65 *  Odd frame, 563 total lines, VSYNC at line 543-548, pixel 1128.
66 *  Even frame, 562 total lines, VSYNC at line 542-547, pixel 2448.
67 * Note: Vsync front porch remains constant!
68 *
69 * if (odd_frame) {
70 *   vtotal = mode->crtc_vtotal + 1;
71 *   vbackporch = mode->crtc_vsync_start - mode->crtc_vdisplay + 1;
72 *   vhorizpos = mode->crtc_hsync_start - mode->crtc_htotal / 2
73 * } else {
74 *   vtotal = mode->crtc_vtotal;
75 *   vbackporch = mode->crtc_vsync_start - mode->crtc_vdisplay;
76 *   vhorizpos = mode->crtc_hsync_start;
77 * }
78 * vfrontporch = mode->crtc_vtotal - mode->crtc_vsync_end;
79 *
80 * So, we need to reprogram these registers on each vsync event:
81 *  LCD_SPU_V_PORCH, LCD_SPU_ADV_REG, LCD_SPUT_V_H_TOTAL
82 *
83 * Note: we do not use the frame done interrupts because these appear
84 * to happen too early, and lead to jitter on the display (presumably
85 * they occur at the end of the last active line, before the vsync back
86 * porch, which we're reprogramming.)
87 */
88
89void
90armada_drm_crtc_update_regs(struct armada_crtc *dcrtc, struct armada_regs *regs)
91{
92	while (regs->offset != ~0) {
93		void __iomem *reg = dcrtc->base + regs->offset;
94		uint32_t val;
95
96		val = regs->mask;
97		if (val != 0)
98			val &= readl_relaxed(reg);
99		writel_relaxed(val | regs->val, reg);
100		++regs;
101	}
102}
103
104#define dpms_blanked(dpms)	((dpms) != DRM_MODE_DPMS_ON)
105
106static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
107{
108	uint32_t dumb_ctrl;
109
110	dumb_ctrl = dcrtc->cfg_dumb_ctrl;
111
112	if (!dpms_blanked(dcrtc->dpms))
113		dumb_ctrl |= CFG_DUMB_ENA;
114
115	/*
116	 * When the dumb interface isn't in DUMB24_RGB888_0 mode, it might
117	 * be using SPI or GPIO.  If we set this to DUMB_BLANK, we will
118	 * force LCD_D[23:0] to output blank color, overriding the GPIO or
119	 * SPI usage.  So leave it as-is unless in DUMB24_RGB888_0 mode.
120	 */
121	if (dpms_blanked(dcrtc->dpms) &&
122	    (dumb_ctrl & DUMB_MASK) == DUMB24_RGB888_0) {
123		dumb_ctrl &= ~DUMB_MASK;
124		dumb_ctrl |= DUMB_BLANK;
125	}
126
127	/*
128	 * The documentation doesn't indicate what the normal state of
129	 * the sync signals are.  Sebastian Hesselbart kindly probed
130	 * these signals on his board to determine their state.
131	 *
132	 * The non-inverted state of the sync signals is active high.
133	 * Setting these bits makes the appropriate signal active low.
134	 */
135	if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NCSYNC)
136		dumb_ctrl |= CFG_INV_CSYNC;
137	if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NHSYNC)
138		dumb_ctrl |= CFG_INV_HSYNC;
139	if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NVSYNC)
140		dumb_ctrl |= CFG_INV_VSYNC;
141
142	if (dcrtc->dumb_ctrl != dumb_ctrl) {
143		dcrtc->dumb_ctrl = dumb_ctrl;
144		writel_relaxed(dumb_ctrl, dcrtc->base + LCD_SPU_DUMB_CTRL);
145	}
146}
147
148static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
149	int x, int y, struct armada_regs *regs, bool interlaced)
150{
151	struct armada_gem_object *obj = drm_fb_obj(fb);
152	unsigned pitch = fb->pitches[0];
153	unsigned offset = y * pitch + x * fb->bits_per_pixel / 8;
154	uint32_t addr_odd, addr_even;
155	unsigned i = 0;
156
157	DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n",
158		pitch, x, y, fb->bits_per_pixel);
159
160	addr_odd = addr_even = obj->dev_addr + offset;
161
162	if (interlaced) {
163		addr_even += pitch;
164		pitch *= 2;
165	}
166
167	/* write offset, base, and pitch */
168	armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0);
169	armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1);
170	armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH);
171
172	return i;
173}
174
175static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
176	struct armada_frame_work *work)
177{
178	struct drm_device *dev = dcrtc->crtc.dev;
179	unsigned long flags;
180	int ret;
181
182	ret = drm_vblank_get(dev, dcrtc->num);
183	if (ret) {
184		DRM_ERROR("failed to acquire vblank counter\n");
185		return ret;
186	}
187
188	spin_lock_irqsave(&dev->event_lock, flags);
189	if (!dcrtc->frame_work)
190		dcrtc->frame_work = work;
191	else
192		ret = -EBUSY;
193	spin_unlock_irqrestore(&dev->event_lock, flags);
194
195	if (ret)
196		drm_vblank_put(dev, dcrtc->num);
197
198	return ret;
199}
200
201static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc)
202{
203	struct drm_device *dev = dcrtc->crtc.dev;
204	struct armada_frame_work *work = dcrtc->frame_work;
205
206	dcrtc->frame_work = NULL;
207
208	armada_drm_crtc_update_regs(dcrtc, work->regs);
209
210	if (work->event)
211		drm_send_vblank_event(dev, dcrtc->num, work->event);
212
213	drm_vblank_put(dev, dcrtc->num);
214
215	/* Finally, queue the process-half of the cleanup. */
216	__armada_drm_queue_unref_work(dcrtc->crtc.dev, work->old_fb);
217	kfree(work);
218}
219
220static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
221	struct drm_framebuffer *fb, bool force)
222{
223	struct armada_frame_work *work;
224
225	if (!fb)
226		return;
227
228	if (force) {
229		/* Display is disabled, so just drop the old fb */
230		drm_framebuffer_unreference(fb);
231		return;
232	}
233
234	work = kmalloc(sizeof(*work), GFP_KERNEL);
235	if (work) {
236		int i = 0;
237		work->event = NULL;
238		work->old_fb = fb;
239		armada_reg_queue_end(work->regs, i);
240
241		if (armada_drm_crtc_queue_frame_work(dcrtc, work) == 0)
242			return;
243
244		kfree(work);
245	}
246
247	/*
248	 * Oops - just drop the reference immediately and hope for
249	 * the best.  The worst that will happen is the buffer gets
250	 * reused before it has finished being displayed.
251	 */
252	drm_framebuffer_unreference(fb);
253}
254
255static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
256{
257	struct drm_device *dev = dcrtc->crtc.dev;
258
259	/*
260	 * Tell the DRM core that vblank IRQs aren't going to happen for
261	 * a while.  This cleans up any pending vblank events for us.
262	 */
263	drm_crtc_vblank_off(&dcrtc->crtc);
264
265	/* Handle any pending flip event. */
266	spin_lock_irq(&dev->event_lock);
267	if (dcrtc->frame_work)
268		armada_drm_crtc_complete_frame_work(dcrtc);
269	spin_unlock_irq(&dev->event_lock);
270}
271
272void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
273	int idx)
274{
275}
276
277void armada_drm_crtc_gamma_get(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
278	int idx)
279{
280}
281
282/* The mode_config.mutex will be held for this call */
283static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
284{
285	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
286
287	if (dcrtc->dpms != dpms) {
288		dcrtc->dpms = dpms;
289		armada_drm_crtc_update(dcrtc);
290		if (dpms_blanked(dpms))
291			armada_drm_vblank_off(dcrtc);
292		else
293			drm_crtc_vblank_on(&dcrtc->crtc);
294	}
295}
296
297/*
298 * Prepare for a mode set.  Turn off overlay to ensure that we don't end
299 * up with the overlay size being bigger than the active screen size.
300 * We rely upon X refreshing this state after the mode set has completed.
301 *
302 * The mode_config.mutex will be held for this call
303 */
304static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
305{
306	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
307	struct drm_plane *plane;
308
309	/*
310	 * If we have an overlay plane associated with this CRTC, disable
311	 * it before the modeset to avoid its coordinates being outside
312	 * the new mode parameters.  DRM doesn't provide help with this.
313	 */
314	plane = dcrtc->plane;
315	if (plane) {
316		struct drm_framebuffer *fb = plane->fb;
317
318		plane->funcs->disable_plane(plane);
319		plane->fb = NULL;
320		plane->crtc = NULL;
321		drm_framebuffer_unreference(fb);
322	}
323}
324
325/* The mode_config.mutex will be held for this call */
326static void armada_drm_crtc_commit(struct drm_crtc *crtc)
327{
328	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
329
330	if (dcrtc->dpms != DRM_MODE_DPMS_ON) {
331		dcrtc->dpms = DRM_MODE_DPMS_ON;
332		armada_drm_crtc_update(dcrtc);
333	}
334}
335
336/* The mode_config.mutex will be held for this call */
337static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
338	const struct drm_display_mode *mode, struct drm_display_mode *adj)
339{
340	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
341	int ret;
342
343	/* We can't do interlaced modes if we don't have the SPU_ADV_REG */
344	if (!dcrtc->variant->has_spu_adv_reg &&
345	    adj->flags & DRM_MODE_FLAG_INTERLACE)
346		return false;
347
348	/* Check whether the display mode is possible */
349	ret = dcrtc->variant->compute_clock(dcrtc, adj, NULL);
350	if (ret)
351		return false;
352
353	return true;
354}
355
356static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
357{
358	struct armada_vbl_event *e, *n;
359	void __iomem *base = dcrtc->base;
360
361	if (stat & DMA_FF_UNDERFLOW)
362		DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
363	if (stat & GRA_FF_UNDERFLOW)
364		DRM_ERROR("graphics underflow on crtc %u\n", dcrtc->num);
365
366	if (stat & VSYNC_IRQ)
367		drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);
368
369	spin_lock(&dcrtc->irq_lock);
370
371	list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
372		list_del_init(&e->node);
373		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
374		e->fn(dcrtc, e->data);
375	}
376
377	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
378		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
379		uint32_t val;
380
381		writel_relaxed(dcrtc->v[i].spu_v_porch, base + LCD_SPU_V_PORCH);
382		writel_relaxed(dcrtc->v[i].spu_v_h_total,
383			       base + LCD_SPUT_V_H_TOTAL);
384
385		val = readl_relaxed(base + LCD_SPU_ADV_REG);
386		val &= ~(ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF | ADV_VSYNCOFFEN);
387		val |= dcrtc->v[i].spu_adv_reg;
388		writel_relaxed(val, base + LCD_SPU_ADV_REG);
389	}
390
391	if (stat & DUMB_FRAMEDONE && dcrtc->cursor_update) {
392		writel_relaxed(dcrtc->cursor_hw_pos,
393			       base + LCD_SPU_HWC_OVSA_HPXL_VLN);
394		writel_relaxed(dcrtc->cursor_hw_sz,
395			       base + LCD_SPU_HWC_HPXL_VLN);
396		armada_updatel(CFG_HWC_ENA,
397			       CFG_HWC_ENA | CFG_HWC_1BITMOD | CFG_HWC_1BITENA,
398			       base + LCD_SPU_DMA_CTRL0);
399		dcrtc->cursor_update = false;
400		armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
401	}
402
403	spin_unlock(&dcrtc->irq_lock);
404
405	if (stat & GRA_FRAME_IRQ) {
406		struct drm_device *dev = dcrtc->crtc.dev;
407
408		spin_lock(&dev->event_lock);
409		if (dcrtc->frame_work)
410			armada_drm_crtc_complete_frame_work(dcrtc);
411		spin_unlock(&dev->event_lock);
412
413		wake_up(&dcrtc->frame_wait);
414	}
415}
416
417static irqreturn_t armada_drm_irq(int irq, void *arg)
418{
419	struct armada_crtc *dcrtc = arg;
420	u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
421
422	/*
423	 * This is rediculous - rather than writing bits to clear, we
424	 * have to set the actual status register value.  This is racy.
425	 */
426	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
427
428	/* Mask out those interrupts we haven't enabled */
429	v = stat & dcrtc->irq_ena;
430
431	if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
432		armada_drm_crtc_irq(dcrtc, stat);
433		return IRQ_HANDLED;
434	}
435	return IRQ_NONE;
436}
437
438/* These are locked by dev->vbl_lock */
439void armada_drm_crtc_disable_irq(struct armada_crtc *dcrtc, u32 mask)
440{
441	if (dcrtc->irq_ena & mask) {
442		dcrtc->irq_ena &= ~mask;
443		writel(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
444	}
445}
446
447void armada_drm_crtc_enable_irq(struct armada_crtc *dcrtc, u32 mask)
448{
449	if ((dcrtc->irq_ena & mask) != mask) {
450		dcrtc->irq_ena |= mask;
451		writel(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
452		if (readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR) & mask)
453			writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
454	}
455}
456
457static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc)
458{
459	struct drm_display_mode *adj = &dcrtc->crtc.mode;
460	uint32_t val = 0;
461
462	if (dcrtc->csc_yuv_mode == CSC_YUV_CCIR709)
463		val |= CFG_CSC_YUV_CCIR709;
464	if (dcrtc->csc_rgb_mode == CSC_RGB_STUDIO)
465		val |= CFG_CSC_RGB_STUDIO;
466
467	/*
468	 * In auto mode, set the colorimetry, based upon the HDMI spec.
469	 * 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use
470	 * ITU601.  It may be more appropriate to set this depending on
471	 * the source - but what if the graphic frame is YUV and the
472	 * video frame is RGB?
473	 */
474	if ((adj->hdisplay == 1280 && adj->vdisplay == 720 &&
475	     !(adj->flags & DRM_MODE_FLAG_INTERLACE)) ||
476	    (adj->hdisplay == 1920 && adj->vdisplay == 1080)) {
477		if (dcrtc->csc_yuv_mode == CSC_AUTO)
478			val |= CFG_CSC_YUV_CCIR709;
479	}
480
481	/*
482	 * We assume we're connected to a TV-like device, so the YUV->RGB
483	 * conversion should produce a limited range.  We should set this
484	 * depending on the connectors attached to this CRTC, and what
485	 * kind of device they report being connected.
486	 */
487	if (dcrtc->csc_rgb_mode == CSC_AUTO)
488		val |= CFG_CSC_RGB_STUDIO;
489
490	return val;
491}
492
493/* The mode_config.mutex will be held for this call */
494static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
495	struct drm_display_mode *mode, struct drm_display_mode *adj,
496	int x, int y, struct drm_framebuffer *old_fb)
497{
498	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
499	struct armada_regs regs[17];
500	uint32_t lm, rm, tm, bm, val, sclk;
501	unsigned long flags;
502	unsigned i;
503	bool interlaced;
504
505	drm_framebuffer_reference(crtc->primary->fb);
506
507	interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
508
509	i = armada_drm_crtc_calc_fb(dcrtc->crtc.primary->fb,
510				    x, y, regs, interlaced);
511
512	rm = adj->crtc_hsync_start - adj->crtc_hdisplay;
513	lm = adj->crtc_htotal - adj->crtc_hsync_end;
514	bm = adj->crtc_vsync_start - adj->crtc_vdisplay;
515	tm = adj->crtc_vtotal - adj->crtc_vsync_end;
516
517	DRM_DEBUG_DRIVER("H: %d %d %d %d lm %d rm %d\n",
518		adj->crtc_hdisplay,
519		adj->crtc_hsync_start,
520		adj->crtc_hsync_end,
521		adj->crtc_htotal, lm, rm);
522	DRM_DEBUG_DRIVER("V: %d %d %d %d tm %d bm %d\n",
523		adj->crtc_vdisplay,
524		adj->crtc_vsync_start,
525		adj->crtc_vsync_end,
526		adj->crtc_vtotal, tm, bm);
527
528	/* Wait for pending flips to complete */
529	wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
530
531	drm_crtc_vblank_off(crtc);
532
533	crtc->mode = *adj;
534
535	val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA;
536	if (val != dcrtc->dumb_ctrl) {
537		dcrtc->dumb_ctrl = val;
538		writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
539	}
540
541	/* Now compute the divider for real */
542	dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
543
544	/* Ensure graphic fifo is enabled */
545	armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
546	armada_reg_queue_set(regs, i, sclk, LCD_CFG_SCLK_DIV);
547
548	if (interlaced ^ dcrtc->interlaced) {
549		if (adj->flags & DRM_MODE_FLAG_INTERLACE)
550			drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
551		else
552			drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
553		dcrtc->interlaced = interlaced;
554	}
555
556	spin_lock_irqsave(&dcrtc->irq_lock, flags);
557
558	/* Even interlaced/progressive frame */
559	dcrtc->v[1].spu_v_h_total = adj->crtc_vtotal << 16 |
560				    adj->crtc_htotal;
561	dcrtc->v[1].spu_v_porch = tm << 16 | bm;
562	val = adj->crtc_hsync_start;
563	dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
564		dcrtc->variant->spu_adv_reg;
565
566	if (interlaced) {
567		/* Odd interlaced frame */
568		dcrtc->v[0].spu_v_h_total = dcrtc->v[1].spu_v_h_total +
569						(1 << 16);
570		dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
571		val = adj->crtc_hsync_start - adj->crtc_htotal / 2;
572		dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
573			dcrtc->variant->spu_adv_reg;
574	} else {
575		dcrtc->v[0] = dcrtc->v[1];
576	}
577
578	val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay;
579
580	armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE);
581	armada_reg_queue_set(regs, i, val, LCD_SPU_GRA_HPXL_VLN);
582	armada_reg_queue_set(regs, i, val, LCD_SPU_GZM_HPXL_VLN);
583	armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH);
584	armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH);
585	armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
586			   LCD_SPUT_V_H_TOTAL);
587
588	if (dcrtc->variant->has_spu_adv_reg) {
589		armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
590				     ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
591				     ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
592	}
593
594	val = CFG_GRA_ENA | CFG_GRA_HSMOOTH;
595	val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt);
596	val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod);
597
598	if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420)
599		val |= CFG_PALETTE_ENA;
600
601	if (interlaced)
602		val |= CFG_GRA_FTOGGLE;
603
604	armada_reg_queue_mod(regs, i, val, CFG_GRAFORMAT |
605			     CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
606					 CFG_SWAPYU | CFG_YUV2RGB) |
607			     CFG_PALETTE_ENA | CFG_GRA_FTOGGLE,
608			     LCD_SPU_DMA_CTRL0);
609
610	val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
611	armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
612
613	val = dcrtc->spu_iopad_ctrl | armada_drm_crtc_calculate_csc(dcrtc);
614	armada_reg_queue_set(regs, i, val, LCD_SPU_IOPAD_CONTROL);
615	armada_reg_queue_end(regs, i);
616
617	armada_drm_crtc_update_regs(dcrtc, regs);
618	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
619
620	armada_drm_crtc_update(dcrtc);
621
622	drm_crtc_vblank_on(crtc);
623	armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
624
625	return 0;
626}
627
628/* The mode_config.mutex will be held for this call */
629static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
630	struct drm_framebuffer *old_fb)
631{
632	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
633	struct armada_regs regs[4];
634	unsigned i;
635
636	i = armada_drm_crtc_calc_fb(crtc->primary->fb, crtc->x, crtc->y, regs,
637				    dcrtc->interlaced);
638	armada_reg_queue_end(regs, i);
639
640	/* Wait for pending flips to complete */
641	wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
642
643	/* Take a reference to the new fb as we're using it */
644	drm_framebuffer_reference(crtc->primary->fb);
645
646	/* Update the base in the CRTC */
647	armada_drm_crtc_update_regs(dcrtc, regs);
648
649	/* Drop our previously held reference */
650	armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
651
652	return 0;
653}
654
655static void armada_drm_crtc_load_lut(struct drm_crtc *crtc)
656{
657}
658
659/* The mode_config.mutex will be held for this call */
660static void armada_drm_crtc_disable(struct drm_crtc *crtc)
661{
662	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
663
664	armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
665	armada_drm_crtc_finish_fb(dcrtc, crtc->primary->fb, true);
666
667	/* Power down most RAMs and FIFOs */
668	writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
669		       CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
670		       CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
671}
672
673static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
674	.dpms		= armada_drm_crtc_dpms,
675	.prepare	= armada_drm_crtc_prepare,
676	.commit		= armada_drm_crtc_commit,
677	.mode_fixup	= armada_drm_crtc_mode_fixup,
678	.mode_set	= armada_drm_crtc_mode_set,
679	.mode_set_base	= armada_drm_crtc_mode_set_base,
680	.load_lut	= armada_drm_crtc_load_lut,
681	.disable	= armada_drm_crtc_disable,
682};
683
684static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix,
685	unsigned stride, unsigned width, unsigned height)
686{
687	uint32_t addr;
688	unsigned y;
689
690	addr = SRAM_HWC32_RAM1;
691	for (y = 0; y < height; y++) {
692		uint32_t *p = &pix[y * stride];
693		unsigned x;
694
695		for (x = 0; x < width; x++, p++) {
696			uint32_t val = *p;
697
698			val = (val & 0xff00ff00) |
699			      (val & 0x000000ff) << 16 |
700			      (val & 0x00ff0000) >> 16;
701
702			writel_relaxed(val,
703				       base + LCD_SPU_SRAM_WRDAT);
704			writel_relaxed(addr | SRAM_WRITE,
705				       base + LCD_SPU_SRAM_CTRL);
706			readl_relaxed(base + LCD_SPU_HWC_OVSA_HPXL_VLN);
707			addr += 1;
708			if ((addr & 0x00ff) == 0)
709				addr += 0xf00;
710			if ((addr & 0x30ff) == 0)
711				addr = SRAM_HWC32_RAM2;
712		}
713	}
714}
715
716static void armada_drm_crtc_cursor_tran(void __iomem *base)
717{
718	unsigned addr;
719
720	for (addr = 0; addr < 256; addr++) {
721		/* write the default value */
722		writel_relaxed(0x55555555, base + LCD_SPU_SRAM_WRDAT);
723		writel_relaxed(addr | SRAM_WRITE | SRAM_HWC32_TRAN,
724			       base + LCD_SPU_SRAM_CTRL);
725	}
726}
727
728static int armada_drm_crtc_cursor_update(struct armada_crtc *dcrtc, bool reload)
729{
730	uint32_t xoff, xscr, w = dcrtc->cursor_w, s;
731	uint32_t yoff, yscr, h = dcrtc->cursor_h;
732	uint32_t para1;
733
734	/*
735	 * Calculate the visible width and height of the cursor,
736	 * screen position, and the position in the cursor bitmap.
737	 */
738	if (dcrtc->cursor_x < 0) {
739		xoff = -dcrtc->cursor_x;
740		xscr = 0;
741		w -= min(xoff, w);
742	} else if (dcrtc->cursor_x + w > dcrtc->crtc.mode.hdisplay) {
743		xoff = 0;
744		xscr = dcrtc->cursor_x;
745		w = max_t(int, dcrtc->crtc.mode.hdisplay - dcrtc->cursor_x, 0);
746	} else {
747		xoff = 0;
748		xscr = dcrtc->cursor_x;
749	}
750
751	if (dcrtc->cursor_y < 0) {
752		yoff = -dcrtc->cursor_y;
753		yscr = 0;
754		h -= min(yoff, h);
755	} else if (dcrtc->cursor_y + h > dcrtc->crtc.mode.vdisplay) {
756		yoff = 0;
757		yscr = dcrtc->cursor_y;
758		h = max_t(int, dcrtc->crtc.mode.vdisplay - dcrtc->cursor_y, 0);
759	} else {
760		yoff = 0;
761		yscr = dcrtc->cursor_y;
762	}
763
764	/* On interlaced modes, the vertical cursor size must be halved */
765	s = dcrtc->cursor_w;
766	if (dcrtc->interlaced) {
767		s *= 2;
768		yscr /= 2;
769		h /= 2;
770	}
771
772	if (!dcrtc->cursor_obj || !h || !w) {
773		spin_lock_irq(&dcrtc->irq_lock);
774		armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
775		dcrtc->cursor_update = false;
776		armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
777		spin_unlock_irq(&dcrtc->irq_lock);
778		return 0;
779	}
780
781	para1 = readl_relaxed(dcrtc->base + LCD_SPU_SRAM_PARA1);
782	armada_updatel(CFG_CSB_256x32, CFG_CSB_256x32 | CFG_PDWN256x32,
783		       dcrtc->base + LCD_SPU_SRAM_PARA1);
784
785	/*
786	 * Initialize the transparency if the SRAM was powered down.
787	 * We must also reload the cursor data as well.
788	 */
789	if (!(para1 & CFG_CSB_256x32)) {
790		armada_drm_crtc_cursor_tran(dcrtc->base);
791		reload = true;
792	}
793
794	if (dcrtc->cursor_hw_sz != (h << 16 | w)) {
795		spin_lock_irq(&dcrtc->irq_lock);
796		armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
797		dcrtc->cursor_update = false;
798		armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
799		spin_unlock_irq(&dcrtc->irq_lock);
800		reload = true;
801	}
802	if (reload) {
803		struct armada_gem_object *obj = dcrtc->cursor_obj;
804		uint32_t *pix;
805		/* Set the top-left corner of the cursor image */
806		pix = obj->addr;
807		pix += yoff * s + xoff;
808		armada_load_cursor_argb(dcrtc->base, pix, s, w, h);
809	}
810
811	/* Reload the cursor position, size and enable in the IRQ handler */
812	spin_lock_irq(&dcrtc->irq_lock);
813	dcrtc->cursor_hw_pos = yscr << 16 | xscr;
814	dcrtc->cursor_hw_sz = h << 16 | w;
815	dcrtc->cursor_update = true;
816	armada_drm_crtc_enable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
817	spin_unlock_irq(&dcrtc->irq_lock);
818
819	return 0;
820}
821
822static void cursor_update(void *data)
823{
824	armada_drm_crtc_cursor_update(data, true);
825}
826
827static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
828	struct drm_file *file, uint32_t handle, uint32_t w, uint32_t h)
829{
830	struct drm_device *dev = crtc->dev;
831	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
832	struct armada_gem_object *obj = NULL;
833	int ret;
834
835	/* If no cursor support, replicate drm's return value */
836	if (!dcrtc->variant->has_spu_adv_reg)
837		return -ENXIO;
838
839	if (handle && w > 0 && h > 0) {
840		/* maximum size is 64x32 or 32x64 */
841		if (w > 64 || h > 64 || (w > 32 && h > 32))
842			return -ENOMEM;
843
844		obj = armada_gem_object_lookup(dev, file, handle);
845		if (!obj)
846			return -ENOENT;
847
848		/* Must be a kernel-mapped object */
849		if (!obj->addr) {
850			drm_gem_object_unreference_unlocked(&obj->obj);
851			return -EINVAL;
852		}
853
854		if (obj->obj.size < w * h * 4) {
855			DRM_ERROR("buffer is too small\n");
856			drm_gem_object_unreference_unlocked(&obj->obj);
857			return -ENOMEM;
858		}
859	}
860
861	mutex_lock(&dev->struct_mutex);
862	if (dcrtc->cursor_obj) {
863		dcrtc->cursor_obj->update = NULL;
864		dcrtc->cursor_obj->update_data = NULL;
865		drm_gem_object_unreference(&dcrtc->cursor_obj->obj);
866	}
867	dcrtc->cursor_obj = obj;
868	dcrtc->cursor_w = w;
869	dcrtc->cursor_h = h;
870	ret = armada_drm_crtc_cursor_update(dcrtc, true);
871	if (obj) {
872		obj->update_data = dcrtc;
873		obj->update = cursor_update;
874	}
875	mutex_unlock(&dev->struct_mutex);
876
877	return ret;
878}
879
880static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
881{
882	struct drm_device *dev = crtc->dev;
883	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
884	int ret;
885
886	/* If no cursor support, replicate drm's return value */
887	if (!dcrtc->variant->has_spu_adv_reg)
888		return -EFAULT;
889
890	mutex_lock(&dev->struct_mutex);
891	dcrtc->cursor_x = x;
892	dcrtc->cursor_y = y;
893	ret = armada_drm_crtc_cursor_update(dcrtc, false);
894	mutex_unlock(&dev->struct_mutex);
895
896	return ret;
897}
898
899static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
900{
901	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
902	struct armada_private *priv = crtc->dev->dev_private;
903
904	if (dcrtc->cursor_obj)
905		drm_gem_object_unreference(&dcrtc->cursor_obj->obj);
906
907	priv->dcrtc[dcrtc->num] = NULL;
908	drm_crtc_cleanup(&dcrtc->crtc);
909
910	if (!IS_ERR(dcrtc->clk))
911		clk_disable_unprepare(dcrtc->clk);
912
913	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
914
915	of_node_put(dcrtc->crtc.port);
916
917	kfree(dcrtc);
918}
919
920/*
921 * The mode_config lock is held here, to prevent races between this
922 * and a mode_set.
923 */
924static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
925	struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
926{
927	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
928	struct armada_frame_work *work;
929	struct drm_device *dev = crtc->dev;
930	unsigned long flags;
931	unsigned i;
932	int ret;
933
934	/* We don't support changing the pixel format */
935	if (fb->pixel_format != crtc->primary->fb->pixel_format)
936		return -EINVAL;
937
938	work = kmalloc(sizeof(*work), GFP_KERNEL);
939	if (!work)
940		return -ENOMEM;
941
942	work->event = event;
943	work->old_fb = dcrtc->crtc.primary->fb;
944
945	i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs,
946				    dcrtc->interlaced);
947	armada_reg_queue_end(work->regs, i);
948
949	/*
950	 * Ensure that we hold a reference on the new framebuffer.
951	 * This has to match the behaviour in mode_set.
952	 */
953	drm_framebuffer_reference(fb);
954
955	ret = armada_drm_crtc_queue_frame_work(dcrtc, work);
956	if (ret) {
957		/* Undo our reference above */
958		drm_framebuffer_unreference(fb);
959		kfree(work);
960		return ret;
961	}
962
963	/*
964	 * Don't take a reference on the new framebuffer;
965	 * drm_mode_page_flip_ioctl() has already grabbed a reference and
966	 * will _not_ drop that reference on successful return from this
967	 * function.  Simply mark this new framebuffer as the current one.
968	 */
969	dcrtc->crtc.primary->fb = fb;
970
971	/*
972	 * Finally, if the display is blanked, we won't receive an
973	 * interrupt, so complete it now.
974	 */
975	if (dpms_blanked(dcrtc->dpms)) {
976		spin_lock_irqsave(&dev->event_lock, flags);
977		if (dcrtc->frame_work)
978			armada_drm_crtc_complete_frame_work(dcrtc);
979		spin_unlock_irqrestore(&dev->event_lock, flags);
980	}
981
982	return 0;
983}
984
985static int
986armada_drm_crtc_set_property(struct drm_crtc *crtc,
987	struct drm_property *property, uint64_t val)
988{
989	struct armada_private *priv = crtc->dev->dev_private;
990	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
991	bool update_csc = false;
992
993	if (property == priv->csc_yuv_prop) {
994		dcrtc->csc_yuv_mode = val;
995		update_csc = true;
996	} else if (property == priv->csc_rgb_prop) {
997		dcrtc->csc_rgb_mode = val;
998		update_csc = true;
999	}
1000
1001	if (update_csc) {
1002		uint32_t val;
1003
1004		val = dcrtc->spu_iopad_ctrl |
1005		      armada_drm_crtc_calculate_csc(dcrtc);
1006		writel_relaxed(val, dcrtc->base + LCD_SPU_IOPAD_CONTROL);
1007	}
1008
1009	return 0;
1010}
1011
1012static struct drm_crtc_funcs armada_crtc_funcs = {
1013	.cursor_set	= armada_drm_crtc_cursor_set,
1014	.cursor_move	= armada_drm_crtc_cursor_move,
1015	.destroy	= armada_drm_crtc_destroy,
1016	.set_config	= drm_crtc_helper_set_config,
1017	.page_flip	= armada_drm_crtc_page_flip,
1018	.set_property	= armada_drm_crtc_set_property,
1019};
1020
1021static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
1022	{ CSC_AUTO,        "Auto" },
1023	{ CSC_YUV_CCIR601, "CCIR601" },
1024	{ CSC_YUV_CCIR709, "CCIR709" },
1025};
1026
1027static struct drm_prop_enum_list armada_drm_csc_rgb_enum_list[] = {
1028	{ CSC_AUTO,         "Auto" },
1029	{ CSC_RGB_COMPUTER, "Computer system" },
1030	{ CSC_RGB_STUDIO,   "Studio" },
1031};
1032
1033static int armada_drm_crtc_create_properties(struct drm_device *dev)
1034{
1035	struct armada_private *priv = dev->dev_private;
1036
1037	if (priv->csc_yuv_prop)
1038		return 0;
1039
1040	priv->csc_yuv_prop = drm_property_create_enum(dev, 0,
1041				"CSC_YUV", armada_drm_csc_yuv_enum_list,
1042				ARRAY_SIZE(armada_drm_csc_yuv_enum_list));
1043	priv->csc_rgb_prop = drm_property_create_enum(dev, 0,
1044				"CSC_RGB", armada_drm_csc_rgb_enum_list,
1045				ARRAY_SIZE(armada_drm_csc_rgb_enum_list));
1046
1047	if (!priv->csc_yuv_prop || !priv->csc_rgb_prop)
1048		return -ENOMEM;
1049
1050	return 0;
1051}
1052
1053int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
1054	struct resource *res, int irq, const struct armada_variant *variant,
1055	struct device_node *port)
1056{
1057	struct armada_private *priv = drm->dev_private;
1058	struct armada_crtc *dcrtc;
1059	void __iomem *base;
1060	int ret;
1061
1062	ret = armada_drm_crtc_create_properties(drm);
1063	if (ret)
1064		return ret;
1065
1066	base = devm_ioremap_resource(dev, res);
1067	if (IS_ERR(base))
1068		return PTR_ERR(base);
1069
1070	dcrtc = kzalloc(sizeof(*dcrtc), GFP_KERNEL);
1071	if (!dcrtc) {
1072		DRM_ERROR("failed to allocate Armada crtc\n");
1073		return -ENOMEM;
1074	}
1075
1076	if (dev != drm->dev)
1077		dev_set_drvdata(dev, dcrtc);
1078
1079	dcrtc->variant = variant;
1080	dcrtc->base = base;
1081	dcrtc->num = drm->mode_config.num_crtc;
1082	dcrtc->clk = ERR_PTR(-EINVAL);
1083	dcrtc->csc_yuv_mode = CSC_AUTO;
1084	dcrtc->csc_rgb_mode = CSC_AUTO;
1085	dcrtc->cfg_dumb_ctrl = DUMB24_RGB888_0;
1086	dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
1087	spin_lock_init(&dcrtc->irq_lock);
1088	dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
1089	INIT_LIST_HEAD(&dcrtc->vbl_list);
1090	init_waitqueue_head(&dcrtc->frame_wait);
1091
1092	/* Initialize some registers which we don't otherwise set */
1093	writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
1094	writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_BLANKCOLOR);
1095	writel_relaxed(dcrtc->spu_iopad_ctrl,
1096		       dcrtc->base + LCD_SPU_IOPAD_CONTROL);
1097	writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_SRAM_PARA0);
1098	writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
1099		       CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
1100		       CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
1101	writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1);
1102	writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN);
1103	writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
1104	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
1105
1106	ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc",
1107			       dcrtc);
1108	if (ret < 0) {
1109		kfree(dcrtc);
1110		return ret;
1111	}
1112
1113	if (dcrtc->variant->init) {
1114		ret = dcrtc->variant->init(dcrtc, dev);
1115		if (ret) {
1116			kfree(dcrtc);
1117			return ret;
1118		}
1119	}
1120
1121	/* Ensure AXI pipeline is enabled */
1122	armada_updatel(CFG_ARBFAST_ENA, 0, dcrtc->base + LCD_SPU_DMA_CTRL0);
1123
1124	priv->dcrtc[dcrtc->num] = dcrtc;
1125
1126	dcrtc->crtc.port = port;
1127	drm_crtc_init(drm, &dcrtc->crtc, &armada_crtc_funcs);
1128	drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
1129
1130	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
1131				   dcrtc->csc_yuv_mode);
1132	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_rgb_prop,
1133				   dcrtc->csc_rgb_mode);
1134
1135	return armada_overlay_plane_create(drm, 1 << dcrtc->num);
1136}
1137
1138static int
1139armada_lcd_bind(struct device *dev, struct device *master, void *data)
1140{
1141	struct platform_device *pdev = to_platform_device(dev);
1142	struct drm_device *drm = data;
1143	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1144	int irq = platform_get_irq(pdev, 0);
1145	const struct armada_variant *variant;
1146	struct device_node *port = NULL;
1147
1148	if (irq < 0)
1149		return irq;
1150
1151	if (!dev->of_node) {
1152		const struct platform_device_id *id;
1153
1154		id = platform_get_device_id(pdev);
1155		if (!id)
1156			return -ENXIO;
1157
1158		variant = (const struct armada_variant *)id->driver_data;
1159	} else {
1160		const struct of_device_id *match;
1161		struct device_node *np, *parent = dev->of_node;
1162
1163		match = of_match_device(dev->driver->of_match_table, dev);
1164		if (!match)
1165			return -ENXIO;
1166
1167		np = of_get_child_by_name(parent, "ports");
1168		if (np)
1169			parent = np;
1170		port = of_get_child_by_name(parent, "port");
1171		of_node_put(np);
1172		if (!port) {
1173			dev_err(dev, "no port node found in %s\n",
1174				parent->full_name);
1175			return -ENXIO;
1176		}
1177
1178		variant = match->data;
1179	}
1180
1181	return armada_drm_crtc_create(drm, dev, res, irq, variant, port);
1182}
1183
1184static void
1185armada_lcd_unbind(struct device *dev, struct device *master, void *data)
1186{
1187	struct armada_crtc *dcrtc = dev_get_drvdata(dev);
1188
1189	armada_drm_crtc_destroy(&dcrtc->crtc);
1190}
1191
1192static const struct component_ops armada_lcd_ops = {
1193	.bind = armada_lcd_bind,
1194	.unbind = armada_lcd_unbind,
1195};
1196
1197static int armada_lcd_probe(struct platform_device *pdev)
1198{
1199	return component_add(&pdev->dev, &armada_lcd_ops);
1200}
1201
1202static int armada_lcd_remove(struct platform_device *pdev)
1203{
1204	component_del(&pdev->dev, &armada_lcd_ops);
1205	return 0;
1206}
1207
1208static struct of_device_id armada_lcd_of_match[] = {
1209	{
1210		.compatible	= "marvell,dove-lcd",
1211		.data		= &armada510_ops,
1212	},
1213	{}
1214};
1215MODULE_DEVICE_TABLE(of, armada_lcd_of_match);
1216
1217static const struct platform_device_id armada_lcd_platform_ids[] = {
1218	{
1219		.name		= "armada-lcd",
1220		.driver_data	= (unsigned long)&armada510_ops,
1221	}, {
1222		.name		= "armada-510-lcd",
1223		.driver_data	= (unsigned long)&armada510_ops,
1224	},
1225	{ },
1226};
1227MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids);
1228
1229struct platform_driver armada_lcd_platform_driver = {
1230	.probe	= armada_lcd_probe,
1231	.remove	= armada_lcd_remove,
1232	.driver = {
1233		.name	= "armada-lcd",
1234		.owner	=  THIS_MODULE,
1235		.of_match_table = armada_lcd_of_match,
1236	},
1237	.id_table = armada_lcd_platform_ids,
1238};
1239