aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-02-12 22:02:49 -0500
committerDave Airlie <airlied@redhat.com>2015-02-12 22:02:49 -0500
commitab07881a2a51ccc55ecfb128094f57101d0669a8 (patch)
treee1146623d91a9283e3e818ab631079b9843040a7 /drivers/gpu
parent96abd10ecc2e9ab5c8060697ce721683f387c64e (diff)
parent96976c3d9aff4e1387c30f6356ac01fa6f72ef46 (diff)
Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
Summary: - Add code cleanups and bug fixups. - Add a new display controller dirver, DECON which is a new display controller of Exynos7 SoC. This device is much different from FIMD of Exynos4 and Exynos4 SoC series. * 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: drm/exynos: Add DECON driver drm/exynos: fix NULL pointer reference drm/exynos: remove exynos_plane_dpms drm/exynos: remove mode property of exynos crtc drm/exynos: Remove exynos_plane_dpms() call with no effect drm/exynos: fix DMA_ATTR_NO_KERNEL_MAPPING usage drm/exynos: hdmi: replace fb size with mode size from win commit drm/exynos: fix no hdmi output drm/exynos: use driver internal struct drm/exynos: fix wrong pipe calculation for crtc drm/exynos: remove to use unnecessary MODULE_xxx macro drm/exynos: remove DRM_EXYNOS_DMABUF config drm/exynos: IOMMU support should not be selectable by user drm/exynos: add support for 'hdmi' clock
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/Kconfig24
-rw-r--r--drivers/gpu/drm/exynos/Makefile4
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c990
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c14
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c62
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c56
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c33
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.h1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c23
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c48
19 files changed, 1102 insertions, 226 deletions
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index c072999b7e03..a5e74612100e 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -12,16 +12,9 @@ config DRM_EXYNOS
12 If M is selected the module will be called exynosdrm. 12 If M is selected the module will be called exynosdrm.
13 13
14config DRM_EXYNOS_IOMMU 14config DRM_EXYNOS_IOMMU
15 bool "EXYNOS DRM IOMMU Support" 15 bool
16 depends on DRM_EXYNOS && EXYNOS_IOMMU && ARM_DMA_USE_IOMMU 16 depends on DRM_EXYNOS && EXYNOS_IOMMU && ARM_DMA_USE_IOMMU
17 help 17 default y
18 Choose this option if you want to use IOMMU feature for DRM.
19
20config DRM_EXYNOS_DMABUF
21 bool "EXYNOS DRM DMABUF"
22 depends on DRM_EXYNOS
23 help
24 Choose this option if you want to use DMABUF feature for DRM.
25 18
26config DRM_EXYNOS_FIMD 19config DRM_EXYNOS_FIMD
27 bool "Exynos DRM FIMD" 20 bool "Exynos DRM FIMD"
@@ -31,9 +24,16 @@ config DRM_EXYNOS_FIMD
31 help 24 help
32 Choose this option if you want to use Exynos FIMD for DRM. 25 Choose this option if you want to use Exynos FIMD for DRM.
33 26
27config DRM_EXYNOS7_DECON
28 bool "Exynos DRM DECON"
29 depends on DRM_EXYNOS
30 select FB_MODE_HELPERS
31 help
32 Choose this option if you want to use Exynos DECON for DRM.
33
34config DRM_EXYNOS_DPI 34config DRM_EXYNOS_DPI
35 bool "EXYNOS DRM parallel output support" 35 bool "EXYNOS DRM parallel output support"
36 depends on DRM_EXYNOS_FIMD 36 depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
37 select DRM_PANEL 37 select DRM_PANEL
38 default n 38 default n
39 help 39 help
@@ -41,7 +41,7 @@ config DRM_EXYNOS_DPI
41 41
42config DRM_EXYNOS_DSI 42config DRM_EXYNOS_DSI
43 bool "EXYNOS DRM MIPI-DSI driver support" 43 bool "EXYNOS DRM MIPI-DSI driver support"
44 depends on DRM_EXYNOS_FIMD 44 depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
45 select DRM_MIPI_DSI 45 select DRM_MIPI_DSI
46 select DRM_PANEL 46 select DRM_PANEL
47 default n 47 default n
@@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI
50 50
51config DRM_EXYNOS_DP 51config DRM_EXYNOS_DP
52 bool "EXYNOS DRM DP driver support" 52 bool "EXYNOS DRM DP driver support"
53 depends on DRM_EXYNOS_FIMD && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS) 53 depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
54 default DRM_EXYNOS 54 default DRM_EXYNOS
55 select DRM_PANEL 55 select DRM_PANEL
56 help 56 help
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 33ae3652b8da..cc90679cfc06 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -6,11 +6,11 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
6exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \ 6exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o \
7 exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \ 7 exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
8 exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \ 8 exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
9 exynos_drm_plane.o 9 exynos_drm_plane.o exynos_drm_dmabuf.o
10 10
11exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o 11exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
12exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
13exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 12exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
13exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o
14exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o 14exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o
15exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o 15exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o
16exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o 16exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
new file mode 100644
index 000000000000..63f02e2380ae
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -0,0 +1,990 @@
1/* drivers/gpu/drm/exynos/exynos7_drm_decon.c
2 *
3 * Copyright (C) 2014 Samsung Electronics Co.Ltd
4 * Authors:
5 * Akshu Agarwal <akshua@gmail.com>
6 * Ajay Kumar <ajaykumar.rs@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14#include <drm/drmP.h>
15#include <drm/exynos_drm.h>
16
17#include <linux/clk.h>
18#include <linux/component.h>
19#include <linux/kernel.h>
20#include <linux/of.h>
21#include <linux/of_address.h>
22#include <linux/of_device.h>
23#include <linux/platform_device.h>
24#include <linux/pm_runtime.h>
25
26#include <video/of_display_timing.h>
27#include <video/of_videomode.h>
28#include <video/exynos7_decon.h>
29
30#include "exynos_drm_crtc.h"
31#include "exynos_drm_drv.h"
32#include "exynos_drm_fbdev.h"
33#include "exynos_drm_iommu.h"
34
35/*
36 * DECON stands for Display and Enhancement controller.
37 */
38
39#define DECON_DEFAULT_FRAMERATE 60
40#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
41
42#define WINDOWS_NR 2
43
44struct decon_win_data {
45 unsigned int ovl_x;
46 unsigned int ovl_y;
47 unsigned int offset_x;
48 unsigned int offset_y;
49 unsigned int ovl_width;
50 unsigned int ovl_height;
51 unsigned int fb_width;
52 unsigned int fb_height;
53 unsigned int bpp;
54 unsigned int pixel_format;
55 dma_addr_t dma_addr;
56 bool enabled;
57 bool resume;
58};
59
60struct decon_context {
61 struct device *dev;
62 struct drm_device *drm_dev;
63 struct exynos_drm_crtc *crtc;
64 struct clk *pclk;
65 struct clk *aclk;
66 struct clk *eclk;
67 struct clk *vclk;
68 void __iomem *regs;
69 struct decon_win_data win_data[WINDOWS_NR];
70 unsigned int default_win;
71 unsigned long irq_flags;
72 bool i80_if;
73 bool suspended;
74 int pipe;
75 wait_queue_head_t wait_vsync_queue;
76 atomic_t wait_vsync_event;
77
78 struct exynos_drm_panel_info panel;
79 struct exynos_drm_display *display;
80};
81
82static const struct of_device_id decon_driver_dt_match[] = {
83 {.compatible = "samsung,exynos7-decon"},
84 {},
85};
86MODULE_DEVICE_TABLE(of, decon_driver_dt_match);
87
88static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
89{
90 struct decon_context *ctx = crtc->ctx;
91
92 if (ctx->suspended)
93 return;
94
95 atomic_set(&ctx->wait_vsync_event, 1);
96
97 /*
98 * wait for DECON to signal VSYNC interrupt or return after
99 * timeout which is set to 50ms (refresh rate of 20).
100 */
101 if (!wait_event_timeout(ctx->wait_vsync_queue,
102 !atomic_read(&ctx->wait_vsync_event),
103 HZ/20))
104 DRM_DEBUG_KMS("vblank wait timed out.\n");
105}
106
107static void decon_clear_channel(struct decon_context *ctx)
108{
109 int win, ch_enabled = 0;
110
111 DRM_DEBUG_KMS("%s\n", __FILE__);
112
113 /* Check if any channel is enabled. */
114 for (win = 0; win < WINDOWS_NR; win++) {
115 u32 val = readl(ctx->regs + WINCON(win));
116
117 if (val & WINCONx_ENWIN) {
118 val &= ~WINCONx_ENWIN;
119 writel(val, ctx->regs + WINCON(win));
120 ch_enabled = 1;
121 }
122 }
123
124 /* Wait for vsync, as disable channel takes effect at next vsync */
125 if (ch_enabled) {
126 unsigned int state = ctx->suspended;
127
128 ctx->suspended = 0;
129 decon_wait_for_vblank(ctx->crtc);
130 ctx->suspended = state;
131 }
132}
133
134static int decon_ctx_initialize(struct decon_context *ctx,
135 struct drm_device *drm_dev)
136{
137 struct exynos_drm_private *priv = drm_dev->dev_private;
138
139 ctx->drm_dev = drm_dev;
140 ctx->pipe = priv->pipe++;
141
142 /* attach this sub driver to iommu mapping if supported. */
143 if (is_drm_iommu_supported(ctx->drm_dev)) {
144 int ret;
145
146 /*
147 * If any channel is already active, iommu will throw
148 * a PAGE FAULT when enabled. So clear any channel if enabled.
149 */
150 decon_clear_channel(ctx);
151 ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
152 if (ret) {
153 DRM_ERROR("drm_iommu_attach failed.\n");
154 return ret;
155 }
156 }
157
158 return 0;
159}
160
161static void decon_ctx_remove(struct decon_context *ctx)
162{
163 /* detach this sub driver from iommu mapping if supported. */
164 if (is_drm_iommu_supported(ctx->drm_dev))
165 drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
166}
167
168static u32 decon_calc_clkdiv(struct decon_context *ctx,
169 const struct drm_display_mode *mode)
170{
171 unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh;
172 u32 clkdiv;
173
174 /* Find the clock divider value that gets us closest to ideal_clk */
175 clkdiv = DIV_ROUND_UP(clk_get_rate(ctx->vclk), ideal_clk);
176
177 return (clkdiv < 0x100) ? clkdiv : 0xff;
178}
179
180static bool decon_mode_fixup(struct exynos_drm_crtc *crtc,
181 const struct drm_display_mode *mode,
182 struct drm_display_mode *adjusted_mode)
183{
184 if (adjusted_mode->vrefresh == 0)
185 adjusted_mode->vrefresh = DECON_DEFAULT_FRAMERATE;
186
187 return true;
188}
189
190static void decon_commit(struct exynos_drm_crtc *crtc)
191{
192 struct decon_context *ctx = crtc->ctx;
193 struct drm_display_mode *mode = &crtc->base.mode;
194 u32 val, clkdiv;
195
196 if (ctx->suspended)
197 return;
198
199 /* nothing to do if we haven't set the mode yet */
200 if (mode->htotal == 0 || mode->vtotal == 0)
201 return;
202
203 if (!ctx->i80_if) {
204 int vsync_len, vbpd, vfpd, hsync_len, hbpd, hfpd;
205 /* setup vertical timing values. */
206 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
207 vbpd = mode->crtc_vtotal - mode->crtc_vsync_end;
208 vfpd = mode->crtc_vsync_start - mode->crtc_vdisplay;
209
210 val = VIDTCON0_VBPD(vbpd - 1) | VIDTCON0_VFPD(vfpd - 1);
211 writel(val, ctx->regs + VIDTCON0);
212
213 val = VIDTCON1_VSPW(vsync_len - 1);
214 writel(val, ctx->regs + VIDTCON1);
215
216 /* setup horizontal timing values. */
217 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
218 hbpd = mode->crtc_htotal - mode->crtc_hsync_end;
219 hfpd = mode->crtc_hsync_start - mode->crtc_hdisplay;
220
221 /* setup horizontal timing values. */
222 val = VIDTCON2_HBPD(hbpd - 1) | VIDTCON2_HFPD(hfpd - 1);
223 writel(val, ctx->regs + VIDTCON2);
224
225 val = VIDTCON3_HSPW(hsync_len - 1);
226 writel(val, ctx->regs + VIDTCON3);
227 }
228
229 /* setup horizontal and vertical display size. */
230 val = VIDTCON4_LINEVAL(mode->vdisplay - 1) |
231 VIDTCON4_HOZVAL(mode->hdisplay - 1);
232 writel(val, ctx->regs + VIDTCON4);
233
234 writel(mode->vdisplay - 1, ctx->regs + LINECNT_OP_THRESHOLD);
235
236 /*
237 * fields of register with prefix '_F' would be updated
238 * at vsync(same as dma start)
239 */
240 val = VIDCON0_ENVID | VIDCON0_ENVID_F;
241 writel(val, ctx->regs + VIDCON0);
242
243 clkdiv = decon_calc_clkdiv(ctx, mode);
244 if (clkdiv > 1) {
245 val = VCLKCON1_CLKVAL_NUM_VCLK(clkdiv - 1);
246 writel(val, ctx->regs + VCLKCON1);
247 writel(val, ctx->regs + VCLKCON2);
248 }
249
250 val = readl(ctx->regs + DECON_UPDATE);
251 val |= DECON_UPDATE_STANDALONE_F;
252 writel(val, ctx->regs + DECON_UPDATE);
253}
254
255static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
256{
257 struct decon_context *ctx = crtc->ctx;
258 u32 val;
259
260 if (ctx->suspended)
261 return -EPERM;
262
263 if (!test_and_set_bit(0, &ctx->irq_flags)) {
264 val = readl(ctx->regs + VIDINTCON0);
265
266 val |= VIDINTCON0_INT_ENABLE;
267
268 if (!ctx->i80_if) {
269 val |= VIDINTCON0_INT_FRAME;
270 val &= ~VIDINTCON0_FRAMESEL0_MASK;
271 val |= VIDINTCON0_FRAMESEL0_VSYNC;
272 }
273
274 writel(val, ctx->regs + VIDINTCON0);
275 }
276
277 return 0;
278}
279
280static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
281{
282 struct decon_context *ctx = crtc->ctx;
283 u32 val;
284
285 if (ctx->suspended)
286 return;
287
288 if (test_and_clear_bit(0, &ctx->irq_flags)) {
289 val = readl(ctx->regs + VIDINTCON0);
290
291 val &= ~VIDINTCON0_INT_ENABLE;
292 if (!ctx->i80_if)
293 val &= ~VIDINTCON0_INT_FRAME;
294
295 writel(val, ctx->regs + VIDINTCON0);
296 }
297}
298
299static void decon_win_mode_set(struct exynos_drm_crtc *crtc,
300 struct exynos_drm_plane *plane)
301{
302 struct decon_context *ctx = crtc->ctx;
303 struct decon_win_data *win_data;
304 int win, padding;
305
306 if (!plane) {
307 DRM_ERROR("plane is NULL\n");
308 return;
309 }
310
311 win = plane->zpos;
312 if (win == DEFAULT_ZPOS)
313 win = ctx->default_win;
314
315 if (win < 0 || win >= WINDOWS_NR)
316 return;
317
318
319 win_data = &ctx->win_data[win];
320
321 padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width;
322 win_data->offset_x = plane->fb_x;
323 win_data->offset_y = plane->fb_y;
324 win_data->fb_width = plane->fb_width + padding;
325 win_data->fb_height = plane->fb_height;
326 win_data->ovl_x = plane->crtc_x;
327 win_data->ovl_y = plane->crtc_y;
328 win_data->ovl_width = plane->crtc_width;
329 win_data->ovl_height = plane->crtc_height;
330 win_data->dma_addr = plane->dma_addr[0];
331 win_data->bpp = plane->bpp;
332 win_data->pixel_format = plane->pixel_format;
333
334 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
335 win_data->offset_x, win_data->offset_y);
336 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
337 win_data->ovl_width, win_data->ovl_height);
338 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
339 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
340 plane->fb_width, plane->crtc_width);
341}
342
343static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win)
344{
345 struct decon_win_data *win_data = &ctx->win_data[win];
346 unsigned long val;
347
348 val = readl(ctx->regs + WINCON(win));
349 val &= ~WINCONx_BPPMODE_MASK;
350
351 switch (win_data->pixel_format) {
352 case DRM_FORMAT_RGB565:
353 val |= WINCONx_BPPMODE_16BPP_565;
354 val |= WINCONx_BURSTLEN_16WORD;
355 break;
356 case DRM_FORMAT_XRGB8888:
357 val |= WINCONx_BPPMODE_24BPP_xRGB;
358 val |= WINCONx_BURSTLEN_16WORD;
359 break;
360 case DRM_FORMAT_XBGR8888:
361 val |= WINCONx_BPPMODE_24BPP_xBGR;
362 val |= WINCONx_BURSTLEN_16WORD;
363 break;
364 case DRM_FORMAT_RGBX8888:
365 val |= WINCONx_BPPMODE_24BPP_RGBx;
366 val |= WINCONx_BURSTLEN_16WORD;
367 break;
368 case DRM_FORMAT_BGRX8888:
369 val |= WINCONx_BPPMODE_24BPP_BGRx;
370 val |= WINCONx_BURSTLEN_16WORD;
371 break;
372 case DRM_FORMAT_ARGB8888:
373 val |= WINCONx_BPPMODE_32BPP_ARGB | WINCONx_BLD_PIX |
374 WINCONx_ALPHA_SEL;
375 val |= WINCONx_BURSTLEN_16WORD;
376 break;
377 case DRM_FORMAT_ABGR8888:
378 val |= WINCONx_BPPMODE_32BPP_ABGR | WINCONx_BLD_PIX |
379 WINCONx_ALPHA_SEL;
380 val |= WINCONx_BURSTLEN_16WORD;
381 break;
382 case DRM_FORMAT_RGBA8888:
383 val |= WINCONx_BPPMODE_32BPP_RGBA | WINCONx_BLD_PIX |
384 WINCONx_ALPHA_SEL;
385 val |= WINCONx_BURSTLEN_16WORD;
386 break;
387 case DRM_FORMAT_BGRA8888:
388 val |= WINCONx_BPPMODE_32BPP_BGRA | WINCONx_BLD_PIX |
389 WINCONx_ALPHA_SEL;
390 val |= WINCONx_BURSTLEN_16WORD;
391 break;
392 default:
393 DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n");
394
395 val |= WINCONx_BPPMODE_24BPP_xRGB;
396 val |= WINCONx_BURSTLEN_16WORD;
397 break;
398 }
399
400 DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp);
401
402 /*
403 * In case of exynos, setting dma-burst to 16Word causes permanent
404 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
405 * switching which is based on plane size is not recommended as
406 * plane size varies a lot towards the end of the screen and rapid
407 * movement causes unstable DMA which results into iommu crash/tear.
408 */
409
410 if (win_data->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
411 val &= ~WINCONx_BURSTLEN_MASK;
412 val |= WINCONx_BURSTLEN_8WORD;
413 }
414
415 writel(val, ctx->regs + WINCON(win));
416}
417
418static void decon_win_set_colkey(struct decon_context *ctx, unsigned int win)
419{
420 unsigned int keycon0 = 0, keycon1 = 0;
421
422 keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F |
423 WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
424
425 keycon1 = WxKEYCON1_COLVAL(0xffffffff);
426
427 writel(keycon0, ctx->regs + WKEYCON0_BASE(win));
428 writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
429}
430
431/**
432 * shadow_protect_win() - disable updating values from shadow registers at vsync
433 *
434 * @win: window to protect registers for
435 * @protect: 1 to protect (disable updates)
436 */
437static void decon_shadow_protect_win(struct decon_context *ctx,
438 int win, bool protect)
439{
440 u32 bits, val;
441
442 bits = SHADOWCON_WINx_PROTECT(win);
443
444 val = readl(ctx->regs + SHADOWCON);
445 if (protect)
446 val |= bits;
447 else
448 val &= ~bits;
449 writel(val, ctx->regs + SHADOWCON);
450}
451
452static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos)
453{
454 struct decon_context *ctx = crtc->ctx;
455 struct drm_display_mode *mode = &crtc->base.mode;
456 struct decon_win_data *win_data;
457 int win = zpos;
458 unsigned long val, alpha;
459 unsigned int last_x;
460 unsigned int last_y;
461
462 if (ctx->suspended)
463 return;
464
465 if (win == DEFAULT_ZPOS)
466 win = ctx->default_win;
467
468 if (win < 0 || win >= WINDOWS_NR)
469 return;
470
471 win_data = &ctx->win_data[win];
472
473 /* If suspended, enable this on resume */
474 if (ctx->suspended) {
475 win_data->resume = true;
476 return;
477 }
478
479 /*
480 * SHADOWCON/PRTCON register is used for enabling timing.
481 *
482 * for example, once only width value of a register is set,
483 * if the dma is started then decon hardware could malfunction so
484 * with protect window setting, the register fields with prefix '_F'
485 * wouldn't be updated at vsync also but updated once unprotect window
486 * is set.
487 */
488
489 /* protect windows */
490 decon_shadow_protect_win(ctx, win, true);
491
492 /* buffer start address */
493 val = (unsigned long)win_data->dma_addr;
494 writel(val, ctx->regs + VIDW_BUF_START(win));
495
496 /* buffer size */
497 writel(win_data->fb_width, ctx->regs + VIDW_WHOLE_X(win));
498 writel(win_data->fb_height, ctx->regs + VIDW_WHOLE_Y(win));
499
500 /* offset from the start of the buffer to read */
501 writel(win_data->offset_x, ctx->regs + VIDW_OFFSET_X(win));
502 writel(win_data->offset_y, ctx->regs + VIDW_OFFSET_Y(win));
503
504 DRM_DEBUG_KMS("start addr = 0x%lx\n",
505 (unsigned long)win_data->dma_addr);
506 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
507 win_data->ovl_width, win_data->ovl_height);
508
509 /*
510 * OSD position.
511 * In case the window layout goes of LCD layout, DECON fails.
512 */
513 if ((win_data->ovl_x + win_data->ovl_width) > mode->hdisplay)
514 win_data->ovl_x = mode->hdisplay - win_data->ovl_width;
515 if ((win_data->ovl_y + win_data->ovl_height) > mode->vdisplay)
516 win_data->ovl_y = mode->vdisplay - win_data->ovl_height;
517
518 val = VIDOSDxA_TOPLEFT_X(win_data->ovl_x) |
519 VIDOSDxA_TOPLEFT_Y(win_data->ovl_y);
520 writel(val, ctx->regs + VIDOSD_A(win));
521
522 last_x = win_data->ovl_x + win_data->ovl_width;
523 if (last_x)
524 last_x--;
525 last_y = win_data->ovl_y + win_data->ovl_height;
526 if (last_y)
527 last_y--;
528
529 val = VIDOSDxB_BOTRIGHT_X(last_x) | VIDOSDxB_BOTRIGHT_Y(last_y);
530
531 writel(val, ctx->regs + VIDOSD_B(win));
532
533 DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
534 win_data->ovl_x, win_data->ovl_y, last_x, last_y);
535
536 /* OSD alpha */
537 alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
538 VIDOSDxC_ALPHA0_G_F(0x0) |
539 VIDOSDxC_ALPHA0_B_F(0x0);
540
541 writel(alpha, ctx->regs + VIDOSD_C(win));
542
543 alpha = VIDOSDxD_ALPHA1_R_F(0xff) |
544 VIDOSDxD_ALPHA1_G_F(0xff) |
545 VIDOSDxD_ALPHA1_B_F(0xff);
546
547 writel(alpha, ctx->regs + VIDOSD_D(win));
548
549 decon_win_set_pixfmt(ctx, win);
550
551 /* hardware window 0 doesn't support color key. */
552 if (win != 0)
553 decon_win_set_colkey(ctx, win);
554
555 /* wincon */
556 val = readl(ctx->regs + WINCON(win));
557 val |= WINCONx_TRIPLE_BUF_MODE;
558 val |= WINCONx_ENWIN;
559 writel(val, ctx->regs + WINCON(win));
560
561 /* Enable DMA channel and unprotect windows */
562 decon_shadow_protect_win(ctx, win, false);
563
564 val = readl(ctx->regs + DECON_UPDATE);
565 val |= DECON_UPDATE_STANDALONE_F;
566 writel(val, ctx->regs + DECON_UPDATE);
567
568 win_data->enabled = true;
569}
570
571static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos)
572{
573 struct decon_context *ctx = crtc->ctx;
574 struct decon_win_data *win_data;
575 int win = zpos;
576 u32 val;
577
578 if (win == DEFAULT_ZPOS)
579 win = ctx->default_win;
580
581 if (win < 0 || win >= WINDOWS_NR)
582 return;
583
584 win_data = &ctx->win_data[win];
585
586 if (ctx->suspended) {
587 /* do not resume this window*/
588 win_data->resume = false;
589 return;
590 }
591
592 /* protect windows */
593 decon_shadow_protect_win(ctx, win, true);
594
595 /* wincon */
596 val = readl(ctx->regs + WINCON(win));
597 val &= ~WINCONx_ENWIN;
598 writel(val, ctx->regs + WINCON(win));
599
600 /* unprotect windows */
601 decon_shadow_protect_win(ctx, win, false);
602
603 val = readl(ctx->regs + DECON_UPDATE);
604 val |= DECON_UPDATE_STANDALONE_F;
605 writel(val, ctx->regs + DECON_UPDATE);
606
607 win_data->enabled = false;
608}
609
610static void decon_window_suspend(struct decon_context *ctx)
611{
612 struct decon_win_data *win_data;
613 int i;
614
615 for (i = 0; i < WINDOWS_NR; i++) {
616 win_data = &ctx->win_data[i];
617 win_data->resume = win_data->enabled;
618 if (win_data->enabled)
619 decon_win_disable(ctx->crtc, i);
620 }
621}
622
623static void decon_window_resume(struct decon_context *ctx)
624{
625 struct decon_win_data *win_data;
626 int i;
627
628 for (i = 0; i < WINDOWS_NR; i++) {
629 win_data = &ctx->win_data[i];
630 win_data->enabled = win_data->resume;
631 win_data->resume = false;
632 }
633}
634
635static void decon_apply(struct decon_context *ctx)
636{
637 struct decon_win_data *win_data;
638 int i;
639
640 for (i = 0; i < WINDOWS_NR; i++) {
641 win_data = &ctx->win_data[i];
642 if (win_data->enabled)
643 decon_win_commit(ctx->crtc, i);
644 else
645 decon_win_disable(ctx->crtc, i);
646 }
647
648 decon_commit(ctx->crtc);
649}
650
651static void decon_init(struct decon_context *ctx)
652{
653 u32 val;
654
655 writel(VIDCON0_SWRESET, ctx->regs + VIDCON0);
656
657 val = VIDOUTCON0_DISP_IF_0_ON;
658 if (!ctx->i80_if)
659 val |= VIDOUTCON0_RGBIF;
660 writel(val, ctx->regs + VIDOUTCON0);
661
662 writel(VCLKCON0_CLKVALUP | VCLKCON0_VCLKFREE, ctx->regs + VCLKCON0);
663
664 if (!ctx->i80_if)
665 writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0));
666}
667
668static int decon_poweron(struct decon_context *ctx)
669{
670 int ret;
671
672 if (!ctx->suspended)
673 return 0;
674
675 ctx->suspended = false;
676
677 pm_runtime_get_sync(ctx->dev);
678
679 ret = clk_prepare_enable(ctx->pclk);
680 if (ret < 0) {
681 DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret);
682 goto pclk_err;
683 }
684
685 ret = clk_prepare_enable(ctx->aclk);
686 if (ret < 0) {
687 DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret);
688 goto aclk_err;
689 }
690
691 ret = clk_prepare_enable(ctx->eclk);
692 if (ret < 0) {
693 DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret);
694 goto eclk_err;
695 }
696
697 ret = clk_prepare_enable(ctx->vclk);
698 if (ret < 0) {
699 DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret);
700 goto vclk_err;
701 }
702
703 decon_init(ctx);
704
705 /* if vblank was enabled status, enable it again. */
706 if (test_and_clear_bit(0, &ctx->irq_flags)) {
707 ret = decon_enable_vblank(ctx->crtc);
708 if (ret) {
709 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
710 goto err;
711 }
712 }
713
714 decon_window_resume(ctx);
715
716 decon_apply(ctx);
717
718 return 0;
719
720err:
721 clk_disable_unprepare(ctx->vclk);
722vclk_err:
723 clk_disable_unprepare(ctx->eclk);
724eclk_err:
725 clk_disable_unprepare(ctx->aclk);
726aclk_err:
727 clk_disable_unprepare(ctx->pclk);
728pclk_err:
729 ctx->suspended = true;
730 return ret;
731}
732
733static int decon_poweroff(struct decon_context *ctx)
734{
735 if (ctx->suspended)
736 return 0;
737
738 /*
739 * We need to make sure that all windows are disabled before we
740 * suspend that connector. Otherwise we might try to scan from
741 * a destroyed buffer later.
742 */
743 decon_window_suspend(ctx);
744
745 clk_disable_unprepare(ctx->vclk);
746 clk_disable_unprepare(ctx->eclk);
747 clk_disable_unprepare(ctx->aclk);
748 clk_disable_unprepare(ctx->pclk);
749
750 pm_runtime_put_sync(ctx->dev);
751
752 ctx->suspended = true;
753 return 0;
754}
755
756static void decon_dpms(struct exynos_drm_crtc *crtc, int mode)
757{
758 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
759
760 switch (mode) {
761 case DRM_MODE_DPMS_ON:
762 decon_poweron(crtc->ctx);
763 break;
764 case DRM_MODE_DPMS_STANDBY:
765 case DRM_MODE_DPMS_SUSPEND:
766 case DRM_MODE_DPMS_OFF:
767 decon_poweroff(crtc->ctx);
768 break;
769 default:
770 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
771 break;
772 }
773}
774
775static struct exynos_drm_crtc_ops decon_crtc_ops = {
776 .dpms = decon_dpms,
777 .mode_fixup = decon_mode_fixup,
778 .commit = decon_commit,
779 .enable_vblank = decon_enable_vblank,
780 .disable_vblank = decon_disable_vblank,
781 .wait_for_vblank = decon_wait_for_vblank,
782 .win_mode_set = decon_win_mode_set,
783 .win_commit = decon_win_commit,
784 .win_disable = decon_win_disable,
785};
786
787
788static irqreturn_t decon_irq_handler(int irq, void *dev_id)
789{
790 struct decon_context *ctx = (struct decon_context *)dev_id;
791 u32 val, clear_bit;
792
793 val = readl(ctx->regs + VIDINTCON1);
794
795 clear_bit = ctx->i80_if ? VIDINTCON1_INT_I80 : VIDINTCON1_INT_FRAME;
796 if (val & clear_bit)
797 writel(clear_bit, ctx->regs + VIDINTCON1);
798
799 /* check the crtc is detached already from encoder */
800 if (ctx->pipe < 0 || !ctx->drm_dev)
801 goto out;
802
803 if (!ctx->i80_if) {
804 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
805 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
806
807 /* set wait vsync event to zero and wake up queue. */
808 if (atomic_read(&ctx->wait_vsync_event)) {
809 atomic_set(&ctx->wait_vsync_event, 0);
810 wake_up(&ctx->wait_vsync_queue);
811 }
812 }
813out:
814 return IRQ_HANDLED;
815}
816
817static int decon_bind(struct device *dev, struct device *master, void *data)
818{
819 struct decon_context *ctx = dev_get_drvdata(dev);
820 struct drm_device *drm_dev = data;
821 int ret;
822
823 ret = decon_ctx_initialize(ctx, drm_dev);
824 if (ret) {
825 DRM_ERROR("decon_ctx_initialize failed.\n");
826 return ret;
827 }
828
829 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
830 EXYNOS_DISPLAY_TYPE_LCD,
831 &decon_crtc_ops, ctx);
832 if (IS_ERR(ctx->crtc)) {
833 decon_ctx_remove(ctx);
834 return PTR_ERR(ctx->crtc);
835 }
836
837 if (ctx->display)
838 exynos_drm_create_enc_conn(drm_dev, ctx->display);
839
840 return 0;
841
842}
843
844static void decon_unbind(struct device *dev, struct device *master,
845 void *data)
846{
847 struct decon_context *ctx = dev_get_drvdata(dev);
848
849 decon_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
850
851 if (ctx->display)
852 exynos_dpi_remove(ctx->display);
853
854 decon_ctx_remove(ctx);
855}
856
857static const struct component_ops decon_component_ops = {
858 .bind = decon_bind,
859 .unbind = decon_unbind,
860};
861
862static int decon_probe(struct platform_device *pdev)
863{
864 struct device *dev = &pdev->dev;
865 struct decon_context *ctx;
866 struct device_node *i80_if_timings;
867 struct resource *res;
868 int ret;
869
870 if (!dev->of_node)
871 return -ENODEV;
872
873 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
874 if (!ctx)
875 return -ENOMEM;
876
877 ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
878 EXYNOS_DISPLAY_TYPE_LCD);
879 if (ret)
880 return ret;
881
882 ctx->dev = dev;
883 ctx->suspended = true;
884
885 i80_if_timings = of_get_child_by_name(dev->of_node, "i80-if-timings");
886 if (i80_if_timings)
887 ctx->i80_if = true;
888 of_node_put(i80_if_timings);
889
890 ctx->regs = of_iomap(dev->of_node, 0);
891 if (IS_ERR(ctx->regs)) {
892 ret = PTR_ERR(ctx->regs);
893 goto err_del_component;
894 }
895
896 ctx->pclk = devm_clk_get(dev, "pclk_decon0");
897 if (IS_ERR(ctx->pclk)) {
898 dev_err(dev, "failed to get bus clock pclk\n");
899 ret = PTR_ERR(ctx->pclk);
900 goto err_iounmap;
901 }
902
903 ctx->aclk = devm_clk_get(dev, "aclk_decon0");
904 if (IS_ERR(ctx->aclk)) {
905 dev_err(dev, "failed to get bus clock aclk\n");
906 ret = PTR_ERR(ctx->aclk);
907 goto err_iounmap;
908 }
909
910 ctx->eclk = devm_clk_get(dev, "decon0_eclk");
911 if (IS_ERR(ctx->eclk)) {
912 dev_err(dev, "failed to get eclock\n");
913 ret = PTR_ERR(ctx->eclk);
914 goto err_iounmap;
915 }
916
917 ctx->vclk = devm_clk_get(dev, "decon0_vclk");
918 if (IS_ERR(ctx->vclk)) {
919 dev_err(dev, "failed to get vclock\n");
920 ret = PTR_ERR(ctx->vclk);
921 goto err_iounmap;
922 }
923
924 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
925 ctx->i80_if ? "lcd_sys" : "vsync");
926 if (!res) {
927 dev_err(dev, "irq request failed.\n");
928 ret = -ENXIO;
929 goto err_iounmap;
930 }
931
932 ret = devm_request_irq(dev, res->start, decon_irq_handler,
933 0, "drm_decon", ctx);
934 if (ret) {
935 dev_err(dev, "irq request failed.\n");
936 goto err_iounmap;
937 }
938
939 init_waitqueue_head(&ctx->wait_vsync_queue);
940 atomic_set(&ctx->wait_vsync_event, 0);
941
942 platform_set_drvdata(pdev, ctx);
943
944 ctx->display = exynos_dpi_probe(dev);
945 if (IS_ERR(ctx->display)) {
946 ret = PTR_ERR(ctx->display);
947 goto err_iounmap;
948 }
949
950 pm_runtime_enable(dev);
951
952 ret = component_add(dev, &decon_component_ops);
953 if (ret)
954 goto err_disable_pm_runtime;
955
956 return ret;
957
958err_disable_pm_runtime:
959 pm_runtime_disable(dev);
960
961err_iounmap:
962 iounmap(ctx->regs);
963
964err_del_component:
965 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
966 return ret;
967}
968
969static int decon_remove(struct platform_device *pdev)
970{
971 struct decon_context *ctx = dev_get_drvdata(&pdev->dev);
972
973 pm_runtime_disable(&pdev->dev);
974
975 iounmap(ctx->regs);
976
977 component_del(&pdev->dev, &decon_component_ops);
978 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
979
980 return 0;
981}
982
983struct platform_driver decon_driver = {
984 .probe = decon_probe,
985 .remove = decon_remove,
986 .driver = {
987 .name = "exynos-decon",
988 .of_match_table = decon_driver_dt_match,
989 },
990};
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 46f149737bc8..bf17a60b40ed 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1058,10 +1058,8 @@ static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1058 phy_power_off(dp->phy); 1058 phy_power_off(dp->phy);
1059} 1059}
1060 1060
1061static void exynos_dp_poweron(struct exynos_drm_display *display) 1061static void exynos_dp_poweron(struct exynos_dp_device *dp)
1062{ 1062{
1063 struct exynos_dp_device *dp = display_to_dp(display);
1064
1065 if (dp->dpms_mode == DRM_MODE_DPMS_ON) 1063 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1066 return; 1064 return;
1067 1065
@@ -1076,13 +1074,11 @@ static void exynos_dp_poweron(struct exynos_drm_display *display)
1076 exynos_dp_phy_init(dp); 1074 exynos_dp_phy_init(dp);
1077 exynos_dp_init_dp(dp); 1075 exynos_dp_init_dp(dp);
1078 enable_irq(dp->irq); 1076 enable_irq(dp->irq);
1079 exynos_dp_commit(display); 1077 exynos_dp_commit(&dp->display);
1080} 1078}
1081 1079
1082static void exynos_dp_poweroff(struct exynos_drm_display *display) 1080static void exynos_dp_poweroff(struct exynos_dp_device *dp)
1083{ 1081{
1084 struct exynos_dp_device *dp = display_to_dp(display);
1085
1086 if (dp->dpms_mode != DRM_MODE_DPMS_ON) 1082 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
1087 return; 1083 return;
1088 1084
@@ -1110,12 +1106,12 @@ static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
1110 1106
1111 switch (mode) { 1107 switch (mode) {
1112 case DRM_MODE_DPMS_ON: 1108 case DRM_MODE_DPMS_ON:
1113 exynos_dp_poweron(display); 1109 exynos_dp_poweron(dp);
1114 break; 1110 break;
1115 case DRM_MODE_DPMS_STANDBY: 1111 case DRM_MODE_DPMS_STANDBY:
1116 case DRM_MODE_DPMS_SUSPEND: 1112 case DRM_MODE_DPMS_SUSPEND:
1117 case DRM_MODE_DPMS_OFF: 1113 case DRM_MODE_DPMS_OFF:
1118 exynos_dp_poweroff(display); 1114 exynos_dp_poweroff(dp);
1119 break; 1115 break;
1120 default: 1116 default:
1121 break; 1117 break;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 9c8088462c26..24994ba10e28 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -63,11 +63,11 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
63 return -ENOMEM; 63 return -ENOMEM;
64 } 64 }
65 65
66 buf->kvaddr = (void __iomem *)dma_alloc_attrs(dev->dev, 66 buf->cookie = dma_alloc_attrs(dev->dev,
67 buf->size, 67 buf->size,
68 &buf->dma_addr, GFP_KERNEL, 68 &buf->dma_addr, GFP_KERNEL,
69 &buf->dma_attrs); 69 &buf->dma_attrs);
70 if (!buf->kvaddr) { 70 if (!buf->cookie) {
71 DRM_ERROR("failed to allocate buffer.\n"); 71 DRM_ERROR("failed to allocate buffer.\n");
72 ret = -ENOMEM; 72 ret = -ENOMEM;
73 goto err_free; 73 goto err_free;
@@ -132,7 +132,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
132 buf->sgt = NULL; 132 buf->sgt = NULL;
133 133
134 if (!is_drm_iommu_supported(dev)) { 134 if (!is_drm_iommu_supported(dev)) {
135 dma_free_attrs(dev->dev, buf->size, buf->kvaddr, 135 dma_free_attrs(dev->dev, buf->size, buf->cookie,
136 (dma_addr_t)buf->dma_addr, &buf->dma_attrs); 136 (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
137 drm_free_large(buf->pages); 137 drm_free_large(buf->pages);
138 } else 138 } else
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index a85c451ba392..48ccab7fdf63 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -66,8 +66,6 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
66 66
67 if (exynos_crtc->ops->commit) 67 if (exynos_crtc->ops->commit)
68 exynos_crtc->ops->commit(exynos_crtc); 68 exynos_crtc->ops->commit(exynos_crtc);
69
70 exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON);
71} 69}
72 70
73static bool 71static bool
@@ -234,70 +232,12 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc)
234 kfree(exynos_crtc); 232 kfree(exynos_crtc);
235} 233}
236 234
237static int exynos_drm_crtc_set_property(struct drm_crtc *crtc,
238 struct drm_property *property,
239 uint64_t val)
240{
241 struct drm_device *dev = crtc->dev;
242 struct exynos_drm_private *dev_priv = dev->dev_private;
243 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
244
245 if (property == dev_priv->crtc_mode_property) {
246 enum exynos_crtc_mode mode = val;
247
248 if (mode == exynos_crtc->mode)
249 return 0;
250
251 exynos_crtc->mode = mode;
252
253 switch (mode) {
254 case CRTC_MODE_NORMAL:
255 exynos_drm_crtc_commit(crtc);
256 break;
257 case CRTC_MODE_BLANK:
258 exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_OFF);
259 break;
260 default:
261 break;
262 }
263
264 return 0;
265 }
266
267 return -EINVAL;
268}
269
270static struct drm_crtc_funcs exynos_crtc_funcs = { 235static struct drm_crtc_funcs exynos_crtc_funcs = {
271 .set_config = drm_crtc_helper_set_config, 236 .set_config = drm_crtc_helper_set_config,
272 .page_flip = exynos_drm_crtc_page_flip, 237 .page_flip = exynos_drm_crtc_page_flip,
273 .destroy = exynos_drm_crtc_destroy, 238 .destroy = exynos_drm_crtc_destroy,
274 .set_property = exynos_drm_crtc_set_property,
275};
276
277static const struct drm_prop_enum_list mode_names[] = {
278 { CRTC_MODE_NORMAL, "normal" },
279 { CRTC_MODE_BLANK, "blank" },
280}; 239};
281 240
282static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
283{
284 struct drm_device *dev = crtc->dev;
285 struct exynos_drm_private *dev_priv = dev->dev_private;
286 struct drm_property *prop;
287
288 prop = dev_priv->crtc_mode_property;
289 if (!prop) {
290 prop = drm_property_create_enum(dev, 0, "mode", mode_names,
291 ARRAY_SIZE(mode_names));
292 if (!prop)
293 return;
294
295 dev_priv->crtc_mode_property = prop;
296 }
297
298 drm_object_attach_property(&crtc->base, prop, 0);
299}
300
301struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, 241struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
302 int pipe, 242 int pipe,
303 enum exynos_drm_output_type type, 243 enum exynos_drm_output_type type,
@@ -340,8 +280,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
340 280
341 drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs); 281 drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs);
342 282
343 exynos_drm_crtc_attach_mode_property(crtc);
344
345 return exynos_crtc; 283 return exynos_crtc;
346 284
347err_crtc: 285err_crtc:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 60192ed544f0..3833bf8ca025 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -279,7 +279,3 @@ err_buf_detach:
279 279
280 return ERR_PTR(ret); 280 return ERR_PTR(ret);
281} 281}
282
283MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
284MODULE_DESCRIPTION("Samsung SoC DRM DMABUF Module");
285MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
index 49acfafb4fdb..886de9ff484d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
@@ -12,14 +12,9 @@
12#ifndef _EXYNOS_DRM_DMABUF_H_ 12#ifndef _EXYNOS_DRM_DMABUF_H_
13#define _EXYNOS_DRM_DMABUF_H_ 13#define _EXYNOS_DRM_DMABUF_H_
14 14
15#ifdef CONFIG_DRM_EXYNOS_DMABUF
16struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, 15struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
17 struct drm_gem_object *obj, int flags); 16 struct drm_gem_object *obj, int flags);
18 17
19struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, 18struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
20 struct dma_buf *dma_buf); 19 struct dma_buf *dma_buf);
21#else
22#define exynos_dmabuf_prime_export NULL
23#define exynos_dmabuf_prime_import NULL
24#endif
25#endif 20#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 1bcbe07cecfc..90168d7cf66a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -556,6 +556,9 @@ static struct platform_driver *const exynos_drm_kms_drivers[] = {
556#ifdef CONFIG_DRM_EXYNOS_FIMD 556#ifdef CONFIG_DRM_EXYNOS_FIMD
557 &fimd_driver, 557 &fimd_driver,
558#endif 558#endif
559#ifdef CONFIG_DRM_EXYNOS7_DECON
560 &decon_driver,
561#endif
559#ifdef CONFIG_DRM_EXYNOS_DP 562#ifdef CONFIG_DRM_EXYNOS_DP
560 &dp_driver, 563 &dp_driver,
561#endif 564#endif
@@ -612,6 +615,7 @@ static const char * const strings[] = {
612 "samsung,exynos3", 615 "samsung,exynos3",
613 "samsung,exynos4", 616 "samsung,exynos4",
614 "samsung,exynos5", 617 "samsung,exynos5",
618 "samsung,exynos7",
615}; 619};
616 620
617static struct platform_driver exynos_drm_platform_driver = { 621static struct platform_driver exynos_drm_platform_driver = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index d490b49f71c9..9afd390d4674 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -197,11 +197,6 @@ struct exynos_drm_crtc_ops {
197 void (*te_handler)(struct exynos_drm_crtc *crtc); 197 void (*te_handler)(struct exynos_drm_crtc *crtc);
198}; 198};
199 199
200enum exynos_crtc_mode {
201 CRTC_MODE_NORMAL, /* normal mode */
202 CRTC_MODE_BLANK, /* The private plane of crtc is blank */
203};
204
205/* 200/*
206 * Exynos specific crtc structure. 201 * Exynos specific crtc structure.
207 * 202 *
@@ -215,7 +210,6 @@ enum exynos_crtc_mode {
215 * we can refer to the crtc to current hardware interrupt occurred through 210 * we can refer to the crtc to current hardware interrupt occurred through
216 * this pipe value. 211 * this pipe value.
217 * @dpms: store the crtc dpms value 212 * @dpms: store the crtc dpms value
218 * @mode: store the crtc mode value
219 * @ops: pointer to callbacks for exynos drm specific functionality 213 * @ops: pointer to callbacks for exynos drm specific functionality
220 * @ctx: A pointer to the crtc's implementation specific context 214 * @ctx: A pointer to the crtc's implementation specific context
221 */ 215 */
@@ -224,7 +218,6 @@ struct exynos_drm_crtc {
224 enum exynos_drm_output_type type; 218 enum exynos_drm_output_type type;
225 unsigned int pipe; 219 unsigned int pipe;
226 unsigned int dpms; 220 unsigned int dpms;
227 enum exynos_crtc_mode mode;
228 wait_queue_head_t pending_flip_queue; 221 wait_queue_head_t pending_flip_queue;
229 atomic_t pending_flip; 222 atomic_t pending_flip;
230 struct exynos_drm_crtc_ops *ops; 223 struct exynos_drm_crtc_ops *ops;
@@ -265,7 +258,6 @@ struct exynos_drm_private {
265 */ 258 */
266 struct drm_crtc *crtc[MAX_CRTC]; 259 struct drm_crtc *crtc[MAX_CRTC];
267 struct drm_property *plane_zpos_property; 260 struct drm_property *plane_zpos_property;
268 struct drm_property *crtc_mode_property;
269 261
270 unsigned long da_start; 262 unsigned long da_start;
271 unsigned long da_space_size; 263 unsigned long da_space_size;
@@ -352,6 +344,7 @@ void exynos_drm_component_del(struct device *dev,
352 enum exynos_drm_device_type dev_type); 344 enum exynos_drm_device_type dev_type);
353 345
354extern struct platform_driver fimd_driver; 346extern struct platform_driver fimd_driver;
347extern struct platform_driver decon_driver;
355extern struct platform_driver dp_driver; 348extern struct platform_driver dp_driver;
356extern struct platform_driver dsi_driver; 349extern struct platform_driver dsi_driver;
357extern struct platform_driver mixer_driver; 350extern struct platform_driver mixer_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 7e282e3d6038..57de0bdc5a3b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -102,7 +102,7 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
102 102
103 /* all planes connected to this encoder should be also disabled. */ 103 /* all planes connected to this encoder should be also disabled. */
104 drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 104 drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
105 if (plane->crtc == encoder->crtc) 105 if (plane->crtc && (plane->crtc == encoder->crtc))
106 plane->funcs->disable_plane(plane); 106 plane->funcs->disable_plane(plane);
107 } 107 }
108} 108}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index e12ea90c6237..84f8dfe1c5ec 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -79,9 +79,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
79 struct drm_framebuffer *fb) 79 struct drm_framebuffer *fb)
80{ 80{
81 struct fb_info *fbi = helper->fbdev; 81 struct fb_info *fbi = helper->fbdev;
82 struct drm_device *dev = helper->dev;
83 struct exynos_drm_gem_buf *buffer; 82 struct exynos_drm_gem_buf *buffer;
84 unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3); 83 unsigned int size = fb->width * fb->height * (fb->bits_per_pixel >> 3);
84 unsigned int nr_pages;
85 unsigned long offset; 85 unsigned long offset;
86 86
87 drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); 87 drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
@@ -94,25 +94,14 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
94 return -EFAULT; 94 return -EFAULT;
95 } 95 }
96 96
97 /* map pages with kernel virtual space. */ 97 nr_pages = buffer->size >> PAGE_SHIFT;
98
99 buffer->kvaddr = (void __iomem *) vmap(buffer->pages,
100 nr_pages, VM_MAP,
101 pgprot_writecombine(PAGE_KERNEL));
98 if (!buffer->kvaddr) { 102 if (!buffer->kvaddr) {
99 if (is_drm_iommu_supported(dev)) { 103 DRM_ERROR("failed to map pages to kernel space.\n");
100 unsigned int nr_pages = buffer->size >> PAGE_SHIFT; 104 return -EIO;
101
102 buffer->kvaddr = (void __iomem *) vmap(buffer->pages,
103 nr_pages, VM_MAP,
104 pgprot_writecombine(PAGE_KERNEL));
105 } else {
106 phys_addr_t dma_addr = buffer->dma_addr;
107 if (dma_addr)
108 buffer->kvaddr = (void __iomem *)phys_to_virt(dma_addr);
109 else
110 buffer->kvaddr = (void __iomem *)NULL;
111 }
112 if (!buffer->kvaddr) {
113 DRM_ERROR("failed to map pages to kernel space.\n");
114 return -EIO;
115 }
116 } 105 }
117 106
118 /* buffer count to framebuffer always is 1 at booting time. */ 107 /* buffer count to framebuffer always is 1 at booting time. */
@@ -313,7 +302,7 @@ static void exynos_drm_fbdev_destroy(struct drm_device *dev,
313 struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj; 302 struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj;
314 struct drm_framebuffer *fb; 303 struct drm_framebuffer *fb;
315 304
316 if (is_drm_iommu_supported(dev) && exynos_gem_obj->buffer->kvaddr) 305 if (exynos_gem_obj->buffer->kvaddr)
317 vunmap(exynos_gem_obj->buffer->kvaddr); 306 vunmap(exynos_gem_obj->buffer->kvaddr);
318 307
319 /* release drm framebuffer and real buffer */ 308 /* release drm framebuffer and real buffer */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 682806ef4d33..925fc69af1a0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -253,9 +253,8 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
253 writel(val, ctx->regs + SHADOWCON); 253 writel(val, ctx->regs + SHADOWCON);
254} 254}
255 255
256static void fimd_clear_channel(struct exynos_drm_crtc *crtc) 256static void fimd_clear_channel(struct fimd_context *ctx)
257{ 257{
258 struct fimd_context *ctx = crtc->ctx;
259 int win, ch_enabled = 0; 258 int win, ch_enabled = 0;
260 259
261 DRM_DEBUG_KMS("%s\n", __FILE__); 260 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -280,7 +279,7 @@ static void fimd_clear_channel(struct exynos_drm_crtc *crtc)
280 unsigned int state = ctx->suspended; 279 unsigned int state = ctx->suspended;
281 280
282 ctx->suspended = 0; 281 ctx->suspended = 0;
283 fimd_wait_for_vblank(crtc); 282 fimd_wait_for_vblank(ctx->crtc);
284 ctx->suspended = state; 283 ctx->suspended = state;
285 } 284 }
286} 285}
@@ -302,7 +301,7 @@ static int fimd_ctx_initialize(struct fimd_context *ctx,
302 * If any channel is already active, iommu will throw 301 * If any channel is already active, iommu will throw
303 * a PAGE FAULT when enabled. So clear any channel if enabled. 302 * a PAGE FAULT when enabled. So clear any channel if enabled.
304 */ 303 */
305 fimd_clear_channel(ctx->crtc); 304 fimd_clear_channel(ctx);
306 ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev); 305 ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
307 if (ret) { 306 if (ret) {
308 DRM_ERROR("drm_iommu_attach failed.\n"); 307 DRM_ERROR("drm_iommu_attach failed.\n");
@@ -823,9 +822,8 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos)
823 win_data->enabled = false; 822 win_data->enabled = false;
824} 823}
825 824
826static void fimd_window_suspend(struct exynos_drm_crtc *crtc) 825static void fimd_window_suspend(struct fimd_context *ctx)
827{ 826{
828 struct fimd_context *ctx = crtc->ctx;
829 struct fimd_win_data *win_data; 827 struct fimd_win_data *win_data;
830 int i; 828 int i;
831 829
@@ -833,13 +831,12 @@ static void fimd_window_suspend(struct exynos_drm_crtc *crtc)
833 win_data = &ctx->win_data[i]; 831 win_data = &ctx->win_data[i];
834 win_data->resume = win_data->enabled; 832 win_data->resume = win_data->enabled;
835 if (win_data->enabled) 833 if (win_data->enabled)
836 fimd_win_disable(crtc, i); 834 fimd_win_disable(ctx->crtc, i);
837 } 835 }
838} 836}
839 837
840static void fimd_window_resume(struct exynos_drm_crtc *crtc) 838static void fimd_window_resume(struct fimd_context *ctx)
841{ 839{
842 struct fimd_context *ctx = crtc->ctx;
843 struct fimd_win_data *win_data; 840 struct fimd_win_data *win_data;
844 int i; 841 int i;
845 842
@@ -850,26 +847,24 @@ static void fimd_window_resume(struct exynos_drm_crtc *crtc)
850 } 847 }
851} 848}
852 849
853static void fimd_apply(struct exynos_drm_crtc *crtc) 850static void fimd_apply(struct fimd_context *ctx)
854{ 851{
855 struct fimd_context *ctx = crtc->ctx;
856 struct fimd_win_data *win_data; 852 struct fimd_win_data *win_data;
857 int i; 853 int i;
858 854
859 for (i = 0; i < WINDOWS_NR; i++) { 855 for (i = 0; i < WINDOWS_NR; i++) {
860 win_data = &ctx->win_data[i]; 856 win_data = &ctx->win_data[i];
861 if (win_data->enabled) 857 if (win_data->enabled)
862 fimd_win_commit(crtc, i); 858 fimd_win_commit(ctx->crtc, i);
863 else 859 else
864 fimd_win_disable(crtc, i); 860 fimd_win_disable(ctx->crtc, i);
865 } 861 }
866 862
867 fimd_commit(crtc); 863 fimd_commit(ctx->crtc);
868} 864}
869 865
870static int fimd_poweron(struct exynos_drm_crtc *crtc) 866static int fimd_poweron(struct fimd_context *ctx)
871{ 867{
872 struct fimd_context *ctx = crtc->ctx;
873 int ret; 868 int ret;
874 869
875 if (!ctx->suspended) 870 if (!ctx->suspended)
@@ -893,16 +888,16 @@ static int fimd_poweron(struct exynos_drm_crtc *crtc)
893 888
894 /* if vblank was enabled status, enable it again. */ 889 /* if vblank was enabled status, enable it again. */
895 if (test_and_clear_bit(0, &ctx->irq_flags)) { 890 if (test_and_clear_bit(0, &ctx->irq_flags)) {
896 ret = fimd_enable_vblank(crtc); 891 ret = fimd_enable_vblank(ctx->crtc);
897 if (ret) { 892 if (ret) {
898 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); 893 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
899 goto enable_vblank_err; 894 goto enable_vblank_err;
900 } 895 }
901 } 896 }
902 897
903 fimd_window_resume(crtc); 898 fimd_window_resume(ctx);
904 899
905 fimd_apply(crtc); 900 fimd_apply(ctx);
906 901
907 return 0; 902 return 0;
908 903
@@ -915,10 +910,8 @@ bus_clk_err:
915 return ret; 910 return ret;
916} 911}
917 912
918static int fimd_poweroff(struct exynos_drm_crtc *crtc) 913static int fimd_poweroff(struct fimd_context *ctx)
919{ 914{
920 struct fimd_context *ctx = crtc->ctx;
921
922 if (ctx->suspended) 915 if (ctx->suspended)
923 return 0; 916 return 0;
924 917
@@ -927,7 +920,7 @@ static int fimd_poweroff(struct exynos_drm_crtc *crtc)
927 * suspend that connector. Otherwise we might try to scan from 920 * suspend that connector. Otherwise we might try to scan from
928 * a destroyed buffer later. 921 * a destroyed buffer later.
929 */ 922 */
930 fimd_window_suspend(crtc); 923 fimd_window_suspend(ctx);
931 924
932 clk_disable_unprepare(ctx->lcd_clk); 925 clk_disable_unprepare(ctx->lcd_clk);
933 clk_disable_unprepare(ctx->bus_clk); 926 clk_disable_unprepare(ctx->bus_clk);
@@ -944,12 +937,12 @@ static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode)
944 937
945 switch (mode) { 938 switch (mode) {
946 case DRM_MODE_DPMS_ON: 939 case DRM_MODE_DPMS_ON:
947 fimd_poweron(crtc); 940 fimd_poweron(crtc->ctx);
948 break; 941 break;
949 case DRM_MODE_DPMS_STANDBY: 942 case DRM_MODE_DPMS_STANDBY:
950 case DRM_MODE_DPMS_SUSPEND: 943 case DRM_MODE_DPMS_SUSPEND:
951 case DRM_MODE_DPMS_OFF: 944 case DRM_MODE_DPMS_OFF:
952 fimd_poweroff(crtc); 945 fimd_poweroff(crtc->ctx);
953 break; 946 break;
954 default: 947 default:
955 DRM_DEBUG_KMS("unspecified mode %d\n", mode); 948 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -1065,18 +1058,19 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
1065 struct drm_device *drm_dev = data; 1058 struct drm_device *drm_dev = data;
1066 int ret; 1059 int ret;
1067 1060
1068 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
1069 EXYNOS_DISPLAY_TYPE_LCD,
1070 &fimd_crtc_ops, ctx);
1071 if (IS_ERR(ctx->crtc))
1072 return PTR_ERR(ctx->crtc);
1073
1074 ret = fimd_ctx_initialize(ctx, drm_dev); 1061 ret = fimd_ctx_initialize(ctx, drm_dev);
1075 if (ret) { 1062 if (ret) {
1076 DRM_ERROR("fimd_ctx_initialize failed.\n"); 1063 DRM_ERROR("fimd_ctx_initialize failed.\n");
1077 return ret; 1064 return ret;
1078 } 1065 }
1079 1066
1067 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
1068 EXYNOS_DISPLAY_TYPE_LCD,
1069 &fimd_crtc_ops, ctx);
1070 if (IS_ERR(ctx->crtc)) {
1071 fimd_ctx_remove(ctx);
1072 return PTR_ERR(ctx->crtc);
1073 }
1080 1074
1081 if (ctx->display) 1075 if (ctx->display)
1082 exynos_drm_create_enc_conn(drm_dev, ctx->display); 1076 exynos_drm_create_enc_conn(drm_dev, ctx->display);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index ec58fe9c40df..308173cb4f0a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -22,6 +22,7 @@
22/* 22/*
23 * exynos drm gem buffer structure. 23 * exynos drm gem buffer structure.
24 * 24 *
25 * @cookie: cookie returned by dma_alloc_attrs
25 * @kvaddr: kernel virtual address to allocated memory region. 26 * @kvaddr: kernel virtual address to allocated memory region.
26 * *userptr: user space address. 27 * *userptr: user space address.
27 * @dma_addr: bus address(accessed by dma) to allocated memory region. 28 * @dma_addr: bus address(accessed by dma) to allocated memory region.
@@ -35,6 +36,7 @@
35 * VM_PFNMAP or not. 36 * VM_PFNMAP or not.
36 */ 37 */
37struct exynos_drm_gem_buf { 38struct exynos_drm_gem_buf {
39 void *cookie;
38 void __iomem *kvaddr; 40 void __iomem *kvaddr;
39 unsigned long userptr; 41 unsigned long userptr;
40 dma_addr_t dma_addr; 42 dma_addr_t dma_addr;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 2f43a3c4f7b7..a5616872eee7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -144,32 +144,6 @@ void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
144 exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane); 144 exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane);
145} 145}
146 146
147void exynos_plane_dpms(struct drm_plane *plane, int mode)
148{
149 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
150 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
151
152 if (mode == DRM_MODE_DPMS_ON) {
153 if (exynos_plane->enabled)
154 return;
155
156 if (exynos_crtc->ops->win_enable)
157 exynos_crtc->ops->win_enable(exynos_crtc,
158 exynos_plane->zpos);
159
160 exynos_plane->enabled = true;
161 } else {
162 if (!exynos_plane->enabled)
163 return;
164
165 if (exynos_crtc->ops->win_disable)
166 exynos_crtc->ops->win_disable(exynos_crtc,
167 exynos_plane->zpos);
168
169 exynos_plane->enabled = false;
170 }
171}
172
173int 147int
174exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 148exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
175 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 149 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -198,7 +172,12 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
198 172
199static int exynos_disable_plane(struct drm_plane *plane) 173static int exynos_disable_plane(struct drm_plane *plane)
200{ 174{
201 exynos_plane_dpms(plane, DRM_MODE_DPMS_OFF); 175 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
176 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
177
178 if (exynos_crtc->ops->win_disable)
179 exynos_crtc->ops->win_disable(exynos_crtc,
180 exynos_plane->zpos);
202 181
203 return 0; 182 return 0;
204} 183}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
index 59d40755095b..9d3c374e7b3e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
@@ -20,7 +20,6 @@ int exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
20 unsigned int crtc_w, unsigned int crtc_h, 20 unsigned int crtc_w, unsigned int crtc_h,
21 uint32_t src_x, uint32_t src_y, 21 uint32_t src_x, uint32_t src_y,
22 uint32_t src_w, uint32_t src_h); 22 uint32_t src_w, uint32_t src_h);
23void exynos_plane_dpms(struct drm_plane *plane, int mode);
24struct drm_plane *exynos_plane_init(struct drm_device *dev, 23struct drm_plane *exynos_plane_init(struct drm_device *dev,
25 unsigned long possible_crtcs, 24 unsigned long possible_crtcs,
26 enum drm_plane_type type); 25 enum drm_plane_type type);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 9c8300edd348..b886972b5888 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -97,17 +97,16 @@ static const char fake_edid_info[] = {
97 0x00, 0x00, 0x00, 0x06 97 0x00, 0x00, 0x00, 0x06
98}; 98};
99 99
100static void vidi_apply(struct exynos_drm_crtc *crtc) 100static void vidi_apply(struct vidi_context *ctx)
101{ 101{
102 struct vidi_context *ctx = crtc->ctx; 102 struct exynos_drm_crtc_ops *crtc_ops = ctx->crtc->ops;
103 struct exynos_drm_crtc_ops *crtc_ops = crtc->ops;
104 struct vidi_win_data *win_data; 103 struct vidi_win_data *win_data;
105 int i; 104 int i;
106 105
107 for (i = 0; i < WINDOWS_NR; i++) { 106 for (i = 0; i < WINDOWS_NR; i++) {
108 win_data = &ctx->win_data[i]; 107 win_data = &ctx->win_data[i];
109 if (win_data->enabled && (crtc_ops && crtc_ops->win_commit)) 108 if (win_data->enabled && (crtc_ops && crtc_ops->win_commit))
110 crtc_ops->win_commit(crtc, i); 109 crtc_ops->win_commit(ctx->crtc, i);
111 } 110 }
112} 111}
113 112
@@ -240,10 +239,8 @@ static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos)
240 /* TODO. */ 239 /* TODO. */
241} 240}
242 241
243static int vidi_power_on(struct exynos_drm_crtc *crtc, bool enable) 242static int vidi_power_on(struct vidi_context *ctx, bool enable)
244{ 243{
245 struct vidi_context *ctx = crtc->ctx;
246
247 DRM_DEBUG_KMS("%s\n", __FILE__); 244 DRM_DEBUG_KMS("%s\n", __FILE__);
248 245
249 if (enable != false && enable != true) 246 if (enable != false && enable != true)
@@ -254,9 +251,9 @@ static int vidi_power_on(struct exynos_drm_crtc *crtc, bool enable)
254 251
255 /* if vblank was enabled status, enable it again. */ 252 /* if vblank was enabled status, enable it again. */
256 if (test_and_clear_bit(0, &ctx->irq_flags)) 253 if (test_and_clear_bit(0, &ctx->irq_flags))
257 vidi_enable_vblank(crtc); 254 vidi_enable_vblank(ctx->crtc);
258 255
259 vidi_apply(crtc); 256 vidi_apply(ctx);
260 } else { 257 } else {
261 ctx->suspended = true; 258 ctx->suspended = true;
262 } 259 }
@@ -274,12 +271,12 @@ static void vidi_dpms(struct exynos_drm_crtc *crtc, int mode)
274 271
275 switch (mode) { 272 switch (mode) {
276 case DRM_MODE_DPMS_ON: 273 case DRM_MODE_DPMS_ON:
277 vidi_power_on(crtc, true); 274 vidi_power_on(ctx, true);
278 break; 275 break;
279 case DRM_MODE_DPMS_STANDBY: 276 case DRM_MODE_DPMS_STANDBY:
280 case DRM_MODE_DPMS_SUSPEND: 277 case DRM_MODE_DPMS_SUSPEND:
281 case DRM_MODE_DPMS_OFF: 278 case DRM_MODE_DPMS_OFF:
282 vidi_power_on(crtc, false); 279 vidi_power_on(ctx, false);
283 break; 280 break;
284 default: 281 default:
285 DRM_DEBUG_KMS("unspecified mode %d\n", mode); 282 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -548,6 +545,8 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
548 struct drm_device *drm_dev = data; 545 struct drm_device *drm_dev = data;
549 int ret; 546 int ret;
550 547
548 vidi_ctx_initialize(ctx, drm_dev);
549
551 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, 550 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
552 EXYNOS_DISPLAY_TYPE_VIDI, 551 EXYNOS_DISPLAY_TYPE_VIDI,
553 &vidi_crtc_ops, ctx); 552 &vidi_crtc_ops, ctx);
@@ -556,8 +555,6 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
556 return PTR_ERR(ctx->crtc); 555 return PTR_ERR(ctx->crtc);
557 } 556 }
558 557
559 vidi_ctx_initialize(ctx, drm_dev);
560
561 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display); 558 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
562 if (ret) { 559 if (ret) {
563 ctx->crtc->base.funcs->destroy(&ctx->crtc->base); 560 ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 98051e8e855a..229b3613c60b 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -2032,9 +2032,8 @@ static void hdmi_commit(struct exynos_drm_display *display)
2032 hdmi_conf_apply(hdata); 2032 hdmi_conf_apply(hdata);
2033} 2033}
2034 2034
2035static void hdmi_poweron(struct exynos_drm_display *display) 2035static void hdmi_poweron(struct hdmi_context *hdata)
2036{ 2036{
2037 struct hdmi_context *hdata = display_to_hdmi(display);
2038 struct hdmi_resources *res = &hdata->res; 2037 struct hdmi_resources *res = &hdata->res;
2039 2038
2040 mutex_lock(&hdata->hdmi_mutex); 2039 mutex_lock(&hdata->hdmi_mutex);
@@ -2060,12 +2059,11 @@ static void hdmi_poweron(struct exynos_drm_display *display)
2060 clk_prepare_enable(res->sclk_hdmi); 2059 clk_prepare_enable(res->sclk_hdmi);
2061 2060
2062 hdmiphy_poweron(hdata); 2061 hdmiphy_poweron(hdata);
2063 hdmi_commit(display); 2062 hdmi_commit(&hdata->display);
2064} 2063}
2065 2064
2066static void hdmi_poweroff(struct exynos_drm_display *display) 2065static void hdmi_poweroff(struct hdmi_context *hdata)
2067{ 2066{
2068 struct hdmi_context *hdata = display_to_hdmi(display);
2069 struct hdmi_resources *res = &hdata->res; 2067 struct hdmi_resources *res = &hdata->res;
2070 2068
2071 mutex_lock(&hdata->hdmi_mutex); 2069 mutex_lock(&hdata->hdmi_mutex);
@@ -2109,7 +2107,7 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
2109 2107
2110 switch (mode) { 2108 switch (mode) {
2111 case DRM_MODE_DPMS_ON: 2109 case DRM_MODE_DPMS_ON:
2112 hdmi_poweron(display); 2110 hdmi_poweron(hdata);
2113 break; 2111 break;
2114 case DRM_MODE_DPMS_STANDBY: 2112 case DRM_MODE_DPMS_STANDBY:
2115 case DRM_MODE_DPMS_SUSPEND: 2113 case DRM_MODE_DPMS_SUSPEND:
@@ -2128,7 +2126,7 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
2128 if (funcs && funcs->dpms) 2126 if (funcs && funcs->dpms)
2129 (*funcs->dpms)(crtc, mode); 2127 (*funcs->dpms)(crtc, mode);
2130 2128
2131 hdmi_poweroff(display); 2129 hdmi_poweroff(hdata);
2132 break; 2130 break;
2133 default: 2131 default:
2134 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 2132 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 2fd2e5d46142..3518bc4654c5 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -72,6 +72,7 @@ struct mixer_resources {
72 spinlock_t reg_slock; 72 spinlock_t reg_slock;
73 struct clk *mixer; 73 struct clk *mixer;
74 struct clk *vp; 74 struct clk *vp;
75 struct clk *hdmi;
75 struct clk *sclk_mixer; 76 struct clk *sclk_mixer;
76 struct clk *sclk_hdmi; 77 struct clk *sclk_hdmi;
77 struct clk *mout_mixer; 78 struct clk *mout_mixer;
@@ -580,8 +581,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
580 /* setup display size */ 581 /* setup display size */
581 if (ctx->mxr_ver == MXR_VER_128_0_0_184 && 582 if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
582 win == MIXER_DEFAULT_WIN) { 583 win == MIXER_DEFAULT_WIN) {
583 val = MXR_MXR_RES_HEIGHT(win_data->fb_height); 584 val = MXR_MXR_RES_HEIGHT(win_data->mode_height);
584 val |= MXR_MXR_RES_WIDTH(win_data->fb_width); 585 val |= MXR_MXR_RES_WIDTH(win_data->mode_width);
585 mixer_reg_write(res, MXR_RESOLUTION, val); 586 mixer_reg_write(res, MXR_RESOLUTION, val);
586 } 587 }
587 588
@@ -767,6 +768,12 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
767 return -ENODEV; 768 return -ENODEV;
768 } 769 }
769 770
771 mixer_res->hdmi = devm_clk_get(dev, "hdmi");
772 if (IS_ERR(mixer_res->hdmi)) {
773 dev_err(dev, "failed to get clock 'hdmi'\n");
774 return PTR_ERR(mixer_res->hdmi);
775 }
776
770 mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); 777 mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
771 if (IS_ERR(mixer_res->sclk_hdmi)) { 778 if (IS_ERR(mixer_res->sclk_hdmi)) {
772 dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); 779 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
@@ -1045,23 +1052,21 @@ static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
1045 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe); 1052 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
1046} 1053}
1047 1054
1048static void mixer_window_suspend(struct exynos_drm_crtc *crtc) 1055static void mixer_window_suspend(struct mixer_context *ctx)
1049{ 1056{
1050 struct mixer_context *ctx = crtc->ctx;
1051 struct hdmi_win_data *win_data; 1057 struct hdmi_win_data *win_data;
1052 int i; 1058 int i;
1053 1059
1054 for (i = 0; i < MIXER_WIN_NR; i++) { 1060 for (i = 0; i < MIXER_WIN_NR; i++) {
1055 win_data = &ctx->win_data[i]; 1061 win_data = &ctx->win_data[i];
1056 win_data->resume = win_data->enabled; 1062 win_data->resume = win_data->enabled;
1057 mixer_win_disable(crtc, i); 1063 mixer_win_disable(ctx->crtc, i);
1058 } 1064 }
1059 mixer_wait_for_vblank(crtc); 1065 mixer_wait_for_vblank(ctx->crtc);
1060} 1066}
1061 1067
1062static void mixer_window_resume(struct exynos_drm_crtc *crtc) 1068static void mixer_window_resume(struct mixer_context *ctx)
1063{ 1069{
1064 struct mixer_context *ctx = crtc->ctx;
1065 struct hdmi_win_data *win_data; 1070 struct hdmi_win_data *win_data;
1066 int i; 1071 int i;
1067 1072
@@ -1070,13 +1075,12 @@ static void mixer_window_resume(struct exynos_drm_crtc *crtc)
1070 win_data->enabled = win_data->resume; 1075 win_data->enabled = win_data->resume;
1071 win_data->resume = false; 1076 win_data->resume = false;
1072 if (win_data->enabled) 1077 if (win_data->enabled)
1073 mixer_win_commit(crtc, i); 1078 mixer_win_commit(ctx->crtc, i);
1074 } 1079 }
1075} 1080}
1076 1081
1077static void mixer_poweron(struct exynos_drm_crtc *crtc) 1082static void mixer_poweron(struct mixer_context *ctx)
1078{ 1083{
1079 struct mixer_context *ctx = crtc->ctx;
1080 struct mixer_resources *res = &ctx->mixer_res; 1084 struct mixer_resources *res = &ctx->mixer_res;
1081 1085
1082 mutex_lock(&ctx->mixer_mutex); 1086 mutex_lock(&ctx->mixer_mutex);
@@ -1090,6 +1094,7 @@ static void mixer_poweron(struct exynos_drm_crtc *crtc)
1090 pm_runtime_get_sync(ctx->dev); 1094 pm_runtime_get_sync(ctx->dev);
1091 1095
1092 clk_prepare_enable(res->mixer); 1096 clk_prepare_enable(res->mixer);
1097 clk_prepare_enable(res->hdmi);
1093 if (ctx->vp_enabled) { 1098 if (ctx->vp_enabled) {
1094 clk_prepare_enable(res->vp); 1099 clk_prepare_enable(res->vp);
1095 if (ctx->has_sclk) 1100 if (ctx->has_sclk)
@@ -1105,12 +1110,11 @@ static void mixer_poweron(struct exynos_drm_crtc *crtc)
1105 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 1110 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1106 mixer_win_reset(ctx); 1111 mixer_win_reset(ctx);
1107 1112
1108 mixer_window_resume(crtc); 1113 mixer_window_resume(ctx);
1109} 1114}
1110 1115
1111static void mixer_poweroff(struct exynos_drm_crtc *crtc) 1116static void mixer_poweroff(struct mixer_context *ctx)
1112{ 1117{
1113 struct mixer_context *ctx = crtc->ctx;
1114 struct mixer_resources *res = &ctx->mixer_res; 1118 struct mixer_resources *res = &ctx->mixer_res;
1115 1119
1116 mutex_lock(&ctx->mixer_mutex); 1120 mutex_lock(&ctx->mixer_mutex);
@@ -1121,7 +1125,7 @@ static void mixer_poweroff(struct exynos_drm_crtc *crtc)
1121 mutex_unlock(&ctx->mixer_mutex); 1125 mutex_unlock(&ctx->mixer_mutex);
1122 1126
1123 mixer_stop(ctx); 1127 mixer_stop(ctx);
1124 mixer_window_suspend(crtc); 1128 mixer_window_suspend(ctx);
1125 1129
1126 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 1130 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1127 1131
@@ -1129,6 +1133,7 @@ static void mixer_poweroff(struct exynos_drm_crtc *crtc)
1129 ctx->powered = false; 1133 ctx->powered = false;
1130 mutex_unlock(&ctx->mixer_mutex); 1134 mutex_unlock(&ctx->mixer_mutex);
1131 1135
1136 clk_disable_unprepare(res->hdmi);
1132 clk_disable_unprepare(res->mixer); 1137 clk_disable_unprepare(res->mixer);
1133 if (ctx->vp_enabled) { 1138 if (ctx->vp_enabled) {
1134 clk_disable_unprepare(res->vp); 1139 clk_disable_unprepare(res->vp);
@@ -1143,12 +1148,12 @@ static void mixer_dpms(struct exynos_drm_crtc *crtc, int mode)
1143{ 1148{
1144 switch (mode) { 1149 switch (mode) {
1145 case DRM_MODE_DPMS_ON: 1150 case DRM_MODE_DPMS_ON:
1146 mixer_poweron(crtc); 1151 mixer_poweron(crtc->ctx);
1147 break; 1152 break;
1148 case DRM_MODE_DPMS_STANDBY: 1153 case DRM_MODE_DPMS_STANDBY:
1149 case DRM_MODE_DPMS_SUSPEND: 1154 case DRM_MODE_DPMS_SUSPEND:
1150 case DRM_MODE_DPMS_OFF: 1155 case DRM_MODE_DPMS_OFF:
1151 mixer_poweroff(crtc); 1156 mixer_poweroff(crtc->ctx);
1152 break; 1157 break;
1153 default: 1158 default:
1154 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 1159 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
@@ -1247,18 +1252,19 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
1247 struct drm_device *drm_dev = data; 1252 struct drm_device *drm_dev = data;
1248 int ret; 1253 int ret;
1249 1254
1255 ret = mixer_initialize(ctx, drm_dev);
1256 if (ret)
1257 return ret;
1258
1250 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, 1259 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
1251 EXYNOS_DISPLAY_TYPE_HDMI, 1260 EXYNOS_DISPLAY_TYPE_HDMI,
1252 &mixer_crtc_ops, ctx); 1261 &mixer_crtc_ops, ctx);
1253 if (IS_ERR(ctx->crtc)) { 1262 if (IS_ERR(ctx->crtc)) {
1263 mixer_ctx_remove(ctx);
1254 ret = PTR_ERR(ctx->crtc); 1264 ret = PTR_ERR(ctx->crtc);
1255 goto free_ctx; 1265 goto free_ctx;
1256 } 1266 }
1257 1267
1258 ret = mixer_initialize(ctx, drm_dev);
1259 if (ret)
1260 goto free_ctx;
1261
1262 return 0; 1268 return 0;
1263 1269
1264free_ctx: 1270free_ctx: