GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / gpu / drm / tve200 / tve200_display.c
1 /*
2  * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
3  * Parts of this file were based on sources as follows:
4  *
5  * Copyright (C) 2006-2008 Intel Corporation
6  * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com>
7  * Copyright (C) 2007 Dave Airlie <airlied@linux.ie>
8  * Copyright (C) 2011 Texas Instruments
9  * Copyright (C) 2017 Eric Anholt
10  *
11  * This program is free software and is provided to you under the terms of the
12  * GNU General Public License version 2 as published by the Free Software
13  * Foundation, and any use by you of this program is subject to the terms of
14  * such GNU licence.
15  */
16 #include <linux/clk.h>
17 #include <linux/version.h>
18 #include <linux/dma-buf.h>
19 #include <linux/of_graph.h>
20 #include <linux/delay.h>
21
22 #include <drm/drmP.h>
23 #include <drm/drm_panel.h>
24 #include <drm/drm_gem_cma_helper.h>
25 #include <drm/drm_gem_framebuffer_helper.h>
26 #include <drm/drm_fb_cma_helper.h>
27
28 #include "tve200_drm.h"
29
30 irqreturn_t tve200_irq(int irq, void *data)
31 {
32         struct tve200_drm_dev_private *priv = data;
33         u32 stat;
34         u32 val;
35
36         stat = readl(priv->regs + TVE200_INT_STAT);
37
38         if (!stat)
39                 return IRQ_NONE;
40
41         /*
42          * Vblank IRQ
43          *
44          * The hardware is a bit tilted: the line stays high after clearing
45          * the vblank IRQ, firing many more interrupts. We counter this
46          * by toggling the IRQ back and forth from firing at vblank and
47          * firing at start of active image, which works around the problem
48          * since those occur strictly in sequence, and we get two IRQs for each
49          * frame, one at start of Vblank (that we make call into the CRTC) and
50          * another one at the start of the image (that we discard).
51          */
52         if (stat & TVE200_INT_V_STATUS) {
53                 val = readl(priv->regs + TVE200_CTRL);
54                 /* We have an actual start of vsync */
55                 if (!(val & TVE200_VSTSTYPE_BITS)) {
56                         drm_crtc_handle_vblank(&priv->pipe.crtc);
57                         /* Toggle trigger to start of active image */
58                         val |= TVE200_VSTSTYPE_VAI;
59                 } else {
60                         /* Toggle trigger back to start of vsync */
61                         val &= ~TVE200_VSTSTYPE_BITS;
62                 }
63                 writel(val, priv->regs + TVE200_CTRL);
64         } else
65                 dev_err(priv->drm->dev, "stray IRQ %08x\n", stat);
66
67         /* Clear the interrupt once done */
68         writel(stat, priv->regs + TVE200_INT_CLR);
69
70         return IRQ_HANDLED;
71 }
72
73 static int tve200_display_check(struct drm_simple_display_pipe *pipe,
74                                struct drm_plane_state *pstate,
75                                struct drm_crtc_state *cstate)
76 {
77         const struct drm_display_mode *mode = &cstate->mode;
78         struct drm_framebuffer *old_fb = pipe->plane.state->fb;
79         struct drm_framebuffer *fb = pstate->fb;
80
81         /*
82          * We support these specific resolutions and nothing else.
83          */
84         if (!(mode->hdisplay == 352 && mode->vdisplay == 240) && /* SIF(525) */
85             !(mode->hdisplay == 352 && mode->vdisplay == 288) && /* CIF(625) */
86             !(mode->hdisplay == 640 && mode->vdisplay == 480) && /* VGA */
87             !(mode->hdisplay == 720 && mode->vdisplay == 480) && /* D1 */
88             !(mode->hdisplay == 720 && mode->vdisplay == 576)) { /* D1 */
89                 DRM_DEBUG_KMS("unsupported display mode (%u x %u)\n",
90                         mode->hdisplay, mode->vdisplay);
91                 return -EINVAL;
92         }
93
94         if (fb) {
95                 u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0);
96
97                 /* FB base address must be dword aligned. */
98                 if (offset & 3) {
99                         DRM_DEBUG_KMS("FB not 32-bit aligned\n");
100                         return -EINVAL;
101                 }
102
103                 /*
104                  * There's no pitch register, the mode's hdisplay
105                  * controls this.
106                  */
107                 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) {
108                         DRM_DEBUG_KMS("can't handle pitches\n");
109                         return -EINVAL;
110                 }
111
112                 /*
113                  * We can't change the FB format in a flicker-free
114                  * manner (and only update it during CRTC enable).
115                  */
116                 if (old_fb && old_fb->format != fb->format)
117                         cstate->mode_changed = true;
118         }
119
120         return 0;
121 }
122
123 static void tve200_display_enable(struct drm_simple_display_pipe *pipe,
124                                  struct drm_crtc_state *cstate,
125                                  struct drm_plane_state *plane_state)
126 {
127         struct drm_crtc *crtc = &pipe->crtc;
128         struct drm_plane *plane = &pipe->plane;
129         struct drm_device *drm = crtc->dev;
130         struct tve200_drm_dev_private *priv = drm->dev_private;
131         const struct drm_display_mode *mode = &cstate->mode;
132         struct drm_framebuffer *fb = plane->state->fb;
133         struct drm_connector *connector = priv->connector;
134         u32 format = fb->format->format;
135         u32 ctrl1 = 0;
136         int retries;
137
138         clk_prepare_enable(priv->clk);
139
140         /* Reset the TVE200 and wait for it to come back online */
141         writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
142         for (retries = 0; retries < 5; retries++) {
143                 usleep_range(30000, 50000);
144                 if (readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET)
145                         continue;
146                 else
147                         break;
148         }
149         if (retries == 5 &&
150             readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET) {
151                 dev_err(drm->dev, "can't get hardware out of reset\n");
152                 return;
153         }
154
155         /* Function 1 */
156         ctrl1 |= TVE200_CTRL_CSMODE;
157         /* Interlace mode for CCIR656: parameterize? */
158         ctrl1 |= TVE200_CTRL_NONINTERLACE;
159         /* 32 words per burst */
160         ctrl1 |= TVE200_CTRL_BURST_32_WORDS;
161         /* 16 retries */
162         ctrl1 |= TVE200_CTRL_RETRYCNT_16;
163         /* NTSC mode: parametrize? */
164         ctrl1 |= TVE200_CTRL_NTSC;
165
166         /* Vsync IRQ at start of Vsync at first */
167         ctrl1 |= TVE200_VSTSTYPE_VSYNC;
168
169         if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
170                 ctrl1 |= TVE200_CTRL_TVCLKP;
171
172         if ((mode->hdisplay == 352 && mode->vdisplay == 240) || /* SIF(525) */
173             (mode->hdisplay == 352 && mode->vdisplay == 288)) { /* CIF(625) */
174                 ctrl1 |= TVE200_CTRL_IPRESOL_CIF;
175                 dev_info(drm->dev, "CIF mode\n");
176         } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
177                 ctrl1 |= TVE200_CTRL_IPRESOL_VGA;
178                 dev_info(drm->dev, "VGA mode\n");
179         } else if ((mode->hdisplay == 720 && mode->vdisplay == 480) ||
180                    (mode->hdisplay == 720 && mode->vdisplay == 576)) {
181                 ctrl1 |= TVE200_CTRL_IPRESOL_D1;
182                 dev_info(drm->dev, "D1 mode\n");
183         }
184
185         if (format & DRM_FORMAT_BIG_ENDIAN) {
186                 ctrl1 |= TVE200_CTRL_BBBP;
187                 format &= ~DRM_FORMAT_BIG_ENDIAN;
188         }
189
190         switch (format) {
191         case DRM_FORMAT_XRGB8888:
192                 ctrl1 |= TVE200_IPDMOD_RGB888;
193                 break;
194         case DRM_FORMAT_RGB565:
195                 ctrl1 |= TVE200_IPDMOD_RGB565;
196                 break;
197         case DRM_FORMAT_XRGB1555:
198                 ctrl1 |= TVE200_IPDMOD_RGB555;
199                 break;
200         case DRM_FORMAT_XBGR8888:
201                 ctrl1 |= TVE200_IPDMOD_RGB888 | TVE200_BGR;
202                 break;
203         case DRM_FORMAT_BGR565:
204                 ctrl1 |= TVE200_IPDMOD_RGB565 | TVE200_BGR;
205                 break;
206         case DRM_FORMAT_XBGR1555:
207                 ctrl1 |= TVE200_IPDMOD_RGB555 | TVE200_BGR;
208                 break;
209         case DRM_FORMAT_YUYV:
210                 ctrl1 |= TVE200_IPDMOD_YUV422;
211                 ctrl1 |= TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0;
212                 break;
213         case DRM_FORMAT_YVYU:
214                 ctrl1 |= TVE200_IPDMOD_YUV422;
215                 ctrl1 |= TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0;
216                 break;
217         case DRM_FORMAT_UYVY:
218                 ctrl1 |= TVE200_IPDMOD_YUV422;
219                 ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0;
220                 break;
221         case DRM_FORMAT_VYUY:
222                 ctrl1 |= TVE200_IPDMOD_YUV422;
223                 ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0;
224                 break;
225         case DRM_FORMAT_YUV420:
226                 ctrl1 |= TVE200_CTRL_YUV420;
227                 ctrl1 |= TVE200_IPDMOD_YUV420;
228                 break;
229         default:
230                 dev_err(drm->dev, "Unknown FB format 0x%08x\n",
231                         fb->format->format);
232                 break;
233         }
234
235         ctrl1 |= TVE200_TVEEN;
236
237         /* Turn it on */
238         writel(ctrl1, priv->regs + TVE200_CTRL);
239
240         drm_crtc_vblank_on(crtc);
241 }
242
243 static void tve200_display_disable(struct drm_simple_display_pipe *pipe)
244 {
245         struct drm_crtc *crtc = &pipe->crtc;
246         struct drm_device *drm = crtc->dev;
247         struct tve200_drm_dev_private *priv = drm->dev_private;
248
249         drm_crtc_vblank_off(crtc);
250
251         /* Disable put into reset and Power Down */
252         writel(0, priv->regs + TVE200_CTRL);
253         writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
254
255         clk_disable_unprepare(priv->clk);
256 }
257
258 static void tve200_display_update(struct drm_simple_display_pipe *pipe,
259                                  struct drm_plane_state *old_pstate)
260 {
261         struct drm_crtc *crtc = &pipe->crtc;
262         struct drm_device *drm = crtc->dev;
263         struct tve200_drm_dev_private *priv = drm->dev_private;
264         struct drm_pending_vblank_event *event = crtc->state->event;
265         struct drm_plane *plane = &pipe->plane;
266         struct drm_plane_state *pstate = plane->state;
267         struct drm_framebuffer *fb = pstate->fb;
268
269         if (fb) {
270                 /* For RGB, the Y component is used as base address */
271                 writel(drm_fb_cma_get_gem_addr(fb, pstate, 0),
272                        priv->regs + TVE200_Y_FRAME_BASE_ADDR);
273
274                 /* For three plane YUV we need two more addresses */
275                 if (fb->format->format == DRM_FORMAT_YUV420) {
276                         writel(drm_fb_cma_get_gem_addr(fb, pstate, 1),
277                                priv->regs + TVE200_U_FRAME_BASE_ADDR);
278                         writel(drm_fb_cma_get_gem_addr(fb, pstate, 2),
279                                priv->regs + TVE200_V_FRAME_BASE_ADDR);
280                 }
281         }
282
283         if (event) {
284                 crtc->state->event = NULL;
285
286                 spin_lock_irq(&crtc->dev->event_lock);
287                 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
288                         drm_crtc_arm_vblank_event(crtc, event);
289                 else
290                         drm_crtc_send_vblank_event(crtc, event);
291                 spin_unlock_irq(&crtc->dev->event_lock);
292         }
293 }
294
295 static int tve200_display_enable_vblank(struct drm_simple_display_pipe *pipe)
296 {
297         struct drm_crtc *crtc = &pipe->crtc;
298         struct drm_device *drm = crtc->dev;
299         struct tve200_drm_dev_private *priv = drm->dev_private;
300
301         /* Clear any IRQs and enable */
302         writel(0xFF, priv->regs + TVE200_INT_CLR);
303         writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN);
304         return 0;
305 }
306
307 static void tve200_display_disable_vblank(struct drm_simple_display_pipe *pipe)
308 {
309         struct drm_crtc *crtc = &pipe->crtc;
310         struct drm_device *drm = crtc->dev;
311         struct tve200_drm_dev_private *priv = drm->dev_private;
312
313         writel(0, priv->regs + TVE200_INT_EN);
314 }
315
316 static const struct drm_simple_display_pipe_funcs tve200_display_funcs = {
317         .check = tve200_display_check,
318         .enable = tve200_display_enable,
319         .disable = tve200_display_disable,
320         .update = tve200_display_update,
321         .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
322         .enable_vblank = tve200_display_enable_vblank,
323         .disable_vblank = tve200_display_disable_vblank,
324 };
325
326 int tve200_display_init(struct drm_device *drm)
327 {
328         struct tve200_drm_dev_private *priv = drm->dev_private;
329         int ret;
330         static const u32 formats[] = {
331                 DRM_FORMAT_XRGB8888,
332                 DRM_FORMAT_XBGR8888,
333                 DRM_FORMAT_RGB565,
334                 DRM_FORMAT_BGR565,
335                 DRM_FORMAT_XRGB1555,
336                 DRM_FORMAT_XBGR1555,
337                 /*
338                  * The controller actually supports any YCbCr ordering,
339                  * for packed YCbCr. This just lists the orderings that
340                  * DRM supports.
341                  */
342                 DRM_FORMAT_YUYV,
343                 DRM_FORMAT_YVYU,
344                 DRM_FORMAT_UYVY,
345                 DRM_FORMAT_VYUY,
346                 /* This uses three planes */
347                 DRM_FORMAT_YUV420,
348         };
349
350         ret = drm_simple_display_pipe_init(drm, &priv->pipe,
351                                            &tve200_display_funcs,
352                                            formats, ARRAY_SIZE(formats),
353                                            NULL,
354                                            priv->connector);
355         if (ret)
356                 return ret;
357
358         return 0;
359 }