summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorLuke Huang <lhuang@nvidia.com>2011-01-27 16:14:44 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:01:04 -0400
commit9422790b0eacbbeb801072cc292a353de086b86b (patch)
tree8006ac16140878915fba0a7372e69f09120f1f75 /drivers/video/tegra/dc/dsi.c
parent0503cd99d91bdd9660ef3640dd252964ab9fe646 (diff)
video: tegra: dsi: Added dsi support.
Bug 793366 Bug 794499 Original-Change-Id: Id49d86dd7760b75ef4947f5bdab9e37f0333391d Reviewed-on: http://git-master/r/#change,18950 Reviewed-on: http://git-master/r/22508 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: R28d85faa28119d5803ab717831d610ee8ad37700
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c1466
1 files changed, 1466 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
new file mode 100644
index 000000000..a6ea0f43d
--- /dev/null
+++ b/drivers/video/tegra/dc/dsi.c
@@ -0,0 +1,1466 @@
1/*
2 * drivers/video/tegra/dc/dsi.c
3 *
4 * Copyright (c) 2011, NVIDIA Corporation.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/clk.h>
18#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/fb.h>
21#include <linux/gpio.h>
22#include <linux/interrupt.h>
23#include <linux/kernel.h>
24#include <linux/slab.h>
25#include <linux/spinlock.h>
26#include <linux/workqueue.h>
27
28#include <mach/clk.h>
29#include <mach/dc.h>
30#include <mach/fb.h>
31#include <mach/nvhost.h>
32#include <../gpio-names.h>
33
34#include "dc_reg.h"
35#include "dc_priv.h"
36#include "dsi_regs.h"
37#include "dsi.h"
38
39#define DSI_USE_SYNC_POINTS 0
40
41
42#define DSI_MODULE_NOT_INIT 0x0
43#define DSI_MODULE_INIT 0x1
44
45#define DSI_LPHS_NOT_INIT 0x0
46#define DSI_LPHS_IN_LP_MODE 0x1
47#define DSI_LPHS_IN_HS_MODE 0x2
48
49#define DSI_VIDEO_TYPE_NOT_INIT 0x0
50#define DSI_VIDEO_TYPE_VIDEO_MODE 0x1
51#define DSI_VIDEO_TYPE_CMD_MODE 0x2
52
53#define DSI_DRIVEN_MODE_NOT_INIT 0x0
54#define DSI_DRIVEN_MODE_DC 0x1
55#define DSI_DRIVEN_MODE_HOST 0x2
56
57#define DSI_PHYCLK_OUT_DIS 0x0
58#define DSI_PHYCLK_OUT_EN 0x1
59
60#define DSI_PHYCLK_NOT_INIT 0x0
61#define DSI_PHYCLK_CONTINUOUS 0x1
62#define DSI_PHYCLK_TX_ONLY 0x2
63
64#define DSI_CLK_BURST_NOT_INIT 0x0
65#define DSI_CLK_BURST_NONE_BURST 0x1
66#define DSI_CLK_BURST_BURST_MODE 0x2
67
68struct dsi_status {
69 unsigned init:2;
70
71 unsigned lphs:2;
72
73 unsigned vtype:2;
74 unsigned driven:2;
75
76 unsigned clk_out:2;
77 unsigned clk_mode:2;
78 unsigned clk_burst:2;
79};
80
81/* source of video data */
82enum{
83 TEGRA_DSI_DRIVEN_BY_DC,
84 TEGRA_DSI_DRIVEN_BY_HOST,
85};
86
87struct tegra_dc_dsi_data {
88 struct tegra_dc *dc;
89 void __iomem *base;
90 struct resource *base_res;
91
92 struct clk *dc_clk;
93 struct clk *dsi_clk;
94
95 struct mutex lock;
96
97 /* data from board info */
98 struct tegra_dsi_out info;
99
100 struct dsi_status status;
101
102 u8 driven_mode;
103 u8 controller_index;
104
105 u8 pixel_scaler_mul;
106 u8 pixel_scaler_div;
107
108 u32 default_pixel_clk_khz;
109 u32 default_hs_clk_khz;
110
111 u32 target_hs_clk_khz;
112 u32 target_lp_clk_khz;
113
114 u16 current_bit_clk_ns;
115 u32 current_dsi_clk_khz;
116
117 u32 dsi_control_val;
118};
119
120const u32 dsi_pkt_seq_reg[NUMOF_PKT_SEQ] = {
121 DSI_PKT_SEQ_0_LO,
122 DSI_PKT_SEQ_0_HI,
123 DSI_PKT_SEQ_1_LO,
124 DSI_PKT_SEQ_1_HI,
125 DSI_PKT_SEQ_2_LO,
126 DSI_PKT_SEQ_2_HI,
127 DSI_PKT_SEQ_3_LO,
128 DSI_PKT_SEQ_3_HI,
129 DSI_PKT_SEQ_4_LO,
130 DSI_PKT_SEQ_4_HI,
131 DSI_PKT_SEQ_5_LO,
132 DSI_PKT_SEQ_5_HI,
133};
134
135const u32 dsi_pkt_seq_video_non_burst_syne[NUMOF_PKT_SEQ] = {
136 PKT_ID0(CMD_VS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
137 0,
138 PKT_ID0(CMD_VE) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
139 0,
140 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
141 0,
142 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_BLNK) | PKT_LEN1(1) |
143 PKT_ID2(CMD_HE) | PKT_LEN2(0),
144 PKT_ID3(CMD_BLNK) | PKT_LEN3(2) | PKT_ID4(CMD_RGB) | PKT_LEN4(3) |
145 PKT_ID5(CMD_BLNK) | PKT_LEN5(4),
146 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
147 0,
148 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_BLNK) | PKT_LEN1(1) |
149 PKT_ID2(CMD_HE) | PKT_LEN2(0),
150 PKT_ID3(CMD_BLNK) | PKT_LEN3(2) | PKT_ID4(CMD_RGB) | PKT_LEN4(3) |
151 PKT_ID5(CMD_BLNK) | PKT_LEN5(4),
152};
153
154const u32 dsi_pkt_seq_video_non_burst[NUMOF_PKT_SEQ] = {
155 PKT_ID0(CMD_VS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
156 0,
157 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
158 0,
159 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
160 0,
161 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_BLNK) | PKT_LEN1(2) |
162 PKT_ID2(CMD_RGB) | PKT_LEN2(3),
163 PKT_ID3(CMD_BLNK) | PKT_LEN3(4),
164 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_EOT) | PKT_LEN1(0) | PKT_LP,
165 0,
166 PKT_ID0(CMD_HS) | PKT_LEN0(0) | PKT_ID1(CMD_BLNK) | PKT_LEN1(2) |
167 PKT_ID2(CMD_RGB) | PKT_LEN2(3),
168 PKT_ID3(CMD_BLNK) | PKT_LEN3(4),
169};
170
171static const u32 dsi_pkt_seq_video_burst[NUMOF_PKT_SEQ] = {
172 PKT_ID0(CMD_NULL) | PKT_LEN0(4) | PKT_ID1(CMD_VS) | PKT_LEN1(0) |
173 PKT_ID2(CMD_EOT) | PKT_LEN2(0) | PKT_LP,
174 0,
175 PKT_ID0(CMD_NULL) | PKT_LEN0(4) | PKT_ID1(CMD_HS) | PKT_LEN1(0) |
176 PKT_ID2(CMD_EOT) | PKT_LEN2(0) | PKT_LP,
177 0,
178 PKT_ID0(CMD_NULL) | PKT_LEN0(4) | PKT_ID1(CMD_HS) | PKT_LEN1(0) |
179 PKT_ID2(CMD_EOT) | PKT_LEN2(0) | PKT_LP,
180 PKT_ID0(CMD_BLNK) | PKT_LEN0(4) | PKT_ID1(CMD_HS) | PKT_LEN1(0) |
181 PKT_ID2(CMD_BLNK) | PKT_LEN2(2),
182 PKT_ID3(CMD_RGB) | PKT_LEN3(3) | PKT_ID4(CMD_EOT) | PKT_LEN4(0),
183 PKT_ID0(CMD_NULL) | PKT_LEN0(4) | PKT_ID1(CMD_HS) | PKT_LEN1(0) |
184 PKT_ID2(CMD_EOT) | PKT_LEN2(0) | PKT_LP,
185 0,
186 PKT_ID0(CMD_BLNK) | PKT_LEN0(4) | PKT_ID1(CMD_HS) | PKT_LEN1(0) |
187 PKT_ID2(CMD_BLNK) | PKT_LEN2(2),
188 PKT_ID3(CMD_RGB) | PKT_LEN3(3) | PKT_ID4(CMD_EOT) | PKT_LEN4(0),
189};
190
191/* TODO: verify with hw about this format */
192const u32 dsi_pkt_seq_cmd_mode [NUMOF_PKT_SEQ] = {
193 0,
194 0,
195 0,
196 0,
197 0,
198 0,
199 PKT_ID0(CMD_LONGW) | PKT_LEN0(3) | PKT_ID1(CMD_EOT) | PKT_LEN1(7),
200 0,
201 0,
202 0,
203 PKT_ID0(CMD_LONGW) | PKT_LEN0(3) | PKT_ID1(CMD_EOT) | PKT_LEN1(7),
204 0,
205};
206
207const u32 init_reg[] = {
208 DSI_WR_DATA,
209 DSI_INT_ENABLE,
210 DSI_INT_STATUS,
211 DSI_INT_MASK,
212 DSI_INIT_SEQ_DATA_0,
213 DSI_INIT_SEQ_DATA_1,
214 DSI_INIT_SEQ_DATA_2,
215 DSI_INIT_SEQ_DATA_3,
216 DSI_DCS_CMDS,
217 DSI_PKT_SEQ_0_LO,
218 DSI_PKT_SEQ_1_LO,
219 DSI_PKT_SEQ_2_LO,
220 DSI_PKT_SEQ_3_LO,
221 DSI_PKT_SEQ_4_LO,
222 DSI_PKT_SEQ_5_LO,
223 DSI_PKT_SEQ_0_HI,
224 DSI_PKT_SEQ_1_HI,
225 DSI_PKT_SEQ_2_HI,
226 DSI_PKT_SEQ_3_HI,
227 DSI_PKT_SEQ_4_HI,
228 DSI_PKT_SEQ_5_HI,
229 DSI_CONTROL,
230 DSI_HOST_DSI_CONTROL,
231 DSI_PAD_CONTROL,
232 DSI_PAD_CONTROL_CD,
233 DSI_SOL_DELAY,
234 DSI_MAX_THRESHOLD,
235 DSI_TRIGGER,
236 DSI_TX_CRC,
237 DSI_INIT_SEQ_CONTROL,
238 DSI_PKT_LEN_0_1,
239 DSI_PKT_LEN_2_3,
240 DSI_PKT_LEN_4_5,
241 DSI_PKT_LEN_6_7,
242};
243
244static inline unsigned long tegra_dsi_readl(struct tegra_dc_dsi_data *dsi,
245 u32 reg)
246{
247 return readl(dsi->base + reg * 4);
248}
249
250static inline void tegra_dsi_writel(struct tegra_dc_dsi_data *dsi,u32 val,
251 u32 reg)
252{
253 writel(val, dsi->base + reg * 4);
254}
255
256static u32 tegra_dsi_get_hs_clk_rate(struct tegra_dc_dsi_data *dsi)
257{
258 u32 dsi_clock_rate_khz;
259
260 switch (dsi->info.video_burst_mode) {
261 case TEGRA_DSI_VIDEO_BURST_MODE_LOW_SPEED:
262 case TEGRA_DSI_VIDEO_BURST_MODE_MEDIUM_SPEED:
263 case TEGRA_DSI_VIDEO_BURST_MODE_FAST_SPEED:
264 case TEGRA_DSI_VIDEO_BURST_MODE_FASTEST_SPEED:
265 /* TODO: implement algo for these speed rate */
266
267 case TEGRA_DSI_VIDEO_BURST_MODE_MANUAL:
268 if (dsi->info.burst_mode_freq_khz) {
269 dsi_clock_rate_khz = dsi->info.burst_mode_freq_khz;
270 break;
271 }
272 case TEGRA_DSI_VIDEO_NONE_BURST_MODE:
273 case TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END:
274 case TEGRA_DSI_VIDEO_BURST_MODE_LOWEST_SPEED:
275 default:
276 dsi_clock_rate_khz = dsi->default_hs_clk_khz;
277 break;
278 }
279
280 return dsi_clock_rate_khz;
281}
282
283static u32 tegra_dsi_get_lp_clk_rate(struct tegra_dc_dsi_data *dsi)
284{
285 u32 dsi_clock_rate_khz;
286
287 if (dsi->info.enable_hs_clock_on_lp_cmd_mode)
288 if (dsi->info.hs_clk_in_lp_cmd_mode_freq_khz)
289 dsi_clock_rate_khz =
290 dsi->info.hs_clk_in_lp_cmd_mode_freq_khz;
291 else
292 dsi_clock_rate_khz = tegra_dsi_get_hs_clk_rate(dsi);
293 else
294 dsi_clock_rate_khz = dsi->info.lp_cmd_mode_freq_khz;
295
296 return dsi_clock_rate_khz;
297}
298
299static void tegra_dsi_init_sw(struct tegra_dc *dc,
300 struct tegra_dc_dsi_data *dsi)
301{
302 u32 h_width_pixels;
303 u32 v_width_lines;
304 u32 pixel_clk_hz;
305 u32 byte_clk_hz;
306
307 switch (dsi->info.pixel_format) {
308 case TEGRA_DSI_PIXEL_FORMAT_16BIT_P:
309 /* 2 bytes per pixel */
310 dsi->pixel_scaler_mul = 2;
311 dsi->pixel_scaler_div = 1;
312 break;
313 case TEGRA_DSI_PIXEL_FORMAT_18BIT_P:
314 /* 2.25 bytes per pixel */
315 dsi->pixel_scaler_mul = 9;
316 dsi->pixel_scaler_div = 4;
317 break;
318 case TEGRA_DSI_PIXEL_FORMAT_18BIT_NP:
319 case TEGRA_DSI_PIXEL_FORMAT_24BIT_P:
320 /* 3 bytes per pixel */
321 dsi->pixel_scaler_mul = 3;
322 dsi->pixel_scaler_div = 1;
323 break;
324 default:
325 break;
326 }
327
328 h_width_pixels = dc->mode.h_back_porch + dc->mode.h_front_porch +
329 dc->mode.h_sync_width + dc->mode.h_active;
330 v_width_lines = dc->mode.v_back_porch + dc->mode.v_front_porch +
331 dc->mode.v_sync_width + dc->mode.v_active;
332
333 /* The slowest pixel rate that is required */
334 /* for the given display timing */
335 pixel_clk_hz = h_width_pixels * v_width_lines * dsi->info.refresh_rate;
336
337 /* Pixel byte rate on DSI interface */
338 byte_clk_hz = (pixel_clk_hz * dsi->pixel_scaler_mul) /
339 (dsi->pixel_scaler_div * dsi->info.n_data_lanes);
340
341 dsi->default_pixel_clk_khz = pixel_clk_hz / 1000;
342
343 printk("dsi: default pixel rate %d khz\n", dsi->default_pixel_clk_khz);
344
345 /*
346 * Pixel bit rate on DSI. Since DSI interface is double data rate (
347 * transferring data on both rising and falling edge of clk), div by 2
348 * to get the actual clock rate.
349 */
350 dsi->default_hs_clk_khz =
351 (byte_clk_hz * NUMOF_BIT_PER_BYTE) / (1000 * 2);
352
353 dsi->dsi_control_val =
354 DSI_CONTROL_VIRTUAL_CHANNEL(dsi->info.virtual_channel) |
355 DSI_CONTROL_NUM_DATA_LANES(dsi->info.n_data_lanes - 1) |
356 DSI_CONTROL_VID_SOURCE(dsi->controller_index) |
357 DSI_CONTROL_DATA_FORMAT(dsi->info.pixel_format);
358
359 dsi->target_lp_clk_khz = tegra_dsi_get_lp_clk_rate(dsi);
360 dsi->target_hs_clk_khz = tegra_dsi_get_hs_clk_rate(dsi);
361
362 /*
363 * Force video clock to be continuous mode if
364 * enable_hs_clock_on_lp_cmd_mode is set
365 */
366 if (dsi->info.enable_hs_clock_on_lp_cmd_mode) {
367 if (dsi->info.video_clock_mode != TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS)
368 printk("Force to clock continuous mode\n");
369
370 dsi->info.video_clock_mode = TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS;
371 }
372
373}
374
375static void tegra_dsi_get_phy_timing(struct tegra_dc_dsi_data *dsi,
376 struct dsi_phy_timing_inclk *phy_timing_clk,
377 u32 clk_ns)
378{
379
380 phy_timing_clk->t_hsdexit = dsi->info.phy_timing.t_hsdexit_ns ?
381 (dsi->info.phy_timing.t_hsdexit_ns / clk_ns) :
382 (T_HSEXIT_DEFAULT(clk_ns));
383
384 phy_timing_clk->t_hstrail = dsi->info.phy_timing.t_hstrail_ns ?
385 (dsi->info.phy_timing.t_hstrail_ns / clk_ns) :
386 (T_HSTRAIL_DEFAULT(clk_ns));
387
388 phy_timing_clk->t_datzero = dsi->info.phy_timing.t_datzero_ns ?
389 (dsi->info.phy_timing.t_datzero_ns / clk_ns) :
390 (T_DATZERO_DEFAULT(clk_ns));
391
392 phy_timing_clk->t_hsprepr = dsi->info.phy_timing.t_hsprepr_ns ?
393 (dsi->info.phy_timing.t_hsprepr_ns / clk_ns) :
394 (T_HSPREPR_DEFAULT(clk_ns));
395
396 phy_timing_clk->t_clktrail = dsi->info.phy_timing.t_clktrail_ns ?
397 (dsi->info.phy_timing.t_clktrail_ns / clk_ns) :
398 (T_CLKTRAIL_DEFAULT(clk_ns));
399
400 phy_timing_clk->t_clkpost = dsi->info.phy_timing.t_clkpost_ns ?
401 (dsi->info.phy_timing.t_clkpost_ns / clk_ns) :
402 (T_CLKPOST_DEFAULT(clk_ns));
403
404 phy_timing_clk->t_clkzero = dsi->info.phy_timing.t_clkzero_ns ?
405 (dsi->info.phy_timing.t_clkzero_ns / clk_ns) :
406 (T_CLKZERO_DEFAULT(clk_ns));
407
408 phy_timing_clk->t_tlpx = dsi->info.phy_timing.t_tlpx_ns ?
409 (dsi->info.phy_timing.t_tlpx_ns / clk_ns) :
410 (T_TLPX_DEFAULT(clk_ns));
411
412 phy_timing_clk->t_clkpre = T_CLKPRE_DEFAULT(clk_ns);
413 phy_timing_clk->t_clkprepare = T_CLKPREPARE_DEFAULT(clk_ns);
414 phy_timing_clk->t_wakeup = T_WAKEUP_DEFAULT(clk_ns);
415
416 phy_timing_clk->t_taget = 5 * phy_timing_clk->t_tlpx;
417 phy_timing_clk->t_tasure = 2 * phy_timing_clk->t_tlpx;
418 phy_timing_clk->t_tago = 4 * phy_timing_clk->t_tlpx;
419}
420
421static void tegra_dsi_set_phy_timing(struct tegra_dc_dsi_data *dsi)
422{
423 u32 val;
424 struct dsi_phy_timing_inclk phy_timing;
425
426 tegra_dsi_get_phy_timing(dsi, &phy_timing, dsi->current_bit_clk_ns);
427
428 val = DSI_PHY_TIMING_0_THSDEXIT(phy_timing.t_hsdexit) |
429 DSI_PHY_TIMING_0_THSTRAIL(phy_timing.t_hstrail) |
430 DSI_PHY_TIMING_0_TDATZERO(phy_timing.t_datzero) |
431 DSI_PHY_TIMING_0_THSPREPR(phy_timing.t_hsprepr);
432 tegra_dsi_writel(dsi, val, DSI_PHY_TIMING_0);
433
434 val = DSI_PHY_TIMING_1_TCLKTRAIL(phy_timing.t_clktrail) |
435 DSI_PHY_TIMING_1_TCLKPOST(phy_timing.t_clkpost) |
436 DSI_PHY_TIMING_1_TCLKZERO(phy_timing.t_clkzero) |
437 DSI_PHY_TIMING_1_TTLPX(phy_timing.t_tlpx);
438 tegra_dsi_writel(dsi, val, DSI_PHY_TIMING_1);
439
440 val = DSI_PHY_TIMING_2_TCLKPREPARE(phy_timing.t_clkprepare) |
441 DSI_PHY_TIMING_2_TCLKPRE(phy_timing.t_clkpre) |
442 DSI_PHY_TIMING_2_TWAKEUP(phy_timing.t_wakeup);
443 tegra_dsi_writel(dsi, val, DSI_PHY_TIMING_2);
444
445 val = DSI_BTA_TIMING_TTAGET(phy_timing.t_taget) |
446 DSI_BTA_TIMING_TTASURE(phy_timing.t_tasure) |
447 DSI_BTA_TIMING_TTAGO(phy_timing.t_tago);
448 tegra_dsi_writel(dsi, val, DSI_BTA_TIMING);
449}
450
451static u32 tegra_dsi_sol_delay_burst(struct tegra_dc *dc,
452 struct tegra_dc_dsi_data *dsi)
453{
454 u32 dsi_to_pixel_clk_ratio;
455 u32 temp;
456 u32 temp1;
457 u32 mipi_clk_adj_kHz;
458 u32 sol_delay;
459 struct tegra_dc_mode *dc_modes = &dc->mode;
460
461 /* Get Fdsi/Fpixel ration (note: Fdsi si in bit format) */
462 dsi_to_pixel_clk_ratio = (dsi->current_dsi_clk_khz * 2 +
463 dsi->default_pixel_clk_khz - 1) / dsi->default_pixel_clk_khz;
464
465 /* Convert Fdsi to byte format */
466 dsi_to_pixel_clk_ratio *= 1000/8;
467
468 /* Multiplying by 1000 so that we don't loose the fraction part */
469 temp = dc_modes->h_active * 1000;
470 temp1 = dc_modes->h_active + dc_modes->h_back_porch +
471 dc_modes->h_sync_width;
472
473 sol_delay = temp1 * dsi_to_pixel_clk_ratio -
474 temp * dsi->pixel_scaler_mul /
475 (dsi->pixel_scaler_div * dsi->info.n_data_lanes);
476
477 /* Do rounding on sol delay */
478 sol_delay = (sol_delay + 1000 - 1)/1000;
479
480 /* TODO:
481 * 1. find out the correct sol fifo depth to use
482 * 2. verify with hw about the clamping function
483 */
484 if (sol_delay > (480 * 4)) {
485 sol_delay = (480 * 4);
486 mipi_clk_adj_kHz = sol_delay +
487 (dc_modes->h_active * dsi->pixel_scaler_mul) /
488 (dsi->info.n_data_lanes * dsi->pixel_scaler_div);
489
490 mipi_clk_adj_kHz *= (dsi->default_pixel_clk_khz / temp1);
491
492 mipi_clk_adj_kHz *= 4;
493 }
494
495 dsi->target_hs_clk_khz = mipi_clk_adj_kHz;
496
497 return sol_delay;
498}
499
500static void tegra_dsi_set_sol_delay(struct tegra_dc *dc,
501 struct tegra_dc_dsi_data *dsi)
502{
503 u32 sol_delay;
504
505 if (dsi->info.video_burst_mode == TEGRA_DSI_VIDEO_NONE_BURST_MODE ||
506 dsi->info.video_burst_mode ==
507 TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END) {
508 sol_delay = NUMOF_BIT_PER_BYTE * dsi->pixel_scaler_mul /
509 (dsi->pixel_scaler_div * dsi->info.n_data_lanes);
510 dsi->status.clk_burst = DSI_CLK_BURST_NONE_BURST;
511 } else {
512 sol_delay = tegra_dsi_sol_delay_burst(dc, dsi);
513 dsi->status.clk_burst = DSI_CLK_BURST_BURST_MODE;
514 }
515
516 tegra_dsi_writel(dsi, DSI_SOL_DELAY_SOL_DELAY(sol_delay),
517 DSI_SOL_DELAY);
518}
519
520static void tegra_dsi_set_timeout(struct tegra_dc_dsi_data *dsi)
521{
522 u32 val;
523 u32 bytes_per_frame;
524 u32 timeout = 0;
525
526 /* TODO: verify the following eq */
527 bytes_per_frame = dsi->current_dsi_clk_khz * 1000 * 2 /
528 (dsi->info.refresh_rate * 8);
529 timeout = bytes_per_frame / DSI_CYCLE_COUNTER_VALUE;
530 timeout = (timeout + DSI_HTX_TO_MARGIN) & 0xffff;
531
532 val = DSI_TIMEOUT_0_LRXH_TO(DSI_LRXH_TO_VALUE) |
533 DSI_TIMEOUT_0_HTX_TO(timeout);
534 tegra_dsi_writel(dsi, val, DSI_TIMEOUT_0);
535
536 if (dsi->info.panel_reset_timeout_msec)
537 timeout = (dsi->info.panel_reset_timeout_msec * 1000*1000)
538 / dsi->current_bit_clk_ns;
539 else
540 timeout = DSI_PR_TO_VALUE;
541
542 val = DSI_TIMEOUT_1_PR_TO(timeout) |
543 DSI_TIMEOUT_1_TA_TO(DSI_TA_TO_VALUE);
544 tegra_dsi_writel(dsi, val, DSI_TIMEOUT_1);
545
546 val = DSI_TO_TALLY_P_RESET_STATUS(IN_RESET) |
547 DSI_TO_TALLY_TA_TALLY(DSI_TA_TALLY_VALUE)|
548 DSI_TO_TALLY_LRXH_TALLY(DSI_LRXH_TALLY_VALUE)|
549 DSI_TO_TALLY_HTX_TALLY(DSI_HTX_TALLY_VALUE);
550 tegra_dsi_writel(dsi, val, DSI_TO_TALLY);
551}
552
553static void tegra_dsi_setup_video_mode_pkt_length(struct tegra_dc *dc,
554 struct tegra_dc_dsi_data *dsi)
555{
556 u32 val;
557 u32 hact_pkt_len;
558 u32 hsa_pkt_len;
559 u32 hbp_pkt_len;
560 u32 hfp_pkt_len;
561
562 hact_pkt_len = dc->mode.h_active * dsi->pixel_scaler_mul /
563 dsi->pixel_scaler_div;
564 hsa_pkt_len = dc->mode.h_sync_width * dsi->pixel_scaler_mul /
565 dsi->pixel_scaler_div;
566 hbp_pkt_len = dc->mode.h_back_porch * dsi->pixel_scaler_mul /
567 dsi->pixel_scaler_div;
568 hfp_pkt_len = dc->mode.h_front_porch * dsi->pixel_scaler_mul /
569 dsi->pixel_scaler_div;
570
571 if (dsi->info.video_burst_mode !=
572 TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END)
573 hbp_pkt_len += hsa_pkt_len;
574
575 hsa_pkt_len -= DSI_HSYNC_BLNK_PKT_OVERHEAD;
576 hbp_pkt_len -= DSI_HBACK_PORCH_PKT_OVERHEAD;
577 hfp_pkt_len -= DSI_HFRONT_PORCH_PKT_OVERHEAD;
578
579 val = DSI_PKT_LEN_0_1_LENGTH_0(0) | DSI_PKT_LEN_0_1_LENGTH_1(hsa_pkt_len);
580 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_0_1);
581
582 val = DSI_PKT_LEN_2_3_LENGTH_2(hbp_pkt_len) |
583 DSI_PKT_LEN_2_3_LENGTH_3(hact_pkt_len);
584 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_2_3);
585
586 val = DSI_PKT_LEN_4_5_LENGTH_4(hfp_pkt_len) | DSI_PKT_LEN_4_5_LENGTH_5(0);
587 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_4_5);
588
589 val = DSI_PKT_LEN_6_7_LENGTH_6(0) | DSI_PKT_LEN_6_7_LENGTH_7(0);
590 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_6_7);
591}
592
593static void tegra_dsi_setup_cmd_mode_pkt_length(struct tegra_dc *dc,
594 struct tegra_dc_dsi_data *dsi)
595{
596 unsigned long val;
597 unsigned long act_bytes;
598
599 act_bytes = dc->mode.h_active * dsi->pixel_scaler_mul /
600 dsi->pixel_scaler_div + 1;
601
602 val = DSI_PKT_LEN_0_1_LENGTH_0(0) | DSI_PKT_LEN_0_1_LENGTH_1(0);
603 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_0_1);
604
605 val = DSI_PKT_LEN_2_3_LENGTH_2(0) | DSI_PKT_LEN_2_3_LENGTH_3(act_bytes);
606 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_2_3);
607
608 val = DSI_PKT_LEN_4_5_LENGTH_4(0) | DSI_PKT_LEN_4_5_LENGTH_5(act_bytes);
609 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_4_5);
610
611 val = DSI_PKT_LEN_6_7_LENGTH_6(0) | DSI_PKT_LEN_6_7_LENGTH_7(0x0f0f);
612 tegra_dsi_writel(dsi, val, DSI_PKT_LEN_6_7);
613}
614
615static void tegra_dsi_set_pkt_length(struct tegra_dc *dc,
616 struct tegra_dc_dsi_data *dsi)
617{
618 if (dsi->driven_mode == TEGRA_DSI_DRIVEN_BY_HOST)
619 return;
620
621 if (dsi->info.video_data_type == TEGRA_DSI_VIDEO_TYPE_VIDEO_MODE)
622 tegra_dsi_setup_video_mode_pkt_length(dc, dsi);
623 else
624 tegra_dsi_setup_cmd_mode_pkt_length(dc, dsi);
625}
626
627static void tegra_dsi_set_pkt_seq(struct tegra_dc *dc,
628 struct tegra_dc_dsi_data *dsi)
629{
630 const u32 *pkt_seq;
631 u32 rgb_info;
632 u32 pkt_seq_3_5_rgb_lo;
633 u32 pkt_seq_3_5_rgb_hi;
634 u32 val;
635 u32 reg;
636 u8 i;
637
638 if (dsi->driven_mode == TEGRA_DSI_DRIVEN_BY_HOST)
639 return;
640
641 switch(dsi->info.pixel_format) {
642 case TEGRA_DSI_PIXEL_FORMAT_16BIT_P:
643 rgb_info = CMD_RGB_16BPP;
644 break;
645 case TEGRA_DSI_PIXEL_FORMAT_18BIT_P:
646 rgb_info = CMD_RGB_18BPP;
647 break;
648 case TEGRA_DSI_PIXEL_FORMAT_18BIT_NP:
649 rgb_info = CMD_RGB_18BPPNP;
650 break;
651 case TEGRA_DSI_PIXEL_FORMAT_24BIT_P:
652 default:
653 rgb_info = CMD_RGB_24BPP;
654 break;
655 }
656
657 pkt_seq_3_5_rgb_lo = 0;
658 pkt_seq_3_5_rgb_hi = 0;
659 if (dsi->info.video_data_type == TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE)
660 pkt_seq = dsi_pkt_seq_cmd_mode;
661 else {
662 switch (dsi->info.video_burst_mode) {
663 case TEGRA_DSI_VIDEO_BURST_MODE_LOWEST_SPEED:
664 case TEGRA_DSI_VIDEO_BURST_MODE_LOW_SPEED:
665 case TEGRA_DSI_VIDEO_BURST_MODE_MEDIUM_SPEED:
666 case TEGRA_DSI_VIDEO_BURST_MODE_FAST_SPEED:
667 case TEGRA_DSI_VIDEO_BURST_MODE_FASTEST_SPEED:
668 case TEGRA_DSI_VIDEO_BURST_MODE_MANUAL:
669 pkt_seq_3_5_rgb_hi = DSI_PKT_SEQ_3_HI_PKT_33_ID(rgb_info);
670 pkt_seq = dsi_pkt_seq_video_burst;
671 break;
672 case TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END:
673 pkt_seq_3_5_rgb_hi = DSI_PKT_SEQ_3_HI_PKT_34_ID(rgb_info);
674 pkt_seq = dsi_pkt_seq_video_non_burst_syne;
675 break;
676 case TEGRA_DSI_VIDEO_NONE_BURST_MODE:
677 default:
678 pkt_seq_3_5_rgb_lo = DSI_PKT_SEQ_3_LO_PKT_32_ID(rgb_info);
679 pkt_seq = dsi_pkt_seq_video_non_burst;
680 break;
681 }
682 }
683
684 for (i = 0; i < NUMOF_PKT_SEQ; i++) {
685 val = pkt_seq[i];
686 reg = dsi_pkt_seq_reg[i];
687 if ((reg == DSI_PKT_SEQ_3_LO) || (reg == DSI_PKT_SEQ_5_LO))
688 val |= pkt_seq_3_5_rgb_lo;
689 if ((reg == DSI_PKT_SEQ_3_HI) || (reg == DSI_PKT_SEQ_5_HI))
690 val |= pkt_seq_3_5_rgb_hi;
691 tegra_dsi_writel(dsi, val, reg);
692 }
693}
694
695static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc,
696 struct tegra_dc_dsi_data *dsi)
697{
698 /*
699 * TODO: It is possible that we are in the middle of video stream,
700 * Add code to wait for vsync and then stop DC from sending data to dsi
701 */
702 tegra_dc_writel(dc, 0, DC_DISP_DISP_WIN_OPTIONS);
703}
704
705static void tegra_dsi_start_dc_stream(struct tegra_dc *dc,
706 struct tegra_dc_dsi_data *dsi)
707{
708 u32 val;
709 tegra_dc_writel(dc, DSI_ENABLE, DC_DISP_DISP_WIN_OPTIONS);
710
711 /* TODO: clean up */
712 val = PIN_INPUT_LSPI_INPUT_EN;
713 tegra_dc_writel(dc, val, DC_COM_PIN_INPUT_ENABLE3);
714
715 val = PIN_OUTPUT_LSPI_OUTPUT_DIS;
716 tegra_dc_writel(dc, val, DC_COM_PIN_OUTPUT_ENABLE3);
717
718 tegra_dc_writel(dc, PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
719 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
720 DC_CMD_DISPLAY_POWER_CONTROL);
721
722 val = MSF_POLARITY_HIGH | MSF_ENABLE | MSF_LSPI;
723 tegra_dc_writel(dc, val, DC_CMD_DISPLAY_COMMAND_OPTION0);
724
725
726 /* TODO: using continuous video mode for now */
727 /* if (dsi->info.panel_has_frame_buffer) {*/
728 if (0) {
729 tegra_dc_writel(dc, DISP_CTRL_MODE_NC_DISPLAY, DC_CMD_DISPLAY_COMMAND);
730 tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
731 val = GENERAL_ACT_REQ | NC_HOST_TRIG;
732 tegra_dc_writel(dc, val, DC_CMD_STATE_CONTROL);
733 } else {
734 tegra_dc_writel(dc, DISP_CTRL_MODE_C_DISPLAY, DC_CMD_DISPLAY_COMMAND);
735 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
736 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
737 }
738}
739
740static void tegra_dsi_set_dc_clk(struct tegra_dc *dc,
741 struct tegra_dc_dsi_data *dsi)
742{
743 u32 shift_clk_div;
744 u32 val;
745
746 if (dsi->info.video_burst_mode == TEGRA_DSI_VIDEO_NONE_BURST_MODE ||
747 dsi->info.video_burst_mode ==
748 TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END)
749 shift_clk_div = NUMOF_BIT_PER_BYTE * dsi->pixel_scaler_mul /
750 (dsi->pixel_scaler_div * dsi->info.n_data_lanes) - 2;
751 else
752 shift_clk_div = (dsi->current_dsi_clk_khz * 2 +
753 dsi->default_hs_clk_khz - 1) /
754 (dsi->default_hs_clk_khz) - 2;
755
756#ifdef CONFIG_TEGRA_FPGA_PLATFORM
757 shift_clk_div = 1;
758#endif
759
760 /* TODO: find out if PCD3 option is required */
761 val = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(shift_clk_div);
762 tegra_dc_writel(dc, val, DC_DISP_DISP_CLOCK_CONTROL);
763
764 clk_enable(dsi->dc_clk);
765}
766
767static void tegra_dsi_set_dsi_clk(struct tegra_dc *dc,
768 struct tegra_dc_dsi_data *dsi, u32 clk)
769{
770 u32 rm;
771
772 rm = clk % 100;
773 if (rm != 0)
774 clk -= rm;
775
776 clk *= 2; /* Value for PLLD routine is required to be twice as */
777 /* the desired clock rate */
778
779 dc->mode.pclk = clk*1000;
780 tegra_dc_setup_clk(dc, dsi->dsi_clk);
781 clk_enable(dsi->dsi_clk);
782 tegra_periph_reset_deassert(dsi->dsi_clk);
783
784 dsi->current_dsi_clk_khz = clk_get_rate(dsi->dsi_clk) / 1000;
785
786 dsi->current_bit_clk_ns = 1000*1000 / (dsi->current_dsi_clk_khz * 2);
787}
788
789static void tegra_dsi_hs_clk_out_enable(struct tegra_dc_dsi_data *dsi)
790{
791 u32 val;
792
793 val = tegra_dsi_readl(dsi, DSI_CONTROL);
794 val &= ~DSI_CONTROL_HS_CLK_CTRL(1);
795
796 if (dsi->info.video_clock_mode == TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS) {
797 val |= DSI_CONTROL_HS_CLK_CTRL(CONTINUOUS);
798 dsi->status.clk_mode = DSI_PHYCLK_CONTINUOUS;
799 } else {
800 val |= DSI_CONTROL_HS_CLK_CTRL(TX_ONLY);
801 dsi->status.clk_mode = DSI_PHYCLK_TX_ONLY;
802 }
803 tegra_dsi_writel(dsi, val, DSI_CONTROL);
804
805 val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL);
806 val &= ~DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(1);
807 val |= DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(TEGRA_DSI_HIGH);
808 tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL);
809
810 dsi->status.clk_out = DSI_PHYCLK_OUT_EN;
811}
812
813static void tegra_dsi_hs_clk_out_enable_in_lp(struct tegra_dc_dsi_data *dsi)
814{
815 u32 val;
816 tegra_dsi_hs_clk_out_enable(dsi);
817
818 val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL);
819 val &= ~DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(1);
820 val |= DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(TEGRA_DSI_LOW);
821 tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL);
822}
823
824static void tegra_dsi_hs_clk_out_disable(struct tegra_dc *dc,
825 struct tegra_dc_dsi_data *dsi)
826{
827 u32 val;
828
829 if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
830 tegra_dsi_stop_dc_stream(dc, dsi);
831
832 val = tegra_dsi_readl(dsi, DSI_CONTROL);
833 val &= ~DSI_CONTROL_HS_CLK_CTRL(1);
834 val |= DSI_CONTROL_HS_CLK_CTRL(TX_ONLY);
835 tegra_dsi_writel(dsi, val, DSI_CONTROL);
836
837 /* TODO: issue a cmd */
838
839 val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL);
840 val &= ~DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(1);
841 val |= DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(TEGRA_DSI_LOW);
842 tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL);
843
844 dsi->status.clk_mode = DSI_PHYCLK_NOT_INIT;
845 dsi->status.clk_out = DSI_PHYCLK_OUT_DIS;
846}
847
848static void tegra_dsi_set_control_reg_lp(struct tegra_dc_dsi_data *dsi)
849{
850 u32 dsi_control;
851 u32 host_dsi_control;
852 u32 max_threshold;
853
854 dsi_control = dsi->dsi_control_val | DSI_CTRL_HOST_DRIVEN;
855 host_dsi_control = HOST_DSI_CTRL_COMMON |
856 HOST_DSI_CTRL_HOST_DRIVEN |
857 DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(TEGRA_DSI_LOW);
858 max_threshold = DSI_MAX_THRESHOLD_MAX_THRESHOLD(DSI_HOST_FIFO_DEPTH);
859
860 tegra_dsi_writel(dsi, max_threshold, DSI_MAX_THRESHOLD);
861 tegra_dsi_writel(dsi, dsi_control, DSI_CONTROL);
862 tegra_dsi_writel(dsi, host_dsi_control, DSI_HOST_DSI_CONTROL);
863
864 dsi->status.driven = DSI_DRIVEN_MODE_HOST;
865 dsi->status.clk_burst = DSI_CLK_BURST_NOT_INIT;
866 dsi->status.vtype = DSI_VIDEO_TYPE_NOT_INIT;
867}
868
869static void tegra_dsi_set_control_reg_hs(struct tegra_dc_dsi_data *dsi)
870{
871 u32 dsi_control;
872 u32 host_dsi_control;
873 u32 max_threshold;
874 u32 dcs_cmd;
875
876 dsi_control = dsi->dsi_control_val;
877 host_dsi_control = HOST_DSI_CTRL_COMMON;
878 max_threshold = 0;
879 dcs_cmd = 0;
880
881 if (dsi->driven_mode == TEGRA_DSI_DRIVEN_BY_HOST) {
882 dsi_control |= DSI_CTRL_HOST_DRIVEN;
883 host_dsi_control |= HOST_DSI_CTRL_HOST_DRIVEN;
884 max_threshold = DSI_MAX_THRESHOLD_MAX_THRESHOLD(DSI_HOST_FIFO_DEPTH);
885 dsi->status.driven = DSI_DRIVEN_MODE_HOST;
886 } else {
887 dsi_control |= DSI_CTRL_DC_DRIVEN;
888 host_dsi_control |= HOST_DSI_CTRL_DC_DRIVEN;
889 max_threshold = DSI_MAX_THRESHOLD_MAX_THRESHOLD(DSI_VIDEO_FIFO_DEPTH);
890 dsi->status.driven = DSI_DRIVEN_MODE_DC;
891 }
892
893 if (dsi->info.video_data_type == TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE) {
894 dsi_control |= DSI_CTRL_CMD_MODE;
895 host_dsi_control |= HOST_DSI_CTRL_CMD_MODE;
896 dcs_cmd = DSI_DCS_CMDS_LT5_DCS_CMD(DSI_WRITE_MEMORY_START)|
897 DSI_DCS_CMDS_LT3_DCS_CMD(DSI_WRITE_MEMORY_CONTINUE);
898 dsi->status.vtype = DSI_VIDEO_TYPE_CMD_MODE;
899
900 } else {
901 dsi_control |= DSI_CTRL_VIDEO_MODE;
902 host_dsi_control |= HOST_DSI_CTRL_VIDEO_MODE;
903 dsi->status.vtype = DSI_VIDEO_TYPE_VIDEO_MODE;
904 }
905
906 tegra_dsi_writel(dsi, max_threshold, DSI_MAX_THRESHOLD);
907 tegra_dsi_writel(dsi, dcs_cmd, DSI_DCS_CMDS);
908 tegra_dsi_writel(dsi, dsi_control, DSI_CONTROL);
909 tegra_dsi_writel(dsi, host_dsi_control, DSI_HOST_DSI_CONTROL);
910}
911
912static int tegra_dsi_init_hw(struct tegra_dc *dc,
913 struct tegra_dc_dsi_data *dsi)
914{
915 u32 val;
916 u32 i;
917 int err;
918
919 tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz);
920
921 /* TODO: only need to change the timing for bta */
922 tegra_dsi_set_phy_timing(dsi);
923
924 err = gpio_request(TEGRA_GPIO_PJ1, "DSI TE");
925 if (err < 0)
926 goto fail;
927
928 err = gpio_direction_input(TEGRA_GPIO_PJ1);
929 if (err < 0) {
930 gpio_free(TEGRA_GPIO_PJ1);
931 goto fail;
932 }
933 tegra_gpio_enable(TEGRA_GPIO_PJ1);
934
935 if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
936 tegra_dsi_stop_dc_stream(dc, dsi);
937
938 /* Initializing DSI registers */
939 for (i = 0; i < ARRAY_SIZE(init_reg); i++) {
940 tegra_dsi_writel(dsi, 0, init_reg[i]);
941 }
942 tegra_dsi_writel(dsi, dsi->dsi_control_val, DSI_CONTROL);
943
944 val = DSI_PAD_CONTROL_PAD_PDIO(0) |
945 DSI_PAD_CONTROL_PAD_PDIO_CLK(0) |
946 DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_DISABLE);
947 tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL);
948
949 val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE);
950 tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
951
952 while (tegra_dsi_readl(dsi, DSI_POWER_CONTROL) != val) {
953 tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
954 }
955
956 dsi->status.init = DSI_MODULE_INIT;
957 dsi->status.lphs = DSI_LPHS_NOT_INIT;
958 dsi->status.vtype = DSI_VIDEO_TYPE_NOT_INIT;
959 dsi->status.driven = DSI_DRIVEN_MODE_NOT_INIT;
960 dsi->status.clk_out = DSI_PHYCLK_OUT_DIS;
961 dsi->status.clk_mode = DSI_PHYCLK_NOT_INIT;
962 dsi->status.clk_burst = DSI_CLK_BURST_NOT_INIT;
963fail:
964 return err;
965}
966
967static int tegra_dsi_set_to_lp_mode(struct tegra_dc *dc,
968 struct tegra_dc_dsi_data *dsi)
969{
970 int err;
971
972 if (dsi->status.init != DSI_MODULE_INIT) {
973 err = -EPERM;
974 goto fail;
975 }
976
977 if (dsi->status.lphs == DSI_LPHS_IN_LP_MODE)
978 goto success;
979
980 if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
981 tegra_dsi_stop_dc_stream(dc, dsi);
982
983 /* disable/enable hs clock according to enable_hs_clock_on_lp_cmd_mode */
984 if ((dsi->status.clk_out == DSI_PHYCLK_OUT_EN) &&
985 (!dsi->info.enable_hs_clock_on_lp_cmd_mode))
986 tegra_dsi_hs_clk_out_disable(dc, dsi);
987
988 if (dsi->current_dsi_clk_khz != dsi->target_lp_clk_khz){
989 tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz);
990 tegra_dsi_set_timeout(dsi);
991 }
992
993 tegra_dsi_set_control_reg_lp(dsi);
994
995 if ((dsi->status.clk_out == DSI_PHYCLK_OUT_DIS) &&
996 (dsi->info.enable_hs_clock_on_lp_cmd_mode))
997 tegra_dsi_hs_clk_out_enable_in_lp(dsi);
998
999success:
1000 dsi->status.lphs = DSI_LPHS_IN_LP_MODE;
1001 err = 0;
1002fail:
1003 return err;
1004}
1005
1006static int tegra_dsi_set_to_hs_mode(struct tegra_dc *dc,
1007 struct tegra_dc_dsi_data *dsi)
1008{
1009 int err;
1010
1011 if (dsi->status.init != DSI_MODULE_INIT) {
1012 err = -EPERM;
1013 goto fail;
1014 }
1015
1016 if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
1017 tegra_dsi_stop_dc_stream(dc, dsi);
1018
1019 if ((dsi->status.clk_out == DSI_PHYCLK_OUT_EN) &&
1020 (!dsi->info.enable_hs_clock_on_lp_cmd_mode))
1021 tegra_dsi_hs_clk_out_disable(dc, dsi);
1022
1023 if (dsi->current_dsi_clk_khz != dsi->target_hs_clk_khz) {
1024 tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_hs_clk_khz);
1025 tegra_dsi_set_timeout(dsi);
1026 }
1027
1028 tegra_dsi_set_phy_timing(dsi);
1029
1030 if (dsi->driven_mode == TEGRA_DSI_DRIVEN_BY_DC){
1031 tegra_dsi_set_pkt_seq(dc, dsi);
1032 tegra_dsi_set_pkt_length(dc, dsi);
1033 tegra_dsi_set_sol_delay(dc, dsi);
1034 tegra_dsi_set_dc_clk(dc, dsi);
1035 }
1036
1037 tegra_dsi_set_control_reg_hs(dsi);
1038
1039 if (dsi->status.clk_out == DSI_PHYCLK_OUT_DIS)
1040 tegra_dsi_hs_clk_out_enable(dsi);
1041
1042 dsi->status.lphs = DSI_LPHS_IN_HS_MODE;
1043 err = 0;
1044fail:
1045 return err;
1046}
1047
1048static bool tegra_dsi_is_controller_idle(struct tegra_dc_dsi_data *dsi)
1049{
1050 u32 timeout = 0;
1051 bool retVal;
1052
1053 retVal = false;
1054 while (timeout <= DSI_MAX_COMMAND_DELAY_USEC) {
1055 if (!tegra_dsi_readl(dsi, DSI_TRIGGER)) {
1056 retVal = true;
1057 break;
1058 }
1059 udelay(DSI_COMMAND_DELAY_STEPS_USEC);
1060 timeout += DSI_COMMAND_DELAY_STEPS_USEC;
1061 }
1062
1063 return retVal;
1064}
1065
1066static bool tegra_dsi_host_trigger(struct tegra_dc_dsi_data *dsi)
1067{
1068 bool status;
1069
1070 status = false;
1071 if (tegra_dsi_readl(dsi, DSI_TRIGGER))
1072 goto fail;
1073
1074 tegra_dsi_writel(dsi, DSI_TRIGGER_HOST_TRIGGER(TEGRA_DSI_ENABLE),
1075 DSI_TRIGGER);
1076
1077#if DSI_USE_SYNC_POINTS
1078 /* TODO: Implement sync point */
1079#else
1080 status = tegra_dsi_is_controller_idle(dsi);
1081#endif
1082
1083fail:
1084 return status;
1085}
1086
1087static int tegra_dsi_read_data(struct tegra_dc *dc,
1088 struct tegra_dc_dsi_data *dsi)
1089{
1090 /* TODO: implement DSI read */
1091 return ENXIO;
1092}
1093
1094static int tegra_dsi_write_data(struct tegra_dc *dc,
1095 struct tegra_dc_dsi_data *dsi,
1096 u8* pdata, u8 data_id, u16 data_len)
1097{
1098 bool switch_back_to_hs_mode;
1099 bool switch_back_to_dc_mode;
1100 u32 val;
1101 u8 *pval;
1102 int err;
1103 u8 virtua_channel;
1104
1105 err = 0;
1106 switch_back_to_hs_mode = false;
1107 switch_back_to_dc_mode = false;
1108
1109 if ((dsi->status.init != DSI_MODULE_INIT) ||
1110 (dsi->status.lphs == DSI_LPHS_NOT_INIT)) {
1111 err = -EPERM;
1112 goto fail;
1113 }
1114
1115 if (!tegra_dsi_is_controller_idle(dsi)) {
1116 err = -EBUSY;
1117 goto fail;
1118 }
1119
1120 err = 0;
1121
1122 if (dsi->status.lphs == DSI_LPHS_IN_HS_MODE) {
1123 if (dsi->info.hs_cmd_mode_supported) {
1124 if (dsi->status.driven == DSI_DRIVEN_MODE_DC) {
1125 dsi->driven_mode = TEGRA_DSI_DRIVEN_BY_HOST;
1126 tegra_dsi_set_to_hs_mode(dc, dsi);
1127 switch_back_to_dc_mode = true;
1128 }
1129 } else {
1130 tegra_dsi_set_to_lp_mode(dc, dsi);
1131 switch_back_to_hs_mode = true;
1132 }
1133 }
1134
1135 virtua_channel = dsi->info.virtual_channel << DSI_VIR_CHANNEL_BIT_POSITION;
1136
1137 /* always use hw for ecc */
1138 val = (virtua_channel | data_id) << 0 |
1139 data_len << 8;
1140 tegra_dsi_writel(dsi, val, DSI_WR_DATA);
1141
1142 /* if pdata != NULL, pkt type is long pkt */
1143 if (pdata != NULL) {
1144 while (data_len) {
1145 if (data_len >= 4) {
1146 val = ((u32*) pdata)[0];
1147 data_len -= 4;
1148 pdata += 4;
1149 } else {
1150 val = 0;
1151 pval = (u8*) &val;
1152 do
1153 *pval++ = *pdata++;
1154 while(--data_len);
1155 }
1156 tegra_dsi_writel(dsi, val, DSI_WR_DATA);
1157 }
1158 }
1159
1160 if (!tegra_dsi_host_trigger(dsi))
1161 err = -EIO;
1162
1163 if (switch_back_to_dc_mode)
1164 dsi->driven_mode = TEGRA_DSI_DRIVEN_BY_DC;
1165 if (switch_back_to_dc_mode || switch_back_to_hs_mode)
1166 tegra_dsi_set_to_hs_mode(dc, dsi);
1167
1168fail:
1169 return err;
1170}
1171
1172static int tegra_dsi_init_panel(struct tegra_dc *dc,
1173 struct tegra_dc_dsi_data *dsi)
1174{
1175 u32 i;
1176 int err;
1177
1178 err = 0;
1179 for (i = 0; i < dsi->info.n_init_cmd; i++) {
1180 struct tegra_dsi_cmd *cur_cmd;
1181 cur_cmd = &dsi->info.dsi_init_cmd[i];
1182
1183 if (cur_cmd->cmd_type == TEGRA_DSI_DELAY_MS)
1184 mdelay(cur_cmd->sp_len_dly.delay_ms);
1185 else {
1186 err = tegra_dsi_write_data(dc, dsi,
1187 cur_cmd->pdata,
1188 cur_cmd->data_id,
1189 cur_cmd->sp_len_dly.data_len);
1190 if (err < 0)
1191 break;
1192 }
1193 }
1194 return err;
1195}
1196
1197static void tegra_dc_dsi_enable(struct tegra_dc *dc)
1198{
1199 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
1200 int err;
1201
1202 tegra_dc_io_start(dc);
1203 mutex_lock(&dsi->lock);
1204
1205 err = tegra_dsi_init_hw(dc, dsi);
1206 if (err < 0) {
1207 dev_err(&dc->ndev->dev, "dsi: not able to init dsi hardware\n");
1208 return;
1209 }
1210
1211 err = tegra_dsi_set_to_lp_mode(dc, dsi);
1212 if (err < 0) {
1213 dev_err(&dc->ndev->dev, "dsi: not able to set to lp mode\n");
1214 return;
1215 }
1216
1217 err = tegra_dsi_init_panel(dc, dsi);
1218 if (err < 0) {
1219 dev_err(&dc->ndev->dev, "dsi: error while sending dsi cmd\n");
1220 return;
1221 }
1222
1223 err = tegra_dsi_set_to_hs_mode(dc, dsi);
1224 if (err < 0) {
1225 dev_err(&dc->ndev->dev,
1226 "dsi: not able to set to hs mode\n");
1227 return;
1228 }
1229
1230 if (dsi->status.driven == DSI_DRIVEN_MODE_DC) {
1231 tegra_dsi_start_dc_stream(dc, dsi);
1232 }
1233
1234 mutex_unlock(&dsi->lock);
1235 tegra_dc_io_end(dc);
1236}
1237
1238static void _tegra_dc_dsi_init(struct tegra_dc *dc)
1239{
1240 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
1241
1242 tegra_dsi_init_sw(dc, dsi);
1243 /* TODO: Configure the CSI pad configuration */
1244}
1245
1246static int tegra_dc_dsi_cp_init_cmd(struct tegra_dsi_cmd* src,
1247 struct tegra_dsi_cmd* dst, u16 n_cmd)
1248{
1249 u16 i;
1250 u16 len;
1251
1252 memcpy(dst, src, sizeof(*dst) * n_cmd);
1253
1254 for (i = 0; i < n_cmd; i++)
1255 if (src[i].pdata) {
1256 len = sizeof(*src[i].pdata) * src[i].sp_len_dly.data_len;
1257 dst[i].pdata = kzalloc(len, GFP_KERNEL);
1258 if (!dst[i].pdata)
1259 goto free_cmd_pdata;
1260 memcpy(dst[i].pdata, src[i].pdata, len);
1261 }
1262
1263 return 0;
1264
1265free_cmd_pdata:
1266 for (--i; i >=0; i--)
1267 if (dst[i].pdata)
1268 kfree(dst[i].pdata);
1269 return -ENOMEM;
1270}
1271
1272static int tegra_dc_dsi_cp_info(struct tegra_dc_dsi_data* dsi,
1273 struct tegra_dsi_out* p_dsi)
1274{
1275 struct tegra_dsi_cmd* pcmd;
1276 int err;
1277
1278 pcmd = kzalloc(sizeof(*pcmd) * p_dsi->n_init_cmd, GFP_KERNEL);
1279 if (!pcmd)
1280 return -ENOMEM;
1281
1282 if (p_dsi->n_data_lanes > MAX_DSI_DATA_LANES) {
1283 err = -EINVAL;
1284 goto err_free_pcmd;
1285 }
1286
1287 memcpy(&dsi->info, p_dsi, sizeof(dsi->info));
1288
1289 err = tegra_dc_dsi_cp_init_cmd(p_dsi->dsi_init_cmd,
1290 pcmd, p_dsi->n_init_cmd);
1291 if (err < 0)
1292 goto err_free_pcmd;
1293
1294 dsi->info.dsi_init_cmd = pcmd;
1295
1296 if (!dsi->info.panel_reset_timeout_msec)
1297 dsi->info.panel_reset_timeout_msec = DEFAULT_PANEL_RESET_TIMEOUT;
1298
1299 if (!dsi->info.panel_buffer_size_byte)
1300 dsi->info.panel_buffer_size_byte = DEFAULT_PANEL_BUFFER_BYTE;
1301
1302 if (!dsi->info.max_panel_freq_khz)
1303 dsi->info.max_panel_freq_khz = DEFAULT_MAX_DSI_PHY_CLK_KHZ;
1304
1305 if (!dsi->info.lp_cmd_mode_freq_khz)
1306 dsi->info.lp_cmd_mode_freq_khz = DEFAULT_LP_CMD_MODE_CLK_KHZ;
1307
1308 dsi->controller_index = 0;
1309
1310 /* host mode is for testing only*/
1311 dsi->driven_mode = TEGRA_DSI_DRIVEN_BY_DC;
1312
1313 return 0;
1314
1315err_free_pcmd:
1316 kfree(pcmd);
1317 return err;
1318}
1319
1320static int tegra_dc_dsi_init(struct tegra_dc *dc)
1321{
1322 struct tegra_dc_dsi_data *dsi;
1323 struct resource *res;
1324 struct resource *base_res;
1325 void __iomem *base;
1326 struct clk *dc_clk = NULL;
1327 struct clk *dsi_clk = NULL;
1328 int err;
1329
1330 err = 0;
1331
1332 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
1333 if (!dsi)
1334 return -ENOMEM;
1335
1336 res = nvhost_get_resource_byname(dc->ndev, IORESOURCE_MEM,
1337 "dsi_regs");
1338 if (!res) {
1339 dev_err(&dc->ndev->dev, "dsi: no mem resource\n");
1340 err = -ENOENT;
1341 goto err_free_dsi;
1342 }
1343
1344 base_res = request_mem_region(res->start, resource_size(res),
1345 dc->ndev->name);
1346 if (!base_res) {
1347 dev_err(&dc->ndev->dev, "dsi: request_mem_region failed\n");
1348 err = -EBUSY;
1349 goto err_free_dsi;
1350 }
1351
1352 base = ioremap(res->start, resource_size(res));
1353 if (!base) {
1354 dev_err(&dc->ndev->dev, "dsi: registers can't be mapped\n");
1355 err = -EBUSY;
1356 goto err_release_regs;
1357 }
1358
1359 dsi_clk = clk_get(&dc->ndev->dev, "dsi");
1360 if (IS_ERR_OR_NULL(dsi_clk)) {
1361 dev_err(&dc->ndev->dev, "dsi: can't get clock\n");
1362 err = -EBUSY;
1363 goto err_release_regs;
1364 }
1365
1366 dc_clk = clk_get_sys(dev_name(&dc->ndev->dev), NULL);
1367 if (IS_ERR_OR_NULL(dc_clk)) {
1368 dev_err(&dc->ndev->dev, "dsi: dc clock %s unavailable\n",
1369 dev_name(&dc->ndev->dev));
1370 err = -EBUSY;
1371 goto err_clk_put;
1372 }
1373
1374 if (!dc->pdata->default_out->dsi) {
1375 dev_err(&dc->ndev->dev, "dsi: dsi data not available\n");
1376 goto err_dsi_data;
1377 }
1378
1379 err = tegra_dc_dsi_cp_info(dsi, dc->pdata->default_out->dsi);
1380 if (err < 0)
1381 goto err_dsi_data;
1382
1383 mutex_init(&dsi->lock);
1384 dsi->dc = dc;
1385 dsi->base = base;
1386 dsi->base_res = base_res;
1387 dsi->dc_clk = dc_clk;
1388 dsi->dsi_clk = dsi_clk;
1389
1390 tegra_dc_set_outdata(dc, dsi);
1391 _tegra_dc_dsi_init(dc);
1392
1393 return 0;
1394
1395err_dsi_data:
1396err_clk_put:
1397 clk_put(dsi->dsi_clk);
1398err_release_regs:
1399 release_resource(base_res);
1400err_free_dsi:
1401 kfree(dsi);
1402
1403 return err;
1404}
1405
1406static void tegra_dc_dsi_destroy(struct tegra_dc *dc)
1407{
1408 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
1409 u16 i;
1410 u32 val;
1411
1412 mutex_lock(&dsi->lock);
1413
1414 /* free up the pdata*/
1415 for(i = 0; i < dsi->info.n_init_cmd; i++){
1416 if(dsi->info.dsi_init_cmd[i].pdata)
1417 kfree(dsi->info.dsi_init_cmd[i].pdata);
1418 }
1419 kfree(dsi->info.dsi_init_cmd);
1420
1421 /* Disable dc stream*/
1422 if(dsi->status.driven == DSI_DRIVEN_MODE_DC)
1423 tegra_dsi_stop_dc_stream(dc, dsi);
1424
1425 /* Disable dsi phy clock*/
1426 if(dsi->status.clk_out == DSI_PHYCLK_OUT_EN)
1427 tegra_dsi_hs_clk_out_disable(dc, dsi);
1428
1429 val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
1430 tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
1431
1432 iounmap(dsi->base);
1433 release_resource(dsi->base_res);
1434
1435 clk_put(dsi->dc_clk);
1436 clk_put(dsi->dsi_clk);
1437
1438 mutex_unlock(&dsi->lock);
1439
1440 mutex_destroy(&dsi->lock);
1441 kfree(dsi);
1442}
1443
1444static void tegra_dc_dsi_disable(struct tegra_dc *dc)
1445{
1446 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
1447
1448 mutex_lock(&dsi->lock);
1449
1450 if (dsi->status.driven == DSI_DRIVEN_MODE_DC)
1451 tegra_dsi_stop_dc_stream(dc, dsi);
1452
1453 if (dsi->status.clk_out == DSI_PHYCLK_OUT_EN)
1454 tegra_dsi_hs_clk_out_disable(dc, dsi);
1455
1456 mutex_unlock(&dsi->lock);
1457
1458 dev_err(&dc->ndev->dev, "dsi: disable\n");
1459}
1460
1461struct tegra_dc_out_ops tegra_dc_dsi_ops = {
1462 .init = tegra_dc_dsi_init,
1463 .destroy = tegra_dc_dsi_destroy,
1464 .enable = tegra_dc_dsi_enable,
1465 .disable = tegra_dc_dsi_disable,
1466};