All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] drm/i915: backlight rewrite
@ 2013-11-08 14:48 Jani Nikula
  2013-11-08 14:48 ` [PATCH 01/13] drm/i915: clean up backlight conditional build Jani Nikula
                   ` (14 more replies)
  0 siblings, 15 replies; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Hi all -

This series is a successor to [1], but with too many changes to list so
I'll just consider this v1 of the patches.

This is pretty much a rewrite of our backlight code. Highlights:

* All the platform specific stuff in platform specific functions. The
  code is much easier to follow, and it will be easier to enable future
  platforms without breaking old ones all the time.

* Backlight enable writes all the backlight registers based on
  information retrieved at setup stage. We no longer depend on what's in
  the registers prior to enable, which should make things more
  deterministic, and we no longer need to save/restore backlight
  registers.

* We no longer keep reading max backlight value or combination mode bits
  etc. from the registers all over the place. All that is based on the
  initial values read in the setup stage.

TODO:

* If initial setup in registers is bogus, we should try to read the
  values from VBT and/or try to use sane defaults. (This problem we have
  already, not introduced by the series.)

I've tested this so far on ILK and IVB, trying carefully keep it working
commit by commit to keep things bisectable. More testing across
platforms is very much needed. We have a history with backlight...

Also available at backlight-rework branch at [2].


BR,
Jani.


[1] http://mid.gmane.org/cover.1383237868.git.jani.nikula@intel.com
[2] git://gitorious.org/jani/drm.git


Jani Nikula (13):
  drm/i915: clean up backlight conditional build
  drm/i915: make backlight info per-connector
  drm/i915: make asle notifications update backlight on all connectors
  drm/i915: handle backlight through chip specific functions
  drm/i915: fix gen2-gen3 backlight set
  drm/i915: vlv does not have pipe field in backlight registers
  drm/i915: move backlight level setting in enable/disable to hooks
  drm/i915: use the initialized backlight max value instead of reading
    it
  drm/i915: debug print on backlight register
  drm/i915: gather backlight information at setup
  drm/i915: do full backlight setup at enable time
  drm/i915: nuke get max backlight functions
  drm/i915: do not save/restore backlight registers

 drivers/gpu/drm/i915/i915_dma.c       |    2 +-
 drivers/gpu/drm/i915/i915_drv.h       |   23 +-
 drivers/gpu/drm/i915/i915_suspend.c   |   45 --
 drivers/gpu/drm/i915/intel_display.c  |   11 +-
 drivers/gpu/drm/i915/intel_drv.h      |   14 +-
 drivers/gpu/drm/i915/intel_opregion.c |   43 +-
 drivers/gpu/drm/i915/intel_panel.c    |  819 +++++++++++++++++++++------------
 7 files changed, 566 insertions(+), 391 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 01/13] drm/i915: clean up backlight conditional build
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 21:23   ` Imre Deak
  2013-11-08 14:48 ` [PATCH 02/13] drm/i915: make backlight info per-connector Jani Nikula
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

I've always felt the backlight device conditional build has been all
backwards. Make it feel right.

Gently move things towards connector based stuff while at it.

There should be no functional changes.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |    9 +++--
 drivers/gpu/drm/i915/intel_drv.h     |    2 +-
 drivers/gpu/drm/i915/intel_panel.c   |   65 +++++++++++++++++++---------------
 3 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 68bca7b..30d3993 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11256,12 +11256,11 @@ void intel_modeset_cleanup(struct drm_device *dev)
 	/* flush any delayed tasks or pending work */
 	flush_scheduled_work();
 
-	/* destroy backlight, if any, before the connectors */
-	intel_panel_destroy_backlight(dev);
-
-	/* destroy the sysfs files before encoders/connectors */
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+	/* destroy the backlight and sysfs files before encoders/connectors */
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		intel_panel_destroy_backlight(connector);
 		drm_sysfs_connector_remove(connector);
+	}
 
 	drm_mode_config_cleanup(dev);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1876ea1..1625580 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -808,7 +808,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 int intel_panel_setup_backlight(struct drm_connector *connector);
 void intel_panel_enable_backlight(struct intel_connector *connector);
 void intel_panel_disable_backlight(struct intel_connector *connector);
-void intel_panel_destroy_backlight(struct drm_device *dev);
+void intel_panel_destroy_backlight(struct drm_connector *connector);
 enum drm_connector_status intel_panel_detect(struct drm_device *dev);
 
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index f161ac0..a0d13d3 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -709,16 +709,6 @@ static void intel_panel_init_backlight_regs(struct drm_device *dev)
 	}
 }
 
-static void intel_panel_init_backlight(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	intel_panel_init_backlight_regs(dev);
-
-	dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
-	dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
-}
-
 enum drm_connector_status
 intel_panel_detect(struct drm_device *dev)
 {
@@ -742,7 +732,7 @@ intel_panel_detect(struct drm_device *dev)
 }
 
 #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
-static int intel_panel_update_status(struct backlight_device *bd)
+static int intel_backlight_device_update_status(struct backlight_device *bd)
 {
 	struct intel_connector *connector = bl_get_data(bd);
 	struct drm_device *dev = connector->base.dev;
@@ -756,7 +746,7 @@ static int intel_panel_update_status(struct backlight_device *bd)
 	return 0;
 }
 
-static int intel_panel_get_brightness(struct backlight_device *bd)
+static int intel_backlight_device_get_brightness(struct backlight_device *bd)
 {
 	struct intel_connector *connector = bl_get_data(bd);
 	struct drm_device *dev = connector->base.dev;
@@ -771,20 +761,18 @@ static int intel_panel_get_brightness(struct backlight_device *bd)
 	return intel_panel_get_backlight(connector->base.dev, pipe);
 }
 
-static const struct backlight_ops intel_panel_bl_ops = {
-	.update_status = intel_panel_update_status,
-	.get_brightness = intel_panel_get_brightness,
+static const struct backlight_ops intel_backlight_device_ops = {
+	.update_status = intel_backlight_device_update_status,
+	.get_brightness = intel_backlight_device_get_brightness,
 };
 
-int intel_panel_setup_backlight(struct drm_connector *connector)
+static int intel_backlight_device_register(struct intel_connector *connector)
 {
-	struct drm_device *dev = connector->dev;
+	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct backlight_properties props;
 	unsigned long flags;
 
-	intel_panel_init_backlight(dev);
-
 	if (WARN_ON(dev_priv->backlight.device))
 		return -ENODEV;
 
@@ -802,9 +790,9 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
 	}
 	dev_priv->backlight.device =
 		backlight_device_register("intel_backlight",
-					  connector->kdev,
-					  to_intel_connector(connector),
-					  &intel_panel_bl_ops, &props);
+					  connector->base.kdev,
+					  connector,
+					  &intel_backlight_device_ops, &props);
 
 	if (IS_ERR(dev_priv->backlight.device)) {
 		DRM_ERROR("Failed to register backlight: %ld\n",
@@ -815,26 +803,47 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
 	return 0;
 }
 
-void intel_panel_destroy_backlight(struct drm_device *dev)
+static void intel_backlight_device_unregister(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	if (dev_priv->backlight.device) {
 		backlight_device_unregister(dev_priv->backlight.device);
 		dev_priv->backlight.device = NULL;
 	}
 }
-#else
+#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+static int intel_backlight_device_register(struct intel_connector *connector)
+{
+	return 0;
+}
+static void intel_backlight_device_unregister(struct intel_connector *connector)
+{
+}
+#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
+
 int intel_panel_setup_backlight(struct drm_connector *connector)
 {
-	intel_panel_init_backlight(connector->dev);
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	intel_panel_init_backlight_regs(dev);
+
+	dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
+	dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
+
+	intel_backlight_device_register(intel_connector);
+
 	return 0;
 }
 
-void intel_panel_destroy_backlight(struct drm_device *dev)
+void intel_panel_destroy_backlight(struct drm_connector *connector)
 {
-	return;
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+
+	intel_backlight_device_unregister(intel_connector);
 }
-#endif
 
 int intel_panel_init(struct intel_panel *panel,
 		     struct drm_display_mode *fixed_mode)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 02/13] drm/i915: make backlight info per-connector
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
  2013-11-08 14:48 ` [PATCH 01/13] drm/i915: clean up backlight conditional build Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 21:29   ` Imre Deak
  2013-11-08 14:48 ` [PATCH 03/13] drm/i915: make asle notifications update backlight on all connectors Jani Nikula
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Move from dev_priv to connector->panel. We still don't allow multiple
sysfs interfaces, though.

There should be no functional changes, except for a slight reordering of
connector backlight and sysfs destroy calls. (This change happens now
that the backlight device is actually per-connector, even though the
destroy calls became per-connector earlier.)

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_dma.c     |    2 +-
 drivers/gpu/drm/i915/i915_drv.h     |    9 +---
 drivers/gpu/drm/i915/i915_suspend.c |    8 ++--
 drivers/gpu/drm/i915/intel_drv.h    |    7 +++
 drivers/gpu/drm/i915/intel_panel.c  |   85 +++++++++++++++++++----------------
 5 files changed, 61 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 0cab2d0..9a2a175 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1486,7 +1486,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
 	spin_lock_init(&dev_priv->irq_lock);
 	spin_lock_init(&dev_priv->gpu_error.lock);
-	spin_lock_init(&dev_priv->backlight.lock);
+	spin_lock_init(&dev_priv->backlight_lock);
 	spin_lock_init(&dev_priv->uncore.lock);
 	spin_lock_init(&dev_priv->mm.object_stat_lock);
 	mutex_init(&dev_priv->dpio_lock);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 67117e7..0517d47 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1368,13 +1368,8 @@ typedef struct drm_i915_private {
 	struct intel_overlay *overlay;
 	unsigned int sprite_scaling_enabled;
 
-	/* backlight */
-	struct {
-		int level;
-		bool enabled;
-		spinlock_t lock; /* bl registers and the above bl fields */
-		struct backlight_device *device;
-	} backlight;
+	/* backlight registers and fields in struct intel_panel */
+	spinlock_t backlight_lock;
 
 	/* LVDS info */
 	bool no_aux_handshake;
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 98790c7..eadf8e1 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -203,7 +203,7 @@ static void i915_save_display(struct drm_device *dev)
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_save_display_reg(dev);
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	/* LVDS state */
 	if (HAS_PCH_SPLIT(dev)) {
@@ -241,7 +241,7 @@ static void i915_save_display(struct drm_device *dev)
 			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 
 	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
 		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
@@ -287,7 +287,7 @@ static void i915_restore_display(struct drm_device *dev)
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_restore_display_reg(dev);
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	/* LVDS state */
 	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
@@ -341,7 +341,7 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 
 	/* only restore FBC info on the platform that supports FBC*/
 	intel_disable_fbc(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1625580..a0d8dda 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -156,6 +156,13 @@ struct intel_encoder {
 struct intel_panel {
 	struct drm_display_mode *fixed_mode;
 	int fitting_mode;
+
+	/* backlight */
+	struct {
+		u32 level;
+		bool enabled;
+		struct backlight_device *device;
+	} backlight;
 };
 
 struct intel_connector {
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index a0d13d3..0a4aeaf 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -346,7 +346,7 @@ 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;
 
-	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock));
+	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
 
 	/* Restore the CTL value if it lost, e.g. GPU reset */
 
@@ -449,7 +449,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
 	unsigned long flags;
 	int reg;
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	if (HAS_PCH_SPLIT(dev)) {
 		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
@@ -473,7 +473,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
 
 	val = intel_panel_compute_brightness(dev, pipe, val);
 
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 
 	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
 	return val;
@@ -530,6 +530,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	u32 freq;
 	unsigned long flags;
@@ -537,7 +538,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 	if (pipe == INVALID_PIPE)
 		return;
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	freq = intel_panel_get_max_backlight(dev, pipe);
 	if (!freq) {
@@ -551,20 +552,21 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 	else
 		level = freq / max * level;
 
-	dev_priv->backlight.level = level;
-	if (dev_priv->backlight.device)
-		dev_priv->backlight.device->props.brightness = level;
+	panel->backlight.level = level;
+	if (panel->backlight.device)
+		panel->backlight.device->props.brightness = level;
 
-	if (dev_priv->backlight.enabled)
+	if (panel->backlight.enabled)
 		intel_panel_actually_set_backlight(dev, pipe, level);
 out:
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
 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;
+	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	unsigned long flags;
 
@@ -582,9 +584,9 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
 		return;
 	}
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-	dev_priv->backlight.enabled = false;
+	panel->backlight.enabled = false;
 	intel_panel_actually_set_backlight(dev, pipe, 0);
 
 	if (INTEL_INFO(dev)->gen >= 4) {
@@ -606,13 +608,14 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
 		}
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
 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;
+	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	enum transcoder cpu_transcoder =
 		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
@@ -623,14 +626,14 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 
 	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-	if (dev_priv->backlight.level == 0) {
-		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;
+	if (panel->backlight.level == 0) {
+		panel->backlight.level = intel_panel_get_max_backlight(dev,
+								       pipe);
+		if (panel->backlight.device)
+			panel->backlight.device->props.brightness =
+				panel->backlight.level;
 	}
 
 	if (INTEL_INFO(dev)->gen >= 4) {
@@ -680,11 +683,11 @@ set_level:
 	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
 	 * registers are set.
 	 */
-	dev_priv->backlight.enabled = true;
+	panel->backlight.enabled = true;
 	intel_panel_actually_set_backlight(dev, pipe,
-					   dev_priv->backlight.level);
+					   panel->backlight.level);
 
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
 /* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
@@ -770,34 +773,40 @@ static int intel_backlight_device_register(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	struct backlight_properties props;
 	unsigned long flags;
 
-	if (WARN_ON(dev_priv->backlight.device))
+	if (WARN_ON(panel->backlight.device))
 		return -ENODEV;
 
 	memset(&props, 0, sizeof(props));
 	props.type = BACKLIGHT_RAW;
-	props.brightness = dev_priv->backlight.level;
+	props.brightness = panel->backlight.level;
 
-	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 	props.max_brightness = intel_panel_get_max_backlight(dev, 0);
-	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 
 	if (props.max_brightness == 0) {
 		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
 		return -ENODEV;
 	}
-	dev_priv->backlight.device =
+
+	/*
+	 * Note: using the same name independent of the connector prevents
+	 * registration of multiple backlight devices in the driver.
+	 */
+	panel->backlight.device =
 		backlight_device_register("intel_backlight",
 					  connector->base.kdev,
 					  connector,
 					  &intel_backlight_device_ops, &props);
 
-	if (IS_ERR(dev_priv->backlight.device)) {
+	if (IS_ERR(panel->backlight.device)) {
 		DRM_ERROR("Failed to register backlight: %ld\n",
-			  PTR_ERR(dev_priv->backlight.device));
-		dev_priv->backlight.device = NULL;
+			  PTR_ERR(panel->backlight.device));
+		panel->backlight.device = NULL;
 		return -ENODEV;
 	}
 	return 0;
@@ -805,11 +814,11 @@ static int intel_backlight_device_register(struct intel_connector *connector)
 
 static void intel_backlight_device_unregister(struct intel_connector *connector)
 {
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	if (dev_priv->backlight.device) {
-		backlight_device_unregister(dev_priv->backlight.device);
-		dev_priv->backlight.device = NULL;
+	struct intel_panel *panel = &connector->panel;
+
+	if (panel->backlight.device) {
+		backlight_device_unregister(panel->backlight.device);
+		panel->backlight.device = NULL;
 	}
 }
 #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
@@ -825,13 +834,13 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
 int intel_panel_setup_backlight(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_panel *panel = &intel_connector->panel;
 
 	intel_panel_init_backlight_regs(dev);
 
-	dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
-	dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
+	panel->backlight.level = intel_panel_get_backlight(dev, 0);
+	panel->backlight.enabled = panel->backlight.level != 0;
 
 	intel_backlight_device_register(intel_connector);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 03/13] drm/i915: make asle notifications update backlight on all connectors
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
  2013-11-08 14:48 ` [PATCH 01/13] drm/i915: clean up backlight conditional build Jani Nikula
  2013-11-08 14:48 ` [PATCH 02/13] drm/i915: make backlight info per-connector Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 21:29   ` Imre Deak
  2013-11-08 14:48 ` [PATCH 04/13] drm/i915: handle backlight through chip specific functions Jani Nikula
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

ALthough usually there's only one connector that supports backlight,
this also finds the correct connector. Before, we only updated the
connector on pipe A, which might not be the one with backlight. (This
only made a difference on BYT.)

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_opregion.c |   43 ++++++++++-----------------------
 drivers/gpu/drm/i915/intel_panel.c    |    4 +++
 3 files changed, 18 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a0d8dda..68bec63 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -159,6 +159,7 @@ struct intel_panel {
 
 	/* backlight */
 	struct {
+		bool present;
 		u32 level;
 		bool enabled;
 		struct backlight_device *device;
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 91b68dc..a0b5a99 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -396,13 +396,10 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
 static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_encoder *encoder;
 	struct drm_connector *connector;
-	struct intel_connector *intel_connector = NULL;
-	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
+	struct intel_connector *intel_connector;
+	struct intel_panel *panel;
 	struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
-	u32 ret = 0;
-	bool found = false;
 
 	DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
 
@@ -414,38 +411,24 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
 		return ASLC_BACKLIGHT_FAILED;
 
 	mutex_lock(&dev->mode_config.mutex);
+
 	/*
-	 * Could match the OpRegion connector here instead, but we'd also need
-	 * to verify the connector could handle a backlight call.
+	 * Update backlight on all connectors that support backlight (usually
+	 * only one).
 	 */
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-		if (encoder->crtc == crtc) {
-			found = true;
-			break;
-		}
-
-	if (!found) {
-		ret = ASLC_BACKLIGHT_FAILED;
-		goto out;
-	}
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-		if (connector->encoder == encoder)
-			intel_connector = to_intel_connector(connector);
-
-	if (!intel_connector) {
-		ret = ASLC_BACKLIGHT_FAILED;
-		goto out;
-	}
-
 	DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
-	intel_panel_set_backlight(intel_connector, bclp, 255);
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		intel_connector = to_intel_connector(connector);
+		panel = &intel_connector->panel;
+		if (panel->backlight.present)
+			intel_panel_set_backlight(intel_connector, bclp, 255);
+	}
 	iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
 
-out:
 	mutex_unlock(&dev->mode_config.mutex);
 
-	return ret;
+
+	return 0;
 }
 
 static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 0a4aeaf..c80bffc 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -844,13 +844,17 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
 
 	intel_backlight_device_register(intel_connector);
 
+	panel->backlight.present = true;
+
 	return 0;
 }
 
 void intel_panel_destroy_backlight(struct drm_connector *connector)
 {
 	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_panel *panel = &intel_connector->panel;
 
+	panel->backlight.present = false;
 	intel_backlight_device_unregister(intel_connector);
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 04/13] drm/i915: handle backlight through chip specific functions
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (2 preceding siblings ...)
  2013-11-08 14:48 ` [PATCH 03/13] drm/i915: make asle notifications update backlight on all connectors Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 21:36   ` Imre Deak
  2013-11-08 14:48 ` [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set Jani Nikula
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

The backlight code has grown rather hairy, not least because the
hardware registers and bits have repeatedly been shuffled around. And
this isn't expected to get any easier with new hardware. Make things
easier for our (read: my) poor brains, and split the code up into chip
specific functions.

There should be no functional changes.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    9 +
 drivers/gpu/drm/i915/intel_display.c |    2 +
 drivers/gpu/drm/i915/intel_drv.h     |    2 +
 drivers/gpu/drm/i915/intel_panel.c   |  642 +++++++++++++++++++++++-----------
 4 files changed, 447 insertions(+), 208 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0517d47..2d70ae4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -351,6 +351,7 @@ struct drm_i915_error_state {
 	enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
 };
 
+struct intel_connector;
 struct intel_crtc_config;
 struct intel_crtc;
 struct intel_limit;
@@ -413,6 +414,14 @@ struct drm_i915_display_funcs {
 	/* render clock increase/decrease */
 	/* display clock increase/decrease */
 	/* pll clock increase/decrease */
+
+	int (*setup_backlight)(struct intel_connector *connector);
+	uint32_t (*get_max_backlight)(struct intel_connector *connector);
+	uint32_t (*get_backlight)(struct intel_connector *connector);
+	void (*set_backlight)(struct intel_connector *connector,
+			      uint32_t level);
+	void (*disable_backlight)(struct intel_connector *connector);
+	void (*enable_backlight)(struct intel_connector *connector);
 };
 
 struct intel_uncore_funcs {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 30d3993..b6533f8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10604,6 +10604,8 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.queue_flip = intel_gen7_queue_flip;
 		break;
 	}
+
+	intel_panel_init_backlight_funcs(dev);
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 68bec63..7384a7b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -161,6 +161,7 @@ struct intel_panel {
 	struct {
 		bool present;
 		u32 level;
+		u32 max;
 		bool enabled;
 		struct backlight_device *device;
 	} backlight;
@@ -817,6 +818,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector);
 void intel_panel_enable_backlight(struct intel_connector *connector);
 void intel_panel_disable_backlight(struct intel_connector *connector);
 void intel_panel_destroy_backlight(struct drm_connector *connector);
+void intel_panel_init_backlight_funcs(struct drm_device *dev);
 enum drm_connector_status intel_panel_detect(struct drm_device *dev);
 
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index c80bffc..a821949 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -338,79 +338,117 @@ static int is_backlight_combination_mode(struct drm_device *dev)
 	return 0;
 }
 
-/* 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, enum pipe pipe)
+static u32 pch_get_max_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 val;
 
-	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
+	val = I915_READ(BLC_PWM_PCH_CTL2);
+	if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL2 = val;
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL2;
+		I915_WRITE(BLC_PWM_PCH_CTL2, val);
+	}
 
-	/* Restore the CTL value if it lost, e.g. GPU reset */
+	val >>= 16;
 
-	if (HAS_PCH_SPLIT(dev_priv->dev)) {
-		val = I915_READ(BLC_PWM_PCH_CTL2);
-		if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
-			dev_priv->regfile.saveBLC_PWM_CTL2 = val;
-		} else if (val == 0) {
-			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);
-		}
+	return val;
+}
 
-		if (!val)
-			val = 0x0f42ffff;
-	} else {
-		val = I915_READ(BLC_PWM_CTL);
-		if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-			dev_priv->regfile.saveBLC_PWM_CTL = val;
-			if (INTEL_INFO(dev)->gen >= 4)
-				dev_priv->regfile.saveBLC_PWM_CTL2 =
-					I915_READ(BLC_PWM_CTL2);
-		} else if (val == 0) {
-			val = dev_priv->regfile.saveBLC_PWM_CTL;
-			I915_WRITE(BLC_PWM_CTL, val);
-			if (INTEL_INFO(dev)->gen >= 4)
-				I915_WRITE(BLC_PWM_CTL2,
-					   dev_priv->regfile.saveBLC_PWM_CTL2);
-		}
+static u32 i9xx_get_max_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	val = I915_READ(BLC_PWM_CTL);
+	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL = val;
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL;
+		I915_WRITE(BLC_PWM_CTL, val);
 	}
 
+	val >>= 17;
+
+	if (is_backlight_combination_mode(dev))
+		val *= 0xff;
+
 	return val;
 }
 
-static u32 intel_panel_get_max_backlight(struct drm_device *dev,
-					 enum pipe pipe)
+static u32 i965_get_max_backlight(struct intel_connector *connector)
 {
-	u32 max;
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+
+	val = I915_READ(BLC_PWM_CTL);
+	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
+		dev_priv->regfile.saveBLC_PWM_CTL = val;
+		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+	} else if (val == 0) {
+		val = dev_priv->regfile.saveBLC_PWM_CTL;
+		I915_WRITE(BLC_PWM_CTL, val);
+		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
+	}
 
-	max = i915_read_blc_pwm_ctl(dev, pipe);
+	val >>= 16;
 
-	if (HAS_PCH_SPLIT(dev)) {
-		max >>= 16;
-	} else {
-		if (INTEL_INFO(dev)->gen < 4)
-			max >>= 17;
-		else
-			max >>= 16;
+	if (is_backlight_combination_mode(dev))
+		val *= 0xff;
+
+	return val;
+}
+
+static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
 
-		if (is_backlight_combination_mode(dev))
-			max *= 0xff;
+	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;
+
+	val >>= 16;
+
+	return val;
+}
+
+static u32 vlv_get_max_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+
+	return _vlv_get_max_backlight(dev, pipe);
+}
+
+/* XXX: query mode clock or hardware clock and program max PWM appropriately
+ * when it's 0.
+ */
+static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 max;
+
+	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
+
+	max = dev_priv->display.get_max_backlight(connector);
+
 	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
 
 	return max;
@@ -423,9 +461,10 @@ 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,
-					  enum pipe pipe, u32 val)
+static u32 intel_panel_compute_brightness(struct intel_connector *connector,
+					  u32 val)
 {
+	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (i915_panel_invert_brightness < 0)
@@ -433,7 +472,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
 
 	if (i915_panel_invert_brightness > 0 ||
 	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
-		u32 max = intel_panel_get_max_backlight(dev, pipe);
+		u32 max = intel_panel_get_max_backlight(connector);
 		if (max)
 			return max - val;
 	}
@@ -441,37 +480,60 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
 	return val;
 }
 
-static u32 intel_panel_get_backlight(struct drm_device *dev,
-				     enum pipe pipe)
+static u32 pch_get_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val;
-	unsigned long flags;
-	int reg;
 
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
 
-	if (HAS_PCH_SPLIT(dev)) {
-		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-	} else {
-		if (IS_VALLEYVIEW(dev))
-			reg = VLV_BLC_PWM_CTL(pipe);
-		else
-			reg = BLC_PWM_CTL;
+static u32 i9xx_get_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
 
-		val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
-		if (INTEL_INFO(dev)->gen < 4)
-			val >>= 1;
+	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
+	if (INTEL_INFO(dev)->gen < 4)
+		val >>= 1;
 
-		if (is_backlight_combination_mode(dev)) {
-			u8 lbpc;
+	if (is_backlight_combination_mode(dev)) {
+		u8 lbpc;
 
-			pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
-			val *= lbpc;
-		}
+		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
+		val *= lbpc;
 	}
 
-	val = intel_panel_compute_brightness(dev, pipe, val);
+	return val;
+}
+
+static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
+}
+
+static u32 vlv_get_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	enum pipe pipe = intel_get_pipe_from_connector(connector);
+
+	return _vlv_get_backlight(dev, pipe);
+}
+
+static u32 intel_panel_get_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+
+	val = dev_priv->display.get_backlight(connector);
+	val = intel_panel_compute_brightness(connector, val);
 
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 
@@ -479,28 +541,24 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
 	return val;
 }
 
-static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
+static void pch_set_backlight(struct intel_connector *connector, u32 level)
 {
+	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
-	I915_WRITE(BLC_PWM_CPU_CTL, val | level);
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
 }
 
-static void intel_panel_actually_set_backlight(struct drm_device *dev,
-					       enum pipe pipe, u32 level)
+static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
 {
+	struct drm_device *dev = connector->base.dev;
 	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, 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, pipe);
+		u32 max = intel_panel_get_max_backlight(connector);
 		u8 lbpc;
 
 		/* we're screwed, but keep behaviour backwards compatible */
@@ -512,16 +570,34 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
 		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
 	}
 
-	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(reg, tmp | level);
+
+	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(BLC_PWM_CTL, tmp | level);
+}
+
+static void vlv_set_backlight(struct intel_connector *connector, u32 level)
+{
+	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 tmp;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
+}
+
+static void
+intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
+
+	level = intel_panel_compute_brightness(connector, level);
+	dev_priv->display.set_backlight(connector, level);
 }
 
 /* set backlight brightness to level in range [0..max] */
@@ -540,7 +616,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-	freq = intel_panel_get_max_backlight(dev, pipe);
+	freq = intel_panel_get_max_backlight(connector);
 	if (!freq) {
 		/* we are screwed, bail out */
 		goto out;
@@ -557,11 +633,45 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 		panel->backlight.device->props.brightness = level;
 
 	if (panel->backlight.enabled)
-		intel_panel_actually_set_backlight(dev, pipe, level);
+		intel_panel_actually_set_backlight(connector, level);
 out:
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
+static void pch_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
+
+	tmp = I915_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
+}
+
+static void i965_disable_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
+}
+
+static void vlv_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);
+	u32 tmp;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
+}
+
 void intel_panel_disable_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
@@ -587,28 +697,100 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	panel->backlight.enabled = false;
-	intel_panel_actually_set_backlight(dev, pipe, 0);
+	intel_panel_actually_set_backlight(connector, 0);
 
-	if (INTEL_INFO(dev)->gen >= 4) {
-		uint32_t reg, tmp;
+	if (dev_priv->display.disable_backlight)
+		dev_priv->display.disable_backlight(connector);
 
-		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;
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+}
 
-		I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
+static void pch_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);
+	u32 tmp;
 
-		if (HAS_PCH_SPLIT(dev)) {
-			tmp = I915_READ(BLC_PWM_PCH_CTL1);
-			tmp &= ~BLM_PCH_PWM_ENABLE;
-			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-		}
+	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+
+	/* Note that this can also get called through dpms changes. And
+	 * we don't track the backlight dpms state, hence check whether
+	 * we have to do anything first. */
+	if (tmp & BLM_PWM_ENABLE)
+		return;
+
+	if (INTEL_INFO(dev)->num_pipes == 3)
+		tmp &= ~BLM_PIPE_SELECT_IVB;
+	else
+		tmp &= ~BLM_PIPE_SELECT;
+
+	if (cpu_transcoder == TRANSCODER_EDP)
+		tmp |= BLM_TRANSCODER_EDP;
+	else
+		tmp |= BLM_PIPE(cpu_transcoder);
+	tmp &= ~BLM_PWM_ENABLE;
+
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
+	POSTING_READ(BLC_PWM_CPU_CTL2);
+	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
+
+	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
+		tmp = I915_READ(BLC_PWM_PCH_CTL1);
+		tmp |= BLM_PCH_PWM_ENABLE;
+		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
+		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
 	}
+}
 
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+static void i965_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);
+	u32 tmp;
+
+	tmp = I915_READ(BLC_PWM_CTL2);
+
+	/* Note that this can also get called through dpms changes. And
+	 * we don't track the backlight dpms state, hence check whether
+	 * we have to do anything first. */
+	if (tmp & BLM_PWM_ENABLE)
+		return;
+
+	tmp &= ~BLM_PIPE_SELECT;
+	tmp |= BLM_PIPE(pipe);
+	tmp &= ~BLM_PWM_ENABLE;
+
+	I915_WRITE(BLC_PWM_CTL2, tmp);
+	POSTING_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
+}
+
+static void vlv_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);
+	u32 tmp;
+
+	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+
+	/* Note that this can also get called through dpms changes. And
+	 * we don't track the backlight dpms state, hence check whether
+	 * we have to do anything first. */
+	if (tmp & BLM_PWM_ENABLE)
+		return;
+
+	tmp &= ~BLM_PIPE_SELECT;
+	tmp |= BLM_PIPE(pipe);
+	tmp &= ~BLM_PWM_ENABLE;
+
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
+	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
 }
 
 void intel_panel_enable_backlight(struct intel_connector *connector)
@@ -617,8 +799,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	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)
@@ -629,89 +809,25 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	if (panel->backlight.level == 0) {
-		panel->backlight.level = intel_panel_get_max_backlight(dev,
-								       pipe);
+		panel->backlight.level = intel_panel_get_max_backlight(connector);
 		if (panel->backlight.device)
 			panel->backlight.device->props.brightness =
 				panel->backlight.level;
 	}
 
-	if (INTEL_INFO(dev)->gen >= 4) {
-		uint32_t reg, tmp;
-
-		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);
-
-		/* Note that this can also get called through dpms changes. And
-		 * we don't track the backlight dpms state, hence check whether
-		 * we have to do anything first. */
-		if (tmp & BLM_PWM_ENABLE)
-			goto set_level;
-
-		if (INTEL_INFO(dev)->num_pipes == 3)
-			tmp &= ~BLM_PIPE_SELECT_IVB;
-		else
-			tmp &= ~BLM_PIPE_SELECT;
-
-		if (cpu_transcoder == TRANSCODER_EDP)
-			tmp |= BLM_TRANSCODER_EDP;
-		else
-			tmp |= BLM_PIPE(cpu_transcoder);
-		tmp &= ~BLM_PWM_ENABLE;
-
-		I915_WRITE(reg, tmp);
-		POSTING_READ(reg);
-		I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
-
-		if (HAS_PCH_SPLIT(dev) &&
-		    !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
-			tmp = I915_READ(BLC_PWM_PCH_CTL1);
-			tmp |= BLM_PCH_PWM_ENABLE;
-			tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
-			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-		}
-	}
+	if (dev_priv->display.enable_backlight)
+		dev_priv->display.enable_backlight(connector);
 
-set_level:
 	/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
 	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
 	 * registers are set.
 	 */
 	panel->backlight.enabled = true;
-	intel_panel_actually_set_backlight(dev, pipe,
-					   panel->backlight.level);
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
-/* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
-static void intel_panel_init_backlight_regs(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (IS_VALLEYVIEW(dev)) {
-		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);
-		}
-	}
-}
-
 enum drm_connector_status
 intel_panel_detect(struct drm_device *dev)
 {
@@ -753,15 +869,13 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd)
 {
 	struct intel_connector *connector = bl_get_data(bd);
 	struct drm_device *dev = connector->base.dev;
-	enum pipe pipe;
+	int ret;
 
 	mutex_lock(&dev->mode_config.mutex);
-	pipe = intel_get_pipe_from_connector(connector);
+	ret = intel_panel_get_backlight(connector);
 	mutex_unlock(&dev->mode_config.mutex);
-	if (pipe == INVALID_PIPE)
-		return 0;
 
-	return intel_panel_get_backlight(connector->base.dev, pipe);
+	return ret;
 }
 
 static const struct backlight_ops intel_backlight_device_ops = {
@@ -771,27 +885,18 @@ static const struct backlight_ops intel_backlight_device_ops = {
 
 static int intel_backlight_device_register(struct intel_connector *connector)
 {
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	struct backlight_properties props;
-	unsigned long flags;
 
 	if (WARN_ON(panel->backlight.device))
 		return -ENODEV;
 
+	BUG_ON(panel->backlight.max == 0);
+
 	memset(&props, 0, sizeof(props));
 	props.type = BACKLIGHT_RAW;
 	props.brightness = panel->backlight.level;
-
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-	props.max_brightness = intel_panel_get_max_backlight(dev, 0);
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
-	if (props.max_brightness == 0) {
-		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
-		return -ENODEV;
-	}
+	props.max_brightness = panel->backlight.max;
 
 	/*
 	 * Note: using the same name independent of the connector prevents
@@ -831,15 +936,102 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
 }
 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
 
+/* Note: The setup hooks can't assume pipe is set! */
+static int pch_setup_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 val;
+
+	panel->backlight.max = pch_get_max_backlight(connector);
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	val = pch_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	return 0;
+}
+
+static int i9xx_setup_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 val;
+
+	panel->backlight.max = i9xx_get_max_backlight(connector);
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	val = i9xx_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	return 0;
+}
+
+static int i965_setup_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+	u32 val;
+
+	panel->backlight.max = i965_get_max_backlight(connector);
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	val = i9xx_get_backlight(connector);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	return 0;
+}
+
+static int vlv_setup_backlight(struct intel_connector *connector)
+{
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
+	enum pipe pipe;
+	u32 val;
+
+	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);
+	}
+
+	panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A);
+	if (!panel->backlight.max)
+		return -ENODEV;
+
+	val = _vlv_get_backlight(dev, PIPE_A);
+	panel->backlight.level = intel_panel_compute_brightness(connector, val);
+
+	return 0;
+}
+
 int intel_panel_setup_backlight(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 	struct intel_panel *panel = &intel_connector->panel;
+	unsigned long flags;
+	int ret;
 
-	intel_panel_init_backlight_regs(dev);
+	/* set level and max in panel struct */
+	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
+	ret = dev_priv->display.setup_backlight(intel_connector);
+	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
+
+	if (ret) {
+		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
+			      drm_get_connector_name(connector));
+		return ret;
+	}
 
-	panel->backlight.level = intel_panel_get_backlight(dev, 0);
 	panel->backlight.enabled = panel->backlight.level != 0;
 
 	intel_backlight_device_register(intel_connector);
@@ -858,6 +1050,40 @@ void intel_panel_destroy_backlight(struct drm_connector *connector)
 	intel_backlight_device_unregister(intel_connector);
 }
 
+/* Set up chip specific backlight functions */
+void intel_panel_init_backlight_funcs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_PCH_SPLIT(dev)) {
+		dev_priv->display.setup_backlight = pch_setup_backlight;
+		dev_priv->display.enable_backlight = pch_enable_backlight;
+		dev_priv->display.disable_backlight = pch_disable_backlight;
+		dev_priv->display.set_backlight = pch_set_backlight;
+		dev_priv->display.get_backlight = pch_get_backlight;
+		dev_priv->display.get_max_backlight = pch_get_max_backlight;
+	} else if (IS_VALLEYVIEW(dev)) {
+		dev_priv->display.setup_backlight = vlv_setup_backlight;
+		dev_priv->display.enable_backlight = vlv_enable_backlight;
+		dev_priv->display.disable_backlight = vlv_disable_backlight;
+		dev_priv->display.set_backlight = vlv_set_backlight;
+		dev_priv->display.get_backlight = vlv_get_backlight;
+		dev_priv->display.get_max_backlight = vlv_get_max_backlight;
+	} else if (IS_GEN4(dev)) {
+		dev_priv->display.setup_backlight = i965_setup_backlight;
+		dev_priv->display.enable_backlight = i965_enable_backlight;
+		dev_priv->display.disable_backlight = i965_disable_backlight;
+		dev_priv->display.set_backlight = i9xx_set_backlight;
+		dev_priv->display.get_backlight = i9xx_get_backlight;
+		dev_priv->display.get_max_backlight = i965_get_max_backlight;
+	} else {
+		dev_priv->display.setup_backlight = i9xx_setup_backlight;
+		dev_priv->display.set_backlight = i9xx_set_backlight;
+		dev_priv->display.get_backlight = i9xx_get_backlight;
+		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
+	}
+}
+
 int intel_panel_init(struct intel_panel *panel,
 		     struct drm_display_mode *fixed_mode)
 {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (3 preceding siblings ...)
  2013-11-08 14:48 ` [PATCH 04/13] drm/i915: handle backlight through chip specific functions Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 22:00   ` Imre Deak
  2013-11-08 14:48 ` [PATCH 06/13] drm/i915: vlv does not have pipe field in backlight registers Jani Nikula
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index a821949..e82b2dd 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -555,7 +555,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 tmp;
+	u32 tmp, mask;
 
 	if (is_backlight_combination_mode(dev)) {
 		u32 max = intel_panel_get_max_backlight(connector);
@@ -570,10 +570,14 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
 		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
 	}
 
-	if (INTEL_INFO(dev)->gen < 4)
+	if (IS_GEN4(dev)) {
+		mask = BACKLIGHT_DUTY_CYCLE_MASK;
+	} else {
 		level <<= 1;
+		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
+	}
 
-	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
 	I915_WRITE(BLC_PWM_CTL, tmp | level);
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 06/13] drm/i915: vlv does not have pipe field in backlight registers
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (4 preceding siblings ...)
  2013-11-08 14:48 ` [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 22:00   ` Imre Deak
  2013-11-08 14:48 ` [PATCH 07/13] drm/i915: move backlight level setting in enable/disable to hooks Jani Nikula
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

It has per pipe registers.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index e82b2dd..5bd64db 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -788,8 +788,6 @@ static void vlv_enable_backlight(struct intel_connector *connector)
 	if (tmp & BLM_PWM_ENABLE)
 		return;
 
-	tmp &= ~BLM_PIPE_SELECT;
-	tmp |= BLM_PIPE(pipe);
 	tmp &= ~BLM_PWM_ENABLE;
 
 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 07/13] drm/i915: move backlight level setting in enable/disable to hooks
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (5 preceding siblings ...)
  2013-11-08 14:48 ` [PATCH 06/13] drm/i915: vlv does not have pipe field in backlight registers Jani Nikula
@ 2013-11-08 14:48 ` Jani Nikula
  2013-11-12 22:01   ` Imre Deak
  2013-11-08 14:49 ` [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it Jani Nikula
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

This allows more flexibility in the ordering of the register writes, and
lets us drop level setting altogether as necessary on a per platform
basis.

For gen2-gen3, this is the only thing that happens in enable/disable.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |   48 +++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 5bd64db..ed6b1ec 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -648,6 +648,8 @@ static void pch_disable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 tmp;
 
+	intel_panel_actually_set_backlight(connector, 0);
+
 	tmp = I915_READ(BLC_PWM_CPU_CTL2);
 	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
 
@@ -655,12 +657,19 @@ static void pch_disable_backlight(struct intel_connector *connector)
 	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
 }
 
+static void i9xx_disable_backlight(struct intel_connector *connector)
+{
+	intel_panel_actually_set_backlight(connector, 0);
+}
+
 static void i965_disable_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 tmp;
 
+	intel_panel_actually_set_backlight(connector, 0);
+
 	tmp = I915_READ(BLC_PWM_CTL2);
 	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
 }
@@ -672,6 +681,8 @@ static void vlv_disable_backlight(struct intel_connector *connector)
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	u32 tmp;
 
+	intel_panel_actually_set_backlight(connector, 0);
+
 	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
 }
@@ -701,10 +712,7 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
 	panel->backlight.enabled = false;
-	intel_panel_actually_set_backlight(connector, 0);
-
-	if (dev_priv->display.disable_backlight)
-		dev_priv->display.disable_backlight(connector);
+	dev_priv->display.disable_backlight(connector);
 
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
@@ -713,6 +721,7 @@ static void pch_enable_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	enum transcoder cpu_transcoder =
 		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
@@ -747,12 +756,27 @@ static void pch_enable_backlight(struct intel_connector *connector)
 		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
 		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
 	}
+
+	/*
+	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
+	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
+	 * registers are set.
+	 */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+}
+
+static void i9xx_enable_backlight(struct intel_connector *connector)
+{
+	struct intel_panel *panel = &connector->panel;
+
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
 static void i965_enable_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	u32 tmp;
 
@@ -771,12 +795,15 @@ static void i965_enable_backlight(struct intel_connector *connector)
 	I915_WRITE(BLC_PWM_CTL2, tmp);
 	POSTING_READ(BLC_PWM_CTL2);
 	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
+
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
 static void vlv_enable_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	u32 tmp;
 
@@ -793,6 +820,8 @@ static void vlv_enable_backlight(struct intel_connector *connector)
 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
 	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
 	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
+
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
 void intel_panel_enable_backlight(struct intel_connector *connector)
@@ -817,15 +846,8 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 				panel->backlight.level;
 	}
 
-	if (dev_priv->display.enable_backlight)
-		dev_priv->display.enable_backlight(connector);
-
-	/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
-	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
-	 * registers are set.
-	 */
+	dev_priv->display.enable_backlight(connector);
 	panel->backlight.enabled = true;
-	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
@@ -1080,6 +1102,8 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
 		dev_priv->display.get_max_backlight = i965_get_max_backlight;
 	} else {
 		dev_priv->display.setup_backlight = i9xx_setup_backlight;
+		dev_priv->display.enable_backlight = i9xx_enable_backlight;
+		dev_priv->display.disable_backlight = i9xx_disable_backlight;
 		dev_priv->display.set_backlight = i9xx_set_backlight;
 		dev_priv->display.get_backlight = i9xx_get_backlight;
 		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (6 preceding siblings ...)
  2013-11-08 14:48 ` [PATCH 07/13] drm/i915: move backlight level setting in enable/disable to hooks Jani Nikula
@ 2013-11-08 14:49 ` Jani Nikula
  2013-11-12 22:42   ` Imre Deak
  2013-11-08 14:49 ` [PATCH 09/13] drm/i915: debug print on backlight register Jani Nikula
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

We now have the max backlight value cached. Use it.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |   45 +++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index ed6b1ec..9a55b36 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -436,9 +436,6 @@ static u32 vlv_get_max_backlight(struct intel_connector *connector)
 	return _vlv_get_max_backlight(dev, pipe);
 }
 
-/* XXX: query mode clock or hardware clock and program max PWM appropriately
- * when it's 0.
- */
 static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
@@ -466,15 +463,16 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
+
+	WARN_ON(panel->backlight.max == 0);
 
 	if (i915_panel_invert_brightness < 0)
 		return val;
 
 	if (i915_panel_invert_brightness > 0 ||
 	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
-		u32 max = intel_panel_get_max_backlight(connector);
-		if (max)
-			return max - val;
+		return panel->backlight.max - val;
 	}
 
 	return val;
@@ -555,17 +553,15 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	u32 tmp, mask;
 
+	WARN_ON(panel->backlight.max == 0);
+
 	if (is_backlight_combination_mode(dev)) {
-		u32 max = intel_panel_get_max_backlight(connector);
 		u8 lbpc;
 
-		/* we're screwed, but keep behaviour backwards compatible */
-		if (!max)
-			max = 1;
-
-		lbpc = level * 0xfe / max + 1;
+		lbpc = level * 0xfe / panel->backlight.max + 1;
 		level /= lbpc;
 		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
 	}
@@ -620,13 +616,10 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-	freq = intel_panel_get_max_backlight(connector);
-	if (!freq) {
-		/* we are screwed, bail out */
-		goto out;
-	}
+	WARN_ON(panel->backlight.max == 0);
 
-	/* scale to hardware, but be careful to not overflow */
+	/* scale to hardware max, but be careful to not overflow */
+	freq = panel->backlight.max;
 	if (freq < max)
 		level = level * freq / max;
 	else
@@ -638,7 +631,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 
 	if (panel->backlight.enabled)
 		intel_panel_actually_set_backlight(connector, level);
-out:
+
 	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
 }
 
@@ -839,8 +832,13 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
+	/* XXX: transitional, call to make sure freq is set */
+	intel_panel_get_max_backlight(connector);
+
+	WARN_ON(panel->backlight.max == 0);
+
 	if (panel->backlight.level == 0) {
-		panel->backlight.level = intel_panel_get_max_backlight(connector);
+		panel->backlight.level = panel->backlight.max;
 		if (panel->backlight.device)
 			panel->backlight.device->props.brightness =
 				panel->backlight.level;
@@ -960,7 +958,12 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
 }
 #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
 
-/* Note: The setup hooks can't assume pipe is set! */
+/*
+ * Note: The setup hooks can't assume pipe is set!
+ *
+ * XXX: Query mode clock or hardware clock and program PWM modulation frequency
+ * appropriately when it's 0. Use VBT and/or sane defaults.
+ */
 static int pch_setup_backlight(struct intel_connector *connector)
 {
 	struct intel_panel *panel = &connector->panel;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 09/13] drm/i915: debug print on backlight register
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (7 preceding siblings ...)
  2013-11-08 14:49 ` [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it Jani Nikula
@ 2013-11-08 14:49 ` Jani Nikula
  2013-11-12 22:48   ` Imre Deak
  2013-11-08 14:49 ` [PATCH 10/13] drm/i915: gather backlight information at setup Jani Nikula
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 9a55b36..3dd9f57d 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1065,6 +1065,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
 
 	panel->backlight.present = true;
 
+	DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
+		      "sysfs interface %sregistered\n",
+		      panel->backlight.enabled ? "enabled" : "disabled",
+		      panel->backlight.level, panel->backlight.max,
+		      panel->backlight.device ? "" : "not ");
+
 	return 0;
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 10/13] drm/i915: gather backlight information at setup
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (8 preceding siblings ...)
  2013-11-08 14:49 ` [PATCH 09/13] drm/i915: debug print on backlight register Jani Nikula
@ 2013-11-08 14:49 ` Jani Nikula
  2013-11-13 17:01   ` Imre Deak
  2013-11-08 14:49 ` [PATCH 11/13] drm/i915: do full backlight setup at enable time Jani Nikula
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

Prepare for being able to use the information at enable.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h   |    2 ++
 drivers/gpu/drm/i915/intel_panel.c |   68 +++++++++++++++++++++++++++++-------
 2 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7384a7b..6f2bc82 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -163,6 +163,8 @@ struct intel_panel {
 		u32 level;
 		u32 max;
 		bool enabled;
+		bool combination_mode;	/* gen 2/4 only */
+		bool active_low_pwm;
 		struct backlight_device *device;
 	} backlight;
 };
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 3dd9f57d..0e8f0a3 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -490,13 +490,14 @@ static u32 i9xx_get_backlight(struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_panel *panel = &connector->panel;
 	u32 val;
 
 	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
 	if (INTEL_INFO(dev)->gen < 4)
 		val >>= 1;
 
-	if (is_backlight_combination_mode(dev)) {
+	if (panel->backlight.combination_mode) {
 		u8 lbpc;
 
 		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
@@ -558,7 +559,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
 
 	WARN_ON(panel->backlight.max == 0);
 
-	if (is_backlight_combination_mode(dev)) {
+	if (panel->backlight.combination_mode) {
 		u8 lbpc;
 
 		lbpc = level * 0xfe / panel->backlight.max + 1;
@@ -966,46 +967,84 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
  */
 static int pch_setup_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
-	u32 val;
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
 
-	panel->backlight.max = pch_get_max_backlight(connector);
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+
+	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
+	panel->backlight.max = pch_ctl2 >> 16;
 	if (!panel->backlight.max)
 		return -ENODEV;
 
 	val = pch_get_backlight(connector);
 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
 
+	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
+		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
+
 	return 0;
 }
 
 static int i9xx_setup_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
-	u32 val;
+	u32 ctl, val;
+
+	ctl = I915_READ(BLC_PWM_CTL);
+
+	if (IS_GEN2(dev))
+		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
+
+	if (IS_PINEVIEW(dev))
+		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
+
+	panel->backlight.max = ctl >> 17;
+	if (panel->backlight.combination_mode)
+		panel->backlight.max *= 0xff;
 
-	panel->backlight.max = i9xx_get_max_backlight(connector);
 	if (!panel->backlight.max)
 		return -ENODEV;
 
 	val = i9xx_get_backlight(connector);
 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
 
+	panel->backlight.enabled = panel->backlight.level != 0;
+
 	return 0;
 }
 
 static int i965_setup_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
-	u32 val;
+	u32 ctl, ctl2, val;
+
+	ctl2 = I915_READ(BLC_PWM_CTL2);
+	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
+	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+	ctl = I915_READ(BLC_PWM_CTL);
+	panel->backlight.max = ctl >> 16;
+	if (panel->backlight.combination_mode)
+		panel->backlight.max *= 0xff;
 
-	panel->backlight.max = i965_get_max_backlight(connector);
 	if (!panel->backlight.max)
 		return -ENODEV;
 
 	val = i9xx_get_backlight(connector);
 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
 
+	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
+		panel->backlight.level != 0;
+
 	return 0;
 }
 
@@ -1015,7 +1054,7 @@ static int vlv_setup_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe;
-	u32 val;
+	u32 ctl, ctl2, val;
 
 	for_each_pipe(pipe) {
 		u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
@@ -1029,13 +1068,20 @@ static int vlv_setup_backlight(struct intel_connector *connector)
 			   cur_val);
 	}
 
-	panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A);
+	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
+	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
+
+	ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
+	panel->backlight.max = ctl >> 16;
 	if (!panel->backlight.max)
 		return -ENODEV;
 
 	val = _vlv_get_backlight(dev, PIPE_A);
 	panel->backlight.level = intel_panel_compute_brightness(connector, val);
 
+	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
+		panel->backlight.level != 0;
+
 	return 0;
 }
 
@@ -1059,8 +1105,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
 		return ret;
 	}
 
-	panel->backlight.enabled = panel->backlight.level != 0;
-
 	intel_backlight_device_register(intel_connector);
 
 	panel->backlight.present = true;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 11/13] drm/i915: do full backlight setup at enable time
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (9 preceding siblings ...)
  2013-11-08 14:49 ` [PATCH 10/13] drm/i915: gather backlight information at setup Jani Nikula
@ 2013-11-08 14:49 ` Jani Nikula
  2013-11-13 17:53   ` Imre Deak
                     ` (2 more replies)
  2013-11-08 14:49 ` [PATCH 12/13] drm/i915: nuke get max backlight functions Jani Nikula
                   ` (3 subsequent siblings)
  14 siblings, 3 replies; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

We should now have all the information we need to do a full
initialization of the backlight registers.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |  145 ++++++++++++++++++++++--------------
 1 file changed, 89 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 0e8f0a3..da088e3 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -719,50 +719,71 @@ static void pch_enable_backlight(struct intel_connector *connector)
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	enum transcoder cpu_transcoder =
 		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
-	u32 tmp;
-
-	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
 
-	/* Note that this can also get called through dpms changes. And
-	 * we don't track the backlight dpms state, hence check whether
-	 * we have to do anything first. */
-	if (tmp & BLM_PWM_ENABLE)
-		return;
+	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+	if (cpu_ctl2 & BLM_PWM_ENABLE) {
+		WARN(1, "cpu backlight already enabled\n");
+		cpu_ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
+	}
 
-	if (INTEL_INFO(dev)->num_pipes == 3)
-		tmp &= ~BLM_PIPE_SELECT_IVB;
-	else
-		tmp &= ~BLM_PIPE_SELECT;
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+		DRM_DEBUG_KMS("pch backlight already enabled\n");
+		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	}
 
 	if (cpu_transcoder == TRANSCODER_EDP)
-		tmp |= BLM_TRANSCODER_EDP;
+		cpu_ctl2 = BLM_TRANSCODER_EDP;
 	else
-		tmp |= BLM_PIPE(cpu_transcoder);
-	tmp &= ~BLM_PWM_ENABLE;
-
-	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
+		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
+	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
 	POSTING_READ(BLC_PWM_CPU_CTL2);
-	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
-
-	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
-		tmp = I915_READ(BLC_PWM_PCH_CTL1);
-		tmp |= BLM_PCH_PWM_ENABLE;
-		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
-		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-	}
+	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
 
-	/*
-	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
-	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
-	 * registers are set.
-	 */
+	/* This won't stick until the above enable. */
 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	pch_ctl2 = panel->backlight.max << 16;
+	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
+
+	pch_ctl1 = 0;
+	if (panel->backlight.active_low_pwm)
+		pch_ctl1 |= BLM_PCH_POLARITY;
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	POSTING_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
 }
 
 static void i9xx_enable_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
+	u32 ctl, freq;
 
+	ctl = I915_READ(BLC_PWM_CTL);
+	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
+		WARN(1, "backlight already enabled\n");
+		I915_WRITE(BLC_PWM_CTL, 0);
+	}
+
+	freq = panel->backlight.max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
+
+	ctl = freq << 17;
+	if (IS_GEN2(dev) && panel->backlight.combination_mode)
+		ctl |= BLM_LEGACY_MODE;
+	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
+		ctl |= BLM_POLARITY_PNV;
+
+	I915_WRITE(BLC_PWM_CTL, ctl);
+	POSTING_READ(BLC_PWM_CTL);
+
+	/* XXX: combine this into above write? */
 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
@@ -772,25 +793,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
-	u32 tmp;
-
-	tmp = I915_READ(BLC_PWM_CTL2);
+	u32 ctl, ctl2, freq;
 
-	/* Note that this can also get called through dpms changes. And
-	 * we don't track the backlight dpms state, hence check whether
-	 * we have to do anything first. */
-	if (tmp & BLM_PWM_ENABLE)
-		return;
+	ctl2 = I915_READ(BLC_PWM_CTL2);
+	if (ctl2 & BLM_PWM_ENABLE) {
+		WARN(1, "backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_CTL2, ctl2);
+	}
 
-	tmp &= ~BLM_PIPE_SELECT;
-	tmp |= BLM_PIPE(pipe);
-	tmp &= ~BLM_PWM_ENABLE;
+	freq = panel->backlight.max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
 
-	I915_WRITE(BLC_PWM_CTL2, tmp);
-	POSTING_READ(BLC_PWM_CTL2);
-	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
+	ctl = freq << 16;
+	I915_WRITE(BLC_PWM_CTL, ctl);
 
+	/* XXX: combine this into above write? */
 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	ctl2 = BLM_PIPE(pipe);
+	if (panel->backlight.combination_mode)
+		ctl2 |= BLM_COMBINATION_MODE;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	I915_WRITE(BLC_PWM_CTL2, ctl2);
+	POSTING_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
 }
 
 static void vlv_enable_backlight(struct intel_connector *connector)
@@ -799,23 +828,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
-	u32 tmp;
+	u32 ctl, ctl2;
 
-	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	if (ctl2 & BLM_PWM_ENABLE) {
+		WARN(1, "backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
+	}
 
-	/* Note that this can also get called through dpms changes. And
-	 * we don't track the backlight dpms state, hence check whether
-	 * we have to do anything first. */
-	if (tmp & BLM_PWM_ENABLE)
-		return;
+	ctl = panel->backlight.max << 16;
+	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
 
-	tmp &= ~BLM_PWM_ENABLE;
+	/* XXX: combine this into above write? */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
-	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
+	ctl2 = 0;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
 	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
-	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
-
-	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
 }
 
 void intel_panel_enable_backlight(struct intel_connector *connector)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 12/13] drm/i915: nuke get max backlight functions
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (10 preceding siblings ...)
  2013-11-08 14:49 ` [PATCH 11/13] drm/i915: do full backlight setup at enable time Jani Nikula
@ 2013-11-08 14:49 ` Jani Nikula
  2013-11-13 17:54   ` Imre Deak
  2013-11-08 14:49 ` [PATCH 13/13] drm/i915: do not save/restore backlight registers Jani Nikula
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

No longer needed. We now have fully cached max backlight values.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h    |    1 -
 drivers/gpu/drm/i915/intel_panel.c |  133 ------------------------------------
 2 files changed, 134 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2d70ae4..500bab3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -416,7 +416,6 @@ struct drm_i915_display_funcs {
 	/* pll clock increase/decrease */
 
 	int (*setup_backlight)(struct intel_connector *connector);
-	uint32_t (*get_max_backlight)(struct intel_connector *connector);
 	uint32_t (*get_backlight)(struct intel_connector *connector);
 	void (*set_backlight)(struct intel_connector *connector,
 			      uint32_t level);
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index da088e3..eadfe33 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -325,132 +325,6 @@ out:
 	pipe_config->gmch_pfit.lvds_border_bits = border;
 }
 
-static int is_backlight_combination_mode(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (IS_GEN4(dev))
-		return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
-
-	if (IS_GEN2(dev))
-		return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
-
-	return 0;
-}
-
-static u32 pch_get_max_backlight(struct intel_connector *connector)
-{
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val;
-
-	val = I915_READ(BLC_PWM_PCH_CTL2);
-	if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
-		dev_priv->regfile.saveBLC_PWM_CTL2 = val;
-	} else if (val == 0) {
-		val = dev_priv->regfile.saveBLC_PWM_CTL2;
-		I915_WRITE(BLC_PWM_PCH_CTL2, val);
-	}
-
-	val >>= 16;
-
-	return val;
-}
-
-static u32 i9xx_get_max_backlight(struct intel_connector *connector)
-{
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val;
-
-	val = I915_READ(BLC_PWM_CTL);
-	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-		dev_priv->regfile.saveBLC_PWM_CTL = val;
-	} else if (val == 0) {
-		val = dev_priv->regfile.saveBLC_PWM_CTL;
-		I915_WRITE(BLC_PWM_CTL, val);
-	}
-
-	val >>= 17;
-
-	if (is_backlight_combination_mode(dev))
-		val *= 0xff;
-
-	return val;
-}
-
-static u32 i965_get_max_backlight(struct intel_connector *connector)
-{
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val;
-
-	val = I915_READ(BLC_PWM_CTL);
-	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
-		dev_priv->regfile.saveBLC_PWM_CTL = val;
-		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
-	} else if (val == 0) {
-		val = dev_priv->regfile.saveBLC_PWM_CTL;
-		I915_WRITE(BLC_PWM_CTL, val);
-		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-	}
-
-	val >>= 16;
-
-	if (is_backlight_combination_mode(dev))
-		val *= 0xff;
-
-	return val;
-}
-
-static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 val;
-
-	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;
-
-	val >>= 16;
-
-	return val;
-}
-
-static u32 vlv_get_max_backlight(struct intel_connector *connector)
-{
-	struct drm_device *dev = connector->base.dev;
-	enum pipe pipe = intel_get_pipe_from_connector(connector);
-
-	return _vlv_get_max_backlight(dev, pipe);
-}
-
-static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
-{
-	struct drm_device *dev = connector->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	u32 max;
-
-	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
-
-	max = dev_priv->display.get_max_backlight(connector);
-
-	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
-
-	return max;
-}
-
 static int i915_panel_invert_brightness;
 MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
 	"(-1 force normal, 0 machine defaults, 1 force inversion), please "
@@ -866,9 +740,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
 
 	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
 
-	/* XXX: transitional, call to make sure freq is set */
-	intel_panel_get_max_backlight(connector);
-
 	WARN_ON(panel->backlight.max == 0);
 
 	if (panel->backlight.level == 0) {
@@ -1171,28 +1042,24 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
 		dev_priv->display.disable_backlight = pch_disable_backlight;
 		dev_priv->display.set_backlight = pch_set_backlight;
 		dev_priv->display.get_backlight = pch_get_backlight;
-		dev_priv->display.get_max_backlight = pch_get_max_backlight;
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->display.setup_backlight = vlv_setup_backlight;
 		dev_priv->display.enable_backlight = vlv_enable_backlight;
 		dev_priv->display.disable_backlight = vlv_disable_backlight;
 		dev_priv->display.set_backlight = vlv_set_backlight;
 		dev_priv->display.get_backlight = vlv_get_backlight;
-		dev_priv->display.get_max_backlight = vlv_get_max_backlight;
 	} else if (IS_GEN4(dev)) {
 		dev_priv->display.setup_backlight = i965_setup_backlight;
 		dev_priv->display.enable_backlight = i965_enable_backlight;
 		dev_priv->display.disable_backlight = i965_disable_backlight;
 		dev_priv->display.set_backlight = i9xx_set_backlight;
 		dev_priv->display.get_backlight = i9xx_get_backlight;
-		dev_priv->display.get_max_backlight = i965_get_max_backlight;
 	} else {
 		dev_priv->display.setup_backlight = i9xx_setup_backlight;
 		dev_priv->display.enable_backlight = i9xx_enable_backlight;
 		dev_priv->display.disable_backlight = i9xx_disable_backlight;
 		dev_priv->display.set_backlight = i9xx_set_backlight;
 		dev_priv->display.get_backlight = i9xx_get_backlight;
-		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
 	}
 }
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 13/13] drm/i915: do not save/restore backlight registers
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (11 preceding siblings ...)
  2013-11-08 14:49 ` [PATCH 12/13] drm/i915: nuke get max backlight functions Jani Nikula
@ 2013-11-08 14:49 ` Jani Nikula
  2013-11-12 23:25   ` Daniel Vetter
  2013-11-11  8:36 ` [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
  2013-11-12 21:22 ` Imre Deak
  14 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-08 14:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

The backlight enable code now has the smarts to do the right thing.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     |    6 -----
 drivers/gpu/drm/i915/i915_suspend.c |   45 -----------------------------------
 2 files changed, 51 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 500bab3..6fec21e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -766,13 +766,7 @@ struct i915_suspend_saved_registers {
 	u32 saveDSPATILEOFF;
 	u32 savePFIT_PGM_RATIOS;
 	u32 saveBLC_HIST_CTL;
-	u32 saveBLC_PWM_CTL;
-	u32 saveBLC_PWM_CTL2;
 	u32 saveBLC_HIST_CTL_B;
-	u32 saveBLC_PWM_CTL_B;
-	u32 saveBLC_PWM_CTL2_B;
-	u32 saveBLC_CPU_PWM_CTL;
-	u32 saveBLC_CPU_PWM_CTL2;
 	u32 saveFPB0;
 	u32 saveFPB1;
 	u32 saveDPLL_B;
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index eadf8e1..6b8fef7 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -192,7 +192,6 @@ static void i915_restore_vga(struct drm_device *dev)
 static void i915_save_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long flags;
 
 	/* Display arbitration control */
 	if (INTEL_INFO(dev)->gen <= 4)
@@ -203,46 +202,27 @@ static void i915_save_display(struct drm_device *dev)
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_save_display_reg(dev);
 
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-
 	/* LVDS state */
 	if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
-		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
-		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
-		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
-		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
 		if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
 			dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
 		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
 
-		dev_priv->regfile.saveBLC_PWM_CTL =
-			I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
 		dev_priv->regfile.saveBLC_HIST_CTL =
 			I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
-		dev_priv->regfile.saveBLC_PWM_CTL2 =
-			I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
-		dev_priv->regfile.saveBLC_PWM_CTL_B =
-			I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
 		dev_priv->regfile.saveBLC_HIST_CTL_B =
 			I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
-		dev_priv->regfile.saveBLC_PWM_CTL2_B =
-			I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
 	} else {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
 		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
-		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
 		dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
-		if (INTEL_INFO(dev)->gen >= 4)
-			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
 		if (IS_MOBILE(dev) && !IS_I830(dev))
 			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
 		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
 
@@ -278,7 +258,6 @@ static void i915_restore_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 mask = 0xffffffff;
-	unsigned long flags;
 
 	/* Display arbitration */
 	if (INTEL_INFO(dev)->gen <= 4)
@@ -287,12 +266,6 @@ static void i915_restore_display(struct drm_device *dev)
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_restore_display_reg(dev);
 
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-
-	/* LVDS state */
-	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
-		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		mask = ~LVDS_PORT_EN;
 
@@ -305,13 +278,6 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL);
 
 	if (HAS_PCH_SPLIT(dev)) {
-		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
-		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
-		 * otherwise we get blank eDP screen after S3 on some machines
-		 */
-		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
-		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
 		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
 		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
 		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
@@ -319,21 +285,12 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(RSTDBYCTL,
 			   dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
 	} else if (IS_VALLEYVIEW(dev)) {
-		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
-			   dev_priv->regfile.saveBLC_PWM_CTL);
 		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
 			   dev_priv->regfile.saveBLC_HIST_CTL);
-		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
-			   dev_priv->regfile.saveBLC_PWM_CTL2);
-		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
-			   dev_priv->regfile.saveBLC_PWM_CTL);
 		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
 			   dev_priv->regfile.saveBLC_HIST_CTL);
-		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
-			   dev_priv->regfile.saveBLC_PWM_CTL2);
 	} else {
 		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
-		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
 		I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL);
 		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
 		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
@@ -341,8 +298,6 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 	/* only restore FBC info on the platform that supports FBC*/
 	intel_disable_fbc(dev);
 	if (I915_HAS_FBC(dev)) {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 00/13] drm/i915: backlight rewrite
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (12 preceding siblings ...)
  2013-11-08 14:49 ` [PATCH 13/13] drm/i915: do not save/restore backlight registers Jani Nikula
@ 2013-11-11  8:36 ` Jani Nikula
  2013-11-12 21:22 ` Imre Deak
  14 siblings, 0 replies; 49+ messages in thread
From: Jani Nikula @ 2013-11-11  8:36 UTC (permalink / raw)
  To: intel-gfx

On Fri, 08 Nov 2013, Jani Nikula <jani.nikula@intel.com> wrote:
> I've tested this so far on ILK and IVB, trying carefully keep it working
> commit by commit to keep things bisectable. More testing across
> platforms is very much needed. We have a history with backlight...

I've now tested this on PNV and SNB too, seems to work fine.

Cheers,
Jani.


-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 00/13] drm/i915: backlight rewrite
  2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
                   ` (13 preceding siblings ...)
  2013-11-11  8:36 ` [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
@ 2013-11-12 21:22 ` Imre Deak
  14 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-12 21:22 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> Hi all -
> 
> This series is a successor to [1], but with too many changes to list so
> I'll just consider this v1 of the patches.
> 
> This is pretty much a rewrite of our backlight code. Highlights:
> 
> * All the platform specific stuff in platform specific functions. The
>   code is much easier to follow, and it will be easier to enable future
>   platforms without breaking old ones all the time.
> 
> * Backlight enable writes all the backlight registers based on
>   information retrieved at setup stage. We no longer depend on what's in
>   the registers prior to enable, which should make things more
>   deterministic, and we no longer need to save/restore backlight
>   registers.
> 
> * We no longer keep reading max backlight value or combination mode bits
>   etc. from the registers all over the place. All that is based on the
>   initial values read in the setup stage.
> 
> TODO:
> 
> * If initial setup in registers is bogus, we should try to read the
>   values from VBT and/or try to use sane defaults. (This problem we have
>   already, not introduced by the series.)
> 
> I've tested this so far on ILK and IVB, trying carefully keep it working
> commit by commit to keep things bisectable. More testing across
> platforms is very much needed. We have a history with backlight...
> 
> Also available at backlight-rework branch at [2].

Looks like a nice improvement to code readability and separation of init
vs. run-time HW programming steps. The diff is big and I only managed to
review patches 1-9 so far; afaics those could be applied even
separately. r-bs and some nitpicks inlined.

--Imre 

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 01/13] drm/i915: clean up backlight conditional build
  2013-11-08 14:48 ` [PATCH 01/13] drm/i915: clean up backlight conditional build Jani Nikula
@ 2013-11-12 21:23   ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-12 21:23 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> I've always felt the backlight device conditional build has been all
> backwards. Make it feel right.
> 
> Gently move things towards connector based stuff while at it.
> 
> There should be no functional changes.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 02/13] drm/i915: make backlight info per-connector
  2013-11-08 14:48 ` [PATCH 02/13] drm/i915: make backlight info per-connector Jani Nikula
@ 2013-11-12 21:29   ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-12 21:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> Move from dev_priv to connector->panel. We still don't allow multiple
> sysfs interfaces, though.
> 
> There should be no functional changes, except for a slight reordering of
> connector backlight and sysfs destroy calls. (This change happens now
> that the backlight device is actually per-connector, even though the
> destroy calls became per-connector earlier.)
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_dma.c     |    2 +-
>  drivers/gpu/drm/i915/i915_drv.h     |    9 +---
>  drivers/gpu/drm/i915/i915_suspend.c |    8 ++--
>  drivers/gpu/drm/i915/intel_drv.h    |    7 +++
>  drivers/gpu/drm/i915/intel_panel.c  |   85 +++++++++++++++++++----------------
>  5 files changed, 61 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 0cab2d0..9a2a175 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -1486,7 +1486,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
>  
>  	spin_lock_init(&dev_priv->irq_lock);
>  	spin_lock_init(&dev_priv->gpu_error.lock);
> -	spin_lock_init(&dev_priv->backlight.lock);
> +	spin_lock_init(&dev_priv->backlight_lock);
>  	spin_lock_init(&dev_priv->uncore.lock);
>  	spin_lock_init(&dev_priv->mm.object_stat_lock);
>  	mutex_init(&dev_priv->dpio_lock);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 67117e7..0517d47 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1368,13 +1368,8 @@ typedef struct drm_i915_private {
>  	struct intel_overlay *overlay;
>  	unsigned int sprite_scaling_enabled;
>  
> -	/* backlight */
> -	struct {
> -		int level;
> -		bool enabled;
> -		spinlock_t lock; /* bl registers and the above bl fields */
> -		struct backlight_device *device;
> -	} backlight;
> +	/* backlight registers and fields in struct intel_panel */
> +	spinlock_t backlight_lock;
>  
>  	/* LVDS info */
>  	bool no_aux_handshake;
> diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
> index 98790c7..eadf8e1 100644
> --- a/drivers/gpu/drm/i915/i915_suspend.c
> +++ b/drivers/gpu/drm/i915/i915_suspend.c
> @@ -203,7 +203,7 @@ static void i915_save_display(struct drm_device *dev)
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		i915_save_display_reg(dev);
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	/* LVDS state */
>  	if (HAS_PCH_SPLIT(dev)) {
> @@ -241,7 +241,7 @@ static void i915_save_display(struct drm_device *dev)
>  			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  
>  	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
>  		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
> @@ -287,7 +287,7 @@ static void i915_restore_display(struct drm_device *dev)
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		i915_restore_display_reg(dev);
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	/* LVDS state */
>  	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
> @@ -341,7 +341,7 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  
>  	/* only restore FBC info on the platform that supports FBC*/
>  	intel_disable_fbc(dev);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 1625580..a0d8dda 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -156,6 +156,13 @@ struct intel_encoder {
>  struct intel_panel {
>  	struct drm_display_mode *fixed_mode;
>  	int fitting_mode;
> +
> +	/* backlight */
> +	struct {
> +		u32 level;
> +		bool enabled;
> +		struct backlight_device *device;
> +	} backlight;
>  };
>  
>  struct intel_connector {
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index a0d13d3..0a4aeaf 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -346,7 +346,7 @@ 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;
>  
> -	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight.lock));
> +	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
>  
>  	/* Restore the CTL value if it lost, e.g. GPU reset */
>  
> @@ -449,7 +449,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
>  	unsigned long flags;
>  	int reg;
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	if (HAS_PCH_SPLIT(dev)) {
>  		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> @@ -473,7 +473,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
>  
>  	val = intel_panel_compute_brightness(dev, pipe, val);
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  
>  	DRM_DEBUG_DRIVER("get backlight PWM = %d\n", val);
>  	return val;
> @@ -530,6 +530,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	u32 freq;
>  	unsigned long flags;
> @@ -537,7 +538,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  	if (pipe == INVALID_PIPE)
>  		return;
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	freq = intel_panel_get_max_backlight(dev, pipe);
>  	if (!freq) {
> @@ -551,20 +552,21 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  	else
>  		level = freq / max * level;
>  
> -	dev_priv->backlight.level = level;
> -	if (dev_priv->backlight.device)
> -		dev_priv->backlight.device->props.brightness = level;
> +	panel->backlight.level = level;
> +	if (panel->backlight.device)
> +		panel->backlight.device->props.brightness = level;
>  
> -	if (dev_priv->backlight.enabled)
> +	if (panel->backlight.enabled)
>  		intel_panel_actually_set_backlight(dev, pipe, level);
>  out:
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
>  
>  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;
> +	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	unsigned long flags;
>  
> @@ -582,9 +584,9 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
>  		return;
>  	}
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
> -	dev_priv->backlight.enabled = false;
> +	panel->backlight.enabled = false;
>  	intel_panel_actually_set_backlight(dev, pipe, 0);
>  
>  	if (INTEL_INFO(dev)->gen >= 4) {
> @@ -606,13 +608,14 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
>  		}
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
>  
>  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;
> +	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	enum transcoder cpu_transcoder =
>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> @@ -623,14 +626,14 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>  
>  	DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe));
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
> -	if (dev_priv->backlight.level == 0) {
> -		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;
> +	if (panel->backlight.level == 0) {
> +		panel->backlight.level = intel_panel_get_max_backlight(dev,
> +								       pipe);
> +		if (panel->backlight.device)
> +			panel->backlight.device->props.brightness =
> +				panel->backlight.level;
>  	}
>  
>  	if (INTEL_INFO(dev)->gen >= 4) {
> @@ -680,11 +683,11 @@ set_level:
>  	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
>  	 * registers are set.
>  	 */
> -	dev_priv->backlight.enabled = true;
> +	panel->backlight.enabled = true;
>  	intel_panel_actually_set_backlight(dev, pipe,
> -					   dev_priv->backlight.level);
> +					   panel->backlight.level);
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
>  
>  /* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
> @@ -770,34 +773,40 @@ static int intel_backlight_device_register(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	struct backlight_properties props;
>  	unsigned long flags;
>  
> -	if (WARN_ON(dev_priv->backlight.device))
> +	if (WARN_ON(panel->backlight.device))
>  		return -ENODEV;
>  
>  	memset(&props, 0, sizeof(props));
>  	props.type = BACKLIGHT_RAW;
> -	props.brightness = dev_priv->backlight.level;
> +	props.brightness = panel->backlight.level;
>  
> -	spin_lock_irqsave(&dev_priv->backlight.lock, flags);
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  	props.max_brightness = intel_panel_get_max_backlight(dev, 0);
> -	spin_unlock_irqrestore(&dev_priv->backlight.lock, flags);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  
>  	if (props.max_brightness == 0) {
>  		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
>  		return -ENODEV;
>  	}
> -	dev_priv->backlight.device =
> +
> +	/*
> +	 * Note: using the same name independent of the connector prevents
> +	 * registration of multiple backlight devices in the driver.
> +	 */
> +	panel->backlight.device =
>  		backlight_device_register("intel_backlight",
>  					  connector->base.kdev,
>  					  connector,
>  					  &intel_backlight_device_ops, &props);
>  
> -	if (IS_ERR(dev_priv->backlight.device)) {
> +	if (IS_ERR(panel->backlight.device)) {
>  		DRM_ERROR("Failed to register backlight: %ld\n",
> -			  PTR_ERR(dev_priv->backlight.device));
> -		dev_priv->backlight.device = NULL;
> +			  PTR_ERR(panel->backlight.device));
> +		panel->backlight.device = NULL;
>  		return -ENODEV;
>  	}
>  	return 0;
> @@ -805,11 +814,11 @@ static int intel_backlight_device_register(struct intel_connector *connector)
>  
>  static void intel_backlight_device_unregister(struct intel_connector *connector)
>  {
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	if (dev_priv->backlight.device) {
> -		backlight_device_unregister(dev_priv->backlight.device);
> -		dev_priv->backlight.device = NULL;
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (panel->backlight.device) {
> +		backlight_device_unregister(panel->backlight.device);
> +		panel->backlight.device = NULL;
>  	}
>  }
>  #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> @@ -825,13 +834,13 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
>  int intel_panel_setup_backlight(struct drm_connector *connector)
>  {
>  	struct drm_device *dev = connector->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
> +	struct intel_panel *panel = &intel_connector->panel;
>  
>  	intel_panel_init_backlight_regs(dev);
>  
> -	dev_priv->backlight.level = intel_panel_get_backlight(dev, 0);
> -	dev_priv->backlight.enabled = dev_priv->backlight.level != 0;
> +	panel->backlight.level = intel_panel_get_backlight(dev, 0);
> +	panel->backlight.enabled = panel->backlight.level != 0;
>  
>  	intel_backlight_device_register(intel_connector);
>  

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 03/13] drm/i915: make asle notifications update backlight on all connectors
  2013-11-08 14:48 ` [PATCH 03/13] drm/i915: make asle notifications update backlight on all connectors Jani Nikula
@ 2013-11-12 21:29   ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-12 21:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> ALthough usually there's only one connector that supports backlight,
> this also finds the correct connector. Before, we only updated the
> connector on pipe A, which might not be the one with backlight. (This
> only made a difference on BYT.)
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_drv.h      |    1 +
>  drivers/gpu/drm/i915/intel_opregion.c |   43 ++++++++++-----------------------
>  drivers/gpu/drm/i915/intel_panel.c    |    4 +++
>  3 files changed, 18 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index a0d8dda..68bec63 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -159,6 +159,7 @@ struct intel_panel {
>  
>  	/* backlight */
>  	struct {
> +		bool present;
>  		u32 level;
>  		bool enabled;
>  		struct backlight_device *device;
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index 91b68dc..a0b5a99 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -396,13 +396,10 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
>  static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct drm_encoder *encoder;
>  	struct drm_connector *connector;
> -	struct intel_connector *intel_connector = NULL;
> -	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
> +	struct intel_connector *intel_connector;
> +	struct intel_panel *panel;
>  	struct opregion_asle __iomem *asle = dev_priv->opregion.asle;
> -	u32 ret = 0;
> -	bool found = false;
>  
>  	DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
>  
> @@ -414,38 +411,24 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
>  		return ASLC_BACKLIGHT_FAILED;
>  
>  	mutex_lock(&dev->mode_config.mutex);
> +
>  	/*
> -	 * Could match the OpRegion connector here instead, but we'd also need
> -	 * to verify the connector could handle a backlight call.
> +	 * Update backlight on all connectors that support backlight (usually
> +	 * only one).
>  	 */
> -	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
> -		if (encoder->crtc == crtc) {
> -			found = true;
> -			break;
> -		}
> -
> -	if (!found) {
> -		ret = ASLC_BACKLIGHT_FAILED;
> -		goto out;
> -	}
> -
> -	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
> -		if (connector->encoder == encoder)
> -			intel_connector = to_intel_connector(connector);
> -
> -	if (!intel_connector) {
> -		ret = ASLC_BACKLIGHT_FAILED;
> -		goto out;
> -	}
> -
>  	DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
> -	intel_panel_set_backlight(intel_connector, bclp, 255);
> +	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> +		intel_connector = to_intel_connector(connector);
> +		panel = &intel_connector->panel;
> +		if (panel->backlight.present)
> +			intel_panel_set_backlight(intel_connector, bclp, 255);
> +	}
>  	iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv);
>  
> -out:
>  	mutex_unlock(&dev->mode_config.mutex);
>  
> -	return ret;
> +
> +	return 0;
>  }
>  
>  static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 0a4aeaf..c80bffc 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -844,13 +844,17 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
>  
>  	intel_backlight_device_register(intel_connector);
>  
> +	panel->backlight.present = true;
> +
>  	return 0;
>  }
>  
>  void intel_panel_destroy_backlight(struct drm_connector *connector)
>  {
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
> +	struct intel_panel *panel = &intel_connector->panel;
>  
> +	panel->backlight.present = false;
>  	intel_backlight_device_unregister(intel_connector);
>  }
>  

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 04/13] drm/i915: handle backlight through chip specific functions
  2013-11-08 14:48 ` [PATCH 04/13] drm/i915: handle backlight through chip specific functions Jani Nikula
@ 2013-11-12 21:36   ` Imre Deak
  2013-11-12 23:19     ` Daniel Vetter
  0 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-12 21:36 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> The backlight code has grown rather hairy, not least because the
> hardware registers and bits have repeatedly been shuffled around. And
> this isn't expected to get any easier with new hardware. Make things
> easier for our (read: my) poor brains, and split the code up into chip
> specific functions.
> 
> There should be no functional changes.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

This was rather difficult to read. Perhaps breaking it to per-callback
refactoring patches would've been feasible and easier to review, but
looks anyway good to me:

Reviewed-by: Imre Deak <imre.deak@intel.com> 

> ---
>  drivers/gpu/drm/i915/i915_drv.h      |    9 +
>  drivers/gpu/drm/i915/intel_display.c |    2 +
>  drivers/gpu/drm/i915/intel_drv.h     |    2 +
>  drivers/gpu/drm/i915/intel_panel.c   |  642 +++++++++++++++++++++++-----------
>  4 files changed, 447 insertions(+), 208 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0517d47..2d70ae4 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -351,6 +351,7 @@ struct drm_i915_error_state {
>  	enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
>  };
>  
> +struct intel_connector;
>  struct intel_crtc_config;
>  struct intel_crtc;
>  struct intel_limit;
> @@ -413,6 +414,14 @@ struct drm_i915_display_funcs {
>  	/* render clock increase/decrease */
>  	/* display clock increase/decrease */
>  	/* pll clock increase/decrease */
> +
> +	int (*setup_backlight)(struct intel_connector *connector);
> +	uint32_t (*get_max_backlight)(struct intel_connector *connector);
> +	uint32_t (*get_backlight)(struct intel_connector *connector);
> +	void (*set_backlight)(struct intel_connector *connector,
> +			      uint32_t level);
> +	void (*disable_backlight)(struct intel_connector *connector);
> +	void (*enable_backlight)(struct intel_connector *connector);
>  };
>  
>  struct intel_uncore_funcs {
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 30d3993..b6533f8 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10604,6 +10604,8 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.queue_flip = intel_gen7_queue_flip;
>  		break;
>  	}
> +
> +	intel_panel_init_backlight_funcs(dev);
>  }
>  
>  /*
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 68bec63..7384a7b 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -161,6 +161,7 @@ struct intel_panel {
>  	struct {
>  		bool present;
>  		u32 level;
> +		u32 max;
>  		bool enabled;
>  		struct backlight_device *device;
>  	} backlight;
> @@ -817,6 +818,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector);
>  void intel_panel_enable_backlight(struct intel_connector *connector);
>  void intel_panel_disable_backlight(struct intel_connector *connector);
>  void intel_panel_destroy_backlight(struct drm_connector *connector);
> +void intel_panel_init_backlight_funcs(struct drm_device *dev);
>  enum drm_connector_status intel_panel_detect(struct drm_device *dev);
>  
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index c80bffc..a821949 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -338,79 +338,117 @@ static int is_backlight_combination_mode(struct drm_device *dev)
>  	return 0;
>  }
>  
> -/* 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, enum pipe pipe)
> +static u32 pch_get_max_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 val;
>  
> -	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
> +	val = I915_READ(BLC_PWM_PCH_CTL2);
> +	if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
> +		dev_priv->regfile.saveBLC_PWM_CTL2 = val;
> +	} else if (val == 0) {
> +		val = dev_priv->regfile.saveBLC_PWM_CTL2;
> +		I915_WRITE(BLC_PWM_PCH_CTL2, val);
> +	}
>  
> -	/* Restore the CTL value if it lost, e.g. GPU reset */
> +	val >>= 16;
>  
> -	if (HAS_PCH_SPLIT(dev_priv->dev)) {
> -		val = I915_READ(BLC_PWM_PCH_CTL2);
> -		if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
> -			dev_priv->regfile.saveBLC_PWM_CTL2 = val;
> -		} else if (val == 0) {
> -			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);
> -		}
> +	return val;
> +}
>  
> -		if (!val)
> -			val = 0x0f42ffff;
> -	} else {
> -		val = I915_READ(BLC_PWM_CTL);
> -		if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> -			dev_priv->regfile.saveBLC_PWM_CTL = val;
> -			if (INTEL_INFO(dev)->gen >= 4)
> -				dev_priv->regfile.saveBLC_PWM_CTL2 =
> -					I915_READ(BLC_PWM_CTL2);
> -		} else if (val == 0) {
> -			val = dev_priv->regfile.saveBLC_PWM_CTL;
> -			I915_WRITE(BLC_PWM_CTL, val);
> -			if (INTEL_INFO(dev)->gen >= 4)
> -				I915_WRITE(BLC_PWM_CTL2,
> -					   dev_priv->regfile.saveBLC_PWM_CTL2);
> -		}
> +static u32 i9xx_get_max_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 val;
> +
> +	val = I915_READ(BLC_PWM_CTL);
> +	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> +		dev_priv->regfile.saveBLC_PWM_CTL = val;
> +	} else if (val == 0) {
> +		val = dev_priv->regfile.saveBLC_PWM_CTL;
> +		I915_WRITE(BLC_PWM_CTL, val);
>  	}
>  
> +	val >>= 17;
> +
> +	if (is_backlight_combination_mode(dev))
> +		val *= 0xff;
> +
>  	return val;
>  }
>  
> -static u32 intel_panel_get_max_backlight(struct drm_device *dev,
> -					 enum pipe pipe)
> +static u32 i965_get_max_backlight(struct intel_connector *connector)
>  {
> -	u32 max;
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 val;
> +
> +	val = I915_READ(BLC_PWM_CTL);
> +	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> +		dev_priv->regfile.saveBLC_PWM_CTL = val;
> +		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
> +	} else if (val == 0) {
> +		val = dev_priv->regfile.saveBLC_PWM_CTL;
> +		I915_WRITE(BLC_PWM_CTL, val);
> +		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> +	}
>  
> -	max = i915_read_blc_pwm_ctl(dev, pipe);
> +	val >>= 16;
>  
> -	if (HAS_PCH_SPLIT(dev)) {
> -		max >>= 16;
> -	} else {
> -		if (INTEL_INFO(dev)->gen < 4)
> -			max >>= 17;
> -		else
> -			max >>= 16;
> +	if (is_backlight_combination_mode(dev))
> +		val *= 0xff;
> +
> +	return val;
> +}
> +
> +static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 val;
>  
> -		if (is_backlight_combination_mode(dev))
> -			max *= 0xff;
> +	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;
> +
> +	val >>= 16;
> +
> +	return val;
> +}
> +
> +static u32 vlv_get_max_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	enum pipe pipe = intel_get_pipe_from_connector(connector);
> +
> +	return _vlv_get_max_backlight(dev, pipe);
> +}
> +
> +/* XXX: query mode clock or hardware clock and program max PWM appropriately
> + * when it's 0.
> + */
> +static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 max;
> +
> +	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
> +
> +	max = dev_priv->display.get_max_backlight(connector);
> +
>  	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
>  
>  	return max;
> @@ -423,9 +461,10 @@ 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,
> -					  enum pipe pipe, u32 val)
> +static u32 intel_panel_compute_brightness(struct intel_connector *connector,
> +					  u32 val)
>  {
> +	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
>  	if (i915_panel_invert_brightness < 0)
> @@ -433,7 +472,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
>  
>  	if (i915_panel_invert_brightness > 0 ||
>  	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
> -		u32 max = intel_panel_get_max_backlight(dev, pipe);
> +		u32 max = intel_panel_get_max_backlight(connector);
>  		if (max)
>  			return max - val;
>  	}
> @@ -441,37 +480,60 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
>  	return val;
>  }
>  
> -static u32 intel_panel_get_backlight(struct drm_device *dev,
> -				     enum pipe pipe)
> +static u32 pch_get_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val;
> -	unsigned long flags;
> -	int reg;
>  
> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> +	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> +}
>  
> -	if (HAS_PCH_SPLIT(dev)) {
> -		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> -	} else {
> -		if (IS_VALLEYVIEW(dev))
> -			reg = VLV_BLC_PWM_CTL(pipe);
> -		else
> -			reg = BLC_PWM_CTL;
> +static u32 i9xx_get_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 val;
>  
> -		val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
> -		if (INTEL_INFO(dev)->gen < 4)
> -			val >>= 1;
> +	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> +	if (INTEL_INFO(dev)->gen < 4)
> +		val >>= 1;
>  
> -		if (is_backlight_combination_mode(dev)) {
> -			u8 lbpc;
> +	if (is_backlight_combination_mode(dev)) {
> +		u8 lbpc;
>  
> -			pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
> -			val *= lbpc;
> -		}
> +		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
> +		val *= lbpc;
>  	}
>  
> -	val = intel_panel_compute_brightness(dev, pipe, val);
> +	return val;
> +}
> +
> +static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
> +}
> +
> +static u32 vlv_get_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	enum pipe pipe = intel_get_pipe_from_connector(connector);
> +
> +	return _vlv_get_backlight(dev, pipe);
> +}
> +
> +static u32 intel_panel_get_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 val;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> +
> +	val = dev_priv->display.get_backlight(connector);
> +	val = intel_panel_compute_brightness(connector, val);
>  
>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  
> @@ -479,28 +541,24 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
>  	return val;
>  }
>  
> -static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
> +static void pch_set_backlight(struct intel_connector *connector, u32 level)
>  {
> +	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> -	I915_WRITE(BLC_PWM_CPU_CTL, val | level);
> +	u32 tmp;
> +
> +	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
>  }
>  
> -static void intel_panel_actually_set_backlight(struct drm_device *dev,
> -					       enum pipe pipe, u32 level)
> +static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>  {
> +	struct drm_device *dev = connector->base.dev;
>  	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, 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, pipe);
> +		u32 max = intel_panel_get_max_backlight(connector);
>  		u8 lbpc;
>  
>  		/* we're screwed, but keep behaviour backwards compatible */
> @@ -512,16 +570,34 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
>  	}
>  
> -	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(reg, tmp | level);
> +
> +	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	I915_WRITE(BLC_PWM_CTL, tmp | level);
> +}
> +
> +static void vlv_set_backlight(struct intel_connector *connector, u32 level)
> +{
> +	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 tmp;
> +
> +	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
> +}
> +
> +static void
> +intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
> +
> +	level = intel_panel_compute_brightness(connector, level);
> +	dev_priv->display.set_backlight(connector, level);
>  }
>  
>  /* set backlight brightness to level in range [0..max] */
> @@ -540,7 +616,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
> -	freq = intel_panel_get_max_backlight(dev, pipe);
> +	freq = intel_panel_get_max_backlight(connector);
>  	if (!freq) {
>  		/* we are screwed, bail out */
>  		goto out;
> @@ -557,11 +633,45 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  		panel->backlight.device->props.brightness = level;
>  
>  	if (panel->backlight.enabled)
> -		intel_panel_actually_set_backlight(dev, pipe, level);
> +		intel_panel_actually_set_backlight(connector, level);
>  out:
>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
>  
> +static void pch_disable_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 tmp;
> +
> +	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> +	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
> +
> +	tmp = I915_READ(BLC_PWM_PCH_CTL1);
> +	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
> +}
> +
> +static void i965_disable_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	u32 tmp;
> +
> +	tmp = I915_READ(BLC_PWM_CTL2);
> +	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
> +}
> +
> +static void vlv_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);
> +	u32 tmp;
> +
> +	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
> +}
> +
>  void intel_panel_disable_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
> @@ -587,28 +697,100 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	panel->backlight.enabled = false;
> -	intel_panel_actually_set_backlight(dev, pipe, 0);
> +	intel_panel_actually_set_backlight(connector, 0);
>  
> -	if (INTEL_INFO(dev)->gen >= 4) {
> -		uint32_t reg, tmp;
> +	if (dev_priv->display.disable_backlight)
> +		dev_priv->display.disable_backlight(connector);
>  
> -		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;
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> +}
>  
> -		I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
> +static void pch_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);
> +	u32 tmp;
>  
> -		if (HAS_PCH_SPLIT(dev)) {
> -			tmp = I915_READ(BLC_PWM_PCH_CTL1);
> -			tmp &= ~BLM_PCH_PWM_ENABLE;
> -			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> -		}
> +	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> +
> +	/* Note that this can also get called through dpms changes. And
> +	 * we don't track the backlight dpms state, hence check whether
> +	 * we have to do anything first. */
> +	if (tmp & BLM_PWM_ENABLE)
> +		return;
> +
> +	if (INTEL_INFO(dev)->num_pipes == 3)
> +		tmp &= ~BLM_PIPE_SELECT_IVB;
> +	else
> +		tmp &= ~BLM_PIPE_SELECT;
> +
> +	if (cpu_transcoder == TRANSCODER_EDP)
> +		tmp |= BLM_TRANSCODER_EDP;
> +	else
> +		tmp |= BLM_PIPE(cpu_transcoder);
> +	tmp &= ~BLM_PWM_ENABLE;
> +
> +	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
> +	POSTING_READ(BLC_PWM_CPU_CTL2);
> +	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
> +
> +	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> +		tmp = I915_READ(BLC_PWM_PCH_CTL1);
> +		tmp |= BLM_PCH_PWM_ENABLE;
> +		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> +		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
>  	}
> +}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> +static void i965_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);
> +	u32 tmp;
> +
> +	tmp = I915_READ(BLC_PWM_CTL2);
> +
> +	/* Note that this can also get called through dpms changes. And
> +	 * we don't track the backlight dpms state, hence check whether
> +	 * we have to do anything first. */
> +	if (tmp & BLM_PWM_ENABLE)
> +		return;
> +
> +	tmp &= ~BLM_PIPE_SELECT;
> +	tmp |= BLM_PIPE(pipe);
> +	tmp &= ~BLM_PWM_ENABLE;
> +
> +	I915_WRITE(BLC_PWM_CTL2, tmp);
> +	POSTING_READ(BLC_PWM_CTL2);
> +	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> +}
> +
> +static void vlv_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);
> +	u32 tmp;
> +
> +	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> +
> +	/* Note that this can also get called through dpms changes. And
> +	 * we don't track the backlight dpms state, hence check whether
> +	 * we have to do anything first. */
> +	if (tmp & BLM_PWM_ENABLE)
> +		return;
> +
> +	tmp &= ~BLM_PIPE_SELECT;
> +	tmp |= BLM_PIPE(pipe);
> +	tmp &= ~BLM_PWM_ENABLE;
> +
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
> +	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
>  }
>  
>  void intel_panel_enable_backlight(struct intel_connector *connector)
> @@ -617,8 +799,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	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)
> @@ -629,89 +809,25 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	if (panel->backlight.level == 0) {
> -		panel->backlight.level = intel_panel_get_max_backlight(dev,
> -								       pipe);
> +		panel->backlight.level = intel_panel_get_max_backlight(connector);
>  		if (panel->backlight.device)
>  			panel->backlight.device->props.brightness =
>  				panel->backlight.level;
>  	}
>  
> -	if (INTEL_INFO(dev)->gen >= 4) {
> -		uint32_t reg, tmp;
> -
> -		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);
> -
> -		/* Note that this can also get called through dpms changes. And
> -		 * we don't track the backlight dpms state, hence check whether
> -		 * we have to do anything first. */
> -		if (tmp & BLM_PWM_ENABLE)
> -			goto set_level;
> -
> -		if (INTEL_INFO(dev)->num_pipes == 3)
> -			tmp &= ~BLM_PIPE_SELECT_IVB;
> -		else
> -			tmp &= ~BLM_PIPE_SELECT;
> -
> -		if (cpu_transcoder == TRANSCODER_EDP)
> -			tmp |= BLM_TRANSCODER_EDP;
> -		else
> -			tmp |= BLM_PIPE(cpu_transcoder);
> -		tmp &= ~BLM_PWM_ENABLE;
> -
> -		I915_WRITE(reg, tmp);
> -		POSTING_READ(reg);
> -		I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
> -
> -		if (HAS_PCH_SPLIT(dev) &&
> -		    !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> -			tmp = I915_READ(BLC_PWM_PCH_CTL1);
> -			tmp |= BLM_PCH_PWM_ENABLE;
> -			tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> -			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> -		}
> -	}
> +	if (dev_priv->display.enable_backlight)
> +		dev_priv->display.enable_backlight(connector);
>  
> -set_level:
>  	/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
>  	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
>  	 * registers are set.
>  	 */
>  	panel->backlight.enabled = true;
> -	intel_panel_actually_set_backlight(dev, pipe,
> -					   panel->backlight.level);
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  
>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
>  
> -/* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
> -static void intel_panel_init_backlight_regs(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	if (IS_VALLEYVIEW(dev)) {
> -		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);
> -		}
> -	}
> -}
> -
>  enum drm_connector_status
>  intel_panel_detect(struct drm_device *dev)
>  {
> @@ -753,15 +869,13 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd)
>  {
>  	struct intel_connector *connector = bl_get_data(bd);
>  	struct drm_device *dev = connector->base.dev;
> -	enum pipe pipe;
> +	int ret;
>  
>  	mutex_lock(&dev->mode_config.mutex);
> -	pipe = intel_get_pipe_from_connector(connector);
> +	ret = intel_panel_get_backlight(connector);
>  	mutex_unlock(&dev->mode_config.mutex);
> -	if (pipe == INVALID_PIPE)
> -		return 0;
>  
> -	return intel_panel_get_backlight(connector->base.dev, pipe);
> +	return ret;
>  }
>  
>  static const struct backlight_ops intel_backlight_device_ops = {
> @@ -771,27 +885,18 @@ static const struct backlight_ops intel_backlight_device_ops = {
>  
>  static int intel_backlight_device_register(struct intel_connector *connector)
>  {
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	struct backlight_properties props;
> -	unsigned long flags;
>  
>  	if (WARN_ON(panel->backlight.device))
>  		return -ENODEV;
>  
> +	BUG_ON(panel->backlight.max == 0);
> +
>  	memset(&props, 0, sizeof(props));
>  	props.type = BACKLIGHT_RAW;
>  	props.brightness = panel->backlight.level;
> -
> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> -	props.max_brightness = intel_panel_get_max_backlight(dev, 0);
> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> -
> -	if (props.max_brightness == 0) {
> -		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
> -		return -ENODEV;
> -	}
> +	props.max_brightness = panel->backlight.max;
>  
>  	/*
>  	 * Note: using the same name independent of the connector prevents
> @@ -831,15 +936,102 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
>  }
>  #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
>  
> +/* Note: The setup hooks can't assume pipe is set! */
> +static int pch_setup_backlight(struct intel_connector *connector)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	u32 val;
> +
> +	panel->backlight.max = pch_get_max_backlight(connector);
> +	if (!panel->backlight.max)
> +		return -ENODEV;
> +
> +	val = pch_get_backlight(connector);
> +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> +
> +	return 0;
> +}
> +
> +static int i9xx_setup_backlight(struct intel_connector *connector)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	u32 val;
> +
> +	panel->backlight.max = i9xx_get_max_backlight(connector);
> +	if (!panel->backlight.max)
> +		return -ENODEV;
> +
> +	val = i9xx_get_backlight(connector);
> +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> +
> +	return 0;
> +}
> +
> +static int i965_setup_backlight(struct intel_connector *connector)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +	u32 val;
> +
> +	panel->backlight.max = i965_get_max_backlight(connector);
> +	if (!panel->backlight.max)
> +		return -ENODEV;
> +
> +	val = i9xx_get_backlight(connector);
> +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> +
> +	return 0;
> +}
> +
> +static int vlv_setup_backlight(struct intel_connector *connector)
> +{
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
> +	enum pipe pipe;
> +	u32 val;
> +
> +	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);
> +	}
> +
> +	panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A);
> +	if (!panel->backlight.max)
> +		return -ENODEV;
> +
> +	val = _vlv_get_backlight(dev, PIPE_A);
> +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> +
> +	return 0;
> +}
> +
>  int intel_panel_setup_backlight(struct drm_connector *connector)
>  {
>  	struct drm_device *dev = connector->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_connector *intel_connector = to_intel_connector(connector);
>  	struct intel_panel *panel = &intel_connector->panel;
> +	unsigned long flags;
> +	int ret;
>  
> -	intel_panel_init_backlight_regs(dev);
> +	/* set level and max in panel struct */
> +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> +	ret = dev_priv->display.setup_backlight(intel_connector);
> +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> +
> +	if (ret) {
> +		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
> +			      drm_get_connector_name(connector));
> +		return ret;
> +	}
>  
> -	panel->backlight.level = intel_panel_get_backlight(dev, 0);
>  	panel->backlight.enabled = panel->backlight.level != 0;
>  
>  	intel_backlight_device_register(intel_connector);
> @@ -858,6 +1050,40 @@ void intel_panel_destroy_backlight(struct drm_connector *connector)
>  	intel_backlight_device_unregister(intel_connector);
>  }
>  
> +/* Set up chip specific backlight functions */
> +void intel_panel_init_backlight_funcs(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	if (HAS_PCH_SPLIT(dev)) {
> +		dev_priv->display.setup_backlight = pch_setup_backlight;
> +		dev_priv->display.enable_backlight = pch_enable_backlight;
> +		dev_priv->display.disable_backlight = pch_disable_backlight;
> +		dev_priv->display.set_backlight = pch_set_backlight;
> +		dev_priv->display.get_backlight = pch_get_backlight;
> +		dev_priv->display.get_max_backlight = pch_get_max_backlight;
> +	} else if (IS_VALLEYVIEW(dev)) {
> +		dev_priv->display.setup_backlight = vlv_setup_backlight;
> +		dev_priv->display.enable_backlight = vlv_enable_backlight;
> +		dev_priv->display.disable_backlight = vlv_disable_backlight;
> +		dev_priv->display.set_backlight = vlv_set_backlight;
> +		dev_priv->display.get_backlight = vlv_get_backlight;
> +		dev_priv->display.get_max_backlight = vlv_get_max_backlight;
> +	} else if (IS_GEN4(dev)) {
> +		dev_priv->display.setup_backlight = i965_setup_backlight;
> +		dev_priv->display.enable_backlight = i965_enable_backlight;
> +		dev_priv->display.disable_backlight = i965_disable_backlight;
> +		dev_priv->display.set_backlight = i9xx_set_backlight;
> +		dev_priv->display.get_backlight = i9xx_get_backlight;
> +		dev_priv->display.get_max_backlight = i965_get_max_backlight;
> +	} else {
> +		dev_priv->display.setup_backlight = i9xx_setup_backlight;
> +		dev_priv->display.set_backlight = i9xx_set_backlight;
> +		dev_priv->display.get_backlight = i9xx_get_backlight;
> +		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
> +	}
> +}
> +
>  int intel_panel_init(struct intel_panel *panel,
>  		     struct drm_display_mode *fixed_mode)
>  {

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set
  2013-11-08 14:48 ` [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set Jani Nikula
@ 2013-11-12 22:00   ` Imre Deak
  2013-11-13  8:27     ` Jani Nikula
  0 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-12 22:00 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_panel.c |   10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index a821949..e82b2dd 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -555,7 +555,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 tmp;
> +	u32 tmp, mask;
>  
>  	if (is_backlight_combination_mode(dev)) {
>  		u32 max = intel_panel_get_max_backlight(connector);
> @@ -570,10 +570,14 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
>  	}
>  
> -	if (INTEL_INFO(dev)->gen < 4)
> +	if (IS_GEN4(dev)) {
> +		mask = BACKLIGHT_DUTY_CYCLE_MASK;
> +	} else {
>  		level <<= 1;
> +		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
> +	}

According to the gen2/3 bspec I have, the correct mask is
BACKLIGHT_DUTY_CYCLE_MASK_PNV only in case of IS_PINEVIEW(dev), for
everything else it's BACKLIGHT_DUTY_CYCLE_MASK.

--Imre

>  
> -	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> +	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
>  	I915_WRITE(BLC_PWM_CTL, tmp | level);
>  }
>  

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 06/13] drm/i915: vlv does not have pipe field in backlight registers
  2013-11-08 14:48 ` [PATCH 06/13] drm/i915: vlv does not have pipe field in backlight registers Jani Nikula
@ 2013-11-12 22:00   ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-12 22:00 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> It has per pipe registers.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_panel.c |    2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index e82b2dd..5bd64db 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -788,8 +788,6 @@ static void vlv_enable_backlight(struct intel_connector *connector)
>  	if (tmp & BLM_PWM_ENABLE)
>  		return;
>  
> -	tmp &= ~BLM_PIPE_SELECT;
> -	tmp |= BLM_PIPE(pipe);
>  	tmp &= ~BLM_PWM_ENABLE;
>  
>  	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 07/13] drm/i915: move backlight level setting in enable/disable to hooks
  2013-11-08 14:48 ` [PATCH 07/13] drm/i915: move backlight level setting in enable/disable to hooks Jani Nikula
@ 2013-11-12 22:01   ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-12 22:01 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> This allows more flexibility in the ordering of the register writes, and
> lets us drop level setting altogether as necessary on a per platform
> basis.
> 
> For gen2-gen3, this is the only thing that happens in enable/disable.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_panel.c |   48 +++++++++++++++++++++++++++---------
>  1 file changed, 36 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 5bd64db..ed6b1ec 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -648,6 +648,8 @@ static void pch_disable_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 tmp;
>  
> +	intel_panel_actually_set_backlight(connector, 0);
> +
>  	tmp = I915_READ(BLC_PWM_CPU_CTL2);
>  	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
>  
> @@ -655,12 +657,19 @@ static void pch_disable_backlight(struct intel_connector *connector)
>  	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
>  }
>  
> +static void i9xx_disable_backlight(struct intel_connector *connector)
> +{
> +	intel_panel_actually_set_backlight(connector, 0);
> +}
> +
>  static void i965_disable_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 tmp;
>  
> +	intel_panel_actually_set_backlight(connector, 0);
> +
>  	tmp = I915_READ(BLC_PWM_CTL2);
>  	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
>  }
> @@ -672,6 +681,8 @@ static void vlv_disable_backlight(struct intel_connector *connector)
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	u32 tmp;
>  
> +	intel_panel_actually_set_backlight(connector, 0);
> +
>  	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
>  	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
>  }
> @@ -701,10 +712,7 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
>  	panel->backlight.enabled = false;
> -	intel_panel_actually_set_backlight(connector, 0);
> -
> -	if (dev_priv->display.disable_backlight)
> -		dev_priv->display.disable_backlight(connector);
> +	dev_priv->display.disable_backlight(connector);
>  
>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
> @@ -713,6 +721,7 @@ static void pch_enable_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	enum transcoder cpu_transcoder =
>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> @@ -747,12 +756,27 @@ static void pch_enable_backlight(struct intel_connector *connector)
>  		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
>  		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
>  	}
> +
> +	/*
> +	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> +	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> +	 * registers are set.
> +	 */
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +}
> +
> +static void i9xx_enable_backlight(struct intel_connector *connector)
> +{
> +	struct intel_panel *panel = &connector->panel;
> +
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  }
>  
>  static void i965_enable_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	u32 tmp;
>  
> @@ -771,12 +795,15 @@ static void i965_enable_backlight(struct intel_connector *connector)
>  	I915_WRITE(BLC_PWM_CTL2, tmp);
>  	POSTING_READ(BLC_PWM_CTL2);
>  	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> +
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  }
>  
>  static void vlv_enable_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	u32 tmp;
>  
> @@ -793,6 +820,8 @@ static void vlv_enable_backlight(struct intel_connector *connector)
>  	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
>  	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
>  	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
> +
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  }
>  
>  void intel_panel_enable_backlight(struct intel_connector *connector)
> @@ -817,15 +846,8 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>  				panel->backlight.level;
>  	}
>  
> -	if (dev_priv->display.enable_backlight)
> -		dev_priv->display.enable_backlight(connector);
> -
> -	/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> -	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> -	 * registers are set.
> -	 */
> +	dev_priv->display.enable_backlight(connector);
>  	panel->backlight.enabled = true;
> -	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  
>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
> @@ -1080,6 +1102,8 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
>  		dev_priv->display.get_max_backlight = i965_get_max_backlight;
>  	} else {
>  		dev_priv->display.setup_backlight = i9xx_setup_backlight;
> +		dev_priv->display.enable_backlight = i9xx_enable_backlight;
> +		dev_priv->display.disable_backlight = i9xx_disable_backlight;
>  		dev_priv->display.set_backlight = i9xx_set_backlight;
>  		dev_priv->display.get_backlight = i9xx_get_backlight;
>  		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it
  2013-11-08 14:49 ` [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it Jani Nikula
@ 2013-11-12 22:42   ` Imre Deak
  2013-11-13  8:39     ` Jani Nikula
  0 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-12 22:42 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> We now have the max backlight value cached. Use it.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_panel.c |   45 +++++++++++++++++++-----------------
>  1 file changed, 24 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index ed6b1ec..9a55b36 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -436,9 +436,6 @@ static u32 vlv_get_max_backlight(struct intel_connector *connector)
>  	return _vlv_get_max_backlight(dev, pipe);
>  }
>  
> -/* XXX: query mode clock or hardware clock and program max PWM appropriately
> - * when it's 0.
> - */
>  static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
> @@ -466,15 +463,16 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
> +
> +	WARN_ON(panel->backlight.max == 0);

Just to clarify that I understood this: we can't hit this any more since
setup_backlight returns now -ENODEV if backlight.max == 0 and so we
won't register the backlight device in that case. I assume then that
during booting the BIOS always leaves us with a valid max PWM value in
one of the PWM_CTL regs and it can only get zeroed due to suspend, which
isn't a problem after patch 4. With this:

Reviewed-by: Imre Deak <imre.deak@intel.com>

>  
>  	if (i915_panel_invert_brightness < 0)
>  		return val;
>  
>  	if (i915_panel_invert_brightness > 0 ||
>  	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
> -		u32 max = intel_panel_get_max_backlight(connector);
> -		if (max)
> -			return max - val;
> +		return panel->backlight.max - val;
>  	}
>  
>  	return val;
> @@ -555,17 +553,15 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	u32 tmp, mask;
>  
> +	WARN_ON(panel->backlight.max == 0);
> +
>  	if (is_backlight_combination_mode(dev)) {
> -		u32 max = intel_panel_get_max_backlight(connector);
>  		u8 lbpc;
>  
> -		/* we're screwed, but keep behaviour backwards compatible */
> -		if (!max)
> -			max = 1;
> -
> -		lbpc = level * 0xfe / max + 1;
> +		lbpc = level * 0xfe / panel->backlight.max + 1;
>  		level /= lbpc;
>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
>  	}
> @@ -620,13 +616,10 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
> -	freq = intel_panel_get_max_backlight(connector);
> -	if (!freq) {
> -		/* we are screwed, bail out */
> -		goto out;
> -	}
> +	WARN_ON(panel->backlight.max == 0);
>  
> -	/* scale to hardware, but be careful to not overflow */
> +	/* scale to hardware max, but be careful to not overflow */
> +	freq = panel->backlight.max;
>  	if (freq < max)
>  		level = level * freq / max;
>  	else
> @@ -638,7 +631,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>  
>  	if (panel->backlight.enabled)
>  		intel_panel_actually_set_backlight(connector, level);
> -out:
> +
>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>  }
>  
> @@ -839,8 +832,13 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>  
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
> +	/* XXX: transitional, call to make sure freq is set */
> +	intel_panel_get_max_backlight(connector);
> +
> +	WARN_ON(panel->backlight.max == 0);
> +
>  	if (panel->backlight.level == 0) {
> -		panel->backlight.level = intel_panel_get_max_backlight(connector);
> +		panel->backlight.level = panel->backlight.max;
>  		if (panel->backlight.device)
>  			panel->backlight.device->props.brightness =
>  				panel->backlight.level;
> @@ -960,7 +958,12 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
>  }
>  #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
>  
> -/* Note: The setup hooks can't assume pipe is set! */
> +/*
> + * Note: The setup hooks can't assume pipe is set!
> + *
> + * XXX: Query mode clock or hardware clock and program PWM modulation frequency
> + * appropriately when it's 0. Use VBT and/or sane defaults.
> + */
>  static int pch_setup_backlight(struct intel_connector *connector)
>  {
>  	struct intel_panel *panel = &connector->panel;

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 09/13] drm/i915: debug print on backlight register
  2013-11-08 14:49 ` [PATCH 09/13] drm/i915: debug print on backlight register Jani Nikula
@ 2013-11-12 22:48   ` Imre Deak
  2013-11-13 10:22     ` Daniel Vetter
  0 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-12 22:48 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_panel.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 9a55b36..3dd9f57d 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -1065,6 +1065,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
>  
>  	panel->backlight.present = true;
>  
> +	DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
> +		      "sysfs interface %sregistered\n",
> +		      panel->backlight.enabled ? "enabled" : "disabled",
> +		      panel->backlight.level, panel->backlight.max,
> +		      panel->backlight.device ? "" : "not ");
> +
>  	return 0;
>  }
>  

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 04/13] drm/i915: handle backlight through chip specific functions
  2013-11-12 21:36   ` Imre Deak
@ 2013-11-12 23:19     ` Daniel Vetter
  0 siblings, 0 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-12 23:19 UTC (permalink / raw)
  To: Imre Deak; +Cc: Jani Nikula, intel-gfx

On Tue, Nov 12, 2013 at 11:36:57PM +0200, Imre Deak wrote:
> On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> > The backlight code has grown rather hairy, not least because the
> > hardware registers and bits have repeatedly been shuffled around. And
> > this isn't expected to get any easier with new hardware. Make things
> > easier for our (read: my) poor brains, and split the code up into chip
> > specific functions.
> > 
> > There should be no functional changes.
> > 
> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> 
> This was rather difficult to read. Perhaps breaking it to per-callback
> refactoring patches would've been feasible and easier to review, but
> looks anyway good to me:
> 
> Reviewed-by: Imre Deak <imre.deak@intel.com> 

Ok, this will be fun to merge. I've slurped in the patches up to this one
into a new backlight-rework topic branch. Plan is to merge everything in
there, then merge in the bdw stuff and then pull that into dinq. I've
started with the merge resolve already, but probably only worth to test it
at the end.
-Daniel

> 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h      |    9 +
> >  drivers/gpu/drm/i915/intel_display.c |    2 +
> >  drivers/gpu/drm/i915/intel_drv.h     |    2 +
> >  drivers/gpu/drm/i915/intel_panel.c   |  642 +++++++++++++++++++++++-----------
> >  4 files changed, 447 insertions(+), 208 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 0517d47..2d70ae4 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -351,6 +351,7 @@ struct drm_i915_error_state {
> >  	enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
> >  };
> >  
> > +struct intel_connector;
> >  struct intel_crtc_config;
> >  struct intel_crtc;
> >  struct intel_limit;
> > @@ -413,6 +414,14 @@ struct drm_i915_display_funcs {
> >  	/* render clock increase/decrease */
> >  	/* display clock increase/decrease */
> >  	/* pll clock increase/decrease */
> > +
> > +	int (*setup_backlight)(struct intel_connector *connector);
> > +	uint32_t (*get_max_backlight)(struct intel_connector *connector);
> > +	uint32_t (*get_backlight)(struct intel_connector *connector);
> > +	void (*set_backlight)(struct intel_connector *connector,
> > +			      uint32_t level);
> > +	void (*disable_backlight)(struct intel_connector *connector);
> > +	void (*enable_backlight)(struct intel_connector *connector);
> >  };
> >  
> >  struct intel_uncore_funcs {
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 30d3993..b6533f8 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10604,6 +10604,8 @@ static void intel_init_display(struct drm_device *dev)
> >  		dev_priv->display.queue_flip = intel_gen7_queue_flip;
> >  		break;
> >  	}
> > +
> > +	intel_panel_init_backlight_funcs(dev);
> >  }
> >  
> >  /*
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 68bec63..7384a7b 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -161,6 +161,7 @@ struct intel_panel {
> >  	struct {
> >  		bool present;
> >  		u32 level;
> > +		u32 max;
> >  		bool enabled;
> >  		struct backlight_device *device;
> >  	} backlight;
> > @@ -817,6 +818,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector);
> >  void intel_panel_enable_backlight(struct intel_connector *connector);
> >  void intel_panel_disable_backlight(struct intel_connector *connector);
> >  void intel_panel_destroy_backlight(struct drm_connector *connector);
> > +void intel_panel_init_backlight_funcs(struct drm_device *dev);
> >  enum drm_connector_status intel_panel_detect(struct drm_device *dev);
> >  
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> > index c80bffc..a821949 100644
> > --- a/drivers/gpu/drm/i915/intel_panel.c
> > +++ b/drivers/gpu/drm/i915/intel_panel.c
> > @@ -338,79 +338,117 @@ static int is_backlight_combination_mode(struct drm_device *dev)
> >  	return 0;
> >  }
> >  
> > -/* 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, enum pipe pipe)
> > +static u32 pch_get_max_backlight(struct intel_connector *connector)
> >  {
> > +	struct drm_device *dev = connector->base.dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	u32 val;
> >  
> > -	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
> > +	val = I915_READ(BLC_PWM_PCH_CTL2);
> > +	if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
> > +		dev_priv->regfile.saveBLC_PWM_CTL2 = val;
> > +	} else if (val == 0) {
> > +		val = dev_priv->regfile.saveBLC_PWM_CTL2;
> > +		I915_WRITE(BLC_PWM_PCH_CTL2, val);
> > +	}
> >  
> > -	/* Restore the CTL value if it lost, e.g. GPU reset */
> > +	val >>= 16;
> >  
> > -	if (HAS_PCH_SPLIT(dev_priv->dev)) {
> > -		val = I915_READ(BLC_PWM_PCH_CTL2);
> > -		if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
> > -			dev_priv->regfile.saveBLC_PWM_CTL2 = val;
> > -		} else if (val == 0) {
> > -			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);
> > -		}
> > +	return val;
> > +}
> >  
> > -		if (!val)
> > -			val = 0x0f42ffff;
> > -	} else {
> > -		val = I915_READ(BLC_PWM_CTL);
> > -		if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> > -			dev_priv->regfile.saveBLC_PWM_CTL = val;
> > -			if (INTEL_INFO(dev)->gen >= 4)
> > -				dev_priv->regfile.saveBLC_PWM_CTL2 =
> > -					I915_READ(BLC_PWM_CTL2);
> > -		} else if (val == 0) {
> > -			val = dev_priv->regfile.saveBLC_PWM_CTL;
> > -			I915_WRITE(BLC_PWM_CTL, val);
> > -			if (INTEL_INFO(dev)->gen >= 4)
> > -				I915_WRITE(BLC_PWM_CTL2,
> > -					   dev_priv->regfile.saveBLC_PWM_CTL2);
> > -		}
> > +static u32 i9xx_get_max_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 val;
> > +
> > +	val = I915_READ(BLC_PWM_CTL);
> > +	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> > +		dev_priv->regfile.saveBLC_PWM_CTL = val;
> > +	} else if (val == 0) {
> > +		val = dev_priv->regfile.saveBLC_PWM_CTL;
> > +		I915_WRITE(BLC_PWM_CTL, val);
> >  	}
> >  
> > +	val >>= 17;
> > +
> > +	if (is_backlight_combination_mode(dev))
> > +		val *= 0xff;
> > +
> >  	return val;
> >  }
> >  
> > -static u32 intel_panel_get_max_backlight(struct drm_device *dev,
> > -					 enum pipe pipe)
> > +static u32 i965_get_max_backlight(struct intel_connector *connector)
> >  {
> > -	u32 max;
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 val;
> > +
> > +	val = I915_READ(BLC_PWM_CTL);
> > +	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> > +		dev_priv->regfile.saveBLC_PWM_CTL = val;
> > +		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
> > +	} else if (val == 0) {
> > +		val = dev_priv->regfile.saveBLC_PWM_CTL;
> > +		I915_WRITE(BLC_PWM_CTL, val);
> > +		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> > +	}
> >  
> > -	max = i915_read_blc_pwm_ctl(dev, pipe);
> > +	val >>= 16;
> >  
> > -	if (HAS_PCH_SPLIT(dev)) {
> > -		max >>= 16;
> > -	} else {
> > -		if (INTEL_INFO(dev)->gen < 4)
> > -			max >>= 17;
> > -		else
> > -			max >>= 16;
> > +	if (is_backlight_combination_mode(dev))
> > +		val *= 0xff;
> > +
> > +	return val;
> > +}
> > +
> > +static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe)
> > +{
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 val;
> >  
> > -		if (is_backlight_combination_mode(dev))
> > -			max *= 0xff;
> > +	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;
> > +
> > +	val >>= 16;
> > +
> > +	return val;
> > +}
> > +
> > +static u32 vlv_get_max_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	enum pipe pipe = intel_get_pipe_from_connector(connector);
> > +
> > +	return _vlv_get_max_backlight(dev, pipe);
> > +}
> > +
> > +/* XXX: query mode clock or hardware clock and program max PWM appropriately
> > + * when it's 0.
> > + */
> > +static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 max;
> > +
> > +	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
> > +
> > +	max = dev_priv->display.get_max_backlight(connector);
> > +
> >  	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
> >  
> >  	return max;
> > @@ -423,9 +461,10 @@ 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,
> > -					  enum pipe pipe, u32 val)
> > +static u32 intel_panel_compute_brightness(struct intel_connector *connector,
> > +					  u32 val)
> >  {
> > +	struct drm_device *dev = connector->base.dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  
> >  	if (i915_panel_invert_brightness < 0)
> > @@ -433,7 +472,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
> >  
> >  	if (i915_panel_invert_brightness > 0 ||
> >  	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
> > -		u32 max = intel_panel_get_max_backlight(dev, pipe);
> > +		u32 max = intel_panel_get_max_backlight(connector);
> >  		if (max)
> >  			return max - val;
> >  	}
> > @@ -441,37 +480,60 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev,
> >  	return val;
> >  }
> >  
> > -static u32 intel_panel_get_backlight(struct drm_device *dev,
> > -				     enum pipe pipe)
> > +static u32 pch_get_backlight(struct intel_connector *connector)
> >  {
> > +	struct drm_device *dev = connector->base.dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	u32 val;
> > -	unsigned long flags;
> > -	int reg;
> >  
> > -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> > +	return I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> > +}
> >  
> > -	if (HAS_PCH_SPLIT(dev)) {
> > -		val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> > -	} else {
> > -		if (IS_VALLEYVIEW(dev))
> > -			reg = VLV_BLC_PWM_CTL(pipe);
> > -		else
> > -			reg = BLC_PWM_CTL;
> > +static u32 i9xx_get_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 val;
> >  
> > -		val = I915_READ(reg) & BACKLIGHT_DUTY_CYCLE_MASK;
> > -		if (INTEL_INFO(dev)->gen < 4)
> > -			val >>= 1;
> > +	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> > +	if (INTEL_INFO(dev)->gen < 4)
> > +		val >>= 1;
> >  
> > -		if (is_backlight_combination_mode(dev)) {
> > -			u8 lbpc;
> > +	if (is_backlight_combination_mode(dev)) {
> > +		u8 lbpc;
> >  
> > -			pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
> > -			val *= lbpc;
> > -		}
> > +		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
> > +		val *= lbpc;
> >  	}
> >  
> > -	val = intel_panel_compute_brightness(dev, pipe, val);
> > +	return val;
> > +}
> > +
> > +static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe)
> > +{
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +
> > +	return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK;
> > +}
> > +
> > +static u32 vlv_get_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	enum pipe pipe = intel_get_pipe_from_connector(connector);
> > +
> > +	return _vlv_get_backlight(dev, pipe);
> > +}
> > +
> > +static u32 intel_panel_get_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 val;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> > +
> > +	val = dev_priv->display.get_backlight(connector);
> > +	val = intel_panel_compute_brightness(connector, val);
> >  
> >  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> >  
> > @@ -479,28 +541,24 @@ static u32 intel_panel_get_backlight(struct drm_device *dev,
> >  	return val;
> >  }
> >  
> > -static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level)
> > +static void pch_set_backlight(struct intel_connector *connector, u32 level)
> >  {
> > +	struct drm_device *dev = connector->base.dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	u32 val = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> > -	I915_WRITE(BLC_PWM_CPU_CTL, val | level);
> > +	u32 tmp;
> > +
> > +	tmp = I915_READ(BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> > +	I915_WRITE(BLC_PWM_CPU_CTL, tmp | level);
> >  }
> >  
> > -static void intel_panel_actually_set_backlight(struct drm_device *dev,
> > -					       enum pipe pipe, u32 level)
> > +static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
> >  {
> > +	struct drm_device *dev = connector->base.dev;
> >  	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, 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, pipe);
> > +		u32 max = intel_panel_get_max_backlight(connector);
> >  		u8 lbpc;
> >  
> >  		/* we're screwed, but keep behaviour backwards compatible */
> > @@ -512,16 +570,34 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev,
> >  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
> >  	}
> >  
> > -	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(reg, tmp | level);
> > +
> > +	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> > +	I915_WRITE(BLC_PWM_CTL, tmp | level);
> > +}
> > +
> > +static void vlv_set_backlight(struct intel_connector *connector, u32 level)
> > +{
> > +	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 tmp;
> > +
> > +	tmp = I915_READ(VLV_BLC_PWM_CTL(pipe)) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> > +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level);
> > +}
> > +
> > +static void
> > +intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +
> > +	DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level);
> > +
> > +	level = intel_panel_compute_brightness(connector, level);
> > +	dev_priv->display.set_backlight(connector, level);
> >  }
> >  
> >  /* set backlight brightness to level in range [0..max] */
> > @@ -540,7 +616,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
> >  
> >  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> >  
> > -	freq = intel_panel_get_max_backlight(dev, pipe);
> > +	freq = intel_panel_get_max_backlight(connector);
> >  	if (!freq) {
> >  		/* we are screwed, bail out */
> >  		goto out;
> > @@ -557,11 +633,45 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
> >  		panel->backlight.device->props.brightness = level;
> >  
> >  	if (panel->backlight.enabled)
> > -		intel_panel_actually_set_backlight(dev, pipe, level);
> > +		intel_panel_actually_set_backlight(connector, level);
> >  out:
> >  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> >  }
> >  
> > +static void pch_disable_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 tmp;
> > +
> > +	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> > +	I915_WRITE(BLC_PWM_CPU_CTL2, tmp & ~BLM_PWM_ENABLE);
> > +
> > +	tmp = I915_READ(BLC_PWM_PCH_CTL1);
> > +	I915_WRITE(BLC_PWM_PCH_CTL1, tmp & ~BLM_PCH_PWM_ENABLE);
> > +}
> > +
> > +static void i965_disable_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	u32 tmp;
> > +
> > +	tmp = I915_READ(BLC_PWM_CTL2);
> > +	I915_WRITE(BLC_PWM_CTL2, tmp & ~BLM_PWM_ENABLE);
> > +}
> > +
> > +static void vlv_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);
> > +	u32 tmp;
> > +
> > +	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> > +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE);
> > +}
> > +
> >  void intel_panel_disable_backlight(struct intel_connector *connector)
> >  {
> >  	struct drm_device *dev = connector->base.dev;
> > @@ -587,28 +697,100 @@ void intel_panel_disable_backlight(struct intel_connector *connector)
> >  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> >  
> >  	panel->backlight.enabled = false;
> > -	intel_panel_actually_set_backlight(dev, pipe, 0);
> > +	intel_panel_actually_set_backlight(connector, 0);
> >  
> > -	if (INTEL_INFO(dev)->gen >= 4) {
> > -		uint32_t reg, tmp;
> > +	if (dev_priv->display.disable_backlight)
> > +		dev_priv->display.disable_backlight(connector);
> >  
> > -		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;
> > +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> > +}
> >  
> > -		I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
> > +static void pch_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);
> > +	u32 tmp;
> >  
> > -		if (HAS_PCH_SPLIT(dev)) {
> > -			tmp = I915_READ(BLC_PWM_PCH_CTL1);
> > -			tmp &= ~BLM_PCH_PWM_ENABLE;
> > -			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> > -		}
> > +	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> > +
> > +	/* Note that this can also get called through dpms changes. And
> > +	 * we don't track the backlight dpms state, hence check whether
> > +	 * we have to do anything first. */
> > +	if (tmp & BLM_PWM_ENABLE)
> > +		return;
> > +
> > +	if (INTEL_INFO(dev)->num_pipes == 3)
> > +		tmp &= ~BLM_PIPE_SELECT_IVB;
> > +	else
> > +		tmp &= ~BLM_PIPE_SELECT;
> > +
> > +	if (cpu_transcoder == TRANSCODER_EDP)
> > +		tmp |= BLM_TRANSCODER_EDP;
> > +	else
> > +		tmp |= BLM_PIPE(cpu_transcoder);
> > +	tmp &= ~BLM_PWM_ENABLE;
> > +
> > +	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
> > +	POSTING_READ(BLC_PWM_CPU_CTL2);
> > +	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
> > +
> > +	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> > +		tmp = I915_READ(BLC_PWM_PCH_CTL1);
> > +		tmp |= BLM_PCH_PWM_ENABLE;
> > +		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> > +		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> >  	}
> > +}
> >  
> > -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> > +static void i965_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);
> > +	u32 tmp;
> > +
> > +	tmp = I915_READ(BLC_PWM_CTL2);
> > +
> > +	/* Note that this can also get called through dpms changes. And
> > +	 * we don't track the backlight dpms state, hence check whether
> > +	 * we have to do anything first. */
> > +	if (tmp & BLM_PWM_ENABLE)
> > +		return;
> > +
> > +	tmp &= ~BLM_PIPE_SELECT;
> > +	tmp |= BLM_PIPE(pipe);
> > +	tmp &= ~BLM_PWM_ENABLE;
> > +
> > +	I915_WRITE(BLC_PWM_CTL2, tmp);
> > +	POSTING_READ(BLC_PWM_CTL2);
> > +	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> > +}
> > +
> > +static void vlv_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);
> > +	u32 tmp;
> > +
> > +	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> > +
> > +	/* Note that this can also get called through dpms changes. And
> > +	 * we don't track the backlight dpms state, hence check whether
> > +	 * we have to do anything first. */
> > +	if (tmp & BLM_PWM_ENABLE)
> > +		return;
> > +
> > +	tmp &= ~BLM_PIPE_SELECT;
> > +	tmp |= BLM_PIPE(pipe);
> > +	tmp &= ~BLM_PWM_ENABLE;
> > +
> > +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
> > +	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
> > +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
> >  }
> >  
> >  void intel_panel_enable_backlight(struct intel_connector *connector)
> > @@ -617,8 +799,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct intel_panel *panel = &connector->panel;
> >  	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)
> > @@ -629,89 +809,25 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
> >  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> >  
> >  	if (panel->backlight.level == 0) {
> > -		panel->backlight.level = intel_panel_get_max_backlight(dev,
> > -								       pipe);
> > +		panel->backlight.level = intel_panel_get_max_backlight(connector);
> >  		if (panel->backlight.device)
> >  			panel->backlight.device->props.brightness =
> >  				panel->backlight.level;
> >  	}
> >  
> > -	if (INTEL_INFO(dev)->gen >= 4) {
> > -		uint32_t reg, tmp;
> > -
> > -		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);
> > -
> > -		/* Note that this can also get called through dpms changes. And
> > -		 * we don't track the backlight dpms state, hence check whether
> > -		 * we have to do anything first. */
> > -		if (tmp & BLM_PWM_ENABLE)
> > -			goto set_level;
> > -
> > -		if (INTEL_INFO(dev)->num_pipes == 3)
> > -			tmp &= ~BLM_PIPE_SELECT_IVB;
> > -		else
> > -			tmp &= ~BLM_PIPE_SELECT;
> > -
> > -		if (cpu_transcoder == TRANSCODER_EDP)
> > -			tmp |= BLM_TRANSCODER_EDP;
> > -		else
> > -			tmp |= BLM_PIPE(cpu_transcoder);
> > -		tmp &= ~BLM_PWM_ENABLE;
> > -
> > -		I915_WRITE(reg, tmp);
> > -		POSTING_READ(reg);
> > -		I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
> > -
> > -		if (HAS_PCH_SPLIT(dev) &&
> > -		    !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> > -			tmp = I915_READ(BLC_PWM_PCH_CTL1);
> > -			tmp |= BLM_PCH_PWM_ENABLE;
> > -			tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> > -			I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> > -		}
> > -	}
> > +	if (dev_priv->display.enable_backlight)
> > +		dev_priv->display.enable_backlight(connector);
> >  
> > -set_level:
> >  	/* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> >  	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> >  	 * registers are set.
> >  	 */
> >  	panel->backlight.enabled = true;
> > -	intel_panel_actually_set_backlight(dev, pipe,
> > -					   panel->backlight.level);
> > +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >  
> >  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> >  }
> >  
> > -/* FIXME: use VBT vals to init PWM_CTL and PWM_CTL2 correctly */
> > -static void intel_panel_init_backlight_regs(struct drm_device *dev)
> > -{
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > -
> > -	if (IS_VALLEYVIEW(dev)) {
> > -		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);
> > -		}
> > -	}
> > -}
> > -
> >  enum drm_connector_status
> >  intel_panel_detect(struct drm_device *dev)
> >  {
> > @@ -753,15 +869,13 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd)
> >  {
> >  	struct intel_connector *connector = bl_get_data(bd);
> >  	struct drm_device *dev = connector->base.dev;
> > -	enum pipe pipe;
> > +	int ret;
> >  
> >  	mutex_lock(&dev->mode_config.mutex);
> > -	pipe = intel_get_pipe_from_connector(connector);
> > +	ret = intel_panel_get_backlight(connector);
> >  	mutex_unlock(&dev->mode_config.mutex);
> > -	if (pipe == INVALID_PIPE)
> > -		return 0;
> >  
> > -	return intel_panel_get_backlight(connector->base.dev, pipe);
> > +	return ret;
> >  }
> >  
> >  static const struct backlight_ops intel_backlight_device_ops = {
> > @@ -771,27 +885,18 @@ static const struct backlight_ops intel_backlight_device_ops = {
> >  
> >  static int intel_backlight_device_register(struct intel_connector *connector)
> >  {
> > -	struct drm_device *dev = connector->base.dev;
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct intel_panel *panel = &connector->panel;
> >  	struct backlight_properties props;
> > -	unsigned long flags;
> >  
> >  	if (WARN_ON(panel->backlight.device))
> >  		return -ENODEV;
> >  
> > +	BUG_ON(panel->backlight.max == 0);
> > +
> >  	memset(&props, 0, sizeof(props));
> >  	props.type = BACKLIGHT_RAW;
> >  	props.brightness = panel->backlight.level;
> > -
> > -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> > -	props.max_brightness = intel_panel_get_max_backlight(dev, 0);
> > -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> > -
> > -	if (props.max_brightness == 0) {
> > -		DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
> > -		return -ENODEV;
> > -	}
> > +	props.max_brightness = panel->backlight.max;
> >  
> >  	/*
> >  	 * Note: using the same name independent of the connector prevents
> > @@ -831,15 +936,102 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
> >  }
> >  #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
> >  
> > +/* Note: The setup hooks can't assume pipe is set! */
> > +static int pch_setup_backlight(struct intel_connector *connector)
> > +{
> > +	struct intel_panel *panel = &connector->panel;
> > +	u32 val;
> > +
> > +	panel->backlight.max = pch_get_max_backlight(connector);
> > +	if (!panel->backlight.max)
> > +		return -ENODEV;
> > +
> > +	val = pch_get_backlight(connector);
> > +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> > +
> > +	return 0;
> > +}
> > +
> > +static int i9xx_setup_backlight(struct intel_connector *connector)
> > +{
> > +	struct intel_panel *panel = &connector->panel;
> > +	u32 val;
> > +
> > +	panel->backlight.max = i9xx_get_max_backlight(connector);
> > +	if (!panel->backlight.max)
> > +		return -ENODEV;
> > +
> > +	val = i9xx_get_backlight(connector);
> > +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> > +
> > +	return 0;
> > +}
> > +
> > +static int i965_setup_backlight(struct intel_connector *connector)
> > +{
> > +	struct intel_panel *panel = &connector->panel;
> > +	u32 val;
> > +
> > +	panel->backlight.max = i965_get_max_backlight(connector);
> > +	if (!panel->backlight.max)
> > +		return -ENODEV;
> > +
> > +	val = i9xx_get_backlight(connector);
> > +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> > +
> > +	return 0;
> > +}
> > +
> > +static int vlv_setup_backlight(struct intel_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->base.dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +	struct intel_panel *panel = &connector->panel;
> > +	enum pipe pipe;
> > +	u32 val;
> > +
> > +	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);
> > +	}
> > +
> > +	panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A);
> > +	if (!panel->backlight.max)
> > +		return -ENODEV;
> > +
> > +	val = _vlv_get_backlight(dev, PIPE_A);
> > +	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> > +
> > +	return 0;
> > +}
> > +
> >  int intel_panel_setup_backlight(struct drm_connector *connector)
> >  {
> >  	struct drm_device *dev = connector->dev;
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct intel_connector *intel_connector = to_intel_connector(connector);
> >  	struct intel_panel *panel = &intel_connector->panel;
> > +	unsigned long flags;
> > +	int ret;
> >  
> > -	intel_panel_init_backlight_regs(dev);
> > +	/* set level and max in panel struct */
> > +	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> > +	ret = dev_priv->display.setup_backlight(intel_connector);
> > +	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> > +
> > +	if (ret) {
> > +		DRM_DEBUG_KMS("failed to setup backlight for connector %s\n",
> > +			      drm_get_connector_name(connector));
> > +		return ret;
> > +	}
> >  
> > -	panel->backlight.level = intel_panel_get_backlight(dev, 0);
> >  	panel->backlight.enabled = panel->backlight.level != 0;
> >  
> >  	intel_backlight_device_register(intel_connector);
> > @@ -858,6 +1050,40 @@ void intel_panel_destroy_backlight(struct drm_connector *connector)
> >  	intel_backlight_device_unregister(intel_connector);
> >  }
> >  
> > +/* Set up chip specific backlight functions */
> > +void intel_panel_init_backlight_funcs(struct drm_device *dev)
> > +{
> > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > +
> > +	if (HAS_PCH_SPLIT(dev)) {
> > +		dev_priv->display.setup_backlight = pch_setup_backlight;
> > +		dev_priv->display.enable_backlight = pch_enable_backlight;
> > +		dev_priv->display.disable_backlight = pch_disable_backlight;
> > +		dev_priv->display.set_backlight = pch_set_backlight;
> > +		dev_priv->display.get_backlight = pch_get_backlight;
> > +		dev_priv->display.get_max_backlight = pch_get_max_backlight;
> > +	} else if (IS_VALLEYVIEW(dev)) {
> > +		dev_priv->display.setup_backlight = vlv_setup_backlight;
> > +		dev_priv->display.enable_backlight = vlv_enable_backlight;
> > +		dev_priv->display.disable_backlight = vlv_disable_backlight;
> > +		dev_priv->display.set_backlight = vlv_set_backlight;
> > +		dev_priv->display.get_backlight = vlv_get_backlight;
> > +		dev_priv->display.get_max_backlight = vlv_get_max_backlight;
> > +	} else if (IS_GEN4(dev)) {
> > +		dev_priv->display.setup_backlight = i965_setup_backlight;
> > +		dev_priv->display.enable_backlight = i965_enable_backlight;
> > +		dev_priv->display.disable_backlight = i965_disable_backlight;
> > +		dev_priv->display.set_backlight = i9xx_set_backlight;
> > +		dev_priv->display.get_backlight = i9xx_get_backlight;
> > +		dev_priv->display.get_max_backlight = i965_get_max_backlight;
> > +	} else {
> > +		dev_priv->display.setup_backlight = i9xx_setup_backlight;
> > +		dev_priv->display.set_backlight = i9xx_set_backlight;
> > +		dev_priv->display.get_backlight = i9xx_get_backlight;
> > +		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
> > +	}
> > +}
> > +
> >  int intel_panel_init(struct intel_panel *panel,
> >  		     struct drm_display_mode *fixed_mode)
> >  {
> 
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 13/13] drm/i915: do not save/restore backlight registers
  2013-11-08 14:49 ` [PATCH 13/13] drm/i915: do not save/restore backlight registers Jani Nikula
@ 2013-11-12 23:25   ` Daniel Vetter
  2013-11-13  8:40     ` Jani Nikula
  2013-11-13 10:56     ` [PATCH v2] drm/i915: do not save/restore backlight registers in KMS Jani Nikula
  0 siblings, 2 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-12 23:25 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Fri, Nov 08, 2013 at 04:49:05PM +0200, Jani Nikula wrote:
> The backlight enable code now has the smarts to do the right thing.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

You can't just kill this due to ums code, instead it needs to be protected
by if (!DRIVER_MODESET) checks.
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h     |    6 -----
>  drivers/gpu/drm/i915/i915_suspend.c |   45 -----------------------------------
>  2 files changed, 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 500bab3..6fec21e 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -766,13 +766,7 @@ struct i915_suspend_saved_registers {
>  	u32 saveDSPATILEOFF;
>  	u32 savePFIT_PGM_RATIOS;
>  	u32 saveBLC_HIST_CTL;
> -	u32 saveBLC_PWM_CTL;
> -	u32 saveBLC_PWM_CTL2;
>  	u32 saveBLC_HIST_CTL_B;
> -	u32 saveBLC_PWM_CTL_B;
> -	u32 saveBLC_PWM_CTL2_B;
> -	u32 saveBLC_CPU_PWM_CTL;
> -	u32 saveBLC_CPU_PWM_CTL2;
>  	u32 saveFPB0;
>  	u32 saveFPB1;
>  	u32 saveDPLL_B;
> diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
> index eadf8e1..6b8fef7 100644
> --- a/drivers/gpu/drm/i915/i915_suspend.c
> +++ b/drivers/gpu/drm/i915/i915_suspend.c
> @@ -192,7 +192,6 @@ static void i915_restore_vga(struct drm_device *dev)
>  static void i915_save_display(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned long flags;
>  
>  	/* Display arbitration control */
>  	if (INTEL_INFO(dev)->gen <= 4)
> @@ -203,46 +202,27 @@ static void i915_save_display(struct drm_device *dev)
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		i915_save_display_reg(dev);
>  
> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> -
>  	/* LVDS state */
>  	if (HAS_PCH_SPLIT(dev)) {
>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
> -		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
> -		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
> -		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
> -		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
>  		if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
>  			dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
>  		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
>  
> -		dev_priv->regfile.saveBLC_PWM_CTL =
> -			I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
>  		dev_priv->regfile.saveBLC_HIST_CTL =
>  			I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
> -		dev_priv->regfile.saveBLC_PWM_CTL2 =
> -			I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
> -		dev_priv->regfile.saveBLC_PWM_CTL_B =
> -			I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
>  		dev_priv->regfile.saveBLC_HIST_CTL_B =
>  			I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
> -		dev_priv->regfile.saveBLC_PWM_CTL2_B =
> -			I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
>  	} else {
>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
>  		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
> -		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
>  		dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
> -		if (INTEL_INFO(dev)->gen >= 4)
> -			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
>  		if (IS_MOBILE(dev) && !IS_I830(dev))
>  			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> -
>  	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
>  		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
>  
> @@ -278,7 +258,6 @@ static void i915_restore_display(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 mask = 0xffffffff;
> -	unsigned long flags;
>  
>  	/* Display arbitration */
>  	if (INTEL_INFO(dev)->gen <= 4)
> @@ -287,12 +266,6 @@ static void i915_restore_display(struct drm_device *dev)
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		i915_restore_display_reg(dev);
>  
> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> -
> -	/* LVDS state */
> -	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
> -		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> -
>  	if (drm_core_check_feature(dev, DRIVER_MODESET))
>  		mask = ~LVDS_PORT_EN;
>  
> @@ -305,13 +278,6 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL);
>  
>  	if (HAS_PCH_SPLIT(dev)) {
> -		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
> -		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> -		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
> -		 * otherwise we get blank eDP screen after S3 on some machines
> -		 */
> -		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
> -		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
>  		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
>  		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
>  		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
> @@ -319,21 +285,12 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(RSTDBYCTL,
>  			   dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
>  	} else if (IS_VALLEYVIEW(dev)) {
> -		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
> -			   dev_priv->regfile.saveBLC_PWM_CTL);
>  		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
>  			   dev_priv->regfile.saveBLC_HIST_CTL);
> -		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
> -			   dev_priv->regfile.saveBLC_PWM_CTL2);
> -		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
> -			   dev_priv->regfile.saveBLC_PWM_CTL);
>  		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
>  			   dev_priv->regfile.saveBLC_HIST_CTL);
> -		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
> -			   dev_priv->regfile.saveBLC_PWM_CTL2);
>  	} else {
>  		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
> -		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
>  		I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL);
>  		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
>  		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
> @@ -341,8 +298,6 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> -
>  	/* only restore FBC info on the platform that supports FBC*/
>  	intel_disable_fbc(dev);
>  	if (I915_HAS_FBC(dev)) {
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set
  2013-11-12 22:00   ` Imre Deak
@ 2013-11-13  8:27     ` Jani Nikula
  2013-11-13  9:04       ` Daniel Vetter
  2013-11-13  9:12       ` Imre Deak
  0 siblings, 2 replies; 49+ messages in thread
From: Jani Nikula @ 2013-11-13  8:27 UTC (permalink / raw)
  To: imre.deak; +Cc: intel-gfx

On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_panel.c |   10 +++++++---
>>  1 file changed, 7 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
>> index a821949..e82b2dd 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -555,7 +555,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>>  {
>>  	struct drm_device *dev = connector->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	u32 tmp;
>> +	u32 tmp, mask;
>>  
>>  	if (is_backlight_combination_mode(dev)) {
>>  		u32 max = intel_panel_get_max_backlight(connector);
>> @@ -570,10 +570,14 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
>>  	}
>>  
>> -	if (INTEL_INFO(dev)->gen < 4)
>> +	if (IS_GEN4(dev)) {
>> +		mask = BACKLIGHT_DUTY_CYCLE_MASK;
>> +	} else {
>>  		level <<= 1;
>> +		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
>> +	}
>
> According to the gen2/3 bspec I have, the correct mask is
> BACKLIGHT_DUTY_CYCLE_MASK_PNV only in case of IS_PINEVIEW(dev), for
> everything else it's BACKLIGHT_DUTY_CYCLE_MASK.

What you say is correct, but we've treated all gen2/3 similar to PNV
since

commit ca88479c1c3b7b1a9f94320745f5331e1de77f80
Author: Keith Packard <keithp@keithp.com>
Date:   Fri Nov 18 11:09:24 2011 -0800

    drm/i915: Treat pre-gen4 backlight duty cycle value consistently

i.e. we only use the high 15 bits for all gen2/3. For non-PNV this just
means the lowest bit is always zero. For PNV the lowest bit has a
different meaning in both the PWM freq and duty cycle fields.

I don't want to take any chances by changing this behaviour. I realize
there's zero comments about this in the code; would you like me to add
some?


BR,
Jani.


>
> --Imre
>
>>  
>> -	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
>> +	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
>>  	I915_WRITE(BLC_PWM_CTL, tmp | level);
>>  }
>>  
>
>

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it
  2013-11-12 22:42   ` Imre Deak
@ 2013-11-13  8:39     ` Jani Nikula
  2013-11-13  9:12       ` Daniel Vetter
  0 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-13  8:39 UTC (permalink / raw)
  To: imre.deak; +Cc: intel-gfx

On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
>> We now have the max backlight value cached. Use it.
>> 
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_panel.c |   45 +++++++++++++++++++-----------------
>>  1 file changed, 24 insertions(+), 21 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
>> index ed6b1ec..9a55b36 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -436,9 +436,6 @@ static u32 vlv_get_max_backlight(struct intel_connector *connector)
>>  	return _vlv_get_max_backlight(dev, pipe);
>>  }
>>  
>> -/* XXX: query mode clock or hardware clock and program max PWM appropriately
>> - * when it's 0.
>> - */
>>  static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
>>  {
>>  	struct drm_device *dev = connector->base.dev;
>> @@ -466,15 +463,16 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
>>  {
>>  	struct drm_device *dev = connector->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct intel_panel *panel = &connector->panel;
>> +
>> +	WARN_ON(panel->backlight.max == 0);
>
> Just to clarify that I understood this: we can't hit this any more since
> setup_backlight returns now -ENODEV if backlight.max == 0 and so we
> won't register the backlight device in that case. I assume then that
> during booting the BIOS always leaves us with a valid max PWM value in
> one of the PWM_CTL regs and it can only get zeroed due to suspend, which
> isn't a problem after patch 4. With this:

You've correctly understood what I meant. I do hope what I meant is the
right thing to do! ;)

Now that I think about it, there are hints that (at least on some
platforms) a GPU reset might cause the registers to be reset too:

commit 0b0b053a3949f5c467c3b3ba135d4c161f9fbd00
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Tue Nov 23 09:45:50 2010 +0000

    drm/i915/panel: Restore saved value of BLC_PWM_CTL

The big question is, are we okay with re-writing the potentially zeroed
out registers at crtc enable time? The current upstream code would do
that at reading the max backlight level, which happens also at adjusting
the backlight. But there are no guarantees about anyone adjusting the
backlight either.

I don't understand our GPU reset enough to say for sure, but my gut
feeling is that what I have in this series should be enough.

BR,
Jani.

>
> Reviewed-by: Imre Deak <imre.deak@intel.com>
>
>>  
>>  	if (i915_panel_invert_brightness < 0)
>>  		return val;
>>  
>>  	if (i915_panel_invert_brightness > 0 ||
>>  	    dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
>> -		u32 max = intel_panel_get_max_backlight(connector);
>> -		if (max)
>> -			return max - val;
>> +		return panel->backlight.max - val;
>>  	}
>>  
>>  	return val;
>> @@ -555,17 +553,15 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>>  {
>>  	struct drm_device *dev = connector->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct intel_panel *panel = &connector->panel;
>>  	u32 tmp, mask;
>>  
>> +	WARN_ON(panel->backlight.max == 0);
>> +
>>  	if (is_backlight_combination_mode(dev)) {
>> -		u32 max = intel_panel_get_max_backlight(connector);
>>  		u8 lbpc;
>>  
>> -		/* we're screwed, but keep behaviour backwards compatible */
>> -		if (!max)
>> -			max = 1;
>> -
>> -		lbpc = level * 0xfe / max + 1;
>> +		lbpc = level * 0xfe / panel->backlight.max + 1;
>>  		level /= lbpc;
>>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
>>  	}
>> @@ -620,13 +616,10 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>>  
>>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>>  
>> -	freq = intel_panel_get_max_backlight(connector);
>> -	if (!freq) {
>> -		/* we are screwed, bail out */
>> -		goto out;
>> -	}
>> +	WARN_ON(panel->backlight.max == 0);
>>  
>> -	/* scale to hardware, but be careful to not overflow */
>> +	/* scale to hardware max, but be careful to not overflow */
>> +	freq = panel->backlight.max;
>>  	if (freq < max)
>>  		level = level * freq / max;
>>  	else
>> @@ -638,7 +631,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
>>  
>>  	if (panel->backlight.enabled)
>>  		intel_panel_actually_set_backlight(connector, level);
>> -out:
>> +
>>  	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>>  }
>>  
>> @@ -839,8 +832,13 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>>  
>>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>>  
>> +	/* XXX: transitional, call to make sure freq is set */
>> +	intel_panel_get_max_backlight(connector);
>> +
>> +	WARN_ON(panel->backlight.max == 0);
>> +
>>  	if (panel->backlight.level == 0) {
>> -		panel->backlight.level = intel_panel_get_max_backlight(connector);
>> +		panel->backlight.level = panel->backlight.max;
>>  		if (panel->backlight.device)
>>  			panel->backlight.device->props.brightness =
>>  				panel->backlight.level;
>> @@ -960,7 +958,12 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
>>  }
>>  #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */
>>  
>> -/* Note: The setup hooks can't assume pipe is set! */
>> +/*
>> + * Note: The setup hooks can't assume pipe is set!
>> + *
>> + * XXX: Query mode clock or hardware clock and program PWM modulation frequency
>> + * appropriately when it's 0. Use VBT and/or sane defaults.
>> + */
>>  static int pch_setup_backlight(struct intel_connector *connector)
>>  {
>>  	struct intel_panel *panel = &connector->panel;
>
>

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 13/13] drm/i915: do not save/restore backlight registers
  2013-11-12 23:25   ` Daniel Vetter
@ 2013-11-13  8:40     ` Jani Nikula
  2013-11-13 10:56     ` [PATCH v2] drm/i915: do not save/restore backlight registers in KMS Jani Nikula
  1 sibling, 0 replies; 49+ messages in thread
From: Jani Nikula @ 2013-11-13  8:40 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Wed, 13 Nov 2013, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, Nov 08, 2013 at 04:49:05PM +0200, Jani Nikula wrote:
>> The backlight enable code now has the smarts to do the right thing.
>> 
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> You can't just kill this due to ums code, instead it needs to be protected
> by if (!DRIVER_MODESET) checks.

/me cries a little.


> -Daniel
>
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h     |    6 -----
>>  drivers/gpu/drm/i915/i915_suspend.c |   45 -----------------------------------
>>  2 files changed, 51 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 500bab3..6fec21e 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -766,13 +766,7 @@ struct i915_suspend_saved_registers {
>>  	u32 saveDSPATILEOFF;
>>  	u32 savePFIT_PGM_RATIOS;
>>  	u32 saveBLC_HIST_CTL;
>> -	u32 saveBLC_PWM_CTL;
>> -	u32 saveBLC_PWM_CTL2;
>>  	u32 saveBLC_HIST_CTL_B;
>> -	u32 saveBLC_PWM_CTL_B;
>> -	u32 saveBLC_PWM_CTL2_B;
>> -	u32 saveBLC_CPU_PWM_CTL;
>> -	u32 saveBLC_CPU_PWM_CTL2;
>>  	u32 saveFPB0;
>>  	u32 saveFPB1;
>>  	u32 saveDPLL_B;
>> diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
>> index eadf8e1..6b8fef7 100644
>> --- a/drivers/gpu/drm/i915/i915_suspend.c
>> +++ b/drivers/gpu/drm/i915/i915_suspend.c
>> @@ -192,7 +192,6 @@ static void i915_restore_vga(struct drm_device *dev)
>>  static void i915_save_display(struct drm_device *dev)
>>  {
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	unsigned long flags;
>>  
>>  	/* Display arbitration control */
>>  	if (INTEL_INFO(dev)->gen <= 4)
>> @@ -203,46 +202,27 @@ static void i915_save_display(struct drm_device *dev)
>>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>>  		i915_save_display_reg(dev);
>>  
>> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>> -
>>  	/* LVDS state */
>>  	if (HAS_PCH_SPLIT(dev)) {
>>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
>> -		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
>> -		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
>> -		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
>> -		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
>>  		if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
>>  			dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
>>  	} else if (IS_VALLEYVIEW(dev)) {
>>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
>>  		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
>>  
>> -		dev_priv->regfile.saveBLC_PWM_CTL =
>> -			I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
>>  		dev_priv->regfile.saveBLC_HIST_CTL =
>>  			I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
>> -		dev_priv->regfile.saveBLC_PWM_CTL2 =
>> -			I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
>> -		dev_priv->regfile.saveBLC_PWM_CTL_B =
>> -			I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
>>  		dev_priv->regfile.saveBLC_HIST_CTL_B =
>>  			I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
>> -		dev_priv->regfile.saveBLC_PWM_CTL2_B =
>> -			I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
>>  	} else {
>>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
>>  		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
>> -		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
>>  		dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
>> -		if (INTEL_INFO(dev)->gen >= 4)
>> -			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
>>  		if (IS_MOBILE(dev) && !IS_I830(dev))
>>  			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
>>  	}
>>  
>> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>> -
>>  	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
>>  		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
>>  
>> @@ -278,7 +258,6 @@ static void i915_restore_display(struct drm_device *dev)
>>  {
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	u32 mask = 0xffffffff;
>> -	unsigned long flags;
>>  
>>  	/* Display arbitration */
>>  	if (INTEL_INFO(dev)->gen <= 4)
>> @@ -287,12 +266,6 @@ static void i915_restore_display(struct drm_device *dev)
>>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>>  		i915_restore_display_reg(dev);
>>  
>> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>> -
>> -	/* LVDS state */
>> -	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
>> -		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
>> -
>>  	if (drm_core_check_feature(dev, DRIVER_MODESET))
>>  		mask = ~LVDS_PORT_EN;
>>  
>> @@ -305,13 +278,6 @@ static void i915_restore_display(struct drm_device *dev)
>>  		I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL);
>>  
>>  	if (HAS_PCH_SPLIT(dev)) {
>> -		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
>> -		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
>> -		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
>> -		 * otherwise we get blank eDP screen after S3 on some machines
>> -		 */
>> -		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
>> -		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
>>  		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
>>  		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
>>  		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
>> @@ -319,21 +285,12 @@ static void i915_restore_display(struct drm_device *dev)
>>  		I915_WRITE(RSTDBYCTL,
>>  			   dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
>>  	} else if (IS_VALLEYVIEW(dev)) {
>> -		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
>> -			   dev_priv->regfile.saveBLC_PWM_CTL);
>>  		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
>>  			   dev_priv->regfile.saveBLC_HIST_CTL);
>> -		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
>> -			   dev_priv->regfile.saveBLC_PWM_CTL2);
>> -		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
>> -			   dev_priv->regfile.saveBLC_PWM_CTL);
>>  		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
>>  			   dev_priv->regfile.saveBLC_HIST_CTL);
>> -		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
>> -			   dev_priv->regfile.saveBLC_PWM_CTL2);
>>  	} else {
>>  		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
>> -		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
>>  		I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL);
>>  		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
>>  		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
>> @@ -341,8 +298,6 @@ static void i915_restore_display(struct drm_device *dev)
>>  		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
>>  	}
>>  
>> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
>> -
>>  	/* only restore FBC info on the platform that supports FBC*/
>>  	intel_disable_fbc(dev);
>>  	if (I915_HAS_FBC(dev)) {
>> -- 
>> 1.7.10.4
>> 
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set
  2013-11-13  8:27     ` Jani Nikula
@ 2013-11-13  9:04       ` Daniel Vetter
  2013-11-13  9:12       ` Imre Deak
  1 sibling, 0 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-13  9:04 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Wed, Nov 13, 2013 at 10:27:38AM +0200, Jani Nikula wrote:
> On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> > On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_panel.c |   10 +++++++---
> >>  1 file changed, 7 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index a821949..e82b2dd 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -555,7 +555,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
> >>  {
> >>  	struct drm_device *dev = connector->base.dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	u32 tmp;
> >> +	u32 tmp, mask;
> >>  
> >>  	if (is_backlight_combination_mode(dev)) {
> >>  		u32 max = intel_panel_get_max_backlight(connector);
> >> @@ -570,10 +570,14 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
> >>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
> >>  	}
> >>  
> >> -	if (INTEL_INFO(dev)->gen < 4)
> >> +	if (IS_GEN4(dev)) {
> >> +		mask = BACKLIGHT_DUTY_CYCLE_MASK;
> >> +	} else {
> >>  		level <<= 1;
> >> +		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
> >> +	}
> >
> > According to the gen2/3 bspec I have, the correct mask is
> > BACKLIGHT_DUTY_CYCLE_MASK_PNV only in case of IS_PINEVIEW(dev), for
> > everything else it's BACKLIGHT_DUTY_CYCLE_MASK.
> 
> What you say is correct, but we've treated all gen2/3 similar to PNV
> since
> 
> commit ca88479c1c3b7b1a9f94320745f5331e1de77f80
> Author: Keith Packard <keithp@keithp.com>
> Date:   Fri Nov 18 11:09:24 2011 -0800
> 
>     drm/i915: Treat pre-gen4 backlight duty cycle value consistently
> 
> i.e. we only use the high 15 bits for all gen2/3. For non-PNV this just
> means the lowest bit is always zero. For PNV the lowest bit has a
> different meaning in both the PWM freq and duty cycle fields.
> 
> I don't want to take any chances by changing this behaviour. I realize
> there's zero comments about this in the code; would you like me to add
> some?

Yeah, I think some comment here would be good. Or maybe a follow-up patch
to differentiate between pnv and everything else on gen2/3.
-Daniel

> 
> 
> BR,
> Jani.
> 
> 
> >
> > --Imre
> >
> >>  
> >> -	tmp = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
> >> +	tmp = I915_READ(BLC_PWM_CTL) & ~mask;
> >>  	I915_WRITE(BLC_PWM_CTL, tmp | level);
> >>  }
> >>  
> >
> >
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set
  2013-11-13  8:27     ` Jani Nikula
  2013-11-13  9:04       ` Daniel Vetter
@ 2013-11-13  9:12       ` Imre Deak
  1 sibling, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-13  9:12 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 2493 bytes --]

