blob: d5e9ff64ca02c1e6f27ff42b974699b7fbd702b3 [file] [log] [blame]
Greg Griscod6250552011-06-29 14:40:23 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
Chandan Uddaraju78ae6752010-10-19 12:57:10 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#include <reg.h>
Shashank Mittalcbd271d2011-01-14 15:18:33 -080031#include <endian.h>
Chandan Uddaraju78ae6752010-10-19 12:57:10 -070032#include <mipi_dsi.h>
33#include <dev/fbcon.h>
34#include <target/display.h>
Greg Griscod6250552011-06-29 14:40:23 -070035#include <stdlib.h>
Kinson Chike5c93432011-06-17 09:10:29 -070036#include <debug.h>
Chandan Uddaraju78ae6752010-10-19 12:57:10 -070037
Chandan Uddarajufe93e822010-11-21 20:44:47 -080038#if DISPLAY_MIPI_PANEL_TOSHIBA
Chandan Uddaraju78ae6752010-10-19 12:57:10 -070039static struct fbcon_config mipi_fb_cfg = {
40 .height = TSH_MIPI_FB_HEIGHT,
41 .width = TSH_MIPI_FB_WIDTH,
42 .stride = TSH_MIPI_FB_WIDTH,
43 .format = FB_FORMAT_RGB888,
44 .bpp = 24,
45 .update_start = NULL,
46 .update_done = NULL,
47};
Kinson Chike5c93432011-06-17 09:10:29 -070048struct mipi_dsi_panel_config toshiba_panel_info = {
49 .mode = MIPI_VIDEO_MODE,
50 .num_of_lanes = 1,
51 .dsi_phy_config = &mipi_dsi_toshiba_panel_phy_ctrl,
52 .panel_cmds = toshiba_panel_video_mode_cmds,
53 .num_of_panel_cmds = ARRAY_SIZE(toshiba_panel_video_mode_cmds),
54};
Chandan Uddarajufe93e822010-11-21 20:44:47 -080055#elif DISPLAY_MIPI_PANEL_NOVATEK_BLUE
56static struct fbcon_config mipi_fb_cfg = {
57 .height = NOV_MIPI_FB_HEIGHT,
58 .width = NOV_MIPI_FB_WIDTH,
59 .stride = NOV_MIPI_FB_WIDTH,
60 .format = FB_FORMAT_RGB888,
61 .bpp = 24,
62 .update_start = NULL,
63 .update_done = NULL,
64};
Kinson Chike5c93432011-06-17 09:10:29 -070065struct mipi_dsi_panel_config novatek_panel_info = {
66 .mode = MIPI_CMD_MODE,
67 .num_of_lanes = 2,
68 .dsi_phy_config = &mipi_dsi_novatek_panel_phy_ctrl,
69 .panel_cmds = novatek_panel_cmd_mode_cmds,
70 .num_of_panel_cmds = ARRAY_SIZE(novatek_panel_cmd_mode_cmds),
71};
72#elif DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
73static struct fbcon_config mipi_fb_cfg = {
74 .height = TSH_MDT61_MIPI_FB_HEIGHT,
75 .width = TSH_MDT61_MIPI_FB_WIDTH,
76 .stride = TSH_MDT61_MIPI_FB_WIDTH,
77 .format = FB_FORMAT_RGB888,
78 .bpp = 24,
79 .update_start = NULL,
80 .update_done = NULL,
81};
82struct mipi_dsi_panel_config toshiba_mdt61_panel_info = {
83 .mode = MIPI_VIDEO_MODE,
84 .num_of_lanes = 3,
85 .dsi_phy_config = &mipi_dsi_toshiba_mdt61_panel_phy_ctrl,
86 .panel_cmds = toshiba_mdt61_video_mode_cmds,
87 .num_of_panel_cmds = ARRAY_SIZE(toshiba_mdt61_video_mode_cmds),
88};
Chandan Uddarajufe93e822010-11-21 20:44:47 -080089#else
90static struct fbcon_config mipi_fb_cfg = {
91 .height = 0,
92 .width = 0,
93 .stride = 0,
94 .format = 0,
95 .bpp = 0,
96 .update_start = NULL,
97 .update_done = NULL,
98};
99#endif
100
101static int cmd_mode_status = 0;
Greg Griscod6250552011-06-29 14:40:23 -0700102void secure_writel(uint32_t, uint32_t);
103uint32_t secure_readl(uint32_t);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700104
105void configure_dsicore_dsiclk()
106{
107 unsigned char mnd_mode, root_en, clk_en;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800108 unsigned long src_sel = 0x3; // dsi_phy_pll0_src
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700109 unsigned long pre_div_func = 0x00; // predivide by 1
110 unsigned long pmxo_sel;
111
Chandan Uddaraju3cbbd302011-03-11 11:48:11 -0800112 secure_writel(pre_div_func << 14 | src_sel, MMSS_DSI_NS);
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800113 mnd_mode = 0; // Bypass MND
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700114 root_en = 1;
115 clk_en = 1;
116 pmxo_sel = 0;
117
Chandan Uddaraju3cbbd302011-03-11 11:48:11 -0800118 secure_writel((pmxo_sel << 8) | (mnd_mode << 6), MMSS_DSI_CC);
119 secure_writel(secure_readl(MMSS_DSI_CC) | root_en << 2, MMSS_DSI_CC);
120 secure_writel(secure_readl(MMSS_DSI_CC) | clk_en, MMSS_DSI_CC);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700121}
122
123void configure_dsicore_byteclk(void)
124{
Chandan Uddaraju3cbbd302011-03-11 11:48:11 -0800125 secure_writel(0x00400401, MMSS_MISC_CC2); // select pxo
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700126}
127
128void configure_dsicore_pclk(void)
129{
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700130 unsigned char mnd_mode, root_en, clk_en;
131 unsigned long src_sel = 0x3; // dsi_phy_pll0_src
132 unsigned long pre_div_func = 0x01; // predivide by 2
133
Chandan Uddaraju3cbbd302011-03-11 11:48:11 -0800134 secure_writel(pre_div_func << 12 | src_sel, MMSS_DSI_PIXEL_NS);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700135
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800136 mnd_mode = 0; // Bypass MND
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700137 root_en = 1;
138 clk_en = 1;
Chandan Uddaraju3cbbd302011-03-11 11:48:11 -0800139 secure_writel(mnd_mode << 6, MMSS_DSI_PIXEL_CC);
140 secure_writel(secure_readl(MMSS_DSI_PIXEL_CC) | root_en << 2,
Kinson Chike5c93432011-06-17 09:10:29 -0700141 MMSS_DSI_PIXEL_CC);
Chandan Uddaraju3cbbd302011-03-11 11:48:11 -0800142 secure_writel(secure_readl(MMSS_DSI_PIXEL_CC) | clk_en,
Kinson Chike5c93432011-06-17 09:10:29 -0700143 MMSS_DSI_PIXEL_CC);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700144}
145
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800146int mipi_dsi_phy_ctrl_config(struct mipi_dsi_panel_config *pinfo)
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700147{
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800148 unsigned i;
149 unsigned off = 0;
150 struct mipi_dsi_phy_ctrl *pd;
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700151
152 writel(0x00000001, DSI_PHY_SW_RESET);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700153 writel(0x00000000, DSI_PHY_SW_RESET);
154
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800155 pd = (pinfo->dsi_phy_config);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700156
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800157 off = 0x02cc; /* regulator ctrl 0 */
158 for (i = 0; i < 4; i++) {
159 writel(pd->regulator[i], MIPI_DSI_BASE + off);
160 off += 4;
161 }
162
163 off = 0x0260; /* phy timig ctrl 0 */
164 for (i = 0; i < 11; i++) {
165 writel(pd->timing[i], MIPI_DSI_BASE + off);
166 off += 4;
167 }
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700168
169 // T_CLK_POST, T_CLK_PRE for CLK lane P/N HS 200 mV timing length should >
170 // data lane HS timing length
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800171 writel(0xa1e, DSI_CLKOUT_TIMING_CTRL);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700172
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800173 off = 0x0290; /* ctrl 0 */
174 for (i = 0; i < 4; i++) {
175 writel(pd->ctrl[i], MIPI_DSI_BASE + off);
176 off += 4;
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700177 }
178
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800179 off = 0x02a0; /* strength 0 */
180 for (i = 0; i < 4; i++) {
181 writel(pd->strength[i], MIPI_DSI_BASE + off);
182 off += 4;
183 }
184
185 off = 0x0204; /* pll ctrl 1, skip 0 */
186 for (i = 1; i < 21; i++) {
187 writel(pd->pll[i], MIPI_DSI_BASE + off);
188 off += 4;
189 }
190
191 /* pll ctrl 0 */
192 writel(pd->pll[0], MIPI_DSI_BASE + 0x200);
193 writel((pd->pll[0] | 0x01), MIPI_DSI_BASE + 0x200);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700194
195 return (0);
196}
197
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800198struct mipi_dsi_panel_config *get_panel_info(void)
199{
200#if DISPLAY_MIPI_PANEL_TOSHIBA
201 return &toshiba_panel_info;
202#elif DISPLAY_MIPI_PANEL_NOVATEK_BLUE
203 return &novatek_panel_info;
Kinson Chike5c93432011-06-17 09:10:29 -0700204#elif DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
205 return &toshiba_mdt61_panel_info;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800206#endif
207 return NULL;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800208}
209
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700210int dsi_cmd_dma_trigger_for_panel()
211{
212 unsigned long ReadValue;
213 unsigned long count = 0;
214 int status = 0;
215
216 writel(0x03030303, DSI_INT_CTRL);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700217 writel(0x1, DSI_CMD_MODE_DMA_SW_TRIGGER);
218 ReadValue = readl(DSI_INT_CTRL) & 0x00000001;
219 while (ReadValue != 0x00000001) {
220 ReadValue = readl(DSI_INT_CTRL) & 0x00000001;
221 count++;
222 if (count > 0xffff) {
223 status = FAIL;
Kinson Chike5c93432011-06-17 09:10:29 -0700224 dprintf(CRITICAL, "Panel CMD: command mode dma test failed\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700225 return status;
226 }
227 }
228
229 writel((readl(DSI_INT_CTRL) | 0x01000001), DSI_INT_CTRL);
Kinson Chike5c93432011-06-17 09:10:29 -0700230 dprintf
231 (SPEW, "Panel CMD: command mode dma tested successfully\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700232 return status;
233}
234
Chandan Uddarajuc1df5652011-03-03 21:15:51 -0800235
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800236int mipi_dsi_cmds_tx(struct mipi_dsi_cmd *cmds, int count)
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700237{
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800238 int ret = 0;
239 struct mipi_dsi_cmd *cm;
240 int i = 0;
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700241
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800242 cm = cmds;
243 for (i = 0; i < count; i++) {
244 memcpy(DSI_CMD_DMA_MEM_START_ADDR_PANEL, (cm->payload), cm->size);
245 writel(DSI_CMD_DMA_MEM_START_ADDR_PANEL, DSI_DMA_CMD_OFFSET);
246 writel(cm->size, DSI_DMA_CMD_LENGTH); // reg 0x48 for this build
247 ret += dsi_cmd_dma_trigger_for_panel();
Kinson Chikf91907f2011-07-15 10:06:48 -0700248 udelay(80);
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800249 cm++;
250 }
251 return ret;
252}
253
Shashank Mittalcbd271d2011-01-14 15:18:33 -0800254/*
255 * mipi_dsi_cmd_rx: can receive at most 16 bytes
256 * per transaction since it only have 4 32bits reigsters
257 * to hold data.
258 * therefore Maximum Return Packet Size need to be set to 16.
259 * any return data more than MRPS need to be break down
260 * to multiple transactions.
261 */
262int mipi_dsi_cmds_rx(char **rp, int len)
263{
264 uint32_t *lp, data;
265 char * dp;
266 int i, off, cnt;
267 int rlen, res;
268
269 if(len <= 2)
270 rlen = 4; /* short read */
271 else
272 rlen = MIPI_DSI_MRPS + 6; /* 4 bytes header + 2 bytes crc */
273
274 if (rlen > MIPI_DSI_REG_LEN) {
275 return 0;
276 }
277
278 res = rlen & 0x03;
279
280 rlen += res; /* 4 byte align */
281 lp = (uint32_t *)(*rp);
282
283 cnt = rlen;
284 cnt += 3;
285 cnt >>=2;
286
287 if (cnt > 4)
288 cnt = 4; /* 4 x 32 bits registers only */
289
290 off = 0x068; /* DSI_RDBK_DATA0 */
291 off += ((cnt - 1) * 4);
292
293 for (i = 0; i < cnt; i++) {
294 data = (uint32_t)readl(MIPI_DSI_BASE + off);
295 *lp++ = ntohl(data); /* to network byte order */
296 off -= 4;
297 }
298
299 if(len > 2)
300 {
301 /*First 4 bytes + paded bytes will be header next len bytes would be payload*/
302 for(i = 0; i < len; i++)
303 {
304 dp = *rp;
305 dp[i] = dp[4 + res + i];
306 }
307 }
308
309 return len;
310}
311
312static int mipi_dsi_cmd_bta_sw_trigger(void)
313{
314 uint32_t data;
315 int cnt = 0;
316 int err = 0;
317
318 writel(0x01, MIPI_DSI_BASE + 0x094); /* trigger */
319 while (cnt < 10000) {
320 data = readl(MIPI_DSI_BASE + 0x0004); /*DSI_STATUS*/
321 if ((data & 0x0010) == 0)
322 break;
323 cnt++;
324 }
325 if(cnt == 10000)
326 err = 1;
327 return err;
328}
329
330static uint32_t mipi_novatek_manufacture_id(void)
331{
332 char rec_buf[24];
333 char *rp = rec_buf;
334 uint32_t *lp, data;
335
336 mipi_dsi_cmds_tx(&novatek_panel_manufacture_id_cmd, 1);
337 mipi_dsi_cmds_rx(&rp, 3);
338
339 lp = (uint32_t *)rp;
340 data = (uint32_t)*lp;
341 data = ntohl(data);
342 data = data >> 8;
343 return data;
344}
345
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800346int mipi_dsi_panel_initialize(struct mipi_dsi_panel_config *pinfo)
347{
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700348 unsigned char DMA_STREAM1 = 0; // for mdp display processor path
349 unsigned char EMBED_MODE1 = 1; // from frame buffer
350 unsigned char POWER_MODE2 = 1; // from frame buffer
351 unsigned char PACK_TYPE1 = 1; // long packet
352 unsigned char VC1 = 0;
353 unsigned char DT1 = 0; // non embedded mode
354 unsigned short WC1 = 0; // for non embedded mode only
355 int status = 0;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800356 unsigned char DLNx_EN;
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700357
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800358 switch (pinfo->num_of_lanes) {
359 default:
360 case 1:
361 DLNx_EN = 1; // 1 lane
362 break;
363 case 2:
364 DLNx_EN = 3; // 2 lane
365 break;
366 case 3:
367 DLNx_EN = 7; // 3 lane
368 break;
369 }
370
371 writel(0x0001, DSI_SOFT_RESET);
372 writel(0x0000, DSI_SOFT_RESET);
373
Kinson Chike5c93432011-06-17 09:10:29 -0700374 writel((0 << 16) | 0x3f, DSI_CLK_CTRL); /* Turn on all DSI Clks */
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700375 writel(DMA_STREAM1 << 8 | 0x04, DSI_TRIG_CTRL); // reg 0x80 dma trigger: sw
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800376 // trigger 0x4; dma stream1
Kinson Chike5c93432011-06-17 09:10:29 -0700377
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700378 writel(0 << 30 | DLNx_EN << 4 | 0x105, DSI_CTRL); // reg 0x00 for this
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800379 // build
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700380 writel(EMBED_MODE1 << 28 | POWER_MODE2 << 26
381 | PACK_TYPE1 << 24 | VC1 << 22 | DT1 << 16 | WC1,
382 DSI_COMMAND_MODE_DMA_CTRL);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700383
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800384 status = mipi_dsi_cmds_tx(pinfo->panel_cmds, pinfo->num_of_panel_cmds);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700385
386 return status;
387}
388
Kinson Chike5c93432011-06-17 09:10:29 -0700389//TODO: Clean up arguments being passed in not being used
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700390int config_dsi_video_mode(unsigned short disp_width, unsigned short disp_height,
391 unsigned short img_width, unsigned short img_height,
392 unsigned short hsync_porch0_fp,
393 unsigned short hsync_porch0_bp,
394 unsigned short vsync_porch0_fp,
395 unsigned short vsync_porch0_bp,
396 unsigned short hsync_width,
397 unsigned short vsync_width, unsigned short dst_format,
398 unsigned short traffic_mode,
399 unsigned short datalane_num)
400{
401
402 unsigned char DST_FORMAT;
403 unsigned char TRAFIC_MODE;
404 unsigned char DLNx_EN;
405 // video mode data ctrl
406 int status = 0;
407 unsigned long low_pwr_stop_mode = 0;
408 unsigned char eof_bllp_pwr = 0x9;
409 unsigned char interleav = 0;
410
411 // disable mdp first
412 writel(0x00000000, MDP_DSI_VIDEO_EN);
413
414 writel(0x00000000, DSI_CLK_CTRL);
415 writel(0x00000000, DSI_CLK_CTRL);
416 writel(0x00000000, DSI_CLK_CTRL);
417 writel(0x00000000, DSI_CLK_CTRL);
418 writel(0x00000002, DSI_CLK_CTRL);
419 writel(0x00000006, DSI_CLK_CTRL);
420 writel(0x0000000e, DSI_CLK_CTRL);
421 writel(0x0000001e, DSI_CLK_CTRL);
422 writel(0x0000003e, DSI_CLK_CTRL);
423
424 writel(0, DSI_CTRL);
425
426 writel(0, DSI_ERR_INT_MASK0);
427
428 DST_FORMAT = 0; // RGB565
Kinson Chike5c93432011-06-17 09:10:29 -0700429 dprintf(SPEW, "DSI_Video_Mode - Dst Format: RGB565\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700430
431 DLNx_EN = 1; // 1 lane with clk programming
Kinson Chike5c93432011-06-17 09:10:29 -0700432 dprintf(SPEW, "Data Lane: 1 lane\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700433
434 TRAFIC_MODE = 0; // non burst mode with sync pulses
Kinson Chike5c93432011-06-17 09:10:29 -0700435 dprintf(SPEW, "Traffic mode: non burst mode with sync pulses\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700436
437 writel(0x02020202, DSI_INT_CTRL);
438
439 writel(((img_width + hsync_porch0_bp) << 16) | hsync_porch0_bp,
440 DSI_VIDEO_MODE_ACTIVE_H);
441
442 writel(((img_height + vsync_porch0_bp) << 16) | (vsync_porch0_bp),
443 DSI_VIDEO_MODE_ACTIVE_V);
444
445 writel(((img_height + vsync_porch0_fp + vsync_porch0_bp) << 16)
446 | img_width + hsync_porch0_fp + hsync_porch0_bp,
447 DSI_VIDEO_MODE_TOTAL);
448
449 writel((hsync_width << 16) | 0, DSI_VIDEO_MODE_HSYNC);
450
451 writel(0 << 16 | 0, DSI_VIDEO_MODE_VSYNC);
452
453 writel(vsync_width << 16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS);
454
455 writel(1, DSI_EOT_PACKET_CTRL);
456
457 writel(0x00000100, DSI_MISR_VIDEO_CTRL);
458
459 writel(low_pwr_stop_mode << 16 | eof_bllp_pwr << 12 | TRAFIC_MODE << 8
460 | DST_FORMAT << 4 | 0x0, DSI_VIDEO_MODE_CTRL);
461
462 writel(0x67, DSI_CAL_STRENGTH_CTRL);
463
464 writel(0x80006711, DSI_CAL_CTRL);
465
466 writel(0x00010100, DSI_MISR_VIDEO_CTRL);
467
468 writel(0x00010100, DSI_INT_CTRL);
469 writel(0x02010202, DSI_INT_CTRL);
470
471 writel(0x02030303, DSI_INT_CTRL);
472
473 writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4
474 | 0x103, DSI_CTRL);
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800475 mdelay(10);
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700476
477 return status;
478}
479
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800480int config_dsi_cmd_mode(unsigned short disp_width, unsigned short disp_height,
481 unsigned short img_width, unsigned short img_height,
482 unsigned short dst_format,
483 unsigned short traffic_mode,
484 unsigned short datalane_num)
485{
486 unsigned char DST_FORMAT;
487 unsigned char TRAFIC_MODE;
488 unsigned char DLNx_EN;
489 // video mode data ctrl
490 int status = 0;
Greg Griscod6250552011-06-29 14:40:23 -0700491 unsigned char interleav = 0;
492 unsigned char ystride = 0x03;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800493 // disable mdp first
494
495 writel(0x00000000, DSI_CLK_CTRL);
496 writel(0x00000000, DSI_CLK_CTRL);
497 writel(0x00000000, DSI_CLK_CTRL);
498 writel(0x00000000, DSI_CLK_CTRL);
499 writel(0x00000002, DSI_CLK_CTRL);
500 writel(0x00000006, DSI_CLK_CTRL);
501 writel(0x0000000e, DSI_CLK_CTRL);
502 writel(0x0000001e, DSI_CLK_CTRL);
503 writel(0x0000003e, DSI_CLK_CTRL);
504
505 writel(0x10000000, DSI_ERR_INT_MASK0);
506
507 // writel(0, DSI_CTRL);
508
509 // writel(0, DSI_ERR_INT_MASK0);
510
511 DST_FORMAT = 8; // RGB888
Kinson Chike5c93432011-06-17 09:10:29 -0700512 dprintf(SPEW, "DSI_Cmd_Mode - Dst Format: RGB888\n");
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800513
514 DLNx_EN = 3; // 2 lane with clk programming
Kinson Chike5c93432011-06-17 09:10:29 -0700515 dprintf(SPEW, "Data Lane: 2 lane\n");
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800516
517 TRAFIC_MODE = 0; // non burst mode with sync pulses
Kinson Chike5c93432011-06-17 09:10:29 -0700518 dprintf(SPEW, "Traffic mode: non burst mode with sync pulses\n");
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800519
520 writel(0x02020202, DSI_INT_CTRL);
521
522 writel(0x00100000 | DST_FORMAT, DSI_COMMAND_MODE_MDP_CTRL);
523 writel((img_width * ystride + 1) << 16 | 0x0039,
524 DSI_COMMAND_MODE_MDP_STREAM0_CTRL);
525 writel((img_width * ystride + 1) << 16 | 0x0039,
526 DSI_COMMAND_MODE_MDP_STREAM1_CTRL);
527 writel(img_height << 16 | img_width, DSI_COMMAND_MODE_MDP_STREAM0_TOTAL);
528 writel(img_height << 16 | img_width, DSI_COMMAND_MODE_MDP_STREAM1_TOTAL);
529 writel(0xEE, DSI_CAL_STRENGTH_CTRL);
530 writel(0x80000000, DSI_CAL_CTRL);
531 writel(0x40, DSI_TRIG_CTRL);
532 writel(0x13c2c, DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL);
533 writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4 | 0x105,
534 DSI_CTRL);
535 mdelay(10);
536 writel(0x10000000, DSI_COMMAND_MODE_DMA_CTRL);
537 writel(0x10000000, DSI_MISR_CMD_CTRL);
538 writel(0x00000040, DSI_ERR_INT_MASK0);
539 writel(0x1, DSI_EOT_PACKET_CTRL);
540 // writel(0x0, MDP_OVERLAYPROC0_START);
541 writel(0x00000001, MDP_DMA_P_START);
542 mdelay(10);
543 writel(0x1, DSI_CMD_MODE_MDP_SW_TRIGGER);
544
545 status = 1;
546 return status;
547}
548
Kinson Chike5c93432011-06-17 09:10:29 -0700549void mdp_setup_dma_p_video_config(unsigned short pack_pattern,
550 unsigned short img_width,
551 unsigned short img_height,
552 unsigned long input_img_addr,
553 unsigned short img_width_full_size,
554 unsigned char ystride){
555 dprintf(SPEW, "MDP4.2 Setup for DSI Video Mode\n");
556
557 // ----- programming MDP_AXI_RDMASTER_CONFIG --------
558 /* MDP_AXI_RDMASTER_CONFIG set all master to read from AXI port 0, that's
559 the only port connected */
560 //TODO: Seems to still work without this
561 writel(0x00290000, MDP_AXI_RDMASTER_CONFIG);
562 writel(0x00000004, MDP_AXI_WRMASTER_CONFIG);
563 writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG);
564
565 /* Set up CMD_INTF_SEL, VIDEO_INTF_SEL, EXT_INTF_SEL, SEC_INTF_SEL, PRIM_INTF_SEL */
566 writel(0x00000049, MDP_DISP_INTF_SEL);
567
568 /* DMA P */
569 writel(0x0000000b, MDP_OVERLAYPROC0_CFG);
570
571 /* RGB 888 */
572 writel(pack_pattern << 8 | 0xbf | (0 << 25), MDP_DMA_P_CONFIG);
573
574 writel(0x0, MDP_DMA_P_OUT_XY);
575
576 writel(img_height << 16 | img_width, MDP_DMA_P_SIZE);
577
578 writel(input_img_addr, MDP_DMA_P_BUF_ADDR);
579
580 writel(img_width_full_size * ystride, MDP_DMA_P_BUF_Y_STRIDE);
581}
582
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700583int mdp_setup_dma_p_video_mode(unsigned short disp_width,
584 unsigned short disp_height,
585 unsigned short img_width,
586 unsigned short img_height,
587 unsigned short hsync_porch0_fp,
588 unsigned short hsync_porch0_bp,
589 unsigned short vsync_porch0_fp,
590 unsigned short vsync_porch0_bp,
591 unsigned short hsync_width,
592 unsigned short vsync_width,
593 unsigned long input_img_addr,
594 unsigned short img_width_full_size,
595 unsigned short pack_pattern,
596 unsigned char ystride)
597{
598
599 // unsigned long mdp_intr_status;
600 int status = FAIL;
601 unsigned long hsync_period;
602 unsigned long vsync_period;
603 unsigned long vsync_period_intmd;
604
Kinson Chike5c93432011-06-17 09:10:29 -0700605 dprintf(SPEW, "Hi setup MDP4.1 for DSI Video Mode\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700606
607 hsync_period = img_width + hsync_porch0_fp + hsync_porch0_bp + 1;
608 vsync_period_intmd = img_height + vsync_porch0_fp + vsync_porch0_bp + 1;
609 vsync_period = vsync_period_intmd * hsync_period;
610
611 // ----- programming MDP_AXI_RDMASTER_CONFIG --------
612 /* MDP_AXI_RDMASTER_CONFIG set all master to read from AXI port 0, that's
613 the only port connected */
614 writel(0x00290000, MDP_AXI_RDMASTER_CONFIG);
615 writel(0x00000004, MDP_AXI_WRMASTER_CONFIG);
616 writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG);
Kinson Chike5c93432011-06-17 09:10:29 -0700617 /* sets PRIM_INTF_SEL to 0x1 and SEC_INTF_SEL to 0x2 and DSI_VIDEO_INTF_SEL*/
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700618 writel(0x00000049, MDP_DISP_INTF_SEL);
619 writel(0x0000000b, MDP_OVERLAYPROC0_CFG);
620
621 // ------------- programming MDP_DMA_P_CONFIG ---------------------
622 writel(pack_pattern << 8 | 0xbf | (0 << 25), MDP_DMA_P_CONFIG); // rgb888
623
624 writel(0x00000000, MDP_DMA_P_OUT_XY);
625 writel(img_height << 16 | img_width, MDP_DMA_P_SIZE);
626 writel(input_img_addr, MDP_DMA_P_BUF_ADDR);
627 writel(img_width_full_size * ystride, MDP_DMA_P_BUF_Y_STRIDE);
628 writel(0x00ff0000, MDP_DMA_P_OP_MODE);
629 writel(hsync_period << 16 | hsync_width, MDP_DSI_VIDEO_HSYNC_CTL);
630 writel(vsync_period, MDP_DSI_VIDEO_VSYNC_PERIOD);
631 writel(vsync_width * hsync_period, MDP_DSI_VIDEO_VSYNC_PULSE_WIDTH);
632 writel((img_width + hsync_porch0_bp - 1) << 16 | hsync_porch0_bp,
633 MDP_DSI_VIDEO_DISPLAY_HCTL);
634 writel(vsync_porch0_bp * hsync_period, MDP_DSI_VIDEO_DISPLAY_V_START);
635 writel((img_height + vsync_porch0_bp) * hsync_period,
636 MDP_DSI_VIDEO_DISPLAY_V_END);
637 writel(0x00ABCDEF, MDP_DSI_VIDEO_BORDER_CLR);
638 writel(0x00000000, MDP_DSI_VIDEO_HSYNC_SKEW);
639 writel(0x00000000, MDP_DSI_VIDEO_CTL_POLARITY);
640 // end of cmd mdp
641
642 writel(0x00000001, MDP_DSI_VIDEO_EN); // MDP_DSI_EN ENABLE
643
644 status = PASS;
645 return status;
646}
647
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800648int mipi_dsi_video_config(unsigned short num_of_lanes)
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700649{
650
651 int status = 0;
652 unsigned long ReadValue;
653 unsigned long count = 0;
654 unsigned long low_pwr_stop_mode = 0; // low power mode 0x1111 start from
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800655 // bit16, high spd mode 0x0
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700656 unsigned char eof_bllp_pwr = 0x9; // bit 12, 15, 1:low power stop mode or
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800657 // let cmd mode eng send packets in hs
658 // or lp mode
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700659 unsigned short display_wd = mipi_fb_cfg.width;
660 unsigned short display_ht = mipi_fb_cfg.height;
661 unsigned short image_wd = mipi_fb_cfg.width;
662 unsigned short image_ht = mipi_fb_cfg.height;
663 unsigned short hsync_porch_fp = MIPI_HSYNC_FRONT_PORCH_DCLK;
664 unsigned short hsync_porch_bp = MIPI_HSYNC_BACK_PORCH_DCLK;
665 unsigned short vsync_porch_fp = MIPI_VSYNC_FRONT_PORCH_LINES;
666 unsigned short vsync_porch_bp = MIPI_VSYNC_BACK_PORCH_LINES;
667 unsigned short hsync_width = MIPI_HSYNC_PULSE_WIDTH;
668 unsigned short vsync_width = MIPI_VSYNC_PULSE_WIDTH;
669 unsigned short dst_format = 0;
670 unsigned short traffic_mode = 0;
Kinson Chike5c93432011-06-17 09:10:29 -0700671 unsigned short pack_pattern = 0x12; //BGR
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700672 unsigned char ystride = 3;
673
674 low_pwr_stop_mode = 0x1111; // low pwr mode bit16:HSA, bit20:HBA,
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800675 // bit24:HFP, bit28:PULSE MODE, need enough
676 // time for swithc from LP to HS
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700677 eof_bllp_pwr = 0x9; // low power stop mode or let cmd mode eng send
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800678 // packets in hs or lp mode
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700679
Kinson Chike5c93432011-06-17 09:10:29 -0700680#if DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
681 pack_pattern = 0x21; //RGB
682 config_mdt61_dsi_video_mode();
683
684 /* Two functions make up mdp_setup_dma_p_video_mode with mdt61 panel functions*/
685 mdp_setup_dma_p_video_config(pack_pattern, image_wd, image_ht, MIPI_FB_ADDR, image_wd, ystride);
686 mdp_setup_mdt61_video_dsi_config();
687#else
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700688 status += config_dsi_video_mode(display_wd, display_ht, image_wd, image_ht,
689 hsync_porch_fp, hsync_porch_bp,
690 vsync_porch_fp, vsync_porch_bp, hsync_width,
691 vsync_width, dst_format, traffic_mode,
692 num_of_lanes);
693
694 status +=
695 mdp_setup_dma_p_video_mode(display_wd, display_ht, image_wd, image_ht,
696 hsync_porch_fp, hsync_porch_bp,
697 vsync_porch_fp, vsync_porch_bp, hsync_width,
698 vsync_width, MIPI_FB_ADDR, image_wd,
699 pack_pattern, ystride);
Kinson Chike5c93432011-06-17 09:10:29 -0700700#endif
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700701
702 ReadValue = readl(DSI_INT_CTRL) & 0x00010000;
703 while (ReadValue != 0x00010000) {
704 ReadValue = readl(DSI_INT_CTRL) & 0x00010000;
705 count++;
706 if (count > 0xffff) {
707 status = FAIL;
Kinson Chike5c93432011-06-17 09:10:29 -0700708 dprintf(CRITICAL, "Toshiba Video lane test failed\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700709 return status;
710 }
711 }
712
Kinson Chike5c93432011-06-17 09:10:29 -0700713 dprintf(SPEW, "Toshiba Video lane tested successfully\n");
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700714 return status;
715}
716
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800717int mipi_dsi_cmd_config(unsigned short num_of_lanes)
718{
719
720 int status = 0;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800721 unsigned long input_img_addr = MIPI_FB_ADDR;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800722 unsigned short image_wd = mipi_fb_cfg.width;
723 unsigned short image_ht = mipi_fb_cfg.height;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800724 unsigned short pack_pattern = 0x12;
725 unsigned char ystride = 3;
726
727 writel(0x03ffffff, MDP_INTR_ENABLE);
728 writel(0x0000000b, MDP_OVERLAYPROC0_CFG);
729
730 // ------------- programming MDP_DMA_P_CONFIG ---------------------
731 writel(pack_pattern << 8 | 0x3f | (0 << 25), MDP_DMA_P_CONFIG); // rgb888
732
733 writel(0x00000000, MDP_DMA_P_OUT_XY);
734 writel(image_ht << 16 | image_wd, MDP_DMA_P_SIZE);
735 writel(input_img_addr, MDP_DMA_P_BUF_ADDR);
736
737 writel(image_wd * ystride, MDP_DMA_P_BUF_Y_STRIDE);
738
739 writel(0x00000000, MDP_DMA_P_OP_MODE);
740
741 writel(0x10, MDP_DSI_CMD_MODE_ID_MAP);
742 writel(0x01, MDP_DSI_CMD_MODE_TRIGGER_EN);
743
744 writel(0x0001a000, MDP_AXI_RDMASTER_CONFIG);
745 writel(0x00000004, MDP_AXI_WRMASTER_CONFIG);
746 writel(0x00007777, MDP_MAX_RD_PENDING_CMD_CONFIG);
747 writel(0x8a, MDP_DISP_INTF_SEL);
748
749 return status;
750}
751
752int is_cmd_mode_enabled(void)
753{
754 return cmd_mode_status;
755}
756
Kinson Chike5c93432011-06-17 09:10:29 -0700757#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800758void mipi_dsi_cmd_mode_trigger(void)
759{
760 int status = 0;
761 unsigned short display_wd = mipi_fb_cfg.width;
762 unsigned short display_ht = mipi_fb_cfg.height;
763 unsigned short image_wd = mipi_fb_cfg.width;
764 unsigned short image_ht = mipi_fb_cfg.height;
765 unsigned short dst_format = 0;
766 unsigned short traffic_mode = 0;
767 struct mipi_dsi_panel_config *panel_info = &novatek_panel_info;
768 status += mipi_dsi_cmd_config(panel_info->num_of_lanes);
769 mdelay(50);
770 config_dsi_cmd_mode(display_wd, display_ht, image_wd, image_ht,
771 dst_format, traffic_mode,
772 panel_info->num_of_lanes /* num_of_lanes */ );
773}
Kinson Chike5c93432011-06-17 09:10:29 -0700774#endif
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800775
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700776void mipi_dsi_shutdown(void)
777{
Chandan Uddarajuc1df5652011-03-03 21:15:51 -0800778 writel(0x00000000, MDP_DSI_VIDEO_EN);
Kinson Chikf91907f2011-07-15 10:06:48 -0700779 mdelay(10);
Chandan Uddarajuc1df5652011-03-03 21:15:51 -0800780 writel(0x00000000, MDP_INTR_ENABLE);
781 writel(0x00000003, MDP_OVERLAYPROC0_CFG);
Ajay Dudani8fb36092011-01-27 18:09:50 -0800782 writel(0x01010101, DSI_INT_CTRL);
Chandan Uddarajuc1df5652011-03-03 21:15:51 -0800783 writel(0x13FF3BFF, DSI_ERR_INT_MASK0);
Ajay Dudani8fb36092011-01-27 18:09:50 -0800784 writel(0, DSIPHY_PLL_CTRL_0);
785 writel(0, DSI_CLK_CTRL);
786 writel(0, DSI_CTRL);
Kinson Chike5c93432011-06-17 09:10:29 -0700787#if DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
788 writel(0x0, MMSS_DSI_CC);
789 writel(0x0, MMSS_DSI_PIXEL_CC);
790#else
Chandan Uddarajuc1df5652011-03-03 21:15:51 -0800791 secure_writel(0x0, MMSS_DSI_CC);
792 secure_writel(0x0, MMSS_DSI_PIXEL_CC);
Kinson Chike5c93432011-06-17 09:10:29 -0700793#endif
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700794}
795
796struct fbcon_config *mipi_init(void)
797{
798 int status = 0;
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800799 struct mipi_dsi_panel_config *panel_info = get_panel_info();
Kinson Chike5c93432011-06-17 09:10:29 -0700800 /* Enable MMSS_AHB_ARB_MATER_PORT_E for arbiter master0 and master 1 request */
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700801 writel(0x00001800, MMSS_SFPB_GPREG);
Kinson Chike5c93432011-06-17 09:10:29 -0700802
803#if DISPLAY_MIPI_PANEL_TOSHIBA_MDT61
804 mipi_dsi_phy_init(panel_info);
805#else
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700806 configure_dsicore_dsiclk();
807 configure_dsicore_byteclk();
808 configure_dsicore_pclk();
Kinson Chike5c93432011-06-17 09:10:29 -0700809
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800810 mipi_dsi_phy_ctrl_config(panel_info);
Kinson Chike5c93432011-06-17 09:10:29 -0700811#endif
812
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800813 status += mipi_dsi_panel_initialize(panel_info);
Kinson Chike5c93432011-06-17 09:10:29 -0700814
Shashank Mittalcbd271d2011-01-14 15:18:33 -0800815#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
816 mipi_dsi_cmd_bta_sw_trigger();
817 mipi_novatek_manufacture_id();
818#endif
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700819 mipi_fb_cfg.base = MIPI_FB_ADDR;
820
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800821 if (panel_info->mode == MIPI_VIDEO_MODE)
822 status += mipi_dsi_video_config(panel_info->num_of_lanes);
823
824 if (panel_info->mode == MIPI_CMD_MODE)
825 cmd_mode_status = 1;
826
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700827 return &mipi_fb_cfg;
828}