summaryrefslogtreecommitdiffstats
path: root/drivers/video
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
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')
-rw-r--r--drivers/video/tegra/dc/Makefile1
-rw-r--r--drivers/video/tegra/dc/dc.c21
-rw-r--r--drivers/video/tegra/dc/dc_priv.h1
-rw-r--r--drivers/video/tegra/dc/dc_reg.h13
-rw-r--r--drivers/video/tegra/dc/dsi.c1466
-rw-r--r--drivers/video/tegra/dc/dsi.h272
-rw-r--r--drivers/video/tegra/dc/dsi_regs.h336
7 files changed, 2109 insertions, 1 deletions
diff --git a/drivers/video/tegra/dc/Makefile b/drivers/video/tegra/dc/Makefile
index 8ab906465..db675fd82 100644
--- a/drivers/video/tegra/dc/Makefile
+++ b/drivers/video/tegra/dc/Makefile
@@ -3,4 +3,5 @@ obj-y += rgb.o
3obj-y += hdmi.o 3obj-y += hdmi.o
4obj-y += nvhdcp.o 4obj-y += nvhdcp.o
5obj-y += edid.o 5obj-y += edid.o
6obj-$(CONFIG_TEGRA_DSI) += dsi.o
6obj-$(CONFIG_TEGRA_OVERLAY) += overlay.o 7obj-$(CONFIG_TEGRA_OVERLAY) += overlay.o
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 29f572b76..88e6a0c32 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -743,6 +743,21 @@ void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
743 clk_set_parent(clk, pll_d_out0_clk); 743 clk_set_parent(clk, pll_d_out0_clk);
744 } 744 }
745 745
746 if (dc->out->type == TEGRA_DC_OUT_DSI) {
747 unsigned long rate;
748 struct clk *pll_d_out0_clk =
749 clk_get_sys(NULL, "pll_d_out0");
750 struct clk *pll_d_clk =
751 clk_get_sys(NULL, "pll_d");
752
753 rate = dc->mode.pclk;
754 if (rate != clk_get_rate(pll_d_clk))
755 clk_set_rate(pll_d_clk, rate);
756
757 if (clk_get_parent(clk) != pll_d_out0_clk)
758 clk_set_parent(clk, pll_d_out0_clk);
759 }
760
746 pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk); 761 pclk = tegra_dc_pclk_round_rate(dc, dc->mode.pclk);
747 tegra_dvfs_set_rate(clk, pclk); 762 tegra_dvfs_set_rate(clk, pclk);
748} 763}
@@ -935,7 +950,11 @@ static void tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
935 case TEGRA_DC_OUT_HDMI: 950 case TEGRA_DC_OUT_HDMI:
936 dc->out_ops = &tegra_dc_hdmi_ops; 951 dc->out_ops = &tegra_dc_hdmi_ops;
937 break; 952 break;
938 953#ifdef CONFIG_TEGRA_DSI
954 case TEGRA_DC_OUT_DSI:
955 dc->out_ops = &tegra_dc_dsi_ops;
956 break;
957#endif
939 default: 958 default:
940 dc->out_ops = NULL; 959 dc->out_ops = NULL;
941 break; 960 break;
diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h
index ec7e4f450..2042310c1 100644
--- a/drivers/video/tegra/dc/dc_priv.h
+++ b/drivers/video/tegra/dc/dc_priv.h
@@ -142,5 +142,6 @@ void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk);
142 142
143extern struct tegra_dc_out_ops tegra_dc_rgb_ops; 143extern struct tegra_dc_out_ops tegra_dc_rgb_ops;
144extern struct tegra_dc_out_ops tegra_dc_hdmi_ops; 144extern struct tegra_dc_out_ops tegra_dc_hdmi_ops;
145extern struct tegra_dc_out_ops tegra_dc_dsi_ops;
145 146
146#endif 147#endif
diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h
index 7347352a0..11bce9a4e 100644
--- a/drivers/video/tegra/dc/dc_reg.h
+++ b/drivers/video/tegra/dc/dc_reg.h
@@ -32,6 +32,14 @@
32#define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a 32#define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a
33#define DC_CMD_CONT_SYNCPT_VSYNC 0x028 33#define DC_CMD_CONT_SYNCPT_VSYNC 0x028
34#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 34#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
35#define MSF_POLARITY_HIGH (0 << 0)
36#define MSF_POLARITY_LOW (1 << 0)
37#define MSF_DISABLE (0 << 1)
38#define MSF_ENABLE (1 << 1)
39#define MSF_LSPI (0 << 2)
40#define MSF_LDC (1 << 2)
41#define MSF_LSDI (2 << 2)
42
35#define DC_CMD_DISPLAY_COMMAND 0x032 43#define DC_CMD_DISPLAY_COMMAND 0x032
36#define DISP_COMMAND_RAISE (1 << 0) 44#define DISP_COMMAND_RAISE (1 << 0)
37#define DISP_CTRL_MODE_STOP (0 << 5) 45#define DISP_CTRL_MODE_STOP (0 << 5)
@@ -93,6 +101,7 @@
93#define WIN_A_UPDATE (1 << 9) 101#define WIN_A_UPDATE (1 << 9)
94#define WIN_B_UPDATE (1 << 10) 102#define WIN_B_UPDATE (1 << 10)
95#define WIN_C_UPDATE (1 << 11) 103#define WIN_C_UPDATE (1 << 11)
104#define NC_HOST_TRIG (1 << 24)
96 105
97#define DC_CMD_DISPLAY_WINDOW_HEADER 0x042 106#define DC_CMD_DISPLAY_WINDOW_HEADER 0x042
98#define WINDOW_A_SELECT (1 << 4) 107#define WINDOW_A_SELECT (1 << 4)
@@ -107,6 +116,8 @@
107#define DC_COM_PIN_OUTPUT_ENABLE1 0x303 116#define DC_COM_PIN_OUTPUT_ENABLE1 0x303
108#define DC_COM_PIN_OUTPUT_ENABLE2 0x304 117#define DC_COM_PIN_OUTPUT_ENABLE2 0x304
109#define DC_COM_PIN_OUTPUT_ENABLE3 0x305 118#define DC_COM_PIN_OUTPUT_ENABLE3 0x305
119#define PIN_OUTPUT_LSPI_OUTPUT_EN (1 << 8)
120#define PIN_OUTPUT_LSPI_OUTPUT_DIS (1 << 8)
110#define DC_COM_PIN_OUTPUT_POLARITY0 0x306 121#define DC_COM_PIN_OUTPUT_POLARITY0 0x306
111 122
112#define DC_COM_PIN_OUTPUT_POLARITY1 0x307 123#define DC_COM_PIN_OUTPUT_POLARITY1 0x307
@@ -127,6 +138,8 @@
127#define DC_COM_PIN_INPUT_ENABLE1 0x30f 138#define DC_COM_PIN_INPUT_ENABLE1 0x30f
128#define DC_COM_PIN_INPUT_ENABLE2 0x310 139#define DC_COM_PIN_INPUT_ENABLE2 0x310
129#define DC_COM_PIN_INPUT_ENABLE3 0x311 140#define DC_COM_PIN_INPUT_ENABLE3 0x311
141#define PIN_INPUT_LSPI_INPUT_EN (1 << 8)
142#define PIN_INPUT_LSPI_INPUT_DIS (1 << 8)
130#define DC_COM_PIN_INPUT_DATA0 0x312 143#define DC_COM_PIN_INPUT_DATA0 0x312
131#define DC_COM_PIN_INPUT_DATA1 0x313 144#define DC_COM_PIN_INPUT_DATA1 0x313
132#define DC_COM_PIN_OUTPUT_SELECT0 0x314 145#define DC_COM_PIN_OUTPUT_SELECT0 0x314
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};
diff --git a/drivers/video/tegra/dc/dsi.h b/drivers/video/tegra/dc/dsi.h
new file mode 100644
index 000000000..dbbb35731
--- /dev/null
+++ b/drivers/video/tegra/dc/dsi.h
@@ -0,0 +1,272 @@
1/*
2 * drivers/video/tegra/dc/dsi.h
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#ifndef __DRIVERS_VIDEO_TEGRA_DC_DSI_H__
18#define __DRIVERS_VIDEO_TEGRA_DC_DSI_H__
19
20/* source of video data */
21enum{
22 TEGRA_DSI_VIDEO_DRIVEN_BY_DC,
23 TEGRA_DSI_VIDEO_DRIVEN_BY_HOST,
24};
25
26/* Max number of data lanes supported */
27#define MAX_DSI_DATA_LANES 2
28/* Default Peripheral reset timeout */
29#define DSI_PR_TO_VALUE 0x2000
30
31/* DCS commands for command mode */
32#define DSI_ENTER_PARTIAL_MODE 0x12
33#define DSI_SET_PIXEL_FORMAT 0x3A
34#define DSI_AREA_COLOR_MODE 0x4C
35#define DSI_SET_PARTIAL_AREA 0x30
36#define DSI_SET_PAGE_ADDRESS 0x2B
37#define DSI_SET_ADDRESS_MODE 0x36
38#define DSI_SET_COLUMN_ADDRESS 0x2A
39#define DSI_WRITE_MEMORY_START 0x2C
40#define DSI_WRITE_MEMORY_CONTINUE 0x3C
41#define DSI_MAX_COMMAND_DELAY_USEC 250000
42#define DSI_COMMAND_DELAY_STEPS_USEC 10
43
44/* End of Transmit command for HS mode */
45#define DSI_CMD_HS_EOT_PACKAGE 0x000F0F08
46
47/* Delay required after issuing the trigger*/
48#define DSI_COMMAND_COMPLETION_DELAY_USEC 5
49
50#define DSI_DELAY_FOR_READ_FIFO 5
51
52/* Dsi virtual channel bit position, refer to the DSI specs */
53#define DSI_VIR_CHANNEL_BIT_POSITION 6
54
55/* DSI packet commands from Host to peripherals */
56enum {
57 dsi_command_v_sync_start = 0x01,
58 dsi_command_v_sync_end = 0x11,
59 dsi_command_h_sync_start = 0x21,
60 dsi_command_h_sync_end = 0x31,
61 dsi_command_end_of_transaction = 0x08,
62 dsi_command_blanking = 0x19,
63 dsi_command_null_packet = 0x09,
64 dsi_command_h_active_length_16bpp = 0x0E,
65 dsi_command_h_active_length_18bpp = 0x1E,
66 dsi_command_h_active_length_18bpp_np = 0x2E,
67 dsi_command_h_active_length_24bpp = 0x3E,
68 dsi_command_h_sync_active = dsi_command_blanking,
69 dsi_command_h_back_porch = dsi_command_blanking,
70 dsi_command_h_front_porch = dsi_command_blanking,
71 dsi_command_writ_no_param = 0x05,
72 dsi_command_long_write = 0x39,
73 dsi_command_max_return_pkt_size = 0x37,
74 dsi_command_generic_read_request_with_2_param = 0x24,
75 dsi_command_dcs_read_with_no_params = 0x06,
76};
77
78/* Maximum polling time for reading the dsi status register */
79#define DSI_STATUS_POLLING_DURATION_USEC 100000
80#define DSI_STATUS_POLLING_DELAY_USEC 100
81
82/*
83 * Horizontal Sync Blank Packet Over head
84 * DSI_overhead = size_of(HS packet header)
85 * + size_of(BLANK packet header) + size_of(checksum)
86 * DSI_overhead = 4 + 4 + 2 = 10
87 */
88#define DSI_HSYNC_BLNK_PKT_OVERHEAD 10
89
90/*
91 * Horizontal Front Porch Packet Overhead
92 * DSI_overhead = size_of(checksum)
93 * + size_of(BLANK packet header) + size_of(checksum)
94 * DSI_overhead = 2 + 4 + 2 = 8
95 */
96#define DSI_HFRONT_PORCH_PKT_OVERHEAD 8
97
98/*
99 * Horizontal Back Porch Packet
100 * DSI_overhead = size_of(HE packet header)
101 * + size_of(BLANK packet header) + size_of(checksum)
102 * + size_of(RGB packet header)
103 * DSI_overhead = 4 + 4 + 2 + 4 = 14
104 */
105#define DSI_HBACK_PORCH_PKT_OVERHEAD 14
106
107/* Additional Hs TX timeout margin */
108#define DSI_HTX_TO_MARGIN 720
109
110#define DSI_CYCLE_COUNTER_VALUE 512
111
112#define DSI_LRXH_TO_VALUE 0x2000
113
114/* Turn around timeout terminal count */
115#define DSI_TA_TO_VALUE 0x2000
116
117/* Turn around timeout tally */
118#define DSI_TA_TALLY_VALUE 0x0
119/* LP Rx timeout tally */
120#define DSI_LRXH_TALLY_VALUE 0x0
121/* HS Tx Timeout tally */
122#define DSI_HTX_TALLY_VALUE 0x0
123
124/* DSI Power control settle time 10 micro seconds */
125#define DSI_POWER_CONTROL_SETTLE_TIME_US 10
126
127#define DSI_HOST_FIFO_DEPTH 64
128#define DSI_VIDEO_FIFO_DEPTH 480
129#define DSI_READ_FIFO_DEPTH (32 << 2)
130
131#define NUMOF_BIT_PER_BYTE 8
132#define DEFAULT_LP_CMD_MODE_CLK_KHZ 10000
133#define DEFAULT_MAX_DSI_PHY_CLK_KHZ (500*1000)
134#define DEFAULT_PANEL_RESET_TIMEOUT 2
135#define DEFAULT_PANEL_BUFFER_BYTE 512
136
137/*
138 * TODO: are DSI_HOST_DSI_CONTROL_CRC_RESET(RESET_CRC) and
139 * DSI_HOST_DSI_CONTROL_HOST_TX_TRIG_SRC(IMMEDIATE) required for everyone?
140 */
141#define HOST_DSI_CTRL_COMMON \
142 (DSI_HOST_DSI_CONTROL_PHY_CLK_DIV(DSI_PHY_CLK_DIV1) | \
143 DSI_HOST_DSI_CONTROL_ULTRA_LOW_POWER(NORMAL) | \
144 DSI_HOST_DSI_CONTROL_PERIPH_RESET(TEGRA_DSI_DISABLE) | \
145 DSI_HOST_DSI_CONTROL_RAW_DATA(TEGRA_DSI_DISABLE) | \
146 DSI_HOST_DSI_CONTROL_IMM_BTA(TEGRA_DSI_DISABLE) | \
147 DSI_HOST_DSI_CONTROL_PKT_BTA(TEGRA_DSI_DISABLE) | \
148 DSI_HOST_DSI_CONTROL_CS_ENABLE(TEGRA_DSI_ENABLE) | \
149 DSI_HOST_DSI_CONTROL_ECC_ENABLE(TEGRA_DSI_ENABLE))
150
151#define HOST_DSI_CTRL_HOST_DRIVEN \
152 (DSI_HOST_DSI_CONTROL_CRC_RESET(RESET_CRC) | \
153 DSI_HOST_DSI_CONTROL_HOST_TX_TRIG_SRC(IMMEDIATE) | \
154 DSI_HOST_DSI_CONTROL_PKT_WR_FIFO_SEL(HOST_ONLY))
155
156#define HOST_DSI_CTRL_DC_DRIVEN 0
157
158#define HOST_DSI_CTRL_VIDEO_MODE \
159 (DSI_HOST_DSI_CONTROL_PKT_WR_FIFO_SEL(VIDEO_HOST))
160
161#define HOST_DSI_CTRL_CMD_MODE \
162 (DSI_HOST_DSI_CONTROL_PKT_WR_FIFO_SEL(HOST_ONLY))
163
164
165#define DSI_CTRL_HOST_DRIVEN (DSI_CONTROL_VID_ENABLE(TEGRA_DSI_DISABLE) | \
166 DSI_CONTROL_HOST_ENABLE(TEGRA_DSI_ENABLE))
167
168#define DSI_CTRL_DC_DRIVEN (DSI_CONTROL_VID_TX_TRIG_SRC(SOL) | \
169 DSI_CONTROL_VID_ENABLE(TEGRA_DSI_ENABLE) | \
170 DSI_CONTROL_HOST_ENABLE(TEGRA_DSI_DISABLE))
171
172#define DSI_CTRL_CMD_MODE (DSI_CONTROL_VID_DCS_ENABLE(TEGRA_DSI_ENABLE))
173
174#define DSI_CTRL_VIDEO_MODE (DSI_CONTROL_VID_DCS_ENABLE(TEGRA_DSI_DISABLE))
175
176
177enum {
178 CMD_VS = 0x01,
179 CMD_VE = 0x11,
180
181 CMD_HS = 0x21,
182 CMD_HE = 0x31,
183
184 CMD_EOT = 0x08,
185 CMD_NULL = 0x09,
186 CMD_BLNK = 0x19,
187 CMD_LONGW = 0x39,
188
189 CMD_RGB = 0x00,
190 CMD_RGB_16BPP = 0x0E,
191 CMD_RGB_18BPP = 0x1E,
192 CMD_RGB_18BPPNP = 0x2E,
193 CMD_RGB_24BPP = 0x3E,
194};
195
196#define PKT_ID0(id) DSI_PKT_SEQ_0_LO_PKT_00_ID(id) | \
197 DSI_PKT_SEQ_1_LO_PKT_10_EN(TEGRA_DSI_ENABLE)
198#define PKT_LEN0(len) DSI_PKT_SEQ_0_LO_PKT_00_SIZE(len)
199
200#define PKT_ID1(id) DSI_PKT_SEQ_0_LO_PKT_01_ID(id) | \
201 DSI_PKT_SEQ_1_LO_PKT_11_EN(TEGRA_DSI_ENABLE)
202#define PKT_LEN1(len) DSI_PKT_SEQ_0_LO_PKT_01_SIZE(len)
203
204#define PKT_ID2(id) DSI_PKT_SEQ_0_LO_PKT_02_ID(id) | \
205 DSI_PKT_SEQ_1_LO_PKT_12_EN(TEGRA_DSI_ENABLE)
206#define PKT_LEN2(len) DSI_PKT_SEQ_0_LO_PKT_02_SIZE(len)
207
208#define PKT_ID3(id) DSI_PKT_SEQ_0_HI_PKT_03_ID(id) | \
209 DSI_PKT_SEQ_1_HI_PKT_13_EN(TEGRA_DSI_ENABLE)
210#define PKT_LEN3(len) DSI_PKT_SEQ_0_HI_PKT_03_SIZE(len)
211
212#define PKT_ID4(id) DSI_PKT_SEQ_0_HI_PKT_04_ID(id) | \
213 DSI_PKT_SEQ_1_HI_PKT_14_EN(TEGRA_DSI_ENABLE)
214#define PKT_LEN4(len) DSI_PKT_SEQ_0_HI_PKT_04_SIZE(len)
215
216#define PKT_ID5(id) DSI_PKT_SEQ_0_HI_PKT_05_ID(id) | \
217 DSI_PKT_SEQ_1_HI_PKT_15_EN(TEGRA_DSI_ENABLE)
218#define PKT_LEN5(len) DSI_PKT_SEQ_0_HI_PKT_05_SIZE(len)
219
220#define PKT_LP DSI_PKT_SEQ_0_LO_SEQ_0_FORCE_LP(TEGRA_DSI_ENABLE)
221
222#define NUMOF_PKT_SEQ 12
223
224
225/* Macros for calculating the phy timings */
226#define T_HSEXIT_DEFAULT(clkns) (100 / ((clkns) * 8) + 1)
227#define T_HSTRAIL_DEFAULT(clkns) (3 + max((8 * (clkns)), \
228 (60 + 4 * (clkns))) / ((clkns) * 8) + 1)
229#define T_HSPREPR_ORG(clkns) ((65 + 5 * (clkns)) / ((clkns) * 8))
230#define T_HSPREPR_DEFAULT(clkns) ((T_HSPREPR_ORG(clkns) == 0) ? \
231 1 : T_HSPREPR_ORG(clkns))
232#define T_DATZERO_DEFAULT(clkns) ((145 + 5 * (clkns)) / ((clkns) * 8) +1)
233
234#define T_CLKTRAIL_DEFAULT(clkns) (60 / ((clkns) * 8) + 1)
235#define T_CLKPOST_DEFAULT(clkns) ((60 + 52 * (clkns)) / ((clkns) * 8) +1)
236#define T_CLKZERO_DEFAULT(clkns) (170 / ((clkns) * 8) + 1)
237#define T_TLPX_ORG(clkns) (50 / ((clkns) * 8) + 1)
238#define T_TLPX_DEFAULT(clkns) ((T_TLPX_ORG(clkns) == 0) ? \
239 1 : T_TLPX_ORG(clkns))
240
241#define T_CLKPRE_DEFAULT(clkns) 1
242#define T_CLKPREPARE_DEFAULT(clkns) 4
243
244/* Minimum ULPM wakeup time as per the spec is 1msec */
245#define T_WAKEUP_DEFAULT(clkns) (2*1000*1000 / (clkns))
246
247#define DSI_CYCLE_COUNTER_VALUE 512
248
249/* Defines the DSI phy timing parameters */
250struct dsi_phy_timing_inclk
251{
252 unsigned t_hsdexit;
253 unsigned t_hstrail;
254 unsigned t_hsprepr;
255 unsigned t_datzero;
256
257 unsigned t_clktrail;
258 unsigned t_clkpost;
259 unsigned t_clkzero;
260 unsigned t_tlpx;
261
262 unsigned t_clkpre;
263 unsigned t_clkprepare;
264 unsigned t_wakeup;
265
266 unsigned t_taget;
267 unsigned t_tasure;
268 unsigned t_tago;
269
270};
271
272#endif
diff --git a/drivers/video/tegra/dc/dsi_regs.h b/drivers/video/tegra/dc/dsi_regs.h
new file mode 100644
index 000000000..7625f93c4
--- /dev/null
+++ b/drivers/video/tegra/dc/dsi_regs.h
@@ -0,0 +1,336 @@
1/*
2 * drivers/video/tegra/dc/dsi_regs.h
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#ifndef __DRIVERS_VIDEO_TEGRA_DC_DSI_REG_H__
18#define __DRIVERS_VIDEO_TEGRA_DC_DSI_REG_H__
19
20enum {
21 TEGRA_DSI_DISABLE,
22 TEGRA_DSI_ENABLE,
23};
24
25/* These are word offsets from base (not byte offsets) */
26#define DSI_INCR_SYNCPT 0x00
27#define DSI_INCR_SYNCPT_CNTRL 0x01
28#define DSI_INCR_SYNCPT_ERROR 0x02
29#define DSI_CTXSW 0x08
30#define DSI_RD_DATA 0x09
31#define DSI_WR_DATA 0x0a
32
33#define DSI_POWER_CONTROL 0x0b
34#define DSI_POWER_CONTROL_LEG_DSI_ENABLE(x) (((x) & 0x1) << 0)
35
36#define DSI_INT_ENABLE 0x0c
37#define DSI_INT_STATUS 0x0d
38#define DSI_INT_MASK 0x0e
39
40#define DSI_HOST_DSI_CONTROL 0x0f
41enum {
42 RESET_CRC = 1,
43};
44#define DSI_HOST_CONTROL_FIFO_STAT_RESET(x) (((x) & 0x1) << 21)
45#define DSI_HOST_DSI_CONTROL_CRC_RESET(x) (((x) & 0x1) << 20)
46enum {
47 DSI_PHY_CLK_DIV1,
48 DSI_PHY_CLK_DIV2,
49};
50#define DSI_HOST_DSI_CONTROL_PHY_CLK_DIV(x) (((x) & 0x7) << 16)
51enum {
52 SOL,
53 FIFO_LEVEL,
54 IMMEDIATE,
55};
56#define DSI_HOST_DSI_CONTROL_HOST_TX_TRIG_SRC(x) (((x) & 0x3) << 12)
57enum {
58 NORMAL,
59 ENTER_ULPM,
60 EXIT_ULPM,
61};
62#define DSI_HOST_DSI_CONTROL_ULTRA_LOW_POWER(x) (((x) & 0x3) << 8)
63#define DSI_HOST_DSI_CONTROL_PERIPH_RESET(x) (((x) & 0x1) << 7)
64#define DSI_HOST_DSI_CONTROL_RAW_DATA(x) (((x) & 0x1) << 6)
65enum {
66 TEGRA_DSI_LOW,
67 TEGRA_DSI_HIGH,
68};
69#define DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(x) (((x) & 0x1) << 5)
70enum {
71 HOST_ONLY,
72 VIDEO_HOST,
73};
74#define DSI_HOST_DSI_CONTROL_PKT_WR_FIFO_SEL(x) (((x) & 0x1) << 4)
75#define DSI_HOST_DSI_CONTROL_IMM_BTA(x) (((x) & 0x1) << 3)
76#define DSI_HOST_DSI_CONTROL_PKT_BTA(x) (((x) & 0x1) << 2)
77#define DSI_HOST_DSI_CONTROL_CS_ENABLE(x) (((x) & 0x1) << 1)
78#define DSI_HOST_DSI_CONTROL_ECC_ENABLE(x) (((x) & 0x1) << 0)
79
80#define DSI_CONTROL 0x10
81#define DSI_CONTROL_DBG_ENABLE(x) (((x) & 0x1) << 31)
82enum {
83 CONTINUOUS,
84 TX_ONLY,
85};
86#define DSI_CONTROL_HS_CLK_CTRL(x) (((x) & 0x1) << 20)
87#define DSI_CONTROL_VIRTUAL_CHANNEL(x) (((x) & 0x3) << 16)
88#define DSI_CONTROL_DATA_FORMAT(x) (((x) & 0x3) << 12)
89#define DSI_CONTROL_VID_TX_TRIG_SRC(x) (((x) & 0x3) << 8)
90#define DSI_CONTROL_NUM_DATA_LANES(x) (((x) & 0x3) << 4)
91#define DSI_CONTROL_VID_DCS_ENABLE(x) (((x) & 0x1) << 3)
92#define DSI_CONTROL_VID_SOURCE(x) (((x) & 0x1) << 2)
93#define DSI_CONTROL_VID_ENABLE(x) (((x) & 0x1) << 1)
94#define DSI_CONTROL_HOST_ENABLE(x) (((x) & 0x1) << 0)
95
96#define DSI_SOL_DELAY 0x11
97#define DSI_SOL_DELAY_SOL_DELAY(x) (((x) & 0xffff) << 0)
98
99#define DSI_MAX_THRESHOLD 0x12
100#define DSI_MAX_THRESHOLD_MAX_THRESHOLD(x) (((x) & 0xffff) << 0)
101
102#define DSI_TRIGGER 0x13
103#define DSI_TRIGGER_HOST_TRIGGER(x) (((x) & 0x1) << 1)
104#define DSI_TRIGGER_VID_TRIGGER(x) (((x) & 0x1) << 0)
105
106#define DSI_TX_CRC 0x14
107#define DSI_TX_CRC_TX_CRC(x) (((x) & 0xffffffff) << 0)
108
109#define DSI_STATUS 0x15
110#define DSI_STATUS_IDLE(x) (((x) & 0x1) << 10)
111#define DSI_STATUS_LB_UNDERFLOW(x) (((x) & 0x1) << 9)
112#define DSI_STATUS_LB_OVERFLOW(x) (((x) & 0x1) << 8)
113#define DSI_STATUS_RD_FIFO_COUNT(x) (((x) & 0x1f) << 0)
114
115#define DSI_INIT_SEQ_CONTROL 0x1a
116#define DSI_INIT_SEQ_CONTROL_DSI_FRAME_INIT_BYTE_COUNT(x) \
117 (((x) & 0x3f) << 8)
118#define DSI_INIT_SEQ_CONTROL_DSI_SEND_INIT_SEQUENCE(x) \
119 (((x) & 0xff) << 0)
120
121#define DSI_INIT_SEQ_DATA_0 0x1b
122#define DSI_INIT_SEQ_DATA_1 0x1c
123#define DSI_INIT_SEQ_DATA_2 0x1d
124#define DSI_INIT_SEQ_DATA_3 0x1e
125
126#define DSI_PKT_SEQ_0_LO 0x23
127#define DSI_PKT_SEQ_0_LO_SEQ_0_FORCE_LP(x) (((x) & 0x1) << 30)
128#define DSI_PKT_SEQ_0_LO_PKT_02_EN(x) (((x) & 0x1) << 29)
129#define DSI_PKT_SEQ_0_LO_PKT_02_ID(x) (((x) & 0x3f) << 23)
130#define DSI_PKT_SEQ_0_LO_PKT_02_SIZE(x) (((x) & 0x7) << 20)
131#define DSI_PKT_SEQ_0_LO_PKT_01_EN(x) (((x) & 0x1) << 19)
132#define DSI_PKT_SEQ_0_LO_PKT_01_ID(x) (((x) & 0x3f) << 13)
133#define DSI_PKT_SEQ_0_LO_PKT_01_SIZE(x) (((x) & 0x7) << 10)
134#define DSI_PKT_SEQ_0_LO_PKT_00_EN(x) (((x) & 0x1) << 9)
135#define DSI_PKT_SEQ_0_LO_PKT_00_ID(x) (((x) & 0x3f) << 3)
136#define DSI_PKT_SEQ_0_LO_PKT_00_SIZE(x) (((x) & 0x7) << 0)
137
138#define DSI_PKT_SEQ_0_HI 0x24
139#define DSI_PKT_SEQ_0_HI_PKT_05_EN(x) (((x) & 0x1) << 29)
140#define DSI_PKT_SEQ_0_HI_PKT_05_ID(x) (((x) & 0x3f) << 23)
141#define DSI_PKT_SEQ_0_HI_PKT_05_SIZE(x) (((x) & 0x7) << 20)
142#define DSI_PKT_SEQ_0_HI_PKT_04_EN(x) (((x) & 0x1) << 19)
143#define DSI_PKT_SEQ_0_HI_PKT_04_ID(x) (((x) & 0x3f) << 13)
144#define DSI_PKT_SEQ_0_HI_PKT_04_SIZE(x) (((x) & 0x7) << 10)
145#define DSI_PKT_SEQ_0_HI_PKT_03_EN(x) (((x) & 0x1) << 9)
146#define DSI_PKT_SEQ_0_HI_PKT_03_ID(x) (((x) & 0x3f) << 3)
147#define DSI_PKT_SEQ_0_HI_PKT_03_SIZE(x) (((x) & 0x7) << 0)
148
149#define DSI_PKT_SEQ_1_LO 0x25
150#define DSI_PKT_SEQ_1_LO_SEQ_1_FORCE_LP(x) (((x) & 0x1) << 30)
151#define DSI_PKT_SEQ_1_LO_PKT_12_EN(x) (((x) & 0x1) << 29)
152#define DSI_PKT_SEQ_1_LO_PKT_12_ID(x) (((x) & 0x3f) << 23)
153#define DSI_PKT_SEQ_1_LO_PKT_12_SIZE(x) (((x) & 0x7) << 20)
154#define DSI_PKT_SEQ_1_LO_PKT_11_EN(x) (((x) & 0x1) << 19)
155#define DSI_PKT_SEQ_1_LO_PKT_11_ID(x) (((x) & 0x3f) << 13)
156#define DSI_PKT_SEQ_1_LO_PKT_11_SIZE(x) (((x) & 0x7) << 10)
157#define DSI_PKT_SEQ_1_LO_PKT_10_EN(x) (((x) & 0x1) << 9)
158#define DSI_PKT_SEQ_1_LO_PKT_10_ID(x) (((x) & 0x3f) << 3)
159#define DSI_PKT_SEQ_1_LO_PKT_10_SIZE(x) (((x) & 0x7) << 0)
160
161#define DSI_PKT_SEQ_1_HI 0x26
162#define DSI_PKT_SEQ_1_HI_PKT_15_EN(x) (((x) & 0x1) << 29)
163#define DSI_PKT_SEQ_1_HI_PKT_15_ID(x) (((x) & 0x3f) << 23)
164#define DSI_PKT_SEQ_1_HI_PKT_15_SIZE(x) (((x) & 0x7) << 20)
165#define DSI_PKT_SEQ_1_HI_PKT_14_EN(x) (((x) & 0x1) << 19)
166#define DSI_PKT_SEQ_1_HI_PKT_14_ID(x) (((x) & 0x3f) << 13)
167#define DSI_PKT_SEQ_1_HI_PKT_14_SIZE(x) (((x) & 0x7) << 10)
168#define DSI_PKT_SEQ_1_HI_PKT_13_EN(x) (((x) & 0x1) << 9)
169#define DSI_PKT_SEQ_1_HI_PKT_13_ID(x) (((x) & 0x3f) << 3)
170#define DSI_PKT_SEQ_1_HI_PKT_13_SIZE(x) (((x) & 0x7) << 0)
171
172#define DSI_PKT_SEQ_2_LO 0x27
173#define DSI_PKT_SEQ_2_LO_SEQ_2_FORCE_LP(x) (((x) & 0x1) << 30)
174#define DSI_PKT_SEQ_2_LO_PKT_22_EN(x) (((x) & 0x1) << 29)
175#define DSI_PKT_SEQ_2_LO_PKT_22_ID(x) (((x) & 0x3f) << 23)
176#define DSI_PKT_SEQ_2_LO_PKT_22_SIZE(x) (((x) & 0x7) << 20)
177#define DSI_PKT_SEQ_2_LO_PKT_21_EN(x) (((x) & 0x1) << 19)
178#define DSI_PKT_SEQ_2_LO_PKT_21_ID(x) (((x) & 0x3f) << 13)
179#define DSI_PKT_SEQ_2_LO_PKT_21_SIZE(x) (((x) & 0x7) << 10)
180#define DSI_PKT_SEQ_2_LO_PKT_20_EN(x) (((x) & 0x1) << 9)
181#define DSI_PKT_SEQ_2_LO_PKT_20_ID(x) (((x) & 0x3f) << 3)
182#define DSI_PKT_SEQ_2_LO_PKT_20_SIZE(x) (((x) & 0x7) << 0)
183
184#define DSI_PKT_SEQ_2_HI 0x28
185#define DSI_PKT_SEQ_2_HI_PKT_25_EN(x) (((x) & 0x1) << 29)
186#define DSI_PKT_SEQ_2_HI_PKT_25_ID(x) (((x) & 0x3f) << 23)
187#define DSI_PKT_SEQ_2_HI_PKT_25_SIZE(x) (((x) & 0x7) << 20)
188#define DSI_PKT_SEQ_2_HI_PKT_24_EN(x) (((x) & 0x1) << 19)
189#define DSI_PKT_SEQ_2_HI_PKT_24_ID(x) (((x) & 0x3f) << 13)
190#define DSI_PKT_SEQ_2_HI_PKT_24_SIZE(x) (((x) & 0x7) << 10)
191#define DSI_PKT_SEQ_2_HI_PKT_23_EN(x) (((x) & 0x1) << 9)
192#define DSI_PKT_SEQ_2_HI_PKT_23_ID(x) (((x) & 0x3f) << 3)
193#define DSI_PKT_SEQ_2_HI_PKT_23_SIZE(x) (((x) & 0x7) << 0)
194
195#define DSI_PKT_SEQ_3_LO 0x29
196#define DSI_PKT_SEQ_3_LO_SEQ_3_FORCE_LP(x) (((x) & 0x1) << 30)
197#define DSI_PKT_SEQ_3_LO_PKT_32_EN(x) (((x) & 0x1) << 29)
198#define DSI_PKT_SEQ_3_LO_PKT_32_ID(x) (((x) & 0x3f) << 23)
199#define DSI_PKT_SEQ_3_LO_PKT_32_SIZE(x) (((x) & 0x7) << 20)
200#define DSI_PKT_SEQ_3_LO_PKT_31_EN(x) (((x) & 0x1) << 19)
201#define DSI_PKT_SEQ_3_LO_PKT_31_ID(x) (((x) & 0x3f) << 13)
202#define DSI_PKT_SEQ_3_LO_PKT_31_SIZE(x) (((x) & 0x7) << 10)
203#define DSI_PKT_SEQ_3_LO_PKT_30_EN(x) (((x) & 0x1) << 9)
204#define DSI_PKT_SEQ_3_LO_PKT_30_ID(x) (((x) & 0x3f) << 3)
205#define DSI_PKT_SEQ_3_LO_PKT_30_SIZE(x) (((x) & 0x7) << 0)
206
207#define DSI_PKT_SEQ_3_HI 0x2a
208#define DSI_PKT_SEQ_3_HI_PKT_35_EN(x) (((x) & 0x1) << 29)
209#define DSI_PKT_SEQ_3_HI_PKT_35_ID(x) (((x) & 0x3f) << 23)
210#define DSI_PKT_SEQ_3_HI_PKT_35_SIZE(x) (((x) & 0x7) << 20)
211#define DSI_PKT_SEQ_3_HI_PKT_34_EN(x) (((x) & 0x1) << 19)
212#define DSI_PKT_SEQ_3_HI_PKT_34_ID(x) (((x) & 0x3f) << 13)
213#define DSI_PKT_SEQ_3_HI_PKT_34_SIZE(x) (((x) & 0x7) << 10)
214#define DSI_PKT_SEQ_3_HI_PKT_33_EN(x) (((x) & 0x1) << 9)
215#define DSI_PKT_SEQ_3_HI_PKT_33_ID(x) (((x) & 0x3f) << 3)
216#define DSI_PKT_SEQ_3_HI_PKT_33_SIZE(x) (((x) & 0x7) << 0)
217
218#define DSI_PKT_SEQ_4_LO 0x2b
219#define DSI_PKT_SEQ_4_LO_SEQ_4_FORCE_LP(x) (((x) & 0x1) << 30)
220#define DSI_PKT_SEQ_4_LO_PKT_42_EN(x) (((x) & 0x1) << 29)
221#define DSI_PKT_SEQ_4_LO_PKT_42_ID(x) (((x) & 0x3f) << 23)
222#define DSI_PKT_SEQ_4_LO_PKT_42_SIZE(x) (((x) & 0x7) << 20)
223#define DSI_PKT_SEQ_4_LO_PKT_41_EN(x) (((x) & 0x1) << 19)
224#define DSI_PKT_SEQ_4_LO_PKT_41_ID(x) (((x) & 0x3f) << 13)
225#define DSI_PKT_SEQ_4_LO_PKT_41_SIZE(x) (((x) & 0x7) << 10)
226#define DSI_PKT_SEQ_4_LO_PKT_40_EN(x) (((x) & 0x1) << 9)
227#define DSI_PKT_SEQ_4_LO_PKT_40_ID(x) (((x) & 0x3f) << 3)
228#define DSI_PKT_SEQ_4_LO_PKT_40_SIZE(x) (((x) & 0x7) << 0)
229
230#define DSI_PKT_SEQ_4_HI 0x2c
231#define DSI_PKT_SEQ_4_HI_PKT_45_EN(x) (((x) & 0x1) << 29)
232#define DSI_PKT_SEQ_4_HI_PKT_45_ID(x) (((x) & 0x3f) << 23)
233#define DSI_PKT_SEQ_4_HI_PKT_45_SIZE(x) (((x) & 0x7) << 20)
234#define DSI_PKT_SEQ_4_HI_PKT_44_EN(x) (((x) & 0x1) << 19)
235#define DSI_PKT_SEQ_4_HI_PKT_44_ID(x) (((x) & 0x3f) << 13)
236#define DSI_PKT_SEQ_4_HI_PKT_44_SIZE(x) (((x) & 0x7) << 10)
237#define DSI_PKT_SEQ_4_HI_PKT_43_EN(x) (((x) & 0x1) << 9)
238#define DSI_PKT_SEQ_4_HI_PKT_43_ID(x) (((x) & 0x3f) << 3)
239#define DSI_PKT_SEQ_4_HI_PKT_43_SIZE(x) (((x) & 0x7) << 0)
240
241#define DSI_PKT_SEQ_5_LO 0x2d
242#define DSI_PKT_SEQ_5_LO_SEQ_5_FORCE_LP(x) (((x) & 0x1) << 30)
243#define DSI_PKT_SEQ_5_LO_PKT_52_EN(x) (((x) & 0x1) << 29)
244#define DSI_PKT_SEQ_5_LO_PKT_52_ID(x) (((x) & 0x3f) << 23)
245#define DSI_PKT_SEQ_5_LO_PKT_52_SIZE(x) (((x) & 0x7) << 20)
246#define DSI_PKT_SEQ_5_LO_PKT_51_EN(x) (((x) & 0x1) << 19)
247#define DSI_PKT_SEQ_5_LO_PKT_51_ID(x) (((x) & 0x3f) << 13)
248#define DSI_PKT_SEQ_5_LO_PKT_51_SIZE(x) (((x) & 0x7) << 10)
249#define DSI_PKT_SEQ_5_LO_PKT_50_EN(x) (((x) & 0x1) << 9)
250#define DSI_PKT_SEQ_5_LO_PKT_50_ID(x) (((x) & 0x3f) << 3)
251#define DSI_PKT_SEQ_5_LO_PKT_50_SIZE(x) (((x) & 0x7) << 0)
252
253#define DSI_PKT_SEQ_5_HI 0x2e
254#define DSI_PKT_SEQ_5_HI_PKT_55_EN(x) (((x) & 0x1) << 29)
255#define DSI_PKT_SEQ_5_HI_PKT_55_ID(x) (((x) & 0x3f) << 23)
256#define DSI_PKT_SEQ_5_HI_PKT_55_SIZE(x) (((x) & 0x7) << 20)
257#define DSI_PKT_SEQ_5_HI_PKT_54_EN(x) (((x) & 0x1) << 19)
258#define DSI_PKT_SEQ_5_HI_PKT_54_ID(x) (((x) & 0x3f) << 13)
259#define DSI_PKT_SEQ_5_HI_PKT_54_SIZE(x) (((x) & 0x7) << 10)
260#define DSI_PKT_SEQ_5_HI_PKT_53_EN(x) (((x) & 0x1) << 9)
261#define DSI_PKT_SEQ_5_HI_PKT_53_ID(x) (((x) & 0x3f) << 3)
262#define DSI_PKT_SEQ_5_HI_PKT_53_SIZE(x) (((x) & 0x7) << 0)
263
264#define DSI_DCS_CMDS 0x33
265#define DSI_DCS_CMDS_LT5_DCS_CMD(x) (((x) & 0xff) << 8)
266#define DSI_DCS_CMDS_LT3_DCS_CMD(x) (((x) & 0xff) << 0)
267
268#define DSI_PKT_LEN_0_1 0x34
269#define DSI_PKT_LEN_0_1_LENGTH_1(x) (((x) & 0xffff) << 16)
270#define DSI_PKT_LEN_0_1_LENGTH_0(x) (((x) & 0xffff) << 0)
271
272#define DSI_PKT_LEN_2_3 0x35
273#define DSI_PKT_LEN_2_3_LENGTH_3(x) (((x) & 0xffff) << 16)
274#define DSI_PKT_LEN_2_3_LENGTH_2(x) (((x) & 0xffff) << 0)
275
276
277#define DSI_PKT_LEN_4_5 0x36
278#define DSI_PKT_LEN_4_5_LENGTH_5(x) (((x) & 0xffff) << 16)
279#define DSI_PKT_LEN_4_5_LENGTH_4(x) (((x) & 0xffff) << 0)
280
281#define DSI_PKT_LEN_6_7 0x37
282#define DSI_PKT_LEN_6_7_LENGTH_7(x) (((x) & 0xffff) << 16)
283#define DSI_PKT_LEN_6_7_LENGTH_6(x) (((x) & 0xffff) << 0)
284
285#define DSI_PHY_TIMING_0 0x3c
286#define DSI_PHY_TIMING_0_THSDEXIT(x) (((x) & 0xff) << 24)
287#define DSI_PHY_TIMING_0_THSTRAIL(x) (((x) & 0xff) << 16)
288#define DSI_PHY_TIMING_0_TDATZERO(x) (((x) & 0xff) << 8)
289#define DSI_PHY_TIMING_0_THSPREPR(x) (((x) & 0xff) << 0)
290
291#define DSI_PHY_TIMING_1 0x3d
292#define DSI_PHY_TIMING_1_TCLKTRAIL(x) (((x) & 0xff) << 24)
293#define DSI_PHY_TIMING_1_TCLKPOST(x) (((x) & 0xff) << 16)
294#define DSI_PHY_TIMING_1_TCLKZERO(x) (((x) & 0xff) << 8)
295#define DSI_PHY_TIMING_1_TTLPX(x) (((x) & 0xff) << 0)
296
297#define DSI_PHY_TIMING_2 0x3e
298#define DSI_PHY_TIMING_2_TCLKPREPARE(x) (((x) & 0xff) << 16)
299#define DSI_PHY_TIMING_2_TCLKPRE(x) (((x) & 0xff) << 8)
300#define DSI_PHY_TIMING_2_TWAKEUP(x) (((x) & 0xff) << 0)
301
302#define DSI_BTA_TIMING 0x3f
303#define DSI_BTA_TIMING_TTAGET(x) (((x) & 0xff) << 16)
304#define DSI_BTA_TIMING_TTASURE(x) (((x) & 0xff) << 8)
305#define DSI_BTA_TIMING_TTAGO(x) (((x) & 0xff) << 0)
306
307
308#define DSI_TIMEOUT_0 0x44
309#define DSI_TIMEOUT_0_LRXH_TO(x) (((x) & 0xffff) << 16)
310#define DSI_TIMEOUT_0_HTX_TO(x) (((x) & 0xffff) << 0)
311
312#define DSI_TIMEOUT_1 0x45
313#define DSI_TIMEOUT_1_PR_TO(x) (((x) & 0xffff) << 16)
314#define DSI_TIMEOUT_1_TA_TO(x) (((x) & 0xffff) << 0)
315
316#define DSI_TO_TALLY 0x46
317enum {
318 IN_RESET,
319 READY,
320};
321#define DSI_TO_TALLY_P_RESET_STATUS(x) (((x) & 0x1) << 24)
322#define DSI_TO_TALLY_TA_TALLY(x) (((x) & 0xff) << 16)
323#define DSI_TO_TALLY_LRXH_TALLY(x) (((x) & 0xff) << 8)
324#define DSI_TO_TALLY_HTX_TALLY(x) (((x) & 0xff) << 0)
325
326#define DSI_PAD_CONTROL 0x4b
327#define DSI_PAD_CONTROL_PAD_PULLDN_ENAB(x) (((x) & 0x1) << 28)
328#define DSI_PAD_CONTROL_PAD_PDIO_CLK(x) (((x) & 0x1) << 18)
329#define DSI_PAD_CONTROL_PAD_PDIO(x) (((x) & 0x3) << 16)
330
331#define DSI_PAD_CONTROL_CD 0x4c
332#define DSI_PAD_CD_STATUS 0x4d
333#define DSI_VID_MODE_CONTROL 0x4e
334
335#endif
336