gma500: Medfield support
[pandora-kernel.git] / drivers / staging / gma500 / mdfld_dsi_output.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_output.h"
29 #include "mdfld_dsi_dbi.h"
30 #include "mdfld_dsi_dpi.h"
31 #include "mdfld_output.h"
32 #include <asm/intel_scu_ipc.h>
33 #include "mdfld_dsi_pkg_sender.h"
34 #include <linux/pm_runtime.h>
35
36 #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
37
38 /* get the CABC LABC from command line. */
39 static int CABC_control = 1;
40 static int LABC_control = 1;
41
42 #ifdef MODULE
43 module_param (CABC_control, int, 0644);
44 module_param (LABC_control, int, 0644);
45 #else
46 static int __init parse_CABC_control(char *arg)
47 {
48         /* CABC control can be passed in as a cmdline parameter */
49         /* to enable this feature add CABC=1 to cmdline */
50         /* to disable this feature add CABC=0 to cmdline */
51         if (!arg)
52                 return -EINVAL;
53
54         if (!strcasecmp(arg, "0"))
55                 CABC_control = 0;
56         else if (!strcasecmp (arg, "1"))
57                 CABC_control = 1;
58
59         return 0;
60 }
61 early_param ("CABC", parse_CABC_control);
62
63 static int __init parse_LABC_control(char *arg)
64 {
65         /* LABC control can be passed in as a cmdline parameter */
66         /* to enable this feature add LABC=1 to cmdline */
67         /* to disable this feature add LABC=0 to cmdline */
68         if (!arg)
69                 return -EINVAL;
70
71         if (!strcasecmp(arg, "0"))
72                 LABC_control = 0;
73         else if (!strcasecmp (arg, "1"))
74                 LABC_control = 1;
75
76         return 0;
77 }
78 early_param ("LABC", parse_LABC_control);
79 #endif
80
81 /**
82  * make these MCS command global 
83  * we don't need 'movl' everytime we send them.
84  * FIXME: these datas were provided by OEM, we should get them from GCT.
85  **/
86 static u32 mdfld_dbi_mcs_hysteresis[] = {
87         0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
88         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
89         0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
90         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
91         0x000000ff,
92 };
93
94 static u32 mdfld_dbi_mcs_display_profile[] = {
95         0x50281450, 0x0000c882, 0x00000000, 0x00000000,
96         0x00000000,
97 };
98
99 static u32 mdfld_dbi_mcs_kbbc_profile[] = {
100         0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
101 }; 
102         
103 static u32 mdfld_dbi_mcs_gamma_profile[] = {
104         0x81111158, 0x88888888, 0x88888888,
105 }; 
106
107 /*
108  * write hysteresis values.
109  */
110 static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config * dsi_config, int pipe)
111 {
112         struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
113
114         if(!sender) {
115                 WARN_ON(1);
116                 return;
117         }
118         mdfld_dsi_send_mcs_long_hs(sender,
119                                    mdfld_dbi_mcs_hysteresis,
120                                    17,
121                                    MDFLD_DSI_SEND_PACKAGE);
122 }
123
124 /*
125  * write display profile values.
126  */
127 static void mdfld_dsi_write_display_profile (struct mdfld_dsi_config * dsi_config, int pipe)
128 {
129         struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
130
131         if(!sender) {
132                 WARN_ON(1);
133                 return;
134         }
135         mdfld_dsi_send_mcs_long_hs(sender,
136                                    mdfld_dbi_mcs_display_profile,
137                                    5,
138                                    MDFLD_DSI_SEND_PACKAGE);
139 }
140
141 /*
142  * write KBBC profile values.
143  */
144 static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe)
145 {
146         struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
147
148         if(!sender) {
149                 WARN_ON(1);
150                 return;
151         }
152         mdfld_dsi_send_mcs_long_hs(sender,
153                                    mdfld_dbi_mcs_kbbc_profile,
154                                    4,
155                                    MDFLD_DSI_SEND_PACKAGE);
156 }
157
158 /**
159  * write gamma setting.
160  */
161 static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config * dsi_config, int pipe)
162 {
163         struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
164
165         if(!sender) {
166                 WARN_ON(1);
167                 return;
168         }
169         mdfld_dsi_send_mcs_long_hs(sender,
170                                    mdfld_dbi_mcs_gamma_profile,
171                                    3,
172                                    MDFLD_DSI_SEND_PACKAGE);
173 }
174
175 /**
176  * Check and see if the generic control or data buffer is empty and ready.
177  */
178 void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat)
179 {
180         u32 GEN_BF_time_out_count = 0;
181         
182         /* Check MIPI Adatper command registers */
183         for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++)
184         {
185                 if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat)
186                         break;
187                 udelay (100);
188         }
189
190         if (GEN_BF_time_out_count == GEN_FB_TIME_OUT)
191                 dev_err(dev->dev,
192         "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n",
193                                                 gen_fifo_stat_reg);
194 }
195
196 /**
197  * Manage the DSI MIPI keyboard and display brightness.
198  * FIXME: this is exported to OSPM code. should work out an specific 
199  * display interface to OSPM. 
200  */
201 void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe)
202 {
203         struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
204         struct drm_device * dev = sender->dev;
205         struct drm_psb_private * dev_priv = dev->dev_private;
206         u32 gen_ctrl_val;
207         
208         if(!sender) {
209                 WARN_ON(1);
210                 return;
211         }
212         /* Set default display backlight value to 85% (0xd8)*/
213         mdfld_dsi_send_mcs_short_hs(sender,
214                                     write_display_brightness,
215                                     0xd8,
216                                     1,
217                                     MDFLD_DSI_SEND_PACKAGE);
218
219         /* Set minimum brightness setting of CABC function to 20% (0x33)*/
220         mdfld_dsi_send_mcs_short_hs(sender,
221                                     write_cabc_min_bright,
222                                     0x33,
223                                     1,
224                                     MDFLD_DSI_SEND_PACKAGE);
225
226         mdfld_dsi_write_hysteresis (dsi_config, pipe);
227         mdfld_dsi_write_display_profile (dsi_config, pipe);
228         mdfld_dsi_write_kbbc_profile (dsi_config, pipe);
229         mdfld_dsi_write_gamma_setting (dsi_config, pipe);
230
231         /* Enable backlight or/and LABC */
232         gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON;
233         if (LABC_control == 1 || CABC_control == 1)
234                 gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO;
235
236         if (LABC_control == 1)
237                 gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON;
238
239         dev_priv->mipi_ctrl_display = gen_ctrl_val;
240
241         mdfld_dsi_send_mcs_short_hs(sender,
242                                     write_ctrl_display,
243                                     (u8)gen_ctrl_val,
244                                     1,
245                                     MDFLD_DSI_SEND_PACKAGE);
246
247         if (CABC_control == 0)
248                 return;
249         mdfld_dsi_send_mcs_short_hs(sender,
250                                     write_ctrl_cabc,
251                                     UI_IMAGE,
252                                     1,
253                                     MDFLD_DSI_SEND_PACKAGE);
254 }
255
256 /**
257  * Manage the mipi display brightness.
258  * TODO: refine this interface later
259  */
260 void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level)
261 {
262         struct mdfld_dsi_pkg_sender *sender;
263         struct drm_psb_private *dev_priv;
264         struct mdfld_dsi_config *dsi_config;
265         u32 gen_ctrl_val = 0;
266         int p_type = TMD_VID;   
267         
268         if (!dev || (pipe != 0 && pipe != 2)) {
269                 dev_err(dev->dev, "Invalid parameter\n");
270                 return;
271         }
272
273         p_type = mdfld_get_panel_type(dev, 0);
274
275         dev_priv = dev->dev_private;
276
277         if(pipe)
278                 dsi_config = dev_priv->dsi_configs[1];
279         else
280                 dsi_config = dev_priv->dsi_configs[0];
281
282         sender = mdfld_dsi_get_pkg_sender(dsi_config);
283
284         if(!sender) {
285                 WARN_ON(1);
286                 return;
287         }
288
289         gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff;
290
291         dev_dbg(dev->dev, "pipe = %d, gen_ctrl_val = %d.  \n", pipe, gen_ctrl_val);
292         
293         if(p_type == TMD_VID || p_type == TMD_CMD){
294                 /* Set display backlight value */
295                 mdfld_dsi_send_mcs_short_hs(sender, 
296                                         tmd_write_display_brightness, 
297                                         (u8)gen_ctrl_val, 
298                                          1, 
299                                         MDFLD_DSI_SEND_PACKAGE);                
300         } else {                        
301                 /* Set display backlight value */
302                 mdfld_dsi_send_mcs_short_hs(sender,
303                                     write_display_brightness,
304                                     (u8)gen_ctrl_val,
305                                     1,
306                                     MDFLD_DSI_SEND_PACKAGE);
307
308
309                 /* Enable backlight control */
310                 if (level == 0)
311                         gen_ctrl_val = 0;
312                 else 
313                         gen_ctrl_val = dev_priv->mipi_ctrl_display;
314
315                 mdfld_dsi_send_mcs_short_hs(sender,
316                                     write_ctrl_display,
317                                    (u8)gen_ctrl_val,
318                                    1,
319                                    MDFLD_DSI_SEND_PACKAGE);
320         }
321 }
322
323 /*
324  * shut down DSI controller
325  */ 
326 void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe)
327 {
328         struct drm_device * dev;
329         u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
330         int retry = 100;
331         
332         if (!dsi_config) {
333                 WARN_ON(1);
334                 return;
335         }
336         
337         dev = dsi_config->dev;
338         
339         if (!gma_power_begin(dev, true)) {
340                 dev_err(dev->dev, "hw begin failed\n");
341                 return;
342         }
343                 
344         if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) &  DSI_DEVICE_READY)) 
345                 goto shutdown_out;
346         
347         /*send shut down package, clean packet send bit first*/
348         if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
349                 REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), 
350                                 (REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT));
351         }
352         
353         /*send shut down package in HS*/
354         REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
355         
356         
357         /*
358          * make sure shut down is sent.
359          * FIXME: add max retry counter
360          */
361         while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
362                 retry--;
363                 
364                 if(!retry) {
365                         dev_err(dev->dev, "timeout\n");
366                         break;
367                 }
368         }
369         
370         /*sleep 1 ms to ensure shutdown finished*/
371         msleep(100);
372         
373         /*un-ready device*/
374         REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
375                            (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & ~DSI_DEVICE_READY));
376
377 shutdown_out:                      
378         gma_power_end(dev);
379 }
380
381 void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe)
382 {
383         struct drm_device * dev;
384         u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
385         int retry = 100;
386         
387         
388         if (!dsi_config) {
389                 WARN_ON(1);
390                 return;
391         }
392         
393         dev = dsi_config->dev;
394         dev_dbg(dev->dev, "starting up DSI controller on pipe %d...\n", pipe);
395         
396         if (!gma_power_begin(dev, true)) {
397                 dev_err(dev->dev, "hw begin failed\n");
398                 return;
399         }
400         
401         if((REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY)) 
402                 goto startup_out;
403         
404         /*if config DPI, turn on DPI interface*/
405         if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
406                 if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
407                         REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
408                 }
409                 
410                 REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
411                 
412                 /*
413                  * make sure shut down is sent.
414                  * FIXME: add max retry counter
415                  */
416                 while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
417                         retry--;
418                         if(!retry) {
419                                 dev_err(dev->dev, "timeout\n");
420                                 break;
421                         }
422                 }
423                 
424                 msleep(100);
425         }
426         
427         /*set device ready*/
428         REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
429                            (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) | DSI_DEVICE_READY));
430
431 startup_out:    
432         gma_power_end(dev);
433 }
434
435 /*
436  * NOTE: this function was used by OSPM.
437  * TODO: will be removed later, should work out display interfaces for OSPM
438  */
439 void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
440 {
441         if(!dsi_config || ((pipe != 0) && (pipe != 2))) {
442                 WARN_ON(1);
443                 return;
444         }
445
446         if(dsi_config->type)
447                 mdfld_dsi_dpi_controller_init(dsi_config, pipe);
448         else
449                 mdfld_dsi_controller_dbi_init(dsi_config, pipe);
450 }
451
452 static void mdfld_dsi_connector_save(struct drm_connector * connector)
453 {
454 }
455
456 static void mdfld_dsi_connector_restore(struct drm_connector * connector)
457 {
458 }
459
460 static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force)
461 {
462         return connector_status_connected;
463 }
464
465 static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
466                                                                                         struct drm_property * property,
467                                                                                         uint64_t value)
468 {
469         struct drm_encoder * encoder = connector->encoder;
470         struct backlight_device * psb_bd;
471
472         if (!strcmp(property->name, "scaling mode") && encoder) {
473                 struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
474                 bool bTransitionFromToCentered;
475                 uint64_t curValue;
476
477                 if (!psb_crtc)
478                         goto set_prop_error;
479
480                 switch (value) {
481                 case DRM_MODE_SCALE_FULLSCREEN:
482                         break;
483                 case DRM_MODE_SCALE_NO_SCALE:
484                         break;
485                 case DRM_MODE_SCALE_ASPECT:
486                         break;
487                 default:
488                         goto set_prop_error;
489                 }
490
491                 if (drm_connector_property_get_value(connector, property, &curValue))
492                         goto set_prop_error;
493
494                 if (curValue == value)
495                         goto set_prop_done;
496
497                 if (drm_connector_property_set_value(connector, property, value))
498                         goto set_prop_error;
499
500                 bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
501                         (value == DRM_MODE_SCALE_NO_SCALE);
502
503                 if (psb_crtc->saved_mode.hdisplay != 0 &&
504                     psb_crtc->saved_mode.vdisplay != 0) {
505                         if (bTransitionFromToCentered) {
506                                 if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode,
507                                             encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
508                                         goto set_prop_error;
509                         } else {
510                                 struct drm_encoder_helper_funcs *pEncHFuncs  = encoder->helper_private;
511                                 pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode,
512                                                      &psb_crtc->saved_adjusted_mode);
513                         }
514                 }
515         } else if (!strcmp(property->name, "backlight") && encoder) {
516                 dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
517                 if (drm_connector_property_set_value(connector, property, value))
518                         goto set_prop_error;
519                 else {
520                         dev_dbg(encoder->dev->dev,
521                                         "set brightness to %d", (int)value);
522                         psb_bd = psb_get_backlight_device();
523                         if(psb_bd) {
524                                 psb_bd->props.brightness = value;
525                                 psb_set_brightness(psb_bd);
526                         }
527                 }
528         } 
529 set_prop_done:
530     return 0;
531 set_prop_error:
532     return -1;
533 }
534
535 static void mdfld_dsi_connector_destroy(struct drm_connector * connector)
536 {
537         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
538         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
539         struct mdfld_dsi_pkg_sender * sender;
540         
541         if(!dsi_connector)
542                 return;
543         
544         drm_sysfs_connector_remove(connector);
545         drm_connector_cleanup(connector);
546         
547         sender = dsi_connector->pkg_sender;
548
549         mdfld_dsi_pkg_sender_destroy(sender);
550
551         kfree(dsi_connector);
552 }
553
554 static int mdfld_dsi_connector_get_modes(struct drm_connector * connector)
555 {
556         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
557         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
558         struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
559         struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
560         struct drm_display_mode * dup_mode = NULL;
561         struct drm_device * dev = connector->dev;
562         
563         connector->display_info.min_vfreq = 0;
564         connector->display_info.max_vfreq = 200;
565         connector->display_info.min_hfreq = 0;
566         connector->display_info.max_hfreq = 200;
567
568         if(fixed_mode) {
569                 dev_dbg(dev->dev, "fixed_mode %dx%d\n",
570                         fixed_mode->hdisplay, fixed_mode->vdisplay);
571                 
572                 dup_mode = drm_mode_duplicate(dev, fixed_mode);
573                 drm_mode_probed_add(connector, dup_mode);
574                 return 1;
575         }
576         dev_err(dev->dev, "Didn't get any modes!\n");
577         return 0;
578 }
579
580 static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode)
581 {
582         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
583         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
584         struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
585         struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
586
587         dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n",
588                                                         mode, fixed_mode);
589
590         if(mode->flags & DRM_MODE_FLAG_DBLSCAN) 
591                 return MODE_NO_DBLESCAN;
592
593         if(mode->flags & DRM_MODE_FLAG_INTERLACE)
594                 return MODE_NO_INTERLACE;
595
596         /**
597          * FIXME: current DC has no fitting unit, reject any mode setting request
598          * will figure out a way to do up-scaling(pannel fitting) later.  
599          **/
600         if(fixed_mode) {
601                 if(mode->hdisplay != fixed_mode->hdisplay)
602                         return MODE_PANEL;
603
604                 if(mode->vdisplay != fixed_mode->vdisplay)
605                         return MODE_PANEL;
606         }
607         dev_dbg(connector->dev->dev, "mode ok\n");
608
609         return MODE_OK;
610 }
611
612 static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
613 {
614 #ifdef CONFIG_PM_RUNTIME
615         struct drm_device * dev = connector->dev;
616         struct drm_psb_private * dev_priv = dev->dev_private;
617         bool panel_on, panel_on2;
618 #endif
619         /* First, execute DPMS */
620         drm_helper_connector_dpms(connector, mode);
621
622 #ifdef CONFIG_PM_RUNTIME
623         if(mdfld_panel_dpi(dev)) {
624                 /* DPI panel */
625                 panel_on = dev_priv->dpi_panel_on;
626                 panel_on2 = dev_priv->dpi_panel_on2;
627         } else {
628                 /* DBI panel */
629                 panel_on = dev_priv->dbi_panel_on;
630                 panel_on2 = dev_priv->dbi_panel_on2;
631         }
632
633         /* Then check all display panels + monitors status */
634         if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL)
635                                                 & HDMIB_PORT_EN)) {
636                 /*request rpm idle*/
637                 if(dev_priv->rpm_enabled)
638                         pm_request_idle(&dev->pdev->dev);
639         }
640         /*
641          * if rpm wasn't enabled yet, try to allow it
642          * FIXME: won't enable rpm for DPI since DPI
643          * CRTC setting is a little messy now.
644          * Enable it later!
645          */
646 #if 0
647         if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev))
648                 ospm_runtime_pm_allow(dev);
649 #endif
650 #endif
651 }
652
653 static struct drm_encoder * mdfld_dsi_connector_best_encoder(
654                                         struct drm_connector * connector) 
655 {
656         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
657         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
658         struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
659         struct mdfld_dsi_encoder * encoder = NULL;
660         
661         if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) 
662                 encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI];
663         else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) 
664                 encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI];
665         
666         dev_dbg(connector->dev->dev, "get encoder %p\n", encoder);
667         
668         if(!encoder) {
669                 dev_err(connector->dev->dev,
670                         "Invalid encoder for type %d\n", dsi_config->type);
671                 return NULL;
672         }
673         dsi_config->encoder = encoder;  
674         return &encoder->base;  
675 }
676
677 /* DSI connector funcs */
678 static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
679         .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
680         .save = mdfld_dsi_connector_save,
681         .restore = mdfld_dsi_connector_restore,
682         .detect = mdfld_dsi_connector_detect,
683         .fill_modes = drm_helper_probe_single_connector_modes,
684         .set_property = mdfld_dsi_connector_set_property,
685         .destroy = mdfld_dsi_connector_destroy,
686 };
687
688 /* DSI connector helper funcs */
689 static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = {
690         .get_modes = mdfld_dsi_connector_get_modes,
691         .mode_valid = mdfld_dsi_connector_mode_valid,
692         .best_encoder = mdfld_dsi_connector_best_encoder,
693 };
694
695 static int mdfld_dsi_get_default_config(struct drm_device * dev, 
696                                                                                 struct mdfld_dsi_config * config, int pipe)
697 {
698         if(!dev || !config) {
699                 WARN_ON(1);
700                 return -EINVAL;
701         }
702         
703         config->bpp = 24;
704         config->type = mdfld_panel_dpi(dev);
705         config->lane_count = 2;
706         config->channel_num = 0;
707         /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/
708         if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
709                 config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE;
710         } else {
711                 config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE;
712         }
713         
714         return 0;
715 }
716
717 /*
718  * Returns the panel fixed mode from configuration. 
719  */
720 struct drm_display_mode *
721 mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
722 {
723         struct drm_device *dev = dsi_config->dev;
724         struct drm_display_mode *mode;
725         struct drm_psb_private *dev_priv = dev->dev_private;
726         struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
727         bool use_gct = false;
728
729         mode = kzalloc(sizeof(*mode), GFP_KERNEL);
730         if (!mode) {
731                 dev_err(dev->dev, "Out of memory for mode\n");
732                 return NULL;
733         }
734         if (use_gct) {
735                 dev_dbg(dev->dev, "gct find MIPI panel.\n");
736
737                 mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
738                 mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
739                 mode->hsync_start = mode->hdisplay + \
740                                 ((ti->hsync_offset_hi << 8) | \
741                                 ti->hsync_offset_lo);
742                 mode->hsync_end = mode->hsync_start + \
743                                 ((ti->hsync_pulse_width_hi << 8) | \
744                                 ti->hsync_pulse_width_lo);
745                 mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
746                                                                 ti->hblank_lo);
747                 mode->vsync_start = \
748                         mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
749                                                 ti->vsync_offset_lo);
750                 mode->vsync_end = \
751                         mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
752                                                 ti->vsync_pulse_width_lo);
753                 mode->vtotal = mode->vdisplay + \
754                                 ((ti->vblank_hi << 8) | ti->vblank_lo);
755                 mode->clock = ti->pixel_clock * 10;
756
757                 dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
758                 dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
759                 dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
760                 dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
761                 dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
762                 dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
763                 dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
764                 dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
765                 dev_dbg(dev->dev, "clock is %d\n", mode->clock);
766         } else {
767                 if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { 
768                         if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
769                                 mode->hdisplay = 480;
770                                 mode->vdisplay = 854;
771                                 mode->hsync_start = 487;
772                                 mode->hsync_end = 490;
773                                 mode->htotal = 499;
774                                 mode->vsync_start = 861;
775                                 mode->vsync_end = 865;
776                                 mode->vtotal = 873;
777                                 mode->clock = 33264;
778                         } else {
779                                 mode->hdisplay = 864;
780                                 mode->vdisplay = 480;
781                                 mode->hsync_start = 873;
782                                 mode->hsync_end = 876;
783                                 mode->htotal = 887;
784                                 mode->vsync_start = 487;
785                                 mode->vsync_end = 490;
786                                 mode->vtotal = 499;
787                                 mode->clock = 33264;
788                         }
789                 } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
790                         mode->hdisplay = 864;
791                         mode->vdisplay = 480;
792                         mode->hsync_start = 872;
793                         mode->hsync_end = 876;
794                         mode->htotal = 884;
795                         mode->vsync_start = 482;
796                         mode->vsync_end = 494;
797                         mode->vtotal = 486;
798                         mode->clock = 25777;
799                         
800                 }
801         }
802
803         drm_mode_set_name(mode);
804         drm_mode_set_crtcinfo(mode, 0);
805         
806         mode->type |= DRM_MODE_TYPE_PREFERRED;
807
808         return mode;
809 }
810
811 /*
812  * MIPI output init
813  * @dev drm device
814  * @pipe pipe number. 0 or 2
815  * @config 
816  * 
817  * Do the initialization of a MIPI output, including create DRM mode objects
818  * initialization of DSI output on @pipe 
819  */
820 void mdfld_dsi_output_init(struct drm_device * dev,
821                            int pipe, 
822                            struct mdfld_dsi_config * config,
823                            struct panel_funcs* p_cmd_funcs,
824                            struct panel_funcs* p_vid_funcs)
825 {
826         struct mdfld_dsi_config * dsi_config;
827         struct mdfld_dsi_connector * dsi_connector;
828         struct psb_intel_output * psb_output;
829         struct drm_connector * connector;
830         struct mdfld_dsi_encoder * encoder;
831         struct drm_psb_private * dev_priv = dev->dev_private;
832         struct panel_info dsi_panel_info;
833         u32 width_mm, height_mm;
834
835         dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe);
836         
837         if(!dev || ((pipe != 0) && (pipe != 2))) {
838                 WARN_ON(1);
839                 return;
840         }
841         
842         /*create a new connetor*/
843         dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL);
844         if(!dsi_connector) {
845                 DRM_ERROR("No memory");
846                 return;
847         }
848         
849         dsi_connector->pipe =  pipe;
850         
851         /*set DSI config*/
852         if(config) { 
853                 dsi_config = config;
854         } else {
855                 dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL);
856                 if(!dsi_config) {
857                         dev_err(dev->dev,
858                                 "cannot allocate memory for DSI config\n");
859                         goto dsi_init_err0;
860                 }
861                 
862                 mdfld_dsi_get_default_config(dev, dsi_config, pipe);
863         }
864         
865         dsi_connector->private = dsi_config;
866         
867         dsi_config->changed = 1;
868         dsi_config->dev = dev;
869         
870         /*init fixed mode basing on DSI config type*/
871         if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
872                 dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
873                 if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
874                         goto dsi_init_err0;
875         } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
876                 dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
877                 if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
878                         goto dsi_init_err0;
879         }
880
881         width_mm = dsi_panel_info.width_mm;
882         height_mm = dsi_panel_info.height_mm;
883
884         dsi_config->mode = dsi_config->fixed_mode;
885         dsi_config->connector = dsi_connector;
886         
887         if(!dsi_config->fixed_mode) {
888                 dev_err(dev->dev, "No pannel fixed mode was found\n");
889                 goto dsi_init_err0;
890         }
891         
892         if(pipe && dev_priv->dsi_configs[0]) {
893                 dsi_config->dvr_ic_inited = 0;
894                 dev_priv->dsi_configs[1] = dsi_config;
895         } else if(pipe == 0) {
896                 dsi_config->dvr_ic_inited = 1;
897                 dev_priv->dsi_configs[0] = dsi_config;
898         } else {
899                 dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n");
900                 goto dsi_init_err0;
901         }
902
903         /*init drm connector object*/
904         psb_output = &dsi_connector->base;
905         
906         psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2;
907
908         connector = &psb_output->base;
909         drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, DRM_MODE_CONNECTOR_MIPI);
910         drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
911         
912         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
913         connector->display_info.width_mm = width_mm;
914         connector->display_info.height_mm = height_mm;
915         connector->interlace_allowed = false;
916         connector->doublescan_allowed = false;
917         
918         /*attach properties*/
919         drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
920         drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
921
922         /*init DBI & DPI encoders*/
923         if(p_cmd_funcs) {
924                 encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
925                 if(!encoder) {
926                         dev_err(dev->dev, "Create DBI encoder failed\n");
927                         goto dsi_init_err1;
928                 }
929                 encoder->private = dsi_config;
930                 dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
931                 if(pipe == 2)
932                         dev_priv->encoder2 = encoder;
933         
934                 if(pipe == 0)
935                         dev_priv->encoder0 = encoder;
936                         
937         }
938         
939         if(p_vid_funcs) {
940                 encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
941                 if(!encoder) {
942                         dev_err(dev->dev, "Create DPI encoder failed\n");
943                         goto dsi_init_err1;
944                 }
945                 encoder->private = dsi_config;
946                 dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
947
948         if(pipe == 2)
949             dev_priv->encoder2 = encoder;
950
951                 if(pipe == 0)
952             dev_priv->encoder0 = encoder;
953         }
954         
955         drm_sysfs_connector_add(connector);
956         
957         /*init DSI package sender on this output*/
958         if(mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) {
959                 dev_err(dev->dev, 
960                         "Package Sender initialization failed on pipe %d\n",
961                                                                 pipe);
962                 goto dsi_init_err2;
963         }
964
965         dev_dbg(dev->dev, "successfully\n");
966         return;
967         
968         /*TODO: add code to destroy outputs on error*/
969 dsi_init_err2:
970         drm_sysfs_connector_remove(connector);
971 dsi_init_err1:
972         drm_connector_cleanup(connector);
973         kfree(dsi_config->fixed_mode);
974         kfree(dsi_config);
975 dsi_init_err0:
976         kfree(dsi_connector);
977 }