blob: 1164e6f2f9af853dcfa0b1c58dcc5a5678fbb5a6 [file] [log] [blame]
raghavendra ambadasa46d3882019-05-22 17:14:21 +05301/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <linux/spinlock.h>
17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/of_device.h>
20#include <linux/of_gpio.h>
21#include <linux/gpio.h>
22#include <linux/err.h>
23#include <linux/regulator/consumer.h>
24#include <linux/leds-qpnp-wled.h>
25#include <linux/clk.h>
26#include <linux/uaccess.h>
27#include <linux/msm-bus.h>
28#include <linux/pm_qos.h>
Sachin Bhayare3d3767e2018-01-02 21:10:57 +053029#include <linux/mdss_io_util.h>
Sandeep Panda812f5002017-02-24 11:36:59 +053030#include <linux/dma-buf.h>
Sachin Bhayareeeb88892018-01-02 16:36:01 +053031
32#include "mdss.h"
33#include "mdss_panel.h"
34#include "mdss_dsi.h"
35#include "mdss_debug.h"
36#include "mdss_dsi_phy.h"
37#include "mdss_dba_utils.h"
38
39#define XO_CLK_RATE 19200000
40#define CMDLINE_DSI_CTL_NUM_STRING_LEN 2
41
42/* Master structure to hold all the information about the DSI/panel */
43static struct mdss_dsi_data *mdss_dsi_res;
44
45#define DSI_DISABLE_PC_LATENCY 100
46#define DSI_ENABLE_PC_LATENCY PM_QOS_DEFAULT_VALUE
47
48static struct pm_qos_request mdss_dsi_pm_qos_request;
49
Sandeep Panda812f5002017-02-24 11:36:59 +053050void mdss_dump_dsi_debug_bus(u32 bus_dump_flag,
51 u32 **dump_mem)
52{
53 struct mdss_dsi_data *sdata = mdss_dsi_res;
54 struct mdss_dsi_ctrl_pdata *m_ctrl, *s_ctrl;
55 bool in_log, in_mem;
56 u32 *dump_addr = NULL;
57 u32 status0 = 0, status1 = 0;
58 phys_addr_t phys = 0;
59 int list_size = 0;
60 int i;
61 bool dsi0_active = false, dsi1_active = false;
62
63 if (!sdata || !sdata->dbg_bus || !sdata->dbg_bus_size)
64 return;
65
66 m_ctrl = sdata->ctrl_pdata[0];
67 s_ctrl = sdata->ctrl_pdata[1];
68
69 if (!m_ctrl)
70 return;
71
72 if (m_ctrl && m_ctrl->shared_data->dsi0_active)
73 dsi0_active = true;
74 if (s_ctrl && s_ctrl->shared_data->dsi1_active)
75 dsi1_active = true;
76
77 list_size = (sdata->dbg_bus_size * sizeof(sdata->dbg_bus[0]) * 4);
78
79 in_log = (bus_dump_flag & MDSS_DBG_DUMP_IN_LOG);
80 in_mem = (bus_dump_flag & MDSS_DBG_DUMP_IN_MEM);
81
82 if (in_mem) {
83 if (!(*dump_mem))
84 *dump_mem = dma_alloc_coherent(&sdata->pdev->dev,
85 list_size, &phys, GFP_KERNEL);
86
87 if (*dump_mem) {
88 dump_addr = *dump_mem;
89 pr_info("%s: start_addr:0x%pK end_addr:0x%pK\n",
90 __func__, dump_addr, dump_addr + list_size);
91 } else {
92 in_mem = false;
93 pr_err("dump_mem: allocation fails\n");
94 }
95 }
96
97 pr_info("========= Start DSI Debug Bus =========\n");
98
99 mdss_dsi_clk_ctrl(m_ctrl, m_ctrl->dsi_clk_handle,
100 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_ON);
101
102 for (i = 0; i < sdata->dbg_bus_size; i++) {
103 if (dsi0_active) {
104 writel_relaxed(sdata->dbg_bus[i],
105 m_ctrl->ctrl_base + 0x124);
106 wmb(); /* ensure regsiter is committed */
107 }
108 if (dsi1_active) {
109 writel_relaxed(sdata->dbg_bus[i],
110 s_ctrl->ctrl_base + 0x124);
111 wmb(); /* ensure register is committed */
112 }
113
114 if (dsi0_active) {
115 status0 = readl_relaxed(m_ctrl->ctrl_base + 0x128);
116 if (in_log)
117 pr_err("CTRL:0 bus_ctrl: 0x%x status: 0x%x\n",
118 sdata->dbg_bus[i], status0);
119 }
120 if (dsi1_active) {
121 status1 = readl_relaxed(s_ctrl->ctrl_base + 0x128);
122 if (in_log)
123 pr_err("CTRL:1 bus_ctrl: 0x%x status: 0x%x\n",
124 sdata->dbg_bus[i], status1);
125 }
126
127 if (dump_addr && in_mem) {
128 dump_addr[i*4] = sdata->dbg_bus[i];
129 dump_addr[i*4 + 1] = status0;
130 dump_addr[i*4 + 2] = status1;
131 dump_addr[i*4 + 3] = 0x0;
132 }
133 }
134
135 mdss_dsi_clk_ctrl(m_ctrl, m_ctrl->dsi_clk_handle,
136 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_OFF);
137
138 pr_info("========End DSI Debug Bus=========\n");
139}
140
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530141static void mdss_dsi_pm_qos_add_request(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
142{
143 struct irq_info *irq_info;
144
145 if (!ctrl_pdata || !ctrl_pdata->shared_data)
146 return;
147
148 irq_info = ctrl_pdata->dsi_hw->irq_info;
149
150 if (!irq_info)
151 return;
152
153 mutex_lock(&ctrl_pdata->shared_data->pm_qos_lock);
154 if (!ctrl_pdata->shared_data->pm_qos_req_cnt) {
155 pr_debug("%s: add request irq\n", __func__);
156
157 mdss_dsi_pm_qos_request.type = PM_QOS_REQ_AFFINE_IRQ;
158 mdss_dsi_pm_qos_request.irq = irq_info->irq;
159 pm_qos_add_request(&mdss_dsi_pm_qos_request,
160 PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
161 }
162 ctrl_pdata->shared_data->pm_qos_req_cnt++;
163 mutex_unlock(&ctrl_pdata->shared_data->pm_qos_lock);
164}
165
166static void mdss_dsi_pm_qos_remove_request(struct dsi_shared_data *sdata)
167{
168 if (!sdata)
169 return;
170
171 mutex_lock(&sdata->pm_qos_lock);
172 if (sdata->pm_qos_req_cnt) {
173 sdata->pm_qos_req_cnt--;
174 if (!sdata->pm_qos_req_cnt) {
175 pr_debug("%s: remove request", __func__);
176 pm_qos_remove_request(&mdss_dsi_pm_qos_request);
177 }
178 } else {
179 pr_warn("%s: unbalanced pm_qos ref count\n", __func__);
180 }
181 mutex_unlock(&sdata->pm_qos_lock);
182}
183
184static void mdss_dsi_pm_qos_update_request(int val)
185{
186 pr_debug("%s: update request %d", __func__, val);
187 pm_qos_update_request(&mdss_dsi_pm_qos_request, val);
188}
189
190static int mdss_dsi_pinctrl_set_state(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
191 bool active);
192
193static struct mdss_dsi_ctrl_pdata *mdss_dsi_get_ctrl(u32 ctrl_id)
194{
195 if (ctrl_id >= DSI_CTRL_MAX || !mdss_dsi_res)
196 return NULL;
197
198 return mdss_dsi_res->ctrl_pdata[ctrl_id];
199}
200
201static void mdss_dsi_config_clk_src(struct platform_device *pdev)
202{
203 struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev);
204 struct dsi_shared_data *sdata = dsi_res->shared_data;
205
206 if (!sdata->ext_byte0_clk || !sdata->ext_pixel0_clk) {
207 pr_debug("%s: DSI-0 ext. clocks not present\n", __func__);
208 return;
209 }
210
211 if (mdss_dsi_is_pll_src_default(sdata)) {
212 /*
213 * Default Mapping:
214 * 1. dual-dsi/single-dsi:
215 * DSI0 <--> PLL0
216 * DSI1 <--> PLL1
217 * 2. split-dsi:
218 * DSI0 <--> PLL0
219 * DSI1 <--> PLL0
220 */
221 sdata->byte0_parent = sdata->ext_byte0_clk;
222 sdata->pixel0_parent = sdata->ext_pixel0_clk;
223
224 if (mdss_dsi_is_hw_config_split(sdata)) {
225 sdata->byte1_parent = sdata->byte0_parent;
226 sdata->pixel1_parent = sdata->pixel0_parent;
227 } else if (sdata->ext_byte1_clk && sdata->ext_pixel1_clk) {
228 sdata->byte1_parent = sdata->ext_byte1_clk;
229 sdata->pixel1_parent = sdata->ext_pixel1_clk;
230 } else {
231 pr_debug("%s: DSI-1 external clocks not present\n",
232 __func__);
233 return;
234 }
235
236 pr_debug("%s: default: DSI0 <--> PLL0, DSI1 <--> %s", __func__,
237 mdss_dsi_is_hw_config_split(sdata) ? "PLL0" : "PLL1");
238 } else {
239 /*
240 * For split-dsi and single-dsi use cases, map the PLL source
241 * based on the pll source configuration. It is possible that
242 * for split-dsi case, the only supported config is to source
243 * the clocks from PLL0. This is not explicitly checked here as
244 * it should have been already enforced when validating the
245 * board configuration.
246 */
247 if (mdss_dsi_is_pll_src_pll0(sdata)) {
248 pr_debug("%s: single source: PLL0", __func__);
249 sdata->byte0_parent = sdata->ext_byte0_clk;
250 sdata->pixel0_parent = sdata->ext_pixel0_clk;
251 } else if (mdss_dsi_is_pll_src_pll1(sdata)) {
252 if (sdata->ext_byte1_clk && sdata->ext_pixel1_clk) {
253 pr_debug("%s: single source: PLL1", __func__);
254 sdata->byte0_parent = sdata->ext_byte1_clk;
255 sdata->pixel0_parent = sdata->ext_pixel1_clk;
256 } else {
257 pr_err("%s: DSI-1 external clocks not present\n",
258 __func__);
259 return;
260 }
261 }
262 sdata->byte1_parent = sdata->byte0_parent;
263 sdata->pixel1_parent = sdata->pixel0_parent;
264 }
265}
266
267static char const *mdss_dsi_get_clk_src(struct mdss_dsi_ctrl_pdata *ctrl)
268{
269 struct dsi_shared_data *sdata;
270
271 if (!ctrl) {
272 pr_err("%s: Invalid input data\n", __func__);
273 return "????";
274 }
275
276 sdata = ctrl->shared_data;
277
278 if (mdss_dsi_is_left_ctrl(ctrl)) {
279 if (sdata->byte0_parent == sdata->ext_byte0_clk)
280 return "PLL0";
281 else
282 return "PLL1";
283 } else {
284 if (sdata->byte1_parent == sdata->ext_byte0_clk)
285 return "PLL0";
286 else
287 return "PLL1";
288 }
289}
290
291static int mdss_dsi_set_clk_src(struct mdss_dsi_ctrl_pdata *ctrl)
292{
293 int rc;
294 struct dsi_shared_data *sdata;
295 struct clk *byte_parent, *pixel_parent;
296
297 if (!ctrl) {
298 pr_err("%s: Invalid input data\n", __func__);
299 return -EINVAL;
300 }
301
302 sdata = ctrl->shared_data;
303
304 if (!ctrl->byte_clk_rcg || !ctrl->pixel_clk_rcg) {
305 pr_debug("%s: set_clk_src not needed\n", __func__);
306 return 0;
307 }
308
309 if (mdss_dsi_is_left_ctrl(ctrl)) {
310 byte_parent = sdata->byte0_parent;
311 pixel_parent = sdata->pixel0_parent;
312 } else {
313 byte_parent = sdata->byte1_parent;
314 pixel_parent = sdata->pixel1_parent;
315 }
316
317 rc = clk_set_parent(ctrl->byte_clk_rcg, byte_parent);
318 if (rc) {
319 pr_err("%s: failed to set parent for byte clk for ctrl%d. rc=%d\n",
320 __func__, ctrl->ndx, rc);
321 goto error;
322 }
323
324 rc = clk_set_parent(ctrl->pixel_clk_rcg, pixel_parent);
325 if (rc) {
326 pr_err("%s: failed to set parent for pixel clk for ctrl%d. rc=%d\n",
327 __func__, ctrl->ndx, rc);
328 goto error;
329 }
330
331 pr_debug("%s: ctrl%d clock source set to %s", __func__, ctrl->ndx,
332 mdss_dsi_get_clk_src(ctrl));
333
334error:
335 return rc;
336}
337
338static int mdss_dsi_regulator_init(struct platform_device *pdev,
339 struct dsi_shared_data *sdata)
340{
341 int rc = 0, i = 0, j = 0;
342
343 if (!pdev || !sdata) {
344 pr_err("%s: invalid input\n", __func__);
345 return -EINVAL;
346 }
347
348 for (i = DSI_CORE_PM; !rc && (i < DSI_MAX_PM); i++) {
Sachin Bhayare5076e252018-01-18 14:56:45 +0530349 rc = msm_mdss_config_vreg(&pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530350 sdata->power_data[i].vreg_config,
351 sdata->power_data[i].num_vreg, 1);
352 if (rc) {
353 pr_err("%s: failed to init vregs for %s\n",
354 __func__, __mdss_dsi_pm_name(i));
355 for (j = i-1; j >= DSI_CORE_PM; j--) {
Sachin Bhayare5076e252018-01-18 14:56:45 +0530356 msm_mdss_config_vreg(&pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530357 sdata->power_data[j].vreg_config,
358 sdata->power_data[j].num_vreg, 0);
359 }
360 }
361 }
362
363 return rc;
364}
365
366static int mdss_dsi_panel_power_off(struct mdss_panel_data *pdata)
367{
368 int ret = 0;
369 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
370
371 if (pdata == NULL) {
372 pr_err("%s: Invalid input data\n", __func__);
373 ret = -EINVAL;
374 goto end;
375 }
376
377 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
378 panel_data);
379
380 ret = mdss_dsi_panel_reset(pdata, 0);
381 if (ret) {
382 pr_warn("%s: Panel reset failed. rc=%d\n", __func__, ret);
383 ret = 0;
384 }
385
Narender Ankam4fcd6892018-06-11 13:09:00 +0530386 if (gpio_is_valid(ctrl_pdata->vdd_ext_gpio)) {
387 ret = gpio_direction_output(
388 ctrl_pdata->vdd_ext_gpio, 0);
389 if (ret)
390 pr_err("%s: unable to set dir for vdd gpio\n",
391 __func__);
392 }
393
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530394 if (mdss_dsi_pinctrl_set_state(ctrl_pdata, false))
395 pr_debug("reset disable: pinctrl not enabled\n");
396
Sachin Bhayare5076e252018-01-18 14:56:45 +0530397 ret = msm_mdss_enable_vreg(
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530398 ctrl_pdata->panel_power_data.vreg_config,
399 ctrl_pdata->panel_power_data.num_vreg, 0);
400 if (ret)
401 pr_err("%s: failed to disable vregs for %s\n",
402 __func__, __mdss_dsi_pm_name(DSI_PANEL_PM));
403
404end:
405 return ret;
406}
407
408static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata)
409{
410 int ret = 0;
411 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
412
413 if (pdata == NULL) {
414 pr_err("%s: Invalid input data\n", __func__);
415 return -EINVAL;
416 }
417
418 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
419 panel_data);
420
Narender Ankam4fcd6892018-06-11 13:09:00 +0530421 if (gpio_is_valid(ctrl_pdata->vdd_ext_gpio)) {
422 ret = gpio_direction_output(
423 ctrl_pdata->vdd_ext_gpio, 1);
424 usleep_range(3000, 4000); /* h/w recommended delay */
425 if (ret)
426 pr_err("%s: unable to set dir for vdd gpio\n",
427 __func__);
428 }
429
Sachin Bhayare5076e252018-01-18 14:56:45 +0530430 ret = msm_mdss_enable_vreg(
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530431 ctrl_pdata->panel_power_data.vreg_config,
432 ctrl_pdata->panel_power_data.num_vreg, 1);
433 if (ret) {
434 pr_err("%s: failed to enable vregs for %s\n",
435 __func__, __mdss_dsi_pm_name(DSI_PANEL_PM));
436 return ret;
437 }
438
439 /*
440 * If continuous splash screen feature is enabled, then we need to
441 * request all the GPIOs that have already been configured in the
442 * bootloader. This needs to be done irresepective of whether
443 * the lp11_init flag is set or not.
444 */
445 if (pdata->panel_info.cont_splash_enabled ||
446 !pdata->panel_info.mipi.lp11_init) {
447 if (mdss_dsi_pinctrl_set_state(ctrl_pdata, true))
448 pr_debug("reset enable: pinctrl not enabled\n");
449
450 ret = mdss_dsi_panel_reset(pdata, 1);
451 if (ret)
452 pr_err("%s: Panel reset failed. rc=%d\n",
453 __func__, ret);
454 }
455
456 return ret;
457}
458
459static int mdss_dsi_panel_power_lp(struct mdss_panel_data *pdata, int enable)
460{
461 /* Panel power control when entering/exiting lp mode */
462 return 0;
463}
464
465static int mdss_dsi_panel_power_ulp(struct mdss_panel_data *pdata,
466 int enable)
467{
468 int ret = 0, i;
469 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
470 u32 mode = enable ? DSS_REG_MODE_ULP : DSS_REG_MODE_ENABLE;
471 struct dsi_shared_data *sdata;
472
473 pr_debug("%s: +\n", __func__);
474 if (pdata == NULL) {
475 pr_err("%s: Invalid input data\n", __func__);
476 return -EINVAL;
477 }
478
479 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
480 panel_data);
481 sdata = ctrl_pdata->shared_data;
482
483 for (i = 0; i < DSI_MAX_PM; i++) {
484 /*
485 * Core power module need to be controlled along with
486 * DSI core clocks.
487 */
488 if (i == DSI_CORE_PM)
489 continue;
490 if (i == DSI_PANEL_PM)
Sachin Bhayare5076e252018-01-18 14:56:45 +0530491 ret = msm_mdss_config_vreg_opt_mode(
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530492 ctrl_pdata->panel_power_data.vreg_config,
493 ctrl_pdata->panel_power_data.num_vreg, mode);
494 else
Sachin Bhayare5076e252018-01-18 14:56:45 +0530495 ret = msm_mdss_config_vreg_opt_mode(
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530496 sdata->power_data[i].vreg_config,
497 sdata->power_data[i].num_vreg, mode);
498 if (ret) {
499 pr_err("%s: failed to config ulp opt mode for %s.rc=%d\n",
500 __func__, __mdss_dsi_pm_name(i), ret);
501 break;
502 }
503 }
504
505 if (ret) {
506 mode = enable ? DSS_REG_MODE_ENABLE : DSS_REG_MODE_ULP;
507 for (; i >= 0; i--)
Sachin Bhayare5076e252018-01-18 14:56:45 +0530508 msm_mdss_config_vreg_opt_mode(
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530509 ctrl_pdata->power_data[i].vreg_config,
510 ctrl_pdata->power_data[i].num_vreg, mode);
511 }
512 return ret;
513}
514
515int mdss_dsi_panel_power_ctrl(struct mdss_panel_data *pdata,
516 int power_state)
517{
Sachin Bhayare3d3767e2018-01-02 21:10:57 +0530518 int ret = 0;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530519 struct mdss_panel_info *pinfo;
520 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
521
522 if (pdata == NULL) {
523 pr_err("%s: Invalid input data\n", __func__);
524 return -EINVAL;
525 }
526
527 pinfo = &pdata->panel_info;
528 pr_debug("%pS-->%s: cur_power_state=%d req_power_state=%d\n",
529 __builtin_return_address(0), __func__,
530 pinfo->panel_power_state, power_state);
531
532 if (pinfo->panel_power_state == power_state) {
533 pr_debug("%s: no change needed\n", __func__);
534 return 0;
535 }
536
537 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
538 panel_data);
539
540 /*
541 * If a dynamic mode switch is pending, the regulators should not
542 * be turned off or on.
543 */
544 if (pdata->panel_info.dynamic_switch_pending)
545 return 0;
546
547 switch (power_state) {
548 case MDSS_PANEL_POWER_OFF:
549 ret = mdss_dsi_panel_power_off(pdata);
550 break;
551 case MDSS_PANEL_POWER_ON:
552 if (mdss_dsi_is_panel_on_ulp(pdata)) {
553 ret = mdss_dsi_panel_power_ulp(pdata, false);
554 goto end;
555 } else if (mdss_dsi_is_panel_on_lp(pdata)) {
556 ret = mdss_dsi_panel_power_lp(pdata, false);
557 goto end;
558 } else {
559 ret = mdss_dsi_panel_power_on(pdata);
560 }
561 break;
562 case MDSS_PANEL_POWER_LP1:
563 if (mdss_dsi_is_panel_on_ulp(pdata))
564 ret = mdss_dsi_panel_power_ulp(pdata, false);
565 else
566 ret = mdss_dsi_panel_power_lp(pdata, true);
567 /*
568 * temp workaround until framework issues pertaining to LP2
569 * power state transitions are fixed. For now, we internally
570 * transition to LP2 state whenever core power is turned off
571 * in LP1 state
572 */
573 break;
574 case MDSS_PANEL_POWER_LP2:
575 if (!ctrl_pdata->core_power)
576 ret = mdss_dsi_panel_power_ulp(pdata, true);
577 break;
578 default:
579 pr_err("%s: unknown panel power state requested (%d)\n",
580 __func__, power_state);
581 ret = -EINVAL;
582 }
583
584 if (!ret)
585 pinfo->panel_power_state = power_state;
586end:
587 return ret;
588}
589
590static void mdss_dsi_put_dt_vreg_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +0530591 struct mdss_module_power *module_power)
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530592{
593 if (!module_power) {
594 pr_err("%s: invalid input\n", __func__);
595 return;
596 }
597
598 if (module_power->vreg_config) {
599 devm_kfree(dev, module_power->vreg_config);
600 module_power->vreg_config = NULL;
601 }
602 module_power->num_vreg = 0;
603}
604
605static int mdss_dsi_get_dt_vreg_data(struct device *dev,
Sachin Bhayare5076e252018-01-18 14:56:45 +0530606 struct device_node *of_node, struct mdss_module_power *mp,
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530607 enum dsi_pm_type module)
608{
609 int i = 0, rc = 0;
610 u32 tmp = 0;
611 struct device_node *supply_node = NULL;
612 const char *pm_supply_name = NULL;
613 struct device_node *supply_root_node = NULL;
614
615 if (!dev || !mp) {
616 pr_err("%s: invalid input\n", __func__);
617 rc = -EINVAL;
618 return rc;
619 }
620
621 mp->num_vreg = 0;
622 pm_supply_name = __mdss_dsi_pm_supply_node_name(module);
623 supply_root_node = of_get_child_by_name(of_node, pm_supply_name);
624 if (!supply_root_node) {
625 /*
626 * Try to get the root node for panel power supply using
627 * of_parse_phandle() API if of_get_child_by_name() API fails.
628 */
629 supply_root_node = of_parse_phandle(of_node, pm_supply_name, 0);
630 if (!supply_root_node) {
631 pr_err("no supply entry present: %s\n", pm_supply_name);
632 goto novreg;
633 }
634 }
635
636
637 for_each_child_of_node(supply_root_node, supply_node) {
638 mp->num_vreg++;
639 }
640
641 if (mp->num_vreg == 0) {
642 pr_debug("%s: no vreg\n", __func__);
643 goto novreg;
644 } else {
645 pr_debug("%s: vreg found. count=%d\n", __func__, mp->num_vreg);
646 }
647
Sachin Bhayare5076e252018-01-18 14:56:45 +0530648 mp->vreg_config = devm_kzalloc(dev, sizeof(struct mdss_vreg) *
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530649 mp->num_vreg, GFP_KERNEL);
650 if (!mp->vreg_config) {
651 rc = -ENOMEM;
652 goto error;
653 }
654
655 for_each_child_of_node(supply_root_node, supply_node) {
656 const char *st = NULL;
657 /* vreg-name */
658 rc = of_property_read_string(supply_node,
659 "qcom,supply-name", &st);
660 if (rc) {
661 pr_err("%s: error reading name. rc=%d\n",
662 __func__, rc);
663 goto error;
664 }
665 snprintf(mp->vreg_config[i].vreg_name,
666 ARRAY_SIZE((mp->vreg_config[i].vreg_name)), "%s", st);
667 /* vreg-min-voltage */
668 rc = of_property_read_u32(supply_node,
669 "qcom,supply-min-voltage", &tmp);
670 if (rc) {
671 pr_err("%s: error reading min volt. rc=%d\n",
672 __func__, rc);
673 goto error;
674 }
675 mp->vreg_config[i].min_voltage = tmp;
676
677 /* vreg-max-voltage */
678 rc = of_property_read_u32(supply_node,
679 "qcom,supply-max-voltage", &tmp);
680 if (rc) {
681 pr_err("%s: error reading max volt. rc=%d\n",
682 __func__, rc);
683 goto error;
684 }
685 mp->vreg_config[i].max_voltage = tmp;
686
687 /* enable-load */
688 rc = of_property_read_u32(supply_node,
689 "qcom,supply-enable-load", &tmp);
690 if (rc) {
691 pr_err("%s: error reading enable load. rc=%d\n",
692 __func__, rc);
693 goto error;
694 }
695 mp->vreg_config[i].load[DSS_REG_MODE_ENABLE] = tmp;
696
697 /* disable-load */
698 rc = of_property_read_u32(supply_node,
699 "qcom,supply-disable-load", &tmp);
700 if (rc) {
701 pr_err("%s: error reading disable load. rc=%d\n",
702 __func__, rc);
703 goto error;
704 }
705 mp->vreg_config[i].load[DSS_REG_MODE_DISABLE] = tmp;
706
707 /* ulp-load */
708 rc = of_property_read_u32(supply_node,
709 "qcom,supply-ulp-load", &tmp);
710 if (rc) {
711 pr_warn("%s: error reading ulp load. rc=%d\n",
712 __func__, rc);
713 rc = 0;
714 }
715 mp->vreg_config[i].load[DSS_REG_MODE_ULP] = (!rc ? tmp :
716 mp->vreg_config[i].load[DSS_REG_MODE_ENABLE]);
717
718 /* pre-sleep */
719 rc = of_property_read_u32(supply_node,
720 "qcom,supply-pre-on-sleep", &tmp);
721 if (rc) {
722 pr_debug("%s: error reading supply pre sleep value. rc=%d\n",
723 __func__, rc);
724 rc = 0;
725 } else {
726 mp->vreg_config[i].pre_on_sleep = tmp;
727 }
728
729 rc = of_property_read_u32(supply_node,
730 "qcom,supply-pre-off-sleep", &tmp);
731 if (rc) {
732 pr_debug("%s: error reading supply pre sleep value. rc=%d\n",
733 __func__, rc);
734 rc = 0;
735 } else {
736 mp->vreg_config[i].pre_off_sleep = tmp;
737 }
738
739 /* post-sleep */
740 rc = of_property_read_u32(supply_node,
741 "qcom,supply-post-on-sleep", &tmp);
742 if (rc) {
743 pr_debug("%s: error reading supply post sleep value. rc=%d\n",
744 __func__, rc);
745 rc = 0;
746 } else {
747 mp->vreg_config[i].post_on_sleep = tmp;
748 }
749
750 rc = of_property_read_u32(supply_node,
751 "qcom,supply-post-off-sleep", &tmp);
752 if (rc) {
753 pr_debug("%s: error reading supply post sleep value. rc=%d\n",
754 __func__, rc);
755 rc = 0;
756 } else {
757 mp->vreg_config[i].post_off_sleep = tmp;
758 }
759
760 pr_debug("%s: %s min=%d, max=%d, enable=%d, disable=%d, ulp_load=%d preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%d\n",
761 __func__,
762 mp->vreg_config[i].vreg_name,
763 mp->vreg_config[i].min_voltage,
764 mp->vreg_config[i].max_voltage,
765 mp->vreg_config[i].load[DSS_REG_MODE_ENABLE],
766 mp->vreg_config[i].load[DSS_REG_MODE_DISABLE],
767 mp->vreg_config[i].load[DSS_REG_MODE_ULP],
768 mp->vreg_config[i].pre_on_sleep,
769 mp->vreg_config[i].post_on_sleep,
770 mp->vreg_config[i].pre_off_sleep,
771 mp->vreg_config[i].post_off_sleep
772 );
773 ++i;
774 }
775
776 return rc;
777
778error:
779 if (mp->vreg_config) {
780 devm_kfree(dev, mp->vreg_config);
781 mp->vreg_config = NULL;
782 }
783novreg:
784 mp->num_vreg = 0;
785
786 return rc;
787}
788
789static int mdss_dsi_get_panel_cfg(char *panel_cfg,
790 struct mdss_dsi_ctrl_pdata *ctrl)
791{
792 int rc;
793 struct mdss_panel_cfg *pan_cfg = NULL;
794
795 if (!panel_cfg)
796 return MDSS_PANEL_INTF_INVALID;
797
798 pan_cfg = ctrl->mdss_util->panel_intf_type(MDSS_PANEL_INTF_DSI);
799 if (IS_ERR(pan_cfg)) {
800 return PTR_ERR(pan_cfg);
801 } else if (!pan_cfg) {
802 panel_cfg[0] = 0;
803 return 0;
804 }
805
806 pr_debug("%s:%d: cfg:[%s]\n", __func__, __LINE__,
807 pan_cfg->arg_cfg);
808 rc = strlcpy(panel_cfg, pan_cfg->arg_cfg,
809 sizeof(pan_cfg->arg_cfg));
810 return rc;
811}
812
813struct buf_data {
814 char *buf; /* cmd buf */
815 int blen; /* cmd buf length */
816 char *string_buf; /* cmd buf as string, 3 bytes per number */
817 int sblen; /* string buffer length */
818 int sync_flag;
819 struct mutex dbg_mutex; /* mutex to synchronize read/write/flush */
820};
821
822struct mdss_dsi_debugfs_info {
823 struct dentry *root;
824 struct mdss_dsi_ctrl_pdata ctrl_pdata;
825 struct buf_data on_cmd;
826 struct buf_data off_cmd;
827 u32 override_flag;
828};
829
830static int mdss_dsi_cmd_state_open(struct inode *inode, struct file *file)
831{
832 /* non-seekable */
833 file->private_data = inode->i_private;
834 return nonseekable_open(inode, file);
835}
836
837static ssize_t mdss_dsi_cmd_state_read(struct file *file, char __user *buf,
838 size_t count, loff_t *ppos)
839{
840 int *link_state = file->private_data;
841 char buffer[32];
842 int blen = 0;
843
844 if (*ppos)
845 return 0;
846
847 if ((*link_state) == DSI_HS_MODE)
848 blen = snprintf(buffer, sizeof(buffer), "dsi_hs_mode\n");
849 else
850 blen = snprintf(buffer, sizeof(buffer), "dsi_lp_mode\n");
851
852 if (blen < 0)
853 return 0;
854
Rashi Bindra1dba4522018-04-04 17:58:15 +0530855 if (copy_to_user(buf, buffer, min(count, (size_t)blen+1)))
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530856 return -EFAULT;
857
858 *ppos += blen;
859 return blen;
860}
861
862static ssize_t mdss_dsi_cmd_state_write(struct file *file,
863 const char __user *p, size_t count, loff_t *ppos)
864{
865 int *link_state = file->private_data;
866 char *input;
867
868 if (!count) {
869 pr_err("%s: Zero bytes to be written\n", __func__);
870 return -EINVAL;
871 }
872
873 input = kmalloc(count, GFP_KERNEL);
874 if (!input)
875 return -ENOMEM;
876
877 if (copy_from_user(input, p, count)) {
878 kfree(input);
879 return -EFAULT;
880 }
881 input[count-1] = '\0';
882
883 if (strnstr(input, "dsi_hs_mode", strlen("dsi_hs_mode")))
884 *link_state = DSI_HS_MODE;
885 else
886 *link_state = DSI_LP_MODE;
887
888 kfree(input);
889 return count;
890}
891
892static const struct file_operations mdss_dsi_cmd_state_fop = {
893 .open = mdss_dsi_cmd_state_open,
894 .read = mdss_dsi_cmd_state_read,
895 .write = mdss_dsi_cmd_state_write,
896};
897
898static int mdss_dsi_cmd_open(struct inode *inode, struct file *file)
899{
900 /* non-seekable */
901 file->private_data = inode->i_private;
902 return nonseekable_open(inode, file);
903}
904
905static ssize_t mdss_dsi_cmd_read(struct file *file, char __user *buf,
906 size_t count, loff_t *ppos)
907{
908 struct buf_data *pcmds = file->private_data;
909 char *bp;
910 ssize_t ret = 0;
911
912 mutex_lock(&pcmds->dbg_mutex);
913 if (*ppos == 0) {
914 kfree(pcmds->string_buf);
915 pcmds->string_buf = NULL;
916 pcmds->sblen = 0;
917 }
918
919 if (!pcmds->string_buf) {
920 /*
921 * Buffer size is the sum of cmd length (3 bytes per number)
922 * with NULL terminater
923 */
924 int bsize = ((pcmds->blen)*3 + 1);
925 int blen = 0;
926 char *buffer;
927
928 buffer = kmalloc(bsize, GFP_KERNEL);
929 if (!buffer) {
930 mutex_unlock(&pcmds->dbg_mutex);
931 return -ENOMEM;
932 }
933
934 bp = pcmds->buf;
935 while ((blen < (bsize-1)) &&
936 (bp < ((pcmds->buf) + (pcmds->blen)))) {
937 struct dsi_ctrl_hdr dchdr =
938 *((struct dsi_ctrl_hdr *)bp);
939 int dhrlen = sizeof(dchdr), dlen;
940 char *tmp = (char *)(&dchdr);
941
942 dlen = dchdr.dlen;
943 dchdr.dlen = htons(dchdr.dlen);
944 while (dhrlen--)
945 blen += snprintf(buffer+blen, bsize-blen,
946 "%02x ", (*tmp++));
947
948 bp += sizeof(dchdr);
949 while (dlen--)
950 blen += snprintf(buffer+blen, bsize-blen,
951 "%02x ", (*bp++));
952 buffer[blen-1] = '\n';
953 }
954 buffer[blen] = '\0';
955 pcmds->string_buf = buffer;
956 pcmds->sblen = blen;
957 }
958
959 /*
960 * The max value of count is PAGE_SIZE(4096).
961 * It may need multiple times of reading if string buf is too large
962 */
963 if (*ppos >= (pcmds->sblen)) {
964 kfree(pcmds->string_buf);
965 pcmds->string_buf = NULL;
966 pcmds->sblen = 0;
967 mutex_unlock(&pcmds->dbg_mutex);
968 return 0; /* the end */
969 }
970 ret = simple_read_from_buffer(buf, count, ppos, pcmds->string_buf,
971 pcmds->sblen);
972 mutex_unlock(&pcmds->dbg_mutex);
973 return ret;
974}
975
976static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
977 size_t count, loff_t *ppos)
978{
979 struct buf_data *pcmds = file->private_data;
980 ssize_t ret = 0;
Nirmal Abraham6d32cea2019-08-16 16:39:17 +0530981 unsigned int blen = 0;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530982 char *string_buf;
983
984 mutex_lock(&pcmds->dbg_mutex);
985 if (*ppos == 0) {
986 kfree(pcmds->string_buf);
987 pcmds->string_buf = NULL;
988 pcmds->sblen = 0;
989 }
990
991 /* Allocate memory for the received string */
992 blen = count + (pcmds->sblen);
Nirmal Abraham6d32cea2019-08-16 16:39:17 +0530993 if (blen > U32_MAX - 1) {
994 mutex_unlock(&pcmds->dbg_mutex);
995 return -EINVAL;
996 }
997
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530998 string_buf = krealloc(pcmds->string_buf, blen + 1, GFP_KERNEL);
999 if (!string_buf) {
1000 pr_err("%s: Failed to allocate memory\n", __func__);
1001 mutex_unlock(&pcmds->dbg_mutex);
1002 return -ENOMEM;
1003 }
1004
Nirmal Abraham6d32cea2019-08-16 16:39:17 +05301005 pcmds->string_buf = string_buf;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301006 /* Writing in batches is possible */
1007 ret = simple_write_to_buffer(string_buf, blen, ppos, p, count);
1008 if (ret < 0) {
1009 pr_err("%s: Failed to copy data\n", __func__);
1010 mutex_unlock(&pcmds->dbg_mutex);
1011 return -EINVAL;
1012 }
1013
1014 string_buf[ret] = '\0';
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301015 pcmds->sblen = count;
1016 mutex_unlock(&pcmds->dbg_mutex);
1017 return ret;
1018}
1019
1020static int mdss_dsi_cmd_flush(struct file *file, fl_owner_t id)
1021{
1022 struct buf_data *pcmds = file->private_data;
raghavendra ambadasa46d3882019-05-22 17:14:21 +05301023 unsigned int len;
1024 int blen, i;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301025 char *buf, *bufp, *bp;
1026 struct dsi_ctrl_hdr *dchdr;
1027
1028 mutex_lock(&pcmds->dbg_mutex);
1029
1030 if (!pcmds->string_buf) {
1031 mutex_unlock(&pcmds->dbg_mutex);
1032 return 0;
1033 }
1034
1035 /*
1036 * Allocate memory for command buffer
1037 * 3 bytes per number, and 2 bytes for the last one
1038 */
1039 blen = ((pcmds->sblen) + 2) / 3;
1040 buf = kcalloc(1, blen, GFP_KERNEL);
1041 if (!buf) {
1042 pr_err("%s: Failed to allocate memory\n", __func__);
1043 kfree(pcmds->string_buf);
1044 pcmds->string_buf = NULL;
1045 pcmds->sblen = 0;
1046 mutex_unlock(&pcmds->dbg_mutex);
1047 return -ENOMEM;
1048 }
1049
1050 /* Translate the input string to command array */
1051 bufp = pcmds->string_buf;
1052 for (i = 0; i < blen; i++) {
1053 uint32_t value = 0;
1054 int step = 0;
1055
1056 if (sscanf(bufp, "%02x%n", &value, &step) > 0) {
1057 *(buf+i) = (char)value;
1058 bufp += step;
1059 }
1060 }
1061
1062 /* Scan dcs commands */
1063 bp = buf;
1064 len = blen;
1065 while (len >= sizeof(*dchdr)) {
1066 dchdr = (struct dsi_ctrl_hdr *)bp;
1067 dchdr->dlen = ntohs(dchdr->dlen);
raghavendra ambadasa46d3882019-05-22 17:14:21 +05301068 if (dchdr->dlen > (len - sizeof(*dchdr)) || dchdr->dlen < 0) {
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301069 pr_err("%s: dtsi cmd=%x error, len=%d\n",
1070 __func__, dchdr->dtype, dchdr->dlen);
1071 kfree(buf);
1072 mutex_unlock(&pcmds->dbg_mutex);
1073 return -EINVAL;
1074 }
1075 bp += sizeof(*dchdr);
1076 len -= sizeof(*dchdr);
1077 bp += dchdr->dlen;
1078 len -= dchdr->dlen;
1079 }
1080 if (len != 0) {
1081 pr_err("%s: dcs_cmd=%x len=%d error!\n", __func__,
1082 bp[0], len);
1083 kfree(buf);
1084 mutex_unlock(&pcmds->dbg_mutex);
1085 return -EINVAL;
1086 }
1087
1088 if (pcmds->sync_flag) {
1089 pcmds->buf = buf;
1090 pcmds->blen = blen;
1091 pcmds->sync_flag = 0;
1092 } else {
1093 kfree(pcmds->buf);
1094 pcmds->buf = buf;
1095 pcmds->blen = blen;
1096 }
1097 mutex_unlock(&pcmds->dbg_mutex);
1098 return 0;
1099}
1100
1101static const struct file_operations mdss_dsi_cmd_fop = {
1102 .open = mdss_dsi_cmd_open,
1103 .read = mdss_dsi_cmd_read,
1104 .write = mdss_dsi_cmd_write,
1105 .flush = mdss_dsi_cmd_flush,
1106};
1107
1108struct dentry *dsi_debugfs_create_dcs_cmd(const char *name, umode_t mode,
1109 struct dentry *parent, struct buf_data *cmd,
1110 struct dsi_panel_cmds ctrl_cmds)
1111{
1112 mutex_init(&cmd->dbg_mutex);
1113 cmd->buf = ctrl_cmds.buf;
1114 cmd->blen = ctrl_cmds.blen;
1115 cmd->string_buf = NULL;
1116 cmd->sblen = 0;
1117 cmd->sync_flag = 1;
1118
1119 return debugfs_create_file(name, mode, parent,
1120 cmd, &mdss_dsi_cmd_fop);
1121}
1122
1123#define DEBUGFS_CREATE_DCS_CMD(name, node, cmd, ctrl_cmd) \
1124 dsi_debugfs_create_dcs_cmd(name, 0644, node, cmd, ctrl_cmd)
1125
1126static int mdss_dsi_debugfs_setup(struct mdss_panel_data *pdata,
1127 struct dentry *parent)
1128{
1129 struct mdss_dsi_ctrl_pdata *ctrl_pdata, *dfs_ctrl;
1130 struct mdss_dsi_debugfs_info *dfs;
1131
1132 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1133 panel_data);
1134
1135 dfs = kcalloc(1, sizeof(*dfs), GFP_KERNEL);
1136 if (!dfs)
1137 return -ENOMEM;
1138
1139 dfs->root = debugfs_create_dir("dsi_ctrl_pdata", parent);
1140 if (IS_ERR_OR_NULL(dfs->root)) {
1141 pr_err("%s: debugfs_create_dir dsi fail, error %ld\n",
1142 __func__, PTR_ERR(dfs->root));
1143 kfree(dfs);
1144 return -ENODEV;
1145 }
1146
1147 dfs_ctrl = &dfs->ctrl_pdata;
1148 debugfs_create_u32("override_flag", 0644, dfs->root,
1149 &dfs->override_flag);
1150
1151 debugfs_create_bool("cmd_sync_wait_broadcast", 0644, dfs->root,
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05301152 &dfs_ctrl->cmd_sync_wait_broadcast);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301153 debugfs_create_bool("cmd_sync_wait_trigger", 0644, dfs->root,
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05301154 &dfs_ctrl->cmd_sync_wait_trigger);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301155
1156 debugfs_create_file("dsi_on_cmd_state", 0644, dfs->root,
1157 &dfs_ctrl->on_cmds.link_state, &mdss_dsi_cmd_state_fop);
1158 debugfs_create_file("dsi_off_cmd_state", 0644, dfs->root,
1159 &dfs_ctrl->off_cmds.link_state, &mdss_dsi_cmd_state_fop);
1160
1161 DEBUGFS_CREATE_DCS_CMD("dsi_on_cmd", dfs->root, &dfs->on_cmd,
1162 ctrl_pdata->on_cmds);
1163 DEBUGFS_CREATE_DCS_CMD("dsi_off_cmd", dfs->root, &dfs->off_cmd,
1164 ctrl_pdata->off_cmds);
1165
1166 debugfs_create_u32("dsi_err_counter", 0644, dfs->root,
1167 &dfs_ctrl->err_cont.max_err_index);
1168 debugfs_create_u32("dsi_err_time_delta", 0644, dfs->root,
1169 &dfs_ctrl->err_cont.err_time_delta);
1170
1171 dfs->override_flag = 0;
1172 dfs->ctrl_pdata = *ctrl_pdata;
1173 ctrl_pdata->debugfs_info = dfs;
1174 return 0;
1175}
1176
1177static int mdss_dsi_debugfs_init(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
1178{
1179 int rc;
1180 struct mdss_panel_data *pdata;
1181 struct mdss_panel_info panel_info;
1182
1183 if (!ctrl_pdata) {
1184 pr_warn_once("%s: Invalid pdata!\n", __func__);
1185 return -EINVAL;
1186 }
1187
1188 pdata = &ctrl_pdata->panel_data;
1189 if (!pdata)
1190 return -EINVAL;
1191
1192 panel_info = pdata->panel_info;
1193 rc = mdss_dsi_debugfs_setup(pdata, panel_info.debugfs_info->root);
1194 if (rc) {
1195 pr_err("%s: Error in initilizing dsi ctrl debugfs\n",
1196 __func__);
1197 return rc;
1198 }
1199
1200 pr_debug("%s: Initialized mdss_dsi_debugfs_init\n", __func__);
1201 return 0;
1202}
1203
1204static void mdss_dsi_debugfs_cleanup(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
1205{
1206 struct mdss_panel_data *pdata = &ctrl_pdata->panel_data;
1207
1208 do {
1209 struct mdss_dsi_ctrl_pdata *ctrl = container_of(pdata,
1210 struct mdss_dsi_ctrl_pdata, panel_data);
1211 struct mdss_dsi_debugfs_info *dfs = ctrl->debugfs_info;
1212
1213 if (dfs && dfs->root)
1214 debugfs_remove_recursive(dfs->root);
1215 kfree(dfs);
1216 pdata = pdata->next;
1217 } while (pdata);
1218 pr_debug("%s: Cleaned up mdss_dsi_debugfs_info\n", __func__);
1219}
1220
1221static int _mdss_dsi_refresh_cmd(struct buf_data *new_cmds,
1222 struct dsi_panel_cmds *original_pcmds)
1223{
1224 char *bp;
1225 int len, cnt, i;
1226 struct dsi_ctrl_hdr *dchdr;
1227 struct dsi_cmd_desc *cmds;
1228
1229 if (new_cmds->sync_flag)
1230 return 0;
1231
1232 bp = new_cmds->buf;
1233 len = new_cmds->blen;
1234 cnt = 0;
1235 /* Scan dcs commands and get dcs command count */
1236 while (len >= sizeof(*dchdr)) {
1237 dchdr = (struct dsi_ctrl_hdr *)bp;
1238 if (dchdr->dlen > len) {
1239 pr_err("%s: dtsi cmd=%x error, len=%d\n",
1240 __func__, dchdr->dtype, dchdr->dlen);
1241 return -EINVAL;
1242 }
1243 bp += sizeof(*dchdr) + dchdr->dlen;
1244 len -= sizeof(*dchdr) + dchdr->dlen;
1245 cnt++;
1246 }
1247
1248 if (len != 0) {
1249 pr_err("%s: dcs_cmd=%x len=%d error!\n", __func__,
1250 bp[0], len);
1251 return -EINVAL;
1252 }
1253
1254 /* Reallocate space for dcs commands */
1255 cmds = kcalloc(cnt, sizeof(struct dsi_cmd_desc), GFP_KERNEL);
1256 if (!cmds)
1257 return -ENOMEM;
1258
1259 kfree(original_pcmds->buf);
1260 kfree(original_pcmds->cmds);
1261 original_pcmds->cmd_cnt = cnt;
1262 original_pcmds->cmds = cmds;
1263 original_pcmds->buf = new_cmds->buf;
1264 original_pcmds->blen = new_cmds->blen;
1265
1266 bp = original_pcmds->buf;
1267 len = original_pcmds->blen;
1268 for (i = 0; i < cnt; i++) {
1269 dchdr = (struct dsi_ctrl_hdr *)bp;
1270 len -= sizeof(*dchdr);
1271 bp += sizeof(*dchdr);
1272 original_pcmds->cmds[i].dchdr = *dchdr;
1273 original_pcmds->cmds[i].payload = bp;
1274 bp += dchdr->dlen;
1275 len -= dchdr->dlen;
1276 }
1277
1278 new_cmds->sync_flag = 1;
1279 return 0;
1280}
1281
1282static void mdss_dsi_debugfsinfo_to_dsictrl_info(
1283 struct mdss_dsi_ctrl_pdata *ctrl_pdata)
1284{
1285 struct mdss_dsi_debugfs_info *dfs = ctrl_pdata->debugfs_info;
1286 struct dsi_err_container *dfs_err_cont = &dfs->ctrl_pdata.err_cont;
1287 struct dsi_err_container *err_cont = &ctrl_pdata->err_cont;
1288
1289 ctrl_pdata->cmd_sync_wait_broadcast =
1290 dfs->ctrl_pdata.cmd_sync_wait_broadcast;
1291 ctrl_pdata->cmd_sync_wait_trigger =
1292 dfs->ctrl_pdata.cmd_sync_wait_trigger;
1293
1294 _mdss_dsi_refresh_cmd(&dfs->on_cmd, &ctrl_pdata->on_cmds);
1295 _mdss_dsi_refresh_cmd(&dfs->off_cmd, &ctrl_pdata->off_cmds);
1296
1297 ctrl_pdata->on_cmds.link_state =
1298 dfs->ctrl_pdata.on_cmds.link_state;
1299 ctrl_pdata->off_cmds.link_state =
1300 dfs->ctrl_pdata.off_cmds.link_state;
1301
1302 /* keep error counter between 2 to 10 */
1303 if (dfs_err_cont->max_err_index >= 2 &&
1304 dfs_err_cont->max_err_index <= MAX_ERR_INDEX) {
1305 err_cont->max_err_index = dfs_err_cont->max_err_index;
1306 } else {
1307 dfs_err_cont->max_err_index = err_cont->max_err_index;
1308 pr_warn("resetting the dsi error counter to %d\n",
1309 err_cont->max_err_index);
1310 }
1311
1312 /* keep error duration between 16 ms to 100 seconds */
1313 if (dfs_err_cont->err_time_delta >= 16 &&
1314 dfs_err_cont->err_time_delta <= 100000) {
1315 err_cont->err_time_delta = dfs_err_cont->err_time_delta;
1316 } else {
1317 dfs_err_cont->err_time_delta = err_cont->err_time_delta;
1318 pr_warn("resetting the dsi error time delta to %d ms\n",
1319 err_cont->err_time_delta);
1320 }
1321}
1322
1323static void mdss_dsi_validate_debugfs_info(
1324 struct mdss_dsi_ctrl_pdata *ctrl_pdata)
1325{
1326 struct mdss_dsi_debugfs_info *dfs = ctrl_pdata->debugfs_info;
1327
1328 if (dfs->override_flag) {
1329 pr_debug("%s: Overriding dsi ctrl_pdata with debugfs data\n",
1330 __func__);
1331 dfs->override_flag = 0;
1332 mdss_dsi_debugfsinfo_to_dsictrl_info(ctrl_pdata);
1333 }
1334}
1335
1336static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state)
1337{
1338 int ret = 0;
1339 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1340 struct mdss_panel_info *panel_info = NULL;
1341
1342 if (pdata == NULL) {
1343 pr_err("%s: Invalid input data\n", __func__);
1344 return -EINVAL;
1345 }
1346
1347 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1348 panel_data);
1349
1350 panel_info = &ctrl_pdata->panel_data.panel_info;
1351
1352 pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n",
1353 __func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
1354
1355 if (power_state == panel_info->panel_power_state) {
1356 pr_debug("%s: No change in power state %d -> %d\n", __func__,
1357 panel_info->panel_power_state, power_state);
1358 goto end;
1359 }
1360
1361 if (mdss_panel_is_power_on(power_state)) {
1362 pr_debug("%s: dsi_off with panel always on\n", __func__);
1363 goto panel_power_ctrl;
1364 }
1365
1366 /*
1367 * Link clocks should be turned off before PHY can be disabled.
1368 * For command mode panels, all clocks are turned off prior to reaching
1369 * here, so core clocks should be turned on before accessing hardware
1370 * registers. For video mode panel, turn off link clocks and then
1371 * disable PHY
1372 */
1373 if (pdata->panel_info.type == MIPI_CMD_PANEL)
1374 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1375 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_ON);
1376 else
1377 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1378 MDSS_DSI_LINK_CLK, MDSS_DSI_CLK_OFF);
1379
1380 if (!pdata->panel_info.ulps_suspend_enabled) {
1381 /* disable DSI controller */
1382 mdss_dsi_controller_cfg(0, pdata);
1383
1384 /* disable DSI phy */
1385 mdss_dsi_phy_disable(ctrl_pdata);
1386 }
1387 ctrl_pdata->ctrl_state &= ~CTRL_STATE_DSI_ACTIVE;
1388
1389 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1390 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_OFF);
1391
1392panel_power_ctrl:
1393 ret = mdss_dsi_panel_power_ctrl(pdata, power_state);
1394 if (ret) {
1395 pr_err("%s: Panel power off failed\n", __func__);
1396 goto end;
1397 }
1398
1399 if (panel_info->dynamic_fps
1400 && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE)
1401 && (panel_info->new_fps != panel_info->mipi.frame_rate))
1402 panel_info->mipi.frame_rate = panel_info->new_fps;
1403
1404 /* Initialize Max Packet size for DCS reads */
1405 ctrl_pdata->cur_max_pkt_size = 0;
1406end:
1407 pr_debug("%s-:\n", __func__);
1408
1409 return ret;
1410}
1411
1412int mdss_dsi_switch_mode(struct mdss_panel_data *pdata, int mode)
1413{
1414 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1415 struct mipi_panel_info *pinfo;
1416 bool dsi_ctrl_setup_needed = false;
1417
1418 if (!pdata) {
1419 pr_err("%s: Invalid input data\n", __func__);
1420 return -EINVAL;
1421 }
1422 pr_debug("%s, start\n", __func__);
1423
1424 pinfo = &pdata->panel_info.mipi;
1425 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1426 panel_data);
1427
1428 if ((pinfo->dms_mode != DYNAMIC_MODE_RESOLUTION_SWITCH_IMMEDIATE) &&
1429 (pinfo->dms_mode != DYNAMIC_MODE_SWITCH_IMMEDIATE)) {
1430 pr_debug("%s: Dynamic mode switch not enabled.\n", __func__);
1431 return -EPERM;
1432 }
1433
1434 if (mode == MIPI_VIDEO_PANEL) {
1435 mode = SWITCH_TO_VIDEO_MODE;
1436 } else if (mode == MIPI_CMD_PANEL) {
1437 mode = SWITCH_TO_CMD_MODE;
1438 } else if (mode == SWITCH_RESOLUTION) {
1439 dsi_ctrl_setup_needed = true;
1440 pr_debug("Resolution switch mode selected\n");
1441 } else {
1442 pr_err("Invalid mode selected, mode=%d\n", mode);
1443 return -EINVAL;
1444 }
1445
1446 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1447 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
1448 if (dsi_ctrl_setup_needed)
1449 mdss_dsi_ctrl_setup(ctrl_pdata);
1450 ctrl_pdata->switch_mode(pdata, mode);
1451 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1452 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1453
1454 pr_debug("%s, end\n", __func__);
1455 return 0;
1456}
1457
1458static int mdss_dsi_reconfig(struct mdss_panel_data *pdata, int mode)
1459{
1460 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1461 struct mipi_panel_info *pinfo;
1462
1463 if (!pdata) {
1464 pr_err("%s: Invalid input data\n", __func__);
1465 return -EINVAL;
1466 }
1467 pr_debug("%s, start\n", __func__);
1468
1469 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1470 panel_data);
1471 pinfo = &pdata->panel_info.mipi;
1472
1473 if (pinfo->dms_mode == DYNAMIC_MODE_SWITCH_IMMEDIATE) {
1474 /* reset DSI */
1475 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1476 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
1477 mdss_dsi_sw_reset(ctrl_pdata, true);
1478 mdss_dsi_ctrl_setup(ctrl_pdata);
1479 mdss_dsi_controller_cfg(true, pdata);
1480 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1481 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1482 }
1483
1484 pr_debug("%s, end\n", __func__);
1485 return 0;
1486}
1487static int mdss_dsi_update_panel_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
1488 int mode)
1489{
1490 int ret = 0;
1491 struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
1492
1493 if (mode == DSI_CMD_MODE) {
1494 pinfo->mipi.mode = DSI_CMD_MODE;
1495 pinfo->type = MIPI_CMD_PANEL;
1496 pinfo->mipi.vsync_enable = 1;
1497 pinfo->mipi.hw_vsync_mode = 1;
1498 pinfo->partial_update_enabled = pinfo->partial_update_supported;
1499 } else { /*video mode*/
1500 pinfo->mipi.mode = DSI_VIDEO_MODE;
1501 pinfo->type = MIPI_VIDEO_PANEL;
1502 pinfo->mipi.vsync_enable = 0;
1503 pinfo->mipi.hw_vsync_mode = 0;
1504 pinfo->partial_update_enabled = 0;
1505 }
1506
1507 ctrl_pdata->panel_mode = pinfo->mipi.mode;
1508 mdss_panel_get_dst_fmt(pinfo->bpp, pinfo->mipi.mode,
1509 pinfo->mipi.pixel_packing, &(pinfo->mipi.dst_format));
1510 return ret;
1511}
1512
1513int mdss_dsi_on(struct mdss_panel_data *pdata)
1514{
1515 int ret = 0;
1516 struct mdss_panel_info *pinfo;
1517 struct mipi_panel_info *mipi;
1518 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1519 int cur_power_state;
1520
1521 if (pdata == NULL) {
1522 pr_err("%s: Invalid input data\n", __func__);
1523 return -EINVAL;
1524 }
1525
1526 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1527 panel_data);
1528
1529 if (ctrl_pdata->debugfs_info)
1530 mdss_dsi_validate_debugfs_info(ctrl_pdata);
1531
1532 cur_power_state = pdata->panel_info.panel_power_state;
1533 pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d\n", __func__,
1534 ctrl_pdata, ctrl_pdata->ndx, cur_power_state);
1535
1536 pinfo = &pdata->panel_info;
1537 mipi = &pdata->panel_info.mipi;
1538
1539 if (mdss_dsi_is_panel_on_interactive(pdata)) {
1540 /*
1541 * all interrupts are disabled at LK
1542 * for cont_splash case, intr mask bits need
1543 * to be restored to allow dcs command be
1544 * sent to panel
1545 */
1546 mdss_dsi_restore_intr_mask(ctrl_pdata);
1547 pr_debug("%s: panel already on\n", __func__);
1548 goto end;
1549 }
1550
1551 ret = mdss_dsi_panel_power_ctrl(pdata, MDSS_PANEL_POWER_ON);
1552 if (ret) {
1553 pr_err("%s:Panel power on failed. rc=%d\n", __func__, ret);
1554 goto end;
1555 }
1556
1557 if (mdss_panel_is_power_on(cur_power_state)) {
1558 pr_debug("%s: dsi_on from panel low power state\n", __func__);
1559 goto end;
1560 }
1561
1562 ret = mdss_dsi_set_clk_src(ctrl_pdata);
1563 if (ret) {
1564 pr_err("%s: failed to set clk src. rc=%d\n", __func__, ret);
1565 goto end;
1566 }
1567
1568 /*
1569 * Enable DSI core clocks prior to resetting and initializing DSI
1570 * Phy. Phy and ctrl setup need to be done before enabling the link
1571 * clocks.
1572 */
1573 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1574 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_ON);
1575
1576 /*
1577 * If ULPS during suspend feature is enabled, then DSI PHY was
1578 * left on during suspend. In this case, we do not need to reset/init
1579 * PHY. This would have already been done when the CORE clocks are
1580 * turned on. However, if cont splash is disabled, the first time DSI
1581 * is powered on, phy init needs to be done unconditionally.
1582 */
1583 if (!pdata->panel_info.ulps_suspend_enabled || !ctrl_pdata->ulps) {
1584 mdss_dsi_phy_sw_reset(ctrl_pdata);
1585 mdss_dsi_phy_init(ctrl_pdata);
1586 mdss_dsi_ctrl_setup(ctrl_pdata);
1587 }
1588 ctrl_pdata->ctrl_state |= CTRL_STATE_DSI_ACTIVE;
1589
1590 /* DSI link clocks need to be on prior to ctrl sw reset */
1591 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1592 MDSS_DSI_LINK_CLK, MDSS_DSI_CLK_ON);
1593 mdss_dsi_sw_reset(ctrl_pdata, true);
1594
1595 /*
1596 * Issue hardware reset line after enabling the DSI clocks and data
1597 * data lanes for LP11 init
1598 */
1599 if (mipi->lp11_init) {
1600 if (mdss_dsi_pinctrl_set_state(ctrl_pdata, true))
1601 pr_debug("reset enable: pinctrl not enabled\n");
1602 mdss_dsi_panel_reset(pdata, 1);
1603 }
1604
1605 if (mipi->init_delay)
1606 usleep_range(mipi->init_delay, mipi->init_delay + 10);
1607
1608 if (mipi->force_clk_lane_hs) {
1609 u32 tmp;
1610
1611 tmp = MIPI_INP((ctrl_pdata->ctrl_base) + 0xac);
1612 tmp |= (1<<28);
1613 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0xac, tmp);
1614 wmb(); /* ensure write is finished before progressing */
1615 }
1616
1617 if (pdata->panel_info.type == MIPI_CMD_PANEL)
1618 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1619 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1620
1621end:
1622 pr_debug("%s-:\n", __func__);
1623 return ret;
1624}
1625
1626static int mdss_dsi_pinctrl_set_state(
1627 struct mdss_dsi_ctrl_pdata *ctrl_pdata,
1628 bool active)
1629{
1630 struct pinctrl_state *pin_state;
1631 struct mdss_panel_info *pinfo = NULL;
1632 int rc = -EFAULT;
1633
1634 if (IS_ERR_OR_NULL(ctrl_pdata->pin_res.pinctrl))
1635 return PTR_ERR(ctrl_pdata->pin_res.pinctrl);
1636
1637 pinfo = &ctrl_pdata->panel_data.panel_info;
1638 if ((mdss_dsi_is_right_ctrl(ctrl_pdata) &&
1639 mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) ||
1640 pinfo->is_dba_panel) {
1641 pr_debug("%s:%d, right ctrl pinctrl config not needed\n",
1642 __func__, __LINE__);
1643 return 0;
1644 }
1645
1646 pin_state = active ? ctrl_pdata->pin_res.gpio_state_active
1647 : ctrl_pdata->pin_res.gpio_state_suspend;
1648 if (!IS_ERR_OR_NULL(pin_state)) {
1649 rc = pinctrl_select_state(ctrl_pdata->pin_res.pinctrl,
1650 pin_state);
1651 if (rc)
1652 pr_err("%s: can not set %s pins\n", __func__,
1653 active ? MDSS_PINCTRL_STATE_DEFAULT
1654 : MDSS_PINCTRL_STATE_SLEEP);
1655 } else {
1656 pr_err("%s: invalid '%s' pinstate\n", __func__,
1657 active ? MDSS_PINCTRL_STATE_DEFAULT
1658 : MDSS_PINCTRL_STATE_SLEEP);
1659 }
1660 return rc;
1661}
1662
1663static int mdss_dsi_pinctrl_init(struct platform_device *pdev)
1664{
1665 struct mdss_dsi_ctrl_pdata *ctrl_pdata;
1666
1667 ctrl_pdata = platform_get_drvdata(pdev);
1668 ctrl_pdata->pin_res.pinctrl = devm_pinctrl_get(&pdev->dev);
1669 if (IS_ERR_OR_NULL(ctrl_pdata->pin_res.pinctrl)) {
1670 pr_err("%s: failed to get pinctrl\n", __func__);
1671 return PTR_ERR(ctrl_pdata->pin_res.pinctrl);
1672 }
1673
1674 ctrl_pdata->pin_res.gpio_state_active
1675 = pinctrl_lookup_state(ctrl_pdata->pin_res.pinctrl,
1676 MDSS_PINCTRL_STATE_DEFAULT);
1677 if (IS_ERR_OR_NULL(ctrl_pdata->pin_res.gpio_state_active))
1678 pr_warn("%s: can not get default pinstate\n", __func__);
1679
1680 ctrl_pdata->pin_res.gpio_state_suspend
1681 = pinctrl_lookup_state(ctrl_pdata->pin_res.pinctrl,
1682 MDSS_PINCTRL_STATE_SLEEP);
1683 if (IS_ERR_OR_NULL(ctrl_pdata->pin_res.gpio_state_suspend))
1684 pr_warn("%s: can not get sleep pinstate\n", __func__);
1685
1686 return 0;
1687}
1688
1689static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
1690{
1691 int ret = 0;
1692 struct mipi_panel_info *mipi;
1693 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1694 struct mdss_dsi_ctrl_pdata *sctrl = NULL;
1695
1696 if (pdata == NULL) {
1697 pr_err("%s: Invalid input data\n", __func__);
1698 return -EINVAL;
1699 }
1700
1701 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1702 panel_data);
1703 mipi = &pdata->panel_info.mipi;
1704
1705 pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d ctrl_state=%x\n",
1706 __func__, ctrl_pdata, ctrl_pdata->ndx,
1707 pdata->panel_info.panel_power_state, ctrl_pdata->ctrl_state);
1708
1709 mdss_dsi_pm_qos_update_request(DSI_DISABLE_PC_LATENCY);
1710
1711 if (mdss_dsi_is_ctrl_clk_master(ctrl_pdata))
1712 sctrl = mdss_dsi_get_ctrl_clk_slave();
1713
1714 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1715 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
1716 if (sctrl)
1717 mdss_dsi_clk_ctrl(sctrl, sctrl->dsi_clk_handle,
1718 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
1719
1720 if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_LP) {
1721 pr_debug("%s: dsi_unblank with panel always on\n", __func__);
1722 if (ctrl_pdata->low_power_config)
1723 ret = ctrl_pdata->low_power_config(pdata, false);
1724 if (!ret)
1725 ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_LP;
1726 goto error;
1727 }
1728
1729 if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {
1730 if (!pdata->panel_info.dynamic_switch_pending) {
1731 ATRACE_BEGIN("dsi_panel_on");
1732 ret = ctrl_pdata->on(pdata);
1733 if (ret) {
1734 pr_err("%s: unable to initialize the panel\n",
1735 __func__);
1736 goto error;
1737 }
1738 ATRACE_END("dsi_panel_on");
1739 }
1740 }
1741
1742 if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
1743 mipi->vsync_enable && mipi->hw_vsync_mode) {
1744 mdss_dsi_set_tear_on(ctrl_pdata);
1745 }
1746
1747 ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
1748
1749error:
1750 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1751 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1752 if (sctrl)
1753 mdss_dsi_clk_ctrl(sctrl, sctrl->dsi_clk_handle,
1754 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1755
1756 mdss_dsi_pm_qos_update_request(DSI_ENABLE_PC_LATENCY);
1757
1758 pr_debug("%s-:\n", __func__);
1759
1760 return ret;
1761}
1762
1763static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state)
1764{
1765 int ret = 0;
1766 struct mipi_panel_info *mipi;
1767 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1768
1769 if (pdata == NULL) {
1770 pr_err("%s: Invalid input data\n", __func__);
1771 return -EINVAL;
1772 }
1773
1774 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1775 panel_data);
1776 mipi = &pdata->panel_info.mipi;
1777
1778 pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n",
1779 __func__, ctrl_pdata, ctrl_pdata->ndx, power_state);
1780
1781 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1782 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
1783
1784 if (mdss_panel_is_power_on_lp(power_state)) {
1785 pr_debug("%s: low power state requested\n", __func__);
1786 if (ctrl_pdata->low_power_config)
1787 ret = ctrl_pdata->low_power_config(pdata, true);
1788 if (!ret)
1789 ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_LP;
1790 goto error;
1791 }
1792
1793 if (pdata->panel_info.type == MIPI_VIDEO_PANEL &&
1794 ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) {
1795 mdss_dsi_sw_reset(ctrl_pdata, false);
1796 mdss_dsi_host_init(pdata);
1797 }
1798
1799 mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);
1800
1801 if (pdata->panel_info.dynamic_switch_pending) {
1802 pr_info("%s: switching to %s mode\n", __func__,
1803 (pdata->panel_info.mipi.mode ? "video" : "command"));
1804 if (pdata->panel_info.type == MIPI_CMD_PANEL) {
1805 ctrl_pdata->switch_mode(pdata, SWITCH_TO_VIDEO_MODE);
1806 } else if (pdata->panel_info.type == MIPI_VIDEO_PANEL) {
1807 ctrl_pdata->switch_mode(pdata, SWITCH_TO_CMD_MODE);
1808 mdss_dsi_set_tear_off(ctrl_pdata);
1809 }
1810 }
1811
1812 if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
1813 mipi->vsync_enable && mipi->hw_vsync_mode) {
1814 mdss_dsi_set_tear_off(ctrl_pdata);
1815 }
1816
1817 if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT) {
1818 if (!pdata->panel_info.dynamic_switch_pending) {
1819 ATRACE_BEGIN("dsi_panel_off");
1820 ret = ctrl_pdata->off(pdata);
1821 if (ret) {
Arun kumar162db222018-05-09 17:28:40 +05301822 pr_err("%s: Panel OFF failed\n",
1823 __func__);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301824 goto error;
1825 }
1826 ATRACE_END("dsi_panel_off");
1827 }
1828 ctrl_pdata->ctrl_state &= ~(CTRL_STATE_PANEL_INIT |
1829 CTRL_STATE_PANEL_LP);
1830 }
1831
1832error:
1833 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1834 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1835 pr_debug("%s-:End\n", __func__);
1836 return ret;
1837}
1838
1839static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata)
1840{
1841 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1842
1843 if (pdata == NULL) {
1844 pr_err("%s: Invalid input data\n", __func__);
1845 return -EINVAL;
1846 }
1847
1848 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1849 panel_data);
1850
1851 pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__,
1852 ctrl_pdata, ctrl_pdata->ndx);
1853
1854 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1855 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
1856
1857 if (ctrl_pdata->post_panel_on)
1858 ctrl_pdata->post_panel_on(pdata);
1859
1860 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
1861 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
1862 pr_debug("%s-:\n", __func__);
1863
1864 return 0;
1865}
1866
1867static irqreturn_t test_hw_vsync_handler(int irq, void *data)
1868{
1869 struct mdss_panel_data *pdata = (struct mdss_panel_data *)data;
1870
1871 pr_debug("HW VSYNC\n");
1872 MDSS_XLOG(0xaaa, irq);
1873 complete_all(&pdata->te_done);
1874 if (pdata->next)
1875 complete_all(&pdata->next->te_done);
1876 return IRQ_HANDLED;
1877}
1878
1879int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata)
1880{
1881 int ret = 0;
1882 struct mipi_panel_info *mipi;
1883 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1884
1885 pr_info("%s:%d DSI on for continuous splash.\n", __func__, __LINE__);
1886
1887 if (pdata == NULL) {
1888 pr_err("%s: Invalid input data\n", __func__);
1889 return -EINVAL;
1890 }
1891
1892 mipi = &pdata->panel_info.mipi;
1893
1894 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1895 panel_data);
1896
1897 pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__,
1898 ctrl_pdata, ctrl_pdata->ndx);
1899
1900 WARN((ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT),
1901 "Incorrect Ctrl state=0x%x\n", ctrl_pdata->ctrl_state);
1902
1903 mdss_dsi_ctrl_setup(ctrl_pdata);
1904 mdss_dsi_sw_reset(ctrl_pdata, true);
1905 pr_debug("%s-:End\n", __func__);
1906 return ret;
1907}
1908
1909static void __mdss_dsi_mask_dfps_errors(struct mdss_dsi_ctrl_pdata *ctrl,
1910 bool mask)
1911{
1912 u32 data = 0;
1913
1914 /*
1915 * Assumption is that the DSI clocks will be enabled
1916 * when this API is called from dfps thread
1917 */
1918 if (mask) {
1919 /* mask FIFO underflow and PLL unlock bits */
1920 mdss_dsi_set_reg(ctrl, 0x10c, 0x7c000000, 0x7c000000);
1921 } else {
1922 data = MIPI_INP((ctrl->ctrl_base) + 0x0120);
1923 if (data & BIT(16)) {
1924 pr_debug("pll unlocked: 0x%x\n", data);
1925 /* clear PLL unlock bit */
1926 MIPI_OUTP((ctrl->ctrl_base) + 0x120, BIT(16));
1927 }
1928
1929 data = MIPI_INP((ctrl->ctrl_base) + 0x00c);
1930 if (data & 0x88880000) {
1931 pr_debug("dsi fifo underflow: 0x%x\n", data);
1932 /* clear DSI FIFO underflow and empty */
1933 MIPI_OUTP((ctrl->ctrl_base) + 0x00c, 0x99990000);
1934 }
1935
1936 /* restore FIFO underflow and PLL unlock bits */
1937 mdss_dsi_set_reg(ctrl, 0x10c, 0x7c000000, 0x0);
1938 }
1939}
1940
1941static void __mdss_dsi_update_video_mode_total(struct mdss_panel_data *pdata,
1942 int new_fps)
1943{
1944 u32 hsync_period, vsync_period;
1945 u32 new_dsi_v_total, current_dsi_v_total;
1946 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
1947
1948 if (pdata == NULL) {
1949 pr_err("%s Invalid pdata\n", __func__);
1950 return;
1951 }
1952
1953 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
1954 panel_data);
1955 if (ctrl_pdata == NULL) {
1956 pr_err("%s Invalid ctrl_pdata\n", __func__);
1957 return;
1958 }
1959
Benjamin Chanabc9f3c2016-06-06 16:50:55 -04001960 if (ctrl_pdata->timing_db_mode)
1961 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e8, 0x1);
1962
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301963 vsync_period =
1964 mdss_panel_get_vtotal(&pdata->panel_info);
1965 hsync_period =
1966 mdss_panel_get_htotal(&pdata->panel_info, true);
1967 current_dsi_v_total =
1968 MIPI_INP((ctrl_pdata->ctrl_base) + 0x2C);
1969 new_dsi_v_total =
1970 ((vsync_period - 1) << 16) | (hsync_period - 1);
1971
Benjamin Chanabc9f3c2016-06-06 16:50:55 -04001972 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, new_dsi_v_total);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301973
1974 if (ctrl_pdata->timing_db_mode)
1975 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x1e4, 0x1);
1976
Benjamin Chanabc9f3c2016-06-06 16:50:55 -04001977 pr_debug("%s new_fps:%d new_vtotal:0x%X cur_vtotal:0x%X frame_rate:%d\n",
1978 __func__, new_fps, new_dsi_v_total, current_dsi_v_total,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301979 ctrl_pdata->panel_data.panel_info.mipi.frame_rate);
1980
1981 ctrl_pdata->panel_data.panel_info.current_fps = new_fps;
1982 MDSS_XLOG(current_dsi_v_total, new_dsi_v_total, new_fps,
1983 ctrl_pdata->timing_db_mode);
1984
1985}
1986
1987static void __mdss_dsi_dyn_refresh_config(
1988 struct mdss_dsi_ctrl_pdata *ctrl_pdata)
1989{
1990 int reg_data = 0;
1991 u32 phy_rev = ctrl_pdata->shared_data->phy_rev;
1992
1993 /* configure only for master control in split display */
1994 if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
1995 mdss_dsi_is_ctrl_clk_slave(ctrl_pdata))
1996 return;
1997
1998 switch (phy_rev) {
1999 case DSI_PHY_REV_10:
2000 reg_data = MIPI_INP((ctrl_pdata->ctrl_base) +
2001 DSI_DYNAMIC_REFRESH_CTRL);
2002 reg_data &= ~BIT(12);
2003 MIPI_OUTP((ctrl_pdata->ctrl_base)
2004 + DSI_DYNAMIC_REFRESH_CTRL, reg_data);
2005 break;
2006 case DSI_PHY_REV_20:
2007 reg_data = BIT(13);
2008 MIPI_OUTP((ctrl_pdata->ctrl_base)
2009 + DSI_DYNAMIC_REFRESH_CTRL, reg_data);
2010 break;
2011 default:
2012 pr_err("Phy rev %d unsupported\n", phy_rev);
2013 break;
2014 }
2015
2016 pr_debug("Dynamic fps ctrl = 0x%x\n", reg_data);
2017}
2018
2019static void __mdss_dsi_calc_dfps_delay(struct mdss_panel_data *pdata)
2020{
2021 u32 esc_clk_rate = XO_CLK_RATE;
2022 u32 pipe_delay, pipe_delay2 = 0, pll_delay;
2023 u32 hsync_period = 0;
2024 u32 pclk_to_esc_ratio, byte_to_esc_ratio, hr_bit_to_esc_ratio;
2025 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2026 struct mdss_panel_info *pinfo = NULL;
2027 struct mdss_dsi_phy_ctrl *pd = NULL;
2028
2029 if (pdata == NULL) {
2030 pr_err("%s Invalid pdata\n", __func__);
2031 return;
2032 }
2033
2034 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2035 panel_data);
2036 if (ctrl_pdata == NULL) {
2037 pr_err("%s Invalid ctrl_pdata\n", __func__);
2038 return;
2039 }
2040
2041 if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
2042 mdss_dsi_is_ctrl_clk_slave(ctrl_pdata))
2043 return;
2044
2045 pinfo = &pdata->panel_info;
2046 pd = &(pinfo->mipi.dsi_phy_db);
2047
2048 pclk_to_esc_ratio = (ctrl_pdata->pclk_rate / esc_clk_rate);
2049 byte_to_esc_ratio = (ctrl_pdata->byte_clk_rate / esc_clk_rate);
2050 hr_bit_to_esc_ratio = ((ctrl_pdata->byte_clk_rate * 4) / esc_clk_rate);
2051
2052 hsync_period = mdss_panel_get_htotal(pinfo, true);
2053 pipe_delay = (hsync_period + 1) / pclk_to_esc_ratio;
2054 if (pinfo->mipi.eof_bllp_power_stop == 0)
2055 pipe_delay += (17 / pclk_to_esc_ratio) +
2056 ((21 + (pinfo->mipi.t_clk_pre + 1) +
2057 (pinfo->mipi.t_clk_post + 1)) /
2058 byte_to_esc_ratio) +
2059 ((((pd->timing[8] >> 1) + 1) +
2060 ((pd->timing[6] >> 1) + 1) +
2061 ((pd->timing[3] * 4) + (pd->timing[5] >> 1) + 1) +
2062 ((pd->timing[7] >> 1) + 1) +
2063 ((pd->timing[1] >> 1) + 1) +
2064 ((pd->timing[4] >> 1) + 1)) / hr_bit_to_esc_ratio);
2065
2066 if (pinfo->mipi.force_clk_lane_hs)
2067 pipe_delay2 = (6 / byte_to_esc_ratio) +
2068 ((((pd->timing[1] >> 1) + 1) +
2069 ((pd->timing[4] >> 1) + 1)) / hr_bit_to_esc_ratio);
2070
2071 /* 130 us pll delay recommended by h/w doc */
2072 pll_delay = ((130 * esc_clk_rate) / 1000000) * 2;
2073
2074 MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_PIPE_DELAY,
2075 pipe_delay);
2076 MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_PIPE_DELAY2,
2077 pipe_delay2);
2078 MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_PLL_DELAY,
2079 pll_delay);
2080}
2081
2082static int __mdss_dsi_dfps_calc_clks(struct mdss_panel_data *pdata,
2083 int new_fps)
2084{
2085 int rc = 0;
2086 u64 clk_rate;
2087 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2088 struct mdss_panel_info *pinfo;
2089 u32 phy_rev;
2090
2091 if (pdata == NULL) {
2092 pr_err("%s Invalid pdata\n", __func__);
2093 return -EINVAL;
2094 }
2095
2096 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2097 panel_data);
2098 if (ctrl_pdata == NULL) {
2099 pr_err("%s Invalid ctrl_pdata\n", __func__);
2100 return -EINVAL;
2101 }
2102
2103 pinfo = &pdata->panel_info;
2104 phy_rev = ctrl_pdata->shared_data->phy_rev;
2105
2106 rc = mdss_dsi_clk_div_config
2107 (&ctrl_pdata->panel_data.panel_info, new_fps);
2108 if (rc) {
2109 pr_err("%s: unable to initialize the clk dividers\n",
2110 __func__);
2111 return rc;
2112 }
2113
2114 __mdss_dsi_dyn_refresh_config(ctrl_pdata);
2115
2116 if (phy_rev == DSI_PHY_REV_20)
2117 mdss_dsi_dfps_config_8996(ctrl_pdata);
2118
2119 __mdss_dsi_calc_dfps_delay(pdata);
2120
2121 /* take a backup of current clk rates */
2122 ctrl_pdata->pclk_rate_bkp = ctrl_pdata->pclk_rate;
2123 ctrl_pdata->byte_clk_rate_bkp = ctrl_pdata->byte_clk_rate;
2124
2125 ctrl_pdata->pclk_rate = pinfo->mipi.dsi_pclk_rate;
2126 clk_rate = pinfo->clk_rate;
2127 do_div(clk_rate, 8U);
2128 ctrl_pdata->byte_clk_rate = (u32) clk_rate;
2129
2130 pr_debug("byte_rate=%i\n", ctrl_pdata->byte_clk_rate);
2131 pr_debug("pclk_rate=%i\n", ctrl_pdata->pclk_rate);
2132
2133 return rc;
2134}
2135
2136static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
2137 int new_fps)
2138{
2139 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2140 struct mdss_dsi_ctrl_pdata *sctrl_pdata = NULL;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05302141 struct mdss_panel_info *pinfo, *spinfo = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302142 int rc = 0;
2143
2144 if (pdata == NULL) {
2145 pr_err("%s Invalid pdata\n", __func__);
2146 return -EINVAL;
2147 }
2148
2149 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2150 panel_data);
2151 if (IS_ERR_OR_NULL(ctrl_pdata)) {
2152 pr_err("Invalid sctrl_pdata = %lu\n", PTR_ERR(ctrl_pdata));
2153 return PTR_ERR(ctrl_pdata);
2154 }
2155
2156 pinfo = &ctrl_pdata->panel_data.panel_info;
2157
2158 /*
2159 * In split display case, configure and enable dynamic refresh
2160 * register only after both the ctrl data is programmed. So,
2161 * ignore enabling dynamic refresh for the master control and
2162 * configure only when it is slave control.
2163 */
2164 if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
2165 mdss_dsi_is_ctrl_clk_master(ctrl_pdata))
2166 return 0;
2167
2168 if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
2169 mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) {
2170 sctrl_pdata = ctrl_pdata;
2171 spinfo = pinfo;
2172 ctrl_pdata = mdss_dsi_get_ctrl_clk_master();
2173 if (IS_ERR_OR_NULL(ctrl_pdata)) {
2174 pr_err("Invalid ctrl_pdata = %lu\n",
2175 PTR_ERR(ctrl_pdata));
2176 return PTR_ERR(ctrl_pdata);
2177 }
2178
2179 pinfo = &ctrl_pdata->panel_data.panel_info;
2180 }
2181
2182 /*
2183 * For programming dynamic refresh registers, we need to change
2184 * the parent to shadow clocks for the software byte and pixel mux.
2185 * After switching to shadow clocks, if there is no ref count on
2186 * main byte and pixel clocks, clock driver may shutdown those
2187 * unreferenced byte and pixel clocks. Hence add an extra reference
2188 * count to avoid shutting down the main byte and pixel clocks.
2189 */
2190 rc = clk_prepare_enable(ctrl_pdata->pll_byte_clk);
2191 if (rc) {
2192 pr_err("Unable to add extra refcnt for byte clock\n");
2193 goto error_byte;
2194 }
2195
2196 rc = clk_prepare_enable(ctrl_pdata->pll_pixel_clk);
2197 if (rc) {
2198 pr_err("Unable to add extra refcnt for pixel clock\n");
2199 goto error_pixel;
2200 }
2201
2202 /* change the parent to shadow clocks*/
2203 rc = clk_set_parent(ctrl_pdata->mux_byte_clk,
2204 ctrl_pdata->shadow_byte_clk);
2205 if (rc) {
2206 pr_err("Unable to set parent to shadow byte clock\n");
2207 goto error_shadow_byte;
2208 }
2209
2210 rc = clk_set_parent(ctrl_pdata->mux_pixel_clk,
2211 ctrl_pdata->shadow_pixel_clk);
2212 if (rc) {
2213 pr_err("Unable to set parent to shadow pixel clock\n");
2214 goto error_shadow_pixel;
2215 }
2216
2217 rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
2218 MDSS_DSI_LINK_BYTE_CLK, ctrl_pdata->byte_clk_rate, 0);
2219 if (rc) {
2220 pr_err("%s: dsi_byte_clk - clk_set_rate failed\n",
2221 __func__);
2222 goto error_byte_link;
2223 }
2224
2225 rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
2226 MDSS_DSI_LINK_PIX_CLK, ctrl_pdata->pclk_rate, 0);
2227 if (rc) {
2228 pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n",
2229 __func__);
2230 goto error_pixel_link;
2231 }
2232
2233 if (sctrl_pdata) {
2234 rc = mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle,
2235 MDSS_DSI_LINK_BYTE_CLK, sctrl_pdata->byte_clk_rate, 0);
2236 if (rc) {
2237 pr_err("%s: slv dsi_byte_clk - clk_set_rate failed\n",
2238 __func__);
2239 goto error_sbyte_link;
2240 }
2241
2242 rc = mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle,
2243 MDSS_DSI_LINK_PIX_CLK, sctrl_pdata->pclk_rate, 0);
2244 if (rc) {
2245 pr_err("%s: slv dsi_pixel_clk - clk_set_rate failed\n",
2246 __func__);
2247 goto error_spixel_link;
2248 }
2249 }
2250
2251 rc = mdss_dsi_en_wait4dynamic_done(ctrl_pdata);
2252 if (rc < 0) {
2253 pr_err("Unsuccessful dynamic fps change");
2254 goto dfps_timeout;
2255 }
2256
2257 MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, 0x00);
2258 if (sctrl_pdata)
2259 MIPI_OUTP((sctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL,
2260 0x00);
2261
2262 rc = mdss_dsi_phy_pll_reset_status(ctrl_pdata);
2263 if (rc) {
2264 pr_err("%s: pll cannot be locked reset core ready failed %d\n",
2265 __func__, rc);
2266 goto dfps_timeout;
2267 }
2268
2269 __mdss_dsi_mask_dfps_errors(ctrl_pdata, false);
2270 if (sctrl_pdata)
2271 __mdss_dsi_mask_dfps_errors(sctrl_pdata, false);
2272
2273 /* Move the mux clocks to main byte and pixel clocks */
2274 rc = clk_set_parent(ctrl_pdata->mux_byte_clk,
2275 ctrl_pdata->pll_byte_clk);
2276 if (rc)
2277 pr_err("Unable to set parent back to main byte clock\n");
2278
2279 rc = clk_set_parent(ctrl_pdata->mux_pixel_clk,
2280 ctrl_pdata->pll_pixel_clk);
2281 if (rc)
2282 pr_err("Unable to set parent back to main pixel clock\n");
2283
2284 /* Remove extra ref count on parent clocks */
2285 clk_disable_unprepare(ctrl_pdata->pll_byte_clk);
2286 clk_disable_unprepare(ctrl_pdata->pll_pixel_clk);
2287
2288 /* update new fps that at this point is already updated in hw */
2289 pinfo->current_fps = new_fps;
2290 if (sctrl_pdata)
2291 spinfo->current_fps = new_fps;
2292
2293 return rc;
2294
2295dfps_timeout:
2296 if (sctrl_pdata)
2297 mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle,
2298 MDSS_DSI_LINK_PIX_CLK,
2299 sctrl_pdata->pclk_rate_bkp, 0);
2300error_spixel_link:
2301 if (sctrl_pdata)
2302 mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle,
2303 MDSS_DSI_LINK_BYTE_CLK,
2304 sctrl_pdata->byte_clk_rate_bkp, 0);
2305error_sbyte_link:
2306 mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
2307 MDSS_DSI_LINK_PIX_CLK, ctrl_pdata->pclk_rate_bkp, 0);
2308error_pixel_link:
2309 mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
2310 MDSS_DSI_LINK_BYTE_CLK, ctrl_pdata->byte_clk_rate_bkp, 0);
2311error_byte_link:
2312 clk_set_parent(ctrl_pdata->mux_pixel_clk, ctrl_pdata->pll_pixel_clk);
2313error_shadow_pixel:
2314 clk_set_parent(ctrl_pdata->mux_byte_clk, ctrl_pdata->pll_byte_clk);
2315error_shadow_byte:
2316 clk_disable_unprepare(ctrl_pdata->pll_pixel_clk);
2317error_pixel:
2318 clk_disable_unprepare(ctrl_pdata->pll_byte_clk);
2319error_byte:
2320 return rc;
2321}
2322
2323static int mdss_dsi_check_params(struct mdss_dsi_ctrl_pdata *ctrl, void *arg)
2324{
2325 struct mdss_panel_info *var_pinfo, *pinfo;
2326 int rc = 0;
2327
2328 if (!ctrl || !arg)
2329 return 0;
2330
2331 pinfo = &ctrl->panel_data.panel_info;
2332 if (!pinfo->is_pluggable)
2333 return 0;
2334
2335 var_pinfo = (struct mdss_panel_info *)arg;
2336
2337 pr_debug("%s: reconfig xres: %d yres: %d, current xres: %d yres: %d\n",
2338 __func__, var_pinfo->xres, var_pinfo->yres,
2339 pinfo->xres, pinfo->yres);
2340 if ((var_pinfo->xres != pinfo->xres) ||
2341 (var_pinfo->yres != pinfo->yres) ||
2342 (var_pinfo->lcdc.h_back_porch != pinfo->lcdc.h_back_porch) ||
2343 (var_pinfo->lcdc.h_front_porch != pinfo->lcdc.h_front_porch) ||
2344 (var_pinfo->lcdc.h_pulse_width != pinfo->lcdc.h_pulse_width) ||
2345 (var_pinfo->lcdc.v_back_porch != pinfo->lcdc.v_back_porch) ||
2346 (var_pinfo->lcdc.v_front_porch != pinfo->lcdc.v_front_porch) ||
2347 (var_pinfo->lcdc.v_pulse_width != pinfo->lcdc.v_pulse_width)
2348 )
2349 rc = 1;
2350
2351 return rc;
2352}
2353
2354#ifdef TARGET_HW_MDSS_HDMI
2355static void mdss_dsi_update_params(struct mdss_dsi_ctrl_pdata *ctrl, void *arg)
2356{
2357 struct mdss_panel_info *pinfo;
2358
2359 if (!ctrl || !arg)
2360 return;
2361
2362 pinfo = &ctrl->panel_data.panel_info;
2363 mdss_dba_update_lane_cfg(pinfo);
2364}
2365#else
2366static void mdss_dsi_update_params(struct mdss_dsi_ctrl_pdata *ctrl, void *arg)
2367{
2368}
2369#endif
2370
2371static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
2372{
2373 int rc = 0;
2374 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2375 struct mdss_panel_info *pinfo;
2376 u32 phy_rev;
2377 u32 frame_rate_bkp;
2378
2379 pr_debug("%s+:\n", __func__);
2380
2381 if (pdata == NULL) {
2382 pr_err("%s: Invalid input data\n", __func__);
2383 return -EINVAL;
2384 }
2385
2386 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2387 panel_data);
2388
2389 if (!ctrl_pdata->panel_data.panel_info.dynamic_fps) {
2390 pr_err("Dynamic fps not enabled for this panel\n");
2391 return -EINVAL;
2392 }
2393
2394 phy_rev = ctrl_pdata->shared_data->phy_rev;
2395 pinfo = &pdata->panel_info;
2396
2397 /* get the fps configured in HW */
2398 frame_rate_bkp = pinfo->current_fps;
2399
2400 if (new_fps == pinfo->current_fps) {
2401 /*
2402 * This is unlikely as mdss driver checks for previously
2403 * configured frame rate.
2404 */
2405 pr_debug("Panel is already at this FPS\n");
2406 goto end_update;
2407 }
2408
2409 if (pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP ||
2410 pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP) {
2411 /* Porch method */
2412 __mdss_dsi_update_video_mode_total(pdata, new_fps);
2413 } else if (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
2414 /* Clock update method */
2415
2416 __mdss_dsi_mask_dfps_errors(ctrl_pdata, true);
2417
2418 if (phy_rev == DSI_PHY_REV_20) {
2419 rc = mdss_dsi_phy_calc_timing_param(pinfo, phy_rev,
2420 new_fps);
2421 if (rc) {
2422 pr_err("PHY calculations failed-%d\n", new_fps);
2423 goto end_update;
2424 }
2425 }
2426
2427 rc = __mdss_dsi_dfps_calc_clks(pdata, new_fps);
2428 if (rc) {
2429 pr_err("error calculating clocks for %d\n", new_fps);
2430 goto error_clks;
2431 }
2432
2433 rc = __mdss_dsi_dfps_update_clks(pdata, new_fps);
2434 if (rc) {
2435 pr_err("Dynamic refresh failed-%d\n", new_fps);
2436 goto error_dfps;
2437 }
2438 }
2439
2440 return rc;
2441error_dfps:
2442 if (__mdss_dsi_dfps_calc_clks(pdata, frame_rate_bkp))
2443 pr_err("error reverting clock calculations for %d\n",
2444 frame_rate_bkp);
2445error_clks:
2446 if (mdss_dsi_phy_calc_timing_param(pinfo, phy_rev, frame_rate_bkp))
2447 pr_err("Unable to revert phy timing-%d\n", frame_rate_bkp);
2448end_update:
2449 return rc;
2450}
2451
2452static int mdss_dsi_ctl_partial_roi(struct mdss_panel_data *pdata)
2453{
2454 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2455 int rc = -EINVAL;
2456
2457 if (pdata == NULL) {
2458 pr_err("%s: Invalid input data\n", __func__);
2459 return -EINVAL;
2460 }
2461
2462 if (!pdata->panel_info.partial_update_enabled)
2463 return 0;
2464
2465 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2466 panel_data);
2467
2468 if (ctrl_pdata->set_col_page_addr)
2469 rc = ctrl_pdata->set_col_page_addr(pdata, false);
2470
2471 return rc;
2472}
2473
2474static int mdss_dsi_set_stream_size(struct mdss_panel_data *pdata)
2475{
2476 u32 stream_ctrl, stream_total, idle;
2477 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2478 struct mdss_panel_info *pinfo;
2479 struct dsc_desc *dsc = NULL;
2480 struct mdss_rect *roi;
2481 struct panel_horizontal_idle *pidle;
2482 int i;
2483
2484 if (pdata == NULL) {
2485 pr_err("%s: Invalid input data\n", __func__);
2486 return -EINVAL;
2487 }
2488
2489 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2490 panel_data);
2491
2492 pinfo = &pdata->panel_info;
2493
2494 if (!pinfo->partial_update_supported)
2495 return -EINVAL;
2496
2497 if (pinfo->compression_mode == COMPRESSION_DSC)
2498 dsc = &pinfo->dsc;
2499
2500 roi = &pinfo->roi;
2501
2502 /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */
2503 if (dsc) {
2504 u16 byte_num = dsc->bytes_per_pkt;
2505
2506 if (pinfo->mipi.insert_dcs_cmd)
2507 byte_num++;
2508
2509 stream_ctrl = (byte_num << 16) | (pinfo->mipi.vc << 8) |
2510 DTYPE_DCS_LWRITE;
2511 stream_total = dsc->pic_height << 16 | dsc->pclk_per_line;
2512 } else {
2513
2514 stream_ctrl = (((roi->w * 3) + 1) << 16) |
2515 (pdata->panel_info.mipi.vc << 8) | DTYPE_DCS_LWRITE;
2516 stream_total = roi->h << 16 | roi->w;
2517 }
2518 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x60, stream_ctrl);
2519 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x58, stream_ctrl);
2520
2521 /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */
2522 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, stream_total);
2523 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, stream_total);
2524
2525 /* set idle control -- dsi clk cycle */
2526 idle = 0;
2527 pidle = ctrl_pdata->line_idle;
2528 for (i = 0; i < ctrl_pdata->horizontal_idle_cnt; i++) {
2529 if (roi->w > pidle->min && roi->w <= pidle->max) {
2530 idle = pidle->idle;
2531 pr_debug("%s: ndx=%d w=%d range=%d-%d idle=%d\n",
2532 __func__, ctrl_pdata->ndx, roi->w,
2533 pidle->min, pidle->max, pidle->idle);
2534 break;
2535 }
2536 pidle++;
2537 }
2538
2539 if (idle)
2540 idle |= BIT(12); /* enable */
2541
2542 MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x194, idle);
2543
2544 if (dsc)
2545 mdss_dsi_dsc_config(ctrl_pdata, dsc);
2546
2547 return 0;
2548}
2549
2550#ifdef TARGET_HW_MDSS_HDMI
2551static void mdss_dsi_dba_work(struct work_struct *work)
2552{
2553 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2554 struct delayed_work *dw = to_delayed_work(work);
2555 struct mdss_dba_utils_init_data utils_init_data;
2556 struct mdss_panel_info *pinfo;
2557
2558 ctrl_pdata = container_of(dw, struct mdss_dsi_ctrl_pdata, dba_work);
2559 if (!ctrl_pdata) {
2560 pr_err("%s: invalid ctrl data\n", __func__);
2561 return;
2562 }
2563
2564 pinfo = &ctrl_pdata->panel_data.panel_info;
2565 if (!pinfo) {
2566 pr_err("%s: invalid ctrl data\n", __func__);
2567 return;
2568 }
2569
2570 memset(&utils_init_data, 0, sizeof(utils_init_data));
2571
2572 utils_init_data.chip_name = ctrl_pdata->bridge_name;
2573 utils_init_data.client_name = "dsi";
2574 utils_init_data.instance_id = ctrl_pdata->bridge_index;
2575 utils_init_data.fb_node = ctrl_pdata->fb_node;
2576 utils_init_data.kobj = ctrl_pdata->kobj;
2577 utils_init_data.pinfo = pinfo;
2578 if (ctrl_pdata->mdss_util)
2579 utils_init_data.cont_splash_enabled =
2580 ctrl_pdata->mdss_util->panel_intf_status(
2581 ctrl_pdata->panel_data.panel_info.pdest,
2582 MDSS_PANEL_INTF_DSI) ? true : false;
2583 else
2584 utils_init_data.cont_splash_enabled = false;
2585
2586 pinfo->dba_data = mdss_dba_utils_init(&utils_init_data);
2587
2588 if (!IS_ERR_OR_NULL(pinfo->dba_data)) {
2589 ctrl_pdata->ds_registered = true;
2590 } else {
2591 pr_debug("%s: dba device not ready, queue again\n", __func__);
2592 queue_delayed_work(ctrl_pdata->workq,
2593 &ctrl_pdata->dba_work, HZ);
2594 }
2595}
2596#else
2597static void mdss_dsi_dba_work(struct work_struct *work)
2598{
2599 (void)(*work);
2600}
2601#endif
2602static int mdss_dsi_reset_write_ptr(struct mdss_panel_data *pdata)
2603{
2604
2605 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2606 struct mdss_panel_info *pinfo;
2607 int rc = 0;
2608
2609 if (pdata == NULL) {
2610 pr_err("%s: Invalid input data\n", __func__);
2611 return -EINVAL;
2612 }
2613
2614 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2615 panel_data);
2616
2617 pinfo = &ctrl_pdata->panel_data.panel_info;
2618 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
2619 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
2620 /* Need to reset the DSI core since the pixel stream was stopped. */
2621 mdss_dsi_sw_reset(ctrl_pdata, true);
2622
2623 /*
2624 * Reset the partial update co-ordinates to the panel height and
2625 * width
2626 */
2627 if (pinfo->dcs_cmd_by_left && (ctrl_pdata->ndx == 1))
2628 goto skip_cmd_send;
2629
2630 pinfo->roi.x = 0;
2631 pinfo->roi.y = 0;
2632 pinfo->roi.w = pinfo->xres;
2633 if (pinfo->dcs_cmd_by_left)
2634 pinfo->roi.w = pinfo->xres;
2635 if (pdata->next)
2636 pinfo->roi.w += pdata->next->panel_info.xres;
2637 pinfo->roi.h = pinfo->yres;
2638
2639 mdss_dsi_set_stream_size(pdata);
2640
2641 if (ctrl_pdata->set_col_page_addr)
2642 rc = ctrl_pdata->set_col_page_addr(pdata, true);
2643
2644skip_cmd_send:
2645 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
2646 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_OFF);
2647
2648 pr_debug("%s: DSI%d write ptr reset finished\n", __func__,
2649 ctrl_pdata->ndx);
2650
2651 return rc;
2652}
2653
2654int mdss_dsi_register_recovery_handler(struct mdss_dsi_ctrl_pdata *ctrl,
2655 struct mdss_intf_recovery *recovery)
2656{
2657 mutex_lock(&ctrl->mutex);
2658 ctrl->recovery = recovery;
2659 mutex_unlock(&ctrl->mutex);
2660 return 0;
2661}
2662
2663static int mdss_dsi_register_mdp_callback(struct mdss_dsi_ctrl_pdata *ctrl,
2664 struct mdss_intf_recovery *mdp_callback)
2665{
2666 mutex_lock(&ctrl->mutex);
2667 ctrl->mdp_callback = mdp_callback;
2668 mutex_unlock(&ctrl->mutex);
2669 return 0;
2670}
2671
2672static struct device_node *mdss_dsi_get_fb_node_cb(struct platform_device *pdev)
2673{
2674 struct device_node *fb_node;
2675 struct platform_device *dsi_dev;
2676 struct mdss_dsi_ctrl_pdata *ctrl_pdata;
2677
2678 if (pdev == NULL) {
2679 pr_err("%s: Invalid input data\n", __func__);
2680 return NULL;
2681 }
2682
2683 ctrl_pdata = platform_get_drvdata(pdev);
2684 dsi_dev = of_find_device_by_node(pdev->dev.of_node->parent);
2685 if (!dsi_dev) {
2686 pr_err("Unable to find dsi master device: %s\n",
2687 pdev->dev.of_node->full_name);
2688 return NULL;
2689 }
2690
2691 fb_node = of_parse_phandle(dsi_dev->dev.of_node,
2692 mdss_dsi_get_fb_name(ctrl_pdata), 0);
2693 if (!fb_node) {
2694 pr_err("Unable to find fb node for device: %s\n", pdev->name);
2695 return NULL;
2696 }
2697
2698 return fb_node;
2699}
2700
2701static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
2702 int event, void *arg)
2703{
2704 int rc = 0;
2705 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
2706 struct fb_info *fbi;
2707 int power_state;
2708 u32 mode;
2709 struct mdss_panel_info *pinfo;
2710
2711 if (pdata == NULL) {
2712 pr_err("%s: Invalid input data\n", __func__);
2713 return -EINVAL;
2714 }
2715 pinfo = &pdata->panel_info;
2716 ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
2717 panel_data);
2718 pr_debug("%s+: ctrl=%d event=%d\n", __func__, ctrl_pdata->ndx, event);
2719
2720 MDSS_XLOG(event, arg, ctrl_pdata->ndx, 0x3333);
2721
2722 switch (event) {
2723 case MDSS_EVENT_UPDATE_PARAMS:
2724 pr_debug("%s:Entered Case MDSS_EVENT_UPDATE_PARAMS\n",
2725 __func__);
2726 mdss_dsi_update_params(ctrl_pdata, arg);
2727 break;
2728 case MDSS_EVENT_CHECK_PARAMS:
2729 pr_debug("%s:Entered Case MDSS_EVENT_CHECK_PARAMS\n", __func__);
2730 if (mdss_dsi_check_params(ctrl_pdata, arg)) {
2731 ctrl_pdata->update_phy_timing = true;
2732 /*
2733 * Call to MDSS_EVENT_CHECK_PARAMS expects
2734 * the return value of 1, if there is a change
2735 * in panel timing parameters.
2736 */
2737 rc = 1;
2738 }
2739 ctrl_pdata->refresh_clk_rate = true;
2740 break;
2741 case MDSS_EVENT_LINK_READY:
2742 if (ctrl_pdata->refresh_clk_rate)
2743 rc = mdss_dsi_clk_refresh(pdata,
2744 ctrl_pdata->update_phy_timing);
2745
2746 rc = mdss_dsi_on(pdata);
2747 mdss_dsi_op_mode_config(pdata->panel_info.mipi.mode,
2748 pdata);
2749 break;
2750 case MDSS_EVENT_UNBLANK:
2751 if (ctrl_pdata->on_cmds.link_state == DSI_LP_MODE)
2752 rc = mdss_dsi_unblank(pdata);
2753 break;
2754 case MDSS_EVENT_POST_PANEL_ON:
2755 rc = mdss_dsi_post_panel_on(pdata);
2756 break;
2757 case MDSS_EVENT_PANEL_ON:
2758 ctrl_pdata->ctrl_state |= CTRL_STATE_MDP_ACTIVE;
2759 if (ctrl_pdata->on_cmds.link_state == DSI_HS_MODE)
2760 rc = mdss_dsi_unblank(pdata);
2761 pdata->panel_info.esd_rdy = true;
2762 break;
2763 case MDSS_EVENT_BLANK:
2764 power_state = (int) (unsigned long) arg;
2765 if (ctrl_pdata->off_cmds.link_state == DSI_HS_MODE)
2766 rc = mdss_dsi_blank(pdata, power_state);
2767 break;
2768 case MDSS_EVENT_PANEL_OFF:
2769 power_state = (int) (unsigned long) arg;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302770 ctrl_pdata->ctrl_state &= ~CTRL_STATE_MDP_ACTIVE;
2771 if (ctrl_pdata->off_cmds.link_state == DSI_LP_MODE)
2772 rc = mdss_dsi_blank(pdata, power_state);
2773 rc = mdss_dsi_off(pdata, power_state);
2774 break;
2775 case MDSS_EVENT_CONT_SPLASH_FINISH:
2776 if (ctrl_pdata->off_cmds.link_state == DSI_LP_MODE)
2777 rc = mdss_dsi_blank(pdata, MDSS_PANEL_POWER_OFF);
2778 ctrl_pdata->ctrl_state &= ~CTRL_STATE_MDP_ACTIVE;
2779 rc = mdss_dsi_cont_splash_on(pdata);
2780 break;
2781 case MDSS_EVENT_PANEL_CLK_CTRL:
2782 mdss_dsi_clk_req(ctrl_pdata,
2783 (struct dsi_panel_clk_ctrl *) arg);
2784 break;
2785 case MDSS_EVENT_DSI_CMDLIST_KOFF:
2786 mdss_dsi_cmdlist_commit(ctrl_pdata, 1);
2787 break;
2788 case MDSS_EVENT_PANEL_UPDATE_FPS:
2789 if (arg != NULL) {
2790 rc = mdss_dsi_dfps_config(pdata,
2791 (int) (unsigned long) arg);
2792 if (rc)
2793 pr_err("unable to change fps-%d, error-%d\n",
2794 (int) (unsigned long) arg, rc);
2795 else
2796 pr_debug("panel frame rate changed to %d\n",
2797 (int) (unsigned long) arg);
2798 }
2799 break;
2800 case MDSS_EVENT_CONT_SPLASH_BEGIN:
2801 if (ctrl_pdata->off_cmds.link_state == DSI_HS_MODE) {
2802 /* Panel is Enabled in Bootloader */
2803 rc = mdss_dsi_blank(pdata, MDSS_PANEL_POWER_OFF);
2804 }
2805 break;
2806 case MDSS_EVENT_DSC_PPS_SEND:
2807 if (pinfo->compression_mode == COMPRESSION_DSC)
2808 mdss_dsi_panel_dsc_pps_send(ctrl_pdata, pinfo);
2809 break;
2810 case MDSS_EVENT_ENABLE_PARTIAL_ROI:
2811 rc = mdss_dsi_ctl_partial_roi(pdata);
2812 break;
2813 case MDSS_EVENT_DSI_RESET_WRITE_PTR:
2814 rc = mdss_dsi_reset_write_ptr(pdata);
2815 break;
2816 case MDSS_EVENT_DSI_STREAM_SIZE:
2817 rc = mdss_dsi_set_stream_size(pdata);
2818 break;
2819 case MDSS_EVENT_DSI_UPDATE_PANEL_DATA:
2820 rc = mdss_dsi_update_panel_config(ctrl_pdata,
2821 (int)(unsigned long) arg);
2822 break;
2823 case MDSS_EVENT_REGISTER_RECOVERY_HANDLER:
2824 rc = mdss_dsi_register_recovery_handler(ctrl_pdata,
2825 (struct mdss_intf_recovery *)arg);
2826 break;
2827 case MDSS_EVENT_REGISTER_MDP_CALLBACK:
2828 rc = mdss_dsi_register_mdp_callback(ctrl_pdata,
2829 (struct mdss_intf_recovery *)arg);
2830 break;
2831 case MDSS_EVENT_DSI_DYNAMIC_SWITCH:
2832 mode = (u32)(unsigned long) arg;
2833 mdss_dsi_switch_mode(pdata, mode);
2834 break;
2835 case MDSS_EVENT_DSI_RECONFIG_CMD:
2836 mode = (u32)(unsigned long) arg;
2837 rc = mdss_dsi_reconfig(pdata, mode);
2838 break;
2839 case MDSS_EVENT_DSI_PANEL_STATUS:
2840 if (ctrl_pdata->check_status)
2841 rc = ctrl_pdata->check_status(ctrl_pdata);
2842 else
2843 rc = true;
2844 break;
2845 case MDSS_EVENT_PANEL_TIMING_SWITCH:
2846 rc = mdss_dsi_panel_timing_switch(ctrl_pdata, arg);
2847 break;
2848 case MDSS_EVENT_FB_REGISTERED:
2849 mdss_dsi_debugfs_init(ctrl_pdata);
2850
2851 fbi = (struct fb_info *)arg;
2852 if (!fbi || !fbi->dev)
2853 break;
2854
2855 ctrl_pdata->kobj = &fbi->dev->kobj;
2856 ctrl_pdata->fb_node = fbi->node;
2857
2858 if (IS_ENABLED(CONFIG_MSM_DBA) &&
2859 pdata->panel_info.is_dba_panel) {
2860 queue_delayed_work(ctrl_pdata->workq,
2861 &ctrl_pdata->dba_work, HZ);
2862 }
2863 break;
2864 default:
2865 pr_debug("%s: unhandled event=%d\n", __func__, event);
2866 break;
2867 }
2868 pr_debug("%s-:event=%d, rc=%d\n", __func__, event, rc);
2869 return rc;
2870}
2871
2872static int mdss_dsi_set_override_cfg(char *override_cfg,
2873 struct mdss_dsi_ctrl_pdata *ctrl_pdata, char *panel_cfg)
2874{
2875 struct mdss_panel_info *pinfo = &ctrl_pdata->panel_data.panel_info;
2876 char *token = NULL;
2877
2878 pr_debug("%s: override config:%s\n", __func__, override_cfg);
2879 while ((token = strsep(&override_cfg, ":"))) {
2880 if (!strcmp(token, OVERRIDE_CFG)) {
2881 continue;
2882 } else if (!strcmp(token, SIM_HW_TE_PANEL)) {
2883 pinfo->sim_panel_mode = SIM_HW_TE_MODE;
2884 } else if (!strcmp(token, SIM_SW_TE_PANEL)) {
2885 pinfo->sim_panel_mode = SIM_SW_TE_MODE;
2886 } else if (!strcmp(token, SIM_PANEL)) {
2887 pinfo->sim_panel_mode = SIM_MODE;
2888 } else {
2889 pr_err("%s: invalid override_cfg token: %s\n",
2890 __func__, token);
2891 return -EINVAL;
2892 }
2893 }
2894 pr_debug("%s:sim_panel_mode:%d\n", __func__, pinfo->sim_panel_mode);
2895
2896 return 0;
2897}
2898
2899static struct device_node *mdss_dsi_pref_prim_panel(
2900 struct platform_device *pdev)
2901{
2902 struct device_node *dsi_pan_node = NULL;
2903
2904 pr_debug("%s:%d: Select primary panel from dt\n",
2905 __func__, __LINE__);
2906 dsi_pan_node = of_parse_phandle(pdev->dev.of_node,
2907 "qcom,dsi-pref-prim-pan", 0);
2908 if (!dsi_pan_node)
2909 pr_err("%s:can't find panel phandle\n", __func__);
2910
2911 return dsi_pan_node;
2912}
2913
2914/**
2915 * mdss_dsi_find_panel_of_node(): find device node of dsi panel
2916 * @pdev: platform_device of the dsi ctrl node
2917 * @panel_cfg: string containing intf specific config data
2918 *
2919 * Function finds the panel device node using the interface
2920 * specific configuration data. This configuration data is
2921 * could be derived from the result of bootloader's GCDB
2922 * panel detection mechanism. If such config data doesn't
2923 * exist then this panel returns the default panel configured
2924 * in the device tree.
2925 *
2926 * returns pointer to panel node on success, NULL on error.
2927 */
2928static struct device_node *mdss_dsi_find_panel_of_node(
2929 struct platform_device *pdev, char *panel_cfg)
2930{
2931 int len, i = 0;
2932 int ctrl_id = pdev->id - 1;
2933 char panel_name[MDSS_MAX_PANEL_LEN] = "";
2934 char ctrl_id_stream[3] = "0:";
2935 char *str1 = NULL, *str2 = NULL, *override_cfg = NULL;
2936 char cfg_np_name[MDSS_MAX_PANEL_LEN] = "";
2937 struct device_node *dsi_pan_node = NULL, *mdss_node = NULL;
2938 struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev);
2939 struct mdss_panel_info *pinfo = &ctrl_pdata->panel_data.panel_info;
2940
2941 len = strlen(panel_cfg);
2942 ctrl_pdata->panel_data.dsc_cfg_np_name[0] = '\0';
2943 if (!len) {
2944 /* no panel cfg chg, parse dt */
2945 pr_debug("%s:%d: no cmd line cfg present\n",
2946 __func__, __LINE__);
2947 goto end;
2948 } else {
2949 /* check if any override parameters are set */
2950 pinfo->sim_panel_mode = 0;
2951 override_cfg = strnstr(panel_cfg, "#" OVERRIDE_CFG, len);
2952 if (override_cfg) {
2953 *override_cfg = '\0';
2954 if (mdss_dsi_set_override_cfg(override_cfg + 1,
2955 ctrl_pdata, panel_cfg))
2956 return NULL;
2957 len = strlen(panel_cfg);
2958 }
2959
2960 if (ctrl_id == 1)
2961 strlcpy(ctrl_id_stream, "1:", 3);
2962
2963 /* get controller number */
2964 str1 = strnstr(panel_cfg, ctrl_id_stream, len);
2965 if (!str1) {
2966 pr_err("%s: controller %s is not present in %s\n",
2967 __func__, ctrl_id_stream, panel_cfg);
2968 goto end;
2969 }
2970 if ((str1 != panel_cfg) && (*(str1-1) != ':')) {
2971 str1 += CMDLINE_DSI_CTL_NUM_STRING_LEN;
2972 pr_debug("false match with config node name in \"%s\". search again in \"%s\"\n",
2973 panel_cfg, str1);
2974 str1 = strnstr(str1, ctrl_id_stream, len);
2975 if (!str1) {
2976 pr_err("%s: 2. controller %s is not present in %s\n",
2977 __func__, ctrl_id_stream, str1);
2978 goto end;
2979 }
2980 }
2981 str1 += CMDLINE_DSI_CTL_NUM_STRING_LEN;
2982
2983 /* get panel name */
2984 str2 = strnchr(str1, strlen(str1), ':');
2985 if (!str2) {
2986 strlcpy(panel_name, str1, MDSS_MAX_PANEL_LEN);
2987 } else {
2988 for (i = 0; (str1 + i) < str2; i++)
2989 panel_name[i] = *(str1 + i);
2990 panel_name[i] = 0;
2991 }
2992 pr_info("%s: cmdline:%s panel_name:%s\n",
2993 __func__, panel_cfg, panel_name);
2994 if (!strcmp(panel_name, NONE_PANEL))
2995 goto exit;
2996
2997 mdss_node = of_parse_phandle(pdev->dev.of_node,
2998 "qcom,mdss-mdp", 0);
2999 if (!mdss_node) {
3000 pr_err("%s: %d: mdss_node null\n",
3001 __func__, __LINE__);
3002 return NULL;
3003 }
3004 dsi_pan_node = of_find_node_by_name(mdss_node, panel_name);
3005 if (!dsi_pan_node) {
3006 pr_err("%s: invalid pan node \"%s\"\n",
3007 __func__, panel_name);
3008 goto end;
3009 } else {
3010 /* extract config node name if present */
3011 str1 += i;
3012 str2 = strnstr(str1, "config", strlen(str1));
3013 if (str2) {
3014 str1 = strnchr(str2, strlen(str2), ':');
3015 if (str1) {
3016 for (i = 0; ((str2 + i) < str1) &&
3017 i < (MDSS_MAX_PANEL_LEN - 1); i++)
3018 cfg_np_name[i] = *(str2 + i);
3019 if ((i >= 0)
3020 && (i < MDSS_MAX_PANEL_LEN))
3021 cfg_np_name[i] = 0;
3022 } else {
3023 strlcpy(cfg_np_name, str2,
3024 MDSS_MAX_PANEL_LEN);
3025 }
3026 strlcpy(ctrl_pdata->panel_data.dsc_cfg_np_name,
3027 cfg_np_name, MDSS_MAX_PANEL_LEN);
3028 }
3029 }
3030
3031 return dsi_pan_node;
3032 }
3033end:
3034 if (strcmp(panel_name, NONE_PANEL))
3035 dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
3036exit:
3037 return dsi_pan_node;
3038}
3039
3040static struct device_node *mdss_dsi_config_panel(struct platform_device *pdev,
3041 int ndx)
3042{
3043 struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev);
3044 char panel_cfg[MDSS_MAX_PANEL_LEN];
3045 struct device_node *dsi_pan_node = NULL;
3046 int rc = 0;
3047
3048 if (!ctrl_pdata) {
3049 pr_err("%s: Unable to get the ctrl_pdata\n", __func__);
3050 return NULL;
3051 }
3052
3053 /* DSI panels can be different between controllers */
3054 rc = mdss_dsi_get_panel_cfg(panel_cfg, ctrl_pdata);
3055 if (!rc)
3056 /* dsi panel cfg not present */
3057 pr_warn("%s:%d:dsi specific cfg not present\n",
3058 __func__, __LINE__);
3059
3060 /* find panel device node */
3061 dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg);
3062 if (!dsi_pan_node) {
3063 pr_err("%s: can't find panel node %s\n", __func__, panel_cfg);
3064 of_node_put(dsi_pan_node);
3065 return NULL;
3066 }
3067
3068 rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, ndx);
3069 if (rc) {
3070 pr_err("%s: dsi panel init failed\n", __func__);
3071 of_node_put(dsi_pan_node);
3072 return NULL;
3073 }
3074
3075 return dsi_pan_node;
3076}
3077
3078static int mdss_dsi_ctrl_clock_init(struct platform_device *ctrl_pdev,
3079 struct mdss_dsi_ctrl_pdata *ctrl_pdata)
3080{
3081 int rc = 0;
3082 struct mdss_dsi_clk_info info;
3083 struct mdss_dsi_clk_client client1 = {"dsi_clk_client"};
3084 struct mdss_dsi_clk_client client2 = {"mdp_event_client"};
3085 void *handle;
3086
3087 if (mdss_dsi_link_clk_init(ctrl_pdev, ctrl_pdata)) {
3088 pr_err("%s: unable to initialize Dsi ctrl clks\n", __func__);
3089 return -EPERM;
3090 }
3091
3092 memset(&info, 0x0, sizeof(info));
3093
3094 info.core_clks.mdp_core_clk = ctrl_pdata->shared_data->mdp_core_clk;
3095 info.core_clks.ahb_clk = ctrl_pdata->shared_data->ahb_clk;
3096 info.core_clks.axi_clk = ctrl_pdata->shared_data->axi_clk;
3097 info.core_clks.mmss_misc_ahb_clk =
3098 ctrl_pdata->shared_data->mmss_misc_ahb_clk;
3099
Padmanabhan Komandurub0008fd2018-04-12 16:25:43 +05303100 info.link_lp_clks.esc_clk = ctrl_pdata->esc_clk;
3101 info.link_hs_clks.byte_clk = ctrl_pdata->byte_clk;
3102 info.link_hs_clks.pixel_clk = ctrl_pdata->pixel_clk;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303103
3104 info.pre_clkoff_cb = mdss_dsi_pre_clkoff_cb;
3105 info.post_clkon_cb = mdss_dsi_post_clkon_cb;
3106 info.pre_clkon_cb = mdss_dsi_pre_clkon_cb;
3107 info.post_clkoff_cb = mdss_dsi_post_clkoff_cb;
3108 info.priv_data = ctrl_pdata;
3109 snprintf(info.name, DSI_CLK_NAME_LEN, "DSI%d", ctrl_pdata->ndx);
3110 ctrl_pdata->clk_mngr = mdss_dsi_clk_init(&info);
3111 if (IS_ERR_OR_NULL(ctrl_pdata->clk_mngr)) {
3112 rc = PTR_ERR(ctrl_pdata->clk_mngr);
3113 ctrl_pdata->clk_mngr = NULL;
3114 pr_err("dsi clock registration failed, rc = %d\n", rc);
3115 goto error_link_clk_deinit;
3116 }
3117
3118 /*
3119 * There are two clients that control dsi clocks. MDP driver controls
3120 * the clock through MDSS_PANEL_EVENT_CLK_CTRL event and dsi driver
3121 * through clock interface. To differentiate between the votes from the
3122 * two clients, dsi driver will use two different handles to vote for
3123 * clock states from dsi and mdp driver.
3124 */
3125 handle = mdss_dsi_clk_register(ctrl_pdata->clk_mngr, &client1);
3126 if (IS_ERR_OR_NULL(handle)) {
3127 rc = PTR_ERR(handle);
3128 pr_err("failed to register %s client, rc = %d\n",
3129 client1.client_name, rc);
3130 goto error_clk_deinit;
3131 } else {
3132 ctrl_pdata->dsi_clk_handle = handle;
3133 }
3134
3135 handle = mdss_dsi_clk_register(ctrl_pdata->clk_mngr, &client2);
3136 if (IS_ERR_OR_NULL(handle)) {
3137 rc = PTR_ERR(handle);
3138 pr_err("failed to register %s client, rc = %d\n",
3139 client2.client_name, rc);
3140 goto error_clk_client_deregister;
3141 } else {
3142 ctrl_pdata->mdp_clk_handle = handle;
3143 }
3144
3145 return rc;
3146error_clk_client_deregister:
3147 mdss_dsi_clk_deregister(ctrl_pdata->dsi_clk_handle);
3148error_clk_deinit:
3149 mdss_dsi_clk_deinit(ctrl_pdata->clk_mngr);
3150error_link_clk_deinit:
3151 mdss_dsi_link_clk_deinit(&ctrl_pdev->dev, ctrl_pdata);
3152 return rc;
3153}
3154
3155static int mdss_dsi_set_clk_rates(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
3156{
3157 int rc = 0;
3158
3159 rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
3160 MDSS_DSI_LINK_BYTE_CLK,
3161 ctrl_pdata->byte_clk_rate,
3162 MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON);
3163 if (rc) {
3164 pr_err("%s: dsi_byte_clk - clk_set_rate failed\n",
3165 __func__);
3166 return rc;
3167 }
3168
3169 rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
3170 MDSS_DSI_LINK_PIX_CLK,
3171 ctrl_pdata->pclk_rate,
3172 MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON);
3173 if (rc) {
3174 pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n",
3175 __func__);
3176 return rc;
3177 }
3178
3179 rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle,
3180 MDSS_DSI_LINK_ESC_CLK,
3181 19200000,
3182 MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON);
3183 if (rc) {
3184 pr_err("%s: dsi_esc_clk - clk_set_rate failed\n",
3185 __func__);
3186 return rc;
3187 }
3188
3189 return rc;
3190}
3191
3192static int mdss_dsi_cont_splash_config(struct mdss_panel_info *pinfo,
3193 struct mdss_dsi_ctrl_pdata *ctrl_pdata)
3194{
3195 void *clk_handle;
3196 int rc = 0;
3197
3198 if (pinfo->cont_splash_enabled) {
3199 rc = mdss_dsi_panel_power_ctrl(&(ctrl_pdata->panel_data),
3200 MDSS_PANEL_POWER_ON);
3201 if (rc) {
3202 pr_err("%s: Panel power on failed\n", __func__);
3203 return rc;
3204 }
3205 if (ctrl_pdata->bklt_ctrl == BL_PWM)
3206 mdss_dsi_panel_pwm_enable(ctrl_pdata);
3207 ctrl_pdata->ctrl_state |= (CTRL_STATE_PANEL_INIT |
3208 CTRL_STATE_MDP_ACTIVE | CTRL_STATE_DSI_ACTIVE);
3209
3210 /*
3211 * MDP client removes this extra vote during splash reconfigure
3212 * for command mode panel from interface. DSI removes the vote
3213 * during suspend-resume for video mode panel.
3214 */
3215 if (ctrl_pdata->panel_data.panel_info.type == MIPI_CMD_PANEL)
3216 clk_handle = ctrl_pdata->mdp_clk_handle;
3217 else
3218 clk_handle = ctrl_pdata->dsi_clk_handle;
3219
3220 mdss_dsi_clk_ctrl(ctrl_pdata, clk_handle,
3221 MDSS_DSI_ALL_CLKS, MDSS_DSI_CLK_ON);
3222 mdss_dsi_read_hw_revision(ctrl_pdata);
3223 mdss_dsi_read_phy_revision(ctrl_pdata);
3224 ctrl_pdata->is_phyreg_enabled = 1;
3225 if (pinfo->type == MIPI_CMD_PANEL)
3226 mdss_dsi_set_burst_mode(ctrl_pdata);
3227 } else {
3228 /* Turn on the clocks to read the DSI and PHY revision */
3229 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
3230 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_ON);
3231 mdss_dsi_read_hw_revision(ctrl_pdata);
3232 mdss_dsi_read_phy_revision(ctrl_pdata);
3233 mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle,
3234 MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_OFF);
3235 pinfo->panel_power_state = MDSS_PANEL_POWER_OFF;
3236 }
3237
3238 return rc;
3239}
3240
3241static int mdss_dsi_get_bridge_chip_params(struct mdss_panel_info *pinfo,
3242 struct mdss_dsi_ctrl_pdata *ctrl_pdata,
3243 struct platform_device *pdev)
3244{
3245 int rc = 0;
3246 u32 temp_val = 0;
3247
3248 if (!ctrl_pdata || !pdev || !pinfo) {
3249 pr_err("%s: Invalid Params ctrl_pdata=%pK, pdev=%pK\n",
3250 __func__, ctrl_pdata, pdev);
3251 rc = -EINVAL;
3252 goto end;
3253 }
3254
3255 if (pinfo->is_dba_panel) {
3256 rc = of_property_read_u32(pdev->dev.of_node,
3257 "qcom,bridge-index", &temp_val);
3258 if (rc) {
3259 pr_err("%s:%d Unable to read qcom,bridge-index, ret=%d\n",
3260 __func__, __LINE__, rc);
3261 goto end;
3262 }
3263 pr_debug("%s: DT property %s is %X\n", __func__,
3264 "qcom,bridge-index", temp_val);
3265 ctrl_pdata->bridge_index = temp_val;
3266 }
3267end:
3268 return rc;
3269}
3270
3271static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
3272{
3273 int rc = 0;
3274 u32 index;
3275 struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
3276 struct mdss_panel_info *pinfo = NULL;
3277 struct device_node *dsi_pan_node = NULL;
3278 const char *ctrl_name;
3279 struct mdss_util_intf *util;
3280 static int te_irq_registered;
3281 struct mdss_panel_data *pdata;
Arun kumardb962812018-05-30 16:31:52 +05303282 struct mdss_panel_cfg *pan_cfg = NULL;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303283
3284 if (!pdev || !pdev->dev.of_node) {
3285 pr_err("%s: pdev not found for DSI controller\n", __func__);
3286 return -ENODEV;
3287 }
3288 rc = of_property_read_u32(pdev->dev.of_node,
3289 "cell-index", &index);
3290 if (rc) {
3291 dev_err(&pdev->dev, "%s: Cell-index not specified, rc=%d\n",
3292 __func__, rc);
3293 return rc;
3294 }
3295
3296 if (index == 0)
3297 pdev->id = 1;
3298 else
3299 pdev->id = 2;
3300
3301 ctrl_pdata = mdss_dsi_get_ctrl(index);
3302 if (!ctrl_pdata) {
3303 pr_err("%s: Unable to get the ctrl_pdata\n", __func__);
3304 return -EINVAL;
3305 }
3306
3307 platform_set_drvdata(pdev, ctrl_pdata);
3308
3309 util = mdss_get_util_intf();
3310 if (util == NULL) {
3311 pr_err("Failed to get mdss utility functions\n");
3312 return -ENODEV;
3313 }
3314
Arun kumardb962812018-05-30 16:31:52 +05303315 pan_cfg = util->panel_intf_type(MDSS_PANEL_INTF_SPI);
3316 if (IS_ERR(pan_cfg)) {
3317 return PTR_ERR(pan_cfg);
3318 } else if (pan_cfg) {
3319 pr_debug("%s: SPI is primary\n", __func__);
3320 return -ENODEV;
3321 }
3322
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303323 ctrl_pdata->mdss_util = util;
3324 atomic_set(&ctrl_pdata->te_irq_ready, 0);
3325
3326 ctrl_name = of_get_property(pdev->dev.of_node, "label", NULL);
3327 if (!ctrl_name)
3328 pr_info("%s:%d, DSI Ctrl name not specified\n",
3329 __func__, __LINE__);
3330 else
3331 pr_info("%s: DSI Ctrl name = %s\n",
3332 __func__, ctrl_name);
3333
3334 rc = mdss_dsi_pinctrl_init(pdev);
3335 if (rc)
3336 pr_warn("%s: failed to get pin resources\n", __func__);
3337
3338 if (index == 0) {
3339 ctrl_pdata->panel_data.panel_info.pdest = DISPLAY_1;
3340 ctrl_pdata->ndx = DSI_CTRL_0;
3341 } else {
3342 ctrl_pdata->panel_data.panel_info.pdest = DISPLAY_2;
3343 ctrl_pdata->ndx = DSI_CTRL_1;
3344 }
3345
3346 if (mdss_dsi_ctrl_clock_init(pdev, ctrl_pdata)) {
3347 pr_err("%s: unable to initialize dsi clk manager\n", __func__);
3348 return -EPERM;
3349 }
3350
3351 dsi_pan_node = mdss_dsi_config_panel(pdev, index);
3352 if (!dsi_pan_node) {
3353 pr_err("%s: panel configuration failed\n", __func__);
3354 return -EINVAL;
3355 }
3356
3357 if (!mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) ||
3358 (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
3359 (ctrl_pdata->panel_data.panel_info.pdest == DISPLAY_1))) {
3360 rc = mdss_panel_parse_bl_settings(dsi_pan_node, ctrl_pdata);
3361 if (rc) {
3362 pr_warn("%s: dsi bl settings parse failed\n", __func__);
3363 /* Panels like AMOLED and dsi2hdmi chip
3364 * does not need backlight control.
3365 * So we should not fail probe here.
3366 */
3367 ctrl_pdata->bklt_ctrl = UNKNOWN_CTRL;
3368 }
3369 } else {
3370 ctrl_pdata->bklt_ctrl = UNKNOWN_CTRL;
3371 }
3372
3373 rc = dsi_panel_device_register(pdev, dsi_pan_node, ctrl_pdata);
3374 if (rc) {
3375 pr_err("%s: dsi panel dev reg failed\n", __func__);
3376 goto error_pan_node;
3377 }
3378
3379 pinfo = &(ctrl_pdata->panel_data.panel_info);
3380 if (!(mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
3381 mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) &&
3382 pinfo->dynamic_fps) {
3383 rc = mdss_dsi_shadow_clk_init(pdev, ctrl_pdata);
3384
3385 if (rc) {
3386 pr_err("%s: unable to initialize shadow ctrl clks\n",
3387 __func__);
3388 rc = -EPERM;
3389 }
3390 }
3391
3392 rc = mdss_dsi_set_clk_rates(ctrl_pdata);
3393 if (rc) {
3394 pr_err("%s: Failed to set dsi clk rates\n", __func__);
3395 return rc;
3396 }
3397
3398 rc = mdss_dsi_cont_splash_config(pinfo, ctrl_pdata);
3399 if (rc) {
3400 pr_err("%s: Failed to set dsi splash config\n", __func__);
3401 return rc;
3402 }
3403
3404 if (mdss_dsi_is_te_based_esd(ctrl_pdata)) {
3405 init_completion(&ctrl_pdata->te_irq_comp);
3406 rc = devm_request_irq(&pdev->dev,
3407 gpio_to_irq(ctrl_pdata->disp_te_gpio),
3408 hw_vsync_handler, IRQF_TRIGGER_FALLING,
3409 "VSYNC_GPIO", ctrl_pdata);
3410 if (rc) {
3411 pr_err("%s: TE request_irq failed for ESD\n", __func__);
3412 goto error_shadow_clk_deinit;
3413 }
3414 te_irq_registered = 1;
3415 disable_irq(gpio_to_irq(ctrl_pdata->disp_te_gpio));
3416 }
3417
3418 pdata = &ctrl_pdata->panel_data;
3419 init_completion(&pdata->te_done);
3420 if (pdata->panel_info.type == MIPI_CMD_PANEL) {
3421 if (!te_irq_registered) {
3422 rc = devm_request_irq(&pdev->dev,
3423 gpio_to_irq(pdata->panel_te_gpio),
3424 test_hw_vsync_handler, IRQF_TRIGGER_FALLING,
3425 "VSYNC_GPIO", &ctrl_pdata->panel_data);
3426 if (rc) {
3427 pr_err("%s: TE request_irq failed\n", __func__);
3428 goto error_shadow_clk_deinit;
3429 }
3430 te_irq_registered = 1;
3431 disable_irq_nosync(gpio_to_irq(pdata->panel_te_gpio));
3432 }
3433 }
3434
3435 rc = mdss_dsi_get_bridge_chip_params(pinfo, ctrl_pdata, pdev);
3436 if (rc) {
3437 pr_err("%s: Failed to get bridge params\n", __func__);
3438 goto error_shadow_clk_deinit;
3439 }
3440
3441 ctrl_pdata->workq = create_workqueue("mdss_dsi_dba");
3442 if (!ctrl_pdata->workq) {
3443 pr_err("%s: Error creating workqueue\n", __func__);
3444 rc = -EPERM;
3445 goto error_pan_node;
3446 }
3447
3448 INIT_DELAYED_WORK(&ctrl_pdata->dba_work, mdss_dsi_dba_work);
3449
3450 pr_info("%s: Dsi Ctrl->%d initialized, DSI rev:0x%x, PHY rev:0x%x\n",
3451 __func__, index, ctrl_pdata->shared_data->hw_rev,
3452 ctrl_pdata->shared_data->phy_rev);
3453 mdss_dsi_pm_qos_add_request(ctrl_pdata);
3454
3455 if (index == 0)
3456 ctrl_pdata->shared_data->dsi0_active = true;
3457 else
3458 ctrl_pdata->shared_data->dsi1_active = true;
3459
Sandeep Panda812f5002017-02-24 11:36:59 +05303460 mdss_dsi_debug_bus_init(mdss_dsi_res);
3461
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303462 return 0;
3463
3464error_shadow_clk_deinit:
3465 mdss_dsi_shadow_clk_deinit(&pdev->dev, ctrl_pdata);
3466error_pan_node:
3467 mdss_dsi_unregister_bl_settings(ctrl_pdata);
3468 of_node_put(dsi_pan_node);
3469 return rc;
3470}
3471
3472static int mdss_dsi_bus_scale_init(struct platform_device *pdev,
3473 struct dsi_shared_data *sdata)
3474{
3475 int rc = 0;
3476
3477 sdata->bus_scale_table = msm_bus_cl_get_pdata(pdev);
3478 if (IS_ERR_OR_NULL(sdata->bus_scale_table)) {
3479 rc = PTR_ERR(sdata->bus_scale_table);
3480 pr_err("%s: msm_bus_cl_get_pdata() failed, rc=%d\n", __func__,
3481 rc);
3482 return rc;
3483 sdata->bus_scale_table = NULL;
3484 }
3485
3486 sdata->bus_handle =
3487 msm_bus_scale_register_client(sdata->bus_scale_table);
3488
3489 if (!sdata->bus_handle) {
3490 rc = -EINVAL;
3491 pr_err("%sbus_client register failed\n", __func__);
3492 }
3493
3494 return rc;
3495}
3496
3497static void mdss_dsi_bus_scale_deinit(struct dsi_shared_data *sdata)
3498{
3499 if (sdata->bus_handle) {
3500 if (sdata->bus_refcount)
3501 msm_bus_scale_client_update_request(sdata->bus_handle,
3502 0);
3503
3504 sdata->bus_refcount = 0;
3505 msm_bus_scale_unregister_client(sdata->bus_handle);
3506 sdata->bus_handle = 0;
3507 }
3508}
3509
3510static int mdss_dsi_parse_dt_params(struct platform_device *pdev,
3511 struct dsi_shared_data *sdata)
3512{
3513 int rc = 0;
3514
3515 rc = of_property_read_u32(pdev->dev.of_node,
3516 "qcom,mmss-ulp-clamp-ctrl-offset",
3517 &sdata->ulps_clamp_ctrl_off);
3518 if (!rc) {
3519 rc = of_property_read_u32(pdev->dev.of_node,
3520 "qcom,mmss-phyreset-ctrl-offset",
3521 &sdata->ulps_phyrst_ctrl_off);
3522 }
3523
3524 sdata->cmd_clk_ln_recovery_en =
3525 of_property_read_bool(pdev->dev.of_node,
3526 "qcom,dsi-clk-ln-recovery");
3527
Xipeng Gu28b6d152019-09-11 10:54:17 +08003528 sdata->skip_clamp =
3529 of_property_read_bool(pdev->dev.of_node,
3530 "qcom,mdss-skip-clamp");
3531
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303532 return 0;
3533}
3534
3535#ifdef TARGET_HW_MDSS_HDMI
3536static void mdss_dsi_res_deinit_hdmi(struct platform_device *pdev, int val)
3537{
3538 struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev);
3539
3540 if (dsi_res->ctrl_pdata[val]->ds_registered) {
3541 struct mdss_panel_info *pinfo =
3542 &dsi_res->ctrl_pdata[val]->
3543 panel_data.panel_info;
3544 if (pinfo)
3545 mdss_dba_utils_deinit(pinfo->dba_data);
3546 }
3547}
3548#else
3549static void mdss_dsi_res_deinit_hdmi(struct platform_device *pdev, int val)
3550{
3551 (void)(*pdev);
3552 (void)(val);
3553}
3554#endif
3555
3556static void mdss_dsi_res_deinit(struct platform_device *pdev)
3557{
3558 int i;
3559 struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev);
3560 struct dsi_shared_data *sdata;
3561
3562 if (!dsi_res) {
3563 pr_err("%s: DSI root device drvdata not found\n", __func__);
3564 return;
3565 }
3566
3567 for (i = 0; i < DSI_CTRL_MAX; i++) {
3568 if (dsi_res->ctrl_pdata[i]) {
3569 mdss_dsi_res_deinit_hdmi(pdev, i);
3570 devm_kfree(&pdev->dev, dsi_res->ctrl_pdata[i]);
3571 }
3572 }
3573
3574 sdata = dsi_res->shared_data;
3575 if (!sdata)
3576 goto res_release;
3577
3578 for (i = (DSI_MAX_PM - 1); i >= DSI_CORE_PM; i--) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05303579 if (msm_mdss_config_vreg(&pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303580 sdata->power_data[i].vreg_config,
3581 sdata->power_data[i].num_vreg, 1) < 0)
3582 pr_err("%s: failed to de-init vregs for %s\n",
3583 __func__, __mdss_dsi_pm_name(i));
3584 mdss_dsi_put_dt_vreg_data(&pdev->dev,
3585 &sdata->power_data[i]);
3586 }
3587
3588 mdss_dsi_bus_scale_deinit(sdata);
3589 mdss_dsi_core_clk_deinit(&pdev->dev, sdata);
3590
3591 if (sdata)
3592 devm_kfree(&pdev->dev, sdata);
3593
3594res_release:
3595 if (dsi_res)
3596 devm_kfree(&pdev->dev, dsi_res);
3597
3598}
3599
3600static int mdss_dsi_res_init(struct platform_device *pdev)
3601{
3602 int rc = 0, i;
3603 struct dsi_shared_data *sdata;
3604
3605 mdss_dsi_res = platform_get_drvdata(pdev);
3606 if (!mdss_dsi_res) {
3607 mdss_dsi_res = devm_kzalloc(&pdev->dev,
3608 sizeof(struct mdss_dsi_data),
3609 GFP_KERNEL);
3610 if (!mdss_dsi_res) {
3611 pr_err("%s: FAILED: cannot alloc dsi data\n",
3612 __func__);
3613 rc = -ENOMEM;
3614 goto mem_fail;
3615 }
3616
3617 mdss_dsi_res->shared_data = devm_kzalloc(&pdev->dev,
3618 sizeof(struct dsi_shared_data),
3619 GFP_KERNEL);
3620 pr_debug("%s Allocated shared_data=%pK\n", __func__,
3621 mdss_dsi_res->shared_data);
3622 if (!mdss_dsi_res->shared_data) {
3623 pr_err("%s Unable to alloc mem for shared_data\n",
3624 __func__);
3625 rc = -ENOMEM;
3626 goto mem_fail;
3627 }
3628
3629 sdata = mdss_dsi_res->shared_data;
3630
3631 rc = mdss_dsi_parse_dt_params(pdev, sdata);
3632 if (rc) {
3633 pr_err("%s: failed to parse mdss dsi DT params\n",
3634 __func__);
3635 goto mem_fail;
3636 }
3637
3638 rc = mdss_dsi_core_clk_init(pdev, sdata);
3639 if (rc) {
3640 pr_err("%s: failed to initialize DSI core clocks\n",
3641 __func__);
3642 goto mem_fail;
3643 }
3644
3645 /* Parse the regulator information */
3646 for (i = DSI_CORE_PM; i < DSI_MAX_PM; i++) {
3647 rc = mdss_dsi_get_dt_vreg_data(&pdev->dev,
3648 pdev->dev.of_node, &sdata->power_data[i], i);
3649 if (rc) {
3650 pr_err("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
3651 __func__, __mdss_dsi_pm_name(i), rc);
3652 i--;
3653 for (; i >= DSI_CORE_PM; i--)
3654 mdss_dsi_put_dt_vreg_data(&pdev->dev,
3655 &sdata->power_data[i]);
3656 goto mem_fail;
3657 }
3658 }
3659 rc = mdss_dsi_regulator_init(pdev, sdata);
3660 if (rc) {
3661 pr_err("%s: failed to init regulator, rc=%d\n",
3662 __func__, rc);
3663 goto mem_fail;
3664 }
3665
3666 rc = mdss_dsi_bus_scale_init(pdev, sdata);
3667 if (rc) {
3668 pr_err("%s: failed to init bus scale settings, rc=%d\n",
3669 __func__, rc);
3670 goto mem_fail;
3671 }
3672
3673 mutex_init(&sdata->phy_reg_lock);
3674 mutex_init(&sdata->pm_qos_lock);
3675
3676 for (i = 0; i < DSI_CTRL_MAX; i++) {
3677 mdss_dsi_res->ctrl_pdata[i] = devm_kzalloc(&pdev->dev,
3678 sizeof(struct mdss_dsi_ctrl_pdata),
3679 GFP_KERNEL);
3680 if (!mdss_dsi_res->ctrl_pdata[i]) {
3681 pr_err("%s Unable to alloc mem for ctrl=%d\n",
3682 __func__, i);
3683 rc = -ENOMEM;
3684 goto mem_fail;
3685 }
3686 pr_debug("%s Allocated ctrl_pdata[%d]=%pK\n",
3687 __func__, i, mdss_dsi_res->ctrl_pdata[i]);
3688 mdss_dsi_res->ctrl_pdata[i]->shared_data =
3689 mdss_dsi_res->shared_data;
3690 }
3691
3692 platform_set_drvdata(pdev, mdss_dsi_res);
3693 }
3694
3695 mdss_dsi_res->pdev = pdev;
3696 pr_debug("%s: Setting up mdss_dsi_res=%pK\n", __func__, mdss_dsi_res);
3697
3698 return 0;
3699
3700mem_fail:
3701 mdss_dsi_res_deinit(pdev);
3702 return rc;
3703}
3704
3705static int mdss_dsi_parse_hw_cfg(struct platform_device *pdev, char *pan_cfg)
3706{
3707 const char *data;
3708 struct mdss_dsi_data *dsi_res = platform_get_drvdata(pdev);
3709 struct dsi_shared_data *sdata;
3710 char dsi_cfg[20];
3711 char *cfg_prim = NULL, *cfg_sec = NULL, *ch = NULL;
3712 int i = 0;
3713
3714 if (!dsi_res) {
3715 pr_err("%s: DSI root device drvdata not found\n", __func__);
3716 return -EINVAL;
3717 }
3718
3719 sdata = mdss_dsi_res->shared_data;
3720 if (!sdata) {
3721 pr_err("%s: DSI shared data not found\n", __func__);
3722 return -EINVAL;
3723 }
3724
3725 sdata->hw_config = SINGLE_DSI;
3726
3727 if (pan_cfg)
3728 cfg_prim = strnstr(pan_cfg, "cfg:", strlen(pan_cfg));
3729 if (cfg_prim) {
3730 cfg_prim += 4;
3731
3732 cfg_sec = strnchr(cfg_prim, strlen(cfg_prim), ':');
3733 if (!cfg_sec)
3734 cfg_sec = cfg_prim + strlen(cfg_prim);
3735
3736 for (i = 0; ((cfg_prim + i) < cfg_sec) &&
3737 (*(cfg_prim+i) != '#'); i++)
3738 dsi_cfg[i] = *(cfg_prim + i);
3739
3740 dsi_cfg[i] = '\0';
3741 data = dsi_cfg;
3742 } else {
3743 data = of_get_property(pdev->dev.of_node,
3744 "hw-config", NULL);
3745 }
3746
3747 if (data) {
3748 /*
3749 * To handle the override parameter (#override:sim)
3750 * passed for simulator panels
3751 */
3752 ch = strnstr(data, "#", strlen(data));
3753 ch ? *ch = '\0' : false;
3754
3755 if (!strcmp(data, "dual_dsi"))
3756 sdata->hw_config = DUAL_DSI;
3757 else if (!strcmp(data, "split_dsi"))
3758 sdata->hw_config = SPLIT_DSI;
3759 else if (!strcmp(data, "single_dsi"))
3760 sdata->hw_config = SINGLE_DSI;
3761 else
3762 pr_err("%s: Incorrect string for DSI config:%s. Setting default as SINGLE_DSI\n",
3763 __func__, data);
3764 } else {
3765 pr_err("%s: Error: No DSI HW config found\n",
3766 __func__);
3767 return -EINVAL;
3768 }
3769
3770 pr_debug("%s: DSI h/w configuration is %d\n", __func__,
3771 sdata->hw_config);
3772
3773 return 0;
3774}
3775
3776static void mdss_dsi_parse_pll_src_cfg(struct platform_device *pdev,
3777 char *pan_cfg)
3778{
3779 const char *data;
3780 char *pll_ptr, pll_cfg[10] = {'\0'};
3781 struct dsi_shared_data *sdata = mdss_dsi_res->shared_data;
3782
3783 sdata->pll_src_config = PLL_SRC_DEFAULT;
3784
3785 if (pan_cfg) {
3786 pll_ptr = strnstr(pan_cfg, ":pll0", strlen(pan_cfg));
3787 if (!pll_ptr) {
3788 pll_ptr = strnstr(pan_cfg, ":pll1", strlen(pan_cfg));
3789 if (pll_ptr)
3790 strlcpy(pll_cfg, "PLL1", strlen(pll_cfg));
3791 } else {
3792 strlcpy(pll_cfg, "PLL0", strlen(pll_cfg));
3793 }
3794 }
3795 data = pll_cfg;
3796
3797 if (!data || !strcmp(data, ""))
3798 data = of_get_property(pdev->dev.of_node,
3799 "pll-src-config", NULL);
3800 if (data) {
3801 if (!strcmp(data, "PLL0"))
3802 sdata->pll_src_config = PLL_SRC_0;
3803 else if (!strcmp(data, "PLL1"))
3804 sdata->pll_src_config = PLL_SRC_1;
3805 else
3806 pr_err("%s: invalid pll src config %s\n",
3807 __func__, data);
3808 } else {
3809 pr_debug("%s: PLL src config not specified\n", __func__);
3810 }
3811
3812 pr_debug("%s: pll_src_config = %d", __func__, sdata->pll_src_config);
3813}
3814
3815static int mdss_dsi_validate_pll_src_config(struct dsi_shared_data *sdata)
3816{
3817 int rc = 0;
3818
3819 /*
3820 * DSI PLL1 can only drive DSI PHY1. As such:
3821 * - For split dsi config, only PLL0 is supported
3822 * - For dual dsi config, DSI0-PLL0 and DSI1-PLL1 is the only
3823 * possible configuration
3824 */
3825 if (mdss_dsi_is_hw_config_split(sdata) &&
3826 mdss_dsi_is_pll_src_pll1(sdata)) {
3827 pr_err("%s: unsupported PLL config: using PLL1 for split-dsi\n",
3828 __func__);
3829 rc = -EINVAL;
3830 goto error;
3831 }
3832
3833 if (mdss_dsi_is_hw_config_dual(sdata) &&
3834 !mdss_dsi_is_pll_src_default(sdata)) {
3835 pr_debug("%s: pll src config not applicable for dual-dsi\n",
3836 __func__);
3837 sdata->pll_src_config = PLL_SRC_DEFAULT;
3838 }
3839
3840error:
3841 return rc;
3842}
3843
3844static int mdss_dsi_validate_config(struct platform_device *pdev)
3845{
3846 struct dsi_shared_data *sdata = mdss_dsi_res->shared_data;
3847
3848 return mdss_dsi_validate_pll_src_config(sdata);
3849}
3850
3851static const struct of_device_id mdss_dsi_ctrl_dt_match[] = {
3852 {.compatible = "qcom,mdss-dsi-ctrl"},
3853 {}
3854};
3855MODULE_DEVICE_TABLE(of, mdss_dsi_ctrl_dt_match);
3856
3857static int mdss_dsi_probe(struct platform_device *pdev)
3858{
3859 struct mdss_panel_cfg *pan_cfg = NULL;
3860 struct mdss_util_intf *util;
3861 char *panel_cfg;
3862 int rc = 0;
3863
3864 util = mdss_get_util_intf();
3865 if (util == NULL) {
3866 pr_err("%s: Failed to get mdss utility functions\n", __func__);
3867 return -ENODEV;
3868 }
3869
3870 if (!util->mdp_probe_done) {
3871 pr_err("%s: MDP not probed yet!\n", __func__);
3872 return -EPROBE_DEFER;
3873 }
3874
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303875 if (!pdev || !pdev->dev.of_node) {
3876 pr_err("%s: DSI driver only supports device tree probe\n",
3877 __func__);
3878 return -ENOTSUPP;
3879 }
3880
3881 pan_cfg = util->panel_intf_type(MDSS_PANEL_INTF_HDMI);
3882 if (IS_ERR(pan_cfg)) {
3883 return PTR_ERR(pan_cfg);
3884 } else if (pan_cfg) {
3885 pr_debug("%s: HDMI is primary\n", __func__);
3886 return -ENODEV;
3887 }
3888
3889 pan_cfg = util->panel_intf_type(MDSS_PANEL_INTF_DSI);
3890 if (IS_ERR_OR_NULL(pan_cfg)) {
3891 rc = PTR_ERR(pan_cfg);
3892 goto error;
3893 } else {
3894 panel_cfg = pan_cfg->arg_cfg;
3895 }
3896
3897 rc = mdss_dsi_res_init(pdev);
3898 if (rc) {
3899 pr_err("%s Unable to set dsi res\n", __func__);
3900 return rc;
3901 }
3902
3903 rc = mdss_dsi_parse_hw_cfg(pdev, panel_cfg);
3904 if (rc) {
3905 pr_err("%s Unable to parse dsi h/w config\n", __func__);
3906 mdss_dsi_res_deinit(pdev);
3907 return rc;
3908 }
3909
3910 mdss_dsi_parse_pll_src_cfg(pdev, panel_cfg);
3911
3912 of_platform_populate(pdev->dev.of_node, mdss_dsi_ctrl_dt_match,
3913 NULL, &pdev->dev);
3914
3915 rc = mdss_dsi_validate_config(pdev);
3916 if (rc) {
3917 pr_err("%s: Invalid DSI hw configuration\n", __func__);
3918 goto error;
3919 }
3920
3921 mdss_dsi_config_clk_src(pdev);
3922
3923error:
3924 return rc;
3925}
3926
3927static int mdss_dsi_remove(struct platform_device *pdev)
3928{
3929 mdss_dsi_res_deinit(pdev);
3930 return 0;
3931}
3932
3933static int mdss_dsi_ctrl_remove(struct platform_device *pdev)
3934{
3935 struct msm_fb_data_type *mfd;
3936 struct mdss_dsi_ctrl_pdata *ctrl_pdata = platform_get_drvdata(pdev);
3937
3938 if (!ctrl_pdata) {
3939 pr_err("%s: no driver data\n", __func__);
3940 return -ENODEV;
3941 }
3942
3943 mdss_dsi_pm_qos_remove_request(ctrl_pdata->shared_data);
3944
Sachin Bhayare5076e252018-01-18 14:56:45 +05303945 if (msm_mdss_config_vreg(&pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303946 ctrl_pdata->panel_power_data.vreg_config,
3947 ctrl_pdata->panel_power_data.num_vreg, 1) < 0)
3948 pr_err("%s: failed to de-init vregs for %s\n",
3949 __func__, __mdss_dsi_pm_name(DSI_PANEL_PM));
3950 mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->panel_power_data);
3951
3952 mfd = platform_get_drvdata(pdev);
Sachin Bhayare5076e252018-01-18 14:56:45 +05303953 msm_mdss_iounmap(&ctrl_pdata->mmss_misc_io);
3954 msm_mdss_iounmap(&ctrl_pdata->phy_io);
3955 msm_mdss_iounmap(&ctrl_pdata->ctrl_io);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303956 mdss_dsi_debugfs_cleanup(ctrl_pdata);
3957
3958 if (ctrl_pdata->workq)
3959 destroy_workqueue(ctrl_pdata->workq);
3960
3961 return 0;
3962}
3963
3964struct device dsi_dev;
3965
3966int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode,
3967 struct mdss_dsi_ctrl_pdata *ctrl)
3968{
3969 int rc = 0;
3970 u32 index;
3971
3972 rc = of_property_read_u32(pdev->dev.of_node, "cell-index", &index);
3973 if (rc) {
3974 dev_err(&pdev->dev,
3975 "%s: Cell-index not specified, rc=%d\n",
3976 __func__, rc);
3977 return rc;
3978 }
3979
3980 if (index == 0) {
3981 if (mode != DISPLAY_1) {
3982 pr_err("%s:%d Panel->Ctrl mapping is wrong\n",
3983 __func__, __LINE__);
3984 return -EPERM;
3985 }
3986 } else if (index == 1) {
3987 if (mode != DISPLAY_2) {
3988 pr_err("%s:%d Panel->Ctrl mapping is wrong\n",
3989 __func__, __LINE__);
3990 return -EPERM;
3991 }
3992 } else {
3993 pr_err("%s:%d Unknown Ctrl mapped to panel\n",
3994 __func__, __LINE__);
3995 return -EPERM;
3996 }
3997
Sachin Bhayare5076e252018-01-18 14:56:45 +05303998 rc = msm_mdss_ioremap_byname(pdev, &ctrl->ctrl_io, "dsi_ctrl");
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303999 if (rc) {
4000 pr_err("%s:%d unable to remap dsi ctrl resources\n",
4001 __func__, __LINE__);
4002 return rc;
4003 }
4004
4005 ctrl->ctrl_base = ctrl->ctrl_io.base;
4006 ctrl->reg_size = ctrl->ctrl_io.len;
4007
Sachin Bhayare5076e252018-01-18 14:56:45 +05304008 rc = msm_mdss_ioremap_byname(pdev, &ctrl->phy_io, "dsi_phy");
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304009 if (rc) {
4010 pr_err("%s:%d unable to remap dsi phy resources\n",
4011 __func__, __LINE__);
4012 return rc;
4013 }
4014
Sachin Bhayare5076e252018-01-18 14:56:45 +05304015 rc = msm_mdss_ioremap_byname(pdev, &ctrl->phy_regulator_io,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304016 "dsi_phy_regulator");
4017 if (rc)
4018 pr_debug("%s:%d unable to remap dsi phy regulator resources\n",
4019 __func__, __LINE__);
4020 else
4021 pr_info("%s: phy_regulator_base=%pK phy_regulator_size=%x\n",
4022 __func__, ctrl->phy_regulator_io.base,
4023 ctrl->phy_regulator_io.len);
4024
4025 pr_info("%s: ctrl_base=%pK ctrl_size=%x phy_base=%pK phy_size=%x\n",
4026 __func__, ctrl->ctrl_base, ctrl->reg_size, ctrl->phy_io.base,
4027 ctrl->phy_io.len);
4028
Sachin Bhayare5076e252018-01-18 14:56:45 +05304029 rc = msm_mdss_ioremap_byname(pdev, &ctrl->mmss_misc_io,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304030 "mmss_misc_phys");
4031 if (rc) {
4032 pr_debug("%s:%d mmss_misc IO remap failed\n",
4033 __func__, __LINE__);
4034 }
4035
4036 return 0;
4037}
4038
4039static int mdss_dsi_irq_init(struct device *dev, int irq_no,
4040 struct mdss_dsi_ctrl_pdata *ctrl)
4041{
4042 int ret;
4043
4044 ret = devm_request_irq(dev, irq_no, mdss_dsi_isr,
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05304045 0, "DSI", ctrl);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304046 if (ret) {
4047 pr_err("msm_dsi_irq_init request_irq() failed!\n");
4048 return ret;
4049 }
4050
4051 disable_irq(irq_no);
4052 ctrl->dsi_hw->irq_info = kcalloc(1, sizeof(struct irq_info),
4053 GFP_KERNEL);
4054 if (!ctrl->dsi_hw->irq_info)
4055 return -ENOMEM;
4056
4057 ctrl->dsi_hw->irq_info->irq = irq_no;
4058 ctrl->dsi_hw->irq_info->irq_ena = false;
4059
4060 return ret;
4061}
4062
4063static void mdss_dsi_parse_lane_swap(struct device_node *np, char *dlane_swap)
4064{
4065 const char *data;
4066
4067 *dlane_swap = DSI_LANE_MAP_0123;
4068 data = of_get_property(np, "qcom,lane-map", NULL);
4069 if (data) {
4070 if (!strcmp(data, "lane_map_3012"))
4071 *dlane_swap = DSI_LANE_MAP_3012;
4072 else if (!strcmp(data, "lane_map_2301"))
4073 *dlane_swap = DSI_LANE_MAP_2301;
4074 else if (!strcmp(data, "lane_map_1230"))
4075 *dlane_swap = DSI_LANE_MAP_1230;
4076 else if (!strcmp(data, "lane_map_0321"))
4077 *dlane_swap = DSI_LANE_MAP_0321;
4078 else if (!strcmp(data, "lane_map_1032"))
4079 *dlane_swap = DSI_LANE_MAP_1032;
4080 else if (!strcmp(data, "lane_map_2103"))
4081 *dlane_swap = DSI_LANE_MAP_2103;
4082 else if (!strcmp(data, "lane_map_3210"))
4083 *dlane_swap = DSI_LANE_MAP_3210;
4084 }
4085}
4086
4087static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
4088 struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata)
4089{
4090 int i, len;
4091 struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
4092 const char *data;
4093
4094 ctrl_pdata->null_insert_enabled = of_property_read_bool(
4095 ctrl_pdev->dev.of_node, "qcom,null-insertion-enabled");
4096
4097 data = of_get_property(ctrl_pdev->dev.of_node,
4098 "qcom,platform-strength-ctrl", &len);
4099 if (!data) {
4100 pr_err("%s:%d, Unable to read Phy Strength ctrl settings\n",
4101 __func__, __LINE__);
Padmanabhan Komanduru81d8dc522018-03-22 20:00:58 +05304102 } else {
4103 pinfo->mipi.dsi_phy_db.strength_len = len;
4104 for (i = 0; i < len; i++)
4105 pinfo->mipi.dsi_phy_db.strength[i] = data[i];
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304106 }
4107
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304108 pinfo->mipi.dsi_phy_db.reg_ldo_mode = of_property_read_bool(
4109 ctrl_pdev->dev.of_node, "qcom,regulator-ldo-mode");
4110
4111 data = of_get_property(ctrl_pdev->dev.of_node,
4112 "qcom,platform-regulator-settings", &len);
4113 if (!data) {
4114 pr_err("%s:%d, Unable to read Phy regulator settings\n",
4115 __func__, __LINE__);
Padmanabhan Komanduru81d8dc522018-03-22 20:00:58 +05304116 } else {
4117 pinfo->mipi.dsi_phy_db.regulator_len = len;
4118 for (i = 0; i < len; i++)
4119 pinfo->mipi.dsi_phy_db.regulator[i] = data[i];
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304120 }
4121
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304122 data = of_get_property(ctrl_pdev->dev.of_node,
4123 "qcom,platform-bist-ctrl", &len);
4124 if ((!data) || (len != 6))
4125 pr_debug("%s:%d, Unable to read Phy Bist Ctrl settings\n",
4126 __func__, __LINE__);
4127 else
4128 for (i = 0; i < len; i++)
4129 pinfo->mipi.dsi_phy_db.bistctrl[i] = data[i];
4130
4131 data = of_get_property(ctrl_pdev->dev.of_node,
4132 "qcom,platform-lane-config", &len);
4133 if (!data) {
4134 pr_err("%s:%d, Unable to read Phy lane configure settings\n",
4135 __func__, __LINE__);
Padmanabhan Komanduru81d8dc522018-03-22 20:00:58 +05304136 } else {
4137 pinfo->mipi.dsi_phy_db.lanecfg_len = len;
4138 for (i = 0; i < len; i++)
4139 pinfo->mipi.dsi_phy_db.lanecfg[i] = data[i];
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304140 }
4141
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304142 ctrl_pdata->timing_db_mode = of_property_read_bool(
4143 ctrl_pdev->dev.of_node, "qcom,timing-db-mode");
4144
4145 ctrl_pdata->cmd_sync_wait_broadcast = of_property_read_bool(
4146 pan_node, "qcom,cmd-sync-wait-broadcast");
4147
4148 if (ctrl_pdata->cmd_sync_wait_broadcast &&
4149 mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
4150 (pinfo->pdest == DISPLAY_2))
4151 ctrl_pdata->cmd_sync_wait_trigger = true;
4152
4153 pr_debug("%s: cmd_sync_wait_enable=%d trigger=%d\n", __func__,
4154 ctrl_pdata->cmd_sync_wait_broadcast,
4155 ctrl_pdata->cmd_sync_wait_trigger);
4156
4157 mdss_dsi_parse_lane_swap(ctrl_pdev->dev.of_node,
4158 &(ctrl_pdata->dlane_swap));
4159
4160 pinfo->is_pluggable = of_property_read_bool(ctrl_pdev->dev.of_node,
4161 "qcom,pluggable");
4162
4163 data = of_get_property(ctrl_pdev->dev.of_node,
4164 "qcom,display-id", &len);
4165 if (!data || len <= 0)
4166 pr_err("%s:%d Unable to read qcom,display-id, data=%pK,len=%d\n",
4167 __func__, __LINE__, data, len);
4168 else
4169 snprintf(ctrl_pdata->panel_data.panel_info.display_id,
4170 MDSS_DISPLAY_ID_MAX_LEN, "%s", data);
4171
4172 return 0;
4173
4174
4175}
4176
4177static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev,
4178 struct mdss_dsi_ctrl_pdata *ctrl_pdata)
4179{
4180 struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
4181 struct mdss_panel_data *pdata = &ctrl_pdata->panel_data;
4182
4183 /*
4184 * If disp_en_gpio has been set previously (disp_en_gpio > 0)
4185 * while parsing the panel node, then do not override it
4186 */
4187 if (ctrl_pdata->disp_en_gpio <= 0) {
4188 ctrl_pdata->disp_en_gpio = of_get_named_gpio(
4189 ctrl_pdev->dev.of_node,
4190 "qcom,platform-enable-gpio", 0);
4191
4192 if (!gpio_is_valid(ctrl_pdata->disp_en_gpio))
4193 pr_debug("%s:%d, Disp_en gpio not specified\n",
4194 __func__, __LINE__);
Arun kumarec570b72018-05-09 20:23:38 +05304195 pdata->panel_en_gpio = ctrl_pdata->disp_en_gpio;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304196 }
4197
4198 ctrl_pdata->disp_te_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
4199 "qcom,platform-te-gpio", 0);
4200
4201 if (!gpio_is_valid(ctrl_pdata->disp_te_gpio))
4202 pr_err("%s:%d, TE gpio not specified\n",
4203 __func__, __LINE__);
4204 pdata->panel_te_gpio = ctrl_pdata->disp_te_gpio;
4205
4206 ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
4207 "qcom,platform-bklight-en-gpio", 0);
4208 if (!gpio_is_valid(ctrl_pdata->bklt_en_gpio))
4209 pr_info("%s: bklt_en gpio not specified\n", __func__);
4210
Yahui Wang12a6d372016-12-12 22:43:20 +08004211 ctrl_pdata->bklt_en_gpio_invert =
4212 of_property_read_bool(ctrl_pdev->dev.of_node,
4213 "qcom,platform-bklight-en-gpio-invert");
4214
Narender Ankam4fcd6892018-06-11 13:09:00 +05304215 ctrl_pdata->vdd_ext_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
4216 "qcom,ext-vdd-gpio", 0);
4217 if (!gpio_is_valid(ctrl_pdata->vdd_ext_gpio))
4218 pr_info("%s: ext vdd gpio not specified\n", __func__);
4219
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304220 ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
4221 "qcom,platform-reset-gpio", 0);
4222 if (!gpio_is_valid(ctrl_pdata->rst_gpio))
4223 pr_err("%s:%d, reset gpio not specified\n",
4224 __func__, __LINE__);
4225
4226 if (pinfo->mode_gpio_state != MODE_GPIO_NOT_VALID) {
4227
4228 ctrl_pdata->mode_gpio = of_get_named_gpio(
4229 ctrl_pdev->dev.of_node,
4230 "qcom,platform-mode-gpio", 0);
4231 if (!gpio_is_valid(ctrl_pdata->mode_gpio))
4232 pr_info("%s:%d, mode gpio not specified\n",
4233 __func__, __LINE__);
4234 } else {
4235 ctrl_pdata->mode_gpio = -EINVAL;
4236 }
4237
4238 ctrl_pdata->intf_mux_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node,
4239 "qcom,platform-intf-mux-gpio", 0);
4240 if (!gpio_is_valid(ctrl_pdata->intf_mux_gpio))
4241 pr_debug("%s:%d, intf mux gpio not specified\n",
4242 __func__, __LINE__);
4243
4244 return 0;
4245}
4246
4247static void mdss_dsi_set_prim_panel(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
4248{
4249 struct mdss_dsi_ctrl_pdata *octrl = NULL;
4250 struct mdss_panel_info *pinfo;
4251
4252 pinfo = &ctrl_pdata->panel_data.panel_info;
4253
4254 /*
4255 * for Split and Single DSI case default is always primary
4256 * and for Dual dsi case below assumptions are made.
4257 * 1. DSI controller with bridge chip is always secondary
4258 * 2. When there is no brigde chip, DSI1 is secondary
4259 */
4260 pinfo->is_prim_panel = true;
4261 if (mdss_dsi_is_hw_config_dual(ctrl_pdata->shared_data)) {
4262 if (mdss_dsi_is_right_ctrl(ctrl_pdata)) {
4263 octrl = mdss_dsi_get_other_ctrl(ctrl_pdata);
4264 if (octrl && octrl->panel_data.panel_info.is_prim_panel)
4265 pinfo->is_prim_panel = false;
4266 else
4267 pinfo->is_prim_panel = true;
4268 }
4269 }
4270}
4271
4272int dsi_panel_device_register(struct platform_device *ctrl_pdev,
4273 struct device_node *pan_node, struct mdss_dsi_ctrl_pdata *ctrl_pdata)
4274{
4275 struct mipi_panel_info *mipi;
4276 int rc;
4277 struct dsi_shared_data *sdata;
4278 struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
4279 struct resource *res;
4280 u64 clk_rate;
4281
4282 mipi = &(pinfo->mipi);
4283
4284 pinfo->type =
4285 ((mipi->mode == DSI_VIDEO_MODE)
4286 ? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL);
4287
4288 rc = mdss_dsi_clk_div_config(pinfo, mipi->frame_rate);
4289 if (rc) {
4290 pr_err("%s: unable to initialize the clk dividers\n", __func__);
4291 return rc;
4292 }
4293 ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate;
4294 clk_rate = pinfo->clk_rate;
4295 do_div(clk_rate, 8U);
4296 ctrl_pdata->byte_clk_rate = (u32)clk_rate;
4297 pr_debug("%s: pclk=%d, bclk=%d\n", __func__,
4298 ctrl_pdata->pclk_rate, ctrl_pdata->byte_clk_rate);
4299
4300
4301 rc = mdss_dsi_get_dt_vreg_data(&ctrl_pdev->dev, pan_node,
4302 &ctrl_pdata->panel_power_data, DSI_PANEL_PM);
4303 if (rc) {
4304 DEV_ERR("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
4305 __func__, __mdss_dsi_pm_name(DSI_PANEL_PM), rc);
4306 return rc;
4307 }
4308
Sachin Bhayare5076e252018-01-18 14:56:45 +05304309 rc = msm_mdss_config_vreg(&ctrl_pdev->dev,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304310 ctrl_pdata->panel_power_data.vreg_config,
4311 ctrl_pdata->panel_power_data.num_vreg, 1);
4312 if (rc) {
4313 pr_err("%s: failed to init regulator, rc=%d\n",
4314 __func__, rc);
4315 return rc;
4316 }
4317
4318 rc = mdss_dsi_parse_ctrl_params(ctrl_pdev, pan_node, ctrl_pdata);
4319 if (rc) {
4320 pr_err("%s: failed to parse ctrl settings, rc=%d\n",
4321 __func__, rc);
4322 return rc;
4323 }
4324
4325 pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo,
4326 FPS_RESOLUTION_HZ);
4327 pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo);
4328
4329 rc = mdss_dsi_parse_gpio_params(ctrl_pdev, ctrl_pdata);
4330 if (rc) {
4331 pr_err("%s: failed to parse gpio params, rc=%d\n",
4332 __func__, rc);
4333 return rc;
4334 }
4335
4336 if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev,
4337 pinfo->pdest,
4338 ctrl_pdata)) {
4339 pr_err("%s: unable to get Dsi controller res\n", __func__);
4340 return -EPERM;
4341 }
4342
4343 ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler;
4344 ctrl_pdata->panel_data.get_fb_node = mdss_dsi_get_fb_node_cb;
4345
4346 if (ctrl_pdata->status_mode == ESD_REG ||
4347 ctrl_pdata->status_mode == ESD_REG_NT35596)
4348 ctrl_pdata->check_status = mdss_dsi_reg_status_check;
4349 else if (ctrl_pdata->status_mode == ESD_BTA)
4350 ctrl_pdata->check_status = mdss_dsi_bta_status_check;
4351
4352 if (ctrl_pdata->status_mode == ESD_MAX) {
4353 pr_err("%s: Using default BTA for ESD check\n", __func__);
4354 ctrl_pdata->check_status = mdss_dsi_bta_status_check;
4355 }
4356 if (ctrl_pdata->bklt_ctrl == BL_PWM)
4357 mdss_dsi_panel_pwm_cfg(ctrl_pdata);
4358
4359 mdss_dsi_ctrl_init(&ctrl_pdev->dev, ctrl_pdata);
4360 mdss_dsi_set_prim_panel(ctrl_pdata);
4361
4362 ctrl_pdata->dsi_irq_line = of_property_read_bool(
4363 ctrl_pdev->dev.of_node, "qcom,dsi-irq-line");
4364
4365 if (ctrl_pdata->dsi_irq_line) {
4366 /* DSI has it's own irq line */
4367 res = platform_get_resource(ctrl_pdev, IORESOURCE_IRQ, 0);
4368 if (!res || res->start == 0) {
4369 pr_err("%s:%d unable to get the MDSS irq resources\n",
4370 __func__, __LINE__);
4371 return -ENODEV;
4372 }
4373 rc = mdss_dsi_irq_init(&ctrl_pdev->dev, res->start, ctrl_pdata);
4374 if (rc) {
4375 dev_err(&ctrl_pdev->dev, "%s: failed to init irq\n",
4376 __func__);
4377 return rc;
4378 }
4379 }
4380 ctrl_pdata->ctrl_state = CTRL_STATE_UNKNOWN;
4381
4382 /*
4383 * If ULPS during suspend is enabled, add an extra vote for the
4384 * DSI CTRL power module. This keeps the regulator always enabled.
4385 * This is needed for the DSI PHY to maintain ULPS state during
4386 * suspend also.
4387 */
4388 sdata = ctrl_pdata->shared_data;
4389
4390 if (pinfo->ulps_suspend_enabled) {
Sachin Bhayare5076e252018-01-18 14:56:45 +05304391 rc = msm_mdss_enable_vreg(
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304392 sdata->power_data[DSI_PHY_PM].vreg_config,
4393 sdata->power_data[DSI_PHY_PM].num_vreg, 1);
4394 if (rc) {
4395 pr_err("%s: failed to enable vregs for DSI_CTRL_PM\n",
4396 __func__);
4397 return rc;
4398 }
4399 }
4400
4401 pinfo->cont_splash_enabled =
4402 ctrl_pdata->mdss_util->panel_intf_status(pinfo->pdest,
4403 MDSS_PANEL_INTF_DSI) ? true : false;
4404
4405 pr_info("%s: Continuous splash %s\n", __func__,
4406 pinfo->cont_splash_enabled ? "enabled" : "disabled");
4407
4408 rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data));
4409 if (rc) {
4410 pr_err("%s: unable to register MIPI DSI panel\n", __func__);
4411 return rc;
4412 }
4413
4414 if (pinfo->pdest == DISPLAY_1) {
4415 mdss_debug_register_io("dsi0_ctrl", &ctrl_pdata->ctrl_io, NULL);
4416 mdss_debug_register_io("dsi0_phy", &ctrl_pdata->phy_io, NULL);
4417 if (ctrl_pdata->phy_regulator_io.len)
4418 mdss_debug_register_io("dsi0_phy_regulator",
4419 &ctrl_pdata->phy_regulator_io, NULL);
4420 } else {
4421 mdss_debug_register_io("dsi1_ctrl", &ctrl_pdata->ctrl_io, NULL);
4422 mdss_debug_register_io("dsi1_phy", &ctrl_pdata->phy_io, NULL);
4423 if (ctrl_pdata->phy_regulator_io.len)
4424 mdss_debug_register_io("dsi1_phy_regulator",
4425 &ctrl_pdata->phy_regulator_io, NULL);
4426 }
4427
4428 panel_debug_register_base("panel",
4429 ctrl_pdata->ctrl_base, ctrl_pdata->reg_size);
4430
4431 pr_debug("%s: Panel data initialized\n", __func__);
4432 return 0;
4433}
4434
4435static const struct of_device_id mdss_dsi_dt_match[] = {
4436 {.compatible = "qcom,mdss-dsi"},
4437 {}
4438};
4439MODULE_DEVICE_TABLE(of, mdss_dsi_dt_match);
4440
4441static struct platform_driver mdss_dsi_driver = {
4442 .probe = mdss_dsi_probe,
4443 .remove = mdss_dsi_remove,
4444 .shutdown = NULL,
4445 .driver = {
4446 .name = "mdss_dsi",
4447 .of_match_table = mdss_dsi_dt_match,
4448 },
4449};
4450
4451static struct platform_driver mdss_dsi_ctrl_driver = {
4452 .probe = mdss_dsi_ctrl_probe,
4453 .remove = mdss_dsi_ctrl_remove,
4454 .shutdown = NULL,
4455 .driver = {
4456 .name = "mdss_dsi_ctrl",
4457 .of_match_table = mdss_dsi_ctrl_dt_match,
4458 },
4459};
4460
4461static int mdss_dsi_register_driver(void)
4462{
4463 return platform_driver_register(&mdss_dsi_driver);
4464}
4465
4466static int __init mdss_dsi_driver_init(void)
4467{
4468 int ret;
4469
4470 ret = mdss_dsi_register_driver();
4471 if (ret) {
4472 pr_err("mdss_dsi_register_driver() failed!\n");
4473 return ret;
4474 }
4475
4476 return ret;
4477}
4478module_init(mdss_dsi_driver_init);
4479
4480
4481static int mdss_dsi_ctrl_register_driver(void)
4482{
4483 return platform_driver_register(&mdss_dsi_ctrl_driver);
4484}
4485
4486static int __init mdss_dsi_ctrl_driver_init(void)
4487{
4488 int ret;
4489
4490 ret = mdss_dsi_ctrl_register_driver();
4491 if (ret) {
4492 pr_err("mdss_dsi_ctrl_register_driver() failed!\n");
4493 return ret;
4494 }
4495
4496 return ret;
4497}
4498module_init(mdss_dsi_ctrl_driver_init);
4499
4500static void __exit mdss_dsi_driver_cleanup(void)
4501{
4502 platform_driver_unregister(&mdss_dsi_ctrl_driver);
4503}
4504module_exit(mdss_dsi_driver_cleanup);
4505
4506MODULE_LICENSE("GPL v2");
4507MODULE_DESCRIPTION("DSI controller driver");