diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/dvo_ch7017.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 12 |
8 files changed, 103 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index af70337567c..d3e8c540f77 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -242,7 +242,7 @@ fail: | |||
242 | 242 | ||
243 | static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) | 243 | static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) |
244 | { | 244 | { |
245 | return connector_status_unknown; | 245 | return connector_status_connected; |
246 | } | 246 | } |
247 | 247 | ||
248 | static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, | 248 | static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e6800819bca..cb900dc83d9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
36 | #include "i915_trace.h" | 36 | #include "i915_trace.h" |
37 | #include "../../../platform/x86/intel_ips.h" | ||
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
38 | #include <linux/vgaarb.h> | 39 | #include <linux/vgaarb.h> |
39 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
@@ -1871,6 +1872,26 @@ out_unlock: | |||
1871 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); | 1872 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); |
1872 | 1873 | ||
1873 | /** | 1874 | /** |
1875 | * Tells the intel_ips driver that the i915 driver is now loaded, if | ||
1876 | * IPS got loaded first. | ||
1877 | * | ||
1878 | * This awkward dance is so that neither module has to depend on the | ||
1879 | * other in order for IPS to do the appropriate communication of | ||
1880 | * GPU turbo limits to i915. | ||
1881 | */ | ||
1882 | static void | ||
1883 | ips_ping_for_i915_load(void) | ||
1884 | { | ||
1885 | void (*link)(void); | ||
1886 | |||
1887 | link = symbol_get(ips_link_to_i915_driver); | ||
1888 | if (link) { | ||
1889 | link(); | ||
1890 | symbol_put(ips_link_to_i915_driver); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | /** | ||
1874 | * i915_driver_load - setup chip and create an initial config | 1895 | * i915_driver_load - setup chip and create an initial config |
1875 | * @dev: DRM device | 1896 | * @dev: DRM device |
1876 | * @flags: startup flags | 1897 | * @flags: startup flags |
@@ -2075,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2075 | dev_priv->mchdev_lock = &mchdev_lock; | 2096 | dev_priv->mchdev_lock = &mchdev_lock; |
2076 | spin_unlock(&mchdev_lock); | 2097 | spin_unlock(&mchdev_lock); |
2077 | 2098 | ||
2099 | ips_ping_for_i915_load(); | ||
2100 | |||
2078 | return 0; | 2101 | return 0; |
2079 | 2102 | ||
2080 | out_workqueue_free: | 2103 | out_workqueue_free: |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 878fc766a12..cb8f4342927 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2471,6 +2471,9 @@ | |||
2471 | # define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) | 2471 | # define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) |
2472 | # define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) | 2472 | # define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) |
2473 | 2473 | ||
2474 | #define PCH_3DCGDIS1 0x46024 | ||
2475 | # define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11) | ||
2476 | |||
2474 | #define FDI_PLL_FREQ_CTL 0x46030 | 2477 | #define FDI_PLL_FREQ_CTL 0x46030 |
2475 | #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) | 2478 | #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) |
2476 | #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 | 2479 | #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 |
@@ -2588,6 +2591,13 @@ | |||
2588 | #define ILK_DISPLAY_CHICKEN2 0x42004 | 2591 | #define ILK_DISPLAY_CHICKEN2 0x42004 |
2589 | #define ILK_DPARB_GATE (1<<22) | 2592 | #define ILK_DPARB_GATE (1<<22) |
2590 | #define ILK_VSDPFD_FULL (1<<21) | 2593 | #define ILK_VSDPFD_FULL (1<<21) |
2594 | #define ILK_DISPLAY_CHICKEN_FUSES 0x42014 | ||
2595 | #define ILK_INTERNAL_GRAPHICS_DISABLE (1<<31) | ||
2596 | #define ILK_INTERNAL_DISPLAY_DISABLE (1<<30) | ||
2597 | #define ILK_DISPLAY_DEBUG_DISABLE (1<<29) | ||
2598 | #define ILK_HDCP_DISABLE (1<<25) | ||
2599 | #define ILK_eDP_A_DISABLE (1<<24) | ||
2600 | #define ILK_DESKTOP (1<<23) | ||
2591 | #define ILK_DSPCLK_GATE 0x42020 | 2601 | #define ILK_DSPCLK_GATE 0x42020 |
2592 | #define ILK_DPARB_CLK_GATE (1<<5) | 2602 | #define ILK_DPARB_CLK_GATE (1<<5) |
2593 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ | 2603 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d9b7092439e..fca523288ac 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -5379,6 +5379,23 @@ static int intel_encoder_clones(struct drm_device *dev, int type_mask) | |||
5379 | return index_mask; | 5379 | return index_mask; |
5380 | } | 5380 | } |
5381 | 5381 | ||
5382 | static bool has_edp_a(struct drm_device *dev) | ||
5383 | { | ||
5384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5385 | |||
5386 | if (!IS_MOBILE(dev)) | ||
5387 | return false; | ||
5388 | |||
5389 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) | ||
5390 | return false; | ||
5391 | |||
5392 | if (IS_GEN5(dev) && | ||
5393 | (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) | ||
5394 | return false; | ||
5395 | |||
5396 | return true; | ||
5397 | } | ||
5398 | |||
5382 | static void intel_setup_outputs(struct drm_device *dev) | 5399 | static void intel_setup_outputs(struct drm_device *dev) |
5383 | { | 5400 | { |
5384 | struct drm_i915_private *dev_priv = dev->dev_private; | 5401 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5396,7 +5413,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5396 | if (HAS_PCH_SPLIT(dev)) { | 5413 | if (HAS_PCH_SPLIT(dev)) { |
5397 | dpd_is_edp = intel_dpd_is_edp(dev); | 5414 | dpd_is_edp = intel_dpd_is_edp(dev); |
5398 | 5415 | ||
5399 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | 5416 | if (has_edp_a(dev)) |
5400 | intel_dp_init(dev, DP_A); | 5417 | intel_dp_init(dev, DP_A); |
5401 | 5418 | ||
5402 | if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) | 5419 | if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) |
@@ -5825,6 +5842,8 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5825 | I915_WRITE(PCH_3DCGDIS0, | 5842 | I915_WRITE(PCH_3DCGDIS0, |
5826 | MARIUNIT_CLOCK_GATE_DISABLE | | 5843 | MARIUNIT_CLOCK_GATE_DISABLE | |
5827 | SVSMUNIT_CLOCK_GATE_DISABLE); | 5844 | SVSMUNIT_CLOCK_GATE_DISABLE); |
5845 | I915_WRITE(PCH_3DCGDIS1, | ||
5846 | VFMUNIT_CLOCK_GATE_DISABLE); | ||
5828 | } | 5847 | } |
5829 | 5848 | ||
5830 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | 5849 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index df648cb4c29..864417cffe9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
479 | uint16_t address = algo_data->address; | 479 | uint16_t address = algo_data->address; |
480 | uint8_t msg[5]; | 480 | uint8_t msg[5]; |
481 | uint8_t reply[2]; | 481 | uint8_t reply[2]; |
482 | unsigned retry; | ||
482 | int msg_bytes; | 483 | int msg_bytes; |
483 | int reply_bytes; | 484 | int reply_bytes; |
484 | int ret; | 485 | int ret; |
@@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
513 | break; | 514 | break; |
514 | } | 515 | } |
515 | 516 | ||
516 | for (;;) { | 517 | for (retry = 0; retry < 5; retry++) { |
517 | ret = intel_dp_aux_ch(intel_dp, | 518 | ret = intel_dp_aux_ch(intel_dp, |
518 | msg, msg_bytes, | 519 | msg, msg_bytes, |
519 | reply, reply_bytes); | 520 | reply, reply_bytes); |
520 | if (ret < 0) { | 521 | if (ret < 0) { |
521 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); | 522 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); |
522 | return ret; | 523 | return ret; |
523 | } | 524 | } |
525 | |||
526 | switch (reply[0] & AUX_NATIVE_REPLY_MASK) { | ||
527 | case AUX_NATIVE_REPLY_ACK: | ||
528 | /* I2C-over-AUX Reply field is only valid | ||
529 | * when paired with AUX ACK. | ||
530 | */ | ||
531 | break; | ||
532 | case AUX_NATIVE_REPLY_NACK: | ||
533 | DRM_DEBUG_KMS("aux_ch native nack\n"); | ||
534 | return -EREMOTEIO; | ||
535 | case AUX_NATIVE_REPLY_DEFER: | ||
536 | udelay(100); | ||
537 | continue; | ||
538 | default: | ||
539 | DRM_ERROR("aux_ch invalid native reply 0x%02x\n", | ||
540 | reply[0]); | ||
541 | return -EREMOTEIO; | ||
542 | } | ||
543 | |||
524 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | 544 | switch (reply[0] & AUX_I2C_REPLY_MASK) { |
525 | case AUX_I2C_REPLY_ACK: | 545 | case AUX_I2C_REPLY_ACK: |
526 | if (mode == MODE_I2C_READ) { | 546 | if (mode == MODE_I2C_READ) { |
@@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
528 | } | 548 | } |
529 | return reply_bytes - 1; | 549 | return reply_bytes - 1; |
530 | case AUX_I2C_REPLY_NACK: | 550 | case AUX_I2C_REPLY_NACK: |
531 | DRM_DEBUG_KMS("aux_ch nack\n"); | 551 | DRM_DEBUG_KMS("aux_i2c nack\n"); |
532 | return -EREMOTEIO; | 552 | return -EREMOTEIO; |
533 | case AUX_I2C_REPLY_DEFER: | 553 | case AUX_I2C_REPLY_DEFER: |
534 | DRM_DEBUG_KMS("aux_ch defer\n"); | 554 | DRM_DEBUG_KMS("aux_i2c defer\n"); |
535 | udelay(100); | 555 | udelay(100); |
536 | break; | 556 | break; |
537 | default: | 557 | default: |
538 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); | 558 | DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); |
539 | return -EREMOTEIO; | 559 | return -EREMOTEIO; |
540 | } | 560 | } |
541 | } | 561 | } |
562 | |||
563 | DRM_ERROR("too many retries, giving up\n"); | ||
564 | return -EREMOTEIO; | ||
542 | } | 565 | } |
543 | 566 | ||
544 | static int | 567 | static int |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 89a65be8a3f..31cd7e33e82 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -696,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev, | |||
696 | drm_i915_private_t *dev_priv = dev->dev_private; | 696 | drm_i915_private_t *dev_priv = dev->dev_private; |
697 | u32 head; | 697 | u32 head; |
698 | 698 | ||
699 | head = intel_read_status_page(ring, 4); | ||
700 | if (head) { | ||
701 | ring->head = head & HEAD_ADDR; | ||
702 | ring->space = ring->head - (ring->tail + 8); | ||
703 | if (ring->space < 0) | ||
704 | ring->space += ring->size; | ||
705 | if (ring->space >= n) | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | trace_i915_ring_wait_begin (dev); | 699 | trace_i915_ring_wait_begin (dev); |
710 | end = jiffies + 3 * HZ; | 700 | end = jiffies + 3 * HZ; |
711 | do { | 701 | do { |
712 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; | 702 | /* If the reported head position has wrapped or hasn't advanced, |
703 | * fallback to the slow and accurate path. | ||
704 | */ | ||
705 | head = intel_read_status_page(ring, 4); | ||
706 | if (head < ring->actual_head) | ||
707 | head = I915_READ_HEAD(ring); | ||
708 | ring->actual_head = head; | ||
709 | ring->head = head & HEAD_ADDR; | ||
713 | ring->space = ring->head - (ring->tail + 8); | 710 | ring->space = ring->head - (ring->tail + 8); |
714 | if (ring->space < 0) | 711 | if (ring->space < 0) |
715 | ring->space += ring->size; | 712 | ring->space += ring->size; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c268198..d2cd0f1efee 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -30,8 +30,9 @@ struct intel_ring_buffer { | |||
30 | struct drm_device *dev; | 30 | struct drm_device *dev; |
31 | struct drm_gem_object *gem_object; | 31 | struct drm_gem_object *gem_object; |
32 | 32 | ||
33 | unsigned int head; | 33 | u32 actual_head; |
34 | unsigned int tail; | 34 | u32 head; |
35 | u32 tail; | ||
35 | int space; | 36 | int space; |
36 | struct intel_hw_status_page status_page; | 37 | struct intel_hw_status_page status_page; |
37 | 38 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d97e6cb52d3..6bc42fa2a6e 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1908,9 +1908,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | |||
1908 | speed = mapping->i2c_speed; | 1908 | speed = mapping->i2c_speed; |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; | 1911 | if (pin < GMBUS_NUM_PORTS) { |
1912 | intel_gmbus_set_speed(sdvo->i2c, speed); | 1912 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; |
1913 | intel_gmbus_force_bit(sdvo->i2c, true); | 1913 | intel_gmbus_set_speed(sdvo->i2c, speed); |
1914 | intel_gmbus_force_bit(sdvo->i2c, true); | ||
1915 | } else | ||
1916 | sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; | ||
1914 | } | 1917 | } |
1915 | 1918 | ||
1916 | static bool | 1919 | static bool |
@@ -2037,13 +2040,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2037 | SDVO_COLORIMETRY_RGB256); | 2040 | SDVO_COLORIMETRY_RGB256); |
2038 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2041 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2039 | 2042 | ||
2040 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2041 | intel_sdvo->is_hdmi = true; | 2043 | intel_sdvo->is_hdmi = true; |
2042 | } | 2044 | } |
2043 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2045 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2044 | (1 << INTEL_ANALOG_CLONE_BIT)); | 2046 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2045 | 2047 | ||
2046 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2048 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2049 | if (intel_sdvo->is_hdmi) | ||
2050 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2047 | 2051 | ||
2048 | return true; | 2052 | return true; |
2049 | } | 2053 | } |