diff mbox

[RFC,v5,9/9] drm/i915: Backlight control using CRC PMIC based PWM driver

Message ID 1426177893-17945-10-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
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 | 25 +++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_dsi.h |  3 +++
 2 files changed, 28 insertions(+)

Comments

Ville Syrjälä March 13, 2015, 2:30 p.m. UTC | #1
On Thu, Mar 12, 2015 at 10:01:33PM +0530, Shobhit Kumar wrote:
> 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 | 25 +++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_dsi.h |  3 +++
>  2 files changed, 28 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 219421c..511446f 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -32,6 +32,7 @@
>  #include <drm/drm_mipi_dsi.h>
>  #include <linux/slab.h>
>  #include <linux/gpio/consumer.h>
> +#include <linux/pwm.h>
>  #include "i915_drv.h"
>  #include "intel_drv.h"
>  #include "intel_dsi.h"
> @@ -402,6 +403,10 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
>  
>  		intel_dsi_port_enable(encoder);
>  	}
> +
> +	/* Enable the backlight with default PWM as programmed by BIOS */
> +	pwm_enable(intel_dsi->pwm);
> +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 100);

I suppose we migth want to wrap these in 'if (intel_dsi->pwm)' checks,
or does the pwm subsystem take care of NULL checks for us?

>  }
>  
>  static void intel_dsi_pre_enable(struct intel_encoder *encoder)
> @@ -467,6 +472,11 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder)
>  
>  	DRM_DEBUG_KMS("\n");
>  
> +	/* Disable the backlight */
> +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 0);
> +	usleep_range(2000, 3000);
> +	pwm_disable(intel_dsi->pwm);

ditto

