提交 1ecc1c6c 编写于 作者: D Deepak M 提交者: Jani Nikula

drm/i915/dsi: CABC support for Panel PWM backlight control

In CABC (Content Adaptive Brightness Control) content grey level
scale can be increased while simultaneously decreasing
brightness of the backlight to achieve same perceived brightness.

The CABC is not standardized and panel vendors are free to follow
their implementation. The CABC implementaion here assumes that the
panels use standard SW register for control.

CABC is supported only when the PWM source for backlight is
from the panel.

v2 by Jani: rebase, renames, check cabc support earlier, etc.
Signed-off-by: NDeepak M <m.deepak@intel.com>
Signed-off-by: NJani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/883faade74d2e598b143221ccc7df6daf4393a13.1461676337.git.jani.nikula@intel.com
上级 90198355
...@@ -1489,11 +1489,28 @@ void intel_dsi_init(struct drm_device *dev) ...@@ -1489,11 +1489,28 @@ void intel_dsi_init(struct drm_device *dev)
intel_dsi->dcs_backlight_ports = BIT(PORT_A) | BIT(PORT_C); intel_dsi->dcs_backlight_ports = BIT(PORT_A) | BIT(PORT_C);
break; break;
} }
switch (dev_priv->vbt.dsi.config->dl_dcs_cabc_ports) {
case DL_DCS_PORT_A:
intel_dsi->dcs_cabc_ports = BIT(PORT_A);
break;
case DL_DCS_PORT_C:
intel_dsi->dcs_cabc_ports = BIT(PORT_C);
break;
default:
case DL_DCS_PORT_A_AND_C:
intel_dsi->dcs_cabc_ports = BIT(PORT_A) | BIT(PORT_C);
break;
}
} else { } else {
intel_dsi->ports = BIT(port); intel_dsi->ports = BIT(port);
intel_dsi->dcs_backlight_ports = BIT(port); intel_dsi->dcs_backlight_ports = BIT(port);
intel_dsi->dcs_cabc_ports = BIT(port);
} }
if (!dev_priv->vbt.dsi.config->cabc_supported)
intel_dsi->dcs_cabc_ports = 0;
/* Create a DSI host (and a device) for each port. */ /* Create a DSI host (and a device) for each port. */
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
struct intel_dsi_host *host; struct intel_dsi_host *host;
......
...@@ -80,6 +80,7 @@ struct intel_dsi { ...@@ -80,6 +80,7 @@ struct intel_dsi {
u8 dual_link; u8 dual_link;
u16 dcs_backlight_ports; u16 dcs_backlight_ports;
u16 dcs_cabc_ports;
u8 pixel_overlap; u8 pixel_overlap;
u32 port_bits; u32 port_bits;
......
...@@ -33,6 +33,12 @@ ...@@ -33,6 +33,12 @@
#define CONTROL_DISPLAY_DD (1 << 3) #define CONTROL_DISPLAY_DD (1 << 3)
#define CONTROL_DISPLAY_BL (1 << 2) #define CONTROL_DISPLAY_BL (1 << 2)
#define POWER_SAVE_OFF (0 << 0)
#define POWER_SAVE_LOW (1 << 0)
#define POWER_SAVE_MEDIUM (2 << 0)
#define POWER_SAVE_HIGH (3 << 0)
#define POWER_SAVE_OUTDOOR_MODE (4 << 0)
#define PANEL_PWM_MAX_VALUE 0xFF #define PANEL_PWM_MAX_VALUE 0xFF
static u32 dcs_get_backlight(struct intel_connector *connector) static u32 dcs_get_backlight(struct intel_connector *connector)
...@@ -79,6 +85,14 @@ static void dcs_disable_backlight(struct intel_connector *connector) ...@@ -79,6 +85,14 @@ static void dcs_disable_backlight(struct intel_connector *connector)
dcs_set_backlight(connector, 0); dcs_set_backlight(connector, 0);
for_each_dsi_port(port, intel_dsi->dcs_cabc_ports) {
u8 cabc = POWER_SAVE_OFF;
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_POWER_SAVE,
&cabc, sizeof(cabc));
}
for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) { for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
u8 ctrl = 0; u8 ctrl = 0;
...@@ -120,6 +134,14 @@ static void dcs_enable_backlight(struct intel_connector *connector) ...@@ -120,6 +134,14 @@ static void dcs_enable_backlight(struct intel_connector *connector)
&ctrl, sizeof(ctrl)); &ctrl, sizeof(ctrl));
} }
for_each_dsi_port(port, intel_dsi->dcs_cabc_ports) {
u8 cabc = POWER_SAVE_MEDIUM;
dsi_device = intel_dsi->dsi_hosts[port]->device;
mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_POWER_SAVE,
&cabc, sizeof(cabc));
}
dcs_set_backlight(connector, panel->backlight.level); dcs_set_backlight(connector, panel->backlight.level);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册