@@ -912,6 +912,65 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
912912 dsi_write (msm_host , REG_DSI_CPHY_MODE_CTRL , BIT (0 ));
913913}
914914
915+ static void dsi_update_dsc_timing (struct msm_dsi_host * msm_host , bool is_cmd_mode , u32 hdisplay )
916+ {
917+ struct msm_display_dsc_config * dsc = msm_host -> dsc ;
918+ u32 reg , intf_width , reg_ctrl , reg_ctrl2 ;
919+ u32 slice_per_intf , total_bytes_per_intf ;
920+ u32 pkt_per_line ;
921+ u32 bytes_in_slice ;
922+ u32 eol_byte_num ;
923+
924+ /* first calculate dsc parameters and then program
925+ * compress mode registers
926+ */
927+ intf_width = hdisplay ;
928+ slice_per_intf = DIV_ROUND_UP (intf_width , dsc -> drm -> slice_width );
929+
930+ /* If slice_per_pkt is greater than slice_per_intf
931+ * then default to 1. This can happen during partial
932+ * update.
933+ */
934+ if (slice_per_intf > dsc -> drm -> slice_count )
935+ dsc -> drm -> slice_count = 1 ;
936+
937+ slice_per_intf = DIV_ROUND_UP (hdisplay , dsc -> drm -> slice_width );
938+ bytes_in_slice = DIV_ROUND_UP (dsc -> drm -> slice_width * dsc -> drm -> bits_per_pixel , 8 );
939+
940+ dsc -> drm -> slice_chunk_size = bytes_in_slice ;
941+
942+ total_bytes_per_intf = bytes_in_slice * slice_per_intf ;
943+
944+ eol_byte_num = total_bytes_per_intf % 3 ;
945+ pkt_per_line = slice_per_intf / dsc -> drm -> slice_count ;
946+
947+ if (is_cmd_mode ) /* packet data type */
948+ reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE (MIPI_DSI_DCS_LONG_WRITE );
949+ else
950+ reg = DSI_VIDEO_COMPRESSION_MODE_CTRL_DATATYPE (MIPI_DSI_COMPRESSED_PIXEL_STREAM );
951+
952+ /* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
953+ * registers have similar offsets, so for below common code use
954+ * DSI_VIDEO_COMPRESSION_MODE_XXXX for setting bits
955+ */
956+ reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE (pkt_per_line >> 1 );
957+ reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM (eol_byte_num );
958+ reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EN ;
959+
960+ if (is_cmd_mode ) {
961+ reg_ctrl = dsi_read (msm_host , REG_DSI_COMMAND_COMPRESSION_MODE_CTRL );
962+ reg_ctrl2 = dsi_read (msm_host , REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 );
963+
964+ reg_ctrl |= reg ;
965+ reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH (bytes_in_slice );
966+
967+ dsi_write (msm_host , REG_DSI_COMMAND_COMPRESSION_MODE_CTRL , reg );
968+ dsi_write (msm_host , REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 , reg_ctrl2 );
969+ } else {
970+ dsi_write (msm_host , REG_DSI_VIDEO_COMPRESSION_MODE_CTRL , reg );
971+ }
972+ }
973+
915974static void dsi_timing_setup (struct msm_dsi_host * msm_host , bool is_bonded_dsi )
916975{
917976 struct drm_display_mode * mode = msm_host -> mode ;
@@ -944,7 +1003,38 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
9441003 hdisplay /= 2 ;
9451004 }
9461005
1006+ if (msm_host -> dsc ) {
1007+ struct msm_display_dsc_config * dsc = msm_host -> dsc ;
1008+
1009+ /* update dsc params with timing params */
1010+ if (!dsc || !mode -> hdisplay || !mode -> vdisplay ) {
1011+ pr_err ("DSI: invalid input: pic_width: %d pic_height: %d\n" ,
1012+ mode -> hdisplay , mode -> vdisplay );
1013+ return ;
1014+ }
1015+
1016+ dsc -> drm -> pic_width = mode -> hdisplay ;
1017+ dsc -> drm -> pic_height = mode -> vdisplay ;
1018+ DBG ("Mode %dx%d\n" , dsc -> drm -> pic_width , dsc -> drm -> pic_height );
1019+
1020+ /* we do the calculations for dsc parameters here so that
1021+ * panel can use these parameters
1022+ */
1023+ dsi_populate_dsc_params (dsc );
1024+
1025+ /* Divide the display by 3 but keep back/font porch and
1026+ * pulse width same
1027+ */
1028+ h_total -= hdisplay ;
1029+ hdisplay /= 3 ;
1030+ h_total += hdisplay ;
1031+ ha_end = ha_start + hdisplay ;
1032+ }
1033+
9471034 if (msm_host -> mode_flags & MIPI_DSI_MODE_VIDEO ) {
1035+ if (msm_host -> dsc )
1036+ dsi_update_dsc_timing (msm_host , false, mode -> hdisplay );
1037+
9481038 dsi_write (msm_host , REG_DSI_ACTIVE_H ,
9491039 DSI_ACTIVE_H_START (ha_start ) |
9501040 DSI_ACTIVE_H_END (ha_end ));
@@ -963,8 +1053,14 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
9631053 DSI_ACTIVE_VSYNC_VPOS_START (vs_start ) |
9641054 DSI_ACTIVE_VSYNC_VPOS_END (vs_end ));
9651055 } else { /* command mode */
1056+ if (msm_host -> dsc )
1057+ dsi_update_dsc_timing (msm_host , true, mode -> hdisplay );
1058+
9661059 /* image data and 1 byte write_memory_start cmd */
967- wc = hdisplay * dsi_get_bpp (msm_host -> format ) / 8 + 1 ;
1060+ if (!msm_host -> dsc )
1061+ wc = hdisplay * dsi_get_bpp (msm_host -> format ) / 8 + 1 ;
1062+ else
1063+ wc = mode -> hdisplay / 2 + 1 ;
9681064
9691065 dsi_write (msm_host , REG_DSI_CMD_MDP_STREAM0_CTRL ,
9701066 DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT (wc ) |
0 commit comments