소스 검색

drm/amd/powerplay: original power state table should not be changed.

power state table was set based on vbios and should not be changed.
when client need to change power state, just make a copy and send to
smu.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Rex Zhu 9 년 전
부모
커밋
48fad3aff6
3개의 변경된 파일16개의 추가작업 그리고 5개의 파일을 삭제
  1. 0 1
      drivers/gpu/drm/amd/powerplay/amd_powerplay.c
  2. 3 2
      drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
  3. 13 2
      drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c

+ 0 - 1
drivers/gpu/drm/amd/powerplay/amd_powerplay.c

@@ -538,7 +538,6 @@ int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id, void *input,
 		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
 		break;
 	case AMD_PP_EVENT_READJUST_POWER_STATE:
-		pp_handle->hwmgr->current_ps = pp_handle->hwmgr->boot_ps;
 		ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
 		break;
 	default:

+ 3 - 2
drivers/gpu/drm/amd/powerplay/eventmgr/psm.c

@@ -70,11 +70,12 @@ int psm_set_states(struct pp_eventmgr *eventmgr, unsigned long *state_id)
 	int i;
 
 	table_entries = hwmgr->num_ps;
+
 	state = hwmgr->ps;
 
 	for (i = 0; i < table_entries; i++) {
 		if (state->id == *state_id) {
-			hwmgr->request_ps = state;
+			memcpy(hwmgr->request_ps, state, hwmgr->ps_size);
 			return 0;
 		}
 		state = (struct pp_power_state *)((unsigned long)state + hwmgr->ps_size);
@@ -106,7 +107,7 @@ int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip)
 	if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) {
 		phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
 		phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware);
-		hwmgr->current_ps = requested;
+		memcpy(hwmgr->current_ps, hwmgr->request_ps, hwmgr->ps_size);
 	}
 	return 0;
 }

+ 13 - 2
drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c

@@ -128,6 +128,8 @@ int hwmgr_fini(struct pp_hwmgr *hwmgr)
 	kfree(hwmgr->set_temperature_range.function_list);
 
 	kfree(hwmgr->ps);
+	kfree(hwmgr->current_ps);
+	kfree(hwmgr->request_ps);
 	kfree(hwmgr);
 	return 0;
 }
@@ -152,10 +154,17 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
 					  sizeof(struct pp_power_state);
 
 	hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
-
 	if (hwmgr->ps == NULL)
 		return -ENOMEM;
 
+	hwmgr->request_ps = kzalloc(size, GFP_KERNEL);
+	if (hwmgr->request_ps == NULL)
+		return -ENOMEM;
+
+	hwmgr->current_ps = kzalloc(size, GFP_KERNEL);
+	if (hwmgr->current_ps == NULL)
+		return -ENOMEM;
+
 	state = hwmgr->ps;
 
 	for (i = 0; i < table_entries; i++) {
@@ -163,7 +172,8 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
 
 		if (state->classification.flags & PP_StateClassificationFlag_Boot) {
 			hwmgr->boot_ps = state;
-			hwmgr->current_ps = hwmgr->request_ps = state;
+			memcpy(hwmgr->current_ps, state, size);
+			memcpy(hwmgr->request_ps, state, size);
 		}
 
 		state->id = i + 1; /* assigned unique num for every power state id */
@@ -173,6 +183,7 @@ int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
 		state = (struct pp_power_state *)((unsigned long)state + size);
 	}
 
+
 	return 0;
 }