diff options
Diffstat (limited to 'drivers/staging/media/atomisp/pci/sh_css_params.c')
-rw-r--r-- | drivers/staging/media/atomisp/pci/sh_css_params.c | 5247 |
1 files changed, 5247 insertions, 0 deletions
diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c new file mode 100644 index 000000000000..2e719f7db89e --- /dev/null +++ b/drivers/staging/media/atomisp/pci/sh_css_params.c @@ -0,0 +1,5247 @@ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "gdc_device.h" /* gdc_lut_store(), ... */ +#include "isp.h" /* ISP_VEC_ELEMBITS */ +#include "vamem.h" +#if !defined(HAS_NO_HMEM) +#ifndef __INLINE_HMEM__ +#define __INLINE_HMEM__ +#endif +#include "hmem.h" +#endif /* !defined(HAS_NO_HMEM) */ +#define IA_CSS_INCLUDE_PARAMETERS +#define IA_CSS_INCLUDE_ACC_PARAMETERS + +#include "sh_css_params.h" +#include "ia_css_queue.h" +#include "sw_event_global.h" /* Event IDs */ + +#include "platform_support.h" +#include "assert_support.h" +#include "misc_support.h" /* NOT_USED */ +#include "math_support.h" /* max(), min() EVEN_FLOOR()*/ + +#include "ia_css_stream.h" +#include "sh_css_params_internal.h" +#include "sh_css_param_shading.h" +#include "sh_css_param_dvs.h" +#include "ia_css_refcount.h" +#include "sh_css_internal.h" +#include "ia_css_control.h" +#include "ia_css_shading.h" +#include "sh_css_defs.h" +#include "sh_css_sp.h" +#include "ia_css_pipeline.h" +#include "ia_css_debug.h" +#include "memory_access.h" +#if 0 /* FIXME */ +#include "memory_realloc.h" +#endif +#include "ia_css_isp_param.h" +#include "ia_css_isp_params.h" +#include "ia_css_mipi.h" +#include "ia_css_morph.h" +#include "ia_css_host_data.h" +#include "ia_css_pipe.h" +#include "ia_css_pipe_binarydesc.h" +#if 0 +#include "ia_css_system_ctrl.h" +#endif + +/* Include all kernel host interfaces for ISP1 */ + +#include "anr/anr_1.0/ia_css_anr.host.h" +#include "cnr/cnr_1.0/ia_css_cnr.host.h" +#include "csc/csc_1.0/ia_css_csc.host.h" +#include "de/de_1.0/ia_css_de.host.h" +#include "dp/dp_1.0/ia_css_dp.host.h" +#include "bnr/bnr_1.0/ia_css_bnr.host.h" +#include "dvs/dvs_1.0/ia_css_dvs.host.h" +#include "fpn/fpn_1.0/ia_css_fpn.host.h" +#include "gc/gc_1.0/ia_css_gc.host.h" +#include "macc/macc_1.0/ia_css_macc.host.h" +#include "ctc/ctc_1.0/ia_css_ctc.host.h" +#include "ob/ob_1.0/ia_css_ob.host.h" +#include "raw/raw_1.0/ia_css_raw.host.h" +#include "fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h" +#include "s3a/s3a_1.0/ia_css_s3a.host.h" +#include "sc/sc_1.0/ia_css_sc.host.h" +#include "sdis/sdis_1.0/ia_css_sdis.host.h" +#include "tnr/tnr_1.0/ia_css_tnr.host.h" +#include "uds/uds_1.0/ia_css_uds_param.h" +#include "wb/wb_1.0/ia_css_wb.host.h" +#include "ynr/ynr_1.0/ia_css_ynr.host.h" +#include "xnr/xnr_1.0/ia_css_xnr.host.h" + +/* Include additional kernel host interfaces for ISP2 */ + +#include "aa/aa_2/ia_css_aa2.host.h" +#include "anr/anr_2/ia_css_anr2.host.h" +#include "bh/bh_2/ia_css_bh.host.h" +#include "cnr/cnr_2/ia_css_cnr2.host.h" +#include "ctc/ctc1_5/ia_css_ctc1_5.host.h" +#include "de/de_2/ia_css_de2.host.h" +#include "gc/gc_2/ia_css_gc2.host.h" +#include "sdis/sdis_2/ia_css_sdis2.host.h" +#include "ynr/ynr_2/ia_css_ynr2.host.h" +#include "fc/fc_1.0/ia_css_formats.host.h" + +#include "xnr/xnr_3.0/ia_css_xnr3.host.h" + +#if defined(HAS_OUTPUT_SYSTEM) +#include <components/output_system/sc_output_system_1.0/host/output_system.host.h> +#endif + +#include "sh_css_frac.h" +#include "ia_css_bufq.h" + +#define FPNTBL_BYTES(binary) \ + (sizeof(char) * (binary)->in_frame_info.res.height * \ + (binary)->in_frame_info.padded_width) + +#define ISP2400_SCTBL_BYTES(binary) \ + (sizeof(unsigned short) * (binary)->sctbl_height * \ + (binary)->sctbl_aligned_width_per_color * IA_CSS_SC_NUM_COLORS) + +#define ISP2401_SCTBL_BYTES(binary) \ + (sizeof(unsigned short) * max((binary)->sctbl_height, (binary)->sctbl_legacy_height) * \ + /* height should be the larger height between new api and legacy api */ \ + (binary)->sctbl_aligned_width_per_color * IA_CSS_SC_NUM_COLORS) + +#define MORPH_PLANE_BYTES(binary) \ + (SH_CSS_MORPH_TABLE_ELEM_BYTES * (binary)->morph_tbl_aligned_width * \ + (binary)->morph_tbl_height) + +/* We keep a second copy of the ptr struct for the SP to access. + Again, this would not be necessary on the chip. */ +static hrt_vaddress sp_ddr_ptrs; + +/* sp group address on DDR */ +static hrt_vaddress xmem_sp_group_ptrs; + +static hrt_vaddress xmem_sp_stage_ptrs[IA_CSS_PIPE_ID_NUM] +[SH_CSS_MAX_STAGES]; +static hrt_vaddress xmem_isp_stage_ptrs[IA_CSS_PIPE_ID_NUM] +[SH_CSS_MAX_STAGES]; + +static hrt_vaddress default_gdc_lut; +static int interleaved_lut_temp[4][HRT_GDC_N]; + +/* END DO NOT MOVE INTO VIMALS_WORLD */ + +/* Digital Zoom lookup table. See documentation for more details about the + * contents of this table. + */ +#if defined(HAS_GDC_VERSION_2) +#if defined(CONFIG_CSI2_PLUS) +/* + * Coefficients from + * Css_Mizuchi/regressions/20140424_0930/all/applications/common/gdc_v2_common/lut.h + */ + +static const int zoom_table[4][HRT_GDC_N] = { + { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -2, -2, -2, -2, -2, -2, -2, + -3, -3, -3, -3, -3, -3, -3, -4, + -4, -4, -4, -4, -5, -5, -5, -5, + -5, -5, -6, -6, -6, -6, -7, -7, + -7, -7, -7, -8, -8, -8, -8, -9, + -9, -9, -9, -10, -10, -10, -10, -11, + -11, -11, -12, -12, -12, -12, -13, -13, + -13, -14, -14, -14, -15, -15, -15, -15, + -16, -16, -16, -17, -17, -17, -18, -18, + -18, -19, -19, -20, -20, -20, -21, -21, + -21, -22, -22, -22, -23, -23, -24, -24, + -24, -25, -25, -25, -26, -26, -27, -27, + -28, -28, -28, -29, -29, -30, -30, -30, + -31, -31, -32, -32, -33, -33, -33, -34, + -34, -35, -35, -36, -36, -37, -37, -37, + -38, -38, -39, -39, -40, -40, -41, -41, + -42, -42, -43, -43, -44, -44, -45, -45, + -46, -46, -47, -47, -48, -48, -49, -49, + -50, -50, -51, -51, -52, -52, -53, -53, + -54, -54, -55, -55, -56, -56, -57, -57, + -58, -59, -59, -60, -60, -61, -61, -62, + -62, -63, -63, -64, -65, -65, -66, -66, + -67, -67, -68, -69, -69, -70, -70, -71, + -71, -72, -73, -73, -74, -74, -75, -75, + -76, -77, -77, -78, -78, -79, -80, -80, + -81, -81, -82, -83, -83, -84, -84, -85, + -86, -86, -87, -87, -88, -89, -89, -90, + -91, -91, -92, -92, -93, -94, -94, -95, + -96, -96, -97, -97, -98, -99, -99, -100, + -101, -101, -102, -102, -103, -104, -104, -105, + -106, -106, -107, -108, -108, -109, -109, -110, + -111, -111, -112, -113, -113, -114, -115, -115, + -116, -117, -117, -118, -119, -119, -120, -121, + -121, -122, -122, -123, -124, -124, -125, -126, + -126, -127, -128, -128, -129, -130, -130, -131, + -132, -132, -133, -134, -134, -135, -136, -136, + -137, -138, -138, -139, -140, -140, -141, -142, + -142, -143, -144, -144, -145, -146, -146, -147, + -148, -148, -149, -150, -150, -151, -152, -152, + -153, -154, -154, -155, -156, -156, -157, -158, + -158, -159, -160, -160, -161, -162, -162, -163, + -164, -164, -165, -166, -166, -167, -168, -168, + -169, -170, -170, -171, -172, -172, -173, -174, + -174, -175, -176, -176, -177, -178, -178, -179, + -180, -180, -181, -181, -182, -183, -183, -184, + -185, -185, -186, -187, -187, -188, -189, -189, + -190, -191, -191, -192, -193, -193, -194, -194, + -195, -196, -196, -197, -198, -198, -199, -200, + -200, -201, -201, -202, -203, -203, -204, -205, + -205, -206, -206, -207, -208, -208, -209, -210, + -210, -211, -211, -212, -213, -213, -214, -215, + -215, -216, -216, -217, -218, -218, -219, -219, + -220, -221, -221, -222, -222, -223, -224, -224, + -225, -225, -226, -227, -227, -228, -228, -229, + -229, -230, -231, -231, -232, -232, -233, -233, + -234, -235, -235, -236, -236, -237, -237, -238, + -239, -239, -240, -240, -241, -241, -242, -242, + -243, -244, -244, -245, -245, -246, -246, -247, + -247, -248, -248, -249, -249, -250, -250, -251, + -251, -252, -252, -253, -253, -254, -254, -255, + -256, -256, -256, -257, -257, -258, -258, -259, + -259, -260, -260, -261, -261, -262, -262, -263, + -263, -264, -264, -265, -265, -266, -266, -266, + -267, -267, -268, -268, -269, -269, -270, -270, + -270, -271, -271, -272, -272, -273, -273, -273, + -274, -274, -275, -275, -275, -276, -276, -277, + -277, -277, -278, -278, -279, -279, -279, -280, + -280, -280, -281, -281, -282, -282, -282, -283, + -283, -283, -284, -284, -284, -285, -285, -285, + -286, -286, -286, -287, -287, -287, -288, -288, + -288, -289, -289, -289, -289, -290, -290, -290, + -291, -291, -291, -291, -292, -292, -292, -293, + -293, -293, -293, -294, -294, -294, -294, -295, + -295, -295, -295, -295, -296, -296, -296, -296, + -297, -297, -297, -297, -297, -298, -298, -298, + -298, -298, -299, -299, -299, -299, -299, -299, + -300, -300, -300, -300, -300, -300, -300, -301, + -301, -301, -301, -301, -301, -301, -301, -301, + -302, -302, -302, -302, -302, -302, -302, -302, + -302, -302, -302, -302, -302, -303, -303, -303, + -303, -303, -303, -303, -303, -303, -303, -303, + -303, -303, -303, -303, -303, -303, -303, -303, + -303, -303, -303, -303, -303, -303, -303, -303, + -303, -303, -302, -302, -302, -302, -302, -302, + -302, -302, -302, -302, -302, -302, -301, -301, + -301, -301, -301, -301, -301, -301, -300, -300, + -300, -300, -300, -300, -299, -299, -299, -299, + -299, -299, -298, -298, -298, -298, -298, -297, + -297, -297, -297, -296, -296, -296, -296, -295, + -295, -295, -295, -294, -294, -294, -293, -293, + -293, -293, -292, -292, -292, -291, -291, -291, + -290, -290, -290, -289, -289, -289, -288, -288, + -288, -287, -287, -286, -286, -286, -285, -285, + -284, -284, -284, -283, -283, -282, -282, -281, + -281, -280, -280, -279, -279, -279, -278, -278, + -277, -277, -276, -276, -275, -275, -274, -273, + -273, -272, -272, -271, -271, -270, -270, -269, + -268, -268, -267, -267, -266, -266, -265, -264, + -264, -263, -262, -262, -261, -260, -260, -259, + -259, -258, -257, -256, -256, -255, -254, -254, + -253, -252, -252, -251, -250, -249, -249, -248, + -247, -246, -246, -245, -244, -243, -242, -242, + -241, -240, -239, -238, -238, -237, -236, -235, + -234, -233, -233, -232, -231, -230, -229, -228, + -227, -226, -226, -225, -224, -223, -222, -221, + -220, -219, -218, -217, -216, -215, -214, -213, + -212, -211, -210, -209, -208, -207, -206, -205, + -204, -203, -202, -201, -200, -199, -198, -197, + -196, -194, -193, -192, -191, -190, -189, -188, + -187, -185, -184, -183, -182, -181, -180, -178, + -177, -176, -175, -174, -172, -171, -170, -169, + -167, -166, -165, -164, -162, -161, -160, -158, + -157, -156, -155, -153, -152, -151, -149, -148, + -147, -145, -144, -142, -141, -140, -138, -137, + -135, -134, -133, -131, -130, -128, -127, -125, + -124, -122, -121, -120, -118, -117, -115, -114, + -112, -110, -109, -107, -106, -104, -103, -101, + -100, -98, -96, -95, -93, -92, -90, -88, + -87, -85, -83, -82, -80, -78, -77, -75, + -73, -72, -70, -68, -67, -65, -63, -61, + -60, -58, -56, -54, -52, -51, -49, -47, + -45, -43, -42, -40, -38, -36, -34, -32, + -31, -29, -27, -25, -23, -21, -19, -17, + -15, -13, -11, -9, -7, -5, -3, -1 + }, + { + 0, 2, 4, 6, 8, 10, 12, 14, + 16, 18, 20, 22, 25, 27, 29, 31, + 33, 36, 38, 40, 43, 45, 47, 50, + 52, 54, 57, 59, 61, 64, 66, 69, + 71, 74, 76, 79, 81, 84, 86, 89, + 92, 94, 97, 99, 102, 105, 107, 110, + 113, 116, 118, 121, 124, 127, 129, 132, + 135, 138, 141, 144, 146, 149, 152, 155, + 158, 161, 164, 167, 170, 173, 176, 179, + 182, 185, 188, 191, 194, 197, 200, 203, + 207, 210, 213, 216, 219, 222, 226, 229, + 232, 235, 239, 242, 245, 248, 252, 255, + 258, 262, 265, 269, 272, 275, 279, 282, + 286, 289, 292, 296, 299, 303, 306, 310, + 313, 317, 321, 324, 328, 331, 335, 338, + 342, 346, 349, 353, 357, 360, 364, 368, + 372, 375, 379, 383, 386, 390, 394, 398, + 402, 405, 409, 413, 417, 421, 425, 429, + 432, 436, 440, 444, 448, 452, 456, 460, + 464, 468, 472, 476, 480, 484, 488, 492, + 496, 500, 504, 508, 512, 516, 521, 525, + 529, 533, 537, 541, 546, 550, 554, 558, + 562, 567, 571, 575, 579, 584, 588, 592, + 596, 601, 605, 609, 614, 618, 622, 627, + 631, 635, 640, 644, 649, 653, 657, 662, + 666, 671, 675, 680, 684, 689, 693, 698, + 702, 707, 711, 716, 720, 725, 729, 734, + 738, 743, 747, 752, 757, 761, 766, 771, + 775, 780, 784, 789, 794, 798, 803, 808, + 813, 817, 822, 827, 831, 836, 841, 846, + 850, 855, 860, 865, 870, 874, 879, 884, + 889, 894, 898, 903, 908, 913, 918, 923, + 928, 932, 937, 942, 947, 952, 957, 962, + 967, 972, 977, 982, 986, 991, 996, 1001, + 1006, 1011, 1016, 1021, 1026, 1031, 1036, 1041, + 1046, 1051, 1056, 1062, 1067, 1072, 1077, 1082, + 1087, 1092, 1097, 1102, 1107, 1112, 1117, 1122, + 1128, 1133, 1138, 1143, 1148, 1153, 1158, 1164, + 1169, 1174, 1179, 1184, 1189, 1195, 1200, 1205, + 1210, 1215, 1221, 1226, 1231, 1236, 1242, 1247, + 1252, 1257, 1262, 1268, 1273, 1278, 1284, 1289, + 1294, 1299, 1305, 1310, 1315, 1321, 1326, 1331, + 1336, 1342, 1347, 1352, 1358, 1363, 1368, 1374, + 1379, 1384, 1390, 1395, 1400, 1406, 1411, 1417, + 1422, 1427, 1433, 1438, 1443, 1449, 1454, 1460, + 1465, 1470, 1476, 1481, 1487, 1492, 1497, 1503, + 1508, 1514, 1519, 1525, 1530, 1535, 1541, 1546, + 1552, 1557, 1563, 1568, 1574, 1579, 1585, 1590, + 1596, 1601, 1606, 1612, 1617, 1623, 1628, 1634, + 1639, 1645, 1650, 1656, 1661, 1667, 1672, 1678, + 1683, 1689, 1694, 1700, 1705, 1711, 1716, 1722, + 1727, 1733, 1738, 1744, 1749, 1755, 1761, 1766, + 1772, 1777, 1783, 1788, 1794, 1799, 1805, 1810, + 1816, 1821, 1827, 1832, 1838, 1844, 1849, 1855, + 1860, 1866, 1871, 1877, 1882, 1888, 1893, 1899, + 1905, 1910, 1916, 1921, 1927, 1932, 1938, 1943, + 1949, 1955, 1960, 1966, 1971, 1977, 1982, 1988, + 1993, 1999, 2005, 2010, 2016, 2021, 2027, 2032, + 2038, 2043, 2049, 2055, 2060, 2066, 2071, 2077, + 2082, 2088, 2093, 2099, 2105, 2110, 2116, 2121, + 2127, 2132, 2138, 2143, 2149, 2154, 2160, 2165, + 2171, 2177, 2182, 2188, 2193, 2199, 2204, 2210, + 2215, 2221, 2226, 2232, 2237, 2243, 2248, 2254, + 2259, 2265, 2270, 2276, 2281, 2287, 2292, 2298, + 2304, 2309, 2314, 2320, 2325, 2331, 2336, 2342, + 2347, 2353, 2358, 2364, 2369, 2375, 2380, 2386, + 2391, 2397, 2402, 2408, 2413, 2419, 2424, 2429, + 2435, 2440, 2446, 2451, 2457, 2462, 2467, 2473, + 2478, 2484, 2489, 2495, 2500, 2505, 2511, 2516, + 2522, 2527, 2532, 2538, 2543, 2549, 2554, 2559, + 2565, 2570, 2575, 2581, 2586, 2591, 2597, 2602, + 2607, 2613, 2618, 2623, 2629, 2634, 2639, 2645, + 2650, 2655, 2661, 2666, 2671, 2676, 2682, 2687, + 2692, 2698, 2703, 2708, 2713, 2719, 2724, 2729, + 2734, 2740, 2745, 2750, 2755, 2760, 2766, 2771, + 2776, 2781, 2786, 2792, 2797, 2802, 2807, 2812, + 2817, 2823, 2828, 2833, 2838, 2843, 2848, 2853, + 2859, 2864, 2869, 2874, 2879, 2884, 2889, 2894, + 2899, 2904, 2909, 2914, 2919, 2924, 2930, 2935, + 2940, 2945, 2950, 2955, 2960, 2965, 2970, 2975, + 2980, 2984, 2989, 2994, 2999, 3004, 3009, 3014, + 3019, 3024, 3029, 3034, 3039, 3044, 3048, 3053, + 3058, 3063, 3068, 3073, 3078, 3082, 3087, 3092, + 3097, 3102, 3106, 3111, 3116, 3121, 3126, 3130, + 3135, 3140, 3145, 3149, 3154, 3159, 3163, 3168, + 3173, 3177, 3182, 3187, 3191, 3196, 3201, 3205, + 3210, 3215, 3219, 3224, 3228, 3233, 3238, 3242, + 3247, 3251, 3256, 3260, 3265, 3269, 3274, 3279, + 3283, 3287, 3292, 3296, 3301, 3305, 3310, 3314, + 3319, 3323, 3327, 3332, 3336, 3341, 3345, 3349, + 3354, 3358, 3362, 3367, 3371, 3375, 3380, 3384, + 3388, 3393, 3397, 3401, 3405, 3410, 3414, 3418, + 3422, 3426, 3431, 3435, 3439, 3443, 3447, 3451, + 3455, 3460, 3464, 3468, 3472, 3476, 3480, 3484, + 3488, 3492, 3496, 3500, 3504, 3508, 3512, 3516, + 3520, 3524, 3528, 3532, 3536, 3540, 3544, 3548, + 3552, 3555, 3559, 3563, 3567, 3571, 3575, 3578, + 3582, 3586, 3590, 3593, 3597, 3601, 3605, 3608, + 3612, 3616, 3619, 3623, 3627, 3630, 3634, 3638, + 3641, 3645, 3649, 3652, 3656, 3659, 3663, 3666, + 3670, 3673, 3677, 3680, 3684, 3687, 3691, 3694, + 3698, 3701, 3704, 3708, 3711, 3714, 3718, 3721, + 3724, 3728, 3731, 3734, 3738, 3741, 3744, 3747, + 3751, 3754, 3757, 3760, 3763, 3767, 3770, 3773, + 3776, 3779, 3782, 3785, 3788, 3791, 3794, 3798, + 3801, 3804, 3807, 3809, 3812, 3815, 3818, 3821, + 3824, 3827, 3830, 3833, 3836, 3839, 3841, 3844, + 3847, 3850, 3853, 3855, 3858, 3861, 3864, 3866, + 3869, 3872, 3874, 3877, 3880, 3882, 3885, 3887, + 3890, 3893, 3895, 3898, 3900, 3903, 3905, 3908, + 3910, 3913, 3915, 3917, 3920, 3922, 3925, 3927, + 3929, 3932, 3934, 3936, 3939, 3941, 3943, 3945, + 3948, 3950, 3952, 3954, 3956, 3958, 3961, 3963, + 3965, 3967, 3969, 3971, 3973, 3975, 3977, 3979, + 3981, 3983, 3985, 3987, 3989, 3991, 3993, 3994, + 3996, 3998, 4000, 4002, 4004, 4005, 4007, 4009, + 4011, 4012, 4014, 4016, 4017, 4019, 4021, 4022, + 4024, 4025, 4027, 4028, 4030, 4031, 4033, 4034, + 4036, 4037, 4039, 4040, 4042, 4043, 4044, 4046, + 4047, 4048, 4050, 4051, 4052, 4053, 4055, 4056, + 4057, 4058, 4059, 4060, 4062, 4063, 4064, 4065, + 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, + 4074, 4075, 4075, 4076, 4077, 4078, 4079, 4079, + 4080, 4081, 4082, 4082, 4083, 4084, 4084, 4085, + 4086, 4086, 4087, 4087, 4088, 4088, 4089, 4089, + 4090, 4090, 4091, 4091, 4092, 4092, 4092, 4093, + 4093, 4093, 4094, 4094, 4094, 4094, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095 + }, + { + 4096, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4094, 4094, 4094, 4094, 4093, + 4093, 4093, 4092, 4092, 4092, 4091, 4091, 4090, + 4090, 4089, 4089, 4088, 4088, 4087, 4087, 4086, + 4086, 4085, 4084, 4084, 4083, 4082, 4082, 4081, + 4080, 4079, 4079, 4078, 4077, 4076, 4075, 4075, + 4074, 4073, 4072, 4071, 4070, 4069, 4068, 4067, + 4066, 4065, 4064, 4063, 4062, 4060, 4059, 4058, + 4057, 4056, 4055, 4053, 4052, 4051, 4050, 4048, + 4047, 4046, 4044, 4043, 4042, 4040, 4039, 4037, + 4036, 4034, 4033, 4031, 4030, 4028, 4027, 4025, + 4024, 4022, 4021, 4019, 4017, 4016, 4014, 4012, + 4011, 4009, 4007, 4005, 4004, 4002, 4000, 3998, + 3996, 3994, 3993, 3991, 3989, 3987, 3985, 3983, + 3981, 3979, 3977, 3975, 3973, 3971, 3969, 3967, + 3965, 3963, 3961, 3958, 3956, 3954, 3952, 3950, + 3948, 3945, 3943, 3941, 3939, 3936, 3934, 3932, + 3929, 3927, 3925, 3922, 3920, 3917, 3915, 3913, + 3910, 3908, 3905, 3903, 3900, 3898, 3895, 3893, + 3890, 3887, 3885, 3882, 3880, 3877, 3874, 3872, + 3869, 3866, 3864, 3861, 3858, 3855, 3853, 3850, + 3847, 3844, 3841, 3839, 3836, 3833, 3830, 3827, + 3824, 3821, 3818, 3815, 3812, 3809, 3807, 3804, + 3801, 3798, 3794, 3791, 3788, 3785, 3782, 3779, + 3776, 3773, 3770, 3767, 3763, 3760, 3757, 3754, + 3751, 3747, 3744, 3741, 3738, 3734, 3731, 3728, + 3724, 3721, 3718, 3714, 3711, 3708, 3704, 3701, + 3698, 3694, 3691, 3687, 3684, 3680, 3677, 3673, + 3670, 3666, 3663, 3659, 3656, 3652, 3649, 3645, + 3641, 3638, 3634, 3630, 3627, 3623, 3619, 3616, + 3612, 3608, 3605, 3601, 3597, 3593, 3590, 3586, + 3582, 3578, 3575, 3571, 3567, 3563, 3559, 3555, + 3552, 3548, 3544, 3540, 3536, 3532, 3528, 3524, + 3520, 3516, 3512, 3508, 3504, 3500, 3496, 3492, + 3488, 3484, 3480, 3476, 3472, 3468, 3464, 3460, + 3455, 3451, 3447, 3443, 3439, 3435, 3431, 3426, + 3422, 3418, 3414, 3410, 3405, 3401, 3397, 3393, + 3388, 3384, 3380, 3375, 3371, 3367, 3362, 3358, + 3354, 3349, 3345, 3341, 3336, 3332, 3327, 3323, + 3319, 3314, 3310, 3305, 3301, 3296, 3292, 3287, + 3283, 3279, 3274, 3269, 3265, 3260, 3256, 3251, + 3247, 3242, 3238, 3233, 3228, 3224, 3219, 3215, + 3210, 3205, 3201, 3196, 3191, 3187, 3182, 3177, + 3173, 3168, 3163, 3159, 3154, 3149, 3145, 3140, + 3135, 3130, 3126, 3121, 3116, 3111, 3106, 3102, + 3097, 3092, 3087, 3082, 3078, 3073, 3068, 3063, + 3058, 3053, 3048, 3044, 3039, 3034, 3029, 3024, + 3019, 3014, 3009, 3004, 2999, 2994, 2989, 2984, + 2980, 2975, 2970, 2965, 2960, 2955, 2950, 2945, + 2940, 2935, 2930, 2924, 2919, 2914, 2909, 2904, + 2899, 2894, 2889, 2884, 2879, 2874, 2869, 2864, + 2859, 2853, 2848, 2843, 2838, 2833, 2828, 2823, + 2817, 2812, 2807, 2802, 2797, 2792, 2786, 2781, + 2776, 2771, 2766, 2760, 2755, 2750, 2745, 2740, + 2734, 2729, 2724, 2719, 2713, 2708, 2703, 2698, + 2692, 2687, 2682, 2676, 2671, 2666, 2661, 2655, + 2650, 2645, 2639, 2634, 2629, 2623, 2618, 2613, + 2607, 2602, 2597, 2591, 2586, 2581, 2575, 2570, + 2565, 2559, 2554, 2549, 2543, 2538, 2532, 2527, + 2522, 2516, 2511, 2505, 2500, 2495, 2489, 2484, + 2478, 2473, 2467, 2462, 2457, 2451, 2446, 2440, + 2435, 2429, 2424, 2419, 2413, 2408, 2402, 2397, + 2391, 2386, 2380, 2375, 2369, 2364, 2358, 2353, + 2347, 2342, 2336, 2331, 2325, 2320, 2314, 2309, + 2304, 2298, 2292, 2287, 2281, 2276, 2270, 2265, + 2259, 2254, 2248, 2243, 2237, 2232, 2226, 2221, + 2215, 2210, 2204, 2199, 2193, 2188, 2182, 2177, + 2171, 2165, 2160, 2154, 2149, 2143, 2138, 2132, + 2127, 2121, 2116, 2110, 2105, 2099, 2093, 2088, + 2082, 2077, 2071, 2066, 2060, 2055, 2049, 2043, + 2038, 2032, 2027, 2021, 2016, 2010, 2005, 1999, + 1993, 1988, 1982, 1977, 1971, 1966, 1960, 1955, + 1949, 1943, 1938, 1932, 1927, 1921, 1916, 1910, + 1905, 1899, 1893, 1888, 1882, 1877, 1871, 1866, + 1860, 1855, 1849, 1844, 1838, 1832, 1827, 1821, + 1816, 1810, 1805, 1799, 1794, 1788, 1783, 1777, + 1772, 1766, 1761, 1755, 1749, 1744, 1738, 1733, + 1727, 1722, 1716, 1711, 1705, 1700, 1694, 1689, + 1683, 1678, 1672, 1667, 1661, 1656, 1650, 1645, + 1639, 1634, 1628, 1623, 1617, 1612, 1606, 1601, + 1596, 1590, 1585, 1579, 1574, 1568, 1563, 1557, + 1552, 1546, 1541, 1535, 1530, 1525, 1519, 1514, + 1508, 1503, 1497, 1492, 1487, 1481, 1476, 1470, + 1465, 1460, 1454, 1449, 1443, 1438, 1433, 1427, + 1422, 1417, 1411, 1406, 1400, 1395, 1390, 1384, + 1379, 1374, 1368, 1363, 1358, 1352, 1347, 1342, + 1336, 1331, 1326, 1321, 1315, 1310, 1305, 1299, + 1294, 1289, 1284, 1278, 1273, 1268, 1262, 1257, + 1252, 1247, 1242, 1236, 1231, 1226, 1221, 1215, + 1210, 1205, 1200, 1195, 1189, 1184, 1179, 1174, + 1169, 1164, 1158, 1153, 1148, 1143, 1138, 1133, + 1128, 1122, 1117, 1112, 1107, 1102, 1097, 1092, + 1087, 1082, 1077, 1072, 1067, 1062, 1056, 1051, + 1046, 1041, 1036, 1031, 1026, 1021, 1016, 1011, + 1006, 1001, 996, 991, 986, 982, 977, 972, + 967, 962, 957, 952, 947, 942, 937, 932, + 928, 923, 918, 913, 908, 903, 898, 894, + 889, 884, 879, 874, 870, 865, 860, 855, + 850, 846, 841, 836, 831, 827, 822, 817, + 813, 808, 803, 798, 794, 789, 784, 780, + 775, 771, 766, 761, 757, 752, 747, 743, + 738, 734, 729, 725, 720, 716, 711, 707, + 702, 698, 693, 689, 684, 680, 675, 671, + 666, 662, 657, 653, 649, 644, 640, 635, + 631, 627, 622, 618, 614, 609, 605, 601, + 596, 592, 588, 584, 579, 575, 571, 567, + 562, 558, 554, 550, 546, 541, 537, 533, + 529, 525, 521, 516, 512, 508, 504, 500, + 496, 492, 488, 484, 480, 476, 472, 468, + 464, 460, 456, 452, 448, 444, 440, 436, + 432, 429, 425, 421, 417, 413, 409, 405, + 402, 398, 394, 390, 386, 383, 379, 375, + 372, 368, 364, 360, 357, 353, 349, 346, + 342, 338, 335, 331, 328, 324, 321, 317, + 313, 310, 306, 303, 299, 296, 292, 289, + 286, 282, 279, 275, 272, 269, 265, 262, + 258, 255, 252, 248, 245, 242, 239, 235, + 232, 229, 226, 222, 219, 216, 213, 210, + 207, 203, 200, 197, 194, 191, 188, 185, + 182, 179, 176, 173, 170, 167, 164, 161, + 158, 155, 152, 149, 146, 144, 141, 138, + 135, 132, 129, 127, 124, 121, 118, 116, + 113, 110, 107, 105, 102, 99, 97, 94, + 92, 89, 86, 84, 81, 79, 76, 74, + 71, 69, 66, 64, 61, 59, 57, 54, + 52, 50, 47, 45, 43, 40, 38, 36, + 33, 31, 29, 27, 25, 22, 20, 18, + 16, 14, 12, 10, 8, 6, 4, 2 + }, + { + 0, -1, -3, -5, -7, -9, -11, -13, + -15, -17, -19, -20, -23, -25, -27, -28, + -30, -33, -34, -36, -39, -40, -42, -43, + -45, -46, -49, -50, -52, -54, -56, -58, + -60, -61, -62, -65, -66, -68, -70, -72, + -73, -74, -77, -78, -80, -82, -83, -85, + -87, -89, -90, -92, -93, -95, -96, -98, + -100, -102, -103, -105, -106, -107, -108, -110, + -112, -114, -116, -116, -118, -120, -122, -122, + -124, -126, -127, -128, -130, -131, -133, -133, + -136, -137, -138, -139, -141, -142, -144, -145, + -147, -147, -150, -151, -151, -153, -155, -156, + -157, -159, -160, -161, -163, -164, -165, -166, + -168, -168, -170, -171, -172, -174, -174, -176, + -177, -178, -180, -181, -182, -183, -184, -185, + -187, -188, -189, -190, -191, -192, -193, -195, + -196, -196, -198, -199, -200, -200, -202, -204, + -204, -205, -206, -207, -208, -209, -211, -212, + -212, -213, -214, -215, -216, -217, -218, -220, + -220, -221, -222, -223, -224, -225, -225, -227, + -227, -228, -229, -230, -230, -231, -233, -234, + -234, -235, -235, -237, -238, -239, -239, -240, + -240, -242, -242, -243, -243, -245, -246, -247, + -247, -249, -248, -249, -250, -251, -251, -253, + -253, -253, -255, -255, -256, -256, -257, -258, + -259, -259, -260, -261, -261, -262, -262, -264, + -263, -265, -265, -265, -266, -267, -267, -268, + -269, -269, -269, -270, -271, -271, -272, -273, + -273, -273, -274, -274, -276, -275, -276, -277, + -277, -278, -278, -278, -279, -279, -280, -281, + -280, -281, -282, -283, -283, -282, -284, -284, + -284, -285, -285, -286, -286, -286, -287, -287, + -288, -288, -288, -289, -289, -289, -290, -290, + -290, -291, -291, -292, -291, -291, -292, -292, + -292, -293, -293, -293, -294, -294, -295, -295, + -294, -295, -295, -296, -297, -297, -297, -297, + -297, -297, -298, -298, -297, -298, -298, -298, + -299, -299, -300, -299, -299, -300, -299, -300, + -301, -300, -300, -301, -300, -301, -301, -301, + -301, -301, -302, -301, -302, -301, -302, -302, + -302, -302, -302, -302, -302, -302, -303, -302, + -303, -302, -303, -303, -302, -303, -303, -303, + -302, -303, -303, -302, -303, -303, -302, -303, + -303, -302, -303, -303, -302, -303, -303, -303, + -303, -302, -303, -303, -302, -302, -302, -303, + -302, -302, -302, -301, -303, -302, -301, -302, + -301, -301, -301, -302, -301, -301, -301, -300, + -301, -300, -300, -300, -300, -299, -300, -299, + -300, -300, -299, -300, -299, -299, -299, -299, + -298, -299, -298, -297, -297, -297, -296, -297, + -296, -296, -296, -296, -295, -296, -295, -296, + -295, -294, -294, -294, -293, -294, -294, -293, + -293, -292, -293, -292, -292, -292, -291, -290, + -291, -290, -291, -289, -289, -290, -289, -289, + -288, -288, -288, -288, -286, -287, -286, -286, + -286, -285, -286, -284, -284, -284, -284, -283, + -283, -283, -282, -282, -282, -281, -280, -281, + -279, -280, -280, -278, -279, -278, -278, -277, + -278, -276, -276, -277, -275, -276, -274, -275, + -274, -273, -273, -272, -273, -272, -272, -271, + -270, -270, -269, -269, -269, -268, -268, -267, + -267, -266, -266, -266, -265, -265, -264, -264, + -263, -263, -262, -262, -261, -261, -260, -260, + -259, -259, -258, -258, -257, -257, -256, -256, + -256, -255, -254, -254, -253, -253, -252, -252, + -251, -251, -250, -250, -249, -249, -248, -248, + -247, -247, -246, -246, -245, -245, -244, -244, + -243, -242, -242, -241, -241, -240, -239, -239, + -239, -238, -238, -237, -237, -235, -235, -235, + -234, -234, -232, -233, -232, -232, -231, -229, + -230, -229, -228, -228, -227, -226, -227, -225, + -224, -225, -223, -223, -222, -222, -221, -221, + -220, -219, -219, -218, -218, -216, -217, -216, + -215, -215, -214, -213, -212, -213, -211, -211, + -210, -210, -209, -209, -208, -206, -207, -206, + -205, -204, -204, -204, -203, -202, -202, -200, + -200, -200, -200, -198, -197, -197, -196, -195, + -195, -195, -194, -194, -192, -192, -191, -191, + -189, -189, -188, -188, -187, -186, -186, -186, + -185, -185, -183, -183, -182, -182, -181, -181, + -180, -178, -178, -177, -177, -176, -176, -174, + -174, -173, -173, -172, -172, -172, -170, -170, + -168, -168, -167, -167, -167, -165, -165, -164, + -164, -164, -162, -162, -161, -160, -160, -158, + -158, -158, -157, -156, -155, -155, -154, -153, + -153, -152, -151, -151, -150, -149, -149, -148, + -147, -147, -146, -146, -144, -144, -144, -142, + -142, -141, -142, -140, -140, -139, -138, -138, + -137, -136, -136, -134, -134, -133, -134, -132, + -132, -131, -130, -130, -128, -128, -128, -127, + -127, -126, -124, -124, -124, -123, -123, -122, + -121, -120, -120, -119, -118, -118, -117, -117, + -116, -115, -115, -115, -114, -113, -111, -111, + -110, -110, -109, -109, -108, -107, -107, -106, + -105, -104, -104, -103, -102, -103, -102, -101, + -101, -100, -99, -99, -98, -97, -97, -96, + -96, -95, -94, -94, -93, -92, -92, -91, + -91, -90, -89, -88, -88, -88, -87, -86, + -85, -86, -84, -84, -83, -82, -82, -81, + -81, -80, -80, -78, -79, -77, -77, -77, + -76, -76, -75, -74, -74, -73, -72, -72, + -72, -71, -70, -70, -69, -68, -68, -68, + -66, -67, -66, -65, -65, -65, -63, -63, + -62, -62, -61, -61, -60, -60, -60, -58, + -58, -58, -56, -56, -56, -55, -54, -55, + -54, -54, -53, -52, -51, -51, -51, -50, + -49, -49, -49, -49, -48, -47, -46, -46, + -46, -46, -45, -43, -43, -43, -43, -42, + -42, -42, -40, -40, -40, -39, -39, -38, + -38, -38, -37, -37, -36, -36, -35, -35, + -34, -35, -34, -33, -33, -32, -32, -31, + -31, -31, -30, -29, -29, -29, -28, -27, + -28, -28, -27, -26, -26, -25, -25, -25, + -24, -24, -24, -23, -23, -22, -22, -22, + -21, -21, -20, -20, -20, -20, -19, -18, + -19, -18, -18, -17, -18, -17, -16, -17, + -16, -15, -15, -15, -14, -14, -15, -13, + -13, -13, -13, -12, -12, -11, -12, -11, + -12, -10, -10, -10, -10, -10, -9, -10, + -9, -9, -9, -8, -8, -7, -8, -7, + -7, -7, -6, -6, -6, -7, -6, -6, + -5, -5, -5, -5, -5, -4, -4, -5, + -4, -4, -3, -3, -3, -3, -3, -2, + -3, -2, -2, -2, -1, -2, -1, -2, + -1, -1, -1, -1, -1, 0, -1, 0, + -1, -1, 0, 0, -1, 0, 0, -1, + 1, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + } +}; +#else /* defined(CONFIG_CSI2_PLUS) */ +static const int zoom_table[4][HRT_GDC_N] = { + { + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, + -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, + -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, + -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, + -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, + -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, -7 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4 + }, + { + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, + 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, + 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, + 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, + 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, + 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, + 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, + 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, + 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, + 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, + 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, + 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, + 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, + 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, + 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, + 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, + 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, + 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, + 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, + 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, + 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, + 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, + 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, + 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, + 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, + 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, + 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, + 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, + 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, + 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, + 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, + 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, + 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, + 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, + 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, + 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, + 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, + 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, + 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, + 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, + 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, + 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, + 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, + 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, + 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, + 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, + 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, + 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, + 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, + 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, + 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, + 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, + 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, + 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, + 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, + 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, + 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, + 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, + 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, + 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, + 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, + 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, + 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, + 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, + 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, + 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, + 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, + 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, + 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, + 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, + 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, + 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, + 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, + 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, + 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, + 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, + 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, + 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, + 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, + 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, + 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, + 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, + 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, + 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, + 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, + 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, + 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, + 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, + 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, + 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, + 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, + 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, + 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, + 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, + 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, + 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, + 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, + 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, + 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, + 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, + 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, + 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, + 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, + 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, + 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, + 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, + 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, + 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, + 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, + 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, + 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, + 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, + 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, + 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, + 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, + 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, + 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, + 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, + 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, + 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, + 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, + 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4 + }, + { + 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, + 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, 256 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, 255 << 4, + 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, + 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, 254 << 4, + 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, + 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, 253 << 4, + 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, + 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, 252 << 4, + 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, + 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, 250 << 4, + 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, + 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, 248 << 4, + 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, + 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, 246 << 4, + 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, + 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, 244 << 4, + 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, + 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, 241 << 4, + 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, + 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, 239 << 4, + 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, + 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, 236 << 4, + 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, + 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, 232 << 4, + 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, + 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, 229 << 4, + 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, + 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, 225 << 4, + 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, + 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, 222 << 4, + 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, + 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, 218 << 4, + 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, + 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, 213 << 4, + 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, + 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, 209 << 4, + 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, + 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, 205 << 4, + 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, + 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, 200 << 4, + 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, + 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, 195 << 4, + 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, + 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, 191 << 4, + 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, + 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, 186 << 4, + 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, + 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, 181 << 4, + 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, + 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, 176 << 4, + 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, + 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, 170 << 4, + 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, + 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, 165 << 4, + 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, + 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, 160 << 4, + 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, + 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, 154 << 4, + 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, + 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, 149 << 4, + 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, + 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, 144 << 4, + 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, + 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, 138 << 4, + 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, + 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, 132 << 4, + 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, + 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, 127 << 4, + 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, + 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, 121 << 4, + 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, + 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, 116 << 4, + 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, + 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, 110 << 4, + 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, + 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, 105 << 4, + 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, + 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, 99 << 4, + 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, + 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, 94 << 4, + 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, + 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, 88 << 4, + 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, + 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, 83 << 4, + 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, + 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, 78 << 4, + 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, + 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, 73 << 4, + 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, + 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, 67 << 4, + 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, + 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, 62 << 4, + 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, + 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, 58 << 4, + 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, + 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, 53 << 4, + 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, + 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, 48 << 4, + 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, + 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, 43 << 4, + 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, + 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, 39 << 4, + 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, + 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, 35 << 4, + 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, + 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, 31 << 4, + 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, + 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, 27 << 4, + 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, + 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, 23 << 4, + 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, + 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, 19 << 4, + 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, + 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, 16 << 4, + 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, + 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, 12 << 4, + 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, + 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, 9 << 4, + 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, + 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, 7 << 4, + 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, + 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, 4 << 4, + 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, + 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4, 2 << 4 + }, + { + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, + -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, -10 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, -19 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, -18 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, -17 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, -16 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, -15 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, -14 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, -13 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, -12 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, -11 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, -9 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, -8 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, -6 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, -5 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, -4 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, -3 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, -2 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, -1 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, + 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, 1 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, + 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4, 0 << 4 + } +}; +#endif +#else +#error "sh_css_params.c: GDC version must be \ +one of {GDC_VERSION_2}" +#endif + +static const struct ia_css_dz_config default_dz_config = { + HRT_GDC_N, + HRT_GDC_N, + { + \ + {0, 0}, \ + {0, 0}, \ + } +}; + +static const struct ia_css_vector default_motion_config = { + 0, + 0 +}; + +/* ------ deprecated(bz675) : from ------ */ +static const struct ia_css_shading_settings default_shading_settings = { + 1 /* enable shading table conversion in the css + (This matches the legacy way.) */ +}; + +/* ------ deprecated(bz675) : to ------ */ + +struct ia_css_isp_skc_dvs_statistics { + ia_css_ptr p_data; +}; + +static enum ia_css_err +ref_sh_css_ddr_address_map( + struct sh_css_ddr_address_map *map, + struct sh_css_ddr_address_map *out); + +static enum ia_css_err +write_ia_css_isp_parameter_set_info_to_ddr( + struct ia_css_isp_parameter_set_info *me, + hrt_vaddress *out); + +static enum ia_css_err +free_ia_css_isp_parameter_set_info(hrt_vaddress ptr); + +static enum ia_css_err +sh_css_params_write_to_ddr_internal( + struct ia_css_pipe *pipe, + unsigned int pipe_id, + struct ia_css_isp_parameters *params, + const struct ia_css_pipeline_stage *stage, + struct sh_css_ddr_address_map *ddr_map, + struct sh_css_ddr_address_map_size *ddr_map_size); + +static enum ia_css_err +sh_css_create_isp_params(struct ia_css_stream *stream, + struct ia_css_isp_parameters **isp_params_out); + +static bool +sh_css_init_isp_params_from_global(struct ia_css_stream *stream, + struct ia_css_isp_parameters *params, + bool use_default_config, + struct ia_css_pipe *pipe_in); + +static enum ia_css_err +sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe, + struct ia_css_isp_parameters *params, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe_in); + +static enum ia_css_err +sh_css_set_global_isp_config_on_pipe( + struct ia_css_pipe *curr_pipe, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe); + +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) +static enum ia_css_err +sh_css_set_per_frame_isp_config_on_pipe( + struct ia_css_stream *stream, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe); +#endif + +static enum ia_css_err +sh_css_update_uds_and_crop_info_based_on_zoom_region( + const struct ia_css_binary_info *info, + const struct ia_css_frame_info *in_frame_info, + const struct ia_css_frame_info *out_frame_info, + const struct ia_css_resolution *dvs_env, + const struct ia_css_dz_config *zoom, + const struct ia_css_vector *motion_vector, + struct sh_css_uds_info *uds, /* out */ + struct sh_css_crop_pos *sp_out_crop_pos, /* out */ + struct ia_css_resolution pipe_in_res, + bool enable_zoom); + +hrt_vaddress +sh_css_params_ddr_address_map(void) +{ + return sp_ddr_ptrs; +} + +/* **************************************************** + * Each coefficient is stored as 7bits to fit 2 of them into one + * ISP vector element, so we will store 4 coefficents on every + * memory word (32bits) + * + * 0: Coefficient 0 used bits + * 1: Coefficient 1 used bits + * 2: Coefficient 2 used bits + * 3: Coefficient 3 used bits + * x: not used + * + * xx33333332222222 | xx11111110000000 + * + * *************************************************** + */ +static struct ia_css_host_data * +convert_allocate_fpntbl(struct ia_css_isp_parameters *params) +{ + unsigned int i, j; + short *data_ptr; + struct ia_css_host_data *me; + unsigned int isp_format_data_size; + u32 *isp_format_data_ptr; + + assert(params); + + data_ptr = params->fpn_config.data; + isp_format_data_size = params->fpn_config.height * params->fpn_config.width * + sizeof(uint32_t); + + me = ia_css_host_data_allocate(isp_format_data_size); + + if (!me) + return NULL; + + isp_format_data_ptr = (uint32_t *)me->address; + + for (i = 0; i < params->fpn_config.height; i++) { + for (j = 0; + j < params->fpn_config.width; + j += 4, data_ptr += 4, isp_format_data_ptr++) { + int data = data_ptr[0] << 0 | + data_ptr[1] << 7 | + data_ptr[2] << 16 | + data_ptr[3] << 23; + *isp_format_data_ptr = data; + } + } + return me; +} + +static enum ia_css_err +store_fpntbl(struct ia_css_isp_parameters *params, hrt_vaddress ptr) { + struct ia_css_host_data *isp_data; + + assert(params); + assert(ptr != mmgr_NULL); + + isp_data = convert_allocate_fpntbl(params); + if (!isp_data) + { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + ia_css_params_store_ia_css_host_data(ptr, isp_data); + + ia_css_host_data_free(isp_data); + return IA_CSS_SUCCESS; +} + +static void +convert_raw_to_fpn(struct ia_css_isp_parameters *params) +{ + int maxval = 0; + unsigned int i; + + assert(params); + + /* Find the maximum value in the table */ + for (i = 0; i < params->fpn_config.height * params->fpn_config.width; i++) { + int val = params->fpn_config.data[i]; + /* Make sure FPN value can be represented in 13-bit unsigned + * number (ISP precision - 1), but note that actual input range + * depends on precision of input frame data. + */ + if (val < 0) { + /* Checkpatch patch */ + val = 0; + } else if (val >= (1 << 13)) { + /* Checkpatch patch */ + /* MW: BUG, is "13" a system or application property */ + val = (1 << 13) - 1; + } + maxval = max(maxval, val); + } + /* Find the lowest shift value to remap the values in the range + * 0..maxval to 0..2^shiftval*63. + */ + params->fpn_config.shift = 0; + while (maxval > 63) { + /* MW: BUG, is "63" a system or application property */ + maxval >>= 1; + params->fpn_config.shift++; + } + /* Adjust the values in the table for the shift value */ + for (i = 0; i < params->fpn_config.height * params->fpn_config.width; i++) + ((unsigned short *)params->fpn_config.data)[i] >>= params->fpn_config.shift; +} + +static void +ia_css_process_kernel(struct ia_css_stream *stream, + struct ia_css_isp_parameters *params, + void (*process)(unsigned int pipe_id, + const struct ia_css_pipeline_stage *stage, + struct ia_css_isp_parameters *params)) +{ + int i; + + for (i = 0; i < stream->num_pipes; i++) { + struct ia_css_pipe *pipe = stream->pipes[i]; + struct ia_css_pipeline *pipeline = ia_css_pipe_get_pipeline(pipe); + struct ia_css_pipeline_stage *stage; + + /* update the other buffers to the pipe specific copies */ + for (stage = pipeline->stages; stage; stage = stage->next) { + if (!stage || !stage->binary) continue; + process(pipeline->pipe_id, stage, params); + } + } +} + +static enum ia_css_err +sh_css_select_dp_10bpp_config(const struct ia_css_pipe *pipe, + bool *is_dp_10bpp) { + enum ia_css_err err = IA_CSS_SUCCESS; + /* Currently we check if 10bpp DPC configuration is required based + * on the use case,i.e. if BDS and DPC is both enabled. The more cleaner + * design choice would be to expose the type of DPC (either 10bpp or 13bpp) + * using the binary info, but the current control flow does not allow this + * implementation. (This is because the configuration is set before a + * binary is selected, and the binary info is not available) + */ + if ((!pipe) || (!is_dp_10bpp)) + { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR); + err = IA_CSS_ERR_INTERNAL_ERROR; + } else + { + *is_dp_10bpp = false; + + /* check if DPC is enabled from the host */ + if (pipe->config.enable_dpc) { + /*check if BDS is enabled*/ + unsigned int required_bds_factor = SH_CSS_BDS_FACTOR_1_00; + + if ((pipe->config.bayer_ds_out_res.width != 0) && + (pipe->config.bayer_ds_out_res.height != 0)) { + if (IA_CSS_SUCCESS == binarydesc_calculate_bds_factor( + pipe->config.input_effective_res, + pipe->config.bayer_ds_out_res, + &required_bds_factor)) { + if (required_bds_factor != SH_CSS_BDS_FACTOR_1_00) { + /*we use 10bpp BDS configuration*/ + *is_dp_10bpp = true; + } + } + } + } + } + + return err; +} + +enum ia_css_err +sh_css_set_black_frame(struct ia_css_stream *stream, + const struct ia_css_frame *raw_black_frame) { + struct ia_css_isp_parameters *params; + /* this function desperately needs to be moved to the ISP or SP such + * that it can use the DMA. + */ + unsigned int height, width, y, x, k, data; + hrt_vaddress ptr; + + assert(stream); + assert(raw_black_frame); + + params = stream->isp_params_configs; + height = raw_black_frame->info.res.height; + width = raw_black_frame->info.padded_width, + + ptr = raw_black_frame->data + + raw_black_frame->planes.raw.offset; + + IA_CSS_ENTER_PRIVATE("black_frame=%p", raw_black_frame); + + if (params->fpn_config.data && + (params->fpn_config.width != width || params->fpn_config.height != height)) + { + sh_css_free(params->fpn_config.data); + params->fpn_config.data = NULL; + } + if (!params->fpn_config.data) + { + params->fpn_config.data = sh_css_malloc(height * width * sizeof(short)); + if (!params->fpn_config.data) { + IA_CSS_ERROR("out of memory"); + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + params->fpn_config.width = width; + params->fpn_config.height = height; + params->fpn_config.shift = 0; + } + + /* store raw to fpntbl */ + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x += (ISP_VEC_NELEMS * 2)) { + int ofs = y * width + x; + + for (k = 0; k < ISP_VEC_NELEMS; k += 2) { + mmgr_load(ptr, (void *)(&data), sizeof(int)); + params->fpn_config.data[ofs + 2 * k] = + (short)(data & 0xFFFF); + params->fpn_config.data[ofs + 2 * k + 2] = + (short)((data >> 16) & 0xFFFF); + ptr += sizeof(int); /* byte system address */ + } + for (k = 0; k < ISP_VEC_NELEMS; k += 2) { + mmgr_load(ptr, (void *)(&data), sizeof(int)); + params->fpn_config.data[ofs + 2 * k + 1] = + (short)(data & 0xFFFF); + params->fpn_config.data[ofs + 2 * k + 3] = + (short)((data >> 16) & 0xFFFF); + ptr += sizeof(int); /* byte system address */ + } + } + } + + /* raw -> fpn */ + convert_raw_to_fpn(params); + + /* overwrite isp parameter */ + ia_css_process_kernel(stream, params, ia_css_kernel_process_param[IA_CSS_FPN_ID]); + + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS); + + return IA_CSS_SUCCESS; +} + +bool +sh_css_params_set_binning_factor(struct ia_css_stream *stream, + unsigned int binning_fact) +{ + struct ia_css_isp_parameters *params; + + IA_CSS_ENTER_PRIVATE("void"); + assert(stream); + + params = stream->isp_params_configs; + + if (params->sensor_binning != binning_fact) { + params->sensor_binning = binning_fact; + params->sc_table_changed = true; + } + + IA_CSS_LEAVE_PRIVATE("void"); + + return params->sc_table_changed; +} + +static void +sh_css_update_shading_table_status(struct ia_css_pipe *pipe, + struct ia_css_isp_parameters *params) +{ + if (params && pipe && (pipe->pipe_num != params->sc_table_last_pipe_num)) { + params->sc_table_dirty = true; + params->sc_table_last_pipe_num = pipe->pipe_num; + } +} + +static void +sh_css_set_shading_table(struct ia_css_stream *stream, + struct ia_css_isp_parameters *params, + const struct ia_css_shading_table *table) +{ + IA_CSS_ENTER_PRIVATE(""); + if (!table) + return; + assert(stream); + + if (!table->enable) + table = NULL; + + if ((table != params->sc_table) || params->sc_table_dirty) { + params->sc_table = table; + params->sc_table_changed = true; + params->sc_table_dirty = false; + /* Not very clean, this goes to sh_css.c to invalidate the + * shading table for all pipes. Should replaced by a loop + * and a pipe-specific call. + */ + if (!params->output_frame) + sh_css_invalidate_shading_tables(stream); + } + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void +ia_css_params_store_ia_css_host_data( + hrt_vaddress ddr_addr, + struct ia_css_host_data *data) +{ + assert(data); + assert(data->address); + assert(ddr_addr != mmgr_NULL); + + IA_CSS_ENTER_PRIVATE(""); + + mmgr_store(ddr_addr, + (void *)(data->address), + (size_t)data->size); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +struct ia_css_host_data * +ia_css_params_alloc_convert_sctbl( + const struct ia_css_pipeline_stage *stage, + const struct ia_css_shading_table *shading_table) +{ + const struct ia_css_binary *binary = stage->binary; + struct ia_css_host_data *sctbl; + unsigned int i, j, aligned_width, row_padding; + unsigned int sctbl_size; + short int *ptr; + + assert(binary); + assert(shading_table); + + IA_CSS_ENTER_PRIVATE(""); + + if (!shading_table) { + IA_CSS_LEAVE_PRIVATE("void"); + return NULL; + } + + aligned_width = binary->sctbl_aligned_width_per_color; + row_padding = aligned_width - shading_table->width; + sctbl_size = shading_table->height * IA_CSS_SC_NUM_COLORS * aligned_width * + sizeof(short); + + sctbl = ia_css_host_data_allocate((size_t)sctbl_size); + + if (!sctbl) + return NULL; + ptr = (short int *)sctbl->address; + memset(ptr, + 0, + sctbl_size); + + for (i = 0; i < shading_table->height; i++) { + for (j = 0; j < IA_CSS_SC_NUM_COLORS; j++) { + memcpy(ptr, + &shading_table->data[j] + [i * shading_table->width], + shading_table->width * sizeof(short)); + ptr += aligned_width; + } + } + + IA_CSS_LEAVE_PRIVATE("void"); + return sctbl; +} + +enum ia_css_err ia_css_params_store_sctbl( + const struct ia_css_pipeline_stage *stage, + hrt_vaddress sc_tbl, + const struct ia_css_shading_table *sc_config) +{ + struct ia_css_host_data *isp_sc_tbl; + + IA_CSS_ENTER_PRIVATE(""); + + if (!sc_config) { + IA_CSS_LEAVE_PRIVATE("void"); + return IA_CSS_SUCCESS; + } + + isp_sc_tbl = ia_css_params_alloc_convert_sctbl(stage, sc_config); + if (!isp_sc_tbl) { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + /* store the shading table to ddr */ + ia_css_params_store_ia_css_host_data(sc_tbl, isp_sc_tbl); + ia_css_host_data_free(isp_sc_tbl); + + IA_CSS_LEAVE_PRIVATE("void"); + + return IA_CSS_SUCCESS; +} + +static void +sh_css_enable_pipeline(const struct ia_css_binary *binary) +{ + if (!binary) + return; + + IA_CSS_ENTER_PRIVATE(""); + + ia_css_isp_param_enable_pipeline(&binary->mem_params); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static enum ia_css_err +ia_css_process_zoom_and_motion( + struct ia_css_isp_parameters *params, + const struct ia_css_pipeline_stage *first_stage) { + /* first_stage can be NULL */ + const struct ia_css_pipeline_stage *stage; + enum ia_css_err err = IA_CSS_SUCCESS; + struct ia_css_resolution pipe_in_res; + + pipe_in_res.width = 0; + pipe_in_res.height = 0; + + assert(params); + + IA_CSS_ENTER_PRIVATE(""); + + /* Go through all stages to udate uds and cropping */ + for (stage = first_stage; stage; stage = stage->next) + { + struct ia_css_binary *binary; + /* note: the var below is made static as it is quite large; + if it is not static it ends up on the stack which could + cause issues for drivers + */ + static struct ia_css_binary tmp_binary; + + const struct ia_css_binary_xinfo *info = NULL; + + binary = stage->binary; + if (binary) { + info = binary->info; + } else { + const struct sh_css_binary_args *args = &stage->args; + const struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS] = {NULL}; + + if (args->out_frame[0]) + out_infos[0] = &args->out_frame[0]->info; + info = &stage->firmware->info.isp; + ia_css_binary_fill_info(info, false, false, + ATOMISP_INPUT_FORMAT_RAW_10, + args->in_frame ? &args->in_frame->info : NULL, + NULL, + out_infos, + args->out_vf_frame ? &args->out_vf_frame->info + : NULL, + &tmp_binary, + NULL, + -1, true); + binary = &tmp_binary; + binary->info = info; + } + + if (stage == first_stage) { + /* we will use pipe_in_res to scale the zoom crop region if needed */ + pipe_in_res = binary->effective_in_frame_res; + } + + assert(stage->stage_num < SH_CSS_MAX_STAGES); + if (params->dz_config.zoom_region.resolution.width == 0 && + params->dz_config.zoom_region.resolution.height == 0) { + sh_css_update_uds_and_crop_info( + &info->sp, + &binary->in_frame_info, + &binary->out_frame_info[0], + &binary->dvs_envelope, + ¶ms->dz_config, + ¶ms->motion_config, + ¶ms->uds[stage->stage_num].uds, + ¶ms->uds[stage->stage_num].crop_pos, + stage->enable_zoom); + } else { + err = sh_css_update_uds_and_crop_info_based_on_zoom_region( + &info->sp, + &binary->in_frame_info, + &binary->out_frame_info[0], + &binary->dvs_envelope, + ¶ms->dz_config, + ¶ms->motion_config, + ¶ms->uds[stage->stage_num].uds, + ¶ms->uds[stage->stage_num].crop_pos, + pipe_in_res, + stage->enable_zoom); + if (err != IA_CSS_SUCCESS) + return err; + } + } + params->isp_params_changed = true; + + IA_CSS_LEAVE_PRIVATE("void"); + return err; +} + +static void +sh_css_set_gamma_table(struct ia_css_isp_parameters *params, + const struct ia_css_gamma_table *table) +{ + if (!table) + return; + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + params->gc_table = *table; + params->config_changed[IA_CSS_GC_ID] = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_gamma_table(const struct ia_css_isp_parameters *params, + struct ia_css_gamma_table *table) +{ + if (!table) + return; + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + *table = params->gc_table; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_ctc_table(struct ia_css_isp_parameters *params, + const struct ia_css_ctc_table *table) +{ + if (!table) + return; + + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + params->ctc_table = *table; + params->config_changed[IA_CSS_CTC_ID] = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_ctc_table(const struct ia_css_isp_parameters *params, + struct ia_css_ctc_table *table) +{ + if (!table) + return; + + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + *table = params->ctc_table; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_macc_table(struct ia_css_isp_parameters *params, + const struct ia_css_macc_table *table) +{ + if (!table) + return; + + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + params->macc_table = *table; + params->config_changed[IA_CSS_MACC_ID] = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_macc_table(const struct ia_css_isp_parameters *params, + struct ia_css_macc_table *table) +{ + if (!table) + return; + + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + *table = params->macc_table; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void ia_css_morph_table_free( + struct ia_css_morph_table *me) +{ + unsigned int i; + + if (!me) + return; + + IA_CSS_ENTER(""); + + for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { + if (me->coordinates_x[i]) { + sh_css_free(me->coordinates_x[i]); + me->coordinates_x[i] = NULL; + } + if (me->coordinates_y[i]) { + sh_css_free(me->coordinates_y[i]); + me->coordinates_y[i] = NULL; + } + } + + sh_css_free(me); + IA_CSS_LEAVE("void"); +} + +struct ia_css_morph_table *ia_css_morph_table_allocate( + unsigned int width, + unsigned int height) +{ + unsigned int i; + struct ia_css_morph_table *me; + + IA_CSS_ENTER(""); + + me = sh_css_malloc(sizeof(*me)); + if (!me) { + IA_CSS_ERROR("out of memory"); + return me; + } + + for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { + me->coordinates_x[i] = NULL; + me->coordinates_y[i] = NULL; + } + + for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { + me->coordinates_x[i] = + sh_css_malloc(height * width * + sizeof(*me->coordinates_x[i])); + me->coordinates_y[i] = + sh_css_malloc(height * width * + sizeof(*me->coordinates_y[i])); + + if ((!me->coordinates_x[i]) || + (!me->coordinates_y[i])) { + ia_css_morph_table_free(me); + me = NULL; + return me; + } + } + me->width = width; + me->height = height; + IA_CSS_LEAVE(""); + return me; +} + +static enum ia_css_err sh_css_params_default_morph_table( + struct ia_css_morph_table **table, + const struct ia_css_binary *binary) +{ + /* MW 2400 advanced requires different scaling */ + unsigned int i, j, k, step, width, height; + short start_x[IA_CSS_MORPH_TABLE_NUM_PLANES] = { -8, 0, -8, 0, 0, -8 }, + start_y[IA_CSS_MORPH_TABLE_NUM_PLANES] = { 0, 0, -8, -8, -8, 0 }; + struct ia_css_morph_table *tab; + + assert(table); + assert(binary); + + IA_CSS_ENTER_PRIVATE(""); + + step = (ISP_VEC_NELEMS / 16) * 128, + width = binary->morph_tbl_width, + height = binary->morph_tbl_height; + + tab = ia_css_morph_table_allocate(width, height); + if (!tab) + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + + for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { + short val_y = start_y[i]; + + for (j = 0; j < height; j++) { + short val_x = start_x[i]; + unsigned short *x_ptr, *y_ptr; + + x_ptr = &tab->coordinates_x[i][j * width]; + y_ptr = &tab->coordinates_y[i][j * width]; + for (k = 0; k < width; + k++, x_ptr++, y_ptr++, val_x += (short)step) { + if (k == 0) + *x_ptr = 0; + else if (k == width - 1) + *x_ptr = val_x + 2 * start_x[i]; + else + *x_ptr = val_x; + if (j == 0) + *y_ptr = 0; + else + *y_ptr = val_y; + } + val_y += (short)step; + } + } + *table = tab; + + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS); + + return IA_CSS_SUCCESS; +} + +static void +sh_css_set_morph_table(struct ia_css_isp_parameters *params, + const struct ia_css_morph_table *table) +{ + if (!table) + return; + + IA_CSS_ENTER_PRIVATE("table=%p", table); + + assert(params); + if (table->enable == false) + table = NULL; + params->morph_table = table; + params->morph_table_changed = true; + IA_CSS_LEAVE_PRIVATE("void"); +} + +void +ia_css_translate_3a_statistics( + struct ia_css_3a_statistics *host_stats, + const struct ia_css_isp_3a_statistics_map *isp_stats) +{ + IA_CSS_ENTER(""); + if (host_stats->grid.use_dmem) { + IA_CSS_LOG("3A: DMEM"); + ia_css_s3a_dmem_decode(host_stats, isp_stats->dmem_stats); + } else { + IA_CSS_LOG("3A: VMEM"); + ia_css_s3a_vmem_decode(host_stats, isp_stats->vmem_stats_hi, + isp_stats->vmem_stats_lo); + } +#if !defined(HAS_NO_HMEM) + IA_CSS_LOG("3A: HMEM"); + ia_css_s3a_hmem_decode(host_stats, isp_stats->hmem_stats); +#endif + + IA_CSS_LEAVE("void"); +} + +void +ia_css_isp_3a_statistics_map_free(struct ia_css_isp_3a_statistics_map *me) +{ + if (me) { + if (me->data_allocated) { + sh_css_free(me->data_ptr); + me->data_ptr = NULL; + me->data_allocated = false; + } + sh_css_free(me); + } +} + +struct ia_css_isp_3a_statistics_map * +ia_css_isp_3a_statistics_map_allocate( + const struct ia_css_isp_3a_statistics *isp_stats, + void *data_ptr) +{ + struct ia_css_isp_3a_statistics_map *me; + /* Windows compiler does not like adding sizes to a void * + * so we use a local char * instead. */ + char *base_ptr; + + me = sh_css_malloc(sizeof(*me)); + if (!me) { + IA_CSS_LEAVE("cannot allocate memory"); + goto err; + } + + me->data_ptr = data_ptr; + me->data_allocated = !data_ptr; + if (!data_ptr) { + me->data_ptr = sh_css_malloc(isp_stats->size); + if (!me->data_ptr) { + IA_CSS_LEAVE("cannot allocate memory"); + goto err; + } + } + base_ptr = me->data_ptr; + + me->size = isp_stats->size; + /* GCC complains when we assign a char * to a void *, so these + * casts are necessary unfortunately. */ + me->dmem_stats = (void *)base_ptr; + me->vmem_stats_hi = (void *)(base_ptr + isp_stats->dmem_size); + me->vmem_stats_lo = (void *)(base_ptr + isp_stats->dmem_size + + isp_stats->vmem_size); + me->hmem_stats = (void *)(base_ptr + isp_stats->dmem_size + + 2 * isp_stats->vmem_size); + + IA_CSS_LEAVE("map=%p", me); + return me; + +err: + if (me) + sh_css_free(me); + return NULL; +} + +enum ia_css_err +ia_css_get_3a_statistics(struct ia_css_3a_statistics *host_stats, + const struct ia_css_isp_3a_statistics *isp_stats) { + struct ia_css_isp_3a_statistics_map *map; + enum ia_css_err ret = IA_CSS_SUCCESS; + + IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats); + + assert(host_stats); + assert(isp_stats); + + map = ia_css_isp_3a_statistics_map_allocate(isp_stats, NULL); + if (map) + { + mmgr_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size); + ia_css_translate_3a_statistics(host_stats, map); + ia_css_isp_3a_statistics_map_free(map); + } else + { + IA_CSS_ERROR("out of memory"); + ret = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + + IA_CSS_LEAVE_ERR(ret); + return ret; +} + +/* Parameter encoding is not yet orthogonal. + This function hnadles some of the exceptions. +*/ +static void +ia_css_set_param_exceptions(const struct ia_css_pipe *pipe, + struct ia_css_isp_parameters *params) +{ + assert(params); + + /* Copy also to DP. Should be done by the driver. */ + params->dp_config.gr = params->wb_config.gr; + params->dp_config.r = params->wb_config.r; + params->dp_config.b = params->wb_config.b; + params->dp_config.gb = params->wb_config.gb; + + if (atomisp_hw_is_isp2401) { + assert(pipe); + assert(pipe->mode < IA_CSS_PIPE_ID_NUM); + + if (pipe->mode < IA_CSS_PIPE_ID_NUM) { + params->pipe_dp_config[pipe->mode].gr = params->wb_config.gr; + params->pipe_dp_config[pipe->mode].r = params->wb_config.r; + params->pipe_dp_config[pipe->mode].b = params->wb_config.b; + params->pipe_dp_config[pipe->mode].gb = params->wb_config.gb; + } + } +} + +/* ISP2401 */ +static void +sh_css_set_dp_config(const struct ia_css_pipe *pipe, + struct ia_css_isp_parameters *params, + const struct ia_css_dp_config *config) +{ + if (!config) + return; + + assert(params); + assert(pipe); + assert(pipe->mode < IA_CSS_PIPE_ID_NUM); + + IA_CSS_ENTER_PRIVATE("config=%p", config); + ia_css_dp_debug_dtrace(config, IA_CSS_DEBUG_TRACE_PRIVATE); + if (pipe->mode < IA_CSS_PIPE_ID_NUM) { + params->pipe_dp_config[pipe->mode] = *config; + params->pipe_dpc_config_changed[pipe->mode] = true; + } + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_dp_config(const struct ia_css_pipe *pipe, + const struct ia_css_isp_parameters *params, + struct ia_css_dp_config *config) +{ + if (!config) + return; + + assert(params); + assert(pipe); + IA_CSS_ENTER_PRIVATE("config=%p", config); + + *config = params->pipe_dp_config[pipe->mode]; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_nr_config(struct ia_css_isp_parameters *params, + const struct ia_css_nr_config *config) +{ + if (!config) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("config=%p", config); + + ia_css_nr_debug_dtrace(config, IA_CSS_DEBUG_TRACE_PRIVATE); + params->nr_config = *config; + params->yee_config.nr = *config; + params->config_changed[IA_CSS_NR_ID] = true; + params->config_changed[IA_CSS_YEE_ID] = true; + params->config_changed[IA_CSS_BNR_ID] = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_ee_config(struct ia_css_isp_parameters *params, + const struct ia_css_ee_config *config) +{ + if (!config) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("config=%p", config); + ia_css_ee_debug_dtrace(config, IA_CSS_DEBUG_TRACE_PRIVATE); + + params->ee_config = *config; + params->yee_config.ee = *config; + params->config_changed[IA_CSS_YEE_ID] = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_ee_config(const struct ia_css_isp_parameters *params, + struct ia_css_ee_config *config) +{ + if (!config) + return; + + IA_CSS_ENTER_PRIVATE("config=%p", config); + + assert(params); + *config = params->ee_config; + + ia_css_ee_debug_dtrace(config, IA_CSS_DEBUG_TRACE_PRIVATE); + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_pipe_dvs_6axis_config(const struct ia_css_pipe *pipe, + struct ia_css_isp_parameters *params, + const struct ia_css_dvs_6axis_config *dvs_config) +{ + if (!dvs_config) + return; + assert(params); + assert(pipe); + assert(dvs_config->height_y == dvs_config->height_uv); + assert((dvs_config->width_y - 1) == 2 * (dvs_config->width_uv - 1)); + assert(pipe->mode < IA_CSS_PIPE_ID_NUM); + + IA_CSS_ENTER_PRIVATE("dvs_config=%p", dvs_config); + + copy_dvs_6axis_table(params->pipe_dvs_6axis_config[pipe->mode], dvs_config); + +#if !defined(HAS_NO_DVS_6AXIS_CONFIG_UPDATE) + params->pipe_dvs_6axis_config_changed[pipe->mode] = true; +#endif + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_pipe_dvs_6axis_config(const struct ia_css_pipe *pipe, + const struct ia_css_isp_parameters *params, + struct ia_css_dvs_6axis_config *dvs_config) +{ + if (!dvs_config) + return; + assert(params); + assert(pipe); + assert(dvs_config->height_y == dvs_config->height_uv); + assert((dvs_config->width_y - 1) == 2 * dvs_config->width_uv - 1); + + IA_CSS_ENTER_PRIVATE("dvs_config=%p", dvs_config); + + if ((pipe->mode < IA_CSS_PIPE_ID_NUM) && + (dvs_config->width_y == params->pipe_dvs_6axis_config[pipe->mode]->width_y) && + (dvs_config->height_y == params->pipe_dvs_6axis_config[pipe->mode]->height_y) && + (dvs_config->width_uv == params->pipe_dvs_6axis_config[pipe->mode]->width_uv) && + (dvs_config->height_uv == params->pipe_dvs_6axis_config[pipe->mode]->height_uv) + && + dvs_config->xcoords_y && + dvs_config->ycoords_y && + dvs_config->xcoords_uv && + dvs_config->ycoords_uv) { + copy_dvs_6axis_table(dvs_config, params->pipe_dvs_6axis_config[pipe->mode]); + } + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_baa_config(struct ia_css_isp_parameters *params, + const struct ia_css_aa_config *config) +{ + if (!config) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("config=%p", config); + + params->bds_config = *config; + params->config_changed[IA_CSS_BDS_ID] = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_baa_config(const struct ia_css_isp_parameters *params, + struct ia_css_aa_config *config) +{ + if (!config) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("config=%p", config); + + *config = params->bds_config; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_set_dz_config(struct ia_css_isp_parameters *params, + const struct ia_css_dz_config *config) +{ + if (!config) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("dx=%d, dy=%d", config->dx, config->dy); + + assert(config->dx <= HRT_GDC_N); + assert(config->dy <= HRT_GDC_N); + + params->dz_config = *config; + params->dz_config_changed = true; + /* JK: Why isp params changed?? */ + params->isp_params_changed = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_dz_config(const struct ia_css_isp_parameters *params, + struct ia_css_dz_config *config) +{ + if (!config) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("config=%p", config); + + *config = params->dz_config; + + IA_CSS_LEAVE_PRIVATE("dx=%d, dy=%d", config->dx, config->dy); +} + +static void +sh_css_set_motion_vector(struct ia_css_isp_parameters *params, + const struct ia_css_vector *motion) +{ + if (!motion) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("x=%d, y=%d", motion->x, motion->y); + + params->motion_config = *motion; + /* JK: Why do isp params change? */ + params->motion_config_changed = true; + params->isp_params_changed = true; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +sh_css_get_motion_vector(const struct ia_css_isp_parameters *params, + struct ia_css_vector *motion) +{ + if (!motion) + return; + assert(params); + + IA_CSS_ENTER_PRIVATE("motion=%p", motion); + + *motion = params->motion_config; + + IA_CSS_LEAVE_PRIVATE("x=%d, y=%d", motion->x, motion->y); +} + +struct ia_css_isp_config * +sh_css_pipe_isp_config_get(struct ia_css_pipe *pipe) +{ + if (!pipe) { + IA_CSS_ERROR("pipe=%p", NULL); + return NULL; + } + return pipe->config.p_isp_config; +} + +enum ia_css_err +ia_css_stream_set_isp_config( + struct ia_css_stream *stream, + const struct ia_css_isp_config *config) { + return ia_css_stream_set_isp_config_on_pipe(stream, config, NULL); +} + +enum ia_css_err +ia_css_stream_set_isp_config_on_pipe( + struct ia_css_stream *stream, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe) { + enum ia_css_err err = IA_CSS_SUCCESS; + + if ((!stream) || (!config)) + return IA_CSS_ERR_INVALID_ARGUMENTS; + + IA_CSS_ENTER("stream=%p, config=%p, pipe=%p", stream, config, pipe); + +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) + if (config->output_frame) + err = sh_css_set_per_frame_isp_config_on_pipe(stream, config, pipe); + else +#endif + err = sh_css_set_global_isp_config_on_pipe(stream->pipes[0], config, pipe); + + IA_CSS_LEAVE_ERR(err); + return err; +} + +enum ia_css_err +ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe, + struct ia_css_isp_config *config) { + struct ia_css_pipe *pipe_in = pipe; + enum ia_css_err err = IA_CSS_SUCCESS; + + IA_CSS_ENTER("pipe=%p", pipe); + + if ((!pipe) || (!pipe->stream)) + return IA_CSS_ERR_INVALID_ARGUMENTS; + + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "config=%p\n", config); + +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) + if (config->output_frame) + err = sh_css_set_per_frame_isp_config_on_pipe(pipe->stream, config, pipe); + else +#endif + err = sh_css_set_global_isp_config_on_pipe(pipe, config, pipe_in); + IA_CSS_LEAVE_ERR(err); + return err; +} + +static enum ia_css_err +sh_css_set_global_isp_config_on_pipe( + struct ia_css_pipe *curr_pipe, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe) { + enum ia_css_err err = IA_CSS_SUCCESS; + enum ia_css_err err1 = IA_CSS_SUCCESS; + enum ia_css_err err2 = IA_CSS_SUCCESS; + + IA_CSS_ENTER_PRIVATE("stream=%p, config=%p, pipe=%p", curr_pipe, config, pipe); + + err1 = sh_css_init_isp_params_from_config(curr_pipe, curr_pipe->stream->isp_params_configs, config, pipe); + + /* Now commit all changes to the SP */ + err2 = sh_css_param_update_isp_params(curr_pipe, curr_pipe->stream->isp_params_configs, sh_css_sp_is_running(), pipe); + + /* The following code is intentional. The sh_css_init_isp_params_from_config interface + * throws an error when both DPC and BDS is enabled. The CSS API must pass this error + * information to the caller, ie. the host. We do not return this error immediately, + * but instead continue with updating the ISP params to enable testing of features + * which are currently in TR phase. */ + + err = (err1 != IA_CSS_SUCCESS) ? err1 : ((err2 != IA_CSS_SUCCESS) ? err2 : err); + + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) +static enum ia_css_err +sh_css_set_per_frame_isp_config_on_pipe( + struct ia_css_stream *stream, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe) { + unsigned int i; + bool per_frame_config_created = false; + enum ia_css_err err = IA_CSS_SUCCESS; + enum ia_css_err err1 = IA_CSS_SUCCESS; + enum ia_css_err err2 = IA_CSS_SUCCESS; + enum ia_css_err err3 = IA_CSS_SUCCESS; + + struct sh_css_ddr_address_map *ddr_ptrs; + struct sh_css_ddr_address_map_size *ddr_ptrs_size; + struct ia_css_isp_parameters *params; + + IA_CSS_ENTER_PRIVATE("stream=%p, config=%p, pipe=%p", stream, config, pipe); + + if (!pipe) + { + err = IA_CSS_ERR_INVALID_ARGUMENTS; + goto exit; + } + + /* create per-frame ISP params object with default values + * from stream->isp_params_configs if one doesn't already exist + */ + if (!stream->per_frame_isp_params_configs) + { + err = sh_css_create_isp_params(stream, + &stream->per_frame_isp_params_configs); + if (err != IA_CSS_SUCCESS) + goto exit; + per_frame_config_created = true; + } + + params = stream->per_frame_isp_params_configs; + + /* update new ISP params object with the new config */ + if (!sh_css_init_isp_params_from_global(stream, params, false, pipe)) + { + err1 = IA_CSS_ERR_INVALID_ARGUMENTS; + } + + err2 = sh_css_init_isp_params_from_config(stream->pipes[0], params, config, pipe); + + if (per_frame_config_created) + { + ddr_ptrs = ¶ms->ddr_ptrs; + ddr_ptrs_size = ¶ms->ddr_ptrs_size; + /* create per pipe reference to general ddr_ptrs */ + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) { + ref_sh_css_ddr_address_map(ddr_ptrs, ¶ms->pipe_ddr_ptrs[i]); + params->pipe_ddr_ptrs_size[i] = *ddr_ptrs_size; + } + } + + /* now commit to ddr */ + err3 = sh_css_param_update_isp_params(stream->pipes[0], params, sh_css_sp_is_running(), pipe); + + /* The following code is intentional. The sh_css_init_sp_params_from_config and + * sh_css_init_isp_params_from_config throws an error when both DPC and BDS is enabled. + * The CSS API must pass this error information to the caller, ie. the host. + * We do not return this error immediately, but instead continue with updating the ISP params + * to enable testing of features which are currently in TR phase. */ + err = (err1 != IA_CSS_SUCCESS) ? err1 : + (err2 != IA_CSS_SUCCESS) ? err2 : + (err3 != IA_CSS_SUCCESS) ? err3 : err; +exit: + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} +#endif + +static enum ia_css_err +sh_css_init_isp_params_from_config(struct ia_css_pipe *pipe, + struct ia_css_isp_parameters *params, + const struct ia_css_isp_config *config, + struct ia_css_pipe *pipe_in) { + enum ia_css_err err = IA_CSS_SUCCESS; + bool is_dp_10bpp = true; + + assert(pipe); + + IA_CSS_ENTER_PRIVATE("pipe=%p, config=%p, params=%p", pipe, config, params); + + ia_css_set_configs(params, config); + + sh_css_set_nr_config(params, config->nr_config); + sh_css_set_ee_config(params, config->ee_config); + sh_css_set_baa_config(params, config->baa_config); + if ((pipe->mode < IA_CSS_PIPE_ID_NUM) && + (params->pipe_dvs_6axis_config[pipe->mode])) + sh_css_set_pipe_dvs_6axis_config(pipe, params, config->dvs_6axis_config); + sh_css_set_dz_config(params, config->dz_config); + sh_css_set_motion_vector(params, config->motion_vector); + sh_css_update_shading_table_status(pipe_in, params); + sh_css_set_shading_table(pipe->stream, params, config->shading_table); + sh_css_set_morph_table(params, config->morph_table); + sh_css_set_macc_table(params, config->macc_table); + sh_css_set_gamma_table(params, config->gamma_table); + sh_css_set_ctc_table(params, config->ctc_table); + /* ------ deprecated(bz675) : from ------ */ + sh_css_set_shading_settings(params, config->shading_settings); + /* ------ deprecated(bz675) : to ------ */ + + params->dis_coef_table_changed = (config->dvs_coefs); + params->dvs2_coef_table_changed = (config->dvs2_coefs); + + params->output_frame = config->output_frame; + params->isp_parameters_id = config->isp_config_id; + + /* Currently we do not offer CSS interface to set different + * configurations for DPC, i.e. depending on DPC being enabled + * before (NORM+OBC) or after. The folllowing code to set the + * DPC configuration should be updated when this interface is made + * available */ + if (atomisp_hw_is_isp2401) { + sh_css_set_dp_config(pipe, params, config->dp_config); + ia_css_set_param_exceptions(pipe, params); + } + + if (IA_CSS_SUCCESS == + sh_css_select_dp_10bpp_config(pipe, &is_dp_10bpp)) + { + /* return an error when both DPC and BDS is enabled by the + * user. */ + /* we do not exit from this point immediately to allow internal + * firmware feature testing. */ + if (is_dp_10bpp) { + err = IA_CSS_ERR_INVALID_ARGUMENTS; + } + } else + { + err = IA_CSS_ERR_INTERNAL_ERROR; + goto exit; + } + + if (!atomisp_hw_is_isp2401) + ia_css_set_param_exceptions(pipe, params); + +exit: + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +void +ia_css_stream_get_isp_config( + const struct ia_css_stream *stream, + struct ia_css_isp_config *config) +{ + IA_CSS_ENTER("void"); + ia_css_pipe_get_isp_config(stream->pipes[0], config); + IA_CSS_LEAVE("void"); +} + +void +ia_css_pipe_get_isp_config(struct ia_css_pipe *pipe, + struct ia_css_isp_config *config) +{ + struct ia_css_isp_parameters *params = NULL; + + assert(config); + + IA_CSS_ENTER("config=%p", config); + + params = pipe->stream->isp_params_configs; + assert(params); + + ia_css_get_configs(params, config); + + sh_css_get_ee_config(params, config->ee_config); + sh_css_get_baa_config(params, config->baa_config); + sh_css_get_pipe_dvs_6axis_config(pipe, params, config->dvs_6axis_config); + sh_css_get_dp_config(pipe, params, config->dp_config); + sh_css_get_macc_table(params, config->macc_table); + sh_css_get_gamma_table(params, config->gamma_table); + sh_css_get_ctc_table(params, config->ctc_table); + sh_css_get_dz_config(params, config->dz_config); + sh_css_get_motion_vector(params, config->motion_vector); + /* ------ deprecated(bz675) : from ------ */ + sh_css_get_shading_settings(params, config->shading_settings); + /* ------ deprecated(bz675) : to ------ */ + + config->output_frame = params->output_frame; + config->isp_config_id = params->isp_parameters_id; + + IA_CSS_LEAVE("void"); +} + +/* + * coding style says the return of "mmgr_NULL" is the error signal + * + * Deprecated: Implement mmgr_realloc() + */ +static bool realloc_isp_css_mm_buf( + hrt_vaddress *curr_buf, + size_t *curr_size, + size_t needed_size, + bool force, + enum ia_css_err *err, + uint16_t mmgr_attribute) +{ + s32 id; + + *err = IA_CSS_SUCCESS; + /* Possible optimization: add a function sh_css_isp_css_mm_realloc() + * and implement on top of hmm. */ + + IA_CSS_ENTER_PRIVATE("void"); + + if (!force && *curr_size >= needed_size) { + IA_CSS_LEAVE_PRIVATE("false"); + return false; + } + /* don't reallocate if single ref to buffer and same size */ + if (*curr_size == needed_size && ia_css_refcount_is_single(*curr_buf)) { + IA_CSS_LEAVE_PRIVATE("false"); + return false; + } + + id = IA_CSS_REFCOUNT_PARAM_BUFFER; + ia_css_refcount_decrement(id, *curr_buf); + *curr_buf = ia_css_refcount_increment(id, mmgr_alloc_attr(needed_size, + mmgr_attribute)); + + if (!*curr_buf) { + *err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + *curr_size = 0; + } else { + *curr_size = needed_size; + } + IA_CSS_LEAVE_PRIVATE("true"); + return true; +} + +static bool reallocate_buffer( + hrt_vaddress *curr_buf, + size_t *curr_size, + size_t needed_size, + bool force, + enum ia_css_err *err) +{ + bool ret; + u16 mmgr_attribute = MMGR_ATTRIBUTE_DEFAULT; + + IA_CSS_ENTER_PRIVATE("void"); + + ret = realloc_isp_css_mm_buf(curr_buf, + curr_size, needed_size, force, err, mmgr_attribute); + + IA_CSS_LEAVE_PRIVATE("ret=%d", ret); + return ret; +} + +struct ia_css_isp_3a_statistics * +ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) +{ + struct ia_css_isp_3a_statistics *me; + + IA_CSS_ENTER("grid=%p", grid); + + assert(grid); + + /* MW: Does "grid->enable" also control the histogram output ?? */ + if (!grid->enable) + return NULL; + + me = sh_css_calloc(1, sizeof(*me)); + if (!me) + goto err; + + if (grid->use_dmem) { + me->dmem_size = sizeof(struct ia_css_3a_output) * + grid->aligned_width * + grid->aligned_height; + } else { + me->vmem_size = ISP_S3ATBL_HI_LO_STRIDE_BYTES * + grid->aligned_height; + } +#if !defined(HAS_NO_HMEM) + me->hmem_size = sizeof_hmem(HMEM0_ID); +#endif + + /* All subsections need to be aligned to the system bus width */ + me->dmem_size = CEIL_MUL(me->dmem_size, HIVE_ISP_DDR_WORD_BYTES); + me->vmem_size = CEIL_MUL(me->vmem_size, HIVE_ISP_DDR_WORD_BYTES); + me->hmem_size = CEIL_MUL(me->hmem_size, HIVE_ISP_DDR_WORD_BYTES); + + me->size = me->dmem_size + me->vmem_size * 2 + me->hmem_size; + me->data_ptr = mmgr_malloc(me->size); + if (me->data_ptr == mmgr_NULL) { + sh_css_free(me); + me = NULL; + goto err; + } + if (me->dmem_size) + me->data.dmem.s3a_tbl = me->data_ptr; + if (me->vmem_size) { + me->data.vmem.s3a_tbl_hi = me->data_ptr + me->dmem_size; + me->data.vmem.s3a_tbl_lo = me->data_ptr + me->dmem_size + me->vmem_size; + } + if (me->hmem_size) + me->data_hmem.rgby_tbl = me->data_ptr + me->dmem_size + 2 * me->vmem_size; + +err: + IA_CSS_LEAVE("return=%p", me); + return me; +} + +void +ia_css_isp_3a_statistics_free(struct ia_css_isp_3a_statistics *me) +{ + if (me) { + hmm_free(me->data_ptr); + sh_css_free(me); + } +} + +struct ia_css_isp_skc_dvs_statistics *ia_css_skc_dvs_statistics_allocate(void) +{ + return NULL; +} + +struct ia_css_metadata * +ia_css_metadata_allocate(const struct ia_css_metadata_info *metadata_info) +{ + struct ia_css_metadata *md = NULL; + + IA_CSS_ENTER(""); + + if (metadata_info->size == 0) + return NULL; + + md = sh_css_malloc(sizeof(*md)); + if (!md) + goto error; + + md->info = *metadata_info; + md->exp_id = 0; + md->address = mmgr_malloc(metadata_info->size); + if (md->address == mmgr_NULL) + goto error; + + IA_CSS_LEAVE("return=%p", md); + return md; + +error: + ia_css_metadata_free(md); + IA_CSS_LEAVE("return=%p", NULL); + return NULL; +} + +void +ia_css_metadata_free(struct ia_css_metadata *me) +{ + if (me) { + /* The enter and leave macros are placed inside + * the condition to avoid false logging of metadata + * free events when metadata is disabled. + * We found this to be confusing during development + * and debugging. */ + IA_CSS_ENTER("me=%p", me); + hmm_free(me->address); + sh_css_free(me); + IA_CSS_LEAVE("void"); + } +} + +void +ia_css_metadata_free_multiple(unsigned int num_bufs, + struct ia_css_metadata **bufs) +{ + unsigned int i; + + if (bufs) { + for (i = 0; i < num_bufs; i++) + ia_css_metadata_free(bufs[i]); + } +} + +static unsigned int g_param_buffer_dequeue_count; +static unsigned int g_param_buffer_enqueue_count; + +enum ia_css_err +ia_css_stream_isp_parameters_init(struct ia_css_stream *stream) { + enum ia_css_err err = IA_CSS_SUCCESS; + unsigned int i; + struct sh_css_ddr_address_map *ddr_ptrs; + struct sh_css_ddr_address_map_size *ddr_ptrs_size; + struct ia_css_isp_parameters *params; + + assert(stream); + IA_CSS_ENTER_PRIVATE("void"); + + if (!stream) + { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS); + return IA_CSS_ERR_INVALID_ARGUMENTS; + } + /* TMP: tracking of paramsets */ + g_param_buffer_dequeue_count = 0; + g_param_buffer_enqueue_count = 0; + + stream->per_frame_isp_params_configs = NULL; + err = sh_css_create_isp_params(stream, + &stream->isp_params_configs); + if (err != IA_CSS_SUCCESS) + goto ERR; + + params = stream->isp_params_configs; + if (!sh_css_init_isp_params_from_global(stream, params, true, NULL)) + { + /* we do not return the error immediately to enable internal + * firmware feature testing */ + err = IA_CSS_ERR_INVALID_ARGUMENTS; + } + + ddr_ptrs = ¶ms->ddr_ptrs; + ddr_ptrs_size = ¶ms->ddr_ptrs_size; + + /* create per pipe reference to general ddr_ptrs */ + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) + { + ref_sh_css_ddr_address_map(ddr_ptrs, ¶ms->pipe_ddr_ptrs[i]); + params->pipe_ddr_ptrs_size[i] = *ddr_ptrs_size; + } + +ERR: + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +static void +ia_css_set_sdis_config( + struct ia_css_isp_parameters *params, + const struct ia_css_dvs_coefficients *dvs_coefs) +{ + ia_css_set_sdis_horicoef_config(params, dvs_coefs); + ia_css_set_sdis_vertcoef_config(params, dvs_coefs); + ia_css_set_sdis_horiproj_config(params, dvs_coefs); + ia_css_set_sdis_vertproj_config(params, dvs_coefs); +} + +static void +ia_css_set_sdis2_config( + struct ia_css_isp_parameters *params, + const struct ia_css_dvs2_coefficients *dvs2_coefs) +{ + ia_css_set_sdis2_horicoef_config(params, dvs2_coefs); + ia_css_set_sdis2_vertcoef_config(params, dvs2_coefs); + ia_css_set_sdis2_horiproj_config(params, dvs2_coefs); + ia_css_set_sdis2_vertproj_config(params, dvs2_coefs); +} + +static enum ia_css_err +sh_css_create_isp_params(struct ia_css_stream *stream, + struct ia_css_isp_parameters **isp_params_out) { + bool succ = true; + unsigned int i; + struct sh_css_ddr_address_map *ddr_ptrs; + struct sh_css_ddr_address_map_size *ddr_ptrs_size; + enum ia_css_err err = IA_CSS_SUCCESS; + size_t params_size; + struct ia_css_isp_parameters *params = + sh_css_malloc(sizeof(struct ia_css_isp_parameters)); + + if (!params) + { + *isp_params_out = NULL; + err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + IA_CSS_ERROR("%s:%d error: cannot allocate memory", __FILE__, __LINE__); + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } else + { + memset(params, 0, sizeof(struct ia_css_isp_parameters)); + } + + ddr_ptrs = ¶ms->ddr_ptrs; + ddr_ptrs_size = ¶ms->ddr_ptrs_size; + + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) + { + memset(¶ms->pipe_ddr_ptrs[i], 0, + sizeof(params->pipe_ddr_ptrs[i])); + memset(¶ms->pipe_ddr_ptrs_size[i], 0, + sizeof(params->pipe_ddr_ptrs_size[i])); + } + + memset(ddr_ptrs, 0, sizeof(*ddr_ptrs)); + memset(ddr_ptrs_size, 0, sizeof(*ddr_ptrs_size)); + + params_size = sizeof(params->uds); + ddr_ptrs_size->isp_param = params_size; + ddr_ptrs->isp_param = + ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_BUFFER, + mmgr_malloc(params_size)); + succ &= (ddr_ptrs->isp_param != mmgr_NULL); + + ddr_ptrs_size->macc_tbl = sizeof(struct ia_css_macc_table); + ddr_ptrs->macc_tbl = + ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_BUFFER, + mmgr_malloc(sizeof(struct ia_css_macc_table))); + succ &= (ddr_ptrs->macc_tbl != mmgr_NULL); + + *isp_params_out = params; + return err; +} + +static bool +sh_css_init_isp_params_from_global(struct ia_css_stream *stream, + struct ia_css_isp_parameters *params, + bool use_default_config, + struct ia_css_pipe *pipe_in) +{ + bool retval = true; + int i = 0; + bool is_dp_10bpp = true; + unsigned int isp_pipe_version = ia_css_pipe_get_isp_pipe_version( + stream->pipes[0]); + struct ia_css_isp_parameters *stream_params = stream->isp_params_configs; + + if (!use_default_config && !stream_params) { + retval = false; + goto exit; + } + + params->output_frame = NULL; + params->isp_parameters_id = 0; + + if (use_default_config) { + ia_css_set_xnr3_config(params, &default_xnr3_config); + + sh_css_set_nr_config(params, &default_nr_config); + sh_css_set_ee_config(params, &default_ee_config); + if (isp_pipe_version == SH_CSS_ISP_PIPE_VERSION_1) + sh_css_set_macc_table(params, &default_macc_table); + else if (isp_pipe_version == SH_CSS_ISP_PIPE_VERSION_2_2) + sh_css_set_macc_table(params, &default_macc2_table); + sh_css_set_gamma_table(params, &default_gamma_table); + sh_css_set_ctc_table(params, &default_ctc_table); + sh_css_set_baa_config(params, &default_baa_config); + sh_css_set_dz_config(params, &default_dz_config); + /* ------ deprecated(bz675) : from ------ */ + sh_css_set_shading_settings(params, &default_shading_settings); + /* ------ deprecated(bz675) : to ------ */ + + ia_css_set_s3a_config(params, &default_3a_config); + ia_css_set_wb_config(params, &default_wb_config); + ia_css_set_csc_config(params, &default_cc_config); + ia_css_set_tnr_config(params, &default_tnr_config); + ia_css_set_ob_config(params, &default_ob_config); + ia_css_set_dp_config(params, &default_dp_config); + + if (!atomisp_hw_is_isp2401) { + ia_css_set_param_exceptions(pipe_in, params); + } else { + for (i = 0; i < stream->num_pipes; i++) { + if (sh_css_select_dp_10bpp_config(stream->pipes[i], + &is_dp_10bpp) == IA_CSS_SUCCESS) { + /* set the return value as false if both DPC and + * BDS is enabled by the user. But we do not return + * the value immediately to enable internal firmware + * feature testing. */ + if (is_dp_10bpp) { + sh_css_set_dp_config(stream->pipes[i], params, &default_dp_10bpp_config); + } else { + sh_css_set_dp_config(stream->pipes[i], params, &default_dp_config); + } + } else { + retval = false; + goto exit; + } + + ia_css_set_param_exceptions(stream->pipes[i], params); + } + } + + ia_css_set_de_config(params, &default_de_config); + ia_css_set_gc_config(params, &default_gc_config); + ia_css_set_anr_config(params, &default_anr_config); + ia_css_set_anr2_config(params, &default_anr_thres); + ia_css_set_ce_config(params, &default_ce_config); + ia_css_set_xnr_table_config(params, &default_xnr_table); + ia_css_set_ecd_config(params, &default_ecd_config); + ia_css_set_ynr_config(params, &default_ynr_config); + ia_css_set_fc_config(params, &default_fc_config); + ia_css_set_cnr_config(params, &default_cnr_config); + ia_css_set_macc_config(params, &default_macc_config); + ia_css_set_ctc_config(params, &default_ctc_config); + ia_css_set_aa_config(params, &default_aa_config); + ia_css_set_r_gamma_config(params, &default_r_gamma_table); + ia_css_set_g_gamma_config(params, &default_g_gamma_table); + ia_css_set_b_gamma_config(params, &default_b_gamma_table); + ia_css_set_yuv2rgb_config(params, &default_yuv2rgb_cc_config); + ia_css_set_rgb2yuv_config(params, &default_rgb2yuv_cc_config); + ia_css_set_xnr_config(params, &default_xnr_config); + ia_css_set_sdis_config(params, &default_sdis_config); + ia_css_set_sdis2_config(params, &default_sdis2_config); + ia_css_set_formats_config(params, &default_formats_config); + + params->fpn_config.data = NULL; + params->config_changed[IA_CSS_FPN_ID] = true; + params->fpn_config.enabled = 0; + + params->motion_config = default_motion_config; + params->motion_config_changed = true; + + params->morph_table = NULL; + params->morph_table_changed = true; + + params->sc_table = NULL; + params->sc_table_changed = true; + params->sc_table_dirty = false; + params->sc_table_last_pipe_num = 0; + + ia_css_sdis2_clear_coefficients(¶ms->dvs2_coefs); + params->dvs2_coef_table_changed = true; + + ia_css_sdis_clear_coefficients(¶ms->dvs_coefs); + params->dis_coef_table_changed = true; + } else { + ia_css_set_xnr3_config(params, &stream_params->xnr3_config); + + sh_css_set_nr_config(params, &stream_params->nr_config); + sh_css_set_ee_config(params, &stream_params->ee_config); + if (isp_pipe_version == SH_CSS_ISP_PIPE_VERSION_1) + sh_css_set_macc_table(params, &stream_params->macc_table); + else if (isp_pipe_version == SH_CSS_ISP_PIPE_VERSION_2_2) + sh_css_set_macc_table(params, &stream_params->macc_table); + sh_css_set_gamma_table(params, &stream_params->gc_table); + sh_css_set_ctc_table(params, &stream_params->ctc_table); + sh_css_set_baa_config(params, &stream_params->bds_config); + sh_css_set_dz_config(params, &stream_params->dz_config); + /* ------ deprecated(bz675) : from ------ */ + sh_css_set_shading_settings(params, &stream_params->shading_settings); + /* ------ deprecated(bz675) : to ------ */ + + ia_css_set_s3a_config(params, &stream_params->s3a_config); + ia_css_set_wb_config(params, &stream_params->wb_config); + ia_css_set_csc_config(params, &stream_params->cc_config); + ia_css_set_tnr_config(params, &stream_params->tnr_config); + ia_css_set_ob_config(params, &stream_params->ob_config); + ia_css_set_dp_config(params, &stream_params->dp_config); + ia_css_set_de_config(params, &stream_params->de_config); + ia_css_set_gc_config(params, &stream_params->gc_config); + ia_css_set_anr_config(params, &stream_params->anr_config); + ia_css_set_anr2_config(params, &stream_params->anr_thres); + ia_css_set_ce_config(params, &stream_params->ce_config); + ia_css_set_xnr_table_config(params, &stream_params->xnr_table); + ia_css_set_ecd_config(params, &stream_params->ecd_config); + ia_css_set_ynr_config(params, &stream_params->ynr_config); + ia_css_set_fc_config(params, &stream_params->fc_config); + ia_css_set_cnr_config(params, &stream_params->cnr_config); + ia_css_set_macc_config(params, &stream_params->macc_config); + ia_css_set_ctc_config(params, &stream_params->ctc_config); + ia_css_set_aa_config(params, &stream_params->aa_config); + ia_css_set_r_gamma_config(params, &stream_params->r_gamma_table); + ia_css_set_g_gamma_config(params, &stream_params->g_gamma_table); + ia_css_set_b_gamma_config(params, &stream_params->b_gamma_table); + ia_css_set_yuv2rgb_config(params, &stream_params->yuv2rgb_cc_config); + ia_css_set_rgb2yuv_config(params, &stream_params->rgb2yuv_cc_config); + ia_css_set_xnr_config(params, &stream_params->xnr_config); + ia_css_set_formats_config(params, &stream_params->formats_config); + + for (i = 0; i < stream->num_pipes; i++) { + if (IA_CSS_SUCCESS == + sh_css_select_dp_10bpp_config(stream->pipes[i], &is_dp_10bpp)) { + /* set the return value as false if both DPC and + * BDS is enabled by the user. But we do not return + * the value immediately to enable internal firmware + * feature testing. */ + + if (is_dp_10bpp) { + retval = false; + /* FIXME: should it ignore this error? */ + } + } else { + retval = false; + goto exit; + } + if (atomisp_hw_is_isp2401) { + if (stream->pipes[i]->mode < IA_CSS_PIPE_ID_NUM) { + sh_css_set_dp_config(stream->pipes[i], params, + &stream_params->pipe_dp_config[stream->pipes[i]->mode]); + ia_css_set_param_exceptions(stream->pipes[i], params); + } else { + retval = false; + goto exit; + } + } + } + + if (!atomisp_hw_is_isp2401) + ia_css_set_param_exceptions(pipe_in, params); + + params->fpn_config.data = stream_params->fpn_config.data; + params->config_changed[IA_CSS_FPN_ID] = + stream_params->config_changed[IA_CSS_FPN_ID]; + params->fpn_config.enabled = stream_params->fpn_config.enabled; + + sh_css_set_motion_vector(params, &stream_params->motion_config); + sh_css_set_morph_table(params, stream_params->morph_table); + + if (stream_params->sc_table) { + sh_css_update_shading_table_status(pipe_in, params); + sh_css_set_shading_table(stream, params, stream_params->sc_table); + } else { + params->sc_table = NULL; + params->sc_table_changed = true; + params->sc_table_dirty = false; + params->sc_table_last_pipe_num = 0; + } + + /* Only IA_CSS_PIPE_ID_VIDEO & IA_CSS_PIPE_ID_CAPTURE will support dvs_6axis_config*/ + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) { + if (stream_params->pipe_dvs_6axis_config[i]) { + if (params->pipe_dvs_6axis_config[i]) { + copy_dvs_6axis_table(params->pipe_dvs_6axis_config[i], + stream_params->pipe_dvs_6axis_config[i]); + } else { + params->pipe_dvs_6axis_config[i] = + generate_dvs_6axis_table_from_config(stream_params->pipe_dvs_6axis_config[i]); + } + } + } + ia_css_set_sdis_config(params, &stream_params->dvs_coefs); + params->dis_coef_table_changed = stream_params->dis_coef_table_changed; + + ia_css_set_sdis2_config(params, &stream_params->dvs2_coefs); + params->dvs2_coef_table_changed = stream_params->dvs2_coef_table_changed; + params->sensor_binning = stream_params->sensor_binning; + } + +exit: + return retval; +} + +enum ia_css_err +sh_css_params_init(void) { + int i, p; + + IA_CSS_ENTER_PRIVATE("void"); + + /* TMP: tracking of paramsets */ + g_param_buffer_dequeue_count = 0; + g_param_buffer_enqueue_count = 0; + + for (p = 0; p < IA_CSS_PIPE_ID_NUM; p++) + { + for (i = 0; i < SH_CSS_MAX_STAGES; i++) { + xmem_sp_stage_ptrs[p][i] = + ia_css_refcount_increment(-1, + mmgr_calloc(1, + sizeof(struct sh_css_sp_stage))); + xmem_isp_stage_ptrs[p][i] = + ia_css_refcount_increment(-1, + mmgr_calloc(1, + sizeof(struct sh_css_isp_stage))); + + if ((xmem_sp_stage_ptrs[p][i] == mmgr_NULL) || + (xmem_isp_stage_ptrs[p][i] == mmgr_NULL)) { + sh_css_params_uninit(); + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + } + } + + ia_css_config_gamma_table(); + ia_css_config_ctc_table(); + ia_css_config_rgb_gamma_tables(); + ia_css_config_xnr_table(); + + sp_ddr_ptrs = ia_css_refcount_increment(-1, mmgr_calloc(1, + CEIL_MUL(sizeof(struct sh_css_ddr_address_map), + HIVE_ISP_DDR_WORD_BYTES))); + xmem_sp_group_ptrs = ia_css_refcount_increment(-1, mmgr_calloc(1, + sizeof(struct sh_css_sp_group))); + + if ((sp_ddr_ptrs == mmgr_NULL) || + (xmem_sp_group_ptrs == mmgr_NULL)) + { + ia_css_uninit(); + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS); + return IA_CSS_SUCCESS; +} + +static void host_lut_store(const void *lut) +{ + unsigned int i; + + for (i = 0; i < N_GDC_ID; i++) + gdc_lut_store((gdc_ID_t)i, (const int (*)[HRT_GDC_N]) lut); +} + +/* Note that allocation is in ipu address space. */ +inline hrt_vaddress sh_css_params_alloc_gdc_lut(void) +{ + return mmgr_malloc(sizeof(zoom_table)); +} + +inline void sh_css_params_free_gdc_lut(hrt_vaddress addr) +{ + if (addr != mmgr_NULL) + hmm_free(addr); +} + +enum ia_css_err ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe, + const void *lut) +{ + enum ia_css_err err = IA_CSS_SUCCESS; + bool stream_started = false; + + IA_CSS_ENTER("pipe=%p lut=%p", pipe, lut); + + if (!lut || !pipe) { + err = IA_CSS_ERR_INVALID_ARGUMENTS; + IA_CSS_LEAVE("err=%d", err); + return err; + } + + /* If the pipe belongs to a stream and the stream has started, it is not + * safe to store lut to gdc HW. If pipe->stream is NULL, then no stream is + * created with this pipe, so it is safe to do this operation as long as + * ia_css_init() has been called. */ + if (pipe->stream && pipe->stream->started) { + ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, + "unable to set scaler lut since stream has started\n"); + stream_started = true; + err = IA_CSS_ERR_NOT_SUPPORTED; + } + + /* Free any existing tables. */ + sh_css_params_free_gdc_lut(pipe->scaler_pp_lut); + pipe->scaler_pp_lut = mmgr_NULL; + + if (!stream_started) { + if (!atomisp_hw_is_isp2401) + pipe->scaler_pp_lut = mmgr_malloc(sizeof(zoom_table)); + else + pipe->scaler_pp_lut = sh_css_params_alloc_gdc_lut(); + + if (pipe->scaler_pp_lut == mmgr_NULL) { + ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, + "unable to allocate scaler_pp_lut\n"); + err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } else { + gdc_lut_convert_to_isp_format((const int(*)[HRT_GDC_N])lut, + interleaved_lut_temp); + mmgr_store(pipe->scaler_pp_lut, + (int *)interleaved_lut_temp, + sizeof(zoom_table)); + } + } + + IA_CSS_LEAVE("lut(%u) err=%d", pipe->scaler_pp_lut, err); + return err; +} + +/* if pipe is NULL, returns default lut addr. */ +hrt_vaddress sh_css_pipe_get_pp_gdc_lut(const struct ia_css_pipe *pipe) +{ + assert(pipe); + + if (pipe->scaler_pp_lut != mmgr_NULL) + return pipe->scaler_pp_lut; + else + return sh_css_params_get_default_gdc_lut(); +} + +enum ia_css_err sh_css_params_map_and_store_default_gdc_lut(void) +{ + enum ia_css_err err = IA_CSS_SUCCESS; + + IA_CSS_ENTER_PRIVATE("void"); + + /* Is table already mapped? Nothing to do if it is mapped. */ + if (default_gdc_lut != mmgr_NULL) + return err; + + host_lut_store((void *)zoom_table); + + if (!atomisp_hw_is_isp2401) + default_gdc_lut = mmgr_malloc(sizeof(zoom_table)); + else + default_gdc_lut = sh_css_params_alloc_gdc_lut(); + + if (default_gdc_lut == mmgr_NULL) + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + + gdc_lut_convert_to_isp_format((const int(*)[HRT_GDC_N])zoom_table, + interleaved_lut_temp); + mmgr_store(default_gdc_lut, (int *)interleaved_lut_temp, + sizeof(zoom_table)); + + IA_CSS_LEAVE_PRIVATE("lut(%u) err=%d", default_gdc_lut, err); + return err; +} + +void sh_css_params_free_default_gdc_lut(void) +{ + IA_CSS_ENTER_PRIVATE("void"); + + sh_css_params_free_gdc_lut(default_gdc_lut); + default_gdc_lut = mmgr_NULL; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +hrt_vaddress sh_css_params_get_default_gdc_lut(void) +{ + return default_gdc_lut; +} + +static void free_param_set_callback( + hrt_vaddress ptr) +{ + IA_CSS_ENTER_PRIVATE("void"); + + free_ia_css_isp_parameter_set_info(ptr); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void free_buffer_callback( + hrt_vaddress ptr) +{ + IA_CSS_ENTER_PRIVATE("void"); + + hmm_free(ptr); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void +sh_css_param_clear_param_sets(void) +{ + IA_CSS_ENTER_PRIVATE("void"); + + ia_css_refcount_clear(IA_CSS_REFCOUNT_PARAM_SET_POOL, &free_param_set_callback); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +/* + * MW: we can define hmm_free() to return a NULL + * then you can write ptr = hmm_free(ptr); + */ +#define safe_free(id, x) \ + do { \ + ia_css_refcount_decrement(id, x); \ + (x) = mmgr_NULL; \ + } while (0) + +static void free_map(struct sh_css_ddr_address_map *map) +{ + unsigned int i; + + hrt_vaddress *addrs = (hrt_vaddress *)map; + + IA_CSS_ENTER_PRIVATE("void"); + + /* free buffers */ + for (i = 0; i < (sizeof(struct sh_css_ddr_address_map_size) / + sizeof(size_t)); i++) { + if (addrs[i] == mmgr_NULL) + continue; + safe_free(IA_CSS_REFCOUNT_PARAM_BUFFER, addrs[i]); + } + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void +ia_css_stream_isp_parameters_uninit(struct ia_css_stream *stream) +{ + int i; + struct ia_css_isp_parameters *params = stream->isp_params_configs; + struct ia_css_isp_parameters *per_frame_params = + stream->per_frame_isp_params_configs; + + IA_CSS_ENTER_PRIVATE("void"); + if (!params) { + IA_CSS_LEAVE_PRIVATE("isp_param_configs is NULL"); + return; + } + + /* free existing ddr_ptr maps */ + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) { + free_map(¶ms->pipe_ddr_ptrs[i]); + if (per_frame_params) + free_map(&per_frame_params->pipe_ddr_ptrs[i]); + /* Free up theDVS table memory blocks before recomputing new table */ + if (params->pipe_dvs_6axis_config[i]) + free_dvs_6axis_table(¶ms->pipe_dvs_6axis_config[i]); + if (per_frame_params && per_frame_params->pipe_dvs_6axis_config[i]) + free_dvs_6axis_table(&per_frame_params->pipe_dvs_6axis_config[i]); + } + free_map(¶ms->ddr_ptrs); + if (per_frame_params) + free_map(&per_frame_params->ddr_ptrs); + + if (params->fpn_config.data) { + sh_css_free(params->fpn_config.data); + params->fpn_config.data = NULL; + } + + /* Free up sc_config (temporal shading table) if it is allocated. */ + if (params->sc_config) { + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + } + if (per_frame_params) { + if (per_frame_params->sc_config) { + ia_css_shading_table_free(per_frame_params->sc_config); + per_frame_params->sc_config = NULL; + } + } + + sh_css_free(params); + if (per_frame_params) + sh_css_free(per_frame_params); + stream->isp_params_configs = NULL; + stream->per_frame_isp_params_configs = NULL; + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void +sh_css_params_uninit(void) +{ + unsigned int p, i; + + IA_CSS_ENTER_PRIVATE("void"); + + ia_css_refcount_decrement(-1, sp_ddr_ptrs); + sp_ddr_ptrs = mmgr_NULL; + ia_css_refcount_decrement(-1, xmem_sp_group_ptrs); + xmem_sp_group_ptrs = mmgr_NULL; + + for (p = 0; p < IA_CSS_PIPE_ID_NUM; p++) + for (i = 0; i < SH_CSS_MAX_STAGES; i++) { + ia_css_refcount_decrement(-1, xmem_sp_stage_ptrs[p][i]); + xmem_sp_stage_ptrs[p][i] = mmgr_NULL; + ia_css_refcount_decrement(-1, xmem_isp_stage_ptrs[p][i]); + xmem_isp_stage_ptrs[p][i] = mmgr_NULL; + } + + /* go through the pools to clear references */ + ia_css_refcount_clear(IA_CSS_REFCOUNT_PARAM_SET_POOL, &free_param_set_callback); + ia_css_refcount_clear(IA_CSS_REFCOUNT_PARAM_BUFFER, &free_buffer_callback); + ia_css_refcount_clear(-1, &free_buffer_callback); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static struct ia_css_host_data * +convert_allocate_morph_plane( + unsigned short *data, + unsigned int width, + unsigned int height, + unsigned int aligned_width) +{ + unsigned int i, j, padding, w; + struct ia_css_host_data *me; + unsigned int isp_data_size; + u16 *isp_data_ptr; + + IA_CSS_ENTER_PRIVATE("void"); + + /* currently we don't have morph table interpolation yet, + * so we allow a wider table to be used. This will be removed + * in the future. */ + if (width > aligned_width) { + padding = 0; + w = aligned_width; + } else { + padding = aligned_width - width; + w = width; + } + isp_data_size = height * (w + padding) * sizeof(uint16_t); + + me = ia_css_host_data_allocate((size_t)isp_data_size); + + if (!me) { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return NULL; + } + + isp_data_ptr = (uint16_t *)me->address; + + memset(isp_data_ptr, 0, (size_t)isp_data_size); + + for (i = 0; i < height; i++) { + for (j = 0; j < w; j++) + *isp_data_ptr++ = (uint16_t)data[j]; + isp_data_ptr += padding; + data += width; + } + + IA_CSS_LEAVE_PRIVATE("void"); + return me; +} + +static enum ia_css_err +store_morph_plane( + unsigned short *data, + unsigned int width, + unsigned int height, + hrt_vaddress dest, + unsigned int aligned_width) { + struct ia_css_host_data *isp_data; + + assert(dest != mmgr_NULL); + + isp_data = convert_allocate_morph_plane(data, width, height, aligned_width); + if (!isp_data) + { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + ia_css_params_store_ia_css_host_data(dest, isp_data); + + ia_css_host_data_free(isp_data); + return IA_CSS_SUCCESS; +} + +static void sh_css_update_isp_params_to_ddr( + struct ia_css_isp_parameters *params, + hrt_vaddress ddr_ptr) +{ + size_t size = sizeof(params->uds); + + IA_CSS_ENTER_PRIVATE("void"); + + assert(params); + + mmgr_store(ddr_ptr, ¶ms->uds, size); + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void sh_css_update_isp_mem_params_to_ddr( + const struct ia_css_binary *binary, + hrt_vaddress ddr_mem_ptr, + size_t size, + enum ia_css_isp_memories mem) +{ + const struct ia_css_host_data *params; + + IA_CSS_ENTER_PRIVATE("void"); + + params = ia_css_isp_param_get_mem_init(&binary->mem_params, + IA_CSS_PARAM_CLASS_PARAM, mem); + mmgr_store(ddr_mem_ptr, params->address, size); + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void ia_css_dequeue_param_buffers(/*unsigned int pipe_num*/ void) +{ + unsigned int i; + hrt_vaddress cpy; + enum sh_css_queue_id param_queue_ids[3] = { IA_CSS_PARAMETER_SET_QUEUE_ID, + IA_CSS_PER_FRAME_PARAMETER_SET_QUEUE_ID, + SH_CSS_INVALID_QUEUE_ID + }; + + IA_CSS_ENTER_PRIVATE("void"); + + if (!sh_css_sp_is_running()) { + IA_CSS_LEAVE_PRIVATE("sp is not running"); + /* SP is not running. The queues are not valid */ + return; + } + + for (i = 0; SH_CSS_INVALID_QUEUE_ID != param_queue_ids[i]; i++) { + cpy = (hrt_vaddress)0; + /* clean-up old copy */ + while (ia_css_bufq_dequeue_buffer(param_queue_ids[i], + (uint32_t *)&cpy) == IA_CSS_SUCCESS) { + /* TMP: keep track of dequeued param set count + */ + g_param_buffer_dequeue_count++; + ia_css_bufq_enqueue_psys_event( + IA_CSS_PSYS_SW_EVENT_BUFFER_DEQUEUED, + 0, + param_queue_ids[i], + 0); + + IA_CSS_LOG("dequeued param set %x from %d, release ref", cpy, 0); + free_ia_css_isp_parameter_set_info(cpy); + cpy = (hrt_vaddress)0; + } + } + + IA_CSS_LEAVE_PRIVATE("void"); +} + +static void +process_kernel_parameters(unsigned int pipe_id, + struct ia_css_pipeline_stage *stage, + struct ia_css_isp_parameters *params, + unsigned int isp_pipe_version, + unsigned int raw_bit_depth) +{ + unsigned int param_id; + + (void)isp_pipe_version; + (void)raw_bit_depth; + + sh_css_enable_pipeline(stage->binary); + + if (params->config_changed[IA_CSS_OB_ID]) { + ia_css_ob_configure(¶ms->stream_configs.ob, + isp_pipe_version, raw_bit_depth); + } + if (params->config_changed[IA_CSS_S3A_ID]) { + ia_css_s3a_configure(raw_bit_depth); + } + /* Copy stage uds parameters to config, since they can differ per stage. + */ + params->crop_config.crop_pos = params->uds[stage->stage_num].crop_pos; + params->uds_config.crop_pos = params->uds[stage->stage_num].crop_pos; + params->uds_config.uds = params->uds[stage->stage_num].uds; + /* Call parameter process functions for all kernels */ + /* Skip SC, since that is called on a temp sc table */ + for (param_id = 0; param_id < IA_CSS_NUM_PARAMETER_IDS; param_id++) { + if (param_id == IA_CSS_SC_ID) continue; + if (params->config_changed[param_id]) + ia_css_kernel_process_param[param_id](pipe_id, stage, params); + } +} + +enum ia_css_err +sh_css_param_update_isp_params(struct ia_css_pipe *curr_pipe, + struct ia_css_isp_parameters *params, + bool commit, + struct ia_css_pipe *pipe_in) { + enum ia_css_err err = IA_CSS_SUCCESS; + hrt_vaddress cpy; + int i; + unsigned int raw_bit_depth = 10; + unsigned int isp_pipe_version = SH_CSS_ISP_PIPE_VERSION_1; + bool acc_cluster_params_changed = false; + unsigned int thread_id, pipe_num; + + (void)acc_cluster_params_changed; + + assert(curr_pipe); + + IA_CSS_ENTER_PRIVATE("pipe=%p, isp_parameters_id=%d", pipe_in, params->isp_parameters_id); + raw_bit_depth = ia_css_stream_input_format_bits_per_pixel(curr_pipe->stream); + + /* now make the map available to the sp */ + if (!commit) + { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + /* enqueue a copies of the mem_map to + the designated pipelines */ + for (i = 0; i < curr_pipe->stream->num_pipes; i++) + { + struct ia_css_pipe *pipe; + struct sh_css_ddr_address_map *cur_map; + struct sh_css_ddr_address_map_size *cur_map_size; + struct ia_css_isp_parameter_set_info isp_params_info; + struct ia_css_pipeline *pipeline; + struct ia_css_pipeline_stage *stage; + + enum sh_css_queue_id queue_id; + + pipe = curr_pipe->stream->pipes[i]; + pipeline = ia_css_pipe_get_pipeline(pipe); + pipe_num = ia_css_pipe_get_pipe_num(pipe); + isp_pipe_version = ia_css_pipe_get_isp_pipe_version(pipe); + ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id); + +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) + ia_css_query_internal_queue_id(params->output_frame + ? IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET + : IA_CSS_BUFFER_TYPE_PARAMETER_SET, + thread_id, &queue_id); +#else + ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_PARAMETER_SET, thread_id, + &queue_id); +#endif + if (!sh_css_sp_is_running()) { + /* SP is not running. The queues are not valid */ + err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE; + break; + } + cur_map = ¶ms->pipe_ddr_ptrs[pipeline->pipe_id]; + cur_map_size = ¶ms->pipe_ddr_ptrs_size[pipeline->pipe_id]; + + /* TODO: Normally, zoom and motion parameters shouldn't + * be part of "isp_params" as it is resolution/pipe dependent + * Therefore, move the zoom config elsewhere (e.g. shading + * table can be taken as an example! @GC + * */ + { + /* we have to do this per pipeline because */ + /* the processing is a.o. resolution dependent */ + err = ia_css_process_zoom_and_motion(params, + pipeline->stages); + if (err != IA_CSS_SUCCESS) + return err; + } + /* check if to actually update the parameters for this pipe */ + /* When API change is implemented making good distinction between + * stream config and pipe config this skipping code can be moved out of the #ifdef */ + if (pipe_in && (pipe != pipe_in)) { + IA_CSS_LOG("skipping pipe %p", pipe); + continue; + } + + /* BZ 125915, should be moved till after "update other buff" */ + /* update the other buffers to the pipe specific copies */ + for (stage = pipeline->stages; stage; stage = stage->next) { + unsigned int mem; + + if (!stage || !stage->binary) + continue; + + process_kernel_parameters(pipeline->pipe_id, + stage, params, + isp_pipe_version, raw_bit_depth); + + err = sh_css_params_write_to_ddr_internal( + pipe, + pipeline->pipe_id, + params, + stage, + cur_map, + cur_map_size); + + if (err != IA_CSS_SUCCESS) + break; + for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) { + params->isp_mem_params_changed + [pipeline->pipe_id][stage->stage_num][mem] = false; + } + } /* for */ + if (err != IA_CSS_SUCCESS) + break; + /* update isp_params to pipe specific copies */ + if (params->isp_params_changed) { + reallocate_buffer(&cur_map->isp_param, + &cur_map_size->isp_param, + cur_map_size->isp_param, + true, + &err); + if (err != IA_CSS_SUCCESS) + break; + sh_css_update_isp_params_to_ddr(params, cur_map->isp_param); + } + + /* last make referenced copy */ + err = ref_sh_css_ddr_address_map( + cur_map, + &isp_params_info.mem_map); + if (err != IA_CSS_SUCCESS) + break; + + /* Update Parameters ID */ + isp_params_info.isp_parameters_id = params->isp_parameters_id; + + /* Update output frame pointer */ + isp_params_info.output_frame_ptr = + (params->output_frame) ? params->output_frame->data : mmgr_NULL; + + /* now write the copy to ddr */ + err = write_ia_css_isp_parameter_set_info_to_ddr(&isp_params_info, &cpy); + if (err != IA_CSS_SUCCESS) + break; + + /* enqueue the set to sp */ + IA_CSS_LOG("queue param set %x to %d", cpy, thread_id); + + err = ia_css_bufq_enqueue_buffer(thread_id, queue_id, (uint32_t)cpy); + if (err != IA_CSS_SUCCESS) { + free_ia_css_isp_parameter_set_info(cpy); +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) + IA_CSS_LOG("pfp: FAILED to add config id %d for OF %d to q %d on thread %d", + isp_params_info.isp_parameters_id, + isp_params_info.output_frame_ptr, + queue_id, thread_id); +#endif + break; + } else { + /* TMP: check discrepancy between nr of enqueued + * parameter sets and dequeued sets + */ + g_param_buffer_enqueue_count++; + assert(g_param_buffer_enqueue_count < g_param_buffer_dequeue_count + 50); + /* + * Tell the SP which queues are not empty, + * by sending the software event. + */ + if (!sh_css_sp_is_running()) { + /* SP is not running. The queues are not valid */ + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE); + return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE; + } + ia_css_bufq_enqueue_psys_event( + IA_CSS_PSYS_SW_EVENT_BUFFER_ENQUEUED, + (uint8_t)thread_id, + (uint8_t)queue_id, + 0); +#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) + IA_CSS_LOG("pfp: added config id %d for OF %d to q %d on thread %d", + isp_params_info.isp_parameters_id, + isp_params_info.output_frame_ptr, + queue_id, thread_id); +#endif + } + /* clean-up old copy */ + ia_css_dequeue_param_buffers(/*pipe_num*/); + params->pipe_dvs_6axis_config_changed[pipeline->pipe_id] = false; + } /* end for each 'active' pipeline */ + /* clear the changed flags after all params + for all pipelines have been updated */ + params->isp_params_changed = false; + params->sc_table_changed = false; + params->dis_coef_table_changed = false; + params->dvs2_coef_table_changed = false; + params->morph_table_changed = false; + params->dz_config_changed = false; + params->motion_config_changed = false; + /* ------ deprecated(bz675) : from ------ */ + params->shading_settings_changed = false; + /* ------ deprecated(bz675) : to ------ */ + + memset(¶ms->config_changed[0], 0, sizeof(params->config_changed)); + + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +static enum ia_css_err +sh_css_params_write_to_ddr_internal( + struct ia_css_pipe *pipe, + unsigned int pipe_id, + struct ia_css_isp_parameters *params, + const struct ia_css_pipeline_stage *stage, + struct sh_css_ddr_address_map *ddr_map, + struct sh_css_ddr_address_map_size *ddr_map_size) { + enum ia_css_err err; + const struct ia_css_binary *binary; + + unsigned int stage_num; + unsigned int mem; + bool buff_realloced; + + /* struct is > 128 bytes so it should not be on stack (see checkpatch) */ + static struct ia_css_macc_table converted_macc_table; + + IA_CSS_ENTER_PRIVATE("void"); + assert(params); + assert(ddr_map); + assert(ddr_map_size); + assert(stage); + + binary = stage->binary; + assert(binary); + + stage_num = stage->stage_num; + + if (binary->info->sp.enable.fpnr) + { + buff_realloced = reallocate_buffer(&ddr_map->fpn_tbl, + &ddr_map_size->fpn_tbl, + (size_t)(FPNTBL_BYTES(binary)), + params->config_changed[IA_CSS_FPN_ID], + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + if (params->config_changed[IA_CSS_FPN_ID] || buff_realloced) { + if (params->fpn_config.enabled) { + err = store_fpntbl(params, ddr_map->fpn_tbl); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + } + } + } + + if (binary->info->sp.enable.sc) + { + u32 enable_conv; + size_t bytes; + + if (!atomisp_hw_is_isp2401) + bytes = ISP2400_SCTBL_BYTES(binary); + else + bytes = ISP2401_SCTBL_BYTES(binary); + + enable_conv = params->shading_settings.enable_shading_table_conversion; + + buff_realloced = reallocate_buffer(&ddr_map->sc_tbl, + &ddr_map_size->sc_tbl, + bytes, + params->sc_table_changed, + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + + if (params->shading_settings_changed || + params->sc_table_changed || buff_realloced) { + if (enable_conv == 0) { + if (params->sc_table) { + /* store the shading table to ddr */ + err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_table); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + /* set sc_config to isp */ + params->sc_config = (struct ia_css_shading_table *)params->sc_table; + ia_css_kernel_process_param[IA_CSS_SC_ID](pipe_id, stage, params); + params->sc_config = NULL; + } else { + /* generate the identical shading table */ + if (params->sc_config) { + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + } + sh_css_params_shading_id_table_generate(¶ms->sc_config, + binary->sctbl_width_per_color, + binary->sctbl_height); + if (!params->sc_config) { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + + /* store the shading table to ddr */ + err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_config); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + + /* set sc_config to isp */ + ia_css_kernel_process_param[IA_CSS_SC_ID](pipe_id, stage, params); + + /* free the shading table */ + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + } + } else { /* legacy */ + /* ------ deprecated(bz675) : from ------ */ + /* shading table is full resolution, reduce */ + if (params->sc_config) { + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + } + prepare_shading_table( + (const struct ia_css_shading_table *)params->sc_table, + params->sensor_binning, + ¶ms->sc_config, + binary, pipe->required_bds_factor); + if (!params->sc_config) { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + + /* store the shading table to ddr */ + err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_config); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + + /* set sc_config to isp */ + ia_css_kernel_process_param[IA_CSS_SC_ID](pipe_id, stage, params); + + /* free the shading table */ + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + /* ------ deprecated(bz675) : to ------ */ + } + } + } + + /* DPC configuration is made pipe specific to allow flexibility in positioning of the + * DPC kernel. The code below sets the pipe specific configuration to + * individual binaries. */ + if (atomisp_hw_is_isp2401 && + params->pipe_dpc_config_changed[pipe_id] && binary->info->sp.enable.dpc) + { + unsigned int size = + stage->binary->info->mem_offsets.offsets.param->dmem.dp.size; + + unsigned int offset = + stage->binary->info->mem_offsets.offsets.param->dmem.dp.offset; + + if (size) { + ia_css_dp_encode((struct sh_css_isp_dp_params *) + &binary->mem_params.params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM].address[offset], + ¶ms->pipe_dp_config[pipe_id], size); + + params->isp_params_changed = true; + params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM] = + true; + } + } + + if (params->config_changed[IA_CSS_MACC_ID] && binary->info->sp.enable.macc) + { + unsigned int i, j, idx; + unsigned int idx_map[] = { + 0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8 + }; + + for (i = 0; i < IA_CSS_MACC_NUM_AXES; i++) { + idx = 4 * idx_map[i]; + j = 4 * i; + + if (binary->info->sp.pipeline.isp_pipe_version == SH_CSS_ISP_PIPE_VERSION_1) { + converted_macc_table.data[idx] = + (int16_t)sDIGIT_FITTING(params->macc_table.data[j], + 13, SH_CSS_MACC_COEF_SHIFT); + converted_macc_table.data[idx + 1] = + (int16_t)sDIGIT_FITTING(params->macc_table.data[j + 1], + 13, SH_CSS_MACC_COEF_SHIFT); + converted_macc_table.data[idx + 2] = + (int16_t)sDIGIT_FITTING(params->macc_table.data[j + 2], + 13, SH_CSS_MACC_COEF_SHIFT); + converted_macc_table.data[idx + 3] = + (int16_t)sDIGIT_FITTING(params->macc_table.data[j + 3], + 13, SH_CSS_MACC_COEF_SHIFT); + } else if (binary->info->sp.pipeline.isp_pipe_version == + SH_CSS_ISP_PIPE_VERSION_2_2) { + converted_macc_table.data[idx] = + params->macc_table.data[j]; + converted_macc_table.data[idx + 1] = + params->macc_table.data[j + 1]; + converted_macc_table.data[idx + 2] = + params->macc_table.data[j + 2]; + converted_macc_table.data[idx + 3] = + params->macc_table.data[j + 3]; + } + } + reallocate_buffer(&ddr_map->macc_tbl, + &ddr_map_size->macc_tbl, + ddr_map_size->macc_tbl, + true, + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + mmgr_store(ddr_map->macc_tbl, + converted_macc_table.data, + sizeof(converted_macc_table.data)); + } + + if (binary->info->sp.enable.dvs_6axis) + { + /* because UV is packed into the Y plane, calc total + * YYU size = /2 gives size of UV-only, + * total YYU size = UV-only * 3. + */ + buff_realloced = reallocate_buffer( + &ddr_map->dvs_6axis_params_y, + &ddr_map_size->dvs_6axis_params_y, + (size_t)((DVS_6AXIS_BYTES(binary) / 2) * 3), + params->pipe_dvs_6axis_config_changed[pipe_id], + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + + if (params->pipe_dvs_6axis_config_changed[pipe_id] || buff_realloced) { + const struct ia_css_frame_info *dvs_in_frame_info; + + if (stage->args.delay_frames[0]) { + /*When delay frames are present(as in case of video), + they are used for dvs. Configure DVS using those params*/ + dvs_in_frame_info = &stage->args.delay_frames[0]->info; + } else { + /*Otherwise, use input frame to configure DVS*/ + dvs_in_frame_info = &stage->args.in_frame->info; + } + + /* Generate default DVS unity table on start up*/ + if (!params->pipe_dvs_6axis_config[pipe_id]) { + struct ia_css_resolution dvs_offset = {0}; + + if (!atomisp_hw_is_isp2401) { + dvs_offset.width = (PIX_SHIFT_FILTER_RUN_IN_X + binary->dvs_envelope.width) / 2; + } else { + if (binary->dvs_envelope.width || binary->dvs_envelope.height) { + dvs_offset.width = (PIX_SHIFT_FILTER_RUN_IN_X + binary->dvs_envelope.width) / 2; + } + } + dvs_offset.height = (PIX_SHIFT_FILTER_RUN_IN_Y + binary->dvs_envelope.height) / 2; + + params->pipe_dvs_6axis_config[pipe_id] = + generate_dvs_6axis_table(&binary->out_frame_info[0].res, &dvs_offset); + if (!params->pipe_dvs_6axis_config[pipe_id]) { + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY); + return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + } + params->pipe_dvs_6axis_config_changed[pipe_id] = true; + + store_dvs_6axis_config(params->pipe_dvs_6axis_config[pipe_id], + binary, + dvs_in_frame_info, + ddr_map->dvs_6axis_params_y); + params->isp_params_changed = true; + } + } + } + + if (binary->info->sp.enable.ca_gdc) + { + unsigned int i; + hrt_vaddress *virt_addr_tetra_x[ + IA_CSS_MORPH_TABLE_NUM_PLANES]; + size_t *virt_size_tetra_x[ + IA_CSS_MORPH_TABLE_NUM_PLANES]; + hrt_vaddress *virt_addr_tetra_y[ + IA_CSS_MORPH_TABLE_NUM_PLANES]; + size_t *virt_size_tetra_y[ + IA_CSS_MORPH_TABLE_NUM_PLANES]; + + virt_addr_tetra_x[0] = &ddr_map->tetra_r_x; + virt_addr_tetra_x[1] = &ddr_map->tetra_gr_x; + virt_addr_tetra_x[2] = &ddr_map->tetra_gb_x; + virt_addr_tetra_x[3] = &ddr_map->tetra_b_x; + virt_addr_tetra_x[4] = &ddr_map->tetra_ratb_x; + virt_addr_tetra_x[5] = &ddr_map->tetra_batr_x; + + virt_size_tetra_x[0] = &ddr_map_size->tetra_r_x; + virt_size_tetra_x[1] = &ddr_map_size->tetra_gr_x; + virt_size_tetra_x[2] = &ddr_map_size->tetra_gb_x; + virt_size_tetra_x[3] = &ddr_map_size->tetra_b_x; + virt_size_tetra_x[4] = &ddr_map_size->tetra_ratb_x; + virt_size_tetra_x[5] = &ddr_map_size->tetra_batr_x; + + virt_addr_tetra_y[0] = &ddr_map->tetra_r_y; + virt_addr_tetra_y[1] = &ddr_map->tetra_gr_y; + virt_addr_tetra_y[2] = &ddr_map->tetra_gb_y; + virt_addr_tetra_y[3] = &ddr_map->tetra_b_y; + virt_addr_tetra_y[4] = &ddr_map->tetra_ratb_y; + virt_addr_tetra_y[5] = &ddr_map->tetra_batr_y; + + virt_size_tetra_y[0] = &ddr_map_size->tetra_r_y; + virt_size_tetra_y[1] = &ddr_map_size->tetra_gr_y; + virt_size_tetra_y[2] = &ddr_map_size->tetra_gb_y; + virt_size_tetra_y[3] = &ddr_map_size->tetra_b_y; + virt_size_tetra_y[4] = &ddr_map_size->tetra_ratb_y; + virt_size_tetra_y[5] = &ddr_map_size->tetra_batr_y; + + buff_realloced = false; + for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { + buff_realloced |= + reallocate_buffer(virt_addr_tetra_x[i], + virt_size_tetra_x[i], + (size_t) + (MORPH_PLANE_BYTES(binary)), + params->morph_table_changed, + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + buff_realloced |= + reallocate_buffer(virt_addr_tetra_y[i], + virt_size_tetra_y[i], + (size_t) + (MORPH_PLANE_BYTES(binary)), + params->morph_table_changed, + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + } + if (params->morph_table_changed || buff_realloced) { + const struct ia_css_morph_table *table = params->morph_table; + struct ia_css_morph_table *id_table = NULL; + + if ((table) && + (table->width < binary->morph_tbl_width || + table->height < binary->morph_tbl_height)) { + table = NULL; + } + if (!table) { + err = sh_css_params_default_morph_table(&id_table, + binary); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + table = id_table; + } + + for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { + store_morph_plane(table->coordinates_x[i], + table->width, + table->height, + *virt_addr_tetra_x[i], + binary->morph_tbl_aligned_width); + store_morph_plane(table->coordinates_y[i], + table->width, + table->height, + *virt_addr_tetra_y[i], + binary->morph_tbl_aligned_width); + } + if (id_table) + ia_css_morph_table_free(id_table); + } + } + + /* After special cases like SC, FPN since they may change parameters */ + for (mem = 0; mem < N_IA_CSS_MEMORIES; mem++) + { + const struct ia_css_isp_data *isp_data = + ia_css_isp_param_get_isp_mem_init(&binary->info->sp.mem_initializers, + IA_CSS_PARAM_CLASS_PARAM, mem); + size_t size = isp_data->size; + + if (!size) continue; + buff_realloced = reallocate_buffer(&ddr_map->isp_mem_param[stage_num][mem], + &ddr_map_size->isp_mem_param[stage_num][mem], + size, + params->isp_mem_params_changed[pipe_id][stage_num][mem], + &err); + if (err != IA_CSS_SUCCESS) { + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + if (params->isp_mem_params_changed[pipe_id][stage_num][mem] || buff_realloced) { + sh_css_update_isp_mem_params_to_ddr(binary, + ddr_map->isp_mem_param[stage_num][mem], + ddr_map_size->isp_mem_param[stage_num][mem], mem); + } + } + + IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS); + return IA_CSS_SUCCESS; +} + +const struct ia_css_fpn_table *ia_css_get_fpn_table(struct ia_css_stream + *stream) +{ + struct ia_css_isp_parameters *params; + + IA_CSS_ENTER_LEAVE("void"); + assert(stream); + + params = stream->isp_params_configs; + + return ¶ms->fpn_config; +} + +struct ia_css_shading_table *ia_css_get_shading_table(struct ia_css_stream + *stream) +{ + struct ia_css_shading_table *table = NULL; + struct ia_css_isp_parameters *params; + + IA_CSS_ENTER("void"); + + assert(stream); + + params = stream->isp_params_configs; + if (!params) + return NULL; + + if (params->shading_settings.enable_shading_table_conversion == 0) { + if (params->sc_table) { + table = (struct ia_css_shading_table *)params->sc_table; + } else { + const struct ia_css_binary *binary + = ia_css_stream_get_shading_correction_binary(stream); + if (binary) { + /* generate the identical shading table */ + if (params->sc_config) { + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + } + sh_css_params_shading_id_table_generate(¶ms->sc_config, + binary->sctbl_width_per_color, + binary->sctbl_height); + table = params->sc_config; + /* The sc_config will be freed in the + * ia_css_stream_isp_parameters_uninit function. */ + } + } + } else { + /* ------ deprecated(bz675) : from ------ */ + const struct ia_css_binary *binary + = ia_css_stream_get_shading_correction_binary(stream); + struct ia_css_pipe *pipe; + + /**********************************************************************/ + /* following code is copied from function ia_css_stream_get_shading_correction_binary() + * to match with the binary */ + pipe = stream->pipes[0]; + + if (stream->num_pipes == 2) { + assert(stream->pipes[1]); + if (stream->pipes[1]->config.mode == IA_CSS_PIPE_MODE_VIDEO || + stream->pipes[1]->config.mode == IA_CSS_PIPE_MODE_PREVIEW) + pipe = stream->pipes[1]; + } + /**********************************************************************/ + if (binary) { + if (params->sc_config) { + ia_css_shading_table_free(params->sc_config); + params->sc_config = NULL; + } + prepare_shading_table( + (const struct ia_css_shading_table *)params->sc_table, + params->sensor_binning, + ¶ms->sc_config, + binary, pipe->required_bds_factor); + + table = params->sc_config; + /* The sc_config will be freed in the + * ia_css_stream_isp_parameters_uninit function. */ + } + /* ------ deprecated(bz675) : to ------ */ + } + + IA_CSS_LEAVE("table=%p", table); + + return table; +} + +hrt_vaddress sh_css_store_sp_group_to_ddr(void) +{ + IA_CSS_ENTER_LEAVE_PRIVATE("void"); + mmgr_store(xmem_sp_group_ptrs, + &sh_css_sp_group, + sizeof(struct sh_css_sp_group)); + return xmem_sp_group_ptrs; +} + +hrt_vaddress sh_css_store_sp_stage_to_ddr( + unsigned int pipe, + unsigned int stage) +{ + IA_CSS_ENTER_LEAVE_PRIVATE("void"); + mmgr_store(xmem_sp_stage_ptrs[pipe][stage], + &sh_css_sp_stage, + sizeof(struct sh_css_sp_stage)); + return xmem_sp_stage_ptrs[pipe][stage]; +} + +hrt_vaddress sh_css_store_isp_stage_to_ddr( + unsigned int pipe, + unsigned int stage) +{ + IA_CSS_ENTER_LEAVE_PRIVATE("void"); + mmgr_store(xmem_isp_stage_ptrs[pipe][stage], + &sh_css_isp_stage, + sizeof(struct sh_css_isp_stage)); + return xmem_isp_stage_ptrs[pipe][stage]; +} + +static enum ia_css_err ref_sh_css_ddr_address_map( + struct sh_css_ddr_address_map *map, + struct sh_css_ddr_address_map *out) +{ + enum ia_css_err err = IA_CSS_SUCCESS; + unsigned int i; + + /* we will use a union to copy things; overlaying an array + with the struct; that way adding fields in the struct + will keep things working, and we will not get type errors. + */ + union { + struct sh_css_ddr_address_map *map; + hrt_vaddress *addrs; + } in_addrs, to_addrs; + + IA_CSS_ENTER_PRIVATE("void"); + assert(map); + assert(out); + + in_addrs.map = map; + to_addrs.map = out; + + assert(sizeof(struct sh_css_ddr_address_map_size) / sizeof(size_t) == + sizeof(struct sh_css_ddr_address_map) / sizeof(hrt_vaddress)); + + /* copy map using size info */ + for (i = 0; i < (sizeof(struct sh_css_ddr_address_map_size) / + sizeof(size_t)); i++) { + if (in_addrs.addrs[i] == mmgr_NULL) + to_addrs.addrs[i] = mmgr_NULL; + else + to_addrs.addrs[i] = ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_BUFFER, + in_addrs.addrs[i]); + } + + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +static enum ia_css_err write_ia_css_isp_parameter_set_info_to_ddr( + struct ia_css_isp_parameter_set_info *me, + hrt_vaddress *out) +{ + enum ia_css_err err = IA_CSS_SUCCESS; + bool succ; + + IA_CSS_ENTER_PRIVATE("void"); + + assert(me); + assert(out); + + *out = ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_SET_POOL, mmgr_malloc( + sizeof(struct ia_css_isp_parameter_set_info))); + succ = (*out != mmgr_NULL); + if (succ) + mmgr_store(*out, + me, sizeof(struct ia_css_isp_parameter_set_info)); + else + err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; + + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +static enum ia_css_err +free_ia_css_isp_parameter_set_info( + hrt_vaddress ptr) { + enum ia_css_err err = IA_CSS_SUCCESS; + struct ia_css_isp_parameter_set_info isp_params_info; + unsigned int i; + hrt_vaddress *addrs = (hrt_vaddress *) &isp_params_info.mem_map; + + IA_CSS_ENTER_PRIVATE("ptr = %u", ptr); + + /* sanity check - ptr must be valid */ + if (!ia_css_refcount_is_valid(ptr)) + { + IA_CSS_ERROR("%s: IA_CSS_REFCOUNT_PARAM_SET_POOL(0x%x) invalid arg", __func__, + ptr); + err = IA_CSS_ERR_INVALID_ARGUMENTS; + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; + } + + mmgr_load(ptr, &isp_params_info.mem_map, sizeof(struct sh_css_ddr_address_map)); + /* copy map using size info */ + for (i = 0; i < (sizeof(struct sh_css_ddr_address_map_size) / + sizeof(size_t)); i++) + { + if (addrs[i] == mmgr_NULL) + continue; + + /* sanity check - ptr must be valid */ + if (!ia_css_refcount_is_valid(addrs[i])) { + IA_CSS_ERROR("%s: IA_CSS_REFCOUNT_PARAM_BUFFER(0x%x) invalid arg", __func__, + ptr); + err = IA_CSS_ERR_INVALID_ARGUMENTS; + continue; + } + + ia_css_refcount_decrement(IA_CSS_REFCOUNT_PARAM_BUFFER, addrs[i]); + } + ia_css_refcount_decrement(IA_CSS_REFCOUNT_PARAM_SET_POOL, ptr); + + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +/* Mark all parameters as changed to force recomputing the derived ISP parameters */ +void +sh_css_invalidate_params(struct ia_css_stream *stream) +{ + struct ia_css_isp_parameters *params; + unsigned int i, j, mem; + + IA_CSS_ENTER_PRIVATE("void"); + assert(stream); + + params = stream->isp_params_configs; + params->isp_params_changed = true; + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) { + for (j = 0; j < SH_CSS_MAX_STAGES; j++) { + for (mem = 0; mem < N_IA_CSS_MEMORIES; mem++) { + params->isp_mem_params_changed[i][j][mem] = true; + } + } + } + + memset(¶ms->config_changed[0], 1, sizeof(params->config_changed)); + params->dis_coef_table_changed = true; + params->dvs2_coef_table_changed = true; + params->morph_table_changed = true; + params->sc_table_changed = true; + params->dz_config_changed = true; + params->motion_config_changed = true; + + /*Free up theDVS table memory blocks before recomputing new table */ + for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) { + if (params->pipe_dvs_6axis_config[i]) { + free_dvs_6axis_table(¶ms->pipe_dvs_6axis_config[i]); + params->pipe_dvs_6axis_config_changed[i] = true; + } + } + + IA_CSS_LEAVE_PRIVATE("void"); +} + +void +sh_css_update_uds_and_crop_info( + const struct ia_css_binary_info *info, + const struct ia_css_frame_info *in_frame_info, + const struct ia_css_frame_info *out_frame_info, + const struct ia_css_resolution *dvs_env, + const struct ia_css_dz_config *zoom, + const struct ia_css_vector *motion_vector, + struct sh_css_uds_info *uds, /* out */ + struct sh_css_crop_pos *sp_out_crop_pos, /* out */ + + bool enable_zoom) +{ + IA_CSS_ENTER_PRIVATE("void"); + + assert(info); + assert(in_frame_info); + assert(out_frame_info); + assert(dvs_env); + assert(zoom); + assert(motion_vector); + assert(uds); + assert(sp_out_crop_pos); + + uds->curr_dx = enable_zoom ? (uint16_t)zoom->dx : HRT_GDC_N; + uds->curr_dy = enable_zoom ? (uint16_t)zoom->dy : HRT_GDC_N; + + if (info->enable.dvs_envelope) { + unsigned int crop_x = 0, + crop_y = 0, + uds_xc = 0, + uds_yc = 0, + env_width, env_height; + int half_env_x, half_env_y; + int motion_x = motion_vector->x; + int motion_y = motion_vector->y; + bool upscale_x = in_frame_info->res.width < out_frame_info->res.width; + bool upscale_y = in_frame_info->res.height < out_frame_info->res.height; + + if (info->enable.uds && !info->enable.ds) { + /** + * we calculate with the envelope that we can actually + * use, the min dvs envelope is for the filter + * initialization. + */ + env_width = dvs_env->width - + SH_CSS_MIN_DVS_ENVELOPE; + env_height = dvs_env->height - + SH_CSS_MIN_DVS_ENVELOPE; + half_env_x = env_width / 2; + half_env_y = env_height / 2; + /** + * for digital zoom, we use the dvs envelope and make + * sure that we don't include the 8 leftmost pixels or + * 8 topmost rows. + */ + if (upscale_x) { + uds_xc = (in_frame_info->res.width + + env_width + + SH_CSS_MIN_DVS_ENVELOPE) / 2; + } else { + uds_xc = (out_frame_info->res.width + + env_width) / 2 + + SH_CSS_MIN_DVS_ENVELOPE; + } + if (upscale_y) { + uds_yc = (in_frame_info->res.height + + env_height + + SH_CSS_MIN_DVS_ENVELOPE) / 2; + } else { + uds_yc = (out_frame_info->res.height + + env_height) / 2 + + SH_CSS_MIN_DVS_ENVELOPE; + } + /* clip the motion vector to +/- half the envelope */ + motion_x = clamp(motion_x, -half_env_x, half_env_x); + motion_y = clamp(motion_y, -half_env_y, half_env_y); + uds_xc += motion_x; + uds_yc += motion_y; + /* uds can be pipelined, remove top lines */ + crop_y = 2; + } else if (info->enable.ds) { + env_width = dvs_env->width; + env_height = dvs_env->height; + half_env_x = env_width / 2; + half_env_y = env_height / 2; + /* clip the motion vector to +/- half the envelope */ + motion_x = clamp(motion_x, -half_env_x, half_env_x); + motion_y = clamp(motion_y, -half_env_y, half_env_y); + /* for video with downscaling, the envelope is included + in the input resolution. */ + uds_xc = in_frame_info->res.width / 2 + motion_x; + uds_yc = in_frame_info->res.height / 2 + motion_y; + crop_x = info->pipeline.left_cropping; + /* ds == 2 (yuv_ds) can be pipelined, remove top + lines */ + if (info->enable.ds & 1) + crop_y = info->pipeline.top_cropping; + else + crop_y = 2; + } else { + /* video nodz: here we can only crop. We make sure we + crop at least the first 8x8 pixels away. */ + env_width = dvs_env->width - + SH_CSS_MIN_DVS_ENVELOPE; + env_height = dvs_env->height - + SH_CSS_MIN_DVS_ENVELOPE; + half_env_x = env_width / 2; + half_env_y = env_height / 2; + motion_x = clamp(motion_x, -half_env_x, half_env_x); + motion_y = clamp(motion_y, -half_env_y, half_env_y); + crop_x = SH_CSS_MIN_DVS_ENVELOPE + + half_env_x + motion_x; + crop_y = SH_CSS_MIN_DVS_ENVELOPE + + half_env_y + motion_y; + } + + /* Must enforce that the crop position is even */ + crop_x = EVEN_FLOOR(crop_x); + crop_y = EVEN_FLOOR(crop_y); + uds_xc = EVEN_FLOOR(uds_xc); + uds_yc = EVEN_FLOOR(uds_yc); + + uds->xc = (uint16_t)uds_xc; + uds->yc = (uint16_t)uds_yc; + sp_out_crop_pos->x = (uint16_t)crop_x; + sp_out_crop_pos->y = (uint16_t)crop_y; + } else { + /* for down scaling, we always use the center of the image */ + uds->xc = (uint16_t)in_frame_info->res.width / 2; + uds->yc = (uint16_t)in_frame_info->res.height / 2; + sp_out_crop_pos->x = (uint16_t)info->pipeline.left_cropping; + sp_out_crop_pos->y = (uint16_t)info->pipeline.top_cropping; + } + IA_CSS_LEAVE_PRIVATE("void"); +} + +static enum ia_css_err +sh_css_update_uds_and_crop_info_based_on_zoom_region( + const struct ia_css_binary_info *info, + const struct ia_css_frame_info *in_frame_info, + const struct ia_css_frame_info *out_frame_info, + const struct ia_css_resolution *dvs_env, + const struct ia_css_dz_config *zoom, + const struct ia_css_vector *motion_vector, + struct sh_css_uds_info *uds, /* out */ + struct sh_css_crop_pos *sp_out_crop_pos, /* out */ + struct ia_css_resolution pipe_in_res, + bool enable_zoom) { + unsigned int x0 = 0, y0 = 0, x1 = 0, y1 = 0; + enum ia_css_err err = IA_CSS_SUCCESS; + /* Note: + * Filter_Envelope = 0 for NND/LUT + * Filter_Envelope = 1 for BCI + * Filter_Envelope = 3 for BLI + * Currently, not considering this filter envelope because, In uds.sp.c is recalculating + * the dx/dy based on filter envelope and other information (ia_css_uds_sp_scale_params) + * Ideally, That should be done on host side not on sp side. + */ + unsigned int filter_envelope = 0; + + IA_CSS_ENTER_PRIVATE("void"); + + assert(info); + assert(in_frame_info); + assert(out_frame_info); + assert(dvs_env); + assert(zoom); + assert(motion_vector); + assert(uds); + assert(sp_out_crop_pos); + x0 = zoom->zoom_region.origin.x; + y0 = zoom->zoom_region.origin.y; + x1 = zoom->zoom_region.resolution.width + x0; + y1 = zoom->zoom_region.resolution.height + y0; + + if ((x0 > x1) || (y0 > y1) || (x1 > pipe_in_res.width) || (y1 > pipe_in_res.height)) + return IA_CSS_ERR_INVALID_ARGUMENTS; + + if (!enable_zoom) + { + uds->curr_dx = HRT_GDC_N; + uds->curr_dy = HRT_GDC_N; + } + + if (info->enable.dvs_envelope) + { + /* Zoom region is only supported by the UDS module on ISP + * 2 and higher. It is not supported in video mode on ISP 1 */ + return IA_CSS_ERR_INVALID_ARGUMENTS; + } else + { + if (enable_zoom) { + /* A. Calculate dx/dy based on crop region using in_frame_info + * Scale the crop region if in_frame_info to the stage is not same as + * actual effective input of the pipeline + */ + if (in_frame_info->res.width != pipe_in_res.width || + in_frame_info->res.height != pipe_in_res.height) { + x0 = (x0 * in_frame_info->res.width) / (pipe_in_res.width); + y0 = (y0 * in_frame_info->res.height) / (pipe_in_res.height); + x1 = (x1 * in_frame_info->res.width) / (pipe_in_res.width); + y1 = (y1 * in_frame_info->res.height) / (pipe_in_res.height); + } + uds->curr_dx = + ((x1 - x0 - filter_envelope) * HRT_GDC_N) / in_frame_info->res.width; + uds->curr_dy = + ((y1 - y0 - filter_envelope) * HRT_GDC_N) / in_frame_info->res.height; + + /* B. Calculate xc/yc based on crop region */ + uds->xc = (uint16_t)x0 + (((x1) - (x0)) / 2); + uds->yc = (uint16_t)y0 + (((y1) - (y0)) / 2); + } else { + uds->xc = (uint16_t)in_frame_info->res.width / 2; + uds->yc = (uint16_t)in_frame_info->res.height / 2; + } + + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, + "uds->curr_dx=%d, uds->xc=%d, uds->yc=%d\n", + uds->curr_dx, uds->xc, uds->yc); + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "x0=%d, y0=%d, x1=%d, y1=%d\n", + x0, y0, x1, y1); + sp_out_crop_pos->x = (uint16_t)info->pipeline.left_cropping; + sp_out_crop_pos->y = (uint16_t)info->pipeline.top_cropping; + } + IA_CSS_LEAVE_PRIVATE("void"); + return err; +} + +struct ia_css_3a_statistics * +ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) +{ + struct ia_css_3a_statistics *me; + int grid_size; + + IA_CSS_ENTER("grid=%p", grid); + + assert(grid); + + me = sh_css_calloc(1, sizeof(*me)); + if (!me) + goto err; + + me->grid = *grid; + grid_size = grid->width * grid->height; + me->data = sh_css_malloc(grid_size * sizeof(*me->data)); + if (!me->data) + goto err; +#if !defined(HAS_NO_HMEM) + /* No weighted histogram, no structure, treat the histogram data as a byte dump in a byte array */ + me->rgby_data = (struct ia_css_3a_rgby_output *)sh_css_malloc(sizeof_hmem( + HMEM0_ID)); +#else + me->rgby_data = NULL; +#endif + + IA_CSS_LEAVE("return=%p", me); + return me; +err: + ia_css_3a_statistics_free(me); + + IA_CSS_LEAVE("return=%p", NULL); + return NULL; +} + +void +ia_css_3a_statistics_free(struct ia_css_3a_statistics *me) +{ + if (me) { + sh_css_free(me->rgby_data); + sh_css_free(me->data); + memset(me, 0, sizeof(struct ia_css_3a_statistics)); + sh_css_free(me); + } +} + +struct ia_css_dvs_statistics * +ia_css_dvs_statistics_allocate(const struct ia_css_dvs_grid_info *grid) +{ + struct ia_css_dvs_statistics *me; + + assert(grid); + + me = sh_css_calloc(1, sizeof(*me)); + if (!me) + goto err; + + me->grid = *grid; + me->hor_proj = sh_css_malloc(grid->height * IA_CSS_DVS_NUM_COEF_TYPES * + sizeof(*me->hor_proj)); + if (!me->hor_proj) + goto err; + + me->ver_proj = sh_css_malloc(grid->width * IA_CSS_DVS_NUM_COEF_TYPES * + sizeof(*me->ver_proj)); + if (!me->ver_proj) + goto err; + + return me; +err: + ia_css_dvs_statistics_free(me); + return NULL; +} + +void +ia_css_dvs_statistics_free(struct ia_css_dvs_statistics *me) +{ + if (me) { + sh_css_free(me->hor_proj); + sh_css_free(me->ver_proj); + memset(me, 0, sizeof(struct ia_css_dvs_statistics)); + sh_css_free(me); + } +} + +struct ia_css_dvs_coefficients * +ia_css_dvs_coefficients_allocate(const struct ia_css_dvs_grid_info *grid) +{ + struct ia_css_dvs_coefficients *me; + + assert(grid); + + me = sh_css_calloc(1, sizeof(*me)); + if (!me) + goto err; + + me->grid = *grid; + + me->hor_coefs = sh_css_malloc(grid->num_hor_coefs * + IA_CSS_DVS_NUM_COEF_TYPES * + sizeof(*me->hor_coefs)); + if (!me->hor_coefs) + goto err; + + me->ver_coefs = sh_css_malloc(grid->num_ver_coefs * + IA_CSS_DVS_NUM_COEF_TYPES * + sizeof(*me->ver_coefs)); + if (!me->ver_coefs) + goto err; + + return me; +err: + ia_css_dvs_coefficients_free(me); + return NULL; +} + +void +ia_css_dvs_coefficients_free(struct ia_css_dvs_coefficients *me) +{ + if (me) { + sh_css_free(me->hor_coefs); + sh_css_free(me->ver_coefs); + memset(me, 0, sizeof(struct ia_css_dvs_coefficients)); + sh_css_free(me); + } +} + +struct ia_css_dvs2_statistics * +ia_css_dvs2_statistics_allocate(const struct ia_css_dvs_grid_info *grid) +{ + struct ia_css_dvs2_statistics *me; + + assert(grid); + + me = sh_css_calloc(1, sizeof(*me)); + if (!me) + goto err; + + me->grid = *grid; + + me->hor_prod.odd_real = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->hor_prod.odd_real)); + if (!me->hor_prod.odd_real) + goto err; + + me->hor_prod.odd_imag = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->hor_prod.odd_imag)); + if (!me->hor_prod.odd_imag) + goto err; + + me->hor_prod.even_real = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->hor_prod.even_real)); + if (!me->hor_prod.even_real) + goto err; + + me->hor_prod.even_imag = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->hor_prod.even_imag)); + if (!me->hor_prod.even_imag) + goto err; + + me->ver_prod.odd_real = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->ver_prod.odd_real)); + if (!me->ver_prod.odd_real) + goto err; + + me->ver_prod.odd_imag = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->ver_prod.odd_imag)); + if (!me->ver_prod.odd_imag) + goto err; + + me->ver_prod.even_real = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->ver_prod.even_real)); + if (!me->ver_prod.even_real) + goto err; + + me->ver_prod.even_imag = sh_css_malloc(grid->aligned_width * + grid->aligned_height * sizeof(*me->ver_prod.even_imag)); + if (!me->ver_prod.even_imag) + goto err; + + return me; +err: + ia_css_dvs2_statistics_free(me); + return NULL; +} + +void +ia_css_dvs2_statistics_free(struct ia_css_dvs2_statistics *me) +{ + if (me) { + sh_css_free(me->hor_prod.odd_real); + sh_css_free(me->hor_prod.odd_imag); + sh_css_free(me->hor_prod.even_real); + sh_css_free(me->hor_prod.even_imag); + sh_css_free(me->ver_prod.odd_real); + sh_css_free(me->ver_prod.odd_imag); + sh_css_free(me->ver_prod.even_real); + sh_css_free(me->ver_prod.even_imag); + memset(me, 0, sizeof(struct ia_css_dvs2_statistics)); + sh_css_free(me); + } +} + +struct ia_css_dvs2_coefficients * +ia_css_dvs2_coefficients_allocate(const struct ia_css_dvs_grid_info *grid) +{ + struct ia_css_dvs2_coefficients *me; + + assert(grid); + + me = sh_css_calloc(1, sizeof(*me)); + if (!me) + goto err; + + me->grid = *grid; + + me->hor_coefs.odd_real = sh_css_malloc(grid->num_hor_coefs * + sizeof(*me->hor_coefs.odd_real)); + if (!me->hor_coefs.odd_real) + goto err; + + me->hor_coefs.odd_imag = sh_css_malloc(grid->num_hor_coefs * + sizeof(*me->hor_coefs.odd_imag)); + if (!me->hor_coefs.odd_imag) + goto err; + + me->hor_coefs.even_real = sh_css_malloc(grid->num_hor_coefs * + sizeof(*me->hor_coefs.even_real)); + if (!me->hor_coefs.even_real) + goto err; + + me->hor_coefs.even_imag = sh_css_malloc(grid->num_hor_coefs * + sizeof(*me->hor_coefs.even_imag)); + if (!me->hor_coefs.even_imag) + goto err; + + me->ver_coefs.odd_real = sh_css_malloc(grid->num_ver_coefs * + sizeof(*me->ver_coefs.odd_real)); + if (!me->ver_coefs.odd_real) + goto err; + + me->ver_coefs.odd_imag = sh_css_malloc(grid->num_ver_coefs * + sizeof(*me->ver_coefs.odd_imag)); + if (!me->ver_coefs.odd_imag) + goto err; + + me->ver_coefs.even_real = sh_css_malloc(grid->num_ver_coefs * + sizeof(*me->ver_coefs.even_real)); + if (!me->ver_coefs.even_real) + goto err; + + me->ver_coefs.even_imag = sh_css_malloc(grid->num_ver_coefs * + sizeof(*me->ver_coefs.even_imag)); + if (!me->ver_coefs.even_imag) + goto err; + + return me; +err: + ia_css_dvs2_coefficients_free(me); + return NULL; +} + +void +ia_css_dvs2_coefficients_free(struct ia_css_dvs2_coefficients *me) +{ + if (me) { + sh_css_free(me->hor_coefs.odd_real); + sh_css_free(me->hor_coefs.odd_imag); + sh_css_free(me->hor_coefs.even_real); + sh_css_free(me->hor_coefs.even_imag); + sh_css_free(me->ver_coefs.odd_real); + sh_css_free(me->ver_coefs.odd_imag); + sh_css_free(me->ver_coefs.even_real); + sh_css_free(me->ver_coefs.even_imag); + memset(me, 0, sizeof(struct ia_css_dvs2_coefficients)); + sh_css_free(me); + } +} + +struct ia_css_dvs_6axis_config * +ia_css_dvs2_6axis_config_allocate(const struct ia_css_stream *stream) +{ + struct ia_css_dvs_6axis_config *dvs_config = NULL; + struct ia_css_isp_parameters *params = NULL; + unsigned int width_y; + unsigned int height_y; + unsigned int width_uv; + unsigned int height_uv; + + assert(stream); + params = stream->isp_params_configs; + + /* Backward compatibility by default consider pipe as Video*/ + if (!params || (params && + !params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO])) { + goto err; + } + + dvs_config = (struct ia_css_dvs_6axis_config *)sh_css_calloc(1, + sizeof(struct ia_css_dvs_6axis_config)); + if (!dvs_config) + goto err; + + dvs_config->width_y = width_y = + params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]->width_y; + dvs_config->height_y = height_y = + params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]->height_y; + dvs_config->width_uv = width_uv = + params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]->width_uv; + dvs_config->height_uv = height_uv = + params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]->height_uv; + IA_CSS_LOG("table Y: W %d H %d", width_y, height_y); + IA_CSS_LOG("table UV: W %d H %d", width_uv, height_uv); + dvs_config->xcoords_y = (uint32_t *)sh_css_malloc(width_y * height_y * sizeof( + uint32_t)); + if (!dvs_config->xcoords_y) + goto err; + + dvs_config->ycoords_y = (uint32_t *)sh_css_malloc(width_y * height_y * sizeof( + uint32_t)); + if (!dvs_config->ycoords_y) + goto err; + + dvs_config->xcoords_uv = (uint32_t *)sh_css_malloc(width_uv * height_uv * + sizeof(uint32_t)); + if (!dvs_config->xcoords_uv) + goto err; + + dvs_config->ycoords_uv = (uint32_t *)sh_css_malloc(width_uv * height_uv * + sizeof(uint32_t)); + if (!dvs_config->ycoords_uv) + goto err; + + return dvs_config; +err: + ia_css_dvs2_6axis_config_free(dvs_config); + return NULL; +} + +void +ia_css_dvs2_6axis_config_free(struct ia_css_dvs_6axis_config *dvs_6axis_config) +{ + if (dvs_6axis_config) { + sh_css_free(dvs_6axis_config->xcoords_y); + sh_css_free(dvs_6axis_config->ycoords_y); + sh_css_free(dvs_6axis_config->xcoords_uv); + sh_css_free(dvs_6axis_config->ycoords_uv); + memset(dvs_6axis_config, 0, sizeof(struct ia_css_dvs_6axis_config)); + sh_css_free(dvs_6axis_config); + } +} + +void +ia_css_en_dz_capt_pipe(struct ia_css_stream *stream, bool enable) +{ + struct ia_css_pipe *pipe; + struct ia_css_pipeline *pipeline; + struct ia_css_pipeline_stage *stage; + enum ia_css_pipe_id pipe_id; + enum ia_css_err err; + int i; + + if (!stream) + return; + + for (i = 0; i < stream->num_pipes; i++) { + pipe = stream->pipes[i]; + pipeline = ia_css_pipe_get_pipeline(pipe); + pipe_id = pipeline->pipe_id; + + if (pipe_id == IA_CSS_PIPE_ID_CAPTURE) { + err = ia_css_pipeline_get_stage(pipeline, IA_CSS_BINARY_MODE_CAPTURE_PP, + &stage); + if (err == IA_CSS_SUCCESS) + stage->enable_zoom = enable; + break; + } + } +} |