Commit a12d6a07 authored by Patrik Jakobsson's avatar Patrik Jakobsson Committed by Dave Airlie

gma500: Convert Cedarview to work with new output handling

Replace psb_intel_output with psb_intel_encoder and psb_intel_connector.
Things will need to be cleaned up and tested so consider this an initial
patch for Cedarview.
Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5736995b
...@@ -204,9 +204,10 @@ static enum drm_connector_status cdv_intel_crt_detect( ...@@ -204,9 +204,10 @@ static enum drm_connector_status cdv_intel_crt_detect(
static void cdv_intel_crt_destroy(struct drm_connector *connector) static void cdv_intel_crt_destroy(struct drm_connector *connector)
{ {
struct psb_intel_output *intel_output = to_psb_intel_output(connector); struct psb_intel_encoder *psb_intel_encoder =
psb_intel_attached_encoder(connector);
psb_intel_i2c_destroy(intel_output->ddc_bus); psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(connector);
...@@ -214,9 +215,9 @@ static void cdv_intel_crt_destroy(struct drm_connector *connector) ...@@ -214,9 +215,9 @@ static void cdv_intel_crt_destroy(struct drm_connector *connector)
static int cdv_intel_crt_get_modes(struct drm_connector *connector) static int cdv_intel_crt_get_modes(struct drm_connector *connector)
{ {
struct psb_intel_output *intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(connector); psb_intel_attached_encoder(connector);
return psb_intel_ddc_get_modes(intel_output); return psb_intel_ddc_get_modes(connector, &psb_intel_encoder->ddc_bus->adapter);
} }
static int cdv_intel_crt_set_property(struct drm_connector *connector, static int cdv_intel_crt_set_property(struct drm_connector *connector,
...@@ -266,27 +267,31 @@ void cdv_intel_crt_init(struct drm_device *dev, ...@@ -266,27 +267,31 @@ void cdv_intel_crt_init(struct drm_device *dev,
struct psb_intel_mode_device *mode_dev) struct psb_intel_mode_device *mode_dev)
{ {
struct psb_intel_output *psb_intel_output; struct psb_intel_connector *psb_intel_connector;
struct psb_intel_encoder *psb_intel_encoder;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_encoder *encoder; struct drm_encoder *encoder;
u32 i2c_reg; u32 i2c_reg;
psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
if (!psb_intel_output) if (!psb_intel_encoder)
return; return;
psb_intel_output->mode_dev = mode_dev; psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
connector = &psb_intel_output->base; if (!psb_intel_connector)
goto failed_connector;
connector = &psb_intel_connector->base;
drm_connector_init(dev, connector, drm_connector_init(dev, connector,
&cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
encoder = &psb_intel_output->enc; encoder = &psb_intel_encoder->base;
drm_encoder_init(dev, encoder, drm_encoder_init(dev, encoder,
&cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
drm_mode_connector_attach_encoder(&psb_intel_output->base, psb_intel_connector_attach_encoder(psb_intel_connector,
&psb_intel_output->enc); psb_intel_encoder);
/* Set up the DDC bus. */ /* Set up the DDC bus. */
i2c_reg = GPIOA; i2c_reg = GPIOA;
...@@ -295,15 +300,15 @@ void cdv_intel_crt_init(struct drm_device *dev, ...@@ -295,15 +300,15 @@ void cdv_intel_crt_init(struct drm_device *dev,
if (dev_priv->crt_ddc_bus != 0) if (dev_priv->crt_ddc_bus != 0)
i2c_reg = dev_priv->crt_ddc_bus; i2c_reg = dev_priv->crt_ddc_bus;
}*/ }*/
psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, psb_intel_encoder->ddc_bus = psb_intel_i2c_create(dev,
i2c_reg, "CRTDDC_A"); i2c_reg, "CRTDDC_A");
if (!psb_intel_output->ddc_bus) { if (!psb_intel_encoder->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n"); "failed.\n");
goto failed_ddc; goto failed_ddc;
} }
psb_intel_output->type = INTEL_OUTPUT_ANALOG; psb_intel_encoder->type = INTEL_OUTPUT_ANALOG;
/* /*
psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT); psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT);
psb_intel_output->crtc_mask = (1 << 0) | (1 << 1); psb_intel_output->crtc_mask = (1 << 0) | (1 << 1);
...@@ -319,8 +324,10 @@ void cdv_intel_crt_init(struct drm_device *dev, ...@@ -319,8 +324,10 @@ void cdv_intel_crt_init(struct drm_device *dev,
return; return;
failed_ddc: failed_ddc:
drm_encoder_cleanup(&psb_intel_output->enc); drm_encoder_cleanup(&psb_intel_encoder->base);
drm_connector_cleanup(&psb_intel_output->base); drm_connector_cleanup(&psb_intel_connector->base);
kfree(psb_intel_output); kfree(psb_intel_connector);
failed_connector:
kfree(psb_intel_encoder);
return; return;
} }
...@@ -342,7 +342,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, ...@@ -342,7 +342,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc,
} }
/* /*
* Returns whether any output on the specified pipe is of the specified type * Returns whether any encoder on the specified pipe is of the specified type
*/ */
bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type) bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type)
{ {
...@@ -352,9 +352,9 @@ bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type) ...@@ -352,9 +352,9 @@ bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type)
list_for_each_entry(l_entry, &mode_config->connector_list, head) { list_for_each_entry(l_entry, &mode_config->connector_list, head) {
if (l_entry->encoder && l_entry->encoder->crtc == crtc) { if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(l_entry); psb_intel_attached_encoder(l_entry);
if (psb_intel_output->type == type) if (psb_intel_encoder->type == type)
return true; return true;
} }
} }
...@@ -752,14 +752,14 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, ...@@ -752,14 +752,14 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc,
struct drm_connector *connector; struct drm_connector *connector;
list_for_each_entry(connector, &mode_config->connector_list, head) { list_for_each_entry(connector, &mode_config->connector_list, head) {
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(connector); psb_intel_attached_encoder(connector);
if (!connector->encoder if (!connector->encoder
|| connector->encoder->crtc != crtc) || connector->encoder->crtc != crtc)
continue; continue;
switch (psb_intel_output->type) { switch (psb_intel_encoder->type) {
case INTEL_OUTPUT_LVDS: case INTEL_OUTPUT_LVDS:
is_lvds = true; is_lvds = true;
break; break;
......
...@@ -63,8 +63,8 @@ static void cdv_hdmi_mode_set(struct drm_encoder *encoder, ...@@ -63,8 +63,8 @@ static void cdv_hdmi_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct psb_intel_encoder *psb_intel_encoder = to_psb_intel_encoder(encoder);
struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
u32 hdmib; u32 hdmib;
struct drm_crtc *crtc = encoder->crtc; struct drm_crtc *crtc = encoder->crtc;
struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(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, ...@@ -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) static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct psb_intel_encoder *psb_intel_encoder =
struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; to_psb_intel_encoder(encoder);
struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_encoder->dev_priv;
u32 hdmib; u32 hdmib;
hdmib = REG_READ(hdmi_priv->hdmi_reg); hdmib = REG_READ(hdmi_priv->hdmi_reg);
...@@ -114,8 +115,9 @@ static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode) ...@@ -114,8 +115,9 @@ static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode)
static void cdv_hdmi_save(struct drm_connector *connector) static void cdv_hdmi_save(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct psb_intel_output *output = to_psb_intel_output(connector); struct psb_intel_encoder *psb_intel_encoder =
struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; 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); hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg);
} }
...@@ -123,8 +125,9 @@ static void cdv_hdmi_save(struct drm_connector *connector) ...@@ -123,8 +125,9 @@ static void cdv_hdmi_save(struct drm_connector *connector)
static void cdv_hdmi_restore(struct drm_connector *connector) static void cdv_hdmi_restore(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct psb_intel_output *output = to_psb_intel_output(connector); struct psb_intel_encoder *psb_intel_encoder =
struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; 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_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB);
REG_READ(hdmi_priv->hdmi_reg); REG_READ(hdmi_priv->hdmi_reg);
...@@ -133,14 +136,15 @@ static void cdv_hdmi_restore(struct drm_connector *connector) ...@@ -133,14 +136,15 @@ static void cdv_hdmi_restore(struct drm_connector *connector)
static enum drm_connector_status cdv_hdmi_detect( static enum drm_connector_status cdv_hdmi_detect(
struct drm_connector *connector, bool force) struct drm_connector *connector, bool force)
{ {
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(connector); psb_intel_attached_encoder(connector);
struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv; 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; struct edid *edid = NULL;
enum drm_connector_status status = connector_status_disconnected; enum drm_connector_status status = connector_status_disconnected;
edid = drm_get_edid(&psb_intel_output->base, edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);
psb_intel_output->hdmi_i2c_adapter);
hdmi_priv->has_hdmi_sink = false; hdmi_priv->has_hdmi_sink = false;
hdmi_priv->has_hdmi_audio = false; hdmi_priv->has_hdmi_audio = false;
...@@ -153,7 +157,7 @@ static enum drm_connector_status cdv_hdmi_detect( ...@@ -153,7 +157,7 @@ static enum drm_connector_status cdv_hdmi_detect(
drm_detect_monitor_audio(edid); 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); kfree(edid);
} }
return status; return status;
...@@ -220,17 +224,15 @@ static int cdv_hdmi_set_property(struct drm_connector *connector, ...@@ -220,17 +224,15 @@ static int cdv_hdmi_set_property(struct drm_connector *connector,
*/ */
static int cdv_hdmi_get_modes(struct drm_connector *connector) static int cdv_hdmi_get_modes(struct drm_connector *connector)
{ {
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(connector); psb_intel_attached_encoder(connector);
struct edid *edid = NULL; struct edid *edid = NULL;
int ret = 0; int ret = 0;
edid = drm_get_edid(&psb_intel_output->base, edid = drm_get_edid(connector, &psb_intel_encoder->i2c_bus->adapter);
psb_intel_output->hdmi_i2c_adapter);
if (edid) { if (edid) {
drm_mode_connector_update_edid_property(&psb_intel_output-> drm_mode_connector_update_edid_property(connector, edid);
base, edid); ret = drm_add_edid_modes(connector, edid);
ret = drm_add_edid_modes(&psb_intel_output->base, edid);
kfree(edid); kfree(edid);
} }
return ret; return ret;
...@@ -266,11 +268,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector, ...@@ -266,11 +268,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector,
static void cdv_hdmi_destroy(struct drm_connector *connector) static void cdv_hdmi_destroy(struct drm_connector *connector)
{ {
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(connector); psb_intel_attached_encoder(connector);
if (psb_intel_output->ddc_bus) if (psb_intel_encoder->i2c_bus)
psb_intel_i2c_destroy(psb_intel_output->ddc_bus); psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(connector);
...@@ -304,34 +306,45 @@ static const struct drm_connector_funcs cdv_hdmi_connector_funcs = { ...@@ -304,34 +306,45 @@ static const struct drm_connector_funcs cdv_hdmi_connector_funcs = {
void cdv_hdmi_init(struct drm_device *dev, void cdv_hdmi_init(struct drm_device *dev,
struct psb_intel_mode_device *mode_dev, int reg) 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_connector *connector;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct mid_intel_hdmi_priv *hdmi_priv; struct mid_intel_hdmi_priv *hdmi_priv;
int ddc_bus; int ddc_bus;
psb_intel_output = kzalloc(sizeof(struct psb_intel_output) + psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); GFP_KERNEL);
if (!psb_intel_output)
if (!psb_intel_encoder)
return; return;
hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1); psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector),
psb_intel_output->mode_dev = mode_dev; GFP_KERNEL);
connector = &psb_intel_output->base;
encoder = &psb_intel_output->enc; if (!psb_intel_connector)
drm_connector_init(dev, &psb_intel_output->base, 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, &cdv_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_DVID); 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_ENCODER_TMDS);
drm_mode_connector_attach_encoder(&psb_intel_output->base, psb_intel_connector_attach_encoder(psb_intel_connector,
&psb_intel_output->enc); psb_intel_encoder);
psb_intel_output->type = INTEL_OUTPUT_HDMI; psb_intel_encoder->type = INTEL_OUTPUT_HDMI;
hdmi_priv->hdmi_reg = reg; hdmi_priv->hdmi_reg = reg;
hdmi_priv->has_hdmi_sink = false; 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_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs);
drm_connector_helper_add(connector, drm_connector_helper_add(connector,
...@@ -341,7 +354,8 @@ void cdv_hdmi_init(struct drm_device *dev, ...@@ -341,7 +354,8 @@ void cdv_hdmi_init(struct drm_device *dev,
connector->doublescan_allowed = false; connector->doublescan_allowed = false;
drm_connector_attach_property(connector, 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) { switch (reg) {
case SDVOB: case SDVOB:
...@@ -356,21 +370,25 @@ void cdv_hdmi_init(struct drm_device *dev, ...@@ -356,21 +370,25 @@ void cdv_hdmi_init(struct drm_device *dev,
break; 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"); 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"); dev_err(dev->dev, "No ddc adapter available!\n");
goto failed_ddc; 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; hdmi_priv->dev = dev;
drm_sysfs_connector_add(connector); drm_sysfs_connector_add(connector);
return; return;
failed_ddc: failed_ddc:
drm_encoder_cleanup(&psb_intel_output->enc); drm_encoder_cleanup(encoder);
drm_connector_cleanup(&psb_intel_output->base); drm_connector_cleanup(connector);
kfree(psb_intel_output); err_priv:
kfree(psb_intel_connector);
err_connector:
kfree(psb_intel_encoder);
} }
...@@ -195,8 +195,9 @@ static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level) ...@@ -195,8 +195,9 @@ static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level)
* Sets the power state for the panel. * Sets the power state for the panel.
*/ */
static void cdv_intel_lvds_set_power(struct drm_device *dev, static void cdv_intel_lvds_set_power(struct drm_device *dev,
struct psb_intel_output *output, bool on) struct drm_encoder *encoder, bool on)
{ {
struct drm_psb_private *dev_priv = dev->dev_private;
u32 pp_status; u32 pp_status;
if (!gma_power_begin(dev, true)) if (!gma_power_begin(dev, true))
...@@ -210,8 +211,7 @@ static void cdv_intel_lvds_set_power(struct drm_device *dev, ...@@ -210,8 +211,7 @@ static void cdv_intel_lvds_set_power(struct drm_device *dev,
} while ((pp_status & PP_ON) == 0); } while ((pp_status & PP_ON) == 0);
cdv_intel_lvds_set_backlight(dev, cdv_intel_lvds_set_backlight(dev,
output-> dev_priv->mode_dev.backlight_duty_cycle);
mode_dev->backlight_duty_cycle);
} else { } else {
cdv_intel_lvds_set_backlight(dev, 0); cdv_intel_lvds_set_backlight(dev, 0);
...@@ -227,11 +227,10 @@ static void cdv_intel_lvds_set_power(struct drm_device *dev, ...@@ -227,11 +227,10 @@ static void cdv_intel_lvds_set_power(struct drm_device *dev,
static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
if (mode == DRM_MODE_DPMS_ON) if (mode == DRM_MODE_DPMS_ON)
cdv_intel_lvds_set_power(dev, output, true); cdv_intel_lvds_set_power(dev, encoder, true);
else else
cdv_intel_lvds_set_power(dev, output, false); cdv_intel_lvds_set_power(dev, encoder, false);
/* XXX: We never power down the LVDS pairs. */ /* XXX: We never power down the LVDS pairs. */
} }
...@@ -244,12 +243,12 @@ static void cdv_intel_lvds_restore(struct drm_connector *connector) ...@@ -244,12 +243,12 @@ static void cdv_intel_lvds_restore(struct drm_connector *connector)
} }
int cdv_intel_lvds_mode_valid(struct drm_connector *connector, int cdv_intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct psb_intel_output *psb_intel_output = struct drm_device *dev = connector->dev;
to_psb_intel_output(connector); struct drm_psb_private *dev_priv = dev->dev_private;
struct drm_display_mode *fixed_mode = struct drm_display_mode *fixed_mode =
psb_intel_output->mode_dev->panel_fixed_mode; dev_priv->mode_dev.panel_fixed_mode;
/* just in case */ /* just in case */
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
...@@ -272,9 +271,9 @@ bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -272,9 +271,9 @@ bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct psb_intel_mode_device *mode_dev =
enc_to_psb_intel_output(encoder)->mode_dev;
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
struct drm_encoder *tmp_encoder; struct drm_encoder *tmp_encoder;
struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode; struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode;
...@@ -321,8 +320,8 @@ bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -321,8 +320,8 @@ bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder,
static void cdv_intel_lvds_prepare(struct drm_encoder *encoder) static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_intel_mode_device *mode_dev = output->mode_dev; struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
if (!gma_power_begin(dev, true)) if (!gma_power_begin(dev, true))
return; return;
...@@ -331,7 +330,7 @@ static void cdv_intel_lvds_prepare(struct drm_encoder *encoder) ...@@ -331,7 +330,7 @@ static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
BACKLIGHT_DUTY_CYCLE_MASK); BACKLIGHT_DUTY_CYCLE_MASK);
cdv_intel_lvds_set_power(dev, output, false); cdv_intel_lvds_set_power(dev, encoder, false);
gma_power_end(dev); gma_power_end(dev);
} }
...@@ -339,14 +338,14 @@ static void cdv_intel_lvds_prepare(struct drm_encoder *encoder) ...@@ -339,14 +338,14 @@ static void cdv_intel_lvds_prepare(struct drm_encoder *encoder)
static void cdv_intel_lvds_commit(struct drm_encoder *encoder) static void cdv_intel_lvds_commit(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_intel_mode_device *mode_dev = output->mode_dev; struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
if (mode_dev->backlight_duty_cycle == 0) if (mode_dev->backlight_duty_cycle == 0)
mode_dev->backlight_duty_cycle = mode_dev->backlight_duty_cycle =
cdv_intel_lvds_get_max_backlight(dev); cdv_intel_lvds_get_max_backlight(dev);
cdv_intel_lvds_set_power(dev, output, true); cdv_intel_lvds_set_power(dev, encoder, true);
} }
static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder, static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
...@@ -401,13 +400,13 @@ static enum drm_connector_status cdv_intel_lvds_detect( ...@@ -401,13 +400,13 @@ static enum drm_connector_status cdv_intel_lvds_detect(
static int cdv_intel_lvds_get_modes(struct drm_connector *connector) static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct psb_intel_output *psb_intel_output = struct drm_psb_private *dev_priv = dev->dev_private;
to_psb_intel_output(connector); struct psb_intel_encoder *psb_intel_encoder =
struct psb_intel_mode_device *mode_dev = psb_intel_attached_encoder(connector);
psb_intel_output->mode_dev; struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
int ret; int ret;
ret = psb_intel_ddc_get_modes(psb_intel_output); ret = psb_intel_ddc_get_modes(connector, &psb_intel_encoder->i2c_bus->adapter);
if (ret) if (ret)
return ret; return ret;
...@@ -439,11 +438,11 @@ static int cdv_intel_lvds_get_modes(struct drm_connector *connector) ...@@ -439,11 +438,11 @@ static int cdv_intel_lvds_get_modes(struct drm_connector *connector)
*/ */
void cdv_intel_lvds_destroy(struct drm_connector *connector) void cdv_intel_lvds_destroy(struct drm_connector *connector)
{ {
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
to_psb_intel_output(connector); psb_intel_attached_encoder(connector);
if (psb_intel_output->ddc_bus) if (psb_intel_encoder->i2c_bus)
psb_intel_i2c_destroy(psb_intel_output->ddc_bus); psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(connector);
...@@ -565,7 +564,8 @@ const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { ...@@ -565,7 +564,8 @@ const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = {
void cdv_intel_lvds_init(struct drm_device *dev, void cdv_intel_lvds_init(struct drm_device *dev,
struct psb_intel_mode_device *mode_dev) struct psb_intel_mode_device *mode_dev)
{ {
struct psb_intel_output *psb_intel_output; struct psb_intel_encoder *psb_intel_encoder;
struct psb_intel_connector *psb_intel_connector;
struct cdv_intel_lvds_priv *lvds_priv; struct cdv_intel_lvds_priv *lvds_priv;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -575,32 +575,38 @@ void cdv_intel_lvds_init(struct drm_device *dev, ...@@ -575,32 +575,38 @@ void cdv_intel_lvds_init(struct drm_device *dev,
u32 lvds; u32 lvds;
int pipe; int pipe;
psb_intel_output = kzalloc(sizeof(struct psb_intel_output) + psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder),
sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL); GFP_KERNEL);
if (!psb_intel_output) if (!psb_intel_encoder)
return; return;
lvds_priv = (struct cdv_intel_lvds_priv *)(psb_intel_output + 1); psb_intel_connector = kzalloc(sizeof(struct psb_intel_connector),
GFP_KERNEL);
if (!psb_intel_connector)
goto failed_connector;
psb_intel_output->dev_priv = lvds_priv; lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL);
if (!lvds_priv)
goto failed_lvds_priv;
psb_intel_output->mode_dev = mode_dev; psb_intel_encoder->dev_priv = lvds_priv;
connector = &psb_intel_output->base;
encoder = &psb_intel_output->enc;
connector = &psb_intel_connector->base;
encoder = &psb_intel_encoder->base;
drm_connector_init(dev, &psb_intel_output->base,
drm_connector_init(dev, connector,
&cdv_intel_lvds_connector_funcs, &cdv_intel_lvds_connector_funcs,
DRM_MODE_CONNECTOR_LVDS); DRM_MODE_CONNECTOR_LVDS);
drm_encoder_init(dev, &psb_intel_output->enc, drm_encoder_init(dev, encoder,
&cdv_intel_lvds_enc_funcs, &cdv_intel_lvds_enc_funcs,
DRM_MODE_ENCODER_LVDS); DRM_MODE_ENCODER_LVDS);
drm_mode_connector_attach_encoder(&psb_intel_output->base, psb_intel_connector_attach_encoder(psb_intel_connector,
&psb_intel_output->enc); psb_intel_encoder);
psb_intel_output->type = INTEL_OUTPUT_LVDS; psb_intel_encoder->type = INTEL_OUTPUT_LVDS;
drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs); drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs);
drm_connector_helper_add(connector, drm_connector_helper_add(connector,
...@@ -621,16 +627,16 @@ void cdv_intel_lvds_init(struct drm_device *dev, ...@@ -621,16 +627,16 @@ void cdv_intel_lvds_init(struct drm_device *dev,
* Set up I2C bus * Set up I2C bus
* FIXME: distroy i2c_bus when exit * FIXME: distroy i2c_bus when exit
*/ */
psb_intel_output->i2c_bus = psb_intel_i2c_create(dev, psb_intel_encoder->i2c_bus = psb_intel_i2c_create(dev,
GPIOB, GPIOB,
"LVDSBLC_B"); "LVDSBLC_B");
if (!psb_intel_output->i2c_bus) { if (!psb_intel_encoder->i2c_bus) {
dev_printk(KERN_ERR, dev_printk(KERN_ERR,
&dev->pdev->dev, "I2C bus registration failed.\n"); &dev->pdev->dev, "I2C bus registration failed.\n");
goto failed_blc_i2c; goto failed_blc_i2c;
} }
psb_intel_output->i2c_bus->slave_addr = 0x2C; psb_intel_encoder->i2c_bus->slave_addr = 0x2C;
dev_priv->lvds_i2c_bus = psb_intel_output->i2c_bus; dev_priv->lvds_i2c_bus = psb_intel_encoder->i2c_bus;
/* /*
* LVDS discovery: * LVDS discovery:
...@@ -643,10 +649,10 @@ void cdv_intel_lvds_init(struct drm_device *dev, ...@@ -643,10 +649,10 @@ void cdv_intel_lvds_init(struct drm_device *dev,
*/ */
/* Set up the DDC bus. */ /* Set up the DDC bus. */
psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, psb_intel_encoder->ddc_bus = psb_intel_i2c_create(dev,
GPIOC, GPIOC,
"LVDSDDC_C"); "LVDSDDC_C");
if (!psb_intel_output->ddc_bus) { if (!psb_intel_encoder->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, dev_printk(KERN_ERR, &dev->pdev->dev,
"DDC bus registration " "failed.\n"); "DDC bus registration " "failed.\n");
goto failed_ddc; goto failed_ddc;
...@@ -656,7 +662,8 @@ void cdv_intel_lvds_init(struct drm_device *dev, ...@@ -656,7 +662,8 @@ void cdv_intel_lvds_init(struct drm_device *dev,
* Attempt to get the fixed panel mode from DDC. Assume that the * Attempt to get the fixed panel mode from DDC. Assume that the
* preferred mode is the right one. * preferred mode is the right one.
*/ */
psb_intel_ddc_get_modes(psb_intel_output); psb_intel_ddc_get_modes(connector,
&psb_intel_encoder->ddc_bus->adapter);
list_for_each_entry(scan, &connector->probed_modes, head) { list_for_each_entry(scan, &connector->probed_modes, head) {
if (scan->type & DRM_MODE_TYPE_PREFERRED) { if (scan->type & DRM_MODE_TYPE_PREFERRED) {
mode_dev->panel_fixed_mode = mode_dev->panel_fixed_mode =
...@@ -707,15 +714,19 @@ void cdv_intel_lvds_init(struct drm_device *dev, ...@@ -707,15 +714,19 @@ void cdv_intel_lvds_init(struct drm_device *dev,
failed_find: failed_find:
printk(KERN_ERR "Failed find\n"); printk(KERN_ERR "Failed find\n");
if (psb_intel_output->ddc_bus) if (psb_intel_encoder->ddc_bus)
psb_intel_i2c_destroy(psb_intel_output->ddc_bus); psb_intel_i2c_destroy(psb_intel_encoder->ddc_bus);
failed_ddc: failed_ddc:
printk(KERN_ERR "Failed DDC\n"); printk(KERN_ERR "Failed DDC\n");
if (psb_intel_output->i2c_bus) if (psb_intel_encoder->i2c_bus)
psb_intel_i2c_destroy(psb_intel_output->i2c_bus); psb_intel_i2c_destroy(psb_intel_encoder->i2c_bus);
failed_blc_i2c: failed_blc_i2c:
printk(KERN_ERR "Failed BLC\n"); printk(KERN_ERR "Failed BLC\n");
drm_encoder_cleanup(encoder); drm_encoder_cleanup(encoder);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(lvds_priv);
failed_lvds_priv:
kfree(psb_intel_connector);
failed_connector:
kfree(psb_intel_encoder);
} }
...@@ -374,7 +374,7 @@ struct drm_psb_private { ...@@ -374,7 +374,7 @@ struct drm_psb_private {
struct drm_display_mode *sdvo_lvds_vbt_mode; struct drm_display_mode *sdvo_lvds_vbt_mode;
struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */ struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */
struct psb_intel_i2c_chan *lvds_i2c_bus; struct psb_intel_i2c_chan *lvds_i2c_bus; /* FIXME: Remove this? */
/* Feature bits from the VBIOS */ /* Feature bits from the VBIOS */
unsigned int int_tv_support:1; unsigned int int_tv_support:1;
......
...@@ -139,6 +139,11 @@ struct psb_intel_encoder { ...@@ -139,6 +139,11 @@ struct psb_intel_encoder {
int crtc_mask; int crtc_mask;
int clone_mask; int clone_mask;
void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */ void *dev_priv; /* For sdvo_priv, lvds_priv, etc... */
/* FIXME: Either make SDVO and LVDS store it's i2c here or give CDV it's
own set of output privates */
struct psb_intel_i2c_chan *i2c_bus;
struct psb_intel_i2c_chan *ddc_bus;
}; };
struct psb_intel_connector { struct psb_intel_connector {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment