diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2015-10-08 16:33:33 -0300 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2015-10-13 11:19:09 +0100 |
commit | 2414dfc95667254cbc6e60662473895b42a98ad0 (patch) | |
tree | 56ca3ef508915870b5d017369dce1cd9e4be58e0 | |
parent | bd2c14b5c2b7663f927da74a0fdd014d986313a0 (diff) | |
download | drm-exynos-dithering.tar.gz |
WIP: fimd ditheringdithering
-rw-r--r-- | Documentation/devicetree/bindings/video/samsung-fimd.txt | 1 | ||||
-rw-r--r-- | arch/arm/boot/dts/exynos5250-snow.dts | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 68 | ||||
-rw-r--r-- | include/video/samsung_fimd.h | 42 |
4 files changed, 112 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/video/samsung-fimd.txt b/Documentation/devicetree/bindings/video/samsung-fimd.txt index a8bbbde03e79e4..6e4dd36fd719fd 100644 --- a/Documentation/devicetree/bindings/video/samsung-fimd.txt +++ b/Documentation/devicetree/bindings/video/samsung-fimd.txt @@ -41,6 +41,7 @@ Optional Properties: - power-domains: a phandle to FIMD power domain node. - samsung,invert-vden: video enable signal is inverted - samsung,invert-vclk: video clock signal is inverted +- samsung,mie-dithering: enable dither for the Mobile Image Enhancement - display-timings: timing settings for FIMD, as described in document [1]. Can be used in case timings cannot be provided otherwise or to override timings provided by the panel. diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index 0720caab551111..4535596b1944de 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -267,6 +267,7 @@ &fimd { status = "okay"; samsung,invert-vclk; + samsung,mie-dithering; }; &hdmi { diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index bd75c1531cac8d..7c7b021a2ec9a8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -85,6 +85,9 @@ #define LCD_WR_HOLD(x) ((x) << 4) #define I80IFEN_ENABLE (1 << 0) +#define NO_DITHERING 0x00 +#define MIE_DITHERING 0x01 + /* FIMD has totally five hardware windows. */ #define WINDOWS_NR 5 #define CURSOR_WIN 4 @@ -153,12 +156,14 @@ struct fimd_context { struct clk *bus_clk; struct clk *lcd_clk; void __iomem *regs; + void __iomem *regs_mie; struct regmap *sysreg; unsigned long irq_flags; u32 vidcon0; u32 vidcon1; u32 vidout_con; u32 i80ifcon; + u32 dither_mode; bool i80_if; bool suspended; int pipe; @@ -376,6 +381,52 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx, return (clkdiv < 0x100) ? clkdiv : 0xff; } +static void fimd_enable_dithering(struct exynos_drm_crtc *crtc) +{ + struct fimd_context *ctx = crtc->ctx; + struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; + int bpd, fpd, sync_len, i; + + DRM_DEBUG("first\n"); + if (ctx->dither_mode == MIE_DITHERING) { + writel(DP_MIE_CLK_DP_ENABLE, ctx->regs + DP_MIE_CLKCON); + + writel(MIE_HRESOL(mode->crtc_hdisplay) | + MIE_VRESOL(mode->crtc_vdisplay) | MIE_MODE_UI, + ctx->regs_mie + MIE_CTRL1); + + writel(MIE_WINHADDR0(0) | MIE_WINHADDR1(mode->crtc_hdisplay), + ctx->regs_mie + MIE_WINHADDR); + + writel(MIE_WINVADDR0(0) | MIE_WINVADDR1(mode->crtc_vdisplay), + ctx->regs_mie + MIE_WINVADDR); + + writel(PWMCLKCNT(mode->crtc_vtotal * mode->crtc_htotal / + (MIE_PWMCLKVAL + 1)), ctx->regs_mie + MIE_PWMCLKCNT); + + bpd = mode->crtc_vtotal - mode->crtc_vsync_end; + fpd = mode->crtc_vsync_start - mode->crtc_vdisplay; + sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; + writel(MIE_VBPD(bpd) | MIE_VFPD(fpd) | MIE_VSPW(sync_len), + ctx->regs_mie + MIE_PWMVIDTCON1); + + bpd = mode->crtc_htotal - mode->crtc_hsync_end; + fpd = mode->crtc_hsync_start - mode->crtc_hdisplay; + sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + writel(MIE_HBPD(bpd) | MIE_HFPD(fpd) | MIE_HSPW(sync_len), + ctx->regs_mie + MIE_PWMVIDTCON2); + + writel(MIE_DITHCON_EN | MIE_RGB6MODE, + ctx->regs_mie + MIE_AUXCON); + + /* Bypass MIE image brightness enhancement */ + for (i = 0; i <= 0x30; i += 4) { + writel(0, ctx->regs_mie + 0x100 + i); + writel(0, ctx->regs_mie + 0x200 + i); + } + } +} + static void fimd_commit(struct exynos_drm_crtc *crtc) { struct fimd_context *ctx = crtc->ctx; @@ -474,6 +525,8 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) val |= VIDCON0_CLKVAL_F(clkdiv - 1) | VIDCON0_CLKDIR; writel(val, ctx->regs + VIDCON0); + + fimd_enable_dithering(crtc); } @@ -795,6 +848,9 @@ static void fimd_disable(struct exynos_drm_crtc *crtc) writel(0, ctx->regs + VIDCON0); + if (ctx->dither_mode == MIE_DITHERING) + writel(DP_MIE_CLK_DISABLE, ctx->regs + DP_MIE_CLKCON); + clk_disable_unprepare(ctx->lcd_clk); clk_disable_unprepare(ctx->bus_clk); @@ -862,6 +918,10 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) struct fimd_context *ctx = crtc->ctx; u32 val; + DRM_DEBUG_KMS("first\n"); + + return; + /* * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE * clock. On these SoCs the bootloader may enable it but any @@ -1018,6 +1078,8 @@ static int fimd_probe(struct platform_device *pdev) ctx->vidcon1 |= VIDCON1_INV_VDEN; if (of_property_read_bool(dev->of_node, "samsung,invert-vclk")) ctx->vidcon1 |= VIDCON1_INV_VCLK; + if (of_property_read_bool(dev->of_node, "samsung,mie-dithering")) + ctx->dither_mode = MIE_DITHERING; i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings"); if (i80_if_timings) { @@ -1075,6 +1137,12 @@ static int fimd_probe(struct platform_device *pdev) if (IS_ERR(ctx->regs)) return PTR_ERR(ctx->regs); + if (ctx->dither_mode == MIE_DITHERING) { + ctx->regs_mie = devm_ioremap(dev, MIE_BASE_ADDRESS, 0x400); + if (!ctx->regs_mie) + ctx->dither_mode = NO_DITHERING; + } + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, ctx->i80_if ? "lcd_sys" : "vsync"); if (!res) { diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h index d8fc96ed11e9d2..9b79ad4683d6f0 100644 --- a/include/video/samsung_fimd.h +++ b/include/video/samsung_fimd.h @@ -475,3 +475,45 @@ #define FIMD_V8_VIDTCON2 0x20018 #define FIMD_V8_VIDTCON3 0x2001C #define FIMD_V8_VIDCON1 0x20004 + +/* MIE registers */ +#define MIE_BASE_ADDRESS 0x14430000 +#define MIE_CTRL1 0x0 +#define MIE_HRESOL_SHIFT 18 +#define MIE_HRESOL(x) ((x & 0xfff) << MIE_HRESOL_SHIFT) +#define MIE_VRESOL_SHIFT 7 +#define MIE_VRESOL(x) ((x & 0x7ff) << MIE_VRESOL_SHIFT) +#define MIE_MODE_UI (1 << 5) + +#define MIE_WINHADDR 0x10 +#define MIE_WINHADDR0_SHIFT 0 +#define MIE_WINHADDR1_SHIFT 20 +#define MIE_WINHADDR0(x) ((x & 0xfff) << MIE_WINHADDR0_SHIFT) +#define MIE_WINHADDR1(x) (((x-1) & 0xfff)\ + << MIE_WINHADDR1_SHIFT) + +#define MIE_WINVADDR 0x14 +#define MIE_WINVADDR0_SHIFT 0 +#define MIE_WINVADDR1_SHIFT 21 +#define MIE_WINVADDR0(x) ((x & 0x7ff) << MIE_WINVADDR0_SHIFT) +#define MIE_WINVADDR1(x) (((x - 1) & 0x7ff)\ + << MIE_WINVADDR1_SHIFT) + +#define MIE_PWMCLKCNT 0x20 +#define MIE_PWMCLKVAL 1 +#define PWMCLKCNT(x) ((x & 0x3fffff) << 4) + +#define MIE_PWMVIDTCON1 0x38 +#define MIE_VBPD(x) ((x - 1) << 16) +#define MIE_VFPD(x) ((x - 1) << 8) +#define MIE_VSPW(x) (x - 1) + +#define MIE_PWMVIDTCON2 0x3c +#define MIE_HBPD(x) ((x - 1) << 16) +#define MIE_HFPD(x) ((x - 1) << 8) +#define MIE_HSPW(x) (x - 1) + +#define MIE_AUXCON 0x300 +#define MIE_DITHCON_EN 0x1 +#define MIE_RGBMODE_SHIFT 1 +#define MIE_RGB6MODE (0 << MIE_RGBMODE_SHIFT) |