3 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 * Inki Dae <inki.dae@samsung.com>
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.
15 #include <linux/kernel.h>
16 #include <linux/platform_device.h>
17 #include <linux/component.h>
19 #include <drm/exynos_drm.h>
21 #include <drm/drm_edid.h>
22 #include <drm/drm_crtc_helper.h>
24 #include "exynos_drm_drv.h"
25 #include "exynos_drm_crtc.h"
26 #include "exynos_drm_encoder.h"
27 #include "exynos_drm_vidi.h"
29 /* vidi has totally three virtual windows. */
32 #define ctx_from_connector(c) container_of(c, struct vidi_context, \
35 struct vidi_win_data {
36 unsigned int offset_x;
37 unsigned int offset_y;
38 unsigned int ovl_width;
39 unsigned int ovl_height;
40 unsigned int fb_width;
41 unsigned int fb_height;
44 unsigned int buf_offsize;
45 unsigned int line_size; /* bytes */
50 struct exynos_drm_manager manager;
51 struct exynos_drm_display display;
52 struct platform_device *pdev;
53 struct drm_device *drm_dev;
54 struct drm_crtc *crtc;
55 struct drm_encoder *encoder;
56 struct drm_connector connector;
57 struct vidi_win_data win_data[WINDOWS_NR];
58 struct edid *raw_edid;
60 unsigned int default_win;
61 unsigned long irq_flags;
62 unsigned int connected;
66 struct work_struct work;
71 static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
73 return container_of(m, struct vidi_context, manager);
76 static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
78 return container_of(d, struct vidi_context, display);
81 static const char fake_edid_info[] = {
82 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,
83 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78,
84 0x0a, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0xbd,
85 0xee, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
86 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x66, 0x21, 0x50, 0xb0, 0x51, 0x00,
87 0x1b, 0x30, 0x40, 0x70, 0x36, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e,
88 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
89 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18,
90 0x4b, 0x1a, 0x44, 0x17, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
91 0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47,
92 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xbc, 0x02, 0x03, 0x1e, 0xf1,
93 0x46, 0x84, 0x05, 0x03, 0x10, 0x20, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83,
94 0x01, 0x00, 0x00, 0xe2, 0x00, 0x0f, 0x67, 0x03, 0x0c, 0x00, 0x10, 0x00,
95 0xb8, 0x2d, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, 0x16, 0x20, 0x58, 0x2c,
96 0x25, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x9e, 0x8c, 0x0a, 0xd0, 0x8a,
97 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xa0, 0x5a, 0x00, 0x00,
98 0x00, 0x18, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
99 0x45, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x06
106 static void vidi_apply(struct exynos_drm_manager *mgr)
108 struct vidi_context *ctx = manager_to_vidi(mgr);
109 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
110 struct vidi_win_data *win_data;
113 for (i = 0; i < WINDOWS_NR; i++) {
114 win_data = &ctx->win_data[i];
115 if (win_data->enabled && (mgr_ops && mgr_ops->win_commit))
116 mgr_ops->win_commit(mgr, i);
119 if (mgr_ops && mgr_ops->commit)
120 mgr_ops->commit(mgr);
123 static void vidi_commit(struct exynos_drm_manager *mgr)
125 struct vidi_context *ctx = manager_to_vidi(mgr);
131 static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
133 struct vidi_context *ctx = manager_to_vidi(mgr);
138 if (!test_and_set_bit(0, &ctx->irq_flags))
139 ctx->vblank_on = true;
141 ctx->direct_vblank = true;
144 * in case of page flip request, vidi_finish_pageflip function
145 * will not be called because direct_vblank is true and then
146 * that function will be called by manager_ops->win_commit callback
148 schedule_work(&ctx->work);
153 static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
155 struct vidi_context *ctx = manager_to_vidi(mgr);
160 if (test_and_clear_bit(0, &ctx->irq_flags))
161 ctx->vblank_on = false;
164 static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
165 struct exynos_drm_overlay *overlay)
167 struct vidi_context *ctx = manager_to_vidi(mgr);
168 struct vidi_win_data *win_data;
170 unsigned long offset;
173 DRM_ERROR("overlay is NULL\n");
178 if (win == DEFAULT_ZPOS)
179 win = ctx->default_win;
181 if (win < 0 || win >= WINDOWS_NR)
184 offset = overlay->fb_x * (overlay->bpp >> 3);
185 offset += overlay->fb_y * overlay->pitch;
187 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
189 win_data = &ctx->win_data[win];
191 win_data->offset_x = overlay->crtc_x;
192 win_data->offset_y = overlay->crtc_y;
193 win_data->ovl_width = overlay->crtc_width;
194 win_data->ovl_height = overlay->crtc_height;
195 win_data->fb_width = overlay->fb_width;
196 win_data->fb_height = overlay->fb_height;
197 win_data->dma_addr = overlay->dma_addr[0] + offset;
198 win_data->bpp = overlay->bpp;
199 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
201 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
204 * some parts of win_data should be transferred to user side
205 * through specific ioctl.
208 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
209 win_data->offset_x, win_data->offset_y);
210 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
211 win_data->ovl_width, win_data->ovl_height);
212 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
213 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
214 overlay->fb_width, overlay->crtc_width);
217 static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
219 struct vidi_context *ctx = manager_to_vidi(mgr);
220 struct vidi_win_data *win_data;
226 if (win == DEFAULT_ZPOS)
227 win = ctx->default_win;
229 if (win < 0 || win >= WINDOWS_NR)
232 win_data = &ctx->win_data[win];
234 win_data->enabled = true;
236 DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr);
239 schedule_work(&ctx->work);
242 static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
244 struct vidi_context *ctx = manager_to_vidi(mgr);
245 struct vidi_win_data *win_data;
248 if (win == DEFAULT_ZPOS)
249 win = ctx->default_win;
251 if (win < 0 || win >= WINDOWS_NR)
254 win_data = &ctx->win_data[win];
255 win_data->enabled = false;
260 static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
262 struct vidi_context *ctx = manager_to_vidi(mgr);
264 DRM_DEBUG_KMS("%s\n", __FILE__);
266 if (enable != false && enable != true)
270 ctx->suspended = false;
272 /* if vblank was enabled status, enable it again. */
273 if (test_and_clear_bit(0, &ctx->irq_flags))
274 vidi_enable_vblank(mgr);
278 ctx->suspended = true;
284 static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
286 struct vidi_context *ctx = manager_to_vidi(mgr);
288 DRM_DEBUG_KMS("%d\n", mode);
290 mutex_lock(&ctx->lock);
293 case DRM_MODE_DPMS_ON:
294 vidi_power_on(mgr, true);
296 case DRM_MODE_DPMS_STANDBY:
297 case DRM_MODE_DPMS_SUSPEND:
298 case DRM_MODE_DPMS_OFF:
299 vidi_power_on(mgr, false);
302 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
306 mutex_unlock(&ctx->lock);
309 static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
310 struct drm_device *drm_dev)
312 struct vidi_context *ctx = manager_to_vidi(mgr);
313 struct exynos_drm_private *priv = drm_dev->dev_private;
315 mgr->drm_dev = ctx->drm_dev = drm_dev;
316 mgr->pipe = ctx->pipe = priv->pipe++;
321 static struct exynos_drm_manager_ops vidi_manager_ops = {
323 .commit = vidi_commit,
324 .enable_vblank = vidi_enable_vblank,
325 .disable_vblank = vidi_disable_vblank,
326 .win_mode_set = vidi_win_mode_set,
327 .win_commit = vidi_win_commit,
328 .win_disable = vidi_win_disable,
331 static void vidi_fake_vblank_handler(struct work_struct *work)
333 struct vidi_context *ctx = container_of(work, struct vidi_context,
339 /* refresh rate is about 50Hz. */
340 usleep_range(16000, 20000);
342 mutex_lock(&ctx->lock);
344 if (ctx->direct_vblank) {
345 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
346 ctx->direct_vblank = false;
347 mutex_unlock(&ctx->lock);
351 mutex_unlock(&ctx->lock);
353 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
356 static int vidi_show_connection(struct device *dev,
357 struct device_attribute *attr, char *buf)
359 struct vidi_context *ctx = dev_get_drvdata(dev);
362 mutex_lock(&ctx->lock);
364 rc = sprintf(buf, "%d\n", ctx->connected);
366 mutex_unlock(&ctx->lock);
371 static int vidi_store_connection(struct device *dev,
372 struct device_attribute *attr,
373 const char *buf, size_t len)
375 struct vidi_context *ctx = dev_get_drvdata(dev);
378 ret = kstrtoint(buf, 0, &ctx->connected);
382 if (ctx->connected > 1)
385 /* use fake edid data for test. */
387 ctx->raw_edid = (struct edid *)fake_edid_info;
389 /* if raw_edid isn't same as fake data then it can't be tested. */
390 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
391 DRM_DEBUG_KMS("edid data is not fake data.\n");
395 DRM_DEBUG_KMS("requested connection.\n");
397 drm_helper_hpd_irq_event(ctx->drm_dev);
402 static DEVICE_ATTR(connection, 0644, vidi_show_connection,
403 vidi_store_connection);
405 int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
406 struct drm_file *file_priv)
408 struct vidi_context *ctx = NULL;
409 struct drm_encoder *encoder;
410 struct exynos_drm_display *display;
411 struct drm_exynos_vidi_connection *vidi = data;
414 DRM_DEBUG_KMS("user data for vidi is null.\n");
418 if (vidi->connection > 1) {
419 DRM_DEBUG_KMS("connection should be 0 or 1.\n");
423 list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list,
425 display = exynos_drm_get_display(encoder);
427 if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
428 ctx = display_to_vidi(display);
434 DRM_DEBUG_KMS("not found virtual device type encoder.\n");
438 if (ctx->connected == vidi->connection) {
439 DRM_DEBUG_KMS("same connection request.\n");
443 if (vidi->connection) {
444 struct edid *raw_edid = (struct edid *)(uint32_t)vidi->edid;
445 if (!drm_edid_is_valid(raw_edid)) {
446 DRM_DEBUG_KMS("edid data is invalid.\n");
449 ctx->raw_edid = drm_edid_duplicate(raw_edid);
450 if (!ctx->raw_edid) {
451 DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
456 * with connection = 0, free raw_edid
457 * only if raw edid data isn't same as fake data.
459 if (ctx->raw_edid && ctx->raw_edid !=
460 (struct edid *)fake_edid_info) {
461 kfree(ctx->raw_edid);
462 ctx->raw_edid = NULL;
466 ctx->connected = vidi->connection;
467 drm_helper_hpd_irq_event(ctx->drm_dev);
472 static enum drm_connector_status vidi_detect(struct drm_connector *connector,
475 struct vidi_context *ctx = ctx_from_connector(connector);
478 * connection request would come from user side
479 * to do hotplug through specific ioctl.
481 return ctx->connected ? connector_status_connected :
482 connector_status_disconnected;
485 static void vidi_connector_destroy(struct drm_connector *connector)
489 static struct drm_connector_funcs vidi_connector_funcs = {
490 .dpms = drm_helper_connector_dpms,
491 .fill_modes = drm_helper_probe_single_connector_modes,
492 .detect = vidi_detect,
493 .destroy = vidi_connector_destroy,
496 static int vidi_get_modes(struct drm_connector *connector)
498 struct vidi_context *ctx = ctx_from_connector(connector);
503 * the edid data comes from user side and it would be set
504 * to ctx->raw_edid through specific ioctl.
506 if (!ctx->raw_edid) {
507 DRM_DEBUG_KMS("raw_edid is null.\n");
511 edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
512 edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
514 DRM_DEBUG_KMS("failed to allocate edid\n");
518 drm_mode_connector_update_edid_property(connector, edid);
520 return drm_add_edid_modes(connector, edid);
523 static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
525 struct vidi_context *ctx = ctx_from_connector(connector);
530 static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
531 .get_modes = vidi_get_modes,
532 .best_encoder = vidi_best_encoder,
535 static int vidi_create_connector(struct exynos_drm_display *display,
536 struct drm_encoder *encoder)
538 struct vidi_context *ctx = display_to_vidi(display);
539 struct drm_connector *connector = &ctx->connector;
542 ctx->encoder = encoder;
543 connector->polled = DRM_CONNECTOR_POLL_HPD;
545 ret = drm_connector_init(ctx->drm_dev, connector,
546 &vidi_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL);
548 DRM_ERROR("Failed to initialize connector with drm\n");
552 drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
553 drm_connector_register(connector);
554 drm_mode_connector_attach_encoder(connector, encoder);
560 static struct exynos_drm_display_ops vidi_display_ops = {
561 .create_connector = vidi_create_connector,
564 static int vidi_bind(struct device *dev, struct device *master, void *data)
566 struct vidi_context *ctx = dev_get_drvdata(dev);
567 struct drm_device *drm_dev = data;
568 struct drm_crtc *crtc = ctx->crtc;
571 vidi_mgr_initialize(&ctx->manager, drm_dev);
573 ret = exynos_drm_crtc_create(&ctx->manager);
575 DRM_ERROR("failed to create crtc.\n");
579 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
581 crtc->funcs->destroy(crtc);
582 DRM_ERROR("failed to create encoder and connector.\n");
590 static void vidi_unbind(struct device *dev, struct device *master, void *data)
594 static const struct component_ops vidi_component_ops = {
596 .unbind = vidi_unbind,
599 static int vidi_probe(struct platform_device *pdev)
601 struct vidi_context *ctx;
604 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
608 ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI;
609 ctx->manager.ops = &vidi_manager_ops;
610 ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
611 ctx->display.ops = &vidi_display_ops;
612 ctx->default_win = 0;
615 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
620 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
623 goto err_del_crtc_component;
625 INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
627 mutex_init(&ctx->lock);
629 platform_set_drvdata(pdev, ctx);
631 ret = device_create_file(&pdev->dev, &dev_attr_connection);
633 DRM_ERROR("failed to create connection sysfs.\n");
634 goto err_del_conn_component;
637 ret = component_add(&pdev->dev, &vidi_component_ops);
639 goto err_remove_file;
644 device_remove_file(&pdev->dev, &dev_attr_connection);
645 err_del_conn_component:
646 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
647 err_del_crtc_component:
648 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
653 static int vidi_remove(struct platform_device *pdev)
655 struct vidi_context *ctx = platform_get_drvdata(pdev);
657 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
658 kfree(ctx->raw_edid);
659 ctx->raw_edid = NULL;
664 component_del(&pdev->dev, &vidi_component_ops);
665 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
666 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
671 struct platform_driver vidi_driver = {
673 .remove = vidi_remove,
675 .name = "exynos-drm-vidi",
676 .owner = THIS_MODULE,
680 int exynos_drm_probe_vidi(void)
682 struct platform_device *pdev;
685 pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0);
687 return PTR_ERR(pdev);
689 ret = platform_driver_register(&vidi_driver);
691 platform_device_unregister(pdev);
698 static int exynos_drm_remove_vidi_device(struct device *dev, void *data)
700 platform_device_unregister(to_platform_device(dev));
705 void exynos_drm_remove_vidi(void)
707 int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL,
708 exynos_drm_remove_vidi_device);
709 /* silence compiler warning */
712 platform_driver_unregister(&vidi_driver);