提交 da63a9f2 编写于 作者: P Paulo Zanoni 提交者: Daniel Vetter

drm/i915: create intel_digital_port and use it

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: NPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: NDamien Lespiau <damien.lespiau@intel.com>
[danvet: Add the missing ' ' spotted by Damien Lespiau.]
Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
上级 30add22d
......@@ -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;
}
/**
......@@ -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)
......@@ -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))
......@@ -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;
......@@ -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;
......@@ -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;
......@@ -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;
......@@ -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
......@@ -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 */
......@@ -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);
}
......@@ -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);
......@@ -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);
}
......@@ -2454,7 +2464,8 @@ 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);
......@@ -2462,7 +2473,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
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 = {
......@@ -2680,14 +2691,16 @@ 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. */
......@@ -2695,10 +2708,10 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
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)
......
......@@ -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;
......@@ -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];
......@@ -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)
{
......@@ -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,
......
......@@ -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
......@@ -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)
......@@ -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;
......@@ -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);
}
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册