Skip to content

Commit

Permalink
drm/i915: create intel_digital_port and use it
Browse files Browse the repository at this point in the history
The goal is to have one single encoder capable of controlling both DP
and HDMI outputs. This patch just adds the initial infrastructure, no
functional changes.

Previously, both intel_dp and intel_hdmi were intel_encoders. Now,
these 2 structs do not have intel_encoder as members anymore. The new
struct intel_digital_port has intel_encoder as a member, and it also
includes intel_dp and intel_hdmi as members. In other words: see the
changes inside intel_drv.h: it's the most important change, everything
else is only to make it compile and work.

For now, each intel_digital_port is still only able to control one of
HDMI or DP, but not both together.

In the future we should also try to merge the common fields from
intel_dp and intel_hdmi (e.g., port).

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
[danvet: Add the missing ' ' spotted by Damien Lespiau.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Paulo Zanoni authored and Daniel Vetter committed Nov 11, 2012
1 parent 30add22 commit da63a9f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 36 deletions.
59 changes: 36 additions & 23 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
*/
static bool is_edp(struct intel_dp *intel_dp)
{
return intel_dp->base.type == INTEL_OUTPUT_EDP;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);

return intel_dig_port->base.type == INTEL_OUTPUT_EDP;
}

/**
Expand Down Expand Up @@ -76,7 +78,9 @@ static bool is_cpu_edp(struct intel_dp *intel_dp)

static struct drm_device *intel_dp_to_dev(struct intel_dp *intel_dp)
{
return intel_dp->base.base.dev;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);

return intel_dig_port->base.base.dev;
}

static struct intel_dp *intel_attached_dp(struct drm_connector *connector)
Expand Down Expand Up @@ -1169,9 +1173,10 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)

void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
int pipe = to_intel_crtc(intel_dp->base.base.crtc)->pipe;
int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe;
u32 pp;

if (!is_edp(intel_dp))
Expand Down Expand Up @@ -1214,8 +1219,9 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp)

static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;

Expand All @@ -1239,8 +1245,9 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)

static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpa_ctl;

Expand Down Expand Up @@ -1773,7 +1780,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp,
void
intel_dp_start_link_train(struct intel_dp *intel_dp)
{
struct drm_encoder *encoder = &intel_dp->base.base;
struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base;
struct drm_device *dev = encoder->dev;
int i;
uint8_t voltage;
Expand Down Expand Up @@ -1946,7 +1953,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
static void
intel_dp_link_down(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t DP = intel_dp->DP;

Expand Down Expand Up @@ -1986,7 +1994,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)

if (HAS_PCH_IBX(dev) &&
I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
struct drm_crtc *crtc = intel_dp->base.base.crtc;
struct drm_crtc *crtc = intel_dig_port->base.base.crtc;

/* Hardware workaround: leaving our transcoder select
* set to transcoder B while it's off will prevent the
Expand Down Expand Up @@ -2102,13 +2110,14 @@ intel_dp_handle_test_request(struct intel_dp *intel_dp)
static void
intel_dp_check_link_status(struct intel_dp *intel_dp)
{
struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
u8 sink_irq_vector;
u8 link_status[DP_LINK_STATUS_SIZE];

if (!intel_dp->base.connectors_active)
if (!intel_encoder->connectors_active)
return;

if (WARN_ON(!intel_dp->base.base.crtc))
if (WARN_ON(!intel_encoder->base.crtc))
return;

/* Try to read receiver status if the link appears to be up */
Expand Down Expand Up @@ -2139,7 +2148,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)

