Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[pandora-kernel.git] / drivers / staging / gma500 / mdfld_dsi_dpi.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  * jim liu <jim.liu@intel.com>
25  * Jackie Li<yaodong.li@intel.com>
26  */
27
28 #include "mdfld_dsi_dpi.h"
29 #include "mdfld_output.h"
30 #include "mdfld_dsi_pkg_sender.h"
31
32
33 static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
34 {
35         u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
36         int timeout = 0;
37
38         if (pipe == 2)
39                 gen_fifo_stat_reg += MIPIC_REG_OFFSET;
40
41         udelay(500);
42
43         /* This will time out after approximately 2+ seconds */
44         while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
45                 udelay(100);
46                 timeout++;
47         }
48
49         if (timeout == 20000)
50                 dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
51 }
52
53 static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
54 {
55         u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
56         int timeout = 0;
57
58         if (pipe == 2)
59                 gen_fifo_stat_reg += MIPIC_REG_OFFSET;
60
61         udelay(500);
62
63         /* This will time out after approximately 2+ seconds */
64         while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) {
65                 udelay(100);
66                 timeout++;
67         }
68         if (timeout == 20000)
69                 dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
70 }
71
72 static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
73 {
74         u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
75         int timeout = 0;
76
77         if (pipe == 2)
78                 gen_fifo_stat_reg += MIPIC_REG_OFFSET;
79
80         udelay(500);
81
82         /* This will time out after approximately 2+ seconds */
83         while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY)
84                                                         != DPI_FIFO_EMPTY)) {
85                 udelay(100);
86                 timeout++;
87         }
88
89         if (timeout == 20000)
90                 dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
91 }
92
93 static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
94 {
95         u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
96         int timeout = 0;
97
98         if (pipe == 2)
99                 intr_stat_reg += MIPIC_REG_OFFSET;
100
101         udelay(500);
102
103         /* This will time out after approximately 2+ seconds */
104         while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) {
105                 udelay(100);
106                 timeout++;
107         }
108
109         if (timeout == 20000)
110                 dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
111 }
112
113
114 /* ************************************************************************* *\
115  * FUNCTION: mdfld_dsi_tpo_ic_init
116  *
117  * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
118  *               restore_display_registers.  since this function does not
119  *               acquire the mutex, it is important that the calling function
120  *               does!
121 \* ************************************************************************* */
122 void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
123 {
124         struct drm_device *dev = dsi_config->dev;
125         u32 dcsChannelNumber = dsi_config->channel_num;
126         u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG; 
127         u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
128         u32 gen_ctrl_val = GEN_LONG_WRITE;
129
130         if (pipe == 2) {
131                 gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET; 
132                 gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
133         }
134
135         gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
136
137         /* Flip page order */
138         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
139         REG_WRITE(gen_data_reg, 0x00008036);
140         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
141         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
142
143         /* 0xF0 */
144         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
145         REG_WRITE(gen_data_reg, 0x005a5af0);
146         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
147         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
148
149         /* Write protection key */
150         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
151         REG_WRITE(gen_data_reg, 0x005a5af1);
152         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
153         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
154
155         /* 0xFC */
156         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
157         REG_WRITE(gen_data_reg, 0x005a5afc);
158         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
159         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
160
161         /* 0xB7 */
162         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
163         REG_WRITE(gen_data_reg, 0x770000b7);
164         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
165         REG_WRITE(gen_data_reg, 0x00000044);
166         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
167         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
168
169         /* 0xB6 */
170         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
171         REG_WRITE(gen_data_reg, 0x000a0ab6);
172         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
173         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
174
175         /* 0xF2 */
176         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
177         REG_WRITE(gen_data_reg, 0x081010f2);
178         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
179         REG_WRITE(gen_data_reg, 0x4a070708);
180         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
181         REG_WRITE(gen_data_reg, 0x000000c5);
182         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
183         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
184
185         /* 0xF8 */
186         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
187         REG_WRITE(gen_data_reg, 0x024003f8);
188         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
189         REG_WRITE(gen_data_reg, 0x01030a04);
190         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
191         REG_WRITE(gen_data_reg, 0x0e020220);
192         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
193         REG_WRITE(gen_data_reg, 0x00000004);
194         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
195         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
196
197         /* 0xE2 */
198         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
199         REG_WRITE(gen_data_reg, 0x398fc3e2);
200         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
201         REG_WRITE(gen_data_reg, 0x0000916f);
202         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
203         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
204
205         /* 0xB0 */
206         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
207         REG_WRITE(gen_data_reg, 0x000000b0);
208         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
209         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
210
211         /* 0xF4 */
212         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
213         REG_WRITE(gen_data_reg, 0x240242f4);
214         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
215         REG_WRITE(gen_data_reg, 0x78ee2002);
216         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
217         REG_WRITE(gen_data_reg, 0x2a071050);
218         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
219         REG_WRITE(gen_data_reg, 0x507fee10);
220         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
221         REG_WRITE(gen_data_reg, 0x10300710);
222         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
223         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
224
225         /* 0xBA */
226         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
227         REG_WRITE(gen_data_reg, 0x19fe07ba);
228         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
229         REG_WRITE(gen_data_reg, 0x101c0a31);
230         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
231         REG_WRITE(gen_data_reg, 0x00000010);
232         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
233         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
234
235         /* 0xBB */
236         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
237         REG_WRITE(gen_data_reg, 0x28ff07bb);
238         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
239         REG_WRITE(gen_data_reg, 0x24280a31);
240         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
241         REG_WRITE(gen_data_reg, 0x00000034);
242         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
243         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
244
245         /* 0xFB */
246         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
247         REG_WRITE(gen_data_reg, 0x535d05fb);
248         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
249         REG_WRITE(gen_data_reg, 0x1b1a2130);
250         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
251         REG_WRITE(gen_data_reg, 0x221e180e);
252         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
253         REG_WRITE(gen_data_reg, 0x131d2120);
254         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
255         REG_WRITE(gen_data_reg, 0x535d0508);
256         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
257         REG_WRITE(gen_data_reg, 0x1c1a2131);
258         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
259         REG_WRITE(gen_data_reg, 0x231f160d);
260         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
261         REG_WRITE(gen_data_reg, 0x111b2220);
262         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
263         REG_WRITE(gen_data_reg, 0x535c2008);
264         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
265         REG_WRITE(gen_data_reg, 0x1f1d2433);
266         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
267         REG_WRITE(gen_data_reg, 0x2c251a10);
268         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
269         REG_WRITE(gen_data_reg, 0x2c34372d);
270         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
271         REG_WRITE(gen_data_reg, 0x00000023);
272         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
273         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
274
275         /* 0xFA */
276         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
277         REG_WRITE(gen_data_reg, 0x525c0bfa);
278         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
279         REG_WRITE(gen_data_reg, 0x1c1c232f);
280         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
281         REG_WRITE(gen_data_reg, 0x2623190e);
282         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
283         REG_WRITE(gen_data_reg, 0x18212625);
284         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
285         REG_WRITE(gen_data_reg, 0x545d0d0e);
286         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
287         REG_WRITE(gen_data_reg, 0x1e1d2333);
288         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
289         REG_WRITE(gen_data_reg, 0x26231a10);
290         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
291         REG_WRITE(gen_data_reg, 0x1a222725);
292         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
293         REG_WRITE(gen_data_reg, 0x545d280f);
294         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
295         REG_WRITE(gen_data_reg, 0x21202635);
296         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
297         REG_WRITE(gen_data_reg, 0x31292013);
298         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
299         REG_WRITE(gen_data_reg, 0x31393d33);
300         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
301         REG_WRITE(gen_data_reg, 0x00000029);
302         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
303         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
304
305         /* Set DM */
306         mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
307         REG_WRITE(gen_data_reg, 0x000100f7);
308         mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
309         REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
310 }
311
312 static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
313                                                 int num_lane, int bpp)
314 {
315         return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); 
316 }
317
318 /*
319  * Calculate the dpi time basing on a given drm mode @mode
320  * return 0 on success.
321  * FIXME: I was using proposed mode value for calculation, may need to 
322  * use crtc mode values later 
323  */
324 int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, 
325                         struct mdfld_dsi_dpi_timing *dpi_timing,
326                         int num_lane, int bpp)
327 {
328         int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
329         int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
330         
331         if(!mode || !dpi_timing) {
332                 DRM_ERROR("Invalid parameter\n");
333                 return -EINVAL;
334         }
335         
336         pclk_hactive = mode->hdisplay;
337         pclk_hfp = mode->hsync_start - mode->hdisplay;
338         pclk_hsync = mode->hsync_end - mode->hsync_start;
339         pclk_hbp = mode->htotal - mode->hsync_end;
340         
341         pclk_vactive = mode->vdisplay;
342         pclk_vfp = mode->vsync_start - mode->vdisplay;
343         pclk_vsync = mode->vsync_end - mode->vsync_start;
344         pclk_vbp = mode->vtotal - mode->vsync_end;
345
346         /*
347          * byte clock counts were calculated by following formula
348          * bclock_count = pclk_count * bpp / num_lane / 8
349          */
350         dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp);
351         dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp);
352         dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp);
353         dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp);
354         dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp);
355         dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp);
356         dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp);
357
358         return 0; 
359 }
360
361 void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
362 {
363         struct drm_device *dev = dsi_config->dev;
364         u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
365         int lane_count = dsi_config->lane_count;
366         struct mdfld_dsi_dpi_timing dpi_timing;
367         struct drm_display_mode *mode = dsi_config->mode;
368         u32 val = 0;
369         
370         /*un-ready device*/
371         REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
372         
373         /*init dsi adapter before kicking off*/
374         REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
375         
376         /*enable all interrupts*/
377         REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
378         
379
380         /*set up func_prg*/
381         val |= lane_count;
382         val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
383                 
384         switch(dsi_config->bpp) {
385         case 16:
386                 val |= DSI_DPI_COLOR_FORMAT_RGB565;
387                 break;
388         case 18:
389                 val |= DSI_DPI_COLOR_FORMAT_RGB666;
390                 break;
391         case 24:
392                 val |= DSI_DPI_COLOR_FORMAT_RGB888;
393                 break;
394         default:
395                 DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
396         }
397         REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
398         
399         REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 
400                         (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
401         REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
402         
403         /*max value: 20 clock cycles of txclkesc*/
404         REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
405         
406         /*min 21 txclkesc, max: ffffh*/
407         REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
408
409         REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
410         
411         /*set DPI timing registers*/
412         mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
413         
414         REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
415         REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
416         REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
417         REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
418         REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
419         REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
420         REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
421         
422         REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
423         
424         /*min: 7d0 max: 4e20*/
425         REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
426         
427         /*set up video mode*/
428         val = 0;
429         val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
430         REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
431         
432         REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
433         
434         REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
435         
436         /*TODO: figure out how to setup these registers*/
437         REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
438         
439         REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
440         /*set device ready*/
441         REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
442 }
443
444 void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
445 {
446         struct drm_device *dev = output->dev;
447         u32 reg_offset = 0;
448         
449         if(output->panel_on) 
450                 return;
451                 
452         if(pipe) 
453                 reg_offset = MIPIC_REG_OFFSET;
454
455         /* clear special packet sent bit */
456         if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
457                 REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
458         }
459                 
460         /*send turn on package*/
461         REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
462         
463         /*wait for SPL_PKG_SENT interrupt*/
464         mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
465         
466         if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
467                 REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
468         }
469
470         output->panel_on = 1;
471
472         /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
473         /* if(pipe == 2) */
474         /*      dev_priv->dpi_panel_on2 = true; */
475         /* else if (pipe == 0) */
476         /*      dev_priv->dpi_panel_on = true; */
477 }
478
479 static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
480 {
481         struct drm_device *dev = output->dev;
482         u32 reg_offset = 0;
483         
484         /*if output is on, or mode setting didn't happen, ignore this*/
485         if((!output->panel_on) || output->first_boot) {
486                 output->first_boot = 0; 
487                 return;
488         }
489         
490         if(pipe)
491                 reg_offset = MIPIC_REG_OFFSET;
492
493         /* Wait for dpi fifo to empty */
494         mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
495
496         /* Clear the special packet interrupt bit if set */
497         if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
498                 REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
499         }
500         
501         if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) {
502                 dev_warn(dev->dev, "try to send the same package again, abort!");
503                 goto shutdown_out;
504         }
505         
506         REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
507
508 shutdown_out:
509         output->panel_on = 0;
510         output->first_boot = 0;
511
512         /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
513         /* if(pipe == 2) */
514         /*      dev_priv->dpi_panel_on2 = false; */
515         /* else if (pipe == 0) */
516         /*      dev_priv->dpi_panel_on = false;  */
517         /* #ifdef CONFIG_PM_RUNTIME*/ 
518         /*      if (drm_psb_ospm && !enable_gfx_rtpm) { */
519         /*              pm_runtime_allow(&gpDrmDevice->pdev->dev); */
520         /*      schedule_delayed_work(&dev_priv->rtpm_work, 30 * 1000); */
521         /* } */
522         /*if (enable_gfx_rtpm) */
523         /*              pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
524         /* #endif */
525 }
526
527 void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
528 {
529         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
530         struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
531         struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
532         int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
533         struct drm_device *dev = dsi_config->dev;
534         struct drm_psb_private *dev_priv = dev->dev_private;
535         u32 mipi_reg = MIPI;
536         u32 pipeconf_reg = PIPEACONF;
537         
538         if(pipe) {
539                 mipi_reg = MIPI_C;
540                 pipeconf_reg = PIPECCONF;
541         }
542         
543         /* Start up display island if it was shutdown */
544         if (!gma_power_begin(dev, true))
545                 return;
546
547         if(on) {
548                 if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
549                         mdfld_dsi_dpi_turn_on(dpi_output, pipe);
550                 } else {
551                         /* Enable mipi port */
552                         REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
553                         REG_READ(mipi_reg);
554
555                         mdfld_dsi_dpi_turn_on(dpi_output, pipe);
556                         mdfld_dsi_tpo_ic_init(dsi_config, pipe);
557                 }
558
559                 if(pipe == 2) {
560                         dev_priv->dpi_panel_on2 = true;
561                 }
562                 else {
563                         dev_priv->dpi_panel_on  = true;
564                 }
565
566         } else {
567                 if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
568                         mdfld_dsi_dpi_shut_down(dpi_output, pipe);
569                 } else {
570                         mdfld_dsi_dpi_shut_down(dpi_output, pipe);
571                         /* Disable mipi port */
572                         REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
573                         REG_READ(mipi_reg);
574                 }
575
576                 if(pipe == 2)
577                         dev_priv->dpi_panel_on2 = false;
578                 else
579                         dev_priv->dpi_panel_on  = false;
580         }
581         gma_power_end(dev);
582 }
583
584 void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
585 {
586         dev_dbg(encoder->dev->dev, "DPMS %s\n",
587                         (mode == DRM_MODE_DPMS_ON ? "on":"off"));
588
589         if (mode == DRM_MODE_DPMS_ON)
590                 mdfld_dsi_dpi_set_power(encoder, true);
591         else {
592                 mdfld_dsi_dpi_set_power(encoder, false);
593 #if 0 /* FIXME */
594 #ifdef CONFIG_PM_RUNTIME
595                 if (enable_gfx_rtpm)
596                         pm_schedule_suspend(&gpDrmDevice->pdev->dev, gfxrtdelay);
597 #endif
598 #endif
599         }
600 }
601
602 bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
603                                      struct drm_display_mode *mode,
604                                      struct drm_display_mode *adjusted_mode)
605 {
606         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
607         struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
608         struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
609
610         if(fixed_mode) {
611                 adjusted_mode->hdisplay = fixed_mode->hdisplay;
612                 adjusted_mode->hsync_start = fixed_mode->hsync_start;
613                 adjusted_mode->hsync_end = fixed_mode->hsync_end;
614                 adjusted_mode->htotal = fixed_mode->htotal;
615                 adjusted_mode->vdisplay = fixed_mode->vdisplay;
616                 adjusted_mode->vsync_start = fixed_mode->vsync_start;
617                 adjusted_mode->vsync_end = fixed_mode->vsync_end;
618                 adjusted_mode->vtotal = fixed_mode->vtotal;
619                 adjusted_mode->clock = fixed_mode->clock;
620                 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
621         }
622         
623         return true;
624 }
625
626 void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) 
627 {
628         mdfld_dsi_dpi_set_power(encoder, false);
629 }
630
631 void mdfld_dsi_dpi_commit(struct drm_encoder *encoder) 
632 {
633         mdfld_dsi_dpi_set_power(encoder, true);
634 }
635
636 void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
637                                    struct drm_display_mode *mode,
638                                    struct drm_display_mode *adjusted_mode)
639 {
640         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
641         struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
642         struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
643         struct drm_device *dev = dsi_config->dev;
644         struct drm_psb_private *dev_priv = dev->dev_private;
645         int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
646         
647         u32 pipeconf_reg = PIPEACONF;
648         u32 dspcntr_reg = DSPACNTR;
649         u32 mipi_reg = MIPI;
650         u32 reg_offset = 0;
651         
652         u32 pipeconf = dev_priv->pipeconf;
653         u32 dspcntr = dev_priv->dspcntr;
654         u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
655         
656         dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
657                                 mode->hdisplay, mode->vdisplay, pipe);
658
659         if(pipe) {
660                 pipeconf_reg = PIPECCONF;
661                 dspcntr_reg = DSPCCNTR;
662                 mipi_reg = MIPI_C;
663                 reg_offset = MIPIC_REG_OFFSET;
664         } else {
665                 mipi |= 2;
666         }
667         
668         if (!gma_power_begin(dev, true))
669                 return;
670
671         /* Set up mipi port FIXME: do at init time */
672         REG_WRITE(mipi_reg, mipi);
673         REG_READ(mipi_reg);
674
675         /* Set up DSI controller DPI interface */
676         mdfld_dsi_dpi_controller_init(dsi_config, pipe);
677
678         if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
679                 /* Turn on DPI interface */
680                 mdfld_dsi_dpi_turn_on(dpi_output, pipe);
681         }
682         
683         /* Set up pipe */
684         REG_WRITE(pipeconf_reg, pipeconf);
685         REG_READ(pipeconf_reg);
686         
687         /* Set up display plane */
688         REG_WRITE(dspcntr_reg, dspcntr);
689         REG_READ(dspcntr_reg);
690         
691         msleep(20); /* FIXME: this should wait for vblank */
692         
693         dev_dbg(dev->dev, "State %x, power %d\n",
694                 REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
695                 dpi_output->panel_on);
696
697         if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
698                 /* Init driver ic */
699                 mdfld_dsi_tpo_ic_init(dsi_config, pipe);
700                 /* Init backlight */
701                 mdfld_dsi_brightness_init(dsi_config, pipe);
702         }
703         gma_power_end(dev);
704 }
705
706
707 /*
708  * Init DSI DPI encoder. 
709  * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
710  * return pointer of newly allocated DPI encoder, NULL on error
711  */ 
712 struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, 
713                                 struct mdfld_dsi_connector *dsi_connector,
714                                 struct panel_funcs *p_funcs)
715 {
716         struct mdfld_dsi_dpi_output *dpi_output = NULL;
717         struct mdfld_dsi_config *dsi_config;
718         struct drm_connector *connector = NULL;
719         struct drm_encoder *encoder = NULL;
720         struct drm_display_mode *fixed_mode = NULL;
721         int pipe;
722         u32 data;
723         int ret;
724
725         if (!dsi_connector || !p_funcs) {
726                 WARN_ON(1);
727                 return NULL;
728         }
729
730         dsi_config = mdfld_dsi_get_config(dsi_connector);
731         pipe = dsi_connector->pipe;
732
733         /* Panel hard-reset */
734         if (p_funcs->reset) {
735                 ret = p_funcs->reset(pipe);
736                 if (ret) {
737                         DRM_ERROR("Panel %d hard-reset failed\n", pipe);
738                         return NULL;
739                 }
740         }
741
742         /* Panel drvIC init */
743         if (p_funcs->drv_ic_init)
744                 p_funcs->drv_ic_init(dsi_config, pipe);
745
746         /* Panel power mode detect */
747         ret = mdfld_dsi_get_power_mode(dsi_config,
748                                         &data,
749                                         MDFLD_DSI_LP_TRANSMISSION);
750         if (ret) {
751                 DRM_ERROR("Panel %d get power mode failed\n", pipe);
752                 dsi_connector->status = connector_status_disconnected;
753         } else {
754                 DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
755                 dsi_connector->status = connector_status_connected;
756         }
757
758         dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
759         if(!dpi_output) {
760                 dev_err(dev->dev, "No memory for dsi_dpi_output\n");
761                 return NULL;
762         }
763
764         if(dsi_connector->pipe) 
765                 dpi_output->panel_on = 0;
766         else
767                 dpi_output->panel_on = 0;
768         
769         dpi_output->dev = dev;
770         dpi_output->p_funcs = p_funcs;
771         dpi_output->first_boot = 1;
772         
773         /* Get fixed mode */
774         dsi_config = mdfld_dsi_get_config(dsi_connector);
775         fixed_mode = dsi_config->fixed_mode;
776         
777         /* Create drm encoder object */
778         connector = &dsi_connector->base.base;
779         encoder = &dpi_output->base.base;
780         drm_encoder_init(dev,
781                         encoder,
782                         p_funcs->encoder_funcs,
783                         DRM_MODE_ENCODER_MIPI);
784         drm_encoder_helper_add(encoder,
785                                 p_funcs->encoder_helper_funcs);
786         
787         /* Attach to given connector */
788         drm_mode_connector_attach_encoder(connector, encoder);
789         
790         /* Set possible crtcs and clones */
791         if(dsi_connector->pipe) {
792                 encoder->possible_crtcs = (1 << 2);
793                 encoder->possible_clones = (1 << 1);
794         } else {
795                 encoder->possible_crtcs = (1 << 0);
796                 encoder->possible_clones = (1 << 0);
797         }
798         return &dpi_output->base;
799 }
800