diff options
Diffstat (limited to 'drivers/staging/gma500/mrst_lvds.c')
-rw-r--r-- | drivers/staging/gma500/mrst_lvds.c | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c index 4a08b74f5ff..e7999a2a379 100644 --- a/drivers/staging/gma500/mrst_lvds.c +++ b/drivers/staging/gma500/mrst_lvds.c @@ -24,11 +24,11 @@ #include <drm/drmP.h> #include <asm/mrst.h> -#include "psb_intel_bios.h" +#include "intel_bios.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" -#include "psb_powermgmt.h" +#include "power.h" #include <linux/pm_runtime.h> /* The max/min PWM frequency in BPCR[31:17] - */ @@ -46,8 +46,7 @@ static void mrst_lvds_set_power(struct drm_device *dev, struct psb_intel_output *output, bool on) { u32 pp_status; - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; - PSB_DEBUG_ENTRY("\n"); + struct drm_psb_private *dev_priv = dev->dev_private; if (!gma_power_begin(dev, true)) return; @@ -59,7 +58,11 @@ static void mrst_lvds_set_power(struct drm_device *dev, pp_status = REG_READ(PP_STATUS); } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); dev_priv->is_lvds_on = true; + if (dev_priv->ops->lvds_bl_power) + dev_priv->ops->lvds_bl_power(dev, true); } else { + if (dev_priv->ops->lvds_bl_power) + dev_priv->ops->lvds_bl_power(dev, false); REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); do { @@ -68,7 +71,6 @@ static void mrst_lvds_set_power(struct drm_device *dev, dev_priv->is_lvds_on = false; pm_request_idle(&dev->pdev->dev); } - gma_power_end(dev); } @@ -77,8 +79,6 @@ static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); - PSB_DEBUG_ENTRY("\n"); - if (mode == DRM_MODE_DPMS_ON) mrst_lvds_set_power(dev, output, true); else @@ -94,11 +94,10 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, struct psb_intel_mode_device *mode_dev = enc_to_psb_intel_output(encoder)->mode_dev; struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; u32 lvds_port; uint64_t v = DRM_MODE_SCALE_FULLSCREEN; - PSB_DEBUG_ENTRY("\n"); - if (!gma_power_begin(dev, true)) return; @@ -112,7 +111,9 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, LVDS_PORT_EN | LVDS_BORDER_EN; - if (mode_dev->panel_wants_dither) + /* If the firmware says dither on Moorestown, or the BIOS does + on Oaktrail then enable dithering */ + if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; REG_WRITE(LVDS, lvds_port); @@ -146,13 +147,59 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, gma_power_end(dev); } +static void mrst_lvds_prepare(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + if (!gma_power_begin(dev, true)) + return; + + mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); + mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + mrst_lvds_set_power(dev, output, false); + gma_power_end(dev); +} + +static u32 mrst_lvds_get_max_backlight(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 ret; + + if (gma_power_begin(dev, false)) { + ret = ((REG_READ(BLC_PWM_CTL) & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + gma_power_end(dev); + } else + ret = ((dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + return ret; +} + +static void mrst_lvds_commit(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + if (mode_dev->backlight_duty_cycle == 0) + mode_dev->backlight_duty_cycle = + mrst_lvds_get_max_backlight(dev); + mrst_lvds_set_power(dev, output, true); +} static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = { .dpms = mrst_lvds_dpms, .mode_fixup = psb_intel_lvds_mode_fixup, - .prepare = psb_intel_lvds_prepare, + .prepare = mrst_lvds_prepare, .mode_set = mrst_lvds_mode_set, - .commit = psb_intel_lvds_commit, + .commit = mrst_lvds_commit, }; static struct drm_display_mode lvds_configuration_modes[] = { @@ -252,8 +299,6 @@ void mrst_lvds_init(struct drm_device *dev, struct i2c_adapter *i2c_adap; struct drm_display_mode *scan; /* *modes, *bios_mode; */ - PSB_DEBUG_ENTRY("\n"); - psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); if (!psb_intel_output) return; @@ -302,16 +347,10 @@ void mrst_lvds_init(struct drm_device *dev, * if closed, act like it's not there for now */ - /* This ifdef can go once the cpu ident stuff is cleaned up in arch */ -#if defined(CONFIG_X86_MRST) - if (mrst_identify_cpu()) - i2c_adap = i2c_get_adapter(2); - else /* Oaktrail uses I2C 1 */ -#endif - i2c_adap = i2c_get_adapter(1); + i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus); if (i2c_adap == NULL) - printk(KERN_ALERT "No ddc adapter available!\n"); + dev_err(dev->dev, "No ddc adapter available!\n"); /* * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. @@ -333,7 +372,6 @@ void mrst_lvds_init(struct drm_device *dev, } } } - /* * If we didn't get EDID, try geting panel timing * from configuration data @@ -341,15 +379,13 @@ void mrst_lvds_init(struct drm_device *dev, mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev); if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; + mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; goto out; /* FIXME: check for quirks */ } /* If we still don't have a mode after all that, give up. */ if (!mode_dev->panel_fixed_mode) { - DRM_DEBUG - ("Found no modes on the lvds, ignoring the LVDS\n"); + dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); goto failed_find; } @@ -358,7 +394,7 @@ out: return; failed_find: - DRM_DEBUG("No LVDS modes found, disabling.\n"); + dev_dbg(dev->dev, "No LVDS modes found, disabling.\n"); if (psb_intel_output->ddc_bus) psb_intel_i2c_destroy(psb_intel_output->ddc_bus); |