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