On Wed, 2013-11-13 at 10:27 +0200, Jani Nikula wrote:
> On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> > On Fri, 2013-11-08 at 16:48 +0200, Jani Nikula wrote:
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_panel.c |   10 +++++++---
> >>  1 file changed, 7 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index a821949..e82b2dd 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -555,7 +555,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
> >>  {
> >>  	struct drm_device *dev = connector->base.dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	u32 tmp;
> >> +	u32 tmp, mask;
> >>  
> >>  	if (is_backlight_combination_mode(dev)) {
> >>  		u32 max = intel_panel_get_max_backlight(connector);
> >> @@ -570,10 +570,14 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
> >>  		pci_write_config_byte(dev->pdev, PCI_LBPC, lbpc);
> >>  	}
> >>  
> >> -	if (INTEL_INFO(dev)->gen < 4)
> >> +	if (IS_GEN4(dev)) {
> >> +		mask = BACKLIGHT_DUTY_CYCLE_MASK;
> >> +	} else {
> >>  		level <<= 1;
> >> +		mask = BACKLIGHT_DUTY_CYCLE_MASK_PNV;
> >> +	}
> >
> > According to the gen2/3 bspec I have, the correct mask is
> > BACKLIGHT_DUTY_CYCLE_MASK_PNV only in case of IS_PINEVIEW(dev), for
> > everything else it's BACKLIGHT_DUTY_CYCLE_MASK.
> 
> What you say is correct, but we've treated all gen2/3 similar to PNV
> since
> 
> commit ca88479c1c3b7b1a9f94320745f5331e1de77f80
> Author: Keith Packard <keithp@keithp.com>
> Date:   Fri Nov 18 11:09:24 2011 -0800
> 
>     drm/i915: Treat pre-gen4 backlight duty cycle value consistently
> 
> i.e. we only use the high 15 bits for all gen2/3. For non-PNV this just
> means the lowest bit is always zero. For PNV the lowest bit has a
> different meaning in both the PWM freq and duty cycle fields.
> 
> I don't want to take any chances by changing this behaviour. I realize
> there's zero comments about this in the code; would you like me to add
> some?

Yea, looking at the log would've been useful.. I see now from that
commit that there was a problem with setting bit 0 on some old HW, so
I'm ok to leave this as-is. A comment would be nice, but either way:

Reviewed-by: Imre Deak <imre.deak@intel.com>


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it
  2013-11-13  8:39     ` Jani Nikula
@ 2013-11-13  9:12       ` Daniel Vetter
  0 siblings, 0 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-13  9:12 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Wed, Nov 13, 2013 at 10:39:43AM +0200, Jani Nikula wrote:
> On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> > On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> >> We now have the max backlight value cached. Use it.
> >> 
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_panel.c |   45 +++++++++++++++++++-----------------
> >>  1 file changed, 24 insertions(+), 21 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index ed6b1ec..9a55b36 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -436,9 +436,6 @@ static u32 vlv_get_max_backlight(struct intel_connector *connector)
> >>  	return _vlv_get_max_backlight(dev, pipe);
> >>  }
> >>  
> >> -/* XXX: query mode clock or hardware clock and program max PWM appropriately
> >> - * when it's 0.
> >> - */
> >>  static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
> >>  {
> >>  	struct drm_device *dev = connector->base.dev;
> >> @@ -466,15 +463,16 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
> >>  {
> >>  	struct drm_device *dev = connector->base.dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> +	struct intel_panel *panel = &connector->panel;
> >> +
> >> +	WARN_ON(panel->backlight.max == 0);
> >
> > Just to clarify that I understood this: we can't hit this any more since
> > setup_backlight returns now -ENODEV if backlight.max == 0 and so we
> > won't register the backlight device in that case. I assume then that
> > during booting the BIOS always leaves us with a valid max PWM value in
> > one of the PWM_CTL regs and it can only get zeroed due to suspend, which
> > isn't a problem after patch 4. With this:
> 
> You've correctly understood what I meant. I do hope what I meant is the
> right thing to do! ;)
> 
> Now that I think about it, there are hints that (at least on some
> platforms) a GPU reset might cause the registers to be reset too:
> 
> commit 0b0b053a3949f5c467c3b3ba135d4c161f9fbd00
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date:   Tue Nov 23 09:45:50 2010 +0000
> 
>     drm/i915/panel: Restore saved value of BLC_PWM_CTL
> 
> The big question is, are we okay with re-writing the potentially zeroed
> out registers at crtc enable time? The current upstream code would do
> that at reading the max backlight level, which happens also at adjusting
> the backlight. But there are no guarantees about anyone adjusting the
> backlight either.
> 
> I don't understand our GPU reset enough to say for sure, but my gut
> feeling is that what I have in this series should be enough.

Also not that nowadays we don't reinitialize the display stuff any more
since it caused trouble. And it wasn't necessary either. So if we'd indeed
need to readjust the backlight I think we'd have a bug report by now:

commit 523bcb28c3fb92baecda6daa60560f67eb4a6177
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Fri Apr 27 15:17:46 2012 +0200

    drm/i915: remove modeset reset from i915_reset

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 09/13] drm/i915: debug print on backlight register
  2013-11-12 22:48   ` Imre Deak
@ 2013-11-13 10:22     ` Daniel Vetter
  0 siblings, 0 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-13 10:22 UTC (permalink / raw)
  To: Imre Deak; +Cc: Jani Nikula, intel-gfx

On Wed, Nov 13, 2013 at 12:48:01AM +0200, Imre Deak wrote:
> On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> 
> Reviewed-by: Imre Deak <imre.deak@intel.com>

Merged up to this patch with a pimped commit message for patch 5.
-Daniel

> 
> > ---
> >  drivers/gpu/drm/i915/intel_panel.c |    6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> > index 9a55b36..3dd9f57d 100644
> > --- a/drivers/gpu/drm/i915/intel_panel.c
> > +++ b/drivers/gpu/drm/i915/intel_panel.c
> > @@ -1065,6 +1065,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
> >  
> >  	panel->backlight.present = true;
> >  
> > +	DRM_DEBUG_KMS("backlight initialized, %s, brightness %u/%u, "
> > +		      "sysfs interface %sregistered\n",
> > +		      panel->backlight.enabled ? "enabled" : "disabled",
> > +		      panel->backlight.level, panel->backlight.max,
> > +		      panel->backlight.device ? "" : "not ");
> > +
> >  	return 0;
> >  }
> >  
> 
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2] drm/i915: do not save/restore backlight registers in KMS
  2013-11-12 23:25   ` Daniel Vetter
  2013-11-13  8:40     ` Jani Nikula
@ 2013-11-13 10:56     ` Jani Nikula
  2013-11-13 18:05       ` Imre Deak
  1 sibling, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-13 10:56 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

The backlight enable code now has the smarts to do the right thing. Only
do backlight register save/restore in UMS.

Some VLV specific code gets dropped as UMS is not supported on VLV.

v2: Move save/restore to UMS instead of removing completely (Daniel).

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     |    2 --
 drivers/gpu/drm/i915/i915_suspend.c |   45 -----------------------------------
 drivers/gpu/drm/i915/i915_ums.c     |   27 +++++++++++++++++++++
 3 files changed, 27 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 73f4833..7997538 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -769,8 +769,6 @@ struct i915_suspend_saved_registers {
 	u32 saveBLC_PWM_CTL;
 	u32 saveBLC_PWM_CTL2;
 	u32 saveBLC_HIST_CTL_B;
-	u32 saveBLC_PWM_CTL_B;
-	u32 saveBLC_PWM_CTL2_B;
 	u32 saveBLC_CPU_PWM_CTL;
 	u32 saveBLC_CPU_PWM_CTL2;
 	u32 saveFPB0;
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index eadf8e1..6b8fef7 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -192,7 +192,6 @@ static void i915_restore_vga(struct drm_device *dev)
 static void i915_save_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long flags;
 
 	/* Display arbitration control */
 	if (INTEL_INFO(dev)->gen <= 4)
@@ -203,46 +202,27 @@ static void i915_save_display(struct drm_device *dev)
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_save_display_reg(dev);
 
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-
 	/* LVDS state */
 	if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
-		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
-		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
-		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
-		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
 		if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
 			dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
 		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
 
-		dev_priv->regfile.saveBLC_PWM_CTL =
-			I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
 		dev_priv->regfile.saveBLC_HIST_CTL =
 			I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
-		dev_priv->regfile.saveBLC_PWM_CTL2 =
-			I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
-		dev_priv->regfile.saveBLC_PWM_CTL_B =
-			I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
 		dev_priv->regfile.saveBLC_HIST_CTL_B =
 			I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
-		dev_priv->regfile.saveBLC_PWM_CTL2_B =
-			I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
 	} else {
 		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
 		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
-		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
 		dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
-		if (INTEL_INFO(dev)->gen >= 4)
-			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
 		if (IS_MOBILE(dev) && !IS_I830(dev))
 			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
 		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
 
@@ -278,7 +258,6 @@ static void i915_restore_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 mask = 0xffffffff;
-	unsigned long flags;
 
 	/* Display arbitration */
 	if (INTEL_INFO(dev)->gen <= 4)
@@ -287,12 +266,6 @@ static void i915_restore_display(struct drm_device *dev)
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		i915_restore_display_reg(dev);
 
-	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
-
-	/* LVDS state */
-	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
-		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-
 	if (drm_core_check_feature(dev, DRIVER_MODESET))
 		mask = ~LVDS_PORT_EN;
 
@@ -305,13 +278,6 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL);
 
 	if (HAS_PCH_SPLIT(dev)) {
-		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
-		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
-		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
-		 * otherwise we get blank eDP screen after S3 on some machines
-		 */
-		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
-		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
 		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
 		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
 		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
@@ -319,21 +285,12 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(RSTDBYCTL,
 			   dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
 	} else if (IS_VALLEYVIEW(dev)) {
-		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
-			   dev_priv->regfile.saveBLC_PWM_CTL);
 		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
 			   dev_priv->regfile.saveBLC_HIST_CTL);
-		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
-			   dev_priv->regfile.saveBLC_PWM_CTL2);
-		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
-			   dev_priv->regfile.saveBLC_PWM_CTL);
 		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
 			   dev_priv->regfile.saveBLC_HIST_CTL);
-		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
-			   dev_priv->regfile.saveBLC_PWM_CTL2);
 	} else {
 		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
-		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
 		I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL);
 		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
 		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
@@ -341,8 +298,6 @@ static void i915_restore_display(struct drm_device *dev)
 		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
 	}
 
-	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
-
 	/* only restore FBC info on the platform that supports FBC*/
 	intel_disable_fbc(dev);
 	if (I915_HAS_FBC(dev)) {
diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c
index 967da47..caa18e8 100644
--- a/drivers/gpu/drm/i915/i915_ums.c
+++ b/drivers/gpu/drm/i915/i915_ums.c
@@ -270,6 +270,18 @@ void i915_save_display_reg(struct drm_device *dev)
 	}
 	/* FIXME: regfile.save TV & SDVO state */
 
+	/* Backlight */
+	if (HAS_PCH_SPLIT(dev)) {
+		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
+		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
+		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
+		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
+	} else {
+		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+		if (INTEL_INFO(dev)->gen >= 4)
+			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+	}
+
 	return;
 }
 
@@ -280,6 +292,21 @@ void i915_restore_display_reg(struct drm_device *dev)
 	int dpll_b_reg, fpb0_reg, fpb1_reg;
 	int i;
 
+	/* Backlight */
+	if (HAS_PCH_SPLIT(dev)) {
+		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
+		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
+		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
+		 * otherwise we get blank eDP screen after S3 on some machines
+		 */
+		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
+		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
+	} else {
+		if (INTEL_INFO(dev)->gen >= 4)
+			I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
+		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
+	}
+
 	/* Display port ratios (must be done before clock is set) */
 	if (SUPPORTS_INTEGRATED_DP(dev)) {
 		I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 10/13] drm/i915: gather backlight information at setup
  2013-11-08 14:49 ` [PATCH 10/13] drm/i915: gather backlight information at setup Jani Nikula
@ 2013-11-13 17:01   ` Imre Deak
  2013-11-14  5:19     ` Jani Nikula
  0 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-13 17:01 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 6349 bytes --]

On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> Prepare for being able to use the information at enable.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_drv.h   |    2 ++
>  drivers/gpu/drm/i915/intel_panel.c |   68 +++++++++++++++++++++++++++++-------
>  2 files changed, 58 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7384a7b..6f2bc82 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -163,6 +163,8 @@ struct intel_panel {
>  		u32 level;
>  		u32 max;
>  		bool enabled;
> +		bool combination_mode;	/* gen 2/4 only */
> +		bool active_low_pwm;
>  		struct backlight_device *device;
>  	} backlight;
>  };
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 3dd9f57d..0e8f0a3 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -490,13 +490,14 @@ static u32 i9xx_get_backlight(struct intel_connector *connector)
>  {
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_panel *panel = &connector->panel;
>  	u32 val;
>  
>  	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
>  	if (INTEL_INFO(dev)->gen < 4)
>  		val >>= 1;
>  
> -	if (is_backlight_combination_mode(dev)) {
> +	if (panel->backlight.combination_mode) {
>  		u8 lbpc;
>  
>  		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
> @@ -558,7 +559,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>  
>  	WARN_ON(panel->backlight.max == 0);
>  
> -	if (is_backlight_combination_mode(dev)) {
> +	if (panel->backlight.combination_mode) {
>  		u8 lbpc;
>  
>  		lbpc = level * 0xfe / panel->backlight.max + 1;
> @@ -966,46 +967,84 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
>   */
>  static int pch_setup_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
> -	u32 val;
> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
>  
> -	panel->backlight.max = pch_get_max_backlight(connector);
> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
> +	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> +
> +	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
> +	panel->backlight.max = pch_ctl2 >> 16;
>  	if (!panel->backlight.max)
>  		return -ENODEV;
>  
>  	val = pch_get_backlight(connector);
>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>  
> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> +	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
> +		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;

Don't we need to check here for QUIRK_NO_PCH_PWM_ENABLE?

--Imre

> +
>  	return 0;
>  }
>  
>  static int i9xx_setup_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
> -	u32 val;
> +	u32 ctl, val;
> +
> +	ctl = I915_READ(BLC_PWM_CTL);
> +
> +	if (IS_GEN2(dev))
> +		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
> +
> +	if (IS_PINEVIEW(dev))
> +		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
> +
> +	panel->backlight.max = ctl >> 17;
> +	if (panel->backlight.combination_mode)
> +		panel->backlight.max *= 0xff;
>  
> -	panel->backlight.max = i9xx_get_max_backlight(connector);
>  	if (!panel->backlight.max)
>  		return -ENODEV;
>  
>  	val = i9xx_get_backlight(connector);
>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>  
> +	panel->backlight.enabled = panel->backlight.level != 0;
> +
>  	return 0;
>  }
>  
>  static int i965_setup_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
> -	u32 val;
> +	u32 ctl, ctl2, val;
> +
> +	ctl2 = I915_READ(BLC_PWM_CTL2);
> +	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
> +	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
> +
> +	ctl = I915_READ(BLC_PWM_CTL);
> +	panel->backlight.max = ctl >> 16;
> +	if (panel->backlight.combination_mode)
> +		panel->backlight.max *= 0xff;
>  
> -	panel->backlight.max = i965_get_max_backlight(connector);
>  	if (!panel->backlight.max)
>  		return -ENODEV;
>  
>  	val = i9xx_get_backlight(connector);
>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>  
> +	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
> +		panel->backlight.level != 0;
> +
>  	return 0;
>  }
>  
> @@ -1015,7 +1054,7 @@ static int vlv_setup_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe;
> -	u32 val;
> +	u32 ctl, ctl2, val;
>  
>  	for_each_pipe(pipe) {
>  		u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
> @@ -1029,13 +1068,20 @@ static int vlv_setup_backlight(struct intel_connector *connector)
>  			   cur_val);
>  	}
>  
> -	panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A);
> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
> +	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
> +
> +	ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
> +	panel->backlight.max = ctl >> 16;
>  	if (!panel->backlight.max)
>  		return -ENODEV;
>  
>  	val = _vlv_get_backlight(dev, PIPE_A);
>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>  
> +	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
> +		panel->backlight.level != 0;
> +
>  	return 0;
>  }
>  
> @@ -1059,8 +1105,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
>  		return ret;
>  	}
>  
> -	panel->backlight.enabled = panel->backlight.level != 0;
> -
>  	intel_backlight_device_register(intel_connector);
>  
>  	panel->backlight.present = true;


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 11/13] drm/i915: do full backlight setup at enable time
  2013-11-08 14:49 ` [PATCH 11/13] drm/i915: do full backlight setup at enable time Jani Nikula
@ 2013-11-13 17:53   ` Imre Deak
  2013-11-14  5:43     ` Jani Nikula
  2013-11-14 10:13   ` [PATCH v2 " Jani Nikula
  2013-11-14 10:14   ` [PATCH 11.5/13] drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE Jani Nikula
  2 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-13 17:53 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7429 bytes --]

On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> We should now have all the information we need to do a full
> initialization of the backlight registers.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_panel.c |  145 ++++++++++++++++++++++--------------
>  1 file changed, 89 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 0e8f0a3..da088e3 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -719,50 +719,71 @@ static void pch_enable_backlight(struct intel_connector *connector)
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	enum transcoder cpu_transcoder =
>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> -	u32 tmp;
> -
> -	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
>  
> -	/* Note that this can also get called through dpms changes. And
> -	 * we don't track the backlight dpms state, hence check whether
> -	 * we have to do anything first. */
> -	if (tmp & BLM_PWM_ENABLE)
> -		return;
> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> +	if (cpu_ctl2 & BLM_PWM_ENABLE) {
> +		WARN(1, "cpu backlight already enabled\n");
> +		cpu_ctl2 &= ~BLM_PWM_ENABLE;
> +		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
> +	}
>  
> -	if (INTEL_INFO(dev)->num_pipes == 3)
> -		tmp &= ~BLM_PIPE_SELECT_IVB;
> -	else
> -		tmp &= ~BLM_PIPE_SELECT;
> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> +		DRM_DEBUG_KMS("pch backlight already enabled\n");
> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> +		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> +	}
>  
>  	if (cpu_transcoder == TRANSCODER_EDP)
> -		tmp |= BLM_TRANSCODER_EDP;
> +		cpu_ctl2 = BLM_TRANSCODER_EDP;
>  	else
> -		tmp |= BLM_PIPE(cpu_transcoder);
> -	tmp &= ~BLM_PWM_ENABLE;
> -
> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
> +		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
>  	POSTING_READ(BLC_PWM_CPU_CTL2);
> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
> -
> -	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> -		tmp = I915_READ(BLC_PWM_PCH_CTL1);
> -		tmp |= BLM_PCH_PWM_ENABLE;
> -		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> -		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> -	}

Like in the previous patch, why is this removed? If the w/a is not
needed any more it should be a separate patch.

> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
>  
> -	/*
> -	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> -	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> -	 * registers are set.
> -	 */
> +	/* This won't stick until the above enable. */
>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +
> +	pch_ctl2 = panel->backlight.max << 16;
> +	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
> +
> +	pch_ctl1 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		pch_ctl1 |= BLM_PCH_POLARITY;
> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> +	POSTING_READ(BLC_PWM_PCH_CTL1);
> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
>  }
>  
>  static void i9xx_enable_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
> +	u32 ctl, freq;
>  
> +	ctl = I915_READ(BLC_PWM_CTL);
> +	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
> +		WARN(1, "backlight already enabled\n");
> +		I915_WRITE(BLC_PWM_CTL, 0);
> +	}
> +
> +	freq = panel->backlight.max;
> +	if (panel->backlight.combination_mode)
> +		freq /= 0xff;
> +
> +	ctl = freq << 17;
> +	if (IS_GEN2(dev) && panel->backlight.combination_mode)
> +		ctl |= BLM_LEGACY_MODE;
> +	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
> +		ctl |= BLM_POLARITY_PNV;
> +
> +	I915_WRITE(BLC_PWM_CTL, ctl);
> +	POSTING_READ(BLC_PWM_CTL);
> +
> +	/* XXX: combine this into above write? */
>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  }
>  
> @@ -772,25 +793,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> -	u32 tmp;
> -
> -	tmp = I915_READ(BLC_PWM_CTL2);
> +	u32 ctl, ctl2, freq;
>  
> -	/* Note that this can also get called through dpms changes. And
> -	 * we don't track the backlight dpms state, hence check whether
> -	 * we have to do anything first. */
> -	if (tmp & BLM_PWM_ENABLE)
> -		return;
> +	ctl2 = I915_READ(BLC_PWM_CTL2);
> +	if (ctl2 & BLM_PWM_ENABLE) {
> +		WARN(1, "backlight already enabled\n");
> +		ctl2 &= ~BLM_PWM_ENABLE;
> +		I915_WRITE(BLC_PWM_CTL2, ctl2);
> +	}
>  
> -	tmp &= ~BLM_PIPE_SELECT;
> -	tmp |= BLM_PIPE(pipe);
> -	tmp &= ~BLM_PWM_ENABLE;
> +	freq = panel->backlight.max;
> +	if (panel->backlight.combination_mode)
> +		freq /= 0xff;
>  
> -	I915_WRITE(BLC_PWM_CTL2, tmp);
> -	POSTING_READ(BLC_PWM_CTL2);
> -	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> +	ctl = freq << 16;
> +	I915_WRITE(BLC_PWM_CTL, ctl);
>  
> +	/* XXX: combine this into above write? */
>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +
> +	ctl2 = BLM_PIPE(pipe);
> +	if (panel->backlight.combination_mode)
> +		ctl2 |= BLM_COMBINATION_MODE;
> +	if (panel->backlight.active_low_pwm)
> +		ctl2 |= BLM_POLARITY_I965;
> +	I915_WRITE(BLC_PWM_CTL2, ctl2);
> +	POSTING_READ(BLC_PWM_CTL2);
> +	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
>  }
>  
>  static void vlv_enable_backlight(struct intel_connector *connector)
> @@ -799,23 +828,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> -	u32 tmp;
> +	u32 ctl, ctl2;
>  
> -	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> +	if (ctl2 & BLM_PWM_ENABLE) {
> +		WARN(1, "backlight already enabled\n");
> +		ctl2 &= ~BLM_PWM_ENABLE;
> +		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
> +	}
>  
> -	/* Note that this can also get called through dpms changes. And
> -	 * we don't track the backlight dpms state, hence check whether
> -	 * we have to do anything first. */
> -	if (tmp & BLM_PWM_ENABLE)
> -		return;
> +	ctl = panel->backlight.max << 16;
> +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
>  
> -	tmp &= ~BLM_PWM_ENABLE;
> +	/* XXX: combine this into above write? */
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  
> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
> +	ctl2 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		ctl2 |= BLM_POLARITY_I965;
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
>  	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
> -
> -	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
>  }
>  
>  void intel_panel_enable_backlight(struct intel_connector *connector)


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 12/13] drm/i915: nuke get max backlight functions
  2013-11-08 14:49 ` [PATCH 12/13] drm/i915: nuke get max backlight functions Jani Nikula
@ 2013-11-13 17:54   ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-13 17:54 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7011 bytes --]

On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> No longer needed. We now have fully cached max backlight values.
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h    |    1 -
>  drivers/gpu/drm/i915/intel_panel.c |  133 ------------------------------------
>  2 files changed, 134 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 2d70ae4..500bab3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -416,7 +416,6 @@ struct drm_i915_display_funcs {
>  	/* pll clock increase/decrease */
>  
>  	int (*setup_backlight)(struct intel_connector *connector);
> -	uint32_t (*get_max_backlight)(struct intel_connector *connector);
>  	uint32_t (*get_backlight)(struct intel_connector *connector);
>  	void (*set_backlight)(struct intel_connector *connector,
>  			      uint32_t level);
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index da088e3..eadfe33 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -325,132 +325,6 @@ out:
>  	pipe_config->gmch_pfit.lvds_border_bits = border;
>  }
>  
> -static int is_backlight_combination_mode(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	if (IS_GEN4(dev))
> -		return I915_READ(BLC_PWM_CTL2) & BLM_COMBINATION_MODE;
> -
> -	if (IS_GEN2(dev))
> -		return I915_READ(BLC_PWM_CTL) & BLM_LEGACY_MODE;
> -
> -	return 0;
> -}
> -
> -static u32 pch_get_max_backlight(struct intel_connector *connector)
> -{
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val;
> -
> -	val = I915_READ(BLC_PWM_PCH_CTL2);
> -	if (dev_priv->regfile.saveBLC_PWM_CTL2 == 0) {
> -		dev_priv->regfile.saveBLC_PWM_CTL2 = val;
> -	} else if (val == 0) {
> -		val = dev_priv->regfile.saveBLC_PWM_CTL2;
> -		I915_WRITE(BLC_PWM_PCH_CTL2, val);
> -	}
> -
> -	val >>= 16;
> -
> -	return val;
> -}
> -
> -static u32 i9xx_get_max_backlight(struct intel_connector *connector)
> -{
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val;
> -
> -	val = I915_READ(BLC_PWM_CTL);
> -	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> -		dev_priv->regfile.saveBLC_PWM_CTL = val;
> -	} else if (val == 0) {
> -		val = dev_priv->regfile.saveBLC_PWM_CTL;
> -		I915_WRITE(BLC_PWM_CTL, val);
> -	}
> -
> -	val >>= 17;
> -
> -	if (is_backlight_combination_mode(dev))
> -		val *= 0xff;
> -
> -	return val;
> -}
> -
> -static u32 i965_get_max_backlight(struct intel_connector *connector)
> -{
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val;
> -
> -	val = I915_READ(BLC_PWM_CTL);
> -	if (dev_priv->regfile.saveBLC_PWM_CTL == 0) {
> -		dev_priv->regfile.saveBLC_PWM_CTL = val;
> -		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
> -	} else if (val == 0) {
> -		val = dev_priv->regfile.saveBLC_PWM_CTL;
> -		I915_WRITE(BLC_PWM_CTL, val);
> -		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> -	}
> -
> -	val >>= 16;
> -
> -	if (is_backlight_combination_mode(dev))
> -		val *= 0xff;
> -
> -	return val;
> -}
> -
> -static u32 _vlv_get_max_backlight(struct drm_device *dev, enum pipe pipe)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 val;
> -
> -	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;
> -
> -	val >>= 16;
> -
> -	return val;
> -}
> -
> -static u32 vlv_get_max_backlight(struct intel_connector *connector)
> -{
> -	struct drm_device *dev = connector->base.dev;
> -	enum pipe pipe = intel_get_pipe_from_connector(connector);
> -
> -	return _vlv_get_max_backlight(dev, pipe);
> -}
> -
> -static u32 intel_panel_get_max_backlight(struct intel_connector *connector)
> -{
> -	struct drm_device *dev = connector->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	u32 max;
> -
> -	WARN_ON_SMP(!spin_is_locked(&dev_priv->backlight_lock));
> -
> -	max = dev_priv->display.get_max_backlight(connector);
> -
> -	DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max);
> -
> -	return max;
> -}
> -
>  static int i915_panel_invert_brightness;
>  MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness "
>  	"(-1 force normal, 0 machine defaults, 1 force inversion), please "
> @@ -866,9 +740,6 @@ void intel_panel_enable_backlight(struct intel_connector *connector)
>  
>  	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
>  
> -	/* XXX: transitional, call to make sure freq is set */
> -	intel_panel_get_max_backlight(connector);
> -
>  	WARN_ON(panel->backlight.max == 0);
>  
>  	if (panel->backlight.level == 0) {
> @@ -1171,28 +1042,24 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)
>  		dev_priv->display.disable_backlight = pch_disable_backlight;
>  		dev_priv->display.set_backlight = pch_set_backlight;
>  		dev_priv->display.get_backlight = pch_get_backlight;
> -		dev_priv->display.get_max_backlight = pch_get_max_backlight;
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		dev_priv->display.setup_backlight = vlv_setup_backlight;
>  		dev_priv->display.enable_backlight = vlv_enable_backlight;
>  		dev_priv->display.disable_backlight = vlv_disable_backlight;
>  		dev_priv->display.set_backlight = vlv_set_backlight;
>  		dev_priv->display.get_backlight = vlv_get_backlight;
> -		dev_priv->display.get_max_backlight = vlv_get_max_backlight;
>  	} else if (IS_GEN4(dev)) {
>  		dev_priv->display.setup_backlight = i965_setup_backlight;
>  		dev_priv->display.enable_backlight = i965_enable_backlight;
>  		dev_priv->display.disable_backlight = i965_disable_backlight;
>  		dev_priv->display.set_backlight = i9xx_set_backlight;
>  		dev_priv->display.get_backlight = i9xx_get_backlight;
> -		dev_priv->display.get_max_backlight = i965_get_max_backlight;
>  	} else {
>  		dev_priv->display.setup_backlight = i9xx_setup_backlight;
>  		dev_priv->display.enable_backlight = i9xx_enable_backlight;
>  		dev_priv->display.disable_backlight = i9xx_disable_backlight;
>  		dev_priv->display.set_backlight = i9xx_set_backlight;
>  		dev_priv->display.get_backlight = i9xx_get_backlight;
> -		dev_priv->display.get_max_backlight = i9xx_get_max_backlight;
>  	}
>  }
>  


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] drm/i915: do not save/restore backlight registers in KMS
  2013-11-13 10:56     ` [PATCH v2] drm/i915: do not save/restore backlight registers in KMS Jani Nikula
@ 2013-11-13 18:05       ` Imre Deak
  2013-11-14 11:22         ` Daniel Vetter
  0 siblings, 1 reply; 49+ messages in thread
From: Imre Deak @ 2013-11-13 18:05 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 8822 bytes --]

