diff options
author | Vinod Koul <vkoul@kernel.org> | 2020-01-28 19:52:10 +0530 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2020-01-28 19:52:10 +0530 |
commit | a63578693f35150b01b82df10efc70e591f3628f (patch) | |
tree | 5c953eaca363b566a3de390e9d84a880654b9bc4 | |
parent | d37bc367754eed277bbc40f131b7f30688d62918 (diff) |
drm/msm/dsi: configure dsc registers
DSC configuration registers need to be programmed in video mode and
command mode, add support for that
Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi.xml.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi_host.c | 84 |
2 files changed, 92 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 21f489a737d7..18fc5198d22b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -1726,5 +1726,13 @@ static inline uint32_t REG_DSI_10nm_PHY_LN_TX_DCTRL(uint32_t i0) { return 0x0000 #define REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE 0x000001a0 +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL 0x000002a0 +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL2 0x000002a4 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL 0x000002a8 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 0x000002ac + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL3 0x000002b0 #endif /* DSI_XML */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index feedbe713835..444358c83b3c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -984,6 +984,59 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_dual_dsi) } if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { + if (msm_host->is_dsc_enabled) { + struct msm_dsc_config *dsc = msm_host->dsc_config; + u32 reg, intf_width, slice_per_intf, width; + u32 bytes_in_slice, total_bytes_per_intf, bytes_per_pkt; + u32 eol_byte_num, pclk_per_line, slice_per_pkt, pkt_per_line; + + /* first calculate dsc parameters and then program + * compress mode registers + */ + intf_width = hdisplay; + slice_per_intf = DIV_ROUND_UP(intf_width, dsc->slice_width); + + /* If slice_per_pkt > slice_per_intf, then use 1 + * This can happen during partial update + */ + slice_per_pkt = dsc->slice_per_pkt; + if (slice_per_pkt > slice_per_intf) + slice_per_pkt = 1; + + bytes_in_slice = DIV_ROUND_UP( + dsc->slice_width * + dsi_get_bpp(msm_host->format), 8); + total_bytes_per_intf = bytes_in_slice * slice_per_intf; + + eol_byte_num = total_bytes_per_intf % 3; + pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3); + bytes_per_pkt = bytes_in_slice * slice_per_pkt; + pkt_per_line = slice_per_intf / slice_per_pkt; + + reg = mode->clock << 16; + reg |= (0x0b << 8); /* dtype of compressed image */ + + width = pclk_per_line; + reg = bytes_per_pkt << 16; + reg |= (0x0b << 8); /* dtype of compressed image */ + + /* pkt_per_line: + * 0 == 1 pkt + * 1 == 2 pkt + * 2 == 4 pkt + * 3 pkt is not supported + * above translates to ffs() - 1 + */ + reg = (ffs(pkt_per_line) - 1) << 6; + + eol_byte_num = total_bytes_per_intf % 3; + reg |= eol_byte_num << 4; + reg |= 1; + + dsi_write(msm_host, + REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg); + } + dsi_write(msm_host, REG_DSI_ACTIVE_H, DSI_ACTIVE_H_START(ha_start) | DSI_ACTIVE_H_END(ha_end)); @@ -1002,6 +1055,37 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_dual_dsi) DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); } else { /* command mode */ + if (msm_host->is_dsc_enabled) { + struct msm_dsc_config *dsc = msm_host->dsc_config; + u32 reg, reg_ctrl, reg_ctrl2; + u32 slice_per_intf, bytes_in_slice, total_bytes_per_intf; + u32 pkt_per_line, eol_byte_num; + + reg_ctrl = dsi_read(msm_host, + REG_DSI_COMMAND_COMPRESSION_MODE_CTRL); + reg_ctrl2 = dsi_read( + msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2); + + slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width); + bytes_in_slice = DIV_ROUND_UP( + dsc->slice_width * + dsi_get_bpp(msm_host->format), 8); + total_bytes_per_intf = bytes_in_slice * slice_per_intf; + pkt_per_line = slice_per_intf / dsc->slice_per_pkt; + reg = 0x39 << 8; + reg = (ffs(pkt_per_line) - 1) << 6; + + eol_byte_num = total_bytes_per_intf % 3; + reg |= eol_byte_num << 4; + reg |= 1; + + reg_ctrl |= reg; + reg_ctrl2 |= bytes_in_slice; + + dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl); + dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2); + } + /* image data and 1 byte write_memory_start cmd */ wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; |