diff options
Diffstat (limited to 'drivers/gpu/drm/rcar-du/rcar_du_encoder.c')
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index 7c0ec95915ef..34a122a39664 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #include "rcar_du_drv.h" | 20 | #include "rcar_du_drv.h" |
21 | #include "rcar_du_encoder.h" | 21 | #include "rcar_du_encoder.h" |
22 | #include "rcar_du_hdmicon.h" | ||
23 | #include "rcar_du_hdmienc.h" | ||
22 | #include "rcar_du_kms.h" | 24 | #include "rcar_du_kms.h" |
23 | #include "rcar_du_lvdscon.h" | 25 | #include "rcar_du_lvdscon.h" |
24 | #include "rcar_du_lvdsenc.h" | 26 | #include "rcar_du_lvdsenc.h" |
@@ -33,7 +35,7 @@ rcar_du_connector_best_encoder(struct drm_connector *connector) | |||
33 | { | 35 | { |
34 | struct rcar_du_connector *rcon = to_rcar_connector(connector); | 36 | struct rcar_du_connector *rcon = to_rcar_connector(connector); |
35 | 37 | ||
36 | return &rcon->encoder->encoder; | 38 | return rcar_encoder_to_drm_encoder(rcon->encoder); |
37 | } | 39 | } |
38 | 40 | ||
39 | /* ----------------------------------------------------------------------------- | 41 | /* ----------------------------------------------------------------------------- |
@@ -142,10 +144,11 @@ static const struct drm_encoder_funcs encoder_funcs = { | |||
142 | int rcar_du_encoder_init(struct rcar_du_device *rcdu, | 144 | int rcar_du_encoder_init(struct rcar_du_device *rcdu, |
143 | enum rcar_du_encoder_type type, | 145 | enum rcar_du_encoder_type type, |
144 | enum rcar_du_output output, | 146 | enum rcar_du_output output, |
145 | const struct rcar_du_encoder_data *data, | 147 | struct device_node *enc_node, |
146 | struct device_node *np) | 148 | struct device_node *con_node) |
147 | { | 149 | { |
148 | struct rcar_du_encoder *renc; | 150 | struct rcar_du_encoder *renc; |
151 | struct drm_encoder *encoder; | ||
149 | unsigned int encoder_type; | 152 | unsigned int encoder_type; |
150 | int ret; | 153 | int ret; |
151 | 154 | ||
@@ -154,6 +157,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, | |||
154 | return -ENOMEM; | 157 | return -ENOMEM; |
155 | 158 | ||
156 | renc->output = output; | 159 | renc->output = output; |
160 | encoder = rcar_encoder_to_drm_encoder(renc); | ||
157 | 161 | ||
158 | switch (output) { | 162 | switch (output) { |
159 | case RCAR_DU_OUTPUT_LVDS0: | 163 | case RCAR_DU_OUTPUT_LVDS0: |
@@ -175,6 +179,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, | |||
175 | case RCAR_DU_ENCODER_LVDS: | 179 | case RCAR_DU_ENCODER_LVDS: |
176 | encoder_type = DRM_MODE_ENCODER_LVDS; | 180 | encoder_type = DRM_MODE_ENCODER_LVDS; |
177 | break; | 181 | break; |
182 | case RCAR_DU_ENCODER_HDMI: | ||
183 | encoder_type = DRM_MODE_ENCODER_TMDS; | ||
184 | break; | ||
178 | case RCAR_DU_ENCODER_NONE: | 185 | case RCAR_DU_ENCODER_NONE: |
179 | default: | 186 | default: |
180 | /* No external encoder, use the internal encoder type. */ | 187 | /* No external encoder, use the internal encoder type. */ |
@@ -182,23 +189,35 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, | |||
182 | break; | 189 | break; |
183 | } | 190 | } |
184 | 191 | ||
185 | ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, | 192 | if (type == RCAR_DU_ENCODER_HDMI) { |
186 | encoder_type); | 193 | if (renc->lvds) { |
187 | if (ret < 0) | 194 | dev_err(rcdu->dev, |
188 | return ret; | 195 | "Chaining LVDS and HDMI encoders not supported\n"); |
196 | return -EINVAL; | ||
197 | } | ||
189 | 198 | ||
190 | drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); | 199 | ret = rcar_du_hdmienc_init(rcdu, renc, enc_node); |
200 | if (ret < 0) | ||
201 | return ret; | ||
202 | } else { | ||
203 | ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, | ||
204 | encoder_type); | ||
205 | if (ret < 0) | ||
206 | return ret; | ||
191 | 207 | ||
192 | switch (encoder_type) { | 208 | drm_encoder_helper_add(encoder, &encoder_helper_funcs); |
193 | case DRM_MODE_ENCODER_LVDS: { | ||
194 | const struct rcar_du_panel_data *pdata = | ||
195 | data ? &data->connector.lvds.panel : NULL; | ||
196 | return rcar_du_lvds_connector_init(rcdu, renc, pdata, np); | ||
197 | } | 209 | } |
198 | 210 | ||
211 | switch (encoder_type) { | ||
212 | case DRM_MODE_ENCODER_LVDS: | ||
213 | return rcar_du_lvds_connector_init(rcdu, renc, con_node); | ||
214 | |||
199 | case DRM_MODE_ENCODER_DAC: | 215 | case DRM_MODE_ENCODER_DAC: |
200 | return rcar_du_vga_connector_init(rcdu, renc); | 216 | return rcar_du_vga_connector_init(rcdu, renc); |
201 | 217 | ||
218 | case DRM_MODE_ENCODER_TMDS: | ||
219 | return rcar_du_hdmi_connector_init(rcdu, renc); | ||
220 | |||
202 | default: | 221 | default: |
203 | return -EINVAL; | 222 | return -EINVAL; |
204 | } | 223 | } |