1 #include "bflb_mjpeg.h"
2 #include "hardware/mjpeg_reg.h"
3
bflb_mjpeg_set_yuv422_interleave_order(struct bflb_device_s * dev,uint8_t y0,uint8_t u0,uint8_t y1,uint8_t v0)4 static void bflb_mjpeg_set_yuv422_interleave_order(struct bflb_device_s *dev, uint8_t y0, uint8_t u0, uint8_t y1, uint8_t v0)
5 {
6 uint32_t regval;
7 uint32_t reg_base;
8
9 reg_base = dev->reg_base;
10
11 regval = getreg32(reg_base + MJPEG_HEADER_BYTE_OFFSET);
12 regval &= ~MJPEG_REG_Y0_ORDER_MASK;
13 regval &= ~MJPEG_REG_U0_ORDER_MASK;
14 regval &= ~MJPEG_REG_Y1_ORDER_MASK;
15 regval &= ~MJPEG_REG_V0_ORDER_MASK;
16
17 regval |= (y0 << MJPEG_REG_Y0_ORDER_SHIFT);
18 regval |= (u0 << MJPEG_REG_U0_ORDER_SHIFT);
19 regval |= (y1 << MJPEG_REG_Y1_ORDER_SHIFT);
20 regval |= (v0 << MJPEG_REG_V0_ORDER_SHIFT);
21
22 putreg32(regval, reg_base + MJPEG_HEADER_BYTE_OFFSET);
23 }
24
bflb_mjpeg_set_framesize(struct bflb_device_s * dev,uint16_t x,uint16_t y)25 static void bflb_mjpeg_set_framesize(struct bflb_device_s *dev, uint16_t x, uint16_t y)
26 {
27 uint32_t regval;
28 uint32_t reg_base;
29
30 reg_base = dev->reg_base;
31
32 regval = 0;
33 regval |= (x << MJPEG_REG_FRAME_WBLK_SHIFT);
34 regval |= (y << MJPEG_REG_FRAME_HBLK_SHIFT);
35 putreg32(regval, reg_base + MJPEG_FRAME_SIZE_OFFSET);
36 }
37
bflb_mjpeg_init(struct bflb_device_s * dev,const struct bflb_mjpeg_config_s * config)38 void bflb_mjpeg_init(struct bflb_device_s *dev, const struct bflb_mjpeg_config_s *config)
39 {
40 uint32_t regval;
41 uint32_t reg_base;
42 uint16_t blocks;
43
44 reg_base = dev->reg_base;
45
46 regval = getreg32(reg_base + MJPEG_CONTROL_1_OFFSET);
47 regval &= ~MJPEG_REG_MJPEG_ENABLE;
48 putreg32(regval, reg_base + MJPEG_CONTROL_1_OFFSET);
49
50 regval = 0;
51 regval |= (3 << MJPEG_REG_W_XLEN_SHIFT); /* burst count 16 increment */
52 regval |= MJPEG_REG_READ_FWRAP;
53 regval |= MJPEG_REG_MJPEG_BIT_ORDER;
54
55 switch (config->format) {
56 case MJPEG_FORMAT_YUV422_YUYV:
57 regval |= (3 << MJPEG_REG_YUV_MODE_SHIFT);
58 bflb_mjpeg_set_yuv422_interleave_order(dev, 0, 1, 2, 3);
59 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 7) >> 3);
60 break;
61 case MJPEG_FORMAT_YUV422_YVYU:
62 regval |= (3 << MJPEG_REG_YUV_MODE_SHIFT);
63 bflb_mjpeg_set_yuv422_interleave_order(dev, 0, 3, 2, 1);
64 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 7) >> 3);
65 break;
66 case MJPEG_FORMAT_YUV422_UYVY:
67 regval |= (3 << MJPEG_REG_YUV_MODE_SHIFT);
68 bflb_mjpeg_set_yuv422_interleave_order(dev, 1, 0, 3, 2);
69 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 7) >> 3);
70 break;
71 case MJPEG_FORMAT_YUV422_VYUY:
72 regval |= (3 << MJPEG_REG_YUV_MODE_SHIFT);
73 bflb_mjpeg_set_yuv422_interleave_order(dev, 1, 2, 3, 0);
74 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 7) >> 3);
75 break;
76 case MJPEG_FORMAT_YUV422SP_NV16:
77 regval |= (2 << MJPEG_REG_YUV_MODE_SHIFT);
78 regval |= MJPEG_REG_ORDER_U_EVEN;
79 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 7) >> 3);
80 break;
81 case MJPEG_FORMAT_YUV422SP_NV61:
82 regval |= (2 << MJPEG_REG_YUV_MODE_SHIFT);
83 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 7) >> 3);
84 break;
85 case MJPEG_FORMAT_YUV420SP_NV12:
86 regval |= (0 << MJPEG_REG_YUV_MODE_SHIFT);
87 regval |= MJPEG_REG_ORDER_U_EVEN;
88
89 if (config->resolution_x % 16) {
90 regval |= MJPEG_REG_LAST_HF_WBLK_DMY;
91 }
92
93 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 15) >> 4);
94 break;
95 case MJPEG_FORMAT_YUV420SP_NV21:
96 regval |= (0 << MJPEG_REG_YUV_MODE_SHIFT);
97
98 if (config->resolution_x % 16) {
99 regval |= MJPEG_REG_LAST_HF_WBLK_DMY;
100 }
101
102 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 15) >> 4, (config->resolution_y + 15) >> 3);
103 break;
104 case MJPEG_FORMAT_GRAY:
105 regval |= (1 << MJPEG_REG_YUV_MODE_SHIFT);
106
107 if (config->resolution_x % 16) {
108 regval |= MJPEG_REG_LAST_HF_WBLK_DMY;
109 }
110
111 if (config->resolution_y % 16) {
112 regval |= MJPEG_REG_LAST_HF_HBLK_DMY;
113 }
114
115 bflb_mjpeg_set_framesize(dev, (config->resolution_x + 7) >> 3, (config->resolution_y + 7) >> 3);
116 break;
117
118 default:
119 break;
120 }
121
122 putreg32(regval, reg_base + MJPEG_CONTROL_1_OFFSET);
123
124 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
125 regval &= ~MJPEG_REG_MJPEG_WAIT_CYCLE_MASK;
126 regval |= (0x100 << MJPEG_REG_MJPEG_WAIT_CYCLE_SHIFT);
127 regval &= ~MJPEG_REG_MJPEG_SW_MODE;
128 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
129
130 regval = getreg32(reg_base + MJPEG_SWAP_MODE_OFFSET);
131 regval &= ~MJPEG_REG_W_SWAP_MODE;
132 putreg32(regval, reg_base + MJPEG_SWAP_MODE_OFFSET);
133
134 putreg32(config->input_bufaddr0, reg_base + MJPEG_YY_FRAME_ADDR_OFFSET);
135 putreg32(config->input_bufaddr1, reg_base + MJPEG_UV_FRAME_ADDR_OFFSET);
136
137 blocks = config->rows / 8;
138
139 switch (config->format) {
140 case MJPEG_FORMAT_YUV422_YUYV:
141 case MJPEG_FORMAT_YUV422_YVYU:
142 case MJPEG_FORMAT_YUV422_UYVY:
143 case MJPEG_FORMAT_YUV422_VYUY:
144 putreg32((0 << 16) + blocks, reg_base + MJPEG_YUV_MEM_OFFSET); /* uv << 16 + yy */
145 break;
146 case MJPEG_FORMAT_YUV422SP_NV16:
147 case MJPEG_FORMAT_YUV422SP_NV61:
148 putreg32((blocks << 16) + blocks, reg_base + MJPEG_YUV_MEM_OFFSET);
149 break;
150 case MJPEG_FORMAT_YUV420SP_NV12:
151 case MJPEG_FORMAT_YUV420SP_NV21:
152 putreg32((blocks << 16) + blocks, reg_base + MJPEG_YUV_MEM_OFFSET);
153 break;
154 case MJPEG_FORMAT_GRAY:
155 putreg32((0 << 16) + blocks, reg_base + MJPEG_YUV_MEM_OFFSET);
156 break;
157
158 default:
159 break;
160 }
161
162 putreg32(config->output_bufaddr, reg_base + MJPEG_JPEG_FRAME_ADDR_OFFSET);
163 putreg32(config->output_bufsize / 128, reg_base + MJPEG_JPEG_STORE_MEMORY_OFFSET);
164
165 regval = getreg32(reg_base + MJPEG_CONTROL_3_OFFSET);
166 regval &= ~MJPEG_REG_INT_NORMAL_EN;
167 regval &= ~MJPEG_REG_INT_CAM_EN;
168 regval &= ~MJPEG_REG_INT_MEM_EN;
169 regval &= ~MJPEG_REG_INT_FRAME_EN;
170 regval &= ~MJPEG_REG_INT_IDLE_EN;
171 regval &= ~MJPEG_REG_INT_SWAP_EN;
172 regval &= ~MJPEG_REG_FRAME_CNT_TRGR_INT_MASK;
173 regval |= (1 << MJPEG_REG_FRAME_CNT_TRGR_INT_SHIFT); /* trigger int with one frame */
174 putreg32(regval, reg_base + MJPEG_CONTROL_3_OFFSET);
175
176 regval = getreg32(reg_base + MJPEG_HEADER_BYTE_OFFSET);
177 regval &= ~MJPEG_REG_HEAD_BYTE_MASK;
178 regval &= ~MJPEG_REG_TAIL_EXP;
179 putreg32(regval, reg_base + MJPEG_HEADER_BYTE_OFFSET);
180
181 /* Clear interrupt */
182 putreg32(0x3F00, reg_base + MJPEG_FRAME_FIFO_POP_OFFSET);
183
184 static uint16_t q_table_50_y[64] = {
185 16, 11, 10, 16, 24, 40, 51, 61,
186 12, 12, 14, 19, 26, 58, 60, 55,
187 14, 13, 16, 24, 40, 57, 69, 56,
188 14, 17, 22, 29, 51, 87, 80, 62,
189 18, 22, 37, 56, 68, 109, 103, 77,
190 24, 35, 55, 64, 81, 104, 113, 92,
191 49, 64, 78, 87, 103, 121, 120, 101,
192 72, 92, 95, 98, 112, 100, 103, 99
193 };
194
195 static uint16_t q_table_50_uv[64] = {
196 17, 18, 24, 47, 99, 99, 99, 99,
197 18, 21, 26, 66, 99, 99, 99, 99,
198 24, 26, 56, 99, 99, 99, 99, 99,
199 47, 66, 99, 99, 99, 99, 99, 99,
200 99, 99, 99, 99, 99, 99, 99, 99,
201 99, 99, 99, 99, 99, 99, 99, 99,
202 99, 99, 99, 99, 99, 99, 99, 99,
203 99, 99, 99, 99, 99, 99, 99, 99
204 };
205
206 uint16_t tmp_table_y[64] = { 0 };
207 uint16_t tmp_table_uv[64] = { 0 };
208
209 if (config->input_yy_table) {
210 bflb_mjpeg_calculate_quantize_table(config->quality, config->input_yy_table, tmp_table_y);
211 } else {
212 bflb_mjpeg_calculate_quantize_table(config->quality, q_table_50_y, tmp_table_y);
213 }
214 if (config->input_uv_table) {
215 bflb_mjpeg_calculate_quantize_table(config->quality, config->input_uv_table, tmp_table_uv);
216 } else {
217 bflb_mjpeg_calculate_quantize_table(config->quality, q_table_50_uv, tmp_table_uv);
218 }
219
220 bflb_mjpeg_fill_quantize_table(dev, tmp_table_y, tmp_table_uv);
221 }
222
bflb_mjpeg_start(struct bflb_device_s * dev)223 void bflb_mjpeg_start(struct bflb_device_s *dev)
224 {
225 uint32_t regval;
226 uint32_t reg_base;
227
228 reg_base = dev->reg_base;
229
230 regval = getreg32(reg_base + MJPEG_CONTROL_1_OFFSET);
231 regval |= MJPEG_REG_MJPEG_ENABLE;
232 putreg32(regval, reg_base + MJPEG_CONTROL_1_OFFSET);
233 }
234
bflb_mjpeg_stop(struct bflb_device_s * dev)235 void bflb_mjpeg_stop(struct bflb_device_s *dev)
236 {
237 uint32_t regval;
238 uint32_t reg_base;
239
240 reg_base = dev->reg_base;
241
242 regval = getreg32(reg_base + MJPEG_CONTROL_1_OFFSET);
243 regval &= ~MJPEG_REG_MJPEG_ENABLE;
244 putreg32(regval, reg_base + MJPEG_CONTROL_1_OFFSET);
245 }
246
bflb_mjpeg_sw_run(struct bflb_device_s * dev,uint8_t frame_count)247 void bflb_mjpeg_sw_run(struct bflb_device_s *dev, uint8_t frame_count)
248 {
249 uint32_t regval;
250 uint32_t reg_base;
251
252 reg_base = dev->reg_base;
253
254 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
255 regval &= ~MJPEG_REG_SW_KICK_MODE;
256 regval &= ~MJPEG_REG_SW_FRAME_MASK;
257 regval |= (frame_count << MJPEG_REG_SW_FRAME_SHIFT);
258 regval |= MJPEG_REG_MJPEG_SW_MODE;
259 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
260
261 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
262 regval &= ~MJPEG_REG_MJPEG_SW_MODE;
263 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
264
265 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
266 regval |= MJPEG_REG_MJPEG_SW_RUN;
267 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
268
269 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
270 regval &= ~MJPEG_REG_MJPEG_SW_RUN;
271 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
272 }
273
bflb_mjpeg_kick_run(struct bflb_device_s * dev,uint16_t kick_count)274 void bflb_mjpeg_kick_run(struct bflb_device_s *dev, uint16_t kick_count)
275 {
276 uint32_t regval;
277 uint32_t reg_base;
278
279 reg_base = dev->reg_base;
280
281 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
282 regval |= MJPEG_REG_SW_KICK_MODE;
283 regval &= ~MJPEG_REG_SW_FRAME_MASK;
284 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
285
286 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
287 regval |= MJPEG_REG_MJPEG_SW_MODE;
288 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
289
290 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
291 regval &= ~MJPEG_REG_MJPEG_SW_MODE;
292 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
293
294 regval = getreg32(reg_base + MJPEG_YUV_MEM_SW_OFFSET);
295 regval &= ~MJPEG_REG_SW_KICK_HBLK_MASK;
296 regval |= (kick_count << MJPEG_REG_SW_KICK_HBLK_SHIFT);
297 putreg32(regval, reg_base + MJPEG_YUV_MEM_SW_OFFSET);
298
299 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
300 regval |= MJPEG_REG_MJPEG_SW_RUN;
301 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
302
303 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
304 regval &= ~MJPEG_REG_MJPEG_SW_RUN;
305 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
306 }
307
bflb_mjpeg_kick_stop(struct bflb_device_s * dev)308 void bflb_mjpeg_kick_stop(struct bflb_device_s *dev)
309 {
310 uint32_t regval;
311 uint32_t reg_base;
312
313 reg_base = dev->reg_base;
314
315 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
316 regval &= ~MJPEG_REG_SW_KICK_MODE;
317 regval &= ~MJPEG_REG_SW_FRAME_MASK;
318 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
319
320 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
321 regval |= MJPEG_REG_MJPEG_SW_MODE;
322 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
323
324 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
325 regval &= ~MJPEG_REG_MJPEG_SW_MODE;
326 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
327 }
328
bflb_mjpeg_kick(struct bflb_device_s * dev)329 void bflb_mjpeg_kick(struct bflb_device_s *dev)
330 {
331 uint32_t regval;
332 uint32_t reg_base;
333
334 reg_base = dev->reg_base;
335
336 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
337 regval |= MJPEG_REG_SW_KICK;
338 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
339 }
340
bflb_mjpeg_tcint_mask(struct bflb_device_s * dev,bool mask)341 void bflb_mjpeg_tcint_mask(struct bflb_device_s *dev, bool mask)
342 {
343 uint32_t regval;
344 uint32_t reg_base;
345
346 reg_base = dev->reg_base;
347
348 regval = getreg32(reg_base + MJPEG_CONTROL_3_OFFSET);
349
350 if (mask) {
351 regval &= ~MJPEG_REG_INT_NORMAL_EN;
352 } else {
353 regval |= MJPEG_REG_INT_NORMAL_EN;
354 }
355
356 putreg32(regval, reg_base + MJPEG_CONTROL_3_OFFSET);
357 }
358
bflb_mjpeg_errint_mask(struct bflb_device_s * dev,bool mask)359 void bflb_mjpeg_errint_mask(struct bflb_device_s *dev, bool mask)
360 {
361 uint32_t regval;
362 uint32_t reg_base;
363
364 reg_base = dev->reg_base;
365
366 regval = getreg32(reg_base + MJPEG_CONTROL_3_OFFSET);
367
368 if (mask) {
369 regval &= ~MJPEG_REG_INT_CAM_EN;
370 regval &= ~MJPEG_REG_INT_MEM_EN;
371 regval &= ~MJPEG_REG_INT_FRAME_EN;
372 regval &= ~MJPEG_REG_INT_IDLE_EN;
373 regval &= ~MJPEG_REG_INT_SWAP_EN;
374 } else {
375 regval |= MJPEG_REG_INT_CAM_EN;
376 regval |= MJPEG_REG_INT_MEM_EN;
377 regval |= MJPEG_REG_INT_FRAME_EN;
378 regval |= MJPEG_REG_INT_IDLE_EN;
379 regval |= MJPEG_REG_INT_SWAP_EN;
380 }
381
382 putreg32(regval, reg_base + MJPEG_CONTROL_3_OFFSET);
383 }
384
bflb_mjpeg_get_intstatus(struct bflb_device_s * dev)385 uint32_t bflb_mjpeg_get_intstatus(struct bflb_device_s *dev)
386 {
387 uint32_t regval;
388 uint32_t reg_base;
389
390 reg_base = dev->reg_base;
391
392 regval = getreg32(reg_base + MJPEG_CONTROL_3_OFFSET);
393 regval &= 0xf0;
394
395 return regval;
396 }
397
bflb_mjpeg_int_clear(struct bflb_device_s * dev,uint32_t int_clear)398 void bflb_mjpeg_int_clear(struct bflb_device_s *dev, uint32_t int_clear)
399 {
400 uint32_t reg_base;
401
402 reg_base = dev->reg_base;
403
404 putreg32(int_clear, reg_base + MJPEG_FRAME_FIFO_POP_OFFSET);
405 }
406
bflb_mjpeg_get_frame_count(struct bflb_device_s * dev)407 uint8_t bflb_mjpeg_get_frame_count(struct bflb_device_s *dev)
408 {
409 uint32_t reg_base;
410
411 reg_base = dev->reg_base;
412
413 return ((getreg32(reg_base + MJPEG_CONTROL_3_OFFSET) & MJPEG_FRAME_VALID_CNT_MASK) >> MJPEG_FRAME_VALID_CNT_SHIFT);
414 }
415
bflb_mjpeg_pop_one_frame(struct bflb_device_s * dev)416 void bflb_mjpeg_pop_one_frame(struct bflb_device_s *dev)
417 {
418 uint32_t reg_base;
419
420 reg_base = dev->reg_base;
421
422 putreg32(1, reg_base + MJPEG_FRAME_FIFO_POP_OFFSET);
423 }
424
bflb_mjpeg_get_frame_info(struct bflb_device_s * dev,uint8_t ** pic)425 uint32_t bflb_mjpeg_get_frame_info(struct bflb_device_s *dev, uint8_t **pic)
426 {
427 uint32_t bytes;
428 uint32_t reg_base;
429
430 reg_base = dev->reg_base;
431
432 *pic = (uint8_t *)getreg32(reg_base + MJPEG_START_ADDR0_OFFSET);
433 bytes = (getreg32(reg_base + MJPEG_BIT_CNT0_OFFSET) + 7) >> 3;
434
435 return bytes;
436 }
437
bflb_mjpeg_calculate_quantize_table(uint8_t quality,uint16_t * input_table,uint16_t * output_table)438 void bflb_mjpeg_calculate_quantize_table(uint8_t quality, uint16_t *input_table, uint16_t *output_table)
439 {
440 uint32_t scale_factor, i;
441
442 if (quality == 0) {
443 quality = 1;
444 } else if (quality > 100) {
445 quality = 100;
446 }
447
448 if (quality < 50) {
449 scale_factor = 5000000 / quality;
450 } else {
451 scale_factor = 200000 - quality * 2000;
452 }
453
454 for (i = 0; i < 64; i++) {
455 output_table[i] = (input_table[i] * scale_factor + 50000) / 100000;
456
457 if (output_table[i] == 0) {
458 output_table[i] = 1;
459 } else if (output_table[i] > 0xff) {
460 output_table[i] = 0xff;
461 }
462 }
463 }
464
bflb_mjpeg_fill_quantize_table(struct bflb_device_s * dev,uint16_t * input_yy,uint16_t * input_uv)465 void bflb_mjpeg_fill_quantize_table(struct bflb_device_s *dev, uint16_t *input_yy, uint16_t *input_uv)
466 {
467 #define MJPEG_Q_PARAM_00_OFFSET (0x400)
468 #define MJPEG_Q_PARAM_40_OFFSET (0x480)
469
470 uint8_t i, j;
471 uint16_t tmp1;
472 uint16_t tmp2;
473 uint32_t regval;
474 uint32_t reg_base;
475
476 reg_base = dev->reg_base;
477
478 for (i = 0; i < 8; i++) {
479 for (j = 0; j < 4; j++) {
480 tmp1 = 2048 / input_yy[16 * j + i];
481 tmp2 = 2048 / input_yy[16 * j + i + 8];
482
483 if (20480 / input_yy[16 * j + i] % 10 > 4) {
484 tmp1++;
485 }
486
487 if (20480 / input_yy[16 * j + i + 8] % 10 > 4) {
488 tmp2++;
489 }
490
491 putreg32(tmp1 | tmp2 << 16, reg_base + MJPEG_Q_PARAM_00_OFFSET + (i * 4 + j) * 4);
492 }
493 }
494
495 for (i = 0; i < 8; i++) {
496 for (j = 0; j < 4; j++) {
497 tmp1 = 2048 / input_uv[16 * j + i];
498 tmp2 = 2048 / input_uv[16 * j + i + 8];
499
500 if (20480 / input_uv[16 * j + i] % 10 > 4) {
501 tmp1++;
502 }
503
504 if (20480 / input_uv[16 * j + i + 8] % 10 > 4) {
505 tmp2++;
506 }
507
508 putreg32(tmp1 | tmp2 << 16, reg_base + MJPEG_Q_PARAM_40_OFFSET + (i * 4 + j) * 4);
509 }
510 }
511
512 regval = getreg32(reg_base + MJPEG_Q_ENC_OFFSET);
513 regval |= MJPEG_REG_Q_SRAM_SW;
514 putreg32(regval, reg_base + MJPEG_Q_ENC_OFFSET);
515 }
516
bflb_mjpeg_fill_jpeg_header_tail(struct bflb_device_s * dev,uint8_t * header,uint32_t header_len)517 void bflb_mjpeg_fill_jpeg_header_tail(struct bflb_device_s *dev, uint8_t *header, uint32_t header_len)
518 {
519 uint32_t regval;
520 uint32_t reg_base;
521
522 reg_base = dev->reg_base;
523
524 arch_memcpy_fast((void *)(reg_base + 0x800), header, header_len);
525
526 regval = getreg32(reg_base + MJPEG_HEADER_BYTE_OFFSET);
527 regval &= ~MJPEG_REG_HEAD_BYTE_MASK;
528 regval |= (header_len << MJPEG_REG_HEAD_BYTE_SHIFT);
529 regval |= MJPEG_REG_TAIL_EXP;
530 putreg32(regval, reg_base + MJPEG_HEADER_BYTE_OFFSET);
531 }
532
bflb_mjpeg_set_yuv420sp_cam_input(struct bflb_device_s * dev,uint8_t yy,uint8_t uv)533 void bflb_mjpeg_set_yuv420sp_cam_input(struct bflb_device_s *dev, uint8_t yy, uint8_t uv)
534 {
535 uint32_t regval;
536 uint32_t reg_base;
537
538 reg_base = dev->reg_base;
539
540 regval = getreg32(reg_base + MJPEG_CONTROL_2_OFFSET);
541 regval &= ~MJPEG_REG_YY_DVP2AXI_SEL_MASK;
542 regval &= ~MJPEG_REG_UV_DVP2AXI_SEL_MASK;
543 regval |= (yy << MJPEG_REG_YY_DVP2AXI_SEL_SHIFT);
544 regval |= (uv << MJPEG_REG_UV_DVP2AXI_SEL_SHIFT);
545 putreg32(regval, reg_base + MJPEG_CONTROL_2_OFFSET);
546 }
547
bflb_mjpeg_update_input_output_buff(struct bflb_device_s * dev,void * input_buf0,void * input_buf1,void * output_buff,size_t output_buff_size)548 void bflb_mjpeg_update_input_output_buff(struct bflb_device_s *dev, void *input_buf0, void *input_buf1, void *output_buff, size_t output_buff_size)
549 {
550 uint32_t reg_base;
551
552 reg_base = dev->reg_base;
553
554 if (input_buf0 != NULL) {
555 putreg32((uint32_t)input_buf0, reg_base + MJPEG_YY_FRAME_ADDR_OFFSET);
556 }
557
558 if (input_buf1 != NULL) {
559 putreg32((uint32_t)input_buf1, reg_base + MJPEG_UV_FRAME_ADDR_OFFSET);
560 }
561
562 if (output_buff != NULL) {
563 putreg32((uint32_t)output_buff, reg_base + MJPEG_JPEG_FRAME_ADDR_OFFSET);
564 putreg32((uint32_t)output_buff_size / 128, reg_base + MJPEG_JPEG_STORE_MEMORY_OFFSET);
565 }
566 }
567
bflb_mjpeg_feature_control(struct bflb_device_s * dev,int cmd,size_t arg)568 int bflb_mjpeg_feature_control(struct bflb_device_s *dev, int cmd, size_t arg)
569 {
570 int ret = 0;
571 uint32_t reg_base;
572
573 reg_base = dev->reg_base;
574
575 switch (cmd) {
576 case MJPEG_CMD_SET_INPUTADDR0:
577 putreg32(arg, reg_base + MJPEG_YY_FRAME_ADDR_OFFSET);
578 break;
579 case MJPEG_CMD_SET_INPUTADDR1:
580 putreg32(arg, reg_base + MJPEG_UV_FRAME_ADDR_OFFSET);
581 break;
582
583 default:
584 ret = -EPERM;
585 break;
586 }
587
588 return ret;
589 }