On Wed, 2013-11-13 at 12:56 +0200, Jani Nikula wrote:
> The backlight enable code now has the smarts to do the right thing. Only
> do backlight register save/restore in UMS.
> 
> Some VLV specific code gets dropped as UMS is not supported on VLV.
> 
> v2: Move save/restore to UMS instead of removing completely (Daniel).
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h     |    2 --
>  drivers/gpu/drm/i915/i915_suspend.c |   45 -----------------------------------
>  drivers/gpu/drm/i915/i915_ums.c     |   27 +++++++++++++++++++++
>  3 files changed, 27 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 73f4833..7997538 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -769,8 +769,6 @@ struct i915_suspend_saved_registers {
>  	u32 saveBLC_PWM_CTL;
>  	u32 saveBLC_PWM_CTL2;
>  	u32 saveBLC_HIST_CTL_B;
> -	u32 saveBLC_PWM_CTL_B;
> -	u32 saveBLC_PWM_CTL2_B;
>  	u32 saveBLC_CPU_PWM_CTL;
>  	u32 saveBLC_CPU_PWM_CTL2;
>  	u32 saveFPB0;
> diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
> index eadf8e1..6b8fef7 100644
> --- a/drivers/gpu/drm/i915/i915_suspend.c
> +++ b/drivers/gpu/drm/i915/i915_suspend.c
> @@ -192,7 +192,6 @@ static void i915_restore_vga(struct drm_device *dev)
>  static void i915_save_display(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned long flags;
>  
>  	/* Display arbitration control */
>  	if (INTEL_INFO(dev)->gen <= 4)
> @@ -203,46 +202,27 @@ static void i915_save_display(struct drm_device *dev)
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		i915_save_display_reg(dev);
>  
> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> -
>  	/* LVDS state */
>  	if (HAS_PCH_SPLIT(dev)) {
>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL);
> -		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
> -		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
> -		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
> -		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
>  		if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
>  			dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS);
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
>  		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
>  
> -		dev_priv->regfile.saveBLC_PWM_CTL =
> -			I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
>  		dev_priv->regfile.saveBLC_HIST_CTL =
>  			I915_READ(VLV_BLC_HIST_CTL(PIPE_A));
> -		dev_priv->regfile.saveBLC_PWM_CTL2 =
> -			I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
> -		dev_priv->regfile.saveBLC_PWM_CTL_B =
> -			I915_READ(VLV_BLC_PWM_CTL(PIPE_B));
>  		dev_priv->regfile.saveBLC_HIST_CTL_B =
>  			I915_READ(VLV_BLC_HIST_CTL(PIPE_B));
> -		dev_priv->regfile.saveBLC_PWM_CTL2_B =
> -			I915_READ(VLV_BLC_PWM_CTL2(PIPE_B));
>  	} else {
>  		dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL);
>  		dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
> -		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
>  		dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL);
> -		if (INTEL_INFO(dev)->gen >= 4)
> -			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
>  		if (IS_MOBILE(dev) && !IS_I830(dev))
>  			dev_priv->regfile.saveLVDS = I915_READ(LVDS);
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> -
>  	if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev))
>  		dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
>  
> @@ -278,7 +258,6 @@ static void i915_restore_display(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	u32 mask = 0xffffffff;
> -	unsigned long flags;
>  
>  	/* Display arbitration */
>  	if (INTEL_INFO(dev)->gen <= 4)
> @@ -287,12 +266,6 @@ static void i915_restore_display(struct drm_device *dev)
>  	if (!drm_core_check_feature(dev, DRIVER_MODESET))
>  		i915_restore_display_reg(dev);
>  
> -	spin_lock_irqsave(&dev_priv->backlight_lock, flags);
> -
> -	/* LVDS state */
> -	if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
> -		I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> -
>  	if (drm_core_check_feature(dev, DRIVER_MODESET))
>  		mask = ~LVDS_PORT_EN;
>  
> @@ -305,13 +278,6 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL);
>  
>  	if (HAS_PCH_SPLIT(dev)) {
> -		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
> -		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> -		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
> -		 * otherwise we get blank eDP screen after S3 on some machines
> -		 */
> -		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
> -		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
>  		I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
>  		I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
>  		I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR);
> @@ -319,21 +285,12 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(RSTDBYCTL,
>  			   dev_priv->regfile.saveMCHBAR_RENDER_STANDBY);
>  	} else if (IS_VALLEYVIEW(dev)) {
> -		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_A),
> -			   dev_priv->regfile.saveBLC_PWM_CTL);
>  		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A),
>  			   dev_priv->regfile.saveBLC_HIST_CTL);
> -		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_A),
> -			   dev_priv->regfile.saveBLC_PWM_CTL2);
> -		I915_WRITE(VLV_BLC_PWM_CTL(PIPE_B),
> -			   dev_priv->regfile.saveBLC_PWM_CTL);
>  		I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B),
>  			   dev_priv->regfile.saveBLC_HIST_CTL);
> -		I915_WRITE(VLV_BLC_PWM_CTL2(PIPE_B),
> -			   dev_priv->regfile.saveBLC_PWM_CTL2);
>  	} else {
>  		I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS);
> -		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
>  		I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL);
>  		I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS);
>  		I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS);
> @@ -341,8 +298,6 @@ static void i915_restore_display(struct drm_device *dev)
>  		I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL);
>  	}
>  
> -	spin_unlock_irqrestore(&dev_priv->backlight_lock, flags);
> -
>  	/* only restore FBC info on the platform that supports FBC*/
>  	intel_disable_fbc(dev);
>  	if (I915_HAS_FBC(dev)) {
> diff --git a/drivers/gpu/drm/i915/i915_ums.c b/drivers/gpu/drm/i915/i915_ums.c
> index 967da47..caa18e8 100644
> --- a/drivers/gpu/drm/i915/i915_ums.c
> +++ b/drivers/gpu/drm/i915/i915_ums.c
> @@ -270,6 +270,18 @@ void i915_save_display_reg(struct drm_device *dev)
>  	}
>  	/* FIXME: regfile.save TV & SDVO state */
>  
> +	/* Backlight */
> +	if (HAS_PCH_SPLIT(dev)) {
> +		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1);
> +		dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2);
> +		dev_priv->regfile.saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL);
> +		dev_priv->regfile.saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2);
> +	} else {
> +		dev_priv->regfile.saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
> +		if (INTEL_INFO(dev)->gen >= 4)
> +			dev_priv->regfile.saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
> +	}
> +
>  	return;
>  }
>  
> @@ -280,6 +292,21 @@ void i915_restore_display_reg(struct drm_device *dev)
>  	int dpll_b_reg, fpb0_reg, fpb1_reg;
>  	int i;
>  
> +	/* Backlight */
> +	if (HAS_PCH_SPLIT(dev)) {
> +		I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->regfile.saveBLC_PWM_CTL);
> +		I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> +		/* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
> +		 * otherwise we get blank eDP screen after S3 on some machines
> +		 */
> +		I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->regfile.saveBLC_CPU_PWM_CTL2);
> +		I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->regfile.saveBLC_CPU_PWM_CTL);
> +	} else {
> +		if (INTEL_INFO(dev)->gen >= 4)
> +			I915_WRITE(BLC_PWM_CTL2, dev_priv->regfile.saveBLC_PWM_CTL2);
> +		I915_WRITE(BLC_PWM_CTL, dev_priv->regfile.saveBLC_PWM_CTL);
> +	}
> +
>  	/* Display port ratios (must be done before clock is set) */
>  	if (SUPPORTS_INTEGRATED_DP(dev)) {
>  		I915_WRITE(_PIPEA_DATA_M_G4X, dev_priv->regfile.savePIPEA_GMCH_DATA_M);


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 10/13] drm/i915: gather backlight information at setup
  2013-11-13 17:01   ` Imre Deak
@ 2013-11-14  5:19     ` Jani Nikula
  2013-11-14  8:22       ` Imre Deak
  0 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-14  5:19 UTC (permalink / raw)
  To: imre.deak; +Cc: intel-gfx

On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
>> Prepare for being able to use the information at enable.
>> 
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_drv.h   |    2 ++
>>  drivers/gpu/drm/i915/intel_panel.c |   68 +++++++++++++++++++++++++++++-------
>>  2 files changed, 58 insertions(+), 12 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index 7384a7b..6f2bc82 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -163,6 +163,8 @@ struct intel_panel {
>>  		u32 level;
>>  		u32 max;
>>  		bool enabled;
>> +		bool combination_mode;	/* gen 2/4 only */
>> +		bool active_low_pwm;
>>  		struct backlight_device *device;
>>  	} backlight;
>>  };
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
>> index 3dd9f57d..0e8f0a3 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -490,13 +490,14 @@ static u32 i9xx_get_backlight(struct intel_connector *connector)
>>  {
>>  	struct drm_device *dev = connector->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct intel_panel *panel = &connector->panel;
>>  	u32 val;
>>  
>>  	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
>>  	if (INTEL_INFO(dev)->gen < 4)
>>  		val >>= 1;
>>  
>> -	if (is_backlight_combination_mode(dev)) {
>> +	if (panel->backlight.combination_mode) {
>>  		u8 lbpc;
>>  
>>  		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
>> @@ -558,7 +559,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
>>  
>>  	WARN_ON(panel->backlight.max == 0);
>>  
>> -	if (is_backlight_combination_mode(dev)) {
>> +	if (panel->backlight.combination_mode) {
>>  		u8 lbpc;
>>  
>>  		lbpc = level * 0xfe / panel->backlight.max + 1;
>> @@ -966,46 +967,84 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
>>   */
>>  static int pch_setup_backlight(struct intel_connector *connector)
>>  {
>> +	struct drm_device *dev = connector->base.dev;
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>> -	u32 val;
>> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
>>  
>> -	panel->backlight.max = pch_get_max_backlight(connector);
>> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
>> +	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
>> +
>> +	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
>> +	panel->backlight.max = pch_ctl2 >> 16;
>>  	if (!panel->backlight.max)
>>  		return -ENODEV;
>>  
>>  	val = pch_get_backlight(connector);
>>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>>  
>> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
>> +	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
>> +		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
>
> Don't we need to check here for QUIRK_NO_PCH_PWM_ENABLE?

Up front, I think the quirk is bogus, and it breaks machines.

Even if *we* don't set BLM_PCH_PWM_ENABLE on quirked machines, we just
expect the BIOS to have done it. So for checking whether the backlight
is enabled, this should be accurate.

BR,
Jani.


>
> --Imre
>
>> +
>>  	return 0;
>>  }
>>  
>>  static int i9xx_setup_backlight(struct intel_connector *connector)
>>  {
>> +	struct drm_device *dev = connector->base.dev;
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>> -	u32 val;
>> +	u32 ctl, val;
>> +
>> +	ctl = I915_READ(BLC_PWM_CTL);
>> +
>> +	if (IS_GEN2(dev))
>> +		panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
>> +
>> +	if (IS_PINEVIEW(dev))
>> +		panel->backlight.active_low_pwm = ctl & BLM_POLARITY_PNV;
>> +
>> +	panel->backlight.max = ctl >> 17;
>> +	if (panel->backlight.combination_mode)
>> +		panel->backlight.max *= 0xff;
>>  
>> -	panel->backlight.max = i9xx_get_max_backlight(connector);
>>  	if (!panel->backlight.max)
>>  		return -ENODEV;
>>  
>>  	val = i9xx_get_backlight(connector);
>>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>>  
>> +	panel->backlight.enabled = panel->backlight.level != 0;
>> +
>>  	return 0;
>>  }
>>  
>>  static int i965_setup_backlight(struct intel_connector *connector)
>>  {
>> +	struct drm_device *dev = connector->base.dev;
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>> -	u32 val;
>> +	u32 ctl, ctl2, val;
>> +
>> +	ctl2 = I915_READ(BLC_PWM_CTL2);
>> +	panel->backlight.combination_mode = ctl2 & BLM_COMBINATION_MODE;
>> +	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
>> +
>> +	ctl = I915_READ(BLC_PWM_CTL);
>> +	panel->backlight.max = ctl >> 16;
>> +	if (panel->backlight.combination_mode)
>> +		panel->backlight.max *= 0xff;
>>  
>> -	panel->backlight.max = i965_get_max_backlight(connector);
>>  	if (!panel->backlight.max)
>>  		return -ENODEV;
>>  
>>  	val = i9xx_get_backlight(connector);
>>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>>  
>> +	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
>> +		panel->backlight.level != 0;
>> +
>>  	return 0;
>>  }
>>  
>> @@ -1015,7 +1054,7 @@ static int vlv_setup_backlight(struct intel_connector *connector)
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>>  	enum pipe pipe;
>> -	u32 val;
>> +	u32 ctl, ctl2, val;
>>  
>>  	for_each_pipe(pipe) {
>>  		u32 cur_val = I915_READ(VLV_BLC_PWM_CTL(pipe));
>> @@ -1029,13 +1068,20 @@ static int vlv_setup_backlight(struct intel_connector *connector)
>>  			   cur_val);
>>  	}
>>  
>> -	panel->backlight.max = _vlv_get_max_backlight(dev, PIPE_A);
>> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(PIPE_A));
>> +	panel->backlight.active_low_pwm = ctl2 & BLM_POLARITY_I965;
>> +
>> +	ctl = I915_READ(VLV_BLC_PWM_CTL(PIPE_A));
>> +	panel->backlight.max = ctl >> 16;
>>  	if (!panel->backlight.max)
>>  		return -ENODEV;
>>  
>>  	val = _vlv_get_backlight(dev, PIPE_A);
>>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
>>  
>> +	panel->backlight.enabled = (ctl2 & BLM_PWM_ENABLE) &&
>> +		panel->backlight.level != 0;
>> +
>>  	return 0;
>>  }
>>  
>> @@ -1059,8 +1105,6 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
>>  		return ret;
>>  	}
>>  
>> -	panel->backlight.enabled = panel->backlight.level != 0;
>> -
>>  	intel_backlight_device_register(intel_connector);
>>  
>>  	panel->backlight.present = true;
>

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 11/13] drm/i915: do full backlight setup at enable time
  2013-11-13 17:53   ` Imre Deak
@ 2013-11-14  5:43     ` Jani Nikula
  2013-11-14  8:27       ` Daniel Vetter
  2013-11-14  8:28       ` Imre Deak
  0 siblings, 2 replies; 49+ messages in thread
From: Jani Nikula @ 2013-11-14  5:43 UTC (permalink / raw)
  To: imre.deak; +Cc: intel-gfx

On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
>> We should now have all the information we need to do a full
>> initialization of the backlight registers.
>> 
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_panel.c |  145 ++++++++++++++++++++++--------------
>>  1 file changed, 89 insertions(+), 56 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
>> index 0e8f0a3..da088e3 100644
>> --- a/drivers/gpu/drm/i915/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/intel_panel.c
>> @@ -719,50 +719,71 @@ static void pch_enable_backlight(struct intel_connector *connector)
>>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>>  	enum transcoder cpu_transcoder =
>>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
>> -	u32 tmp;
>> -
>> -	tmp = I915_READ(BLC_PWM_CPU_CTL2);
>> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
>>  
>> -	/* Note that this can also get called through dpms changes. And
>> -	 * we don't track the backlight dpms state, hence check whether
>> -	 * we have to do anything first. */
>> -	if (tmp & BLM_PWM_ENABLE)
>> -		return;
>> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
>> +	if (cpu_ctl2 & BLM_PWM_ENABLE) {
>> +		WARN(1, "cpu backlight already enabled\n");
>> +		cpu_ctl2 &= ~BLM_PWM_ENABLE;
>> +		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
>> +	}
>>  
>> -	if (INTEL_INFO(dev)->num_pipes == 3)
>> -		tmp &= ~BLM_PIPE_SELECT_IVB;
>> -	else
>> -		tmp &= ~BLM_PIPE_SELECT;
>> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
>> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
>> +		DRM_DEBUG_KMS("pch backlight already enabled\n");
>> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
>> +		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
>> +	}
>>  
>>  	if (cpu_transcoder == TRANSCODER_EDP)
>> -		tmp |= BLM_TRANSCODER_EDP;
>> +		cpu_ctl2 = BLM_TRANSCODER_EDP;
>>  	else
>> -		tmp |= BLM_PIPE(cpu_transcoder);
>> -	tmp &= ~BLM_PWM_ENABLE;
>> -
>> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
>> +		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
>> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
>>  	POSTING_READ(BLC_PWM_CPU_CTL2);
>> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
>> -
>> -	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
>> -		tmp = I915_READ(BLC_PWM_PCH_CTL1);
>> -		tmp |= BLM_PCH_PWM_ENABLE;
>> -		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
>> -		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
>> -	}
>
> Like in the previous patch, why is this removed? If the w/a is not
> needed any more it should be a separate patch.

As I said, I think the quirk is bogus. With the full backlight setup at
enable, we shouldn't trust this to have been set by the BIOS. Again, it
is required to be enabled, even on the machines that supposedly need the
quirk.

I expect the new enable sequence to tackle the problems. And any fallout
we should fix properly, without quirks - and with this series we are
much more flexible to adjust the sequence on a per platform basis. For
example, I was able to test on an IVB that we can't set the backlight
duty cycle until the cpu pwm has been enabled (hence the comment
below). But we do it the before the pch pwm enable.

All that said, maybe it should be a separate patch.


BR,
Jani.

>
>> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
>>  
>> -	/*
>> -	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
>> -	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
>> -	 * registers are set.
>> -	 */
>> +	/* This won't stick until the above enable. */
>>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>> +
>> +	pch_ctl2 = panel->backlight.max << 16;
>> +	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
>> +
>> +	pch_ctl1 = 0;
>> +	if (panel->backlight.active_low_pwm)
>> +		pch_ctl1 |= BLM_PCH_POLARITY;
>> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
>> +	POSTING_READ(BLC_PWM_PCH_CTL1);
>> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
>>  }
>>  
>>  static void i9xx_enable_backlight(struct intel_connector *connector)
>>  {
>> +	struct drm_device *dev = connector->base.dev;
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>> +	u32 ctl, freq;
>>  
>> +	ctl = I915_READ(BLC_PWM_CTL);
>> +	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
>> +		WARN(1, "backlight already enabled\n");
>> +		I915_WRITE(BLC_PWM_CTL, 0);
>> +	}
>> +
>> +	freq = panel->backlight.max;
>> +	if (panel->backlight.combination_mode)
>> +		freq /= 0xff;
>> +
>> +	ctl = freq << 17;
>> +	if (IS_GEN2(dev) && panel->backlight.combination_mode)
>> +		ctl |= BLM_LEGACY_MODE;
>> +	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
>> +		ctl |= BLM_POLARITY_PNV;
>> +
>> +	I915_WRITE(BLC_PWM_CTL, ctl);
>> +	POSTING_READ(BLC_PWM_CTL);
>> +
>> +	/* XXX: combine this into above write? */
>>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>>  }
>>  
>> @@ -772,25 +793,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>> -	u32 tmp;
>> -
>> -	tmp = I915_READ(BLC_PWM_CTL2);
>> +	u32 ctl, ctl2, freq;
>>  
>> -	/* Note that this can also get called through dpms changes. And
>> -	 * we don't track the backlight dpms state, hence check whether
>> -	 * we have to do anything first. */
>> -	if (tmp & BLM_PWM_ENABLE)
>> -		return;
>> +	ctl2 = I915_READ(BLC_PWM_CTL2);
>> +	if (ctl2 & BLM_PWM_ENABLE) {
>> +		WARN(1, "backlight already enabled\n");
>> +		ctl2 &= ~BLM_PWM_ENABLE;
>> +		I915_WRITE(BLC_PWM_CTL2, ctl2);
>> +	}
>>  
>> -	tmp &= ~BLM_PIPE_SELECT;
>> -	tmp |= BLM_PIPE(pipe);
>> -	tmp &= ~BLM_PWM_ENABLE;
>> +	freq = panel->backlight.max;
>> +	if (panel->backlight.combination_mode)
>> +		freq /= 0xff;
>>  
>> -	I915_WRITE(BLC_PWM_CTL2, tmp);
>> -	POSTING_READ(BLC_PWM_CTL2);
>> -	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
>> +	ctl = freq << 16;
>> +	I915_WRITE(BLC_PWM_CTL, ctl);
>>  
>> +	/* XXX: combine this into above write? */
>>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>> +
>> +	ctl2 = BLM_PIPE(pipe);
>> +	if (panel->backlight.combination_mode)
>> +		ctl2 |= BLM_COMBINATION_MODE;
>> +	if (panel->backlight.active_low_pwm)
>> +		ctl2 |= BLM_POLARITY_I965;
>> +	I915_WRITE(BLC_PWM_CTL2, ctl2);
>> +	POSTING_READ(BLC_PWM_CTL2);
>> +	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
>>  }
>>  
>>  static void vlv_enable_backlight(struct intel_connector *connector)
>> @@ -799,23 +828,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_panel *panel = &connector->panel;
>>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>> -	u32 tmp;
>> +	u32 ctl, ctl2;
>>  
>> -	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
>> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
>> +	if (ctl2 & BLM_PWM_ENABLE) {
>> +		WARN(1, "backlight already enabled\n");
>> +		ctl2 &= ~BLM_PWM_ENABLE;
>> +		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
>> +	}
>>  
>> -	/* Note that this can also get called through dpms changes. And
>> -	 * we don't track the backlight dpms state, hence check whether
>> -	 * we have to do anything first. */
>> -	if (tmp & BLM_PWM_ENABLE)
>> -		return;
>> +	ctl = panel->backlight.max << 16;
>> +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
>>  
>> -	tmp &= ~BLM_PWM_ENABLE;
>> +	/* XXX: combine this into above write? */
>> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>>  
>> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
>> +	ctl2 = 0;
>> +	if (panel->backlight.active_low_pwm)
>> +		ctl2 |= BLM_POLARITY_I965;
>> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
>>  	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
>> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
>> -
>> -	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
>>  }
>>  
>>  void intel_panel_enable_backlight(struct intel_connector *connector)
>

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 10/13] drm/i915: gather backlight information at setup
  2013-11-14  5:19     ` Jani Nikula
@ 2013-11-14  8:22       ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-14  8:22 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Thu, 2013-11-14 at 07:19 +0200, Jani Nikula wrote:
> On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> > On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> >> Prepare for being able to use the information at enable.
> >> 
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_drv.h   |    2 ++
> >>  drivers/gpu/drm/i915/intel_panel.c |   68 +++++++++++++++++++++++++++++-------
> >>  2 files changed, 58 insertions(+), 12 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> >> index 7384a7b..6f2bc82 100644
> >> --- a/drivers/gpu/drm/i915/intel_drv.h
> >> +++ b/drivers/gpu/drm/i915/intel_drv.h
> >> @@ -163,6 +163,8 @@ struct intel_panel {
> >>  		u32 level;
> >>  		u32 max;
> >>  		bool enabled;
> >> +		bool combination_mode;	/* gen 2/4 only */
> >> +		bool active_low_pwm;
> >>  		struct backlight_device *device;
> >>  	} backlight;
> >>  };
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index 3dd9f57d..0e8f0a3 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -490,13 +490,14 @@ static u32 i9xx_get_backlight(struct intel_connector *connector)
> >>  {
> >>  	struct drm_device *dev = connector->base.dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> +	struct intel_panel *panel = &connector->panel;
> >>  	u32 val;
> >>  
> >>  	val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
> >>  	if (INTEL_INFO(dev)->gen < 4)
> >>  		val >>= 1;
> >>  
> >> -	if (is_backlight_combination_mode(dev)) {
> >> +	if (panel->backlight.combination_mode) {
> >>  		u8 lbpc;
> >>  
> >>  		pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc);
> >> @@ -558,7 +559,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level)
> >>  
> >>  	WARN_ON(panel->backlight.max == 0);
> >>  
> >> -	if (is_backlight_combination_mode(dev)) {
> >> +	if (panel->backlight.combination_mode) {
> >>  		u8 lbpc;
> >>  
> >>  		lbpc = level * 0xfe / panel->backlight.max + 1;
> >> @@ -966,46 +967,84 @@ static void intel_backlight_device_unregister(struct intel_connector *connector)
> >>   */
> >>  static int pch_setup_backlight(struct intel_connector *connector)
> >>  {
> >> +	struct drm_device *dev = connector->base.dev;
> >> +	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >> -	u32 val;
> >> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
> >>  
> >> -	panel->backlight.max = pch_get_max_backlight(connector);
> >> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
> >> +	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
> >> +
> >> +	pch_ctl2 = I915_READ(BLC_PWM_PCH_CTL2);
> >> +	panel->backlight.max = pch_ctl2 >> 16;
> >>  	if (!panel->backlight.max)
> >>  		return -ENODEV;
> >>  
> >>  	val = pch_get_backlight(connector);
> >>  	panel->backlight.level = intel_panel_compute_brightness(connector, val);
> >>  
> >> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> >> +	panel->backlight.enabled = (cpu_ctl2 & BLM_PWM_ENABLE) &&
> >> +		(pch_ctl1 & BLM_PCH_PWM_ENABLE) && panel->backlight.level != 0;
> >
> > Don't we need to check here for QUIRK_NO_PCH_PWM_ENABLE?
> 
> Up front, I think the quirk is bogus, and it breaks machines.
> 
> Even if *we* don't set BLM_PCH_PWM_ENABLE on quirked machines, we just
> expect the BIOS to have done it. 

Ok. I checked the commit adding the quirk, which only says: "Some
machines suffer from non-functional backlight controls if
BLM_PCH_PWM_ENABLE is set", so from that this wasn't clear.

> So for checking whether the backlight is enabled, this should be
accurate.

Ok, in that case the patch looks ok to me:

Reviewed-by: Imre Deak <imre.deak@intel.com>

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 11/13] drm/i915: do full backlight setup at enable time
  2013-11-14  5:43     ` Jani Nikula
@ 2013-11-14  8:27       ` Daniel Vetter
  2013-11-14  8:28       ` Imre Deak
  1 sibling, 0 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-14  8:27 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Thu, Nov 14, 2013 at 07:43:07AM +0200, Jani Nikula wrote:
> On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> > On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> >> We should now have all the information we need to do a full
> >> initialization of the backlight registers.
> >> 
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_panel.c |  145 ++++++++++++++++++++++--------------
> >>  1 file changed, 89 insertions(+), 56 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index 0e8f0a3..da088e3 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -719,50 +719,71 @@ static void pch_enable_backlight(struct intel_connector *connector)
> >>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> >>  	enum transcoder cpu_transcoder =
> >>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> >> -	u32 tmp;
> >> -
> >> -	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> >> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
> >>  
> >> -	/* Note that this can also get called through dpms changes. And
> >> -	 * we don't track the backlight dpms state, hence check whether
> >> -	 * we have to do anything first. */
> >> -	if (tmp & BLM_PWM_ENABLE)
> >> -		return;
> >> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> >> +	if (cpu_ctl2 & BLM_PWM_ENABLE) {
> >> +		WARN(1, "cpu backlight already enabled\n");
> >> +		cpu_ctl2 &= ~BLM_PWM_ENABLE;
> >> +		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
> >> +	}
> >>  
> >> -	if (INTEL_INFO(dev)->num_pipes == 3)
> >> -		tmp &= ~BLM_PIPE_SELECT_IVB;
> >> -	else
> >> -		tmp &= ~BLM_PIPE_SELECT;
> >> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
> >> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> >> +		DRM_DEBUG_KMS("pch backlight already enabled\n");
> >> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> >> +		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> >> +	}
> >>  
> >>  	if (cpu_transcoder == TRANSCODER_EDP)
> >> -		tmp |= BLM_TRANSCODER_EDP;
> >> +		cpu_ctl2 = BLM_TRANSCODER_EDP;
> >>  	else
> >> -		tmp |= BLM_PIPE(cpu_transcoder);
> >> -	tmp &= ~BLM_PWM_ENABLE;
> >> -
> >> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
> >> +		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
> >> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
> >>  	POSTING_READ(BLC_PWM_CPU_CTL2);
> >> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
> >> -
> >> -	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> >> -		tmp = I915_READ(BLC_PWM_PCH_CTL1);
> >> -		tmp |= BLM_PCH_PWM_ENABLE;
> >> -		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> >> -		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> >> -	}
> >
> > Like in the previous patch, why is this removed? If the w/a is not
> > needed any more it should be a separate patch.
> 
> As I said, I think the quirk is bogus. With the full backlight setup at
> enable, we shouldn't trust this to have been set by the BIOS. Again, it
> is required to be enabled, even on the machines that supposedly need the
> quirk.
> 
> I expect the new enable sequence to tackle the problems. And any fallout
> we should fix properly, without quirks - and with this series we are
> much more flexible to adjust the sequence on a per platform basis. For
> example, I was able to test on an IVB that we can't set the backlight
> duty cycle until the cpu pwm has been enabled (hence the comment
> below). But we do it the before the pch pwm enable.
> 
> All that said, maybe it should be a separate patch.

Yeah, and then we can also rip out the quirk entries and tables with it,
too. Also maybe mention findings like the one about the cpu pwm register
in the commit message quickly.
-Daniel

> 
> 
> BR,
> Jani.
> 
> >
> >> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
> >>  
> >> -	/*
> >> -	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> >> -	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> >> -	 * registers are set.
> >> -	 */
> >> +	/* This won't stick until the above enable. */
> >>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >> +
> >> +	pch_ctl2 = panel->backlight.max << 16;
> >> +	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
> >> +
> >> +	pch_ctl1 = 0;
> >> +	if (panel->backlight.active_low_pwm)
> >> +		pch_ctl1 |= BLM_PCH_POLARITY;
> >> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> >> +	POSTING_READ(BLC_PWM_PCH_CTL1);
> >> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
> >>  }
> >>  
> >>  static void i9xx_enable_backlight(struct intel_connector *connector)
> >>  {
> >> +	struct drm_device *dev = connector->base.dev;
> >> +	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >> +	u32 ctl, freq;
> >>  
> >> +	ctl = I915_READ(BLC_PWM_CTL);
> >> +	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
> >> +		WARN(1, "backlight already enabled\n");
> >> +		I915_WRITE(BLC_PWM_CTL, 0);
> >> +	}
> >> +
> >> +	freq = panel->backlight.max;
> >> +	if (panel->backlight.combination_mode)
> >> +		freq /= 0xff;
> >> +
> >> +	ctl = freq << 17;
> >> +	if (IS_GEN2(dev) && panel->backlight.combination_mode)
> >> +		ctl |= BLM_LEGACY_MODE;
> >> +	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
> >> +		ctl |= BLM_POLARITY_PNV;
> >> +
> >> +	I915_WRITE(BLC_PWM_CTL, ctl);
> >> +	POSTING_READ(BLC_PWM_CTL);
> >> +
> >> +	/* XXX: combine this into above write? */
> >>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >>  }
> >>  
> >> @@ -772,25 +793,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> >> -	u32 tmp;
> >> -
> >> -	tmp = I915_READ(BLC_PWM_CTL2);
> >> +	u32 ctl, ctl2, freq;
> >>  
> >> -	/* Note that this can also get called through dpms changes. And
> >> -	 * we don't track the backlight dpms state, hence check whether
> >> -	 * we have to do anything first. */
> >> -	if (tmp & BLM_PWM_ENABLE)
> >> -		return;
> >> +	ctl2 = I915_READ(BLC_PWM_CTL2);
> >> +	if (ctl2 & BLM_PWM_ENABLE) {
> >> +		WARN(1, "backlight already enabled\n");
> >> +		ctl2 &= ~BLM_PWM_ENABLE;
> >> +		I915_WRITE(BLC_PWM_CTL2, ctl2);
> >> +	}
> >>  
> >> -	tmp &= ~BLM_PIPE_SELECT;
> >> -	tmp |= BLM_PIPE(pipe);
> >> -	tmp &= ~BLM_PWM_ENABLE;
> >> +	freq = panel->backlight.max;
> >> +	if (panel->backlight.combination_mode)
> >> +		freq /= 0xff;
> >>  
> >> -	I915_WRITE(BLC_PWM_CTL2, tmp);
> >> -	POSTING_READ(BLC_PWM_CTL2);
> >> -	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> >> +	ctl = freq << 16;
> >> +	I915_WRITE(BLC_PWM_CTL, ctl);
> >>  
> >> +	/* XXX: combine this into above write? */
> >>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >> +
> >> +	ctl2 = BLM_PIPE(pipe);
> >> +	if (panel->backlight.combination_mode)
> >> +		ctl2 |= BLM_COMBINATION_MODE;
> >> +	if (panel->backlight.active_low_pwm)
> >> +		ctl2 |= BLM_POLARITY_I965;
> >> +	I915_WRITE(BLC_PWM_CTL2, ctl2);
> >> +	POSTING_READ(BLC_PWM_CTL2);
> >> +	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
> >>  }
> >>  
> >>  static void vlv_enable_backlight(struct intel_connector *connector)
> >> @@ -799,23 +828,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> >> -	u32 tmp;
> >> +	u32 ctl, ctl2;
> >>  
> >> -	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> >> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> >> +	if (ctl2 & BLM_PWM_ENABLE) {
> >> +		WARN(1, "backlight already enabled\n");
> >> +		ctl2 &= ~BLM_PWM_ENABLE;
> >> +		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
> >> +	}
> >>  
> >> -	/* Note that this can also get called through dpms changes. And
> >> -	 * we don't track the backlight dpms state, hence check whether
> >> -	 * we have to do anything first. */
> >> -	if (tmp & BLM_PWM_ENABLE)
> >> -		return;
> >> +	ctl = panel->backlight.max << 16;
> >> +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
> >>  
> >> -	tmp &= ~BLM_PWM_ENABLE;
> >> +	/* XXX: combine this into above write? */
> >> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >>  
> >> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
> >> +	ctl2 = 0;
> >> +	if (panel->backlight.active_low_pwm)
> >> +		ctl2 |= BLM_POLARITY_I965;
> >> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
> >>  	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
> >> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
> >> -
> >> -	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
> >>  }
> >>  
> >>  void intel_panel_enable_backlight(struct intel_connector *connector)
> >
> 
> -- 
> Jani Nikula, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 11/13] drm/i915: do full backlight setup at enable time
  2013-11-14  5:43     ` Jani Nikula
  2013-11-14  8:27       ` Daniel Vetter
@ 2013-11-14  8:28       ` Imre Deak
  1 sibling, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-14  8:28 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Thu, 2013-11-14 at 07:43 +0200, Jani Nikula wrote:
> On Wed, 13 Nov 2013, Imre Deak <imre.deak@intel.com> wrote:
> > On Fri, 2013-11-08 at 16:49 +0200, Jani Nikula wrote:
> >> We should now have all the information we need to do a full
> >> initialization of the backlight registers.
> >> 
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_panel.c |  145 ++++++++++++++++++++++--------------
> >>  1 file changed, 89 insertions(+), 56 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index 0e8f0a3..da088e3 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -719,50 +719,71 @@ static void pch_enable_backlight(struct intel_connector *connector)
> >>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> >>  	enum transcoder cpu_transcoder =
> >>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> >> -	u32 tmp;
> >> -
> >> -	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> >> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
> >>  
> >> -	/* Note that this can also get called through dpms changes. And
> >> -	 * we don't track the backlight dpms state, hence check whether
> >> -	 * we have to do anything first. */
> >> -	if (tmp & BLM_PWM_ENABLE)
> >> -		return;
> >> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> >> +	if (cpu_ctl2 & BLM_PWM_ENABLE) {
> >> +		WARN(1, "cpu backlight already enabled\n");
> >> +		cpu_ctl2 &= ~BLM_PWM_ENABLE;
> >> +		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
> >> +	}
> >>  
> >> -	if (INTEL_INFO(dev)->num_pipes == 3)
> >> -		tmp &= ~BLM_PIPE_SELECT_IVB;
> >> -	else
> >> -		tmp &= ~BLM_PIPE_SELECT;
> >> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
> >> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> >> +		DRM_DEBUG_KMS("pch backlight already enabled\n");
> >> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> >> +		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> >> +	}
> >>  
> >>  	if (cpu_transcoder == TRANSCODER_EDP)
> >> -		tmp |= BLM_TRANSCODER_EDP;
> >> +		cpu_ctl2 = BLM_TRANSCODER_EDP;
> >>  	else
> >> -		tmp |= BLM_PIPE(cpu_transcoder);
> >> -	tmp &= ~BLM_PWM_ENABLE;
> >> -
> >> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
> >> +		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
> >> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
> >>  	POSTING_READ(BLC_PWM_CPU_CTL2);
> >> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
> >> -
> >> -	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> >> -		tmp = I915_READ(BLC_PWM_PCH_CTL1);
> >> -		tmp |= BLM_PCH_PWM_ENABLE;
> >> -		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> >> -		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> >> -	}
> >
> > Like in the previous patch, why is this removed? If the w/a is not
> > needed any more it should be a separate patch.
> 
> As I said, I think the quirk is bogus. With the full backlight setup at
> enable, we shouldn't trust this to have been set by the BIOS. Again, it
> is required to be enabled, even on the machines that supposedly need the
> quirk.
> 
> I expect the new enable sequence to tackle the problems. And any fallout
> we should fix properly, without quirks - and with this series we are
> much more flexible to adjust the sequence on a per platform basis. For
> example, I was able to test on an IVB that we can't set the backlight
> duty cycle until the cpu pwm has been enabled (hence the comment
> below). But we do it the before the pch pwm enable.
> 
> All that said, maybe it should be a separate patch.

Ok, hm I realize now that removing the quirk might not be trivial since
we depend on the new sequence to do things right. So if you decide so,
I'm also fine leaving it as-is, if it's mentioned in the log. Also since
it's not used elsewhere the quirk should be removed fully.

--Imre

> 
> 
> BR,
> Jani.
> 
> >
> >> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
> >>  
> >> -	/*
> >> -	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> >> -	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> >> -	 * registers are set.
> >> -	 */
> >> +	/* This won't stick until the above enable. */
> >>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >> +
> >> +	pch_ctl2 = panel->backlight.max << 16;
> >> +	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
> >> +
> >> +	pch_ctl1 = 0;
> >> +	if (panel->backlight.active_low_pwm)
> >> +		pch_ctl1 |= BLM_PCH_POLARITY;
> >> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> >> +	POSTING_READ(BLC_PWM_PCH_CTL1);
> >> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
> >>  }
> >>  
> >>  static void i9xx_enable_backlight(struct intel_connector *connector)
> >>  {
> >> +	struct drm_device *dev = connector->base.dev;
> >> +	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >> +	u32 ctl, freq;
> >>  
> >> +	ctl = I915_READ(BLC_PWM_CTL);
> >> +	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
> >> +		WARN(1, "backlight already enabled\n");
> >> +		I915_WRITE(BLC_PWM_CTL, 0);
> >> +	}
> >> +
> >> +	freq = panel->backlight.max;
> >> +	if (panel->backlight.combination_mode)
> >> +		freq /= 0xff;
> >> +
> >> +	ctl = freq << 17;
> >> +	if (IS_GEN2(dev) && panel->backlight.combination_mode)
> >> +		ctl |= BLM_LEGACY_MODE;
> >> +	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
> >> +		ctl |= BLM_POLARITY_PNV;
> >> +
> >> +	I915_WRITE(BLC_PWM_CTL, ctl);
> >> +	POSTING_READ(BLC_PWM_CTL);
> >> +
> >> +	/* XXX: combine this into above write? */
> >>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >>  }
> >>  
> >> @@ -772,25 +793,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> >> -	u32 tmp;
> >> -
> >> -	tmp = I915_READ(BLC_PWM_CTL2);
> >> +	u32 ctl, ctl2, freq;
> >>  
> >> -	/* Note that this can also get called through dpms changes. And
> >> -	 * we don't track the backlight dpms state, hence check whether
> >> -	 * we have to do anything first. */
> >> -	if (tmp & BLM_PWM_ENABLE)
> >> -		return;
> >> +	ctl2 = I915_READ(BLC_PWM_CTL2);
> >> +	if (ctl2 & BLM_PWM_ENABLE) {
> >> +		WARN(1, "backlight already enabled\n");
> >> +		ctl2 &= ~BLM_PWM_ENABLE;
> >> +		I915_WRITE(BLC_PWM_CTL2, ctl2);
> >> +	}
> >>  
> >> -	tmp &= ~BLM_PIPE_SELECT;
> >> -	tmp |= BLM_PIPE(pipe);
> >> -	tmp &= ~BLM_PWM_ENABLE;
> >> +	freq = panel->backlight.max;
> >> +	if (panel->backlight.combination_mode)
> >> +		freq /= 0xff;
> >>  
> >> -	I915_WRITE(BLC_PWM_CTL2, tmp);
> >> -	POSTING_READ(BLC_PWM_CTL2);
> >> -	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> >> +	ctl = freq << 16;
> >> +	I915_WRITE(BLC_PWM_CTL, ctl);
> >>  
> >> +	/* XXX: combine this into above write? */
> >>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >> +
> >> +	ctl2 = BLM_PIPE(pipe);
> >> +	if (panel->backlight.combination_mode)
> >> +		ctl2 |= BLM_COMBINATION_MODE;
> >> +	if (panel->backlight.active_low_pwm)
> >> +		ctl2 |= BLM_POLARITY_I965;
> >> +	I915_WRITE(BLC_PWM_CTL2, ctl2);
> >> +	POSTING_READ(BLC_PWM_CTL2);
> >> +	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
> >>  }
> >>  
> >>  static void vlv_enable_backlight(struct intel_connector *connector)
> >> @@ -799,23 +828,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_panel *panel = &connector->panel;
> >>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> >> -	u32 tmp;
> >> +	u32 ctl, ctl2;
> >>  
> >> -	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> >> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> >> +	if (ctl2 & BLM_PWM_ENABLE) {
> >> +		WARN(1, "backlight already enabled\n");
> >> +		ctl2 &= ~BLM_PWM_ENABLE;
> >> +		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
> >> +	}
> >>  
> >> -	/* Note that this can also get called through dpms changes. And
> >> -	 * we don't track the backlight dpms state, hence check whether
> >> -	 * we have to do anything first. */
> >> -	if (tmp & BLM_PWM_ENABLE)
> >> -		return;
> >> +	ctl = panel->backlight.max << 16;
> >> +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
> >>  
> >> -	tmp &= ~BLM_PWM_ENABLE;
> >> +	/* XXX: combine this into above write? */
> >> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >>  
> >> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
> >> +	ctl2 = 0;
> >> +	if (panel->backlight.active_low_pwm)
> >> +		ctl2 |= BLM_POLARITY_I965;
> >> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
> >>  	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
> >> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
> >> -
> >> -	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> >> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
> >>  }
> >>  
> >>  void intel_panel_enable_backlight(struct intel_connector *connector)
> >
> 

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 11/13] drm/i915: do full backlight setup at enable time
  2013-11-08 14:49 ` [PATCH 11/13] drm/i915: do full backlight setup at enable time Jani Nikula
  2013-11-13 17:53   ` Imre Deak
