gma500: Add support for Cedarview
[linux-2.6.git] / drivers / gpu / drm / gma500 / cdv_intel_lvds.c
1 /*
2  * Copyright © 2006-2011 Intel Corporation
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16  *
17  * Authors:
18  *      Eric Anholt <eric@anholt.net>
19  *      Dave Airlie <airlied@linux.ie>
20  *      Jesse Barnes <jesse.barnes@intel.com>
21  */
22
23 #include <linux/i2c.h>
24 #include <linux/dmi.h>
25 #include <drm/drmP.h>
26
27 #include "intel_bios.h"
28 #include "psb_drv.h"
29 #include "psb_intel_drv.h"
30 #include "psb_intel_reg.h"
31 #include "power.h"
32 #include <linux/pm_runtime.h>
33 #include "cdv_device.h"
34
35 /**
36  * LVDS I2C backlight control macros
37  */
38 #define BRIGHTNESS_MAX_LEVEL 100
39 #define BRIGHTNESS_MASK 0xFF
40 #define BLC_I2C_TYPE    0x01
41 #define BLC_PWM_TYPT    0x02
42
43 #define BLC_POLARITY_NORMAL 0
44 #define BLC_POLARITY_INVERSE 1
45
46 #define PSB_BLC_MAX_PWM_REG_FREQ       (0xFFFE)
47 #define PSB_BLC_MIN_PWM_REG_FREQ        (0x2)
48 #define PSB_BLC_PWM_PRECISION_FACTOR    (10)
49 #define PSB_BACKLIGHT_PWM_CTL_SHIFT     (16)
50 #define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
51
52 struct cdv_intel_lvds_priv {
53         /**
54          * Saved LVDO output states
55          */
56         uint32_t savePP_ON;
57         uint32_t savePP_OFF;
58         uint32_t saveLVDS;
59         uint32_t savePP_CONTROL;
60         uint32_t savePP_CYCLE;
61         uint32_t savePFIT_CONTROL;
62         uint32_t savePFIT_PGM_RATIOS;
63         uint32_t saveBLC_PWM_CTL;
64 };
65
66 /*
67  * Returns the maximum level of the backlight duty cycle field.
68  */
69 static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev)
70 {
71         struct drm_psb_private *dev_priv = dev->dev_private;
72         u32 retval;
73
74         if (gma_power_begin(dev, false)) {
75                 retval = ((REG_READ(BLC_PWM_CTL) &
76                           BACKLIGHT_MODULATION_FREQ_MASK) >>
77                           BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
78
79                 gma_power_end(dev);
80         } else
81                 retval = ((dev_priv->saveBLC_PWM_CTL &
82                           BACKLIGHT_MODULATION_FREQ_MASK) >>
83                           BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
84
85         return retval;
86 }
87
88 /*
89  * Set LVDS backlight level by I2C command
90  */
91 static int cdv_lvds_i2c_set_brightness(struct drm_device *dev,
92                                         unsigned int level)
93 {
94         struct drm_psb_private *dev_priv = dev->dev_private;
95         struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus;
96         u8 out_buf[2];
97         unsigned int blc_i2c_brightness;
98
99         struct i2c_msg msgs[] = {
100                 {
101                         .addr = lvds_i2c_bus->slave_addr,
102                         .flags = 0,
103                         .len = 2,
104                         .buf = out_buf,
105                 }
106         };
107
108         blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level *
109                              BRIGHTNESS_MASK /
110                              BRIGHTNESS_MAX_LEVEL);
111
112         if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
113                 blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness;
114
115         out_buf[0] = dev_priv->lvds_bl->brightnesscmd;
116         out_buf[1] = (u8)blc_i2c_brightness;
117
118         if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1)
119                 return 0;
120
121         DRM_ERROR("I2C transfer error\n");
122         return -1;
123 }
124
125
126 static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level)
127 {
128         struct drm_psb_private *dev_priv = dev->dev_private;
129
130         u32 max_pwm_blc;
131         u32 blc_pwm_duty_cycle;
132
133         max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev);
134
135         /*BLC_PWM_CTL Should be initiated while backlight device init*/
136         BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
137
138         blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
139
140         if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE)
141                 blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle;
142
143         blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
144         REG_WRITE(BLC_PWM_CTL,
145                   (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
146                   (blc_pwm_duty_cycle));
147
148         return 0;
149 }
150
151 /*
152  * Set LVDS backlight level either by I2C or PWM
153  */
154 void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level)
155 {
156         struct drm_psb_private *dev_priv = dev->dev_private;
157
158         if (!dev_priv->lvds_bl) {
159                 DRM_ERROR("NO LVDS Backlight Info\n");
160                 return;
161         }
162
163         if (dev_priv->lvds_bl->type == BLC_I2C_TYPE)
164                 cdv_lvds_i2c_set_brightness(dev, level);
165         else
166                 cdv_lvds_pwm_set_brightness(dev, level);
167 }
168
169 /**
170  * Sets the backlight level.
171  *
172  * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight().
173  */
174 static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
175 {
176         struct drm_psb_private *dev_priv = dev->dev_private;
177         u32 blc_pwm_ctl;
178
179         if (gma_power_begin(dev, false)) {
180                 blc_pwm_ctl =
181                         REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
182                 REG_WRITE(BLC_PWM_CTL,
183                                 (blc_pwm_ctl |
184                                 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
185                 gma_power_end(dev);
186         } else {
187                 blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
188                                 ~BACKLIGHT_DUTY_CYCLE_MASK;
189                 dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
190                                         (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
191         }
192 }
193
194 /**
195  * Sets the power state for the panel.
196  */
197 static void cdv_intel_lvds_set_power(struct drm_device *dev,
198                                  struct psb_intel_output *output, bool on)
199 {
200         u32 pp_status;
201
202         if (!gma_power_begin(dev, true))
203                 return;
204
205         if (on) {
206                 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
207                           POWER_TARGET_ON);
208                 do {
209                         pp_status = REG_READ(PP_STATUS);
210                 } while ((pp_status & PP_ON) == 0);
211
212                 cdv_intel_lvds_set_backlight(dev,
213                                          output->
214                                          mode_dev->backlight_duty_cycle);
215         } else {
216                 cdv_intel_lvds_set_backlight(dev, 0);
217
218                 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
219                           ~POWER_TARGET_ON);
220                 do {
221                         pp_status = REG_READ(PP_STATUS);
222                 } while (pp_status & PP_ON);
223         }
224         gma_power_end(dev);
225 }
226
227 static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
228 {
229         struct drm_device *dev = encoder->dev;
230         struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
231         if (mode == DRM_MODE_DPMS_ON)
232                 cdv_intel_lvds_set_power(dev, output, true);
233         else
234                 cdv_intel_lvds_set_power(dev, output, false);
235         /* XXX: We never power down the LVDS pairs. */
236 }
237
238 static void cdv_intel_lvds_save(struct drm_connector *connector)
239 {
240 }
241
242 static void cdv_intel_lvds_restore(struct drm_connector *connector)
243 {
244 }
245
246 int cdv_intel_lvds_mode_valid(struct drm_connector *connector,
247                                  struct drm_display_mode *mode)
248 {
249         struct psb_intel_output *psb_intel_output =
250                                 to_psb_intel_output(connector);
251         struct drm_display_mode *fixed_mode =
252             psb_intel_output->mode_dev->panel_fixed_mode;
253
254         /* just in case */
255         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
256                 return MODE_NO_DBLESCAN;
257
258         /* just in case */
259         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
260                 return MODE_NO_INTERLACE;
261
262         if (fixed_mode) {
263                 if (mode->hdisplay > fixed_mode->hdisplay)
264                         return MODE_PANEL;
265                 if (mode->vdisplay > fixed_mode->vdisplay)
266                         return MODE_PANEL;
267         }
268         return MODE_OK;
269 }
270
271 bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
272                                   struct drm_display_mode *mode,
273                                   struct drm_display_mode *adjusted_mode)
274 {
275         struct psb_intel_mode_device *mode_dev =
276             enc_to_psb_intel_output(encoder)->mode_dev;
277         struct drm_device *dev = encoder->dev;
278         struct drm_encoder *tmp_encoder;
279         struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
280
281         /* Should never happen!! */
282         list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
283                             head) {
284                 if (tmp_encoder != encoder
285                     && tmp_encoder->crtc == encoder->crtc) {
286                         printk(KERN_ERR "Can't enable LVDS and another "
287                                "encoder on the same pipe\n");
288                         return false;
289                 }
290         }
291
292         /*
293          * If we have timings from the BIOS for the panel, put them in
294          * to the adjusted mode.  The CRTC will be set up for this mode,
295          * with the panel scaling set up to source from the H/VDisplay
296          * of the original mode.
297          */
298         if (panel_fixed_mode != NULL) {
299                 adjusted_mode->hdisplay = panel_fixed_mode->hdisplay;
300                 adjusted_mode->hsync_start = panel_fixed_mode->hsync_start;
301                 adjusted_mode->hsync_end = panel_fixed_mode->hsync_end;
302                 adjusted_mode->htotal = panel_fixed_mode->htotal;
303                 adjusted_mode->vdisplay = panel_fixed_mode->vdisplay;
304                 adjusted_mode->vsync_start = panel_fixed_mode->vsync_start;
305                 adjusted_mode->vsync_end = panel_fixed_mode->vsync_end;
306                 adjusted_mode->vtotal = panel_fixed_mode->vtotal;
307                 adjusted_mode->clock = panel_fixed_mode->clock;
308                 drm_mode_set_crtcinfo(adjusted_mode,
309                                       CRTC_INTERLACE_HALVE_V);
310         }
311
312         /*
313          * XXX: It would be nice to support lower refresh rates on the
314          * panels to reduce power consumption, and perhaps match the
315          * user's requested refresh rate.
316          */
317
318         return true;
319 }
320
321 static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
322 {
323         struct drm_device *dev = encoder->dev;
324         struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
325         struct psb_intel_mode_device *mode_dev = output->mode_dev;
326
327         if (!gma_power_begin(dev, true))
328                 return;
329
330         mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
331         mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
332                                           BACKLIGHT_DUTY_CYCLE_MASK);
333
334         cdv_intel_lvds_set_power(dev, output, false);
335
336         gma_power_end(dev);
337 }
338
339 static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
340 {
341         struct drm_device *dev = encoder->dev;
342         struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
343         struct psb_intel_mode_device *mode_dev = output->mode_dev;
344
345         if (mode_dev->backlight_duty_cycle == 0)
346                 mode_dev->backlight_duty_cycle =
347                     cdv_intel_lvds_get_max_backlight(dev);
348
349         cdv_intel_lvds_set_power(dev, output, true);
350 }
351
352 static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
353                                 struct drm_display_mode *mode,
354                                 struct drm_display_mode *adjusted_mode)
355 {
356         struct drm_device *dev = encoder->dev;
357         struct drm_psb_private *dev_priv = dev->dev_private;
358         u32 pfit_control;
359
360         /*
361          * The LVDS pin pair will already have been turned on in the
362          * cdv_intel_crtc_mode_set since it has a large impact on the DPLL
363          * settings.
364          */
365
366         /*
367          * Enable automatic panel scaling so that non-native modes fill the
368          * screen.  Should be enabled before the pipe is enabled, according to
369          * register description and PRM.
370          */
371         if (mode->hdisplay != adjusted_mode->hdisplay ||
372             mode->vdisplay != adjusted_mode->vdisplay)
373                 pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
374                                 HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
375                                 HORIZ_INTERP_BILINEAR);
376         else
377                 pfit_control = 0;
378
379         if (dev_priv->lvds_dither)
380                 pfit_control |= PANEL_8TO6_DITHER_ENABLE;
381
382         REG_WRITE(PFIT_CONTROL, pfit_control);
383 }
384
385 /**
386  * Detect the LVDS connection.
387  *
388  * This always returns CONNECTOR_STATUS_CONNECTED.
389  * This connector should only have
390  * been set up if the LVDS was actually connected anyway.
391  */
392 static enum drm_connector_status cdv_intel_lvds_detect(
393                                 struct drm_connector *connector, bool force)
394 {
395         return connector_status_connected;
396 }
397
398 /**
399  * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
400  */
401 static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
402 {
403         struct drm_device *dev = connector->dev;
404         struct psb_intel_output *psb_intel_output =
405                                         to_psb_intel_output(connector);
406         struct psb_intel_mode_device *mode_dev =
407                                         psb_intel_output->mode_dev;
408         int ret;
409
410         ret = psb_intel_ddc_get_modes(psb_intel_output);
411
412         if (ret)
413                 return ret;
414
415         /* Didn't get an EDID, so
416          * Set wide sync ranges so we get all modes
417          * handed to valid_mode for checking
418          */
419         connector->display_info.min_vfreq = 0;
420         connector->display_info.max_vfreq = 200;
421         connector->display_info.min_hfreq = 0;
422         connector->display_info.max_hfreq = 200;
423         if (mode_dev->panel_fixed_mode != NULL) {
424                 struct drm_display_mode *mode =
425                     drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
426                 drm_mode_probed_add(connector, mode);
427                 return 1;
428         }
429
430         return 0;
431 }
432
433 /**
434  * cdv_intel_lvds_destroy - unregister and free LVDS structures
435  * @connector: connector to free
436  *
437  * Unregister the DDC bus for this connector then free the driver private
438  * structure.
439  */
440 void cdv_intel_lvds_destroy(struct drm_connector *connector)
441 {
442         struct psb_intel_output *psb_intel_output =
443                                         to_psb_intel_output(connector);
444
445         if (psb_intel_output->ddc_bus)
446                 psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
447         drm_sysfs_connector_remove(connector);
448         drm_connector_cleanup(connector);
449         kfree(connector);
450 }
451
452 int cdv_intel_lvds_set_property(struct drm_connector *connector,
453                                        struct drm_property *property,
454                                        uint64_t value)
455 {
456         struct drm_encoder *encoder = connector->encoder;
457
458         if (!strcmp(property->name, "scaling mode") && encoder) {
459                 struct psb_intel_crtc *crtc =
460                                         to_psb_intel_crtc(encoder->crtc);
461                 uint64_t curValue;
462
463                 if (!crtc)
464                         return -1;
465
466                 switch (value) {
467                 case DRM_MODE_SCALE_FULLSCREEN:
468                         break;
469                 case DRM_MODE_SCALE_NO_SCALE:
470                         break;
471                 case DRM_MODE_SCALE_ASPECT:
472                         break;
473                 default:
474                         return -1;
475                 }
476
477                 if (drm_connector_property_get_value(connector,
478                                                      property,
479                                                      &curValue))
480                         return -1;
481
482                 if (curValue == value)
483                         return 0;
484
485                 if (drm_connector_property_set_value(connector,
486                                                         property,
487                                                         value))
488                         return -1;
489
490                 if (crtc->saved_mode.hdisplay != 0 &&
491                     crtc->saved_mode.vdisplay != 0) {
492                         if (!drm_crtc_helper_set_mode(encoder->crtc,
493                                                       &crtc->saved_mode,
494                                                       encoder->crtc->x,
495                                                       encoder->crtc->y,
496                                                       encoder->crtc->fb))
497                                 return -1;
498                 }
499         } else if (!strcmp(property->name, "backlight") && encoder) {
500                 if (drm_connector_property_set_value(connector,
501                                                         property,
502                                                         value))
503                         return -1;
504                 else {
505 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
506                         struct drm_psb_private *dev_priv =
507                                                 encoder->dev->dev_private;
508                         struct backlight_device *bd =
509                                                 dev_priv->backlight_device;
510                         bd->props.brightness = value;
511                         backlight_update_status(bd);
512 #endif
513                 }
514         } else if (!strcmp(property->name, "DPMS") && encoder) {
515                 struct drm_encoder_helper_funcs *helpers =
516                                         encoder->helper_private;
517                 helpers->dpms(encoder, value);
518         }
519         return 0;
520 }
521
522 static const struct drm_encoder_helper_funcs
523                                         cdv_intel_lvds_helper_funcs = {
524         .dpms = cdv_intel_lvds_encoder_dpms,
525         .mode_fixup = cdv_intel_lvds_mode_fixup,
526         .prepare = cdv_intel_lvds_prepare,
527         .mode_set = cdv_intel_lvds_mode_set,
528         .commit = cdv_intel_lvds_commit,
529 };
530
531 static const struct drm_connector_helper_funcs
532                                 cdv_intel_lvds_connector_helper_funcs = {
533         .get_modes = cdv_intel_lvds_get_modes,
534         .mode_valid = cdv_intel_lvds_mode_valid,
535         .best_encoder = psb_intel_best_encoder,
536 };
537
538 static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = {
539         .dpms = drm_helper_connector_dpms,
540         .save = cdv_intel_lvds_save,
541         .restore = cdv_intel_lvds_restore,
542         .detect = cdv_intel_lvds_detect,
543         .fill_modes = drm_helper_probe_single_connector_modes,
544         .set_property = cdv_intel_lvds_set_property,
545         .destroy = cdv_intel_lvds_destroy,
546 };
547
548
549 static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder)
550 {
551         drm_encoder_cleanup(encoder);
552 }
553
554 const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
555         .destroy = cdv_intel_lvds_enc_destroy,
556 };
557
558 /**
559  * cdv_intel_lvds_init - setup LVDS connectors on this device
560  * @dev: drm device
561  *
562  * Create the connector, register the LVDS DDC bus, and try to figure out what
563  * modes we can display on the LVDS panel (if present).
564  */
565 void cdv_intel_lvds_init(struct drm_device *dev,
566                      struct psb_intel_mode_device *mode_dev)
567 {
568         struct psb_intel_output *psb_intel_output;
569         struct cdv_intel_lvds_priv *lvds_priv;
570         struct drm_connector *connector;
571         struct drm_encoder *encoder;
572         struct drm_display_mode *scan;
573         struct drm_crtc *crtc;
574         struct drm_psb_private *dev_priv = dev->dev_private;
575         u32 lvds;
576         int pipe;
577
578         psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
579                         sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
580         if (!psb_intel_output)
581                 return;
582
583         lvds_priv = (struct cdv_intel_lvds_priv *)(psb_intel_output + 1);
584
585         psb_intel_output->dev_priv = lvds_priv;
586
587         psb_intel_output->mode_dev = mode_dev;
588         connector = &psb_intel_output->base;
589         encoder = &psb_intel_output->enc;
590
591
592         drm_connector_init(dev, &psb_intel_output->base,
593                            &cdv_intel_lvds_connector_funcs,
594                            DRM_MODE_CONNECTOR_LVDS);
595
596         drm_encoder_init(dev, &psb_intel_output->enc,
597                          &cdv_intel_lvds_enc_funcs,
598                          DRM_MODE_ENCODER_LVDS);
599
600
601         drm_mode_connector_attach_encoder(&psb_intel_output->base,
602                                           &psb_intel_output->enc);
603         psb_intel_output->type = INTEL_OUTPUT_LVDS;
604
605         drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
606         drm_connector_helper_add(connector,
607                                  &cdv_intel_lvds_connector_helper_funcs);
608         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
609         connector->interlace_allowed = false;
610         connector->doublescan_allowed = false;
611
612         /*Attach connector properties*/
613         drm_connector_attach_property(connector,
614                                       dev->mode_config.scaling_mode_property,
615                                       DRM_MODE_SCALE_FULLSCREEN);
616         drm_connector_attach_property(connector,
617                                       dev_priv->backlight_property,
618                                       BRIGHTNESS_MAX_LEVEL);
619
620         /**
621          * Set up I2C bus
622          * FIXME: distroy i2c_bus when exit
623          */
624         psb_intel_output->i2c_bus = psb_intel_i2c_create(dev,
625                                                          GPIOB,
626                                                          "LVDSBLC_B");
627         if (!psb_intel_output->i2c_bus) {
628                 dev_printk(KERN_ERR,
629                         &dev->pdev->dev, "I2C bus registration failed.\n");
630                 goto failed_blc_i2c;
631         }
632         psb_intel_output->i2c_bus->slave_addr = 0x2C;
633         dev_priv->lvds_i2c_bus =  psb_intel_output->i2c_bus;
634
635         /*
636          * LVDS discovery:
637          * 1) check for EDID on DDC
638          * 2) check for VBT data
639          * 3) check to see if LVDS is already on
640          *    if none of the above, no panel
641          * 4) make sure lid is open
642          *    if closed, act like it's not there for now
643          */
644
645         /* Set up the DDC bus. */
646         psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
647                                                          GPIOC,
648                                                          "LVDSDDC_C");
649         if (!psb_intel_output->ddc_bus) {
650                 dev_printk(KERN_ERR, &dev->pdev->dev,
651                            "DDC bus registration " "failed.\n");
652                 goto failed_ddc;
653         }
654
655         /*
656          * Attempt to get the fixed panel mode from DDC.  Assume that the
657          * preferred mode is the right one.
658          */
659         psb_intel_ddc_get_modes(psb_intel_output);
660         list_for_each_entry(scan, &connector->probed_modes, head) {
661                 if (scan->type & DRM_MODE_TYPE_PREFERRED) {
662                         mode_dev->panel_fixed_mode =
663                             drm_mode_duplicate(dev, scan);
664                         goto out;       /* FIXME: check for quirks */
665                 }
666         }
667
668         /* Failed to get EDID, what about VBT? do we need this?*/
669         if (dev_priv->lfp_lvds_vbt_mode) {
670                 mode_dev->panel_fixed_mode =
671                         drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
672                 if (mode_dev->panel_fixed_mode) {
673                         mode_dev->panel_fixed_mode->type |=
674                                 DRM_MODE_TYPE_PREFERRED;
675                         goto out;       /* FIXME: check for quirks */
676                 }
677         }
678         /*
679          * If we didn't get EDID, try checking if the panel is already turned
680          * on.  If so, assume that whatever is currently programmed is the
681          * correct mode.
682          */
683         lvds = REG_READ(LVDS);
684         pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
685         crtc = psb_intel_get_crtc_from_pipe(dev, pipe);
686
687         if (crtc && (lvds & LVDS_PORT_EN)) {
688                 mode_dev->panel_fixed_mode =
689                     cdv_intel_crtc_mode_get(dev, crtc);
690                 if (mode_dev->panel_fixed_mode) {
691                         mode_dev->panel_fixed_mode->type |=
692                             DRM_MODE_TYPE_PREFERRED;
693                         goto out;       /* FIXME: check for quirks */
694                 }
695         }
696
697         /* If we still don't have a mode after all that, give up. */
698         if (!mode_dev->panel_fixed_mode) {
699                 DRM_DEBUG
700                         ("Found no modes on the lvds, ignoring the LVDS\n");
701                 goto failed_find;
702         }
703
704 out:
705         drm_sysfs_connector_add(connector);
706         return;
707
708 failed_find:
709         printk(KERN_ERR "Failed find\n");
710         if (psb_intel_output->ddc_bus)
711                 psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
712 failed_ddc:
713         printk(KERN_ERR "Failed DDC\n");
714         if (psb_intel_output->i2c_bus)
715                 psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
716 failed_blc_i2c:
717         printk(KERN_ERR "Failed BLC\n");
718         drm_encoder_cleanup(encoder);
719         drm_connector_cleanup(connector);
720         kfree(connector);
721 }