aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2014-09-19 08:58:53 -0400
committerInki Dae <daeinki@gmail.com>2014-09-19 12:17:53 -0400
commit72ed6ccd086f679aa61c79cd3af733756b72429e (patch)
treebcc5a8306a7c69f0a6e9138304c7f7fa04053814
parent832316c704fe3d15ae6ca9a552ae80411d1bbbcd (diff)
drm/exynos: switch to universal plane API
The patch replaces legacy functions drm_plane_init() / drm_crtc_init() with drm_universal_plane_init() and drm_crtc_init_with_planes(). It allows to replace fake primary plane with the real one. Additionally the patch leaves cleanup of crtcs to core, this way planes and crtcs are cleaned in correct order. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c62
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c19
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.h3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c3
7 files changed, 46 insertions, 51 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index b68e58f78cd1..8e38e9f8e542 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -32,7 +32,6 @@ enum exynos_crtc_mode {
32 * Exynos specific crtc structure. 32 * Exynos specific crtc structure.
33 * 33 *
34 * @drm_crtc: crtc object. 34 * @drm_crtc: crtc object.
35 * @drm_plane: pointer of private plane object for this crtc
36 * @manager: the manager associated with this crtc 35 * @manager: the manager associated with this crtc
37 * @pipe: a crtc index created at load() with a new crtc object creation 36 * @pipe: a crtc index created at load() with a new crtc object creation
38 * and the crtc object would be set to private->crtc array 37 * and the crtc object would be set to private->crtc array
@@ -46,7 +45,6 @@ enum exynos_crtc_mode {
46 */ 45 */
47struct exynos_drm_crtc { 46struct exynos_drm_crtc {
48 struct drm_crtc drm_crtc; 47 struct drm_crtc drm_crtc;
49 struct drm_plane *plane;
50 struct exynos_drm_manager *manager; 48 struct exynos_drm_manager *manager;
51 unsigned int pipe; 49 unsigned int pipe;
52 unsigned int dpms; 50 unsigned int dpms;
@@ -94,12 +92,12 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
94 92
95 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 93 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
96 94
97 exynos_plane_commit(exynos_crtc->plane); 95 exynos_plane_commit(crtc->primary);
98 96
99 if (manager->ops->commit) 97 if (manager->ops->commit)
100 manager->ops->commit(manager); 98 manager->ops->commit(manager);
101 99
102 exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON); 100 exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON);
103} 101}
104 102
105static bool 103static bool
@@ -123,10 +121,9 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
123{ 121{
124 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 122 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
125 struct exynos_drm_manager *manager = exynos_crtc->manager; 123 struct exynos_drm_manager *manager = exynos_crtc->manager;
126 struct drm_plane *plane = exynos_crtc->plane; 124 struct drm_framebuffer *fb = crtc->primary->fb;
127 unsigned int crtc_w; 125 unsigned int crtc_w;
128 unsigned int crtc_h; 126 unsigned int crtc_h;
129 int ret;
130 127
131 /* 128 /*
132 * copy the mode data adjusted by mode_fixup() into crtc->mode 129 * copy the mode data adjusted by mode_fixup() into crtc->mode
@@ -134,29 +131,21 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
134 */ 131 */
135 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); 132 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
136 133
137 crtc_w = crtc->primary->fb->width - x; 134 crtc_w = fb->width - x;
138 crtc_h = crtc->primary->fb->height - y; 135 crtc_h = fb->height - y;
139 136
140 if (manager->ops->mode_set) 137 if (manager->ops->mode_set)
141 manager->ops->mode_set(manager, &crtc->mode); 138 manager->ops->mode_set(manager, &crtc->mode);
142 139
143 ret = exynos_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, crtc_w, crtc_h, 140 return exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
144 x, y, crtc_w, crtc_h); 141 crtc_w, crtc_h, x, y, crtc_w, crtc_h);
145 if (ret)
146 return ret;
147
148 plane->crtc = crtc;
149 plane->fb = crtc->primary->fb;
150 drm_framebuffer_reference(plane->fb);
151
152 return 0;
153} 142}
154 143
155static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y, 144static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
156 struct drm_framebuffer *old_fb) 145 struct drm_framebuffer *old_fb)
157{ 146{
158 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 147 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
159 struct drm_plane *plane = exynos_crtc->plane; 148 struct drm_framebuffer *fb = crtc->primary->fb;
160 unsigned int crtc_w; 149 unsigned int crtc_w;
161 unsigned int crtc_h; 150 unsigned int crtc_h;
162 int ret; 151 int ret;
@@ -167,11 +156,11 @@ static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
167 return -EPERM; 156 return -EPERM;
168 } 157 }
169 158
170 crtc_w = crtc->primary->fb->width - x; 159 crtc_w = fb->width - x;
171 crtc_h = crtc->primary->fb->height - y; 160 crtc_h = fb->height - y;
172 161
173 ret = exynos_plane_mode_set(plane, crtc, crtc->primary->fb, 0, 0, crtc_w, crtc_h, 162 ret = exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
174 x, y, crtc_w, crtc_h); 163 crtc_w, crtc_h, x, y, crtc_w, crtc_h);
175 if (ret) 164 if (ret)
176 return ret; 165 return ret;
177 166
@@ -304,8 +293,7 @@ static int exynos_drm_crtc_set_property(struct drm_crtc *crtc,
304 exynos_drm_crtc_commit(crtc); 293 exynos_drm_crtc_commit(crtc);
305 break; 294 break;
306 case CRTC_MODE_BLANK: 295 case CRTC_MODE_BLANK:
307 exynos_plane_dpms(exynos_crtc->plane, 296 exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_OFF);
308 DRM_MODE_DPMS_OFF);
309 break; 297 break;
310 default: 298 default:
311 break; 299 break;
@@ -351,8 +339,10 @@ static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
351int exynos_drm_crtc_create(struct exynos_drm_manager *manager) 339int exynos_drm_crtc_create(struct exynos_drm_manager *manager)
352{ 340{
353 struct exynos_drm_crtc *exynos_crtc; 341 struct exynos_drm_crtc *exynos_crtc;
342 struct drm_plane *plane;
354 struct exynos_drm_private *private = manager->drm_dev->dev_private; 343 struct exynos_drm_private *private = manager->drm_dev->dev_private;
355 struct drm_crtc *crtc; 344 struct drm_crtc *crtc;
345 int ret;
356 346
357 exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); 347 exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
358 if (!exynos_crtc) 348 if (!exynos_crtc)
@@ -364,11 +354,11 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager)
364 exynos_crtc->dpms = DRM_MODE_DPMS_OFF; 354 exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
365 exynos_crtc->manager = manager; 355 exynos_crtc->manager = manager;
366 exynos_crtc->pipe = manager->pipe; 356 exynos_crtc->pipe = manager->pipe;
367 exynos_crtc->plane = exynos_plane_init(manager->drm_dev, 357 plane = exynos_plane_init(manager->drm_dev, 1 << manager->pipe,
368 1 << manager->pipe, true); 358 DRM_PLANE_TYPE_PRIMARY);
369 if (!exynos_crtc->plane) { 359 if (IS_ERR(plane)) {
370 kfree(exynos_crtc); 360 ret = PTR_ERR(plane);
371 return -ENOMEM; 361 goto err_plane;
372 } 362 }
373 363
374 manager->crtc = &exynos_crtc->drm_crtc; 364 manager->crtc = &exynos_crtc->drm_crtc;
@@ -376,12 +366,22 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager)
376 366
377 private->crtc[manager->pipe] = crtc; 367 private->crtc[manager->pipe] = crtc;
378 368
379 drm_crtc_init(manager->drm_dev, crtc, &exynos_crtc_funcs); 369 ret = drm_crtc_init_with_planes(manager->drm_dev, crtc, plane, NULL,
370 &exynos_crtc_funcs);
371 if (ret < 0)
372 goto err_crtc;
373
380 drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs); 374 drm_crtc_helper_add(crtc, &exynos_crtc_helper_funcs);
381 375
382 exynos_drm_crtc_attach_mode_property(crtc); 376 exynos_drm_crtc_attach_mode_property(crtc);
383 377
384 return 0; 378 return 0;
379
380err_crtc:
381 plane->funcs->destroy(plane);
382err_plane:
383 kfree(exynos_crtc);
384 return ret;
385} 385}
386 386
387int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) 387int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 513ba940bae0..443a2069858a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -85,8 +85,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
85 struct drm_plane *plane; 85 struct drm_plane *plane;
86 unsigned long possible_crtcs = (1 << MAX_CRTC) - 1; 86 unsigned long possible_crtcs = (1 << MAX_CRTC) - 1;
87 87
88 plane = exynos_plane_init(dev, possible_crtcs, false); 88 plane = exynos_plane_init(dev, possible_crtcs,
89 if (!plane) 89 DRM_PLANE_TYPE_OVERLAY);
90 if (IS_ERR(plane))
90 goto err_mode_config_cleanup; 91 goto err_mode_config_cleanup;
91 } 92 }
92 93
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 6fee63c985b8..085b066a9993 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1057,7 +1057,6 @@ static void fimd_unbind(struct device *dev, struct device *master,
1057{ 1057{
1058 struct exynos_drm_manager *mgr = dev_get_drvdata(dev); 1058 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1059 struct fimd_context *ctx = fimd_manager.ctx; 1059 struct fimd_context *ctx = fimd_manager.ctx;
1060 struct drm_crtc *crtc = mgr->crtc;
1061 1060
1062 fimd_dpms(mgr, DRM_MODE_DPMS_OFF); 1061 fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
1063 1062
@@ -1065,8 +1064,6 @@ static void fimd_unbind(struct device *dev, struct device *master,
1065 exynos_dpi_remove(dev); 1064 exynos_dpi_remove(dev);
1066 1065
1067 fimd_mgr_remove(mgr); 1066 fimd_mgr_remove(mgr);
1068
1069 crtc->funcs->destroy(crtc);
1070} 1067}
1071 1068
1072static const struct component_ops fimd_component_ops = { 1069static const struct component_ops fimd_component_ops = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 8371cbd7631d..c7045a663763 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -139,6 +139,8 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
139 overlay->crtc_x, overlay->crtc_y, 139 overlay->crtc_x, overlay->crtc_y,
140 overlay->crtc_width, overlay->crtc_height); 140 overlay->crtc_width, overlay->crtc_height);
141 141
142 plane->crtc = crtc;
143
142 exynos_drm_crtc_plane_mode_set(crtc, overlay); 144 exynos_drm_crtc_plane_mode_set(crtc, overlay);
143 145
144 return 0; 146 return 0;
@@ -187,8 +189,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
187 if (ret < 0) 189 if (ret < 0)
188 return ret; 190 return ret;
189 191
190 plane->crtc = crtc;
191
192 exynos_plane_commit(plane); 192 exynos_plane_commit(plane);
193 exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); 193 exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
194 194
@@ -254,25 +254,26 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane)
254} 254}
255 255
256struct drm_plane *exynos_plane_init(struct drm_device *dev, 256struct drm_plane *exynos_plane_init(struct drm_device *dev,
257 unsigned long possible_crtcs, bool priv) 257 unsigned long possible_crtcs,
258 enum drm_plane_type type)
258{ 259{
259 struct exynos_plane *exynos_plane; 260 struct exynos_plane *exynos_plane;
260 int err; 261 int err;
261 262
262 exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL); 263 exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
263 if (!exynos_plane) 264 if (!exynos_plane)
264 return NULL; 265 return ERR_PTR(-ENOMEM);
265 266
266 err = drm_plane_init(dev, &exynos_plane->base, possible_crtcs, 267 err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs,
267 &exynos_plane_funcs, formats, ARRAY_SIZE(formats), 268 &exynos_plane_funcs, formats,
268 priv); 269 ARRAY_SIZE(formats), type);
269 if (err) { 270 if (err) {
270 DRM_ERROR("failed to initialize plane\n"); 271 DRM_ERROR("failed to initialize plane\n");
271 kfree(exynos_plane); 272 kfree(exynos_plane);
272 return NULL; 273 return ERR_PTR(err);
273 } 274 }
274 275
275 if (priv) 276 if (type == DRM_PLANE_TYPE_PRIMARY)
276 exynos_plane->overlay.zpos = DEFAULT_ZPOS; 277 exynos_plane->overlay.zpos = DEFAULT_ZPOS;
277 else 278 else
278 exynos_plane_attach_zpos_property(&exynos_plane->base); 279 exynos_plane_attach_zpos_property(&exynos_plane->base);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
index 84d464c90d3d..0d1986b115f8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
@@ -17,4 +17,5 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
17void exynos_plane_commit(struct drm_plane *plane); 17void exynos_plane_commit(struct drm_plane *plane);
18void exynos_plane_dpms(struct drm_plane *plane, int mode); 18void exynos_plane_dpms(struct drm_plane *plane, int mode);
19struct drm_plane *exynos_plane_init(struct drm_device *dev, 19struct drm_plane *exynos_plane_init(struct drm_device *dev,
20 unsigned long possible_crtcs, bool priv); 20 unsigned long possible_crtcs,
21 enum drm_plane_type type);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 2e6120b5e74f..d565207040a2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -631,7 +631,6 @@ static int vidi_remove(struct platform_device *pdev)
631 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); 631 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
632 struct vidi_context *ctx = mgr->ctx; 632 struct vidi_context *ctx = mgr->ctx;
633 struct drm_encoder *encoder = ctx->encoder; 633 struct drm_encoder *encoder = ctx->encoder;
634 struct drm_crtc *crtc = mgr->crtc;
635 634
636 if (ctx->raw_edid != (struct edid *)fake_edid_info) { 635 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
637 kfree(ctx->raw_edid); 636 kfree(ctx->raw_edid);
@@ -640,7 +639,6 @@ static int vidi_remove(struct platform_device *pdev)
640 return -EINVAL; 639 return -EINVAL;
641 } 640 }
642 641
643 crtc->funcs->destroy(crtc);
644 encoder->funcs->destroy(encoder); 642 encoder->funcs->destroy(encoder);
645 drm_connector_cleanup(&ctx->connector); 643 drm_connector_cleanup(&ctx->connector);
646 644
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index e8b4ec84b312..a41c84ee3a2d 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1302,15 +1302,12 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
1302static void mixer_unbind(struct device *dev, struct device *master, void *data) 1302static void mixer_unbind(struct device *dev, struct device *master, void *data)
1303{ 1303{
1304 struct exynos_drm_manager *mgr = dev_get_drvdata(dev); 1304 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1305 struct drm_crtc *crtc = mgr->crtc;
1306 1305
1307 dev_info(dev, "remove successful\n"); 1306 dev_info(dev, "remove successful\n");
1308 1307
1309 mixer_mgr_remove(mgr); 1308 mixer_mgr_remove(mgr);
1310 1309
1311 pm_runtime_disable(dev); 1310 pm_runtime_disable(dev);
1312
1313 crtc->funcs->destroy(crtc);
1314} 1311}
1315 1312
1316static const struct component_ops mixer_component_ops = { 1313static const struct component_ops mixer_component_ops = {