@ 2013-11-14 10:13   ` Jani Nikula
  2013-11-14 10:46     ` Imre Deak
  2013-11-14 10:14   ` [PATCH 11.5/13] drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE Jani Nikula
  2 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-14 10:13 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

We should now have all the information we need to do a full
initialization of the backlight registers.

v2: Keep QUIRK_NO_PCH_PWM_ENABLE for now (Imre).

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/intel_panel.c |  149 ++++++++++++++++++++++--------------
 1 file changed, 93 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 0e8f0a3..0986472 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -719,50 +719,75 @@ static void pch_enable_backlight(struct intel_connector *connector)
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	enum transcoder cpu_transcoder =
 		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
-	u32 tmp;
-
-	tmp = I915_READ(BLC_PWM_CPU_CTL2);
+	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
 
-	/* Note that this can also get called through dpms changes. And
-	 * we don't track the backlight dpms state, hence check whether
-	 * we have to do anything first. */
-	if (tmp & BLM_PWM_ENABLE)
-		return;
+	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
+	if (cpu_ctl2 & BLM_PWM_ENABLE) {
+		WARN(1, "cpu backlight already enabled\n");
+		cpu_ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
+	}
 
-	if (INTEL_INFO(dev)->num_pipes == 3)
-		tmp &= ~BLM_PIPE_SELECT_IVB;
-	else
-		tmp &= ~BLM_PIPE_SELECT;
+	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+		DRM_DEBUG_KMS("pch backlight already enabled\n");
+		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	}
 
 	if (cpu_transcoder == TRANSCODER_EDP)
-		tmp |= BLM_TRANSCODER_EDP;
+		cpu_ctl2 = BLM_TRANSCODER_EDP;
 	else
-		tmp |= BLM_PIPE(cpu_transcoder);
-	tmp &= ~BLM_PWM_ENABLE;
-
-	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
+		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
+	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
 	POSTING_READ(BLC_PWM_CPU_CTL2);
-	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
-
-	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
-		tmp = I915_READ(BLC_PWM_PCH_CTL1);
-		tmp |= BLM_PCH_PWM_ENABLE;
-		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
-		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
-	}
+	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
 
-	/*
-	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
-	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
-	 * registers are set.
-	 */
+	/* This won't stick until the above enable. */
 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	pch_ctl2 = panel->backlight.max << 16;
+	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
+
+	/* XXX: transitional */
+	if (dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)
+		return;
+
+	pch_ctl1 = 0;
+	if (panel->backlight.active_low_pwm)
+		pch_ctl1 |= BLM_PCH_POLARITY;
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+	POSTING_READ(BLC_PWM_PCH_CTL1);
+	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
 }
 
 static void i9xx_enable_backlight(struct intel_connector *connector)
 {
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
+	u32 ctl, freq;
+
+	ctl = I915_READ(BLC_PWM_CTL);
+	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
+		WARN(1, "backlight already enabled\n");
+		I915_WRITE(BLC_PWM_CTL, 0);
+	}
 
+	freq = panel->backlight.max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
+
+	ctl = freq << 17;
+	if (IS_GEN2(dev) && panel->backlight.combination_mode)
+		ctl |= BLM_LEGACY_MODE;
+	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
+		ctl |= BLM_POLARITY_PNV;
+
+	I915_WRITE(BLC_PWM_CTL, ctl);
+	POSTING_READ(BLC_PWM_CTL);
+
+	/* XXX: combine this into above write? */
 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
@@ -772,25 +797,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
-	u32 tmp;
+	u32 ctl, ctl2, freq;
 
-	tmp = I915_READ(BLC_PWM_CTL2);
+	ctl2 = I915_READ(BLC_PWM_CTL2);
+	if (ctl2 & BLM_PWM_ENABLE) {
+		WARN(1, "backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(BLC_PWM_CTL2, ctl2);
+	}
 
-	/* Note that this can also get called through dpms changes. And
-	 * we don't track the backlight dpms state, hence check whether
-	 * we have to do anything first. */
-	if (tmp & BLM_PWM_ENABLE)
-		return;
+	freq = panel->backlight.max;
+	if (panel->backlight.combination_mode)
+		freq /= 0xff;
 
-	tmp &= ~BLM_PIPE_SELECT;
-	tmp |= BLM_PIPE(pipe);
-	tmp &= ~BLM_PWM_ENABLE;
-
-	I915_WRITE(BLC_PWM_CTL2, tmp);
-	POSTING_READ(BLC_PWM_CTL2);
-	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
+	ctl = freq << 16;
+	I915_WRITE(BLC_PWM_CTL, ctl);
 
+	/* XXX: combine this into above write? */
 	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+
+	ctl2 = BLM_PIPE(pipe);
+	if (panel->backlight.combination_mode)
+		ctl2 |= BLM_COMBINATION_MODE;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	I915_WRITE(BLC_PWM_CTL2, ctl2);
+	POSTING_READ(BLC_PWM_CTL2);
+	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
 }
 
 static void vlv_enable_backlight(struct intel_connector *connector)
@@ -799,23 +832,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
 	enum pipe pipe = intel_get_pipe_from_connector(connector);
-	u32 tmp;
+	u32 ctl, ctl2;
 
-	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
+	if (ctl2 & BLM_PWM_ENABLE) {
+		WARN(1, "backlight already enabled\n");
+		ctl2 &= ~BLM_PWM_ENABLE;
+		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
+	}
 
-	/* Note that this can also get called through dpms changes. And
-	 * we don't track the backlight dpms state, hence check whether
-	 * we have to do anything first. */
-	if (tmp & BLM_PWM_ENABLE)
-		return;
+	ctl = panel->backlight.max << 16;
+	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
 
-	tmp &= ~BLM_PWM_ENABLE;
+	/* XXX: combine this into above write? */
+	intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
-	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
+	ctl2 = 0;
+	if (panel->backlight.active_low_pwm)
+		ctl2 |= BLM_POLARITY_I965;
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
 	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
-	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
-
-	intel_panel_actually_set_backlight(connector, panel->backlight.level);
+	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
 }
 
 void intel_panel_enable_backlight(struct intel_connector *connector)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 11.5/13] drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE
  2013-11-08 14:49 ` [PATCH 11/13] drm/i915: do full backlight setup at enable time Jani Nikula
  2013-11-13 17:53   ` Imre Deak
  2013-11-14 10:13   ` [PATCH v2 " Jani Nikula
@ 2013-11-14 10:14   ` Jani Nikula
  2013-11-14 10:50     ` Imre Deak
  2 siblings, 1 reply; 49+ messages in thread
From: Jani Nikula @ 2013-11-14 10:14 UTC (permalink / raw)
  To: intel-gfx; +Cc: jani.nikula

The quirk was added as what I'd say was a stopgap measure in

commit e85843bec6c2ea7c10ec61238396891cc2b753a9
Author: Kamal Mostafa <kamal@canonical.com>
Date:   Fri Jul 19 15:02:01 2013 -0700

    drm/i915: quirk no PCH_PWM_ENABLE for Dell XPS13 backlight

without really digging into what was going on.

Also, as mentioned in the related bug [1], having the quirk regressed
some of the machines it was supposed to fix to begin with, and there
were patches posted to disable the quirk on such machines [2]!

The fact is, we do need the BLM_PCH_PWM_ENABLE bit set to have
backlight. With the quirk, we've relied on BIOS to have set it, and our
save/restore code to retain it. With the full backlight setup at enable,
we have no place for things that rely on previous state.

With the per platform hooks, we've also made a change in the PCH
platform enable order: setting the backlight duty cycle between CPU and
PCH PWM enable. Some experimenting and

commit 770c12312ad617172b1a65b911d3e6564fc5aca8
Author: Takashi Iwai <tiwai@suse.de>
Date:   Sat Aug 11 08:56:42 2012 +0200

    drm/i915: Fix blank panel at reopening lid

indicate that we can't set the backlight before enabling CPU PWM; the
value just won't stick. But AFAICT we should do it before enabling the
PCH PWM.

Finally, any fallout we should fix properly, preferrably without quirks,
and absolutely without quirks that rely on existing state. With the per
platform hooks have much more flexibility to adjust the sequence as
required by platforms.

[1] https://bugzilla.kernel.org/show_bug.cgi?id=47941
[2] http://lkml.kernel.org/r/1378229848-29113-1-git-send-email-kamal@canonical.com

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 -
 drivers/gpu/drm/i915/intel_display.c |   16 ----------------
 drivers/gpu/drm/i915/intel_panel.c   |    4 ----
 3 files changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c243b8e..e726ab9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -717,7 +717,6 @@ enum intel_sbi_destination {
 #define QUIRK_PIPEA_FORCE (1<<0)
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
-#define QUIRK_NO_PCH_PWM_ENABLE (1<<3)
 
 struct intel_fbdev;
 struct intel_fbc_work;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 25ef080..b9f763c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10456,17 +10456,6 @@ static void quirk_invert_brightness(struct drm_device *dev)
 	DRM_INFO("applying inverted panel brightness quirk\n");
 }
 
-/*
- * Some machines (Dell XPS13) suffer broken backlight controls if
- * BLM_PCH_PWM_ENABLE is set.
- */
-static void quirk_no_pcm_pwm_enable(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE;
-	DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n");
-}
-
 struct intel_quirk {
 	int device;
 	int subsystem_vendor;
@@ -10526,11 +10515,6 @@ static struct intel_quirk intel_quirks[] = {
 	 * seem to use inverted backlight PWM.
 	 */
 	{ 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness },
-
-	/* Dell XPS13 HD Sandy Bridge */
-	{ 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
-	/* Dell XPS13 HD and XPS13 FHD Ivy Bridge */
-	{ 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable },
 };
 
 static void intel_init_quirks(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 0986472..da088e3 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -749,10 +749,6 @@ static void pch_enable_backlight(struct intel_connector *connector)
 	pch_ctl2 = panel->backlight.max << 16;
 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 
-	/* XXX: transitional */
-	if (dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)
-		return;
-
 	pch_ctl1 = 0;
 	if (panel->backlight.active_low_pwm)
 		pch_ctl1 |= BLM_PCH_POLARITY;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 11/13] drm/i915: do full backlight setup at enable time
  2013-11-14 10:13   ` [PATCH v2 " Jani Nikula
@ 2013-11-14 10:46     ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-14 10:46 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7527 bytes --]

On Thu, 2013-11-14 at 12:13 +0200, Jani Nikula wrote:
> We should now have all the information we need to do a full
> initialization of the backlight registers.
> 
> v2: Keep QUIRK_NO_PCH_PWM_ENABLE for now (Imre).
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Looks ok:
Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_panel.c |  149 ++++++++++++++++++++++--------------
>  1 file changed, 93 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 0e8f0a3..0986472 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -719,50 +719,75 @@ static void pch_enable_backlight(struct intel_connector *connector)
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	enum transcoder cpu_transcoder =
>  		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> -	u32 tmp;
> -
> -	tmp = I915_READ(BLC_PWM_CPU_CTL2);
> +	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
>  
> -	/* Note that this can also get called through dpms changes. And
> -	 * we don't track the backlight dpms state, hence check whether
> -	 * we have to do anything first. */
> -	if (tmp & BLM_PWM_ENABLE)
> -		return;
> +	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> +	if (cpu_ctl2 & BLM_PWM_ENABLE) {
> +		WARN(1, "cpu backlight already enabled\n");
> +		cpu_ctl2 &= ~BLM_PWM_ENABLE;
> +		I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
> +	}
>  
> -	if (INTEL_INFO(dev)->num_pipes == 3)
> -		tmp &= ~BLM_PIPE_SELECT_IVB;
> -	else
> -		tmp &= ~BLM_PIPE_SELECT;
> +	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
> +	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
> +		DRM_DEBUG_KMS("pch backlight already enabled\n");
> +		pch_ctl1 &= ~BLM_PCH_PWM_ENABLE;
> +		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> +	}
>  
>  	if (cpu_transcoder == TRANSCODER_EDP)
> -		tmp |= BLM_TRANSCODER_EDP;
> +		cpu_ctl2 = BLM_TRANSCODER_EDP;
>  	else
> -		tmp |= BLM_PIPE(cpu_transcoder);
> -	tmp &= ~BLM_PWM_ENABLE;
> -
> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp);
> +		cpu_ctl2 = BLM_PIPE(cpu_transcoder);
> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
>  	POSTING_READ(BLC_PWM_CPU_CTL2);
> -	I915_WRITE(BLC_PWM_CPU_CTL2, tmp | BLM_PWM_ENABLE);
> -
> -	if (!(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) {
> -		tmp = I915_READ(BLC_PWM_PCH_CTL1);
> -		tmp |= BLM_PCH_PWM_ENABLE;
> -		tmp &= ~BLM_PCH_OVERRIDE_ENABLE;
> -		I915_WRITE(BLC_PWM_PCH_CTL1, tmp);
> -	}
> +	I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 | BLM_PWM_ENABLE);
>  
> -	/*
> -	 * Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
> -	 * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
> -	 * registers are set.
> -	 */
> +	/* This won't stick until the above enable. */
>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +
> +	pch_ctl2 = panel->backlight.max << 16;
> +	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
> +
> +	/* XXX: transitional */
> +	if (dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)
> +		return;
> +
> +	pch_ctl1 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		pch_ctl1 |= BLM_PCH_POLARITY;
> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
> +	POSTING_READ(BLC_PWM_PCH_CTL1);
> +	I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
>  }
>  
>  static void i9xx_enable_backlight(struct intel_connector *connector)
>  {
> +	struct drm_device *dev = connector->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
> +	u32 ctl, freq;
> +
> +	ctl = I915_READ(BLC_PWM_CTL);
> +	if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
> +		WARN(1, "backlight already enabled\n");
> +		I915_WRITE(BLC_PWM_CTL, 0);
> +	}
>  
> +	freq = panel->backlight.max;
> +	if (panel->backlight.combination_mode)
> +		freq /= 0xff;
> +
> +	ctl = freq << 17;
> +	if (IS_GEN2(dev) && panel->backlight.combination_mode)
> +		ctl |= BLM_LEGACY_MODE;
> +	if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm)
> +		ctl |= BLM_POLARITY_PNV;
> +
> +	I915_WRITE(BLC_PWM_CTL, ctl);
> +	POSTING_READ(BLC_PWM_CTL);
> +
> +	/* XXX: combine this into above write? */
>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  }
>  
> @@ -772,25 +797,33 @@ static void i965_enable_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> -	u32 tmp;
> +	u32 ctl, ctl2, freq;
>  
> -	tmp = I915_READ(BLC_PWM_CTL2);
> +	ctl2 = I915_READ(BLC_PWM_CTL2);
> +	if (ctl2 & BLM_PWM_ENABLE) {
> +		WARN(1, "backlight already enabled\n");
> +		ctl2 &= ~BLM_PWM_ENABLE;
> +		I915_WRITE(BLC_PWM_CTL2, ctl2);
> +	}
>  
> -	/* Note that this can also get called through dpms changes. And
> -	 * we don't track the backlight dpms state, hence check whether
> -	 * we have to do anything first. */
> -	if (tmp & BLM_PWM_ENABLE)
> -		return;
> +	freq = panel->backlight.max;
> +	if (panel->backlight.combination_mode)
> +		freq /= 0xff;
>  
> -	tmp &= ~BLM_PIPE_SELECT;
> -	tmp |= BLM_PIPE(pipe);
> -	tmp &= ~BLM_PWM_ENABLE;
> -
> -	I915_WRITE(BLC_PWM_CTL2, tmp);
> -	POSTING_READ(BLC_PWM_CTL2);
> -	I915_WRITE(BLC_PWM_CTL2, tmp | BLM_PWM_ENABLE);
> +	ctl = freq << 16;
> +	I915_WRITE(BLC_PWM_CTL, ctl);
>  
> +	/* XXX: combine this into above write? */
>  	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +
> +	ctl2 = BLM_PIPE(pipe);
> +	if (panel->backlight.combination_mode)
> +		ctl2 |= BLM_COMBINATION_MODE;
> +	if (panel->backlight.active_low_pwm)
> +		ctl2 |= BLM_POLARITY_I965;
> +	I915_WRITE(BLC_PWM_CTL2, ctl2);
> +	POSTING_READ(BLC_PWM_CTL2);
> +	I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE);
>  }
>  
>  static void vlv_enable_backlight(struct intel_connector *connector)
> @@ -799,23 +832,27 @@ static void vlv_enable_backlight(struct intel_connector *connector)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
>  	enum pipe pipe = intel_get_pipe_from_connector(connector);
> -	u32 tmp;
> +	u32 ctl, ctl2;
>  
> -	tmp = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> +	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> +	if (ctl2 & BLM_PWM_ENABLE) {
> +		WARN(1, "backlight already enabled\n");
> +		ctl2 &= ~BLM_PWM_ENABLE;
> +		I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
> +	}
>  
> -	/* Note that this can also get called through dpms changes. And
> -	 * we don't track the backlight dpms state, hence check whether
> -	 * we have to do anything first. */
> -	if (tmp & BLM_PWM_ENABLE)
> -		return;
> +	ctl = panel->backlight.max << 16;
> +	I915_WRITE(VLV_BLC_PWM_CTL(pipe), ctl);
>  
> -	tmp &= ~BLM_PWM_ENABLE;
> +	/* XXX: combine this into above write? */
> +	intel_panel_actually_set_backlight(connector, panel->backlight.level);
>  
> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp);
> +	ctl2 = 0;
> +	if (panel->backlight.active_low_pwm)
> +		ctl2 |= BLM_POLARITY_I965;
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
>  	POSTING_READ(VLV_BLC_PWM_CTL2(pipe));
> -	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp | BLM_PWM_ENABLE);
> -
> -	intel_panel_actually_set_backlight(connector, panel->backlight.level);
> +	I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE);
>  }
>  
>  void intel_panel_enable_backlight(struct intel_connector *connector)


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 11.5/13] drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE
  2013-11-14 10:14   ` [PATCH 11.5/13] drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE Jani Nikula
@ 2013-11-14 10:50     ` Imre Deak
  0 siblings, 0 replies; 49+ messages in thread
From: Imre Deak @ 2013-11-14 10:50 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 4518 bytes --]

On Thu, 2013-11-14 at 12:14 +0200, Jani Nikula wrote:
> The quirk was added as what I'd say was a stopgap measure in
> 
> commit e85843bec6c2ea7c10ec61238396891cc2b753a9
> Author: Kamal Mostafa <kamal@canonical.com>
> Date:   Fri Jul 19 15:02:01 2013 -0700
> 
>     drm/i915: quirk no PCH_PWM_ENABLE for Dell XPS13 backlight
> 
> without really digging into what was going on.
> 
> Also, as mentioned in the related bug [1], having the quirk regressed
> some of the machines it was supposed to fix to begin with, and there
> were patches posted to disable the quirk on such machines [2]!
> 
> The fact is, we do need the BLM_PCH_PWM_ENABLE bit set to have
> backlight. With the quirk, we've relied on BIOS to have set it, and our
> save/restore code to retain it. With the full backlight setup at enable,
> we have no place for things that rely on previous state.
> 
> With the per platform hooks, we've also made a change in the PCH
> platform enable order: setting the backlight duty cycle between CPU and
> PCH PWM enable. Some experimenting and
> 
> commit 770c12312ad617172b1a65b911d3e6564fc5aca8
> Author: Takashi Iwai <tiwai@suse.de>
> Date:   Sat Aug 11 08:56:42 2012 +0200
> 
>     drm/i915: Fix blank panel at reopening lid
> 
> indicate that we can't set the backlight before enabling CPU PWM; the
> value just won't stick. But AFAICT we should do it before enabling the
> PCH PWM.
> 
> Finally, any fallout we should fix properly, preferrably without quirks,
> and absolutely without quirks that rely on existing state. With the per
> platform hooks have much more flexibility to adjust the sequence as
> required by platforms.
> 
> [1] https://bugzilla.kernel.org/show_bug.cgi?id=47941
> [2] http://lkml.kernel.org/r/1378229848-29113-1-git-send-email-kamal@canonical.com
> 
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Thanks for the explanation:
Reviewed-by: Imre Deak <imre.deak@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h      |    1 -
>  drivers/gpu/drm/i915/intel_display.c |   16 ----------------
>  drivers/gpu/drm/i915/intel_panel.c   |    4 ----
>  3 files changed, 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c243b8e..e726ab9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -717,7 +717,6 @@ enum intel_sbi_destination {
>  #define QUIRK_PIPEA_FORCE (1<<0)
>  #define QUIRK_LVDS_SSC_DISABLE (1<<1)
>  #define QUIRK_INVERT_BRIGHTNESS (1<<2)
> -#define QUIRK_NO_PCH_PWM_ENABLE (1<<3)
>  
>  struct intel_fbdev;
>  struct intel_fbc_work;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 25ef080..b9f763c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10456,17 +10456,6 @@ static void quirk_invert_brightness(struct drm_device *dev)
>  	DRM_INFO("applying inverted panel brightness quirk\n");
>  }
>  
> -/*
> - * Some machines (Dell XPS13) suffer broken backlight controls if
> - * BLM_PCH_PWM_ENABLE is set.
> - */
> -static void quirk_no_pcm_pwm_enable(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE;
> -	DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n");
> -}
> -
>  struct intel_quirk {
>  	int device;
>  	int subsystem_vendor;
> @@ -10526,11 +10515,6 @@ static struct intel_quirk intel_quirks[] = {
>  	 * seem to use inverted backlight PWM.
>  	 */
>  	{ 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness },
> -
> -	/* Dell XPS13 HD Sandy Bridge */
> -	{ 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
> -	/* Dell XPS13 HD and XPS13 FHD Ivy Bridge */
> -	{ 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable },
>  };
>  
>  static void intel_init_quirks(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 0986472..da088e3 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -749,10 +749,6 @@ static void pch_enable_backlight(struct intel_connector *connector)
>  	pch_ctl2 = panel->backlight.max << 16;
>  	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
>  
> -	/* XXX: transitional */
> -	if (dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)
> -		return;
> -
>  	pch_ctl1 = 0;
>  	if (panel->backlight.active_low_pwm)
>  		pch_ctl1 |= BLM_PCH_POLARITY;


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2] drm/i915: do not save/restore backlight registers in KMS
  2013-11-13 18:05       ` Imre Deak
@ 2013-11-14 11:22         ` Daniel Vetter
  0 siblings, 0 replies; 49+ messages in thread
From: Daniel Vetter @ 2013-11-14 11:22 UTC (permalink / raw)
  To: Imre Deak; +Cc: Jani Nikula, intel-gfx

On Wed, Nov 13, 2013 at 08:05:40PM +0200, Imre Deak wrote:
> On Wed, 2013-11-13 at 12:56 +0200, Jani Nikula wrote:
> > The backlight enable code now has the smarts to do the right thing. Only
> > do backlight register save/restore in UMS.
> > 
> > Some VLV specific code gets dropped as UMS is not supported on VLV.
> > 
> > v2: Move save/restore to UMS instead of removing completely (Daniel).
> > 
> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> 
> Reviewed-by: Imre Deak <imre.deak@intel.com>

Slurped in the remaining ones, thanks for patches&review.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2013-11-14 11:22 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-08 14:48 [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
2013-11-08 14:48 ` [PATCH 01/13] drm/i915: clean up backlight conditional build Jani Nikula
2013-11-12 21:23   ` Imre Deak
2013-11-08 14:48 ` [PATCH 02/13] drm/i915: make backlight info per-connector Jani Nikula
2013-11-12 21:29   ` Imre Deak
2013-11-08 14:48 ` [PATCH 03/13] drm/i915: make asle notifications update backlight on all connectors Jani Nikula
2013-11-12 21:29   ` Imre Deak
2013-11-08 14:48 ` [PATCH 04/13] drm/i915: handle backlight through chip specific functions Jani Nikula
2013-11-12 21:36   ` Imre Deak
2013-11-12 23:19     ` Daniel Vetter
2013-11-08 14:48 ` [PATCH 05/13] drm/i915: fix gen2-gen3 backlight set Jani Nikula
2013-11-12 22:00   ` Imre Deak
2013-11-13  8:27     ` Jani Nikula
2013-11-13  9:04       ` Daniel Vetter
2013-11-13  9:12       ` Imre Deak
2013-11-08 14:48 ` [PATCH 06/13] drm/i915: vlv does not have pipe field in backlight registers Jani Nikula
2013-11-12 22:00   ` Imre Deak
2013-11-08 14:48 ` [PATCH 07/13] drm/i915: move backlight level setting in enable/disable to hooks Jani Nikula
2013-11-12 22:01   ` Imre Deak
2013-11-08 14:49 ` [PATCH 08/13] drm/i915: use the initialized backlight max value instead of reading it Jani Nikula
2013-11-12 22:42   ` Imre Deak
2013-11-13  8:39     ` Jani Nikula
2013-11-13  9:12       ` Daniel Vetter
2013-11-08 14:49 ` [PATCH 09/13] drm/i915: debug print on backlight register Jani Nikula
2013-11-12 22:48   ` Imre Deak
2013-11-13 10:22     ` Daniel Vetter
2013-11-08 14:49 ` [PATCH 10/13] drm/i915: gather backlight information at setup Jani Nikula
2013-11-13 17:01   ` Imre Deak
2013-11-14  5:19     ` Jani Nikula
2013-11-14  8:22       ` Imre Deak
2013-11-08 14:49 ` [PATCH 11/13] drm/i915: do full backlight setup at enable time Jani Nikula
2013-11-13 17:53   ` Imre Deak
2013-11-14  5:43     ` Jani Nikula
2013-11-14  8:27       ` Daniel Vetter
2013-11-14  8:28       ` Imre Deak
2013-11-14 10:13   ` [PATCH v2 " Jani Nikula
2013-11-14 10:46     ` Imre Deak
2013-11-14 10:14   ` [PATCH 11.5/13] drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE Jani Nikula
2013-11-14 10:50     ` Imre Deak
2013-11-08 14:49 ` [PATCH 12/13] drm/i915: nuke get max backlight functions Jani Nikula
2013-11-13 17:54   ` Imre Deak
2013-11-08 14:49 ` [PATCH 13/13] drm/i915: do not save/restore backlight registers Jani Nikula
2013-11-12 23:25   ` Daniel Vetter
2013-11-13  8:40     ` Jani Nikula
2013-11-13 10:56     ` [PATCH v2] drm/i915: do not save/restore backlight registers in KMS Jani Nikula
2013-11-13 18:05       ` Imre Deak
2013-11-14 11:22         ` Daniel Vetter
2013-11-11  8:36 ` [PATCH 00/13] drm/i915: backlight rewrite Jani Nikula
2013-11-12 21:22 ` Imre Deak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.