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 static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output
*dbi_output
,
333 struct drm_device
*dev
= dbi_output
->dev
;
334 struct drm_crtc
*crtc
= dbi_output
->base
.base
.crtc
;
335 struct psb_intel_crtc
*psb_crtc
= (crtc
) ?
336 to_psb_intel_crtc(crtc
) : NULL
;
338 u32 dpll_reg
= MRST_DPLL_A
;
339 u32 pipeconf_reg
= PIPEACONF
;
340 u32 dspcntr_reg
= DSPACNTR
;
343 /*if mode setting on-going, back off*/
344 if ((dbi_output
->mode_flags
& MODE_SETTING_ON_GOING
) ||
345 (psb_crtc
&& psb_crtc
->mode_flags
& MODE_SETTING_ON_GOING
))
349 dpll_reg
= MRST_DPLL_A
;
350 pipeconf_reg
= PIPECCONF
;
351 dspcntr_reg
= DSPCCNTR
;
352 reg_offset
= MIPIC_REG_OFFSET
;
355 if (!gma_power_begin(dev
, true)) {
356 dev_err(dev
->dev
, "hw begin failed\n");
361 reg_val
= REG_READ(dpll_reg
);
362 if (!(reg_val
& DPLL_VCO_ENABLE
)) {
363 if (reg_val
& MDFLD_PWR_GATE_EN
) {
364 reg_val
&= ~MDFLD_PWR_GATE_EN
;
365 REG_WRITE(dpll_reg
, reg_val
);
370 reg_val
|= DPLL_VCO_ENABLE
;
371 REG_WRITE(dpll_reg
, reg_val
);
376 while (!(REG_READ(pipeconf_reg
) & PIPECONF_DSIPLL_LOCK
))
381 reg_val
= REG_READ(pipeconf_reg
);
382 if (!(reg_val
& PIPEACONF_ENABLE
)) {
383 reg_val
|= PIPEACONF_ENABLE
;
384 REG_WRITE(pipeconf_reg
, reg_val
);
385 REG_READ(pipeconf_reg
);
387 mdfldWaitForPipeEnable(dev
, pipe
);
391 reg_val
= REG_READ(dspcntr_reg
);
392 if (!(reg_val
& DISPLAY_PLANE_ENABLE
)) {
393 reg_val
|= DISPLAY_PLANE_ENABLE
;
394 REG_WRITE(dspcntr_reg
, reg_val
);
395 REG_READ(dspcntr_reg
);
399 /* Enable TE interrupt on this pipe */
400 mdfld_enable_te(dev
, pipe
);
403 /*clean IN_DSR flag*/
404 dbi_output
->mode_flags
&= ~MODE_SETTING_IN_DSR
;
410 void mdfld_dsi_dbi_exit_dsr(struct drm_device
*dev
, u32 update_src
)
412 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
413 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
414 struct mdfld_dsi_dbi_output
**dbi_output
;
419 dev_priv
->is_in_idle
= false;
420 dbi_output
= dsr_info
->dbi_outputs
;
422 #ifdef CONFIG_PM_RUNTIME
423 if (!enable_gfx_rtpm
) {
424 /* pm_runtime_allow(&gpDrmDevice->pdev->dev); */
425 /* schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
429 /* For each output, exit dsr */
430 for (i
= 0; i
< dsr_info
->dbi_output_num
; i
++) {
431 /* If panel has been turned off, skip */
432 if (!dbi_output
[i
] || !dbi_output
[i
]->dbi_panel_on
)
434 pipe
= dbi_output
[i
]->channel_num
? 2 : 0;
436 mdfld_dbi_output_exit_dsr(dbi_output
[i
], pipe
);
438 dev_priv
->dsr_fb_update
|= update_src
;
441 static bool mdfld_dbi_is_in_dsr(struct drm_device
*dev
)
443 if (REG_READ(MRST_DPLL_A
) & DPLL_VCO_ENABLE
)
445 if ((REG_READ(PIPEACONF
) & PIPEACONF_ENABLE
) ||
446 (REG_READ(PIPECCONF
) & PIPEACONF_ENABLE
))
448 if ((REG_READ(DSPACNTR
) & DISPLAY_PLANE_ENABLE
) ||
449 (REG_READ(DSPCCNTR
) & DISPLAY_PLANE_ENABLE
))
455 /* Periodically update dbi panel */
456 void mdfld_dbi_update_panel(struct drm_device
*dev
, int pipe
)
458 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
459 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
460 struct mdfld_dsi_dbi_output
**dbi_outputs
;
461 struct mdfld_dsi_dbi_output
*dbi_output
;
463 int can_enter_dsr
= 0;
466 dbi_outputs
= dsr_info
->dbi_outputs
;
467 dbi_output
= pipe
? dbi_outputs
[1] : dbi_outputs
[0];
473 damage_mask
= dev_priv
->dsr_fb_update
& MDFLD_DSR_DAMAGE_MASK_0
;
475 damage_mask
= dev_priv
->dsr_fb_update
& MDFLD_DSR_DAMAGE_MASK_2
;
479 /* If FB is damaged and panel is on update on-panel FB */
480 if (damage_mask
&& dbi_output
->dbi_panel_on
) {
481 dbi_output
->dsr_fb_update_done
= false;
483 if (dbi_output
->p_funcs
->update_fb
)
484 dbi_output
->p_funcs
->update_fb(dbi_output
, pipe
);
486 if (dev_priv
->dsr_enable
&& dbi_output
->dsr_fb_update_done
)
487 dev_priv
->dsr_fb_update
&= ~damage_mask
;
489 /*clean IN_DSR flag*/
490 dbi_output
->mode_flags
&= ~MODE_SETTING_IN_DSR
;
492 dbi_output
->dsr_idle_count
= 0;
494 dbi_output
->dsr_idle_count
++;
497 switch (dsr_info
->dbi_output_num
) {
499 if (dbi_output
->dsr_idle_count
> MDFLD_DSR_MAX_IDLE_COUNT
)
503 if (dbi_outputs
[0]->dsr_idle_count
> MDFLD_DSR_MAX_IDLE_COUNT
504 && dbi_outputs
[1]->dsr_idle_count
> MDFLD_DSR_MAX_IDLE_COUNT
)
508 DRM_ERROR("Wrong DBI output number\n");
511 /* Try to enter DSR */
513 for (i
= 0; i
< dsr_info
->dbi_output_num
; i
++) {
514 if (!mdfld_dbi_is_in_dsr(dev
) && dbi_outputs
[i
] &&
515 !(dbi_outputs
[i
]->mode_flags
& MODE_SETTING_ON_GOING
)) {
516 mdfld_dsi_dbi_enter_dsr(dbi_outputs
[i
],
517 dbi_outputs
[i
]->channel_num
? 2 : 0);
520 pr_err("%s: enter_dsr = 1\n", __func__
);
524 /*schedule rpm suspend after gfxrtdelay*/
525 #ifdef CONFIG_GFX_RTPM
526 if (!dev_priv
->rpm_enabled
528 /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
529 || pm_schedule_suspend(&dev
->pdev
->dev
, gfxrtdelay
))
531 "Runtime PM schedule suspend failed, rpm %d\n",
532 dev_priv
->rpm_enabled
);
537 int mdfld_dbi_dsr_init(struct drm_device
*dev
)
539 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
540 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
542 if (!dsr_info
|| IS_ERR(dsr_info
)) {
543 dsr_info
= kzalloc(sizeof(struct mdfld_dbi_dsr_info
),
546 dev_err(dev
->dev
, "No memory\n");
549 dev_priv
->dbi_dsr_info
= dsr_info
;
554 void mdfld_dbi_dsr_exit(struct drm_device
*dev
)
556 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
557 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
->dbi_dsr_info
;
561 dev_priv
->dbi_dsr_info
= NULL
;
565 void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config
*dsi_config
,
568 struct drm_device
*dev
= dsi_config
->dev
;
569 u32 reg_offset
= pipe
? MIPIC_REG_OFFSET
: 0;
570 int lane_count
= dsi_config
->lane_count
;
573 dev_dbg(dev
->dev
, "Init DBI interface on pipe %d...\n", pipe
);
575 /* Un-ready device */
576 REG_WRITE((MIPIA_DEVICE_READY_REG
+ reg_offset
), 0x00000000);
578 /* Init dsi adapter before kicking off */
579 REG_WRITE((MIPIA_CONTROL_REG
+ reg_offset
), 0x00000018);
581 /* TODO: figure out how to setup these registers */
582 REG_WRITE((MIPIA_DPHY_PARAM_REG
+ reg_offset
), 0x150c3408);
583 REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG
+ reg_offset
),
585 REG_WRITE((MIPIA_DBI_BW_CTRL_REG
+ reg_offset
), 0x00000400);
586 REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG
+ reg_offset
), 0x00000001);
587 REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG
+ reg_offset
), 0x00000000);
589 /* Enable all interrupts */
590 REG_WRITE((MIPIA_INTR_EN_REG
+ reg_offset
), 0xffffffff);
591 /* Max value: 20 clock cycles of txclkesc */
592 REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG
+ reg_offset
), 0x0000001f);
593 /* Min 21 txclkesc, max: ffffh */
594 REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG
+ reg_offset
), 0x0000ffff);
595 /* Min: 7d0 max: 4e20 */
596 REG_WRITE((MIPIA_INIT_COUNT_REG
+ reg_offset
), 0x00000fa0);
598 /* Set up func_prg */
600 val
|= (dsi_config
->channel_num
<< DSI_DBI_VIRT_CHANNEL_OFFSET
);
601 val
|= DSI_DBI_COLOR_FORMAT_OPTION2
;
602 REG_WRITE((MIPIA_DSI_FUNC_PRG_REG
+ reg_offset
), val
);
604 REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG
+ reg_offset
), 0x3fffff);
605 REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG
+ reg_offset
), 0xffff);
607 /* De-assert dbi_stall when half of DBI FIFO is empty */
608 /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
610 REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG
+ reg_offset
), 0x46);
611 REG_WRITE((MIPIA_EOT_DISABLE_REG
+ reg_offset
), 0x00000000);
612 REG_WRITE((MIPIA_LP_BYTECLK_REG
+ reg_offset
), 0x00000004);
613 REG_WRITE((MIPIA_DEVICE_READY_REG
+ reg_offset
), 0x00000001);
617 /*DBI encoder helper funcs*/
618 static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs
= {
619 .dpms
= mdfld_dsi_dbi_dpms
,
620 .mode_fixup
= mdfld_dsi_dbi_mode_fixup
,
621 .prepare
= mdfld_dsi_dbi_prepare
,
622 .mode_set
= mdfld_dsi_dbi_mode_set
,
623 .commit
= mdfld_dsi_dbi_commit
,
626 /*DBI encoder funcs*/
627 static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs
= {
628 .destroy
= drm_encoder_cleanup
,
634 * Init DSI DBI encoder.
635 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
636 * return pointer of newly allocated DBI encoder, NULL on error
638 struct mdfld_dsi_encoder
*mdfld_dsi_dbi_init(struct drm_device
*dev
,
639 struct mdfld_dsi_connector
*dsi_connector
,
640 struct panel_funcs
*p_funcs
)
642 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
643 struct mdfld_dsi_dbi_output
*dbi_output
= NULL
;
644 struct mdfld_dsi_config
*dsi_config
;
645 struct drm_connector
*connector
= NULL
;
646 struct drm_encoder
*encoder
= NULL
;
647 struct drm_display_mode
*fixed_mode
= NULL
;
648 struct psb_gtt
*pg
= dev_priv
? (&dev_priv
->gtt
) : NULL
;
649 struct mdfld_dbi_dpu_info
*dpu_info
= dev_priv
? (dev_priv
->dbi_dpu_info
) : NULL
;
650 struct mdfld_dbi_dsr_info
*dsr_info
= dev_priv
? (dev_priv
->dbi_dsr_info
) : NULL
;
655 if (!pg
|| !dsi_connector
|| !p_funcs
) {
660 dsi_config
= mdfld_dsi_get_config(dsi_connector
);
661 pipe
= dsi_connector
->pipe
;
664 if (p_funcs
->reset
) {
665 ret
= p_funcs
->reset(pipe
);
667 DRM_ERROR("Panel %d hard-reset failed\n", pipe
);
671 /* Panel drvIC init */
672 if (p_funcs
->drv_ic_init
)
673 p_funcs
->drv_ic_init(dsi_config
, pipe
);
675 /* Panel power mode detect */
676 ret
= mdfld_dsi_get_power_mode(dsi_config
,
678 MDFLD_DSI_HS_TRANSMISSION
);
680 DRM_ERROR("Panel %d get power mode failed\n", pipe
);
681 dsi_connector
->status
= connector_status_disconnected
;
683 DRM_INFO("pipe %d power mode 0x%x\n", pipe
, data
);
684 dsi_connector
->status
= connector_status_connected
;
687 /*TODO: get panel info from DDB*/
689 dbi_output
= kzalloc(sizeof(struct mdfld_dsi_dbi_output
), GFP_KERNEL
);
691 dev_err(dev
->dev
, "No memory\n");
695 if (dsi_connector
->pipe
== 0) {
696 dbi_output
->channel_num
= 0;
697 dev_priv
->dbi_output
= dbi_output
;
698 } else if (dsi_connector
->pipe
== 2) {
699 dbi_output
->channel_num
= 1;
700 dev_priv
->dbi_output2
= dbi_output
;
702 dev_err(dev
->dev
, "only support 2 DSI outputs\n");
706 dbi_output
->dev
= dev
;
707 dbi_output
->p_funcs
= p_funcs
;
708 fixed_mode
= dsi_config
->fixed_mode
;
709 dbi_output
->panel_fixed_mode
= fixed_mode
;
711 /* Create drm encoder object */
712 connector
= &dsi_connector
->base
.base
;
713 encoder
= &dbi_output
->base
.base
;
714 /* Review this if we ever get MIPI-HDMI bridges or similar */
715 drm_encoder_init(dev
,
717 p_funcs
->encoder_funcs
,
718 DRM_MODE_ENCODER_LVDS
);
719 drm_encoder_helper_add(encoder
, p_funcs
->encoder_helper_funcs
);
721 /* Attach to given connector */
722 drm_mode_connector_attach_encoder(connector
, encoder
);
724 /* Set possible CRTCs and clones */
725 if (dsi_connector
->pipe
) {
726 encoder
->possible_crtcs
= (1 << 2);
727 encoder
->possible_clones
= (1 << 1);
729 encoder
->possible_crtcs
= (1 << 0);
730 encoder
->possible_clones
= (1 << 0);
733 dev_priv
->dsr_fb_update
= 0;
734 dev_priv
->dsr_enable
= false;
735 dev_priv
->exit_idle
= mdfld_dsi_dbi_exit_dsr
;
737 dbi_output
->first_boot
= true;
738 dbi_output
->mode_flags
= MODE_SETTING_IN_ENCODER
;
740 /* Add this output to dpu_info if in DPU mode */
741 if (dpu_info
&& dsi_connector
->status
== connector_status_connected
) {
742 if (dsi_connector
->pipe
== 0)
743 dpu_info
->dbi_outputs
[0] = dbi_output
;
745 dpu_info
->dbi_outputs
[1] = dbi_output
;
747 dpu_info
->dbi_output_num
++;
748 } else if (dsi_connector
->status
== connector_status_connected
) {
749 /* Add this output to dsr_info if not */
750 if (dsi_connector
->pipe
== 0)
751 dsr_info
->dbi_outputs
[0] = dbi_output
;
753 dsr_info
->dbi_outputs
[1] = dbi_output
;
755 dsr_info
->dbi_output_num
++;
757 return &dbi_output
->base
;