aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-01-16 13:44:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-01-16 13:44:38 -0500
commit33f724eb9e3d6e33aad410318d3ac720fecbdbcd (patch)
treead0824aec7e1e89276ca4e0b3e63d067f0d34e4c /drivers
parent9ddabb6700f82a033a76bcf7a547204fa12aaa17 (diff)
parent9b974cc17166d31afed2638d56bdbf9829afbfaa (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: drm/i915: enable 36bit physical address for hardware status page drm/i915: fix eDP pipe mask drm/i915: fix pixel color depth setting on eDP drm/i915: parse eDP panel color depth from VBT block drm/i915: disable LVDS downclock by default drm/i915: Fix the incorrect cursor A bit definition in DSPFW2 register drm/i915: Remove chatty execbuf failure message. drm/i915: remove loop in Ironlake interrupt handler drm/i915: Don't wait interruptible for possible plane buffer flush drm/i915: try another possible DDC bus for the SDVO device with multiple outputs drm/i915: Read the response after issuing DDC bus switch command drm/i915: Don't use the child device parsed from VBT to setup HDMI/DP drm/i915: Fix resume regression on MSI Wind U100 w/o KMS drm/i915: Fix Ironlake M/N/P ranges to match the spec drm/i915: Use find_pll function to calculate DPLL setting for LVDS downclock drm/i915: Add HP nx9020/SamsungSX20S to ACPI LID quirk list drm/i915: disable TV hotplug status check Trivial conflicts in drivers/gpu/drm/i915/i915_drv.c due to i915 non-modeset suspend fix with different comment.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/agp/intel-agp.c6
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c4
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c6
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c53
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c68
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c35
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h40
-rw-r--r--drivers/gpu/drm/i915/intel_display.c84
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c75
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c50
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c17
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c83
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
15 files changed, 305 insertions, 223 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 30c36ac2cd00..3999a5f25f38 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -2460,10 +2460,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2460 &bridge->mode); 2460 &bridge->mode);
2461 } 2461 }
2462 2462
2463 if (bridge->driver->mask_memory == intel_i965_mask_memory) 2463 if (bridge->driver->mask_memory == intel_i965_mask_memory) {
2464 if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) 2464 if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
2465 dev_err(&intel_private.pcidev->dev, 2465 dev_err(&intel_private.pcidev->dev,
2466 "set gfx device dma mask 36bit failed!\n"); 2466 "set gfx device dma mask 36bit failed!\n");
2467 else
2468 pci_set_consistent_dma_mask(intel_private.pcidev,
2469 DMA_BIT_MASK(36));
2470 }
2467 2471
2468 pci_set_drvdata(pdev, bridge); 2472 pci_set_drvdata(pdev, bridge);
2469 return agp_add_bridge(bridge); 2473 return agp_add_bridge(bridge);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index bbe47812e4b6..e660ac07f3b2 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -134,6 +134,10 @@ static int i915_init_phys_hws(struct drm_device *dev)
134 134
135 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 135 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
136 136
137 if (IS_I965G(dev))
138 dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) &
139 0xf0;
140
137 I915_WRITE(HWS_PGA, dev_priv->dma_status_page); 141 I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
138 DRM_DEBUG_DRIVER("Enabled hardware status page\n"); 142 DRM_DEBUG_DRIVER("Enabled hardware status page\n");
139 return 0; 143 return 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index be631cc3e4dc..46d88965852a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -45,6 +45,9 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
45unsigned int i915_powersave = 1; 45unsigned int i915_powersave = 1;
46module_param_named(powersave, i915_powersave, int, 0400); 46module_param_named(powersave, i915_powersave, int, 0400);
47 47
48unsigned int i915_lvds_downclock = 0;
49module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
50
48static struct drm_driver driver; 51static struct drm_driver driver;
49 52
50#define INTEL_VGA_DEVICE(id, info) { \ 53#define INTEL_VGA_DEVICE(id, info) { \
@@ -464,8 +467,11 @@ static struct drm_driver driver = {
464 .lastclose = i915_driver_lastclose, 467 .lastclose = i915_driver_lastclose,
465 .preclose = i915_driver_preclose, 468 .preclose = i915_driver_preclose,
466 .postclose = i915_driver_postclose, 469 .postclose = i915_driver_postclose,
470
471 /* Used in place of i915_pm_ops for non-DRIVER_MODESET */
467 .suspend = i915_suspend, 472 .suspend = i915_suspend,
468 .resume = i915_resume, 473 .resume = i915_resume,
474
469 .device_is_agp = i915_driver_device_is_agp, 475 .device_is_agp = i915_driver_device_is_agp,
470 .enable_vblank = i915_enable_vblank, 476 .enable_vblank = i915_enable_vblank,
471 .disable_vblank = i915_disable_vblank, 477 .disable_vblank = i915_disable_vblank,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 29dd67626967..2c1669488b5a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -283,6 +283,7 @@ typedef struct drm_i915_private {
283 unsigned int lvds_use_ssc:1; 283 unsigned int lvds_use_ssc:1;
284 unsigned int edp_support:1; 284 unsigned int edp_support:1;
285 int lvds_ssc_freq; 285 int lvds_ssc_freq;
286 int edp_bpp;
286 287
287 struct notifier_block lid_notifier; 288 struct notifier_block lid_notifier;
288 289
@@ -722,6 +723,7 @@ extern struct drm_ioctl_desc i915_ioctls[];
722extern int i915_max_ioctl; 723extern int i915_max_ioctl;
723extern unsigned int i915_fbpercrtc; 724extern unsigned int i915_fbpercrtc;
724extern unsigned int i915_powersave; 725extern unsigned int i915_powersave;
726extern unsigned int i915_lvds_downclock;
725 727
726extern void i915_save_display(struct drm_device *dev); 728extern void i915_save_display(struct drm_device *dev);
727extern void i915_restore_display(struct drm_device *dev); 729extern void i915_restore_display(struct drm_device *dev);
@@ -864,6 +866,7 @@ int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptib
864int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 866int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
865int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, 867int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
866 int write); 868 int write);
869int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj);
867int i915_gem_attach_phys_object(struct drm_device *dev, 870int i915_gem_attach_phys_object(struct drm_device *dev,
868 struct drm_gem_object *obj, int id); 871 struct drm_gem_object *obj, int id);
869void i915_gem_detach_phys_object(struct drm_device *dev, 872void i915_gem_detach_phys_object(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2748609f05b3..0c67924ca80c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2837,6 +2837,57 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
2837 return 0; 2837 return 0;
2838} 2838}
2839 2839
2840/*
2841 * Prepare buffer for display plane. Use uninterruptible for possible flush
2842 * wait, as in modesetting process we're not supposed to be interrupted.
2843 */
2844int
2845i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
2846{
2847 struct drm_device *dev = obj->dev;
2848 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2849 uint32_t old_write_domain, old_read_domains;
2850 int ret;
2851
2852 /* Not valid to be called on unbound objects. */
2853 if (obj_priv->gtt_space == NULL)
2854 return -EINVAL;
2855
2856 i915_gem_object_flush_gpu_write_domain(obj);
2857
2858 /* Wait on any GPU rendering and flushing to occur. */
2859 if (obj_priv->active) {
2860#if WATCH_BUF
2861 DRM_INFO("%s: object %p wait for seqno %08x\n",
2862 __func__, obj, obj_priv->last_rendering_seqno);
2863#endif
2864 ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0);
2865 if (ret != 0)
2866 return ret;
2867 }
2868
2869 old_write_domain = obj->write_domain;
2870 old_read_domains = obj->read_domains;
2871
2872 obj->read_domains &= I915_GEM_DOMAIN_GTT;
2873
2874 i915_gem_object_flush_cpu_write_domain(obj);
2875
2876 /* It should now be out of any other write domains, and we can update
2877 * the domain values for our changes.
2878 */
2879 BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
2880 obj->read_domains |= I915_GEM_DOMAIN_GTT;
2881 obj->write_domain = I915_GEM_DOMAIN_GTT;
2882 obj_priv->dirty = 1;
2883
2884 trace_i915_gem_object_change_domain(obj,
2885 old_read_domains,
2886 old_write_domain);
2887
2888 return 0;
2889}
2890
2840/** 2891/**
2841 * Moves a single object to the CPU read, and possibly write domain. 2892 * Moves a single object to the CPU read, and possibly write domain.
2842 * 2893 *
@@ -4000,8 +4051,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
4000 "back to user (%d)\n", 4051 "back to user (%d)\n",
4001 args->buffer_count, ret); 4052 args->buffer_count, ret);
4002 } 4053 }
4003 } else {
4004 DRM_ERROR("i915_gem_do_execbuffer returns %d\n", ret);
4005 } 4054 }
4006 4055
4007 drm_free_large(exec_list); 4056 drm_free_large(exec_list);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7cd8110051b6..89a071a3e6fb 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -274,7 +274,6 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
274 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 274 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
275 int ret = IRQ_NONE; 275 int ret = IRQ_NONE;
276 u32 de_iir, gt_iir, de_ier, pch_iir; 276 u32 de_iir, gt_iir, de_ier, pch_iir;
277 u32 new_de_iir, new_gt_iir, new_pch_iir;
278 struct drm_i915_master_private *master_priv; 277 struct drm_i915_master_private *master_priv;
279 278
280 /* disable master interrupt before clearing iir */ 279 /* disable master interrupt before clearing iir */
@@ -286,51 +285,42 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
286 gt_iir = I915_READ(GTIIR); 285 gt_iir = I915_READ(GTIIR);
287 pch_iir = I915_READ(SDEIIR); 286 pch_iir = I915_READ(SDEIIR);
288 287
289 for (;;) { 288 if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
290 if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) 289 goto done;
291 break;
292
293 ret = IRQ_HANDLED;
294 290
295 /* should clear PCH hotplug event before clear CPU irq */ 291 ret = IRQ_HANDLED;
296 I915_WRITE(SDEIIR, pch_iir);
297 new_pch_iir = I915_READ(SDEIIR);
298 292
299 I915_WRITE(DEIIR, de_iir); 293 if (dev->primary->master) {
300 new_de_iir = I915_READ(DEIIR); 294 master_priv = dev->primary->master->driver_priv;
301 I915_WRITE(GTIIR, gt_iir); 295 if (master_priv->sarea_priv)
302 new_gt_iir = I915_READ(GTIIR); 296 master_priv->sarea_priv->last_dispatch =
303 297 READ_BREADCRUMB(dev_priv);
304 if (dev->primary->master) { 298 }
305 master_priv = dev->primary->master->driver_priv;
306 if (master_priv->sarea_priv)
307 master_priv->sarea_priv->last_dispatch =
308 READ_BREADCRUMB(dev_priv);
309 }
310
311 if (gt_iir & GT_USER_INTERRUPT) {
312 u32 seqno = i915_get_gem_seqno(dev);
313 dev_priv->mm.irq_gem_seqno = seqno;
314 trace_i915_gem_request_complete(dev, seqno);
315 DRM_WAKEUP(&dev_priv->irq_queue);
316 dev_priv->hangcheck_count = 0;
317 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
318 }
319 299
320 if (de_iir & DE_GSE) 300 if (gt_iir & GT_USER_INTERRUPT) {
321 ironlake_opregion_gse_intr(dev); 301 u32 seqno = i915_get_gem_seqno(dev);
302 dev_priv->mm.irq_gem_seqno = seqno;
303 trace_i915_gem_request_complete(dev, seqno);
304 DRM_WAKEUP(&dev_priv->irq_queue);
305 dev_priv->hangcheck_count = 0;
306 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
307 }
322 308
323 /* check event from PCH */ 309 if (de_iir & DE_GSE)
324 if ((de_iir & DE_PCH_EVENT) && 310 ironlake_opregion_gse_intr(dev);
325 (pch_iir & SDE_HOTPLUG_MASK)) {
326 queue_work(dev_priv->wq, &dev_priv->hotplug_work);
327 }
328 311
329 de_iir = new_de_iir; 312 /* check event from PCH */
330 gt_iir = new_gt_iir; 313 if ((de_iir & DE_PCH_EVENT) &&
331 pch_iir = new_pch_iir; 314 (pch_iir & SDE_HOTPLUG_MASK)) {
315 queue_work(dev_priv->wq, &dev_priv->hotplug_work);
332 } 316 }
333 317
318 /* should clear PCH hotplug event before clear CPU irq */
319 I915_WRITE(SDEIIR, pch_iir);
320 I915_WRITE(GTIIR, gt_iir);
321 I915_WRITE(DEIIR, de_iir);
322
323done:
334 I915_WRITE(DEIER, de_ier); 324 I915_WRITE(DEIER, de_ier);
335 (void)I915_READ(DEIER); 325 (void)I915_READ(DEIER);
336 326
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 149d360d64a3..847006c5218e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1815,7 +1815,7 @@
1815#define DSPFW_PLANEB_SHIFT 8 1815#define DSPFW_PLANEB_SHIFT 8
1816#define DSPFW2 0x70038 1816#define DSPFW2 0x70038
1817#define DSPFW_CURSORA_MASK 0x00003f00 1817#define DSPFW_CURSORA_MASK 0x00003f00
1818#define DSPFW_CURSORA_SHIFT 16 1818#define DSPFW_CURSORA_SHIFT 8
1819#define DSPFW3 0x7003c 1819#define DSPFW3 0x7003c
1820#define DSPFW_HPLL_SR_EN (1<<31) 1820#define DSPFW_HPLL_SR_EN (1<<31)
1821#define DSPFW_CURSOR_SR_SHIFT 24 1821#define DSPFW_CURSOR_SR_SHIFT 24
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index f27567747580..15fbc1b5a83e 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -33,6 +33,8 @@
33#define SLAVE_ADDR1 0x70 33#define SLAVE_ADDR1 0x70
34#define SLAVE_ADDR2 0x72 34#define SLAVE_ADDR2 0x72
35 35
36static int panel_type;
37
36static void * 38static void *
37find_section(struct bdb_header *bdb, int section_id) 39find_section(struct bdb_header *bdb, int section_id)
38{ 40{
@@ -128,6 +130,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
128 dev_priv->lvds_dither = lvds_options->pixel_dither; 130 dev_priv->lvds_dither = lvds_options->pixel_dither;
129 if (lvds_options->panel_type == 0xff) 131 if (lvds_options->panel_type == 0xff)
130 return; 132 return;
133 panel_type = lvds_options->panel_type;
131 134
132 lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); 135 lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
133 if (!lvds_lfp_data) 136 if (!lvds_lfp_data)
@@ -197,7 +200,8 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
197 memset(temp_mode, 0, sizeof(*temp_mode)); 200 memset(temp_mode, 0, sizeof(*temp_mode));
198 } 201 }
199 kfree(temp_mode); 202 kfree(temp_mode);
200 if (temp_downclock < panel_fixed_mode->clock) { 203 if (temp_downclock < panel_fixed_mode->clock &&
204 i915_lvds_downclock) {
201 dev_priv->lvds_downclock_avail = 1; 205 dev_priv->lvds_downclock_avail = 1;
202 dev_priv->lvds_downclock = temp_downclock; 206 dev_priv->lvds_downclock = temp_downclock;
203 DRM_DEBUG_KMS("LVDS downclock is found in VBT. ", 207 DRM_DEBUG_KMS("LVDS downclock is found in VBT. ",
@@ -405,6 +409,34 @@ parse_driver_features(struct drm_i915_private *dev_priv,
405} 409}
406 410
407static void 411static void
412parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
413{
414 struct bdb_edp *edp;
415
416 edp = find_section(bdb, BDB_EDP);
417 if (!edp) {
418 if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) {
419 DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\
420 assume 18bpp panel color depth.\n");
421 dev_priv->edp_bpp = 18;
422 }
423 return;
424 }
425
426 switch ((edp->color_depth >> (panel_type * 2)) & 3) {
427 case EDP_18BPP:
428 dev_priv->edp_bpp = 18;
429 break;
430 case EDP_24BPP:
431 dev_priv->edp_bpp = 24;
432 break;
433 case EDP_30BPP:
434 dev_priv->edp_bpp = 30;
435 break;
436 }
437}
438
439static void
408parse_device_mapping(struct drm_i915_private *dev_priv, 440parse_device_mapping(struct drm_i915_private *dev_priv,
409 struct bdb_header *bdb) 441 struct bdb_header *bdb)
410{ 442{
@@ -521,6 +553,7 @@ intel_init_bios(struct drm_device *dev)
521 parse_sdvo_device_mapping(dev_priv, bdb); 553 parse_sdvo_device_mapping(dev_priv, bdb);
522 parse_device_mapping(dev_priv, bdb); 554 parse_device_mapping(dev_priv, bdb);
523 parse_driver_features(dev_priv, bdb); 555 parse_driver_features(dev_priv, bdb);
556 parse_edp(dev_priv, bdb);
524 557
525 pci_unmap_rom(pdev, bios); 558 pci_unmap_rom(pdev, bios);
526 559
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 425ac9d7f724..4c18514f6f80 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -98,6 +98,7 @@ struct vbios_data {
98#define BDB_SDVO_LVDS_PNP_IDS 24 98#define BDB_SDVO_LVDS_PNP_IDS 24
99#define BDB_SDVO_LVDS_POWER_SEQ 25 99#define BDB_SDVO_LVDS_POWER_SEQ 25
100#define BDB_TV_OPTIONS 26 100#define BDB_TV_OPTIONS 26
101#define BDB_EDP 27
101#define BDB_LVDS_OPTIONS 40 102#define BDB_LVDS_OPTIONS 40
102#define BDB_LVDS_LFP_DATA_PTRS 41 103#define BDB_LVDS_LFP_DATA_PTRS 41
103#define BDB_LVDS_LFP_DATA 42 104#define BDB_LVDS_LFP_DATA 42
@@ -426,6 +427,45 @@ struct bdb_driver_features {
426 u8 custom_vbt_version; 427 u8 custom_vbt_version;
427} __attribute__((packed)); 428} __attribute__((packed));
428 429
430#define EDP_18BPP 0
431#define EDP_24BPP 1
432#define EDP_30BPP 2
433#define EDP_RATE_1_62 0
434#define EDP_RATE_2_7 1
435#define EDP_LANE_1 0
436#define EDP_LANE_2 1
437#define EDP_LANE_4 3
438#define EDP_PREEMPHASIS_NONE 0
439#define EDP_PREEMPHASIS_3_5dB 1
440#define EDP_PREEMPHASIS_6dB 2
441#define EDP_PREEMPHASIS_9_5dB 3
442#define EDP_VSWING_0_4V 0
443#define EDP_VSWING_0_6V 1
444#define EDP_VSWING_0_8V 2
445#define EDP_VSWING_1_2V 3
446
447struct edp_power_seq {
448 u16 t3;
449 u16 t7;
450 u16 t9;
451 u16 t10;
452 u16 t12;
453} __attribute__ ((packed));
454
455struct edp_link_params {
456 u8 rate:4;
457 u8 lanes:4;
458 u8 preemphasis:4;
459 u8 vswing:4;
460} __attribute__ ((packed));
461
462struct bdb_edp {
463 struct edp_power_seq power_seqs[16];
464 u32 color_depth;
465 u32 sdrrs_msa_timing_delay;
466 struct edp_link_params link_params[16];
467} __attribute__ ((packed));
468
429bool intel_init_bios(struct drm_device *dev); 469bool intel_init_bios(struct drm_device *dev);
430 470
431/* 471/*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 002612fae717..45da78ef4a92 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -70,8 +70,6 @@ struct intel_limit {
70 intel_p2_t p2; 70 intel_p2_t p2;
71 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, 71 bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
72 int, int, intel_clock_t *); 72 int, int, intel_clock_t *);
73 bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
74 int, int, intel_clock_t *);
75}; 73};
76 74
77#define I8XX_DOT_MIN 25000 75#define I8XX_DOT_MIN 25000
@@ -243,11 +241,11 @@ struct intel_limit {
243#define IRONLAKE_VCO_MIN 1760000 241#define IRONLAKE_VCO_MIN 1760000
244#define IRONLAKE_VCO_MAX 3510000 242#define IRONLAKE_VCO_MAX 3510000
245#define IRONLAKE_N_MIN 1 243#define IRONLAKE_N_MIN 1
246#define IRONLAKE_N_MAX 5 244#define IRONLAKE_N_MAX 6
247#define IRONLAKE_M_MIN 79 245#define IRONLAKE_M_MIN 79
248#define IRONLAKE_M_MAX 118 246#define IRONLAKE_M_MAX 127
249#define IRONLAKE_M1_MIN 12 247#define IRONLAKE_M1_MIN 12
250#define IRONLAKE_M1_MAX 23 248#define IRONLAKE_M1_MAX 22
251#define IRONLAKE_M2_MIN 5 249#define IRONLAKE_M2_MIN 5
252#define IRONLAKE_M2_MAX 9 250#define IRONLAKE_M2_MAX 9
253#define IRONLAKE_P_SDVO_DAC_MIN 5 251#define IRONLAKE_P_SDVO_DAC_MIN 5
@@ -274,9 +272,6 @@ static bool
274intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 272intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
275 int target, int refclk, intel_clock_t *best_clock); 273 int target, int refclk, intel_clock_t *best_clock);
276static bool 274static bool
277intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
278 int target, int refclk, intel_clock_t *best_clock);
279static bool
280intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 275intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
281 int target, int refclk, intel_clock_t *best_clock); 276 int target, int refclk, intel_clock_t *best_clock);
282 277
@@ -299,7 +294,6 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
299 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 294 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
300 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, 295 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
301 .find_pll = intel_find_best_PLL, 296 .find_pll = intel_find_best_PLL,
302 .find_reduced_pll = intel_find_best_reduced_PLL,
303}; 297};
304 298
305static const intel_limit_t intel_limits_i8xx_lvds = { 299static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -314,7 +308,6 @@ static const intel_limit_t intel_limits_i8xx_lvds = {
314 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, 308 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
315 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, 309 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
316 .find_pll = intel_find_best_PLL, 310 .find_pll = intel_find_best_PLL,
317 .find_reduced_pll = intel_find_best_reduced_PLL,
318}; 311};
319 312
320static const intel_limit_t intel_limits_i9xx_sdvo = { 313static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -329,7 +322,6 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
329 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 322 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
330 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 323 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
331 .find_pll = intel_find_best_PLL, 324 .find_pll = intel_find_best_PLL,
332 .find_reduced_pll = intel_find_best_reduced_PLL,
333}; 325};
334 326
335static const intel_limit_t intel_limits_i9xx_lvds = { 327static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -347,7 +339,6 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
347 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 339 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
348 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, 340 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
349 .find_pll = intel_find_best_PLL, 341 .find_pll = intel_find_best_PLL,
350 .find_reduced_pll = intel_find_best_reduced_PLL,
351}; 342};
352 343
353 /* below parameter and function is for G4X Chipset Family*/ 344 /* below parameter and function is for G4X Chipset Family*/
@@ -365,7 +356,6 @@ static const intel_limit_t intel_limits_g4x_sdvo = {
365 .p2_fast = G4X_P2_SDVO_FAST 356 .p2_fast = G4X_P2_SDVO_FAST
366 }, 357 },
367 .find_pll = intel_g4x_find_best_PLL, 358 .find_pll = intel_g4x_find_best_PLL,
368 .find_reduced_pll = intel_g4x_find_best_PLL,
369}; 359};
370 360
371static const intel_limit_t intel_limits_g4x_hdmi = { 361static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -382,7 +372,6 @@ static const intel_limit_t intel_limits_g4x_hdmi = {
382 .p2_fast = G4X_P2_HDMI_DAC_FAST 372 .p2_fast = G4X_P2_HDMI_DAC_FAST
383 }, 373 },
384 .find_pll = intel_g4x_find_best_PLL, 374 .find_pll = intel_g4x_find_best_PLL,
385 .find_reduced_pll = intel_g4x_find_best_PLL,
386}; 375};
387 376
388static const intel_limit_t intel_limits_g4x_single_channel_lvds = { 377static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -407,7 +396,6 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
407 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST 396 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
408 }, 397 },
409 .find_pll = intel_g4x_find_best_PLL, 398 .find_pll = intel_g4x_find_best_PLL,
410 .find_reduced_pll = intel_g4x_find_best_PLL,
411}; 399};
412 400
413static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { 401static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -432,7 +420,6 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
432 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST 420 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
433 }, 421 },
434 .find_pll = intel_g4x_find_best_PLL, 422 .find_pll = intel_g4x_find_best_PLL,
435 .find_reduced_pll = intel_g4x_find_best_PLL,
436}; 423};
437 424
438static const intel_limit_t intel_limits_g4x_display_port = { 425static const intel_limit_t intel_limits_g4x_display_port = {
@@ -470,7 +457,6 @@ static const intel_limit_t intel_limits_pineview_sdvo = {
470 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, 457 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
471 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, 458 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
472 .find_pll = intel_find_best_PLL, 459 .find_pll = intel_find_best_PLL,
473 .find_reduced_pll = intel_find_best_reduced_PLL,
474}; 460};
475 461
476static const intel_limit_t intel_limits_pineview_lvds = { 462static const intel_limit_t intel_limits_pineview_lvds = {
@@ -486,7 +472,6 @@ static const intel_limit_t intel_limits_pineview_lvds = {
486 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, 472 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
487 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, 473 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
488 .find_pll = intel_find_best_PLL, 474 .find_pll = intel_find_best_PLL,
489 .find_reduced_pll = intel_find_best_reduced_PLL,
490}; 475};
491 476
492static const intel_limit_t intel_limits_ironlake_sdvo = { 477static const intel_limit_t intel_limits_ironlake_sdvo = {
@@ -768,46 +753,6 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
768 return (err != target); 753 return (err != target);
769} 754}
770 755
771
772static bool
773intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
774 int target, int refclk, intel_clock_t *best_clock)
775
776{
777 struct drm_device *dev = crtc->dev;
778 intel_clock_t clock;
779 int err = target;
780 bool found = false;
781
782 memcpy(&clock, best_clock, sizeof(intel_clock_t));
783
784 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
785 for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
786 /* m1 is always 0 in Pineview */
787 if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev))
788 break;
789 for (clock.n = limit->n.min; clock.n <= limit->n.max;
790 clock.n++) {
791 int this_err;
792
793 intel_clock(dev, refclk, &clock);
794
795 if (!intel_PLL_is_valid(crtc, &clock))
796 continue;
797
798 this_err = abs(clock.dot - target);
799 if (this_err < err) {
800 *best_clock = clock;
801 err = this_err;
802 found = true;
803 }
804 }
805 }
806 }
807
808 return found;
809}
810
811static bool 756static bool
812intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, 757intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
813 int target, int refclk, intel_clock_t *best_clock) 758 int target, int refclk, intel_clock_t *best_clock)
@@ -1262,7 +1207,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1262 return ret; 1207 return ret;
1263 } 1208 }
1264 1209
1265 ret = i915_gem_object_set_to_gtt_domain(obj, 1); 1210 ret = i915_gem_object_set_to_display_plane(obj);
1266 if (ret != 0) { 1211 if (ret != 0) {
1267 i915_gem_object_unpin(obj); 1212 i915_gem_object_unpin(obj);
1268 mutex_unlock(&dev->struct_mutex); 1213 mutex_unlock(&dev->struct_mutex);
@@ -2910,10 +2855,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2910 return -EINVAL; 2855 return -EINVAL;
2911 } 2856 }
2912 2857
2913 if (is_lvds && limit->find_reduced_pll && 2858 if (is_lvds && dev_priv->lvds_downclock_avail) {
2914 dev_priv->lvds_downclock_avail) { 2859 has_reduced_clock = limit->find_pll(limit, crtc,
2915 memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
2916 has_reduced_clock = limit->find_reduced_pll(limit, crtc,
2917 dev_priv->lvds_downclock, 2860 dev_priv->lvds_downclock,
2918 refclk, 2861 refclk,
2919 &reduced_clock); 2862 &reduced_clock);
@@ -2981,6 +2924,21 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2981 temp |= PIPE_8BPC; 2924 temp |= PIPE_8BPC;
2982 else 2925 else
2983 temp |= PIPE_6BPC; 2926 temp |= PIPE_6BPC;
2927 } else if (is_edp) {
2928 switch (dev_priv->edp_bpp/3) {
2929 case 8:
2930 temp |= PIPE_8BPC;
2931 break;
2932 case 10:
2933 temp |= PIPE_10BPC;
2934 break;
2935 case 6:
2936 temp |= PIPE_6BPC;
2937 break;
2938 case 12:
2939 temp |= PIPE_12BPC;
2940 break;
2941 }
2984 } else 2942 } else
2985 temp |= PIPE_8BPC; 2943 temp |= PIPE_8BPC;
2986 I915_WRITE(pipeconf_reg, temp); 2944 I915_WRITE(pipeconf_reg, temp);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1349d9fd01c4..439506cefc14 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -125,9 +125,15 @@ intel_dp_link_clock(uint8_t link_bw)
125 125
126/* I think this is a fiction */ 126/* I think this is a fiction */
127static int 127static int
128intel_dp_link_required(int pixel_clock) 128intel_dp_link_required(struct drm_device *dev,
129 struct intel_output *intel_output, int pixel_clock)
129{ 130{
130 return pixel_clock * 3; 131 struct drm_i915_private *dev_priv = dev->dev_private;
132
133 if (IS_eDP(intel_output))
134 return (pixel_clock * dev_priv->edp_bpp) / 8;
135 else
136 return pixel_clock * 3;
131} 137}
132 138
133static int 139static int
@@ -138,7 +144,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
138 int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); 144 int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
139 int max_lanes = intel_dp_max_lane_count(intel_output); 145 int max_lanes = intel_dp_max_lane_count(intel_output);
140 146
141 if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes) 147 if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
148 > max_link_clock * max_lanes)
142 return MODE_CLOCK_HIGH; 149 return MODE_CLOCK_HIGH;
143 150
144 if (mode->clock < 10000) 151 if (mode->clock < 10000)
@@ -492,7 +499,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
492 for (clock = 0; clock <= max_clock; clock++) { 499 for (clock = 0; clock <= max_clock; clock++) {
493 int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; 500 int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
494 501
495 if (intel_dp_link_required(mode->clock) <= link_avail) { 502 if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
503 <= link_avail) {
496 dp_priv->link_bw = bws[clock]; 504 dp_priv->link_bw = bws[clock];
497 dp_priv->lane_count = lane_count; 505 dp_priv->lane_count = lane_count;
498 adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); 506 adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
@@ -1289,53 +1297,7 @@ intel_dp_hot_plug(struct intel_output *intel_output)
1289 if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) 1297 if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
1290 intel_dp_check_link_status(intel_output); 1298 intel_dp_check_link_status(intel_output);
1291} 1299}
1292/* 1300
1293 * Enumerate the child dev array parsed from VBT to check whether
1294 * the given DP is present.
1295 * If it is present, return 1.
1296 * If it is not present, return false.
1297 * If no child dev is parsed from VBT, it is assumed that the given
1298 * DP is present.
1299 */
1300static int dp_is_present_in_vbt(struct drm_device *dev, int dp_reg)
1301{
1302 struct drm_i915_private *dev_priv = dev->dev_private;
1303 struct child_device_config *p_child;
1304 int i, dp_port, ret;
1305
1306 if (!dev_priv->child_dev_num)
1307 return 1;
1308
1309 dp_port = 0;
1310 if (dp_reg == DP_B || dp_reg == PCH_DP_B)
1311 dp_port = PORT_IDPB;
1312 else if (dp_reg == DP_C || dp_reg == PCH_DP_C)
1313 dp_port = PORT_IDPC;
1314 else if (dp_reg == DP_D || dp_reg == PCH_DP_D)
1315 dp_port = PORT_IDPD;
1316
1317 ret = 0;
1318 for (i = 0; i < dev_priv->child_dev_num; i++) {
1319 p_child = dev_priv->child_dev + i;
1320 /*
1321 * If the device type is not DP, continue.
1322 */
1323 if (p_child->device_type != DEVICE_TYPE_DP &&
1324 p_child->device_type != DEVICE_TYPE_eDP)
1325 continue;
1326 /* Find the eDP port */
1327 if (dp_reg == DP_A && p_child->device_type == DEVICE_TYPE_eDP) {
1328 ret = 1;
1329 break;
1330 }
1331 /* Find the DP port */
1332 if (p_child->dvo_port == dp_port) {
1333 ret = 1;
1334 break;
1335 }
1336 }
1337 return ret;
1338}
1339void 1301void
1340intel_dp_init(struct drm_device *dev, int output_reg) 1302intel_dp_init(struct drm_device *dev, int output_reg)
1341{ 1303{
@@ -1345,10 +1307,6 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1345 struct intel_dp_priv *dp_priv; 1307 struct intel_dp_priv *dp_priv;
1346 const char *name = NULL; 1308 const char *name = NULL;
1347 1309
1348 if (!dp_is_present_in_vbt(dev, output_reg)) {
1349 DRM_DEBUG_KMS("DP is not present. Ignore it\n");
1350 return;
1351 }
1352 intel_output = kcalloc(sizeof(struct intel_output) + 1310 intel_output = kcalloc(sizeof(struct intel_output) +
1353 sizeof(struct intel_dp_priv), 1, GFP_KERNEL); 1311 sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
1354 if (!intel_output) 1312 if (!intel_output)
@@ -1373,11 +1331,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1373 else if (output_reg == DP_D || output_reg == PCH_DP_D) 1331 else if (output_reg == DP_D || output_reg == PCH_DP_D)
1374 intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); 1332 intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
1375 1333
1376 if (IS_eDP(intel_output)) { 1334 if (IS_eDP(intel_output))
1377 intel_output->crtc_mask = (1 << 1);
1378 intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); 1335 intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
1379 } else 1336
1380 intel_output->crtc_mask = (1 << 0) | (1 << 1); 1337 intel_output->crtc_mask = (1 << 0) | (1 << 1);
1381 connector->interlace_allowed = true; 1338 connector->interlace_allowed = true;
1382 connector->doublescan_allowed = 0; 1339 connector->doublescan_allowed = 0;
1383 1340
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 06431941b233..0e268deed761 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -225,52 +225,6 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
225 .destroy = intel_hdmi_enc_destroy, 225 .destroy = intel_hdmi_enc_destroy,
226}; 226};
227 227
228/*
229 * Enumerate the child dev array parsed from VBT to check whether
230 * the given HDMI is present.
231 * If it is present, return 1.
232 * If it is not present, return false.
233 * If no child dev is parsed from VBT, it assumes that the given
234 * HDMI is present.
235 */
236static int hdmi_is_present_in_vbt(struct drm_device *dev, int hdmi_reg)
237{
238 struct drm_i915_private *dev_priv = dev->dev_private;
239 struct child_device_config *p_child;
240 int i, hdmi_port, ret;
241
242 if (!dev_priv->child_dev_num)
243 return 1;
244
245 if (hdmi_reg == SDVOB)
246 hdmi_port = DVO_B;
247 else if (hdmi_reg == SDVOC)
248 hdmi_port = DVO_C;
249 else if (hdmi_reg == HDMIB)
250 hdmi_port = DVO_B;
251 else if (hdmi_reg == HDMIC)
252 hdmi_port = DVO_C;
253 else if (hdmi_reg == HDMID)
254 hdmi_port = DVO_D;
255 else
256 return 0;
257
258 ret = 0;
259 for (i = 0; i < dev_priv->child_dev_num; i++) {
260 p_child = dev_priv->child_dev + i;
261 /*
262 * If the device type is not HDMI, continue.
263 */
264 if (p_child->device_type != DEVICE_TYPE_HDMI)
265 continue;
266 /* Find the HDMI port */
267 if (p_child->dvo_port == hdmi_port) {
268 ret = 1;
269 break;
270 }
271 }
272 return ret;
273}
274void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) 228void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
275{ 229{
276 struct drm_i915_private *dev_priv = dev->dev_private; 230 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -278,10 +232,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
278 struct intel_output *intel_output; 232 struct intel_output *intel_output;
279 struct intel_hdmi_priv *hdmi_priv; 233 struct intel_hdmi_priv *hdmi_priv;
280 234
281 if (!hdmi_is_present_in_vbt(dev, sdvox_reg)) {
282 DRM_DEBUG_KMS("HDMI is not present. Ignored it \n");
283 return;
284 }
285 intel_output = kcalloc(sizeof(struct intel_output) + 235 intel_output = kcalloc(sizeof(struct intel_output) +
286 sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); 236 sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
287 if (!intel_output) 237 if (!intel_output)
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index f4b4aa242df1..aa74e59bec61 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -602,6 +602,20 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
602/* Some lid devices report incorrect lid status, assume they're connected */ 602/* Some lid devices report incorrect lid status, assume they're connected */
603static const struct dmi_system_id bad_lid_status[] = { 603static const struct dmi_system_id bad_lid_status[] = {
604 { 604 {
605 .ident = "Compaq nx9020",
606 .matches = {
607 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
608 DMI_MATCH(DMI_BOARD_NAME, "3084"),
609 },
610 },
611 {
612 .ident = "Samsung SX20S",
613 .matches = {
614 DMI_MATCH(DMI_SYS_VENDOR, "Phoenix Technologies LTD"),
615 DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
616 },
617 },
618 {
605 .ident = "Aspire One", 619 .ident = "Aspire One",
606 .matches = { 620 .matches = {
607 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 621 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -912,7 +926,8 @@ static void intel_find_lvds_downclock(struct drm_device *dev,
912 } 926 }
913 } 927 }
914 mutex_unlock(&dev->mode_config.mutex); 928 mutex_unlock(&dev->mode_config.mutex);
915 if (temp_downclock < panel_fixed_mode->clock) { 929 if (temp_downclock < panel_fixed_mode->clock &&
930 i915_lvds_downclock) {
916 /* We found the downclock for LVDS. */ 931 /* We found the downclock for LVDS. */
917 dev_priv->lvds_downclock_avail = 1; 932 dev_priv->lvds_downclock_avail = 1;
918 dev_priv->lvds_downclock = temp_downclock; 933 dev_priv->lvds_downclock = temp_downclock;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index de5144c8c153..eaacfd0920df 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -462,14 +462,63 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
462} 462}
463 463
464/** 464/**
465 * Don't check status code from this as it switches the bus back to the 465 * Try to read the response after issuie the DDC switch command. But it
466 * SDVO chips which defeats the purpose of doing a bus switch in the first 466 * is noted that we must do the action of reading response and issuing DDC
467 * place. 467 * switch command in one I2C transaction. Otherwise when we try to start
468 * another I2C transaction after issuing the DDC bus switch, it will be
469 * switched to the internal SDVO register.
468 */ 470 */
469static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, 471static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
470 u8 target) 472 u8 target)
471{ 473{
472 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1); 474 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
475 u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
476 struct i2c_msg msgs[] = {
477 {
478 .addr = sdvo_priv->slave_addr >> 1,
479 .flags = 0,
480 .len = 2,
481 .buf = out_buf,
482 },
483 /* the following two are to read the response */
484 {
485 .addr = sdvo_priv->slave_addr >> 1,
486 .flags = 0,
487 .len = 1,
488 .buf = cmd_buf,
489 },
490 {
491 .addr = sdvo_priv->slave_addr >> 1,
492 .flags = I2C_M_RD,
493 .len = 1,
494 .buf = ret_value,
495 },
496 };
497
498 intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
499 &target, 1);
500 /* write the DDC switch command argument */
501 intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
502
503 out_buf[0] = SDVO_I2C_OPCODE;
504 out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
505 cmd_buf[0] = SDVO_I2C_CMD_STATUS;
506 cmd_buf[1] = 0;
507 ret_value[0] = 0;
508 ret_value[1] = 0;
509
510 ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
511 if (ret != 3) {
512 /* failure in I2C transfer */
513 DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
514 return;
515 }
516 if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) {
517 DRM_DEBUG_KMS("DDC switch command returns response %d\n",
518 ret_value[0]);
519 return;
520 }
521 return;
473} 522}
474 523
475static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) 524static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
@@ -1579,6 +1628,32 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1579 edid = drm_get_edid(&intel_output->base, 1628 edid = drm_get_edid(&intel_output->base,
1580 intel_output->ddc_bus); 1629 intel_output->ddc_bus);
1581 1630
1631 /* This is only applied to SDVO cards with multiple outputs */
1632 if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
1633 uint8_t saved_ddc, temp_ddc;
1634 saved_ddc = sdvo_priv->ddc_bus;
1635 temp_ddc = sdvo_priv->ddc_bus >> 1;
1636 /*
1637 * Don't use the 1 as the argument of DDC bus switch to get
1638 * the EDID. It is used for SDVO SPD ROM.
1639 */
1640 while(temp_ddc > 1) {
1641 sdvo_priv->ddc_bus = temp_ddc;
1642 edid = drm_get_edid(&intel_output->base,
1643 intel_output->ddc_bus);
1644 if (edid) {
1645 /*
1646 * When we can get the EDID, maybe it is the
1647 * correct DDC bus. Update it.
1648 */
1649 sdvo_priv->ddc_bus = temp_ddc;
1650 break;
1651 }
1652 temp_ddc >>= 1;
1653 }
1654 if (edid == NULL)
1655 sdvo_priv->ddc_bus = saved_ddc;
1656 }
1582 /* when there is no edid and no monitor is connected with VGA 1657 /* when there is no edid and no monitor is connected with VGA
1583 * port, try to use the CRT ddc to read the EDID for DVI-connector 1658 * port, try to use the CRT ddc to read the EDID for DVI-connector
1584 */ 1659 */
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 1d5b9b7b033f..552ec110b741 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1840,8 +1840,6 @@ intel_tv_init(struct drm_device *dev)
1840 drm_connector_attach_property(connector, 1840 drm_connector_attach_property(connector,
1841 dev->mode_config.tv_bottom_margin_property, 1841 dev->mode_config.tv_bottom_margin_property,
1842 tv_priv->margin[TV_MARGIN_BOTTOM]); 1842 tv_priv->margin[TV_MARGIN_BOTTOM]);
1843
1844 dev_priv->hotplug_supported_mask |= TV_HOTPLUG_INT_STATUS;
1845out: 1843out:
1846 drm_sysfs_connector_add(connector); 1844 drm_sysfs_connector_add(connector);
1847} 1845}