drm/exynos: consolidate driver/device initialization code
[linux-drm-fsl-dcu.git] / drivers / gpu / drm / exynos / exynos_drm_vidi.c
1 /* exynos_drm_vidi.c
2  *
3  * Copyright (C) 2012 Samsung Electronics Co.Ltd
4  * Authors:
5  *      Inki Dae <inki.dae@samsung.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  *
12  */
13 #include <drm/drmP.h>
14
15 #include <linux/kernel.h>
16 #include <linux/platform_device.h>
17 #include <linux/component.h>
18
19 #include <drm/exynos_drm.h>
20
21 #include <drm/drm_edid.h>
22 #include <drm/drm_crtc_helper.h>
23 #include <drm/drm_atomic_helper.h>
24
25 #include "exynos_drm_drv.h"
26 #include "exynos_drm_crtc.h"
27 #include "exynos_drm_plane.h"
28 #include "exynos_drm_encoder.h"
29 #include "exynos_drm_vidi.h"
30
31 /* vidi has totally three virtual windows. */
32 #define WINDOWS_NR              3
33
34 #define ctx_from_connector(c)   container_of(c, struct vidi_context, \
35                                         connector)
36
37 struct vidi_context {
38         struct exynos_drm_display       display;
39         struct platform_device          *pdev;
40         struct drm_device               *drm_dev;
41         struct exynos_drm_crtc          *crtc;
42         struct drm_encoder              *encoder;
43         struct drm_connector            connector;
44         struct exynos_drm_plane         planes[WINDOWS_NR];
45         struct edid                     *raw_edid;
46         unsigned int                    clkdiv;
47         unsigned int                    default_win;
48         unsigned long                   irq_flags;
49         unsigned int                    connected;
50         bool                            vblank_on;
51         bool                            suspended;
52         bool                            direct_vblank;
53         struct work_struct              work;
54         struct mutex                    lock;
55         int                             pipe;
56 };
57
58 static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
59 {
60         return container_of(d, struct vidi_context, display);
61 }
62
63 static const char fake_edid_info[] = {
64         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,
65         0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78,
66         0x0a, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0xbd,
67         0xee, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
68         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x66, 0x21, 0x50, 0xb0, 0x51, 0x00,
69         0x1b, 0x30, 0x40, 0x70, 0x36, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e,
70         0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
71         0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18,
72         0x4b, 0x1a, 0x44, 0x17, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
73         0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47,
74         0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xbc, 0x02, 0x03, 0x1e, 0xf1,
75         0x46, 0x84, 0x05, 0x03, 0x10, 0x20, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83,
76         0x01, 0x00, 0x00, 0xe2, 0x00, 0x0f, 0x67, 0x03, 0x0c, 0x00, 0x10, 0x00,
77         0xb8, 0x2d, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, 0x16, 0x20, 0x58, 0x2c,
78         0x25, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x9e, 0x8c, 0x0a, 0xd0, 0x8a,
79         0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xa0, 0x5a, 0x00, 0x00,
80         0x00, 0x18, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
81         0x45, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
82         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85         0x00, 0x00, 0x00, 0x06
86 };
87
88 static int vidi_enable_vblank(struct exynos_drm_crtc *crtc)
89 {
90         struct vidi_context *ctx = crtc->ctx;
91
92         if (ctx->suspended)
93                 return -EPERM;
94
95         if (!test_and_set_bit(0, &ctx->irq_flags))
96                 ctx->vblank_on = true;
97
98         ctx->direct_vblank = true;
99
100         /*
101          * in case of page flip request, vidi_finish_pageflip function
102          * will not be called because direct_vblank is true and then
103          * that function will be called by crtc_ops->win_commit callback
104          */
105         schedule_work(&ctx->work);
106
107         return 0;
108 }
109
110 static void vidi_disable_vblank(struct exynos_drm_crtc *crtc)
111 {
112         struct vidi_context *ctx = crtc->ctx;
113
114         if (ctx->suspended)
115                 return;
116
117         if (test_and_clear_bit(0, &ctx->irq_flags))
118                 ctx->vblank_on = false;
119 }
120
121 static void vidi_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
122 {
123         struct vidi_context *ctx = crtc->ctx;
124         struct exynos_drm_plane *plane;
125
126         if (ctx->suspended)
127                 return;
128
129         if (win < 0 || win >= WINDOWS_NR)
130                 return;
131
132         plane = &ctx->planes[win];
133
134         plane->enabled = true;
135
136         DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr);
137
138         if (ctx->vblank_on)
139                 schedule_work(&ctx->work);
140 }
141
142 static void vidi_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
143 {
144         struct vidi_context *ctx = crtc->ctx;
145         struct exynos_drm_plane *plane;
146
147         if (win < 0 || win >= WINDOWS_NR)
148                 return;
149
150         plane = &ctx->planes[win];
151         plane->enabled = false;
152
153         /* TODO. */
154 }
155
156 static void vidi_enable(struct exynos_drm_crtc *crtc)
157 {
158         struct vidi_context *ctx = crtc->ctx;
159         struct exynos_drm_plane *plane;
160         int i;
161
162         mutex_lock(&ctx->lock);
163
164         ctx->suspended = false;
165
166         /* if vblank was enabled status, enable it again. */
167         if (test_and_clear_bit(0, &ctx->irq_flags))
168                 vidi_enable_vblank(ctx->crtc);
169
170         for (i = 0; i < WINDOWS_NR; i++) {
171                 plane = &ctx->planes[i];
172                 if (plane->enabled)
173                         vidi_win_commit(ctx->crtc, i);
174         }
175
176         mutex_unlock(&ctx->lock);
177 }
178
179 static void vidi_disable(struct exynos_drm_crtc *crtc)
180 {
181         struct vidi_context *ctx = crtc->ctx;
182
183         mutex_lock(&ctx->lock);
184
185         ctx->suspended = true;
186
187         mutex_unlock(&ctx->lock);
188 }
189
190 static int vidi_ctx_initialize(struct vidi_context *ctx,
191                         struct drm_device *drm_dev)
192 {
193         struct exynos_drm_private *priv = drm_dev->dev_private;
194
195         ctx->drm_dev = drm_dev;
196         ctx->pipe = priv->pipe++;
197
198         return 0;
199 }
200
201 static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
202         .enable = vidi_enable,
203         .disable = vidi_disable,
204         .enable_vblank = vidi_enable_vblank,
205         .disable_vblank = vidi_disable_vblank,
206         .win_commit = vidi_win_commit,
207         .win_disable = vidi_win_disable,
208 };
209
210 static void vidi_fake_vblank_handler(struct work_struct *work)
211 {
212         struct vidi_context *ctx = container_of(work, struct vidi_context,
213                                         work);
214
215         if (ctx->pipe < 0)
216                 return;
217
218         /* refresh rate is about 50Hz. */
219         usleep_range(16000, 20000);
220
221         mutex_lock(&ctx->lock);
222
223         if (ctx->direct_vblank) {
224                 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
225                 ctx->direct_vblank = false;
226                 mutex_unlock(&ctx->lock);
227                 return;
228         }
229
230         mutex_unlock(&ctx->lock);
231
232         exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
233 }
234
235 static int vidi_show_connection(struct device *dev,
236                                 struct device_attribute *attr, char *buf)
237 {
238         struct vidi_context *ctx = dev_get_drvdata(dev);
239         int rc;
240
241         mutex_lock(&ctx->lock);
242
243         rc = sprintf(buf, "%d\n", ctx->connected);
244
245         mutex_unlock(&ctx->lock);
246
247         return rc;
248 }
249
250 static int vidi_store_connection(struct device *dev,
251                                 struct device_attribute *attr,
252                                 const char *buf, size_t len)
253 {
254         struct vidi_context *ctx = dev_get_drvdata(dev);
255         int ret;
256
257         ret = kstrtoint(buf, 0, &ctx->connected);
258         if (ret)
259                 return ret;
260
261         if (ctx->connected > 1)
262                 return -EINVAL;
263
264         /* use fake edid data for test. */
265         if (!ctx->raw_edid)
266                 ctx->raw_edid = (struct edid *)fake_edid_info;
267
268         /* if raw_edid isn't same as fake data then it can't be tested. */
269         if (ctx->raw_edid != (struct edid *)fake_edid_info) {
270                 DRM_DEBUG_KMS("edid data is not fake data.\n");
271                 return -EINVAL;
272         }
273
274         DRM_DEBUG_KMS("requested connection.\n");
275
276         drm_helper_hpd_irq_event(ctx->drm_dev);
277
278         return len;
279 }
280
281 static DEVICE_ATTR(connection, 0644, vidi_show_connection,
282                         vidi_store_connection);
283
284 int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
285                                 struct drm_file *file_priv)
286 {
287         struct vidi_context *ctx = NULL;
288         struct drm_encoder *encoder;
289         struct exynos_drm_display *display;
290         struct drm_exynos_vidi_connection *vidi = data;
291
292         if (!vidi) {
293                 DRM_DEBUG_KMS("user data for vidi is null.\n");
294                 return -EINVAL;
295         }
296
297         if (vidi->connection > 1) {
298                 DRM_DEBUG_KMS("connection should be 0 or 1.\n");
299                 return -EINVAL;
300         }
301
302         list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list,
303                                                                 head) {
304                 display = exynos_drm_get_display(encoder);
305
306                 if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
307                         ctx = display_to_vidi(display);
308                         break;
309                 }
310         }
311
312         if (!ctx) {
313                 DRM_DEBUG_KMS("not found virtual device type encoder.\n");
314                 return -EINVAL;
315         }
316
317         if (ctx->connected == vidi->connection) {
318                 DRM_DEBUG_KMS("same connection request.\n");
319                 return -EINVAL;
320         }
321
322         if (vidi->connection) {
323                 struct edid *raw_edid  = (struct edid *)(uint32_t)vidi->edid;
324                 if (!drm_edid_is_valid(raw_edid)) {
325                         DRM_DEBUG_KMS("edid data is invalid.\n");
326                         return -EINVAL;
327                 }
328                 ctx->raw_edid = drm_edid_duplicate(raw_edid);
329                 if (!ctx->raw_edid) {
330                         DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
331                         return -ENOMEM;
332                 }
333         } else {
334                 /*
335                  * with connection = 0, free raw_edid
336                  * only if raw edid data isn't same as fake data.
337                  */
338                 if (ctx->raw_edid && ctx->raw_edid !=
339                                 (struct edid *)fake_edid_info) {
340                         kfree(ctx->raw_edid);
341                         ctx->raw_edid = NULL;
342                 }
343         }
344
345         ctx->connected = vidi->connection;
346         drm_helper_hpd_irq_event(ctx->drm_dev);
347
348         return 0;
349 }
350
351 static enum drm_connector_status vidi_detect(struct drm_connector *connector,
352                         bool force)
353 {
354         struct vidi_context *ctx = ctx_from_connector(connector);
355
356         /*
357          * connection request would come from user side
358          * to do hotplug through specific ioctl.
359          */
360         return ctx->connected ? connector_status_connected :
361                         connector_status_disconnected;
362 }
363
364 static void vidi_connector_destroy(struct drm_connector *connector)
365 {
366 }
367
368 static struct drm_connector_funcs vidi_connector_funcs = {
369         .dpms = drm_atomic_helper_connector_dpms,
370         .fill_modes = drm_helper_probe_single_connector_modes,
371         .detect = vidi_detect,
372         .destroy = vidi_connector_destroy,
373         .reset = drm_atomic_helper_connector_reset,
374         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
375         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
376 };
377
378 static int vidi_get_modes(struct drm_connector *connector)
379 {
380         struct vidi_context *ctx = ctx_from_connector(connector);
381         struct edid *edid;
382         int edid_len;
383
384         /*
385          * the edid data comes from user side and it would be set
386          * to ctx->raw_edid through specific ioctl.
387          */
388         if (!ctx->raw_edid) {
389                 DRM_DEBUG_KMS("raw_edid is null.\n");
390                 return -EFAULT;
391         }
392
393         edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
394         edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
395         if (!edid) {
396                 DRM_DEBUG_KMS("failed to allocate edid\n");
397                 return -ENOMEM;
398         }
399
400         drm_mode_connector_update_edid_property(connector, edid);
401
402         return drm_add_edid_modes(connector, edid);
403 }
404
405 static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
406 {
407         struct vidi_context *ctx = ctx_from_connector(connector);
408
409         return ctx->encoder;
410 }
411
412 static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
413         .get_modes = vidi_get_modes,
414         .best_encoder = vidi_best_encoder,
415 };
416
417 static int vidi_create_connector(struct exynos_drm_display *display,
418                                 struct drm_encoder *encoder)
419 {
420         struct vidi_context *ctx = display_to_vidi(display);
421         struct drm_connector *connector = &ctx->connector;
422         int ret;
423
424         ctx->encoder = encoder;
425         connector->polled = DRM_CONNECTOR_POLL_HPD;
426
427         ret = drm_connector_init(ctx->drm_dev, connector,
428                         &vidi_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL);
429         if (ret) {
430                 DRM_ERROR("Failed to initialize connector with drm\n");
431                 return ret;
432         }
433
434         drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
435         drm_connector_register(connector);
436         drm_mode_connector_attach_encoder(connector, encoder);
437
438         return 0;
439 }
440
441
442 static struct exynos_drm_display_ops vidi_display_ops = {
443         .create_connector = vidi_create_connector,
444 };
445
446 static int vidi_bind(struct device *dev, struct device *master, void *data)
447 {
448         struct vidi_context *ctx = dev_get_drvdata(dev);
449         struct drm_device *drm_dev = data;
450         struct exynos_drm_plane *exynos_plane;
451         enum drm_plane_type type;
452         unsigned int zpos;
453         int ret;
454
455         vidi_ctx_initialize(ctx, drm_dev);
456
457         for (zpos = 0; zpos < WINDOWS_NR; zpos++) {
458                 type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY :
459                                                 DRM_PLANE_TYPE_OVERLAY;
460                 ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
461                                         1 << ctx->pipe, type, zpos);
462                 if (ret)
463                         return ret;
464         }
465
466         exynos_plane = &ctx->planes[ctx->default_win];
467         ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
468                                            ctx->pipe, EXYNOS_DISPLAY_TYPE_VIDI,
469                                            &vidi_crtc_ops, ctx);
470         if (IS_ERR(ctx->crtc)) {
471                 DRM_ERROR("failed to create crtc.\n");
472                 return PTR_ERR(ctx->crtc);
473         }
474
475         ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
476         if (ret) {
477                 ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
478                 return ret;
479         }
480
481         return 0;
482 }
483
484
485 static void vidi_unbind(struct device *dev, struct device *master, void *data)
486 {
487 }
488
489 static const struct component_ops vidi_component_ops = {
490         .bind   = vidi_bind,
491         .unbind = vidi_unbind,
492 };
493
494 static int vidi_probe(struct platform_device *pdev)
495 {
496         struct vidi_context *ctx;
497         int ret;
498
499         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
500         if (!ctx)
501                 return -ENOMEM;
502
503         ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
504         ctx->display.ops = &vidi_display_ops;
505         ctx->default_win = 0;
506         ctx->pdev = pdev;
507
508         ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
509                                         EXYNOS_DISPLAY_TYPE_VIDI);
510         if (ret)
511                 return ret;
512
513         ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
514                                         ctx->display.type);
515         if (ret)
516                 goto err_del_crtc_component;
517
518         INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
519
520         mutex_init(&ctx->lock);
521
522         platform_set_drvdata(pdev, ctx);
523
524         ret = device_create_file(&pdev->dev, &dev_attr_connection);
525         if (ret < 0) {
526                 DRM_ERROR("failed to create connection sysfs.\n");
527                 goto err_del_conn_component;
528         }
529
530         ret = component_add(&pdev->dev, &vidi_component_ops);
531         if (ret)
532                 goto err_remove_file;
533
534         return ret;
535
536 err_remove_file:
537         device_remove_file(&pdev->dev, &dev_attr_connection);
538 err_del_conn_component:
539         exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
540 err_del_crtc_component:
541         exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
542
543         return ret;
544 }
545
546 static int vidi_remove(struct platform_device *pdev)
547 {
548         struct vidi_context *ctx = platform_get_drvdata(pdev);
549
550         if (ctx->raw_edid != (struct edid *)fake_edid_info) {
551                 kfree(ctx->raw_edid);
552                 ctx->raw_edid = NULL;
553
554                 return -EINVAL;
555         }
556
557         component_del(&pdev->dev, &vidi_component_ops);
558         exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
559         exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
560
561         return 0;
562 }
563
564 struct platform_driver vidi_driver = {
565         .probe          = vidi_probe,
566         .remove         = vidi_remove,
567         .driver         = {
568                 .name   = "exynos-drm-vidi",
569                 .owner  = THIS_MODULE,
570         },
571 };