> +
>  	if (is_vid_mode(intel_dsi)) {
>  		/* Send Shutdown command to the panel in LP mode */
>  		for_each_dsi_port(port, intel_dsi->ports)
> @@ -971,6 +981,10 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
>  	if (intel_dsi->gpio_panel)
>  		gpiod_put(intel_dsi->gpio_panel);
>  
> +	/* dispose of the pwm */
> +	if (intel_dsi->pwm)
> +		pwm_put(intel_dsi->pwm);
> +
>  	intel_encoder_destroy(encoder);
>  }
>  
> @@ -1098,6 +1112,17 @@ void intel_dsi_init(struct drm_device *dev)
>  			DRM_ERROR("Failed to own gpio for panel control\n");
>  			intel_dsi->gpio_panel = NULL;
>  		}
> +
> +		/* Get the PWM chip for backlight control */
> +		intel_dsi->pwm = pwm_get(dev->dev, "pwm_backlight");
> +		if (IS_ERR(intel_dsi->pwm)) {
> +			DRM_ERROR("Faild to own the pwm chip\n");
> +			intel_dsi->pwm = NULL;
> +		} else if (pwm_config_alternate(intel_dsi->pwm, 0x7F, 100) < 0) {
> +			DRM_ERROR("Failed to configure the pwm chip\n");
> +			pwm_put(intel_dsi->pwm);
> +			intel_dsi->pwm = NULL;
> +		}
>  	}
>  
>  	intel_encoder->type = INTEL_OUTPUT_DSI;
> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
> index 8be75a7..d8ec9c1 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.h
> +++ b/drivers/gpu/drm/i915/intel_dsi.h
> @@ -52,6 +52,9 @@ struct intel_dsi {
>  	/* GPIO Desc for CRC based Panel control */
>  	struct gpio_desc *gpio_panel;
>  
> +	/* PWM chip */
> +	struct pwm_device *pwm;
> +
>  	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
Daniel Vetter March 13, 2015, 5:20 p.m. UTC | #2
On Fri, Mar 13, 2015 at 04:30:43PM +0200, Ville Syrjälä wrote:
> On Thu, Mar 12, 2015 at 10:01:33PM +0530, Shobhit Kumar wrote:
> > 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 | 25 +++++++++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_dsi.h |  3 +++
> >  2 files changed, 28 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> > index 219421c..511446f 100644
> > --- a/drivers/gpu/drm/i915/intel_dsi.c
> > +++ b/drivers/gpu/drm/i915/intel_dsi.c
> > @@ -32,6 +32,7 @@
> >  #include <drm/drm_mipi_dsi.h>
> >  #include <linux/slab.h>
> >  #include <linux/gpio/consumer.h>
> > +#include <linux/pwm.h>
> >  #include "i915_drv.h"
> >  #include "intel_drv.h"
> >  #include "intel_dsi.h"
> > @@ -402,6 +403,10 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
> >  
> >  		intel_dsi_port_enable(encoder);
> >  	}
> > +
> > +	/* Enable the backlight with default PWM as programmed by BIOS */
> > +	pwm_enable(intel_dsi->pwm);
> > +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 100);
> 
> I suppose we migth want to wrap these in 'if (intel_dsi->pwm)' checks,
> or does the pwm subsystem take care of NULL checks for us?
> 
> >  }
> >  
> >  static void intel_dsi_pre_enable(struct intel_encoder *encoder)
> > @@ -467,6 +472,11 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder)
> >  
> >  	DRM_DEBUG_KMS("\n");
> >  
> > +	/* Disable the backlight */
> > +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 0);
> > +	usleep_range(2000, 3000);
> > +	pwm_disable(intel_dsi->pwm);
> 
> ditto
> 
> > +
> >  	if (is_vid_mode(intel_dsi)) {
> >  		/* Send Shutdown command to the panel in LP mode */
> >  		for_each_dsi_port(port, intel_dsi->ports)
> > @@ -971,6 +981,10 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
> >  	if (intel_dsi->gpio_panel)
> >  		gpiod_put(intel_dsi->gpio_panel);
> >  
> > +	/* dispose of the pwm */
> > +	if (intel_dsi->pwm)
> > +		pwm_put(intel_dsi->pwm);
> > +
> >  	intel_encoder_destroy(encoder);
> >  }
> >  
> > @@ -1098,6 +1112,17 @@ void intel_dsi_init(struct drm_device *dev)
> >  			DRM_ERROR("Failed to own gpio for panel control\n");
> >  			intel_dsi->gpio_panel = NULL;
> >  		}
> > +
> > +		/* Get the PWM chip for backlight control */
> > +		intel_dsi->pwm = pwm_get(dev->dev, "pwm_backlight");
> > +		if (IS_ERR(intel_dsi->pwm)) {
> > +			DRM_ERROR("Faild to own the pwm chip\n");
> > +			intel_dsi->pwm = NULL;

If the i915.ko driver loads before the mfd.ko driver we need to do a
deferred probe here I think. Just failing isn't robust.

This also means that if people don't configure their kernel properly then
we'll fall over here, but meh.
-Daniel

> > +		} else if (pwm_config_alternate(intel_dsi->pwm, 0x7F, 100) < 0) {
> > +			DRM_ERROR("Failed to configure the pwm chip\n");
> > +			pwm_put(intel_dsi->pwm);
> > +			intel_dsi->pwm = NULL;
> > +		}
> >  	}
> >  
> >  	intel_encoder->type = INTEL_OUTPUT_DSI;
> > diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
> > index 8be75a7..d8ec9c1 100644
> > --- a/drivers/gpu/drm/i915/intel_dsi.h
> > +++ b/drivers/gpu/drm/i915/intel_dsi.h
> > @@ -52,6 +52,9 @@ struct intel_dsi {
> >  	/* GPIO Desc for CRC based Panel control */
> >  	struct gpio_desc *gpio_panel;
> >  
> > +	/* PWM chip */
> > +	struct pwm_device *pwm;
> > +
> >  	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
> 
> -- 
> Ville Syrjälä
> Intel OTC
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Shobhit Kumar March 16, 2015, 4:23 a.m. UTC | #3
On 03/13/2015 10:50 PM, Daniel Vetter wrote:
> On Fri, Mar 13, 2015 at 04:30:43PM +0200, Ville Syrjälä wrote:
>> On Thu, Mar 12, 2015 at 10:01:33PM +0530, Shobhit Kumar wrote:
>>> 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 | 25 +++++++++++++++++++++++++
>>>  drivers/gpu/drm/i915/intel_dsi.h |  3 +++
>>>  2 files changed, 28 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
>>> index 219421c..511446f 100644
>>> --- a/drivers/gpu/drm/i915/intel_dsi.c
>>> +++ b/drivers/gpu/drm/i915/intel_dsi.c
>>> @@ -32,6 +32,7 @@
>>>  #include <drm/drm_mipi_dsi.h>
>>>  #include <linux/slab.h>
>>>  #include <linux/gpio/consumer.h>
>>> +#include <linux/pwm.h>
>>>  #include "i915_drv.h"
>>>  #include "intel_drv.h"
>>>  #include "intel_dsi.h"
>>> @@ -402,6 +403,10 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
>>>  
>>>  		intel_dsi_port_enable(encoder);
>>>  	}
>>> +
>>> +	/* Enable the backlight with default PWM as programmed by BIOS */
>>> +	pwm_enable(intel_dsi->pwm);
>>> +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 100);
>>
>> I suppose we migth want to wrap these in 'if (intel_dsi->pwm)' checks,
>> or does the pwm subsystem take care of NULL checks for us?
>>
>>>  }
>>>  
>>>  static void intel_dsi_pre_enable(struct intel_encoder *encoder)
>>> @@ -467,6 +472,11 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder)
>>>  
>>>  	DRM_DEBUG_KMS("\n");
>>>  
>>> +	/* Disable the backlight */
>>> +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 0);
>>> +	usleep_range(2000, 3000);
>>> +	pwm_disable(intel_dsi->pwm);
>>
>> ditto
>>
>>> +
>>>  	if (is_vid_mode(intel_dsi)) {
>>>  		/* Send Shutdown command to the panel in LP mode */
>>>  		for_each_dsi_port(port, intel_dsi->ports)
>>> @@ -971,6 +981,10 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
>>>  	if (intel_dsi->gpio_panel)
>>>  		gpiod_put(intel_dsi->gpio_panel);
>>>  
>>> +	/* dispose of the pwm */
>>> +	if (intel_dsi->pwm)
>>> +		pwm_put(intel_dsi->pwm);
>>> +
>>>  	intel_encoder_destroy(encoder);
>>>  }
>>>  
>>> @@ -1098,6 +1112,17 @@ void intel_dsi_init(struct drm_device *dev)
>>>  			DRM_ERROR("Failed to own gpio for panel control\n");
>>>  			intel_dsi->gpio_panel = NULL;
>>>  		}
>>> +
>>> +		/* Get the PWM chip for backlight control */
>>> +		intel_dsi->pwm = pwm_get(dev->dev, "pwm_backlight");
>>> +		if (IS_ERR(intel_dsi->pwm)) {
>>> +			DRM_ERROR("Faild to own the pwm chip\n");
>>> +			intel_dsi->pwm = NULL;
> 
> If the i915.ko driver loads before the mfd.ko driver we need to do a
> deferred probe here I think. Just failing isn't robust.

The PMIC MFD driver is a boolean if you remember our discussions earlier
and hence I made the PWM driver also a bool config. Given that i915 is a
.ko in default kernel config, perhaps it should not be that big an issue
for now. But I will look into deferred probe as a fail safe.

> 
> This also means that if people don't configure their kernel properly then
> we'll fall over here, but meh.

True.

Regards
Shobhit

> -Daniel
> 
>>> +		} else if (pwm_config_alternate(intel_dsi->pwm, 0x7F, 100) < 0) {
>>> +			DRM_ERROR("Failed to configure the pwm chip\n");
>>> +			pwm_put(intel_dsi->pwm);
>>> +			intel_dsi->pwm = NULL;
>>> +		}
>>>  	}
>>>  
>>>  	intel_encoder->type = INTEL_OUTPUT_DSI;
>>> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
>>> index 8be75a7..d8ec9c1 100644
>>> --- a/drivers/gpu/drm/i915/intel_dsi.h
>>> +++ b/drivers/gpu/drm/i915/intel_dsi.h
>>> @@ -52,6 +52,9 @@ struct intel_dsi {
>>>  	/* GPIO Desc for CRC based Panel control */
>>>  	struct gpio_desc *gpio_panel;
>>>  
>>> +	/* PWM chip */
>>> +	struct pwm_device *pwm;
>>> +
>>>  	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
>>
>> -- 
>> Ville Syrjälä
>> Intel OTC
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
Shobhit Kumar March 16, 2015, 4:33 a.m. UTC | #4
On 03/13/2015 08:00 PM, Ville Syrjälä wrote:
> On Thu, Mar 12, 2015 at 10:01:33PM +0530, Shobhit Kumar wrote:
>> 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 | 25 +++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_dsi.h |  3 +++
>>  2 files changed, 28 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
>> index 219421c..511446f 100644
>> --- a/drivers/gpu/drm/i915/intel_dsi.c
>> +++ b/drivers/gpu/drm/i915/intel_dsi.c
>> @@ -32,6 +32,7 @@
>>  #include <drm/drm_mipi_dsi.h>
>>  #include <linux/slab.h>
>>  #include <linux/gpio/consumer.h>
>> +#include <linux/pwm.h>
>>  #include "i915_drv.h"
>>  #include "intel_drv.h"
>>  #include "intel_dsi.h"
>> @@ -402,6 +403,10 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
>>  
>>  		intel_dsi_port_enable(encoder);
>>  	}
>> +
>> +	/* Enable the backlight with default PWM as programmed by BIOS */
>> +	pwm_enable(intel_dsi->pwm);
>> +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 100);
> 
> I suppose we migth want to wrap these in 'if (intel_dsi->pwm)' checks,
> or does the pwm subsystem take care of NULL checks for us?

