1 // SPDX-License-Identifier: GPL-2.0
3 * Hantro VPU HEVC codec driver
5 * Copyright (C) 2020 Safran Passenger Innovations LLC
8 #include <linux/types.h>
9 #include <media/v4l2-mem2mem.h>
12 #include "hantro_hw.h"
14 #define VERT_FILTER_RAM_SIZE 8 /* bytes per pixel row */
16 * BSD control data of current picture at tile border
17 * 128 bits per 4x4 tile = 128/(8*4) bytes per row
19 #define BSD_CTRL_RAM_SIZE 4 /* bytes per pixel row */
20 /* tile border coefficients of filter */
21 #define VERT_SAO_RAM_SIZE 48 /* bytes per pixel */
23 #define SCALING_LIST_SIZE (16 * 64)
25 #define MAX_TILE_COLS 20
26 #define MAX_TILE_ROWS 22
28 void hantro_hevc_ref_init(struct hantro_ctx *ctx)
30 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
32 hevc_dec->ref_bufs_used = 0;
35 dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
38 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
41 /* Find the reference buffer in already known ones */
42 for (i = 0; i < NUM_REF_PICTURES; i++) {
43 if (hevc_dec->ref_bufs_poc[i] == poc) {
44 hevc_dec->ref_bufs_used |= 1 << i;
45 return hevc_dec->ref_bufs[i].dma;
52 int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
54 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
57 /* Add a new reference buffer */
58 for (i = 0; i < NUM_REF_PICTURES; i++) {
59 if (!(hevc_dec->ref_bufs_used & 1 << i)) {
60 hevc_dec->ref_bufs_used |= 1 << i;
61 hevc_dec->ref_bufs_poc[i] = poc;
62 hevc_dec->ref_bufs[i].dma = addr;
70 static int tile_buffer_reallocate(struct hantro_ctx *ctx)
72 struct hantro_dev *vpu = ctx->dev;
73 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
74 const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
75 const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
76 const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
77 unsigned int num_tile_cols = pps->num_tile_columns_minus1 + 1;
78 unsigned int height64 = (sps->pic_height_in_luma_samples + 63) & ~63;
81 if (num_tile_cols <= 1 ||
82 num_tile_cols <= hevc_dec->num_tile_cols_allocated)
85 /* Need to reallocate due to tiles passed via PPS */
86 if (hevc_dec->tile_filter.cpu) {
87 dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size,
88 hevc_dec->tile_filter.cpu,
89 hevc_dec->tile_filter.dma);
90 hevc_dec->tile_filter.cpu = NULL;
93 if (hevc_dec->tile_sao.cpu) {
94 dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size,
95 hevc_dec->tile_sao.cpu,
96 hevc_dec->tile_sao.dma);
97 hevc_dec->tile_sao.cpu = NULL;
100 if (hevc_dec->tile_bsd.cpu) {
101 dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size,
102 hevc_dec->tile_bsd.cpu,
103 hevc_dec->tile_bsd.dma);
104 hevc_dec->tile_bsd.cpu = NULL;
107 size = VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1);
108 hevc_dec->tile_filter.cpu = dma_alloc_coherent(vpu->dev, size,
109 &hevc_dec->tile_filter.dma,
111 if (!hevc_dec->tile_filter.cpu)
112 goto err_free_tile_buffers;
113 hevc_dec->tile_filter.size = size;
115 size = VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1);
116 hevc_dec->tile_sao.cpu = dma_alloc_coherent(vpu->dev, size,
117 &hevc_dec->tile_sao.dma,
119 if (!hevc_dec->tile_sao.cpu)
120 goto err_free_tile_buffers;
121 hevc_dec->tile_sao.size = size;
123 size = BSD_CTRL_RAM_SIZE * height64 * (num_tile_cols - 1);
124 hevc_dec->tile_bsd.cpu = dma_alloc_coherent(vpu->dev, size,
125 &hevc_dec->tile_bsd.dma,
127 if (!hevc_dec->tile_bsd.cpu)
128 goto err_free_tile_buffers;
129 hevc_dec->tile_bsd.size = size;
131 hevc_dec->num_tile_cols_allocated = num_tile_cols;
135 err_free_tile_buffers:
136 if (hevc_dec->tile_filter.cpu)
137 dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size,
138 hevc_dec->tile_filter.cpu,
139 hevc_dec->tile_filter.dma);
140 hevc_dec->tile_filter.cpu = NULL;
142 if (hevc_dec->tile_sao.cpu)
143 dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size,
144 hevc_dec->tile_sao.cpu,
145 hevc_dec->tile_sao.dma);
146 hevc_dec->tile_sao.cpu = NULL;
148 if (hevc_dec->tile_bsd.cpu)
149 dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size,
150 hevc_dec->tile_bsd.cpu,
151 hevc_dec->tile_bsd.dma);
152 hevc_dec->tile_bsd.cpu = NULL;
157 int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx)
159 struct hantro_hevc_dec_hw_ctx *hevc_ctx = &ctx->hevc_dec;
160 struct hantro_hevc_dec_ctrls *ctrls = &hevc_ctx->ctrls;
163 hantro_start_prepare_run(ctx);
165 ctrls->decode_params =
166 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS);
167 if (WARN_ON(!ctrls->decode_params))
171 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
172 if (WARN_ON(!ctrls->scaling))
176 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS);
177 if (WARN_ON(!ctrls->sps))
181 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_PPS);
182 if (WARN_ON(!ctrls->pps))
185 ret = tile_buffer_reallocate(ctx);
192 void hantro_hevc_dec_exit(struct hantro_ctx *ctx)
194 struct hantro_dev *vpu = ctx->dev;
195 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
197 if (hevc_dec->tile_sizes.cpu)
198 dma_free_coherent(vpu->dev, hevc_dec->tile_sizes.size,
199 hevc_dec->tile_sizes.cpu,
200 hevc_dec->tile_sizes.dma);
201 hevc_dec->tile_sizes.cpu = NULL;
203 if (hevc_dec->scaling_lists.cpu)
204 dma_free_coherent(vpu->dev, hevc_dec->scaling_lists.size,
205 hevc_dec->scaling_lists.cpu,
206 hevc_dec->scaling_lists.dma);
207 hevc_dec->scaling_lists.cpu = NULL;
209 if (hevc_dec->tile_filter.cpu)
210 dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size,
211 hevc_dec->tile_filter.cpu,
212 hevc_dec->tile_filter.dma);
213 hevc_dec->tile_filter.cpu = NULL;
215 if (hevc_dec->tile_sao.cpu)
216 dma_free_coherent(vpu->dev, hevc_dec->tile_sao.size,
217 hevc_dec->tile_sao.cpu,
218 hevc_dec->tile_sao.dma);
219 hevc_dec->tile_sao.cpu = NULL;
221 if (hevc_dec->tile_bsd.cpu)
222 dma_free_coherent(vpu->dev, hevc_dec->tile_bsd.size,
223 hevc_dec->tile_bsd.cpu,
224 hevc_dec->tile_bsd.dma);
225 hevc_dec->tile_bsd.cpu = NULL;
228 int hantro_hevc_dec_init(struct hantro_ctx *ctx)
230 struct hantro_dev *vpu = ctx->dev;
231 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
234 memset(hevc_dec, 0, sizeof(*hevc_dec));
237 * Maximum number of tiles times width and height (2 bytes each),
238 * rounding up to next 16 bytes boundary + one extra 16 byte
239 * chunk (HW guys wanted to have this).
241 size = round_up(MAX_TILE_COLS * MAX_TILE_ROWS * 4 * sizeof(u16) + 16, 16);
242 hevc_dec->tile_sizes.cpu = dma_alloc_coherent(vpu->dev, size,
243 &hevc_dec->tile_sizes.dma,
245 if (!hevc_dec->tile_sizes.cpu)
248 hevc_dec->tile_sizes.size = size;
250 hevc_dec->scaling_lists.cpu = dma_alloc_coherent(vpu->dev, SCALING_LIST_SIZE,
251 &hevc_dec->scaling_lists.dma,
253 if (!hevc_dec->scaling_lists.cpu)
256 hevc_dec->scaling_lists.size = SCALING_LIST_SIZE;
258 hantro_hevc_ref_init(ctx);