diff options
author | Luke Huang <lhuang@nvidia.com> | 2011-01-27 16:14:44 -0500 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:01:04 -0400 |
commit | 9422790b0eacbbeb801072cc292a353de086b86b (patch) | |
tree | 8006ac16140878915fba0a7372e69f09120f1f75 /drivers/video | |
parent | 0503cd99d91bdd9660ef3640dd252964ab9fe646 (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/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 21 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv.h | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_reg.h | 13 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 1466 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.h | 272 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi_regs.h | 336 |
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 | |||
3 | obj-y += hdmi.o | 3 | obj-y += hdmi.o |
4 | obj-y += nvhdcp.o | 4 | obj-y += nvhdcp.o |
5 | obj-y += edid.o | 5 | obj-y += edid.o |
6 | obj-$(CONFIG_TEGRA_DSI) += dsi.o | ||
6 | obj-$(CONFIG_TEGRA_OVERLAY) += overlay.o | 7 | obj-$(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 | ||
143 | extern struct tegra_dc_out_ops tegra_dc_rgb_ops; | 143 | extern struct tegra_dc_out_ops tegra_dc_rgb_ops; |
144 | extern struct tegra_dc_out_ops tegra_dc_hdmi_ops; | 144 | extern struct tegra_dc_out_ops tegra_dc_hdmi_ops; |
145 | extern 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 | |||
68 | struct 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 */ | ||
82 | enum{ | ||
83 | TEGRA_DSI_DRIVEN_BY_DC, | ||
84 | TEGRA_DSI_DRIVEN_BY_HOST, | ||
85 | }; | ||
86 | |||
87 | struct 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 | |||
120 | const 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 | |||
135 | const 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 | |||
154 | const 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 | |||
171 | static 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 */ | ||
192 | const 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 | |||
207 | const 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 | |||
244 | static 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 | |||
250 | static 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 | |||
256 | static 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 | |||
283 | static 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 | |||
299 | static 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 | |||
375 | static 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 | |||
421 | static 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 | |||
451 | static 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 | |||
500 | static 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 | |||
520 | static 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 | |||
553 | static 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 | |||
593 | static 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 | |||
615 | static 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 | |||
627 | static 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 | |||
695 | static 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 | |||
705 | static 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 | |||
740 | static 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 | |||
767 | static 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 | |||
789 | static 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 | |||
813 | static 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 | |||
824 | static 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 | |||
848 | static 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 | |||
869 | static 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 | |||
912 | static 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; | ||
963 | fail: | ||
964 | return err; | ||
965 | } | ||
966 | |||
967 | static 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 | |||
999 | success: | ||
1000 | dsi->status.lphs = DSI_LPHS_IN_LP_MODE; | ||
1001 | err = 0; | ||
1002 | fail: | ||
1003 | return err; | ||
1004 | } | ||
1005 | |||
1006 | static 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; | ||
1044 | fail: | ||
1045 | return err; | ||
1046 | } | ||
1047 | |||
1048 | static 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 | |||
1066 | static 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 | |||
1083 | fail: | ||
1084 | return status; | ||
1085 | } | ||
1086 | |||
1087 | static 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 | |||
1094 | static 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 | |||
1168 | fail: | ||
1169 | return err; | ||
1170 | } | ||
1171 | |||
1172 | static 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 | |||
1197 | static 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 | |||
1238 | static 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 | |||
1246 | static 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 | |||
1265 | free_cmd_pdata: | ||
1266 | for (--i; i >=0; i--) | ||
1267 | if (dst[i].pdata) | ||
1268 | kfree(dst[i].pdata); | ||
1269 | return -ENOMEM; | ||
1270 | } | ||
1271 | |||
1272 | static 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 | |||
1315 | err_free_pcmd: | ||
1316 | kfree(pcmd); | ||
1317 | return err; | ||
1318 | } | ||
1319 | |||
1320 | static 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 | |||
1395 | err_dsi_data: | ||
1396 | err_clk_put: | ||
1397 | clk_put(dsi->dsi_clk); | ||
1398 | err_release_regs: | ||
1399 | release_resource(base_res); | ||
1400 | err_free_dsi: | ||
1401 | kfree(dsi); | ||
1402 | |||
1403 | return err; | ||
1404 | } | ||
1405 | |||
1406 | static 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 | |||
1444 | static 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 | |||
1461 | struct 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 */ | ||
21 | enum{ | ||
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 */ | ||
56 | enum { | ||
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 | |||
177 | enum { | ||
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 */ | ||
250 | struct 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 | |||
20 | enum { | ||
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 | ||
41 | enum { | ||
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) | ||
46 | enum { | ||
47 | DSI_PHY_CLK_DIV1, | ||
48 | DSI_PHY_CLK_DIV2, | ||
49 | }; | ||
50 | #define DSI_HOST_DSI_CONTROL_PHY_CLK_DIV(x) (((x) & 0x7) << 16) | ||
51 | enum { | ||
52 | SOL, | ||
53 | FIFO_LEVEL, | ||
54 | IMMEDIATE, | ||
55 | }; | ||
56 | #define DSI_HOST_DSI_CONTROL_HOST_TX_TRIG_SRC(x) (((x) & 0x3) << 12) | ||
57 | enum { | ||
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) | ||
65 | enum { | ||
66 | TEGRA_DSI_LOW, | ||
67 | TEGRA_DSI_HIGH, | ||
68 | }; | ||
69 | #define DSI_HOST_DSI_CONTROL_HIGH_SPEED_TRANS(x) (((x) & 0x1) << 5) | ||
70 | enum { | ||
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) | ||
82 | enum { | ||
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 | ||
317 | enum { | ||
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 | |||