19d4fa1a1SMauro Carvalho Chehab /* 29d4fa1a1SMauro Carvalho Chehab * Support for Intel Camera Imaging ISP subsystem. 33c0538fbSMauro Carvalho Chehab * Copyright (c) 2010 - 2015, Intel Corporation. 49d4fa1a1SMauro Carvalho Chehab * 59d4fa1a1SMauro Carvalho Chehab * This program is free software; you can redistribute it and/or modify it 69d4fa1a1SMauro Carvalho Chehab * under the terms and conditions of the GNU General Public License, 79d4fa1a1SMauro Carvalho Chehab * version 2, as published by the Free Software Foundation. 89d4fa1a1SMauro Carvalho Chehab * 99d4fa1a1SMauro Carvalho Chehab * This program is distributed in the hope it will be useful, but WITHOUT 109d4fa1a1SMauro Carvalho Chehab * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 119d4fa1a1SMauro Carvalho Chehab * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 129d4fa1a1SMauro Carvalho Chehab * more details. 139d4fa1a1SMauro Carvalho Chehab */ 149d4fa1a1SMauro Carvalho Chehab 159d4fa1a1SMauro Carvalho Chehab #include "platform_support.h" 169d4fa1a1SMauro Carvalho Chehab 179d4fa1a1SMauro Carvalho Chehab #include "ia_css_inputfifo.h" 189d4fa1a1SMauro Carvalho Chehab 199d4fa1a1SMauro Carvalho Chehab #include "device_access.h" 209d4fa1a1SMauro Carvalho Chehab 219d4fa1a1SMauro Carvalho Chehab #define __INLINE_SP__ 229d4fa1a1SMauro Carvalho Chehab #include "sp.h" 239d4fa1a1SMauro Carvalho Chehab #define __INLINE_ISP__ 249d4fa1a1SMauro Carvalho Chehab #include "isp.h" 259d4fa1a1SMauro Carvalho Chehab #define __INLINE_IRQ__ 269d4fa1a1SMauro Carvalho Chehab #include "irq.h" 279d4fa1a1SMauro Carvalho Chehab #define __INLINE_FIFO_MONITOR__ 289d4fa1a1SMauro Carvalho Chehab #include "fifo_monitor.h" 299d4fa1a1SMauro Carvalho Chehab 309d4fa1a1SMauro Carvalho Chehab #define __INLINE_EVENT__ 319d4fa1a1SMauro Carvalho Chehab #include "event_fifo.h" 329d4fa1a1SMauro Carvalho Chehab #define __INLINE_SP__ 339d4fa1a1SMauro Carvalho Chehab 349d4fa1a1SMauro Carvalho Chehab #if !defined(HAS_NO_INPUT_SYSTEM) 359d4fa1a1SMauro Carvalho Chehab #include "input_system.h" /* MIPI_PREDICTOR_NONE,... */ 369d4fa1a1SMauro Carvalho Chehab #endif 379d4fa1a1SMauro Carvalho Chehab 389d4fa1a1SMauro Carvalho Chehab #include "assert_support.h" 399d4fa1a1SMauro Carvalho Chehab 409d4fa1a1SMauro Carvalho Chehab /* System independent */ 419d4fa1a1SMauro Carvalho Chehab #include "sh_css_internal.h" 429d4fa1a1SMauro Carvalho Chehab #if !defined(HAS_NO_INPUT_SYSTEM) 439d4fa1a1SMauro Carvalho Chehab #include "ia_css_isys.h" 449d4fa1a1SMauro Carvalho Chehab #endif 459d4fa1a1SMauro Carvalho Chehab 469d4fa1a1SMauro Carvalho Chehab #define HBLANK_CYCLES (187) 479d4fa1a1SMauro Carvalho Chehab #define MARKER_CYCLES (6) 489d4fa1a1SMauro Carvalho Chehab 499d4fa1a1SMauro Carvalho Chehab #if !defined(HAS_NO_INPUT_SYSTEM) 509d4fa1a1SMauro Carvalho Chehab #include <hive_isp_css_streaming_to_mipi_types_hrt.h> 519d4fa1a1SMauro Carvalho Chehab #endif 529d4fa1a1SMauro Carvalho Chehab 539d4fa1a1SMauro Carvalho Chehab /* The data type is used to send special cases: 549d4fa1a1SMauro Carvalho Chehab * yuv420: odd lines (1, 3 etc) are twice as wide as even 559d4fa1a1SMauro Carvalho Chehab * lines (0, 2, 4 etc). 569d4fa1a1SMauro Carvalho Chehab * rgb: for two pixels per clock, the R and B values are sent 579d4fa1a1SMauro Carvalho Chehab * to output_0 while only G is sent to output_1. This means 589d4fa1a1SMauro Carvalho Chehab * that output_1 only gets half the number of values of output_0. 599d4fa1a1SMauro Carvalho Chehab * WARNING: This type should also be used for Legacy YUV420. 609d4fa1a1SMauro Carvalho Chehab * regular: used for all other data types (RAW, YUV422, etc) 619d4fa1a1SMauro Carvalho Chehab */ 629d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type { 639d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_regular, 649d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_yuv420, 659d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_yuv420_legacy, 669d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_rgb, 679d4fa1a1SMauro Carvalho Chehab }; 689d4fa1a1SMauro Carvalho Chehab 699d4fa1a1SMauro Carvalho Chehab #if !defined(HAS_NO_INPUT_SYSTEM) 709d4fa1a1SMauro Carvalho Chehab static unsigned int inputfifo_curr_ch_id, inputfifo_curr_fmt_type; 719d4fa1a1SMauro Carvalho Chehab #endif 729d4fa1a1SMauro Carvalho Chehab struct inputfifo_instance { 739d4fa1a1SMauro Carvalho Chehab unsigned int ch_id; 749d4fa1a1SMauro Carvalho Chehab enum atomisp_input_format input_format; 759d4fa1a1SMauro Carvalho Chehab bool two_ppc; 769d4fa1a1SMauro Carvalho Chehab bool streaming; 779d4fa1a1SMauro Carvalho Chehab unsigned int hblank_cycles; 789d4fa1a1SMauro Carvalho Chehab unsigned int marker_cycles; 799d4fa1a1SMauro Carvalho Chehab unsigned int fmt_type; 809d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type type; 819d4fa1a1SMauro Carvalho Chehab }; 829d4fa1a1SMauro Carvalho Chehab 839d4fa1a1SMauro Carvalho Chehab #if !defined(HAS_NO_INPUT_SYSTEM) 849d4fa1a1SMauro Carvalho Chehab /* 859d4fa1a1SMauro Carvalho Chehab * Maintain a basic streaming to Mipi administration with ch_id as index 869d4fa1a1SMauro Carvalho Chehab * ch_id maps on the "Mipi virtual channel ID" and can have value 0..3 879d4fa1a1SMauro Carvalho Chehab */ 889d4fa1a1SMauro Carvalho Chehab #define INPUTFIFO_NR_OF_S2M_CHANNELS (4) 899d4fa1a1SMauro Carvalho Chehab static struct inputfifo_instance 909d4fa1a1SMauro Carvalho Chehab inputfifo_inst_admin[INPUTFIFO_NR_OF_S2M_CHANNELS]; 919d4fa1a1SMauro Carvalho Chehab 929d4fa1a1SMauro Carvalho Chehab /* Streaming to MIPI */ 939d4fa1a1SMauro Carvalho Chehab static unsigned int inputfifo_wrap_marker( 949d4fa1a1SMauro Carvalho Chehab /* static inline unsigned inputfifo_wrap_marker( */ 959d4fa1a1SMauro Carvalho Chehab unsigned int marker) 969d4fa1a1SMauro Carvalho Chehab { 979d4fa1a1SMauro Carvalho Chehab return marker | 989d4fa1a1SMauro Carvalho Chehab (inputfifo_curr_ch_id << HIVE_STR_TO_MIPI_CH_ID_LSB) | 999d4fa1a1SMauro Carvalho Chehab (inputfifo_curr_fmt_type << _HIVE_STR_TO_MIPI_FMT_TYPE_LSB); 1009d4fa1a1SMauro Carvalho Chehab } 1019d4fa1a1SMauro Carvalho Chehab 1029d4fa1a1SMauro Carvalho Chehab static inline void 1039d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(unsigned int token) 1049d4fa1a1SMauro Carvalho Chehab { 1059d4fa1a1SMauro Carvalho Chehab while (!can_event_send_token(STR2MIPI_EVENT_ID)) 1069d4fa1a1SMauro Carvalho Chehab hrt_sleep(); 1079d4fa1a1SMauro Carvalho Chehab event_send_token(STR2MIPI_EVENT_ID, token); 1089d4fa1a1SMauro Carvalho Chehab return; 1099d4fa1a1SMauro Carvalho Chehab } 1109d4fa1a1SMauro Carvalho Chehab 1119d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_data_a( 1129d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_data_a( */ 1139d4fa1a1SMauro Carvalho Chehab unsigned int data) 1149d4fa1a1SMauro Carvalho Chehab { 1159d4fa1a1SMauro Carvalho Chehab unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_A_BIT) | 1169d4fa1a1SMauro Carvalho Chehab (data << HIVE_STR_TO_MIPI_DATA_A_LSB); 1179d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1189d4fa1a1SMauro Carvalho Chehab return; 1199d4fa1a1SMauro Carvalho Chehab } 1209d4fa1a1SMauro Carvalho Chehab 1219d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_data_b( 1229d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_data_b( */ 1239d4fa1a1SMauro Carvalho Chehab unsigned int data) 1249d4fa1a1SMauro Carvalho Chehab { 1259d4fa1a1SMauro Carvalho Chehab unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) | 1269d4fa1a1SMauro Carvalho Chehab (data << _HIVE_STR_TO_MIPI_DATA_B_LSB); 1279d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1289d4fa1a1SMauro Carvalho Chehab return; 1299d4fa1a1SMauro Carvalho Chehab } 1309d4fa1a1SMauro Carvalho Chehab 1319d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_data( 1329d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_data( */ 1339d4fa1a1SMauro Carvalho Chehab unsigned int a, 1349d4fa1a1SMauro Carvalho Chehab unsigned int b) 1359d4fa1a1SMauro Carvalho Chehab { 1369d4fa1a1SMauro Carvalho Chehab unsigned int token = ((1 << HIVE_STR_TO_MIPI_VALID_A_BIT) | 1379d4fa1a1SMauro Carvalho Chehab (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) | 1389d4fa1a1SMauro Carvalho Chehab (a << HIVE_STR_TO_MIPI_DATA_A_LSB) | 1399d4fa1a1SMauro Carvalho Chehab (b << _HIVE_STR_TO_MIPI_DATA_B_LSB)); 1409d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1419d4fa1a1SMauro Carvalho Chehab return; 1429d4fa1a1SMauro Carvalho Chehab } 1439d4fa1a1SMauro Carvalho Chehab 1449d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_sol(void) 1459d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_sol(void) */ 1469d4fa1a1SMauro Carvalho Chehab { 1479d4fa1a1SMauro Carvalho Chehab hrt_data token = inputfifo_wrap_marker( 1489d4fa1a1SMauro Carvalho Chehab 1 << HIVE_STR_TO_MIPI_SOL_BIT); 1499d4fa1a1SMauro Carvalho Chehab 1509d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1519d4fa1a1SMauro Carvalho Chehab return; 1529d4fa1a1SMauro Carvalho Chehab } 1539d4fa1a1SMauro Carvalho Chehab 1549d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_eol(void) 1559d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_eol(void) */ 1569d4fa1a1SMauro Carvalho Chehab { 1579d4fa1a1SMauro Carvalho Chehab hrt_data token = inputfifo_wrap_marker( 1589d4fa1a1SMauro Carvalho Chehab 1 << HIVE_STR_TO_MIPI_EOL_BIT); 1599d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1609d4fa1a1SMauro Carvalho Chehab return; 1619d4fa1a1SMauro Carvalho Chehab } 1629d4fa1a1SMauro Carvalho Chehab 1639d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_sof(void) 1649d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_sof(void) */ 1659d4fa1a1SMauro Carvalho Chehab { 1669d4fa1a1SMauro Carvalho Chehab hrt_data token = inputfifo_wrap_marker( 1679d4fa1a1SMauro Carvalho Chehab 1 << HIVE_STR_TO_MIPI_SOF_BIT); 1689d4fa1a1SMauro Carvalho Chehab 1699d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1709d4fa1a1SMauro Carvalho Chehab return; 1719d4fa1a1SMauro Carvalho Chehab } 1729d4fa1a1SMauro Carvalho Chehab 1739d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_eof(void) 1749d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_eof(void) */ 1759d4fa1a1SMauro Carvalho Chehab { 1769d4fa1a1SMauro Carvalho Chehab hrt_data token = inputfifo_wrap_marker( 1779d4fa1a1SMauro Carvalho Chehab 1 << HIVE_STR_TO_MIPI_EOF_BIT); 1789d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1799d4fa1a1SMauro Carvalho Chehab return; 1809d4fa1a1SMauro Carvalho Chehab } 1819d4fa1a1SMauro Carvalho Chehab 1829d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_ch_id_and_fmt_type( 1839d4fa1a1SMauro Carvalho Chehab /* static inline 1849d4fa1a1SMauro Carvalho Chehab void inputfifo_send_ch_id_and_fmt_type( */ 1859d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 1869d4fa1a1SMauro Carvalho Chehab unsigned int fmt_type) 1879d4fa1a1SMauro Carvalho Chehab { 1889d4fa1a1SMauro Carvalho Chehab hrt_data token; 1899d4fa1a1SMauro Carvalho Chehab 1909d4fa1a1SMauro Carvalho Chehab inputfifo_curr_ch_id = ch_id & _HIVE_ISP_CH_ID_MASK; 1919d4fa1a1SMauro Carvalho Chehab inputfifo_curr_fmt_type = fmt_type & _HIVE_ISP_FMT_TYPE_MASK; 1929d4fa1a1SMauro Carvalho Chehab /* we send an zero marker, this will wrap the ch_id and 1939d4fa1a1SMauro Carvalho Chehab * fmt_type automatically. 1949d4fa1a1SMauro Carvalho Chehab */ 1959d4fa1a1SMauro Carvalho Chehab token = inputfifo_wrap_marker(0); 1969d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 1979d4fa1a1SMauro Carvalho Chehab return; 1989d4fa1a1SMauro Carvalho Chehab } 1999d4fa1a1SMauro Carvalho Chehab 2009d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_empty_token(void) 2019d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_send_empty_token(void) */ 2029d4fa1a1SMauro Carvalho Chehab { 2039d4fa1a1SMauro Carvalho Chehab hrt_data token = inputfifo_wrap_marker(0); 2049d4fa1a1SMauro Carvalho Chehab 2059d4fa1a1SMauro Carvalho Chehab _sh_css_fifo_snd(token); 2069d4fa1a1SMauro Carvalho Chehab return; 2079d4fa1a1SMauro Carvalho Chehab } 2089d4fa1a1SMauro Carvalho Chehab 2099d4fa1a1SMauro Carvalho Chehab static void inputfifo_start_frame( 2109d4fa1a1SMauro Carvalho Chehab /* static inline void inputfifo_start_frame( */ 2119d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 2129d4fa1a1SMauro Carvalho Chehab unsigned int fmt_type) 2139d4fa1a1SMauro Carvalho Chehab { 2149d4fa1a1SMauro Carvalho Chehab inputfifo_send_ch_id_and_fmt_type(ch_id, fmt_type); 2159d4fa1a1SMauro Carvalho Chehab inputfifo_send_sof(); 2169d4fa1a1SMauro Carvalho Chehab return; 2179d4fa1a1SMauro Carvalho Chehab } 2189d4fa1a1SMauro Carvalho Chehab 2199d4fa1a1SMauro Carvalho Chehab static void inputfifo_end_frame( 2209d4fa1a1SMauro Carvalho Chehab unsigned int marker_cycles) 2219d4fa1a1SMauro Carvalho Chehab { 2229d4fa1a1SMauro Carvalho Chehab unsigned int i; 2239d4fa1a1SMauro Carvalho Chehab 2249d4fa1a1SMauro Carvalho Chehab for (i = 0; i < marker_cycles; i++) 2259d4fa1a1SMauro Carvalho Chehab inputfifo_send_empty_token(); 2269d4fa1a1SMauro Carvalho Chehab inputfifo_send_eof(); 2279d4fa1a1SMauro Carvalho Chehab return; 2289d4fa1a1SMauro Carvalho Chehab } 2299d4fa1a1SMauro Carvalho Chehab 2309d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_line2( 2319d4fa1a1SMauro Carvalho Chehab const unsigned short *data, 2329d4fa1a1SMauro Carvalho Chehab unsigned int width, 2339d4fa1a1SMauro Carvalho Chehab const unsigned short *data2, 2349d4fa1a1SMauro Carvalho Chehab unsigned int width2, 2359d4fa1a1SMauro Carvalho Chehab unsigned int hblank_cycles, 2369d4fa1a1SMauro Carvalho Chehab unsigned int marker_cycles, 2379d4fa1a1SMauro Carvalho Chehab unsigned int two_ppc, 2389d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type type) 2399d4fa1a1SMauro Carvalho Chehab { 2409d4fa1a1SMauro Carvalho Chehab unsigned int i, is_rgb = 0, is_legacy = 0; 2419d4fa1a1SMauro Carvalho Chehab 2429d4fa1a1SMauro Carvalho Chehab assert(data); 2439d4fa1a1SMauro Carvalho Chehab assert((data2) || (width2 == 0)); 2449d4fa1a1SMauro Carvalho Chehab if (type == inputfifo_mipi_data_type_rgb) 2459d4fa1a1SMauro Carvalho Chehab is_rgb = 1; 2469d4fa1a1SMauro Carvalho Chehab 2479d4fa1a1SMauro Carvalho Chehab if (type == inputfifo_mipi_data_type_yuv420_legacy) 2489d4fa1a1SMauro Carvalho Chehab is_legacy = 1; 2499d4fa1a1SMauro Carvalho Chehab 2509d4fa1a1SMauro Carvalho Chehab for (i = 0; i < hblank_cycles; i++) 2519d4fa1a1SMauro Carvalho Chehab inputfifo_send_empty_token(); 2529d4fa1a1SMauro Carvalho Chehab inputfifo_send_sol(); 2539d4fa1a1SMauro Carvalho Chehab for (i = 0; i < marker_cycles; i++) 2549d4fa1a1SMauro Carvalho Chehab inputfifo_send_empty_token(); 2559d4fa1a1SMauro Carvalho Chehab for (i = 0; i < width; i++, data++) { 2569d4fa1a1SMauro Carvalho Chehab /* for RGB in two_ppc, we only actually send 2 pixels per 2579d4fa1a1SMauro Carvalho Chehab * clock in the even pixels (0, 2 etc). In the other cycles, 2589d4fa1a1SMauro Carvalho Chehab * we only send 1 pixel, to data[0]. 2599d4fa1a1SMauro Carvalho Chehab */ 2609d4fa1a1SMauro Carvalho Chehab unsigned int send_two_pixels = two_ppc; 2619d4fa1a1SMauro Carvalho Chehab 2629d4fa1a1SMauro Carvalho Chehab if ((is_rgb || is_legacy) && (i % 3 == 2)) 2639d4fa1a1SMauro Carvalho Chehab send_two_pixels = 0; 2649d4fa1a1SMauro Carvalho Chehab if (send_two_pixels) { 2659d4fa1a1SMauro Carvalho Chehab if (i + 1 == width) { 2669d4fa1a1SMauro Carvalho Chehab /* for jpg (binary) copy, this can occur 2679d4fa1a1SMauro Carvalho Chehab * if the file contains an odd number of bytes. 2689d4fa1a1SMauro Carvalho Chehab */ 2699d4fa1a1SMauro Carvalho Chehab inputfifo_send_data( 2709d4fa1a1SMauro Carvalho Chehab data[0], 0); 2719d4fa1a1SMauro Carvalho Chehab } else { 2729d4fa1a1SMauro Carvalho Chehab inputfifo_send_data( 2739d4fa1a1SMauro Carvalho Chehab data[0], data[1]); 2749d4fa1a1SMauro Carvalho Chehab } 2759d4fa1a1SMauro Carvalho Chehab /* Additional increment because we send 2 pixels */ 2769d4fa1a1SMauro Carvalho Chehab data++; 2779d4fa1a1SMauro Carvalho Chehab i++; 2789d4fa1a1SMauro Carvalho Chehab } else if (two_ppc && is_legacy) { 2799d4fa1a1SMauro Carvalho Chehab inputfifo_send_data_b(data[0]); 2809d4fa1a1SMauro Carvalho Chehab } else { 2819d4fa1a1SMauro Carvalho Chehab inputfifo_send_data_a(data[0]); 2829d4fa1a1SMauro Carvalho Chehab } 2839d4fa1a1SMauro Carvalho Chehab } 2849d4fa1a1SMauro Carvalho Chehab 2859d4fa1a1SMauro Carvalho Chehab for (i = 0; i < width2; i++, data2++) { 2869d4fa1a1SMauro Carvalho Chehab /* for RGB in two_ppc, we only actually send 2 pixels per 2879d4fa1a1SMauro Carvalho Chehab * clock in the even pixels (0, 2 etc). In the other cycles, 2889d4fa1a1SMauro Carvalho Chehab * we only send 1 pixel, to data2[0]. 2899d4fa1a1SMauro Carvalho Chehab */ 2909d4fa1a1SMauro Carvalho Chehab unsigned int send_two_pixels = two_ppc; 2919d4fa1a1SMauro Carvalho Chehab 2929d4fa1a1SMauro Carvalho Chehab if ((is_rgb || is_legacy) && (i % 3 == 2)) 2939d4fa1a1SMauro Carvalho Chehab send_two_pixels = 0; 2949d4fa1a1SMauro Carvalho Chehab if (send_two_pixels) { 2959d4fa1a1SMauro Carvalho Chehab if (i + 1 == width2) { 2969d4fa1a1SMauro Carvalho Chehab /* for jpg (binary) copy, this can occur 2979d4fa1a1SMauro Carvalho Chehab * if the file contains an odd number of bytes. 2989d4fa1a1SMauro Carvalho Chehab */ 2999d4fa1a1SMauro Carvalho Chehab inputfifo_send_data( 3009d4fa1a1SMauro Carvalho Chehab data2[0], 0); 3019d4fa1a1SMauro Carvalho Chehab } else { 3029d4fa1a1SMauro Carvalho Chehab inputfifo_send_data( 3039d4fa1a1SMauro Carvalho Chehab data2[0], data2[1]); 3049d4fa1a1SMauro Carvalho Chehab } 3059d4fa1a1SMauro Carvalho Chehab /* Additional increment because we send 2 pixels */ 3069d4fa1a1SMauro Carvalho Chehab data2++; 3079d4fa1a1SMauro Carvalho Chehab i++; 3089d4fa1a1SMauro Carvalho Chehab } else if (two_ppc && is_legacy) { 3099d4fa1a1SMauro Carvalho Chehab inputfifo_send_data_b(data2[0]); 3109d4fa1a1SMauro Carvalho Chehab } else { 3119d4fa1a1SMauro Carvalho Chehab inputfifo_send_data_a(data2[0]); 3129d4fa1a1SMauro Carvalho Chehab } 3139d4fa1a1SMauro Carvalho Chehab } 3149d4fa1a1SMauro Carvalho Chehab for (i = 0; i < hblank_cycles; i++) 3159d4fa1a1SMauro Carvalho Chehab inputfifo_send_empty_token(); 3169d4fa1a1SMauro Carvalho Chehab inputfifo_send_eol(); 3179d4fa1a1SMauro Carvalho Chehab return; 3189d4fa1a1SMauro Carvalho Chehab } 3199d4fa1a1SMauro Carvalho Chehab 3209d4fa1a1SMauro Carvalho Chehab static void 3219d4fa1a1SMauro Carvalho Chehab inputfifo_send_line(const unsigned short *data, 3229d4fa1a1SMauro Carvalho Chehab unsigned int width, 3239d4fa1a1SMauro Carvalho Chehab unsigned int hblank_cycles, 3249d4fa1a1SMauro Carvalho Chehab unsigned int marker_cycles, 3259d4fa1a1SMauro Carvalho Chehab unsigned int two_ppc, 3269d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type type) 3279d4fa1a1SMauro Carvalho Chehab { 3289d4fa1a1SMauro Carvalho Chehab assert(data); 3299d4fa1a1SMauro Carvalho Chehab inputfifo_send_line2(data, width, NULL, 0, 3309d4fa1a1SMauro Carvalho Chehab hblank_cycles, 3319d4fa1a1SMauro Carvalho Chehab marker_cycles, 3329d4fa1a1SMauro Carvalho Chehab two_ppc, 3339d4fa1a1SMauro Carvalho Chehab type); 3349d4fa1a1SMauro Carvalho Chehab } 3359d4fa1a1SMauro Carvalho Chehab 3369d4fa1a1SMauro Carvalho Chehab /* Send a frame of data into the input network via the GP FIFO. 3379d4fa1a1SMauro Carvalho Chehab * Parameters: 3389d4fa1a1SMauro Carvalho Chehab * - data: array of 16 bit values that contains all data for the frame. 3399d4fa1a1SMauro Carvalho Chehab * - width: width of a line in number of subpixels, for yuv420 it is the 3409d4fa1a1SMauro Carvalho Chehab * number of Y components per line. 3419d4fa1a1SMauro Carvalho Chehab * - height: height of the frame in number of lines. 3429d4fa1a1SMauro Carvalho Chehab * - ch_id: channel ID. 3439d4fa1a1SMauro Carvalho Chehab * - fmt_type: format type. 3449d4fa1a1SMauro Carvalho Chehab * - hblank_cycles: length of horizontal blanking in cycles. 3459d4fa1a1SMauro Carvalho Chehab * - marker_cycles: number of empty cycles after start-of-line and before 3469d4fa1a1SMauro Carvalho Chehab * end-of-frame. 3479d4fa1a1SMauro Carvalho Chehab * - two_ppc: boolean, describes whether to send one or two pixels per clock 3489d4fa1a1SMauro Carvalho Chehab * cycle. In this mode, we sent pixels N and N+1 in the same cycle, 3499d4fa1a1SMauro Carvalho Chehab * to IF_PRIM_A and IF_PRIM_B respectively. The caller must make 3509d4fa1a1SMauro Carvalho Chehab * sure the input data has been formatted correctly for this. 3519d4fa1a1SMauro Carvalho Chehab * For example, for RGB formats this means that unused values 3529d4fa1a1SMauro Carvalho Chehab * must be inserted. 3539d4fa1a1SMauro Carvalho Chehab * - yuv420: boolean, describes whether (non-legacy) yuv420 data is used. In 3549d4fa1a1SMauro Carvalho Chehab * this mode, the odd lines (1,3,5 etc) are half as long as the 3559d4fa1a1SMauro Carvalho Chehab * even lines (2,4,6 etc). 3569d4fa1a1SMauro Carvalho Chehab * Note that the first line is odd (1) and the second line is even 3579d4fa1a1SMauro Carvalho Chehab * (2). 3589d4fa1a1SMauro Carvalho Chehab * 3599d4fa1a1SMauro Carvalho Chehab * This function does not do any reordering of pixels, the caller must make 3609d4fa1a1SMauro Carvalho Chehab * sure the data is in the righ format. Please refer to the CSS receiver 3619d4fa1a1SMauro Carvalho Chehab * documentation for details on the data formats. 3629d4fa1a1SMauro Carvalho Chehab */ 3639d4fa1a1SMauro Carvalho Chehab 3649d4fa1a1SMauro Carvalho Chehab static void inputfifo_send_frame( 3659d4fa1a1SMauro Carvalho Chehab const unsigned short *data, 3669d4fa1a1SMauro Carvalho Chehab unsigned int width, 3679d4fa1a1SMauro Carvalho Chehab unsigned int height, 3689d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 3699d4fa1a1SMauro Carvalho Chehab unsigned int fmt_type, 3709d4fa1a1SMauro Carvalho Chehab unsigned int hblank_cycles, 3719d4fa1a1SMauro Carvalho Chehab unsigned int marker_cycles, 3729d4fa1a1SMauro Carvalho Chehab unsigned int two_ppc, 3739d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type type) 3749d4fa1a1SMauro Carvalho Chehab { 3759d4fa1a1SMauro Carvalho Chehab unsigned int i; 3769d4fa1a1SMauro Carvalho Chehab 3779d4fa1a1SMauro Carvalho Chehab assert(data); 3789d4fa1a1SMauro Carvalho Chehab inputfifo_start_frame(ch_id, fmt_type); 3799d4fa1a1SMauro Carvalho Chehab 3809d4fa1a1SMauro Carvalho Chehab for (i = 0; i < height; i++) { 3819d4fa1a1SMauro Carvalho Chehab if ((type == inputfifo_mipi_data_type_yuv420) && 3829d4fa1a1SMauro Carvalho Chehab (i & 1) == 1) { 3839d4fa1a1SMauro Carvalho Chehab inputfifo_send_line(data, 2 * width, 3849d4fa1a1SMauro Carvalho Chehab hblank_cycles, 3859d4fa1a1SMauro Carvalho Chehab marker_cycles, 3869d4fa1a1SMauro Carvalho Chehab two_ppc, type); 3879d4fa1a1SMauro Carvalho Chehab data += 2 * width; 3889d4fa1a1SMauro Carvalho Chehab } else { 3899d4fa1a1SMauro Carvalho Chehab inputfifo_send_line(data, width, 3909d4fa1a1SMauro Carvalho Chehab hblank_cycles, 3919d4fa1a1SMauro Carvalho Chehab marker_cycles, 3929d4fa1a1SMauro Carvalho Chehab two_ppc, type); 3939d4fa1a1SMauro Carvalho Chehab data += width; 3949d4fa1a1SMauro Carvalho Chehab } 3959d4fa1a1SMauro Carvalho Chehab } 3969d4fa1a1SMauro Carvalho Chehab inputfifo_end_frame(marker_cycles); 3979d4fa1a1SMauro Carvalho Chehab return; 3989d4fa1a1SMauro Carvalho Chehab } 3999d4fa1a1SMauro Carvalho Chehab 4009d4fa1a1SMauro Carvalho Chehab static enum inputfifo_mipi_data_type inputfifo_determine_type( 4019d4fa1a1SMauro Carvalho Chehab enum atomisp_input_format input_format) 4029d4fa1a1SMauro Carvalho Chehab { 4039d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type type; 4049d4fa1a1SMauro Carvalho Chehab 4059d4fa1a1SMauro Carvalho Chehab type = inputfifo_mipi_data_type_regular; 4069d4fa1a1SMauro Carvalho Chehab if (input_format == ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY) { 4079d4fa1a1SMauro Carvalho Chehab type = 4089d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_yuv420_legacy; 4099d4fa1a1SMauro Carvalho Chehab } else if (input_format == ATOMISP_INPUT_FORMAT_YUV420_8 || 4109d4fa1a1SMauro Carvalho Chehab input_format == ATOMISP_INPUT_FORMAT_YUV420_10 || 4119d4fa1a1SMauro Carvalho Chehab input_format == ATOMISP_INPUT_FORMAT_YUV420_16) { 4129d4fa1a1SMauro Carvalho Chehab type = 4139d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_yuv420; 4149d4fa1a1SMauro Carvalho Chehab } else if (input_format >= ATOMISP_INPUT_FORMAT_RGB_444 && 4159d4fa1a1SMauro Carvalho Chehab input_format <= ATOMISP_INPUT_FORMAT_RGB_888) { 4169d4fa1a1SMauro Carvalho Chehab type = 4179d4fa1a1SMauro Carvalho Chehab inputfifo_mipi_data_type_rgb; 4189d4fa1a1SMauro Carvalho Chehab } 4199d4fa1a1SMauro Carvalho Chehab return type; 4209d4fa1a1SMauro Carvalho Chehab } 4219d4fa1a1SMauro Carvalho Chehab 4229d4fa1a1SMauro Carvalho Chehab static struct inputfifo_instance *inputfifo_get_inst( 4239d4fa1a1SMauro Carvalho Chehab unsigned int ch_id) 4249d4fa1a1SMauro Carvalho Chehab { 4259d4fa1a1SMauro Carvalho Chehab return &inputfifo_inst_admin[ch_id]; 4269d4fa1a1SMauro Carvalho Chehab } 4279d4fa1a1SMauro Carvalho Chehab 4289d4fa1a1SMauro Carvalho Chehab void ia_css_inputfifo_send_input_frame( 4299d4fa1a1SMauro Carvalho Chehab const unsigned short *data, 4309d4fa1a1SMauro Carvalho Chehab unsigned int width, 4319d4fa1a1SMauro Carvalho Chehab unsigned int height, 4329d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 4339d4fa1a1SMauro Carvalho Chehab enum atomisp_input_format input_format, 4349d4fa1a1SMauro Carvalho Chehab bool two_ppc) 4359d4fa1a1SMauro Carvalho Chehab { 4369d4fa1a1SMauro Carvalho Chehab unsigned int fmt_type, hblank_cycles, marker_cycles; 4379d4fa1a1SMauro Carvalho Chehab enum inputfifo_mipi_data_type type; 4389d4fa1a1SMauro Carvalho Chehab 4399d4fa1a1SMauro Carvalho Chehab assert(data); 4409d4fa1a1SMauro Carvalho Chehab hblank_cycles = HBLANK_CYCLES; 4419d4fa1a1SMauro Carvalho Chehab marker_cycles = MARKER_CYCLES; 4429d4fa1a1SMauro Carvalho Chehab ia_css_isys_convert_stream_format_to_mipi_format(input_format, 4439d4fa1a1SMauro Carvalho Chehab MIPI_PREDICTOR_NONE, 4449d4fa1a1SMauro Carvalho Chehab &fmt_type); 4459d4fa1a1SMauro Carvalho Chehab 4469d4fa1a1SMauro Carvalho Chehab type = inputfifo_determine_type(input_format); 4479d4fa1a1SMauro Carvalho Chehab 4489d4fa1a1SMauro Carvalho Chehab inputfifo_send_frame(data, width, height, 4499d4fa1a1SMauro Carvalho Chehab ch_id, fmt_type, hblank_cycles, marker_cycles, 4509d4fa1a1SMauro Carvalho Chehab two_ppc, type); 4519d4fa1a1SMauro Carvalho Chehab } 4529d4fa1a1SMauro Carvalho Chehab 4539d4fa1a1SMauro Carvalho Chehab void ia_css_inputfifo_start_frame( 4549d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 4559d4fa1a1SMauro Carvalho Chehab enum atomisp_input_format input_format, 4569d4fa1a1SMauro Carvalho Chehab bool two_ppc) 4579d4fa1a1SMauro Carvalho Chehab { 4589d4fa1a1SMauro Carvalho Chehab struct inputfifo_instance *s2mi; 4599d4fa1a1SMauro Carvalho Chehab 4609d4fa1a1SMauro Carvalho Chehab s2mi = inputfifo_get_inst(ch_id); 4619d4fa1a1SMauro Carvalho Chehab 4629d4fa1a1SMauro Carvalho Chehab s2mi->ch_id = ch_id; 4639d4fa1a1SMauro Carvalho Chehab ia_css_isys_convert_stream_format_to_mipi_format(input_format, 4649d4fa1a1SMauro Carvalho Chehab MIPI_PREDICTOR_NONE, 4659d4fa1a1SMauro Carvalho Chehab &s2mi->fmt_type); 4669d4fa1a1SMauro Carvalho Chehab s2mi->two_ppc = two_ppc; 4679d4fa1a1SMauro Carvalho Chehab s2mi->type = inputfifo_determine_type(input_format); 4689d4fa1a1SMauro Carvalho Chehab s2mi->hblank_cycles = HBLANK_CYCLES; 4699d4fa1a1SMauro Carvalho Chehab s2mi->marker_cycles = MARKER_CYCLES; 4709d4fa1a1SMauro Carvalho Chehab s2mi->streaming = true; 4719d4fa1a1SMauro Carvalho Chehab 4729d4fa1a1SMauro Carvalho Chehab inputfifo_start_frame(ch_id, s2mi->fmt_type); 4739d4fa1a1SMauro Carvalho Chehab return; 4749d4fa1a1SMauro Carvalho Chehab } 4759d4fa1a1SMauro Carvalho Chehab 4769d4fa1a1SMauro Carvalho Chehab void ia_css_inputfifo_send_line( 4779d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 4789d4fa1a1SMauro Carvalho Chehab const unsigned short *data, 4799d4fa1a1SMauro Carvalho Chehab unsigned int width, 4809d4fa1a1SMauro Carvalho Chehab const unsigned short *data2, 4819d4fa1a1SMauro Carvalho Chehab unsigned int width2) 4829d4fa1a1SMauro Carvalho Chehab { 4839d4fa1a1SMauro Carvalho Chehab struct inputfifo_instance *s2mi; 4849d4fa1a1SMauro Carvalho Chehab 4859d4fa1a1SMauro Carvalho Chehab assert(data); 4869d4fa1a1SMauro Carvalho Chehab assert((data2) || (width2 == 0)); 4879d4fa1a1SMauro Carvalho Chehab s2mi = inputfifo_get_inst(ch_id); 4889d4fa1a1SMauro Carvalho Chehab 4899d4fa1a1SMauro Carvalho Chehab /* Set global variables that indicate channel_id and format_type */ 4909d4fa1a1SMauro Carvalho Chehab inputfifo_curr_ch_id = (s2mi->ch_id) & _HIVE_ISP_CH_ID_MASK; 4919d4fa1a1SMauro Carvalho Chehab inputfifo_curr_fmt_type = (s2mi->fmt_type) & _HIVE_ISP_FMT_TYPE_MASK; 4929d4fa1a1SMauro Carvalho Chehab 4939d4fa1a1SMauro Carvalho Chehab inputfifo_send_line2(data, width, data2, width2, 4949d4fa1a1SMauro Carvalho Chehab s2mi->hblank_cycles, 4959d4fa1a1SMauro Carvalho Chehab s2mi->marker_cycles, 4969d4fa1a1SMauro Carvalho Chehab s2mi->two_ppc, 4979d4fa1a1SMauro Carvalho Chehab s2mi->type); 4989d4fa1a1SMauro Carvalho Chehab } 4999d4fa1a1SMauro Carvalho Chehab 5009d4fa1a1SMauro Carvalho Chehab void ia_css_inputfifo_send_embedded_line( 5019d4fa1a1SMauro Carvalho Chehab unsigned int ch_id, 5029d4fa1a1SMauro Carvalho Chehab enum atomisp_input_format data_type, 5039d4fa1a1SMauro Carvalho Chehab const unsigned short *data, 5049d4fa1a1SMauro Carvalho Chehab unsigned int width) 5059d4fa1a1SMauro Carvalho Chehab { 5069d4fa1a1SMauro Carvalho Chehab struct inputfifo_instance *s2mi; 5079d4fa1a1SMauro Carvalho Chehab unsigned int fmt_type; 5089d4fa1a1SMauro Carvalho Chehab 5099d4fa1a1SMauro Carvalho Chehab assert(data); 5109d4fa1a1SMauro Carvalho Chehab s2mi = inputfifo_get_inst(ch_id); 5119d4fa1a1SMauro Carvalho Chehab ia_css_isys_convert_stream_format_to_mipi_format(data_type, 5129d4fa1a1SMauro Carvalho Chehab MIPI_PREDICTOR_NONE, &fmt_type); 5139d4fa1a1SMauro Carvalho Chehab 5149d4fa1a1SMauro Carvalho Chehab /* Set format_type for metadata line. */ 5159d4fa1a1SMauro Carvalho Chehab inputfifo_curr_fmt_type = fmt_type & _HIVE_ISP_FMT_TYPE_MASK; 5169d4fa1a1SMauro Carvalho Chehab 5179d4fa1a1SMauro Carvalho Chehab inputfifo_send_line(data, width, s2mi->hblank_cycles, s2mi->marker_cycles, 5189d4fa1a1SMauro Carvalho Chehab s2mi->two_ppc, inputfifo_mipi_data_type_regular); 5199d4fa1a1SMauro Carvalho Chehab } 5209d4fa1a1SMauro Carvalho Chehab 5219d4fa1a1SMauro Carvalho Chehab void ia_css_inputfifo_end_frame( 5229d4fa1a1SMauro Carvalho Chehab unsigned int ch_id) 5239d4fa1a1SMauro Carvalho Chehab { 5249d4fa1a1SMauro Carvalho Chehab struct inputfifo_instance *s2mi; 5259d4fa1a1SMauro Carvalho Chehab 5269d4fa1a1SMauro Carvalho Chehab s2mi = inputfifo_get_inst(ch_id); 5279d4fa1a1SMauro Carvalho Chehab 5289d4fa1a1SMauro Carvalho Chehab /* Set global variables that indicate channel_id and format_type */ 5299d4fa1a1SMauro Carvalho Chehab inputfifo_curr_ch_id = (s2mi->ch_id) & _HIVE_ISP_CH_ID_MASK; 5309d4fa1a1SMauro Carvalho Chehab inputfifo_curr_fmt_type = (s2mi->fmt_type) & _HIVE_ISP_FMT_TYPE_MASK; 5319d4fa1a1SMauro Carvalho Chehab 5329d4fa1a1SMauro Carvalho Chehab /* Call existing HRT function */ 5339d4fa1a1SMauro Carvalho Chehab inputfifo_end_frame(s2mi->marker_cycles); 5349d4fa1a1SMauro Carvalho Chehab 5359d4fa1a1SMauro Carvalho Chehab s2mi->streaming = false; 5369d4fa1a1SMauro Carvalho Chehab return; 5379d4fa1a1SMauro Carvalho Chehab } 5389d4fa1a1SMauro Carvalho Chehab #endif /* #if !defined(HAS_NO_INPUT_SYSTEM) */ 539