1 /* linux/drivers/video/exynos/decon_8890/decon_reg_8890.c
3 * Copyright 2013-2015 Samsung Electronics
4 * Jiun Yu <jiun.yu@samsung.com>
6 * Jiun Yu <jiun.yu@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
15 /******************* CAL raw functions implementation *************************/
17 u32
decon_reg_get_cam_status(void __iomem
*cam_status
)
20 return readl(cam_status
);
26 void decon_reg_set_vclk_freerun(u32 id
, u32 en
)
28 u32 val
= en
? ~0 : 0;
33 decon_write_mask(id
, DISPIF_CONTROL
, val
, DISPIF_CLOCK_FREE_RUN_EN
);
37 void decon_reg_set_underrun_scheme(u32 id
, enum decon_hold_scheme mode
)
44 val
= DISPIF_CLOCK_UNDERRUN_SCHEME_F(mode
);
45 mask
= DISPIF_CLOCK_UNDERRUN_SCHEME_MASK
;
46 decon_write_mask(id
, DISPIF_CONTROL
, val
, mask
);
50 void decon_reg_set_dispif_porch(u32 id
, struct decon_lcd
*lcd_info
)
57 val
= DISPIF_VBPD_F(lcd_info
->vbp
) | DISPIF_VFPD_F(lcd_info
->vfp
);
58 decon_write(id
, DISPIF_TIMING_CONTROL_0
, val
);
59 val
= DISPIF_VSPD_F(lcd_info
->vsa
);
60 decon_write(id
, DISPIF_TIMING_CONTROL_1
, val
);
62 val
= DISPIF_HBPD_F(lcd_info
->hbp
) | DISPIF_HFPD_F(lcd_info
->hfp
);
63 decon_write(id
, DISPIF_TIMING_CONTROL_2
, val
);
64 val
= DISPIF_HSPD_F(lcd_info
->hsa
);
65 decon_write(id
, DISPIF_TIMING_CONTROL_3
, val
);
69 void decon_reg_set_dispif_size(u32 id
, u32 width
, u32 height
)
76 val
= DISPIF_HEIGHT_F(height
) | DISPIF_WIDTH_F(width
);
77 decon_write(id
, DISPIF_SIZE_CONTROL_0
, val
);
80 decon_write(id
, DISPIF_SIZE_CONTROL_1
, val
);
84 void decon_reg_get_dispif_size(u32 id
, u32
*w
, u32
*h
)
91 val
= decon_read(id
, DISPIF_SIZE_CONTROL_0
);
92 *w
= DISPIF_WIDTH_GET(val
);
93 *h
= DISPIF_HEIGHT_GET(val
);
97 void decon_reg_set_dispif_sync_pol(u32 id
, u8 h_sync_pol
, u8 v_sync_pol
)
102 decon_write_mask(id
, DISPIF_CONTROL
,
103 DISPIF_HSYNC_ACTIVE_VALUE(h_sync_pol
) | DISPIF_VSYNC_ACTIVE_VALUE(v_sync_pol
),
104 DISPIF_HSYNC_ACTIVE_VALUE_MASK
| DISPIF_VSYNC_ACTIVE_VALUE_MASK
);
107 int decon_reg_reset(u32 id
)
111 decon_write_mask(id
, GLOBAL_CONTROL
, ~0, GLOBAL_CONTROL_SRESET
);
112 for (tries
= 2000; tries
; --tries
) {
113 if (~decon_read(id
, GLOBAL_CONTROL
) & GLOBAL_CONTROL_SRESET
)
119 decon_err("failed to reset Decon\n");
126 void decon_reg_set_operation_mode(u32 id
, enum decon_psr_mode mode
)
130 mask
= GLOBAL_CONTROL_OPERATION_MODE_F
;
131 if (mode
== DECON_MIPI_COMMAND_MODE
)
132 val
= GLOBAL_CONTROL_OPERATION_MODE_I80IF_F
;
134 val
= GLOBAL_CONTROL_OPERATION_MODE_RGBIF_F
;
135 decon_write_mask(id
, GLOBAL_CONTROL
, val
, mask
);
138 void decon_reg_direct_on_off(u32 id
, u32 en
)
143 mask
= (GLOBAL_CONTROL_DECON_EN
| GLOBAL_CONTROL_DECON_EN_F
);
144 decon_write_mask(id
, GLOBAL_CONTROL
, val
, mask
);
147 void decon_reg_per_frame_off(u32 id
)
149 decon_write_mask(id
, GLOBAL_CONTROL
, 0, GLOBAL_CONTROL_DECON_EN_F
);
152 void decon_reg_set_clkgate_mode(u32 id
, u32 en
)
159 mask
= CLOCK_CONTROL_0_S_MASK
;
161 mask
= CLOCK_CONTROL_0_T_MASK
;
163 mask
= CLOCK_CONTROL_0_F_MASK
;
164 decon_write_mask(id
, CLOCK_CONTROL_0
, val
, mask
);
168 * Check the connection of DECON & DMA(DPP)
170 * CH0[5:4](vg0=2) - CH1[9:8](vgf0=4) - CH2[13:12](vgf1=5)
171 * - CH3[17:16](g1=1) - CH4[21:20](vg1=3)
173 * return : 0=decon0, 1=decon1, 2=decon2, 3=idle
175 u32
decon_reg_get_rsc_dma_info(u32 id
, u32 dpp_id
)
178 /* NA, G1-VG0-VG1-VGF0-VGF1 */
179 u32 bit_pos
[6] = {0, 16, 4, 20, 8, 12};
185 val
= decon_read(id
, RESOURCE_OCCUPANCY_INFO_1
);
187 decon_id
= (val
>> bit_pos
[dpp_id
]) & 0x3;
191 int decon_reg_instant_stop(u32 id
, unsigned long timeout
)
195 decon_reg_direct_on_off(id
, 0);
196 decon_reg_update_req_global(id
);
197 ret
= decon_reg_wait_idle_status_timeout(id
, timeout
);
203 * API is considering real possible Display Scenario
204 * such as following examples
205 * < Single display > D0=16K, D1=0K, D2=0K
206 * < Dual/Triple display > D0=8K, D1=8K, D2=0K
207 * < Single display + USB TV > D0=8K, D1=8K, D2=0K
208 * < Dual display + DP > D0=4K, D1=4K, D2=8K
209 * < Dual display + WB-PRE > D0=8K, D1=8K, D2=0K
210 * --> Not necessary OutFIFO @preWB ( need @postWB )
212 * Current API does not configure various 8K case fully!
213 * Therefore, modify/add configuration cases if necessary
214 * "Resource Confliction" will happen if enabled simultaneously
216 void decon_reg_set_sram_share(u32 id
, enum decon_fifo_mode fifo_mode
)
222 val
= ALL_SRAM_SHARE_DISABLE
;
226 val
= FF0_SRAM_SHARE_ENABLE_F
;
228 val
= FF1_SRAM_SHARE_ENABLE_F
;
230 val
= FF2_SRAM_SHARE_ENABLE_F
;
233 /* [HACK] only available for D0+D1 or D0+D2 */
235 val
= (FLOATING_SRAM_SHARE_ENABLE_F
236 | FF0_SRAM_SHARE_ENABLE_F
);
240 val
= (FF1_SRAM_SHARE_ENABLE_F
241 | FF2_SRAM_SHARE_ENABLE_F
);
244 val
= ALL_SRAM_SHARE_ENABLE
;
249 decon_write(id
, SRAM_SHARE_ENABLE
, val
);
252 void decon_reg_set_splitter(u32 id
, u32 width
, u32 height
,
253 u32 split_idx
, u32 overlap_w
)
260 val
= SPLITTER_HEIGHT_F(height
) | SPLITTER_WIDTH_F(width
* 2);
261 decon_write(id
, SPLITTER_SIZE_CONTROL_0
, val
);
263 val
= height
* width
;
264 decon_write(id
, SPLITTER_SIZE_CONTROL_1
, val
);
267 decon_write(id
, SPLITTER_SPLIT_IDX_CONTROL
, split_idx
);
268 val
= SPLITTER_OVERLAP_F(overlap_w
);
269 decon_write(id
, SPLITTER_OVERLAP_CONTROL
, val
);
272 void decon_reg_get_splitter_size(u32 id
, u32
*w
, u32
*h
)
276 val
= decon_read(id
, SPLITTER_SIZE_CONTROL_0
);
277 *w
= SPLITTER_WIDTH_GET(val
);
278 *h
= SPLITTER_HEIGHT_GET(val
);
281 void decon_reg_set_frame_fifo_threshold(u32 id
, u32 ff0_th
, u32 ff1_th
)
286 val
= FRAME_FIFO_1_TH_F(ff1_th
) | FRAME_FIFO_0_TH_F(ff0_th
);
288 val
= FRAME_FIFO_0_TH_F(ff0_th
);
290 decon_write(id
, FRAME_FIFO_TH_CONTROL_0
, val
);
294 * frame_fifo0 : must be set always
295 * frame_fifo1 : must be set for dual-dsi or dual-dsc
297 void decon_reg_set_frame_fifo_size(u32 id
, u32 ff_id
, u32 width
, u32 height
)
302 val
= FRAME_FIFO_HEIGHT_F(height
) | FRAME_FIFO_WIDTH_F(width
);
303 cnt
= height
* width
;
306 decon_write(id
, FRAME_FIFO_0_SIZE_CONTROL_0
, val
);
307 decon_write(id
, FRAME_FIFO_0_SIZE_CONTROL_1
, cnt
);
308 th
= FRAME_FIFO_0_TH_F(width
);
309 mask
= FRAME_FIFO_0_TH_MASK
;
311 decon_write(id
, FRAME_FIFO_1_SIZE_CONTROL_0
, val
);
312 decon_write(id
, FRAME_FIFO_1_SIZE_CONTROL_1
, cnt
);
313 th
= FRAME_FIFO_1_TH_F(width
);
314 mask
= FRAME_FIFO_1_TH_MASK
;
317 decon_write_mask(id
, FRAME_FIFO_TH_CONTROL_0
, th
, mask
);
320 void decon_reg_get_frame_fifo_size(u32 id
, u32 ff_id
, u32
*w
, u32
*h
)
325 val
= decon_read(id
, FRAME_FIFO_0_SIZE_CONTROL_0
);
328 val
= decon_read(id
, FRAME_FIFO_1_SIZE_CONTROL_0
);
333 *w
= FRAME_FIFO_WIDTH_GET(val
);
334 *h
= FRAME_FIFO_HEIGHT_GET(val
);
337 void decon_reg_get_frame_fifo_threshold(u32 id
, u32
*ff0_th
, u32
*ff1_th
)
341 val
= decon_read(id
, FRAME_FIFO_TH_CONTROL_0
);
342 *ff0_th
= FRAME_FIFO_0_TH_GET(val
);
343 *ff1_th
= FRAME_FIFO_1_TH_GET(val
);
346 void decon_reg_get_frame_fifo_level(u32 id
, u32
*ff0_lv
, u32
*ff1_lv
)
349 *ff0_lv
= decon_read(id
, FRAME_FIFO_0_LEVEL
);
350 *ff1_lv
= decon_read(id
, FRAME_FIFO_1_LEVEL
);
352 *ff1_lv
= decon_read(id
, FRAME_FIFO_0_LEVEL
);
357 void decon_reg_set_hysteresis(u32 id
, u32 en
)
359 u32 val
= en
? ~0 : 0;
361 decon_write_mask(id
, HYSTERESIS_CONTROL
, val
, HYSTERESIS_ENABLE_F
);
364 void decon_reg_set_hysteresis_threshold(u32 id
, u32 high_th
, u32 low_th
)
368 val
= HYSTERESIS_HIGH_TH_F(high_th
) | HYSTERESIS_LOW_TH_F(low_th
);
369 decon_write(id
, HYSTERESIS_THRESHOLD
, val
);
372 void decon_reg_set_formatter_pixel_order_swap(u32 id
,
373 u32 en_p0123
, u32 en_p23
, u32 en_p01
)
377 val
= FORMATTER_PIXEL_ORDER_SWAP(en_p0123
, en_p23
, en_p01
);
378 mask
= FORMATTER_PIXEL_ORDER_SWAP_MASK
;
379 decon_write_mask(id
, FORMATTER_CONTROL
, val
, mask
);
382 void decon_reg_set_rgb_order(u32 id
, enum decon_rgb_order order
)
387 val
= DISPIF_RGB_ORDER_F(order
);
388 mask
= DISPIF_RGB_ORDER_MASK
;
389 decon_write_mask(id
, DISPIF_CONTROL
, val
, mask
);
391 val
= FORMATTER_OUT_RGB_ORDER_F(order
);
392 mask
= FORMATTER_OUT_RGB_ORDER_MASK
;
393 decon_write_mask(id
, FORMATTER_CONTROL
, val
, mask
);
398 * formatter0/1 setting depends on DSIM_IFx
400 * 2. dsim_if0 only : formatter0
401 * 3. dsim_if1 only : formatter1
403 void decon_reg_set_formatter_size(u32 id
, u32 fmt_id
, u32 width
, u32 height
)
407 if (id
&& (fmt_id
== 1))
410 val
= FORMATTER_HEIGHT_F(height
) | FORMATTER_WIDTH_F(width
);
411 cnt
= height
* width
;
414 decon_write(id
, FORMATTER0_SIZE_CONTROL_0
, val
);
415 decon_write(id
, FORMATTER0_SIZE_CONTROL_1
, cnt
);
417 decon_write(id
, FORMATTER1_SIZE_CONTROL_0
, val
);
418 decon_write(id
, FORMATTER1_SIZE_CONTROL_1
, cnt
);
422 void decon_reg_get_formatter_size(u32 id
, u32 fmt_id
, u32
*w
, u32
*h
)
427 val
= decon_read(id
, FORMATTER0_SIZE_CONTROL_0
);
430 val
= decon_read(id
, FORMATTER1_SIZE_CONTROL_0
);
435 *w
= FORMATTER_WIDTH_GET(val
);
436 *h
= FORMATTER_HEIGHT_GET(val
);
439 void decon_reg_set_blender_bg_image_size(u32 id
,
440 enum decon_dsi_mode dsi_mode
, struct decon_lcd
*lcd_info
)
442 u32 width
, val
, mask
;
444 width
= lcd_info
->xres
;
446 if (dsi_mode
== DSI_MODE_DUAL_DSI
)
449 val
= BLENDER_BG_HEIGHT_F(lcd_info
->yres
) | BLENDER_BG_WIDTH_F(width
);
450 mask
= BLENDER_BG_HEIGHT_MASK
| BLENDER_BG_WIDTH_MASK
;
451 decon_write_mask(id
, BLENDER_BG_IMAGE_SIZE_0
, val
, mask
);
453 val
= (lcd_info
->yres
) * width
;
454 decon_write(id
, BLENDER_BG_IMAGE_SIZE_1
, val
);
457 void decon_reg_get_blender_bg_image_size(u32 id
, u32
*p_width
, u32
*p_height
)
461 val
= decon_read(id
, BLENDER_BG_IMAGE_SIZE_0
);
462 *p_width
= BLENDER_BG_WIDTH_GET(val
);
463 *p_height
= BLENDER_BG_HEIGHT_GET(val
);
467 * argb_color : 32-bit
468 * A[31:24] - R[23:16] - G[15:8] - B[7:0]
470 void decon_reg_set_blender_bg_image_color(u32 id
, u32 argb_color
)
473 u32 bg_alpha
= 0, bg_red
= 0;
474 u32 bg_green
= 0, bg_blue
= 0;
476 bg_alpha
= (argb_color
>> 24) & 0xFF;
477 bg_red
= (argb_color
>> 16) & 0xFF;
478 bg_green
= (argb_color
>> 8) & 0xFF;
479 bg_blue
= (argb_color
>> 0) & 0xFF;
481 val
= BLENDER_BG_A_F(bg_alpha
) | BLENDER_BG_R_F(bg_red
);
482 mask
= BLENDER_BG_A_MASK
| BLENDER_BG_R_MASK
;
483 decon_write_mask(id
, BLENDER_BG_IMAGE_COLOR_0
, val
, mask
);
485 val
= BLENDER_BG_G_F(bg_green
) | BLENDER_BG_B_F(bg_blue
);
486 mask
= BLENDER_BG_G_MASK
| BLENDER_BG_B_MASK
;
487 decon_write_mask(id
, BLENDER_BG_IMAGE_COLOR_1
, val
, mask
);
490 void decon_reg_set_lrmerger_mode(u32 id
, u32 win_idx
,
491 enum decon_merger_mode lrm_mode
)
495 if (win_idx
== 0 || win_idx
== 1) {
496 val
= LRM01_MODE_F(lrm_mode
);
497 mask
= LRM01_MODE_MASK
;
498 } else if (win_idx
== 2 || win_idx
== 3) {
499 val
= LRM23_MODE_F(lrm_mode
);
500 mask
= LRM23_MODE_MASK
;
503 decon_write_mask(id
, LRMERGER_MODE_CONTROL
, val
, mask
);
506 void decon_reg_set_dqe_lpd_exit_control(u32 id
, u32 en
)
508 u32 val
= en
? ~0 : 0;
510 decon_write_mask(id
, DATA_PATH_CONTROL_2
, val
, DQE_LPD_EXIT_CTRL
);
513 void decon_reg_set_dqe_hsc_path(u32 id
, enum decon_share_path hsc_path
)
517 val
= HSC_PATH_F(hsc_path
);
518 decon_write_mask(id
, DATA_PATH_CONTROL_2
, val
, HSC_PATH_MASK
);
521 void decon_reg_set_dqe_aps_path(u32 id
, enum decon_share_path aps_path
)
525 val
= APS_PATH_F(aps_path
);
526 decon_write_mask(id
, DATA_PATH_CONTROL_2
, val
, APS_PATH_MASK
);
529 void decon_reg_set_data_path(u32 id
, enum decon_data_path d_path
,
530 enum decon_enhance_path e_path
)
534 val
= ENHANCE_LOGIC_PATH_F(e_path
) | COMP_LINKIF_WB_PATH_F(d_path
);
535 mask
= ENHANCE_LOGIC_PATH_MASK
| COMP_LINKIF_WB_PATH_MASK
;
536 decon_write_mask(id
, DATA_PATH_CONTROL_2
, val
, mask
);
539 void decon_reg_get_data_path(u32 id
, enum decon_data_path
*d_path
,
540 enum decon_enhance_path
*e_path
)
544 val
= decon_read(id
, DATA_PATH_CONTROL_2
);
545 *d_path
= COMP_LINKIF_WB_PATH_GET(val
);
546 *e_path
= ENHANCE_LOGIC_PATH_GET(val
);
550 * Check major configuration of data_path_control
553 * DSC_ENC1[5] DSC_ENC0[4]
555 * DSIM_IF1[1] DSIM_IF0[0]
557 u32
decon_reg_get_data_path_cfg(u32 id
, enum decon_path_cfg con_id
)
563 val
= decon_read(id
, DATA_PATH_CONTROL_2
);
564 d_path
= COMP_LINKIF_WB_PATH_GET(val
);
567 case PATH_CON_ID_DSCC_EN
:
568 if (d_path
& (0x1 << PATH_CON_ID_DSCC_EN
))
571 case PATH_CON_ID_DUAL_DSC
:
572 if ((d_path
& (0x3 << PATH_CON_ID_DUAL_DSC
)) == 0x30)
575 case PATH_CON_ID_DSIM_IF0
:
576 if (d_path
& (0x1 << PATH_CON_ID_DSIM_IF0
))
579 case PATH_CON_ID_DSIM_IF1
:
580 if (d_path
& (0x1 << PATH_CON_ID_DSIM_IF1
))
591 * 'DATA_PATH_CONTROL_2' SFR must be set before calling this function!!
593 * - no compression : x-resolution
594 * - dsc compression : width_per_enc
596 void decon_reg_config_data_path_size(u32 id
,
597 u32 width
, u32 height
, u32 overlap_w
)
603 struct decon_device
*decon
= get_decon_drvdata(id
);
605 dual_dsc
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DUAL_DSC
);
606 dsim_if0
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DSIM_IF0
);
607 dsim_if1
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DSIM_IF1
);
608 if (dsim_if0
&& dsim_if1
)
612 if (dual_dsi
&& !dual_dsc
)
613 decon_reg_set_splitter(id
, width
*2, height
, width
, overlap_w
);
615 decon_reg_set_splitter(id
, width
, height
, width
, 0);
618 decon_reg_set_frame_fifo_size(id
, 0, width
, height
);
619 if (dual_dsi
|| dual_dsc
)
620 decon_reg_set_frame_fifo_size(id
, 1, width
, height
);
623 if (dsim_if0
&& !dsim_if1
) {
624 /* Single-DSI : DSIM0 */
626 decon_reg_set_formatter_size(id
, 0, width
*2, height
);
628 decon_reg_set_formatter_size(id
, 0, width
, height
);
629 } else if (!dsim_if0
&& dsim_if1
) {
630 /* Single-DSI : DSIM1 */
632 decon_reg_set_formatter_size(id
, 1, width
*2, height
);
634 decon_reg_set_formatter_size(id
, 1, width
, height
);
635 } else if (dual_dsi
) {
637 decon_reg_set_formatter_size(id
, 0, width
, height
);
638 decon_reg_set_formatter_size(id
, 1, width
, height
);
640 /* When Decon WrightBack, Remove Log. Too many logs*/
641 if (decon
->dt
.out_type
!= DECON_OUT_WB
)
642 decon_err("decon%d : not specified case for FORMATTER\n", id
);
643 decon_reg_set_formatter_size(id
, 0, width
, height
);
647 void decon_reg_print_data_path_size(u32 id
)
651 decon_reg_get_splitter_size(id
, &w
, &h
);
652 decon_dbg("SPLITTER size: w(%d), h(%d)\n", w
, h
);
653 decon_reg_get_frame_fifo_size(id
, 0, &w
, &h
);
654 decon_dbg("FIFO0 size: w(%d), h(%d)\n", w
, h
);
655 decon_reg_get_formatter_size(id
, 0, &w
, &h
);
656 decon_dbg("FORMATTER0 size: w(%d), h(%d)\n", w
, h
);
659 decon_reg_get_frame_fifo_size(id
, 1, &w
, &h
);
660 decon_dbg("FIFO1 size: w(%d), h(%d)\n", w
, h
);
661 decon_reg_get_formatter_size(id
, 1, &w
, &h
);
662 decon_dbg("FORMATTER1 size: w(%d), h(%d)\n", w
, h
);
666 /* TODO: This will be modified in the future */
667 void dpu_sysreg_set_lpmux(void __iomem
*sysreg
)
669 writel(0x1201, sysreg
+ DISP_LPMUX_CFG
);
678 void dpu_sysreg_set_te_sel(u32 id
, u32 te_sel
)
682 /* TE_SEL : GPIO -> change SPEEDY if necessary */
683 val
= SEL_TE_PATH(0, te_sel
)
684 | SEL_TE_PATH(1, te_sel
)
685 | SEL_TE_PATH(2, te_sel
);
686 sysreg_write(id
, DISP_DPU_TE_SEL
, val
);
687 decon_dbg("%s: TE_SEL = 0x%x\n", __func__
, val
);
692 * 'DATA_PATH_CONTROL_2' SFR must be set before calling this function!!
694 * [ Implementation Info about CONNECTION ]
695 * 1) dsim_if0@DECON0 - DSIM0
696 * 2) dsim_if1@DECON0 - DSIM1
697 * 3) dsim_if0@DECON1 - DSIM1 (description for 'dsim_if2')
698 * --> modify code if you want to change connection between dsim_if and dsim
700 void decon_reg_set_disp_ss_cfg(u32 id
, struct decon_mode_info
*psr
)
706 if (psr
->out_type
!= DECON_OUT_DSI
) {
707 decon_err("%s: [decon%d] output is not DSI\n",
712 /* dsim_if2 is equal to dsim_if0 at DECON1 */
713 dsim_if0
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DSIM_IF0
);
714 dsim_if1
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DSIM_IF1
);
715 if (!dsim_if0
&& !dsim_if1
) {
716 decon_err("%s: [decon%d] both dsim_if are not used\n",
721 /* DPMUX_CFG configuration : DECON(DISPIF) - DSIM connnection */
722 val
= sysreg_read(id
, DISP_DLMUX_CFG
);
726 * - SEL_DSIM2DISPIF must be set as 'Reserved Value(=4)'
727 * when connection is not necessary.
728 * Otherwise, abnormal operation will happen!
732 /* [ dsim_if0-dsim0 ] + [ dsim_if1-dsim1 ] */
733 val
= val
& (~(SEL_DISPIF2DSIM_MASK(0) | SEL_DSIM2DISPIF_MASK(0)
734 | SEL_DISPIF2DSIM_MASK(1) | SEL_DSIM2DISPIF_MASK(1)));
736 val
|= SEL_DISPIF2DSIM(0, 0) | SEL_DSIM2DISPIF(0, 0);
738 /* for setting Reserved Value */
739 val
|= SEL_DISPIF2DSIM(0, 0) | SEL_DSIM2DISPIF(3, 0);
742 val
|= SEL_DISPIF2DSIM(1, 1) | SEL_DSIM2DISPIF(1, 1);
744 /* for setting Reserved Value */
745 val
|= SEL_DISPIF2DSIM(1, 1) | SEL_DSIM2DISPIF(3, 1);
750 val
= val
& (~(SEL_DISPIF2DSIM_MASK(1)
751 | SEL_DSIM2DISPIF_MASK(2)));
753 val
|= SEL_DISPIF2DSIM(2, 1) | SEL_DSIM2DISPIF(1, 2);
755 /* for setting Reserved Value */
756 val
|= SEL_DISPIF2DSIM(2, 1) | SEL_DSIM2DISPIF(3, 2);
763 sysreg_write(id
, DISP_DLMUX_CFG
, val
);
764 decon_dbg("%s: DLMUX_CFG = 0x%x\n", __func__
, val
);
766 /* TE_SEL : GPIO -> change SPEEDY if necessary */
767 val
= SEL_TE_PATH(0, TE_FROM_GPIO
)
768 | SEL_TE_PATH(1, TE_FROM_GPIO
)
769 | SEL_TE_PATH(2, TE_FROM_GPIO
);
770 sysreg_write(id
, DISP_DPU_TE_SEL
, val
);
771 decon_dbg("%s: TE_SEL = 0x%x\n", __func__
, val
);
774 * LPMUX_CFG configuration : DSIM - MIPI_DPHY connection
775 * -> will be configured at DSIM
779 void decon_reg_set_start_crc(u32 id
, u32 en
)
781 u32 val
= en
? ~0 : 0;
783 decon_write_mask(id
, CRC_CONTROL
, val
, CRC_START
);
786 /* bit_sel : 0=B, 1=G, 2=R */
787 void decon_reg_set_select_crc_bits(u32 id
, u32 bit_sel
)
791 val
= CRC_BITS_SEL(bit_sel
);
792 decon_write_mask(id
, CRC_CONTROL
, val
, CRC_BITS_SEL_MASK
);
795 void decon_reg_get_crc_data(u32 id
, u32
*w0_data
, u32
*w1_data
)
799 val
= decon_read(id
, CRC_DATA
);
800 *w0_data
= CRC_DATA_WCLK0_GET(val
);
801 *w1_data
= CRC_DATA_WCLK1_GET(val
);
804 void decon_reg_clear_all_update_req(u32 id
)
806 decon_write(id
, SHADOW_REG_UPDATE_REQ
, 0);
809 void decon_reg_update_req_global(u32 id
)
813 mask
= SHADOW_REG_UPDATE_REQ_GLOBAL
;
814 decon_write_mask(id
, SHADOW_REG_UPDATE_REQ
, ~0, mask
);
817 void decon_reg_update_req_window(u32 id
, u32 win_idx
)
821 mask
= SHADOW_REG_UPDATE_REQ_WIN(win_idx
);
822 decon_write_mask(id
, SHADOW_REG_UPDATE_REQ
, ~0, mask
);
825 void decon_reg_all_win_shadow_update_req(u32 id
)
829 /* DECON0 has 6 windows */
831 mask
= SHADOW_REG_UPDATE_REQ_FOR_DECON0
;
832 /* DECON1/2 has 5 windows */
834 mask
= SHADOW_REG_UPDATE_REQ_FOR_DECON2
;
836 decon_write_mask(id
, SHADOW_REG_UPDATE_REQ
, ~0, mask
);
840 u32
decon_reg_get_idle_status(u32 id
)
844 val
= decon_read(id
, GLOBAL_CONTROL
);
845 if (val
& GLOBAL_CONTROL_IDLE_STATUS
)
851 int decon_reg_wait_idle_status_timeout(u32 id
, unsigned long timeout
)
853 unsigned long delay_time
= 10;
854 unsigned long cnt
= timeout
/ delay_time
;
858 status
= decon_reg_get_idle_status(id
);
861 } while (!status
&& cnt
);
864 decon_err("decon%d wait timeout decon idle status(%u)\n", id
, status
);
871 u32
decon_reg_get_run_status(u32 id
)
875 val
= decon_read(id
, GLOBAL_CONTROL
);
876 if (val
& GLOBAL_CONTROL_RUN_STATUS
)
882 /* Determine that DECON is perfectly shuttled off through checking this * function */
883 int decon_reg_wait_run_is_off_timeout(u32 id
, unsigned long timeout
)
885 unsigned long delay_time
= 10;
886 unsigned long cnt
= timeout
/ delay_time
;
890 status
= decon_reg_get_run_status(id
);
893 } while (status
&& cnt
);
896 decon_err("decon%d wait timeout decon run is shut-off(%u)\n", id
, status
);
903 int decon_reg_wait_run_status_timeout(u32 id
, unsigned long timeout
)
905 unsigned long delay_time
= 10;
906 unsigned long cnt
= timeout
/ delay_time
;
910 status
= decon_reg_get_run_status(id
);
913 } while (!status
&& cnt
);
916 decon_err("decon%d wait timeout decon run status(%u)\n", id
, status
);
923 void decon_reg_config_win_channel(u32 id
, u32 win_idx
,
924 enum decon_idma_type type
)
929 ch_id
= dpu_dma_type_to_channel(type
);
931 val
= WIN_CHMAP_F(win_idx
, ch_id
);
932 mask
= WIN_CHMAP_MASK(win_idx
);
933 decon_write_mask(id
, DATA_PATH_CONTROL_1
, val
, mask
);
937 /* wait until shadow update is finished */
938 int decon_reg_wait_for_update_timeout(u32 id
, unsigned long timeout
)
940 unsigned long delay_time
= 100;
941 unsigned long cnt
= timeout
/ delay_time
;
943 while (decon_read(id
, SHADOW_REG_UPDATE_REQ
) && --cnt
)
947 decon_err("decon%d timeout of updating decon registers\n", id
);
955 /* wait until shadow update is finished */
956 int decon_reg_wait_for_window_update_timeout(u32 id
, u32 win_idx
,
957 unsigned long timeout
)
959 unsigned long delay_time
= 100;
960 unsigned long cnt
= timeout
/ delay_time
;
962 while ((decon_read(id
, SHADOW_REG_UPDATE_REQ
) & SHADOW_REG_UPDATE_REQ_WIN(win_idx
)) && --cnt
)
966 decon_err("decon%d timeout of updating decon window registers\n", id
);
973 void decon_reg_set_hw_trig_sel(u32 id
, enum decon_te_src te_src
)
977 val
= HW_TRIG_SEL(te_src
);
978 mask
= HW_TRIG_SEL_MASK
;
979 decon_write_mask(id
, HW_SW_TRIG_CONTROL
, val
, mask
);
982 void decon_reg_set_hw_trig_skip(u32 id
, u32 cnt
)
986 val
= HW_TRIG_SKIP(cnt
);
987 mask
= HW_TRIG_SKIP_MASK
;
988 decon_write_mask(id
, HW_SW_TRIG_CONTROL
, val
, mask
);
991 void decon_reg_configure_trigger(u32 id
, enum decon_trig_mode mode
)
996 /* Using TRIG_AUTO_MASK_EN=1'b0 is strictly prohibited! (SPEC-OUT) */
998 if (mode
== DECON_SW_TRIG
)
1003 decon_write_mask(id
, HW_SW_TRIG_CONTROL
, val
, mask
);
1006 void decon_reg_set_trigger(u32 id
, struct decon_mode_info
*psr
,
1007 enum decon_set_trig en
)
1011 if (psr
->psr_mode
== DECON_VIDEO_MODE
)
1014 if (psr
->trig_mode
== DECON_SW_TRIG
) {
1015 val
= (en
== DECON_TRIG_ENABLE
) ? SW_TRIG_EN
: 0;
1016 mask
= HW_TRIG_EN
| SW_TRIG_EN
;
1018 val
= (en
== DECON_TRIG_ENABLE
) ?
1019 HW_TRIG_EN
: HW_TRIG_MASK_DECON
;
1020 mask
= HW_TRIG_EN
| HW_TRIG_MASK_DECON
;
1023 decon_write_mask(id
, HW_SW_TRIG_CONTROL
, val
, mask
);
1026 void decon_reg_set_timeout_value(u32 id
, u32 to_val
)
1028 decon_write(id
, TIME_OUT_VALUE
, to_val
);
1031 /****************** DSC related functions ********************/
1032 void dsc_reg_swreset(u32 dsc_id
)
1034 dsc_write_mask(dsc_id
, DSC_CONTROL0
, 1, DSC_SW_RESET
);
1037 void dsc_reg_set_dcg_all(u32 dsc_id
, u32 en
)
1042 val
= DSC_DCG_EN_ALL_MASK
;
1043 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_DCG_EN_ALL_MASK
);
1046 void dsc_reg_set_swap(u32 dsc_id
, u32 bit_s
, u32 byte_s
, u32 word_s
)
1050 val
= DSC_SWAP(bit_s
, byte_s
, word_s
);
1051 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_SWAP_MASK
);
1054 void dsc_reg_set_flatness_det_th(u32 dsc_id
, u32 th
)
1058 val
= DSC_FLATNESS_DET_TH_F(th
);
1059 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_FLATNESS_DET_TH_MASK
);
1062 void dsc_reg_set_slice_mode_change(u32 dsc_id
, u32 en
)
1066 val
= DSC_SLICE_MODE_CH_F(en
);
1067 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_SLICE_MODE_CH_MASK
);
1070 void dsc_reg_set_encoder_bypass(u32 dsc_id
, u32 en
)
1074 val
= DSC_BYPASS_F(en
);
1075 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_BYPASS_MASK
);
1078 void dsc_reg_set_auto_clock_gate(u32 dsc_id
, u32 en
)
1082 val
= DSC_CG_EN_F(en
);
1083 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_CG_EN_MASK
);
1086 void dsc_reg_set_dual_slice(u32 dsc_id
, u32 en
)
1090 val
= DSC_DUAL_SLICE_EN_F(en
);
1091 dsc_write_mask(dsc_id
, DSC_CONTROL0
, val
, DSC_DUAL_SLICE_EN_MASK
);
1094 /* V-porch setting is unnecessary : use reset values */
1095 void dsc_reg_set_vertical_porch(u32 dsc_id
, u32 vfp
, u32 vsw
, u32 vbp
)
1099 val
= (DSC_V_FRONT_F(vfp
) | DSC_V_SYNC_F(vsw
) | DSC_V_BACK_F(vbp
));
1100 dsc_write_mask(dsc_id
, DSC_CONTROL1
, val
, DSC_V_BLANK_MASK
);
1103 /* H-porch setting is unnecessary : use reset values */
1104 void dsc_reg_set_horizontal_porch(u32 dsc_id
, u32 hfp
, u32 hsw
, u32 hbp
)
1108 val
= (DSC_H_FRONT_F(hfp
) | DSC_H_SYNC_F(hsw
) | DSC_H_BACK_F(hbp
));
1109 dsc_write_mask(dsc_id
, DSC_CONTROL2
, val
, DSC_H_BLANK_MASK
);
1114 ###############################################################################
1115 dsc PPS Configuration
1116 ###############################################################################
1120 * APIs which user setting or calculation is required are implemented
1121 * - PPS04 ~ PPS35 except reserved
1124 void dsc_reg_set_pps_04_comp_cfg(u32 dsc_id
, u32 comp_cfg
)
1128 val
= PPS04_COMP_CFG(comp_cfg
);
1129 mask
= PPS04_COMP_CFG_MASK
;
1130 dsc_write_mask(dsc_id
, DSC_PPS04_07
, val
, mask
);
1133 void dsc_reg_set_pps_05_bit_per_pixel(u32 dsc_id
, u32 bpp
)
1137 val
= PPS05_BPP(bpp
);
1138 mask
= PPS05_BPP_MASK
;
1139 dsc_write_mask(dsc_id
, DSC_PPS04_07
, val
, mask
);
1142 void dsc_reg_set_pps_06_07_picture_height(u32 dsc_id
, u32 height
)
1146 val
= PPS06_07_PIC_HEIGHT(height
);
1147 mask
= PPS06_07_PIC_HEIGHT_MASK
;
1148 dsc_write_mask(dsc_id
, DSC_PPS04_07
, val
, mask
);
1151 void dsc_reg_set_pps_08_09_picture_width(u32 dsc_id
, u32 width
)
1155 val
= PPS08_09_PIC_WIDHT(width
);
1156 mask
= PPS08_09_PIC_WIDHT_MASK
;
1157 dsc_write_mask(dsc_id
, DSC_PPS08_11
, val
, mask
);
1159 void dsc_reg_set_pps_10_11_slice_height(u32 dsc_id
, u32 slice_height
)
1163 val
= PPS10_11_SLICE_HEIGHT(slice_height
);
1164 mask
= PPS10_11_SLICE_HEIGHT_MASK
;
1165 dsc_write_mask(dsc_id
, DSC_PPS08_11
, val
, mask
);
1168 void dsc_reg_set_pps_12_13_slice_width(u32 dsc_id
, u32 slice_width
)
1172 val
= PPS12_13_SLICE_WIDTH(slice_width
);
1173 mask
= PPS12_13_SLICE_WIDTH_MASK
;
1174 dsc_write_mask(dsc_id
, DSC_PPS12_15
, val
, mask
);
1177 /* chunk_size = slice_width */
1178 void dsc_reg_set_pps_14_15_chunk_size(u32 dsc_id
, u32 chunk_size
)
1182 val
= PPS14_15_CHUNK_SIZE(chunk_size
);
1183 mask
= PPS14_15_CHUNK_SIZE_MASK
;
1184 dsc_write_mask(dsc_id
, DSC_PPS12_15
, val
, mask
);
1187 void dsc_reg_set_pps_16_17_init_xmit_delay(u32 dsc_id
, u32 xmit_delay
)
1191 val
= PPS16_17_INIT_XMIT_DELAY(xmit_delay
);
1192 mask
= PPS16_17_INIT_XMIT_DELAY_MASK
;
1193 dsc_write_mask(dsc_id
, DSC_PPS16_19
, val
, mask
);
1196 void dsc_reg_set_pps_18_19_init_dec_delay(u32 dsc_id
, u32 dec_delay
)
1200 val
= PPS18_19_INIT_DEC_DELAY(dec_delay
);
1201 mask
= PPS18_19_INIT_DEC_DELAY_MASK
;
1202 dsc_write_mask(dsc_id
, DSC_PPS16_19
, val
, mask
);
1205 void dsc_reg_set_pps_21_initial_scale_value(u32 dsc_id
, u32 scale_value
)
1209 val
= PPS21_INIT_SCALE_VALUE(scale_value
);
1210 mask
= PPS21_INIT_SCALE_VALUE_MASK
;
1211 dsc_write_mask(dsc_id
, DSC_PPS20_23
, val
, mask
);
1214 void dsc_reg_set_pps_22_23_scale_increment_interval(u32 dsc_id
, u32 sc_inc
)
1218 val
= PPS22_23_SCALE_INC_INTERVAL(sc_inc
);
1219 mask
= PPS22_23_SCALE_INC_INTERVAL_MASK
;
1220 dsc_write_mask(dsc_id
, DSC_PPS20_23
, val
, mask
);
1223 void dsc_reg_set_pps_24_25_scale_decrement_interval(u32 dsc_id
, u32 sc_dec
)
1227 val
= PPS24_25_SCALE_DEC_INTERVAL(sc_dec
);
1228 mask
= PPS24_25_SCALE_DEC_INTERVAL_MASK
;
1229 dsc_write_mask(dsc_id
, DSC_PPS24_27
, val
, mask
);
1232 void dsc_reg_set_pps_27_first_line_bpg_offset(u32 dsc_id
, u32 fl_bpg_off
)
1236 val
= PPS27_FL_BPG_OFFSET(fl_bpg_off
);
1237 mask
= PPS27_FL_BPG_OFFSET_MASK
;
1238 dsc_write_mask(dsc_id
, DSC_PPS24_27
, val
, mask
);
1241 void dsc_reg_set_pps_28_29_nfl_bpg_offset(u32 dsc_id
, u32 nfl_bpg_off
)
1245 val
= PPS28_29_NFL_BPG_OFFSET(nfl_bpg_off
);
1246 mask
= PPS28_29_NFL_BPG_OFFSET_MASK
;
1247 dsc_write_mask(dsc_id
, DSC_PPS28_31
, val
, mask
);
1250 void dsc_reg_set_pps_30_31_slice_bpg_offset(u32 dsc_id
, u32 slice_bpg_off
)
1254 val
= PPS30_31_SLICE_BPG_OFFSET(slice_bpg_off
);
1255 mask
= PPS30_31_SLICE_BPG_OFFSET_MASK
;
1256 dsc_write_mask(dsc_id
, DSC_PPS28_31
, val
, mask
);
1259 void dsc_reg_set_pps_32_33_initial_offset(u32 dsc_id
, u32 init_off
)
1263 val
= PPS32_33_INIT_OFFSET(init_off
);
1264 mask
= PPS32_33_INIT_OFFSET_MASK
;
1265 dsc_write_mask(dsc_id
, DSC_PPS32_35
, val
, mask
);
1268 void dsc_reg_set_pps_34_35_final_offset(u32 dsc_id
, u32 fin_off
)
1272 val
= PPS34_35_FINAL_OFFSET(fin_off
);
1273 mask
= PPS34_35_FINAL_OFFSET_MASK
;
1274 dsc_write_mask(dsc_id
, DSC_PPS32_35
, val
, mask
);
1277 void dsc_reg_set_pps_58_59_rc_range_param0(u32 dsc_id
, u32 rc_range_param
)
1281 val
= PPS58_59_RC_RANGE_PARAM(rc_range_param
);
1282 mask
= PPS58_59_RC_RANGE_PARAM_MASK
;
1283 dsc_write_mask(dsc_id
, DSC_PPS56_59
, val
, mask
);
1286 static inline u32
dsc_round_up(u32 x
, u32 a
)
1288 u32 remained
= x
% a
;
1293 return x
+ a
- remained
;
1296 static inline u32
ceil_div(u32 a
, u32 b
)
1298 return (a
+ (b
- 1)) / b
;
1301 /* full size default value */
1302 u32
dsc_get_dual_slice_mode(struct decon_lcd
*lcd_info
)
1304 u32 dual_slice_en
= 0;
1306 if (lcd_info
->dsc_cnt
== 1) {
1307 if (lcd_info
->dsc_slice_num
== 2)
1309 } else if(lcd_info
->dsc_cnt
== 2) {
1310 if (lcd_info
->dsc_slice_num
== 4)
1316 return dual_slice_en
;
1319 /* full size default value */
1320 u32
dsc_get_slice_mode_change(struct decon_lcd
*lcd_info
)
1322 u32 slice_mode_ch
= 0;
1324 if (lcd_info
->dsc_cnt
== 2) {
1325 if (lcd_info
->dsc_slice_num
== 2)
1329 return slice_mode_ch
;
1332 void dsc_get_partial_update_info(struct decon_lcd
*lcd
,
1333 bool in_slice
[4], u32 ds_en
[2], u32 sm_ch
[2])
1335 switch (lcd
->dsc_slice_num
) {
1337 if ((in_slice
[0] + in_slice
[1]) % 2) {
1338 ds_en
[DECON_DSC_ENC0
] = 0;
1339 sm_ch
[DECON_DSC_ENC0
] = 1;
1341 ds_en
[DECON_DSC_ENC0
] = 1;
1342 sm_ch
[DECON_DSC_ENC0
] = 0;
1345 if ((in_slice
[2] + in_slice
[3]) % 2) {
1346 ds_en
[DECON_DSC_ENC1
] = 0;
1347 sm_ch
[DECON_DSC_ENC1
] = 1;
1349 ds_en
[DECON_DSC_ENC1
] = 1;
1350 sm_ch
[DECON_DSC_ENC1
] = 0;
1355 if (lcd
->dsc_cnt
== 2) {
1356 ds_en
[DECON_DSC_ENC0
] = 0;
1357 sm_ch
[DECON_DSC_ENC0
] = 1;
1359 ds_en
[DECON_DSC_ENC1
] = 0;
1360 sm_ch
[DECON_DSC_ENC1
] = 1;
1363 ds_en
[DECON_DSC_ENC0
] = 0;
1364 sm_ch
[DECON_DSC_ENC0
] = 1;
1365 } else if (in_slice
[1]) {
1366 ds_en
[DECON_DSC_ENC0
] = 0;
1367 sm_ch
[DECON_DSC_ENC0
] = 1;
1369 ds_en
[DECON_DSC_ENC0
] = 1;
1370 sm_ch
[DECON_DSC_ENC0
] = 0;
1373 ds_en
[DECON_DSC_ENC1
] = ds_en
[DECON_DSC_ENC0
];
1374 sm_ch
[DECON_DSC_ENC1
] = sm_ch
[DECON_DSC_ENC0
];
1378 ds_en
[DECON_DSC_ENC0
] = 0;
1379 sm_ch
[DECON_DSC_ENC0
] = 0;
1381 ds_en
[DECON_DSC_ENC1
] = 0;
1382 sm_ch
[DECON_DSC_ENC1
] = 0;
1385 decon_err("Not specified case for Partial Update in DSC!\n");
1391 void dsc_reg_config_control(u32 dsc_id
, u32 ds_en
, u32 sm_ch
)
1393 dsc_reg_set_dcg_all(dsc_id
, 1);
1394 dsc_reg_set_swap(dsc_id
, 0x0, 0x1, 0x0);
1395 /* flatness detection is fixed 2@8bpc / 8@10bpc / 32@12bpc */
1396 dsc_reg_set_flatness_det_th(dsc_id
, 0x2);
1397 dsc_reg_set_auto_clock_gate(dsc_id
, 1);
1398 dsc_reg_set_dual_slice(dsc_id
, ds_en
);
1399 dsc_reg_set_encoder_bypass(dsc_id
, 0);
1400 dsc_reg_set_slice_mode_change(dsc_id
, sm_ch
);
1406 * - range : [0, 32] & (multiples of 2)
1407 * if non-zero value is applied, this means slice_w increasing.
1408 * therefore, DECON & DSIM setting must also be aligned.
1409 * --> must check if DDI module is supporting this feature !!!
1411 void dsc_calc_pps_info(struct decon_lcd
*lcd_info
, u32 dscc_en
,
1412 struct decon_dsc
*dsc_enc
)
1415 u32 slice_width
, slice_height
;
1416 u32 pic_width
, pic_height
;
1418 u32 dual_slice_en
= 0;
1419 u32 bpp
, chunk_size
;
1421 u32 groups_per_line
, groups_total
;
1423 /* initial values, also used for other pps calcualtion */
1424 u32 rc_model_size
= 0x2000;
1425 u32 num_extra_mux_bits
= 246;
1426 u32 initial_xmit_delay
= 0x200;
1427 u32 initial_dec_delay
= 0x4c0;
1428 /* when 'slice_w >= 70' */
1429 u32 initial_scale_value
= 0x20;
1430 u32 first_line_bpg_offset
= 0x0c;
1431 u32 initial_offset
= 0x1800;
1432 u32 rc_range_parameters
= 0x0102;
1434 u32 final_offset
, final_scale
;
1435 u32 flag
, nfl_bpg_offset
, slice_bpg_offset
;
1436 u32 scale_increment_interval
, scale_decrement_interval
;
1437 u32 slice_width_byte_unit
, comp_slice_width_byte_unit
;
1438 u32 comp_slice_width_pixel_unit
;
1440 u32 dsc_enc0_w
= 0, dsc_enc0_h
;
1441 u32 dsc_enc1_w
= 0, dsc_enc1_h
;
1444 width
= lcd_info
->xres
;
1445 height
= lcd_info
->yres
;
1447 overlap_w
= dsc_enc
->overlap_w
;
1450 /* OVERLAP can be used in the dual-slice case (if one ENC) */
1451 width_eff
= (width
>> 1) + overlap_w
;
1453 width_eff
= width
+ overlap_w
;
1455 pic_width
= width_eff
;
1456 dual_slice_en
= dsc_get_dual_slice_mode(lcd_info
);
1458 slice_width
= width_eff
>> 1;
1460 slice_width
= width_eff
;
1462 pic_height
= height
;
1463 slice_height
= lcd_info
->dsc_slice_h
;
1466 chunk_size
= slice_width
;
1467 slice_bits
= 8 * chunk_size
* slice_height
;
1469 while ((slice_bits
- num_extra_mux_bits
) % 48) {
1470 num_extra_mux_bits
--;
1473 groups_per_line
= (slice_width
+ 2) / 3;
1474 groups_total
= groups_per_line
* slice_height
;
1476 final_offset
= rc_model_size
- ((initial_xmit_delay
* (8<<4) + 8)>>4)
1477 + num_extra_mux_bits
;
1478 final_scale
= 8 * rc_model_size
/ (rc_model_size
- final_offset
);
1480 flag
= (first_line_bpg_offset
* 2048) % (slice_height
- 1);
1481 nfl_bpg_offset
= (first_line_bpg_offset
* 2048) / (slice_height
- 1);
1483 nfl_bpg_offset
= nfl_bpg_offset
+ 1;
1485 flag
= 2048 * (rc_model_size
- initial_offset
+ num_extra_mux_bits
)
1487 slice_bpg_offset
= 2048
1488 * (rc_model_size
- initial_offset
+ num_extra_mux_bits
)
1491 slice_bpg_offset
= slice_bpg_offset
+ 1;
1493 scale_increment_interval
= (2048 * final_offset
) / ((final_scale
- 9)
1494 * (nfl_bpg_offset
+ slice_bpg_offset
));
1495 scale_decrement_interval
= groups_per_line
/ (initial_scale_value
- 8);
1497 /* 3bytes per pixel */
1498 slice_width_byte_unit
= slice_width
* 3;
1499 /* integer value, /3 for 1/3 compression */
1500 comp_slice_width_byte_unit
= slice_width_byte_unit
/ 3;
1501 /* integer value, /3 for pixel unit */
1502 comp_slice_width_pixel_unit
= comp_slice_width_byte_unit
/ 3;
1504 i
= comp_slice_width_byte_unit
% 3;
1505 j
= comp_slice_width_pixel_unit
% 2;
1507 if ( i
== 0 && j
== 0) {
1508 dsc_enc0_w
= comp_slice_width_pixel_unit
;
1509 dsc_enc0_h
= pic_height
;
1511 dsc_enc1_w
= comp_slice_width_pixel_unit
;
1512 dsc_enc1_h
= pic_height
;
1514 } else if (i
== 0 && j
!= 0) {
1515 dsc_enc0_w
= comp_slice_width_pixel_unit
+ 1;
1516 dsc_enc0_h
= pic_height
;
1518 dsc_enc1_w
= comp_slice_width_pixel_unit
+ 1;
1519 dsc_enc1_h
= pic_height
;
1521 } else if (i
!= 0) {
1523 comp_slice_width_pixel_unit
++;
1524 j
= comp_slice_width_pixel_unit
% 2;
1528 dsc_enc0_w
= comp_slice_width_pixel_unit
;
1529 dsc_enc0_h
= pic_height
;
1531 dsc_enc1_w
= comp_slice_width_pixel_unit
;
1532 dsc_enc1_h
= pic_height
;
1536 if (dual_slice_en
) {
1537 dsc_enc0_w
= dsc_enc0_w
* 2;
1539 dsc_enc1_w
= dsc_enc1_w
* 2;
1542 /* Save information to structure variable */
1543 dsc_enc
->comp_cfg
= 0x30;
1544 dsc_enc
->bit_per_pixel
= bpp
<< 4;
1545 dsc_enc
->pic_height
= pic_height
;
1546 dsc_enc
->pic_width
= pic_width
;
1547 dsc_enc
->slice_height
= slice_height
;
1548 dsc_enc
->slice_width
= slice_width
;
1549 dsc_enc
->chunk_size
= chunk_size
;
1550 dsc_enc
->initial_xmit_delay
= initial_xmit_delay
;
1551 dsc_enc
->initial_dec_delay
= initial_dec_delay
;
1552 dsc_enc
->initial_scale_value
= initial_scale_value
;
1553 dsc_enc
->scale_increment_interval
= scale_increment_interval
;
1554 dsc_enc
->scale_decrement_interval
= scale_decrement_interval
;
1555 dsc_enc
->first_line_bpg_offset
= first_line_bpg_offset
;
1556 dsc_enc
->nfl_bpg_offset
= nfl_bpg_offset
;
1557 dsc_enc
->slice_bpg_offset
= slice_bpg_offset
;
1558 dsc_enc
->initial_offset
= initial_offset
;
1559 dsc_enc
->final_offset
= final_offset
;
1560 dsc_enc
->rc_range_parameters
= rc_range_parameters
;
1562 dsc_enc
->width_per_enc
= dsc_enc0_w
;
1565 u32
dsc_get_compressed_slice_width(u32 x_resol
, u32 dscc_en
, u32 ds_en
)
1569 u32 slice_width_byte_unit
, comp_slice_width_byte_unit
;
1570 u32 comp_slice_width_pixel_unit
;
1572 u32 comp_slice_w
= 0;
1575 /* check if two encoders are used */
1577 width_eff
= (x_resol
>> 1) + overlap_w
;
1579 width_eff
= x_resol
+ overlap_w
;
1581 /* check if dual slice is enabled */
1583 slice_width
= width_eff
>> 1;
1585 slice_width
= width_eff
;
1587 /* 3bytes per pixel */
1588 slice_width_byte_unit
= slice_width
* 3;
1589 /* integer value, /3 for 1/3 compression */
1590 comp_slice_width_byte_unit
= slice_width_byte_unit
/ 3;
1591 /* integer value, /3 for pixel unit */
1592 comp_slice_width_pixel_unit
= comp_slice_width_byte_unit
/ 3;
1594 i
= comp_slice_width_byte_unit
% 3;
1595 j
= comp_slice_width_pixel_unit
% 2;
1597 if ( i
== 0 && j
== 0) {
1598 comp_slice_w
= comp_slice_width_pixel_unit
;
1599 } else if (i
== 0 && j
!= 0) {
1600 comp_slice_w
= comp_slice_width_pixel_unit
+ 1;
1601 } else if (i
!= 0) {
1603 comp_slice_width_pixel_unit
++;
1604 j
= comp_slice_width_pixel_unit
% 2;
1608 comp_slice_w
= comp_slice_width_pixel_unit
;
1611 return comp_slice_w
;
1615 void dsc_reg_set_pps(u32 dsc_id
, struct decon_dsc
*dsc_enc
)
1617 dsc_reg_set_pps_04_comp_cfg(dsc_id
, dsc_enc
->comp_cfg
);
1618 dsc_reg_set_pps_05_bit_per_pixel(dsc_id
, dsc_enc
->bit_per_pixel
);
1619 dsc_reg_set_pps_06_07_picture_height(dsc_id
, dsc_enc
->pic_height
);
1621 dsc_reg_set_pps_08_09_picture_width(dsc_id
, dsc_enc
->pic_width
);
1622 dsc_reg_set_pps_10_11_slice_height(dsc_id
, dsc_enc
->slice_height
);
1623 dsc_reg_set_pps_12_13_slice_width(dsc_id
, dsc_enc
->slice_width
);
1624 dsc_reg_set_pps_14_15_chunk_size(dsc_id
, dsc_enc
->chunk_size
);
1626 dsc_reg_set_pps_16_17_init_xmit_delay(dsc_id
,
1627 dsc_enc
->initial_xmit_delay
);
1630 dsc_reg_set_pps_18_19_init_dec_delay(dsc_id
, 0x01B4);
1632 dsc_reg_set_pps_18_19_init_dec_delay(dsc_id
,
1633 dsc_enc
->initial_dec_delay
);
1635 dsc_reg_set_pps_21_initial_scale_value(dsc_id
,
1636 dsc_enc
->initial_scale_value
);
1638 dsc_reg_set_pps_22_23_scale_increment_interval(dsc_id
,
1639 dsc_enc
->scale_increment_interval
);
1640 dsc_reg_set_pps_24_25_scale_decrement_interval(dsc_id
,
1641 dsc_enc
->scale_decrement_interval
);
1643 dsc_reg_set_pps_27_first_line_bpg_offset(dsc_id
,
1644 dsc_enc
->first_line_bpg_offset
);
1645 dsc_reg_set_pps_28_29_nfl_bpg_offset(dsc_id
, dsc_enc
->nfl_bpg_offset
);
1647 dsc_reg_set_pps_30_31_slice_bpg_offset(dsc_id
,
1648 dsc_enc
->slice_bpg_offset
);
1649 dsc_reg_set_pps_32_33_initial_offset(dsc_id
, dsc_enc
->initial_offset
);
1650 dsc_reg_set_pps_34_35_final_offset(dsc_id
, dsc_enc
->final_offset
);
1652 /* min_qp0 = 0 , max_qp0 = 4 , bpg_off0 = 2 */
1653 dsc_reg_set_pps_58_59_rc_range_param0(dsc_id
,
1654 dsc_enc
->rc_range_parameters
);
1656 /* PPS79 ~ PPS87 : 3HF4 is different with VESA SCR v4 */
1657 dsc_write(dsc_id
, 0x006C, 0x1AB62AF6);
1658 dsc_write(dsc_id
, 0x0070, 0x2B342B74);
1659 dsc_write(dsc_id
, 0x0074, 0x3B746BF4);
1665 * Following PPS SFRs will be set from DDI PPS Table (DSC Decoder)
1669 * <PPS Table e.g.> SEQ_PPS_SLICE4[] @ s6e3hf4_param.h
1671 void dsc_get_decoder_pps_info(struct decon_dsc
*dsc_dec
,
1672 const unsigned char pps_t
[90])
1674 dsc_dec
->comp_cfg
= (u32
) pps_t
[4];
1675 dsc_dec
->bit_per_pixel
= (u32
) pps_t
[5];
1676 dsc_dec
->pic_height
= (u32
) (pps_t
[6] << 8 | pps_t
[7]);
1677 dsc_dec
->pic_width
= (u32
) (pps_t
[8] << 8 | pps_t
[9]);
1678 dsc_dec
->slice_height
= (u32
) (pps_t
[10] << 8 | pps_t
[11]);
1679 dsc_dec
->slice_width
= (u32
) (pps_t
[12] << 8 | pps_t
[13]);
1680 dsc_dec
->chunk_size
= (u32
) (pps_t
[14] << 8 | pps_t
[15]);
1681 dsc_dec
->initial_xmit_delay
= (u32
) (pps_t
[16] << 8 | pps_t
[17]);
1682 dsc_dec
->initial_dec_delay
= (u32
) (pps_t
[18] << 8 | pps_t
[19]);
1683 dsc_dec
->initial_scale_value
= (u32
) pps_t
[21];
1684 dsc_dec
->scale_increment_interval
= (u32
) (pps_t
[22] << 8 | pps_t
[23]);
1685 dsc_dec
->scale_decrement_interval
= (u32
) (pps_t
[24] << 8 | pps_t
[25]);
1686 dsc_dec
->first_line_bpg_offset
= (u32
) pps_t
[27];
1687 dsc_dec
->nfl_bpg_offset
= (u32
) (pps_t
[28] << 8 | pps_t
[29]);
1688 dsc_dec
->slice_bpg_offset
= (u32
) (pps_t
[30] << 8 | pps_t
[31]);
1689 dsc_dec
->initial_offset
= (u32
) (pps_t
[32] << 8 | pps_t
[33]);
1690 dsc_dec
->final_offset
= (u32
) (pps_t
[34] << 8 | pps_t
[35]);
1691 dsc_dec
->rc_range_parameters
= (u32
) (pps_t
[58] << 8 | pps_t
[59]);
1694 u32
dsc_cmp_pps_enc_dec(struct decon_dsc
*p_enc
, struct decon_dsc
*p_dec
)
1698 if (p_enc
->comp_cfg
!= p_dec
->comp_cfg
) {
1700 decon_dbg("[dsc_pps] comp_cfg (enc:dec = %d:%d)\n",
1701 p_enc
->comp_cfg
, p_dec
->comp_cfg
);
1703 if (p_enc
->bit_per_pixel
!= p_dec
->bit_per_pixel
) {
1705 decon_dbg("[dsc_pps] bit_per_pixel (enc:dec = %d:%d)\n",
1706 p_enc
->bit_per_pixel
, p_dec
->bit_per_pixel
);
1708 if (p_enc
->pic_height
!= p_dec
->pic_height
) {
1710 decon_dbg("[dsc_pps] pic_height (enc:dec = %d:%d)\n",
1711 p_enc
->pic_height
, p_dec
->pic_height
);
1713 if (p_enc
->pic_width
!= p_dec
->pic_width
) {
1715 decon_dbg("[dsc_pps] pic_width (enc:dec = %d:%d)\n",
1716 p_enc
->pic_width
, p_dec
->pic_width
);
1718 if (p_enc
->slice_height
!= p_dec
->slice_height
) {
1720 decon_dbg("[dsc_pps] slice_height (enc:dec = %d:%d)\n",
1721 p_enc
->slice_height
, p_dec
->slice_height
);
1723 if (p_enc
->slice_width
!= p_dec
->slice_width
) {
1725 decon_dbg("[dsc_pps] slice_width (enc:dec = %d:%d)\n",
1726 p_enc
->slice_width
, p_dec
->slice_width
);
1728 if (p_enc
->chunk_size
!= p_dec
->chunk_size
) {
1730 decon_dbg("[dsc_pps] chunk_size (enc:dec = %d:%d)\n",
1731 p_enc
->chunk_size
, p_dec
->chunk_size
);
1733 if (p_enc
->initial_xmit_delay
!= p_dec
->initial_xmit_delay
) {
1735 decon_dbg("[dsc_pps] initial_xmit_delay (enc:dec = %d:%d)\n",
1736 p_enc
->initial_xmit_delay
, p_dec
->initial_xmit_delay
);
1738 if (p_enc
->initial_dec_delay
!= p_dec
->initial_dec_delay
) {
1740 decon_dbg("[dsc_pps] initial_dec_delay (enc:dec = %d:%d)\n",
1741 p_enc
->initial_dec_delay
, p_dec
->initial_dec_delay
);
1743 if (p_enc
->initial_scale_value
!= p_dec
->initial_scale_value
) {
1745 decon_dbg("[dsc_pps] initial_scale_value (enc:dec = %d:%d)\n",
1746 p_enc
->initial_scale_value
, p_dec
->initial_scale_value
);
1748 if (p_enc
->scale_increment_interval
!= p_dec
->scale_increment_interval
) {
1750 decon_dbg("[dsc_pps] scale_increment_interval (enc:dec = %d:%d)\n",
1751 p_enc
->scale_increment_interval
, p_dec
->scale_increment_interval
);
1753 if (p_enc
->scale_decrement_interval
!= p_dec
->scale_decrement_interval
) {
1755 decon_dbg("[dsc_pps] scale_decrement_interval (enc:dec = %d:%d)\n",
1756 p_enc
->scale_decrement_interval
, p_dec
->scale_decrement_interval
);
1758 if (p_enc
->first_line_bpg_offset
!= p_dec
->first_line_bpg_offset
) {
1760 decon_dbg("[dsc_pps] first_line_bpg_offset (enc:dec = %d:%d)\n",
1761 p_enc
->first_line_bpg_offset
, p_dec
->first_line_bpg_offset
);
1763 if (p_enc
->nfl_bpg_offset
!= p_dec
->nfl_bpg_offset
) {
1765 decon_dbg("[dsc_pps] nfl_bpg_offset (enc:dec = %d:%d)\n",
1766 p_enc
->nfl_bpg_offset
, p_dec
->nfl_bpg_offset
);
1768 if (p_enc
->slice_bpg_offset
!= p_dec
->slice_bpg_offset
) {
1770 decon_dbg("[dsc_pps] slice_bpg_offset (enc:dec = %d:%d)\n",
1771 p_enc
->slice_bpg_offset
, p_dec
->slice_bpg_offset
);
1773 if (p_enc
->initial_offset
!= p_dec
->initial_offset
) {
1775 decon_dbg("[dsc_pps] initial_offset (enc:dec = %d:%d)\n",
1776 p_enc
->initial_offset
, p_dec
->initial_offset
);
1778 if (p_enc
->final_offset
!= p_dec
->final_offset
) {
1780 decon_dbg("[dsc_pps] final_offset (enc:dec = %d:%d)\n",
1781 p_enc
->final_offset
, p_dec
->final_offset
);
1783 if (p_enc
->rc_range_parameters
!= p_dec
->rc_range_parameters
) {
1785 decon_dbg("[dsc_pps] rc_range_parameters (enc:dec = %d:%d)\n",
1786 p_enc
->rc_range_parameters
, p_dec
->rc_range_parameters
);
1789 decon_dbg("[dsc_pps] total different count : %d\n", diff_cnt
);
1794 void dsc_reg_set_partial_update(u32 dsc_id
, u32 dual_slice_en
,
1795 u32 slice_mode_ch
, u32 pic_h
)
1798 * Following SFRs must be considered
1800 * - slice_mode_change
1802 * - picture_width (don't care @KC) : decided by DSI (-> dual: /2)
1804 dsc_reg_set_dual_slice(dsc_id
, dual_slice_en
);
1805 dsc_reg_set_slice_mode_change(dsc_id
, slice_mode_ch
);
1806 dsc_reg_set_pps_06_07_picture_height(dsc_id
, pic_h
);
1810 * This table is only used to check DSC setting value when debugging
1811 * Copy or Replace table's data from current using LCD information
1812 * ( e.g. : SEQ_PPS_SLICE4 @ s6e3hf4_param.h )
1814 static const unsigned char DDI_PPS_INFO
[] = {
1815 0x11, 0x00, 0x00, 0x89, 0x30,
1816 0x80, 0x0A, 0x00, 0x05, 0xA0,
1817 0x00, 0x40, 0x01, 0x68, 0x01,
1818 0x68, 0x02, 0x00, 0x01, 0xB4,
1820 0x00, 0x20, 0x04, 0xF2, 0x00,
1821 0x05, 0x00, 0x0C, 0x01, 0x87,
1822 0x02, 0x63, 0x18, 0x00, 0x10,
1823 0xF0, 0x03, 0x0C, 0x20, 0x00,
1825 0x06, 0x0B, 0x0B, 0x33, 0x0E,
1826 0x1C, 0x2A, 0x38, 0x46, 0x54,
1827 0x62, 0x69, 0x70, 0x77, 0x79,
1828 0x7B, 0x7D, 0x7E, 0x01, 0x02,
1830 0x01, 0x00, 0x09, 0x40, 0x09,
1831 0xBE, 0x19, 0xFC, 0x19, 0xFA,
1832 0x19, 0xF8, 0x1A, 0x38, 0x1A,
1833 0x78, 0x1A, 0xB6, 0x2A, 0xF6,
1835 0x2B, 0x34, 0x2B, 0x74, 0x3B,
1836 0x74, 0x6B, 0xF4, 0x00, 0x00
1839 void dsc_reg_set_encoder(u32 id
, struct decon_param
*p
,
1840 struct decon_dsc
*dsc_enc
, u32 chk_en
)
1846 struct decon_lcd
*lcd_info
= p
->lcd_info
;
1847 /* DDI PPS table : for compare with ENC PPS value */
1848 struct decon_dsc dsc_dec
;
1849 /* set corresponding table like 'SEQ_PPS_SLICE4' */
1850 const unsigned char *pps_t
= DDI_PPS_INFO
;
1852 ds_en
= dsc_get_dual_slice_mode(lcd_info
);
1853 decon_dbg("dual slice(%d)\n", ds_en
);
1855 sm_ch
= dsc_get_slice_mode_change(lcd_info
);
1856 decon_dbg("slice mode change(%d)\n", sm_ch
);
1858 dscc_en
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DSCC_EN
);
1859 dsc_calc_pps_info(lcd_info
, dscc_en
, dsc_enc
);
1862 dsc_reg_config_control(DECON_DSC_ENC1
, ds_en
, sm_ch
);
1863 dsc_reg_set_pps(DECON_DSC_ENC1
, dsc_enc
);
1865 for (dsc_id
= 0; dsc_id
< lcd_info
->dsc_cnt
; dsc_id
++) {
1866 dsc_reg_config_control(dsc_id
, ds_en
, sm_ch
);
1867 dsc_reg_set_pps(dsc_id
, dsc_enc
);
1872 dsc_get_decoder_pps_info(&dsc_dec
, pps_t
);
1873 if (dsc_cmp_pps_enc_dec(dsc_enc
, &dsc_dec
))
1874 decon_dbg("[WARNING] Check PPS value!!\n");
1879 int dsc_reg_init(u32 id
, struct decon_param
*p
, u32 overlap_w
, u32 swrst
)
1882 struct decon_lcd
*lcd_info
= p
->lcd_info
;
1883 struct decon_dsc dsc_enc
;
1885 /* Basically, all SW-resets in DPU are not necessary ! */
1887 for (dsc_id
= 0; dsc_id
< lcd_info
->dsc_cnt
; dsc_id
++)
1888 dsc_reg_swreset(dsc_id
);
1891 dsc_enc
.overlap_w
= overlap_w
;
1892 dsc_reg_set_encoder(id
, p
, &dsc_enc
, 0);
1893 decon_reg_config_data_path_size(id
,
1894 dsc_enc
.width_per_enc
, lcd_info
->yres
, overlap_w
);
1896 /* To check SFR size configurations */
1897 decon_reg_print_data_path_size(id
);
1902 void decon_reg_configure_lcd(u32 id
, struct decon_param
*p
)
1906 * 1. available when DDI is supporting
1907 * 1. non-zero value is only valid at dual-DSI extension display
1908 * 2. default=0 : range=[0, 32] & (multiples of 2)
1911 enum decon_data_path d_path
= DPATH_DSCC_DSCENC01_FF01_FORMATTER0_DSIMIF0
;
1912 enum decon_enhance_path e_path
= ENHANCEPATH_ENHANCE_ALL_OFF
;
1913 enum decon_share_path aps_path
= SHAREPATH_DQE_USE
;
1914 enum decon_share_path hsc_path
= SHAREPATH_DQE_USE
;
1916 struct decon_lcd
*lcd_info
= p
->lcd_info
;
1917 struct decon_mode_info
*psr
= &p
->psr
;
1918 enum decon_dsi_mode dsi_mode
= psr
->dsi_mode
;
1919 enum decon_rgb_order rgb_order
= DECON_RGB
;
1921 if (lcd_info
->dsc_enabled
|| (id
== 2))
1922 rgb_order
= DECON_RGB
;
1924 rgb_order
= DECON_BGR
;
1925 decon_reg_set_rgb_order(id
, rgb_order
);
1926 decon_reg_set_dispif_porch(id
, lcd_info
);
1929 * Following setting sequence must be kept
1930 * 1. decon_reg_set_data_path
1931 * 2. decon_reg_config_data_path_size
1932 * --> because fn2 refer to SFR of fn1
1934 if (lcd_info
->dsc_enabled
) {
1935 if (lcd_info
->dsc_cnt
== 1)
1936 d_path
= DPATH_DSCENC0_FF0_FORMATTER0_DSIMIF0
;
1937 else if (lcd_info
->dsc_cnt
== 2)
1938 d_path
= DPATH_DSCC_DSCENC01_FF01_FORMATTER0_DSIMIF0
;
1940 decon_err("[decon%d] dsc_cnt=%d : not supported\n",
1941 id
, lcd_info
->dsc_cnt
);
1943 decon_reg_set_data_path(id
, d_path
, e_path
);
1945 dsc_reg_init(id
, p
, overlap_w
, 0);
1947 if (dsi_mode
== DSI_MODE_DUAL_DSI
)
1948 d_path
= DPATH_NOCOMP_SPLITTER_FF0FF1_FORMATTER01_DSIMIF01
;
1950 d_path
= DECON2_NOCOMP_FF0_FORMATTER0_DISPIF
;
1952 d_path
= DPATH_NOCOMP_FF0_FORMATTER0_DSIMIF0
;
1953 decon_reg_set_data_path(id
, d_path
, e_path
);
1955 decon_reg_config_data_path_size(id
,
1956 lcd_info
->xres
, lcd_info
->yres
, overlap_w
);
1958 decon_reg_set_dispif_size(id
, lcd_info
->xres
, lcd_info
->yres
);
1961 decon_reg_set_dqe_aps_path(id
, aps_path
);
1962 decon_reg_set_dqe_hsc_path(id
, hsc_path
);
1964 decon_reg_per_frame_off(id
);
1967 /***************** CAL APIs implementation *******************/
1968 static void decon_reg_init_probe(u32 id
, u32 dsi_idx
, struct decon_param
*p
)
1970 struct decon_lcd
*lcd_info
= p
->lcd_info
;
1971 struct decon_mode_info
*psr
= &p
->psr
;
1972 enum decon_data_path d_path
= DPATH_NOCOMP_FF0_FORMATTER0_DSIMIF0
;
1973 enum decon_enhance_path e_path
= ENHANCEPATH_ENHANCE_ALL_OFF
;
1974 u32 overlap_w
= 0; /* default=0 : range=[0, 32] & (multiples of 2) */
1975 enum decon_rgb_order rgb_order
= DECON_RGB
;
1977 if (lcd_info
->dsc_enabled
|| (id
== 2))
1978 rgb_order
= DECON_RGB
;
1980 rgb_order
= DECON_BGR
;
1982 decon_reg_set_clkgate_mode(id
, 1);
1984 decon_reg_set_sram_share(id
, DECON_FIFO_08K
);
1986 decon_reg_set_operation_mode(id
, psr
->psr_mode
);
1988 decon_reg_set_blender_bg_image_size(id
, psr
->dsi_mode
, lcd_info
);
1990 /* valid only for DECON2-DP */
1991 decon_reg_set_underrun_scheme(id
, DECON_VCLK_NOT_AFFECTED
);
1994 * same as decon_reg_configure_lcd(...) function
1995 * except using decon_reg_update_req_global(id)
1996 * instead of decon_reg_direct_on_off(id, 0)
1998 decon_reg_set_rgb_order(id
, rgb_order
);
1999 decon_reg_set_dispif_porch(id
, lcd_info
);
2001 if (lcd_info
->dsc_enabled
) {
2002 if (lcd_info
->dsc_cnt
== 1)
2003 d_path
= DPATH_DSCENC0_FF0_FORMATTER0_DSIMIF0
;
2004 else if (lcd_info
->dsc_cnt
== 2)
2005 d_path
= DPATH_DSCC_DSCENC01_FF01_FORMATTER0_DSIMIF0
;
2007 decon_err("[decon%d] dsc_cnt=%d : not supported\n",
2008 id
, lcd_info
->dsc_cnt
);
2010 decon_reg_set_data_path(id
, d_path
, e_path
);
2012 dsc_reg_init(id
, p
, overlap_w
, 0);
2014 if (psr
->dsi_mode
== DSI_MODE_DUAL_DSI
)
2015 d_path
= DPATH_NOCOMP_SPLITTER_FF0FF1_FORMATTER01_DSIMIF01
;
2017 d_path
= DPATH_NOCOMP_FF0_FORMATTER0_DSIMIF0
;
2018 decon_reg_set_data_path(id
, d_path
, e_path
);
2020 decon_reg_config_data_path_size(id
,
2021 lcd_info
->xres
, lcd_info
->yres
, overlap_w
);
2023 decon_reg_set_dispif_size(id
, lcd_info
->xres
, lcd_info
->yres
);
2026 decon_reg_get_data_path(id
, &d_path
, &e_path
);
2027 decon_dbg("%s: decon%d, enhance path(0x%x), data path(0x%x)\n",
2028 __func__
, id
, e_path
, d_path
);
2031 int decon_reg_init(u32 id
, u32 dsi_idx
, struct decon_param
*p
)
2033 struct decon_lcd
*lcd_info
= p
->lcd_info
;
2034 struct decon_mode_info
*psr
= &p
->psr
;
2035 enum decon_enhance_path e_path
= ENHANCEPATH_ENHANCE_ALL_OFF
;
2037 /* DECON does not need to start, if DECON is already
2038 * running(enabled in LCD_ON_UBOOT) */
2039 if (decon_reg_get_run_status(id
)) {
2040 decon_info("decon_reg_init already called by BOOTLOADER\n");
2041 decon_reg_init_probe(id
, dsi_idx
, p
);
2042 if (psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
)
2043 decon_reg_set_trigger(id
, psr
, DECON_TRIG_DISABLE
);
2047 dpu_sysreg_set_te_sel(id
, TE_FROM_GPIO
);
2049 //decon_reg_reset(id);
2051 decon_reg_set_clkgate_mode(id
, 1);
2053 decon_reg_set_sram_share(id
, DECON_FIFO_08K
);
2055 decon_reg_set_operation_mode(id
, psr
->psr_mode
);
2057 decon_reg_set_blender_bg_image_size(id
, psr
->dsi_mode
, lcd_info
);
2060 /* Set a TRIG mode */
2061 decon_reg_configure_trigger(id
, psr
->trig_mode
);
2064 * Interrupt of DECON-T should be set to video mode,
2065 * because of malfunction of I80 frame done interrupt.
2067 if (psr
->out_type
== DECON_OUT_WB
)
2068 psr
->psr_mode
= DECON_MIPI_COMMAND_MODE
;
2069 else if (psr
->out_type
== DECON_OUT_DP
)
2070 psr
->psr_mode
= DECON_VIDEO_MODE
;
2071 decon_reg_set_int(id
, psr
, 1);
2072 decon_reg_set_underrun_scheme(id
, DECON_VCLK_NOT_AFFECTED
);
2073 decon_reg_set_vclk_freerun(id
, 1);
2075 decon_reg_configure_lcd(id
, p
);
2077 decon_reg_configure_lcd(id
, p
);
2079 if (psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
) {
2080 decon_reg_set_trigger(id
, psr
, DECON_TRIG_DISABLE
);
2084 /* FIXME: DECON_T dedicated to PRE_WB */
2085 if (p
->psr
.out_type
== DECON_OUT_WB
)
2086 decon_reg_set_data_path(id
, DPATH_WBPRE_ONLY
, e_path
);
2088 /* asserted interrupt should be cleared before initializing decon hw */
2089 decon_reg_clear_int_all(id
);
2091 /* Configure DISP_SS : 'data_path' setting is required */
2092 decon_reg_set_disp_ss_cfg(id
, psr
);
2097 int decon_reg_start(u32 id
, struct decon_mode_info
*psr
)
2101 decon_reg_direct_on_off(id
, 1);
2102 decon_reg_update_req_global(id
);
2104 /* DECON goes to run-status as soon as request shadow update without HW_TE */
2105 ret
= decon_reg_wait_run_status_timeout(id
, 20 * 1000);
2107 /* wait until run-status, then trigger */
2108 if (psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
)
2109 decon_reg_set_trigger(id
, psr
, DECON_TRIG_ENABLE
);
2113 void decon_reg_set_partial_update(u32 id
, enum decon_dsi_mode dsi_mode
,
2114 struct decon_lcd
*lcd_info
, bool in_slice
[])
2116 u32 overlap_w
= 0; /* default=0 : range=[0, 32] & (multiples of 2) */
2117 u32 dual_slice_en
[2] = {1, 1};
2118 u32 slice_mode_ch
[2] = {0, 0};
2119 u32 width
= lcd_info
->xres
;
2122 u32 comp_slice_w
= 0;
2124 /* Here, lcd_info contains the size to be updated */
2125 decon_reg_set_blender_bg_image_size(id
, dsi_mode
, lcd_info
);
2126 decon_reg_set_dispif_porch(id
, lcd_info
);
2128 if (lcd_info
->dsc_enabled
) {
2129 /* for DECON SFR setting */
2130 ds_en
= dsc_get_dual_slice_mode(lcd_info
);
2131 dscc_en
= decon_reg_get_data_path_cfg(id
, PATH_CON_ID_DSCC_EN
);
2132 comp_slice_w
= dsc_get_compressed_slice_width(width
,
2135 /* get correct DSC configuration */
2136 dsc_get_partial_update_info(lcd_info
, in_slice
,
2137 dual_slice_en
, slice_mode_ch
);
2139 /* To support dual-display : DECON1 have to set DSC1 */
2140 dsc_reg_set_partial_update(id
, dual_slice_en
[0],
2141 slice_mode_ch
[0], lcd_info
->yres
);
2142 if (lcd_info
->dsc_cnt
== 2)
2143 dsc_reg_set_partial_update(1, dual_slice_en
[1],
2144 slice_mode_ch
[1], lcd_info
->yres
);
2146 /* for full width update */
2148 width
= comp_slice_w
* 2;
2150 width
= comp_slice_w
;
2153 decon_reg_config_data_path_size(id
, width
, lcd_info
->yres
, overlap_w
);
2154 decon_reg_set_dispif_size(id
, width
, lcd_info
->yres
);
2157 int decon_reg_stop_nreset(u32 id
, struct decon_mode_info
*psr
)
2161 if ((psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
) &&
2162 (psr
->trig_mode
== DECON_HW_TRIG
)) {
2163 decon_reg_set_trigger(id
, psr
, DECON_TRIG_DISABLE
);
2166 decon_reg_per_frame_off(id
);
2167 decon_reg_update_req_global(id
);
2169 /* timeout : 20ms */
2170 ret
= decon_reg_wait_run_is_off_timeout(id
, 20 * 1000);
2173 decon_err("decon_reg_stop_nreset failed!\n");
2181 int decon_reg_stop(u32 id
, u32 dsi_idx
, struct decon_mode_info
*psr
)
2184 //int ret1 = 0, ret2 = 0;
2185 int timeout_value
= 0;
2186 struct decon_device
*decon
= get_decon_drvdata(id
);
2188 if ((psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
) &&
2189 (psr
->trig_mode
== DECON_HW_TRIG
)) {
2190 decon_reg_set_trigger(id
, psr
, DECON_TRIG_DISABLE
);
2193 decon_reg_per_frame_off(id
);
2195 decon_reg_update_req_global(id
);
2197 if (id
!= 2 || psr
->out_type
!= DECON_OUT_DP
) {
2198 /* timeout : 20ms @ 60Hz */
2199 ret
= decon_reg_wait_run_is_off_timeout(id
, 20 * 1000);
2201 /* timeout : 1 / fps + 20% margin */
2202 timeout_value
= 1000 / decon
->lcd_info
->fps
* 12 / 10;
2203 ret
= decon_reg_wait_run_is_off_timeout(id
, timeout_value
* 1000);
2207 ret2
= decon_reg_reset(id
);
2215 void decon_reg_release_resource(u32 id
, struct decon_mode_info
*psr
)
2217 decon_reg_per_frame_off(id
);
2218 decon_reg_update_req_global(id
);
2219 decon_reg_set_trigger(id
, psr
, DECON_TRIG_ENABLE
);
2222 void decon_reg_clear_int_all(u32 id
)
2227 mask
= (DPU_MDNIE_DIMMING_END_INT_EN
2228 | DPU_MDNIE_DIMMING_START_INT_EN
2229 | DPU_DQE_DIMMING_END_INT_EN
2230 | DPU_DQE_DIMMING_START_INT_EN
2231 | DPU_FRAME_DONE_INT_EN
2232 | DPU_FRAME_START_INT_EN
2233 | DPU_FIFO_SEL_FIFO0
2234 | DPU_UNDER_FLOW_INT_EN
);
2236 mask
= (DPU_DISPIF_VSTATUS_INT_SEL_MASK
2237 | DPU_DISPIF_VSTATUS_INT_EN
2238 | DPU_FRAME_DONE_INT_EN
2239 | DPU_FRAME_START_INT_EN
2241 | DPU_UNDER_FLOW_INT_EN
);
2243 mask
|= DPU_EXTRA_INT_EN
;
2244 decon_write_mask(id
, INTERRUPT_PENDING
, ~0, mask
);
2246 mask
= (DPU_RESOURCE_CONFLICT_INT_EN
2247 | DPU_TIME_OUT_INT_EN
2248 | DPU_ERROR_INT_EN
);
2249 decon_write_mask(id
, EXTRA_INTERRUPT_PENDING
, ~0, mask
);
2252 void decon_reg_set_int(u32 id
, struct decon_mode_info
*psr
, u32 en
)
2256 decon_reg_clear_int_all(id
);
2259 val
= (DPU_DQE_DIMMING_END_INT_EN
2260 | DPU_DQE_DIMMING_START_INT_EN
2261 | DPU_FRAME_DONE_INT_EN
2262 | DPU_FRAME_START_INT_EN
2265 /* DPU_UNDER_FLOW_INT_EN : don't use when DSIM and WB-POST */
2266 if (psr
->psr_mode
== DECON_VIDEO_MODE
)
2267 val
|= DPU_UNDER_FLOW_INT_EN
;
2269 if (psr
->psr_mode
== DECON_VIDEO_MODE
&& psr
->out_type
== DECON_OUT_DP
) {
2270 val
= (DPU_FIFO_SEL_DISPIF
2271 | DPU_UNDER_FLOW_INT_EN
2272 | DPU_FRAME_DONE_INT_EN
2273 | DPU_DISPIF_VSTATUS_INT_EN
2274 | DPU_DISPIF_VSTATUS_INT_SEL(DPU_VERTICAL_VSYNC_START
)
2280 decon_write_mask(id
, INTERRUPT_ENABLE
, val
, INTERRUPT_ENABLE_MASK
);
2282 decon_write_mask(id
, INTERRUPT_ENABLE
, val
, INTERRUPT_ENABLE_MASK_DECON2
);
2284 decon_dbg("decon %d, interrupt val = %x\n", id
, val
);
2286 val
= (DPU_RESOURCE_CONFLICT_INT_EN
2287 | DPU_TIME_OUT_INT_EN
2288 | DPU_ERROR_INT_EN
);
2289 decon_write(id
, EXTRA_INTERRUPT_ENABLE
, val
);
2291 mask
= (DPU_EXTRA_INT_EN
| DPU_INT_EN
);
2292 decon_write_mask(id
, INTERRUPT_ENABLE
, 0, mask
);
2296 void decon_reg_set_win_enable(u32 id
, u32 win_idx
, u32 en
)
2301 mask
= WIN_EN_F(win_idx
);
2302 decon_write_mask(id
, DATA_PATH_CONTROL_0
, val
, mask
);
2306 * argb_color : 32-bit
2307 * A[31:24] - R[23:16] - G[15:8] - B[7:0]
2309 void decon_reg_set_win_mapcolor(u32 id
, u32 win_idx
, u32 argb_color
)
2312 u32 mc_alpha
= 0, mc_red
= 0;
2313 u32 mc_green
= 0, mc_blue
= 0;
2315 mc_alpha
= (argb_color
>> 24) & 0xFF;
2316 mc_red
= (argb_color
>> 16) & 0xFF;
2317 mc_green
= (argb_color
>> 8) & 0xFF;
2318 mc_blue
= (argb_color
>> 0) & 0xFF;
2320 val
= WIN_MAPCOLOR_A_F(mc_alpha
) | WIN_MAPCOLOR_R_F(mc_red
);
2321 mask
= WIN_MAPCOLOR_A_MASK
| WIN_MAPCOLOR_R_MASK
;
2322 decon_write_mask(id
, WIN_COLORMAP_0(win_idx
), val
, mask
);
2324 val
= WIN_MAPCOLOR_G_F(mc_green
) | WIN_MAPCOLOR_B_F(mc_blue
);
2325 mask
= WIN_MAPCOLOR_G_MASK
| WIN_MAPCOLOR_B_MASK
;
2326 decon_write_mask(id
, WIN_COLORMAP_1(win_idx
), val
, mask
);
2329 void decon_reg_set_winmap(u32 id
, u32 win_idx
, u32 color
, u32 en
)
2335 mask
= WIN_MAPCOLOR_EN_F(win_idx
);
2336 decon_write_mask(id
, DATA_PATH_CONTROL_0
, val
, mask
);
2339 decon_reg_set_win_mapcolor(0, win_idx
, color
);
2342 /* ALPHA_MULT selection used in (a',b',c',d') coefficient */
2343 void decon_reg_set_win_alpha_mult(u32 id
, u32 win_idx
, u32 a_sel
)
2347 val
= WIN_ALPHA_MULT_SRC_SEL_F(a_sel
);
2348 mask
= WIN_ALPHA_MULT_SRC_SEL_MASK
;
2349 decon_write_mask(id
, WIN_CONTROL_0(win_idx
), val
, mask
);
2352 void decon_reg_set_win_sub_coeff(u32 id
, u32 win_idx
,
2353 u32 fgd
, u32 bgd
, u32 fga
, u32 bga
)
2358 * [ Blending Equation ]
2359 * Color : Cr = (a x Cf) + (b x Cb) <Cf=FG pxl_C, Cb=BG pxl_C>
2360 * Alpha : Ar = (c x Af) + (d x Ab) <Af=FG pxl_A, Ab=BG pxl_A>
2363 * a' = WINx_FG_ALPHA_D_SEL : Af' that is multiplied by FG Pixel Color
2364 * b' = WINx_BG_ALPHA_D_SEL : Ab' that is multiplied by BG Pixel Color
2365 * c' = WINx_FG_ALPHA_A_SEL : Af' that is multiplied by FG Pixel Alpha
2366 * d' = WINx_BG_ALPHA_A_SEL : Ab' that is multiplied by BG Pixel Alpha
2369 val
= ( WIN_FG_ALPHA_D_SEL_F(fgd
)
2370 | WIN_BG_ALPHA_D_SEL_F(bgd
)
2371 | WIN_FG_ALPHA_A_SEL_F(fga
)
2372 | WIN_BG_ALPHA_A_SEL_F(bga
) );
2373 mask
= ( WIN_FG_ALPHA_D_SEL_MASK
2374 | WIN_BG_ALPHA_D_SEL_MASK
2375 | WIN_FG_ALPHA_A_SEL_MASK
2376 | WIN_BG_ALPHA_A_SEL_MASK
);
2377 decon_write_mask(id
, WIN_CONTROL_1(win_idx
), val
, mask
);
2380 void decon_reg_set_win_plane_alpha(u32 id
, u32 win_idx
, u32 a0
, u32 a1
)
2384 val
= WIN_ALPHA1_F(a1
) | WIN_ALPHA0_F(a0
);
2385 mask
= WIN_ALPHA1_MASK
| WIN_ALPHA0_MASK
;
2386 decon_write_mask(id
, WIN_CONTROL_0(win_idx
), val
, mask
);
2389 void decon_reg_get_win_plane_alpha(u32 id
, u32 win_idx
, u32
*a0
, u32
*a1
)
2393 val
= decon_read(id
, WIN_CONTROL_0(win_idx
));
2394 *a0
= WIN_ALPHA_GET(val
, 0);
2395 *a1
= WIN_ALPHA_GET(val
, 1);
2398 void decon_reg_set_win_func(u32 id
, u32 win_idx
, enum decon_win_func pd_func
)
2402 val
= WIN_FUNC_F(pd_func
);
2403 mask
= WIN_FUNC_MASK
;
2404 decon_write_mask(id
, WIN_CONTROL_0(win_idx
), val
, mask
);
2407 void decon_reg_set_win_bnd_function(u32 id
, u32 win_idx
,
2408 struct decon_window_regs
*regs
)
2410 int plane_a
= regs
->plane_alpha
;
2411 enum decon_blending blend
= regs
->blend
;
2412 enum decon_win_func pd_func
= PD_FUNC_USER_DEFINED
;
2415 bool is_plane_a
= false;
2416 u32 af_d
= BND_COEF_ONE
, ab_d
= BND_COEF_ZERO
,
2417 af_a
= BND_COEF_ONE
, ab_a
= BND_COEF_ZERO
;
2419 if (blend
== DECON_BLENDING_NONE
)
2420 pd_func
= PD_FUNC_COPY
;
2422 if ((plane_a
>= 0) && (plane_a
<= 0xff)) {
2428 if ((blend
== DECON_BLENDING_COVERAGE
) && !is_plane_a
) {
2430 ab_d
= BND_COEF_1_M_AF
;
2432 ab_a
= BND_COEF_1_M_AF
;
2433 } else if ((blend
== DECON_BLENDING_COVERAGE
) && is_plane_a
) {
2434 af_d
= BND_COEF_ALPHA_MULT
;
2435 ab_d
= BND_COEF_1_M_ALPHA_MULT
;
2436 af_a
= BND_COEF_ALPHA_MULT
;
2437 ab_a
= BND_COEF_1_M_ALPHA_MULT
;
2438 } else if ((blend
== DECON_BLENDING_PREMULT
) && !is_plane_a
) {
2439 af_d
= BND_COEF_ONE
;
2440 ab_d
= BND_COEF_1_M_AF
;
2441 af_a
= BND_COEF_ONE
;
2442 ab_a
= BND_COEF_1_M_AF
;
2443 } else if ((blend
== DECON_BLENDING_PREMULT
) && is_plane_a
) {
2444 af_d
= BND_COEF_PLNAE_ALPHA0
;
2445 ab_d
= BND_COEF_1_M_ALPHA_MULT
;
2446 af_a
= BND_COEF_PLNAE_ALPHA0
;
2447 ab_a
= BND_COEF_1_M_ALPHA_MULT
;
2448 } else if (blend
== DECON_BLENDING_NONE
) {
2449 decon_dbg("%s:%d none blending mode\n", __func__
, __LINE__
);
2451 decon_warn("%s:%d undefined blending mode\n", __func__
, __LINE__
);
2454 decon_reg_set_win_plane_alpha(id
, win_idx
, alpha0
, alpha1
);
2455 decon_reg_set_win_alpha_mult(id
, win_idx
, ALPHA_MULT_SRC_SEL_AF
);
2456 decon_reg_set_win_func(id
, win_idx
, pd_func
);
2457 if (pd_func
== PD_FUNC_USER_DEFINED
)
2458 decon_reg_set_win_sub_coeff(id
, win_idx
, af_d
, ab_d
, af_a
, ab_a
);
2461 void decon_reg_set_window_control(u32 id
, int win_idx
,
2462 struct decon_window_regs
*regs
, u32 winmap_en
)
2464 u32 win_en
= regs
->wincon
& WIN_EN_F(win_idx
) ? 1 : 0;
2467 decon_reg_set_win_bnd_function(0, win_idx
, regs
);
2468 decon_write(0, WIN_START_POSITION(win_idx
), regs
->start_pos
);
2469 decon_write(0, WIN_END_POSITION(win_idx
), regs
->end_pos
);
2470 decon_write(0, WIN_START_TIME_CONTROL(win_idx
), regs
->start_time
);
2471 decon_write(0, WIN_PIXEL_COUNT(win_idx
), regs
->pixel_count
);
2474 decon_reg_set_win_enable(id
, win_idx
, win_en
);
2476 decon_reg_set_winmap(id
, win_idx
, regs
->colormap
, winmap_en
);
2477 decon_reg_config_win_channel(id
, win_idx
, regs
->type
);
2479 decon_dbg("%s: regs->type(%d)\n", __func__
, regs
->type
);
2483 void decon_reg_update_req_and_unmask(u32 id
, struct decon_mode_info
*psr
)
2485 decon_reg_update_req_global(id
);
2487 if (psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
)
2488 decon_reg_set_trigger(id
, psr
, DECON_TRIG_ENABLE
);
2492 int decon_reg_wait_update_done_and_mask(u32 id
, struct decon_mode_info
*psr
, u32 timeout
)
2496 result
= decon_reg_wait_for_update_timeout(id
, timeout
);
2498 if (psr
->psr_mode
== DECON_MIPI_COMMAND_MODE
)
2499 decon_reg_set_trigger(id
, psr
, DECON_TRIG_DISABLE
);
2504 int decon_reg_get_interrupt_and_clear(u32 id
, u32
*ext_irq
)
2509 reg_id
= INTERRUPT_PENDING
;
2510 val
= decon_read(id
, reg_id
);
2512 if (val
& DPU_UNDER_FLOW_INT_PEND
)
2513 decon_write(id
, reg_id
, DPU_UNDER_FLOW_INT_PEND
);
2515 if (val
& DPU_DISPIF_VSTATUS_INT_PEND
)
2516 decon_write(id
, reg_id
, DPU_DISPIF_VSTATUS_INT_PEND
);
2518 if (val
& DPU_FRAME_START_INT_PEND
)
2519 decon_write(id
, reg_id
, DPU_FRAME_START_INT_PEND
);
2521 if (val
& DPU_FRAME_DONE_INT_PEND
)
2522 decon_write(id
, reg_id
, DPU_FRAME_DONE_INT_PEND
);
2524 if (val
& DPU_DQE_DIMMING_START_INT_PEND
)
2525 decon_write(id
, reg_id
, DPU_DQE_DIMMING_START_INT_PEND
);
2527 if (val
& DPU_DQE_DIMMING_END_INT_PEND
)
2528 decon_write(id
, reg_id
, DPU_DQE_DIMMING_END_INT_PEND
);
2530 if (val
& DPU_MDNIE_DIMMING_START_INT_PEND
)
2531 decon_write(id
, reg_id
, DPU_MDNIE_DIMMING_START_INT_PEND
);
2533 if (val
& DPU_MDNIE_DIMMING_END_INT_PEND
)
2534 decon_write(id
, reg_id
, DPU_MDNIE_DIMMING_END_INT_PEND
);
2536 if (val
& DPU_EXTRA_INT_PEND
) {
2537 decon_write(id
, reg_id
, DPU_EXTRA_INT_PEND
);
2539 reg_id
= EXTRA_INTERRUPT_PENDING
;
2540 val1
= decon_read(id
, reg_id
);
2543 if (val1
& DPU_RESOURCE_CONFLICT_INT_PEND
) {
2544 decon_write(id
, reg_id
, DPU_RESOURCE_CONFLICT_INT_PEND
);
2545 decon_warn("decon%d INFO0: SRAM_RSC= 0x%x\n",
2547 decon_read(id
, RESOURCE_OCCUPANCY_INFO_0
));
2548 decon_warn("decon%d INFO1: DMA_CH_RSC= 0x%x\n",
2550 decon_read(id
, RESOURCE_OCCUPANCY_INFO_1
));
2551 decon_warn("decon%d INFO2: WIN_RSC= 0x%x\n",
2553 decon_read(id
, RESOURCE_OCCUPANCY_INFO_2
));
2556 if (val1
& DPU_TIME_OUT_INT_PEND
)
2557 decon_write(id
, reg_id
, DPU_TIME_OUT_INT_PEND
);
2559 if (val1
& DPU_ERROR_INT_PEND
)
2560 decon_write(id
, reg_id
, DPU_ERROR_INT_PEND
);
2566 /****************** OS Only ******************/
2567 int decon_reg_is_win_enabled(u32 id
, int win_idx
)
2569 if (decon_read(id
, DATA_PATH_CONTROL_0
) & WIN_EN_F(win_idx
))
2575 u32
decon_reg_get_width(u32 id
, int dsi_mode
)
2579 val
= decon_read(id
, FORMATTER0_SIZE_CONTROL_0
);
2580 return (FORMATTER_WIDTH_GET(val
));
2583 u32
decon_reg_get_height(u32 id
, int dsi_mode
)
2587 val
= decon_read(id
, FORMATTER0_SIZE_CONTROL_0
);
2588 return (FORMATTER_HEIGHT_GET(val
));
2591 const unsigned long decon_clocks_table
[][CLK_ID_MAX
] = {
2592 /* VCLK, ECLK, ACLK, PCLK, DISP_PLL, resolution, MIC_ratio, DSC count */
2593 { 71, 168, 400, 66, 71, 1080 * 1920, MIC_COMP_BYPASS
, 0},
2594 { 63, 168, 400, 66, 63, 1440 * 2560, MIC_COMP_RATIO_1_2
, 0},
2595 { 41.7, 137.5, 400, 66, 62.5, 1440 * 2560, MIC_COMP_RATIO_1_3
, 0},
2596 { 141, 137.5, 400, 66, 141, 1440 * 2560, MIC_COMP_BYPASS
, 0},
2597 { 42, 337, 400, 66, 42, 1440 * 2560, MIC_COMP_BYPASS
, 1},
2598 { 42, 168, 400, 66, 42, 1440 * 2560, MIC_COMP_BYPASS
, 2},
2601 void decon_reg_get_clock_ratio(struct decon_clocks
*clks
, struct decon_lcd
*lcd_info
)
2603 int i
= sizeof(decon_clocks_table
) / sizeof(decon_clocks_table
[0]) - 1;
2605 /* set reset value */
2606 clks
->decon
[CLK_ID_VCLK
] = decon_clocks_table
[0][CLK_ID_VCLK
];
2607 clks
->decon
[CLK_ID_ECLK
] = decon_clocks_table
[0][CLK_ID_ECLK
];
2608 clks
->decon
[CLK_ID_ACLK
] = decon_clocks_table
[0][CLK_ID_ACLK
];
2609 clks
->decon
[CLK_ID_PCLK
] = decon_clocks_table
[0][CLK_ID_PCLK
];
2610 clks
->decon
[CLK_ID_DPLL
] = decon_clocks_table
[0][CLK_ID_DPLL
];
2612 for (; i
>= 0; i
--) {
2613 if (decon_clocks_table
[i
][CLK_ID_RESOLUTION
]
2614 != lcd_info
->xres
* lcd_info
->yres
) {
2618 if (!lcd_info
->mic_enabled
&& !lcd_info
->dsc_enabled
) {
2619 if (decon_clocks_table
[i
][CLK_ID_MIC_RATIO
]
2624 if (lcd_info
->mic_enabled
) {
2625 if (decon_clocks_table
[i
][CLK_ID_MIC_RATIO
]
2626 != lcd_info
->mic_ratio
)
2630 if (lcd_info
->dsc_enabled
) {
2631 if (decon_clocks_table
[i
][CLK_ID_DSC_RATIO
]
2632 != lcd_info
->dsc_cnt
)
2636 clks
->decon
[CLK_ID_VCLK
] = decon_clocks_table
[i
][CLK_ID_VCLK
];
2637 clks
->decon
[CLK_ID_ECLK
] = decon_clocks_table
[i
][CLK_ID_ECLK
];
2638 clks
->decon
[CLK_ID_ACLK
] = decon_clocks_table
[i
][CLK_ID_ACLK
];
2639 clks
->decon
[CLK_ID_PCLK
] = decon_clocks_table
[i
][CLK_ID_PCLK
];
2640 clks
->decon
[CLK_ID_DPLL
] = decon_clocks_table
[i
][CLK_ID_DPLL
];
2644 decon_dbg("%s: VCLK %ld ECLK %ld ACLK %ld PCLK %ld DPLL %ld\n",
2646 clks
->decon
[CLK_ID_VCLK
],
2647 clks
->decon
[CLK_ID_ECLK
],
2648 clks
->decon
[CLK_ID_ACLK
],
2649 clks
->decon
[CLK_ID_PCLK
],
2650 clks
->decon
[CLK_ID_DPLL
]);
2652 #ifdef CONFIG_SUPPORT_DSU
2653 void decon_set_dsu_update(u32 id
, enum decon_dsi_mode dsi_mode
,
2654 struct decon_param
*p
)
2658 enum decon_data_path d_path
= DPATH_DSCC_DSCENC01_FF01_FORMATTER0_DSIMIF0
;
2659 enum decon_rgb_order rgb
= DECON_RGB
;
2660 enum decon_enhance_path e_path
= ENHANCEPATH_ENHANCE_ALL_OFF
;
2661 struct decon_lcd
*lcd_info
= p
->lcd_info
;
2663 width
= lcd_info
->xres
;
2665 decon_reg_set_blender_bg_image_size(id
, dsi_mode
, lcd_info
);
2666 decon_reg_set_dispif_porch(id
, lcd_info
);
2668 if (lcd_info
->dsc_enabled
) {
2669 if (lcd_info
->dsc_cnt
== 1)
2670 d_path
= DPATH_DSCENC0_FF0_FORMATTER0_DSIMIF0
;
2671 else if (lcd_info
->dsc_cnt
== 2)
2672 d_path
= DPATH_DSCC_DSCENC01_FF01_FORMATTER0_DSIMIF0
;
2674 decon_err("[decon%d] dsc_cnt=%d : not supported\n",
2675 id
, lcd_info
->dsc_cnt
);
2676 decon_reg_set_data_path(id
, d_path
, e_path
);
2677 dsc_reg_init(id
, p
, overlap_w
, 0);
2681 if (dsi_mode
== DSI_MODE_DUAL_DSI
)
2682 d_path
= DPATH_NOCOMP_SPLITTER_FF0FF1_FORMATTER01_DSIMIF01
;
2684 d_path
= DECON2_NOCOMP_FF0_FORMATTER0_DISPIF
;
2686 d_path
= DPATH_NOCOMP_FF0_FORMATTER0_DSIMIF0
;
2688 decon_reg_set_data_path(id
, d_path
, e_path
);
2689 decon_reg_config_data_path_size(id
,
2690 lcd_info
->xres
, lcd_info
->yres
, overlap_w
);
2691 decon_reg_set_dispif_size(id
, lcd_info
->xres
, lcd_info
->yres
);
2694 decon_reg_set_rgb_order(id
, rgb
);
2695 //decon_reg_config_data_path_size(id, width, lcd_info->yres, overlap_w);
2696 //decon_reg_set_dispif_size(id, width, lcd_info->yres);