aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2014-07-18 11:54:20 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-08-05 08:53:36 -0400
commit4807c5a8a0c87a210c36e3ad74c451a909d88588 (patch)
tree0e786a121073e3e3e3491838f60e7eaecf95bf2b
parent391bfec33cd4e103274f197924d41ef648b849de (diff)
drm/radeon: add a PX quirk list
Some PX laptops seems to have problems turning the dGPU on/off. Add a quirk list to disable runpm by default on those systems. Also convert the current PX d3 delay handling to a quirk. bug: https://bugzilla.kernel.org/show_bug.cgi?id=51381 https://bugzilla.kernel.org/show_bug.cgi?id=74551 Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c70
2 files changed, 51 insertions, 20 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f9ffd98aa6a4..8d0ce11ef47b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2353,6 +2353,7 @@ struct radeon_device {
2353 2353
2354 struct dev_pm_domain vga_pm_domain; 2354 struct dev_pm_domain vga_pm_domain;
2355 bool have_disp_power_ref; 2355 bool have_disp_power_ref;
2356 u32 px_quirk_flags;
2356 2357
2357 /* tracking pinned memory */ 2358 /* tracking pinned memory */
2358 u64 vram_pin_size; 2359 u64 vram_pin_size;
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 61990bda285d..248bce86af51 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -103,6 +103,31 @@ static const char radeon_family_name[][16] = {
103 "LAST", 103 "LAST",
104}; 104};
105 105
106#define RADEON_PX_QUIRK_DISABLE_PX (1 << 0)
107#define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1)
108
109struct radeon_px_quirk {
110 u32 chip_vendor;
111 u32 chip_device;
112 u32 subsys_vendor;
113 u32 subsys_device;
114 u32 px_quirk_flags;
115};
116
117static struct radeon_px_quirk radeon_px_quirk_list[] = {
118 /* Acer aspire 5560g (CPU: AMD A4-3305M; GPU: AMD Radeon HD 6480g + 7470m)
119 * https://bugzilla.kernel.org/show_bug.cgi?id=74551
120 */
121 { PCI_VENDOR_ID_ATI, 0x6760, 0x1025, 0x0672, RADEON_PX_QUIRK_DISABLE_PX },
122 /* Asus K73TA laptop with AMD A6-3400M APU and Radeon 6550 GPU
123 * https://bugzilla.kernel.org/show_bug.cgi?id=51381
124 */
125 { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX },
126 /* macbook pro 8.2 */
127 { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP },
128 { 0, 0, 0, 0, 0 },
129};
130
106bool radeon_is_px(struct drm_device *dev) 131bool radeon_is_px(struct drm_device *dev)
107{ 132{
108 struct radeon_device *rdev = dev->dev_private; 133 struct radeon_device *rdev = dev->dev_private;
@@ -112,6 +137,26 @@ bool radeon_is_px(struct drm_device *dev)
112 return false; 137 return false;
113} 138}
114 139
140static void radeon_device_handle_px_quirks(struct radeon_device *rdev)
141{
142 struct radeon_px_quirk *p = radeon_px_quirk_list;
143
144 /* Apply PX quirks */
145 while (p && p->chip_device != 0) {
146 if (rdev->pdev->vendor == p->chip_vendor &&
147 rdev->pdev->device == p->chip_device &&
148 rdev->pdev->subsystem_vendor == p->subsys_vendor &&
149 rdev->pdev->subsystem_device == p->subsys_device) {
150 rdev->px_quirk_flags = p->px_quirk_flags;
151 break;
152 }
153 ++p;
154 }
155
156 if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX)
157 rdev->flags &= ~RADEON_IS_PX;
158}
159
115/** 160/**
116 * radeon_program_register_sequence - program an array of registers. 161 * radeon_program_register_sequence - program an array of registers.
117 * 162 *
@@ -1093,25 +1138,6 @@ static void radeon_check_arguments(struct radeon_device *rdev)
1093} 1138}
1094 1139
1095/** 1140/**
1096 * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is
1097 * needed for waking up.
1098 *
1099 * @pdev: pci dev pointer
1100 */
1101static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
1102{
1103
1104 /* 6600m in a macbook pro */
1105 if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
1106 pdev->subsystem_device == 0x00e2) {
1107 printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n");
1108 return true;
1109 }
1110
1111 return false;
1112}
1113
1114/**
1115 * radeon_switcheroo_set_state - set switcheroo state 1141 * radeon_switcheroo_set_state - set switcheroo state
1116 * 1142 *
1117 * @pdev: pci dev pointer 1143 * @pdev: pci dev pointer
@@ -1123,6 +1149,7 @@ static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
1123static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) 1149static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
1124{ 1150{
1125 struct drm_device *dev = pci_get_drvdata(pdev); 1151 struct drm_device *dev = pci_get_drvdata(pdev);
1152 struct radeon_device *rdev = dev->dev_private;
1126 1153
1127 if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF) 1154 if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF)
1128 return; 1155 return;
@@ -1134,7 +1161,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
1134 /* don't suspend or resume card normally */ 1161 /* don't suspend or resume card normally */
1135 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 1162 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
1136 1163
1137 if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) 1164 if (d3_delay < 20 && (rdev->px_quirk_flags & RADEON_PX_QUIRK_LONG_WAKEUP))
1138 dev->pdev->d3_delay = 20; 1165 dev->pdev->d3_delay = 20;
1139 1166
1140 radeon_resume_kms(dev, true, true); 1167 radeon_resume_kms(dev, true, true);
@@ -1338,6 +1365,9 @@ int radeon_device_init(struct radeon_device *rdev,
1338 if (rdev->rio_mem == NULL) 1365 if (rdev->rio_mem == NULL)
1339 DRM_ERROR("Unable to find PCI I/O BAR\n"); 1366 DRM_ERROR("Unable to find PCI I/O BAR\n");
1340 1367
1368 if (rdev->flags & RADEON_IS_PX)
1369 radeon_device_handle_px_quirks(rdev);
1370
1341 /* if we have > 1 VGA cards, then disable the radeon VGA resources */ 1371 /* if we have > 1 VGA cards, then disable the radeon VGA resources */
1342 /* this will fail for cards that aren't VGA class devices, just 1372 /* this will fail for cards that aren't VGA class devices, just
1343 * ignore it */ 1373 * ignore it */