29
29
#define WINDOWS_NR 3
30
30
31
31
#define get_vidi_mgr (dev ) platform_get_drvdata(to_platform_device(dev))
32
+ #define ctx_from_connector (c ) container_of(c, struct vidi_context, \
33
+ connector)
32
34
33
35
struct vidi_win_data {
34
36
unsigned int offset_x ;
@@ -47,6 +49,8 @@ struct vidi_win_data {
47
49
struct vidi_context {
48
50
struct drm_device * drm_dev ;
49
51
struct drm_crtc * crtc ;
52
+ struct drm_encoder * encoder ;
53
+ struct drm_connector connector ;
50
54
struct vidi_win_data win_data [WINDOWS_NR ];
51
55
struct edid * raw_edid ;
52
56
unsigned int clkdiv ;
@@ -86,60 +90,6 @@ static const char fake_edid_info[] = {
86
90
0x00 , 0x00 , 0x00 , 0x06
87
91
};
88
92
89
- static bool vidi_display_is_connected (struct exynos_drm_display * display )
90
- {
91
- struct vidi_context * ctx = display -> ctx ;
92
-
93
- /*
94
- * connection request would come from user side
95
- * to do hotplug through specific ioctl.
96
- */
97
- return ctx -> connected ? true : false;
98
- }
99
-
100
- static struct edid * vidi_get_edid (struct exynos_drm_display * display ,
101
- struct drm_connector * connector )
102
- {
103
- struct vidi_context * ctx = display -> ctx ;
104
- struct edid * edid ;
105
-
106
- /*
107
- * the edid data comes from user side and it would be set
108
- * to ctx->raw_edid through specific ioctl.
109
- */
110
- if (!ctx -> raw_edid ) {
111
- DRM_DEBUG_KMS ("raw_edid is null.\n" );
112
- return ERR_PTR (- EFAULT );
113
- }
114
-
115
- edid = drm_edid_duplicate (ctx -> raw_edid );
116
- if (!edid ) {
117
- DRM_DEBUG_KMS ("failed to allocate edid\n" );
118
- return ERR_PTR (- ENOMEM );
119
- }
120
-
121
- return edid ;
122
- }
123
-
124
- static int vidi_check_mode (struct exynos_drm_display * display ,
125
- struct drm_display_mode * mode )
126
- {
127
- /* TODO. */
128
-
129
- return 0 ;
130
- }
131
-
132
- static struct exynos_drm_display_ops vidi_display_ops = {
133
- .is_connected = vidi_display_is_connected ,
134
- .get_edid = vidi_get_edid ,
135
- .check_mode = vidi_check_mode ,
136
- };
137
-
138
- static struct exynos_drm_display vidi_display = {
139
- .type = EXYNOS_DISPLAY_TYPE_VIDI ,
140
- .ops = & vidi_display_ops ,
141
- };
142
-
143
93
static void vidi_apply (struct exynos_drm_manager * mgr )
144
94
{
145
95
struct vidi_context * ctx = mgr -> ctx ;
@@ -532,6 +482,110 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
532
482
return 0 ;
533
483
}
534
484
485
+ static enum drm_connector_status vidi_detect (struct drm_connector * connector ,
486
+ bool force )
487
+ {
488
+ struct vidi_context * ctx = ctx_from_connector (connector );
489
+
490
+ /*
491
+ * connection request would come from user side
492
+ * to do hotplug through specific ioctl.
493
+ */
494
+ return ctx -> connected ? connector_status_connected :
495
+ connector_status_disconnected ;
496
+ }
497
+
498
+ static void vidi_connector_destroy (struct drm_connector * connector )
499
+ {
500
+ }
501
+
502
+ static struct drm_connector_funcs vidi_connector_funcs = {
503
+ .dpms = drm_helper_connector_dpms ,
504
+ .fill_modes = drm_helper_probe_single_connector_modes ,
505
+ .detect = vidi_detect ,
506
+ .destroy = vidi_connector_destroy ,
507
+ };
508
+
509
+ static int vidi_get_modes (struct drm_connector * connector )
510
+ {
511
+ struct vidi_context * ctx = ctx_from_connector (connector );
512
+ struct edid * edid ;
513
+ int edid_len ;
514
+
515
+ /*
516
+ * the edid data comes from user side and it would be set
517
+ * to ctx->raw_edid through specific ioctl.
518
+ */
519
+ if (!ctx -> raw_edid ) {
520
+ DRM_DEBUG_KMS ("raw_edid is null.\n" );
521
+ return - EFAULT ;
522
+ }
523
+
524
+ edid_len = (1 + ctx -> raw_edid -> extensions ) * EDID_LENGTH ;
525
+ edid = kmemdup (ctx -> raw_edid , edid_len , GFP_KERNEL );
526
+ if (!edid ) {
527
+ DRM_DEBUG_KMS ("failed to allocate edid\n" );
528
+ return - ENOMEM ;
529
+ }
530
+
531
+ drm_mode_connector_update_edid_property (connector , edid );
532
+
533
+ return drm_add_edid_modes (connector , edid );
534
+ }
535
+
536
+ static int vidi_mode_valid (struct drm_connector * connector ,
537
+ struct drm_display_mode * mode )
538
+ {
539
+ return MODE_OK ;
540
+ }
541
+
542
+ static struct drm_encoder * vidi_best_encoder (struct drm_connector * connector )
543
+ {
544
+ struct vidi_context * ctx = ctx_from_connector (connector );
545
+
546
+ return ctx -> encoder ;
547
+ }
548
+
549
+ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
550
+ .get_modes = vidi_get_modes ,
551
+ .mode_valid = vidi_mode_valid ,
552
+ .best_encoder = vidi_best_encoder ,
553
+ };
554
+
555
+ static int vidi_create_connector (struct exynos_drm_display * display ,
556
+ struct drm_encoder * encoder )
557
+ {
558
+ struct vidi_context * ctx = display -> ctx ;
559
+ struct drm_connector * connector = & ctx -> connector ;
560
+ int ret ;
561
+
562
+ ctx -> encoder = encoder ;
563
+ connector -> polled = DRM_CONNECTOR_POLL_HPD ;
564
+
565
+ ret = drm_connector_init (ctx -> drm_dev , connector ,
566
+ & vidi_connector_funcs , DRM_MODE_CONNECTOR_VIRTUAL );
567
+ if (ret ) {
568
+ DRM_ERROR ("Failed to initialize connector with drm\n" );
569
+ return ret ;
570
+ }
571
+
572
+ drm_connector_helper_add (connector , & vidi_connector_helper_funcs );
573
+ drm_sysfs_connector_add (connector );
574
+ drm_mode_connector_attach_encoder (connector , encoder );
575
+
576
+ return 0 ;
577
+ }
578
+
579
+
580
+ static struct exynos_drm_display_ops vidi_display_ops = {
581
+ .create_connector = vidi_create_connector ,
582
+ };
583
+
584
+ static struct exynos_drm_display vidi_display = {
585
+ .type = EXYNOS_DISPLAY_TYPE_VIDI ,
586
+ .ops = & vidi_display_ops ,
587
+ };
588
+
535
589
static int vidi_probe (struct platform_device * pdev )
536
590
{
537
591
struct device * dev = & pdev -> dev ;
0 commit comments