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