Skip to content

Commit 08802f5

Browse files
vinodkoullumag
authored andcommitted
drm/msm/dsi: Add support for DSC configuration
When DSC is enabled, we need to configure DSI registers accordingly and configure the respective stream compression registers. Add support to calculate the register setting based on DSC params and timing information and configure these registers. Signed-off-by: Dmitry Baryshkov <[email protected]> Reviewed-by: Dmitry Baryshkov <[email protected]> Signed-off-by: Vinod Koul <[email protected]> Patchwork: https://patchwork.freedesktop.org/patch/480934/ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent 83527af commit 08802f5

File tree

1 file changed

+97
-1
lines changed

1 file changed

+97
-1
lines changed

drivers/gpu/drm/msm/dsi/dsi_host.c

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
915974
static 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

Comments
 (0)