PWM subsystem does make the checks. Actually this patch is kind of
prelim patch and I have to still hook up pwm usage in our back-light
infra in intel_panel.c. I have a working patch for that though not
posted yet. Will take care in that final patch for enabling this.

Regards
Shobhit

> 
>>  }
>>  
>>  static void intel_dsi_pre_enable(struct intel_encoder *encoder)
>> @@ -467,6 +472,11 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder)
>>  
>>  	DRM_DEBUG_KMS("\n");
>>  
>> +	/* Disable the backlight */
>> +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 0);
>> +	usleep_range(2000, 3000);
>> +	pwm_disable(intel_dsi->pwm);
> 
> ditto
> 
>> +
>>  	if (is_vid_mode(intel_dsi)) {
>>  		/* Send Shutdown command to the panel in LP mode */
>>  		for_each_dsi_port(port, intel_dsi->ports)
>> @@ -971,6 +981,10 @@ static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
>>  	if (intel_dsi->gpio_panel)
>>  		gpiod_put(intel_dsi->gpio_panel);
>>  
>> +	/* dispose of the pwm */
>> +	if (intel_dsi->pwm)
>> +		pwm_put(intel_dsi->pwm);
>> +
>>  	intel_encoder_destroy(encoder);
>>  }
>>  
>> @@ -1098,6 +1112,17 @@ void intel_dsi_init(struct drm_device *dev)
>>  			DRM_ERROR("Failed to own gpio for panel control\n");
>>  			intel_dsi->gpio_panel = NULL;
>>  		}
>> +
>> +		/* Get the PWM chip for backlight control */
>> +		intel_dsi->pwm = pwm_get(dev->dev, "pwm_backlight");
>> +		if (IS_ERR(intel_dsi->pwm)) {
>> +			DRM_ERROR("Faild to own the pwm chip\n");
>> +			intel_dsi->pwm = NULL;
>> +		} else if (pwm_config_alternate(intel_dsi->pwm, 0x7F, 100) < 0) {
>> +			DRM_ERROR("Failed to configure the pwm chip\n");
>> +			pwm_put(intel_dsi->pwm);
>> +			intel_dsi->pwm = NULL;
>> +		}
>>  	}
>>  
>>  	intel_encoder->type = INTEL_OUTPUT_DSI;
>> diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
>> index 8be75a7..d8ec9c1 100644
>> --- a/drivers/gpu/drm/i915/intel_dsi.h
>> +++ b/drivers/gpu/drm/i915/intel_dsi.h
>> @@ -52,6 +52,9 @@ struct intel_dsi {
>>  	/* GPIO Desc for CRC based Panel control */
>>  	struct gpio_desc *gpio_panel;
>>  
>> +	/* PWM chip */
>> +	struct pwm_device *pwm;
>> +
>>  	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
>
Thierry Reding March 24, 2015, 8:59 a.m. UTC | #5
On Fri, Mar 13, 2015 at 04:30:43PM +0200, Ville Syrjälä wrote:
> On Thu, Mar 12, 2015 at 10:01:33PM +0530, Shobhit Kumar wrote:
> > 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 | 25 +++++++++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_dsi.h |  3 +++
> >  2 files changed, 28 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> > index 219421c..511446f 100644
> > --- a/drivers/gpu/drm/i915/intel_dsi.c
> > +++ b/drivers/gpu/drm/i915/intel_dsi.c
> > @@ -32,6 +32,7 @@
> >  #include <drm/drm_mipi_dsi.h>
> >  #include <linux/slab.h>
> >  #include <linux/gpio/consumer.h>
> > +#include <linux/pwm.h>
> >  #include "i915_drv.h"
> >  #include "intel_drv.h"
> >  #include "intel_dsi.h"
> > @@ -402,6 +403,10 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
> >  
> >  		intel_dsi_port_enable(encoder);
> >  	}
> > +
> > +	/* Enable the backlight with default PWM as programmed by BIOS */
> > +	pwm_enable(intel_dsi->pwm);
> > +	pwm_config_alternate(intel_dsi->pwm, 0x7F, 100);
> 
> I suppose we migth want to wrap these in 'if (intel_dsi->pwm)' checks,
> or does the pwm subsystem take care of NULL checks for us?

