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__ */