aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-03 23:41:11 -0400
committerDave Airlie <airlied@redhat.com>2014-06-03 23:41:11 -0400
commitb33a51e457b7e01e3e25eaa7c99aec32e65c00de (patch)
tree18db4abbdb05bd0cf97d320ab41e85af0eb2fe89
parent1c404d88b26170b82aa274e7a40c91aa33145942 (diff)
parentdf5225bc9a87f1589a17797ee8e193608e4f3a9e (diff)
Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
Summary: - Resolve probe order and deferred probe issue with component framework support. - Resolve hdmi dt broken issue. . HDMI DT support, which was broken since CCF (common clock framework) support, and considring legacy dt binding. - Consolidate HDMI part. . APB based phy support for Exynos5420 and later, and fixups related to power on/off sequence. - Consolidate IPP part. . Mostly bug fixups and code cleanups. - Trivial fixups and code cleanups. * 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (64 commits) drm/exynos: consider deferred probe case drm/exynos: remove unnecessary exynos_hdmi.h file drm/exynos/fimd: allow multiplatform configuration drm/exynos: add hdmiphy power on/off sequence drm/exynos: ipp: remove description of non-existing field drm/exynos: ipp: update comment for struct drm_ipp_buf_info drm/exynos: ipp: rearrange c_node->event_lock using routine drm/exynos: ipp: rearrange c_node->mem_lock using routines drm/exynos: ipp: add ipp_remove_id() drm/exynos: ipp: add cmd_lock for cmd_list drm/exynos: ipp: rename cmd_lock to lock drm/exynos: ipp: remove duplicated setting drm/exynos: ipp: remove usless list_empty() functions drm/exynos: Use PTR_ERR_OR_ZERO in exynos_dp_core.c drm/exynos: remove hardware overlays disable from fimd probe drm/exynos: Fix checkpatch warning in exynos_dp_reg.c drm/exynos: add fimd dependency to fimd related encoders drm/exynos: remove redundant mutex_unlock drm/exynos/fimc: simplify and rename fimc_dst_get_buf_seq drm/exynos/fimc: replace mutex by spinlock ...
-rw-r--r--Documentation/devicetree/bindings/video/exynos_dp.txt4
-rw-r--r--Documentation/devicetree/bindings/video/exynos_hdmi.txt3
-rw-r--r--drivers/gpu/drm/Kconfig4
-rw-r--r--drivers/gpu/drm/exynos/Kconfig8
-rw-r--r--drivers/gpu/drm/exynos/exynos_ddc.c63
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.c202
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_core.h60
-rw-r--r--drivers/gpu/drm/exynos/exynos_dp_reg.c46
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c216
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c17
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c65
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c446
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h87
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c114
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimc.c427
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c211
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c22
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gsc.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c258
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.h12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_rotator.c11
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c101
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c652
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.h23
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmiphy.c65
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c67
-rw-r--r--drivers/gpu/drm/exynos/regs-hdmi.h16
-rw-r--r--include/drm/drm_dp_helper.h2
30 files changed, 1807 insertions, 1419 deletions
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 57ccdde02c3a..53dbccfa80ca 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -62,6 +62,10 @@ Optional properties for dp-controller:
62 -hsync-active-high: 62 -hsync-active-high:
63 HSYNC polarity configuration. 63 HSYNC polarity configuration.
64 High if defined, Low if not defined 64 High if defined, Low if not defined
65 -samsung,hpd-gpio:
66 Hotplug detect GPIO.
67 Indicates which GPIO should be used for hotplug
68 detection
65 69
66Example: 70Example:
67 71
diff --git a/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
index f9187a259259..1fd8cf9cbfac 100644
--- a/Documentation/devicetree/bindings/video/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/video/exynos_hdmi.txt
@@ -5,6 +5,7 @@ Required properties:
5 1) "samsung,exynos5-hdmi" <DEPRECATED> 5 1) "samsung,exynos5-hdmi" <DEPRECATED>
6 2) "samsung,exynos4210-hdmi" 6 2) "samsung,exynos4210-hdmi"
7 3) "samsung,exynos4212-hdmi" 7 3) "samsung,exynos4212-hdmi"
8 4) "samsung,exynos5420-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.
@@ -27,6 +28,7 @@ Required properties:
27 "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi". 28 "hdmi", "sclk_hdmi", "sclk_pixel", "sclk_hdmiphy" and "mout_hdmi".
28- ddc: phandle to the hdmi ddc node 29- ddc: phandle to the hdmi ddc node
29- phy: phandle to the hdmi phy node 30- phy: phandle to the hdmi phy node
31- samsung,syscon-phandle: phandle for system controller node for PMU.
30 32
31Example: 33Example:
32 34
@@ -37,4 +39,5 @@ Example:
37 hpd-gpio = <&gpx3 7 1>; 39 hpd-gpio = <&gpx3 7 1>;
38 ddc = <&hdmi_ddc_node>; 40 ddc = <&hdmi_ddc_node>;
39 phy = <&hdmi_phy_node>; 41 phy = <&hdmi_phy_node>;
42 samsung,syscon-phandle = <&pmu_system_controller>;
40 }; 43 };
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index d1cc2f613a78..f5120046ff80 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -83,6 +83,8 @@ config DRM_KMS_CMA_HELPER
83 83
84source "drivers/gpu/drm/i2c/Kconfig" 84source "drivers/gpu/drm/i2c/Kconfig"
85 85
86source "drivers/gpu/drm/bridge/Kconfig"
87
86config DRM_TDFX 88config DRM_TDFX
87 tristate "3dfx Banshee/Voodoo3+" 89 tristate "3dfx Banshee/Voodoo3+"
88 depends on DRM && PCI 90 depends on DRM && PCI
@@ -199,5 +201,3 @@ source "drivers/gpu/drm/msm/Kconfig"
199source "drivers/gpu/drm/tegra/Kconfig" 201source "drivers/gpu/drm/tegra/Kconfig"
200 202
201source "drivers/gpu/drm/panel/Kconfig" 203source "drivers/gpu/drm/panel/Kconfig"
202
203source "drivers/gpu/drm/bridge/Kconfig"
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 5bf5bca94f56..178d2a9672a8 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -26,14 +26,14 @@ config DRM_EXYNOS_DMABUF
26 26
27config DRM_EXYNOS_FIMD 27config DRM_EXYNOS_FIMD
28 bool "Exynos DRM FIMD" 28 bool "Exynos DRM FIMD"
29 depends on DRM_EXYNOS && !FB_S3C && !ARCH_MULTIPLATFORM 29 depends on DRM_EXYNOS && !FB_S3C
30 select FB_MODE_HELPERS 30 select FB_MODE_HELPERS
31 help 31 help
32 Choose this option if you want to use Exynos FIMD for DRM. 32 Choose this option if you want to use Exynos FIMD for DRM.
33 33
34config DRM_EXYNOS_DPI 34config DRM_EXYNOS_DPI
35 bool "EXYNOS DRM parallel output support" 35 bool "EXYNOS DRM parallel output support"
36 depends on DRM_EXYNOS 36 depends on DRM_EXYNOS_FIMD
37 select DRM_PANEL 37 select DRM_PANEL
38 default n 38 default n
39 help 39 help
@@ -41,7 +41,7 @@ config DRM_EXYNOS_DPI
41 41
42config DRM_EXYNOS_DSI 42config DRM_EXYNOS_DSI
43 bool "EXYNOS DRM MIPI-DSI driver support" 43 bool "EXYNOS DRM MIPI-DSI driver support"
44 depends on DRM_EXYNOS 44 depends on DRM_EXYNOS_FIMD
45 select DRM_MIPI_DSI 45 select DRM_MIPI_DSI
46 select DRM_PANEL 46 select DRM_PANEL
47 default n 47 default n
@@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI
50 50
51config DRM_EXYNOS_DP 51config DRM_EXYNOS_DP
52 bool "EXYNOS DRM DP driver support" 52 bool "EXYNOS DRM DP driver support"
53 depends on DRM_EXYNOS && ARCH_EXYNOS 53 depends on DRM_EXYNOS_FIMD && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
54 default DRM_EXYNOS 54 default DRM_EXYNOS
55 help 55 help
56 This enables support for DP device. 56 This enables support for DP device.
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
deleted file mode 100644
index 6a8c84e7c839..000000000000
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Authors:
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <drm/drmP.h>
15
16#include <linux/kernel.h>
17#include <linux/i2c.h>
18#include <linux/of.h>
19
20#include "exynos_drm_drv.h"
21#include "exynos_hdmi.h"
22
23static int s5p_ddc_probe(struct i2c_client *client,
24 const struct i2c_device_id *dev_id)
25{
26 hdmi_attach_ddc_client(client);
27
28 dev_info(&client->adapter->dev,
29 "attached %s into i2c adapter successfully\n",
30 client->name);
31
32 return 0;
33}
34
35static int s5p_ddc_remove(struct i2c_client *client)
36{
37 dev_info(&client->adapter->dev,
38 "detached %s from i2c adapter successfully\n",
39 client->name);
40
41 return 0;
42}
43
44static struct of_device_id hdmiddc_match_types[] = {
45 {
46 .compatible = "samsung,exynos5-hdmiddc",
47 }, {
48 .compatible = "samsung,exynos4210-hdmiddc",
49 }, {
50 /* end node */
51 }
52};
53
54struct i2c_driver ddc_driver = {
55 .driver = {
56 .name = "exynos-hdmiddc",
57 .owner = THIS_MODULE,
58 .of_match_table = hdmiddc_match_types,
59 },
60 .probe = s5p_ddc_probe,
61 .remove = s5p_ddc_remove,
62 .command = NULL,
63};
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index bb74472b4e4b..5e05dbc60082 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -18,6 +18,9 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_gpio.h>
22#include <linux/gpio.h>
23#include <linux/component.h>
21#include <linux/phy/phy.h> 24#include <linux/phy/phy.h>
22#include <video/of_display_timing.h> 25#include <video/of_display_timing.h>
23#include <video/of_videomode.h> 26#include <video/of_videomode.h>
@@ -141,15 +144,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
141 return -EIO; 144 return -EIO;
142 } 145 }
143 146
144 exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST, 147 exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
145 &test_vector); 148 &test_vector);
146 if (test_vector & DPCD_TEST_EDID_READ) { 149 if (test_vector & DP_TEST_LINK_EDID_READ) {
147 exynos_dp_write_byte_to_dpcd(dp, 150 exynos_dp_write_byte_to_dpcd(dp,
148 DPCD_ADDR_TEST_EDID_CHECKSUM, 151 DP_TEST_EDID_CHECKSUM,
149 edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); 152 edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
150 exynos_dp_write_byte_to_dpcd(dp, 153 exynos_dp_write_byte_to_dpcd(dp,
151 DPCD_ADDR_TEST_RESPONSE, 154 DP_TEST_RESPONSE,
152 DPCD_TEST_EDID_CHECKSUM_WRITE); 155 DP_TEST_EDID_CHECKSUM_WRITE);
153 } 156 }
154 } else { 157 } else {
155 dev_info(dp->dev, "EDID data does not include any extensions.\n"); 158 dev_info(dp->dev, "EDID data does not include any extensions.\n");
@@ -171,15 +174,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
171 } 174 }
172 175
173 exynos_dp_read_byte_from_dpcd(dp, 176 exynos_dp_read_byte_from_dpcd(dp,
174 DPCD_ADDR_TEST_REQUEST, 177 DP_TEST_REQUEST,
175 &test_vector); 178 &test_vector);
176 if (test_vector & DPCD_TEST_EDID_READ) { 179 if (test_vector & DP_TEST_LINK_EDID_READ) {
177 exynos_dp_write_byte_to_dpcd(dp, 180 exynos_dp_write_byte_to_dpcd(dp,
178 DPCD_ADDR_TEST_EDID_CHECKSUM, 181 DP_TEST_EDID_CHECKSUM,
179 edid[EDID_CHECKSUM]); 182 edid[EDID_CHECKSUM]);
180 exynos_dp_write_byte_to_dpcd(dp, 183 exynos_dp_write_byte_to_dpcd(dp,
181 DPCD_ADDR_TEST_RESPONSE, 184 DP_TEST_RESPONSE,
182 DPCD_TEST_EDID_CHECKSUM_WRITE); 185 DP_TEST_EDID_CHECKSUM_WRITE);
183 } 186 }
184 } 187 }
185 188
@@ -193,8 +196,8 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
193 int i; 196 int i;
194 int retval; 197 int retval;
195 198
196 /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ 199 /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
197 retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV, 200 retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
198 12, buf); 201 12, buf);
199 if (retval) 202 if (retval)
200 return retval; 203 return retval;
@@ -214,14 +217,14 @@ static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
214{ 217{
215 u8 data; 218 u8 data;
216 219
217 exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data); 220 exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
218 221
219 if (enable) 222 if (enable)
220 exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, 223 exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
221 DPCD_ENHANCED_FRAME_EN | 224 DP_LANE_COUNT_ENHANCED_FRAME_EN |
222 DPCD_LANE_COUNT_SET(data)); 225 DPCD_LANE_COUNT_SET(data));
223 else 226 else
224 exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, 227 exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
225 DPCD_LANE_COUNT_SET(data)); 228 DPCD_LANE_COUNT_SET(data));
226} 229}
227 230
@@ -230,7 +233,7 @@ static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
230 u8 data; 233 u8 data;
231 int retval; 234 int retval;
232 235
233 exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data); 236 exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
234 retval = DPCD_ENHANCED_FRAME_CAP(data); 237 retval = DPCD_ENHANCED_FRAME_CAP(data);
235 238
236 return retval; 239 return retval;
@@ -250,8 +253,8 @@ static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
250 exynos_dp_set_training_pattern(dp, DP_NONE); 253 exynos_dp_set_training_pattern(dp, DP_NONE);
251 254
252 exynos_dp_write_byte_to_dpcd(dp, 255 exynos_dp_write_byte_to_dpcd(dp,
253 DPCD_ADDR_TRAINING_PATTERN_SET, 256 DP_TRAINING_PATTERN_SET,
254 DPCD_TRAINING_PATTERN_DISABLED); 257 DP_TRAINING_PATTERN_DISABLE);
255} 258}
256 259
257static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp, 260static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
@@ -295,7 +298,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
295 /* Setup RX configuration */ 298 /* Setup RX configuration */
296 buf[0] = dp->link_train.link_rate; 299 buf[0] = dp->link_train.link_rate;
297 buf[1] = dp->link_train.lane_count; 300 buf[1] = dp->link_train.lane_count;
298 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, 301 retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
299 2, buf); 302 2, buf);
300 if (retval) 303 if (retval)
301 return retval; 304 return retval;
@@ -322,16 +325,16 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
322 325
323 /* Set RX training pattern */ 326 /* Set RX training pattern */
324 retval = exynos_dp_write_byte_to_dpcd(dp, 327 retval = exynos_dp_write_byte_to_dpcd(dp,
325 DPCD_ADDR_TRAINING_PATTERN_SET, 328 DP_TRAINING_PATTERN_SET,
326 DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1); 329 DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
327 if (retval) 330 if (retval)
328 return retval; 331 return retval;
329 332
330 for (lane = 0; lane < lane_count; lane++) 333 for (lane = 0; lane < lane_count; lane++)
331 buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | 334 buf[lane] = DP_TRAIN_PRE_EMPHASIS_0 |
332 DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; 335 DP_TRAIN_VOLTAGE_SWING_400;
333 336
334 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, 337 retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
335 lane_count, buf); 338 lane_count, buf);
336 339
337 return retval; 340 return retval;
@@ -352,7 +355,7 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
352 355
353 for (lane = 0; lane < lane_count; lane++) { 356 for (lane = 0; lane < lane_count; lane++) {
354 lane_status = exynos_dp_get_lane_status(link_status, lane); 357 lane_status = exynos_dp_get_lane_status(link_status, lane);
355 if ((lane_status & DPCD_LANE_CR_DONE) == 0) 358 if ((lane_status & DP_LANE_CR_DONE) == 0)
356 return -EINVAL; 359 return -EINVAL;
357 } 360 }
358 return 0; 361 return 0;
@@ -364,13 +367,13 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
364 int lane; 367 int lane;
365 u8 lane_status; 368 u8 lane_status;
366 369
367 if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0) 370 if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0)
368 return -EINVAL; 371 return -EINVAL;
369 372
370 for (lane = 0; lane < lane_count; lane++) { 373 for (lane = 0; lane < lane_count; lane++) {
371 lane_status = exynos_dp_get_lane_status(link_status, lane); 374 lane_status = exynos_dp_get_lane_status(link_status, lane);
372 lane_status &= DPCD_CHANNEL_EQ_BITS; 375 lane_status &= DP_CHANNEL_EQ_BITS;
373 if (lane_status != DPCD_CHANNEL_EQ_BITS) 376 if (lane_status != DP_CHANNEL_EQ_BITS)
374 return -EINVAL; 377 return -EINVAL;
375 } 378 }
376 379
@@ -468,9 +471,9 @@ static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
468 DPCD_PRE_EMPHASIS_SET(pre_emphasis); 471 DPCD_PRE_EMPHASIS_SET(pre_emphasis);
469 472
470 if (voltage_swing == VOLTAGE_LEVEL_3) 473 if (voltage_swing == VOLTAGE_LEVEL_3)
471 training_lane |= DPCD_MAX_SWING_REACHED; 474 training_lane |= DP_TRAIN_MAX_SWING_REACHED;
472 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) 475 if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
473 training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; 476 training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
474 477
475 dp->link_train.training_lane[lane] = training_lane; 478 dp->link_train.training_lane[lane] = training_lane;
476 } 479 }
@@ -487,12 +490,12 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
487 lane_count = dp->link_train.lane_count; 490 lane_count = dp->link_train.lane_count;
488 491
489 retval = exynos_dp_read_bytes_from_dpcd(dp, 492 retval = exynos_dp_read_bytes_from_dpcd(dp,
490 DPCD_ADDR_LANE0_1_STATUS, 2, link_status); 493 DP_LANE0_1_STATUS, 2, link_status);
491 if (retval) 494 if (retval)
492 return retval; 495 return retval;
493 496
494 retval = exynos_dp_read_bytes_from_dpcd(dp, 497 retval = exynos_dp_read_bytes_from_dpcd(dp,
495 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 498 DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
496 if (retval) 499 if (retval)
497 return retval; 500 return retval;
498 501
@@ -501,9 +504,9 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
501 exynos_dp_set_training_pattern(dp, TRAINING_PTN2); 504 exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
502 505
503 retval = exynos_dp_write_byte_to_dpcd(dp, 506 retval = exynos_dp_write_byte_to_dpcd(dp,
504 DPCD_ADDR_TRAINING_PATTERN_SET, 507 DP_TRAINING_PATTERN_SET,
505 DPCD_SCRAMBLING_DISABLED | 508 DP_LINK_SCRAMBLING_DISABLE |
506 DPCD_TRAINING_PATTERN_2); 509 DP_TRAINING_PATTERN_2);
507 if (retval) 510 if (retval)
508 return retval; 511 return retval;
509 512
@@ -543,7 +546,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
543 dp->link_train.training_lane[lane], lane); 546 dp->link_train.training_lane[lane], lane);
544 547
545 retval = exynos_dp_write_bytes_to_dpcd(dp, 548 retval = exynos_dp_write_bytes_to_dpcd(dp,
546 DPCD_ADDR_TRAINING_LANE0_SET, lane_count, 549 DP_TRAINING_LANE0_SET, lane_count,
547 dp->link_train.training_lane); 550 dp->link_train.training_lane);
548 if (retval) 551 if (retval)
549 return retval; 552 return retval;
@@ -562,7 +565,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
562 lane_count = dp->link_train.lane_count; 565 lane_count = dp->link_train.lane_count;
563 566
564 retval = exynos_dp_read_bytes_from_dpcd(dp, 567 retval = exynos_dp_read_bytes_from_dpcd(dp,
565 DPCD_ADDR_LANE0_1_STATUS, 2, link_status); 568 DP_LANE0_1_STATUS, 2, link_status);
566 if (retval) 569 if (retval)
567 return retval; 570 return retval;
568 571
@@ -572,12 +575,12 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
572 } 575 }
573 576
574 retval = exynos_dp_read_bytes_from_dpcd(dp, 577 retval = exynos_dp_read_bytes_from_dpcd(dp,
575 DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 578 DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
576 if (retval) 579 if (retval)
577 return retval; 580 return retval;
578 581
579 retval = exynos_dp_read_byte_from_dpcd(dp, 582 retval = exynos_dp_read_byte_from_dpcd(dp,
580 DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align); 583 DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
581 if (retval) 584 if (retval)
582 return retval; 585 return retval;
583 586
@@ -619,7 +622,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
619 exynos_dp_set_lane_link_training(dp, 622 exynos_dp_set_lane_link_training(dp,
620 dp->link_train.training_lane[lane], lane); 623 dp->link_train.training_lane[lane], lane);
621 624
622 retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, 625 retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
623 lane_count, dp->link_train.training_lane); 626 lane_count, dp->link_train.training_lane);
624 627
625 return retval; 628 return retval;
@@ -634,7 +637,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
634 * For DP rev.1.1, Maximum link rate of Main Link lanes 637 * For DP rev.1.1, Maximum link rate of Main Link lanes
635 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps 638 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
636 */ 639 */
637 exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data); 640 exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
638 *bandwidth = data; 641 *bandwidth = data;
639} 642}
640 643
@@ -647,7 +650,7 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
647 * For DP rev.1.1, Maximum number of Main Link lanes 650 * For DP rev.1.1, Maximum number of Main Link lanes
648 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes 651 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
649 */ 652 */
650 exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data); 653 exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data);
651 *lane_count = DPCD_MAX_LANE_COUNT(data); 654 *lane_count = DPCD_MAX_LANE_COUNT(data);
652} 655}
653 656
@@ -819,20 +822,20 @@ static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
819 exynos_dp_enable_scrambling(dp); 822 exynos_dp_enable_scrambling(dp);
820 823
821 exynos_dp_read_byte_from_dpcd(dp, 824 exynos_dp_read_byte_from_dpcd(dp,
822 DPCD_ADDR_TRAINING_PATTERN_SET, 825 DP_TRAINING_PATTERN_SET,
823 &data); 826 &data);
824 exynos_dp_write_byte_to_dpcd(dp, 827 exynos_dp_write_byte_to_dpcd(dp,
825 DPCD_ADDR_TRAINING_PATTERN_SET, 828 DP_TRAINING_PATTERN_SET,
826 (u8)(data & ~DPCD_SCRAMBLING_DISABLED)); 829 (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
827 } else { 830 } else {
828 exynos_dp_disable_scrambling(dp); 831 exynos_dp_disable_scrambling(dp);
829 832
830 exynos_dp_read_byte_from_dpcd(dp, 833 exynos_dp_read_byte_from_dpcd(dp,
831 DPCD_ADDR_TRAINING_PATTERN_SET, 834 DP_TRAINING_PATTERN_SET,
832 &data); 835 &data);
833 exynos_dp_write_byte_to_dpcd(dp, 836 exynos_dp_write_byte_to_dpcd(dp,
834 DPCD_ADDR_TRAINING_PATTERN_SET, 837 DP_TRAINING_PATTERN_SET,
835 (u8)(data | DPCD_SCRAMBLING_DISABLED)); 838 (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
836 } 839 }
837} 840}
838 841
@@ -962,16 +965,6 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
962 .best_encoder = exynos_dp_best_encoder, 965 .best_encoder = exynos_dp_best_encoder,
963}; 966};
964 967
965static int exynos_dp_initialize(struct exynos_drm_display *display,
966 struct drm_device *drm_dev)
967{
968 struct exynos_dp_device *dp = display->ctx;
969
970 dp->drm_dev = drm_dev;
971
972 return 0;
973}
974
975static bool find_bridge(const char *compat, struct bridge_init *bridge) 968static bool find_bridge(const char *compat, struct bridge_init *bridge)
976{ 969{
977 bridge->client = NULL; 970 bridge->client = NULL;
@@ -1099,7 +1092,6 @@ static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
1099} 1092}
1100 1093
1101static struct exynos_drm_display_ops exynos_dp_display_ops = { 1094static struct exynos_drm_display_ops exynos_dp_display_ops = {
1102 .initialize = exynos_dp_initialize,
1103 .create_connector = exynos_dp_create_connector, 1095 .create_connector = exynos_dp_create_connector,
1104 .dpms = exynos_dp_dpms, 1096 .dpms = exynos_dp_dpms,
1105}; 1097};
@@ -1116,10 +1108,8 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
1116 1108
1117 dp_video_config = devm_kzalloc(dev, 1109 dp_video_config = devm_kzalloc(dev,
1118 sizeof(*dp_video_config), GFP_KERNEL); 1110 sizeof(*dp_video_config), GFP_KERNEL);
1119 if (!dp_video_config) { 1111 if (!dp_video_config)
1120 dev_err(dev, "memory allocation for video config failed\n");
1121 return ERR_PTR(-ENOMEM); 1112 return ERR_PTR(-ENOMEM);
1122 }
1123 1113
1124 dp_video_config->h_sync_polarity = 1114 dp_video_config->h_sync_polarity =
1125 of_property_read_bool(dp_node, "hsync-active-high"); 1115 of_property_read_bool(dp_node, "hsync-active-high");
@@ -1178,10 +1168,7 @@ static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
1178 dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); 1168 dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
1179 if (!dp_phy_node) { 1169 if (!dp_phy_node) {
1180 dp->phy = devm_phy_get(dp->dev, "dp"); 1170 dp->phy = devm_phy_get(dp->dev, "dp");
1181 if (IS_ERR(dp->phy)) 1171 return PTR_ERR_OR_ZERO(dp->phy);
1182 return PTR_ERR(dp->phy);
1183 else
1184 return 0;
1185 } 1172 }
1186 1173
1187 if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) { 1174 if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
@@ -1223,19 +1210,20 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
1223 return 0; 1210 return 0;
1224} 1211}
1225 1212
1226static int exynos_dp_probe(struct platform_device *pdev) 1213static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
1227{ 1214{
1215 struct platform_device *pdev = to_platform_device(dev);
1216 struct drm_device *drm_dev = data;
1228 struct resource *res; 1217 struct resource *res;
1229 struct exynos_dp_device *dp; 1218 struct exynos_dp_device *dp;
1219 unsigned int irq_flags;
1230 1220
1231 int ret = 0; 1221 int ret = 0;
1232 1222
1233 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 1223 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
1234 GFP_KERNEL); 1224 GFP_KERNEL);
1235 if (!dp) { 1225 if (!dp)
1236 dev_err(&pdev->dev, "no memory for device data\n");
1237 return -ENOMEM; 1226 return -ENOMEM;
1238 }
1239 1227
1240 dp->dev = &pdev->dev; 1228 dp->dev = &pdev->dev;
1241 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1229 dp->dpms_mode = DRM_MODE_DPMS_OFF;
@@ -1266,7 +1254,30 @@ static int exynos_dp_probe(struct platform_device *pdev)
1266 if (IS_ERR(dp->reg_base)) 1254 if (IS_ERR(dp->reg_base))
1267 return PTR_ERR(dp->reg_base); 1255 return PTR_ERR(dp->reg_base);
1268 1256
1269 dp->irq = platform_get_irq(pdev, 0); 1257 dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0);
1258
1259 if (gpio_is_valid(dp->hpd_gpio)) {
1260 /*
1261 * Set up the hotplug GPIO from the device tree as an interrupt.
1262 * Simply specifying a different interrupt in the device tree
1263 * doesn't work since we handle hotplug rather differently when
1264 * using a GPIO. We also need the actual GPIO specifier so
1265 * that we can get the current state of the GPIO.
1266 */
1267 ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN,
1268 "hpd_gpio");
1269 if (ret) {
1270 dev_err(&pdev->dev, "failed to get hpd gpio\n");
1271 return ret;
1272 }
1273 dp->irq = gpio_to_irq(dp->hpd_gpio);
1274 irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
1275 } else {
1276 dp->hpd_gpio = -ENODEV;
1277 dp->irq = platform_get_irq(pdev, 0);
1278 irq_flags = 0;
1279 }
1280
1270 if (dp->irq == -ENXIO) { 1281 if (dp->irq == -ENXIO) {
1271 dev_err(&pdev->dev, "failed to get irq\n"); 1282 dev_err(&pdev->dev, "failed to get irq\n");
1272 return -ENODEV; 1283 return -ENODEV;
@@ -1278,28 +1289,61 @@ static int exynos_dp_probe(struct platform_device *pdev)
1278 1289
1279 exynos_dp_init_dp(dp); 1290 exynos_dp_init_dp(dp);
1280 1291
1281 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, 1292 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
1282 "exynos-dp", dp); 1293 irq_flags, "exynos-dp", dp);
1283 if (ret) { 1294 if (ret) {
1284 dev_err(&pdev->dev, "failed to request irq\n"); 1295 dev_err(&pdev->dev, "failed to request irq\n");
1285 return ret; 1296 return ret;
1286 } 1297 }
1287 disable_irq(dp->irq); 1298 disable_irq(dp->irq);
1288 1299
1300 dp->drm_dev = drm_dev;
1289 exynos_dp_display.ctx = dp; 1301 exynos_dp_display.ctx = dp;
1290 1302
1291 platform_set_drvdata(pdev, &exynos_dp_display); 1303 platform_set_drvdata(pdev, &exynos_dp_display);
1292 exynos_drm_display_register(&exynos_dp_display);
1293 1304
1294 return 0; 1305 return exynos_drm_create_enc_conn(drm_dev, &exynos_dp_display);
1295} 1306}
1296 1307
1297static int exynos_dp_remove(struct platform_device *pdev) 1308static void exynos_dp_unbind(struct device *dev, struct device *master,
1309 void *data)
1298{ 1310{
1299 struct exynos_drm_display *display = platform_get_drvdata(pdev); 1311 struct exynos_drm_display *display = dev_get_drvdata(dev);
1312 struct exynos_dp_device *dp = display->ctx;
1313 struct drm_encoder *encoder = dp->encoder;
1300 1314
1301 exynos_dp_dpms(display, DRM_MODE_DPMS_OFF); 1315 exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
1302 exynos_drm_display_unregister(&exynos_dp_display); 1316
1317 encoder->funcs->destroy(encoder);
1318 drm_connector_cleanup(&dp->connector);
1319}
1320
1321static const struct component_ops exynos_dp_ops = {
1322 .bind = exynos_dp_bind,
1323 .unbind = exynos_dp_unbind,
1324};
1325
1326static int exynos_dp_probe(struct platform_device *pdev)
1327{
1328 int ret;
1329
1330 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1331 exynos_dp_display.type);
1332 if (ret)
1333 return ret;
1334
1335 ret = component_add(&pdev->dev, &exynos_dp_ops);
1336 if (ret)
1337 exynos_drm_component_del(&pdev->dev,
1338 EXYNOS_DEVICE_TYPE_CONNECTOR);
1339
1340 return ret;
1341}
1342
1343static int exynos_dp_remove(struct platform_device *pdev)
1344{
1345 component_del(&pdev->dev, &exynos_dp_ops);
1346 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1303 1347
1304 return 0; 1348 return 0;
1305} 1349}
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index d6a900d4ee40..02cc4f9ab903 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -14,6 +14,7 @@
14#define _EXYNOS_DP_CORE_H 14#define _EXYNOS_DP_CORE_H
15 15
16#include <drm/drm_crtc.h> 16#include <drm/drm_crtc.h>
17#include <drm/drm_dp_helper.h>
17#include <drm/exynos_drm.h> 18#include <drm/exynos_drm.h>
18 19
19#define DP_TIMEOUT_LOOP_COUNT 100 20#define DP_TIMEOUT_LOOP_COUNT 100
@@ -159,6 +160,7 @@ struct exynos_dp_device {
159 struct work_struct hotplug_work; 160 struct work_struct hotplug_work;
160 struct phy *phy; 161 struct phy *phy;
161 int dpms_mode; 162 int dpms_mode;
163 int hpd_gpio;
162 164
163 struct exynos_drm_panel_info panel; 165 struct exynos_drm_panel_info panel;
164}; 166};
@@ -261,69 +263,17 @@ void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
261#define EDID_EXTENSION_FLAG 0x7e 263#define EDID_EXTENSION_FLAG 0x7e
262#define EDID_CHECKSUM 0x7f 264#define EDID_CHECKSUM 0x7f
263 265
264/* Definition for DPCD Register */ 266/* DP_MAX_LANE_COUNT */
265#define DPCD_ADDR_DPCD_REV 0x0000
266#define DPCD_ADDR_MAX_LINK_RATE 0x0001
267#define DPCD_ADDR_MAX_LANE_COUNT 0x0002
268#define DPCD_ADDR_LINK_BW_SET 0x0100
269#define DPCD_ADDR_LANE_COUNT_SET 0x0101
270#define DPCD_ADDR_TRAINING_PATTERN_SET 0x0102
271#define DPCD_ADDR_TRAINING_LANE0_SET 0x0103
272#define DPCD_ADDR_LANE0_1_STATUS 0x0202
273#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED 0x0204
274#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1 0x0206
275#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3 0x0207
276#define DPCD_ADDR_TEST_REQUEST 0x0218
277#define DPCD_ADDR_TEST_RESPONSE 0x0260
278#define DPCD_ADDR_TEST_EDID_CHECKSUM 0x0261
279#define DPCD_ADDR_SINK_POWER_STATE 0x0600
280
281/* DPCD_ADDR_MAX_LANE_COUNT */
282#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) 267#define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
283#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) 268#define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
284 269
285/* DPCD_ADDR_LANE_COUNT_SET */ 270/* DP_LANE_COUNT_SET */
286#define DPCD_ENHANCED_FRAME_EN (0x1 << 7)
287#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f) 271#define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f)
288 272
289/* DPCD_ADDR_TRAINING_PATTERN_SET */ 273/* DP_TRAINING_LANE0_SET */
290#define DPCD_SCRAMBLING_DISABLED (0x1 << 5)
291#define DPCD_SCRAMBLING_ENABLED (0x0 << 5)
292#define DPCD_TRAINING_PATTERN_2 (0x2 << 0)
293#define DPCD_TRAINING_PATTERN_1 (0x1 << 0)
294#define DPCD_TRAINING_PATTERN_DISABLED (0x0 << 0)
295
296/* DPCD_ADDR_TRAINING_LANE0_SET */
297#define DPCD_MAX_PRE_EMPHASIS_REACHED (0x1 << 5)
298#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3) 274#define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3)
299#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3) 275#define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3)
300#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 (0x0 << 3)
301#define DPCD_MAX_SWING_REACHED (0x1 << 2)
302#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0) 276#define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0)
303#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3) 277#define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3)
304#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0 (0x0 << 0)
305
306/* DPCD_ADDR_LANE0_1_STATUS */
307#define DPCD_LANE_SYMBOL_LOCKED (0x1 << 2)
308#define DPCD_LANE_CHANNEL_EQ_DONE (0x1 << 1)
309#define DPCD_LANE_CR_DONE (0x1 << 0)
310#define DPCD_CHANNEL_EQ_BITS (DPCD_LANE_CR_DONE| \
311 DPCD_LANE_CHANNEL_EQ_DONE|\
312 DPCD_LANE_SYMBOL_LOCKED)
313
314/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */
315#define DPCD_LINK_STATUS_UPDATED (0x1 << 7)
316#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED (0x1 << 6)
317#define DPCD_INTERLANE_ALIGN_DONE (0x1 << 0)
318
319/* DPCD_ADDR_TEST_REQUEST */
320#define DPCD_TEST_EDID_READ (0x1 << 2)
321
322/* DPCD_ADDR_TEST_RESPONSE */
323#define DPCD_TEST_EDID_CHECKSUM_WRITE (0x1 << 2)
324
325/* DPCD_ADDR_SINK_POWER_STATE */
326#define DPCD_SET_POWER_STATE_D0 (0x1 << 0)
327#define DPCD_SET_POWER_STATE_D4 (0x2 << 0)
328 278
329#endif /* _EXYNOS_DP_CORE_H */ 279#endif /* _EXYNOS_DP_CORE_H */
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index b70da5052ff0..c1f87a2a9284 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/gpio.h>
16 17
17#include "exynos_dp_core.h" 18#include "exynos_dp_core.h"
18#include "exynos_dp_reg.h" 19#include "exynos_dp_reg.h"
@@ -326,6 +327,9 @@ void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp)
326{ 327{
327 u32 reg; 328 u32 reg;
328 329
330 if (gpio_is_valid(dp->hpd_gpio))
331 return;
332
329 reg = HOTPLUG_CHG | HPD_LOST | PLUG; 333 reg = HOTPLUG_CHG | HPD_LOST | PLUG;
330 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 334 writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
331 335
@@ -337,6 +341,9 @@ void exynos_dp_init_hpd(struct exynos_dp_device *dp)
337{ 341{
338 u32 reg; 342 u32 reg;
339 343
344 if (gpio_is_valid(dp->hpd_gpio))
345 return;
346
340 exynos_dp_clear_hotplug_interrupts(dp); 347 exynos_dp_clear_hotplug_interrupts(dp);
341 348
342 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 349 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
@@ -348,19 +355,27 @@ enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp)
348{ 355{
349 u32 reg; 356 u32 reg;
350 357
351 /* Parse hotplug interrupt status register */ 358 if (gpio_is_valid(dp->hpd_gpio)) {
352 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 359 reg = gpio_get_value(dp->hpd_gpio);
360 if (reg)
361 return DP_IRQ_TYPE_HP_CABLE_IN;
362 else
363 return DP_IRQ_TYPE_HP_CABLE_OUT;
364 } else {
365 /* Parse hotplug interrupt status register */
366 reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
353 367
354 if (reg & PLUG) 368 if (reg & PLUG)
355 return DP_IRQ_TYPE_HP_CABLE_IN; 369 return DP_IRQ_TYPE_HP_CABLE_IN;
356 370
357 if (reg & HPD_LOST) 371 if (reg & HPD_LOST)
358 return DP_IRQ_TYPE_HP_CABLE_OUT; 372 return DP_IRQ_TYPE_HP_CABLE_OUT;
359 373
360 if (reg & HOTPLUG_CHG) 374 if (reg & HOTPLUG_CHG)
361 return DP_IRQ_TYPE_HP_CHANGE; 375 return DP_IRQ_TYPE_HP_CHANGE;
362 376
363 return DP_IRQ_TYPE_UNKNOWN; 377 return DP_IRQ_TYPE_UNKNOWN;
378 }
364} 379}
365 380
366void exynos_dp_reset_aux(struct exynos_dp_device *dp) 381void exynos_dp_reset_aux(struct exynos_dp_device *dp)
@@ -386,7 +401,7 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
386 /* Disable AUX transaction H/W retry */ 401 /* Disable AUX transaction H/W retry */
387 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| 402 reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
388 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 403 AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
389 writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ; 404 writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
390 405
391 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ 406 /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
392 reg = DEFER_CTRL_EN | DEFER_COUNT(1); 407 reg = DEFER_CTRL_EN | DEFER_COUNT(1);
@@ -402,9 +417,14 @@ int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
402{ 417{
403 u32 reg; 418 u32 reg;
404 419
405 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 420 if (gpio_is_valid(dp->hpd_gpio)) {
406 if (reg & HPD_STATUS) 421 if (gpio_get_value(dp->hpd_gpio))
407 return 0; 422 return 0;
423 } else {
424 reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
425 if (reg & HPD_STATUS)
426 return 0;
427 }
408 428
409 return -EINVAL; 429 return -EINVAL;
410} 430}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 0e9e06ce36b8..4c9f972eaa07 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -19,21 +19,19 @@
19#include "exynos_drm_fbdev.h" 19#include "exynos_drm_fbdev.h"
20 20
21static LIST_HEAD(exynos_drm_subdrv_list); 21static LIST_HEAD(exynos_drm_subdrv_list);
22static LIST_HEAD(exynos_drm_manager_list);
23static LIST_HEAD(exynos_drm_display_list);
24 22
25static int exynos_drm_create_enc_conn(struct drm_device *dev, 23int exynos_drm_create_enc_conn(struct drm_device *dev,
26 struct exynos_drm_display *display) 24 struct exynos_drm_display *display)
27{ 25{
28 struct drm_encoder *encoder; 26 struct drm_encoder *encoder;
29 struct exynos_drm_manager *manager;
30 int ret; 27 int ret;
31 unsigned long possible_crtcs = 0; 28 unsigned long possible_crtcs = 0;
32 29
33 /* Find possible crtcs for this display */ 30 ret = exynos_drm_crtc_get_pipe_from_type(dev, display->type);
34 list_for_each_entry(manager, &exynos_drm_manager_list, list) 31 if (ret < 0)
35 if (manager->type == display->type) 32 return ret;
36 possible_crtcs |= 1 << manager->pipe; 33
34 possible_crtcs |= 1 << ret;
37 35
38 /* create and initialize a encoder for this sub driver. */ 36 /* create and initialize a encoder for this sub driver. */
39 encoder = exynos_drm_encoder_create(dev, display, possible_crtcs); 37 encoder = exynos_drm_encoder_create(dev, display, possible_crtcs);
@@ -57,127 +55,29 @@ err_destroy_encoder:
57 return ret; 55 return ret;
58} 56}
59 57
60static int exynos_drm_subdrv_probe(struct drm_device *dev, 58int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
61 struct exynos_drm_subdrv *subdrv)
62{
63 if (subdrv->probe) {
64 int ret;
65
66 subdrv->drm_dev = dev;
67
68 /*
69 * this probe callback would be called by sub driver
70 * after setting of all resources to this sub driver,
71 * such as clock, irq and register map are done or by load()
72 * of exynos drm driver.
73 *
74 * P.S. note that this driver is considered for modularization.
75 */
76 ret = subdrv->probe(dev, subdrv->dev);
77 if (ret)
78 return ret;
79 }
80
81 return 0;
82}
83
84static void exynos_drm_subdrv_remove(struct drm_device *dev,
85 struct exynos_drm_subdrv *subdrv)
86{
87 if (subdrv->remove)
88 subdrv->remove(dev, subdrv->dev);
89}
90
91int exynos_drm_initialize_managers(struct drm_device *dev)
92{ 59{
93 struct exynos_drm_manager *manager, *n; 60 if (!subdrv)
94 int ret, pipe = 0; 61 return -EINVAL;
95
96 list_for_each_entry(manager, &exynos_drm_manager_list, list) {
97 if (manager->ops->initialize) {
98 ret = manager->ops->initialize(manager, dev, pipe);
99 if (ret) {
100 DRM_ERROR("Mgr init [%d] failed with %d\n",
101 manager->type, ret);
102 goto err;
103 }
104 }
105 62
106 manager->drm_dev = dev; 63 list_add_tail(&subdrv->list, &exynos_drm_subdrv_list);
107 manager->pipe = pipe++;
108 64
109 ret = exynos_drm_crtc_create(manager);
110 if (ret) {
111 DRM_ERROR("CRTC create [%d] failed with %d\n",
112 manager->type, ret);
113 goto err;
114 }
115 }
116 return 0; 65 return 0;
117
118err:
119 list_for_each_entry_safe(manager, n, &exynos_drm_manager_list, list) {
120 if (pipe-- > 0)
121 exynos_drm_manager_unregister(manager);
122 else
123 list_del(&manager->list);
124 }
125 return ret;
126}
127
128void exynos_drm_remove_managers(struct drm_device *dev)
129{
130 struct exynos_drm_manager *manager, *n;
131
132 list_for_each_entry_safe(manager, n, &exynos_drm_manager_list, list)
133 exynos_drm_manager_unregister(manager);
134} 66}
67EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register);
135 68
136int exynos_drm_initialize_displays(struct drm_device *dev) 69int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
137{ 70{
138 struct exynos_drm_display *display, *n; 71 if (!subdrv)
139 int ret, initialized = 0; 72 return -EINVAL;
140
141 list_for_each_entry(display, &exynos_drm_display_list, list) {
142 if (display->ops->initialize) {
143 ret = display->ops->initialize(display, dev);
144 if (ret) {
145 DRM_ERROR("Display init [%d] failed with %d\n",
146 display->type, ret);
147 goto err;
148 }
149 }
150 73
151 initialized++; 74 list_del(&subdrv->list);
152 75
153 ret = exynos_drm_create_enc_conn(dev, display);
154 if (ret) {
155 DRM_ERROR("Encoder create [%d] failed with %d\n",
156 display->type, ret);
157 goto err;
158 }
159 }
160 return 0; 76 return 0;
161
162err:
163 list_for_each_entry_safe(display, n, &exynos_drm_display_list, list) {
164 if (initialized-- > 0)
165 exynos_drm_display_unregister(display);
166 else
167 list_del(&display->list);
168 }
169 return ret;
170}
171
172void exynos_drm_remove_displays(struct drm_device *dev)
173{
174 struct exynos_drm_display *display, *n;
175
176 list_for_each_entry_safe(display, n, &exynos_drm_display_list, list)
177 exynos_drm_display_unregister(display);
178} 77}
78EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister);
179 79
180int exynos_drm_device_register(struct drm_device *dev) 80int exynos_drm_device_subdrv_probe(struct drm_device *dev)
181{ 81{
182 struct exynos_drm_subdrv *subdrv, *n; 82 struct exynos_drm_subdrv *subdrv, *n;
183 int err; 83 int err;
@@ -186,19 +86,28 @@ int exynos_drm_device_register(struct drm_device *dev)
186 return -EINVAL; 86 return -EINVAL;
187 87
188 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { 88 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
189 err = exynos_drm_subdrv_probe(dev, subdrv); 89 if (subdrv->probe) {
190 if (err) { 90 subdrv->drm_dev = dev;
191 DRM_DEBUG("exynos drm subdrv probe failed.\n"); 91
192 list_del(&subdrv->list); 92 /*
193 continue; 93 * this probe callback would be called by sub driver
94 * after setting of all resources to this sub driver,
95 * such as clock, irq and register map are done.
96 */
97 err = subdrv->probe(dev, subdrv->dev);
98 if (err) {
99 DRM_DEBUG("exynos drm subdrv probe failed.\n");
100 list_del(&subdrv->list);
101 continue;
102 }
194 } 103 }
195 } 104 }
196 105
197 return 0; 106 return 0;
198} 107}
199EXPORT_SYMBOL_GPL(exynos_drm_device_register); 108EXPORT_SYMBOL_GPL(exynos_drm_device_subdrv_probe);
200 109
201int exynos_drm_device_unregister(struct drm_device *dev) 110int exynos_drm_device_subdrv_remove(struct drm_device *dev)
202{ 111{
203 struct exynos_drm_subdrv *subdrv; 112 struct exynos_drm_subdrv *subdrv;
204 113
@@ -208,66 +117,13 @@ int exynos_drm_device_unregister(struct drm_device *dev)
208 } 117 }
209 118
210 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { 119 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
211 exynos_drm_subdrv_remove(dev, subdrv); 120 if (subdrv->remove)
121 subdrv->remove(dev, subdrv->dev);
212 } 122 }
213 123
214 return 0; 124 return 0;
215} 125}
216EXPORT_SYMBOL_GPL(exynos_drm_device_unregister); 126EXPORT_SYMBOL_GPL(exynos_drm_device_subdrv_remove);
217
218int exynos_drm_manager_register(struct exynos_drm_manager *manager)
219{
220 BUG_ON(!manager->ops);
221 list_add_tail(&manager->list, &exynos_drm_manager_list);
222 return 0;
223}
224
225int exynos_drm_manager_unregister(struct exynos_drm_manager *manager)
226{
227 if (manager->ops->remove)
228 manager->ops->remove(manager);
229
230 list_del(&manager->list);
231 return 0;
232}
233
234int exynos_drm_display_register(struct exynos_drm_display *display)
235{
236 BUG_ON(!display->ops);
237 list_add_tail(&display->list, &exynos_drm_display_list);
238 return 0;
239}
240
241int exynos_drm_display_unregister(struct exynos_drm_display *display)
242{
243 if (display->ops->remove)
244 display->ops->remove(display);
245
246 list_del(&display->list);
247 return 0;
248}
249
250int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
251{
252 if (!subdrv)
253 return -EINVAL;
254
255 list_add_tail(&subdrv->list, &exynos_drm_subdrv_list);
256
257 return 0;
258}
259EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register);
260
261int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
262{
263 if (!subdrv)
264 return -EINVAL;
265
266 list_del(&subdrv->list);
267
268 return 0;
269}
270EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister);
271 127
272int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) 128int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
273{ 129{
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 1ef5ab9c9d51..95c9435d0266 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -368,6 +368,7 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager)
368 return -ENOMEM; 368 return -ENOMEM;
369 } 369 }
370 370
371 manager->crtc = &exynos_crtc->drm_crtc;
371 crtc = &exynos_crtc->drm_crtc; 372 crtc = &exynos_crtc->drm_crtc;
372 373
373 private->crtc[manager->pipe] = crtc; 374 private->crtc[manager->pipe] = crtc;
@@ -491,3 +492,19 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
491 manager->ops->wait_for_vblank(manager); 492 manager->ops->wait_for_vblank(manager);
492 } 493 }
493} 494}
495
496int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
497 unsigned int out_type)
498{
499 struct drm_crtc *crtc;
500
501 list_for_each_entry(crtc, &drm_dev->mode_config.crtc_list, head) {
502 struct exynos_drm_crtc *exynos_crtc;
503
504 exynos_crtc = to_exynos_crtc(crtc);
505 if (exynos_crtc->manager->type == out_type)
506 return exynos_crtc->manager->pipe;
507 }
508
509 return -EPERM;
510}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index c27b66cc5d24..9f74b10a8a01 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -32,4 +32,8 @@ void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos);
32void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos); 32void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos);
33void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos); 33void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
34 34
35/* This function gets pipe value to crtc device matched with out_type. */
36int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
37 unsigned int out_type);
38
35#endif 39#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 82e52c71bccc..f1b8587cc63d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -40,20 +40,10 @@ exynos_dpi_detect(struct drm_connector *connector, bool force)
40{ 40{
41 struct exynos_dpi *ctx = connector_to_dpi(connector); 41 struct exynos_dpi *ctx = connector_to_dpi(connector);
42 42
43 /* panels supported only by boot-loader are always connected */ 43 if (!ctx->panel->connector)
44 if (!ctx->panel_node) 44 drm_panel_attach(ctx->panel, &ctx->connector);
45 return connector_status_connected;
46 45
47 if (!ctx->panel) { 46 return connector_status_connected;
48 ctx->panel = of_drm_find_panel(ctx->panel_node);
49 if (ctx->panel)
50 drm_panel_attach(ctx->panel, &ctx->connector);
51 }
52
53 if (ctx->panel)
54 return connector_status_connected;
55
56 return connector_status_disconnected;
57} 47}
58 48
59static void exynos_dpi_connector_destroy(struct drm_connector *connector) 49static void exynos_dpi_connector_destroy(struct drm_connector *connector)
@@ -116,10 +106,7 @@ static int exynos_dpi_create_connector(struct exynos_drm_display *display,
116 106
117 ctx->encoder = encoder; 107 ctx->encoder = encoder;
118 108
119 if (ctx->panel_node) 109 connector->polled = DRM_CONNECTOR_POLL_HPD;
120 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
121 else
122 connector->polled = DRM_CONNECTOR_POLL_HPD;
123 110
124 ret = drm_connector_init(encoder->dev, connector, 111 ret = drm_connector_init(encoder->dev, connector,
125 &exynos_dpi_connector_funcs, 112 &exynos_dpi_connector_funcs,
@@ -287,8 +274,10 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
287 return -ENOMEM; 274 return -ENOMEM;
288 275
289 ret = of_get_videomode(dn, vm, 0); 276 ret = of_get_videomode(dn, vm, 0);
290 if (ret < 0) 277 if (ret < 0) {
278 devm_kfree(dev, vm);
291 return ret; 279 return ret;
280 }
292 281
293 ctx->vm = vm; 282 ctx->vm = vm;
294 283
@@ -301,32 +290,58 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
301 return 0; 290 return 0;
302} 291}
303 292
304int exynos_dpi_probe(struct device *dev) 293struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
305{ 294{
306 struct exynos_dpi *ctx; 295 struct exynos_dpi *ctx;
307 int ret; 296 int ret;
308 297
298 ret = exynos_drm_component_add(dev,
299 EXYNOS_DEVICE_TYPE_CONNECTOR,
300 exynos_dpi_display.type);
301 if (ret)
302 return ERR_PTR(ret);
303
309 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 304 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
310 if (!ctx) 305 if (!ctx)
311 return -ENOMEM; 306 goto err_del_component;
312 307
313 ctx->dev = dev; 308 ctx->dev = dev;
314 exynos_dpi_display.ctx = ctx; 309 exynos_dpi_display.ctx = ctx;
315 ctx->dpms_mode = DRM_MODE_DPMS_OFF; 310 ctx->dpms_mode = DRM_MODE_DPMS_OFF;
316 311
317 ret = exynos_dpi_parse_dt(ctx); 312 ret = exynos_dpi_parse_dt(ctx);
318 if (ret < 0) 313 if (ret < 0) {
319 return ret; 314 devm_kfree(dev, ctx);
315 goto err_del_component;
316 }
320 317
321 exynos_drm_display_register(&exynos_dpi_display); 318 if (ctx->panel_node) {
319 ctx->panel = of_drm_find_panel(ctx->panel_node);
320 if (!ctx->panel) {
321 exynos_drm_component_del(dev,
322 EXYNOS_DEVICE_TYPE_CONNECTOR);
323 return ERR_PTR(-EPROBE_DEFER);
324 }
325 }
322 326
323 return 0; 327 return &exynos_dpi_display;
328
329err_del_component:
330 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
331
332 return NULL;
324} 333}
325 334
326int exynos_dpi_remove(struct device *dev) 335int exynos_dpi_remove(struct device *dev)
327{ 336{
337 struct drm_encoder *encoder = exynos_dpi_display.encoder;
338 struct exynos_dpi *ctx = exynos_dpi_display.ctx;
339
328 exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF); 340 exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF);
329 exynos_drm_display_unregister(&exynos_dpi_display); 341 encoder->funcs->destroy(encoder);
342 drm_connector_cleanup(&ctx->connector);
343
344 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
330 345
331 return 0; 346 return 0;
332} 347}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2d27ba23a6a8..5d225dd58a87 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -16,6 +16,7 @@
16#include <drm/drm_crtc_helper.h> 16#include <drm/drm_crtc_helper.h>
17 17
18#include <linux/anon_inodes.h> 18#include <linux/anon_inodes.h>
19#include <linux/component.h>
19 20
20#include <drm/exynos_drm.h> 21#include <drm/exynos_drm.h>
21 22
@@ -40,9 +41,19 @@
40 41
41#define VBLANK_OFF_DELAY 50000 42#define VBLANK_OFF_DELAY 50000
42 43
43/* platform device pointer for eynos drm device. */
44static struct platform_device *exynos_drm_pdev; 44static struct platform_device *exynos_drm_pdev;
45 45
46static DEFINE_MUTEX(drm_component_lock);
47static LIST_HEAD(drm_component_list);
48
49struct component_dev {
50 struct list_head list;
51 struct device *crtc_dev;
52 struct device *conn_dev;
53 enum exynos_drm_output_type out_type;
54 unsigned int dev_type_flag;
55};
56
46static int exynos_drm_load(struct drm_device *dev, unsigned long flags) 57static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
47{ 58{
48 struct exynos_drm_private *private; 59 struct exynos_drm_private *private;
@@ -73,38 +84,21 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
73 84
74 exynos_drm_mode_config_init(dev); 85 exynos_drm_mode_config_init(dev);
75 86
76 ret = exynos_drm_initialize_managers(dev);
77 if (ret)
78 goto err_mode_config_cleanup;
79
80 for (nr = 0; nr < MAX_PLANE; nr++) { 87 for (nr = 0; nr < MAX_PLANE; nr++) {
81 struct drm_plane *plane; 88 struct drm_plane *plane;
82 unsigned long possible_crtcs = (1 << MAX_CRTC) - 1; 89 unsigned long possible_crtcs = (1 << MAX_CRTC) - 1;
83 90
84 plane = exynos_plane_init(dev, possible_crtcs, false); 91 plane = exynos_plane_init(dev, possible_crtcs, false);
85 if (!plane) 92 if (!plane)
86 goto err_manager_cleanup; 93 goto err_mode_config_cleanup;
87 } 94 }
88 95
89 ret = exynos_drm_initialize_displays(dev);
90 if (ret)
91 goto err_manager_cleanup;
92
93 /* init kms poll for handling hpd */ 96 /* init kms poll for handling hpd */
94 drm_kms_helper_poll_init(dev); 97 drm_kms_helper_poll_init(dev);
95 98
96 ret = drm_vblank_init(dev, MAX_CRTC); 99 ret = drm_vblank_init(dev, MAX_CRTC);
97 if (ret) 100 if (ret)
98 goto err_display_cleanup; 101 goto err_mode_config_cleanup;
99
100 /*
101 * probe sub drivers such as display controller and hdmi driver,
102 * that were registered at probe() of platform driver
103 * to the sub driver and create encoder and connector for them.
104 */
105 ret = exynos_drm_device_register(dev);
106 if (ret)
107 goto err_vblank;
108 102
109 /* setup possible_clones. */ 103 /* setup possible_clones. */
110 exynos_drm_encoder_setup(dev); 104 exynos_drm_encoder_setup(dev);
@@ -113,17 +107,25 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
113 107
114 platform_set_drvdata(dev->platformdev, dev); 108 platform_set_drvdata(dev->platformdev, dev);
115 109
110 /* Try to bind all sub drivers. */
111 ret = component_bind_all(dev->dev, dev);
112 if (ret)
113 goto err_cleanup_vblank;
114
115 /* Probe non kms sub drivers and virtual display driver. */
116 ret = exynos_drm_device_subdrv_probe(dev);
117 if (ret)
118 goto err_unbind_all;
119
116 /* force connectors detection */ 120 /* force connectors detection */
117 drm_helper_hpd_irq_event(dev); 121 drm_helper_hpd_irq_event(dev);
118 122
119 return 0; 123 return 0;
120 124
121err_vblank: 125err_unbind_all:
126 component_unbind_all(dev->dev, dev);
127err_cleanup_vblank:
122 drm_vblank_cleanup(dev); 128 drm_vblank_cleanup(dev);
123err_display_cleanup:
124 exynos_drm_remove_displays(dev);
125err_manager_cleanup:
126 exynos_drm_remove_managers(dev);
127err_mode_config_cleanup: 129err_mode_config_cleanup:
128 drm_mode_config_cleanup(dev); 130 drm_mode_config_cleanup(dev);
129 drm_release_iommu_mapping(dev); 131 drm_release_iommu_mapping(dev);
@@ -135,17 +137,17 @@ err_free_private:
135 137
136static int exynos_drm_unload(struct drm_device *dev) 138static int exynos_drm_unload(struct drm_device *dev)
137{ 139{
140 exynos_drm_device_subdrv_remove(dev);
141
138 exynos_drm_fbdev_fini(dev); 142 exynos_drm_fbdev_fini(dev);
139 exynos_drm_device_unregister(dev);
140 drm_vblank_cleanup(dev); 143 drm_vblank_cleanup(dev);
141 drm_kms_helper_poll_fini(dev); 144 drm_kms_helper_poll_fini(dev);
142 exynos_drm_remove_displays(dev);
143 exynos_drm_remove_managers(dev);
144 drm_mode_config_cleanup(dev); 145 drm_mode_config_cleanup(dev);
145 146
146 drm_release_iommu_mapping(dev); 147 drm_release_iommu_mapping(dev);
147 kfree(dev->dev_private); 148 kfree(dev->dev_private);
148 149
150 component_unbind_all(dev->dev, dev);
149 dev->dev_private = NULL; 151 dev->dev_private = NULL;
150 152
151 return 0; 153 return 0;
@@ -183,9 +185,9 @@ static int exynos_drm_resume(struct drm_device *dev)
183 if (connector->funcs->dpms) 185 if (connector->funcs->dpms)
184 connector->funcs->dpms(connector, connector->dpms); 186 connector->funcs->dpms(connector, connector->dpms);
185 } 187 }
188 drm_modeset_unlock_all(dev);
186 189
187 drm_helper_resume_force_mode(dev); 190 drm_helper_resume_force_mode(dev);
188 drm_modeset_unlock_all(dev);
189 191
190 return 0; 192 return 0;
191} 193}
@@ -323,8 +325,7 @@ static const struct file_operations exynos_drm_driver_fops = {
323}; 325};
324 326
325static struct drm_driver exynos_drm_driver = { 327static struct drm_driver exynos_drm_driver = {
326 .driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | 328 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
327 DRIVER_GEM | DRIVER_PRIME,
328 .load = exynos_drm_load, 329 .load = exynos_drm_load,
329 .unload = exynos_drm_unload, 330 .unload = exynos_drm_unload,
330 .suspend = exynos_drm_suspend, 331 .suspend = exynos_drm_suspend,
@@ -355,27 +356,6 @@ static struct drm_driver exynos_drm_driver = {
355 .minor = DRIVER_MINOR, 356 .minor = DRIVER_MINOR,
356}; 357};
357 358
358static int exynos_drm_platform_probe(struct platform_device *pdev)
359{
360 int ret;
361
362 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
363 if (ret)
364 return ret;
365
366 pm_runtime_enable(&pdev->dev);
367 pm_runtime_get_sync(&pdev->dev);
368
369 return drm_platform_init(&exynos_drm_driver, pdev);
370}
371
372static int exynos_drm_platform_remove(struct platform_device *pdev)
373{
374 drm_put_dev(platform_get_drvdata(pdev));
375
376 return 0;
377}
378
379#ifdef CONFIG_PM_SLEEP 359#ifdef CONFIG_PM_SLEEP
380static int exynos_drm_sys_suspend(struct device *dev) 360static int exynos_drm_sys_suspend(struct device *dev)
381{ 361{
@@ -400,196 +380,319 @@ static int exynos_drm_sys_resume(struct device *dev)
400} 380}
401#endif 381#endif
402 382
403#ifdef CONFIG_PM_RUNTIME 383static const struct dev_pm_ops exynos_drm_pm_ops = {
404static int exynos_drm_runtime_suspend(struct device *dev) 384 SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
385};
386
387int exynos_drm_component_add(struct device *dev,
388 enum exynos_drm_device_type dev_type,
389 enum exynos_drm_output_type out_type)
405{ 390{
406 struct drm_device *drm_dev = dev_get_drvdata(dev); 391 struct component_dev *cdev;
407 pm_message_t message;
408 392
409 if (pm_runtime_suspended(dev)) 393 if (dev_type != EXYNOS_DEVICE_TYPE_CRTC &&
410 return 0; 394 dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) {
395 DRM_ERROR("invalid device type.\n");
396 return -EINVAL;
397 }
411 398
412 message.event = PM_EVENT_SUSPEND; 399 mutex_lock(&drm_component_lock);
413 return exynos_drm_suspend(drm_dev, message); 400
401 /*
402 * Make sure to check if there is a component which has two device
403 * objects, for connector and for encoder/connector.
404 * It should make sure that crtc and encoder/connector drivers are
405 * ready before exynos drm core binds them.
406 */
407 list_for_each_entry(cdev, &drm_component_list, list) {
408 if (cdev->out_type == out_type) {
409 /*
410 * If crtc and encoder/connector device objects are
411 * added already just return.
412 */
413 if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC |
414 EXYNOS_DEVICE_TYPE_CONNECTOR)) {
415 mutex_unlock(&drm_component_lock);
416 return 0;
417 }
418
419 if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
420 cdev->crtc_dev = dev;
421 cdev->dev_type_flag |= dev_type;
422 }
423
424 if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
425 cdev->conn_dev = dev;
426 cdev->dev_type_flag |= dev_type;
427 }
428
429 mutex_unlock(&drm_component_lock);
430 return 0;
431 }
432 }
433
434 mutex_unlock(&drm_component_lock);
435
436 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
437 if (!cdev)
438 return -ENOMEM;
439
440 if (dev_type == EXYNOS_DEVICE_TYPE_CRTC)
441 cdev->crtc_dev = dev;
442 if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR)
443 cdev->conn_dev = dev;
444
445 cdev->out_type = out_type;
446 cdev->dev_type_flag = dev_type;
447
448 mutex_lock(&drm_component_lock);
449 list_add_tail(&cdev->list, &drm_component_list);
450 mutex_unlock(&drm_component_lock);
451
452 return 0;
414} 453}
415 454
416static int exynos_drm_runtime_resume(struct device *dev) 455void exynos_drm_component_del(struct device *dev,
456 enum exynos_drm_device_type dev_type)
417{ 457{
418 struct drm_device *drm_dev = dev_get_drvdata(dev); 458 struct component_dev *cdev, *next;
419 459
420 if (!pm_runtime_suspended(dev)) 460 mutex_lock(&drm_component_lock);
421 return 0;
422 461
423 return exynos_drm_resume(drm_dev); 462 list_for_each_entry_safe(cdev, next, &drm_component_list, list) {
463 if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
464 if (cdev->crtc_dev == dev) {
465 cdev->crtc_dev = NULL;
466 cdev->dev_type_flag &= ~dev_type;
467 }
468 }
469
470 if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
471 if (cdev->conn_dev == dev) {
472 cdev->conn_dev = NULL;
473 cdev->dev_type_flag &= ~dev_type;
474 }
475 }
476
477 /*
478 * Release cdev object only in case that both of crtc and
479 * encoder/connector device objects are NULL.
480 */
481 if (!cdev->crtc_dev && !cdev->conn_dev) {
482 list_del(&cdev->list);
483 kfree(cdev);
484 }
485
486 break;
487 }
488
489 mutex_unlock(&drm_component_lock);
424} 490}
425#endif
426 491
427static const struct dev_pm_ops exynos_drm_pm_ops = { 492static int compare_of(struct device *dev, void *data)
428 SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume) 493{
429 SET_RUNTIME_PM_OPS(exynos_drm_runtime_suspend, 494 return dev == (struct device *)data;
430 exynos_drm_runtime_resume, NULL) 495}
431};
432 496
433static struct platform_driver exynos_drm_platform_driver = { 497static int exynos_drm_add_components(struct device *dev, struct master *m)
434 .probe = exynos_drm_platform_probe, 498{
435 .remove = exynos_drm_platform_remove, 499 struct component_dev *cdev;
436 .driver = { 500 unsigned int attach_cnt = 0;
437 .owner = THIS_MODULE, 501
438 .name = "exynos-drm", 502 mutex_lock(&drm_component_lock);
439 .pm = &exynos_drm_pm_ops, 503
440 }, 504 list_for_each_entry(cdev, &drm_component_list, list) {
505 int ret;
506
507 /*
508 * Add components to master only in case that crtc and
509 * encoder/connector device objects exist.
510 */
511 if (!cdev->crtc_dev || !cdev->conn_dev)
512 continue;
513
514 attach_cnt++;
515
516 mutex_unlock(&drm_component_lock);
517
518 /*
519 * fimd and dpi modules have same device object so add
520 * only crtc device object in this case.
521 *
522 * TODO. if dpi module follows driver-model driver then
523 * below codes can be removed.
524 */
525 if (cdev->crtc_dev == cdev->conn_dev) {
526 ret = component_master_add_child(m, compare_of,
527 cdev->crtc_dev);
528 if (ret < 0)
529 return ret;
530
531 goto out_lock;
532 }
533
534 /*
535 * Do not chage below call order.
536 * crtc device first should be added to master because
537 * connector/encoder need pipe number of crtc when they
538 * are created.
539 */
540 ret = component_master_add_child(m, compare_of, cdev->crtc_dev);
541 ret |= component_master_add_child(m, compare_of,
542 cdev->conn_dev);
543 if (ret < 0)
544 return ret;
545
546out_lock:
547 mutex_lock(&drm_component_lock);
548 }
549
550 mutex_unlock(&drm_component_lock);
551
552 return attach_cnt ? 0 : -ENODEV;
553}
554
555static int exynos_drm_bind(struct device *dev)
556{
557 return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
558}
559
560static void exynos_drm_unbind(struct device *dev)
561{
562 drm_put_dev(dev_get_drvdata(dev));
563}
564
565static const struct component_master_ops exynos_drm_ops = {
566 .add_components = exynos_drm_add_components,
567 .bind = exynos_drm_bind,
568 .unbind = exynos_drm_unbind,
441}; 569};
442 570
443static int __init exynos_drm_init(void) 571static int exynos_drm_platform_probe(struct platform_device *pdev)
444{ 572{
445 int ret; 573 int ret;
446 574
575 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
576 exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
577
578#ifdef CONFIG_DRM_EXYNOS_FIMD
579 ret = platform_driver_register(&fimd_driver);
580 if (ret < 0)
581 return ret;
582#endif
583
447#ifdef CONFIG_DRM_EXYNOS_DP 584#ifdef CONFIG_DRM_EXYNOS_DP
448 ret = platform_driver_register(&dp_driver); 585 ret = platform_driver_register(&dp_driver);
449 if (ret < 0) 586 if (ret < 0)
450 goto out_dp; 587 goto err_unregister_fimd_drv;
451#endif 588#endif
452 589
453#ifdef CONFIG_DRM_EXYNOS_DSI 590#ifdef CONFIG_DRM_EXYNOS_DSI
454 ret = platform_driver_register(&dsi_driver); 591 ret = platform_driver_register(&dsi_driver);
455 if (ret < 0) 592 if (ret < 0)
456 goto out_dsi; 593 goto err_unregister_dp_drv;
457#endif
458
459#ifdef CONFIG_DRM_EXYNOS_FIMD
460 ret = platform_driver_register(&fimd_driver);
461 if (ret < 0)
462 goto out_fimd;
463#endif 594#endif
464 595
465#ifdef CONFIG_DRM_EXYNOS_HDMI 596#ifdef CONFIG_DRM_EXYNOS_HDMI
466 ret = platform_driver_register(&hdmi_driver);
467 if (ret < 0)
468 goto out_hdmi;
469 ret = platform_driver_register(&mixer_driver); 597 ret = platform_driver_register(&mixer_driver);
470 if (ret < 0) 598 if (ret < 0)
471 goto out_mixer; 599 goto err_unregister_dsi_drv;
472#endif 600 ret = platform_driver_register(&hdmi_driver);
473
474#ifdef CONFIG_DRM_EXYNOS_VIDI
475 ret = platform_driver_register(&vidi_driver);
476 if (ret < 0) 601 if (ret < 0)
477 goto out_vidi; 602 goto err_unregister_mixer_drv;
478#endif 603#endif
479 604
480#ifdef CONFIG_DRM_EXYNOS_G2D 605#ifdef CONFIG_DRM_EXYNOS_G2D
481 ret = platform_driver_register(&g2d_driver); 606 ret = platform_driver_register(&g2d_driver);
482 if (ret < 0) 607 if (ret < 0)
483 goto out_g2d; 608 goto err_unregister_hdmi_drv;
484#endif 609#endif
485 610
486#ifdef CONFIG_DRM_EXYNOS_FIMC 611#ifdef CONFIG_DRM_EXYNOS_FIMC
487 ret = platform_driver_register(&fimc_driver); 612 ret = platform_driver_register(&fimc_driver);
488 if (ret < 0) 613 if (ret < 0)
489 goto out_fimc; 614 goto err_unregister_g2d_drv;
490#endif 615#endif
491 616
492#ifdef CONFIG_DRM_EXYNOS_ROTATOR 617#ifdef CONFIG_DRM_EXYNOS_ROTATOR
493 ret = platform_driver_register(&rotator_driver); 618 ret = platform_driver_register(&rotator_driver);
494 if (ret < 0) 619 if (ret < 0)
495 goto out_rotator; 620 goto err_unregister_fimc_drv;
496#endif 621#endif
497 622
498#ifdef CONFIG_DRM_EXYNOS_GSC 623#ifdef CONFIG_DRM_EXYNOS_GSC
499 ret = platform_driver_register(&gsc_driver); 624 ret = platform_driver_register(&gsc_driver);
500 if (ret < 0) 625 if (ret < 0)
501 goto out_gsc; 626 goto err_unregister_rotator_drv;
502#endif 627#endif
503 628
504#ifdef CONFIG_DRM_EXYNOS_IPP 629#ifdef CONFIG_DRM_EXYNOS_IPP
505 ret = platform_driver_register(&ipp_driver); 630 ret = platform_driver_register(&ipp_driver);
506 if (ret < 0) 631 if (ret < 0)
507 goto out_ipp; 632 goto err_unregister_gsc_drv;
508 633
509 ret = exynos_platform_device_ipp_register(); 634 ret = exynos_platform_device_ipp_register();
510 if (ret < 0) 635 if (ret < 0)
511 goto out_ipp_dev; 636 goto err_unregister_ipp_drv;
512#endif 637#endif
513 638
514 ret = platform_driver_register(&exynos_drm_platform_driver); 639 ret = component_master_add(&pdev->dev, &exynos_drm_ops);
515 if (ret < 0) 640 if (ret < 0)
516 goto out_drm; 641 DRM_DEBUG_KMS("re-tried by last sub driver probed later.\n");
517
518 exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
519 NULL, 0);
520 if (IS_ERR(exynos_drm_pdev)) {
521 ret = PTR_ERR(exynos_drm_pdev);
522 goto out;
523 }
524 642
525 return 0; 643 return 0;
526 644
527out:
528 platform_driver_unregister(&exynos_drm_platform_driver);
529
530out_drm:
531#ifdef CONFIG_DRM_EXYNOS_IPP 645#ifdef CONFIG_DRM_EXYNOS_IPP
532 exynos_platform_device_ipp_unregister(); 646err_unregister_ipp_drv:
533out_ipp_dev:
534 platform_driver_unregister(&ipp_driver); 647 platform_driver_unregister(&ipp_driver);
535out_ipp: 648err_unregister_gsc_drv:
536#endif 649#endif
537 650
538#ifdef CONFIG_DRM_EXYNOS_GSC 651#ifdef CONFIG_DRM_EXYNOS_GSC
539 platform_driver_unregister(&gsc_driver); 652 platform_driver_unregister(&gsc_driver);
540out_gsc: 653err_unregister_rotator_drv:
541#endif 654#endif
542 655
543#ifdef CONFIG_DRM_EXYNOS_ROTATOR 656#ifdef CONFIG_DRM_EXYNOS_ROTATOR
544 platform_driver_unregister(&rotator_driver); 657 platform_driver_unregister(&rotator_driver);
545out_rotator: 658err_unregister_fimc_drv:
546#endif 659#endif
547 660
548#ifdef CONFIG_DRM_EXYNOS_FIMC 661#ifdef CONFIG_DRM_EXYNOS_FIMC
549 platform_driver_unregister(&fimc_driver); 662 platform_driver_unregister(&fimc_driver);
550out_fimc: 663err_unregister_g2d_drv:
551#endif 664#endif
552 665
553#ifdef CONFIG_DRM_EXYNOS_G2D 666#ifdef CONFIG_DRM_EXYNOS_G2D
554 platform_driver_unregister(&g2d_driver); 667 platform_driver_unregister(&g2d_driver);
555out_g2d: 668err_unregister_hdmi_drv:
556#endif
557
558#ifdef CONFIG_DRM_EXYNOS_VIDI
559 platform_driver_unregister(&vidi_driver);
560out_vidi:
561#endif 669#endif
562 670
563#ifdef CONFIG_DRM_EXYNOS_HDMI 671#ifdef CONFIG_DRM_EXYNOS_HDMI
564 platform_driver_unregister(&mixer_driver);
565out_mixer:
566 platform_driver_unregister(&hdmi_driver); 672 platform_driver_unregister(&hdmi_driver);
567out_hdmi: 673err_unregister_mixer_drv:
568#endif 674 platform_driver_unregister(&mixer_driver);
569 675err_unregister_dsi_drv:
570#ifdef CONFIG_DRM_EXYNOS_FIMD
571 platform_driver_unregister(&fimd_driver);
572out_fimd:
573#endif 676#endif
574 677
575#ifdef CONFIG_DRM_EXYNOS_DSI 678#ifdef CONFIG_DRM_EXYNOS_DSI
576 platform_driver_unregister(&dsi_driver); 679 platform_driver_unregister(&dsi_driver);
577out_dsi: 680err_unregister_dp_drv:
578#endif 681#endif
579 682
580#ifdef CONFIG_DRM_EXYNOS_DP 683#ifdef CONFIG_DRM_EXYNOS_DP
581 platform_driver_unregister(&dp_driver); 684 platform_driver_unregister(&dp_driver);
582out_dp: 685err_unregister_fimd_drv:
686#endif
687
688#ifdef CONFIG_DRM_EXYNOS_FIMD
689 platform_driver_unregister(&fimd_driver);
583#endif 690#endif
584 return ret; 691 return ret;
585} 692}
586 693
587static void __exit exynos_drm_exit(void) 694static int exynos_drm_platform_remove(struct platform_device *pdev)
588{ 695{
589 platform_device_unregister(exynos_drm_pdev);
590
591 platform_driver_unregister(&exynos_drm_platform_driver);
592
593#ifdef CONFIG_DRM_EXYNOS_IPP 696#ifdef CONFIG_DRM_EXYNOS_IPP
594 exynos_platform_device_ipp_unregister(); 697 exynos_platform_device_ipp_unregister();
595 platform_driver_unregister(&ipp_driver); 698 platform_driver_unregister(&ipp_driver);
@@ -616,10 +719,6 @@ static void __exit exynos_drm_exit(void)
616 platform_driver_unregister(&hdmi_driver); 719 platform_driver_unregister(&hdmi_driver);
617#endif 720#endif
618 721
619#ifdef CONFIG_DRM_EXYNOS_VIDI
620 platform_driver_unregister(&vidi_driver);
621#endif
622
623#ifdef CONFIG_DRM_EXYNOS_FIMD 722#ifdef CONFIG_DRM_EXYNOS_FIMD
624 platform_driver_unregister(&fimd_driver); 723 platform_driver_unregister(&fimd_driver);
625#endif 724#endif
@@ -631,6 +730,59 @@ static void __exit exynos_drm_exit(void)
631#ifdef CONFIG_DRM_EXYNOS_DP 730#ifdef CONFIG_DRM_EXYNOS_DP
632 platform_driver_unregister(&dp_driver); 731 platform_driver_unregister(&dp_driver);
633#endif 732#endif
733 component_master_del(&pdev->dev, &exynos_drm_ops);
734 return 0;
735}
736
737static struct platform_driver exynos_drm_platform_driver = {
738 .probe = exynos_drm_platform_probe,
739 .remove = exynos_drm_platform_remove,
740 .driver = {
741 .owner = THIS_MODULE,
742 .name = "exynos-drm",
743 .pm = &exynos_drm_pm_ops,
744 },
745};
746
747static int exynos_drm_init(void)
748{
749 int ret;
750
751 exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
752 NULL, 0);
753 if (IS_ERR(exynos_drm_pdev))
754 return PTR_ERR(exynos_drm_pdev);
755
756#ifdef CONFIG_DRM_EXYNOS_VIDI
757 ret = exynos_drm_probe_vidi();
758 if (ret < 0)
759 goto err_unregister_pd;
760#endif
761
762 ret = platform_driver_register(&exynos_drm_platform_driver);
763 if (ret)
764 goto err_remove_vidi;
765
766 return 0;
767
768err_unregister_pd:
769 platform_device_unregister(exynos_drm_pdev);
770
771err_remove_vidi:
772#ifdef CONFIG_DRM_EXYNOS_VIDI
773 exynos_drm_remove_vidi();
774#endif
775
776 return ret;
777}
778
779static void exynos_drm_exit(void)
780{
781#ifdef CONFIG_DRM_EXYNOS_VIDI
782 exynos_drm_remove_vidi();
783#endif
784 platform_device_unregister(exynos_drm_pdev);
785 platform_driver_unregister(&exynos_drm_platform_driver);
634} 786}
635 787
636module_init(exynos_drm_init); 788module_init(exynos_drm_init);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index ce3e6a30deaa..36535f398848 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -42,6 +42,13 @@ struct drm_connector;
42 42
43extern unsigned int drm_vblank_offdelay; 43extern unsigned int drm_vblank_offdelay;
44 44
45/* This enumerates device type. */
46enum exynos_drm_device_type {
47 EXYNOS_DEVICE_TYPE_NONE,
48 EXYNOS_DEVICE_TYPE_CRTC,
49 EXYNOS_DEVICE_TYPE_CONNECTOR,
50};
51
45/* this enumerates display type. */ 52/* this enumerates display type. */
46enum exynos_drm_output_type { 53enum exynos_drm_output_type {
47 EXYNOS_DISPLAY_TYPE_NONE, 54 EXYNOS_DISPLAY_TYPE_NONE,
@@ -122,7 +129,6 @@ struct exynos_drm_overlay {
122 * Exynos DRM Display Structure. 129 * Exynos DRM Display Structure.
123 * - this structure is common to analog tv, digital tv and lcd panel. 130 * - this structure is common to analog tv, digital tv and lcd panel.
124 * 131 *
125 * @initialize: initializes the display with drm_dev
126 * @remove: cleans up the display for removal 132 * @remove: cleans up the display for removal
127 * @mode_fixup: fix mode data comparing to hw specific display mode. 133 * @mode_fixup: fix mode data comparing to hw specific display mode.
128 * @mode_set: convert drm_display_mode to hw specific display mode and 134 * @mode_set: convert drm_display_mode to hw specific display mode and
@@ -133,8 +139,6 @@ struct exynos_drm_overlay {
133 */ 139 */
134struct exynos_drm_display; 140struct exynos_drm_display;
135struct exynos_drm_display_ops { 141struct exynos_drm_display_ops {
136 int (*initialize)(struct exynos_drm_display *display,
137 struct drm_device *drm_dev);
138 int (*create_connector)(struct exynos_drm_display *display, 142 int (*create_connector)(struct exynos_drm_display *display,
139 struct drm_encoder *encoder); 143 struct drm_encoder *encoder);
140 void (*remove)(struct exynos_drm_display *display); 144 void (*remove)(struct exynos_drm_display *display);
@@ -172,8 +176,6 @@ struct exynos_drm_display {
172/* 176/*
173 * Exynos drm manager ops 177 * Exynos drm manager ops
174 * 178 *
175 * @initialize: initializes the manager with drm_dev
176 * @remove: cleans up the manager for removal
177 * @dpms: control device power. 179 * @dpms: control device power.
178 * @mode_fixup: fix mode data before applying it 180 * @mode_fixup: fix mode data before applying it
179 * @mode_set: set the given mode to the manager 181 * @mode_set: set the given mode to the manager
@@ -189,9 +191,6 @@ struct exynos_drm_display {
189 */ 191 */
190struct exynos_drm_manager; 192struct exynos_drm_manager;
191struct exynos_drm_manager_ops { 193struct exynos_drm_manager_ops {
192 int (*initialize)(struct exynos_drm_manager *mgr,
193 struct drm_device *drm_dev, int pipe);
194 void (*remove)(struct exynos_drm_manager *mgr);
195 void (*dpms)(struct exynos_drm_manager *mgr, int mode); 194 void (*dpms)(struct exynos_drm_manager *mgr, int mode);
196 bool (*mode_fixup)(struct exynos_drm_manager *mgr, 195 bool (*mode_fixup)(struct exynos_drm_manager *mgr,
197 const struct drm_display_mode *mode, 196 const struct drm_display_mode *mode,
@@ -215,6 +214,7 @@ struct exynos_drm_manager_ops {
215 * @list: the list entry for this manager 214 * @list: the list entry for this manager
216 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. 215 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
217 * @drm_dev: pointer to the drm device 216 * @drm_dev: pointer to the drm device
217 * @crtc: crtc object.
218 * @pipe: the pipe number for this crtc/manager 218 * @pipe: the pipe number for this crtc/manager
219 * @ops: pointer to callbacks for exynos drm specific functionality 219 * @ops: pointer to callbacks for exynos drm specific functionality
220 * @ctx: A pointer to the manager's implementation specific context 220 * @ctx: A pointer to the manager's implementation specific context
@@ -223,6 +223,7 @@ struct exynos_drm_manager {
223 struct list_head list; 223 struct list_head list;
224 enum exynos_drm_output_type type; 224 enum exynos_drm_output_type type;
225 struct drm_device *drm_dev; 225 struct drm_device *drm_dev;
226 struct drm_crtc *crtc;
226 int pipe; 227 int pipe;
227 struct exynos_drm_manager_ops *ops; 228 struct exynos_drm_manager_ops *ops;
228 void *ctx; 229 void *ctx;
@@ -254,6 +255,7 @@ struct drm_exynos_file_private {
254 * otherwise default one. 255 * otherwise default one.
255 * @da_space_size: size of device address space. 256 * @da_space_size: size of device address space.
256 * if 0 then default value is used for it. 257 * if 0 then default value is used for it.
258 * @pipe: the pipe number for this crtc/manager.
257 */ 259 */
258struct exynos_drm_private { 260struct exynos_drm_private {
259 struct drm_fb_helper *fb_helper; 261 struct drm_fb_helper *fb_helper;
@@ -271,6 +273,8 @@ struct exynos_drm_private {
271 273
272 unsigned long da_start; 274 unsigned long da_start;
273 unsigned long da_space_size; 275 unsigned long da_space_size;
276
277 unsigned int pipe;
274}; 278};
275 279
276/* 280/*
@@ -281,11 +285,11 @@ struct exynos_drm_private {
281 * @drm_dev: pointer to drm_device and this pointer would be set 285 * @drm_dev: pointer to drm_device and this pointer would be set
282 * when sub driver calls exynos_drm_subdrv_register(). 286 * when sub driver calls exynos_drm_subdrv_register().
283 * @manager: subdrv has its own manager to control a hardware appropriately 287 * @manager: subdrv has its own manager to control a hardware appropriately
284 * and we can access a hardware drawing on this manager. 288 * and we can access a hardware drawing on this manager.
285 * @probe: this callback would be called by exynos drm driver after 289 * @probe: this callback would be called by exynos drm driver after
286 * subdrv is registered to it. 290 * subdrv is registered to it.
287 * @remove: this callback is used to release resources created 291 * @remove: this callback is used to release resources created
288 * by probe callback. 292 * by probe callback.
289 * @open: this would be called with drm device file open. 293 * @open: this would be called with drm device file open.
290 * @close: this would be called with drm device file close. 294 * @close: this would be called with drm device file close.
291 */ 295 */
@@ -302,39 +306,14 @@ struct exynos_drm_subdrv {
302 struct drm_file *file); 306 struct drm_file *file);
303}; 307};
304 308
305/* 309 /* This function would be called by non kms drivers such as g2d and ipp. */
306 * this function calls a probe callback registered to sub driver list and
307 * create its own encoder and connector and then set drm_device object
308 * to global one.
309 */
310int exynos_drm_device_register(struct drm_device *dev);
311/*
312 * this function calls a remove callback registered to sub driver list and
313 * destroy its own encoder and connetor.
314 */
315int exynos_drm_device_unregister(struct drm_device *dev);
316
317int exynos_drm_initialize_managers(struct drm_device *dev);
318void exynos_drm_remove_managers(struct drm_device *dev);
319int exynos_drm_initialize_displays(struct drm_device *dev);
320void exynos_drm_remove_displays(struct drm_device *dev);
321
322int exynos_drm_manager_register(struct exynos_drm_manager *manager);
323int exynos_drm_manager_unregister(struct exynos_drm_manager *manager);
324int exynos_drm_display_register(struct exynos_drm_display *display);
325int exynos_drm_display_unregister(struct exynos_drm_display *display);
326
327/*
328 * this function would be called by sub drivers such as display controller
329 * or hdmi driver to register this sub driver object to exynos drm driver
330 * and when a sub driver is registered to exynos drm driver a probe callback
331 * of the sub driver is called and creates its own encoder and connector.
332 */
333int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv); 310int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv);
334 311
335/* this function removes subdrv list from exynos drm driver */ 312/* this function removes subdrv list from exynos drm driver */
336int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv); 313int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv);
337 314
315int exynos_drm_device_subdrv_probe(struct drm_device *dev);
316int exynos_drm_device_subdrv_remove(struct drm_device *dev);
338int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); 317int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
339void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); 318void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
340 319
@@ -360,18 +339,40 @@ int exynos_platform_device_ipp_register(void);
360void exynos_platform_device_ipp_unregister(void); 339void exynos_platform_device_ipp_unregister(void);
361 340
362#ifdef CONFIG_DRM_EXYNOS_DPI 341#ifdef CONFIG_DRM_EXYNOS_DPI
363int exynos_dpi_probe(struct device *dev); 342struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
364int exynos_dpi_remove(struct device *dev); 343int exynos_dpi_remove(struct device *dev);
365#else 344#else
366static inline int exynos_dpi_probe(struct device *dev) { return 0; } 345static inline struct exynos_drm_display *
346exynos_dpi_probe(struct device *dev) { return 0; }
367static inline int exynos_dpi_remove(struct device *dev) { return 0; } 347static inline int exynos_dpi_remove(struct device *dev) { return 0; }
368#endif 348#endif
369 349
350/*
351 * this function registers exynos drm vidi platform device/driver.
352 */
353int exynos_drm_probe_vidi(void);
354
355/*
356 * this function unregister exynos drm vidi platform device/driver.
357 */
358void exynos_drm_remove_vidi(void);
359
360/* This function creates a encoder and a connector, and initializes them. */
361int exynos_drm_create_enc_conn(struct drm_device *dev,
362 struct exynos_drm_display *display);
363
364int exynos_drm_component_add(struct device *dev,
365 enum exynos_drm_device_type dev_type,
366 enum exynos_drm_output_type out_type);
367
368void exynos_drm_component_del(struct device *dev,
369 enum exynos_drm_device_type dev_type);
370
371extern struct platform_driver fimd_driver;
370extern struct platform_driver dp_driver; 372extern struct platform_driver dp_driver;
371extern struct platform_driver dsi_driver; 373extern struct platform_driver dsi_driver;
372extern struct platform_driver fimd_driver;
373extern struct platform_driver hdmi_driver;
374extern struct platform_driver mixer_driver; 374extern struct platform_driver mixer_driver;
375extern struct platform_driver hdmi_driver;
375extern struct platform_driver exynos_drm_common_hdmi_driver; 376extern struct platform_driver exynos_drm_common_hdmi_driver;
376extern struct platform_driver vidi_driver; 377extern struct platform_driver vidi_driver;
377extern struct platform_driver g2d_driver; 378extern struct platform_driver g2d_driver;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index 4ac438187568..6302aa64f6c1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -19,6 +19,7 @@
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/phy/phy.h> 20#include <linux/phy/phy.h>
21#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
22#include <linux/component.h>
22 23
23#include <video/mipi_display.h> 24#include <video/mipi_display.h>
24#include <video/videomode.h> 25#include <video/videomode.h>
@@ -1378,16 +1379,60 @@ end:
1378 return ret; 1379 return ret;
1379} 1380}
1380 1381
1382static int exynos_dsi_bind(struct device *dev, struct device *master,
1383 void *data)
1384{
1385 struct drm_device *drm_dev = data;
1386 struct exynos_dsi *dsi;
1387 int ret;
1388
1389 ret = exynos_drm_create_enc_conn(drm_dev, &exynos_dsi_display);
1390 if (ret) {
1391 DRM_ERROR("Encoder create [%d] failed with %d\n",
1392 exynos_dsi_display.type, ret);
1393 return ret;
1394 }
1395
1396 dsi = exynos_dsi_display.ctx;
1397
1398 return mipi_dsi_host_register(&dsi->dsi_host);
1399}
1400
1401static void exynos_dsi_unbind(struct device *dev, struct device *master,
1402 void *data)
1403{
1404 struct exynos_dsi *dsi = exynos_dsi_display.ctx;
1405 struct drm_encoder *encoder = dsi->encoder;
1406
1407 exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);
1408
1409 mipi_dsi_host_unregister(&dsi->dsi_host);
1410
1411 encoder->funcs->destroy(encoder);
1412 drm_connector_cleanup(&dsi->connector);
1413}
1414
1415static const struct component_ops exynos_dsi_component_ops = {
1416 .bind = exynos_dsi_bind,
1417 .unbind = exynos_dsi_unbind,
1418};
1419
1381static int exynos_dsi_probe(struct platform_device *pdev) 1420static int exynos_dsi_probe(struct platform_device *pdev)
1382{ 1421{
1383 struct resource *res; 1422 struct resource *res;
1384 struct exynos_dsi *dsi; 1423 struct exynos_dsi *dsi;
1385 int ret; 1424 int ret;
1386 1425
1426 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1427 exynos_dsi_display.type);
1428 if (ret)
1429 return ret;
1430
1387 dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL); 1431 dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
1388 if (!dsi) { 1432 if (!dsi) {
1389 dev_err(&pdev->dev, "failed to allocate dsi object.\n"); 1433 dev_err(&pdev->dev, "failed to allocate dsi object.\n");
1390 return -ENOMEM; 1434 ret = -ENOMEM;
1435 goto err_del_component;
1391 } 1436 }
1392 1437
1393 init_completion(&dsi->completed); 1438 init_completion(&dsi->completed);
@@ -1401,7 +1446,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1401 1446
1402 ret = exynos_dsi_parse_dt(dsi); 1447 ret = exynos_dsi_parse_dt(dsi);
1403 if (ret) 1448 if (ret)
1404 return ret; 1449 goto err_del_component;
1405 1450
1406 dsi->supplies[0].supply = "vddcore"; 1451 dsi->supplies[0].supply = "vddcore";
1407 dsi->supplies[1].supply = "vddio"; 1452 dsi->supplies[1].supply = "vddio";
@@ -1415,32 +1460,37 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1415 dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk"); 1460 dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk");
1416 if (IS_ERR(dsi->pll_clk)) { 1461 if (IS_ERR(dsi->pll_clk)) {
1417 dev_info(&pdev->dev, "failed to get dsi pll input clock\n"); 1462 dev_info(&pdev->dev, "failed to get dsi pll input clock\n");
1418 return -EPROBE_DEFER; 1463 ret = PTR_ERR(dsi->pll_clk);
1464 goto err_del_component;
1419 } 1465 }
1420 1466
1421 dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk"); 1467 dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
1422 if (IS_ERR(dsi->bus_clk)) { 1468 if (IS_ERR(dsi->bus_clk)) {
1423 dev_info(&pdev->dev, "failed to get dsi bus clock\n"); 1469 dev_info(&pdev->dev, "failed to get dsi bus clock\n");
1424 return -EPROBE_DEFER; 1470 ret = PTR_ERR(dsi->bus_clk);
1471 goto err_del_component;
1425 } 1472 }
1426 1473
1427 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1474 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1428 dsi->reg_base = devm_ioremap_resource(&pdev->dev, res); 1475 dsi->reg_base = devm_ioremap_resource(&pdev->dev, res);
1429 if (IS_ERR(dsi->reg_base)) { 1476 if (IS_ERR(dsi->reg_base)) {
1430 dev_err(&pdev->dev, "failed to remap io region\n"); 1477 dev_err(&pdev->dev, "failed to remap io region\n");
1431 return PTR_ERR(dsi->reg_base); 1478 ret = PTR_ERR(dsi->reg_base);
1479 goto err_del_component;
1432 } 1480 }
1433 1481
1434 dsi->phy = devm_phy_get(&pdev->dev, "dsim"); 1482 dsi->phy = devm_phy_get(&pdev->dev, "dsim");
1435 if (IS_ERR(dsi->phy)) { 1483 if (IS_ERR(dsi->phy)) {
1436 dev_info(&pdev->dev, "failed to get dsim phy\n"); 1484 dev_info(&pdev->dev, "failed to get dsim phy\n");
1437 return -EPROBE_DEFER; 1485 ret = PTR_ERR(dsi->phy);
1486 goto err_del_component;
1438 } 1487 }
1439 1488
1440 dsi->irq = platform_get_irq(pdev, 0); 1489 dsi->irq = platform_get_irq(pdev, 0);
1441 if (dsi->irq < 0) { 1490 if (dsi->irq < 0) {
1442 dev_err(&pdev->dev, "failed to request dsi irq resource\n"); 1491 dev_err(&pdev->dev, "failed to request dsi irq resource\n");
1443 return dsi->irq; 1492 ret = dsi->irq;
1493 goto err_del_component;
1444 } 1494 }
1445 1495
1446 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); 1496 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
@@ -1449,58 +1499,31 @@ static int exynos_dsi_probe(struct platform_device *pdev)
1449 dev_name(&pdev->dev), dsi); 1499 dev_name(&pdev->dev), dsi);
1450 if (ret) { 1500 if (ret) {
1451 dev_err(&pdev->dev, "failed to request dsi irq\n"); 1501 dev_err(&pdev->dev, "failed to request dsi irq\n");
1452 return ret; 1502 goto err_del_component;
1453 } 1503 }
1454 1504
1455 exynos_dsi_display.ctx = dsi; 1505 exynos_dsi_display.ctx = dsi;
1456 1506
1457 platform_set_drvdata(pdev, &exynos_dsi_display); 1507 platform_set_drvdata(pdev, &exynos_dsi_display);
1458 exynos_drm_display_register(&exynos_dsi_display);
1459
1460 return mipi_dsi_host_register(&dsi->dsi_host);
1461}
1462
1463static int exynos_dsi_remove(struct platform_device *pdev)
1464{
1465 struct exynos_dsi *dsi = exynos_dsi_display.ctx;
1466
1467 exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);
1468
1469 exynos_drm_display_unregister(&exynos_dsi_display);
1470 mipi_dsi_host_unregister(&dsi->dsi_host);
1471
1472 return 0;
1473}
1474 1508
1475#if CONFIG_PM_SLEEP 1509 ret = component_add(&pdev->dev, &exynos_dsi_component_ops);
1476static int exynos_dsi_resume(struct device *dev) 1510 if (ret)
1477{ 1511 goto err_del_component;
1478 struct exynos_dsi *dsi = exynos_dsi_display.ctx;
1479 1512
1480 if (dsi->state & DSIM_STATE_ENABLED) { 1513 return ret;
1481 dsi->state &= ~DSIM_STATE_ENABLED;
1482 exynos_dsi_enable(dsi);
1483 }
1484 1514
1485 return 0; 1515err_del_component:
1516 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1517 return ret;
1486} 1518}
1487 1519
1488static int exynos_dsi_suspend(struct device *dev) 1520static int exynos_dsi_remove(struct platform_device *pdev)
1489{ 1521{
1490 struct exynos_dsi *dsi = exynos_dsi_display.ctx; 1522 component_del(&pdev->dev, &exynos_dsi_component_ops);
1491 1523 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1492 if (dsi->state & DSIM_STATE_ENABLED) {
1493 exynos_dsi_disable(dsi);
1494 dsi->state |= DSIM_STATE_ENABLED;
1495 }
1496 1524
1497 return 0; 1525 return 0;
1498} 1526}
1499#endif
1500
1501static const struct dev_pm_ops exynos_dsi_pm_ops = {
1502 SET_SYSTEM_SLEEP_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume)
1503};
1504 1527
1505static struct of_device_id exynos_dsi_of_match[] = { 1528static struct of_device_id exynos_dsi_of_match[] = {
1506 { .compatible = "samsung,exynos4210-mipi-dsi" }, 1529 { .compatible = "samsung,exynos4210-mipi-dsi" },
@@ -1513,7 +1536,6 @@ struct platform_driver dsi_driver = {
1513 .driver = { 1536 .driver = {
1514 .name = "exynos-dsi", 1537 .name = "exynos-dsi",
1515 .owner = THIS_MODULE, 1538 .owner = THIS_MODULE,
1516 .pm = &exynos_dsi_pm_ops,
1517 .of_match_table = exynos_dsi_of_match, 1539 .of_match_table = exynos_dsi_of_match,
1518 }, 1540 },
1519}; 1541};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index addbf7536da4..14bbaa33b477 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -121,16 +121,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
121 offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); 121 offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
122 offset += fbi->var.yoffset * fb->pitches[0]; 122 offset += fbi->var.yoffset * fb->pitches[0];
123 123
124 dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
125 fbi->screen_base = buffer->kvaddr + offset; 124 fbi->screen_base = buffer->kvaddr + offset;
126 if (is_drm_iommu_supported(dev))
127 fbi->fix.smem_start = (unsigned long)
128 (page_to_phys(sg_page(buffer->sgt->sgl)) + offset);
129 else
130 fbi->fix.smem_start = (unsigned long)buffer->dma_addr;
131
132 fbi->screen_size = size; 125 fbi->screen_size = size;
133 fbi->fix.smem_len = size;
134 126
135 return 0; 127 return 0;
136} 128}
@@ -237,7 +229,7 @@ static struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = {
237 .fb_probe = exynos_drm_fbdev_create, 229 .fb_probe = exynos_drm_fbdev_create,
238}; 230};
239 231
240bool exynos_drm_fbdev_is_anything_connected(struct drm_device *dev) 232static bool exynos_drm_fbdev_is_anything_connected(struct drm_device *dev)
241{ 233{
242 struct drm_connector *connector; 234 struct drm_connector *connector;
243 bool ret = false; 235 bool ret = false;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index 30d76b2ff9c2..831dde9034c6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -18,6 +18,7 @@
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/pm_runtime.h> 19#include <linux/pm_runtime.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/spinlock.h>
21 22
22#include <drm/drmP.h> 23#include <drm/drmP.h>
23#include <drm/exynos_drm.h> 24#include <drm/exynos_drm.h>
@@ -57,7 +58,6 @@
57#define FIMC_SHFACTOR 10 58#define FIMC_SHFACTOR 10
58#define FIMC_BUF_STOP 1 59#define FIMC_BUF_STOP 1
59#define FIMC_BUF_START 2 60#define FIMC_BUF_START 2
60#define FIMC_REG_SZ 32
61#define FIMC_WIDTH_ITU_709 1280 61#define FIMC_WIDTH_ITU_709 1280
62#define FIMC_REFRESH_MAX 60 62#define FIMC_REFRESH_MAX 60
63#define FIMC_REFRESH_MIN 12 63#define FIMC_REFRESH_MIN 12
@@ -69,9 +69,6 @@
69#define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev)) 69#define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev))
70#define get_ctx_from_ippdrv(ippdrv) container_of(ippdrv,\ 70#define get_ctx_from_ippdrv(ippdrv) container_of(ippdrv,\
71 struct fimc_context, ippdrv); 71 struct fimc_context, ippdrv);
72#define fimc_read(offset) readl(ctx->regs + (offset))
73#define fimc_write(cfg, offset) writel(cfg, ctx->regs + (offset))
74
75enum fimc_wb { 72enum fimc_wb {
76 FIMC_WB_NONE, 73 FIMC_WB_NONE,
77 FIMC_WB_A, 74 FIMC_WB_A,
@@ -161,7 +158,7 @@ struct fimc_context {
161 struct exynos_drm_ippdrv ippdrv; 158 struct exynos_drm_ippdrv ippdrv;
162 struct resource *regs_res; 159 struct resource *regs_res;
163 void __iomem *regs; 160 void __iomem *regs;
164 struct mutex lock; 161 spinlock_t lock;
165 struct clk *clocks[FIMC_CLKS_MAX]; 162 struct clk *clocks[FIMC_CLKS_MAX];
166 u32 clk_frequency; 163 u32 clk_frequency;
167 struct regmap *sysreg; 164 struct regmap *sysreg;
@@ -172,39 +169,53 @@ struct fimc_context {
172 bool suspended; 169 bool suspended;
173}; 170};
174 171
172static u32 fimc_read(struct fimc_context *ctx, u32 reg)
173{
174 return readl(ctx->regs + reg);
175}
176
177static void fimc_write(struct fimc_context *ctx, u32 val, u32 reg)
178{
179 writel(val, ctx->regs + reg);
180}
181
182static void fimc_set_bits(struct fimc_context *ctx, u32 reg, u32 bits)
183{
184 void __iomem *r = ctx->regs + reg;
185
186 writel(readl(r) | bits, r);
187}
188
189static void fimc_clear_bits(struct fimc_context *ctx, u32 reg, u32 bits)
190{
191 void __iomem *r = ctx->regs + reg;
192
193 writel(readl(r) & ~bits, r);
194}
195
175static void fimc_sw_reset(struct fimc_context *ctx) 196static void fimc_sw_reset(struct fimc_context *ctx)
176{ 197{
177 u32 cfg; 198 u32 cfg;
178 199
179 /* stop dma operation */ 200 /* stop dma operation */
180 cfg = fimc_read(EXYNOS_CISTATUS); 201 cfg = fimc_read(ctx, EXYNOS_CISTATUS);
181 if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) { 202 if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg))
182 cfg = fimc_read(EXYNOS_MSCTRL); 203 fimc_clear_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
183 cfg &= ~EXYNOS_MSCTRL_ENVID;
184 fimc_write(cfg, EXYNOS_MSCTRL);
185 }
186 204
187 cfg = fimc_read(EXYNOS_CISRCFMT); 205 fimc_set_bits(ctx, EXYNOS_CISRCFMT, EXYNOS_CISRCFMT_ITU601_8BIT);
188 cfg |= EXYNOS_CISRCFMT_ITU601_8BIT;
189 fimc_write(cfg, EXYNOS_CISRCFMT);
190 206
191 /* disable image capture */ 207 /* disable image capture */
192 cfg = fimc_read(EXYNOS_CIIMGCPT); 208 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT,
193 cfg &= ~(EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 209 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
194 fimc_write(cfg, EXYNOS_CIIMGCPT);
195 210
196 /* s/w reset */ 211 /* s/w reset */
197 cfg = fimc_read(EXYNOS_CIGCTRL); 212 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST);
198 cfg |= (EXYNOS_CIGCTRL_SWRST);
199 fimc_write(cfg, EXYNOS_CIGCTRL);
200 213
201 /* s/w reset complete */ 214 /* s/w reset complete */
202 cfg = fimc_read(EXYNOS_CIGCTRL); 215 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST);
203 cfg &= ~EXYNOS_CIGCTRL_SWRST;
204 fimc_write(cfg, EXYNOS_CIGCTRL);
205 216
206 /* reset sequence */ 217 /* reset sequence */
207 fimc_write(0x0, EXYNOS_CIFCNTSEQ); 218 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
208} 219}
209 220
210static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx) 221static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)
@@ -220,7 +231,7 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
220 231
221 DRM_DEBUG_KMS("wb[%d]\n", wb); 232 DRM_DEBUG_KMS("wb[%d]\n", wb);
222 233
223 cfg = fimc_read(EXYNOS_CIGCTRL); 234 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
224 cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK | 235 cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
225 EXYNOS_CIGCTRL_SELCAM_ITU_MASK | 236 EXYNOS_CIGCTRL_SELCAM_ITU_MASK |
226 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK | 237 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK |
@@ -246,7 +257,7 @@ static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
246 break; 257 break;
247 } 258 }
248 259
249 fimc_write(cfg, EXYNOS_CIGCTRL); 260 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
250} 261}
251 262
252static void fimc_set_polarity(struct fimc_context *ctx, 263static void fimc_set_polarity(struct fimc_context *ctx,
@@ -259,7 +270,7 @@ static void fimc_set_polarity(struct fimc_context *ctx,
259 DRM_DEBUG_KMS("inv_href[%d]inv_hsync[%d]\n", 270 DRM_DEBUG_KMS("inv_href[%d]inv_hsync[%d]\n",
260 pol->inv_href, pol->inv_hsync); 271 pol->inv_href, pol->inv_hsync);
261 272
262 cfg = fimc_read(EXYNOS_CIGCTRL); 273 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
263 cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC | 274 cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC |
264 EXYNOS_CIGCTRL_INVPOLHREF | EXYNOS_CIGCTRL_INVPOLHSYNC); 275 EXYNOS_CIGCTRL_INVPOLHREF | EXYNOS_CIGCTRL_INVPOLHSYNC);
265 276
@@ -272,7 +283,7 @@ static void fimc_set_polarity(struct fimc_context *ctx,
272 if (pol->inv_hsync) 283 if (pol->inv_hsync)
273 cfg |= EXYNOS_CIGCTRL_INVPOLHSYNC; 284 cfg |= EXYNOS_CIGCTRL_INVPOLHSYNC;
274 285
275 fimc_write(cfg, EXYNOS_CIGCTRL); 286 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
276} 287}
277 288
278static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable) 289static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
@@ -281,70 +292,54 @@ static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
281 292
282 DRM_DEBUG_KMS("enable[%d]\n", enable); 293 DRM_DEBUG_KMS("enable[%d]\n", enable);
283 294
284 cfg = fimc_read(EXYNOS_CIGCTRL); 295 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
285 if (enable) 296 if (enable)
286 cfg |= EXYNOS_CIGCTRL_CAM_JPEG; 297 cfg |= EXYNOS_CIGCTRL_CAM_JPEG;
287 else 298 else
288 cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG; 299 cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG;
289 300
290 fimc_write(cfg, EXYNOS_CIGCTRL); 301 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
291} 302}
292 303
293static void fimc_handle_irq(struct fimc_context *ctx, bool enable, 304static void fimc_mask_irq(struct fimc_context *ctx, bool enable)
294 bool overflow, bool level)
295{ 305{
296 u32 cfg; 306 u32 cfg;
297 307
298 DRM_DEBUG_KMS("enable[%d]overflow[%d]level[%d]\n", 308 DRM_DEBUG_KMS("enable[%d]\n", enable);
299 enable, overflow, level);
300 309
301 cfg = fimc_read(EXYNOS_CIGCTRL); 310 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
302 if (enable) { 311 if (enable) {
303 cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_LEVEL); 312 cfg &= ~EXYNOS_CIGCTRL_IRQ_OVFEN;
304 cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE; 313 cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE | EXYNOS_CIGCTRL_IRQ_LEVEL;
305 if (overflow)
306 cfg |= EXYNOS_CIGCTRL_IRQ_OVFEN;
307 if (level)
308 cfg |= EXYNOS_CIGCTRL_IRQ_LEVEL;
309 } else 314 } else
310 cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_ENABLE); 315 cfg &= ~EXYNOS_CIGCTRL_IRQ_ENABLE;
311 316 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
312 fimc_write(cfg, EXYNOS_CIGCTRL);
313} 317}
314 318
315static void fimc_clear_irq(struct fimc_context *ctx) 319static void fimc_clear_irq(struct fimc_context *ctx)
316{ 320{
317 u32 cfg; 321 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_CLR);
318
319 cfg = fimc_read(EXYNOS_CIGCTRL);
320 cfg |= EXYNOS_CIGCTRL_IRQ_CLR;
321 fimc_write(cfg, EXYNOS_CIGCTRL);
322} 322}
323 323
324static bool fimc_check_ovf(struct fimc_context *ctx) 324static bool fimc_check_ovf(struct fimc_context *ctx)
325{ 325{
326 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 326 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
327 u32 cfg, status, flag; 327 u32 status, flag;
328 328
329 status = fimc_read(EXYNOS_CISTATUS); 329 status = fimc_read(ctx, EXYNOS_CISTATUS);
330 flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB | 330 flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB |
331 EXYNOS_CISTATUS_OVFICR; 331 EXYNOS_CISTATUS_OVFICR;
332 332
333 DRM_DEBUG_KMS("flag[0x%x]\n", flag); 333 DRM_DEBUG_KMS("flag[0x%x]\n", flag);
334 334
335 if (status & flag) { 335 if (status & flag) {
336 cfg = fimc_read(EXYNOS_CIWDOFST); 336 fimc_set_bits(ctx, EXYNOS_CIWDOFST,
337 cfg |= (EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | 337 EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
338 EXYNOS_CIWDOFST_CLROVFICR); 338 EXYNOS_CIWDOFST_CLROVFICR);
339 339 fimc_clear_bits(ctx, EXYNOS_CIWDOFST,
340 fimc_write(cfg, EXYNOS_CIWDOFST); 340 EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
341
342 cfg = fimc_read(EXYNOS_CIWDOFST);
343 cfg &= ~(EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
344 EXYNOS_CIWDOFST_CLROVFICR); 341 EXYNOS_CIWDOFST_CLROVFICR);
345 342
346 fimc_write(cfg, EXYNOS_CIWDOFST);
347
348 dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", 343 dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n",
349 ctx->id, status); 344 ctx->id, status);
350 return true; 345 return true;
@@ -357,7 +352,7 @@ static bool fimc_check_frame_end(struct fimc_context *ctx)
357{ 352{
358 u32 cfg; 353 u32 cfg;
359 354
360 cfg = fimc_read(EXYNOS_CISTATUS); 355 cfg = fimc_read(ctx, EXYNOS_CISTATUS);
361 356
362 DRM_DEBUG_KMS("cfg[0x%x]\n", cfg); 357 DRM_DEBUG_KMS("cfg[0x%x]\n", cfg);
363 358
@@ -365,7 +360,7 @@ static bool fimc_check_frame_end(struct fimc_context *ctx)
365 return false; 360 return false;
366 361
367 cfg &= ~(EXYNOS_CISTATUS_FRAMEEND); 362 cfg &= ~(EXYNOS_CISTATUS_FRAMEEND);
368 fimc_write(cfg, EXYNOS_CISTATUS); 363 fimc_write(ctx, cfg, EXYNOS_CISTATUS);
369 364
370 return true; 365 return true;
371} 366}
@@ -375,7 +370,7 @@ static int fimc_get_buf_id(struct fimc_context *ctx)
375 u32 cfg; 370 u32 cfg;
376 int frame_cnt, buf_id; 371 int frame_cnt, buf_id;
377 372
378 cfg = fimc_read(EXYNOS_CISTATUS2); 373 cfg = fimc_read(ctx, EXYNOS_CISTATUS2);
379 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg); 374 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
380 375
381 if (frame_cnt == 0) 376 if (frame_cnt == 0)
@@ -402,13 +397,13 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
402 397
403 DRM_DEBUG_KMS("enable[%d]\n", enable); 398 DRM_DEBUG_KMS("enable[%d]\n", enable);
404 399
405 cfg = fimc_read(EXYNOS_CIOCTRL); 400 cfg = fimc_read(ctx, EXYNOS_CIOCTRL);
406 if (enable) 401 if (enable)
407 cfg |= EXYNOS_CIOCTRL_LASTENDEN; 402 cfg |= EXYNOS_CIOCTRL_LASTENDEN;
408 else 403 else
409 cfg &= ~EXYNOS_CIOCTRL_LASTENDEN; 404 cfg &= ~EXYNOS_CIOCTRL_LASTENDEN;
410 405
411 fimc_write(cfg, EXYNOS_CIOCTRL); 406 fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
412} 407}
413 408
414 409
@@ -420,18 +415,18 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
420 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 415 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
421 416
422 /* RGB */ 417 /* RGB */
423 cfg = fimc_read(EXYNOS_CISCCTRL); 418 cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
424 cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK; 419 cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK;
425 420
426 switch (fmt) { 421 switch (fmt) {
427 case DRM_FORMAT_RGB565: 422 case DRM_FORMAT_RGB565:
428 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565; 423 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565;
429 fimc_write(cfg, EXYNOS_CISCCTRL); 424 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
430 return 0; 425 return 0;
431 case DRM_FORMAT_RGB888: 426 case DRM_FORMAT_RGB888:
432 case DRM_FORMAT_XRGB8888: 427 case DRM_FORMAT_XRGB8888:
433 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888; 428 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888;
434 fimc_write(cfg, EXYNOS_CISCCTRL); 429 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
435 return 0; 430 return 0;
436 default: 431 default:
437 /* bypass */ 432 /* bypass */
@@ -439,7 +434,7 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
439 } 434 }
440 435
441 /* YUV */ 436 /* YUV */
442 cfg = fimc_read(EXYNOS_MSCTRL); 437 cfg = fimc_read(ctx, EXYNOS_MSCTRL);
443 cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK | 438 cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK |
444 EXYNOS_MSCTRL_C_INT_IN_2PLANE | 439 EXYNOS_MSCTRL_C_INT_IN_2PLANE |
445 EXYNOS_MSCTRL_ORDER422_YCBYCR); 440 EXYNOS_MSCTRL_ORDER422_YCBYCR);
@@ -479,7 +474,7 @@ static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
479 return -EINVAL; 474 return -EINVAL;
480 } 475 }
481 476
482 fimc_write(cfg, EXYNOS_MSCTRL); 477 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
483 478
484 return 0; 479 return 0;
485} 480}
@@ -492,7 +487,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
492 487
493 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 488 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
494 489
495 cfg = fimc_read(EXYNOS_MSCTRL); 490 cfg = fimc_read(ctx, EXYNOS_MSCTRL);
496 cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB; 491 cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB;
497 492
498 switch (fmt) { 493 switch (fmt) {
@@ -527,9 +522,9 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
527 return -EINVAL; 522 return -EINVAL;
528 } 523 }
529 524
530 fimc_write(cfg, EXYNOS_MSCTRL); 525 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
531 526
532 cfg = fimc_read(EXYNOS_CIDMAPARAM); 527 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
533 cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK; 528 cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK;
534 529
535 if (fmt == DRM_FORMAT_NV12MT) 530 if (fmt == DRM_FORMAT_NV12MT)
@@ -537,7 +532,7 @@ static int fimc_src_set_fmt(struct device *dev, u32 fmt)
537 else 532 else
538 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR; 533 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
539 534
540 fimc_write(cfg, EXYNOS_CIDMAPARAM); 535 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
541 536
542 return fimc_src_set_fmt_order(ctx, fmt); 537 return fimc_src_set_fmt_order(ctx, fmt);
543} 538}
@@ -552,11 +547,11 @@ static int fimc_src_set_transf(struct device *dev,
552 547
553 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip); 548 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
554 549
555 cfg1 = fimc_read(EXYNOS_MSCTRL); 550 cfg1 = fimc_read(ctx, EXYNOS_MSCTRL);
556 cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR | 551 cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
557 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 552 EXYNOS_MSCTRL_FLIP_Y_MIRROR);
558 553
559 cfg2 = fimc_read(EXYNOS_CITRGFMT); 554 cfg2 = fimc_read(ctx, EXYNOS_CITRGFMT);
560 cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 555 cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
561 556
562 switch (degree) { 557 switch (degree) {
@@ -595,8 +590,8 @@ static int fimc_src_set_transf(struct device *dev,
595 return -EINVAL; 590 return -EINVAL;
596 } 591 }
597 592
598 fimc_write(cfg1, EXYNOS_MSCTRL); 593 fimc_write(ctx, cfg1, EXYNOS_MSCTRL);
599 fimc_write(cfg2, EXYNOS_CITRGFMT); 594 fimc_write(ctx, cfg2, EXYNOS_CITRGFMT);
600 *swap = (cfg2 & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) ? 1 : 0; 595 *swap = (cfg2 & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) ? 1 : 0;
601 596
602 return 0; 597 return 0;
@@ -621,17 +616,17 @@ static int fimc_set_window(struct fimc_context *ctx,
621 * set window offset 1, 2 size 616 * set window offset 1, 2 size
622 * check figure 43-21 in user manual 617 * check figure 43-21 in user manual
623 */ 618 */
624 cfg = fimc_read(EXYNOS_CIWDOFST); 619 cfg = fimc_read(ctx, EXYNOS_CIWDOFST);
625 cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK | 620 cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK |
626 EXYNOS_CIWDOFST_WINVEROFST_MASK); 621 EXYNOS_CIWDOFST_WINVEROFST_MASK);
627 cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) | 622 cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) |
628 EXYNOS_CIWDOFST_WINVEROFST(v1)); 623 EXYNOS_CIWDOFST_WINVEROFST(v1));
629 cfg |= EXYNOS_CIWDOFST_WINOFSEN; 624 cfg |= EXYNOS_CIWDOFST_WINOFSEN;
630 fimc_write(cfg, EXYNOS_CIWDOFST); 625 fimc_write(ctx, cfg, EXYNOS_CIWDOFST);
631 626
632 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) | 627 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) |
633 EXYNOS_CIWDOFST2_WINVEROFST2(v2)); 628 EXYNOS_CIWDOFST2_WINVEROFST2(v2));
634 fimc_write(cfg, EXYNOS_CIWDOFST2); 629 fimc_write(ctx, cfg, EXYNOS_CIWDOFST2);
635 630
636 return 0; 631 return 0;
637} 632}
@@ -651,7 +646,7 @@ static int fimc_src_set_size(struct device *dev, int swap,
651 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) | 646 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) |
652 EXYNOS_ORGISIZE_VERTICAL(img_sz.vsize)); 647 EXYNOS_ORGISIZE_VERTICAL(img_sz.vsize));
653 648
654 fimc_write(cfg, EXYNOS_ORGISIZE); 649 fimc_write(ctx, cfg, EXYNOS_ORGISIZE);
655 650
656 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h); 651 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h);
657 652
@@ -663,12 +658,12 @@ static int fimc_src_set_size(struct device *dev, int swap,
663 } 658 }
664 659
665 /* set input DMA image size */ 660 /* set input DMA image size */
666 cfg = fimc_read(EXYNOS_CIREAL_ISIZE); 661 cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE);
667 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK | 662 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK |
668 EXYNOS_CIREAL_ISIZE_WIDTH_MASK); 663 EXYNOS_CIREAL_ISIZE_WIDTH_MASK);
669 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(img_pos.w) | 664 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(img_pos.w) |
670 EXYNOS_CIREAL_ISIZE_HEIGHT(img_pos.h)); 665 EXYNOS_CIREAL_ISIZE_HEIGHT(img_pos.h));
671 fimc_write(cfg, EXYNOS_CIREAL_ISIZE); 666 fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE);
672 667
673 /* 668 /*
674 * set input FIFO image size 669 * set input FIFO image size
@@ -677,18 +672,18 @@ static int fimc_src_set_size(struct device *dev, int swap,
677 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT | 672 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT |
678 EXYNOS_CISRCFMT_SOURCEHSIZE(img_sz.hsize) | 673 EXYNOS_CISRCFMT_SOURCEHSIZE(img_sz.hsize) |
679 EXYNOS_CISRCFMT_SOURCEVSIZE(img_sz.vsize)); 674 EXYNOS_CISRCFMT_SOURCEVSIZE(img_sz.vsize));
680 fimc_write(cfg, EXYNOS_CISRCFMT); 675 fimc_write(ctx, cfg, EXYNOS_CISRCFMT);
681 676
682 /* offset Y(RGB), Cb, Cr */ 677 /* offset Y(RGB), Cb, Cr */
683 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(img_pos.x) | 678 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(img_pos.x) |
684 EXYNOS_CIIYOFF_VERTICAL(img_pos.y)); 679 EXYNOS_CIIYOFF_VERTICAL(img_pos.y));
685 fimc_write(cfg, EXYNOS_CIIYOFF); 680 fimc_write(ctx, cfg, EXYNOS_CIIYOFF);
686 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(img_pos.x) | 681 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(img_pos.x) |
687 EXYNOS_CIICBOFF_VERTICAL(img_pos.y)); 682 EXYNOS_CIICBOFF_VERTICAL(img_pos.y));
688 fimc_write(cfg, EXYNOS_CIICBOFF); 683 fimc_write(ctx, cfg, EXYNOS_CIICBOFF);
689 cfg = (EXYNOS_CIICROFF_HORIZONTAL(img_pos.x) | 684 cfg = (EXYNOS_CIICROFF_HORIZONTAL(img_pos.x) |
690 EXYNOS_CIICROFF_VERTICAL(img_pos.y)); 685 EXYNOS_CIICROFF_VERTICAL(img_pos.y));
691 fimc_write(cfg, EXYNOS_CIICROFF); 686 fimc_write(ctx, cfg, EXYNOS_CIICROFF);
692 687
693 return fimc_set_window(ctx, &img_pos, &img_sz); 688 return fimc_set_window(ctx, &img_pos, &img_sz);
694} 689}
@@ -722,25 +717,25 @@ static int fimc_src_set_addr(struct device *dev,
722 switch (buf_type) { 717 switch (buf_type) {
723 case IPP_BUF_ENQUEUE: 718 case IPP_BUF_ENQUEUE:
724 config = &property->config[EXYNOS_DRM_OPS_SRC]; 719 config = &property->config[EXYNOS_DRM_OPS_SRC];
725 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y], 720 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
726 EXYNOS_CIIYSA(buf_id)); 721 EXYNOS_CIIYSA(buf_id));
727 722
728 if (config->fmt == DRM_FORMAT_YVU420) { 723 if (config->fmt == DRM_FORMAT_YVU420) {
729 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR], 724 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
730 EXYNOS_CIICBSA(buf_id)); 725 EXYNOS_CIICBSA(buf_id));
731 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB], 726 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
732 EXYNOS_CIICRSA(buf_id)); 727 EXYNOS_CIICRSA(buf_id));
733 } else { 728 } else {
734 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB], 729 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
735 EXYNOS_CIICBSA(buf_id)); 730 EXYNOS_CIICBSA(buf_id));
736 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR], 731 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
737 EXYNOS_CIICRSA(buf_id)); 732 EXYNOS_CIICRSA(buf_id));
738 } 733 }
739 break; 734 break;
740 case IPP_BUF_DEQUEUE: 735 case IPP_BUF_DEQUEUE:
741 fimc_write(0x0, EXYNOS_CIIYSA(buf_id)); 736 fimc_write(ctx, 0x0, EXYNOS_CIIYSA(buf_id));
742 fimc_write(0x0, EXYNOS_CIICBSA(buf_id)); 737 fimc_write(ctx, 0x0, EXYNOS_CIICBSA(buf_id));
743 fimc_write(0x0, EXYNOS_CIICRSA(buf_id)); 738 fimc_write(ctx, 0x0, EXYNOS_CIICRSA(buf_id));
744 break; 739 break;
745 default: 740 default:
746 /* bypass */ 741 /* bypass */
@@ -765,22 +760,22 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
765 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 760 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
766 761
767 /* RGB */ 762 /* RGB */
768 cfg = fimc_read(EXYNOS_CISCCTRL); 763 cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
769 cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK; 764 cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK;
770 765
771 switch (fmt) { 766 switch (fmt) {
772 case DRM_FORMAT_RGB565: 767 case DRM_FORMAT_RGB565:
773 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565; 768 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565;
774 fimc_write(cfg, EXYNOS_CISCCTRL); 769 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
775 return 0; 770 return 0;
776 case DRM_FORMAT_RGB888: 771 case DRM_FORMAT_RGB888:
777 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888; 772 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888;
778 fimc_write(cfg, EXYNOS_CISCCTRL); 773 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
779 return 0; 774 return 0;
780 case DRM_FORMAT_XRGB8888: 775 case DRM_FORMAT_XRGB8888:
781 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 | 776 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 |
782 EXYNOS_CISCCTRL_EXTRGB_EXTENSION); 777 EXYNOS_CISCCTRL_EXTRGB_EXTENSION);
783 fimc_write(cfg, EXYNOS_CISCCTRL); 778 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
784 break; 779 break;
785 default: 780 default:
786 /* bypass */ 781 /* bypass */
@@ -788,7 +783,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
788 } 783 }
789 784
790 /* YUV */ 785 /* YUV */
791 cfg = fimc_read(EXYNOS_CIOCTRL); 786 cfg = fimc_read(ctx, EXYNOS_CIOCTRL);
792 cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK | 787 cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK |
793 EXYNOS_CIOCTRL_ORDER422_MASK | 788 EXYNOS_CIOCTRL_ORDER422_MASK |
794 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK); 789 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK);
@@ -830,7 +825,7 @@ static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
830 return -EINVAL; 825 return -EINVAL;
831 } 826 }
832 827
833 fimc_write(cfg, EXYNOS_CIOCTRL); 828 fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
834 829
835 return 0; 830 return 0;
836} 831}
@@ -843,16 +838,16 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
843 838
844 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 839 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt);
845 840
846 cfg = fimc_read(EXYNOS_CIEXTEN); 841 cfg = fimc_read(ctx, EXYNOS_CIEXTEN);
847 842
848 if (fmt == DRM_FORMAT_AYUV) { 843 if (fmt == DRM_FORMAT_AYUV) {
849 cfg |= EXYNOS_CIEXTEN_YUV444_OUT; 844 cfg |= EXYNOS_CIEXTEN_YUV444_OUT;
850 fimc_write(cfg, EXYNOS_CIEXTEN); 845 fimc_write(ctx, cfg, EXYNOS_CIEXTEN);
851 } else { 846 } else {
852 cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT; 847 cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT;
853 fimc_write(cfg, EXYNOS_CIEXTEN); 848 fimc_write(ctx, cfg, EXYNOS_CIEXTEN);
854 849
855 cfg = fimc_read(EXYNOS_CITRGFMT); 850 cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
856 cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK; 851 cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK;
857 852
858 switch (fmt) { 853 switch (fmt) {
@@ -885,10 +880,10 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
885 return -EINVAL; 880 return -EINVAL;
886 } 881 }
887 882
888 fimc_write(cfg, EXYNOS_CITRGFMT); 883 fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
889 } 884 }
890 885
891 cfg = fimc_read(EXYNOS_CIDMAPARAM); 886 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
892 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK; 887 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK;
893 888
894 if (fmt == DRM_FORMAT_NV12MT) 889 if (fmt == DRM_FORMAT_NV12MT)
@@ -896,7 +891,7 @@ static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
896 else 891 else
897 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR; 892 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
898 893
899 fimc_write(cfg, EXYNOS_CIDMAPARAM); 894 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
900 895
901 return fimc_dst_set_fmt_order(ctx, fmt); 896 return fimc_dst_set_fmt_order(ctx, fmt);
902} 897}
@@ -911,7 +906,7 @@ static int fimc_dst_set_transf(struct device *dev,
911 906
912 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip); 907 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip);
913 908
914 cfg = fimc_read(EXYNOS_CITRGFMT); 909 cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
915 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK; 910 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
916 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 911 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
917 912
@@ -951,53 +946,23 @@ static int fimc_dst_set_transf(struct device *dev,
951 return -EINVAL; 946 return -EINVAL;
952 } 947 }
953 948
954 fimc_write(cfg, EXYNOS_CITRGFMT); 949 fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
955 *swap = (cfg & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) ? 1 : 0; 950 *swap = (cfg & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) ? 1 : 0;
956 951
957 return 0; 952 return 0;
958} 953}
959 954
960static int fimc_get_ratio_shift(u32 src, u32 dst, u32 *ratio, u32 *shift)
961{
962 DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst);
963
964 if (src >= dst * 64) {
965 DRM_ERROR("failed to make ratio and shift.\n");
966 return -EINVAL;
967 } else if (src >= dst * 32) {
968 *ratio = 32;
969 *shift = 5;
970 } else if (src >= dst * 16) {
971 *ratio = 16;
972 *shift = 4;
973 } else if (src >= dst * 8) {
974 *ratio = 8;
975 *shift = 3;
976 } else if (src >= dst * 4) {
977 *ratio = 4;
978 *shift = 2;
979 } else if (src >= dst * 2) {
980 *ratio = 2;
981 *shift = 1;
982 } else {
983 *ratio = 1;
984 *shift = 0;
985 }
986
987 return 0;
988}
989
990static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, 955static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
991 struct drm_exynos_pos *src, struct drm_exynos_pos *dst) 956 struct drm_exynos_pos *src, struct drm_exynos_pos *dst)
992{ 957{
993 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 958 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
994 u32 cfg, cfg_ext, shfactor; 959 u32 cfg, cfg_ext, shfactor;
995 u32 pre_dst_width, pre_dst_height; 960 u32 pre_dst_width, pre_dst_height;
996 u32 pre_hratio, hfactor, pre_vratio, vfactor; 961 u32 hfactor, vfactor;
997 int ret = 0; 962 int ret = 0;
998 u32 src_w, src_h, dst_w, dst_h; 963 u32 src_w, src_h, dst_w, dst_h;
999 964
1000 cfg_ext = fimc_read(EXYNOS_CITRGFMT); 965 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT);
1001 if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) { 966 if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) {
1002 src_w = src->h; 967 src_w = src->h;
1003 src_h = src->w; 968 src_h = src->w;
@@ -1014,24 +979,24 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
1014 dst_h = dst->h; 979 dst_h = dst->h;
1015 } 980 }
1016 981
1017 ret = fimc_get_ratio_shift(src_w, dst_w, &pre_hratio, &hfactor); 982 /* fimc_ippdrv_check_property assures that dividers are not null */
1018 if (ret) { 983 hfactor = fls(src_w / dst_w / 2);
984 if (hfactor > FIMC_SHFACTOR / 2) {
1019 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n"); 985 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n");
1020 return ret; 986 return -EINVAL;
1021 } 987 }
1022 988
1023 ret = fimc_get_ratio_shift(src_h, dst_h, &pre_vratio, &vfactor); 989 vfactor = fls(src_h / dst_h / 2);
1024 if (ret) { 990 if (vfactor > FIMC_SHFACTOR / 2) {
1025 dev_err(ippdrv->dev, "failed to get ratio vertical.\n"); 991 dev_err(ippdrv->dev, "failed to get ratio vertical.\n");
1026 return ret; 992 return -EINVAL;
1027 } 993 }
1028 994
1029 pre_dst_width = src_w / pre_hratio; 995 pre_dst_width = src_w >> hfactor;
1030 pre_dst_height = src_h / pre_vratio; 996 pre_dst_height = src_h >> vfactor;
1031 DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n", 997 DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n",
1032 pre_dst_width, pre_dst_height); 998 pre_dst_width, pre_dst_height);
1033 DRM_DEBUG_KMS("pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n", 999 DRM_DEBUG_KMS("hfactor[%d]vfactor[%d]\n", hfactor, vfactor);
1034 pre_hratio, hfactor, pre_vratio, vfactor);
1035 1000
1036 sc->hratio = (src_w << 14) / (dst_w << hfactor); 1001 sc->hratio = (src_w << 14) / (dst_w << hfactor);
1037 sc->vratio = (src_h << 14) / (dst_h << vfactor); 1002 sc->vratio = (src_h << 14) / (dst_h << vfactor);
@@ -1044,13 +1009,13 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
1044 DRM_DEBUG_KMS("shfactor[%d]\n", shfactor); 1009 DRM_DEBUG_KMS("shfactor[%d]\n", shfactor);
1045 1010
1046 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) | 1011 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
1047 EXYNOS_CISCPRERATIO_PREHORRATIO(pre_hratio) | 1012 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) |
1048 EXYNOS_CISCPRERATIO_PREVERRATIO(pre_vratio)); 1013 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor));
1049 fimc_write(cfg, EXYNOS_CISCPRERATIO); 1014 fimc_write(ctx, cfg, EXYNOS_CISCPRERATIO);
1050 1015
1051 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) | 1016 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) |
1052 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height)); 1017 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height));
1053 fimc_write(cfg, EXYNOS_CISCPREDST); 1018 fimc_write(ctx, cfg, EXYNOS_CISCPREDST);
1054 1019
1055 return ret; 1020 return ret;
1056} 1021}
@@ -1064,7 +1029,7 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
1064 DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n", 1029 DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n",
1065 sc->hratio, sc->vratio); 1030 sc->hratio, sc->vratio);
1066 1031
1067 cfg = fimc_read(EXYNOS_CISCCTRL); 1032 cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
1068 cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS | 1033 cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS |
1069 EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V | 1034 EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V |
1070 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK | 1035 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK |
@@ -1084,14 +1049,14 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
1084 1049
1085 cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) | 1050 cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) |
1086 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6))); 1051 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6)));
1087 fimc_write(cfg, EXYNOS_CISCCTRL); 1052 fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
1088 1053
1089 cfg_ext = fimc_read(EXYNOS_CIEXTEN); 1054 cfg_ext = fimc_read(ctx, EXYNOS_CIEXTEN);
1090 cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK; 1055 cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK;
1091 cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK; 1056 cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK;
1092 cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) | 1057 cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) |
1093 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio)); 1058 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio));
1094 fimc_write(cfg_ext, EXYNOS_CIEXTEN); 1059 fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN);
1095} 1060}
1096 1061
1097static int fimc_dst_set_size(struct device *dev, int swap, 1062static int fimc_dst_set_size(struct device *dev, int swap,
@@ -1109,12 +1074,12 @@ static int fimc_dst_set_size(struct device *dev, int swap,
1109 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) | 1074 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) |
1110 EXYNOS_ORGOSIZE_VERTICAL(img_sz.vsize)); 1075 EXYNOS_ORGOSIZE_VERTICAL(img_sz.vsize));
1111 1076
1112 fimc_write(cfg, EXYNOS_ORGOSIZE); 1077 fimc_write(ctx, cfg, EXYNOS_ORGOSIZE);
1113 1078
1114 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h); 1079 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h);
1115 1080
1116 /* CSC ITU */ 1081 /* CSC ITU */
1117 cfg = fimc_read(EXYNOS_CIGCTRL); 1082 cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
1118 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK; 1083 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK;
1119 1084
1120 if (sz->hsize >= FIMC_WIDTH_ITU_709) 1085 if (sz->hsize >= FIMC_WIDTH_ITU_709)
@@ -1122,7 +1087,7 @@ static int fimc_dst_set_size(struct device *dev, int swap,
1122 else 1087 else
1123 cfg |= EXYNOS_CIGCTRL_CSC_ITU601; 1088 cfg |= EXYNOS_CIGCTRL_CSC_ITU601;
1124 1089
1125 fimc_write(cfg, EXYNOS_CIGCTRL); 1090 fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
1126 1091
1127 if (swap) { 1092 if (swap) {
1128 img_pos.w = pos->h; 1093 img_pos.w = pos->h;
@@ -1132,41 +1097,38 @@ static int fimc_dst_set_size(struct device *dev, int swap,
1132 } 1097 }
1133 1098
1134 /* target image size */ 1099 /* target image size */
1135 cfg = fimc_read(EXYNOS_CITRGFMT); 1100 cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
1136 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK | 1101 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK |
1137 EXYNOS_CITRGFMT_TARGETV_MASK); 1102 EXYNOS_CITRGFMT_TARGETV_MASK);
1138 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(img_pos.w) | 1103 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(img_pos.w) |
1139 EXYNOS_CITRGFMT_TARGETVSIZE(img_pos.h)); 1104 EXYNOS_CITRGFMT_TARGETVSIZE(img_pos.h));
1140 fimc_write(cfg, EXYNOS_CITRGFMT); 1105 fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
1141 1106
1142 /* target area */ 1107 /* target area */
1143 cfg = EXYNOS_CITAREA_TARGET_AREA(img_pos.w * img_pos.h); 1108 cfg = EXYNOS_CITAREA_TARGET_AREA(img_pos.w * img_pos.h);
1144 fimc_write(cfg, EXYNOS_CITAREA); 1109 fimc_write(ctx, cfg, EXYNOS_CITAREA);
1145 1110
1146 /* offset Y(RGB), Cb, Cr */ 1111 /* offset Y(RGB), Cb, Cr */
1147 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(img_pos.x) | 1112 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(img_pos.x) |
1148 EXYNOS_CIOYOFF_VERTICAL(img_pos.y)); 1113 EXYNOS_CIOYOFF_VERTICAL(img_pos.y));
1149 fimc_write(cfg, EXYNOS_CIOYOFF); 1114 fimc_write(ctx, cfg, EXYNOS_CIOYOFF);
1150 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(img_pos.x) | 1115 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(img_pos.x) |
1151 EXYNOS_CIOCBOFF_VERTICAL(img_pos.y)); 1116 EXYNOS_CIOCBOFF_VERTICAL(img_pos.y));
1152 fimc_write(cfg, EXYNOS_CIOCBOFF); 1117 fimc_write(ctx, cfg, EXYNOS_CIOCBOFF);
1153 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(img_pos.x) | 1118 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(img_pos.x) |
1154 EXYNOS_CIOCROFF_VERTICAL(img_pos.y)); 1119 EXYNOS_CIOCROFF_VERTICAL(img_pos.y));
1155 fimc_write(cfg, EXYNOS_CIOCROFF); 1120 fimc_write(ctx, cfg, EXYNOS_CIOCROFF);
1156 1121
1157 return 0; 1122 return 0;
1158} 1123}
1159 1124
1160static int fimc_dst_get_buf_seq(struct fimc_context *ctx) 1125static int fimc_dst_get_buf_count(struct fimc_context *ctx)
1161{ 1126{
1162 u32 cfg, i, buf_num = 0; 1127 u32 cfg, buf_num;
1163 u32 mask = 0x00000001;
1164 1128
1165 cfg = fimc_read(EXYNOS_CIFCNTSEQ); 1129 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
1166 1130
1167 for (i = 0; i < FIMC_REG_SZ; i++) 1131 buf_num = hweight32(cfg);
1168 if (cfg & (mask << i))
1169 buf_num++;
1170 1132
1171 DRM_DEBUG_KMS("buf_num[%d]\n", buf_num); 1133 DRM_DEBUG_KMS("buf_num[%d]\n", buf_num);
1172 1134
@@ -1181,13 +1143,14 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
1181 u32 cfg; 1143 u32 cfg;
1182 u32 mask = 0x00000001 << buf_id; 1144 u32 mask = 0x00000001 << buf_id;
1183 int ret = 0; 1145 int ret = 0;
1146 unsigned long flags;
1184 1147
1185 DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type); 1148 DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
1186 1149
1187 mutex_lock(&ctx->lock); 1150 spin_lock_irqsave(&ctx->lock, flags);
1188 1151
1189 /* mask register set */ 1152 /* mask register set */
1190 cfg = fimc_read(EXYNOS_CIFCNTSEQ); 1153 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
1191 1154
1192 switch (buf_type) { 1155 switch (buf_type) {
1193 case IPP_BUF_ENQUEUE: 1156 case IPP_BUF_ENQUEUE:
@@ -1205,20 +1168,20 @@ static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
1205 /* sequence id */ 1168 /* sequence id */
1206 cfg &= ~mask; 1169 cfg &= ~mask;
1207 cfg |= (enable << buf_id); 1170 cfg |= (enable << buf_id);
1208 fimc_write(cfg, EXYNOS_CIFCNTSEQ); 1171 fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ);
1209 1172
1210 /* interrupt enable */ 1173 /* interrupt enable */
1211 if (buf_type == IPP_BUF_ENQUEUE && 1174 if (buf_type == IPP_BUF_ENQUEUE &&
1212 fimc_dst_get_buf_seq(ctx) >= FIMC_BUF_START) 1175 fimc_dst_get_buf_count(ctx) >= FIMC_BUF_START)
1213 fimc_handle_irq(ctx, true, false, true); 1176 fimc_mask_irq(ctx, true);
1214 1177
1215 /* interrupt disable */ 1178 /* interrupt disable */
1216 if (buf_type == IPP_BUF_DEQUEUE && 1179 if (buf_type == IPP_BUF_DEQUEUE &&
1217 fimc_dst_get_buf_seq(ctx) <= FIMC_BUF_STOP) 1180 fimc_dst_get_buf_count(ctx) <= FIMC_BUF_STOP)
1218 fimc_handle_irq(ctx, false, false, true); 1181 fimc_mask_irq(ctx, false);
1219 1182
1220err_unlock: 1183err_unlock:
1221 mutex_unlock(&ctx->lock); 1184 spin_unlock_irqrestore(&ctx->lock, flags);
1222 return ret; 1185 return ret;
1223} 1186}
1224 1187
@@ -1252,25 +1215,25 @@ static int fimc_dst_set_addr(struct device *dev,
1252 case IPP_BUF_ENQUEUE: 1215 case IPP_BUF_ENQUEUE:
1253 config = &property->config[EXYNOS_DRM_OPS_DST]; 1216 config = &property->config[EXYNOS_DRM_OPS_DST];
1254 1217
1255 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y], 1218 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y],
1256 EXYNOS_CIOYSA(buf_id)); 1219 EXYNOS_CIOYSA(buf_id));
1257 1220
1258 if (config->fmt == DRM_FORMAT_YVU420) { 1221 if (config->fmt == DRM_FORMAT_YVU420) {
1259 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR], 1222 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
1260 EXYNOS_CIOCBSA(buf_id)); 1223 EXYNOS_CIOCBSA(buf_id));
1261 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB], 1224 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
1262 EXYNOS_CIOCRSA(buf_id)); 1225 EXYNOS_CIOCRSA(buf_id));
1263 } else { 1226 } else {
1264 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB], 1227 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB],
1265 EXYNOS_CIOCBSA(buf_id)); 1228 EXYNOS_CIOCBSA(buf_id));
1266 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR], 1229 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR],
1267 EXYNOS_CIOCRSA(buf_id)); 1230 EXYNOS_CIOCRSA(buf_id));
1268 } 1231 }
1269 break; 1232 break;
1270 case IPP_BUF_DEQUEUE: 1233 case IPP_BUF_DEQUEUE:
1271 fimc_write(0x0, EXYNOS_CIOYSA(buf_id)); 1234 fimc_write(ctx, 0x0, EXYNOS_CIOYSA(buf_id));
1272 fimc_write(0x0, EXYNOS_CIOCBSA(buf_id)); 1235 fimc_write(ctx, 0x0, EXYNOS_CIOCBSA(buf_id));
1273 fimc_write(0x0, EXYNOS_CIOCRSA(buf_id)); 1236 fimc_write(ctx, 0x0, EXYNOS_CIOCRSA(buf_id));
1274 break; 1237 break;
1275 default: 1238 default:
1276 /* bypass */ 1239 /* bypass */
@@ -1342,11 +1305,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
1342 1305
1343static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv) 1306static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1344{ 1307{
1345 struct drm_exynos_ipp_prop_list *prop_list; 1308 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list;
1346
1347 prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
1348 if (!prop_list)
1349 return -ENOMEM;
1350 1309
1351 prop_list->version = 1; 1310 prop_list->version = 1;
1352 prop_list->writeback = 1; 1311 prop_list->writeback = 1;
@@ -1371,8 +1330,6 @@ static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1371 prop_list->scale_min.hsize = FIMC_SCALE_MIN; 1330 prop_list->scale_min.hsize = FIMC_SCALE_MIN;
1372 prop_list->scale_min.vsize = FIMC_SCALE_MIN; 1331 prop_list->scale_min.vsize = FIMC_SCALE_MIN;
1373 1332
1374 ippdrv->prop_list = prop_list;
1375
1376 return 0; 1333 return 0;
1377} 1334}
1378 1335
@@ -1395,7 +1352,7 @@ static int fimc_ippdrv_check_property(struct device *dev,
1395{ 1352{
1396 struct fimc_context *ctx = get_fimc_context(dev); 1353 struct fimc_context *ctx = get_fimc_context(dev);
1397 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1354 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1398 struct drm_exynos_ipp_prop_list *pp = ippdrv->prop_list; 1355 struct drm_exynos_ipp_prop_list *pp = &ippdrv->prop_list;
1399 struct drm_exynos_ipp_config *config; 1356 struct drm_exynos_ipp_config *config;
1400 struct drm_exynos_pos *pos; 1357 struct drm_exynos_pos *pos;
1401 struct drm_exynos_sz *sz; 1358 struct drm_exynos_sz *sz;
@@ -1508,15 +1465,15 @@ static void fimc_clear_addr(struct fimc_context *ctx)
1508 int i; 1465 int i;
1509 1466
1510 for (i = 0; i < FIMC_MAX_SRC; i++) { 1467 for (i = 0; i < FIMC_MAX_SRC; i++) {
1511 fimc_write(0, EXYNOS_CIIYSA(i)); 1468 fimc_write(ctx, 0, EXYNOS_CIIYSA(i));
1512 fimc_write(0, EXYNOS_CIICBSA(i)); 1469 fimc_write(ctx, 0, EXYNOS_CIICBSA(i));
1513 fimc_write(0, EXYNOS_CIICRSA(i)); 1470 fimc_write(ctx, 0, EXYNOS_CIICRSA(i));
1514 } 1471 }
1515 1472
1516 for (i = 0; i < FIMC_MAX_DST; i++) { 1473 for (i = 0; i < FIMC_MAX_DST; i++) {
1517 fimc_write(0, EXYNOS_CIOYSA(i)); 1474 fimc_write(ctx, 0, EXYNOS_CIOYSA(i));
1518 fimc_write(0, EXYNOS_CIOCBSA(i)); 1475 fimc_write(ctx, 0, EXYNOS_CIOCBSA(i));
1519 fimc_write(0, EXYNOS_CIOCRSA(i)); 1476 fimc_write(ctx, 0, EXYNOS_CIOCRSA(i));
1520 } 1477 }
1521} 1478}
1522 1479
@@ -1556,7 +1513,7 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1556 1513
1557 property = &c_node->property; 1514 property = &c_node->property;
1558 1515
1559 fimc_handle_irq(ctx, true, false, true); 1516 fimc_mask_irq(ctx, true);
1560 1517
1561 for_each_ipp_ops(i) { 1518 for_each_ipp_ops(i) {
1562 config = &property->config[i]; 1519 config = &property->config[i];
@@ -1582,10 +1539,10 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1582 fimc_handle_lastend(ctx, false); 1539 fimc_handle_lastend(ctx, false);
1583 1540
1584 /* setup dma */ 1541 /* setup dma */
1585 cfg0 = fimc_read(EXYNOS_MSCTRL); 1542 cfg0 = fimc_read(ctx, EXYNOS_MSCTRL);
1586 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK; 1543 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK;
1587 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY; 1544 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY;
1588 fimc_write(cfg0, EXYNOS_MSCTRL); 1545 fimc_write(ctx, cfg0, EXYNOS_MSCTRL);
1589 break; 1546 break;
1590 case IPP_CMD_WB: 1547 case IPP_CMD_WB:
1591 fimc_set_type_ctrl(ctx, FIMC_WB_A); 1548 fimc_set_type_ctrl(ctx, FIMC_WB_A);
@@ -1610,41 +1567,33 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1610 } 1567 }
1611 1568
1612 /* Reset status */ 1569 /* Reset status */
1613 fimc_write(0x0, EXYNOS_CISTATUS); 1570 fimc_write(ctx, 0x0, EXYNOS_CISTATUS);
1614 1571
1615 cfg0 = fimc_read(EXYNOS_CIIMGCPT); 1572 cfg0 = fimc_read(ctx, EXYNOS_CIIMGCPT);
1616 cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1573 cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC;
1617 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1574 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC;
1618 1575
1619 /* Scaler */ 1576 /* Scaler */
1620 cfg1 = fimc_read(EXYNOS_CISCCTRL); 1577 cfg1 = fimc_read(ctx, EXYNOS_CISCCTRL);
1621 cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK; 1578 cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK;
1622 cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE | 1579 cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE |
1623 EXYNOS_CISCCTRL_SCALERSTART); 1580 EXYNOS_CISCCTRL_SCALERSTART);
1624 1581
1625 fimc_write(cfg1, EXYNOS_CISCCTRL); 1582 fimc_write(ctx, cfg1, EXYNOS_CISCCTRL);
1626 1583
1627 /* Enable image capture*/ 1584 /* Enable image capture*/
1628 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN; 1585 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN;
1629 fimc_write(cfg0, EXYNOS_CIIMGCPT); 1586 fimc_write(ctx, cfg0, EXYNOS_CIIMGCPT);
1630 1587
1631 /* Disable frame end irq */ 1588 /* Disable frame end irq */
1632 cfg0 = fimc_read(EXYNOS_CIGCTRL); 1589 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
1633 cfg0 &= ~EXYNOS_CIGCTRL_IRQ_END_DISABLE;
1634 fimc_write(cfg0, EXYNOS_CIGCTRL);
1635 1590
1636 cfg0 = fimc_read(EXYNOS_CIOCTRL); 1591 fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK);
1637 cfg0 &= ~EXYNOS_CIOCTRL_WEAVE_MASK;
1638 fimc_write(cfg0, EXYNOS_CIOCTRL);
1639 1592
1640 if (cmd == IPP_CMD_M2M) { 1593 if (cmd == IPP_CMD_M2M) {
1641 cfg0 = fimc_read(EXYNOS_MSCTRL); 1594 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
1642 cfg0 |= EXYNOS_MSCTRL_ENVID;
1643 fimc_write(cfg0, EXYNOS_MSCTRL);
1644 1595
1645 cfg0 = fimc_read(EXYNOS_MSCTRL); 1596 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
1646 cfg0 |= EXYNOS_MSCTRL_ENVID;
1647 fimc_write(cfg0, EXYNOS_MSCTRL);
1648 } 1597 }
1649 1598
1650 return 0; 1599 return 0;
@@ -1661,10 +1610,10 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1661 switch (cmd) { 1610 switch (cmd) {
1662 case IPP_CMD_M2M: 1611 case IPP_CMD_M2M:
1663 /* Source clear */ 1612 /* Source clear */
1664 cfg = fimc_read(EXYNOS_MSCTRL); 1613 cfg = fimc_read(ctx, EXYNOS_MSCTRL);
1665 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK; 1614 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK;
1666 cfg &= ~EXYNOS_MSCTRL_ENVID; 1615 cfg &= ~EXYNOS_MSCTRL_ENVID;
1667 fimc_write(cfg, EXYNOS_MSCTRL); 1616 fimc_write(ctx, cfg, EXYNOS_MSCTRL);
1668 break; 1617 break;
1669 case IPP_CMD_WB: 1618 case IPP_CMD_WB:
1670 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb); 1619 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
@@ -1675,25 +1624,20 @@ static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1675 break; 1624 break;
1676 } 1625 }
1677 1626
1678 fimc_handle_irq(ctx, false, false, true); 1627 fimc_mask_irq(ctx, false);
1679 1628
1680 /* reset sequence */ 1629 /* reset sequence */
1681 fimc_write(0x0, EXYNOS_CIFCNTSEQ); 1630 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
1682 1631
1683 /* Scaler disable */ 1632 /* Scaler disable */
1684 cfg = fimc_read(EXYNOS_CISCCTRL); 1633 fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
1685 cfg &= ~EXYNOS_CISCCTRL_SCALERSTART;
1686 fimc_write(cfg, EXYNOS_CISCCTRL);
1687 1634
1688 /* Disable image capture */ 1635 /* Disable image capture */
1689 cfg = fimc_read(EXYNOS_CIIMGCPT); 1636 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT,
1690 cfg &= ~(EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 1637 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
1691 fimc_write(cfg, EXYNOS_CIIMGCPT);
1692 1638
1693 /* Enable frame end irq */ 1639 /* Enable frame end irq */
1694 cfg = fimc_read(EXYNOS_CIGCTRL); 1640 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
1695 cfg |= EXYNOS_CIGCTRL_IRQ_END_DISABLE;
1696 fimc_write(cfg, EXYNOS_CIGCTRL);
1697} 1641}
1698 1642
1699static void fimc_put_clocks(struct fimc_context *ctx) 1643static void fimc_put_clocks(struct fimc_context *ctx)
@@ -1848,7 +1792,7 @@ static int fimc_probe(struct platform_device *pdev)
1848 1792
1849 DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv); 1793 DRM_DEBUG_KMS("id[%d]ippdrv[0x%x]\n", ctx->id, (int)ippdrv);
1850 1794
1851 mutex_init(&ctx->lock); 1795 spin_lock_init(&ctx->lock);
1852 platform_set_drvdata(pdev, ctx); 1796 platform_set_drvdata(pdev, ctx);
1853 1797
1854 pm_runtime_set_active(dev); 1798 pm_runtime_set_active(dev);
@@ -1879,7 +1823,6 @@ static int fimc_remove(struct platform_device *pdev)
1879 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1823 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1880 1824
1881 exynos_drm_ippdrv_unregister(ippdrv); 1825 exynos_drm_ippdrv_unregister(ippdrv);
1882 mutex_destroy(&ctx->lock);
1883 1826
1884 fimc_put_clocks(ctx); 1827 fimc_put_clocks(ctx);
1885 pm_runtime_set_suspended(dev); 1828 pm_runtime_set_suspended(dev);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 40fd6ccfcd6f..bb45ab2e7384 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -19,6 +19,7 @@
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/of_device.h> 20#include <linux/of_device.h>
21#include <linux/pm_runtime.h> 21#include <linux/pm_runtime.h>
22#include <linux/component.h>
22 23
23#include <video/of_display_timing.h> 24#include <video/of_display_timing.h>
24#include <video/of_videomode.h> 25#include <video/of_videomode.h>
@@ -38,6 +39,7 @@
38 */ 39 */
39 40
40#define FIMD_DEFAULT_FRAMERATE 60 41#define FIMD_DEFAULT_FRAMERATE 60
42#define MIN_FB_WIDTH_FOR_16WORD_BURST 128
41 43
42/* position control register for hardware window 0, 2 ~ 4.*/ 44/* position control register for hardware window 0, 2 ~ 4.*/
43#define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16) 45#define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16)
@@ -122,6 +124,7 @@ struct fimd_context {
122 124
123 struct exynos_drm_panel_info panel; 125 struct exynos_drm_panel_info panel;
124 struct fimd_driver_data *driver_data; 126 struct fimd_driver_data *driver_data;
127 struct exynos_drm_display *display;
125}; 128};
126 129
127static const struct of_device_id fimd_driver_dt_match[] = { 130static const struct of_device_id fimd_driver_dt_match[] = {
@@ -143,13 +146,57 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
143 return (struct fimd_driver_data *)of_id->data; 146 return (struct fimd_driver_data *)of_id->data;
144} 147}
145 148
149static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
150{
151 struct fimd_context *ctx = mgr->ctx;
152
153 if (ctx->suspended)
154 return;
155
156 atomic_set(&ctx->wait_vsync_event, 1);
157
158 /*
159 * wait for FIMD to signal VSYNC interrupt or return after
160 * timeout which is set to 50ms (refresh rate of 20).
161 */
162 if (!wait_event_timeout(ctx->wait_vsync_queue,
163 !atomic_read(&ctx->wait_vsync_event),
164 HZ/20))
165 DRM_DEBUG_KMS("vblank wait timed out.\n");
166}
167
168
169static void fimd_clear_channel(struct exynos_drm_manager *mgr)
170{
171 struct fimd_context *ctx = mgr->ctx;
172 int win, ch_enabled = 0;
173
174 DRM_DEBUG_KMS("%s\n", __FILE__);
175
176 /* Check if any channel is enabled. */
177 for (win = 0; win < WINDOWS_NR; win++) {
178 u32 val = readl(ctx->regs + SHADOWCON);
179 if (val & SHADOWCON_CHx_ENABLE(win)) {
180 val &= ~SHADOWCON_CHx_ENABLE(win);
181 writel(val, ctx->regs + SHADOWCON);
182 ch_enabled = 1;
183 }
184 }
185
186 /* Wait for vsync, as disable channel takes effect at next vsync */
187 if (ch_enabled)
188 fimd_wait_for_vblank(mgr);
189}
190
146static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, 191static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
147 struct drm_device *drm_dev, int pipe) 192 struct drm_device *drm_dev)
148{ 193{
149 struct fimd_context *ctx = mgr->ctx; 194 struct fimd_context *ctx = mgr->ctx;
195 struct exynos_drm_private *priv;
196 priv = drm_dev->dev_private;
150 197
151 ctx->drm_dev = drm_dev; 198 mgr->drm_dev = ctx->drm_dev = drm_dev;
152 ctx->pipe = pipe; 199 mgr->pipe = ctx->pipe = priv->pipe++;
153 200
154 /* 201 /*
155 * enable drm irq mode. 202 * enable drm irq mode.
@@ -169,8 +216,14 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
169 drm_dev->vblank_disable_allowed = true; 216 drm_dev->vblank_disable_allowed = true;
170 217
171 /* attach this sub driver to iommu mapping if supported. */ 218 /* attach this sub driver to iommu mapping if supported. */
172 if (is_drm_iommu_supported(ctx->drm_dev)) 219 if (is_drm_iommu_supported(ctx->drm_dev)) {
220 /*
221 * If any channel is already active, iommu will throw
222 * a PAGE FAULT when enabled. So clear any channel if enabled.
223 */
224 fimd_clear_channel(mgr);
173 drm_iommu_attach_device(ctx->drm_dev, ctx->dev); 225 drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
226 }
174 227
175 return 0; 228 return 0;
176} 229}
@@ -324,25 +377,6 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
324 } 377 }
325} 378}
326 379
327static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
328{
329 struct fimd_context *ctx = mgr->ctx;
330
331 if (ctx->suspended)
332 return;
333
334 atomic_set(&ctx->wait_vsync_event, 1);
335
336 /*
337 * wait for FIMD to signal VSYNC interrupt or return after
338 * timeout which is set to 50ms (refresh rate of 20).
339 */
340 if (!wait_event_timeout(ctx->wait_vsync_queue,
341 !atomic_read(&ctx->wait_vsync_event),
342 HZ/20))
343 DRM_DEBUG_KMS("vblank wait timed out.\n");
344}
345
346static void fimd_win_mode_set(struct exynos_drm_manager *mgr, 380static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
347 struct exynos_drm_overlay *overlay) 381 struct exynos_drm_overlay *overlay)
348{ 382{
@@ -446,6 +480,19 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
446 480
447 DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp); 481 DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp);
448 482
483 /*
484 * In case of exynos, setting dma-burst to 16Word causes permanent
485 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
486 * switching which is based on overlay size is not recommended as
487 * overlay size varies alot towards the end of the screen and rapid
488 * movement causes unstable DMA which results into iommu crash/tear.
489 */
490
491 if (win_data->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
492 val &= ~WINCONx_BURSTLEN_MASK;
493 val |= WINCONx_BURSTLEN_4WORD;
494 }
495
449 writel(val, ctx->regs + WINCON(win)); 496 writel(val, ctx->regs + WINCON(win));
450} 497}
451 498
@@ -656,19 +703,6 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
656 win_data->enabled = false; 703 win_data->enabled = false;
657} 704}
658 705
659static void fimd_clear_win(struct fimd_context *ctx, int win)
660{
661 writel(0, ctx->regs + WINCON(win));
662 writel(0, ctx->regs + VIDOSD_A(win));
663 writel(0, ctx->regs + VIDOSD_B(win));
664 writel(0, ctx->regs + VIDOSD_C(win));
665
666 if (win == 1 || win == 2)
667 writel(0, ctx->regs + VIDOSD_D(win));
668
669 fimd_shadow_protect_win(ctx, win, false);
670}
671
672static void fimd_window_suspend(struct exynos_drm_manager *mgr) 706static void fimd_window_suspend(struct exynos_drm_manager *mgr)
673{ 707{
674 struct fimd_context *ctx = mgr->ctx; 708 struct fimd_context *ctx = mgr->ctx;
@@ -803,8 +837,6 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
803} 837}
804 838
805static struct exynos_drm_manager_ops fimd_manager_ops = { 839static struct exynos_drm_manager_ops fimd_manager_ops = {
806 .initialize = fimd_mgr_initialize,
807 .remove = fimd_mgr_remove,
808 .dpms = fimd_dpms, 840 .dpms = fimd_dpms,
809 .mode_fixup = fimd_mode_fixup, 841 .mode_fixup = fimd_mode_fixup,
810 .mode_set = fimd_mode_set, 842 .mode_set = fimd_mode_set,
@@ -849,20 +881,64 @@ out:
849 return IRQ_HANDLED; 881 return IRQ_HANDLED;
850} 882}
851 883
884static int fimd_bind(struct device *dev, struct device *master, void *data)
885{
886 struct fimd_context *ctx = fimd_manager.ctx;
887 struct drm_device *drm_dev = data;
888
889 fimd_mgr_initialize(&fimd_manager, drm_dev);
890 exynos_drm_crtc_create(&fimd_manager);
891 if (ctx->display)
892 exynos_drm_create_enc_conn(drm_dev, ctx->display);
893
894 return 0;
895
896}
897
898static void fimd_unbind(struct device *dev, struct device *master,
899 void *data)
900{
901 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
902 struct fimd_context *ctx = fimd_manager.ctx;
903 struct drm_crtc *crtc = mgr->crtc;
904
905 fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
906
907 if (ctx->display)
908 exynos_dpi_remove(dev);
909
910 fimd_mgr_remove(mgr);
911
912 crtc->funcs->destroy(crtc);
913}
914
915static const struct component_ops fimd_component_ops = {
916 .bind = fimd_bind,
917 .unbind = fimd_unbind,
918};
919
852static int fimd_probe(struct platform_device *pdev) 920static int fimd_probe(struct platform_device *pdev)
853{ 921{
854 struct device *dev = &pdev->dev; 922 struct device *dev = &pdev->dev;
855 struct fimd_context *ctx; 923 struct fimd_context *ctx;
856 struct resource *res; 924 struct resource *res;
857 int win;
858 int ret = -EINVAL; 925 int ret = -EINVAL;
859 926
860 if (!dev->of_node) 927 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
861 return -ENODEV; 928 fimd_manager.type);
929 if (ret)
930 return ret;
931
932 if (!dev->of_node) {
933 ret = -ENODEV;
934 goto err_del_component;
935 }
862 936
863 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 937 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
864 if (!ctx) 938 if (!ctx) {
865 return -ENOMEM; 939 ret = -ENOMEM;
940 goto err_del_component;
941 }
866 942
867 ctx->dev = dev; 943 ctx->dev = dev;
868 ctx->suspended = true; 944 ctx->suspended = true;
@@ -875,32 +951,37 @@ static int fimd_probe(struct platform_device *pdev)
875 ctx->bus_clk = devm_clk_get(dev, "fimd"); 951 ctx->bus_clk = devm_clk_get(dev, "fimd");
876 if (IS_ERR(ctx->bus_clk)) { 952 if (IS_ERR(ctx->bus_clk)) {
877 dev_err(dev, "failed to get bus clock\n"); 953 dev_err(dev, "failed to get bus clock\n");
878 return PTR_ERR(ctx->bus_clk); 954 ret = PTR_ERR(ctx->bus_clk);
955 goto err_del_component;
879 } 956 }
880 957
881 ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd"); 958 ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd");
882 if (IS_ERR(ctx->lcd_clk)) { 959 if (IS_ERR(ctx->lcd_clk)) {
883 dev_err(dev, "failed to get lcd clock\n"); 960 dev_err(dev, "failed to get lcd clock\n");
884 return PTR_ERR(ctx->lcd_clk); 961 ret = PTR_ERR(ctx->lcd_clk);
962 goto err_del_component;
885 } 963 }
886 964
887 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 965 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
888 966
889 ctx->regs = devm_ioremap_resource(dev, res); 967 ctx->regs = devm_ioremap_resource(dev, res);
890 if (IS_ERR(ctx->regs)) 968 if (IS_ERR(ctx->regs)) {
891 return PTR_ERR(ctx->regs); 969 ret = PTR_ERR(ctx->regs);
970 goto err_del_component;
971 }
892 972
893 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync"); 973 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vsync");
894 if (!res) { 974 if (!res) {
895 dev_err(dev, "irq request failed.\n"); 975 dev_err(dev, "irq request failed.\n");
896 return -ENXIO; 976 ret = -ENXIO;
977 goto err_del_component;
897 } 978 }
898 979
899 ret = devm_request_irq(dev, res->start, fimd_irq_handler, 980 ret = devm_request_irq(dev, res->start, fimd_irq_handler,
900 0, "drm_fimd", ctx); 981 0, "drm_fimd", ctx);
901 if (ret) { 982 if (ret) {
902 dev_err(dev, "irq request failed.\n"); 983 dev_err(dev, "irq request failed.\n");
903 return ret; 984 goto err_del_component;
904 } 985 }
905 986
906 ctx->driver_data = drm_fimd_get_driver_data(pdev); 987 ctx->driver_data = drm_fimd_get_driver_data(pdev);
@@ -910,30 +991,34 @@ static int fimd_probe(struct platform_device *pdev)
910 platform_set_drvdata(pdev, &fimd_manager); 991 platform_set_drvdata(pdev, &fimd_manager);
911 992
912 fimd_manager.ctx = ctx; 993 fimd_manager.ctx = ctx;
913 exynos_drm_manager_register(&fimd_manager);
914 994
915 exynos_dpi_probe(ctx->dev); 995 ctx->display = exynos_dpi_probe(dev);
996 if (IS_ERR(ctx->display))
997 return PTR_ERR(ctx->display);
916 998
917 pm_runtime_enable(dev); 999 pm_runtime_enable(&pdev->dev);
918 1000
919 for (win = 0; win < WINDOWS_NR; win++) 1001 ret = component_add(&pdev->dev, &fimd_component_ops);
920 fimd_clear_win(ctx, win); 1002 if (ret)
1003 goto err_disable_pm_runtime;
921 1004
922 return 0; 1005 return ret;
1006
1007err_disable_pm_runtime:
1008 pm_runtime_disable(&pdev->dev);
1009
1010err_del_component:
1011 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1012 return ret;
923} 1013}
924 1014
925static int fimd_remove(struct platform_device *pdev) 1015static int fimd_remove(struct platform_device *pdev)
926{ 1016{
927 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
928
929 exynos_dpi_remove(&pdev->dev);
930
931 exynos_drm_manager_unregister(&fimd_manager);
932
933 fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
934
935 pm_runtime_disable(&pdev->dev); 1017 pm_runtime_disable(&pdev->dev);
936 1018
1019 component_del(&pdev->dev, &fimd_component_ops);
1020 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1021
937 return 0; 1022 return 0;
938} 1023}
939 1024
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 42d2904d88c7..163a054922cb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -612,22 +612,20 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
612 args->pitch = args->width * ((args->bpp + 7) / 8); 612 args->pitch = args->width * ((args->bpp + 7) / 8);
613 args->size = args->pitch * args->height; 613 args->size = args->pitch * args->height;
614 614
615 exynos_gem_obj = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG | 615 if (is_drm_iommu_supported(dev)) {
616 EXYNOS_BO_WC, args->size); 616 exynos_gem_obj = exynos_drm_gem_create(dev,
617 /* 617 EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC,
618 * If physically contiguous memory allocation fails and if IOMMU is 618 args->size);
619 * supported then try to get buffer from non physically contiguous 619 } else {
620 * memory area.
621 */
622 if (IS_ERR(exynos_gem_obj) && is_drm_iommu_supported(dev)) {
623 dev_warn(dev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n");
624 exynos_gem_obj = exynos_drm_gem_create(dev, 620 exynos_gem_obj = exynos_drm_gem_create(dev,
625 EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC, 621 EXYNOS_BO_CONTIG | EXYNOS_BO_WC,
626 args->size); 622 args->size);
627 } 623 }
628 624
629 if (IS_ERR(exynos_gem_obj)) 625 if (IS_ERR(exynos_gem_obj)) {
626 dev_warn(dev->dev, "FB allocation failed.\n");
630 return PTR_ERR(exynos_gem_obj); 627 return PTR_ERR(exynos_gem_obj);
628 }
631 629
632 ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, 630 ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv,
633 &args->handle); 631 &args->handle);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index fa75059a6104..9e3ff1672965 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1335,11 +1335,7 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id)
1335 1335
1336static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv) 1336static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1337{ 1337{
1338 struct drm_exynos_ipp_prop_list *prop_list; 1338 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list;
1339
1340 prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
1341 if (!prop_list)
1342 return -ENOMEM;
1343 1339
1344 prop_list->version = 1; 1340 prop_list->version = 1;
1345 prop_list->writeback = 1; 1341 prop_list->writeback = 1;
@@ -1363,8 +1359,6 @@ static int gsc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1363 prop_list->scale_min.hsize = GSC_SCALE_MIN; 1359 prop_list->scale_min.hsize = GSC_SCALE_MIN;
1364 prop_list->scale_min.vsize = GSC_SCALE_MIN; 1360 prop_list->scale_min.vsize = GSC_SCALE_MIN;
1365 1361
1366 ippdrv->prop_list = prop_list;
1367
1368 return 0; 1362 return 0;
1369} 1363}
1370 1364
@@ -1387,7 +1381,7 @@ static int gsc_ippdrv_check_property(struct device *dev,
1387{ 1381{
1388 struct gsc_context *ctx = get_gsc_context(dev); 1382 struct gsc_context *ctx = get_gsc_context(dev);
1389 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1383 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1390 struct drm_exynos_ipp_prop_list *pp = ippdrv->prop_list; 1384 struct drm_exynos_ipp_prop_list *pp = &ippdrv->prop_list;
1391 struct drm_exynos_ipp_config *config; 1385 struct drm_exynos_ipp_config *config;
1392 struct drm_exynos_pos *pos; 1386 struct drm_exynos_pos *pos;
1393 struct drm_exynos_sz *sz; 1387 struct drm_exynos_sz *sz;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 09312b877470..603a79602f31 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -167,6 +167,13 @@ static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
167 return 0; 167 return 0;
168} 168}
169 169
170static void ipp_remove_id(struct idr *id_idr, struct mutex *lock, u32 id)
171{
172 mutex_lock(lock);
173 idr_remove(id_idr, id);
174 mutex_unlock(lock);
175}
176
170static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id) 177static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
171{ 178{
172 void *obj; 179 void *obj;
@@ -276,11 +283,6 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id)
276 283
277 DRM_DEBUG_KMS("prop_id[%d]\n", prop_id); 284 DRM_DEBUG_KMS("prop_id[%d]\n", prop_id);
278 285
279 if (list_empty(&exynos_drm_ippdrv_list)) {
280 DRM_DEBUG_KMS("ippdrv_list is empty.\n");
281 return ERR_PTR(-ENODEV);
282 }
283
284 /* 286 /*
285 * This case is search ipp driver by prop_id handle. 287 * This case is search ipp driver by prop_id handle.
286 * sometimes, ipp subsystem find driver by prop_id. 288 * sometimes, ipp subsystem find driver by prop_id.
@@ -289,11 +291,14 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id)
289 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { 291 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
290 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv); 292 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv);
291 293
292 if (!list_empty(&ippdrv->cmd_list)) { 294 mutex_lock(&ippdrv->cmd_lock);
293 list_for_each_entry(c_node, &ippdrv->cmd_list, list) 295 list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
294 if (c_node->property.prop_id == prop_id) 296 if (c_node->property.prop_id == prop_id) {
295 return ippdrv; 297 mutex_unlock(&ippdrv->cmd_lock);
298 return ippdrv;
299 }
296 } 300 }
301 mutex_unlock(&ippdrv->cmd_lock);
297 } 302 }
298 303
299 return ERR_PTR(-ENODEV); 304 return ERR_PTR(-ENODEV);
@@ -325,6 +330,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
325 if (!prop_list->ipp_id) { 330 if (!prop_list->ipp_id) {
326 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) 331 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list)
327 count++; 332 count++;
333
328 /* 334 /*
329 * Supports ippdrv list count for user application. 335 * Supports ippdrv list count for user application.
330 * First step user application getting ippdrv count. 336 * First step user application getting ippdrv count.
@@ -346,7 +352,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
346 return PTR_ERR(ippdrv); 352 return PTR_ERR(ippdrv);
347 } 353 }
348 354
349 prop_list = ippdrv->prop_list; 355 *prop_list = ippdrv->prop_list;
350 } 356 }
351 357
352 return 0; 358 return 0;
@@ -386,9 +392,11 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property)
386 * when we find this command no using prop_id. 392 * when we find this command no using prop_id.
387 * return property information set in this command node. 393 * return property information set in this command node.
388 */ 394 */
395 mutex_lock(&ippdrv->cmd_lock);
389 list_for_each_entry(c_node, &ippdrv->cmd_list, list) { 396 list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
390 if ((c_node->property.prop_id == prop_id) && 397 if ((c_node->property.prop_id == prop_id) &&
391 (c_node->state == IPP_STATE_STOP)) { 398 (c_node->state == IPP_STATE_STOP)) {
399 mutex_unlock(&ippdrv->cmd_lock);
392 DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", 400 DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n",
393 property->cmd, (int)ippdrv); 401 property->cmd, (int)ippdrv);
394 402
@@ -396,6 +404,7 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property)
396 return 0; 404 return 0;
397 } 405 }
398 } 406 }
407 mutex_unlock(&ippdrv->cmd_lock);
399 408
400 DRM_ERROR("failed to search property.\n"); 409 DRM_ERROR("failed to search property.\n");
401 410
@@ -499,7 +508,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
499 c_node->start_work = ipp_create_cmd_work(); 508 c_node->start_work = ipp_create_cmd_work();
500 if (IS_ERR(c_node->start_work)) { 509 if (IS_ERR(c_node->start_work)) {
501 DRM_ERROR("failed to create start work.\n"); 510 DRM_ERROR("failed to create start work.\n");
502 goto err_clear; 511 goto err_remove_id;
503 } 512 }
504 513
505 c_node->stop_work = ipp_create_cmd_work(); 514 c_node->stop_work = ipp_create_cmd_work();
@@ -514,7 +523,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
514 goto err_free_stop; 523 goto err_free_stop;
515 } 524 }
516 525
517 mutex_init(&c_node->cmd_lock); 526 mutex_init(&c_node->lock);
518 mutex_init(&c_node->mem_lock); 527 mutex_init(&c_node->mem_lock);
519 mutex_init(&c_node->event_lock); 528 mutex_init(&c_node->event_lock);
520 529
@@ -526,7 +535,9 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
526 535
527 INIT_LIST_HEAD(&c_node->event_list); 536 INIT_LIST_HEAD(&c_node->event_list);
528 list_splice_init(&priv->event_list, &c_node->event_list); 537 list_splice_init(&priv->event_list, &c_node->event_list);
538 mutex_lock(&ippdrv->cmd_lock);
529 list_add_tail(&c_node->list, &ippdrv->cmd_list); 539 list_add_tail(&c_node->list, &ippdrv->cmd_list);
540 mutex_unlock(&ippdrv->cmd_lock);
530 541
531 /* make dedicated state without m2m */ 542 /* make dedicated state without m2m */
532 if (!ipp_is_m2m_cmd(property->cmd)) 543 if (!ipp_is_m2m_cmd(property->cmd))
@@ -538,18 +549,24 @@ err_free_stop:
538 kfree(c_node->stop_work); 549 kfree(c_node->stop_work);
539err_free_start: 550err_free_start:
540 kfree(c_node->start_work); 551 kfree(c_node->start_work);
552err_remove_id:
553 ipp_remove_id(&ctx->prop_idr, &ctx->prop_lock, property->prop_id);
541err_clear: 554err_clear:
542 kfree(c_node); 555 kfree(c_node);
543 return ret; 556 return ret;
544} 557}
545 558
546static void ipp_clean_cmd_node(struct drm_exynos_ipp_cmd_node *c_node) 559static void ipp_clean_cmd_node(struct ipp_context *ctx,
560 struct drm_exynos_ipp_cmd_node *c_node)
547{ 561{
548 /* delete list */ 562 /* delete list */
549 list_del(&c_node->list); 563 list_del(&c_node->list);
550 564
565 ipp_remove_id(&ctx->prop_idr, &ctx->prop_lock,
566 c_node->property.prop_id);
567
551 /* destroy mutex */ 568 /* destroy mutex */
552 mutex_destroy(&c_node->cmd_lock); 569 mutex_destroy(&c_node->lock);
553 mutex_destroy(&c_node->mem_lock); 570 mutex_destroy(&c_node->mem_lock);
554 mutex_destroy(&c_node->event_lock); 571 mutex_destroy(&c_node->event_lock);
555 572
@@ -567,17 +584,10 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
567 struct list_head *head; 584 struct list_head *head;
568 int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, }; 585 int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
569 586
570 mutex_lock(&c_node->mem_lock);
571
572 for_each_ipp_ops(i) { 587 for_each_ipp_ops(i) {
573 /* source/destination memory list */ 588 /* source/destination memory list */
574 head = &c_node->mem_list[i]; 589 head = &c_node->mem_list[i];
575 590
576 if (list_empty(head)) {
577 DRM_DEBUG_KMS("%s memory empty.\n", i ? "dst" : "src");
578 continue;
579 }
580
581 /* find memory node entry */ 591 /* find memory node entry */
582 list_for_each_entry(m_node, head, list) { 592 list_for_each_entry(m_node, head, list) {
583 DRM_DEBUG_KMS("%s,count[%d]m_node[0x%x]\n", 593 DRM_DEBUG_KMS("%s,count[%d]m_node[0x%x]\n",
@@ -602,8 +612,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
602 ret = max(count[EXYNOS_DRM_OPS_SRC], 612 ret = max(count[EXYNOS_DRM_OPS_SRC],
603 count[EXYNOS_DRM_OPS_DST]); 613 count[EXYNOS_DRM_OPS_DST]);
604 614
605 mutex_unlock(&c_node->mem_lock);
606
607 return ret; 615 return ret;
608} 616}
609 617
@@ -646,16 +654,13 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
646 return -EFAULT; 654 return -EFAULT;
647 } 655 }
648 656
649 mutex_lock(&c_node->mem_lock);
650
651 DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); 657 DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
652 658
653 /* get operations callback */ 659 /* get operations callback */
654 ops = ippdrv->ops[m_node->ops_id]; 660 ops = ippdrv->ops[m_node->ops_id];
655 if (!ops) { 661 if (!ops) {
656 DRM_ERROR("not support ops.\n"); 662 DRM_ERROR("not support ops.\n");
657 ret = -EFAULT; 663 return -EFAULT;
658 goto err_unlock;
659 } 664 }
660 665
661 /* set address and enable irq */ 666 /* set address and enable irq */
@@ -664,12 +669,10 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
664 m_node->buf_id, IPP_BUF_ENQUEUE); 669 m_node->buf_id, IPP_BUF_ENQUEUE);
665 if (ret) { 670 if (ret) {
666 DRM_ERROR("failed to set addr.\n"); 671 DRM_ERROR("failed to set addr.\n");
667 goto err_unlock; 672 return ret;
668 } 673 }
669 } 674 }
670 675
671err_unlock:
672 mutex_unlock(&c_node->mem_lock);
673 return ret; 676 return ret;
674} 677}
675 678
@@ -684,11 +687,9 @@ static struct drm_exynos_ipp_mem_node
684 void *addr; 687 void *addr;
685 int i; 688 int i;
686 689
687 mutex_lock(&c_node->mem_lock);
688
689 m_node = kzalloc(sizeof(*m_node), GFP_KERNEL); 690 m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
690 if (!m_node) 691 if (!m_node)
691 goto err_unlock; 692 return ERR_PTR(-ENOMEM);
692 693
693 /* clear base address for error handling */ 694 /* clear base address for error handling */
694 memset(&buf_info, 0x0, sizeof(buf_info)); 695 memset(&buf_info, 0x0, sizeof(buf_info));
@@ -722,15 +723,14 @@ static struct drm_exynos_ipp_mem_node
722 723
723 m_node->filp = file; 724 m_node->filp = file;
724 m_node->buf_info = buf_info; 725 m_node->buf_info = buf_info;
726 mutex_lock(&c_node->mem_lock);
725 list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]); 727 list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]);
726
727 mutex_unlock(&c_node->mem_lock); 728 mutex_unlock(&c_node->mem_lock);
729
728 return m_node; 730 return m_node;
729 731
730err_clear: 732err_clear:
731 kfree(m_node); 733 kfree(m_node);
732err_unlock:
733 mutex_unlock(&c_node->mem_lock);
734 return ERR_PTR(-EFAULT); 734 return ERR_PTR(-EFAULT);
735} 735}
736 736
@@ -747,13 +747,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
747 return -EFAULT; 747 return -EFAULT;
748 } 748 }
749 749
750 if (list_empty(&m_node->list)) {
751 DRM_ERROR("empty memory node.\n");
752 return -ENOMEM;
753 }
754
755 mutex_lock(&c_node->mem_lock);
756
757 DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); 750 DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
758 751
759 /* put gem buffer */ 752 /* put gem buffer */
@@ -768,8 +761,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
768 list_del(&m_node->list); 761 list_del(&m_node->list);
769 kfree(m_node); 762 kfree(m_node);
770 763
771 mutex_unlock(&c_node->mem_lock);
772
773 return 0; 764 return 0;
774} 765}
775 766
@@ -805,7 +796,9 @@ static int ipp_get_event(struct drm_device *drm_dev,
805 e->base.event = &e->event.base; 796 e->base.event = &e->event.base;
806 e->base.file_priv = file; 797 e->base.file_priv = file;
807 e->base.destroy = ipp_free_event; 798 e->base.destroy = ipp_free_event;
799 mutex_lock(&c_node->event_lock);
808 list_add_tail(&e->base.link, &c_node->event_list); 800 list_add_tail(&e->base.link, &c_node->event_list);
801 mutex_unlock(&c_node->event_lock);
809 802
810 return 0; 803 return 0;
811} 804}
@@ -816,11 +809,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
816 struct drm_exynos_ipp_send_event *e, *te; 809 struct drm_exynos_ipp_send_event *e, *te;
817 int count = 0; 810 int count = 0;
818 811
819 if (list_empty(&c_node->event_list)) { 812 mutex_lock(&c_node->event_lock);
820 DRM_DEBUG_KMS("event_list is empty.\n");
821 return;
822 }
823
824 list_for_each_entry_safe(e, te, &c_node->event_list, base.link) { 813 list_for_each_entry_safe(e, te, &c_node->event_list, base.link) {
825 DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); 814 DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e);
826 815
@@ -841,9 +830,13 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node,
841 /* delete list */ 830 /* delete list */
842 list_del(&e->base.link); 831 list_del(&e->base.link);
843 kfree(e); 832 kfree(e);
844 return; 833 goto out_unlock;
845 } 834 }
846 } 835 }
836
837out_unlock:
838 mutex_unlock(&c_node->event_lock);
839 return;
847} 840}
848 841
849static void ipp_handle_cmd_work(struct device *dev, 842static void ipp_handle_cmd_work(struct device *dev,
@@ -887,7 +880,9 @@ static int ipp_queue_buf_with_run(struct device *dev,
887 return 0; 880 return 0;
888 } 881 }
889 882
883 mutex_lock(&c_node->mem_lock);
890 if (!ipp_check_mem_list(c_node)) { 884 if (!ipp_check_mem_list(c_node)) {
885 mutex_unlock(&c_node->mem_lock);
891 DRM_DEBUG_KMS("empty memory.\n"); 886 DRM_DEBUG_KMS("empty memory.\n");
892 return 0; 887 return 0;
893 } 888 }
@@ -904,10 +899,12 @@ static int ipp_queue_buf_with_run(struct device *dev,
904 } else { 899 } else {
905 ret = ipp_set_mem_node(ippdrv, c_node, m_node); 900 ret = ipp_set_mem_node(ippdrv, c_node, m_node);
906 if (ret) { 901 if (ret) {
902 mutex_unlock(&c_node->mem_lock);
907 DRM_ERROR("failed to set m node.\n"); 903 DRM_ERROR("failed to set m node.\n");
908 return ret; 904 return ret;
909 } 905 }
910 } 906 }
907 mutex_unlock(&c_node->mem_lock);
911 908
912 return 0; 909 return 0;
913} 910}
@@ -918,15 +915,15 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev,
918{ 915{
919 struct drm_exynos_ipp_mem_node *m_node, *tm_node; 916 struct drm_exynos_ipp_mem_node *m_node, *tm_node;
920 917
921 if (!list_empty(&c_node->mem_list[qbuf->ops_id])) { 918 /* delete list */
922 /* delete list */ 919 mutex_lock(&c_node->mem_lock);
923 list_for_each_entry_safe(m_node, tm_node, 920 list_for_each_entry_safe(m_node, tm_node,
924 &c_node->mem_list[qbuf->ops_id], list) { 921 &c_node->mem_list[qbuf->ops_id], list) {
925 if (m_node->buf_id == qbuf->buf_id && 922 if (m_node->buf_id == qbuf->buf_id &&
926 m_node->ops_id == qbuf->ops_id) 923 m_node->ops_id == qbuf->ops_id)
927 ipp_put_mem_node(drm_dev, c_node, m_node); 924 ipp_put_mem_node(drm_dev, c_node, m_node);
928 }
929 } 925 }
926 mutex_unlock(&c_node->mem_lock);
930} 927}
931 928
932int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, 929int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
@@ -998,7 +995,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
998 } 995 }
999 break; 996 break;
1000 case IPP_BUF_DEQUEUE: 997 case IPP_BUF_DEQUEUE:
1001 mutex_lock(&c_node->cmd_lock); 998 mutex_lock(&c_node->lock);
1002 999
1003 /* put event for destination buffer */ 1000 /* put event for destination buffer */
1004 if (qbuf->ops_id == EXYNOS_DRM_OPS_DST) 1001 if (qbuf->ops_id == EXYNOS_DRM_OPS_DST)
@@ -1006,7 +1003,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
1006 1003
1007 ipp_clean_queue_buf(drm_dev, c_node, qbuf); 1004 ipp_clean_queue_buf(drm_dev, c_node, qbuf);
1008 1005
1009 mutex_unlock(&c_node->cmd_lock); 1006 mutex_unlock(&c_node->lock);
1010 break; 1007 break;
1011 default: 1008 default:
1012 DRM_ERROR("invalid buffer control.\n"); 1009 DRM_ERROR("invalid buffer control.\n");
@@ -1109,12 +1106,12 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
1109 case IPP_CTRL_PLAY: 1106 case IPP_CTRL_PLAY:
1110 if (pm_runtime_suspended(ippdrv->dev)) 1107 if (pm_runtime_suspended(ippdrv->dev))
1111 pm_runtime_get_sync(ippdrv->dev); 1108 pm_runtime_get_sync(ippdrv->dev);
1109
1112 c_node->state = IPP_STATE_START; 1110 c_node->state = IPP_STATE_START;
1113 1111
1114 cmd_work = c_node->start_work; 1112 cmd_work = c_node->start_work;
1115 cmd_work->ctrl = cmd_ctrl->ctrl; 1113 cmd_work->ctrl = cmd_ctrl->ctrl;
1116 ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node); 1114 ipp_handle_cmd_work(dev, ippdrv, cmd_work, c_node);
1117 c_node->state = IPP_STATE_START;
1118 break; 1115 break;
1119 case IPP_CTRL_STOP: 1116 case IPP_CTRL_STOP:
1120 cmd_work = c_node->stop_work; 1117 cmd_work = c_node->stop_work;
@@ -1129,10 +1126,12 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
1129 1126
1130 c_node->state = IPP_STATE_STOP; 1127 c_node->state = IPP_STATE_STOP;
1131 ippdrv->dedicated = false; 1128 ippdrv->dedicated = false;
1132 ipp_clean_cmd_node(c_node); 1129 mutex_lock(&ippdrv->cmd_lock);
1130 ipp_clean_cmd_node(ctx, c_node);
1133 1131
1134 if (list_empty(&ippdrv->cmd_list)) 1132 if (list_empty(&ippdrv->cmd_list))
1135 pm_runtime_put_sync(ippdrv->dev); 1133 pm_runtime_put_sync(ippdrv->dev);
1134 mutex_unlock(&ippdrv->cmd_lock);
1136 break; 1135 break;
1137 case IPP_CTRL_PAUSE: 1136 case IPP_CTRL_PAUSE:
1138 cmd_work = c_node->stop_work; 1137 cmd_work = c_node->stop_work;
@@ -1260,9 +1259,11 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1260 /* store command info in ippdrv */ 1259 /* store command info in ippdrv */
1261 ippdrv->c_node = c_node; 1260 ippdrv->c_node = c_node;
1262 1261
1262 mutex_lock(&c_node->mem_lock);
1263 if (!ipp_check_mem_list(c_node)) { 1263 if (!ipp_check_mem_list(c_node)) {
1264 DRM_DEBUG_KMS("empty memory.\n"); 1264 DRM_DEBUG_KMS("empty memory.\n");
1265 return -ENOMEM; 1265 ret = -ENOMEM;
1266 goto err_unlock;
1266 } 1267 }
1267 1268
1268 /* set current property in ippdrv */ 1269 /* set current property in ippdrv */
@@ -1270,7 +1271,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1270 if (ret) { 1271 if (ret) {
1271 DRM_ERROR("failed to set property.\n"); 1272 DRM_ERROR("failed to set property.\n");
1272 ippdrv->c_node = NULL; 1273 ippdrv->c_node = NULL;
1273 return ret; 1274 goto err_unlock;
1274 } 1275 }
1275 1276
1276 /* check command */ 1277 /* check command */
@@ -1285,7 +1286,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1285 if (!m_node) { 1286 if (!m_node) {
1286 DRM_ERROR("failed to get node.\n"); 1287 DRM_ERROR("failed to get node.\n");
1287 ret = -EFAULT; 1288 ret = -EFAULT;
1288 return ret; 1289 goto err_unlock;
1289 } 1290 }
1290 1291
1291 DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node); 1292 DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
@@ -1293,7 +1294,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1293 ret = ipp_set_mem_node(ippdrv, c_node, m_node); 1294 ret = ipp_set_mem_node(ippdrv, c_node, m_node);
1294 if (ret) { 1295 if (ret) {
1295 DRM_ERROR("failed to set m node.\n"); 1296 DRM_ERROR("failed to set m node.\n");
1296 return ret; 1297 goto err_unlock;
1297 } 1298 }
1298 } 1299 }
1299 break; 1300 break;
@@ -1305,7 +1306,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1305 ret = ipp_set_mem_node(ippdrv, c_node, m_node); 1306 ret = ipp_set_mem_node(ippdrv, c_node, m_node);
1306 if (ret) { 1307 if (ret) {
1307 DRM_ERROR("failed to set m node.\n"); 1308 DRM_ERROR("failed to set m node.\n");
1308 return ret; 1309 goto err_unlock;
1309 } 1310 }
1310 } 1311 }
1311 break; 1312 break;
@@ -1317,14 +1318,16 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1317 ret = ipp_set_mem_node(ippdrv, c_node, m_node); 1318 ret = ipp_set_mem_node(ippdrv, c_node, m_node);
1318 if (ret) { 1319 if (ret) {
1319 DRM_ERROR("failed to set m node.\n"); 1320 DRM_ERROR("failed to set m node.\n");
1320 return ret; 1321 goto err_unlock;
1321 } 1322 }
1322 } 1323 }
1323 break; 1324 break;
1324 default: 1325 default:
1325 DRM_ERROR("invalid operations.\n"); 1326 DRM_ERROR("invalid operations.\n");
1326 return -EINVAL; 1327 ret = -EINVAL;
1328 goto err_unlock;
1327 } 1329 }
1330 mutex_unlock(&c_node->mem_lock);
1328 1331
1329 DRM_DEBUG_KMS("cmd[%d]\n", property->cmd); 1332 DRM_DEBUG_KMS("cmd[%d]\n", property->cmd);
1330 1333
@@ -1333,11 +1336,17 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
1333 ret = ippdrv->start(ippdrv->dev, property->cmd); 1336 ret = ippdrv->start(ippdrv->dev, property->cmd);
1334 if (ret) { 1337 if (ret) {
1335 DRM_ERROR("failed to start ops.\n"); 1338 DRM_ERROR("failed to start ops.\n");
1339 ippdrv->c_node = NULL;
1336 return ret; 1340 return ret;
1337 } 1341 }
1338 } 1342 }
1339 1343
1340 return 0; 1344 return 0;
1345
1346err_unlock:
1347 mutex_unlock(&c_node->mem_lock);
1348 ippdrv->c_node = NULL;
1349 return ret;
1341} 1350}
1342 1351
1343static int ipp_stop_property(struct drm_device *drm_dev, 1352static int ipp_stop_property(struct drm_device *drm_dev,
@@ -1354,6 +1363,8 @@ static int ipp_stop_property(struct drm_device *drm_dev,
1354 /* put event */ 1363 /* put event */
1355 ipp_put_event(c_node, NULL); 1364 ipp_put_event(c_node, NULL);
1356 1365
1366 mutex_lock(&c_node->mem_lock);
1367
1357 /* check command */ 1368 /* check command */
1358 switch (property->cmd) { 1369 switch (property->cmd) {
1359 case IPP_CMD_M2M: 1370 case IPP_CMD_M2M:
@@ -1361,11 +1372,6 @@ static int ipp_stop_property(struct drm_device *drm_dev,
1361 /* source/destination memory list */ 1372 /* source/destination memory list */
1362 head = &c_node->mem_list[i]; 1373 head = &c_node->mem_list[i];
1363 1374
1364 if (list_empty(head)) {
1365 DRM_DEBUG_KMS("mem_list is empty.\n");
1366 break;
1367 }
1368
1369 list_for_each_entry_safe(m_node, tm_node, 1375 list_for_each_entry_safe(m_node, tm_node,
1370 head, list) { 1376 head, list) {
1371 ret = ipp_put_mem_node(drm_dev, c_node, 1377 ret = ipp_put_mem_node(drm_dev, c_node,
@@ -1381,11 +1387,6 @@ static int ipp_stop_property(struct drm_device *drm_dev,
1381 /* destination memory list */ 1387 /* destination memory list */
1382 head = &c_node->mem_list[EXYNOS_DRM_OPS_DST]; 1388 head = &c_node->mem_list[EXYNOS_DRM_OPS_DST];
1383 1389
1384 if (list_empty(head)) {
1385 DRM_DEBUG_KMS("mem_list is empty.\n");
1386 break;
1387 }
1388
1389 list_for_each_entry_safe(m_node, tm_node, head, list) { 1390 list_for_each_entry_safe(m_node, tm_node, head, list) {
1390 ret = ipp_put_mem_node(drm_dev, c_node, m_node); 1391 ret = ipp_put_mem_node(drm_dev, c_node, m_node);
1391 if (ret) { 1392 if (ret) {
@@ -1398,11 +1399,6 @@ static int ipp_stop_property(struct drm_device *drm_dev,
1398 /* source memory list */ 1399 /* source memory list */
1399 head = &c_node->mem_list[EXYNOS_DRM_OPS_SRC]; 1400 head = &c_node->mem_list[EXYNOS_DRM_OPS_SRC];
1400 1401
1401 if (list_empty(head)) {
1402 DRM_DEBUG_KMS("mem_list is empty.\n");
1403 break;
1404 }
1405
1406 list_for_each_entry_safe(m_node, tm_node, head, list) { 1402 list_for_each_entry_safe(m_node, tm_node, head, list) {
1407 ret = ipp_put_mem_node(drm_dev, c_node, m_node); 1403 ret = ipp_put_mem_node(drm_dev, c_node, m_node);
1408 if (ret) { 1404 if (ret) {
@@ -1418,6 +1414,8 @@ static int ipp_stop_property(struct drm_device *drm_dev,
1418 } 1414 }
1419 1415
1420err_clear: 1416err_clear:
1417 mutex_unlock(&c_node->mem_lock);
1418
1421 /* stop operations */ 1419 /* stop operations */
1422 if (ippdrv->stop) 1420 if (ippdrv->stop)
1423 ippdrv->stop(ippdrv->dev, property->cmd); 1421 ippdrv->stop(ippdrv->dev, property->cmd);
@@ -1446,7 +1444,7 @@ void ipp_sched_cmd(struct work_struct *work)
1446 return; 1444 return;
1447 } 1445 }
1448 1446
1449 mutex_lock(&c_node->cmd_lock); 1447 mutex_lock(&c_node->lock);
1450 1448
1451 property = &c_node->property; 1449 property = &c_node->property;
1452 1450
@@ -1494,7 +1492,7 @@ void ipp_sched_cmd(struct work_struct *work)
1494 DRM_DEBUG_KMS("ctrl[%d] done.\n", cmd_work->ctrl); 1492 DRM_DEBUG_KMS("ctrl[%d] done.\n", cmd_work->ctrl);
1495 1493
1496err_unlock: 1494err_unlock:
1497 mutex_unlock(&c_node->cmd_lock); 1495 mutex_unlock(&c_node->lock);
1498} 1496}
1499 1497
1500static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, 1498static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
@@ -1524,14 +1522,18 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1524 return -EINVAL; 1522 return -EINVAL;
1525 } 1523 }
1526 1524
1525 mutex_lock(&c_node->event_lock);
1527 if (list_empty(&c_node->event_list)) { 1526 if (list_empty(&c_node->event_list)) {
1528 DRM_DEBUG_KMS("event list is empty.\n"); 1527 DRM_DEBUG_KMS("event list is empty.\n");
1529 return 0; 1528 ret = 0;
1529 goto err_event_unlock;
1530 } 1530 }
1531 1531
1532 mutex_lock(&c_node->mem_lock);
1532 if (!ipp_check_mem_list(c_node)) { 1533 if (!ipp_check_mem_list(c_node)) {
1533 DRM_DEBUG_KMS("empty memory.\n"); 1534 DRM_DEBUG_KMS("empty memory.\n");
1534 return 0; 1535 ret = 0;
1536 goto err_mem_unlock;
1535 } 1537 }
1536 1538
1537 /* check command */ 1539 /* check command */
@@ -1545,7 +1547,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1545 struct drm_exynos_ipp_mem_node, list); 1547 struct drm_exynos_ipp_mem_node, list);
1546 if (!m_node) { 1548 if (!m_node) {
1547 DRM_ERROR("empty memory node.\n"); 1549 DRM_ERROR("empty memory node.\n");
1548 return -ENOMEM; 1550 ret = -ENOMEM;
1551 goto err_mem_unlock;
1549 } 1552 }
1550 1553
1551 tbuf_id[i] = m_node->buf_id; 1554 tbuf_id[i] = m_node->buf_id;
@@ -1567,7 +1570,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1567 m_node = ipp_find_mem_node(c_node, &qbuf); 1570 m_node = ipp_find_mem_node(c_node, &qbuf);
1568 if (!m_node) { 1571 if (!m_node) {
1569 DRM_ERROR("empty memory node.\n"); 1572 DRM_ERROR("empty memory node.\n");
1570 return -ENOMEM; 1573 ret = -ENOMEM;
1574 goto err_mem_unlock;
1571 } 1575 }
1572 1576
1573 tbuf_id[EXYNOS_DRM_OPS_DST] = m_node->buf_id; 1577 tbuf_id[EXYNOS_DRM_OPS_DST] = m_node->buf_id;
@@ -1584,7 +1588,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1584 struct drm_exynos_ipp_mem_node, list); 1588 struct drm_exynos_ipp_mem_node, list);
1585 if (!m_node) { 1589 if (!m_node) {
1586 DRM_ERROR("empty memory node.\n"); 1590 DRM_ERROR("empty memory node.\n");
1587 return -ENOMEM; 1591 ret = -ENOMEM;
1592 goto err_mem_unlock;
1588 } 1593 }
1589 1594
1590 tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id; 1595 tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id;
@@ -1595,8 +1600,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1595 break; 1600 break;
1596 default: 1601 default:
1597 DRM_ERROR("invalid operations.\n"); 1602 DRM_ERROR("invalid operations.\n");
1598 return -EINVAL; 1603 ret = -EINVAL;
1604 goto err_mem_unlock;
1599 } 1605 }
1606 mutex_unlock(&c_node->mem_lock);
1600 1607
1601 if (tbuf_id[EXYNOS_DRM_OPS_DST] != buf_id[EXYNOS_DRM_OPS_DST]) 1608 if (tbuf_id[EXYNOS_DRM_OPS_DST] != buf_id[EXYNOS_DRM_OPS_DST])
1602 DRM_ERROR("failed to match buf_id[%d %d]prop_id[%d]\n", 1609 DRM_ERROR("failed to match buf_id[%d %d]prop_id[%d]\n",
@@ -1611,11 +1618,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1611 e = list_first_entry(&c_node->event_list, 1618 e = list_first_entry(&c_node->event_list,
1612 struct drm_exynos_ipp_send_event, base.link); 1619 struct drm_exynos_ipp_send_event, base.link);
1613 1620
1614 if (!e) {
1615 DRM_ERROR("empty event.\n");
1616 return -EINVAL;
1617 }
1618
1619 do_gettimeofday(&now); 1621 do_gettimeofday(&now);
1620 DRM_DEBUG_KMS("tv_sec[%ld]tv_usec[%ld]\n", now.tv_sec, now.tv_usec); 1622 DRM_DEBUG_KMS("tv_sec[%ld]tv_usec[%ld]\n", now.tv_sec, now.tv_usec);
1621 e->event.tv_sec = now.tv_sec; 1623 e->event.tv_sec = now.tv_sec;
@@ -1630,11 +1632,18 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
1630 list_move_tail(&e->base.link, &e->base.file_priv->event_list); 1632 list_move_tail(&e->base.link, &e->base.file_priv->event_list);
1631 wake_up_interruptible(&e->base.file_priv->event_wait); 1633 wake_up_interruptible(&e->base.file_priv->event_wait);
1632 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 1634 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
1635 mutex_unlock(&c_node->event_lock);
1633 1636
1634 DRM_DEBUG_KMS("done cmd[%d]prop_id[%d]buf_id[%d]\n", 1637 DRM_DEBUG_KMS("done cmd[%d]prop_id[%d]buf_id[%d]\n",
1635 property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]); 1638 property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]);
1636 1639
1637 return 0; 1640 return 0;
1641
1642err_mem_unlock:
1643 mutex_unlock(&c_node->mem_lock);
1644err_event_unlock:
1645 mutex_unlock(&c_node->event_lock);
1646 return ret;
1638} 1647}
1639 1648
1640void ipp_sched_event(struct work_struct *work) 1649void ipp_sched_event(struct work_struct *work)
@@ -1676,8 +1685,6 @@ void ipp_sched_event(struct work_struct *work)
1676 goto err_completion; 1685 goto err_completion;
1677 } 1686 }
1678 1687
1679 mutex_lock(&c_node->event_lock);
1680
1681 ret = ipp_send_event(ippdrv, c_node, event_work->buf_id); 1688 ret = ipp_send_event(ippdrv, c_node, event_work->buf_id);
1682 if (ret) { 1689 if (ret) {
1683 DRM_ERROR("failed to send event.\n"); 1690 DRM_ERROR("failed to send event.\n");
@@ -1687,8 +1694,6 @@ void ipp_sched_event(struct work_struct *work)
1687err_completion: 1694err_completion:
1688 if (ipp_is_m2m_cmd(c_node->property.cmd)) 1695 if (ipp_is_m2m_cmd(c_node->property.cmd))
1689 complete(&c_node->start_complete); 1696 complete(&c_node->start_complete);
1690
1691 mutex_unlock(&c_node->event_lock);
1692} 1697}
1693 1698
1694static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev) 1699static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
@@ -1699,23 +1704,21 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
1699 1704
1700 /* get ipp driver entry */ 1705 /* get ipp driver entry */
1701 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { 1706 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
1707 u32 ipp_id;
1708
1702 ippdrv->drm_dev = drm_dev; 1709 ippdrv->drm_dev = drm_dev;
1703 1710
1704 ret = ipp_create_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv, 1711 ret = ipp_create_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv,
1705 &ippdrv->ipp_id); 1712 &ipp_id);
1706 if (ret) { 1713 if (ret || ipp_id == 0) {
1707 DRM_ERROR("failed to create id.\n"); 1714 DRM_ERROR("failed to create id.\n");
1708 goto err_idr; 1715 goto err;
1709 } 1716 }
1710 1717
1711 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n", 1718 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
1712 count++, (int)ippdrv, ippdrv->ipp_id); 1719 count++, (int)ippdrv, ipp_id);
1713 1720
1714 if (ippdrv->ipp_id == 0) { 1721 ippdrv->prop_list.ipp_id = ipp_id;
1715 DRM_ERROR("failed to get ipp_id[%d]\n",
1716 ippdrv->ipp_id);
1717 goto err_idr;
1718 }
1719 1722
1720 /* store parent device for node */ 1723 /* store parent device for node */
1721 ippdrv->parent_dev = dev; 1724 ippdrv->parent_dev = dev;
@@ -1724,39 +1727,46 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
1724 ippdrv->event_workq = ctx->event_workq; 1727 ippdrv->event_workq = ctx->event_workq;
1725 ippdrv->sched_event = ipp_sched_event; 1728 ippdrv->sched_event = ipp_sched_event;
1726 INIT_LIST_HEAD(&ippdrv->cmd_list); 1729 INIT_LIST_HEAD(&ippdrv->cmd_list);
1730 mutex_init(&ippdrv->cmd_lock);
1727 1731
1728 if (is_drm_iommu_supported(drm_dev)) { 1732 if (is_drm_iommu_supported(drm_dev)) {
1729 ret = drm_iommu_attach_device(drm_dev, ippdrv->dev); 1733 ret = drm_iommu_attach_device(drm_dev, ippdrv->dev);
1730 if (ret) { 1734 if (ret) {
1731 DRM_ERROR("failed to activate iommu\n"); 1735 DRM_ERROR("failed to activate iommu\n");
1732 goto err_iommu; 1736 goto err;
1733 } 1737 }
1734 } 1738 }
1735 } 1739 }
1736 1740
1737 return 0; 1741 return 0;
1738 1742
1739err_iommu: 1743err:
1740 /* get ipp driver entry */ 1744 /* get ipp driver entry */
1741 list_for_each_entry_reverse(ippdrv, &exynos_drm_ippdrv_list, drv_list) 1745 list_for_each_entry_continue_reverse(ippdrv, &exynos_drm_ippdrv_list,
1746 drv_list) {
1742 if (is_drm_iommu_supported(drm_dev)) 1747 if (is_drm_iommu_supported(drm_dev))
1743 drm_iommu_detach_device(drm_dev, ippdrv->dev); 1748 drm_iommu_detach_device(drm_dev, ippdrv->dev);
1744 1749
1745err_idr: 1750 ipp_remove_id(&ctx->ipp_idr, &ctx->ipp_lock,
1746 idr_destroy(&ctx->ipp_idr); 1751 ippdrv->prop_list.ipp_id);
1747 idr_destroy(&ctx->prop_idr); 1752 }
1753
1748 return ret; 1754 return ret;
1749} 1755}
1750 1756
1751static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev) 1757static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
1752{ 1758{
1753 struct exynos_drm_ippdrv *ippdrv; 1759 struct exynos_drm_ippdrv *ippdrv;
1760 struct ipp_context *ctx = get_ipp_context(dev);
1754 1761
1755 /* get ipp driver entry */ 1762 /* get ipp driver entry */
1756 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { 1763 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
1757 if (is_drm_iommu_supported(drm_dev)) 1764 if (is_drm_iommu_supported(drm_dev))
1758 drm_iommu_detach_device(drm_dev, ippdrv->dev); 1765 drm_iommu_detach_device(drm_dev, ippdrv->dev);
1759 1766
1767 ipp_remove_id(&ctx->ipp_idr, &ctx->ipp_lock,
1768 ippdrv->prop_list.ipp_id);
1769
1760 ippdrv->drm_dev = NULL; 1770 ippdrv->drm_dev = NULL;
1761 exynos_drm_ippdrv_unregister(ippdrv); 1771 exynos_drm_ippdrv_unregister(ippdrv);
1762 } 1772 }
@@ -1787,20 +1797,14 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
1787 struct drm_exynos_file_private *file_priv = file->driver_priv; 1797 struct drm_exynos_file_private *file_priv = file->driver_priv;
1788 struct exynos_drm_ipp_private *priv = file_priv->ipp_priv; 1798 struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
1789 struct exynos_drm_ippdrv *ippdrv = NULL; 1799 struct exynos_drm_ippdrv *ippdrv = NULL;
1800 struct ipp_context *ctx = get_ipp_context(dev);
1790 struct drm_exynos_ipp_cmd_node *c_node, *tc_node; 1801 struct drm_exynos_ipp_cmd_node *c_node, *tc_node;
1791 int count = 0; 1802 int count = 0;
1792 1803
1793 DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv); 1804 DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv);
1794 1805
1795 if (list_empty(&exynos_drm_ippdrv_list)) {
1796 DRM_DEBUG_KMS("ippdrv_list is empty.\n");
1797 goto err_clear;
1798 }
1799
1800 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { 1806 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
1801 if (list_empty(&ippdrv->cmd_list)) 1807 mutex_lock(&ippdrv->cmd_lock);
1802 continue;
1803
1804 list_for_each_entry_safe(c_node, tc_node, 1808 list_for_each_entry_safe(c_node, tc_node,
1805 &ippdrv->cmd_list, list) { 1809 &ippdrv->cmd_list, list) {
1806 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", 1810 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n",
@@ -1820,14 +1824,14 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
1820 } 1824 }
1821 1825
1822 ippdrv->dedicated = false; 1826 ippdrv->dedicated = false;
1823 ipp_clean_cmd_node(c_node); 1827 ipp_clean_cmd_node(ctx, c_node);
1824 if (list_empty(&ippdrv->cmd_list)) 1828 if (list_empty(&ippdrv->cmd_list))
1825 pm_runtime_put_sync(ippdrv->dev); 1829 pm_runtime_put_sync(ippdrv->dev);
1826 } 1830 }
1827 } 1831 }
1832 mutex_unlock(&ippdrv->cmd_lock);
1828 } 1833 }
1829 1834
1830err_clear:
1831 kfree(priv); 1835 kfree(priv);
1832 return; 1836 return;
1833} 1837}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
index ab1634befc05..7aaeaae757c2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -52,7 +52,7 @@ struct drm_exynos_ipp_cmd_work {
52 * @list: list head to command queue information. 52 * @list: list head to command queue information.
53 * @event_list: list head of event. 53 * @event_list: list head of event.
54 * @mem_list: list head to source,destination memory queue information. 54 * @mem_list: list head to source,destination memory queue information.
55 * @cmd_lock: lock for synchronization of access to ioctl. 55 * @lock: lock for synchronization of access to ioctl.
56 * @mem_lock: lock for synchronization of access to memory nodes. 56 * @mem_lock: lock for synchronization of access to memory nodes.
57 * @event_lock: lock for synchronization of access to scheduled event. 57 * @event_lock: lock for synchronization of access to scheduled event.
58 * @start_complete: completion of start of command. 58 * @start_complete: completion of start of command.
@@ -68,7 +68,7 @@ struct drm_exynos_ipp_cmd_node {
68 struct list_head list; 68 struct list_head list;
69 struct list_head event_list; 69 struct list_head event_list;
70 struct list_head mem_list[EXYNOS_DRM_OPS_MAX]; 70 struct list_head mem_list[EXYNOS_DRM_OPS_MAX];
71 struct mutex cmd_lock; 71 struct mutex lock;
72 struct mutex mem_lock; 72 struct mutex mem_lock;
73 struct mutex event_lock; 73 struct mutex event_lock;
74 struct completion start_complete; 74 struct completion start_complete;
@@ -83,7 +83,7 @@ struct drm_exynos_ipp_cmd_node {
83/* 83/*
84 * A structure of buffer information. 84 * A structure of buffer information.
85 * 85 *
86 * @gem_objs: Y, Cb, Cr each gem object. 86 * @handles: Y, Cb, Cr each gem object handle.
87 * @base: Y, Cb, Cr each planar address. 87 * @base: Y, Cb, Cr each planar address.
88 */ 88 */
89struct drm_exynos_ipp_buf_info { 89struct drm_exynos_ipp_buf_info {
@@ -142,12 +142,12 @@ struct exynos_drm_ipp_ops {
142 * @parent_dev: parent device information. 142 * @parent_dev: parent device information.
143 * @dev: platform device. 143 * @dev: platform device.
144 * @drm_dev: drm device. 144 * @drm_dev: drm device.
145 * @ipp_id: id of ipp driver.
146 * @dedicated: dedicated ipp device. 145 * @dedicated: dedicated ipp device.
147 * @ops: source, destination operations. 146 * @ops: source, destination operations.
148 * @event_workq: event work queue. 147 * @event_workq: event work queue.
149 * @c_node: current command information. 148 * @c_node: current command information.
150 * @cmd_list: list head for command information. 149 * @cmd_list: list head for command information.
150 * @cmd_lock: lock for synchronization of access to cmd_list.
151 * @prop_list: property informations of current ipp driver. 151 * @prop_list: property informations of current ipp driver.
152 * @check_property: check property about format, size, buffer. 152 * @check_property: check property about format, size, buffer.
153 * @reset: reset ipp block. 153 * @reset: reset ipp block.
@@ -160,13 +160,13 @@ struct exynos_drm_ippdrv {
160 struct device *parent_dev; 160 struct device *parent_dev;
161 struct device *dev; 161 struct device *dev;
162 struct drm_device *drm_dev; 162 struct drm_device *drm_dev;
163 u32 ipp_id;
164 bool dedicated; 163 bool dedicated;
165 struct exynos_drm_ipp_ops *ops[EXYNOS_DRM_OPS_MAX]; 164 struct exynos_drm_ipp_ops *ops[EXYNOS_DRM_OPS_MAX];
166 struct workqueue_struct *event_workq; 165 struct workqueue_struct *event_workq;
167 struct drm_exynos_ipp_cmd_node *c_node; 166 struct drm_exynos_ipp_cmd_node *c_node;
168 struct list_head cmd_list; 167 struct list_head cmd_list;
169 struct drm_exynos_ipp_prop_list *prop_list; 168 struct mutex cmd_lock;
169 struct drm_exynos_ipp_prop_list prop_list;
170 170
171 int (*check_property)(struct device *dev, 171 int (*check_property)(struct device *dev,
172 struct drm_exynos_ipp_property *property); 172 struct drm_exynos_ipp_property *property);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index 7b901688defa..f01fbb6dc1f0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -158,8 +158,9 @@ static irqreturn_t rotator_irq_handler(int irq, void *arg)
158 rot->cur_buf_id[EXYNOS_DRM_OPS_DST]; 158 rot->cur_buf_id[EXYNOS_DRM_OPS_DST];
159 queue_work(ippdrv->event_workq, 159 queue_work(ippdrv->event_workq,
160 (struct work_struct *)event_work); 160 (struct work_struct *)event_work);
161 } else 161 } else {
162 DRM_ERROR("the SFR is set illegally\n"); 162 DRM_ERROR("the SFR is set illegally\n");
163 }
163 164
164 return IRQ_HANDLED; 165 return IRQ_HANDLED;
165} 166}
@@ -469,11 +470,7 @@ static struct exynos_drm_ipp_ops rot_dst_ops = {
469 470
470static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv) 471static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
471{ 472{
472 struct drm_exynos_ipp_prop_list *prop_list; 473 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list;
473
474 prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
475 if (!prop_list)
476 return -ENOMEM;
477 474
478 prop_list->version = 1; 475 prop_list->version = 1;
479 prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) | 476 prop_list->flip = (1 << EXYNOS_DRM_FLIP_VERTICAL) |
@@ -486,8 +483,6 @@ static int rotator_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
486 prop_list->crop = 0; 483 prop_list->crop = 0;
487 prop_list->scale = 0; 484 prop_list->scale = 0;
488 485
489 ippdrv->prop_list = prop_list;
490
491 return 0; 486 return 0;
492} 487}
493 488
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 3fa987df906a..2fb8705d6461 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -51,6 +51,7 @@ struct vidi_context {
51 struct drm_crtc *crtc; 51 struct drm_crtc *crtc;
52 struct drm_encoder *encoder; 52 struct drm_encoder *encoder;
53 struct drm_connector connector; 53 struct drm_connector connector;
54 struct exynos_drm_subdrv subdrv;
54 struct vidi_win_data win_data[WINDOWS_NR]; 55 struct vidi_win_data win_data[WINDOWS_NR];
55 struct edid *raw_edid; 56 struct edid *raw_edid;
56 unsigned int clkdiv; 57 unsigned int clkdiv;
@@ -294,14 +295,13 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
294} 295}
295 296
296static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, 297static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
297 struct drm_device *drm_dev, int pipe) 298 struct drm_device *drm_dev)
298{ 299{
299 struct vidi_context *ctx = mgr->ctx; 300 struct vidi_context *ctx = mgr->ctx;
301 struct exynos_drm_private *priv = drm_dev->dev_private;
300 302
301 DRM_ERROR("vidi initialize ct=%p dev=%p pipe=%d\n", ctx, drm_dev, pipe); 303 mgr->drm_dev = ctx->drm_dev = drm_dev;
302 304 mgr->pipe = ctx->pipe = priv->pipe++;
303 ctx->drm_dev = drm_dev;
304 ctx->pipe = pipe;
305 305
306 /* 306 /*
307 * enable drm irq mode. 307 * enable drm irq mode.
@@ -324,7 +324,6 @@ static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
324} 324}
325 325
326static struct exynos_drm_manager_ops vidi_manager_ops = { 326static struct exynos_drm_manager_ops vidi_manager_ops = {
327 .initialize = vidi_mgr_initialize,
328 .dpms = vidi_dpms, 327 .dpms = vidi_dpms,
329 .commit = vidi_commit, 328 .commit = vidi_commit,
330 .enable_vblank = vidi_enable_vblank, 329 .enable_vblank = vidi_enable_vblank,
@@ -579,13 +578,38 @@ static struct exynos_drm_display vidi_display = {
579 .ops = &vidi_display_ops, 578 .ops = &vidi_display_ops,
580}; 579};
581 580
581static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
582{
583 struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
584 struct vidi_context *ctx = mgr->ctx;
585 struct drm_crtc *crtc = ctx->crtc;
586 int ret;
587
588 vidi_mgr_initialize(mgr, drm_dev);
589
590 ret = exynos_drm_crtc_create(&vidi_manager);
591 if (ret) {
592 DRM_ERROR("failed to create crtc.\n");
593 return ret;
594 }
595
596 ret = exynos_drm_create_enc_conn(drm_dev, &vidi_display);
597 if (ret) {
598 crtc->funcs->destroy(crtc);
599 DRM_ERROR("failed to create encoder and connector.\n");
600 return ret;
601 }
602
603 return 0;
604}
605
582static int vidi_probe(struct platform_device *pdev) 606static int vidi_probe(struct platform_device *pdev)
583{ 607{
584 struct device *dev = &pdev->dev; 608 struct exynos_drm_subdrv *subdrv;
585 struct vidi_context *ctx; 609 struct vidi_context *ctx;
586 int ret; 610 int ret;
587 611
588 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 612 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
589 if (!ctx) 613 if (!ctx)
590 return -ENOMEM; 614 return -ENOMEM;
591 615
@@ -600,28 +624,43 @@ static int vidi_probe(struct platform_device *pdev)
600 624
601 platform_set_drvdata(pdev, &vidi_manager); 625 platform_set_drvdata(pdev, &vidi_manager);
602 626
603 ret = device_create_file(dev, &dev_attr_connection); 627 subdrv = &ctx->subdrv;
604 if (ret < 0) 628 subdrv->dev = &pdev->dev;
605 DRM_INFO("failed to create connection sysfs.\n"); 629 subdrv->probe = vidi_subdrv_probe;
606 630
607 exynos_drm_manager_register(&vidi_manager); 631 ret = exynos_drm_subdrv_register(subdrv);
608 exynos_drm_display_register(&vidi_display); 632 if (ret < 0) {
633 dev_err(&pdev->dev, "failed to register drm vidi device\n");
634 return ret;
635 }
636
637 ret = device_create_file(&pdev->dev, &dev_attr_connection);
638 if (ret < 0) {
639 exynos_drm_subdrv_unregister(subdrv);
640 DRM_INFO("failed to create connection sysfs.\n");
641 }
609 642
610 return 0; 643 return 0;
611} 644}
612 645
613static int vidi_remove(struct platform_device *pdev) 646static int vidi_remove(struct platform_device *pdev)
614{ 647{
615 struct vidi_context *ctx = platform_get_drvdata(pdev); 648 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
616 649 struct vidi_context *ctx = mgr->ctx;
617 exynos_drm_display_unregister(&vidi_display); 650 struct drm_encoder *encoder = ctx->encoder;
618 exynos_drm_manager_unregister(&vidi_manager); 651 struct drm_crtc *crtc = mgr->crtc;
619 652
620 if (ctx->raw_edid != (struct edid *)fake_edid_info) { 653 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
621 kfree(ctx->raw_edid); 654 kfree(ctx->raw_edid);
622 ctx->raw_edid = NULL; 655 ctx->raw_edid = NULL;
656
657 return -EINVAL;
623 } 658 }
624 659
660 crtc->funcs->destroy(crtc);
661 encoder->funcs->destroy(encoder);
662 drm_connector_cleanup(&ctx->connector);
663
625 return 0; 664 return 0;
626} 665}
627 666
@@ -633,3 +672,31 @@ struct platform_driver vidi_driver = {
633 .owner = THIS_MODULE, 672 .owner = THIS_MODULE,
634 }, 673 },
635}; 674};
675
676int exynos_drm_probe_vidi(void)
677{
678 struct platform_device *pdev;
679 int ret;
680
681 pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0);
682 if (IS_ERR(pdev))
683 return PTR_ERR(pdev);
684
685 ret = platform_driver_register(&vidi_driver);
686 if (ret) {
687 platform_device_unregister(pdev);
688 return ret;
689 }
690
691 return ret;
692}
693
694void exynos_drm_remove_vidi(void)
695{
696 struct vidi_context *ctx = vidi_manager.ctx;
697 struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
698 struct platform_device *pdev = to_platform_device(subdrv->dev);
699
700 platform_driver_unregister(&vidi_driver);
701 platform_device_unregister(pdev);
702}
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 9a6d652a3ef2..c104d0c9b385 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -33,13 +33,17 @@
33#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
34#include <linux/io.h> 34#include <linux/io.h>
35#include <linux/of.h> 35#include <linux/of.h>
36#include <linux/i2c.h> 36#include <linux/of_address.h>
37#include <linux/of_gpio.h> 37#include <linux/of_gpio.h>
38#include <linux/hdmi.h> 38#include <linux/hdmi.h>
39#include <linux/component.h>
40#include <linux/mfd/syscon.h>
41#include <linux/regmap.h>
39 42
40#include <drm/exynos_drm.h> 43#include <drm/exynos_drm.h>
41 44
42#include "exynos_drm_drv.h" 45#include "exynos_drm_drv.h"
46#include "exynos_drm_crtc.h"
43#include "exynos_mixer.h" 47#include "exynos_mixer.h"
44 48
45#include <linux/gpio.h> 49#include <linux/gpio.h>
@@ -48,6 +52,8 @@
48#define get_hdmi_display(dev) platform_get_drvdata(to_platform_device(dev)) 52#define get_hdmi_display(dev) platform_get_drvdata(to_platform_device(dev))
49#define ctx_from_connector(c) container_of(c, struct hdmi_context, connector) 53#define ctx_from_connector(c) container_of(c, struct hdmi_context, connector)
50 54
55#define HOTPLUG_DEBOUNCE_MS 1100
56
51/* AVI header and aspect ratio */ 57/* AVI header and aspect ratio */
52#define HDMI_AVI_VERSION 0x02 58#define HDMI_AVI_VERSION 0x02
53#define HDMI_AVI_LENGTH 0x0D 59#define HDMI_AVI_LENGTH 0x0D
@@ -66,6 +72,8 @@ enum hdmi_type {
66 72
67struct hdmi_driver_data { 73struct hdmi_driver_data {
68 unsigned int type; 74 unsigned int type;
75 const struct hdmiphy_config *phy_confs;
76 unsigned int phy_conf_count;
69 unsigned int is_apb_phy:1; 77 unsigned int is_apb_phy:1;
70}; 78};
71 79
@@ -74,7 +82,6 @@ struct hdmi_resources {
74 struct clk *sclk_hdmi; 82 struct clk *sclk_hdmi;
75 struct clk *sclk_pixel; 83 struct clk *sclk_pixel;
76 struct clk *sclk_hdmiphy; 84 struct clk *sclk_hdmiphy;
77 struct clk *hdmiphy;
78 struct clk *mout_hdmi; 85 struct clk *mout_hdmi;
79 struct regulator_bulk_data *regul_bulk; 86 struct regulator_bulk_data *regul_bulk;
80 int regul_count; 87 int regul_count;
@@ -185,17 +192,23 @@ struct hdmi_context {
185 192
186 void __iomem *regs; 193 void __iomem *regs;
187 int irq; 194 int irq;
195 struct delayed_work hotplug_work;
188 196
189 struct i2c_adapter *ddc_adpt; 197 struct i2c_adapter *ddc_adpt;
190 struct i2c_client *hdmiphy_port; 198 struct i2c_client *hdmiphy_port;
191 199
192 /* current hdmiphy conf regs */ 200 /* current hdmiphy conf regs */
201 struct drm_display_mode current_mode;
193 struct hdmi_conf_regs mode_conf; 202 struct hdmi_conf_regs mode_conf;
194 203
195 struct hdmi_resources res; 204 struct hdmi_resources res;
196 205
197 int hpd_gpio; 206 int hpd_gpio;
207 void __iomem *regs_hdmiphy;
208 const struct hdmiphy_config *phy_confs;
209 unsigned int phy_conf_count;
198 210
211 struct regmap *pmureg;
199 enum hdmi_type type; 212 enum hdmi_type type;
200}; 213};
201 214
@@ -204,14 +217,6 @@ struct hdmiphy_config {
204 u8 conf[32]; 217 u8 conf[32];
205}; 218};
206 219
207struct hdmi_driver_data exynos4212_hdmi_driver_data = {
208 .type = HDMI_TYPE14,
209};
210
211struct hdmi_driver_data exynos5_hdmi_driver_data = {
212 .type = HDMI_TYPE14,
213};
214
215/* list of phy config settings */ 220/* list of phy config settings */
216static const struct hdmiphy_config hdmiphy_v13_configs[] = { 221static const struct hdmiphy_config hdmiphy_v13_configs[] = {
217 { 222 {
@@ -319,18 +324,18 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = {
319 { 324 {
320 .pixel_clock = 71000000, 325 .pixel_clock = 71000000,
321 .conf = { 326 .conf = {
322 0x01, 0x91, 0x1e, 0x15, 0x40, 0x3c, 0xce, 0x08, 327 0x01, 0xd1, 0x3b, 0x35, 0x40, 0x0c, 0x04, 0x08,
323 0x04, 0x20, 0xb2, 0xd8, 0x45, 0xa0, 0xac, 0x80, 328 0x85, 0xa0, 0x63, 0xd9, 0x45, 0xa0, 0xac, 0x80,
324 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 329 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
325 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, 330 0x54, 0xad, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
326 }, 331 },
327 }, 332 },
328 { 333 {
329 .pixel_clock = 73250000, 334 .pixel_clock = 73250000,
330 .conf = { 335 .conf = {
331 0x01, 0xd1, 0x1f, 0x15, 0x40, 0x18, 0xe9, 0x08, 336 0x01, 0xd1, 0x3d, 0x35, 0x40, 0x18, 0x02, 0x08,
332 0x02, 0xa0, 0xb7, 0xd8, 0x45, 0xa0, 0xac, 0x80, 337 0x83, 0xa0, 0x6e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
333 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 338 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
334 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80, 339 0x54, 0xa8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
335 }, 340 },
336 }, 341 },
@@ -362,15 +367,6 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = {
362 }, 367 },
363 }, 368 },
364 { 369 {
365 .pixel_clock = 88750000,
366 .conf = {
367 0x01, 0x91, 0x25, 0x17, 0x40, 0x30, 0xfe, 0x08,
368 0x06, 0x20, 0xde, 0xd8, 0x45, 0xa0, 0xac, 0x80,
369 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
370 0x54, 0x8a, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
371 },
372 },
373 {
374 .pixel_clock = 106500000, 370 .pixel_clock = 106500000,
375 .conf = { 371 .conf = {
376 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08, 372 0x01, 0xd1, 0x2c, 0x12, 0x40, 0x0c, 0x09, 0x08,
@@ -391,18 +387,18 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = {
391 { 387 {
392 .pixel_clock = 115500000, 388 .pixel_clock = 115500000,
393 .conf = { 389 .conf = {
394 0x01, 0xd1, 0x30, 0x1a, 0x40, 0x40, 0x10, 0x04, 390 0x01, 0xd1, 0x30, 0x12, 0x40, 0x40, 0x10, 0x08,
395 0x04, 0xa0, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80, 391 0x80, 0x80, 0x21, 0xd9, 0x45, 0xa0, 0xac, 0x80,
396 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 392 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
397 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80, 393 0x54, 0xaa, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
398 }, 394 },
399 }, 395 },
400 { 396 {
401 .pixel_clock = 119000000, 397 .pixel_clock = 119000000,
402 .conf = { 398 .conf = {
403 0x01, 0x91, 0x32, 0x14, 0x40, 0x60, 0xd8, 0x08, 399 0x01, 0xd1, 0x32, 0x1a, 0x40, 0x30, 0xd8, 0x08,
404 0x06, 0x20, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80, 400 0x04, 0xa0, 0x2a, 0xd9, 0x45, 0xa0, 0xac, 0x80,
405 0x06, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86, 401 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
406 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80, 402 0x54, 0x9d, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
407 }, 403 },
408 }, 404 },
@@ -426,6 +422,183 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = {
426 }, 422 },
427}; 423};
428 424
425static const struct hdmiphy_config hdmiphy_5420_configs[] = {
426 {
427 .pixel_clock = 25200000,
428 .conf = {
429 0x01, 0x52, 0x3F, 0x55, 0x40, 0x01, 0x00, 0xC8,
430 0x82, 0xC8, 0xBD, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
431 0x06, 0x80, 0x01, 0x84, 0x05, 0x02, 0x24, 0x66,
432 0x54, 0xF4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
433 },
434 },
435 {
436 .pixel_clock = 27000000,
437 .conf = {
438 0x01, 0xD1, 0x22, 0x51, 0x40, 0x08, 0xFC, 0xE0,
439 0x98, 0xE8, 0xCB, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
440 0x06, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
441 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
442 },
443 },
444 {
445 .pixel_clock = 27027000,
446 .conf = {
447 0x01, 0xD1, 0x2D, 0x72, 0x40, 0x64, 0x12, 0xC8,
448 0x43, 0xE8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
449 0x26, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
450 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
451 },
452 },
453 {
454 .pixel_clock = 36000000,
455 .conf = {
456 0x01, 0x51, 0x2D, 0x55, 0x40, 0x40, 0x00, 0xC8,
457 0x02, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
458 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
459 0x54, 0xAB, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
460 },
461 },
462 {
463 .pixel_clock = 40000000,
464 .conf = {
465 0x01, 0xD1, 0x21, 0x31, 0x40, 0x3C, 0x28, 0xC8,
466 0x87, 0xE8, 0xC8, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
467 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
468 0x54, 0x9A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
469 },
470 },
471 {
472 .pixel_clock = 65000000,
473 .conf = {
474 0x01, 0xD1, 0x36, 0x34, 0x40, 0x0C, 0x04, 0xC8,
475 0x82, 0xE8, 0x45, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
476 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
477 0x54, 0xBD, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
478 },
479 },
480 {
481 .pixel_clock = 71000000,
482 .conf = {
483 0x01, 0xD1, 0x3B, 0x35, 0x40, 0x0C, 0x04, 0xC8,
484 0x85, 0xE8, 0x63, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
485 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
486 0x54, 0x57, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
487 },
488 },
489 {
490 .pixel_clock = 73250000,
491 .conf = {
492 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x78, 0x8D, 0xC8,
493 0x81, 0xE8, 0xB7, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
494 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
495 0x54, 0xA8, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
496 },
497 },
498 {
499 .pixel_clock = 74176000,
500 .conf = {
501 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0xC8,
502 0x81, 0xE8, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
503 0x56, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
504 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
505 },
506 },
507 {
508 .pixel_clock = 74250000,
509 .conf = {
510 0x01, 0xD1, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
511 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
512 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
513 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
514 },
515 },
516 {
517 .pixel_clock = 83500000,
518 .conf = {
519 0x01, 0xD1, 0x23, 0x11, 0x40, 0x0C, 0xFB, 0xC8,
520 0x85, 0xE8, 0xD1, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
521 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
522 0x54, 0x4A, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
523 },
524 },
525 {
526 .pixel_clock = 88750000,
527 .conf = {
528 0x01, 0xD1, 0x25, 0x11, 0x40, 0x18, 0xFF, 0xC8,
529 0x83, 0xE8, 0xDE, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
530 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
531 0x54, 0x45, 0x24, 0x00, 0x00, 0x00, 0x01, 0x80,
532 },
533 },
534 {
535 .pixel_clock = 106500000,
536 .conf = {
537 0x01, 0xD1, 0x2C, 0x12, 0x40, 0x0C, 0x09, 0xC8,
538 0x84, 0xE8, 0x0A, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
539 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
540 0x54, 0x73, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
541 },
542 },
543 {
544 .pixel_clock = 108000000,
545 .conf = {
546 0x01, 0x51, 0x2D, 0x15, 0x40, 0x01, 0x00, 0xC8,
547 0x82, 0xC8, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
548 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
549 0x54, 0xC7, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
550 },
551 },
552 {
553 .pixel_clock = 115500000,
554 .conf = {
555 0x01, 0xD1, 0x30, 0x14, 0x40, 0x0C, 0x03, 0xC8,
556 0x88, 0xE8, 0x21, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
557 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
558 0x54, 0x6A, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
559 },
560 },
561 {
562 .pixel_clock = 146250000,
563 .conf = {
564 0x01, 0xD1, 0x3D, 0x15, 0x40, 0x18, 0xFD, 0xC8,
565 0x83, 0xE8, 0x6E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
566 0x08, 0x80, 0x09, 0x84, 0x05, 0x02, 0x24, 0x66,
567 0x54, 0x54, 0x24, 0x01, 0x00, 0x00, 0x01, 0x80,
568 },
569 },
570 {
571 .pixel_clock = 148500000,
572 .conf = {
573 0x01, 0xD1, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
574 0x81, 0xE8, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
575 0x26, 0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x66,
576 0x54, 0x4B, 0x25, 0x03, 0x00, 0x80, 0x01, 0x80,
577 },
578 },
579};
580
581static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
582 .type = HDMI_TYPE14,
583 .phy_confs = hdmiphy_5420_configs,
584 .phy_conf_count = ARRAY_SIZE(hdmiphy_5420_configs),
585 .is_apb_phy = 1,
586};
587
588static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
589 .type = HDMI_TYPE14,
590 .phy_confs = hdmiphy_v14_configs,
591 .phy_conf_count = ARRAY_SIZE(hdmiphy_v14_configs),
592 .is_apb_phy = 0,
593};
594
595static struct hdmi_driver_data exynos5_hdmi_driver_data = {
596 .type = HDMI_TYPE14,
597 .phy_confs = hdmiphy_v13_configs,
598 .phy_conf_count = ARRAY_SIZE(hdmiphy_v13_configs),
599 .is_apb_phy = 0,
600};
601
429static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) 602static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
430{ 603{
431 return readl(hdata->regs + reg_id); 604 return readl(hdata->regs + reg_id);
@@ -445,6 +618,48 @@ static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
445 writel(value, hdata->regs + reg_id); 618 writel(value, hdata->regs + reg_id);
446} 619}
447 620
621static int hdmiphy_reg_writeb(struct hdmi_context *hdata,
622 u32 reg_offset, u8 value)
623{
624 if (hdata->hdmiphy_port) {
625 u8 buffer[2];
626 int ret;
627
628 buffer[0] = reg_offset;
629 buffer[1] = value;
630
631 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 2);
632 if (ret == 2)
633 return 0;
634 return ret;
635 } else {
636 writeb(value, hdata->regs_hdmiphy + (reg_offset<<2));
637 return 0;
638 }
639}
640
641static int hdmiphy_reg_write_buf(struct hdmi_context *hdata,
642 u32 reg_offset, const u8 *buf, u32 len)
643{
644 if ((reg_offset + len) > 32)
645 return -EINVAL;
646
647 if (hdata->hdmiphy_port) {
648 int ret;
649
650 ret = i2c_master_send(hdata->hdmiphy_port, buf, len);
651 if (ret == len)
652 return 0;
653 return ret;
654 } else {
655 int i;
656 for (i = 0; i < len; i++)
657 writeb(buf[i], hdata->regs_hdmiphy +
658 ((reg_offset + i)<<2));
659 return 0;
660 }
661}
662
448static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix) 663static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
449{ 664{
450#define DUMPREG(reg_id) \ 665#define DUMPREG(reg_id) \
@@ -809,6 +1024,8 @@ static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
809{ 1024{
810 struct hdmi_context *hdata = ctx_from_connector(connector); 1025 struct hdmi_context *hdata = ctx_from_connector(connector);
811 1026
1027 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
1028
812 return hdata->hpd ? connector_status_connected : 1029 return hdata->hpd ? connector_status_connected :
813 connector_status_disconnected; 1030 connector_status_disconnected;
814} 1031}
@@ -848,20 +1065,10 @@ static int hdmi_get_modes(struct drm_connector *connector)
848 1065
849static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) 1066static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
850{ 1067{
851 const struct hdmiphy_config *confs; 1068 int i;
852 int count, i;
853
854 if (hdata->type == HDMI_TYPE13) {
855 confs = hdmiphy_v13_configs;
856 count = ARRAY_SIZE(hdmiphy_v13_configs);
857 } else if (hdata->type == HDMI_TYPE14) {
858 confs = hdmiphy_v14_configs;
859 count = ARRAY_SIZE(hdmiphy_v14_configs);
860 } else
861 return -EINVAL;
862 1069
863 for (i = 0; i < count; i++) 1070 for (i = 0; i < hdata->phy_conf_count; i++)
864 if (confs[i].pixel_clock == pixel_clock) 1071 if (hdata->phy_confs[i].pixel_clock == pixel_clock)
865 return i; 1072 return i;
866 1073
867 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock); 1074 DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock);
@@ -928,16 +1135,6 @@ static int hdmi_create_connector(struct exynos_drm_display *display,
928 return 0; 1135 return 0;
929} 1136}
930 1137
931static int hdmi_initialize(struct exynos_drm_display *display,
932 struct drm_device *drm_dev)
933{
934 struct hdmi_context *hdata = display->ctx;
935
936 hdata->drm_dev = drm_dev;
937
938 return 0;
939}
940
941static void hdmi_mode_fixup(struct exynos_drm_display *display, 1138static void hdmi_mode_fixup(struct exynos_drm_display *display,
942 struct drm_connector *connector, 1139 struct drm_connector *connector,
943 const struct drm_display_mode *mode, 1140 const struct drm_display_mode *mode,
@@ -1136,20 +1333,15 @@ static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1136 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK); 1333 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1137} 1334}
1138 1335
1139static void hdmi_conf_reset(struct hdmi_context *hdata) 1336static void hdmi_start(struct hdmi_context *hdata, bool start)
1140{ 1337{
1141 u32 reg; 1338 u32 val = start ? HDMI_TG_EN : 0;
1142 1339
1143 if (hdata->type == HDMI_TYPE13) 1340 if (hdata->current_mode.flags & DRM_MODE_FLAG_INTERLACE)
1144 reg = HDMI_V13_CORE_RSTOUT; 1341 val |= HDMI_FIELD_EN;
1145 else
1146 reg = HDMI_CORE_RSTOUT;
1147 1342
1148 /* resetting HDMI core */ 1343 hdmi_reg_writemask(hdata, HDMI_CON_0, val, HDMI_EN);
1149 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT); 1344 hdmi_reg_writemask(hdata, HDMI_TG_CMD, val, HDMI_TG_EN | HDMI_FIELD_EN);
1150 usleep_range(10000, 12000);
1151 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
1152 usleep_range(10000, 12000);
1153} 1345}
1154 1346
1155static void hdmi_conf_init(struct hdmi_context *hdata) 1347static void hdmi_conf_init(struct hdmi_context *hdata)
@@ -1163,6 +1355,8 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
1163 /* choose HDMI mode */ 1355 /* choose HDMI mode */
1164 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1356 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
1165 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); 1357 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
1358 /* Apply Video preable and Guard band in HDMI mode only */
1359 hdmi_reg_writeb(hdata, HDMI_CON_2, 0);
1166 /* disable bluescreen */ 1360 /* disable bluescreen */
1167 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); 1361 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
1168 1362
@@ -1286,12 +1480,7 @@ static void hdmi_v13_mode_apply(struct hdmi_context *hdata)
1286 clk_prepare_enable(hdata->res.sclk_hdmi); 1480 clk_prepare_enable(hdata->res.sclk_hdmi);
1287 1481
1288 /* enable HDMI and timing generator */ 1482 /* enable HDMI and timing generator */
1289 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); 1483 hdmi_start(hdata, true);
1290 if (core->int_pro_mode[0])
1291 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1292 HDMI_FIELD_EN);
1293 else
1294 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1295} 1484}
1296 1485
1297static void hdmi_v14_mode_apply(struct hdmi_context *hdata) 1486static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
@@ -1453,12 +1642,7 @@ static void hdmi_v14_mode_apply(struct hdmi_context *hdata)
1453 clk_prepare_enable(hdata->res.sclk_hdmi); 1642 clk_prepare_enable(hdata->res.sclk_hdmi);
1454 1643
1455 /* enable HDMI and timing generator */ 1644 /* enable HDMI and timing generator */
1456 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN); 1645 hdmi_start(hdata, true);
1457 if (core->int_pro_mode[0])
1458 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1459 HDMI_FIELD_EN);
1460 else
1461 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1462} 1646}
1463 1647
1464static void hdmi_mode_apply(struct hdmi_context *hdata) 1648static void hdmi_mode_apply(struct hdmi_context *hdata)
@@ -1499,32 +1683,51 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1499 1683
1500static void hdmiphy_poweron(struct hdmi_context *hdata) 1684static void hdmiphy_poweron(struct hdmi_context *hdata)
1501{ 1685{
1502 if (hdata->type == HDMI_TYPE14) 1686 if (hdata->type != HDMI_TYPE14)
1503 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, 0, 1687 return;
1504 HDMI_PHY_POWER_OFF_EN); 1688
1689 DRM_DEBUG_KMS("\n");
1690
1691 /* For PHY Mode Setting */
1692 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1693 HDMI_PHY_ENABLE_MODE_SET);
1694 /* Phy Power On */
1695 hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1696 HDMI_PHY_POWER_ON);
1697 /* For PHY Mode Setting */
1698 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1699 HDMI_PHY_DISABLE_MODE_SET);
1700 /* PHY SW Reset */
1701 hdmiphy_conf_reset(hdata);
1505} 1702}
1506 1703
1507static void hdmiphy_poweroff(struct hdmi_context *hdata) 1704static void hdmiphy_poweroff(struct hdmi_context *hdata)
1508{ 1705{
1509 if (hdata->type == HDMI_TYPE14) 1706 if (hdata->type != HDMI_TYPE14)
1510 hdmi_reg_writemask(hdata, HDMI_PHY_CON_0, ~0, 1707 return;
1511 HDMI_PHY_POWER_OFF_EN); 1708
1709 DRM_DEBUG_KMS("\n");
1710
1711 /* PHY SW Reset */
1712 hdmiphy_conf_reset(hdata);
1713 /* For PHY Mode Setting */
1714 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1715 HDMI_PHY_ENABLE_MODE_SET);
1716
1717 /* PHY Power Off */
1718 hdmiphy_reg_writeb(hdata, HDMIPHY_POWER,
1719 HDMI_PHY_POWER_OFF);
1720
1721 /* For PHY Mode Setting */
1722 hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1723 HDMI_PHY_DISABLE_MODE_SET);
1512} 1724}
1513 1725
1514static void hdmiphy_conf_apply(struct hdmi_context *hdata) 1726static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1515{ 1727{
1516 const u8 *hdmiphy_data;
1517 u8 buffer[32];
1518 u8 operation[2];
1519 u8 read_buffer[32] = {0, };
1520 int ret; 1728 int ret;
1521 int i; 1729 int i;
1522 1730
1523 if (!hdata->hdmiphy_port) {
1524 DRM_ERROR("hdmiphy is not attached\n");
1525 return;
1526 }
1527
1528 /* pixel clock */ 1731 /* pixel clock */
1529 i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock); 1732 i = hdmi_find_phy_conf(hdata, hdata->mode_conf.pixel_clock);
1530 if (i < 0) { 1733 if (i < 0) {
@@ -1532,39 +1735,21 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1532 return; 1735 return;
1533 } 1736 }
1534 1737
1535 if (hdata->type == HDMI_TYPE13) 1738 ret = hdmiphy_reg_write_buf(hdata, 0, hdata->phy_confs[i].conf, 32);
1536 hdmiphy_data = hdmiphy_v13_configs[i].conf; 1739 if (ret) {
1537 else 1740 DRM_ERROR("failed to configure hdmiphy\n");
1538 hdmiphy_data = hdmiphy_v14_configs[i].conf;
1539
1540 memcpy(buffer, hdmiphy_data, 32);
1541 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
1542 if (ret != 32) {
1543 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
1544 return; 1741 return;
1545 } 1742 }
1546 1743
1547 usleep_range(10000, 12000); 1744 usleep_range(10000, 12000);
1548 1745
1549 /* operation mode */ 1746 ret = hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
1550 operation[0] = 0x1f; 1747 HDMI_PHY_DISABLE_MODE_SET);
1551 operation[1] = 0x80; 1748 if (ret) {
1552
1553 ret = i2c_master_send(hdata->hdmiphy_port, operation, 2);
1554 if (ret != 2) {
1555 DRM_ERROR("failed to enable hdmiphy\n"); 1749 DRM_ERROR("failed to enable hdmiphy\n");
1556 return; 1750 return;
1557 } 1751 }
1558 1752
1559 ret = i2c_master_recv(hdata->hdmiphy_port, read_buffer, 32);
1560 if (ret < 0) {
1561 DRM_ERROR("failed to read hdmiphy config\n");
1562 return;
1563 }
1564
1565 for (i = 0; i < ret; i++)
1566 DRM_DEBUG_KMS("hdmiphy[0x%02x] write[0x%02x] - "
1567 "recv [0x%02x]\n", i, buffer[i], read_buffer[i]);
1568} 1753}
1569 1754
1570static void hdmi_conf_apply(struct hdmi_context *hdata) 1755static void hdmi_conf_apply(struct hdmi_context *hdata)
@@ -1573,7 +1758,7 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
1573 hdmiphy_conf_apply(hdata); 1758 hdmiphy_conf_apply(hdata);
1574 1759
1575 mutex_lock(&hdata->hdmi_mutex); 1760 mutex_lock(&hdata->hdmi_mutex);
1576 hdmi_conf_reset(hdata); 1761 hdmi_start(hdata, false);
1577 hdmi_conf_init(hdata); 1762 hdmi_conf_init(hdata);
1578 mutex_unlock(&hdata->hdmi_mutex); 1763 mutex_unlock(&hdata->hdmi_mutex);
1579 1764
@@ -1814,6 +1999,9 @@ static void hdmi_mode_set(struct exynos_drm_display *display,
1814 m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ? 1999 m->vrefresh, (m->flags & DRM_MODE_FLAG_INTERLACE) ?
1815 "INTERLACED" : "PROGERESSIVE"); 2000 "INTERLACED" : "PROGERESSIVE");
1816 2001
2002 /* preserve mode information for later use. */
2003 drm_mode_copy(&hdata->current_mode, mode);
2004
1817 if (hdata->type == HDMI_TYPE13) 2005 if (hdata->type == HDMI_TYPE13)
1818 hdmi_v13_mode_set(hdata, mode); 2006 hdmi_v13_mode_set(hdata, mode);
1819 else 2007 else
@@ -1854,7 +2042,10 @@ static void hdmi_poweron(struct exynos_drm_display *display)
1854 if (regulator_bulk_enable(res->regul_count, res->regul_bulk)) 2042 if (regulator_bulk_enable(res->regul_count, res->regul_bulk))
1855 DRM_DEBUG_KMS("failed to enable regulator bulk\n"); 2043 DRM_DEBUG_KMS("failed to enable regulator bulk\n");
1856 2044
1857 clk_prepare_enable(res->hdmiphy); 2045 /* set pmu hdmiphy control bit to enable hdmiphy */
2046 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2047 PMU_HDMI_PHY_ENABLE_BIT, 1);
2048
1858 clk_prepare_enable(res->hdmi); 2049 clk_prepare_enable(res->hdmi);
1859 clk_prepare_enable(res->sclk_hdmi); 2050 clk_prepare_enable(res->sclk_hdmi);
1860 2051
@@ -1872,16 +2063,20 @@ static void hdmi_poweroff(struct exynos_drm_display *display)
1872 goto out; 2063 goto out;
1873 mutex_unlock(&hdata->hdmi_mutex); 2064 mutex_unlock(&hdata->hdmi_mutex);
1874 2065
1875 /* 2066 /* HDMI System Disable */
1876 * The TV power domain needs any condition of hdmiphy to turn off and 2067 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN);
1877 * its reset state seems to meet the condition. 2068
1878 */
1879 hdmiphy_conf_reset(hdata);
1880 hdmiphy_poweroff(hdata); 2069 hdmiphy_poweroff(hdata);
1881 2070
2071 cancel_delayed_work(&hdata->hotplug_work);
2072
1882 clk_disable_unprepare(res->sclk_hdmi); 2073 clk_disable_unprepare(res->sclk_hdmi);
1883 clk_disable_unprepare(res->hdmi); 2074 clk_disable_unprepare(res->hdmi);
1884 clk_disable_unprepare(res->hdmiphy); 2075
2076 /* reset pmu hdmiphy control bit to disable hdmiphy */
2077 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL,
2078 PMU_HDMI_PHY_ENABLE_BIT, 0);
2079
1885 regulator_bulk_disable(res->regul_count, res->regul_bulk); 2080 regulator_bulk_disable(res->regul_count, res->regul_bulk);
1886 2081
1887 pm_runtime_put_sync(hdata->dev); 2082 pm_runtime_put_sync(hdata->dev);
@@ -1913,7 +2108,6 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
1913} 2108}
1914 2109
1915static struct exynos_drm_display_ops hdmi_display_ops = { 2110static struct exynos_drm_display_ops hdmi_display_ops = {
1916 .initialize = hdmi_initialize,
1917 .create_connector = hdmi_create_connector, 2111 .create_connector = hdmi_create_connector,
1918 .mode_fixup = hdmi_mode_fixup, 2112 .mode_fixup = hdmi_mode_fixup,
1919 .mode_set = hdmi_mode_set, 2113 .mode_set = hdmi_mode_set,
@@ -1926,9 +2120,11 @@ static struct exynos_drm_display hdmi_display = {
1926 .ops = &hdmi_display_ops, 2120 .ops = &hdmi_display_ops,
1927}; 2121};
1928 2122
1929static irqreturn_t hdmi_irq_thread(int irq, void *arg) 2123static void hdmi_hotplug_work_func(struct work_struct *work)
1930{ 2124{
1931 struct hdmi_context *hdata = arg; 2125 struct hdmi_context *hdata;
2126
2127 hdata = container_of(work, struct hdmi_context, hotplug_work.work);
1932 2128
1933 mutex_lock(&hdata->hdmi_mutex); 2129 mutex_lock(&hdata->hdmi_mutex);
1934 hdata->hpd = gpio_get_value(hdata->hpd_gpio); 2130 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
@@ -1936,6 +2132,14 @@ static irqreturn_t hdmi_irq_thread(int irq, void *arg)
1936 2132
1937 if (hdata->drm_dev) 2133 if (hdata->drm_dev)
1938 drm_helper_hpd_irq_event(hdata->drm_dev); 2134 drm_helper_hpd_irq_event(hdata->drm_dev);
2135}
2136
2137static irqreturn_t hdmi_irq_thread(int irq, void *arg)
2138{
2139 struct hdmi_context *hdata = arg;
2140
2141 mod_delayed_work(system_wq, &hdata->hotplug_work,
2142 msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
1939 2143
1940 return IRQ_HANDLED; 2144 return IRQ_HANDLED;
1941} 2145}
@@ -1954,37 +2158,35 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
1954 2158
1955 DRM_DEBUG_KMS("HDMI resource init\n"); 2159 DRM_DEBUG_KMS("HDMI resource init\n");
1956 2160
1957 memset(res, 0, sizeof(*res));
1958
1959 /* get clocks, power */ 2161 /* get clocks, power */
1960 res->hdmi = devm_clk_get(dev, "hdmi"); 2162 res->hdmi = devm_clk_get(dev, "hdmi");
1961 if (IS_ERR(res->hdmi)) { 2163 if (IS_ERR(res->hdmi)) {
1962 DRM_ERROR("failed to get clock 'hdmi'\n"); 2164 DRM_ERROR("failed to get clock 'hdmi'\n");
2165 ret = PTR_ERR(res->hdmi);
1963 goto fail; 2166 goto fail;
1964 } 2167 }
1965 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); 2168 res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1966 if (IS_ERR(res->sclk_hdmi)) { 2169 if (IS_ERR(res->sclk_hdmi)) {
1967 DRM_ERROR("failed to get clock 'sclk_hdmi'\n"); 2170 DRM_ERROR("failed to get clock 'sclk_hdmi'\n");
2171 ret = PTR_ERR(res->sclk_hdmi);
1968 goto fail; 2172 goto fail;
1969 } 2173 }
1970 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel"); 2174 res->sclk_pixel = devm_clk_get(dev, "sclk_pixel");
1971 if (IS_ERR(res->sclk_pixel)) { 2175 if (IS_ERR(res->sclk_pixel)) {
1972 DRM_ERROR("failed to get clock 'sclk_pixel'\n"); 2176 DRM_ERROR("failed to get clock 'sclk_pixel'\n");
2177 ret = PTR_ERR(res->sclk_pixel);
1973 goto fail; 2178 goto fail;
1974 } 2179 }
1975 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy"); 2180 res->sclk_hdmiphy = devm_clk_get(dev, "sclk_hdmiphy");
1976 if (IS_ERR(res->sclk_hdmiphy)) { 2181 if (IS_ERR(res->sclk_hdmiphy)) {
1977 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n"); 2182 DRM_ERROR("failed to get clock 'sclk_hdmiphy'\n");
1978 goto fail; 2183 ret = PTR_ERR(res->sclk_hdmiphy);
1979 }
1980 res->hdmiphy = devm_clk_get(dev, "hdmiphy");
1981 if (IS_ERR(res->hdmiphy)) {
1982 DRM_ERROR("failed to get clock 'hdmiphy'\n");
1983 goto fail; 2184 goto fail;
1984 } 2185 }
1985 res->mout_hdmi = devm_clk_get(dev, "mout_hdmi"); 2186 res->mout_hdmi = devm_clk_get(dev, "mout_hdmi");
1986 if (IS_ERR(res->mout_hdmi)) { 2187 if (IS_ERR(res->mout_hdmi)) {
1987 DRM_ERROR("failed to get clock 'mout_hdmi'\n"); 2188 DRM_ERROR("failed to get clock 'mout_hdmi'\n");
2189 ret = PTR_ERR(res->mout_hdmi);
1988 goto fail; 2190 goto fail;
1989 } 2191 }
1990 2192
@@ -1992,8 +2194,10 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
1992 2194
1993 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) * 2195 res->regul_bulk = devm_kzalloc(dev, ARRAY_SIZE(supply) *
1994 sizeof(res->regul_bulk[0]), GFP_KERNEL); 2196 sizeof(res->regul_bulk[0]), GFP_KERNEL);
1995 if (!res->regul_bulk) 2197 if (!res->regul_bulk) {
2198 ret = -ENOMEM;
1996 goto fail; 2199 goto fail;
2200 }
1997 for (i = 0; i < ARRAY_SIZE(supply); ++i) { 2201 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
1998 res->regul_bulk[i].supply = supply[i]; 2202 res->regul_bulk[i].supply = supply[i];
1999 res->regul_bulk[i].consumer = NULL; 2203 res->regul_bulk[i].consumer = NULL;
@@ -2001,14 +2205,14 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
2001 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk); 2205 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
2002 if (ret) { 2206 if (ret) {
2003 DRM_ERROR("failed to get regulators\n"); 2207 DRM_ERROR("failed to get regulators\n");
2004 goto fail; 2208 return ret;
2005 } 2209 }
2006 res->regul_count = ARRAY_SIZE(supply); 2210 res->regul_count = ARRAY_SIZE(supply);
2007 2211
2008 return 0; 2212 return ret;
2009fail: 2213fail:
2010 DRM_ERROR("HDMI resource init - failed\n"); 2214 DRM_ERROR("HDMI resource init - failed\n");
2011 return -ENODEV; 2215 return ret;
2012} 2216}
2013 2217
2014static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata 2218static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
@@ -2043,42 +2247,105 @@ static struct of_device_id hdmi_match_types[] = {
2043 .compatible = "samsung,exynos4212-hdmi", 2247 .compatible = "samsung,exynos4212-hdmi",
2044 .data = &exynos4212_hdmi_driver_data, 2248 .data = &exynos4212_hdmi_driver_data,
2045 }, { 2249 }, {
2250 .compatible = "samsung,exynos5420-hdmi",
2251 .data = &exynos5420_hdmi_driver_data,
2252 }, {
2046 /* end node */ 2253 /* end node */
2047 } 2254 }
2048}; 2255};
2049 2256
2257static int hdmi_bind(struct device *dev, struct device *master, void *data)
2258{
2259 struct drm_device *drm_dev = data;
2260 struct hdmi_context *hdata;
2261
2262 hdata = hdmi_display.ctx;
2263 hdata->drm_dev = drm_dev;
2264
2265 return exynos_drm_create_enc_conn(drm_dev, &hdmi_display);
2266}
2267
2268static void hdmi_unbind(struct device *dev, struct device *master, void *data)
2269{
2270 struct exynos_drm_display *display = get_hdmi_display(dev);
2271 struct drm_encoder *encoder = display->encoder;
2272 struct hdmi_context *hdata = display->ctx;
2273
2274 encoder->funcs->destroy(encoder);
2275 drm_connector_cleanup(&hdata->connector);
2276}
2277
2278static const struct component_ops hdmi_component_ops = {
2279 .bind = hdmi_bind,
2280 .unbind = hdmi_unbind,
2281};
2282
2283static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
2284{
2285 const char *compatible_str = "samsung,exynos4210-hdmiddc";
2286 struct device_node *np;
2287
2288 np = of_find_compatible_node(NULL, NULL, compatible_str);
2289 if (np)
2290 return of_get_next_parent(np);
2291
2292 return NULL;
2293}
2294
2295static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
2296{
2297 const char *compatible_str = "samsung,exynos4212-hdmiphy";
2298
2299 return of_find_compatible_node(NULL, NULL, compatible_str);
2300}
2301
2050static int hdmi_probe(struct platform_device *pdev) 2302static int hdmi_probe(struct platform_device *pdev)
2051{ 2303{
2304 struct device_node *ddc_node, *phy_node;
2305 struct s5p_hdmi_platform_data *pdata;
2306 struct hdmi_driver_data *drv_data;
2307 const struct of_device_id *match;
2052 struct device *dev = &pdev->dev; 2308 struct device *dev = &pdev->dev;
2053 struct hdmi_context *hdata; 2309 struct hdmi_context *hdata;
2054 struct s5p_hdmi_platform_data *pdata;
2055 struct resource *res; 2310 struct resource *res;
2056 const struct of_device_id *match;
2057 struct device_node *ddc_node, *phy_node;
2058 struct hdmi_driver_data *drv_data;
2059 int ret; 2311 int ret;
2060 2312
2061 if (!dev->of_node) 2313 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
2062 return -ENODEV; 2314 hdmi_display.type);
2315 if (ret)
2316 return ret;
2317
2318 if (!dev->of_node) {
2319 ret = -ENODEV;
2320 goto err_del_component;
2321 }
2063 2322
2064 pdata = drm_hdmi_dt_parse_pdata(dev); 2323 pdata = drm_hdmi_dt_parse_pdata(dev);
2065 if (!pdata) 2324 if (!pdata) {
2066 return -EINVAL; 2325 ret = -EINVAL;
2326 goto err_del_component;
2327 }
2067 2328
2068 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL); 2329 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2069 if (!hdata) 2330 if (!hdata) {
2070 return -ENOMEM; 2331 ret = -ENOMEM;
2332 goto err_del_component;
2333 }
2071 2334
2072 mutex_init(&hdata->hdmi_mutex); 2335 mutex_init(&hdata->hdmi_mutex);
2073 2336
2074 platform_set_drvdata(pdev, &hdmi_display); 2337 platform_set_drvdata(pdev, &hdmi_display);
2075 2338
2076 match = of_match_node(hdmi_match_types, dev->of_node); 2339 match = of_match_node(hdmi_match_types, dev->of_node);
2077 if (!match) 2340 if (!match) {
2078 return -ENODEV; 2341 ret = -ENODEV;
2342 goto err_del_component;
2343 }
2079 2344
2080 drv_data = (struct hdmi_driver_data *)match->data; 2345 drv_data = (struct hdmi_driver_data *)match->data;
2081 hdata->type = drv_data->type; 2346 hdata->type = drv_data->type;
2347 hdata->phy_confs = drv_data->phy_confs;
2348 hdata->phy_conf_count = drv_data->phy_conf_count;
2082 2349
2083 hdata->hpd_gpio = pdata->hpd_gpio; 2350 hdata->hpd_gpio = pdata->hpd_gpio;
2084 hdata->dev = dev; 2351 hdata->dev = dev;
@@ -2086,35 +2353,44 @@ static int hdmi_probe(struct platform_device *pdev)
2086 ret = hdmi_resources_init(hdata); 2353 ret = hdmi_resources_init(hdata);
2087 if (ret) { 2354 if (ret) {
2088 DRM_ERROR("hdmi_resources_init failed\n"); 2355 DRM_ERROR("hdmi_resources_init failed\n");
2089 return -EINVAL; 2356 return ret;
2090 } 2357 }
2091 2358
2092 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2359 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2093 hdata->regs = devm_ioremap_resource(dev, res); 2360 hdata->regs = devm_ioremap_resource(dev, res);
2094 if (IS_ERR(hdata->regs)) 2361 if (IS_ERR(hdata->regs)) {
2095 return PTR_ERR(hdata->regs); 2362 ret = PTR_ERR(hdata->regs);
2363 goto err_del_component;
2364 }
2096 2365
2097 ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD"); 2366 ret = devm_gpio_request(dev, hdata->hpd_gpio, "HPD");
2098 if (ret) { 2367 if (ret) {
2099 DRM_ERROR("failed to request HPD gpio\n"); 2368 DRM_ERROR("failed to request HPD gpio\n");
2100 return ret; 2369 goto err_del_component;
2101 } 2370 }
2102 2371
2372 ddc_node = hdmi_legacy_ddc_dt_binding(dev);
2373 if (ddc_node)
2374 goto out_get_ddc_adpt;
2375
2103 /* DDC i2c driver */ 2376 /* DDC i2c driver */
2104 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); 2377 ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
2105 if (!ddc_node) { 2378 if (!ddc_node) {
2106 DRM_ERROR("Failed to find ddc node in device tree\n"); 2379 DRM_ERROR("Failed to find ddc node in device tree\n");
2107 return -ENODEV; 2380 ret = -ENODEV;
2381 goto err_del_component;
2108 } 2382 }
2383
2384out_get_ddc_adpt:
2109 hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node); 2385 hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
2110 if (!hdata->ddc_adpt) { 2386 if (!hdata->ddc_adpt) {
2111 DRM_ERROR("Failed to get ddc i2c adapter by node\n"); 2387 DRM_ERROR("Failed to get ddc i2c adapter by node\n");
2112 return -ENODEV; 2388 return -EPROBE_DEFER;
2113 } 2389 }
2114 2390
2115 /* Not support APB PHY yet. */ 2391 phy_node = hdmi_legacy_phy_dt_binding(dev);
2116 if (drv_data->is_apb_phy) 2392 if (phy_node)
2117 return -EPERM; 2393 goto out_get_phy_port;
2118 2394
2119 /* hdmiphy i2c driver */ 2395 /* hdmiphy i2c driver */
2120 phy_node = of_parse_phandle(dev->of_node, "phy", 0); 2396 phy_node = of_parse_phandle(dev->of_node, "phy", 0);
@@ -2123,11 +2399,22 @@ static int hdmi_probe(struct platform_device *pdev)
2123 ret = -ENODEV; 2399 ret = -ENODEV;
2124 goto err_ddc; 2400 goto err_ddc;
2125 } 2401 }
2126 hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node); 2402
2127 if (!hdata->hdmiphy_port) { 2403out_get_phy_port:
2128 DRM_ERROR("Failed to get hdmi phy i2c client from node\n"); 2404 if (drv_data->is_apb_phy) {
2129 ret = -ENODEV; 2405 hdata->regs_hdmiphy = of_iomap(phy_node, 0);
2130 goto err_ddc; 2406 if (!hdata->regs_hdmiphy) {
2407 DRM_ERROR("failed to ioremap hdmi phy\n");
2408 ret = -ENOMEM;
2409 goto err_ddc;
2410 }
2411 } else {
2412 hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
2413 if (!hdata->hdmiphy_port) {
2414 DRM_ERROR("Failed to get hdmi phy i2c client\n");
2415 ret = -EPROBE_DEFER;
2416 goto err_ddc;
2417 }
2131 } 2418 }
2132 2419
2133 hdata->irq = gpio_to_irq(hdata->hpd_gpio); 2420 hdata->irq = gpio_to_irq(hdata->hpd_gpio);
@@ -2139,6 +2426,8 @@ static int hdmi_probe(struct platform_device *pdev)
2139 2426
2140 hdata->hpd = gpio_get_value(hdata->hpd_gpio); 2427 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2141 2428
2429 INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
2430
2142 ret = devm_request_threaded_irq(dev, hdata->irq, NULL, 2431 ret = devm_request_threaded_irq(dev, hdata->irq, NULL,
2143 hdmi_irq_thread, IRQF_TRIGGER_RISING | 2432 hdmi_irq_thread, IRQF_TRIGGER_RISING |
2144 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 2433 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
@@ -2148,30 +2437,51 @@ static int hdmi_probe(struct platform_device *pdev)
2148 goto err_hdmiphy; 2437 goto err_hdmiphy;
2149 } 2438 }
2150 2439
2151 pm_runtime_enable(dev); 2440 hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
2441 "samsung,syscon-phandle");
2442 if (IS_ERR(hdata->pmureg)) {
2443 DRM_ERROR("syscon regmap lookup failed.\n");
2444 ret = -EPROBE_DEFER;
2445 goto err_hdmiphy;
2446 }
2152 2447
2448 pm_runtime_enable(dev);
2153 hdmi_display.ctx = hdata; 2449 hdmi_display.ctx = hdata;
2154 exynos_drm_display_register(&hdmi_display);
2155 2450
2156 return 0; 2451 ret = component_add(&pdev->dev, &hdmi_component_ops);
2452 if (ret)
2453 goto err_disable_pm_runtime;
2454
2455 return ret;
2456
2457err_disable_pm_runtime:
2458 pm_runtime_disable(dev);
2157 2459
2158err_hdmiphy: 2460err_hdmiphy:
2159 put_device(&hdata->hdmiphy_port->dev); 2461 if (hdata->hdmiphy_port)
2462 put_device(&hdata->hdmiphy_port->dev);
2160err_ddc: 2463err_ddc:
2161 put_device(&hdata->ddc_adpt->dev); 2464 put_device(&hdata->ddc_adpt->dev);
2465
2466err_del_component:
2467 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2468
2162 return ret; 2469 return ret;
2163} 2470}
2164 2471
2165static int hdmi_remove(struct platform_device *pdev) 2472static int hdmi_remove(struct platform_device *pdev)
2166{ 2473{
2167 struct device *dev = &pdev->dev; 2474 struct hdmi_context *hdata = hdmi_display.ctx;
2168 struct exynos_drm_display *display = get_hdmi_display(dev); 2475
2169 struct hdmi_context *hdata = display->ctx; 2476 cancel_delayed_work_sync(&hdata->hotplug_work);
2170 2477
2171 put_device(&hdata->hdmiphy_port->dev); 2478 put_device(&hdata->hdmiphy_port->dev);
2172 put_device(&hdata->ddc_adpt->dev); 2479 put_device(&hdata->ddc_adpt->dev);
2480
2173 pm_runtime_disable(&pdev->dev); 2481 pm_runtime_disable(&pdev->dev);
2482 component_del(&pdev->dev, &hdmi_component_ops);
2174 2483
2484 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
2175 return 0; 2485 return 0;
2176} 2486}
2177 2487
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.h b/drivers/gpu/drm/exynos/exynos_hdmi.h
deleted file mode 100644
index 0ddf3957de15..000000000000
--- a/drivers/gpu/drm/exynos/exynos_hdmi.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * Authors:
5 * Inki Dae <inki.dae@samsung.com>
6 * Seung-Woo Kim <sw0312.kim@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef _EXYNOS_HDMI_H_
15#define _EXYNOS_HDMI_H_
16
17void hdmi_attach_ddc_client(struct i2c_client *ddc);
18void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy);
19
20extern struct i2c_driver hdmiphy_driver;
21extern struct i2c_driver ddc_driver;
22
23#endif
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
deleted file mode 100644
index 59abb1494ceb..000000000000
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ /dev/null
@@ -1,65 +0,0 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Authors:
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <drm/drmP.h>
15
16#include <linux/kernel.h>
17#include <linux/i2c.h>
18#include <linux/of.h>
19
20#include "exynos_drm_drv.h"
21#include "exynos_hdmi.h"
22
23
24static int hdmiphy_probe(struct i2c_client *client,
25 const struct i2c_device_id *id)
26{
27 hdmi_attach_hdmiphy_client(client);
28
29 dev_info(&client->adapter->dev, "attached s5p_hdmiphy "
30 "into i2c adapter successfully\n");
31
32 return 0;
33}
34
35static int hdmiphy_remove(struct i2c_client *client)
36{
37 dev_info(&client->adapter->dev, "detached s5p_hdmiphy "
38 "from i2c adapter successfully\n");
39
40 return 0;
41}
42
43static struct of_device_id hdmiphy_match_types[] = {
44 {
45 .compatible = "samsung,exynos5-hdmiphy",
46 }, {
47 .compatible = "samsung,exynos4210-hdmiphy",
48 }, {
49 .compatible = "samsung,exynos4212-hdmiphy",
50 }, {
51 /* end node */
52 }
53};
54
55struct i2c_driver hdmiphy_driver = {
56 .driver = {
57 .name = "exynos-hdmiphy",
58 .owner = THIS_MODULE,
59 .of_match_table = hdmiphy_match_types,
60 },
61 .probe = hdmiphy_probe,
62 .remove = hdmiphy_remove,
63 .command = NULL,
64};
65EXPORT_SYMBOL(hdmiphy_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index ce288818d2c0..4c5aed7e54c8 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/component.h>
34 35
35#include <drm/exynos_drm.h> 36#include <drm/exynos_drm.h>
36 37
@@ -830,13 +831,15 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
830} 831}
831 832
832static int mixer_initialize(struct exynos_drm_manager *mgr, 833static int mixer_initialize(struct exynos_drm_manager *mgr,
833 struct drm_device *drm_dev, int pipe) 834 struct drm_device *drm_dev)
834{ 835{
835 int ret; 836 int ret;
836 struct mixer_context *mixer_ctx = mgr->ctx; 837 struct mixer_context *mixer_ctx = mgr->ctx;
838 struct exynos_drm_private *priv;
839 priv = drm_dev->dev_private;
837 840
838 mixer_ctx->drm_dev = drm_dev; 841 mgr->drm_dev = mixer_ctx->drm_dev = drm_dev;
839 mixer_ctx->pipe = pipe; 842 mgr->pipe = mixer_ctx->pipe = priv->pipe++;
840 843
841 /* acquire resources: regs, irqs, clocks */ 844 /* acquire resources: regs, irqs, clocks */
842 ret = mixer_resources_init(mixer_ctx); 845 ret = mixer_resources_init(mixer_ctx);
@@ -1142,8 +1145,6 @@ int mixer_check_mode(struct drm_display_mode *mode)
1142} 1145}
1143 1146
1144static struct exynos_drm_manager_ops mixer_manager_ops = { 1147static struct exynos_drm_manager_ops mixer_manager_ops = {
1145 .initialize = mixer_initialize,
1146 .remove = mixer_mgr_remove,
1147 .dpms = mixer_dpms, 1148 .dpms = mixer_dpms,
1148 .enable_vblank = mixer_enable_vblank, 1149 .enable_vblank = mixer_enable_vblank,
1149 .disable_vblank = mixer_disable_vblank, 1150 .disable_vblank = mixer_disable_vblank,
@@ -1200,11 +1201,13 @@ static struct of_device_id mixer_match_types[] = {
1200 } 1201 }
1201}; 1202};
1202 1203
1203static int mixer_probe(struct platform_device *pdev) 1204static int mixer_bind(struct device *dev, struct device *manager, void *data)
1204{ 1205{
1205 struct device *dev = &pdev->dev; 1206 struct platform_device *pdev = to_platform_device(dev);
1207 struct drm_device *drm_dev = data;
1206 struct mixer_context *ctx; 1208 struct mixer_context *ctx;
1207 struct mixer_drv_data *drv; 1209 struct mixer_drv_data *drv;
1210 int ret;
1208 1211
1209 dev_info(dev, "probe start\n"); 1212 dev_info(dev, "probe start\n");
1210 1213
@@ -1233,19 +1236,61 @@ static int mixer_probe(struct platform_device *pdev)
1233 atomic_set(&ctx->wait_vsync_event, 0); 1236 atomic_set(&ctx->wait_vsync_event, 0);
1234 1237
1235 mixer_manager.ctx = ctx; 1238 mixer_manager.ctx = ctx;
1239 ret = mixer_initialize(&mixer_manager, drm_dev);
1240 if (ret)
1241 return ret;
1242
1236 platform_set_drvdata(pdev, &mixer_manager); 1243 platform_set_drvdata(pdev, &mixer_manager);
1237 exynos_drm_manager_register(&mixer_manager); 1244 ret = exynos_drm_crtc_create(&mixer_manager);
1245 if (ret) {
1246 mixer_mgr_remove(&mixer_manager);
1247 return ret;
1248 }
1238 1249
1239 pm_runtime_enable(dev); 1250 pm_runtime_enable(dev);
1240 1251
1241 return 0; 1252 return 0;
1242} 1253}
1243 1254
1244static int mixer_remove(struct platform_device *pdev) 1255static void mixer_unbind(struct device *dev, struct device *master, void *data)
1256{
1257 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1258 struct drm_crtc *crtc = mgr->crtc;
1259
1260 dev_info(dev, "remove successful\n");
1261
1262 mixer_mgr_remove(mgr);
1263
1264 pm_runtime_disable(dev);
1265
1266 crtc->funcs->destroy(crtc);
1267}
1268
1269static const struct component_ops mixer_component_ops = {
1270 .bind = mixer_bind,
1271 .unbind = mixer_unbind,
1272};
1273
1274static int mixer_probe(struct platform_device *pdev)
1245{ 1275{
1246 dev_info(&pdev->dev, "remove successful\n"); 1276 int ret;
1247 1277
1248 pm_runtime_disable(&pdev->dev); 1278 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1279 mixer_manager.type);
1280 if (ret)
1281 return ret;
1282
1283 ret = component_add(&pdev->dev, &mixer_component_ops);
1284 if (ret)
1285 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1286
1287 return ret;
1288}
1289
1290static int mixer_remove(struct platform_device *pdev)
1291{
1292 component_del(&pdev->dev, &mixer_component_ops);
1293 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1249 1294
1250 return 0; 1295 return 0;
1251} 1296}
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
index ef1b3eb3ba6e..3f35ac6d8a47 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -578,4 +578,20 @@
578#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074) 578#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074)
579#define HDMI_TG_3D HDMI_TG_BASE(0x00F0) 579#define HDMI_TG_3D HDMI_TG_BASE(0x00F0)
580 580
581/* HDMI PHY Registers Offsets*/
582#define HDMIPHY_POWER (0x74 >> 2)
583#define HDMIPHY_MODE_SET_DONE (0x7c >> 2)
584
585/* HDMI PHY Values */
586#define HDMI_PHY_POWER_ON 0x80
587#define HDMI_PHY_POWER_OFF 0xff
588
589/* HDMI PHY Values */
590#define HDMI_PHY_DISABLE_MODE_SET 0x80
591#define HDMI_PHY_ENABLE_MODE_SET 0x00
592
593/* PMU Registers for PHY */
594#define PMU_HDMI_PHY_CONTROL 0x700
595#define PMU_HDMI_PHY_ENABLE_BIT BIT(0)
596
581#endif /* SAMSUNG_REGS_HDMI_H */ 597#endif /* SAMSUNG_REGS_HDMI_H */
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index efcde2c38cc1..488b41635dec 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -310,6 +310,8 @@
310# define DP_TEST_NAK (1 << 1) 310# define DP_TEST_NAK (1 << 1)
311# define DP_TEST_EDID_CHECKSUM_WRITE (1 << 2) 311# define DP_TEST_EDID_CHECKSUM_WRITE (1 << 2)
312 312
313#define DP_TEST_EDID_CHECKSUM 0x261
314
313#define DP_TEST_SINK 0x270 315#define DP_TEST_SINK 0x270
314#define DP_TEST_SINK_START (1 << 0) 316#define DP_TEST_SINK_START (1 << 0)
315 317