The PWM core checks for valid PWM devices and will return an error if
you pass in an invalid device. What this is completely missing is any
kind of error checking. But perhaps you don't care about failure here
for this particular platform? It would be useful to debug issues with
black screens and such I can imagine.

Also, though it's admittedly somewhat underdocumented, the typical
sequence of calls should be pwm_config() followed by pwm_enable(). The
reason is that some devices don't support being configured while
enabled. But you may not care about this here since you're always
dealing with a fixed device anyway.

Thierry
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 219421c..511446f 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -32,6 +32,7 @@ 
 #include <drm/drm_mipi_dsi.h>
 #include <linux/slab.h>
 #include <linux/gpio/consumer.h>
+#include <linux/pwm.h>
 #include "i915_drv.h"
 #include "intel_drv.h"
 #include "intel_dsi.h"
@@ -402,6 +403,10 @@  static void intel_dsi_enable(struct intel_encoder *encoder)
 
 		intel_dsi_port_enable(encoder);
 	}
+
+	/* Enable the backlight with default PWM as programmed by BIOS */
+	pwm_enable(intel_dsi->pwm);
+	pwm_config_alternate(intel_dsi->pwm, 0x7F, 100);
 }
 
 static void intel_dsi_pre_enable(struct intel_encoder *encoder)
