提交 de7af100 编写于 作者: T Tomasz Figa 提交者: Inki Dae

drm/exynos: fimd: Add support for FIMD versions without SHADOWCON register

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: NTomasz Figa <tomasz.figa@gmail.com>
Acked-by: NJoonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: NInki Dae <inki.dae@samsung.com>
上级 18873465
......@@ -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 {
......@@ -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);
......@@ -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
......@@ -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;
......@@ -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;
}
......@@ -634,9 +666,7 @@ 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));
......@@ -644,10 +674,13 @@ static void fimd_win_disable(struct device *dev, int zpos)
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;
}
......@@ -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));
......@@ -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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册