aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-05-04 03:37:20 -0400
committerDave Airlie <airlied@redhat.com>2016-05-04 03:37:20 -0400
commit00c1beab15df9216cf39818a437b34f296423ac4 (patch)
treebdd83f80022f4c921853c92e46193cb9c873eab1
parentacff058f8625022bbc37a3521f8208810a42c4ef (diff)
parentb5bf0f1ea3658254bd72ef64abc97786e8a32255 (diff)
Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
Summary: - Support for pipeline clock between KMS drivers. . Exynos SoC is required to control clocks across KMS drivers according to Exynos SoC version. So this patch refactos some relevant codes and provides generic solution for it. - Add Exynos5433 SoC support to HDMI parts - HDMI and DECON-TV. - Add HW trigger mode support to CRTC drivers. . In case of using i80 Panel, some Exynos SoC supports HW trigger mode so this patch makes trigger mode - HW or SW trigger - to be set according to SoC version properly. - And some cleanups and regression fixups. * 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (39 commits) drm/exynos: clean up register definions for fimd and decon drm/exynos: decon: clean up interface type drm/exynos: fimd: add HW trigger support drm/exynos: clean up wait_for_vblank drm/exynos: mixer: use generic of_device_get_match_data helper drm/exynos: mixer: remove support for non-dt platforms drm/exynos: hdmi: use generic of_device_get_match_data helper drm/exynos: rotator: use generic of_device_get_match_data helper drm/exynos: fimd: use generic of_device_get_match_data helper drm/exynos: dsi: use generic of_device_get_match_data helper drm/exynos: exynos5433_decon: use generic of_device_get_match_data helper drm/exynos: convert clock_enable crtc callback to pipeline clock drm/exynos/mixer: enable HDMI-PHY before configuring MIXER drm/exynos/decon5433: enable HDMI-PHY before configuring DECON drm/exynos: add support for pipeline clock to the framework drm/exynos: add helper to get crtc from pipe drm/exynos/decon5433: do not protect window in plane disable drm/exynos/decon5433: reset decon on start drm/exynos/decon5433: fix DECON standalone update drm/exynos/hdmi: remove registry dump ...
-rw-r--r--Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt5
-rw-r--r--Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt27
-rw-r--r--drivers/gpu/drm/exynos/Kconfig2
-rw-r--r--drivers/gpu/drm/exynos/Makefile6
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c86
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h28
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c27
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c11
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c11
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.h23
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c99
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_mic.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_rotator.c11
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c738
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c69
-rw-r--r--drivers/gpu/drm/exynos/regs-hdmi.h9
-rw-r--r--include/video/exynos5433_decon.h6
22 files changed, 572 insertions, 623 deletions
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
index 377afbf5122a..c9fd7b3807e7 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt
@@ -5,7 +5,8 @@ Exynos series of SoCs which transfers the image data from a video memory
5buffer to an external LCD interface. 5buffer to an external LCD interface.
6 6
7Required properties: 7Required properties:
8- compatible: value should be "samsung,exynos5433-decon"; 8- compatible: value should be one of:
9 "samsung,exynos5433-decon", "samsung,exynos5433-decon-tv";
9- reg: physical base address and length of the DECON registers set. 10- reg: physical base address and length of the DECON registers set.
10- interrupts: should contain a list of all DECON IP block interrupts in the 11- interrupts: should contain a list of all DECON IP block interrupts in the
11 order: VSYNC, LCD_SYSTEM. The interrupt specifier format 12 order: VSYNC, LCD_SYSTEM. The interrupt specifier format
@@ -16,7 +17,7 @@ Required properties:
16- clocks: must include clock specifiers corresponding to entries in the 17- clocks: must include clock specifiers corresponding to entries in the
17 clock-names property. 18 clock-names property.
18- clock-names: list of clock names sorted in the same order as the clocks 19- clock-names: list of clock names sorted in the same order as the clocks
19 property. Must contain "aclk_decon", "aclk_smmu_decon0x", 20 property. Must contain "pclk", "aclk_decon", "aclk_smmu_decon0x",
20 "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk", 21 "aclk_xiu_decon0x", "pclk_smmu_decon0x", clk_decon_vclk",
21 "sclk_decon_eclk" 22 "sclk_decon_eclk"
22- ports: contains a port which is connected to mic node. address-cells and 23- ports: contains a port which is connected to mic node. address-cells and
diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
index d474f59be6d6..a2ec4c1c9382 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
@@ -5,6 +5,7 @@ Required properties:
5 1) "samsung,exynos4210-hdmi" 5 1) "samsung,exynos4210-hdmi"
6 2) "samsung,exynos4212-hdmi" 6 2) "samsung,exynos4212-hdmi"
7 3) "samsung,exynos5420-hdmi" 7 3) "samsung,exynos5420-hdmi"
8 4) "samsung,exynos5433-hdmi"
8- reg: physical base address of the hdmi and length of memory mapped 9- reg: physical base address of the hdmi and length of memory mapped
9 region. 10 region.
10- interrupts: interrupt number to the cpu. 11- interrupts: interrupt number to the cpu.
@@ -12,6 +13,11 @@ Required properties:
12 a) phandle of the gpio controller node. 13 a) phandle of the gpio controller node.
13 b) pin number within the gpio controller. 14 b) pin number within the gpio controller.
14 c) optional flags and pull up/down. 15 c) optional flags and pull up/down.
16- ddc: phandle to the hdmi ddc node
17- phy: phandle to the hdmi phy node
18- samsung,syscon-phandle: phandle for system controller node for PMU.
19
20Required properties for Exynos 4210, 4212, 5420 and 5433:
15- clocks: list of clock IDs from SoC clock driver. 21- clocks: list of clock IDs from SoC clock driver.
16 a) hdmi: Gate of HDMI IP bus clock. 22 a) hdmi: Gate of HDMI IP bus clock.
17 b) sclk_hdmi: Gate of HDMI special clock. 23 b) sclk_hdmi: Gate of HDMI special clock.
@@ -25,9 +31,24 @@ Required properties:
25 sclk_pixel. 31 sclk_pixel.
26- clock-names: aliases as per driver requirements for above clock IDs: 32- clock-names: aliases as per driver requirements for above clock IDs:
27 "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi". 33 "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
28- ddc: phandle to the hdmi ddc node 34
29- phy: phandle to the hdmi phy node 35Required properties for Exynos 5433:
30- samsung,syscon-phandle: phandle for system controller node for PMU. 36- clocks: list of clock specifiers according to common clock bindings.
37 a) hdmi_pclk: Gate of HDMI IP APB bus.
38 b) hdmi_i_pclk: Gate of HDMI-PHY IP APB bus.
39 d) i_tmds_clk: Gate of HDMI TMDS clock.
40 e) i_pixel_clk: Gate of HDMI pixel clock.
41 f) i_spdif_clk: Gate of HDMI SPDIF clock.
42 g) oscclk: Oscillator clock, used as parent of following *_user clocks
43 in case HDMI-PHY is not operational.
44 h) tmds_clko: TMDS clock generated by HDMI-PHY.
45 i) tmds_clko_user: MUX used to switch between oscclk and tmds_clko,
46 respectively if HDMI-PHY is off and operational.
47 j) pixel_clko: Pixel clock generated by HDMI-PHY.
48 k) pixel_clko_user: MUX used to switch between oscclk and pixel_clko,
49 respectively if HDMI-PHY is off and operational.
50- clock-names: aliases for above clock specfiers.
51- samsung,sysreg: handle to syscon used to control the system registers.
31 52
32Example: 53Example:
33 54
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 2fadd8275fa5..d814b3048ee5 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -95,7 +95,7 @@ comment "Sub-drivers"
95 95
96config DRM_EXYNOS_G2D 96config DRM_EXYNOS_G2D
97 bool "G2D" 97 bool "G2D"
98 depends on !VIDEO_SAMSUNG_S5P_G2D 98 depends on VIDEO_SAMSUNG_S5P_G2D=n
99 select FRAME_VECTOR 99 select FRAME_VECTOR
100 help 100 help
101 Choose this option if you want to use Exynos G2D for DRM. 101 Choose this option if you want to use Exynos G2D for DRM.
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 126b0a1915db..f663490e949d 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -2,10 +2,10 @@
2# Makefile for the drm device driver. This driver provides support for the 2# Makefile for the drm device driver. This driver provides support for the
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4 4
5exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \ 5exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
6 exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \ 6 exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o
7 exynos_drm_plane.o
8 7
8exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
9exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o 9exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
10exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 10exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
11exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o 11exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 5245bc5e82e9..4ab5bfc23647 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -28,6 +28,10 @@
28#define WINDOWS_NR 3 28#define WINDOWS_NR 3
29#define MIN_FB_WIDTH_FOR_16WORD_BURST 128 29#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
30 30
31#define IFTYPE_I80 (1 << 0)
32#define I80_HW_TRG (1 << 1)
33#define IFTYPE_HDMI (1 << 2)
34
31static const char * const decon_clks_name[] = { 35static const char * const decon_clks_name[] = {
32 "pclk", 36 "pclk",
33 "aclk_decon", 37 "aclk_decon",
@@ -38,12 +42,6 @@ static const char * const decon_clks_name[] = {
38 "sclk_decon_eclk", 42 "sclk_decon_eclk",
39}; 43};
40 44
41enum decon_iftype {
42 IFTYPE_RGB,
43 IFTYPE_I80,
44 IFTYPE_HDMI
45};
46
47enum decon_flag_bits { 45enum decon_flag_bits {
48 BIT_CLKS_ENABLED, 46 BIT_CLKS_ENABLED,
49 BIT_IRQS_ENABLED, 47 BIT_IRQS_ENABLED,
@@ -61,7 +59,7 @@ struct decon_context {
61 struct clk *clks[ARRAY_SIZE(decon_clks_name)]; 59 struct clk *clks[ARRAY_SIZE(decon_clks_name)];
62 int pipe; 60 int pipe;
63 unsigned long flags; 61 unsigned long flags;
64 enum decon_iftype out_type; 62 unsigned long out_type;
65 int first_win; 63 int first_win;
66}; 64};
67 65
@@ -95,7 +93,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
95 93
96 if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) { 94 if (!test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
97 val = VIDINTCON0_INTEN; 95 val = VIDINTCON0_INTEN;
98 if (ctx->out_type == IFTYPE_I80) 96 if (ctx->out_type & IFTYPE_I80)
99 val |= VIDINTCON0_FRAMEDONE; 97 val |= VIDINTCON0_FRAMEDONE;
100 else 98 else
101 val |= VIDINTCON0_INTFRMEN; 99 val |= VIDINTCON0_INTFRMEN;
@@ -119,11 +117,11 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
119 117
120static void decon_setup_trigger(struct decon_context *ctx) 118static void decon_setup_trigger(struct decon_context *ctx)
121{ 119{
122 u32 val = (ctx->out_type != IFTYPE_HDMI) 120 u32 val = !(ctx->out_type & I80_HW_TRG)
123 ? TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | 121 ? TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
124 TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN 122 TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN
125 : TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | 123 : TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
126 TRIGCON_HWTRIGMASK_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB; 124 TRIGCON_HWTRIGMASK | TRIGCON_HWTRIGEN;
127 writel(val, ctx->addr + DECON_TRIGCON); 125 writel(val, ctx->addr + DECON_TRIGCON);
128} 126}
129 127
@@ -136,7 +134,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
136 if (test_bit(BIT_SUSPENDED, &ctx->flags)) 134 if (test_bit(BIT_SUSPENDED, &ctx->flags))
137 return; 135 return;
138 136
139 if (ctx->out_type == IFTYPE_HDMI) { 137 if (ctx->out_type & IFTYPE_HDMI) {
140 m->crtc_hsync_start = m->crtc_hdisplay + 10; 138 m->crtc_hsync_start = m->crtc_hdisplay + 10;
141 m->crtc_hsync_end = m->crtc_htotal - 92; 139 m->crtc_hsync_end = m->crtc_htotal - 92;
142 m->crtc_vsync_start = m->crtc_vdisplay + 1; 140 m->crtc_vsync_start = m->crtc_vdisplay + 1;
@@ -151,17 +149,20 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
151 149
152 /* lcd on and use command if */ 150 /* lcd on and use command if */
153 val = VIDOUT_LCD_ON; 151 val = VIDOUT_LCD_ON;
154 if (ctx->out_type == IFTYPE_I80) 152 if (ctx->out_type & IFTYPE_I80) {
155 val |= VIDOUT_COMMAND_IF; 153 val |= VIDOUT_COMMAND_IF;
156 else 154 decon_setup_trigger(ctx);
155 } else {
157 val |= VIDOUT_RGB_IF; 156 val |= VIDOUT_RGB_IF;
157 }
158
158 writel(val, ctx->addr + DECON_VIDOUTCON0); 159 writel(val, ctx->addr + DECON_VIDOUTCON0);
159 160
160 val = VIDTCON2_LINEVAL(m->vdisplay - 1) | 161 val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
161 VIDTCON2_HOZVAL(m->hdisplay - 1); 162 VIDTCON2_HOZVAL(m->hdisplay - 1);
162 writel(val, ctx->addr + DECON_VIDTCON2); 163 writel(val, ctx->addr + DECON_VIDTCON2);
163 164
164 if (ctx->out_type != IFTYPE_I80) { 165 if (!(ctx->out_type & IFTYPE_I80)) {
165 val = VIDTCON00_VBPD_F( 166 val = VIDTCON00_VBPD_F(
166 m->crtc_vtotal - m->crtc_vsync_end - 1) | 167 m->crtc_vtotal - m->crtc_vsync_end - 1) |
167 VIDTCON00_VFPD_F( 168 VIDTCON00_VFPD_F(
@@ -183,10 +184,10 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
183 writel(val, ctx->addr + DECON_VIDTCON11); 184 writel(val, ctx->addr + DECON_VIDTCON11);
184 } 185 }
185 186
186 decon_setup_trigger(ctx);
187
188 /* enable output and display signal */ 187 /* enable output and display signal */
189 decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0); 188 decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
189
190 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
190} 191}
191 192
192static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, 193static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
@@ -300,7 +301,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
300 val = dma_addr + pitch * state->src.h; 301 val = dma_addr + pitch * state->src.h;
301 writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); 302 writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
302 303
303 if (ctx->out_type != IFTYPE_HDMI) 304 if (!(ctx->out_type & IFTYPE_HDMI))
304 val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14) 305 val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
305 | BIT_VAL(state->crtc.w * bpp, 13, 0); 306 | BIT_VAL(state->crtc.w * bpp, 13, 0);
306 else 307 else
@@ -312,9 +313,6 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
312 313
313 /* window enable */ 314 /* window enable */
314 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0); 315 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
315
316 /* standalone update */
317 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
318} 316}
319 317
320static void decon_disable_plane(struct exynos_drm_crtc *crtc, 318static void decon_disable_plane(struct exynos_drm_crtc *crtc,
@@ -326,15 +324,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
326 if (test_bit(BIT_SUSPENDED, &ctx->flags)) 324 if (test_bit(BIT_SUSPENDED, &ctx->flags))
327 return; 325 return;
328 326
329 decon_shadow_protect_win(ctx, win, true);
330
331 /* window disable */
332 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); 327 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
333
334 decon_shadow_protect_win(ctx, win, false);
335
336 /* standalone update */
337 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
338} 328}
339 329
340static void decon_atomic_flush(struct exynos_drm_crtc *crtc) 330static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
@@ -348,7 +338,10 @@ static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
348 for (i = ctx->first_win; i < WINDOWS_NR; i++) 338 for (i = ctx->first_win; i < WINDOWS_NR; i++)
349 decon_shadow_protect_win(ctx, i, false); 339 decon_shadow_protect_win(ctx, i, false);
350 340
351 if (ctx->out_type == IFTYPE_I80) 341 /* standalone update */
342 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
343
344 if (ctx->out_type & IFTYPE_I80)
352 set_bit(BIT_WIN_UPDATED, &ctx->flags); 345 set_bit(BIT_WIN_UPDATED, &ctx->flags);
353} 346}
354 347
@@ -374,7 +367,7 @@ static void decon_swreset(struct decon_context *ctx)
374 367
375 WARN(tries == 0, "failed to software reset DECON\n"); 368 WARN(tries == 0, "failed to software reset DECON\n");
376 369
377 if (ctx->out_type != IFTYPE_HDMI) 370 if (!(ctx->out_type & IFTYPE_HDMI))
378 return; 371 return;
379 372
380 writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0); 373 writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0);
@@ -383,7 +376,9 @@ static void decon_swreset(struct decon_context *ctx)
383 writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1); 376 writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
384 writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN, 377 writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
385 ctx->addr + DECON_CRCCTRL); 378 ctx->addr + DECON_CRCCTRL);
386 decon_setup_trigger(ctx); 379
380 if (ctx->out_type & IFTYPE_I80)
381 decon_setup_trigger(ctx);
387} 382}
388 383
389static void decon_enable(struct exynos_drm_crtc *crtc) 384static void decon_enable(struct exynos_drm_crtc *crtc)
@@ -395,8 +390,12 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
395 390
396 pm_runtime_get_sync(ctx->dev); 391 pm_runtime_get_sync(ctx->dev);
397 392
393 exynos_drm_pipe_clk_enable(crtc, true);
394
398 set_bit(BIT_CLKS_ENABLED, &ctx->flags); 395 set_bit(BIT_CLKS_ENABLED, &ctx->flags);
399 396
397 decon_swreset(ctx);
398
400 /* if vblank was enabled status, enable it again. */ 399 /* if vblank was enabled status, enable it again. */
401 if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags)) 400 if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
402 decon_enable_vblank(ctx->crtc); 401 decon_enable_vblank(ctx->crtc);
@@ -424,6 +423,8 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
424 423
425 clear_bit(BIT_CLKS_ENABLED, &ctx->flags); 424 clear_bit(BIT_CLKS_ENABLED, &ctx->flags);
426 425
426 exynos_drm_pipe_clk_enable(crtc, false);
427
427 pm_runtime_put_sync(ctx->dev); 428 pm_runtime_put_sync(ctx->dev);
428 429
429 set_bit(BIT_SUSPENDED, &ctx->flags); 430 set_bit(BIT_SUSPENDED, &ctx->flags);
@@ -459,8 +460,10 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
459 decon_shadow_protect_win(ctx, win, true); 460 decon_shadow_protect_win(ctx, win, true);
460 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0); 461 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
461 decon_shadow_protect_win(ctx, win, false); 462 decon_shadow_protect_win(ctx, win, false);
462 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
463 } 463 }
464
465 decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
466
464 /* TODO: wait for possible vsync */ 467 /* TODO: wait for possible vsync */
465 msleep(50); 468 msleep(50);
466 469
@@ -509,7 +512,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
509 } 512 }
510 513
511 exynos_plane = &ctx->planes[ctx->first_win]; 514 exynos_plane = &ctx->planes[ctx->first_win];
512 out_type = (ctx->out_type == IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI 515 out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
513 : EXYNOS_DISPLAY_TYPE_LCD; 516 : EXYNOS_DISPLAY_TYPE_LCD;
514 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, 517 ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
515 ctx->pipe, out_type, 518 ctx->pipe, out_type,
@@ -617,11 +620,11 @@ static const struct dev_pm_ops exynos5433_decon_pm_ops = {
617static const struct of_device_id exynos5433_decon_driver_dt_match[] = { 620static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
618 { 621 {
619 .compatible = "samsung,exynos5433-decon", 622 .compatible = "samsung,exynos5433-decon",
620 .data = (void *)IFTYPE_RGB 623 .data = (void *)I80_HW_TRG
621 }, 624 },
622 { 625 {
623 .compatible = "samsung,exynos5433-decon-tv", 626 .compatible = "samsung,exynos5433-decon-tv",
624 .data = (void *)IFTYPE_HDMI 627 .data = (void *)(I80_HW_TRG | IFTYPE_HDMI)
625 }, 628 },
626 {}, 629 {},
627}; 630};
@@ -629,7 +632,6 @@ MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
629 632
630static int exynos5433_decon_probe(struct platform_device *pdev) 633static int exynos5433_decon_probe(struct platform_device *pdev)
631{ 634{
632 const struct of_device_id *of_id;
633 struct device *dev = &pdev->dev; 635 struct device *dev = &pdev->dev;
634 struct decon_context *ctx; 636 struct decon_context *ctx;
635 struct resource *res; 637 struct resource *res;
@@ -642,14 +644,14 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
642 644
643 __set_bit(BIT_SUSPENDED, &ctx->flags); 645 __set_bit(BIT_SUSPENDED, &ctx->flags);
644 ctx->dev = dev; 646 ctx->dev = dev;
647 ctx->out_type = (unsigned long)of_device_get_match_data(dev);
645 648
646 of_id = of_match_device(exynos5433_decon_driver_dt_match, &pdev->dev); 649 if (ctx->out_type & IFTYPE_HDMI) {
647 ctx->out_type = (enum decon_iftype)of_id->data;
648
649 if (ctx->out_type == IFTYPE_HDMI)
650 ctx->first_win = 1; 650 ctx->first_win = 1;
651 else if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
652 ctx->out_type = IFTYPE_I80; 651 ctx->out_type = IFTYPE_I80;
652 } else if (of_get_child_by_name(dev->of_node, "i80-if-timings")) {
653 ctx->out_type = IFTYPE_I80;
654 }
653 655
654 for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 656 for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
655 struct clk *clk; 657 struct clk *clk;
@@ -674,7 +676,7 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
674 } 676 }
675 677
676 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 678 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
677 (ctx->out_type == IFTYPE_I80) ? "lcd_sys" : "vsync"); 679 (ctx->out_type & IFTYPE_I80) ? "lcd_sys" : "vsync");
678 if (!res) { 680 if (!res) {
679 dev_err(dev, "cannot find IRQ resource\n"); 681 dev_err(dev, "cannot find IRQ resource\n");
680 return -ENXIO; 682 return -ENXIO;
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 93361073af9a..f6223f907c15 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -593,7 +593,6 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
593 .commit = decon_commit, 593 .commit = decon_commit,
594 .enable_vblank = decon_enable_vblank, 594 .enable_vblank = decon_enable_vblank,
595 .disable_vblank = decon_disable_vblank, 595 .disable_vblank = decon_disable_vblank,
596 .wait_for_vblank = decon_wait_for_vblank,
597 .atomic_begin = decon_atomic_begin, 596 .atomic_begin = decon_atomic_begin,
598 .update_plane = decon_update_plane, 597 .update_plane = decon_update_plane,
599 .disable_plane = decon_disable_plane, 598 .disable_plane = decon_disable_plane,
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 8ae3d51b5b33..468498e3fec1 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -48,14 +48,11 @@ int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
48{ 48{
49 struct exynos_dp_device *dp = to_dp(plat_data); 49 struct exynos_dp_device *dp = to_dp(plat_data);
50 struct drm_encoder *encoder = &dp->encoder; 50 struct drm_encoder *encoder = &dp->encoder;
51 struct exynos_drm_crtc *crtc;
52 51
53 if (!encoder) 52 if (!encoder->crtc)
54 return -1; 53 return -EPERM;
55 54
56 crtc = to_exynos_crtc(encoder->crtc); 55 exynos_drm_pipe_clk_enable(to_exynos_crtc(encoder->crtc), enable);
57 if (crtc && crtc->ops && crtc->ops->clock_enable)
58 crtc->ops->clock_enable(crtc, enable);
59 56
60 return 0; 57 return 0;
61} 58}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 7f55ba6771c6..011211e4167d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -101,7 +101,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
101 return 0; 101 return 0;
102 102
103err: 103err:
104 list_for_each_entry_reverse(subdrv, &subdrv->list, list) { 104 list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) {
105 if (subdrv->close) 105 if (subdrv->close)
106 subdrv->close(dev, subdrv->dev, file); 106 subdrv->close(dev, subdrv->dev, file);
107 } 107 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index e36579c1c025..50dd33d5045d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -157,9 +157,8 @@ err_crtc:
157 157
158int exynos_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe) 158int exynos_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe)
159{ 159{
160 struct exynos_drm_private *private = dev->dev_private; 160 struct exynos_drm_crtc *exynos_crtc = exynos_drm_crtc_from_pipe(dev,
161 struct exynos_drm_crtc *exynos_crtc = 161 pipe);
162 to_exynos_crtc(private->crtc[pipe]);
163 162
164 if (exynos_crtc->ops->enable_vblank) 163 if (exynos_crtc->ops->enable_vblank)
165 return exynos_crtc->ops->enable_vblank(exynos_crtc); 164 return exynos_crtc->ops->enable_vblank(exynos_crtc);
@@ -169,9 +168,8 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe)
169 168
170void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe) 169void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe)
171{ 170{
172 struct exynos_drm_private *private = dev->dev_private; 171 struct exynos_drm_crtc *exynos_crtc = exynos_drm_crtc_from_pipe(dev,
173 struct exynos_drm_crtc *exynos_crtc = 172 pipe);
174 to_exynos_crtc(private->crtc[pipe]);
175 173
176 if (exynos_crtc->ops->disable_vblank) 174 if (exynos_crtc->ops->disable_vblank)
177 exynos_crtc->ops->disable_vblank(exynos_crtc); 175 exynos_crtc->ops->disable_vblank(exynos_crtc);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 502f750bad2a..2ca719cc3e2a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -120,8 +120,6 @@ struct exynos_drm_plane_config {
120 * @commit: set current hw specific display mode to hw. 120 * @commit: set current hw specific display mode to hw.
121 * @enable_vblank: specific driver callback for enabling vblank interrupt. 121 * @enable_vblank: specific driver callback for enabling vblank interrupt.
122 * @disable_vblank: specific driver callback for disabling vblank interrupt. 122 * @disable_vblank: specific driver callback for disabling vblank interrupt.
123 * @wait_for_vblank: wait for vblank interrupt to make sure that
124 * hardware overlay is updated.
125 * @atomic_check: validate state 123 * @atomic_check: validate state
126 * @atomic_begin: prepare device to receive an update 124 * @atomic_begin: prepare device to receive an update
127 * @atomic_flush: mark the end of device update 125 * @atomic_flush: mark the end of device update
@@ -129,10 +127,6 @@ struct exynos_drm_plane_config {
129 * @disable_plane: disable hardware specific overlay. 127 * @disable_plane: disable hardware specific overlay.
130 * @te_handler: trigger to transfer video image at the tearing effect 128 * @te_handler: trigger to transfer video image at the tearing effect
131 * synchronization signal if there is a page flip request. 129 * synchronization signal if there is a page flip request.
132 * @clock_enable: optional function enabling/disabling display domain clock,
133 * called from exynos-dp driver before powering up (with
134 * 'enable' argument as true) and after powering down (with
135 * 'enable' as false).
136 */ 130 */
137struct exynos_drm_crtc; 131struct exynos_drm_crtc;
138struct exynos_drm_crtc_ops { 132struct exynos_drm_crtc_ops {
@@ -141,7 +135,6 @@ struct exynos_drm_crtc_ops {
141 void (*commit)(struct exynos_drm_crtc *crtc); 135 void (*commit)(struct exynos_drm_crtc *crtc);
142 int (*enable_vblank)(struct exynos_drm_crtc *crtc); 136 int (*enable_vblank)(struct exynos_drm_crtc *crtc);
143 void (*disable_vblank)(struct exynos_drm_crtc *crtc); 137 void (*disable_vblank)(struct exynos_drm_crtc *crtc);
144 void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
145 int (*atomic_check)(struct exynos_drm_crtc *crtc, 138 int (*atomic_check)(struct exynos_drm_crtc *crtc,
146 struct drm_crtc_state *state); 139 struct drm_crtc_state *state);
147 void (*atomic_begin)(struct exynos_drm_crtc *crtc); 140 void (*atomic_begin)(struct exynos_drm_crtc *crtc);
@@ -151,7 +144,10 @@ struct exynos_drm_crtc_ops {
151 struct exynos_drm_plane *plane); 144 struct exynos_drm_plane *plane);
152 void (*atomic_flush)(struct exynos_drm_crtc *crtc); 145 void (*atomic_flush)(struct exynos_drm_crtc *crtc);
153 void (*te_handler)(struct exynos_drm_crtc *crtc); 146 void (*te_handler)(struct exynos_drm_crtc *crtc);
154 void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); 147};
148
149struct exynos_drm_clk {
150 void (*enable)(struct exynos_drm_clk *clk, bool enable);
155}; 151};
156 152
157/* 153/*
@@ -182,8 +178,16 @@ struct exynos_drm_crtc {
182 atomic_t pending_update; 178 atomic_t pending_update;
183 const struct exynos_drm_crtc_ops *ops; 179 const struct exynos_drm_crtc_ops *ops;
184 void *ctx; 180 void *ctx;
181 struct exynos_drm_clk *pipe_clk;
185}; 182};
186 183
184static inline void exynos_drm_pipe_clk_enable(struct exynos_drm_crtc *crtc,
185 bool enable)
186{
187 if (crtc->pipe_clk)
188 crtc->pipe_clk->enable(crtc->pipe_clk, enable);
189}
190
187struct exynos_drm_g2d_private { 191struct exynos_drm_g2d_private {
188 struct device *dev; 192 struct device *dev;
189 struct list_head inuse_cmdlist; 193 struct list_head inuse_cmdlist;
@@ -232,6 +236,14 @@ struct exynos_drm_private {
232 wait_queue_head_t wait; 236 wait_queue_head_t wait;
233}; 237};
234 238
239static inline struct exynos_drm_crtc *
240exynos_drm_crtc_from_pipe(struct drm_device *dev, int pipe)
241{
242 struct exynos_drm_private *private = dev->dev_private;
243
244 return to_exynos_crtc(private->crtc[pipe]);
245}
246
235static inline struct device *to_dma_dev(struct drm_device *dev) 247static inline struct device *to_dma_dev(struct drm_device *dev)
236{ 248{
237 struct exynos_drm_private *priv = dev->dev_private; 249 struct exynos_drm_private *priv = dev->dev_private;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 63c84a106c0b..72c3565d22ee 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -280,7 +280,7 @@ struct exynos_dsi {
280 spinlock_t transfer_lock; /* protects transfer_list */ 280 spinlock_t transfer_lock; /* protects transfer_list */
281 struct list_head transfer_list; 281 struct list_head transfer_list;
282 282
283 struct exynos_dsi_driver_data *driver_data; 283 const struct exynos_dsi_driver_data *driver_data;
284 struct device_node *bridge_node; 284 struct device_node *bridge_node;
285}; 285};
286 286
@@ -532,15 +532,6 @@ static const struct of_device_id exynos_dsi_of_match[] = {
532 { } 532 { }
533}; 533};
534 534
535static inline struct exynos_dsi_driver_data *exynos_dsi_get_driver_data(
536 struct platform_device *pdev)
537{
538 const struct of_device_id *of_id =
539 of_match_device(exynos_dsi_of_match, &pdev->dev);
540
541 return (struct exynos_dsi_driver_data *)of_id->data;
542}
543
544static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi) 535static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
545{ 536{
546 if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300))) 537 if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))
@@ -564,7 +555,7 @@ static void exynos_dsi_reset(struct exynos_dsi *dsi)
564static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi, 555static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
565 unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s) 556 unsigned long fin, unsigned long fout, u8 *p, u16 *m, u8 *s)
566{ 557{
567 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 558 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
568 unsigned long best_freq = 0; 559 unsigned long best_freq = 0;
569 u32 min_delta = 0xffffffff; 560 u32 min_delta = 0xffffffff;
570 u8 p_min, p_max; 561 u8 p_min, p_max;
@@ -618,7 +609,7 @@ static unsigned long exynos_dsi_pll_find_pms(struct exynos_dsi *dsi,
618static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi, 609static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
619 unsigned long freq) 610 unsigned long freq)
620{ 611{
621 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 612 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
622 unsigned long fin, fout; 613 unsigned long fin, fout;
623 int timeout; 614 int timeout;
624 u8 p, s; 615 u8 p, s;
@@ -712,7 +703,7 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
712 703
713static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi) 704static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
714{ 705{
715 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 706 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
716 const unsigned int *reg_values = driver_data->reg_values; 707 const unsigned int *reg_values = driver_data->reg_values;
717 u32 reg; 708 u32 reg;
718 709
@@ -790,7 +781,7 @@ static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
790 781
791static int exynos_dsi_init_link(struct exynos_dsi *dsi) 782static int exynos_dsi_init_link(struct exynos_dsi *dsi)
792{ 783{
793 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 784 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
794 int timeout; 785 int timeout;
795 u32 reg; 786 u32 reg;
796 u32 lanes_mask; 787 u32 lanes_mask;
@@ -1334,7 +1325,7 @@ static void exynos_dsi_disable_irq(struct exynos_dsi *dsi)
1334 1325
1335static int exynos_dsi_init(struct exynos_dsi *dsi) 1326static int exynos_dsi_init(struct exynos_dsi *dsi)
1336{ 1327{
1337 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1328 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
1338 1329
1339 exynos_dsi_reset(dsi); 1330 exynos_dsi_reset(dsi);
1340 exynos_dsi_enable_irq(dsi); 1331 exynos_dsi_enable_irq(dsi);
@@ -1833,7 +1824,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1833 dsi->dsi_host.dev = dev; 1824 dsi->dsi_host.dev = dev;
1834 1825
1835 dsi->dev = dev; 1826 dsi->dev = dev;
1836 dsi->driver_data = exynos_dsi_get_driver_data(pdev); 1827 dsi->driver_data = of_device_get_match_data(dev);
1837 1828
1838 ret = exynos_dsi_parse_dt(dsi); 1829 ret = exynos_dsi_parse_dt(dsi);
1839 if (ret) 1830 if (ret)
@@ -1917,7 +1908,7 @@ static int __maybe_unused exynos_dsi_suspend(struct device *dev)
1917{ 1908{
1918 struct drm_encoder *encoder = dev_get_drvdata(dev); 1909 struct drm_encoder *encoder = dev_get_drvdata(dev);
1919 struct exynos_dsi *dsi = encoder_to_dsi(encoder); 1910 struct exynos_dsi *dsi = encoder_to_dsi(encoder);
1920 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1911 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
1921 int ret, i; 1912 int ret, i;
1922 1913
1923 usleep_range(10000, 20000); 1914 usleep_range(10000, 20000);
@@ -1948,7 +1939,7 @@ static int __maybe_unused exynos_dsi_resume(struct device *dev)
1948{ 1939{
1949 struct drm_encoder *encoder = dev_get_drvdata(dev); 1940 struct drm_encoder *encoder = dev_get_drvdata(dev);
1950 struct exynos_dsi *dsi = encoder_to_dsi(encoder); 1941 struct exynos_dsi *dsi = encoder_to_dsi(encoder);
1951 struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1942 const struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
1952 int ret, i; 1943 int ret, i;
1953 1944
1954 ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1945 ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index d614194644c8..81cc5537cf25 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -199,17 +199,6 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
199 return exynos_fb->dma_addr[index]; 199 return exynos_fb->dma_addr[index];
200} 200}
201 201
202static void exynos_drm_output_poll_changed(struct drm_device *dev)
203{
204 struct exynos_drm_private *private = dev->dev_private;
205 struct drm_fb_helper *fb_helper = private->fb_helper;
206
207 if (fb_helper)
208 drm_fb_helper_hotplug_event(fb_helper);
209 else
210 exynos_drm_fbdev_init(dev);
211}
212
213static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { 202static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
214 .fb_create = exynos_user_fb_create, 203 .fb_create = exynos_user_fb_create,
215 .output_poll_changed = exynos_drm_output_poll_changed, 204 .output_poll_changed = exynos_drm_output_poll_changed,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 4656cd6e7083..67dcd6831291 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -311,3 +311,14 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
311 311
312 drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper); 312 drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper);
313} 313}
314
315void exynos_drm_output_poll_changed(struct drm_device *dev)
316{
317 struct exynos_drm_private *private = dev->dev_private;
318 struct drm_fb_helper *fb_helper = private->fb_helper;
319
320 if (fb_helper)
321 drm_fb_helper_hotplug_event(fb_helper);
322 else
323 exynos_drm_fbdev_init(dev);
324}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h
index e16d7f0ae192..330eef87f718 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.h
@@ -15,9 +15,30 @@
15#ifndef _EXYNOS_DRM_FBDEV_H_ 15#ifndef _EXYNOS_DRM_FBDEV_H_
16#define _EXYNOS_DRM_FBDEV_H_ 16#define _EXYNOS_DRM_FBDEV_H_
17 17
18#ifdef CONFIG_DRM_FBDEV_EMULATION
19
18int exynos_drm_fbdev_init(struct drm_device *dev); 20int exynos_drm_fbdev_init(struct drm_device *dev);
19int exynos_drm_fbdev_reinit(struct drm_device *dev);
20void exynos_drm_fbdev_fini(struct drm_device *dev); 21void exynos_drm_fbdev_fini(struct drm_device *dev);
21void exynos_drm_fbdev_restore_mode(struct drm_device *dev); 22void exynos_drm_fbdev_restore_mode(struct drm_device *dev);
23void exynos_drm_output_poll_changed(struct drm_device *dev);
24
25#else
26
27static inline int exynos_drm_fbdev_init(struct drm_device *dev)
28{
29 return 0;
30}
31
32static inline void exynos_drm_fbdev_fini(struct drm_device *dev)
33{
34}
35
36static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
37{
38}
39
40#define exynos_drm_output_poll_changed (NULL)
41
42#endif
22 43
23#endif 44#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 51d484ae9f49..547d759a0a6f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -68,10 +68,15 @@
68/* color key value register for hardware window 1 ~ 4. */ 68/* color key value register for hardware window 1 ~ 4. */
69#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8)) 69#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8))
70 70
71/* I80 / RGB trigger control register */ 71/* I80 trigger control register */
72#define TRIGCON 0x1A4 72#define TRIGCON 0x1A4
73#define TRGMODE_I80_RGB_ENABLE_I80 (1 << 0) 73#define TRGMODE_ENABLE (1 << 0)
74#define SWTRGCMD_I80_RGB_ENABLE (1 << 1) 74#define SWTRGCMD_ENABLE (1 << 1)
75/* Exynos3250, 3472, 4415, 5260 5410, 5420 and 5422 only supported. */
76#define HWTRGEN_ENABLE (1 << 3)
77#define HWTRGMASK_ENABLE (1 << 4)
78/* Exynos3250, 3472, 4415, 5260, 5420 and 5422 only supported. */
79#define HWTRIGEN_PER_ENABLE (1 << 31)
75 80
76/* display mode change control register except exynos4 */ 81/* display mode change control register except exynos4 */
77#define VIDOUT_CON 0x000 82#define VIDOUT_CON 0x000
@@ -89,12 +94,16 @@
89/* FIMD has totally five hardware windows. */ 94/* FIMD has totally five hardware windows. */
90#define WINDOWS_NR 5 95#define WINDOWS_NR 5
91 96
97/* HW trigger flag on i80 panel. */
98#define I80_HW_TRG (1 << 1)
99
92struct fimd_driver_data { 100struct fimd_driver_data {
93 unsigned int timing_base; 101 unsigned int timing_base;
94 unsigned int lcdblk_offset; 102 unsigned int lcdblk_offset;
95 unsigned int lcdblk_vt_shift; 103 unsigned int lcdblk_vt_shift;
96 unsigned int lcdblk_bypass_shift; 104 unsigned int lcdblk_bypass_shift;
97 unsigned int lcdblk_mic_bypass_shift; 105 unsigned int lcdblk_mic_bypass_shift;
106 unsigned int trg_type;
98 107
99 unsigned int has_shadowcon:1; 108 unsigned int has_shadowcon:1;
100 unsigned int has_clksel:1; 109 unsigned int has_clksel:1;
@@ -102,20 +111,26 @@ struct fimd_driver_data {
102 unsigned int has_vidoutcon:1; 111 unsigned int has_vidoutcon:1;
103 unsigned int has_vtsel:1; 112 unsigned int has_vtsel:1;
104 unsigned int has_mic_bypass:1; 113 unsigned int has_mic_bypass:1;
114 unsigned int has_dp_clk:1;
115 unsigned int has_hw_trigger:1;
116 unsigned int has_trigger_per_te:1;
105}; 117};
106 118
107static struct fimd_driver_data s3c64xx_fimd_driver_data = { 119static struct fimd_driver_data s3c64xx_fimd_driver_data = {
108 .timing_base = 0x0, 120 .timing_base = 0x0,
109 .has_clksel = 1, 121 .has_clksel = 1,
110 .has_limited_fmt = 1, 122 .has_limited_fmt = 1,
123 .has_hw_trigger = 1,
111}; 124};
112 125
113static struct fimd_driver_data exynos3_fimd_driver_data = { 126static struct fimd_driver_data exynos3_fimd_driver_data = {
114 .timing_base = 0x20000, 127 .timing_base = 0x20000,
115 .lcdblk_offset = 0x210, 128 .lcdblk_offset = 0x210,
116 .lcdblk_bypass_shift = 1, 129 .lcdblk_bypass_shift = 1,
130 .trg_type = I80_HW_TRG,
117 .has_shadowcon = 1, 131 .has_shadowcon = 1,
118 .has_vidoutcon = 1, 132 .has_vidoutcon = 1,
133 .has_trigger_per_te = 1,
119}; 134};
120 135
121static struct fimd_driver_data exynos4_fimd_driver_data = { 136static struct fimd_driver_data exynos4_fimd_driver_data = {
@@ -132,9 +147,11 @@ static struct fimd_driver_data exynos4415_fimd_driver_data = {
132 .lcdblk_offset = 0x210, 147 .lcdblk_offset = 0x210,
133 .lcdblk_vt_shift = 10, 148 .lcdblk_vt_shift = 10,
134 .lcdblk_bypass_shift = 1, 149 .lcdblk_bypass_shift = 1,
150 .trg_type = I80_HW_TRG,
135 .has_shadowcon = 1, 151 .has_shadowcon = 1,
136 .has_vidoutcon = 1, 152 .has_vidoutcon = 1,
137 .has_vtsel = 1, 153 .has_vtsel = 1,
154 .has_trigger_per_te = 1,
138}; 155};
139 156
140static struct fimd_driver_data exynos5_fimd_driver_data = { 157static struct fimd_driver_data exynos5_fimd_driver_data = {
@@ -145,6 +162,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = {
145 .has_shadowcon = 1, 162 .has_shadowcon = 1,
146 .has_vidoutcon = 1, 163 .has_vidoutcon = 1,
147 .has_vtsel = 1, 164 .has_vtsel = 1,
165 .has_dp_clk = 1,
148}; 166};
149 167
150static struct fimd_driver_data exynos5420_fimd_driver_data = { 168static struct fimd_driver_data exynos5420_fimd_driver_data = {
@@ -153,10 +171,14 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = {
153 .lcdblk_vt_shift = 24, 171 .lcdblk_vt_shift = 24,
154 .lcdblk_bypass_shift = 15, 172 .lcdblk_bypass_shift = 15,
155 .lcdblk_mic_bypass_shift = 11, 173 .lcdblk_mic_bypass_shift = 11,
174 .trg_type = I80_HW_TRG,
156 .has_shadowcon = 1, 175 .has_shadowcon = 1,
157 .has_vidoutcon = 1, 176 .has_vidoutcon = 1,
158 .has_vtsel = 1, 177 .has_vtsel = 1,
159 .has_mic_bypass = 1, 178 .has_mic_bypass = 1,
179 .has_dp_clk = 1,
180 .has_hw_trigger = 1,
181 .has_trigger_per_te = 1,
160}; 182};
161 183
162struct fimd_context { 184struct fimd_context {
@@ -182,8 +204,9 @@ struct fimd_context {
182 atomic_t win_updated; 204 atomic_t win_updated;
183 atomic_t triggering; 205 atomic_t triggering;
184 206
185 struct fimd_driver_data *driver_data; 207 const struct fimd_driver_data *driver_data;
186 struct drm_encoder *encoder; 208 struct drm_encoder *encoder;
209 struct exynos_drm_clk dp_clk;
187}; 210};
188 211
189static const struct of_device_id fimd_driver_dt_match[] = { 212static const struct of_device_id fimd_driver_dt_match[] = {
@@ -219,15 +242,6 @@ static const uint32_t fimd_formats[] = {
219 DRM_FORMAT_ARGB8888, 242 DRM_FORMAT_ARGB8888,
220}; 243};
221 244
222static inline struct fimd_driver_data *drm_fimd_get_driver_data(
223 struct platform_device *pdev)
224{
225 const struct of_device_id *of_id =
226 of_match_device(fimd_driver_dt_match, &pdev->dev);
227
228 return (struct fimd_driver_data *)of_id->data;
229}
230
231static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) 245static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
232{ 246{
233 struct fimd_context *ctx = crtc->ctx; 247 struct fimd_context *ctx = crtc->ctx;
@@ -400,11 +414,31 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
400 return (clkdiv < 0x100) ? clkdiv : 0xff; 414 return (clkdiv < 0x100) ? clkdiv : 0xff;
401} 415}
402 416
417static void fimd_setup_trigger(struct fimd_context *ctx)
418{
419 void __iomem *timing_base = ctx->regs + ctx->driver_data->timing_base;
420 u32 trg_type = ctx->driver_data->trg_type;
421 u32 val = readl(timing_base + TRIGCON);
422
423 val &= ~(TRGMODE_ENABLE);
424
425 if (trg_type == I80_HW_TRG) {
426 if (ctx->driver_data->has_hw_trigger)
427 val |= HWTRGEN_ENABLE | HWTRGMASK_ENABLE;
428 if (ctx->driver_data->has_trigger_per_te)
429 val |= HWTRIGEN_PER_ENABLE;
430 } else {
431 val |= TRGMODE_ENABLE;
432 }
433
434 writel(val, timing_base + TRIGCON);
435}
436
403static void fimd_commit(struct exynos_drm_crtc *crtc) 437static void fimd_commit(struct exynos_drm_crtc *crtc)
404{ 438{
405 struct fimd_context *ctx = crtc->ctx; 439 struct fimd_context *ctx = crtc->ctx;
406 struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; 440 struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
407 struct fimd_driver_data *driver_data = ctx->driver_data; 441 const struct fimd_driver_data *driver_data = ctx->driver_data;
408 void *timing_base = ctx->regs + driver_data->timing_base; 442 void *timing_base = ctx->regs + driver_data->timing_base;
409 u32 val, clkdiv; 443 u32 val, clkdiv;
410 444
@@ -495,6 +529,8 @@ static void fimd_commit(struct exynos_drm_crtc *crtc)
495 VIDTCON2_HOZVAL_E(mode->hdisplay - 1); 529 VIDTCON2_HOZVAL_E(mode->hdisplay - 1);
496 writel(val, ctx->regs + driver_data->timing_base + VIDTCON2); 530 writel(val, ctx->regs + driver_data->timing_base + VIDTCON2);
497 531
532 fimd_setup_trigger(ctx);
533
498 /* 534 /*
499 * fields of register with prefix '_F' would be updated 535 * fields of register with prefix '_F' would be updated
500 * at vsync(same as dma start) 536 * at vsync(same as dma start)
@@ -827,7 +863,7 @@ static void fimd_disable(struct exynos_drm_crtc *crtc)
827static void fimd_trigger(struct device *dev) 863static void fimd_trigger(struct device *dev)
828{ 864{
829 struct fimd_context *ctx = dev_get_drvdata(dev); 865 struct fimd_context *ctx = dev_get_drvdata(dev);
830 struct fimd_driver_data *driver_data = ctx->driver_data; 866 const struct fimd_driver_data *driver_data = ctx->driver_data;
831 void *timing_base = ctx->regs + driver_data->timing_base; 867 void *timing_base = ctx->regs + driver_data->timing_base;
832 u32 reg; 868 u32 reg;
833 869
@@ -842,7 +878,7 @@ static void fimd_trigger(struct device *dev)
842 atomic_set(&ctx->triggering, 1); 878 atomic_set(&ctx->triggering, 1);
843 879
844 reg = readl(timing_base + TRIGCON); 880 reg = readl(timing_base + TRIGCON);
845 reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE); 881 reg |= (TRGMODE_ENABLE | SWTRGCMD_ENABLE);
846 writel(reg, timing_base + TRIGCON); 882 writel(reg, timing_base + TRIGCON);
847 883
848 /* 884 /*
@@ -856,11 +892,15 @@ static void fimd_trigger(struct device *dev)
856static void fimd_te_handler(struct exynos_drm_crtc *crtc) 892static void fimd_te_handler(struct exynos_drm_crtc *crtc)
857{ 893{
858 struct fimd_context *ctx = crtc->ctx; 894 struct fimd_context *ctx = crtc->ctx;
895 u32 trg_type = ctx->driver_data->trg_type;
859 896
860 /* Checks the crtc is detached already from encoder */ 897 /* Checks the crtc is detached already from encoder */
861 if (ctx->pipe < 0 || !ctx->drm_dev) 898 if (ctx->pipe < 0 || !ctx->drm_dev)
862 return; 899 return;
863 900
901 if (trg_type == I80_HW_TRG)
902 goto out;
903
864 /* 904 /*
865 * If there is a page flip request, triggers and handles the page flip 905 * If there is a page flip request, triggers and handles the page flip
866 * event so that current fb can be updated into panel GRAM. 906 * event so that current fb can be updated into panel GRAM.
@@ -868,6 +908,7 @@ static void fimd_te_handler(struct exynos_drm_crtc *crtc)
868 if (atomic_add_unless(&ctx->win_updated, -1, 0)) 908 if (atomic_add_unless(&ctx->win_updated, -1, 0))
869 fimd_trigger(ctx->dev); 909 fimd_trigger(ctx->dev);
870 910
911out:
871 /* Wakes up vsync event queue */ 912 /* Wakes up vsync event queue */
872 if (atomic_read(&ctx->wait_vsync_event)) { 913 if (atomic_read(&ctx->wait_vsync_event)) {
873 atomic_set(&ctx->wait_vsync_event, 0); 914 atomic_set(&ctx->wait_vsync_event, 0);
@@ -878,21 +919,12 @@ static void fimd_te_handler(struct exynos_drm_crtc *crtc)
878 drm_crtc_handle_vblank(&ctx->crtc->base); 919 drm_crtc_handle_vblank(&ctx->crtc->base);
879} 920}
880 921
881static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) 922static void fimd_dp_clock_enable(struct exynos_drm_clk *clk, bool enable)
882{ 923{
883 struct fimd_context *ctx = crtc->ctx; 924 struct fimd_context *ctx = container_of(clk, struct fimd_context,
884 u32 val; 925 dp_clk);
926 u32 val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
885 927
886 /*
887 * Only Exynos 5250, 5260, 5410 and 542x requires enabling DP/MIE
888 * clock. On these SoCs the bootloader may enable it but any
889 * power domain off/on will reset it to disable state.
890 */
891 if (ctx->driver_data != &exynos5_fimd_driver_data ||
892 ctx->driver_data != &exynos5420_fimd_driver_data)
893 return;
894
895 val = enable ? DP_MIE_CLK_DP_ENABLE : DP_MIE_CLK_DISABLE;
896 writel(val, ctx->regs + DP_MIE_CLKCON); 928 writel(val, ctx->regs + DP_MIE_CLKCON);
897} 929}
898 930
@@ -902,13 +934,11 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
902 .commit = fimd_commit, 934 .commit = fimd_commit,
903 .enable_vblank = fimd_enable_vblank, 935 .enable_vblank = fimd_enable_vblank,
904 .disable_vblank = fimd_disable_vblank, 936 .disable_vblank = fimd_disable_vblank,
905 .wait_for_vblank = fimd_wait_for_vblank,
906 .atomic_begin = fimd_atomic_begin, 937 .atomic_begin = fimd_atomic_begin,
907 .update_plane = fimd_update_plane, 938 .update_plane = fimd_update_plane,
908 .disable_plane = fimd_disable_plane, 939 .disable_plane = fimd_disable_plane,
909 .atomic_flush = fimd_atomic_flush, 940 .atomic_flush = fimd_atomic_flush,
910 .te_handler = fimd_te_handler, 941 .te_handler = fimd_te_handler,
911 .clock_enable = fimd_dp_clock_enable,
912}; 942};
913 943
914static irqreturn_t fimd_irq_handler(int irq, void *dev_id) 944static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
@@ -987,6 +1017,11 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
987 if (IS_ERR(ctx->crtc)) 1017 if (IS_ERR(ctx->crtc))
988 return PTR_ERR(ctx->crtc); 1018 return PTR_ERR(ctx->crtc);
989 1019
1020 if (ctx->driver_data->has_dp_clk) {
1021 ctx->dp_clk.enable = fimd_dp_clock_enable;
1022 ctx->crtc->pipe_clk = &ctx->dp_clk;
1023 }
1024
990 if (ctx->encoder) 1025 if (ctx->encoder)
991 exynos_dpi_bind(drm_dev, ctx->encoder); 1026 exynos_dpi_bind(drm_dev, ctx->encoder);
992 1027
@@ -1035,7 +1070,7 @@ static int fimd_probe(struct platform_device *pdev)
1035 1070
1036 ctx->dev = dev; 1071 ctx->dev = dev;
1037 ctx->suspended = true; 1072 ctx->suspended = true;
1038 ctx->driver_data = drm_fimd_get_driver_data(pdev); 1073 ctx->driver_data = of_device_get_match_data(dev);
1039 1074
1040 if (of_property_read_bool(dev->of_node, "samsung,invert-vden")) 1075 if (of_property_read_bool(dev->of_node, "samsung,invert-vden"))
1041 ctx->vidcon1 |= VIDCON1_INV_VDEN; 1076 ctx->vidcon1 |= VIDCON1_INV_VDEN;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 9869d70e9e54..a0def0be6d65 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -129,7 +129,7 @@ static void mic_set_path(struct exynos_mic *mic, bool enable)
129 } else 129 } else
130 val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); 130 val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX);
131 131
132 regmap_write(mic->sysreg, DSD_CFG_MUX, val); 132 ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val);
133 if (ret) 133 if (ret)
134 DRM_ERROR("mic: Failed to read system register\n"); 134 DRM_ERROR("mic: Failed to read system register\n");
135} 135}
@@ -457,6 +457,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
457 "samsung,disp-syscon"); 457 "samsung,disp-syscon");
458 if (IS_ERR(mic->sysreg)) { 458 if (IS_ERR(mic->sysreg)) {
459 DRM_ERROR("mic: Failed to get system register.\n"); 459 DRM_ERROR("mic: Failed to get system register.\n");
460 ret = PTR_ERR(mic->sysreg);
460 goto err; 461 goto err;
461 } 462 }
462 463
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index d86227236f55..50185ac347b2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -11,9 +11,10 @@
11 11
12#include <drm/drmP.h> 12#include <drm/drmP.h>
13 13
14#include <drm/exynos_drm.h> 14#include <drm/drm_atomic.h>
15#include <drm/drm_plane_helper.h>
16#include <drm/drm_atomic_helper.h> 15#include <drm/drm_atomic_helper.h>
16#include <drm/drm_plane_helper.h>
17#include <drm/exynos_drm.h>
17#include "exynos_drm_drv.h" 18#include "exynos_drm_drv.h"
18#include "exynos_drm_crtc.h" 19#include "exynos_drm_crtc.h"
19#include "exynos_drm_fb.h" 20#include "exynos_drm_fb.h"
@@ -57,11 +58,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
57} 58}
58 59
59static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) 60static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
60
61{ 61{
62 struct drm_plane_state *state = &exynos_state->base; 62 struct drm_plane_state *state = &exynos_state->base;
63 struct drm_crtc *crtc = exynos_state->base.crtc; 63 struct drm_crtc *crtc = state->crtc;
64 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 64 struct drm_crtc_state *crtc_state =
65 drm_atomic_get_existing_crtc_state(state->state, crtc);
66 struct drm_display_mode *mode = &crtc_state->adjusted_mode;
65 int crtc_x, crtc_y; 67 int crtc_x, crtc_y;
66 unsigned int crtc_w, crtc_h; 68 unsigned int crtc_w, crtc_h;
67 unsigned int src_x, src_y; 69 unsigned int src_x, src_y;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index f18fbe43f55f..404367a430b5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -15,6 +15,7 @@
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/clk.h> 17#include <linux/clk.h>
18#include <linux/of_device.h>
18#include <linux/pm_runtime.h> 19#include <linux/pm_runtime.h>
19 20
20#include <drm/drmP.h> 21#include <drm/drmP.h>
@@ -696,7 +697,6 @@ static int rotator_probe(struct platform_device *pdev)
696 struct device *dev = &pdev->dev; 697 struct device *dev = &pdev->dev;
697 struct rot_context *rot; 698 struct rot_context *rot;
698 struct exynos_drm_ippdrv *ippdrv; 699 struct exynos_drm_ippdrv *ippdrv;
699 const struct of_device_id *match;
700 int ret; 700 int ret;
701 701
702 if (!dev->of_node) { 702 if (!dev->of_node) {
@@ -708,13 +708,8 @@ static int rotator_probe(struct platform_device *pdev)
708 if (!rot) 708 if (!rot)
709 return -ENOMEM; 709 return -ENOMEM;
710 710
711 match = of_match_node(exynos_rotator_match, dev->of_node); 711 rot->limit_tbl = (struct rot_limit_table *)
712 if (!match) { 712 of_device_get_match_data(dev);
713 dev_err(dev, "failed to match node\n");
714 return -ENODEV;
715 }
716 rot->limit_tbl = (struct rot_limit_table *)match->data;
717
718 rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 713 rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
719 rot->regs = devm_ioremap_resource(dev, rot->regs_res); 714 rot->regs = devm_ioremap_resource(dev, rot->regs_res);
720 if (IS_ERR(rot->regs)) 715 if (IS_ERR(rot->regs))
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index e148d728e28c..0f87acb4cf21 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -7,9 +7,9 @@
7 * 7 *
8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c 8 * Based on drivers/media/video/s5p-tv/hdmi_drv.c
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. 13 * option) any later version.
14 * 14 *
15 */ 15 */
@@ -49,14 +49,16 @@
49 49
50/* AVI header and aspect ratio */ 50/* AVI header and aspect ratio */
51#define HDMI_AVI_VERSION 0x02 51#define HDMI_AVI_VERSION 0x02
52#define HDMI_AVI_LENGTH 0x0D 52#define HDMI_AVI_LENGTH 0x0d
53 53
54/* AUI header info */ 54/* AUI header info */
55#define HDMI_AUI_VERSION 0x01 55#define HDMI_AUI_VERSION 0x01
56#define HDMI_AUI_LENGTH 0x0A 56#define HDMI_AUI_LENGTH 0x0a
57#define AVI_SAME_AS_PIC_ASPECT_RATIO 0x8 57
58#define AVI_4_3_CENTER_RATIO 0x9 58/* AVI active format aspect ratio */
59#define AVI_16_9_CENTER_RATIO 0xa 59#define AVI_SAME_AS_PIC_ASPECT_RATIO 0x08
60#define AVI_4_3_CENTER_RATIO 0x09
61#define AVI_16_9_CENTER_RATIO 0x0a
60 62
61enum hdmi_type { 63enum hdmi_type {
62 HDMI_TYPE13, 64 HDMI_TYPE13,
@@ -90,11 +92,34 @@ static const char * const supply[] = {
90 "vdd_pll", 92 "vdd_pll",
91}; 93};
92 94
95struct hdmiphy_config {
96 int pixel_clock;
97 u8 conf[32];
98};
99
100struct hdmiphy_configs {
101 int count;
102 const struct hdmiphy_config *data;
103};
104
105struct string_array_spec {
106 int count;
107 const char * const *data;
108};
109
110#define INIT_ARRAY_SPEC(a) { .count = ARRAY_SIZE(a), .data = a }
111
93struct hdmi_driver_data { 112struct hdmi_driver_data {
94 unsigned int type; 113 unsigned int type;
95 const struct hdmiphy_config *phy_confs;
96 unsigned int phy_conf_count;
97 unsigned int is_apb_phy:1; 114 unsigned int is_apb_phy:1;
115 unsigned int has_sysreg:1;
116 struct hdmiphy_configs phy_confs;
117 struct string_array_spec clk_gates;
118 /*
119 * Array of triplets (p_off, p_on, clock), where p_off and p_on are
120 * required parents of clock when HDMI-PHY is respectively off or on.
121 */
122 struct string_array_spec clk_muxes;
98}; 123};
99 124
100struct hdmi_context { 125struct hdmi_context {
@@ -116,11 +141,9 @@ struct hdmi_context {
116 struct gpio_desc *hpd_gpio; 141 struct gpio_desc *hpd_gpio;
117 int irq; 142 int irq;
118 struct regmap *pmureg; 143 struct regmap *pmureg;
119 struct clk *hdmi; 144 struct regmap *sysreg;
120 struct clk *sclk_hdmi; 145 struct clk **clk_gates;
121 struct clk *sclk_pixel; 146 struct clk **clk_muxes;
122 struct clk *sclk_hdmiphy;
123 struct clk *mout_hdmi;
124 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)]; 147 struct regulator_bulk_data regul_bulk[ARRAY_SIZE(supply)];
125 struct regulator *reg_hdmi_en; 148 struct regulator *reg_hdmi_en;
126}; 149};
@@ -135,12 +158,6 @@ static inline struct hdmi_context *connector_to_hdmi(struct drm_connector *c)
135 return container_of(c, struct hdmi_context, connector); 158 return container_of(c, struct hdmi_context, connector);
136} 159}
137 160
138struct hdmiphy_config {
139 int pixel_clock;
140 u8 conf[32];
141};
142
143/* list of phy config settings */
144static const struct hdmiphy_config hdmiphy_v13_configs[] = { 161static const struct hdmiphy_config hdmiphy_v13_configs[] = {
145 { 162 {
146 .pixel_clock = 27000000, 163 .pixel_clock = 27000000,
@@ -501,25 +518,136 @@ static const struct hdmiphy_config hdmiphy_5420_configs[] = {
501 }, 518 },
502}; 519};
503 520
504static struct hdmi_driver_data exynos5420_hdmi_driver_data = { 521static const struct hdmiphy_config hdmiphy_5433_configs[] = {
522 {
523 .pixel_clock = 27000000,
524 .conf = {
525 0x01, 0x51, 0x22, 0x51, 0x08, 0xfc, 0x88, 0x46,
526 0x72, 0x50, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
527 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
528 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
529 },
530 },
531 {
532 .pixel_clock = 27027000,
533 .conf = {
534 0x01, 0x51, 0x2d, 0x72, 0x64, 0x09, 0x88, 0xc3,
535 0x71, 0x50, 0x24, 0x14, 0x24, 0x0f, 0x7c, 0xa5,
536 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
537 0x28, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
538 },
539 },
540 {
541 .pixel_clock = 40000000,
542 .conf = {
543 0x01, 0x51, 0x32, 0x55, 0x01, 0x00, 0x88, 0x02,
544 0x4d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
545 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
546 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
547 },
548 },
549 {
550 .pixel_clock = 50000000,
551 .conf = {
552 0x01, 0x51, 0x34, 0x40, 0x64, 0x09, 0x88, 0xc3,
553 0x3d, 0x50, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
554 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
555 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
556 },
557 },
558 {
559 .pixel_clock = 65000000,
560 .conf = {
561 0x01, 0x51, 0x36, 0x31, 0x40, 0x10, 0x04, 0xc6,
562 0x2e, 0xe8, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
563 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
564 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
565 },
566 },
567 {
568 .pixel_clock = 74176000,
569 .conf = {
570 0x01, 0x51, 0x3E, 0x35, 0x5B, 0xDE, 0x88, 0x42,
571 0x53, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
572 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
573 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
574 },
575 },
576 {
577 .pixel_clock = 74250000,
578 .conf = {
579 0x01, 0x51, 0x3E, 0x35, 0x40, 0xF0, 0x88, 0xC2,
580 0x52, 0x51, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
581 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
582 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
583 },
584 },
585 {
586 .pixel_clock = 108000000,
587 .conf = {
588 0x01, 0x51, 0x2d, 0x15, 0x01, 0x00, 0x88, 0x02,
589 0x72, 0x52, 0x44, 0x8C, 0x27, 0x00, 0x7C, 0xAC,
590 0xD6, 0x2B, 0x67, 0x00, 0x00, 0x04, 0x00, 0x30,
591 0x08, 0x10, 0x01, 0x01, 0x48, 0x40, 0x00, 0x40,
592 },
593 },
594 {
595 .pixel_clock = 148500000,
596 .conf = {
597 0x01, 0x51, 0x1f, 0x00, 0x40, 0xf8, 0x88, 0xc1,
598 0x52, 0x52, 0x24, 0x0c, 0x24, 0x0f, 0x7c, 0xa5,
599 0xd4, 0x2b, 0x87, 0x00, 0x00, 0x04, 0x00, 0x30,
600 0x08, 0x10, 0x01, 0x01, 0x48, 0x4a, 0x00, 0x40,
601 },
602 },
603};
604
605static const char * const hdmi_clk_gates4[] = {
606 "hdmi", "sclk_hdmi"
607};
608
609static const char * const hdmi_clk_muxes4[] = {
610 "sclk_pixel", "sclk_hdmiphy", "mout_hdmi"
611};
612
613static const char * const hdmi_clk_gates5433[] = {
614 "hdmi_pclk", "hdmi_i_pclk", "i_tmds_clk", "i_pixel_clk", "i_spdif_clk"
615};
616
617static const char * const hdmi_clk_muxes5433[] = {
618 "oscclk", "tmds_clko", "tmds_clko_user",
619 "oscclk", "pixel_clko", "pixel_clko_user"
620};
621
622static const struct hdmi_driver_data exynos4210_hdmi_driver_data = {
623 .type = HDMI_TYPE13,
624 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v13_configs),
625 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
626 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
627};
628
629static const struct hdmi_driver_data exynos4212_hdmi_driver_data = {
505 .type = HDMI_TYPE14, 630 .type = HDMI_TYPE14,
506 .phy_confs = hdmiphy_5420_configs, 631 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_v14_configs),
507 .phy_conf_count = ARRAY_SIZE(hdmiphy_5420_configs), 632 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
508 .is_apb_phy = 1, 633 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
509}; 634};
510 635
511static struct hdmi_driver_data exynos4212_hdmi_driver_data = { 636static const struct hdmi_driver_data exynos5420_hdmi_driver_data = {
512 .type = HDMI_TYPE14, 637 .type = HDMI_TYPE14,
513 .phy_confs = hdmiphy_v14_configs, 638 .is_apb_phy = 1,
514 .phy_conf_count = ARRAY_SIZE(hdmiphy_v14_configs), 639 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5420_configs),
515 .is_apb_phy = 0, 640 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
641 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
516}; 642};
517 643
518static struct hdmi_driver_data exynos4210_hdmi_driver_data = { 644static const struct hdmi_driver_data exynos5433_hdmi_driver_data = {
519 .type = HDMI_TYPE13, 645 .type = HDMI_TYPE14,
520 .phy_confs = hdmiphy_v13_configs, 646 .is_apb_phy = 1,
521 .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs), 647 .has_sysreg = 1,
522 .is_apb_phy = 0, 648 .phy_confs = INIT_ARRAY_SPEC(hdmiphy_5433_configs),
649 .clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates5433),
650 .clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes5433),
523}; 651};
524 652
525static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id) 653static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
@@ -585,266 +713,52 @@ static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
585 } 713 }
586} 714}
587 715
588static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) 716static int hdmi_clk_enable_gates(struct hdmi_context *hdata)
589{ 717{
590#define DUMPREG(reg_id) \ 718 int i, ret;
591 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 719
592 readl(hdata->regs + reg_id)) 720 for (i = 0; i < hdata->drv_data->clk_gates.count; ++i) {
593 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix); 721 ret = clk_prepare_enable(hdata->clk_gates[i]);
594 DUMPREG(HDMI_INTC_FLAG); 722 if (!ret)
595 DUMPREG(HDMI_INTC_CON); 723 continue;
596 DUMPREG(HDMI_HPD_STATUS); 724
597 DUMPREG(HDMI_V13_PHY_RSTOUT); 725 dev_err(hdata->dev, "Cannot enable clock '%s', %d\n",
598 DUMPREG(HDMI_V13_PHY_VPLL); 726 hdata->drv_data->clk_gates.data[i], ret);
599 DUMPREG(HDMI_V13_PHY_CMU); 727 while (i--)
600 DUMPREG(HDMI_V13_CORE_RSTOUT); 728 clk_disable_unprepare(hdata->clk_gates[i]);
601 729 return ret;
602 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix); 730 }
603 DUMPREG(HDMI_CON_0); 731
604 DUMPREG(HDMI_CON_1); 732 return 0;
605 DUMPREG(HDMI_CON_2);
606 DUMPREG(HDMI_SYS_STATUS);
607 DUMPREG(HDMI_V13_PHY_STATUS);
608 DUMPREG(HDMI_STATUS_EN);
609 DUMPREG(HDMI_HPD);
610 DUMPREG(HDMI_MODE_SEL);
611 DUMPREG(HDMI_V13_HPD_GEN);
612 DUMPREG(HDMI_V13_DC_CONTROL);
613 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
614
615 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
616 DUMPREG(HDMI_H_BLANK_0);
617 DUMPREG(HDMI_H_BLANK_1);
618 DUMPREG(HDMI_V13_V_BLANK_0);
619 DUMPREG(HDMI_V13_V_BLANK_1);
620 DUMPREG(HDMI_V13_V_BLANK_2);
621 DUMPREG(HDMI_V13_H_V_LINE_0);
622 DUMPREG(HDMI_V13_H_V_LINE_1);
623 DUMPREG(HDMI_V13_H_V_LINE_2);
624 DUMPREG(HDMI_VSYNC_POL);
625 DUMPREG(HDMI_INT_PRO_MODE);
626 DUMPREG(HDMI_V13_V_BLANK_F_0);
627 DUMPREG(HDMI_V13_V_BLANK_F_1);
628 DUMPREG(HDMI_V13_V_BLANK_F_2);
629 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
630 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
631 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
632 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
633 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
634 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
635 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
636 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
637 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
638 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
639 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
640 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
641
642 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
643 DUMPREG(HDMI_TG_CMD);
644 DUMPREG(HDMI_TG_H_FSZ_L);
645 DUMPREG(HDMI_TG_H_FSZ_H);
646 DUMPREG(HDMI_TG_HACT_ST_L);
647 DUMPREG(HDMI_TG_HACT_ST_H);
648 DUMPREG(HDMI_TG_HACT_SZ_L);
649 DUMPREG(HDMI_TG_HACT_SZ_H);
650 DUMPREG(HDMI_TG_V_FSZ_L);
651 DUMPREG(HDMI_TG_V_FSZ_H);
652 DUMPREG(HDMI_TG_VSYNC_L);
653 DUMPREG(HDMI_TG_VSYNC_H);
654 DUMPREG(HDMI_TG_VSYNC2_L);
655 DUMPREG(HDMI_TG_VSYNC2_H);
656 DUMPREG(HDMI_TG_VACT_ST_L);
657 DUMPREG(HDMI_TG_VACT_ST_H);
658 DUMPREG(HDMI_TG_VACT_SZ_L);
659 DUMPREG(HDMI_TG_VACT_SZ_H);
660 DUMPREG(HDMI_TG_FIELD_CHG_L);
661 DUMPREG(HDMI_TG_FIELD_CHG_H);
662 DUMPREG(HDMI_TG_VACT_ST2_L);
663 DUMPREG(HDMI_TG_VACT_ST2_H);
664 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
665 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
666 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
667 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
668 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
669 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
670 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
671 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
672#undef DUMPREG
673} 733}
674 734
675static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix) 735static void hdmi_clk_disable_gates(struct hdmi_context *hdata)
676{ 736{
677 int i; 737 int i = hdata->drv_data->clk_gates.count;
678 738
679#define DUMPREG(reg_id) \ 739 while (i--)
680 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 740 clk_disable_unprepare(hdata->clk_gates[i]);
681 readl(hdata->regs + reg_id))
682
683 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
684 DUMPREG(HDMI_INTC_CON);
685 DUMPREG(HDMI_INTC_FLAG);
686 DUMPREG(HDMI_HPD_STATUS);
687 DUMPREG(HDMI_INTC_CON_1);
688 DUMPREG(HDMI_INTC_FLAG_1);
689 DUMPREG(HDMI_PHY_STATUS_0);
690 DUMPREG(HDMI_PHY_STATUS_PLL);
691 DUMPREG(HDMI_PHY_CON_0);
692 DUMPREG(HDMI_V14_PHY_RSTOUT);
693 DUMPREG(HDMI_PHY_VPLL);
694 DUMPREG(HDMI_PHY_CMU);
695 DUMPREG(HDMI_CORE_RSTOUT);
696
697 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
698 DUMPREG(HDMI_CON_0);
699 DUMPREG(HDMI_CON_1);
700 DUMPREG(HDMI_CON_2);
701 DUMPREG(HDMI_SYS_STATUS);
702 DUMPREG(HDMI_PHY_STATUS_0);
703 DUMPREG(HDMI_STATUS_EN);
704 DUMPREG(HDMI_HPD);
705 DUMPREG(HDMI_MODE_SEL);
706 DUMPREG(HDMI_ENC_EN);
707 DUMPREG(HDMI_DC_CONTROL);
708 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
709
710 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
711 DUMPREG(HDMI_H_BLANK_0);
712 DUMPREG(HDMI_H_BLANK_1);
713 DUMPREG(HDMI_V2_BLANK_0);
714 DUMPREG(HDMI_V2_BLANK_1);
715 DUMPREG(HDMI_V1_BLANK_0);
716 DUMPREG(HDMI_V1_BLANK_1);
717 DUMPREG(HDMI_V_LINE_0);
718 DUMPREG(HDMI_V_LINE_1);
719 DUMPREG(HDMI_H_LINE_0);
720 DUMPREG(HDMI_H_LINE_1);
721 DUMPREG(HDMI_HSYNC_POL);
722
723 DUMPREG(HDMI_VSYNC_POL);
724 DUMPREG(HDMI_INT_PRO_MODE);
725 DUMPREG(HDMI_V_BLANK_F0_0);
726 DUMPREG(HDMI_V_BLANK_F0_1);
727 DUMPREG(HDMI_V_BLANK_F1_0);
728 DUMPREG(HDMI_V_BLANK_F1_1);
729
730 DUMPREG(HDMI_H_SYNC_START_0);
731 DUMPREG(HDMI_H_SYNC_START_1);
732 DUMPREG(HDMI_H_SYNC_END_0);
733 DUMPREG(HDMI_H_SYNC_END_1);
734
735 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
736 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
737 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
738 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
739
740 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
741 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
742 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
743 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
744
745 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
746 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
747 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
748 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
749
750 DUMPREG(HDMI_V_BLANK_F2_0);
751 DUMPREG(HDMI_V_BLANK_F2_1);
752 DUMPREG(HDMI_V_BLANK_F3_0);
753 DUMPREG(HDMI_V_BLANK_F3_1);
754 DUMPREG(HDMI_V_BLANK_F4_0);
755 DUMPREG(HDMI_V_BLANK_F4_1);
756 DUMPREG(HDMI_V_BLANK_F5_0);
757 DUMPREG(HDMI_V_BLANK_F5_1);
758
759 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
760 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
761 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
762 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
763 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
764 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
765 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
766 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
767
768 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
769 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
770 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
771 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
772 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
773 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
774 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
775 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
776
777 DUMPREG(HDMI_VACT_SPACE_1_0);
778 DUMPREG(HDMI_VACT_SPACE_1_1);
779 DUMPREG(HDMI_VACT_SPACE_2_0);
780 DUMPREG(HDMI_VACT_SPACE_2_1);
781 DUMPREG(HDMI_VACT_SPACE_3_0);
782 DUMPREG(HDMI_VACT_SPACE_3_1);
783 DUMPREG(HDMI_VACT_SPACE_4_0);
784 DUMPREG(HDMI_VACT_SPACE_4_1);
785 DUMPREG(HDMI_VACT_SPACE_5_0);
786 DUMPREG(HDMI_VACT_SPACE_5_1);
787 DUMPREG(HDMI_VACT_SPACE_6_0);
788 DUMPREG(HDMI_VACT_SPACE_6_1);
789
790 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
791 DUMPREG(HDMI_TG_CMD);
792 DUMPREG(HDMI_TG_H_FSZ_L);
793 DUMPREG(HDMI_TG_H_FSZ_H);
794 DUMPREG(HDMI_TG_HACT_ST_L);
795 DUMPREG(HDMI_TG_HACT_ST_H);
796 DUMPREG(HDMI_TG_HACT_SZ_L);
797 DUMPREG(HDMI_TG_HACT_SZ_H);
798 DUMPREG(HDMI_TG_V_FSZ_L);
799 DUMPREG(HDMI_TG_V_FSZ_H);
800 DUMPREG(HDMI_TG_VSYNC_L);
801 DUMPREG(HDMI_TG_VSYNC_H);
802 DUMPREG(HDMI_TG_VSYNC2_L);
803 DUMPREG(HDMI_TG_VSYNC2_H);
804 DUMPREG(HDMI_TG_VACT_ST_L);
805 DUMPREG(HDMI_TG_VACT_ST_H);
806 DUMPREG(HDMI_TG_VACT_SZ_L);
807 DUMPREG(HDMI_TG_VACT_SZ_H);
808 DUMPREG(HDMI_TG_FIELD_CHG_L);
809 DUMPREG(HDMI_TG_FIELD_CHG_H);
810 DUMPREG(HDMI_TG_VACT_ST2_L);
811 DUMPREG(HDMI_TG_VACT_ST2_H);
812 DUMPREG(HDMI_TG_VACT_ST3_L);
813 DUMPREG(HDMI_TG_VACT_ST3_H);
814 DUMPREG(HDMI_TG_VACT_ST4_L);
815 DUMPREG(HDMI_TG_VACT_ST4_H);
816 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
817 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
818 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
819 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
820 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
821 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
822 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
823 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
824 DUMPREG(HDMI_TG_3D);
825
826 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
827 DUMPREG(HDMI_AVI_CON);
828 DUMPREG(HDMI_AVI_HEADER0);
829 DUMPREG(HDMI_AVI_HEADER1);
830 DUMPREG(HDMI_AVI_HEADER2);
831 DUMPREG(HDMI_AVI_CHECK_SUM);
832 DUMPREG(HDMI_VSI_CON);
833 DUMPREG(HDMI_VSI_HEADER0);
834 DUMPREG(HDMI_VSI_HEADER1);
835 DUMPREG(HDMI_VSI_HEADER2);
836 for (i = 0; i < 7; ++i)
837 DUMPREG(HDMI_VSI_DATA(i));
838
839#undef DUMPREG
840} 741}
841 742
842static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) 743static int hdmi_clk_set_parents(struct hdmi_context *hdata, bool to_phy)
843{ 744{
844 if (hdata->drv_data->type == HDMI_TYPE13) 745 struct device *dev = hdata->dev;
845 hdmi_v13_regs_dump(hdata, prefix); 746 int ret = 0;
846 else 747 int i;
847 hdmi_v14_regs_dump(hdata, prefix); 748
749 for (i = 0; i < hdata->drv_data->clk_muxes.count; i += 3) {
750 struct clk **c = &hdata->clk_muxes[i];
751
752 ret = clk_set_parent(c[2], c[to_phy]);
753 if (!ret)
754 continue;
755
756 dev_err(dev, "Cannot set clock parent of '%s' to '%s', %d\n",
757 hdata->drv_data->clk_muxes.data[i + 2],
758 hdata->drv_data->clk_muxes.data[i + to_phy], ret);
759 }
760
761 return ret;
848} 762}
849 763
850static u8 hdmi_chksum(struct hdmi_context *hdata, 764static u8 hdmi_chksum(struct hdmi_context *hdata,
@@ -993,10 +907,11 @@ static int hdmi_get_modes(struct drm_connector *connector)
993 907
994static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) 908static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
995{ 909{
910 const struct hdmiphy_configs *confs = &hdata->drv_data->phy_confs;
996 int i; 911 int i;
997 912
998 for (i = 0; i < hdata->drv_data->phy_conf_count; i++) 913 for (i = 0; i < confs->count; i++)
999 if (hdata->drv_data->phy_confs[i].pixel_clock == pixel_clock) 914 if (confs->data[i].pixel_clock == pixel_clock)
1000 return i; 915 return i;
1001 916
1002 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock); 917 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
@@ -1078,13 +993,11 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder,
1078 993
1079 mode_ok = hdmi_mode_valid(connector, adjusted_mode); 994 mode_ok = hdmi_mode_valid(connector, adjusted_mode);
1080 995
1081 /* just return if user desired mode exists. */
1082 if (mode_ok == MODE_OK) 996 if (mode_ok == MODE_OK)
1083 return true; 997 return true;
1084 998
1085 /* 999 /*
1086 * otherwise, find the most suitable mode among modes and change it 1000 * Find the most suitable mode and copy it to adjusted_mode.
1087 * to adjusted_mode.
1088 */ 1001 */
1089 list_for_each_entry(m, &connector->modes, head) { 1002 list_for_each_entry(m, &connector->modes, head) {
1090 mode_ok = hdmi_mode_valid(connector, m); 1003 mode_ok = hdmi_mode_valid(connector, m);
@@ -1129,15 +1042,15 @@ static void hdmi_audio_init(struct hdmi_context *hdata)
1129 switch (bits_per_sample) { 1042 switch (bits_per_sample) {
1130 case 20: 1043 case 20:
1131 data_num = 2; 1044 data_num = 2;
1132 bit_ch = 1; 1045 bit_ch = 1;
1133 break; 1046 break;
1134 case 24: 1047 case 24:
1135 data_num = 3; 1048 data_num = 3;
1136 bit_ch = 1; 1049 bit_ch = 1;
1137 break; 1050 break;
1138 default: 1051 default:
1139 data_num = 1; 1052 data_num = 1;
1140 bit_ch = 0; 1053 bit_ch = 0;
1141 break; 1054 break;
1142 } 1055 }
1143 1056
@@ -1230,13 +1143,12 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
1230 /* choose HDMI mode */ 1143 /* choose HDMI mode */
1231 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1144 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1232 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); 1145 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1233 /* Apply Video preable and Guard band in HDMI mode only */ 1146 /* apply video pre-amble and guard band in HDMI mode only */
1234 hdmi_reg_writeb(hdata, HDMI_CON_2, 0); 1147 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1235 /* disable bluescreen */ 1148 /* disable bluescreen */
1236 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); 1149 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1237 1150
1238 if (hdata->dvi_mode) { 1151 if (hdata->dvi_mode) {
1239 /* choose DVI mode */
1240 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1152 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1241 HDMI_MODE_DVI_EN, HDMI_MODE_MASK); 1153 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
1242 hdmi_reg_writeb(hdata, HDMI_CON_2, 1154 hdmi_reg_writeb(hdata, HDMI_CON_2,
@@ -1308,7 +1220,7 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1308 1220
1309 val = (m->hsync_start - m->hdisplay - 2); 1221 val = (m->hsync_start - m->hdisplay - 2);
1310 val |= ((m->hsync_end - m->hdisplay - 2) << 10); 1222 val |= ((m->hsync_end - m->hdisplay - 2) << 10);
1311 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20; 1223 val |= ((m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0)<<20;
1312 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val); 1224 hdmi_reg_writev(hdata, HDMI_V13_H_SYNC_GEN_0, 3, val);
1313 1225
1314 /* 1226 /*
@@ -1319,7 +1231,6 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1319 1231
1320 /* Following values & calculations differ for different type of modes */ 1232 /* Following values & calculations differ for different type of modes */
1321 if (m->flags & DRM_MODE_FLAG_INTERLACE) { 1233 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1322 /* Interlaced Mode */
1323 val = ((m->vsync_end - m->vdisplay) / 2); 1234 val = ((m->vsync_end - m->vdisplay) / 2);
1324 val |= ((m->vsync_start - m->vdisplay) / 2) << 12; 1235 val |= ((m->vsync_start - m->vdisplay) / 2) << 12;
1325 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val); 1236 hdmi_reg_writev(hdata, HDMI_V13_V_SYNC_GEN_1_0, 3, val);
@@ -1348,8 +1259,6 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1348 1259
1349 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249); 1260 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x249);
1350 } else { 1261 } else {
1351 /* Progressive Mode */
1352
1353 val = m->vtotal; 1262 val = m->vtotal;
1354 val |= (m->vtotal - m->vdisplay) << 11; 1263 val |= (m->vtotal - m->vdisplay) << 11;
1355 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val); 1264 hdmi_reg_writev(hdata, HDMI_V13_V_BLANK_0, 3, val);
@@ -1365,21 +1274,12 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1365 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2, 1274 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1366 m->vtotal - m->vdisplay); 1275 m->vtotal - m->vdisplay);
1367 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay); 1276 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1368 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248);
1369 } 1277 }
1370 1278
1371 /* Timing generator registers */
1372 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); 1279 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1373 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); 1280 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1374 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); 1281 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1375 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); 1282 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1376 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1);
1377 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233);
1378 hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233);
1379 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1);
1380 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233);
1381 hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1);
1382 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233);
1383} 1283}
1384 1284
1385static void hdmi_v14_mode_apply(struct hdmi_context *hdata) 1285static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
@@ -1390,7 +1290,7 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1390 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal); 1290 hdmi_reg_writev(hdata, HDMI_V_LINE_0, 2, m->vtotal);
1391 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal); 1291 hdmi_reg_writev(hdata, HDMI_H_LINE_0, 2, m->htotal);
1392 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1, 1292 hdmi_reg_writev(hdata, HDMI_HSYNC_POL, 1,
1393 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0); 1293 (m->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0);
1394 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1, 1294 hdmi_reg_writev(hdata, HDMI_VSYNC_POL, 1,
1395 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0); 1295 (m->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0);
1396 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1, 1296 hdmi_reg_writev(hdata, HDMI_INT_PRO_MODE, 1,
@@ -1404,7 +1304,6 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1404 1304
1405 /* Following values & calculations differ for different type of modes */ 1305 /* Following values & calculations differ for different type of modes */
1406 if (m->flags & DRM_MODE_FLAG_INTERLACE) { 1306 if (m->flags & DRM_MODE_FLAG_INTERLACE) {
1407 /* Interlaced Mode */
1408 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2, 1307 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1409 (m->vsync_end - m->vdisplay) / 2); 1308 (m->vsync_end - m->vdisplay) / 2);
1410 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2, 1309 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
@@ -1437,7 +1336,6 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1437 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0); 1336 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x0);
1438 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0); 1337 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x0);
1439 } else { 1338 } else {
1440 /* Progressive Mode */
1441 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2, 1339 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_2_0, 2,
1442 m->vsync_end - m->vdisplay); 1340 m->vsync_end - m->vdisplay);
1443 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2, 1341 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_BEF_1_0, 2,
@@ -1454,15 +1352,8 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1454 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2, 1352 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST_L, 2,
1455 m->vtotal - m->vdisplay); 1353 m->vtotal - m->vdisplay);
1456 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay); 1354 hdmi_reg_writev(hdata, HDMI_TG_VACT_SZ_L, 2, m->vdisplay);
1457 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST2_L, 2, 0x248);
1458 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST3_L, 2, 0x47b);
1459 hdmi_reg_writev(hdata, HDMI_TG_VACT_ST4_L, 2, 0x6ae);
1460 hdmi_reg_writev(hdata, HDMI_TG_VSYNC2_L, 2, 0x233);
1461 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, 2, 0x233);
1462 hdmi_reg_writev(hdata, HDMI_TG_FIELD_BOT_HDMI_L, 2, 0x233);
1463 } 1355 }
1464 1356
1465 /* Following values & calculations are same irrespective of mode type */
1466 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2, 1357 hdmi_reg_writev(hdata, HDMI_H_SYNC_START_0, 2,
1467 m->hsync_start - m->hdisplay - 2); 1358 m->hsync_start - m->hdisplay - 2);
1468 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2, 1359 hdmi_reg_writev(hdata, HDMI_H_SYNC_END_0, 2,
@@ -1486,16 +1377,12 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1486 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff); 1377 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0, 2, 0xffff);
1487 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff); 1378 hdmi_reg_writev(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0, 2, 0xffff);
1488 1379
1489 /* Timing generator registers */
1490 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal); 1380 hdmi_reg_writev(hdata, HDMI_TG_H_FSZ_L, 2, m->htotal);
1491 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay); 1381 hdmi_reg_writev(hdata, HDMI_TG_HACT_ST_L, 2, m->htotal - m->hdisplay);
1492 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay); 1382 hdmi_reg_writev(hdata, HDMI_TG_HACT_SZ_L, 2, m->hdisplay);
1493 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal); 1383 hdmi_reg_writev(hdata, HDMI_TG_V_FSZ_L, 2, m->vtotal);
1494 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_L, 2, 0x1); 1384 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1495 hdmi_reg_writev(hdata, HDMI_TG_FIELD_CHG_L, 2, 0x233); 1385 hdmi_reg_writeb(hdata, HDMI_TG_DECON_EN, 1);
1496 hdmi_reg_writev(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, 2, 0x1);
1497 hdmi_reg_writev(hdata, HDMI_TG_FIELD_TOP_HDMI_L, 2, 0x1);
1498 hdmi_reg_writev(hdata, HDMI_TG_3D, 1, 0x0);
1499} 1386}
1500 1387
1501static void hdmi_mode_apply(struct hdmi_context *hdata) 1388static void hdmi_mode_apply(struct hdmi_context *hdata)
@@ -1505,62 +1392,65 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
1505 else 1392 else
1506 hdmi_v14_mode_apply(hdata); 1393 hdmi_v14_mode_apply(hdata);
1507 1394
1508 hdmiphy_wait_for_pll(hdata);
1509
1510 clk_set_parent(hdata->mout_hdmi, hdata->sclk_hdmiphy);
1511
1512 /* enable HDMI and timing generator */
1513 hdmi_start(hdata, true); 1395 hdmi_start(hdata, true);
1514} 1396}
1515 1397
1516static void hdmiphy_conf_reset(struct hdmi_context *hdata) 1398static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1517{ 1399{
1518 clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel); 1400 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, 1);
1519 1401 usleep_range(10000, 12000);
1520 /* reset hdmiphy */ 1402 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, 1);
1403 usleep_range(10000, 12000);
1521 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); 1404 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
1522 usleep_range(10000, 12000); 1405 usleep_range(10000, 12000);
1523 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT); 1406 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
1524 usleep_range(10000, 12000); 1407 usleep_range(10000, 12000);
1525} 1408}
1526 1409
1410static void hdmiphy_enable_mode_set(struct hdmi_context *hdata, bool enable)
1411{
1412 u8 v = enable ? HDMI_PHY_ENABLE_MODE_SET : HDMI_PHY_DISABLE_MODE_SET;
1413
1414 if (hdata->drv_data == &exynos5433_hdmi_driver_data)
1415 writel(v, hdata->regs_hdmiphy + HDMIPHY5433_MODE_SET_DONE);
1416}
1417
1527static void hdmiphy_conf_apply(struct hdmi_context *hdata) 1418static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1528{ 1419{
1529 int ret; 1420 int ret;
1530 int i; 1421 const u8 *phy_conf;
1531 1422
1532 /* pixel clock */ 1423 ret = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000);
1533 i = hdmi_find_phy_conf(hdata, hdata->current_mode.clock * 1000); 1424 if (ret < 0) {
1534 if (i < 0) {
1535 DRM_ERROR("failed to find hdmiphy conf\n"); 1425 DRM_ERROR("failed to find hdmiphy conf\n");
1536 return; 1426 return;
1537 } 1427 }
1428 phy_conf = hdata->drv_data->phy_confs.data[ret].conf;
1429
1430 hdmi_clk_set_parents(hdata, false);
1431
1432 hdmiphy_conf_reset(hdata);
1538 1433
1539 ret = hdmiphy_reg_write_buf(hdata, 0, 1434 hdmiphy_enable_mode_set(hdata, true);
1540 hdata->drv_data->phy_confs[i].conf, 32); 1435 ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32);
1541 if (ret) { 1436 if (ret) {
1542 DRM_ERROR("failed to configure hdmiphy\n"); 1437 DRM_ERROR("failed to configure hdmiphy\n");
1543 return; 1438 return;
1544 } 1439 }
1545 1440 hdmiphy_enable_mode_set(hdata, false);
1441 hdmi_clk_set_parents(hdata, true);
1546 usleep_range(10000, 12000); 1442 usleep_range(10000, 12000);
1443 hdmiphy_wait_for_pll(hdata);
1547} 1444}
1548 1445
1549static void hdmi_conf_apply(struct hdmi_context *hdata) 1446static void hdmi_conf_apply(struct hdmi_context *hdata)
1550{ 1447{
1551 hdmiphy_conf_reset(hdata);
1552 hdmiphy_conf_apply(hdata); 1448 hdmiphy_conf_apply(hdata);
1553
1554 hdmi_start(hdata, false); 1449 hdmi_start(hdata, false);
1555 hdmi_conf_init(hdata); 1450 hdmi_conf_init(hdata);
1556
1557 hdmi_audio_init(hdata); 1451 hdmi_audio_init(hdata);
1558
1559 /* setting core registers */
1560 hdmi_mode_apply(hdata); 1452 hdmi_mode_apply(hdata);
1561 hdmi_audio_control(hdata, true); 1453 hdmi_audio_control(hdata, true);
1562
1563 hdmi_regs_dump(hdata, "start");
1564} 1454}
1565 1455
1566static void hdmi_mode_set(struct drm_encoder *encoder, 1456static void hdmi_mode_set(struct drm_encoder *encoder,
@@ -1579,6 +1469,15 @@ static void hdmi_mode_set(struct drm_encoder *encoder,
1579 hdata->cea_video_id = drm_match_cea_mode(mode); 1469 hdata->cea_video_id = drm_match_cea_mode(mode);
1580} 1470}
1581 1471
1472static void hdmi_set_refclk(struct hdmi_context *hdata, bool on)
1473{
1474 if (!hdata->sysreg)
1475 return;
1476
1477 regmap_update_bits(hdata->sysreg, EXYNOS5433_SYSREG_DISP_HDMI_PHY,
1478 SYSREG_HDMI_REFCLK_INT_CLK, on ? ~0 : 0);
1479}
1480
1582static void hdmi_enable(struct drm_encoder *encoder) 1481static void hdmi_enable(struct drm_encoder *encoder)
1583{ 1482{
1584 struct hdmi_context *hdata = encoder_to_hdmi(encoder); 1483 struct hdmi_context *hdata = encoder_to_hdmi(encoder);
@@ -1591,10 +1490,13 @@ static void hdmi_enable(struct drm_encoder *encoder)
1591 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk)) 1490 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk))
1592 DRM_DEBUG_KMS("failed to enable regulator bulk\n"); 1491 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1593 1492
1594 /* set pmu hdmiphy control bit to enable hdmiphy */
1595 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1493 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1596 PMU_HDMI_PHY_ENABLE_BIT, 1); 1494 PMU_HDMI_PHY_ENABLE_BIT, 1);
1597 1495
1496 hdmi_set_refclk(hdata, true);
1497
1498 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, HDMI_PHY_POWER_OFF_EN);
1499
1598 hdmi_conf_apply(hdata); 1500 hdmi_conf_apply(hdata);
1599 1501
1600 hdata->powered = true; 1502 hdata->powered = true;
@@ -1623,12 +1525,14 @@ static void hdmi_disable(struct drm_encoder *encoder)
1623 if (funcs && funcs->disable) 1525 if (funcs && funcs->disable)
1624 (*funcs->disable)(crtc); 1526 (*funcs->disable)(crtc);
1625 1527
1626 /* HDMI System Disable */
1627 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN); 1528 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1628 1529
1629 cancel_delayed_work(&hdata->hotplug_work); 1530 cancel_delayed_work(&hdata->hotplug_work);
1630 1531
1631 /* reset pmu hdmiphy control bit to disable hdmiphy */ 1532 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, HDMI_PHY_POWER_OFF_EN);
1533
1534 hdmi_set_refclk(hdata, false);
1535
1632 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1536 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
1633 PMU_HDMI_PHY_ENABLE_BIT, 0); 1537 PMU_HDMI_PHY_ENABLE_BIT, 0);
1634 1538
@@ -1670,6 +1574,57 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1670 return IRQ_HANDLED; 1574 return IRQ_HANDLED;
1671} 1575}
1672 1576
1577static int hdmi_clks_get(struct hdmi_context *hdata,
1578 const struct string_array_spec *names,
1579 struct clk **clks)
1580{
1581 struct device *dev = hdata->dev;
1582 int i;
1583
1584 for (i = 0; i < names->count; ++i) {
1585 struct clk *clk = devm_clk_get(dev, names->data[i]);
1586
1587 if (IS_ERR(clk)) {
1588 int ret = PTR_ERR(clk);
1589
1590 dev_err(dev, "Cannot get clock %s, %d\n",
1591 names->data[i], ret);
1592
1593 return ret;
1594 }
1595
1596 clks[i] = clk;
1597 }
1598
1599 return 0;
1600}
1601
1602static int hdmi_clk_init(struct hdmi_context *hdata)
1603{
1604 const struct hdmi_driver_data *drv_data = hdata->drv_data;
1605 int count = drv_data->clk_gates.count + drv_data->clk_muxes.count;
1606 struct device *dev = hdata->dev;
1607 struct clk **clks;
1608 int ret;
1609
1610 if (!count)
1611 return 0;
1612
1613 clks = devm_kzalloc(dev, sizeof(*clks) * count, GFP_KERNEL);
1614 if (!clks)
1615 return -ENOMEM;
1616
1617 hdata->clk_gates = clks;
1618 hdata->clk_muxes = clks + drv_data->clk_gates.count;
1619
1620 ret = hdmi_clks_get(hdata, &drv_data->clk_gates, hdata->clk_gates);
1621 if (ret)
1622 return ret;
1623
1624 return hdmi_clks_get(hdata, &drv_data->clk_muxes, hdata->clk_muxes);
1625}
1626
1627
1673static int hdmi_resources_init(struct hdmi_context *hdata) 1628static int hdmi_resources_init(struct hdmi_context *hdata)
1674{ 1629{
1675 struct device *dev = hdata->dev; 1630 struct device *dev = hdata->dev;
@@ -1688,39 +1643,14 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
1688 DRM_ERROR("failed to get GPIO irq\n"); 1643 DRM_ERROR("failed to get GPIO irq\n");
1689 return hdata->irq; 1644 return hdata->irq;
1690 } 1645 }
1691 /* get clocks, power */
1692 hdata->hdmi = devm_clk_get(dev, "hdmi");
1693 if (IS_ERR(hdata->hdmi)) {
1694 DRM_ERROR("failed to get clock 'hdmi'\n");
1695 ret = PTR_ERR(hdata->hdmi);
1696 goto fail;
1697 }
1698 hdata->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1699 if (IS_ERR(hdata->sclk_hdmi)) {
1700 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
1701 ret = PTR_ERR(hdata->sclk_hdmi);
1702 goto fail;
1703 }
1704 hdata->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
1705 if (IS_ERR(hdata->sclk_pixel)) {
1706 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
1707 ret = PTR_ERR(hdata->sclk_pixel);
1708 goto fail;
1709 }
1710 hdata->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
1711 if (IS_ERR(hdata->sclk_hdmiphy)) {
1712 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1713 ret = PTR_ERR(hdata->sclk_hdmiphy);
1714 goto fail;
1715 }
1716 hdata->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
1717 if (IS_ERR(hdata->mout_hdmi)) {
1718 DRM_ERROR("failed to get clock 'mout_hdmi'\n");
1719 ret = PTR_ERR(hdata->mout_hdmi);
1720 goto fail;
1721 }
1722 1646
1723 clk_set_parent(hdata->mout_hdmi, hdata->sclk_pixel); 1647 ret = hdmi_clk_init(hdata);
1648 if (ret)
1649 return ret;
1650
1651 ret = hdmi_clk_set_parents(hdata, false);
1652 if (ret)
1653 return ret;
1724 1654
1725 for (i = 0; i < ARRAY_SIZE(supply); ++i) { 1655 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1726 hdata->regul_bulk[i].supply = supply[i]; 1656 hdata->regul_bulk[i].supply = supply[i];
@@ -1745,9 +1675,6 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
1745 DRM_ERROR("failed to enable hdmi-en regulator\n"); 1675 DRM_ERROR("failed to enable hdmi-en regulator\n");
1746 1676
1747 return ret; 1677 return ret;
1748fail:
1749 DRM_ERROR("HDMI resource init - failed\n");
1750 return ret;
1751} 1678}
1752 1679
1753static struct of_device_id hdmi_match_types[] = { 1680static struct of_device_id hdmi_match_types[] = {
@@ -1761,6 +1688,9 @@ static struct of_device_id hdmi_match_types[] = {
1761 .compatible = "samsung,exynos5420-hdmi", 1688 .compatible = "samsung,exynos5420-hdmi",
1762 .data = &exynos5420_hdmi_driver_data, 1689 .data = &exynos5420_hdmi_driver_data,
1763 }, { 1690 }, {
1691 .compatible = "samsung,exynos5433-hdmi",
1692 .data = &exynos5433_hdmi_driver_data,
1693 }, {
1764 /* end node */ 1694 /* end node */
1765 } 1695 }
1766}; 1696};
@@ -1830,7 +1760,6 @@ static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
1830static int hdmi_probe(struct platform_device *pdev) 1760static int hdmi_probe(struct platform_device *pdev)
1831{ 1761{
1832 struct device_node *ddc_node, *phy_node; 1762 struct device_node *ddc_node, *phy_node;
1833 const struct of_device_id *match;
1834 struct device *dev = &pdev->dev; 1763 struct device *dev = &pdev->dev;
1835 struct hdmi_context *hdata; 1764 struct hdmi_context *hdata;
1836 struct resource *res; 1765 struct resource *res;
@@ -1840,11 +1769,7 @@ static int hdmi_probe(struct platform_device *pdev)
1840 if (!hdata) 1769 if (!hdata)
1841 return -ENOMEM; 1770 return -ENOMEM;
1842 1771
1843 match = of_match_device(hdmi_match_types, dev); 1772 hdata->drv_data = of_device_get_match_data(dev);
1844 if (!match)
1845 return -ENODEV;
1846
1847 hdata->drv_data = match->data;
1848 1773
1849 platform_set_drvdata(pdev, hdata); 1774 platform_set_drvdata(pdev, hdata);
1850 1775
@@ -1867,7 +1792,6 @@ static int hdmi_probe(struct platform_device *pdev)
1867 if (ddc_node) 1792 if (ddc_node)
1868 goto out_get_ddc_adpt; 1793 goto out_get_ddc_adpt;
1869 1794
1870 /* DDC i2c driver */
1871 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); 1795 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
1872 if (!ddc_node) { 1796 if (!ddc_node) {
1873 DRM_ERROR("Failed to find ddc node in device tree\n"); 1797 DRM_ERROR("Failed to find ddc node in device tree\n");
@@ -1885,7 +1809,6 @@ out_get_ddc_adpt:
1885 if (phy_node) 1809 if (phy_node)
1886 goto out_get_phy_port; 1810 goto out_get_phy_port;
1887 1811
1888 /* hdmiphy i2c driver */
1889 phy_node = of_parse_phandle(dev->of_node, "phy", 0); 1812 phy_node = of_parse_phandle(dev->of_node, "phy", 0);
1890 if (!phy_node) { 1813 if (!phy_node) {
1891 DRM_ERROR("Failed to find hdmiphy node in device tree\n"); 1814 DRM_ERROR("Failed to find hdmiphy node in device tree\n");
@@ -1929,6 +1852,16 @@ out_get_phy_port:
1929 goto err_hdmiphy; 1852 goto err_hdmiphy;
1930 } 1853 }
1931 1854
1855 if (hdata->drv_data->has_sysreg) {
1856 hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
1857 "samsung,sysreg-phandle");
1858 if (IS_ERR(hdata->sysreg)) {
1859 DRM_ERROR("sysreg regmap lookup failed.\n");
1860 ret = -EPROBE_DEFER;
1861 goto err_hdmiphy;
1862 }
1863 }
1864
1932 pm_runtime_enable(dev); 1865 pm_runtime_enable(dev);
1933 1866
1934 ret = component_add(&pdev->dev, &hdmi_component_ops); 1867 ret = component_add(&pdev->dev, &hdmi_component_ops);
@@ -1975,8 +1908,7 @@ static int exynos_hdmi_suspend(struct device *dev)
1975{ 1908{
1976 struct hdmi_context *hdata = dev_get_drvdata(dev); 1909 struct hdmi_context *hdata = dev_get_drvdata(dev);
1977 1910
1978 clk_disable_unprepare(hdata->sclk_hdmi); 1911 hdmi_clk_disable_gates(hdata);
1979 clk_disable_unprepare(hdata->hdmi);
1980 1912
1981 return 0; 1913 return 0;
1982} 1914}
@@ -1986,17 +1918,9 @@ static int exynos_hdmi_resume(struct device *dev)
1986 struct hdmi_context *hdata = dev_get_drvdata(dev); 1918 struct hdmi_context *hdata = dev_get_drvdata(dev);
1987 int ret; 1919 int ret;
1988 1920
1989 ret = clk_prepare_enable(hdata->hdmi); 1921 ret = hdmi_clk_enable_gates(hdata);
1990 if (ret < 0) { 1922 if (ret < 0)
1991 DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
1992 return ret;
1993 }
1994 ret = clk_prepare_enable(hdata->sclk_hdmi);
1995 if (ret < 0) {
1996 DRM_ERROR("Failed to prepare_enable the sclk_mixer clk [%d]\n",
1997 ret);
1998 return ret; 1923 return ret;
1999 }
2000 1924
2001 return 0; 1925 return 0;
2002} 1926}
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 0a5a60005f7e..74a4269cc1b0 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -31,6 +31,7 @@
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/regulator/consumer.h> 32#include <linux/regulator/consumer.h>
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/of_device.h>
34#include <linux/component.h> 35#include <linux/component.h>
35 36
36#include <drm/exynos_drm.h> 37#include <drm/exynos_drm.h>
@@ -103,8 +104,6 @@ struct mixer_context {
103 104
104 struct mixer_resources mixer_res; 105 struct mixer_resources mixer_res;
105 enum mixer_version_id mxr_ver; 106 enum mixer_version_id mxr_ver;
106 wait_queue_head_t wait_vsync_queue;
107 atomic_t wait_vsync_event;
108}; 107};
109 108
110struct mixer_drv_data { 109struct mixer_drv_data {
@@ -787,12 +786,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
787 786
788 exynos_drm_crtc_finish_update(ctx->crtc, plane); 787 exynos_drm_crtc_finish_update(ctx->crtc, plane);
789 } 788 }
790
791 /* set wait vsync event to zero and wake up queue. */
792 if (atomic_read(&ctx->wait_vsync_event)) {
793 atomic_set(&ctx->wait_vsync_event, 0);
794 wake_up(&ctx->wait_vsync_queue);
795 }
796 } 789 }
797 790
798out: 791out:
@@ -1027,34 +1020,6 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
1027 mixer_vsync_set_update(mixer_ctx, true); 1020 mixer_vsync_set_update(mixer_ctx, true);
1028} 1021}
1029 1022
1030static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
1031{
1032 struct mixer_context *mixer_ctx = crtc->ctx;
1033 int err;
1034
1035 if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
1036 return;
1037
1038 err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe);
1039 if (err < 0) {
1040 DRM_DEBUG_KMS("failed to acquire vblank counter\n");
1041 return;
1042 }
1043
1044 atomic_set(&mixer_ctx->wait_vsync_event, 1);
1045
1046 /*
1047 * wait for MIXER to signal VSYNC interrupt or return after
1048 * timeout which is set to 50ms (refresh rate of 20).
1049 */
1050 if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
1051 !atomic_read(&mixer_ctx->wait_vsync_event),
1052 HZ/20))
1053 DRM_DEBUG_KMS("vblank wait timed out.\n");
1054
1055 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
1056}
1057
1058static void mixer_enable(struct exynos_drm_crtc *crtc) 1023static void mixer_enable(struct exynos_drm_crtc *crtc)
1059{ 1024{
1060 struct mixer_context *ctx = crtc->ctx; 1025 struct mixer_context *ctx = crtc->ctx;
@@ -1065,6 +1030,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
1065 1030
1066 pm_runtime_get_sync(ctx->dev); 1031 pm_runtime_get_sync(ctx->dev);
1067 1032
1033 exynos_drm_pipe_clk_enable(crtc, true);
1034
1068 mixer_vsync_set_update(ctx, false); 1035 mixer_vsync_set_update(ctx, false);
1069 1036
1070 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); 1037 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
@@ -1094,6 +1061,8 @@ static void mixer_disable(struct exynos_drm_crtc *crtc)
1094 for (i = 0; i < MIXER_WIN_NR; i++) 1061 for (i = 0; i < MIXER_WIN_NR; i++)
1095 mixer_disable_plane(crtc, &ctx->planes[i]); 1062 mixer_disable_plane(crtc, &ctx->planes[i]);
1096 1063
1064 exynos_drm_pipe_clk_enable(crtc, false);
1065
1097 pm_runtime_put(ctx->dev); 1066 pm_runtime_put(ctx->dev);
1098 1067
1099 clear_bit(MXR_BIT_POWERED, &ctx->flags); 1068 clear_bit(MXR_BIT_POWERED, &ctx->flags);
@@ -1126,7 +1095,6 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
1126 .disable = mixer_disable, 1095 .disable = mixer_disable,
1127 .enable_vblank = mixer_enable_vblank, 1096 .enable_vblank = mixer_enable_vblank,
1128 .disable_vblank = mixer_disable_vblank, 1097 .disable_vblank = mixer_disable_vblank,
1129 .wait_for_vblank = mixer_wait_for_vblank,
1130 .atomic_begin = mixer_atomic_begin, 1098 .atomic_begin = mixer_atomic_begin,
1131 .update_plane = mixer_update_plane, 1099 .update_plane = mixer_update_plane,
1132 .disable_plane = mixer_disable_plane, 1100 .disable_plane = mixer_disable_plane,
@@ -1155,18 +1123,6 @@ static struct mixer_drv_data exynos4210_mxr_drv_data = {
1155 .has_sclk = 1, 1123 .has_sclk = 1,
1156}; 1124};
1157 1125
1158static const struct platform_device_id mixer_driver_types[] = {
1159 {
1160 .name = "s5p-mixer",
1161 .driver_data = (unsigned long)&exynos4210_mxr_drv_data,
1162 }, {
1163 .name = "exynos5-mixer",
1164 .driver_data = (unsigned long)&exynos5250_mxr_drv_data,
1165 }, {
1166 /* end node */
1167 }
1168};
1169
1170static struct of_device_id mixer_match_types[] = { 1126static struct of_device_id mixer_match_types[] = {
1171 { 1127 {
1172 .compatible = "samsung,exynos4210-mixer", 1128 .compatible = "samsung,exynos4210-mixer",
@@ -1243,7 +1199,7 @@ static const struct component_ops mixer_component_ops = {
1243static int mixer_probe(struct platform_device *pdev) 1199static int mixer_probe(struct platform_device *pdev)
1244{ 1200{
1245 struct device *dev = &pdev->dev; 1201 struct device *dev = &pdev->dev;
1246 struct mixer_drv_data *drv; 1202 const struct mixer_drv_data *drv;
1247 struct mixer_context *ctx; 1203 struct mixer_context *ctx;
1248 int ret; 1204 int ret;
1249 1205
@@ -1253,23 +1209,13 @@ static int mixer_probe(struct platform_device *pdev)
1253 return -ENOMEM; 1209 return -ENOMEM;
1254 } 1210 }
1255 1211
1256 if (dev->of_node) { 1212 drv = of_device_get_match_data(dev);
1257 const struct of_device_id *match;
1258
1259 match = of_match_node(mixer_match_types, dev->of_node);
1260 drv = (struct mixer_drv_data *)match->data;
1261 } else {
1262 drv = (struct mixer_drv_data *)
1263 platform_get_device_id(pdev)->driver_data;
1264 }
1265 1213
1266 ctx->pdev = pdev; 1214 ctx->pdev = pdev;
1267 ctx->dev = dev; 1215 ctx->dev = dev;
1268 ctx->vp_enabled = drv->is_vp_enabled; 1216 ctx->vp_enabled = drv->is_vp_enabled;
1269 ctx->has_sclk = drv->has_sclk; 1217 ctx->has_sclk = drv->has_sclk;
1270 ctx->mxr_ver = drv->version; 1218 ctx->mxr_ver = drv->version;
1271 init_waitqueue_head(&ctx->wait_vsync_queue);
1272 atomic_set(&ctx->wait_vsync_event, 0);
1273 1219
1274 platform_set_drvdata(pdev, ctx); 1220 platform_set_drvdata(pdev, ctx);
1275 1221
@@ -1355,5 +1301,4 @@ struct platform_driver mixer_driver = {
1355 }, 1301 },
1356 .probe = mixer_probe, 1302 .probe = mixer_probe,
1357 .remove = mixer_remove, 1303 .remove = mixer_remove,
1358 .id_table = mixer_driver_types,
1359}; 1304};
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
index 8c891e59be21..169667a22bdc 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -586,10 +586,12 @@
586#define HDMI_TG_VACT_ST4_L HDMI_TG_BASE(0x0070) 586#define HDMI_TG_VACT_ST4_L HDMI_TG_BASE(0x0070)
587#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) 587#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074)
588#define HDMI_TG_3D HDMI_TG_BASE(0x00F0) 588#define HDMI_TG_3D HDMI_TG_BASE(0x00F0)
589#define HDMI_TG_DECON_EN HDMI_TG_BASE(0x01e0)
589 590
590/* HDMI PHY Registers Offsets*/ 591/* HDMI PHY Registers Offsets*/
591#define HDMIPHY_POWER (0x74 >> 2) 592#define HDMIPHY_POWER 0x74
592#define HDMIPHY_MODE_SET_DONE (0x7c >> 2) 593#define HDMIPHY_MODE_SET_DONE 0x7c
594#define HDMIPHY5433_MODE_SET_DONE 0x84
593 595
594/* HDMI PHY Values */ 596/* HDMI PHY Values */
595#define HDMI_PHY_POWER_ON 0x80 597#define HDMI_PHY_POWER_ON 0x80
@@ -603,4 +605,7 @@
603#define PMU_HDMI_PHY_CONTROL 0x700 605#define PMU_HDMI_PHY_CONTROL 0x700
604#define PMU_HDMI_PHY_ENABLE_BIT BIT(0) 606#define PMU_HDMI_PHY_ENABLE_BIT BIT(0)
605 607
608#define EXYNOS5433_SYSREG_DISP_HDMI_PHY 0x1008
609#define SYSREG_HDMI_REFCLK_INT_CLK 1
610
606#endif /* SAMSUNG_REGS_HDMI_H */ 611#endif /* SAMSUNG_REGS_HDMI_H */
diff --git a/include/video/exynos5433_decon.h b/include/video/exynos5433_decon.h
index c1c1ca18abc0..0098a522d9f4 100644
--- a/include/video/exynos5433_decon.h
+++ b/include/video/exynos5433_decon.h
@@ -179,9 +179,9 @@
179#define TRIGCON_TRIGMODE_W1BUF (1 << 10) 179#define TRIGCON_TRIGMODE_W1BUF (1 << 10)
180#define TRIGCON_SWTRIGCMD_W0BUF (1 << 6) 180#define TRIGCON_SWTRIGCMD_W0BUF (1 << 6)
181#define TRIGCON_TRIGMODE_W0BUF (1 << 5) 181#define TRIGCON_TRIGMODE_W0BUF (1 << 5)
182#define TRIGCON_HWTRIGMASK_I80_RGB (1 << 4) 182#define TRIGCON_HWTRIGMASK (1 << 4)
183#define TRIGCON_HWTRIGEN_I80_RGB (1 << 3) 183#define TRIGCON_HWTRIGEN (1 << 3)
184#define TRIGCON_HWTRIG_INV_I80_RGB (1 << 2) 184#define TRIGCON_HWTRIG_INV (1 << 2)
185#define TRIGCON_SWTRIGCMD (1 << 1) 185#define TRIGCON_SWTRIGCMD (1 << 1)
186#define TRIGCON_SWTRIGEN (1 << 0) 186#define TRIGCON_SWTRIGEN (1 << 0)
187 187