diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_vidi.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 136 |
1 files changed, 34 insertions, 102 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index b886972b5888..27e84ec21694 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -23,6 +23,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_crtc.h" +#include "exynos_drm_plane.h" #include "exynos_drm_encoder.h" #include "exynos_drm_vidi.h" @@ -32,20 +33,6 @@ #define ctx_from_connector(c) container_of(c, struct vidi_context, \ connector) -struct vidi_win_data { - unsigned int offset_x; - unsigned int offset_y; - unsigned int ovl_width; - unsigned int ovl_height; - unsigned int fb_width; - unsigned int fb_height; - unsigned int bpp; - dma_addr_t dma_addr; - unsigned int buf_offsize; - unsigned int line_size; /* bytes */ - bool enabled; -}; - struct vidi_context { struct exynos_drm_display display; struct platform_device *pdev; @@ -53,7 +40,7 @@ struct vidi_context { struct exynos_drm_crtc *crtc; struct drm_encoder *encoder; struct drm_connector connector; - struct vidi_win_data win_data[WINDOWS_NR]; + struct exynos_drm_plane planes[WINDOWS_NR]; struct edid *raw_edid; unsigned int clkdiv; unsigned int default_win; @@ -97,19 +84,6 @@ static const char fake_edid_info[] = { 0x00, 0x00, 0x00, 0x06 }; -static void vidi_apply(struct vidi_context *ctx) -{ - struct exynos_drm_crtc_ops *crtc_ops = ctx->crtc->ops; - struct vidi_win_data *win_data; - int i; - - for (i = 0; i < WINDOWS_NR; i++) { - win_data = &ctx->win_data[i]; - if (win_data->enabled && (crtc_ops && crtc_ops->win_commit)) - crtc_ops->win_commit(ctx->crtc, i); - } -} - static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) { struct vidi_context *ctx = crtc->ctx; @@ -143,104 +117,46 @@ static void vidi_disable_vblank(struct exynos_drm_crtc *crtc) ctx->vblank_on = false; } -static void vidi_win_mode_set(struct exynos_drm_crtc *crtc, - struct exynos_drm_plane *plane) -{ - struct vidi_context *ctx = crtc->ctx; - struct vidi_win_data *win_data; - int win; - unsigned long offset; - - if (!plane) { - DRM_ERROR("plane is NULL\n"); - return; - } - - win = plane->zpos; - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - - if (win < 0 || win >= WINDOWS_NR) - return; - - offset = plane->fb_x * (plane->bpp >> 3); - offset += plane->fb_y * plane->pitch; - - DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch); - - win_data = &ctx->win_data[win]; - - win_data->offset_x = plane->crtc_x; - win_data->offset_y = plane->crtc_y; - win_data->ovl_width = plane->crtc_width; - win_data->ovl_height = plane->crtc_height; - win_data->fb_width = plane->fb_width; - win_data->fb_height = plane->fb_height; - win_data->dma_addr = plane->dma_addr[0] + offset; - win_data->bpp = plane->bpp; - win_data->buf_offsize = (plane->fb_width - plane->crtc_width) * - (plane->bpp >> 3); - win_data->line_size = plane->crtc_width * (plane->bpp >> 3); - - /* - * some parts of win_data should be transferred to user side - * through specific ioctl. - */ - - DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", - win_data->offset_x, win_data->offset_y); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - win_data->ovl_width, win_data->ovl_height); - DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); - DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", - plane->fb_width, plane->crtc_width); -} - -static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos) +static void vidi_win_commit(struct exynos_drm_crtc *crtc, unsigned int win) { struct vidi_context *ctx = crtc->ctx; - struct vidi_win_data *win_data; - int win = zpos; + struct exynos_drm_plane *plane; if (ctx->suspended) return; - if (win == DEFAULT_ZPOS) - win = ctx->default_win; - if (win < 0 || win >= WINDOWS_NR) return; - win_data = &ctx->win_data[win]; + plane = &ctx->planes[win]; - win_data->enabled = true; + plane->enabled = true; - DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr); + DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr); if (ctx->vblank_on) schedule_work(&ctx->work); } -static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos) +static void vidi_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) { struct vidi_context *ctx = crtc->ctx; - struct vidi_win_data *win_data; - int win = zpos; - - if (win == DEFAULT_ZPOS) - win = ctx->default_win; + struct exynos_drm_plane *plane; if (win < 0 || win >= WINDOWS_NR) return; - win_data = &ctx->win_data[win]; - win_data->enabled = false; + plane = &ctx->planes[win]; + plane->enabled = false; /* TODO. */ } static int vidi_power_on(struct vidi_context *ctx, bool enable) { + struct exynos_drm_plane *plane; + int i; + DRM_DEBUG_KMS("%s\n", __FILE__); if (enable != false && enable != true) @@ -253,7 +169,11 @@ static int vidi_power_on(struct vidi_context *ctx, bool enable) if (test_and_clear_bit(0, &ctx->irq_flags)) vidi_enable_vblank(ctx->crtc); - vidi_apply(ctx); + for (i = 0; i < WINDOWS_NR; i++) { + plane = &ctx->planes[i]; + if (plane->enabled) + vidi_win_commit(ctx->crtc, i); + } } else { ctx->suspended = true; } @@ -301,7 +221,6 @@ static struct exynos_drm_crtc_ops vidi_crtc_ops = { .dpms = vidi_dpms, .enable_vblank = vidi_enable_vblank, .disable_vblank = vidi_disable_vblank, - .win_mode_set = vidi_win_mode_set, .win_commit = vidi_win_commit, .win_disable = vidi_win_disable, }; @@ -543,12 +462,25 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) { struct vidi_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; + struct exynos_drm_plane *exynos_plane; + enum drm_plane_type type; + unsigned int zpos; int ret; vidi_ctx_initialize(ctx, drm_dev); - ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, - EXYNOS_DISPLAY_TYPE_VIDI, + for (zpos = 0; zpos < WINDOWS_NR; zpos++) { + type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY : + DRM_PLANE_TYPE_OVERLAY; + ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], + 1 << ctx->pipe, type, zpos); + if (ret) + return ret; + } + + exynos_plane = &ctx->planes[ctx->default_win]; + ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, + ctx->pipe, EXYNOS_DISPLAY_TYPE_VIDI, &vidi_crtc_ops, ctx); if (IS_ERR(ctx->crtc)) { DRM_ERROR("failed to create crtc.\n"); |