diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
28 files changed, 407 insertions, 142 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a59c07590cee..7dcbac8af9a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -190,6 +190,7 @@ struct amdgpu_job;  struct amdgpu_irq_src;  struct amdgpu_fpriv;  struct amdgpu_bo_va_mapping; +struct amdgpu_atif;  enum amdgpu_cp_irq {  	AMDGPU_CP_IRQ_GFX_EOP = 0, @@ -1269,43 +1270,6 @@ struct amdgpu_vram_scratch {  /*   * ACPI   */ -struct amdgpu_atif_notification_cfg { -	bool enabled; -	int command_code; -}; - -struct amdgpu_atif_notifications { -	bool display_switch; -	bool expansion_mode_change; -	bool thermal_state; -	bool forced_power_state; -	bool system_power_state; -	bool display_conf_change; -	bool px_gfx_switch; -	bool brightness_change; -	bool dgpu_display_event; -}; - -struct amdgpu_atif_functions { -	bool system_params; -	bool sbios_requests; -	bool select_active_disp; -	bool lid_state; -	bool get_tv_standard; -	bool set_tv_standard; -	bool get_panel_expansion_mode; -	bool set_panel_expansion_mode; -	bool temperature_change; -	bool graphics_device_types; -}; - -struct amdgpu_atif { -	struct amdgpu_atif_notifications notifications; -	struct amdgpu_atif_functions functions; -	struct amdgpu_atif_notification_cfg notification_cfg; -	struct amdgpu_encoder *encoder_for_bl; -}; -  struct amdgpu_atcs_functions {  	bool get_ext_state;  	bool pcie_perf_req; @@ -1466,7 +1430,7 @@ struct amdgpu_device {  #if defined(CONFIG_DEBUG_FS)  	struct dentry			*debugfs_regs[AMDGPU_DEBUGFS_MAX_COMPONENTS];  #endif -	struct amdgpu_atif		atif; +	struct amdgpu_atif		*atif;  	struct amdgpu_atcs		atcs;  	struct mutex			srbm_mutex;  	/* GRBM index mutex. Protects concurrent access to GRBM index */ @@ -1894,6 +1858,12 @@ static inline bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return false;  static inline bool amdgpu_has_atpx(void) { return false; }  #endif +#if defined(CONFIG_VGA_SWITCHEROO) && defined(CONFIG_ACPI) +void *amdgpu_atpx_get_dhandle(void); +#else +static inline void *amdgpu_atpx_get_dhandle(void) { return NULL; } +#endif +  /*   * KMS   */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index f4c474a95875..71efcf38f11b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -57,6 +57,10 @@  #define ACP_I2S_COMP2_CAP_REG_OFFSET		0xa8  #define ACP_I2S_COMP1_PLAY_REG_OFFSET		0x6c  #define ACP_I2S_COMP2_PLAY_REG_OFFSET		0x68 +#define ACP_BT_PLAY_REGS_START			0x14970 +#define ACP_BT_PLAY_REGS_END			0x14a24 +#define ACP_BT_COMP1_REG_OFFSET			0xac +#define ACP_BT_COMP2_REG_OFFSET			0xa8  #define mmACP_PGFSM_RETAIN_REG			0x51c9  #define mmACP_PGFSM_CONFIG_REG			0x51ca @@ -77,7 +81,7 @@  #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE	0x000000FF  #define ACP_TIMEOUT_LOOP			0x000000FF -#define ACP_DEVS				3 +#define ACP_DEVS				4  #define ACP_SRC_ID				162  enum { @@ -316,14 +320,13 @@ static int acp_hw_init(void *handle)  	if (adev->acp.acp_cell == NULL)  		return -ENOMEM; -	adev->acp.acp_res = kcalloc(4, sizeof(struct resource), GFP_KERNEL); - +	adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);  	if (adev->acp.acp_res == NULL) {  		kfree(adev->acp.acp_cell);  		return -ENOMEM;  	} -	i2s_pdata = kcalloc(2, sizeof(struct i2s_platform_data), GFP_KERNEL); +	i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);  	if (i2s_pdata == NULL) {  		kfree(adev->acp.acp_res);  		kfree(adev->acp.acp_cell); @@ -358,6 +361,20 @@ static int acp_hw_init(void *handle)  	i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;  	i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; +	i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; +	switch (adev->asic_type) { +	case CHIP_STONEY: +		i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; +		break; +	default: +		break; +	} + +	i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD; +	i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000; +	i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET; +	i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET; +  	adev->acp.acp_res[0].name = "acp2x_dma";  	adev->acp.acp_res[0].flags = IORESOURCE_MEM;  	adev->acp.acp_res[0].start = acp_base; @@ -373,13 +390,18 @@ static int acp_hw_init(void *handle)  	adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;  	adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; -	adev->acp.acp_res[3].name = "acp2x_dma_irq"; -	adev->acp.acp_res[3].flags = IORESOURCE_IRQ; -	adev->acp.acp_res[3].start = amdgpu_irq_create_mapping(adev, 162); -	adev->acp.acp_res[3].end = adev->acp.acp_res[3].start; +	adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap"; +	adev->acp.acp_res[3].flags = IORESOURCE_MEM; +	adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START; +	adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END; + +	adev->acp.acp_res[4].name = "acp2x_dma_irq"; +	adev->acp.acp_res[4].flags = IORESOURCE_IRQ; +	adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162); +	adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;  	adev->acp.acp_cell[0].name = "acp_audio_dma"; -	adev->acp.acp_cell[0].num_resources = 4; +	adev->acp.acp_cell[0].num_resources = 5;  	adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];  	adev->acp.acp_cell[0].platform_data = &adev->asic_type;  	adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); @@ -396,6 +418,12 @@ static int acp_hw_init(void *handle)  	adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];  	adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); +	adev->acp.acp_cell[3].name = "designware-i2s"; +	adev->acp.acp_cell[3].num_resources = 1; +	adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3]; +	adev->acp.acp_cell[3].platform_data = &i2s_pdata[2]; +	adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data); +  	r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell,  								ACP_DEVS);  	if (r) @@ -451,7 +479,6 @@ static int acp_hw_init(void *handle)  	val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);  	val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;  	cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); -  	return 0;  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 8fa850a070e0..0d8c3fc6eace 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -34,6 +34,45 @@  #include "amd_acpi.h"  #include "atom.h" +struct amdgpu_atif_notification_cfg { +	bool enabled; +	int command_code; +}; + +struct amdgpu_atif_notifications { +	bool display_switch; +	bool expansion_mode_change; +	bool thermal_state; +	bool forced_power_state; +	bool system_power_state; +	bool display_conf_change; +	bool px_gfx_switch; +	bool brightness_change; +	bool dgpu_display_event; +}; + +struct amdgpu_atif_functions { +	bool system_params; +	bool sbios_requests; +	bool select_active_disp; +	bool lid_state; +	bool get_tv_standard; +	bool set_tv_standard; +	bool get_panel_expansion_mode; +	bool set_panel_expansion_mode; +	bool temperature_change; +	bool graphics_device_types; +}; + +struct amdgpu_atif { +	acpi_handle handle; + +	struct amdgpu_atif_notifications notifications; +	struct amdgpu_atif_functions functions; +	struct amdgpu_atif_notification_cfg notification_cfg; +	struct amdgpu_encoder *encoder_for_bl; +}; +  /* Call the ATIF method   */  /** @@ -46,8 +85,9 @@   * Executes the requested ATIF function (all asics).   * Returns a pointer to the acpi output buffer.   */ -static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, -		struct acpi_buffer *params) +static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif, +					   int function, +					   struct acpi_buffer *params)  {  	acpi_status status;  	union acpi_object atif_arg_elements[2]; @@ -70,7 +110,8 @@ static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function,  		atif_arg_elements[1].integer.value = 0;  	} -	status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); +	status = acpi_evaluate_object(atif->handle, NULL, &atif_arg, +				      &buffer);  	/* Fail only if calling the method fails and ATIF is supported */  	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { @@ -141,15 +182,14 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas   * (all asics).   * returns 0 on success, error on failure.   */ -static int amdgpu_atif_verify_interface(acpi_handle handle, -		struct amdgpu_atif *atif) +static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)  {  	union acpi_object *info;  	struct atif_verify_interface output;  	size_t size;  	int err = 0; -	info = amdgpu_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); +	info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);  	if (!info)  		return -EIO; @@ -176,6 +216,35 @@ out:  	return err;  } +static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle) +{ +	acpi_handle handle = NULL; +	char acpi_method_name[255] = { 0 }; +	struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name }; +	acpi_status status; + +	/* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only +	 * systems, ATIF is in the dGPU's namespace. +	 */ +	status = acpi_get_handle(dhandle, "ATIF", &handle); +	if (ACPI_SUCCESS(status)) +		goto out; + +	if (amdgpu_has_atpx()) { +		status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF", +					 &handle); +		if (ACPI_SUCCESS(status)) +			goto out; +	} + +	DRM_DEBUG_DRIVER("No ATIF handle found\n"); +	return NULL; +out: +	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); +	DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name); +	return handle; +} +  /**   * amdgpu_atif_get_notification_params - determine notify configuration   * @@ -188,15 +257,16 @@ out:   * where n is specified in the result if a notifier is used.   * Returns 0 on success, error on failure.   */ -static int amdgpu_atif_get_notification_params(acpi_handle handle, -		struct amdgpu_atif_notification_cfg *n) +static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)  {  	union acpi_object *info; +	struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;  	struct atif_system_params params;  	size_t size;  	int err = 0; -	info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); +	info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, +				NULL);  	if (!info) {  		err = -EIO;  		goto out; @@ -250,14 +320,15 @@ out:   * (all asics).   * Returns 0 on success, error on failure.   */ -static int amdgpu_atif_get_sbios_requests(acpi_handle handle, -		struct atif_sbios_requests *req) +static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif, +					  struct atif_sbios_requests *req)  {  	union acpi_object *info;  	size_t size;  	int count = 0; -	info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); +	info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, +				NULL);  	if (!info)  		return -EIO; @@ -290,11 +361,10 @@ out:   * Returns NOTIFY code   */  static int amdgpu_atif_handler(struct amdgpu_device *adev, -			struct acpi_bus_event *event) +			       struct acpi_bus_event *event)  { -	struct amdgpu_atif *atif = &adev->atif; +	struct amdgpu_atif *atif = adev->atif;  	struct atif_sbios_requests req; -	acpi_handle handle;  	int count;  	DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", @@ -303,14 +373,14 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,  	if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)  		return NOTIFY_DONE; -	if (!atif->notification_cfg.enabled || +	if (!atif || +	    !atif->notification_cfg.enabled ||  	    event->type != atif->notification_cfg.command_code)  		/* Not our event */  		return NOTIFY_DONE;  	/* Check pending SBIOS requests */ -	handle = ACPI_HANDLE(&adev->pdev->dev); -	count = amdgpu_atif_get_sbios_requests(handle, &req); +	count = amdgpu_atif_get_sbios_requests(atif, &req);  	if (count <= 0)  		return NOTIFY_DONE; @@ -641,8 +711,8 @@ static int amdgpu_acpi_event(struct notifier_block *nb,   */  int amdgpu_acpi_init(struct amdgpu_device *adev)  { -	acpi_handle handle; -	struct amdgpu_atif *atif = &adev->atif; +	acpi_handle handle, atif_handle; +	struct amdgpu_atif *atif;  	struct amdgpu_atcs *atcs = &adev->atcs;  	int ret; @@ -658,12 +728,26 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)  		DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);  	} +	/* Probe for ATIF, and initialize it if found */ +	atif_handle = amdgpu_atif_probe_handle(handle); +	if (!atif_handle) +		goto out; + +	atif = kzalloc(sizeof(*atif), GFP_KERNEL); +	if (!atif) { +		DRM_WARN("Not enough memory to initialize ATIF\n"); +		goto out; +	} +	atif->handle = atif_handle; +  	/* Call the ATIF method */ -	ret = amdgpu_atif_verify_interface(handle, atif); +	ret = amdgpu_atif_verify_interface(atif);  	if (ret) {  		DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); +		kfree(atif);  		goto out;  	} +	adev->atif = atif;  	if (atif->notifications.brightness_change) {  		struct drm_encoder *tmp; @@ -693,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)  	}  	if (atif->functions.system_params) { -		ret = amdgpu_atif_get_notification_params(handle, -				&atif->notification_cfg); +		ret = amdgpu_atif_get_notification_params(atif);  		if (ret) {  			DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",  					ret); @@ -720,4 +803,6 @@ out:  void amdgpu_acpi_fini(struct amdgpu_device *adev)  {  	unregister_acpi_notifier(&adev->acpi_nb); +	if (adev->atif) +		kfree(adev->atif);  } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index daa06e7c5bb7..ca8bf1c9a98e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -90,6 +90,12 @@ bool amdgpu_atpx_dgpu_req_power_for_displays(void) {  	return amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays;  } +#if defined(CONFIG_ACPI) +void *amdgpu_atpx_get_dhandle(void) { +	return amdgpu_atpx_priv.dhandle; +} +#endif +  /**   * amdgpu_atpx_call - call an ATPX method   * @@ -569,6 +575,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {  	{ 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },  	{ 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },  	{ 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX }, +	{ 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX },  	{ 0, 0, 0, 0, 0 },  }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 82312a7bc6ad..9c85a90be293 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -927,6 +927,10 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,  		r = amdgpu_bo_vm_update_pte(p);  		if (r)  			return r; + +		r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv); +		if (r) +			return r;  	}  	return amdgpu_cs_sync_rings(p); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 6e5284e6c028..2c5f093e79e3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2747,6 +2747,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)  	if (r)  		return r; +	/* Make sure IB tests flushed */ +	flush_delayed_work(&adev->late_init_work); +  	/* blat the mode back in */  	if (fbcon) {  		if (!amdgpu_device_has_dc_support(adev)) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index f70eeed9ed76..7aaa263ad8c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -231,6 +231,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,  	if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)  		fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY; +	/* wrap the last IB with fence */ +	if (job && job->uf_addr) { +		amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence, +				       fence_flags | AMDGPU_FENCE_FLAG_64BIT); +	} +  	r = amdgpu_fence_emit(ring, f, fence_flags);  	if (r) {  		dev_err(adev->dev, "failed to emit fence (%d)\n", r); @@ -243,12 +249,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,  	if (ring->funcs->insert_end)  		ring->funcs->insert_end(ring); -	/* wrap the last IB with fence */ -	if (job && job->uf_addr) { -		amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence, -				       fence_flags | AMDGPU_FENCE_FLAG_64BIT); -	} -  	if (patch_offset != ~0 && ring->funcs->patch_cond_exec)  		amdgpu_ring_patch_cond_exec(ring, patch_offset); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index b455da487782..fc818b4d849c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -1882,7 +1882,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)  		if (!amdgpu_device_has_dc_support(adev)) {  			mutex_lock(&adev->pm.mutex);  			amdgpu_dpm_get_active_displays(adev); -			adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtcs; +			adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count;  			adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);  			adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);  			/* we have issues with mclk switching with refresh rates over 120 hz on the non-DC code. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index edf16b2b957a..fdcb498f6d19 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -107,6 +107,9 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,  		return;  	list_add_tail(&base->bo_list, &bo->va); +	if (bo->tbo.type == ttm_bo_type_kernel) +		list_move(&base->vm_status, &vm->relocated); +  	if (bo->tbo.resv != vm->root.base.bo->tbo.resv)  		return; @@ -468,7 +471,6 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,  			pt->parent = amdgpu_bo_ref(parent->base.bo);  			amdgpu_vm_bo_base_init(&entry->base, vm, pt); -			list_move(&entry->base.vm_status, &vm->relocated);  		}  		if (level < AMDGPU_VM_PTB) { diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 0999c843f623..a71b97519cc0 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -900,7 +900,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_phys_funcs = {  	.emit_frame_size =  		4 + /* vce_v3_0_emit_pipeline_sync */  		6, /* amdgpu_vce_ring_emit_fence x1 no user fence */ -	.emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */ +	.emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */  	.emit_ib = amdgpu_vce_ring_emit_ib,  	.emit_fence = amdgpu_vce_ring_emit_fence,  	.test_ring = amdgpu_vce_ring_test_ring, @@ -924,7 +924,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = {  		6 + /* vce_v3_0_emit_vm_flush */  		4 + /* vce_v3_0_emit_pipeline_sync */  		6 + 6, /* amdgpu_vce_ring_emit_fence x2 vm fence */ -	.emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */ +	.emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */  	.emit_ib = vce_v3_0_ring_emit_ib,  	.emit_vm_flush = vce_v3_0_emit_vm_flush,  	.emit_pipeline_sync = vce_v3_0_emit_pipeline_sync, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3a8d6356afc2..770c6b24be0b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2175,6 +2175,46 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing)  	return color_space;  } +static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out) +{ +	if (timing_out->display_color_depth <= COLOR_DEPTH_888) +		return; + +	timing_out->display_color_depth--; +} + +static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out, +						const struct drm_display_info *info) +{ +	int normalized_clk; +	if (timing_out->display_color_depth <= COLOR_DEPTH_888) +		return; +	do { +		normalized_clk = timing_out->pix_clk_khz; +		/* YCbCr 4:2:0 requires additional adjustment of 1/2 */ +		if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420) +			normalized_clk /= 2; +		/* Adjusting pix clock following on HDMI spec based on colour depth */ +		switch (timing_out->display_color_depth) { +		case COLOR_DEPTH_101010: +			normalized_clk = (normalized_clk * 30) / 24; +			break; +		case COLOR_DEPTH_121212: +			normalized_clk = (normalized_clk * 36) / 24; +			break; +		case COLOR_DEPTH_161616: +			normalized_clk = (normalized_clk * 48) / 24; +			break; +		default: +			return; +		} +		if (normalized_clk <= info->max_tmds_clock) +			return; +		reduce_mode_colour_depth(timing_out); + +	} while (timing_out->display_color_depth > COLOR_DEPTH_888); + +}  /*****************************************************************************/  static void @@ -2183,6 +2223,7 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,  					     const struct drm_connector *connector)  {  	struct dc_crtc_timing *timing_out = &stream->timing; +	const struct drm_display_info *info = &connector->display_info;  	memset(timing_out, 0, sizeof(struct dc_crtc_timing)); @@ -2191,8 +2232,10 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,  	timing_out->v_border_top = 0;  	timing_out->v_border_bottom = 0;  	/* TODO: un-hardcode */ - -	if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444) +	if (drm_mode_is_420_only(info, mode_in) +			&& stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) +		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; +	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444)  			&& stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A)  		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;  	else @@ -2228,6 +2271,8 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,  	stream->out_transfer_func->type = TF_TYPE_PREDEFINED;  	stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; +	if (stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) +		adjust_colour_depth_from_display_info(timing_out, info);  }  static void fill_audio_info(struct audio_info *audio_info, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 4304d9e408b8..ace9ad578ca0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -83,22 +83,21 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,  	enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ?  		I2C_MOT_TRUE : I2C_MOT_FALSE;  	enum ddc_result res; -	uint32_t read_bytes = msg->size; +	ssize_t read_bytes;  	if (WARN_ON(msg->size > 16))  		return -E2BIG;  	switch (msg->request & ~DP_AUX_I2C_MOT) {  	case DP_AUX_NATIVE_READ: -		res = dal_ddc_service_read_dpcd_data( +		read_bytes = dal_ddc_service_read_dpcd_data(  				TO_DM_AUX(aux)->ddc_service,  				false,  				I2C_MOT_UNDEF,  				msg->address,  				msg->buffer, -				msg->size, -				&read_bytes); -		break; +				msg->size); +		return read_bytes;  	case DP_AUX_NATIVE_WRITE:  		res = dal_ddc_service_write_dpcd_data(  				TO_DM_AUX(aux)->ddc_service, @@ -109,15 +108,14 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,  				msg->size);  		break;  	case DP_AUX_I2C_READ: -		res = dal_ddc_service_read_dpcd_data( +		read_bytes = dal_ddc_service_read_dpcd_data(  				TO_DM_AUX(aux)->ddc_service,  				true,  				mot,  				msg->address,  				msg->buffer, -				msg->size, -				&read_bytes); -		break; +				msg->size); +		return read_bytes;  	case DP_AUX_I2C_WRITE:  		res = dal_ddc_service_write_dpcd_data(  				TO_DM_AUX(aux)->ddc_service, @@ -139,9 +137,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,  		 r == DDC_RESULT_SUCESSFULL);  #endif -	if (res != DDC_RESULT_SUCESSFULL) -		return -EIO; -	return read_bytes; +	return msg->size;  }  static enum drm_connector_status diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c index 5a3346124a01..5a2e952c5bea 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c @@ -255,8 +255,9 @@ static void pp_to_dc_clock_levels_with_latency(  			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));  	for (i = 0; i < clk_level_info->num_levels; i++) { -		DRM_DEBUG("DM_PPLIB:\t %d\n", pp_clks->data[i].clocks_in_khz); -		clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz; +		DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz); +		/* translate 10kHz to kHz */ +		clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10;  		clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us;  	}  } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index ae48d603ebd6..49c2face1e7a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -629,14 +629,13 @@ bool dal_ddc_service_query_ddc_data(  	return ret;  } -enum ddc_result dal_ddc_service_read_dpcd_data( +ssize_t dal_ddc_service_read_dpcd_data(  	struct ddc_service *ddc,  	bool i2c,  	enum i2c_mot_mode mot,  	uint32_t address,  	uint8_t *data, -	uint32_t len, -	uint32_t *read) +	uint32_t len)  {  	struct aux_payload read_payload = {  		.i2c_over_aux = i2c, @@ -653,8 +652,6 @@ enum ddc_result dal_ddc_service_read_dpcd_data(  		.mot = mot  	}; -	*read = 0; -  	if (len > DEFAULT_AUX_MAX_DATA_SIZE) {  		BREAK_TO_DEBUGGER();  		return DDC_RESULT_FAILED_INVALID_OPERATION; @@ -664,8 +661,7 @@ enum ddc_result dal_ddc_service_read_dpcd_data(  		ddc->ctx->i2caux,  		ddc->ddc_pin,  		&command)) { -		*read = command.payloads->length; -		return DDC_RESULT_SUCESSFULL; +		return (ssize_t)command.payloads->length;  	}  	return DDC_RESULT_FAILED_OPERATION; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 7857cb42b3e6..bdd121485cbc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1767,12 +1767,10 @@ static void dp_test_send_link_training(struct dc_link *link)  	dp_retrain_link_dp_test(link, &link_settings, false);  } -/* TODO hbr2 compliance eye output is unstable +/* TODO Raven hbr2 compliance eye output is unstable   * (toggling on and off) with debugger break   * This caueses intermittent PHY automation failure   * Need to look into the root cause */ -static uint8_t force_tps4_for_cp2520 = 1; -  static void dp_test_send_phy_test_pattern(struct dc_link *link)  {  	union phy_test_pattern dpcd_test_pattern; @@ -1832,13 +1830,13 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)  		break;  	case PHY_TEST_PATTERN_CP2520_1:  		/* CP2520 pattern is unstable, temporarily use TPS4 instead */ -		test_pattern = (force_tps4_for_cp2520 == 1) ? +		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?  				DP_TEST_PATTERN_TRAINING_PATTERN4 :  				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;  		break;  	case PHY_TEST_PATTERN_CP2520_2:  		/* CP2520 pattern is unstable, temporarily use TPS4 instead */ -		test_pattern = (force_tps4_for_cp2520 == 1) ? +		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?  				DP_TEST_PATTERN_TRAINING_PATTERN4 :  				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;  		break; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 9cfde0ccf4e9..53c71296f3dd 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -76,6 +76,7 @@ struct dc_caps {  	bool is_apu;  	bool dual_link_dvi;  	bool post_blend_color_processing; +	bool force_dp_tps4_for_cp2520;  };  struct dc_dcc_surface_param { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c index b235a75355b8..bae752332a9f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c @@ -741,6 +741,29 @@ static struct mem_input_funcs dce_mi_funcs = {  	.mem_input_is_flip_pending = dce_mi_is_flip_pending  }; +static struct mem_input_funcs dce112_mi_funcs = { +	.mem_input_program_display_marks = dce112_mi_program_display_marks, +	.allocate_mem_input = dce_mi_allocate_dmif, +	.free_mem_input = dce_mi_free_dmif, +	.mem_input_program_surface_flip_and_addr = +			dce_mi_program_surface_flip_and_addr, +	.mem_input_program_pte_vm = dce_mi_program_pte_vm, +	.mem_input_program_surface_config = +			dce_mi_program_surface_config, +	.mem_input_is_flip_pending = dce_mi_is_flip_pending +}; + +static struct mem_input_funcs dce120_mi_funcs = { +	.mem_input_program_display_marks = dce120_mi_program_display_marks, +	.allocate_mem_input = dce_mi_allocate_dmif, +	.free_mem_input = dce_mi_free_dmif, +	.mem_input_program_surface_flip_and_addr = +			dce_mi_program_surface_flip_and_addr, +	.mem_input_program_pte_vm = dce_mi_program_pte_vm, +	.mem_input_program_surface_config = +			dce_mi_program_surface_config, +	.mem_input_is_flip_pending = dce_mi_is_flip_pending +};  void dce_mem_input_construct(  	struct dce_mem_input *dce_mi, @@ -769,7 +792,7 @@ void dce112_mem_input_construct(  	const struct dce_mem_input_mask *mi_mask)  {  	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); -	dce_mi->base.funcs->mem_input_program_display_marks = dce112_mi_program_display_marks; +	dce_mi->base.funcs = &dce112_mi_funcs;  }  void dce120_mem_input_construct( @@ -781,5 +804,5 @@ void dce120_mem_input_construct(  	const struct dce_mem_input_mask *mi_mask)  {  	dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); -	dce_mi->base.funcs->mem_input_program_display_marks = dce120_mi_program_display_marks; +	dce_mi->base.funcs = &dce120_mi_funcs;  } diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 38ec0d609297..344dd2e69e7c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -678,9 +678,22 @@ bool dce100_validate_bandwidth(  	struct dc  *dc,  	struct dc_state *context)  { -	/* TODO implement when needed but for now hardcode max value*/ -	context->bw.dce.dispclk_khz = 681000; -	context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER; +	int i; +	bool at_least_one_pipe = false; + +	for (i = 0; i < dc->res_pool->pipe_count; i++) { +		if (context->res_ctx.pipe_ctx[i].stream) +			at_least_one_pipe = true; +	} + +	if (at_least_one_pipe) { +		/* TODO implement when needed but for now hardcode max value*/ +		context->bw.dce.dispclk_khz = 681000; +		context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER; +	} else { +		context->bw.dce.dispclk_khz = 0; +		context->bw.dce.yclk_khz = 0; +	}  	return true;  } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index df5cb2d1d164..34dac84066a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1027,6 +1027,8 @@ static bool construct(  	dc->caps.max_slave_planes = 1;  	dc->caps.is_apu = true;  	dc->caps.post_blend_color_processing = false; +	/* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ +	dc->caps.force_dp_tps4_for_cp2520 = true;  	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)  		dc->debug = debug_defaults_drv; diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index 30b3a08b91be..090b7a8dd67b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h @@ -102,14 +102,13 @@ bool dal_ddc_service_query_ddc_data(  		uint8_t *read_buf,  		uint32_t read_size); -enum ddc_result dal_ddc_service_read_dpcd_data( +ssize_t dal_ddc_service_read_dpcd_data(  		struct ddc_service *ddc,  		bool i2c,  		enum i2c_mot_mode mot,  		uint32_t address,  		uint8_t *data, -		uint32_t len, -		uint32_t *read); +		uint32_t len);  enum ddc_result dal_ddc_service_write_dpcd_data(  		struct ddc_service *ddc, diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index 092d800b703a..33b4de4ad66e 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h @@ -1433,7 +1433,10 @@ struct atom_smc_dpm_info_v4_1  	uint8_t  acggfxclkspreadpercent;  	uint16_t acggfxclkspreadfreq; -	uint32_t boardreserved[10]; +	uint8_t Vr2_I2C_address; +	uint8_t padding_vr2[3]; + +	uint32_t boardreserved[9];  };  /*  diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c index 5325661fedff..d27c1c9df286 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c @@ -512,14 +512,82 @@ int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKI  	return 0;  } +static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr, +			struct pp_atomfwctrl_bios_boot_up_values *boot_values, +			struct atom_firmware_info_v3_2 *fw_info) +{ +	uint32_t frequency = 0; + +	boot_values->ulRevision = fw_info->firmware_revision; +	boot_values->ulGfxClk   = fw_info->bootup_sclk_in10khz; +	boot_values->ulUClk     = fw_info->bootup_mclk_in10khz; +	boot_values->usVddc     = fw_info->bootup_vddc_mv; +	boot_values->usVddci    = fw_info->bootup_vddci_mv; +	boot_values->usMvddc    = fw_info->bootup_mvddc_mv; +	boot_values->usVddGfx   = fw_info->bootup_vddgfx_mv; +	boot_values->ucCoolingID = fw_info->coolingsolution_id; +	boot_values->ulSocClk   = 0; +	boot_values->ulDCEFClk   = 0; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, &frequency)) +		boot_values->ulSocClk   = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, &frequency)) +		boot_values->ulDCEFClk  = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, &frequency)) +		boot_values->ulEClk     = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, &frequency)) +		boot_values->ulVClk     = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, &frequency)) +		boot_values->ulDClk     = frequency; +} + +static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr, +			struct pp_atomfwctrl_bios_boot_up_values *boot_values, +			struct atom_firmware_info_v3_1 *fw_info) +{ +	uint32_t frequency = 0; + +	boot_values->ulRevision = fw_info->firmware_revision; +	boot_values->ulGfxClk   = fw_info->bootup_sclk_in10khz; +	boot_values->ulUClk     = fw_info->bootup_mclk_in10khz; +	boot_values->usVddc     = fw_info->bootup_vddc_mv; +	boot_values->usVddci    = fw_info->bootup_vddci_mv; +	boot_values->usMvddc    = fw_info->bootup_mvddc_mv; +	boot_values->usVddGfx   = fw_info->bootup_vddgfx_mv; +	boot_values->ucCoolingID = fw_info->coolingsolution_id; +	boot_values->ulSocClk   = 0; +	boot_values->ulDCEFClk   = 0; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency)) +		boot_values->ulSocClk   = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency)) +		boot_values->ulDCEFClk  = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, &frequency)) +		boot_values->ulEClk     = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, &frequency)) +		boot_values->ulVClk     = frequency; + +	if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, &frequency)) +		boot_values->ulDClk     = frequency; +} +  int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,  			struct pp_atomfwctrl_bios_boot_up_values *boot_values)  { -	struct atom_firmware_info_v3_1 *info = NULL; +	struct atom_firmware_info_v3_2 *fwinfo_3_2; +	struct atom_firmware_info_v3_1 *fwinfo_3_1; +	struct atom_common_table_header *info = NULL;  	uint16_t ix;  	ix = GetIndexIntoMasterDataTable(firmwareinfo); -	info = (struct atom_firmware_info_v3_1 *) +	info = (struct atom_common_table_header *)  		smu_atom_get_data_table(hwmgr->adev,  				ix, NULL, NULL, NULL); @@ -528,16 +596,18 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,  		return -EINVAL;  	} -	boot_values->ulRevision = info->firmware_revision; -	boot_values->ulGfxClk   = info->bootup_sclk_in10khz; -	boot_values->ulUClk     = info->bootup_mclk_in10khz; -	boot_values->usVddc     = info->bootup_vddc_mv; -	boot_values->usVddci    = info->bootup_vddci_mv; -	boot_values->usMvddc    = info->bootup_mvddc_mv; -	boot_values->usVddGfx   = info->bootup_vddgfx_mv; -	boot_values->ucCoolingID = info->coolingsolution_id; -	boot_values->ulSocClk   = 0; -	boot_values->ulDCEFClk   = 0; +	if ((info->format_revision == 3) && (info->content_revision == 2)) { +		fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info; +		pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr, +				boot_values, fwinfo_3_2); +	} else if ((info->format_revision == 3) && (info->content_revision == 1)) { +		fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info; +		pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr, +				boot_values, fwinfo_3_1); +	} else { +		pr_info("Fw info table revision does not match!"); +		return -EINVAL; +	}  	return 0;  } @@ -629,5 +699,7 @@ int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,  	param->acggfxclkspreadpercent = info->acggfxclkspreadpercent;  	param->acggfxclkspreadfreq = info->acggfxclkspreadfreq; +	param->Vr2_I2C_address = info->Vr2_I2C_address; +  	return 0;  } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h index fe10aa4db5e6..22e21668c93a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h @@ -136,6 +136,9 @@ struct pp_atomfwctrl_bios_boot_up_values {  	uint32_t   ulUClk;  	uint32_t   ulSocClk;  	uint32_t   ulDCEFClk; +	uint32_t   ulEClk; +	uint32_t   ulVClk; +	uint32_t   ulDClk;  	uint16_t   usVddc;  	uint16_t   usVddci;  	uint16_t   usMvddc; @@ -207,6 +210,8 @@ struct pp_atomfwctrl_smc_dpm_parameters  	uint8_t  acggfxclkspreadenabled;  	uint8_t  acggfxclkspreadpercent;  	uint16_t acggfxclkspreadfreq; + +	uint8_t Vr2_I2C_address;  };  int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index 782e2098824d..c98e5de777cd 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c @@ -81,6 +81,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr)  	data->registry_data.disallowed_features = 0x0;  	data->registry_data.od_state_in_dc_support = 0; +	data->registry_data.thermal_support = 1;  	data->registry_data.skip_baco_hardware = 0;  	data->registry_data.log_avfs_param = 0; @@ -803,6 +804,9 @@ static int vega12_init_smc_table(struct pp_hwmgr *hwmgr)  		data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;  		data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk;  		data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID; +		data->vbios_boot_state.eclock = boot_up_values.ulEClk; +		data->vbios_boot_state.dclock = boot_up_values.ulDClk; +		data->vbios_boot_state.vclock = boot_up_values.ulVClk;  		smum_send_msg_to_smc_with_parameter(hwmgr,  				PPSMC_MSG_SetMinDeepSleepDcefclk,  			(uint32_t)(data->vbios_boot_state.dcef_clock / 100)); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index e81ded1ec198..49b38df8c7f2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h @@ -167,6 +167,9 @@ struct vega12_vbios_boot_state {  	uint32_t    mem_clock;  	uint32_t    soc_clock;  	uint32_t    dcef_clock; +	uint32_t    eclock; +	uint32_t    dclock; +	uint32_t    vclock;  };  #define DPMTABLE_OD_UPDATE_SCLK     0x00000001 diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c index 888ddca902d8..29914700ee82 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c @@ -230,6 +230,8 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable  		ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF;  	} +	ppsmc_pptable->Vr2_I2C_address = smc_dpm_table.Vr2_I2C_address; +  	return 0;  } diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h index 2f8a3b983cce..b08526fd1619 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h +++ b/drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h @@ -499,7 +499,10 @@ typedef struct {  	uint8_t      AcgGfxclkSpreadPercent;  	uint16_t     AcgGfxclkSpreadFreq; -	uint32_t     BoardReserved[10]; +  uint8_t      Vr2_I2C_address; +  uint8_t      padding_vr2[3]; + +  uint32_t     BoardReserved[9];    uint32_t     MmHubPadding[7]; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index d644a9bb9078..9f407c48d4f0 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c @@ -381,6 +381,7 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr)  	uint32_t fw_to_load;  	int result = 0;  	struct SMU_DRAMData_TOC *toc; +	uint32_t num_entries = 0;  	if (!hwmgr->reload_fw) {  		pr_info("skip reloading...\n"); @@ -422,41 +423,41 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr)  	}  	toc = (struct SMU_DRAMData_TOC *)smu_data->header; -	toc->num_entries = 0;  	toc->structure_version = 1;  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_RLC_G, &toc->entry[toc->num_entries++]), +				UCODE_ID_RLC_G, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_CP_CE, &toc->entry[toc->num_entries++]), +				UCODE_ID_CP_CE, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]), +				UCODE_ID_CP_PFP, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]), +				UCODE_ID_CP_ME, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]), +				UCODE_ID_CP_MEC, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]), +				UCODE_ID_CP_MEC_JT1, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]), +				UCODE_ID_CP_MEC_JT2, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]), +				UCODE_ID_SDMA0, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]), +				UCODE_ID_SDMA1, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL);  	if (!hwmgr->not_vf)  		PP_ASSERT_WITH_CODE(0 == smu7_populate_single_firmware_entry(hwmgr, -				UCODE_ID_MEC_STORAGE, &toc->entry[toc->num_entries++]), +				UCODE_ID_MEC_STORAGE, &toc->entry[num_entries++]),  				"Failed to Get Firmware Entry.", return -EINVAL); +	toc->num_entries = num_entries;  	smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_HI, upper_32_bits(smu_data->header_buffer.mc_addr));  	smu7_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_DRV_DRAM_ADDR_LO, lower_32_bits(smu_data->header_buffer.mc_addr)); |