aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/cik.c12
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c8
-rw-r--r--drivers/gpu/drm/radeon/r600.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c44
-rw-r--r--drivers/gpu/drm/radeon/si.c8
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 */
4804static int cik_cp_compute_resume(struct radeon_device *rdev) 4804static 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;
106extern int radeon_deep_color; 106extern int radeon_deep_color;
107extern int radeon_use_pflipirq; 107extern int radeon_use_pflipirq;
108extern int radeon_bapm; 108extern int radeon_bapm;
109extern 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;
181int radeon_deep_color = 0; 181int radeon_deep_color = 0;
182int radeon_use_pflipirq = 2; 182int radeon_use_pflipirq = 2;
183int radeon_bapm = -1; 183int radeon_bapm = -1;
184int radeon_backlight = -1;
184 185
185MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); 186MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
186module_param_named(no_wb, radeon_no_wb, int, 0444); 187module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -263,6 +264,9 @@ module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444);
263MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); 264MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)");
264module_param_named(bapm, radeon_bapm, int, 0444); 265module_param_named(bapm, radeon_bapm, int, 0444);
265 266
267MODULE_PARM_DESC(backlight, "backlight support (1 = enable, 0 = disable, -1 = auto)");
268module_param_named(backlight, radeon_backlight, int, 0444);
269
266static struct pci_device_id pciidlist[] = { 270static 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
161static 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
161void 195void
162radeon_link_encoder_connector(struct drm_device *dev) 196radeon_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 */