Skip to content

Commit

Permalink
drm/exynos: fimd: Add support for FIMD versions without SHADOWCON reg…
Browse files Browse the repository at this point in the history
…ister

Some platforms that can be supported with this driver have PRTCON
register instead of SHADOWCON, which requires slightly different
handling.

This patch factors out all register shadow control code from the driver
and adds a function to control register shadowing appropriately,
depending on driver data.

Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Acked-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
  • Loading branch information
Tomasz Figa authored and Inki Dae committed Jun 28, 2013
1 parent 1887346 commit de7af10
Showing 1 changed file with 49 additions and 20 deletions.
69 changes: 49 additions & 20 deletions drivers/gpu/drm/exynos/exynos_drm_fimd.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,18 @@

struct fimd_driver_data {
unsigned int timing_base;

unsigned int has_shadowcon:1;
};

static struct fimd_driver_data exynos4_fimd_driver_data = {
.timing_base = 0x0,
.has_shadowcon = 1,
};

static struct fimd_driver_data exynos5_fimd_driver_data = {
.timing_base = 0x20000,
.has_shadowcon = 1,
};

struct fimd_win_data {
Expand Down Expand Up @@ -489,6 +493,33 @@ static void fimd_win_set_colkey(struct device *dev, unsigned int win)
writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
}

/**
* shadow_protect_win() - disable updating values from shadow registers at vsync
*
* @win: window to protect registers for
* @protect: 1 to protect (disable updates)
*/
static void fimd_shadow_protect_win(struct fimd_context *ctx,
int win, bool protect)
{
u32 reg, bits, val;

if (ctx->driver_data->has_shadowcon) {
reg = SHADOWCON;
bits = SHADOWCON_WINx_PROTECT(win);
} else {
reg = PRTCON;
bits = PRTCON_PROTECT;
}

val = readl(ctx->regs + reg);
if (protect)
val |= bits;
else
val &= ~bits;
writel(val, ctx->regs + reg);
}

static void fimd_win_commit(struct device *dev, int zpos)
{
struct fimd_context *ctx = get_fimd_context(dev);
Expand All @@ -512,7 +543,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
win_data = &ctx->win_data[win];

/*
* SHADOWCON register is used for enabling timing.
* SHADOWCON/PRTCON register is used for enabling timing.
*
* for example, once only width value of a register is set,
* if the dma is started then fimd hardware could malfunction so
Expand All @@ -522,9 +553,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
*/

/* protect windows */
val = readl(ctx->regs + SHADOWCON);
val |= SHADOWCON_WINx_PROTECT(win);
writel(val, ctx->regs + SHADOWCON);
fimd_shadow_protect_win(ctx, win, true);

/* buffer start address */
val = (unsigned long)win_data->dma_addr;
Expand Down Expand Up @@ -602,10 +631,13 @@ static void fimd_win_commit(struct device *dev, int zpos)
writel(val, ctx->regs + WINCON(win));

/* Enable DMA channel and unprotect windows */
val = readl(ctx->regs + SHADOWCON);
val |= SHADOWCON_CHx_ENABLE(win);
val &= ~SHADOWCON_WINx_PROTECT(win);
writel(val, ctx->regs + SHADOWCON);
fimd_shadow_protect_win(ctx, win, false);

if (ctx->driver_data->has_shadowcon) {
val = readl(ctx->regs + SHADOWCON);
val |= SHADOWCON_CHx_ENABLE(win);
writel(val, ctx->regs + SHADOWCON);
}

win_data->enabled = true;
}
Expand Down Expand Up @@ -634,20 +666,21 @@ static void fimd_win_disable(struct device *dev, int zpos)
}

/* protect windows */
val = readl(ctx->regs + SHADOWCON);
val |= SHADOWCON_WINx_PROTECT(win);
writel(val, ctx->regs + SHADOWCON);
fimd_shadow_protect_win(ctx, win, true);

/* wincon */
val = readl(ctx->regs + WINCON(win));
val &= ~WINCONx_ENWIN;
writel(val, ctx->regs + WINCON(win));

/* unprotect windows */
val = readl(ctx->regs + SHADOWCON);
val &= ~SHADOWCON_CHx_ENABLE(win);
val &= ~SHADOWCON_WINx_PROTECT(win);
writel(val, ctx->regs + SHADOWCON);
if (ctx->driver_data->has_shadowcon) {
val = readl(ctx->regs + SHADOWCON);
val &= ~SHADOWCON_CHx_ENABLE(win);
writel(val, ctx->regs + SHADOWCON);
}

fimd_shadow_protect_win(ctx, win, false);

win_data->enabled = false;
}
Expand Down Expand Up @@ -777,8 +810,6 @@ static int fimd_calc_clkdiv(struct fimd_context *ctx,

static void fimd_clear_win(struct fimd_context *ctx, int win)
{
u32 val;

DRM_DEBUG_KMS("%s\n", __FILE__);

writel(0, ctx->regs + WINCON(win));
Expand All @@ -789,9 +820,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
if (win == 1 || win == 2)
writel(0, ctx->regs + VIDOSD_D(win));

val = readl(ctx->regs + SHADOWCON);
val &= ~SHADOWCON_WINx_PROTECT(win);
writel(val, ctx->regs + SHADOWCON);
fimd_shadow_protect_win(ctx, win, false);
}

static int fimd_clock(struct fimd_context *ctx, bool enable)
Expand Down

0 comments on commit de7af10

Please sign in to comment.