if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
drm_get_encoder_name(&intel_dp->base.base));
drm_get_encoder_name(&intel_encoder->base));
intel_dp_start_link_train(intel_dp);
intel_dp_complete_link_train(intel_dp);
}
Expand Down Expand Up @@ -2368,7 +2377,8 @@ intel_dp_set_property(struct drm_connector *connector,
{
struct drm_i915_private *dev_priv = connector->dev->dev_private;
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
int ret;

ret = drm_connector_property_set_value(connector, property, val);
Expand Down Expand Up @@ -2423,8 +2433,8 @@ intel_dp_set_property(struct drm_connector *connector,
return -EINVAL;

done:
if (intel_dp->base.base.crtc) {
struct drm_crtc *crtc = intel_dp->base.base.crtc;
if (intel_encoder->base.crtc) {
struct drm_crtc *crtc = intel_encoder->base.crtc;
intel_set_mode(crtc, &crtc->mode,
crtc->x, crtc->y, crtc->fb);
}
Expand Down Expand Up @@ -2454,15 +2464,16 @@ intel_dp_destroy(struct drm_connector *connector)

static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
struct intel_dp *intel_dp = &intel_dig_port->dp;

i2c_del_adapter(&intel_dp->adapter);
drm_encoder_cleanup(encoder);
if (is_edp(intel_dp)) {
cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
ironlake_panel_vdd_off_sync(intel_dp);
}
kfree(intel_dp);
kfree(intel_dig_port);
}

static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
Expand Down Expand Up @@ -2680,25 +2691,27 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
struct intel_dp *intel_dp;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct intel_digital_port *intel_dig_port;
struct drm_display_mode *fixed_mode = NULL;
const char *name = NULL;
int type;

intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL);
if (!intel_dp)
intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
if (!intel_dig_port)
return;

intel_dp = &intel_dig_port->dp;
intel_dp->output_reg = output_reg;
intel_dp->port = port;
/* Preserve the current hw state. */
intel_dp->DP = I915_READ(intel_dp->output_reg);

intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
if (!intel_connector) {
kfree(intel_dp);
kfree(intel_dig_port);
return;
}
intel_encoder = &intel_dp->base;
intel_encoder = &intel_dig_port->base;
intel_dp->attached_connector = intel_connector;

if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D)
Expand Down
30 changes: 27 additions & 3 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ struct dip_infoframe {
} __attribute__((packed));

struct intel_hdmi {
struct intel_encoder base;
u32 sdvox_reg;
int ddc_bus;
int ddi_port;
Expand All @@ -349,7 +348,6 @@ struct intel_hdmi {
#define DP_LINK_CONFIGURATION_SIZE 9

struct intel_dp {
struct intel_encoder base;
uint32_t output_reg;
uint32_t DP;
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
Expand All @@ -375,6 +373,12 @@ struct intel_dp {
struct intel_connector *attached_connector;
};

struct intel_digital_port {
struct intel_encoder base;
struct intel_dp dp;
struct intel_hdmi hdmi;
};

static inline struct drm_crtc *
intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
{
Expand Down Expand Up @@ -502,7 +506,27 @@ static inline struct intel_encoder *intel_attached_encoder(struct drm_connector

static inline struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder)
{
return container_of(encoder, struct intel_dp, base.base);
struct intel_digital_port *intel_dig_port =
container_of(encoder, struct intel_digital_port, base.base);
return &intel_dig_port->dp;
}

static inline struct intel_digital_port *
enc_to_dig_port(struct drm_encoder *encoder)
{
return container_of(encoder, struct intel_digital_port, base.base);
}

static inline struct intel_digital_port *
dp_to_dig_port(struct intel_dp *intel_dp)
{
return container_of(intel_dp, struct intel_digital_port, dp);
}

static inline struct intel_digital_port *
hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
{
return container_of(intel_hdmi, struct intel_digital_port, hdmi);
}

extern void intel_connector_attach_encoder(struct intel_connector *connector,
Expand Down
25 changes: 15 additions & 10 deletions drivers/gpu/drm/i915/intel_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
{
return intel_hdmi->base.base.dev;
return hdmi_to_dig_port(intel_hdmi)->base.base.dev;
}

static void
Expand All @@ -56,13 +56,14 @@ assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi)

struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
{
return container_of(encoder, struct intel_hdmi, base.base);
struct intel_digital_port *intel_dig_port =
container_of(encoder, struct intel_digital_port, base.base);
return &intel_dig_port->hdmi;
}

static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector)
{
return container_of(intel_attached_encoder(connector),
struct intel_hdmi, base);
return enc_to_intel_hdmi(&intel_attached_encoder(connector)->base);
}

void intel_dip_infoframe_csum(struct dip_infoframe *frame)
Expand Down Expand Up @@ -864,6 +865,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
uint64_t val)
{
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
struct intel_digital_port *intel_dig_port =
hdmi_to_dig_port(intel_hdmi);
struct drm_i915_private *dev_priv = connector->dev->dev_private;
int ret;

Expand Down Expand Up @@ -903,8 +906,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
return -EINVAL;

done:
if (intel_hdmi->base.base.crtc) {
struct drm_crtc *crtc = intel_hdmi->base.base.crtc;
if (intel_dig_port->base.base.crtc) {
struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
intel_set_mode(crtc, &crtc->mode,
crtc->x, crtc->y, crtc->fb);
}
Expand Down Expand Up @@ -962,19 +965,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
struct drm_connector *connector;
struct intel_encoder *intel_encoder;
struct intel_connector *intel_connector;
struct intel_digital_port *intel_dig_port;
struct intel_hdmi *intel_hdmi;

intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL);
if (!intel_hdmi)
intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
if (!intel_dig_port)
return;

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

intel_encoder = &intel_hdmi->base;
intel_hdmi = &intel_dig_port->hdmi;
intel_encoder = &intel_dig_port->base;
drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs,
DRM_MODE_ENCODER_TMDS);

Expand Down

0 comments on commit da63a9f

Please sign in to comment.