mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 17:51:43 +00:00
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
This commit is contained in:
commit
67f33f30fc
@ -4803,7 +4803,7 @@ struct bonaire_mqd
|
||||
*/
|
||||
static int cik_cp_compute_resume(struct radeon_device *rdev)
|
||||
{
|
||||
int r, i, idx;
|
||||
int r, i, j, idx;
|
||||
u32 tmp;
|
||||
bool use_doorbell = true;
|
||||
u64 hqd_gpu_addr;
|
||||
@ -4922,7 +4922,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
|
||||
mqd->queue_state.cp_hqd_pq_wptr= 0;
|
||||
if (RREG32(CP_HQD_ACTIVE) & 1) {
|
||||
WREG32(CP_HQD_DEQUEUE_REQUEST, 1);
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
for (j = 0; j < rdev->usec_timeout; j++) {
|
||||
if (!(RREG32(CP_HQD_ACTIVE) & 1))
|
||||
break;
|
||||
udelay(1);
|
||||
@ -7751,17 +7751,17 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev)
|
||||
wptr = RREG32(IH_RB_WPTR);
|
||||
|
||||
if (wptr & RB_OVERFLOW) {
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
/* When a ring buffer overflow happen start parsing interrupt
|
||||
* from the last not overwritten vector (wptr + 16). Hopefully
|
||||
* this should allow us to catchup.
|
||||
*/
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
|
||||
rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
|
||||
tmp = RREG32(IH_RB_CNTL);
|
||||
tmp |= IH_WPTR_OVERFLOW_CLEAR;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
}
|
||||
return (wptr & rdev->ih.ptr_mask);
|
||||
}
|
||||
@ -8251,6 +8251,7 @@ restart_ih:
|
||||
/* wptr/rptr are in bytes! */
|
||||
rptr += 16;
|
||||
rptr &= rdev->ih.ptr_mask;
|
||||
WREG32(IH_RB_RPTR, rptr);
|
||||
}
|
||||
if (queue_hotplug)
|
||||
schedule_work(&rdev->hotplug_work);
|
||||
@ -8259,7 +8260,6 @@ restart_ih:
|
||||
if (queue_thermal)
|
||||
schedule_work(&rdev->pm.dpm.thermal.work);
|
||||
rdev->ih.rptr = rptr;
|
||||
WREG32(IH_RB_RPTR, rdev->ih.rptr);
|
||||
atomic_set(&rdev->ih.lock, 0);
|
||||
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
|
@ -4749,17 +4749,17 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
|
||||
wptr = RREG32(IH_RB_WPTR);
|
||||
|
||||
if (wptr & RB_OVERFLOW) {
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
/* When a ring buffer overflow happen start parsing interrupt
|
||||
* from the last not overwritten vector (wptr + 16). Hopefully
|
||||
* this should allow us to catchup.
|
||||
*/
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
|
||||
rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
|
||||
tmp = RREG32(IH_RB_CNTL);
|
||||
tmp |= IH_WPTR_OVERFLOW_CLEAR;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
}
|
||||
return (wptr & rdev->ih.ptr_mask);
|
||||
}
|
||||
@ -5137,6 +5137,7 @@ restart_ih:
|
||||
/* wptr/rptr are in bytes! */
|
||||
rptr += 16;
|
||||
rptr &= rdev->ih.ptr_mask;
|
||||
WREG32(IH_RB_RPTR, rptr);
|
||||
}
|
||||
if (queue_hotplug)
|
||||
schedule_work(&rdev->hotplug_work);
|
||||
@ -5145,7 +5146,6 @@ restart_ih:
|
||||
if (queue_thermal && rdev->pm.dpm_enabled)
|
||||
schedule_work(&rdev->pm.dpm.thermal.work);
|
||||
rdev->ih.rptr = rptr;
|
||||
WREG32(IH_RB_RPTR, rdev->ih.rptr);
|
||||
atomic_set(&rdev->ih.lock, 0);
|
||||
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
|
@ -3792,17 +3792,17 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev)
|
||||
wptr = RREG32(IH_RB_WPTR);
|
||||
|
||||
if (wptr & RB_OVERFLOW) {
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
/* When a ring buffer overflow happen start parsing interrupt
|
||||
* from the last not overwritten vector (wptr + 16). Hopefully
|
||||
* this should allow us to catchup.
|
||||
*/
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
|
||||
rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
|
||||
tmp = RREG32(IH_RB_CNTL);
|
||||
tmp |= IH_WPTR_OVERFLOW_CLEAR;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
}
|
||||
return (wptr & rdev->ih.ptr_mask);
|
||||
}
|
||||
@ -4048,6 +4048,7 @@ restart_ih:
|
||||
/* wptr/rptr are in bytes! */
|
||||
rptr += 16;
|
||||
rptr &= rdev->ih.ptr_mask;
|
||||
WREG32(IH_RB_RPTR, rptr);
|
||||
}
|
||||
if (queue_hotplug)
|
||||
schedule_work(&rdev->hotplug_work);
|
||||
@ -4056,7 +4057,6 @@ restart_ih:
|
||||
if (queue_thermal && rdev->pm.dpm_enabled)
|
||||
schedule_work(&rdev->pm.dpm.thermal.work);
|
||||
rdev->ih.rptr = rptr;
|
||||
WREG32(IH_RB_RPTR, rdev->ih.rptr);
|
||||
atomic_set(&rdev->ih.lock, 0);
|
||||
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
|
@ -106,6 +106,7 @@ extern int radeon_vm_block_size;
|
||||
extern int radeon_deep_color;
|
||||
extern int radeon_use_pflipirq;
|
||||
extern int radeon_bapm;
|
||||
extern int radeon_backlight;
|
||||
|
||||
/*
|
||||
* Copy from radeon_drv.h so we don't have to include both and have conflicting
|
||||
|
@ -123,6 +123,10 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = {
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=51381
|
||||
*/
|
||||
{ PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX },
|
||||
/* Asus K53TK laptop with AMD A6-3420M APU and Radeon 7670m GPU
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=51381
|
||||
*/
|
||||
{ PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX },
|
||||
/* macbook pro 8.2 */
|
||||
{ PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP },
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
|
@ -181,6 +181,7 @@ int radeon_vm_block_size = -1;
|
||||
int radeon_deep_color = 0;
|
||||
int radeon_use_pflipirq = 2;
|
||||
int radeon_bapm = -1;
|
||||
int radeon_backlight = -1;
|
||||
|
||||
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
|
||||
module_param_named(no_wb, radeon_no_wb, int, 0444);
|
||||
@ -263,6 +264,9 @@ module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444);
|
||||
MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)");
|
||||
module_param_named(bapm, radeon_bapm, int, 0444);
|
||||
|
||||
MODULE_PARM_DESC(backlight, "backlight support (1 = enable, 0 = disable, -1 = auto)");
|
||||
module_param_named(backlight, radeon_backlight, int, 0444);
|
||||
|
||||
static struct pci_device_id pciidlist[] = {
|
||||
radeon_PCI_IDS
|
||||
};
|
||||
|
@ -158,10 +158,43 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = radeon_encoder->base.dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
bool use_bl = false;
|
||||
|
||||
if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)))
|
||||
return;
|
||||
|
||||
if (radeon_backlight == 0) {
|
||||
return;
|
||||
} else if (radeon_backlight == 1) {
|
||||
use_bl = true;
|
||||
} else if (radeon_backlight == -1) {
|
||||
/* Quirks */
|
||||
/* Amilo Xi 2550 only works with acpi bl */
|
||||
if ((rdev->pdev->device == 0x9583) &&
|
||||
(rdev->pdev->subsystem_vendor == 0x1734) &&
|
||||
(rdev->pdev->subsystem_device == 0x1107))
|
||||
use_bl = false;
|
||||
else
|
||||
use_bl = true;
|
||||
}
|
||||
|
||||
if (use_bl) {
|
||||
if (rdev->is_atom_bios)
|
||||
radeon_atom_backlight_init(radeon_encoder, connector);
|
||||
else
|
||||
radeon_legacy_backlight_init(radeon_encoder, connector);
|
||||
rdev->mode_info.bl_encoder = radeon_encoder;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radeon_link_encoder_connector(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_connector *connector;
|
||||
struct radeon_connector *radeon_connector;
|
||||
struct drm_encoder *encoder;
|
||||
@ -174,13 +207,8 @@ radeon_link_encoder_connector(struct drm_device *dev)
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
if (radeon_encoder->devices & radeon_connector->devices) {
|
||||
drm_mode_connector_attach_encoder(connector, encoder);
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
if (rdev->is_atom_bios)
|
||||
radeon_atom_backlight_init(radeon_encoder, connector);
|
||||
else
|
||||
radeon_legacy_backlight_init(radeon_encoder, connector);
|
||||
rdev->mode_info.bl_encoder = radeon_encoder;
|
||||
}
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
|
||||
radeon_encoder_add_backlight(radeon_encoder, connector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6316,17 +6316,17 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
|
||||
wptr = RREG32(IH_RB_WPTR);
|
||||
|
||||
if (wptr & RB_OVERFLOW) {
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
/* When a ring buffer overflow happen start parsing interrupt
|
||||
* from the last not overwritten vector (wptr + 16). Hopefully
|
||||
* this should allow us to catchup.
|
||||
*/
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
|
||||
dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
|
||||
wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
|
||||
rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
|
||||
tmp = RREG32(IH_RB_CNTL);
|
||||
tmp |= IH_WPTR_OVERFLOW_CLEAR;
|
||||
WREG32(IH_RB_CNTL, tmp);
|
||||
wptr &= ~RB_OVERFLOW;
|
||||
}
|
||||
return (wptr & rdev->ih.ptr_mask);
|
||||
}
|
||||
@ -6664,13 +6664,13 @@ restart_ih:
|
||||
/* wptr/rptr are in bytes! */
|
||||
rptr += 16;
|
||||
rptr &= rdev->ih.ptr_mask;
|
||||
WREG32(IH_RB_RPTR, rptr);
|
||||
}
|
||||
if (queue_hotplug)
|
||||
schedule_work(&rdev->hotplug_work);
|
||||
if (queue_thermal && rdev->pm.dpm_enabled)
|
||||
schedule_work(&rdev->pm.dpm.thermal.work);
|
||||
rdev->ih.rptr = rptr;
|
||||
WREG32(IH_RB_RPTR, rdev->ih.rptr);
|
||||
atomic_set(&rdev->ih.lock, 0);
|
||||
|
||||
/* make sure wptr hasn't changed while processing */
|
||||
|
Loading…
Reference in New Issue
Block a user