// SPDX-License-Identifier: GPL-2.0 /* * 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 "hmm.h" #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 "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 #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 ia_css_ptr sp_ddr_ptrs; /* sp group address on DDR */ static ia_css_ptr xmem_sp_group_ptrs; static ia_css_ptr xmem_sp_stage_ptrs[IA_CSS_PIPE_ID_NUM] [SH_CSS_MAX_STAGES]; static ia_css_ptr xmem_isp_stage_ptrs[IA_CSS_PIPE_ID_NUM] [SH_CSS_MAX_STAGES]; static ia_css_ptr 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 int ref_sh_css_ddr_address_map( struct sh_css_ddr_address_map *map, struct sh_css_ddr_address_map *out); static int write_ia_css_isp_parameter_set_info_to_ddr( struct ia_css_isp_parameter_set_info *me, ia_css_ptr *out); static int free_ia_css_isp_parameter_set_info(ia_css_ptr ptr); static int 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 int 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 int 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 int 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 int 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 int 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); ia_css_ptr 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 int store_fpntbl(struct ia_css_isp_parameters *params, ia_css_ptr 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(-ENOMEM); return -ENOMEM; } ia_css_params_store_ia_css_host_data(ptr, isp_data); ia_css_host_data_free(isp_data); return 0; } 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 int sh_css_select_dp_10bpp_config(const struct ia_css_pipe *pipe, bool *is_dp_10bpp) { int err = 0; /* 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(-EINVAL); err = -EINVAL; } 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 (0 == 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; } int 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; ia_css_ptr 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)) { kvfree(params->fpn_config.data); params->fpn_config.data = NULL; } if (!params->fpn_config.data) { params->fpn_config.data = kvmalloc(height * width * sizeof(short), GFP_KERNEL); if (!params->fpn_config.data) { IA_CSS_ERROR("out of memory"); IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM); return -ENOMEM; } 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) { hmm_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) { hmm_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(0); return 0; } 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( ia_css_ptr ddr_addr, struct ia_css_host_data *data) { assert(data); assert(data->address); assert(ddr_addr != mmgr_NULL); IA_CSS_ENTER_PRIVATE(""); hmm_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; } int ia_css_params_store_sctbl( const struct ia_css_pipeline_stage *stage, ia_css_ptr 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 0; } isp_sc_tbl = ia_css_params_alloc_convert_sctbl(stage, sc_config); if (!isp_sc_tbl) { IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM); return -ENOMEM; } /* 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 0; } 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 int 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; int err = 0; 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) 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]) { kvfree(me->coordinates_x[i]); me->coordinates_x[i] = NULL; } if (me->coordinates_y[i]) { kvfree(me->coordinates_y[i]); me->coordinates_y[i] = NULL; } } kvfree(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 = kvmalloc(sizeof(*me), GFP_KERNEL); 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] = kvmalloc(height * width * sizeof(*me->coordinates_x[i]), GFP_KERNEL); me->coordinates_y[i] = kvmalloc(height * width * sizeof(*me->coordinates_y[i]), GFP_KERNEL); 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 int 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 -ENOMEM; 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(0); return 0; } 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) { kvfree(me->data_ptr); me->data_ptr = NULL; me->data_allocated = false; } kvfree(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 = kvmalloc(sizeof(*me), GFP_KERNEL); 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 = kvmalloc(isp_stats->size, GFP_KERNEL); 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) kvfree(me); return NULL; } int 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; int ret = 0; 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) { hmm_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 = -ENOMEM; } 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 (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; } int 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); } int 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) { int err = 0; if ((!stream) || (!config)) return -EINVAL; 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; } int ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe, struct ia_css_isp_config *config) { struct ia_css_pipe *pipe_in = pipe; int err = 0; IA_CSS_ENTER("pipe=%p", pipe); if ((!pipe) || (!pipe->stream)) return -EINVAL; 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 int 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) { int err = 0; int err1 = 0; int err2 = 0; 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 != 0) ? err1 : ((err2 != 0) ? err2 : err); IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) static int 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; int err = 0; int err1 = 0; int err2 = 0; int err3 = 0; 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 = -EINVAL; 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) 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 = -EINVAL; } 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 != 0) ? err1 : (err2 != 0) ? err2 : (err3 != 0) ? err3 : err; exit: IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } #endif static int 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) { int err = 0; 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 (IS_ISP2401) { sh_css_set_dp_config(pipe, params, config->dp_config); ia_css_set_param_exceptions(pipe, params); } if (0 == 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 = -EINVAL; } } else { err = -EINVAL; goto exit; } if (!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( ia_css_ptr *curr_buf, size_t *curr_size, size_t needed_size, bool force, int *err, uint16_t mmgr_attribute) { s32 id; *err = 0; /* 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, hmm_alloc(needed_size, HMM_BO_PRIVATE, 0, NULL, mmgr_attribute)); if (!*curr_buf) { *err = -ENOMEM; *curr_size = 0; } else { *curr_size = needed_size; } IA_CSS_LEAVE_PRIVATE("true"); return true; } static bool reallocate_buffer( ia_css_ptr *curr_buf, size_t *curr_size, size_t needed_size, bool force, int *err) { bool ret; IA_CSS_ENTER_PRIVATE("void"); ret = realloc_isp_css_mm_buf(curr_buf, curr_size, needed_size, force, err, 0); 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 = kvcalloc(1, sizeof(*me), GFP_KERNEL); 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 = hmm_alloc(me->size, HMM_BO_PRIVATE, 0, NULL, 0); if (me->data_ptr == mmgr_NULL) { kvfree(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); kvfree(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 = kvmalloc(sizeof(*md), GFP_KERNEL); if (!md) goto error; md->info = *metadata_info; md->exp_id = 0; md->address = hmm_alloc(metadata_info->size, HMM_BO_PRIVATE, 0, NULL, 0); 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); kvfree(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; int ia_css_stream_isp_parameters_init(struct ia_css_stream *stream) { int err = 0; 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(-EINVAL); return -EINVAL; } /* 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) 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 = -EINVAL; } 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 int 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; int err = 0; size_t params_size; struct ia_css_isp_parameters *params = kvmalloc(sizeof(struct ia_css_isp_parameters), GFP_KERNEL); if (!params) { *isp_params_out = NULL; err = -ENOMEM; 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, hmm_alloc(params_size, HMM_BO_PRIVATE, 0, NULL, 0)); 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, hmm_alloc(sizeof(struct ia_css_macc_table), HMM_BO_PRIVATE, 0, NULL, 0)); 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 (!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) == 0) { /* 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 (0 == 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 (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 (!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; } int 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, hmm_alloc(sizeof(struct sh_css_sp_stage), HMM_BO_PRIVATE, 0, NULL, ATOMISP_MAP_FLAG_CLEARED)); xmem_isp_stage_ptrs[p][i] = ia_css_refcount_increment(-1, hmm_alloc(sizeof(struct sh_css_sp_stage), HMM_BO_PRIVATE, 0, NULL, ATOMISP_MAP_FLAG_CLEARED)); 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(-ENOMEM); return -ENOMEM; } } } 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, hmm_alloc(CEIL_MUL(sizeof(struct sh_css_ddr_address_map), HIVE_ISP_DDR_WORD_BYTES), HMM_BO_PRIVATE, 0, NULL, ATOMISP_MAP_FLAG_CLEARED)); xmem_sp_group_ptrs = ia_css_refcount_increment(-1, hmm_alloc(sizeof(struct sh_css_sp_group), HMM_BO_PRIVATE, 0, NULL, ATOMISP_MAP_FLAG_CLEARED)); if ((sp_ddr_ptrs == mmgr_NULL) || (xmem_sp_group_ptrs == mmgr_NULL)) { ia_css_uninit(); IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM); return -ENOMEM; } IA_CSS_LEAVE_ERR_PRIVATE(0); return 0; } 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 ia_css_ptr sh_css_params_alloc_gdc_lut(void) { return hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0); } inline void sh_css_params_free_gdc_lut(ia_css_ptr addr) { if (addr != mmgr_NULL) hmm_free(addr); } int ia_css_pipe_set_bci_scaler_lut(struct ia_css_pipe *pipe, const void *lut) { int err = 0; bool stream_started = false; IA_CSS_ENTER("pipe=%p lut=%p", pipe, lut); if (!lut || !pipe) { err = -EINVAL; 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 = -ENOTSUPP; } /* Free any existing tables. */ sh_css_params_free_gdc_lut(pipe->scaler_pp_lut); pipe->scaler_pp_lut = mmgr_NULL; if (!stream_started) { if (!IS_ISP2401) pipe->scaler_pp_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0); 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 = -ENOMEM; } else { gdc_lut_convert_to_isp_format((const int(*)[HRT_GDC_N])lut, interleaved_lut_temp); hmm_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. */ ia_css_ptr 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(); } int sh_css_params_map_and_store_default_gdc_lut(void) { int err = 0; 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 (!IS_ISP2401) default_gdc_lut = hmm_alloc(sizeof(zoom_table), HMM_BO_PRIVATE, 0, NULL, 0); else default_gdc_lut = sh_css_params_alloc_gdc_lut(); if (default_gdc_lut == mmgr_NULL) return -ENOMEM; gdc_lut_convert_to_isp_format((const int(*)[HRT_GDC_N])zoom_table, interleaved_lut_temp); hmm_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"); } ia_css_ptr sh_css_params_get_default_gdc_lut(void) { return default_gdc_lut; } static void free_param_set_callback( ia_css_ptr ptr) { IA_CSS_ENTER_PRIVATE("void"); free_ia_css_isp_parameter_set_info(ptr); IA_CSS_LEAVE_PRIVATE("void"); } static void free_buffer_callback( ia_css_ptr 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; ia_css_ptr *addrs = (ia_css_ptr *)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) { kvfree(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; } } kvfree(params); if (per_frame_params) kvfree(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(-ENOMEM); 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 int store_morph_plane( unsigned short *data, unsigned int width, unsigned int height, ia_css_ptr 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(-ENOMEM); return -ENOMEM; } ia_css_params_store_ia_css_host_data(dest, isp_data); ia_css_host_data_free(isp_data); return 0; } static void sh_css_update_isp_params_to_ddr( struct ia_css_isp_parameters *params, ia_css_ptr ddr_ptr) { size_t size = sizeof(params->uds); IA_CSS_ENTER_PRIVATE("void"); assert(params); hmm_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, ia_css_ptr 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); hmm_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; ia_css_ptr 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 = (ia_css_ptr)0; /* clean-up old copy */ while (ia_css_bufq_dequeue_buffer(param_queue_ids[i], (uint32_t *)&cpy) == 0) { /* 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 = (ia_css_ptr)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); } } int 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) { int err = 0; ia_css_ptr 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 = -EBUSY; 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) 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) 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) 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) 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) 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) 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) { 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(-EBUSY); return -EBUSY; } 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 int 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) { int 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_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_LEAVE_ERR_PRIVATE(err); return err; } } } } if (binary->info->sp.enable.sc) { u32 enable_conv; size_t bytes; if (!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_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_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(-ENOMEM); return -ENOMEM; } /* store the shading table to ddr */ err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_config); if (err) { 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(-ENOMEM); return -ENOMEM; } /* store the shading table to ddr */ err = ia_css_params_store_sctbl(stage, ddr_map->sc_tbl, params->sc_config); if (err) { 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 (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_LEAVE_ERR_PRIVATE(err); return err; } hmm_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_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 (!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(-ENOMEM); return -ENOMEM; } 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; ia_css_ptr *virt_addr_tetra_x[ IA_CSS_MORPH_TABLE_NUM_PLANES]; size_t *virt_size_tetra_x[ IA_CSS_MORPH_TABLE_NUM_PLANES]; ia_css_ptr *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_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_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_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_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(0); return 0; } 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; } ia_css_ptr sh_css_store_sp_group_to_ddr(void) { IA_CSS_ENTER_LEAVE_PRIVATE("void"); hmm_store(xmem_sp_group_ptrs, &sh_css_sp_group, sizeof(struct sh_css_sp_group)); return xmem_sp_group_ptrs; } ia_css_ptr sh_css_store_sp_stage_to_ddr( unsigned int pipe, unsigned int stage) { IA_CSS_ENTER_LEAVE_PRIVATE("void"); hmm_store(xmem_sp_stage_ptrs[pipe][stage], &sh_css_sp_stage, sizeof(struct sh_css_sp_stage)); return xmem_sp_stage_ptrs[pipe][stage]; } ia_css_ptr sh_css_store_isp_stage_to_ddr( unsigned int pipe, unsigned int stage) { IA_CSS_ENTER_LEAVE_PRIVATE("void"); hmm_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 int ref_sh_css_ddr_address_map( struct sh_css_ddr_address_map *map, struct sh_css_ddr_address_map *out) { int err = 0; 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; ia_css_ptr *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(ia_css_ptr)); /* 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 int write_ia_css_isp_parameter_set_info_to_ddr( struct ia_css_isp_parameter_set_info *me, ia_css_ptr *out) { int err = 0; bool succ; IA_CSS_ENTER_PRIVATE("void"); assert(me); assert(out); *out = ia_css_refcount_increment(IA_CSS_REFCOUNT_PARAM_SET_POOL, hmm_alloc(sizeof(struct ia_css_isp_parameter_set_info), HMM_BO_PRIVATE, 0, NULL, 0)); succ = (*out != mmgr_NULL); if (succ) hmm_store(*out, me, sizeof(struct ia_css_isp_parameter_set_info)); else err = -ENOMEM; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } static int free_ia_css_isp_parameter_set_info( ia_css_ptr ptr) { int err = 0; struct ia_css_isp_parameter_set_info isp_params_info; unsigned int i; ia_css_ptr *addrs = (ia_css_ptr *)&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 = -EINVAL; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } hmm_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 = -EINVAL; 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 int 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; int err = 0; /* 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 -EINVAL; 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 -EINVAL; } 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 = kvcalloc(1, sizeof(*me), GFP_KERNEL); if (!me) goto err; me->grid = *grid; grid_size = grid->width * grid->height; me->data = kvmalloc(grid_size * sizeof(*me->data), GFP_KERNEL); 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 = kvmalloc(sizeof_hmem(HMEM0_ID), GFP_KERNEL); #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) { kvfree(me->rgby_data); kvfree(me->data); memset(me, 0, sizeof(struct ia_css_3a_statistics)); kvfree(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 = kvcalloc(1, sizeof(*me), GFP_KERNEL); if (!me) goto err; me->grid = *grid; me->hor_proj = kvmalloc(grid->height * IA_CSS_DVS_NUM_COEF_TYPES * sizeof(*me->hor_proj), GFP_KERNEL); if (!me->hor_proj) goto err; me->ver_proj = kvmalloc(grid->width * IA_CSS_DVS_NUM_COEF_TYPES * sizeof(*me->ver_proj), GFP_KERNEL); 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) { kvfree(me->hor_proj); kvfree(me->ver_proj); memset(me, 0, sizeof(struct ia_css_dvs_statistics)); kvfree(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 = kvcalloc(1, sizeof(*me), GFP_KERNEL); if (!me) goto err; me->grid = *grid; me->hor_coefs = kvmalloc(grid->num_hor_coefs * IA_CSS_DVS_NUM_COEF_TYPES * sizeof(*me->hor_coefs), GFP_KERNEL); if (!me->hor_coefs) goto err; me->ver_coefs = kvmalloc(grid->num_ver_coefs * IA_CSS_DVS_NUM_COEF_TYPES * sizeof(*me->ver_coefs), GFP_KERNEL); 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) { kvfree(me->hor_coefs); kvfree(me->ver_coefs); memset(me, 0, sizeof(struct ia_css_dvs_coefficients)); kvfree(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 = kvcalloc(1, sizeof(*me), GFP_KERNEL); if (!me) goto err; me->grid = *grid; me->hor_prod.odd_real = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->hor_prod.odd_real), GFP_KERNEL); if (!me->hor_prod.odd_real) goto err; me->hor_prod.odd_imag = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->hor_prod.odd_imag), GFP_KERNEL); if (!me->hor_prod.odd_imag) goto err; me->hor_prod.even_real = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->hor_prod.even_real), GFP_KERNEL); if (!me->hor_prod.even_real) goto err; me->hor_prod.even_imag = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->hor_prod.even_imag), GFP_KERNEL); if (!me->hor_prod.even_imag) goto err; me->ver_prod.odd_real = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->ver_prod.odd_real), GFP_KERNEL); if (!me->ver_prod.odd_real) goto err; me->ver_prod.odd_imag = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->ver_prod.odd_imag), GFP_KERNEL); if (!me->ver_prod.odd_imag) goto err; me->ver_prod.even_real = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->ver_prod.even_real), GFP_KERNEL); if (!me->ver_prod.even_real) goto err; me->ver_prod.even_imag = kvmalloc(grid->aligned_width * grid->aligned_height * sizeof(*me->ver_prod.even_imag), GFP_KERNEL); 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) { kvfree(me->hor_prod.odd_real); kvfree(me->hor_prod.odd_imag); kvfree(me->hor_prod.even_real); kvfree(me->hor_prod.even_imag); kvfree(me->ver_prod.odd_real); kvfree(me->ver_prod.odd_imag); kvfree(me->ver_prod.even_real); kvfree(me->ver_prod.even_imag); memset(me, 0, sizeof(struct ia_css_dvs2_statistics)); kvfree(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 = kvcalloc(1, sizeof(*me), GFP_KERNEL); if (!me) goto err; me->grid = *grid; me->hor_coefs.odd_real = kvmalloc(grid->num_hor_coefs * sizeof(*me->hor_coefs.odd_real), GFP_KERNEL); if (!me->hor_coefs.odd_real) goto err; me->hor_coefs.odd_imag = kvmalloc(grid->num_hor_coefs * sizeof(*me->hor_coefs.odd_imag), GFP_KERNEL); if (!me->hor_coefs.odd_imag) goto err; me->hor_coefs.even_real = kvmalloc(grid->num_hor_coefs * sizeof(*me->hor_coefs.even_real), GFP_KERNEL); if (!me->hor_coefs.even_real) goto err; me->hor_coefs.even_imag = kvmalloc(grid->num_hor_coefs * sizeof(*me->hor_coefs.even_imag), GFP_KERNEL); if (!me->hor_coefs.even_imag) goto err; me->ver_coefs.odd_real = kvmalloc(grid->num_ver_coefs * sizeof(*me->ver_coefs.odd_real), GFP_KERNEL); if (!me->ver_coefs.odd_real) goto err; me->ver_coefs.odd_imag = kvmalloc(grid->num_ver_coefs * sizeof(*me->ver_coefs.odd_imag), GFP_KERNEL); if (!me->ver_coefs.odd_imag) goto err; me->ver_coefs.even_real = kvmalloc(grid->num_ver_coefs * sizeof(*me->ver_coefs.even_real), GFP_KERNEL); if (!me->ver_coefs.even_real) goto err; me->ver_coefs.even_imag = kvmalloc(grid->num_ver_coefs * sizeof(*me->ver_coefs.even_imag), GFP_KERNEL); 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) { kvfree(me->hor_coefs.odd_real); kvfree(me->hor_coefs.odd_imag); kvfree(me->hor_coefs.even_real); kvfree(me->hor_coefs.even_imag); kvfree(me->ver_coefs.odd_real); kvfree(me->ver_coefs.odd_imag); kvfree(me->ver_coefs.even_real); kvfree(me->ver_coefs.even_imag); memset(me, 0, sizeof(struct ia_css_dvs2_coefficients)); kvfree(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 = kvcalloc(1, sizeof(struct ia_css_dvs_6axis_config), GFP_KERNEL); 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 = kvmalloc(width_y * height_y * sizeof(uint32_t), GFP_KERNEL); if (!dvs_config->xcoords_y) goto err; dvs_config->ycoords_y = kvmalloc(width_y * height_y * sizeof(uint32_t), GFP_KERNEL); if (!dvs_config->ycoords_y) goto err; dvs_config->xcoords_uv = kvmalloc(width_uv * height_uv * sizeof(uint32_t), GFP_KERNEL); if (!dvs_config->xcoords_uv) goto err; dvs_config->ycoords_uv = kvmalloc(width_uv * height_uv * sizeof(uint32_t), GFP_KERNEL); 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) { kvfree(dvs_6axis_config->xcoords_y); kvfree(dvs_6axis_config->ycoords_y); kvfree(dvs_6axis_config->xcoords_uv); kvfree(dvs_6axis_config->ycoords_uv); memset(dvs_6axis_config, 0, sizeof(struct ia_css_dvs_6axis_config)); kvfree(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; int 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) stage->enable_zoom = enable; break; } } }