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

Submitted by Alex Deucher on Sept. 30, 2016, 5:08 p.m.

Details

Message ID 1475255328-21598-4-git-send-email-alexander.deucher@amd.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Alex Deucher Sept. 30, 2016, 5:08 p.m.
No need to emulate all of the stuff for real hw.

Signed-off-by: Alex Deucher <alexander.deucher@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(-)

Patch hide | download patch | download mbox

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,
 };

Comments

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


> -----Original Message-----

> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf

> Of Alex Deucher

> Sent: Saturday, October 01, 2016 1:09 AM

> To: amd-gfx@lists.freedesktop.org

> Cc: Deucher, Alexander <Alexander.Deucher@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@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@lists.freedesktop.org

> https://lists.freedesktop.org/mailman/listinfo/amd-gfx