aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2011-11-04 10:09:43 -0400
committerDave Airlie <airlied@redhat.com>2011-11-11 09:16:05 -0500
commit8f3f1c9a22a6420e28c2d3eff59b832893bc8efc (patch)
treefff750d9ccf699b3607ca473791c9e5820e1a7c5 /drivers
parentbbe26ffe9ffd231de7cf88c4361f1939858e8594 (diff)
drm/radeon/kms/pm: switch to dynamically allocating clock mode array
On newer chips the number of clock modes per power state varies. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c118
2 files changed, 82 insertions, 39 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 41f7cd26515b..fc5a1d642cb5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -784,8 +784,7 @@ struct radeon_pm_clock_info {
784 784
785struct radeon_power_state { 785struct radeon_power_state {
786 enum radeon_pm_state_type type; 786 enum radeon_pm_state_type type;
787 /* XXX: use a define for num clock modes */ 787 struct radeon_pm_clock_info *clock_info;
788 struct radeon_pm_clock_info clock_info[8];
789 /* number of valid clock modes in this power state */ 788 /* number of valid clock modes in this power state */
790 int num_clock_modes; 789 int num_clock_modes;
791 struct radeon_pm_clock_info *default_clock_mode; 790 struct radeon_pm_clock_info *default_clock_mode;
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 08d0b94332e6..d2d179267af3 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1999,6 +1999,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
1999 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 1999 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2000 switch (frev) { 2000 switch (frev) {
2001 case 1: 2001 case 1:
2002 rdev->pm.power_state[state_index].clock_info =
2003 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2004 if (!rdev->pm.power_state[state_index].clock_info)
2005 return state_index;
2002 rdev->pm.power_state[state_index].num_clock_modes = 1; 2006 rdev->pm.power_state[state_index].num_clock_modes = 1;
2003 rdev->pm.power_state[state_index].clock_info[0].mclk = 2007 rdev->pm.power_state[state_index].clock_info[0].mclk =
2004 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); 2008 le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock);
@@ -2035,6 +2039,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
2035 state_index++; 2039 state_index++;
2036 break; 2040 break;
2037 case 2: 2041 case 2:
2042 rdev->pm.power_state[state_index].clock_info =
2043 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2044 if (!rdev->pm.power_state[state_index].clock_info)
2045 return state_index;
2038 rdev->pm.power_state[state_index].num_clock_modes = 1; 2046 rdev->pm.power_state[state_index].num_clock_modes = 1;
2039 rdev->pm.power_state[state_index].clock_info[0].mclk = 2047 rdev->pm.power_state[state_index].clock_info[0].mclk =
2040 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); 2048 le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock);
@@ -2072,6 +2080,10 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
2072 state_index++; 2080 state_index++;
2073 break; 2081 break;
2074 case 3: 2082 case 3:
2083 rdev->pm.power_state[state_index].clock_info =
2084 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2085 if (!rdev->pm.power_state[state_index].clock_info)
2086 return state_index;
2075 rdev->pm.power_state[state_index].num_clock_modes = 1; 2087 rdev->pm.power_state[state_index].num_clock_modes = 1;
2076 rdev->pm.power_state[state_index].clock_info[0].mclk = 2088 rdev->pm.power_state[state_index].clock_info[0].mclk =
2077 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); 2089 le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock);
@@ -2257,7 +2269,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
2257 rdev->pm.default_power_state_index = state_index; 2269 rdev->pm.default_power_state_index = state_index;
2258 rdev->pm.power_state[state_index].default_clock_mode = 2270 rdev->pm.power_state[state_index].default_clock_mode =
2259 &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; 2271 &rdev->pm.power_state[state_index].clock_info[mode_index - 1];
2260 if (ASIC_IS_DCE5(rdev)) { 2272 if (ASIC_IS_DCE5(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
2261 /* NI chips post without MC ucode, so default clocks are strobe mode only */ 2273 /* NI chips post without MC ucode, so default clocks are strobe mode only */
2262 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; 2274 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
2263 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; 2275 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
@@ -2377,17 +2389,31 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
2377 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + 2389 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
2378 (power_state->v1.ucNonClockStateIndex * 2390 (power_state->v1.ucNonClockStateIndex *
2379 power_info->pplib.ucNonClockSize)); 2391 power_info->pplib.ucNonClockSize));
2380 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { 2392 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2381 clock_info = (union pplib_clock_info *) 2393 ((power_info->pplib.ucStateEntrySize - 1) ?
2382 (mode_info->atom_context->bios + data_offset + 2394 (power_info->pplib.ucStateEntrySize - 1) : 1),
2383 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + 2395 GFP_KERNEL);
2384 (power_state->v1.ucClockStateIndices[j] * 2396 if (!rdev->pm.power_state[i].clock_info)
2385 power_info->pplib.ucClockInfoSize)); 2397 return state_index;
2386 valid = radeon_atombios_parse_pplib_clock_info(rdev, 2398 if (power_info->pplib.ucStateEntrySize - 1) {
2387 state_index, mode_index, 2399 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
2388 clock_info); 2400 clock_info = (union pplib_clock_info *)
2389 if (valid) 2401 (mode_info->atom_context->bios + data_offset +
2390 mode_index++; 2402 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
2403 (power_state->v1.ucClockStateIndices[j] *
2404 power_info->pplib.ucClockInfoSize));
2405 valid = radeon_atombios_parse_pplib_clock_info(rdev,
2406 state_index, mode_index,
2407 clock_info);
2408 if (valid)
2409 mode_index++;
2410 }
2411 } else {
2412 rdev->pm.power_state[state_index].clock_info[0].mclk =
2413 rdev->clock.default_mclk;
2414 rdev->pm.power_state[state_index].clock_info[0].sclk =
2415 rdev->clock.default_sclk;
2416 mode_index++;
2391 } 2417 }
2392 rdev->pm.power_state[state_index].num_clock_modes = mode_index; 2418 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
2393 if (mode_index) { 2419 if (mode_index) {
@@ -2456,18 +2482,32 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2456 non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ 2482 non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */
2457 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) 2483 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2458 &non_clock_info_array->nonClockInfo[non_clock_array_index]; 2484 &non_clock_info_array->nonClockInfo[non_clock_array_index];
2459 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { 2485 rdev->pm.power_state[i].clock_info = kzalloc(sizeof(struct radeon_pm_clock_info) *
2460 clock_array_index = power_state->v2.clockInfoIndex[j]; 2486 (power_state->v2.ucNumDPMLevels ?
2461 /* XXX this might be an inagua bug... */ 2487 power_state->v2.ucNumDPMLevels : 1),
2462 if (clock_array_index >= clock_info_array->ucNumEntries) 2488 GFP_KERNEL);
2463 continue; 2489 if (!rdev->pm.power_state[i].clock_info)
2464 clock_info = (union pplib_clock_info *) 2490 return state_index;
2465 &clock_info_array->clockInfo[clock_array_index]; 2491 if (power_state->v2.ucNumDPMLevels) {
2466 valid = radeon_atombios_parse_pplib_clock_info(rdev, 2492 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
2467 state_index, mode_index, 2493 clock_array_index = power_state->v2.clockInfoIndex[j];
2468 clock_info); 2494 /* XXX this might be an inagua bug... */
2469 if (valid) 2495 if (clock_array_index >= clock_info_array->ucNumEntries)
2470 mode_index++; 2496 continue;
2497 clock_info = (union pplib_clock_info *)
2498 &clock_info_array->clockInfo[clock_array_index];
2499 valid = radeon_atombios_parse_pplib_clock_info(rdev,
2500 state_index, mode_index,
2501 clock_info);
2502 if (valid)
2503 mode_index++;
2504 }
2505 } else {
2506 rdev->pm.power_state[state_index].clock_info[0].mclk =
2507 rdev->clock.default_mclk;
2508 rdev->pm.power_state[state_index].clock_info[0].sclk =
2509 rdev->clock.default_sclk;
2510 mode_index++;
2471 } 2511 }
2472 rdev->pm.power_state[state_index].num_clock_modes = mode_index; 2512 rdev->pm.power_state[state_index].num_clock_modes = mode_index;
2473 if (mode_index) { 2513 if (mode_index) {
@@ -2524,19 +2564,23 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
2524 } else { 2564 } else {
2525 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); 2565 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
2526 if (rdev->pm.power_state) { 2566 if (rdev->pm.power_state) {
2527 /* add the default mode */ 2567 rdev->pm.power_state[0].clock_info =
2528 rdev->pm.power_state[state_index].type = 2568 kzalloc(sizeof(struct radeon_pm_clock_info) * 1, GFP_KERNEL);
2529 POWER_STATE_TYPE_DEFAULT; 2569 if (rdev->pm.power_state[0].clock_info) {
2530 rdev->pm.power_state[state_index].num_clock_modes = 1; 2570 /* add the default mode */
2531 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; 2571 rdev->pm.power_state[state_index].type =
2532 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; 2572 POWER_STATE_TYPE_DEFAULT;
2533 rdev->pm.power_state[state_index].default_clock_mode = 2573 rdev->pm.power_state[state_index].num_clock_modes = 1;
2534 &rdev->pm.power_state[state_index].clock_info[0]; 2574 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2535 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 2575 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2536 rdev->pm.power_state[state_index].pcie_lanes = 16; 2576 rdev->pm.power_state[state_index].default_clock_mode =
2537 rdev->pm.default_power_state_index = state_index; 2577 &rdev->pm.power_state[state_index].clock_info[0];
2538 rdev->pm.power_state[state_index].flags = 0; 2578 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2539 state_index++; 2579 rdev->pm.power_state[state_index].pcie_lanes = 16;
2580 rdev->pm.default_power_state_index = state_index;
2581 rdev->pm.power_state[state_index].flags = 0;
2582 state_index++;
2583 }
2540 } 2584 }
2541 } 2585 }
2542 2586