Move ip block related functions to amdgpu_ip.c. No functional change intended.
Signed-off-by: Lijo Lazar <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 121 +------- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 323 -------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c | 324 +++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ip.h | 125 ++++++++ 4 files changed, 450 insertions(+), 443 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index fa71df36f4b3..de8fb746daf1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -116,6 +116,7 @@ #include "amdgpu_reg_state.h" #include "amdgpu_userq.h" #include "amdgpu_eviction_fence.h" +#include "amdgpu_ip.h" #if defined(CONFIG_DRM_AMD_ISP) #include "amdgpu_isp.h" #endif @@ -362,59 +363,6 @@ enum amdgpu_kiq_irq { #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ #define MAX_KIQ_REG_TRY 1000 -int amdgpu_device_ip_set_clockgating_state(void *dev, - enum amd_ip_block_type block_type, - enum amd_clockgating_state state); -int amdgpu_device_ip_set_powergating_state(void *dev, - enum amd_ip_block_type block_type, - enum amd_powergating_state state); -void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, - u64 *flags); -int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, - enum amd_ip_block_type block_type); -bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev, - enum amd_ip_block_type block_type); -bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev, - enum amd_ip_block_type block_type); -int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block); - -int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block); - -#define AMDGPU_MAX_IP_NUM AMD_IP_BLOCK_TYPE_NUM - -struct amdgpu_ip_block_status { - bool valid; - bool sw; - bool hw; - bool late_initialized; - bool hang; -}; - -struct amdgpu_ip_block_version { - const enum amd_ip_block_type type; - const u32 major; - const u32 minor; - const u32 rev; - const struct amd_ip_funcs *funcs; -}; - -struct amdgpu_ip_block { - struct amdgpu_ip_block_status status; - const struct amdgpu_ip_block_version *version; - struct amdgpu_device *adev; -}; - -int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev, - enum amd_ip_block_type type, - u32 major, u32 minor); - -struct amdgpu_ip_block * -amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev, - enum amd_ip_block_type type); - -int amdgpu_device_ip_block_add(struct amdgpu_device *adev, - const struct amdgpu_ip_block_version *ip_block_version); - /* * BIOS. */ @@ -757,73 +705,6 @@ struct amdgpu_mmio_remap { struct amdgpu_bo *bo; }; -/* Define the HW IP blocks will be used in driver , add more if necessary */ -enum amd_hw_ip_block_type { - GC_HWIP = 1, - HDP_HWIP, - SDMA0_HWIP, - SDMA1_HWIP, - SDMA2_HWIP, - SDMA3_HWIP, - SDMA4_HWIP, - SDMA5_HWIP, - SDMA6_HWIP, - SDMA7_HWIP, - LSDMA_HWIP, - MMHUB_HWIP, - ATHUB_HWIP, - NBIO_HWIP, - MP0_HWIP, - MP1_HWIP, - UVD_HWIP, - VCN_HWIP = UVD_HWIP, - JPEG_HWIP = VCN_HWIP, - VCN1_HWIP, - VCE_HWIP, - VPE_HWIP, - DF_HWIP, - DCE_HWIP, - OSSSYS_HWIP, - SMUIO_HWIP, - PWR_HWIP, - NBIF_HWIP, - THM_HWIP, - CLK_HWIP, - UMC_HWIP, - RSMU_HWIP, - XGMI_HWIP, - DCI_HWIP, - PCIE_HWIP, - ISP_HWIP, - ATU_HWIP, - AIGC_HWIP, - MAX_HWIP -}; - -#define HWIP_MAX_INSTANCE 48 - -#define HW_ID_MAX 300 -#define IP_VERSION_FULL(mj, mn, rv, var, srev) \ - (((mj) << 24) | ((mn) << 16) | ((rv) << 8) | ((var) << 4) | (srev)) -#define IP_VERSION(mj, mn, rv) IP_VERSION_FULL(mj, mn, rv, 0, 0) -#define IP_VERSION_MAJ(ver) ((ver) >> 24) -#define IP_VERSION_MIN(ver) (((ver) >> 16) & 0xFF) -#define IP_VERSION_REV(ver) (((ver) >> 8) & 0xFF) -#define IP_VERSION_VARIANT(ver) (((ver) >> 4) & 0xF) -#define IP_VERSION_SUBREV(ver) ((ver) & 0xF) -#define IP_VERSION_MAJ_MIN_REV(ver) ((ver) >> 8) - -struct amdgpu_ip_map_info { - /* Map of logical to actual dev instances/mask */ - uint32_t dev_inst[MAX_HWIP][HWIP_MAX_INSTANCE]; - int8_t (*logical_to_dev_inst)(struct amdgpu_device *adev, - enum amd_hw_ip_block_type block, - int8_t inst); - uint32_t (*logical_to_dev_mask)(struct amdgpu_device *adev, - enum amd_hw_ip_block_type block, - uint32_t mask); -}; - enum amdgpu_uid_type { AMDGPU_UID_TYPE_XCD, AMDGPU_UID_TYPE_AID, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7a0213a07023..d93453c3b07c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -313,42 +313,6 @@ void amdgpu_reg_state_sysfs_fini(struct amdgpu_device *adev) sysfs_remove_bin_file(&adev->dev->kobj, &bin_attr_reg_state); } -int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block) -{ - int r; - - if (ip_block->version->funcs->suspend) { - r = ip_block->version->funcs->suspend(ip_block); - if (r) { - dev_err(ip_block->adev->dev, - "suspend of IP block <%s> failed %d\n", - ip_block->version->funcs->name, r); - return r; - } - } - - ip_block->status.hw = false; - return 0; -} - -int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block) -{ - int r; - - if (ip_block->version->funcs->resume) { - r = ip_block->version->funcs->resume(ip_block); - if (r) { - dev_err(ip_block->adev->dev, - "resume of IP block <%s> failed %d\n", - ip_block->version->funcs->name, r); - return r; - } - } - - ip_block->status.hw = true; - return 0; -} - /** * DOC: board_info * @@ -2265,293 +2229,6 @@ static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = { .can_switch = amdgpu_switcheroo_can_switch, }; -/** - * amdgpu_device_ip_set_clockgating_state - set the CG state - * - * @dev: amdgpu_device pointer - * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) - * @state: clockgating state (gate or ungate) - * - * Sets the requested clockgating state for all instances of - * the hardware IP specified. - * Returns the error code from the last instance. - */ -int amdgpu_device_ip_set_clockgating_state(void *dev, - enum amd_ip_block_type block_type, - enum amd_clockgating_state state) -{ - struct amdgpu_device *adev = dev; - int i, r = 0; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (!adev->ip_blocks[i].status.valid) - continue; - if (adev->ip_blocks[i].version->type != block_type) - continue; - if (!adev->ip_blocks[i].version->funcs->set_clockgating_state) - continue; - r = adev->ip_blocks[i].version->funcs->set_clockgating_state( - &adev->ip_blocks[i], state); - if (r) - dev_err(adev->dev, - "set_clockgating_state of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - } - return r; -} - -/** - * amdgpu_device_ip_set_powergating_state - set the PG state - * - * @dev: amdgpu_device pointer - * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) - * @state: powergating state (gate or ungate) - * - * Sets the requested powergating state for all instances of - * the hardware IP specified. - * Returns the error code from the last instance. - */ -int amdgpu_device_ip_set_powergating_state(void *dev, - enum amd_ip_block_type block_type, - enum amd_powergating_state state) -{ - struct amdgpu_device *adev = dev; - int i, r = 0; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (!adev->ip_blocks[i].status.valid) - continue; - if (adev->ip_blocks[i].version->type != block_type) - continue; - if (!adev->ip_blocks[i].version->funcs->set_powergating_state) - continue; - r = adev->ip_blocks[i].version->funcs->set_powergating_state( - &adev->ip_blocks[i], state); - if (r) - dev_err(adev->dev, - "set_powergating_state of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - } - return r; -} - -/** - * amdgpu_device_ip_get_clockgating_state - get the CG state - * - * @adev: amdgpu_device pointer - * @flags: clockgating feature flags - * - * Walks the list of IPs on the device and updates the clockgating - * flags for each IP. - * Updates @flags with the feature flags for each hardware IP where - * clockgating is enabled. - */ -void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, - u64 *flags) -{ - int i; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (!adev->ip_blocks[i].status.valid) - continue; - if (adev->ip_blocks[i].version->funcs->get_clockgating_state) - adev->ip_blocks[i].version->funcs->get_clockgating_state( - &adev->ip_blocks[i], flags); - } -} - -/** - * amdgpu_device_ip_wait_for_idle - wait for idle - * - * @adev: amdgpu_device pointer - * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) - * - * Waits for the request hardware IP to be idle. - * Returns 0 for success or a negative error code on failure. - */ -int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, - enum amd_ip_block_type block_type) -{ - int i, r; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (!adev->ip_blocks[i].status.valid) - continue; - if (adev->ip_blocks[i].version->type == block_type) { - if (adev->ip_blocks[i].version->funcs->wait_for_idle) { - r = adev->ip_blocks[i].version->funcs->wait_for_idle( - &adev->ip_blocks[i]); - if (r) - return r; - } - break; - } - } - return 0; - -} - -/** - * amdgpu_device_ip_is_hw - is the hardware IP enabled - * - * @adev: amdgpu_device pointer - * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) - * - * Check if the hardware IP is enable or not. - * Returns true if it the IP is enable, false if not. - */ -bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev, - enum amd_ip_block_type block_type) -{ - int i; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (adev->ip_blocks[i].version->type == block_type) - return adev->ip_blocks[i].status.hw; - } - return false; -} - -/** - * amdgpu_device_ip_is_valid - is the hardware IP valid - * - * @adev: amdgpu_device pointer - * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) - * - * Check if the hardware IP is valid or not. - * Returns true if it the IP is valid, false if not. - */ -bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev, - enum amd_ip_block_type block_type) -{ - int i; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (adev->ip_blocks[i].version->type == block_type) - return adev->ip_blocks[i].status.valid; - } - return false; - -} - -/** - * amdgpu_device_ip_get_ip_block - get a hw IP pointer - * - * @adev: amdgpu_device pointer - * @type: Type of hardware IP (SMU, GFX, UVD, etc.) - * - * Returns a pointer to the hardware IP block structure - * if it exists for the asic, otherwise NULL. - */ -struct amdgpu_ip_block * -amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev, - enum amd_ip_block_type type) -{ - int i; - - for (i = 0; i < adev->num_ip_blocks; i++) - if (adev->ip_blocks[i].version->type == type) - return &adev->ip_blocks[i]; - - return NULL; -} - -/** - * amdgpu_device_ip_block_version_cmp - * - * @adev: amdgpu_device pointer - * @type: enum amd_ip_block_type - * @major: major version - * @minor: minor version - * - * return 0 if equal or greater - * return 1 if smaller or the ip_block doesn't exist - */ -int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev, - enum amd_ip_block_type type, - u32 major, u32 minor) -{ - struct amdgpu_ip_block *ip_block = amdgpu_device_ip_get_ip_block(adev, type); - - if (ip_block && ((ip_block->version->major > major) || - ((ip_block->version->major == major) && - (ip_block->version->minor >= minor)))) - return 0; - - return 1; -} - -static const char *ip_block_names[] = { - [AMD_IP_BLOCK_TYPE_COMMON] = "common", - [AMD_IP_BLOCK_TYPE_GMC] = "gmc", - [AMD_IP_BLOCK_TYPE_IH] = "ih", - [AMD_IP_BLOCK_TYPE_SMC] = "smu", - [AMD_IP_BLOCK_TYPE_PSP] = "psp", - [AMD_IP_BLOCK_TYPE_DCE] = "dce", - [AMD_IP_BLOCK_TYPE_GFX] = "gfx", - [AMD_IP_BLOCK_TYPE_SDMA] = "sdma", - [AMD_IP_BLOCK_TYPE_UVD] = "uvd", - [AMD_IP_BLOCK_TYPE_VCE] = "vce", - [AMD_IP_BLOCK_TYPE_ACP] = "acp", - [AMD_IP_BLOCK_TYPE_VCN] = "vcn", - [AMD_IP_BLOCK_TYPE_MES] = "mes", - [AMD_IP_BLOCK_TYPE_JPEG] = "jpeg", - [AMD_IP_BLOCK_TYPE_VPE] = "vpe", - [AMD_IP_BLOCK_TYPE_UMSCH_MM] = "umsch_mm", - [AMD_IP_BLOCK_TYPE_ISP] = "isp", - [AMD_IP_BLOCK_TYPE_RAS] = "ras", -}; - -static const char *ip_block_name(struct amdgpu_device *adev, enum amd_ip_block_type type) -{ - int idx = (int)type; - - return idx < ARRAY_SIZE(ip_block_names) ? ip_block_names[idx] : "unknown"; -} - -/** - * amdgpu_device_ip_block_add - * - * @adev: amdgpu_device pointer - * @ip_block_version: pointer to the IP to add - * - * Adds the IP block driver information to the collection of IPs - * on the asic. - */ -int amdgpu_device_ip_block_add(struct amdgpu_device *adev, - const struct amdgpu_ip_block_version *ip_block_version) -{ - if (!ip_block_version) - return -EINVAL; - - switch (ip_block_version->type) { - case AMD_IP_BLOCK_TYPE_VCN: - if (adev->harvest_ip_mask & AMD_HARVEST_IP_VCN_MASK) - return 0; - break; - case AMD_IP_BLOCK_TYPE_JPEG: - if (adev->harvest_ip_mask & AMD_HARVEST_IP_JPEG_MASK) - return 0; - break; - default: - break; - } - - dev_info(adev->dev, "detected ip block number %d <%s_v%d_%d_%d> (%s)\n", - adev->num_ip_blocks, - ip_block_name(adev, ip_block_version->type), - ip_block_version->major, - ip_block_version->minor, - ip_block_version->rev, - ip_block_version->funcs->name); - - adev->ip_blocks[adev->num_ip_blocks].adev = adev; - - adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version; - - return 0; -} - /** * amdgpu_device_enable_virtual_display - enable virtual display feature * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c index 99e1cf4fc955..b5e6d9d6937a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c @@ -94,3 +94,327 @@ void amdgpu_ip_map_init(struct amdgpu_device *adev) adev->ip_map.logical_to_dev_inst = amdgpu_logical_to_dev_inst; adev->ip_map.logical_to_dev_mask = amdgpu_logical_to_dev_mask; } + +int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block) +{ + int r; + + if (ip_block->version->funcs->suspend) { + r = ip_block->version->funcs->suspend(ip_block); + if (r) { + dev_err(ip_block->adev->dev, + "suspend of IP block <%s> failed %d\n", + ip_block->version->funcs->name, r); + return r; + } + } + + ip_block->status.hw = false; + return 0; +} + +int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block) +{ + int r; + + if (ip_block->version->funcs->resume) { + r = ip_block->version->funcs->resume(ip_block); + if (r) { + dev_err(ip_block->adev->dev, + "resume of IP block <%s> failed %d\n", + ip_block->version->funcs->name, r); + return r; + } + } + + ip_block->status.hw = true; + return 0; +} + +/** + * amdgpu_device_ip_get_ip_block - get a hw IP pointer + * + * @adev: amdgpu_device pointer + * @type: Type of hardware IP (SMU, GFX, UVD, etc.) + * + * Returns a pointer to the hardware IP block structure + * if it exists for the asic, otherwise NULL. + */ +struct amdgpu_ip_block * +amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev, + enum amd_ip_block_type type) +{ + int i; + + for (i = 0; i < adev->num_ip_blocks; i++) + if (adev->ip_blocks[i].version->type == type) + return &adev->ip_blocks[i]; + + return NULL; +} + +/** + * amdgpu_device_ip_block_version_cmp + * + * @adev: amdgpu_device pointer + * @type: enum amd_ip_block_type + * @major: major version + * @minor: minor version + * + * return 0 if equal or greater + * return 1 if smaller or the ip_block doesn't exist + */ +int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev, + enum amd_ip_block_type type, u32 major, + u32 minor) +{ + struct amdgpu_ip_block *ip_block = + amdgpu_device_ip_get_ip_block(adev, type); + + if (ip_block && ((ip_block->version->major > major) || + ((ip_block->version->major == major) && + (ip_block->version->minor >= minor)))) + return 0; + + return 1; +} + +static const char *const ip_block_names[] = { + [AMD_IP_BLOCK_TYPE_COMMON] = "common", + [AMD_IP_BLOCK_TYPE_GMC] = "gmc", + [AMD_IP_BLOCK_TYPE_IH] = "ih", + [AMD_IP_BLOCK_TYPE_SMC] = "smu", + [AMD_IP_BLOCK_TYPE_PSP] = "psp", + [AMD_IP_BLOCK_TYPE_DCE] = "dce", + [AMD_IP_BLOCK_TYPE_GFX] = "gfx", + [AMD_IP_BLOCK_TYPE_SDMA] = "sdma", + [AMD_IP_BLOCK_TYPE_UVD] = "uvd", + [AMD_IP_BLOCK_TYPE_VCE] = "vce", + [AMD_IP_BLOCK_TYPE_ACP] = "acp", + [AMD_IP_BLOCK_TYPE_VCN] = "vcn", + [AMD_IP_BLOCK_TYPE_MES] = "mes", + [AMD_IP_BLOCK_TYPE_JPEG] = "jpeg", + [AMD_IP_BLOCK_TYPE_VPE] = "vpe", + [AMD_IP_BLOCK_TYPE_UMSCH_MM] = "umsch_mm", + [AMD_IP_BLOCK_TYPE_ISP] = "isp", + [AMD_IP_BLOCK_TYPE_RAS] = "ras", +}; + +static const char *ip_block_name(struct amdgpu_device *adev, + enum amd_ip_block_type type) +{ + int idx = (int)type; + + return idx < ARRAY_SIZE(ip_block_names) ? ip_block_names[idx] : + "unknown"; +} + +/** + * amdgpu_device_ip_block_add + * + * @adev: amdgpu_device pointer + * @ip_block_version: pointer to the IP to add + * + * Adds the IP block driver information to the collection of IPs + * on the asic. + */ +int amdgpu_device_ip_block_add( + struct amdgpu_device *adev, + const struct amdgpu_ip_block_version *ip_block_version) +{ + if (!ip_block_version) + return -EINVAL; + + switch (ip_block_version->type) { + case AMD_IP_BLOCK_TYPE_VCN: + if (adev->harvest_ip_mask & AMD_HARVEST_IP_VCN_MASK) + return 0; + break; + case AMD_IP_BLOCK_TYPE_JPEG: + if (adev->harvest_ip_mask & AMD_HARVEST_IP_JPEG_MASK) + return 0; + break; + default: + break; + } + + dev_info(adev->dev, "detected ip block number %d <%s_v%d_%d_%d> (%s)\n", + adev->num_ip_blocks, + ip_block_name(adev, ip_block_version->type), + ip_block_version->major, ip_block_version->minor, + ip_block_version->rev, ip_block_version->funcs->name); + + adev->ip_blocks[adev->num_ip_blocks].adev = adev; + + adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version; + + return 0; +} + +/** + * amdgpu_device_ip_set_clockgating_state - set the CG state + * + * @dev: amdgpu_device pointer + * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) + * @state: clockgating state (gate or ungate) + * + * Sets the requested clockgating state for all instances of + * the hardware IP specified. + * Returns the error code from the last instance. + */ +int amdgpu_device_ip_set_clockgating_state(void *dev, + enum amd_ip_block_type block_type, + enum amd_clockgating_state state) +{ + struct amdgpu_device *adev = dev; + int i, r = 0; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.valid) + continue; + if (adev->ip_blocks[i].version->type != block_type) + continue; + if (!adev->ip_blocks[i].version->funcs->set_clockgating_state) + continue; + r = adev->ip_blocks[i].version->funcs->set_clockgating_state( + &adev->ip_blocks[i], state); + if (r) + dev_err(adev->dev, + "set_clockgating_state of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + } + return r; +} + +/** + * amdgpu_device_ip_set_powergating_state - set the PG state + * + * @dev: amdgpu_device pointer + * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) + * @state: powergating state (gate or ungate) + * + * Sets the requested powergating state for all instances of + * the hardware IP specified. + * Returns the error code from the last instance. + */ +int amdgpu_device_ip_set_powergating_state(void *dev, + enum amd_ip_block_type block_type, + enum amd_powergating_state state) +{ + struct amdgpu_device *adev = dev; + int i, r = 0; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.valid) + continue; + if (adev->ip_blocks[i].version->type != block_type) + continue; + if (!adev->ip_blocks[i].version->funcs->set_powergating_state) + continue; + r = adev->ip_blocks[i].version->funcs->set_powergating_state( + &adev->ip_blocks[i], state); + if (r) + dev_err(adev->dev, + "set_powergating_state of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + } + return r; +} + +/** + * amdgpu_device_ip_get_clockgating_state - get the CG state + * + * @adev: amdgpu_device pointer + * @flags: clockgating feature flags + * + * Walks the list of IPs on the device and updates the clockgating + * flags for each IP. + * Updates @flags with the feature flags for each hardware IP where + * clockgating is enabled. + */ +void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, + u64 *flags) +{ + int i; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.valid) + continue; + if (adev->ip_blocks[i].version->funcs->get_clockgating_state) + adev->ip_blocks[i].version->funcs->get_clockgating_state( + &adev->ip_blocks[i], flags); + } +} + +/** + * amdgpu_device_ip_wait_for_idle - wait for idle + * + * @adev: amdgpu_device pointer + * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) + * + * Waits for the request hardware IP to be idle. + * Returns 0 for success or a negative error code on failure. + */ +int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, + enum amd_ip_block_type block_type) +{ + int i, r; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.valid) + continue; + if (adev->ip_blocks[i].version->type == block_type) { + if (adev->ip_blocks[i].version->funcs->wait_for_idle) { + r = adev->ip_blocks[i] + .version->funcs->wait_for_idle( + &adev->ip_blocks[i]); + if (r) + return r; + } + break; + } + } + return 0; +} + +/** + * amdgpu_device_ip_is_hw - is the hardware IP enabled + * + * @adev: amdgpu_device pointer + * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) + * + * Check if the hardware IP is enable or not. + * Returns true if it the IP is enable, false if not. + */ +bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev, + enum amd_ip_block_type block_type) +{ + int i; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (adev->ip_blocks[i].version->type == block_type) + return adev->ip_blocks[i].status.hw; + } + return false; +} + +/** + * amdgpu_device_ip_is_valid - is the hardware IP valid + * + * @adev: amdgpu_device pointer + * @block_type: Type of hardware IP (SMU, GFX, UVD, etc.) + * + * Check if the hardware IP is valid or not. + * Returns true if it the IP is valid, false if not. + */ +bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev, + enum amd_ip_block_type block_type) +{ + int i; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (adev->ip_blocks[i].version->type == block_type) + return adev->ip_blocks[i].status.valid; + } + return false; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.h index 2490fd322aec..77d1c642953c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.h @@ -24,6 +24,131 @@ #ifndef __AMDGPU_IP_H__ #define __AMDGPU_IP_H__ +#include "amd_shared.h" + +struct amdgpu_device; + +/* Define the HW IP blocks will be used in driver , add more if necessary */ +enum amd_hw_ip_block_type { + GC_HWIP = 1, + HDP_HWIP, + SDMA0_HWIP, + SDMA1_HWIP, + SDMA2_HWIP, + SDMA3_HWIP, + SDMA4_HWIP, + SDMA5_HWIP, + SDMA6_HWIP, + SDMA7_HWIP, + LSDMA_HWIP, + MMHUB_HWIP, + ATHUB_HWIP, + NBIO_HWIP, + MP0_HWIP, + MP1_HWIP, + UVD_HWIP, + VCN_HWIP = UVD_HWIP, + JPEG_HWIP = VCN_HWIP, + VCN1_HWIP, + VCE_HWIP, + VPE_HWIP, + DF_HWIP, + DCE_HWIP, + OSSSYS_HWIP, + SMUIO_HWIP, + PWR_HWIP, + NBIF_HWIP, + THM_HWIP, + CLK_HWIP, + UMC_HWIP, + RSMU_HWIP, + XGMI_HWIP, + DCI_HWIP, + PCIE_HWIP, + ISP_HWIP, + ATU_HWIP, + AIGC_HWIP, + MAX_HWIP +}; + +#define HWIP_MAX_INSTANCE 48 + +#define HW_ID_MAX 300 +#define IP_VERSION_FULL(mj, mn, rv, var, srev) \ + (((mj) << 24) | ((mn) << 16) | ((rv) << 8) | ((var) << 4) | (srev)) +#define IP_VERSION(mj, mn, rv) IP_VERSION_FULL(mj, mn, rv, 0, 0) +#define IP_VERSION_MAJ(ver) ((ver) >> 24) +#define IP_VERSION_MIN(ver) (((ver) >> 16) & 0xFF) +#define IP_VERSION_REV(ver) (((ver) >> 8) & 0xFF) +#define IP_VERSION_VARIANT(ver) (((ver) >> 4) & 0xF) +#define IP_VERSION_SUBREV(ver) ((ver) & 0xF) +#define IP_VERSION_MAJ_MIN_REV(ver) ((ver) >> 8) + +struct amdgpu_ip_map_info { + /* Map of logical to actual dev instances/mask */ + uint32_t dev_inst[MAX_HWIP][HWIP_MAX_INSTANCE]; + int8_t (*logical_to_dev_inst)(struct amdgpu_device *adev, + enum amd_hw_ip_block_type block, + int8_t inst); + uint32_t (*logical_to_dev_mask)(struct amdgpu_device *adev, + enum amd_hw_ip_block_type block, + uint32_t mask); +}; + +#define AMDGPU_MAX_IP_NUM AMD_IP_BLOCK_TYPE_NUM + +struct amdgpu_ip_block_status { + bool valid; + bool sw; + bool hw; + bool late_initialized; + bool hang; +}; + +struct amdgpu_ip_block_version { + const enum amd_ip_block_type type; + const u32 major; + const u32 minor; + const u32 rev; + const struct amd_ip_funcs *funcs; +}; + +struct amdgpu_ip_block { + struct amdgpu_ip_block_status status; + const struct amdgpu_ip_block_version *version; + struct amdgpu_device *adev; +}; + void amdgpu_ip_map_init(struct amdgpu_device *adev); +int amdgpu_ip_block_suspend(struct amdgpu_ip_block *ip_block); +int amdgpu_ip_block_resume(struct amdgpu_ip_block *ip_block); + +struct amdgpu_ip_block * +amdgpu_device_ip_get_ip_block(struct amdgpu_device *adev, + enum amd_ip_block_type type); + +int amdgpu_device_ip_block_version_cmp(struct amdgpu_device *adev, + enum amd_ip_block_type type, u32 major, + u32 minor); + +int amdgpu_device_ip_block_add( + struct amdgpu_device *adev, + const struct amdgpu_ip_block_version *ip_block_version); + +int amdgpu_device_ip_set_clockgating_state(void *dev, + enum amd_ip_block_type block_type, + enum amd_clockgating_state state); +int amdgpu_device_ip_set_powergating_state(void *dev, + enum amd_ip_block_type block_type, + enum amd_powergating_state state); +void amdgpu_device_ip_get_clockgating_state(struct amdgpu_device *adev, + u64 *flags); +int amdgpu_device_ip_wait_for_idle(struct amdgpu_device *adev, + enum amd_ip_block_type block_type); +bool amdgpu_device_ip_is_hw(struct amdgpu_device *adev, + enum amd_ip_block_type block_type); +bool amdgpu_device_ip_is_valid(struct amdgpu_device *adev, + enum amd_ip_block_type block_type); + #endif /* __AMDGPU_IP_H__ */ -- 2.49.0
