diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-13 10:41:01 -0400 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-13 10:41:01 -0400 |
| commit | 78890b5989d96ddce989cde929c45ceeded0fcaf (patch) | |
| tree | 4e2da81fc7c97f11aee174b1eedac110c9a68b3a /drivers/gpu | |
| parent | 1959ec5f82acbdf91425b41600f119ebecb5f6a8 (diff) | |
| parent | 55d512e245bc7699a8800e23df1a24195dd08217 (diff) | |
Merge commit 'v3.6-rc5' into next
* commit 'v3.6-rc5': (1098 commits)
Linux 3.6-rc5
HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured
Remove user-triggerable BUG from mpol_to_str
xen/pciback: Fix proper FLR steps.
uml: fix compile error in deliver_alarm()
dj: memory scribble in logi_dj
Fix order of arguments to compat_put_time[spec|val]
xen: Use correct masking in xen_swiotlb_alloc_coherent.
xen: fix logical error in tlb flushing
xen/p2m: Fix one-off error in checking the P2M tree directory.
powerpc: Don't use __put_user() in patch_instruction
powerpc: Make sure IPI handlers see data written by IPI senders
powerpc: Restore correct DSCR in context switch
powerpc: Fix DSCR inheritance in copy_thread()
powerpc: Keep thread.dscr and thread.dscr_inherit in sync
powerpc: Update DSCR on all CPUs when writing sysfs dscr_default
powerpc/powernv: Always go into nap mode when CPU is offline
powerpc: Give hypervisor decrementer interrupts their own handler
powerpc/vphn: Fix arch_update_cpu_topology() return value
ARM: gemini: fix the gemini build
...
Conflicts:
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/rapidio/devices/tsi721.c
Diffstat (limited to 'drivers/gpu')
70 files changed, 1055 insertions, 574 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 23120c00a881..90e28081712d 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
| @@ -22,6 +22,7 @@ menuconfig DRM | |||
| 22 | config DRM_USB | 22 | config DRM_USB |
| 23 | tristate | 23 | tristate |
| 24 | depends on DRM | 24 | depends on DRM |
| 25 | depends on USB_ARCH_HAS_HCD | ||
| 25 | select USB | 26 | select USB |
| 26 | 27 | ||
| 27 | config DRM_KMS_HELPER | 28 | config DRM_KMS_HELPER |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 08a7aa722d6b..6fbfc244748f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, | |||
| 1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
| 1982 | return -EINVAL; | 1982 | return -EINVAL; |
| 1983 | 1983 | ||
| 1984 | if (!req->flags) | 1984 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
| 1985 | return -EINVAL; | 1985 | return -EINVAL; |
| 1986 | 1986 | ||
| 1987 | mutex_lock(&dev->mode_config.mutex); | 1987 | mutex_lock(&dev->mode_config.mutex); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a8743c399e83..b7ee230572b7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -87,6 +87,9 @@ static struct edid_quirk { | |||
| 87 | int product_id; | 87 | int product_id; |
| 88 | u32 quirks; | 88 | u32 quirks; |
| 89 | } edid_quirk_list[] = { | 89 | } edid_quirk_list[] = { |
| 90 | /* ASUS VW222S */ | ||
| 91 | { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, | ||
| 92 | |||
| 90 | /* Acer AL1706 */ | 93 | /* Acer AL1706 */ |
| 91 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, | 94 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, |
| 92 | /* Acer F51 */ | 95 | /* Acer F51 */ |
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 66d4a28ad5a2..0303935d10e2 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c | |||
| @@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
| 119 | { | 119 | { |
| 120 | const struct firmware *fw; | 120 | const struct firmware *fw; |
| 121 | struct platform_device *pdev; | 121 | struct platform_device *pdev; |
| 122 | u8 *fwdata = NULL, *edid; | 122 | u8 *fwdata = NULL, *edid, *new_edid; |
| 123 | int fwsize, expected; | 123 | int fwsize, expected; |
| 124 | int builtin = 0, err = 0; | 124 | int builtin = 0, err = 0; |
| 125 | int i, valid_extensions = 0; | 125 | int i, valid_extensions = 0; |
| @@ -195,12 +195,14 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
| 195 | "\"%s\" for connector \"%s\"\n", valid_extensions, | 195 | "\"%s\" for connector \"%s\"\n", valid_extensions, |
| 196 | edid[0x7e], name, connector_name); | 196 | edid[0x7e], name, connector_name); |
| 197 | edid[0x7e] = valid_extensions; | 197 | edid[0x7e] = valid_extensions; |
| 198 | edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, | 198 | new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, |
| 199 | GFP_KERNEL); | 199 | GFP_KERNEL); |
| 200 | if (edid == NULL) { | 200 | if (new_edid == NULL) { |
| 201 | err = -ENOMEM; | 201 | err = -ENOMEM; |
| 202 | kfree(edid); | ||
| 202 | goto relfw_out; | 203 | goto relfw_out; |
| 203 | } | 204 | } |
| 205 | edid = new_edid; | ||
| 204 | } | 206 | } |
| 205 | 207 | ||
| 206 | connector->display_info.raw_edid = edid; | 208 | connector->display_info.raw_edid = edid; |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b7adb4a967fd..28637c181b15 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
| @@ -706,9 +706,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) | |||
| 706 | p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); | 706 | p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); |
| 707 | p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); | 707 | p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); |
| 708 | p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); | 708 | p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); |
| 709 | |||
| 710 | p->crtc_hadjusted = false; | ||
| 711 | p->crtc_vadjusted = false; | ||
| 712 | } | 709 | } |
| 713 | EXPORT_SYMBOL(drm_mode_set_crtcinfo); | 710 | EXPORT_SYMBOL(drm_mode_set_crtcinfo); |
| 714 | 711 | ||
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index 371c695322d9..da457b18eaaf 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
| @@ -89,7 +89,7 @@ static const struct file_operations drm_proc_fops = { | |||
| 89 | * Create a given set of proc files represented by an array of | 89 | * Create a given set of proc files represented by an array of |
| 90 | * gdm_proc_lists in the given root directory. | 90 | * gdm_proc_lists in the given root directory. |
| 91 | */ | 91 | */ |
| 92 | int drm_proc_create_files(struct drm_info_list *files, int count, | 92 | static int drm_proc_create_files(struct drm_info_list *files, int count, |
| 93 | struct proc_dir_entry *root, struct drm_minor *minor) | 93 | struct proc_dir_entry *root, struct drm_minor *minor) |
| 94 | { | 94 | { |
| 95 | struct drm_device *dev = minor->dev; | 95 | struct drm_device *dev = minor->dev; |
| @@ -172,7 +172,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
| 172 | return 0; | 172 | return 0; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | int drm_proc_remove_files(struct drm_info_list *files, int count, | 175 | static int drm_proc_remove_files(struct drm_info_list *files, int count, |
| 176 | struct drm_minor *minor) | 176 | struct drm_minor *minor) |
| 177 | { | 177 | { |
| 178 | struct list_head *pos, *q; | 178 | struct list_head *pos, *q; |
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 30dc22a7156c..8033526bb53b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c | |||
| @@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, | |||
| 1362 | (struct drm_connector **) (psb_intel_crtc + 1); | 1362 | (struct drm_connector **) (psb_intel_crtc + 1); |
| 1363 | psb_intel_crtc->mode_set.num_connectors = 0; | 1363 | psb_intel_crtc->mode_set.num_connectors = 0; |
| 1364 | psb_intel_cursor_init(dev, psb_intel_crtc); | 1364 | psb_intel_cursor_init(dev, psb_intel_crtc); |
| 1365 | |||
| 1366 | /* Set to true so that the pipe is forced off on initial config. */ | ||
| 1367 | psb_intel_crtc->active = true; | ||
| 1365 | } | 1368 | } |
| 1366 | 1369 | ||
| 1367 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 1370 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ed22612bc847..a24ffbe97c01 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -346,11 +346,40 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
| 346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ | 346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ |
| 347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ | 347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ |
| 348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ | 348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ |
| 349 | INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ | ||
| 349 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ | 350 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ |
| 350 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ | 351 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ |
| 352 | INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ | ||
| 351 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ | 353 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ |
| 352 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ | 354 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ |
| 353 | INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ | 355 | INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ |
| 356 | INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ | ||
| 357 | INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
| 358 | INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
| 359 | INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ | ||
| 360 | INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
| 361 | INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
| 362 | INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ | ||
| 363 | INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
| 364 | INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
| 365 | INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ | ||
| 366 | INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
| 367 | INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
| 368 | INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ | ||
| 369 | INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
| 370 | INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
| 371 | INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ | ||
| 372 | INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
| 373 | INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
| 374 | INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ | ||
| 375 | INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
| 376 | INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
| 377 | INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ | ||
| 378 | INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
| 379 | INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
| 380 | INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ | ||
| 381 | INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
| 382 | INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
| 354 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), | 383 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), |
| 355 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), | 384 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), |
| 356 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), | 385 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5c4657a54f97..489e2b162b27 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -2365,6 +2365,10 @@ int i915_gpu_idle(struct drm_device *dev) | |||
| 2365 | 2365 | ||
| 2366 | /* Flush everything onto the inactive list. */ | 2366 | /* Flush everything onto the inactive list. */ |
| 2367 | for_each_ring(ring, dev_priv, i) { | 2367 | for_each_ring(ring, dev_priv, i) { |
| 2368 | ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); | ||
| 2369 | if (ret) | ||
| 2370 | return ret; | ||
| 2371 | |||
| 2368 | ret = i915_ring_idle(ring); | 2372 | ret = i915_ring_idle(ring); |
| 2369 | if (ret) | 2373 | if (ret) |
| 2370 | return ret; | 2374 | return ret; |
| @@ -2372,10 +2376,6 @@ int i915_gpu_idle(struct drm_device *dev) | |||
| 2372 | /* Is the device fubar? */ | 2376 | /* Is the device fubar? */ |
| 2373 | if (WARN_ON(!list_empty(&ring->gpu_write_list))) | 2377 | if (WARN_ON(!list_empty(&ring->gpu_write_list))) |
| 2374 | return -EBUSY; | 2378 | return -EBUSY; |
| 2375 | |||
| 2376 | ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); | ||
| 2377 | if (ret) | ||
| 2378 | return ret; | ||
| 2379 | } | 2379 | } |
| 2380 | 2380 | ||
| 2381 | return 0; | 2381 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index da8b01fb1bf8..a9d58d72bb4d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
| @@ -451,7 +451,6 @@ int i915_switch_context(struct intel_ring_buffer *ring, | |||
| 451 | struct drm_i915_file_private *file_priv = NULL; | 451 | struct drm_i915_file_private *file_priv = NULL; |
| 452 | struct i915_hw_context *to; | 452 | struct i915_hw_context *to; |
| 453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; | 453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; |
| 454 | int ret; | ||
| 455 | 454 | ||
| 456 | if (dev_priv->hw_contexts_disabled) | 455 | if (dev_priv->hw_contexts_disabled) |
| 457 | return 0; | 456 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 5af631e788c8..ff2819ea0813 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -291,6 +291,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
| 291 | target_i915_obj = to_intel_bo(target_obj); | 291 | target_i915_obj = to_intel_bo(target_obj); |
| 292 | target_offset = target_i915_obj->gtt_offset; | 292 | target_offset = target_i915_obj->gtt_offset; |
| 293 | 293 | ||
| 294 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
| 295 | * pipe_control writes because the gpu doesn't properly redirect them | ||
| 296 | * through the ppgtt for non_secure batchbuffers. */ | ||
| 297 | if (unlikely(IS_GEN6(dev) && | ||
| 298 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
| 299 | !target_i915_obj->has_global_gtt_mapping)) { | ||
| 300 | i915_gem_gtt_bind_object(target_i915_obj, | ||
| 301 | target_i915_obj->cache_level); | ||
| 302 | } | ||
| 303 | |||
| 294 | /* The target buffer should have appeared before us in the | 304 | /* The target buffer should have appeared before us in the |
| 295 | * exec_object list, so it should have a GTT space bound by now. | 305 | * exec_object list, so it should have a GTT space bound by now. |
| 296 | */ | 306 | */ |
| @@ -399,16 +409,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
| 399 | io_mapping_unmap_atomic(reloc_page); | 409 | io_mapping_unmap_atomic(reloc_page); |
| 400 | } | 410 | } |
| 401 | 411 | ||
| 402 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
| 403 | * pipe_control writes because the gpu doesn't properly redirect them | ||
| 404 | * through the ppgtt for non_secure batchbuffers. */ | ||
| 405 | if (unlikely(IS_GEN6(dev) && | ||
| 406 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
| 407 | !target_i915_obj->has_global_gtt_mapping)) { | ||
| 408 | i915_gem_gtt_bind_object(target_i915_obj, | ||
| 409 | target_i915_obj->cache_level); | ||
| 410 | } | ||
| 411 | |||
| 412 | /* and update the user's relocation entry */ | 412 | /* and update the user's relocation entry */ |
| 413 | reloc->presumed_offset = target_offset; | 413 | reloc->presumed_offset = target_offset; |
| 414 | 414 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9fd25a435536..60815b861ec2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
| 72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 | 72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 |
| 73 | * entries. For aliasing ppgtt support we just steal them at the end for | 73 | * entries. For aliasing ppgtt support we just steal them at the end for |
| 74 | * now. */ | 74 | * now. */ |
| 75 | first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; | 75 | first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES; |
| 76 | 76 | ||
| 77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); | 77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); |
| 78 | if (!ppgtt) | 78 | if (!ppgtt) |
| @@ -261,7 +261,10 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, | |||
| 261 | pte_flags |= GEN6_PTE_CACHE_LLC; | 261 | pte_flags |= GEN6_PTE_CACHE_LLC; |
| 262 | break; | 262 | break; |
| 263 | case I915_CACHE_NONE: | 263 | case I915_CACHE_NONE: |
| 264 | pte_flags |= GEN6_PTE_UNCACHED; | 264 | if (IS_HASWELL(dev)) |
| 265 | pte_flags |= HSW_PTE_UNCACHED; | ||
| 266 | else | ||
| 267 | pte_flags |= GEN6_PTE_UNCACHED; | ||
| 265 | break; | 268 | break; |
| 266 | default: | 269 | default: |
| 267 | BUG(); | 270 | BUG(); |
| @@ -361,7 +364,8 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | |||
| 361 | struct drm_device *dev = obj->base.dev; | 364 | struct drm_device *dev = obj->base.dev; |
| 362 | struct drm_i915_private *dev_priv = dev->dev_private; | 365 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 363 | 366 | ||
| 364 | if (dev_priv->mm.gtt->needs_dmar) | 367 | /* don't map imported dma buf objects */ |
| 368 | if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table) | ||
| 365 | return intel_gtt_map_memory(obj->pages, | 369 | return intel_gtt_map_memory(obj->pages, |
| 366 | obj->base.size >> PAGE_SHIFT, | 370 | obj->base.size >> PAGE_SHIFT, |
| 367 | &obj->sg_list, | 371 | &obj->sg_list, |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index acc99b21e0b6..28725ce5b82c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -115,6 +115,7 @@ | |||
| 115 | 115 | ||
| 116 | #define GEN6_PTE_VALID (1 << 0) | 116 | #define GEN6_PTE_VALID (1 << 0) |
| 117 | #define GEN6_PTE_UNCACHED (1 << 1) | 117 | #define GEN6_PTE_UNCACHED (1 << 1) |
| 118 | #define HSW_PTE_UNCACHED (0) | ||
| 118 | #define GEN6_PTE_CACHE_LLC (2 << 1) | 119 | #define GEN6_PTE_CACHE_LLC (2 << 1) |
| 119 | #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) | 120 | #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) |
| 120 | #define GEN6_PTE_CACHE_BITS (3 << 1) | 121 | #define GEN6_PTE_CACHE_BITS (3 << 1) |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 2f5388af8df9..7631807a2788 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include "intel_drv.h" | 32 | #include "intel_drv.h" |
| 33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
| 34 | 34 | ||
| 35 | #ifdef CONFIG_PM | ||
| 35 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | 36 | static u32 calc_residency(struct drm_device *dev, const u32 reg) |
| 36 | { | 37 | { |
| 37 | struct drm_i915_private *dev_priv = dev->dev_private; | 38 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -224,3 +225,14 @@ void i915_teardown_sysfs(struct drm_device *dev) | |||
| 224 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); | 225 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); |
| 225 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 226 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); |
| 226 | } | 227 | } |
| 228 | #else | ||
| 229 | void i915_setup_sysfs(struct drm_device *dev) | ||
| 230 | { | ||
| 231 | return; | ||
| 232 | } | ||
| 233 | |||
| 234 | void i915_teardown_sysfs(struct drm_device *dev) | ||
| 235 | { | ||
| 236 | return; | ||
| 237 | } | ||
| 238 | #endif /* CONFIG_PM */ | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 7ed4a41c3965..23bdc8cd1458 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -326,6 +326,36 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
| 326 | return ret; | 326 | return ret; |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | static struct edid *intel_crt_get_edid(struct drm_connector *connector, | ||
| 330 | struct i2c_adapter *i2c) | ||
| 331 | { | ||
| 332 | struct edid *edid; | ||
| 333 | |||
| 334 | edid = drm_get_edid(connector, i2c); | ||
| 335 | |||
| 336 | if (!edid && !intel_gmbus_is_forced_bit(i2c)) { | ||
| 337 | DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n"); | ||
| 338 | intel_gmbus_force_bit(i2c, true); | ||
| 339 | edid = drm_get_edid(connector, i2c); | ||
| 340 | intel_gmbus_force_bit(i2c, false); | ||
| 341 | } | ||
| 342 | |||
| 343 | return edid; | ||
| 344 | } | ||
| 345 | |||
| 346 | /* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ | ||
| 347 | static int intel_crt_ddc_get_modes(struct drm_connector *connector, | ||
| 348 | struct i2c_adapter *adapter) | ||
| 349 | { | ||
| 350 | struct edid *edid; | ||
| 351 | |||
| 352 | edid = intel_crt_get_edid(connector, adapter); | ||
| 353 | if (!edid) | ||
| 354 | return 0; | ||
| 355 | |||
| 356 | return intel_connector_update_modes(connector, edid); | ||
| 357 | } | ||
| 358 | |||
| 329 | static bool intel_crt_detect_ddc(struct drm_connector *connector) | 359 | static bool intel_crt_detect_ddc(struct drm_connector *connector) |
| 330 | { | 360 | { |
| 331 | struct intel_crt *crt = intel_attached_crt(connector); | 361 | struct intel_crt *crt = intel_attached_crt(connector); |
| @@ -336,7 +366,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) | |||
| 336 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); | 366 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); |
| 337 | 367 | ||
| 338 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); | 368 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
| 339 | edid = drm_get_edid(connector, i2c); | 369 | edid = intel_crt_get_edid(connector, i2c); |
| 340 | 370 | ||
| 341 | if (edid) { | 371 | if (edid) { |
| 342 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; | 372 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; |
| @@ -544,13 +574,13 @@ static int intel_crt_get_modes(struct drm_connector *connector) | |||
| 544 | struct i2c_adapter *i2c; | 574 | struct i2c_adapter *i2c; |
| 545 | 575 | ||
| 546 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); | 576 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
| 547 | ret = intel_ddc_get_modes(connector, i2c); | 577 | ret = intel_crt_ddc_get_modes(connector, i2c); |
| 548 | if (ret || !IS_G4X(dev)) | 578 | if (ret || !IS_G4X(dev)) |
| 549 | return ret; | 579 | return ret; |
| 550 | 580 | ||
| 551 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | 581 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
| 552 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); | 582 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); |
| 553 | return intel_ddc_get_modes(connector, i2c); | 583 | return intel_crt_ddc_get_modes(connector, i2c); |
| 554 | } | 584 | } |
| 555 | 585 | ||
| 556 | static int intel_crt_set_property(struct drm_connector *connector, | 586 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f6159765f1eb..2dfa6cf4886b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -869,6 +869,7 @@ intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
| 869 | unsigned long bestppm, ppm, absppm; | 869 | unsigned long bestppm, ppm, absppm; |
| 870 | int dotclk, flag; | 870 | int dotclk, flag; |
| 871 | 871 | ||
| 872 | flag = 0; | ||
| 872 | dotclk = target * 1000; | 873 | dotclk = target * 1000; |
| 873 | bestppm = 1000000; | 874 | bestppm = 1000000; |
| 874 | ppm = absppm = 0; | 875 | ppm = absppm = 0; |
| @@ -1383,7 +1384,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
| 1383 | enum pipe pipe, int reg) | 1384 | enum pipe pipe, int reg) |
| 1384 | { | 1385 | { |
| 1385 | u32 val = I915_READ(reg); | 1386 | u32 val = I915_READ(reg); |
| 1386 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), | 1387 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), |
| 1387 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | 1388 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
| 1388 | reg, pipe_name(pipe)); | 1389 | reg, pipe_name(pipe)); |
| 1389 | 1390 | ||
| @@ -1403,13 +1404,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | |||
| 1403 | 1404 | ||
| 1404 | reg = PCH_ADPA; | 1405 | reg = PCH_ADPA; |
| 1405 | val = I915_READ(reg); | 1406 | val = I915_READ(reg); |
| 1406 | WARN(adpa_pipe_enabled(dev_priv, val, pipe), | 1407 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), |
| 1407 | "PCH VGA enabled on transcoder %c, should be disabled\n", | 1408 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
| 1408 | pipe_name(pipe)); | 1409 | pipe_name(pipe)); |
| 1409 | 1410 | ||
| 1410 | reg = PCH_LVDS; | 1411 | reg = PCH_LVDS; |
| 1411 | val = I915_READ(reg); | 1412 | val = I915_READ(reg); |
| 1412 | WARN(lvds_pipe_enabled(dev_priv, val, pipe), | 1413 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), |
| 1413 | "PCH LVDS enabled on transcoder %c, should be disabled\n", | 1414 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
| 1414 | pipe_name(pipe)); | 1415 | pipe_name(pipe)); |
| 1415 | 1416 | ||
| @@ -1871,7 +1872,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv, | |||
| 1871 | enum pipe pipe, int reg) | 1872 | enum pipe pipe, int reg) |
| 1872 | { | 1873 | { |
| 1873 | u32 val = I915_READ(reg); | 1874 | u32 val = I915_READ(reg); |
| 1874 | if (hdmi_pipe_enabled(dev_priv, val, pipe)) { | 1875 | if (hdmi_pipe_enabled(dev_priv, pipe, val)) { |
| 1875 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", | 1876 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", |
| 1876 | reg, pipe); | 1877 | reg, pipe); |
| 1877 | I915_WRITE(reg, val & ~PORT_ENABLE); | 1878 | I915_WRITE(reg, val & ~PORT_ENABLE); |
| @@ -1893,12 +1894,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, | |||
| 1893 | 1894 | ||
| 1894 | reg = PCH_ADPA; | 1895 | reg = PCH_ADPA; |
| 1895 | val = I915_READ(reg); | 1896 | val = I915_READ(reg); |
| 1896 | if (adpa_pipe_enabled(dev_priv, val, pipe)) | 1897 | if (adpa_pipe_enabled(dev_priv, pipe, val)) |
| 1897 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); | 1898 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); |
| 1898 | 1899 | ||
| 1899 | reg = PCH_LVDS; | 1900 | reg = PCH_LVDS; |
| 1900 | val = I915_READ(reg); | 1901 | val = I915_READ(reg); |
| 1901 | if (lvds_pipe_enabled(dev_priv, val, pipe)) { | 1902 | if (lvds_pipe_enabled(dev_priv, pipe, val)) { |
| 1902 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); | 1903 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); |
| 1903 | I915_WRITE(reg, val & ~LVDS_PORT_EN); | 1904 | I915_WRITE(reg, val & ~LVDS_PORT_EN); |
| 1904 | POSTING_READ(reg); | 1905 | POSTING_READ(reg); |
| @@ -3753,17 +3754,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
| 3753 | continue; | 3754 | continue; |
| 3754 | } | 3755 | } |
| 3755 | 3756 | ||
| 3756 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { | ||
| 3757 | /* Use VBT settings if we have an eDP panel */ | ||
| 3758 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | ||
| 3759 | |||
| 3760 | if (edp_bpc < display_bpc) { | ||
| 3761 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | ||
| 3762 | display_bpc = edp_bpc; | ||
| 3763 | } | ||
| 3764 | continue; | ||
| 3765 | } | ||
| 3766 | |||
| 3767 | /* Not one of the known troublemakers, check the EDID */ | 3757 | /* Not one of the known troublemakers, check the EDID */ |
| 3768 | list_for_each_entry(connector, &dev->mode_config.connector_list, | 3758 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
| 3769 | head) { | 3759 | head) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0a56b9ab0f58..a6c426afaa7a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1174,10 +1174,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
| 1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | 1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); |
| 1175 | 1175 | ||
| 1176 | pp = ironlake_get_pp_control(dev_priv); | 1176 | pp = ironlake_get_pp_control(dev_priv); |
| 1177 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1177 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
| 1178 | * panels get very unhappy and cease to work. */ | ||
| 1179 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); | ||
| 1178 | I915_WRITE(PCH_PP_CONTROL, pp); | 1180 | I915_WRITE(PCH_PP_CONTROL, pp); |
| 1179 | POSTING_READ(PCH_PP_CONTROL); | 1181 | POSTING_READ(PCH_PP_CONTROL); |
| 1180 | 1182 | ||
| 1183 | intel_dp->want_panel_vdd = false; | ||
| 1184 | |||
| 1181 | ironlake_wait_panel_off(intel_dp); | 1185 | ironlake_wait_panel_off(intel_dp); |
| 1182 | } | 1186 | } |
| 1183 | 1187 | ||
| @@ -1287,11 +1291,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
| 1287 | * ensure that we have vdd while we switch off the panel. */ | 1291 | * ensure that we have vdd while we switch off the panel. */ |
| 1288 | ironlake_edp_panel_vdd_on(intel_dp); | 1292 | ironlake_edp_panel_vdd_on(intel_dp); |
| 1289 | ironlake_edp_backlight_off(intel_dp); | 1293 | ironlake_edp_backlight_off(intel_dp); |
| 1290 | ironlake_edp_panel_off(intel_dp); | ||
| 1291 | |||
| 1292 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1294 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
| 1295 | ironlake_edp_panel_off(intel_dp); | ||
| 1293 | intel_dp_link_down(intel_dp); | 1296 | intel_dp_link_down(intel_dp); |
| 1294 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
| 1295 | } | 1297 | } |
| 1296 | 1298 | ||
| 1297 | static void intel_dp_commit(struct drm_encoder *encoder) | 1299 | static void intel_dp_commit(struct drm_encoder *encoder) |
| @@ -1326,11 +1328,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
| 1326 | /* Switching the panel off requires vdd. */ | 1328 | /* Switching the panel off requires vdd. */ |
| 1327 | ironlake_edp_panel_vdd_on(intel_dp); | 1329 | ironlake_edp_panel_vdd_on(intel_dp); |
| 1328 | ironlake_edp_backlight_off(intel_dp); | 1330 | ironlake_edp_backlight_off(intel_dp); |
| 1329 | ironlake_edp_panel_off(intel_dp); | ||
| 1330 | |||
| 1331 | intel_dp_sink_dpms(intel_dp, mode); | 1331 | intel_dp_sink_dpms(intel_dp, mode); |
| 1332 | ironlake_edp_panel_off(intel_dp); | ||
| 1332 | intel_dp_link_down(intel_dp); | 1333 | intel_dp_link_down(intel_dp); |
| 1333 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
| 1334 | 1334 | ||
| 1335 | if (is_cpu_edp(intel_dp)) | 1335 | if (is_cpu_edp(intel_dp)) |
| 1336 | ironlake_edp_pll_off(encoder); | 1336 | ironlake_edp_pll_off(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 84353559441c..cd54cf88a28f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -46,15 +46,16 @@ | |||
| 46 | }) | 46 | }) |
| 47 | 47 | ||
| 48 | #define wait_for_atomic_us(COND, US) ({ \ | 48 | #define wait_for_atomic_us(COND, US) ({ \ |
| 49 | int i, ret__ = -ETIMEDOUT; \ | 49 | unsigned long timeout__ = jiffies + usecs_to_jiffies(US); \ |
| 50 | for (i = 0; i < (US); i++) { \ | 50 | int ret__ = 0; \ |
| 51 | if ((COND)) { \ | 51 | while (!(COND)) { \ |
| 52 | ret__ = 0; \ | 52 | if (time_after(jiffies, timeout__)) { \ |
| 53 | break; \ | 53 | ret__ = -ETIMEDOUT; \ |
| 54 | } \ | 54 | break; \ |
| 55 | udelay(1); \ | 55 | } \ |
| 56 | } \ | 56 | cpu_relax(); \ |
| 57 | ret__; \ | 57 | } \ |
| 58 | ret__; \ | ||
| 58 | }) | 59 | }) |
| 59 | 60 | ||
| 60 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | 61 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) |
| @@ -341,6 +342,8 @@ struct intel_fbc_work { | |||
| 341 | int interval; | 342 | int interval; |
| 342 | }; | 343 | }; |
| 343 | 344 | ||
| 345 | int intel_connector_update_modes(struct drm_connector *connector, | ||
| 346 | struct edid *edid); | ||
| 344 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 347 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
| 345 | 348 | ||
| 346 | extern void intel_attach_force_audio_property(struct drm_connector *connector); | 349 | extern void intel_attach_force_audio_property(struct drm_connector *connector); |
| @@ -380,7 +383,6 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, | |||
| 380 | const struct drm_display_mode *mode, | 383 | const struct drm_display_mode *mode, |
| 381 | struct drm_display_mode *adjusted_mode); | 384 | struct drm_display_mode *adjusted_mode); |
| 382 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 385 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
| 383 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | ||
| 384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 386 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
| 385 | extern int intel_panel_setup_backlight(struct drm_device *dev); | 387 | extern int intel_panel_setup_backlight(struct drm_device *dev); |
| 386 | extern void intel_panel_enable_backlight(struct drm_device *dev, | 388 | extern void intel_panel_enable_backlight(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 1991a4408cf9..b9755f6378d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
| @@ -486,9 +486,6 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
| 486 | bus->dev_priv = dev_priv; | 486 | bus->dev_priv = dev_priv; |
| 487 | 487 | ||
| 488 | bus->adapter.algo = &gmbus_algorithm; | 488 | bus->adapter.algo = &gmbus_algorithm; |
| 489 | ret = i2c_add_adapter(&bus->adapter); | ||
| 490 | if (ret) | ||
| 491 | goto err; | ||
| 492 | 489 | ||
| 493 | /* By default use a conservative clock rate */ | 490 | /* By default use a conservative clock rate */ |
| 494 | bus->reg0 = port | GMBUS_RATE_100KHZ; | 491 | bus->reg0 = port | GMBUS_RATE_100KHZ; |
| @@ -498,6 +495,10 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
| 498 | bus->force_bit = true; | 495 | bus->force_bit = true; |
| 499 | 496 | ||
| 500 | intel_gpio_setup(bus, port); | 497 | intel_gpio_setup(bus, port); |
| 498 | |||
| 499 | ret = i2c_add_adapter(&bus->adapter); | ||
| 500 | if (ret) | ||
| 501 | goto err; | ||
| 501 | } | 502 | } |
| 502 | 503 | ||
| 503 | intel_i2c_reset(dev_priv->dev); | 504 | intel_i2c_reset(dev_priv->dev); |
| @@ -540,9 +541,6 @@ void intel_teardown_gmbus(struct drm_device *dev) | |||
| 540 | struct drm_i915_private *dev_priv = dev->dev_private; | 541 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 541 | int i; | 542 | int i; |
| 542 | 543 | ||
| 543 | if (dev_priv->gmbus == NULL) | ||
| 544 | return; | ||
| 545 | |||
| 546 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | 544 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
| 547 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | 545 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
| 548 | i2c_del_adapter(&bus->adapter); | 546 | i2c_del_adapter(&bus->adapter); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e05c0d3e3440..e9a6f6aaed85 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), | 780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), |
| 781 | }, | 781 | }, |
| 782 | }, | 782 | }, |
| 783 | { | ||
| 784 | .callback = intel_no_lvds_dmi_callback, | ||
| 785 | .ident = "Gigabyte GA-D525TUD", | ||
| 786 | .matches = { | ||
| 787 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), | ||
| 788 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), | ||
| 789 | }, | ||
| 790 | }, | ||
| 783 | 791 | ||
| 784 | { } /* terminating entry */ | 792 | { } /* terminating entry */ |
| 785 | }; | 793 | }; |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 45848b9b670b..29b72593fbb2 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
| @@ -33,6 +33,25 @@ | |||
| 33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | * intel_connector_update_modes - update connector from edid | ||
| 37 | * @connector: DRM connector device to use | ||
| 38 | * @edid: previously read EDID information | ||
| 39 | */ | ||
| 40 | int intel_connector_update_modes(struct drm_connector *connector, | ||
| 41 | struct edid *edid) | ||
| 42 | { | ||
| 43 | int ret; | ||
| 44 | |||
| 45 | drm_mode_connector_update_edid_property(connector, edid); | ||
| 46 | ret = drm_add_edid_modes(connector, edid); | ||
| 47 | drm_edid_to_eld(connector, edid); | ||
| 48 | connector->display_info.raw_edid = NULL; | ||
| 49 | kfree(edid); | ||
| 50 | |||
| 51 | return ret; | ||
| 52 | } | ||
| 53 | |||
| 54 | /** | ||
| 36 | * intel_ddc_get_modes - get modelist from monitor | 55 | * intel_ddc_get_modes - get modelist from monitor |
| 37 | * @connector: DRM connector device to use | 56 | * @connector: DRM connector device to use |
| 38 | * @adapter: i2c adapter | 57 | * @adapter: i2c adapter |
| @@ -43,18 +62,12 @@ int intel_ddc_get_modes(struct drm_connector *connector, | |||
| 43 | struct i2c_adapter *adapter) | 62 | struct i2c_adapter *adapter) |
| 44 | { | 63 | { |
| 45 | struct edid *edid; | 64 | struct edid *edid; |
| 46 | int ret = 0; | ||
| 47 | 65 | ||
| 48 | edid = drm_get_edid(connector, adapter); | 66 | edid = drm_get_edid(connector, adapter); |
| 49 | if (edid) { | 67 | if (!edid) |
| 50 | drm_mode_connector_update_edid_property(connector, edid); | 68 | return 0; |
| 51 | ret = drm_add_edid_modes(connector, edid); | ||
| 52 | drm_edid_to_eld(connector, edid); | ||
| 53 | connector->display_info.raw_edid = NULL; | ||
| 54 | kfree(edid); | ||
| 55 | } | ||
| 56 | 69 | ||
| 57 | return ret; | 70 | return intel_connector_update_modes(connector, edid); |
| 58 | } | 71 | } |
| 59 | 72 | ||
| 60 | static const struct drm_prop_enum_list force_audio_names[] = { | 73 | static const struct drm_prop_enum_list force_audio_names[] = { |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 10c7d39034e1..3df4f5fa892a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -213,7 +213,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | |||
| 213 | return val; | 213 | return val; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | u32 intel_panel_get_backlight(struct drm_device *dev) | 216 | static u32 intel_panel_get_backlight(struct drm_device *dev) |
| 217 | { | 217 | { |
| 218 | struct drm_i915_private *dev_priv = dev->dev_private; | 218 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 219 | u32 val; | 219 | u32 val; |
| @@ -311,9 +311,6 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
| 311 | if (dev_priv->backlight_level == 0) | 311 | if (dev_priv->backlight_level == 0) |
| 312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | 312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); |
| 313 | 313 | ||
| 314 | dev_priv->backlight_enabled = true; | ||
| 315 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
| 316 | |||
| 317 | if (INTEL_INFO(dev)->gen >= 4) { | 314 | if (INTEL_INFO(dev)->gen >= 4) { |
| 318 | uint32_t reg, tmp; | 315 | uint32_t reg, tmp; |
| 319 | 316 | ||
| @@ -326,7 +323,7 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
| 326 | * we don't track the backlight dpms state, hence check whether | 323 | * we don't track the backlight dpms state, hence check whether |
| 327 | * we have to do anything first. */ | 324 | * we have to do anything first. */ |
| 328 | if (tmp & BLM_PWM_ENABLE) | 325 | if (tmp & BLM_PWM_ENABLE) |
| 329 | return; | 326 | goto set_level; |
| 330 | 327 | ||
| 331 | if (dev_priv->num_pipe == 3) | 328 | if (dev_priv->num_pipe == 3) |
| 332 | tmp &= ~BLM_PIPE_SELECT_IVB; | 329 | tmp &= ~BLM_PIPE_SELECT_IVB; |
| @@ -347,6 +344,14 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
| 347 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | 344 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); |
| 348 | } | 345 | } |
| 349 | } | 346 | } |
| 347 | |||
| 348 | set_level: | ||
| 349 | /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. | ||
| 350 | * BLC_PWM_CPU_CTL may be cleared to zero automatically when these | ||
| 351 | * registers are set. | ||
| 352 | */ | ||
| 353 | dev_priv->backlight_enabled = true; | ||
| 354 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
| 350 | } | 355 | } |
| 351 | 356 | ||
| 352 | static void intel_panel_init_backlight(struct drm_device *dev) | 357 | static void intel_panel_init_backlight(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 94aabcaa3a67..1881c8c83f0e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -2441,17 +2441,10 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
| 2441 | dev_priv->max_delay << 24 | | 2441 | dev_priv->max_delay << 24 | |
| 2442 | dev_priv->min_delay << 16); | 2442 | dev_priv->min_delay << 16); |
| 2443 | 2443 | ||
| 2444 | if (IS_HASWELL(dev)) { | 2444 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
| 2445 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); | 2445 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
| 2446 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); | 2446 | I915_WRITE(GEN6_RP_UP_EI, 66000); |
| 2447 | I915_WRITE(GEN6_RP_UP_EI, 66000); | 2447 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
| 2448 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); | ||
| 2449 | } else { | ||
| 2450 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); | ||
| 2451 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); | ||
| 2452 | I915_WRITE(GEN6_RP_UP_EI, 100000); | ||
| 2453 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); | ||
| 2454 | } | ||
| 2455 | 2448 | ||
| 2456 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | 2449 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
| 2457 | I915_WRITE(GEN6_RP_CONTROL, | 2450 | I915_WRITE(GEN6_RP_CONTROL, |
| @@ -3963,6 +3956,7 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
| 3963 | DRM_ERROR("Force wake wait timed out\n"); | 3956 | DRM_ERROR("Force wake wait timed out\n"); |
| 3964 | 3957 | ||
| 3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | 3958 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
| 3959 | POSTING_READ(FORCEWAKE); | ||
| 3966 | 3960 | ||
| 3967 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3961 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
| 3968 | DRM_ERROR("Force wake wait timed out\n"); | 3962 | DRM_ERROR("Force wake wait timed out\n"); |
| @@ -3983,6 +3977,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
| 3983 | DRM_ERROR("Force wake wait timed out\n"); | 3977 | DRM_ERROR("Force wake wait timed out\n"); |
| 3984 | 3978 | ||
| 3985 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); | 3979 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); |
| 3980 | POSTING_READ(FORCEWAKE_MT); | ||
| 3986 | 3981 | ||
| 3987 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3982 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
| 3988 | DRM_ERROR("Force wake wait timed out\n"); | 3983 | DRM_ERROR("Force wake wait timed out\n"); |
| @@ -4018,14 +4013,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | |||
| 4018 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 4013 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
| 4019 | { | 4014 | { |
| 4020 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | 4015 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
| 4021 | /* The below doubles as a POSTING_READ */ | 4016 | POSTING_READ(FORCEWAKE); |
| 4022 | gen6_gt_check_fifodbg(dev_priv); | 4017 | gen6_gt_check_fifodbg(dev_priv); |
| 4023 | } | 4018 | } |
| 4024 | 4019 | ||
| 4025 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | 4020 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) |
| 4026 | { | 4021 | { |
| 4027 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); | 4022 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); |
| 4028 | /* The below doubles as a POSTING_READ */ | 4023 | POSTING_READ(FORCEWAKE_MT); |
| 4029 | gen6_gt_check_fifodbg(dev_priv); | 4024 | gen6_gt_check_fifodbg(dev_priv); |
| 4030 | } | 4025 | } |
| 4031 | 4026 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index bf0195a96d53..e2a73b38abe9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -227,31 +227,36 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
| 227 | * number of bits based on the write domains has little performance | 227 | * number of bits based on the write domains has little performance |
| 228 | * impact. | 228 | * impact. |
| 229 | */ | 229 | */ |
| 230 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | 230 | if (flush_domains) { |
| 231 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | 231 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; |
| 232 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | 232 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; |
| 233 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | 233 | /* |
| 234 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | 234 | * Ensure that any following seqno writes only happen |
| 235 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | 235 | * when the render cache is indeed flushed. |
| 236 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | 236 | */ |
| 237 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
| 238 | /* | ||
| 239 | * Ensure that any following seqno writes only happen when the render | ||
| 240 | * cache is indeed flushed (but only if the caller actually wants that). | ||
| 241 | */ | ||
| 242 | if (flush_domains) | ||
| 243 | flags |= PIPE_CONTROL_CS_STALL; | 237 | flags |= PIPE_CONTROL_CS_STALL; |
| 238 | } | ||
| 239 | if (invalidate_domains) { | ||
| 240 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | ||
| 241 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | ||
| 242 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | ||
| 243 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | ||
| 244 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | ||
| 245 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
| 246 | /* | ||
| 247 | * TLB invalidate requires a post-sync write. | ||
| 248 | */ | ||
| 249 | flags |= PIPE_CONTROL_QW_WRITE; | ||
| 250 | } | ||
| 244 | 251 | ||
| 245 | ret = intel_ring_begin(ring, 6); | 252 | ret = intel_ring_begin(ring, 4); |
| 246 | if (ret) | 253 | if (ret) |
| 247 | return ret; | 254 | return ret; |
| 248 | 255 | ||
| 249 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | 256 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); |
| 250 | intel_ring_emit(ring, flags); | 257 | intel_ring_emit(ring, flags); |
| 251 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); | 258 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); |
| 252 | intel_ring_emit(ring, 0); /* lower dword */ | 259 | intel_ring_emit(ring, 0); |
| 253 | intel_ring_emit(ring, 0); /* uppwer dword */ | ||
| 254 | intel_ring_emit(ring, MI_NOOP); | ||
| 255 | intel_ring_advance(ring); | 260 | intel_ring_advance(ring); |
| 256 | 261 | ||
| 257 | return 0; | 262 | return 0; |
| @@ -289,8 +294,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 289 | I915_WRITE_HEAD(ring, 0); | 294 | I915_WRITE_HEAD(ring, 0); |
| 290 | ring->write_tail(ring, 0); | 295 | ring->write_tail(ring, 0); |
| 291 | 296 | ||
| 292 | /* Initialize the ring. */ | ||
| 293 | I915_WRITE_START(ring, obj->gtt_offset); | ||
| 294 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 297 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
| 295 | 298 | ||
| 296 | /* G45 ring initialization fails to reset head to zero */ | 299 | /* G45 ring initialization fails to reset head to zero */ |
| @@ -316,6 +319,11 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
| 316 | } | 319 | } |
| 317 | } | 320 | } |
| 318 | 321 | ||
| 322 | /* Initialize the ring. This must happen _after_ we've cleared the ring | ||
| 323 | * registers with the above sequence (the readback of the HEAD registers | ||
| 324 | * also enforces ordering), otherwise the hw might lose the new ring | ||
| 325 | * register values. */ | ||
| 326 | I915_WRITE_START(ring, obj->gtt_offset); | ||
| 319 | I915_WRITE_CTL(ring, | 327 | I915_WRITE_CTL(ring, |
| 320 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | 328 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
| 321 | | RING_VALID); | 329 | | RING_VALID); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 26a6a4d0d078..d81bb0bf2885 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -444,13 +444,16 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
| 444 | struct i2c_msg *msgs; | 444 | struct i2c_msg *msgs; |
| 445 | int i, ret = true; | 445 | int i, ret = true; |
| 446 | 446 | ||
| 447 | /* Would be simpler to allocate both in one go ? */ | ||
| 447 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); | 448 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); |
| 448 | if (!buf) | 449 | if (!buf) |
| 449 | return false; | 450 | return false; |
| 450 | 451 | ||
| 451 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); | 452 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); |
| 452 | if (!msgs) | 453 | if (!msgs) { |
| 454 | kfree(buf); | ||
| 453 | return false; | 455 | return false; |
| 456 | } | ||
| 454 | 457 | ||
| 455 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 458 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
| 456 | 459 | ||
| @@ -1689,6 +1692,7 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) | |||
| 1689 | edid = intel_sdvo_get_edid(connector); | 1692 | edid = intel_sdvo_get_edid(connector); |
| 1690 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) | 1693 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) |
| 1691 | has_audio = drm_detect_monitor_audio(edid); | 1694 | has_audio = drm_detect_monitor_audio(edid); |
| 1695 | kfree(edid); | ||
| 1692 | 1696 | ||
| 1693 | return has_audio; | 1697 | return has_audio; |
| 1694 | } | 1698 | } |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index cc8df4de2d92..7644f31a3778 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
| @@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
| 60 | 60 | ||
| 61 | switch (fb->pixel_format) { | 61 | switch (fb->pixel_format) { |
| 62 | case DRM_FORMAT_XBGR8888: | 62 | case DRM_FORMAT_XBGR8888: |
| 63 | sprctl |= SPRITE_FORMAT_RGBX888; | 63 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
| 64 | pixel_size = 4; | 64 | pixel_size = 4; |
| 65 | break; | 65 | break; |
| 66 | case DRM_FORMAT_XRGB8888: | 66 | case DRM_FORMAT_XRGB8888: |
| 67 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; | 67 | sprctl |= SPRITE_FORMAT_RGBX888; |
| 68 | pixel_size = 4; | 68 | pixel_size = 4; |
| 69 | break; | 69 | break; |
| 70 | case DRM_FORMAT_YUYV: | 70 | case DRM_FORMAT_YUYV: |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a4d7c500c97b..b69642d5d850 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
| @@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
| 468 | { | 468 | { |
| 469 | unsigned int vcomax, vcomin, pllreffreq; | 469 | unsigned int vcomax, vcomin, pllreffreq; |
| 470 | unsigned int delta, tmpdelta; | 470 | unsigned int delta, tmpdelta; |
| 471 | unsigned int testr, testn, testm, testo; | 471 | int testr, testn, testm, testo; |
| 472 | unsigned int p, m, n; | 472 | unsigned int p, m, n; |
| 473 | unsigned int computed; | 473 | unsigned int computed, vco; |
| 474 | int tmp; | 474 | int tmp; |
| 475 | const unsigned int m_div_val[] = { 1, 2, 4, 8 }; | ||
| 475 | 476 | ||
| 476 | m = n = p = 0; | 477 | m = n = p = 0; |
| 477 | vcomax = 1488000; | 478 | vcomax = 1488000; |
| @@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
| 490 | if (delta == 0) | 491 | if (delta == 0) |
| 491 | break; | 492 | break; |
| 492 | for (testo = 5; testo < 33; testo++) { | 493 | for (testo = 5; testo < 33; testo++) { |
| 493 | computed = pllreffreq * (testn + 1) / | 494 | vco = pllreffreq * (testn + 1) / |
| 494 | (testr + 1); | 495 | (testr + 1); |
| 495 | if (computed < vcomin) | 496 | if (vco < vcomin) |
| 496 | continue; | 497 | continue; |
| 497 | if (computed > vcomax) | 498 | if (vco > vcomax) |
| 498 | continue; | 499 | continue; |
| 500 | computed = vco / (m_div_val[testm] * (testo + 1)); | ||
| 499 | if (computed > clock) | 501 | if (computed > clock) |
| 500 | tmpdelta = computed - clock; | 502 | tmpdelta = computed - clock; |
| 501 | else | 503 | else |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index fc841e87b343..26ebffebe710 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
| @@ -211,11 +211,6 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, | |||
| 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); | 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | static int nouveau_dsm_init(void) | ||
| 215 | { | ||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | 214 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) |
| 220 | { | 215 | { |
| 221 | /* easy option one - intel vendor ID means Integrated */ | 216 | /* easy option one - intel vendor ID means Integrated */ |
| @@ -232,7 +227,6 @@ static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | |||
| 232 | static struct vga_switcheroo_handler nouveau_dsm_handler = { | 227 | static struct vga_switcheroo_handler nouveau_dsm_handler = { |
| 233 | .switchto = nouveau_dsm_switchto, | 228 | .switchto = nouveau_dsm_switchto, |
| 234 | .power_state = nouveau_dsm_power_state, | 229 | .power_state = nouveau_dsm_power_state, |
| 235 | .init = nouveau_dsm_init, | ||
| 236 | .get_client_id = nouveau_dsm_get_client_id, | 230 | .get_client_id = nouveau_dsm_get_client_id, |
| 237 | }; | 231 | }; |
| 238 | 232 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 77e564667b5c..240cf962c999 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
| @@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev) | |||
| 229 | } | 229 | } |
| 230 | break; | 230 | break; |
| 231 | case 6: /* NV50- DP AUX */ | 231 | case 6: /* NV50- DP AUX */ |
| 232 | port->drive = entry[0]; | 232 | port->drive = entry[0] & 0x0f; |
| 233 | port->sense = port->drive; | 233 | port->sense = port->drive; |
| 234 | port->adapter.algo = &nouveau_dp_i2c_algo; | 234 | port->adapter.algo = &nouveau_dp_i2c_algo; |
| 235 | break; | 235 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1cdfd6e757ce..c61014442aa9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
| @@ -731,15 +731,16 @@ nouveau_card_init(struct drm_device *dev) | |||
| 731 | case 0xa3: | 731 | case 0xa3: |
| 732 | case 0xa5: | 732 | case 0xa5: |
| 733 | case 0xa8: | 733 | case 0xa8: |
| 734 | case 0xaf: | ||
| 735 | nva3_copy_create(dev); | 734 | nva3_copy_create(dev); |
| 736 | break; | 735 | break; |
| 737 | } | 736 | } |
| 738 | break; | 737 | break; |
| 739 | case NV_C0: | 738 | case NV_C0: |
| 740 | nvc0_copy_create(dev, 1); | 739 | if (!(nv_rd32(dev, 0x022500) & 0x00000200)) |
| 740 | nvc0_copy_create(dev, 1); | ||
| 741 | case NV_D0: | 741 | case NV_D0: |
| 742 | nvc0_copy_create(dev, 0); | 742 | if (!(nv_rd32(dev, 0x022500) & 0x00000100)) |
| 743 | nvc0_copy_create(dev, 0); | ||
| 743 | break; | 744 | break; |
| 744 | default: | 745 | default: |
| 745 | break; | 746 | break; |
diff --git a/drivers/gpu/drm/nouveau/nv84_fifo.c b/drivers/gpu/drm/nouveau/nv84_fifo.c index cc82d799fc3b..c564c5e4c30a 100644 --- a/drivers/gpu/drm/nouveau/nv84_fifo.c +++ b/drivers/gpu/drm/nouveau/nv84_fifo.c | |||
| @@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine) | |||
| 117 | struct drm_device *dev = chan->dev; | 117 | struct drm_device *dev = chan->dev; |
| 118 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 118 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 119 | unsigned long flags; | 119 | unsigned long flags; |
| 120 | u32 save; | ||
| 120 | 121 | ||
| 121 | /* remove channel from playlist, will context switch if active */ | 122 | /* remove channel from playlist, will context switch if active */ |
| 122 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 123 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
| 123 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); | 124 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); |
| 124 | nv50_fifo_playlist_update(dev); | 125 | nv50_fifo_playlist_update(dev); |
| 125 | 126 | ||
| 127 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
| 128 | |||
| 126 | /* tell any engines on this channel to unload their contexts */ | 129 | /* tell any engines on this channel to unload their contexts */ |
| 127 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); | 130 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); |
| 128 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) | 131 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) |
| 129 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); | 132 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); |
| 130 | 133 | ||
| 134 | nv_wr32(dev, 0x002520, save); | ||
| 135 | |||
| 131 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); | 136 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); |
| 132 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 137 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
| 133 | 138 | ||
| @@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
| 184 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 189 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 185 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); | 190 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); |
| 186 | int i; | 191 | int i; |
| 192 | u32 save; | ||
| 187 | 193 | ||
| 188 | /* set playlist length to zero, fifo will unload context */ | 194 | /* set playlist length to zero, fifo will unload context */ |
| 189 | nv_wr32(dev, 0x0032ec, 0); | 195 | nv_wr32(dev, 0x0032ec, 0); |
| 190 | 196 | ||
| 197 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
| 198 | |||
| 191 | /* tell all connected engines to unload their contexts */ | 199 | /* tell all connected engines to unload their contexts */ |
| 192 | for (i = 0; i < priv->base.channels; i++) { | 200 | for (i = 0; i < priv->base.channels; i++) { |
| 193 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; | 201 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; |
| @@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
| 199 | } | 207 | } |
| 200 | } | 208 | } |
| 201 | 209 | ||
| 210 | nv_wr32(dev, 0x002520, save); | ||
| 202 | nv_wr32(dev, 0x002140, 0); | 211 | nv_wr32(dev, 0x002140, 0); |
| 203 | return 0; | 212 | return 0; |
| 204 | } | 213 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c index 7c95c44e2887..4e712b10ebdb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_pm.c +++ b/drivers/gpu/drm/nouveau/nvc0_pm.c | |||
| @@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info) | |||
| 557 | nouveau_mem_exec(&exec, info->perflvl); | 557 | nouveau_mem_exec(&exec, info->perflvl); |
| 558 | 558 | ||
| 559 | if (dev_priv->chipset < 0xd0) | 559 | if (dev_priv->chipset < 0xd0) |
| 560 | nv_wr32(dev, 0x611200, 0x00003300); | 560 | nv_wr32(dev, 0x611200, 0x00003330); |
| 561 | else | 561 | else |
| 562 | nv_wr32(dev, 0x62c000, 0x03030300); | 562 | nv_wr32(dev, 0x62c000, 0x03030300); |
| 563 | } | 563 | } |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index d0d60e1e7f95..dac525b2994e 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
| @@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
| 790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
| 791 | int ch = EVO_CURS(nv_crtc->index); | 791 | int ch = EVO_CURS(nv_crtc->index); |
| 792 | 792 | ||
| 793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x); | 793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | (x & 0xffff)); |
| 794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); | 794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); |
| 795 | return 0; | 795 | return 0; |
| 796 | } | 796 | } |
diff --git a/drivers/gpu/drm/nouveau/nve0_fifo.c b/drivers/gpu/drm/nouveau/nve0_fifo.c index 1855ecbd843b..e98d144e6eb9 100644 --- a/drivers/gpu/drm/nouveau/nve0_fifo.c +++ b/drivers/gpu/drm/nouveau/nve0_fifo.c | |||
| @@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit) | |||
| 294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); | 294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | static int | ||
| 298 | nve0_fifo_page_flip(struct drm_device *dev, u32 chid) | ||
| 299 | { | ||
| 300 | struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO); | ||
| 301 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 302 | struct nouveau_channel *chan = NULL; | ||
| 303 | unsigned long flags; | ||
| 304 | int ret = -EINVAL; | ||
| 305 | |||
| 306 | spin_lock_irqsave(&dev_priv->channels.lock, flags); | ||
| 307 | if (likely(chid >= 0 && chid < priv->base.channels)) { | ||
| 308 | chan = dev_priv->channels.ptr[chid]; | ||
| 309 | if (likely(chan)) | ||
| 310 | ret = nouveau_finish_page_flip(chan, NULL); | ||
| 311 | } | ||
| 312 | spin_unlock_irqrestore(&dev_priv->channels.lock, flags); | ||
| 313 | return ret; | ||
| 314 | } | ||
| 315 | |||
| 297 | static void | 316 | static void |
| 298 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | 317 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) |
| 299 | { | 318 | { |
| @@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | |||
| 303 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; | 322 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; |
| 304 | u32 subc = (addr & 0x00070000); | 323 | u32 subc = (addr & 0x00070000); |
| 305 | u32 mthd = (addr & 0x00003ffc); | 324 | u32 mthd = (addr & 0x00003ffc); |
| 325 | u32 show = stat; | ||
| 326 | |||
| 327 | if (stat & 0x00200000) { | ||
| 328 | if (mthd == 0x0054) { | ||
| 329 | if (!nve0_fifo_page_flip(dev, chid)) | ||
| 330 | show &= ~0x00200000; | ||
| 331 | } | ||
| 332 | } | ||
| 306 | 333 | ||
| 307 | NV_INFO(dev, "PSUBFIFO %d:", unit); | 334 | if (show) { |
| 308 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat); | 335 | NV_INFO(dev, "PFIFO%d:", unit); |
| 309 | NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", | 336 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, show); |
| 310 | unit, chid, subc, mthd, data); | 337 | NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n", |
| 338 | unit, chid, subc, mthd, data); | ||
| 339 | } | ||
| 311 | 340 | ||
| 312 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); | 341 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); |
| 313 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); | 342 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9e6f76fec527..2817101fb167 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -258,8 +258,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 258 | radeon_crtc->enabled = true; | 258 | radeon_crtc->enabled = true; |
| 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
| 260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
| 261 | /* disable crtc pair power gating before programming */ | 261 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
| 262 | if (ASIC_IS_DCE6(rdev)) | ||
| 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 262 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
| 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 263 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
| 265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 264 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
| @@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 278 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); | 277 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
| 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 278 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
| 280 | radeon_crtc->enabled = false; | 279 | radeon_crtc->enabled = false; |
| 281 | /* power gating is per-pair */ | 280 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
| 282 | if (ASIC_IS_DCE6(rdev)) { | 281 | atombios_powergate_crtc(crtc, ATOM_ENABLE); |
| 283 | struct drm_crtc *other_crtc; | ||
| 284 | struct radeon_crtc *other_radeon_crtc; | ||
| 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | ||
| 286 | other_radeon_crtc = to_radeon_crtc(other_crtc); | ||
| 287 | if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || | ||
| 288 | ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || | ||
| 289 | ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || | ||
| 290 | ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || | ||
| 291 | ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || | ||
| 292 | ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { | ||
| 293 | /* if both crtcs in the pair are off, enable power gating */ | ||
| 294 | if (other_radeon_crtc->enabled == false) | ||
| 295 | atombios_powergate_crtc(crtc, ATOM_ENABLE); | ||
| 296 | break; | ||
| 297 | } | ||
| 298 | } | ||
| 299 | } | ||
| 300 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 282 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
| 301 | radeon_pm_compute_clocks(rdev); | 283 | radeon_pm_compute_clocks(rdev); |
| 302 | break; | 284 | break; |
| @@ -444,11 +426,28 @@ union atom_enable_ss { | |||
| 444 | static void atombios_crtc_program_ss(struct radeon_device *rdev, | 426 | static void atombios_crtc_program_ss(struct radeon_device *rdev, |
| 445 | int enable, | 427 | int enable, |
| 446 | int pll_id, | 428 | int pll_id, |
| 429 | int crtc_id, | ||
| 447 | struct radeon_atom_ss *ss) | 430 | struct radeon_atom_ss *ss) |
| 448 | { | 431 | { |
| 432 | unsigned i; | ||
| 449 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); | 433 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
| 450 | union atom_enable_ss args; | 434 | union atom_enable_ss args; |
| 451 | 435 | ||
| 436 | if (!enable) { | ||
| 437 | for (i = 0; i < rdev->num_crtc; i++) { | ||
| 438 | if (rdev->mode_info.crtcs[i] && | ||
| 439 | rdev->mode_info.crtcs[i]->enabled && | ||
| 440 | i != crtc_id && | ||
| 441 | pll_id == rdev->mode_info.crtcs[i]->pll_id) { | ||
| 442 | /* one other crtc is using this pll don't turn | ||
| 443 | * off spread spectrum as it might turn off | ||
| 444 | * display on active crtc | ||
| 445 | */ | ||
| 446 | return; | ||
| 447 | } | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 452 | memset(&args, 0, sizeof(args)); | 451 | memset(&args, 0, sizeof(args)); |
| 453 | 452 | ||
| 454 | if (ASIC_IS_DCE5(rdev)) { | 453 | if (ASIC_IS_DCE5(rdev)) { |
| @@ -1028,7 +1027,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 1028 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 1027 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
| 1029 | &ref_div, &post_div); | 1028 | &ref_div, &post_div); |
| 1030 | 1029 | ||
| 1031 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); | 1030 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); |
| 1032 | 1031 | ||
| 1033 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 1032 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
| 1034 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | 1033 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
| @@ -1051,7 +1050,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 1051 | ss.step = step_size; | 1050 | ss.step = step_size; |
| 1052 | } | 1051 | } |
| 1053 | 1052 | ||
| 1054 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); | 1053 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); |
| 1055 | } | 1054 | } |
| 1056 | } | 1055 | } |
| 1057 | 1056 | ||
| @@ -1531,12 +1530,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
| 1531 | * crtc virtual pixel clock. | 1530 | * crtc virtual pixel clock. |
| 1532 | */ | 1531 | */ |
| 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1532 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
| 1534 | if (ASIC_IS_DCE5(rdev)) | 1533 | if (rdev->clock.dp_extclk) |
| 1535 | return ATOM_DCPLL; | 1534 | return ATOM_PPLL_INVALID; |
| 1536 | else if (ASIC_IS_DCE6(rdev)) | 1535 | else if (ASIC_IS_DCE6(rdev)) |
| 1537 | return ATOM_PPLL0; | 1536 | return ATOM_PPLL0; |
| 1538 | else if (rdev->clock.dp_extclk) | 1537 | else if (ASIC_IS_DCE5(rdev)) |
| 1539 | return ATOM_PPLL_INVALID; | 1538 | return ATOM_DCPLL; |
| 1540 | } | 1539 | } |
| 1541 | } | 1540 | } |
| 1542 | } | 1541 | } |
| @@ -1572,11 +1571,11 @@ void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) | |||
| 1572 | ASIC_INTERNAL_SS_ON_DCPLL, | 1571 | ASIC_INTERNAL_SS_ON_DCPLL, |
| 1573 | rdev->clock.default_dispclk); | 1572 | rdev->clock.default_dispclk); |
| 1574 | if (ss_enabled) | 1573 | if (ss_enabled) |
| 1575 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); | 1574 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss); |
| 1576 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ | 1575 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ |
| 1577 | atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); | 1576 | atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); |
| 1578 | if (ss_enabled) | 1577 | if (ss_enabled) |
| 1579 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); | 1578 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss); |
| 1580 | } | 1579 | } |
| 1581 | 1580 | ||
| 1582 | } | 1581 | } |
| @@ -1635,18 +1634,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
| 1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 1634 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
| 1636 | { | 1635 | { |
| 1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1636 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 1637 | struct drm_device *dev = crtc->dev; | ||
| 1638 | struct radeon_device *rdev = dev->dev_private; | ||
| 1638 | 1639 | ||
| 1640 | radeon_crtc->in_mode_set = true; | ||
| 1639 | /* pick pll */ | 1641 | /* pick pll */ |
| 1640 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | 1642 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
| 1641 | 1643 | ||
| 1644 | /* disable crtc pair power gating before programming */ | ||
| 1645 | if (ASIC_IS_DCE6(rdev)) | ||
| 1646 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | ||
| 1647 | |||
| 1642 | atombios_lock_crtc(crtc, ATOM_ENABLE); | 1648 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
| 1643 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1649 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
| 1644 | } | 1650 | } |
| 1645 | 1651 | ||
| 1646 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 1652 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
| 1647 | { | 1653 | { |
| 1654 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1655 | |||
| 1648 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1656 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
| 1649 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1657 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
| 1658 | radeon_crtc->in_mode_set = false; | ||
| 1650 | } | 1659 | } |
| 1651 | 1660 | ||
| 1652 | static void atombios_crtc_disable(struct drm_crtc *crtc) | 1661 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
| @@ -1655,9 +1664,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
| 1655 | struct drm_device *dev = crtc->dev; | 1664 | struct drm_device *dev = crtc->dev; |
| 1656 | struct radeon_device *rdev = dev->dev_private; | 1665 | struct radeon_device *rdev = dev->dev_private; |
| 1657 | struct radeon_atom_ss ss; | 1666 | struct radeon_atom_ss ss; |
| 1667 | int i; | ||
| 1658 | 1668 | ||
| 1659 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1669 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
| 1660 | 1670 | ||
| 1671 | for (i = 0; i < rdev->num_crtc; i++) { | ||
| 1672 | if (rdev->mode_info.crtcs[i] && | ||
| 1673 | rdev->mode_info.crtcs[i]->enabled && | ||
| 1674 | i != radeon_crtc->crtc_id && | ||
| 1675 | radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { | ||
| 1676 | /* one other crtc is using this pll don't turn | ||
| 1677 | * off the pll | ||
| 1678 | */ | ||
| 1679 | goto done; | ||
| 1680 | } | ||
| 1681 | } | ||
| 1682 | |||
| 1661 | switch (radeon_crtc->pll_id) { | 1683 | switch (radeon_crtc->pll_id) { |
| 1662 | case ATOM_PPLL1: | 1684 | case ATOM_PPLL1: |
| 1663 | case ATOM_PPLL2: | 1685 | case ATOM_PPLL2: |
| @@ -1674,6 +1696,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
| 1674 | default: | 1696 | default: |
| 1675 | break; | 1697 | break; |
| 1676 | } | 1698 | } |
| 1699 | done: | ||
| 1677 | radeon_crtc->pll_id = -1; | 1700 | radeon_crtc->pll_id = -1; |
| 1678 | } | 1701 | } |
| 1679 | 1702 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7712cf5ab33b..3623b98ed3fe 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
| 577 | struct radeon_device *rdev = dev->dev_private; | 577 | struct radeon_device *rdev = dev->dev_private; |
| 578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 580 | u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); | ||
| 581 | u8 tmp; | ||
| 580 | 582 | ||
| 581 | if (!ASIC_IS_DCE4(rdev)) | 583 | if (!ASIC_IS_DCE4(rdev)) |
| 582 | return panel_mode; | 584 | return panel_mode; |
| 583 | 585 | ||
| 584 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 586 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
| 585 | ENCODER_OBJECT_ID_NUTMEG) | 587 | /* DP bridge chips */ |
| 586 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 588 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
| 587 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 589 | if (tmp & 1) |
| 588 | ENCODER_OBJECT_ID_TRAVIS) { | 590 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
| 589 | u8 id[6]; | 591 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
| 590 | int i; | 592 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
| 591 | for (i = 0; i < 6; i++) | ||
| 592 | id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); | ||
| 593 | if (id[0] == 0x73 && | ||
| 594 | id[1] == 0x69 && | ||
| 595 | id[2] == 0x76 && | ||
| 596 | id[3] == 0x61 && | ||
| 597 | id[4] == 0x72 && | ||
| 598 | id[5] == 0x54) | ||
| 599 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 593 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
| 600 | else | 594 | else |
| 601 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 595 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 602 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 596 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| 603 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | 597 | /* eDP */ |
| 598 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | ||
| 604 | if (tmp & 1) | 599 | if (tmp & 1) |
| 605 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 600 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
| 606 | } | 601 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f9bc27fe269a..6e8803a1170c 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1379 | struct drm_device *dev = encoder->dev; | 1379 | struct drm_device *dev = encoder->dev; |
| 1380 | struct radeon_device *rdev = dev->dev_private; | 1380 | struct radeon_device *rdev = dev->dev_private; |
| 1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1382 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1383 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 1382 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1384 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 1383 | struct radeon_connector *radeon_connector = NULL; | 1385 | struct radeon_connector *radeon_connector = NULL; |
| 1384 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | 1386 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; |
| @@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1390 | 1392 | ||
| 1391 | switch (mode) { | 1393 | switch (mode) { |
| 1392 | case DRM_MODE_DPMS_ON: | 1394 | case DRM_MODE_DPMS_ON: |
| 1393 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1395 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
| 1394 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || | 1396 | if (!connector) |
| 1395 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1397 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 1396 | if (ASIC_IS_DCE6(rdev)) { | 1398 | else |
| 1397 | /* It seems we need to call ATOM_ENCODER_CMD_SETUP again | 1399 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); |
| 1398 | * before reenabling encoder on DPMS ON, otherwise we never | 1400 | |
| 1399 | * get picture | 1401 | /* setup and enable the encoder */ |
| 1400 | */ | 1402 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); |
| 1401 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | 1403 | atombios_dig_encoder_setup(encoder, |
| 1404 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
| 1405 | dig->panel_mode); | ||
| 1406 | if (ext_encoder) { | ||
| 1407 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
| 1408 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1409 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1402 | } | 1410 | } |
| 1403 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1411 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1404 | } else { | 1412 | } else if (ASIC_IS_DCE4(rdev)) { |
| 1413 | /* setup and enable the encoder */ | ||
| 1414 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1415 | /* enable the transmitter */ | ||
| 1416 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1405 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1417 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1418 | } else { | ||
| 1419 | /* setup and enable the encoder and transmitter */ | ||
| 1420 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
| 1421 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
| 1422 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1423 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
| 1424 | if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | ||
| 1425 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
| 1406 | } | 1426 | } |
| 1407 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| 1408 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1428 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| @@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1420 | case DRM_MODE_DPMS_STANDBY: | 1440 | case DRM_MODE_DPMS_STANDBY: |
| 1421 | case DRM_MODE_DPMS_SUSPEND: | 1441 | case DRM_MODE_DPMS_SUSPEND: |
| 1422 | case DRM_MODE_DPMS_OFF: | 1442 | case DRM_MODE_DPMS_OFF: |
| 1423 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | 1443 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
| 1444 | /* disable the transmitter */ | ||
| 1424 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1445 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
| 1425 | else | 1446 | } else if (ASIC_IS_DCE4(rdev)) { |
| 1447 | /* disable the transmitter */ | ||
| 1448 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
| 1449 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1450 | } else { | ||
| 1451 | /* disable the encoder and transmitter */ | ||
| 1426 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1452 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
| 1453 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1454 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 1455 | } | ||
| 1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1456 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| 1428 | if (ASIC_IS_DCE4(rdev)) | 1457 | if (ASIC_IS_DCE4(rdev)) |
| 1429 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | 1458 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
| @@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
| 1740 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1769 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
| 1741 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1770 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1742 | struct drm_encoder *test_encoder; | 1771 | struct drm_encoder *test_encoder; |
| 1743 | struct radeon_encoder_atom_dig *dig; | 1772 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
| 1744 | uint32_t dig_enc_in_use = 0; | 1773 | uint32_t dig_enc_in_use = 0; |
| 1745 | 1774 | ||
| 1746 | /* DCE4/5 */ | 1775 | if (ASIC_IS_DCE6(rdev)) { |
| 1747 | if (ASIC_IS_DCE4(rdev)) { | 1776 | /* DCE6 */ |
| 1748 | dig = radeon_encoder->enc_priv; | 1777 | switch (radeon_encoder->encoder_id) { |
| 1749 | if (ASIC_IS_DCE41(rdev)) { | 1778 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
| 1779 | if (dig->linkb) | ||
| 1780 | return 1; | ||
| 1781 | else | ||
| 1782 | return 0; | ||
| 1783 | break; | ||
| 1784 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
| 1785 | if (dig->linkb) | ||
| 1786 | return 3; | ||
| 1787 | else | ||
| 1788 | return 2; | ||
| 1789 | break; | ||
| 1790 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
| 1791 | if (dig->linkb) | ||
| 1792 | return 5; | ||
| 1793 | else | ||
| 1794 | return 4; | ||
| 1795 | break; | ||
| 1796 | } | ||
| 1797 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 1798 | /* DCE4/5 */ | ||
| 1799 | if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) { | ||
| 1750 | /* ontario follows DCE4 */ | 1800 | /* ontario follows DCE4 */ |
| 1751 | if (rdev->family == CHIP_PALM) { | 1801 | if (rdev->family == CHIP_PALM) { |
| 1752 | if (dig->linkb) | 1802 | if (dig->linkb) |
| @@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1848 | struct drm_device *dev = encoder->dev; | 1898 | struct drm_device *dev = encoder->dev; |
| 1849 | struct radeon_device *rdev = dev->dev_private; | 1899 | struct radeon_device *rdev = dev->dev_private; |
| 1850 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1900 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1851 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
| 1852 | 1901 | ||
| 1853 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1902 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
| 1854 | 1903 | ||
| 1904 | /* need to call this here rather than in prepare() since we need some crtc info */ | ||
| 1905 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 1906 | |||
| 1855 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | 1907 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { |
| 1856 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1908 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
| 1857 | atombios_yuv_setup(encoder, true); | 1909 | atombios_yuv_setup(encoder, true); |
| @@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1870 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1922 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 1871 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1923 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 1872 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1924 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 1873 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1925 | /* handled in dpms */ |
| 1874 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1875 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 1876 | |||
| 1877 | if (!connector) | ||
| 1878 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | ||
| 1879 | else | ||
| 1880 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); | ||
| 1881 | |||
| 1882 | /* setup and enable the encoder */ | ||
| 1883 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1884 | atombios_dig_encoder_setup(encoder, | ||
| 1885 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
| 1886 | dig->panel_mode); | ||
| 1887 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 1888 | /* disable the transmitter */ | ||
| 1889 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1890 | /* setup and enable the encoder */ | ||
| 1891 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1892 | |||
| 1893 | /* enable the transmitter */ | ||
| 1894 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1895 | } else { | ||
| 1896 | /* disable the encoder and transmitter */ | ||
| 1897 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1898 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 1899 | |||
| 1900 | /* setup and enable the encoder and transmitter */ | ||
| 1901 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
| 1902 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
| 1903 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
| 1904 | } | ||
| 1905 | break; | 1926 | break; |
| 1906 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1927 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
| 1907 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 1928 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
| @@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1922 | break; | 1943 | break; |
| 1923 | } | 1944 | } |
| 1924 | 1945 | ||
| 1925 | if (ext_encoder) { | ||
| 1926 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
| 1927 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 1928 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
| 1929 | else | ||
| 1930 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1946 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
| 1934 | 1947 | ||
| 1935 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | 1948 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
| @@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
| 2116 | } | 2129 | } |
| 2117 | 2130 | ||
| 2118 | radeon_atom_output_lock(encoder, true); | 2131 | radeon_atom_output_lock(encoder, true); |
| 2119 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
| 2120 | 2132 | ||
| 2121 | if (connector) { | 2133 | if (connector) { |
| 2122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 2134 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| @@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
| 2137 | 2149 | ||
| 2138 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 2150 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
| 2139 | { | 2151 | { |
| 2152 | /* need to call this here as we need the crtc set up */ | ||
| 2140 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 2153 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); |
| 2141 | radeon_atom_output_lock(encoder, false); | 2154 | radeon_atom_output_lock(encoder, false); |
| 2142 | } | 2155 | } |
| @@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
| 2177 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2190 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2178 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2191 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2179 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 2192 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 2180 | if (ASIC_IS_DCE4(rdev)) | 2193 | /* handled in dpms */ |
| 2181 | /* disable the transmitter */ | ||
| 2182 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2183 | else { | ||
| 2184 | /* disable the encoder and transmitter */ | ||
| 2185 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 2186 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
| 2187 | } | ||
| 2188 | break; | 2194 | break; |
| 2189 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 2195 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
| 2190 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 2196 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index b106c56c9af1..ed3340adeb6f 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -1225,24 +1225,8 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
| 1225 | 1225 | ||
| 1226 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1226 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
| 1227 | { | 1227 | { |
| 1228 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | ||
| 1229 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | ||
| 1230 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 1228 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
| 1231 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 1229 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
| 1232 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
| 1233 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
| 1234 | if (rdev->num_crtc >= 4) { | ||
| 1235 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
| 1236 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
| 1237 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
| 1238 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
| 1239 | } | ||
| 1240 | if (rdev->num_crtc >= 6) { | ||
| 1241 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
| 1242 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
| 1243 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
| 1244 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
| 1245 | } | ||
| 1246 | 1230 | ||
| 1247 | /* Stop all video */ | 1231 | /* Stop all video */ |
| 1248 | WREG32(VGA_RENDER_CONTROL, 0); | 1232 | WREG32(VGA_RENDER_CONTROL, 0); |
| @@ -1353,47 +1337,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
| 1353 | /* Unlock host access */ | 1337 | /* Unlock host access */ |
| 1354 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 1338 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
| 1355 | mdelay(1); | 1339 | mdelay(1); |
| 1356 | /* Restore video state */ | ||
| 1357 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | ||
| 1358 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | ||
| 1359 | if (rdev->num_crtc >= 4) { | ||
| 1360 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | ||
| 1361 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | ||
| 1362 | } | ||
| 1363 | if (rdev->num_crtc >= 6) { | ||
| 1364 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
| 1365 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
| 1366 | } | ||
| 1367 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
| 1368 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
| 1369 | if (rdev->num_crtc >= 4) { | ||
| 1370 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
| 1371 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
| 1372 | } | ||
| 1373 | if (rdev->num_crtc >= 6) { | ||
| 1374 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
| 1375 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
| 1376 | } | ||
| 1377 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | ||
| 1378 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | ||
| 1379 | if (rdev->num_crtc >= 4) { | ||
| 1380 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | ||
| 1381 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | ||
| 1382 | } | ||
| 1383 | if (rdev->num_crtc >= 6) { | ||
| 1384 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
| 1385 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
| 1386 | } | ||
| 1387 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
| 1388 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
| 1389 | if (rdev->num_crtc >= 4) { | ||
| 1390 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
| 1391 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
| 1392 | } | ||
| 1393 | if (rdev->num_crtc >= 6) { | ||
| 1394 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
| 1395 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
| 1396 | } | ||
| 1397 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1340 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
| 1398 | } | 1341 | } |
| 1399 | 1342 | ||
| @@ -1982,10 +1925,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
| 1982 | if (rdev->flags & RADEON_IS_IGP) | 1925 | if (rdev->flags & RADEON_IS_IGP) |
| 1983 | rdev->config.evergreen.tile_config |= 1 << 4; | 1926 | rdev->config.evergreen.tile_config |= 1 << 4; |
| 1984 | else { | 1927 | else { |
| 1985 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1928 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 1986 | rdev->config.evergreen.tile_config |= 1 << 4; | 1929 | case 0: /* four banks */ |
| 1987 | else | ||
| 1988 | rdev->config.evergreen.tile_config |= 0 << 4; | 1930 | rdev->config.evergreen.tile_config |= 0 << 4; |
| 1931 | break; | ||
| 1932 | case 1: /* eight banks */ | ||
| 1933 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
| 1934 | break; | ||
| 1935 | case 2: /* sixteen banks */ | ||
| 1936 | default: | ||
| 1937 | rdev->config.evergreen.tile_config |= 2 << 4; | ||
| 1938 | break; | ||
| 1939 | } | ||
| 1989 | } | 1940 | } |
| 1990 | rdev->config.evergreen.tile_config |= 0 << 8; | 1941 | rdev->config.evergreen.tile_config |= 0 << 8; |
| 1991 | rdev->config.evergreen.tile_config |= | 1942 | rdev->config.evergreen.tile_config |= |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index c16554122ccd..e44a62a07fe3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -788,6 +788,13 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | |||
| 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: | 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: |
| 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: | 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: |
| 790 | depth = 1; | 790 | depth = 1; |
| 791 | break; | ||
| 792 | case V_030000_SQ_TEX_DIM_2D_MSAA: | ||
| 793 | case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA: | ||
| 794 | surf.nsamples = 1 << llevel; | ||
| 795 | llevel = 0; | ||
| 796 | depth = 1; | ||
| 797 | break; | ||
| 791 | case V_030000_SQ_TEX_DIM_3D: | 798 | case V_030000_SQ_TEX_DIM_3D: |
| 792 | break; | 799 | break; |
| 793 | default: | 800 | default: |
| @@ -961,13 +968,15 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
| 961 | 968 | ||
| 962 | if (track->db_dirty) { | 969 | if (track->db_dirty) { |
| 963 | /* Check stencil buffer */ | 970 | /* Check stencil buffer */ |
| 964 | if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { | 971 | if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID && |
| 972 | G_028800_STENCIL_ENABLE(track->db_depth_control)) { | ||
| 965 | r = evergreen_cs_track_validate_stencil(p); | 973 | r = evergreen_cs_track_validate_stencil(p); |
| 966 | if (r) | 974 | if (r) |
| 967 | return r; | 975 | return r; |
| 968 | } | 976 | } |
| 969 | /* Check depth buffer */ | 977 | /* Check depth buffer */ |
| 970 | if (G_028800_Z_ENABLE(track->db_depth_control)) { | 978 | if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID && |
| 979 | G_028800_Z_ENABLE(track->db_depth_control)) { | ||
| 971 | r = evergreen_cs_track_validate_depth(p); | 980 | r = evergreen_cs_track_validate_depth(p); |
| 972 | if (r) | 981 | if (r) |
| 973 | return r; | 982 | return r; |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index d3bd098e4e19..79347855d9bf 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -1277,6 +1277,8 @@ | |||
| 1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) | 1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) |
| 1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) | 1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) |
| 1279 | #define C_028044_FORMAT 0xFFFFFFFE | 1279 | #define C_028044_FORMAT 0xFFFFFFFE |
| 1280 | #define V_028044_STENCIL_INVALID 0 | ||
| 1281 | #define V_028044_STENCIL_8 1 | ||
| 1280 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) | 1282 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) |
| 1281 | #define DB_Z_READ_BASE 0x28048 | 1283 | #define DB_Z_READ_BASE 0x28048 |
| 1282 | #define DB_STENCIL_READ_BASE 0x2804c | 1284 | #define DB_STENCIL_READ_BASE 0x2804c |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 9945d86d9001..853800e8582f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -574,10 +574,18 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
| 574 | if (rdev->flags & RADEON_IS_IGP) | 574 | if (rdev->flags & RADEON_IS_IGP) |
| 575 | rdev->config.cayman.tile_config |= 1 << 4; | 575 | rdev->config.cayman.tile_config |= 1 << 4; |
| 576 | else { | 576 | else { |
| 577 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 577 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 578 | rdev->config.cayman.tile_config |= 1 << 4; | 578 | case 0: /* four banks */ |
| 579 | else | ||
| 580 | rdev->config.cayman.tile_config |= 0 << 4; | 579 | rdev->config.cayman.tile_config |= 0 << 4; |
| 580 | break; | ||
| 581 | case 1: /* eight banks */ | ||
| 582 | rdev->config.cayman.tile_config |= 1 << 4; | ||
| 583 | break; | ||
| 584 | case 2: /* sixteen banks */ | ||
| 585 | default: | ||
| 586 | rdev->config.cayman.tile_config |= 2 << 4; | ||
| 587 | break; | ||
| 588 | } | ||
| 581 | } | 589 | } |
| 582 | rdev->config.cayman.tile_config |= | 590 | rdev->config.cayman.tile_config |= |
| 583 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 591 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 637280f541a3..d79c639ae739 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
| 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); |
| 3790 | } | 3790 | } |
| 3791 | } | 3791 | } |
| 3792 | |||
| 3793 | /** | ||
| 3794 | * r600_get_gpu_clock - return GPU clock counter snapshot | ||
| 3795 | * | ||
| 3796 | * @rdev: radeon_device pointer | ||
| 3797 | * | ||
| 3798 | * Fetches a GPU clock counter snapshot (R6xx-cayman). | ||
| 3799 | * Returns the 64 bit clock counter snapshot. | ||
| 3800 | */ | ||
| 3801 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev) | ||
| 3802 | { | ||
| 3803 | uint64_t clock; | ||
| 3804 | |||
| 3805 | mutex_lock(&rdev->gpu_clock_mutex); | ||
| 3806 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
| 3807 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
| 3808 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
| 3809 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
| 3810 | return clock; | ||
| 3811 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..f37676d7f217 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -47,18 +47,23 @@ struct r600_cs_track { | |||
| 47 | u32 npipes; | 47 | u32 npipes; |
| 48 | /* value we track */ | 48 | /* value we track */ |
| 49 | u32 sq_config; | 49 | u32 sq_config; |
| 50 | u32 log_nsamples; | ||
| 50 | u32 nsamples; | 51 | u32 nsamples; |
| 51 | u32 cb_color_base_last[8]; | 52 | u32 cb_color_base_last[8]; |
| 52 | struct radeon_bo *cb_color_bo[8]; | 53 | struct radeon_bo *cb_color_bo[8]; |
| 53 | u64 cb_color_bo_mc[8]; | 54 | u64 cb_color_bo_mc[8]; |
| 54 | u32 cb_color_bo_offset[8]; | 55 | u64 cb_color_bo_offset[8]; |
| 55 | struct radeon_bo *cb_color_frag_bo[8]; /* unused */ | 56 | struct radeon_bo *cb_color_frag_bo[8]; |
| 56 | struct radeon_bo *cb_color_tile_bo[8]; /* unused */ | 57 | u64 cb_color_frag_offset[8]; |
| 58 | struct radeon_bo *cb_color_tile_bo[8]; | ||
| 59 | u64 cb_color_tile_offset[8]; | ||
| 60 | u32 cb_color_mask[8]; | ||
| 57 | u32 cb_color_info[8]; | 61 | u32 cb_color_info[8]; |
| 58 | u32 cb_color_view[8]; | 62 | u32 cb_color_view[8]; |
| 59 | u32 cb_color_size_idx[8]; /* unused */ | 63 | u32 cb_color_size_idx[8]; /* unused */ |
| 60 | u32 cb_target_mask; | 64 | u32 cb_target_mask; |
| 61 | u32 cb_shader_mask; /* unused */ | 65 | u32 cb_shader_mask; /* unused */ |
| 66 | bool is_resolve; | ||
| 62 | u32 cb_color_size[8]; | 67 | u32 cb_color_size[8]; |
| 63 | u32 vgt_strmout_en; | 68 | u32 vgt_strmout_en; |
| 64 | u32 vgt_strmout_buffer_en; | 69 | u32 vgt_strmout_buffer_en; |
| @@ -311,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
| 311 | track->cb_color_bo[i] = NULL; | 316 | track->cb_color_bo[i] = NULL; |
| 312 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 317 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
| 313 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; | 318 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; |
| 314 | } | 319 | track->cb_color_frag_bo[i] = NULL; |
| 320 | track->cb_color_frag_offset[i] = 0xFFFFFFFF; | ||
| 321 | track->cb_color_tile_bo[i] = NULL; | ||
| 322 | track->cb_color_tile_offset[i] = 0xFFFFFFFF; | ||
| 323 | track->cb_color_mask[i] = 0xFFFFFFFF; | ||
| 324 | } | ||
| 325 | track->is_resolve = false; | ||
| 326 | track->nsamples = 16; | ||
| 327 | track->log_nsamples = 4; | ||
| 315 | track->cb_target_mask = 0xFFFFFFFF; | 328 | track->cb_target_mask = 0xFFFFFFFF; |
| 316 | track->cb_shader_mask = 0xFFFFFFFF; | 329 | track->cb_shader_mask = 0xFFFFFFFF; |
| 317 | track->cb_dirty = true; | 330 | track->cb_dirty = true; |
| @@ -348,11 +361,9 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 348 | volatile u32 *ib = p->ib.ptr; | 361 | volatile u32 *ib = p->ib.ptr; |
| 349 | unsigned array_mode; | 362 | unsigned array_mode; |
| 350 | u32 format; | 363 | u32 format; |
| 364 | /* When resolve is used, the second colorbuffer has always 1 sample. */ | ||
| 365 | unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples; | ||
| 351 | 366 | ||
| 352 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
| 353 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); | ||
| 354 | return -EINVAL; | ||
| 355 | } | ||
| 356 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; | 367 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; |
| 357 | format = G_0280A0_FORMAT(track->cb_color_info[i]); | 368 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
| 358 | if (!r600_fmt_is_valid_color(format)) { | 369 | if (!r600_fmt_is_valid_color(format)) { |
| @@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 375 | array_check.group_size = track->group_size; | 386 | array_check.group_size = track->group_size; |
| 376 | array_check.nbanks = track->nbanks; | 387 | array_check.nbanks = track->nbanks; |
| 377 | array_check.npipes = track->npipes; | 388 | array_check.npipes = track->npipes; |
| 378 | array_check.nsamples = track->nsamples; | 389 | array_check.nsamples = nsamples; |
| 379 | array_check.blocksize = r600_fmt_get_blocksize(format); | 390 | array_check.blocksize = r600_fmt_get_blocksize(format); |
| 380 | if (r600_get_array_mode_alignment(&array_check, | 391 | if (r600_get_array_mode_alignment(&array_check, |
| 381 | &pitch_align, &height_align, &depth_align, &base_align)) { | 392 | &pitch_align, &height_align, &depth_align, &base_align)) { |
| @@ -420,7 +431,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 420 | } | 431 | } |
| 421 | 432 | ||
| 422 | /* check offset */ | 433 | /* check offset */ |
| 423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); | 434 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * |
| 435 | r600_fmt_get_blocksize(format) * nsamples; | ||
| 424 | switch (array_mode) { | 436 | switch (array_mode) { |
| 425 | default: | 437 | default: |
| 426 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 438 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
| @@ -441,7 +453,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 441 | * broken userspace. | 453 | * broken userspace. |
| 442 | */ | 454 | */ |
| 443 | } else { | 455 | } else { |
| 444 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", | 456 | dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n", |
| 445 | __func__, i, array_mode, | 457 | __func__, i, array_mode, |
| 446 | track->cb_color_bo_offset[i], tmp, | 458 | track->cb_color_bo_offset[i], tmp, |
| 447 | radeon_bo_size(track->cb_color_bo[i]), | 459 | radeon_bo_size(track->cb_color_bo[i]), |
| @@ -458,6 +470,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
| 458 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | | 470 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | |
| 459 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); | 471 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); |
| 460 | ib[track->cb_color_size_idx[i]] = tmp; | 472 | ib[track->cb_color_size_idx[i]] = tmp; |
| 473 | |||
| 474 | /* FMASK/CMASK */ | ||
| 475 | switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
| 476 | case V_0280A0_TILE_DISABLE: | ||
| 477 | break; | ||
| 478 | case V_0280A0_FRAG_ENABLE: | ||
| 479 | if (track->nsamples > 1) { | ||
| 480 | uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); | ||
| 481 | /* the tile size is 8x8, but the size is in units of bits. | ||
| 482 | * for bytes, do just * 8. */ | ||
| 483 | uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); | ||
| 484 | |||
| 485 | if (bytes + track->cb_color_frag_offset[i] > | ||
| 486 | radeon_bo_size(track->cb_color_frag_bo[i])) { | ||
| 487 | dev_warn(p->dev, "%s FMASK_TILE_MAX too large " | ||
| 488 | "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
| 489 | __func__, tile_max, bytes, | ||
| 490 | track->cb_color_frag_offset[i], | ||
| 491 | radeon_bo_size(track->cb_color_frag_bo[i])); | ||
| 492 | return -EINVAL; | ||
| 493 | } | ||
| 494 | } | ||
| 495 | /* fall through */ | ||
| 496 | case V_0280A0_CLEAR_ENABLE: | ||
| 497 | { | ||
| 498 | uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); | ||
| 499 | /* One block = 128x128 pixels, one 8x8 tile has 4 bits.. | ||
| 500 | * (128*128) / (8*8) / 2 = 128 bytes per block. */ | ||
| 501 | uint32_t bytes = (block_max + 1) * 128; | ||
| 502 | |||
| 503 | if (bytes + track->cb_color_tile_offset[i] > | ||
| 504 | radeon_bo_size(track->cb_color_tile_bo[i])) { | ||
| 505 | dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " | ||
| 506 | "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
| 507 | __func__, block_max, bytes, | ||
| 508 | track->cb_color_tile_offset[i], | ||
| 509 | radeon_bo_size(track->cb_color_tile_bo[i])); | ||
| 510 | return -EINVAL; | ||
| 511 | } | ||
| 512 | break; | ||
| 513 | } | ||
| 514 | default: | ||
| 515 | dev_warn(p->dev, "%s invalid tile mode\n", __func__); | ||
| 516 | return -EINVAL; | ||
| 517 | } | ||
| 461 | return 0; | 518 | return 0; |
| 462 | } | 519 | } |
| 463 | 520 | ||
| @@ -566,7 +623,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p) | |||
| 566 | 623 | ||
| 567 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | 624 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; |
| 568 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | 625 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; |
| 569 | tmp = ntiles * bpe * 64 * nviews; | 626 | tmp = ntiles * bpe * 64 * nviews * track->nsamples; |
| 570 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | 627 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { |
| 571 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", | 628 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", |
| 572 | array_mode, | 629 | array_mode, |
| @@ -746,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 746 | */ | 803 | */ |
| 747 | if (track->cb_dirty) { | 804 | if (track->cb_dirty) { |
| 748 | tmp = track->cb_target_mask; | 805 | tmp = track->cb_target_mask; |
| 806 | |||
| 807 | /* We must check both colorbuffers for RESOLVE. */ | ||
| 808 | if (track->is_resolve) { | ||
| 809 | tmp |= 0xff; | ||
| 810 | } | ||
| 811 | |||
| 749 | for (i = 0; i < 8; i++) { | 812 | for (i = 0; i < 8; i++) { |
| 750 | if ((tmp >> (i * 4)) & 0xF) { | 813 | if ((tmp >> (i * 4)) & 0xF) { |
| 751 | /* at least one component is enabled */ | 814 | /* at least one component is enabled */ |
| @@ -764,8 +827,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
| 764 | } | 827 | } |
| 765 | 828 | ||
| 766 | /* Check depth buffer */ | 829 | /* Check depth buffer */ |
| 767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 830 | if (track->db_dirty && |
| 768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 831 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
| 832 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
| 833 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
| 769 | r = r600_cs_track_validate_db(p); | 834 | r = r600_cs_track_validate_db(p); |
| 770 | if (r) | 835 | if (r) |
| 771 | return r; | 836 | return r; |
| @@ -1229,9 +1294,15 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 1229 | break; | 1294 | break; |
| 1230 | case R_028C04_PA_SC_AA_CONFIG: | 1295 | case R_028C04_PA_SC_AA_CONFIG: |
| 1231 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); | 1296 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); |
| 1297 | track->log_nsamples = tmp; | ||
| 1232 | track->nsamples = 1 << tmp; | 1298 | track->nsamples = 1 << tmp; |
| 1233 | track->cb_dirty = true; | 1299 | track->cb_dirty = true; |
| 1234 | break; | 1300 | break; |
| 1301 | case R_028808_CB_COLOR_CONTROL: | ||
| 1302 | tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); | ||
| 1303 | track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; | ||
| 1304 | track->cb_dirty = true; | ||
| 1305 | break; | ||
| 1235 | case R_0280A0_CB_COLOR0_INFO: | 1306 | case R_0280A0_CB_COLOR0_INFO: |
| 1236 | case R_0280A4_CB_COLOR1_INFO: | 1307 | case R_0280A4_CB_COLOR1_INFO: |
| 1237 | case R_0280A8_CB_COLOR2_INFO: | 1308 | case R_0280A8_CB_COLOR2_INFO: |
| @@ -1310,16 +1381,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 1310 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | 1381 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
| 1311 | return -EINVAL; | 1382 | return -EINVAL; |
| 1312 | } | 1383 | } |
| 1313 | ib[idx] = track->cb_color_base_last[tmp]; | ||
| 1314 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; | 1384 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; |
| 1385 | track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
| 1386 | ib[idx] = track->cb_color_base_last[tmp]; | ||
| 1315 | } else { | 1387 | } else { |
| 1316 | r = r600_cs_packet_next_reloc(p, &reloc); | 1388 | r = r600_cs_packet_next_reloc(p, &reloc); |
| 1317 | if (r) { | 1389 | if (r) { |
| 1318 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1390 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
| 1319 | return -EINVAL; | 1391 | return -EINVAL; |
| 1320 | } | 1392 | } |
| 1321 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
| 1322 | track->cb_color_frag_bo[tmp] = reloc->robj; | 1393 | track->cb_color_frag_bo[tmp] = reloc->robj; |
| 1394 | track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; | ||
| 1395 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
| 1396 | } | ||
| 1397 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
| 1398 | track->cb_dirty = true; | ||
| 1323 | } | 1399 | } |
| 1324 | break; | 1400 | break; |
| 1325 | case R_0280C0_CB_COLOR0_TILE: | 1401 | case R_0280C0_CB_COLOR0_TILE: |
| @@ -1336,16 +1412,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 1336 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | 1412 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
| 1337 | return -EINVAL; | 1413 | return -EINVAL; |
| 1338 | } | 1414 | } |
| 1339 | ib[idx] = track->cb_color_base_last[tmp]; | ||
| 1340 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; | 1415 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; |
| 1416 | track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
| 1417 | ib[idx] = track->cb_color_base_last[tmp]; | ||
| 1341 | } else { | 1418 | } else { |
| 1342 | r = r600_cs_packet_next_reloc(p, &reloc); | 1419 | r = r600_cs_packet_next_reloc(p, &reloc); |
| 1343 | if (r) { | 1420 | if (r) { |
| 1344 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1421 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
| 1345 | return -EINVAL; | 1422 | return -EINVAL; |
| 1346 | } | 1423 | } |
| 1347 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
| 1348 | track->cb_color_tile_bo[tmp] = reloc->robj; | 1424 | track->cb_color_tile_bo[tmp] = reloc->robj; |
| 1425 | track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; | ||
| 1426 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
| 1427 | } | ||
| 1428 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
| 1429 | track->cb_dirty = true; | ||
| 1430 | } | ||
| 1431 | break; | ||
| 1432 | case R_028100_CB_COLOR0_MASK: | ||
| 1433 | case R_028104_CB_COLOR1_MASK: | ||
| 1434 | case R_028108_CB_COLOR2_MASK: | ||
| 1435 | case R_02810C_CB_COLOR3_MASK: | ||
| 1436 | case R_028110_CB_COLOR4_MASK: | ||
| 1437 | case R_028114_CB_COLOR5_MASK: | ||
| 1438 | case R_028118_CB_COLOR6_MASK: | ||
| 1439 | case R_02811C_CB_COLOR7_MASK: | ||
| 1440 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; | ||
| 1441 | track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx); | ||
| 1442 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
| 1443 | track->cb_dirty = true; | ||
| 1349 | } | 1444 | } |
| 1350 | break; | 1445 | break; |
| 1351 | case CB_COLOR0_BASE: | 1446 | case CB_COLOR0_BASE: |
| @@ -1490,7 +1585,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level) | |||
| 1490 | } | 1585 | } |
| 1491 | 1586 | ||
| 1492 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | 1587 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, |
| 1493 | unsigned w0, unsigned h0, unsigned d0, unsigned format, | 1588 | unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, |
| 1494 | unsigned block_align, unsigned height_align, unsigned base_align, | 1589 | unsigned block_align, unsigned height_align, unsigned base_align, |
| 1495 | unsigned *l0_size, unsigned *mipmap_size) | 1590 | unsigned *l0_size, unsigned *mipmap_size) |
| 1496 | { | 1591 | { |
| @@ -1518,7 +1613,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | |||
| 1518 | 1613 | ||
| 1519 | depth = r600_mip_minify(d0, i); | 1614 | depth = r600_mip_minify(d0, i); |
| 1520 | 1615 | ||
| 1521 | size = nbx * nby * blocksize; | 1616 | size = nbx * nby * blocksize * nsamples; |
| 1522 | if (nfaces) | 1617 | if (nfaces) |
| 1523 | size *= nfaces; | 1618 | size *= nfaces; |
| 1524 | else | 1619 | else |
| @@ -1557,13 +1652,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1557 | u32 tiling_flags) | 1652 | u32 tiling_flags) |
| 1558 | { | 1653 | { |
| 1559 | struct r600_cs_track *track = p->track; | 1654 | struct r600_cs_track *track = p->track; |
| 1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1655 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
| 1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1656 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
| 1562 | u32 height_align, pitch, pitch_align, depth_align; | 1657 | u32 height_align, pitch, pitch_align, depth_align; |
| 1563 | u32 array, barray, larray; | 1658 | u32 barray, larray; |
| 1564 | u64 base_align; | 1659 | u64 base_align; |
| 1565 | struct array_mode_checker array_check; | 1660 | struct array_mode_checker array_check; |
| 1566 | u32 format; | 1661 | u32 format; |
| 1662 | bool is_array; | ||
| 1567 | 1663 | ||
| 1568 | /* on legacy kernel we don't perform advanced check */ | 1664 | /* on legacy kernel we don't perform advanced check */ |
| 1569 | if (p->rdev == NULL) | 1665 | if (p->rdev == NULL) |
| @@ -1581,12 +1677,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1581 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1677 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
| 1582 | } | 1678 | } |
| 1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1679 | word1 = radeon_get_ib_value(p, idx + 1); |
| 1680 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1681 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1682 | word4 = radeon_get_ib_value(p, idx + 4); | ||
| 1683 | word5 = radeon_get_ib_value(p, idx + 5); | ||
| 1684 | dim = G_038000_DIM(word0); | ||
| 1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1685 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
| 1686 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1687 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
| 1586 | d0 = G_038004_TEX_DEPTH(word1); | 1688 | d0 = G_038004_TEX_DEPTH(word1); |
| 1689 | format = G_038004_DATA_FORMAT(word1); | ||
| 1690 | blevel = G_038010_BASE_LEVEL(word4); | ||
| 1691 | llevel = G_038014_LAST_LEVEL(word5); | ||
| 1692 | /* pitch in texels */ | ||
| 1693 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1694 | array_check.group_size = track->group_size; | ||
| 1695 | array_check.nbanks = track->nbanks; | ||
| 1696 | array_check.npipes = track->npipes; | ||
| 1697 | array_check.nsamples = 1; | ||
| 1698 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1587 | nfaces = 1; | 1699 | nfaces = 1; |
| 1588 | array = 0; | 1700 | is_array = false; |
| 1589 | switch (G_038000_DIM(word0)) { | 1701 | switch (dim) { |
| 1590 | case V_038000_SQ_TEX_DIM_1D: | 1702 | case V_038000_SQ_TEX_DIM_1D: |
| 1591 | case V_038000_SQ_TEX_DIM_2D: | 1703 | case V_038000_SQ_TEX_DIM_2D: |
| 1592 | case V_038000_SQ_TEX_DIM_3D: | 1704 | case V_038000_SQ_TEX_DIM_3D: |
| @@ -1599,29 +1711,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1599 | break; | 1711 | break; |
| 1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1712 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
| 1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1713 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
| 1602 | array = 1; | 1714 | is_array = true; |
| 1603 | break; | 1715 | break; |
| 1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1716 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
| 1717 | is_array = true; | ||
| 1718 | /* fall through */ | ||
| 1719 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
| 1720 | array_check.nsamples = 1 << llevel; | ||
| 1721 | llevel = 0; | ||
| 1722 | break; | ||
| 1606 | default: | 1723 | default: |
| 1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1724 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
| 1608 | return -EINVAL; | 1725 | return -EINVAL; |
| 1609 | } | 1726 | } |
| 1610 | format = G_038004_DATA_FORMAT(word1); | ||
| 1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1727 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
| 1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1728 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
| 1613 | __func__, __LINE__, format); | 1729 | __func__, __LINE__, format); |
| 1614 | return -EINVAL; | 1730 | return -EINVAL; |
| 1615 | } | 1731 | } |
| 1616 | 1732 | ||
| 1617 | /* pitch in texels */ | ||
| 1618 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
| 1619 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
| 1620 | array_check.group_size = track->group_size; | ||
| 1621 | array_check.nbanks = track->nbanks; | ||
| 1622 | array_check.npipes = track->npipes; | ||
| 1623 | array_check.nsamples = 1; | ||
| 1624 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
| 1625 | if (r600_get_array_mode_alignment(&array_check, | 1733 | if (r600_get_array_mode_alignment(&array_check, |
| 1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1734 | &pitch_align, &height_align, &depth_align, &base_align)) { |
| 1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1735 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
| @@ -1647,24 +1755,17 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1647 | return -EINVAL; | 1755 | return -EINVAL; |
| 1648 | } | 1756 | } |
| 1649 | 1757 | ||
| 1650 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
| 1651 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1652 | |||
| 1653 | word0 = radeon_get_ib_value(p, idx + 4); | ||
| 1654 | word1 = radeon_get_ib_value(p, idx + 5); | ||
| 1655 | blevel = G_038010_BASE_LEVEL(word0); | ||
| 1656 | llevel = G_038014_LAST_LEVEL(word1); | ||
| 1657 | if (blevel > llevel) { | 1758 | if (blevel > llevel) { |
| 1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1759 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
| 1659 | blevel, llevel); | 1760 | blevel, llevel); |
| 1660 | } | 1761 | } |
| 1661 | if (array == 1) { | 1762 | if (is_array) { |
| 1662 | barray = G_038014_BASE_ARRAY(word1); | 1763 | barray = G_038014_BASE_ARRAY(word5); |
| 1663 | larray = G_038014_LAST_ARRAY(word1); | 1764 | larray = G_038014_LAST_ARRAY(word5); |
| 1664 | 1765 | ||
| 1665 | nfaces = larray - barray + 1; | 1766 | nfaces = larray - barray + 1; |
| 1666 | } | 1767 | } |
| 1667 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, | 1768 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format, |
| 1668 | pitch_align, height_align, base_align, | 1769 | pitch_align, height_align, base_align, |
| 1669 | &l0_size, &mipmap_size); | 1770 | &l0_size, &mipmap_size); |
| 1670 | /* using get ib will give us the offset into the texture bo */ | 1771 | /* using get ib will give us the offset into the texture bo */ |
| @@ -1677,7 +1778,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
| 1677 | return -EINVAL; | 1778 | return -EINVAL; |
| 1678 | } | 1779 | } |
| 1679 | /* using get ib will give us the offset into the mipmap bo */ | 1780 | /* using get ib will give us the offset into the mipmap bo */ |
| 1680 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
| 1681 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1781 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
| 1682 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1782 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
| 1683 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1783 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4b116ae75fc2..fa6f37099ba9 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
| @@ -66,6 +66,14 @@ | |||
| 66 | #define CC_RB_BACKEND_DISABLE 0x98F4 | 66 | #define CC_RB_BACKEND_DISABLE 0x98F4 |
| 67 | #define BACKEND_DISABLE(x) ((x) << 16) | 67 | #define BACKEND_DISABLE(x) ((x) << 16) |
| 68 | 68 | ||
| 69 | #define R_028808_CB_COLOR_CONTROL 0x28808 | ||
| 70 | #define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4) | ||
| 71 | #define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7) | ||
| 72 | #define C_028808_SPECIAL_OP 0xFFFFFF8F | ||
| 73 | #define V_028808_SPECIAL_NORMAL 0x00 | ||
| 74 | #define V_028808_SPECIAL_DISABLE 0x01 | ||
| 75 | #define V_028808_SPECIAL_RESOLVE_BOX 0x07 | ||
| 76 | |||
| 69 | #define CB_COLOR0_BASE 0x28040 | 77 | #define CB_COLOR0_BASE 0x28040 |
| 70 | #define CB_COLOR1_BASE 0x28044 | 78 | #define CB_COLOR1_BASE 0x28044 |
| 71 | #define CB_COLOR2_BASE 0x28048 | 79 | #define CB_COLOR2_BASE 0x28048 |
| @@ -92,6 +100,20 @@ | |||
| 92 | #define R_028094_CB_COLOR5_VIEW 0x028094 | 100 | #define R_028094_CB_COLOR5_VIEW 0x028094 |
| 93 | #define R_028098_CB_COLOR6_VIEW 0x028098 | 101 | #define R_028098_CB_COLOR6_VIEW 0x028098 |
| 94 | #define R_02809C_CB_COLOR7_VIEW 0x02809C | 102 | #define R_02809C_CB_COLOR7_VIEW 0x02809C |
| 103 | #define R_028100_CB_COLOR0_MASK 0x028100 | ||
| 104 | #define S_028100_CMASK_BLOCK_MAX(x) (((x) & 0xFFF) << 0) | ||
| 105 | #define G_028100_CMASK_BLOCK_MAX(x) (((x) >> 0) & 0xFFF) | ||
| 106 | #define C_028100_CMASK_BLOCK_MAX 0xFFFFF000 | ||
| 107 | #define S_028100_FMASK_TILE_MAX(x) (((x) & 0xFFFFF) << 12) | ||
| 108 | #define G_028100_FMASK_TILE_MAX(x) (((x) >> 12) & 0xFFFFF) | ||
| 109 | #define C_028100_FMASK_TILE_MAX 0x00000FFF | ||
| 110 | #define R_028104_CB_COLOR1_MASK 0x028104 | ||
| 111 | #define R_028108_CB_COLOR2_MASK 0x028108 | ||
| 112 | #define R_02810C_CB_COLOR3_MASK 0x02810C | ||
| 113 | #define R_028110_CB_COLOR4_MASK 0x028110 | ||
| 114 | #define R_028114_CB_COLOR5_MASK 0x028114 | ||
| 115 | #define R_028118_CB_COLOR6_MASK 0x028118 | ||
| 116 | #define R_02811C_CB_COLOR7_MASK 0x02811C | ||
| 95 | #define CB_COLOR0_INFO 0x280a0 | 117 | #define CB_COLOR0_INFO 0x280a0 |
| 96 | # define CB_FORMAT(x) ((x) << 2) | 118 | # define CB_FORMAT(x) ((x) << 2) |
| 97 | # define CB_ARRAY_MODE(x) ((x) << 8) | 119 | # define CB_ARRAY_MODE(x) ((x) << 8) |
| @@ -602,6 +624,9 @@ | |||
| 602 | #define RLC_HB_WPTR 0x3f1c | 624 | #define RLC_HB_WPTR 0x3f1c |
| 603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 | 625 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 |
| 604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 | 626 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 |
| 627 | #define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 | ||
| 628 | #define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c | ||
| 629 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 | ||
| 605 | #define RLC_MC_CNTL 0x3f44 | 630 | #define RLC_MC_CNTL 0x3f44 |
| 606 | #define RLC_UCODE_CNTL 0x3f48 | 631 | #define RLC_UCODE_CNTL 0x3f48 |
| 607 | #define RLC_UCODE_ADDR 0x3f2c | 632 | #define RLC_UCODE_ADDR 0x3f2c |
| @@ -1397,6 +1422,9 @@ | |||
| 1397 | #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) | 1422 | #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) |
| 1398 | #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) | 1423 | #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) |
| 1399 | #define C_0280A0_TILE_MODE 0xFFF3FFFF | 1424 | #define C_0280A0_TILE_MODE 0xFFF3FFFF |
| 1425 | #define V_0280A0_TILE_DISABLE 0 | ||
| 1426 | #define V_0280A0_CLEAR_ENABLE 1 | ||
| 1427 | #define V_0280A0_FRAG_ENABLE 2 | ||
| 1400 | #define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) | 1428 | #define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) |
| 1401 | #define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) | 1429 | #define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) |
| 1402 | #define C_0280A0_BLEND_CLAMP 0xFFEFFFFF | 1430 | #define C_0280A0_BLEND_CLAMP 0xFFEFFFFF |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5431af292408..59a15315ae9f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -142,21 +142,6 @@ struct radeon_device; | |||
| 142 | /* | 142 | /* |
| 143 | * BIOS. | 143 | * BIOS. |
| 144 | */ | 144 | */ |
| 145 | #define ATRM_BIOS_PAGE 4096 | ||
| 146 | |||
| 147 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
| 148 | bool radeon_atrm_supported(struct pci_dev *pdev); | ||
| 149 | int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); | ||
| 150 | #else | ||
| 151 | static inline bool radeon_atrm_supported(struct pci_dev *pdev) | ||
| 152 | { | ||
| 153 | return false; | ||
| 154 | } | ||
| 155 | |||
| 156 | static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ | ||
| 157 | return -EINVAL; | ||
| 158 | } | ||
| 159 | #endif | ||
| 160 | bool radeon_get_bios(struct radeon_device *rdev); | 145 | bool radeon_get_bios(struct radeon_device *rdev); |
| 161 | 146 | ||
| 162 | /* | 147 | /* |
| @@ -300,6 +285,7 @@ struct radeon_bo_va { | |||
| 300 | uint64_t soffset; | 285 | uint64_t soffset; |
| 301 | uint64_t eoffset; | 286 | uint64_t eoffset; |
| 302 | uint32_t flags; | 287 | uint32_t flags; |
| 288 | struct radeon_fence *fence; | ||
| 303 | bool valid; | 289 | bool valid; |
| 304 | }; | 290 | }; |
| 305 | 291 | ||
| @@ -1533,6 +1519,7 @@ struct radeon_device { | |||
| 1533 | unsigned debugfs_count; | 1519 | unsigned debugfs_count; |
| 1534 | /* virtual memory */ | 1520 | /* virtual memory */ |
| 1535 | struct radeon_vm_manager vm_manager; | 1521 | struct radeon_vm_manager vm_manager; |
| 1522 | struct mutex gpu_clock_mutex; | ||
| 1536 | }; | 1523 | }; |
| 1537 | 1524 | ||
| 1538 | int radeon_device_init(struct radeon_device *rdev, | 1525 | int radeon_device_init(struct radeon_device *rdev, |
| @@ -1733,11 +1720,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
| 1733 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) | 1720 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) |
| 1734 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) | 1721 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) |
| 1735 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) | 1722 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) |
| 1736 | #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) | 1723 | #define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) |
| 1737 | #define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) | 1724 | #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) |
| 1738 | #define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) | 1725 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) |
| 1739 | #define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) | 1726 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) |
| 1740 | #define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) | 1727 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) |
| 1741 | 1728 | ||
| 1742 | /* Common functions */ | 1729 | /* Common functions */ |
| 1743 | /* AGP */ | 1730 | /* AGP */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f4af24310438..18c38d14c8cd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); | |||
| 255 | * rv515 | 255 | * rv515 |
| 256 | */ | 256 | */ |
| 257 | struct rv515_mc_save { | 257 | struct rv515_mc_save { |
| 258 | u32 d1vga_control; | ||
| 259 | u32 d2vga_control; | ||
| 260 | u32 vga_render_control; | 258 | u32 vga_render_control; |
| 261 | u32 vga_hdp_control; | 259 | u32 vga_hdp_control; |
| 262 | u32 d1crtc_control; | ||
| 263 | u32 d2crtc_control; | ||
| 264 | }; | 260 | }; |
| 261 | |||
| 265 | int rv515_init(struct radeon_device *rdev); | 262 | int rv515_init(struct radeon_device *rdev); |
| 266 | void rv515_fini(struct radeon_device *rdev); | 263 | void rv515_fini(struct radeon_device *rdev); |
| 267 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 264 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| @@ -371,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
| 371 | unsigned num_gpu_pages, | 368 | unsigned num_gpu_pages, |
| 372 | struct radeon_sa_bo *vb); | 369 | struct radeon_sa_bo *vb); |
| 373 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 370 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
| 371 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev); | ||
| 374 | 372 | ||
| 375 | /* | 373 | /* |
| 376 | * rv770,rv730,rv710,rv740 | 374 | * rv770,rv730,rv710,rv740 |
| @@ -389,11 +387,10 @@ void r700_cp_fini(struct radeon_device *rdev); | |||
| 389 | * evergreen | 387 | * evergreen |
| 390 | */ | 388 | */ |
| 391 | struct evergreen_mc_save { | 389 | struct evergreen_mc_save { |
| 392 | u32 vga_control[6]; | ||
| 393 | u32 vga_render_control; | 390 | u32 vga_render_control; |
| 394 | u32 vga_hdp_control; | 391 | u32 vga_hdp_control; |
| 395 | u32 crtc_control[6]; | ||
| 396 | }; | 392 | }; |
| 393 | |||
| 397 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); | 394 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); |
| 398 | int evergreen_init(struct radeon_device *rdev); | 395 | int evergreen_init(struct radeon_device *rdev); |
| 399 | void evergreen_fini(struct radeon_device *rdev); | 396 | void evergreen_fini(struct radeon_device *rdev); |
| @@ -472,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | |||
| 472 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 469 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); |
| 473 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 470 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); |
| 474 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 471 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
| 472 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | ||
| 475 | 473 | ||
| 476 | #endif | 474 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b1e3820df363..d67d4f3eb6f4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -452,7 +452,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ | 454 | /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ |
| 455 | if ((dev->pdev->device == 0x9802) && | 455 | if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) && |
| 456 | (dev->pdev->subsystem_vendor == 0x1734) && | 456 | (dev->pdev->subsystem_vendor == 0x1734) && |
| 457 | (dev->pdev->subsystem_device == 0x11bd)) { | 457 | (dev->pdev->subsystem_device == 0x11bd)) { |
| 458 | if (*connector_type == DRM_MODE_CONNECTOR_VGA) { | 458 | if (*connector_type == DRM_MODE_CONNECTOR_VGA) { |
| @@ -1263,6 +1263,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
| 1263 | union igp_info { | 1263 | union igp_info { |
| 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
| 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
| 1266 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
| 1267 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
| 1266 | }; | 1268 | }; |
| 1267 | 1269 | ||
| 1268 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | 1270 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
| @@ -1390,27 +1392,50 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | |||
| 1390 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1392 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
| 1391 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | 1393 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); |
| 1392 | u16 data_offset, size; | 1394 | u16 data_offset, size; |
| 1393 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | 1395 | union igp_info *igp_info; |
| 1394 | u8 frev, crev; | 1396 | u8 frev, crev; |
| 1395 | u16 percentage = 0, rate = 0; | 1397 | u16 percentage = 0, rate = 0; |
| 1396 | 1398 | ||
| 1397 | /* get any igp specific overrides */ | 1399 | /* get any igp specific overrides */ |
| 1398 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | 1400 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
| 1399 | &frev, &crev, &data_offset)) { | 1401 | &frev, &crev, &data_offset)) { |
| 1400 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | 1402 | igp_info = (union igp_info *) |
| 1401 | (mode_info->atom_context->bios + data_offset); | 1403 | (mode_info->atom_context->bios + data_offset); |
| 1402 | switch (id) { | 1404 | switch (crev) { |
| 1403 | case ASIC_INTERNAL_SS_ON_TMDS: | 1405 | case 6: |
| 1404 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | 1406 | switch (id) { |
| 1405 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | 1407 | case ASIC_INTERNAL_SS_ON_TMDS: |
| 1408 | percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage); | ||
| 1409 | rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz); | ||
| 1410 | break; | ||
| 1411 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1412 | percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage); | ||
| 1413 | rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz); | ||
| 1414 | break; | ||
| 1415 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1416 | percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage); | ||
| 1417 | rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz); | ||
| 1418 | break; | ||
| 1419 | } | ||
| 1406 | break; | 1420 | break; |
| 1407 | case ASIC_INTERNAL_SS_ON_HDMI: | 1421 | case 7: |
| 1408 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | 1422 | switch (id) { |
| 1409 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | 1423 | case ASIC_INTERNAL_SS_ON_TMDS: |
| 1424 | percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage); | ||
| 1425 | rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz); | ||
| 1426 | break; | ||
| 1427 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
| 1428 | percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage); | ||
| 1429 | rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz); | ||
| 1430 | break; | ||
| 1431 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
| 1432 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); | ||
| 1433 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); | ||
| 1434 | break; | ||
| 1435 | } | ||
| 1410 | break; | 1436 | break; |
| 1411 | case ASIC_INTERNAL_SS_ON_LVDS: | 1437 | default: |
| 1412 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | 1438 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
| 1413 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
| 1414 | break; | 1439 | break; |
| 1415 | } | 1440 | } |
| 1416 | if (percentage) | 1441 | if (percentage) |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 98724fcb0088..2a2cf0b88a28 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
| @@ -30,57 +30,8 @@ static struct radeon_atpx_priv { | |||
| 30 | /* handle for device - and atpx */ | 30 | /* handle for device - and atpx */ |
| 31 | acpi_handle dhandle; | 31 | acpi_handle dhandle; |
| 32 | acpi_handle atpx_handle; | 32 | acpi_handle atpx_handle; |
| 33 | acpi_handle atrm_handle; | ||
| 34 | } radeon_atpx_priv; | 33 | } radeon_atpx_priv; |
| 35 | 34 | ||
| 36 | /* retrieve the ROM in 4k blocks */ | ||
| 37 | static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | ||
| 38 | int offset, int len) | ||
| 39 | { | ||
| 40 | acpi_status status; | ||
| 41 | union acpi_object atrm_arg_elements[2], *obj; | ||
| 42 | struct acpi_object_list atrm_arg; | ||
| 43 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
| 44 | |||
| 45 | atrm_arg.count = 2; | ||
| 46 | atrm_arg.pointer = &atrm_arg_elements[0]; | ||
| 47 | |||
| 48 | atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
| 49 | atrm_arg_elements[0].integer.value = offset; | ||
| 50 | |||
| 51 | atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
| 52 | atrm_arg_elements[1].integer.value = len; | ||
| 53 | |||
| 54 | status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); | ||
| 55 | if (ACPI_FAILURE(status)) { | ||
| 56 | printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); | ||
| 57 | return -ENODEV; | ||
| 58 | } | ||
| 59 | |||
| 60 | obj = (union acpi_object *)buffer.pointer; | ||
| 61 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); | ||
| 62 | len = obj->buffer.length; | ||
| 63 | kfree(buffer.pointer); | ||
| 64 | return len; | ||
| 65 | } | ||
| 66 | |||
| 67 | bool radeon_atrm_supported(struct pci_dev *pdev) | ||
| 68 | { | ||
| 69 | /* get the discrete ROM only via ATRM */ | ||
| 70 | if (!radeon_atpx_priv.atpx_detected) | ||
| 71 | return false; | ||
| 72 | |||
| 73 | if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
| 74 | return false; | ||
| 75 | return true; | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) | ||
| 80 | { | ||
| 81 | return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); | ||
| 82 | } | ||
| 83 | |||
| 84 | static int radeon_atpx_get_version(acpi_handle handle) | 35 | static int radeon_atpx_get_version(acpi_handle handle) |
| 85 | { | 36 | { |
| 86 | acpi_status status; | 37 | acpi_status status; |
| @@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
| 198 | 149 | ||
| 199 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 150 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
| 200 | { | 151 | { |
| 201 | acpi_handle dhandle, atpx_handle, atrm_handle; | 152 | acpi_handle dhandle, atpx_handle; |
| 202 | acpi_status status; | 153 | acpi_status status; |
| 203 | 154 | ||
| 204 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | 155 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); |
| @@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
| 209 | if (ACPI_FAILURE(status)) | 160 | if (ACPI_FAILURE(status)) |
| 210 | return false; | 161 | return false; |
| 211 | 162 | ||
| 212 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||
| 213 | if (ACPI_FAILURE(status)) | ||
| 214 | return false; | ||
| 215 | |||
| 216 | radeon_atpx_priv.dhandle = dhandle; | 163 | radeon_atpx_priv.dhandle = dhandle; |
| 217 | radeon_atpx_priv.atpx_handle = atpx_handle; | 164 | radeon_atpx_priv.atpx_handle = atpx_handle; |
| 218 | radeon_atpx_priv.atrm_handle = atrm_handle; | ||
| 219 | return true; | 165 | return true; |
| 220 | } | 166 | } |
| 221 | 167 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 501f4881e5aa..d306cc8fdeaa 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | #include <linux/vga_switcheroo.h> | 33 | #include <linux/vga_switcheroo.h> |
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | #include <linux/acpi.h> | ||
| 35 | /* | 36 | /* |
| 36 | * BIOS. | 37 | * BIOS. |
| 37 | */ | 38 | */ |
| @@ -98,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev) | |||
| 98 | return true; | 99 | return true; |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 102 | #ifdef CONFIG_ACPI | ||
| 101 | /* ATRM is used to get the BIOS on the discrete cards in | 103 | /* ATRM is used to get the BIOS on the discrete cards in |
| 102 | * dual-gpu systems. | 104 | * dual-gpu systems. |
| 103 | */ | 105 | */ |
| 106 | /* retrieve the ROM in 4k blocks */ | ||
| 107 | #define ATRM_BIOS_PAGE 4096 | ||
| 108 | /** | ||
| 109 | * radeon_atrm_call - fetch a chunk of the vbios | ||
| 110 | * | ||
| 111 | * @atrm_handle: acpi ATRM handle | ||
| 112 | * @bios: vbios image pointer | ||
| 113 | * @offset: offset of vbios image data to fetch | ||
| 114 | * @len: length of vbios image data to fetch | ||
| 115 | * | ||
| 116 | * Executes ATRM to fetch a chunk of the discrete | ||
| 117 | * vbios image on PX systems (all asics). | ||
| 118 | * Returns the length of the buffer fetched. | ||
| 119 | */ | ||
| 120 | static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | ||
| 121 | int offset, int len) | ||
| 122 | { | ||
| 123 | acpi_status status; | ||
| 124 | union acpi_object atrm_arg_elements[2], *obj; | ||
| 125 | struct acpi_object_list atrm_arg; | ||
| 126 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
| 127 | |||
| 128 | atrm_arg.count = 2; | ||
| 129 | atrm_arg.pointer = &atrm_arg_elements[0]; | ||
| 130 | |||
| 131 | atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
| 132 | atrm_arg_elements[0].integer.value = offset; | ||
| 133 | |||
| 134 | atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
| 135 | atrm_arg_elements[1].integer.value = len; | ||
| 136 | |||
| 137 | status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); | ||
| 138 | if (ACPI_FAILURE(status)) { | ||
| 139 | printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); | ||
| 140 | return -ENODEV; | ||
| 141 | } | ||
| 142 | |||
| 143 | obj = (union acpi_object *)buffer.pointer; | ||
| 144 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); | ||
| 145 | len = obj->buffer.length; | ||
| 146 | kfree(buffer.pointer); | ||
| 147 | return len; | ||
| 148 | } | ||
| 149 | |||
| 104 | static bool radeon_atrm_get_bios(struct radeon_device *rdev) | 150 | static bool radeon_atrm_get_bios(struct radeon_device *rdev) |
| 105 | { | 151 | { |
| 106 | int ret; | 152 | int ret; |
| 107 | int size = 256 * 1024; | 153 | int size = 256 * 1024; |
| 108 | int i; | 154 | int i; |
| 155 | struct pci_dev *pdev = NULL; | ||
| 156 | acpi_handle dhandle, atrm_handle; | ||
| 157 | acpi_status status; | ||
| 158 | bool found = false; | ||
| 159 | |||
| 160 | /* ATRM is for the discrete card only */ | ||
| 161 | if (rdev->flags & RADEON_IS_IGP) | ||
| 162 | return false; | ||
| 163 | |||
| 164 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { | ||
| 165 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | ||
| 166 | if (!dhandle) | ||
| 167 | continue; | ||
| 168 | |||
| 169 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||
| 170 | if (!ACPI_FAILURE(status)) { | ||
| 171 | found = true; | ||
| 172 | break; | ||
| 173 | } | ||
| 174 | } | ||
| 109 | 175 | ||
| 110 | if (!radeon_atrm_supported(rdev->pdev)) | 176 | if (!found) |
| 111 | return false; | 177 | return false; |
| 112 | 178 | ||
| 113 | rdev->bios = kmalloc(size, GFP_KERNEL); | 179 | rdev->bios = kmalloc(size, GFP_KERNEL); |
| @@ -117,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
| 117 | } | 183 | } |
| 118 | 184 | ||
| 119 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { | 185 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { |
| 120 | ret = radeon_atrm_get_bios_chunk(rdev->bios, | 186 | ret = radeon_atrm_call(atrm_handle, |
| 121 | (i * ATRM_BIOS_PAGE), | 187 | rdev->bios, |
| 122 | ATRM_BIOS_PAGE); | 188 | (i * ATRM_BIOS_PAGE), |
| 189 | ATRM_BIOS_PAGE); | ||
| 123 | if (ret < ATRM_BIOS_PAGE) | 190 | if (ret < ATRM_BIOS_PAGE) |
| 124 | break; | 191 | break; |
| 125 | } | 192 | } |
| @@ -130,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
| 130 | } | 197 | } |
| 131 | return true; | 198 | return true; |
| 132 | } | 199 | } |
| 200 | #else | ||
| 201 | static inline bool radeon_atrm_get_bios(struct radeon_device *rdev) | ||
| 202 | { | ||
| 203 | return false; | ||
| 204 | } | ||
| 205 | #endif | ||
| 133 | 206 | ||
| 134 | static bool ni_read_disabled_bios(struct radeon_device *rdev) | 207 | static bool ni_read_disabled_bios(struct radeon_device *rdev) |
| 135 | { | 208 | { |
| @@ -476,6 +549,61 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) | |||
| 476 | return legacy_read_disabled_bios(rdev); | 549 | return legacy_read_disabled_bios(rdev); |
| 477 | } | 550 | } |
| 478 | 551 | ||
| 552 | #ifdef CONFIG_ACPI | ||
| 553 | static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) | ||
| 554 | { | ||
| 555 | bool ret = false; | ||
| 556 | struct acpi_table_header *hdr; | ||
| 557 | acpi_size tbl_size; | ||
| 558 | UEFI_ACPI_VFCT *vfct; | ||
| 559 | GOP_VBIOS_CONTENT *vbios; | ||
| 560 | VFCT_IMAGE_HEADER *vhdr; | ||
| 561 | |||
| 562 | if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) | ||
| 563 | return false; | ||
| 564 | if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { | ||
| 565 | DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); | ||
| 566 | goto out_unmap; | ||
| 567 | } | ||
| 568 | |||
| 569 | vfct = (UEFI_ACPI_VFCT *)hdr; | ||
| 570 | if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { | ||
| 571 | DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); | ||
| 572 | goto out_unmap; | ||
| 573 | } | ||
| 574 | |||
| 575 | vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); | ||
| 576 | vhdr = &vbios->VbiosHeader; | ||
| 577 | DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", | ||
| 578 | vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, | ||
| 579 | vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); | ||
| 580 | |||
| 581 | if (vhdr->PCIBus != rdev->pdev->bus->number || | ||
| 582 | vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) || | ||
| 583 | vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) || | ||
| 584 | vhdr->VendorID != rdev->pdev->vendor || | ||
| 585 | vhdr->DeviceID != rdev->pdev->device) { | ||
| 586 | DRM_INFO("ACPI VFCT table is not for this card\n"); | ||
| 587 | goto out_unmap; | ||
| 588 | }; | ||
| 589 | |||
| 590 | if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { | ||
| 591 | DRM_ERROR("ACPI VFCT image truncated\n"); | ||
| 592 | goto out_unmap; | ||
| 593 | } | ||
| 594 | |||
| 595 | rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); | ||
| 596 | ret = !!rdev->bios; | ||
| 597 | |||
| 598 | out_unmap: | ||
| 599 | return ret; | ||
| 600 | } | ||
| 601 | #else | ||
| 602 | static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) | ||
| 603 | { | ||
| 604 | return false; | ||
| 605 | } | ||
| 606 | #endif | ||
| 479 | 607 | ||
| 480 | bool radeon_get_bios(struct radeon_device *rdev) | 608 | bool radeon_get_bios(struct radeon_device *rdev) |
| 481 | { | 609 | { |
| @@ -484,6 +612,8 @@ bool radeon_get_bios(struct radeon_device *rdev) | |||
| 484 | 612 | ||
| 485 | r = radeon_atrm_get_bios(rdev); | 613 | r = radeon_atrm_get_bios(rdev); |
| 486 | if (r == false) | 614 | if (r == false) |
| 615 | r = radeon_acpi_vfct_bios(rdev); | ||
| 616 | if (r == false) | ||
| 487 | r = igp_read_bios_from_vram(rdev); | 617 | r = igp_read_bios_from_vram(rdev); |
| 488 | if (r == false) | 618 | if (r == false) |
| 489 | r = radeon_read_bios(rdev); | 619 | r = radeon_read_bios(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 576f4f6919f2..f75247d42ffd 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -719,6 +719,34 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde | |||
| 719 | return i2c; | 719 | return i2c; |
| 720 | } | 720 | } |
| 721 | 721 | ||
| 722 | static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) | ||
| 723 | { | ||
| 724 | struct drm_device *dev = rdev->ddev; | ||
| 725 | struct radeon_i2c_bus_rec i2c; | ||
| 726 | u16 offset; | ||
| 727 | u8 id, blocks, clk, data; | ||
| 728 | int i; | ||
| 729 | |||
| 730 | i2c.valid = false; | ||
| 731 | |||
| 732 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | ||
| 733 | if (offset) { | ||
| 734 | blocks = RBIOS8(offset + 2); | ||
| 735 | for (i = 0; i < blocks; i++) { | ||
| 736 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
| 737 | if (id == 136) { | ||
| 738 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
| 739 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
| 740 | /* gpiopad */ | ||
| 741 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
| 742 | (1 << clk), (1 << data)); | ||
| 743 | break; | ||
| 744 | } | ||
| 745 | } | ||
| 746 | } | ||
| 747 | return i2c; | ||
| 748 | } | ||
| 749 | |||
| 722 | void radeon_combios_i2c_init(struct radeon_device *rdev) | 750 | void radeon_combios_i2c_init(struct radeon_device *rdev) |
| 723 | { | 751 | { |
| 724 | struct drm_device *dev = rdev->ddev; | 752 | struct drm_device *dev = rdev->ddev; |
| @@ -755,30 +783,14 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
| 755 | } else if (rdev->family == CHIP_RS300 || | 783 | } else if (rdev->family == CHIP_RS300 || |
| 756 | rdev->family == CHIP_RS400 || | 784 | rdev->family == CHIP_RS400 || |
| 757 | rdev->family == CHIP_RS480) { | 785 | rdev->family == CHIP_RS480) { |
| 758 | u16 offset; | ||
| 759 | u8 id, blocks, clk, data; | ||
| 760 | int i; | ||
| 761 | |||
| 762 | /* 0x68 */ | 786 | /* 0x68 */ |
| 763 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 787 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
| 764 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); | 788 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
| 765 | 789 | ||
| 766 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | 790 | /* gpiopad */ |
| 767 | if (offset) { | 791 | i2c = radeon_combios_get_i2c_info_from_table(rdev); |
| 768 | blocks = RBIOS8(offset + 2); | 792 | if (i2c.valid) |
| 769 | for (i = 0; i < blocks; i++) { | 793 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); |
| 770 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
| 771 | if (id == 136) { | ||
| 772 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
| 773 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
| 774 | /* gpiopad */ | ||
| 775 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
| 776 | (1 << clk), (1 << data)); | ||
| 777 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | } | ||
| 781 | } | ||
| 782 | } else if ((rdev->family == CHIP_R200) || | 794 | } else if ((rdev->family == CHIP_R200) || |
| 783 | (rdev->family >= CHIP_R300)) { | 795 | (rdev->family >= CHIP_R300)) { |
| 784 | /* 0x68 */ | 796 | /* 0x68 */ |
| @@ -2321,7 +2333,10 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
| 2321 | connector = (tmp >> 12) & 0xf; | 2333 | connector = (tmp >> 12) & 0xf; |
| 2322 | 2334 | ||
| 2323 | ddc_type = (tmp >> 8) & 0xf; | 2335 | ddc_type = (tmp >> 8) & 0xf; |
| 2324 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | 2336 | if (ddc_type == 5) |
| 2337 | ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); | ||
| 2338 | else | ||
| 2339 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | ||
| 2325 | 2340 | ||
| 2326 | switch (connector) { | 2341 | switch (connector) { |
| 2327 | case CONNECTOR_PROPRIETARY_LEGACY: | 2342 | case CONNECTOR_PROPRIETARY_LEGACY: |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 8a4c49ef0cc4..b4a0db24f4dd 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -278,6 +278,30 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
| 278 | return 0; | 278 | return 0; |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, | ||
| 282 | struct radeon_fence *fence) | ||
| 283 | { | ||
| 284 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
| 285 | struct radeon_vm *vm = &fpriv->vm; | ||
| 286 | struct radeon_bo_list *lobj; | ||
| 287 | |||
| 288 | if (parser->chunk_ib_idx == -1) { | ||
| 289 | return; | ||
| 290 | } | ||
| 291 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { | ||
| 292 | return; | ||
| 293 | } | ||
| 294 | |||
| 295 | list_for_each_entry(lobj, &parser->validated, tv.head) { | ||
| 296 | struct radeon_bo_va *bo_va; | ||
| 297 | struct radeon_bo *rbo = lobj->bo; | ||
| 298 | |||
| 299 | bo_va = radeon_bo_va(rbo, vm); | ||
| 300 | radeon_fence_unref(&bo_va->fence); | ||
| 301 | bo_va->fence = radeon_fence_ref(fence); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 281 | /** | 305 | /** |
| 282 | * cs_parser_fini() - clean parser states | 306 | * cs_parser_fini() - clean parser states |
| 283 | * @parser: parser structure holding parsing context. | 307 | * @parser: parser structure holding parsing context. |
| @@ -290,11 +314,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
| 290 | { | 314 | { |
| 291 | unsigned i; | 315 | unsigned i; |
| 292 | 316 | ||
| 293 | if (!error) | 317 | if (!error) { |
| 318 | /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ | ||
| 319 | radeon_bo_vm_fence_va(parser, parser->ib.fence); | ||
| 294 | ttm_eu_fence_buffer_objects(&parser->validated, | 320 | ttm_eu_fence_buffer_objects(&parser->validated, |
| 295 | parser->ib.fence); | 321 | parser->ib.fence); |
| 296 | else | 322 | } else { |
| 297 | ttm_eu_backoff_reservation(&parser->validated); | 323 | ttm_eu_backoff_reservation(&parser->validated); |
| 324 | } | ||
| 298 | 325 | ||
| 299 | if (parser->relocs != NULL) { | 326 | if (parser->relocs != NULL) { |
| 300 | for (i = 0; i < parser->nrelocs; i++) { | 327 | for (i = 0; i < parser->nrelocs; i++) { |
| @@ -388,7 +415,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
| 388 | 415 | ||
| 389 | if (parser->chunk_ib_idx == -1) | 416 | if (parser->chunk_ib_idx == -1) |
| 390 | return 0; | 417 | return 0; |
| 391 | |||
| 392 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 418 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
| 393 | return 0; | 419 | return 0; |
| 394 | 420 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 711e95ad39bf..8794744cdf1a 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
| @@ -67,7 +67,8 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) | |||
| 67 | 67 | ||
| 68 | if (ASIC_IS_DCE4(rdev)) { | 68 | if (ASIC_IS_DCE4(rdev)) { |
| 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
| 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
| 71 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
| 71 | } else if (ASIC_IS_AVIVO(rdev)) { | 72 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 72 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 73 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
| 73 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 74 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
| @@ -94,7 +95,8 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
| 94 | if (ASIC_IS_DCE4(rdev)) { | 95 | if (ASIC_IS_DCE4(rdev)) { |
| 95 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 96 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
| 96 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | | 97 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
| 97 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 98 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
| 99 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
| 98 | } else if (ASIC_IS_AVIVO(rdev)) { | 100 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 101 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
| 100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | | 102 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 742af8244e89..7a3daebd732d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1009 | atomic_set(&rdev->ih.lock, 0); | 1009 | atomic_set(&rdev->ih.lock, 0); |
| 1010 | mutex_init(&rdev->gem.mutex); | 1010 | mutex_init(&rdev->gem.mutex); |
| 1011 | mutex_init(&rdev->pm.mutex); | 1011 | mutex_init(&rdev->pm.mutex); |
| 1012 | mutex_init(&rdev->gpu_clock_mutex); | ||
| 1012 | init_rwsem(&rdev->pm.mclk_lock); | 1013 | init_rwsem(&rdev->pm.mclk_lock); |
| 1013 | init_rwsem(&rdev->exclusive_lock); | 1014 | init_rwsem(&rdev->exclusive_lock); |
| 1014 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1015 | init_waitqueue_head(&rdev->irq.vblank_queue); |
| @@ -1050,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 1050 | if (rdev->flags & RADEON_IS_AGP) | 1051 | if (rdev->flags & RADEON_IS_AGP) |
| 1051 | rdev->need_dma32 = true; | 1052 | rdev->need_dma32 = true; |
| 1052 | if ((rdev->flags & RADEON_IS_PCI) && | 1053 | if ((rdev->flags & RADEON_IS_PCI) && |
| 1053 | (rdev->family < CHIP_RS400)) | 1054 | (rdev->family <= CHIP_RS740)) |
| 1054 | rdev->need_dma32 = true; | 1055 | rdev->need_dma32 = true; |
| 1055 | 1056 | ||
| 1056 | dma_bits = rdev->need_dma32 ? 32 : 40; | 1057 | dma_bits = rdev->need_dma32 ? 32 : 40; |
| @@ -1345,12 +1346,15 @@ retry: | |||
| 1345 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1346 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
| 1346 | radeon_ring_restore(rdev, &rdev->ring[i], | 1347 | radeon_ring_restore(rdev, &rdev->ring[i], |
| 1347 | ring_sizes[i], ring_data[i]); | 1348 | ring_sizes[i], ring_data[i]); |
| 1349 | ring_sizes[i] = 0; | ||
| 1350 | ring_data[i] = NULL; | ||
| 1348 | } | 1351 | } |
| 1349 | 1352 | ||
| 1350 | r = radeon_ib_ring_tests(rdev); | 1353 | r = radeon_ib_ring_tests(rdev); |
| 1351 | if (r) { | 1354 | if (r) { |
| 1352 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); | 1355 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); |
| 1353 | if (saved) { | 1356 | if (saved) { |
| 1357 | saved = false; | ||
| 1354 | radeon_suspend(rdev); | 1358 | radeon_suspend(rdev); |
| 1355 | goto retry; | 1359 | goto retry; |
| 1356 | } | 1360 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dcea6f01ae4e..8c593ea82c41 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -59,9 +59,14 @@ | |||
| 59 | * 2.15.0 - add max_pipes query | 59 | * 2.15.0 - add max_pipes query |
| 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation | 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation |
| 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx | 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx |
| 62 | * 2.18.0 - r600-eg: allow "invalid" DB formats | ||
| 63 | * 2.19.0 - r600-eg: MSAA textures | ||
| 64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | ||
| 65 | * 2.21.0 - r600-r700: FMASK and CMASK | ||
| 66 | * 2.22.0 - r600 only: RESOLVE_BOX allowed | ||
| 62 | */ | 67 | */ |
| 63 | #define KMS_DRIVER_MAJOR 2 | 68 | #define KMS_DRIVER_MAJOR 2 |
| 64 | #define KMS_DRIVER_MINOR 17 | 69 | #define KMS_DRIVER_MINOR 22 |
| 65 | #define KMS_DRIVER_PATCHLEVEL 0 | 70 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 66 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 71 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
| 67 | int radeon_driver_unload_kms(struct drm_device *dev); | 72 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b3720054614d..bb3b7fe05ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
| @@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
| 814 | return -EINVAL; | 814 | return -EINVAL; |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | if (bo_va->valid) | 817 | if (bo_va->valid && mem) |
| 818 | return 0; | 818 | return 0; |
| 819 | 819 | ||
| 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
| @@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
| 859 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
| 860 | { | 860 | { |
| 861 | struct radeon_bo_va *bo_va; | 861 | struct radeon_bo_va *bo_va; |
| 862 | int r; | ||
| 862 | 863 | ||
| 863 | bo_va = radeon_bo_va(bo, vm); | 864 | bo_va = radeon_bo_va(bo, vm); |
| 864 | if (bo_va == NULL) | 865 | if (bo_va == NULL) |
| 865 | return 0; | 866 | return 0; |
| 866 | 867 | ||
| 868 | /* wait for va use to end */ | ||
| 869 | while (bo_va->fence) { | ||
| 870 | r = radeon_fence_wait(bo_va->fence, false); | ||
| 871 | if (r) { | ||
| 872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
| 873 | } | ||
| 874 | if (r == -EDEADLK) { | ||
| 875 | r = radeon_gpu_reset(rdev); | ||
| 876 | if (!r) | ||
| 877 | continue; | ||
| 878 | } | ||
| 879 | break; | ||
| 880 | } | ||
| 881 | radeon_fence_unref(&bo_va->fence); | ||
| 882 | |||
| 867 | mutex_lock(&rdev->vm_manager.lock); | 883 | mutex_lock(&rdev->vm_manager.lock); |
| 868 | mutex_lock(&vm->mutex); | 884 | mutex_lock(&vm->mutex); |
| 869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
| @@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 934 | } | 950 | } |
| 935 | 951 | ||
| 936 | /** | 952 | /** |
| 937 | * radeon_vm_init - tear down a vm instance | 953 | * radeon_vm_fini - tear down a vm instance |
| 938 | * | 954 | * |
| 939 | * @rdev: radeon_device pointer | 955 | * @rdev: radeon_device pointer |
| 940 | * @vm: requested vm | 956 | * @vm: requested vm |
| @@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 952 | radeon_vm_unbind_locked(rdev, vm); | 968 | radeon_vm_unbind_locked(rdev, vm); |
| 953 | mutex_unlock(&rdev->vm_manager.lock); | 969 | mutex_unlock(&rdev->vm_manager.lock); |
| 954 | 970 | ||
| 955 | /* remove all bo */ | 971 | /* remove all bo at this point non are busy any more because unbind |
| 972 | * waited for the last vm fence to signal | ||
| 973 | */ | ||
| 956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
| 957 | if (!r) { | 975 | if (!r) { |
| 958 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); |
| 959 | list_del_init(&bo_va->bo_list); | 977 | list_del_init(&bo_va->bo_list); |
| 960 | list_del_init(&bo_va->vm_list); | 978 | list_del_init(&bo_va->vm_list); |
| 979 | radeon_fence_unref(&bo_va->fence); | ||
| 961 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
| 962 | kfree(bo_va); | 981 | kfree(bo_va); |
| 963 | } | 982 | } |
| @@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
| 969 | r = radeon_bo_reserve(bo_va->bo, false); | 988 | r = radeon_bo_reserve(bo_va->bo, false); |
| 970 | if (!r) { | 989 | if (!r) { |
| 971 | list_del_init(&bo_va->bo_list); | 990 | list_del_init(&bo_va->bo_list); |
| 991 | radeon_fence_unref(&bo_va->fence); | ||
| 972 | radeon_bo_unreserve(bo_va->bo); | 992 | radeon_bo_unreserve(bo_va->bo); |
| 973 | kfree(bo_va); | 993 | kfree(bo_va); |
| 974 | } | 994 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 84d045245739..1b57b0058ad6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
| 134 | struct radeon_device *rdev = rbo->rdev; | 134 | struct radeon_device *rdev = rbo->rdev; |
| 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
| 136 | struct radeon_vm *vm = &fpriv->vm; | 136 | struct radeon_vm *vm = &fpriv->vm; |
| 137 | struct radeon_bo_va *bo_va, *tmp; | ||
| 138 | 137 | ||
| 139 | if (rdev->family < CHIP_CAYMAN) { | 138 | if (rdev->family < CHIP_CAYMAN) { |
| 140 | return; | 139 | return; |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | if (radeon_bo_reserve(rbo, false)) { | 142 | if (radeon_bo_reserve(rbo, false)) { |
| 143 | dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); | ||
| 144 | return; | 144 | return; |
| 145 | } | 145 | } |
| 146 | list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { | 146 | radeon_vm_bo_rmv(rdev, vm, rbo); |
| 147 | if (bo_va->vm == vm) { | ||
| 148 | /* remove from this vm address space */ | ||
| 149 | mutex_lock(&vm->mutex); | ||
| 150 | list_del(&bo_va->vm_list); | ||
| 151 | mutex_unlock(&vm->mutex); | ||
| 152 | list_del(&bo_va->bo_list); | ||
| 153 | kfree(bo_va); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | radeon_bo_unreserve(rbo); | 147 | radeon_bo_unreserve(rbo); |
| 157 | } | 148 | } |
| 158 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 1d73f16b5d97..414b4acf6947 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "drm_sarea.h" | 29 | #include "drm_sarea.h" |
| 30 | #include "radeon.h" | 30 | #include "radeon.h" |
| 31 | #include "radeon_drm.h" | 31 | #include "radeon_drm.h" |
| 32 | #include "radeon_asic.h" | ||
| 32 | 33 | ||
| 33 | #include <linux/vga_switcheroo.h> | 34 | #include <linux/vga_switcheroo.h> |
| 34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| @@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, | |||
| 167 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 168 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
| 168 | { | 169 | { |
| 169 | struct radeon_device *rdev = dev->dev_private; | 170 | struct radeon_device *rdev = dev->dev_private; |
| 170 | struct drm_radeon_info *info; | 171 | struct drm_radeon_info *info = data; |
| 171 | struct radeon_mode_info *minfo = &rdev->mode_info; | 172 | struct radeon_mode_info *minfo = &rdev->mode_info; |
| 172 | uint32_t *value_ptr; | 173 | uint32_t value, *value_ptr; |
| 173 | uint32_t value; | 174 | uint64_t value64, *value_ptr64; |
| 174 | struct drm_crtc *crtc; | 175 | struct drm_crtc *crtc; |
| 175 | int i, found; | 176 | int i, found; |
| 176 | 177 | ||
| 177 | info = data; | 178 | /* TIMESTAMP is a 64-bit value, needs special handling. */ |
| 179 | if (info->request == RADEON_INFO_TIMESTAMP) { | ||
| 180 | if (rdev->family >= CHIP_R600) { | ||
| 181 | value_ptr64 = (uint64_t*)((unsigned long)info->value); | ||
| 182 | if (rdev->family >= CHIP_TAHITI) { | ||
| 183 | value64 = si_get_gpu_clock(rdev); | ||
| 184 | } else { | ||
| 185 | value64 = r600_get_gpu_clock(rdev); | ||
| 186 | } | ||
| 187 | |||
| 188 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { | ||
| 189 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); | ||
| 190 | return -EFAULT; | ||
| 191 | } | ||
| 192 | return 0; | ||
| 193 | } else { | ||
| 194 | DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); | ||
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 178 | value_ptr = (uint32_t *)((unsigned long)info->value); | 199 | value_ptr = (uint32_t *)((unsigned long)info->value); |
| 179 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) | 200 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { |
| 201 | DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); | ||
| 180 | return -EFAULT; | 202 | return -EFAULT; |
| 203 | } | ||
| 181 | 204 | ||
| 182 | switch (info->request) { | 205 | switch (info->request) { |
| 183 | case RADEON_INFO_DEVICE_ID: | 206 | case RADEON_INFO_DEVICE_ID: |
| @@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 337 | return -EINVAL; | 360 | return -EINVAL; |
| 338 | } | 361 | } |
| 339 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { | 362 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { |
| 340 | DRM_ERROR("copy_to_user\n"); | 363 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); |
| 341 | return -EFAULT; | 364 | return -EFAULT; |
| 342 | } | 365 | } |
| 343 | return 0; | 366 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index d5fd615897ec..94b4a1c12893 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1025 | 1025 | ||
| 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
| 1027 | { | 1027 | { |
| 1028 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1028 | struct drm_device *dev = crtc->dev; | 1029 | struct drm_device *dev = crtc->dev; |
| 1029 | struct drm_crtc *crtci; | 1030 | struct drm_crtc *crtci; |
| 1030 | 1031 | ||
| 1032 | radeon_crtc->in_mode_set = true; | ||
| 1031 | /* | 1033 | /* |
| 1032 | * The hardware wedges sometimes if you reconfigure one CRTC | 1034 | * The hardware wedges sometimes if you reconfigure one CRTC |
| 1033 | * whilst another is running (see fdo bug #24611). | 1035 | * whilst another is running (see fdo bug #24611). |
| @@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) | |||
| 1038 | 1040 | ||
| 1039 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1041 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
| 1040 | { | 1042 | { |
| 1043 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 1041 | struct drm_device *dev = crtc->dev; | 1044 | struct drm_device *dev = crtc->dev; |
| 1042 | struct drm_crtc *crtci; | 1045 | struct drm_crtc *crtci; |
| 1043 | 1046 | ||
| @@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) | |||
| 1048 | if (crtci->enabled) | 1051 | if (crtci->enabled) |
| 1049 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | 1052 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
| 1050 | } | 1053 | } |
| 1054 | radeon_crtc->in_mode_set = false; | ||
| 1051 | } | 1055 | } |
| 1052 | 1056 | ||
| 1053 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1057 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f380d59c5763..d56978949f34 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -275,6 +275,7 @@ struct radeon_crtc { | |||
| 275 | u16 lut_r[256], lut_g[256], lut_b[256]; | 275 | u16 lut_r[256], lut_g[256], lut_b[256]; |
| 276 | bool enabled; | 276 | bool enabled; |
| 277 | bool can_tile; | 277 | bool can_tile; |
| 278 | bool in_mode_set; | ||
| 278 | uint32_t crtc_offset; | 279 | uint32_t crtc_offset; |
| 279 | struct drm_gem_object *cursor_bo; | 280 | struct drm_gem_object *cursor_bo; |
| 280 | uint64_t cursor_addr; | 281 | uint64_t cursor_addr; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1f1a4c803c1d..9024e7222839 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
| @@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo) | |||
| 52 | 52 | ||
| 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { | 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { |
| 54 | /* remove from all vm address space */ | 54 | /* remove from all vm address space */ |
| 55 | mutex_lock(&bo_va->vm->mutex); | 55 | radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); |
| 56 | list_del(&bo_va->vm_list); | ||
| 57 | mutex_unlock(&bo_va->vm->mutex); | ||
| 58 | list_del(&bo_va->bo_list); | ||
| 59 | kfree(bo_va); | ||
| 60 | } | 56 | } |
| 61 | } | 57 | } |
| 62 | 58 | ||
| @@ -136,6 +132,7 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
| 136 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, | 132 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, |
| 137 | sizeof(struct radeon_bo)); | 133 | sizeof(struct radeon_bo)); |
| 138 | 134 | ||
| 135 | retry: | ||
| 139 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 136 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
| 140 | if (bo == NULL) | 137 | if (bo == NULL) |
| 141 | return -ENOMEM; | 138 | return -ENOMEM; |
| @@ -149,8 +146,6 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
| 149 | bo->surface_reg = -1; | 146 | bo->surface_reg = -1; |
| 150 | INIT_LIST_HEAD(&bo->list); | 147 | INIT_LIST_HEAD(&bo->list); |
| 151 | INIT_LIST_HEAD(&bo->va); | 148 | INIT_LIST_HEAD(&bo->va); |
| 152 | |||
| 153 | retry: | ||
| 154 | radeon_ttm_placement_from_domain(bo, domain); | 149 | radeon_ttm_placement_from_domain(bo, domain); |
| 155 | /* Kernel allocation are uninterruptible */ | 150 | /* Kernel allocation are uninterruptible */ |
| 156 | down_read(&rdev->pm.mclk_lock); | 151 | down_read(&rdev->pm.mclk_lock); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index ec79b3750430..43c431a2686d 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
| @@ -706,6 +706,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
| 706 | if (radeon_debugfs_ring_init(rdev, ring)) { | 706 | if (radeon_debugfs_ring_init(rdev, ring)) { |
| 707 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 707 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
| 708 | } | 708 | } |
| 709 | radeon_ring_lockup_update(ring); | ||
| 709 | return 0; | 710 | return 0; |
| 710 | } | 711 | } |
| 711 | 712 | ||
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 5e659b034d9a..20bfbda7b3f1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
| @@ -744,15 +744,6 @@ r600 0x9400 | |||
| 744 | 0x00028C38 CB_CLRCMP_DST | 744 | 0x00028C38 CB_CLRCMP_DST |
| 745 | 0x00028C3C CB_CLRCMP_MSK | 745 | 0x00028C3C CB_CLRCMP_MSK |
| 746 | 0x00028C34 CB_CLRCMP_SRC | 746 | 0x00028C34 CB_CLRCMP_SRC |
| 747 | 0x00028100 CB_COLOR0_MASK | ||
| 748 | 0x00028104 CB_COLOR1_MASK | ||
| 749 | 0x00028108 CB_COLOR2_MASK | ||
| 750 | 0x0002810C CB_COLOR3_MASK | ||
| 751 | 0x00028110 CB_COLOR4_MASK | ||
| 752 | 0x00028114 CB_COLOR5_MASK | ||
| 753 | 0x00028118 CB_COLOR6_MASK | ||
| 754 | 0x0002811C CB_COLOR7_MASK | ||
| 755 | 0x00028808 CB_COLOR_CONTROL | ||
| 756 | 0x0002842C CB_FOG_BLUE | 747 | 0x0002842C CB_FOG_BLUE |
| 757 | 0x00028428 CB_FOG_GREEN | 748 | 0x00028428 CB_FOG_GREEN |
| 758 | 0x00028424 CB_FOG_RED | 749 | 0x00028424 CB_FOG_RED |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index a12fbcc8ccb6..aa8ef491ef3c 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
| 281 | 281 | ||
| 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
| 283 | { | 283 | { |
| 284 | save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); | ||
| 285 | save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); | ||
| 286 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | 284 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); |
| 287 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | 285 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); |
| 288 | save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); | ||
| 289 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | ||
| 290 | 286 | ||
| 291 | /* Stop all video */ | 287 | /* Stop all video */ |
| 292 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 288 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
| @@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
| 311 | /* Unlock host access */ | 307 | /* Unlock host access */ |
| 312 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 308 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
| 313 | mdelay(1); | 309 | mdelay(1); |
| 314 | /* Restore video state */ | ||
| 315 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
| 316 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
| 317 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
| 318 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
| 319 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | ||
| 320 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | ||
| 321 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
| 322 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
| 323 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
| 324 | } | 311 | } |
| 325 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c053f8193771..0139e227e3c7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -1639,11 +1639,19 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
| 1639 | /* XXX what about 12? */ | 1639 | /* XXX what about 12? */ |
| 1640 | rdev->config.si.tile_config |= (3 << 0); | 1640 | rdev->config.si.tile_config |= (3 << 0); |
| 1641 | break; | 1641 | break; |
| 1642 | } | 1642 | } |
| 1643 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1643 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
| 1644 | rdev->config.si.tile_config |= 1 << 4; | 1644 | case 0: /* four banks */ |
| 1645 | else | ||
| 1646 | rdev->config.si.tile_config |= 0 << 4; | 1645 | rdev->config.si.tile_config |= 0 << 4; |
| 1646 | break; | ||
| 1647 | case 1: /* eight banks */ | ||
| 1648 | rdev->config.si.tile_config |= 1 << 4; | ||
| 1649 | break; | ||
| 1650 | case 2: /* sixteen banks */ | ||
| 1651 | default: | ||
| 1652 | rdev->config.si.tile_config |= 2 << 4; | ||
| 1653 | break; | ||
| 1654 | } | ||
| 1647 | rdev->config.si.tile_config |= | 1655 | rdev->config.si.tile_config |= |
| 1648 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 1656 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
| 1649 | rdev->config.si.tile_config |= | 1657 | rdev->config.si.tile_config |= |
| @@ -3960,3 +3968,22 @@ void si_fini(struct radeon_device *rdev) | |||
| 3960 | rdev->bios = NULL; | 3968 | rdev->bios = NULL; |
| 3961 | } | 3969 | } |
| 3962 | 3970 | ||
| 3971 | /** | ||
| 3972 | * si_get_gpu_clock - return GPU clock counter snapshot | ||
| 3973 | * | ||
| 3974 | * @rdev: radeon_device pointer | ||
| 3975 | * | ||
| 3976 | * Fetches a GPU clock counter snapshot (SI). | ||
| 3977 | * Returns the 64 bit clock counter snapshot. | ||
| 3978 | */ | ||
| 3979 | uint64_t si_get_gpu_clock(struct radeon_device *rdev) | ||
| 3980 | { | ||
| 3981 | uint64_t clock; | ||
| 3982 | |||
| 3983 | mutex_lock(&rdev->gpu_clock_mutex); | ||
| 3984 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
| 3985 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
| 3986 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
| 3987 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
| 3988 | return clock; | ||
| 3989 | } | ||
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7869089e8761..ef4815c27b1c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
| @@ -698,6 +698,9 @@ | |||
| 698 | #define RLC_UCODE_ADDR 0xC32C | 698 | #define RLC_UCODE_ADDR 0xC32C |
| 699 | #define RLC_UCODE_DATA 0xC330 | 699 | #define RLC_UCODE_DATA 0xC330 |
| 700 | 700 | ||
| 701 | #define RLC_GPU_CLOCK_COUNT_LSB 0xC338 | ||
| 702 | #define RLC_GPU_CLOCK_COUNT_MSB 0xC33C | ||
| 703 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 | ||
| 701 | #define RLC_MC_CNTL 0xC344 | 704 | #define RLC_MC_CNTL 0xC344 |
| 702 | #define RLC_UCODE_CNTL 0xC348 | 705 | #define RLC_UCODE_CNTL 0xC348 |
| 703 | 706 | ||
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index 0b5e096d39a6..56e0bf31d425 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | config DRM_UDL | 1 | config DRM_UDL |
| 2 | tristate "DisplayLink" | 2 | tristate "DisplayLink" |
| 3 | depends on DRM && EXPERIMENTAL | 3 | depends on DRM && EXPERIMENTAL |
| 4 | depends on USB_ARCH_HAS_HCD | ||
| 4 | select DRM_USB | 5 | select DRM_USB |
| 5 | select FB_SYS_FILLRECT | 6 | select FB_SYS_FILLRECT |
| 6 | select FB_SYS_COPYAREA | 7 | select FB_SYS_COPYAREA |
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 7bd65bdd15a8..291ecc145585 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c | |||
| @@ -308,7 +308,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, | |||
| 308 | /* need to attach */ | 308 | /* need to attach */ |
| 309 | attach = dma_buf_attach(dma_buf, dev->dev); | 309 | attach = dma_buf_attach(dma_buf, dev->dev); |
| 310 | if (IS_ERR(attach)) | 310 | if (IS_ERR(attach)) |
| 311 | return ERR_PTR(PTR_ERR(attach)); | 311 | return ERR_CAST(attach); |
| 312 | 312 | ||
| 313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | 313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); |
| 314 | if (IS_ERR(sg)) { | 314 | if (IS_ERR(sg)) { |
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index f5dd89e891de..9159d48d1dfd 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c | |||
| @@ -354,8 +354,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, | |||
| 354 | 354 | ||
| 355 | static void udl_crtc_disable(struct drm_crtc *crtc) | 355 | static void udl_crtc_disable(struct drm_crtc *crtc) |
| 356 | { | 356 | { |
| 357 | 357 | udl_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | |
| 358 | |||
| 359 | } | 358 | } |
| 360 | 359 | ||
| 361 | static void udl_crtc_destroy(struct drm_crtc *crtc) | 360 | static void udl_crtc_destroy(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 6b0078ffa763..c50724bd30f6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -1688,15 +1688,19 @@ int vmw_du_page_flip(struct drm_crtc *crtc, | |||
| 1688 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); | 1688 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); |
| 1689 | struct drm_framebuffer *old_fb = crtc->fb; | 1689 | struct drm_framebuffer *old_fb = crtc->fb; |
| 1690 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); | 1690 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); |
| 1691 | struct drm_file *file_priv = event->base.file_priv; | 1691 | struct drm_file *file_priv ; |
| 1692 | struct vmw_fence_obj *fence = NULL; | 1692 | struct vmw_fence_obj *fence = NULL; |
| 1693 | struct drm_clip_rect clips; | 1693 | struct drm_clip_rect clips; |
| 1694 | int ret; | 1694 | int ret; |
| 1695 | 1695 | ||
| 1696 | if (event == NULL) | ||
| 1697 | return -EINVAL; | ||
| 1698 | |||
| 1696 | /* require ScreenObject support for page flipping */ | 1699 | /* require ScreenObject support for page flipping */ |
| 1697 | if (!dev_priv->sou_priv) | 1700 | if (!dev_priv->sou_priv) |
| 1698 | return -ENOSYS; | 1701 | return -ENOSYS; |
| 1699 | 1702 | ||
| 1703 | file_priv = event->base.file_priv; | ||
| 1700 | if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) | 1704 | if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) |
| 1701 | return -EINVAL; | 1705 | return -EINVAL; |
| 1702 | 1706 | ||
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 5b3c7d135dc9..e25cf31faab2 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
| @@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = { | |||
| 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), | 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | 73 | static bool vga_switcheroo_ready(void) |
| 74 | { | ||
| 75 | mutex_lock(&vgasr_mutex); | ||
| 76 | if (vgasr_priv.handler) { | ||
| 77 | mutex_unlock(&vgasr_mutex); | ||
| 78 | return -EINVAL; | ||
| 79 | } | ||
| 80 | |||
| 81 | vgasr_priv.handler = handler; | ||
| 82 | mutex_unlock(&vgasr_mutex); | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
| 86 | |||
| 87 | void vga_switcheroo_unregister_handler(void) | ||
| 88 | { | 74 | { |
| 89 | mutex_lock(&vgasr_mutex); | 75 | /* we're ready if we get two clients + handler */ |
| 90 | vgasr_priv.handler = NULL; | 76 | return !vgasr_priv.active && |
| 91 | mutex_unlock(&vgasr_mutex); | 77 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler; |
| 92 | } | 78 | } |
| 93 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
| 94 | 79 | ||
| 95 | static void vga_switcheroo_enable(void) | 80 | static void vga_switcheroo_enable(void) |
| 96 | { | 81 | { |
| @@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void) | |||
| 98 | struct vga_switcheroo_client *client; | 83 | struct vga_switcheroo_client *client; |
| 99 | 84 | ||
| 100 | /* call the handler to init */ | 85 | /* call the handler to init */ |
| 101 | vgasr_priv.handler->init(); | 86 | if (vgasr_priv.handler->init) |
| 87 | vgasr_priv.handler->init(); | ||
| 102 | 88 | ||
| 103 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 89 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
| 104 | if (client->id != -1) | 90 | if (client->id != -1) |
| @@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void) | |||
| 113 | vgasr_priv.active = true; | 99 | vgasr_priv.active = true; |
| 114 | } | 100 | } |
| 115 | 101 | ||
| 102 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | ||
| 103 | { | ||
| 104 | mutex_lock(&vgasr_mutex); | ||
| 105 | if (vgasr_priv.handler) { | ||
| 106 | mutex_unlock(&vgasr_mutex); | ||
| 107 | return -EINVAL; | ||
| 108 | } | ||
| 109 | |||
| 110 | vgasr_priv.handler = handler; | ||
| 111 | if (vga_switcheroo_ready()) { | ||
| 112 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | ||
| 113 | vga_switcheroo_enable(); | ||
| 114 | } | ||
| 115 | mutex_unlock(&vgasr_mutex); | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
| 119 | |||
| 120 | void vga_switcheroo_unregister_handler(void) | ||
| 121 | { | ||
| 122 | mutex_lock(&vgasr_mutex); | ||
| 123 | vgasr_priv.handler = NULL; | ||
| 124 | if (vgasr_priv.active) { | ||
| 125 | pr_info("vga_switcheroo: disabled\n"); | ||
| 126 | vga_switcheroo_debugfs_fini(&vgasr_priv); | ||
| 127 | vgasr_priv.active = false; | ||
| 128 | } | ||
| 129 | mutex_unlock(&vgasr_mutex); | ||
| 130 | } | ||
| 131 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
| 132 | |||
| 116 | static int register_client(struct pci_dev *pdev, | 133 | static int register_client(struct pci_dev *pdev, |
| 117 | const struct vga_switcheroo_client_ops *ops, | 134 | const struct vga_switcheroo_client_ops *ops, |
| 118 | int id, bool active) | 135 | int id, bool active) |
| @@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev, | |||
| 134 | if (client_is_vga(client)) | 151 | if (client_is_vga(client)) |
| 135 | vgasr_priv.registered_clients++; | 152 | vgasr_priv.registered_clients++; |
| 136 | 153 | ||
| 137 | /* if we get two clients + handler */ | 154 | if (vga_switcheroo_ready()) { |
| 138 | if (!vgasr_priv.active && | ||
| 139 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler) { | ||
| 140 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | 155 | printk(KERN_INFO "vga_switcheroo: enabled\n"); |
| 141 | vga_switcheroo_enable(); | 156 | vga_switcheroo_enable(); |
| 142 | } | 157 | } |
