*/
#include <linux/i2c.h>
-/* #include <drm/drm_crtc.h> */
-/* #include <drm/drm_edid.h> */
#include <drm/drmP.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>
-/* MRST defines start */
-uint8_t blc_freq;
-uint8_t blc_minbrightness;
-uint8_t blc_i2caddr;
-uint8_t blc_brightnesscmd;
-int lvds_backlight; /* restore backlight to this value */
-
-u32 CoreClock;
-u32 PWMControlRegFreq;
-
-/**
+/*
* LVDS I2C backlight control macros
*/
#define BRIGHTNESS_MAX_LEVEL 100
#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
struct psb_intel_lvds_priv {
- /**
+ /*
* Saved LVDO output states
*/
uint32_t savePP_ON;
uint32_t saveBLC_PWM_CTL;
};
-/* MRST defines end */
-/**
+/*
* Returns the maximum level of the backlight duty cycle field.
*/
static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
struct drm_psb_private *dev_priv = dev->dev_private;
u32 retVal;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
retVal = ((REG_READ(BLC_PWM_CTL) &
BACKLIGHT_MODULATION_FREQ_MASK) >>
BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else
retVal = ((dev_priv->saveBLC_PWM_CTL &
BACKLIGHT_MODULATION_FREQ_MASK) >>
return retVal;
}
-/**
+/*
* Set LVDS backlight level by I2C command
+ *
+ * FIXME: at some point we need to both track this for PM and also
+ * disable runtime pm on MRST if the brightness is nil (ie blanked)
*/
static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
unsigned int level)
out_buf[1] = (u8)blc_i2c_brightness;
if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
- DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n",
- blc_brightnesscmd,
+ dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n",
+ dev_priv->lvds_bl->brightnesscmd,
blc_i2c_brightness);
return 0;
}
- DRM_ERROR("I2C transfer error\n");
+ dev_err(dev->dev, "I2C transfer error\n");
return -1;
}
return 0;
}
-/**
+/*
* Set LVDS backlight level either by I2C or PWM
*/
void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private;
- DRM_DEBUG("backlight level is %d\n", level);
+ dev_dbg(dev->dev, "backlight level is %d\n", level);
if (!dev_priv->lvds_bl) {
- DRM_ERROR("NO LVDS Backlight Info\n");
+ dev_err(dev->dev, "NO LVDS Backlight Info\n");
return;
}
psb_lvds_pwm_set_brightness(dev, level);
}
-/**
+/*
* Sets the backlight level.
*
- * \param level backlight level, from 0 to psb_intel_lvds_get_max_backlight().
+ * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight().
*/
static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
{
struct drm_psb_private *dev_priv = dev->dev_private;
u32 blc_pwm_ctl;
- if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_ONLY_IF_ON)) {
+ if (gma_power_begin(dev, false)) {
blc_pwm_ctl =
REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
REG_WRITE(BLC_PWM_CTL,
(blc_pwm_ctl |
(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
} else {
blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
~BACKLIGHT_DUTY_CYCLE_MASK;
}
}
-/**
+/*
* Sets the power state for the panel.
*/
static void psb_intel_lvds_set_power(struct drm_device *dev,
{
u32 pp_status;
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_FORCE_POWER_ON))
+ if (!gma_power_begin(dev, true))
return;
if (on) {
} while (pp_status & PP_ON);
}
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
dev_priv->backlight_duty_cycle =
psb_intel_lvds_get_max_backlight(dev);
- DRM_DEBUG("(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_OFF,
lvds_priv->saveLVDS,
struct psb_intel_lvds_priv *lvds_priv =
(struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;
- DRM_DEBUG("(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_OFF,
lvds_priv->saveLVDS,
struct drm_display_mode *fixed_mode =
psb_intel_output->mode_dev->panel_fixed_mode;
- PSB_DEBUG_ENTRY("\n");
-
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2;
struct psb_intel_output *psb_intel_output =
enc_to_psb_intel_output(encoder);
- PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n",
- psb_intel_output->type, psb_intel_crtc->pipe);
-
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
panel_fixed_mode = mode_dev->panel_fixed_mode2;
- /* PSB doesn't appear to be GEN4 */
- if (psb_intel_crtc->pipe == 0) {
+ /* FIXME: review for Medfield */
+ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
+ if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
printk(KERN_ERR "Can't support LVDS on pipe A\n");
return false;
}
+ if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
+ printk(KERN_ERR "Must use PIPE A\n");
+ return false;
+ }
/* Should never happen!! */
list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
head) {
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
struct psb_intel_mode_device *mode_dev = output->mode_dev;
- PSB_DEBUG_ENTRY("\n");
-
- if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
- OSPM_UHB_FORCE_POWER_ON))
+ if (!gma_power_begin(dev, true))
return;
mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
psb_intel_lvds_set_power(dev, output, false);
- ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ gma_power_end(dev);
}
static void psb_intel_lvds_commit(struct drm_encoder *encoder)
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
struct psb_intel_mode_device *mode_dev = output->mode_dev;
- PSB_DEBUG_ENTRY("\n");
-
if (mode_dev->backlight_duty_cycle == 0)
mode_dev->backlight_duty_cycle =
psb_intel_lvds_get_max_backlight(dev);
struct drm_display_mode *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_psb_private *dev_priv = dev->dev_private;
u32 pfit_control;
/*
else
pfit_control = 0;
- if (mode_dev->panel_wants_dither)
+ if (dev_priv->lvds_dither)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
REG_WRITE(PFIT_CONTROL, pfit_control);
}
-/**
+/*
* Detect the LVDS connection.
*
* This always returns CONNECTOR_STATUS_CONNECTED.
return connector_status_connected;
}
-/**
+/*
* Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
*/
static int psb_intel_lvds_get_modes(struct drm_connector *connector)
psb_intel_output->mode_dev;
int ret = 0;
- ret = psb_intel_ddc_get_modes(psb_intel_output);
+ if (!IS_MRST(dev))
+ ret = psb_intel_ddc_get_modes(psb_intel_output);
if (ret)
return ret;
struct drm_property *property,
uint64_t value)
{
- struct drm_encoder *pEncoder = connector->encoder;
-
- PSB_DEBUG_ENTRY("\n");
+ struct drm_encoder *encoder = connector->encoder;
- if (!strcmp(property->name, "scaling mode") && pEncoder) {
- struct psb_intel_crtc *pPsbCrtc =
- to_psb_intel_crtc(pEncoder->crtc);
- uint64_t curValue;
+ if (!encoder)
+ return -1;
- PSB_DEBUG_ENTRY("scaling mode\n");
+ if (!strcmp(property->name, "scaling mode")) {
+ struct psb_intel_crtc *crtc =
+ to_psb_intel_crtc(encoder->crtc);
+ uint64_t curval;
- if (!pPsbCrtc)
+ if (!crtc)
goto set_prop_error;
switch (value) {
if (drm_connector_property_get_value(connector,
property,
- &curValue))
+ &curval))
goto set_prop_error;
- if (curValue == value)
+ if (curval == value)
goto set_prop_done;
if (drm_connector_property_set_value(connector,
value))
goto set_prop_error;
- if (pPsbCrtc->saved_mode.hdisplay != 0 &&
- pPsbCrtc->saved_mode.vdisplay != 0) {
- if (!drm_crtc_helper_set_mode(pEncoder->crtc,
- &pPsbCrtc->saved_mode,
- pEncoder->crtc->x,
- pEncoder->crtc->y,
- pEncoder->crtc->fb))
+ if (crtc->saved_mode.hdisplay != 0 &&
+ crtc->saved_mode.vdisplay != 0) {
+ if (!drm_crtc_helper_set_mode(encoder->crtc,
+ &crtc->saved_mode,
+ encoder->crtc->x,
+ encoder->crtc->y,
+ encoder->crtc->fb))
goto set_prop_error;
}
- } else if (!strcmp(property->name, "backlight") && pEncoder) {
- PSB_DEBUG_ENTRY("backlight\n");
-
+ } else if (!strcmp(property->name, "backlight")) {
if (drm_connector_property_set_value(connector,
property,
value))
goto set_prop_error;
else {
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct backlight_device bd;
- bd.props.brightness = value;
- psb_set_brightness(&bd);
+ struct drm_psb_private *devp = encoder->dev->dev_private;
+ struct backlight_device *bd = devp->backlight_device;
+ if (bd) {
+ bd->props.brightness = value;
+ backlight_update_status(bd);
+ }
#endif
}
- } else if (!strcmp(property->name, "DPMS") && pEncoder) {
- struct drm_encoder_helper_funcs *pEncHFuncs
- = pEncoder->helper_private;
- PSB_DEBUG_ENTRY("DPMS\n");
- pEncHFuncs->dpms(pEncoder, value);
+ } else if (!strcmp(property->name, "DPMS")) {
+ struct drm_encoder_helper_funcs *hfuncs
+ = encoder->helper_private;
+ hfuncs->dpms(encoder, value);
}
set_prop_done:
.commit = psb_intel_lvds_commit,
};
-static const struct drm_connector_helper_funcs
+const struct drm_connector_helper_funcs
psb_intel_lvds_connector_helper_funcs = {
.get_modes = psb_intel_lvds_get_modes,
.mode_valid = psb_intel_lvds_mode_valid,
.best_encoder = psb_intel_best_encoder,
};
-static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
+const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = psb_intel_lvds_save,
.restore = psb_intel_lvds_restore,
lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
if (!lvds_priv) {
kfree(psb_intel_output);
- DRM_DEBUG("LVDS private allocation error\n");
+ dev_err(dev->dev, "LVDS private allocation error\n");
return;
}
dev_priv->backlight_property,
BRIGHTNESS_MAX_LEVEL);
- /**
+ /*
* Set up I2C bus
* FIXME: distroy i2c_bus when exit
*/
}
}
- /* Failed to get EDID, what about VBT? do we need this?*/
+ /* Failed to get EDID, what about VBT? do we need this? */
if (mode_dev->vbt_mode)
mode_dev->panel_fixed_mode =
drm_mode_duplicate(dev, mode_dev->vbt_mode);
/* 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;
}
*/
out:
drm_sysfs_connector_add(connector);
-
- PSB_DEBUG_ENTRY("hdisplay = %d\n",
- mode_dev->panel_fixed_mode->hdisplay);
- PSB_DEBUG_ENTRY(" vdisplay = %d\n",
- mode_dev->panel_fixed_mode->vdisplay);
- PSB_DEBUG_ENTRY(" hsync_start = %d\n",
- mode_dev->panel_fixed_mode->hsync_start);
- PSB_DEBUG_ENTRY(" hsync_end = %d\n",
- mode_dev->panel_fixed_mode->hsync_end);
- PSB_DEBUG_ENTRY(" htotal = %d\n",
- mode_dev->panel_fixed_mode->htotal);
- PSB_DEBUG_ENTRY(" vsync_start = %d\n",
- mode_dev->panel_fixed_mode->vsync_start);
- PSB_DEBUG_ENTRY(" vsync_end = %d\n",
- mode_dev->panel_fixed_mode->vsync_end);
- PSB_DEBUG_ENTRY(" vtotal = %d\n",
- mode_dev->panel_fixed_mode->vtotal);
- PSB_DEBUG_ENTRY(" clock = %d\n",
- mode_dev->panel_fixed_mode->clock);
-
return;
failed_find: