Commit 1daa892c authored by Inki Dae's avatar Inki Dae

drm/exynos: make sure that overlay data are updated

Changelog v2:
fix a little bit performance issue to previous patch.
- When drm framebuffer is destroyed, make sure that overlay
  data are updated to real hardwrae for all encoders
  instead of waiting for vblank every page flip request.
  For this, it adds a new function,
  exynos_drm_encoder_complete_scanout function.

Changelog v1:
This patch removes wait_for_vblank call from
exynos_drm_encoder_plane_disable function and move it to
exynos_drm_encoder_plane_commit function.

Disabling dma channel to each plane doens't need vblank
signal to update data to real hardware. But updating
overlay data to real hardware does need vblank signal.
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
parent 5b07c660
...@@ -234,6 +234,39 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder) ...@@ -234,6 +234,39 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
exynos_encoder->dpms = DRM_MODE_DPMS_ON; exynos_encoder->dpms = DRM_MODE_DPMS_ON;
} }
void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb)
{
struct exynos_drm_encoder *exynos_encoder;
struct exynos_drm_overlay_ops *overlay_ops;
struct exynos_drm_manager *manager;
struct drm_device *dev = fb->dev;
struct drm_encoder *encoder;
/*
* make sure that overlay data are updated to real hardware
* for all encoders.
*/
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
exynos_encoder = to_exynos_encoder(encoder);
/* if exynos was disabled, just ignor it. */
if (exynos_encoder->dpms > DRM_MODE_DPMS_ON)
continue;
manager = exynos_encoder->manager;
overlay_ops = manager->overlay_ops;
/*
* wait for vblank interrupt
* - this makes sure that overlay data are updated to
* real hardware.
*/
if (overlay_ops->wait_for_vblank)
overlay_ops->wait_for_vblank(manager->dev);
}
}
static void exynos_drm_encoder_disable(struct drm_encoder *encoder) static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
{ {
struct drm_plane *plane; struct drm_plane *plane;
...@@ -505,14 +538,4 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) ...@@ -505,14 +538,4 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
if (overlay_ops && overlay_ops->disable) if (overlay_ops && overlay_ops->disable)
overlay_ops->disable(manager->dev, zpos); overlay_ops->disable(manager->dev, zpos);
/*
* wait for vblank interrupt
* - this makes sure that hardware overlay is disabled to avoid
* for the dma accesses to memory after gem buffer was released
* because the setting for disabling the overlay will be updated
* at vsync.
*/
if (overlay_ops && overlay_ops->wait_for_vblank)
overlay_ops->wait_for_vblank(manager->dev);
} }
...@@ -46,5 +46,6 @@ void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data); ...@@ -46,5 +46,6 @@ void exynos_drm_encoder_plane_mode_set(struct drm_encoder *encoder, void *data);
void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data); void exynos_drm_encoder_plane_commit(struct drm_encoder *encoder, void *data);
void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data); void exynos_drm_encoder_plane_enable(struct drm_encoder *encoder, void *data);
void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data); void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data);
void exynos_drm_encoder_complete_scanout(struct drm_framebuffer *fb);
#endif #endif
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "exynos_drm_fb.h" #include "exynos_drm_fb.h"
#include "exynos_drm_gem.h" #include "exynos_drm_gem.h"
#include "exynos_drm_iommu.h" #include "exynos_drm_iommu.h"
#include "exynos_drm_encoder.h"
#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb) #define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb)
...@@ -85,6 +86,9 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) ...@@ -85,6 +86,9 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
DRM_DEBUG_KMS("%s\n", __FILE__); DRM_DEBUG_KMS("%s\n", __FILE__);
/* make sure that overlay data are updated before relesing fb. */
exynos_drm_encoder_complete_scanout(fb);
drm_framebuffer_cleanup(fb); drm_framebuffer_cleanup(fb);
for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) { for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem_obj); i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment