summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 13:40:25 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-17 13:40:25 -0800
commit984065055e6e39f8dd812529e11922374bd39352 (patch)
treea8f1bcbd81e0fadce0cef39ab5ce09ab84b261fe /drivers/gpu/drm/exynos/exynos5433_drm_decon.c
parent12768c1e2c83b05ea1658470045789a14b6edf4c (diff)
parent1df59b8497f47495e873c23abd6d3d290c730505 (diff)
downloadop-kernel-dev-984065055e6e39f8dd812529e11922374bd39352.zip
op-kernel-dev-984065055e6e39f8dd812529e11922374bd39352.tar.gz
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "This is the main drm pull request for 4.5. I don't think I've missed anything too major, I'm mostly back at work now but I'll probably get some sleep in 5 years time. Summary: New drivers: - etnaviv: GPU driver for the 3D core on the Vivante core used in numerous ARM boards. Highlights: Core: - Atomic suspend/resume helpers - Move the headers to using userspace friendlier types. - Documentation updates - Lots of struct_mutex removal. - Bunch of DP MST fixes from AMD. Panel: - More DSI helpers - Support for some new basic panels i915: - Basic Kabylake support - DP link training and detect code refactoring - fbc/psr fixes - FIFO underrun fixes - SDE interrupt handling fixes - dma-buf/fence support in pageflip path. - GPU side for MST audio support radeon/amdgpu: - Drop UMS support - GPUVM/Scheduler optimisations - Initial Powerplay support for Tonga/Fiji/CZ/ST - ACP audio prerequisites nouveau: - GK20a instmem improvements - PCIE link speed change support msm: - DSI support for msm8960/apq8064 tegra: - Host1X support for Tegra210 SoC vc4: - 3D acceleration support armada: - Get rid of struct mutex tda998x: - Atomic modesetting support - TMDS clock limitations omapdrm: - Atomic modesetting support - improved TILER performance rockchip: - RK3036 VOP support - Atomic modesetting support - Synopsys DW MIPI DSI support exynos: - Runtime PM support - of_graph binding for DP panels - Cleanup of IPP code - Configurable plane support - Kernel panic fixes at release time" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (711 commits) drm/fb_cma_helper: Remove implicit call to disable_unused_functions drm/amdgpu: add missing irq.h include drm/vmwgfx: Fix a width / pitch mismatch on framebuffer updates drm/vmwgfx: Fix an incorrect lock check drm: nouveau: fix nouveau_debugfs_init prototype drm/nouveau/pci: fix check in nvkm_pcie_set_link drm/amdgpu: validate duplicates first drm/amdgpu: move VM page tables to the LRU end on CS v2 drm/ttm: add ttm_bo_move_to_lru_tail function v2 drm/ttm: fix adding foreign BOs to the swap LRU drm/ttm: fix adding foreign BOs to the LRU during init v2 drm/radeon: use kobj_to_dev() drm/amdgpu: use kobj_to_dev() drm/amdgpu/cz: force vce clocks when sclks are forced drm/amdgpu/cz: force uvd clocks when sclks are forced drm/amdgpu/cz: add code to enable forcing VCE clocks drm/amdgpu/cz: add code to enable forcing UVD clocks drm/amdgpu: fix lost sync_to if scheduler is enabled. drm/amd/powerplay: fix static checker warning for return meaningless value. drm/sysfs: use kobj_to_dev() ...
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos5433_drm_decon.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c124
1 files changed, 80 insertions, 44 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index fbe1b31..1bf6a21 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -21,11 +21,11 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
+#include "exynos_drm_fb.h"
#include "exynos_drm_plane.h"
#include "exynos_drm_iommu.h"
#define WINDOWS_NR 3
-#define CURSOR_WIN 2
#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
static const char * const decon_clks_name[] = {
@@ -56,6 +56,7 @@ struct decon_context {
struct drm_device *drm_dev;
struct exynos_drm_crtc *crtc;
struct exynos_drm_plane planes[WINDOWS_NR];
+ struct exynos_drm_plane_config configs[WINDOWS_NR];
void __iomem *addr;
struct clk *clks[ARRAY_SIZE(decon_clks_name)];
int pipe;
@@ -71,6 +72,12 @@ static const uint32_t decon_formats[] = {
DRM_FORMAT_ARGB8888,
};
+static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
+ DRM_PLANE_TYPE_PRIMARY,
+ DRM_PLANE_TYPE_OVERLAY,
+ DRM_PLANE_TYPE_CURSOR,
+};
+
static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
u32 val)
{
@@ -241,15 +248,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win,
protect ? ~0 : 0);
}
-static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
- struct exynos_drm_plane *plane)
+static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
{
struct decon_context *ctx = crtc->ctx;
+ int i;
if (test_bit(BIT_SUSPENDED, &ctx->flags))
return;
- decon_shadow_protect_win(ctx, plane->zpos, true);
+ for (i = ctx->first_win; i < WINDOWS_NR; i++)
+ decon_shadow_protect_win(ctx, i, true);
}
#define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
@@ -259,21 +267,24 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
+ struct exynos_drm_plane_state *state =
+ to_exynos_plane_state(plane->base.state);
struct decon_context *ctx = crtc->ctx;
- struct drm_plane_state *state = plane->base.state;
- unsigned int win = plane->zpos;
- unsigned int bpp = state->fb->bits_per_pixel >> 3;
- unsigned int pitch = state->fb->pitches[0];
+ struct drm_framebuffer *fb = state->base.fb;
+ unsigned int win = plane->index;
+ unsigned int bpp = fb->bits_per_pixel >> 3;
+ unsigned int pitch = fb->pitches[0];
+ dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
u32 val;
if (test_bit(BIT_SUSPENDED, &ctx->flags))
return;
- val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
+ val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
writel(val, ctx->addr + DECON_VIDOSDxA(win));
- val = COORDINATE_X(plane->crtc_x + plane->crtc_w - 1) |
- COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1);
+ val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
+ COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
writel(val, ctx->addr + DECON_VIDOSDxB(win));
val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
@@ -284,20 +295,20 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
VIDOSD_Wx_ALPHA_B_F(0x0);
writel(val, ctx->addr + DECON_VIDOSDxD(win));
- writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win));
+ writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
- val = plane->dma_addr[0] + pitch * plane->crtc_h;
+ val = dma_addr + pitch * state->src.h;
writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
if (ctx->out_type != IFTYPE_HDMI)
- val = BIT_VAL(pitch - plane->crtc_w * bpp, 27, 14)
- | BIT_VAL(plane->crtc_w * bpp, 13, 0);
+ val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
+ | BIT_VAL(state->crtc.w * bpp, 13, 0);
else
- val = BIT_VAL(pitch - plane->crtc_w * bpp, 29, 15)
- | BIT_VAL(plane->crtc_w * bpp, 14, 0);
+ val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
+ | BIT_VAL(state->crtc.w * bpp, 14, 0);
writel(val, ctx->addr + DECON_VIDW0xADD2(win));
- decon_win_set_pixfmt(ctx, win, state->fb);
+ decon_win_set_pixfmt(ctx, win, fb);
/* window enable */
decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
@@ -310,7 +321,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
struct decon_context *ctx = crtc->ctx;
- unsigned int win = plane->zpos;
+ unsigned int win = plane->index;
if (test_bit(BIT_SUSPENDED, &ctx->flags))
return;
@@ -326,15 +337,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
}
-static void decon_atomic_flush(struct exynos_drm_crtc *crtc,
- struct exynos_drm_plane *plane)
+static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
{
struct decon_context *ctx = crtc->ctx;
+ int i;
if (test_bit(BIT_SUSPENDED, &ctx->flags))
return;
- decon_shadow_protect_win(ctx, plane->zpos, false);
+ for (i = ctx->first_win; i < WINDOWS_NR; i++)
+ decon_shadow_protect_win(ctx, i, false);
if (ctx->out_type == IFTYPE_I80)
set_bit(BIT_WIN_UPDATED, &ctx->flags);
@@ -377,20 +389,12 @@ static void decon_swreset(struct decon_context *ctx)
static void decon_enable(struct exynos_drm_crtc *crtc)
{
struct decon_context *ctx = crtc->ctx;
- int ret;
- int i;
if (!test_and_clear_bit(BIT_SUSPENDED, &ctx->flags))
return;
pm_runtime_get_sync(ctx->dev);
- for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
- ret = clk_prepare_enable(ctx->clks[i]);
- if (ret < 0)
- goto err;
- }
-
set_bit(BIT_CLKS_ENABLED, &ctx->flags);
/* if vblank was enabled status, enable it again. */
@@ -399,11 +403,6 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
decon_commit(ctx->crtc);
- return;
-err:
- while (--i >= 0)
- clk_disable_unprepare(ctx->clks[i]);
-
set_bit(BIT_SUSPENDED, &ctx->flags);
}
@@ -425,9 +424,6 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
decon_swreset(ctx);
- for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
- clk_disable_unprepare(ctx->clks[i]);
-
clear_bit(BIT_CLKS_ENABLED, &ctx->flags);
pm_runtime_put_sync(ctx->dev);
@@ -478,7 +474,6 @@ err:
static struct exynos_drm_crtc_ops decon_crtc_ops = {
.enable = decon_enable,
.disable = decon_disable,
- .commit = decon_commit,
.enable_vblank = decon_enable_vblank,
.disable_vblank = decon_disable_vblank,
.atomic_begin = decon_atomic_begin,
@@ -495,7 +490,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
struct exynos_drm_private *priv = drm_dev->dev_private;
struct exynos_drm_plane *exynos_plane;
enum exynos_drm_output_type out_type;
- enum drm_plane_type type;
unsigned int win;
int ret;
@@ -505,10 +499,13 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
for (win = ctx->first_win; win < WINDOWS_NR; win++) {
int tmp = (win == ctx->first_win) ? 0 : win;
- type = exynos_plane_get_type(tmp, CURSOR_WIN);
- ret = exynos_plane_init(drm_dev, &ctx->planes[win],
- 1 << ctx->pipe, type, decon_formats,
- ARRAY_SIZE(decon_formats), win);
+ ctx->configs[win].pixel_formats = decon_formats;
+ ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats);
+ ctx->configs[win].zpos = win;
+ ctx->configs[win].type = decon_win_types[tmp];
+
+ ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
+ 1 << ctx->pipe, &ctx->configs[win]);
if (ret)
return ret;
}
@@ -581,6 +578,44 @@ out:
return IRQ_HANDLED;
}
+#ifdef CONFIG_PM
+static int exynos5433_decon_suspend(struct device *dev)
+{
+ struct decon_context *ctx = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
+ clk_disable_unprepare(ctx->clks[i]);
+
+ return 0;
+}
+
+static int exynos5433_decon_resume(struct device *dev)
+{
+ struct decon_context *ctx = dev_get_drvdata(dev);
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
+ ret = clk_prepare_enable(ctx->clks[i]);
+ if (ret < 0)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ while (--i >= 0)
+ clk_disable_unprepare(ctx->clks[i]);
+
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops exynos5433_decon_pm_ops = {
+ SET_RUNTIME_PM_OPS(exynos5433_decon_suspend, exynos5433_decon_resume,
+ NULL)
+};
+
static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
{
.compatible = "samsung,exynos5433-decon",
@@ -684,6 +719,7 @@ struct platform_driver exynos5433_decon_driver = {
.remove = exynos5433_decon_remove,
.driver = {
.name = "exynos5433-decon",
+ .pm = &exynos5433_decon_pm_ops,
.of_match_table = exynos5433_decon_driver_dt_match,
},
};
OpenPOWER on IntegriCloud