diff options
| -rw-r--r-- | drivers/char/agp/intel-gtt.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_irq.c | 19 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_acpi.c | 34 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 76 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 98 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 30 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.c | 13 | ||||
| -rw-r--r-- | include/drm/i915_drm.h | 2 |
15 files changed, 210 insertions, 121 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9272c38dd3c6..16a2847b7cdb 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
| @@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void) | |||
| 812 | 812 | ||
| 813 | static void i830_cleanup(void) | 813 | static void i830_cleanup(void) |
| 814 | { | 814 | { |
| 815 | kunmap(intel_private.i8xx_page); | 815 | if (intel_private.i8xx_flush_page) { |
| 816 | intel_private.i8xx_flush_page = NULL; | 816 | kunmap(intel_private.i8xx_flush_page); |
| 817 | intel_private.i8xx_flush_page = NULL; | ||
| 818 | } | ||
| 817 | 819 | ||
| 818 | __free_page(intel_private.i8xx_page); | 820 | __free_page(intel_private.i8xx_page); |
| 819 | intel_private.i8xx_page = NULL; | 821 | intel_private.i8xx_page = NULL; |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7ca59359fee2..bede10a03407 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) | |||
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 243 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
| 244 | if (!drm_helper_encoder_in_use(encoder)) { | 244 | if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) { |
| 245 | drm_encoder_disable(encoder); | 245 | drm_encoder_disable(encoder); |
| 246 | /* disconnector encoder from any connector */ | 246 | /* disconnector encoder from any connector */ |
| 247 | encoder->crtc = NULL; | 247 | encoder->crtc = NULL; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9d3a5030b6e1..722700d5d73e 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
| 585 | struct timeval now; | 585 | struct timeval now; |
| 586 | unsigned long flags; | 586 | unsigned long flags; |
| 587 | unsigned int seq; | 587 | unsigned int seq; |
| 588 | int ret; | ||
| 588 | 589 | ||
| 589 | e = kzalloc(sizeof *e, GFP_KERNEL); | 590 | e = kzalloc(sizeof *e, GFP_KERNEL); |
| 590 | if (e == NULL) | 591 | if (e == NULL) { |
| 591 | return -ENOMEM; | 592 | ret = -ENOMEM; |
| 593 | goto err_put; | ||
| 594 | } | ||
| 592 | 595 | ||
| 593 | e->pipe = pipe; | 596 | e->pipe = pipe; |
| 594 | e->base.pid = current->pid; | 597 | e->base.pid = current->pid; |
| @@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
| 603 | spin_lock_irqsave(&dev->event_lock, flags); | 606 | spin_lock_irqsave(&dev->event_lock, flags); |
| 604 | 607 | ||
| 605 | if (file_priv->event_space < sizeof e->event) { | 608 | if (file_priv->event_space < sizeof e->event) { |
| 606 | spin_unlock_irqrestore(&dev->event_lock, flags); | 609 | ret = -EBUSY; |
| 607 | kfree(e); | 610 | goto err_unlock; |
| 608 | return -ENOMEM; | ||
| 609 | } | 611 | } |
| 610 | 612 | ||
| 611 | file_priv->event_space -= sizeof e->event; | 613 | file_priv->event_space -= sizeof e->event; |
| @@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
| 638 | spin_unlock_irqrestore(&dev->event_lock, flags); | 640 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 639 | 641 | ||
| 640 | return 0; | 642 | return 0; |
| 643 | |||
| 644 | err_unlock: | ||
| 645 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 646 | kfree(e); | ||
| 647 | err_put: | ||
| 648 | drm_vblank_put(dev, e->pipe); | ||
| 649 | return ret; | ||
| 641 | } | 650 | } |
| 642 | 651 | ||
| 643 | /** | 652 | /** |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a26f4dd21ae..e6800819bca8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -767,6 +767,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
| 767 | case I915_PARAM_HAS_BLT: | 767 | case I915_PARAM_HAS_BLT: |
| 768 | value = HAS_BLT(dev); | 768 | value = HAS_BLT(dev); |
| 769 | break; | 769 | break; |
| 770 | case I915_PARAM_HAS_COHERENT_RINGS: | ||
| 771 | value = 1; | ||
| 772 | break; | ||
| 770 | default: | 773 | default: |
| 771 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 774 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
| 772 | param->param); | 775 | param->param); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5e54821af996..275ec6ed43ae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -4374,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
| 4374 | * use this buffer rather sooner than later, so issuing the required | 4374 | * use this buffer rather sooner than later, so issuing the required |
| 4375 | * flush earlier is beneficial. | 4375 | * flush earlier is beneficial. |
| 4376 | */ | 4376 | */ |
| 4377 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) | 4377 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) { |
| 4378 | i915_gem_flush_ring(dev, file_priv, | 4378 | i915_gem_flush_ring(dev, file_priv, |
| 4379 | obj_priv->ring, | 4379 | obj_priv->ring, |
| 4380 | 0, obj->write_domain); | 4380 | 0, obj->write_domain); |
| 4381 | } else if (obj_priv->ring->outstanding_lazy_request) { | ||
| 4382 | /* This ring is not being cleared by active usage, | ||
| 4383 | * so emit a request to do so. | ||
| 4384 | */ | ||
| 4385 | u32 seqno = i915_add_request(dev, | ||
| 4386 | NULL, NULL, | ||
| 4387 | obj_priv->ring); | ||
| 4388 | if (seqno == 0) | ||
| 4389 | ret = -ENOMEM; | ||
| 4390 | } | ||
| 4381 | 4391 | ||
| 4382 | /* Update the active list for the hardware's current position. | 4392 | /* Update the active list for the hardware's current position. |
| 4383 | * Otherwise this only updates on a delayed timer or when irqs | 4393 | * Otherwise this only updates on a delayed timer or when irqs |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 25ed911a3112..878fc766a12c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -3033,6 +3033,7 @@ | |||
| 3033 | #define TRANS_DP_10BPC (1<<9) | 3033 | #define TRANS_DP_10BPC (1<<9) |
| 3034 | #define TRANS_DP_6BPC (2<<9) | 3034 | #define TRANS_DP_6BPC (2<<9) |
| 3035 | #define TRANS_DP_12BPC (3<<9) | 3035 | #define TRANS_DP_12BPC (3<<9) |
| 3036 | #define TRANS_DP_BPC_MASK (3<<9) | ||
| 3036 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) | 3037 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) |
| 3037 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 3038 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
| 3038 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 3039 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index 65c88f9ba12c..2cb8e0b9f1ee 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
| @@ -190,37 +190,6 @@ out: | |||
| 190 | kfree(output.pointer); | 190 | kfree(output.pointer); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static int intel_dsm_switchto(enum vga_switcheroo_client_id id) | ||
| 194 | { | ||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | |||
| 198 | static int intel_dsm_power_state(enum vga_switcheroo_client_id id, | ||
| 199 | enum vga_switcheroo_state state) | ||
| 200 | { | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | static int intel_dsm_init(void) | ||
| 205 | { | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int intel_dsm_get_client_id(struct pci_dev *pdev) | ||
| 210 | { | ||
| 211 | if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
| 212 | return VGA_SWITCHEROO_IGD; | ||
| 213 | else | ||
| 214 | return VGA_SWITCHEROO_DIS; | ||
| 215 | } | ||
| 216 | |||
| 217 | static struct vga_switcheroo_handler intel_dsm_handler = { | ||
| 218 | .switchto = intel_dsm_switchto, | ||
| 219 | .power_state = intel_dsm_power_state, | ||
| 220 | .init = intel_dsm_init, | ||
| 221 | .get_client_id = intel_dsm_get_client_id, | ||
| 222 | }; | ||
| 223 | |||
| 224 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 193 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
| 225 | { | 194 | { |
| 226 | acpi_handle dhandle, intel_handle; | 195 | acpi_handle dhandle, intel_handle; |
| @@ -276,11 +245,8 @@ void intel_register_dsm_handler(void) | |||
| 276 | { | 245 | { |
| 277 | if (!intel_dsm_detect()) | 246 | if (!intel_dsm_detect()) |
| 278 | return; | 247 | return; |
| 279 | |||
| 280 | vga_switcheroo_register_handler(&intel_dsm_handler); | ||
| 281 | } | 248 | } |
| 282 | 249 | ||
| 283 | void intel_unregister_dsm_handler(void) | 250 | void intel_unregister_dsm_handler(void) |
| 284 | { | 251 | { |
| 285 | vga_switcheroo_unregister_handler(); | ||
| 286 | } | 252 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 255b52ee0091..d9b7092439ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2120,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
| 2120 | reg = TRANS_DP_CTL(pipe); | 2120 | reg = TRANS_DP_CTL(pipe); |
| 2121 | temp = I915_READ(reg); | 2121 | temp = I915_READ(reg); |
| 2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | | 2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | |
| 2123 | TRANS_DP_SYNC_MASK); | 2123 | TRANS_DP_SYNC_MASK | |
| 2124 | TRANS_DP_BPC_MASK); | ||
| 2124 | temp |= (TRANS_DP_OUTPUT_ENABLE | | 2125 | temp |= (TRANS_DP_OUTPUT_ENABLE | |
| 2125 | TRANS_DP_ENH_FRAMING); | 2126 | TRANS_DP_ENH_FRAMING); |
| 2127 | temp |= TRANS_DP_8BPC; | ||
| 2126 | 2128 | ||
| 2127 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2129 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
| 2128 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2130 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
| @@ -2712,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) | |||
| 2712 | } | 2714 | } |
| 2713 | } | 2715 | } |
| 2714 | 2716 | ||
| 2715 | #define DATA_N 0x800000 | ||
| 2716 | #define LINK_N 0x80000 | ||
| 2717 | |||
| 2718 | static void | 2717 | static void |
| 2719 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, | 2718 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, |
| 2720 | int link_clock, struct fdi_m_n *m_n) | 2719 | int link_clock, struct fdi_m_n *m_n) |
| 2721 | { | 2720 | { |
| 2722 | u64 temp; | ||
| 2723 | |||
| 2724 | m_n->tu = 64; /* default size */ | 2721 | m_n->tu = 64; /* default size */ |
| 2725 | 2722 | ||
| 2726 | temp = (u64) DATA_N * pixel_clock; | 2723 | /* BUG_ON(pixel_clock > INT_MAX / 36); */ |
| 2727 | temp = div_u64(temp, link_clock); | 2724 | m_n->gmch_m = bits_per_pixel * pixel_clock; |
| 2728 | m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); | 2725 | m_n->gmch_n = link_clock * nlanes * 8; |
| 2729 | m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ | ||
| 2730 | m_n->gmch_n = DATA_N; | ||
| 2731 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 2726 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
| 2732 | 2727 | ||
| 2733 | temp = (u64) LINK_N * pixel_clock; | 2728 | m_n->link_m = pixel_clock; |
| 2734 | m_n->link_m = div_u64(temp, link_clock); | 2729 | m_n->link_n = link_clock; |
| 2735 | m_n->link_n = LINK_N; | ||
| 2736 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); | 2730 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
| 2737 | } | 2731 | } |
| 2738 | 2732 | ||
| @@ -3716,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3716 | 3710 | ||
| 3717 | /* FDI link */ | 3711 | /* FDI link */ |
| 3718 | if (HAS_PCH_SPLIT(dev)) { | 3712 | if (HAS_PCH_SPLIT(dev)) { |
| 3713 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
| 3719 | int lane = 0, link_bw, bpp; | 3714 | int lane = 0, link_bw, bpp; |
| 3720 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 3715 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
| 3721 | according to current link config */ | 3716 | according to current link config */ |
| @@ -3799,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 3799 | 3794 | ||
| 3800 | intel_crtc->fdi_lanes = lane; | 3795 | intel_crtc->fdi_lanes = lane; |
| 3801 | 3796 | ||
| 3797 | if (pixel_multiplier > 1) | ||
| 3798 | link_bw *= pixel_multiplier; | ||
| 3802 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); | 3799 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); |
| 3803 | } | 3800 | } |
| 3804 | 3801 | ||
| @@ -5236,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { | |||
| 5236 | .page_flip = intel_crtc_page_flip, | 5233 | .page_flip = intel_crtc_page_flip, |
| 5237 | }; | 5234 | }; |
| 5238 | 5235 | ||
| 5236 | static void intel_sanitize_modesetting(struct drm_device *dev, | ||
| 5237 | int pipe, int plane) | ||
| 5238 | { | ||
| 5239 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5240 | u32 reg, val; | ||
| 5241 | |||
| 5242 | if (HAS_PCH_SPLIT(dev)) | ||
| 5243 | return; | ||
| 5244 | |||
| 5245 | /* Who knows what state these registers were left in by the BIOS or | ||
| 5246 | * grub? | ||
| 5247 | * | ||
| 5248 | * If we leave the registers in a conflicting state (e.g. with the | ||
| 5249 | * display plane reading from the other pipe than the one we intend | ||
| 5250 | * to use) then when we attempt to teardown the active mode, we will | ||
| 5251 | * not disable the pipes and planes in the correct order -- leaving | ||
| 5252 | * a plane reading from a disabled pipe and possibly leading to | ||
| 5253 | * undefined behaviour. | ||
| 5254 | */ | ||
| 5255 | |||
| 5256 | reg = DSPCNTR(plane); | ||
| 5257 | val = I915_READ(reg); | ||
| 5258 | |||
| 5259 | if ((val & DISPLAY_PLANE_ENABLE) == 0) | ||
| 5260 | return; | ||
| 5261 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) | ||
| 5262 | return; | ||
| 5263 | |||
| 5264 | /* This display plane is active and attached to the other CPU pipe. */ | ||
| 5265 | pipe = !pipe; | ||
| 5266 | |||
| 5267 | /* Disable the plane and wait for it to stop reading from the pipe. */ | ||
| 5268 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); | ||
| 5269 | intel_flush_display_plane(dev, plane); | ||
| 5270 | |||
| 5271 | if (IS_GEN2(dev)) | ||
| 5272 | intel_wait_for_vblank(dev, pipe); | ||
| 5273 | |||
| 5274 | if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | ||
| 5275 | return; | ||
| 5276 | |||
| 5277 | /* Switch off the pipe. */ | ||
| 5278 | reg = PIPECONF(pipe); | ||
| 5279 | val = I915_READ(reg); | ||
| 5280 | if (val & PIPECONF_ENABLE) { | ||
| 5281 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); | ||
| 5282 | intel_wait_for_pipe_off(dev, pipe); | ||
| 5283 | } | ||
| 5284 | } | ||
| 5239 | 5285 | ||
| 5240 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 5286 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
| 5241 | { | 5287 | { |
| @@ -5287,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 5287 | 5333 | ||
| 5288 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 5334 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
| 5289 | (unsigned long)intel_crtc); | 5335 | (unsigned long)intel_crtc); |
| 5336 | |||
| 5337 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
| 5290 | } | 5338 | } |
| 5291 | 5339 | ||
| 5292 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 5340 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 300f64b4238b..df648cb4c296 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1376,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
| 1376 | struct drm_i915_private *dev_priv = dev->dev_private; | 1376 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1377 | uint32_t DP = intel_dp->DP; | 1377 | uint32_t DP = intel_dp->DP; |
| 1378 | 1378 | ||
| 1379 | if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) | ||
| 1380 | return; | ||
| 1381 | |||
| 1379 | DRM_DEBUG_KMS("\n"); | 1382 | DRM_DEBUG_KMS("\n"); |
| 1380 | 1383 | ||
| 1381 | if (is_edp(intel_dp)) { | 1384 | if (is_edp(intel_dp)) { |
| @@ -1398,6 +1401,28 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
| 1398 | 1401 | ||
| 1399 | if (is_edp(intel_dp)) | 1402 | if (is_edp(intel_dp)) |
| 1400 | DP |= DP_LINK_TRAIN_OFF; | 1403 | DP |= DP_LINK_TRAIN_OFF; |
| 1404 | |||
| 1405 | if (!HAS_PCH_CPT(dev) && | ||
| 1406 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | ||
| 1407 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | ||
| 1408 | /* Hardware workaround: leaving our transcoder select | ||
| 1409 | * set to transcoder B while it's off will prevent the | ||
| 1410 | * corresponding HDMI output on transcoder A. | ||
| 1411 | * | ||
| 1412 | * Combine this with another hardware workaround: | ||
| 1413 | * transcoder select bit can only be cleared while the | ||
| 1414 | * port is enabled. | ||
| 1415 | */ | ||
| 1416 | DP &= ~DP_PIPEB_SELECT; | ||
| 1417 | I915_WRITE(intel_dp->output_reg, DP); | ||
| 1418 | |||
| 1419 | /* Changes to enable or select take place the vblank | ||
| 1420 | * after being written. | ||
| 1421 | */ | ||
| 1422 | intel_wait_for_vblank(intel_dp->base.base.dev, | ||
| 1423 | intel_crtc->pipe); | ||
| 1424 | } | ||
| 1425 | |||
| 1401 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1426 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
| 1402 | POSTING_READ(intel_dp->output_reg); | 1427 | POSTING_READ(intel_dp->output_reg); |
| 1403 | } | 1428 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f79327fc6653..25bcedf386fd 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) | |||
| 68 | /** | 68 | /** |
| 69 | * Sets the power state for the panel. | 69 | * Sets the power state for the panel. |
| 70 | */ | 70 | */ |
| 71 | static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | 71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) |
| 72 | { | 72 | { |
| 73 | struct drm_device *dev = intel_lvds->base.base.dev; | 73 | struct drm_device *dev = intel_lvds->base.base.dev; |
| 74 | struct drm_i915_private *dev_priv = dev->dev_private; | 74 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | |||
| 82 | lvds_reg = LVDS; | 82 | lvds_reg = LVDS; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | if (on) { | 85 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
| 86 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); | ||
| 87 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
| 88 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
| 89 | } else { | ||
| 90 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
| 91 | |||
| 92 | intel_panel_set_backlight(dev, 0); | ||
| 93 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
| 94 | 86 | ||
| 95 | if (intel_lvds->pfit_control) { | 87 | if (intel_lvds->pfit_dirty) { |
| 96 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | 88 | /* |
| 97 | DRM_ERROR("timed out waiting for panel to power off\n"); | 89 | * Enable automatic panel scaling so that non-native modes |
| 98 | I915_WRITE(PFIT_CONTROL, 0); | 90 | * fill the screen. The panel fitter should only be |
| 99 | intel_lvds->pfit_control = 0; | 91 | * adjusted whilst the pipe is disabled, according to |
| 92 | * register description and PRM. | ||
| 93 | */ | ||
| 94 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
| 95 | intel_lvds->pfit_control, | ||
| 96 | intel_lvds->pfit_pgm_ratios); | ||
| 97 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) { | ||
| 98 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
| 99 | } else { | ||
| 100 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
| 101 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
| 100 | intel_lvds->pfit_dirty = false; | 102 | intel_lvds->pfit_dirty = false; |
| 101 | } | 103 | } |
| 104 | } | ||
| 105 | |||
| 106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
| 107 | POSTING_READ(lvds_reg); | ||
| 108 | |||
| 109 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
| 110 | } | ||
| 102 | 111 | ||
| 103 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 112 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) |
| 113 | { | ||
| 114 | struct drm_device *dev = intel_lvds->base.base.dev; | ||
| 115 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 116 | u32 ctl_reg, lvds_reg; | ||
| 117 | |||
| 118 | if (HAS_PCH_SPLIT(dev)) { | ||
| 119 | ctl_reg = PCH_PP_CONTROL; | ||
| 120 | lvds_reg = PCH_LVDS; | ||
| 121 | } else { | ||
| 122 | ctl_reg = PP_CONTROL; | ||
| 123 | lvds_reg = LVDS; | ||
| 124 | } | ||
| 125 | |||
| 126 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
| 127 | intel_panel_set_backlight(dev, 0); | ||
| 128 | |||
| 129 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
| 130 | |||
| 131 | if (intel_lvds->pfit_control) { | ||
| 132 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
| 133 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
| 134 | |||
| 135 | I915_WRITE(PFIT_CONTROL, 0); | ||
| 136 | intel_lvds->pfit_dirty = true; | ||
| 104 | } | 137 | } |
| 138 | |||
| 139 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | ||
| 105 | POSTING_READ(lvds_reg); | 140 | POSTING_READ(lvds_reg); |
| 106 | } | 141 | } |
| 107 | 142 | ||
| @@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
| 110 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 145 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
| 111 | 146 | ||
| 112 | if (mode == DRM_MODE_DPMS_ON) | 147 | if (mode == DRM_MODE_DPMS_ON) |
| 113 | intel_lvds_set_power(intel_lvds, true); | 148 | intel_lvds_enable(intel_lvds); |
| 114 | else | 149 | else |
| 115 | intel_lvds_set_power(intel_lvds, false); | 150 | intel_lvds_disable(intel_lvds); |
| 116 | 151 | ||
| 117 | /* XXX: We never power down the LVDS pairs. */ | 152 | /* XXX: We never power down the LVDS pairs. */ |
| 118 | } | 153 | } |
| @@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder) | |||
| 411 | /* Always do a full power on as we do not know what state | 446 | /* Always do a full power on as we do not know what state |
| 412 | * we were left in. | 447 | * we were left in. |
| 413 | */ | 448 | */ |
| 414 | intel_lvds_set_power(intel_lvds, true); | 449 | intel_lvds_enable(intel_lvds); |
| 415 | } | 450 | } |
| 416 | 451 | ||
| 417 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 452 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
| 418 | struct drm_display_mode *mode, | 453 | struct drm_display_mode *mode, |
| 419 | struct drm_display_mode *adjusted_mode) | 454 | struct drm_display_mode *adjusted_mode) |
| 420 | { | 455 | { |
| 421 | struct drm_device *dev = encoder->dev; | ||
| 422 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 423 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
| 424 | |||
| 425 | /* | 456 | /* |
| 426 | * The LVDS pin pair will already have been turned on in the | 457 | * The LVDS pin pair will already have been turned on in the |
| 427 | * intel_crtc_mode_set since it has a large impact on the DPLL | 458 | * intel_crtc_mode_set since it has a large impact on the DPLL |
| 428 | * settings. | 459 | * settings. |
| 429 | */ | 460 | */ |
| 430 | |||
| 431 | if (HAS_PCH_SPLIT(dev)) | ||
| 432 | return; | ||
| 433 | |||
| 434 | if (!intel_lvds->pfit_dirty) | ||
| 435 | return; | ||
| 436 | |||
| 437 | /* | ||
| 438 | * Enable automatic panel scaling so that non-native modes fill the | ||
| 439 | * screen. Should be enabled before the pipe is enabled, according to | ||
| 440 | * register description and PRM. | ||
| 441 | */ | ||
| 442 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
| 443 | intel_lvds->pfit_control, | ||
| 444 | intel_lvds->pfit_pgm_ratios); | ||
| 445 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
| 446 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
| 447 | |||
| 448 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
| 449 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
| 450 | intel_lvds->pfit_dirty = false; | ||
| 451 | } | 461 | } |
| 452 | 462 | ||
| 453 | /** | 463 | /** |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f9244b..89a65be8a3f3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev, | |||
| 156 | 156 | ||
| 157 | /* G45 ring initialization fails to reset head to zero */ | 157 | /* G45 ring initialization fails to reset head to zero */ |
| 158 | if (head != 0) { | 158 | if (head != 0) { |
| 159 | DRM_ERROR("%s head not reset to zero " | 159 | DRM_DEBUG_KMS("%s head not reset to zero " |
| 160 | "ctl %08x head %08x tail %08x start %08x\n", | 160 | "ctl %08x head %08x tail %08x start %08x\n", |
| 161 | ring->name, | 161 | ring->name, |
| 162 | I915_READ_CTL(ring), | 162 | I915_READ_CTL(ring), |
| 163 | I915_READ_HEAD(ring), | 163 | I915_READ_HEAD(ring), |
| 164 | I915_READ_TAIL(ring), | 164 | I915_READ_TAIL(ring), |
| 165 | I915_READ_START(ring)); | 165 | I915_READ_START(ring)); |
| 166 | 166 | ||
| 167 | I915_WRITE_HEAD(ring, 0); | 167 | I915_WRITE_HEAD(ring, 0); |
| 168 | 168 | ||
| 169 | DRM_ERROR("%s head forced to zero " | 169 | if (I915_READ_HEAD(ring) & HEAD_ADDR) { |
| 170 | "ctl %08x head %08x tail %08x start %08x\n", | 170 | DRM_ERROR("failed to set %s head to zero " |
| 171 | ring->name, | 171 | "ctl %08x head %08x tail %08x start %08x\n", |
| 172 | I915_READ_CTL(ring), | 172 | ring->name, |
| 173 | I915_READ_HEAD(ring), | 173 | I915_READ_CTL(ring), |
| 174 | I915_READ_TAIL(ring), | 174 | I915_READ_HEAD(ring), |
| 175 | I915_READ_START(ring)); | 175 | I915_READ_TAIL(ring), |
| 176 | I915_READ_START(ring)); | ||
| 177 | } | ||
| 176 | } | 178 | } |
| 177 | 179 | ||
| 178 | I915_WRITE_CTL(ring, | 180 | I915_WRITE_CTL(ring, |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a3552594ccc4..a322d4f647bd 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1195,8 +1195,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
| 1195 | mc->vram_end, mc->real_vram_size >> 20); | 1195 | mc->vram_end, mc->real_vram_size >> 20); |
| 1196 | } else { | 1196 | } else { |
| 1197 | u64 base = 0; | 1197 | u64 base = 0; |
| 1198 | if (rdev->flags & RADEON_IS_IGP) | 1198 | if (rdev->flags & RADEON_IS_IGP) { |
| 1199 | base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | 1199 | base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; |
| 1200 | base <<= 24; | ||
| 1201 | } | ||
| 1200 | radeon_vram_location(rdev, &rdev->mc, base); | 1202 | radeon_vram_location(rdev, &rdev->mc, base); |
| 1201 | rdev->mc.gtt_base_align = 0; | 1203 | rdev->mc.gtt_base_align = 0; |
| 1202 | radeon_gtt_location(rdev, mc); | 1204 | radeon_gtt_location(rdev, mc); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d8ac1849180d..e12e79326cb1 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
| 286 | mc->mc_vram_size = mc->aper_size; | 286 | mc->mc_vram_size = mc->aper_size; |
| 287 | } | 287 | } |
| 288 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 288 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 289 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | 289 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
| 290 | mc->mc_vram_size >> 20, mc->vram_start, | 290 | mc->mc_vram_size >> 20, mc->vram_start, |
| 291 | mc->vram_end, mc->real_vram_size >> 20); | 291 | mc->vram_end, mc->real_vram_size >> 20); |
| 292 | } | 292 | } |
| @@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
| 323 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; | 323 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; |
| 324 | } | 324 | } |
| 325 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; | 325 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; |
| 326 | dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", | 326 | dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", |
| 327 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); | 327 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); |
| 328 | } | 328 | } |
| 329 | 329 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d067743fee0..a598d0049aa5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
| 69 | u32 c = 0; | 69 | u32 c = 0; |
| 70 | 70 | ||
| 71 | rbo->placement.fpfn = 0; | 71 | rbo->placement.fpfn = 0; |
| 72 | rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; | 72 | rbo->placement.lpfn = 0; |
| 73 | rbo->placement.placement = rbo->placements; | 73 | rbo->placement.placement = rbo->placements; |
| 74 | rbo->placement.busy_placement = rbo->placements; | 74 | rbo->placement.busy_placement = rbo->placements; |
| 75 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 75 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
| @@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
| 91 | { | 91 | { |
| 92 | struct radeon_bo *bo; | 92 | struct radeon_bo *bo; |
| 93 | enum ttm_bo_type type; | 93 | enum ttm_bo_type type; |
| 94 | int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; | 94 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
| 95 | unsigned long max_size = 0; | ||
| 95 | int r; | 96 | int r; |
| 96 | 97 | ||
| 97 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 98 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { |
| @@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
| 104 | } | 105 | } |
| 105 | *bo_ptr = NULL; | 106 | *bo_ptr = NULL; |
| 106 | 107 | ||
| 108 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
| 109 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
| 110 | if ((page_align << PAGE_SHIFT) >= max_size) { | ||
| 111 | printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | ||
| 112 | __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | ||
| 113 | return -ENOMEM; | ||
| 114 | } | ||
| 115 | |||
| 107 | retry: | 116 | retry: |
| 108 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 117 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
| 109 | if (bo == NULL) | 118 | if (bo == NULL) |
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8c641bed9bbd..a2776e2807a4 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h | |||
| @@ -287,6 +287,8 @@ typedef struct drm_i915_irq_wait { | |||
| 287 | #define I915_PARAM_HAS_EXECBUF2 9 | 287 | #define I915_PARAM_HAS_EXECBUF2 9 |
| 288 | #define I915_PARAM_HAS_BSD 10 | 288 | #define I915_PARAM_HAS_BSD 10 |
| 289 | #define I915_PARAM_HAS_BLT 11 | 289 | #define I915_PARAM_HAS_BLT 11 |
| 290 | #define I915_PARAM_HAS_RELAXED_FENCING 12 | ||
| 291 | #define I915_PARAM_HAS_COHERENT_RINGS 13 | ||
| 290 | 292 | ||
| 291 | typedef struct drm_i915_getparam { | 293 | typedef struct drm_i915_getparam { |
| 292 | int param; | 294 | int param; |
