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
61static 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
71static 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
87static 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
241static 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
346static 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
363static 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
372struct 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