Lines Matching +full:flip +full:- +full:vertical
1 // SPDX-License-Identifier: GPL-2.0+
3 * shmob_drm_crtc.c -- SH Mobile DRM CRTCs
11 #include <linux/media-bus-format.h>
43 /* -----------------------------------------------------------------------------
44 * Page Flip
50 struct drm_device *dev = scrtc->base.dev; in shmob_drm_crtc_finish_page_flip()
53 spin_lock_irqsave(&dev->event_lock, flags); in shmob_drm_crtc_finish_page_flip()
54 event = scrtc->event; in shmob_drm_crtc_finish_page_flip()
55 scrtc->event = NULL; in shmob_drm_crtc_finish_page_flip()
57 drm_crtc_send_vblank_event(&scrtc->base, event); in shmob_drm_crtc_finish_page_flip()
58 wake_up(&scrtc->flip_wait); in shmob_drm_crtc_finish_page_flip()
59 drm_crtc_vblank_put(&scrtc->base); in shmob_drm_crtc_finish_page_flip()
61 spin_unlock_irqrestore(&dev->event_lock, flags); in shmob_drm_crtc_finish_page_flip()
66 struct drm_device *dev = scrtc->base.dev; in shmob_drm_crtc_page_flip_pending()
70 spin_lock_irqsave(&dev->event_lock, flags); in shmob_drm_crtc_page_flip_pending()
71 pending = scrtc->event != NULL; in shmob_drm_crtc_page_flip_pending()
72 spin_unlock_irqrestore(&dev->event_lock, flags); in shmob_drm_crtc_page_flip_pending()
79 struct drm_crtc *crtc = &scrtc->base; in shmob_drm_crtc_wait_page_flip()
80 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); in shmob_drm_crtc_wait_page_flip()
82 if (wait_event_timeout(scrtc->flip_wait, in shmob_drm_crtc_wait_page_flip()
87 dev_warn(sdev->dev, "page flip timeout\n"); in shmob_drm_crtc_wait_page_flip()
92 /* -----------------------------------------------------------------------------
112 struct drm_crtc *crtc = &scrtc->base; in shmob_drm_crtc_setup_geometry()
113 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); in shmob_drm_crtc_setup_geometry()
114 const struct drm_display_info *info = &sdev->connector->display_info; in shmob_drm_crtc_setup_geometry()
115 const struct drm_display_mode *mode = &crtc->mode; in shmob_drm_crtc_setup_geometry()
119 if (!info->num_bus_formats || !info->bus_formats) { in shmob_drm_crtc_setup_geometry()
120 dev_warn(sdev->dev, "No bus format reported, using RGB888\n"); in shmob_drm_crtc_setup_geometry()
124 if (shmob_drm_bus_fmts[i].fmt == info->bus_formats[0]) in shmob_drm_crtc_setup_geometry()
130 dev_warn(sdev->dev, in shmob_drm_crtc_setup_geometry()
132 info->bus_formats[0]); in shmob_drm_crtc_setup_geometry()
137 if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) in shmob_drm_crtc_setup_geometry()
139 if (info->bus_flags & DRM_BUS_FLAG_DE_LOW) in shmob_drm_crtc_setup_geometry()
141 if (mode->flags & DRM_MODE_FLAG_NVSYNC) in shmob_drm_crtc_setup_geometry()
143 if (mode->flags & DRM_MODE_FLAG_NHSYNC) in shmob_drm_crtc_setup_geometry()
147 value = ((mode->hdisplay / 8) << 16) /* HDCN */ in shmob_drm_crtc_setup_geometry()
148 | (mode->htotal / 8); /* HTCN */ in shmob_drm_crtc_setup_geometry()
151 value = (((mode->hsync_end - mode->hsync_start) / 8) << 16) /* HSYNW */ in shmob_drm_crtc_setup_geometry()
152 | (mode->hsync_start / 8); /* HSYNP */ in shmob_drm_crtc_setup_geometry()
155 value = ((mode->hdisplay & 7) << 24) | ((mode->htotal & 7) << 16) in shmob_drm_crtc_setup_geometry()
156 | (((mode->hsync_end - mode->hsync_start) & 7) << 8) in shmob_drm_crtc_setup_geometry()
157 | (mode->hsync_start & 7); in shmob_drm_crtc_setup_geometry()
160 value = ((mode->vdisplay) << 16) /* VDLN */ in shmob_drm_crtc_setup_geometry()
161 | mode->vtotal; /* VTLN */ in shmob_drm_crtc_setup_geometry()
164 value = ((mode->vsync_end - mode->vsync_start) << 16) /* VSYNW */ in shmob_drm_crtc_setup_geometry()
165 | mode->vsync_start; /* VSYNP */ in shmob_drm_crtc_setup_geometry()
171 struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev); in shmob_drm_crtc_start_stop()
204 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); in shmob_drm_crtc_atomic_enable()
205 unsigned int clk_div = sdev->config.clk_div; in shmob_drm_crtc_atomic_enable()
206 struct device *dev = sdev->dev; in shmob_drm_crtc_atomic_enable()
226 value = sdev->lddckr; in shmob_drm_crtc_atomic_enable()
232 lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1); in shmob_drm_crtc_atomic_enable()
254 /* Turn vertical blank interrupt reporting back on. */ in shmob_drm_crtc_atomic_enable()
262 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); in shmob_drm_crtc_atomic_disable()
265 * Disable vertical blank interrupt reporting. We first need to wait in shmob_drm_crtc_atomic_disable()
266 * for page flip completion before stopping the CRTC as userspace in shmob_drm_crtc_atomic_disable()
278 pm_runtime_put(sdev->dev); in shmob_drm_crtc_atomic_disable()
285 struct drm_device *dev = crtc->dev; in shmob_drm_crtc_atomic_flush()
288 if (crtc->state->event) { in shmob_drm_crtc_atomic_flush()
289 spin_lock_irqsave(&dev->event_lock, flags); in shmob_drm_crtc_atomic_flush()
290 event = crtc->state->event; in shmob_drm_crtc_atomic_flush()
291 crtc->state->event = NULL; in shmob_drm_crtc_atomic_flush()
293 spin_unlock_irqrestore(&dev->event_lock, flags); in shmob_drm_crtc_atomic_flush()
310 struct drm_device *dev = scrtc->base.dev; in shmob_drm_crtc_page_flip()
313 spin_lock_irqsave(&dev->event_lock, flags); in shmob_drm_crtc_page_flip()
314 if (scrtc->event != NULL) { in shmob_drm_crtc_page_flip()
315 spin_unlock_irqrestore(&dev->event_lock, flags); in shmob_drm_crtc_page_flip()
316 return -EBUSY; in shmob_drm_crtc_page_flip()
318 spin_unlock_irqrestore(&dev->event_lock, flags); in shmob_drm_crtc_page_flip()
320 drm_atomic_set_fb_for_plane(crtc->primary->state, fb); in shmob_drm_crtc_page_flip()
323 event->pipe = 0; in shmob_drm_crtc_page_flip()
324 drm_crtc_vblank_get(&scrtc->base); in shmob_drm_crtc_page_flip()
325 spin_lock_irqsave(&dev->event_lock, flags); in shmob_drm_crtc_page_flip()
326 scrtc->event = event; in shmob_drm_crtc_page_flip()
327 spin_unlock_irqrestore(&dev->event_lock, flags); in shmob_drm_crtc_page_flip()
340 spin_lock_irqsave(&sdev->irq_lock, flags); in shmob_drm_crtc_enable_vblank()
347 spin_unlock_irqrestore(&sdev->irq_lock, flags); in shmob_drm_crtc_enable_vblank()
352 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); in shmob_drm_enable_vblank()
361 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); in shmob_drm_disable_vblank()
379 struct drm_crtc *crtc = &sdev->crtc.base; in shmob_drm_crtc_create()
384 init_waitqueue_head(&sdev->crtc.flip_wait); in shmob_drm_crtc_create()
396 ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL, in shmob_drm_crtc_create()
403 /* Start with vertical blank interrupt reporting disabled. */ in shmob_drm_crtc_create()
409 /* -----------------------------------------------------------------------------
417 struct drm_device *dev = encoder->dev; in shmob_drm_encoder_mode_fixup()
419 struct drm_connector *connector = sdev->connector; in shmob_drm_encoder_mode_fixup()
422 if (list_empty(&connector->modes)) { in shmob_drm_encoder_mode_fixup()
423 dev_dbg(dev->dev, "mode_fixup: empty modes list\n"); in shmob_drm_encoder_mode_fixup()
428 panel_mode = list_first_entry(&connector->modes, in shmob_drm_encoder_mode_fixup()
439 /* -----------------------------------------------------------------------------
445 struct drm_encoder *encoder = &sdev->encoder; in shmob_drm_encoder_create()
449 encoder->possible_crtcs = 1; in shmob_drm_encoder_create()
451 ret = drm_simple_encoder_init(&sdev->ddev, encoder, in shmob_drm_encoder_create()
456 if (sdev->pdata) { in shmob_drm_encoder_create()
462 bridge = devm_drm_of_get_bridge(sdev->dev, sdev->dev->of_node, 0, 0); in shmob_drm_encoder_create()
470 dev_err(sdev->dev, "failed to attach bridge: %pe\n", in shmob_drm_encoder_create()
478 /* -----------------------------------------------------------------------------
492 mode = drm_mode_create(connector->dev); in shmob_drm_connector_get_modes()
496 mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; in shmob_drm_connector_get_modes()
498 drm_display_mode_from_videomode(scon->mode, mode); in shmob_drm_connector_get_modes()
510 return scon->encoder; in shmob_drm_connector_best_encoder()
538 u32 bus_fmt = sdev->pdata->iface.bus_fmt; in shmob_drm_connector_init()
550 dev_err(sdev->dev, "unsupported bus format 0x%x\n", bus_fmt); in shmob_drm_connector_init()
551 return ERR_PTR(-EINVAL); in shmob_drm_connector_init()
556 return ERR_PTR(-ENOMEM); in shmob_drm_connector_init()
558 connector = &scon->base; in shmob_drm_connector_init()
559 scon->encoder = encoder; in shmob_drm_connector_init()
560 scon->mode = &sdev->pdata->panel.mode; in shmob_drm_connector_init()
562 info = &connector->display_info; in shmob_drm_connector_init()
563 info->width_mm = sdev->pdata->panel.width_mm; in shmob_drm_connector_init()
564 info->height_mm = sdev->pdata->panel.height_mm; in shmob_drm_connector_init()
566 if (scon->mode->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) in shmob_drm_connector_init()
567 info->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; in shmob_drm_connector_init()
568 if (scon->mode->flags & DISPLAY_FLAGS_DE_LOW) in shmob_drm_connector_init()
569 info->bus_flags |= DRM_BUS_FLAG_DE_LOW; in shmob_drm_connector_init()
577 ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs, in shmob_drm_connector_init()
589 /* -----------------------------------------------------------------------------
599 if (sdev->pdata) in shmob_drm_connector_create()
602 connector = drm_bridge_connector_init(&sdev->ddev, encoder); in shmob_drm_connector_create()
604 dev_err(sdev->dev, "failed to created connector: %pe\n", in shmob_drm_connector_create()
613 connector->dpms = DRM_MODE_DPMS_OFF; in shmob_drm_connector_create()
615 sdev->connector = connector; in shmob_drm_connector_create()