diff mbox

[RFC,v5,3/9] drm/i915: Use the CRC gpio for panel enable/disable

Message ID 1426177893-17945-4-git-send-email-shobhit.kumar@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kumar, Shobhit March 12, 2015, 4:31 p.m. UTC
The CRC (Crystal Cove) PMIC, controls the panel enable and disable
signals for BYT for dsi panels. This is indicated in the VBT fields. Use
that to initialize and use GPIO based control for these signals.

v2: Use the newer gpiod interface(Alexandre)

CC: Samuel Ortiz <sameo@linux.intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
---
 drivers/gpu/drm/i915/intel_dsi.c | 34 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_dsi.h | 10 ++++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

Comments

Ville Syrjälä March 13, 2015, 2:29 p.m. UTC | #1
On Thu, Mar 12, 2015 at 10:01:27PM +0530, Shobhit Kumar wrote:
> The CRC (Crystal Cove) PMIC, controls the panel enable and disable
> signals for BYT for dsi panels. This is indicated in the VBT fields. Use
> that to initialize and use GPIO based control for these signals.
> 
> v2: Use the newer gpiod interface(Alexandre)

I definitely like how this looks. No pmic specific information has
leaked into i915. I can't really comment on the gpio/pwm specific bits
as I'm all that familiar with them, but based on a cursory look it
seemed pretty nice as well.

Just a few small bikesheds below about the i915 bits.

> 
> CC: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Alexandre Courbot <gnurou@gmail.com>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dsi.c | 34 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_dsi.h | 10 ++++++++++
>  2 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index c8c8b24..219421c 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -31,6 +31,7 @@
>  #include <drm/drm_panel.h>
>  #include <drm/drm_mipi_dsi.h>
>  #include <linux/slab.h>
> +#include <linux/gpio/consumer.h>
>  #include "i915_drv.h"
>  #include "intel_drv.h"
>  #include "intel_dsi.h"
> @@ -415,6 +416,13 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
>  
>  	DRM_DEBUG_KMS("\n");
>  
> +	/* Panel Enable over CRC PMIC */
> +	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC &&
> +						intel_dsi->gpio_panel)

The vbt check here seems redundant.

> +		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
> +
> +	msleep(intel_dsi->panel_on_delay);
> +
>  	/* Disable DPOunit clock gating, can stall pipe
>  	 * and we need DPLL REFA always enabled */
>  	tmp = I915_READ(DPLL(pipe));
> @@ -432,8 +440,6 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
>  	/* put device in ready state */
>  	intel_dsi_device_ready(encoder);
>  
> -	msleep(intel_dsi->panel_on_delay);
> -
>  	drm_panel_prepare(intel_dsi->panel);
>  
>  	for_each_dsi_port(port, intel_dsi->ports)
> @@ -576,6 +582,11 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder)
>  
>  	msleep(intel_dsi->panel_off_delay);
>  	msleep(intel_dsi->panel_pwr_cycle_delay);
> +
> +	/* Panel Disable over CRC PMIC */
> +	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC &&
> +						 intel_dsi->gpio_panel)

ditto

> +		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
>  }
>  
>  static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
> @@ -955,6 +966,11 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
>  		/* XXX: Logically this call belongs in the panel driver. */
>  		drm_panel_remove(intel_dsi->panel);
>  	}
> +
> +	/* dispose of the gpios */
> +	if (intel_dsi->gpio_panel)
> +		gpiod_put(intel_dsi->gpio_panel);
> +
>  	intel_encoder_destroy(encoder);
>  }
>  
> @@ -1070,6 +1086,20 @@ void intel_dsi_init(struct drm_device *dev)
>  		goto err;
>  	}
>  
> +	/*
> +	 * In case of BYT with CRC PMIC, we need to use GPIO for
> +	 * Panel control.
> +	 */
> +	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
> +		intel_dsi->gpio_panel =
> +			gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH);
> +
> +		if (IS_ERR(intel_dsi->gpio_panel)) {
> +			DRM_ERROR("Failed to own gpio for panel control\n");
> +			intel_dsi->gpio_panel = NULL;
> +		}
> +	}
> +
>  	intel_encoder->type = INTEL_OUTPUT_DSI;
>  	intel_encoder->cloneable = 0;
>  	drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
> index 2784ac4..8be75a7 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.h
> +++ b/drivers/gpu/drm/i915/intel_dsi.h
> @@ -29,6 +29,13 @@
>  #include <drm/drm_mipi_dsi.h>
>  #include "intel_drv.h"
>  
> +/* CRC PMIC GPIO Access */
> +#define GPIO_CHIP_NAME		"gpio_crystalcove"
> +#define GPIO_PANEL_EN		94

