|
31 | 31 |
|
32 | 32 | #define DSI_RESET_TOGGLE_DELAY_MS 20
|
33 | 33 |
|
| 34 | +static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc); |
| 35 | + |
34 | 36 | static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
|
35 | 37 | {
|
36 | 38 | u32 ver;
|
@@ -157,6 +159,7 @@ struct msm_dsi_host {
|
157 | 159 | struct regmap *sfpb;
|
158 | 160 |
|
159 | 161 | struct drm_display_mode *mode;
|
| 162 | + struct msm_display_dsc_config *dsc; |
160 | 163 |
|
161 | 164 | /* connected device info */
|
162 | 165 | struct device_node *device_node;
|
@@ -1722,6 +1725,133 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host,
|
1722 | 1725 | return -EINVAL;
|
1723 | 1726 | }
|
1724 | 1727 |
|
| 1728 | +static u32 dsi_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = { |
| 1729 | + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, |
| 1730 | + 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e |
| 1731 | +}; |
| 1732 | + |
| 1733 | +/* only 8bpc, 8bpp added */ |
| 1734 | +static char min_qp[DSC_NUM_BUF_RANGES] = { |
| 1735 | + 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13 |
| 1736 | +}; |
| 1737 | + |
| 1738 | +static char max_qp[DSC_NUM_BUF_RANGES] = { |
| 1739 | + 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15 |
| 1740 | +}; |
| 1741 | + |
| 1742 | +static char bpg_offset[DSC_NUM_BUF_RANGES] = { |
| 1743 | + 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 |
| 1744 | +}; |
| 1745 | + |
| 1746 | +static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc) |
| 1747 | +{ |
| 1748 | + int mux_words_size; |
| 1749 | + int groups_per_line, groups_total; |
| 1750 | + int min_rate_buffer_size; |
| 1751 | + int hrd_delay; |
| 1752 | + int pre_num_extra_mux_bits, num_extra_mux_bits; |
| 1753 | + int slice_bits; |
| 1754 | + int target_bpp_x16; |
| 1755 | + int data; |
| 1756 | + int final_value, final_scale; |
| 1757 | + int i; |
| 1758 | + |
| 1759 | + dsc->drm->rc_model_size = 8192; |
| 1760 | + dsc->drm->first_line_bpg_offset = 12; |
| 1761 | + dsc->drm->rc_edge_factor = 6; |
| 1762 | + dsc->drm->rc_tgt_offset_high = 3; |
| 1763 | + dsc->drm->rc_tgt_offset_low = 3; |
| 1764 | + dsc->drm->simple_422 = 0; |
| 1765 | + dsc->drm->convert_rgb = 1; |
| 1766 | + dsc->drm->vbr_enable = 0; |
| 1767 | + |
| 1768 | + /* handle only bpp = bpc = 8 */ |
| 1769 | + for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) |
| 1770 | + dsc->drm->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i]; |
| 1771 | + |
| 1772 | + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { |
| 1773 | + dsc->drm->rc_range_params[i].range_min_qp = min_qp[i]; |
| 1774 | + dsc->drm->rc_range_params[i].range_max_qp = max_qp[i]; |
| 1775 | + dsc->drm->rc_range_params[i].range_bpg_offset = bpg_offset[i]; |
| 1776 | + } |
| 1777 | + |
| 1778 | + dsc->drm->initial_offset = 6144; /* Not bpp 12 */ |
| 1779 | + if (dsc->drm->bits_per_pixel != 8) |
| 1780 | + dsc->drm->initial_offset = 2048; /* bpp = 12 */ |
| 1781 | + |
| 1782 | + mux_words_size = 48; /* bpc == 8/10 */ |
| 1783 | + if (dsc->drm->bits_per_component == 12) |
| 1784 | + mux_words_size = 64; |
| 1785 | + |
| 1786 | + dsc->drm->initial_xmit_delay = 512; |
| 1787 | + dsc->drm->initial_scale_value = 32; |
| 1788 | + dsc->drm->first_line_bpg_offset = 12; |
| 1789 | + dsc->drm->line_buf_depth = dsc->drm->bits_per_component + 1; |
| 1790 | + |
| 1791 | + /* bpc 8 */ |
| 1792 | + dsc->drm->flatness_min_qp = 3; |
| 1793 | + dsc->drm->flatness_max_qp = 12; |
| 1794 | + dsc->drm->rc_quant_incr_limit0 = 11; |
| 1795 | + dsc->drm->rc_quant_incr_limit1 = 11; |
| 1796 | + dsc->drm->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; |
| 1797 | + |
| 1798 | + /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of |
| 1799 | + * params are calculated |
| 1800 | + */ |
| 1801 | + groups_per_line = DIV_ROUND_UP(dsc->drm->slice_width, 3); |
| 1802 | + dsc->drm->slice_chunk_size = dsc->drm->slice_width * dsc->drm->bits_per_pixel / 8; |
| 1803 | + if ((dsc->drm->slice_width * dsc->drm->bits_per_pixel) % 8) |
| 1804 | + dsc->drm->slice_chunk_size++; |
| 1805 | + |
| 1806 | + /* rbs-min */ |
| 1807 | + min_rate_buffer_size = dsc->drm->rc_model_size - dsc->drm->initial_offset + |
| 1808 | + dsc->drm->initial_xmit_delay * dsc->drm->bits_per_pixel + |
| 1809 | + groups_per_line * dsc->drm->first_line_bpg_offset; |
| 1810 | + |
| 1811 | + hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->drm->bits_per_pixel); |
| 1812 | + |
| 1813 | + dsc->drm->initial_dec_delay = hrd_delay - dsc->drm->initial_xmit_delay; |
| 1814 | + |
| 1815 | + dsc->drm->initial_scale_value = 8 * dsc->drm->rc_model_size / |
| 1816 | + (dsc->drm->rc_model_size - dsc->drm->initial_offset); |
| 1817 | + |
| 1818 | + slice_bits = 8 * dsc->drm->slice_chunk_size * dsc->drm->slice_height; |
| 1819 | + |
| 1820 | + groups_total = groups_per_line * dsc->drm->slice_height; |
| 1821 | + |
| 1822 | + data = dsc->drm->first_line_bpg_offset * 2048; |
| 1823 | + |
| 1824 | + dsc->drm->nfl_bpg_offset = DIV_ROUND_UP(data, (dsc->drm->slice_height - 1)); |
| 1825 | + |
| 1826 | + pre_num_extra_mux_bits = 3 * (mux_words_size + (4 * dsc->drm->bits_per_component + 4) - 2); |
| 1827 | + |
| 1828 | + num_extra_mux_bits = pre_num_extra_mux_bits - (mux_words_size - |
| 1829 | + ((slice_bits - pre_num_extra_mux_bits) % mux_words_size)); |
| 1830 | + |
| 1831 | + data = 2048 * (dsc->drm->rc_model_size - dsc->drm->initial_offset + num_extra_mux_bits); |
| 1832 | + dsc->drm->slice_bpg_offset = DIV_ROUND_UP(data, groups_total); |
| 1833 | + |
| 1834 | + /* bpp * 16 + 0.5 */ |
| 1835 | + data = dsc->drm->bits_per_pixel * 16; |
| 1836 | + data *= 2; |
| 1837 | + data++; |
| 1838 | + data /= 2; |
| 1839 | + target_bpp_x16 = data; |
| 1840 | + |
| 1841 | + data = (dsc->drm->initial_xmit_delay * target_bpp_x16) / 16; |
| 1842 | + final_value = dsc->drm->rc_model_size - data + num_extra_mux_bits; |
| 1843 | + dsc->drm->final_offset = final_value; |
| 1844 | + |
| 1845 | + final_scale = 8 * dsc->drm->rc_model_size / (dsc->drm->rc_model_size - final_value); |
| 1846 | + |
| 1847 | + data = (final_scale - 9) * (dsc->drm->nfl_bpg_offset + dsc->drm->slice_bpg_offset); |
| 1848 | + dsc->drm->scale_increment_interval = (2048 * dsc->drm->final_offset) / data; |
| 1849 | + |
| 1850 | + dsc->drm->scale_decrement_interval = groups_per_line / (dsc->drm->initial_scale_value - 8); |
| 1851 | + |
| 1852 | + return 0; |
| 1853 | +} |
| 1854 | + |
1725 | 1855 | static int dsi_host_parse_dt(struct msm_dsi_host *msm_host)
|
1726 | 1856 | {
|
1727 | 1857 | struct device *dev = &msm_host->pdev->dev;
|
|
0 commit comments