aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dvo.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-04-19 23:11:45 -0400
committerDave Airlie <airlied@redhat.com>2010-04-19 23:11:45 -0400
commit97921a5b03d40681b3aed620a5e719710336c6df (patch)
tree33d6badc2afb50e87cbd232549c7708596ac12a7 /drivers/gpu/drm/i915/intel_dvo.c
parent01bf0b64579ead8a82e7cfc32ae44bc667e7ad0f (diff)
parente15831656778d032f3c7655949f8cc3997f2b04a (diff)
Merge remote branch 'anholt/drm-intel-next' of /home/airlied/kernel/drm-next into drm-core-next
* 'anholt/drm-intel-next' of /home/airlied/kernel/drm-next: (48 commits) agp/intel-gtt: kill previous_size assignments agp/intel-gtt: kill intel_i830_tlbflush agp/intel: split out gmch/gtt probe, part 1 agp/intel: kill mutli_gmch_chip agp/intel: uncoditionally reconfigure driver on resume agp/intel: split out the GTT support agp/intel: introduce intel-agp.h header file drm/i915: Don't touch PORT_HOTPLUG_EN in intel_dp_detect() drm/i915/pch: Use minimal number of FDI lanes (v2) drm/i915: Add the support of memory self-refresh on Ironlake drm/i915: Move Pineview CxSR and watermark code into update_wm hook. drm/i915: Only save/restore FBC on the platform that supports FBC drm/i915: Fix the incorrect argument for SDVO SET_TV_format command drm/i915: Add support of SDVO on Ibexpeak PCH drm/i915: Don't enable pipe/plane/VCO early (wait for DPMS on). drm/i915: do not read uninitialized ->dev_private Revert "drm/i915: Use a dmi quirk to skip a broken SDVO TV output." drm/i915: implement multifunction SDVO device support drm/i915: remove unused intel_pipe_get_connector() drm/i915: remove connector object in old output structure ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c103
1 files changed, 35 insertions, 68 deletions
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index ebf213c96b9c..227feca7cf8d 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -96,39 +96,11 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
96 } 96 }
97} 97}
98 98
99static void intel_dvo_save(struct drm_connector *connector)
100{
101 struct drm_i915_private *dev_priv = connector->dev->dev_private;
102 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
103 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
104
105 /* Each output should probably just save the registers it touches,
106 * but for now, use more overkill.
107 */
108 dev_priv->saveDVOA = I915_READ(DVOA);
109 dev_priv->saveDVOB = I915_READ(DVOB);
110 dev_priv->saveDVOC = I915_READ(DVOC);
111
112 dvo->dev_ops->save(dvo);
113}
114
115static void intel_dvo_restore(struct drm_connector *connector)
116{
117 struct drm_i915_private *dev_priv = connector->dev->dev_private;
118 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
119 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
120
121 dvo->dev_ops->restore(dvo);
122
123 I915_WRITE(DVOA, dev_priv->saveDVOA);
124 I915_WRITE(DVOB, dev_priv->saveDVOB);
125 I915_WRITE(DVOC, dev_priv->saveDVOC);
126}
127
128static int intel_dvo_mode_valid(struct drm_connector *connector, 99static int intel_dvo_mode_valid(struct drm_connector *connector,
129 struct drm_display_mode *mode) 100 struct drm_display_mode *mode)
130{ 101{
131 struct intel_encoder *intel_encoder = to_intel_encoder(connector); 102 struct drm_encoder *encoder = intel_attached_encoder(connector);
103 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
132 struct intel_dvo_device *dvo = intel_encoder->dev_priv; 104 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
133 105
134 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 106 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -241,7 +213,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
241 */ 213 */
242static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) 214static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
243{ 215{
244 struct intel_encoder *intel_encoder = to_intel_encoder(connector); 216 struct drm_encoder *encoder = intel_attached_encoder(connector);
217 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
245 struct intel_dvo_device *dvo = intel_encoder->dev_priv; 218 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
246 219
247 return dvo->dev_ops->detect(dvo); 220 return dvo->dev_ops->detect(dvo);
@@ -249,7 +222,8 @@ static enum drm_connector_status intel_dvo_detect(struct drm_connector *connecto
249 222
250static int intel_dvo_get_modes(struct drm_connector *connector) 223static int intel_dvo_get_modes(struct drm_connector *connector)
251{ 224{
252 struct intel_encoder *intel_encoder = to_intel_encoder(connector); 225 struct drm_encoder *encoder = intel_attached_encoder(connector);
226 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
253 struct intel_dvo_device *dvo = intel_encoder->dev_priv; 227 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
254 228
255 /* We should probably have an i2c driver get_modes function for those 229 /* We should probably have an i2c driver get_modes function for those
@@ -257,7 +231,7 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
257 * (TV-out, for example), but for now with just TMDS and LVDS, 231 * (TV-out, for example), but for now with just TMDS and LVDS,
258 * that's not the case. 232 * that's not the case.
259 */ 233 */
260 intel_ddc_get_modes(intel_encoder); 234 intel_ddc_get_modes(connector, intel_encoder->ddc_bus);
261 if (!list_empty(&connector->probed_modes)) 235 if (!list_empty(&connector->probed_modes))
262 return 1; 236 return 1;
263 237
@@ -275,38 +249,10 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
275 249
276static void intel_dvo_destroy (struct drm_connector *connector) 250static void intel_dvo_destroy (struct drm_connector *connector)
277{ 251{
278 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
279 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
280
281 if (dvo) {
282 if (dvo->dev_ops->destroy)
283 dvo->dev_ops->destroy(dvo);
284 if (dvo->panel_fixed_mode)
285 kfree(dvo->panel_fixed_mode);
286 /* no need, in i830_dvoices[] now */
287 //kfree(dvo);
288 }
289 if (intel_encoder->i2c_bus)
290 intel_i2c_destroy(intel_encoder->i2c_bus);
291 if (intel_encoder->ddc_bus)
292 intel_i2c_destroy(intel_encoder->ddc_bus);
293 drm_sysfs_connector_remove(connector); 252 drm_sysfs_connector_remove(connector);
294 drm_connector_cleanup(connector); 253 drm_connector_cleanup(connector);
295 kfree(intel_encoder); 254 kfree(connector);
296}
297
298#ifdef RANDR_GET_CRTC_INTERFACE
299static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
300{
301 struct drm_device *dev = connector->dev;
302 struct drm_i915_private *dev_priv = dev->dev_private;
303 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
304 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
305 int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
306
307 return intel_pipe_to_crtc(pScrn, pipe);
308} 255}
309#endif
310 256
311static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { 257static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
312 .dpms = intel_dvo_dpms, 258 .dpms = intel_dvo_dpms,
@@ -318,8 +264,6 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
318 264
319static const struct drm_connector_funcs intel_dvo_connector_funcs = { 265static const struct drm_connector_funcs intel_dvo_connector_funcs = {
320 .dpms = drm_helper_connector_dpms, 266 .dpms = drm_helper_connector_dpms,
321 .save = intel_dvo_save,
322 .restore = intel_dvo_restore,
323 .detect = intel_dvo_detect, 267 .detect = intel_dvo_detect,
324 .destroy = intel_dvo_destroy, 268 .destroy = intel_dvo_destroy,
325 .fill_modes = drm_helper_probe_single_connector_modes, 269 .fill_modes = drm_helper_probe_single_connector_modes,
@@ -328,12 +272,26 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
328static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { 272static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
329 .mode_valid = intel_dvo_mode_valid, 273 .mode_valid = intel_dvo_mode_valid,
330 .get_modes = intel_dvo_get_modes, 274 .get_modes = intel_dvo_get_modes,
331 .best_encoder = intel_best_encoder, 275 .best_encoder = intel_attached_encoder,
332}; 276};
333 277
334static void intel_dvo_enc_destroy(struct drm_encoder *encoder) 278static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
335{ 279{
280 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
281 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
282
283 if (dvo) {
284 if (dvo->dev_ops->destroy)
285 dvo->dev_ops->destroy(dvo);
286 if (dvo->panel_fixed_mode)
287 kfree(dvo->panel_fixed_mode);
288 }
289 if (intel_encoder->i2c_bus)
290 intel_i2c_destroy(intel_encoder->i2c_bus);
291 if (intel_encoder->ddc_bus)
292 intel_i2c_destroy(intel_encoder->ddc_bus);
336 drm_encoder_cleanup(encoder); 293 drm_encoder_cleanup(encoder);
294 kfree(intel_encoder);
337} 295}
338 296
339static const struct drm_encoder_funcs intel_dvo_enc_funcs = { 297static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
@@ -352,7 +310,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
352{ 310{
353 struct drm_device *dev = connector->dev; 311 struct drm_device *dev = connector->dev;
354 struct drm_i915_private *dev_priv = dev->dev_private; 312 struct drm_i915_private *dev_priv = dev->dev_private;
355 struct intel_encoder *intel_encoder = to_intel_encoder(connector); 313 struct drm_encoder *encoder = intel_attached_encoder(connector);
314 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
356 struct intel_dvo_device *dvo = intel_encoder->dev_priv; 315 struct intel_dvo_device *dvo = intel_encoder->dev_priv;
357 uint32_t dvo_reg = dvo->dvo_reg; 316 uint32_t dvo_reg = dvo->dvo_reg;
358 uint32_t dvo_val = I915_READ(dvo_reg); 317 uint32_t dvo_val = I915_READ(dvo_reg);
@@ -384,6 +343,7 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
384void intel_dvo_init(struct drm_device *dev) 343void intel_dvo_init(struct drm_device *dev)
385{ 344{
386 struct intel_encoder *intel_encoder; 345 struct intel_encoder *intel_encoder;
346 struct intel_connector *intel_connector;
387 struct intel_dvo_device *dvo; 347 struct intel_dvo_device *dvo;
388 struct i2c_adapter *i2cbus = NULL; 348 struct i2c_adapter *i2cbus = NULL;
389 int ret = 0; 349 int ret = 0;
@@ -393,6 +353,12 @@ void intel_dvo_init(struct drm_device *dev)
393 if (!intel_encoder) 353 if (!intel_encoder)
394 return; 354 return;
395 355
356 intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
357 if (!intel_connector) {
358 kfree(intel_encoder);
359 return;
360 }
361
396 /* Set up the DDC bus */ 362 /* Set up the DDC bus */
397 intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); 363 intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
398 if (!intel_encoder->ddc_bus) 364 if (!intel_encoder->ddc_bus)
@@ -400,7 +366,7 @@ void intel_dvo_init(struct drm_device *dev)
400 366
401 /* Now, try to find a controller */ 367 /* Now, try to find a controller */
402 for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { 368 for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
403 struct drm_connector *connector = &intel_encoder->base; 369 struct drm_connector *connector = &intel_connector->base;
404 int gpio; 370 int gpio;
405 371
406 dvo = &intel_dvo_devices[i]; 372 dvo = &intel_dvo_devices[i];
@@ -471,7 +437,7 @@ void intel_dvo_init(struct drm_device *dev)
471 drm_encoder_helper_add(&intel_encoder->enc, 437 drm_encoder_helper_add(&intel_encoder->enc,
472 &intel_dvo_helper_funcs); 438 &intel_dvo_helper_funcs);
473 439
474 drm_mode_connector_attach_encoder(&intel_encoder->base, 440 drm_mode_connector_attach_encoder(&intel_connector->base,
475 &intel_encoder->enc); 441 &intel_encoder->enc);
476 if (dvo->type == INTEL_DVO_CHIP_LVDS) { 442 if (dvo->type == INTEL_DVO_CHIP_LVDS) {
477 /* For our LVDS chipsets, we should hopefully be able 443 /* For our LVDS chipsets, we should hopefully be able
@@ -496,4 +462,5 @@ void intel_dvo_init(struct drm_device *dev)
496 intel_i2c_destroy(i2cbus); 462 intel_i2c_destroy(i2cbus);
497free_intel: 463free_intel:
498 kfree(intel_encoder); 464 kfree(intel_encoder);
465 kfree(intel_connector);
499} 466}