diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2011-09-01 13:46:15 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-09-02 04:40:20 -0400 |
commit | d054ac16eeb658bccadb06b12c39cee22243b10f (patch) | |
tree | 22a3382e7ceb3469e6723cf6ce42828e42a35df6 /drivers/gpu/drm/radeon/evergreen.c | |
parent | 9adceaa5b3d2480e2252c4a7f9c4bd7d66b8c4a2 (diff) |
drm/radeon/kms: make sure pci max read request size is valid on evergreen+ (v2)
If the bios or OS sets the pci max read request size to 0 or an
invalid value (6,7), it can result in a hang or slowdown. Check
and set it to something sane if it's invalid.
Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=42162
v2: use pci reg defines from include/linux/pci_regs.h
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@kernel.org
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d8d71a399f52..dc0a5b56c81a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -41,6 +41,31 @@ static void evergreen_gpu_init(struct radeon_device *rdev); | |||
41 | void evergreen_fini(struct radeon_device *rdev); | 41 | void evergreen_fini(struct radeon_device *rdev); |
42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | 42 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); |
43 | 43 | ||
44 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | ||
45 | { | ||
46 | u16 ctl, v; | ||
47 | int cap, err; | ||
48 | |||
49 | cap = pci_pcie_cap(rdev->pdev); | ||
50 | if (!cap) | ||
51 | return; | ||
52 | |||
53 | err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); | ||
54 | if (err) | ||
55 | return; | ||
56 | |||
57 | v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; | ||
58 | |||
59 | /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it | ||
60 | * to avoid hangs or perfomance issues | ||
61 | */ | ||
62 | if ((v == 0) || (v == 6) || (v == 7)) { | ||
63 | ctl &= ~PCI_EXP_DEVCTL_READRQ; | ||
64 | ctl |= (2 << 12); | ||
65 | pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); | ||
66 | } | ||
67 | } | ||
68 | |||
44 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) | 69 | void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) |
45 | { | 70 | { |
46 | /* enable the pflip int */ | 71 | /* enable the pflip int */ |
@@ -1863,6 +1888,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1863 | 1888 | ||
1864 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); | 1889 | WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); |
1865 | 1890 | ||
1891 | evergreen_fix_pci_max_read_req_size(rdev); | ||
1892 | |||
1866 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; | 1893 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2; |
1867 | 1894 | ||
1868 | cc_gc_shader_pipe_config |= | 1895 | cc_gc_shader_pipe_config |= |