aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-10-07 07:06:33 -0400
committerDave Airlie <airlied@redhat.com>2012-10-07 07:06:33 -0400
commita5a0fc67435599d9d787a8d7153967a70fed968e (patch)
treefd0015e62bd9b66af78e98e0c0a084596bfcaec4 /drivers
parent0dbe23218333bad3e75148f090fe670d8ca41ad6 (diff)
parent768c3059d87876ce124dafc40078718dc85cec65 (diff)
Merge branch 'exynos-drm-next' of git://git.infradead.org/users/kmpark/linux-samsung into drm-next
Inki writes: "this patch set updates exynos drm framework and includes minor fixups. and this pull request except hdmi device tree support patch set posted by Rahul Sharma because that includes media side patch so for this patch set, we may have git pull one more time in addition, if we get an agreement with media guys. for this patch, you can refer to below link, http://comments.gmane.org/gmane.comp.video.dri.devel/74504 this pull request adds hdmi device tree support and includes related patch set such as disabling of hdmi internal interrupt, suppport for platform variants for hdmi and mixer, support to disable video processor based on platform type and removal of drm common platform data. as you know, this patch set was delayed because it included an media side patch. so for this, we got an ack from v4l2-based hdmi driver author, Tomasz Stanislawski." * 'exynos-drm-next' of git://git.infradead.org/users/kmpark/linux-samsung: (34 commits) drm: exynos: hdmi: remove drm common hdmi platform data struct drm: exynos: hdmi: add support for exynos5 hdmi drm: exynos: hdmi: replace is_v13 with version check in hdmi drm: exynos: hdmi: add support for exynos5 mixer drm: exynos: hdmi: add support to disable video processor in mixer drm: exynos: hdmi: add support for platform variants for mixer drm: exynos: hdmi: add support for exynos5 hdmiphy drm: exynos: hdmi: add support for exynos5 ddc drm: exynos: remove drm hdmi platform data struct drm: exynos: hdmi: turn off HPD interrupt in HDMI chip drm: exynos: hdmi: use s5p-hdmi platform data drm: exynos: hdmi: fix interrupt handling drm: exynos: hdmi: support for platform variants media: s5p-hdmi: add HPD GPIO to platform data drm/exynos: fix kcalloc size of g2d cmdlist node drm/exynos: fix to calculate CRTC shown via screen drm/exynos: fix display power call issue. drm/exynos: add platform_device_id table and driver data for drm fimd drm/exynos: Fix potential NULL pointer dereference drm/exynos: support drm_wait_vblank feature for VIDI ... Conflicts: include/drm/exynos_drm.h
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/exynos/exynos_ddc.c22
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.c50
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c100
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h19
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c116
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c65
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.h20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c117
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_g2d.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c62
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c58
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c24
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c196
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmiphy.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c240
-rw-r--r--drivers/gpu/drm/exynos/regs-mixer.h3
20 files changed, 896 insertions, 243 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
index 961a1806a246..37e6ec704e1d 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -26,29 +26,41 @@ static int s5p_ddc_probe(struct i2c_client *client,
26{ 26{
27 hdmi_attach_ddc_client(client); 27 hdmi_attach_ddc_client(client);
28 28
29 dev_info(&client->adapter->dev, "attached s5p_ddc " 29 dev_info(&client->adapter->dev,
30 "into i2c adapter successfully\n"); 30 "attached %s into i2c adapter successfully\n",
31 client->name);
31 32
32 return 0; 33 return 0;
33} 34}
34 35
35static int s5p_ddc_remove(struct i2c_client *client) 36static int s5p_ddc_remove(struct i2c_client *client)
36{ 37{
37 dev_info(&client->adapter->dev, "detached s5p_ddc " 38 dev_info(&client->adapter->dev,
38 "from i2c adapter successfully\n"); 39 "detached %s from i2c adapter successfully\n",
40 client->name);
39 41
40 return 0; 42 return 0;
41} 43}
42 44
43static struct i2c_device_id ddc_idtable[] = { 45static struct i2c_device_id ddc_idtable[] = {
44 {"s5p_ddc", 0}, 46 {"s5p_ddc", 0},
47 {"exynos5-hdmiddc", 0},
45 { }, 48 { },
46}; 49};
47 50
51static struct of_device_id hdmiddc_match_types[] = {
52 {
53 .compatible = "samsung,exynos5-hdmiddc",
54 }, {
55 /* end node */
56 }
57};
58
48struct i2c_driver ddc_driver = { 59struct i2c_driver ddc_driver = {
49 .driver = { 60 .driver = {
50 .name = "s5p_ddc", 61 .name = "exynos-hdmiddc",
51 .owner = THIS_MODULE, 62 .owner = THIS_MODULE,
63 .of_match_table = hdmiddc_match_types,
52 }, 64 },
53 .id_table = ddc_idtable, 65 .id_table = ddc_idtable,
54 .probe = s5p_ddc_probe, 66 .probe = s5p_ddc_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index c2b1b1441ed0..18c271862ca8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -40,6 +40,7 @@ struct exynos_drm_connector {
40 struct drm_connector drm_connector; 40 struct drm_connector drm_connector;
41 uint32_t encoder_id; 41 uint32_t encoder_id;
42 struct exynos_drm_manager *manager; 42 struct exynos_drm_manager *manager;
43 uint32_t dpms;
43}; 44};
44 45
45/* convert exynos_video_timings to drm_display_mode */ 46/* convert exynos_video_timings to drm_display_mode */
@@ -149,8 +150,12 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
149 count = drm_add_edid_modes(connector, edid); 150 count = drm_add_edid_modes(connector, edid);
150 kfree(edid); 151 kfree(edid);
151 } else { 152 } else {
152 struct drm_display_mode *mode = drm_mode_create(connector->dev);
153 struct exynos_drm_panel_info *panel; 153 struct exynos_drm_panel_info *panel;
154 struct drm_display_mode *mode = drm_mode_create(connector->dev);
155 if (!mode) {
156 DRM_ERROR("failed to create a new display mode.\n");
157 return 0;
158 }
154 159
155 if (display_ops->get_panel) 160 if (display_ops->get_panel)
156 panel = display_ops->get_panel(manager->dev); 161 panel = display_ops->get_panel(manager->dev);
@@ -194,8 +199,7 @@ static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
194 return ret; 199 return ret;
195} 200}
196 201
197static struct drm_encoder *exynos_drm_best_encoder( 202struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
198 struct drm_connector *connector)
199{ 203{
200 struct drm_device *dev = connector->dev; 204 struct drm_device *dev = connector->dev;
201 struct exynos_drm_connector *exynos_connector = 205 struct exynos_drm_connector *exynos_connector =
@@ -224,6 +228,43 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
224 .best_encoder = exynos_drm_best_encoder, 228 .best_encoder = exynos_drm_best_encoder,
225}; 229};
226 230
231void exynos_drm_display_power(struct drm_connector *connector, int mode)
232{
233 struct drm_encoder *encoder = exynos_drm_best_encoder(connector);
234 struct exynos_drm_connector *exynos_connector;
235 struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
236 struct exynos_drm_display_ops *display_ops = manager->display_ops;
237
238 exynos_connector = to_exynos_connector(connector);
239
240 if (exynos_connector->dpms == mode) {
241 DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
242 return;
243 }
244
245 if (display_ops && display_ops->power_on)
246 display_ops->power_on(manager->dev, mode);
247
248 exynos_connector->dpms = mode;
249}
250
251static void exynos_drm_connector_dpms(struct drm_connector *connector,
252 int mode)
253{
254 DRM_DEBUG_KMS("%s\n", __FILE__);
255
256 /*
257 * in case that drm_crtc_helper_set_mode() is called,
258 * encoder/crtc->funcs->dpms() will be just returned
259 * because they already were DRM_MODE_DPMS_ON so only
260 * exynos_drm_display_power() will be called.
261 */
262 drm_helper_connector_dpms(connector, mode);
263
264 exynos_drm_display_power(connector, mode);
265
266}
267
227static int exynos_drm_connector_fill_modes(struct drm_connector *connector, 268static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
228 unsigned int max_width, unsigned int max_height) 269 unsigned int max_width, unsigned int max_height)
229{ 270{
@@ -283,7 +324,7 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
283} 324}
284 325
285static struct drm_connector_funcs exynos_connector_funcs = { 326static struct drm_connector_funcs exynos_connector_funcs = {
286 .dpms = drm_helper_connector_dpms, 327 .dpms = exynos_drm_connector_dpms,
287 .fill_modes = exynos_drm_connector_fill_modes, 328 .fill_modes = exynos_drm_connector_fill_modes,
288 .detect = exynos_drm_connector_detect, 329 .detect = exynos_drm_connector_detect,
289 .destroy = exynos_drm_connector_destroy, 330 .destroy = exynos_drm_connector_destroy,
@@ -332,6 +373,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
332 373
333 exynos_connector->encoder_id = encoder->base.id; 374 exynos_connector->encoder_id = encoder->base.id;
334 exynos_connector->manager = manager; 375 exynos_connector->manager = manager;
376 exynos_connector->dpms = DRM_MODE_DPMS_OFF;
335 connector->encoder = encoder; 377 connector->encoder = encoder;
336 378
337 err = drm_mode_connector_attach_encoder(connector, encoder); 379 err = drm_mode_connector_attach_encoder(connector, encoder);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.h b/drivers/gpu/drm/exynos/exynos_drm_connector.h
index 1c7b2b5b579c..22f6cc442c3d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.h
@@ -31,4 +31,8 @@
31struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, 31struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
32 struct drm_encoder *encoder); 32 struct drm_encoder *encoder);
33 33
34struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector);
35
36void exynos_drm_display_power(struct drm_connector *connector, int mode);
37
34#endif 38#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 19bdf0a194eb..94026ad76a77 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -34,33 +34,15 @@
34 34
35static LIST_HEAD(exynos_drm_subdrv_list); 35static LIST_HEAD(exynos_drm_subdrv_list);
36 36
37static int exynos_drm_subdrv_probe(struct drm_device *dev, 37static int exynos_drm_create_enc_conn(struct drm_device *dev,
38 struct exynos_drm_subdrv *subdrv) 38 struct exynos_drm_subdrv *subdrv)
39{ 39{
40 struct drm_encoder *encoder; 40 struct drm_encoder *encoder;
41 struct drm_connector *connector; 41 struct drm_connector *connector;
42 int ret;
42 43
43 DRM_DEBUG_DRIVER("%s\n", __FILE__); 44 DRM_DEBUG_DRIVER("%s\n", __FILE__);
44 45
45 if (subdrv->probe) {
46 int ret;
47
48 /*
49 * this probe callback would be called by sub driver
50 * after setting of all resources to this sub driver,
51 * such as clock, irq and register map are done or by load()
52 * of exynos drm driver.
53 *
54 * P.S. note that this driver is considered for modularization.
55 */
56 ret = subdrv->probe(dev, subdrv->dev);
57 if (ret)
58 return ret;
59 }
60
61 if (!subdrv->manager)
62 return 0;
63
64 subdrv->manager->dev = subdrv->dev; 46 subdrv->manager->dev = subdrv->dev;
65 47
66 /* create and initialize a encoder for this sub driver. */ 48 /* create and initialize a encoder for this sub driver. */
@@ -78,24 +60,22 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
78 connector = exynos_drm_connector_create(dev, encoder); 60 connector = exynos_drm_connector_create(dev, encoder);
79 if (!connector) { 61 if (!connector) {
80 DRM_ERROR("failed to create connector\n"); 62 DRM_ERROR("failed to create connector\n");
81 encoder->funcs->destroy(encoder); 63 ret = -EFAULT;
82 return -EFAULT; 64 goto err_destroy_encoder;
83 } 65 }
84 66
85 subdrv->encoder = encoder; 67 subdrv->encoder = encoder;
86 subdrv->connector = connector; 68 subdrv->connector = connector;
87 69
88 return 0; 70 return 0;
71
72err_destroy_encoder:
73 encoder->funcs->destroy(encoder);
74 return ret;
89} 75}
90 76
91static void exynos_drm_subdrv_remove(struct drm_device *dev, 77static void exynos_drm_destroy_enc_conn(struct exynos_drm_subdrv *subdrv)
92 struct exynos_drm_subdrv *subdrv)
93{ 78{
94 DRM_DEBUG_DRIVER("%s\n", __FILE__);
95
96 if (subdrv->remove)
97 subdrv->remove(dev);
98
99 if (subdrv->encoder) { 79 if (subdrv->encoder) {
100 struct drm_encoder *encoder = subdrv->encoder; 80 struct drm_encoder *encoder = subdrv->encoder;
101 encoder->funcs->destroy(encoder); 81 encoder->funcs->destroy(encoder);
@@ -109,9 +89,43 @@ static void exynos_drm_subdrv_remove(struct drm_device *dev,
109 } 89 }
110} 90}
111 91
92static int exynos_drm_subdrv_probe(struct drm_device *dev,
93 struct exynos_drm_subdrv *subdrv)
94{
95 if (subdrv->probe) {
96 int ret;
97
98 subdrv->drm_dev = dev;
99
100 /*
101 * this probe callback would be called by sub driver
102 * after setting of all resources to this sub driver,
103 * such as clock, irq and register map are done or by load()
104 * of exynos drm driver.
105 *
106 * P.S. note that this driver is considered for modularization.
107 */
108 ret = subdrv->probe(dev, subdrv->dev);
109 if (ret)
110 return ret;
111 }
112
113 return 0;
114}
115
116static void exynos_drm_subdrv_remove(struct drm_device *dev,
117 struct exynos_drm_subdrv *subdrv)
118{
119 DRM_DEBUG_DRIVER("%s\n", __FILE__);
120
121 if (subdrv->remove)
122 subdrv->remove(dev, subdrv->dev);
123}
124
112int exynos_drm_device_register(struct drm_device *dev) 125int exynos_drm_device_register(struct drm_device *dev)
113{ 126{
114 struct exynos_drm_subdrv *subdrv, *n; 127 struct exynos_drm_subdrv *subdrv, *n;
128 unsigned int fine_cnt = 0;
115 int err; 129 int err;
116 130
117 DRM_DEBUG_DRIVER("%s\n", __FILE__); 131 DRM_DEBUG_DRIVER("%s\n", __FILE__);
@@ -120,14 +134,36 @@ int exynos_drm_device_register(struct drm_device *dev)
120 return -EINVAL; 134 return -EINVAL;
121 135
122 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { 136 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
123 subdrv->drm_dev = dev;
124 err = exynos_drm_subdrv_probe(dev, subdrv); 137 err = exynos_drm_subdrv_probe(dev, subdrv);
125 if (err) { 138 if (err) {
126 DRM_DEBUG("exynos drm subdrv probe failed.\n"); 139 DRM_DEBUG("exynos drm subdrv probe failed.\n");
127 list_del(&subdrv->list); 140 list_del(&subdrv->list);
141 continue;
142 }
143
144 /*
145 * if manager is null then it means that this sub driver
146 * doesn't need encoder and connector.
147 */
148 if (!subdrv->manager) {
149 fine_cnt++;
150 continue;
151 }
152
153 err = exynos_drm_create_enc_conn(dev, subdrv);
154 if (err) {
155 DRM_DEBUG("failed to create encoder and connector.\n");
156 exynos_drm_subdrv_remove(dev, subdrv);
157 list_del(&subdrv->list);
158 continue;
128 } 159 }
160
161 fine_cnt++;
129 } 162 }
130 163
164 if (!fine_cnt)
165 return -EINVAL;
166
131 return 0; 167 return 0;
132} 168}
133EXPORT_SYMBOL_GPL(exynos_drm_device_register); 169EXPORT_SYMBOL_GPL(exynos_drm_device_register);
@@ -143,8 +179,10 @@ int exynos_drm_device_unregister(struct drm_device *dev)
143 return -EINVAL; 179 return -EINVAL;
144 } 180 }
145 181
146 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) 182 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
147 exynos_drm_subdrv_remove(dev, subdrv); 183 exynos_drm_subdrv_remove(dev, subdrv);
184 exynos_drm_destroy_enc_conn(subdrv);
185 }
148 186
149 return 0; 187 return 0;
150} 188}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index df1e34f0f091..fce245f64c4f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -66,7 +66,6 @@ struct exynos_drm_crtc {
66 66
67static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) 67static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
68{ 68{
69 struct drm_device *dev = crtc->dev;
70 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 69 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
71 70
72 DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); 71 DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
@@ -76,12 +75,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
76 return; 75 return;
77 } 76 }
78 77
79 mutex_lock(&dev->struct_mutex);
80
81 exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms); 78 exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
82 exynos_crtc->dpms = mode; 79 exynos_crtc->dpms = mode;
83
84 mutex_unlock(&dev->struct_mutex);
85} 80}
86 81
87static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) 82static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
@@ -97,6 +92,7 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
97 92
98 DRM_DEBUG_KMS("%s\n", __FILE__); 93 DRM_DEBUG_KMS("%s\n", __FILE__);
99 94
95 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
100 exynos_plane_commit(exynos_crtc->plane); 96 exynos_plane_commit(exynos_crtc->plane);
101 exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON); 97 exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
102} 98}
@@ -126,8 +122,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
126 122
127 DRM_DEBUG_KMS("%s\n", __FILE__); 123 DRM_DEBUG_KMS("%s\n", __FILE__);
128 124
129 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
130
131 /* 125 /*
132 * copy the mode data adjusted by mode_fixup() into crtc->mode 126 * copy the mode data adjusted by mode_fixup() into crtc->mode
133 * so that hardware can be seet to proper mode. 127 * so that hardware can be seet to proper mode.
@@ -161,6 +155,12 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
161 155
162 DRM_DEBUG_KMS("%s\n", __FILE__); 156 DRM_DEBUG_KMS("%s\n", __FILE__);
163 157
158 /* when framebuffer changing is requested, crtc's dpms should be on */
159 if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
160 DRM_ERROR("failed framebuffer changing request.\n");
161 return -EPERM;
162 }
163
164 crtc_w = crtc->fb->width - x; 164 crtc_w = crtc->fb->width - x;
165 crtc_h = crtc->fb->height - y; 165 crtc_h = crtc->fb->height - y;
166 166
@@ -213,6 +213,12 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
213 213
214 DRM_DEBUG_KMS("%s\n", __FILE__); 214 DRM_DEBUG_KMS("%s\n", __FILE__);
215 215
216 /* when the page flip is requested, crtc's dpms should be on */
217 if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
218 DRM_ERROR("failed page flip request.\n");
219 return -EINVAL;
220 }
221
216 mutex_lock(&dev->struct_mutex); 222 mutex_lock(&dev->struct_mutex);
217 223
218 if (event) { 224 if (event) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a4ab98b52dd8..a34231036496 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -36,6 +36,20 @@
36#define MAX_FB_BUFFER 4 36#define MAX_FB_BUFFER 4
37#define DEFAULT_ZPOS -1 37#define DEFAULT_ZPOS -1
38 38
39#define _wait_for(COND, MS) ({ \
40 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
41 int ret__ = 0; \
42 while (!(COND)) { \
43 if (time_after(jiffies, timeout__)) { \
44 ret__ = -ETIMEDOUT; \
45 break; \
46 } \
47 } \
48 ret__; \
49})
50
51#define wait_for(COND, MS) _wait_for(COND, MS)
52
39struct drm_device; 53struct drm_device;
40struct exynos_drm_overlay; 54struct exynos_drm_overlay;
41struct drm_connector; 55struct drm_connector;
@@ -60,6 +74,8 @@ enum exynos_drm_output_type {
60 * @commit: apply hardware specific overlay data to registers. 74 * @commit: apply hardware specific overlay data to registers.
61 * @enable: enable hardware specific overlay. 75 * @enable: enable hardware specific overlay.
62 * @disable: disable hardware specific overlay. 76 * @disable: disable hardware specific overlay.
77 * @wait_for_vblank: wait for vblank interrupt to make sure that
78 * hardware overlay is disabled.
63 */ 79 */
64struct exynos_drm_overlay_ops { 80struct exynos_drm_overlay_ops {
65 void (*mode_set)(struct device *subdrv_dev, 81 void (*mode_set)(struct device *subdrv_dev,
@@ -67,6 +83,7 @@ struct exynos_drm_overlay_ops {
67 void (*commit)(struct device *subdrv_dev, int zpos); 83 void (*commit)(struct device *subdrv_dev, int zpos);
68 void (*enable)(struct device *subdrv_dev, int zpos); 84 void (*enable)(struct device *subdrv_dev, int zpos);
69 void (*disable)(struct device *subdrv_dev, int zpos); 85 void (*disable)(struct device *subdrv_dev, int zpos);
86 void (*wait_for_vblank)(struct device *subdrv_dev);
70}; 87};
71 88
72/* 89/*
@@ -265,7 +282,7 @@ struct exynos_drm_subdrv {
265 struct exynos_drm_manager *manager; 282 struct exynos_drm_manager *manager;
266 283
267 int (*probe)(struct drm_device *drm_dev, struct device *dev); 284 int (*probe)(struct drm_device *drm_dev, struct device *dev);
268 void (*remove)(struct drm_device *dev); 285 void (*remove)(struct drm_device *drm_dev, struct device *dev);
269 int (*open)(struct drm_device *drm_dev, struct device *dev, 286 int (*open)(struct drm_device *drm_dev, struct device *dev,
270 struct drm_file *file); 287 struct drm_file *file);
271 void (*close)(struct drm_device *drm_dev, struct device *dev, 288 void (*close)(struct drm_device *drm_dev, struct device *dev,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 39bd8abff3f1..e51503fbaf2b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -31,6 +31,7 @@
31 31
32#include "exynos_drm_drv.h" 32#include "exynos_drm_drv.h"
33#include "exynos_drm_encoder.h" 33#include "exynos_drm_encoder.h"
34#include "exynos_drm_connector.h"
34 35
35#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\ 36#define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\
36 drm_encoder) 37 drm_encoder)
@@ -44,26 +45,23 @@
44 * @dpms: store the encoder dpms value. 45 * @dpms: store the encoder dpms value.
45 */ 46 */
46struct exynos_drm_encoder { 47struct exynos_drm_encoder {
48 struct drm_crtc *old_crtc;
47 struct drm_encoder drm_encoder; 49 struct drm_encoder drm_encoder;
48 struct exynos_drm_manager *manager; 50 struct exynos_drm_manager *manager;
49 int dpms; 51 int dpms;
50}; 52};
51 53
52static void exynos_drm_display_power(struct drm_encoder *encoder, int mode) 54static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
53{ 55{
54 struct drm_device *dev = encoder->dev; 56 struct drm_device *dev = encoder->dev;
55 struct drm_connector *connector; 57 struct drm_connector *connector;
56 struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
57 58
58 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 59 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
59 if (connector->encoder == encoder) { 60 if (exynos_drm_best_encoder(connector) == encoder) {
60 struct exynos_drm_display_ops *display_ops =
61 manager->display_ops;
62
63 DRM_DEBUG_KMS("connector[%d] dpms[%d]\n", 61 DRM_DEBUG_KMS("connector[%d] dpms[%d]\n",
64 connector->base.id, mode); 62 connector->base.id, mode);
65 if (display_ops && display_ops->power_on) 63
66 display_ops->power_on(manager->dev, mode); 64 exynos_drm_display_power(connector, mode);
67 } 65 }
68 } 66 }
69} 67}
@@ -88,13 +86,13 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
88 case DRM_MODE_DPMS_ON: 86 case DRM_MODE_DPMS_ON:
89 if (manager_ops && manager_ops->apply) 87 if (manager_ops && manager_ops->apply)
90 manager_ops->apply(manager->dev); 88 manager_ops->apply(manager->dev);
91 exynos_drm_display_power(encoder, mode); 89 exynos_drm_connector_power(encoder, mode);
92 exynos_encoder->dpms = mode; 90 exynos_encoder->dpms = mode;
93 break; 91 break;
94 case DRM_MODE_DPMS_STANDBY: 92 case DRM_MODE_DPMS_STANDBY:
95 case DRM_MODE_DPMS_SUSPEND: 93 case DRM_MODE_DPMS_SUSPEND:
96 case DRM_MODE_DPMS_OFF: 94 case DRM_MODE_DPMS_OFF:
97 exynos_drm_display_power(encoder, mode); 95 exynos_drm_connector_power(encoder, mode);
98 exynos_encoder->dpms = mode; 96 exynos_encoder->dpms = mode;
99 break; 97 break;
100 default: 98 default:
@@ -127,24 +125,74 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
127 return true; 125 return true;
128} 126}
129 127
128static void disable_plane_to_crtc(struct drm_device *dev,
129 struct drm_crtc *old_crtc,
130 struct drm_crtc *new_crtc)
131{
132 struct drm_plane *plane;
133
134 /*
135 * if old_crtc isn't same as encoder->crtc then it means that
136 * user changed crtc id to another one so the plane to old_crtc
137 * should be disabled and plane->crtc should be set to new_crtc
138 * (encoder->crtc)
139 */
140 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
141 if (plane->crtc == old_crtc) {
142 /*
143 * do not change below call order.
144 *
145 * plane->funcs->disable_plane call checks
146 * if encoder->crtc is same as plane->crtc and if same
147 * then overlay_ops->disable callback will be called
148 * to diasble current hw overlay so plane->crtc should
149 * have new_crtc because new_crtc was set to
150 * encoder->crtc in advance.
151 */
152 plane->crtc = new_crtc;
153 plane->funcs->disable_plane(plane);
154 }
155 }
156}
157
130static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder, 158static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
131 struct drm_display_mode *mode, 159 struct drm_display_mode *mode,
132 struct drm_display_mode *adjusted_mode) 160 struct drm_display_mode *adjusted_mode)
133{ 161{
134 struct drm_device *dev = encoder->dev; 162 struct drm_device *dev = encoder->dev;
135 struct drm_connector *connector; 163 struct drm_connector *connector;
136 struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); 164 struct exynos_drm_manager *manager;
137 struct exynos_drm_manager_ops *manager_ops = manager->ops; 165 struct exynos_drm_manager_ops *manager_ops;
138 166
139 DRM_DEBUG_KMS("%s\n", __FILE__); 167 DRM_DEBUG_KMS("%s\n", __FILE__);
140 168
141 exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
142
143 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 169 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
144 if (connector->encoder == encoder) 170 if (connector->encoder == encoder) {
171 struct exynos_drm_encoder *exynos_encoder;
172
173 exynos_encoder = to_exynos_encoder(encoder);
174
175 if (exynos_encoder->old_crtc != encoder->crtc &&
176 exynos_encoder->old_crtc) {
177
178 /*
179 * disable a plane to old crtc and change
180 * crtc of the plane to new one.
181 */
182 disable_plane_to_crtc(dev,
183 exynos_encoder->old_crtc,
184 encoder->crtc);
185 }
186
187 manager = exynos_drm_get_manager(encoder);
188 manager_ops = manager->ops;
189
145 if (manager_ops && manager_ops->mode_set) 190 if (manager_ops && manager_ops->mode_set)
146 manager_ops->mode_set(manager->dev, 191 manager_ops->mode_set(manager->dev,
147 adjusted_mode); 192 adjusted_mode);
193
194 exynos_encoder->old_crtc = encoder->crtc;
195 }
148 } 196 }
149} 197}
150 198
@@ -166,12 +214,27 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
166 manager_ops->commit(manager->dev); 214 manager_ops->commit(manager->dev);
167} 215}
168 216
217static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
218{
219 struct drm_plane *plane;
220 struct drm_device *dev = encoder->dev;
221
222 exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
223
224 /* all planes connected to this encoder should be also disabled. */
225 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
226 if (plane->crtc == encoder->crtc)
227 plane->funcs->disable_plane(plane);
228 }
229}
230
169static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { 231static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
170 .dpms = exynos_drm_encoder_dpms, 232 .dpms = exynos_drm_encoder_dpms,
171 .mode_fixup = exynos_drm_encoder_mode_fixup, 233 .mode_fixup = exynos_drm_encoder_mode_fixup,
172 .mode_set = exynos_drm_encoder_mode_set, 234 .mode_set = exynos_drm_encoder_mode_set,
173 .prepare = exynos_drm_encoder_prepare, 235 .prepare = exynos_drm_encoder_prepare,
174 .commit = exynos_drm_encoder_commit, 236 .commit = exynos_drm_encoder_commit,
237 .disable = exynos_drm_encoder_disable,
175}; 238};
176 239
177static void exynos_drm_encoder_destroy(struct drm_encoder *encoder) 240static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
@@ -338,6 +401,19 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
338 manager_ops->dpms(manager->dev, mode); 401 manager_ops->dpms(manager->dev, mode);
339 402
340 /* 403 /*
404 * set current mode to new one so that data aren't updated into
405 * registers by drm_helper_connector_dpms two times.
406 *
407 * in case that drm_crtc_helper_set_mode() is called,
408 * overlay_ops->commit() and manager_ops->commit() callbacks
409 * can be called two times, first at drm_crtc_helper_set_mode()
410 * and second at drm_helper_connector_dpms().
411 * so with this setting, when drm_helper_connector_dpms() is called
412 * encoder->funcs->dpms() will be ignored.
413 */
414 exynos_encoder->dpms = mode;
415
416 /*
341 * if this condition is ok then it means that the crtc is already 417 * if this condition is ok then it means that the crtc is already
342 * detached from encoder and last function for detaching is properly 418 * detached from encoder and last function for detaching is properly
343 * done, so clear pipe from manager to prevent repeated call. 419 * done, so clear pipe from manager to prevent repeated call.
@@ -422,4 +498,14 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
422 498
423 if (overlay_ops && overlay_ops->disable) 499 if (overlay_ops && overlay_ops->disable)
424 overlay_ops->disable(manager->dev, zpos); 500 overlay_ops->disable(manager->dev, zpos);
501
502 /*
503 * wait for vblank interrupt
504 * - this makes sure that hardware overlay is disabled to avoid
505 * for the dma accesses to memory after gem buffer was released
506 * because the setting for disabling the overlay will be updated
507 * at vsync.
508 */
509 if (overlay_ops->wait_for_vblank)
510 overlay_ops->wait_for_vblank(manager->dev);
425} 511}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 53afcc5f0945..4ef4cd3f9936 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -41,10 +41,12 @@
41 * exynos specific framebuffer structure. 41 * exynos specific framebuffer structure.
42 * 42 *
43 * @fb: drm framebuffer obejct. 43 * @fb: drm framebuffer obejct.
44 * @buf_cnt: a buffer count to drm framebuffer.
44 * @exynos_gem_obj: array of exynos specific gem object containing a gem object. 45 * @exynos_gem_obj: array of exynos specific gem object containing a gem object.
45 */ 46 */
46struct exynos_drm_fb { 47struct exynos_drm_fb {
47 struct drm_framebuffer fb; 48 struct drm_framebuffer fb;
49 unsigned int buf_cnt;
48 struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; 50 struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER];
49}; 51};
50 52
@@ -101,6 +103,25 @@ static struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
101 .dirty = exynos_drm_fb_dirty, 103 .dirty = exynos_drm_fb_dirty,
102}; 104};
103 105
106void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
107 unsigned int cnt)
108{
109 struct exynos_drm_fb *exynos_fb;
110
111 exynos_fb = to_exynos_fb(fb);
112
113 exynos_fb->buf_cnt = cnt;
114}
115
116unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb)
117{
118 struct exynos_drm_fb *exynos_fb;
119
120 exynos_fb = to_exynos_fb(fb);
121
122 return exynos_fb->buf_cnt;
123}
124
104struct drm_framebuffer * 125struct drm_framebuffer *
105exynos_drm_framebuffer_init(struct drm_device *dev, 126exynos_drm_framebuffer_init(struct drm_device *dev,
106 struct drm_mode_fb_cmd2 *mode_cmd, 127 struct drm_mode_fb_cmd2 *mode_cmd,
@@ -127,6 +148,43 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
127 return &exynos_fb->fb; 148 return &exynos_fb->fb;
128} 149}
129 150
151static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd)
152{
153 unsigned int cnt = 0;
154
155 if (mode_cmd->pixel_format != DRM_FORMAT_NV12)
156 return drm_format_num_planes(mode_cmd->pixel_format);
157
158 while (cnt != MAX_FB_BUFFER) {
159 if (!mode_cmd->handles[cnt])
160 break;
161 cnt++;
162 }
163
164 /*
165 * check if NV12 or NV12M.
166 *
167 * NV12
168 * handles[0] = base1, offsets[0] = 0
169 * handles[1] = base1, offsets[1] = Y_size
170 *
171 * NV12M
172 * handles[0] = base1, offsets[0] = 0
173 * handles[1] = base2, offsets[1] = 0
174 */
175 if (cnt == 2) {
176 /*
177 * in case of NV12 format, offsets[1] is not 0 and
178 * handles[0] is same as handles[1].
179 */
180 if (mode_cmd->offsets[1] &&
181 mode_cmd->handles[0] == mode_cmd->handles[1])
182 cnt = 1;
183 }
184
185 return cnt;
186}
187
130static struct drm_framebuffer * 188static struct drm_framebuffer *
131exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, 189exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
132 struct drm_mode_fb_cmd2 *mode_cmd) 190 struct drm_mode_fb_cmd2 *mode_cmd)
@@ -134,7 +192,6 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
134 struct drm_gem_object *obj; 192 struct drm_gem_object *obj;
135 struct drm_framebuffer *fb; 193 struct drm_framebuffer *fb;
136 struct exynos_drm_fb *exynos_fb; 194 struct exynos_drm_fb *exynos_fb;
137 int nr;
138 int i; 195 int i;
139 196
140 DRM_DEBUG_KMS("%s\n", __FILE__); 197 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -152,9 +209,11 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
152 } 209 }
153 210
154 exynos_fb = to_exynos_fb(fb); 211 exynos_fb = to_exynos_fb(fb);
155 nr = exynos_drm_format_num_buffers(fb->pixel_format); 212 exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd);
213
214 DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
156 215
157 for (i = 1; i < nr; i++) { 216 for (i = 1; i < exynos_fb->buf_cnt; i++) {
158 obj = drm_gem_object_lookup(dev, file_priv, 217 obj = drm_gem_object_lookup(dev, file_priv,
159 mode_cmd->handles[i]); 218 mode_cmd->handles[i]);
160 if (!obj) { 219 if (!obj) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 50823756cdea..96262e54f76d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -28,19 +28,6 @@
28#ifndef _EXYNOS_DRM_FB_H_ 28#ifndef _EXYNOS_DRM_FB_H_
29#define _EXYNOS_DRM_FB_H 29#define _EXYNOS_DRM_FB_H
30 30
31static inline int exynos_drm_format_num_buffers(uint32_t format)
32{
33 switch (format) {
34 case DRM_FORMAT_NV12:
35 case DRM_FORMAT_NV12MT:
36 return 2;
37 case DRM_FORMAT_YUV420:
38 return 3;
39 default:
40 return 1;
41 }
42}
43
44struct drm_framebuffer * 31struct drm_framebuffer *
45exynos_drm_framebuffer_init(struct drm_device *dev, 32exynos_drm_framebuffer_init(struct drm_device *dev,
46 struct drm_mode_fb_cmd2 *mode_cmd, 33 struct drm_mode_fb_cmd2 *mode_cmd,
@@ -52,4 +39,11 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,
52 39
53void exynos_drm_mode_config_init(struct drm_device *dev); 40void exynos_drm_mode_config_init(struct drm_device *dev);
54 41
42/* set a buffer count to drm framebuffer. */
43void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
44 unsigned int cnt);
45
46/* get a buffer count to drm framebuffer. */
47unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb);
48
55#endif 49#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index bd4ff6348239..67eb6ba56edf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -79,6 +79,9 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
79 return -EFAULT; 79 return -EFAULT;
80 } 80 }
81 81
82 /* buffer count to framebuffer always is 1 at booting time. */
83 exynos_drm_fb_set_buf_cnt(fb, 1);
84
82 offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3); 85 offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
83 offset += fbi->var.yoffset * fb->pitches[0]; 86 offset += fbi->var.yoffset * fb->pitches[0];
84 87
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 58d50e368a58..a32837951dd2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -57,6 +57,18 @@
57 57
58#define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev)) 58#define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev))
59 59
60struct fimd_driver_data {
61 unsigned int timing_base;
62};
63
64struct fimd_driver_data exynos4_fimd_driver_data = {
65 .timing_base = 0x0,
66};
67
68struct fimd_driver_data exynos5_fimd_driver_data = {
69 .timing_base = 0x20000,
70};
71
60struct fimd_win_data { 72struct fimd_win_data {
61 unsigned int offset_x; 73 unsigned int offset_x;
62 unsigned int offset_y; 74 unsigned int offset_y;
@@ -91,6 +103,13 @@ struct fimd_context {
91 struct exynos_drm_panel_info *panel; 103 struct exynos_drm_panel_info *panel;
92}; 104};
93 105
106static inline struct fimd_driver_data *drm_fimd_get_driver_data(
107 struct platform_device *pdev)
108{
109 return (struct fimd_driver_data *)
110 platform_get_device_id(pdev)->driver_data;
111}
112
94static bool fimd_display_is_connected(struct device *dev) 113static bool fimd_display_is_connected(struct device *dev)
95{ 114{
96 DRM_DEBUG_KMS("%s\n", __FILE__); 115 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -194,32 +213,35 @@ static void fimd_commit(struct device *dev)
194 struct fimd_context *ctx = get_fimd_context(dev); 213 struct fimd_context *ctx = get_fimd_context(dev);
195 struct exynos_drm_panel_info *panel = ctx->panel; 214 struct exynos_drm_panel_info *panel = ctx->panel;
196 struct fb_videomode *timing = &panel->timing; 215 struct fb_videomode *timing = &panel->timing;
216 struct fimd_driver_data *driver_data;
217 struct platform_device *pdev = to_platform_device(dev);
197 u32 val; 218 u32 val;
198 219
220 driver_data = drm_fimd_get_driver_data(pdev);
199 if (ctx->suspended) 221 if (ctx->suspended)
200 return; 222 return;
201 223
202 DRM_DEBUG_KMS("%s\n", __FILE__); 224 DRM_DEBUG_KMS("%s\n", __FILE__);
203 225
204 /* setup polarity values from machine code. */ 226 /* setup polarity values from machine code. */
205 writel(ctx->vidcon1, ctx->regs + VIDCON1); 227 writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
206 228
207 /* setup vertical timing values. */ 229 /* setup vertical timing values. */
208 val = VIDTCON0_VBPD(timing->upper_margin - 1) | 230 val = VIDTCON0_VBPD(timing->upper_margin - 1) |
209 VIDTCON0_VFPD(timing->lower_margin - 1) | 231 VIDTCON0_VFPD(timing->lower_margin - 1) |
210 VIDTCON0_VSPW(timing->vsync_len - 1); 232 VIDTCON0_VSPW(timing->vsync_len - 1);
211 writel(val, ctx->regs + VIDTCON0); 233 writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
212 234
213 /* setup horizontal timing values. */ 235 /* setup horizontal timing values. */
214 val = VIDTCON1_HBPD(timing->left_margin - 1) | 236 val = VIDTCON1_HBPD(timing->left_margin - 1) |
215 VIDTCON1_HFPD(timing->right_margin - 1) | 237 VIDTCON1_HFPD(timing->right_margin - 1) |
216 VIDTCON1_HSPW(timing->hsync_len - 1); 238 VIDTCON1_HSPW(timing->hsync_len - 1);
217 writel(val, ctx->regs + VIDTCON1); 239 writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
218 240
219 /* setup horizontal and vertical display size. */ 241 /* setup horizontal and vertical display size. */
220 val = VIDTCON2_LINEVAL(timing->yres - 1) | 242 val = VIDTCON2_LINEVAL(timing->yres - 1) |
221 VIDTCON2_HOZVAL(timing->xres - 1); 243 VIDTCON2_HOZVAL(timing->xres - 1);
222 writel(val, ctx->regs + VIDTCON2); 244 writel(val, ctx->regs + driver_data->timing_base + VIDTCON2);
223 245
224 /* setup clock source, clock divider, enable dma. */ 246 /* setup clock source, clock divider, enable dma. */
225 val = ctx->vidcon0; 247 val = ctx->vidcon0;
@@ -570,10 +592,22 @@ static void fimd_win_disable(struct device *dev, int zpos)
570 win_data->enabled = false; 592 win_data->enabled = false;
571} 593}
572 594
595static void fimd_wait_for_vblank(struct device *dev)
596{
597 struct fimd_context *ctx = get_fimd_context(dev);
598 int ret;
599
600 ret = wait_for((__raw_readl(ctx->regs + VIDCON1) &
601 VIDCON1_VSTATUS_VSYNC), 50);
602 if (ret < 0)
603 DRM_DEBUG_KMS("vblank wait timed out.\n");
604}
605
573static struct exynos_drm_overlay_ops fimd_overlay_ops = { 606static struct exynos_drm_overlay_ops fimd_overlay_ops = {
574 .mode_set = fimd_win_mode_set, 607 .mode_set = fimd_win_mode_set,
575 .commit = fimd_win_commit, 608 .commit = fimd_win_commit,
576 .disable = fimd_win_disable, 609 .disable = fimd_win_disable,
610 .wait_for_vblank = fimd_wait_for_vblank,
577}; 611};
578 612
579static struct exynos_drm_manager fimd_manager = { 613static struct exynos_drm_manager fimd_manager = {
@@ -678,7 +712,7 @@ static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
678 return 0; 712 return 0;
679} 713}
680 714
681static void fimd_subdrv_remove(struct drm_device *drm_dev) 715static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
682{ 716{
683 DRM_DEBUG_KMS("%s\n", __FILE__); 717 DRM_DEBUG_KMS("%s\n", __FILE__);
684 718
@@ -747,16 +781,10 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
747 writel(val, ctx->regs + SHADOWCON); 781 writel(val, ctx->regs + SHADOWCON);
748} 782}
749 783
750static int fimd_power_on(struct fimd_context *ctx, bool enable) 784static int fimd_clock(struct fimd_context *ctx, bool enable)
751{ 785{
752 struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
753 struct device *dev = subdrv->dev;
754
755 DRM_DEBUG_KMS("%s\n", __FILE__); 786 DRM_DEBUG_KMS("%s\n", __FILE__);
756 787
757 if (enable != false && enable != true)
758 return -EINVAL;
759
760 if (enable) { 788 if (enable) {
761 int ret; 789 int ret;
762 790
@@ -769,18 +797,31 @@ static int fimd_power_on(struct fimd_context *ctx, bool enable)
769 clk_disable(ctx->bus_clk); 797 clk_disable(ctx->bus_clk);
770 return ret; 798 return ret;
771 } 799 }
800 } else {
801 clk_disable(ctx->lcd_clk);
802 clk_disable(ctx->bus_clk);
803 }
804
805 return 0;
806}
807
808static int fimd_activate(struct fimd_context *ctx, bool enable)
809{
810 if (enable) {
811 int ret;
812 struct device *dev = ctx->subdrv.dev;
813
814 ret = fimd_clock(ctx, true);
815 if (ret < 0)
816 return ret;
772 817
773 ctx->suspended = false; 818 ctx->suspended = false;
774 819
775 /* if vblank was enabled status, enable it again. */ 820 /* if vblank was enabled status, enable it again. */
776 if (test_and_clear_bit(0, &ctx->irq_flags)) 821 if (test_and_clear_bit(0, &ctx->irq_flags))
777 fimd_enable_vblank(dev); 822 fimd_enable_vblank(dev);
778
779 fimd_apply(dev);
780 } else { 823 } else {
781 clk_disable(ctx->lcd_clk); 824 fimd_clock(ctx, false);
782 clk_disable(ctx->bus_clk);
783
784 ctx->suspended = true; 825 ctx->suspended = true;
785 } 826 }
786 827
@@ -930,15 +971,15 @@ static int fimd_suspend(struct device *dev)
930{ 971{
931 struct fimd_context *ctx = get_fimd_context(dev); 972 struct fimd_context *ctx = get_fimd_context(dev);
932 973
933 if (pm_runtime_suspended(dev))
934 return 0;
935
936 /* 974 /*
937 * do not use pm_runtime_suspend(). if pm_runtime_suspend() is 975 * do not use pm_runtime_suspend(). if pm_runtime_suspend() is
938 * called here, an error would be returned by that interface 976 * called here, an error would be returned by that interface
939 * because the usage_count of pm runtime is more than 1. 977 * because the usage_count of pm runtime is more than 1.
940 */ 978 */
941 return fimd_power_on(ctx, false); 979 if (!pm_runtime_suspended(dev))
980 return fimd_activate(ctx, false);
981
982 return 0;
942} 983}
943 984
944static int fimd_resume(struct device *dev) 985static int fimd_resume(struct device *dev)
@@ -950,8 +991,21 @@ static int fimd_resume(struct device *dev)
950 * of pm runtime would still be 1 so in this case, fimd driver 991 * of pm runtime would still be 1 so in this case, fimd driver
951 * should be on directly not drawing on pm runtime interface. 992 * should be on directly not drawing on pm runtime interface.
952 */ 993 */
953 if (!pm_runtime_suspended(dev)) 994 if (pm_runtime_suspended(dev)) {
954 return fimd_power_on(ctx, true); 995 int ret;
996
997 ret = fimd_activate(ctx, true);
998 if (ret < 0)
999 return ret;
1000
1001 /*
1002 * in case of dpms on(standby), fimd_apply function will
1003 * be called by encoder's dpms callback to update fimd's
1004 * registers but in case of sleep wakeup, it's not.
1005 * so fimd_apply function should be called at here.
1006 */
1007 fimd_apply(dev);
1008 }
955 1009
956 return 0; 1010 return 0;
957} 1011}
@@ -964,7 +1018,7 @@ static int fimd_runtime_suspend(struct device *dev)
964 1018
965 DRM_DEBUG_KMS("%s\n", __FILE__); 1019 DRM_DEBUG_KMS("%s\n", __FILE__);
966 1020
967 return fimd_power_on(ctx, false); 1021 return fimd_activate(ctx, false);
968} 1022}
969 1023
970static int fimd_runtime_resume(struct device *dev) 1024static int fimd_runtime_resume(struct device *dev)
@@ -973,10 +1027,22 @@ static int fimd_runtime_resume(struct device *dev)
973 1027
974 DRM_DEBUG_KMS("%s\n", __FILE__); 1028 DRM_DEBUG_KMS("%s\n", __FILE__);
975 1029
976 return fimd_power_on(ctx, true); 1030 return fimd_activate(ctx, true);
977} 1031}
978#endif 1032#endif
979 1033
1034static struct platform_device_id fimd_driver_ids[] = {
1035 {
1036 .name = "exynos4-fb",
1037 .driver_data = (unsigned long)&exynos4_fimd_driver_data,
1038 }, {
1039 .name = "exynos5-fb",
1040 .driver_data = (unsigned long)&exynos5_fimd_driver_data,
1041 },
1042 {},
1043};
1044MODULE_DEVICE_TABLE(platform, fimd_driver_ids);
1045
980static const struct dev_pm_ops fimd_pm_ops = { 1046static const struct dev_pm_ops fimd_pm_ops = {
981 SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) 1047 SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume)
982 SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) 1048 SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL)
@@ -985,6 +1051,7 @@ static const struct dev_pm_ops fimd_pm_ops = {
985struct platform_driver fimd_driver = { 1051struct platform_driver fimd_driver = {
986 .probe = fimd_probe, 1052 .probe = fimd_probe,
987 .remove = __devexit_p(fimd_remove), 1053 .remove = __devexit_p(fimd_remove),
1054 .id_table = fimd_driver_ids,
988 .driver = { 1055 .driver = {
989 .name = "exynos4-fb", 1056 .name = "exynos4-fb",
990 .owner = THIS_MODULE, 1057 .owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index bc2a2e9be8eb..f7aab24ea46c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -122,6 +122,7 @@ struct g2d_runqueue_node {
122 struct list_head list; 122 struct list_head list;
123 struct list_head run_cmdlist; 123 struct list_head run_cmdlist;
124 struct list_head event_list; 124 struct list_head event_list;
125 pid_t pid;
125 struct completion complete; 126 struct completion complete;
126 int async; 127 int async;
127}; 128};
@@ -164,8 +165,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
164 return -ENOMEM; 165 return -ENOMEM;
165 } 166 }
166 167
167 node = kcalloc(G2D_CMDLIST_NUM, G2D_CMDLIST_NUM * sizeof(*node), 168 node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL);
168 GFP_KERNEL);
169 if (!node) { 169 if (!node) {
170 dev_err(dev, "failed to allocate memory\n"); 170 dev_err(dev, "failed to allocate memory\n");
171 ret = -ENOMEM; 171 ret = -ENOMEM;
@@ -679,6 +679,7 @@ int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
679 } 679 }
680 680
681 mutex_lock(&g2d->runqueue_mutex); 681 mutex_lock(&g2d->runqueue_mutex);
682 runqueue_node->pid = current->pid;
682 list_add_tail(&runqueue_node->list, &g2d->runqueue); 683 list_add_tail(&runqueue_node->list, &g2d->runqueue);
683 if (!g2d->runqueue_node) 684 if (!g2d->runqueue_node)
684 g2d_exec_runqueue(g2d); 685 g2d_exec_runqueue(g2d);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index c3d3a5e4f109..c3b9e2b45185 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -29,6 +29,11 @@
29#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\ 29#define get_ctx_from_subdrv(subdrv) container_of(subdrv,\
30 struct drm_hdmi_context, subdrv); 30 struct drm_hdmi_context, subdrv);
31 31
32/* Common hdmi subdrv needs to access the hdmi and mixer though context.
33* These should be initialied by the repective drivers */
34static struct exynos_drm_hdmi_context *hdmi_ctx;
35static struct exynos_drm_hdmi_context *mixer_ctx;
36
32/* these callback points shoud be set by specific drivers. */ 37/* these callback points shoud be set by specific drivers. */
33static struct exynos_hdmi_ops *hdmi_ops; 38static struct exynos_hdmi_ops *hdmi_ops;
34static struct exynos_mixer_ops *mixer_ops; 39static struct exynos_mixer_ops *mixer_ops;
@@ -41,6 +46,18 @@ struct drm_hdmi_context {
41 bool enabled[MIXER_WIN_NR]; 46 bool enabled[MIXER_WIN_NR];
42}; 47};
43 48
49void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx)
50{
51 if (ctx)
52 hdmi_ctx = ctx;
53}
54
55void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx)
56{
57 if (ctx)
58 mixer_ctx = ctx;
59}
60
44void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) 61void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
45{ 62{
46 DRM_DEBUG_KMS("%s\n", __FILE__); 63 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -274,10 +291,21 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
274 ctx->enabled[win] = false; 291 ctx->enabled[win] = false;
275} 292}
276 293
294static void drm_mixer_wait_for_vblank(struct device *subdrv_dev)
295{
296 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
297
298 DRM_DEBUG_KMS("%s\n", __FILE__);
299
300 if (mixer_ops && mixer_ops->wait_for_vblank)
301 mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
302}
303
277static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { 304static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
278 .mode_set = drm_mixer_mode_set, 305 .mode_set = drm_mixer_mode_set,
279 .commit = drm_mixer_commit, 306 .commit = drm_mixer_commit,
280 .disable = drm_mixer_disable, 307 .disable = drm_mixer_disable,
308 .wait_for_vblank = drm_mixer_wait_for_vblank,
281}; 309};
282 310
283static struct exynos_drm_manager hdmi_manager = { 311static struct exynos_drm_manager hdmi_manager = {
@@ -292,46 +320,30 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
292{ 320{
293 struct exynos_drm_subdrv *subdrv = to_subdrv(dev); 321 struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
294 struct drm_hdmi_context *ctx; 322 struct drm_hdmi_context *ctx;
295 struct platform_device *pdev = to_platform_device(dev);
296 struct exynos_drm_common_hdmi_pd *pd;
297 323
298 DRM_DEBUG_KMS("%s\n", __FILE__); 324 DRM_DEBUG_KMS("%s\n", __FILE__);
299 325
300 pd = pdev->dev.platform_data; 326 if (!hdmi_ctx) {
301 327 DRM_ERROR("hdmi context not initialized.\n");
302 if (!pd) {
303 DRM_DEBUG_KMS("platform data is null.\n");
304 return -EFAULT;
305 }
306
307 if (!pd->hdmi_dev) {
308 DRM_DEBUG_KMS("hdmi device is null.\n");
309 return -EFAULT; 328 return -EFAULT;
310 } 329 }
311 330
312 if (!pd->mixer_dev) { 331 if (!mixer_ctx) {
313 DRM_DEBUG_KMS("mixer device is null.\n"); 332 DRM_ERROR("mixer context not initialized.\n");
314 return -EFAULT; 333 return -EFAULT;
315 } 334 }
316 335
317 ctx = get_ctx_from_subdrv(subdrv); 336 ctx = get_ctx_from_subdrv(subdrv);
318 337
319 ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *) 338 if (!ctx) {
320 to_context(pd->hdmi_dev); 339 DRM_ERROR("no drm hdmi context.\n");
321 if (!ctx->hdmi_ctx) {
322 DRM_DEBUG_KMS("hdmi context is null.\n");
323 return -EFAULT; 340 return -EFAULT;
324 } 341 }
325 342
326 ctx->hdmi_ctx->drm_dev = drm_dev; 343 ctx->hdmi_ctx = hdmi_ctx;
327 344 ctx->mixer_ctx = mixer_ctx;
328 ctx->mixer_ctx = (struct exynos_drm_hdmi_context *)
329 to_context(pd->mixer_dev);
330 if (!ctx->mixer_ctx) {
331 DRM_DEBUG_KMS("mixer context is null.\n");
332 return -EFAULT;
333 }
334 345
346 ctx->hdmi_ctx->drm_dev = drm_dev;
335 ctx->mixer_ctx->drm_dev = drm_dev; 347 ctx->mixer_ctx->drm_dev = drm_dev;
336 348
337 return 0; 349 return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index a91c42088e42..2da5ffd3a059 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -67,11 +67,14 @@ struct exynos_mixer_ops {
67 void (*dpms)(void *ctx, int mode); 67 void (*dpms)(void *ctx, int mode);
68 68
69 /* overlay */ 69 /* overlay */
70 void (*wait_for_vblank)(void *ctx);
70 void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); 71 void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
71 void (*win_commit)(void *ctx, int zpos); 72 void (*win_commit)(void *ctx, int zpos);
72 void (*win_disable)(void *ctx, int zpos); 73 void (*win_disable)(void *ctx, int zpos);
73}; 74};
74 75
76void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
77void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
75void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); 78void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
76void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); 79void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
77#endif 80#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 03b472b43013..60b877a388c2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -32,6 +32,42 @@ static const uint32_t formats[] = {
32 DRM_FORMAT_NV12MT, 32 DRM_FORMAT_NV12MT,
33}; 33};
34 34
35/*
36 * This function is to get X or Y size shown via screen. This needs length and
37 * start position of CRTC.
38 *
39 * <--- length --->
40 * CRTC ----------------
41 * ^ start ^ end
42 *
43 * There are six cases from a to b.
44 *
45 * <----- SCREEN ----->
46 * 0 last
47 * ----------|------------------|----------
48 * CRTCs
49 * a -------
50 * b -------
51 * c --------------------------
52 * d --------
53 * e -------
54 * f -------
55 */
56static int exynos_plane_get_size(int start, unsigned length, unsigned last)
57{
58 int end = start + length;
59 int size = 0;
60
61 if (start <= 0) {
62 if (end > 0)
63 size = min_t(unsigned, end, last);
64 } else if (start <= last) {
65 size = min_t(unsigned, last - start, length);
66 }
67
68 return size;
69}
70
35int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, 71int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
36 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 72 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
37 unsigned int crtc_w, unsigned int crtc_h, 73 unsigned int crtc_w, unsigned int crtc_h,
@@ -47,7 +83,7 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
47 83
48 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 84 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
49 85
50 nr = exynos_drm_format_num_buffers(fb->pixel_format); 86 nr = exynos_drm_fb_get_buf_cnt(fb);
51 for (i = 0; i < nr; i++) { 87 for (i = 0; i < nr; i++) {
52 struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i); 88 struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
53 89
@@ -64,8 +100,24 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
64 (unsigned long)overlay->dma_addr[i]); 100 (unsigned long)overlay->dma_addr[i]);
65 } 101 }
66 102
67 actual_w = min((unsigned)(crtc->mode.hdisplay - crtc_x), crtc_w); 103 actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
68 actual_h = min((unsigned)(crtc->mode.vdisplay - crtc_y), crtc_h); 104 actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
105
106 if (crtc_x < 0) {
107 if (actual_w)
108 src_x -= crtc_x;
109 else
110 src_x += crtc_w;
111 crtc_x = 0;
112 }
113
114 if (crtc_y < 0) {
115 if (actual_h)
116 src_y -= crtc_y;
117 else
118 src_y += crtc_h;
119 crtc_y = 0;
120 }
69 121
70 /* set drm framebuffer data. */ 122 /* set drm framebuffer data. */
71 overlay->fb_x = src_x; 123 overlay->fb_x = src_x;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 8fe431ae537b..e4b8a8f741f7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -56,6 +56,7 @@ struct vidi_context {
56 unsigned int connected; 56 unsigned int connected;
57 bool vblank_on; 57 bool vblank_on;
58 bool suspended; 58 bool suspended;
59 bool direct_vblank;
59 struct work_struct work; 60 struct work_struct work;
60 struct mutex lock; 61 struct mutex lock;
61}; 62};
@@ -224,6 +225,15 @@ static int vidi_enable_vblank(struct device *dev)
224 if (!test_and_set_bit(0, &ctx->irq_flags)) 225 if (!test_and_set_bit(0, &ctx->irq_flags))
225 ctx->vblank_on = true; 226 ctx->vblank_on = true;
226 227
228 ctx->direct_vblank = true;
229
230 /*
231 * in case of page flip request, vidi_finish_pageflip function
232 * will not be called because direct_vblank is true and then
233 * that function will be called by overlay_ops->commit callback
234 */
235 schedule_work(&ctx->work);
236
227 return 0; 237 return 0;
228} 238}
229 239
@@ -425,7 +435,17 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
425 /* refresh rate is about 50Hz. */ 435 /* refresh rate is about 50Hz. */
426 usleep_range(16000, 20000); 436 usleep_range(16000, 20000);
427 437
428 drm_handle_vblank(subdrv->drm_dev, manager->pipe); 438 mutex_lock(&ctx->lock);
439
440 if (ctx->direct_vblank) {
441 drm_handle_vblank(subdrv->drm_dev, manager->pipe);
442 ctx->direct_vblank = false;
443 mutex_unlock(&ctx->lock);
444 return;
445 }
446
447 mutex_unlock(&ctx->lock);
448
429 vidi_finish_pageflip(subdrv->drm_dev, manager->pipe); 449 vidi_finish_pageflip(subdrv->drm_dev, manager->pipe);
430} 450}
431 451
@@ -453,7 +473,7 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
453 return 0; 473 return 0;
454} 474}
455 475
456static void vidi_subdrv_remove(struct drm_device *drm_dev) 476static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
457{ 477{
458 DRM_DEBUG_KMS("%s\n", __FILE__); 478 DRM_DEBUG_KMS("%s\n", __FILE__);
459 479
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index e1c53956aa27..2c115f8a62a3 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -32,6 +32,9 @@
32#include <linux/pm_runtime.h> 32#include <linux/pm_runtime.h>
33#include <linux/clk.h> 33#include <linux/clk.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35#include <linux/io.h>
36#include <linux/of_gpio.h>
37#include <plat/gpio-cfg.h>
35 38
36#include <drm/exynos_drm.h> 39#include <drm/exynos_drm.h>
37 40
@@ -40,10 +43,18 @@
40 43
41#include "exynos_hdmi.h" 44#include "exynos_hdmi.h"
42 45
46#include <linux/gpio.h>
47#include <media/s5p_hdmi.h>
48
43#define MAX_WIDTH 1920 49#define MAX_WIDTH 1920
44#define MAX_HEIGHT 1080 50#define MAX_HEIGHT 1080
45#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) 51#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
46 52
53enum hdmi_type {
54 HDMI_TYPE13,
55 HDMI_TYPE14,
56};
57
47struct hdmi_resources { 58struct hdmi_resources {
48 struct clk *hdmi; 59 struct clk *hdmi;
49 struct clk *sclk_hdmi; 60 struct clk *sclk_hdmi;
@@ -59,13 +70,12 @@ struct hdmi_context {
59 struct drm_device *drm_dev; 70 struct drm_device *drm_dev;
60 bool hpd; 71 bool hpd;
61 bool powered; 72 bool powered;
62 bool is_v13;
63 bool dvi_mode; 73 bool dvi_mode;
64 struct mutex hdmi_mutex; 74 struct mutex hdmi_mutex;
65 75
66 void __iomem *regs; 76 void __iomem *regs;
67 unsigned int external_irq; 77 int external_irq;
68 unsigned int internal_irq; 78 int internal_irq;
69 79
70 struct i2c_client *ddc_port; 80 struct i2c_client *ddc_port;
71 struct i2c_client *hdmiphy_port; 81 struct i2c_client *hdmiphy_port;
@@ -76,8 +86,9 @@ struct hdmi_context {
76 struct hdmi_resources res; 86 struct hdmi_resources res;
77 void *parent_ctx; 87 void *parent_ctx;
78 88
79 void (*cfg_hpd)(bool external); 89 int hpd_gpio;
80 int (*get_hpd)(void); 90
91 enum hdmi_type type;
81}; 92};
82 93
83/* HDMI Version 1.3 */ 94/* HDMI Version 1.3 */
@@ -1209,7 +1220,7 @@ static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
1209 1220
1210static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) 1221static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1211{ 1222{
1212 if (hdata->is_v13) 1223 if (hdata->type == HDMI_TYPE13)
1213 hdmi_v13_regs_dump(hdata, prefix); 1224 hdmi_v13_regs_dump(hdata, prefix);
1214 else 1225 else
1215 hdmi_v14_regs_dump(hdata, prefix); 1226 hdmi_v14_regs_dump(hdata, prefix);
@@ -1250,7 +1261,7 @@ static int hdmi_v14_conf_index(struct drm_display_mode *mode)
1250static int hdmi_conf_index(struct hdmi_context *hdata, 1261static int hdmi_conf_index(struct hdmi_context *hdata,
1251 struct drm_display_mode *mode) 1262 struct drm_display_mode *mode)
1252{ 1263{
1253 if (hdata->is_v13) 1264 if (hdata->type == HDMI_TYPE13)
1254 return hdmi_v13_conf_index(mode); 1265 return hdmi_v13_conf_index(mode);
1255 1266
1256 return hdmi_v14_conf_index(mode); 1267 return hdmi_v14_conf_index(mode);
@@ -1346,7 +1357,7 @@ static int hdmi_check_timing(void *ctx, void *timing)
1346 check_timing->yres, check_timing->refresh, 1357 check_timing->yres, check_timing->refresh,
1347 check_timing->vmode); 1358 check_timing->vmode);
1348 1359
1349 if (hdata->is_v13) 1360 if (hdata->type == HDMI_TYPE13)
1350 return hdmi_v13_check_timing(check_timing); 1361 return hdmi_v13_check_timing(check_timing);
1351 else 1362 else
1352 return hdmi_v14_check_timing(check_timing); 1363 return hdmi_v14_check_timing(check_timing);
@@ -1412,7 +1423,7 @@ static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1412 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]); 1423 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1413 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]); 1424 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1414 1425
1415 if (hdata->is_v13) 1426 if (hdata->type == HDMI_TYPE13)
1416 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4); 1427 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1417 else 1428 else
1418 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4); 1429 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
@@ -1516,7 +1527,7 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
1516{ 1527{
1517 u32 reg; 1528 u32 reg;
1518 1529
1519 if (hdata->is_v13) 1530 if (hdata->type == HDMI_TYPE13)
1520 reg = HDMI_V13_CORE_RSTOUT; 1531 reg = HDMI_V13_CORE_RSTOUT;
1521 else 1532 else
1522 reg = HDMI_CORE_RSTOUT; 1533 reg = HDMI_CORE_RSTOUT;
@@ -1530,12 +1541,9 @@ static void hdmi_conf_reset(struct hdmi_context *hdata)
1530 1541
1531static void hdmi_conf_init(struct hdmi_context *hdata) 1542static void hdmi_conf_init(struct hdmi_context *hdata)
1532{ 1543{
1533 /* enable HPD interrupts */ 1544 /* disable HPD interrupts */
1534 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | 1545 hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
1535 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG); 1546 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1536 mdelay(10);
1537 hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
1538 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
1539 1547
1540 /* choose HDMI mode */ 1548 /* choose HDMI mode */
1541 hdmi_reg_writemask(hdata, HDMI_MODE_SEL, 1549 hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
@@ -1551,7 +1559,7 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
1551 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS); 1559 HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
1552 } 1560 }
1553 1561
1554 if (hdata->is_v13) { 1562 if (hdata->type == HDMI_TYPE13) {
1555 /* choose bluescreen (fecal) color */ 1563 /* choose bluescreen (fecal) color */
1556 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12); 1564 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
1557 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34); 1565 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
@@ -1833,7 +1841,7 @@ static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1833 1841
1834static void hdmi_timing_apply(struct hdmi_context *hdata) 1842static void hdmi_timing_apply(struct hdmi_context *hdata)
1835{ 1843{
1836 if (hdata->is_v13) 1844 if (hdata->type == HDMI_TYPE13)
1837 hdmi_v13_timing_apply(hdata); 1845 hdmi_v13_timing_apply(hdata);
1838 else 1846 else
1839 hdmi_v14_timing_apply(hdata); 1847 hdmi_v14_timing_apply(hdata);
@@ -1855,7 +1863,7 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
1855 if (hdata->hdmiphy_port) 1863 if (hdata->hdmiphy_port)
1856 i2c_master_send(hdata->hdmiphy_port, buffer, 2); 1864 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
1857 1865
1858 if (hdata->is_v13) 1866 if (hdata->type == HDMI_TYPE13)
1859 reg = HDMI_V13_PHY_RSTOUT; 1867 reg = HDMI_V13_PHY_RSTOUT;
1860 else 1868 else
1861 reg = HDMI_PHY_RSTOUT; 1869 reg = HDMI_PHY_RSTOUT;
@@ -1882,7 +1890,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
1882 } 1890 }
1883 1891
1884 /* pixel clock */ 1892 /* pixel clock */
1885 if (hdata->is_v13) 1893 if (hdata->type == HDMI_TYPE13)
1886 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data; 1894 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1887 else 1895 else
1888 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data; 1896 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
@@ -1950,7 +1958,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1950 1958
1951 drm_mode_set_crtcinfo(adjusted_mode, 0); 1959 drm_mode_set_crtcinfo(adjusted_mode, 0);
1952 1960
1953 if (hdata->is_v13) 1961 if (hdata->type == HDMI_TYPE13)
1954 index = hdmi_v13_conf_index(adjusted_mode); 1962 index = hdmi_v13_conf_index(adjusted_mode);
1955 else 1963 else
1956 index = hdmi_v14_conf_index(adjusted_mode); 1964 index = hdmi_v14_conf_index(adjusted_mode);
@@ -1964,7 +1972,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1964 * to adjusted_mode. 1972 * to adjusted_mode.
1965 */ 1973 */
1966 list_for_each_entry(m, &connector->modes, head) { 1974 list_for_each_entry(m, &connector->modes, head) {
1967 if (hdata->is_v13) 1975 if (hdata->type == HDMI_TYPE13)
1968 index = hdmi_v13_conf_index(m); 1976 index = hdmi_v13_conf_index(m);
1969 else 1977 else
1970 index = hdmi_v14_conf_index(m); 1978 index = hdmi_v14_conf_index(m);
@@ -2024,8 +2032,6 @@ static void hdmi_poweron(struct hdmi_context *hdata)
2024 2032
2025 hdata->powered = true; 2033 hdata->powered = true;
2026 2034
2027 if (hdata->cfg_hpd)
2028 hdata->cfg_hpd(true);
2029 mutex_unlock(&hdata->hdmi_mutex); 2035 mutex_unlock(&hdata->hdmi_mutex);
2030 2036
2031 pm_runtime_get_sync(hdata->dev); 2037 pm_runtime_get_sync(hdata->dev);
@@ -2061,8 +2067,6 @@ static void hdmi_poweroff(struct hdmi_context *hdata)
2061 pm_runtime_put_sync(hdata->dev); 2067 pm_runtime_put_sync(hdata->dev);
2062 2068
2063 mutex_lock(&hdata->hdmi_mutex); 2069 mutex_lock(&hdata->hdmi_mutex);
2064 if (hdata->cfg_hpd)
2065 hdata->cfg_hpd(false);
2066 2070
2067 hdata->powered = false; 2071 hdata->powered = false;
2068 2072
@@ -2110,17 +2114,13 @@ static irqreturn_t hdmi_external_irq_thread(int irq, void *arg)
2110 struct exynos_drm_hdmi_context *ctx = arg; 2114 struct exynos_drm_hdmi_context *ctx = arg;
2111 struct hdmi_context *hdata = ctx->ctx; 2115 struct hdmi_context *hdata = ctx->ctx;
2112 2116
2113 if (!hdata->get_hpd)
2114 goto out;
2115
2116 mutex_lock(&hdata->hdmi_mutex); 2117 mutex_lock(&hdata->hdmi_mutex);
2117 hdata->hpd = hdata->get_hpd(); 2118 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2118 mutex_unlock(&hdata->hdmi_mutex); 2119 mutex_unlock(&hdata->hdmi_mutex);
2119 2120
2120 if (ctx->drm_dev) 2121 if (ctx->drm_dev)
2121 drm_helper_hpd_irq_event(ctx->drm_dev); 2122 drm_helper_hpd_irq_event(ctx->drm_dev);
2122 2123
2123out:
2124 return IRQ_HANDLED; 2124 return IRQ_HANDLED;
2125} 2125}
2126 2126
@@ -2143,18 +2143,9 @@ static irqreturn_t hdmi_internal_irq_thread(int irq, void *arg)
2143 HDMI_INTC_FLAG_HPD_PLUG); 2143 HDMI_INTC_FLAG_HPD_PLUG);
2144 } 2144 }
2145 2145
2146 mutex_lock(&hdata->hdmi_mutex);
2147 hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
2148 if (hdata->powered && hdata->hpd) {
2149 mutex_unlock(&hdata->hdmi_mutex);
2150 goto out;
2151 }
2152 mutex_unlock(&hdata->hdmi_mutex);
2153
2154 if (ctx->drm_dev) 2146 if (ctx->drm_dev)
2155 drm_helper_hpd_irq_event(ctx->drm_dev); 2147 drm_helper_hpd_irq_event(ctx->drm_dev);
2156 2148
2157out:
2158 return IRQ_HANDLED; 2149 return IRQ_HANDLED;
2159} 2150}
2160 2151
@@ -2262,18 +2253,89 @@ void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
2262 hdmi_hdmiphy = hdmiphy; 2253 hdmi_hdmiphy = hdmiphy;
2263} 2254}
2264 2255
2256#ifdef CONFIG_OF
2257static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2258 (struct device *dev)
2259{
2260 struct device_node *np = dev->of_node;
2261 struct s5p_hdmi_platform_data *pd;
2262 enum of_gpio_flags flags;
2263 u32 value;
2264
2265 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
2266 if (!pd) {
2267 DRM_ERROR("memory allocation for pdata failed\n");
2268 goto err_data;
2269 }
2270
2271 if (!of_find_property(np, "hpd-gpio", &value)) {
2272 DRM_ERROR("no hpd gpio property found\n");
2273 goto err_data;
2274 }
2275
2276 pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
2277
2278 return pd;
2279
2280err_data:
2281 return NULL;
2282}
2283#else
2284static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
2285 (struct device *dev)
2286{
2287 return NULL;
2288}
2289#endif
2290
2291static struct platform_device_id hdmi_driver_types[] = {
2292 {
2293 .name = "s5pv210-hdmi",
2294 .driver_data = HDMI_TYPE13,
2295 }, {
2296 .name = "exynos4-hdmi",
2297 .driver_data = HDMI_TYPE13,
2298 }, {
2299 .name = "exynos4-hdmi14",
2300 .driver_data = HDMI_TYPE14,
2301 }, {
2302 .name = "exynos5-hdmi",
2303 .driver_data = HDMI_TYPE14,
2304 }, {
2305 /* end node */
2306 }
2307};
2308
2309static struct of_device_id hdmi_match_types[] = {
2310 {
2311 .compatible = "samsung,exynos5-hdmi",
2312 .data = (void *)HDMI_TYPE14,
2313 }, {
2314 /* end node */
2315 }
2316};
2317
2265static int __devinit hdmi_probe(struct platform_device *pdev) 2318static int __devinit hdmi_probe(struct platform_device *pdev)
2266{ 2319{
2267 struct device *dev = &pdev->dev; 2320 struct device *dev = &pdev->dev;
2268 struct exynos_drm_hdmi_context *drm_hdmi_ctx; 2321 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
2269 struct hdmi_context *hdata; 2322 struct hdmi_context *hdata;
2270 struct exynos_drm_hdmi_pdata *pdata; 2323 struct s5p_hdmi_platform_data *pdata;
2271 struct resource *res; 2324 struct resource *res;
2272 int ret; 2325 int ret;
2273 2326
2274 DRM_DEBUG_KMS("[%d]\n", __LINE__); 2327 DRM_DEBUG_KMS("[%d]\n", __LINE__);
2275 2328
2276 pdata = pdev->dev.platform_data; 2329 if (pdev->dev.of_node) {
2330 pdata = drm_hdmi_dt_parse_pdata(dev);
2331 if (IS_ERR(pdata)) {
2332 DRM_ERROR("failed to parse dt\n");
2333 return PTR_ERR(pdata);
2334 }
2335 } else {
2336 pdata = pdev->dev.platform_data;
2337 }
2338
2277 if (!pdata) { 2339 if (!pdata) {
2278 DRM_ERROR("no platform data specified\n"); 2340 DRM_ERROR("no platform data specified\n");
2279 return -EINVAL; 2341 return -EINVAL;
@@ -2300,18 +2362,33 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
2300 2362
2301 platform_set_drvdata(pdev, drm_hdmi_ctx); 2363 platform_set_drvdata(pdev, drm_hdmi_ctx);
2302 2364
2303 hdata->is_v13 = pdata->is_v13; 2365 if (dev->of_node) {
2304 hdata->cfg_hpd = pdata->cfg_hpd; 2366 const struct of_device_id *match;
2305 hdata->get_hpd = pdata->get_hpd; 2367 match = of_match_node(of_match_ptr(hdmi_match_types),
2368 pdev->dev.of_node);
2369 hdata->type = (enum hdmi_type)match->data;
2370 } else {
2371 hdata->type = (enum hdmi_type)platform_get_device_id
2372 (pdev)->driver_data;
2373 }
2374
2375 hdata->hpd_gpio = pdata->hpd_gpio;
2306 hdata->dev = dev; 2376 hdata->dev = dev;
2307 2377
2308 ret = hdmi_resources_init(hdata); 2378 ret = hdmi_resources_init(hdata);
2379
2309 if (ret) { 2380 if (ret) {
2310 ret = -EINVAL; 2381 ret = -EINVAL;
2382 DRM_ERROR("hdmi_resources_init failed\n");
2311 goto err_data; 2383 goto err_data;
2312 } 2384 }
2313 2385
2314 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2386 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2387 if (!res) {
2388 DRM_ERROR("failed to find registers\n");
2389 ret = -ENOENT;
2390 goto err_resource;
2391 }
2315 2392
2316 hdata->regs = devm_request_and_ioremap(&pdev->dev, res); 2393 hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
2317 if (!hdata->regs) { 2394 if (!hdata->regs) {
@@ -2320,11 +2397,17 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
2320 goto err_resource; 2397 goto err_resource;
2321 } 2398 }
2322 2399
2400 ret = gpio_request(hdata->hpd_gpio, "HPD");
2401 if (ret) {
2402 DRM_ERROR("failed to request HPD gpio\n");
2403 goto err_resource;
2404 }
2405
2323 /* DDC i2c driver */ 2406 /* DDC i2c driver */
2324 if (i2c_add_driver(&ddc_driver)) { 2407 if (i2c_add_driver(&ddc_driver)) {
2325 DRM_ERROR("failed to register ddc i2c driver\n"); 2408 DRM_ERROR("failed to register ddc i2c driver\n");
2326 ret = -ENOENT; 2409 ret = -ENOENT;
2327 goto err_resource; 2410 goto err_gpio;
2328 } 2411 }
2329 2412
2330 hdata->ddc_port = hdmi_ddc; 2413 hdata->ddc_port = hdmi_ddc;
@@ -2338,32 +2421,31 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
2338 2421
2339 hdata->hdmiphy_port = hdmi_hdmiphy; 2422 hdata->hdmiphy_port = hdmi_hdmiphy;
2340 2423
2341 hdata->external_irq = platform_get_irq_byname(pdev, "external_irq"); 2424 hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
2342 if (hdata->external_irq < 0) { 2425 if (hdata->external_irq < 0) {
2343 DRM_ERROR("failed to get platform irq\n"); 2426 DRM_ERROR("failed to get GPIO external irq\n");
2344 ret = hdata->external_irq; 2427 ret = hdata->external_irq;
2345 goto err_hdmiphy; 2428 goto err_hdmiphy;
2346 } 2429 }
2347 2430
2348 hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq"); 2431 hdata->internal_irq = platform_get_irq(pdev, 0);
2349 if (hdata->internal_irq < 0) { 2432 if (hdata->internal_irq < 0) {
2350 DRM_ERROR("failed to get platform internal irq\n"); 2433 DRM_ERROR("failed to get platform internal irq\n");
2351 ret = hdata->internal_irq; 2434 ret = hdata->internal_irq;
2352 goto err_hdmiphy; 2435 goto err_hdmiphy;
2353 } 2436 }
2354 2437
2438 hdata->hpd = gpio_get_value(hdata->hpd_gpio);
2439
2355 ret = request_threaded_irq(hdata->external_irq, NULL, 2440 ret = request_threaded_irq(hdata->external_irq, NULL,
2356 hdmi_external_irq_thread, IRQF_TRIGGER_RISING | 2441 hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
2357 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 2442 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2358 "hdmi_external", drm_hdmi_ctx); 2443 "hdmi_external", drm_hdmi_ctx);
2359 if (ret) { 2444 if (ret) {
2360 DRM_ERROR("failed to register hdmi internal interrupt\n"); 2445 DRM_ERROR("failed to register hdmi external interrupt\n");
2361 goto err_hdmiphy; 2446 goto err_hdmiphy;
2362 } 2447 }
2363 2448
2364 if (hdata->cfg_hpd)
2365 hdata->cfg_hpd(false);
2366
2367 ret = request_threaded_irq(hdata->internal_irq, NULL, 2449 ret = request_threaded_irq(hdata->internal_irq, NULL,
2368 hdmi_internal_irq_thread, IRQF_ONESHOT, 2450 hdmi_internal_irq_thread, IRQF_ONESHOT,
2369 "hdmi_internal", drm_hdmi_ctx); 2451 "hdmi_internal", drm_hdmi_ctx);
@@ -2372,6 +2454,9 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
2372 goto err_free_irq; 2454 goto err_free_irq;
2373 } 2455 }
2374 2456
2457 /* Attach HDMI Driver to common hdmi. */
2458 exynos_hdmi_drv_attach(drm_hdmi_ctx);
2459
2375 /* register specific callbacks to common hdmi. */ 2460 /* register specific callbacks to common hdmi. */
2376 exynos_hdmi_ops_register(&hdmi_ops); 2461 exynos_hdmi_ops_register(&hdmi_ops);
2377 2462
@@ -2385,6 +2470,8 @@ err_hdmiphy:
2385 i2c_del_driver(&hdmiphy_driver); 2470 i2c_del_driver(&hdmiphy_driver);
2386err_ddc: 2471err_ddc:
2387 i2c_del_driver(&ddc_driver); 2472 i2c_del_driver(&ddc_driver);
2473err_gpio:
2474 gpio_free(hdata->hpd_gpio);
2388err_resource: 2475err_resource:
2389 hdmi_resources_cleanup(hdata); 2476 hdmi_resources_cleanup(hdata);
2390err_data: 2477err_data:
@@ -2402,6 +2489,9 @@ static int __devexit hdmi_remove(struct platform_device *pdev)
2402 pm_runtime_disable(dev); 2489 pm_runtime_disable(dev);
2403 2490
2404 free_irq(hdata->internal_irq, hdata); 2491 free_irq(hdata->internal_irq, hdata);
2492 free_irq(hdata->external_irq, hdata);
2493
2494 gpio_free(hdata->hpd_gpio);
2405 2495
2406 hdmi_resources_cleanup(hdata); 2496 hdmi_resources_cleanup(hdata);
2407 2497
@@ -2447,9 +2537,11 @@ static SIMPLE_DEV_PM_OPS(hdmi_pm_ops, hdmi_suspend, hdmi_resume);
2447struct platform_driver hdmi_driver = { 2537struct platform_driver hdmi_driver = {
2448 .probe = hdmi_probe, 2538 .probe = hdmi_probe,
2449 .remove = __devexit_p(hdmi_remove), 2539 .remove = __devexit_p(hdmi_remove),
2540 .id_table = hdmi_driver_types,
2450 .driver = { 2541 .driver = {
2451 .name = "exynos4-hdmi", 2542 .name = "exynos-hdmi",
2452 .owner = THIS_MODULE, 2543 .owner = THIS_MODULE,
2453 .pm = &hdmi_pm_ops, 2544 .pm = &hdmi_pm_ops,
2545 .of_match_table = hdmi_match_types,
2454 }, 2546 },
2455}; 2547};
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index 0a8162b7de3d..27d1720f1bbd 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -42,13 +42,23 @@ static int hdmiphy_remove(struct i2c_client *client)
42 42
43static const struct i2c_device_id hdmiphy_id[] = { 43static const struct i2c_device_id hdmiphy_id[] = {
44 { "s5p_hdmiphy", 0 }, 44 { "s5p_hdmiphy", 0 },
45 { "exynos5-hdmiphy", 0 },
45 { }, 46 { },
46}; 47};
47 48
49static struct of_device_id hdmiphy_match_types[] = {
50 {
51 .compatible = "samsung,exynos5-hdmiphy",
52 }, {
53 /* end node */
54 }
55};
56
48struct i2c_driver hdmiphy_driver = { 57struct i2c_driver hdmiphy_driver = {
49 .driver = { 58 .driver = {
50 .name = "s5p-hdmiphy", 59 .name = "exynos-hdmiphy",
51 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
61 .of_match_table = hdmiphy_match_types,
52 }, 62 },
53 .id_table = hdmiphy_id, 63 .id_table = hdmiphy_id,
54 .probe = hdmiphy_probe, 64 .probe = hdmiphy_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index e6098f247a5d..614b2e9ac462 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -73,16 +73,28 @@ struct mixer_resources {
73 struct clk *sclk_dac; 73 struct clk *sclk_dac;
74}; 74};
75 75
76enum mixer_version_id {
77 MXR_VER_0_0_0_16,
78 MXR_VER_16_0_33_0,
79};
80
76struct mixer_context { 81struct mixer_context {
77 struct device *dev; 82 struct device *dev;
78 int pipe; 83 int pipe;
79 bool interlace; 84 bool interlace;
80 bool powered; 85 bool powered;
86 bool vp_enabled;
81 u32 int_en; 87 u32 int_en;
82 88
83 struct mutex mixer_mutex; 89 struct mutex mixer_mutex;
84 struct mixer_resources mixer_res; 90 struct mixer_resources mixer_res;
85 struct hdmi_win_data win_data[MIXER_WIN_NR]; 91 struct hdmi_win_data win_data[MIXER_WIN_NR];
92 enum mixer_version_id mxr_ver;
93};
94
95struct mixer_drv_data {
96 enum mixer_version_id version;
97 bool is_vp_enabled;
86}; 98};
87 99
88static const u8 filter_y_horiz_tap8[] = { 100static const u8 filter_y_horiz_tap8[] = {
@@ -251,7 +263,8 @@ static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
251 mixer_reg_writemask(res, MXR_STATUS, enable ? 263 mixer_reg_writemask(res, MXR_STATUS, enable ?
252 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); 264 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
253 265
254 vp_reg_write(res, VP_SHADOW_UPDATE, enable ? 266 if (ctx->vp_enabled)
267 vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
255 VP_SHADOW_UPDATE_ENABLE : 0); 268 VP_SHADOW_UPDATE_ENABLE : 0);
256} 269}
257 270
@@ -333,8 +346,11 @@ static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
333 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); 346 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
334 break; 347 break;
335 case 2: 348 case 2:
336 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); 349 if (ctx->vp_enabled) {
337 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE); 350 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
351 mixer_reg_writemask(res, MXR_CFG, val,
352 MXR_CFG_VP_ENABLE);
353 }
338 break; 354 break;
339 } 355 }
340} 356}
@@ -465,6 +481,18 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
465 vp_regs_dump(ctx); 481 vp_regs_dump(ctx);
466} 482}
467 483
484static void mixer_layer_update(struct mixer_context *ctx)
485{
486 struct mixer_resources *res = &ctx->mixer_res;
487 u32 val;
488
489 val = mixer_reg_read(res, MXR_CFG);
490
491 /* allow one update per vsync only */
492 if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
493 mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
494}
495
468static void mixer_graph_buffer(struct mixer_context *ctx, int win) 496static void mixer_graph_buffer(struct mixer_context *ctx, int win)
469{ 497{
470 struct mixer_resources *res = &ctx->mixer_res; 498 struct mixer_resources *res = &ctx->mixer_res;
@@ -545,6 +573,11 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
545 mixer_cfg_scan(ctx, win_data->mode_height); 573 mixer_cfg_scan(ctx, win_data->mode_height);
546 mixer_cfg_rgb_fmt(ctx, win_data->mode_height); 574 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
547 mixer_cfg_layer(ctx, win, true); 575 mixer_cfg_layer(ctx, win, true);
576
577 /* layer update mandatory for mixer 16.0.33.0 */
578 if (ctx->mxr_ver == MXR_VER_16_0_33_0)
579 mixer_layer_update(ctx);
580
548 mixer_run(ctx); 581 mixer_run(ctx);
549 582
550 mixer_vsync_set_update(ctx, true); 583 mixer_vsync_set_update(ctx, true);
@@ -592,7 +625,8 @@ static void mixer_win_reset(struct mixer_context *ctx)
592 */ 625 */
593 val = MXR_LAYER_CFG_GRP1_VAL(3); 626 val = MXR_LAYER_CFG_GRP1_VAL(3);
594 val |= MXR_LAYER_CFG_GRP0_VAL(2); 627 val |= MXR_LAYER_CFG_GRP0_VAL(2);
595 val |= MXR_LAYER_CFG_VP_VAL(1); 628 if (ctx->vp_enabled)
629 val |= MXR_LAYER_CFG_VP_VAL(1);
596 mixer_reg_write(res, MXR_LAYER_CFG, val); 630 mixer_reg_write(res, MXR_LAYER_CFG, val);
597 631
598 /* setting background color */ 632 /* setting background color */
@@ -615,14 +649,17 @@ static void mixer_win_reset(struct mixer_context *ctx)
615 val = MXR_GRP_CFG_ALPHA_VAL(0); 649 val = MXR_GRP_CFG_ALPHA_VAL(0);
616 mixer_reg_write(res, MXR_VIDEO_CFG, val); 650 mixer_reg_write(res, MXR_VIDEO_CFG, val);
617 651
618 /* configuration of Video Processor Registers */ 652 if (ctx->vp_enabled) {
619 vp_win_reset(ctx); 653 /* configuration of Video Processor Registers */
620 vp_default_filter(res); 654 vp_win_reset(ctx);
655 vp_default_filter(res);
656 }
621 657
622 /* disable all layers */ 658 /* disable all layers */
623 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); 659 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
624 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); 660 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
625 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); 661 if (ctx->vp_enabled)
662 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
626 663
627 mixer_vsync_set_update(ctx, true); 664 mixer_vsync_set_update(ctx, true);
628 spin_unlock_irqrestore(&res->reg_slock, flags); 665 spin_unlock_irqrestore(&res->reg_slock, flags);
@@ -645,8 +682,10 @@ static void mixer_poweron(struct mixer_context *ctx)
645 pm_runtime_get_sync(ctx->dev); 682 pm_runtime_get_sync(ctx->dev);
646 683
647 clk_enable(res->mixer); 684 clk_enable(res->mixer);
648 clk_enable(res->vp); 685 if (ctx->vp_enabled) {
649 clk_enable(res->sclk_mixer); 686 clk_enable(res->vp);
687 clk_enable(res->sclk_mixer);
688 }
650 689
651 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 690 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
652 mixer_win_reset(ctx); 691 mixer_win_reset(ctx);
@@ -666,8 +705,10 @@ static void mixer_poweroff(struct mixer_context *ctx)
666 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 705 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
667 706
668 clk_disable(res->mixer); 707 clk_disable(res->mixer);
669 clk_disable(res->vp); 708 if (ctx->vp_enabled) {
670 clk_disable(res->sclk_mixer); 709 clk_disable(res->vp);
710 clk_disable(res->sclk_mixer);
711 }
671 712
672 pm_runtime_put_sync(ctx->dev); 713 pm_runtime_put_sync(ctx->dev);
673 714
@@ -726,6 +767,18 @@ static void mixer_dpms(void *ctx, int mode)
726 } 767 }
727} 768}
728 769
770static void mixer_wait_for_vblank(void *ctx)
771{
772 struct mixer_context *mixer_ctx = ctx;
773 struct mixer_resources *res = &mixer_ctx->mixer_res;
774 int ret;
775
776 ret = wait_for((mixer_reg_read(res, MXR_INT_STATUS) &
777 MXR_INT_STATUS_VSYNC), 50);
778 if (ret < 0)
779 DRM_DEBUG_KMS("vblank wait timed out.\n");
780}
781
729static void mixer_win_mode_set(void *ctx, 782static void mixer_win_mode_set(void *ctx,
730 struct exynos_drm_overlay *overlay) 783 struct exynos_drm_overlay *overlay)
731{ 784{
@@ -788,7 +841,7 @@ static void mixer_win_commit(void *ctx, int win)
788 841
789 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); 842 DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
790 843
791 if (win > 1) 844 if (win > 1 && mixer_ctx->vp_enabled)
792 vp_video_buffer(mixer_ctx, win); 845 vp_video_buffer(mixer_ctx, win);
793 else 846 else
794 mixer_graph_buffer(mixer_ctx, win); 847 mixer_graph_buffer(mixer_ctx, win);
@@ -818,6 +871,7 @@ static struct exynos_mixer_ops mixer_ops = {
818 .dpms = mixer_dpms, 871 .dpms = mixer_dpms,
819 872
820 /* overlay */ 873 /* overlay */
874 .wait_for_vblank = mixer_wait_for_vblank,
821 .win_mode_set = mixer_win_mode_set, 875 .win_mode_set = mixer_win_mode_set,
822 .win_commit = mixer_win_commit, 876 .win_commit = mixer_win_commit,
823 .win_disable = mixer_win_disable, 877 .win_disable = mixer_win_disable,
@@ -923,39 +977,20 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
923 ret = -ENODEV; 977 ret = -ENODEV;
924 goto fail; 978 goto fail;
925 } 979 }
926 mixer_res->vp = clk_get(dev, "vp"); 980
927 if (IS_ERR_OR_NULL(mixer_res->vp)) {
928 dev_err(dev, "failed to get clock 'vp'\n");
929 ret = -ENODEV;
930 goto fail;
931 }
932 mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
933 if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
934 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
935 ret = -ENODEV;
936 goto fail;
937 }
938 mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); 981 mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
939 if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) { 982 if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
940 dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); 983 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
941 ret = -ENODEV; 984 ret = -ENODEV;
942 goto fail; 985 goto fail;
943 } 986 }
944 mixer_res->sclk_dac = clk_get(dev, "sclk_dac"); 987 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
945 if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
946 dev_err(dev, "failed to get clock 'sclk_dac'\n");
947 ret = -ENODEV;
948 goto fail;
949 }
950 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
951 if (res == NULL) { 988 if (res == NULL) {
952 dev_err(dev, "get memory resource failed.\n"); 989 dev_err(dev, "get memory resource failed.\n");
953 ret = -ENXIO; 990 ret = -ENXIO;
954 goto fail; 991 goto fail;
955 } 992 }
956 993
957 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
958
959 mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start, 994 mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
960 resource_size(res)); 995 resource_size(res));
961 if (mixer_res->mixer_regs == NULL) { 996 if (mixer_res->mixer_regs == NULL) {
@@ -964,57 +999,126 @@ static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
964 goto fail; 999 goto fail;
965 } 1000 }
966 1001
967 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp"); 1002 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
968 if (res == NULL) { 1003 if (res == NULL) {
969 dev_err(dev, "get memory resource failed.\n"); 1004 dev_err(dev, "get interrupt resource failed.\n");
970 ret = -ENXIO; 1005 ret = -ENXIO;
971 goto fail; 1006 goto fail;
972 } 1007 }
973 1008
974 mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start, 1009 ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
975 resource_size(res)); 1010 0, "drm_mixer", ctx);
976 if (mixer_res->vp_regs == NULL) { 1011 if (ret) {
977 dev_err(dev, "register mapping failed.\n"); 1012 dev_err(dev, "request interrupt failed.\n");
978 ret = -ENXIO;
979 goto fail; 1013 goto fail;
980 } 1014 }
1015 mixer_res->irq = res->start;
1016
1017 return 0;
981 1018
982 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq"); 1019fail:
1020 if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
1021 clk_put(mixer_res->sclk_hdmi);
1022 if (!IS_ERR_OR_NULL(mixer_res->mixer))
1023 clk_put(mixer_res->mixer);
1024 return ret;
1025}
1026
1027static int __devinit vp_resources_init(struct exynos_drm_hdmi_context *ctx,
1028 struct platform_device *pdev)
1029{
1030 struct mixer_context *mixer_ctx = ctx->ctx;
1031 struct device *dev = &pdev->dev;
1032 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1033 struct resource *res;
1034 int ret;
1035
1036 mixer_res->vp = clk_get(dev, "vp");
1037 if (IS_ERR_OR_NULL(mixer_res->vp)) {
1038 dev_err(dev, "failed to get clock 'vp'\n");
1039 ret = -ENODEV;
1040 goto fail;
1041 }
1042 mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
1043 if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
1044 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
1045 ret = -ENODEV;
1046 goto fail;
1047 }
1048 mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
1049 if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
1050 dev_err(dev, "failed to get clock 'sclk_dac'\n");
1051 ret = -ENODEV;
1052 goto fail;
1053 }
1054
1055 if (mixer_res->sclk_hdmi)
1056 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
1057
1058 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
983 if (res == NULL) { 1059 if (res == NULL) {
984 dev_err(dev, "get interrupt resource failed.\n"); 1060 dev_err(dev, "get memory resource failed.\n");
985 ret = -ENXIO; 1061 ret = -ENXIO;
986 goto fail; 1062 goto fail;
987 } 1063 }
988 1064
989 ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler, 1065 mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
990 0, "drm_mixer", ctx); 1066 resource_size(res));
991 if (ret) { 1067 if (mixer_res->vp_regs == NULL) {
992 dev_err(dev, "request interrupt failed.\n"); 1068 dev_err(dev, "register mapping failed.\n");
1069 ret = -ENXIO;
993 goto fail; 1070 goto fail;
994 } 1071 }
995 mixer_res->irq = res->start;
996 1072
997 return 0; 1073 return 0;
998 1074
999fail: 1075fail:
1000 if (!IS_ERR_OR_NULL(mixer_res->sclk_dac)) 1076 if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
1001 clk_put(mixer_res->sclk_dac); 1077 clk_put(mixer_res->sclk_dac);
1002 if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
1003 clk_put(mixer_res->sclk_hdmi);
1004 if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer)) 1078 if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
1005 clk_put(mixer_res->sclk_mixer); 1079 clk_put(mixer_res->sclk_mixer);
1006 if (!IS_ERR_OR_NULL(mixer_res->vp)) 1080 if (!IS_ERR_OR_NULL(mixer_res->vp))
1007 clk_put(mixer_res->vp); 1081 clk_put(mixer_res->vp);
1008 if (!IS_ERR_OR_NULL(mixer_res->mixer))
1009 clk_put(mixer_res->mixer);
1010 return ret; 1082 return ret;
1011} 1083}
1012 1084
1085static struct mixer_drv_data exynos5_mxr_drv_data = {
1086 .version = MXR_VER_16_0_33_0,
1087 .is_vp_enabled = 0,
1088};
1089
1090static struct mixer_drv_data exynos4_mxr_drv_data = {
1091 .version = MXR_VER_0_0_0_16,
1092 .is_vp_enabled = 1,
1093};
1094
1095static struct platform_device_id mixer_driver_types[] = {
1096 {
1097 .name = "s5p-mixer",
1098 .driver_data = (unsigned long)&exynos4_mxr_drv_data,
1099 }, {
1100 .name = "exynos5-mixer",
1101 .driver_data = (unsigned long)&exynos5_mxr_drv_data,
1102 }, {
1103 /* end node */
1104 }
1105};
1106
1107static struct of_device_id mixer_match_types[] = {
1108 {
1109 .compatible = "samsung,exynos5-mixer",
1110 .data = &exynos5_mxr_drv_data,
1111 }, {
1112 /* end node */
1113 }
1114};
1115
1013static int __devinit mixer_probe(struct platform_device *pdev) 1116static int __devinit mixer_probe(struct platform_device *pdev)
1014{ 1117{
1015 struct device *dev = &pdev->dev; 1118 struct device *dev = &pdev->dev;
1016 struct exynos_drm_hdmi_context *drm_hdmi_ctx; 1119 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
1017 struct mixer_context *ctx; 1120 struct mixer_context *ctx;
1121 struct mixer_drv_data *drv;
1018 int ret; 1122 int ret;
1019 1123
1020 dev_info(dev, "probe start\n"); 1124 dev_info(dev, "probe start\n");
@@ -1034,15 +1138,41 @@ static int __devinit mixer_probe(struct platform_device *pdev)
1034 1138
1035 mutex_init(&ctx->mixer_mutex); 1139 mutex_init(&ctx->mixer_mutex);
1036 1140
1141 if (dev->of_node) {
1142 const struct of_device_id *match;
1143 match = of_match_node(of_match_ptr(mixer_match_types),
1144 pdev->dev.of_node);
1145 drv = match->data;
1146 } else {
1147 drv = (struct mixer_drv_data *)
1148 platform_get_device_id(pdev)->driver_data;
1149 }
1150
1037 ctx->dev = &pdev->dev; 1151 ctx->dev = &pdev->dev;
1038 drm_hdmi_ctx->ctx = (void *)ctx; 1152 drm_hdmi_ctx->ctx = (void *)ctx;
1153 ctx->vp_enabled = drv->is_vp_enabled;
1154 ctx->mxr_ver = drv->version;
1039 1155
1040 platform_set_drvdata(pdev, drm_hdmi_ctx); 1156 platform_set_drvdata(pdev, drm_hdmi_ctx);
1041 1157
1042 /* acquire resources: regs, irqs, clocks */ 1158 /* acquire resources: regs, irqs, clocks */
1043 ret = mixer_resources_init(drm_hdmi_ctx, pdev); 1159 ret = mixer_resources_init(drm_hdmi_ctx, pdev);
1044 if (ret) 1160 if (ret) {
1161 DRM_ERROR("mixer_resources_init failed\n");
1045 goto fail; 1162 goto fail;
1163 }
1164
1165 if (ctx->vp_enabled) {
1166 /* acquire vp resources: regs, irqs, clocks */
1167 ret = vp_resources_init(drm_hdmi_ctx, pdev);
1168 if (ret) {
1169 DRM_ERROR("vp_resources_init failed\n");
1170 goto fail;
1171 }
1172 }
1173
1174 /* attach mixer driver to common hdmi. */
1175 exynos_mixer_drv_attach(drm_hdmi_ctx);
1046 1176
1047 /* register specific callback point to common hdmi. */ 1177 /* register specific callback point to common hdmi. */
1048 exynos_mixer_ops_register(&mixer_ops); 1178 exynos_mixer_ops_register(&mixer_ops);
@@ -1082,10 +1212,12 @@ static SIMPLE_DEV_PM_OPS(mixer_pm_ops, mixer_suspend, NULL);
1082 1212
1083struct platform_driver mixer_driver = { 1213struct platform_driver mixer_driver = {
1084 .driver = { 1214 .driver = {
1085 .name = "s5p-mixer", 1215 .name = "exynos-mixer",
1086 .owner = THIS_MODULE, 1216 .owner = THIS_MODULE,
1087 .pm = &mixer_pm_ops, 1217 .pm = &mixer_pm_ops,
1218 .of_match_table = mixer_match_types,
1088 }, 1219 },
1089 .probe = mixer_probe, 1220 .probe = mixer_probe,
1090 .remove = __devexit_p(mixer_remove), 1221 .remove = __devexit_p(mixer_remove),
1222 .id_table = mixer_driver_types,
1091}; 1223};
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h
index fd2f4d14cf6d..5d8dbc0301e6 100644
--- a/drivers/gpu/drm/exynos/regs-mixer.h
+++ b/drivers/gpu/drm/exynos/regs-mixer.h
@@ -69,6 +69,7 @@
69 (((val) << (low_bit)) & MXR_MASK(high_bit, low_bit)) 69 (((val) << (low_bit)) & MXR_MASK(high_bit, low_bit))
70 70
71/* bits for MXR_STATUS */ 71/* bits for MXR_STATUS */
72#define MXR_STATUS_SOFT_RESET (1 << 8)
72#define MXR_STATUS_16_BURST (1 << 7) 73#define MXR_STATUS_16_BURST (1 << 7)
73#define MXR_STATUS_BURST_MASK (1 << 7) 74#define MXR_STATUS_BURST_MASK (1 << 7)
74#define MXR_STATUS_BIG_ENDIAN (1 << 3) 75#define MXR_STATUS_BIG_ENDIAN (1 << 3)
@@ -77,6 +78,8 @@
77#define MXR_STATUS_REG_RUN (1 << 0) 78#define MXR_STATUS_REG_RUN (1 << 0)
78 79
79/* bits for MXR_CFG */ 80/* bits for MXR_CFG */
81#define MXR_CFG_LAYER_UPDATE (1 << 31)
82#define MXR_CFG_LAYER_UPDATE_COUNT_MASK (3 << 29)
80#define MXR_CFG_RGB601_0_255 (0 << 9) 83#define MXR_CFG_RGB601_0_255 (0 << 9)
81#define MXR_CFG_RGB601_16_235 (1 << 9) 84#define MXR_CFG_RGB601_16_235 (1 << 9)
82#define MXR_CFG_RGB709_0_255 (2 << 9) 85#define MXR_CFG_RGB709_0_255 (2 << 9)