Commit 28a18bab authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher

drm/amd/powerplay: add CG and PG support for carrizo

This adds clock and powergating support for CZ.

v2: squash in fixes
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bdecc20a
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
# It provides the hardware management services for the driver. # It provides the hardware management services for the driver.
HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \
hardwaremanager.o pp_acpi.o cz_hwmgr.o hardwaremanager.o pp_acpi.o cz_hwmgr.o \
cz_clockpowergating.o
AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR))
......
/*
* Copyright 2015 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "hwmgr.h"
#include "cz_clockpowergating.h"
#include "cz_ppsmc.h"
/* PhyID -> Status Mapping in DDI_PHY_GEN_STATUS
0 GFX0L (3:0), (27:24),
1 GFX0H (7:4), (31:28),
2 GFX1L (3:0), (19:16),
3 GFX1H (7:4), (23:20),
4 DDIL (3:0), (11: 8),
5 DDIH (7:4), (15:12),
6 DDI2L (3:0), ( 3: 0),
7 DDI2H (7:4), ( 7: 4),
*/
#define DDI_PHY_GEN_STATUS_VAL(phyID) (1 << ((3 - ((phyID & 0x07)/2))*8 + (phyID & 0x01)*4))
#define IS_PHY_ID_USED_BY_PLL(PhyID) (((0xF3 & (1 << PhyID)) & 0xFF) ? true : false)
int cz_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating)
{
int ret = 0;
switch (block) {
case PHM_AsicBlock_UVD_MVC:
case PHM_AsicBlock_UVD:
case PHM_AsicBlock_UVD_HD:
case PHM_AsicBlock_UVD_SD:
if (gating == PHM_ClockGateSetting_StaticOff)
ret = cz_dpm_powerdown_uvd(hwmgr);
else
ret = cz_dpm_powerup_uvd(hwmgr);
break;
case PHM_AsicBlock_GFX:
default:
break;
}
return ret;
}
bool cz_phm_is_safe_for_asic_block(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, enum PHM_AsicBlock block)
{
return true;
}
int cz_phm_enable_disable_gfx_power_gating(struct pp_hwmgr *hwmgr, bool enable)
{
return 0;
}
int cz_phm_smu_power_up_down_pcie(struct pp_hwmgr *hwmgr, uint32_t target, bool up, uint32_t args)
{
/* TODO */
return 0;
}
int cz_phm_initialize_display_phy_access(struct pp_hwmgr *hwmgr, bool initialize, bool accesshw)
{
/* TODO */
return 0;
}
int cz_phm_get_display_phy_access_info(struct pp_hwmgr *hwmgr)
{
/* TODO */
return 0;
}
int cz_phm_gate_unused_display_phys(struct pp_hwmgr *hwmgr)
{
/* TODO */
return 0;
}
int cz_phm_ungate_all_display_phys(struct pp_hwmgr *hwmgr)
{
/* TODO */
return 0;
}
static int cz_tf_uvd_power_gating_initialize(struct pp_hwmgr *hwmgr, void *pInput, void *pOutput, void *pStorage, int Result)
{
return 0;
}
static int cz_tf_vce_power_gating_initialize(struct pp_hwmgr *hwmgr, void *pInput, void *pOutput, void *pStorage, int Result)
{
return 0;
}
int cz_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
uint32_t dpm_features = 0;
if (enable &&
phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_UVDDPM)) {
cz_hwmgr->dpm_flags |= DPMFlags_UVD_Enabled;
dpm_features |= UVD_DPM_MASK;
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
} else {
dpm_features |= UVD_DPM_MASK;
cz_hwmgr->dpm_flags &= ~DPMFlags_UVD_Enabled;
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
}
return 0;
}
int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
uint32_t dpm_features = 0;
if (enable && phm_cap_enabled(
hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_VCEDPM)) {
cz_hwmgr->dpm_flags |= DPMFlags_VCE_Enabled;
dpm_features |= VCE_DPM_MASK;
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_EnableAllSmuFeatures, dpm_features);
} else {
dpm_features |= VCE_DPM_MASK;
cz_hwmgr->dpm_flags &= ~DPMFlags_VCE_Enabled;
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_DisableAllSmuFeatures, dpm_features);
}
return 0;
}
int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
if (cz_hwmgr->uvd_power_gated == bgate)
return 0;
cz_hwmgr->uvd_power_gated = bgate;
if (bgate) {
cgs_set_clockgating_state(hwmgr->device,
AMD_IP_BLOCK_TYPE_UVD,
AMD_CG_STATE_UNGATE);
cgs_set_powergating_state(hwmgr->device,
AMD_IP_BLOCK_TYPE_UVD,
AMD_PG_STATE_GATE);
cz_dpm_update_uvd_dpm(hwmgr, true);
cz_dpm_powerdown_uvd(hwmgr);
} else {
cz_dpm_powerup_uvd(hwmgr);
cgs_set_clockgating_state(hwmgr->device,
AMD_IP_BLOCK_TYPE_UVD,
AMD_PG_STATE_GATE);
cgs_set_powergating_state(hwmgr->device,
AMD_IP_BLOCK_TYPE_UVD,
AMD_CG_STATE_UNGATE);
cz_dpm_update_uvd_dpm(hwmgr, false);
}
return 0;
}
int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_VCEPowerGating)) {
if (cz_hwmgr->vce_power_gated != bgate) {
if (bgate) {
cgs_set_clockgating_state(
hwmgr->device,
AMD_IP_BLOCK_TYPE_VCE,
AMD_CG_STATE_UNGATE);
cgs_set_powergating_state(
hwmgr->device,
AMD_IP_BLOCK_TYPE_VCE,
AMD_PG_STATE_GATE);
cz_enable_disable_vce_dpm(hwmgr, false);
/* TODO: to figure out why vce can't be poweroff*/
cz_hwmgr->vce_power_gated = true;
} else {
cz_dpm_powerup_vce(hwmgr);
cz_hwmgr->vce_power_gated = false;
cgs_set_clockgating_state(
hwmgr->device,
AMD_IP_BLOCK_TYPE_VCE,
AMD_PG_STATE_GATE);
cgs_set_powergating_state(
hwmgr->device,
AMD_IP_BLOCK_TYPE_VCE,
AMD_CG_STATE_UNGATE);
cz_dpm_update_vce_dpm(hwmgr);
cz_enable_disable_vce_dpm(hwmgr, true);
return 0;
}
}
} else {
cz_dpm_update_vce_dpm(hwmgr);
cz_enable_disable_vce_dpm(hwmgr, true);
return 0;
}
if (!cz_hwmgr->vce_power_gated)
cz_dpm_update_vce_dpm(hwmgr);
return 0;
}
static struct phm_master_table_item cz_enable_clock_power_gatings_list[] = {
/*we don't need an exit table here, because there is only D3 cold on Kv*/
{ phm_cf_want_uvd_power_gating, cz_tf_uvd_power_gating_initialize },
{ phm_cf_want_vce_power_gating, cz_tf_vce_power_gating_initialize },
/* to do { NULL, cz_tf_xdma_power_gating_enable }, */
{ NULL, NULL }
};
struct phm_master_table_header cz_phm_enable_clock_power_gatings_master = {
0,
PHM_MasterTableFlag_None,
cz_enable_clock_power_gatings_list
};
/*
* Copyright 2015 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _CZ_CLOCK_POWER_GATING_H_
#define _CZ_CLOCK_POWER_GATING_H_
#include "cz_hwmgr.h"
#include "pp_asicblocks.h"
extern int cz_phm_set_asic_block_gating(struct pp_hwmgr *hwmgr, enum PHM_AsicBlock block, enum PHM_ClockGateSetting gating);
extern struct phm_master_table_header cz_phm_enable_clock_power_gatings_master;
extern struct phm_master_table_header cz_phm_disable_clock_power_gatings_master;
extern int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate);
extern int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate);
extern int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable);
extern int cz_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable);
#endif /* _CZ_CLOCK_POWER_GATING_H_ */
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define CZ_AT_DFLT 30 #define CZ_AT_DFLT 30
#define CZ_MAX_HARDWARE_POWERLEVELS 8 #define CZ_MAX_HARDWARE_POWERLEVELS 8
#define PPCZ_VOTINGRIGHTSCLIENTS_DFLT0 0x3FFFC102 #define PPCZ_VOTINGRIGHTSCLIENTS_DFLT0 0x3FFFC102
#define CZ_MIN_DEEP_SLEEP_SCLK 800
/* Carrizo device IDs */ /* Carrizo device IDs */
#define DEVICE_ID_CZ_9870 0x9870 #define DEVICE_ID_CZ_9870 0x9870
...@@ -198,6 +199,9 @@ struct cz_hwmgr { ...@@ -198,6 +199,9 @@ struct cz_hwmgr {
struct cz_sys_info sys_info; struct cz_sys_info sys_info;
struct cz_power_level boot_power_level; struct cz_power_level boot_power_level;
struct cz_power_state *cz_current_ps;
struct cz_power_state *cz_requested_ps;
uint32_t mgcg_cgtt_local0; uint32_t mgcg_cgtt_local0;
uint32_t mgcg_cgtt_local1; uint32_t mgcg_cgtt_local1;
...@@ -299,11 +303,15 @@ struct cz_hwmgr { ...@@ -299,11 +303,15 @@ struct cz_hwmgr {
uint32_t max_sclk_level; uint32_t max_sclk_level;
uint32_t num_of_clk_entries; uint32_t num_of_clk_entries;
struct cz_power_state *cz_ps;
}; };
struct pp_hwmgr; struct pp_hwmgr;
int cz_hwmgr_init(struct pp_hwmgr *hwmgr); int cz_hwmgr_init(struct pp_hwmgr *hwmgr);
int cz_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr);
int cz_dpm_powerup_uvd(struct pp_hwmgr *hwmgr);
int cz_dpm_powerdown_vce(struct pp_hwmgr *hwmgr);
int cz_dpm_powerup_vce(struct pp_hwmgr *hwmgr);
int cz_dpm_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate);
int cz_dpm_update_vce_dpm(struct pp_hwmgr *hwmgr);
#endif /* _CZ_HWMGR_H_ */ #endif /* _CZ_HWMGR_H_ */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include "hwmgr.h" #include "hwmgr.h"
#include "hardwaremanager.h" #include "hardwaremanager.h"
#include "power_state.h"
#include "pp_acpi.h" #include "pp_acpi.h"
#include "amd_acpi.h" #include "amd_acpi.h"
...@@ -55,6 +56,17 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr) ...@@ -55,6 +56,17 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr)
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
} }
bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr)
{
return hwmgr->block_hw_access;
}
int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block)
{
hwmgr->block_hw_access = block;
return 0;
}
int phm_setup_asic(struct pp_hwmgr *hwmgr) int phm_setup_asic(struct pp_hwmgr *hwmgr)
{ {
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
...@@ -62,13 +74,33 @@ int phm_setup_asic(struct pp_hwmgr *hwmgr) ...@@ -62,13 +74,33 @@ int phm_setup_asic(struct pp_hwmgr *hwmgr)
if (NULL != hwmgr->hwmgr_func->asic_setup) if (NULL != hwmgr->hwmgr_func->asic_setup)
return hwmgr->hwmgr_func->asic_setup(hwmgr); return hwmgr->hwmgr_func->asic_setup(hwmgr);
} else { } else {
return phm_dispatch_table (hwmgr, &(hwmgr->setup_asic), return phm_dispatch_table(hwmgr, &(hwmgr->setup_asic),
NULL, NULL); NULL, NULL);
} }
return 0; return 0;
} }
int phm_set_power_state(struct pp_hwmgr *hwmgr,
const struct pp_hw_power_state *pcurrent_state,
const struct pp_hw_power_state *pnew_power_state)
{
struct phm_set_power_state_input states;
states.pcurrent_state = pcurrent_state;
states.pnew_state = pnew_power_state;
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TablelessHardwareInterface)) {
if (NULL != hwmgr->hwmgr_func->power_state_set)
return hwmgr->hwmgr_func->power_state_set(hwmgr, &states);
} else {
return phm_dispatch_table(hwmgr, &(hwmgr->set_power_state), &states, NULL);
}
return 0;
}
int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
{ {
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
...@@ -76,9 +108,62 @@ int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) ...@@ -76,9 +108,62 @@ int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable) if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable)
return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr); return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
} else { } else {
return phm_dispatch_table (hwmgr, return phm_dispatch_table(hwmgr,
&(hwmgr->enable_dynamic_state_management), &(hwmgr->enable_dynamic_state_management),
NULL, NULL); NULL, NULL);
} }
return 0; return 0;
} }
int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level)
{
if (hwmgr->hwmgr_func->force_dpm_level != NULL)
return hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
return 0;
}
int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
struct pp_power_state *adjusted_ps,
const struct pp_power_state *current_ps)
{
if (hwmgr->hwmgr_func->apply_state_adjust_rules != NULL)
return hwmgr->hwmgr_func->apply_state_adjust_rules(
hwmgr,
adjusted_ps,
current_ps);
return 0;
}
int phm_powerdown_uvd(struct pp_hwmgr *hwmgr)
{
if (hwmgr->hwmgr_func->powerdown_uvd != NULL)
return hwmgr->hwmgr_func->powerdown_uvd(hwmgr);
return 0;
}
int phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool gate)
{
if (hwmgr->hwmgr_func->powergate_uvd != NULL)
return hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
return 0;
}
int phm_powergate_vce(struct pp_hwmgr *hwmgr, bool gate)
{
if (hwmgr->hwmgr_func->powergate_vce != NULL)
return hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
return 0;
}
int phm_enable_clock_power_gatings(struct pp_hwmgr *hwmgr)
{
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TablelessHardwareInterface)) {
if (NULL != hwmgr->hwmgr_func->enable_clock_power_gating)
return hwmgr->hwmgr_func->enable_clock_power_gating(hwmgr);
} else {
return phm_dispatch_table(hwmgr, &(hwmgr->enable_clock_power_gatings), NULL, NULL);
}
return 0;
}
...@@ -201,3 +201,13 @@ void phm_wait_for_indirect_register_unequal(struct pp_hwmgr *hwmgr, ...@@ -201,3 +201,13 @@ void phm_wait_for_indirect_register_unequal(struct pp_hwmgr *hwmgr,
phm_wait_for_register_unequal(hwmgr, indirect_port + 1, phm_wait_for_register_unequal(hwmgr, indirect_port + 1,
value, mask); value, mask);
} }
bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr)
{
return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDPowerGating);
}
bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr)
{
return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEPowerGating);
}
...@@ -23,7 +23,12 @@ ...@@ -23,7 +23,12 @@
#ifndef _HARDWARE_MANAGER_H_ #ifndef _HARDWARE_MANAGER_H_
#define _HARDWARE_MANAGER_H_ #define _HARDWARE_MANAGER_H_
struct pp_hwmgr; struct pp_hwmgr;
struct pp_hw_power_state;
struct pp_power_state;
enum amd_dpm_forced_level;
/* Automatic Power State Throttling */ /* Automatic Power State Throttling */
enum PHM_AutoThrottleSource enum PHM_AutoThrottleSource
...@@ -206,6 +211,24 @@ struct pp_hw_descriptor { ...@@ -206,6 +211,24 @@ struct pp_hw_descriptor {
uint32_t hw_caps[PHM_MAX_NUM_CAPS_ULONG_ENTRIES]; uint32_t hw_caps[PHM_MAX_NUM_CAPS_ULONG_ENTRIES];
}; };
enum PHM_PerformanceLevelDesignation {
PHM_PerformanceLevelDesignation_Activity,
PHM_PerformanceLevelDesignation_PowerContainment
};
typedef enum PHM_PerformanceLevelDesignation PHM_PerformanceLevelDesignation;
struct PHM_PerformanceLevel {
uint32_t coreClock;
uint32_t memory_clock;
uint32_t vddc;
uint32_t vddci;
uint32_t nonLocalMemoryFreq;
uint32_t nonLocalMemoryWidth;
};
typedef struct PHM_PerformanceLevel PHM_PerformanceLevel;
/* Function for setting a platform cap */ /* Function for setting a platform cap */
static inline void phm_cap_set(uint32_t *caps, static inline void phm_cap_set(uint32_t *caps,
enum phm_platform_caps c) enum phm_platform_caps c)
...@@ -226,6 +249,20 @@ static inline bool phm_cap_enabled(const uint32_t *caps, enum phm_platform_caps ...@@ -226,6 +249,20 @@ static inline bool phm_cap_enabled(const uint32_t *caps, enum phm_platform_caps
(1UL << (c & (PHM_MAX_NUM_CAPS_BITS_PER_FIELD - 1))))); (1UL << (c & (PHM_MAX_NUM_CAPS_BITS_PER_FIELD - 1)))));
} }
#define PP_PCIEGenInvalid 0xffff
enum PP_PCIEGen {
PP_PCIEGen1 = 0, /* PCIE 1.0 - Transfer rate of 2.5 GT/s */
PP_PCIEGen2, /*PCIE 2.0 - Transfer rate of 5.0 GT/s */
PP_PCIEGen3 /*PCIE 3.0 - Transfer rate of 8.0 GT/s */
};
typedef enum PP_PCIEGen PP_PCIEGen;
#define PP_Min_PCIEGen PP_PCIEGen1
#define PP_Max_PCIEGen PP_PCIEGen3
#define PP_Min_PCIELane 1
#define PP_Max_PCIELane 32
enum phm_clock_Type { enum phm_clock_Type {
PHM_DispClock = 1, PHM_DispClock = 1,
PHM_SClock, PHM_SClock,
...@@ -273,8 +310,22 @@ struct phm_clocks { ...@@ -273,8 +310,22 @@ struct phm_clocks {
uint32_t num_of_entries; uint32_t num_of_entries;
uint32_t clock[MAX_NUM_CLOCKS]; uint32_t clock[MAX_NUM_CLOCKS];
}; };
extern int phm_enable_clock_power_gatings(struct pp_hwmgr *hwmgr);
extern int phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool gate);
extern int phm_powergate_vce(struct pp_hwmgr *hwmgr, bool gate);
extern int phm_powerdown_uvd(struct pp_hwmgr *hwmgr);
extern int phm_setup_asic(struct pp_hwmgr *hwmgr); extern int phm_setup_asic(struct pp_hwmgr *hwmgr);
extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr); extern int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr);
extern void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr); extern void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr);
extern bool phm_is_hw_access_blocked(struct pp_hwmgr *hwmgr);
extern int phm_block_hw_access(struct pp_hwmgr *hwmgr, bool block);
extern int phm_set_power_state(struct pp_hwmgr *hwmgr,
const struct pp_hw_power_state *pcurrent_state,
const struct pp_hw_power_state *pnew_power_state);
extern int phm_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
struct pp_power_state *adjusted_ps,
const struct pp_power_state *current_ps);
extern int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level);
#endif /* _HARDWARE_MANAGER_H_ */ #endif /* _HARDWARE_MANAGER_H_ */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#ifndef _HWMGR_H_ #ifndef _HWMGR_H_
#define _HWMGR_H_ #define _HWMGR_H_
#include <linux/seq_file.h>
#include "amd_powerplay.h" #include "amd_powerplay.h"
#include "pp_instance.h" #include "pp_instance.h"
#include "hardwaremanager.h" #include "hardwaremanager.h"
...@@ -85,6 +86,11 @@ typedef int (*phm_table_function)(struct pp_hwmgr *hwmgr, void *input, ...@@ -85,6 +86,11 @@ typedef int (*phm_table_function)(struct pp_hwmgr *hwmgr, void *input,
typedef bool (*phm_check_function)(struct pp_hwmgr *hwmgr); typedef bool (*phm_check_function)(struct pp_hwmgr *hwmgr);
struct phm_set_power_state_input {
const struct pp_hw_power_state *pcurrent_state;
const struct pp_hw_power_state *pnew_state;
};
struct phm_acp_arbiter { struct phm_acp_arbiter {
uint32_t acpclk; uint32_t acpclk;
}; };
...@@ -252,11 +258,34 @@ struct pp_hwmgr_func { ...@@ -252,11 +258,34 @@ struct pp_hwmgr_func {
int (*backend_fini)(struct pp_hwmgr *hw_mgr); int (*backend_fini)(struct pp_hwmgr *hw_mgr);
int (*asic_setup)(struct pp_hwmgr *hw_mgr); int (*asic_setup)(struct pp_hwmgr *hw_mgr);
int (*get_power_state_size)(struct pp_hwmgr *hw_mgr); int (*get_power_state_size)(struct pp_hwmgr *hw_mgr);
int (*force_dpm_level)(struct pp_hwmgr *hw_mgr, enum amd_dpm_forced_level level);
int (*dynamic_state_management_enable)(struct pp_hwmgr *hw_mgr); int (*apply_state_adjust_rules)(struct pp_hwmgr *hwmgr,
int (*patch_boot_state)(struct pp_hwmgr *hwmgr, struct pp_hw_power_state *hw_ps); struct pp_power_state *prequest_ps,
int (*get_pp_table_entry)(struct pp_hwmgr *hwmgr, unsigned long, struct pp_power_state *); const struct pp_power_state *pcurrent_ps);
int (*force_dpm_level)(struct pp_hwmgr *hw_mgr,
enum amd_dpm_forced_level level);
int (*dynamic_state_management_enable)(
struct pp_hwmgr *hw_mgr);
int (*patch_boot_state)(struct pp_hwmgr *hwmgr,
struct pp_hw_power_state *hw_ps);
int (*get_pp_table_entry)(struct pp_hwmgr *hwmgr,
unsigned long, struct pp_power_state *);
int (*get_num_of_pp_table_entries)(struct pp_hwmgr *hwmgr); int (*get_num_of_pp_table_entries)(struct pp_hwmgr *hwmgr);
int (*powerdown_uvd)(struct pp_hwmgr *hwmgr);
int (*powergate_vce)(struct pp_hwmgr *hwmgr, bool bgate);
int (*powergate_uvd)(struct pp_hwmgr *hwmgr, bool bgate);
int (*get_mclk)(struct pp_hwmgr *hwmgr, bool low);
int (*get_sclk)(struct pp_hwmgr *hwmgr, bool low);
int (*power_state_set)(struct pp_hwmgr *hwmgr,
const void *state);
void (*print_current_perforce_level)(struct pp_hwmgr *hwmgr,
struct seq_file *m);
int (*enable_clock_power_gating)(struct pp_hwmgr *hwmgr);
}; };
struct pp_table_func { struct pp_table_func {
...@@ -416,7 +445,7 @@ struct pp_hwmgr { ...@@ -416,7 +445,7 @@ struct pp_hwmgr {
struct pp_smumgr *smumgr; struct pp_smumgr *smumgr;
const void *soft_pp_table; const void *soft_pp_table;
enum amd_dpm_forced_level dpm_level; enum amd_dpm_forced_level dpm_level;
bool block_hw_access;
struct phm_gfx_arbiter gfx_arbiter; struct phm_gfx_arbiter gfx_arbiter;
struct phm_acp_arbiter acp_arbiter; struct phm_acp_arbiter acp_arbiter;
struct phm_uvd_arbiter uvd_arbiter; struct phm_uvd_arbiter uvd_arbiter;
...@@ -430,6 +459,8 @@ struct pp_hwmgr { ...@@ -430,6 +459,8 @@ struct pp_hwmgr {
struct phm_runtime_table_header setup_asic; struct phm_runtime_table_header setup_asic;
struct phm_runtime_table_header disable_dynamic_state_management; struct phm_runtime_table_header disable_dynamic_state_management;
struct phm_runtime_table_header enable_dynamic_state_management; struct phm_runtime_table_header enable_dynamic_state_management;
struct phm_runtime_table_header set_power_state;
struct phm_runtime_table_header enable_clock_power_gatings;
const struct pp_hwmgr_func *hwmgr_func; const struct pp_hwmgr_func *hwmgr_func;
const struct pp_table_func *pptable_func; const struct pp_table_func *pptable_func;
struct pp_power_state *ps; struct pp_power_state *ps;
...@@ -471,6 +502,11 @@ extern void phm_wait_for_indirect_register_unequal( ...@@ -471,6 +502,11 @@ extern void phm_wait_for_indirect_register_unequal(
uint32_t value, uint32_t value,
uint32_t mask); uint32_t mask);
bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr);
bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr);
#define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU
#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT #define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK #define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK
......
/*
* Copyright 2015 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef PP_ASICBLOCKS_H
#define PP_ASICBLOCKS_H
enum PHM_AsicBlock {
PHM_AsicBlock_GFX,
PHM_AsicBlock_UVD_MVC,
PHM_AsicBlock_UVD,
PHM_AsicBlock_UVD_HD,
PHM_AsicBlock_UVD_SD,
PHM_AsicBlock_Count
};
enum PHM_ClockGateSetting {
PHM_ClockGateSetting_StaticOn,
PHM_ClockGateSetting_StaticOff,
PHM_ClockGateSetting_Dynamic
};
struct phm_asic_blocks {
bool gfx : 1;
bool uvd : 1;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment