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_dbi.h"
29 #include "mdfld_dsi_dbi_dpu.h"
30 #include "mdfld_dsi_pkg_sender.h"
33 #include <linux/pm_runtime.h>
37 extern struct drm_device
*gpDrmDevice
;
38 extern int gfxrtdelay
;
40 struct mdfld_dsi_dbi_output
*gdbi_output
;
41 extern bool gbgfxsuspended
;
42 extern int enable_gfx_rtpm
;
43 extern int gfxrtdelay
;
45 #define MDFLD_DSR_MAX_IDLE_COUNT 2
50 int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output
*dbi_output
,
51 u16 x1
, u16 y1
, u16 x2
, u16 y2
)
53 struct mdfld_dsi_pkg_sender
*sender
=
54 mdfld_dsi_encoder_get_pkg_sender(&dbi_output
->base
);
65 cmd
= DCS_SET_COLUMN_ADDRESS
;
71 err
= mdfld_dsi_send_dcs(sender
,
75 CMD_DATA_SRC_SYSTEM_MEM
,
76 MDFLD_DSI_QUEUE_PACKAGE
);
78 dev_err(sender
->dev
->dev
, "DCS 0x%x sent failed\n", cmd
);
83 cmd
= DCS_SET_PAGE_ADDRESS
;
89 err
= mdfld_dsi_send_dcs(sender
,
93 CMD_DATA_SRC_SYSTEM_MEM
,
94 MDFLD_DSI_QUEUE_PACKAGE
);
96 dev_err(sender
->dev
->dev
, "DCS 0x%x sent failed\n", cmd
);
101 err
= mdfld_dsi_send_dcs(sender
,
106 MDFLD_DSI_QUEUE_PACKAGE
);
108 dev_err(sender
->dev
->dev
, "DCS 0x%x sent failed\n", cmd
);
111 mdfld_dsi_cmds_kick_out(sender
);
117 * set panel's power state
119 int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output
*dbi_output
,
122 struct drm_device
*dev
= dbi_output
->dev
;
123 struct mdfld_dsi_pkg_sender
*sender
=
124 mdfld_dsi_encoder_get_pkg_sender(&dbi_output
->base
);
133 if (mode
== DRM_MODE_DPMS_ON
) {
134 /* Exit sleep mode */
135 err
= mdfld_dsi_send_dcs(sender
,
139 CMD_DATA_SRC_SYSTEM_MEM
,
140 MDFLD_DSI_QUEUE_PACKAGE
);
142 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
143 DCS_EXIT_SLEEP_MODE
);
148 err
= mdfld_dsi_send_dcs(sender
,
152 CMD_DATA_SRC_SYSTEM_MEM
,
153 MDFLD_DSI_QUEUE_PACKAGE
);
155 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
160 /* set tear effect on */
161 err
= mdfld_dsi_send_dcs(sender
,
165 CMD_DATA_SRC_SYSTEM_MEM
,
166 MDFLD_DSI_QUEUE_PACKAGE
);
168 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
174 * FIXME: remove this later
176 err
= mdfld_dsi_send_dcs(sender
,
181 MDFLD_DSI_QUEUE_PACKAGE
);
183 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
184 DCS_WRITE_MEM_START
);
188 /* Set tear effect off */
189 err
= mdfld_dsi_send_dcs(sender
,
193 CMD_DATA_SRC_SYSTEM_MEM
,
194 MDFLD_DSI_QUEUE_PACKAGE
);
196 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
201 /* Turn display off */
202 err
= mdfld_dsi_send_dcs(sender
,
206 CMD_DATA_SRC_SYSTEM_MEM
,
207 MDFLD_DSI_QUEUE_PACKAGE
);
209 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
210 DCS_SET_DISPLAY_OFF
);
214 /* Now enter sleep mode */
215 err
= mdfld_dsi_send_dcs(sender
,
216 DCS_ENTER_SLEEP_MODE
,
219 CMD_DATA_SRC_SYSTEM_MEM
,
220 MDFLD_DSI_QUEUE_PACKAGE
);
222 dev_err(dev
->dev
, "DCS 0x%x sent failed\n",
223 DCS_ENTER_SLEEP_MODE
);
227 mdfld_dsi_cmds_kick_out(sender
);
233 * send a generic DCS command with a parameter list
235 int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output
*dbi_output
,
236 u8 dcs
, u8
*param
, u32 num
, u8 data_src
)
238 struct mdfld_dsi_pkg_sender
*sender
=
239 mdfld_dsi_encoder_get_pkg_sender(&dbi_output
->base
);
247 ret
= mdfld_dsi_send_dcs(sender
,
252 MDFLD_DSI_SEND_PACKAGE
);
260 void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output
*dbi_output
, int pipe
)
263 struct drm_device
*dev
= dbi_output
->dev
;
264 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
265 struct drm_crtc
*crtc
= dbi_output
->base
.base
.crtc
;
266 struct psb_intel_crtc
*psb_crtc
= (crtc
) ?
267 to_psb_intel_crtc(crtc
) : NULL
;
268 u32 dpll_reg
= MRST_DPLL_A
;
269 u32 pipeconf_reg
= PIPEACONF
;
270 u32 dspcntr_reg
= DSPACNTR
;
275 /* FIXME check if can go */
276 dev_priv
->is_in_idle
= true;
278 gdbi_output
= dbi_output
;
279 if ((dbi_output
->mode_flags
& MODE_SETTING_ON_GOING
) ||
280 (psb_crtc
&& psb_crtc
->mode_flags
& MODE_SETTING_ON_GOING
))
284 dpll_reg
= MRST_DPLL_A
;
285 pipeconf_reg
= PIPECCONF
;
286 dspcntr_reg
= DSPCCNTR
;
289 if (!gma_power_begin(dev
, true)) {
290 dev_err(dev
->dev
, "hw begin failed\n");
293 /* Disable te interrupts */
294 mdfld_disable_te(dev
, pipe
);
297 reg_val
= REG_READ(dspcntr_reg
);
298 if (!(reg_val
& DISPLAY_PLANE_ENABLE
)) {
299 REG_WRITE(dspcntr_reg
, reg_val
& ~DISPLAY_PLANE_ENABLE
);
300 REG_READ(dspcntr_reg
);
304 reg_val
= REG_READ(pipeconf_reg
);
305 if (!(reg_val
& DISPLAY_PLANE_ENABLE
)) {
306 reg_val
&= ~DISPLAY_PLANE_ENABLE
;
307 reg_val
|= (PIPECONF_PLANE_OFF
| PIPECONF_CURSOR_OFF
);
308 REG_WRITE(pipeconf_reg
, reg_val
);
309 REG_READ(pipeconf_reg
);
310 mdfldWaitForPipeDisable(dev
, pipe
);
314 reg_val
= REG_READ(dpll_reg
);
315 if (!(reg_val
& DPLL_VCO_ENABLE
)) {
316 reg_val
&= ~DPLL_VCO_ENABLE
;
317 REG_WRITE(dpll_reg
, reg_val
);
323 dbi_output
->mode_flags
|= MODE_SETTING_IN_DSR
;
326 /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
330 #ifndef CONFIG_MDFLD_DSI_DPU
331 static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output
*dbi_output
,
334 struct drm_device
*dev
= dbi_output
->dev
;
335 struct drm_crtc
*crtc
= dbi_output
->base
.base
.crtc
;
336 struct psb_intel_crtc
*psb_crtc
= (crtc
) ?
337 to_psb_intel_crtc(crtc
) : NULL
;
339 u32 dpll_reg
= MRST_DPLL_A
;
340 u32 pipeconf_reg
= PIPEACONF
;
341 u32 dspcntr_reg
= DSPACNTR
;
344 /*if mode setting on-going, back off*/
345 if ((dbi_output
->mode_flags
& MODE_SETTING_ON_GOING
) ||
346 (psb_crtc
&& psb_crtc
->mode_flags
& MODE_SETTING_ON_GOING
))
350 dpll_reg
= MRST_DPLL_A
;
351 pipeconf_reg
= PIPECCONF
;
352 dspcntr_reg
= DSPCCNTR
;
353 reg_offset
= MIPIC_REG_OFFSET
;
356 if (!gma_power_begin(dev
, true)) {
357 dev_err(dev
->dev
, "hw begin failed\n");
362 reg_val
= REG_READ(dpll_reg
);
363 if (!(reg_val
& DPLL_VCO_ENABLE
)) {
364 if (reg_val
& MDFLD_PWR_GATE_EN
) {
365 reg_val
&= ~MDFLD_PWR_GATE_EN
;
366 REG_WRITE(dpll_reg
, reg_val
);
371 reg_val
|= DPLL_VCO_ENABLE
;
372 REG_WRITE(dpll_reg
, reg_val
);
377 while (!(REG_READ(pipeconf_reg
) & PIPECONF_DSIPLL_LOCK
))
382 reg_val
= REG_READ(pipeconf_reg
);
383 if (!(reg_val
& PIPEACONF_ENABLE
)) {
384 reg_val
|= PIPEACONF_ENABLE
;
385 REG_WRITE(pipeconf_reg
, reg_val
);
386 REG_READ(pipeconf_reg
);
388 mdfldWaitForPipeEnable(dev
, pipe
);
392 reg_val
= REG_READ(dspcntr_reg
);
393 if (!(reg_val
& DISPLAY_PLANE_ENABLE
)) {
394 reg_val
|= DISPLAY_PLANE_ENABLE
;
395 REG_WRITE(dspcntr_reg
, reg_val
);
396 REG_READ(dspcntr_reg
);
400 /* Enable TE interrupt on this pipe */
401 mdfld_enable_te(dev
, pipe
);
404 /*clean IN_DSR flag*/
405 dbi_output
->mode_flags
&= ~MODE_SETTING_IN_DSR
;
411 void mdfld_dsi_dbi_exit_dsr(struct drm_device
*dev
, u32 update_src
)
413 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
414 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
415 struct mdfld_dsi_dbi_output
**dbi_output
;
420 dev_priv
->is_in_idle
= false;
421 dbi_output
= dsr_info
->dbi_outputs
;
423 #ifdef CONFIG_PM_RUNTIME
424 if (!enable_gfx_rtpm
) {
425 /* pm_runtime_allow(&gpDrmDevice->pdev->dev); */
426 /* schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
430 /* For each output, exit dsr */
431 for (i
= 0; i
< dsr_info
->dbi_output_num
; i
++) {
432 /* If panel has been turned off, skip */
433 if (!dbi_output
[i
] || !dbi_output
[i
]->dbi_panel_on
)
435 pipe
= dbi_output
[i
]->channel_num
? 2 : 0;
437 mdfld_dbi_output_exit_dsr(dbi_output
[i
], pipe
);
439 dev_priv
->dsr_fb_update
|= update_src
;
442 static bool mdfld_dbi_is_in_dsr(struct drm_device
*dev
)
444 if (REG_READ(MRST_DPLL_A
) & DPLL_VCO_ENABLE
)
446 if ((REG_READ(PIPEACONF
) & PIPEACONF_ENABLE
) ||
447 (REG_READ(PIPECCONF
) & PIPEACONF_ENABLE
))
449 if ((REG_READ(DSPACNTR
) & DISPLAY_PLANE_ENABLE
) ||
450 (REG_READ(DSPCCNTR
) & DISPLAY_PLANE_ENABLE
))
456 /* Periodically update dbi panel */
457 void mdfld_dbi_update_panel(struct drm_device
*dev
, int pipe
)
459 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
460 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
461 struct mdfld_dsi_dbi_output
**dbi_outputs
;
462 struct mdfld_dsi_dbi_output
*dbi_output
;
464 int can_enter_dsr
= 0;
467 dbi_outputs
= dsr_info
->dbi_outputs
;
468 dbi_output
= pipe
? dbi_outputs
[1] : dbi_outputs
[0];
474 damage_mask
= dev_priv
->dsr_fb_update
& MDFLD_DSR_DAMAGE_MASK_0
;
476 damage_mask
= dev_priv
->dsr_fb_update
& MDFLD_DSR_DAMAGE_MASK_2
;
480 /* If FB is damaged and panel is on update on-panel FB */
481 if (damage_mask
&& dbi_output
->dbi_panel_on
) {
482 dbi_output
->dsr_fb_update_done
= false;
484 if (dbi_output
->p_funcs
->update_fb
)
485 dbi_output
->p_funcs
->update_fb(dbi_output
, pipe
);
487 if (dev_priv
->dsr_enable
&& dbi_output
->dsr_fb_update_done
)
488 dev_priv
->dsr_fb_update
&= ~damage_mask
;
490 /*clean IN_DSR flag*/
491 dbi_output
->mode_flags
&= ~MODE_SETTING_IN_DSR
;
493 dbi_output
->dsr_idle_count
= 0;
495 dbi_output
->dsr_idle_count
++;
498 switch (dsr_info
->dbi_output_num
) {
500 if (dbi_output
->dsr_idle_count
> MDFLD_DSR_MAX_IDLE_COUNT
)
504 if (dbi_outputs
[0]->dsr_idle_count
> MDFLD_DSR_MAX_IDLE_COUNT
505 && dbi_outputs
[1]->dsr_idle_count
> MDFLD_DSR_MAX_IDLE_COUNT
)
509 DRM_ERROR("Wrong DBI output number\n");
512 /* Try to enter DSR */
514 for (i
= 0; i
< dsr_info
->dbi_output_num
; i
++) {
515 if (!mdfld_dbi_is_in_dsr(dev
) && dbi_outputs
[i
] &&
516 !(dbi_outputs
[i
]->mode_flags
& MODE_SETTING_ON_GOING
)) {
517 mdfld_dsi_dbi_enter_dsr(dbi_outputs
[i
],
518 dbi_outputs
[i
]->channel_num
? 2 : 0);
521 pr_err("%s: enter_dsr = 1\n", __func__
);
525 /*schedule rpm suspend after gfxrtdelay*/
526 #ifdef CONFIG_GFX_RTPM
527 if (!dev_priv
->rpm_enabled
529 /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
530 || pm_schedule_suspend(&dev
->pdev
->dev
, gfxrtdelay
))
532 "Runtime PM schedule suspend failed, rpm %d\n",
533 dev_priv
->rpm_enabled
);
538 int mdfld_dbi_dsr_init(struct drm_device
*dev
)
540 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
541 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
543 if (!dsr_info
|| IS_ERR(dsr_info
)) {
544 dsr_info
= kzalloc(sizeof(struct mdfld_dbi_dsr_info
),
547 dev_err(dev
->dev
, "No memory\n");
550 dev_priv
->dbi_dsr_info
= dsr_info
;
555 void mdfld_dbi_dsr_exit(struct drm_device
*dev
)
557 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
558 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
562 dev_priv
->dbi_dsr_info
= NULL
;
567 void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config
*dsi_config
,
570 struct drm_device
*dev
= dsi_config
->dev
;
571 u32 reg_offset
= pipe
? MIPIC_REG_OFFSET
: 0;
572 int lane_count
= dsi_config
->lane_count
;
575 dev_dbg(dev
->dev
, "Init DBI interface on pipe %d...\n", pipe
);
577 /* Un-ready device */
578 REG_WRITE((MIPIA_DEVICE_READY_REG
+ reg_offset
), 0x00000000);
580 /* Init dsi adapter before kicking off */
581 REG_WRITE((MIPIA_CONTROL_REG
+ reg_offset
), 0x00000018);
583 /* TODO: figure out how to setup these registers */
584 REG_WRITE((MIPIA_DPHY_PARAM_REG
+ reg_offset
), 0x150c3408);
585 REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG
+ reg_offset
),
587 REG_WRITE((MIPIA_DBI_BW_CTRL_REG
+ reg_offset
), 0x00000400);
588 REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG
+ reg_offset
), 0x00000001);
589 REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG
+ reg_offset
), 0x00000000);
591 /* Enable all interrupts */
592 REG_WRITE((MIPIA_INTR_EN_REG
+ reg_offset
), 0xffffffff);
593 /* Max value: 20 clock cycles of txclkesc */
594 REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG
+ reg_offset
), 0x0000001f);
595 /* Min 21 txclkesc, max: ffffh */
596 REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG
+ reg_offset
), 0x0000ffff);
597 /* Min: 7d0 max: 4e20 */
598 REG_WRITE((MIPIA_INIT_COUNT_REG
+ reg_offset
), 0x00000fa0);
600 /* Set up func_prg */
602 val
|= (dsi_config
->channel_num
<< DSI_DBI_VIRT_CHANNEL_OFFSET
);
603 val
|= DSI_DBI_COLOR_FORMAT_OPTION2
;
604 REG_WRITE((MIPIA_DSI_FUNC_PRG_REG
+ reg_offset
), val
);
606 REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG
+ reg_offset
), 0x3fffff);
607 REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG
+ reg_offset
), 0xffff);
609 /* De-assert dbi_stall when half of DBI FIFO is empty */
610 /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
612 REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG
+ reg_offset
), 0x46);
613 REG_WRITE((MIPIA_EOT_DISABLE_REG
+ reg_offset
), 0x00000000);
614 REG_WRITE((MIPIA_LP_BYTECLK_REG
+ reg_offset
), 0x00000004);
615 REG_WRITE((MIPIA_DEVICE_READY_REG
+ reg_offset
), 0x00000001);
619 /*DBI encoder helper funcs*/
620 static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs
= {
621 .dpms
= mdfld_dsi_dbi_dpms
,
622 .mode_fixup
= mdfld_dsi_dbi_mode_fixup
,
623 .prepare
= mdfld_dsi_dbi_prepare
,
624 .mode_set
= mdfld_dsi_dbi_mode_set
,
625 .commit
= mdfld_dsi_dbi_commit
,
628 /*DBI encoder funcs*/
629 static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs
= {
630 .destroy
= drm_encoder_cleanup
,
636 * Init DSI DBI encoder.
637 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
638 * return pointer of newly allocated DBI encoder, NULL on error
640 struct mdfld_dsi_encoder
*mdfld_dsi_dbi_init(struct drm_device
*dev
,
641 struct mdfld_dsi_connector
*dsi_connector
,
642 struct panel_funcs
*p_funcs
)
644 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
645 struct mdfld_dsi_dbi_output
*dbi_output
= NULL
;
646 struct mdfld_dsi_config
*dsi_config
;
647 struct drm_connector
*connector
= NULL
;
648 struct drm_encoder
*encoder
= NULL
;
649 struct drm_display_mode
*fixed_mode
= NULL
;
650 struct psb_gtt
*pg
= dev_priv
? (&dev_priv
->gtt
) : NULL
;
652 #ifdef CONFIG_MDFLD_DSI_DPU
653 struct mdfld_dbi_dpu_info
*dpu_info
= dev_priv
? (dev_priv
->dbi_dpu_info
) : NULL
;
655 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
? (dev_priv
->dbi_dsr_info
) : NULL
;
661 if (!pg
|| !dsi_connector
|| !p_funcs
) {
666 dsi_config
= mdfld_dsi_get_config(dsi_connector
);
667 pipe
= dsi_connector
->pipe
;
670 if (p_funcs
->reset
) {
671 ret
= p_funcs
->reset(pipe
);
673 DRM_ERROR("Panel %d hard-reset failed\n", pipe
);
677 /* Panel drvIC init */
678 if (p_funcs
->drv_ic_init
)
679 p_funcs
->drv_ic_init(dsi_config
, pipe
);
681 /* Panel power mode detect */
682 ret
= mdfld_dsi_get_power_mode(dsi_config
,
684 MDFLD_DSI_HS_TRANSMISSION
);
686 DRM_ERROR("Panel %d get power mode failed\n", pipe
);
687 dsi_connector
->status
= connector_status_disconnected
;
689 DRM_INFO("pipe %d power mode 0x%x\n", pipe
, data
);
690 dsi_connector
->status
= connector_status_connected
;
693 /*TODO: get panel info from DDB*/
695 dbi_output
= kzalloc(sizeof(struct mdfld_dsi_dbi_output
), GFP_KERNEL
);
697 dev_err(dev
->dev
, "No memory\n");
701 if (dsi_connector
->pipe
== 0) {
702 dbi_output
->channel_num
= 0;
703 dev_priv
->dbi_output
= dbi_output
;
704 } else if (dsi_connector
->pipe
== 2) {
705 dbi_output
->channel_num
= 1;
706 dev_priv
->dbi_output2
= dbi_output
;
708 dev_err(dev
->dev
, "only support 2 DSI outputs\n");
712 dbi_output
->dev
= dev
;
713 dbi_output
->p_funcs
= p_funcs
;
714 fixed_mode
= dsi_config
->fixed_mode
;
715 dbi_output
->panel_fixed_mode
= fixed_mode
;
717 /* Create drm encoder object */
718 connector
= &dsi_connector
->base
.base
;
719 encoder
= &dbi_output
->base
.base
;
720 drm_encoder_init(dev
,
722 p_funcs
->encoder_funcs
,
723 DRM_MODE_ENCODER_MIPI
);
724 drm_encoder_helper_add(encoder
, p_funcs
->encoder_helper_funcs
);
726 /* Attach to given connector */
727 drm_mode_connector_attach_encoder(connector
, encoder
);
729 /* Set possible CRTCs and clones */
730 if (dsi_connector
->pipe
) {
731 encoder
->possible_crtcs
= (1 << 2);
732 encoder
->possible_clones
= (1 << 1);
734 encoder
->possible_crtcs
= (1 << 0);
735 encoder
->possible_clones
= (1 << 0);
738 dev_priv
->dsr_fb_update
= 0;
739 dev_priv
->dsr_enable
= false;
740 dev_priv
->exit_idle
= mdfld_dsi_dbi_exit_dsr
;
742 dbi_output
->first_boot
= true;
743 dbi_output
->mode_flags
= MODE_SETTING_IN_ENCODER
;
745 #ifdef CONFIG_MDFLD_DSI_DPU
746 /* Add this output to dpu_info */
747 if (dsi_connector
->status
== connector_status_connected
) {
748 if (dsi_connector
->pipe
== 0)
749 dpu_info
->dbi_outputs
[0] = dbi_output
;
751 dpu_info
->dbi_outputs
[1] = dbi_output
;
753 dpu_info
->dbi_output_num
++;
756 #else /*CONFIG_MDFLD_DSI_DPU*/
757 if (dsi_connector
->status
== connector_status_connected
) {
758 /* Add this output to dsr_info */
759 if (dsi_connector
->pipe
== 0)
760 dsr_info
->dbi_outputs
[0] = dbi_output
;
762 dsr_info
->dbi_outputs
[1] = dbi_output
;
764 dsr_info
->dbi_output_num
++;
767 return &dbi_output
->base
;