From: Joonyoung Shim Date: Wed, 27 Jun 2012 05:27:04 +0000 (+0900) Subject: BACKPORT: drm/exynos: use private plane for crtc X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=0bd6a3d8e268cefdc2e59ca687945b0ab5242dc5;p=cascardo%2Flinux.git BACKPORT: drm/exynos: use private plane for crtc The crtc can use private plane instead it has overlay struct. It will be helpful use plane feature from crtc later. BUG=chromium:222980 TEST=By hand. Signed-off-by: Joonyoung Shim Signed-off-by: Kyungmin Park Signed-off-by: Inki Dae (cherry picked from commit b5d2eb3bd691c0b6869a2013e719a61c595d73a6) Signed-off-by: Mandeep Singh Baines Change-Id: I3385e40cac26ebb2d71670f71eb1d3f91638437e Reviewed-on: https://gerrit.chromium.org/gerrit/46956 Reviewed-by: John Sheu Reviewed-by: Stéphane Marchesin --- diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index f45d99dd8ff7..864b882e84f2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -38,6 +38,7 @@ #include "exynos_drm_display.h" #include "exynos_drm_gem.h" #include "exynos_trace.h" +#include "exynos_drm_plane.h" #define KDS_WAITALL_MAX_TRIES 15 @@ -52,10 +53,9 @@ struct exynos_drm_flip_desc { * Exynos specific crtc structure. * * @drm_crtc: crtc object. - * @overlay: contain information common to display controller and hdmi and - * contents of this overlay object would be copied to sub driver size. * @current_fb: current fb that is being scanned out * @event: vblank event that is currently queued for flip + * @plane: pointer of private plane object for this crtc * @pipe: a crtc index created at load() with a new crtc object creation * and the crtc object would be set to private->crtc array * to get a crtc object corresponding to this pipe from private->crtc @@ -67,11 +67,11 @@ struct exynos_drm_flip_desc { */ struct exynos_drm_crtc { struct drm_crtc drm_crtc; - struct exynos_drm_overlay overlay; struct drm_pending_vblank_event *event; DECLARE_KFIFO(flip_fifo, struct exynos_drm_flip_desc, 2); struct exynos_drm_flip_desc scanout_desc; struct exynos_drm_display *display; + struct drm_plane *plane; unsigned int pipe; atomic_t flip_pending; }; @@ -169,7 +169,7 @@ static void exynos_drm_crtc_update(struct drm_crtc *crtc, struct drm_display_mode *mode = &crtc->mode; exynos_crtc = to_exynos_crtc(crtc); - overlay = &exynos_crtc->overlay; + overlay = get_exynos_drm_overlay(exynos_crtc->plane); memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos)); @@ -297,7 +297,7 @@ static void exynos_drm_crtc_release_flips(struct drm_crtc *crtc) to_exynos_fb(next_desc.fb)->rendered = true; exynos_drm_crtc_update(crtc, next_desc.fb); - exynos_drm_crtc_apply(crtc, &exynos_crtc->overlay); + exynos_drm_crtc_apply(crtc, get_exynos_drm_overlay(exynos_crtc->plane)); to_exynos_fb(next_desc.fb)->prepared = true; if (exynos_crtc->event) { @@ -408,7 +408,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, if (display->controller_ops && display->controller_ops->mode_set) display->controller_ops->mode_set(display->controller_ctx, - &exynos_crtc->overlay); + get_exynos_drm_overlay(exynos_crtc->plane)); return 0; } @@ -477,8 +477,11 @@ void exynos_drm_kds_callback(void *callback_parameter, void *callback_extra_para to_exynos_fb(fb)->rendered = true; if (!atomic_cmpxchg(&exynos_crtc->flip_pending, 0, 1)) { + struct exynos_drm_overlay *overlay; + + overlay = get_exynos_drm_overlay(exynos_crtc->plane); exynos_drm_crtc_update(crtc, fb); - exynos_drm_crtc_apply(crtc, &exynos_crtc->overlay); + exynos_drm_crtc_apply(crtc, overlay); to_exynos_fb(fb)->prepared = true; } } @@ -627,8 +630,11 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *drm_dev, int crtc_idx) if (kfifo_peek(&exynos_crtc->flip_fifo, &next_desc)) { if (unlikely(to_exynos_fb(next_desc.fb)->rendered) && !atomic_cmpxchg(&exynos_crtc->flip_pending, 0, 1)) { + struct exynos_drm_overlay *overlay; + + overlay = get_exynos_drm_overlay(exynos_crtc->plane); exynos_drm_crtc_update(crtc, next_desc.fb); - exynos_drm_crtc_apply(crtc, &exynos_crtc->overlay); + exynos_drm_crtc_apply(crtc, overlay); to_exynos_fb(next_desc.fb)->prepared = true; } } @@ -673,7 +679,13 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr, INIT_KFIFO(exynos_crtc->flip_fifo); exynos_crtc->pipe = nr; exynos_crtc->display = display; - exynos_crtc->overlay.zpos = DEFAULT_ZPOS; + + exynos_crtc->plane = exynos_plane_init(dev, 1 << nr, true); + if (!exynos_crtc->plane) { + kfree(exynos_crtc); + return -ENOMEM; + } + crtc = &exynos_crtc->drm_crtc; private->crtc[nr] = crtc; diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index ea82476900ad..b092bc494491 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h @@ -34,9 +34,8 @@ #include "drm_crtc.h" struct exynos_drm_display; +struct exynos_drm_overlay; -struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_device *dev, - struct drm_crtc *crtc); int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr, struct exynos_drm_display *display); int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 29dd448616d2..1500edf605c1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -134,8 +134,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) } for (nr = 0; nr < MAX_PLANE; nr++) { - ret = exynos_plane_init(dev, nr); - if (ret) + struct drm_plane *plane; + unsigned int possible_crtcs = + (1 << EXYNOS_DRM_DISPLAY_NUM_DISPLAYS) - 1; + + plane = exynos_plane_init(dev, possible_crtcs, false); + if (!plane) goto err_crtc; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 1e3ec7c28c5d..63a854848947 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -16,6 +16,8 @@ #include "exynos_drm_drv.h" #include "exynos_drm_encoder.h" +#define to_exynos_plane(x) container_of(x, struct exynos_plane, base) + struct exynos_plane { struct drm_plane base; struct exynos_drm_overlay overlay; @@ -105,25 +107,32 @@ static struct drm_plane_funcs exynos_plane_funcs = { .destroy = exynos_plane_destroy, }; -int exynos_plane_init(struct drm_device *dev, unsigned int nr) +struct drm_plane *exynos_plane_init(struct drm_device *dev, + unsigned int possible_crtcs, bool priv) { struct exynos_plane *exynos_plane; - uint32_t possible_crtcs; + int err; - DRM_DEBUG_KMS("[DEV:%s] nr: %u\n", dev->devname, nr); + DRM_DEBUG_KMS("[DEV:%s]\n", dev->devname); exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL); - if (!exynos_plane) - return -ENOMEM; - - /* all CRTCs are available */ - possible_crtcs = (1 << EXYNOS_DRM_DISPLAY_NUM_DISPLAYS) - 1; + if (!exynos_plane) { + DRM_ERROR("failed to allocate plane\n"); + return NULL; + } exynos_plane->overlay.zpos = DEFAULT_ZPOS; - return drm_plane_init(dev, &exynos_plane->base, possible_crtcs, + err = drm_plane_init(dev, &exynos_plane->base, possible_crtcs, &exynos_plane_funcs, formats, ARRAY_SIZE(formats), - false); + priv); + if (err) { + DRM_ERROR("failed to initialize plane\n"); + kfree(exynos_plane); + return NULL; + } + + return &exynos_plane->base; } int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, @@ -168,3 +177,10 @@ out: mutex_unlock(&dev->mode_config.mutex); return ret; } + +struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_plane *plane) +{ + struct exynos_plane *exynos_plane = to_exynos_plane(plane); + + return &exynos_plane->overlay; +} diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h index 16b71f8217e7..d0529181624d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.h +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h @@ -9,6 +9,8 @@ * */ -int exynos_plane_init(struct drm_device *dev, unsigned int nr); +struct drm_plane *exynos_plane_init(struct drm_device *dev, + unsigned int possible_crtcs, bool priv); int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_plane *plane);