diff options
| -rw-r--r-- | drivers/gpu/drm/i915/dvo_tfp410.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 76 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 60 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 10 |
12 files changed, 140 insertions, 64 deletions
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 66c697bc9b22..56f66426207f 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
| @@ -208,7 +208,7 @@ static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo) | |||
| 208 | uint8_t ctl2; | 208 | uint8_t ctl2; |
| 209 | 209 | ||
| 210 | if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) { | 210 | if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) { |
| 211 | if (ctl2 & TFP410_CTL_2_HTPLG) | 211 | if (ctl2 & TFP410_CTL_2_RSEN) |
| 212 | ret = connector_status_connected; | 212 | ret = connector_status_connected; |
| 213 | else | 213 | else |
| 214 | ret = connector_status_disconnected; | 214 | ret = connector_status_disconnected; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 52510ad8b25d..aee83fa178f6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -620,7 +620,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
| 620 | drm_i915_private_t *dev_priv = dev->dev_private; | 620 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 621 | bool sr_enabled = false; | 621 | bool sr_enabled = false; |
| 622 | 622 | ||
| 623 | if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev)) | 623 | if (IS_I965GM(dev) || IS_I945G(dev) || IS_I945GM(dev)) |
| 624 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; | 624 | sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; |
| 625 | else if (IS_I915GM(dev)) | 625 | else if (IS_I915GM(dev)) |
| 626 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; | 626 | sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 59a2bf8592ec..f00c5ae9556c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -128,9 +128,11 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
| 128 | if (dev->irq_enabled) | 128 | if (dev->irq_enabled) |
| 129 | drm_irq_uninstall(dev); | 129 | drm_irq_uninstall(dev); |
| 130 | 130 | ||
| 131 | mutex_lock(&dev->struct_mutex); | ||
| 131 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | 132 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); |
| 132 | if (HAS_BSD(dev)) | 133 | if (HAS_BSD(dev)) |
| 133 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | 134 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); |
| 135 | mutex_unlock(&dev->struct_mutex); | ||
| 134 | 136 | ||
| 135 | /* Clear the HWS virtual address at teardown */ | 137 | /* Clear the HWS virtual address at teardown */ |
| 136 | if (I915_NEED_GFX_HWS(dev)) | 138 | if (I915_NEED_GFX_HWS(dev)) |
| @@ -1229,7 +1231,7 @@ static void i915_warn_stolen(struct drm_device *dev) | |||
| 1229 | static void i915_setup_compression(struct drm_device *dev, int size) | 1231 | static void i915_setup_compression(struct drm_device *dev, int size) |
| 1230 | { | 1232 | { |
| 1231 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1232 | struct drm_mm_node *compressed_fb, *compressed_llb; | 1234 | struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); |
| 1233 | unsigned long cfb_base; | 1235 | unsigned long cfb_base; |
| 1234 | unsigned long ll_base = 0; | 1236 | unsigned long ll_base = 0; |
| 1235 | 1237 | ||
| @@ -1410,6 +1412,10 @@ static int i915_load_modeset_init(struct drm_device *dev, | |||
| 1410 | if (ret) | 1412 | if (ret) |
| 1411 | goto cleanup_vga_client; | 1413 | goto cleanup_vga_client; |
| 1412 | 1414 | ||
| 1415 | /* IIR "flip pending" bit means done if this bit is set */ | ||
| 1416 | if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) | ||
| 1417 | dev_priv->flip_pending_is_done = true; | ||
| 1418 | |||
| 1413 | intel_modeset_init(dev); | 1419 | intel_modeset_init(dev); |
| 1414 | 1420 | ||
| 1415 | ret = drm_irq_install(dev); | 1421 | ret = drm_irq_install(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 276583159847..d147ab2f5bfc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -596,6 +596,7 @@ typedef struct drm_i915_private { | |||
| 596 | struct drm_crtc *plane_to_crtc_mapping[2]; | 596 | struct drm_crtc *plane_to_crtc_mapping[2]; |
| 597 | struct drm_crtc *pipe_to_crtc_mapping[2]; | 597 | struct drm_crtc *pipe_to_crtc_mapping[2]; |
| 598 | wait_queue_head_t pending_flip_queue; | 598 | wait_queue_head_t pending_flip_queue; |
| 599 | bool flip_pending_is_done; | ||
| 599 | 600 | ||
| 600 | /* Reclocking support */ | 601 | /* Reclocking support */ |
| 601 | bool render_reclock_avail; | 602 | bool render_reclock_avail; |
| @@ -1076,7 +1077,7 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
| 1076 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1077 | drm_i915_private_t *dev_priv = dev->dev_private; \ |
| 1077 | if (I915_VERBOSE) \ | 1078 | if (I915_VERBOSE) \ |
| 1078 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | 1079 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ |
| 1079 | intel_ring_begin(dev, &dev_priv->render_ring, 4*(n)); \ | 1080 | intel_ring_begin(dev, &dev_priv->render_ring, (n)); \ |
| 1080 | } while (0) | 1081 | } while (0) |
| 1081 | 1082 | ||
| 1082 | 1083 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2479be001e40..dba53d4b9fb3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -940,22 +940,30 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
| 940 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) | 940 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) |
| 941 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | 941 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); |
| 942 | 942 | ||
| 943 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) | 943 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { |
| 944 | intel_prepare_page_flip(dev, 0); | 944 | intel_prepare_page_flip(dev, 0); |
| 945 | if (dev_priv->flip_pending_is_done) | ||
| 946 | intel_finish_page_flip_plane(dev, 0); | ||
| 947 | } | ||
| 945 | 948 | ||
| 946 | if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) | 949 | if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) { |
| 947 | intel_prepare_page_flip(dev, 1); | 950 | intel_prepare_page_flip(dev, 1); |
| 951 | if (dev_priv->flip_pending_is_done) | ||
| 952 | intel_finish_page_flip_plane(dev, 1); | ||
| 953 | } | ||
| 948 | 954 | ||
| 949 | if (pipea_stats & vblank_status) { | 955 | if (pipea_stats & vblank_status) { |
| 950 | vblank++; | 956 | vblank++; |
| 951 | drm_handle_vblank(dev, 0); | 957 | drm_handle_vblank(dev, 0); |
| 952 | intel_finish_page_flip(dev, 0); | 958 | if (!dev_priv->flip_pending_is_done) |
| 959 | intel_finish_page_flip(dev, 0); | ||
| 953 | } | 960 | } |
| 954 | 961 | ||
| 955 | if (pipeb_stats & vblank_status) { | 962 | if (pipeb_stats & vblank_status) { |
| 956 | vblank++; | 963 | vblank++; |
| 957 | drm_handle_vblank(dev, 1); | 964 | drm_handle_vblank(dev, 1); |
| 958 | intel_finish_page_flip(dev, 1); | 965 | if (!dev_priv->flip_pending_is_done) |
| 966 | intel_finish_page_flip(dev, 1); | ||
| 959 | } | 967 | } |
| 960 | 968 | ||
| 961 | if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || | 969 | if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || |
| @@ -1387,29 +1395,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
| 1387 | dev_priv->pipestat[1] = 0; | 1395 | dev_priv->pipestat[1] = 0; |
| 1388 | 1396 | ||
| 1389 | if (I915_HAS_HOTPLUG(dev)) { | 1397 | if (I915_HAS_HOTPLUG(dev)) { |
| 1390 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | ||
| 1391 | |||
| 1392 | /* Note HDMI and DP share bits */ | ||
| 1393 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | ||
| 1394 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | ||
| 1395 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | ||
| 1396 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | ||
| 1397 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | ||
| 1398 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | ||
| 1399 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
| 1400 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
| 1401 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | ||
| 1402 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
| 1403 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) | ||
| 1404 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
| 1405 | /* Ignore TV since it's buggy */ | ||
| 1406 | |||
| 1407 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | ||
| 1408 | |||
| 1409 | /* Enable in IER... */ | 1398 | /* Enable in IER... */ |
| 1410 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | 1399 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; |
| 1411 | /* and unmask in IMR */ | 1400 | /* and unmask in IMR */ |
| 1412 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); | 1401 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PORT_INTERRUPT; |
| 1413 | } | 1402 | } |
| 1414 | 1403 | ||
| 1415 | /* | 1404 | /* |
| @@ -1427,16 +1416,41 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
| 1427 | } | 1416 | } |
| 1428 | I915_WRITE(EMR, error_mask); | 1417 | I915_WRITE(EMR, error_mask); |
| 1429 | 1418 | ||
| 1430 | /* Disable pipe interrupt enables, clear pending pipe status */ | ||
| 1431 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | ||
| 1432 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | ||
| 1433 | /* Clear pending interrupt status */ | ||
| 1434 | I915_WRITE(IIR, I915_READ(IIR)); | ||
| 1435 | |||
| 1436 | I915_WRITE(IER, enable_mask); | ||
| 1437 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | 1419 | I915_WRITE(IMR, dev_priv->irq_mask_reg); |
| 1420 | I915_WRITE(IER, enable_mask); | ||
| 1438 | (void) I915_READ(IER); | 1421 | (void) I915_READ(IER); |
| 1439 | 1422 | ||
| 1423 | if (I915_HAS_HOTPLUG(dev)) { | ||
| 1424 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | ||
| 1425 | |||
| 1426 | /* Note HDMI and DP share bits */ | ||
| 1427 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | ||
| 1428 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | ||
| 1429 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | ||
| 1430 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | ||
| 1431 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | ||
| 1432 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | ||
| 1433 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
| 1434 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
| 1435 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | ||
| 1436 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
| 1437 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | ||
| 1438 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
| 1439 | |||
| 1440 | /* Programming the CRT detection parameters tends | ||
| 1441 | to generate a spurious hotplug event about three | ||
| 1442 | seconds later. So just do it once. | ||
| 1443 | */ | ||
| 1444 | if (IS_G4X(dev)) | ||
| 1445 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; | ||
| 1446 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | /* Ignore TV since it's buggy */ | ||
| 1450 | |||
| 1451 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | ||
| 1452 | } | ||
| 1453 | |||
| 1440 | opregion_enable_asle(dev); | 1454 | opregion_enable_asle(dev); |
| 1441 | 1455 | ||
| 1442 | return 0; | 1456 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 64b0a3afd92b..150400f40534 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -178,6 +178,7 @@ | |||
| 178 | #define MI_OVERLAY_OFF (0x2<<21) | 178 | #define MI_OVERLAY_OFF (0x2<<21) |
| 179 | #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) | 179 | #define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) |
| 180 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) | 180 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) |
| 181 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) | ||
| 181 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) | 182 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) |
| 182 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | 183 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) |
| 183 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 184 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
| @@ -368,6 +369,9 @@ | |||
| 368 | #define CM0_RC_OP_FLUSH_DISABLE (1<<0) | 369 | #define CM0_RC_OP_FLUSH_DISABLE (1<<0) |
| 369 | #define BB_ADDR 0x02140 /* 8 bytes */ | 370 | #define BB_ADDR 0x02140 /* 8 bytes */ |
| 370 | #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ | 371 | #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ |
| 372 | #define ECOSKPD 0x021d0 | ||
| 373 | #define ECO_GATING_CX_ONLY (1<<3) | ||
| 374 | #define ECO_FLIP_DONE (1<<0) | ||
| 371 | 375 | ||
| 372 | /* GEN6 interrupt control */ | 376 | /* GEN6 interrupt control */ |
| 373 | #define GEN6_RENDER_HWSTAM 0x2098 | 377 | #define GEN6_RENDER_HWSTAM 0x2098 |
| @@ -1130,7 +1134,6 @@ | |||
| 1130 | #define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) | 1134 | #define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) |
| 1131 | #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) | 1135 | #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) |
| 1132 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1136 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
| 1133 | #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ | ||
| 1134 | 1137 | ||
| 1135 | #define PORT_HOTPLUG_STAT 0x61114 | 1138 | #define PORT_HOTPLUG_STAT 0x61114 |
| 1136 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) | 1139 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 22ff38455731..ee0732b222a1 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -234,14 +234,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
| 234 | else | 234 | else |
| 235 | tries = 1; | 235 | tries = 1; |
| 236 | hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); | 236 | hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); |
| 237 | hotplug_en &= CRT_HOTPLUG_MASK; | ||
| 238 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 237 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
| 239 | 238 | ||
| 240 | if (IS_G4X(dev)) | ||
| 241 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; | ||
| 242 | |||
| 243 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; | ||
| 244 | |||
| 245 | for (i = 0; i < tries ; i++) { | 239 | for (i = 0; i < tries ; i++) { |
| 246 | unsigned long timeout; | 240 | unsigned long timeout; |
| 247 | /* turn on the FORCE_DETECT */ | 241 | /* turn on the FORCE_DETECT */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cc8131ff319f..68dcf36e2793 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2970,11 +2970,13 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
| 2970 | if (srwm < 0) | 2970 | if (srwm < 0) |
| 2971 | srwm = 1; | 2971 | srwm = 1; |
| 2972 | srwm &= 0x3f; | 2972 | srwm &= 0x3f; |
| 2973 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 2973 | if (IS_I965GM(dev)) |
| 2974 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
| 2974 | } else { | 2975 | } else { |
| 2975 | /* Turn off self refresh if both pipes are enabled */ | 2976 | /* Turn off self refresh if both pipes are enabled */ |
| 2976 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | 2977 | if (IS_I965GM(dev)) |
| 2977 | & ~FW_BLC_SELF_EN); | 2978 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) |
| 2979 | & ~FW_BLC_SELF_EN); | ||
| 2978 | } | 2980 | } |
| 2979 | 2981 | ||
| 2980 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", | 2982 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
| @@ -4483,6 +4485,7 @@ static void intel_idle_update(struct work_struct *work) | |||
| 4483 | struct drm_device *dev = dev_priv->dev; | 4485 | struct drm_device *dev = dev_priv->dev; |
| 4484 | struct drm_crtc *crtc; | 4486 | struct drm_crtc *crtc; |
| 4485 | struct intel_crtc *intel_crtc; | 4487 | struct intel_crtc *intel_crtc; |
| 4488 | int enabled = 0; | ||
| 4486 | 4489 | ||
| 4487 | if (!i915_powersave) | 4490 | if (!i915_powersave) |
| 4488 | return; | 4491 | return; |
| @@ -4491,21 +4494,22 @@ static void intel_idle_update(struct work_struct *work) | |||
| 4491 | 4494 | ||
| 4492 | i915_update_gfx_val(dev_priv); | 4495 | i915_update_gfx_val(dev_priv); |
| 4493 | 4496 | ||
| 4494 | if (IS_I945G(dev) || IS_I945GM(dev)) { | ||
| 4495 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); | ||
| 4496 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | ||
| 4497 | } | ||
| 4498 | |||
| 4499 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 4497 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 4500 | /* Skip inactive CRTCs */ | 4498 | /* Skip inactive CRTCs */ |
| 4501 | if (!crtc->fb) | 4499 | if (!crtc->fb) |
| 4502 | continue; | 4500 | continue; |
| 4503 | 4501 | ||
| 4502 | enabled++; | ||
| 4504 | intel_crtc = to_intel_crtc(crtc); | 4503 | intel_crtc = to_intel_crtc(crtc); |
| 4505 | if (!intel_crtc->busy) | 4504 | if (!intel_crtc->busy) |
| 4506 | intel_decrease_pllclock(crtc); | 4505 | intel_decrease_pllclock(crtc); |
| 4507 | } | 4506 | } |
| 4508 | 4507 | ||
| 4508 | if ((enabled == 1) && (IS_I945G(dev) || IS_I945GM(dev))) { | ||
| 4509 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); | ||
| 4510 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | ||
| 4511 | } | ||
| 4512 | |||
| 4509 | mutex_unlock(&dev->struct_mutex); | 4513 | mutex_unlock(&dev->struct_mutex); |
| 4510 | } | 4514 | } |
| 4511 | 4515 | ||
| @@ -4601,10 +4605,10 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
| 4601 | kfree(work); | 4605 | kfree(work); |
| 4602 | } | 4606 | } |
| 4603 | 4607 | ||
| 4604 | void intel_finish_page_flip(struct drm_device *dev, int pipe) | 4608 | static void do_intel_finish_page_flip(struct drm_device *dev, |
| 4609 | struct drm_crtc *crtc) | ||
| 4605 | { | 4610 | { |
| 4606 | drm_i915_private_t *dev_priv = dev->dev_private; | 4611 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 4607 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
| 4608 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4612 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 4609 | struct intel_unpin_work *work; | 4613 | struct intel_unpin_work *work; |
| 4610 | struct drm_i915_gem_object *obj_priv; | 4614 | struct drm_i915_gem_object *obj_priv; |
| @@ -4648,6 +4652,22 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
| 4648 | schedule_work(&work->work); | 4652 | schedule_work(&work->work); |
| 4649 | } | 4653 | } |
| 4650 | 4654 | ||
| 4655 | void intel_finish_page_flip(struct drm_device *dev, int pipe) | ||
| 4656 | { | ||
| 4657 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 4658 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
| 4659 | |||
| 4660 | do_intel_finish_page_flip(dev, crtc); | ||
| 4661 | } | ||
| 4662 | |||
| 4663 | void intel_finish_page_flip_plane(struct drm_device *dev, int plane) | ||
| 4664 | { | ||
| 4665 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 4666 | struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; | ||
| 4667 | |||
| 4668 | do_intel_finish_page_flip(dev, crtc); | ||
| 4669 | } | ||
| 4670 | |||
| 4651 | void intel_prepare_page_flip(struct drm_device *dev, int plane) | 4671 | void intel_prepare_page_flip(struct drm_device *dev, int plane) |
| 4652 | { | 4672 | { |
| 4653 | drm_i915_private_t *dev_priv = dev->dev_private; | 4673 | drm_i915_private_t *dev_priv = dev->dev_private; |
| @@ -4678,6 +4698,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 4678 | unsigned long flags; | 4698 | unsigned long flags; |
| 4679 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; | 4699 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; |
| 4680 | int ret, pipesrc; | 4700 | int ret, pipesrc; |
| 4701 | u32 flip_mask; | ||
| 4681 | 4702 | ||
| 4682 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4703 | work = kzalloc(sizeof *work, GFP_KERNEL); |
| 4683 | if (work == NULL) | 4704 | if (work == NULL) |
| @@ -4731,15 +4752,28 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
| 4731 | atomic_inc(&obj_priv->pending_flip); | 4752 | atomic_inc(&obj_priv->pending_flip); |
| 4732 | work->pending_flip_obj = obj; | 4753 | work->pending_flip_obj = obj; |
| 4733 | 4754 | ||
| 4755 | if (intel_crtc->plane) | ||
| 4756 | flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; | ||
| 4757 | else | ||
| 4758 | flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; | ||
| 4759 | |||
| 4760 | /* Wait for any previous flip to finish */ | ||
| 4761 | if (IS_GEN3(dev)) | ||
| 4762 | while (I915_READ(ISR) & flip_mask) | ||
| 4763 | ; | ||
| 4764 | |||
| 4734 | BEGIN_LP_RING(4); | 4765 | BEGIN_LP_RING(4); |
| 4735 | OUT_RING(MI_DISPLAY_FLIP | | ||
| 4736 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
| 4737 | OUT_RING(fb->pitch); | ||
| 4738 | if (IS_I965G(dev)) { | 4766 | if (IS_I965G(dev)) { |
| 4767 | OUT_RING(MI_DISPLAY_FLIP | | ||
| 4768 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
| 4769 | OUT_RING(fb->pitch); | ||
| 4739 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); | 4770 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); |
| 4740 | pipesrc = I915_READ(pipesrc_reg); | 4771 | pipesrc = I915_READ(pipesrc_reg); |
| 4741 | OUT_RING(pipesrc & 0x0fff0fff); | 4772 | OUT_RING(pipesrc & 0x0fff0fff); |
| 4742 | } else { | 4773 | } else { |
| 4774 | OUT_RING(MI_DISPLAY_FLIP_I915 | | ||
| 4775 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
| 4776 | OUT_RING(fb->pitch); | ||
| 4743 | OUT_RING(obj_priv->gtt_offset); | 4777 | OUT_RING(obj_priv->gtt_offset); |
| 4744 | OUT_RING(MI_NOOP); | 4778 | OUT_RING(MI_NOOP); |
| 4745 | } | 4779 | } |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 49b54f05d3cf..1aac59e83bff 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -136,6 +136,12 @@ intel_dp_link_required(struct drm_device *dev, | |||
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int | 138 | static int |
| 139 | intel_dp_max_data_rate(int max_link_clock, int max_lanes) | ||
| 140 | { | ||
| 141 | return (max_link_clock * max_lanes * 8) / 10; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int | ||
| 139 | intel_dp_mode_valid(struct drm_connector *connector, | 145 | intel_dp_mode_valid(struct drm_connector *connector, |
| 140 | struct drm_display_mode *mode) | 146 | struct drm_display_mode *mode) |
| 141 | { | 147 | { |
| @@ -144,8 +150,11 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 144 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 150 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); |
| 145 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 151 | int max_lanes = intel_dp_max_lane_count(intel_encoder); |
| 146 | 152 | ||
| 147 | if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) | 153 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels |
| 148 | > max_link_clock * max_lanes) | 154 | which are outside spec tolerances but somehow work by magic */ |
| 155 | if (!IS_eDP(intel_encoder) && | ||
| 156 | (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) | ||
| 157 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) | ||
| 149 | return MODE_CLOCK_HIGH; | 158 | return MODE_CLOCK_HIGH; |
| 150 | 159 | ||
| 151 | if (mode->clock < 10000) | 160 | if (mode->clock < 10000) |
| @@ -506,7 +515,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 506 | 515 | ||
| 507 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 516 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
| 508 | for (clock = 0; clock <= max_clock; clock++) { | 517 | for (clock = 0; clock <= max_clock; clock++) { |
| 509 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; | 518 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
| 510 | 519 | ||
| 511 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) | 520 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) |
| 512 | <= link_avail) { | 521 | <= link_avail) { |
| @@ -521,6 +530,18 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 521 | } | 530 | } |
| 522 | } | 531 | } |
| 523 | } | 532 | } |
| 533 | |||
| 534 | if (IS_eDP(intel_encoder)) { | ||
| 535 | /* okay we failed just pick the highest */ | ||
| 536 | dp_priv->lane_count = max_lane_count; | ||
| 537 | dp_priv->link_bw = bws[max_clock]; | ||
| 538 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | ||
| 539 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | ||
| 540 | "count %d clock %d\n", | ||
| 541 | dp_priv->link_bw, dp_priv->lane_count, | ||
| 542 | adjusted_mode->clock); | ||
| 543 | return true; | ||
| 544 | } | ||
| 524 | return false; | 545 | return false; |
| 525 | } | 546 | } |
| 526 | 547 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index df931f787665..72206f37c4fb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -224,6 +224,7 @@ extern void intel_fbdev_fini(struct drm_device *dev); | |||
| 224 | 224 | ||
| 225 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); | 225 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); |
| 226 | extern void intel_finish_page_flip(struct drm_device *dev, int pipe); | 226 | extern void intel_finish_page_flip(struct drm_device *dev, int pipe); |
| 227 | extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane); | ||
| 227 | 228 | ||
| 228 | extern void intel_setup_overlay(struct drm_device *dev); | 229 | extern void intel_setup_overlay(struct drm_device *dev); |
| 229 | extern void intel_cleanup_overlay(struct drm_device *dev); | 230 | extern void intel_cleanup_overlay(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6a1accd83aec..31df55f0a0a7 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -983,8 +983,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
| 983 | 983 | ||
| 984 | drm_connector_attach_property(&intel_connector->base, | 984 | drm_connector_attach_property(&intel_connector->base, |
| 985 | dev->mode_config.scaling_mode_property, | 985 | dev->mode_config.scaling_mode_property, |
| 986 | DRM_MODE_SCALE_FULLSCREEN); | 986 | DRM_MODE_SCALE_ASPECT); |
| 987 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; | 987 | lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; |
| 988 | /* | 988 | /* |
| 989 | * LVDS discovery: | 989 | * LVDS discovery: |
| 990 | * 1) check for EDID on DDC | 990 | * 1) check for EDID on DDC |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index cea4f1a8709e..26362f8495a8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -94,7 +94,7 @@ render_ring_flush(struct drm_device *dev, | |||
| 94 | #if WATCH_EXEC | 94 | #if WATCH_EXEC |
| 95 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | 95 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); |
| 96 | #endif | 96 | #endif |
| 97 | intel_ring_begin(dev, ring, 8); | 97 | intel_ring_begin(dev, ring, 2); |
| 98 | intel_ring_emit(dev, ring, cmd); | 98 | intel_ring_emit(dev, ring, cmd); |
| 99 | intel_ring_emit(dev, ring, MI_NOOP); | 99 | intel_ring_emit(dev, ring, MI_NOOP); |
| 100 | intel_ring_advance(dev, ring); | 100 | intel_ring_advance(dev, ring); |
| @@ -358,7 +358,7 @@ bsd_ring_flush(struct drm_device *dev, | |||
| 358 | u32 invalidate_domains, | 358 | u32 invalidate_domains, |
| 359 | u32 flush_domains) | 359 | u32 flush_domains) |
| 360 | { | 360 | { |
| 361 | intel_ring_begin(dev, ring, 8); | 361 | intel_ring_begin(dev, ring, 2); |
| 362 | intel_ring_emit(dev, ring, MI_FLUSH); | 362 | intel_ring_emit(dev, ring, MI_FLUSH); |
| 363 | intel_ring_emit(dev, ring, MI_NOOP); | 363 | intel_ring_emit(dev, ring, MI_NOOP); |
| 364 | intel_ring_advance(dev, ring); | 364 | intel_ring_advance(dev, ring); |
| @@ -687,6 +687,7 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
| 687 | *virt++ = MI_NOOP; | 687 | *virt++ = MI_NOOP; |
| 688 | 688 | ||
| 689 | ring->tail = 0; | 689 | ring->tail = 0; |
| 690 | ring->space = ring->head - 8; | ||
| 690 | 691 | ||
| 691 | return 0; | 692 | return 0; |
| 692 | } | 693 | } |
| @@ -721,8 +722,9 @@ int intel_wait_ring_buffer(struct drm_device *dev, | |||
| 721 | } | 722 | } |
| 722 | 723 | ||
| 723 | void intel_ring_begin(struct drm_device *dev, | 724 | void intel_ring_begin(struct drm_device *dev, |
| 724 | struct intel_ring_buffer *ring, int n) | 725 | struct intel_ring_buffer *ring, int num_dwords) |
| 725 | { | 726 | { |
| 727 | int n = 4*num_dwords; | ||
| 726 | if (unlikely(ring->tail + n > ring->size)) | 728 | if (unlikely(ring->tail + n > ring->size)) |
| 727 | intel_wrap_ring_buffer(dev, ring); | 729 | intel_wrap_ring_buffer(dev, ring); |
| 728 | if (unlikely(ring->space < n)) | 730 | if (unlikely(ring->space < n)) |
| @@ -752,7 +754,7 @@ void intel_fill_struct(struct drm_device *dev, | |||
| 752 | { | 754 | { |
| 753 | unsigned int *virt = ring->virtual_start + ring->tail; | 755 | unsigned int *virt = ring->virtual_start + ring->tail; |
| 754 | BUG_ON((len&~(4-1)) != 0); | 756 | BUG_ON((len&~(4-1)) != 0); |
| 755 | intel_ring_begin(dev, ring, len); | 757 | intel_ring_begin(dev, ring, len/4); |
| 756 | memcpy(virt, data, len); | 758 | memcpy(virt, data, len); |
| 757 | ring->tail += len; | 759 | ring->tail += len; |
| 758 | ring->tail &= ring->size - 1; | 760 | ring->tail &= ring->size - 1; |
