Merge branch 'core-objtool-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-block.git] / drivers / staging / media / hantro / hantro_jpeg.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) Collabora, Ltd.
4  *
5  * Based on GSPCA and CODA drivers:
6  * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
7  * Copyright (C) 2014 Philipp Zabel, Pengutronix
8  */
9 #include <linux/dma-mapping.h>
10 #include <linux/kernel.h>
11 #include <linux/string.h>
12 #include "hantro_jpeg.h"
13 #include "hantro.h"
14
15 #define LUMA_QUANT_OFF          7
16 #define CHROMA_QUANT_OFF        72
17 #define HEIGHT_OFF              141
18 #define WIDTH_OFF               143
19
20 #define HUFF_LUMA_DC_OFF        160
21 #define HUFF_LUMA_AC_OFF        193
22 #define HUFF_CHROMA_DC_OFF      376
23 #define HUFF_CHROMA_AC_OFF      409
24
25 /* Default tables from JPEG ITU-T.81
26  * (ISO/IEC 10918-1) Annex K, tables K.1 and K.2
27  */
28 static const unsigned char luma_q_table[] = {
29         0x10, 0x0b, 0x0a, 0x10, 0x18, 0x28, 0x33, 0x3d,
30         0x0c, 0x0c, 0x0e, 0x13, 0x1a, 0x3a, 0x3c, 0x37,
31         0x0e, 0x0d, 0x10, 0x18, 0x28, 0x39, 0x45, 0x38,
32         0x0e, 0x11, 0x16, 0x1d, 0x33, 0x57, 0x50, 0x3e,
33         0x12, 0x16, 0x25, 0x38, 0x44, 0x6d, 0x67, 0x4d,
34         0x18, 0x23, 0x37, 0x40, 0x51, 0x68, 0x71, 0x5c,
35         0x31, 0x40, 0x4e, 0x57, 0x67, 0x79, 0x78, 0x65,
36         0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0x63
37 };
38
39 static unsigned char luma_q_table_reordered[ARRAY_SIZE(luma_q_table)];
40
41 static const unsigned char chroma_q_table[] = {
42         0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63,
43         0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63,
44         0x18, 0x1a, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,
45         0x2f, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
46         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
47         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
48         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
49         0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
50 };
51
52 static unsigned char chroma_q_table_reordered[ARRAY_SIZE(chroma_q_table)];
53
54 static const unsigned char zigzag[64] = {
55          0,  1,  8, 16,  9,  2,  3, 10,
56         17, 24, 32, 25, 18, 11,  4,  5,
57         12, 19, 26, 33, 40, 48, 41, 34,
58         27, 20, 13,  6,  7, 14, 21, 28,
59         35, 42, 49, 56, 57, 50, 43, 36,
60         29, 22, 15, 23, 30, 37, 44, 51,
61         58, 59, 52, 45, 38, 31, 39, 46,
62         53, 60, 61, 54, 47, 55, 62, 63
63 };
64
65 static const u32 hw_reorder[64] = {
66          0,  8, 16, 24,  1,  9, 17, 25,
67         32, 40, 48, 56, 33, 41, 49, 57,
68          2, 10, 18, 26,  3, 11, 19, 27,
69         34, 42, 50, 58, 35, 43, 51, 59,
70          4, 12, 20, 28,  5, 13, 21, 29,
71         36, 44, 52, 60, 37, 45, 53, 61,
72          6, 14, 22, 30,  7, 15, 23, 31,
73         38, 46, 54, 62, 39, 47, 55, 63
74 };
75
76 /* Huffman tables are shared with CODA */
77 static const unsigned char luma_dc_table[] = {
78         0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
79         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
81         0x08, 0x09, 0x0a, 0x0b,
82 };
83
84 static const unsigned char chroma_dc_table[] = {
85         0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
86         0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
87         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
88         0x08, 0x09, 0x0a, 0x0b,
89 };
90
91 static const unsigned char luma_ac_table[] = {
92         0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
93         0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
94         0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
95         0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
96         0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
97         0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
98         0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
99         0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
100         0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
101         0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
102         0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
103         0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
104         0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
105         0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
106         0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
107         0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
108         0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
109         0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
110         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
111         0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
112         0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
113         0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
114         0xf9, 0xfa,
115 };
116
117 static const unsigned char chroma_ac_table[] = {
118         0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
119         0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
120         0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
121         0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
122         0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
123         0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
124         0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
125         0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
126         0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
127         0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
128         0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
129         0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
130         0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
131         0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
132         0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
133         0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
134         0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
135         0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
136         0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
137         0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
138         0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
139         0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
140         0xf9, 0xfa,
141 };
142
143 /* For simplicity, we keep a pre-formatted JPEG header,
144  * and we'll use fixed offsets to change the width, height
145  * quantization tables, etc.
146  */
147 static const unsigned char hantro_jpeg_header[JPEG_HEADER_SIZE] = {
148         /* SOI */
149         0xff, 0xd8,
150
151         /* DQT */
152         0xff, 0xdb, 0x00, 0x84,
153
154         0x00,
155         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163
164         0x01,
165         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173
174         /* SOF */
175         0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x01,
176         0x40, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01,
177         0x03, 0x11, 0x01,
178
179         /* DHT */
180         0xff, 0xc4, 0x00, 0x1f, 0x00,
181
182         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185         0x00, 0x00, 0x00, 0x00,
186
187         /* DHT */
188         0xff, 0xc4, 0x00, 0xb5, 0x10,
189
190         0x00, 0x00,
191         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213
214         /* DHT */
215         0xff, 0xc4, 0x00, 0x1f, 0x01,
216
217         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220         0x00, 0x00, 0x00, 0x00,
221
222         /* DHT */
223         0xff, 0xc4, 0x00, 0xb5, 0x11,
224
225         0x00, 0x00,
226         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248
249         /* SOS */
250         0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
251         0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
252 };
253
254 static unsigned char jpeg_scale_qp(const unsigned char qp, int scale)
255 {
256         unsigned int temp;
257
258         temp = DIV_ROUND_CLOSEST((unsigned int)qp * scale, 100);
259         if (temp <= 0)
260                 temp = 1;
261         if (temp > 255)
262                 temp = 255;
263
264         return (unsigned char)temp;
265 }
266
267 static void
268 jpeg_scale_quant_table(unsigned char *file_q_tab,
269                        unsigned char *reordered_q_tab,
270                        const unsigned char *tab, int scale)
271 {
272         int i;
273
274         for (i = 0; i < 64; i++) {
275                 file_q_tab[i] = jpeg_scale_qp(tab[zigzag[i]], scale);
276                 reordered_q_tab[i] = jpeg_scale_qp(tab[hw_reorder[i]], scale);
277         }
278 }
279
280 static void jpeg_set_quality(unsigned char *buffer, int quality)
281 {
282         int scale;
283
284         /*
285          * Non-linear scaling factor:
286          * [5,50] -> [1000..100], [51,100] -> [98..0]
287          */
288         if (quality < 50)
289                 scale = 5000 / quality;
290         else
291                 scale = 200 - 2 * quality;
292
293         jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF,
294                                luma_q_table_reordered,
295                                luma_q_table, scale);
296         jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF,
297                                chroma_q_table_reordered,
298                                chroma_q_table, scale);
299 }
300
301 unsigned char *hantro_jpeg_get_qtable(int index)
302 {
303         if (index == 0)
304                 return luma_q_table_reordered;
305         return chroma_q_table_reordered;
306 }
307
308 void hantro_jpeg_header_assemble(struct hantro_jpeg_ctx *ctx)
309 {
310         char *buf = ctx->buffer;
311
312         memcpy(buf, hantro_jpeg_header,
313                sizeof(hantro_jpeg_header));
314
315         buf[HEIGHT_OFF + 0] = ctx->height >> 8;
316         buf[HEIGHT_OFF + 1] = ctx->height;
317         buf[WIDTH_OFF + 0] = ctx->width >> 8;
318         buf[WIDTH_OFF + 1] = ctx->width;
319
320         memcpy(buf + HUFF_LUMA_DC_OFF, luma_dc_table, sizeof(luma_dc_table));
321         memcpy(buf + HUFF_LUMA_AC_OFF, luma_ac_table, sizeof(luma_ac_table));
322         memcpy(buf + HUFF_CHROMA_DC_OFF, chroma_dc_table,
323                sizeof(chroma_dc_table));
324         memcpy(buf + HUFF_CHROMA_AC_OFF, chroma_ac_table,
325                sizeof(chroma_ac_table));
326
327         jpeg_set_quality(buf, ctx->quality);
328 }
329
330 int hantro_jpeg_enc_init(struct hantro_ctx *ctx)
331 {
332         ctx->jpeg_enc.bounce_buffer.size =
333                 ctx->dst_fmt.plane_fmt[0].sizeimage -
334                 ctx->vpu_dst_fmt->header_size;
335
336         ctx->jpeg_enc.bounce_buffer.cpu =
337                 dma_alloc_attrs(ctx->dev->dev,
338                                 ctx->jpeg_enc.bounce_buffer.size,
339                                 &ctx->jpeg_enc.bounce_buffer.dma,
340                                 GFP_KERNEL,
341                                 DMA_ATTR_ALLOC_SINGLE_PAGES);
342         if (!ctx->jpeg_enc.bounce_buffer.cpu)
343                 return -ENOMEM;
344
345         return 0;
346 }
347
348 void hantro_jpeg_enc_exit(struct hantro_ctx *ctx)
349 {
350         dma_free_attrs(ctx->dev->dev,
351                        ctx->jpeg_enc.bounce_buffer.size,
352                        ctx->jpeg_enc.bounce_buffer.cpu,
353                        ctx->jpeg_enc.bounce_buffer.dma,
354                        DMA_ATTR_ALLOC_SINGLE_PAGES);
355 }