1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include "platform_support.h"
17
18#include "ia_css_inputfifo.h"
19
20#include "device_access.h"
21
22#define __INLINE_SP__
23#include "sp.h"
24#define __INLINE_ISP__
25#include "isp.h"
26#define __INLINE_IRQ__
27#include "irq.h"
28#define __INLINE_FIFO_MONITOR__
29#include "fifo_monitor.h"
30
31#define __INLINE_EVENT__
32#include "event_fifo.h"
33#define __INLINE_SP__
34
35#include "input_system.h"
36
37#include "assert_support.h"
38
39
40#include "sh_css_internal.h"
41#include "ia_css_isys.h"
42
43#define HBLANK_CYCLES (187)
44#define MARKER_CYCLES (6)
45
46#include <hive_isp_css_streaming_to_mipi_types_hrt.h>
47
48
49
50
51
52
53
54
55
56
57enum inputfifo_mipi_data_type {
58 inputfifo_mipi_data_type_regular,
59 inputfifo_mipi_data_type_yuv420,
60 inputfifo_mipi_data_type_yuv420_legacy,
61 inputfifo_mipi_data_type_rgb,
62};
63
64static unsigned int inputfifo_curr_ch_id, inputfifo_curr_fmt_type;
65struct inputfifo_instance {
66 unsigned int ch_id;
67 enum atomisp_input_format input_format;
68 bool two_ppc;
69 bool streaming;
70 unsigned int hblank_cycles;
71 unsigned int marker_cycles;
72 unsigned int fmt_type;
73 enum inputfifo_mipi_data_type type;
74};
75
76
77
78
79
80#define INPUTFIFO_NR_OF_S2M_CHANNELS (4)
81static struct inputfifo_instance
82 inputfifo_inst_admin[INPUTFIFO_NR_OF_S2M_CHANNELS];
83
84
85static unsigned int inputfifo_wrap_marker(
86
87 unsigned int marker)
88{
89 return marker |
90 (inputfifo_curr_ch_id << HIVE_STR_TO_MIPI_CH_ID_LSB) |
91 (inputfifo_curr_fmt_type << _HIVE_STR_TO_MIPI_FMT_TYPE_LSB);
92}
93
94static inline void
95_sh_css_fifo_snd(unsigned int token)
96{
97 while (!can_event_send_token(STR2MIPI_EVENT_ID))
98 udelay(1);
99 event_send_token(STR2MIPI_EVENT_ID, token);
100 return;
101}
102
103static void inputfifo_send_data_a(
104
105 unsigned int data)
106{
107 unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_A_BIT) |
108 (data << HIVE_STR_TO_MIPI_DATA_A_LSB);
109 _sh_css_fifo_snd(token);
110 return;
111}
112
113static void inputfifo_send_data_b(
114
115 unsigned int data)
116{
117 unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) |
118 (data << _HIVE_STR_TO_MIPI_DATA_B_LSB);
119 _sh_css_fifo_snd(token);
120 return;
121}
122
123static void inputfifo_send_data(
124
125 unsigned int a,
126 unsigned int b)
127{
128 unsigned int token = ((1 << HIVE_STR_TO_MIPI_VALID_A_BIT) |
129 (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) |
130 (a << HIVE_STR_TO_MIPI_DATA_A_LSB) |
131 (b << _HIVE_STR_TO_MIPI_DATA_B_LSB));
132 _sh_css_fifo_snd(token);
133 return;
134}
135
136static void inputfifo_send_sol(void)
137
138{
139 hrt_data token = inputfifo_wrap_marker(
140 1 << HIVE_STR_TO_MIPI_SOL_BIT);
141
142 _sh_css_fifo_snd(token);
143 return;
144}
145
146static void inputfifo_send_eol(void)
147
148{
149 hrt_data token = inputfifo_wrap_marker(
150 1 << HIVE_STR_TO_MIPI_EOL_BIT);
151 _sh_css_fifo_snd(token);
152 return;
153}
154
155static void inputfifo_send_sof(void)
156
157{
158 hrt_data token = inputfifo_wrap_marker(
159 1 << HIVE_STR_TO_MIPI_SOF_BIT);
160
161 _sh_css_fifo_snd(token);
162 return;
163}
164
165static void inputfifo_send_eof(void)
166
167{
168 hrt_data token = inputfifo_wrap_marker(
169 1 << HIVE_STR_TO_MIPI_EOF_BIT);
170 _sh_css_fifo_snd(token);
171 return;
172}
173
174static void inputfifo_send_ch_id_and_fmt_type(
175
176
177 unsigned int ch_id,
178 unsigned int fmt_type)
179{
180 hrt_data token;
181
182 inputfifo_curr_ch_id = ch_id & _HIVE_ISP_CH_ID_MASK;
183 inputfifo_curr_fmt_type = fmt_type & _HIVE_ISP_FMT_TYPE_MASK;
184
185
186
187 token = inputfifo_wrap_marker(0);
188 _sh_css_fifo_snd(token);
189 return;
190}
191
192static void inputfifo_send_empty_token(void)
193
194{
195 hrt_data token = inputfifo_wrap_marker(0);
196
197 _sh_css_fifo_snd(token);
198 return;
199}
200
201static void inputfifo_start_frame(
202
203 unsigned int ch_id,
204 unsigned int fmt_type)
205{
206 inputfifo_send_ch_id_and_fmt_type(ch_id, fmt_type);
207 inputfifo_send_sof();
208 return;
209}
210
211static void inputfifo_end_frame(
212 unsigned int marker_cycles)
213{
214 unsigned int i;
215
216 for (i = 0; i < marker_cycles; i++)
217 inputfifo_send_empty_token();
218 inputfifo_send_eof();
219 return;
220}
221
222static void inputfifo_send_line2(
223 const unsigned short *data,
224 unsigned int width,
225 const unsigned short *data2,
226 unsigned int width2,
227 unsigned int hblank_cycles,
228 unsigned int marker_cycles,
229 unsigned int two_ppc,
230 enum inputfifo_mipi_data_type type)
231{
232 unsigned int i, is_rgb = 0, is_legacy = 0;
233
234 assert(data);
235 assert((data2) || (width2 == 0));
236 if (type == inputfifo_mipi_data_type_rgb)
237 is_rgb = 1;
238
239 if (type == inputfifo_mipi_data_type_yuv420_legacy)
240 is_legacy = 1;
241
242 for (i = 0; i < hblank_cycles; i++)
243 inputfifo_send_empty_token();
244 inputfifo_send_sol();
245 for (i = 0; i < marker_cycles; i++)
246 inputfifo_send_empty_token();
247 for (i = 0; i < width; i++, data++) {
248
249
250
251
252 unsigned int send_two_pixels = two_ppc;
253
254 if ((is_rgb || is_legacy) && (i % 3 == 2))
255 send_two_pixels = 0;
256 if (send_two_pixels) {
257 if (i + 1 == width) {
258
259
260
261 inputfifo_send_data(
262 data[0], 0);
263 } else {
264 inputfifo_send_data(
265 data[0], data[1]);
266 }
267
268 data++;
269 i++;
270 } else if (two_ppc && is_legacy) {
271 inputfifo_send_data_b(data[0]);
272 } else {
273 inputfifo_send_data_a(data[0]);
274 }
275 }
276
277 for (i = 0; i < width2; i++, data2++) {
278
279
280
281
282 unsigned int send_two_pixels = two_ppc;
283
284 if ((is_rgb || is_legacy) && (i % 3 == 2))
285 send_two_pixels = 0;
286 if (send_two_pixels) {
287 if (i + 1 == width2) {
288
289
290
291 inputfifo_send_data(
292 data2[0], 0);
293 } else {
294 inputfifo_send_data(
295 data2[0], data2[1]);
296 }
297
298 data2++;
299 i++;
300 } else if (two_ppc && is_legacy) {
301 inputfifo_send_data_b(data2[0]);
302 } else {
303 inputfifo_send_data_a(data2[0]);
304 }
305 }
306 for (i = 0; i < hblank_cycles; i++)
307 inputfifo_send_empty_token();
308 inputfifo_send_eol();
309 return;
310}
311
312static void
313inputfifo_send_line(const unsigned short *data,
314 unsigned int width,
315 unsigned int hblank_cycles,
316 unsigned int marker_cycles,
317 unsigned int two_ppc,
318 enum inputfifo_mipi_data_type type)
319{
320 assert(data);
321 inputfifo_send_line2(data, width, NULL, 0,
322 hblank_cycles,
323 marker_cycles,
324 two_ppc,
325 type);
326}
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356static void inputfifo_send_frame(
357 const unsigned short *data,
358 unsigned int width,
359 unsigned int height,
360 unsigned int ch_id,
361 unsigned int fmt_type,
362 unsigned int hblank_cycles,
363 unsigned int marker_cycles,
364 unsigned int two_ppc,
365 enum inputfifo_mipi_data_type type)
366{
367 unsigned int i;
368
369 assert(data);
370 inputfifo_start_frame(ch_id, fmt_type);
371
372 for (i = 0; i < height; i++) {
373 if ((type == inputfifo_mipi_data_type_yuv420) &&
374 (i & 1) == 1) {
375 inputfifo_send_line(data, 2 * width,
376 hblank_cycles,
377 marker_cycles,
378 two_ppc, type);
379 data += 2 * width;
380 } else {
381 inputfifo_send_line(data, width,
382 hblank_cycles,
383 marker_cycles,
384 two_ppc, type);
385 data += width;
386 }
387 }
388 inputfifo_end_frame(marker_cycles);
389 return;
390}
391
392static enum inputfifo_mipi_data_type inputfifo_determine_type(
393 enum atomisp_input_format input_format)
394{
395 enum inputfifo_mipi_data_type type;
396
397 type = inputfifo_mipi_data_type_regular;
398 if (input_format == ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY) {
399 type =
400 inputfifo_mipi_data_type_yuv420_legacy;
401 } else if (input_format == ATOMISP_INPUT_FORMAT_YUV420_8 ||
402 input_format == ATOMISP_INPUT_FORMAT_YUV420_10 ||
403 input_format == ATOMISP_INPUT_FORMAT_YUV420_16) {
404 type =
405 inputfifo_mipi_data_type_yuv420;
406 } else if (input_format >= ATOMISP_INPUT_FORMAT_RGB_444 &&
407 input_format <= ATOMISP_INPUT_FORMAT_RGB_888) {
408 type =
409 inputfifo_mipi_data_type_rgb;
410 }
411 return type;
412}
413
414static struct inputfifo_instance *inputfifo_get_inst(
415 unsigned int ch_id)
416{
417 return &inputfifo_inst_admin[ch_id];
418}
419
420void ia_css_inputfifo_send_input_frame(
421 const unsigned short *data,
422 unsigned int width,
423 unsigned int height,
424 unsigned int ch_id,
425 enum atomisp_input_format input_format,
426 bool two_ppc)
427{
428 unsigned int fmt_type, hblank_cycles, marker_cycles;
429 enum inputfifo_mipi_data_type type;
430
431 assert(data);
432 hblank_cycles = HBLANK_CYCLES;
433 marker_cycles = MARKER_CYCLES;
434 ia_css_isys_convert_stream_format_to_mipi_format(input_format,
435 MIPI_PREDICTOR_NONE,
436 &fmt_type);
437
438 type = inputfifo_determine_type(input_format);
439
440 inputfifo_send_frame(data, width, height,
441 ch_id, fmt_type, hblank_cycles, marker_cycles,
442 two_ppc, type);
443}
444
445void ia_css_inputfifo_start_frame(
446 unsigned int ch_id,
447 enum atomisp_input_format input_format,
448 bool two_ppc)
449{
450 struct inputfifo_instance *s2mi;
451
452 s2mi = inputfifo_get_inst(ch_id);
453
454 s2mi->ch_id = ch_id;
455 ia_css_isys_convert_stream_format_to_mipi_format(input_format,
456 MIPI_PREDICTOR_NONE,
457 &s2mi->fmt_type);
458 s2mi->two_ppc = two_ppc;
459 s2mi->type = inputfifo_determine_type(input_format);
460 s2mi->hblank_cycles = HBLANK_CYCLES;
461 s2mi->marker_cycles = MARKER_CYCLES;
462 s2mi->streaming = true;
463
464 inputfifo_start_frame(ch_id, s2mi->fmt_type);
465 return;
466}
467
468void ia_css_inputfifo_send_line(
469 unsigned int ch_id,
470 const unsigned short *data,
471 unsigned int width,
472 const unsigned short *data2,
473 unsigned int width2)
474{
475 struct inputfifo_instance *s2mi;
476
477 assert(data);
478 assert((data2) || (width2 == 0));
479 s2mi = inputfifo_get_inst(ch_id);
480
481
482 inputfifo_curr_ch_id = (s2mi->ch_id) & _HIVE_ISP_CH_ID_MASK;
483 inputfifo_curr_fmt_type = (s2mi->fmt_type) & _HIVE_ISP_FMT_TYPE_MASK;
484
485 inputfifo_send_line2(data, width, data2, width2,
486 s2mi->hblank_cycles,
487 s2mi->marker_cycles,
488 s2mi->two_ppc,
489 s2mi->type);
490}
491
492void ia_css_inputfifo_send_embedded_line(
493 unsigned int ch_id,
494 enum atomisp_input_format data_type,
495 const unsigned short *data,
496 unsigned int width)
497{
498 struct inputfifo_instance *s2mi;
499 unsigned int fmt_type;
500
501 assert(data);
502 s2mi = inputfifo_get_inst(ch_id);
503 ia_css_isys_convert_stream_format_to_mipi_format(data_type,
504 MIPI_PREDICTOR_NONE, &fmt_type);
505
506
507 inputfifo_curr_fmt_type = fmt_type & _HIVE_ISP_FMT_TYPE_MASK;
508
509 inputfifo_send_line(data, width, s2mi->hblank_cycles, s2mi->marker_cycles,
510 s2mi->two_ppc, inputfifo_mipi_data_type_regular);
511}
512
513void ia_css_inputfifo_end_frame(
514 unsigned int ch_id)
515{
516 struct inputfifo_instance *s2mi;
517
518 s2mi = inputfifo_get_inst(ch_id);
519
520
521 inputfifo_curr_ch_id = (s2mi->ch_id) & _HIVE_ISP_CH_ID_MASK;
522 inputfifo_curr_fmt_type = (s2mi->fmt_type) & _HIVE_ISP_FMT_TYPE_MASK;
523
524
525 inputfifo_end_frame(s2mi->marker_cycles);
526
527 s2mi->streaming = false;
528 return;
529}
530