]> Git Repo - linux.git/blob - drivers/gpu/drm/pl111/pl111_display.c
Merge tag 'perf-urgent-for-mingo-4.18-20180611' of git://git.kernel.org/pub/scm/linux...
[linux.git] / drivers / gpu / drm / pl111 / pl111_display.c
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 <[email protected]>
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 enum drm_mode_status
54 pl111_mode_valid(struct drm_crtc *crtc,
55                  const struct drm_display_mode *mode)
56 {
57         struct drm_device *drm = crtc->dev;
58         struct pl111_drm_dev_private *priv = drm->dev_private;
59         u32 cpp = priv->variant->fb_bpp / 8;
60         u64 bw;
61
62         /*
63          * We use the pixelclock to also account for interlaced modes, the
64          * resulting bandwidth is in bytes per second.
65          */
66         bw = mode->clock * 1000; /* In Hz */
67         bw = bw * mode->hdisplay * mode->vdisplay * cpp;
68         bw = div_u64(bw, mode->htotal * mode->vtotal);
69
70         /*
71          * If no bandwidth constraints, anything goes, else
72          * check if we are too fast.
73          */
74         if (priv->memory_bw && (bw > priv->memory_bw)) {
75                 DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu too fast\n",
76                               mode->hdisplay, mode->vdisplay,
77                               mode->clock * 1000, cpp, bw);
78
79                 return MODE_BAD;
80         }
81         DRM_DEBUG_KMS("%d x %d @ %d Hz, %d cpp, bw %llu bytes/s OK\n",
82                       mode->hdisplay, mode->vdisplay,
83                       mode->clock * 1000, cpp, bw);
84
85         return MODE_OK;
86 }
87
88 static int pl111_display_check(struct drm_simple_display_pipe *pipe,
89                                struct drm_plane_state *pstate,
90                                struct drm_crtc_state *cstate)
91 {
92         const struct drm_display_mode *mode = &cstate->mode;
93         struct drm_framebuffer *old_fb = pipe->plane.state->fb;
94         struct drm_framebuffer *fb = pstate->fb;
95
96         if (mode->hdisplay % 16)
97                 return -EINVAL;
98
99         if (fb) {
100                 u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0);
101
102                 /* FB base address must be dword aligned. */
103                 if (offset & 3)
104                         return -EINVAL;
105
106                 /* There's no pitch register -- the mode's hdisplay
107                  * controls it.
108                  */
109                 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0])
110                         return -EINVAL;
111
112                 /* We can't change the FB format in a flicker-free
113                  * manner (and only update it during CRTC enable).
114                  */
115                 if (old_fb && old_fb->format != fb->format)
116                         cstate->mode_changed = true;
117         }
118
119         return 0;
120 }
121
122 static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
123                                  struct drm_crtc_state *cstate,
124                                  struct drm_plane_state *plane_state)
125 {
126         struct drm_crtc *crtc = &pipe->crtc;
127         struct drm_plane *plane = &pipe->plane;
128         struct drm_device *drm = crtc->dev;
129         struct pl111_drm_dev_private *priv = drm->dev_private;
130         const struct drm_display_mode *mode = &cstate->mode;
131         struct drm_framebuffer *fb = plane->state->fb;
132         struct drm_connector *connector = priv->connector;
133         struct drm_bridge *bridge = priv->bridge;
134         u32 cntl;
135         u32 ppl, hsw, hfp, hbp;
136         u32 lpp, vsw, vfp, vbp;
137         u32 cpl, tim2;
138         int ret;
139
140         ret = clk_set_rate(priv->clk, mode->clock * 1000);
141         if (ret) {
142                 dev_err(drm->dev,
143                         "Failed to set pixel clock rate to %d: %d\n",
144                         mode->clock * 1000, ret);
145         }
146
147         clk_prepare_enable(priv->clk);
148
149         ppl = (mode->hdisplay / 16) - 1;
150         hsw = mode->hsync_end - mode->hsync_start - 1;
151         hfp = mode->hsync_start - mode->hdisplay - 1;
152         hbp = mode->htotal - mode->hsync_end - 1;
153
154         lpp = mode->vdisplay - 1;
155         vsw = mode->vsync_end - mode->vsync_start - 1;
156         vfp = mode->vsync_start - mode->vdisplay;
157         vbp = mode->vtotal - mode->vsync_end;
158
159         cpl = mode->hdisplay - 1;
160
161         writel((ppl << 2) |
162                (hsw << 8) |
163                (hfp << 16) |
164                (hbp << 24),
165                priv->regs + CLCD_TIM0);
166         writel(lpp |
167                (vsw << 10) |
168                (vfp << 16) |
169                (vbp << 24),
170                priv->regs + CLCD_TIM1);
171
172         spin_lock(&priv->tim2_lock);
173
174         tim2 = readl(priv->regs + CLCD_TIM2);
175         tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK);
176
177         if (priv->variant->broken_clockdivider)
178                 tim2 |= TIM2_BCD;
179
180         if (mode->flags & DRM_MODE_FLAG_NHSYNC)
181                 tim2 |= TIM2_IHS;
182
183         if (mode->flags & DRM_MODE_FLAG_NVSYNC)
184                 tim2 |= TIM2_IVS;
185
186         if (connector) {
187                 if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
188                         tim2 |= TIM2_IOE;
189
190                 if (connector->display_info.bus_flags &
191                     DRM_BUS_FLAG_PIXDATA_NEGEDGE)
192                         tim2 |= TIM2_IPC;
193         }
194
195         if (bridge) {
196                 const struct drm_bridge_timings *btimings = bridge->timings;
197
198                 /*
199                  * Here is when things get really fun. Sometimes the bridge
200                  * timings are such that the signal out from PL11x is not
201                  * stable before the receiving bridge (such as a dumb VGA DAC
202                  * or similar) samples it. If that happens, we compensate by
203                  * the only method we have: output the data on the opposite
204                  * edge of the clock so it is for sure stable when it gets
205                  * sampled.
206                  *
207                  * The PL111 manual does not contain proper timining diagrams
208                  * or data for these details, but we know from experiments
209                  * that the setup time is more than 3000 picoseconds (3 ns).
210                  * If we have a bridge that requires the signal to be stable
211                  * earlier than 3000 ps before the clock pulse, we have to
212                  * output the data on the opposite edge to avoid flicker.
213                  */
214                 if (btimings && btimings->setup_time_ps >= 3000)
215                         tim2 ^= TIM2_IPC;
216         }
217
218         tim2 |= cpl << 16;
219         writel(tim2, priv->regs + CLCD_TIM2);
220         spin_unlock(&priv->tim2_lock);
221
222         writel(0, priv->regs + CLCD_TIM3);
223
224         /* Hard-code TFT panel */
225         cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDVCOMP(1);
226
227         /* Note that the the hardware's format reader takes 'r' from
228          * the low bit, while DRM formats list channels from high bit
229          * to low bit as you read left to right.
230          */
231         switch (fb->format->format) {
232         case DRM_FORMAT_ABGR8888:
233         case DRM_FORMAT_XBGR8888:
234                 cntl |= CNTL_LCDBPP24;
235                 break;
236         case DRM_FORMAT_ARGB8888:
237         case DRM_FORMAT_XRGB8888:
238                 cntl |= CNTL_LCDBPP24 | CNTL_BGR;
239                 break;
240         case DRM_FORMAT_BGR565:
241                 if (priv->variant->is_pl110)
242                         cntl |= CNTL_LCDBPP16;
243                 else
244                         cntl |= CNTL_LCDBPP16_565;
245                 break;
246         case DRM_FORMAT_RGB565:
247                 if (priv->variant->is_pl110)
248                         cntl |= CNTL_LCDBPP16;
249                 else
250                         cntl |= CNTL_LCDBPP16_565;
251                 cntl |= CNTL_BGR;
252                 break;
253         case DRM_FORMAT_ABGR1555:
254         case DRM_FORMAT_XBGR1555:
255                 cntl |= CNTL_LCDBPP16;
256                 break;
257         case DRM_FORMAT_ARGB1555:
258         case DRM_FORMAT_XRGB1555:
259                 cntl |= CNTL_LCDBPP16 | CNTL_BGR;
260                 break;
261         case DRM_FORMAT_ABGR4444:
262         case DRM_FORMAT_XBGR4444:
263                 cntl |= CNTL_LCDBPP16_444;
264                 break;
265         case DRM_FORMAT_ARGB4444:
266         case DRM_FORMAT_XRGB4444:
267                 cntl |= CNTL_LCDBPP16_444 | CNTL_BGR;
268                 break;
269         default:
270                 WARN_ONCE(true, "Unknown FB format 0x%08x\n",
271                           fb->format->format);
272                 break;
273         }
274
275         /* The PL110 in Integrator/Versatile does the BGR routing externally */
276         if (priv->variant->external_bgr)
277                 cntl &= ~CNTL_BGR;
278
279         /* Power sequence: first enable and chill */
280         writel(cntl, priv->regs + priv->ctrl);
281
282         /*
283          * We expect this delay to stabilize the contrast
284          * voltage Vee as stipulated by the manual
285          */
286         msleep(20);
287
288         if (priv->variant_display_enable)
289                 priv->variant_display_enable(drm, fb->format->format);
290
291         /* Power Up */
292         cntl |= CNTL_LCDPWR;
293         writel(cntl, priv->regs + priv->ctrl);
294
295         if (!priv->variant->broken_vblank)
296                 drm_crtc_vblank_on(crtc);
297 }
298
299 void pl111_display_disable(struct drm_simple_display_pipe *pipe)
300 {
301         struct drm_crtc *crtc = &pipe->crtc;
302         struct drm_device *drm = crtc->dev;
303         struct pl111_drm_dev_private *priv = drm->dev_private;
304         u32 cntl;
305
306         if (!priv->variant->broken_vblank)
307                 drm_crtc_vblank_off(crtc);
308
309         /* Power Down */
310         cntl = readl(priv->regs + priv->ctrl);
311         if (cntl & CNTL_LCDPWR) {
312                 cntl &= ~CNTL_LCDPWR;
313                 writel(cntl, priv->regs + priv->ctrl);
314         }
315
316         /*
317          * We expect this delay to stabilize the contrast voltage Vee as
318          * stipulated by the manual
319          */
320         msleep(20);
321
322         if (priv->variant_display_disable)
323                 priv->variant_display_disable(drm);
324
325         /* Disable */
326         writel(0, priv->regs + priv->ctrl);
327
328         clk_disable_unprepare(priv->clk);
329 }
330
331 static void pl111_display_update(struct drm_simple_display_pipe *pipe,
332                                  struct drm_plane_state *old_pstate)
333 {
334         struct drm_crtc *crtc = &pipe->crtc;
335         struct drm_device *drm = crtc->dev;
336         struct pl111_drm_dev_private *priv = drm->dev_private;
337         struct drm_pending_vblank_event *event = crtc->state->event;
338         struct drm_plane *plane = &pipe->plane;
339         struct drm_plane_state *pstate = plane->state;
340         struct drm_framebuffer *fb = pstate->fb;
341
342         if (fb) {
343                 u32 addr = drm_fb_cma_get_gem_addr(fb, pstate, 0);
344
345                 writel(addr, priv->regs + CLCD_UBAS);
346         }
347
348         if (event) {
349                 crtc->state->event = NULL;
350
351                 spin_lock_irq(&crtc->dev->event_lock);
352                 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
353                         drm_crtc_arm_vblank_event(crtc, event);
354                 else
355                         drm_crtc_send_vblank_event(crtc, event);
356                 spin_unlock_irq(&crtc->dev->event_lock);
357         }
358 }
359
360 static int pl111_display_enable_vblank(struct drm_simple_display_pipe *pipe)
361 {
362         struct drm_crtc *crtc = &pipe->crtc;
363         struct drm_device *drm = crtc->dev;
364         struct pl111_drm_dev_private *priv = drm->dev_private;
365
366         writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb);
367
368         return 0;
369 }
370
371 static void pl111_display_disable_vblank(struct drm_simple_display_pipe *pipe)
372 {
373         struct drm_crtc *crtc = &pipe->crtc;
374         struct drm_device *drm = crtc->dev;
375         struct pl111_drm_dev_private *priv = drm->dev_private;
376
377         writel(0, priv->regs + priv->ienb);
378 }
379
380 static struct drm_simple_display_pipe_funcs pl111_display_funcs = {
381         .mode_valid = pl111_mode_valid,
382         .check = pl111_display_check,
383         .enable = pl111_display_enable,
384         .disable = pl111_display_disable,
385         .update = pl111_display_update,
386         .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
387 };
388
389 static int pl111_clk_div_choose_div(struct clk_hw *hw, unsigned long rate,
390                                     unsigned long *prate, bool set_parent)
391 {
392         int best_div = 1, div;
393         struct clk_hw *parent = clk_hw_get_parent(hw);
394         unsigned long best_prate = 0;
395         unsigned long best_diff = ~0ul;
396         int max_div = (1 << (TIM2_PCD_LO_BITS + TIM2_PCD_HI_BITS)) - 1;
397
398         for (div = 1; div < max_div; div++) {
399                 unsigned long this_prate, div_rate, diff;
400
401                 if (set_parent)
402                         this_prate = clk_hw_round_rate(parent, rate * div);
403                 else
404                         this_prate = *prate;
405                 div_rate = DIV_ROUND_UP_ULL(this_prate, div);
406                 diff = abs(rate - div_rate);
407
408                 if (diff < best_diff) {
409                         best_div = div;
410                         best_diff = diff;
411                         best_prate = this_prate;
412                 }
413         }
414
415         *prate = best_prate;
416         return best_div;
417 }
418
419 static long pl111_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
420                                      unsigned long *prate)
421 {
422         int div = pl111_clk_div_choose_div(hw, rate, prate, true);
423
424         return DIV_ROUND_UP_ULL(*prate, div);
425 }
426
427 static unsigned long pl111_clk_div_recalc_rate(struct clk_hw *hw,
428                                                unsigned long prate)
429 {
430         struct pl111_drm_dev_private *priv =
431                 container_of(hw, struct pl111_drm_dev_private, clk_div);
432         u32 tim2 = readl(priv->regs + CLCD_TIM2);
433         int div;
434
435         if (tim2 & TIM2_BCD)
436                 return prate;
437
438         div = tim2 & TIM2_PCD_LO_MASK;
439         div |= (tim2 & TIM2_PCD_HI_MASK) >>
440                 (TIM2_PCD_HI_SHIFT - TIM2_PCD_LO_BITS);
441         div += 2;
442
443         return DIV_ROUND_UP_ULL(prate, div);
444 }
445
446 static int pl111_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
447                                   unsigned long prate)
448 {
449         struct pl111_drm_dev_private *priv =
450                 container_of(hw, struct pl111_drm_dev_private, clk_div);
451         int div = pl111_clk_div_choose_div(hw, rate, &prate, false);
452         u32 tim2;
453
454         spin_lock(&priv->tim2_lock);
455         tim2 = readl(priv->regs + CLCD_TIM2);
456         tim2 &= ~(TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK);
457
458         if (div == 1) {
459                 tim2 |= TIM2_BCD;
460         } else {
461                 div -= 2;
462                 tim2 |= div & TIM2_PCD_LO_MASK;
463                 tim2 |= (div >> TIM2_PCD_LO_BITS) << TIM2_PCD_HI_SHIFT;
464         }
465
466         writel(tim2, priv->regs + CLCD_TIM2);
467         spin_unlock(&priv->tim2_lock);
468
469         return 0;
470 }
471
472 static const struct clk_ops pl111_clk_div_ops = {
473         .recalc_rate = pl111_clk_div_recalc_rate,
474         .round_rate = pl111_clk_div_round_rate,
475         .set_rate = pl111_clk_div_set_rate,
476 };
477
478 static int
479 pl111_init_clock_divider(struct drm_device *drm)
480 {
481         struct pl111_drm_dev_private *priv = drm->dev_private;
482         struct clk *parent = devm_clk_get(drm->dev, "clcdclk");
483         struct clk_hw *div = &priv->clk_div;
484         const char *parent_name;
485         struct clk_init_data init = {
486                 .name = "pl111_div",
487                 .ops = &pl111_clk_div_ops,
488                 .parent_names = &parent_name,
489                 .num_parents = 1,
490                 .flags = CLK_SET_RATE_PARENT,
491         };
492         int ret;
493
494         if (IS_ERR(parent)) {
495                 dev_err(drm->dev, "CLCD: unable to get clcdclk.\n");
496                 return PTR_ERR(parent);
497         }
498         /* If the clock divider is broken, use the parent directly */
499         if (priv->variant->broken_clockdivider) {
500                 priv->clk = parent;
501                 return 0;
502         }
503         parent_name = __clk_get_name(parent);
504
505         spin_lock_init(&priv->tim2_lock);
506         div->init = &init;
507
508         ret = devm_clk_hw_register(drm->dev, div);
509
510         priv->clk = div->clk;
511         return ret;
512 }
513
514 int pl111_display_init(struct drm_device *drm)
515 {
516         struct pl111_drm_dev_private *priv = drm->dev_private;
517         struct device *dev = drm->dev;
518         struct device_node *endpoint;
519         u32 tft_r0b0g0[3];
520         int ret;
521
522         endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
523         if (!endpoint)
524                 return -ENODEV;
525
526         if (of_property_read_u32_array(endpoint,
527                                        "arm,pl11x,tft-r0g0b0-pads",
528                                        tft_r0b0g0,
529                                        ARRAY_SIZE(tft_r0b0g0)) != 0) {
530                 dev_err(dev, "arm,pl11x,tft-r0g0b0-pads should be 3 ints\n");
531                 of_node_put(endpoint);
532                 return -ENOENT;
533         }
534         of_node_put(endpoint);
535
536         ret = pl111_init_clock_divider(drm);
537         if (ret)
538                 return ret;
539
540         if (!priv->variant->broken_vblank) {
541                 pl111_display_funcs.enable_vblank = pl111_display_enable_vblank;
542                 pl111_display_funcs.disable_vblank = pl111_display_disable_vblank;
543         }
544
545         ret = drm_simple_display_pipe_init(drm, &priv->pipe,
546                                            &pl111_display_funcs,
547                                            priv->variant->formats,
548                                            priv->variant->nformats,
549                                            NULL,
550                                            priv->connector);
551         if (ret)
552                 return ret;
553
554         return 0;
555 }
This page took 0.06449 seconds and 4 git commands to generate.