Commit 9c8cee47 authored by Patrik Jakobsson's avatar Patrik Jakobsson Committed by Dave Airlie

gma500: Convert PSB LVDS to new output handling

LVDS for PSB now uses psb_intel_encoder and psb_intel_connectors instead of
psb_intel_output. i2c_bus and ddc_bus are moved to lvds_priv. There was also a
pointer to mode_dev (for no obvious reason) that we now get directly from
dev_priv.
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 1730f89b
...@@ -59,6 +59,9 @@ struct psb_intel_lvds_priv { ...@@ -59,6 +59,9 @@ struct psb_intel_lvds_priv {
uint32_t savePFIT_CONTROL; uint32_t savePFIT_CONTROL;
uint32_t savePFIT_PGM_RATIOS; uint32_t savePFIT_PGM_RATIOS;
uint32_t saveBLC_PWM_CTL; uint32_t saveBLC_PWM_CTL;
struct psb_intel_i2c_chan *i2c_bus;
struct psb_intel_i2c_chan *ddc_bus;
}; };
...@@ -214,9 +217,10 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) ...@@ -214,9 +217,10 @@ static void psb_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 psb_intel_lvds_set_power(struct drm_device *dev, static void psb_intel_lvds_set_power(struct drm_device *dev, bool on)
struct psb_intel_output *output, bool on)
{ {
struct drm_psb_private *dev_priv = dev->dev_private;
struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
u32 pp_status; u32 pp_status;
if (!gma_power_begin(dev, true)) { if (!gma_power_begin(dev, true)) {
...@@ -232,8 +236,7 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, ...@@ -232,8 +236,7 @@ static void psb_intel_lvds_set_power(struct drm_device *dev,
} while ((pp_status & PP_ON) == 0); } while ((pp_status & PP_ON) == 0);
psb_intel_lvds_set_backlight(dev, psb_intel_lvds_set_backlight(dev,
output-> mode_dev->backlight_duty_cycle);
mode_dev->backlight_duty_cycle);
} else { } else {
psb_intel_lvds_set_backlight(dev, 0); psb_intel_lvds_set_backlight(dev, 0);
...@@ -250,12 +253,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, ...@@ -250,12 +253,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev,
static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) static void psb_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)
psb_intel_lvds_set_power(dev, output, true); psb_intel_lvds_set_power(dev, true);
else else
psb_intel_lvds_set_power(dev, output, false); psb_intel_lvds_set_power(dev, false);
/* XXX: We never power down the LVDS pairs. */ /* XXX: We never power down the LVDS pairs. */
} }
...@@ -265,10 +267,10 @@ static void psb_intel_lvds_save(struct drm_connector *connector) ...@@ -265,10 +267,10 @@ static void psb_intel_lvds_save(struct drm_connector *connector)
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_psb_private *dev_priv = struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private; (struct drm_psb_private *)dev->dev_private;
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 psb_intel_lvds_priv *lvds_priv = struct psb_intel_lvds_priv *lvds_priv =
(struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; (struct psb_intel_lvds_priv *)psb_intel_encoder->dev_priv;
lvds_priv->savePP_ON = REG_READ(LVDSPP_ON); lvds_priv->savePP_ON = REG_READ(LVDSPP_ON);
lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF); lvds_priv->savePP_OFF = REG_READ(LVDSPP_OFF);
...@@ -305,10 +307,10 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) ...@@ -305,10 +307,10 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
u32 pp_status; u32 pp_status;
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 psb_intel_lvds_priv *lvds_priv = struct psb_intel_lvds_priv *lvds_priv =
(struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; (struct psb_intel_lvds_priv *)psb_intel_encoder->dev_priv;
dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
lvds_priv->savePP_ON, lvds_priv->savePP_ON,
...@@ -346,13 +348,14 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) ...@@ -346,13 +348,14 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
int psb_intel_lvds_mode_valid(struct drm_connector *connector, int psb_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_psb_private *dev_priv = connector->dev->dev_private;
to_psb_intel_output(connector); struct psb_intel_encoder *psb_intel_encoder =
psb_intel_attached_encoder(connector);
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;
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) if (psb_intel_encoder->type == INTEL_OUTPUT_MIPI2)
fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2; fixed_mode = dev_priv->mode_dev.panel_fixed_mode2;
/* just in case */ /* just in case */
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
...@@ -375,17 +378,17 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -375,17 +378,17 @@ bool psb_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 psb_intel_crtc *psb_intel_crtc = struct psb_intel_crtc *psb_intel_crtc =
to_psb_intel_crtc(encoder->crtc); to_psb_intel_crtc(encoder->crtc);
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;
struct psb_intel_output *psb_intel_output = struct psb_intel_encoder *psb_intel_encoder =
enc_to_psb_intel_output(encoder); to_psb_intel_encoder(encoder);
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) if (psb_intel_encoder->type == INTEL_OUTPUT_MIPI2)
panel_fixed_mode = mode_dev->panel_fixed_mode2; panel_fixed_mode = mode_dev->panel_fixed_mode2;
/* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
...@@ -440,8 +443,8 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -440,8 +443,8 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
static void psb_intel_lvds_prepare(struct drm_encoder *encoder) static void psb_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;
...@@ -450,7 +453,7 @@ static void psb_intel_lvds_prepare(struct drm_encoder *encoder) ...@@ -450,7 +453,7 @@ static void psb_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);
psb_intel_lvds_set_power(dev, output, false); psb_intel_lvds_set_power(dev, false);
gma_power_end(dev); gma_power_end(dev);
} }
...@@ -458,14 +461,14 @@ static void psb_intel_lvds_prepare(struct drm_encoder *encoder) ...@@ -458,14 +461,14 @@ static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
static void psb_intel_lvds_commit(struct drm_encoder *encoder) static void psb_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 =
psb_intel_lvds_get_max_backlight(dev); psb_intel_lvds_get_max_backlight(dev);
psb_intel_lvds_set_power(dev, output, true); psb_intel_lvds_set_power(dev, true);
} }
static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
...@@ -520,14 +523,15 @@ static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector ...@@ -520,14 +523,15 @@ static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector
static int psb_intel_lvds_get_modes(struct drm_connector *connector) static int psb_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_mode_device *mode_dev = &dev_priv->mode_dev;
struct psb_intel_mode_device *mode_dev = struct psb_intel_encoder *psb_intel_encoder =
psb_intel_output->mode_dev; psb_intel_attached_encoder(connector);
struct psb_intel_lvds_priv *lvds_priv = psb_intel_encoder->dev_priv;
int ret = 0; int ret = 0;
if (!IS_MRST(dev)) if (!IS_MRST(dev))
ret = psb_intel_ddc_get_modes(psb_intel_output); ret = psb_intel_ddc_get_modes(connector, &lvds_priv->i2c_bus->adapter);
if (ret) if (ret)
return ret; return ret;
...@@ -560,11 +564,12 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector) ...@@ -560,11 +564,12 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector)
*/ */
void psb_intel_lvds_destroy(struct drm_connector *connector) void psb_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);
struct psb_intel_lvds_priv *lvds_priv = psb_intel_encoder->dev_priv;
if (psb_intel_output->ddc_bus) if (lvds_priv->ddc_bus)
psb_intel_i2c_destroy(psb_intel_output->ddc_bus); psb_intel_i2c_destroy(lvds_priv->ddc_bus);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); kfree(connector);
...@@ -693,9 +698,10 @@ const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = { ...@@ -693,9 +698,10 @@ const struct drm_encoder_funcs psb_intel_lvds_enc_funcs = {
* modes we can display on the LVDS panel (if present). * modes we can display on the LVDS panel (if present).
*/ */
void psb_intel_lvds_init(struct drm_device *dev, void psb_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 psb_intel_lvds_priv *lvds_priv; struct psb_intel_lvds_priv *lvds_priv;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -705,33 +711,43 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -705,33 +711,43 @@ void psb_intel_lvds_init(struct drm_device *dev,
u32 lvds; u32 lvds;
int pipe; int pipe;
psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); psb_intel_encoder =
if (!psb_intel_output) kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
if (!psb_intel_encoder) {
dev_err(dev->dev, "psb_intel_encoder allocation error\n");
return; return;
}
psb_intel_connector =
kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
if (!psb_intel_connector) {
kfree(psb_intel_encoder);
dev_err(dev->dev, "psb_intel_connector allocation error\n");
}
lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
if (!lvds_priv) { if (!lvds_priv) {
kfree(psb_intel_output);
dev_err(dev->dev, "LVDS private allocation error\n"); dev_err(dev->dev, "LVDS private allocation error\n");
return; goto failed_connector;
} }
psb_intel_output->dev_priv = lvds_priv; psb_intel_encoder->dev_priv = lvds_priv;
psb_intel_output->mode_dev = mode_dev;
connector = &psb_intel_output->base; connector = &psb_intel_connector->base;
encoder = &psb_intel_output->enc; encoder = &psb_intel_encoder->base;
drm_connector_init(dev, &psb_intel_output->base, drm_connector_init(dev, connector,
&psb_intel_lvds_connector_funcs, &psb_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,
&psb_intel_lvds_enc_funcs, &psb_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, &psb_intel_lvds_helper_funcs); drm_encoder_helper_add(encoder, &psb_intel_lvds_helper_funcs);
drm_connector_helper_add(connector, drm_connector_helper_add(connector,
...@@ -752,16 +768,14 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -752,16 +768,14 @@ void psb_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, lvds_priv->i2c_bus = psb_intel_i2c_create(dev, GPIOB, "LVDSBLC_B");
GPIOB, if (!lvds_priv->i2c_bus) {
"LVDSBLC_B");
if (!psb_intel_output->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; lvds_priv->i2c_bus->slave_addr = 0x2C;
dev_priv->lvds_i2c_bus = psb_intel_output->i2c_bus; dev_priv->lvds_i2c_bus = lvds_priv->i2c_bus;
/* /*
* LVDS discovery: * LVDS discovery:
...@@ -774,10 +788,8 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -774,10 +788,8 @@ void psb_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, lvds_priv->ddc_bus = psb_intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
GPIOC, if (!lvds_priv->ddc_bus) {
"LVDSDDC_C");
if (!psb_intel_output->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;
...@@ -787,7 +799,7 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -787,7 +799,7 @@ void psb_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, &lvds_priv->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 =
...@@ -841,14 +853,16 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -841,14 +853,16 @@ void psb_intel_lvds_init(struct drm_device *dev,
return; return;
failed_find: failed_find:
if (psb_intel_output->ddc_bus) if (lvds_priv->ddc_bus)
psb_intel_i2c_destroy(psb_intel_output->ddc_bus); psb_intel_i2c_destroy(lvds_priv->ddc_bus);
failed_ddc: failed_ddc:
if (psb_intel_output->i2c_bus) if (lvds_priv->i2c_bus)
psb_intel_i2c_destroy(psb_intel_output->i2c_bus); psb_intel_i2c_destroy(lvds_priv->i2c_bus);
failed_blc_i2c: failed_blc_i2c:
drm_encoder_cleanup(encoder); drm_encoder_cleanup(encoder);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
kfree(connector); failed_connector:
if (psb_intel_connector)
kfree(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