Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: hold ref on flip object until it completes
drm/i915: Fix crash while aborting hibernation
drm/i915: Correctly return -ENOMEM on allocation failure in cmdbuf ioctls.
drm/i915: fix pipe source image setting in flip command
drm/i915: fix flip done interrupt on Ironlake
drm/i915: untangle page flip completion
drm/i915: handle FBC and self-refresh better
drm/i915: Increase fb alignment to 64k
drm/i915: Update write_domains on active list after flush.
drm/i915: Rework DPLL calculation parameters for Ironlake

+339 -149
+3 -1
drivers/gpu/drm/i915/i915_dma.c
··· 735 735 if (cmdbuf->num_cliprects) { 736 736 cliprects = kcalloc(cmdbuf->num_cliprects, 737 737 sizeof(struct drm_clip_rect), GFP_KERNEL); 738 - if (cliprects == NULL) 738 + if (cliprects == NULL) { 739 + ret = -ENOMEM; 739 740 goto fail_batch_free; 741 + } 740 742 741 743 ret = copy_from_user(cliprects, cmdbuf->cliprects, 742 744 cmdbuf->num_cliprects *
+107 -73
drivers/gpu/drm/i915/i915_drv.c
··· 174 174 MODULE_DEVICE_TABLE(pci, pciidlist); 175 175 #endif 176 176 177 - static int i915_suspend(struct drm_device *dev, pm_message_t state) 177 + static int i915_drm_freeze(struct drm_device *dev) 178 + { 179 + pci_save_state(dev->pdev); 180 + 181 + /* If KMS is active, we do the leavevt stuff here */ 182 + if (drm_core_check_feature(dev, DRIVER_MODESET)) { 183 + int error = i915_gem_idle(dev); 184 + if (error) { 185 + dev_err(&dev->pdev->dev, 186 + "GEM idle failed, resume might fail\n"); 187 + return error; 188 + } 189 + drm_irq_uninstall(dev); 190 + } 191 + 192 + i915_save_state(dev); 193 + 194 + return 0; 195 + } 196 + 197 + static void i915_drm_suspend(struct drm_device *dev) 178 198 { 179 199 struct drm_i915_private *dev_priv = dev->dev_private; 180 200 181 - if (!dev || !dev_priv) { 182 - DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv); 201 + intel_opregion_free(dev, 1); 202 + 203 + /* Modeset on resume, not lid events */ 204 + dev_priv->modeset_on_lid = 0; 205 + } 206 + 207 + static int i915_suspend(struct drm_device *dev, pm_message_t state) 208 + { 209 + int error; 210 + 211 + if (!dev || !dev->dev_private) { 212 + DRM_ERROR("dev: %p\n", dev); 183 213 DRM_ERROR("DRM not initialized, aborting suspend.\n"); 184 214 return -ENODEV; 185 215 } ··· 217 187 if (state.event == PM_EVENT_PRETHAW) 218 188 return 0; 219 189 220 - pci_save_state(dev->pdev); 190 + error = i915_drm_freeze(dev); 191 + if (error) 192 + return error; 221 193 222 - /* If KMS is active, we do the leavevt stuff here */ 223 - if (drm_core_check_feature(dev, DRIVER_MODESET)) { 224 - if (i915_gem_idle(dev)) 225 - dev_err(&dev->pdev->dev, 226 - "GEM idle failed, resume may fail\n"); 227 - drm_irq_uninstall(dev); 228 - } 229 - 230 - i915_save_state(dev); 231 - 232 - intel_opregion_free(dev, 1); 194 + i915_drm_suspend(dev); 233 195 234 196 if (state.event == PM_EVENT_SUSPEND) { 235 197 /* Shut down the device */ ··· 229 207 pci_set_power_state(dev->pdev, PCI_D3hot); 230 208 } 231 209 232 - /* Modeset on resume, not lid events */ 233 - dev_priv->modeset_on_lid = 0; 234 - 235 210 return 0; 236 211 } 237 212 238 - static int i915_resume(struct drm_device *dev) 213 + static int i915_drm_thaw(struct drm_device *dev) 239 214 { 240 215 struct drm_i915_private *dev_priv = dev->dev_private; 241 - int ret = 0; 242 - 243 - if (pci_enable_device(dev->pdev)) 244 - return -1; 245 - pci_set_master(dev->pdev); 246 - 247 - i915_restore_state(dev); 248 - 249 - intel_opregion_init(dev, 1); 216 + int error = 0; 250 217 251 218 /* KMS EnterVT equivalent */ 252 219 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 253 220 mutex_lock(&dev->struct_mutex); 254 221 dev_priv->mm.suspended = 0; 255 222 256 - ret = i915_gem_init_ringbuffer(dev); 257 - if (ret != 0) 258 - ret = -1; 223 + error = i915_gem_init_ringbuffer(dev); 259 224 mutex_unlock(&dev->struct_mutex); 260 225 261 226 drm_irq_install(dev); 262 - } 263 - if (drm_core_check_feature(dev, DRIVER_MODESET)) { 227 + 264 228 /* Resume the modeset for every activated CRTC */ 265 229 drm_helper_resume_force_mode(dev); 266 230 } 267 231 268 232 dev_priv->modeset_on_lid = 0; 269 233 270 - return ret; 234 + return error; 235 + } 236 + 237 + static int i915_resume(struct drm_device *dev) 238 + { 239 + if (pci_enable_device(dev->pdev)) 240 + return -EIO; 241 + 242 + pci_set_master(dev->pdev); 243 + 244 + i915_restore_state(dev); 245 + 246 + intel_opregion_init(dev, 1); 247 + 248 + return i915_drm_thaw(dev); 271 249 } 272 250 273 251 /** ··· 408 386 drm_put_dev(dev); 409 387 } 410 388 411 - static int 412 - i915_pci_suspend(struct pci_dev *pdev, pm_message_t state) 389 + static int i915_pm_suspend(struct device *dev) 413 390 { 414 - struct drm_device *dev = pci_get_drvdata(pdev); 391 + struct pci_dev *pdev = to_pci_dev(dev); 392 + struct drm_device *drm_dev = pci_get_drvdata(pdev); 393 + int error; 415 394 416 - return i915_suspend(dev, state); 417 - } 395 + if (!drm_dev || !drm_dev->dev_private) { 396 + dev_err(dev, "DRM not initialized, aborting suspend.\n"); 397 + return -ENODEV; 398 + } 418 399 419 - static int 420 - i915_pci_resume(struct pci_dev *pdev) 421 - { 422 - struct drm_device *dev = pci_get_drvdata(pdev); 400 + error = i915_drm_freeze(drm_dev); 401 + if (error) 402 + return error; 423 403 424 - return i915_resume(dev); 425 - } 404 + i915_drm_suspend(drm_dev); 426 405 427 - static int 428 - i915_pm_suspend(struct device *dev) 429 - { 430 - return i915_pci_suspend(to_pci_dev(dev), PMSG_SUSPEND); 431 - } 406 + pci_disable_device(pdev); 407 + pci_set_power_state(pdev, PCI_D3hot); 432 408 433 - static int 434 - i915_pm_resume(struct device *dev) 435 - { 436 - return i915_pci_resume(to_pci_dev(dev)); 437 - } 438 - 439 - static int 440 - i915_pm_freeze(struct device *dev) 441 - { 442 - return i915_pci_suspend(to_pci_dev(dev), PMSG_FREEZE); 443 - } 444 - 445 - static int 446 - i915_pm_thaw(struct device *dev) 447 - { 448 - /* thaw during hibernate, do nothing! */ 449 409 return 0; 450 410 } 451 411 452 - static int 453 - i915_pm_poweroff(struct device *dev) 412 + static int i915_pm_resume(struct device *dev) 454 413 { 455 - return i915_pci_suspend(to_pci_dev(dev), PMSG_HIBERNATE); 414 + struct pci_dev *pdev = to_pci_dev(dev); 415 + struct drm_device *drm_dev = pci_get_drvdata(pdev); 416 + 417 + return i915_resume(drm_dev); 456 418 } 457 419 458 - static int 459 - i915_pm_restore(struct device *dev) 420 + static int i915_pm_freeze(struct device *dev) 460 421 { 461 - return i915_pci_resume(to_pci_dev(dev)); 422 + struct pci_dev *pdev = to_pci_dev(dev); 423 + struct drm_device *drm_dev = pci_get_drvdata(pdev); 424 + 425 + if (!drm_dev || !drm_dev->dev_private) { 426 + dev_err(dev, "DRM not initialized, aborting suspend.\n"); 427 + return -ENODEV; 428 + } 429 + 430 + return i915_drm_freeze(drm_dev); 431 + } 432 + 433 + static int i915_pm_thaw(struct device *dev) 434 + { 435 + struct pci_dev *pdev = to_pci_dev(dev); 436 + struct drm_device *drm_dev = pci_get_drvdata(pdev); 437 + 438 + return i915_drm_thaw(drm_dev); 439 + } 440 + 441 + static int i915_pm_poweroff(struct device *dev) 442 + { 443 + struct pci_dev *pdev = to_pci_dev(dev); 444 + struct drm_device *drm_dev = pci_get_drvdata(pdev); 445 + int error; 446 + 447 + error = i915_drm_freeze(drm_dev); 448 + if (!error) 449 + i915_drm_suspend(drm_dev); 450 + 451 + return error; 462 452 } 463 453 464 454 const struct dev_pm_ops i915_pm_ops = { ··· 479 445 .freeze = i915_pm_freeze, 480 446 .thaw = i915_pm_thaw, 481 447 .poweroff = i915_pm_poweroff, 482 - .restore = i915_pm_restore, 448 + .restore = i915_pm_resume, 483 449 }; 484 450 485 451 static struct vm_operations_struct i915_gem_vm_ops = {
+11
drivers/gpu/drm/i915/i915_drv.h
··· 493 493 struct list_head flushing_list; 494 494 495 495 /** 496 + * List of objects currently pending a GPU write flush. 497 + * 498 + * All elements on this list will belong to either the 499 + * active_list or flushing_list, last_rendering_seqno can 500 + * be used to differentiate between the two elements. 501 + */ 502 + struct list_head gpu_write_list; 503 + 504 + /** 496 505 * LRU list of objects which are not in the ringbuffer and 497 506 * are ready to unbind, but are still in the GTT. 498 507 * ··· 601 592 602 593 /** This object's place on the active/flushing/inactive lists */ 603 594 struct list_head list; 595 + /** This object's place on GPU write list */ 596 + struct list_head gpu_write_list; 604 597 605 598 /** This object's place on the fenced object LRU */ 606 599 struct list_head fence_list;
+22 -5
drivers/gpu/drm/i915/i915_gem.c
··· 1552 1552 else 1553 1553 list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); 1554 1554 1555 + BUG_ON(!list_empty(&obj_priv->gpu_write_list)); 1556 + 1555 1557 obj_priv->last_rendering_seqno = 0; 1556 1558 if (obj_priv->active) { 1557 1559 obj_priv->active = 0; ··· 1624 1622 struct drm_i915_gem_object *obj_priv, *next; 1625 1623 1626 1624 list_for_each_entry_safe(obj_priv, next, 1627 - &dev_priv->mm.flushing_list, list) { 1625 + &dev_priv->mm.gpu_write_list, 1626 + gpu_write_list) { 1628 1627 struct drm_gem_object *obj = obj_priv->obj; 1629 1628 1630 1629 if ((obj->write_domain & flush_domains) == ··· 1633 1630 uint32_t old_write_domain = obj->write_domain; 1634 1631 1635 1632 obj->write_domain = 0; 1633 + list_del_init(&obj_priv->gpu_write_list); 1636 1634 i915_gem_object_move_to_active(obj, seqno); 1637 1635 1638 1636 trace_i915_gem_object_change_domain(obj, ··· 2088 2084 i915_gem_evict_everything(struct drm_device *dev) 2089 2085 { 2090 2086 drm_i915_private_t *dev_priv = dev->dev_private; 2091 - uint32_t seqno; 2092 2087 int ret; 2088 + uint32_t seqno; 2093 2089 bool lists_empty; 2094 2090 2095 2091 spin_lock(&dev_priv->mm.active_list_lock); ··· 2110 2106 ret = i915_wait_request(dev, seqno); 2111 2107 if (ret) 2112 2108 return ret; 2109 + 2110 + BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); 2113 2111 2114 2112 ret = i915_gem_evict_from_inactive_list(dev); 2115 2113 if (ret) ··· 2707 2701 old_write_domain = obj->write_domain; 2708 2702 i915_gem_flush(dev, 0, obj->write_domain); 2709 2703 seqno = i915_add_request(dev, NULL, obj->write_domain); 2710 - obj->write_domain = 0; 2704 + BUG_ON(obj->write_domain); 2711 2705 i915_gem_object_move_to_active(obj, seqno); 2712 2706 2713 2707 trace_i915_gem_object_change_domain(obj, ··· 3688 3682 if (args->num_cliprects != 0) { 3689 3683 cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), 3690 3684 GFP_KERNEL); 3691 - if (cliprects == NULL) 3685 + if (cliprects == NULL) { 3686 + ret = -ENOMEM; 3692 3687 goto pre_mutex_err; 3688 + } 3693 3689 3694 3690 ret = copy_from_user(cliprects, 3695 3691 (struct drm_clip_rect __user *) ··· 3858 3850 i915_gem_flush(dev, 3859 3851 dev->invalidate_domains, 3860 3852 dev->flush_domains); 3861 - if (dev->flush_domains) 3853 + if (dev->flush_domains & I915_GEM_GPU_DOMAINS) 3862 3854 (void)i915_add_request(dev, file_priv, 3863 3855 dev->flush_domains); 3864 3856 } 3865 3857 3866 3858 for (i = 0; i < args->buffer_count; i++) { 3867 3859 struct drm_gem_object *obj = object_list[i]; 3860 + struct drm_i915_gem_object *obj_priv = obj->driver_private; 3868 3861 uint32_t old_write_domain = obj->write_domain; 3869 3862 3870 3863 obj->write_domain = obj->pending_write_domain; 3864 + if (obj->write_domain) 3865 + list_move_tail(&obj_priv->gpu_write_list, 3866 + &dev_priv->mm.gpu_write_list); 3867 + else 3868 + list_del_init(&obj_priv->gpu_write_list); 3869 + 3871 3870 trace_i915_gem_object_change_domain(obj, 3872 3871 obj->read_domains, 3873 3872 old_write_domain); ··· 4385 4370 obj_priv->obj = obj; 4386 4371 obj_priv->fence_reg = I915_FENCE_REG_NONE; 4387 4372 INIT_LIST_HEAD(&obj_priv->list); 4373 + INIT_LIST_HEAD(&obj_priv->gpu_write_list); 4388 4374 INIT_LIST_HEAD(&obj_priv->fence_list); 4389 4375 obj_priv->madv = I915_MADV_WILLNEED; 4390 4376 ··· 4837 4821 spin_lock_init(&dev_priv->mm.active_list_lock); 4838 4822 INIT_LIST_HEAD(&dev_priv->mm.active_list); 4839 4823 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 4824 + INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); 4840 4825 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); 4841 4826 INIT_LIST_HEAD(&dev_priv->mm.request_list); 4842 4827 INIT_LIST_HEAD(&dev_priv->mm.fence_list);
+9 -9
drivers/gpu/drm/i915/i915_irq.c
··· 309 309 if (de_iir & DE_GSE) 310 310 ironlake_opregion_gse_intr(dev); 311 311 312 - if (de_iir & DE_PLANEA_FLIP_DONE) 312 + if (de_iir & DE_PLANEA_FLIP_DONE) { 313 313 intel_prepare_page_flip(dev, 0); 314 - 315 - if (de_iir & DE_PLANEB_FLIP_DONE) 316 - intel_prepare_page_flip(dev, 1); 317 - 318 - if (de_iir & DE_PIPEA_VBLANK) { 319 - drm_handle_vblank(dev, 0); 320 314 intel_finish_page_flip(dev, 0); 321 315 } 322 316 323 - if (de_iir & DE_PIPEB_VBLANK) { 324 - drm_handle_vblank(dev, 1); 317 + if (de_iir & DE_PLANEB_FLIP_DONE) { 318 + intel_prepare_page_flip(dev, 1); 325 319 intel_finish_page_flip(dev, 1); 326 320 } 321 + 322 + if (de_iir & DE_PIPEA_VBLANK) 323 + drm_handle_vblank(dev, 0); 324 + 325 + if (de_iir & DE_PIPEB_VBLANK) 326 + drm_handle_vblank(dev, 1); 327 327 328 328 /* check event from PCH */ 329 329 if ((de_iir & DE_PCH_EVENT) &&
+1
drivers/gpu/drm/i915/i915_reg.h
··· 338 338 #define FBC_CTL_PERIODIC (1<<30) 339 339 #define FBC_CTL_INTERVAL_SHIFT (16) 340 340 #define FBC_CTL_UNCOMPRESSIBLE (1<<14) 341 + #define FBC_C3_IDLE (1<<13) 341 342 #define FBC_CTL_STRIDE_SHIFT (5) 342 343 #define FBC_CTL_FENCENO (1<<0) 343 344 #define FBC_COMMAND 0x0320c
+185 -60
drivers/gpu/drm/i915/intel_display.c
··· 240 240 #define IRONLAKE_DOT_MAX 350000 241 241 #define IRONLAKE_VCO_MIN 1760000 242 242 #define IRONLAKE_VCO_MAX 3510000 243 - #define IRONLAKE_N_MIN 1 244 - #define IRONLAKE_N_MAX 6 245 - #define IRONLAKE_M_MIN 79 246 - #define IRONLAKE_M_MAX 127 247 243 #define IRONLAKE_M1_MIN 12 248 244 #define IRONLAKE_M1_MAX 22 249 245 #define IRONLAKE_M2_MIN 5 250 246 #define IRONLAKE_M2_MAX 9 251 - #define IRONLAKE_P_SDVO_DAC_MIN 5 252 - #define IRONLAKE_P_SDVO_DAC_MAX 80 253 - #define IRONLAKE_P_LVDS_MIN 28 254 - #define IRONLAKE_P_LVDS_MAX 112 255 - #define IRONLAKE_P1_MIN 1 256 - #define IRONLAKE_P1_MAX 8 257 - #define IRONLAKE_P2_SDVO_DAC_SLOW 10 258 - #define IRONLAKE_P2_SDVO_DAC_FAST 5 259 - #define IRONLAKE_P2_LVDS_SLOW 14 /* single channel */ 260 - #define IRONLAKE_P2_LVDS_FAST 7 /* double channel */ 261 247 #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ 262 248 263 - #define IRONLAKE_P_DISPLAY_PORT_MIN 10 264 - #define IRONLAKE_P_DISPLAY_PORT_MAX 20 265 - #define IRONLAKE_P2_DISPLAY_PORT_FAST 10 266 - #define IRONLAKE_P2_DISPLAY_PORT_SLOW 10 267 - #define IRONLAKE_P2_DISPLAY_PORT_LIMIT 0 268 - #define IRONLAKE_P1_DISPLAY_PORT_MIN 1 269 - #define IRONLAKE_P1_DISPLAY_PORT_MAX 2 249 + /* We have parameter ranges for different type of outputs. */ 250 + 251 + /* DAC & HDMI Refclk 120Mhz */ 252 + #define IRONLAKE_DAC_N_MIN 1 253 + #define IRONLAKE_DAC_N_MAX 5 254 + #define IRONLAKE_DAC_M_MIN 79 255 + #define IRONLAKE_DAC_M_MAX 127 256 + #define IRONLAKE_DAC_P_MIN 5 257 + #define IRONLAKE_DAC_P_MAX 80 258 + #define IRONLAKE_DAC_P1_MIN 1 259 + #define IRONLAKE_DAC_P1_MAX 8 260 + #define IRONLAKE_DAC_P2_SLOW 10 261 + #define IRONLAKE_DAC_P2_FAST 5 262 + 263 + /* LVDS single-channel 120Mhz refclk */ 264 + #define IRONLAKE_LVDS_S_N_MIN 1 265 + #define IRONLAKE_LVDS_S_N_MAX 3 266 + #define IRONLAKE_LVDS_S_M_MIN 79 267 + #define IRONLAKE_LVDS_S_M_MAX 118 268 + #define IRONLAKE_LVDS_S_P_MIN 28 269 + #define IRONLAKE_LVDS_S_P_MAX 112 270 + #define IRONLAKE_LVDS_S_P1_MIN 2 271 + #define IRONLAKE_LVDS_S_P1_MAX 8 272 + #define IRONLAKE_LVDS_S_P2_SLOW 14 273 + #define IRONLAKE_LVDS_S_P2_FAST 14 274 + 275 + /* LVDS dual-channel 120Mhz refclk */ 276 + #define IRONLAKE_LVDS_D_N_MIN 1 277 + #define IRONLAKE_LVDS_D_N_MAX 3 278 + #define IRONLAKE_LVDS_D_M_MIN 79 279 + #define IRONLAKE_LVDS_D_M_MAX 127 280 + #define IRONLAKE_LVDS_D_P_MIN 14 281 + #define IRONLAKE_LVDS_D_P_MAX 56 282 + #define IRONLAKE_LVDS_D_P1_MIN 2 283 + #define IRONLAKE_LVDS_D_P1_MAX 8 284 + #define IRONLAKE_LVDS_D_P2_SLOW 7 285 + #define IRONLAKE_LVDS_D_P2_FAST 7 286 + 287 + /* LVDS single-channel 100Mhz refclk */ 288 + #define IRONLAKE_LVDS_S_SSC_N_MIN 1 289 + #define IRONLAKE_LVDS_S_SSC_N_MAX 2 290 + #define IRONLAKE_LVDS_S_SSC_M_MIN 79 291 + #define IRONLAKE_LVDS_S_SSC_M_MAX 126 292 + #define IRONLAKE_LVDS_S_SSC_P_MIN 28 293 + #define IRONLAKE_LVDS_S_SSC_P_MAX 112 294 + #define IRONLAKE_LVDS_S_SSC_P1_MIN 2 295 + #define IRONLAKE_LVDS_S_SSC_P1_MAX 8 296 + #define IRONLAKE_LVDS_S_SSC_P2_SLOW 14 297 + #define IRONLAKE_LVDS_S_SSC_P2_FAST 14 298 + 299 + /* LVDS dual-channel 100Mhz refclk */ 300 + #define IRONLAKE_LVDS_D_SSC_N_MIN 1 301 + #define IRONLAKE_LVDS_D_SSC_N_MAX 3 302 + #define IRONLAKE_LVDS_D_SSC_M_MIN 79 303 + #define IRONLAKE_LVDS_D_SSC_M_MAX 126 304 + #define IRONLAKE_LVDS_D_SSC_P_MIN 14 305 + #define IRONLAKE_LVDS_D_SSC_P_MAX 42 306 + #define IRONLAKE_LVDS_D_SSC_P1_MIN 2 307 + #define IRONLAKE_LVDS_D_SSC_P1_MAX 6 308 + #define IRONLAKE_LVDS_D_SSC_P2_SLOW 7 309 + #define IRONLAKE_LVDS_D_SSC_P2_FAST 7 310 + 311 + /* DisplayPort */ 312 + #define IRONLAKE_DP_N_MIN 1 313 + #define IRONLAKE_DP_N_MAX 2 314 + #define IRONLAKE_DP_M_MIN 81 315 + #define IRONLAKE_DP_M_MAX 90 316 + #define IRONLAKE_DP_P_MIN 10 317 + #define IRONLAKE_DP_P_MAX 20 318 + #define IRONLAKE_DP_P2_FAST 10 319 + #define IRONLAKE_DP_P2_SLOW 10 320 + #define IRONLAKE_DP_P2_LIMIT 0 321 + #define IRONLAKE_DP_P1_MIN 1 322 + #define IRONLAKE_DP_P1_MAX 2 270 323 271 324 static bool 272 325 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ··· 527 474 .find_pll = intel_find_best_PLL, 528 475 }; 529 476 530 - static const intel_limit_t intel_limits_ironlake_sdvo = { 477 + static const intel_limit_t intel_limits_ironlake_dac = { 531 478 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 532 479 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 533 - .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX }, 534 - .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX }, 480 + .n = { .min = IRONLAKE_DAC_N_MIN, .max = IRONLAKE_DAC_N_MAX }, 481 + .m = { .min = IRONLAKE_DAC_M_MIN, .max = IRONLAKE_DAC_M_MAX }, 535 482 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 536 483 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 537 - .p = { .min = IRONLAKE_P_SDVO_DAC_MIN, .max = IRONLAKE_P_SDVO_DAC_MAX }, 538 - .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX }, 484 + .p = { .min = IRONLAKE_DAC_P_MIN, .max = IRONLAKE_DAC_P_MAX }, 485 + .p1 = { .min = IRONLAKE_DAC_P1_MIN, .max = IRONLAKE_DAC_P1_MAX }, 539 486 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 540 - .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW, 541 - .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST }, 487 + .p2_slow = IRONLAKE_DAC_P2_SLOW, 488 + .p2_fast = IRONLAKE_DAC_P2_FAST }, 542 489 .find_pll = intel_g4x_find_best_PLL, 543 490 }; 544 491 545 - static const intel_limit_t intel_limits_ironlake_lvds = { 492 + static const intel_limit_t intel_limits_ironlake_single_lvds = { 546 493 .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 547 494 .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 548 - .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX }, 549 - .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX }, 495 + .n = { .min = IRONLAKE_LVDS_S_N_MIN, .max = IRONLAKE_LVDS_S_N_MAX }, 496 + .m = { .min = IRONLAKE_LVDS_S_M_MIN, .max = IRONLAKE_LVDS_S_M_MAX }, 550 497 .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 551 498 .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 552 - .p = { .min = IRONLAKE_P_LVDS_MIN, .max = IRONLAKE_P_LVDS_MAX }, 553 - .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX }, 499 + .p = { .min = IRONLAKE_LVDS_S_P_MIN, .max = IRONLAKE_LVDS_S_P_MAX }, 500 + .p1 = { .min = IRONLAKE_LVDS_S_P1_MIN, .max = IRONLAKE_LVDS_S_P1_MAX }, 554 501 .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 555 - .p2_slow = IRONLAKE_P2_LVDS_SLOW, 556 - .p2_fast = IRONLAKE_P2_LVDS_FAST }, 502 + .p2_slow = IRONLAKE_LVDS_S_P2_SLOW, 503 + .p2_fast = IRONLAKE_LVDS_S_P2_FAST }, 504 + .find_pll = intel_g4x_find_best_PLL, 505 + }; 506 + 507 + static const intel_limit_t intel_limits_ironlake_dual_lvds = { 508 + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 509 + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 510 + .n = { .min = IRONLAKE_LVDS_D_N_MIN, .max = IRONLAKE_LVDS_D_N_MAX }, 511 + .m = { .min = IRONLAKE_LVDS_D_M_MIN, .max = IRONLAKE_LVDS_D_M_MAX }, 512 + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 513 + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 514 + .p = { .min = IRONLAKE_LVDS_D_P_MIN, .max = IRONLAKE_LVDS_D_P_MAX }, 515 + .p1 = { .min = IRONLAKE_LVDS_D_P1_MIN, .max = IRONLAKE_LVDS_D_P1_MAX }, 516 + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 517 + .p2_slow = IRONLAKE_LVDS_D_P2_SLOW, 518 + .p2_fast = IRONLAKE_LVDS_D_P2_FAST }, 519 + .find_pll = intel_g4x_find_best_PLL, 520 + }; 521 + 522 + static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { 523 + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 524 + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 525 + .n = { .min = IRONLAKE_LVDS_S_SSC_N_MIN, .max = IRONLAKE_LVDS_S_SSC_N_MAX }, 526 + .m = { .min = IRONLAKE_LVDS_S_SSC_M_MIN, .max = IRONLAKE_LVDS_S_SSC_M_MAX }, 527 + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 528 + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 529 + .p = { .min = IRONLAKE_LVDS_S_SSC_P_MIN, .max = IRONLAKE_LVDS_S_SSC_P_MAX }, 530 + .p1 = { .min = IRONLAKE_LVDS_S_SSC_P1_MIN,.max = IRONLAKE_LVDS_S_SSC_P1_MAX }, 531 + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 532 + .p2_slow = IRONLAKE_LVDS_S_SSC_P2_SLOW, 533 + .p2_fast = IRONLAKE_LVDS_S_SSC_P2_FAST }, 534 + .find_pll = intel_g4x_find_best_PLL, 535 + }; 536 + 537 + static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { 538 + .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, 539 + .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, 540 + .n = { .min = IRONLAKE_LVDS_D_SSC_N_MIN, .max = IRONLAKE_LVDS_D_SSC_N_MAX }, 541 + .m = { .min = IRONLAKE_LVDS_D_SSC_M_MIN, .max = IRONLAKE_LVDS_D_SSC_M_MAX }, 542 + .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, 543 + .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, 544 + .p = { .min = IRONLAKE_LVDS_D_SSC_P_MIN, .max = IRONLAKE_LVDS_D_SSC_P_MAX }, 545 + .p1 = { .min = IRONLAKE_LVDS_D_SSC_P1_MIN,.max = IRONLAKE_LVDS_D_SSC_P1_MAX }, 546 + .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, 547 + .p2_slow = IRONLAKE_LVDS_D_SSC_P2_SLOW, 548 + .p2_fast = IRONLAKE_LVDS_D_SSC_P2_FAST }, 557 549 .find_pll = intel_g4x_find_best_PLL, 558 550 }; 559 551 ··· 607 509 .max = IRONLAKE_DOT_MAX }, 608 510 .vco = { .min = IRONLAKE_VCO_MIN, 609 511 .max = IRONLAKE_VCO_MAX}, 610 - .n = { .min = IRONLAKE_N_MIN, 611 - .max = IRONLAKE_N_MAX }, 612 - .m = { .min = IRONLAKE_M_MIN, 613 - .max = IRONLAKE_M_MAX }, 512 + .n = { .min = IRONLAKE_DP_N_MIN, 513 + .max = IRONLAKE_DP_N_MAX }, 514 + .m = { .min = IRONLAKE_DP_M_MIN, 515 + .max = IRONLAKE_DP_M_MAX }, 614 516 .m1 = { .min = IRONLAKE_M1_MIN, 615 517 .max = IRONLAKE_M1_MAX }, 616 518 .m2 = { .min = IRONLAKE_M2_MIN, 617 519 .max = IRONLAKE_M2_MAX }, 618 - .p = { .min = IRONLAKE_P_DISPLAY_PORT_MIN, 619 - .max = IRONLAKE_P_DISPLAY_PORT_MAX }, 620 - .p1 = { .min = IRONLAKE_P1_DISPLAY_PORT_MIN, 621 - .max = IRONLAKE_P1_DISPLAY_PORT_MAX}, 622 - .p2 = { .dot_limit = IRONLAKE_P2_DISPLAY_PORT_LIMIT, 623 - .p2_slow = IRONLAKE_P2_DISPLAY_PORT_SLOW, 624 - .p2_fast = IRONLAKE_P2_DISPLAY_PORT_FAST }, 520 + .p = { .min = IRONLAKE_DP_P_MIN, 521 + .max = IRONLAKE_DP_P_MAX }, 522 + .p1 = { .min = IRONLAKE_DP_P1_MIN, 523 + .max = IRONLAKE_DP_P1_MAX}, 524 + .p2 = { .dot_limit = IRONLAKE_DP_P2_LIMIT, 525 + .p2_slow = IRONLAKE_DP_P2_SLOW, 526 + .p2_fast = IRONLAKE_DP_P2_FAST }, 625 527 .find_pll = intel_find_pll_ironlake_dp, 626 528 }; 627 529 628 530 static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) 629 531 { 532 + struct drm_device *dev = crtc->dev; 533 + struct drm_i915_private *dev_priv = dev->dev_private; 630 534 const intel_limit_t *limit; 631 - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) 632 - limit = &intel_limits_ironlake_lvds; 633 - else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || 535 + int refclk = 120; 536 + 537 + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { 538 + if (dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100) 539 + refclk = 100; 540 + 541 + if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == 542 + LVDS_CLKB_POWER_UP) { 543 + /* LVDS dual channel */ 544 + if (refclk == 100) 545 + limit = &intel_limits_ironlake_dual_lvds_100m; 546 + else 547 + limit = &intel_limits_ironlake_dual_lvds; 548 + } else { 549 + if (refclk == 100) 550 + limit = &intel_limits_ironlake_single_lvds_100m; 551 + else 552 + limit = &intel_limits_ironlake_single_lvds; 553 + } 554 + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || 634 555 HAS_eDP) 635 556 limit = &intel_limits_ironlake_display_port; 636 557 else 637 - limit = &intel_limits_ironlake_sdvo; 558 + limit = &intel_limits_ironlake_dac; 638 559 639 560 return limit; 640 561 } ··· 1031 914 1032 915 /* enable it... */ 1033 916 fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; 917 + if (IS_I945GM(dev)) 918 + fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */ 1034 919 fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; 1035 920 fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; 1036 921 if (obj_priv->tiling_mode != I915_TILING_NONE) ··· 4081 3962 struct intel_unpin_work { 4082 3963 struct work_struct work; 4083 3964 struct drm_device *dev; 4084 - struct drm_gem_object *obj; 3965 + struct drm_gem_object *old_fb_obj; 3966 + struct drm_gem_object *pending_flip_obj; 4085 3967 struct drm_pending_vblank_event *event; 4086 3968 int pending; 4087 3969 }; ··· 4093 3973 container_of(__work, struct intel_unpin_work, work); 4094 3974 4095 3975 mutex_lock(&work->dev->struct_mutex); 4096 - i915_gem_object_unpin(work->obj); 4097 - drm_gem_object_unreference(work->obj); 3976 + i915_gem_object_unpin(work->old_fb_obj); 3977 + drm_gem_object_unreference(work->pending_flip_obj); 3978 + drm_gem_object_unreference(work->old_fb_obj); 4098 3979 mutex_unlock(&work->dev->struct_mutex); 4099 3980 kfree(work); 4100 3981 } ··· 4119 3998 work = intel_crtc->unpin_work; 4120 3999 if (work == NULL || !work->pending) { 4121 4000 if (work && !work->pending) { 4122 - obj_priv = work->obj->driver_private; 4001 + obj_priv = work->pending_flip_obj->driver_private; 4123 4002 DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", 4124 4003 obj_priv, 4125 4004 atomic_read(&obj_priv->pending_flip)); ··· 4144 4023 4145 4024 spin_unlock_irqrestore(&dev->event_lock, flags); 4146 4025 4147 - obj_priv = work->obj->driver_private; 4026 + obj_priv = work->pending_flip_obj->driver_private; 4148 4027 4149 4028 /* Initial scanout buffer will have a 0 pending flip count */ 4150 4029 if ((atomic_read(&obj_priv->pending_flip) == 0) || ··· 4181 4060 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 4182 4061 struct intel_unpin_work *work; 4183 4062 unsigned long flags; 4184 - int ret; 4063 + int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; 4064 + int ret, pipesrc; 4185 4065 RING_LOCALS; 4186 4066 4187 4067 work = kzalloc(sizeof *work, GFP_KERNEL); ··· 4194 4072 work->event = event; 4195 4073 work->dev = crtc->dev; 4196 4074 intel_fb = to_intel_framebuffer(crtc->fb); 4197 - work->obj = intel_fb->obj; 4075 + work->old_fb_obj = intel_fb->obj; 4198 4076 INIT_WORK(&work->work, intel_unpin_work_fn); 4199 4077 4200 4078 /* We borrow the event spin lock for protecting unpin_work */ ··· 4222 4100 return ret; 4223 4101 } 4224 4102 4225 - /* Reference the old fb object for the scheduled work. */ 4226 - drm_gem_object_reference(work->obj); 4103 + /* Reference the objects for the scheduled work. */ 4104 + drm_gem_object_reference(work->old_fb_obj); 4105 + drm_gem_object_reference(obj); 4227 4106 4228 4107 crtc->fb = fb; 4229 4108 i915_gem_object_flush_write_domain(obj); 4230 4109 drm_vblank_get(dev, intel_crtc->pipe); 4231 4110 obj_priv = obj->driver_private; 4232 4111 atomic_inc(&obj_priv->pending_flip); 4112 + work->pending_flip_obj = obj; 4233 4113 4234 4114 BEGIN_LP_RING(4); 4235 4115 OUT_RING(MI_DISPLAY_FLIP | ··· 4239 4115 OUT_RING(fb->pitch); 4240 4116 if (IS_I965G(dev)) { 4241 4117 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); 4242 - OUT_RING((fb->width << 16) | fb->height); 4118 + pipesrc = I915_READ(pipesrc_reg); 4119 + OUT_RING(pipesrc & 0x0fff0fff); 4243 4120 } else { 4244 4121 OUT_RING(obj_priv->gtt_offset); 4245 4122 OUT_RING(MI_NOOP);
+1 -1
drivers/gpu/drm/i915/intel_fb.c
··· 148 148 149 149 mutex_lock(&dev->struct_mutex); 150 150 151 - ret = i915_gem_object_pin(fbo, PAGE_SIZE); 151 + ret = i915_gem_object_pin(fbo, 64*1024); 152 152 if (ret) { 153 153 DRM_ERROR("failed to pin fb: %d\n", ret); 154 154 goto out_unref;