[PATCH 4/7] drm/amdgpu: simplify encoder and connector setup

Deng, Emily Emily.Deng at amd.com
Sat Oct 8 08:22:53 UTC 2016


Reviewed-By: Emily Deng <Emily.Deng at amd.com>

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Alex Deucher
> Sent: Saturday, October 01, 2016 1:09 AM
> To: amd-gfx at lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher at amd.com>
> Subject: [PATCH 4/7] drm/amdgpu: simplify encoder and connector setup
> 
> No need to emulate all of the stuff for real hw.
> 
> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |  93 ----------
>  drivers/gpu/drm/amd/amdgpu/dce_virtual.c       | 231 +++++++++++++++----
> ------
>  2 files changed, 144 insertions(+), 180 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> index decbba5..ff0b55a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
> @@ -1504,88 +1504,6 @@ static const struct drm_connector_funcs
> amdgpu_connector_edp_funcs = {
>  	.force = amdgpu_connector_dvi_force,
>  };
> 
> -static struct drm_encoder *
> -amdgpu_connector_virtual_encoder(struct drm_connector *connector) -{
> -	int enc_id = connector->encoder_ids[0];
> -	struct drm_encoder *encoder;
> -	int i;
> -	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> -		if (connector->encoder_ids[i] == 0)
> -			break;
> -
> -		encoder = drm_encoder_find(connector->dev, connector-
> >encoder_ids[i]);
> -		if (!encoder)
> -			continue;
> -
> -		if (encoder->encoder_type ==
> DRM_MODE_ENCODER_VIRTUAL)
> -			return encoder;
> -	}
> -
> -	/* pick the first one */
> -	if (enc_id)
> -		return drm_encoder_find(connector->dev, enc_id);
> -	return NULL;
> -}
> -
> -static int amdgpu_connector_virtual_get_modes(struct drm_connector
> *connector) -{
> -	struct drm_encoder *encoder =
> amdgpu_connector_best_single_encoder(connector);
> -
> -	if (encoder) {
> -		amdgpu_connector_add_common_modes(encoder,
> connector);
> -	}
> -
> -	return 0;
> -}
> -
> -static int amdgpu_connector_virtual_mode_valid(struct drm_connector
> *connector,
> -					   struct drm_display_mode *mode)
> -{
> -	return MODE_OK;
> -}
> -
> -static int
> -amdgpu_connector_virtual_dpms(struct drm_connector *connector, int
> mode) -{
> -	return 0;
> -}
> -
> -static enum drm_connector_status
> -
> -amdgpu_connector_virtual_detect(struct drm_connector *connector, bool
> force) -{
> -	return connector_status_connected;
> -}
> -
> -static int
> -amdgpu_connector_virtual_set_property(struct drm_connector *connector,
> -				  struct drm_property *property,
> -				  uint64_t val)
> -{
> -	return 0;
> -}
> -
> -static void amdgpu_connector_virtual_force(struct drm_connector
> *connector) -{
> -	return;
> -}
> -
> -static const struct drm_connector_helper_funcs
> amdgpu_connector_virtual_helper_funcs = {
> -	.get_modes = amdgpu_connector_virtual_get_modes,
> -	.mode_valid = amdgpu_connector_virtual_mode_valid,
> -	.best_encoder = amdgpu_connector_virtual_encoder,
> -};
> -
> -static const struct drm_connector_funcs amdgpu_connector_virtual_funcs
> = {
> -	.dpms = amdgpu_connector_virtual_dpms,
> -	.detect = amdgpu_connector_virtual_detect,
> -	.fill_modes = drm_helper_probe_single_connector_modes,
> -	.set_property = amdgpu_connector_virtual_set_property,
> -	.destroy = amdgpu_connector_destroy,
> -	.force = amdgpu_connector_virtual_force,
> -};
> -
>  void
>  amdgpu_connector_add(struct amdgpu_device *adev,
>  		      uint32_t connector_id,
> @@ -1970,17 +1888,6 @@ amdgpu_connector_add(struct amdgpu_device
> *adev,
>  			connector->interlace_allowed = false;
>  			connector->doublescan_allowed = false;
>  			break;
> -		case DRM_MODE_CONNECTOR_VIRTUAL:
> -			amdgpu_dig_connector = kzalloc(sizeof(struct
> amdgpu_connector_atom_dig), GFP_KERNEL);
> -			if (!amdgpu_dig_connector)
> -				goto failed;
> -			amdgpu_connector->con_priv =
> amdgpu_dig_connector;
> -			drm_connector_init(dev, &amdgpu_connector->base,
> &amdgpu_connector_virtual_funcs, connector_type);
> -			drm_connector_helper_add(&amdgpu_connector-
> >base, &amdgpu_connector_virtual_helper_funcs);
> -			subpixel_order = SubPixelHorizontalRGB;
> -			connector->interlace_allowed = false;
> -			connector->doublescan_allowed = false;
> -			break;
>  		}
>  	}
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> index 29e0ce0..0c8b21e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> +++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
> @@ -39,6 +39,8 @@
> 
>  static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
> static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
> +static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
> +					      int index);
> 
>  /**
>   * dce_virtual_vblank_wait - vblank wait asic callback.
> @@ -274,24 +276,6 @@ static bool dce_virtual_crtc_mode_fixup(struct
> drm_crtc *crtc,
>  				     const struct drm_display_mode *mode,
>  				     struct drm_display_mode *adjusted_mode)
> {
> -	struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_encoder *encoder;
> -
> -	/* assign the encoder to the amdgpu crtc to avoid repeated lookups
> later */
> -	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> head) {
> -		if (encoder->crtc == crtc) {
> -			amdgpu_crtc->encoder = encoder;
> -			amdgpu_crtc->connector =
> amdgpu_get_connector_for_encoder(encoder);
> -			break;
> -		}
> -	}
> -	if ((amdgpu_crtc->encoder == NULL) || (amdgpu_crtc->connector ==
> NULL)) {
> -		amdgpu_crtc->encoder = NULL;
> -		amdgpu_crtc->connector = NULL;
> -		return false;
> -	}
> -
>  	return true;
>  }
> 
> @@ -370,38 +354,120 @@ static int dce_virtual_early_init(void *handle)
>  	return 0;
>  }
> 
> -static bool dce_virtual_get_connector_info(struct amdgpu_device *adev)
> +static struct drm_encoder *
> +dce_virtual_encoder(struct drm_connector *connector)
>  {
> -	struct amdgpu_i2c_bus_rec ddc_bus;
> -	struct amdgpu_router router;
> -	struct amdgpu_hpd hpd;
> +	int enc_id = connector->encoder_ids[0];
> +	struct drm_encoder *encoder;
> +	int i;
> +
> +	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> +		if (connector->encoder_ids[i] == 0)
> +			break;
> +
> +		encoder = drm_encoder_find(connector->dev, connector-
> >encoder_ids[i]);
> +		if (!encoder)
> +			continue;
> 
> -	/* look up gpio for ddc, hpd */
> -	ddc_bus.valid = false;
> -	hpd.hpd = AMDGPU_HPD_NONE;
> -	/* needed for aux chan transactions */
> -	ddc_bus.hpd = hpd.hpd;
> +		if (encoder->encoder_type ==
> DRM_MODE_ENCODER_VIRTUAL)
> +			return encoder;
> +	}
> 
> -	memset(&router, 0, sizeof(router));
> -	router.ddc_valid = false;
> -	router.cd_valid = false;
> -	amdgpu_display_add_connector(adev,
> -				      0,
> -				      ATOM_DEVICE_CRT1_SUPPORT,
> -				      DRM_MODE_CONNECTOR_VIRTUAL,
> &ddc_bus,
> -				      CONNECTOR_OBJECT_ID_VIRTUAL,
> -				      &hpd,
> -				      &router);
> +	/* pick the first one */
> +	if (enc_id)
> +		return drm_encoder_find(connector->dev, enc_id);
> +	return NULL;
> +}
> +
> +static int dce_virtual_get_modes(struct drm_connector *connector) {
> +	struct drm_device *dev = connector->dev;
> +	struct drm_display_mode *mode = NULL;
> +	unsigned i;
> +	static const struct mode_size {
> +		int w;
> +		int h;
> +	} common_modes[17] = {
> +		{ 640,  480},
> +		{ 720,  480},
> +		{ 800,  600},
> +		{ 848,  480},
> +		{1024,  768},
> +		{1152,  768},
> +		{1280,  720},
> +		{1280,  800},
> +		{1280,  854},
> +		{1280,  960},
> +		{1280, 1024},
> +		{1440,  900},
> +		{1400, 1050},
> +		{1680, 1050},
> +		{1600, 1200},
> +		{1920, 1080},
> +		{1920, 1200}
> +	};
> +
> +	for (i = 0; i < 17; i++) {
> +		mode = drm_cvt_mode(dev, common_modes[i].w,
> common_modes[i].h, 60, false, false, false);
> +		drm_mode_probed_add(connector, mode);
> +	}
> 
> -	amdgpu_display_add_encoder(adev,
> ENCODER_VIRTUAL_ENUM_VIRTUAL,
> -
> 	ATOM_DEVICE_CRT1_SUPPORT,
> -							0);
> +	return 0;
> +}
> 
> -	amdgpu_link_encoder_connector(adev->ddev);
> +static int dce_virtual_mode_valid(struct drm_connector *connector,
> +				  struct drm_display_mode *mode)
> +{
> +	return MODE_OK;
> +}
> 
> -	return true;
> +static int
> +dce_virtual_dpms(struct drm_connector *connector, int mode) {
> +	return 0;
>  }
> 
> +static enum drm_connector_status
> +dce_virtual_detect(struct drm_connector *connector, bool force) {
> +	return connector_status_connected;
> +}
> +
> +static int
> +dce_virtual_set_property(struct drm_connector *connector,
> +			 struct drm_property *property,
> +			 uint64_t val)
> +{
> +	return 0;
> +}
> +
> +static void dce_virtual_destroy(struct drm_connector *connector) {
> +	drm_connector_unregister(connector);
> +	drm_connector_cleanup(connector);
> +	kfree(connector);
> +}
> +
> +static void dce_virtual_force(struct drm_connector *connector) {
> +	return;
> +}
> +
> +static const struct drm_connector_helper_funcs
> dce_virtual_connector_helper_funcs = {
> +	.get_modes = dce_virtual_get_modes,
> +	.mode_valid = dce_virtual_mode_valid,
> +	.best_encoder = dce_virtual_encoder,
> +};
> +
> +static const struct drm_connector_funcs dce_virtual_connector_funcs = {
> +	.dpms = dce_virtual_dpms,
> +	.detect = dce_virtual_detect,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.set_property = dce_virtual_set_property,
> +	.destroy = dce_virtual_destroy,
> +	.force = dce_virtual_force,
> +};
> +
>  static int dce_virtual_sw_init(void *handle)  {
>  	int r, i;
> @@ -430,16 +496,16 @@ static int dce_virtual_sw_init(void *handle)
>  	adev->ddev->mode_config.max_width = 16384;
>  	adev->ddev->mode_config.max_height = 16384;
> 
> -	/* allocate crtcs */
> +	/* allocate crtcs, encoders, connectors */
>  	for (i = 0; i < adev->mode_info.num_crtc; i++) {
>  		r = dce_virtual_crtc_init(adev, i);
>  		if (r)
>  			return r;
> +		r = dce_virtual_connector_encoder_init(adev, i);
> +		if (r)
> +			return r;
>  	}
> 
> -	dce_virtual_get_connector_info(adev);
> -	amdgpu_print_display_setup(adev->ddev);
> -
>  	drm_kms_helper_poll_init(adev->ddev);
> 
>  	adev->mode_info.mode_config_initialized = true; @@ -540,8 +606,8
> @@ static void dce_virtual_encoder_commit(struct drm_encoder *encoder)
> 
>  static void
>  dce_virtual_encoder_mode_set(struct drm_encoder *encoder,
> -		      struct drm_display_mode *mode,
> -		      struct drm_display_mode *adjusted_mode)
> +			     struct drm_display_mode *mode,
> +			     struct drm_display_mode *adjusted_mode)
>  {
>  	return;
>  }
> @@ -561,10 +627,6 @@ static bool dce_virtual_encoder_mode_fixup(struct
> drm_encoder *encoder,
>  				    const struct drm_display_mode *mode,
>  				    struct drm_display_mode *adjusted_mode)
> {
> -
> -	/* set the active encoder to connector routing */
> -	amdgpu_encoder_set_active_device(encoder);
> -
>  	return true;
>  }
> 
> @@ -590,45 +652,40 @@ static const struct drm_encoder_funcs
> dce_virtual_encoder_funcs = {
>  	.destroy = dce_virtual_encoder_destroy,  };
> 
> -static void dce_virtual_encoder_add(struct amdgpu_device *adev,
> -				 uint32_t encoder_enum,
> -				 uint32_t supported_device,
> -				 u16 caps)
> +static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
> +					      int index)
>  {
> -	struct drm_device *dev = adev->ddev;
>  	struct drm_encoder *encoder;
> -	struct amdgpu_encoder *amdgpu_encoder;
> -
> -	/* see if we already added it */
> -	list_for_each_entry(encoder, &dev->mode_config.encoder_list,
> head) {
> -		amdgpu_encoder = to_amdgpu_encoder(encoder);
> -		if (amdgpu_encoder->encoder_enum == encoder_enum) {
> -			amdgpu_encoder->devices |= supported_device;
> -			return;
> -		}
> +	struct drm_connector *connector;
> 
> +	/* add a new encoder */
> +	encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL);
> +	if (!encoder) {
> +		kfree(connector);
> +		return -ENOMEM;
>  	}
> +	encoder->possible_crtcs = 1 << index;
> +	drm_encoder_init(adev->ddev, encoder,
> &dce_virtual_encoder_funcs,
> +			 DRM_MODE_ENCODER_VIRTUAL, NULL);
> +	drm_encoder_helper_add(encoder,
> &dce_virtual_encoder_helper_funcs);
> 
> -	/* add a new one */
> -	amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder),
> GFP_KERNEL);
> -	if (!amdgpu_encoder)
> -		return;
> +	connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
> +	if (!connector)
> +		return -ENOMEM;
> 
> -	encoder = &amdgpu_encoder->base;
> -	encoder->possible_crtcs = 0x1;
> -	amdgpu_encoder->enc_priv = NULL;
> -	amdgpu_encoder->encoder_enum = encoder_enum;
> -	amdgpu_encoder->encoder_id = (encoder_enum &
> OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
> -	amdgpu_encoder->devices = supported_device;
> -	amdgpu_encoder->rmx_type = RMX_OFF;
> -	amdgpu_encoder->underscan_type = UNDERSCAN_OFF;
> -	amdgpu_encoder->is_ext_encoder = false;
> -	amdgpu_encoder->caps = caps;
> -
> -	drm_encoder_init(dev, encoder, &dce_virtual_encoder_funcs,
> -					 DRM_MODE_ENCODER_VIRTUAL,
> NULL);
> -	drm_encoder_helper_add(encoder,
> &dce_virtual_encoder_helper_funcs);
> -	DRM_INFO("[FM]encoder: %d is VIRTUAL\n", amdgpu_encoder-
> >encoder_id);
> +	/* add a new connector */
> +	drm_connector_init(adev->ddev, connector,
> &dce_virtual_connector_funcs,
> +			   DRM_MODE_CONNECTOR_VIRTUAL);
> +	drm_connector_helper_add(connector,
> &dce_virtual_connector_helper_funcs);
> +	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
> +	connector->interlace_allowed = false;
> +	connector->doublescan_allowed = false;
> +	drm_connector_register(connector);
> +
> +	/* link them */
> +	drm_mode_connector_attach_encoder(connector, encoder);
> +
> +	return 0;
>  }
> 
>  static const struct amdgpu_display_funcs dce_virtual_display_funcs = { @@
> -644,8 +701,8 @@ static const struct amdgpu_display_funcs
> dce_virtual_display_funcs = {
>  	.hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
>  	.page_flip = &dce_virtual_page_flip,
>  	.page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
> -	.add_encoder = &dce_virtual_encoder_add,
> -	.add_connector = &amdgpu_connector_add,
> +	.add_encoder = NULL,
> +	.add_connector = NULL,
>  	.stop_mc_access = &dce_virtual_stop_mc_access,
>  	.resume_mc_access = &dce_virtual_resume_mc_access,  };
> --
> 2.5.5
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list