Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
0004  * Parts of this file were based on sources as follows:
0005  *
0006  * Copyright (C) 2006-2008 Intel Corporation
0007  * Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com>
0008  * Copyright (C) 2007 Dave Airlie <airlied@linux.ie>
0009  * Copyright (C) 2011 Texas Instruments
0010  * Copyright (C) 2017 Eric Anholt
0011  */
0012 
0013 #include <linux/clk.h>
0014 #include <linux/dma-buf.h>
0015 #include <linux/of_graph.h>
0016 #include <linux/delay.h>
0017 
0018 #include <drm/drm_fb_cma_helper.h>
0019 #include <drm/drm_fourcc.h>
0020 #include <drm/drm_framebuffer.h>
0021 #include <drm/drm_gem_atomic_helper.h>
0022 #include <drm/drm_gem_cma_helper.h>
0023 #include <drm/drm_panel.h>
0024 #include <drm/drm_vblank.h>
0025 
0026 #include "tve200_drm.h"
0027 
0028 irqreturn_t tve200_irq(int irq, void *data)
0029 {
0030     struct tve200_drm_dev_private *priv = data;
0031     u32 stat;
0032     u32 val;
0033 
0034     stat = readl(priv->regs + TVE200_INT_STAT);
0035 
0036     if (!stat)
0037         return IRQ_NONE;
0038 
0039     /*
0040      * Vblank IRQ
0041      *
0042      * The hardware is a bit tilted: the line stays high after clearing
0043      * the vblank IRQ, firing many more interrupts. We counter this
0044      * by toggling the IRQ back and forth from firing at vblank and
0045      * firing at start of active image, which works around the problem
0046      * since those occur strictly in sequence, and we get two IRQs for each
0047      * frame, one at start of Vblank (that we make call into the CRTC) and
0048      * another one at the start of the image (that we discard).
0049      */
0050     if (stat & TVE200_INT_V_STATUS) {
0051         val = readl(priv->regs + TVE200_CTRL);
0052         /* We have an actual start of vsync */
0053         if (!(val & TVE200_VSTSTYPE_BITS)) {
0054             drm_crtc_handle_vblank(&priv->pipe.crtc);
0055             /* Toggle trigger to start of active image */
0056             val |= TVE200_VSTSTYPE_VAI;
0057         } else {
0058             /* Toggle trigger back to start of vsync */
0059             val &= ~TVE200_VSTSTYPE_BITS;
0060         }
0061         writel(val, priv->regs + TVE200_CTRL);
0062     } else
0063         dev_err(priv->drm->dev, "stray IRQ %08x\n", stat);
0064 
0065     /* Clear the interrupt once done */
0066     writel(stat, priv->regs + TVE200_INT_CLR);
0067 
0068     return IRQ_HANDLED;
0069 }
0070 
0071 static int tve200_display_check(struct drm_simple_display_pipe *pipe,
0072                    struct drm_plane_state *pstate,
0073                    struct drm_crtc_state *cstate)
0074 {
0075     const struct drm_display_mode *mode = &cstate->mode;
0076     struct drm_framebuffer *old_fb = pipe->plane.state->fb;
0077     struct drm_framebuffer *fb = pstate->fb;
0078 
0079     /*
0080      * We support these specific resolutions and nothing else.
0081      */
0082     if (!(mode->hdisplay == 352 && mode->vdisplay == 240) && /* SIF(525) */
0083         !(mode->hdisplay == 352 && mode->vdisplay == 288) && /* CIF(625) */
0084         !(mode->hdisplay == 640 && mode->vdisplay == 480) && /* VGA */
0085         !(mode->hdisplay == 720 && mode->vdisplay == 480) && /* D1 */
0086         !(mode->hdisplay == 720 && mode->vdisplay == 576)) { /* D1 */
0087         DRM_DEBUG_KMS("unsupported display mode (%u x %u)\n",
0088             mode->hdisplay, mode->vdisplay);
0089         return -EINVAL;
0090     }
0091 
0092     if (fb) {
0093         u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0);
0094 
0095         /* FB base address must be dword aligned. */
0096         if (offset & 3) {
0097             DRM_DEBUG_KMS("FB not 32-bit aligned\n");
0098             return -EINVAL;
0099         }
0100 
0101         /*
0102          * There's no pitch register, the mode's hdisplay
0103          * controls this.
0104          */
0105         if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) {
0106             DRM_DEBUG_KMS("can't handle pitches\n");
0107             return -EINVAL;
0108         }
0109 
0110         /*
0111          * We can't change the FB format in a flicker-free
0112          * manner (and only update it during CRTC enable).
0113          */
0114         if (old_fb && old_fb->format != fb->format)
0115             cstate->mode_changed = true;
0116     }
0117 
0118     return 0;
0119 }
0120 
0121 static void tve200_display_enable(struct drm_simple_display_pipe *pipe,
0122                  struct drm_crtc_state *cstate,
0123                  struct drm_plane_state *plane_state)
0124 {
0125     struct drm_crtc *crtc = &pipe->crtc;
0126     struct drm_plane *plane = &pipe->plane;
0127     struct drm_device *drm = crtc->dev;
0128     struct tve200_drm_dev_private *priv = drm->dev_private;
0129     const struct drm_display_mode *mode = &cstate->mode;
0130     struct drm_framebuffer *fb = plane->state->fb;
0131     struct drm_connector *connector = priv->connector;
0132     u32 format = fb->format->format;
0133     u32 ctrl1 = 0;
0134     int retries;
0135 
0136     clk_prepare_enable(priv->clk);
0137 
0138     /* Reset the TVE200 and wait for it to come back online */
0139     writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
0140     for (retries = 0; retries < 5; retries++) {
0141         usleep_range(30000, 50000);
0142         if (readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET)
0143             continue;
0144         else
0145             break;
0146     }
0147     if (retries == 5 &&
0148         readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET) {
0149         dev_err(drm->dev, "can't get hardware out of reset\n");
0150         return;
0151     }
0152 
0153     /* Function 1 */
0154     ctrl1 |= TVE200_CTRL_CSMODE;
0155     /* Interlace mode for CCIR656: parameterize? */
0156     ctrl1 |= TVE200_CTRL_NONINTERLACE;
0157     /* 32 words per burst */
0158     ctrl1 |= TVE200_CTRL_BURST_32_WORDS;
0159     /* 16 retries */
0160     ctrl1 |= TVE200_CTRL_RETRYCNT_16;
0161     /* NTSC mode: parametrize? */
0162     ctrl1 |= TVE200_CTRL_NTSC;
0163 
0164     /* Vsync IRQ at start of Vsync at first */
0165     ctrl1 |= TVE200_VSTSTYPE_VSYNC;
0166 
0167     if (connector->display_info.bus_flags &
0168         DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
0169         ctrl1 |= TVE200_CTRL_TVCLKP;
0170 
0171     if ((mode->hdisplay == 352 && mode->vdisplay == 240) || /* SIF(525) */
0172         (mode->hdisplay == 352 && mode->vdisplay == 288)) { /* CIF(625) */
0173         ctrl1 |= TVE200_CTRL_IPRESOL_CIF;
0174         dev_info(drm->dev, "CIF mode\n");
0175     } else if (mode->hdisplay == 640 && mode->vdisplay == 480) {
0176         ctrl1 |= TVE200_CTRL_IPRESOL_VGA;
0177         dev_info(drm->dev, "VGA mode\n");
0178     } else if ((mode->hdisplay == 720 && mode->vdisplay == 480) ||
0179            (mode->hdisplay == 720 && mode->vdisplay == 576)) {
0180         ctrl1 |= TVE200_CTRL_IPRESOL_D1;
0181         dev_info(drm->dev, "D1 mode\n");
0182     }
0183 
0184     if (format & DRM_FORMAT_BIG_ENDIAN) {
0185         ctrl1 |= TVE200_CTRL_BBBP;
0186         format &= ~DRM_FORMAT_BIG_ENDIAN;
0187     }
0188 
0189     switch (format) {
0190     case DRM_FORMAT_XRGB8888:
0191         ctrl1 |= TVE200_IPDMOD_RGB888;
0192         break;
0193     case DRM_FORMAT_RGB565:
0194         ctrl1 |= TVE200_IPDMOD_RGB565;
0195         break;
0196     case DRM_FORMAT_XRGB1555:
0197         ctrl1 |= TVE200_IPDMOD_RGB555;
0198         break;
0199     case DRM_FORMAT_XBGR8888:
0200         ctrl1 |= TVE200_IPDMOD_RGB888 | TVE200_BGR;
0201         break;
0202     case DRM_FORMAT_BGR565:
0203         ctrl1 |= TVE200_IPDMOD_RGB565 | TVE200_BGR;
0204         break;
0205     case DRM_FORMAT_XBGR1555:
0206         ctrl1 |= TVE200_IPDMOD_RGB555 | TVE200_BGR;
0207         break;
0208     case DRM_FORMAT_YUYV:
0209         ctrl1 |= TVE200_IPDMOD_YUV422;
0210         ctrl1 |= TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0;
0211         break;
0212     case DRM_FORMAT_YVYU:
0213         ctrl1 |= TVE200_IPDMOD_YUV422;
0214         ctrl1 |= TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0;
0215         break;
0216     case DRM_FORMAT_UYVY:
0217         ctrl1 |= TVE200_IPDMOD_YUV422;
0218         ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0;
0219         break;
0220     case DRM_FORMAT_VYUY:
0221         ctrl1 |= TVE200_IPDMOD_YUV422;
0222         ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0;
0223         break;
0224     case DRM_FORMAT_YUV420:
0225         ctrl1 |= TVE200_CTRL_YUV420;
0226         ctrl1 |= TVE200_IPDMOD_YUV420;
0227         break;
0228     default:
0229         dev_err(drm->dev, "Unknown FB format 0x%08x\n",
0230             fb->format->format);
0231         break;
0232     }
0233 
0234     ctrl1 |= TVE200_TVEEN;
0235 
0236     /* Turn it on */
0237     writel(ctrl1, priv->regs + TVE200_CTRL);
0238 
0239     drm_crtc_vblank_on(crtc);
0240 }
0241 
0242 static void tve200_display_disable(struct drm_simple_display_pipe *pipe)
0243 {
0244     struct drm_crtc *crtc = &pipe->crtc;
0245     struct drm_device *drm = crtc->dev;
0246     struct tve200_drm_dev_private *priv = drm->dev_private;
0247 
0248     drm_crtc_vblank_off(crtc);
0249 
0250     /* Disable put into reset and Power Down */
0251     writel(0, priv->regs + TVE200_CTRL);
0252     writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
0253 
0254     clk_disable_unprepare(priv->clk);
0255 }
0256 
0257 static void tve200_display_update(struct drm_simple_display_pipe *pipe,
0258                  struct drm_plane_state *old_pstate)
0259 {
0260     struct drm_crtc *crtc = &pipe->crtc;
0261     struct drm_device *drm = crtc->dev;
0262     struct tve200_drm_dev_private *priv = drm->dev_private;
0263     struct drm_pending_vblank_event *event = crtc->state->event;
0264     struct drm_plane *plane = &pipe->plane;
0265     struct drm_plane_state *pstate = plane->state;
0266     struct drm_framebuffer *fb = pstate->fb;
0267 
0268     if (fb) {
0269         /* For RGB, the Y component is used as base address */
0270         writel(drm_fb_cma_get_gem_addr(fb, pstate, 0),
0271                priv->regs + TVE200_Y_FRAME_BASE_ADDR);
0272 
0273         /* For three plane YUV we need two more addresses */
0274         if (fb->format->format == DRM_FORMAT_YUV420) {
0275             writel(drm_fb_cma_get_gem_addr(fb, pstate, 1),
0276                    priv->regs + TVE200_U_FRAME_BASE_ADDR);
0277             writel(drm_fb_cma_get_gem_addr(fb, pstate, 2),
0278                    priv->regs + TVE200_V_FRAME_BASE_ADDR);
0279         }
0280     }
0281 
0282     if (event) {
0283         crtc->state->event = NULL;
0284 
0285         spin_lock_irq(&crtc->dev->event_lock);
0286         if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
0287             drm_crtc_arm_vblank_event(crtc, event);
0288         else
0289             drm_crtc_send_vblank_event(crtc, event);
0290         spin_unlock_irq(&crtc->dev->event_lock);
0291     }
0292 }
0293 
0294 static int tve200_display_enable_vblank(struct drm_simple_display_pipe *pipe)
0295 {
0296     struct drm_crtc *crtc = &pipe->crtc;
0297     struct drm_device *drm = crtc->dev;
0298     struct tve200_drm_dev_private *priv = drm->dev_private;
0299 
0300     /* Clear any IRQs and enable */
0301     writel(0xFF, priv->regs + TVE200_INT_CLR);
0302     writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN);
0303     return 0;
0304 }
0305 
0306 static void tve200_display_disable_vblank(struct drm_simple_display_pipe *pipe)
0307 {
0308     struct drm_crtc *crtc = &pipe->crtc;
0309     struct drm_device *drm = crtc->dev;
0310     struct tve200_drm_dev_private *priv = drm->dev_private;
0311 
0312     writel(0, priv->regs + TVE200_INT_EN);
0313 }
0314 
0315 static const struct drm_simple_display_pipe_funcs tve200_display_funcs = {
0316     .check = tve200_display_check,
0317     .enable = tve200_display_enable,
0318     .disable = tve200_display_disable,
0319     .update = tve200_display_update,
0320     .enable_vblank = tve200_display_enable_vblank,
0321     .disable_vblank = tve200_display_disable_vblank,
0322 };
0323 
0324 int tve200_display_init(struct drm_device *drm)
0325 {
0326     struct tve200_drm_dev_private *priv = drm->dev_private;
0327     int ret;
0328     static const u32 formats[] = {
0329         DRM_FORMAT_XRGB8888,
0330         DRM_FORMAT_XBGR8888,
0331         DRM_FORMAT_RGB565,
0332         DRM_FORMAT_BGR565,
0333         DRM_FORMAT_XRGB1555,
0334         DRM_FORMAT_XBGR1555,
0335         /*
0336          * The controller actually supports any YCbCr ordering,
0337          * for packed YCbCr. This just lists the orderings that
0338          * DRM supports.
0339          */
0340         DRM_FORMAT_YUYV,
0341         DRM_FORMAT_YVYU,
0342         DRM_FORMAT_UYVY,
0343         DRM_FORMAT_VYUY,
0344         /* This uses three planes */
0345         DRM_FORMAT_YUV420,
0346     };
0347 
0348     ret = drm_simple_display_pipe_init(drm, &priv->pipe,
0349                        &tve200_display_funcs,
0350                        formats, ARRAY_SIZE(formats),
0351                        NULL,
0352                        priv->connector);
0353     if (ret)
0354         return ret;
0355 
0356     return 0;
0357 }