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 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm/i915: lock correct mutex around object unreference.
drm/i915: add support for physical memory objects
drm/i915: make LVDS fixed mode a preferred mode
drm: handle depth & bpp changes correctly
drm: initial KMS config fixes
drm/i915: setup sarea properly in master_priv
drm/i915: set vblank enabled flag correctly across IRQ install/uninstall
drm/i915: don't enable vblanks on disabled pipes

+406 -69
+126 -49
drivers/gpu/drm/drm_crtc_helper.c
··· 36 36 /* 37 37 * Detailed mode info for 800x600@60Hz 38 38 */ 39 - static struct drm_display_mode std_mode[] = { 39 + static struct drm_display_mode std_modes[] = { 40 40 { DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840, 41 41 968, 1056, 0, 600, 601, 605, 628, 0, 42 42 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ··· 60 60 * changes have occurred. 61 61 * 62 62 * FIXME: take into account monitor limits 63 + * 64 + * RETURNS: 65 + * Number of modes found on @connector. 63 66 */ 64 - void drm_helper_probe_single_connector_modes(struct drm_connector *connector, 65 - uint32_t maxX, uint32_t maxY) 67 + int drm_helper_probe_single_connector_modes(struct drm_connector *connector, 68 + uint32_t maxX, uint32_t maxY) 66 69 { 67 70 struct drm_device *dev = connector->dev; 68 71 struct drm_display_mode *mode, *t; 69 72 struct drm_connector_helper_funcs *connector_funcs = 70 73 connector->helper_private; 71 - int ret; 74 + int count = 0; 72 75 73 76 DRM_DEBUG("%s\n", drm_get_connector_name(connector)); 74 77 /* set all modes to the unverified state */ ··· 84 81 DRM_DEBUG("%s is disconnected\n", 85 82 drm_get_connector_name(connector)); 86 83 /* TODO set EDID to NULL */ 87 - return; 84 + return 0; 88 85 } 89 86 90 - ret = (*connector_funcs->get_modes)(connector); 87 + count = (*connector_funcs->get_modes)(connector); 88 + if (!count) 89 + return 0; 91 90 92 - if (ret) { 93 - drm_mode_connector_list_update(connector); 94 - } 91 + drm_mode_connector_list_update(connector); 95 92 96 93 if (maxX && maxY) 97 94 drm_mode_validate_size(dev, &connector->modes, maxX, ··· 105 102 106 103 drm_mode_prune_invalid(dev, &connector->modes, true); 107 104 108 - if (list_empty(&connector->modes)) { 109 - struct drm_display_mode *stdmode; 110 - 111 - DRM_DEBUG("No valid modes on %s\n", 112 - drm_get_connector_name(connector)); 113 - 114 - /* Should we do this here ??? 115 - * When no valid EDID modes are available we end up 116 - * here and bailed in the past, now we add a standard 117 - * 640x480@60Hz mode and carry on. 118 - */ 119 - stdmode = drm_mode_duplicate(dev, &std_mode[0]); 120 - drm_mode_probed_add(connector, stdmode); 121 - drm_mode_list_concat(&connector->probed_modes, 122 - &connector->modes); 123 - 124 - DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n", 125 - drm_get_connector_name(connector)); 126 - } 105 + if (list_empty(&connector->modes)) 106 + return 0; 127 107 128 108 drm_mode_sort(&connector->modes); 129 109 ··· 117 131 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 118 132 drm_mode_debug_printmodeline(mode); 119 133 } 134 + 135 + return count; 120 136 } 121 137 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); 122 138 123 - void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, 139 + int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, 124 140 uint32_t maxY) 125 141 { 126 142 struct drm_connector *connector; 143 + int count = 0; 127 144 128 145 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 129 - drm_helper_probe_single_connector_modes(connector, maxX, maxY); 146 + count += drm_helper_probe_single_connector_modes(connector, 147 + maxX, maxY); 130 148 } 149 + 150 + return count; 131 151 } 132 152 EXPORT_SYMBOL(drm_helper_probe_connector_modes); 133 153 154 + static void drm_helper_add_std_modes(struct drm_device *dev, 155 + struct drm_connector *connector) 156 + { 157 + struct drm_display_mode *mode, *t; 158 + int i; 159 + 160 + for (i = 0; i < ARRAY_SIZE(std_modes); i++) { 161 + struct drm_display_mode *stdmode; 162 + 163 + /* 164 + * When no valid EDID modes are available we end up 165 + * here and bailed in the past, now we add some standard 166 + * modes and move on. 167 + */ 168 + stdmode = drm_mode_duplicate(dev, &std_modes[i]); 169 + drm_mode_probed_add(connector, stdmode); 170 + drm_mode_list_concat(&connector->probed_modes, 171 + &connector->modes); 172 + 173 + DRM_DEBUG("Adding mode %s to %s\n", stdmode->name, 174 + drm_get_connector_name(connector)); 175 + } 176 + drm_mode_sort(&connector->modes); 177 + 178 + DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector)); 179 + list_for_each_entry_safe(mode, t, &connector->modes, head) { 180 + mode->vrefresh = drm_mode_vrefresh(mode); 181 + 182 + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 183 + drm_mode_debug_printmodeline(mode); 184 + } 185 + } 134 186 135 187 /** 136 188 * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config ··· 261 237 262 238 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 263 239 enabled[i] = drm_connector_enabled(connector, true); 240 + DRM_DEBUG("connector %d enabled? %s\n", connector->base.id, 241 + enabled[i] ? "yes" : "no"); 264 242 any_enabled |= enabled[i]; 265 243 i++; 266 244 } ··· 291 265 continue; 292 266 } 293 267 268 + DRM_DEBUG("looking for preferred mode on connector %d\n", 269 + connector->base.id); 270 + 294 271 modes[i] = drm_has_preferred_mode(connector, width, height); 295 - if (!modes[i]) { 272 + /* No preferred modes, pick one off the list */ 273 + if (!modes[i] && !list_empty(&connector->modes)) { 296 274 list_for_each_entry(modes[i], &connector->modes, head) 297 275 break; 298 276 } 277 + DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name : 278 + "none"); 299 279 i++; 300 280 } 301 281 return true; ··· 401 369 int width, height; 402 370 int i, ret; 403 371 372 + DRM_DEBUG("\n"); 373 + 404 374 width = dev->mode_config.max_width; 405 375 height = dev->mode_config.max_height; 406 376 ··· 424 390 if (!ret) 425 391 DRM_ERROR("Unable to find initial modes\n"); 426 392 393 + DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height); 394 + 427 395 drm_pick_crtcs(dev, crtcs, modes, 0, width, height); 428 396 429 397 i = 0; ··· 439 403 } 440 404 441 405 if (mode && crtc) { 406 + DRM_DEBUG("desired mode %s set on crtc %d\n", 407 + mode->name, crtc->base.id); 442 408 crtc->desired_mode = mode; 443 409 connector->encoder->crtc = crtc; 444 410 } else ··· 480 442 int saved_x, saved_y; 481 443 struct drm_encoder *encoder; 482 444 bool ret = true; 445 + bool depth_changed, bpp_changed; 483 446 484 447 adjusted_mode = drm_mode_duplicate(dev, mode); 485 448 ··· 488 449 489 450 if (!crtc->enabled) 490 451 return true; 452 + 453 + if (old_fb && crtc->fb) { 454 + depth_changed = (old_fb->depth != crtc->fb->depth); 455 + bpp_changed = (old_fb->bits_per_pixel != 456 + crtc->fb->bits_per_pixel); 457 + } else { 458 + depth_changed = true; 459 + bpp_changed = true; 460 + } 491 461 492 462 saved_mode = crtc->mode; 493 463 saved_x = crtc->x; ··· 510 462 crtc->y = y; 511 463 512 464 if (drm_mode_equal(&saved_mode, &crtc->mode)) { 513 - if (saved_x != crtc->x || saved_y != crtc->y) { 465 + if (saved_x != crtc->x || saved_y != crtc->y || 466 + depth_changed || bpp_changed) { 514 467 crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y, 515 468 old_fb); 516 469 goto done; ··· 617 568 struct drm_encoder **save_encoders, *new_encoder; 618 569 struct drm_framebuffer *old_fb; 619 570 bool save_enabled; 620 - bool changed = false; 621 - bool flip_or_move = false; 571 + bool mode_changed = false; 572 + bool fb_changed = false; 622 573 struct drm_connector *connector; 623 574 int count = 0, ro, fail = 0; 624 575 struct drm_crtc_helper_funcs *crtc_funcs; ··· 646 597 /* save previous config */ 647 598 save_enabled = set->crtc->enabled; 648 599 649 - /* this is meant to be num_connector not num_crtc */ 600 + /* 601 + * We do mode_config.num_connectors here since we'll look at the 602 + * CRTC and encoder associated with each connector later. 603 + */ 650 604 save_crtcs = kzalloc(dev->mode_config.num_connector * 651 605 sizeof(struct drm_crtc *), GFP_KERNEL); 652 606 if (!save_crtcs) ··· 665 613 /* We should be able to check here if the fb has the same properties 666 614 * and then just flip_or_move it */ 667 615 if (set->crtc->fb != set->fb) { 668 - /* if we have no fb then its a change not a flip */ 616 + /* If we have no fb then treat it as a full mode set */ 669 617 if (set->crtc->fb == NULL) 670 - changed = true; 618 + mode_changed = true; 619 + else if ((set->fb->bits_per_pixel != 620 + set->crtc->fb->bits_per_pixel) || 621 + set->fb->depth != set->crtc->fb->depth) 622 + fb_changed = true; 671 623 else 672 - flip_or_move = true; 624 + fb_changed = true; 673 625 } 674 626 675 627 if (set->x != set->crtc->x || set->y != set->crtc->y) 676 - flip_or_move = true; 628 + fb_changed = true; 677 629 678 630 if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { 679 631 DRM_DEBUG("modes are different\n"); 680 632 drm_mode_debug_printmodeline(&set->crtc->mode); 681 633 drm_mode_debug_printmodeline(set->mode); 682 - changed = true; 634 + mode_changed = true; 683 635 } 684 636 685 637 /* a) traverse passed in connector list and get encoders for them */ ··· 706 650 } 707 651 708 652 if (new_encoder != connector->encoder) { 709 - changed = true; 653 + mode_changed = true; 710 654 connector->encoder = new_encoder; 711 655 } 712 656 } ··· 733 677 new_crtc = set->crtc; 734 678 } 735 679 if (new_crtc != connector->encoder->crtc) { 736 - changed = true; 680 + mode_changed = true; 737 681 connector->encoder->crtc = new_crtc; 738 682 } 739 683 } 740 684 741 685 /* mode_set_base is not a required function */ 742 - if (flip_or_move && !crtc_funcs->mode_set_base) 743 - changed = true; 686 + if (fb_changed && !crtc_funcs->mode_set_base) 687 + mode_changed = true; 744 688 745 - if (changed) { 689 + if (mode_changed) { 746 690 old_fb = set->crtc->fb; 747 691 set->crtc->fb = set->fb; 748 692 set->crtc->enabled = (set->mode != NULL); ··· 761 705 set->crtc->desired_mode = set->mode; 762 706 } 763 707 drm_helper_disable_unused_functions(dev); 764 - } else if (flip_or_move) { 708 + } else if (fb_changed) { 765 709 old_fb = set->crtc->fb; 766 710 if (set->crtc->fb != set->fb) 767 711 set->crtc->fb = set->fb; ··· 820 764 */ 821 765 bool drm_helper_initial_config(struct drm_device *dev, bool can_grow) 822 766 { 823 - int ret = false; 767 + struct drm_connector *connector; 768 + int count = 0; 824 769 825 - drm_helper_plugged_event(dev); 826 - return ret; 770 + count = drm_helper_probe_connector_modes(dev, 771 + dev->mode_config.max_width, 772 + dev->mode_config.max_height); 773 + 774 + /* 775 + * None of the available connectors had any modes, so add some 776 + * and try to light them up anyway 777 + */ 778 + if (!count) { 779 + DRM_ERROR("connectors have no modes, using standard modes\n"); 780 + list_for_each_entry(connector, 781 + &dev->mode_config.connector_list, 782 + head) 783 + drm_helper_add_std_modes(dev, connector); 784 + } 785 + 786 + drm_setup_crtcs(dev); 787 + 788 + /* alert the driver fb layer */ 789 + dev->mode_config.funcs->fb_changed(dev); 790 + 791 + return 0; 827 792 } 828 793 EXPORT_SYMBOL(drm_helper_initial_config); 829 794
+15 -3
drivers/gpu/drm/drm_irq.c
··· 267 267 */ 268 268 int drm_irq_uninstall(struct drm_device * dev) 269 269 { 270 - int irq_enabled; 270 + unsigned long irqflags; 271 + int irq_enabled, i; 271 272 272 273 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 273 274 return -EINVAL; ··· 277 276 irq_enabled = dev->irq_enabled; 278 277 dev->irq_enabled = 0; 279 278 mutex_unlock(&dev->struct_mutex); 279 + 280 + /* 281 + * Wake up any waiters so they don't hang. 282 + */ 283 + spin_lock_irqsave(&dev->vbl_lock, irqflags); 284 + for (i = 0; i < dev->num_crtcs; i++) { 285 + DRM_WAKEUP(&dev->vbl_queue[i]); 286 + dev->vblank_enabled[i] = 0; 287 + } 288 + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 280 289 281 290 if (!irq_enabled) 282 291 return -EINVAL; ··· 663 652 vblwait->request.sequence, crtc); 664 653 dev->last_vblank_wait[crtc] = vblwait->request.sequence; 665 654 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, 666 - ((drm_vblank_count(dev, crtc) 667 - - vblwait->request.sequence) <= (1 << 23))); 655 + (((drm_vblank_count(dev, crtc) - 656 + vblwait->request.sequence) <= (1 << 23)) || 657 + !dev->irq_enabled)); 668 658 669 659 if (ret != -EINTR) { 670 660 struct timeval now;
+10
drivers/gpu/drm/i915/i915_dma.c
··· 177 177 drm_i915_private_t *dev_priv = dev->dev_private; 178 178 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 179 179 180 + master_priv->sarea = drm_getsarea(dev); 181 + if (master_priv->sarea) { 182 + master_priv->sarea_priv = (drm_i915_sarea_t *) 183 + ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); 184 + } else { 185 + DRM_DEBUG("sarea not found assuming DRI2 userspace\n"); 186 + } 187 + 180 188 if (init->ring_size != 0) { 181 189 if (dev_priv->ring.ring_obj != NULL) { 182 190 i915_dma_cleanup(dev); ··· 1159 1151 1160 1152 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1161 1153 intel_modeset_cleanup(dev); 1154 + 1155 + i915_gem_free_all_phys_object(dev); 1162 1156 1163 1157 mutex_lock(&dev->struct_mutex); 1164 1158 i915_gem_cleanup_ringbuffer(dev);
+23
drivers/gpu/drm/i915/i915_drv.h
··· 72 72 #define WATCH_INACTIVE 0 73 73 #define WATCH_PWRITE 0 74 74 75 + #define I915_GEM_PHYS_CURSOR_0 1 76 + #define I915_GEM_PHYS_CURSOR_1 2 77 + #define I915_GEM_PHYS_OVERLAY_REGS 3 78 + #define I915_MAX_PHYS_OBJECT (I915_GEM_PHYS_OVERLAY_REGS) 79 + 80 + struct drm_i915_gem_phys_object { 81 + int id; 82 + struct page **page_list; 83 + drm_dma_handle_t *handle; 84 + struct drm_gem_object *cur_obj; 85 + }; 86 + 75 87 typedef struct _drm_i915_ring_buffer { 76 88 int tail_mask; 77 89 unsigned long Size; ··· 370 358 uint32_t bit_6_swizzle_x; 371 359 /** Bit 6 swizzling required for Y tiling */ 372 360 uint32_t bit_6_swizzle_y; 361 + 362 + /* storage for physical objects */ 363 + struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; 373 364 } mm; 374 365 } drm_i915_private_t; 375 366 ··· 451 436 /** User space pin count and filp owning the pin */ 452 437 uint32_t user_pin_count; 453 438 struct drm_file *pin_filp; 439 + 440 + /** for phy allocated objects */ 441 + struct drm_i915_gem_phys_object *phys_obj; 454 442 }; 455 443 456 444 /** ··· 616 598 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 617 599 int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, 618 600 int write); 601 + int i915_gem_attach_phys_object(struct drm_device *dev, 602 + struct drm_gem_object *obj, int id); 603 + void i915_gem_detach_phys_object(struct drm_device *dev, 604 + struct drm_gem_object *obj); 605 + void i915_gem_free_all_phys_object(struct drm_device *dev); 619 606 620 607 /* i915_gem_tiling.c */ 621 608 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
+187 -2
drivers/gpu/drm/i915/i915_gem.c
··· 55 55 static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj); 56 56 static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 57 57 static int i915_gem_evict_something(struct drm_device *dev); 58 + static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 59 + struct drm_i915_gem_pwrite *args, 60 + struct drm_file *file_priv); 58 61 59 62 int i915_gem_do_init(struct drm_device *dev, unsigned long start, 60 63 unsigned long end) ··· 389 386 * pread/pwrite currently are reading and writing from the CPU 390 387 * perspective, requiring manual detiling by the client. 391 388 */ 392 - if (obj_priv->tiling_mode == I915_TILING_NONE && 393 - dev->gtt_total != 0) 389 + if (obj_priv->phys_obj) 390 + ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); 391 + else if (obj_priv->tiling_mode == I915_TILING_NONE && 392 + dev->gtt_total != 0) 394 393 ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv); 395 394 else 396 395 ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv); ··· 2863 2858 while (obj_priv->pin_count > 0) 2864 2859 i915_gem_object_unpin(obj); 2865 2860 2861 + if (obj_priv->phys_obj) 2862 + i915_gem_detach_phys_object(dev, obj); 2863 + 2866 2864 i915_gem_object_unbind(obj); 2867 2865 2868 2866 list = &obj->map_list; ··· 3300 3292 dev_priv->num_fence_regs = 8; 3301 3293 3302 3294 i915_gem_detect_bit_6_swizzle(dev); 3295 + } 3296 + 3297 + /* 3298 + * Create a physically contiguous memory object for this object 3299 + * e.g. for cursor + overlay regs 3300 + */ 3301 + int i915_gem_init_phys_object(struct drm_device *dev, 3302 + int id, int size) 3303 + { 3304 + drm_i915_private_t *dev_priv = dev->dev_private; 3305 + struct drm_i915_gem_phys_object *phys_obj; 3306 + int ret; 3307 + 3308 + if (dev_priv->mm.phys_objs[id - 1] || !size) 3309 + return 0; 3310 + 3311 + phys_obj = drm_calloc(1, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); 3312 + if (!phys_obj) 3313 + return -ENOMEM; 3314 + 3315 + phys_obj->id = id; 3316 + 3317 + phys_obj->handle = drm_pci_alloc(dev, size, 0, 0xffffffff); 3318 + if (!phys_obj->handle) { 3319 + ret = -ENOMEM; 3320 + goto kfree_obj; 3321 + } 3322 + #ifdef CONFIG_X86 3323 + set_memory_wc((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); 3324 + #endif 3325 + 3326 + dev_priv->mm.phys_objs[id - 1] = phys_obj; 3327 + 3328 + return 0; 3329 + kfree_obj: 3330 + drm_free(phys_obj, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); 3331 + return ret; 3332 + } 3333 + 3334 + void i915_gem_free_phys_object(struct drm_device *dev, int id) 3335 + { 3336 + drm_i915_private_t *dev_priv = dev->dev_private; 3337 + struct drm_i915_gem_phys_object *phys_obj; 3338 + 3339 + if (!dev_priv->mm.phys_objs[id - 1]) 3340 + return; 3341 + 3342 + phys_obj = dev_priv->mm.phys_objs[id - 1]; 3343 + if (phys_obj->cur_obj) { 3344 + i915_gem_detach_phys_object(dev, phys_obj->cur_obj); 3345 + } 3346 + 3347 + #ifdef CONFIG_X86 3348 + set_memory_wb((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); 3349 + #endif 3350 + drm_pci_free(dev, phys_obj->handle); 3351 + kfree(phys_obj); 3352 + dev_priv->mm.phys_objs[id - 1] = NULL; 3353 + } 3354 + 3355 + void i915_gem_free_all_phys_object(struct drm_device *dev) 3356 + { 3357 + int i; 3358 + 3359 + for (i = 0; i < I915_MAX_PHYS_OBJECT; i++) 3360 + i915_gem_free_phys_object(dev, i); 3361 + } 3362 + 3363 + void i915_gem_detach_phys_object(struct drm_device *dev, 3364 + struct drm_gem_object *obj) 3365 + { 3366 + struct drm_i915_gem_object *obj_priv; 3367 + int i; 3368 + int ret; 3369 + int page_count; 3370 + 3371 + obj_priv = obj->driver_private; 3372 + if (!obj_priv->phys_obj) 3373 + return; 3374 + 3375 + ret = i915_gem_object_get_page_list(obj); 3376 + if (ret) 3377 + goto out; 3378 + 3379 + page_count = obj->size / PAGE_SIZE; 3380 + 3381 + for (i = 0; i < page_count; i++) { 3382 + char *dst = kmap_atomic(obj_priv->page_list[i], KM_USER0); 3383 + char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); 3384 + 3385 + memcpy(dst, src, PAGE_SIZE); 3386 + kunmap_atomic(dst, KM_USER0); 3387 + } 3388 + drm_clflush_pages(obj_priv->page_list, page_count); 3389 + drm_agp_chipset_flush(dev); 3390 + out: 3391 + obj_priv->phys_obj->cur_obj = NULL; 3392 + obj_priv->phys_obj = NULL; 3393 + } 3394 + 3395 + int 3396 + i915_gem_attach_phys_object(struct drm_device *dev, 3397 + struct drm_gem_object *obj, int id) 3398 + { 3399 + drm_i915_private_t *dev_priv = dev->dev_private; 3400 + struct drm_i915_gem_object *obj_priv; 3401 + int ret = 0; 3402 + int page_count; 3403 + int i; 3404 + 3405 + if (id > I915_MAX_PHYS_OBJECT) 3406 + return -EINVAL; 3407 + 3408 + obj_priv = obj->driver_private; 3409 + 3410 + if (obj_priv->phys_obj) { 3411 + if (obj_priv->phys_obj->id == id) 3412 + return 0; 3413 + i915_gem_detach_phys_object(dev, obj); 3414 + } 3415 + 3416 + 3417 + /* create a new object */ 3418 + if (!dev_priv->mm.phys_objs[id - 1]) { 3419 + ret = i915_gem_init_phys_object(dev, id, 3420 + obj->size); 3421 + if (ret) { 3422 + DRM_ERROR("failed to init phys object %d size: %d\n", id, obj->size); 3423 + goto out; 3424 + } 3425 + } 3426 + 3427 + /* bind to the object */ 3428 + obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; 3429 + obj_priv->phys_obj->cur_obj = obj; 3430 + 3431 + ret = i915_gem_object_get_page_list(obj); 3432 + if (ret) { 3433 + DRM_ERROR("failed to get page list\n"); 3434 + goto out; 3435 + } 3436 + 3437 + page_count = obj->size / PAGE_SIZE; 3438 + 3439 + for (i = 0; i < page_count; i++) { 3440 + char *src = kmap_atomic(obj_priv->page_list[i], KM_USER0); 3441 + char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); 3442 + 3443 + memcpy(dst, src, PAGE_SIZE); 3444 + kunmap_atomic(src, KM_USER0); 3445 + } 3446 + 3447 + return 0; 3448 + out: 3449 + return ret; 3450 + } 3451 + 3452 + static int 3453 + i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, 3454 + struct drm_i915_gem_pwrite *args, 3455 + struct drm_file *file_priv) 3456 + { 3457 + struct drm_i915_gem_object *obj_priv = obj->driver_private; 3458 + void *obj_addr; 3459 + int ret; 3460 + char __user *user_data; 3461 + 3462 + user_data = (char __user *) (uintptr_t) args->data_ptr; 3463 + obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; 3464 + 3465 + DRM_ERROR("obj_addr %p, %lld\n", obj_addr, args->size); 3466 + ret = copy_from_user(obj_addr, user_data, args->size); 3467 + if (ret) 3468 + return -EFAULT; 3469 + 3470 + drm_agp_chipset_flush(dev); 3471 + return 0; 3303 3472 }
+6
drivers/gpu/drm/i915/i915_irq.c
··· 411 411 { 412 412 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 413 413 unsigned long irqflags; 414 + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 415 + u32 pipeconf; 416 + 417 + pipeconf = I915_READ(pipeconf_reg); 418 + if (!(pipeconf & PIPEACONF_ENABLE)) 419 + return -EINVAL; 414 420 415 421 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 416 422 if (IS_I965G(dev))
+30 -13
drivers/gpu/drm/i915/intel_display.c
··· 401 401 I915_WRITE(dspstride, crtc->fb->pitch); 402 402 403 403 dspcntr = I915_READ(dspcntr_reg); 404 + /* Mask out pixel format bits in case we change it */ 405 + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 404 406 switch (crtc->fb->bits_per_pixel) { 405 407 case 8: 406 408 dspcntr |= DISPPLANE_8BPP; ··· 1016 1014 1017 1015 if (bo->size < width * height * 4) { 1018 1016 DRM_ERROR("buffer is to small\n"); 1019 - drm_gem_object_unreference(bo); 1020 - return -ENOMEM; 1017 + ret = -ENOMEM; 1018 + goto fail; 1021 1019 } 1022 1020 1023 - if (dev_priv->cursor_needs_physical) { 1024 - addr = dev->agp->base + obj_priv->gtt_offset; 1025 - } else { 1021 + /* we only need to pin inside GTT if cursor is non-phy */ 1022 + if (!dev_priv->cursor_needs_physical) { 1023 + ret = i915_gem_object_pin(bo, PAGE_SIZE); 1024 + if (ret) { 1025 + DRM_ERROR("failed to pin cursor bo\n"); 1026 + goto fail; 1027 + } 1026 1028 addr = obj_priv->gtt_offset; 1027 - } 1028 - 1029 - ret = i915_gem_object_pin(bo, PAGE_SIZE); 1030 - if (ret) { 1031 - DRM_ERROR("failed to pin cursor bo\n"); 1032 - drm_gem_object_unreference(bo); 1033 - return ret; 1029 + } else { 1030 + ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); 1031 + if (ret) { 1032 + DRM_ERROR("failed to attach phys object\n"); 1033 + goto fail; 1034 + } 1035 + addr = obj_priv->phys_obj->handle->busaddr; 1034 1036 } 1035 1037 1036 1038 temp = 0; ··· 1047 1041 I915_WRITE(base, addr); 1048 1042 1049 1043 if (intel_crtc->cursor_bo) { 1050 - i915_gem_object_unpin(intel_crtc->cursor_bo); 1044 + if (dev_priv->cursor_needs_physical) { 1045 + if (intel_crtc->cursor_bo != bo) 1046 + i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); 1047 + } else 1048 + i915_gem_object_unpin(intel_crtc->cursor_bo); 1049 + mutex_lock(&dev->struct_mutex); 1051 1050 drm_gem_object_unreference(intel_crtc->cursor_bo); 1051 + mutex_unlock(&dev->struct_mutex); 1052 1052 } 1053 1053 1054 1054 intel_crtc->cursor_addr = addr; 1055 1055 intel_crtc->cursor_bo = bo; 1056 1056 1057 1057 return 0; 1058 + fail: 1059 + mutex_lock(&dev->struct_mutex); 1060 + drm_gem_object_unreference(bo); 1061 + mutex_unlock(&dev->struct_mutex); 1062 + return ret; 1058 1063 } 1059 1064 1060 1065 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+7
drivers/gpu/drm/i915/intel_lvds.c
··· 456 456 dev_priv->panel_fixed_mode = 457 457 drm_mode_duplicate(dev, dev_priv->vbt_mode); 458 458 mutex_unlock(&dev->mode_config.mutex); 459 + if (dev_priv->panel_fixed_mode) { 460 + dev_priv->panel_fixed_mode->type |= 461 + DRM_MODE_TYPE_PREFERRED; 462 + drm_mode_probed_add(connector, 463 + dev_priv->panel_fixed_mode); 464 + goto out; 465 + } 459 466 } 460 467 461 468 /*
+1 -1
include/drm/drm_crtc.h
··· 395 395 void (*save)(struct drm_connector *connector); 396 396 void (*restore)(struct drm_connector *connector); 397 397 enum drm_connector_status (*detect)(struct drm_connector *connector); 398 - void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); 398 + int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); 399 399 int (*set_property)(struct drm_connector *connector, struct drm_property *property, 400 400 uint64_t val); 401 401 void (*destroy)(struct drm_connector *connector);
+1 -1
include/drm/drm_crtc_helper.h
··· 88 88 struct drm_encoder *(*best_encoder)(struct drm_connector *connector); 89 89 }; 90 90 91 - extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); 91 + extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); 92 92 extern void drm_helper_disable_unused_functions(struct drm_device *dev); 93 93 extern int drm_helper_hotplug_stage_two(struct drm_device *dev); 94 94 extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow);