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
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.
24 * jim liu <jim.liu@intel.com>
25 * Jackie Li<yaodong.li@intel.com>
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>
36 #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
38 /* get the CABC LABC from command line. */
39 static int CABC_control
= 1;
40 static int LABC_control
= 1;
43 module_param (CABC_control
, int, 0644);
44 module_param (LABC_control
, int, 0644);
46 static int __init
parse_CABC_control(char *arg
)
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 */
54 if (!strcasecmp(arg
, "0"))
56 else if (!strcasecmp (arg
, "1"))
61 early_param ("CABC", parse_CABC_control
);
63 static int __init
parse_LABC_control(char *arg
)
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 */
71 if (!strcasecmp(arg
, "0"))
73 else if (!strcasecmp (arg
, "1"))
78 early_param ("LABC", parse_LABC_control
);
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.
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,
94 static u32 mdfld_dbi_mcs_display_profile
[] = {
95 0x50281450, 0x0000c882, 0x00000000, 0x00000000,
99 static u32 mdfld_dbi_mcs_kbbc_profile
[] = {
100 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
103 static u32 mdfld_dbi_mcs_gamma_profile
[] = {
104 0x81111158, 0x88888888, 0x88888888,
108 * write hysteresis values.
110 static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config
* dsi_config
, int pipe
)
112 struct mdfld_dsi_pkg_sender
* sender
= mdfld_dsi_get_pkg_sender(dsi_config
);
118 mdfld_dsi_send_mcs_long_hs(sender
,
119 mdfld_dbi_mcs_hysteresis
,
121 MDFLD_DSI_SEND_PACKAGE
);
125 * write display profile values.
127 static void mdfld_dsi_write_display_profile (struct mdfld_dsi_config
* dsi_config
, int pipe
)
129 struct mdfld_dsi_pkg_sender
* sender
= mdfld_dsi_get_pkg_sender(dsi_config
);
135 mdfld_dsi_send_mcs_long_hs(sender
,
136 mdfld_dbi_mcs_display_profile
,
138 MDFLD_DSI_SEND_PACKAGE
);
142 * write KBBC profile values.
144 static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config
* dsi_config
, int pipe
)
146 struct mdfld_dsi_pkg_sender
* sender
= mdfld_dsi_get_pkg_sender(dsi_config
);
152 mdfld_dsi_send_mcs_long_hs(sender
,
153 mdfld_dbi_mcs_kbbc_profile
,
155 MDFLD_DSI_SEND_PACKAGE
);
159 * write gamma setting.
161 static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config
* dsi_config
, int pipe
)
163 struct mdfld_dsi_pkg_sender
* sender
= mdfld_dsi_get_pkg_sender(dsi_config
);
169 mdfld_dsi_send_mcs_long_hs(sender
,
170 mdfld_dbi_mcs_gamma_profile
,
172 MDFLD_DSI_SEND_PACKAGE
);
176 * Check and see if the generic control or data buffer is empty and ready.
178 void mdfld_dsi_gen_fifo_ready (struct drm_device
*dev
, u32 gen_fifo_stat_reg
, u32 fifo_stat
)
180 u32 GEN_BF_time_out_count
= 0;
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
++)
185 if ((REG_READ(gen_fifo_stat_reg
) & fifo_stat
) == fifo_stat
)
190 if (GEN_BF_time_out_count
== GEN_FB_TIME_OUT
)
192 "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n",
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.
201 void mdfld_dsi_brightness_init (struct mdfld_dsi_config
* dsi_config
, int pipe
)
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
;
212 /* Set default display backlight value to 85% (0xd8)*/
213 mdfld_dsi_send_mcs_short_hs(sender
,
214 write_display_brightness
,
217 MDFLD_DSI_SEND_PACKAGE
);
219 /* Set minimum brightness setting of CABC function to 20% (0x33)*/
220 mdfld_dsi_send_mcs_short_hs(sender
,
221 write_cabc_min_bright
,
224 MDFLD_DSI_SEND_PACKAGE
);
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
);
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
;
236 if (LABC_control
== 1)
237 gen_ctrl_val
|= AMBIENT_LIGHT_SENSE_ON
;
239 dev_priv
->mipi_ctrl_display
= gen_ctrl_val
;
241 mdfld_dsi_send_mcs_short_hs(sender
,
245 MDFLD_DSI_SEND_PACKAGE
);
247 if (CABC_control
== 0)
249 mdfld_dsi_send_mcs_short_hs(sender
,
253 MDFLD_DSI_SEND_PACKAGE
);
257 * Manage the mipi display brightness.
258 * TODO: refine this interface later
260 void mdfld_dsi_brightness_control(struct drm_device
*dev
, int pipe
, int level
)
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
;
268 if (!dev
|| (pipe
!= 0 && pipe
!= 2)) {
269 dev_err(dev
->dev
, "Invalid parameter\n");
273 p_type
= mdfld_get_panel_type(dev
, 0);
275 dev_priv
= dev
->dev_private
;
278 dsi_config
= dev_priv
->dsi_configs
[1];
280 dsi_config
= dev_priv
->dsi_configs
[0];
282 sender
= mdfld_dsi_get_pkg_sender(dsi_config
);
289 gen_ctrl_val
= ((level
* 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL
) & 0xff;
291 dev_dbg(dev
->dev
, "pipe = %d, gen_ctrl_val = %d. \n", pipe
, gen_ctrl_val
);
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
,
299 MDFLD_DSI_SEND_PACKAGE
);
301 /* Set display backlight value */
302 mdfld_dsi_send_mcs_short_hs(sender
,
303 write_display_brightness
,
306 MDFLD_DSI_SEND_PACKAGE
);
309 /* Enable backlight control */
313 gen_ctrl_val
= dev_priv
->mipi_ctrl_display
;
315 mdfld_dsi_send_mcs_short_hs(sender
,
319 MDFLD_DSI_SEND_PACKAGE
);
324 * shut down DSI controller
326 void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config
* dsi_config
, int pipe
)
328 struct drm_device
* dev
;
329 u32 reg_offset
= pipe
? MIPIC_REG_OFFSET
: 0;
337 dev
= dsi_config
->dev
;
339 if (!gma_power_begin(dev
, true)) {
340 dev_err(dev
->dev
, "hw begin failed\n");
344 if(!(REG_READ(MIPIA_DEVICE_READY_REG
+ reg_offset
) & DSI_DEVICE_READY
))
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
));
353 /*send shut down package in HS*/
354 REG_WRITE((MIPIA_DPI_CONTROL_REG
+ reg_offset
), DSI_DPI_CTRL_HS_SHUTDOWN
);
358 * make sure shut down is sent.
359 * FIXME: add max retry counter
361 while(!(REG_READ(MIPIA_INTR_STAT_REG
+ reg_offset
) & DSI_INTR_STATE_SPL_PKG_SENT
)) {
365 dev_err(dev
->dev
, "timeout\n");
370 /*sleep 1 ms to ensure shutdown finished*/
374 REG_WRITE((MIPIA_DEVICE_READY_REG
+ reg_offset
),
375 (REG_READ(MIPIA_DEVICE_READY_REG
+ reg_offset
) & ~DSI_DEVICE_READY
));
381 void mdfld_dsi_controller_startup(struct mdfld_dsi_config
* dsi_config
, int pipe
)
383 struct drm_device
* dev
;
384 u32 reg_offset
= pipe
? MIPIC_REG_OFFSET
: 0;
393 dev
= dsi_config
->dev
;
394 dev_dbg(dev
->dev
, "starting up DSI controller on pipe %d...\n", pipe
);
396 if (!gma_power_begin(dev
, true)) {
397 dev_err(dev
->dev
, "hw begin failed\n");
401 if((REG_READ(MIPIA_DEVICE_READY_REG
+ reg_offset
) & DSI_DEVICE_READY
))
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
);
410 REG_WRITE((MIPIA_DPI_CONTROL_REG
+ reg_offset
), DSI_DPI_CTRL_HS_TURN_ON
);
413 * make sure shut down is sent.
414 * FIXME: add max retry counter
416 while(!(REG_READ(MIPIA_INTR_STAT_REG
+ reg_offset
) & DSI_INTR_STATE_SPL_PKG_SENT
)) {
419 dev_err(dev
->dev
, "timeout\n");
428 REG_WRITE((MIPIA_DEVICE_READY_REG
+ reg_offset
),
429 (REG_READ(MIPIA_DEVICE_READY_REG
+ reg_offset
) | DSI_DEVICE_READY
));
436 * NOTE: this function was used by OSPM.
437 * TODO: will be removed later, should work out display interfaces for OSPM
439 void mdfld_dsi_controller_init(struct mdfld_dsi_config
* dsi_config
, int pipe
)
441 if(!dsi_config
|| ((pipe
!= 0) && (pipe
!= 2))) {
447 mdfld_dsi_dpi_controller_init(dsi_config
, pipe
);
449 mdfld_dsi_controller_dbi_init(dsi_config
, pipe
);
452 static void mdfld_dsi_connector_save(struct drm_connector
* connector
)
456 static void mdfld_dsi_connector_restore(struct drm_connector
* connector
)
460 static enum drm_connector_status
mdfld_dsi_connector_detect(struct drm_connector
* connector
, bool force
)
462 return connector_status_connected
;
465 static int mdfld_dsi_connector_set_property(struct drm_connector
* connector
,
466 struct drm_property
* property
,
469 struct drm_encoder
* encoder
= connector
->encoder
;
470 struct backlight_device
* psb_bd
;
471 struct drm_psb_private
* dev_priv
= encoder
->dev
->dev_private
;
473 if (!strcmp(property
->name
, "scaling mode") && encoder
) {
474 struct psb_intel_crtc
* psb_crtc
= to_psb_intel_crtc(encoder
->crtc
);
475 bool bTransitionFromToCentered
;
482 case DRM_MODE_SCALE_FULLSCREEN
:
484 case DRM_MODE_SCALE_NO_SCALE
:
486 case DRM_MODE_SCALE_ASPECT
:
492 if (drm_connector_property_get_value(connector
, property
, &curValue
))
495 if (curValue
== value
)
498 if (drm_connector_property_set_value(connector
, property
, value
))
501 bTransitionFromToCentered
= (curValue
== DRM_MODE_SCALE_NO_SCALE
) ||
502 (value
== DRM_MODE_SCALE_NO_SCALE
);
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
))
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
);
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
))
522 dev_dbg(encoder
->dev
->dev
,
523 "set brightness to %d", (int)value
);
524 psb_bd
= dev_priv
->backlight_device
;
526 psb_bd
->props
.brightness
= value
;
527 backlight_update_status(psb_bd
);
538 static void mdfld_dsi_connector_destroy(struct drm_connector
*connector
)
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
;
547 drm_sysfs_connector_remove(connector
);
548 drm_connector_cleanup(connector
);
550 sender
= dsi_connector
->pkg_sender
;
552 mdfld_dsi_pkg_sender_destroy(sender
);
554 kfree(dsi_connector
);
557 static int mdfld_dsi_connector_get_modes(struct drm_connector
* connector
)
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
;
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;
572 dev_dbg(dev
->dev
, "fixed_mode %dx%d\n",
573 fixed_mode
->hdisplay
, fixed_mode
->vdisplay
);
575 dup_mode
= drm_mode_duplicate(dev
, fixed_mode
);
576 drm_mode_probed_add(connector
, dup_mode
);
579 dev_err(dev
->dev
, "Didn't get any modes!\n");
583 static int mdfld_dsi_connector_mode_valid(struct drm_connector
* connector
, struct drm_display_mode
* mode
)
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
;
590 dev_dbg(connector
->dev
->dev
, "mode %p, fixed mode %p\n",
593 if(mode
->flags
& DRM_MODE_FLAG_DBLSCAN
)
594 return MODE_NO_DBLESCAN
;
596 if(mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
597 return MODE_NO_INTERLACE
;
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.
604 if(mode
->hdisplay
!= fixed_mode
->hdisplay
)
607 if(mode
->vdisplay
!= fixed_mode
->vdisplay
)
610 dev_dbg(connector
->dev
->dev
, "mode ok\n");
615 static void mdfld_dsi_connector_dpms(struct drm_connector
*connector
, int mode
)
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
;
622 /* First, execute DPMS */
623 drm_helper_connector_dpms(connector
, mode
);
625 #ifdef CONFIG_PM_RUNTIME
626 if(mdfld_panel_dpi(dev
)) {
628 panel_on
= dev_priv
->dpi_panel_on
;
629 panel_on2
= dev_priv
->dpi_panel_on2
;
632 panel_on
= dev_priv
->dbi_panel_on
;
633 panel_on2
= dev_priv
->dbi_panel_on2
;
636 /* Then check all display panels + monitors status */
637 if(!panel_on
&& !panel_on2
&& !(REG_READ(HDMIB_CONTROL
)
640 if(dev_priv
->rpm_enabled
)
641 pm_request_idle(&dev
->pdev
->dev
);
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.
650 if(!dev_priv
->rpm_enabled
&& !mdfld_panel_dpi(dev
))
651 ospm_runtime_pm_allow(dev
);
656 static struct drm_encoder
* mdfld_dsi_connector_best_encoder(
657 struct drm_connector
* connector
)
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
;
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
];
669 dev_dbg(connector
->dev
->dev
, "get encoder %p\n", encoder
);
672 dev_err(connector
->dev
->dev
,
673 "Invalid encoder for type %d\n", dsi_config
->type
);
676 dsi_config
->encoder
= encoder
;
677 return &encoder
->base
;
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
,
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
,
698 static int mdfld_dsi_get_default_config(struct drm_device
* dev
,
699 struct mdfld_dsi_config
* config
, int pipe
)
701 if(!dev
|| !config
) {
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
;
714 config
->video_mode
= MDFLD_DSI_VIDEO_BURST_MODE
;
721 * Returns the panel fixed mode from configuration.
723 struct drm_display_mode
*
724 mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config
* dsi_config
, int pipe
)
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;
732 mode
= kzalloc(sizeof(*mode
), GFP_KERNEL
);
734 dev_err(dev
->dev
, "Out of memory for mode\n");
738 dev_dbg(dev
->dev
, "gct find MIPI panel.\n");
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) | \
750 mode
->vsync_start
= \
751 mode
->vdisplay
+ ((ti
->vsync_offset_hi
<< 8) | \
752 ti
->vsync_offset_lo
);
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;
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
);
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;
777 mode
->vsync_start
= 861;
778 mode
->vsync_end
= 865;
782 mode
->hdisplay
= 864;
783 mode
->vdisplay
= 480;
784 mode
->hsync_start
= 873;
785 mode
->hsync_end
= 876;
787 mode
->vsync_start
= 487;
788 mode
->vsync_end
= 490;
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;
798 mode
->vsync_start
= 482;
799 mode
->vsync_end
= 494;
806 drm_mode_set_name(mode
);
807 drm_mode_set_crtcinfo(mode
, 0);
809 mode
->type
|= DRM_MODE_TYPE_PREFERRED
;
817 * @pipe pipe number. 0 or 2
820 * Do the initialization of a MIPI output, including create DRM mode objects
821 * initialization of DSI output on @pipe
823 void mdfld_dsi_output_init(struct drm_device
* dev
,
825 struct mdfld_dsi_config
* config
,
826 struct panel_funcs
* p_cmd_funcs
,
827 struct panel_funcs
* p_vid_funcs
)
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
;
838 dev_dbg(dev
->dev
, "init DSI output on pipe %d\n", pipe
);
840 if(!dev
|| ((pipe
!= 0) && (pipe
!= 2))) {
845 /*create a new connetor*/
846 dsi_connector
= kzalloc(sizeof(struct mdfld_dsi_connector
), GFP_KERNEL
);
848 DRM_ERROR("No memory");
852 dsi_connector
->pipe
= pipe
;
858 dsi_config
= kzalloc(sizeof(struct mdfld_dsi_config
), GFP_KERNEL
);
861 "cannot allocate memory for DSI config\n");
865 mdfld_dsi_get_default_config(dev
, dsi_config
, pipe
);
868 dsi_connector
->private = dsi_config
;
870 dsi_config
->changed
= 1;
871 dsi_config
->dev
= dev
;
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
))
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
))
884 width_mm
= dsi_panel_info
.width_mm
;
885 height_mm
= dsi_panel_info
.height_mm
;
887 dsi_config
->mode
= dsi_config
->fixed_mode
;
888 dsi_config
->connector
= dsi_connector
;
890 if(!dsi_config
->fixed_mode
) {
891 dev_err(dev
->dev
, "No pannel fixed mode was found\n");
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
;
902 dev_err(dev
->dev
, "Trying to init MIPI1 before MIPI0\n");
906 /*init drm connector object*/
907 psb_output
= &dsi_connector
->base
;
909 psb_output
->type
= (pipe
== 0) ? INTEL_OUTPUT_MIPI
: INTEL_OUTPUT_MIPI2
;
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
);
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;
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
);
925 /*init DBI & DPI encoders*/
927 encoder
= mdfld_dsi_dbi_init(dev
, dsi_connector
, p_cmd_funcs
);
929 dev_err(dev
->dev
, "Create DBI encoder failed\n");
932 encoder
->private = dsi_config
;
933 dsi_config
->encoders
[MDFLD_DSI_ENCODER_DBI
] = encoder
;
935 dev_priv
->encoder2
= encoder
;
938 dev_priv
->encoder0
= encoder
;
943 encoder
= mdfld_dsi_dpi_init(dev
, dsi_connector
, p_vid_funcs
);
945 dev_err(dev
->dev
, "Create DPI encoder failed\n");
948 encoder
->private = dsi_config
;
949 dsi_config
->encoders
[MDFLD_DSI_ENCODER_DPI
] = encoder
;
952 dev_priv
->encoder2
= encoder
;
955 dev_priv
->encoder0
= encoder
;
958 drm_sysfs_connector_add(connector
);
960 /*init DSI package sender on this output*/
961 if(mdfld_dsi_pkg_sender_init(dsi_connector
, pipe
)) {
963 "Package Sender initialization failed on pipe %d\n",
968 dev_dbg(dev
->dev
, "successfully\n");
971 /*TODO: add code to destroy outputs on error*/
973 drm_sysfs_connector_remove(connector
);
975 drm_connector_cleanup(connector
);
976 kfree(dsi_config
->fixed_mode
);
979 kfree(dsi_connector
);