diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 49 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 78 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h | 6 | 
7 files changed, 165 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7cee269ec3e3..3f08be7a913e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2471,6 +2471,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,  	mutex_init(&adev->virt.vf_errors.lock);  	hash_init(adev->mn_hash);  	mutex_init(&adev->lock_reset); +	mutex_init(&adev->virt.dpm_mutex);  	amdgpu_device_check_arguments(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 2e376064bad8..b17d0545728e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -696,6 +696,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file  		if (adev->pm.dpm_enabled) {  			dev_info.max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;  			dev_info.max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10; +		} else if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) && +			   adev->virt.ops->get_pp_clk) { +			dev_info.max_engine_clock = amdgpu_virt_get_sclk(adev, false) * 10; +			dev_info.max_memory_clock = amdgpu_virt_get_mclk(adev, false) * 10;  		} else {  			dev_info.max_engine_clock = adev->clock.default_sclk * 10;  			dev_info.max_memory_clock = adev->clock.default_mclk * 10; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 88362019d1dd..4b7a076eea9c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -327,6 +327,18 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,  		goto fail;  	} +        if (amdgpu_sriov_vf(adev)) { +                if (amdgim_is_hwperf(adev) && +                    adev->virt.ops->force_dpm_level) { +                        mutex_lock(&adev->pm.mutex); +                        adev->virt.ops->force_dpm_level(adev, level); +                        mutex_unlock(&adev->pm.mutex); +                        return count; +                } else { +                        return -EINVAL; +		} +        } +  	if (current_level == level)  		return count; @@ -790,6 +802,10 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) && +	    adev->virt.ops->get_pp_clk) +		return adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf); +  	if (is_support_sw_smu(adev))  		return smu_print_clk_levels(&adev->smu, PP_SCLK, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 462a04e0f5e6..7e7f9ed89ee1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -375,4 +375,53 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)  	}  } +static uint32_t parse_clk(char *buf, bool min) +{ +        char *ptr = buf; +        uint32_t clk = 0; + +        do { +                ptr = strchr(ptr, ':'); +                if (!ptr) +                        break; +                ptr+=2; +                clk = simple_strtoul(ptr, NULL, 10); +        } while (!min); + +        return clk * 100; +} + +uint32_t amdgpu_virt_get_sclk(struct amdgpu_device *adev, bool lowest) +{ +	char *buf = NULL; +	uint32_t clk = 0; + +	buf = kzalloc(PAGE_SIZE, GFP_KERNEL); +	if (!buf) +		return -ENOMEM; + +	adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf); +	clk = parse_clk(buf, lowest); + +	kfree(buf); + +	return clk; +} + +uint32_t amdgpu_virt_get_mclk(struct amdgpu_device *adev, bool lowest) +{ +	char *buf = NULL; +	uint32_t clk = 0; + +	buf = kzalloc(PAGE_SIZE, GFP_KERNEL); +	if (!buf) +		return -ENOMEM; + +	adev->virt.ops->get_pp_clk(adev, PP_MCLK, buf); +	clk = parse_clk(buf, lowest); + +	kfree(buf); + +	return clk; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index 722deefc0a7e..584947b7ccf3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -57,6 +57,8 @@ struct amdgpu_virt_ops {  	int (*reset_gpu)(struct amdgpu_device *adev);  	int (*wait_reset)(struct amdgpu_device *adev);  	void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); +	int (*get_pp_clk)(struct amdgpu_device *adev, u32 type, char *buf); +	int (*force_dpm_level)(struct amdgpu_device *adev, u32 level);  };  /* @@ -83,6 +85,8 @@ enum AMDGIM_FEATURE_FLAG {  	AMDGIM_FEATURE_GIM_LOAD_UCODES   = 0x2,  	/* VRAM LOST by GIM */  	AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4, +	/* HW PERF SIM in GIM */ +	AMDGIM_FEATURE_HW_PERF_SIMULATION = (1 << 3),  };  struct amd_sriov_msg_pf2vf_info_header { @@ -252,6 +256,8 @@ struct amdgpu_virt {  	struct amdgpu_vf_error_buffer   vf_errors;  	struct amdgpu_virt_fw_reserve	fw_reserve;  	uint32_t gim_feature; +	/* protect DPM events to GIM */ +	struct mutex                    dpm_mutex;  };  #define amdgpu_sriov_enabled(adev) \ @@ -278,6 +284,9 @@ static inline bool is_virtual_machine(void)  #endif  } +#define amdgim_is_hwperf(adev) \ +	((adev)->virt.gim_feature & AMDGIM_FEATURE_HW_PERF_SIMULATION) +  bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);  void amdgpu_virt_init_setting(struct amdgpu_device *adev);  uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); @@ -295,5 +304,7 @@ int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,  					unsigned int key,  					unsigned int chksum);  void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); +uint32_t amdgpu_virt_get_sclk(struct amdgpu_device *adev, bool lowest); +uint32_t amdgpu_virt_get_mclk(struct amdgpu_device *adev, bool lowest);  #endif diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index 73851ebb3833..8dbad496b29f 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c @@ -157,6 +157,82 @@ static void xgpu_ai_mailbox_trans_msg (struct amdgpu_device *adev,  	xgpu_ai_mailbox_set_valid(adev, false);  } +static int xgpu_ai_get_pp_clk(struct amdgpu_device *adev, u32 type, char *buf) +{ +        int r = 0; +        u32 req, val, size; + +        if (!amdgim_is_hwperf(adev) || buf == NULL) +                return -EBADRQC; + +        switch(type) { +        case PP_SCLK: +                req = IDH_IRQ_GET_PP_SCLK; +                break; +        case PP_MCLK: +                req = IDH_IRQ_GET_PP_MCLK; +                break; +        default: +                return -EBADRQC; +        } + +        mutex_lock(&adev->virt.dpm_mutex); + +        xgpu_ai_mailbox_trans_msg(adev, req, 0, 0, 0); + +        r = xgpu_ai_poll_msg(adev, IDH_SUCCESS); +        if (!r && adev->fw_vram_usage.va != NULL) { +                val = RREG32_NO_KIQ( +                        SOC15_REG_OFFSET(NBIO, 0, +                                         mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW1)); +                size = strnlen((((char *)adev->virt.fw_reserve.p_pf2vf) + +                                val), PAGE_SIZE); + +                if (size < PAGE_SIZE) +                        strcpy(buf,((char *)adev->virt.fw_reserve.p_pf2vf + val)); +                else +                        size = 0; + +                r = size; +                goto out; +        } + +        r = xgpu_ai_poll_msg(adev, IDH_FAIL); +        if(r) +                pr_info("%s DPM request failed", +                        (type == PP_SCLK)? "SCLK" : "MCLK"); + +out: +        mutex_unlock(&adev->virt.dpm_mutex); +        return r; +} + +static int xgpu_ai_force_dpm_level(struct amdgpu_device *adev, u32 level) +{ +        int r = 0; +        u32 req = IDH_IRQ_FORCE_DPM_LEVEL; + +        if (!amdgim_is_hwperf(adev)) +                return -EBADRQC; + +        mutex_lock(&adev->virt.dpm_mutex); +        xgpu_ai_mailbox_trans_msg(adev, req, level, 0, 0); + +        r = xgpu_ai_poll_msg(adev, IDH_SUCCESS); +        if (!r) +                goto out; + +        r = xgpu_ai_poll_msg(adev, IDH_FAIL); +        if (!r) +                pr_info("DPM request failed"); +        else +                pr_info("Mailbox is broken"); + +out: +        mutex_unlock(&adev->virt.dpm_mutex); +        return r; +} +  static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,  					enum idh_request req)  { @@ -375,4 +451,6 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = {  	.reset_gpu = xgpu_ai_request_reset,  	.wait_reset = NULL,  	.trans_msg = xgpu_ai_mailbox_trans_msg, +	.get_pp_clk = xgpu_ai_get_pp_clk, +	.force_dpm_level = xgpu_ai_force_dpm_level,  }; diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h index b4a9ceea334b..39d151b79153 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h @@ -35,6 +35,10 @@ enum idh_request {  	IDH_REL_GPU_FINI_ACCESS,  	IDH_REQ_GPU_RESET_ACCESS, +	IDH_IRQ_FORCE_DPM_LEVEL = 10, +	IDH_IRQ_GET_PP_SCLK, +	IDH_IRQ_GET_PP_MCLK, +  	IDH_LOG_VF_ERROR       = 200,  }; @@ -43,6 +47,8 @@ enum idh_event {  	IDH_READY_TO_ACCESS_GPU,  	IDH_FLR_NOTIFICATION,  	IDH_FLR_NOTIFICATION_CMPL, +	IDH_SUCCESS, +	IDH_FAIL,  	IDH_EVENT_MAX  };  | 

