aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2016-04-26 09:14:25 -0400
committerJani Nikula <jani.nikula@intel.com>2016-05-17 09:12:38 -0400
commit90198355b83c79e2158ec591085858b191f08502 (patch)
treeb5b6283ebd65709f1d5f18fdad09049f246a2e0d
parent9a652cc01e589e10e2aa341074ea240c9838102b (diff)
drm/i915/dsi: Add DCS control for Panel PWM
If the source of the backlight PWM is from the panel then the PWM can be controlled by DCS command, this patch adds the support to enable/disbale panel PWM, control backlight level etc... v2: Moving the CABC bkl functions to new file.(Jani) v3: Rebase v4: Rebase v5: Use mipi_dsi_dcs_write() instead of mipi_dsi_dcs_write_buffer() (Jani) Move DCS macro`s to include/video/mipi_display.h (Jani) v6: Rename the file to intel_dsi_panel_pwm.c Removing the CABC operations v7 by Jani: renames, rebases, etc. v8 by Jani: s/INTEL_BACKLIGHT_CABC/INTEL_BACKLIGHT_DSI_DCS/ v9 by Jani: rename init function to intel_dsi_dcs_init_backlight_funcs Cc: Jani Nikula <jani.nikula@intel.com> Cc: Daniel Vetter <daniel.vetter@intel.com> Cc: Yetunde Adebisi <yetundex.adebisi@intel.com> Signed-off-by: Deepak M <m.deepak@intel.com> Reviewed-by: Yetunde Adebisi <yetundex.adebisi@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/71238a4b14b8c3a6c04070c789f09f1b4bc00a15.1461676337.git.jani.nikula@intel.com
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c19
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.h3
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c157
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c4
6 files changed, 184 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 63c4d2b7c5b0..7e2944406b8f 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -87,6 +87,7 @@ i915-y += dvo_ch7017.o \
87 intel_dp_mst.o \ 87 intel_dp_mst.o \
88 intel_dp.o \ 88 intel_dp.o \
89 intel_dsi.o \ 89 intel_dsi.o \
90 intel_dsi_dcs_backlight.o \
90 intel_dsi_panel_vbt.o \ 91 intel_dsi_panel_vbt.o \
91 intel_dsi_pll.o \ 92 intel_dsi_pll.o \
92 intel_dvo.o \ 93 intel_dvo.o \
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0dc2bc9c65cf..3536292babe0 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1385,6 +1385,8 @@ void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
1385/* intel_dsi.c */ 1385/* intel_dsi.c */
1386void intel_dsi_init(struct drm_device *dev); 1386void intel_dsi_init(struct drm_device *dev);
1387 1387
1388/* intel_dsi_dcs_backlight.c */
1389int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector);
1388 1390
1389/* intel_dvo.c */ 1391/* intel_dvo.c */
1390void intel_dvo_init(struct drm_device *dev); 1392void intel_dvo_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 40e465b5aa78..edb6bea870d6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1474,10 +1474,25 @@ void intel_dsi_init(struct drm_device *dev)
1474 else 1474 else
1475 intel_encoder->crtc_mask = BIT(PIPE_B); 1475 intel_encoder->crtc_mask = BIT(PIPE_B);
1476 1476
1477 if (dev_priv->vbt.dsi.config->dual_link) 1477 if (dev_priv->vbt.dsi.config->dual_link) {
1478 intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C); 1478 intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C);
1479 else 1479
1480 switch (dev_priv->vbt.dsi.config->dl_dcs_backlight_ports) {
1481 case DL_DCS_PORT_A:
1482 intel_dsi->dcs_backlight_ports = BIT(PORT_A);
1483 break;
1484 case DL_DCS_PORT_C:
1485 intel_dsi->dcs_backlight_ports = BIT(PORT_C);
1486 break;
1487 default:
1488 case DL_DCS_PORT_A_AND_C:
1489 intel_dsi->dcs_backlight_ports = BIT(PORT_A) | BIT(PORT_C);
1490 break;
1491 }
1492 } else {
1480 intel_dsi->ports = BIT(port); 1493 intel_dsi->ports = BIT(port);
1494 intel_dsi->dcs_backlight_ports = BIT(port);
1495 }
1481 1496
1482 /* Create a DSI host (and a device) for each port. */ 1497 /* Create a DSI host (and a device) for each port. */
1483 for_each_dsi_port(port, intel_dsi->ports) { 1498 for_each_dsi_port(port, intel_dsi->ports) {
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 61a6957fc6c2..b00fb3fbb0b1 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -78,6 +78,9 @@ struct intel_dsi {
78 78
79 u8 escape_clk_div; 79 u8 escape_clk_div;
80 u8 dual_link; 80 u8 dual_link;
81
82 u16 dcs_backlight_ports;
83
81 u8 pixel_overlap; 84 u8 pixel_overlap;
82 u32 port_bits; 85 u32 port_bits;
83 u32 bw_timer; 86 u32 bw_timer;
diff --git a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c
new file mode 100644
index 000000000000..7f9bbffa7f8c
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c
@@ -0,0 +1,157 @@
1/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Author: Deepak M <m.deepak at intel.com>
24 */
25
26#include "intel_drv.h"
27#include "intel_dsi.h"
28#include "i915_drv.h"
29#include <video/mipi_display.h>
30#include <drm/drm_mipi_dsi.h>
31
32#define CONTROL_DISPLAY_BCTRL (1 << 5)
33#define CONTROL_DISPLAY_DD (1 << 3)
34#define CONTROL_DISPLAY_BL (1 << 2)
35
36#define PANEL_PWM_MAX_VALUE 0xFF
37
38static u32 dcs_get_backlight(struct intel_connector *connector)
39{
40 struct intel_encoder *encoder = connector->encoder;
41 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
42 struct mipi_dsi_device *dsi_device;
43 u8 data;
44 enum port port;
45
46 /* FIXME: Need to take care of 16 bit brightness level */
47 for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
48 dsi_device = intel_dsi->dsi_hosts[port]->device;
49 mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
50 &data, sizeof(data));
51 break;
52 }
53
54 return data;
55}
56
57static void dcs_set_backlight(struct intel_connector *connector, u32 level)
58{
59 struct intel_encoder *encoder = connector->encoder;
60 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
61 struct mipi_dsi_device *dsi_device;
62 u8 data = level;
63 enum port port;
64
65 /* FIXME: Need to take care of 16 bit brightness level */
66 for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
67 dsi_device = intel_dsi->dsi_hosts[port]->device;
68 mipi_dsi_dcs_write(dsi_device, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
69 &data, sizeof(data));
70 }
71}
72
73static void dcs_disable_backlight(struct intel_connector *connector)
74{
75 struct intel_encoder *encoder = connector->encoder;
76 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
77 struct mipi_dsi_device *dsi_device;
78 enum port port;
79
80 dcs_set_backlight(connector, 0);
81
82 for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
83 u8 ctrl = 0;
84
85 dsi_device = intel_dsi->dsi_hosts[port]->device;
86
87 mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_CONTROL_DISPLAY,
88 &ctrl, sizeof(ctrl));
89
90 ctrl &= ~CONTROL_DISPLAY_BL;
91 ctrl &= ~CONTROL_DISPLAY_DD;
92 ctrl &= ~CONTROL_DISPLAY_BCTRL;
93
94 mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_CONTROL_DISPLAY,
95 &ctrl, sizeof(ctrl));
96 }
97}
98
99static void dcs_enable_backlight(struct intel_connector *connector)
100{
101 struct intel_encoder *encoder = connector->encoder;
102 struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
103 struct intel_panel *panel = &connector->panel;
104 struct mipi_dsi_device *dsi_device;
105 enum port port;
106
107 for_each_dsi_port(port, intel_dsi->dcs_backlight_ports) {
108 u8 ctrl = 0;
109
110 dsi_device = intel_dsi->dsi_hosts[port]->device;
111
112 mipi_dsi_dcs_read(dsi_device, MIPI_DCS_GET_CONTROL_DISPLAY,
113 &ctrl, sizeof(ctrl));
114
115 ctrl |= CONTROL_DISPLAY_BL;
116 ctrl |= CONTROL_DISPLAY_DD;
117 ctrl |= CONTROL_DISPLAY_BCTRL;
118
119 mipi_dsi_dcs_write(dsi_device, MIPI_DCS_WRITE_CONTROL_DISPLAY,
120 &ctrl, sizeof(ctrl));
121 }
122
123 dcs_set_backlight(connector, panel->backlight.level);
124}
125
126static int dcs_setup_backlight(struct intel_connector *connector,
127 enum pipe unused)
128{
129 struct intel_panel *panel = &connector->panel;
130
131 panel->backlight.max = PANEL_PWM_MAX_VALUE;
132 panel->backlight.level = PANEL_PWM_MAX_VALUE;
133
134 return 0;
135}
136
137int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector)
138{
139 struct drm_device *dev = intel_connector->base.dev;
140 struct drm_i915_private *dev_priv = dev->dev_private;
141 struct intel_encoder *encoder = intel_connector->encoder;
142 struct intel_panel *panel = &intel_connector->panel;
143
144 if (dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
145 return -ENODEV;
146
147 if (WARN_ON(encoder->type != INTEL_OUTPUT_DSI))
148 return -EINVAL;
149
150 panel->backlight.setup = dcs_setup_backlight;
151 panel->backlight.enable = dcs_enable_backlight;
152 panel->backlight.disable = dcs_disable_backlight;
153 panel->backlight.set = dcs_set_backlight;
154 panel->backlight.get = dcs_get_backlight;
155
156 return 0;
157}
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 828f0fcaaaf8..efaee7a7f933 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1722,6 +1722,10 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
1722 intel_dp_aux_init_backlight_funcs(connector) == 0) 1722 intel_dp_aux_init_backlight_funcs(connector) == 0)
1723 return; 1723 return;
1724 1724
1725 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
1726 intel_dsi_dcs_init_backlight_funcs(connector) == 0)
1727 return;
1728
1725 if (IS_BROXTON(dev_priv)) { 1729 if (IS_BROXTON(dev_priv)) {
1726 panel->backlight.setup = bxt_setup_backlight; 1730 panel->backlight.setup = bxt_setup_backlight;
1727 panel->backlight.enable = bxt_enable_backlight; 1731 panel->backlight.enable = bxt_enable_backlight;