From 97bdb69e04541c5395853011cfd58f660e3b0093 Mon Sep 17 00:00:00 2001 From: Jan-Michael Brummer Date: Sun, 8 Feb 2015 01:07:08 +0100 Subject: [PATCH] Adding baytrail backlight pmic hack --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_params.c | 5 +++++ drivers/gpu/drm/i915/intel_dsi.c | 10 ++++++++++ drivers/gpu/drm/i915/intel_panel.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- drivers/mfd/intel_soc_pmic_core.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/mfd/intel_soc_pmic.h | 4 ++++ 6 files changed, 112 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9d7a715..7f57036 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2309,6 +2309,7 @@ struct i915_params { bool disable_vtd_wa; int use_mmio_flip; bool mmio_debug; + bool force_backlight_pmic; }; extern struct i915_params i915 __read_mostly; diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index c91cb20..44062d6 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -51,6 +51,7 @@ struct i915_params i915 __read_mostly = { .disable_vtd_wa = 0, .use_mmio_flip = 0, .mmio_debug = 0, + .force_backlight_pmic = 0, }; module_param_named(modeset, i915.modeset, int, 0400); @@ -173,3 +174,7 @@ module_param_named(mmio_debug, i915.mmio_debug, bool, 0600); MODULE_PARM_DESC(mmio_debug, "Enable the MMIO debug code (default: false). This may negatively " "affect performance."); + +module_param_named(force_backlight_pmic, i915.force_backlight_pmic, bool, 0600); +MODULE_PARM_DESC(force_backlight_pmic, + "Force backlight adjusting through pmic (default: false)."); diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 0b18407..01f5a33 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -140,6 +140,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_connector *intel_connector = + &intel_dsi->attached_connector->base; int pipe = intel_crtc->pipe; u32 temp; @@ -163,6 +165,8 @@ static void intel_dsi_enable(struct intel_encoder *encoder) I915_WRITE(MIPI_PORT_CTRL(pipe), temp | DPI_ENABLE); POSTING_READ(MIPI_PORT_CTRL(pipe)); } + + intel_panel_enable_backlight(intel_connector); } static void intel_dsi_pre_enable(struct intel_encoder *encoder) @@ -237,6 +241,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_connector *intel_connector = + &intel_dsi->attached_connector->base; int pipe = intel_crtc->pipe; u32 temp; @@ -253,6 +259,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder) msleep(2); } + intel_panel_disable_backlight(intel_connector); + /* Panel commands can be sent when clock is in LP11 */ I915_WRITE(MIPI_DEVICE_READY(pipe), 0x0); @@ -670,6 +678,7 @@ static void intel_dsi_destroy(struct drm_connector *connector) DRM_DEBUG_KMS("\n"); intel_panel_fini(&intel_connector->panel); + intel_panel_destroy_backlight(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -786,6 +795,7 @@ void intel_dsi_init(struct drm_device *dev) fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; intel_panel_init(&intel_connector->panel, fixed_mode, NULL); + intel_panel_setup_backlight(connector, INVALID_PIPE); return; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index dfb783a..e76d3f2 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -31,6 +31,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include "intel_drv.h" void @@ -535,6 +536,11 @@ static u32 vlv_get_backlight(struct intel_connector *connector) return _vlv_get_backlight(dev, pipe); } +static u32 vlv_pmic_get_backlight(struct intel_connector *connector) +{ + return intel_soc_pmic_readb(0x4E); +} + static u32 intel_panel_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -615,6 +621,11 @@ static void vlv_set_backlight(struct intel_connector *connector, u32 level) I915_WRITE(VLV_BLC_PWM_CTL(pipe), tmp | level); } +static void vlv_pmic_set_backlight(struct intel_connector *connector, u32 level) +{ + intel_soc_pmic_writeb(0x4E, level); +} + static void intel_panel_actually_set_backlight(struct intel_connector *connector, u32 level) { @@ -740,6 +751,14 @@ static void vlv_disable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL2(pipe), tmp & ~BLM_PWM_ENABLE); } +static void vlv_pmic_disable_backlight(struct intel_connector *connector) +{ + intel_panel_actually_set_backlight(connector, 0); + + intel_soc_pmic_writeb(0x51, 0x00); + intel_soc_pmic_writeb(0x4B, 0x7F); +} + void intel_panel_disable_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; @@ -946,6 +965,17 @@ static void vlv_enable_backlight(struct intel_connector *connector) I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2 | BLM_PWM_ENABLE); } +static void vlv_pmic_enable_backlight(struct intel_connector *connector) +{ + struct intel_panel *panel = &connector->panel; + + intel_soc_pmic_writeb(0x4B, 0xFF); + intel_soc_pmic_writeb(0x4E, 0xFF); + intel_soc_pmic_writeb(0x51, 0x01); + + 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; @@ -1298,6 +1328,20 @@ static int vlv_setup_backlight(struct intel_connector *connector, enum pipe pipe return 0; } +static int vlv_pmic_setup_backlight(struct intel_connector *connector, enum pipe unused) +{ + struct intel_panel *panel = &connector->panel; + + printk("vlv_pmic_setup_backlight\n"); + panel->backlight.present = 1; + panel->backlight.min = 0x00; + panel->backlight.max = 0xFF; + panel->backlight.level = 20; + panel->backlight.enabled = 1; + + return 0; +} + int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe) { struct drm_device *dev = connector->dev; @@ -1362,11 +1406,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 (i915.force_backlight_pmic) { + dev_priv->display.setup_backlight = vlv_pmic_setup_backlight; + dev_priv->display.enable_backlight = vlv_pmic_enable_backlight; + dev_priv->display.disable_backlight = vlv_pmic_disable_backlight; + dev_priv->display.set_backlight = vlv_pmic_set_backlight; + dev_priv->display.get_backlight = vlv_pmic_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; diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c index df7b064..6047ee0 100644 --- a/drivers/mfd/intel_soc_pmic_core.c +++ b/drivers/mfd/intel_soc_pmic_core.c @@ -26,6 +26,8 @@ #include #include "intel_soc_pmic_core.h" +static struct intel_soc_pmic *pmic_hack = NULL; + /* * On some boards the PMIC interrupt may come from a GPIO line. * Try to lookup the ACPI table and see if such connection exists. If not, @@ -64,6 +66,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, config = (struct intel_soc_pmic_config *)id->driver_data; pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); + pmic_hack = pmic; dev_set_drvdata(dev, pmic); pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config); @@ -135,6 +138,38 @@ static int intel_soc_pmic_resume(struct device *dev) } #endif +int intel_soc_pmic_readb(int reg) +{ + int ret; + unsigned int val; + + if (!pmic_hack) { + ret = -EIO; + } else { + ret = regmap_read(pmic_hack->regmap, reg, &val); + if (!ret) { + ret = val; + } + } + + return ret; +} +EXPORT_SYMBOL(intel_soc_pmic_readb); + +int intel_soc_pmic_writeb(int reg, u8 val) +{ + int ret; + + if (!pmic_hack) { + ret = -EIO; + } else { + ret = regmap_write(pmic_hack->regmap, reg, val); + } + return ret; +} +EXPORT_SYMBOL(intel_soc_pmic_writeb); + + static SIMPLE_DEV_PM_OPS(intel_soc_pmic_pm_ops, intel_soc_pmic_suspend, intel_soc_pmic_resume); diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h index abcbfcf..56b3e71 100644 --- a/include/linux/mfd/intel_soc_pmic.h +++ b/include/linux/mfd/intel_soc_pmic.h @@ -27,4 +27,8 @@ struct intel_soc_pmic { struct regmap_irq_chip_data *irq_chip_data; }; +int intel_soc_pmic_readb(int reg); +int intel_soc_pmic_writeb(int reg, u8 val); + + #endif /* __INTEL_SOC_PMIC_H__ */ -- libgit2 0.21.0