1 /* exynos_drm_encoder.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
7 * Seung-Woo Kim <sw0312.kim@samsung.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
16 #include <drm/drm_crtc_helper.h>
18 #include "exynos_drm_drv.h"
19 #include "exynos_drm_encoder.h"
21 #define to_exynos_encoder(x) container_of(x, struct exynos_drm_encoder,\
25 * exynos specific encoder structure.
27 * @drm_encoder: encoder object.
28 * @display: the display structure that maps to this encoder
30 struct exynos_drm_encoder
{
31 struct drm_encoder drm_encoder
;
32 struct exynos_drm_display
*display
;
36 exynos_drm_encoder_mode_fixup(struct drm_encoder
*encoder
,
37 const struct drm_display_mode
*mode
,
38 struct drm_display_mode
*adjusted_mode
)
40 struct drm_device
*dev
= encoder
->dev
;
41 struct exynos_drm_encoder
*exynos_encoder
= to_exynos_encoder(encoder
);
42 struct exynos_drm_display
*display
= exynos_encoder
->display
;
43 struct drm_connector
*connector
;
45 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
46 if (connector
->encoder
!= encoder
)
49 if (display
->ops
->mode_fixup
)
50 display
->ops
->mode_fixup(display
, connector
, mode
,
57 static void exynos_drm_encoder_mode_set(struct drm_encoder
*encoder
,
58 struct drm_display_mode
*mode
,
59 struct drm_display_mode
*adjusted_mode
)
61 struct exynos_drm_encoder
*exynos_encoder
= to_exynos_encoder(encoder
);
62 struct exynos_drm_display
*display
= exynos_encoder
->display
;
64 if (display
->ops
->mode_set
)
65 display
->ops
->mode_set(display
, adjusted_mode
);
68 static void exynos_drm_encoder_enable(struct drm_encoder
*encoder
)
70 struct exynos_drm_encoder
*exynos_encoder
= to_exynos_encoder(encoder
);
71 struct exynos_drm_display
*display
= exynos_encoder
->display
;
73 if (display
->ops
->dpms
)
74 display
->ops
->dpms(display
, DRM_MODE_DPMS_ON
);
76 if (display
->ops
->commit
)
77 display
->ops
->commit(display
);
80 static void exynos_drm_encoder_disable(struct drm_encoder
*encoder
)
82 struct exynos_drm_encoder
*exynos_encoder
= to_exynos_encoder(encoder
);
83 struct exynos_drm_display
*display
= exynos_encoder
->display
;
85 if (display
->ops
->dpms
)
86 display
->ops
->dpms(display
, DRM_MODE_DPMS_OFF
);
89 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs
= {
90 .mode_fixup
= exynos_drm_encoder_mode_fixup
,
91 .mode_set
= exynos_drm_encoder_mode_set
,
92 .enable
= exynos_drm_encoder_enable
,
93 .disable
= exynos_drm_encoder_disable
,
96 static void exynos_drm_encoder_destroy(struct drm_encoder
*encoder
)
98 struct exynos_drm_encoder
*exynos_encoder
= to_exynos_encoder(encoder
);
100 drm_encoder_cleanup(encoder
);
101 kfree(exynos_encoder
);
104 static struct drm_encoder_funcs exynos_encoder_funcs
= {
105 .destroy
= exynos_drm_encoder_destroy
,
108 static unsigned int exynos_drm_encoder_clones(struct drm_encoder
*encoder
)
110 struct drm_encoder
*clone
;
111 struct drm_device
*dev
= encoder
->dev
;
112 struct exynos_drm_encoder
*exynos_encoder
= to_exynos_encoder(encoder
);
113 struct exynos_drm_display
*display
= exynos_encoder
->display
;
114 unsigned int clone_mask
= 0;
117 list_for_each_entry(clone
, &dev
->mode_config
.encoder_list
, head
) {
118 switch (display
->type
) {
119 case EXYNOS_DISPLAY_TYPE_LCD
:
120 case EXYNOS_DISPLAY_TYPE_HDMI
:
121 case EXYNOS_DISPLAY_TYPE_VIDI
:
122 clone_mask
|= (1 << (cnt
++));
132 void exynos_drm_encoder_setup(struct drm_device
*dev
)
134 struct drm_encoder
*encoder
;
136 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
)
137 encoder
->possible_clones
= exynos_drm_encoder_clones(encoder
);
141 exynos_drm_encoder_create(struct drm_device
*dev
,
142 struct exynos_drm_display
*display
,
143 unsigned long possible_crtcs
)
145 struct drm_encoder
*encoder
;
146 struct exynos_drm_encoder
*exynos_encoder
;
151 exynos_encoder
= kzalloc(sizeof(*exynos_encoder
), GFP_KERNEL
);
155 exynos_encoder
->display
= display
;
156 encoder
= &exynos_encoder
->drm_encoder
;
157 encoder
->possible_crtcs
= possible_crtcs
;
159 DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder
->possible_crtcs
);
161 drm_encoder_init(dev
, encoder
, &exynos_encoder_funcs
,
162 DRM_MODE_ENCODER_TMDS
);
164 drm_encoder_helper_add(encoder
, &exynos_encoder_helper_funcs
);
166 DRM_DEBUG_KMS("encoder has been created\n");
171 struct exynos_drm_display
*exynos_drm_get_display(struct drm_encoder
*encoder
)
173 return to_exynos_encoder(encoder
)->display
;