1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <drm/drmP.h>
19#include <drm/drm_crtc.h>
20#include <drm/drm_crtc_helper.h>
21#include <drm/drm_encoder_slave.h>
22
23#include <linux/err.h>
24#include <linux/i2c.h>
25#include <linux/of.h>
26#include <linux/of_platform.h>
27#include <linux/platform_device.h>
28
29#include "xilinx_drm_drv.h"
30#include "xilinx_drm_encoder.h"
31
32struct xilinx_drm_encoder {
33 struct drm_encoder_slave slave;
34 struct device *dev;
35 int dpms;
36};
37
38#define to_xilinx_encoder(x) \
39 container_of(x, struct xilinx_drm_encoder, slave)
40
41
42static void xilinx_drm_encoder_dpms(struct drm_encoder *base_encoder, int dpms)
43{
44 struct xilinx_drm_encoder *encoder;
45 struct drm_encoder_slave *encoder_slave;
46 const struct drm_encoder_slave_funcs *encoder_sfuncs;
47
48 encoder_slave = to_encoder_slave(base_encoder);
49 encoder_sfuncs = encoder_slave->slave_funcs;
50 encoder = to_xilinx_encoder(encoder_slave);
51
52 DRM_DEBUG_KMS("dpms: %d -> %d\n", encoder->dpms, dpms);
53
54 if (encoder->dpms == dpms)
55 return;
56
57 encoder->dpms = dpms;
58 if (encoder_sfuncs->dpms)
59 encoder_sfuncs->dpms(base_encoder, dpms);
60}
61
62
63static bool
64xilinx_drm_encoder_mode_fixup(struct drm_encoder *base_encoder,
65 const struct drm_display_mode *mode,
66 struct drm_display_mode *adjusted_mode)
67{
68 struct drm_encoder_slave *encoder_slave;
69 const struct drm_encoder_slave_funcs *encoder_sfuncs = NULL;
70 bool ret = true;
71
72 encoder_slave = to_encoder_slave(base_encoder);
73 encoder_sfuncs = encoder_slave->slave_funcs;
74 if (encoder_sfuncs->mode_fixup)
75 ret = encoder_sfuncs->mode_fixup(base_encoder, mode,
76 adjusted_mode);
77
78 return ret;
79}
80
81
82static void xilinx_drm_encoder_mode_set(struct drm_encoder *base_encoder,
83 struct drm_display_mode *mode,
84 struct drm_display_mode *adjusted_mode)
85{
86 struct drm_encoder_slave *encoder_slave;
87 const struct drm_encoder_slave_funcs *encoder_sfuncs;
88
89 DRM_DEBUG_KMS("h: %d, v: %d\n",
90 adjusted_mode->hdisplay, adjusted_mode->vdisplay);
91 DRM_DEBUG_KMS("refresh: %d, pclock: %d khz\n",
92 adjusted_mode->vrefresh, adjusted_mode->clock);
93
94 encoder_slave = to_encoder_slave(base_encoder);
95 encoder_sfuncs = encoder_slave->slave_funcs;
96 if (encoder_sfuncs->mode_set)
97 encoder_sfuncs->mode_set(base_encoder, mode, adjusted_mode);
98}
99
100
101static void xilinx_drm_encoder_commit(struct drm_encoder *base_encoder)
102{
103
104 xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_ON);
105}
106
107
108static void xilinx_drm_encoder_prepare(struct drm_encoder *base_encoder)
109{
110 xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_OFF);
111}
112
113
114static struct drm_crtc *
115xilinx_drm_encoder_get_crtc(struct drm_encoder *base_encoder)
116{
117 return base_encoder->crtc;
118}
119
120static const struct drm_encoder_helper_funcs xilinx_drm_encoder_helper_funcs = {
121 .dpms = xilinx_drm_encoder_dpms,
122 .mode_fixup = xilinx_drm_encoder_mode_fixup,
123 .mode_set = xilinx_drm_encoder_mode_set,
124 .prepare = xilinx_drm_encoder_prepare,
125 .commit = xilinx_drm_encoder_commit,
126 .get_crtc = xilinx_drm_encoder_get_crtc,
127};
128
129
130void xilinx_drm_encoder_destroy(struct drm_encoder *base_encoder)
131{
132 struct xilinx_drm_encoder *encoder;
133 struct drm_encoder_slave *encoder_slave;
134
135 encoder_slave = to_encoder_slave(base_encoder);
136 encoder = to_xilinx_encoder(encoder_slave);
137
138
139 xilinx_drm_encoder_dpms(base_encoder, DRM_MODE_DPMS_OFF);
140
141 drm_encoder_cleanup(base_encoder);
142 put_device(encoder->dev);
143}
144
145static const struct drm_encoder_funcs xilinx_drm_encoder_funcs = {
146 .destroy = xilinx_drm_encoder_destroy,
147};
148
149
150struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm,
151 struct device_node *node)
152{
153 struct xilinx_drm_encoder *encoder;
154 struct i2c_client *i2c_slv;
155 struct i2c_driver *i2c_driver;
156 struct drm_i2c_encoder_driver *drm_i2c_driver;
157 struct device_driver *device_driver;
158 struct platform_device *platform_slv;
159 struct platform_driver *platform_driver;
160 struct drm_platform_encoder_driver *drm_platform_driver;
161 int ret = 0;
162
163 encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL);
164 if (!encoder)
165 return ERR_PTR(-ENOMEM);
166
167 encoder->dpms = DRM_MODE_DPMS_OFF;
168
169
170 encoder->slave.base.possible_crtcs = 1;
171 encoder->slave.base.possible_clones = ~0;
172 ret = drm_encoder_init(drm, &encoder->slave.base,
173 &xilinx_drm_encoder_funcs,
174 DRM_MODE_ENCODER_TMDS, NULL);
175 if (ret) {
176 DRM_ERROR("failed to initialize drm encoder\n");
177 return ERR_PTR(ret);
178 }
179
180 drm_encoder_helper_add(&encoder->slave.base,
181 &xilinx_drm_encoder_helper_funcs);
182
183
184 i2c_slv = of_find_i2c_device_by_node(node);
185 if (i2c_slv && i2c_slv->dev.driver) {
186 i2c_driver = to_i2c_driver(i2c_slv->dev.driver);
187 drm_i2c_driver = to_drm_i2c_encoder_driver(i2c_driver);
188 if (!drm_i2c_driver || !drm_i2c_driver->encoder_init) {
189 DRM_DEBUG_KMS("failed to initialize i2c slave\n");
190 ret = -EPROBE_DEFER;
191 goto err_out;
192 }
193
194 encoder->dev = &i2c_slv->dev;
195 ret = drm_i2c_driver->encoder_init(i2c_slv, drm,
196 &encoder->slave);
197 } else {
198 platform_slv = of_find_device_by_node(node);
199 if (!platform_slv) {
200 DRM_DEBUG_KMS("failed to get an encoder slv\n");
201 return ERR_PTR(-EPROBE_DEFER);
202 }
203
204 device_driver = platform_slv->dev.driver;
205 if (!device_driver) {
206 DRM_DEBUG_KMS("failed to get device driver\n");
207 return ERR_PTR(-EPROBE_DEFER);
208 }
209
210 platform_driver = to_platform_driver(device_driver);
211 drm_platform_driver =
212 to_drm_platform_encoder_driver(platform_driver);
213 if (!drm_platform_driver ||
214 !drm_platform_driver->encoder_init) {
215 DRM_DEBUG_KMS("failed to initialize platform slave\n");
216 ret = -EPROBE_DEFER;
217 goto err_out;
218 }
219
220 encoder->dev = &platform_slv->dev;
221 ret = drm_platform_driver->encoder_init(platform_slv, drm,
222 &encoder->slave);
223 }
224
225 if (ret) {
226 DRM_ERROR("failed to initialize encoder slave\n");
227 goto err_out;
228 }
229
230 if (!encoder->slave.slave_funcs) {
231 DRM_ERROR("there's no encoder slave function\n");
232 ret = -ENODEV;
233 goto err_out;
234 }
235
236 return &encoder->slave.base;
237
238err_out:
239 return ERR_PTR(ret);
240}
241