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