diff options
| author | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
| commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
| tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /drivers/gpu/drm/i915/intel_panel.c | |
| parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
| parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) | |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'drivers/gpu/drm/i915/intel_panel.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 94 | 
1 files changed, 89 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 55aad2322e10..e2ab3f6ed022 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -32,8 +32,11 @@  #include <linux/kernel.h>  #include <linux/moduleparam.h> +#include <linux/pwm.h>  #include "intel_drv.h" +#define CRC_PMIC_PWM_PERIOD_NS	21333 +  void  intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,  		       struct drm_display_mode *adjusted_mode) @@ -544,6 +547,15 @@ static u32 bxt_get_backlight(struct intel_connector *connector)  	return I915_READ(BXT_BLC_PWM_DUTY1);  } +static u32 pwm_get_backlight(struct intel_connector *connector) +{ +	struct intel_panel *panel = &connector->panel; +	int duty_ns; + +	duty_ns = pwm_get_duty_cycle(panel->backlight.pwm); +	return DIV_ROUND_UP(duty_ns * 100, CRC_PMIC_PWM_PERIOD_NS); +} +  static u32 intel_panel_get_backlight(struct intel_connector *connector)  {  	struct drm_device *dev = connector->base.dev; @@ -632,6 +644,14 @@ static void bxt_set_backlight(struct intel_connector *connector, u32 level)  	I915_WRITE(BXT_BLC_PWM_DUTY1, level);  } +static void pwm_set_backlight(struct intel_connector *connector, u32 level) +{ +	struct intel_panel *panel = &connector->panel; +	int duty_ns = DIV_ROUND_UP(level * CRC_PMIC_PWM_PERIOD_NS, 100); + +	pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS); +} +  static void  intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level)  { @@ -769,6 +789,16 @@ static void bxt_disable_backlight(struct intel_connector *connector)  	I915_WRITE(BXT_BLC_PWM_CTL1, tmp & ~BXT_BLC_PWM_ENABLE);  } +static void pwm_disable_backlight(struct intel_connector *connector) +{ +	struct intel_panel *panel = &connector->panel; + +	/* Disable the backlight */ +	pwm_config(panel->backlight.pwm, 0, CRC_PMIC_PWM_PERIOD_NS); +	usleep_range(2000, 3000); +	pwm_disable(panel->backlight.pwm); +} +  void intel_panel_disable_backlight(struct intel_connector *connector)  {  	struct drm_device *dev = connector->base.dev; @@ -1010,6 +1040,14 @@ static void bxt_enable_backlight(struct intel_connector *connector)  	I915_WRITE(BXT_BLC_PWM_CTL1, pwm_ctl | BXT_BLC_PWM_ENABLE);  } +static void pwm_enable_backlight(struct intel_connector *connector) +{ +	struct intel_panel *panel = &connector->panel; + +	pwm_enable(panel->backlight.pwm); +	intel_panel_actually_set_backlight(connector, panel->backlight.level); +} +  void intel_panel_enable_backlight(struct intel_connector *connector)  {  	struct drm_device *dev = connector->base.dev; @@ -1386,6 +1424,40 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)  	return 0;  } +static int pwm_setup_backlight(struct intel_connector *connector, +			       enum pipe pipe) +{ +	struct drm_device *dev = connector->base.dev; +	struct intel_panel *panel = &connector->panel; +	int retval; + +	/* Get the PWM chip for backlight control */ +	panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight"); +	if (IS_ERR(panel->backlight.pwm)) { +		DRM_ERROR("Failed to own the pwm chip\n"); +		panel->backlight.pwm = NULL; +		return -ENODEV; +	} + +	retval = pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS, +			    CRC_PMIC_PWM_PERIOD_NS); +	if (retval < 0) { +		DRM_ERROR("Failed to configure the pwm chip\n"); +		pwm_put(panel->backlight.pwm); +		panel->backlight.pwm = NULL; +		return retval; +	} + +	panel->backlight.min = 0; /* 0% */ +	panel->backlight.max = 100; /* 100% */ +	panel->backlight.level = DIV_ROUND_UP( +				 pwm_get_duty_cycle(panel->backlight.pwm) * 100, +				 CRC_PMIC_PWM_PERIOD_NS); +	panel->backlight.enabled = panel->backlight.level != 0; + +	return 0; +} +  int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)  {  	struct drm_device *dev = connector->dev; @@ -1429,6 +1501,10 @@ 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; +	/* dispose of the pwm */ +	if (panel->backlight.pwm) +		pwm_put(panel->backlight.pwm); +  	panel->backlight.present = false;  } @@ -1456,11 +1532,19 @@ void intel_panel_init_backlight_funcs(struct drm_device *dev)  		dev_priv->display.set_backlight = pch_set_backlight;  		dev_priv->display.get_backlight = pch_get_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; +		if (dev_priv->vbt.has_mipi) { +			dev_priv->display.setup_backlight = pwm_setup_backlight; +			dev_priv->display.enable_backlight = pwm_enable_backlight; +			dev_priv->display.disable_backlight = pwm_disable_backlight; +			dev_priv->display.set_backlight = pwm_set_backlight; +			dev_priv->display.get_backlight = pwm_get_backlight; +		} else { +			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; +		}  	} else if (IS_GEN4(dev)) {  		dev_priv->display.setup_backlight = i965_setup_backlight;  		dev_priv->display.enable_backlight = i965_enable_backlight;  |