diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display')
8 files changed, 52 insertions, 104 deletions
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 b0df6dc9a775..5a6edf65c9ea 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -429,6 +429,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)  	    adev->asic_type < CHIP_RAVEN)  		init_data.flags.gpu_vm_support = true; +	if (amdgpu_dc_feature_mask & DC_FBC_MASK) +		init_data.flags.fbc_support = true; +  	/* Display Core create. */  	adev->dm.dc = dc_create(&init_data); @@ -1524,13 +1527,6 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)  {  	struct amdgpu_display_manager *dm = bl_get_data(bd); -	/* -	 * PWM interperts 0 as 100% rather than 0% because of HW -	 * limitation for level 0.So limiting minimum brightness level -	 * to 1. -	 */ -	if (bd->props.brightness < 1) -		return 1;  	if (dc_link_set_backlight_level(dm->backlight_link,  			bd->props.brightness, 0, 0))  		return 0; @@ -2362,8 +2358,15 @@ static void update_stream_scaling_settings(const struct drm_display_mode *mode,  static enum dc_color_depth  convert_color_depth_from_display_info(const struct drm_connector *connector)  { +	struct dm_connector_state *dm_conn_state = +		to_dm_connector_state(connector->state);  	uint32_t bpc = connector->display_info.bpc; +	/* TODO: Remove this when there's support for max_bpc in drm */ +	if (dm_conn_state && bpc > dm_conn_state->max_bpc) +		/* Round down to nearest even number. */ +		bpc = dm_conn_state->max_bpc - (dm_conn_state->max_bpc & 1); +  	switch (bpc) {  	case 0:  		/* @@ -2551,9 +2554,9 @@ static void fill_audio_info(struct audio_info *audio_info,  	cea_revision = drm_connector->display_info.cea_rev; -	strncpy(audio_info->display_name, +	strscpy(audio_info->display_name,  		edid_caps->display_name, -		AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS - 1); +		AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS);  	if (cea_revision >= 3) {  		audio_info->mode_count = edid_caps->audio_mode_count; @@ -2707,18 +2710,11 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,  	drm_connector = &aconnector->base;  	if (!aconnector->dc_sink) { -		/* -		 * Create dc_sink when necessary to MST -		 * Don't apply fake_sink to MST -		 */ -		if (aconnector->mst_port) { -			dm_dp_mst_dc_sink_create(drm_connector); -			return stream; +		if (!aconnector->mst_port) { +			sink = create_fake_sink(aconnector); +			if (!sink) +				return stream;  		} - -		sink = create_fake_sink(aconnector); -		if (!sink) -			return stream;  	} else {  		sink = aconnector->dc_sink;  	} @@ -2954,6 +2950,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector,  	} else if (property == adev->mode_info.underscan_property) {  		dm_new_state->underscan_enable = val;  		ret = 0; +	} else if (property == adev->mode_info.max_bpc_property) { +		dm_new_state->max_bpc = val; +		ret = 0;  	}  	return ret; @@ -2996,6 +2995,9 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector,  	} else if (property == adev->mode_info.underscan_property) {  		*val = dm_state->underscan_enable;  		ret = 0; +	} else if (property == adev->mode_info.max_bpc_property) { +		*val = dm_state->max_bpc; +		ret = 0;  	}  	return ret;  } @@ -3040,6 +3042,7 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector)  		state->underscan_enable = false;  		state->underscan_hborder = 0;  		state->underscan_vborder = 0; +		state->max_bpc = 8;  		__drm_atomic_helper_connector_reset(connector, &state->base);  	} @@ -3061,6 +3064,7 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)  	new_state->freesync_capable = state->freesync_capable;  	new_state->freesync_enable = state->freesync_enable; +	new_state->max_bpc = state->max_bpc;  	return &new_state->base;  } @@ -3308,7 +3312,7 @@ void dm_drm_plane_destroy_state(struct drm_plane *plane,  static const struct drm_plane_funcs dm_plane_funcs = {  	.update_plane	= drm_atomic_helper_update_plane,  	.disable_plane	= drm_atomic_helper_disable_plane, -	.destroy	= drm_plane_cleanup, +	.destroy	= drm_primary_helper_destroy,  	.reset = dm_drm_plane_reset,  	.atomic_duplicate_state = dm_drm_plane_duplicate_state,  	.atomic_destroy_state = dm_drm_plane_destroy_state, @@ -3648,7 +3652,7 @@ amdgpu_dm_create_common_mode(struct drm_encoder *encoder,  	mode->hdisplay = hdisplay;  	mode->vdisplay = vdisplay;  	mode->type &= ~DRM_MODE_TYPE_PREFERRED; -	strncpy(mode->name, name, DRM_DISPLAY_MODE_LEN); +	strscpy(mode->name, name, DRM_DISPLAY_MODE_LEN);  	return mode; @@ -3806,6 +3810,9 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,  	drm_object_attach_property(&aconnector->base.base,  				adev->mode_info.underscan_vborder_property,  				0); +	drm_object_attach_property(&aconnector->base.base, +				adev->mode_info.max_bpc_property, +				0);  } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 978b34a5011c..6e069d777ab2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -160,8 +160,6 @@ struct amdgpu_dm_connector {  	struct mutex hpd_lock;  	bool fake_enable; - -	bool mst_connected;  };  #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base) @@ -206,6 +204,7 @@ struct dm_connector_state {  	enum amdgpu_rmx_type scaling;  	uint8_t underscan_vborder;  	uint8_t underscan_hborder; +	uint8_t max_bpc;  	bool underscan_enable;  	bool freesync_enable;  	bool freesync_capable; 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 03601d717fed..1b0d209d8367 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 @@ -205,40 +205,6 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {  	.atomic_get_property = amdgpu_dm_connector_atomic_get_property  }; -void dm_dp_mst_dc_sink_create(struct drm_connector *connector) -{ -	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); -	struct dc_sink *dc_sink; -	struct dc_sink_init_data init_params = { -			.link = aconnector->dc_link, -			.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; - -	/* FIXME none of this is safe. we shouldn't touch aconnector here in -	 * atomic_check -	 */ - -	/* -	 * TODO: Need to further figure out why ddc.algo is NULL while MST port exists -	 */ -	if (!aconnector->port || !aconnector->port->aux.ddc.algo) -		return; - -	ASSERT(aconnector->edid); - -	dc_sink = dc_link_add_remote_sink( -		aconnector->dc_link, -		(uint8_t *)aconnector->edid, -		(aconnector->edid->extensions + 1) * EDID_LENGTH, -		&init_params); - -	dc_sink->priv = aconnector; -	aconnector->dc_sink = dc_sink; - -	if (aconnector->dc_sink) -		amdgpu_dm_update_freesync_caps( -				connector, aconnector->edid); -} -  static int dm_dp_mst_get_modes(struct drm_connector *connector)  {  	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); @@ -319,12 +285,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector)  	struct amdgpu_device *adev = dev->dev_private;  	struct amdgpu_encoder *amdgpu_encoder;  	struct drm_encoder *encoder; -	const struct drm_connector_helper_funcs *connector_funcs = -		connector->base.helper_private; -	struct drm_encoder *enc_master = -		connector_funcs->best_encoder(&connector->base); -	DRM_DEBUG_KMS("enc master is %p\n", enc_master);  	amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL);  	if (!amdgpu_encoder)  		return NULL; @@ -354,25 +315,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,  	struct amdgpu_device *adev = dev->dev_private;  	struct amdgpu_dm_connector *aconnector;  	struct drm_connector *connector; -	struct drm_connector_list_iter conn_iter; - -	drm_connector_list_iter_begin(dev, &conn_iter); -	drm_for_each_connector_iter(connector, &conn_iter) { -		aconnector = to_amdgpu_dm_connector(connector); -		if (aconnector->mst_port == master -				&& !aconnector->port) { -			DRM_INFO("DM_MST: reusing connector: %p [id: %d] [master: %p]\n", -						aconnector, connector->base.id, aconnector->mst_port); - -			aconnector->port = port; -			drm_connector_set_path_property(connector, pathprop); - -			drm_connector_list_iter_end(&conn_iter); -			aconnector->mst_connected = true; -			return &aconnector->base; -		} -	} -	drm_connector_list_iter_end(&conn_iter);  	aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);  	if (!aconnector) @@ -400,10 +342,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,  		master->connector_id);  	aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master); +	drm_connector_attach_encoder(&aconnector->base, +				     &aconnector->mst_encoder->base); -	/* -	 * TODO: understand why this one is needed -	 */  	drm_object_attach_property(  		&connector->base,  		dev->mode_config.path_property, @@ -421,8 +362,6 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,  	 */  	amdgpu_dm_connector_funcs_reset(connector); -	aconnector->mst_connected = true; -  	DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",  			aconnector, connector->base.id, aconnector->mst_port); @@ -434,6 +373,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,  static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,  					struct drm_connector *connector)  { +	struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); +	struct drm_device *dev = master->base.dev; +	struct amdgpu_device *adev = dev->dev_private;  	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);  	DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", @@ -447,7 +389,10 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,  		aconnector->dc_sink = NULL;  	} -	aconnector->mst_connected = false; +	drm_connector_unregister(connector); +	if (adev->mode_info.rfbdev) +		drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector); +	drm_connector_put(connector);  }  static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) @@ -458,18 +403,10 @@ static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)  	drm_kms_helper_hotplug_event(dev);  } -static void dm_dp_mst_link_status_reset(struct drm_connector *connector) -{ -	mutex_lock(&connector->dev->mode_config.mutex); -	drm_connector_set_link_status_property(connector, DRM_MODE_LINK_STATUS_BAD); -	mutex_unlock(&connector->dev->mode_config.mutex); -} -  static void dm_dp_mst_register_connector(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct amdgpu_device *adev = dev->dev_private; -	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);  	if (adev->mode_info.rfbdev)  		drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); @@ -477,9 +414,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector)  		DRM_ERROR("adev->mode_info.rfbdev is NULL\n");  	drm_connector_register(connector); - -	if (aconnector->mst_connected) -		dm_dp_mst_link_status_reset(connector);  }  static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 8cf51da26657..2da851b40042 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -31,6 +31,5 @@ struct amdgpu_dm_connector;  void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,  				       struct amdgpu_dm_connector *aconnector); -void dm_dp_mst_dc_sink_create(struct drm_connector *connector);  #endif diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index fb04a4ad141f..5da2186b3615 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1722,7 +1722,7 @@ static void write_i2c_retimer_setting(  		i2c_success = i2c_write(pipe_ctx, slave_address,  				buffer, sizeof(buffer));  		RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ -			offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n", +			offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",  			slave_address, buffer[0], buffer[1], i2c_success?1:0);  		if (!i2c_success)  			/* Write failure */ @@ -1734,7 +1734,7 @@ static void write_i2c_retimer_setting(  		i2c_success = i2c_write(pipe_ctx, slave_address,  				buffer, sizeof(buffer));  		RETIMER_REDRIVER_INFO("retimer write to slave_address = 0x%x,\ -			offset = 0x%d, reg_val = 0x%d, i2c_success = %d\n", +			offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n",  			slave_address, buffer[0], buffer[1], i2c_success?1:0);  		if (!i2c_success)  			/* Write failure */ diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 199527171100..b57fa61b3034 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -169,6 +169,7 @@ struct link_training_settings;  struct dc_config {  	bool gpu_vm_support;  	bool disable_disp_pll_sharing; +	bool fbc_support;  };  enum visual_confirm { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index b75ede5f84f7..a6bcb90e8419 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1736,7 +1736,12 @@ static void set_static_screen_control(struct pipe_ctx **pipe_ctx,  	if (events->force_trigger)  		value |= 0x1; -	value |= 0x84; +	if (num_pipes) { +		struct dc *dc = pipe_ctx[0]->stream->ctx->dc; + +		if (dc->fbc_compressor) +			value |= 0x84; +	}  	for (i = 0; i < num_pipes; i++)  		pipe_ctx[i]->stream_res.tg->funcs-> @@ -2507,6 +2512,8 @@ static void pplib_apply_display_requirements(  			dc,  			context->bw.dce.sclk_khz); +	pp_display_cfg->min_dcfclock_khz = pp_display_cfg->min_engine_clock_khz; +  	pp_display_cfg->min_engine_clock_deep_sleep_khz  			= context->bw.dce.sclk_deep_sleep_khz; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index e3624ca24574..7c9fd9052ee2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -1362,7 +1362,8 @@ static bool construct(  		pool->base.sw_i2cs[i] = NULL;  	} -	dc->fbc_compressor = dce110_compressor_create(ctx); +	if (dc->config.fbc_support) +		dc->fbc_compressor = dce110_compressor_create(ctx);  	if (!underlay_create(ctx, &pool->base))  		goto res_create_fail;  |