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 }