public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH 0/1] drm/i915: DPCD Backlight Control
@ 2015-09-30 14:36 Yetunde Adebisi
  2015-09-30 14:36 ` [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors Yetunde Adebisi
  0 siblings, 1 reply; 5+ messages in thread
From: Yetunde Adebisi @ 2015-09-30 14:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: Yetunde Adebisi

This patch adds support for backlight control using DPCD registers
for eDP displays.

It depends on a previous patch by Jani Nikula to move the backlight 
hooks from dev_priv->display to intel_panel [1]

Yetunde Adebisi (1):
  drm/i915: Add Backlight Control using DPCD for eDP connectors

 drivers/gpu/drm/i915/intel_dp.c    | 185 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h   |   3 +
 drivers/gpu/drm/i915/intel_panel.c |   5 +-
 include/drm/drm_dp_helper.h        |   6 ++
 4 files changed, 198 insertions(+), 1 deletion(-)

-- 
1.9.3

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

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

* [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors
  2015-09-30 14:36 [PATCH 0/1] drm/i915: DPCD Backlight Control Yetunde Adebisi
@ 2015-09-30 14:36 ` Yetunde Adebisi
  2015-10-27 15:56   ` Adebisi, YetundeX
                     ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Yetunde Adebisi @ 2015-09-30 14:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: Yetunde Adebisi, Jani Nikula, Deepak M

This patch adds support for eDP backlight control using DPCD registers to
backlight hooks in intel_panel.

It checks for backlight control over AUX channel capability and sets up
function pointers to get and set the backlight brightness level if
supported.

Cc: Bob Paauwe <bob.j.paauwe@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Deepak M <m.deepak@intel.com>
Signed-off-by: Yetunde Adebisi <yetundex.adebisi@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c    | 185 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h   |   3 +
 drivers/gpu/drm/i915/intel_panel.c |   5 +-
 include/drm/drm_dp_helper.h        |   6 ++
 4 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fa1a524..fc4b896 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -6259,3 +6259,188 @@ void intel_dp_mst_resume(struct drm_device *dev)
 		}
 	}
 }
+
+static uint8_t read_aux_backlight_mode_set_reg(struct intel_dp *intel_dp)
+{
+	uint8_t dpcd_buf = 0;
+
+	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
+			DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+			&dpcd_buf, sizeof(dpcd_buf)) < 0)
+		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
+				DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
+
+	return dpcd_buf;
+}
+
+static bool get_aux_backlight_enable(struct drm_dp_aux *aux)
+{
+	uint8_t read_val = 0;
+
+	if (intel_dp_dpcd_read_wake(aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+			&read_val, sizeof(read_val)) < 0) {
+		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
+				DP_EDP_DISPLAY_CONTROL_REGISTER);
+		}
+	return read_val & DP_EDP_BACKLIGHT_ENABLE;
+}
+
+static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
+{
+	uint8_t reg_val = 0;
+
+	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
+				DP_EDP_DISPLAY_CONTROL_REGISTER,
+				&reg_val, sizeof(reg_val)) < 0) {
+		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
+				DP_EDP_DISPLAY_CONTROL_REGISTER);
+		return;
+	}
+	if (enable)
+		reg_val |= DP_EDP_BACKLIGHT_ENABLE;
+	else
+		reg_val &= ~(DP_EDP_BACKLIGHT_ENABLE);
+
+	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
+			reg_val) < 0) {
+		DRM_DEBUG_KMS("Failed to %s aux backlight\n",
+				enable ? "enable" : "disable");
+	}
+}
+
+/**
+ * Read the current backlight value from DPCD register(s) based
+ * on if 8-bit(MSB) or 16-bit(MSB and LSB) values are supported
+ */
+static uint32_t intel_dp_aux_get_backlight(struct intel_connector *connector)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
+	uint16_t read_val = 0;
+
+	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
+			DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+			&read_val, sizeof(read_val)) < 0) {
+		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
+				DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
+		return 0;
+	}
+	if (intel_dp->aux_blc_use_lsb) {
+		uint8_t val_lsb = 0;
+
+		if (intel_dp_dpcd_read_wake(&intel_dp->aux,
+				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB,
+				&val_lsb, sizeof(val_lsb)) < 0) {
+			DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
+					DP_EDP_BACKLIGHT_BRIGHTNESS_LSB);
+			return 0;
+		}
+		read_val = (read_val << 8 | val_lsb);
+	}
+
+	return read_val;
+}
+
+/**
+ * Sends the current backlight level over the aux channel, checking if its using
+ * 8-bit or 16 bit value (MSB and LSB)
+ */
+static void
+intel_dp_aux_set_backlight(struct intel_connector *connector, u32 level)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
+	uint8_t vals[2] = { 0x0 };
+
+	vals[0] = level;
+	DRM_DEBUG_KMS("Level 0x%x\n", level);
+
+	/* Write the MSB and/or LSB */
+	 if (intel_dp->aux_blc_use_lsb) {
+		vals[0] = (level & 0xFF00) >> 8;
+		vals[1] = (level & 0xFF);
+		if (drm_dp_dpcd_writeb(&intel_dp->aux,
+				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB, vals[1]) < 0) {
+			DRM_DEBUG_KMS("Failed to write aux backlight level\n");
+			return;
+		}
+	 }
+	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
+			vals[0]) < 0) {
+		DRM_DEBUG_KMS("Failed to write aux backlight level\n");
+		return;
+	}
+}
+
+static void intel_dp_aux_enable_backlight(struct intel_connector *connector)
+{
+	set_aux_backlight_enable(intel_attached_dp(&connector->base), true);
+}
+
+static void intel_dp_aux_disable_backlight(struct intel_connector *connector)
+{
+	set_aux_backlight_enable(intel_attached_dp(&connector->base), false);
+}
+
+static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
+			       enum pipe pipe)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
+	struct intel_panel *panel = &connector->panel;
+
+	if (!intel_dp_aux_display_control_capable(connector)) {
+		DRM_DEBUG_KMS("Backlight control over AUX not supported\n");
+		return -ENODEV;
+	}
+
+	if (intel_dp->aux_blc_use_lsb)
+		panel->backlight.max = 0xFFFF;
+	else
+		panel->backlight.max = 0xFF;
+
+	panel->backlight.min = 0;
+
+	panel->backlight.level = intel_dp_aux_get_backlight(connector);
+	panel->backlight.enabled = get_aux_backlight_enable(&intel_dp->aux);
+
+	return 0;
+}
+
+void intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
+{
+	struct intel_panel *panel = &intel_connector->panel;
+
+	panel->backlight.setup = intel_dp_aux_setup_backlight;
+	panel->backlight.enable = intel_dp_aux_enable_backlight;
+	panel->backlight.disable = intel_dp_aux_disable_backlight;
+	panel->backlight.set = intel_dp_aux_set_backlight;
+	panel->backlight.get = intel_dp_aux_get_backlight;
+}
+
+bool intel_dp_aux_display_control_capable(struct intel_connector *connector)
+{
+	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
+	uint8_t dpcd_edp[2] = { 0x0 };
+
+	/* Check the  eDP Display control capabilities registers to determine if
+	 * the panel can support backlight control over the aux channel*/
+	if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_EDP_GENERAL_CAP_1,
+			dpcd_edp, sizeof(dpcd_edp)) < 0) {
+		DRM_DEBUG_KMS("Failed to read DPCD Display Control registers\n");
+		return false;
+	}
+	DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(dpcd_edp), dpcd_edp);
+
+	if (dpcd_edp[0] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE &&
+			(dpcd_edp[0] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE) &&
+			(dpcd_edp[1] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE) &&
+			((read_aux_backlight_mode_set_reg(intel_dp) &
+					DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK))) {
+
+		DRM_DEBUG_KMS("AUX Backlight Control Supported!\n");
+
+		if (dpcd_edp[1] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
+			intel_dp->aux_blc_use_lsb = true;
+
+		return true;
+	}
+	return false;
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 35a65ca..dacbc37 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -747,6 +747,7 @@ struct intel_dp {
 	unsigned long last_power_cycle;
 	unsigned long last_power_on;
 	unsigned long last_backlight_off;
+	bool aux_blc_use_lsb;
 
 	struct notifier_block edp_notifier;
 
@@ -1221,6 +1222,8 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
 		unsigned frontbuffer_bits);
 void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
 void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
+bool intel_dp_aux_display_control_capable(struct intel_connector *connector);
+void intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);
 
 /* intel_dp_mst.c */
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 9adb62b..04eff34 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1685,7 +1685,10 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
 	struct drm_device *dev = intel_connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (IS_BROXTON(dev)) {
+	if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
+		intel_dp_aux_display_control_capable(intel_connector)) {
+			intel_dp_aux_init_backlight_funcs(intel_connector);
+	} else if (IS_BROXTON(dev)) {
 		panel->backlight.setup = bxt_setup_backlight;
 		panel->backlight.enable = bxt_enable_backlight;
 		panel->backlight.disable = bxt_disable_backlight;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 9ec4716..7367e1a 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -455,16 +455,22 @@
 # define DP_EDP_14			    0x03
 
 #define DP_EDP_GENERAL_CAP_1		    0x701
+#define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE      (1 << 0)
+#define DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE           (1 << 2)
 
 #define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP     0x702
+#define DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE   (1 << 1)
+#define DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT        (1 << 2)
 
 #define DP_EDP_GENERAL_CAP_2		    0x703
 
 #define DP_EDP_GENERAL_CAP_3		    0x704    /* eDP 1.4 */
 
 #define DP_EDP_DISPLAY_CONTROL_REGISTER     0x720
+#define DP_EDP_BACKLIGHT_ENABLE                       (1 << 0)
 
 #define DP_EDP_BACKLIGHT_MODE_SET_REGISTER  0x721
+#define DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK 0x2
 
 #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB     0x722
 #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB     0x723
-- 
1.9.3

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

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

* Re: [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors
  2015-09-30 14:36 ` [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors Yetunde Adebisi
@ 2015-10-27 15:56   ` Adebisi, YetundeX
  2015-10-28 20:17   ` Jesse Barnes
  2015-10-29  9:35   ` Jani Nikula
  2 siblings, 0 replies; 5+ messages in thread
From: Adebisi, YetundeX @ 2015-10-27 15:56 UTC (permalink / raw)
  To: intel-gfx@lists.freedesktop.org; +Cc: Nikula, Jani, Deepak, M

Hi All,

Can someone please review this patch from September.

Thank you.

Yetunde

> -----Original Message-----
> From: Adebisi, YetundeX
> Sent: Wednesday, September 30, 2015 3:36 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Adebisi, YetundeX; Paauwe, Bob J; Nikula, Jani; Deepak, M
> Subject: [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP
> connectors
> 
> This patch adds support for eDP backlight control using DPCD registers to
> backlight hooks in intel_panel.
> 
> It checks for backlight control over AUX channel capability and sets up
> function pointers to get and set the backlight brightness level if supported.
> 
> Cc: Bob Paauwe <bob.j.paauwe@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Deepak M <m.deepak@intel.com>
> Signed-off-by: Yetunde Adebisi <yetundex.adebisi@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c    | 185
> +++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h   |   3 +
>  drivers/gpu/drm/i915/intel_panel.c |   5 +-
>  include/drm/drm_dp_helper.h        |   6 ++
>  4 files changed, 198 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c index fa1a524..fc4b896 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -6259,3 +6259,188 @@ void intel_dp_mst_resume(struct drm_device
> *dev)
>  		}
>  	}
>  }
> +
> +static uint8_t read_aux_backlight_mode_set_reg(struct intel_dp
> +*intel_dp) {
> +	uint8_t dpcd_buf = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +			DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
> +			&dpcd_buf, sizeof(dpcd_buf)) < 0)
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
> +
> +	return dpcd_buf;
> +}
> +
> +static bool get_aux_backlight_enable(struct drm_dp_aux *aux) {
> +	uint8_t read_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(aux,
> DP_EDP_DISPLAY_CONTROL_REGISTER,
> +			&read_val, sizeof(read_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_DISPLAY_CONTROL_REGISTER);
> +		}
> +	return read_val & DP_EDP_BACKLIGHT_ENABLE; }
> +
> +static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool
> +enable) {
> +	uint8_t reg_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +				DP_EDP_DISPLAY_CONTROL_REGISTER,
> +				&reg_val, sizeof(reg_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_DISPLAY_CONTROL_REGISTER);
> +		return;
> +	}
> +	if (enable)
> +		reg_val |= DP_EDP_BACKLIGHT_ENABLE;
> +	else
> +		reg_val &= ~(DP_EDP_BACKLIGHT_ENABLE);
> +
> +	if (drm_dp_dpcd_writeb(&intel_dp->aux,
> DP_EDP_DISPLAY_CONTROL_REGISTER,
> +			reg_val) < 0) {
> +		DRM_DEBUG_KMS("Failed to %s aux backlight\n",
> +				enable ? "enable" : "disable");
> +	}
> +}
> +
> +/**
> + * Read the current backlight value from DPCD register(s) based
> + * on if 8-bit(MSB) or 16-bit(MSB and LSB) values are supported  */
> +static uint32_t intel_dp_aux_get_backlight(struct intel_connector
> +*connector) {
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint16_t read_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +			DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
> +			&read_val, sizeof(read_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
> +		return 0;
> +	}
> +	if (intel_dp->aux_blc_use_lsb) {
> +		uint8_t val_lsb = 0;
> +
> +		if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB,
> +				&val_lsb, sizeof(val_lsb)) < 0) {
> +			DRM_DEBUG_KMS("Failed to read DPCD register
> 0x%x\n",
> +
> 	DP_EDP_BACKLIGHT_BRIGHTNESS_LSB);
> +			return 0;
> +		}
> +		read_val = (read_val << 8 | val_lsb);
> +	}
> +
> +	return read_val;
> +}
> +
> +/**
> + * Sends the current backlight level over the aux channel, checking if
> +its using
> + * 8-bit or 16 bit value (MSB and LSB)
> + */
> +static void
> +intel_dp_aux_set_backlight(struct intel_connector *connector, u32
> +level) {
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint8_t vals[2] = { 0x0 };
> +
> +	vals[0] = level;
> +	DRM_DEBUG_KMS("Level 0x%x\n", level);
> +
> +	/* Write the MSB and/or LSB */
> +	 if (intel_dp->aux_blc_use_lsb) {
> +		vals[0] = (level & 0xFF00) >> 8;
> +		vals[1] = (level & 0xFF);
> +		if (drm_dp_dpcd_writeb(&intel_dp->aux,
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB,
> vals[1]) < 0) {
> +			DRM_DEBUG_KMS("Failed to write aux backlight
> level\n");
> +			return;
> +		}
> +	 }
> +	if (drm_dp_dpcd_writeb(&intel_dp->aux,
> DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
> +			vals[0]) < 0) {
> +		DRM_DEBUG_KMS("Failed to write aux backlight level\n");
> +		return;
> +	}
> +}
> +
> +static void intel_dp_aux_enable_backlight(struct intel_connector
> +*connector) {
> +	set_aux_backlight_enable(intel_attached_dp(&connector->base),
> true); }
> +
> +static void intel_dp_aux_disable_backlight(struct intel_connector
> +*connector) {
> +	set_aux_backlight_enable(intel_attached_dp(&connector->base),
> false);
> +}
> +
> +static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
> +			       enum pipe pipe)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (!intel_dp_aux_display_control_capable(connector)) {
> +		DRM_DEBUG_KMS("Backlight control over AUX not
> supported\n");
> +		return -ENODEV;
> +	}
> +
> +	if (intel_dp->aux_blc_use_lsb)
> +		panel->backlight.max = 0xFFFF;
> +	else
> +		panel->backlight.max = 0xFF;
> +
> +	panel->backlight.min = 0;
> +
> +	panel->backlight.level = intel_dp_aux_get_backlight(connector);
> +	panel->backlight.enabled = get_aux_backlight_enable(&intel_dp-
> >aux);
> +
> +	return 0;
> +}
> +
> +void intel_dp_aux_init_backlight_funcs(struct intel_connector
> +*intel_connector) {
> +	struct intel_panel *panel = &intel_connector->panel;
> +
> +	panel->backlight.setup = intel_dp_aux_setup_backlight;
> +	panel->backlight.enable = intel_dp_aux_enable_backlight;
> +	panel->backlight.disable = intel_dp_aux_disable_backlight;
> +	panel->backlight.set = intel_dp_aux_set_backlight;
> +	panel->backlight.get = intel_dp_aux_get_backlight; }
> +
> +bool intel_dp_aux_display_control_capable(struct intel_connector
> +*connector) {
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint8_t dpcd_edp[2] = { 0x0 };
> +
> +	/* Check the  eDP Display control capabilities registers to determine if
> +	 * the panel can support backlight control over the aux channel*/
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> DP_EDP_GENERAL_CAP_1,
> +			dpcd_edp, sizeof(dpcd_edp)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD Display Control
> registers\n");
> +		return false;
> +	}
> +	DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(dpcd_edp),
> dpcd_edp);
> +
> +	if (dpcd_edp[0] &
> DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE &&
> +			(dpcd_edp[0] &
> DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE) &&
> +			(dpcd_edp[1] &
> DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE) &&
> +			((read_aux_backlight_mode_set_reg(intel_dp) &
> +
> 	DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK))) {
> +
> +		DRM_DEBUG_KMS("AUX Backlight Control Supported!\n");
> +
> +		if (dpcd_edp[1] &
> DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
> +			intel_dp->aux_blc_use_lsb = true;
> +
> +		return true;
> +	}
> +	return false;
> +}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index 35a65ca..dacbc37 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -747,6 +747,7 @@ struct intel_dp {
>  	unsigned long last_power_cycle;
>  	unsigned long last_power_on;
>  	unsigned long last_backlight_off;
> +	bool aux_blc_use_lsb;
> 
>  	struct notifier_block edp_notifier;
> 
> @@ -1221,6 +1222,8 @@ void intel_edp_drrs_invalidate(struct drm_device
> *dev,
>  		unsigned frontbuffer_bits);
>  void intel_edp_drrs_flush(struct drm_device *dev, unsigned
> frontbuffer_bits);  void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state
> *pipe_config);
> +bool intel_dp_aux_display_control_capable(struct intel_connector
> +*connector); void intel_dp_aux_init_backlight_funcs(struct
> +intel_connector *intel_connector);
> 
>  /* intel_dp_mst.c */
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int
> conn_id); diff --git a/drivers/gpu/drm/i915/intel_panel.c
> b/drivers/gpu/drm/i915/intel_panel.c
> index 9adb62b..04eff34 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -1685,7 +1685,10 @@ intel_panel_init_backlight_funcs(struct
> intel_panel *panel)
>  	struct drm_device *dev = intel_connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> 
> -	if (IS_BROXTON(dev)) {
> +	if (intel_connector->base.connector_type ==
> DRM_MODE_CONNECTOR_eDP &&
> +		intel_dp_aux_display_control_capable(intel_connector)) {
> +			intel_dp_aux_init_backlight_funcs(intel_connector);
> +	} else if (IS_BROXTON(dev)) {
>  		panel->backlight.setup = bxt_setup_backlight;
>  		panel->backlight.enable = bxt_enable_backlight;
>  		panel->backlight.disable = bxt_disable_backlight; diff --git
> a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index
> 9ec4716..7367e1a 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -455,16 +455,22 @@
>  # define DP_EDP_14			    0x03
> 
>  #define DP_EDP_GENERAL_CAP_1		    0x701
> +#define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE      (1 << 0)
> +#define DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE           (1 << 2)
> 
>  #define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP     0x702
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE   (1 << 1)
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT        (1 << 2)
> 
>  #define DP_EDP_GENERAL_CAP_2		    0x703
> 
>  #define DP_EDP_GENERAL_CAP_3		    0x704    /* eDP 1.4 */
> 
>  #define DP_EDP_DISPLAY_CONTROL_REGISTER     0x720
> +#define DP_EDP_BACKLIGHT_ENABLE                       (1 << 0)
> 
>  #define DP_EDP_BACKLIGHT_MODE_SET_REGISTER  0x721
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK 0x2
> 
>  #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB     0x722
>  #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB     0x723
> --
> 1.9.3

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

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

* Re: [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors
  2015-09-30 14:36 ` [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors Yetunde Adebisi
  2015-10-27 15:56   ` Adebisi, YetundeX
@ 2015-10-28 20:17   ` Jesse Barnes
  2015-10-29  9:35   ` Jani Nikula
  2 siblings, 0 replies; 5+ messages in thread
From: Jesse Barnes @ 2015-10-28 20:17 UTC (permalink / raw)
  To: Yetunde Adebisi, intel-gfx; +Cc: Jani Nikula, Deepak M

On 09/30/2015 07:36 AM, Yetunde Adebisi wrote:
> This patch adds support for eDP backlight control using DPCD registers to
> backlight hooks in intel_panel.
> 
> It checks for backlight control over AUX channel capability and sets up
> function pointers to get and set the backlight brightness level if
> supported.
> 
> Cc: Bob Paauwe <bob.j.paauwe@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Deepak M <m.deepak@intel.com>
> Signed-off-by: Yetunde Adebisi <yetundex.adebisi@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c    | 185 +++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h   |   3 +
>  drivers/gpu/drm/i915/intel_panel.c |   5 +-
>  include/drm/drm_dp_helper.h        |   6 ++
>  4 files changed, 198 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index fa1a524..fc4b896 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -6259,3 +6259,188 @@ void intel_dp_mst_resume(struct drm_device *dev)
>  		}
>  	}
>  }
> +
> +static uint8_t read_aux_backlight_mode_set_reg(struct intel_dp *intel_dp)
> +{
> +	uint8_t dpcd_buf = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +			DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
> +			&dpcd_buf, sizeof(dpcd_buf)) < 0)
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
> +
> +	return dpcd_buf;
> +}
> +
> +static bool get_aux_backlight_enable(struct drm_dp_aux *aux)
> +{
> +	uint8_t read_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
> +			&read_val, sizeof(read_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_DISPLAY_CONTROL_REGISTER);
> +		}
> +	return read_val & DP_EDP_BACKLIGHT_ENABLE;
> +}
> +
> +static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
> +{
> +	uint8_t reg_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +				DP_EDP_DISPLAY_CONTROL_REGISTER,
> +				&reg_val, sizeof(reg_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_DISPLAY_CONTROL_REGISTER);
> +		return;
> +	}
> +	if (enable)
> +		reg_val |= DP_EDP_BACKLIGHT_ENABLE;
> +	else
> +		reg_val &= ~(DP_EDP_BACKLIGHT_ENABLE);
> +
> +	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
> +			reg_val) < 0) {
> +		DRM_DEBUG_KMS("Failed to %s aux backlight\n",
> +				enable ? "enable" : "disable");
> +	}
> +}
> +
> +/**
> + * Read the current backlight value from DPCD register(s) based
> + * on if 8-bit(MSB) or 16-bit(MSB and LSB) values are supported
> + */
> +static uint32_t intel_dp_aux_get_backlight(struct intel_connector *connector)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint16_t read_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +			DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
> +			&read_val, sizeof(read_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
> +		return 0;
> +	}
> +	if (intel_dp->aux_blc_use_lsb) {
> +		uint8_t val_lsb = 0;
> +
> +		if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB,
> +				&val_lsb, sizeof(val_lsb)) < 0) {
> +			DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +					DP_EDP_BACKLIGHT_BRIGHTNESS_LSB);
> +			return 0;
> +		}
> +		read_val = (read_val << 8 | val_lsb);
> +	}
> +
> +	return read_val;
> +}
> +
> +/**
> + * Sends the current backlight level over the aux channel, checking if its using
> + * 8-bit or 16 bit value (MSB and LSB)
> + */
> +static void
> +intel_dp_aux_set_backlight(struct intel_connector *connector, u32 level)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint8_t vals[2] = { 0x0 };
> +
> +	vals[0] = level;
> +	DRM_DEBUG_KMS("Level 0x%x\n", level);
> +
> +	/* Write the MSB and/or LSB */
> +	 if (intel_dp->aux_blc_use_lsb) {
> +		vals[0] = (level & 0xFF00) >> 8;
> +		vals[1] = (level & 0xFF);
> +		if (drm_dp_dpcd_writeb(&intel_dp->aux,
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB, vals[1]) < 0) {
> +			DRM_DEBUG_KMS("Failed to write aux backlight level\n");
> +			return;
> +		}
> +	 }
> +	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
> +			vals[0]) < 0) {
> +		DRM_DEBUG_KMS("Failed to write aux backlight level\n");
> +		return;
> +	}
> +}
> +
> +static void intel_dp_aux_enable_backlight(struct intel_connector *connector)
> +{
> +	set_aux_backlight_enable(intel_attached_dp(&connector->base), true);
> +}
> +
> +static void intel_dp_aux_disable_backlight(struct intel_connector *connector)
> +{
> +	set_aux_backlight_enable(intel_attached_dp(&connector->base), false);
> +}
> +
> +static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
> +			       enum pipe pipe)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (!intel_dp_aux_display_control_capable(connector)) {
> +		DRM_DEBUG_KMS("Backlight control over AUX not supported\n");
> +		return -ENODEV;
> +	}
> +
> +	if (intel_dp->aux_blc_use_lsb)
> +		panel->backlight.max = 0xFFFF;
> +	else
> +		panel->backlight.max = 0xFF;
> +
> +	panel->backlight.min = 0;
> +
> +	panel->backlight.level = intel_dp_aux_get_backlight(connector);
> +	panel->backlight.enabled = get_aux_backlight_enable(&intel_dp->aux);
> +
> +	return 0;
> +}
> +
> +void intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
> +{
> +	struct intel_panel *panel = &intel_connector->panel;
> +
> +	panel->backlight.setup = intel_dp_aux_setup_backlight;
> +	panel->backlight.enable = intel_dp_aux_enable_backlight;
> +	panel->backlight.disable = intel_dp_aux_disable_backlight;
> +	panel->backlight.set = intel_dp_aux_set_backlight;
> +	panel->backlight.get = intel_dp_aux_get_backlight;
> +}
> +
> +bool intel_dp_aux_display_control_capable(struct intel_connector *connector)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint8_t dpcd_edp[2] = { 0x0 };
> +
> +	/* Check the  eDP Display control capabilities registers to determine if
> +	 * the panel can support backlight control over the aux channel*/
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_EDP_GENERAL_CAP_1,
> +			dpcd_edp, sizeof(dpcd_edp)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD Display Control registers\n");
> +		return false;
> +	}
> +	DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(dpcd_edp), dpcd_edp);
> +
> +	if (dpcd_edp[0] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE &&
> +			(dpcd_edp[0] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE) &&
> +			(dpcd_edp[1] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE) &&
> +			((read_aux_backlight_mode_set_reg(intel_dp) &
> +					DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK))) {
> +
> +		DRM_DEBUG_KMS("AUX Backlight Control Supported!\n");
> +
> +		if (dpcd_edp[1] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
> +			intel_dp->aux_blc_use_lsb = true;
> +
> +		return true;
> +	}
> +	return false;
> +}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 35a65ca..dacbc37 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -747,6 +747,7 @@ struct intel_dp {
>  	unsigned long last_power_cycle;
>  	unsigned long last_power_on;
>  	unsigned long last_backlight_off;
> +	bool aux_blc_use_lsb;
>  
>  	struct notifier_block edp_notifier;
>  
> @@ -1221,6 +1222,8 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
>  		unsigned frontbuffer_bits);
>  void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
>  void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
> +bool intel_dp_aux_display_control_capable(struct intel_connector *connector);
> +void intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);
>  
>  /* intel_dp_mst.c */
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 9adb62b..04eff34 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -1685,7 +1685,10 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
>  	struct drm_device *dev = intel_connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (IS_BROXTON(dev)) {
> +	if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
> +		intel_dp_aux_display_control_capable(intel_connector)) {
> +			intel_dp_aux_init_backlight_funcs(intel_connector);
> +	} else if (IS_BROXTON(dev)) {
>  		panel->backlight.setup = bxt_setup_backlight;
>  		panel->backlight.enable = bxt_enable_backlight;
>  		panel->backlight.disable = bxt_disable_backlight;
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 9ec4716..7367e1a 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -455,16 +455,22 @@
>  # define DP_EDP_14			    0x03
>  
>  #define DP_EDP_GENERAL_CAP_1		    0x701
> +#define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE      (1 << 0)
> +#define DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE           (1 << 2)
>  
>  #define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP     0x702
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE   (1 << 1)
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT        (1 << 2)
>  
>  #define DP_EDP_GENERAL_CAP_2		    0x703
>  
>  #define DP_EDP_GENERAL_CAP_3		    0x704    /* eDP 1.4 */
>  
>  #define DP_EDP_DISPLAY_CONTROL_REGISTER     0x720
> +#define DP_EDP_BACKLIGHT_ENABLE                       (1 << 0)
>  
>  #define DP_EDP_BACKLIGHT_MODE_SET_REGISTER  0x721
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK 0x2
>  
>  #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB     0x722
>  #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB     0x723

I don't have the spec for this but assume you've tested it.  The code looks ok, my only worry is that some eDP panels might return a DPCD backlight capability but then just ignore the writes.  But I guess we'll find that out soon enough if we land this.

So:
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>

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

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

* Re: [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors
  2015-09-30 14:36 ` [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors Yetunde Adebisi
  2015-10-27 15:56   ` Adebisi, YetundeX
  2015-10-28 20:17   ` Jesse Barnes
@ 2015-10-29  9:35   ` Jani Nikula
  2 siblings, 0 replies; 5+ messages in thread
From: Jani Nikula @ 2015-10-29  9:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: Yetunde Adebisi, Deepak M

On Wed, 30 Sep 2015, Yetunde Adebisi <yetundex.adebisi@intel.com> wrote:
> This patch adds support for eDP backlight control using DPCD registers to
> backlight hooks in intel_panel.
>
> It checks for backlight control over AUX channel capability and sets up
> function pointers to get and set the backlight brightness level if
> supported.
>
> Cc: Bob Paauwe <bob.j.paauwe@intel.com>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Deepak M <m.deepak@intel.com>
> Signed-off-by: Yetunde Adebisi <yetundex.adebisi@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c    | 185 +++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h   |   3 +
>  drivers/gpu/drm/i915/intel_panel.c |   5 +-
>  include/drm/drm_dp_helper.h        |   6 ++
>  4 files changed, 198 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index fa1a524..fc4b896 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -6259,3 +6259,188 @@ void intel_dp_mst_resume(struct drm_device *dev)
>  		}
>  	}
>  }

I think I'd like all of the below in a separate file. intel_dp.c is
already way too crowded; this is a logical set to have separately.

intel_dp_aux_backlight.c ?

> +
> +static uint8_t read_aux_backlight_mode_set_reg(struct intel_dp *intel_dp)
> +{
> +	uint8_t dpcd_buf = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +			DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
> +			&dpcd_buf, sizeof(dpcd_buf)) < 0)
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_BACKLIGHT_MODE_SET_REGISTER);

You only need this once, I'd just open code it where it's needed.

> +
> +	return dpcd_buf;
> +}
> +
> +static bool get_aux_backlight_enable(struct drm_dp_aux *aux)

At a quick read _enable at the end is confusing, when you're not
enabling but rather getting the enabled status.

is_aux_backlight_enabled() ?

> +{
> +	uint8_t read_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
> +			&read_val, sizeof(read_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_DISPLAY_CONTROL_REGISTER);
> +		}
> +	return read_val & DP_EDP_BACKLIGHT_ENABLE;
> +}
> +
> +static void set_aux_backlight_enable(struct intel_dp *intel_dp, bool enable)
> +{
> +	uint8_t reg_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +				DP_EDP_DISPLAY_CONTROL_REGISTER,
> +				&reg_val, sizeof(reg_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_DISPLAY_CONTROL_REGISTER);
> +		return;
> +	}
> +	if (enable)
> +		reg_val |= DP_EDP_BACKLIGHT_ENABLE;
> +	else
> +		reg_val &= ~(DP_EDP_BACKLIGHT_ENABLE);
> +
> +	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
> +			reg_val) < 0) {
> +		DRM_DEBUG_KMS("Failed to %s aux backlight\n",
> +				enable ? "enable" : "disable");
> +	}
> +}
> +
> +/**
> + * Read the current backlight value from DPCD register(s) based
> + * on if 8-bit(MSB) or 16-bit(MSB and LSB) values are supported

This is not kernel-doc style comment, please use /* instead of /**.

> + */
> +static uint32_t intel_dp_aux_get_backlight(struct intel_connector *connector)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint16_t read_val = 0;
> +
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +			DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
> +			&read_val, sizeof(read_val)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
> +		return 0;
> +	}
> +	if (intel_dp->aux_blc_use_lsb) {
> +		uint8_t val_lsb = 0;
> +
> +		if (intel_dp_dpcd_read_wake(&intel_dp->aux,
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB,
> +				&val_lsb, sizeof(val_lsb)) < 0) {
> +			DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n",
> +					DP_EDP_BACKLIGHT_BRIGHTNESS_LSB);
> +			return 0;
> +		}
> +		read_val = (read_val << 8 | val_lsb);
> +	}

Please rewrite this to use only one read. Maybe parameterize the length
to read (1 or 2 bytes) so you only have one call to dpcd_read, and then
use either 1 or 2 bytes from the result buf.

> +
> +	return read_val;
> +}
> +
> +/**
> + * Sends the current backlight level over the aux channel, checking if its using
> + * 8-bit or 16 bit value (MSB and LSB)

This is not kernel-doc style comment, please use /* instead of /**.

> + */
> +static void
> +intel_dp_aux_set_backlight(struct intel_connector *connector, u32 level)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint8_t vals[2] = { 0x0 };
> +
> +	vals[0] = level;
> +	DRM_DEBUG_KMS("Level 0x%x\n", level);
> +
> +	/* Write the MSB and/or LSB */
> +	 if (intel_dp->aux_blc_use_lsb) {
> +		vals[0] = (level & 0xFF00) >> 8;
> +		vals[1] = (level & 0xFF);
> +		if (drm_dp_dpcd_writeb(&intel_dp->aux,
> +				DP_EDP_BACKLIGHT_BRIGHTNESS_LSB, vals[1]) < 0) {
> +			DRM_DEBUG_KMS("Failed to write aux backlight level\n");
> +			return;
> +		}
> +	 }
> +	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
> +			vals[0]) < 0) {
> +		DRM_DEBUG_KMS("Failed to write aux backlight level\n");
> +		return;
> +	}

Please rewrite this to use only one write, same as for read.

> +}
> +
> +static void intel_dp_aux_enable_backlight(struct intel_connector *connector)
> +{
> +	set_aux_backlight_enable(intel_attached_dp(&connector->base), true);
> +}
> +
> +static void intel_dp_aux_disable_backlight(struct intel_connector *connector)
> +{
> +	set_aux_backlight_enable(intel_attached_dp(&connector->base), false);
> +}
> +
> +static int intel_dp_aux_setup_backlight(struct intel_connector *connector,
> +			       enum pipe pipe)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	struct intel_panel *panel = &connector->panel;
> +
> +	if (!intel_dp_aux_display_control_capable(connector)) {
> +		DRM_DEBUG_KMS("Backlight control over AUX not supported\n");
> +		return -ENODEV;
> +	}

The above shouldn't happen because you don't end up here unless the call
returns true in the first place. You do the aux reads and logging
twice. Please remove the above check.

> +
> +	if (intel_dp->aux_blc_use_lsb)
> +		panel->backlight.max = 0xFFFF;
> +	else
> +		panel->backlight.max = 0xFF;
> +
> +	panel->backlight.min = 0;
> +
> +	panel->backlight.level = intel_dp_aux_get_backlight(connector);
> +	panel->backlight.enabled = get_aux_backlight_enable(&intel_dp->aux);
> +
> +	return 0;
> +}
> +
> +void intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
> +{
> +	struct intel_panel *panel = &intel_connector->panel;
> +
> +	panel->backlight.setup = intel_dp_aux_setup_backlight;
> +	panel->backlight.enable = intel_dp_aux_enable_backlight;
> +	panel->backlight.disable = intel_dp_aux_disable_backlight;
> +	panel->backlight.set = intel_dp_aux_set_backlight;
> +	panel->backlight.get = intel_dp_aux_get_backlight;
> +}
> +
> +bool intel_dp_aux_display_control_capable(struct intel_connector *connector)
> +{
> +	struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
> +	uint8_t dpcd_edp[2] = { 0x0 };
> +
> +	/* Check the  eDP Display control capabilities registers to determine if
> +	 * the panel can support backlight control over the aux channel*/
> +	if (intel_dp_dpcd_read_wake(&intel_dp->aux, DP_EDP_GENERAL_CAP_1,
> +			dpcd_edp, sizeof(dpcd_edp)) < 0) {
> +		DRM_DEBUG_KMS("Failed to read DPCD Display Control registers\n");
> +		return false;
> +	}

I think it would be more useful to read 3 bytes when intel_dp_get_dpcd
reads DP_EDP_DPCD_REV, and store that in intel_dp, maybe as ->dpcd_edp
or something. It's faster to have fewer reads, and it's more generic to
have that instead of adding intel_dp->aux_blc_use_lsb.

> +	DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(dpcd_edp), dpcd_edp);

Also do this at intel_dp_get_dpcd.

> +
> +	if (dpcd_edp[0] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE &&
> +			(dpcd_edp[0] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE) &&
> +			(dpcd_edp[1] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE) &&
> +			((read_aux_backlight_mode_set_reg(intel_dp) &
> +					DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK))) {

This will enable aux backlight control also for the pwm * dpcd product
control mode. I don't think you handle that yet, so please check (reg &
3) == 2, with the proper #defines of course.

> +
> +		DRM_DEBUG_KMS("AUX Backlight Control Supported!\n");
> +
> +		if (dpcd_edp[1] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
> +			intel_dp->aux_blc_use_lsb = true;
> +
> +		return true;
> +	}
> +	return false;
> +}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 35a65ca..dacbc37 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -747,6 +747,7 @@ struct intel_dp {
>  	unsigned long last_power_cycle;
>  	unsigned long last_power_on;
>  	unsigned long last_backlight_off;
> +	bool aux_blc_use_lsb;
>  
>  	struct notifier_block edp_notifier;
>  
> @@ -1221,6 +1222,8 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
>  		unsigned frontbuffer_bits);
>  void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
>  void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
> +bool intel_dp_aux_display_control_capable(struct intel_connector *connector);
> +void intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);
>  
>  /* intel_dp_mst.c */
>  int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 9adb62b..04eff34 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -1685,7 +1685,10 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
>  	struct drm_device *dev = intel_connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (IS_BROXTON(dev)) {
> +	if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
> +		intel_dp_aux_display_control_capable(intel_connector)) {
> +			intel_dp_aux_init_backlight_funcs(intel_connector);

I'd make this step separate from the platform specific if ladded, and if
the aux init function returns without errors, you return early from
intel_panel_init_backlight_funcs. The function could internally check
for capabilities etc. so you only need to expose one func outside of the
module.

> +	} else if (IS_BROXTON(dev)) {
>  		panel->backlight.setup = bxt_setup_backlight;
>  		panel->backlight.enable = bxt_enable_backlight;
>  		panel->backlight.disable = bxt_disable_backlight;
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 9ec4716..7367e1a 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -455,16 +455,22 @@
>  # define DP_EDP_14			    0x03
>  
>  #define DP_EDP_GENERAL_CAP_1		    0x701
> +#define DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAPABLE      (1 << 0)
> +#define DP_EDP_BACKLIGHT_AUX_ENABLE_CAPABLE           (1 << 2)
>  
>  #define DP_EDP_BACKLIGHT_ADJUSTMENT_CAP     0x702
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAPABLE   (1 << 1)
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT        (1 << 2)
>  
>  #define DP_EDP_GENERAL_CAP_2		    0x703
>  
>  #define DP_EDP_GENERAL_CAP_3		    0x704    /* eDP 1.4 */
>  
>  #define DP_EDP_DISPLAY_CONTROL_REGISTER     0x720
> +#define DP_EDP_BACKLIGHT_ENABLE                       (1 << 0)
>  
>  #define DP_EDP_BACKLIGHT_MODE_SET_REGISTER  0x721
> +#define DP_EDP_BACKLIGHT_BRIGHTNESS_CTL_MODE_DPCD_MASK 0x2
>  
>  #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB     0x722
>  #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB     0x723

As I said in my earlier review, the changes to this file must be
separate, and need to be posted to dri-devel mailing list. I've now done
this, adding all of the other relevant defines as well:

http://patchwork.freedesktop.org/patch/msgid/1446109388-4301-1-git-send-email-jani.nikula@intel.com

BR,
Jani.



-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2015-10-29  9:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-30 14:36 [PATCH 0/1] drm/i915: DPCD Backlight Control Yetunde Adebisi
2015-09-30 14:36 ` [PATCH 1/1] drm/i915: Add Backlight Control using DPCD for eDP connectors Yetunde Adebisi
2015-10-27 15:56   ` Adebisi, YetundeX
2015-10-28 20:17   ` Jesse Barnes
2015-10-29  9:35   ` Jani Nikula

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox