diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2011-11-04 10:09:43 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-11-11 09:16:05 -0500 |
commit | 8f3f1c9a22a6420e28c2d3eff59b832893bc8efc (patch) | |
tree | fff750d9ccf699b3607ca473791c9e5820e1a7c5 /drivers | |
parent | bbe26ffe9ffd231de7cf88c4361f1939858e8594 (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.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 118 |
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 | ||
785 | struct radeon_power_state { | 785 | struct 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 | ||