1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
5  */
6 
7 #include <drm/display/drm_dsc_helper.h>
8 
9 #include "dpu_kms.h"
10 #include "dpu_hw_catalog.h"
11 #include "dpu_hwio.h"
12 #include "dpu_hw_mdss.h"
13 #include "dpu_hw_dsc.h"
14 
15 #define DSC_CMN_MAIN_CNF           0x00
16 
17 /* DPU_DSC_ENC register offsets */
18 #define ENC_DF_CTRL                0x00
19 #define ENC_GENERAL_STATUS         0x04
20 #define ENC_HSLICE_STATUS          0x08
21 #define ENC_OUT_STATUS             0x0C
22 #define ENC_INT_STAT               0x10
23 #define ENC_INT_CLR                0x14
24 #define ENC_INT_MASK               0x18
25 #define DSC_MAIN_CONF              0x30
26 #define DSC_PICTURE_SIZE           0x34
27 #define DSC_SLICE_SIZE             0x38
28 #define DSC_MISC_SIZE              0x3C
29 #define DSC_HRD_DELAYS             0x40
30 #define DSC_RC_SCALE               0x44
31 #define DSC_RC_SCALE_INC_DEC       0x48
32 #define DSC_RC_OFFSETS_1           0x4C
33 #define DSC_RC_OFFSETS_2           0x50
34 #define DSC_RC_OFFSETS_3           0x54
35 #define DSC_RC_OFFSETS_4           0x58
36 #define DSC_FLATNESS_QP            0x5C
37 #define DSC_RC_MODEL_SIZE          0x60
38 #define DSC_RC_CONFIG              0x64
39 #define DSC_RC_BUF_THRESH_0        0x68
40 #define DSC_RC_BUF_THRESH_1        0x6C
41 #define DSC_RC_BUF_THRESH_2        0x70
42 #define DSC_RC_BUF_THRESH_3        0x74
43 #define DSC_RC_MIN_QP_0            0x78
44 #define DSC_RC_MIN_QP_1            0x7C
45 #define DSC_RC_MIN_QP_2            0x80
46 #define DSC_RC_MAX_QP_0            0x84
47 #define DSC_RC_MAX_QP_1            0x88
48 #define DSC_RC_MAX_QP_2            0x8C
49 #define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
50 #define DSC_RC_RANGE_BPG_OFFSETS_1 0x94
51 #define DSC_RC_RANGE_BPG_OFFSETS_2 0x98
52 
53 /* DPU_DSC_CTL register offsets */
54 #define DSC_CTL                    0x00
55 #define DSC_CFG                    0x04
56 #define DSC_DATA_IN_SWAP           0x08
57 #define DSC_CLK_CTRL               0x0C
58 
_dsc_calc_output_buf_max_addr(struct dpu_hw_dsc * hw_dsc,int num_softslice)59 static int _dsc_calc_output_buf_max_addr(struct dpu_hw_dsc *hw_dsc, int num_softslice)
60 {
61 	int max_addr = 2400 / num_softslice;
62 
63 	if (hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_42x_EN))
64 		max_addr /= 2;
65 
66 	return max_addr - 1;
67 };
68 
dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc * hw_dsc)69 static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
70 {
71 	struct dpu_hw_blk_reg_map *hw;
72 	const struct dpu_dsc_sub_blks *sblk;
73 
74 	if (!hw_dsc)
75 		return;
76 
77 	hw = &hw_dsc->hw;
78 	sblk = hw_dsc->caps->sblk;
79 	DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CFG, 0);
80 
81 	DPU_REG_WRITE(hw, sblk->enc.base + ENC_DF_CTRL, 0);
82 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_MAIN_CONF, 0);
83 }
84 
dpu_hw_dsc_config_1_2(struct dpu_hw_dsc * hw_dsc,struct drm_dsc_config * dsc,u32 mode,u32 initial_lines)85 static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
86 				  struct drm_dsc_config *dsc,
87 				  u32 mode,
88 				  u32 initial_lines)
89 {
90 	struct dpu_hw_blk_reg_map *hw;
91 	const struct dpu_dsc_sub_blks *sblk;
92 	u32 data = 0;
93 	u32 det_thresh_flatness;
94 	u32 num_active_slice_per_enc;
95 	u32 bpp;
96 
97 	if (!hw_dsc || !dsc)
98 		return;
99 
100 	hw = &hw_dsc->hw;
101 
102 	sblk = hw_dsc->caps->sblk;
103 
104 	if (mode & DSC_MODE_SPLIT_PANEL)
105 		data |= BIT(0);
106 
107 	if (mode & DSC_MODE_MULTIPLEX)
108 		data |= BIT(1);
109 
110 	num_active_slice_per_enc = dsc->slice_count;
111 	if (mode & DSC_MODE_MULTIPLEX)
112 		num_active_slice_per_enc = dsc->slice_count / 2;
113 
114 	data |= (num_active_slice_per_enc & 0x3) << 7;
115 
116 	DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
117 
118 	data = (initial_lines & 0xff);
119 
120 	if (mode & DSC_MODE_VIDEO)
121 		data |= BIT(9);
122 
123 	data |= (_dsc_calc_output_buf_max_addr(hw_dsc, num_active_slice_per_enc) << 18);
124 
125 	DPU_REG_WRITE(hw, sblk->enc.base + ENC_DF_CTRL, data);
126 
127 	data = (dsc->dsc_version_minor & 0xf) << 28;
128 	if (dsc->dsc_version_minor == 0x2) {
129 		if (dsc->native_422)
130 			data |= BIT(22);
131 		if (dsc->native_420)
132 			data |= BIT(21);
133 	}
134 
135 	bpp = dsc->bits_per_pixel;
136 	/* as per hw requirement bpp should be programmed
137 	 * twice the actual value in case of 420 or 422 encoding
138 	 */
139 	if (dsc->native_422 || dsc->native_420)
140 		bpp = 2 * bpp;
141 
142 	data |= bpp << 10;
143 
144 	if (dsc->block_pred_enable)
145 		data |= BIT(20);
146 
147 	if (dsc->convert_rgb)
148 		data |= BIT(4);
149 
150 	data |= (dsc->line_buf_depth & 0xf) << 6;
151 	data |= dsc->bits_per_component & 0xf;
152 
153 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_MAIN_CONF, data);
154 
155 	data = (dsc->pic_width & 0xffff) |
156 		((dsc->pic_height & 0xffff) << 16);
157 
158 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_PICTURE_SIZE, data);
159 
160 	data = (dsc->slice_width & 0xffff) |
161 		((dsc->slice_height & 0xffff) << 16);
162 
163 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_SLICE_SIZE, data);
164 
165 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_MISC_SIZE,
166 		      (dsc->slice_chunk_size) & 0xffff);
167 
168 	data = (dsc->initial_xmit_delay & 0xffff) |
169 		((dsc->initial_dec_delay & 0xffff) << 16);
170 
171 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_HRD_DELAYS, data);
172 
173 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_SCALE,
174 		      dsc->initial_scale_value & 0x3f);
175 
176 	data = (dsc->scale_increment_interval & 0xffff) |
177 		((dsc->scale_decrement_interval & 0x7ff) << 16);
178 
179 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_SCALE_INC_DEC, data);
180 
181 	data = (dsc->first_line_bpg_offset & 0x1f) |
182 		((dsc->second_line_bpg_offset & 0x1f) << 5);
183 
184 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_1, data);
185 
186 	data = (dsc->nfl_bpg_offset & 0xffff) |
187 		((dsc->slice_bpg_offset & 0xffff) << 16);
188 
189 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_2, data);
190 
191 	data = (dsc->initial_offset & 0xffff) |
192 		((dsc->final_offset & 0xffff) << 16);
193 
194 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_3, data);
195 
196 	data = (dsc->nsl_bpg_offset & 0xffff) |
197 		((dsc->second_line_offset_adj & 0xffff) << 16);
198 
199 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_4, data);
200 
201 	det_thresh_flatness = drm_dsc_flatness_det_thresh(dsc);
202 	data = (dsc->flatness_min_qp & 0x1f) |
203 		((dsc->flatness_max_qp & 0x1f) << 5) |
204 		((det_thresh_flatness & 0xff) << 10);
205 
206 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_FLATNESS_QP, data);
207 
208 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MODEL_SIZE,
209 		      (dsc->rc_model_size) & 0xffff);
210 
211 	data = dsc->rc_edge_factor & 0xf;
212 	data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
213 	data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
214 	data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
215 	data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
216 
217 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_CONFIG, data);
218 
219 	/* program the dsc wrapper */
220 	data = BIT(0); /* encoder enable */
221 	if (dsc->native_422)
222 		data |= BIT(8);
223 	else if (dsc->native_420)
224 		data |= BIT(9);
225 	if (!dsc->convert_rgb)
226 		data |= BIT(10);
227 	if (dsc->bits_per_component == 8)
228 		data |= BIT(11);
229 	if (mode & DSC_MODE_SPLIT_PANEL)
230 		data |= BIT(12);
231 	if (mode & DSC_MODE_MULTIPLEX)
232 		data |= BIT(13);
233 	if (!(mode & DSC_MODE_VIDEO))
234 		data |= BIT(17);
235 
236 	DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CFG, data);
237 }
238 
dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc * hw_dsc,struct drm_dsc_config * dsc)239 static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
240 					 struct drm_dsc_config *dsc)
241 {
242 	struct dpu_hw_blk_reg_map *hw;
243 	const struct dpu_dsc_sub_blks *sblk;
244 	struct drm_dsc_rc_range_parameters *rc;
245 
246 	if (!hw_dsc || !dsc)
247 		return;
248 
249 	hw = &hw_dsc->hw;
250 
251 	sblk = hw_dsc->caps->sblk;
252 
253 	rc = dsc->rc_range_params;
254 
255 	/*
256 	 * With BUF_THRESH -- 14 in total
257 	 * each register contains 4 thresh values with the last register
258 	 * containing only 2 thresh values
259 	 */
260 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_0,
261 		      (dsc->rc_buf_thresh[0] << 0) |
262 		      (dsc->rc_buf_thresh[1] << 8) |
263 		      (dsc->rc_buf_thresh[2] << 16) |
264 		      (dsc->rc_buf_thresh[3] << 24));
265 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_1,
266 		      (dsc->rc_buf_thresh[4] << 0) |
267 		      (dsc->rc_buf_thresh[5] << 8) |
268 		      (dsc->rc_buf_thresh[6] << 16) |
269 		      (dsc->rc_buf_thresh[7] << 24));
270 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_2,
271 		      (dsc->rc_buf_thresh[8] << 0) |
272 		      (dsc->rc_buf_thresh[9] << 8) |
273 		      (dsc->rc_buf_thresh[10] << 16) |
274 		      (dsc->rc_buf_thresh[11] << 24));
275 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_3,
276 		      (dsc->rc_buf_thresh[12] << 0) |
277 		      (dsc->rc_buf_thresh[13] << 8));
278 
279 	/*
280 	 * with min/max_QP -- 5 bits
281 	 * each register contains 5 min_qp or max_qp for total of 15
282 	 *
283 	 * With BPG_OFFSET -- 6 bits
284 	 * each register contains 5 BPG_offset for total of 15
285 	 */
286 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_0,
287 		      (rc[0].range_min_qp << 0) |
288 		      (rc[1].range_min_qp << 5) |
289 		      (rc[2].range_min_qp << 10) |
290 		      (rc[3].range_min_qp << 15) |
291 		      (rc[4].range_min_qp << 20));
292 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_0,
293 		      (rc[0].range_max_qp << 0) |
294 		      (rc[1].range_max_qp << 5) |
295 		      (rc[2].range_max_qp << 10) |
296 		      (rc[3].range_max_qp << 15) |
297 		      (rc[4].range_max_qp << 20));
298 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_0,
299 		      (rc[0].range_bpg_offset << 0) |
300 		      (rc[1].range_bpg_offset << 6) |
301 		      (rc[2].range_bpg_offset << 12) |
302 		      (rc[3].range_bpg_offset << 18) |
303 		      (rc[4].range_bpg_offset << 24));
304 
305 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_1,
306 		      (rc[5].range_min_qp << 0) |
307 		      (rc[6].range_min_qp << 5) |
308 		      (rc[7].range_min_qp << 10) |
309 		      (rc[8].range_min_qp << 15) |
310 		      (rc[9].range_min_qp << 20));
311 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_1,
312 		      (rc[5].range_max_qp << 0) |
313 		      (rc[6].range_max_qp << 5) |
314 		      (rc[7].range_max_qp << 10) |
315 		      (rc[8].range_max_qp << 15) |
316 		      (rc[9].range_max_qp << 20));
317 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_1,
318 		      (rc[5].range_bpg_offset << 0) |
319 		      (rc[6].range_bpg_offset << 6) |
320 		      (rc[7].range_bpg_offset << 12) |
321 		      (rc[8].range_bpg_offset << 18) |
322 		      (rc[9].range_bpg_offset << 24));
323 
324 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_2,
325 		      (rc[10].range_min_qp << 0) |
326 		      (rc[11].range_min_qp << 5) |
327 		      (rc[12].range_min_qp << 10) |
328 		      (rc[13].range_min_qp << 15) |
329 		      (rc[14].range_min_qp << 20));
330 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_2,
331 		      (rc[10].range_max_qp << 0) |
332 		      (rc[11].range_max_qp << 5) |
333 		      (rc[12].range_max_qp << 10) |
334 		      (rc[13].range_max_qp << 15) |
335 		      (rc[14].range_max_qp << 20));
336 	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_2,
337 		      (rc[10].range_bpg_offset << 0) |
338 		      (rc[11].range_bpg_offset << 6) |
339 		      (rc[12].range_bpg_offset << 12) |
340 		      (rc[13].range_bpg_offset << 18) |
341 		      (rc[14].range_bpg_offset << 24));
342 }
343 
dpu_hw_dsc_bind_pingpong_blk_1_2(struct dpu_hw_dsc * hw_dsc,const enum dpu_pingpong pp)344 static void dpu_hw_dsc_bind_pingpong_blk_1_2(struct dpu_hw_dsc *hw_dsc,
345 					     const enum dpu_pingpong pp)
346 {
347 	struct dpu_hw_blk_reg_map *hw;
348 	const struct dpu_dsc_sub_blks *sblk;
349 	int mux_cfg = 0xf; /* Disabled */
350 
351 	hw = &hw_dsc->hw;
352 
353 	sblk = hw_dsc->caps->sblk;
354 
355 	if (pp)
356 		mux_cfg = (pp - PINGPONG_0) & 0x7;
357 
358 	DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CTL, mux_cfg);
359 }
360 
_setup_dcs_ops_1_2(struct dpu_hw_dsc_ops * ops,const unsigned long features)361 static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
362 			       const unsigned long features)
363 {
364 	ops->dsc_disable = dpu_hw_dsc_disable_1_2;
365 	ops->dsc_config = dpu_hw_dsc_config_1_2;
366 	ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
367 	ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
368 }
369 
dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg * cfg,void __iomem * addr)370 struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
371 				       void __iomem *addr)
372 {
373 	struct dpu_hw_dsc *c;
374 
375 	c = kzalloc(sizeof(*c), GFP_KERNEL);
376 	if (!c)
377 		return ERR_PTR(-ENOMEM);
378 
379 	c->hw.blk_addr = addr + cfg->base;
380 	c->hw.log_mask = DPU_DBG_MASK_DSC;
381 
382 	c->idx = cfg->id;
383 	c->caps = cfg;
384 	_setup_dcs_ops_1_2(&c->ops, c->caps->features);
385 
386 	return c;
387 }
388