Skip to content

Commit

Permalink
drm/exynos: remove struct *_win_data abstraction on planes
Browse files Browse the repository at this point in the history
struct {fimd,mixer,vidi}_win_data was just keeping the same data
as struct exynos_drm_plane thus get ride of it and use exynos_drm_plane
directly.

It changes how planes are created and remove .win_mode_set() callback
that was only filling all *_win_data structs.

v2: check for return of exynos_plane_init()

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
  • Loading branch information
Gustavo Padovan authored and Inki Dae committed Apr 13, 2015
1 parent 1be4b7e commit 7ee14cd
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 501 deletions.
166 changes: 61 additions & 105 deletions drivers/gpu/drm/exynos/exynos7_drm_decon.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <video/exynos7_decon.h>

#include "exynos_drm_crtc.h"
#include "exynos_drm_plane.h"
#include "exynos_drm_drv.h"
#include "exynos_drm_fbdev.h"
#include "exynos_drm_iommu.h"
Expand All @@ -41,32 +42,16 @@

#define WINDOWS_NR 2

struct decon_win_data {
unsigned int ovl_x;
unsigned int ovl_y;
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;
unsigned int pixel_format;
dma_addr_t dma_addr;
bool enabled;
bool resume;
};

struct decon_context {
struct device *dev;
struct drm_device *drm_dev;
struct exynos_drm_crtc *crtc;
struct exynos_drm_plane planes[WINDOWS_NR];
struct clk *pclk;
struct clk *aclk;
struct clk *eclk;
struct clk *vclk;
void __iomem *regs;
struct decon_win_data win_data[WINDOWS_NR];
unsigned int default_win;
unsigned long irq_flags;
bool i80_if;
Expand Down Expand Up @@ -296,59 +281,16 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
}
}

static void decon_win_mode_set(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
struct decon_context *ctx = crtc->ctx;
struct decon_win_data *win_data;
int win, padding;

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;


win_data = &ctx->win_data[win];

padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width;
win_data->offset_x = plane->fb_x;
win_data->offset_y = plane->fb_y;
win_data->fb_width = plane->fb_width + padding;
win_data->fb_height = plane->fb_height;
win_data->ovl_x = plane->crtc_x;
win_data->ovl_y = plane->crtc_y;
win_data->ovl_width = plane->crtc_width;
win_data->ovl_height = plane->crtc_height;
win_data->dma_addr = plane->dma_addr[0];
win_data->bpp = plane->bpp;
win_data->pixel_format = plane->pixel_format;

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 decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
{
struct decon_win_data *win_data = &ctx->win_data[win];
struct exynos_drm_plane *plane = &ctx->planes[win];
unsigned long val;
int padding;

val = readl(ctx->regs + WINCON(win));
val &= ~WINCONx_BPPMODE_MASK;

switch (win_data->pixel_format) {
switch (plane->pixel_format) {
case DRM_FORMAT_RGB565:
val |= WINCONx_BPPMODE_16BPP_565;
val |= WINCONx_BURSTLEN_16WORD;
Expand Down Expand Up @@ -397,7 +339,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
break;
}

DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp);
DRM_DEBUG_KMS("bpp = %d\n", plane->bpp);

/*
* In case of exynos, setting dma-burst to 16Word causes permanent
Expand All @@ -407,7 +349,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
* movement causes unstable DMA which results into iommu crash/tear.
*/

if (win_data->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width;
if (plane->fb_width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) {
val &= ~WINCONx_BURSTLEN_MASK;
val |= WINCONx_BURSTLEN_8WORD;
}
Expand Down Expand Up @@ -453,8 +396,8 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
{
struct decon_context *ctx = crtc->ctx;
struct drm_display_mode *mode = &crtc->base.mode;
struct decon_win_data *win_data;
int win = zpos;
struct exynos_drm_plane *plane;
int padding, win = zpos;
unsigned long val, alpha;
unsigned int last_x;
unsigned int last_y;
Expand All @@ -468,11 +411,11 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
if (win < 0 || win >= WINDOWS_NR)
return;

win_data = &ctx->win_data[win];
plane = &ctx->planes[win];

/* If suspended, enable this on resume */
if (ctx->suspended) {
win_data->resume = true;
plane->resume = true;
return;
}

Expand All @@ -490,39 +433,41 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
decon_shadow_protect_win(ctx, win, true);

/* buffer start address */
val = (unsigned long)win_data->dma_addr;
val = (unsigned long)plane->dma_addr[0];
writel(val, ctx->regs + VIDW_BUF_START(win));

padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width;

/* buffer size */
writel(win_data->fb_width, ctx->regs + VIDW_WHOLE_X(win));
writel(win_data->fb_height, ctx->regs + VIDW_WHOLE_Y(win));
writel(plane->fb_width + padding, ctx->regs + VIDW_WHOLE_X(win));
writel(plane->fb_height, ctx->regs + VIDW_WHOLE_Y(win));

/* offset from the start of the buffer to read */
writel(win_data->offset_x, ctx->regs + VIDW_OFFSET_X(win));
writel(win_data->offset_y, ctx->regs + VIDW_OFFSET_Y(win));
writel(plane->fb_x, ctx->regs + VIDW_OFFSET_X(win));
writel(plane->fb_y, ctx->regs + VIDW_OFFSET_Y(win));

DRM_DEBUG_KMS("start addr = 0x%lx\n",
(unsigned long)win_data->dma_addr);
(unsigned long)val);
DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
win_data->ovl_width, win_data->ovl_height);
plane->crtc_width, plane->crtc_height);

/*
* OSD position.
* In case the window layout goes of LCD layout, DECON fails.
*/
if ((win_data->ovl_x + win_data->ovl_width) > mode->hdisplay)
win_data->ovl_x = mode->hdisplay - win_data->ovl_width;
if ((win_data->ovl_y + win_data->ovl_height) > mode->vdisplay)
win_data->ovl_y = mode->vdisplay - win_data->ovl_height;
if ((plane->crtc_x + plane->crtc_width) > mode->hdisplay)
plane->crtc_x = mode->hdisplay - plane->crtc_width;
if ((plane->crtc_y + plane->crtc_height) > mode->vdisplay)
plane->crtc_y = mode->vdisplay - plane->crtc_height;

val = VIDOSDxA_TOPLEFT_X(win_data->ovl_x) |
VIDOSDxA_TOPLEFT_Y(win_data->ovl_y);
val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) |
VIDOSDxA_TOPLEFT_Y(plane->crtc_y);
writel(val, ctx->regs + VIDOSD_A(win));

