Lines Matching +full:int +full:- +full:clock +full:- +full:stable +full:- +full:broken

1 // SPDX-License-Identifier: GPL-2.0-only
3 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
7 * Copyright (c) 2006-2008 Intel Corporation
14 #include <linux/dma-buf.h>
15 #include <linux/media-bus-format.h>
27 irqreturn_t pl111_irq(int irq, void *data) in pl111_irq()
33 irq_stat = readl(priv->regs + CLCD_PL111_MIS); in pl111_irq()
39 drm_crtc_handle_vblank(&priv->pipe.crtc); in pl111_irq()
45 writel(irq_stat, priv->regs + CLCD_PL111_ICR); in pl111_irq()
54 struct drm_device *drm = pipe->crtc.dev; in pl111_mode_valid()
55 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_mode_valid()
56 u32 cpp = DIV_ROUND_UP(priv->variant->fb_depth, 8); in pl111_mode_valid()
63 bw = mode->clock * 1000ULL; /* In Hz */ in pl111_mode_valid()
64 bw = bw * mode->hdisplay * mode->vdisplay * cpp; in pl111_mode_valid()
65 bw = div_u64(bw, mode->htotal * mode->vtotal); in pl111_mode_valid()
71 if (priv->memory_bw && (bw > priv->memory_bw)) { in pl111_mode_valid()
73 mode->hdisplay, mode->vdisplay, in pl111_mode_valid()
74 mode->clock * 1000, cpp, bw); in pl111_mode_valid()
79 mode->hdisplay, mode->vdisplay, in pl111_mode_valid()
80 mode->clock * 1000, cpp, bw); in pl111_mode_valid()
85 static int pl111_display_check(struct drm_simple_display_pipe *pipe, in pl111_display_check()
89 const struct drm_display_mode *mode = &cstate->mode; in pl111_display_check()
90 struct drm_framebuffer *old_fb = pipe->plane.state->fb; in pl111_display_check()
91 struct drm_framebuffer *fb = pstate->fb; in pl111_display_check()
93 if (mode->hdisplay % 16) in pl111_display_check()
94 return -EINVAL; in pl111_display_check()
101 return -EINVAL; in pl111_display_check()
103 /* There's no pitch register -- the mode's hdisplay in pl111_display_check()
106 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) in pl111_display_check()
107 return -EINVAL; in pl111_display_check()
109 /* We can't change the FB format in a flicker-free in pl111_display_check()
112 if (old_fb && old_fb->format != fb->format) in pl111_display_check()
113 cstate->mode_changed = true; in pl111_display_check()
123 struct drm_crtc *crtc = &pipe->crtc; in pl111_display_enable()
124 struct drm_plane *plane = &pipe->plane; in pl111_display_enable()
125 struct drm_device *drm = crtc->dev; in pl111_display_enable()
126 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_display_enable()
127 const struct drm_display_mode *mode = &cstate->mode; in pl111_display_enable()
128 struct drm_framebuffer *fb = plane->state->fb; in pl111_display_enable()
129 struct drm_connector *connector = priv->connector; in pl111_display_enable()
130 struct drm_bridge *bridge = priv->bridge; in pl111_display_enable()
136 int ret; in pl111_display_enable()
138 ret = clk_set_rate(priv->clk, mode->clock * 1000); in pl111_display_enable()
140 dev_err(drm->dev, in pl111_display_enable()
141 "Failed to set pixel clock rate to %d: %d\n", in pl111_display_enable()
142 mode->clock * 1000, ret); in pl111_display_enable()
145 clk_prepare_enable(priv->clk); in pl111_display_enable()
147 ppl = (mode->hdisplay / 16) - 1; in pl111_display_enable()
148 hsw = mode->hsync_end - mode->hsync_start - 1; in pl111_display_enable()
149 hfp = mode->hsync_start - mode->hdisplay - 1; in pl111_display_enable()
150 hbp = mode->htotal - mode->hsync_end - 1; in pl111_display_enable()
152 lpp = mode->vdisplay - 1; in pl111_display_enable()
153 vsw = mode->vsync_end - mode->vsync_start - 1; in pl111_display_enable()
154 vfp = mode->vsync_start - mode->vdisplay; in pl111_display_enable()
155 vbp = mode->vtotal - mode->vsync_end; in pl111_display_enable()
157 cpl = mode->hdisplay - 1; in pl111_display_enable()
163 priv->regs + CLCD_TIM0); in pl111_display_enable()
168 priv->regs + CLCD_TIM1); in pl111_display_enable()
170 spin_lock(&priv->tim2_lock); in pl111_display_enable()
172 tim2 = readl(priv->regs + CLCD_TIM2); in pl111_display_enable()
175 if (priv->variant->broken_clockdivider) in pl111_display_enable()
178 if (mode->flags & DRM_MODE_FLAG_NHSYNC) in pl111_display_enable()
181 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in pl111_display_enable()
185 if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) in pl111_display_enable()
188 if (connector->display_info.bus_flags & in pl111_display_enable()
192 if (connector->display_info.num_bus_formats == 1 && in pl111_display_enable()
193 connector->display_info.bus_formats[0] == in pl111_display_enable()
208 const struct drm_bridge_timings *btimings = bridge->timings; in pl111_display_enable()
213 * stable before the receiving bridge (such as a dumb VGA DAC in pl111_display_enable()
216 * edge of the clock so it is for sure stable when it gets in pl111_display_enable()
222 * If we have a bridge that requires the signal to be stable in pl111_display_enable()
223 * earlier than 3000 ps before the clock pulse, we have to in pl111_display_enable()
226 if (btimings && btimings->setup_time_ps >= 3000) in pl111_display_enable()
231 writel(tim2, priv->regs + CLCD_TIM2); in pl111_display_enable()
232 spin_unlock(&priv->tim2_lock); in pl111_display_enable()
234 writel(0, priv->regs + CLCD_TIM3); in pl111_display_enable()
249 if (priv->variant->st_bitmux_control) in pl111_display_enable()
258 switch (fb->format->format) { in pl111_display_enable()
261 if (priv->variant->st_bitmux_control) in pl111_display_enable()
266 if (priv->variant->st_bitmux_control) in pl111_display_enable()
271 if (priv->variant->st_bitmux_control) in pl111_display_enable()
278 if (priv->variant->st_bitmux_control) in pl111_display_enable()
284 if (priv->variant->is_pl110) in pl111_display_enable()
286 else if (priv->variant->st_bitmux_control) in pl111_display_enable()
292 if (priv->variant->is_pl110) in pl111_display_enable()
294 else if (priv->variant->st_bitmux_control) in pl111_display_enable()
302 if (priv->variant->st_bitmux_control) in pl111_display_enable()
308 if (priv->variant->st_bitmux_control) in pl111_display_enable()
316 if (priv->variant->st_bitmux_control) in pl111_display_enable()
322 if (priv->variant->st_bitmux_control) in pl111_display_enable()
329 fb->format->format); in pl111_display_enable()
334 if (priv->variant->external_bgr) in pl111_display_enable()
338 writel(cntl, priv->regs + priv->ctrl); in pl111_display_enable()
346 if (priv->variant_display_enable) in pl111_display_enable()
347 priv->variant_display_enable(drm, fb->format->format); in pl111_display_enable()
351 writel(cntl, priv->regs + priv->ctrl); in pl111_display_enable()
353 if (!priv->variant->broken_vblank) in pl111_display_enable()
359 struct drm_crtc *crtc = &pipe->crtc; in pl111_display_disable()
360 struct drm_device *drm = crtc->dev; in pl111_display_disable()
361 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_display_disable()
364 if (!priv->variant->broken_vblank) in pl111_display_disable()
368 cntl = readl(priv->regs + priv->ctrl); in pl111_display_disable()
371 writel(cntl, priv->regs + priv->ctrl); in pl111_display_disable()
380 if (priv->variant_display_disable) in pl111_display_disable()
381 priv->variant_display_disable(drm); in pl111_display_disable()
384 writel(0, priv->regs + priv->ctrl); in pl111_display_disable()
386 clk_disable_unprepare(priv->clk); in pl111_display_disable()
392 struct drm_crtc *crtc = &pipe->crtc; in pl111_display_update()
393 struct drm_device *drm = crtc->dev; in pl111_display_update()
394 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_display_update()
395 struct drm_pending_vblank_event *event = crtc->state->event; in pl111_display_update()
396 struct drm_plane *plane = &pipe->plane; in pl111_display_update()
397 struct drm_plane_state *pstate = plane->state; in pl111_display_update()
398 struct drm_framebuffer *fb = pstate->fb; in pl111_display_update()
403 writel(addr, priv->regs + CLCD_UBAS); in pl111_display_update()
407 crtc->state->event = NULL; in pl111_display_update()
409 spin_lock_irq(&crtc->dev->event_lock); in pl111_display_update()
410 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) in pl111_display_update()
414 spin_unlock_irq(&crtc->dev->event_lock); in pl111_display_update()
418 static int pl111_display_enable_vblank(struct drm_simple_display_pipe *pipe) in pl111_display_enable_vblank()
420 struct drm_crtc *crtc = &pipe->crtc; in pl111_display_enable_vblank()
421 struct drm_device *drm = crtc->dev; in pl111_display_enable_vblank()
422 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_display_enable_vblank()
424 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + priv->ienb); in pl111_display_enable_vblank()
431 struct drm_crtc *crtc = &pipe->crtc; in pl111_display_disable_vblank()
432 struct drm_device *drm = crtc->dev; in pl111_display_disable_vblank()
433 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_display_disable_vblank()
435 writel(0, priv->regs + priv->ienb); in pl111_display_disable_vblank()
446 static int pl111_clk_div_choose_div(struct clk_hw *hw, unsigned long rate, in pl111_clk_div_choose_div()
449 int best_div = 1, div; in pl111_clk_div_choose_div()
453 int max_div = (1 << (TIM2_PCD_LO_BITS + TIM2_PCD_HI_BITS)) - 1; in pl111_clk_div_choose_div()
463 diff = abs(rate - div_rate); in pl111_clk_div_choose_div()
479 int div = pl111_clk_div_choose_div(hw, rate, prate, true); in pl111_clk_div_round_rate()
489 u32 tim2 = readl(priv->regs + CLCD_TIM2); in pl111_clk_div_recalc_rate()
490 int div; in pl111_clk_div_recalc_rate()
497 (TIM2_PCD_HI_SHIFT - TIM2_PCD_LO_BITS); in pl111_clk_div_recalc_rate()
503 static int pl111_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, in pl111_clk_div_set_rate()
508 int div = pl111_clk_div_choose_div(hw, rate, &prate, false); in pl111_clk_div_set_rate()
511 spin_lock(&priv->tim2_lock); in pl111_clk_div_set_rate()
512 tim2 = readl(priv->regs + CLCD_TIM2); in pl111_clk_div_set_rate()
518 div -= 2; in pl111_clk_div_set_rate()
523 writel(tim2, priv->regs + CLCD_TIM2); in pl111_clk_div_set_rate()
524 spin_unlock(&priv->tim2_lock); in pl111_clk_div_set_rate()
535 static int
538 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_init_clock_divider()
539 struct clk *parent = devm_clk_get(drm->dev, "clcdclk"); in pl111_init_clock_divider()
540 struct clk_hw *div = &priv->clk_div; in pl111_init_clock_divider()
549 int ret; in pl111_init_clock_divider()
552 dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); in pl111_init_clock_divider()
556 spin_lock_init(&priv->tim2_lock); in pl111_init_clock_divider()
558 /* If the clock divider is broken, use the parent directly */ in pl111_init_clock_divider()
559 if (priv->variant->broken_clockdivider) { in pl111_init_clock_divider()
560 priv->clk = parent; in pl111_init_clock_divider()
564 div->init = &init; in pl111_init_clock_divider()
566 ret = devm_clk_hw_register(drm->dev, div); in pl111_init_clock_divider()
568 priv->clk = div->clk; in pl111_init_clock_divider()
572 int pl111_display_init(struct drm_device *drm) in pl111_display_init()
574 struct pl111_drm_dev_private *priv = drm->dev_private; in pl111_display_init()
575 int ret; in pl111_display_init()
581 if (!priv->variant->broken_vblank) { in pl111_display_init()
586 ret = drm_simple_display_pipe_init(drm, &priv->pipe, in pl111_display_init()
588 priv->variant->formats, in pl111_display_init()
589 priv->variant->nformats, in pl111_display_init()
591 priv->connector); in pl111_display_init()