aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2011-02-02 18:42:03 -0500
committerDave Airlie <airlied@redhat.com>2011-02-03 18:46:35 -0500
commit0975b16274bad1f0bd5c5fd6ab759c5a9ee11949 (patch)
tree522e6af52e285c3616976709f868aa07e38c8cbe /drivers/gpu
parent87364760de5d631390c478fcbac8db1b926e0adf (diff)
drm/radeon/kms: dynamically allocate power state space
We previously used a static array, but some new systems had more states then we had array space, so dynamically allocate space based on the number of states in the vbios. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=33851 Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Cc: stable@kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c40
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c3
4 files changed, 42 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4f29d445d038..56c48b67ef3d 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -812,8 +812,7 @@ struct radeon_pm {
812 fixed20_12 sclk; 812 fixed20_12 sclk;
813 fixed20_12 mclk; 813 fixed20_12 mclk;
814 fixed20_12 needed_bandwidth; 814 fixed20_12 needed_bandwidth;
815 /* XXX: use a define for num power modes */ 815 struct radeon_power_state *power_state;
816 struct radeon_power_state power_state[8];
817 /* number of valid power states */ 816 /* number of valid power states */
818 int num_power_states; 817 int num_power_states;
819 int current_power_state_index; 818 int current_power_state_index;
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index b64e6034b45f..5c1cc7ad9a15 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1977,6 +1977,9 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev)
1977 num_modes = power_info->info.ucNumOfPowerModeEntries; 1977 num_modes = power_info->info.ucNumOfPowerModeEntries;
1978 if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) 1978 if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)
1979 num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; 1979 num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK;
1980 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL);
1981 if (!rdev->pm.power_state)
1982 return state_index;
1980 /* last mode is usually default, array is low to high */ 1983 /* last mode is usually default, array is low to high */
1981 for (i = 0; i < num_modes; i++) { 1984 for (i = 0; i < num_modes; i++) {
1982 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 1985 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
@@ -2328,6 +2331,10 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev)
2328 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); 2331 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2329 2332
2330 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); 2333 radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController);
2334 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2335 power_info->pplib.ucNumStates, GFP_KERNEL);
2336 if (!rdev->pm.power_state)
2337 return state_index;
2331 /* first mode is usually default, followed by low to high */ 2338 /* first mode is usually default, followed by low to high */
2332 for (i = 0; i < power_info->pplib.ucNumStates; i++) { 2339 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
2333 mode_index = 0; 2340 mode_index = 0;
@@ -2408,6 +2415,10 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev)
2408 non_clock_info_array = (struct NonClockInfoArray *) 2415 non_clock_info_array = (struct NonClockInfoArray *)
2409 (mode_info->atom_context->bios + data_offset + 2416 (mode_info->atom_context->bios + data_offset +
2410 power_info->pplib.usNonClockInfoArrayOffset); 2417 power_info->pplib.usNonClockInfoArrayOffset);
2418 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) *
2419 state_array->ucNumEntries, GFP_KERNEL);
2420 if (!rdev->pm.power_state)
2421 return state_index;
2411 for (i = 0; i < state_array->ucNumEntries; i++) { 2422 for (i = 0; i < state_array->ucNumEntries; i++) {
2412 mode_index = 0; 2423 mode_index = 0;
2413 power_state = (union pplib_power_state *)&state_array->states[i]; 2424 power_state = (union pplib_power_state *)&state_array->states[i];
@@ -2481,19 +2492,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)
2481 break; 2492 break;
2482 } 2493 }
2483 } else { 2494 } else {
2484 /* add the default mode */ 2495 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL);
2485 rdev->pm.power_state[state_index].type = 2496 if (rdev->pm.power_state) {
2486 POWER_STATE_TYPE_DEFAULT; 2497 /* add the default mode */
2487 rdev->pm.power_state[state_index].num_clock_modes = 1; 2498 rdev->pm.power_state[state_index].type =
2488 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; 2499 POWER_STATE_TYPE_DEFAULT;
2489 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; 2500 rdev->pm.power_state[state_index].num_clock_modes = 1;
2490 rdev->pm.power_state[state_index].default_clock_mode = 2501 rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk;
2491 &rdev->pm.power_state[state_index].clock_info[0]; 2502 rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk;
2492 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; 2503 rdev->pm.power_state[state_index].default_clock_mode =
2493 rdev->pm.power_state[state_index].pcie_lanes = 16; 2504 &rdev->pm.power_state[state_index].clock_info[0];
2494 rdev->pm.default_power_state_index = state_index; 2505 rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
2495 rdev->pm.power_state[state_index].flags = 0; 2506 rdev->pm.power_state[state_index].pcie_lanes = 16;
2496 state_index++; 2507 rdev->pm.default_power_state_index = state_index;
2508 rdev->pm.power_state[state_index].flags = 0;
2509 state_index++;
2510 }
2497 } 2511 }
2498 2512
2499 rdev->pm.num_power_states = state_index; 2513 rdev->pm.num_power_states = state_index;
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 591fcae8f224..d27ef74590cd 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -2442,6 +2442,17 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev)
2442 2442
2443 rdev->pm.default_power_state_index = -1; 2443 rdev->pm.default_power_state_index = -1;
2444 2444
2445 /* allocate 2 power states */
2446 rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * 2, GFP_KERNEL);
2447 if (!rdev->pm.power_state) {
2448 rdev->pm.default_power_state_index = state_index;
2449 rdev->pm.num_power_states = 0;
2450
2451 rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
2452 rdev->pm.current_clock_mode_index = 0;
2453 return;
2454 }
2455
2445 if (rdev->flags & RADEON_IS_MOBILITY) { 2456 if (rdev->flags & RADEON_IS_MOBILITY) {
2446 offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE); 2457 offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
2447 if (offset) { 2458 if (offset) {
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 813620034a33..2aed03bde4b2 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -646,6 +646,9 @@ void radeon_pm_fini(struct radeon_device *rdev)
646#endif 646#endif
647 } 647 }
648 648
649 if (rdev->pm.power_state)
650 kfree(rdev->pm.power_state);
651
649 radeon_hwmon_fini(rdev); 652 radeon_hwmon_fini(rdev);
650} 653}
651 654