| /* |
| * drivers/amlogic/media/video_sink/vpp.c |
| * |
| * Copyright (C) 2017 Amlogic, Inc. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that 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 <linux/kernel.h> |
| #include <linux/err.h> |
| #include <linux/amlogic/media/vout/vinfo.h> |
| #include <linux/amlogic/media/utils/amports_config.h> |
| #include <linux/amlogic/media/vpu/vpu.h> |
| #include <linux/amlogic/media/vfm/vframe.h> |
| #include <linux/amlogic/media/video_sink/video.h> |
| #include <linux/amlogic/media/video_sink/vpp.h> |
| |
| #include "videolog.h" |
| /* #define CONFIG_VIDEO_LOG */ |
| #ifdef CONFIG_VIDEO_LOG |
| #define AMLOG |
| #endif |
| #include <linux/amlogic/media/utils/amlog.h> |
| #include <linux/amlogic/media/registers/register.h> |
| #include <linux/amlogic/media/utils/vdec_reg.h> |
| |
| #include "video_priv.h" |
| |
| #define MAX_NONLINEAR_FACTOR 0x40 |
| #define MAX_NONLINEAR_T_FACTOR 100 |
| |
| /* vpp filter coefficients */ |
| #define COEF_BICUBIC 0 |
| #define COEF_3POINT_TRIANGLE 1 |
| #define COEF_4POINT_TRIANGLE 2 |
| #define COEF_BILINEAR 3 |
| #define COEF_2POINT_BILINEAR 4 |
| #define COEF_BICUBIC_SHARP 5 |
| #define COEF_3POINT_TRIANGLE_SHARP 6 |
| #define COEF_3POINT_BSPLINE 7 |
| #define COEF_4POINT_BSPLINE 8 |
| #define COEF_3D_FILTER 9 |
| #define COEF_NULL 0xff |
| #define TOTAL_FILTERS 10 |
| |
| #define COEF_BICUBIC_8TAP 0 |
| #define COEF_LANCZOS_8TAP_A2 1 |
| #define COEF_LANCZOS_8TAP_A3 2 |
| #define COEF_LANCZOS_8TAP_A4 3 |
| #define COEF_MITCHELL_NETRAVALI_8TAP 4 |
| #define COEF_BSPLINE_8TAP 5 |
| |
| #define VPP_SPEED_FACTOR 0x110ULL |
| #define SUPER_SCALER_V_FACTOR 100 |
| #define PPS_FRAC_BITS 24 |
| #define PPS_INT_BITS 4 |
| |
| struct filter_info_s { |
| u32 cur_vert_filter; |
| u32 cur_horz_filter; |
| u32 last_vert_filter; |
| u32 last_horz_filter; |
| u32 scaler_filter_cnt; |
| }; |
| |
| #define PPS_COEF_NUM (66 + 2) |
| #define PPS_COEF_8TAP_NUM (132 + 2) |
| static unsigned int pps_coef = PPS_COEF_NUM; |
| static unsigned int pps_coef_8tap = PPS_COEF_8TAP_NUM; |
| static uint test_pps_h_coef[PPS_COEF_NUM] = {2, 33}; |
| static uint test_pps_h_coef_8tap[PPS_COEF_8TAP_NUM] = {8, 33}; |
| static uint test_pps_v_coef[PPS_COEF_NUM] = {2, 33}; |
| static uint test_pps_v_coef_8tap[PPS_COEF_8TAP_NUM] = {8, 33}; |
| static uint force_pps_hcoef_update; |
| static uint force_pps_vcoef_update; |
| uint load_pps_coef; |
| MODULE_PARM_DESC(force_pps_hcoef_update, "\n force_pps_hcoef_update\n"); |
| module_param(force_pps_hcoef_update, uint, 0664); |
| MODULE_PARM_DESC(force_pps_vcoef_update, "\n force_pps_vcoef_update\n"); |
| module_param(force_pps_vcoef_update, uint, 0664); |
| module_param_array(test_pps_h_coef, uint, &pps_coef, 0664); |
| MODULE_PARM_DESC(test_pps_h_coef, "\n test_pps_h_coef\n"); |
| module_param_array(test_pps_v_coef, uint, &pps_coef, 0664); |
| MODULE_PARM_DESC(test_pps_v_coef, "\n test_pps_v_coef\n"); |
| module_param_array(test_pps_h_coef_8tap, uint, &pps_coef_8tap, 0664); |
| MODULE_PARM_DESC(test_pps_h_coef_8tap, "\n test_pps_h_coef_8tap\n"); |
| module_param_array(test_pps_v_coef_8tap, uint, &pps_coef_8tap, 0664); |
| MODULE_PARM_DESC(test_pps_v_coef_8tap, "\n test_pps_v_coef_8tap\n"); |
| |
| static struct filter_info_s gfilter[MAX_VD_LAYERS]; |
| |
| const u32 vpp_filter_coefs_bicubic_sharp[] = { |
| 3, |
| 33, |
| /* 0x01f80090, 0x01f80100, 0xff7f0200, 0xfe7f0300, */ |
| 0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300, |
| 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, |
| 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, |
| 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, |
| 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, |
| 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, |
| 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, |
| 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, |
| 0xf84848f8 |
| }; |
| |
| const u32 vpp_filter_coefs_bicubic[] = { |
| 4, |
| 33, |
| 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, |
| 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, |
| 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, |
| 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, |
| 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, |
| 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, |
| 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, |
| 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, |
| 0xf84848f8 |
| }; |
| |
| const u32 vpp_filter_coefs_bilinear[] = { |
| 4, |
| 33, |
| 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, |
| 0x00780800, 0x00760a00, 0x00740c00, 0x00720e00, |
| 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600, |
| 0x00681800, 0x00661a00, 0x00641c00, 0x00621e00, |
| 0x00602000, 0x005e2200, 0x005c2400, 0x005a2600, |
| 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00, |
| 0x00503000, 0x004e3200, 0x004c3400, 0x004a3600, |
| 0x00483800, 0x00463a00, 0x00443c00, 0x00423e00, |
| 0x00404000 |
| }; |
| |
| const u32 vpp_3d_filter_coefs_bilinear[] = { |
| 2, |
| 33, |
| 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, |
| 0x78080000, 0x760a0000, 0x740c0000, 0x720e0000, |
| 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, |
| 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, |
| 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, |
| 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, |
| 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, |
| 0x48380000, 0x463a0000, 0x443c0000, 0x423e0000, |
| 0x40400000 |
| }; |
| |
| const u32 vpp_filter_coefs_3point_triangle[] = { |
| 3, |
| 33, |
| 0x40400000, 0x3f400100, 0x3d410200, 0x3c410300, |
| 0x3a420400, 0x39420500, 0x37430600, 0x36430700, |
| 0x35430800, 0x33450800, 0x32450900, 0x31450a00, |
| 0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00, |
| 0x2b470e00, 0x29480f00, 0x28481000, 0x27481100, |
| 0x26491100, 0x25491200, 0x24491300, 0x234a1300, |
| 0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600, |
| 0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900, |
| 0x1a4c1a00 |
| }; |
| |
| /* point_num =4, filt_len =4, group_num = 64, [1 2 1] */ |
| const u32 vpp_filter_coefs_4point_triangle[] = { |
| 4, |
| 33, |
| 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, |
| 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, |
| 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, |
| 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, |
| 0x18382808, 0x18382808, 0x17372909, 0x17372909, |
| 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, |
| 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, |
| 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, |
| 0x10303010 |
| }; |
| /* |
| *4th order (cubic) b-spline |
| *filt_cubic point_num =4, filt_len =4, group_num = 64, [1 5 1] |
| */ |
| const u32 vpp_filter_coefs_4point_bspline[] = { |
| 4, |
| 33, |
| 0x15561500, 0x14561600, 0x13561700, 0x12561800, |
| 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00, |
| 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200, |
| 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700, |
| 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01, |
| 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201, |
| 0x05473301, 0x05463401, 0x04453601, 0x04433702, |
| 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02, |
| 0x033d3d03 |
| }; |
| /*3rd order (quadratic) b-spline*/ |
| /*filt_quadratic, point_num =3, filt_len =3, group_num = 64, [1 6 1] */ |
| const u32 vpp_filter_coefs_3point_bspline[] = { |
| 3, |
| 33, |
| 0x40400000, 0x3e420000, 0x3c440000, 0x3a460000, |
| 0x38480000, 0x364a0000, 0x344b0100, 0x334c0100, |
| 0x314e0100, 0x304f0100, 0x2e500200, 0x2c520200, |
| 0x2a540200, 0x29540300, 0x27560300, 0x26570300, |
| 0x24580400, 0x23590400, 0x215a0500, 0x205b0500, |
| 0x1e5c0600, 0x1d5c0700, 0x1c5d0700, 0x1a5e0800, |
| 0x195e0900, 0x185e0a00, 0x175f0a00, 0x15600b00, |
| 0x14600c00, 0x13600d00, 0x12600e00, 0x11600f00, |
| 0x10601000 |
| }; |
| /*filt_triangle, point_num =3, filt_len =2.6, group_num = 64, [1 7 1] */ |
| const u32 vpp_filter_coefs_3point_triangle_sharp[] = { |
| 3, |
| 33, |
| 0x40400000, 0x3e420000, 0x3d430000, 0x3b450000, |
| 0x3a460000, 0x38480000, 0x37490000, 0x354b0000, |
| 0x344c0000, 0x324e0000, 0x314f0000, 0x2f510000, |
| 0x2e520000, 0x2c540000, 0x2b550000, 0x29570000, |
| 0x28580000, 0x265a0000, 0x245c0000, 0x235d0000, |
| 0x215f0000, 0x20600000, 0x1e620000, 0x1d620100, |
| 0x1b620300, 0x19630400, 0x17630600, 0x15640700, |
| 0x14640800, 0x12640a00, 0x11640b00, 0x0f650c00, |
| 0x0d660d00 |
| }; |
| |
| const u32 vpp_filter_coefs_2point_binilear[] = { |
| 2, |
| 33, |
| 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, |
| 0x78080000, 0x760a0000, 0x740c0000, 0x720e0000, |
| 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, |
| 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, |
| 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, |
| 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, |
| 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, |
| 0x48380000, 0x463a0000, 0x443c0000, 0x423e0000, |
| 0x40400000 |
| }; |
| |
| static const u32 *filter_table[] = { |
| vpp_filter_coefs_bicubic, |
| vpp_filter_coefs_3point_triangle, |
| vpp_filter_coefs_4point_triangle, |
| vpp_filter_coefs_bilinear, |
| vpp_filter_coefs_2point_binilear, |
| vpp_filter_coefs_bicubic_sharp, |
| vpp_filter_coefs_3point_triangle_sharp, |
| vpp_filter_coefs_3point_bspline, |
| vpp_filter_coefs_4point_bspline, |
| vpp_3d_filter_coefs_bilinear |
| }; |
| |
| static int chroma_filter_table[] = { |
| COEF_BICUBIC, /* bicubic */ |
| COEF_3POINT_TRIANGLE, |
| COEF_4POINT_TRIANGLE, |
| COEF_4POINT_TRIANGLE, /* bilinear */ |
| COEF_2POINT_BILINEAR, |
| COEF_3POINT_TRIANGLE, /* bicubic_sharp */ |
| COEF_3POINT_TRIANGLE, /* 3point_triangle_sharp */ |
| COEF_3POINT_TRIANGLE, /* 3point_bspline */ |
| COEF_4POINT_TRIANGLE, /* 4point_bspline */ |
| COEF_3D_FILTER /* can not change */ |
| }; |
| |
| const u32 vpp_filter_coeff_bicubic_8tap[] = { |
| 8, |
| 33, |
| 0x80, 0xff80, 0xfe80, 0xfd7f, |
| 0xfc7f, 0xfc7e, 0xfb7e, 0xfa7d, |
| 0xfa7b, 0xf97a, 0xf978, 0xf878, |
| 0xf876, 0xf874, 0xf773, 0xf771, |
| 0xf76f, 0xf76d, 0xf76b, 0xf768, |
| 0xf766, 0xf764, 0xf762, 0xf75f, |
| 0xf75d, 0xf75a, 0xf758, 0xf756, |
| 0xf753, 0xf750, 0xf84d, 0xf84b, |
| 0xf848, |
| 0x0, 0x1000000, 0x2000000, 0x4000000, |
| 0x5000000, 0x6000000, 0x8ff0000, 0xaff0000, |
| 0xcff0000, 0xeff0000, 0x10ff0000, 0x12fe0000, |
| 0x14fe0000, 0x16fe0000, 0x18fe0000, 0x1bfd0000, |
| 0x1dfd0000, 0x1ffd0000, 0x22fc0000, 0x25fc0000, |
| 0x27fc0000, 0x2afb0000, 0x2cfb0000, 0x2ffb0000, |
| 0x32fa0000, 0x35fa0000, 0x37fa0000, 0x3af90000, |
| 0x3df90000, 0x40f90000, 0x42f90000, 0x45f80000, |
| 0x48f80000 |
| }; |
| |
| const u32 vpp_filter_coeff_lanczos_8tap_a2[] = { |
| 8, |
| 33, |
| 0x80, 0xff80, 0xfe80, 0xfd7f, |
| 0xfc7f, 0xfb7e, 0xfa7e, 0xf97d, |
| 0xf87c, 0xf87b, 0xf77a, 0xf778, |
| 0xf677, 0xf675, 0xf674, 0xf572, |
| 0xf570, 0xf56e, 0xf56c, 0xf46a, |
| 0xf568, 0xf466, 0xf364, 0xf561, |
| 0xf45f, 0xf45c, 0xf45a, 0xf557, |
| 0xf654, 0xf552, 0xf54f, 0xf64c, |
| 0xf749, |
| 0x0, 0x1000000, 0x3ff0000, 0x4000000, |
| 0x6ff0000, 0x7000000, 0x9ff0000, 0xbff0000, |
| 0xdff0000, 0xffe0000, 0x11fe0000, 0x13fe0000, |
| 0x15fe0000, 0x17fe0000, 0x19fd0000, 0x1cfd0000, |
| 0x1efd0000, 0x21fc0000, 0x23fc0000, 0x26fc0000, |
| 0x28fb0000, 0x2bfb0000, 0x2efb0000, 0x30fa0000, |
| 0x33fa0000, 0x36fa0000, 0x39f90000, 0x3bf90000, |
| 0x3ef80000, 0x41f80000, 0x44f80000, 0x47f70000, |
| 0x49f70000 |
| }; |
| |
| const u32 vpp_filter_coeff_lanczos_8tap_a3[] = { |
| 8, |
| 33, |
| 0x80, 0xfe80, 0x1fd80, 0x1fb7f, |
| 0x1fa7f, 0x2f97f, 0x2f77e, 0x2f67d, |
| 0x3f57c, 0x3f47b, 0x3f37a, 0x4f279, |
| 0x3f178, 0x4f177, 0x4f075, 0x4f074, |
| 0x4ef72, 0x4ef70, 0x4ee6e, 0x5ee6c, |
| 0x4ee6a, 0x4ed68, 0x4ed66, 0x4ed64, |
| 0x4ed62, 0x4ed5f, 0x4ed5d, 0x4ed5b, |
| 0x4ee58, 0x3ee56, 0x4ee53, 0x4ee50, |
| 0x3ef4e, |
| 0x0, 0x2000000, 0x3ff0000, 0x5ff0100, |
| 0x7fe0100, 0x9feff00, 0xbfd0100, 0xdfd0100, |
| 0xffc0100, 0x12fc0000, 0x14fb0100, 0x16fa0100, |
| 0x19fa0100, 0x1bf90000, 0x1ef90000, 0x20f80000, |
| 0x23f70100, 0x25f70100, 0x28f60200, 0x2af50200, |
| 0x2df50200, 0x30f40300, 0x33f40200, 0x35f30300, |
| 0x38f30200, 0x3bf20300, 0x3ef10300, 0x40f10300, |
| 0x43f00300, 0x46f00300, 0x48ef0400, 0x4bef0400, |
| 0x4eef0300 |
| }; |
| |
| const u32 vpp_filter_coeff_lanczos_8tap_a4[] = { |
| 8, |
| 33, |
| 0x80, 0x1fe80, 0x1fd80, 0xff02fb80, |
| 0xff02f97f, 0xff03f87f, 0xff03f67e, 0xff04f57d, |
| 0xff04f47d, 0xfe05f37c, 0xfe05f27b, 0xfd06f17a, |
| 0xfe06f078, 0xfe06ef77, 0xfe07ee76, 0xfe07ed74, |
| 0xfe07ec73, 0xfe07ec71, 0xfe08eb6f, 0xfe08eb6d, |
| 0xfe08eb6b, 0xfe08ea69, 0xfe08ea67, 0xfe08ea65, |
| 0xfe08ea63, 0xfe08ea61, 0xfe08ea5e, 0xfe08ea5c, |
| 0xfe08ea5a, 0xfe08ea57, 0xfe08ea55, 0xfe08ea52, |
| 0xfe08eb4f, |
| 0x0, 0x2ff0000, 0x4ff00ff, 0x6fe01ff, |
| 0x8fd0101, 0xafd01ff, 0xcfc0101, 0xefb0200, |
| 0x10fa0200, 0x13fa02ff, 0x15f90200, 0x18f803ff, |
| 0x1af70300, 0x1df703ff, 0x1ff603ff, 0x22f504ff, |
| 0x24f40400, 0x27f30400, 0x2af305fe, 0x2cf205ff, |
| 0x2ff105ff, 0x32f105ff, 0x34f006ff, 0x37ef06ff, |
| 0x3aef06fe, 0x3dee06fe, 0x3fed07ff, 0x42ed07fe, |
| 0x45ec07fe, 0x47ec07ff, 0x4aeb07ff, 0x4deb08fe, |
| 0x4feb08fe |
| }; |
| |
| const u32 vpp_filter_coeff_mitchell_netravali_8tap[] = { |
| 8, |
| 33, |
| 0x772, 0x672, 0x572, 0x471, |
| 0x470, 0x370, 0x26f, 0x16f, |
| 0x16e, 0x6e, 0x6c, 0xff6b, |
| 0xff69, 0xfe68, 0xfe67, 0xfd66, |
| 0xfd64, 0xfd62, 0xfc61, 0xfc5f, |
| 0xfc5e, 0xfc5b, 0xfc59, 0xfc57, |
| 0xfb56, 0xfb54, 0xfb52, 0xfb50, |
| 0xfb4e, 0xfb4b, 0xfb49, 0xfb47, |
| 0xfc44, |
| 0x7000000, 0x8000000, 0x9000000, 0xb000000, |
| 0xc000000, 0xd000000, 0xf000000, 0x10000000, |
| 0x12ff0000, 0x13ff0000, 0x15ff0000, 0x17ff0000, |
| 0x19ff0000, 0x1bff0000, 0x1dfe0000, 0x1ffe0000, |
| 0x21fe0000, 0x23fe0000, 0x25fe0000, 0x27fe0000, |
| 0x29fd0000, 0x2cfd0000, 0x2efd0000, 0x30fd0000, |
| 0x32fd0000, 0x35fc0000, 0x37fc0000, 0x39fc0000, |
| 0x3bfc0000, 0x3efc0000, 0x40fc0000, 0x42fc0000, |
| 0x44fc0000 |
| }; |
| |
| const u32 vpp_filter_coeff_bspline_8tap[] = { |
| 8, |
| 33, |
| 0x1556, 0x1456, 0x1356, 0x1256, |
| 0x1254, 0x1154, 0x1054, 0xf54, |
| 0xe54, 0xe53, 0xd52, 0xc52, |
| 0xb52, 0xb51, 0xa50, 0xa4f, |
| 0x94f, 0x84e, 0x84d, 0x74c, |
| 0x74a, 0x64a, 0x649, 0x647, |
| 0x547, 0x546, 0x445, 0x443, |
| 0x442, 0x341, 0x340, 0x33f, |
| 0x33d, |
| 0x15000000, 0x16000000, 0x17000000, 0x18000000, |
| 0x1a000000, 0x1b000000, 0x1c000000, 0x1d000000, |
| 0x1e000000, 0x1f000000, 0x21000000, 0x22000000, |
| 0x23000000, 0x24000000, 0x26000000, 0x27000000, |
| 0x28000000, 0x2a000000, 0x2b000000, 0x2c010000, |
| 0x2e010000, 0x2f010000, 0x30010000, 0x32010000, |
| 0x33010000, 0x34010000, 0x36010000, 0x37020000, |
| 0x38020000, 0x3a020000, 0x3b020000, 0x3c020000, |
| 0x3d030000 |
| }; |
| |
| static const u32 *hscaler_8tap_filter_table[] = { |
| vpp_filter_coeff_bicubic_8tap, |
| vpp_filter_coeff_lanczos_8tap_a2, |
| vpp_filter_coeff_lanczos_8tap_a3, |
| vpp_filter_coeff_lanczos_8tap_a4, |
| vpp_filter_coeff_mitchell_netravali_8tap, |
| vpp_filter_coeff_bspline_8tap |
| }; |
| |
| static unsigned int sharpness1_sr2_ctrl_32d7 = 0x00181008; |
| MODULE_PARM_DESC(sharpness1_sr2_ctrl_32d7, "sharpness1_sr2_ctrl_32d7"); |
| module_param(sharpness1_sr2_ctrl_32d7, uint, 0664); |
| /*0x3280 default val: 1920x1080*/ |
| static unsigned int sharpness1_sr2_ctrl_3280 = 0xffffffff; |
| MODULE_PARM_DESC(sharpness1_sr2_ctrl_3280, "sharpness1_sr2_ctrl_3280"); |
| module_param(sharpness1_sr2_ctrl_3280, uint, 0664); |
| |
| static unsigned int vpp_filter_fix; |
| MODULE_PARM_DESC(vpp_filter_fix, "vpp_filter_fix"); |
| module_param(vpp_filter_fix, uint, 0664); |
| |
| #define MAX_COEFF_LEVEL 5 |
| #define MAX_COEFF_LEVEL_SC2 6 |
| static uint num_coeff_level = MAX_COEFF_LEVEL; |
| static uint vert_coeff_settings[MAX_COEFF_LEVEL] = { |
| /* in:out */ |
| COEF_BICUBIC, |
| /* ratio < 1 */ |
| COEF_BICUBIC_SHARP, |
| /* ratio = 1 and phase = 0, */ |
| /* use for MBX without sharpness HW module, */ |
| /* TV use COEF_BICUBIC in function coeff */ |
| COEF_BICUBIC, |
| /* ratio in (1~0.5) */ |
| COEF_3POINT_BSPLINE, |
| /* ratio in [0.5~0.333) with pre-scaler on */ |
| /* this setting is sharpness/smooth balanced */ |
| /* if need more smooth(less sharp, could use */ |
| /* COEF_4POINT_BSPLINE or COEF_4POINT_TRIANGLE */ |
| COEF_4POINT_TRIANGLE, |
| /* ratio <= 0.333 with pre-scaler on */ |
| /* this setting is most smooth */ |
| }; |
| |
| static uint horz_coeff_settings[MAX_COEFF_LEVEL] = { |
| /* in:out */ |
| COEF_BICUBIC, |
| /* ratio < 1 */ |
| COEF_BICUBIC_SHARP, |
| /* ratio = 1 and phase = 0, */ |
| /* use for MBX without sharpness HW module, */ |
| /* TV use COEF_BICUBIC in function coeff */ |
| COEF_BICUBIC, |
| /* ratio in (1~0.5) */ |
| COEF_3POINT_BSPLINE, |
| /* ratio in [0.5~0.333) with pre-scaler on */ |
| /* this setting is sharpness/smooth balanced */ |
| /* if need more smooth(less sharp, could use */ |
| /* COEF_4POINT_BSPLINE or COEF_4POINT_TRIANGLE */ |
| COEF_4POINT_TRIANGLE, |
| /* ratio <= 0.333 with pre-scaler on */ |
| /* this setting is most smooth */ |
| }; |
| |
| static uint hert_coeff_settings_sc2[MAX_COEFF_LEVEL_SC2] = { |
| /* in:out */ |
| COEF_BICUBIC_8TAP, |
| COEF_LANCZOS_8TAP_A2, |
| COEF_LANCZOS_8TAP_A3, |
| COEF_LANCZOS_8TAP_A4, |
| COEF_MITCHELL_NETRAVALI_8TAP, |
| /* reserved */ |
| COEF_BSPLINE_8TAP, |
| /* reserved */ |
| }; |
| |
| static uint coeff(uint *settings, uint ratio, uint phase, |
| bool interlace, int combing_lev) |
| { |
| uint coeff_select = 0; |
| uint coeff_type = 0; |
| |
| if (ratio >= (3 << 24)) |
| coeff_select = 4; |
| else if (ratio >= (2 << 24)) |
| coeff_select = 3; |
| else if (ratio > (1 << 24)) |
| coeff_select = 2; |
| else if (ratio == (1 << 24)) { |
| if (phase == 0) |
| coeff_select = 1; |
| else |
| coeff_select = 2; |
| } |
| coeff_type = settings[coeff_select]; |
| /* TODO: add future TV chips */ |
| if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || |
| is_meson_txlx_cpu()) { |
| if (coeff_type == COEF_BICUBIC_SHARP) |
| coeff_type = COEF_BICUBIC; |
| } else { |
| /* |
| *gxtvbb use dejaggy in SR0 to reduce intelace combing |
| *other chip no dejaggy, need swtich to more blur filter |
| */ |
| if (interlace && (coeff_select < 3) && vpp_filter_fix) |
| coeff_type = COEF_4POINT_BSPLINE; |
| /* use bicubic for static scene */ |
| if (combing_lev == 0) |
| coeff_type = COEF_BICUBIC; |
| } |
| return coeff_type; |
| } |
| |
| static uint coeff_sc2(uint *settings, uint ratio) |
| { |
| uint coeff_select = 0; |
| uint coeff_type = 0; |
| |
| if (ratio < (8 << 20)) |
| /* zoom out > 2 */ |
| coeff_select = COEF_LANCZOS_8TAP_A4; |
| else if ((ratio <= (1 << 24)) && (ratio >= (8 << 20))) |
| /* ration in >= 1/2 */ |
| coeff_select = COEF_LANCZOS_8TAP_A4; |
| else if (ratio <= (2 << 24)) |
| /* zoom in >= 1/2*/ |
| coeff_select = COEF_LANCZOS_8TAP_A2; |
| else if (ratio > (2 << 24)) |
| /* ratio in < 1/2*/ |
| coeff_select = COEF_LANCZOS_8TAP_A2; |
| |
| coeff_type = settings[coeff_select]; |
| return coeff_type; |
| } |
| |
| /* vertical and horizontal coeff settings */ |
| module_param_array(vert_coeff_settings, uint, &num_coeff_level, 0664); |
| MODULE_PARM_DESC(vert_coeff_settings, "\n vert_coeff_settings\n"); |
| |
| module_param_array(horz_coeff_settings, uint, &num_coeff_level, 0664); |
| MODULE_PARM_DESC(horz_coeff_settings, "\n horz_coeff_settings\n"); |
| |
| static bool vert_chroma_filter_en = true; |
| module_param(vert_chroma_filter_en, bool, 0664); |
| MODULE_PARM_DESC(vert_chroma_filter_en, "enable vertical chromafilter\n"); |
| |
| static bool vert_chroma_filter_force_en; |
| module_param(vert_chroma_filter_force_en, bool, 0664); |
| MODULE_PARM_DESC(vert_chroma_filter_force_en, |
| "force enable vertical chromafilter\n"); |
| |
| static uint vert_chroma_filter_limit = 480; |
| module_param(vert_chroma_filter_limit, uint, 0664); |
| MODULE_PARM_DESC(vert_chroma_filter_limit, "vertical chromafilter limit\n"); |
| |
| static uint num_chroma_filter = TOTAL_FILTERS; |
| module_param_array(chroma_filter_table, uint, &num_chroma_filter, 0664); |
| MODULE_PARM_DESC(chroma_filter_table, "\n chroma_filter_table\n"); |
| |
| static uint cur_vert_chroma_filter; |
| MODULE_PARM_DESC(cur_vert_chroma_filter, "cur_vert_chroma_filter"); |
| module_param(cur_vert_chroma_filter, int, 0444); |
| |
| static uint cur_vert_filter; |
| MODULE_PARM_DESC(cur_vert_filter, "cur_vert_filter"); |
| module_param(cur_vert_filter, int, 0444); |
| |
| static uint cur_horz_filter; |
| MODULE_PARM_DESC(cur_horz_filter, "cur_horz_filter"); |
| module_param(cur_horz_filter, int, 0444); |
| |
| static uint cur_skip_line; |
| MODULE_PARM_DESC(cur_skip_line, "cur_skip_line"); |
| module_param(cur_skip_line, int, 0444); |
| |
| static unsigned int super_scaler_v_ratio = 133; |
| MODULE_PARM_DESC(super_scaler_v_ratio, "super_scaler_v_ratio"); |
| module_param(super_scaler_v_ratio, uint, 0664); |
| |
| static u32 skip_policy = 0x81; |
| module_param(skip_policy, uint, 0664); |
| MODULE_PARM_DESC(skip_policy, "\n skip_policy\n"); |
| |
| static unsigned int scaler_filter_cnt_limit = 10; |
| MODULE_PARM_DESC(scaler_filter_cnt_limit, "scaler_filter_cnt_limit"); |
| module_param(scaler_filter_cnt_limit, uint, 0664); |
| |
| #ifdef TV_3D_FUNCTION_OPEN |
| static int force_filter_mode = 1; |
| MODULE_PARM_DESC(force_filter_mode, "force_filter_mode"); |
| module_param(force_filter_mode, int, 0664); |
| #endif |
| /*temp disable sr for power test*/ |
| bool super_scaler = true; |
| struct sr_info_s sr_info; |
| static unsigned int super_debug; |
| module_param(super_debug, uint, 0664); |
| MODULE_PARM_DESC(super_debug, "super_debug"); |
| |
| static unsigned int scaler_path_sel = SCALER_PATH_MAX; |
| module_param(scaler_path_sel, uint, 0664); |
| MODULE_PARM_DESC(scaler_path_sel, "scaler_path_sel"); |
| |
| static bool bypass_spscl0; |
| module_param(bypass_spscl0, bool, 0664); |
| MODULE_PARM_DESC(bypass_spscl0, "bypass_spscl0"); |
| |
| static bool bypass_spscl1; |
| module_param(bypass_spscl1, bool, 0664); |
| MODULE_PARM_DESC(bypass_spscl1, "bypass_spscl1"); |
| |
| static unsigned int vert_scaler_filter = 0xff; |
| module_param(vert_scaler_filter, uint, 0664); |
| MODULE_PARM_DESC(vert_scaler_filter, "vert_scaler_filter"); |
| |
| static unsigned int vert_chroma_scaler_filter = 0xff; |
| module_param(vert_chroma_scaler_filter, uint, 0664); |
| MODULE_PARM_DESC(vert_chroma_scaler_filter, "vert_chroma_scaler_filter"); |
| |
| static unsigned int horz_scaler_filter = 0xff; |
| module_param(horz_scaler_filter, uint, 0664); |
| MODULE_PARM_DESC(horz_scaler_filter, "horz_scaler_filter"); |
| |
| static unsigned int horz_scaler_filter_8tap = 0xff; |
| module_param(horz_scaler_filter_8tap, uint, 0664); |
| MODULE_PARM_DESC(horz_scaler_filter_8tap, "horz_scaler_filter_8tap"); |
| /*need check this value,*/ |
| static unsigned int bypass_ratio = 205; |
| module_param(bypass_ratio, uint, 0664); |
| MODULE_PARM_DESC(bypass_ratio, "bypass_ratio"); |
| |
| static unsigned int sr0_sr1_refresh = 1; |
| module_param(sr0_sr1_refresh, uint, 0664); |
| MODULE_PARM_DESC(sr0_sr1_refresh, "sr0_sr1_refresh"); |
| |
| static bool pre_scaler_en = true; |
| module_param(pre_scaler_en, bool, 0664); |
| MODULE_PARM_DESC(pre_scaler_en, "pre_scaler_en"); |
| |
| static unsigned int force_vskip_cnt; |
| MODULE_PARM_DESC(force_vskip_cnt, "force_vskip_cnt"); |
| module_param(force_vskip_cnt, uint, 0664); |
| |
| static unsigned int disable_adapted; |
| MODULE_PARM_DESC(disable_adapted, "disable_adapted"); |
| module_param(disable_adapted, uint, 0664); |
| |
| #if 0 |
| #define DECL_PARM(name)\ |
| static int name;\ |
| MODULE_PARM_DESC(name, #name);\ |
| module_param(name, int, 0664); |
| |
| DECL_PARM(debug_wide_mode) |
| DECL_PARM(debug_video_left) |
| DECL_PARM(debug_video_top) |
| DECL_PARM(debug_video_width) |
| DECL_PARM(debug_video_height) |
| DECL_PARM(debug_ratio_x) |
| DECL_PARM(debug_ratio_y) |
| #endif |
| #define ZOOM_BITS 18 |
| #define PHASE_BITS 8 |
| /* |
| * when ratio for Y is 1:1 |
| * Line # In(P) In(I) Out(P) Out(I) Out(P) Out(I) |
| * 0 P_Y IT_Y P_Y IT_Y |
| * 1 P_Y IT_Y |
| * 2 IB_Y IB_Y |
| * 3 IB_Y |
| * 4 P_Y IT_Y P_Y IT_Y |
| * 5 P_Y IT_Y |
| * 6 IB_Y IB_Y |
| * 7 IB_Y |
| * 8 P_Y IT_Y P_Y IT_Y |
| * 9 P_Y IT_Y |
| * 10 IB_Y IB_Y |
| * 11 IB_Y |
| * 12 P_Y IT_Y P_Y IT_Y |
| * P_Y IT_Y |
| */ |
| /* |
| *The table data sequence here is arranged according to |
| * enum f2v_vphase_type_e enum, |
| * IT2IT, IB2IB, T2IB, IB2IT, P2IT, P2IB, IT2P, IB2P, P2P |
| */ |
| static const u8 f2v_420_in_pos[F2V_TYPE_MAX] = { 0, 2, 0, 2, 0, 0, 0, 2, 0 }; |
| static const u8 f2v_420_out_pos1[F2V_TYPE_MAX] = { 0, 2, 2, 0, 0, 2, 0, 0, 0 }; |
| static const u8 f2v_420_out_pos2[F2V_TYPE_MAX] = { 1, 3, 3, 1, 1, 3, 1, 1, 1 }; |
| |
| static void f2v_get_vertical_phase(u32 zoom_ratio, |
| u32 phase_adj, |
| struct f2v_vphase_s vphase[F2V_TYPE_MAX], |
| u32 interlace) |
| { |
| enum f2v_vphase_type_e type; |
| s32 offset_in, offset_out; |
| s32 phase; |
| const u8 *f2v_420_out_pos; |
| |
| if ((interlace == 0) && (zoom_ratio > (1 << ZOOM_BITS))) |
| f2v_420_out_pos = f2v_420_out_pos2; |
| else |
| f2v_420_out_pos = f2v_420_out_pos1; |
| |
| for (type = F2V_IT2IT; type < F2V_TYPE_MAX; type++) { |
| offset_in = f2v_420_in_pos[type] << PHASE_BITS; |
| offset_out = |
| (f2v_420_out_pos[type] * zoom_ratio) >> (ZOOM_BITS - |
| PHASE_BITS); |
| |
| if (offset_in > offset_out) { |
| vphase[type].repeat_skip = -1; /* repeat line */ |
| vphase[type].phase = |
| ((4 << PHASE_BITS) + offset_out - offset_in) >> 2; |
| |
| } else { |
| vphase[type].repeat_skip = 0; /* skip line */ |
| |
| while ((offset_in + (4 << PHASE_BITS)) <= |
| offset_out) { |
| vphase[type].repeat_skip++; |
| offset_in += 4 << PHASE_BITS; |
| } |
| |
| vphase[type].phase = (offset_out - offset_in) >> 2; |
| } |
| |
| phase = vphase[type].phase + phase_adj; |
| |
| if (phase > 0x100) |
| vphase[type].repeat_skip++; |
| |
| vphase[type].phase = phase & 0xff; |
| |
| if (vphase[type].repeat_skip > 5) |
| vphase[type].repeat_skip = 5; |
| } |
| } |
| |
| /* Trapezoid non-linear mode */ |
| /* nonlinear_factor: 0x40: 1 : 1 */ |
| static void calculate_non_linear_ratio_T( |
| unsigned int nonlinear_t_factor, |
| unsigned int width_in, |
| unsigned int width_out, |
| struct vpp_frame_par_s *next_frame_par) |
| { |
| u32 ratio, r2_ratio, r1_ratio; |
| u32 region2_hsize_B_max; |
| u32 region2_hsize_A, region2_hsize_B; |
| u32 region1_hsize; |
| u32 phase_step, phase_slope; |
| struct vppfilter_mode_s *vpp_filter = |
| &next_frame_par->vpp_filter; |
| |
| ratio = (width_in << 18) / width_out; |
| r2_ratio = (ratio * MAX_NONLINEAR_T_FACTOR / |
| nonlinear_t_factor) << 6; |
| if (r2_ratio < ratio) { |
| pr_info("nonlinear_t_factor(%d) is too large!\n", |
| nonlinear_t_factor); |
| return; |
| } |
| region2_hsize_B_max = (((2 * width_in << 18) / r2_ratio) |
| << 6) - width_out; |
| region2_hsize_B = region2_hsize_B_max; |
| region2_hsize_A = (region2_hsize_B * (r2_ratio >> 6)) >> 18; |
| region1_hsize = (width_out - region2_hsize_B) / 2; |
| r1_ratio = (((width_in - region2_hsize_A) << 18) / |
| (width_out - region2_hsize_B)) << 6; |
| phase_step = 2 * r1_ratio - r2_ratio; |
| phase_slope = (r2_ratio - phase_step) / region1_hsize; |
| vpp_filter->vpp_hf_start_phase_step = phase_step; |
| vpp_filter->vpp_hf_start_phase_slope = phase_slope; |
| vpp_filter->vpp_hf_end_phase_slope = |
| vpp_filter->vpp_hf_start_phase_slope | 0x1000000; |
| next_frame_par->VPP_hsc_linear_startp = region1_hsize - 1; |
| next_frame_par->VPP_hsc_linear_endp = |
| region1_hsize + region2_hsize_B - 1; |
| } |
| |
| /* |
| * V-shape non-linear mode |
| */ |
| static void calculate_non_linear_ratio_V( |
| unsigned int nonlinear_factor, |
| unsigned int middle_ratio, |
| unsigned int width_out, |
| struct vpp_frame_par_s *next_frame_par) |
| { |
| unsigned int diff_ratio; |
| struct vppfilter_mode_s *vpp_filter = |
| &next_frame_par->vpp_filter; |
| |
| diff_ratio = middle_ratio * nonlinear_factor; |
| vpp_filter->vpp_hf_start_phase_step = (middle_ratio << 6) - diff_ratio; |
| vpp_filter->vpp_hf_start_phase_slope = diff_ratio * 4 / width_out; |
| vpp_filter->vpp_hf_end_phase_slope = |
| vpp_filter->vpp_hf_start_phase_slope | 0x1000000; |
| |
| } |
| |
| /* |
| *We find that the minimum line the video can be scaled |
| * down without skip line for different modes as below: |
| * 4k2k mode: |
| * video source minimus line ratio(height_in/height_out) |
| * 3840 * 2160 1690 1.278 |
| * 1920 * 1080 860 1.256 |
| * 1280 * 720 390 1.846 |
| * 720 * 480 160 3.000 |
| * 1080p mode: |
| * video source minimus line ratio(height_in/height_out) |
| * 3840 * 2160 840 2.571 |
| * 1920 * 1080 430 2.511 |
| * 1280 * 720 200 3.600 |
| * 720 * 480 80 6.000 |
| * So the safe scal ratio is 1.25 for 4K2K mode and 2.5 |
| * (1.25 * 3840 / 1920) for 1080p mode. |
| */ |
| #define MIN_RATIO_1000 1250 |
| static unsigned int min_skip_ratio = MIN_RATIO_1000; |
| MODULE_PARM_DESC(min_skip_ratio, "min_skip_ratio"); |
| module_param(min_skip_ratio, uint, 0664); |
| static unsigned int max_proc_height = 2160; |
| MODULE_PARM_DESC(max_proc_height, "max_proc_height"); |
| module_param(max_proc_height, uint, 0664); |
| static unsigned int cur_proc_height; |
| MODULE_PARM_DESC(cur_proc_height, "cur_proc_height"); |
| module_param(cur_proc_height, uint, 0444); |
| static unsigned int cur_skip_ratio; |
| MODULE_PARM_DESC(cur_skip_ratio, "cur_skip_ratio"); |
| module_param(cur_skip_ratio, uint, 0444); |
| static unsigned int cur_vf_type; |
| MODULE_PARM_DESC(cur_vf_type, "cur_vf_type"); |
| module_param(cur_vf_type, uint, 0444); |
| static unsigned int cur_freq_ratio; |
| MODULE_PARM_DESC(cur_freq_ratio, "cur_freq_ratio"); |
| module_param(cur_freq_ratio, uint, 0444); |
| |
| static unsigned int custom_ar; |
| MODULE_PARM_DESC(custom_ar, "custom_ar"); |
| module_param(custom_ar, uint, 0664); |
| |
| static unsigned int force_use_ext_ar; |
| MODULE_PARM_DESC(force_use_ext_ar, "force_use_ext_ar"); |
| module_param(force_use_ext_ar, uint, 0664); |
| |
| static unsigned int force_no_compress; |
| MODULE_PARM_DESC(force_no_compress, "force_no_compress"); |
| module_param(force_no_compress, uint, 0664); |
| |
| static unsigned int hscaler_input_h_threshold = 60; |
| MODULE_PARM_DESC(hscaler_input_h_threshold, "hscaler_input_height_threshold"); |
| module_param(hscaler_input_h_threshold, uint, 0664); |
| |
| static unsigned int screen_ar_threshold = 3; |
| |
| /* |
| *test on txlx: |
| *Time_out = (V_out/V_screen_total)/FPS_out; |
| *if di bypas: |
| *Time_in = (H_in * V_in)/Clk_vpu; |
| *if di work; for di clk is less than vpu usually; |
| *Time_in = (H_in * V_in)/Clk_di; |
| *if Time_in < Time_out,need do vskip; |
| *but in effect,test result may have some error. |
| *ratio1:V_out test result may larger than calc result; |
| *--after test is large ratio is 1.09; |
| *--so wo should choose the largest ratio_v_out = 110/100; |
| *ratio2:use clk_di or clk_vpu; |
| *--txlx di clk is 250M or 500M; |
| *--before txlx di clk is 333M; |
| *So need adjust bypass_ratio; |
| */ |
| |
| static int vpp_process_speed_check( |
| u32 layer_id, |
| s32 width_in, |
| s32 height_in, |
| s32 height_out, |
| s32 height_screen, |
| u32 video_speed_check_width, |
| u32 video_speed_check_height, |
| struct vpp_frame_par_s *next_frame_par, |
| const struct vinfo_s *vinfo, struct vframe_s *vf, |
| u32 vpp_flags) |
| { |
| u32 cur_ratio, bpp = 1; |
| int min_ratio_1000 = 0; |
| int freq_ratio = 1; |
| u32 sync_duration_den = 1; |
| u32 vtotal, htotal = 0, clk_in_pps = 0, clk_vpu = 0, clk_temp; |
| u32 input_time_us = 0, display_time_us = 0, dummy_time_us = 0; |
| u32 width_out = 0; |
| u32 vpu_clk = 0, max_height = 2160; /* 4k mode */ |
| |
| if (!vf) |
| return SPEED_CHECK_DONE; |
| |
| /* store the debug info for legacy */ |
| if ((layer_id == 0) && (vpp_flags & VPP_FLAG_MORE_LOG)) |
| cur_vf_type = vf->type; |
| |
| if (force_vskip_cnt == 0xff)/*for debug*/ |
| return SPEED_CHECK_DONE; |
| |
| if (next_frame_par->vscale_skip_count < force_vskip_cnt) |
| return SPEED_CHECK_VSKIP; |
| |
| if (vinfo->sync_duration_den > 0) |
| sync_duration_den = vinfo->sync_duration_den; |
| |
| if (vf->type & VIDTYPE_PRE_INTERLACE) { |
| if (is_meson_txlx_cpu()) |
| clk_in_pps = 250000000; |
| else |
| clk_in_pps = 333000000; |
| } else { |
| clk_in_pps = get_vpu_clk(); |
| } |
| |
| next_frame_par->clk_in_pps = clk_in_pps; |
| vpu_clk = get_vpu_clk(); |
| /* the output is only up to 1080p */ |
| if (vpu_clk <= 250000000) { |
| /* ((3840 * 2160) / 1920) * (vpu_clk / 1000000) / 666 */ |
| max_height = 4320 * (vpu_clk / 1000000) / 666; |
| } |
| |
| if (max_proc_height < max_height) |
| max_height = max_proc_height; |
| |
| if ((layer_id == 0) && (vpp_flags & VPP_FLAG_MORE_LOG)) |
| cur_proc_height = max_height; |
| |
| if (width_in > 720) |
| min_ratio_1000 = min_skip_ratio; |
| else |
| min_ratio_1000 = 1750; |
| |
| if (vinfo->field_height < vinfo->height) |
| vtotal = vinfo->vtotal/2; |
| else |
| vtotal = vinfo->vtotal; |
| |
| /*according vlsi suggest, |
| *if di work need check mif input and vpu process speed |
| */ |
| if (vf->type & VIDTYPE_PRE_INTERLACE) { |
| htotal = vinfo->htotal; |
| clk_vpu = get_vpu_clk(); |
| clk_temp = clk_in_pps / 1000000; |
| if (clk_temp) |
| input_time_us = height_in * width_in / clk_temp; |
| clk_temp = clk_vpu / 1000000; |
| width_out = next_frame_par->VPP_hsc_endp - |
| next_frame_par->VPP_hsc_startp + 1; |
| if (clk_temp) |
| dummy_time_us = (vtotal * htotal - |
| height_out * width_out) / clk_temp; |
| display_time_us = 1000000 * sync_duration_den / |
| vinfo->sync_duration_num; |
| if (display_time_us > dummy_time_us) |
| display_time_us = display_time_us - dummy_time_us; |
| if (input_time_us > display_time_us) |
| return SPEED_CHECK_VSKIP; |
| } |
| |
| if ((vinfo->sync_duration_num / sync_duration_den) > 60) |
| freq_ratio = vinfo->sync_duration_num / |
| sync_duration_den / 60; |
| |
| if (freq_ratio < 1) |
| freq_ratio = 1; |
| |
| if ((layer_id == 0) && (vpp_flags & VPP_FLAG_MORE_LOG)) |
| cur_freq_ratio = freq_ratio; |
| |
| /* #if (MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8) */ |
| if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) && !is_meson_mtvd_cpu()) { |
| if ((width_in <= 0) || (height_in <= 0) || (height_out <= 0) |
| || (height_screen <= 0)) |
| return SPEED_CHECK_DONE; |
| |
| if ((next_frame_par->vscale_skip_count > 0) && |
| ((vf->type & VIDTYPE_VIU_444) || |
| (vf->type & VIDTYPE_RGB_444))) |
| bpp = 2; |
| if (height_in * bpp > height_out) { |
| /* |
| *don't need do skip for under 5% scaler down |
| *reason:for 1080p input,4k output, if di clk is 250M, |
| *the clac height is 1119;which is bigger than 1080! |
| */ |
| if (height_in > height_out && |
| ((height_in - height_out) < height_in/20)) |
| return SPEED_CHECK_DONE; |
| if (get_cpu_type() >= |
| MESON_CPU_MAJOR_ID_GXBB) { |
| cur_ratio = div_u64((u64)height_in * |
| (u64)vinfo->height * |
| 1000 * freq_ratio, |
| height_out * max_height); |
| /* di process first, need more a bit of ratio */ |
| if (vf->type & VIDTYPE_PRE_INTERLACE) |
| cur_ratio = (cur_ratio * 105) / 100; |
| if ((next_frame_par->vscale_skip_count > 0) && |
| ((vf->type & VIDTYPE_VIU_444) || |
| (vf->type & VIDTYPE_RGB_444))) |
| cur_ratio = cur_ratio * 2; |
| |
| /* store the debug info for legacy */ |
| if ((layer_id == 0) && |
| (vpp_flags & VPP_FLAG_MORE_LOG)) |
| cur_skip_ratio = cur_ratio; |
| |
| if ((cur_ratio > min_ratio_1000) && |
| (vf->source_type != |
| VFRAME_SOURCE_TYPE_TUNER) && |
| (vf->source_type != |
| VFRAME_SOURCE_TYPE_CVBS)) |
| return SPEED_CHECK_VSKIP; |
| } |
| if (vf->type & VIDTYPE_VIU_422) { |
| /*TODO vpu */ |
| if (height_out == 0 || |
| div_u64((u64)VPP_SPEED_FACTOR * |
| (u64)width_in * |
| (u64)height_in * |
| (u64)vinfo->sync_duration_num * |
| (u64)vtotal, |
| height_out * |
| sync_duration_den * |
| bypass_ratio) > clk_in_pps) |
| return SPEED_CHECK_VSKIP; |
| else |
| return SPEED_CHECK_DONE; |
| } else { |
| /*TODO vpu */ |
| if (height_out == 0 || |
| div_u64((u64)VPP_SPEED_FACTOR * |
| (u64)width_in * |
| (u64)height_in * |
| (u64)vinfo->sync_duration_num * |
| (u64)vtotal, |
| height_out * |
| sync_duration_den * 256) |
| > clk_in_pps) |
| return SPEED_CHECK_VSKIP; |
| /* 4K down scaling to non 4K > 30hz,*/ |
| /*skip lines for memory bandwidth */ |
| else if ((((vf->type & VIDTYPE_COMPRESS) |
| == 0) || (next_frame_par->nocomp)) |
| && (height_in > 2048) |
| && (height_out < 2048) |
| && (vinfo->sync_duration_num > |
| (30 * sync_duration_den)) |
| && (get_cpu_type() != |
| MESON_CPU_MAJOR_ID_GXTVBB) |
| && (get_cpu_type() != |
| MESON_CPU_MAJOR_ID_GXM)) |
| return SPEED_CHECK_VSKIP; |
| else |
| return SPEED_CHECK_DONE; |
| } |
| } else if (next_frame_par->hscale_skip_count == 0) { |
| /*TODO vpu */ |
| if (div_u64(VPP_SPEED_FACTOR * width_in * |
| vinfo->sync_duration_num * height_screen, |
| sync_duration_den * 256) |
| > get_vpu_clk()) |
| return SPEED_CHECK_HSKIP; |
| else |
| return SPEED_CHECK_DONE; |
| } |
| return SPEED_CHECK_DONE; |
| } |
| /* #else */ |
| /* return okay if vpp preblend enabled */ |
| |
| if ((READ_VCBUS_REG(VPP_MISC) & VPP_PREBLEND_EN) |
| && (READ_VCBUS_REG(VPP_MISC) & VPP_OSD1_PREBLEND)) |
| return SPEED_CHECK_DONE; |
| |
| /* #if (MESON_CPU_TYPE > MESON_CPU_TYPE_MESON6) */ |
| if (get_cpu_type() > MESON_CPU_MAJOR_ID_M6) { |
| if ((height_out + 1) > height_in) |
| return SPEED_CHECK_DONE; |
| } else { |
| /* #else */ |
| if (video_speed_check_width * video_speed_check_height * |
| height_out > height_screen * width_in * height_in) |
| return SPEED_CHECK_DONE; |
| } |
| /* #endif */ |
| amlog_mask(LOG_MASK_VPP, "vpp_process_speed_check failed\n"); |
| return SPEED_CHECK_VSKIP; |
| } |
| |
| static void horz_coef_print(u32 layer_id, struct vppfilter_mode_s *filter) |
| { |
| int i; |
| int bit9_mode = filter->vpp_horz_coeff[1] & 0x8000; |
| |
| if (bit9_mode) { |
| if (hscaler_8tap_enable[layer_id]) { |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 8tap 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2]); |
| } |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 8tap 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2 + 33]); |
| } |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 8tap 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2 + 33 * 2]); |
| } |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 8tap 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2 + 33 * 3]); |
| } |
| } else { |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2]); |
| } |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2 + 33]); |
| } |
| } |
| } else { |
| if (hscaler_8tap_enable[layer_id]) { |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 8tap coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2]); |
| } |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz 8tap coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2 + 33]); |
| } |
| } else { |
| for (i = 0; i < (filter->vpp_horz_coeff[1] |
| & 0xff); i++) { |
| pr_info("horz coef[%d] = %x\n", |
| i, |
| filter->vpp_horz_coeff[i + 2]); |
| } |
| } |
| } |
| } |
| |
| static void vert_coef_print(u32 layer_id, struct vppfilter_mode_s *filter) |
| { |
| int i; |
| int bit9_mode = filter->vpp_vert_coeff[1] & 0x8000; |
| |
| if (bit9_mode) { |
| for (i = 0; i < (filter->vpp_vert_coeff[1] & 0xff); i++) { |
| pr_info("vert 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_vert_coeff[i + 2]); |
| } |
| for (i = 0; i < (filter->vpp_vert_coeff[1] & 0xff); i++) { |
| pr_info("vert 9bit coef[%d] = %x\n", |
| i, |
| filter->vpp_vert_coeff[i + 2 + 33]); |
| } |
| } else { |
| for (i = 0; i < (filter->vpp_vert_coeff[1] & 0xff); i++) { |
| pr_info("vert coef[%d] = %x\n", |
| i, |
| filter->vpp_vert_coeff[i + 2]); |
| } |
| } |
| } |
| |
| static int vpp_set_filters_internal( |
| struct disp_info_s *input, |
| u32 width_in, |
| u32 height_in, |
| u32 wid_out, |
| u32 hei_out, |
| const struct vinfo_s *vinfo, |
| u32 vpp_flags, |
| struct vpp_frame_par_s *next_frame_par, struct vframe_s *vf) |
| { |
| u32 screen_width = 0, screen_height = 0; |
| s32 start, end; |
| s32 video_top, video_left, temp; |
| u32 video_width, video_height; |
| u32 ratio_x = 0; |
| u32 ratio_y = 0; |
| u32 tmp_ratio_y = 0; |
| int temp_width; |
| int temp_height; |
| struct vppfilter_mode_s *filter = &next_frame_par->vpp_filter; |
| u32 wide_mode; |
| s32 height_shift = 0; |
| u32 height_after_ratio = 0; |
| u32 aspect_factor; |
| s32 ini_vphase; |
| u32 w_in = width_in; |
| u32 h_in = height_in; |
| bool h_crop_enable = false, v_crop_enable = false; |
| u32 width_out = wid_out; /* vinfo->width; */ |
| u32 height_out = hei_out; /* vinfo->height; */ |
| u32 aspect_ratio_out = |
| (vinfo->aspect_ratio_den << 10) / vinfo->aspect_ratio_num; |
| bool fill_match = true; |
| u32 orig_aspect = 0; |
| u32 screen_aspect = 0; |
| bool skip_policy_check = true; |
| u32 vskip_step; |
| s32 video_layer_global_offset_x, video_layer_global_offset_y; |
| u32 video_source_crop_top, video_source_crop_left; |
| u32 video_source_crop_bottom, video_source_crop_right; |
| u32 vpp_zoom_ratio, nonlinear_factor, nonlinear_t_factor; |
| u32 speed_check_width, speed_check_height; |
| s32 video_layer_top, video_layer_left; |
| s32 video_layer_width, video_layer_height; |
| u32 cur_custom_ar; |
| #ifdef TV_REVERSE |
| bool reverse = false; |
| #endif |
| int ret = vppfilter_success; |
| u32 vert_chroma_filter; |
| struct filter_info_s *cur_filter; |
| s32 vpp_zoom_center_x, vpp_zoom_center_y; |
| u32 crop_ratio = 1; |
| u32 crop_left, crop_right, crop_top, crop_bottom; |
| u32 sar_width = 0, sar_height = 0; |
| bool ext_sar = false; |
| bool no_compress = false; |
| u32 min_aspect_ratio_out, max_aspect_ratio_out; |
| int is_larger_4k50hz = 0; |
| u32 cur_super_debug = 0; |
| |
| if (!input) |
| return vppfilter_fail; |
| |
| if (vpp_flags & VPP_FLAG_MORE_LOG) |
| cur_super_debug = super_debug; |
| |
| /* min = 0.95 x 1024 * height / width */ |
| min_aspect_ratio_out = |
| ((100 - screen_ar_threshold) << 10) / 100; |
| min_aspect_ratio_out = |
| (vinfo->height * min_aspect_ratio_out) / vinfo->width; |
| /* max = 1.05 x 1024 * height / width */ |
| max_aspect_ratio_out = |
| ((100 + screen_ar_threshold) << 10) / 100; |
| max_aspect_ratio_out = |
| (vinfo->height * max_aspect_ratio_out) / vinfo->width; |
| |
| if ((aspect_ratio_out <= max_aspect_ratio_out) |
| && (aspect_ratio_out >= min_aspect_ratio_out)) |
| aspect_ratio_out = (vinfo->height << 10) / vinfo->width; |
| |
| cur_filter = &gfilter[input->layer_id]; |
| cur_custom_ar = input->custom_ar; |
| vpp_zoom_ratio = input->zoom_ratio; |
| vpp_zoom_center_x = input->zoom_center_x; |
| vpp_zoom_center_y = input->zoom_center_y; |
| speed_check_width = input->speed_check_width; |
| speed_check_height = input->speed_check_height; |
| nonlinear_factor = input->nonlinear_factor; |
| nonlinear_t_factor = input->nonlinear_t_factor; |
| video_layer_global_offset_x = input->global_offset_x; |
| video_layer_global_offset_y = input->global_offset_y; |
| |
| video_layer_top = input->layer_top; |
| video_layer_left = input->layer_left; |
| video_layer_width = input->layer_width; |
| video_layer_height = input->layer_height; |
| #ifdef TV_REVERSE |
| reverse = input->reverse; |
| #endif |
| |
| if ((vf->type & VIDTYPE_MVC) || |
| (input->proc_3d_type & MODE_3D_ENABLE)) { |
| video_source_crop_left = 0; |
| video_source_crop_right = 0; |
| video_source_crop_top = 0; |
| video_source_crop_bottom = 0; |
| } else { |
| video_source_crop_left = input->crop_left; |
| video_source_crop_right = input->crop_right; |
| video_source_crop_top = input->crop_top; |
| video_source_crop_bottom = input->crop_bottom; |
| } |
| |
| #ifndef TV_3D_FUNCTION_OPEN |
| next_frame_par->vscale_skip_count = 0; |
| next_frame_par->hscale_skip_count = 0; |
| #endif |
| next_frame_par->nocomp = false; |
| if (vpp_flags & VPP_FLAG_INTERLACE_IN) |
| next_frame_par->vscale_skip_count++; |
| if (vpp_flags & VPP_FLAG_INTERLACE_OUT) |
| height_shift++; |
| |
| if (vpp_flags & VPP_FLAG_INTERLACE_IN) |
| vskip_step = 2; |
| #ifdef TV_3D_FUNCTION_OPEN |
| else if ((next_frame_par->vpp_3d_mode |
| == VPP_3D_MODE_LA) |
| && (input->proc_3d_type & MODE_3D_ENABLE)) |
| vskip_step = 2; |
| #endif |
| else |
| vskip_step = 1; |
| |
| if (cur_super_debug) |
| pr_info("sar_width=%d, sar_height = %d, %d\n", |
| vf->sar_width, vf->sar_height, |
| force_use_ext_ar); |
| |
| RESTART_ALL: |
| crop_left = video_source_crop_left / crop_ratio; |
| crop_right = video_source_crop_right / crop_ratio; |
| crop_top = video_source_crop_top / crop_ratio; |
| crop_bottom = video_source_crop_bottom / crop_ratio; |
| |
| if (likely(w_in > |
| (crop_left + crop_right))) { |
| w_in -= crop_left; |
| w_in -= crop_right; |
| h_crop_enable = true; |
| } |
| |
| if (likely(h_in > |
| (crop_top + crop_bottom))) { |
| h_in -= crop_top; |
| h_in -= crop_bottom; |
| v_crop_enable = true; |
| } |
| |
| RESTART: |
| aspect_factor = (vpp_flags & VPP_FLAG_AR_MASK) >> VPP_FLAG_AR_BITS; |
| /* don't use input->wide_mode */ |
| wide_mode = (vpp_flags & VPP_FLAG_WIDEMODE_MASK) >> VPP_WIDEMODE_BITS; |
| |
| if ((vpp_flags & VPP_FLAG_AR_MASK) == VPP_FLAG_AR_MASK) { |
| ext_sar = true; |
| sar_width = vf->sar_width; |
| sar_height = vf->sar_height; |
| } else if (force_use_ext_ar) { |
| ext_sar = true; |
| sar_width = 1; |
| sar_height = 1; |
| } |
| |
| if (ext_sar && sar_width && sar_height && width_in) { |
| aspect_factor = |
| div_u64((u64)256ULL * |
| (u64)sar_height * |
| (u64)height_in, |
| (u32)(sar_width * width_in)); |
| } else { |
| ext_sar = false; |
| } |
| |
| /* speical mode did not use ext sar mode */ |
| if (wide_mode == VIDEO_WIDEOPTION_NONLINEAR || |
| wide_mode == VIDEO_WIDEOPTION_NORMAL_NOSCALEUP || |
| wide_mode == VIDEO_WIDEOPTION_NONLINEAR_T) |
| ext_sar = false; |
| |
| /* keep 8 bits resolution for aspect conversion */ |
| if (wide_mode == VIDEO_WIDEOPTION_4_3) { |
| if (vpp_flags & VPP_FLAG_PORTRAIT_MODE) |
| aspect_factor = 0x155; |
| else |
| aspect_factor = 0xc0; |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| ext_sar = false; |
| } else if (wide_mode == VIDEO_WIDEOPTION_16_9) { |
| if (vpp_flags & VPP_FLAG_PORTRAIT_MODE) |
| aspect_factor = 0x1c7; |
| else |
| aspect_factor = 0x90; |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| ext_sar = false; |
| } else if ((wide_mode >= VIDEO_WIDEOPTION_4_3_IGNORE) |
| && (wide_mode <= VIDEO_WIDEOPTION_4_3_COMBINED)) { |
| if (aspect_factor != 0xc0) |
| fill_match = false; |
| |
| orig_aspect = aspect_factor; |
| screen_aspect = 0xc0; |
| ext_sar = false; |
| } else if ((wide_mode >= VIDEO_WIDEOPTION_16_9_IGNORE) |
| && (wide_mode <= VIDEO_WIDEOPTION_16_9_COMBINED)) { |
| if (aspect_factor != 0x90) |
| fill_match = false; |
| |
| orig_aspect = aspect_factor; |
| screen_aspect = 0x90; |
| ext_sar = false; |
| } else if (wide_mode == VIDEO_WIDEOPTION_CUSTOM) { |
| if (cur_super_debug) |
| pr_info("layer%d: wide_mode=%d, aspect_factor=%d, cur_custom_ar=%d\n", |
| input->layer_id, wide_mode, |
| aspect_factor, cur_custom_ar); |
| if (cur_custom_ar != 0) { |
| aspect_factor = cur_custom_ar & 0x3ff; |
| ext_sar = false; |
| } |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| } else if (wide_mode == VIDEO_WIDEOPTION_AFD) { |
| if (aspect_factor == 0x90) { |
| wide_mode = VIDEO_WIDEOPTION_FULL_STRETCH; |
| ext_sar = false; |
| } else |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| } |
| /* if use the mode ar, will disable ext ar */ |
| |
| if (cur_super_debug) |
| pr_info("aspect_factor=%d,%d,%d,%d,%d,%d\n", |
| aspect_factor, w_in, height_out, |
| width_out, h_in, aspect_ratio_out >> 2); |
| |
| if ((aspect_factor == 0) || |
| wide_mode == VIDEO_WIDEOPTION_FULL_STRETCH || |
| wide_mode == VIDEO_WIDEOPTION_NONLINEAR || |
| wide_mode == VIDEO_WIDEOPTION_NONLINEAR_T) { |
| aspect_factor = 0x100; |
| height_after_ratio = h_in; |
| } else if (ext_sar) { |
| /* avoid the bit length overflow */ |
| u64 tmp = (u64)((u64)(width_out * width_in) * aspect_ratio_out); |
| |
| tmp = tmp >> 2; |
| if (tmp != 0) |
| height_after_ratio = |
| div_u64((u64)256ULL * |
| (u64)w_in * |
| (u64)height_out * |
| (u64)sar_height * |
| (u64)height_in, |
| (u32)tmp); |
| height_after_ratio /= sar_width; |
| aspect_factor = (height_after_ratio << 8) / h_in; |
| if (cur_super_debug) |
| pr_info("ext_sar: aspect_factor=%d, %d,%d,%d,%d,%d\n", |
| aspect_factor, w_in, h_in, |
| height_after_ratio, |
| sar_width, sar_height); |
| } else { |
| /* avoid the bit length overflow */ |
| u64 tmp = (u64)((u64)(width_out * h_in) * aspect_ratio_out); |
| |
| tmp = tmp >> 2; |
| if (tmp != 0) |
| aspect_factor = |
| div_u64((unsigned long long)w_in * height_out * |
| (aspect_factor << 8), |
| (u32)tmp); |
| height_after_ratio = (h_in * aspect_factor) >> 8; |
| } |
| |
| /* |
| *if we have ever set a cropped display area for video layer |
| * (by checking video_layer_width/video_height), then |
| * it will override the input width_out/height_out for |
| * ratio calculations, a.k.a we have a window for video content |
| */ |
| video_top = video_layer_top; |
| video_left = video_layer_left; |
| video_width = video_layer_width; |
| video_height = video_layer_height; |
| if ((video_top == 0) && (video_left == 0) && (video_width <= 1) |
| && (video_height <= 1)) { |
| /* special case to do full screen display */ |
| video_width = width_out; |
| video_height = height_out; |
| } else { |
| if ((video_layer_width < 16) |
| && (video_layer_height < 16)) { |
| /* |
| *sanity check to move |
| *video out when the target size is too small |
| */ |
| video_width = width_out; |
| video_height = height_out; |
| video_left = width_out * 2; |
| } |
| video_top += video_layer_global_offset_y; |
| video_left += video_layer_global_offset_x; |
| } |
| |
| /*aspect ratio match */ |
| if ((wide_mode >= VIDEO_WIDEOPTION_4_3_IGNORE) |
| && (wide_mode <= VIDEO_WIDEOPTION_16_9_COMBINED) |
| && orig_aspect) { |
| if (vinfo->width && vinfo->height) |
| aspect_ratio_out = (vinfo->height << 10) / vinfo->width; |
| |
| if ((video_height << 10) > (video_width * aspect_ratio_out)) { |
| u32 real_video_height = |
| (video_width * aspect_ratio_out) >> 10; |
| |
| video_top += (video_height - real_video_height) >> 1; |
| video_height = real_video_height; |
| } else { |
| u32 real_video_width = |
| (video_height << 10) / aspect_ratio_out; |
| |
| video_left += (video_width - real_video_width) >> 1; |
| video_width = real_video_width; |
| } |
| |
| if (!fill_match) { |
| u32 screen_ratio_x, screen_ratio_y; |
| |
| screen_ratio_x = 1 << 18; |
| screen_ratio_y = (orig_aspect << 18) / screen_aspect; |
| |
| switch (wide_mode) { |
| case VIDEO_WIDEOPTION_4_3_LETTER_BOX: |
| case VIDEO_WIDEOPTION_16_9_LETTER_BOX: |
| screen_ratio_x = screen_ratio_y = |
| max(screen_ratio_x, screen_ratio_y); |
| break; |
| case VIDEO_WIDEOPTION_4_3_PAN_SCAN: |
| case VIDEO_WIDEOPTION_16_9_PAN_SCAN: |
| screen_ratio_x = screen_ratio_y = |
| min(screen_ratio_x, screen_ratio_y); |
| break; |
| case VIDEO_WIDEOPTION_4_3_COMBINED: |
| case VIDEO_WIDEOPTION_16_9_COMBINED: |
| screen_ratio_x = screen_ratio_y = |
| ((screen_ratio_x + screen_ratio_y) >> 1); |
| break; |
| default: |
| break; |
| } |
| |
| ratio_x = screen_ratio_x * w_in / video_width; |
| ratio_y = screen_ratio_y * h_in / orig_aspect * |
| screen_aspect / video_height; |
| } else { |
| screen_width = video_width * vpp_zoom_ratio / 100; |
| screen_height = video_height * vpp_zoom_ratio / 100; |
| |
| ratio_x = (w_in << 18) / screen_width; |
| ratio_y = (h_in << 18) / screen_height; |
| } |
| } else { |
| screen_width = video_width * vpp_zoom_ratio / 100; |
| screen_height = video_height * vpp_zoom_ratio / 100; |
| |
| ratio_x = (w_in << 18) / screen_width; |
| if (ratio_x * screen_width < (w_in << 18)) |
| ratio_x++; |
| |
| ratio_y = (height_after_ratio << 18) / screen_height; |
| if (cur_super_debug) |
| pr_info("layer%d: height_after_ratio=%d,%d,%d,%d,%d\n", |
| input->layer_id, |
| height_after_ratio, ratio_x, ratio_y, |
| aspect_factor, wide_mode); |
| |
| if (wide_mode == VIDEO_WIDEOPTION_NORMAL) { |
| ratio_x = ratio_y = max(ratio_x, ratio_y); |
| if (ext_sar) |
| ratio_y = (ratio_y * h_in) / height_after_ratio; |
| else |
| ratio_y = (ratio_y << 8) / aspect_factor; |
| } else if (wide_mode == VIDEO_WIDEOPTION_NORMAL_NOSCALEUP) { |
| u32 r1, r2; |
| |
| r1 = max(ratio_x, ratio_y); |
| r2 = (r1 << 8) / aspect_factor; |
| |
| if ((r1 < (1 << 18)) || (r2 < (1 << 18))) { |
| if (r1 < r2) { |
| ratio_x = 1 << 18; |
| ratio_y = |
| (ratio_x << 8) / aspect_factor; |
| } else { |
| ratio_y = 1 << 18; |
| ratio_x = aspect_factor << 10; |
| } |
| } else { |
| ratio_x = r1; |
| ratio_y = r2; |
| } |
| } |
| } |
| |
| #if 0 |
| debug_video_left = video_left; |
| debug_video_top = video_top; |
| debug_video_width = video_width; |
| debug_video_height = video_height; |
| debug_ratio_x = ratio_x; |
| debug_ratio_y = ratio_y; |
| debug_wide_mode = wide_mode; |
| #endif |
| |
| /* vertical */ |
| ini_vphase = vpp_zoom_center_y & 0xff; |
| |
| /* screen position for source */ |
| start = video_top + (video_height + 1) / 2 - |
| ((h_in << 17) + |
| (vpp_zoom_center_y << 10) + |
| (ratio_y >> 1)) / ratio_y; |
| end = ((h_in << 18) + (ratio_y >> 1)) / ratio_y + start - 1; |
| if (cur_super_debug) |
| pr_info("layer%d: top:start =%d,%d,%d,%d %d,%d,%d\n", |
| input->layer_id, |
| start, end, video_top, |
| video_height, h_in, ratio_y, vpp_zoom_center_y); |
| |
| #ifdef TV_REVERSE |
| if (reverse) { |
| /* calculate source vertical clip */ |
| if (video_top < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_y) >> 18; |
| next_frame_par->VPP_vd_end_lines_ = |
| h_in - 1 - temp; |
| } else |
| next_frame_par->VPP_vd_end_lines_ = h_in - 1; |
| } else { |
| if (start < video_top) { |
| temp = ((video_top - start) * ratio_y) >> 18; |
| next_frame_par->VPP_vd_end_lines_ = |
| h_in - 1 - temp; |
| } else |
| next_frame_par->VPP_vd_end_lines_ = h_in - 1; |
| } |
| temp = next_frame_par->VPP_vd_end_lines_ - |
| (video_height * ratio_y >> 18); |
| next_frame_par->VPP_vd_start_lines_ = (temp >= 0) ? temp : 0; |
| } else |
| #endif |
| { |
| if (video_top < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_y) >> 18; |
| next_frame_par->VPP_vd_start_lines_ = temp; |
| } else |
| next_frame_par->VPP_vd_start_lines_ = 0; |
| temp_height = min((video_top + video_height - 1), |
| (vinfo->height - 1)); |
| } else { |
| if (start < video_top) { |
| temp = ((video_top - start) * ratio_y) >> 18; |
| next_frame_par->VPP_vd_start_lines_ = temp; |
| } else |
| next_frame_par->VPP_vd_start_lines_ = 0; |
| temp_height = min((video_top + video_height - 1), |
| (vinfo->height - 1)) - video_top + 1; |
| } |
| temp = next_frame_par->VPP_vd_start_lines_ + |
| (temp_height * ratio_y >> 18); |
| next_frame_par->VPP_vd_end_lines_ = |
| (temp <= (h_in - 1)) ? temp : (h_in - 1); |
| } |
| |
| if (v_crop_enable) { |
| next_frame_par->VPP_vd_start_lines_ += crop_top; |
| next_frame_par->VPP_vd_end_lines_ += crop_top; |
| } |
| |
| if (vpp_flags & VPP_FLAG_INTERLACE_IN) |
| next_frame_par->VPP_vd_start_lines_ &= ~1; |
| |
| next_frame_par->VPP_pic_in_height_ = |
| next_frame_par->VPP_vd_end_lines_ - |
| next_frame_par->VPP_vd_start_lines_ + 1; |
| next_frame_par->VPP_pic_in_height_ = |
| next_frame_par->VPP_pic_in_height_ / |
| (next_frame_par->vscale_skip_count + 1); |
| |
| /* DI POST link, need make pps input size is even */ |
| if ((next_frame_par->VPP_pic_in_height_ & 1) && |
| (vf->type & VIDTYPE_PRE_INTERLACE) && |
| !(vf->type & VIDTYPE_DI_PW)) { |
| next_frame_par->VPP_pic_in_height_ &= ~1; |
| next_frame_par->VPP_vd_end_lines_ = |
| next_frame_par->VPP_pic_in_height_ * |
| (next_frame_par->vscale_skip_count + 1) + |
| next_frame_par->VPP_vd_start_lines_; |
| if (next_frame_par->VPP_vd_end_lines_ > 0) |
| next_frame_par->VPP_vd_end_lines_--; |
| } |
| /* |
| *find overlapped region between |
| *[start, end], [0, height_out-1], |
| *[video_top, video_top+video_height-1] |
| */ |
| start = max(start, max(0, video_top)); |
| end = min(end, min((s32)(vinfo->height - 1), |
| (s32)(video_top + video_height - 1))); |
| |
| if (start >= end) { |
| /* nothing to display */ |
| next_frame_par->VPP_vsc_startp = 0; |
| next_frame_par->VPP_vsc_endp = 0; |
| } else { |
| next_frame_par->VPP_vsc_startp = |
| (vpp_flags & VPP_FLAG_INTERLACE_OUT) ? |
| (start >> 1) : start; |
| next_frame_par->VPP_vsc_endp = |
| (vpp_flags & VPP_FLAG_INTERLACE_OUT) ? |
| (end >> 1) : end; |
| } |
| |
| /* set filter co-efficients */ |
| tmp_ratio_y = ratio_y; |
| ratio_y <<= height_shift; |
| ratio_y = ratio_y / (next_frame_par->vscale_skip_count + 1); |
| |
| filter->vpp_vsc_start_phase_step = ratio_y << 6; |
| |
| f2v_get_vertical_phase(ratio_y, ini_vphase, |
| next_frame_par->VPP_vf_ini_phase_, |
| vpp_flags & VPP_FLAG_INTERLACE_OUT); |
| |
| /* horizontal */ |
| filter->vpp_hf_start_phase_slope = 0; |
| filter->vpp_hf_end_phase_slope = 0; |
| filter->vpp_hf_start_phase_step = ratio_x << 6; |
| |
| next_frame_par->VPP_hsc_linear_startp = next_frame_par->VPP_hsc_startp; |
| next_frame_par->VPP_hsc_linear_endp = next_frame_par->VPP_hsc_endp; |
| |
| filter->vpp_hsc_start_phase_step = ratio_x << 6; |
| next_frame_par->VPP_hf_ini_phase_ = vpp_zoom_center_x & 0xff; |
| |
| /* screen position for source */ |
| start = video_left + (video_width + 1) / 2 - ((w_in << 17) + |
| (vpp_zoom_center_x << 10) + |
| (ratio_x >> 1)) / ratio_x; |
| end = ((w_in << 18) + (ratio_x >> 1)) / ratio_x + start - 1; |
| if (cur_super_debug) |
| pr_info("layer%d: left:start =%d,%d,%d,%d %d,%d,%d\n", |
| input->layer_id, |
| start, end, video_left, |
| video_width, w_in, ratio_x, vpp_zoom_center_x); |
| |
| /* calculate source horizontal clip */ |
| #ifdef TV_REVERSE |
| if (reverse) { |
| if (video_left < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_x) >> 18; |
| next_frame_par->VPP_hd_end_lines_ = |
| w_in - 1 - temp; |
| } else |
| next_frame_par->VPP_hd_end_lines_ = w_in - 1; |
| } else { |
| if (start < video_left) { |
| temp = ((video_left - start) * ratio_x) >> 18; |
| next_frame_par->VPP_hd_end_lines_ = |
| w_in - 1 - temp; |
| } else |
| next_frame_par->VPP_hd_end_lines_ = w_in - 1; |
| } |
| temp = next_frame_par->VPP_hd_end_lines_ - |
| (video_width * ratio_x >> 18); |
| next_frame_par->VPP_hd_start_lines_ = (temp >= 0) ? temp : 0; |
| } else |
| #endif |
| { |
| if (video_left < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_x) >> 18; |
| next_frame_par->VPP_hd_start_lines_ = temp; |
| |
| } else |
| next_frame_par->VPP_hd_start_lines_ = 0; |
| temp_width = min((video_left + video_width - 1), |
| (vinfo->width - 1)); |
| } else { |
| if (start < video_left) { |
| temp = ((video_left - start) * ratio_x) >> 18; |
| next_frame_par->VPP_hd_start_lines_ = temp; |
| |
| } else |
| next_frame_par->VPP_hd_start_lines_ = 0; |
| temp_width = min((video_left + video_width - 1), |
| (vinfo->width - 1)) - video_left + 1; |
| } |
| temp = next_frame_par->VPP_hd_start_lines_ + |
| (temp_width * ratio_x >> 18); |
| next_frame_par->VPP_hd_end_lines_ = |
| (temp <= (w_in - 1)) ? temp : (w_in - 1); |
| } |
| |
| if (h_crop_enable) { |
| next_frame_par->VPP_hd_start_lines_ += crop_left; |
| next_frame_par->VPP_hd_end_lines_ += crop_left; |
| } |
| |
| next_frame_par->VPP_line_in_length_ = |
| next_frame_par->VPP_hd_end_lines_ - |
| next_frame_par->VPP_hd_start_lines_ + 1; |
| /* |
| *find overlapped region between |
| * [start, end], [0, width_out-1], |
| * [video_left, video_left+video_width-1] |
| */ |
| start = max(start, max(0, video_left)); |
| end = min(end, |
| min((s32)(vinfo->width - 1), |
| (s32)(video_left + video_width - 1))); |
| |
| if (start >= end) { |
| /* nothing to display */ |
| next_frame_par->VPP_hsc_startp = 0; |
| next_frame_par->VPP_hsc_endp = 0; |
| /* avoid mif set wrong or di out size overflow */ |
| next_frame_par->VPP_hd_start_lines_ = 0; |
| next_frame_par->VPP_hd_end_lines_ = 0; |
| next_frame_par->VPP_line_in_length_ = 0; |
| } else { |
| next_frame_par->VPP_hsc_startp = start; |
| |
| next_frame_par->VPP_hsc_endp = end; |
| } |
| |
| if ((wide_mode == VIDEO_WIDEOPTION_NONLINEAR) && (end > start)) { |
| calculate_non_linear_ratio_V( |
| nonlinear_factor, |
| ratio_x, end - start, |
| next_frame_par); |
| next_frame_par->VPP_hsc_linear_startp = |
| next_frame_par->VPP_hsc_linear_endp = (start + end) / 2; |
| } |
| if (wide_mode == VIDEO_WIDEOPTION_NONLINEAR_T && |
| end > start) { |
| calculate_non_linear_ratio_T(nonlinear_t_factor, |
| w_in, end - start + 1, |
| next_frame_par); |
| } |
| |
| /* |
| *check the painful bandwidth limitation and see |
| * if we need skip half resolution on source side for progressive |
| * frames. |
| */ |
| /* check vskip and hskip */ |
| if (((next_frame_par->vscale_skip_count < MAX_VSKIP_COUNT) |
| || !next_frame_par->hscale_skip_count) |
| && (!(vpp_flags & VPP_FLAG_VSCALE_DISABLE))) { |
| int skip = vpp_process_speed_check( |
| input->layer_id, |
| (next_frame_par->VPP_hd_end_lines_ - |
| next_frame_par->VPP_hd_start_lines_ + 1) / |
| (next_frame_par->hscale_skip_count + 1), |
| (next_frame_par->VPP_vd_end_lines_ - |
| next_frame_par->VPP_vd_start_lines_ + 1) / |
| (next_frame_par->vscale_skip_count + 1), |
| (next_frame_par->VPP_vsc_endp - |
| next_frame_par->VPP_vsc_startp + 1), |
| vinfo->height >> |
| ((vpp_flags & VPP_FLAG_INTERLACE_OUT) ? 1 : 0), |
| speed_check_width, |
| speed_check_height, |
| next_frame_par, |
| vinfo, vf, vpp_flags); |
| |
| if (skip == SPEED_CHECK_VSKIP) { |
| u32 next_vskip = |
| next_frame_par->vscale_skip_count + vskip_step; |
| |
| if (next_vskip <= MAX_VSKIP_COUNT) { |
| next_frame_par->vscale_skip_count = next_vskip; |
| goto RESTART; |
| } else |
| next_frame_par->hscale_skip_count = 1; |
| } else if (skip == SPEED_CHECK_HSKIP) |
| next_frame_par->hscale_skip_count = 1; |
| } |
| |
| if ((vf->type & VIDTYPE_COMPRESS) && |
| !(vf->type & VIDTYPE_NO_DW) && |
| (vf->canvas0Addr != 0) && |
| (!next_frame_par->nocomp)) { |
| if ((vpp_flags & VPP_FLAG_FORCE_NO_COMPRESS) |
| || (next_frame_par->vscale_skip_count > 1) |
| || !input->afbc_support |
| || force_no_compress) |
| no_compress = true; |
| } else |
| no_compress = false; |
| |
| if (no_compress) { |
| if ((vpp_flags & VPP_FLAG_MORE_LOG) |
| && input->afbc_support) |
| pr_info( |
| "layer%d: Try DW buffer for compressed frame scaling.\n", |
| input->layer_id); |
| |
| /* for VIDTYPE_COMPRESS, check if we can use double write |
| * buffer when primary frame can not be scaled. |
| */ |
| next_frame_par->nocomp = true; |
| w_in = width_in = vf->width; |
| h_in = height_in = vf->height; |
| next_frame_par->hscale_skip_count = 0; |
| next_frame_par->vscale_skip_count = 0; |
| if (vf->width && vf->compWidth) |
| crop_ratio = vf->compWidth / vf->width; |
| goto RESTART_ALL; |
| } |
| |
| if ((skip_policy & 0xf0) && (skip_policy_check == true)) { |
| skip_policy_check = false; |
| if (skip_policy & 0x40) { |
| next_frame_par->vscale_skip_count = skip_policy & 0xf; |
| goto RESTART; |
| } else if (skip_policy & 0x80) { |
| if ((((vf->width >= 4096) && |
| (!(vf->type & VIDTYPE_COMPRESS))) || |
| (vf->flag & VFRAME_FLAG_HIGH_BANDWIDTH)) |
| && (next_frame_par->vscale_skip_count == 0)) { |
| next_frame_par->vscale_skip_count = |
| skip_policy & 0xf; |
| goto RESTART; |
| } |
| } |
| } |
| |
| next_frame_par->video_input_h = next_frame_par->VPP_vd_end_lines_ - |
| next_frame_par->VPP_vd_start_lines_ + 1; |
| next_frame_par->video_input_h = next_frame_par->video_input_h / |
| (next_frame_par->vscale_skip_count + 1); |
| next_frame_par->video_input_w = next_frame_par->VPP_hd_end_lines_ - |
| next_frame_par->VPP_hd_start_lines_ + 1; |
| next_frame_par->video_input_w = next_frame_par->video_input_w / |
| (next_frame_par->hscale_skip_count + 1); |
| |
| filter->vpp_hsc_start_phase_step = ratio_x << 6; |
| |
| /* coeff selection before skip and apply pre_scaler */ |
| filter->vpp_vert_filter = |
| coeff(vert_coeff_settings, |
| filter->vpp_vsc_start_phase_step * |
| (next_frame_par->vscale_skip_count + 1), |
| 1, |
| ((vf->type_original & VIDTYPE_TYPEMASK) |
| != VIDTYPE_PROGRESSIVE), |
| vf->combing_cur_lev); |
| |
| filter->vpp_vert_coeff = |
| filter_table[filter->vpp_vert_filter]; |
| |
| /* when local interlace or AV or ATV */ |
| /* TODO: add 420 check for local */ |
| if (vert_chroma_filter_force_en || (vert_chroma_filter_en |
| && (((vf->source_type == VFRAME_SOURCE_TYPE_OTHERS) |
| && (((vf->type_original & VIDTYPE_TYPEMASK) |
| != VIDTYPE_PROGRESSIVE) |
| || (vf->height < vert_chroma_filter_limit))) |
| || (vf->source_type == VFRAME_SOURCE_TYPE_CVBS) |
| || (vf->source_type == VFRAME_SOURCE_TYPE_TUNER)))) { |
| vert_chroma_filter = |
| chroma_filter_table[filter->vpp_vert_filter]; |
| filter->vpp_vert_chroma_coeff = |
| filter_table[vert_chroma_filter]; |
| filter->vpp_vert_chroma_filter_en = true; |
| } else { |
| vert_chroma_filter = COEF_NULL; |
| filter->vpp_vert_chroma_filter_en = false; |
| } |
| |
| /* avoid hscaler fitler adjustion affect on picture shift*/ |
| if (hscaler_8tap_enable[input->layer_id]) |
| filter->vpp_horz_filter = |
| coeff_sc2(hert_coeff_settings_sc2, |
| filter->vpp_hf_start_phase_step); |
| else |
| filter->vpp_horz_filter = |
| coeff(horz_coeff_settings, |
| filter->vpp_hf_start_phase_step, |
| next_frame_par->VPP_hf_ini_phase_, |
| ((vf->type_original & VIDTYPE_TYPEMASK) |
| != VIDTYPE_PROGRESSIVE), |
| vf->combing_cur_lev); |
| /*for gxl cvbs out index*/ |
| if ((vinfo->mode == VMODE_CVBS) && //DEBUG_TMP |
| (filter->vpp_hf_start_phase_step == (1 << 24))) { |
| if (hscaler_8tap_enable[input->layer_id]) |
| filter->vpp_horz_filter = |
| COEF_BICUBIC_8TAP; |
| else |
| filter->vpp_horz_filter = |
| COEF_BICUBIC_SHARP; |
| } |
| if (hscaler_8tap_enable[input->layer_id]) { |
| /* hscaler 8 tap */ |
| filter->vpp_horz_coeff = |
| hscaler_8tap_filter_table |
| [filter->vpp_horz_filter]; |
| } else { |
| filter->vpp_horz_coeff = |
| filter_table[filter->vpp_horz_filter]; |
| } |
| |
| /* apply line skip */ |
| if (next_frame_par->hscale_skip_count) { |
| filter->vpp_hf_start_phase_step >>= 1; |
| filter->vpp_hsc_start_phase_step >>= 1; |
| next_frame_par->VPP_line_in_length_ >>= 1; |
| } |
| |
| /*pre hsc&vsc in pps for scaler down*/ |
| if ((filter->vpp_hf_start_phase_step >= 0x2000000) && |
| (filter->vpp_vsc_start_phase_step >= 0x2000000) && |
| (filter->vpp_hsc_start_phase_step == |
| filter->vpp_hf_start_phase_step) && |
| pre_scaler_en) { |
| filter->vpp_pre_vsc_en = 1; |
| filter->vpp_vsc_start_phase_step >>= 1; |
| ratio_y >>= 1; |
| f2v_get_vertical_phase(ratio_y, ini_vphase, |
| next_frame_par->VPP_vf_ini_phase_, |
| vpp_flags & VPP_FLAG_INTERLACE_OUT); |
| } else |
| filter->vpp_pre_vsc_en = 0; |
| |
| if ((filter->vpp_hf_start_phase_step >= 0x2000000) && |
| (filter->vpp_hsc_start_phase_step == |
| filter->vpp_hf_start_phase_step) && |
| pre_scaler_en) { |
| filter->vpp_pre_hsc_en = 1; |
| filter->vpp_hf_start_phase_step >>= 1; |
| filter->vpp_hsc_start_phase_step >>= 1; |
| } else |
| filter->vpp_pre_hsc_en = 0; |
| /* vscaler enable |
| * vout 4k 50hz |
| * video src heiht >= 2160*60% |
| * 4tap pre-hscaler bandwidth issue, need used old pre hscaler |
| */ |
| if (vinfo->sync_duration_den) { |
| if ((vinfo->width >= 3840) && |
| (vinfo->height >= 2160) && |
| (vinfo->sync_duration_num / |
| vinfo->sync_duration_den >= 50)) |
| is_larger_4k50hz = 1; |
| } |
| if (pre_hscaler_ntap_set[input->layer_id] == 0xff) { |
| if (filter->vpp_pre_hsc_en && |
| is_larger_4k50hz && |
| (height_in >= 2160 * hscaler_input_h_threshold / 100) && |
| (filter->vpp_vsc_start_phase_step != 0x1000000)) |
| pre_hscaler_ntap_enable[input->layer_id] = 0; |
| else |
| pre_hscaler_ntap_enable[input->layer_id] = 1; |
| } else |
| pre_hscaler_ntap_enable[input->layer_id] = |
| pre_hscaler_ntap_set[input->layer_id]; |
| next_frame_par->VPP_hf_ini_phase_ = vpp_zoom_center_x & 0xff; |
| |
| /* overwrite filter setting for interlace output*/ |
| /* TODO: not reasonable when 4K input to 480i output */ |
| if (vpp_flags & VPP_FLAG_INTERLACE_OUT) { |
| filter->vpp_vert_coeff = filter_table[COEF_BILINEAR]; |
| filter->vpp_vert_filter = COEF_BILINEAR; |
| } |
| |
| /* force overwrite filter setting */ |
| if (vert_scaler_filter <= COEF_3D_FILTER) { |
| filter->vpp_vert_coeff = filter_table[vert_scaler_filter]; |
| filter->vpp_vert_filter = vert_scaler_filter; |
| } |
| if (vert_chroma_filter_force_en && |
| (vert_chroma_scaler_filter <= COEF_3D_FILTER)) { |
| vert_chroma_filter = vert_chroma_scaler_filter; |
| filter->vpp_vert_chroma_coeff = |
| filter_table[vert_chroma_filter]; |
| filter->vpp_vert_chroma_filter_en = true; |
| } else { |
| vert_chroma_filter = COEF_NULL; |
| filter->vpp_vert_chroma_filter_en = false; |
| } |
| |
| if (hscaler_8tap_enable[input->layer_id] && |
| (horz_scaler_filter_8tap <= COEF_BSPLINE_8TAP)) { |
| /* hscaler 8 tap */ |
| filter->vpp_horz_coeff = |
| hscaler_8tap_filter_table |
| [horz_scaler_filter_8tap]; |
| filter->vpp_horz_filter = |
| horz_scaler_filter_8tap; |
| } else if (horz_scaler_filter <= COEF_3D_FILTER) { |
| filter->vpp_horz_coeff = |
| filter_table[horz_scaler_filter]; |
| filter->vpp_horz_filter = horz_scaler_filter; |
| } |
| |
| #ifdef TV_3D_FUNCTION_OPEN |
| /* final stage for 3D filter overwrite */ |
| if ((next_frame_par->vpp_3d_scale) && force_filter_mode) { |
| filter->vpp_vert_coeff = filter_table[COEF_3D_FILTER]; |
| filter->vpp_vert_filter = COEF_3D_FILTER; |
| } |
| #endif |
| |
| if (force_pps_hcoef_update) { |
| if (hscaler_8tap_enable[input->layer_id]) |
| filter->vpp_horz_coeff = test_pps_h_coef_8tap; |
| else |
| filter->vpp_horz_coeff = test_pps_h_coef; |
| if (load_pps_coef) |
| horz_coef_print(input->layer_id, filter); |
| } |
| if (force_pps_vcoef_update) { |
| filter->vpp_vert_coeff = test_pps_v_coef; |
| if (load_pps_coef) |
| vert_coef_print(input->layer_id, filter); |
| } |
| |
| if ((cur_filter->last_vert_filter != filter->vpp_vert_filter) || |
| (cur_filter->last_horz_filter != filter->vpp_horz_filter)) { |
| cur_filter->last_vert_filter = filter->vpp_vert_filter; |
| cur_filter->last_horz_filter = filter->vpp_horz_filter; |
| cur_filter->scaler_filter_cnt = 0; |
| } else { |
| cur_filter->scaler_filter_cnt++; |
| } |
| if ((cur_filter->scaler_filter_cnt >= |
| scaler_filter_cnt_limit) && |
| ((cur_filter->cur_vert_filter != |
| filter->vpp_vert_filter) || |
| (cur_filter->cur_horz_filter != |
| filter->vpp_horz_filter))) { |
| cur_filter->cur_vert_filter = filter->vpp_vert_filter; |
| cur_filter->cur_horz_filter = filter->vpp_horz_filter; |
| cur_filter->scaler_filter_cnt = scaler_filter_cnt_limit; |
| ret = vppfilter_success_and_changed; |
| } |
| if (load_pps_coef && |
| (force_pps_hcoef_update || |
| force_pps_vcoef_update)) { |
| load_pps_coef = 0; |
| ret = vppfilter_success_and_changed; |
| } |
| |
| /* store the debug info for legacy */ |
| if (input->layer_id == 0) { |
| cur_vert_filter = cur_filter->cur_vert_filter; |
| cur_horz_filter = cur_filter->cur_horz_filter; |
| cur_vert_chroma_filter = vert_chroma_filter; |
| cur_skip_line = |
| next_frame_par->vscale_skip_count; |
| } |
| |
| if ((next_frame_par->vscale_skip_count > 1) |
| && (vf->type & VIDTYPE_COMPRESS) |
| && (vf->type & VIDTYPE_NO_DW)) |
| ret = vppfilter_changed_but_hold; |
| return ret; |
| } |
| |
| /* |
| *VPP_SRSHARP0_CTRL:0x1d91 |
| *[0]srsharp0 enable for sharpness module reg r/w |
| *[1]if sharpness is enable or vscaler is enable,must set to 1, |
| *sharpness1;reg can only to be w on gxtvbb;which is fix after txl |
| */ |
| int vpp_set_super_scaler_regs( |
| int scaler_path_sel, |
| int reg_srscl0_enable, |
| int reg_srscl0_hsize, |
| int reg_srscl0_vsize, |
| int reg_srscl0_hori_ratio, |
| int reg_srscl0_vert_ratio, |
| int reg_srscl1_enable, |
| int reg_srscl1_hsize, |
| int reg_srscl1_vsize, |
| int reg_srscl1_hori_ratio, |
| int reg_srscl1_vert_ratio, |
| int sr_force_disable, |
| int vpp_postblend_out_width, |
| int vpp_postblend_out_height) |
| { |
| |
| int tmp_data = 0; |
| int tmp_data2 = 0; |
| unsigned int data_path_chose; |
| int sr_core0_max_width; |
| struct sr_info_s *sr; |
| u32 sr_reg_offt; |
| u32 sr_reg_offt2; |
| u32 sr_support; |
| |
| sr = &sr_info; |
| sr_support = sr->sr_support; |
| sr_reg_offt = sr->sr_reg_offt; |
| sr_reg_offt2 = sr->sr_reg_offt2; |
| /* just work around for g12a not to disable sr core2 bit2 */ |
| if (reg_srscl0_vert_ratio == 0) |
| sr_core0_max_width = sr->core0_v_disable_width_max; |
| else |
| sr_core0_max_width = sr->core0_v_enable_width_max; |
| |
| /* top config */ |
| tmp_data = VSYNC_RD_MPEG_REG(VPP_SRSHARP0_CTRL); |
| if (sr0_sr1_refresh && !sr_force_disable) { |
| if (reg_srscl0_hsize > sr_core0_max_width) { |
| if (((tmp_data >> 1) & 0x1) != 0) |
| VSYNC_WR_MPEG_REG_BITS(VPP_SRSHARP0_CTRL, |
| 0, 1, 1); |
| } else { |
| if (((tmp_data >> 1) & 0x1) != 1) |
| VSYNC_WR_MPEG_REG_BITS(VPP_SRSHARP0_CTRL, |
| 1, 1, 1); |
| } |
| if ((tmp_data & 0x1) != 1) |
| VSYNC_WR_MPEG_REG_BITS(VPP_SRSHARP0_CTRL, 1, 0, 1); |
| } |
| tmp_data = VSYNC_RD_MPEG_REG(VPP_SRSHARP1_CTRL); |
| if (sr0_sr1_refresh && !sr_force_disable) { |
| if (((tmp_data >> 1) & 0x1) != 1) |
| VSYNC_WR_MPEG_REG_BITS(VPP_SRSHARP1_CTRL, 1, 1, 1); |
| if ((tmp_data & 0x1) != 1) |
| VSYNC_WR_MPEG_REG_BITS(VPP_SRSHARP1_CTRL, 1, 0, 1); |
| } |
| /* core0 config */ |
| tmp_data = VSYNC_RD_MPEG_REG( |
| SRSHARP0_SHARP_SR2_CTRL + sr_reg_offt); |
| if (sr0_sr1_refresh && !sr_force_disable) { |
| if (((tmp_data >> 5) & 0x1) != (reg_srscl0_vert_ratio&0x1)) |
| VSYNC_WR_MPEG_REG_BITS( |
| SRSHARP0_SHARP_SR2_CTRL + sr_reg_offt, |
| reg_srscl0_vert_ratio&0x1, 5, 1); |
| if (((tmp_data >> 4) & 0x1) != (reg_srscl0_hori_ratio&0x1)) |
| VSYNC_WR_MPEG_REG_BITS( |
| SRSHARP0_SHARP_SR2_CTRL + sr_reg_offt, |
| reg_srscl0_hori_ratio&0x1, 4, 1); |
| |
| if (reg_srscl0_hsize > sr_core0_max_width) { |
| if (((tmp_data >> 2) & 0x1) != 0) |
| VSYNC_WR_MPEG_REG_BITS( |
| SRSHARP0_SHARP_SR2_CTRL + sr_reg_offt, |
| 0, 2, 1); |
| } else { |
| if (((tmp_data >> 2) & 0x1) != 1) { |
| if (is_meson_txlx_cpu()) |
| WRITE_VCBUS_REG_BITS( |
| SRSHARP0_SHARP_SR2_CTRL |
| + sr_reg_offt, |
| 1, 2, 1); |
| VSYNC_WR_MPEG_REG_BITS( |
| SRSHARP0_SHARP_SR2_CTRL + sr_reg_offt, |
| 1, 2, 1); |
| } |
| } |
| |
| if ((tmp_data & 0x1) == (reg_srscl0_hori_ratio & 0x1)) |
| VSYNC_WR_MPEG_REG_BITS( |
| SRSHARP0_SHARP_SR2_CTRL + sr_reg_offt, |
| ((~(reg_srscl0_hori_ratio & 0x1)) & 0x1), 0, 1); |
| } |
| /* core1 config */ |
| if (sr_support & SUPER_CORE1_SUPPORT) { |
| if (is_meson_gxtvbb_cpu()) |
| tmp_data = sharpness1_sr2_ctrl_32d7; |
| else |
| tmp_data = VSYNC_RD_MPEG_REG( |
| SRSHARP1_SHARP_SR2_CTRL |
| + sr_reg_offt2); /*0xc80*/ |
| if (is_meson_gxtvbb_cpu() || |
| (((tmp_data >> 5) & 0x1) != |
| (reg_srscl1_vert_ratio & 0x1)) || |
| (((tmp_data >> 4) & 0x1) != |
| (reg_srscl1_hori_ratio & 0x1)) || |
| ((tmp_data & 0x1) == |
| (reg_srscl1_hori_ratio & 0x1)) || |
| (((tmp_data >> 2) & 0x1) != 1)) { |
| tmp_data = tmp_data & (~(1 << 5)); |
| tmp_data = tmp_data & (~(1 << 4)); |
| tmp_data = tmp_data & (~(1 << 2)); |
| tmp_data = tmp_data & (~(1 << 0)); |
| tmp_data |= ((reg_srscl1_vert_ratio & 0x1) << 5); |
| tmp_data |= ((reg_srscl1_hori_ratio & 0x1) << 4); |
| tmp_data |= (1 << 2); |
| tmp_data |= |
| (((~(reg_srscl1_hori_ratio & 0x1)) & 0x1) << 0); |
| if (sr0_sr1_refresh) { |
| VSYNC_WR_MPEG_REG( |
| SRSHARP1_SHARP_SR2_CTRL |
| + sr_reg_offt2, /*0xc80*/ |
| tmp_data); |
| sharpness1_sr2_ctrl_32d7 = tmp_data; |
| } |
| } |
| } |
| |
| /* size config */ |
| tmp_data = ((reg_srscl0_hsize & 0x1fff) << 16) | |
| (reg_srscl0_vsize & 0x1fff); |
| tmp_data2 = VSYNC_RD_MPEG_REG( |
| SRSHARP0_SHARP_HVSIZE + sr_reg_offt); |
| if (tmp_data != tmp_data2) |
| VSYNC_WR_MPEG_REG( |
| SRSHARP0_SHARP_HVSIZE + sr_reg_offt, |
| tmp_data); |
| |
| tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) | |
| (reg_srscl1_vsize & 0x1fff); |
| |
| if (sr_support & SUPER_CORE1_SUPPORT) { |
| if (get_cpu_type() != MESON_CPU_MAJOR_ID_GXTVBB) |
| tmp_data2 = VSYNC_RD_MPEG_REG( |
| SRSHARP1_SHARP_HVSIZE + sr_reg_offt2); |
| if (is_meson_gxtvbb_cpu() || (tmp_data != tmp_data2)) { |
| VSYNC_WR_MPEG_REG( |
| SRSHARP1_SHARP_HVSIZE + sr_reg_offt2, tmp_data); |
| if (is_meson_gxtvbb_cpu()) |
| sharpness1_sr2_ctrl_3280 = tmp_data; |
| } |
| } |
| |
| /*ve input size setting*/ |
| if (sr->core_support == ONLY_CORE0) |
| tmp_data = ((reg_srscl0_hsize & 0x1fff) << 16) | |
| (reg_srscl0_vsize & 0x1fff); |
| else if ((sr->core_support == NEW_CORE0_CORE1) && |
| ((scaler_path_sel == PPS_CORE0_CORE1) || |
| (scaler_path_sel == PPS_CORE0_POSTBLEND_CORE1))) |
| tmp_data = ((reg_srscl0_hsize & 0x1fff) << 16) | |
| (reg_srscl0_vsize & 0x1fff); |
| else |
| tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) | |
| (reg_srscl1_vsize & 0x1fff); |
| tmp_data2 = VSYNC_RD_MPEG_REG(VPP_VE_H_V_SIZE); |
| if (tmp_data != tmp_data2) |
| VSYNC_WR_MPEG_REG(VPP_VE_H_V_SIZE, tmp_data); |
| /*chroma blue stretch size setting*/ |
| if (is_meson_txlx_cpu() || is_meson_txhd_cpu() |
| || (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))) { |
| tmp_data = (((vpp_postblend_out_width & 0x1fff) << 16) | |
| (vpp_postblend_out_height & 0x1fff)); |
| VSYNC_WR_MPEG_REG(VPP_OUT_H_V_SIZE, tmp_data); |
| } else { |
| if (scaler_path_sel == CORE0_PPS_CORE1) { |
| tmp_data = (((reg_srscl1_hsize & 0x1fff) << |
| reg_srscl1_hori_ratio) << 16) | |
| ((reg_srscl1_vsize & 0x1fff) << |
| reg_srscl1_vert_ratio); |
| tmp_data2 = VSYNC_RD_MPEG_REG(VPP_PSR_H_V_SIZE); |
| if (tmp_data != tmp_data2) |
| VSYNC_WR_MPEG_REG(VPP_PSR_H_V_SIZE, tmp_data); |
| } else if ((scaler_path_sel == CORE0_CORE1_PPS) || |
| (scaler_path_sel == CORE1_BEFORE_PPS) || |
| (scaler_path_sel == CORE1_AFTER_PPS)) { |
| tmp_data = ((reg_srscl1_hsize & 0x1fff) << 16) | |
| (reg_srscl1_vsize & 0x1fff); |
| tmp_data2 = VSYNC_RD_MPEG_REG(VPP_PSR_H_V_SIZE); |
| if (tmp_data != tmp_data2) |
| VSYNC_WR_MPEG_REG(VPP_PSR_H_V_SIZE, tmp_data); |
| } |
| } |
| |
| /* path config */ |
| if (is_meson_txhd_cpu()) |
| data_path_chose = 6; |
| else |
| data_path_chose = 5; |
| if (get_cpu_type() <= MESON_CPU_MAJOR_ID_TXHD) { |
| if ((scaler_path_sel == CORE0_PPS_CORE1) || |
| (scaler_path_sel == CORE1_BEFORE_PPS) || |
| (scaler_path_sel == CORE0_BEFORE_PPS)) { |
| VSYNC_WR_MPEG_REG_BITS(VPP_VE_ENABLE_CTRL, |
| 0, data_path_chose, 1); |
| } else { |
| VSYNC_WR_MPEG_REG_BITS(VPP_VE_ENABLE_CTRL, |
| 1, data_path_chose, 1); |
| } |
| } |
| if (super_scaler == 0 || sr_force_disable) { |
| VSYNC_WR_MPEG_REG(VPP_SRSHARP0_CTRL, 0); |
| VSYNC_WR_MPEG_REG(VPP_SRSHARP1_CTRL, 0); |
| } |
| |
| return 0; |
| } |
| |
| static void vpp_set_super_scaler( |
| u32 vpp_wide_mode, |
| const struct vinfo_s *vinfo, |
| struct vpp_frame_par_s *next_frame_par, |
| bool bypass_sr0, bool bypass_sr1, u32 vpp_flags) |
| { |
| unsigned int hor_sc_multiple_num, ver_sc_multiple_num, temp; |
| u32 width_out = next_frame_par->VPP_hsc_endp - |
| next_frame_par->VPP_hsc_startp + 1; |
| u32 height_out = next_frame_par->VPP_vsc_endp - |
| next_frame_par->VPP_vsc_startp + 1; |
| u32 src_width = next_frame_par->video_input_w; |
| u32 src_height = next_frame_par->video_input_h; |
| u32 sr_path; |
| struct sr_info_s *sr; |
| u32 sr_support; |
| |
| sr = &sr_info; |
| sr_support = sr->sr_support; |
| /*for sr adjust*/ |
| vpp_super_scaler_support(); |
| |
| next_frame_par->sr_core_support = sr_support; |
| |
| hor_sc_multiple_num = (1 << PPS_FRAC_BITS) / |
| next_frame_par->vpp_filter.vpp_hsc_start_phase_step; |
| ver_sc_multiple_num = SUPER_SCALER_V_FACTOR*(1 << PPS_FRAC_BITS)/ |
| next_frame_par->vpp_filter.vpp_vsc_start_phase_step; |
| |
| /* just calcuate the enable sclaer module */ |
| /* |
| *note:if first check h may cause v can't do scaling; |
| * for example: 1920x1080(input),3840x2160(output); |
| * todo:if you have better idea,you can improve it |
| */ |
| /* step1: judge core0&core1 vertical enable or disable*/ |
| if (ver_sc_multiple_num >= 2*SUPER_SCALER_V_FACTOR) { |
| next_frame_par->supsc0_vert_ratio = |
| ((src_width < sr->core0_v_enable_width_max) && |
| (sr_support & SUPER_CORE0_SUPPORT)) ? 1 : 0; |
| next_frame_par->supsc1_vert_ratio = |
| ((width_out < sr->core1_v_disable_width_max) && |
| (src_width < sr->core1_v_enable_width_max) && |
| (sr_support & SUPER_CORE1_SUPPORT)) ? 1 : 0; |
| if (next_frame_par->supsc0_vert_ratio && |
| (ver_sc_multiple_num < 4 * SUPER_SCALER_V_FACTOR)) |
| next_frame_par->supsc1_vert_ratio = 0; |
| next_frame_par->supsc0_enable = |
| next_frame_par->supsc0_vert_ratio ? 1 : 0; |
| next_frame_par->supsc1_enable = |
| next_frame_par->supsc1_vert_ratio ? 1 : 0; |
| } else { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc0_vert_ratio = 0; |
| next_frame_par->supsc1_enable = 0; |
| next_frame_par->supsc1_vert_ratio = 0; |
| } |
| /* step2: judge core0&core1 horizontal enable or disable*/ |
| if (hor_sc_multiple_num >= 2 && |
| ((vpp_wide_mode != VIDEO_WIDEOPTION_NONLINEAR) && |
| (vpp_wide_mode != VIDEO_WIDEOPTION_NONLINEAR_T))) { |
| if ((src_width > sr->core0_v_disable_width_max) || |
| ((src_width > sr->core0_v_enable_width_max) && |
| next_frame_par->supsc0_vert_ratio) || |
| (((src_width << 1) > sr->core1_v_enable_width_max) && |
| next_frame_par->supsc1_vert_ratio)) |
| next_frame_par->supsc0_hori_ratio = 0; |
| else if (sr_support & SUPER_CORE0_SUPPORT) |
| next_frame_par->supsc0_hori_ratio = 1; |
| if (((width_out >> 1) > sr->core1_v_disable_width_max) || |
| (((width_out >> 1) > sr->core1_v_enable_width_max) && |
| next_frame_par->supsc1_vert_ratio) || |
| (next_frame_par->supsc0_hori_ratio && |
| (hor_sc_multiple_num < 4))) |
| next_frame_par->supsc1_hori_ratio = 0; |
| else if (sr_support & SUPER_CORE1_SUPPORT) |
| next_frame_par->supsc1_hori_ratio = 1; |
| next_frame_par->supsc0_enable = |
| (next_frame_par->supsc0_hori_ratio || |
| next_frame_par->supsc0_enable) ? 1 : 0; |
| next_frame_par->supsc1_enable = |
| (next_frame_par->supsc1_hori_ratio || |
| next_frame_par->supsc1_enable) ? 1 : 0; |
| } else { |
| next_frame_par->supsc0_enable = |
| next_frame_par->supsc0_vert_ratio ? 1 : 0; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc1_enable = |
| next_frame_par->supsc1_vert_ratio ? 1 : 0; |
| next_frame_par->supsc1_hori_ratio = 0; |
| } |
| |
| /*double check core0 input width for core0_vert_ratio!!!*/ |
| if (next_frame_par->supsc0_vert_ratio && |
| (width_out >> next_frame_par->supsc0_hori_ratio > |
| sr->core0_v_enable_width_max)) { |
| next_frame_par->supsc0_vert_ratio = 0; |
| if (next_frame_par->supsc0_hori_ratio == 0) |
| next_frame_par->supsc0_enable = 0; |
| } |
| |
| /*double check core1 input width for core1_vert_ratio!!!*/ |
| if (next_frame_par->supsc1_vert_ratio && |
| (width_out >> next_frame_par->supsc1_hori_ratio > |
| sr->core1_v_enable_width_max)) { |
| next_frame_par->supsc1_vert_ratio = 0; |
| if (next_frame_par->supsc1_hori_ratio == 0) |
| next_frame_par->supsc1_enable = 0; |
| } |
| |
| /* option add patch */ |
| if ((ver_sc_multiple_num <= super_scaler_v_ratio) && |
| (src_height >= sr->core0_v_enable_width_max) && |
| (src_height <= 1088) && |
| (ver_sc_multiple_num > SUPER_SCALER_V_FACTOR) && |
| (vinfo->height >= 2000)) { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc1_enable = 1; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc1_hori_ratio = 1; |
| next_frame_par->supsc0_vert_ratio = 0; |
| next_frame_par->supsc1_vert_ratio = 1; |
| } |
| if (bypass_sr0 || !(sr_support & SUPER_CORE0_SUPPORT)) { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc0_vert_ratio = 0; |
| } |
| |
| /* much vskip case, no need super scale up */ |
| if (next_frame_par->vscale_skip_count >= 2) { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc0_vert_ratio = 0; |
| } |
| |
| if (bypass_sr1 || !(sr_support & SUPER_CORE1_SUPPORT)) { |
| next_frame_par->supsc1_enable = 0; |
| next_frame_par->supsc1_hori_ratio = 0; |
| next_frame_par->supsc1_vert_ratio = 0; |
| } |
| /* new add according to pq test @20170808 on gxlx*/ |
| if (scaler_path_sel >= SCALER_PATH_MAX) { |
| if (sr->supscl_path == 0xff) { |
| if (is_meson_gxlx_cpu()) { |
| if (next_frame_par->supsc1_hori_ratio && |
| next_frame_par->supsc1_vert_ratio) |
| next_frame_par->supscl_path = |
| CORE1_BEFORE_PPS; |
| else |
| next_frame_par->supscl_path = |
| CORE1_AFTER_PPS; |
| } else if (is_meson_txhd_cpu() || |
| is_meson_g12a_cpu() || |
| is_meson_g12b_cpu() || |
| is_meson_sm1_cpu()) { |
| if (next_frame_par->supsc0_hori_ratio && |
| next_frame_par->supsc0_vert_ratio) |
| next_frame_par->supscl_path = |
| CORE0_BEFORE_PPS; |
| else |
| next_frame_par->supscl_path = |
| CORE0_AFTER_PPS; |
| } else { |
| next_frame_par->supscl_path = CORE0_PPS_CORE1; |
| } |
| } else { |
| next_frame_par->supscl_path = sr->supscl_path; |
| } |
| } else { |
| next_frame_par->supscl_path = scaler_path_sel; |
| } |
| |
| /*patch for width align 2*/ |
| if (super_scaler && (width_out%2) && |
| ((((next_frame_par->supscl_path == CORE0_AFTER_PPS) || |
| (next_frame_par->supscl_path == PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc0_hori_ratio) || |
| (((next_frame_par->supscl_path == CORE0_PPS_CORE1) || |
| (next_frame_par->supscl_path == CORE0_CORE1_PPS) || |
| (next_frame_par->supscl_path == CORE1_AFTER_PPS) || |
| (next_frame_par->supscl_path == CORE0_BEFORE_PPS) || |
| (next_frame_par->supscl_path == PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc1_hori_ratio))) { |
| temp = next_frame_par->VPP_hsc_endp; |
| if (++temp >= vinfo->width) { |
| if ((next_frame_par->VPP_hsc_startp > 0) && |
| (next_frame_par->VPP_hsc_startp < |
| next_frame_par->VPP_hsc_endp)) |
| next_frame_par->VPP_hsc_startp--; |
| else if (((next_frame_par->supscl_path == |
| PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc0_hori_ratio && |
| next_frame_par->supsc1_hori_ratio) { |
| next_frame_par->supsc1_enable = 0; |
| next_frame_par->supsc1_hori_ratio = 0; |
| next_frame_par->supsc1_vert_ratio = 0; |
| next_frame_par->VPP_hsc_endp++; |
| } else if ((next_frame_par->supscl_path == |
| CORE0_AFTER_PPS) || |
| (((next_frame_par->supscl_path == |
| PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc0_hori_ratio)) { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc0_vert_ratio = 0; |
| } else if ((next_frame_par->supscl_path == |
| CORE1_AFTER_PPS) || |
| (next_frame_par->supscl_path == |
| CORE0_PPS_CORE1) || |
| (((next_frame_par->supscl_path == |
| PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc1_hori_ratio)) { |
| next_frame_par->supsc1_enable = 0; |
| next_frame_par->supsc1_hori_ratio = 0; |
| next_frame_par->supsc1_vert_ratio = 0; |
| } |
| } else |
| next_frame_par->VPP_hsc_endp++; |
| width_out++; |
| } |
| |
| /*patch for height align 2*/ |
| if (super_scaler && (height_out%2) && |
| ((((next_frame_par->supscl_path == CORE0_AFTER_PPS) || |
| (next_frame_par->supscl_path == PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc0_vert_ratio) || |
| (((next_frame_par->supscl_path == CORE0_PPS_CORE1) || |
| (next_frame_par->supscl_path == CORE0_CORE1_PPS) || |
| (next_frame_par->supscl_path == CORE1_AFTER_PPS) || |
| (next_frame_par->supscl_path == CORE0_BEFORE_PPS) || |
| (next_frame_par->supscl_path == PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc1_vert_ratio))) { |
| temp = next_frame_par->VPP_vsc_endp; |
| if (++temp >= vinfo->height) { |
| if ((next_frame_par->VPP_vsc_startp > 0) && |
| (next_frame_par->VPP_vsc_startp < |
| next_frame_par->VPP_vsc_endp)) |
| next_frame_par->VPP_vsc_startp--; |
| else if (((next_frame_par->supscl_path == |
| PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc0_vert_ratio && |
| next_frame_par->supsc1_vert_ratio) { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc0_vert_ratio = 0; |
| next_frame_par->VPP_vsc_endp++; |
| } else if ((next_frame_par->supscl_path == |
| CORE0_AFTER_PPS) || |
| (((next_frame_par->supscl_path == |
| PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc0_vert_ratio)) { |
| next_frame_par->supsc0_enable = 0; |
| next_frame_par->supsc0_hori_ratio = 0; |
| next_frame_par->supsc0_vert_ratio = 0; |
| } else if ((next_frame_par->supscl_path == |
| CORE1_AFTER_PPS) || |
| (next_frame_par->supscl_path == |
| CORE0_PPS_CORE1) || |
| (((next_frame_par->supscl_path == |
| PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)) && |
| next_frame_par->supsc1_vert_ratio)) { |
| next_frame_par->supsc1_enable = 0; |
| next_frame_par->supsc1_hori_ratio = 0; |
| next_frame_par->supsc1_vert_ratio = 0; |
| } |
| } else |
| next_frame_par->VPP_vsc_endp++; |
| height_out++; |
| } |
| |
| /* select the scaler path:[core0 =>> |
| *ppscaler =>> core1] or |
| *[core0 =>> ppscaler =>> postblender =>> core1] |
| *gxlx only have core1,so the path:[core1 ==> pps ==> postblend] |
| *or pps ==> core1 ==> postblend |
| *txhd only have core0,so the path:[core0 ==> pps ==> postblend] |
| *or pps ==> core0 ==> postblend |
| */ |
| if (next_frame_par->supscl_path == CORE0_AFTER_PPS) { |
| next_frame_par->spsc0_h_in = |
| height_out >> next_frame_par->supsc0_vert_ratio; |
| next_frame_par->spsc0_w_in = |
| width_out >> next_frame_par->supsc0_hori_ratio; |
| } else if ((next_frame_par->supscl_path == PPS_CORE0_CORE1) |
| || (next_frame_par->supscl_path == |
| PPS_CORE0_POSTBLEND_CORE1)){ /*tl1*/ |
| next_frame_par->spsc0_h_in = |
| (height_out >> next_frame_par->supsc0_vert_ratio) >> |
| next_frame_par->supsc1_vert_ratio; |
| next_frame_par->spsc0_w_in = |
| (width_out >> next_frame_par->supsc0_hori_ratio) >> |
| next_frame_par->supsc1_hori_ratio; |
| } else { |
| next_frame_par->spsc0_h_in = src_height; |
| next_frame_par->spsc0_w_in = src_width; |
| } |
| if ((next_frame_par->supscl_path == CORE0_PPS_CORE1) || |
| (next_frame_par->supscl_path == CORE0_CORE1_PPS) || |
| (next_frame_par->supscl_path == CORE1_AFTER_PPS) || |
| (next_frame_par->supscl_path == CORE0_BEFORE_PPS) || |
| (next_frame_par->supscl_path == PPS_CORE0_CORE1) || |
| (next_frame_par->supscl_path == PPS_CORE0_POSTBLEND_CORE1)) { |
| next_frame_par->spsc1_h_in = |
| (height_out >> next_frame_par->supsc1_vert_ratio); |
| next_frame_par->spsc1_w_in = |
| (width_out >> next_frame_par->supsc1_hori_ratio); |
| } else if (next_frame_par->supscl_path == CORE1_BEFORE_PPS) { |
| next_frame_par->spsc1_h_in = src_height; |
| next_frame_par->spsc1_w_in = src_width; |
| } else if (next_frame_par->supscl_path == CORE0_AFTER_PPS) { |
| next_frame_par->spsc1_h_in = |
| (height_out >> next_frame_par->supsc0_vert_ratio); |
| next_frame_par->spsc1_w_in = |
| (width_out >> next_frame_par->supsc0_hori_ratio); |
| } else { |
| next_frame_par->spsc1_h_in = height_out; |
| next_frame_par->spsc1_w_in = width_out; |
| } |
| /*recalc phase step and pps input&output size param*/ |
| /*phase*/ |
| if (next_frame_par->supsc0_hori_ratio) { |
| next_frame_par->vpp_filter.vpp_hsc_start_phase_step <<= 1; |
| next_frame_par->vpp_filter.vpp_hf_start_phase_step <<= 1; |
| } |
| if (next_frame_par->supsc1_hori_ratio) { |
| next_frame_par->vpp_filter.vpp_hsc_start_phase_step <<= 1; |
| next_frame_par->vpp_filter.vpp_hf_start_phase_step <<= 1; |
| } |
| if (next_frame_par->supsc0_vert_ratio) |
| next_frame_par->vpp_filter.vpp_vsc_start_phase_step <<= 1; |
| if (next_frame_par->supsc1_vert_ratio) |
| next_frame_par->vpp_filter.vpp_vsc_start_phase_step <<= 1; |
| /*pps input size*/ |
| if (((next_frame_par->supscl_path == CORE0_PPS_CORE1) || |
| (next_frame_par->supscl_path == CORE0_CORE1_PPS) || |
| (next_frame_par->supscl_path == CORE0_BEFORE_PPS))) { |
| next_frame_par->VPP_line_in_length_ <<= |
| next_frame_par->supsc0_hori_ratio; |
| next_frame_par->VPP_pic_in_height_ <<= |
| next_frame_par->supsc0_vert_ratio; |
| } |
| if (((next_frame_par->supscl_path == CORE0_CORE1_PPS) || |
| (next_frame_par->supscl_path == CORE1_BEFORE_PPS))) { |
| next_frame_par->VPP_line_in_length_ <<= |
| next_frame_par->supsc1_hori_ratio; |
| next_frame_par->VPP_pic_in_height_ <<= |
| next_frame_par->supsc1_vert_ratio; |
| } |
| |
| sr_path = next_frame_par->supscl_path; |
| /* path config */ |
| if (sr->core_support == NEW_CORE0_CORE1) { |
| if (sr_path == CORE0_PPS_CORE1) { |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 1; |
| } else if (sr_path == PPS_CORE0_CORE1) { |
| next_frame_par->sr0_position = 0; |
| next_frame_par->sr1_position = 1; |
| } else if (sr_path == |
| PPS_CORE0_POSTBLEND_CORE1) { |
| next_frame_par->sr0_position = 0; |
| next_frame_par->sr1_position = 0; |
| } else if (sr_path == |
| CORE0_PPS_POSTBLEND_CORE1) { |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 0; |
| } else { |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 1; |
| } |
| if (next_frame_par->sr1_position) { |
| /* sr core 1 output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->spsc1_w_in << |
| next_frame_par->supsc1_hori_ratio; |
| next_frame_par->cm_input_h = |
| next_frame_par->spsc1_h_in << |
| next_frame_par->supsc1_vert_ratio; |
| } else if (!next_frame_par->sr0_position) { |
| /* sr core 0 output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->spsc0_w_in << |
| next_frame_par->supsc0_hori_ratio; |
| next_frame_par->cm_input_h = |
| next_frame_par->spsc0_h_in << |
| next_frame_par->supsc0_vert_ratio; |
| } else { |
| /* pps output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->VPP_hsc_endp - |
| next_frame_par->VPP_hsc_startp + 1; |
| next_frame_par->cm_input_h = |
| next_frame_par->VPP_vsc_endp - |
| next_frame_par->VPP_vsc_startp + 1; |
| } |
| } else if (sr->core_support == ONLY_CORE0) { |
| if (sr_path == CORE0_BEFORE_PPS) |
| next_frame_par->sr0_position = 1; |
| else if (sr_path == CORE0_AFTER_PPS) |
| next_frame_par->sr0_position = 0; |
| else |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 0; |
| if (!next_frame_par->sr0_position) { |
| /* sr core 0 output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->spsc0_w_in << |
| next_frame_par->supsc0_hori_ratio; |
| next_frame_par->cm_input_h = |
| next_frame_par->spsc0_h_in << |
| next_frame_par->supsc0_vert_ratio; |
| } else { |
| /* pps output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->VPP_hsc_endp - |
| next_frame_par->VPP_hsc_startp + 1; |
| next_frame_par->cm_input_h = |
| next_frame_par->VPP_vsc_endp - |
| next_frame_par->VPP_vsc_startp + 1; |
| } |
| } else if (sr->core_support == ONLY_CORE1) { |
| if (sr_path == CORE1_BEFORE_PPS) |
| next_frame_par->sr1_position = 1; |
| else if (sr_path == CORE1_AFTER_PPS) |
| next_frame_par->sr1_position = 0; |
| else |
| next_frame_par->sr1_position = 1; |
| next_frame_par->sr0_position = 0; |
| if (!next_frame_par->sr1_position) { |
| /* sr core 1 output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->spsc1_w_in << |
| next_frame_par->supsc1_hori_ratio; |
| next_frame_par->cm_input_h = |
| next_frame_par->spsc1_h_in << |
| next_frame_par->supsc1_vert_ratio; |
| } else { |
| /* pps output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->VPP_hsc_endp - |
| next_frame_par->VPP_hsc_startp + 1; |
| next_frame_par->cm_input_h = |
| next_frame_par->VPP_vsc_endp - |
| next_frame_par->VPP_vsc_startp + 1; |
| } |
| } else if (sr->core_support == OLD_CORE0_CORE1) { |
| if (sr_path == CORE0_PPS_CORE1) { |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 1; |
| } else if (sr_path == |
| CORE0_PPS_POSTBLEND_CORE1) { |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 0; |
| } else { |
| next_frame_par->sr0_position = 1; |
| next_frame_par->sr1_position = 1; |
| } |
| if (next_frame_par->sr1_position) { |
| /* sr core 1 output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->spsc1_w_in << |
| next_frame_par->supsc1_hori_ratio; |
| next_frame_par->cm_input_h = |
| next_frame_par->spsc1_h_in << |
| next_frame_par->supsc1_vert_ratio; |
| } else { |
| /* pps output */ |
| next_frame_par->cm_input_w = |
| next_frame_par->VPP_hsc_endp - |
| next_frame_par->VPP_hsc_startp + 1; |
| next_frame_par->cm_input_h = |
| next_frame_par->VPP_vsc_endp - |
| next_frame_par->VPP_vsc_startp + 1; |
| } |
| } |
| |
| if (super_debug && (vpp_flags & VPP_FLAG_MORE_LOG)) { |
| pr_info("layer0: spsc0_w_in=%u, spsc0_h_in=%u, spsc1_w_in=%u, spsc1_h_in=%u.\n", |
| next_frame_par->spsc0_w_in, next_frame_par->spsc0_h_in, |
| next_frame_par->spsc1_w_in, next_frame_par->spsc1_h_in); |
| pr_info("layer0: supsc0_hori=%d,supsc1_hori=%d,supsc0_v=%d,supsc1_v=%d\n", |
| next_frame_par->supsc0_hori_ratio, |
| next_frame_par->supsc1_hori_ratio, |
| next_frame_par->supsc0_vert_ratio, |
| next_frame_par->supsc1_vert_ratio); |
| pr_info("layer0: VPP_hd_start_lines= %d,%d,%d,%d, %d,%d,%d,%d, %d,%d\n", |
| next_frame_par->VPP_hd_start_lines_, |
| next_frame_par->VPP_hd_end_lines_, |
| next_frame_par->VPP_vd_start_lines_, |
| next_frame_par->VPP_vd_end_lines_, |
| next_frame_par->VPP_hsc_startp, |
| next_frame_par->VPP_hsc_endp, |
| next_frame_par->VPP_hsc_linear_startp, |
| next_frame_par->VPP_hsc_linear_endp, |
| next_frame_par->VPP_vsc_startp, |
| next_frame_par->VPP_vsc_endp); |
| pr_info("layer0: cm_input_w=%u, cm_input_h=%u, sr0_position=%u, sr1_position=%u.\n", |
| next_frame_par->cm_input_w, |
| next_frame_par->cm_input_h, |
| next_frame_par->sr0_position, |
| next_frame_par->sr1_position); |
| } |
| } |
| |
| #ifdef TV_3D_FUNCTION_OPEN |
| void get_vpp_3d_mode( |
| u32 process_3d_type, u32 trans_fmt, u32 *vpp_3d_mode) |
| { |
| switch (trans_fmt) { |
| case TVIN_TFMT_3D_LRH_OLOR: |
| case TVIN_TFMT_3D_LRH_OLER: |
| case TVIN_TFMT_3D_LRH_ELOR: |
| case TVIN_TFMT_3D_LRH_ELER: |
| case TVIN_TFMT_3D_DET_LR: |
| *vpp_3d_mode = VPP_3D_MODE_LR; |
| break; |
| case TVIN_TFMT_3D_FP: |
| case TVIN_TFMT_3D_TB: |
| case TVIN_TFMT_3D_DET_TB: |
| case TVIN_TFMT_3D_FA: |
| *vpp_3d_mode = VPP_3D_MODE_TB; |
| if (process_3d_type & MODE_3D_MVC) |
| *vpp_3d_mode = VPP_3D_MODE_FA; |
| break; |
| case TVIN_TFMT_3D_LA: |
| case TVIN_TFMT_3D_DET_INTERLACE: |
| *vpp_3d_mode = VPP_3D_MODE_LA; |
| break; |
| case TVIN_TFMT_3D_DET_CHESSBOARD: |
| default: |
| *vpp_3d_mode = VPP_3D_MODE_NULL; |
| break; |
| } |
| } |
| |
| static void vpp_get_video_source_size( |
| u32 *src_width, u32 *src_height, |
| u32 process_3d_type, struct vframe_s *vf, |
| struct vpp_frame_par_s *next_frame_par) |
| { |
| int frame_width, frame_height; |
| |
| if (vf->type & VIDTYPE_COMPRESS) { |
| frame_width = vf->compWidth; |
| frame_height = vf->compHeight; |
| } else { |
| frame_width = vf->width; |
| frame_height = vf->height; |
| } |
| if ((process_3d_type & MODE_3D_AUTO) || |
| (((process_3d_type & MODE_3D_TO_2D_R) || |
| (process_3d_type & MODE_3D_TO_2D_L) || |
| (process_3d_type & MODE_3D_LR_SWITCH) || |
| (process_3d_type & MODE_FORCE_3D_TO_2D_TB) || |
| (process_3d_type & MODE_FORCE_3D_TO_2D_LR)) && |
| (process_3d_type & MODE_3D_ENABLE))) { |
| if (vf->trans_fmt) { |
| if (process_3d_type & MODE_3D_TO_2D_MASK) |
| *src_height = vf->left_eye.height; |
| else { |
| *src_height = vf->left_eye.height << 1; |
| next_frame_par->vpp_2pic_mode = 1; |
| } |
| *src_width = vf->left_eye.width; |
| } |
| |
| switch (vf->trans_fmt) { |
| case TVIN_TFMT_3D_LRH_OLOR: |
| case TVIN_TFMT_3D_LRH_OLER: |
| case TVIN_TFMT_3D_LRH_ELOR: |
| case TVIN_TFMT_3D_LRH_ELER: |
| case TVIN_TFMT_3D_DET_LR: |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR; |
| break; |
| case TVIN_TFMT_3D_FP: |
| case TVIN_TFMT_3D_TB: |
| case TVIN_TFMT_3D_DET_TB: |
| case TVIN_TFMT_3D_FA: |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; |
| /*just for mvc 3d file */ |
| if (process_3d_type & MODE_3D_MVC) { |
| next_frame_par->vpp_2pic_mode = 2; |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA; |
| } |
| break; |
| case TVIN_TFMT_3D_LA: |
| case TVIN_TFMT_3D_DET_INTERLACE: |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_LA; |
| next_frame_par->vpp_2pic_mode = 0; |
| break; |
| case TVIN_TFMT_3D_DET_CHESSBOARD: |
| default: |
| *src_width = frame_width; |
| *src_height = frame_height; |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; |
| next_frame_par->vpp_3d_scale = 0; |
| next_frame_par->vpp_2pic_mode = 0; |
| break; |
| } |
| |
| } else if ((process_3d_type & MODE_3D_LR) || |
| (process_3d_type & MODE_FORCE_3D_LR)) { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR; |
| if (process_3d_type & MODE_3D_TO_2D_MASK) { |
| *src_width = frame_width >> 1; |
| *src_height = frame_height; |
| } else if (process_3d_type & MODE_3D_OUT_LR) { |
| *src_width = frame_width; |
| *src_height = frame_height; |
| next_frame_par->vpp_2pic_mode = 1; |
| } else { |
| *src_width = frame_width >> 1; |
| *src_height = frame_height << 1; |
| next_frame_par->vpp_2pic_mode = 1; |
| } |
| |
| } else if ((process_3d_type & MODE_3D_TB) || |
| (process_3d_type & MODE_FORCE_3D_TB)) { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; |
| if (process_3d_type & MODE_3D_TO_2D_MASK) { |
| *src_width = frame_width; |
| *src_height = frame_height >> 1; |
| } else if (process_3d_type & MODE_3D_OUT_LR) { |
| *src_width = frame_width << 1; |
| *src_height = frame_height >> 1; |
| next_frame_par->vpp_2pic_mode = 1; |
| } else { |
| *src_width = frame_width; |
| *src_height = frame_height; |
| next_frame_par->vpp_2pic_mode = 1; |
| } |
| if (process_3d_type & MODE_3D_MVC) { |
| *src_width = frame_width; |
| *src_height = frame_height << 1; |
| next_frame_par->vpp_2pic_mode = 2; |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA; |
| } |
| } else if (process_3d_type & MODE_3D_LA) { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_LA; |
| *src_height = frame_height - 1; |
| *src_width = frame_width; |
| next_frame_par->vpp_2pic_mode = 0; |
| next_frame_par->vpp_3d_scale = 1; |
| if (process_3d_type & MODE_3D_TO_2D_MASK) { |
| next_frame_par->vscale_skip_count = 1; |
| next_frame_par->vpp_3d_scale = 0; |
| } else if (process_3d_type & MODE_3D_OUT_TB) { |
| *src_height = frame_height << 1; |
| next_frame_par->vscale_skip_count = 1; |
| next_frame_par->vpp_3d_scale = 0; |
| } else if (process_3d_type & MODE_3D_OUT_LR) { |
| *src_width = frame_width << 1; |
| next_frame_par->vscale_skip_count = 1; |
| next_frame_par->vpp_3d_scale = 0; |
| } |
| } else if ((process_3d_type & MODE_3D_FA) |
| || (process_3d_type & MODE_FORCE_3D_FA_LR) |
| || (process_3d_type & MODE_FORCE_3D_FA_TB)) { |
| |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA; |
| if (process_3d_type & MODE_3D_TO_2D_MASK) { |
| if (process_3d_type & MODE_FORCE_3D_FA_TB) { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; |
| *src_width = frame_width; |
| *src_height = frame_height >> 1; |
| } |
| if (process_3d_type & MODE_FORCE_3D_FA_LR) { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_LR; |
| *src_width = frame_width >> 1; |
| *src_height = frame_height; |
| } |
| if (process_3d_type & MODE_3D_MVC) { |
| *src_width = frame_width; |
| *src_height = frame_height; |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_FA; |
| } |
| if (vf->trans_fmt == TVIN_TFMT_3D_FP) { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_TB; |
| *src_width = frame_width; |
| *src_height = vf->left_eye.height; |
| } |
| next_frame_par->vpp_2pic_mode = 0; |
| } else if (process_3d_type & MODE_3D_OUT_LR) { |
| *src_width = frame_width << 1; |
| *src_height = frame_height; |
| next_frame_par->vpp_2pic_mode = 2; |
| } else { |
| *src_width = frame_width; |
| *src_height = frame_height << 1; |
| next_frame_par->vpp_2pic_mode = 2; |
| } |
| } else { |
| *src_width = frame_width; |
| *src_height = frame_height; |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; |
| next_frame_par->vpp_2pic_mode = 0; |
| next_frame_par->vpp_3d_scale = 0; |
| } |
| /*process 3d->2d or l/r switch case */ |
| if ((next_frame_par->vpp_3d_mode != VPP_3D_MODE_NULL) && |
| (next_frame_par->vpp_3d_mode != VPP_3D_MODE_LA) |
| && (process_3d_type & MODE_3D_ENABLE)) { |
| if (process_3d_type & MODE_3D_TO_2D_R) |
| next_frame_par->vpp_2pic_mode = VPP_SELECT_PIC1; |
| else if (process_3d_type & MODE_3D_TO_2D_L) |
| next_frame_par->vpp_2pic_mode = VPP_SELECT_PIC0; |
| else if (process_3d_type & MODE_3D_LR_SWITCH) |
| next_frame_par->vpp_2pic_mode |= VPP_PIC1_FIRST; |
| if ((process_3d_type & MODE_FORCE_3D_TO_2D_LR) || |
| (process_3d_type & MODE_FORCE_3D_TO_2D_TB)) |
| next_frame_par->vpp_2pic_mode = VPP_SELECT_PIC0; |
| |
| /*only display one pic */ |
| if ((next_frame_par->vpp_2pic_mode & 0x3) == 0) |
| next_frame_par->vpp_3d_scale = 0; |
| else |
| next_frame_par->vpp_3d_scale = 1; |
| } |
| /*avoid dividing 0 error */ |
| if (*src_width == 0 || *src_height == 0) { |
| *src_width = frame_width; |
| *src_height = frame_height; |
| } |
| } |
| #endif |
| |
| static int vpp_set_filters_no_scaler_internal( |
| struct disp_info_s *input, |
| u32 width_in, |
| u32 height_in, |
| u32 wid_out, |
| u32 hei_out, |
| const struct vinfo_s *vinfo, |
| u32 vpp_flags, |
| struct vpp_frame_par_s *next_frame_par, struct vframe_s *vf) |
| { |
| s32 start, end; |
| s32 video_top, video_left, temp; |
| u32 video_width, video_height; |
| u32 ratio_x = 0; |
| u32 ratio_y = 0; |
| u32 ratio_tmp = 0; |
| int temp_width; |
| int temp_height; |
| struct vppfilter_mode_s *filter = &next_frame_par->vpp_filter; |
| u32 wide_mode; |
| s32 height_shift = 0; |
| u32 w_in = width_in; |
| u32 h_in = height_in; |
| bool h_crop_enable = false, v_crop_enable = false; |
| bool skip_policy_check = true; |
| u32 vskip_step; |
| s32 video_layer_global_offset_x, video_layer_global_offset_y; |
| u32 video_source_crop_top, video_source_crop_left; |
| u32 video_source_crop_bottom, video_source_crop_right; |
| s32 video_layer_top, video_layer_left; |
| s32 video_layer_width, video_layer_height; |
| #ifdef TV_REVERSE |
| bool reverse = false; |
| #endif |
| int ret = vppfilter_success; |
| u32 crop_ratio = 1; |
| u32 crop_left, crop_right, crop_top, crop_bottom; |
| bool no_compress = false; |
| u32 cur_super_debug = 0; |
| |
| if (!input) |
| return vppfilter_fail; |
| |
| if (vpp_flags & VPP_FLAG_MORE_LOG) |
| cur_super_debug = super_debug; |
| |
| video_layer_global_offset_x = input->global_offset_x; |
| video_layer_global_offset_y = input->global_offset_y; |
| |
| video_layer_top = input->layer_top; |
| video_layer_left = input->layer_left; |
| video_layer_width = input->layer_width; |
| video_layer_height = input->layer_height; |
| #ifdef TV_REVERSE |
| reverse = input->reverse; |
| #endif |
| |
| if ((vf->type & VIDTYPE_MVC) || |
| (input->proc_3d_type & MODE_3D_ENABLE)) { |
| video_source_crop_left = 0; |
| video_source_crop_right = 0; |
| video_source_crop_top = 0; |
| video_source_crop_bottom = 0; |
| } else { |
| video_source_crop_left = input->crop_left; |
| video_source_crop_right = input->crop_right; |
| video_source_crop_top = input->crop_top; |
| video_source_crop_bottom = input->crop_bottom; |
| } |
| |
| next_frame_par->vscale_skip_count = 0; |
| next_frame_par->hscale_skip_count = 0; |
| next_frame_par->nocomp = false; |
| if (vpp_flags & VPP_FLAG_INTERLACE_IN || |
| vpp_flags & VPP_FLAG_INTERLACE_OUT) |
| next_frame_par->vscale_skip_count++; |
| if (vpp_flags & VPP_FLAG_INTERLACE_OUT) |
| height_shift++; |
| |
| if (vpp_flags & VPP_FLAG_INTERLACE_IN) |
| vskip_step = 2; |
| else |
| vskip_step = 1; |
| |
| RESTART_ALL: |
| crop_left = video_source_crop_left / crop_ratio; |
| crop_right = video_source_crop_right / crop_ratio; |
| crop_top = video_source_crop_top / crop_ratio; |
| crop_bottom = video_source_crop_bottom / crop_ratio; |
| |
| if (likely(w_in > |
| (crop_left + crop_right))) { |
| w_in -= crop_left; |
| w_in -= crop_right; |
| h_crop_enable = true; |
| } |
| |
| if (likely(h_in > |
| (crop_top + crop_bottom))) { |
| h_in -= crop_top; |
| h_in -= crop_bottom; |
| v_crop_enable = true; |
| } |
| |
| RESTART: |
| /* don't use input->wide_mode */ |
| wide_mode = (vpp_flags & VPP_FLAG_WIDEMODE_MASK) >> VPP_WIDEMODE_BITS; |
| |
| /* |
| *if we have ever set a cropped display area for video layer |
| * (by checking video_layer_width/video_height), then |
| * it will override the input width_out/height_out for |
| * ratio calculations, a.k.a we have a window for video content |
| */ |
| video_top = video_layer_top; |
| video_left = video_layer_left; |
| video_width = video_layer_width; |
| video_height = video_layer_height; |
| if ((video_top == 0) && (video_left == 0) && (video_width <= 1) |
| && (video_height <= 1)) { |
| /* special case to do full screen display */ |
| video_width = video_layer_width; |
| video_height = video_layer_height; |
| } else { |
| video_top += video_layer_global_offset_y; |
| video_left += video_layer_global_offset_x; |
| } |
| |
| ratio_x = (1 << 18); |
| ratio_y = (1 << 18); |
| |
| /* screen position for source */ |
| start = video_top + (video_height + 1) / 2 - |
| ((h_in << 17) + |
| (ratio_y >> 1)) / ratio_y; |
| end = ((h_in << 18) + (ratio_y >> 1)) / ratio_y + start - 1; |
| if (cur_super_debug) |
| pr_info("layer%d: top:start =%d,%d,%d,%d %d,%d\n", |
| input->layer_id, |
| start, end, video_top, |
| video_height, h_in, ratio_y); |
| |
| #ifdef TV_REVERSE |
| if (reverse) { |
| /* calculate source vertical clip */ |
| if (video_top < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_y) >> 18; |
| next_frame_par->VPP_vd_end_lines_ = |
| h_in - 1 - temp; |
| } else |
| next_frame_par->VPP_vd_end_lines_ = h_in - 1; |
| } else { |
| if (start < video_top) { |
| temp = ((video_top - start) * ratio_y) >> 18; |
| next_frame_par->VPP_vd_end_lines_ = |
| h_in - 1 - temp; |
| } else |
| next_frame_par->VPP_vd_end_lines_ = h_in - 1; |
| } |
| temp = next_frame_par->VPP_vd_end_lines_ - |
| (video_height * ratio_y >> 18); |
| next_frame_par->VPP_vd_start_lines_ = (temp >= 0) ? temp : 0; |
| } else |
| #endif |
| { |
| if (video_top < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_y) >> 18; |
| next_frame_par->VPP_vd_start_lines_ = temp; |
| } else |
| next_frame_par->VPP_vd_start_lines_ = 0; |
| temp_height = min((video_top + video_height - 1), |
| (vinfo->height - 1)); |
| } else { |
| if (start < video_top) { |
| temp = ((video_top - start) * ratio_y) >> 18; |
| next_frame_par->VPP_vd_start_lines_ = temp; |
| } else |
| next_frame_par->VPP_vd_start_lines_ = 0; |
| temp_height = min((video_top + video_height - 1), |
| (vinfo->height - 1)) - video_top + 1; |
| } |
| temp = next_frame_par->VPP_vd_start_lines_ + |
| (temp_height * ratio_y >> 18); |
| next_frame_par->VPP_vd_end_lines_ = |
| (temp <= (h_in - 1)) ? temp : (h_in - 1); |
| } |
| |
| if (v_crop_enable) { |
| next_frame_par->VPP_vd_start_lines_ += crop_top; |
| next_frame_par->VPP_vd_end_lines_ += crop_top; |
| } |
| |
| if (vpp_flags & VPP_FLAG_INTERLACE_IN) |
| next_frame_par->VPP_vd_start_lines_ &= ~1; |
| |
| next_frame_par->VPP_pic_in_height_ = |
| next_frame_par->VPP_vd_end_lines_ - |
| next_frame_par->VPP_vd_start_lines_ + 1; |
| next_frame_par->VPP_pic_in_height_ = |
| next_frame_par->VPP_pic_in_height_ / |
| (next_frame_par->vscale_skip_count + 1); |
| |
| /* DI POST link, need make pps input size is even */ |
| if ((next_frame_par->VPP_pic_in_height_ & 1) && |
| (vf->type & VIDTYPE_PRE_INTERLACE) && |
| !(vf->type & VIDTYPE_DI_PW)) { |
| next_frame_par->VPP_pic_in_height_ &= ~1; |
| next_frame_par->VPP_vd_end_lines_ = |
| next_frame_par->VPP_pic_in_height_ * |
| (next_frame_par->vscale_skip_count + 1) + |
| next_frame_par->VPP_vd_start_lines_; |
| if (next_frame_par->VPP_vd_end_lines_ > 0) |
| next_frame_par->VPP_vd_end_lines_--; |
| } |
| /* |
| *find overlapped region between |
| *[start, end], [0, height_out-1], |
| *[video_top, video_top+video_height-1] |
| */ |
| start = max(start, max(0, video_top)); |
| end = min(end, min((s32)(vinfo->height - 1), |
| (s32)(video_top + video_height - 1))); |
| |
| if (start >= end) { |
| /* nothing to display */ |
| next_frame_par->VPP_vsc_startp = 0; |
| next_frame_par->VPP_vsc_endp = 0; |
| } else { |
| next_frame_par->VPP_vsc_startp = start; |
| next_frame_par->VPP_vsc_endp = end; |
| } |
| |
| /* set filter co-efficients */ |
| ratio_y <<= height_shift; |
| ratio_tmp = ratio_y / (next_frame_par->vscale_skip_count + 1); |
| ratio_y = ratio_tmp; |
| |
| filter->vpp_vsc_start_phase_step = 0x1000000; |
| |
| /* horizontal */ |
| filter->vpp_hf_start_phase_slope = 0; |
| filter->vpp_hf_end_phase_slope = 0; |
| filter->vpp_hf_start_phase_step = 0x1000000; |
| |
| next_frame_par->VPP_hsc_linear_startp = next_frame_par->VPP_hsc_startp; |
| next_frame_par->VPP_hsc_linear_endp = next_frame_par->VPP_hsc_endp; |
| |
| filter->vpp_hsc_start_phase_step = 0x1000000; |
| next_frame_par->VPP_hf_ini_phase_ = 0; |
| |
| /* screen position for source */ |
| start = video_left + (video_width + 1) / 2 - |
| ((w_in << 17) + (ratio_x >> 1)) / ratio_x; |
| end = ((w_in << 18) + (ratio_x >> 1)) / ratio_x + start - 1; |
| if (cur_super_debug) |
| pr_info("layer%d: left:start =%d,%d,%d,%d %d,%d\n", |
| input->layer_id, |
| start, end, video_left, |
| video_width, w_in, ratio_x); |
| |
| /* calculate source horizontal clip */ |
| #ifdef TV_REVERSE |
| if (reverse) { |
| if (video_left < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_x) >> 18; |
| next_frame_par->VPP_hd_end_lines_ = |
| w_in - 1 - temp; |
| } else |
| next_frame_par->VPP_hd_end_lines_ = w_in - 1; |
| } else { |
| if (start < video_left) { |
| temp = ((video_left - start) * ratio_x) >> 18; |
| next_frame_par->VPP_hd_end_lines_ = |
| w_in - 1 - temp; |
| } else |
| next_frame_par->VPP_hd_end_lines_ = w_in - 1; |
| } |
| temp = next_frame_par->VPP_hd_end_lines_ - |
| (video_width * ratio_x >> 18); |
| next_frame_par->VPP_hd_start_lines_ = (temp >= 0) ? temp : 0; |
| } else |
| #endif |
| { |
| if (video_left < 0) { |
| if (start < 0) { |
| temp = (-start * ratio_x) >> 18; |
| next_frame_par->VPP_hd_start_lines_ = temp; |
| |
| } else |
| next_frame_par->VPP_hd_start_lines_ = 0; |
| temp_width = min((video_left + video_width - 1), |
| (vinfo->width - 1)); |
| } else { |
| if (start < video_left) { |
| temp = ((video_left - start) * ratio_x) >> 18; |
| next_frame_par->VPP_hd_start_lines_ = temp; |
| |
| } else |
| next_frame_par->VPP_hd_start_lines_ = 0; |
| temp_width = min((video_left + video_width - 1), |
| (vinfo->width - 1)) - video_left + 1; |
| } |
| temp = next_frame_par->VPP_hd_start_lines_ + |
| (temp_width * ratio_x >> 18); |
| next_frame_par->VPP_hd_end_lines_ = |
| (temp <= (w_in - 1)) ? temp : (w_in - 1); |
| } |
| |
| if (h_crop_enable) { |
| next_frame_par->VPP_hd_start_lines_ += crop_left; |
| next_frame_par->VPP_hd_end_lines_ += crop_left; |
| } |
| |
| next_frame_par->VPP_line_in_length_ = |
| next_frame_par->VPP_hd_end_lines_ - |
| next_frame_par->VPP_hd_start_lines_ + 1; |
| /* |
| *find overlapped region between |
| * [start, end], [0, width_out-1], |
| * [video_left, video_left+video_width-1] |
| */ |
| start = max(start, max(0, video_left)); |
| end = min(end, |
| min((s32)(vinfo->width - 1), |
| (s32)(video_left + video_width - 1))); |
| |
| if (start >= end) { |
| /* nothing to display */ |
| next_frame_par->VPP_hsc_startp = 0; |
| next_frame_par->VPP_hsc_endp = 0; |
| /* avoid mif set wrong or di out size overflow */ |
| next_frame_par->VPP_hd_start_lines_ = 0; |
| next_frame_par->VPP_hd_end_lines_ = 0; |
| next_frame_par->VPP_line_in_length_ = 0; |
| } else { |
| next_frame_par->VPP_hsc_startp = start; |
| next_frame_par->VPP_hsc_endp = end; |
| } |
| |
| /* |
| *check the painful bandwidth limitation and see |
| * if we need skip half resolution on source side for progressive |
| * frames. |
| */ |
| /* check vskip and hskip */ |
| if (((next_frame_par->vscale_skip_count < MAX_VSKIP_COUNT) |
| || !next_frame_par->hscale_skip_count) |
| && (!(vpp_flags & VPP_FLAG_VSCALE_DISABLE))) { |
| int skip = SPEED_CHECK_DONE; |
| |
| if (skip == SPEED_CHECK_VSKIP) { |
| u32 next_vskip = |
| next_frame_par->vscale_skip_count + vskip_step; |
| |
| if (next_vskip <= MAX_VSKIP_COUNT) { |
| next_frame_par->vscale_skip_count = next_vskip; |
| goto RESTART; |
| } else |
| next_frame_par->hscale_skip_count = 1; |
| } else if (skip == SPEED_CHECK_HSKIP) |
| next_frame_par->hscale_skip_count = 1; |
| } |
| |
| if ((vf->type & VIDTYPE_COMPRESS) && |
| !(vf->type & VIDTYPE_NO_DW) && |
| (vf->canvas0Addr != 0) && |
| (!next_frame_par->nocomp)) { |
| if ((vpp_flags & VPP_FLAG_FORCE_NO_COMPRESS) |
| || (next_frame_par->vscale_skip_count > 1) |
| || !input->afbc_support |
| || force_no_compress) |
| no_compress = true; |
| } else |
| no_compress = false; |
| |
| if (no_compress) { |
| if ((vpp_flags & VPP_FLAG_MORE_LOG) |
| && input->afbc_support) |
| pr_info( |
| "layer%d: Try DW buffer for compressed frame scaling.\n", |
| input->layer_id); |
| |
| /* for VIDTYPE_COMPRESS, check if we can use double write |
| * buffer when primary frame can not be scaled. |
| */ |
| next_frame_par->nocomp = true; |
| w_in = width_in = vf->width; |
| h_in = height_in = vf->height; |
| next_frame_par->hscale_skip_count = 0; |
| next_frame_par->vscale_skip_count = 0; |
| if (vf->width && vf->compWidth) |
| crop_ratio = vf->compWidth / vf->width; |
| goto RESTART_ALL; |
| } |
| |
| if ((skip_policy & 0xf0) && (skip_policy_check == true)) { |
| skip_policy_check = false; |
| if (skip_policy & 0x40) { |
| next_frame_par->vscale_skip_count = skip_policy & 0xf; |
| goto RESTART; |
| } |
| } |
| |
| next_frame_par->video_input_h = next_frame_par->VPP_vd_end_lines_ - |
| next_frame_par->VPP_vd_start_lines_ + 1; |
| next_frame_par->video_input_h = next_frame_par->video_input_h / |
| (next_frame_par->vscale_skip_count + 1); |
| next_frame_par->video_input_w = next_frame_par->VPP_hd_end_lines_ - |
| next_frame_par->VPP_hd_start_lines_ + 1; |
| next_frame_par->video_input_w = next_frame_par->video_input_w / |
| (next_frame_par->hscale_skip_count + 1); |
| |
| filter->vpp_hsc_start_phase_step = 0x1000000; |
| |
| /* apply line skip */ |
| if (next_frame_par->hscale_skip_count) { |
| filter->vpp_hf_start_phase_step >>= 1; |
| filter->vpp_hsc_start_phase_step >>= 1; |
| next_frame_par->VPP_line_in_length_ >>= 1; |
| } |
| |
| if ((next_frame_par->vscale_skip_count > 1) |
| && (vf->type & VIDTYPE_COMPRESS) |
| && (vf->type & VIDTYPE_NO_DW)) |
| ret = vppfilter_changed_but_hold; |
| return ret; |
| } |
| |
| int vpp_set_filters( |
| struct disp_info_s *input, |
| struct vframe_s *vf, |
| struct vpp_frame_par_s *next_frame_par, |
| const struct vinfo_s *vinfo, |
| bool bypass_sr, u32 op_flag) |
| { |
| u32 src_width = 0; |
| u32 src_height = 0; |
| u32 vpp_flags = 0; |
| u32 aspect_ratio = 0; |
| u32 process_3d_type; |
| u32 wide_mode; |
| int ret = vppfilter_fail; |
| struct disp_info_s local_input; |
| bool bypass_sr0 = bypass_sr; |
| bool bypass_sr1 = bypass_sr; |
| |
| if (!input) |
| return ret; |
| |
| WARN_ON(vinfo == NULL); |
| |
| /* use local var to avoid the input data be overwriten */ |
| memcpy(&local_input, input, sizeof(struct disp_info_s)); |
| |
| process_3d_type = local_input.proc_3d_type; |
| wide_mode = local_input.wide_mode; |
| |
| next_frame_par->VPP_post_blend_vd_v_start_ = 0; |
| next_frame_par->VPP_post_blend_vd_h_start_ = 0; |
| |
| next_frame_par->VPP_postproc_misc_ = 0x200; |
| next_frame_par->vscale_skip_count = 0; |
| next_frame_par->hscale_skip_count = 0; |
| |
| if (vf->type & VIDTYPE_COMPRESS) { |
| src_width = vf->compWidth; |
| src_height = vf->compHeight; |
| } else { |
| src_width = vf->width; |
| src_height = vf->height; |
| } |
| |
| #ifdef TV_3D_FUNCTION_OPEN |
| /* |
| *check 3d mode change in display buffer or 3d type |
| *get the source size according to 3d mode |
| */ |
| if (local_input.layer_id == 0) { |
| if (process_3d_type & MODE_3D_ENABLE) { |
| vpp_get_video_source_size( |
| &src_width, &src_height, |
| process_3d_type, |
| vf, next_frame_par); |
| } else { |
| next_frame_par->vpp_3d_mode = |
| VPP_3D_MODE_NULL; |
| next_frame_par->vpp_2pic_mode = 0; |
| next_frame_par->vpp_3d_scale = 0; |
| } |
| next_frame_par->trans_fmt = vf->trans_fmt; |
| get_vpp_3d_mode(process_3d_type, |
| next_frame_par->trans_fmt, |
| &next_frame_par->vpp_3d_mode); |
| if (local_input.vpp_3d_scale) |
| next_frame_par->vpp_3d_scale = 1; |
| } else { |
| next_frame_par->vpp_3d_mode = VPP_3D_MODE_NULL; |
| next_frame_par->vpp_2pic_mode = 0; |
| next_frame_par->vpp_3d_scale = 0; |
| next_frame_par->trans_fmt = vf->trans_fmt; |
| } |
| amlog_mask(LOG_MASK_VPP, "%s: src_width %u,src_height %u.\n", __func__, |
| src_width, src_height); |
| #endif |
| /* check force ratio change flag in display buffer also |
| * if it exist then it will override the settings in display side |
| */ |
| if (vf->ratio_control & DISP_RATIO_FORCECONFIG) { |
| if ((vf->ratio_control & DISP_RATIO_CTRL_MASK) == |
| DISP_RATIO_KEEPRATIO) { |
| if (wide_mode == VIDEO_WIDEOPTION_FULL_STRETCH) |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| } else { |
| if (wide_mode == VIDEO_WIDEOPTION_NORMAL) |
| wide_mode = VIDEO_WIDEOPTION_FULL_STRETCH; |
| } |
| if (vf->ratio_control & DISP_RATIO_FORCE_NORMALWIDE) |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| else if (vf->ratio_control & DISP_RATIO_FORCE_FULL_STRETCH) |
| wide_mode = VIDEO_WIDEOPTION_FULL_STRETCH; |
| } |
| |
| aspect_ratio = (vf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK) |
| >> DISP_RATIO_ASPECT_RATIO_BIT; |
| |
| if (!aspect_ratio) { |
| u32 sar_width, sar_height; |
| |
| if (vf->type & VIDTYPE_COMPRESS) { |
| sar_width = vf->compWidth; |
| sar_height = vf->compHeight; |
| } else { |
| sar_width = vf->width; |
| sar_height = vf->height; |
| } |
| aspect_ratio = (sar_height << 8) / sar_width; |
| } |
| /* the height from vdin afbc will be half */ |
| /* so need no interlace in */ |
| if ((vf->type & VIDTYPE_INTERLACE) |
| && !(vf->type & VIDTYPE_COMPRESS)) |
| vpp_flags = VPP_FLAG_INTERLACE_IN; |
| |
| if (vf->ratio_control & DISP_RATIO_PORTRAIT_MODE) |
| vpp_flags |= VPP_FLAG_PORTRAIT_MODE; |
| |
| if (vf->type & VIDTYPE_VSCALE_DISABLE) |
| vpp_flags |= VPP_FLAG_VSCALE_DISABLE; |
| |
| if ((vf->ratio_control & DISP_RATIO_ADAPTED_PICMODE) |
| && !disable_adapted) { |
| if (vf->pic_mode.screen_mode != 0xff) |
| wide_mode = vf->pic_mode.screen_mode; |
| |
| if (vf->pic_mode.AFD_enable |
| && (vf->ratio_control & DISP_RATIO_INFOFRAME_AVAIL)) |
| wide_mode = VIDEO_WIDEOPTION_AFD; |
| if (wide_mode == VIDEO_WIDEOPTION_CUSTOM) { |
| if (custom_ar) |
| local_input.custom_ar = custom_ar; |
| else |
| local_input.custom_ar = |
| vf->pic_mode.custom_ar; |
| } |
| |
| local_input.crop_top = vf->pic_mode.vs; |
| local_input.crop_left = vf->pic_mode.hs; |
| local_input.crop_bottom = vf->pic_mode.ve; |
| local_input.crop_right = vf->pic_mode.he; |
| } |
| |
| if (!local_input.pps_support) |
| wide_mode = VIDEO_WIDEOPTION_NORMAL; |
| |
| /* don't restore the wide mode */ |
| /* input->wide_mode = wide_mode; */ |
| vpp_flags |= (wide_mode << VPP_WIDEMODE_BITS) | |
| (aspect_ratio << VPP_FLAG_AR_BITS); |
| |
| if (vinfo->field_height != vinfo->height) |
| vpp_flags |= VPP_FLAG_INTERLACE_OUT; |
| |
| if (op_flag & 1) |
| vpp_flags |= VPP_FLAG_MORE_LOG; |
| |
| if (local_input.need_no_compress) |
| vpp_flags |= VPP_FLAG_FORCE_NO_COMPRESS; |
| |
| next_frame_par->VPP_post_blend_vd_v_end_ = vinfo->field_height - 1; |
| next_frame_par->VPP_post_blend_vd_h_end_ = vinfo->width - 1; |
| next_frame_par->VPP_post_blend_h_size_ = vinfo->width; |
| |
| if (local_input.pps_support) |
| ret = vpp_set_filters_internal( |
| &local_input, src_width, src_height, |
| vinfo->width, vinfo->height, |
| vinfo, vpp_flags, next_frame_par, vf); |
| else |
| ret = vpp_set_filters_no_scaler_internal( |
| &local_input, src_width, src_height, |
| vinfo->width, vinfo->height, |
| vinfo, vpp_flags, next_frame_par, vf); |
| |
| /* bypass sr since the input w/h may be wrong */ |
| if (ret == vppfilter_changed_but_hold) { |
| bypass_sr0 = true; |
| bypass_sr1 = true; |
| } |
| /*config super scaler after set next_frame_par is calc ok for pps*/ |
| if (is_meson_tl1_cpu()) { |
| /* disable sr0 when afbc, width >1920 and crop more than half */ |
| if ((vf->type & VIDTYPE_COMPRESS) |
| && (!next_frame_par->nocomp) |
| && (vf->compWidth > 1920) |
| && ((next_frame_par->video_input_w |
| << (next_frame_par->hscale_skip_count + 1)) |
| <= vf->compWidth)) |
| bypass_sr0 = true; |
| } |
| if (local_input.layer_id == 0) { |
| vpp_set_super_scaler( |
| wide_mode, |
| vinfo, next_frame_par, |
| (bypass_sr0 | bypass_spscl0), |
| (bypass_sr1 | bypass_spscl1), |
| vpp_flags); |
| /* cm input size will be set in super scaler function */ |
| } else { |
| if (local_input.pps_support) { |
| next_frame_par->cm_input_w = |
| next_frame_par->VPP_hsc_endp |
| - next_frame_par->VPP_hsc_startp + 1; |
| next_frame_par->cm_input_h = |
| next_frame_par->VPP_vsc_endp |
| - next_frame_par->VPP_vsc_startp + 1; |
| } else { |
| next_frame_par->cm_input_w = |
| next_frame_par->video_input_w; |
| next_frame_par->cm_input_h = |
| next_frame_par->video_input_h; |
| } |
| } |
| return ret; |
| } |
| |
| s32 vpp_set_nonlinear_factor( |
| struct disp_info_s *info, u32 f) |
| { |
| if (f < MAX_NONLINEAR_FACTOR) { |
| info->nonlinear_factor = f; |
| return 0; |
| } |
| return -1; |
| } |
| |
| u32 vpp_get_nonlinear_factor( |
| struct disp_info_s *info) |
| { |
| return info->nonlinear_factor; |
| } |
| |
| s32 vpp_set_nonlinear_t_factor(struct disp_info_s *info, u32 f) |
| { |
| if (f < MAX_NONLINEAR_T_FACTOR) { |
| info->nonlinear_t_factor = f; |
| return 0; |
| } |
| return -1; |
| } |
| |
| u32 vpp_get_nonlinear_t_factor(struct disp_info_s *info) |
| { |
| return info->nonlinear_t_factor; |
| } |
| |
| void vpp_disp_info_init( |
| struct disp_info_s *info, u8 id) |
| { |
| if (info) { |
| memset(info, 0, sizeof(struct disp_info_s)); |
| info->nonlinear_factor = MAX_NONLINEAR_FACTOR / 2; |
| info->nonlinear_t_factor = MAX_NONLINEAR_T_FACTOR - 10; |
| info->zoom_ratio = 100; |
| info->speed_check_width = 1800; |
| info->speed_check_height = 1400; |
| info->layer_id = id; |
| memset(&gfilter[id], 0, sizeof(struct filter_info_s)); |
| } |
| } |
| |
| void vpp_super_scaler_support(void) |
| { |
| struct sr_info_s *sr; |
| |
| sr = &sr_info; |
| if (super_scaler == 0) { |
| sr->sr_support &= ~SUPER_CORE0_SUPPORT; |
| sr->sr_support &= ~SUPER_CORE1_SUPPORT; |
| } |
| } |
| /*for gxlx only have core1 which will affact pip line*/ |
| void vpp_bypass_ratio_config(void) |
| { |
| if (is_meson_gxbb_cpu() || is_meson_gxl_cpu() || |
| is_meson_gxm_cpu()) |
| bypass_ratio = 125; |
| else if (is_meson_txlx_cpu()) |
| /*change from 247 to 210 for bandwidth @20180627*/ |
| bypass_ratio = 210; |
| else if (is_meson_txl_cpu()) |
| bypass_ratio = 247;/*0x110 * (100/110)=0xf7*/ |
| else |
| bypass_ratio = 205; |
| } |
| |
| |