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