Branch data Line data Source code
1 : : /*
2 : : * Copyright © 2014 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: Shobhit Kumar <shobhit.kumar@intel.com>
24 : : *
25 : : */
26 : :
27 : : #include <linux/gpio/consumer.h>
28 : : #include <linux/gpio/machine.h>
29 : : #include <linux/mfd/intel_soc_pmic.h>
30 : : #include <linux/pinctrl/consumer.h>
31 : : #include <linux/pinctrl/machine.h>
32 : : #include <linux/slab.h>
33 : :
34 : : #include <asm/intel-mid.h>
35 : : #include <asm/unaligned.h>
36 : :
37 : : #include <drm/drm_crtc.h>
38 : : #include <drm/drm_edid.h>
39 : : #include <drm/i915_drm.h>
40 : :
41 : : #include <video/mipi_display.h>
42 : :
43 : : #include "i915_drv.h"
44 : : #include "intel_display_types.h"
45 : : #include "intel_dsi.h"
46 : : #include "intel_sideband.h"
47 : :
48 : : #define MIPI_TRANSFER_MODE_SHIFT 0
49 : : #define MIPI_VIRTUAL_CHANNEL_SHIFT 1
50 : : #define MIPI_PORT_SHIFT 3
51 : :
52 : : /* base offsets for gpio pads */
53 : : #define VLV_GPIO_NC_0_HV_DDI0_HPD 0x4130
54 : : #define VLV_GPIO_NC_1_HV_DDI0_DDC_SDA 0x4120
55 : : #define VLV_GPIO_NC_2_HV_DDI0_DDC_SCL 0x4110
56 : : #define VLV_GPIO_NC_3_PANEL0_VDDEN 0x4140
57 : : #define VLV_GPIO_NC_4_PANEL0_BKLTEN 0x4150
58 : : #define VLV_GPIO_NC_5_PANEL0_BKLTCTL 0x4160
59 : : #define VLV_GPIO_NC_6_HV_DDI1_HPD 0x4180
60 : : #define VLV_GPIO_NC_7_HV_DDI1_DDC_SDA 0x4190
61 : : #define VLV_GPIO_NC_8_HV_DDI1_DDC_SCL 0x4170
62 : : #define VLV_GPIO_NC_9_PANEL1_VDDEN 0x4100
63 : : #define VLV_GPIO_NC_10_PANEL1_BKLTEN 0x40E0
64 : : #define VLV_GPIO_NC_11_PANEL1_BKLTCTL 0x40F0
65 : :
66 : : #define VLV_GPIO_PCONF0(base_offset) (base_offset)
67 : : #define VLV_GPIO_PAD_VAL(base_offset) ((base_offset) + 8)
68 : :
69 : : struct gpio_map {
70 : : u16 base_offset;
71 : : bool init;
72 : : };
73 : :
74 : : static struct gpio_map vlv_gpio_table[] = {
75 : : { VLV_GPIO_NC_0_HV_DDI0_HPD },
76 : : { VLV_GPIO_NC_1_HV_DDI0_DDC_SDA },
77 : : { VLV_GPIO_NC_2_HV_DDI0_DDC_SCL },
78 : : { VLV_GPIO_NC_3_PANEL0_VDDEN },
79 : : { VLV_GPIO_NC_4_PANEL0_BKLTEN },
80 : : { VLV_GPIO_NC_5_PANEL0_BKLTCTL },
81 : : { VLV_GPIO_NC_6_HV_DDI1_HPD },
82 : : { VLV_GPIO_NC_7_HV_DDI1_DDC_SDA },
83 : : { VLV_GPIO_NC_8_HV_DDI1_DDC_SCL },
84 : : { VLV_GPIO_NC_9_PANEL1_VDDEN },
85 : : { VLV_GPIO_NC_10_PANEL1_BKLTEN },
86 : : { VLV_GPIO_NC_11_PANEL1_BKLTCTL },
87 : : };
88 : :
89 : : struct i2c_adapter_lookup {
90 : : u16 slave_addr;
91 : : struct intel_dsi *intel_dsi;
92 : : acpi_handle dev_handle;
93 : : };
94 : :
95 : : #define CHV_GPIO_IDX_START_N 0
96 : : #define CHV_GPIO_IDX_START_E 73
97 : : #define CHV_GPIO_IDX_START_SW 100
98 : : #define CHV_GPIO_IDX_START_SE 198
99 : :
100 : : #define CHV_VBT_MAX_PINS_PER_FMLY 15
101 : :
102 : : #define CHV_GPIO_PAD_CFG0(f, i) (0x4400 + (f) * 0x400 + (i) * 8)
103 : : #define CHV_GPIO_GPIOEN (1 << 15)
104 : : #define CHV_GPIO_GPIOCFG_GPIO (0 << 8)
105 : : #define CHV_GPIO_GPIOCFG_GPO (1 << 8)
106 : : #define CHV_GPIO_GPIOCFG_GPI (2 << 8)
107 : : #define CHV_GPIO_GPIOCFG_HIZ (3 << 8)
108 : : #define CHV_GPIO_GPIOTXSTATE(state) ((!!(state)) << 1)
109 : :
110 : : #define CHV_GPIO_PAD_CFG1(f, i) (0x4400 + (f) * 0x400 + (i) * 8 + 4)
111 : : #define CHV_GPIO_CFGLOCK (1 << 31)
112 : :
113 : : /* ICL DSI Display GPIO Pins */
114 : : #define ICL_GPIO_DDSP_HPD_A 0
115 : : #define ICL_GPIO_L_VDDEN_1 1
116 : : #define ICL_GPIO_L_BKLTEN_1 2
117 : : #define ICL_GPIO_DDPA_CTRLCLK_1 3
118 : : #define ICL_GPIO_DDPA_CTRLDATA_1 4
119 : : #define ICL_GPIO_DDSP_HPD_B 5
120 : : #define ICL_GPIO_L_VDDEN_2 6
121 : : #define ICL_GPIO_L_BKLTEN_2 7
122 : : #define ICL_GPIO_DDPA_CTRLCLK_2 8
123 : : #define ICL_GPIO_DDPA_CTRLDATA_2 9
124 : :
125 : 0 : static inline enum port intel_dsi_seq_port_to_port(u8 port)
126 : : {
127 : 0 : return port ? PORT_C : PORT_A;
128 : : }
129 : :
130 : 0 : static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi,
131 : : const u8 *data)
132 : : {
133 : 0 : struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
134 : 0 : struct mipi_dsi_device *dsi_device;
135 : 0 : u8 type, flags, seq_port;
136 : 0 : u16 len;
137 : 0 : enum port port;
138 : :
139 : 0 : DRM_DEBUG_KMS("\n");
140 : :
141 : 0 : flags = *data++;
142 : 0 : type = *data++;
143 : :
144 : 0 : len = *((u16 *) data);
145 : 0 : data += 2;
146 : :
147 : 0 : seq_port = (flags >> MIPI_PORT_SHIFT) & 3;
148 : :
149 : : /* For DSI single link on Port A & C, the seq_port value which is
150 : : * parsed from Sequence Block#53 of VBT has been set to 0
151 : : * Now, read/write of packets for the DSI single link on Port A and
152 : : * Port C will based on the DVO port from VBT block 2.
153 : : */
154 [ # # ]: 0 : if (intel_dsi->ports == (1 << PORT_C))
155 : : port = PORT_C;
156 : : else
157 [ # # ]: 0 : port = intel_dsi_seq_port_to_port(seq_port);
158 : :
159 : 0 : dsi_device = intel_dsi->dsi_hosts[port]->device;
160 [ # # ]: 0 : if (!dsi_device) {
161 : 0 : DRM_DEBUG_KMS("no dsi device for port %c\n", port_name(port));
162 : 0 : goto out;
163 : : }
164 : :
165 [ # # ]: 0 : if ((flags >> MIPI_TRANSFER_MODE_SHIFT) & 1)
166 : 0 : dsi_device->mode_flags &= ~MIPI_DSI_MODE_LPM;
167 : : else
168 : 0 : dsi_device->mode_flags |= MIPI_DSI_MODE_LPM;
169 : :
170 : 0 : dsi_device->channel = (flags >> MIPI_VIRTUAL_CHANNEL_SHIFT) & 3;
171 : :
172 [ # # # # : 0 : switch (type) {
# # # # #
# ]
173 : 0 : case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
174 : 0 : mipi_dsi_generic_write(dsi_device, NULL, 0);
175 : 0 : break;
176 : 0 : case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
177 : 0 : mipi_dsi_generic_write(dsi_device, data, 1);
178 : 0 : break;
179 : 0 : case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
180 : 0 : mipi_dsi_generic_write(dsi_device, data, 2);
181 : 0 : break;
182 : 0 : case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
183 : : case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
184 : : case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
185 : 0 : DRM_DEBUG_DRIVER("Generic Read not yet implemented or used\n");
186 : 0 : break;
187 : 0 : case MIPI_DSI_GENERIC_LONG_WRITE:
188 : 0 : mipi_dsi_generic_write(dsi_device, data, len);
189 : 0 : break;
190 : 0 : case MIPI_DSI_DCS_SHORT_WRITE:
191 : 0 : mipi_dsi_dcs_write_buffer(dsi_device, data, 1);
192 : 0 : break;
193 : 0 : case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
194 : 0 : mipi_dsi_dcs_write_buffer(dsi_device, data, 2);
195 : 0 : break;
196 : 0 : case MIPI_DSI_DCS_READ:
197 : 0 : DRM_DEBUG_DRIVER("DCS Read not yet implemented or used\n");
198 : 0 : break;
199 : 0 : case MIPI_DSI_DCS_LONG_WRITE:
200 : 0 : mipi_dsi_dcs_write_buffer(dsi_device, data, len);
201 : 0 : break;
202 : : }
203 : :
204 [ # # ]: 0 : if (INTEL_GEN(dev_priv) < 11)
205 : 0 : vlv_dsi_wait_for_fifo_empty(intel_dsi, port);
206 : :
207 : 0 : out:
208 : 0 : data += len;
209 : :
210 : 0 : return data;
211 : : }
212 : :
213 : 0 : static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
214 : : {
215 : 0 : u32 delay = *((const u32 *) data);
216 : :
217 : 0 : DRM_DEBUG_KMS("\n");
218 : :
219 : 0 : usleep_range(delay, delay + 10);
220 : 0 : data += 4;
221 : :
222 : 0 : return data;
223 : : }
224 : :
225 : 0 : static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
226 : : u8 gpio_source, u8 gpio_index, bool value)
227 : : {
228 : 0 : struct gpio_map *map;
229 : 0 : u16 pconf0, padval;
230 : 0 : u32 tmp;
231 : 0 : u8 port;
232 : :
233 [ # # ]: 0 : if (gpio_index >= ARRAY_SIZE(vlv_gpio_table)) {
234 : 0 : DRM_DEBUG_KMS("unknown gpio index %u\n", gpio_index);
235 : 0 : return;
236 : : }
237 : :
238 : 0 : map = &vlv_gpio_table[gpio_index];
239 : :
240 [ # # ]: 0 : if (dev_priv->vbt.dsi.seq_version >= 3) {
241 : : /* XXX: this assumes vlv_gpio_table only has NC GPIOs. */
242 : : port = IOSF_PORT_GPIO_NC;
243 : : } else {
244 [ # # ]: 0 : if (gpio_source == 0) {
245 : : port = IOSF_PORT_GPIO_NC;
246 [ # # ]: 0 : } else if (gpio_source == 1) {
247 : 0 : DRM_DEBUG_KMS("SC gpio not supported\n");
248 : 0 : return;
249 : : } else {
250 : 0 : DRM_DEBUG_KMS("unknown gpio source %u\n", gpio_source);
251 : 0 : return;
252 : : }
253 : : }
254 : :
255 : 0 : pconf0 = VLV_GPIO_PCONF0(map->base_offset);
256 : 0 : padval = VLV_GPIO_PAD_VAL(map->base_offset);
257 : :
258 : 0 : vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
259 [ # # ]: 0 : if (!map->init) {
260 : : /* FIXME: remove constant below */
261 : 0 : vlv_iosf_sb_write(dev_priv, port, pconf0, 0x2000CC00);
262 : 0 : map->init = true;
263 : : }
264 : :
265 : 0 : tmp = 0x4 | value;
266 : 0 : vlv_iosf_sb_write(dev_priv, port, padval, tmp);
267 : 0 : vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
268 : : }
269 : :
270 : 0 : static void chv_exec_gpio(struct drm_i915_private *dev_priv,
271 : : u8 gpio_source, u8 gpio_index, bool value)
272 : : {
273 : 0 : u16 cfg0, cfg1;
274 : 0 : u16 family_num;
275 : 0 : u8 port;
276 : :
277 [ # # ]: 0 : if (dev_priv->vbt.dsi.seq_version >= 3) {
278 [ # # ]: 0 : if (gpio_index >= CHV_GPIO_IDX_START_SE) {
279 : : /* XXX: it's unclear whether 255->57 is part of SE. */
280 : 0 : gpio_index -= CHV_GPIO_IDX_START_SE;
281 : 0 : port = CHV_IOSF_PORT_GPIO_SE;
282 [ # # ]: 0 : } else if (gpio_index >= CHV_GPIO_IDX_START_SW) {
283 : 0 : gpio_index -= CHV_GPIO_IDX_START_SW;
284 : 0 : port = CHV_IOSF_PORT_GPIO_SW;
285 [ # # ]: 0 : } else if (gpio_index >= CHV_GPIO_IDX_START_E) {
286 : 0 : gpio_index -= CHV_GPIO_IDX_START_E;
287 : 0 : port = CHV_IOSF_PORT_GPIO_E;
288 : : } else {
289 : : port = CHV_IOSF_PORT_GPIO_N;
290 : : }
291 : : } else {
292 : : /* XXX: The spec is unclear about CHV GPIO on seq v2 */
293 [ # # ]: 0 : if (gpio_source != 0) {
294 : 0 : DRM_DEBUG_KMS("unknown gpio source %u\n", gpio_source);
295 : 0 : return;
296 : : }
297 : :
298 [ # # ]: 0 : if (gpio_index >= CHV_GPIO_IDX_START_E) {
299 : 0 : DRM_DEBUG_KMS("invalid gpio index %u for GPIO N\n",
300 : : gpio_index);
301 : 0 : return;
302 : : }
303 : :
304 : : port = CHV_IOSF_PORT_GPIO_N;
305 : : }
306 : :
307 : 0 : family_num = gpio_index / CHV_VBT_MAX_PINS_PER_FMLY;
308 : 0 : gpio_index = gpio_index % CHV_VBT_MAX_PINS_PER_FMLY;
309 : :
310 : 0 : cfg0 = CHV_GPIO_PAD_CFG0(family_num, gpio_index);
311 : 0 : cfg1 = CHV_GPIO_PAD_CFG1(family_num, gpio_index);
312 : :
313 : 0 : vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
314 : 0 : vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
315 [ # # ]: 0 : vlv_iosf_sb_write(dev_priv, port, cfg0,
316 : : CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
317 : : CHV_GPIO_GPIOTXSTATE(value));
318 : 0 : vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
319 : : }
320 : :
321 : 0 : static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
322 : : u8 gpio_source, u8 gpio_index, bool value)
323 : : {
324 : : /* XXX: this table is a quick ugly hack. */
325 : 0 : static struct gpio_desc *bxt_gpio_table[U8_MAX + 1];
326 : 0 : struct gpio_desc *gpio_desc = bxt_gpio_table[gpio_index];
327 : :
328 [ # # ]: 0 : if (!gpio_desc) {
329 : 0 : gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
330 : : NULL, gpio_index,
331 : : value ? GPIOD_OUT_LOW :
332 : : GPIOD_OUT_HIGH);
333 : :
334 : 0 : if (IS_ERR_OR_NULL(gpio_desc)) {
335 : 0 : DRM_ERROR("GPIO index %u request failed (%ld)\n",
336 : : gpio_index, PTR_ERR(gpio_desc));
337 : 0 : return;
338 : : }
339 : :
340 : : bxt_gpio_table[gpio_index] = gpio_desc;
341 : : }
342 : :
343 : 0 : gpiod_set_value(gpio_desc, value);
344 : : }
345 : :
346 : 0 : static void icl_exec_gpio(struct drm_i915_private *dev_priv,
347 : : u8 gpio_source, u8 gpio_index, bool value)
348 : : {
349 : 0 : DRM_DEBUG_KMS("Skipping ICL GPIO element execution\n");
350 : 0 : }
351 : :
352 : 0 : static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
353 : : {
354 : 0 : struct drm_device *dev = intel_dsi->base.base.dev;
355 : 0 : struct drm_i915_private *dev_priv = to_i915(dev);
356 : 0 : u8 gpio_source, gpio_index = 0, gpio_number;
357 : 0 : bool value;
358 : :
359 : 0 : DRM_DEBUG_KMS("\n");
360 : :
361 [ # # ]: 0 : if (dev_priv->vbt.dsi.seq_version >= 3)
362 : 0 : gpio_index = *data++;
363 : :
364 : 0 : gpio_number = *data++;
365 : :
366 : : /* gpio source in sequence v2 only */
367 [ # # ]: 0 : if (dev_priv->vbt.dsi.seq_version == 2)
368 : 0 : gpio_source = (*data >> 1) & 3;
369 : : else
370 : : gpio_source = 0;
371 : :
372 : : /* pull up/down */
373 : 0 : value = *data++ & 1;
374 : :
375 [ # # ]: 0 : if (INTEL_GEN(dev_priv) >= 11)
376 : 0 : icl_exec_gpio(dev_priv, gpio_source, gpio_index, value);
377 [ # # ]: 0 : else if (IS_VALLEYVIEW(dev_priv))
378 : 0 : vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
379 [ # # ]: 0 : else if (IS_CHERRYVIEW(dev_priv))
380 : 0 : chv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
381 : : else
382 : 0 : bxt_exec_gpio(dev_priv, gpio_source, gpio_index, value);
383 : :
384 : 0 : return data;
385 : : }
386 : :
387 : : #ifdef CONFIG_ACPI
388 : 0 : static int i2c_adapter_lookup(struct acpi_resource *ares, void *data)
389 : : {
390 : 0 : struct i2c_adapter_lookup *lookup = data;
391 : 0 : struct intel_dsi *intel_dsi = lookup->intel_dsi;
392 : 0 : struct acpi_resource_i2c_serialbus *sb;
393 : 0 : struct i2c_adapter *adapter;
394 : 0 : acpi_handle adapter_handle;
395 : 0 : acpi_status status;
396 : :
397 [ # # ]: 0 : if (!i2c_acpi_get_i2c_resource(ares, &sb))
398 : : return 1;
399 : :
400 [ # # ]: 0 : if (lookup->slave_addr != sb->slave_address)
401 : : return 1;
402 : :
403 : 0 : status = acpi_get_handle(lookup->dev_handle,
404 : : sb->resource_source.string_ptr,
405 : : &adapter_handle);
406 [ # # ]: 0 : if (ACPI_FAILURE(status))
407 : : return 1;
408 : :
409 : 0 : adapter = i2c_acpi_find_adapter_by_handle(adapter_handle);
410 [ # # ]: 0 : if (adapter)
411 : 0 : intel_dsi->i2c_bus_num = adapter->nr;
412 : :
413 : : return 1;
414 : : }
415 : :
416 : 0 : static void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,
417 : : const u16 slave_addr)
418 : : {
419 : 0 : struct drm_device *drm_dev = intel_dsi->base.base.dev;
420 : 0 : struct device *dev = &drm_dev->pdev->dev;
421 : 0 : struct acpi_device *acpi_dev;
422 : 0 : struct list_head resource_list;
423 : 0 : struct i2c_adapter_lookup lookup;
424 : :
425 [ # # ]: 0 : acpi_dev = ACPI_COMPANION(dev);
426 [ # # ]: 0 : if (acpi_dev) {
427 : 0 : memset(&lookup, 0, sizeof(lookup));
428 : 0 : lookup.slave_addr = slave_addr;
429 : 0 : lookup.intel_dsi = intel_dsi;
430 : 0 : lookup.dev_handle = acpi_device_handle(acpi_dev);
431 : :
432 : 0 : INIT_LIST_HEAD(&resource_list);
433 : 0 : acpi_dev_get_resources(acpi_dev, &resource_list,
434 : : i2c_adapter_lookup,
435 : : &lookup);
436 : 0 : acpi_dev_free_resource_list(&resource_list);
437 : : }
438 : 0 : }
439 : : #else
440 : : static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi,
441 : : const u16 slave_addr)
442 : : {
443 : : }
444 : : #endif
445 : :
446 : 0 : static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
447 : : {
448 : 0 : struct drm_device *drm_dev = intel_dsi->base.base.dev;
449 : 0 : struct device *dev = &drm_dev->pdev->dev;
450 : 0 : struct i2c_adapter *adapter;
451 : 0 : struct i2c_msg msg;
452 : 0 : int ret;
453 : 0 : u8 vbt_i2c_bus_num = *(data + 2);
454 : 0 : u16 slave_addr = *(u16 *)(data + 3);
455 : 0 : u8 reg_offset = *(data + 5);
456 : 0 : u8 payload_size = *(data + 6);
457 : 0 : u8 *payload_data;
458 : :
459 [ # # ]: 0 : if (intel_dsi->i2c_bus_num < 0) {
460 : 0 : intel_dsi->i2c_bus_num = vbt_i2c_bus_num;
461 : 0 : i2c_acpi_find_adapter(intel_dsi, slave_addr);
462 : : }
463 : :
464 : 0 : adapter = i2c_get_adapter(intel_dsi->i2c_bus_num);
465 [ # # ]: 0 : if (!adapter) {
466 : 0 : DRM_DEV_ERROR(dev, "Cannot find a valid i2c bus for xfer\n");
467 : 0 : goto err_bus;
468 : : }
469 : :
470 : 0 : payload_data = kzalloc(payload_size + 1, GFP_KERNEL);
471 [ # # ]: 0 : if (!payload_data)
472 : 0 : goto err_alloc;
473 : :
474 : 0 : payload_data[0] = reg_offset;
475 : 0 : memcpy(&payload_data[1], (data + 7), payload_size);
476 : :
477 : 0 : msg.addr = slave_addr;
478 : 0 : msg.flags = 0;
479 : 0 : msg.len = payload_size + 1;
480 : 0 : msg.buf = payload_data;
481 : :
482 : 0 : ret = i2c_transfer(adapter, &msg, 1);
483 [ # # ]: 0 : if (ret < 0)
484 : 0 : DRM_DEV_ERROR(dev,
485 : : "Failed to xfer payload of size (%u) to reg (%u)\n",
486 : : payload_size, reg_offset);
487 : :
488 : 0 : kfree(payload_data);
489 : 0 : err_alloc:
490 : 0 : i2c_put_adapter(adapter);
491 : 0 : err_bus:
492 : 0 : return data + payload_size + 7;
493 : : }
494 : :
495 : 0 : static const u8 *mipi_exec_spi(struct intel_dsi *intel_dsi, const u8 *data)
496 : : {
497 : 0 : DRM_DEBUG_KMS("Skipping SPI element execution\n");
498 : :
499 : 0 : return data + *(data + 5) + 6;
500 : : }
501 : :
502 : 0 : static const u8 *mipi_exec_pmic(struct intel_dsi *intel_dsi, const u8 *data)
503 : : {
504 : : #ifdef CONFIG_PMIC_OPREGION
505 : : u32 value, mask, reg_address;
506 : : u16 i2c_address;
507 : : int ret;
508 : :
509 : : /* byte 0 aka PMIC Flag is reserved */
510 : : i2c_address = get_unaligned_le16(data + 1);
511 : : reg_address = get_unaligned_le32(data + 3);
512 : : value = get_unaligned_le32(data + 7);
513 : : mask = get_unaligned_le32(data + 11);
514 : :
515 : : ret = intel_soc_pmic_exec_mipi_pmic_seq_element(i2c_address,
516 : : reg_address,
517 : : value, mask);
518 : : if (ret)
519 : : DRM_ERROR("%s failed, error: %d\n", __func__, ret);
520 : : #else
521 : 0 : DRM_ERROR("Your hardware requires CONFIG_PMIC_OPREGION and it is not set\n");
522 : : #endif
523 : :
524 : 0 : return data + 15;
525 : : }
526 : :
527 : : typedef const u8 * (*fn_mipi_elem_exec)(struct intel_dsi *intel_dsi,
528 : : const u8 *data);
529 : : static const fn_mipi_elem_exec exec_elem[] = {
530 : : [MIPI_SEQ_ELEM_SEND_PKT] = mipi_exec_send_packet,
531 : : [MIPI_SEQ_ELEM_DELAY] = mipi_exec_delay,
532 : : [MIPI_SEQ_ELEM_GPIO] = mipi_exec_gpio,
533 : : [MIPI_SEQ_ELEM_I2C] = mipi_exec_i2c,
534 : : [MIPI_SEQ_ELEM_SPI] = mipi_exec_spi,
535 : : [MIPI_SEQ_ELEM_PMIC] = mipi_exec_pmic,
536 : : };
537 : :
538 : : /*
539 : : * MIPI Sequence from VBT #53 parsing logic
540 : : * We have already separated each seqence during bios parsing
541 : : * Following is generic execution function for any sequence
542 : : */
543 : :
544 : : static const char * const seq_name[] = {
545 : : [MIPI_SEQ_DEASSERT_RESET] = "MIPI_SEQ_DEASSERT_RESET",
546 : : [MIPI_SEQ_INIT_OTP] = "MIPI_SEQ_INIT_OTP",
547 : : [MIPI_SEQ_DISPLAY_ON] = "MIPI_SEQ_DISPLAY_ON",
548 : : [MIPI_SEQ_DISPLAY_OFF] = "MIPI_SEQ_DISPLAY_OFF",
549 : : [MIPI_SEQ_ASSERT_RESET] = "MIPI_SEQ_ASSERT_RESET",
550 : : [MIPI_SEQ_BACKLIGHT_ON] = "MIPI_SEQ_BACKLIGHT_ON",
551 : : [MIPI_SEQ_BACKLIGHT_OFF] = "MIPI_SEQ_BACKLIGHT_OFF",
552 : : [MIPI_SEQ_TEAR_ON] = "MIPI_SEQ_TEAR_ON",
553 : : [MIPI_SEQ_TEAR_OFF] = "MIPI_SEQ_TEAR_OFF",
554 : : [MIPI_SEQ_POWER_ON] = "MIPI_SEQ_POWER_ON",
555 : : [MIPI_SEQ_POWER_OFF] = "MIPI_SEQ_POWER_OFF",
556 : : };
557 : :
558 : 0 : static const char *sequence_name(enum mipi_seq seq_id)
559 : : {
560 [ # # ]: 0 : if (seq_id < ARRAY_SIZE(seq_name) && seq_name[seq_id])
561 : : return seq_name[seq_id];
562 : : else
563 : 0 : return "(unknown)";
564 : : }
565 : :
566 : 0 : static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi,
567 : : enum mipi_seq seq_id)
568 : : {
569 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
570 : 0 : const u8 *data;
571 : 0 : fn_mipi_elem_exec mipi_elem_exec;
572 : :
573 [ # # # # ]: 0 : if (WARN_ON(seq_id >= ARRAY_SIZE(dev_priv->vbt.dsi.sequence)))
574 : : return;
575 : :
576 : 0 : data = dev_priv->vbt.dsi.sequence[seq_id];
577 [ # # ]: 0 : if (!data)
578 : : return;
579 : :
580 [ # # ]: 0 : WARN_ON(*data != seq_id);
581 : :
582 [ # # ]: 0 : DRM_DEBUG_KMS("Starting MIPI sequence %d - %s\n",
583 : : seq_id, sequence_name(seq_id));
584 : :
585 : : /* Skip Sequence Byte. */
586 : 0 : data++;
587 : :
588 : : /* Skip Size of Sequence. */
589 [ # # ]: 0 : if (dev_priv->vbt.dsi.seq_version >= 3)
590 : 0 : data += 4;
591 : :
592 : 0 : while (1) {
593 : 0 : u8 operation_byte = *data++;
594 : 0 : u8 operation_size = 0;
595 : :
596 [ # # ]: 0 : if (operation_byte == MIPI_SEQ_ELEM_END)
597 : : break;
598 : :
599 [ # # ]: 0 : if (operation_byte < ARRAY_SIZE(exec_elem))
600 : 0 : mipi_elem_exec = exec_elem[operation_byte];
601 : : else
602 : : mipi_elem_exec = NULL;
603 : :
604 : : /* Size of Operation. */
605 [ # # ]: 0 : if (dev_priv->vbt.dsi.seq_version >= 3)
606 : 0 : operation_size = *data++;
607 : :
608 [ # # ]: 0 : if (mipi_elem_exec) {
609 : 0 : const u8 *next = data + operation_size;
610 : :
611 : 0 : data = mipi_elem_exec(intel_dsi, data);
612 : :
613 : : /* Consistency check if we have size. */
614 [ # # ]: 0 : if (operation_size && data != next) {
615 : 0 : DRM_ERROR("Inconsistent operation size\n");
616 : 0 : return;
617 : : }
618 [ # # ]: 0 : } else if (operation_size) {
619 : : /* We have size, skip. */
620 : 0 : DRM_DEBUG_KMS("Unsupported MIPI operation byte %u\n",
621 : : operation_byte);
622 : 0 : data += operation_size;
623 : : } else {
624 : : /* No size, can't skip without parsing. */
625 : 0 : DRM_ERROR("Unsupported MIPI operation byte %u\n",
626 : : operation_byte);
627 : 0 : return;
628 : : }
629 : : }
630 : : }
631 : :
632 : 0 : void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi,
633 : : enum mipi_seq seq_id)
634 : : {
635 [ # # # # ]: 0 : if (seq_id == MIPI_SEQ_POWER_ON && intel_dsi->gpio_panel)
636 : 0 : gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1);
637 [ # # # # ]: 0 : if (seq_id == MIPI_SEQ_BACKLIGHT_ON && intel_dsi->gpio_backlight)
638 : 0 : gpiod_set_value_cansleep(intel_dsi->gpio_backlight, 1);
639 : :
640 : 0 : intel_dsi_vbt_exec(intel_dsi, seq_id);
641 : :
642 [ # # # # ]: 0 : if (seq_id == MIPI_SEQ_POWER_OFF && intel_dsi->gpio_panel)
643 : 0 : gpiod_set_value_cansleep(intel_dsi->gpio_panel, 0);
644 [ # # # # ]: 0 : if (seq_id == MIPI_SEQ_BACKLIGHT_OFF && intel_dsi->gpio_backlight)
645 : 0 : gpiod_set_value_cansleep(intel_dsi->gpio_backlight, 0);
646 : 0 : }
647 : :
648 : 0 : void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec)
649 : : {
650 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
651 : :
652 : : /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */
653 [ # # # # ]: 0 : if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3)
654 : : return;
655 : :
656 : 0 : msleep(msec);
657 : : }
658 : :
659 : 0 : void intel_dsi_log_params(struct intel_dsi *intel_dsi)
660 : : {
661 : 0 : DRM_DEBUG_KMS("Pclk %d\n", intel_dsi->pclk);
662 : 0 : DRM_DEBUG_KMS("Pixel overlap %d\n", intel_dsi->pixel_overlap);
663 : 0 : DRM_DEBUG_KMS("Lane count %d\n", intel_dsi->lane_count);
664 : 0 : DRM_DEBUG_KMS("DPHY param reg 0x%x\n", intel_dsi->dphy_reg);
665 [ # # # # : 0 : DRM_DEBUG_KMS("Video mode format %s\n",
# # ]
666 : : intel_dsi->video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE ?
667 : : "non-burst with sync pulse" :
668 : : intel_dsi->video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS ?
669 : : "non-burst with sync events" :
670 : : intel_dsi->video_mode_format == VIDEO_MODE_BURST ?
671 : : "burst" : "<unknown>");
672 : 0 : DRM_DEBUG_KMS("Burst mode ratio %d\n", intel_dsi->burst_mode_ratio);
673 : 0 : DRM_DEBUG_KMS("Reset timer %d\n", intel_dsi->rst_timer_val);
674 [ # # ]: 0 : DRM_DEBUG_KMS("Eot %s\n", enableddisabled(intel_dsi->eotp_pkt));
675 [ # # ]: 0 : DRM_DEBUG_KMS("Clockstop %s\n", enableddisabled(!intel_dsi->clock_stop));
676 [ # # ]: 0 : DRM_DEBUG_KMS("Mode %s\n", intel_dsi->operation_mode ? "command" : "video");
677 [ # # ]: 0 : if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK)
678 : 0 : DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_FRONT_BACK\n");
679 [ # # ]: 0 : else if (intel_dsi->dual_link == DSI_DUAL_LINK_PIXEL_ALT)
680 : 0 : DRM_DEBUG_KMS("Dual link: DSI_DUAL_LINK_PIXEL_ALT\n");
681 : : else
682 : 0 : DRM_DEBUG_KMS("Dual link: NONE\n");
683 : 0 : DRM_DEBUG_KMS("Pixel Format %d\n", intel_dsi->pixel_format);
684 : 0 : DRM_DEBUG_KMS("TLPX %d\n", intel_dsi->escape_clk_div);
685 : 0 : DRM_DEBUG_KMS("LP RX Timeout 0x%x\n", intel_dsi->lp_rx_timeout);
686 : 0 : DRM_DEBUG_KMS("Turnaround Timeout 0x%x\n", intel_dsi->turn_arnd_val);
687 : 0 : DRM_DEBUG_KMS("Init Count 0x%x\n", intel_dsi->init_count);
688 : 0 : DRM_DEBUG_KMS("HS to LP Count 0x%x\n", intel_dsi->hs_to_lp_count);
689 : 0 : DRM_DEBUG_KMS("LP Byte Clock %d\n", intel_dsi->lp_byte_clk);
690 : 0 : DRM_DEBUG_KMS("DBI BW Timer 0x%x\n", intel_dsi->bw_timer);
691 : 0 : DRM_DEBUG_KMS("LP to HS Clock Count 0x%x\n", intel_dsi->clk_lp_to_hs_count);
692 : 0 : DRM_DEBUG_KMS("HS to LP Clock Count 0x%x\n", intel_dsi->clk_hs_to_lp_count);
693 [ # # ]: 0 : DRM_DEBUG_KMS("BTA %s\n",
694 : : enableddisabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA)));
695 : 0 : }
696 : :
697 : 0 : bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
698 : : {
699 : 0 : struct drm_device *dev = intel_dsi->base.base.dev;
700 : 0 : struct drm_i915_private *dev_priv = to_i915(dev);
701 : 0 : struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
702 : 0 : struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps;
703 : 0 : struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode;
704 : 0 : u16 burst_mode_ratio;
705 : 0 : enum port port;
706 : :
707 : 0 : DRM_DEBUG_KMS("\n");
708 : :
709 : 0 : intel_dsi->eotp_pkt = mipi_config->eot_pkt_disabled ? 0 : 1;
710 : 0 : intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0;
711 : 0 : intel_dsi->lane_count = mipi_config->lane_cnt + 1;
712 : 0 : intel_dsi->pixel_format =
713 : 0 : pixel_format_from_register_bits(
714 : 0 : mipi_config->videomode_color_format << 7);
715 : :
716 : 0 : intel_dsi->dual_link = mipi_config->dual_link;
717 : 0 : intel_dsi->pixel_overlap = mipi_config->pixel_overlap;
718 : 0 : intel_dsi->operation_mode = mipi_config->is_cmd_mode;
719 : 0 : intel_dsi->video_mode_format = mipi_config->video_transfer_mode;
720 : 0 : intel_dsi->escape_clk_div = mipi_config->byte_clk_sel;
721 : 0 : intel_dsi->lp_rx_timeout = mipi_config->lp_rx_timeout;
722 : 0 : intel_dsi->hs_tx_timeout = mipi_config->hs_tx_timeout;
723 : 0 : intel_dsi->turn_arnd_val = mipi_config->turn_around_timeout;
724 : 0 : intel_dsi->rst_timer_val = mipi_config->device_reset_timer;
725 : 0 : intel_dsi->init_count = mipi_config->master_init_timer;
726 : 0 : intel_dsi->bw_timer = mipi_config->dbi_bw_timer;
727 : 0 : intel_dsi->video_frmt_cfg_bits =
728 : 0 : mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0;
729 : 0 : intel_dsi->bgr_enabled = mipi_config->rgb_flip;
730 : :
731 : : /* Starting point, adjusted depending on dual link and burst mode */
732 : 0 : intel_dsi->pclk = mode->clock;
733 : :
734 : : /* In dual link mode each port needs half of pixel clock */
735 [ # # ]: 0 : if (intel_dsi->dual_link) {
736 : 0 : intel_dsi->pclk /= 2;
737 : :
738 : : /* we can enable pixel_overlap if needed by panel. In this
739 : : * case we need to increase the pixelclock for extra pixels
740 : : */
741 [ # # ]: 0 : if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
742 : 0 : intel_dsi->pclk += DIV_ROUND_UP(mode->vtotal * intel_dsi->pixel_overlap * 60, 1000);
743 : : }
744 : : }
745 : :
746 : : /* Burst Mode Ratio
747 : : * Target ddr frequency from VBT / non burst ddr freq
748 : : * multiply by 100 to preserve remainder
749 : : */
750 [ # # ]: 0 : if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) {
751 [ # # ]: 0 : if (mipi_config->target_burst_mode_freq) {
752 : 0 : u32 bitrate = intel_dsi_bitrate(intel_dsi);
753 : :
754 : : /*
755 : : * Sometimes the VBT contains a slightly lower clock,
756 : : * then the bitrate we have calculated, in this case
757 : : * just replace it with the calculated bitrate.
758 : : */
759 [ # # # # ]: 0 : if (mipi_config->target_burst_mode_freq < bitrate &&
760 : 0 : intel_fuzzy_clock_check(
761 : : mipi_config->target_burst_mode_freq,
762 : : bitrate))
763 : 0 : mipi_config->target_burst_mode_freq = bitrate;
764 : :
765 [ # # ]: 0 : if (mipi_config->target_burst_mode_freq < bitrate) {
766 : 0 : DRM_ERROR("Burst mode freq is less than computed\n");
767 : 0 : return false;
768 : : }
769 : :
770 : 0 : burst_mode_ratio = DIV_ROUND_UP(
771 : : mipi_config->target_burst_mode_freq * 100,
772 : : bitrate);
773 : :
774 : 0 : intel_dsi->pclk = DIV_ROUND_UP(intel_dsi->pclk * burst_mode_ratio, 100);
775 : : } else {
776 : 0 : DRM_ERROR("Burst mode target is not set\n");
777 : 0 : return false;
778 : : }
779 : : } else
780 : : burst_mode_ratio = 100;
781 : :
782 : 0 : intel_dsi->burst_mode_ratio = burst_mode_ratio;
783 : :
784 : : /* delays in VBT are in unit of 100us, so need to convert
785 : : * here in ms
786 : : * Delay (100us) * 100 /1000 = Delay / 10 (ms) */
787 : 0 : intel_dsi->backlight_off_delay = pps->bl_disable_delay / 10;
788 : 0 : intel_dsi->backlight_on_delay = pps->bl_enable_delay / 10;
789 : 0 : intel_dsi->panel_on_delay = pps->panel_on_delay / 10;
790 : 0 : intel_dsi->panel_off_delay = pps->panel_off_delay / 10;
791 : 0 : intel_dsi->panel_pwr_cycle_delay = pps->panel_power_cycle_delay / 10;
792 : :
793 : 0 : intel_dsi->i2c_bus_num = -1;
794 : :
795 : : /* a regular driver would get the device in probe */
796 [ # # # # ]: 0 : for_each_dsi_port(port, intel_dsi->ports) {
797 : 0 : mipi_dsi_attach(intel_dsi->dsi_hosts[port]->device);
798 : : }
799 : :
800 : : return true;
801 : : }
802 : :
803 : : /*
804 : : * On some BYT/CHT devs some sequences are incomplete and we need to manually
805 : : * control some GPIOs. We need to add a GPIO lookup table before we get these.
806 : : * If the GOP did not initialize the panel (HDMI inserted) we may need to also
807 : : * change the pinmux for the SoC's PWM0 pin from GPIO to PWM.
808 : : */
809 : : static struct gpiod_lookup_table pmic_panel_gpio_table = {
810 : : /* Intel GFX is consumer */
811 : : .dev_id = "0000:00:02.0",
812 : : .table = {
813 : : /* Panel EN/DISABLE */
814 : : GPIO_LOOKUP("gpio_crystalcove", 94, "panel", GPIO_ACTIVE_HIGH),
815 : : { }
816 : : },
817 : : };
818 : :
819 : : static struct gpiod_lookup_table soc_panel_gpio_table = {
820 : : .dev_id = "0000:00:02.0",
821 : : .table = {
822 : : GPIO_LOOKUP("INT33FC:01", 10, "backlight", GPIO_ACTIVE_HIGH),
823 : : GPIO_LOOKUP("INT33FC:01", 11, "panel", GPIO_ACTIVE_HIGH),
824 : : { }
825 : : },
826 : : };
827 : :
828 : : static const struct pinctrl_map soc_pwm_pinctrl_map[] = {
829 : : PIN_MAP_MUX_GROUP("0000:00:02.0", "soc_pwm0", "INT33FC:00",
830 : : "pwm0_grp", "pwm"),
831 : : };
832 : :
833 : 0 : void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on)
834 : : {
835 : 0 : struct drm_device *dev = intel_dsi->base.base.dev;
836 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(dev);
837 : 0 : struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
838 : 0 : enum gpiod_flags flags = panel_is_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
839 : 0 : bool want_backlight_gpio = false;
840 : 0 : bool want_panel_gpio = false;
841 : 0 : struct pinctrl *pinctrl;
842 : 0 : int ret;
843 : :
844 [ # # # # ]: 0 : if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
845 [ # # ]: 0 : mipi_config->pwm_blc == PPS_BLC_PMIC) {
846 : 0 : gpiod_add_lookup_table(&pmic_panel_gpio_table);
847 : 0 : want_panel_gpio = true;
848 : : }
849 : :
850 [ # # # # ]: 0 : if (IS_VALLEYVIEW(dev_priv) && mipi_config->pwm_blc == PPS_BLC_SOC) {
851 : : gpiod_add_lookup_table(&soc_panel_gpio_table);
852 : : want_panel_gpio = true;
853 : : want_backlight_gpio = true;
854 : :
855 : : /* Ensure PWM0 pin is muxed as PWM instead of GPIO */
856 : : ret = pinctrl_register_mappings(soc_pwm_pinctrl_map,
857 : : ARRAY_SIZE(soc_pwm_pinctrl_map));
858 : : if (ret)
859 : : DRM_ERROR("Failed to register pwm0 pinmux mapping\n");
860 : :
861 : : pinctrl = devm_pinctrl_get_select(dev->dev, "soc_pwm0");
862 : : if (IS_ERR(pinctrl))
863 : : DRM_ERROR("Failed to set pinmux to PWM\n");
864 : : }
865 : :
866 [ # # ]: 0 : if (want_panel_gpio) {
867 : 0 : intel_dsi->gpio_panel = gpiod_get(dev->dev, "panel", flags);
868 : 0 : if (IS_ERR(intel_dsi->gpio_panel)) {
869 : 0 : DRM_ERROR("Failed to own gpio for panel control\n");
870 : 0 : intel_dsi->gpio_panel = NULL;
871 : : }
872 : : }
873 : :
874 [ # # ]: 0 : if (want_backlight_gpio) {
875 : 0 : intel_dsi->gpio_backlight =
876 : : gpiod_get(dev->dev, "backlight", flags);
877 : 0 : if (IS_ERR(intel_dsi->gpio_backlight)) {
878 : 0 : DRM_ERROR("Failed to own gpio for backlight control\n");
879 : 0 : intel_dsi->gpio_backlight = NULL;
880 : : }
881 : : }
882 : 0 : }
883 : :
884 : 0 : void intel_dsi_vbt_gpio_cleanup(struct intel_dsi *intel_dsi)
885 : : {
886 : 0 : struct drm_device *dev = intel_dsi->base.base.dev;
887 [ # # ]: 0 : struct drm_i915_private *dev_priv = to_i915(dev);
888 : 0 : struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
889 : :
890 [ # # ]: 0 : if (intel_dsi->gpio_panel) {
891 : 0 : gpiod_put(intel_dsi->gpio_panel);
892 : 0 : intel_dsi->gpio_panel = NULL;
893 : : }
894 : :
895 [ # # ]: 0 : if (intel_dsi->gpio_backlight) {
896 : 0 : gpiod_put(intel_dsi->gpio_backlight);
897 : 0 : intel_dsi->gpio_backlight = NULL;
898 : : }
899 : :
900 : 0 : if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
901 : : mipi_config->pwm_blc == PPS_BLC_PMIC)
902 : : gpiod_remove_lookup_table(&pmic_panel_gpio_table);
903 : :
904 : 0 : if (IS_VALLEYVIEW(dev_priv) && mipi_config->pwm_blc == PPS_BLC_SOC) {
905 : : pinctrl_unregister_mappings(soc_pwm_pinctrl_map);
906 : : gpiod_remove_lookup_table(&soc_panel_gpio_table);
907 : : }
908 : 0 : }
|