last_x = win_data->ovl_x + win_data->ovl_width;
last_x = plane->crtc_x + plane->crtc_width;
if (last_x)
last_x--;
last_y = win_data->ovl_y + win_data->ovl_height;
last_y = plane->crtc_y + plane->crtc_height;
if (last_y)
last_y--;

Expand All @@ -531,7 +476,7 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
writel(val, ctx->regs + VIDOSD_B(win));

DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
win_data->ovl_x, win_data->ovl_y, last_x, last_y);
plane->crtc_x, plane->crtc_y, last_x, last_y);

/* OSD alpha */
alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
Expand Down Expand Up @@ -565,13 +510,13 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
val |= DECON_UPDATE_STANDALONE_F;
writel(val, ctx->regs + DECON_UPDATE);

win_data->enabled = true;
plane->enabled = true;
}

static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos)
{
struct decon_context *ctx = crtc->ctx;
struct decon_win_data *win_data;
struct exynos_drm_plane *plane;
int win = zpos;
u32 val;

Expand All @@ -581,11 +526,11 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos)
if (win < 0 || win >= WINDOWS_NR)
return;

win_data = &ctx->win_data[win];
plane = &ctx->planes[win];

if (ctx->suspended) {
/* do not resume this window*/
win_data->resume = false;
plane->resume = false;
return;
}

Expand All @@ -604,42 +549,42 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos)
val |= DECON_UPDATE_STANDALONE_F;
writel(val, ctx->regs + DECON_UPDATE);

win_data->enabled = false;
plane->enabled = false;
}

static void decon_window_suspend(struct decon_context *ctx)
{
struct decon_win_data *win_data;
struct exynos_drm_plane *plane;
int i;

for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
win_data->resume = win_data->enabled;
if (win_data->enabled)
plane = &ctx->planes[i];
plane->resume = plane->enabled;
if (plane->enabled)
decon_win_disable(ctx->crtc, i);
}
}

static void decon_window_resume(struct decon_context *ctx)
{
struct decon_win_data *win_data;
struct exynos_drm_plane *plane;
int i;

for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
win_data->enabled = win_data->resume;
win_data->resume = false;
plane = &ctx->planes[i];
plane->enabled = plane->resume;
plane->resume = false;
}
}

static void decon_apply(struct decon_context *ctx)
{
struct decon_win_data *win_data;
struct exynos_drm_plane *plane;
int i;

for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
if (win_data->enabled)
plane = &ctx->planes[i];
if (plane->enabled)
decon_win_commit(ctx->crtc, i);
else
decon_win_disable(ctx->crtc, i);
Expand Down Expand Up @@ -779,7 +724,6 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank,
.wait_for_vblank = decon_wait_for_vblank,
.win_mode_set = decon_win_mode_set,
.win_commit = decon_win_commit,
.win_disable = decon_win_disable,
};
Expand Down Expand Up @@ -818,16 +762,28 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
{
struct decon_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
int ret;
struct exynos_drm_plane *exynos_plane;
enum drm_plane_type type;
int zpos, ret;

ret = decon_ctx_initialize(ctx, drm_dev);
if (ret) {
DRM_ERROR("decon_ctx_initialize failed.\n");
return ret;
}

ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
EXYNOS_DISPLAY_TYPE_LCD,
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);
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_LCD,
&decon_crtc_ops, ctx);
if (IS_ERR(ctx->crtc)) {
decon_ctx_remove(ctx);
Expand Down
9 changes: 1 addition & 8 deletions drivers/gpu/drm/exynos/exynos_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,13 +239,13 @@ static struct drm_crtc_funcs exynos_crtc_funcs = {
};

struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
struct drm_plane *plane,
int pipe,
enum exynos_drm_output_type type,
struct exynos_drm_crtc_ops *ops,
void *ctx)
{
struct exynos_drm_crtc *exynos_crtc;
struct drm_plane *plane;
struct exynos_drm_private *private = drm_dev->dev_private;
struct drm_crtc *crtc;
int ret;
Expand All @@ -262,12 +262,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
exynos_crtc->type = type;
exynos_crtc->ops = ops;
exynos_crtc->ctx = ctx;
plane = exynos_plane_init(drm_dev, 1 << pipe,
DRM_PLANE_TYPE_PRIMARY);
if (IS_ERR(plane)) {
ret = PTR_ERR(plane);
goto err_plane;
}

crtc = &exynos_crtc->base;

Expand All @@ -284,7 +278,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,

err_crtc:
plane->funcs->destroy(plane);
err_plane:
kfree(exynos_crtc);
return ERR_PTR(ret);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/exynos/exynos_drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "exynos_drm_drv.h"

struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
struct drm_plane *plane,
int pipe,
enum exynos_drm_output_type type,
struct exynos_drm_crtc_ops *ops,
Expand Down
Loading

0 comments on commit 7ee14cd

Please sign in to comment.