diff options
Diffstat (limited to 'drivers/gpu')
34 files changed, 302 insertions, 168 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index c58f691ec3ce..b493663c7ba7 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -24,6 +24,7 @@ config DRM_KMS_HELPER | |||
24 | depends on DRM | 24 | depends on DRM |
25 | select FB | 25 | select FB |
26 | select FRAMEBUFFER_CONSOLE if !EXPERT | 26 | select FRAMEBUFFER_CONSOLE if !EXPERT |
27 | select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE | ||
27 | help | 28 | help |
28 | FB and CRTC helpers for KMS drivers. | 29 | FB and CRTC helpers for KMS drivers. |
29 | 30 | ||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 950720473967..11d7a72c22d9 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info) | |||
342 | } | 342 | } |
343 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); | 343 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); |
344 | 344 | ||
345 | bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) | ||
346 | { | ||
347 | bool error = false; | ||
348 | int i, ret; | ||
349 | for (i = 0; i < fb_helper->crtc_count; i++) { | ||
350 | struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; | ||
351 | ret = drm_crtc_helper_set_config(mode_set); | ||
352 | if (ret) | ||
353 | error = true; | ||
354 | } | ||
355 | return error; | ||
356 | } | ||
357 | EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); | ||
358 | |||
345 | bool drm_fb_helper_force_kernel_mode(void) | 359 | bool drm_fb_helper_force_kernel_mode(void) |
346 | { | 360 | { |
347 | int i = 0; | ||
348 | bool ret, error = false; | 361 | bool ret, error = false; |
349 | struct drm_fb_helper *helper; | 362 | struct drm_fb_helper *helper; |
350 | 363 | ||
@@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void) | |||
352 | return false; | 365 | return false; |
353 | 366 | ||
354 | list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { | 367 | list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { |
355 | for (i = 0; i < helper->crtc_count; i++) { | 368 | if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
356 | struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; | 369 | continue; |
357 | ret = drm_crtc_helper_set_config(mode_set); | 370 | |
358 | if (ret) | 371 | ret = drm_fb_helper_restore_fbdev_mode(helper); |
359 | error = true; | 372 | if (ret) |
360 | } | 373 | error = true; |
361 | } | 374 | } |
362 | return error; | 375 | return error; |
363 | } | 376 | } |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 741457bd1c46..a1f12cb043de 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put); | |||
932 | 932 | ||
933 | void drm_vblank_off(struct drm_device *dev, int crtc) | 933 | void drm_vblank_off(struct drm_device *dev, int crtc) |
934 | { | 934 | { |
935 | struct drm_pending_vblank_event *e, *t; | ||
936 | struct timeval now; | ||
935 | unsigned long irqflags; | 937 | unsigned long irqflags; |
938 | unsigned int seq; | ||
936 | 939 | ||
937 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 940 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
938 | vblank_disable_and_save(dev, crtc); | 941 | vblank_disable_and_save(dev, crtc); |
939 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | 942 | DRM_WAKEUP(&dev->vbl_queue[crtc]); |
943 | |||
944 | /* Send any queued vblank events, lest the natives grow disquiet */ | ||
945 | seq = drm_vblank_count_and_time(dev, crtc, &now); | ||
946 | list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { | ||
947 | if (e->pipe != crtc) | ||
948 | continue; | ||
949 | DRM_DEBUG("Sending premature vblank event on disable: \ | ||
950 | wanted %d, current %d\n", | ||
951 | e->event.sequence, seq); | ||
952 | |||
953 | e->event.sequence = seq; | ||
954 | e->event.tv_sec = now.tv_sec; | ||
955 | e->event.tv_usec = now.tv_usec; | ||
956 | drm_vblank_put(dev, e->pipe); | ||
957 | list_move_tail(&e->base.link, &e->base.file_priv->event_list); | ||
958 | wake_up_interruptible(&e->base.file_priv->event_wait); | ||
959 | trace_drm_vblank_event_delivered(e->base.pid, e->pipe, | ||
960 | e->event.sequence); | ||
961 | } | ||
962 | |||
940 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 963 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
941 | } | 964 | } |
942 | EXPORT_SYMBOL(drm_vblank_off); | 965 | EXPORT_SYMBOL(drm_vblank_off); |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 5d00b0fc0d91..959186cbf328 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -431,7 +431,7 @@ EXPORT_SYMBOL(drm_mm_search_free_in_range); | |||
431 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) | 431 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) |
432 | { | 432 | { |
433 | list_replace(&old->node_list, &new->node_list); | 433 | list_replace(&old->node_list, &new->node_list); |
434 | list_replace(&old->node_list, &new->hole_stack); | 434 | list_replace(&old->hole_stack, &new->hole_stack); |
435 | new->hole_follows = old->hole_follows; | 435 | new->hole_follows = old->hole_follows; |
436 | new->mm = old->mm; | 436 | new->mm = old->mm; |
437 | new->start = old->start; | 437 | new->start = old->start; |
@@ -699,8 +699,8 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) | |||
699 | entry->size); | 699 | entry->size); |
700 | total_used += entry->size; | 700 | total_used += entry->size; |
701 | if (entry->hole_follows) { | 701 | if (entry->hole_follows) { |
702 | hole_start = drm_mm_hole_node_start(&mm->head_node); | 702 | hole_start = drm_mm_hole_node_start(entry); |
703 | hole_end = drm_mm_hole_node_end(&mm->head_node); | 703 | hole_end = drm_mm_hole_node_end(entry); |
704 | hole_size = hole_end - hole_start; | 704 | hole_size = hole_end - hole_start; |
705 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", | 705 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", |
706 | hole_start, hole_end, hole_size); | 706 | hole_start, hole_end, hole_size); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 72730377a01b..12876f2795d2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -2207,7 +2207,7 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
2207 | drm_i915_private_t *dev_priv = dev->dev_private; | 2207 | drm_i915_private_t *dev_priv = dev->dev_private; |
2208 | 2208 | ||
2209 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { | 2209 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { |
2210 | drm_fb_helper_restore(); | 2210 | intel_fb_restore_mode(dev); |
2211 | vga_switcheroo_process_delayed_switch(); | 2211 | vga_switcheroo_process_delayed_switch(); |
2212 | return; | 2212 | return; |
2213 | } | 2213 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 432fc04c6bff..373c2a005ec1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3771,8 +3771,11 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
3771 | int entries, tlb_miss; | 3771 | int entries, tlb_miss; |
3772 | 3772 | ||
3773 | crtc = intel_get_crtc_for_plane(dev, plane); | 3773 | crtc = intel_get_crtc_for_plane(dev, plane); |
3774 | if (crtc->fb == NULL || !crtc->enabled) | 3774 | if (crtc->fb == NULL || !crtc->enabled) { |
3775 | *cursor_wm = cursor->guard_size; | ||
3776 | *plane_wm = display->guard_size; | ||
3775 | return false; | 3777 | return false; |
3778 | } | ||
3776 | 3779 | ||
3777 | htotal = crtc->mode.htotal; | 3780 | htotal = crtc->mode.htotal; |
3778 | hdisplay = crtc->mode.hdisplay; | 3781 | hdisplay = crtc->mode.hdisplay; |
@@ -5151,8 +5154,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
5151 | 5154 | ||
5152 | I915_WRITE(DSPCNTR(plane), dspcntr); | 5155 | I915_WRITE(DSPCNTR(plane), dspcntr); |
5153 | POSTING_READ(DSPCNTR(plane)); | 5156 | POSTING_READ(DSPCNTR(plane)); |
5154 | if (!HAS_PCH_SPLIT(dev)) | ||
5155 | intel_enable_plane(dev_priv, plane, pipe); | ||
5156 | 5157 | ||
5157 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 5158 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
5158 | 5159 | ||
@@ -5602,9 +5603,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) | |||
5602 | intel_clock_t clock; | 5603 | intel_clock_t clock; |
5603 | 5604 | ||
5604 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) | 5605 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) |
5605 | fp = FP0(pipe); | 5606 | fp = I915_READ(FP0(pipe)); |
5606 | else | 5607 | else |
5607 | fp = FP1(pipe); | 5608 | fp = I915_READ(FP1(pipe)); |
5608 | 5609 | ||
5609 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; | 5610 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; |
5610 | if (IS_PINEVIEW(dev)) { | 5611 | if (IS_PINEVIEW(dev)) { |
@@ -6215,36 +6216,6 @@ cleanup_work: | |||
6215 | return ret; | 6216 | return ret; |
6216 | } | 6217 | } |
6217 | 6218 | ||
6218 | static void intel_crtc_reset(struct drm_crtc *crtc) | ||
6219 | { | ||
6220 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6221 | |||
6222 | /* Reset flags back to the 'unknown' status so that they | ||
6223 | * will be correctly set on the initial modeset. | ||
6224 | */ | ||
6225 | intel_crtc->dpms_mode = -1; | ||
6226 | } | ||
6227 | |||
6228 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | ||
6229 | .dpms = intel_crtc_dpms, | ||
6230 | .mode_fixup = intel_crtc_mode_fixup, | ||
6231 | .mode_set = intel_crtc_mode_set, | ||
6232 | .mode_set_base = intel_pipe_set_base, | ||
6233 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | ||
6234 | .load_lut = intel_crtc_load_lut, | ||
6235 | .disable = intel_crtc_disable, | ||
6236 | }; | ||
6237 | |||
6238 | static const struct drm_crtc_funcs intel_crtc_funcs = { | ||
6239 | .reset = intel_crtc_reset, | ||
6240 | .cursor_set = intel_crtc_cursor_set, | ||
6241 | .cursor_move = intel_crtc_cursor_move, | ||
6242 | .gamma_set = intel_crtc_gamma_set, | ||
6243 | .set_config = drm_crtc_helper_set_config, | ||
6244 | .destroy = intel_crtc_destroy, | ||
6245 | .page_flip = intel_crtc_page_flip, | ||
6246 | }; | ||
6247 | |||
6248 | static void intel_sanitize_modesetting(struct drm_device *dev, | 6219 | static void intel_sanitize_modesetting(struct drm_device *dev, |
6249 | int pipe, int plane) | 6220 | int pipe, int plane) |
6250 | { | 6221 | { |
@@ -6281,6 +6252,42 @@ static void intel_sanitize_modesetting(struct drm_device *dev, | |||
6281 | intel_disable_pipe(dev_priv, pipe); | 6252 | intel_disable_pipe(dev_priv, pipe); |
6282 | } | 6253 | } |
6283 | 6254 | ||
6255 | static void intel_crtc_reset(struct drm_crtc *crtc) | ||
6256 | { | ||
6257 | struct drm_device *dev = crtc->dev; | ||
6258 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6259 | |||
6260 | /* Reset flags back to the 'unknown' status so that they | ||
6261 | * will be correctly set on the initial modeset. | ||
6262 | */ | ||
6263 | intel_crtc->dpms_mode = -1; | ||
6264 | |||
6265 | /* We need to fix up any BIOS configuration that conflicts with | ||
6266 | * our expectations. | ||
6267 | */ | ||
6268 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
6269 | } | ||
6270 | |||
6271 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | ||
6272 | .dpms = intel_crtc_dpms, | ||
6273 | .mode_fixup = intel_crtc_mode_fixup, | ||
6274 | .mode_set = intel_crtc_mode_set, | ||
6275 | .mode_set_base = intel_pipe_set_base, | ||
6276 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | ||
6277 | .load_lut = intel_crtc_load_lut, | ||
6278 | .disable = intel_crtc_disable, | ||
6279 | }; | ||
6280 | |||
6281 | static const struct drm_crtc_funcs intel_crtc_funcs = { | ||
6282 | .reset = intel_crtc_reset, | ||
6283 | .cursor_set = intel_crtc_cursor_set, | ||
6284 | .cursor_move = intel_crtc_cursor_move, | ||
6285 | .gamma_set = intel_crtc_gamma_set, | ||
6286 | .set_config = drm_crtc_helper_set_config, | ||
6287 | .destroy = intel_crtc_destroy, | ||
6288 | .page_flip = intel_crtc_page_flip, | ||
6289 | }; | ||
6290 | |||
6284 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 6291 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
6285 | { | 6292 | { |
6286 | drm_i915_private_t *dev_priv = dev->dev_private; | 6293 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -6330,8 +6337,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
6330 | 6337 | ||
6331 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 6338 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
6332 | (unsigned long)intel_crtc); | 6339 | (unsigned long)intel_crtc); |
6333 | |||
6334 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
6335 | } | 6340 | } |
6336 | 6341 | ||
6337 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 6342 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
@@ -6572,8 +6577,10 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
6572 | return ERR_PTR(-ENOENT); | 6577 | return ERR_PTR(-ENOENT); |
6573 | 6578 | ||
6574 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); | 6579 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
6575 | if (!intel_fb) | 6580 | if (!intel_fb) { |
6581 | drm_gem_object_unreference_unlocked(&obj->base); | ||
6576 | return ERR_PTR(-ENOMEM); | 6582 | return ERR_PTR(-ENOMEM); |
6583 | } | ||
6577 | 6584 | ||
6578 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); | 6585 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); |
6579 | if (ret) { | 6586 | if (ret) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cb8578b7e443..a4d80314e7f8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1470,7 +1470,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1470 | 1470 | ||
1471 | if (!HAS_PCH_CPT(dev) && | 1471 | if (!HAS_PCH_CPT(dev) && |
1472 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | 1472 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
1473 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | 1473 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
1474 | |||
1474 | /* Hardware workaround: leaving our transcoder select | 1475 | /* Hardware workaround: leaving our transcoder select |
1475 | * set to transcoder B while it's off will prevent the | 1476 | * set to transcoder B while it's off will prevent the |
1476 | * corresponding HDMI output on transcoder A. | 1477 | * corresponding HDMI output on transcoder A. |
@@ -1485,7 +1486,19 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1485 | /* Changes to enable or select take place the vblank | 1486 | /* Changes to enable or select take place the vblank |
1486 | * after being written. | 1487 | * after being written. |
1487 | */ | 1488 | */ |
1488 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1489 | if (crtc == NULL) { |
1490 | /* We can arrive here never having been attached | ||
1491 | * to a CRTC, for instance, due to inheriting | ||
1492 | * random state from the BIOS. | ||
1493 | * | ||
1494 | * If the pipe is not running, play safe and | ||
1495 | * wait for the clocks to stabilise before | ||
1496 | * continuing. | ||
1497 | */ | ||
1498 | POSTING_READ(intel_dp->output_reg); | ||
1499 | msleep(50); | ||
1500 | } else | ||
1501 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); | ||
1489 | } | 1502 | } |
1490 | 1503 | ||
1491 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1504 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f5b0d8306d83..1d20712d527f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -338,4 +338,5 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
338 | struct drm_file *file_priv); | 338 | struct drm_file *file_priv); |
339 | 339 | ||
340 | extern void intel_fb_output_poll_changed(struct drm_device *dev); | 340 | extern void intel_fb_output_poll_changed(struct drm_device *dev); |
341 | extern void intel_fb_restore_mode(struct drm_device *dev); | ||
341 | #endif /* __INTEL_DRV_H__ */ | 342 | #endif /* __INTEL_DRV_H__ */ |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 512782728e51..ec49bae73382 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -264,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev) | |||
264 | drm_i915_private_t *dev_priv = dev->dev_private; | 264 | drm_i915_private_t *dev_priv = dev->dev_private; |
265 | drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); | 265 | drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); |
266 | } | 266 | } |
267 | |||
268 | void intel_fb_restore_mode(struct drm_device *dev) | ||
269 | { | ||
270 | int ret; | ||
271 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
272 | |||
273 | ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); | ||
274 | if (ret) | ||
275 | DRM_DEBUG("failed to restore crtc mode\n"); | ||
276 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a562bd2648c7..67cb076d271b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -539,6 +539,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
539 | struct drm_device *dev = dev_priv->dev; | 539 | struct drm_device *dev = dev_priv->dev; |
540 | struct drm_connector *connector = dev_priv->int_lvds_connector; | 540 | struct drm_connector *connector = dev_priv->int_lvds_connector; |
541 | 541 | ||
542 | if (dev->switch_power_state != DRM_SWITCH_POWER_ON) | ||
543 | return NOTIFY_OK; | ||
544 | |||
542 | /* | 545 | /* |
543 | * check and update the status of LVDS connector after receiving | 546 | * check and update the status of LVDS connector after receiving |
544 | * the LID nofication event. | 547 | * the LID nofication event. |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 4256b8ef3947..6b22c1dcc015 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1151,10 +1151,10 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1151 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); | 1151 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); |
1152 | { | 1152 | { |
1153 | int pipeconf_reg = PIPECONF(pipe); | 1153 | int pipeconf_reg = PIPECONF(pipe); |
1154 | int dspcntr_reg = DSPCNTR(pipe); | 1154 | int dspcntr_reg = DSPCNTR(intel_crtc->plane); |
1155 | int pipeconf = I915_READ(pipeconf_reg); | 1155 | int pipeconf = I915_READ(pipeconf_reg); |
1156 | int dspcntr = I915_READ(dspcntr_reg); | 1156 | int dspcntr = I915_READ(dspcntr_reg); |
1157 | int dspbase_reg = DSPADDR(pipe); | 1157 | int dspbase_reg = DSPADDR(intel_crtc->plane); |
1158 | int xpos = 0x0, ypos = 0x0; | 1158 | int xpos = 0x0, ypos = 0x0; |
1159 | unsigned int xsize, ysize; | 1159 | unsigned int xsize, ysize; |
1160 | /* Pipe must be off here */ | 1160 | /* Pipe must be off here */ |
@@ -1378,7 +1378,9 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
1378 | if (type < 0) | 1378 | if (type < 0) |
1379 | return connector_status_disconnected; | 1379 | return connector_status_disconnected; |
1380 | 1380 | ||
1381 | intel_tv->type = type; | ||
1381 | intel_tv_find_better_format(connector); | 1382 | intel_tv_find_better_format(connector); |
1383 | |||
1382 | return connector_status_connected; | 1384 | return connector_status_connected; |
1383 | } | 1385 | } |
1384 | 1386 | ||
@@ -1670,8 +1672,7 @@ intel_tv_init(struct drm_device *dev) | |||
1670 | * | 1672 | * |
1671 | * More recent chipsets favour HDMI rather than integrated S-Video. | 1673 | * More recent chipsets favour HDMI rather than integrated S-Video. |
1672 | */ | 1674 | */ |
1673 | connector->polled = | 1675 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1674 | DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | ||
1675 | 1676 | ||
1676 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1677 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
1677 | DRM_MODE_CONNECTOR_SVIDEO); | 1678 | DRM_MODE_CONNECTOR_SVIDEO); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index ce38e97b9428..568caedd7216 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
@@ -83,7 +83,7 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
83 | return ret; | 83 | return ret; |
84 | 84 | ||
85 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ | 85 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ |
86 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, | 86 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, |
87 | &chan->m2mf_ntfy); | 87 | &chan->m2mf_ntfy); |
88 | if (ret) | 88 | if (ret) |
89 | return ret; | 89 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 856d56a98d1e..a76514a209b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -682,6 +682,9 @@ struct drm_nouveau_private { | |||
682 | /* For PFIFO and PGRAPH. */ | 682 | /* For PFIFO and PGRAPH. */ |
683 | spinlock_t context_switch_lock; | 683 | spinlock_t context_switch_lock; |
684 | 684 | ||
685 | /* VM/PRAMIN flush, legacy PRAMIN aperture */ | ||
686 | spinlock_t vm_lock; | ||
687 | |||
685 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ | 688 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ |
686 | struct nouveau_ramht *ramht; | 689 | struct nouveau_ramht *ramht; |
687 | struct nouveau_gpuobj *ramfc; | 690 | struct nouveau_gpuobj *ramfc; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 889c4454682e..39aee6d4daf8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -181,13 +181,13 @@ nouveau_fbcon_sync(struct fb_info *info) | |||
181 | OUT_RING (chan, 0); | 181 | OUT_RING (chan, 0); |
182 | } | 182 | } |
183 | 183 | ||
184 | nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); | 184 | nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3, 0xffffffff); |
185 | FIRE_RING(chan); | 185 | FIRE_RING(chan); |
186 | mutex_unlock(&chan->mutex); | 186 | mutex_unlock(&chan->mutex); |
187 | 187 | ||
188 | ret = -EBUSY; | 188 | ret = -EBUSY; |
189 | for (i = 0; i < 100000; i++) { | 189 | for (i = 0; i < 100000; i++) { |
190 | if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) { | 190 | if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3)) { |
191 | ret = 0; | 191 | ret = 0; |
192 | break; | 192 | break; |
193 | } | 193 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 78f467fe30be..c3e953b08992 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -152,8 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev) | |||
152 | { | 152 | { |
153 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 153 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
154 | 154 | ||
155 | nouveau_bo_ref(NULL, &dev_priv->vga_ram); | ||
156 | |||
157 | ttm_bo_device_release(&dev_priv->ttm.bdev); | 155 | ttm_bo_device_release(&dev_priv->ttm.bdev); |
158 | 156 | ||
159 | nouveau_ttm_global_release(dev_priv); | 157 | nouveau_ttm_global_release(dev_priv); |
@@ -398,7 +396,7 @@ nouveau_mem_vram_init(struct drm_device *dev) | |||
398 | dma_bits = 40; | 396 | dma_bits = 40; |
399 | } else | 397 | } else |
400 | if (drm_pci_device_is_pcie(dev) && | 398 | if (drm_pci_device_is_pcie(dev) && |
401 | dev_priv->chipset != 0x40 && | 399 | dev_priv->chipset > 0x40 && |
402 | dev_priv->chipset != 0x45) { | 400 | dev_priv->chipset != 0x45) { |
403 | if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) | 401 | if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) |
404 | dma_bits = 39; | 402 | dma_bits = 39; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 7ba3fc0b30c1..5b39718ae1f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -35,19 +35,22 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) | |||
35 | { | 35 | { |
36 | struct drm_device *dev = chan->dev; | 36 | struct drm_device *dev = chan->dev; |
37 | struct nouveau_bo *ntfy = NULL; | 37 | struct nouveau_bo *ntfy = NULL; |
38 | uint32_t flags; | 38 | uint32_t flags, ttmpl; |
39 | int ret; | 39 | int ret; |
40 | 40 | ||
41 | if (nouveau_vram_notify) | 41 | if (nouveau_vram_notify) { |
42 | flags = NOUVEAU_GEM_DOMAIN_VRAM; | 42 | flags = NOUVEAU_GEM_DOMAIN_VRAM; |
43 | else | 43 | ttmpl = TTM_PL_FLAG_VRAM; |
44 | } else { | ||
44 | flags = NOUVEAU_GEM_DOMAIN_GART; | 45 | flags = NOUVEAU_GEM_DOMAIN_GART; |
46 | ttmpl = TTM_PL_FLAG_TT; | ||
47 | } | ||
45 | 48 | ||
46 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy); | 49 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy); |
47 | if (ret) | 50 | if (ret) |
48 | return ret; | 51 | return ret; |
49 | 52 | ||
50 | ret = nouveau_bo_pin(ntfy, flags); | 53 | ret = nouveau_bo_pin(ntfy, ttmpl); |
51 | if (ret) | 54 | if (ret) |
52 | goto out_err; | 55 | goto out_err; |
53 | 56 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 4f00c87ed86e..67a16e01ffa6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -1039,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) | |||
1039 | { | 1039 | { |
1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; | 1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
1041 | struct drm_device *dev = gpuobj->dev; | 1041 | struct drm_device *dev = gpuobj->dev; |
1042 | unsigned long flags; | ||
1042 | 1043 | ||
1043 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { | 1044 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
1044 | u64 ptr = gpuobj->vinst + offset; | 1045 | u64 ptr = gpuobj->vinst + offset; |
1045 | u32 base = ptr >> 16; | 1046 | u32 base = ptr >> 16; |
1046 | u32 val; | 1047 | u32 val; |
1047 | 1048 | ||
1048 | spin_lock(&dev_priv->ramin_lock); | 1049 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
1049 | if (dev_priv->ramin_base != base) { | 1050 | if (dev_priv->ramin_base != base) { |
1050 | dev_priv->ramin_base = base; | 1051 | dev_priv->ramin_base = base; |
1051 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); | 1052 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
1052 | } | 1053 | } |
1053 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); | 1054 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); |
1054 | spin_unlock(&dev_priv->ramin_lock); | 1055 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
1055 | return val; | 1056 | return val; |
1056 | } | 1057 | } |
1057 | 1058 | ||
@@ -1063,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) | |||
1063 | { | 1064 | { |
1064 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; | 1065 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
1065 | struct drm_device *dev = gpuobj->dev; | 1066 | struct drm_device *dev = gpuobj->dev; |
1067 | unsigned long flags; | ||
1066 | 1068 | ||
1067 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { | 1069 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
1068 | u64 ptr = gpuobj->vinst + offset; | 1070 | u64 ptr = gpuobj->vinst + offset; |
1069 | u32 base = ptr >> 16; | 1071 | u32 base = ptr >> 16; |
1070 | 1072 | ||
1071 | spin_lock(&dev_priv->ramin_lock); | 1073 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
1072 | if (dev_priv->ramin_base != base) { | 1074 | if (dev_priv->ramin_base != base) { |
1073 | dev_priv->ramin_base = base; | 1075 | dev_priv->ramin_base = base; |
1074 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); | 1076 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
1075 | } | 1077 | } |
1076 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); | 1078 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); |
1077 | spin_unlock(&dev_priv->ramin_lock); | 1079 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
1078 | return; | 1080 | return; |
1079 | } | 1081 | } |
1080 | 1082 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index a33fe4019286..4bce801bc588 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -55,6 +55,7 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, | |||
55 | be->func->clear(be); | 55 | be->func->clear(be); |
56 | return -EFAULT; | 56 | return -EFAULT; |
57 | } | 57 | } |
58 | nvbe->ttm_alloced[nvbe->nr_pages] = false; | ||
58 | } | 59 | } |
59 | 60 | ||
60 | nvbe->nr_pages++; | 61 | nvbe->nr_pages++; |
@@ -427,7 +428,7 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
427 | u32 aper_size, align; | 428 | u32 aper_size, align; |
428 | int ret; | 429 | int ret; |
429 | 430 | ||
430 | if (dev_priv->card_type >= NV_50 || drm_pci_device_is_pcie(dev)) | 431 | if (dev_priv->card_type >= NV_40 && drm_pci_device_is_pcie(dev)) |
431 | aper_size = 512 * 1024 * 1024; | 432 | aper_size = 512 * 1024 * 1024; |
432 | else | 433 | else |
433 | aper_size = 64 * 1024 * 1024; | 434 | aper_size = 64 * 1024 * 1024; |
@@ -457,7 +458,7 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
457 | dev_priv->gart_info.func = &nv50_sgdma_backend; | 458 | dev_priv->gart_info.func = &nv50_sgdma_backend; |
458 | } else | 459 | } else |
459 | if (drm_pci_device_is_pcie(dev) && | 460 | if (drm_pci_device_is_pcie(dev) && |
460 | dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) { | 461 | dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) { |
461 | if (nv44_graph_class(dev)) { | 462 | if (nv44_graph_class(dev)) { |
462 | dev_priv->gart_info.func = &nv44_sgdma_backend; | 463 | dev_priv->gart_info.func = &nv44_sgdma_backend; |
463 | align = 512 * 1024; | 464 | align = 512 * 1024; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 6e2b1a6caa2d..915fbce89595 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -608,6 +608,7 @@ nouveau_card_init(struct drm_device *dev) | |||
608 | spin_lock_init(&dev_priv->channels.lock); | 608 | spin_lock_init(&dev_priv->channels.lock); |
609 | spin_lock_init(&dev_priv->tile.lock); | 609 | spin_lock_init(&dev_priv->tile.lock); |
610 | spin_lock_init(&dev_priv->context_switch_lock); | 610 | spin_lock_init(&dev_priv->context_switch_lock); |
611 | spin_lock_init(&dev_priv->vm_lock); | ||
611 | 612 | ||
612 | /* Make the CRTCs and I2C buses accessible */ | 613 | /* Make the CRTCs and I2C buses accessible */ |
613 | ret = engine->display.early_init(dev); | 614 | ret = engine->display.early_init(dev); |
@@ -767,6 +768,11 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
767 | engine->mc.takedown(dev); | 768 | engine->mc.takedown(dev); |
768 | engine->display.late_takedown(dev); | 769 | engine->display.late_takedown(dev); |
769 | 770 | ||
771 | if (dev_priv->vga_ram) { | ||
772 | nouveau_bo_unpin(dev_priv->vga_ram); | ||
773 | nouveau_bo_ref(NULL, &dev_priv->vga_ram); | ||
774 | } | ||
775 | |||
770 | mutex_lock(&dev->struct_mutex); | 776 | mutex_lock(&dev->struct_mutex); |
771 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); | 777 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); |
772 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); | 778 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index a6f8aa651fc6..4f95a1e5822e 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -404,23 +404,25 @@ void | |||
404 | nv50_instmem_flush(struct drm_device *dev) | 404 | nv50_instmem_flush(struct drm_device *dev) |
405 | { | 405 | { |
406 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 406 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
407 | unsigned long flags; | ||
407 | 408 | ||
408 | spin_lock(&dev_priv->ramin_lock); | 409 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
409 | nv_wr32(dev, 0x00330c, 0x00000001); | 410 | nv_wr32(dev, 0x00330c, 0x00000001); |
410 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) | 411 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) |
411 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 412 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
412 | spin_unlock(&dev_priv->ramin_lock); | 413 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
413 | } | 414 | } |
414 | 415 | ||
415 | void | 416 | void |
416 | nv84_instmem_flush(struct drm_device *dev) | 417 | nv84_instmem_flush(struct drm_device *dev) |
417 | { | 418 | { |
418 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 419 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
420 | unsigned long flags; | ||
419 | 421 | ||
420 | spin_lock(&dev_priv->ramin_lock); | 422 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
421 | nv_wr32(dev, 0x070000, 0x00000001); | 423 | nv_wr32(dev, 0x070000, 0x00000001); |
422 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) | 424 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) |
423 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 425 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
424 | spin_unlock(&dev_priv->ramin_lock); | 426 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
425 | } | 427 | } |
426 | 428 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 4fd3432b5b8d..6c2694490741 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c | |||
@@ -174,10 +174,11 @@ void | |||
174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) | 174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) |
175 | { | 175 | { |
176 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 176 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
177 | unsigned long flags; | ||
177 | 178 | ||
178 | spin_lock(&dev_priv->ramin_lock); | 179 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
179 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); | 180 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); |
180 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) | 181 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) |
181 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); | 182 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); |
182 | spin_unlock(&dev_priv->ramin_lock); | 183 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
183 | } | 184 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c index a0a2a0277f73..a179e6c55afb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vm.c +++ b/drivers/gpu/drm/nouveau/nvc0_vm.c | |||
@@ -104,11 +104,12 @@ nvc0_vm_flush(struct nouveau_vm *vm) | |||
104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; | 104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; |
105 | struct drm_device *dev = vm->dev; | 105 | struct drm_device *dev = vm->dev; |
106 | struct nouveau_vm_pgd *vpgd; | 106 | struct nouveau_vm_pgd *vpgd; |
107 | unsigned long flags; | ||
107 | u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; | 108 | u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; |
108 | 109 | ||
109 | pinstmem->flush(vm->dev); | 110 | pinstmem->flush(vm->dev); |
110 | 111 | ||
111 | spin_lock(&dev_priv->ramin_lock); | 112 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
112 | list_for_each_entry(vpgd, &vm->pgd_list, head) { | 113 | list_for_each_entry(vpgd, &vm->pgd_list, head) { |
113 | /* looks like maybe a "free flush slots" counter, the | 114 | /* looks like maybe a "free flush slots" counter, the |
114 | * faster you write to 0x100cbc to more it decreases | 115 | * faster you write to 0x100cbc to more it decreases |
@@ -125,5 +126,5 @@ nvc0_vm_flush(struct nouveau_vm *vm) | |||
125 | nv_rd32(dev, 0x100c80), engine); | 126 | nv_rd32(dev, 0x100c80), engine); |
126 | } | 127 | } |
127 | } | 128 | } |
128 | spin_unlock(&dev_priv->ramin_lock); | 129 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
129 | } | 130 | } |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d71d375149f8..7bd745689097 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -135,7 +135,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
135 | case ATOM_IIO_MOVE_INDEX: | 135 | case ATOM_IIO_MOVE_INDEX: |
136 | temp &= | 136 | temp &= |
137 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << | 137 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
138 | CU8(base + 2)); | 138 | CU8(base + 3)); |
139 | temp |= | 139 | temp |= |
140 | ((index >> CU8(base + 2)) & | 140 | ((index >> CU8(base + 2)) & |
141 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + | 141 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + |
@@ -145,7 +145,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
145 | case ATOM_IIO_MOVE_DATA: | 145 | case ATOM_IIO_MOVE_DATA: |
146 | temp &= | 146 | temp &= |
147 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << | 147 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
148 | CU8(base + 2)); | 148 | CU8(base + 3)); |
149 | temp |= | 149 | temp |= |
150 | ((data >> CU8(base + 2)) & | 150 | ((data >> CU8(base + 2)) & |
151 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + | 151 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + |
@@ -155,7 +155,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
155 | case ATOM_IIO_MOVE_ATTR: | 155 | case ATOM_IIO_MOVE_ATTR: |
156 | temp &= | 156 | temp &= |
157 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << | 157 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
158 | CU8(base + 2)); | 158 | CU8(base + 3)); |
159 | temp |= | 159 | temp |= |
160 | ((ctx-> | 160 | ((ctx-> |
161 | io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - | 161 | io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9d516a8c4dfa..529a3a704731 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -532,10 +532,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
532 | else | 532 | else |
533 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 533 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
534 | 534 | ||
535 | if ((rdev->family == CHIP_R600) || | 535 | if (rdev->family < CHIP_RV770) |
536 | (rdev->family == CHIP_RV610) || | ||
537 | (rdev->family == CHIP_RV630) || | ||
538 | (rdev->family == CHIP_RV670)) | ||
539 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | 536 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
540 | } else { | 537 | } else { |
541 | pll->flags |= RADEON_PLL_LEGACY; | 538 | pll->flags |= RADEON_PLL_LEGACY; |
@@ -565,7 +562,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
565 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 562 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
566 | if (ss_enabled) { | 563 | if (ss_enabled) { |
567 | if (ss->refdiv) { | 564 | if (ss->refdiv) { |
568 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | ||
569 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 565 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
570 | pll->reference_div = ss->refdiv; | 566 | pll->reference_div = ss->refdiv; |
571 | if (ASIC_IS_AVIVO(rdev)) | 567 | if (ASIC_IS_AVIVO(rdev)) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 3453910ee0f3..c20eac3379e6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -353,7 +353,7 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, | |||
353 | struct drm_display_mode *mode, | 353 | struct drm_display_mode *mode, |
354 | struct drm_display_mode *other_mode) | 354 | struct drm_display_mode *other_mode) |
355 | { | 355 | { |
356 | u32 tmp = 0; | 356 | u32 tmp; |
357 | /* | 357 | /* |
358 | * Line Buffer Setup | 358 | * Line Buffer Setup |
359 | * There are 3 line buffers, each one shared by 2 display controllers. | 359 | * There are 3 line buffers, each one shared by 2 display controllers. |
@@ -363,64 +363,63 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, | |||
363 | * first display controller | 363 | * first display controller |
364 | * 0 - first half of lb (3840 * 2) | 364 | * 0 - first half of lb (3840 * 2) |
365 | * 1 - first 3/4 of lb (5760 * 2) | 365 | * 1 - first 3/4 of lb (5760 * 2) |
366 | * 2 - whole lb (7680 * 2) | 366 | * 2 - whole lb (7680 * 2), other crtc must be disabled |
367 | * 3 - first 1/4 of lb (1920 * 2) | 367 | * 3 - first 1/4 of lb (1920 * 2) |
368 | * second display controller | 368 | * second display controller |
369 | * 4 - second half of lb (3840 * 2) | 369 | * 4 - second half of lb (3840 * 2) |
370 | * 5 - second 3/4 of lb (5760 * 2) | 370 | * 5 - second 3/4 of lb (5760 * 2) |
371 | * 6 - whole lb (7680 * 2) | 371 | * 6 - whole lb (7680 * 2), other crtc must be disabled |
372 | * 7 - last 1/4 of lb (1920 * 2) | 372 | * 7 - last 1/4 of lb (1920 * 2) |
373 | */ | 373 | */ |
374 | if (mode && other_mode) { | 374 | /* this can get tricky if we have two large displays on a paired group |
375 | if (mode->hdisplay > other_mode->hdisplay) { | 375 | * of crtcs. Ideally for multiple large displays we'd assign them to |
376 | if (mode->hdisplay > 2560) | 376 | * non-linked crtcs for maximum line buffer allocation. |
377 | tmp = 1; /* 3/4 */ | 377 | */ |
378 | else | 378 | if (radeon_crtc->base.enabled && mode) { |
379 | tmp = 0; /* 1/2 */ | 379 | if (other_mode) |
380 | } else if (other_mode->hdisplay > mode->hdisplay) { | ||
381 | if (other_mode->hdisplay > 2560) | ||
382 | tmp = 3; /* 1/4 */ | ||
383 | else | ||
384 | tmp = 0; /* 1/2 */ | ||
385 | } else | ||
386 | tmp = 0; /* 1/2 */ | 380 | tmp = 0; /* 1/2 */ |
387 | } else if (mode) | 381 | else |
388 | tmp = 2; /* whole */ | 382 | tmp = 2; /* whole */ |
389 | else if (other_mode) | 383 | } else |
390 | tmp = 3; /* 1/4 */ | 384 | tmp = 0; |
391 | 385 | ||
392 | /* second controller of the pair uses second half of the lb */ | 386 | /* second controller of the pair uses second half of the lb */ |
393 | if (radeon_crtc->crtc_id % 2) | 387 | if (radeon_crtc->crtc_id % 2) |
394 | tmp += 4; | 388 | tmp += 4; |
395 | WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); | 389 | WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); |
396 | 390 | ||
397 | switch (tmp) { | 391 | if (radeon_crtc->base.enabled && mode) { |
398 | case 0: | 392 | switch (tmp) { |
399 | case 4: | 393 | case 0: |
400 | default: | 394 | case 4: |
401 | if (ASIC_IS_DCE5(rdev)) | 395 | default: |
402 | return 4096 * 2; | 396 | if (ASIC_IS_DCE5(rdev)) |
403 | else | 397 | return 4096 * 2; |
404 | return 3840 * 2; | 398 | else |
405 | case 1: | 399 | return 3840 * 2; |
406 | case 5: | 400 | case 1: |
407 | if (ASIC_IS_DCE5(rdev)) | 401 | case 5: |
408 | return 6144 * 2; | 402 | if (ASIC_IS_DCE5(rdev)) |
409 | else | 403 | return 6144 * 2; |
410 | return 5760 * 2; | 404 | else |
411 | case 2: | 405 | return 5760 * 2; |
412 | case 6: | 406 | case 2: |
413 | if (ASIC_IS_DCE5(rdev)) | 407 | case 6: |
414 | return 8192 * 2; | 408 | if (ASIC_IS_DCE5(rdev)) |
415 | else | 409 | return 8192 * 2; |
416 | return 7680 * 2; | 410 | else |
417 | case 3: | 411 | return 7680 * 2; |
418 | case 7: | 412 | case 3: |
419 | if (ASIC_IS_DCE5(rdev)) | 413 | case 7: |
420 | return 2048 * 2; | 414 | if (ASIC_IS_DCE5(rdev)) |
421 | else | 415 | return 2048 * 2; |
422 | return 1920 * 2; | 416 | else |
417 | return 1920 * 2; | ||
418 | } | ||
423 | } | 419 | } |
420 | |||
421 | /* controller not enabled, so no lb used */ | ||
422 | return 0; | ||
424 | } | 423 | } |
425 | 424 | ||
426 | static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) | 425 | static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) |
@@ -863,9 +862,15 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
863 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | 862 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | |
864 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | | 863 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | |
865 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | 864 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); |
866 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | 865 | if (rdev->flags & RADEON_IS_IGP) { |
867 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | 866 | WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); |
868 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | 867 | WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); |
868 | WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
869 | } else { | ||
870 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
871 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
872 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
873 | } | ||
869 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | 874 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); |
870 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 875 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
871 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 876 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
@@ -2581,7 +2586,7 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
2581 | u32 wptr, tmp; | 2586 | u32 wptr, tmp; |
2582 | 2587 | ||
2583 | if (rdev->wb.enabled) | 2588 | if (rdev->wb.enabled) |
2584 | wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; | 2589 | wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
2585 | else | 2590 | else |
2586 | wptr = RREG32(IH_RB_WPTR); | 2591 | wptr = RREG32(IH_RB_WPTR); |
2587 | 2592 | ||
@@ -2924,11 +2929,6 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
2924 | rdev->asic->copy = NULL; | 2929 | rdev->asic->copy = NULL; |
2925 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | 2930 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
2926 | } | 2931 | } |
2927 | /* XXX: ontario has problems blitting to gart at the moment */ | ||
2928 | if (rdev->family == CHIP_PALM) { | ||
2929 | rdev->asic->copy = NULL; | ||
2930 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | ||
2931 | } | ||
2932 | 2932 | ||
2933 | /* allocate wb buffer */ | 2933 | /* allocate wb buffer */ |
2934 | r = radeon_wb_init(rdev); | 2934 | r = radeon_wb_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 9aaa3f0c9372..94533849927e 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -221,6 +221,11 @@ | |||
221 | #define MC_VM_MD_L1_TLB0_CNTL 0x2654 | 221 | #define MC_VM_MD_L1_TLB0_CNTL 0x2654 |
222 | #define MC_VM_MD_L1_TLB1_CNTL 0x2658 | 222 | #define MC_VM_MD_L1_TLB1_CNTL 0x2658 |
223 | #define MC_VM_MD_L1_TLB2_CNTL 0x265C | 223 | #define MC_VM_MD_L1_TLB2_CNTL 0x265C |
224 | |||
225 | #define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C | ||
226 | #define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 | ||
227 | #define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 | ||
228 | |||
224 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C | 229 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C |
225 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 | 230 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 |
226 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 | 231 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 15d58292677a..6f27593901c7 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3231,7 +3231,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3231 | u32 wptr, tmp; | 3231 | u32 wptr, tmp; |
3232 | 3232 | ||
3233 | if (rdev->wb.enabled) | 3233 | if (rdev->wb.enabled) |
3234 | wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; | 3234 | wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
3235 | else | 3235 | else |
3236 | wptr = RREG32(IH_RB_WPTR); | 3236 | wptr = RREG32(IH_RB_WPTR); |
3237 | 3237 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index f5d12fb103fa..dd881d035f09 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -431,7 +431,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
434 | /* Acer laptop (Acer TravelMate 5730G) has an HDMI port | 434 | /* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port |
435 | * on the laptop and a DVI port on the docking station and | 435 | * on the laptop and a DVI port on the docking station and |
436 | * both share the same encoder, hpd pin, and ddc line. | 436 | * both share the same encoder, hpd pin, and ddc line. |
437 | * So while the bios table is technically correct, | 437 | * So while the bios table is technically correct, |
@@ -440,7 +440,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
440 | * with different crtcs which isn't possible on the hardware | 440 | * with different crtcs which isn't possible on the hardware |
441 | * side and leaves no crtcs for LVDS or VGA. | 441 | * side and leaves no crtcs for LVDS or VGA. |
442 | */ | 442 | */ |
443 | if ((dev->pdev->device == 0x95c4) && | 443 | if (((dev->pdev->device == 0x95c4) || (dev->pdev->device == 0x9591)) && |
444 | (dev->pdev->subsystem_vendor == 0x1025) && | 444 | (dev->pdev->subsystem_vendor == 0x1025) && |
445 | (dev->pdev->subsystem_device == 0x013c)) { | 445 | (dev->pdev->subsystem_device == 0x013c)) { |
446 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && | 446 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && |
@@ -1599,9 +1599,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1599 | memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], | 1599 | memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], |
1600 | fake_edid_record->ucFakeEDIDLength); | 1600 | fake_edid_record->ucFakeEDIDLength); |
1601 | 1601 | ||
1602 | if (drm_edid_is_valid(edid)) | 1602 | if (drm_edid_is_valid(edid)) { |
1603 | rdev->mode_info.bios_hardcoded_edid = edid; | 1603 | rdev->mode_info.bios_hardcoded_edid = edid; |
1604 | else | 1604 | rdev->mode_info.bios_hardcoded_edid_size = edid_size; |
1605 | } else | ||
1605 | kfree(edid); | 1606 | kfree(edid); |
1606 | } | 1607 | } |
1607 | } | 1608 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index ed5dfe58f29c..9d95792bea3e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #define ATPX_VERSION 0 | 15 | #define ATPX_VERSION 0 |
16 | #define ATPX_GPU_PWR 2 | 16 | #define ATPX_GPU_PWR 2 |
17 | #define ATPX_MUX_SELECT 3 | 17 | #define ATPX_MUX_SELECT 3 |
18 | #define ATPX_I2C_MUX_SELECT 4 | ||
19 | #define ATPX_SWITCH_START 5 | ||
20 | #define ATPX_SWITCH_END 6 | ||
18 | 21 | ||
19 | #define ATPX_INTEGRATED 0 | 22 | #define ATPX_INTEGRATED 0 |
20 | #define ATPX_DISCRETE 1 | 23 | #define ATPX_DISCRETE 1 |
@@ -149,13 +152,35 @@ static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) | |||
149 | return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); | 152 | return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); |
150 | } | 153 | } |
151 | 154 | ||
155 | static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) | ||
156 | { | ||
157 | return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); | ||
158 | } | ||
159 | |||
160 | static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) | ||
161 | { | ||
162 | return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); | ||
163 | } | ||
164 | |||
165 | static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) | ||
166 | { | ||
167 | return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); | ||
168 | } | ||
152 | 169 | ||
153 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) | 170 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) |
154 | { | 171 | { |
172 | int gpu_id; | ||
173 | |||
155 | if (id == VGA_SWITCHEROO_IGD) | 174 | if (id == VGA_SWITCHEROO_IGD) |
156 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0); | 175 | gpu_id = ATPX_INTEGRATED; |
157 | else | 176 | else |
158 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1); | 177 | gpu_id = ATPX_DISCRETE; |
178 | |||
179 | radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); | ||
180 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); | ||
181 | radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); | ||
182 | radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); | ||
183 | |||
159 | return 0; | 184 | return 0; |
160 | } | 185 | } |
161 | 186 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2ef6d5135064..5f45fa12bb8b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1199,7 +1199,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1199 | if (router->ddc_valid || router->cd_valid) { | 1199 | if (router->ddc_valid || router->cd_valid) { |
1200 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); | 1200 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
1201 | if (!radeon_connector->router_bus) | 1201 | if (!radeon_connector->router_bus) |
1202 | goto failed; | 1202 | DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n"); |
1203 | } | 1203 | } |
1204 | switch (connector_type) { | 1204 | switch (connector_type) { |
1205 | case DRM_MODE_CONNECTOR_VGA: | 1205 | case DRM_MODE_CONNECTOR_VGA: |
@@ -1208,7 +1208,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1208 | if (i2c_bus->valid) { | 1208 | if (i2c_bus->valid) { |
1209 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1209 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1210 | if (!radeon_connector->ddc_bus) | 1210 | if (!radeon_connector->ddc_bus) |
1211 | goto failed; | 1211 | DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1212 | } | 1212 | } |
1213 | radeon_connector->dac_load_detect = true; | 1213 | radeon_connector->dac_load_detect = true; |
1214 | drm_connector_attach_property(&radeon_connector->base, | 1214 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1226,7 +1226,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1226 | if (i2c_bus->valid) { | 1226 | if (i2c_bus->valid) { |
1227 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1227 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1228 | if (!radeon_connector->ddc_bus) | 1228 | if (!radeon_connector->ddc_bus) |
1229 | goto failed; | 1229 | DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1230 | } | 1230 | } |
1231 | radeon_connector->dac_load_detect = true; | 1231 | radeon_connector->dac_load_detect = true; |
1232 | drm_connector_attach_property(&radeon_connector->base, | 1232 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1249,7 +1249,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1249 | if (i2c_bus->valid) { | 1249 | if (i2c_bus->valid) { |
1250 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1250 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1251 | if (!radeon_connector->ddc_bus) | 1251 | if (!radeon_connector->ddc_bus) |
1252 | goto failed; | 1252 | DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1253 | } | 1253 | } |
1254 | subpixel_order = SubPixelHorizontalRGB; | 1254 | subpixel_order = SubPixelHorizontalRGB; |
1255 | drm_connector_attach_property(&radeon_connector->base, | 1255 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1290,7 +1290,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1290 | if (i2c_bus->valid) { | 1290 | if (i2c_bus->valid) { |
1291 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1291 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1292 | if (!radeon_connector->ddc_bus) | 1292 | if (!radeon_connector->ddc_bus) |
1293 | goto failed; | 1293 | DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1294 | } | 1294 | } |
1295 | drm_connector_attach_property(&radeon_connector->base, | 1295 | drm_connector_attach_property(&radeon_connector->base, |
1296 | rdev->mode_info.coherent_mode_property, | 1296 | rdev->mode_info.coherent_mode_property, |
@@ -1329,10 +1329,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1329 | else | 1329 | else |
1330 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | 1330 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); |
1331 | if (!radeon_dig_connector->dp_i2c_bus) | 1331 | if (!radeon_dig_connector->dp_i2c_bus) |
1332 | goto failed; | 1332 | DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); |
1333 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1333 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1334 | if (!radeon_connector->ddc_bus) | 1334 | if (!radeon_connector->ddc_bus) |
1335 | goto failed; | 1335 | DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1336 | } | 1336 | } |
1337 | subpixel_order = SubPixelHorizontalRGB; | 1337 | subpixel_order = SubPixelHorizontalRGB; |
1338 | drm_connector_attach_property(&radeon_connector->base, | 1338 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1381,7 +1381,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1381 | if (i2c_bus->valid) { | 1381 | if (i2c_bus->valid) { |
1382 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1382 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1383 | if (!radeon_connector->ddc_bus) | 1383 | if (!radeon_connector->ddc_bus) |
1384 | goto failed; | 1384 | DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1385 | } | 1385 | } |
1386 | drm_connector_attach_property(&radeon_connector->base, | 1386 | drm_connector_attach_property(&radeon_connector->base, |
1387 | dev->mode_config.scaling_mode_property, | 1387 | dev->mode_config.scaling_mode_property, |
@@ -1457,7 +1457,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1457 | if (i2c_bus->valid) { | 1457 | if (i2c_bus->valid) { |
1458 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1458 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1459 | if (!radeon_connector->ddc_bus) | 1459 | if (!radeon_connector->ddc_bus) |
1460 | goto failed; | 1460 | DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1461 | } | 1461 | } |
1462 | radeon_connector->dac_load_detect = true; | 1462 | radeon_connector->dac_load_detect = true; |
1463 | drm_connector_attach_property(&radeon_connector->base, | 1463 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1475,7 +1475,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1475 | if (i2c_bus->valid) { | 1475 | if (i2c_bus->valid) { |
1476 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1476 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1477 | if (!radeon_connector->ddc_bus) | 1477 | if (!radeon_connector->ddc_bus) |
1478 | goto failed; | 1478 | DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1479 | } | 1479 | } |
1480 | radeon_connector->dac_load_detect = true; | 1480 | radeon_connector->dac_load_detect = true; |
1481 | drm_connector_attach_property(&radeon_connector->base, | 1481 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1493,7 +1493,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1493 | if (i2c_bus->valid) { | 1493 | if (i2c_bus->valid) { |
1494 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1494 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1495 | if (!radeon_connector->ddc_bus) | 1495 | if (!radeon_connector->ddc_bus) |
1496 | goto failed; | 1496 | DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1497 | } | 1497 | } |
1498 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | 1498 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
1499 | radeon_connector->dac_load_detect = true; | 1499 | radeon_connector->dac_load_detect = true; |
@@ -1538,7 +1538,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1538 | if (i2c_bus->valid) { | 1538 | if (i2c_bus->valid) { |
1539 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1539 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1540 | if (!radeon_connector->ddc_bus) | 1540 | if (!radeon_connector->ddc_bus) |
1541 | goto failed; | 1541 | DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1542 | } | 1542 | } |
1543 | drm_connector_attach_property(&radeon_connector->base, | 1543 | drm_connector_attach_property(&radeon_connector->base, |
1544 | dev->mode_config.scaling_mode_property, | 1544 | dev->mode_config.scaling_mode_property, |
@@ -1567,9 +1567,4 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1567 | radeon_legacy_backlight_init(radeon_encoder, connector); | 1567 | radeon_legacy_backlight_init(radeon_encoder, connector); |
1568 | } | 1568 | } |
1569 | } | 1569 | } |
1570 | return; | ||
1571 | |||
1572 | failed: | ||
1573 | drm_connector_cleanup(connector); | ||
1574 | kfree(connector); | ||
1575 | } | 1570 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index bdf2fa1189ae..3189a7efb2e9 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -167,9 +167,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, | |||
167 | return -EINVAL; | 167 | return -EINVAL; |
168 | } | 168 | } |
169 | 169 | ||
170 | radeon_crtc->cursor_width = width; | ||
171 | radeon_crtc->cursor_height = height; | ||
172 | |||
173 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); | 170 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); |
174 | if (!obj) { | 171 | if (!obj) { |
175 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); | 172 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); |
@@ -180,6 +177,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, | |||
180 | if (ret) | 177 | if (ret) |
181 | goto fail; | 178 | goto fail; |
182 | 179 | ||
180 | radeon_crtc->cursor_width = width; | ||
181 | radeon_crtc->cursor_height = height; | ||
182 | |||
183 | radeon_lock_cursor(crtc, true); | 183 | radeon_lock_cursor(crtc, true); |
184 | /* XXX only 27 bit offset for legacy cursor */ | 184 | /* XXX only 27 bit offset for legacy cursor */ |
185 | radeon_set_cursor(crtc, obj, gpu_addr); | 185 | radeon_set_cursor(crtc, obj, gpu_addr); |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index ccbabf734a61..983cbac75af0 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -1096,6 +1096,9 @@ void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) | |||
1096 | if (!radeon_connector->router.ddc_valid) | 1096 | if (!radeon_connector->router.ddc_valid) |
1097 | return; | 1097 | return; |
1098 | 1098 | ||
1099 | if (!radeon_connector->router_bus) | ||
1100 | return; | ||
1101 | |||
1099 | radeon_i2c_get_byte(radeon_connector->router_bus, | 1102 | radeon_i2c_get_byte(radeon_connector->router_bus, |
1100 | radeon_connector->router.i2c_addr, | 1103 | radeon_connector->router.i2c_addr, |
1101 | 0x3, &val); | 1104 | 0x3, &val); |
@@ -1121,6 +1124,9 @@ void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) | |||
1121 | if (!radeon_connector->router.cd_valid) | 1124 | if (!radeon_connector->router.cd_valid) |
1122 | return; | 1125 | return; |
1123 | 1126 | ||
1127 | if (!radeon_connector->router_bus) | ||
1128 | return; | ||
1129 | |||
1124 | radeon_i2c_get_byte(radeon_connector->router_bus, | 1130 | radeon_i2c_get_byte(radeon_connector->router_bus, |
1125 | radeon_connector->router.i2c_addr, | 1131 | radeon_connector->router.i2c_addr, |
1126 | 0x3, &val); | 1132 | 0x3, &val); |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index bf7d4c061451..bd58af658581 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -221,6 +221,22 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
221 | return -EINVAL; | 221 | return -EINVAL; |
222 | } | 222 | } |
223 | break; | 223 | break; |
224 | case RADEON_INFO_NUM_TILE_PIPES: | ||
225 | if (rdev->family >= CHIP_CAYMAN) | ||
226 | value = rdev->config.cayman.max_tile_pipes; | ||
227 | else if (rdev->family >= CHIP_CEDAR) | ||
228 | value = rdev->config.evergreen.max_tile_pipes; | ||
229 | else if (rdev->family >= CHIP_RV770) | ||
230 | value = rdev->config.rv770.max_tile_pipes; | ||
231 | else if (rdev->family >= CHIP_R600) | ||
232 | value = rdev->config.r600.max_tile_pipes; | ||
233 | else { | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | break; | ||
237 | case RADEON_INFO_FUSION_GART_WORKING: | ||
238 | value = 1; | ||
239 | break; | ||
224 | default: | 240 | default: |
225 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); | 241 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
226 | return -EINVAL; | 242 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index af0da4ae3f55..92f1900dc7ca 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -708,6 +708,7 @@ r600 0x9400 | |||
708 | 0x00028D0C DB_RENDER_CONTROL | 708 | 0x00028D0C DB_RENDER_CONTROL |
709 | 0x00028D10 DB_RENDER_OVERRIDE | 709 | 0x00028D10 DB_RENDER_OVERRIDE |
710 | 0x0002880C DB_SHADER_CONTROL | 710 | 0x0002880C DB_SHADER_CONTROL |
711 | 0x00028D28 DB_SRESULTS_COMPARE_STATE0 | ||
711 | 0x00028D2C DB_SRESULTS_COMPARE_STATE1 | 712 | 0x00028D2C DB_SRESULTS_COMPARE_STATE1 |
712 | 0x00028430 DB_STENCILREFMASK | 713 | 0x00028430 DB_STENCILREFMASK |
713 | 0x00028434 DB_STENCILREFMASK_BF | 714 | 0x00028434 DB_STENCILREFMASK_BF |