blob: 28441b6bcfb2665ae0d800b13814d25020ea70bd [file] [log] [blame]
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301/* Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved.
2 *
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#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include <linux/regulator/consumer.h>
19#include <linux/clk/msm-clk.h>
20
21
22#include "dsi_v2.h"
23#include "dsi_io_v2.h"
24#include "dsi_host_v2.h"
25
26struct msm_dsi_io_private {
27 struct clk *dsi_byte_clk;
28 struct clk *dsi_esc_clk;
29 struct clk *dsi_pixel_clk;
30 struct clk *dsi_ahb_clk;
31 struct clk *dsi_clk;
32 int msm_dsi_clk_on;
33 int msm_dsi_ahb_clk_on;
34};
35
36static struct msm_dsi_io_private *dsi_io_private;
37
38#define DSI_VDDA_VOLTAGE 1200000
39
40void msm_dsi_ahb_ctrl(int enable)
41{
42 if (enable) {
43 dsi_io_private->msm_dsi_ahb_clk_on++;
44 if (dsi_io_private->msm_dsi_ahb_clk_on == 1)
45 clk_enable(dsi_io_private->dsi_ahb_clk);
46 } else {
47 dsi_io_private->msm_dsi_ahb_clk_on--;
48 if (dsi_io_private->msm_dsi_ahb_clk_on == 0)
49 clk_disable(dsi_io_private->dsi_ahb_clk);
50 }
51}
52
Sachin Bhayare5076e252018-01-18 14:56:45 +053053int msm_dsi_io_init(struct platform_device *pdev, struct mdss_module_power *mp)
Sachin Bhayareeeb88892018-01-02 16:36:01 +053054{
55 int rc;
56
57 if (!dsi_io_private) {
58 dsi_io_private = kzalloc(sizeof(struct msm_dsi_io_private),
59 GFP_KERNEL);
60 if (!dsi_io_private)
61 return -ENOMEM;
62 }
63
64 rc = msm_dsi_clk_init(pdev);
65 if (rc) {
66 pr_err("fail to initialize DSI clock\n");
67 return rc;
68 }
69
Sachin Bhayare5076e252018-01-18 14:56:45 +053070 rc = msm_mdss_config_vreg(&pdev->dev, mp->vreg_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +053071 mp->num_vreg, 1);
72 if (rc) {
73 pr_err("fail to initialize DSI regulator\n");
74 return rc;
75 }
76
77 return 0;
78}
79
80void msm_dsi_io_deinit(struct platform_device *pdev,
Sachin Bhayare5076e252018-01-18 14:56:45 +053081 struct mdss_module_power *mp)
Sachin Bhayareeeb88892018-01-02 16:36:01 +053082{
83 if (dsi_io_private) {
84 msm_dsi_clk_deinit();
Sachin Bhayare5076e252018-01-18 14:56:45 +053085 msm_mdss_config_vreg(&pdev->dev, mp->vreg_config,
Sachin Bhayareeeb88892018-01-02 16:36:01 +053086 mp->num_vreg, 0);
87 kfree(dsi_io_private);
88 dsi_io_private = NULL;
89 }
90}
91
92int msm_dsi_clk_init(struct platform_device *dev)
93{
94 int rc = 0;
95
96 dsi_io_private->dsi_clk = clk_get(&dev->dev, "dsi_clk");
97 if (IS_ERR(dsi_io_private->dsi_clk)) {
98 pr_err("can't find dsi core_clk\n");
99 rc = PTR_ERR(dsi_io_private->dsi_clk);
100 dsi_io_private->dsi_clk = NULL;
101 return rc;
102 }
103 dsi_io_private->dsi_byte_clk = clk_get(&dev->dev, "byte_clk");
104 if (IS_ERR(dsi_io_private->dsi_byte_clk)) {
105 pr_err("can't find dsi byte_clk\n");
106 rc = PTR_ERR(dsi_io_private->dsi_byte_clk);
107 dsi_io_private->dsi_byte_clk = NULL;
108 return rc;
109 }
110
111 dsi_io_private->dsi_esc_clk = clk_get(&dev->dev, "esc_clk");
112 if (IS_ERR(dsi_io_private->dsi_esc_clk)) {
113 pr_err("can't find dsi esc_clk\n");
114 rc = PTR_ERR(dsi_io_private->dsi_esc_clk);
115 dsi_io_private->dsi_esc_clk = NULL;
116 return rc;
117 }
118
119 dsi_io_private->dsi_pixel_clk = clk_get(&dev->dev, "pixel_clk");
120 if (IS_ERR(dsi_io_private->dsi_pixel_clk)) {
121 pr_err("can't find dsi pixel\n");
122 rc = PTR_ERR(dsi_io_private->dsi_pixel_clk);
123 dsi_io_private->dsi_pixel_clk = NULL;
124 return rc;
125 }
126
127 dsi_io_private->dsi_ahb_clk = clk_get(&dev->dev, "iface_clk");
128 if (IS_ERR(dsi_io_private->dsi_ahb_clk)) {
129 pr_err("can't find dsi iface_clk\n");
130 rc = PTR_ERR(dsi_io_private->dsi_ahb_clk);
131 dsi_io_private->dsi_ahb_clk = NULL;
132 return rc;
133 }
134 clk_prepare(dsi_io_private->dsi_ahb_clk);
135
136 return 0;
137}
138
139void msm_dsi_clk_deinit(void)
140{
141 if (dsi_io_private->dsi_clk) {
142 clk_put(dsi_io_private->dsi_clk);
143 dsi_io_private->dsi_clk = NULL;
144 }
145 if (dsi_io_private->dsi_byte_clk) {
146 clk_put(dsi_io_private->dsi_byte_clk);
147 dsi_io_private->dsi_byte_clk = NULL;
148 }
149 if (dsi_io_private->dsi_esc_clk) {
150 clk_put(dsi_io_private->dsi_esc_clk);
151 dsi_io_private->dsi_esc_clk = NULL;
152 }
153 if (dsi_io_private->dsi_pixel_clk) {
154 clk_put(dsi_io_private->dsi_pixel_clk);
155 dsi_io_private->dsi_pixel_clk = NULL;
156 }
157 if (dsi_io_private->dsi_ahb_clk) {
158 clk_unprepare(dsi_io_private->dsi_ahb_clk);
159 clk_put(dsi_io_private->dsi_ahb_clk);
160 dsi_io_private->dsi_ahb_clk = NULL;
161 }
162}
163
164int msm_dsi_prepare_clocks(void)
165{
166 clk_prepare(dsi_io_private->dsi_clk);
167 clk_prepare(dsi_io_private->dsi_byte_clk);
168 clk_prepare(dsi_io_private->dsi_esc_clk);
169 clk_prepare(dsi_io_private->dsi_pixel_clk);
170 return 0;
171}
172
173int msm_dsi_unprepare_clocks(void)
174{
175 clk_unprepare(dsi_io_private->dsi_clk);
176 clk_unprepare(dsi_io_private->dsi_esc_clk);
177 clk_unprepare(dsi_io_private->dsi_byte_clk);
178 clk_unprepare(dsi_io_private->dsi_pixel_clk);
179 return 0;
180}
181
182int msm_dsi_clk_set_rate(unsigned long esc_rate,
183 unsigned long dsi_rate,
184 unsigned long byte_rate,
185 unsigned long pixel_rate)
186{
187 int rc;
188
189 rc = clk_set_rate(dsi_io_private->dsi_clk, dsi_rate);
190 if (rc) {
191 pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc);
192 return rc;
193 }
194
195 rc = clk_set_rate(dsi_io_private->dsi_esc_clk, esc_rate);
196 if (rc) {
197 pr_err("dsi_esc_clk - clk_set_rate failed =%d\n", rc);
198 return rc;
199 }
200
201 rc = clk_set_rate(dsi_io_private->dsi_byte_clk, byte_rate);
202 if (rc) {
203 pr_err("dsi_byte_clk - clk_set_rate faile = %dd\n", rc);
204 return rc;
205 }
206
207 rc = clk_set_rate(dsi_io_private->dsi_pixel_clk, pixel_rate);
208 if (rc) {
209 pr_err("dsi_pixel_clk - clk_set_rate failed = %d\n", rc);
210 return rc;
211 }
212 return 0;
213}
214
215int msm_dsi_clk_enable(void)
216{
217 if (dsi_io_private->msm_dsi_clk_on) {
218 pr_debug("dsi_clks on already\n");
219 return 0;
220 }
221
222 clk_enable(dsi_io_private->dsi_clk);
223 clk_enable(dsi_io_private->dsi_esc_clk);
224 clk_enable(dsi_io_private->dsi_byte_clk);
225 clk_enable(dsi_io_private->dsi_pixel_clk);
226
227 dsi_io_private->msm_dsi_clk_on = 1;
228 return 0;
229}
230
231int msm_dsi_clk_disable(void)
232{
233 if (dsi_io_private->msm_dsi_clk_on == 0) {
234 pr_debug("mdss_dsi_clks already OFF\n");
235 return 0;
236 }
237
238 clk_disable(dsi_io_private->dsi_clk);
239 clk_disable(dsi_io_private->dsi_byte_clk);
240 clk_disable(dsi_io_private->dsi_esc_clk);
241 clk_disable(dsi_io_private->dsi_pixel_clk);
242
243 dsi_io_private->msm_dsi_clk_on = 0;
244 return 0;
245}
246
247static void msm_dsi_phy_strength_init(unsigned char *ctrl_base,
248 struct mdss_dsi_phy_ctrl *pd)
249{
250 MIPI_OUTP(ctrl_base + DSI_DSIPHY_STRENGTH_CTRL_0, pd->strength[0]);
251 MIPI_OUTP(ctrl_base + DSI_DSIPHY_STRENGTH_CTRL_2, pd->strength[1]);
252}
253
254static void msm_dsi_phy_ctrl_init(unsigned char *ctrl_base,
255 struct mdss_panel_data *pdata)
256{
257 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_0, 0x5f);
258 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_3, 0x10);
259}
260
261static void msm_dsi_phy_regulator_init(unsigned char *ctrl_base,
262 struct mdss_dsi_phy_ctrl *pd)
263{
264 MIPI_OUTP(ctrl_base + DSI_DSIPHY_LDO_CNTRL, 0x25);
265 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_0, pd->regulator[0]);
266 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_1, pd->regulator[1]);
267 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_2, pd->regulator[2]);
268 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_3, pd->regulator[3]);
269 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_4, pd->regulator[4]);
270 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CAL_PWR_CFG,
271 pd->regulator[5]);
272
273}
274
275static int msm_dsi_phy_calibration(unsigned char *ctrl_base)
276{
277 int i = 0, term_cnt = 5000, ret = 0, cal_busy;
278
279 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_SW_CFG2, 0x0);
280 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG1, 0x5a);
281 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG3, 0x10);
282 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG4, 0x01);
283 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_CFG0, 0x01);
284 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_TRIGGER, 0x01);
285 usleep_range(5000, 5100); /*per DSI controller spec*/
286 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CAL_HW_TRIGGER, 0x00);
287
288 cal_busy = MIPI_INP(ctrl_base + DSI_DSIPHY_REGULATOR_CAL_STATUS0);
289 while (cal_busy & 0x10) {
290 i++;
291 if (i > term_cnt) {
292 ret = -EINVAL;
293 pr_err("msm_dsi_phy_calibration error\n");
294 break;
295 }
296 cal_busy = MIPI_INP(ctrl_base +
297 DSI_DSIPHY_REGULATOR_CAL_STATUS0);
298 }
299
300 return ret;
301}
302
303static void msm_dsi_phy_lane_init(unsigned char *ctrl_base,
304 struct mdss_dsi_phy_ctrl *pd)
305{
306 int ln, index;
307
308 /*CFG0, CFG1, CFG2, TEST_DATAPATH, TEST_STR0, TEST_STR1*/
309 for (ln = 0; ln < 5; ln++) {
310 unsigned char *off = ctrl_base + 0x0300 + (ln * 0x40);
311
312 index = ln * 6;
313
314 MIPI_OUTP(off, pd->lanecfg[index]);
315 MIPI_OUTP(off + 4, pd->lanecfg[index + 1]);
316 MIPI_OUTP(off + 8, pd->lanecfg[index + 2]);
317 MIPI_OUTP(off + 12, pd->lanecfg[index + 3]);
318 MIPI_OUTP(off + 20, pd->lanecfg[index + 4]);
319 MIPI_OUTP(off + 24, pd->lanecfg[index + 5]);
320 }
321 wmb(); /* ensure write is finished before progressing */
322}
323
324static void msm_dsi_phy_timing_init(unsigned char *ctrl_base,
325 struct mdss_dsi_phy_ctrl *pd)
326{
327 int i, off = DSI_DSIPHY_TIMING_CTRL_0;
328
329 for (i = 0; i < 12; i++) {
330 MIPI_OUTP(ctrl_base + off, pd->timing[i]);
331 off += 4;
332 }
333 wmb(); /* ensure write is finished before progressing */
334}
335
336static void msm_dsi_phy_bist_init(unsigned char *ctrl_base,
337 struct mdss_dsi_phy_ctrl *pd)
338{
339 MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL4, pd->bistctrl[4]);
340 MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL1, pd->bistctrl[1]);
341 MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL0, pd->bistctrl[0]);
342 MIPI_OUTP(ctrl_base + DSI_DSIPHY_BIST_CTRL4, 0);
343 wmb(); /* ensure write is finished before progressing */
344}
345
346int msm_dsi_phy_init(unsigned char *ctrl_base,
347 struct mdss_panel_data *pdata)
348{
349 struct mdss_dsi_phy_ctrl *pd;
350
351 pd = &(pdata->panel_info.mipi.dsi_phy_db);
352
353 msm_dsi_phy_strength_init(ctrl_base, pd);
354
355 msm_dsi_phy_ctrl_init(ctrl_base, pdata);
356
357 msm_dsi_phy_regulator_init(ctrl_base, pd);
358
359 msm_dsi_phy_calibration(ctrl_base);
360
361 msm_dsi_phy_lane_init(ctrl_base, pd);
362
363 msm_dsi_phy_timing_init(ctrl_base, pd);
364
365 msm_dsi_phy_bist_init(ctrl_base, pd);
366
367 return 0;
368}
369
370void msm_dsi_phy_sw_reset(unsigned char *ctrl_base)
371{
372 /* start phy sw reset */
373 MIPI_OUTP(ctrl_base + DSI_PHY_SW_RESET, 0x0001);
374 udelay(1000); /*per DSI controller spec*/
375 wmb(); /* ensure write is finished before progressing */
376 /* end phy sw reset */
377 MIPI_OUTP(ctrl_base + DSI_PHY_SW_RESET, 0x0000);
378 udelay(100); /*per DSI controller spec*/
379 wmb(); /* ensure write is finished before progressing */
380}
381
382void msm_dsi_phy_off(unsigned char *ctrl_base)
383{
384 MIPI_OUTP(ctrl_base + DSI_DSIPHY_PLL_CTRL_5, 0x05f);
385 MIPI_OUTP(ctrl_base + DSI_DSIPHY_REGULATOR_CTRL_0, 0x02);
386 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_0, 0x00);
387 MIPI_OUTP(ctrl_base + DSI_DSIPHY_CTRL_1, 0x7f);
388 MIPI_OUTP(ctrl_base + DSI_CLK_CTRL, 0);
389}