summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/gma500/cdv_intel_hdmi.c')
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c112
1 files changed, 65 insertions, 47 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index cbca2b0..50d7cfb 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -63,8 +63,8 @@ static void cdv_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+ struct psb_intel_encoder *psb_intel_encoder = to_psb_intel_encoder(encoder);
+ struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
u32 hdmib;
struct drm_crtc *crtc = encoder->crtc;
struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc);
@@ -98,8 +98,9 @@ static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder,
static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
- struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+ struct psb_intel_encoder *psb_intel_encoder =
+ to_psb_intel_encoder(encoder);
+ struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
u32 hdmib;
hdmib = REG_READ(hdmi_priv->hdmi_reg);
@@ -114,8 +115,9 @@ static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
static void cdv_hdmi_save(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct psb_intel_output *output = to_psb_intel_output(connector);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+ struct psb_intel_encoder *psb_intel_encoder =
+ psb_intel_attached_encoder(connector);
+ struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
}
@@ -123,8 +125,9 @@ static void cdv_hdmi_save(struct drm_connector *connector)
static void cdv_hdmi_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct psb_intel_output *output = to_psb_intel_output(connector);
- struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv;
+ struct psb_intel_encoder *psb_intel_encoder =
+ psb_intel_attached_encoder(connector);
+ struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
REG_READ(hdmi_priv->hdmi_reg);
@@ -133,14 +136,15 @@ static void cdv_hdmi_restore(struct drm_connector *connector)
static enum drm_connector_status cdv_hdmi_detect(
struct drm_connector *connector, bool force)
{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
- struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv;
+ struct psb_intel_encoder *psb_intel_encoder =
+ psb_intel_attached_encoder(connector);
+ struct psb_intel_connector *psb_intel_connector =
+ to_psb_intel_connector(connector);
+ struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected;
- edid = drm_get_edid(&psb_intel_output->base,
- psb_intel_output->hdmi_i2c_adapter);
+ edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);
hdmi_priv->has_hdmi_sink = false;
hdmi_priv->has_hdmi_audio = false;
@@ -153,7 +157,7 @@ static enum drm_connector_status cdv_hdmi_detect(
drm_detect_monitor_audio(edid);
}
- psb_intel_output->base.display_info.raw_edid = NULL;
+ psb_intel_connector->base.display_info.raw_edid = NULL;
kfree(edid);
}
return status;
@@ -220,17 +224,15 @@ static int cdv_hdmi_set_property(struct drm_connector *connector,
*/
static int cdv_hdmi_get_modes(struct drm_connector *connector)
{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
+ struct psb_intel_encoder *psb_intel_encoder =
+ psb_intel_attached_encoder(connector);
struct edid *edid = NULL;
int ret = 0;
- edid = drm_get_edid(&psb_intel_output->base,
- psb_intel_output->hdmi_i2c_adapter);
+ edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);
if (edid) {
- drm_mode_connector_update_edid_property(&psb_intel_output->
- base, edid);
- ret = drm_add_edid_modes(&psb_intel_output->base, edid);
+ drm_mode_connector_update_edid_property(connector, edid);
+ ret = drm_add_edid_modes(connector, edid);
kfree(edid);
}
return ret;
@@ -266,11 +268,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector,
static void cdv_hdmi_destroy(struct drm_connector *connector)
{
- struct psb_intel_output *psb_intel_output =
- to_psb_intel_output(connector);
+ struct psb_intel_encoder *psb_intel_encoder =
+ psb_intel_attached_encoder(connector);
- if (psb_intel_output->ddc_bus)
- psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
+ if (psb_intel_encoder->i2c_bus)
+ psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
@@ -304,34 +306,45 @@ static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
void cdv_hdmi_init(struct drm_device *dev,
struct psb_intel_mode_device *mode_dev, int reg)
{
- struct psb_intel_output *psb_intel_output;
+ struct psb_intel_encoder *psb_intel_encoder;
+ struct psb_intel_connector *psb_intel_connector;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct mid_intel_hdmi_priv *hdmi_priv;
int ddc_bus;
- psb_intel_output = kzalloc(sizeof(struct psb_intel_output) +
- sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
- if (!psb_intel_output)
+ psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
+ GFP_KERNEL);
+
+ if (!psb_intel_encoder)
return;
- hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1);
- psb_intel_output->mode_dev = mode_dev;
- connector = &psb_intel_output->base;
- encoder = &psb_intel_output->enc;
- drm_connector_init(dev, &psb_intel_output->base,
+ psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector),
+ GFP_KERNEL);
+
+ if (!psb_intel_connector)
+ goto err_connector;
+
+ hdmi_priv = kzalloc(sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL);
+
+ if (!hdmi_priv)
+ goto err_priv;
+
+ connector = &psb_intel_connector->base;
+ encoder = &psb_intel_encoder->base;
+ drm_connector_init(dev, connector,
&cdv_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_DVID);
- drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
+ drm_encoder_init(dev, encoder, &psb_intel_lvds_enc_funcs,
DRM_MODE_ENCODER_TMDS);
- drm_mode_connector_attach_encoder(&psb_intel_output->base,
- &psb_intel_output->enc);
- psb_intel_output->type = INTEL_OUTPUT_HDMI;
+ psb_intel_connector_attach_encoder(psb_intel_connector,
+ psb_intel_encoder);
+ psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
hdmi_priv->hdmi_reg = reg;
hdmi_priv->has_hdmi_sink = false;
- psb_intel_output->dev_priv = hdmi_priv;
+ psb_intel_encoder->dev_priv = hdmi_priv;
drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs);
drm_connector_helper_add(connector,
@@ -341,7 +354,8 @@ void cdv_hdmi_init(struct drm_device *dev,
connector->doublescan_allowed = false;
drm_connector_attach_property(connector,
- dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
+ dev->mode_config.scaling_mode_property,
+ DRM_MODE_SCALE_FULLSCREEN);
switch (reg) {
case SDVOB:
@@ -356,21 +370,25 @@ void cdv_hdmi_init(struct drm_device *dev,
break;
}
- psb_intel_output->ddc_bus = psb_intel_i2c_create(dev,
+ psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev,
ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC");
- if (!psb_intel_output->ddc_bus) {
+ if (!psb_intel_encoder->i2c_bus) {
dev_err(dev->dev, "No ddc adapter available!\n");
goto failed_ddc;
}
- psb_intel_output->hdmi_i2c_adapter =
- &(psb_intel_output->ddc_bus->adapter);
+
+ hdmi_priv->hdmi_i2c_adapter =
+ &(psb_intel_encoder->i2c_bus->adapter);
hdmi_priv->dev = dev;
drm_sysfs_connector_add(connector);
return;
failed_ddc:
- drm_encoder_cleanup(&psb_intel_output->enc);
- drm_connector_cleanup(&psb_intel_output->base);
- kfree(psb_intel_output);
+ drm_encoder_cleanup(encoder);
+ drm_connector_cleanup(connector);
+err_priv:
+ kfree(psb_intel_connector);
+err_connector:
+ kfree(psb_intel_encoder);
}