File Index
Files and directories
Sign in
FILE

rkvdec-hevc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Rockchip Video Decoder HEVC backend
  4 *
  5 * Copyright (C) 2023 Collabora, Ltd.
  6 *      Sebastian Fricke <sebastian.fricke@collabora.com>
  7 *
  8 * Copyright (C) 2019 Collabora, Ltd.
  9 *	Boris Brezillon <boris.brezillon@collabora.com>
 10 *
 11 * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
 12 *	Jeffy Chen <jeffy.chen@rock-chips.com>
 13 */
 14
 15#include <media/v4l2-mem2mem.h>
 16
 17#include "rkvdec.h"
 18#include "rkvdec-regs.h"
 19#include "rkvdec-hevc-data.c"
 20
 21/* Size in u8/u32 units. */
 22#define RKV_SCALING_LIST_SIZE		1360
 23#define RKV_PPS_SIZE			(80 / 4)
 24#define RKV_PPS_LEN			64
 25#define RKV_RPS_SIZE			(32 / 4)
 26#define RKV_RPS_LEN			600
 27
 28struct rkvdec_sps_pps_packet {
 29	u32 info[RKV_PPS_SIZE];
 30};
 31
 32struct rkvdec_rps_packet {
 33	u32 info[RKV_RPS_SIZE];
 34};
 35
 36struct rkvdec_ps_field {
 37	u16 offset;
 38	u8 len;
 39};
 40
 41#define PS_FIELD(_offset, _len) \
 42	((struct rkvdec_ps_field){ _offset, _len })
 43
 44/* SPS */
 45#define VIDEO_PARAMETER_SET_ID				PS_FIELD(0, 4)
 46#define SEQ_PARAMETER_SET_ID				PS_FIELD(4, 4)
 47#define CHROMA_FORMAT_IDC				PS_FIELD(8, 2)
 48#define PIC_WIDTH_IN_LUMA_SAMPLES			PS_FIELD(10, 13)
 49#define PIC_HEIGHT_IN_LUMA_SAMPLES			PS_FIELD(23, 13)
 50#define BIT_DEPTH_LUMA					PS_FIELD(36, 4)
 51#define BIT_DEPTH_CHROMA				PS_FIELD(40, 4)
 52#define LOG2_MAX_PIC_ORDER_CNT_LSB			PS_FIELD(44, 5)
 53#define LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE	PS_FIELD(49, 2)
 54#define LOG2_MIN_LUMA_CODING_BLOCK_SIZE			PS_FIELD(51, 3)
 55#define LOG2_MIN_TRANSFORM_BLOCK_SIZE			PS_FIELD(54, 3)
 56#define LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE	PS_FIELD(57, 2)
 57#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTER		PS_FIELD(59, 3)
 58#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA		PS_FIELD(62, 3)
 59#define SCALING_LIST_ENABLED_FLAG			PS_FIELD(65, 1)
 60#define AMP_ENABLED_FLAG				PS_FIELD(66, 1)
 61#define SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG		PS_FIELD(67, 1)
 62#define PCM_ENABLED_FLAG				PS_FIELD(68, 1)
 63#define PCM_SAMPLE_BIT_DEPTH_LUMA			PS_FIELD(69, 4)
 64#define PCM_SAMPLE_BIT_DEPTH_CHROMA			PS_FIELD(73, 4)
 65#define PCM_LOOP_FILTER_DISABLED_FLAG			PS_FIELD(77, 1)
 66#define LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE	PS_FIELD(78, 3)
 67#define LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE		PS_FIELD(81, 3)
 68#define NUM_SHORT_TERM_REF_PIC_SETS			PS_FIELD(84, 7)
 69#define LONG_TERM_REF_PICS_PRESENT_FLAG			PS_FIELD(91, 1)
 70#define NUM_LONG_TERM_REF_PICS_SPS			PS_FIELD(92, 6)
 71#define SPS_TEMPORAL_MVP_ENABLED_FLAG			PS_FIELD(98, 1)
 72#define STRONG_INTRA_SMOOTHING_ENABLED_FLAG		PS_FIELD(99, 1)
 73/* PPS */
 74#define PIC_PARAMETER_SET_ID				PS_FIELD(128, 6)
 75#define PPS_SEQ_PARAMETER_SET_ID			PS_FIELD(134, 4)
 76#define DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG		PS_FIELD(138, 1)
 77#define OUTPUT_FLAG_PRESENT_FLAG			PS_FIELD(139, 1)
 78#define NUM_EXTRA_SLICE_HEADER_BITS			PS_FIELD(140, 13)
 79#define SIGN_DATA_HIDING_ENABLED_FLAG			PS_FIELD(153, 1)
 80#define CABAC_INIT_PRESENT_FLAG				PS_FIELD(154, 1)
 81#define NUM_REF_IDX_L0_DEFAULT_ACTIVE			PS_FIELD(155, 4)
 82#define NUM_REF_IDX_L1_DEFAULT_ACTIVE			PS_FIELD(159, 4)
 83#define INIT_QP_MINUS26					PS_FIELD(163, 7)
 84#define CONSTRAINED_INTRA_PRED_FLAG			PS_FIELD(170, 1)
 85#define TRANSFORM_SKIP_ENABLED_FLAG			PS_FIELD(171, 1)
 86#define CU_QP_DELTA_ENABLED_FLAG			PS_FIELD(172, 1)
 87#define LOG2_MIN_CU_QP_DELTA_SIZE			PS_FIELD(173, 3)
 88#define PPS_CB_QP_OFFSET				PS_FIELD(176, 5)
 89#define PPS_CR_QP_OFFSET				PS_FIELD(181, 5)
 90#define PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG	PS_FIELD(186, 1)
 91#define WEIGHTED_PRED_FLAG				PS_FIELD(187, 1)
 92#define WEIGHTED_BIPRED_FLAG				PS_FIELD(188, 1)
 93#define TRANSQUANT_BYPASS_ENABLED_FLAG			PS_FIELD(189, 1)
 94#define TILES_ENABLED_FLAG				PS_FIELD(190, 1)
 95#define ENTROPY_CODING_SYNC_ENABLED_FLAG		PS_FIELD(191, 1)
 96#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG	PS_FIELD(192, 1)
 97#define LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG		PS_FIELD(193, 1)
 98#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG		PS_FIELD(194, 1)
 99#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG		PS_FIELD(195, 1)
