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 | ||
