On Wed, 29 Apr 2015, Shobhit Kumar shobhit.kumar@intel.com wrote:
Use the CRC PWM device in intel_panel.c and add new MIPI backlight specififc callbacks
v2: Modify to use pwm_config callback
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_drv.h | 5 +++ drivers/gpu/drm/i915/intel_dsi.c | 6 +++ drivers/gpu/drm/i915/intel_panel.c | 92 +++++++++++++++++++++++++++++++++++--- 3 files changed, 98 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 897f17d..b4ebe3b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -182,7 +182,12 @@ struct intel_panel { bool enabled; bool combination_mode; /* gen 2/4 only */ bool active_low_pwm;
/* PWM chip */
struct pwm_device *pwm;
- struct backlight_device *device;
Superfluous whitespace.
} backlight;
void (*backlight_power)(struct intel_connector *, bool enable); diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index be55ffa..83c4540 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -402,6 +402,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder)
intel_dsi_port_enable(encoder);
}
- intel_panel_enable_backlight(intel_dsi->attached_connector);
}
static void intel_dsi_pre_enable(struct intel_encoder *encoder) @@ -466,6 +468,8 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder)
DRM_DEBUG_KMS("\n");
- intel_panel_disable_backlight(intel_dsi->attached_connector);
- if (is_vid_mode(intel_dsi)) { /* Send Shutdown command to the panel in LP mode */ for_each_dsi_port(port, intel_dsi->ports)
@@ -1132,6 +1136,8 @@ void intel_dsi_init(struct drm_device *dev) }
intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
intel_panel_setup_backlight(connector,
(intel_encoder->crtc_mask = (1 << PIPE_A)) ? PIPE_A: PIPE_B);
return;
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 08532d4..5700f6f 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -32,8 +32,12 @@
#include <linux/kernel.h> #include <linux/moduleparam.h> +#include <linux/pwm.h> #include "intel_drv.h"
+#define CRC_PMIC_PWM_PERIOD_NS 21333 +#define CRC_PMIC_PWM_STEPS 255
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode) @@ -536,6 +540,15 @@ static u32 vlv_get_backlight(struct intel_connector *connector) return _vlv_get_backlight(dev, pipe); }
+static u32 vlv_get_mipi_backlight(struct intel_connector *connector)
I'd rather call this either pmic_get_backlight or even pwm_get_backlight because there's nothing really vlv specific about the functions themselves. Same for all of them.
+{
- 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);
Basically we have all the code in place to do the scaling from hw to user. See the note in intel_backlight_device_register. We shouldn't need to add additional scaling all around.
However this can be a future cleanup IMO.
+}
static u32 intel_panel_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -616,6 +629,14 @@ static void vlv_set_backlight(struct intel_connector *connector, u32 level) I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); }
+static void vlv_set_mipi_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) { @@ -741,6 +762,16 @@ static void vlv_disable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); }
+static void vlv_disable_mipi_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; @@ -947,6 +978,16 @@ static void vlv_enable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); }
+static void vlv_enable_mipi_backlight(struct intel_connector *connector) +{
- struct intel_panel *panel = &connector->panel;
- int duty_ns = DIV_ROUND_UP(
panel->backlight.level * CRC_PMIC_PWM_PERIOD_NS, 100);
- pwm_enable(panel->backlight.pwm);
- pwm_config(panel->backlight.pwm, duty_ns, CRC_PMIC_PWM_PERIOD_NS);
All other enable functions call
intel_panel_actually_set_backlight(connector, panel->backlight.level);
to do this. It'll give you logging too.
+}
void intel_panel_enable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -1299,6 +1340,34 @@ static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe return 0; }
+static int vlv_setup_mipi_backlight(struct intel_connector *connector, enum pipe pipe) +{
- struct drm_device *dev = connector->base.dev;
- struct intel_panel *panel = &connector->panel;
- /* Get the PWM chip for backlight control */
- panel->backlight.pwm = pwm_get(dev->dev, "pwm_backlight");
- if (IS_ERR(panel->backlight.pwm)) {
DRM_ERROR("Faild to own the pwm chip\n");
panel->backlight.pwm = NULL;
I think you want to return -ENODEV here. And then you can drop the "else" below and make that a normal if.
- } else if (pwm_config(panel->backlight.pwm, CRC_PMIC_PWM_PERIOD_NS,
CRC_PMIC_PWM_PERIOD_NS) < 0) {
DRM_ERROR("Failed to configure the pwm chip\n");
pwm_put(panel->backlight.pwm);
panel->backlight.pwm = NULL;
return -1;
Save whatever pwm_config returns and return that instead of -1.
- }
- 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 ? true : false;
panel->backlight.level != 0
- return 0;
+}
int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) { struct drm_device *dev = connector->dev; @@ -1363,11 +1432,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 = vlv_setup_mipi_backlight;
dev_priv->display.enable_backlight = vlv_enable_mipi_backlight;
dev_priv->display.disable_backlight = vlv_disable_mipi_backlight;
dev_priv->display.set_backlight = vlv_set_mipi_backlight;
dev_priv->display.get_backlight = vlv_get_mipi_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;}
@@ -1404,6 +1481,11 @@ void intel_panel_fini(struct intel_panel *panel) if (panel->downclock_mode) drm_mode_destroy(intel_connector->base.dev, panel->downclock_mode);
- /* dispose of the pwm */
- if (panel->backlight.pwm)
pwm_put(panel->backlight.pwm);
The cleanup should be in intel_panel_destroy_backlight to match where .pwm is initialized.
BR, Jani.
}
void intel_backlight_register(struct drm_device *dev)
2.1.0