gma500: power can be touched in IRQ state
[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         struct drm_psb_private * dev_priv = encoder->dev->dev_private;
472
473         if (!strcmp(property->name, "scaling mode") && encoder) {
474                 struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
475                 bool bTransitionFromToCentered;
476                 uint64_t curValue;
477
478                 if (!psb_crtc)
479                         goto set_prop_error;
480
481                 switch (value) {
482                 case DRM_MODE_SCALE_FULLSCREEN:
483                         break;
484                 case DRM_MODE_SCALE_NO_SCALE:
485                         break;
486                 case DRM_MODE_SCALE_ASPECT:
487                         break;
488                 default:
489                         goto set_prop_error;
490                 }
491
492                 if (drm_connector_property_get_value(connector, property, &curValue))
493                         goto set_prop_error;
494
495                 if (curValue == value)
496                         goto set_prop_done;
497
498                 if (drm_connector_property_set_value(connector, property, value))
499                         goto set_prop_error;
500
501                 bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
502                         (value == DRM_MODE_SCALE_NO_SCALE);
503
504                 if (psb_crtc->saved_mode.hdisplay != 0 &&
505                     psb_crtc->saved_mode.vdisplay != 0) {
506                         if (bTransitionFromToCentered) {
507                                 if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode,
508                                             encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
509                                         goto set_prop_error;
510                         } else {
511                                 struct drm_encoder_helper_funcs *pEncHFuncs  = encoder->helper_private;
512                                 pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode,
513                                                      &psb_crtc->saved_adjusted_mode);
514                         }
515                 }
516 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
517         } else if (!strcmp(property->name, "backlight") && encoder) {
518                 dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
519                 if (drm_connector_property_set_value(connector, property, value))
520                         goto set_prop_error;
521                 else {
522                         dev_dbg(encoder->dev->dev,
523                                         "set brightness to %d", (int)value);
524                         psb_bd = dev_priv->backlight_device;
525                         if (psb_bd) {
526                                 psb_bd->props.brightness = value;
527                                 backlight_update_status(psb_bd);
528                         }
529                 }
530         } 
531 #endif
532 set_prop_done:
533     return 0;
534 set_prop_error:
535     return -1;
536 }
537
538 static void mdfld_dsi_connector_destroy(struct drm_connector *connector)
539 {
540         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
541         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
542         struct mdfld_dsi_pkg_sender * sender;
543         
544         if(!dsi_connector)
545                 return;
546         
547         drm_sysfs_connector_remove(connector);
548         drm_connector_cleanup(connector);
549         
550         sender = dsi_connector->pkg_sender;
551
552         mdfld_dsi_pkg_sender_destroy(sender);
553
554         kfree(dsi_connector);
555 }
556
557 static int mdfld_dsi_connector_get_modes(struct drm_connector * connector)
558 {
559         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
560         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
561         struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
562         struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
563         struct drm_display_mode * dup_mode = NULL;
564         struct drm_device * dev = connector->dev;
565         
566         connector->display_info.min_vfreq = 0;
567         connector->display_info.max_vfreq = 200;
568         connector->display_info.min_hfreq = 0;
569         connector->display_info.max_hfreq = 200;
570
571         if(fixed_mode) {
572                 dev_dbg(dev->dev, "fixed_mode %dx%d\n",
573                         fixed_mode->hdisplay, fixed_mode->vdisplay);
574                 
575                 dup_mode = drm_mode_duplicate(dev, fixed_mode);
576                 drm_mode_probed_add(connector, dup_mode);
577                 return 1;
578         }
579         dev_err(dev->dev, "Didn't get any modes!\n");
580         return 0;
581 }
582
583 static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode)
584 {
585         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
586         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
587         struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
588         struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
589
590         dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n",
591                                                         mode, fixed_mode);
592
593         if(mode->flags & DRM_MODE_FLAG_DBLSCAN) 
594                 return MODE_NO_DBLESCAN;
595
596         if(mode->flags & DRM_MODE_FLAG_INTERLACE)
597                 return MODE_NO_INTERLACE;
598
599         /**
600          * FIXME: current DC has no fitting unit, reject any mode setting request
601          * will figure out a way to do up-scaling(pannel fitting) later.  
602          **/
603         if(fixed_mode) {
604                 if(mode->hdisplay != fixed_mode->hdisplay)
605                         return MODE_PANEL;
606
607                 if(mode->vdisplay != fixed_mode->vdisplay)
608                         return MODE_PANEL;
609         }
610         dev_dbg(connector->dev->dev, "mode ok\n");
611
612         return MODE_OK;
613 }
614
615 static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
616 {
617 #ifdef CONFIG_PM_RUNTIME
618         struct drm_device * dev = connector->dev;
619         struct drm_psb_private * dev_priv = dev->dev_private;
620         bool panel_on, panel_on2;
621 #endif
622         /* First, execute DPMS */
623         drm_helper_connector_dpms(connector, mode);
624
625 #ifdef CONFIG_PM_RUNTIME
626         if(mdfld_panel_dpi(dev)) {
627                 /* DPI panel */
628                 panel_on = dev_priv->dpi_panel_on;
629                 panel_on2 = dev_priv->dpi_panel_on2;
630         } else {
631                 /* DBI panel */
632                 panel_on = dev_priv->dbi_panel_on;
633                 panel_on2 = dev_priv->dbi_panel_on2;
634         }
635
636         /* Then check all display panels + monitors status */
637         if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL)
638                                                 & HDMIB_PORT_EN)) {
639                 /*request rpm idle*/
640                 if(dev_priv->rpm_enabled)
641                         pm_request_idle(&dev->pdev->dev);
642         }
643         /*
644          * if rpm wasn't enabled yet, try to allow it
645          * FIXME: won't enable rpm for DPI since DPI
646          * CRTC setting is a little messy now.
647          * Enable it later!
648          */
649 #if 0
650         if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev))
651                 ospm_runtime_pm_allow(dev);
652 #endif
653 #endif
654 }
655
656 static struct drm_encoder * mdfld_dsi_connector_best_encoder(
657                                         struct drm_connector * connector) 
658 {
659         struct psb_intel_output * psb_output = to_psb_intel_output(connector);
660         struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
661         struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
662         struct mdfld_dsi_encoder * encoder = NULL;
663         
664         if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) 
665                 encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI];
666         else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) 
667                 encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI];
668         
669         dev_dbg(connector->dev->dev, "get encoder %p\n", encoder);
670         
671         if(!encoder) {
672                 dev_err(connector->dev->dev,
673                         "Invalid encoder for type %d\n", dsi_config->type);
674                 return NULL;
675         }
676         dsi_config->encoder = encoder;  
677         return &encoder->base;  
678 }
679
680 /* DSI connector funcs */
681 static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
682         .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
683         .save = mdfld_dsi_connector_save,
684         .restore = mdfld_dsi_connector_restore,
685         .detect = mdfld_dsi_connector_detect,
686         .fill_modes = drm_helper_probe_single_connector_modes,
687         .set_property = mdfld_dsi_connector_set_property,
688         .destroy = mdfld_dsi_connector_destroy,
689 };
690
691 /* DSI connector helper funcs */
692 static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = {
693         .get_modes = mdfld_dsi_connector_get_modes,
694         .mode_valid = mdfld_dsi_connector_mode_valid,
695         .best_encoder = mdfld_dsi_connector_best_encoder,
696 };
697
698 static int mdfld_dsi_get_default_config(struct drm_device * dev, 
699                                                                                 struct mdfld_dsi_config * config, int pipe)
700 {
701         if(!dev || !config) {
702                 WARN_ON(1);
703                 return -EINVAL;
704         }
705         
706         config->bpp = 24;
707         config->type = mdfld_panel_dpi(dev);
708         config->lane_count = 2;
709         config->channel_num = 0;
710         /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/
711         if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
712                 config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE;
713         } else {
714                 config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE;
715         }
716         
717         return 0;
718 }
719
720 /*
721  * Returns the panel fixed mode from configuration. 
722  */
723 struct drm_display_mode *
724 mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
725 {
726         struct drm_device *dev = dsi_config->dev;
727         struct drm_display_mode *mode;
728         struct drm_psb_private *dev_priv = dev->dev_private;
729         struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
730         bool use_gct = false;
731
732         mode = kzalloc(sizeof(*mode), GFP_KERNEL);
733         if (!mode) {
734                 dev_err(dev->dev, "Out of memory for mode\n");
735                 return NULL;
736         }
737         if (use_gct) {
738                 dev_dbg(dev->dev, "gct find MIPI panel.\n");
739
740                 mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
741                 mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
742                 mode->hsync_start = mode->hdisplay + \
743                                 ((ti->hsync_offset_hi << 8) | \
744                                 ti->hsync_offset_lo);
745                 mode->hsync_end = mode->hsync_start + \
746                                 ((ti->hsync_pulse_width_hi << 8) | \
747                                 ti->hsync_pulse_width_lo);
748                 mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
749                                                                 ti->hblank_lo);
750                 mode->vsync_start = \
751                         mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
752                                                 ti->vsync_offset_lo);
753                 mode->vsync_end = \
754                         mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
755                                                 ti->vsync_pulse_width_lo);
756                 mode->vtotal = mode->vdisplay + \
757                                 ((ti->vblank_hi << 8) | ti->vblank_lo);
758                 mode->clock = ti->pixel_clock * 10;
759
760                 dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
761                 dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
762                 dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
763                 dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
764                 dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
765                 dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
766                 dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
767                 dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
768                 dev_dbg(dev->dev, "clock is %d\n", mode->clock);
769         } else {
770                 if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { 
771                         if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
772                                 mode->hdisplay = 480;
773                                 mode->vdisplay = 854;
774                                 mode->hsync_start = 487;
775                                 mode->hsync_end = 490;
776                                 mode->htotal = 499;
777                                 mode->vsync_start = 861;
778                                 mode->vsync_end = 865;
779                                 mode->vtotal = 873;
780                                 mode->clock = 33264;
781                         } else {
782                                 mode->hdisplay = 864;
783                                 mode->vdisplay = 480;
784                                 mode->hsync_start = 873;
785                                 mode->hsync_end = 876;
786                                 mode->htotal = 887;
787                                 mode->vsync_start = 487;
788                                 mode->vsync_end = 490;
789                                 mode->vtotal = 499;
790                                 mode->clock = 33264;
791                         }
792                 } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
793                         mode->hdisplay = 864;
794                         mode->vdisplay = 480;
795                         mode->hsync_start = 872;
796                         mode->hsync_end = 876;
797                         mode->htotal = 884;
798                         mode->vsync_start = 482;
799                         mode->vsync_end = 494;
800                         mode->vtotal = 486;
801                         mode->clock = 25777;
802                         
803                 }
804         }
805
806         drm_mode_set_name(mode);
807         drm_mode_set_crtcinfo(mode, 0);
808         
809         mode->type |= DRM_MODE_TYPE_PREFERRED;
810
811         return mode;
812 }
813
814 /*
815  * MIPI output init
816  * @dev drm device
817  * @pipe pipe number. 0 or 2
818  * @config 
819  * 
820  * Do the initialization of a MIPI output, including create DRM mode objects
821  * initialization of DSI output on @pipe 
822  */
823 void mdfld_dsi_output_init(struct drm_device * dev,
824                            int pipe, 
825                            struct mdfld_dsi_config * config,
826                            struct panel_funcs* p_cmd_funcs,
827                            struct panel_funcs* p_vid_funcs)
828 {
829         struct mdfld_dsi_config * dsi_config;
830         struct mdfld_dsi_connector * dsi_connector;
831         struct psb_intel_output * psb_output;
832         struct drm_connector * connector;
833         struct mdfld_dsi_encoder * encoder;
834         struct drm_psb_private * dev_priv = dev->dev_private;
835         struct panel_info dsi_panel_info;
836         u32 width_mm, height_mm;
837
838         dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe);
839         
840         if(!dev || ((pipe != 0) && (pipe != 2))) {
841                 WARN_ON(1);
842                 return;
843         }
844         
845         /*create a new connetor*/
846         dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL);
847         if(!dsi_connector) {
848                 DRM_ERROR("No memory");
849                 return;
850         }
851         
852         dsi_connector->pipe =  pipe;
853         
854         /*set DSI config*/
855         if(config) { 
856                 dsi_config = config;
857         } else {
858                 dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL);
859                 if(!dsi_config) {
860                         dev_err(dev->dev,
861                                 "cannot allocate memory for DSI config\n");
862                         goto dsi_init_err0;
863                 }
864                 
865                 mdfld_dsi_get_default_config(dev, dsi_config, pipe);
866         }
867         
868         dsi_connector->private = dsi_config;
869         
870         dsi_config->changed = 1;
871         dsi_config->dev = dev;
872         
873         /*init fixed mode basing on DSI config type*/
874         if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
875                 dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
876                 if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
877                         goto dsi_init_err0;
878         } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
879                 dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
880                 if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
881                         goto dsi_init_err0;
882         }
883
884         width_mm = dsi_panel_info.width_mm;
885         height_mm = dsi_panel_info.height_mm;
886
887         dsi_config->mode = dsi_config->fixed_mode;
888         dsi_config->connector = dsi_connector;
889         
890         if(!dsi_config->fixed_mode) {
891                 dev_err(dev->dev, "No pannel fixed mode was found\n");
892                 goto dsi_init_err0;
893         }
894         
895         if(pipe && dev_priv->dsi_configs[0]) {
896                 dsi_config->dvr_ic_inited = 0;
897                 dev_priv->dsi_configs[1] = dsi_config;
898         } else if(pipe == 0) {
899                 dsi_config->dvr_ic_inited = 1;
900                 dev_priv->dsi_configs[0] = dsi_config;
901         } else {
902                 dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n");
903                 goto dsi_init_err0;
904         }
905
906         /*init drm connector object*/
907         psb_output = &dsi_connector->base;
908         
909         psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2;
910
911         connector = &psb_output->base;
912         drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, DRM_MODE_CONNECTOR_MIPI);
913         drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
914         
915         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
916         connector->display_info.width_mm = width_mm;
917         connector->display_info.height_mm = height_mm;
918         connector->interlace_allowed = false;
919         connector->doublescan_allowed = false;
920         
921         /*attach properties*/
922         drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
923         drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
924
925         /*init DBI & DPI encoders*/
926         if(p_cmd_funcs) {
927                 encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
928                 if(!encoder) {
929                         dev_err(dev->dev, "Create DBI encoder failed\n");
930                         goto dsi_init_err1;
931                 }
932                 encoder->private = dsi_config;
933                 dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
934                 if(pipe == 2)
935                         dev_priv->encoder2 = encoder;
936         
937                 if(pipe == 0)
938                         dev_priv->encoder0 = encoder;
939                         
940         }
941         
942         if(p_vid_funcs) {
943                 encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
944                 if(!encoder) {
945                         dev_err(dev->dev, "Create DPI encoder failed\n");
946                         goto dsi_init_err1;
947                 }
948                 encoder->private = dsi_config;
949                 dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
950
951         if(pipe == 2)
952             dev_priv->encoder2 = encoder;
953
954                 if(pipe == 0)
955             dev_priv->encoder0 = encoder;
956         }
957         
958         drm_sysfs_connector_add(connector);
959         
960         /*init DSI package sender on this output*/
961         if(mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) {
962                 dev_err(dev->dev, 
963                         "Package Sender initialization failed on pipe %d\n",
964                                                                 pipe);
965                 goto dsi_init_err2;
966         }
967
968         dev_dbg(dev->dev, "successfully\n");
969         return;
970         
971         /*TODO: add code to destroy outputs on error*/
972 dsi_init_err2:
973         drm_sysfs_connector_remove(connector);
974 dsi_init_err1:
975         drm_connector_cleanup(connector);
976         kfree(dsi_config->fixed_mode);
977         kfree(dsi_config);
978 dsi_init_err0:
979         kfree(dsi_connector);
980 }