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