Merge tag 'drm-intel-fixes-2013-11-07' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
Bit a bit -fixes pull request in the merge window than usual dua to two feauture-y things: - Display CRCs are now enabled on all platforms, including the odd DP case on gm45/vlv. Since this is a testing-only feature it should ever hurt, but I figured it'll help with regression-testing -fixes. So I left it in and didn't postpone it to 3.14. - Display power well refactoring from Imre. Would have caused major pain conflict with the bdw stage 1 patches if I'd postpone this to -next. It's only an relatively small interface rework, so shouldn't cause pain. It's also been in my tree since almost 3 weeks already. That accounts for about two thirds of the pull, otherwise just bugfixes: - vlv backlight fix from Jesse/Jani - vlv vblank timestamp fix from Jesse - improved edp detection through vbt from Ville (fixes a vlv issue) - eDP vdd fix from Paulo - fixes for dvo lvds on i830M - a few smaller things all over Note: This contains a backmerge of v3.12. Since the -internal branch always applied on top of -nightly I need that unified base to merge bdw patches. So you'll get a conflict with radeon connector props when pulling this (and nouveau/master will also conflict a bit when Ben doesn't rebase). The backmerge itself only had conflicts in drm/i915. There's also a tiny conflict between Jani's backlight fix and your sysfs lifetime fix in drm-next. * tag 'drm-intel-fixes-2013-11-07' of git://people.freedesktop.org/~danvet/drm-intel: (940 commits) drm/i915/vlv: use per-pipe backlight controls v2 drm/i915: make backlight functions take a connector drm/i915: move opregion asle request handling to a work queue drm/i915/vlv: use PIPE_START_VBLANK interrupts on VLV drm/i915: Make intel_dp_is_edp() less specific drm/i915: Give names to the VBT child device type bits drm/i915/vlv: enable HDA display audio for Valleyview2 drm/i915/dvo: call ->mode_set callback only when the port is running drm/i915: avoid unclaimed registers when capturing the error state drm/i915: Enable DP port CRC for the "auto" source on g4x/vlv drm/i915: scramble reset support for DP port CRC on vlv drm/i915: scramble reset support for DP port CRC on g4x drm/i916: add "auto" pipe CRC source ... Conflicts: MAINTAINERS drivers/gpu/drm/i915/intel_panel.c drivers/gpu/drm/nouveau/core/subdev/mc/base.c drivers/gpu/drm/radeon/atombios_encoders.c drivers/gpu/drm/radeon/radeon_connectors.c
This commit is contained in:
@@ -341,7 +341,7 @@ static int is_backlight_combination_mode(struct drm_device *dev)
|
||||
/* XXX: query mode clock or hardware clock and program max PWM appropriately
|
||||
* when it's 0.
|
||||
*/
|
||||
static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
|
||||
static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 val;
|
||||
@@ -358,6 +358,21 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
|
||||
val = dev_priv->regfile.saveBLC_PWM_CTL2;
|
||||
I915_WRITE(BLC_PWM_PCH_CTL2, val);
|
||||
}
|
||||
} else if (IS_VALLEYVIEW(dev)) {
|
||||
val = I915_READ(VLV_BLC_PWM_CTL(pipe));
|
||||
if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
|
||||
dev_priv->regfile.saveBLC_PWM_CTL = val;
|
||||
dev_priv->regfile.saveBLC_PWM_CTL2 =
|
||||
I915_READ(VLV_BLC_PWM_CTL2(pipe));
|
||||
} else if (val == 0) {
|
||||
val = dev_priv->regfile.saveBLC_PWM_CTL;
|
||||
I915_WRITE(VLV_BLC_PWM_CTL(pipe), val);
|
||||
I915_WRITE(VLV_BLC_PWM_CTL2(pipe),
|
||||
dev_priv->regfile.saveBLC_PWM_CTL2);
|
||||
}
|
||||
|
||||
if (!val)
|
||||
val = 0x0f42ffff;
|
||||
} else {
|
||||
val = I915_READ(BLC_PWM_CTL);
|
||||
if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
|
||||
@@ -372,19 +387,17 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev)
|
||||
I915_WRITE(BLC_PWM_CTL2,
|
||||
dev_priv->regfile.saveBLC_PWM_CTL2);
|
||||
}
|
||||
|
||||
if (IS_VALLEYVIEW(dev) && !val)
|
||||
val = 0x0f42ffff;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static u32 intel_panel_get_max_backlight(struct drm_device *dev)
|
||||
static u32 intel_panel_get_max_backlight(struct drm_device *dev,
|
||||
enum pipe pipe)
|
||||
{
|
||||
u32 max;
|
||||
|
||||
max = i915_read_blc_pwm_ctl(dev);
|
||||
max = i915_read_blc_pwm_ctl(dev, pipe);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
max >>= 16;
|
||||
@@ -410,7 +423,8 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
|
||||
"to dri-devel@lists.freedesktop.org, if your machine needs it. "
|
||||
"It will then be included in an upcoming module version.");
|
||||
module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600);
|
||||
static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
|
||||
static u32 intel_panel_compute_brightness(struct drm_device *dev,
|
||||
enum pipe pipe, u32 val)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
@@ -419,7 +433,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
|
||||
|
||||
if (i915_panel_invert_brightness > 0 ||
|
||||
dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
|
||||
u32 max = intel_panel_get_max_backlight(dev);
|
||||
u32 max = intel_panel_get_max_backlight(dev, pipe);
|
||||
if (max)
|
||||
return max - val;
|
||||
}
|
||||
@@ -427,18 +441,25 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val)
|
||||
return val;
|
||||
}
|
||||
|
||||
static u32 intel_panel_get_backlight(struct drm_device *dev)
|
||||
static u32 intel_panel_get_backlight(struct drm_device *dev,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 val;
|
||||
unsigned long flags;
|
||||
int reg;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
} else {
|
||||
val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
if (IS_VALLEYVIEW(dev))
|
||||
reg = VLV_BLC_PWM_CTL(pipe);
|
||||
else
|
||||
reg = BLC_PWM_CTL;
|
||||
|
||||
val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
val >>= 1;
|
||||
|
||||
@@ -450,7 +471,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
val = intel_panel_compute_brightness(dev, val);
|
||||
val = intel_panel_compute_brightness(dev, pipe, val);
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
|
||||
|
||||
@@ -466,19 +487,20 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
|
||||
}
|
||||
|
||||
static void intel_panel_actually_set_backlight(struct drm_device *dev,
|
||||
u32 level)
|
||||
enum pipe pipe, u32 level)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 tmp;
|
||||
int reg;
|
||||
|
||||
DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
|
||||
level = intel_panel_compute_brightness(dev, level);
|
||||
level = intel_panel_compute_brightness(dev, pipe, level);
|
||||
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
return intel_pch_panel_set_backlight(dev, level);
|
||||
|
||||
if (is_backlight_combination_mode(dev)) {
|
||||
u32 max = intel_panel_get_max_backlight(dev);
|
||||
u32 max = intel_panel_get_max_backlight(dev, pipe);
|
||||
u8 lbpc;
|
||||
|
||||
/* we're screwed, but keep behaviour backwards compatible */
|
||||
@@ -490,23 +512,34 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
|
||||
pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
|
||||
}
|
||||
|
||||
tmp = I915_READ(BLC_PWM_CTL);
|
||||
if (IS_VALLEYVIEW(dev))
|
||||
reg = VLV_BLC_PWM_CTL(pipe);
|
||||
else
|
||||
reg = BLC_PWM_CTL;
|
||||
|
||||
tmp = I915_READ(reg);
|
||||
if (INTEL_INFO(dev)->gen < 4)
|
||||
level <<= 1;
|
||||
tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
I915_WRITE(BLC_PWM_CTL, tmp | level);
|
||||
I915_WRITE(reg, tmp | level);
|
||||
}
|
||||
|
||||
/* set backlight brightness to level in range [0..max] */
|
||||
void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
|
||||
void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
|
||||
u32 max)
|
||||
{
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
enum pipe pipe = intel_get_pipe_from_connector(connector);
|
||||
u32 freq;
|
||||
unsigned long flags;
|
||||
|
||||
if (pipe == INVALID_PIPE)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
||||
|
||||
freq = intel_panel_get_max_backlight(dev);
|
||||
freq = intel_panel_get_max_backlight(dev, pipe);
|
||||
if (!freq) {
|
||||
/* we are screwed, bail out */
|
||||
goto out;
|
||||
@@ -523,16 +556,21 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max)
|
||||
dev_priv->backlight.device->props.brightness = level;
|
||||
|
||||
if (dev_priv->backlight.enabled)
|
||||
intel_panel_actually_set_backlight(dev, level);
|
||||
intel_panel_actually_set_backlight(dev, pipe, level);
|
||||
out:
|
||||
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
|
||||
}
|
||||
|
||||
void intel_panel_disable_backlight(struct drm_device *dev)
|
||||
void intel_panel_disable_backlight(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
enum pipe pipe = intel_get_pipe_from_connector(connector);
|
||||
unsigned long flags;
|
||||
|
||||
if (pipe == INVALID_PIPE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Do not disable backlight on the vgaswitcheroo path. When switching
|
||||
* away from i915, the other client may depend on i915 to handle the
|
||||
@@ -547,12 +585,17 @@ void intel_panel_disable_backlight(struct drm_device *dev)
|
||||
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
||||
|
||||
dev_priv->backlight.enabled = false;
|
||||
intel_panel_actually_set_backlight(dev, 0);
|
||||
intel_panel_actually_set_backlight(dev, pipe, 0);
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 4) {
|
||||
uint32_t reg, tmp;
|
||||
|
||||
reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
reg = BLC_PWM_CPU_CTL2;
|
||||
else if (IS_VALLEYVIEW(dev))
|
||||
reg = VLV_BLC_PWM_CTL2(pipe);
|
||||
else
|
||||
reg = BLC_PWM_CTL2;
|
||||
|
||||
I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
|
||||
|
||||
@@ -566,20 +609,25 @@ void intel_panel_disable_backlight(struct drm_device *dev)
|
||||
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
|
||||
}
|
||||
|
||||
void intel_panel_enable_backlight(struct drm_device *dev,
|
||||
enum pipe pipe)
|
||||
void intel_panel_enable_backlight(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
enum pipe pipe = intel_get_pipe_from_connector(connector);
|
||||
enum transcoder cpu_transcoder =
|
||||
intel_pipe_to_cpu_transcoder(dev_priv, pipe);
|
||||
unsigned long flags;
|
||||
|
||||
if (pipe == INVALID_PIPE)
|
||||
return;
|
||||
|
||||
DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
|
||||
|
||||
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
||||
|
||||
if (dev_priv->backlight.level == 0) {
|
||||
dev_priv->backlight.level = intel_panel_get_max_backlight(dev);
|
||||
dev_priv->backlight.level = intel_panel_get_max_backlight(dev,
|
||||
pipe);
|
||||
if (dev_priv->backlight.device)
|
||||
dev_priv->backlight.device->props.brightness =
|
||||
dev_priv->backlight.level;
|
||||
@@ -588,8 +636,12 @@ void intel_panel_enable_backlight(struct drm_device *dev,
|
||||
if (INTEL_INFO(dev)->gen >= 4) {
|
||||
uint32_t reg, tmp;
|
||||
|
||||
reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
|
||||
|
||||
if (HAS_PCH_SPLIT(dev))
|
||||
reg = BLC_PWM_CPU_CTL2;
|
||||
else if (IS_VALLEYVIEW(dev))
|
||||
reg = VLV_BLC_PWM_CTL2(pipe);
|
||||
else
|
||||
reg = BLC_PWM_CTL2;
|
||||
|
||||
tmp = I915_READ(reg);
|
||||
|
||||
@@ -629,7 +681,8 @@ set_level:
|
||||
* registers are set.
|
||||
*/
|
||||
dev_priv->backlight.enabled = true;
|
||||
intel_panel_actually_set_backlight(dev, dev_priv->backlight.level);
|
||||
intel_panel_actually_set_backlight(dev, pipe,
|
||||
dev_priv->backlight.level);
|
||||
|
||||
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
|
||||
}
|
||||
@@ -640,9 +693,19 @@ static void intel_panel_init_backlight_regs(struct drm_device *dev)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (IS_VALLEYVIEW(dev)) {
|
||||
u32 cur_val = I915_READ(BLC_PWM_CTL) &
|
||||
BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
I915_WRITE(BLC_PWM_CTL, (0xf42 << 16) | cur_val);
|
||||
enum pipe pipe;
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
|
||||
|
||||
/* Skip if the modulation freq is already set */
|
||||
if (cur_val & ~BACKLIGHT_DUTY_CYCLE_MASK)
|
||||
continue;
|
||||
|
||||
cur_val &= BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
I915_WRITE(VLV_BLC_PWM_CTL(pipe), (0xf42 << 16) |
|
||||
cur_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,7 +715,7 @@ static void intel_panel_init_backlight(struct drm_device *dev)
|
||||
|
||||
intel_panel_init_backlight_regs(dev);
|
||||
|
||||
dev_priv->backlight.level = intel_panel_get_backlight(dev);
|
||||
dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
|
||||
dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
|
||||
}
|
||||
|
||||
@@ -681,18 +744,31 @@ intel_panel_detect(struct drm_device *dev)
|
||||
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
|
||||
static int intel_panel_update_status(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
struct intel_connector *connector = bl_get_data(bd);
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n",
|
||||
bd->props.brightness, bd->props.max_brightness);
|
||||
intel_panel_set_backlight(dev, bd->props.brightness,
|
||||
intel_panel_set_backlight(connector, bd->props.brightness,
|
||||
bd->props.max_brightness);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_panel_get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
struct drm_device *dev = bl_get_data(bd);
|
||||
return intel_panel_get_backlight(dev);
|
||||
struct intel_connector *connector = bl_get_data(bd);
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
enum pipe pipe;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
pipe = intel_get_pipe_from_connector(connector);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
if (pipe == INVALID_PIPE)
|
||||
return 0;
|
||||
|
||||
return intel_panel_get_backlight(connector->base.dev, pipe);
|
||||
}
|
||||
|
||||
static const struct backlight_ops intel_panel_bl_ops = {
|
||||
@@ -717,7 +793,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
|
||||
props.brightness = dev_priv->backlight.level;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->backlight.lock, flags);
|
||||
props.max_brightness = intel_panel_get_max_backlight(dev);
|
||||
props.max_brightness = intel_panel_get_max_backlight(dev, 0);
|
||||
spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
|
||||
|
||||
if (props.max_brightness == 0) {
|
||||
@@ -726,7 +802,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
|
||||
}
|
||||
dev_priv->backlight.device =
|
||||
backlight_device_register("intel_backlight",
|
||||
connector->kdev, dev,
|
||||
connector->kdev,
|
||||
to_intel_connector(connector),
|
||||
&intel_panel_bl_ops, &props);
|
||||
|
||||
if (IS_ERR(dev_priv->backlight.device)) {
|
||||
|
Reference in New Issue
Block a user