Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 048a5b76 authored by Emily Deng's avatar Emily Deng Committed by Alex Deucher
Browse files

drm/amdgpu: Add DRM_MODE_CONNECTOR_VIRTUAL connector in amdgpu_connector_add.



For virtual display feature, add one connector type in amdgpu_connector_add.

Signed-off-by: default avatarEmily Deng <Emily.Deng@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6b5084cc
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
@@ -1504,6 +1504,86 @@ 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;
}

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

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,
@@ -1888,6 +1968,17 @@ 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;
		}
	}