diff options
author | Patrik Jakobsson <patrik.r.jakobsson@gmail.com> | 2011-12-19 16:41:22 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-20 05:23:15 -0500 |
commit | a12d6a078e47e244a476b67c3f4b6ca03c138a99 (patch) | |
tree | d9196442f0472d7ea582beb9a2c0cf230b75fe80 /drivers/gpu/drm/gma500/cdv_intel_hdmi.c | |
parent | 5736995b473b8853d5ee048c7dfb9c1d20ebf0ea (diff) |
gma500: Convert Cedarview to work with new output handling
Replace psb_intel_output with psb_intel_encoder and psb_intel_connector.
Things will need to be cleaned up and tested so consider this an initial
patch for Cedarview.
Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/gma500/cdv_intel_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_hdmi.c | 112 |
1 files changed, 65 insertions, 47 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index cbca2b0c7d58..50d7cfb51662 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c | |||
@@ -63,8 +63,8 @@ static void cdv_hdmi_mode_set(struct drm_encoder *encoder, | |||
63 | struct drm_display_mode *adjusted_mode) | 63 | struct drm_display_mode *adjusted_mode) |
64 | { | 64 | { |
65 | struct drm_device *dev = encoder->dev; | 65 | struct drm_device *dev = encoder->dev; |
66 | struct psb_intel_output *output = enc_to_psb_intel_output(encoder); | 66 | struct psb_intel_encoder *psb_intel_encoder = to_psb_intel_encoder(encoder); |
67 | struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; | 67 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; |
68 | u32 hdmib; | 68 | u32 hdmib; |
69 | struct drm_crtc *crtc = encoder->crtc; | 69 | struct drm_crtc *crtc = encoder->crtc; |
70 | struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); | 70 | struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); |
@@ -98,8 +98,9 @@ static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
98 | static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode) | 98 | static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode) |
99 | { | 99 | { |
100 | struct drm_device *dev = encoder->dev; | 100 | struct drm_device *dev = encoder->dev; |
101 | struct psb_intel_output *output = enc_to_psb_intel_output(encoder); | 101 | struct psb_intel_encoder *psb_intel_encoder = |
102 | struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; | 102 | to_psb_intel_encoder(encoder); |
103 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; | ||
103 | u32 hdmib; | 104 | u32 hdmib; |
104 | 105 | ||
105 | hdmib = REG_READ(hdmi_priv->hdmi_reg); | 106 | hdmib = REG_READ(hdmi_priv->hdmi_reg); |
@@ -114,8 +115,9 @@ static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
114 | static void cdv_hdmi_save(struct drm_connector *connector) | 115 | static void cdv_hdmi_save(struct drm_connector *connector) |
115 | { | 116 | { |
116 | struct drm_device *dev = connector->dev; | 117 | struct drm_device *dev = connector->dev; |
117 | struct psb_intel_output *output = to_psb_intel_output(connector); | 118 | struct psb_intel_encoder *psb_intel_encoder = |
118 | struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; | 119 | psb_intel_attached_encoder(connector); |
120 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; | ||
119 | 121 | ||
120 | hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg); | 122 | hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg); |
121 | } | 123 | } |
@@ -123,8 +125,9 @@ static void cdv_hdmi_save(struct drm_connector *connector) | |||
123 | static void cdv_hdmi_restore(struct drm_connector *connector) | 125 | static void cdv_hdmi_restore(struct drm_connector *connector) |
124 | { | 126 | { |
125 | struct drm_device *dev = connector->dev; | 127 | struct drm_device *dev = connector->dev; |
126 | struct psb_intel_output *output = to_psb_intel_output(connector); | 128 | struct psb_intel_encoder *psb_intel_encoder = |
127 | struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; | 129 | psb_intel_attached_encoder(connector); |
130 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; | ||
128 | 131 | ||
129 | REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB); | 132 | REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB); |
130 | REG_READ(hdmi_priv->hdmi_reg); | 133 | REG_READ(hdmi_priv->hdmi_reg); |
@@ -133,14 +136,15 @@ static void cdv_hdmi_restore(struct drm_connector *connector) | |||
133 | static enum drm_connector_status cdv_hdmi_detect( | 136 | static enum drm_connector_status cdv_hdmi_detect( |
134 | struct drm_connector *connector, bool force) | 137 | struct drm_connector *connector, bool force) |
135 | { | 138 | { |
136 | struct psb_intel_output *psb_intel_output = | 139 | struct psb_intel_encoder *psb_intel_encoder = |
137 | to_psb_intel_output(connector); | 140 | psb_intel_attached_encoder(connector); |
138 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv; | 141 | struct psb_intel_connector *psb_intel_connector = |
142 | to_psb_intel_connector(connector); | ||
143 | struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv; | ||
139 | struct edid *edid = NULL; | 144 | struct edid *edid = NULL; |
140 | enum drm_connector_status status = connector_status_disconnected; | 145 | enum drm_connector_status status = connector_status_disconnected; |
141 | 146 | ||
142 | edid = drm_get_edid(&psb_intel_output->base, | 147 | edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter); |
143 | psb_intel_output->hdmi_i2c_adapter); | ||
144 | 148 | ||
145 | hdmi_priv->has_hdmi_sink = false; | 149 | hdmi_priv->has_hdmi_sink = false; |
146 | hdmi_priv->has_hdmi_audio = false; | 150 | hdmi_priv->has_hdmi_audio = false; |
@@ -153,7 +157,7 @@ static enum drm_connector_status cdv_hdmi_detect( | |||
153 | drm_detect_monitor_audio(edid); | 157 | drm_detect_monitor_audio(edid); |
154 | } | 158 | } |
155 | 159 | ||
156 | psb_intel_output->base.display_info.raw_edid = NULL; | 160 | psb_intel_connector->base.display_info.raw_edid = NULL; |
157 | kfree(edid); | 161 | kfree(edid); |
158 | } | 162 | } |
159 | return status; | 163 | return status; |
@@ -220,17 +224,15 @@ static int cdv_hdmi_set_property(struct drm_connector *connector, | |||
220 | */ | 224 | */ |
221 | static int cdv_hdmi_get_modes(struct drm_connector *connector) | 225 | static int cdv_hdmi_get_modes(struct drm_connector *connector) |
222 | { | 226 | { |
223 | struct psb_intel_output *psb_intel_output = | 227 | struct psb_intel_encoder *psb_intel_encoder = |
224 | to_psb_intel_output(connector); | 228 | psb_intel_attached_encoder(connector); |
225 | struct edid *edid = NULL; | 229 | struct edid *edid = NULL; |
226 | int ret = 0; | 230 | int ret = 0; |
227 | 231 | ||
228 | edid = drm_get_edid(&psb_intel_output->base, | 232 | edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter); |
229 | psb_intel_output->hdmi_i2c_adapter); | ||
230 | if (edid) { | 233 | if (edid) { |
231 | drm_mode_connector_update_edid_property(&psb_intel_output-> | 234 | drm_mode_connector_update_edid_property(connector, edid); |
232 | base, edid); | 235 | ret = drm_add_edid_modes(connector, edid); |
233 | ret = drm_add_edid_modes(&psb_intel_output->base, edid); | ||
234 | kfree(edid); | 236 | kfree(edid); |
235 | } | 237 | } |
236 | return ret; | 238 | return ret; |
@@ -266,11 +268,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector, | |||
266 | 268 | ||
267 | static void cdv_hdmi_destroy(struct drm_connector *connector) | 269 | static void cdv_hdmi_destroy(struct drm_connector *connector) |
268 | { | 270 | { |
269 | struct psb_intel_output *psb_intel_output = | 271 | struct psb_intel_encoder *psb_intel_encoder = |
270 | to_psb_intel_output(connector); | 272 | psb_intel_attached_encoder(connector); |
271 | 273 | ||
272 | if (psb_intel_output->ddc_bus) | 274 | if (psb_intel_encoder->i2c_bus) |
273 | psb_intel_i2c_destroy(psb_intel_output->ddc_bus); | 275 | psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus); |
274 | drm_sysfs_connector_remove(connector); | 276 | drm_sysfs_connector_remove(connector); |
275 | drm_connector_cleanup(connector); | 277 | drm_connector_cleanup(connector); |
276 | kfree(connector); | 278 | kfree(connector); |
@@ -304,34 +306,45 @@ static const struct drm_connector_funcs cdv_hdmi_connector_funcs = { | |||
304 | void cdv_hdmi_init(struct drm_device *dev, | 306 | void cdv_hdmi_init(struct drm_device *dev, |
305 | struct psb_intel_mode_device *mode_dev, int reg) | 307 | struct psb_intel_mode_device *mode_dev, int reg) |
306 | { | 308 | { |
307 | struct psb_intel_output *psb_intel_output; | 309 | struct psb_intel_encoder *psb_intel_encoder; |
310 | struct psb_intel_connector *psb_intel_connector; | ||
308 | struct drm_connector *connector; | 311 | struct drm_connector *connector; |
309 | struct drm_encoder *encoder; | 312 | struct drm_encoder *encoder; |
310 | struct mid_intel_hdmi_priv *hdmi_priv; | 313 | struct mid_intel_hdmi_priv *hdmi_priv; |
311 | int ddc_bus; | 314 | int ddc_bus; |
312 | 315 | ||
313 | psb_intel_output = kzalloc(sizeof(struct psb_intel_output) + | 316 | psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), |
314 | sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); | 317 | GFP_KERNEL); |
315 | if (!psb_intel_output) | 318 | |
319 | if (!psb_intel_encoder) | ||
316 | return; | 320 | return; |
317 | 321 | ||
318 | hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1); | 322 | psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), |
319 | psb_intel_output->mode_dev = mode_dev; | 323 | GFP_KERNEL); |
320 | connector = &psb_intel_output->base; | 324 | |
321 | encoder = &psb_intel_output->enc; | 325 | if (!psb_intel_connector) |
322 | drm_connector_init(dev, &psb_intel_output->base, | 326 | goto err_connector; |
327 | |||
328 | hdmi_priv = kzalloc(sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); | ||
329 | |||
330 | if (!hdmi_priv) | ||
331 | goto err_priv; | ||
332 | |||
333 | connector = &psb_intel_connector->base; | ||
334 | encoder = &psb_intel_encoder->base; | ||
335 | drm_connector_init(dev, connector, | ||
323 | &cdv_hdmi_connector_funcs, | 336 | &cdv_hdmi_connector_funcs, |
324 | DRM_MODE_CONNECTOR_DVID); | 337 | DRM_MODE_CONNECTOR_DVID); |
325 | 338 | ||
326 | drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs, | 339 | drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs, |
327 | DRM_MODE_ENCODER_TMDS); | 340 | DRM_MODE_ENCODER_TMDS); |
328 | 341 | ||
329 | drm_mode_connector_attach_encoder(&psb_intel_output->base, | 342 | psb_intel_connector_attach_encoder(psb_intel_connector, |
330 | &psb_intel_output->enc); | 343 | psb_intel_encoder); |
331 | psb_intel_output->type = INTEL_OUTPUT_HDMI; | 344 | psb_intel_encoder->type = INTEL_OUTPUT_HDMI; |
332 | hdmi_priv->hdmi_reg = reg; | 345 | hdmi_priv->hdmi_reg = reg; |
333 | hdmi_priv->has_hdmi_sink = false; | 346 | hdmi_priv->has_hdmi_sink = false; |
334 | psb_intel_output->dev_priv = hdmi_priv; | 347 | psb_intel_encoder->dev_priv = hdmi_priv; |
335 | 348 | ||
336 | drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs); | 349 | drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs); |
337 | drm_connector_helper_add(connector, | 350 | drm_connector_helper_add(connector, |
@@ -341,7 +354,8 @@ void cdv_hdmi_init(struct drm_device *dev, | |||
341 | connector->doublescan_allowed = false; | 354 | connector->doublescan_allowed = false; |
342 | 355 | ||
343 | drm_connector_attach_property(connector, | 356 | drm_connector_attach_property(connector, |
344 | dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); | 357 | dev->mode_config.scaling_mode_property, |
358 | DRM_MODE_SCALE_FULLSCREEN); | ||
345 | 359 | ||
346 | switch (reg) { | 360 | switch (reg) { |
347 | case SDVOB: | 361 | case SDVOB: |
@@ -356,21 +370,25 @@ void cdv_hdmi_init(struct drm_device *dev, | |||
356 | break; | 370 | break; |
357 | } | 371 | } |
358 | 372 | ||
359 | psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, | 373 | psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev, |
360 | ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC"); | 374 | ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC"); |
361 | 375 | ||
362 | if (!psb_intel_output->ddc_bus) { | 376 | if (!psb_intel_encoder->i2c_bus) { |
363 | dev_err(dev->dev, "No ddc adapter available!\n"); | 377 | dev_err(dev->dev, "No ddc adapter available!\n"); |
364 | goto failed_ddc; | 378 | goto failed_ddc; |
365 | } | 379 | } |
366 | psb_intel_output->hdmi_i2c_adapter = | 380 | |
367 | &(psb_intel_output->ddc_bus->adapter); | 381 | hdmi_priv->hdmi_i2c_adapter = |
382 | &(psb_intel_encoder->i2c_bus->adapter); | ||
368 | hdmi_priv->dev = dev; | 383 | hdmi_priv->dev = dev; |
369 | drm_sysfs_connector_add(connector); | 384 | drm_sysfs_connector_add(connector); |
370 | return; | 385 | return; |
371 | 386 | ||
372 | failed_ddc: | 387 | failed_ddc: |
373 | drm_encoder_cleanup(&psb_intel_output->enc); | 388 | drm_encoder_cleanup(encoder); |
374 | drm_connector_cleanup(&psb_intel_output->base); | 389 | drm_connector_cleanup(connector); |
375 | kfree(psb_intel_output); | 390 | err_priv: |
391 | kfree(psb_intel_connector); | ||
392 | err_connector: | ||
393 | kfree(psb_intel_encoder); | ||
376 | } | 394 | } |