diff options
author | Dave Airlie <airlied@redhat.com> | 2014-09-24 16:49:26 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-09-24 16:49:26 -0400 |
commit | 67f33f30fc3cb7896cbdbd25c70395d38bfa9520 (patch) | |
tree | 5b51ed3930f99b9b9233c820416142f919fe2293 /drivers/gpu | |
parent | 65e7e5d8f99edef129a3d6ca4467227272823fe3 (diff) | |
parent | 370ce45b5986118fa496dddbcd7039e1aa1a418f (diff) |
Merge branch 'drm-fixes-3.17' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
- fix a backlight regression resulting in dark screen
- add a PX quirk to avoid a hang with runtime pm
- fix an init issue on the CIK compute rings
- fix IH ring buffer overflows gracefully
* 'drm-fixes-3.17' of git://people.freedesktop.org/~agd5f/linux:
drm/radeon/cik: use a separate counter for CP init timeout
drm/radeon: add PX quirk for asus K53TK
drm/radeon: add a backlight quirk for Amilo Xi 2550
drm/radeon: add a module parameter for backlight control (v2)
drm/radeon: Update IH_RB_RPTR register after each processed interrupt
drm/radeon: Make IH ring overflow debugging output more useful
drm/radeon: Clear RB_OVERFLOW bit earlier
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/cik.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 8 |
8 files changed, 63 insertions, 26 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index fa9565957f9d..3d546c606b43 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -4803,7 +4803,7 @@ struct bonaire_mqd | |||
4803 | */ | 4803 | */ |
4804 | static int cik_cp_compute_resume(struct radeon_device *rdev) | 4804 | static int cik_cp_compute_resume(struct radeon_device *rdev) |
4805 | { | 4805 | { |
4806 | int r, i, idx; | 4806 | int r, i, j, idx; |
4807 | u32 tmp; | 4807 | u32 tmp; |
4808 | bool use_doorbell = true; | 4808 | bool use_doorbell = true; |
4809 | u64 hqd_gpu_addr; | 4809 | u64 hqd_gpu_addr; |
@@ -4922,7 +4922,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
4922 | mqd->queue_state.cp_hqd_pq_wptr= 0; | 4922 | mqd->queue_state.cp_hqd_pq_wptr= 0; |
4923 | if (RREG32(CP_HQD_ACTIVE) & 1) { | 4923 | if (RREG32(CP_HQD_ACTIVE) & 1) { |
4924 | WREG32(CP_HQD_DEQUEUE_REQUEST, 1); | 4924 | WREG32(CP_HQD_DEQUEUE_REQUEST, 1); |
4925 | for (i = 0; i < rdev->usec_timeout; i++) { | 4925 | for (j = 0; j < rdev->usec_timeout; j++) { |
4926 | if (!(RREG32(CP_HQD_ACTIVE) & 1)) | 4926 | if (!(RREG32(CP_HQD_ACTIVE) & 1)) |
4927 | break; | 4927 | break; |
4928 | udelay(1); | 4928 | udelay(1); |
@@ -7751,17 +7751,17 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev) | |||
7751 | wptr = RREG32(IH_RB_WPTR); | 7751 | wptr = RREG32(IH_RB_WPTR); |
7752 | 7752 | ||
7753 | if (wptr & RB_OVERFLOW) { | 7753 | if (wptr & RB_OVERFLOW) { |
7754 | wptr &= ~RB_OVERFLOW; | ||
7754 | /* When a ring buffer overflow happen start parsing interrupt | 7755 | /* When a ring buffer overflow happen start parsing interrupt |
7755 | * from the last not overwritten vector (wptr + 16). Hopefully | 7756 | * from the last not overwritten vector (wptr + 16). Hopefully |
7756 | * this should allow us to catchup. | 7757 | * this should allow us to catchup. |
7757 | */ | 7758 | */ |
7758 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 7759 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
7759 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 7760 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
7760 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 7761 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
7761 | tmp = RREG32(IH_RB_CNTL); | 7762 | tmp = RREG32(IH_RB_CNTL); |
7762 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 7763 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
7763 | WREG32(IH_RB_CNTL, tmp); | 7764 | WREG32(IH_RB_CNTL, tmp); |
7764 | wptr &= ~RB_OVERFLOW; | ||
7765 | } | 7765 | } |
7766 | return (wptr & rdev->ih.ptr_mask); | 7766 | return (wptr & rdev->ih.ptr_mask); |
7767 | } | 7767 | } |
@@ -8251,6 +8251,7 @@ restart_ih: | |||
8251 | /* wptr/rptr are in bytes! */ | 8251 | /* wptr/rptr are in bytes! */ |
8252 | rptr += 16; | 8252 | rptr += 16; |
8253 | rptr &= rdev->ih.ptr_mask; | 8253 | rptr &= rdev->ih.ptr_mask; |
8254 | WREG32(IH_RB_RPTR, rptr); | ||
8254 | } | 8255 | } |
8255 | if (queue_hotplug) | 8256 | if (queue_hotplug) |
8256 | schedule_work(&rdev->hotplug_work); | 8257 | schedule_work(&rdev->hotplug_work); |
@@ -8259,7 +8260,6 @@ restart_ih: | |||
8259 | if (queue_thermal) | 8260 | if (queue_thermal) |
8260 | schedule_work(&rdev->pm.dpm.thermal.work); | 8261 | schedule_work(&rdev->pm.dpm.thermal.work); |
8261 | rdev->ih.rptr = rptr; | 8262 | rdev->ih.rptr = rptr; |
8262 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
8263 | atomic_set(&rdev->ih.lock, 0); | 8263 | atomic_set(&rdev->ih.lock, 0); |
8264 | 8264 | ||
8265 | /* make sure wptr hasn't changed while processing */ | 8265 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index dbca60c7d097..e50807c29f69 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -4749,17 +4749,17 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
4749 | wptr = RREG32(IH_RB_WPTR); | 4749 | wptr = RREG32(IH_RB_WPTR); |
4750 | 4750 | ||
4751 | if (wptr & RB_OVERFLOW) { | 4751 | if (wptr & RB_OVERFLOW) { |
4752 | wptr &= ~RB_OVERFLOW; | ||
4752 | /* When a ring buffer overflow happen start parsing interrupt | 4753 | /* When a ring buffer overflow happen start parsing interrupt |
4753 | * from the last not overwritten vector (wptr + 16). Hopefully | 4754 | * from the last not overwritten vector (wptr + 16). Hopefully |
4754 | * this should allow us to catchup. | 4755 | * this should allow us to catchup. |
4755 | */ | 4756 | */ |
4756 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 4757 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
4757 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 4758 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
4758 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 4759 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
4759 | tmp = RREG32(IH_RB_CNTL); | 4760 | tmp = RREG32(IH_RB_CNTL); |
4760 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 4761 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
4761 | WREG32(IH_RB_CNTL, tmp); | 4762 | WREG32(IH_RB_CNTL, tmp); |
4762 | wptr &= ~RB_OVERFLOW; | ||
4763 | } | 4763 | } |
4764 | return (wptr & rdev->ih.ptr_mask); | 4764 | return (wptr & rdev->ih.ptr_mask); |
4765 | } | 4765 | } |
@@ -5137,6 +5137,7 @@ restart_ih: | |||
5137 | /* wptr/rptr are in bytes! */ | 5137 | /* wptr/rptr are in bytes! */ |
5138 | rptr += 16; | 5138 | rptr += 16; |
5139 | rptr &= rdev->ih.ptr_mask; | 5139 | rptr &= rdev->ih.ptr_mask; |
5140 | WREG32(IH_RB_RPTR, rptr); | ||
5140 | } | 5141 | } |
5141 | if (queue_hotplug) | 5142 | if (queue_hotplug) |
5142 | schedule_work(&rdev->hotplug_work); | 5143 | schedule_work(&rdev->hotplug_work); |
@@ -5145,7 +5146,6 @@ restart_ih: | |||
5145 | if (queue_thermal && rdev->pm.dpm_enabled) | 5146 | if (queue_thermal && rdev->pm.dpm_enabled) |
5146 | schedule_work(&rdev->pm.dpm.thermal.work); | 5147 | schedule_work(&rdev->pm.dpm.thermal.work); |
5147 | rdev->ih.rptr = rptr; | 5148 | rdev->ih.rptr = rptr; |
5148 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
5149 | atomic_set(&rdev->ih.lock, 0); | 5149 | atomic_set(&rdev->ih.lock, 0); |
5150 | 5150 | ||
5151 | /* make sure wptr hasn't changed while processing */ | 5151 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 3cfb50056f7a..ea5c9af722ef 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3792,17 +3792,17 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3792 | wptr = RREG32(IH_RB_WPTR); | 3792 | wptr = RREG32(IH_RB_WPTR); |
3793 | 3793 | ||
3794 | if (wptr & RB_OVERFLOW) { | 3794 | if (wptr & RB_OVERFLOW) { |
3795 | wptr &= ~RB_OVERFLOW; | ||
3795 | /* When a ring buffer overflow happen start parsing interrupt | 3796 | /* When a ring buffer overflow happen start parsing interrupt |
3796 | * from the last not overwritten vector (wptr + 16). Hopefully | 3797 | * from the last not overwritten vector (wptr + 16). Hopefully |
3797 | * this should allow us to catchup. | 3798 | * this should allow us to catchup. |
3798 | */ | 3799 | */ |
3799 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 3800 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
3800 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 3801 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
3801 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 3802 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
3802 | tmp = RREG32(IH_RB_CNTL); | 3803 | tmp = RREG32(IH_RB_CNTL); |
3803 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 3804 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
3804 | WREG32(IH_RB_CNTL, tmp); | 3805 | WREG32(IH_RB_CNTL, tmp); |
3805 | wptr &= ~RB_OVERFLOW; | ||
3806 | } | 3806 | } |
3807 | return (wptr & rdev->ih.ptr_mask); | 3807 | return (wptr & rdev->ih.ptr_mask); |
3808 | } | 3808 | } |
@@ -4048,6 +4048,7 @@ restart_ih: | |||
4048 | /* wptr/rptr are in bytes! */ | 4048 | /* wptr/rptr are in bytes! */ |
4049 | rptr += 16; | 4049 | rptr += 16; |
4050 | rptr &= rdev->ih.ptr_mask; | 4050 | rptr &= rdev->ih.ptr_mask; |
4051 | WREG32(IH_RB_RPTR, rptr); | ||
4051 | } | 4052 | } |
4052 | if (queue_hotplug) | 4053 | if (queue_hotplug) |
4053 | schedule_work(&rdev->hotplug_work); | 4054 | schedule_work(&rdev->hotplug_work); |
@@ -4056,7 +4057,6 @@ restart_ih: | |||
4056 | if (queue_thermal && rdev->pm.dpm_enabled) | 4057 | if (queue_thermal && rdev->pm.dpm_enabled) |
4057 | schedule_work(&rdev->pm.dpm.thermal.work); | 4058 | schedule_work(&rdev->pm.dpm.thermal.work); |
4058 | rdev->ih.rptr = rptr; | 4059 | rdev->ih.rptr = rptr; |
4059 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
4060 | atomic_set(&rdev->ih.lock, 0); | 4060 | atomic_set(&rdev->ih.lock, 0); |
4061 | 4061 | ||
4062 | /* make sure wptr hasn't changed while processing */ | 4062 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5f05b4c84338..3247bfd14410 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -106,6 +106,7 @@ extern int radeon_vm_block_size; | |||
106 | extern int radeon_deep_color; | 106 | extern int radeon_deep_color; |
107 | extern int radeon_use_pflipirq; | 107 | extern int radeon_use_pflipirq; |
108 | extern int radeon_bapm; | 108 | extern int radeon_bapm; |
109 | extern int radeon_backlight; | ||
109 | 110 | ||
110 | /* | 111 | /* |
111 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 112 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 75223dd3a8a3..12c8329644c4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -123,6 +123,10 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = { | |||
123 | * https://bugzilla.kernel.org/show_bug.cgi?id=51381 | 123 | * https://bugzilla.kernel.org/show_bug.cgi?id=51381 |
124 | */ | 124 | */ |
125 | { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX }, | 125 | { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX }, |
126 | /* Asus K53TK laptop with AMD A6-3420M APU and Radeon 7670m GPU | ||
127 | * https://bugzilla.kernel.org/show_bug.cgi?id=51381 | ||
128 | */ | ||
129 | { PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX }, | ||
126 | /* macbook pro 8.2 */ | 130 | /* macbook pro 8.2 */ |
127 | { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, | 131 | { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, |
128 | { 0, 0, 0, 0, 0 }, | 132 | { 0, 0, 0, 0, 0 }, |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4126fd0937a2..f9d17b29b343 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -181,6 +181,7 @@ int radeon_vm_block_size = -1; | |||
181 | int radeon_deep_color = 0; | 181 | int radeon_deep_color = 0; |
182 | int radeon_use_pflipirq = 2; | 182 | int radeon_use_pflipirq = 2; |
183 | int radeon_bapm = -1; | 183 | int radeon_bapm = -1; |
184 | int radeon_backlight = -1; | ||
184 | 185 | ||
185 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 186 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
186 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 187 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
@@ -263,6 +264,9 @@ module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444); | |||
263 | MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); | 264 | MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); |
264 | module_param_named(bapm, radeon_bapm, int, 0444); | 265 | module_param_named(bapm, radeon_bapm, int, 0444); |
265 | 266 | ||
267 | MODULE_PARM_DESC(backlight, "backlight support (1 = enable, 0 = disable, -1 = auto)"); | ||
268 | module_param_named(backlight, radeon_backlight, int, 0444); | ||
269 | |||
266 | static struct pci_device_id pciidlist[] = { | 270 | static struct pci_device_id pciidlist[] = { |
267 | radeon_PCI_IDS | 271 | radeon_PCI_IDS |
268 | }; | 272 | }; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 3c2094c25b53..15edf23b465c 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -158,10 +158,43 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8 | |||
158 | return ret; | 158 | return ret; |
159 | } | 159 | } |
160 | 160 | ||
161 | static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder, | ||
162 | struct drm_connector *connector) | ||
163 | { | ||
164 | struct drm_device *dev = radeon_encoder->base.dev; | ||
165 | struct radeon_device *rdev = dev->dev_private; | ||
166 | bool use_bl = false; | ||
167 | |||
168 | if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))) | ||
169 | return; | ||
170 | |||
171 | if (radeon_backlight == 0) { | ||
172 | return; | ||
173 | } else if (radeon_backlight == 1) { | ||
174 | use_bl = true; | ||
175 | } else if (radeon_backlight == -1) { | ||
176 | /* Quirks */ | ||
177 | /* Amilo Xi 2550 only works with acpi bl */ | ||
178 | if ((rdev->pdev->device == 0x9583) && | ||
179 | (rdev->pdev->subsystem_vendor == 0x1734) && | ||
180 | (rdev->pdev->subsystem_device == 0x1107)) | ||
181 | use_bl = false; | ||
182 | else | ||
183 | use_bl = true; | ||
184 | } | ||
185 | |||
186 | if (use_bl) { | ||
187 | if (rdev->is_atom_bios) | ||
188 | radeon_atom_backlight_init(radeon_encoder, connector); | ||
189 | else | ||
190 | radeon_legacy_backlight_init(radeon_encoder, connector); | ||
191 | rdev->mode_info.bl_encoder = radeon_encoder; | ||
192 | } | ||
193 | } | ||
194 | |||
161 | void | 195 | void |
162 | radeon_link_encoder_connector(struct drm_device *dev) | 196 | radeon_link_encoder_connector(struct drm_device *dev) |
163 | { | 197 | { |
164 | struct radeon_device *rdev = dev->dev_private; | ||
165 | struct drm_connector *connector; | 198 | struct drm_connector *connector; |
166 | struct radeon_connector *radeon_connector; | 199 | struct radeon_connector *radeon_connector; |
167 | struct drm_encoder *encoder; | 200 | struct drm_encoder *encoder; |
@@ -174,13 +207,8 @@ radeon_link_encoder_connector(struct drm_device *dev) | |||
174 | radeon_encoder = to_radeon_encoder(encoder); | 207 | radeon_encoder = to_radeon_encoder(encoder); |
175 | if (radeon_encoder->devices & radeon_connector->devices) { | 208 | if (radeon_encoder->devices & radeon_connector->devices) { |
176 | drm_mode_connector_attach_encoder(connector, encoder); | 209 | drm_mode_connector_attach_encoder(connector, encoder); |
177 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 210 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
178 | if (rdev->is_atom_bios) | 211 | radeon_encoder_add_backlight(radeon_encoder, connector); |
179 | radeon_atom_backlight_init(radeon_encoder, connector); | ||
180 | else | ||
181 | radeon_legacy_backlight_init(radeon_encoder, connector); | ||
182 | rdev->mode_info.bl_encoder = radeon_encoder; | ||
183 | } | ||
184 | } | 212 | } |
185 | } | 213 | } |
186 | } | 214 | } |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 6bce40847753..3a0b973e8a96 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -6316,17 +6316,17 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev) | |||
6316 | wptr = RREG32(IH_RB_WPTR); | 6316 | wptr = RREG32(IH_RB_WPTR); |
6317 | 6317 | ||
6318 | if (wptr & RB_OVERFLOW) { | 6318 | if (wptr & RB_OVERFLOW) { |
6319 | wptr &= ~RB_OVERFLOW; | ||
6319 | /* When a ring buffer overflow happen start parsing interrupt | 6320 | /* When a ring buffer overflow happen start parsing interrupt |
6320 | * from the last not overwritten vector (wptr + 16). Hopefully | 6321 | * from the last not overwritten vector (wptr + 16). Hopefully |
6321 | * this should allow us to catchup. | 6322 | * this should allow us to catchup. |
6322 | */ | 6323 | */ |
6323 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 6324 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
6324 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 6325 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
6325 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 6326 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
6326 | tmp = RREG32(IH_RB_CNTL); | 6327 | tmp = RREG32(IH_RB_CNTL); |
6327 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 6328 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
6328 | WREG32(IH_RB_CNTL, tmp); | 6329 | WREG32(IH_RB_CNTL, tmp); |
6329 | wptr &= ~RB_OVERFLOW; | ||
6330 | } | 6330 | } |
6331 | return (wptr & rdev->ih.ptr_mask); | 6331 | return (wptr & rdev->ih.ptr_mask); |
6332 | } | 6332 | } |
@@ -6664,13 +6664,13 @@ restart_ih: | |||
6664 | /* wptr/rptr are in bytes! */ | 6664 | /* wptr/rptr are in bytes! */ |
6665 | rptr += 16; | 6665 | rptr += 16; |
6666 | rptr &= rdev->ih.ptr_mask; | 6666 | rptr &= rdev->ih.ptr_mask; |
6667 | WREG32(IH_RB_RPTR, rptr); | ||
6667 | } | 6668 | } |
6668 | if (queue_hotplug) | 6669 | if (queue_hotplug) |
6669 | schedule_work(&rdev->hotplug_work); | 6670 | schedule_work(&rdev->hotplug_work); |
6670 | if (queue_thermal && rdev->pm.dpm_enabled) | 6671 | if (queue_thermal && rdev->pm.dpm_enabled) |
6671 | schedule_work(&rdev->pm.dpm.thermal.work); | 6672 | schedule_work(&rdev->pm.dpm.thermal.work); |
6672 | rdev->ih.rptr = rptr; | 6673 | rdev->ih.rptr = rptr; |
6673 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
6674 | atomic_set(&rdev->ih.lock, 0); | 6674 | atomic_set(&rdev->ih.lock, 0); |
6675 | 6675 | ||
6676 | /* make sure wptr hasn't changed while processing */ | 6676 | /* make sure wptr hasn't changed while processing */ |