1 /* 2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved. 3 * 4 * Parts of this file were based on sources as follows: 5 * 6 * Copyright (c) 2006-2008 Intel Corporation 7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 8 * Copyright (C) 2011 Texas Instruments 9 * 10 * This program is free software and is provided to you under the terms of the 11 * GNU General Public License version 2 as published by the Free Software 12 * Foundation, and any use by you of this program is subject to the terms of 13 * such GNU licence. 14 * 15 */ 16 17 #include <linux/amba/clcd-regs.h> 18 #include <linux/clk.h> 19 #include <linux/version.h> 20 #include <linux/dma-buf.h> 21 #include <linux/of_graph.h> 22 23 #include <drm/drmP.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 "pl111_drm.h" 29 30 irqreturn_t pl111_irq(int irq, void *data) 31 { 32 struct pl111_drm_dev_private *priv = data; 33 u32 irq_stat; 34 irqreturn_t status = IRQ_NONE; 35 36 irq_stat = readl(priv->regs + CLCD_PL111_MIS); 37 38 if (!irq_stat) 39 return IRQ_NONE; 40 41 if (irq_stat & CLCD_IRQ_NEXTBASE_UPDATE) { 42 drm_crtc_handle_vblank(&priv->pipe.crtc); 43 44 status = IRQ_HANDLED; 45 } 46 47 /* Clear the interrupt once done */ 48 writel(irq_stat, priv->regs + CLCD_PL111_ICR); 49 50 return status; 51 } 52 53 static int pl111_display_check(struct drm_simple_display_pipe *pipe, 54 struct drm_plane_state *pstate, 55 struct drm_crtc_state *cstate) 56 { 57 const struct drm_display_mode *mode = &cstate->mode; 58 struct drm_framebuffer *old_fb = pipe->plane.state->fb; 59 struct drm_framebuffer *fb = pstate->fb; 60 61 if (mode->hdisplay % 16) 62 return -EINVAL; 63 64 if (fb) { 65 u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0); 66 67 /* FB base address must be dword aligned. */ 68 if (offset & 3) 69 return -EINVAL; 70 71 /* There's no pitch register -- the mode's hdisplay 72 * controls it. 73 */ 74 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) 75 return -EINVAL; 76 77 /* We can't change the FB format in a flicker-free 78 * manner (and only update it during CRTC enable). 79 */ 80 if (old_fb && old_fb->format != fb->format) 81 cstate->mode_changed = true; 82 } 83 84 return 0; 85 } 86 87 static void pl111_display_enable(struct drm_simple_display_pipe *pipe, 88 struct drm_crtc_state *cstate) 89 { 90 struct drm_crtc *crtc = &pipe->crtc; 91 struct drm_plane *plane = &pipe->plane; 92 struct drm_device *drm = crtc->dev; 93 struct pl111_drm_dev_private *priv = drm->dev_private; 94 const struct drm_display_mode *mode = &cstate->mode; 95 struct drm_framebuffer *fb = plane->state->fb; 96 struct drm_connector *connector = priv->connector; 97 u32 cntl; 98 u32 ppl, hsw, hfp, hbp; 99 u32 lpp, vsw, vfp, vbp; 100 u32 cpl, tim2; 101 int ret; 102 103 ret = clk_set_rate(priv->clk, mode->clock * 1000); 104 if (ret) { 105 dev_err(drm->dev, 106 "Failed to set pixel clock rate to %d: %d\n", 107 mode->clock * 1000, ret); 108 } 109 110 clk_prepare_enable(priv->clk); 111 112 ppl = (mode->hdisplay / 16) - 1; 113 hsw = mode->hsync_end - mode->hsync_start - 1; 114 hfp = mode->hsync_start - mode->hdisplay - 1; 115 hbp = mode->htotal - mode->hsync_end - 1; 116 117 lpp = mode->vdisplay - 1; 118 vsw = mode->vsync_end - mode->vsync_start - 1; 119 vfp = mode->vsync_start - mode->vdisplay; 120 vbp = mode->vtotal - mode->vsync_end; 121 122 cpl = mode->hdisplay - 1; 123 124 writel((ppl << 2) | 125 (hsw << 8) | 126 (hfp << 16) | 127 (hbp << 24), 128 priv->regs + CLCD_TIM0); 129 writel(lpp | 130 (vsw << 10) | 131 (vfp << 16) | 132 (vbp << 24), 133 priv->regs + CLCD_TIM1); 134 135 spin_lock(&priv->tim2_lock); 136 137 tim2 = readl(priv->regs + CLCD_TIM2); 138 tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); 139 140 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 141 tim2 |= TIM2_IHS; 142 143 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 144 tim2 |= TIM2_IVS; 145 146 if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) 147 tim2 |= TIM2_IOE; 148 149 if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE) 150 tim2 |= TIM2_IPC; 151 152 tim2 |= cpl << 16; 153 writel(tim2, priv->regs + CLCD_TIM2); 154 spin_unlock(&priv->tim2_lock); 155 156 writel(0, priv->regs + CLCD_TIM3); 157 158 /* Hard-code TFT panel */ 159 cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1); 160 161 /* Note that the the hardware's format reader takes 'r' from 162 * the low bit, while DRM formats list channels from high bit 163 * to low bit as you read left to right. 164 */ 165 switch (fb->format->format) { 166 case DRM_FORMAT_ABGR8888: 167 case DRM_FORMAT_XBGR8888: 168 cntl |= CNTL_LCDBPP24; 169 break; 170 case DRM_FORMAT_ARGB8888: 171 case DRM_FORMAT_XRGB8888: 172 cntl |= CNTL_LCDBPP24 | CNTL_BGR; 173 break; 174 case DRM_FORMAT_BGR565: 175 cntl |= CNTL_LCDBPP16_565; 176 break; 177 case DRM_FORMAT_RGB565: 178 cntl |= CNTL_LCDBPP16_565 | CNTL_BGR; 179 break; 180 case DRM_FORMAT_ABGR1555: 181 case DRM_FORMAT_XBGR1555: 182 cntl |= CNTL_LCDBPP16; 183 break; 184 case DRM_FORMAT_ARGB1555: 185 case DRM_FORMAT_XRGB1555: 186 cntl |= CNTL_LCDBPP16 | CNTL_BGR; 187 break; 188 case DRM_FORMAT_ABGR4444: 189 case DRM_FORMAT_XBGR4444: 190 cntl |= CNTL_LCDBPP16_444; 191 break; 192 case DRM_FORMAT_ARGB4444: 193 case DRM_FORMAT_XRGB4444: 194 cntl |= CNTL_LCDBPP16_444 | CNTL_BGR; 195 break; 196 default: 197 WARN_ONCE(true, "Unknown FB format 0x%08x\n", 198 fb->format->format); 199 break; 200 } 201 202 /* Power sequence: first enable and chill */ 203 writel(cntl, priv->regs + priv->ctrl); 204 205 /* 206 * We expect this delay to stabilize the contrast 207 * voltage Vee as stipulated by the manual 208 */ 209 msleep(20); 210 211 if (priv->variant_display_enable) 212 priv->variant_display_enable(drm, fb->format->format); 213 214 /* Power Up */ 215 cntl |= CNTL_LCDPWR; 216 writel(cntl, priv->regs + priv->ctrl); 217 218 drm_crtc_vblank_on(crtc); 219 } 220 221 void pl111_display_disable(struct drm_simple_display_pipe *pipe) 222 { 223 struct drm_crtc *crtc = &pipe->crtc; 224 struct drm_device *drm = crtc->dev; 225 struct pl111_drm_dev_private *priv = drm->dev_private; 226 u32 cntl; 227 228 drm_crtc_vblank_off(crtc); 229 230 /* Power Down */ 231 cntl = readl(priv->regs + priv->ctrl); 232 if (cntl & CNTL_LCDPWR) { 233 cntl &= ~CNTL_LCDPWR; 234 writel(cntl, priv->regs + priv->ctrl); 235 } 236 237 /* 238 * We expect this delay to stabilize the contrast voltage Vee as 239 * stipulated by the manual 240 */ 241 msleep(20); 242 243 if (priv->variant_display_disable) 244 priv->variant_display_disable(drm); 245 246 /* Disable */ 247 writel(0, priv->regs + priv->ctrl); 248 249 clk_disable_unprepare(priv->clk); 250 } 251 252 static void pl111_display_update(struct drm_simple_display_pipe *pipe, 253 struct drm_plane_state *old_pstate) 254 { 255 struct drm_crtc *crtc = &pipe->crtc; 256 struct drm_device *drm = crtc->dev; 257 struct pl111_drm_dev_private *priv = drm->dev_private; 258 struct drm_pending_vblank_event *event = crtc->state->event; 259 struct drm_plane *plane = &pipe->plane; 260 struct drm_plane_state *pstate = plane->state; 261 struct drm_framebuffer *fb = pstate->fb; 262 263 if (fb) { 264 u32 addr = drm_fb_cma_get_gem_addr(fb, pstate, 0); 265 266 writel(addr, priv->regs + CLCD_UBAS); 267 } 268 269 if (event) { 270 crtc->state->event = NULL; 271 272 spin_lock_irq(&crtc->dev->event_lock); 273 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) 274 drm_crtc_arm_vblank_event(crtc, event); 275 else 276 drm_crtc_send_vblank_event(crtc, event); 277 spin_unlock_irq(&crtc->dev->event_lock); 278 } 279 } 280 281 int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc) 282 { 283 struct pl111_drm_dev_private *priv = drm->dev_private; 284 285 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb); 286 287 return 0; 288 } 289 290 void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc) 291 { 292 struct pl111_drm_dev_private *priv = drm->dev_private; 293 294 writel(0, priv->regs + priv->ienb); 295 } 296 297 static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe, 298 struct drm_plane_state *plane_state) 299 { 300 return drm_gem_fb_prepare_fb(&pipe->plane, plane_state); 301 } 302 303 static const struct drm_simple_display_pipe_funcs pl111_display_funcs = { 304 .check = pl111_display_check, 305 .enable = pl111_display_enable, 306 .disable = pl111_display_disable, 307 .update = pl111_display_update, 308 .prepare_fb = pl111_display_prepare_fb, 309 }; 310 311 static int pl111_clk_div_choose_div(struct clk_hw *hw, unsigned long rate, 312 unsigned long *prate, bool set_parent) 313 { 314 int best_div = 1, div; 315 struct clk_hw *parent = clk_hw_get_parent(hw); 316 unsigned long best_prate = 0; 317 unsigned long best_diff = ~0ul; 318 int max_div = (1 << (TIM2_PCD_LO_BITS + TIM2_PCD_HI_BITS)) - 1; 319 320 for (div = 1; div < max_div; div++) { 321 unsigned long this_prate, div_rate, diff; 322 323 if (set_parent) 324 this_prate = clk_hw_round_rate(parent, rate * div); 325 else 326 this_prate = *prate; 327 div_rate = DIV_ROUND_UP_ULL(this_prate, div); 328 diff = abs(rate - div_rate); 329 330 if (diff < best_diff) { 331 best_div = div; 332 best_diff = diff; 333 best_prate = this_prate; 334 } 335 } 336 337 *prate = best_prate; 338 return best_div; 339 } 340 341 static long pl111_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, 342 unsigned long *prate) 343 { 344 int div = pl111_clk_div_choose_div(hw, rate, prate, true); 345 346 return DIV_ROUND_UP_ULL(*prate, div); 347 } 348 349 static unsigned long pl111_clk_div_recalc_rate(struct clk_hw *hw, 350 unsigned long prate) 351 { 352 struct pl111_drm_dev_private *priv = 353 container_of(hw, struct pl111_drm_dev_private, clk_div); 354 u32 tim2 = readl(priv->regs + CLCD_TIM2); 355 int div; 356 357 if (tim2 & TIM2_BCD) 358 return prate; 359 360 div = tim2 & TIM2_PCD_LO_MASK; 361 div |= (tim2 & TIM2_PCD_HI_MASK) >> 362 (TIM2_PCD_HI_SHIFT - TIM2_PCD_LO_BITS); 363 div += 2; 364 365 return DIV_ROUND_UP_ULL(prate, div); 366 } 367 368 static int pl111_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, 369 unsigned long prate) 370 { 371 struct pl111_drm_dev_private *priv = 372 container_of(hw, struct pl111_drm_dev_private, clk_div); 373 int div = pl111_clk_div_choose_div(hw, rate, &prate, false); 374 u32 tim2; 375 376 spin_lock(&priv->tim2_lock); 377 tim2 = readl(priv->regs + CLCD_TIM2); 378 tim2 &= ~(TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); 379 380 if (div == 1) { 381 tim2 |= TIM2_BCD; 382 } else { 383 div -= 2; 384 tim2 |= div & TIM2_PCD_LO_MASK; 385 tim2 |= (div >> TIM2_PCD_LO_BITS) << TIM2_PCD_HI_SHIFT; 386 } 387 388 writel(tim2, priv->regs + CLCD_TIM2); 389 spin_unlock(&priv->tim2_lock); 390 391 return 0; 392 } 393 394 static const struct clk_ops pl111_clk_div_ops = { 395 .recalc_rate = pl111_clk_div_recalc_rate, 396 .round_rate = pl111_clk_div_round_rate, 397 .set_rate = pl111_clk_div_set_rate, 398 }; 399 400 static int 401 pl111_init_clock_divider(struct drm_device *drm) 402 { 403 struct pl111_drm_dev_private *priv = drm->dev_private; 404 struct clk *parent = devm_clk_get(drm->dev, "clcdclk"); 405 struct clk_hw *div = &priv->clk_div; 406 const char *parent_name; 407 struct clk_init_data init = { 408 .name = "pl111_div", 409 .ops = &pl111_clk_div_ops, 410 .parent_names = &parent_name, 411 .num_parents = 1, 412 .flags = CLK_SET_RATE_PARENT, 413 }; 414 int ret; 415 416 if (IS_ERR(parent)) { 417 dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); 418 return PTR_ERR(parent); 419 } 420 parent_name = __clk_get_name(parent); 421 422 spin_lock_init(&priv->tim2_lock); 423 div->init = &init; 424 425 ret = devm_clk_hw_register(drm->dev, div); 426 427 priv->clk = div->clk; 428 return ret; 429 } 430 431 int pl111_display_init(struct drm_device *drm) 432 { 433 struct pl111_drm_dev_private *priv = drm->dev_private; 434 struct device *dev = drm->dev; 435 struct device_node *endpoint; 436 u32 tft_r0b0g0[3]; 437 int ret; 438 439 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 440 if (!endpoint) 441 return -ENODEV; 442 443 if (of_property_read_u32_array(endpoint, 444 "arm,pl11x,tft-r0g0b0-pads", 445 tft_r0b0g0, 446 ARRAY_SIZE(tft_r0b0g0)) != 0) { 447 dev_err(dev, "arm,pl11x,tft-r0g0b0-pads should be 3 ints\n"); 448 of_node_put(endpoint); 449 return -ENOENT; 450 } 451 of_node_put(endpoint); 452 453 ret = pl111_init_clock_divider(drm); 454 if (ret) 455 return ret; 456 457 ret = drm_simple_display_pipe_init(drm, &priv->pipe, 458 &pl111_display_funcs, 459 priv->variant->formats, 460 priv->variant->nformats, 461 NULL, 462 priv->connector); 463 if (ret) 464 return ret; 465 466 return 0; 467 } 468