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>
18 #include <drm/exynos_drm.h>
20 #include <drm/drm_edid.h>
21 #include <drm/drm_crtc_helper.h>
23 #include "exynos_drm_drv.h"
24 #include "exynos_drm_crtc.h"
25 #include "exynos_drm_encoder.h"
26 #include "exynos_drm_vidi.h"
28 /* vidi has totally three virtual windows. */
31 #define ctx_from_connector(c) container_of(c, struct vidi_context, \
34 struct vidi_win_data {
35 unsigned int offset_x;
36 unsigned int offset_y;
37 unsigned int ovl_width;
38 unsigned int ovl_height;
39 unsigned int fb_width;
40 unsigned int fb_height;
43 unsigned int buf_offsize;
44 unsigned int line_size; /* bytes */
49 struct exynos_drm_manager manager;
50 struct exynos_drm_display display;
51 struct drm_device *drm_dev;
52 struct drm_crtc *crtc;
53 struct drm_encoder *encoder;
54 struct drm_connector connector;
55 struct exynos_drm_subdrv subdrv;
56 struct vidi_win_data win_data[WINDOWS_NR];
57 struct edid *raw_edid;
59 unsigned int default_win;
60 unsigned long irq_flags;
61 unsigned int connected;
65 struct work_struct work;
70 static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
72 return container_of(m, struct vidi_context, manager);
75 static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
77 return container_of(d, struct vidi_context, display);
80 static const char fake_edid_info[] = {
81 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,
82 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78,
83 0x0a, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0xbd,
84 0xee, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
85 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x66, 0x21, 0x50, 0xb0, 0x51, 0x00,
86 0x1b, 0x30, 0x40, 0x70, 0x36, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e,
87 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
88 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18,
89 0x4b, 0x1a, 0x44, 0x17, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
90 0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47,
91 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xbc, 0x02, 0x03, 0x1e, 0xf1,
92 0x46, 0x84, 0x05, 0x03, 0x10, 0x20, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83,
93 0x01, 0x00, 0x00, 0xe2, 0x00, 0x0f, 0x67, 0x03, 0x0c, 0x00, 0x10, 0x00,
94 0xb8, 0x2d, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, 0x16, 0x20, 0x58, 0x2c,
95 0x25, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x9e, 0x8c, 0x0a, 0xd0, 0x8a,
96 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xa0, 0x5a, 0x00, 0x00,
97 0x00, 0x18, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
98 0x45, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x06
105 static void vidi_apply(struct exynos_drm_manager *mgr)
107 struct vidi_context *ctx = manager_to_vidi(mgr);
108 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
109 struct vidi_win_data *win_data;
112 for (i = 0; i < WINDOWS_NR; i++) {
113 win_data = &ctx->win_data[i];
114 if (win_data->enabled && (mgr_ops && mgr_ops->win_commit))
115 mgr_ops->win_commit(mgr, i);
118 if (mgr_ops && mgr_ops->commit)
119 mgr_ops->commit(mgr);
122 static void vidi_commit(struct exynos_drm_manager *mgr)
124 struct vidi_context *ctx = manager_to_vidi(mgr);
130 static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
132 struct vidi_context *ctx = manager_to_vidi(mgr);
137 if (!test_and_set_bit(0, &ctx->irq_flags))
138 ctx->vblank_on = true;
140 ctx->direct_vblank = true;
143 * in case of page flip request, vidi_finish_pageflip function
144 * will not be called because direct_vblank is true and then
145 * that function will be called by manager_ops->win_commit callback
147 schedule_work(&ctx->work);
152 static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
154 struct vidi_context *ctx = manager_to_vidi(mgr);
159 if (test_and_clear_bit(0, &ctx->irq_flags))
160 ctx->vblank_on = false;
163 static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
164 struct exynos_drm_overlay *overlay)
166 struct vidi_context *ctx = manager_to_vidi(mgr);
167 struct vidi_win_data *win_data;
169 unsigned long offset;
172 DRM_ERROR("overlay is NULL\n");
177 if (win == DEFAULT_ZPOS)
178 win = ctx->default_win;
180 if (win < 0 || win >= WINDOWS_NR)
183 offset = overlay->fb_x * (overlay->bpp >> 3);
184 offset += overlay->fb_y * overlay->pitch;
186 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
188 win_data = &ctx->win_data[win];
190 win_data->offset_x = overlay->crtc_x;
191 win_data->offset_y = overlay->crtc_y;
192 win_data->ovl_width = overlay->crtc_width;
193 win_data->ovl_height = overlay->crtc_height;
194 win_data->fb_width = overlay->fb_width;
195 win_data->fb_height = overlay->fb_height;
196 win_data->dma_addr = overlay->dma_addr[0] + offset;
197 win_data->bpp = overlay->bpp;
198 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
200 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
203 * some parts of win_data should be transferred to user side
204 * through specific ioctl.
207 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
208 win_data->offset_x, win_data->offset_y);
209 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
210 win_data->ovl_width, win_data->ovl_height);
211 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
212 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
213 overlay->fb_width, overlay->crtc_width);
216 static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
218 struct vidi_context *ctx = manager_to_vidi(mgr);
219 struct vidi_win_data *win_data;
225 if (win == DEFAULT_ZPOS)
226 win = ctx->default_win;
228 if (win < 0 || win >= WINDOWS_NR)
231 win_data = &ctx->win_data[win];
233 win_data->enabled = true;
235 DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr);
238 schedule_work(&ctx->work);
241 static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
243 struct vidi_context *ctx = manager_to_vidi(mgr);
244 struct vidi_win_data *win_data;
247 if (win == DEFAULT_ZPOS)
248 win = ctx->default_win;
250 if (win < 0 || win >= WINDOWS_NR)
253 win_data = &ctx->win_data[win];
254 win_data->enabled = false;
259 static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
261 struct vidi_context *ctx = manager_to_vidi(mgr);
263 DRM_DEBUG_KMS("%s\n", __FILE__);
265 if (enable != false && enable != true)
269 ctx->suspended = false;
271 /* if vblank was enabled status, enable it again. */
272 if (test_and_clear_bit(0, &ctx->irq_flags))
273 vidi_enable_vblank(mgr);
277 ctx->suspended = true;
283 static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
285 struct vidi_context *ctx = manager_to_vidi(mgr);
287 DRM_DEBUG_KMS("%d\n", mode);
289 mutex_lock(&ctx->lock);
292 case DRM_MODE_DPMS_ON:
293 vidi_power_on(mgr, true);
295 case DRM_MODE_DPMS_STANDBY:
296 case DRM_MODE_DPMS_SUSPEND:
297 case DRM_MODE_DPMS_OFF:
298 vidi_power_on(mgr, false);
301 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
305 mutex_unlock(&ctx->lock);
308 static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
309 struct drm_device *drm_dev)
311 struct vidi_context *ctx = manager_to_vidi(mgr);
312 struct exynos_drm_private *priv = drm_dev->dev_private;
314 mgr->drm_dev = ctx->drm_dev = drm_dev;
315 mgr->pipe = ctx->pipe = priv->pipe++;
320 static struct exynos_drm_manager_ops vidi_manager_ops = {
322 .commit = vidi_commit,
323 .enable_vblank = vidi_enable_vblank,
324 .disable_vblank = vidi_disable_vblank,
325 .win_mode_set = vidi_win_mode_set,
326 .win_commit = vidi_win_commit,
327 .win_disable = vidi_win_disable,
330 static void vidi_fake_vblank_handler(struct work_struct *work)
332 struct vidi_context *ctx = container_of(work, struct vidi_context,
338 /* refresh rate is about 50Hz. */
339 usleep_range(16000, 20000);
341 mutex_lock(&ctx->lock);
343 if (ctx->direct_vblank) {
344 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
345 ctx->direct_vblank = false;
346 mutex_unlock(&ctx->lock);
350 mutex_unlock(&ctx->lock);
352 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
355 static int vidi_show_connection(struct device *dev,
356 struct device_attribute *attr, char *buf)
358 struct vidi_context *ctx = dev_get_drvdata(dev);
361 mutex_lock(&ctx->lock);
363 rc = sprintf(buf, "%d\n", ctx->connected);
365 mutex_unlock(&ctx->lock);
370 static int vidi_store_connection(struct device *dev,
371 struct device_attribute *attr,
372 const char *buf, size_t len)
374 struct vidi_context *ctx = dev_get_drvdata(dev);
377 ret = kstrtoint(buf, 0, &ctx->connected);
381 if (ctx->connected > 1)
384 /* use fake edid data for test. */
386 ctx->raw_edid = (struct edid *)fake_edid_info;
388 /* if raw_edid isn't same as fake data then it can't be tested. */
389 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
390 DRM_DEBUG_KMS("edid data is not fake data.\n");
394 DRM_DEBUG_KMS("requested connection.\n");
396 drm_helper_hpd_irq_event(ctx->drm_dev);
401 static DEVICE_ATTR(connection, 0644, vidi_show_connection,
402 vidi_store_connection);
404 int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
405 struct drm_file *file_priv)
407 struct vidi_context *ctx = NULL;
408 struct drm_encoder *encoder;
409 struct exynos_drm_display *display;
410 struct drm_exynos_vidi_connection *vidi = data;
413 DRM_DEBUG_KMS("user data for vidi is null.\n");
417 if (vidi->connection > 1) {
418 DRM_DEBUG_KMS("connection should be 0 or 1.\n");
422 list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list,
424 display = exynos_drm_get_display(encoder);
426 if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
427 ctx = display_to_vidi(display);
433 DRM_DEBUG_KMS("not found virtual device type encoder.\n");
437 if (ctx->connected == vidi->connection) {
438 DRM_DEBUG_KMS("same connection request.\n");
442 if (vidi->connection) {
443 struct edid *raw_edid = (struct edid *)(uint32_t)vidi->edid;
444 if (!drm_edid_is_valid(raw_edid)) {
445 DRM_DEBUG_KMS("edid data is invalid.\n");
448 ctx->raw_edid = drm_edid_duplicate(raw_edid);
449 if (!ctx->raw_edid) {
450 DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
455 * with connection = 0, free raw_edid
456 * only if raw edid data isn't same as fake data.
458 if (ctx->raw_edid && ctx->raw_edid !=
459 (struct edid *)fake_edid_info) {
460 kfree(ctx->raw_edid);
461 ctx->raw_edid = NULL;
465 ctx->connected = vidi->connection;
466 drm_helper_hpd_irq_event(ctx->drm_dev);
471 static enum drm_connector_status vidi_detect(struct drm_connector *connector,
474 struct vidi_context *ctx = ctx_from_connector(connector);
477 * connection request would come from user side
478 * to do hotplug through specific ioctl.
480 return ctx->connected ? connector_status_connected :
481 connector_status_disconnected;
484 static void vidi_connector_destroy(struct drm_connector *connector)
488 static struct drm_connector_funcs vidi_connector_funcs = {
489 .dpms = drm_helper_connector_dpms,
490 .fill_modes = drm_helper_probe_single_connector_modes,
491 .detect = vidi_detect,
492 .destroy = vidi_connector_destroy,
495 static int vidi_get_modes(struct drm_connector *connector)
497 struct vidi_context *ctx = ctx_from_connector(connector);
502 * the edid data comes from user side and it would be set
503 * to ctx->raw_edid through specific ioctl.
505 if (!ctx->raw_edid) {
506 DRM_DEBUG_KMS("raw_edid is null.\n");
510 edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
511 edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
513 DRM_DEBUG_KMS("failed to allocate edid\n");
517 drm_mode_connector_update_edid_property(connector, edid);
519 return drm_add_edid_modes(connector, edid);
522 static struct drm_encoder *vidi_best_encoder(struct drm_connector *connector)
524 struct vidi_context *ctx = ctx_from_connector(connector);
529 static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
530 .get_modes = vidi_get_modes,
531 .best_encoder = vidi_best_encoder,
534 static int vidi_create_connector(struct exynos_drm_display *display,
535 struct drm_encoder *encoder)
537 struct vidi_context *ctx = display_to_vidi(display);
538 struct drm_connector *connector = &ctx->connector;
541 ctx->encoder = encoder;
542 connector->polled = DRM_CONNECTOR_POLL_HPD;
544 ret = drm_connector_init(ctx->drm_dev, connector,
545 &vidi_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL);
547 DRM_ERROR("Failed to initialize connector with drm\n");
551 drm_connector_helper_add(connector, &vidi_connector_helper_funcs);
552 drm_connector_register(connector);
553 drm_mode_connector_attach_encoder(connector, encoder);
559 static struct exynos_drm_display_ops vidi_display_ops = {
560 .create_connector = vidi_create_connector,
563 static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
565 struct vidi_context *ctx = dev_get_drvdata(dev);
566 struct drm_crtc *crtc = ctx->crtc;
569 vidi_mgr_initialize(&ctx->manager, drm_dev);
571 ret = exynos_drm_crtc_create(&ctx->manager);
573 DRM_ERROR("failed to create crtc.\n");
577 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
579 crtc->funcs->destroy(crtc);
580 DRM_ERROR("failed to create encoder and connector.\n");
587 static int vidi_probe(struct platform_device *pdev)
589 struct exynos_drm_subdrv *subdrv;
590 struct vidi_context *ctx;
593 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
597 ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI;
598 ctx->manager.ops = &vidi_manager_ops;
599 ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
600 ctx->display.ops = &vidi_display_ops;
601 ctx->default_win = 0;
603 INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
605 mutex_init(&ctx->lock);
607 platform_set_drvdata(pdev, ctx);
609 subdrv = &ctx->subdrv;
610 subdrv->dev = &pdev->dev;
611 subdrv->probe = vidi_subdrv_probe;
613 ret = exynos_drm_subdrv_register(subdrv);
615 dev_err(&pdev->dev, "failed to register drm vidi device\n");
619 ret = device_create_file(&pdev->dev, &dev_attr_connection);
621 exynos_drm_subdrv_unregister(subdrv);
622 DRM_INFO("failed to create connection sysfs.\n");
628 static int vidi_remove(struct platform_device *pdev)
630 struct vidi_context *ctx = platform_get_drvdata(pdev);
632 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
633 kfree(ctx->raw_edid);
634 ctx->raw_edid = NULL;
642 struct platform_driver vidi_driver = {
644 .remove = vidi_remove,
646 .name = "exynos-drm-vidi",
647 .owner = THIS_MODULE,
651 int exynos_drm_probe_vidi(void)
653 struct platform_device *pdev;
656 pdev = platform_device_register_simple("exynos-drm-vidi", -1, NULL, 0);
658 return PTR_ERR(pdev);
660 ret = platform_driver_register(&vidi_driver);
662 platform_device_unregister(pdev);
669 static int exynos_drm_remove_vidi_device(struct device *dev, void *data)
671 platform_device_unregister(to_platform_device(dev));
676 void exynos_drm_remove_vidi(void)
678 int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL,
679 exynos_drm_remove_vidi_device);
680 /* silence compiler warning */
683 platform_driver_unregister(&vidi_driver);