1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Hantro VPU codec driver |
4 | * |
5 | * Copyright (C) 2018 Rockchip Electronics Co., Ltd. |
6 | */ |
7 | |
8 | #include "hantro.h" |
9 | |
10 | /* |
11 | * probs table with packed |
12 | */ |
13 | struct vp8_prob_tbl_packed { |
14 | u8 prob_mb_skip_false; |
15 | u8 prob_intra; |
16 | u8 prob_ref_last; |
17 | u8 prob_ref_golden; |
18 | u8 prob_segment[3]; |
19 | u8 padding0; |
20 | |
21 | u8 prob_luma_16x16_pred_mode[4]; |
22 | u8 prob_chroma_pred_mode[3]; |
23 | u8 padding1; |
24 | |
25 | /* mv prob */ |
26 | u8 prob_mv_context[2][V4L2_VP8_MV_PROB_CNT]; |
27 | u8 padding2[2]; |
28 | |
29 | /* coeff probs */ |
30 | u8 prob_coeffs[4][8][3][V4L2_VP8_COEFF_PROB_CNT]; |
31 | u8 padding3[96]; |
32 | }; |
33 | |
34 | /* |
35 | * filter taps taken to 7-bit precision, |
36 | * reference RFC6386#Page-16, filters[8][6] |
37 | */ |
38 | const u32 hantro_vp8_dec_mc_filter[8][6] = { |
39 | { 0, 0, 128, 0, 0, 0 }, |
40 | { 0, -6, 123, 12, -1, 0 }, |
41 | { 2, -11, 108, 36, -8, 1 }, |
42 | { 0, -9, 93, 50, -6, 0 }, |
43 | { 3, -16, 77, 77, -16, 3 }, |
44 | { 0, -6, 50, 93, -9, 0 }, |
45 | { 1, -8, 36, 108, -11, 2 }, |
46 | { 0, -1, 12, 123, -6, 0 } |
47 | }; |
48 | |
49 | void hantro_vp8_prob_update(struct hantro_ctx *ctx, |
50 | const struct v4l2_ctrl_vp8_frame *hdr) |
51 | { |
52 | const struct v4l2_vp8_entropy *entropy = &hdr->entropy; |
53 | u32 i, j, k; |
54 | u8 *dst; |
55 | |
56 | /* first probs */ |
57 | dst = ctx->vp8_dec.prob_tbl.cpu; |
58 | |
59 | dst[0] = hdr->prob_skip_false; |
60 | dst[1] = hdr->prob_intra; |
61 | dst[2] = hdr->prob_last; |
62 | dst[3] = hdr->prob_gf; |
63 | dst[4] = hdr->segment.segment_probs[0]; |
64 | dst[5] = hdr->segment.segment_probs[1]; |
65 | dst[6] = hdr->segment.segment_probs[2]; |
66 | dst[7] = 0; |
67 | |
68 | dst += 8; |
69 | dst[0] = entropy->y_mode_probs[0]; |
70 | dst[1] = entropy->y_mode_probs[1]; |
71 | dst[2] = entropy->y_mode_probs[2]; |
72 | dst[3] = entropy->y_mode_probs[3]; |
73 | dst[4] = entropy->uv_mode_probs[0]; |
74 | dst[5] = entropy->uv_mode_probs[1]; |
75 | dst[6] = entropy->uv_mode_probs[2]; |
76 | dst[7] = 0; /*unused */ |
77 | |
78 | /* mv probs */ |
79 | dst += 8; |
80 | dst[0] = entropy->mv_probs[0][0]; /* is short */ |
81 | dst[1] = entropy->mv_probs[1][0]; |
82 | dst[2] = entropy->mv_probs[0][1]; /* sign */ |
83 | dst[3] = entropy->mv_probs[1][1]; |
84 | dst[4] = entropy->mv_probs[0][8 + 9]; |
85 | dst[5] = entropy->mv_probs[0][9 + 9]; |
86 | dst[6] = entropy->mv_probs[1][8 + 9]; |
87 | dst[7] = entropy->mv_probs[1][9 + 9]; |
88 | dst += 8; |
89 | for (i = 0; i < 2; ++i) { |
90 | for (j = 0; j < 8; j += 4) { |
91 | dst[0] = entropy->mv_probs[i][j + 9 + 0]; |
92 | dst[1] = entropy->mv_probs[i][j + 9 + 1]; |
93 | dst[2] = entropy->mv_probs[i][j + 9 + 2]; |
94 | dst[3] = entropy->mv_probs[i][j + 9 + 3]; |
95 | dst += 4; |
96 | } |
97 | } |
98 | for (i = 0; i < 2; ++i) { |
99 | dst[0] = entropy->mv_probs[i][0 + 2]; |
100 | dst[1] = entropy->mv_probs[i][1 + 2]; |
101 | dst[2] = entropy->mv_probs[i][2 + 2]; |
102 | dst[3] = entropy->mv_probs[i][3 + 2]; |
103 | dst[4] = entropy->mv_probs[i][4 + 2]; |
104 | dst[5] = entropy->mv_probs[i][5 + 2]; |
105 | dst[6] = entropy->mv_probs[i][6 + 2]; |
106 | dst[7] = 0; /*unused */ |
107 | dst += 8; |
108 | } |
109 | |
110 | /* coeff probs (header part) */ |
111 | dst = ctx->vp8_dec.prob_tbl.cpu; |
112 | dst += (8 * 7); |
113 | for (i = 0; i < 4; ++i) { |
114 | for (j = 0; j < 8; ++j) { |
115 | for (k = 0; k < 3; ++k) { |
116 | dst[0] = entropy->coeff_probs[i][j][k][0]; |
117 | dst[1] = entropy->coeff_probs[i][j][k][1]; |
118 | dst[2] = entropy->coeff_probs[i][j][k][2]; |
119 | dst[3] = entropy->coeff_probs[i][j][k][3]; |
120 | dst += 4; |
121 | } |
122 | } |
123 | } |
124 | |
125 | /* coeff probs (footer part) */ |
126 | dst = ctx->vp8_dec.prob_tbl.cpu; |
127 | dst += (8 * 55); |
128 | for (i = 0; i < 4; ++i) { |
129 | for (j = 0; j < 8; ++j) { |
130 | for (k = 0; k < 3; ++k) { |
131 | dst[0] = entropy->coeff_probs[i][j][k][4]; |
132 | dst[1] = entropy->coeff_probs[i][j][k][5]; |
133 | dst[2] = entropy->coeff_probs[i][j][k][6]; |
134 | dst[3] = entropy->coeff_probs[i][j][k][7]; |
135 | dst[4] = entropy->coeff_probs[i][j][k][8]; |
136 | dst[5] = entropy->coeff_probs[i][j][k][9]; |
137 | dst[6] = entropy->coeff_probs[i][j][k][10]; |
138 | dst[7] = 0; /*unused */ |
139 | dst += 8; |
140 | } |
141 | } |
142 | } |
143 | } |
144 | |
145 | int hantro_vp8_dec_init(struct hantro_ctx *ctx) |
146 | { |
147 | struct hantro_dev *vpu = ctx->dev; |
148 | struct hantro_aux_buf *aux_buf; |
149 | unsigned int mb_width, mb_height; |
150 | size_t segment_map_size; |
151 | int ret; |
152 | |
153 | /* segment map table size calculation */ |
154 | mb_width = DIV_ROUND_UP(ctx->dst_fmt.width, 16); |
155 | mb_height = DIV_ROUND_UP(ctx->dst_fmt.height, 16); |
156 | segment_map_size = round_up(DIV_ROUND_UP(mb_width * mb_height, 4), 64); |
157 | |
158 | /* |
159 | * In context init the dma buffer for segment map must be allocated. |
160 | * And the data in segment map buffer must be set to all zero. |
161 | */ |
162 | aux_buf = &ctx->vp8_dec.segment_map; |
163 | aux_buf->size = segment_map_size; |
164 | aux_buf->cpu = dma_alloc_coherent(dev: vpu->dev, size: aux_buf->size, |
165 | dma_handle: &aux_buf->dma, GFP_KERNEL); |
166 | if (!aux_buf->cpu) |
167 | return -ENOMEM; |
168 | |
169 | /* |
170 | * Allocate probability table buffer, |
171 | * total 1208 bytes, 4K page is far enough. |
172 | */ |
173 | aux_buf = &ctx->vp8_dec.prob_tbl; |
174 | aux_buf->size = sizeof(struct vp8_prob_tbl_packed); |
175 | aux_buf->cpu = dma_alloc_coherent(dev: vpu->dev, size: aux_buf->size, |
176 | dma_handle: &aux_buf->dma, GFP_KERNEL); |
177 | if (!aux_buf->cpu) { |
178 | ret = -ENOMEM; |
179 | goto err_free_seg_map; |
180 | } |
181 | |
182 | return 0; |
183 | |
184 | err_free_seg_map: |
185 | dma_free_coherent(dev: vpu->dev, size: ctx->vp8_dec.segment_map.size, |
186 | cpu_addr: ctx->vp8_dec.segment_map.cpu, |
187 | dma_handle: ctx->vp8_dec.segment_map.dma); |
188 | |
189 | return ret; |
190 | } |
191 | |
192 | void hantro_vp8_dec_exit(struct hantro_ctx *ctx) |
193 | { |
194 | struct hantro_vp8_dec_hw_ctx *vp8_dec = &ctx->vp8_dec; |
195 | struct hantro_dev *vpu = ctx->dev; |
196 | |
197 | dma_free_coherent(dev: vpu->dev, size: vp8_dec->segment_map.size, |
198 | cpu_addr: vp8_dec->segment_map.cpu, dma_handle: vp8_dec->segment_map.dma); |
199 | dma_free_coherent(dev: vpu->dev, size: vp8_dec->prob_tbl.size, |
200 | cpu_addr: vp8_dec->prob_tbl.cpu, dma_handle: vp8_dec->prob_tbl.dma); |
201 | } |
202 | |