gma500: Fix DPU build
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / gma500 / mdfld_dsi_dpi.c
blob6e03a91e947ea6cd5687f6eeca9a59dbd90df96e
1 /*
2 * Copyright © 2010 Intel Corporation
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:
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.
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.
23 * Authors:
24 * jim liu <jim.liu@intel.com>
25 * Jackie Li<yaodong.li@intel.com>
28 #include "mdfld_dsi_dpi.h"
29 #include "mdfld_output.h"
30 #include "mdfld_dsi_pkg_sender.h"
33 static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
35 u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
36 int timeout = 0;
38 if (pipe == 2)
39 gen_fifo_stat_reg += MIPIC_REG_OFFSET;
41 udelay(500);
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++;
49 if (timeout == 20000)
50 dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
53 static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
55 u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
56 int timeout = 0;
58 if (pipe == 2)
59 gen_fifo_stat_reg += MIPIC_REG_OFFSET;
61 udelay(500);
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++;
68 if (timeout == 20000)
69 dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
72 static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
74 u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
75 int timeout = 0;
77 if (pipe == 2)
78 gen_fifo_stat_reg += MIPIC_REG_OFFSET;
80 udelay(500);
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++;
89 if (timeout == 20000)
90 dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
93 static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
95 u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
96 int timeout = 0;
98 if (pipe == 2)
99 intr_stat_reg += MIPIC_REG_OFFSET;
101 udelay(500);
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++;
109 if (timeout == 20000)
110 dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
114 /* ************************************************************************* *\
115 * FUNCTION: mdfld_dsi_tpo_ic_init
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)
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;
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;
135 gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
312 static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
313 int num_lane, int bpp)
315 return (u16)((pixel_clock_count * bpp) / (num_lane * 8));
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
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)
328 int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
329 int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
331 if(!mode || !dpi_timing) {
332 DRM_ERROR("Invalid parameter\n");
333 return -EINVAL;
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;
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;
347 * byte clock counts were calculated by following formula
348 * bclock_count = pclk_count * bpp / num_lane / 8
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);
358 return 0;
361 void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
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;
370 /*un-ready device*/
371 REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
373 /*init dsi adapter before kicking off*/
374 REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
376 /*enable all interrupts*/
377 REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
380 /*set up func_prg*/
381 val |= lane_count;
382 val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
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);
397 REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
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);
403 /*max value: 20 clock cycles of txclkesc*/
404 REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
406 /*min 21 txclkesc, max: ffffh*/
407 REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
409 REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
411 /*set DPI timing registers*/
412 mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
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);
422 REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
424 /*min: 7d0 max: 4e20*/
425 REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
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);
432 REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
434 REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
436 /*TODO: figure out how to setup these registers*/
437 REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
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);
444 void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
446 struct drm_device *dev = output->dev;
447 u32 reg_offset = 0;
449 if(output->panel_on)
450 return;
452 if(pipe)
453 reg_offset = MIPIC_REG_OFFSET;
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);
460 /*send turn on package*/
461 REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
463 /*wait for SPL_PKG_SENT interrupt*/
464 mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
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);
470 output->panel_on = 1;
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; */
479 static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
481 struct drm_device *dev = output->dev;
482 u32 reg_offset = 0;
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;
490 if(pipe)
491 reg_offset = MIPIC_REG_OFFSET;
493 /* Wait for dpi fifo to empty */
494 mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
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);
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;
506 REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
508 shutdown_out:
509 output->panel_on = 0;
510 output->first_boot = 0;
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 */
527 void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
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;
538 if(pipe) {
539 mipi_reg = MIPI_C;
540 pipeconf_reg = PIPECCONF;
543 /* Start up display island if it was shutdown */
544 if (!gma_power_begin(dev, true))
545 return;
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);
555 mdfld_dsi_dpi_turn_on(dpi_output, pipe);
556 mdfld_dsi_tpo_ic_init(dsi_config, pipe);
559 if(pipe == 2) {
560 dev_priv->dpi_panel_on2 = true;
562 else {
563 dev_priv->dpi_panel_on = true;
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);
576 if(pipe == 2)
577 dev_priv->dpi_panel_on2 = false;
578 else
579 dev_priv->dpi_panel_on = false;
581 gma_power_end(dev);
584 void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
586 dev_dbg(encoder->dev->dev, "DPMS %s\n",
587 (mode == DRM_MODE_DPMS_ON ? "on":"off"));
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
602 bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
603 struct drm_display_mode *mode,
604 struct drm_display_mode *adjusted_mode)
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;
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);
623 return true;
626 void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder)
628 mdfld_dsi_dpi_set_power(encoder, false);
631 void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
633 mdfld_dsi_dpi_set_power(encoder, true);
636 void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
637 struct drm_display_mode *mode,
638 struct drm_display_mode *adjusted_mode)
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);
647 u32 pipeconf_reg = PIPEACONF;
648 u32 dspcntr_reg = DSPACNTR;
649 u32 mipi_reg = MIPI;
650 u32 reg_offset = 0;
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;
656 dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
657 mode->hdisplay, mode->vdisplay, pipe);
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;
668 if (!gma_power_begin(dev, true))
669 return;
671 /* Set up mipi port FIXME: do at init time */
672 REG_WRITE(mipi_reg, mipi);
673 REG_READ(mipi_reg);
675 /* Set up DSI controller DPI interface */
676 mdfld_dsi_dpi_controller_init(dsi_config, pipe);
678 if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
679 /* Turn on DPI interface */
680 mdfld_dsi_dpi_turn_on(dpi_output, pipe);
683 /* Set up pipe */
684 REG_WRITE(pipeconf_reg, pipeconf);
685 REG_READ(pipeconf_reg);
687 /* Set up display plane */
688 REG_WRITE(dspcntr_reg, dspcntr);
689 REG_READ(dspcntr_reg);
691 msleep(20); /* FIXME: this should wait for vblank */
693 dev_dbg(dev->dev, "State %x, power %d\n",
694 REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
695 dpi_output->panel_on);
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);
703 gma_power_end(dev);
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
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)
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;
725 if (!dsi_connector || !p_funcs) {
726 WARN_ON(1);
727 return NULL;
730 dsi_config = mdfld_dsi_get_config(dsi_connector);
731 pipe = dsi_connector->pipe;
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;
742 /* Panel drvIC init */
743 if (p_funcs->drv_ic_init)
744 p_funcs->drv_ic_init(dsi_config, pipe);
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;
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;
764 if(dsi_connector->pipe)
765 dpi_output->panel_on = 0;
766 else
767 dpi_output->panel_on = 0;
769 dpi_output->dev = dev;
770 dpi_output->p_funcs = p_funcs;
771 dpi_output->first_boot = 1;
773 /* Get fixed mode */
774 dsi_config = mdfld_dsi_get_config(dsi_connector);
775 fixed_mode = dsi_config->fixed_mode;
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);
787 /* Attach to given connector */
788 drm_mode_connector_attach_encoder(connector, encoder);
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);
798 return &dpi_output->base;