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

Commit 8f2535d9 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/crt: Introduce struct intel_crt



We will use this structure in future patches to store CRT specific
information on the encoder.

Split out and tweaked from a patch by Keith Packard.

Signed-off-by: default avatarKeith Packard <keithp@kithp.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 3143a2bf
Loading
Loading
Loading
Loading
+37 −27
Original line number Diff line number Diff line
@@ -34,6 +34,16 @@
#include "i915_drm.h"
#include "i915_drv.h"

struct intel_crt {
	struct intel_encoder base;
};

static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
{
	return container_of(intel_attached_encoder(connector),
			    struct intel_crt, base);
}

static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
@@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
	return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
}

static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
static bool intel_crt_detect_ddc(struct intel_crt *crt)
{
	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
	struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;

	/* CRT should always be at 0, but check anyway */
	if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
	if (crt->base.type != INTEL_OUTPUT_ANALOG)
		return false;

	if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) {
@@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
		return true;
	}

	if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) {
	if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
		DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
		return true;
	}
@@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
}

static enum drm_connector_status
intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt)
{
	struct drm_encoder *encoder = &intel_encoder->base;
	struct drm_encoder *encoder = &crt->base.base;
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -434,7 +443,7 @@ static enum drm_connector_status
intel_crt_detect(struct drm_connector *connector, bool force)
{
	struct drm_device *dev = connector->dev;
	struct intel_encoder *encoder = intel_attached_encoder(connector);
	struct intel_crt *crt = intel_attached_crt(connector);
	struct drm_crtc *crtc;
	int dpms_mode;
	enum drm_connector_status status;
@@ -447,24 +456,25 @@ intel_crt_detect(struct drm_connector *connector, bool force)
			return connector_status_disconnected;
	}

	if (intel_crt_detect_ddc(&encoder->base))
	if (intel_crt_detect_ddc(crt))
		return connector_status_connected;

	if (!force)
		return connector->status;

	/* for pre-945g platforms use load detect */
	if (encoder->base.crtc && encoder->base.crtc->enabled) {
		status = intel_crt_load_detect(encoder->base.crtc, encoder);
	crtc = crt->base.base.crtc;
	if (crtc && crtc->enabled) {
		status = intel_crt_load_detect(crtc, crt);
	} else {
		crtc = intel_get_load_detect_pipe(encoder, connector,
		crtc = intel_get_load_detect_pipe(&crt->base, connector,
						  NULL, &dpms_mode);
		if (crtc) {
			if (intel_crt_detect_ddc(&encoder->base))
			if (intel_crt_detect_ddc(crt))
				status = connector_status_connected;
			else
				status = intel_crt_load_detect(crtc, encoder);
			intel_release_load_detect_pipe(encoder,
				status = intel_crt_load_detect(crtc, crt);
			intel_release_load_detect_pipe(&crt->base,
						       connector, dpms_mode);
		} else
			status = connector_status_unknown;
@@ -536,17 +546,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
void intel_crt_init(struct drm_device *dev)
{
	struct drm_connector *connector;
	struct intel_encoder *intel_encoder;
	struct intel_crt *crt;
	struct intel_connector *intel_connector;
	struct drm_i915_private *dev_priv = dev->dev_private;

	intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
	if (!intel_encoder)
	crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
	if (!crt)
		return;

	intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
	if (!intel_connector) {
		kfree(intel_encoder);
		kfree(crt);
		return;
	}

@@ -554,20 +564,20 @@ void intel_crt_init(struct drm_device *dev)
	drm_connector_init(dev, &intel_connector->base,
			   &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);

	drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs,
	drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs,
			 DRM_MODE_ENCODER_DAC);

	intel_connector_attach_encoder(intel_connector, intel_encoder);
	intel_connector_attach_encoder(intel_connector, &crt->base);

	intel_encoder->type = INTEL_OUTPUT_ANALOG;
	intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
				   (1 << INTEL_ANALOG_CLONE_BIT) |
				   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
	crt->base.type = INTEL_OUTPUT_ANALOG;
	crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT |
				1 << INTEL_ANALOG_CLONE_BIT |
				1 << INTEL_SDVO_LVDS_CLONE_BIT);
	crt->base.crtc_mask = (1 << 0) | (1 << 1);
	connector->interlace_allowed = 1;
	connector->doublescan_allowed = 0;

	drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs);
	drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs);
	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);

	drm_sysfs_connector_add(connector);