100#define PPS_BETA_OFFSET_DIV2				PS_FIELD(196, 4)
101#define PPS_TC_OFFSET_DIV2				PS_FIELD(200, 4)
102#define LISTS_MODIFICATION_PRESENT_FLAG			PS_FIELD(204, 1)
103#define LOG2_PARALLEL_MERGE_LEVEL			PS_FIELD(205, 3)
104#define SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG	PS_FIELD(208, 1)
105#define NUM_TILE_COLUMNS				PS_FIELD(212, 5)
106#define NUM_TILE_ROWS					PS_FIELD(217, 5)
107#define COLUMN_WIDTH(i)					PS_FIELD(256 + ((i) * 8), 8)
108#define ROW_HEIGHT(i)					PS_FIELD(416 + ((i) * 8), 8)
109#define SCALING_LIST_ADDRESS				PS_FIELD(592, 32)
110
111/* Data structure describing auxiliary buffer format. */
112struct rkvdec_hevc_priv_tbl {
113	u8 cabac_table[RKV_CABAC_TABLE_SIZE];
114	u8 scaling_list[RKV_SCALING_LIST_SIZE];
115	struct rkvdec_sps_pps_packet param_set[RKV_PPS_LEN];
116	struct rkvdec_rps_packet rps[RKV_RPS_LEN];
117};
118
119struct rkvdec_hevc_run {
120	struct rkvdec_run base;
121	const struct v4l2_ctrl_hevc_slice_params *slices_params;
122	const struct v4l2_ctrl_hevc_decode_params *decode_params;
123	const struct v4l2_ctrl_hevc_sps *sps;
124	const struct v4l2_ctrl_hevc_pps *pps;
125	const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix;
126	int num_slices;
127};
128
129struct rkvdec_hevc_ctx {
130	struct rkvdec_aux_buf priv_tbl;
131	struct v4l2_ctrl_hevc_scaling_matrix scaling_matrix_cache;
132};
133
134struct scaling_factor {
135	u8 scalingfactor0[1248];
136	u8 scalingfactor1[96];		/*4X4 TU Rotate, total 16X4*/
137	u8 scalingdc[12];		/*N1005 Vienna Meeting*/
138	u8 reserved[4];		/*16Bytes align*/
139};
140
141static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value)
142{
143	u8 bit = field.offset % 32, word = field.offset / 32;
144	u64 mask = GENMASK_ULL(bit + field.len - 1, bit);
145	u64 val = ((u64)value << bit) & mask;
146
147	buf[word] &= ~mask;
148	buf[word] |= val;
149	if (bit + field.len > 32) {
150		buf[word + 1] &= ~(mask >> 32);
151		buf[word + 1] |= val >> 32;
152	}
153}
154
155static void assemble_hw_pps(struct rkvdec_ctx *ctx,
156			    struct rkvdec_hevc_run *run)
157{
158	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
159	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
160	const struct v4l2_ctrl_hevc_pps *pps = run->pps;
161	struct rkvdec_hevc_priv_tbl *priv_tbl = hevc_ctx->priv_tbl.cpu;
162	struct rkvdec_sps_pps_packet *hw_ps;
163	u32 min_cb_log2_size_y, ctb_log2_size_y, ctb_size_y;
164	u32 log2_min_cu_qp_delta_size, scaling_distance;
165	dma_addr_t scaling_list_address;
166	int i;
167
168	/*
169	 * HW read the SPS/PPS information from PPS packet index by PPS id.
170	 * offset from the base can be calculated by PPS_id * 80 (size per PPS
171	 * packet unit). so the driver copy SPS/PPS information to the exact PPS
172	 * packet unit for HW accessing.
173	 */
174	hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
175	memset(hw_ps, 0, sizeof(*hw_ps));
176
177#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value)
178	/* write sps */
179	WRITE_PPS(sps->video_parameter_set_id, VIDEO_PARAMETER_SET_ID);
180	WRITE_PPS(sps->seq_parameter_set_id, SEQ_PARAMETER_SET_ID);
181	WRITE_PPS(sps->chroma_format_idc, CHROMA_FORMAT_IDC);
182	WRITE_PPS(sps->pic_width_in_luma_samples, PIC_WIDTH_IN_LUMA_SAMPLES);
183	WRITE_PPS(sps->pic_height_in_luma_samples, PIC_HEIGHT_IN_LUMA_SAMPLES);
184	WRITE_PPS(sps->bit_depth_luma_minus8 + 8, BIT_DEPTH_LUMA);
185	WRITE_PPS(sps->bit_depth_chroma_minus8 + 8, BIT_DEPTH_CHROMA);
186	WRITE_PPS(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
187		  LOG2_MAX_PIC_ORDER_CNT_LSB);
188	WRITE_PPS(sps->log2_diff_max_min_luma_coding_block_size,
189		  LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE);
190	WRITE_PPS(sps->log2_min_luma_coding_block_size_minus3 + 3,
191		  LOG2_MIN_LUMA_CODING_BLOCK_SIZE);
192	WRITE_PPS(sps->log2_min_luma_transform_block_size_minus2 + 2,
193		  LOG2_MIN_TRANSFORM_BLOCK_SIZE);
194	WRITE_PPS(sps->log2_diff_max_min_luma_transform_block_size,
195		  LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE);
196	WRITE_PPS(sps->max_transform_hierarchy_depth_inter,
197		  MAX_TRANSFORM_HIERARCHY_DEPTH_INTER);
198	WRITE_PPS(sps->max_transform_hierarchy_depth_intra,
199		  MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA);
200	WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED),
201		  SCALING_LIST_ENABLED_FLAG);
202	WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED),
203		  AMP_ENABLED_FLAG);
204	WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET),
205		  SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG);
206	if (sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED) {
207		WRITE_PPS(1, PCM_ENABLED_FLAG);
208		WRITE_PPS(sps->pcm_sample_bit_depth_luma_minus1 + 1,
209			  PCM_SAMPLE_BIT_DEPTH_LUMA);
210		WRITE_PPS(sps->pcm_sample_bit_depth_chroma_minus1 + 1,
211			  PCM_SAMPLE_BIT_DEPTH_CHROMA);
212		WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED),
213			  PCM_LOOP_FILTER_DISABLED_FLAG);
214		WRITE_PPS(sps->log2_diff_max_min_pcm_luma_coding_block_size,
215			  LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE);
216		WRITE_PPS(sps->log2_min_pcm_luma_coding_block_size_minus3 + 3,
217			  LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE);
218	}
219	WRITE_PPS(sps->num_short_term_ref_pic_sets, NUM_SHORT_TERM_REF_PIC_SETS);
220	WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT),
221		  LONG_TERM_REF_PICS_PRESENT_FLAG);
222	WRITE_PPS(sps->num_long_term_ref_pics_sps, NUM_LONG_TERM_REF_PICS_SPS);
223	WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED),
224		  SPS_TEMPORAL_MVP_ENABLED_FLAG);
225	WRITE_PPS(!!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED),
226		  STRONG_INTRA_SMOOTHING_ENABLED_FLAG);
227
228	/* write pps */
229	WRITE_PPS(pps->pic_parameter_set_id, PIC_PARAMETER_SET_ID);
230	WRITE_PPS(sps->seq_parameter_set_id, PPS_SEQ_PARAMETER_SET_ID);
231	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED),
232		  DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG);
233	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT),
234		  OUTPUT_FLAG_PRESENT_FLAG);
235	WRITE_PPS(pps->num_extra_slice_header_bits, NUM_EXTRA_SLICE_HEADER_BITS);
236	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED),
237		  SIGN_DATA_HIDING_ENABLED_FLAG);
238	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT),
239		  CABAC_INIT_PRESENT_FLAG);
240	WRITE_PPS(pps->num_ref_idx_l0_default_active_minus1 + 1,
241		  NUM_REF_IDX_L0_DEFAULT_ACTIVE);
242	WRITE_PPS(pps->num_ref_idx_l1_default_active_minus1 + 1,
243		  NUM_REF_IDX_L1_DEFAULT_ACTIVE);
244	WRITE_PPS(pps->init_qp_minus26, INIT_QP_MINUS26);
245	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED),
246		  CONSTRAINED_INTRA_PRED_FLAG);
247	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED),
248		  TRANSFORM_SKIP_ENABLED_FLAG);
249	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED),
250		  CU_QP_DELTA_ENABLED_FLAG);
251
252	min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3;
253	ctb_log2_size_y = min_cb_log2_size_y +
254		sps->log2_diff_max_min_luma_coding_block_size;
255	ctb_size_y = 1 << ctb_log2_size_y;
256	log2_min_cu_qp_delta_size = ctb_log2_size_y - pps->diff_cu_qp_delta_depth;
257	WRITE_PPS(log2_min_cu_qp_delta_size, LOG2_MIN_CU_QP_DELTA_SIZE);
258	WRITE_PPS(pps->pps_cb_qp_offset, PPS_CB_QP_OFFSET);
259	WRITE_PPS(pps->pps_cr_qp_offset, PPS_CR_QP_OFFSET);
260	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT),
261		  PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG);
262	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED),
263		  WEIGHTED_PRED_FLAG);
264	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED),
265		  WEIGHTED_BIPRED_FLAG);
266	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED),
267		  TRANSQUANT_BYPASS_ENABLED_FLAG);
268	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED),
269		  TILES_ENABLED_FLAG);
270	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED),
271		  ENTROPY_CODING_SYNC_ENABLED_FLAG);
272	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED),
273		  PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG);
274	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED),
275		  LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG);
276	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED),
277		  DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG);
278	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER),
279		  PPS_DEBLOCKING_FILTER_DISABLED_FLAG);
280	WRITE_PPS(pps->pps_beta_offset_div2, PPS_BETA_OFFSET_DIV2);
281	WRITE_PPS(pps->pps_tc_offset_div2, PPS_TC_OFFSET_DIV2);
282	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT),
283		  LISTS_MODIFICATION_PRESENT_FLAG);
284	WRITE_PPS(pps->log2_parallel_merge_level_minus2 + 2, LOG2_PARALLEL_MERGE_LEVEL);
285	WRITE_PPS(!!(pps->flags & V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT),
286		  SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG);
287	WRITE_PPS(pps->num_tile_columns_minus1 + 1, NUM_TILE_COLUMNS);
288	WRITE_PPS(pps->num_tile_rows_minus1 + 1, NUM_TILE_ROWS);
289
290	if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) {
291		/* Userspace also provide column width and row height for uniform spacing */
292		for (i = 0; i <= pps->num_tile_columns_minus1; i++)
293			WRITE_PPS(pps->column_width_minus1[i], COLUMN_WIDTH(i));
294		for (i = 0; i <= pps->num_tile_rows_minus1; i++)
295			WRITE_PPS(pps->row_height_minus1[i], ROW_HEIGHT(i));
296	} else {
297		WRITE_PPS(((sps->pic_width_in_luma_samples + ctb_size_y - 1) / ctb_size_y) - 1,
298			  COLUMN_WIDTH(0));
299		WRITE_PPS(((sps->pic_height_in_luma_samples + ctb_size_y - 1) / ctb_size_y) - 1,
300			  ROW_HEIGHT(0));
301	}
302
303	scaling_distance = offsetof(struct rkvdec_hevc_priv_tbl, scaling_list);
304	scaling_list_address = hevc_ctx->priv_tbl.dma + scaling_distance;
305	WRITE_PPS(scaling_list_address, SCALING_LIST_ADDRESS);
306}
307
308/*
309 * Creation of the Reference Picture Set memory blob for the hardware.
310 * The layout looks like this:
311 * [0] 32 bits for L0 (6 references + 2 bits of the 7th reference)
312 * [1] 32 bits for L0 (remaining 3 bits of the 7th reference + 5 references
313 *     + 4 bits of the 13th reference)
314 * [2] 11 bits for L0 (remaining bit for 13 and 2 references) and
315 *     21 bits for L1 (4 references + first bit of 5)
316 * [3] 32 bits of padding with 0s
317 * [4] 32 bits for L1 (remaining 4 bits for 5 + 5 references + 3 bits of 11)
318 * [5] 22 bits for L1 (remaining 2 bits of 11 and 4 references)
319 *     lowdelay flag (bit 23), rps bit offset long term (bit 24 - 32)
320 * [6] rps bit offset long term (bit 1 - 3),  rps bit offset short term (bit 4 - 12)
321 *     number of references (bit 13 - 16), remaining 16 bits of padding with 0s
322 * [7] 32 bits of padding with 0s
323 *
324 * Thus we have to set up padding in between reference 5 of the L1 list.
325 */
326static void assemble_sw_rps(struct rkvdec_ctx *ctx,
327			    struct rkvdec_hevc_run *run)
328{
329	const struct v4l2_ctrl_hevc_decode_params *decode_params = run->decode_params;
330	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
331	const struct v4l2_ctrl_hevc_slice_params *sl_params;
332	const struct v4l2_hevc_dpb_entry *dpb;
333	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
334	struct rkvdec_hevc_priv_tbl *priv_tbl = hevc_ctx->priv_tbl.cpu;
335	struct rkvdec_rps_packet *hw_ps;
336	int i, j;
337	unsigned int lowdelay;
338
339#define WRITE_RPS(value, field) set_ps_field(hw_ps->info, field, value)
340
341#define REF_PIC_LONG_TERM_L0(i)			PS_FIELD((i) * 5, 1)
342#define REF_PIC_IDX_L0(i)			PS_FIELD(1 + ((i) * 5), 4)
343#define REF_PIC_LONG_TERM_L1(i)			PS_FIELD(((i) < 5 ? 75 : 132) + ((i) * 5), 1)
344#define REF_PIC_IDX_L1(i)			PS_FIELD(((i) < 4 ? 76 : 128) + ((i) * 5), 4)
345
346#define LOWDELAY				PS_FIELD(182, 1)
347#define LONG_TERM_RPS_BIT_OFFSET		PS_FIELD(183, 10)
348#define SHORT_TERM_RPS_BIT_OFFSET		PS_FIELD(193, 9)
349#define NUM_RPS_POC				PS_FIELD(202, 4)
350
351	for (j = 0; j < run->num_slices; j++) {
352		uint st_bit_offset = 0;
353		uint num_l0_refs = 0;
354		uint num_l1_refs = 0;
355
356		sl_params = &run->slices_params[j];
357		dpb = decode_params->dpb;
358
359		if (sl_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
360			num_l0_refs = sl_params->num_ref_idx_l0_active_minus1 + 1;
361
362			if (sl_params->slice_type == V4L2_HEVC_SLICE_TYPE_B)
363				num_l1_refs = sl_params->num_ref_idx_l1_active_minus1 + 1;
364
365			lowdelay = 1;
366		} else {
367			lowdelay = 0;
368		}
369
370		hw_ps = &priv_tbl->rps[j];
371		memset(hw_ps, 0, sizeof(*hw_ps));
372
373		for (i = 0; i < num_l0_refs; i++) {
374			const struct v4l2_hevc_dpb_entry dpb_l0 = dpb[sl_params->ref_idx_l0[i]];
375
376			WRITE_RPS(!!(dpb_l0.flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE),
377				  REF_PIC_LONG_TERM_L0(i));
378			WRITE_RPS(sl_params->ref_idx_l0[i], REF_PIC_IDX_L0(i));
379
380			if (dpb_l0.pic_order_cnt_val > sl_params->slice_pic_order_cnt)
381				lowdelay = 0;
382		}
383
384		for (i = 0; i < num_l1_refs; i++) {
385			const struct v4l2_hevc_dpb_entry dpb_l1 = dpb[sl_params->ref_idx_l1[i]];
386			int is_long_term =
387				!!(dpb_l1.flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE);
388
389			WRITE_RPS(is_long_term, REF_PIC_LONG_TERM_L1(i));
390			WRITE_RPS(sl_params->ref_idx_l1[i], REF_PIC_IDX_L1(i));
391
392			if (dpb_l1.pic_order_cnt_val > sl_params->slice_pic_order_cnt)
393				lowdelay = 0;
394		}
395
396		WRITE_RPS(lowdelay, LOWDELAY);
397
398		if (!(decode_params->flags & V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC)) {
399			if (sl_params->short_term_ref_pic_set_size)
400				st_bit_offset = sl_params->short_term_ref_pic_set_size;
401			else if (sps->num_short_term_ref_pic_sets > 1)
402				st_bit_offset = fls(sps->num_short_term_ref_pic_sets - 1);
403		}
404
405		WRITE_RPS(st_bit_offset + sl_params->long_term_ref_pic_set_size,
406			  LONG_TERM_RPS_BIT_OFFSET);
407		WRITE_RPS(sl_params->short_term_ref_pic_set_size,
408			  SHORT_TERM_RPS_BIT_OFFSET);
409
410		WRITE_RPS(decode_params->num_poc_st_curr_before +
411			  decode_params->num_poc_st_curr_after +
412			  decode_params->num_poc_lt_curr,
413			  NUM_RPS_POC);
414	}
415}
416
417/*
418 * Flip one or more matrices along their main diagonal and flatten them
419 * before writing it to the memory.
420 * Convert:
421 * ABCD         AEIM
422 * EFGH     =>  BFJN     =>     AEIMBFJNCGKODHLP
423 * IJKL         CGKO
424 * MNOP         DHLP
425 */
426static void transpose_and_flatten_matrices(u8 *output, const u8 *input,
427					   int matrices, int row_length)
428{
429	int i, j, row, x_offset, matrix_offset, rot_index, y_offset, matrix_size, new_value;
430
431	matrix_size = row_length * row_length;
432	for (i = 0; i < matrices; i++) {
433		row = 0;
434		x_offset = 0;
435		matrix_offset = i * matrix_size;
436		for (j = 0; j < matrix_size; j++) {
437			y_offset = j - (row * row_length);
438			rot_index = y_offset * row_length + x_offset;
439			new_value = *(input + i * matrix_size + j);
440			output[matrix_offset + rot_index] = new_value;
441			if ((j + 1) % row_length == 0) {
442				row += 1;
443				x_offset += 1;
444			}
445		}
446	}
447}
448
449static void assemble_scalingfactor0(u8 *output, const struct v4l2_ctrl_hevc_scaling_matrix *input)
450{
451	int offset = 0;
452
453	transpose_and_flatten_matrices(output, (const u8 *)input->scaling_list_4x4, 6, 4);
454	offset = 6 * 16 * sizeof(u8);
455	transpose_and_flatten_matrices(output + offset, (const u8 *)input->scaling_list_8x8, 6, 8);
456	offset += 6 * 64 * sizeof(u8);
457	transpose_and_flatten_matrices(output + offset,
458				       (const u8 *)input->scaling_list_16x16, 6, 8);
459	offset += 6 * 64 * sizeof(u8);
460	/* Add a 128 byte padding with 0s between the two 32x32 matrices */
461	transpose_and_flatten_matrices(output + offset,
462				       (const u8 *)input->scaling_list_32x32, 1, 8);
463	offset += 64 * sizeof(u8);
464	memset(output + offset, 0, 128);
465	offset += 128 * sizeof(u8);
466	transpose_and_flatten_matrices(output + offset,
467				       (const u8 *)input->scaling_list_32x32 + (64 * sizeof(u8)),
468				       1, 8);
469	offset += 64 * sizeof(u8);
470	memset(output + offset, 0, 128);
471}
472
473/*
474 * Required layout:
475 * A = scaling_list_dc_coef_16x16
476 * B = scaling_list_dc_coef_32x32
477 * 0 = Padding
478 *
479 * A, A, A, A, A, A, B, 0, 0, B, 0, 0
480 */
481static void assemble_scalingdc(u8 *output, const struct v4l2_ctrl_hevc_scaling_matrix *input)
482{
483	u8 list_32x32[6] = {0};
484
485	memcpy(output, input->scaling_list_dc_coef_16x16, 6 * sizeof(u8));
486	list_32x32[0] = input->scaling_list_dc_coef_32x32[0];
487	list_32x32[3] = input->scaling_list_dc_coef_32x32[1];
488	memcpy(output + 6 * sizeof(u8), list_32x32, 6 * sizeof(u8));
489}
490
491static void translate_scaling_list(struct scaling_factor *output,
492				   const struct v4l2_ctrl_hevc_scaling_matrix *input)
493{
494	assemble_scalingfactor0(output->scalingfactor0, input);
495	memcpy(output->scalingfactor1, (const u8 *)input->scaling_list_4x4, 96);
496	assemble_scalingdc(output->scalingdc, input);
497	memset(output->reserved, 0, 4 * sizeof(u8));
498}
499
500static void assemble_hw_scaling_list(struct rkvdec_ctx *ctx,
501				     struct rkvdec_hevc_run *run)
502{
503	const struct v4l2_ctrl_hevc_scaling_matrix *scaling = run->scaling_matrix;
504	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
505	struct rkvdec_hevc_priv_tbl *tbl = hevc_ctx->priv_tbl.cpu;
506	u8 *dst;
507
508	if (!memcmp((void *)&hevc_ctx->scaling_matrix_cache, scaling,
509		    sizeof(struct v4l2_ctrl_hevc_scaling_matrix)))
510		return;
511
512	dst = tbl->scaling_list;
513	translate_scaling_list((struct scaling_factor *)dst, scaling);
514
515	memcpy((void *)&hevc_ctx->scaling_matrix_cache, scaling,
516	       sizeof(struct v4l2_ctrl_hevc_scaling_matrix));
517}
518
519static struct vb2_buffer *
520get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_hevc_run *run,
521	    unsigned int dpb_idx)
522{
523	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
524	const struct v4l2_ctrl_hevc_decode_params *decode_params = run->decode_params;
525	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
526	struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
527	struct vb2_buffer *buf = NULL;
528
529	if (dpb_idx < decode_params->num_active_dpb_entries)
530		buf = vb2_find_buffer(cap_q, dpb[dpb_idx].timestamp);
531
532	/*
533	 * If a DPB entry is unused or invalid, the address of current destination
534	 * buffer is returned.
535	 */
536	if (!buf)
537		return &run->base.bufs.dst->vb2_buf;
538
539	return buf;
540}
541
542static void config_registers(struct rkvdec_ctx *ctx,
543			     struct rkvdec_hevc_run *run)
544{
545	struct rkvdec_dev *rkvdec = ctx->dev;
546	const struct v4l2_ctrl_hevc_decode_params *decode_params = run->decode_params;
547	const struct v4l2_ctrl_hevc_sps *sps = run->sps;
548	const struct v4l2_ctrl_hevc_slice_params *sl_params = &run->slices_params[0];
549	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
550	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
551	dma_addr_t priv_start_addr = hevc_ctx->priv_tbl.dma;
552	const struct v4l2_pix_format_mplane *dst_fmt;
553	struct vb2_v4l2_buffer *src_buf = run->base.bufs.src;
554	struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst;
555	const struct v4l2_format *f;
556	dma_addr_t rlc_addr;
557	dma_addr_t refer_addr;
558	u32 rlc_len;
559	u32 hor_virstride;
560	u32 ver_virstride;
561	u32 y_virstride;
562	u32 yuv_virstride = 0;
563	u32 offset;
564	dma_addr_t dst_addr;
565	u32 reg, i;
566
567	reg = RKVDEC_MODE(RKVDEC_MODE_HEVC);
568	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_SYSCTRL);
569
570	f = &ctx->decoded_fmt;
571	dst_fmt = &f->fmt.pix_mp;
572	hor_virstride = dst_fmt->plane_fmt[0].bytesperline;
573	ver_virstride = dst_fmt->height;
574	y_virstride = hor_virstride * ver_virstride;
575
576	if (sps->chroma_format_idc == 0)
577		yuv_virstride = y_virstride;
578	else if (sps->chroma_format_idc == 1)
579		yuv_virstride = y_virstride + y_virstride / 2;
580	else if (sps->chroma_format_idc == 2)
581		yuv_virstride = 2 * y_virstride;
582
583	reg = RKVDEC_Y_HOR_VIRSTRIDE(hor_virstride / 16) |
584	      RKVDEC_UV_HOR_VIRSTRIDE(hor_virstride / 16) |
585	      RKVDEC_SLICE_NUM_LOWBITS(run->num_slices);
586	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_PICPAR);
587
588	/* config rlc base address */
589	rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
590	writel_relaxed(rlc_addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
591
592	rlc_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
593	reg = RKVDEC_STRM_LEN(round_up(rlc_len, 16) + 64);
594	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_STRM_LEN);
595
596	/* config cabac table */
597	offset = offsetof(struct rkvdec_hevc_priv_tbl, cabac_table);
598	writel_relaxed(priv_start_addr + offset,
599		       rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
600
601	/* config output base address */
602	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
603	writel_relaxed(dst_addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
604
605	reg = RKVDEC_Y_VIRSTRIDE(y_virstride / 16);
606	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
607
608	reg = RKVDEC_YUV_VIRSTRIDE(yuv_virstride / 16);
609	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
610
611	/* config ref pic address */
612	for (i = 0; i < 15; i++) {
613		struct vb2_buffer *vb_buf = get_ref_buf(ctx, run, i);
614
615		if (i < 4 && decode_params->num_active_dpb_entries) {
616			reg = GENMASK(decode_params->num_active_dpb_entries - 1, 0);
617			reg = (reg >> (i * 4)) & 0xf;
618		} else {
619			reg = 0;
620		}
621
622		refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0);
623		writel_relaxed(refer_addr | reg,
624			       rkvdec->regs + RKVDEC_REG_H264_BASE_REFER(i));
625
626		reg = RKVDEC_POC_REFER(i < decode_params->num_active_dpb_entries ?
627			dpb[i].pic_order_cnt_val : 0);
628		writel_relaxed(reg,
629			       rkvdec->regs + RKVDEC_REG_H264_POC_REFER0(i));
630	}
631
632	reg = RKVDEC_CUR_POC(sl_params->slice_pic_order_cnt);
633	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_CUR_POC0);
634
635	/* config hw pps address */
636	offset = offsetof(struct rkvdec_hevc_priv_tbl, param_set);
637	writel_relaxed(priv_start_addr + offset,
638		       rkvdec->regs + RKVDEC_REG_PPS_BASE);
639
640	/* config hw rps address */
641	offset = offsetof(struct rkvdec_hevc_priv_tbl, rps);
642	writel_relaxed(priv_start_addr + offset,
643		       rkvdec->regs + RKVDEC_REG_RPS_BASE);
644
645	reg = RKVDEC_AXI_DDR_RDATA(0);
646	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_RDATA);
647
648	reg = RKVDEC_AXI_DDR_WDATA(0);
649	writel_relaxed(reg, rkvdec->regs + RKVDEC_REG_AXI_DDR_WDATA);
650}
651
652#define RKVDEC_HEVC_MAX_DEPTH_IN_BYTES		2
653
654static int rkvdec_hevc_adjust_fmt(struct rkvdec_ctx *ctx,
655				  struct v4l2_format *f)
656{
657	struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
658
659	fmt->num_planes = 1;
660	if (!fmt->plane_fmt[0].sizeimage)
661		fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height *
662					      RKVDEC_HEVC_MAX_DEPTH_IN_BYTES;
663	return 0;
664}
665
666static enum rkvdec_image_fmt rkvdec_hevc_get_image_fmt(struct rkvdec_ctx *ctx,
667						       struct v4l2_ctrl *ctrl)
668{
669	const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
670
671	if (ctrl->id != V4L2_CID_STATELESS_HEVC_SPS)
672		return RKVDEC_IMG_FMT_ANY;
673
674	if (sps->bit_depth_luma_minus8 == 0) {
675		if (sps->chroma_format_idc == 2)
676			return RKVDEC_IMG_FMT_422_8BIT;
677		else
678			return RKVDEC_IMG_FMT_420_8BIT;
679	} else if (sps->bit_depth_luma_minus8 == 2) {
680		if (sps->chroma_format_idc == 2)
681			return RKVDEC_IMG_FMT_422_10BIT;
682		else
683			return RKVDEC_IMG_FMT_420_10BIT;
684	}
685
686	return RKVDEC_IMG_FMT_ANY;
687}
688
689static int rkvdec_hevc_validate_sps(struct rkvdec_ctx *ctx,
690				    const struct v4l2_ctrl_hevc_sps *sps)
691{
692	if (sps->chroma_format_idc > 1)
693		/* Only 4:0:0 and 4:2:0 are supported */
694		return -EINVAL;
695	if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
696		/* Luma and chroma bit depth mismatch */
697		return -EINVAL;
698	if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
699		/* Only 8-bit and 10-bit is supported */
700		return -EINVAL;
701
702	if (sps->pic_width_in_luma_samples > ctx->coded_fmt.fmt.pix_mp.width ||
703	    sps->pic_height_in_luma_samples > ctx->coded_fmt.fmt.pix_mp.height)
704		return -EINVAL;
705
706	return 0;
707}
708
709static int rkvdec_hevc_start(struct rkvdec_ctx *ctx)
710{
711	struct rkvdec_dev *rkvdec = ctx->dev;
712	struct rkvdec_hevc_priv_tbl *priv_tbl;
713	struct rkvdec_hevc_ctx *hevc_ctx;
714
715	hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL);
716	if (!hevc_ctx)
717		return -ENOMEM;
718
719	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
720				      &hevc_ctx->priv_tbl.dma, GFP_KERNEL);
721	if (!priv_tbl) {
722		kfree(hevc_ctx);
723		return -ENOMEM;
724	}
725
726	hevc_ctx->priv_tbl.size = sizeof(*priv_tbl);
727	hevc_ctx->priv_tbl.cpu = priv_tbl;
728	memcpy(priv_tbl->cabac_table, rkvdec_hevc_cabac_table,
729	       sizeof(rkvdec_hevc_cabac_table));
730
731	ctx->priv = hevc_ctx;
732	return 0;
733}
734
735static void rkvdec_hevc_stop(struct rkvdec_ctx *ctx)
736{
737	struct rkvdec_hevc_ctx *hevc_ctx = ctx->priv;
738	struct rkvdec_dev *rkvdec = ctx->dev;
739
740	dma_free_coherent(rkvdec->dev, hevc_ctx->priv_tbl.size,
741			  hevc_ctx->priv_tbl.cpu, hevc_ctx->priv_tbl.dma);
742	kfree(hevc_ctx);
743}
744
745static void rkvdec_hevc_run_preamble(struct rkvdec_ctx *ctx,
746				     struct rkvdec_hevc_run *run)
747{
748	struct v4l2_ctrl *ctrl;
749
750	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
751			      V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
752	run->decode_params = ctrl ? ctrl->p_cur.p : NULL;
753	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
754			      V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
755	run->slices_params = ctrl ? ctrl->p_cur.p : NULL;
756	run->num_slices = ctrl ? ctrl->new_elems : 0;
757	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
758			      V4L2_CID_STATELESS_HEVC_SPS);
759	run->sps = ctrl ? ctrl->p_cur.p : NULL;
760	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
761			      V4L2_CID_STATELESS_HEVC_PPS);
762	run->pps = ctrl ? ctrl->p_cur.p : NULL;
763	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
764			      V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
765	run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL;
766
767	rkvdec_run_preamble(ctx, &run->base);
768}
769
770static int rkvdec_hevc_run(struct rkvdec_ctx *ctx)
771{
772	struct rkvdec_dev *rkvdec = ctx->dev;
773	struct rkvdec_hevc_run run;
774	u32 reg;
775
776	rkvdec_hevc_run_preamble(ctx, &run);
777
778	assemble_hw_scaling_list(ctx, &run);
779	assemble_hw_pps(ctx, &run);
780	assemble_sw_rps(ctx, &run);
781	config_registers(ctx, &run);
782
783	rkvdec_run_postamble(ctx, &run.base);
784
785	schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
786
787	writel(0, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
788	writel(0, rkvdec->regs + RKVDEC_REG_H264_ERR_E);
789	writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
790	writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
791
792	if (rkvdec->variant->quirks & RKVDEC_QUIRK_DISABLE_QOS)
793		rkvdec_quirks_disable_qos(ctx);
794
795	/* Start decoding! */
796	reg = (run.pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) ?
797		0 : RKVDEC_WR_DDR_ALIGN_EN;
798	writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E |
799	       RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E | reg,
800	       rkvdec->regs + RKVDEC_REG_INTERRUPT);
801
802	return 0;
803}
804
805static int rkvdec_hevc_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl)
806{
807	if (ctrl->id == V4L2_CID_STATELESS_HEVC_SPS)
808		return rkvdec_hevc_validate_sps(ctx, ctrl->p_new.p_hevc_sps);
809
810	return 0;
811}
812
813const struct rkvdec_coded_fmt_ops rkvdec_hevc_fmt_ops = {
814	.adjust_fmt = rkvdec_hevc_adjust_fmt,
815	.start = rkvdec_hevc_start,
816	.stop = rkvdec_hevc_stop,
817	.run = rkvdec_hevc_run,
818	.try_ctrl = rkvdec_hevc_try_ctrl,
819	.get_image_fmt = rkvdec_hevc_get_image_fmt,
820};
~/ Read-only file preview.