@@ -467,6 +472,11 @@  static void intel_dsi_pre_disable(struct intel_encoder *encoder)
 
 	DRM_DEBUG_KMS("\n");
 
+	/* Disable the backlight */
+	pwm_config_alternate(intel_dsi->pwm, 0x7F, 0);
+	usleep_range(2000, 3000);
+	pwm_disable(intel_dsi->pwm);
+
 	if (is_vid_mode(intel_dsi)) {
 		/* Send Shutdown command to the panel in LP mode */
 		for_each_dsi_port(port, intel_dsi->ports)
@@ -971,6 +981,10 @@  static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
 	if (intel_dsi->gpio_panel)
 		gpiod_put(intel_dsi->gpio_panel);
 
+	/* dispose of the pwm */
+	if (intel_dsi->pwm)
+		pwm_put(intel_dsi->pwm);
+
 	intel_encoder_destroy(encoder);
 }
 
@@ -1098,6 +1112,17 @@  void intel_dsi_init(struct drm_device *dev)
 			DRM_ERROR("Failed to own gpio for panel control\n");
 			intel_dsi->gpio_panel = NULL;
 		}
+
+		/* Get the PWM chip for backlight control */
+		intel_dsi->pwm = pwm_get(dev->dev, "pwm_backlight");
+		if (IS_ERR(intel_dsi->pwm)) {
+			DRM_ERROR("Faild to own the pwm chip\n");
+			intel_dsi->pwm = NULL;
+		} else if (pwm_config_alternate(intel_dsi->pwm, 0x7F, 100) < 0) {
+			DRM_ERROR("Failed to configure the pwm chip\n");
+			pwm_put(intel_dsi->pwm);
+			intel_dsi->pwm = NULL;
+		}
 	}
 
 	intel_encoder->type = INTEL_OUTPUT_DSI;
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 8be75a7..d8ec9c1 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -52,6 +52,9 @@  struct intel_dsi {
 	/* GPIO Desc for CRC based Panel control */
 	struct gpio_desc *gpio_panel;
 
+	/* PWM chip */
+	struct pwm_device *pwm;
+
 	struct intel_connector *attached_connector;
 
 	/* bit mask of ports being driven */