These defines seem to be unused.

> +
> +#define PPS_BLC_PMIC   0
> +#define PPS_BLC_SOC    1
> +
>  /* Dual Link support */
>  #define DSI_DUAL_LINK_NONE		0
>  #define DSI_DUAL_LINK_FRONT_BACK	1
> @@ -42,6 +49,9 @@ struct intel_dsi {
>  	struct drm_panel *panel;
>  	struct intel_dsi_host *dsi_hosts[I915_MAX_PORTS];
>  
> +	/* GPIO Desc for CRC based Panel control */
> +	struct gpio_desc *gpio_panel;
> +
>  	struct intel_connector *attached_connector;
>  
>  	/* bit mask of ports being driven */
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index c8c8b24..219421c 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -31,6 +31,7 @@ 
 #include <drm/drm_panel.h>
 #include <drm/drm_mipi_dsi.h>
 #include <linux/slab.h>
+#include <linux/gpio/consumer.h>
 #include "i915_drv.h"
 #include "intel_drv.h"
 #include "intel_dsi.h"
@@ -415,6 +416,13 @@  static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 
 	DRM_DEBUG_KMS("\n");
 
+	/* Panel Enable over CRC PMIC */
+	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC &&
+						intel_dsi->gpio_panel)
+		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
+
+	msleep(intel_dsi->panel_on_delay);
+
 	/* Disable DPOunit clock gating, can stall pipe
 	 * and we need DPLL REFA always enabled */
 	tmp = I915_READ(DPLL(pipe));
@@ -432,8 +440,6 @@  static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 	/* put device in ready state */
 	intel_dsi_device_ready(encoder);
 
-	msleep(intel_dsi->panel_on_delay);
-
 	drm_panel_prepare(intel_dsi->panel);
 
 	for_each_dsi_port(port, intel_dsi->ports)
@@ -576,6 +582,11 @@  static void intel_dsi_post_disable(struct intel_encoder *encoder)
 
 	msleep(intel_dsi->panel_off_delay);
 	msleep(intel_dsi->panel_pwr_cycle_delay);
+
+	/* Panel Disable over CRC PMIC */
+	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC &&
+						 intel_dsi->gpio_panel)
+		gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
 }
 
 static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
@@ -955,6 +966,11 @@  static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
 		/* XXX: Logically this call belongs in the panel driver. */
 		drm_panel_remove(intel_dsi->panel);
 	}
+
+	/* dispose of the gpios */
+	if (intel_dsi->gpio_panel)
+		gpiod_put(intel_dsi->gpio_panel);
+
 	intel_encoder_destroy(encoder);
 }
 
@@ -1070,6 +1086,20 @@  void intel_dsi_init(struct drm_device *dev)
 		goto err;
 	}
 
+	/*
+	 * In case of BYT with CRC PMIC, we need to use GPIO for
+	 * Panel control.
+	 */
+	if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
+		intel_dsi->gpio_panel =
+			gpiod_get(dev->dev, "panel", GPIOD_OUT_HIGH);
+
+		if (IS_ERR(intel_dsi->gpio_panel)) {
+			DRM_ERROR("Failed to own gpio for panel control\n");
+			intel_dsi->gpio_panel = NULL;
+		}
+	}
+
 	intel_encoder->type = INTEL_OUTPUT_DSI;
 	intel_encoder->cloneable = 0;
 	drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 2784ac4..8be75a7 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -29,6 +29,13 @@ 
 #include <drm/drm_mipi_dsi.h>
 #include "intel_drv.h"
 
+/* CRC PMIC GPIO Access */
+#define GPIO_CHIP_NAME		"gpio_crystalcove"
+#define GPIO_PANEL_EN		94
+
+#define PPS_BLC_PMIC   0
+#define PPS_BLC_SOC    1
+
 /* Dual Link support */
 #define DSI_DUAL_LINK_NONE		0
 #define DSI_DUAL_LINK_FRONT_BACK	1
@@ -42,6 +49,9 @@  struct intel_dsi {
 	struct drm_panel *panel;
 	struct intel_dsi_host *dsi_hosts[I915_MAX_PORTS];
 
+	/* GPIO Desc for CRC based Panel control */
+	struct gpio_desc *gpio_panel;
+
 	struct intel_connector *attached_connector;
 
 	/* bit mask of ports being driven */