From 95c94bb7cba0c7328019549ecaeaebd3dc3460f8 Mon Sep 17 00:00:00 2001 From: Xuhua Zhang Date: Fri, 16 Nov 2018 14:23:10 +0800 Subject: [PATCH] tvin: vdin: tl1 improve vdin afbce function [1/1] PD#172587 Problem: vdin afbce can not work well Solution: change afbce work mode Verify: verify on tl1 Change-Id: I3e980c7488bd8a0eb6f043fd1fb2d2b2bc75140f Signed-off-by: Xuhua Zhang 8adc242 tvafe: add control for tvconfig snow config [1/1] 190d82f cvbs: cvbsoutput support for tl1 [1/1] 3e859c8 vdin: add dolby mem release protection [1/1] ba57ce5 vdin: G12A color space error when capture screen by post blend [1/1] 768c100 vdin: add new interface for passing dma-buf to vdin [1/1] f24b329 vdin: QD980 HDMI 4k 30Hz,change bit depth has green screen [1/1] a8c6962 vdin: add afbce reg access protection [1/1] 874fe722 vdin: support afbc/non-afbc switch dynamically [1/1] 321d0bc vdin: revert ignore v4l2start/stop ioctl when vdin1 used for preview [1/1] 05df311 vdin: disable afbce under 4k resolution [1/1] 3038cb8 vdin: recycle garbage frame for afbc mode [1/1] fbb84a75 vdin: support dynamic dest_cfmt changing [1/1] 81c1e14 vdin: ignore v4l2start/stop ioctl when vdin1 used for preview [1/1] bab3adb tvafe: add av/atv/cvbs support for tm2 [1/1] 2c05842 vdin: add vdin support for tm2 [1/1] 5a825f1 vdin: config vdin mif/afbc path directly [1/1] 3cb9517 vdin: sync vdin0 & vdin1 buffer for afbc mode to avoid garbage screen [1/1] d1f8149 vdin: fixed the issue of mem mapping from vmap. [1/1] 0b049e1 vdin: add sm1 support [1/1] bfc5e18 vdin: fix vdin1 dest_cfmt for tl1 afbc preview support [1/1] ded6424 tvin: vdin: add vdin1 scaler preview for vdin0 preview [1/1] b23ca7b vdin: optimize game mode for tl1 phase lock [1/1] 2a95ff7 vlock: add phase lock function [1/1] 51822f9 vlock: screen flash after PAL NTSC swich [1/1] 315f6d3 vlock: vlock for tl1 [1/1] 7f3b8d9 vdin: fix snowflake bottom screen [1/1] c2a4eaf tvafe: optimize stable time on manual setting [1/1] c05cefd tvin: vdin: add interface to get signalinfo [1/1] 5c5d26c tvin: vdin: fix vdin histgram error on tl1 [1/1] 7c0701b tvin: vdin: fix dolby vision memory free print error [1/1] a510d76 tvin: vdin: fix system crash when dolby vision enable [1/1] 2f1ba00 vdin: add vdin1 histgram [1/1] f5abdd8 tvin: vdin: fix TXLX ATv channel switching crash [1/1] 8d1a496 vdin: tl1: add viu loop back vpp path [1/1] 63f1b85 tvin: vdin: add vdin afbce memory power ctrl [1/1] 211b677 hdmirx: add allm mode. [1/2] 2afb3d7 tvafe: fix black border for atv [1/1] ced9632 tvin: vdin: fix afbce 576p color anomaly [1/1] f00295ae tvin: vdin: fix afbce 4k yuv444 display error [1/1] 1fef799 tvin: vdin: vdin add afbce write back to memory interface [1/1] 482e11b tvin: vdin: fix vdin CMA layout adaptation [1/1] 87d67d8 tvin: vdin: vdin afbce fix header size bug [1/1] f938eed vdin: optimize game mode process [1/1] 6e847e0 tvin: vdin: hdmirx format change, display exception [1/1] 4c7bb63 tvin: vdin: tl1 improve vdin function [1/1] 8850ab8 tvin: vdin: tl1 improve vdin afbce function [1/1] tvin: vdin: tl1 improve vdin function [1/1] PD#172587 Problem: 1.in the afbce mode, screen flicker when serial port print too many debugging information 2.vdin afbce 4K crash 3.viu loop back error 4.need afbce lossy mode Solution: 1.vdin use rdma mode 2.change vdin afbce buff size 3.change VDIN_ASFIFO_CTRL3 register 4.add lossy mode Verify: x301 Change-Id: Id66c0d7df22a9aeaca15d645f9a2ce0ecf47be3f Signed-off-by: Xuhua Zhang Signed-off-by: Luan Yuan tvin: vdin: hdmirx format change, display exception [1/1] PD#SWPL-2411 Problem: hdmirx input 4096X2160 yuv422 in a short period of time, formate change form yuv422 to yuv444, screen display is exception. Solution: force malloc yuv444 size Verify: Verify on txlx r311 Change-Id: Ie670b9a2b0c1eceffe423a1cf8606e78b6b347cd Signed-off-by: Xuhua Zhang vdin: optimize game mode process [1/1] PD#SWPL-2145 Problem: HDMI Rx Video path display latency of Game mode and Normal mode Solution: optimize game mode Verify: T962X-R311 Change-Id: Ib0a41915dfb088495c976d56ab812f90e31602f4 Signed-off-by: Dezhi Kong tvin: vdin: vdin afbce fix header size bug [1/1] PD#SWPL-3208 Problem: vdin afbce scaler, display abnormal. Solution: fix afbce header size problem. Verify: TL1 X301 Change-Id: I461b4aa809ceddbe18cf7f6f49e8152b43b86076 Signed-off-by: Xuhua Zhang tvin: vdin: fix vdin CMA layout adaptation [1/1] PD#SWPL-2526 Problem: 1.CMA layout adaptation cause crash 2.vdin buff dump error 3.read_pic error Solution: 1.codec mm has be moved to high memory area, we should map memory use vmap. 2.make vdin high mem and low mem to be compatible when we dump vdin buff. 3.fix read_pic bug. Verify: TXLX R311 Change-Id: I90e4f46ba91d38c6ce0f8bfd65b5c22e6be3b83f Signed-off-by: Xuhua Zhang tvin: vdin: vdin add afbce write back to memory interface [1/1] PD#SWPL-3200 Problem: vdin add afbce need more debug method. Solution: vdin add read_pic_afbce debug interface Verify: TL1 X301 Change-Id: I45a741ba20409dc25b41ce316b0df0dce9d2dc28 Signed-off-by: Xuhua Zhang tvin: vdin: fix afbce 4k yuv444 display error [1/1] PD#SWPL-3429 Problem: vdin output format is afbce 4k yuv444,it display ghost shadow of image Solution: add afbce comb control Verify: x301 Change-Id: I168f13994a4929bd227ba70b006f259ac0726238 Signed-off-by: Xuhua Zhang tvin: vdin: fix afbce 576p color anomaly [1/1] PD#SWPL-3424 Problem: dvd play 576p media, tl1 display color anomaly Solution: encoder use same default color setting with decoder Verify: x301 Change-Id: I8954874ea048b2d9e9b7aa58c883da1f306c4459 Signed-off-by: Xuhua Zhang tvafe: fix black border for atv [1/1] PD#SWPL-3573 Problem: appear black border after unplug/plug signal Solution: reset de when nosignal restore acd hsync when signal unstable Verify: verified by x301 Change-Id: Ia9e2e9dfb326061bd3b9b6f9a02be0d935cdf06f Signed-off-by: Nian Jing hdmirx: add allm mode. [1/2] PD#SWPL-1619 Problem: need support allm mode Solution: add allm mode Verify: None Change-Id: I34d05cfbef4b3fccbbb7c6b35fa613cda9b9cf36 Signed-off-by: yicheng shen Signed-off-by: Luan Yuan tvin: vdin: add vdin afbce memory power ctrl [1/1] PD#SWPL-3635 Problem: Miss vdin afbce memory power ctrl. Solution: Add vdin afbce memory power ctrl. Verify: x301_tl1 Change-Id: I94946e3d16027083688735d68b9d023b6bc5c8bf Signed-off-by: Xuhua Zhang vdin: tl1: add viu loop back vpp path [1/1] PD#SWPL-2676 Problem: tl1 viu loop back error Solution: add viu loop back vpp path Verify: TL1 X301 Change-Id: I4069f6bbd6672d89bd93a0c8b275cfffc273c427 Signed-off-by: Xuhua Zhang tvin: vdin: fix TXLX ATv channel switching crash [1/1] PD#SWPL-3964 Problem: ATv channel switching crash Solution: stop vdin, close afbc need judge platform, there is not afbce on txlx Verify: verify by einstein Change-Id: Ibcff1da47b9fdca7e1758b0d45e7d6800bfc8080 Signed-off-by: Xuhua Zhang vdin: add vdin1 histgram [1/1] PD#SWPL-3059 Problem: vdin1 hisgram and screencap cannot be used simultaneously Solution: add vdin1 histgram,and make hist and screencap function to be compatible Verify: txlx r311 Change-Id: I759d1cdc69d59015ce845898990088eb6943cc41 Signed-off-by: xuhua zhang tvin: vdin: fix system crash when dolby vision enable [1/1] PD#SWPL-3353 Problem: system crash when dolby vision enable Solution: 32bit kernel,phy addr to virt interface is changed Verify: Verified on txlx R311 Change-Id: Ie012bdaf7f9dc24acf7a7e03f0db056ff31e578c Signed-off-by: Xuhua Zhang tvin: vdin: fix dolby vision memory free print error [1/1] PD#SWPL-3353 Problem: dolby vision memory free print error Solution: dolby vision memory has been free by vdin_cma_release, don't free again. Verify: test pass on R311 Change-Id: Id7108cf17260430c53dff707e843ed7833c8ee7c Signed-off-by: Xuhua Zhang tvin: vdin: fix vdin histgram error on tl1 [1/1] PD#TV-2263 Problem: vdin histgram error on tl1 Solution: tl1 use TVIN_PORT_VIU1_WB0_VPP Verify: verify on tl1 Change-Id: I225a85a1debee0e8c42f60751524661fc5c986bd Signed-off-by: Xuhua Zhang tvin: vdin: add interface to get signalinfo [1/1] PD#TV-2083 Problem: TVIN_IOC_G_SIG_INFO not complete enough Solution: add interface to get signalinfo Verify: Verify on TL1 Change-Id: I32f198f14dfcc1f8a8ee1f19c4065bd7d4d5dccc Signed-off-by: Xuhua Zhang tvafe: optimize stable time on manual setting [1/1] PD#SWPL-5052 Problem: optimize swith channel time Solution: lower wait time on manual colorfmt setting stable time optimized from 500ms -> 300ms Verify: x301 Change-Id: I7e7d711d1c3ab0630d41e933c53ce34d0025e860 Signed-off-by: Nian Jing vdin: fix snowflake bottom screen [1/1] PD#SWPL-5129 Problem: cut window need restore when nosignal Solution: restore cutwin when nosignal Verify: verified by r341 Change-Id: If18dbd18df11cce5d1ddb99ee266901b75b065b3 Signed-off-by: Nian Jing vlock: vlock for tl1 [1/1] PD#SWPL-3129 Problem: 1.verify manual pll mode 2.modify vlock hiu register access api 3.add a new fsm for tl1 test 4.add chip match data Solution: add function for tl1 Verify: verified on tl1 Change-Id: I75f8d2a40437056135f8dd0fb241016a9ea680df Signed-off-by: Yong Qin Signed-off-by: Luan Yuan vlock: screen flash after PAL NTSC swich [1/1] PD#SWPL-4246 Problem: the screen always flash after switch PAL to NTSC in AVin Solution: do not change pll M value, M value will case v by one fail Verify: verified on tl1 android p Change-Id: Ib5ea8dfef1c40af5535e69fdc9241a7f77b4a7dd Signed-off-by: Yong Qin vlock: add phase lock function [1/1] PD#SWPL-3644 Problem: new feature on tl1 Solution: add function Verify: verified on tl1 android p Change-Id: I964054512f59a98f03d20df11b8c63d6802744d5 Signed-off-by: Yong Qin vdin: optimize game mode for tl1 phase lock [1/1] PD#SWPL-4788 Problem: sometimes hdmi source display broken in game mode Solution: use phase lock for tl1 game mode ahead 2 frames, and ahead 1 frame for previous chips. Verify: x301 Change-Id: I00df9125c9ea7869ed6e111ba99a8b755c914129 Signed-off-by: Evoke Zhang tvin: vdin: add vdin1 scaler preview for vdin0 preview [1/1] PD#SWPL-4115 Problem: vdin preview error when input 4K Solution: use vdin1 as double write function Verify: x301 Change-Id: I4ed15dd5c445ed3c38b4a2535be075210dcbdac7 Signed-off-by: Xuhua Zhang vdin: fix vdin1 dest_cfmt for tl1 afbc preview support [1/1] PD#SWPL-5971 Problem: preview window color is green with 1080p & 4k hdmirx Solution: vdin1 dest_cfmt follow vdin0 for the software double write for preview Verify: x301 Change-Id: I2e45b5f838cddcac1ca1c4e6710a7cc1f45ae9b5 Signed-off-by: Evoke Zhang vdin: add sm1 support [1/1] PD#SWPL-6065 Problem: need add vdin support for sm1 Solution: add vdin support for sm1 Verify: pxp Change-Id: I55af5273607a88f4e5a2394de0acbb44811da8f9 Signed-off-by: Evoke Zhang vdin: fixed the issue of mem mapping from vmap. [1/1] PD#SWPL-6196 Problem: the memory issue cause to kernel crash. Solution: 1. add flush cache when the mem oper end. 2. unmap addr which from vmap in vdin driver. Verify: X301 Change-Id: Id6efe2b009fe64ad753d51eb06784bd4e66f5e87 Signed-off-by: Nanxin Qin vdin: sync vdin0 & vdin1 buffer for afbc mode to avoid garbage screen [1/1] PD#SWPL-3431 Problem: enter hdmi 4k port will flash garbage screen with afbc mode Solution: sync vdin0 & vdin1 buffer for afbc mode Verify: x301 Change-Id: I443a9be2ed619a5cd2b6229f15814d8b856c5535 Signed-off-by: Evoke Zhang vdin: config vdin mif/afbc path directly [1/1] PD#SWPL-6277 Problem: switch hdmi port maybe display green screen Solution: 1.optimize vdin stop sequence, reduce afbc state polling interval, and rest afbc to get a clean state 2.change vdin mif/afbc patch directly, not rdma method, for vdin0/1 rdma are independent Verify: x301 Change-Id: I0ddf5d27dcfc0fd930eeb681f876c4c5e92e8d70 Signed-off-by: Evoke Zhang vdin: add vdin support for tm2 [1/1] PD#SWPL-6701 Problem: Need vdin supprt for sm2 Solution: add vdin support for tm2 Verify: test pass on tm2 ab311 Change-Id: I57d7b3014938011d18c5e168f18c78e4fa542fc7 Signed-off-by: Nian Jing tvafe: add av/atv/cvbs support for tm2 [1/1] PD#:SWPL-6702 Problem: tm2 bringup Solution: add av/atv/cvbs support for tm2 Verify: tm2 T962E2 Change-Id: I1c7358cd17463843fbdd7a93c7416a22aaa2387c Signed-off-by: Nian Jing Signed-off-by: Luan Yuan vdin: ignore v4l2start/stop ioctl when vdin1 used for preview [1/1] PD#SWPL-6840 Problem: hdmi port can't screencap Solution: ignore v4l2start/stop ioctl when vdin1 used for preview Verify: x301 Change-Id: I26e7b057177a0b7ed203c04bd3008c2a34793b4a Signed-off-by: Evoke Zhang vdin: support dynamic dest_cfmt changing [1/1] PD#TV-4306 Problem: vdin afbc will show green screen when hdmirx change dest_cfmt after stable Solution: dynamic config vdin afbc with cfmt Verify: x301 Change-Id: I404c47934f090222a2cdd7cf98b619826cd92cc7 Signed-off-by: Evoke Zhang vdin: recycle garbage frame for afbc mode [1/1] PD#TV-4335 Problem: switch tvin signals will flash garbage screen Solution: recycle barbage frame for afbc mode Verify: x301 Change-Id: I17c13b5db7a506403aa5ac74568b7a9e16c075c0 Signed-off-by: Evoke Zhang vdin: disable afbce under 4k resolution [1/1] PD#SWPL-7511 Problem: no need enable vdin afbce under 4k, it is no help for bandwidth with these resolution Solution: only enable vdin afbce for 4k resolution Verify: x301 Change-Id: I283efd872004846d158ef6c9addbd1e666d2f61a Signed-off-by: Evoke Zhang vdin: revert ignore v4l2start/stop ioctl when vdin1 used for preview [1/1] PD#SWPL-7324 Problem: tvafe work abnormal when use vdin1 preview Solution: revert the previous commit for v4l2start/stop Verify: x301 This reverts commit 81c1e1449c5e7362dc263bea76e134ba8fd25265. Change-Id: I8cdefececb8b01cb86426684a6c700bc9bf8b615 Signed-off-by: Evoke Zhang vdin: support afbc/non-afbc switch dynamically [1/1] PD#SWPL-7512 Problem: need switch vdin afbc/non-afbc mode sometime Solution: support afbc/non-afbc switch dynamically Verify: x301 Change-Id: I08433938f169a51ed1ed7a23fd99f3ba42e076fe Signed-off-by: Evoke Zhang Signed-off-by: Luan Yuan vdin: add afbce reg access protection [1/1] PD#SWPL-7983 Problem: txlx will crash when access afbce reg without afbce hw Solution: add afbce reg access protection Verify: r311 Change-Id: Iaabf8da9cb2a58e9c26626b9ac718bdf9c6a2ac3 Signed-off-by: Evoke Zhang vdin: QD980 HDMI 4k 30Hz,change bit depth has green screen [1/1] PD#SWPL-8184 Problem: don't updated afbce output color format Solution: update afbce config according afbce support or not, instead of afbce need or not. Verify: verified by t962x2_x301 Change-Id: I7885357c1e5b04b58b059401a5f66d2ee83c76ef Signed-off-by: zhiwei.yuan vdin: add new interface for passing dma-buf to vdin [1/1] PD#TV-3863 Problem: gpu cann't get vdin buf directly Solution: vdin write data to the addr passed by upper layer Verify: verified by t962x2_x301 Change-Id: I495b78c419e10a6dacb9b9f29c0f8e87339ac195 Signed-off-by: zhiwei.yuan Signed-off-by: Luan Yuan vdin: G12A color space error when capture screen by post blend [1/1] PD#SWPL-8335 Problem: color space setting error Solution: set yuv444 when use viu1 post blend port Verify: verified by t962x2_x301 Change-Id: Ic92a6db92f6cec64084d140c5f505489579b294f Signed-off-by: zhiwei.yuan vdin: add dolby mem release protection [1/1] PD#SWPL-8797 Problem: sometime oops occurred for vdin_dolby mem release Solution: add vdin dolby mem alloc flag & release protection Verify: x301 Change-Id: Iee90b58a0624c32032e204adcd043c8e94d03f1f Signed-off-by: Evoke Zhang cvbs: cvbsoutput support for tl1 [1/1] PD#172587 Problem: no cvbsoutput Solution: add cvbsoutput Verify: test pass on x301 Change-Id: I92f70d26e32f95de7c63ddbac9fe6664063c1902 Signed-off-by: Nian Jing Signed-off-by: Luan Yuan tvafe: add control for tvconfig snow config [1/1] PD#SWPL-5985 Problem: display snow when snow config disabled Solution: add control for tvconfig snow config Verify: verify it on x301 Change-Id: I3466efc98577f2403f3a6cd638ad7dbf70ce34dc Signed-off-by: Nian Jing Signed-off-by: Luan Yuan --- arch/arm/boot/dts/amlogic/mesontm2.dtsi | 2 +- arch/arm/boot/dts/amlogic/tl1_pxp.dts | 6 +- arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts | 6 +- arch/arm64/boot/dts/amlogic/mesontm2.dtsi | 2 +- drivers/amlogic/clk/tl1/tl1.h | 2 + drivers/amlogic/media/enhancement/amvecm/amvecm.c | 103 +- .../media/enhancement/amvecm/amvecm_vlock_regmap.h | 26 +- .../media/enhancement/amvecm/arch/vpp_regs.h | 24 +- drivers/amlogic/media/enhancement/amvecm/vlock.c | 1185 +++++++++++++++++--- drivers/amlogic/media/enhancement/amvecm/vlock.h | 84 +- .../amlogic/media/video_processor/pic_dev/picdec.c | 2 + .../media/video_processor/video_dev/amlvideo2.c | 1 + drivers/amlogic/media/video_sink/video.c | 3 + .../amlogic/media/vin/tvin/bt656/bt656_601_in.c | 3 +- .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c | 11 + .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h | 11 +- drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c | 2 + drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h | 2 + .../media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c | 4 + .../media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h | 13 +- drivers/amlogic/media/vin/tvin/tvafe/tvafe.c | 69 +- drivers/amlogic/media/vin/tvin/tvafe/tvafe.h | 5 +- .../media/vin/tvin/tvafe/tvafe_avin_detect.c | 8 + .../media/vin/tvin/tvafe/tvafe_avin_detect.h | 1 + drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c | 35 +- drivers/amlogic/media/vin/tvin/tvafe/tvafe_debug.c | 12 + .../amlogic/media/vin/tvin/tvafe/tvafe_general.c | 36 +- .../amlogic/media/vin/tvin/tvafe/tvafe_general.h | 1 + drivers/amlogic/media/vin/tvin/tvin_global.h | 23 + drivers/amlogic/media/vin/tvin/vdin/Makefile | 5 + drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c | 637 +++++------ drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h | 14 +- drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c | 239 +++- drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h | 4 +- drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c | 300 ++++- drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h | 16 +- drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c | 706 ++++++++---- drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c | 1052 ++++++++++++++--- drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h | 87 +- drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c | 15 +- drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h | 3 + drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c | 8 +- drivers/amlogic/media/vin/tvin/viu/viuin.c | 48 +- drivers/amlogic/media/vout/cvbs/cvbs_out.c | 9 + drivers/amlogic/media/vout/cvbs/cvbs_out.h | 1 + drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h | 7 + drivers/amlogic/media/vout/cvbs/enc_clk_config.c | 28 + drivers/amlogic/media/vout/vdac/vdac_dev.c | 21 +- include/linux/amlogic/media/amvecm/amvecm.h | 23 + .../linux/amlogic/media/frame_provider/tvin/tvin.h | 25 +- .../amlogic/media/frame_provider/tvin/tvin_v4l2.h | 5 + include/linux/amlogic/media/vfm/vframe.h | 5 +- include/linux/amlogic/media/vfm/vframe_provider.h | 1 + include/linux/amlogic/media/vout/vdac_dev.h | 1 + 54 files changed, 3888 insertions(+), 1054 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/mesontm2.dtsi b/arch/arm/boot/dts/amlogic/mesontm2.dtsi index 0ff7ebf..2d642da 100644 --- a/arch/arm/boot/dts/amlogic/mesontm2.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontm2.dtsi @@ -1354,7 +1354,7 @@ }; vdac { - compatible = "amlogic, vdac-tl1"; + compatible = "amlogic, vdac-tm2"; status = "okay"; }; diff --git a/arch/arm/boot/dts/amlogic/tl1_pxp.dts b/arch/arm/boot/dts/amlogic/tl1_pxp.dts index 92a55d7..e90bb20 100644 --- a/arch/arm/boot/dts/amlogic/tl1_pxp.dts +++ b/arch/arm/boot/dts/amlogic/tl1_pxp.dts @@ -96,8 +96,10 @@ vdin1_cma_reserved:linux,vdin1_cma { compatible = "shared-dma-pool"; reusable; - /* 1920x1080x2x4 =16 M */ - size = <0x1400000>; + /*keystone need 4 buffers,each has 1920*1080*3 + *for keystone, change to 0x1800000(24M) + */ + size = <0x1400000>;/*20M*/ alignment = <0x400000>; }; diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts index dc3014d..8824a55 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts @@ -122,8 +122,10 @@ vdin1_cma_reserved:linux,vdin1_cma { compatible = "shared-dma-pool"; reusable; - /* 1920x1080x2x4 =16 M */ - size = <0x1400000>; + /*keystone need 4 buffers,each has 1920*1080*3 + *for keystone, change to 0x1800000(24M) + */ + size = <0x1400000>;/*20M*/ alignment = <0x400000>; }; diff --git a/arch/arm64/boot/dts/amlogic/mesontm2.dtsi b/arch/arm64/boot/dts/amlogic/mesontm2.dtsi index 356d181..980cd4b 100644 --- a/arch/arm64/boot/dts/amlogic/mesontm2.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontm2.dtsi @@ -1334,7 +1334,7 @@ }; vdac { - compatible = "amlogic, vdac-tl1"; + compatible = "amlogic, vdac-tm2"; status = "okay"; }; diff --git a/drivers/amlogic/clk/tl1/tl1.h b/drivers/amlogic/clk/tl1/tl1.h index e3a7b56..bc67643 100644 --- a/drivers/amlogic/clk/tl1/tl1.h +++ b/drivers/amlogic/clk/tl1/tl1.h @@ -123,11 +123,13 @@ #define HHI_SYS_PLL_CNTL5 0x308 /* 0xc2 offset in datasheet */ #define HHI_SYS_PLL_CNTL6 0x30c /* 0xc3 offset in datasheet */ +#if 0/*tl1 no*/ #define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in datasheet */ #define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in datasheet */ #define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in datasheet */ #define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in datasheet */ #define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in datasheet */ +#endif #define HHI_VID_LOCK_CLK_CNTL 0x3c8 /* 0xf2 offset in datasheet1 */ #define HHI_BT656_CLK_CNTL 0x3d4 /* 0xf5 offset in datasheet1 */ #define HHI_SPICC_CLK_CNTL 0x3dc /* 0xf7 offset in datasheet1 */ diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 078a35b..4a54c83 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include /* #include */ #include /* for parse_para_pq */ #include @@ -129,7 +131,7 @@ static struct hdr_metadata_info_s vpp_hdr_metadata_s; static int vdj_mode_flg; struct am_vdj_mode_s vdj_mode_s; -void __iomem *amvecm_hiu_reg_base;/* = *ioremap(0xc883c000, 0x2000); */ +/*void __iomem *amvecm_hiu_reg_base;*//* = *ioremap(0xc883c000, 0x2000); */ static int debug_amvecm; module_param(debug_amvecm, int, 0664); @@ -722,6 +724,7 @@ static ssize_t amvecm_vlock_store(struct class *cla, sel = VLOCK_SUPPORT; } else if (!strncmp(parm[0], "enable", 6)) { vecm_latch_flag |= FLAG_VLOCK_EN; + vlock_set_en(true); } else if (!strncmp(parm[0], "disable", 7)) { vecm_latch_flag |= FLAG_VLOCK_DIS; } else if (!strncmp(parm[0], "status", 6)) { @@ -734,8 +737,36 @@ static ssize_t amvecm_vlock_store(struct class *cla, vlock_log_stop(); } else if (!strncmp(parm[0], "log_print", 9)) { vlock_log_print(); + } else if (!strncmp(parm[0], "phase", 5)) { + if (kstrtol(parm[1], 10, &val) < 0) + return -EINVAL; + vlock_set_phase(val); + } else if (!strncmp(parm[0], "phlock_en", 9)) { + if (kstrtol(parm[1], 10, &val) < 0) + return -EINVAL; + vlock_set_phase_en(val); } else { - pr_info("unsupport cmd!!\n"); + pr_info("----cmd list -----\n"); + pr_info("vlock_mode val\n"); + pr_info("vlock_en val\n"); + pr_info("vlock_debug val\n"); + pr_info("vlock_adapt val\n"); + pr_info("vlock_dis_cnt_limit val\n"); + pr_info("vlock_delta_limit val\n"); + pr_info("vlock_dynamic_adjust val\n"); + pr_info("vlock_line_limit val\n"); + pr_info("vlock_dis_cnt_no_vf_limit val\n"); + pr_info("vlock_line_limit val\n"); + pr_info("vlock_support val\n"); + pr_info("enable\n"); + pr_info("disable\n"); + pr_info("status\n"); + pr_info("dump_reg\n"); + pr_info("log_start\n"); + pr_info("log_stop\n"); + pr_info("log_print\n"); + pr_info("phase persent\n"); + pr_info("phlock_en val\n"); } if (sel < VLOCK_PARAM_MAX) vlock_param_set(temp_val, sel); @@ -5742,11 +5773,40 @@ static const struct file_operations amvecm_fops = { #endif .poll = amvecm_poll, }; + +static const struct vecm_match_data_s vecm_dt_xxx = { + .vlk_support = true, + .vlk_new_fsm = 0, + .vlk_hwver = vlock_hw_org, + .vlk_phlock_en = false, +}; + +static const struct vecm_match_data_s vecm_dt_tl1 = { + .vlk_support = true, + .vlk_new_fsm = 1, + .vlk_hwver = vlock_hw_ver2, + .vlk_phlock_en = true, +}; + +static const struct of_device_id aml_vecm_dt_match[] = { + { + .compatible = "amlogic, vecm", + .data = &vecm_dt_xxx, + }, + { + .compatible = "amlogic, vecm-tl1", + .data = &vecm_dt_tl1, + }, + {}, +}; + static void aml_vecm_dt_parse(struct platform_device *pdev) { struct device_node *node; unsigned int val; int ret; + const struct of_device_id *of_id; + struct vecm_match_data_s *matchdata; node = pdev->dev.of_node; /* get integer value */ @@ -5785,6 +5845,18 @@ static void aml_vecm_dt_parse(struct platform_device *pdev) pr_info("Can't find tx_op_color_primary.\n"); else tx_op_color_primary = val; + + /*get compatible matched device, to get chip related data*/ + of_id = of_match_device(aml_vecm_dt_match, &pdev->dev); + if (of_id != NULL) { + pr_info("%s", of_id->compatible); + matchdata = (struct vecm_match_data_s *)of_id->data; + } else { + matchdata = (struct vecm_match_data_s *)&vecm_dt_xxx; + pr_info("unable to get matched device\n"); + } + vlock_dt_match_init(matchdata); + /*vlock param config*/ vlock_param_config(node); } @@ -5908,16 +5980,7 @@ static int aml_vecm_probe(struct platform_device *pdev) if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) sdr_mode = 2; - /*config vlock mode*/ - /*todo:txlx & g9tv support auto pll,*/ - /*but support not good,need vlsi support optimize*/ - vlock_mode = VLOCK_MODE_MANUAL_PLL; - if (is_meson_gxtvbb_cpu() || - is_meson_txl_cpu() || is_meson_txlx_cpu() - || is_meson_txhd_cpu()) - vlock_en = 1; - else - vlock_en = 0; + vlock_status_init(); hdr_init(&amvecm_dev.hdr_d); aml_vecm_dt_parse(pdev); @@ -6007,13 +6070,6 @@ static void amvecm_shutdown(struct platform_device *pdev) #endif } -static const struct of_device_id aml_vecm_dt_match[] = { - { - .compatible = "amlogic, vecm", - }, - {}, -}; - static struct platform_driver aml_vecm_driver = { .driver = { .name = "aml_vecm", @@ -6032,16 +6088,19 @@ static struct platform_driver aml_vecm_driver = { static int __init aml_vecm_init(void) { - unsigned int hiu_reg_base; + /*unsigned int hiu_reg_base;*/ pr_info("%s:module init\n", __func__); + #if 0 /* remap the hiu bus */ if (is_meson_txlx_cpu() || is_meson_txhd_cpu() || - is_meson_g12a_cpu() || is_meson_g12b_cpu()) + is_meson_g12a_cpu() || is_meson_g12b_cpu() + || is_meson_tl1_cpu()) hiu_reg_base = 0xff63c000; else hiu_reg_base = 0xc883c000; amvecm_hiu_reg_base = ioremap(hiu_reg_base, 0x2000); + #endif if (platform_driver_register(&aml_vecm_driver)) { pr_err("failed to register bl driver module\n"); return -ENODEV; @@ -6053,7 +6112,7 @@ static int __init aml_vecm_init(void) static void __exit aml_vecm_exit(void) { pr_info("%s:module exit\n", __func__); - iounmap(amvecm_hiu_reg_base); + /*iounmap(amvecm_hiu_reg_base);*/ platform_driver_unregister(&aml_vecm_driver); } diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h index bdd4737..292827d 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h @@ -30,13 +30,13 @@ static struct vlock_regs_s vlock_enc_setting[VLOCK_DEFAULT_REG_SIZE] = { {0x3000, 0xE3f50f10 }, {0x3001, 0x41E3c3c }, {0x3002, 0x6000000 }, - {0x3003, 0x20680680 }, - {0x3004, 0x280280 }, + {0x3003, 0x20709709/*0x20680680 */}, + {0x3004, 0x00709709/*0x280280 */}, {0x3005, 0x8020000 }, {0x3006, 0x0008000 }, {0x3007, 0x0000000 }, {0x3008, 0x0000000 }, - {0x3009, 0x0008000 }, + {0x3009, 0x6000000/*0x0008000 */}, {0x300a, 0x8000000 }, {0x300b, 0x000a000 }, {0x300c, 0xa000000 }, @@ -54,7 +54,7 @@ static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = { {0x3001, 0x04053c32 }, {0x3002, 0x06000000 }, {0x3003, 0x20780780 }, - {0x3004, 0x00000000 }, + {0x3004, 0x00680680 }, {0x3005, 0x00080000 }, {0x3006, 0x00070000 }, {0x3007, 0x00000000 }, @@ -62,15 +62,29 @@ static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = { {0x3009, 0x00100000 }, {0x300a, 0x00600000 }, {0x300b, 0x00100000 }, - {0x300c, 0x00000000 }, + {0x300c, 0x00600000 }, {0x300d, 0x00004000 }, {0x3010, 0x20001000 }, {0x3016, 0x0003de00 }, - {0x3017, 0x00001080 }, + {0x3017, 0x00001010 }, {0x301d, 0x30501080 }, {0x301e, 0x00000007 }, {0x301f, 0x06000000 } }; +#define VLOCK_PHASE_REG_SIZE 9 +static struct vlock_regs_s vlock_pll_phase_setting[VLOCK_PHASE_REG_SIZE] = { + {0x3004, 0x00620680}, + {0x3009, 0x06000000}, + {0x300a, 0x00600000}, + {0x300b, 0x06000000}, + {0x300c, 0x00600000}, + + {0x3025, 0x00002000}, + {0x3027, 0x00022002}, + {0x3028, 0x00001000}, + {0x302a, 0x00022002}, +}; + #endif diff --git a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h index ec7f639..37afb66 100644 --- a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h +++ b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h @@ -342,6 +342,7 @@ #define VPU_VLOCK_GCLK_EN 0x301e #define VPU_VLOCK_LOOP1_ACCUM_LMT 0x301f #define VPU_VLOCK_RO_M_INT_FRAC 0x3020 +#define VPU_VLOCK_RO_LCK_FRM 0x3024 #define XVYCC_VD1_RGB_CTRST 0x3170 @@ -529,11 +530,19 @@ /*ve dither*/ #define VPP_VE_DITHER_CTRL 0x3120 +/* TL1 */ +/*offset 0x1000*/ +#define HHI_TCON_PLL_CNTL0 0x20 +#define HHI_TCON_PLL_CNTL1 0x21 +#define HHI_HDMI_PLL_VLOCK_CNTL 0xd1 + /* for pll bug */ -#define HHI_HDMI_PLL_CNTL 0x10c8 -#define HHI_HDMI_PLL_CNTL2 0x10c9 -#define HHI_VID_LOCK_CLK_CNTL 0x10f2 -#define HHI_HDMI_PLL_CNTL6 0x10cd + +#define HHI_HDMI_PLL_CNTL 0xc8 +#define HHI_HDMI_PLL_CNTL2 0xc9 +#define HHI_VID_LOCK_CLK_CNTL 0xf2 +#define HHI_HDMI_PLL_CNTL6 0xcd + /* for vlock enc mode adjust begin */ #define ENCL_VIDEO_MAX_LNCNT 0x1cbb #define ENCL_VIDEO_MAX_PXCNT 0x1cb0 @@ -552,13 +561,12 @@ #define ENCT_MAX_LINE_SWITCH_POINT 0x1c88 /* for vlock enc mode adjust end */ -#define HHI_VID_LOCK_CLK_CNTL 0x10f2 - #define VDIN_MEAS_VS_COUNT_LO 0x125c +/*for vlock*/ /*after GXL new add CNTL1,same with CNTL2 on G9TV/GXTVBB*/ -#define HHI_HDMI_PLL_CNTL1 0x10c9 +#define HHI_HDMI_PLL_CNTL1 0xc9 /*after GXL CNTL5[bit3] is same with CNTL6[bit20] on G9TV/GXTVBB*/ -#define HHI_HDMI_PLL_CNTL5 0x10cd +#define HHI_HDMI_PLL_CNTL5 0xcd /* #define VI_HIST_CTRL 0x2e00 */ diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c index 8ce8c0c..752bdf4 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.c +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.c @@ -35,11 +35,13 @@ #include "amcm.h" /* video lock */ -/* 0:enc;1:pll; - * 2:manual pll; - * 3:manual_enc mode(only support lvds/vx1) +/* 0:off; + * 1:auto enc; + * 2:auto pll; + * 4:manual pll; + * 8:manual_enc mode(only support lvds/vx1) */ -unsigned int vlock_mode = VLOCK_MODE_MANUAL_PLL; +enum VLOCK_MD vlock_mode = VLOCK_MODE_MANUAL_PLL; unsigned int vlock_en = 1; /* *0:only support 50->50;60->60;24->24;30->30; @@ -65,7 +67,7 @@ static unsigned int vlock_intput_type; static signed int vlock_line_limit = 3; static unsigned int vlock_enc_adj_limit; /* 0x3009 default setting for 2 line(1080p-output) is 0x8000 */ -static unsigned int vlock_capture_limit = 0x8000; +static unsigned int vlock_capture_limit = 0x10000/*0x8000*/; static unsigned int vlock_debug; static unsigned int vlock_dynamic_adjust = 1; @@ -102,6 +104,12 @@ static unsigned int vlock_log_last_ivcnt; static unsigned int vlock_log_last_ovcnt; static unsigned int vlock_log_delta_m; static unsigned int vlock_log_delta_en; +static unsigned int hhi_pll_reg_m; +static unsigned int hhi_pll_reg_frac; + +static struct stvlock_sig_sts vlock; + +/*static unsigned int hhi_pll_reg_vlock_ctl;*/ module_param(vlock_log_size, uint, 0664); MODULE_PARM_DESC(vlock_log_size, "\n vlock_log_size\n"); module_param(vlock_log_cnt, uint, 0664); @@ -141,13 +149,17 @@ static unsigned int last_i_vsync; int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val) { - *val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2)); + /**val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));*/ + *val = aml_read_hiubus(reg); + /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), *val);*/ return 0; } int amvecm_hiu_reg_write(unsigned int reg, unsigned int val) { - writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2))); + /*writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));*/ + /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), val);*/ + aml_write_hiubus(reg, val); return 0; } static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value, @@ -162,6 +174,41 @@ static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value, return 0; } +u32 vlock_get_panel_pll_m(void) +{ + u32 val; + + amvecm_hiu_reg_read(hhi_pll_reg_m, &val); + return val; +} + +void vlock_set_panel_pll_m(u32 val) +{ + amvecm_hiu_reg_write(hhi_pll_reg_m, val); +} + +u32 vlock_get_panel_pll_frac(void) +{ + u32 val; + + amvecm_hiu_reg_read(hhi_pll_reg_frac, &val); + return val; +} + +void vlock_set_panel_pll_frac(u32 val) +{ + amvecm_hiu_reg_write(hhi_pll_reg_frac, val); +} + + +/*returen 1: use phase lock*/ +int phase_lock_check(void) +{ + unsigned int ret = 0; + + ret = READ_VPP_REG_BITS(VPU_VLOCK_RO_LCK_FRM, 17, 1); + return ret; +} static unsigned int vlock_check_input_hz(struct vframe_s *vf) { @@ -188,33 +235,41 @@ static unsigned int vlock_check_input_hz(struct vframe_s *vf) return ret_hz; } -static unsigned int vlock_check_output_hz(unsigned int sync_duration_num) +static unsigned int vlock_check_output_hz(unsigned int sync_duration_num, + unsigned int sync_duration_den) { unsigned int ret_hz = 0; + unsigned int tempHz; + + tempHz = (sync_duration_num*100)/sync_duration_den; - switch (sync_duration_num) { - case 24: + switch (tempHz) { + case 2400: ret_hz = 24; break; - case 30: + case 3000: ret_hz = 30; break; - case 50: + case 5000: ret_hz = 50; break; - case 60: + case 6000: ret_hz = 60; break; - case 100: + case 10000: ret_hz = 100; break; - case 120: + case 12000: ret_hz = 120; break; default: ret_hz = 0; break; } + + if ((ret_hz == 0) && (vlock_debug & VLOCK_DEBUG_INFO)) + pr_info("sync_duration_num:%d\n", sync_duration_num); + return ret_hz; } /*vlock is support eq_after gxbb,but which is useful only for tv chip @@ -224,10 +279,9 @@ static void vlock_enable(bool enable) { unsigned int tmp_value; - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); - if (is_meson_gxtvbb_cpu()) { if (vlock_mode & VLOCK_MODE_MANUAL_PLL) { + amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 20, 1); /*vlsi suggest config:don't enable load signal, *on gxtvbb this load signal will effect SSG, @@ -246,7 +300,24 @@ static void vlock_enable(bool enable) else amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5, enable, 3, 1); + } else if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + /*reset*/ + if (!(vlock_mode & VLOCK_MODE_MANUAL_PLL)) { + /*reset*/ + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);*/ + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);*/ + } + + if (!enable) { + /*amvecm_hiu_reg_write_bits(*/ + /* HHI_HDMI_PLL_VLOCK_CNTL, 0, 0, 3);*/ + + /*WRITE_VPP_REG(VPU_VLOCK_CTRL, 0);*/ + } } + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s] (%d)\n", __func__, enable); } static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len) { @@ -256,22 +327,30 @@ static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len) return; for (i = 0; i < len; i++) WRITE_VPP_REG(vlock_regs[i].addr, vlock_regs[i].val); + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s]\n", __func__); } static void vlock_setting(struct vframe_s *vf, unsigned int input_hz, unsigned int output_hz) { - unsigned int freq_hz = 0, hiu_reg_value_2_addr = HHI_HDMI_PLL_CNTL2; + unsigned int freq_hz = 0; unsigned int reg_value = 0, hiu_reg_value, hiu_reg_value_2; - unsigned int hiu_m_val, hiu_frac_val, temp_value; + unsigned int hiu_m_val = 0, hiu_frac_val = 0, temp_value; + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info(">>>[%s]\n", __func__); + pr_info("inputHz:%d,outputHz:%d\n", input_hz, output_hz); + pr_info("type_original:0x%x\n", vf->type_original); + } amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80); - if ((vlock_mode & (VLOCK_MODE_AUTO_ENC | - VLOCK_MODE_MANUAL_ENC | - VLOCK_MODE_MANUAL_SOFT_ENC))) { + if (IS_ENC_MODE(vlock_mode)) { /*init default config for enc mode*/ vlock_hw_reinit(vlock_enc_setting, VLOCK_DEFAULT_REG_SIZE); /*vlock line limit*/ - WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT, vlock_capture_limit); + /*WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT,*/ + /* vlock_capture_limit);*/ + /* VLOCK_CNTL_EN disable */ vlock_enable(0); /* disable to adjust pll */ @@ -292,10 +371,12 @@ static void vlock_setting(struct vframe_s *vf, } /* enable to adjust enc */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 30, 1); - /*clear accum1 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); - /*clear accum0 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) { + /*clear accum1 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + /*clear accum0 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + } /*@20180314 new add*/ /* *set input & output freq @@ -303,8 +384,14 @@ static void vlock_setting(struct vframe_s *vf, *bit8~15:output freq */ if ((vf->type_original & VIDTYPE_TYPEMASK) && - !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) - input_hz = input_hz >> 1; + !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) { + /*tl1 fix i problem*/ + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) + input_hz = input_hz >> 1; + else + WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, + 1, 28, 1); + } freq_hz = input_hz | (output_hz << 8); WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16); /* @@ -317,12 +404,14 @@ static void vlock_setting(struct vframe_s *vf, WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, input_hz, 16, 8); temp_value = READ_VPP_REG(enc_max_line_addr); - WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, temp_value, 0, 14); + WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, + temp_value + 1, 0, 14); temp_value = READ_VPP_REG(enc_max_pixel_addr); - WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, temp_value, 16, 14); + WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, + temp_value + 1, 16, 14); WRITE_VPP_REG_BITS(VPU_VLOCK_ADJ_EN_SYNC_CTRL, vlock_latch_en_cnt, 8, 8); - WRITE_VPP_REG_BITS(enc_video_mode_addr, 0, 15, 1); + WRITE_VPP_REG_BITS(enc_video_mode_addr, 1, 15, 1); } if ((vlock_mode & (VLOCK_MODE_AUTO_PLL | VLOCK_MODE_MANUAL_PLL))) { @@ -333,8 +422,17 @@ static void vlock_setting(struct vframe_s *vf, *bit0~7:input freq *bit8~15:output freq */ - if (vf->type_original & VIDTYPE_TYPEMASK) - input_hz = input_hz >> 1; + if (vf->type_original & VIDTYPE_TYPEMASK) { + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) + input_hz = input_hz >> 1; + else + WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, + 1, 28, 1); + } else { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) + WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, + 0, 28, 1); + } freq_hz = input_hz | (output_hz << 8); WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16); /* @@ -349,10 +447,23 @@ static void vlock_setting(struct vframe_s *vf, /*set PLL M_INT;PLL M_frac*/ /* WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, */ /* READ_CBUS_REG_BITS(HHI_HDMI_PLL_CNTL,0,9),12,9); */ - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &hiu_reg_value); - amvecm_hiu_reg_read(hiu_reg_value_2_addr, - &hiu_reg_value_2); - if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &hiu_reg_value);*/ + /*amvecm_hiu_reg_read(hhi_pll_reg_frac,*/ + /* &hiu_reg_value_2);*/ + hiu_reg_value = vlock_get_panel_pll_m(); + hiu_reg_value_2 = vlock_get_panel_pll_frac(); + + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info("hhi_pll_reg_m:0x%x\n", hiu_reg_value); + pr_info("hhi_pll_reg_frac:0x%x\n", hiu_reg_value_2); + } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { + hiu_m_val = hiu_reg_value & 0xff; + /*discard low 5 bits*/ + hiu_frac_val = (hiu_reg_value_2 >> 5) & 0xfff; + reg_value = (hiu_m_val << 12) + hiu_frac_val; + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { hiu_m_val = hiu_reg_value & 0x1FF; hiu_frac_val = hiu_reg_value_2 & 0x3FF; if (hiu_reg_value_2 & 0x800) { @@ -366,6 +477,12 @@ static void vlock_setting(struct vframe_s *vf, } reg_value = (hiu_m_val << 12) + (hiu_frac_val << 2); + } else { + pr_info("err: m f value\n"); + } + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info("hiu_m_val=0x%x\n", hiu_m_val); + pr_info("hiu_frac_val=0x%x\n", hiu_frac_val); } WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21); /*vlock_pll_adj_limit = (reg_value * 0x8000) >> 24;*/ @@ -383,6 +500,21 @@ static void vlock_setting(struct vframe_s *vf, /* enable to adjust pll */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 29, 1); } + + /*initial phase lock setting*/ + if (vlock.dtdata->vlk_phlock_en) { + vlock_hw_reinit(vlock_pll_phase_setting, VLOCK_PHASE_REG_SIZE); + /*disable pll lock*/ + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 3, 1);*/ + + /*enable pll mode and enc mode phase lock*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 3, 0, 2); + + /*reset*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + } + /* vlock module output goes to which module */ switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL, 0, 2)) { case 0:/* ENCL */ @@ -404,33 +536,40 @@ static void vlock_setting(struct vframe_s *vf, else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI) /* Input Vsync source select from hdmi-rx */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 16, 3); + + /*enable vlock*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 31, 1); } void vlock_vmode_check(void) { const struct vinfo_s *vinfo; - unsigned int t0, t1, hiu_reg_addr; + unsigned int t0, t1; if (vlock_en == 0) return; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - hiu_reg_addr = HHI_HDMI_PLL_CNTL1; - else - hiu_reg_addr = HHI_HDMI_PLL_CNTL2; + vinfo = get_current_vinfo(); vlock_vmode_changed = 0; if ((vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE) || (pre_hiu_reg_m == 0)) { if (vlock_mode & (VLOCK_MODE_MANUAL_PLL | VLOCK_MODE_AUTO_PLL)) { - amvecm_hiu_reg_read(hiu_reg_addr, &t0); - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &t1); - pre_hiu_reg_frac = t0 & 0xfff; - pre_hiu_reg_m = t1 & 0x1ff; + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &t0);*/ + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &t1);*/ + t0 = vlock_get_panel_pll_m(); + t1 = vlock_get_panel_pll_frac(); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { + pre_hiu_reg_frac = (t0 >> 5) & 0xfff; + pre_hiu_reg_m = t1 & 0xff; + } else { + pre_hiu_reg_frac = t0 & 0xfff; + pre_hiu_reg_m = t1 & 0x1ff; + } } if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_AUTO_ENC | VLOCK_MODE_MANUAL_SOFT_ENC))) { + #if 0 switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL, 0, 2)) { case 0: @@ -466,6 +605,7 @@ void vlock_vmode_check(void) ENCL_MAX_LINE_SWITCH_POINT; break; } + #endif pre_enc_max_line = READ_VPP_REG(enc_max_line_addr); pre_enc_max_pixel = READ_VPP_REG(enc_max_pixel_addr); vlock_capture_limit = ((1 << 12) * vlock_line_limit) / @@ -479,7 +619,6 @@ void vlock_vmode_check(void) static void vlock_disable_step1(void) { unsigned int m_reg_value, tmp_value, enc_max_line, enc_max_pixel; - unsigned int hiu_reg_addr; /* VLOCK_CNTL_EN disable */ vlock_enable(0); @@ -487,24 +626,70 @@ static void vlock_disable_step1(void) if ((vlock_mode & (VLOCK_MODE_MANUAL_PLL | VLOCK_MODE_AUTO_PLL | VLOCK_MODE_MANUAL_SOFT_ENC))) { - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - hiu_reg_addr = HHI_HDMI_PLL_CNTL1; - else - hiu_reg_addr = HHI_HDMI_PLL_CNTL2; - amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value); - m_reg_value = tmp_value & 0xfff; - if (m_reg_value != pre_hiu_reg_frac) { - tmp_value = (tmp_value & 0xfffff000) | - (pre_hiu_reg_frac & 0xfff); - amvecm_hiu_reg_write(hiu_reg_addr, tmp_value); - } - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value); - m_reg_value = tmp_value & 0x1ff; - if ((m_reg_value != pre_hiu_reg_m) && - (pre_hiu_reg_m != 0)) { - tmp_value = (tmp_value & 0xfffffe00) | - (pre_hiu_reg_m & 0x1ff); - amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value); + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + #if 0 + amvecm_hiu_reg_read(hhi_pll_reg_frac, + &tmp_value); + m_reg_value = (tmp_value >> 5) & 0xfff; + if (m_reg_value != pre_hiu_reg_frac) { + tmp_value = (tmp_value & 0xfffff000) | + (pre_hiu_reg_frac & 0xfff); + amvecm_hiu_reg_write(hhi_pll_reg_frac, + tmp_value); + pr_info("restore f value=0x%x\n", tmp_value); + } + amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value); + m_reg_value = tmp_value & 0xff; + if ((m_reg_value != pre_hiu_reg_m) && + (pre_hiu_reg_m != 0)) { + tmp_value = (tmp_value & 0xffffff00) | + (pre_hiu_reg_m & 0xff); + amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value); + pr_info("restore m value=0x%x\n", tmp_value); + } + #endif + + #if 1 + /*restore the orginal pll setting*/ + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_m(); + m_reg_value = tmp_value & 0xff; + if (m_reg_value != (vlock.val_m & 0xff)) + vlock_set_panel_pll_m(vlock.val_m); + /*amvecm_hiu_reg_write(hhi_pll_reg_m,*/ + /* vlock.val_m);*/ + + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_frac(); + m_reg_value = tmp_value & 0x1ffff; + if (m_reg_value != (vlock.val_frac & 0xfff)) + vlock_set_panel_pll_frac(vlock.val_frac); + /*amvecm_hiu_reg_write(hhi_pll_reg_frac,*/ + /* vlock.val_frac);*/ + pr_info("restore orignal m,f value\n"); + #endif + } else { + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_frac(); + m_reg_value = tmp_value & 0xfff; + if (m_reg_value != pre_hiu_reg_frac) { + tmp_value = (tmp_value & 0xfffff000) | + (pre_hiu_reg_frac & 0xfff); + /*amvecm_hiu_reg_write(hhi_pll_reg_frac,*/ + /* tmp_value);*/ + vlock_set_panel_pll_frac(tmp_value); + } + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_m(); + m_reg_value = tmp_value & 0x1ff; + if ((m_reg_value != pre_hiu_reg_m) && + (pre_hiu_reg_m != 0)) { + tmp_value = (tmp_value & 0xfffffe00) | + (pre_hiu_reg_m & 0x1ff); + /*amvecm_hiu_reg_write(hhi_pll_reg_m, */ + /*tmp_value);*/ + vlock_set_panel_pll_m(tmp_value); + } } } if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | @@ -537,15 +722,26 @@ static void vlock_disable_step1(void) } vlock_pll_stable_cnt = 0; vlock_enc_stable_flag = 0; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } -static void vlock_disable_step2(void) +static bool vlock_disable_step2(void) { unsigned int temp_val; + bool ret = false; + /* need delay to disable follow regs(vlsi suggest!!!) */ if (vlock_dis_cnt > 0) vlock_dis_cnt--; - if (vlock_dis_cnt == 0) { + else if (vlock_dis_cnt == 0) { + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x4, 0, 3); + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x0, 0, 3); + } + /* disable to adjust pll */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1); /* CFG_VID_LOCK_ADJ_EN disable */ @@ -556,10 +752,19 @@ static void vlock_disable_step2(void) /* disable vid_lock_en */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 31, 1); vlock_state = VLOCK_STATE_DISABLE_STEP2_DONE; - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val); - if (is_meson_gxtvbb_cpu() && (((temp_val >> 21) & 0x3) != 0)) - amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 21, 2); + if (is_meson_gxtvbb_cpu()) { + amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val); + if (((temp_val >> 21) & 0x3) != 0) + amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, + 0, 21, 2); + } + ret = true; + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } + + return ret; } static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, unsigned int input_hz, unsigned int output_hz) @@ -584,10 +789,13 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, vlock_sync_limit_flag = 0; vlock_vmode_changed = 0; vlock_dis_cnt = 0; - vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; + /*vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;*/ vlock_pll_stable_cnt = 0; vlock_log_cnt = 0; vlock_enc_stable_flag = 0; + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } void vlock_log_start(void) @@ -715,6 +923,8 @@ static void vlock_enable_step3_enc(void) vlock_reg_get(); vlock_log_cnt++; } + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } static void vlock_enable_step3_soft_enc(void) @@ -840,7 +1050,10 @@ static void vlock_enable_step3_soft_enc(void) vlock_reg_get(); vlock_log_cnt++; } + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } + /*check pll adj value (0x3020),otherwise may cause blink*/ static void vlock_pll_adj_limit_check(unsigned int *pll_val) { @@ -863,15 +1076,12 @@ static void vlock_pll_adj_limit_check(unsigned int *pll_val) } } } + static void vlock_enable_step3_pll(void) { - unsigned int m_reg_value, tmp_value, abs_val, hiu_reg_addr; + unsigned int m_reg_value, tmp_value, abs_val; unsigned int ia, oa, abs_cnt; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - hiu_reg_addr = HHI_HDMI_PLL_CNTL1; - else - hiu_reg_addr = HHI_HDMI_PLL_CNTL2; + unsigned int pre_m, new_m, tar_m, org_m; /*vs_i*/ tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); @@ -898,10 +1108,20 @@ static void vlock_enable_step3_pll(void) m_reg_value = READ_VPP_REG(VPU_VLOCK_RO_M_INT_FRAC); if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) { + #if 0 vlock_log[vlock_log_cnt]->pll_frac = (vlock_pll_val_last & 0xfff) >> 2; vlock_log[vlock_log_cnt]->pll_m = (vlock_pll_val_last >> 16) & 0x1ff; + #else + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_frac(); + vlock_log[vlock_log_cnt]->pll_frac = tmp_value; + + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_m(); + vlock_log[vlock_log_cnt]->pll_m = tmp_value; + #endif vlock_reg_get(); vlock_log_cnt++; } @@ -913,18 +1133,26 @@ static void vlock_enable_step3_pll(void) return; } /*check adjust delta limit*/ - vlock_pll_adj_limit_check(&m_reg_value); + if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) + vlock_pll_adj_limit_check(&m_reg_value); /*vlsi suggest config:don't enable load signal, *on gxtvbb this load signal will effect SSG, *which may result in flashes black */ - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); - if (is_meson_gxtvbb_cpu() && (((tmp_value >> 21) & 0x3) != 2)) - amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2); - /*add delta count check*/ - /*for interlace input need div 2*/ - if (vlock_intput_type) + if (is_meson_gxtvbb_cpu()) { + amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); + if (((tmp_value >> 21) & 0x3) != 2) + amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2); + } + + /* add delta count check + *for interlace input need div 2 + *0:progressive type + *1:interlace type + */ + if (vlock_intput_type && + (vlock.dtdata->vlk_hwver < vlock_hw_ver2)) ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) / 2; else ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); @@ -936,45 +1164,101 @@ static void vlock_enable_step3_pll(void) return; } /*frac*/ - amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value); - abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff)); - if ((abs_val >= vlock_log_delta_frac) && (vlock_log_delta_en&(1<<3))) - pr_info("vlock frac delta:%d(0x%x,0x%x)\n", - abs_val, ((m_reg_value & 0xfff) >> 2), + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_frac(); + if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) { + abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff)); - if ((abs_val >= vlock_delta_limit) && - (abs_cnt > vlock_delta_cnt_limit)) { - tmp_value = (tmp_value & 0xfffff000) | - ((m_reg_value & 0xfff) >> 2); - amvecm_hiu_reg_write(hiu_reg_addr, tmp_value); - vlock_pll_val_last &= 0xffff0000; - vlock_pll_val_last |= (m_reg_value & 0xfff); + if ((abs_val >= vlock_log_delta_frac) && + (vlock_log_delta_en&(1<<3))) + pr_info("vlock frac delta:%d(0x%x,0x%x)\n", + abs_val, ((m_reg_value & 0xfff) >> 2), + (tmp_value & 0xfff)); + if ((abs_val >= vlock_delta_limit) && + (abs_cnt > vlock_delta_cnt_limit)) { + tmp_value = (tmp_value & 0xfffff000) | + ((m_reg_value & 0xfff) >> 2); + /*amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value);*/ + vlock_set_panel_pll_frac(tmp_value); + vlock_pll_val_last &= 0xffff0000; + vlock_pll_val_last |= (m_reg_value & 0xfff); + } + /*check stable by diff frac*/ + if ((abs_val < (2 * vlock_delta_limit)) && + (abs_cnt < vlock_enc_adj_limit)) + vlock_pll_stable_cnt++; + else + vlock_pll_stable_cnt = 0; + } else { + abs_val = abs((tmp_value & 0x1ffff) - + ((m_reg_value & 0xfff) << 5)); + + if (abs_val > (50 << 5)) + tmp_value = ((tmp_value & 0xfffe0000) | + (((tmp_value & 0x1ffff) + + ((m_reg_value & 0xfff) << 5)) >> 1)); + else + tmp_value = (tmp_value & 0xfffe0000) | + ((m_reg_value & 0xfff) << 5); + + /*16:0*/ + /*amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value);*/ + vlock_set_panel_pll_frac(tmp_value); } - /*check stable by diff frac*/ - if ((abs_val < (2 * vlock_delta_limit)) && - (abs_cnt < vlock_enc_adj_limit)) - vlock_pll_stable_cnt++; - else - vlock_pll_stable_cnt = 0; + /*m*/ - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value); - abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (pre_hiu_reg_m & 0x1ff)); - if ((abs_val > vlock_log_delta_m) && (vlock_log_delta_en&(1<<4))) - pr_info("vlock m delta:%d(0x%x,0x%x)\n", - abs_val, ((m_reg_value >> 16) & 0x1ff), - (tmp_value & 0x1ff)); - if ((abs_val <= vlock_pll_m_limit) && - (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) && - (abs_cnt > vlock_delta_cnt_limit)) { - tmp_value = (tmp_value & 0xfffffe00) | - ((m_reg_value >> 16) & 0x1ff); - amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value); - vlock_pll_val_last &= 0x0000ffff; - vlock_pll_val_last |= (m_reg_value & 0xffff0000); + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);*/ + tmp_value = vlock_get_panel_pll_m(); + if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) { + abs_val = abs(((m_reg_value >> 16) & 0xff) - + (pre_hiu_reg_m & 0xff)); + if ((abs_val > vlock_log_delta_m) && + (vlock_log_delta_en&(1<<4))) + pr_info("vlock m delta:%d(0x%x,0x%x)\n", + abs_val, ((m_reg_value >> 16) & 0x1ff), + (tmp_value & 0x1ff)); + if ((abs_val <= vlock_pll_m_limit) && + (((m_reg_value >> 16) & 0x1ff) != + (tmp_value & 0x1ff)) && + (abs_cnt > vlock_delta_cnt_limit)) { + tmp_value = (tmp_value & 0xfffffe00) | + ((m_reg_value >> 16) & 0x1ff); + /*amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);*/ + vlock_set_panel_pll_m(tmp_value); + vlock_pll_val_last &= 0x0000ffff; + vlock_pll_val_last |= (m_reg_value & 0xffff0000); + } + } else { + pre_m = (tmp_value & 0xff); + new_m = ((m_reg_value >> 16) & 0x1ff); + org_m = (vlock.val_m & 0xff); + if (pre_m != new_m) { + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("vlock m chg: pre=0x%x, report=0x%x\n", + pre_m, new_m); + + if (new_m > pre_m) { + tar_m = ((pre_m + 1) < + (org_m + 1))?(pre_m + 1):(org_m + 1); + } else { + /*tar_m < pre_m*/ + tar_m = ((pre_m - 1) < + (org_m - 1))?(org_m - 1):(pre_m - 1); + } + tmp_value = (tmp_value & 0xffffff00) + tar_m; + /*amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);*/ + vlock_set_panel_pll_m(tmp_value); + } } + /*check stable by diff m*/ - if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) - vlock_pll_stable_cnt = 0; + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + if (((m_reg_value >> 16) & 0xff) != (tmp_value & 0xff)) + vlock_pll_stable_cnt = 0; + } else { + if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) + vlock_pll_stable_cnt = 0; + } } /* won't change this function internal seqence, * if really need change,please be carefull and check with vlsi @@ -994,10 +1278,12 @@ void amve_vlock_process(struct vframe_s *vf) } vinfo = get_current_vinfo(); input_hz = vlock_check_input_hz(vf); - output_hz = vlock_check_output_hz(vinfo->sync_duration_num); + output_hz = vlock_check_output_hz(vinfo->sync_duration_num, + vinfo->sync_duration_den); vlock_dis_cnt_no_vf = 0; if (vecm_latch_flag & FLAG_VLOCK_EN) { vlock_enable_step1(vf, vinfo, input_hz, output_hz); + vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; vlock_en = 1; vecm_latch_flag &= ~FLAG_VLOCK_EN; } @@ -1035,43 +1321,73 @@ void amve_vlock_process(struct vframe_s *vf) (input_hz != pre_input_freq) || (output_hz != pre_output_freq) || vlock_vmode_changed || - (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET)) + (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET)) { vlock_enable_step1(vf, vinfo, input_hz, output_hz); + vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; + } if ((vlock_sync_limit_flag < 10) && (vlock_state >= VLOCK_STATE_ENABLE_STEP1_DONE)) { vlock_sync_limit_flag++; if ((vlock_sync_limit_flag <= 3) && ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_MANUAL_PLL)))) { + /*reset*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + /*clear first 3 frame internal cnt*/ WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0); WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("amve_vlock_process-0\n"); } if ((vlock_sync_limit_flag == 4) && ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_MANUAL_PLL)))) { + /*release reset*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("amve_vlock_process-1\n"); } } + if ((vlock_sync_limit_flag == 5) && (vlock_state == VLOCK_STATE_ENABLE_STEP1_DONE)) { /*input_vs_cnt =*/ /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/ /* 0, 28);*/ input_vs_cnt = XTAL_VLOCK_CLOCK/input_hz; - if (vf->type_original & VIDTYPE_TYPEMASK) + /*tl1 not need */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) && + vf->type_original & VIDTYPE_TYPEMASK) input_vs_cnt = input_vs_cnt << 1; + WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX, input_vs_cnt*125/100); WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN, input_vs_cnt*70/100); + /*cal accum1 value*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); /*cal accum0 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + //WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); vlock_state = VLOCK_STATE_ENABLE_STEP2_DONE; + + /* + * tl1 auto pll,swich clk need after + *several frames + */ + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + if (IS_AUTO_MODE(vlock_mode)) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x7, 0, 3); + else if (IS_MANUAL_MODE(vlock_mode)) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x6, 0, 3); + } + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("amve_vlock_process-2\n"); } else if (vlock_dynamic_adjust && (vlock_sync_limit_flag > 5) && (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) && @@ -1149,18 +1465,566 @@ void amve_vlock_resume(void) } } +void vlock_clear_frame_counter(void) +{ + vlock.frame_cnt_in = 0; + vlock.frame_cnt_no = 0; + vlock_log_cnt = 0; +} + +void vlock_set_en(bool en) +{ + /*if (vlock.dtdata->vlk_support)*/ + vlock_en = en; +} + +void vlock_status_init(void) +{ + /*config vlock mode*/ + /*todo:txlx & g9tv support auto pll,*/ + /*but support not good,need vlsi support optimize*/ + vlock_mode = VLOCK_MODE_MANUAL_PLL; + if (is_meson_gxtvbb_cpu() || + is_meson_txl_cpu() || is_meson_txlx_cpu() + || is_meson_tl1_cpu()) + vlock_en = 1; + else + vlock_en = 0; + + /*initial pll register address*/ + if (is_meson_tl1_cpu()) { + hhi_pll_reg_m = HHI_TCON_PLL_CNTL0; + hhi_pll_reg_frac = HHI_TCON_PLL_CNTL1; + /*hhi_pll_reg_vlock_ctl = HHI_HDMI_PLL_VLOCK_CNTL;*/ + } else if (get_cpu_type() >= + MESON_CPU_MAJOR_ID_GXL) { + hhi_pll_reg_m = HHI_HDMI_PLL_CNTL; + hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2; + } else { + hhi_pll_reg_m = HHI_HDMI_PLL_CNTL; + hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2; + } + + /*initial enc register address*/ + switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL, + 0, 2)) { + case 0: + enc_max_line_addr = ENCL_VIDEO_MAX_LNCNT; + enc_max_pixel_addr = ENCL_VIDEO_MAX_PXCNT; + enc_video_mode_addr = ENCL_VIDEO_MODE; + enc_video_mode_adv_addr = ENCL_VIDEO_MODE_ADV; + enc_max_line_switch_addr = + ENCL_MAX_LINE_SWITCH_POINT; + break; +#if 0 /*enc mode not adapt to ENCP and ENCT*/ + case 2: + enc_max_line_addr = ENCP_VIDEO_MAX_LNCNT; + enc_max_pixel_addr = ENCP_VIDEO_MAX_PXCNT; + enc_video_mode_addr = ENCP_VIDEO_MODE; + enc_max_line_switch_addr = + ENCP_MAX_LINE_SWITCH_POINT; + break; + case 3: + enc_max_line_addr = ENCT_VIDEO_MAX_LNCNT; + enc_max_pixel_addr = ENCT_VIDEO_MAX_PXCNT; + enc_video_mode_addr = ENCT_VIDEO_MODE; + enc_max_line_switch_addr = + ENCT_MAX_LINE_SWITCH_POINT; + break; +#endif + default: + enc_max_line_addr = ENCL_VIDEO_MAX_LNCNT; + enc_max_pixel_addr = ENCL_VIDEO_MAX_PXCNT; + enc_video_mode_addr = ENCL_VIDEO_MODE; + enc_video_mode_adv_addr = ENCL_VIDEO_MODE_ADV; + enc_max_line_switch_addr = + ENCL_MAX_LINE_SWITCH_POINT; + break; + } + + /*back up orignal pll value*/ + vlock.val_m = vlock_get_panel_pll_m(); + vlock.val_frac = vlock_get_panel_pll_frac(); + + vlock.fsm_sts = VLOCK_STATE_NULL; + vlock.fsm_prests = VLOCK_STATE_NULL; + vlock.vf_sts = false; + vlock.vmd_chg = false; + vlock.md_support = false; + /* vlock.phlock_percent = phlock_percent; */ + vlock_clear_frame_counter(); + + + pr_info("%s vlock_en:%d\n", __func__, vlock_en); +} + +void vlock_dt_match_init(struct vecm_match_data_s *pdata) +{ + vlock.dtdata = pdata; + /*vlock_en = vlock.dtdata.vlk_support;*/ + pr_info("vlock dt support: %d\n", vlock.dtdata->vlk_support); + pr_info("vlock dt new_fsm: %d\n", vlock.dtdata->vlk_new_fsm); + pr_info("vlock dt hwver: %d\n", vlock.dtdata->vlk_hwver); + pr_info("vlock dt phlock_en: %d\n", vlock.dtdata->vlk_phlock_en); +} + +void vlock_set_phase(u32 percent) +{ + u32 vs_i_val = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); + /*u32 vs_o_val = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);*/ + u32 data = 0; + + if (!vlock.dtdata->vlk_phlock_en) + return; + + if (percent > 100) { + pr_info("percent val err:%d\n", percent); + return; + } + + vlock.phlock_percent = percent; + data = (vs_i_val * (100 + vlock.phlock_percent))/200; + WRITE_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT, data); + pr_info("LOOP1_PHSDIF_TGT:0x%x\n", data); + + /*reset*/ + data = READ_VPP_REG(VPU_VLOCK_CTRL); + data |= 1 << 2; + data |= 1 << 5; + WRITE_VPP_REG(VPU_VLOCK_CTRL, data); + data &= ~(1 << 2); + data &= ~(1 << 5); + WRITE_VPP_REG(VPU_VLOCK_CTRL, data); +} + +void vlock_set_phase_en(u32 en) +{ + if (en) + vlock.dtdata->vlk_phlock_en = true; + else + vlock.dtdata->vlk_phlock_en = false; + pr_info("vlock phlock_en=%d\n", en); +} + +void vlock_phaselock_check(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + /*vs_i*/ + u32 ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); + u32 val; + static u32 cnt = 48; + + if (vlock.dtdata->vlk_phlock_en) { + if (cnt++ > 50) { + ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); + val = (ia * (100 + vlock.phlock_percent))/200; + WRITE_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT, val); + cnt = 0; + #if 0 + /*reset*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + #endif + } + } +} + +bool vlock_get_phlock_flag(void) +{ + u32 flag; + u32 sts; + + if (!vlock.dtdata->vlk_phlock_en) + return false; + + flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 17; + flag = flag&0x01; + + if (vlock.dtdata->vlk_new_fsm) + sts = vlock.fsm_sts; + else + sts = vlock_state; + + if (flag && (sts == VLOCK_STATE_ENABLE_STEP2_DONE)) + return true; + else + return false; +} + +bool vlock_get_vlock_flag(void) +{ + u32 flag; + u32 sts; + + flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 16; + flag = flag&0x01; + + if (vlock.dtdata->vlk_new_fsm) + sts = vlock.fsm_sts; + else + sts = vlock_state; + + if (flag && (sts == VLOCK_STATE_ENABLE_STEP2_DONE)) + return true; + else + return false; +} + +void vlock_enc_timing_monitor(void) +{ + static unsigned int pre_line, pre_pixel; + unsigned int cur_line, cur_pixel; + unsigned int val; + + val = READ_VPP_REG(VPU_VLOCK_RO_LINE_PIX_ADJ); + cur_pixel = (val & 0x0000ffff); + cur_line = (val >> 16) & 0x0000ffff; + + if ((cur_line != pre_line) || (cur_pixel != pre_pixel)) { + pr_info("vlock line=0x%x pixel=0x%x\n", + cur_line, cur_pixel); + pre_line = cur_line; + pre_pixel = cur_pixel; + } +} + +#if 1 + +u32 vlock_fsm_check_support(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = true; + + if (((pvlock->input_hz != pvlock->output_hz) && (vlock_adapt == 0)) || + (pvlock->input_hz == 0) || (pvlock->output_hz == 0) || + (((vf->type_original & VIDTYPE_TYPEMASK) + != VIDTYPE_PROGRESSIVE) && + is_meson_txlx_package_962E())) { + + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info("[%s] for no support case!!!\n", + __func__); + pr_info("input_hz:%d, output_hz:%d\n", + pvlock->input_hz, pvlock->output_hz); + pr_info("type_original:0x%x\n", vf->type_original); + } + ret = false; + } + + if (vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE_PRE) { + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s] for vmode change pre case!!!\n", + __func__); + ret = false; + } + + return ret; +} + +u32 vlock_fsm_input_check(struct stvlock_sig_sts *vlock, struct vframe_s *vf) +{ + u32 ret = 0; + u32 vframe_sts; + struct vinfo_s *vinfo = NULL; + + if (vf == NULL) + vframe_sts = false; + else + vframe_sts = true; + + vlock_vmode_check(); + + if (vf != NULL) { + vinfo = get_current_vinfo(); + vlock->input_hz = vlock_check_input_hz(vf); + vlock->output_hz = vlock_check_output_hz( + vinfo->sync_duration_num, vinfo->sync_duration_den); + } + + /*check vf exist status*/ + if (vlock->vf_sts != vframe_sts) { + vlock->vf_sts = vframe_sts; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("vlock vfsts chg %d\n", vframe_sts); + ret = 1; + } else if (vlock_vmode_change_status) { + /*check video mode status*/ + vlock->vmd_chg = true; + ret = 1; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("vlock vmode chg\n"); + } + + if (vlock->vf_sts) + vlock->md_support = vlock_fsm_check_support(vlock, vf); + + return ret; +} + +u32 vlock_fsm_to_en_func(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = 0; + struct vinfo_s *vinfo; + + if ((vf->source_type != pre_source_type) || + (vf->source_mode != pre_source_mode) || + (pvlock->input_hz != pre_input_freq) || + (pvlock->output_hz != pre_output_freq) || + vlock_vmode_changed || + (pvlock->fsm_sts == + VLOCK_STATE_ENABLE_FORCE_RESET)) { + + /*back up orignal pll value*/ + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &vlock.val_m);*/ + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &vlock.val_frac);*/ + vlock.val_m = vlock_get_panel_pll_m(); + vlock.val_frac = vlock_get_panel_pll_frac(); + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info("HIU pll m[0x%x]=0x%x\n", + hhi_pll_reg_m, vlock.val_m); + pr_info("HIU pll f[0x%x]=0x%x\n", + hhi_pll_reg_frac, vlock.val_frac); + } + vinfo = get_current_vinfo(); + vlock_enable_step1(vf, vinfo, + pvlock->input_hz, pvlock->output_hz); + ret = 1; + } + + return ret; +} + +u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = 0; + u32 input_vs_cnt; + + if ((pvlock->frame_cnt_in <= 3) && + ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | + VLOCK_MODE_MANUAL_PLL)))) { + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + /*clear first 3 frame internal cnt*/ + WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0); + WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s -0\n", __func__); + } else if ((pvlock->frame_cnt_in == 4) && + ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | + VLOCK_MODE_MANUAL_PLL)))) { + /*cal accum0 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + /*cal accum1 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s -1\n", __func__); + } else if (pvlock->frame_cnt_in == 5) { + /*input_vs_cnt =*/ + /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/ + /* 0, 28);*/ + input_vs_cnt = XTAL_VLOCK_CLOCK/pvlock->input_hz; + /*tl1 not need */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) && + vf->type_original & VIDTYPE_TYPEMASK) + input_vs_cnt = input_vs_cnt << 1; + + WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX, + input_vs_cnt*125/100); + WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN, + input_vs_cnt*70/100); + + /*cal accum1 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + /*cal accum0 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + + /* + * tl1 auto pll,swich clk need after + *several frames + */ + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + if (IS_AUTO_MODE(vlock_mode)) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x7, 0, 3); + else if (IS_MANUAL_MODE(vlock_mode)) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x6, 0, 3); + } + + ret = 1; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s -2\n", __func__); + } + + return ret; +} + +u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = 0; + + if (vlock_dynamic_adjust && + (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) && + (IS_MANUAL_MODE(vlock_mode))) { + if (IS_MANUAL_ENC_MODE(vlock_mode)) + vlock_enable_step3_enc(); + else if (IS_MANUAL_PLL_MODE(vlock_mode)) + vlock_enable_step3_pll(); + else if (IS_MANUAL_SOFTENC_MODE(vlock_mode)) + vlock_enable_step3_soft_enc(); + } + + if (IS_ENC_MODE(vlock_mode)) + vlock_enc_timing_monitor(); + + /*check phase*/ + vlock_phaselock_check(pvlock, vf); + return ret; +} + + +void vlock_fsm_monitor(struct vframe_s *vf) +{ + u32 changed; + + changed = vlock_fsm_input_check(&vlock, vf); + switch (vlock.fsm_sts) { + case VLOCK_STATE_NULL: + if (vlock.vf_sts) { + /*have frame in*/ + if (vlock.frame_cnt_in++ >= 20) { + /*vframe input valid*/ + if (vlock.md_support) { + if (vlock_fsm_to_en_func(&vlock, vf)) { + vlock_clear_frame_counter(); + vlock.fsm_sts = + VLOCK_STATE_ENABLE_STEP1_DONE; + } else { + /*error waitting here*/ + vlock_clear_frame_counter(); + } + } + } + } else if (vlock.vmd_chg) { + vlock_clear_frame_counter(); + vlock.vmd_chg = false; + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE; + } else { + /*disabled and waitting here*/ + vlock_clear_frame_counter(); + } + break; + + case VLOCK_STATE_ENABLE_STEP1_DONE: + if (vlock.vf_sts) { + vlock.frame_cnt_in++; + if (vlock_fsm_en_step1_func(&vlock, vf)) + vlock.fsm_sts = VLOCK_STATE_ENABLE_STEP2_DONE; + } else if (vlock.vmd_chg) { + vlock_clear_frame_counter(); + vlock.vmd_chg = false; + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else { + vlock.frame_cnt_in = 0; + if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) { + /*go to disable state*/ + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } + } + break; + + case VLOCK_STATE_ENABLE_STEP2_DONE: + if (vlock.vf_sts) { + if (!vlock.md_support) { + /*function not support*/ + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else if (vecm_latch_flag & FLAG_VLOCK_DIS) { + /*disable vlock by vecm cmd*/ + vlock_disable_step1(); + vlock_disable_step2(); + vlock_en = 0; + vecm_latch_flag &= ~FLAG_VLOCK_DIS; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s] vlock dis\n", __func__); + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_NULL; + } else { + /*normal mode*/ + vlock.frame_cnt_no = 0; + vlock_fsm_en_step2_func(&vlock, vf); + } + } else if (vlock.vmd_chg) { + vlock_clear_frame_counter(); + vlock.vmd_chg = false; + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else { + /*no frame input*/ + if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) { + /*go to disable state*/ + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } + } + break; + + case VLOCK_STATE_DISABLE_STEP1_DONE: + vlock_disable_step1(); + if (vlock_disable_step2()) + vlock.fsm_sts = VLOCK_STATE_NULL; + else + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE; + break; + + case VLOCK_STATE_DISABLE_STEP2_DONE: + if (vlock_disable_step2()) + vlock.fsm_sts = VLOCK_STATE_NULL; + break; + + default: + pr_info("err state %d\n", vlock.fsm_sts); + break; + } + + /*capture log*/ + if (((vlock_mode & (VLOCK_MODE_AUTO_PLL | + VLOCK_MODE_AUTO_ENC))) && + vlock_log_en && (vlock_log_cnt < vlock_log_size) && + (vlock_debug & VLOCK_DEBUG_AUTO_MODE_LOG_EN)) { + vlock_reg_get(); + vlock_log_cnt++; + } + + if ((vlock_debug & VLOCK_DEBUG_INFO) && + vlock.fsm_sts != vlock.fsm_prests) { + pr_info(">>> %s fsm %d to %d\n", __func__, + vlock.fsm_prests, vlock.fsm_sts); + vlock.fsm_prests = vlock.fsm_sts; + } +} +#endif + /*new packed separeted from amvecm_on_vs,avoid the influencec of repeate call, *which may affect vlock process */ void vlock_process(struct vframe_s *vf) { - if (probe_ok == 0) + if (probe_ok == 0 || !vlock_en) + return; + + if (vlock_debug & VLOCK_DEBUG_FSM_DIS) return; /* todo:vlock processs only for tv chip */ - if (is_meson_gxtvbb_cpu() || - is_meson_txl_cpu() || is_meson_txlx_cpu() - || is_meson_txhd_cpu()) { + if (vlock.dtdata->vlk_new_fsm) + vlock_fsm_monitor(vf); + else { if (vf != NULL) amve_vlock_process(vf); else @@ -1216,7 +2080,10 @@ void vlock_param_set(unsigned int val, enum vlock_param_e sel) } void vlock_status(void) { + struct vinfo_s *vinfo; + pr_info("\n current vlock parameters status:\n"); + pr_info("vlock driver version : %s\n", VLOCK_VER); pr_info("vlock_mode:%d\n", vlock_mode); pr_info("vlock_en:%d\n", vlock_en); pr_info("vlock_adapt:%d\n", vlock_adapt); @@ -1227,6 +2094,7 @@ void vlock_status(void) pr_info("vlock_debug:0x%x\n", vlock_debug); pr_info("vlock_dynamic_adjust:%d\n", vlock_dynamic_adjust); pr_info("vlock_state:%d\n", vlock_state); + pr_info("vecm_latch_flag:0x%x\n", vecm_latch_flag); pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag); pr_info("pre_hiu_reg_m:0x%x\n", pre_hiu_reg_m); pr_info("pre_hiu_reg_frac:0x%x\n", pre_hiu_reg_frac); @@ -1248,17 +2116,52 @@ void vlock_status(void) pr_info("vlock_intput_type:%d\n", vlock_intput_type); pr_info("vlock_pll_adj_limit:%d\n", vlock_pll_adj_limit); pr_info("vlock_pll_val_last:%d\n", vlock_pll_val_last); - pr_info("vlock driver version : %s\n", VLOCK_VER); + pr_info("vlk_fsm_sts:%d(2 is working)\n", vlock.fsm_sts); + pr_info("vlk_support:%d\n", vlock.dtdata->vlk_support); + pr_info("vlk_new_fsm:%d\n", vlock.dtdata->vlk_new_fsm); + pr_info("vlk_phlock_en:%d\n", vlock.dtdata->vlk_phlock_en); + pr_info("vlk_hwver:%d\n", vlock.dtdata->vlk_hwver); + pr_info("phlock flag:%d\n", vlock_get_phlock_flag()); + pr_info("vlock flag:%d\n", vlock_get_vlock_flag()); + pr_info("phase:%d\n", vlock.phlock_percent); + vinfo = get_current_vinfo(); + pr_info("vinfo sync_duration_num:%d\n", vinfo->sync_duration_num); + pr_info("vinfo sync_duration_den:%d\n", vinfo->sync_duration_den); + pr_info("vinfo video_clk:%d\n", vinfo->video_clk); + pr_info("vframe input_hz:%d\n", vlock.input_hz); + pr_info("vframe output_hz:%d\n", vlock.output_hz); } + void vlock_reg_dump(void) { unsigned int addr; + unsigned int val; pr_info("----dump vlock reg----\n"); for (addr = (0x3000); addr <= (0x3020); addr++) pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", (0xd0100000+(addr<<2)), addr, READ_VPP_REG(addr)); + + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + for (addr = (0x3021); addr <= (0x302b); addr++) + pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", + (0xd0100000+(addr<<2)), addr, + READ_VPP_REG(addr)); + amvecm_hiu_reg_read(HHI_HDMI_PLL_VLOCK_CNTL, &val); + pr_info("HIU [0x%04x]=0x%08x\n", HHI_HDMI_PLL_VLOCK_CNTL, val); + } + /*amvecm_hiu_reg_read(hhi_pll_reg_m, &val);*/ + val = vlock_get_panel_pll_m(); + pr_info("HIU pll m[0x%04x]=0x%08x\n", hhi_pll_reg_m, val); + /*amvecm_hiu_reg_read(hhi_pll_reg_frac, &val);*/ + val = vlock_get_panel_pll_frac(); + pr_info("HIU pll f[0x%04x]=0x%08x\n", hhi_pll_reg_frac, val); + + /*back up orignal pll value*/ + pr_info("HIU pll m[0x%x]=0x%x\n", hhi_pll_reg_m, vlock.val_m); + pr_info("HIU pll f[0x%x]=0x%x\n", hhi_pll_reg_frac, vlock.val_frac); + } /*work around method for vlock process hdmirx input interlace source.@20170803 **for interlace input,TOP and BOT have one line delta, @@ -1270,8 +2173,17 @@ void vlock_reg_dump(void) void vdin_vlock_input_sel(unsigned int type, enum vframe_source_type_e source_type) { + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) + return; + /* + *1:fromhdmi rx , + *2:from tv-decoder, + *3:from dvin, + *4:from dvin, + *5:from 2nd bt656 + */ vlock_intput_type = type & VIDTYPE_TYPEMASK; - if ((vlock_intput_type == 0) || + if ((vlock_intput_type == VIDTYPE_PROGRESSIVE) || (vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) return; if (vlock_intput_type == VIDTYPE_INTERLACE_TOP) { @@ -1351,6 +2263,7 @@ void vlock_param_config(struct device_node *node) vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC; vlock_mode |= VLOCK_MODE_MANUAL_PLL; } + pr_info("param_config vlock_en:%d\n", vlock_en); } int vlock_notify_callback(struct notifier_block *block, unsigned long cmd, @@ -1377,5 +2290,19 @@ int vlock_notify_callback(struct notifier_block *block, unsigned long cmd, return 0; } +static int __init phlock_phase_config(char *str) +{ + unsigned char *ptr = str; + + pr_info("%s: bootargs is %s.\n", __func__, str); + if (strstr(ptr, "1")) + vlock.phlock_percent = 99; + else + vlock.phlock_percent = 40; + + return 0; +} +__setup("video_reverse=", phlock_phase_config); + /*video lock end*/ diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h index 96784fb..a91b1c5 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.h +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.h @@ -23,7 +23,7 @@ #include #include "linux/amlogic/media/amvecm/ve.h" -#define VLOCK_VER "Ref.2018/11/07a" +#define VLOCK_VER "Ref.2019/1/24" #define VLOCK_REG_NUM 33 @@ -59,6 +59,21 @@ enum vlock_param_e { VLOCK_PARAM_MAX, }; +struct stvlock_sig_sts { + u32 fsm_sts; + u32 fsm_prests; + u32 vf_sts; + u32 vmd_chg; + u32 frame_cnt_in; + u32 frame_cnt_no; + u32 input_hz; + u32 output_hz; + bool md_support; + u32 phlock_percent; + struct vecm_match_data_s *dtdata; + u32 val_frac; + u32 val_m; +}; extern void amve_vlock_process(struct vframe_s *vf); extern void amve_vlock_resume(void); extern void vlock_param_set(unsigned int val, enum vlock_param_e sel); @@ -67,7 +82,7 @@ extern void vlock_reg_dump(void); extern void vlock_log_start(void); extern void vlock_log_stop(void); extern void vlock_log_print(void); - +extern int phase_lock_check(void); #define VLOCK_STATE_NULL 0 #define VLOCK_STATE_ENABLE_STEP1_DONE 1 @@ -77,12 +92,45 @@ extern void vlock_log_print(void); #define VLOCK_STATE_ENABLE_FORCE_RESET 5 /* video lock */ -#define VLOCK_MODE_AUTO_ENC (1 << 0) -#define VLOCK_MODE_AUTO_PLL (1 << 1) -#define VLOCK_MODE_MANUAL_PLL (1 << 2) -#define VLOCK_MODE_MANUAL_ENC (1 << 3) -#define VLOCK_MODE_MANUAL_SOFT_ENC (1 << 4) -#define VLOCK_MODE_MANUAL_MIX_PLL_ENC (1 << 5) +enum VLOCK_MD { + VLOCK_MODE_AUTO_ENC = 0x01, + VLOCK_MODE_AUTO_PLL = 0x02, + VLOCK_MODE_MANUAL_PLL = 0x04, + VLOCK_MODE_MANUAL_ENC = 0x08, + VLOCK_MODE_MANUAL_SOFT_ENC = 0x10, + VLOCK_MODE_MANUAL_MIX_PLL_ENC = 0x20, +}; + +#define IS_MANUAL_MODE(md) (md & \ + (VLOCK_MODE_MANUAL_PLL | \ + VLOCK_MODE_MANUAL_ENC | \ + VLOCK_MODE_MANUAL_SOFT_ENC)) + +#define IS_AUTO_MODE(md) (md & \ + (VLOCK_MODE_AUTO_PLL | \ + VLOCK_MODE_AUTO_ENC)) + +#define IS_PLL_MODE(md) (md & \ + (VLOCK_MODE_MANUAL_PLL | \ + VLOCK_MODE_AUTO_PLL)) + +#define IS_ENC_MODE(md) (md & \ + (VLOCK_MODE_MANUAL_ENC | \ + VLOCK_MODE_MANUAL_SOFT_ENC | \ + VLOCK_MODE_AUTO_ENC)) + +#define IS_AUTO_PLL_MODE(md) (md & \ + VLOCK_MODE_AUTO_PLL) + +#define IS_MANUAL_ENC_MODE(md) (md & \ + VLOCK_MODE_MANUAL_ENC) + +#define IS_MANUAL_PLL_MODE(md) (md & \ + VLOCK_MODE_MANUAL_PLL) + +#define IS_MANUAL_SOFTENC_MODE(md) (md & \ + VLOCK_MODE_MANUAL_SOFT_ENC) + #define XTAL_VLOCK_CLOCK 24000000/*vlock use xtal clock*/ @@ -95,18 +143,19 @@ extern void vlock_log_print(void); #define VLOCK_PLL_ADJ_LIMIT 9/*vlock pll adj limit(0x300a default)*/ /*vlock_debug mask*/ -#define VLOCK_DEBUG_INFO (1 << 0) -#define VLOCK_DEBUG_FLUSH_REG_DIS (1 << 1) -#define VLOCK_DEBUG_ENC_LINE_ADJ_DIS (1 << 2) -#define VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS (1 << 3) -#define VLOCK_DEBUG_AUTO_MODE_LOG_EN (1 << 4) -#define VLOCK_DEBUG_PLL2ENC_DIS (1 << 5) +#define VLOCK_DEBUG_INFO (0x1) +#define VLOCK_DEBUG_FLUSH_REG_DIS (0x2) +#define VLOCK_DEBUG_ENC_LINE_ADJ_DIS (0x4) +#define VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS (0x8) +#define VLOCK_DEBUG_AUTO_MODE_LOG_EN (0x10) +#define VLOCK_DEBUG_PLL2ENC_DIS (0x20) +#define VLOCK_DEBUG_FSM_DIS (0x40) /* 0:enc;1:pll;2:manual pll */ extern unsigned int vlock_mode; extern unsigned int vlock_en; extern unsigned int vecm_latch_flag; -extern void __iomem *amvecm_hiu_reg_base; +/*extern void __iomem *amvecm_hiu_reg_base;*/ extern unsigned int probe_ok; extern void lcd_ss_enable(bool flag); @@ -123,4 +172,9 @@ extern void vlock_lcd_param_work(struct work_struct *p_work); extern int vlock_notify_callback(struct notifier_block *block, unsigned long cmd, void *para); #endif +extern void vlock_status_init(void); +extern void vlock_dt_match_init(struct vecm_match_data_s *pdata); +extern void vlock_set_en(bool en); +extern void vlock_set_phase(u32 percent); +extern void vlock_set_phase_en(u32 en); diff --git a/drivers/amlogic/media/video_processor/pic_dev/picdec.c b/drivers/amlogic/media/video_processor/pic_dev/picdec.c index 7673c1f3..c9604ebc 100644 --- a/drivers/amlogic/media/video_processor/pic_dev/picdec.c +++ b/drivers/amlogic/media/video_processor/pic_dev/picdec.c @@ -787,6 +787,7 @@ static int picdec_memset_phyaddr(ulong phys, u32 size, u32 val) if (!p) return -1; memset(p, val, span); + codec_mm_dma_flush(p, span, DMA_TO_DEVICE); codec_mm_unmap_phyaddr(p); } return 0; @@ -896,6 +897,7 @@ static int copy_phybuf_to_file(ulong phys, u32 size, p = codec_mm_vmap(addr, span); if (!p) return -1; + codec_mm_dma_flush(p, span, DMA_FROM_DEVICE); vfs_write(fp, (char *)p, span, &pos); pos += span; diff --git a/drivers/amlogic/media/video_processor/video_dev/amlvideo2.c b/drivers/amlogic/media/video_processor/video_dev/amlvideo2.c index 8a58211..78a15aa 100644 --- a/drivers/amlogic/media/video_processor/video_dev/amlvideo2.c +++ b/drivers/amlogic/media/video_processor/video_dev/amlvideo2.c @@ -5054,6 +5054,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) } para.dest_hactive = dst_w; para.dest_vactive = dst_h; + para.reserved |= PARAM_STATE_SCREENCAP; if (para.scan_mode == TVIN_SCAN_MODE_INTERLACED) para.dest_vactive = para.dest_vactive / 2; if (para.port == TVIN_PORT_VIU1_VIDEO) { diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 6f54df4..61ecf76 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -4122,6 +4122,9 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) if (vf && (vf->source_type != VFRAME_SOURCE_TYPE_HDMI)) r |= (1 << 19); /* dos_uncomp */ + + if (type & VIDTYPE_COMB_MODE) + r |= (1 << 20); } VSYNC_WR_MPEG_REG(AFBC_ENABLE, r); diff --git a/drivers/amlogic/media/vin/tvin/bt656/bt656_601_in.c b/drivers/amlogic/media/vin/tvin/bt656/bt656_601_in.c index 0feac45..4f02b42 100644 --- a/drivers/amlogic/media/vin/tvin/bt656/bt656_601_in.c +++ b/drivers/amlogic/media/vin/tvin/bt656/bt656_601_in.c @@ -1129,7 +1129,8 @@ static int amvdec_656in_probe(struct platform_device *pdev) if (is_meson_gxtvbb_cpu() || is_meson_gxl_cpu() || is_meson_gxm_cpu() || is_meson_g12a_cpu() || - is_meson_g12b_cpu() || is_meson_tl1_cpu()) { + is_meson_g12b_cpu() || is_meson_tl1_cpu() || + is_meson_tm2_cpu()) { hw_cnt = 1; } else if (is_meson_gxbb_cpu()) { hw_cnt = 2; diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c index f05772e..ca523b0 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -765,6 +765,16 @@ void hdmirx_get_repetition_info(struct tvin_sig_property_s *prop) } /* + * hdmirx_get_allm_mode - get allm mode + */ +void hdmirx_get_latency_info(struct tvin_sig_property_s *prop) +{ + prop->latency.allm_mode = rx.vs_info_details.allm_mode; + prop->latency.it_content = it_content; + prop->latency.cn_type = rx.cur.cn_type; +} + +/* * hdmirx_get_hdr_info - get hdr info */ void hdmirx_get_hdr_info(struct tvin_sig_property_s *prop) @@ -858,6 +868,7 @@ void hdmirx_get_sig_property(struct tvin_frontend_s *fe, hdmirx_set_timing_info(prop); hdmirx_get_hdr_info(prop); hdmirx_get_vsi_info(prop); + hdmirx_get_latency_info(prop); prop->skip_vf_num = vdin_drop_frame_cnt; } diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 02fcd27..fb3d89a 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -40,7 +40,7 @@ * * */ -#define RX_VER1 "ver.2018/10/22" +#define RX_VER1 "ver.2018/12/24" /* * * @@ -200,6 +200,13 @@ enum map_addr_module_e { MAP_ADDR_MODULE_NUM }; +enum rx_cn_type_e { + CN_GRAPHICS, + CN_PHOTO, + CN_CINEMA, + CN_GAME, +}; + /** * @short HDMI RX controller video parameters * @@ -244,6 +251,7 @@ struct rx_video_info { enum hdmi_vic_e sw_vic; uint8_t sw_dvi; unsigned int it_content; + enum rx_cn_type_e cn_type; /** AVI Q1-0, RGB quantization range */ unsigned int rgb_quant_range; /** AVI Q1-0, YUV quantization range */ @@ -312,6 +320,7 @@ struct vsi_info_s { bool backlt_md_bit; unsigned int dolby_timeout; unsigned int eff_tmax_pq; + bool allm_mode; }; #define CHANNEL_STATUS_SIZE 24 diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c index f231444..d0394cf 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -2363,6 +2363,8 @@ void rx_get_video_info(void) /* AVI parameters */ rx.cur.hw_vic = hdmirx_rd_bits_dwc(DWC_PDEC_AVI_PB, VID_IDENT_CODE); + rx.cur.cn_type = + hdmirx_rd_bits_dwc(DWC_PDEC_AVI_HB, CONETNT_TYPE); rx.cur.repeat = hdmirx_rd_bits_dwc(DWC_PDEC_AVI_HB, PIX_REP_FACTOR); rx.cur.colorspace = diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h index 8c64f4e..e221be70 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -695,6 +695,8 @@ #define N_DECODED MSK(20, 0) /** Register address: auxiliary video information info frame */ #define DWC_PDEC_AVI_HB (0x3A0UL) +/** AVI content type*/ +#define CONETNT_TYPE MSK(2, 28) /** PR3-0, pixel repetition factor */ #define PIX_REP_FACTOR MSK(4, 24) /** Q1-0, YUV quantization range */ diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c index 953e819..d9cdd8d 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c @@ -1391,6 +1391,10 @@ void rx_get_vsi_info(void) ((pkt->sbpkt.payload.data[0] & 0xff) == 0)) { rx.vs_info_details.dolby_vision = false; } + } else if (pkt->ieee == 0xd85dc4) { + /*TODO:hdmi2.1 spec vsi packet*/ + tmp = pkt->sbpkt.payload.data[0] & _BIT(9); + rx.vs_info_details.allm_mode = tmp ? true : false; } else { /*3d VSI*/ if (pkt->sbpkt.vsi_3Dext.vdfmt == VSI_FORMAT_3D_FORMAT) { diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h index c9fcc1a..8a7f020 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h @@ -617,7 +617,18 @@ struct vsi_infoframe_st { /*pb6*/ uint8_t data[22];/* val=0 */ } __packed vsi_DobV; - + /*TODO:hdmi2.1 spec vsi packet*/ + struct vsi_st_21 { + /*pb4*/ + uint8_t ver:8; + /*pb5*/ + uint8_t threeD_valid:1; + uint8_t allm_mode:1; + uint8_t rsvd1:2; + uint8_t ccbpc:4; + /*pb6*/ + /*todo*/ + } __packed vsi_st_21; } __packed sbpkt; } __packed; diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c index f9e2416..630042c 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c @@ -101,6 +101,8 @@ static int cutwindow_val_h_level2 = 18; static int cutwindow_val_h_level3 = 20; static int cutwindow_val_h_level4 = 62;/*48-->62 for ntsc-m*/ +/*tvconfig snow config*/ +static bool snow_cfg; /*1: snow function on;*/ /*0: off snow function*/ bool tvafe_snow_function_flag; @@ -259,7 +261,8 @@ int tvafe_dec_open(struct tvin_frontend_s *fe, enum tvin_port_e port) #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT /*only txlx chip enabled*/ if (tvafe_cpu_type() == CPU_TYPE_TXLX || - tvafe_cpu_type() == CPU_TYPE_TL1) { + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2) { /*synctip set to 0 when tvafe working&&av connected*/ /*enable clamp if av connected*/ if (port == TVIN_PORT_CVBS1) { @@ -323,6 +326,7 @@ void tvafe_dec_start(struct tvin_frontend_s *fe, enum tvin_sig_fmt_e fmt) enum tvin_port_e port = devp->tvafe.parm.port; mutex_lock(&devp->afe_mutex); + manual_flag = 0; if (!(devp->flags & TVAFE_FLAG_DEV_OPENED)) { tvafe_pr_err("tvafe_dec_start(%d) decode havn't opened\n", @@ -352,7 +356,9 @@ void tvafe_dec_start(struct tvin_frontend_s *fe, enum tvin_sig_fmt_e fmt) W_APB_REG(CVD2_H_LOOP_MAXSTATE, 0x9); #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT - if (tvafe_cpu_type() == CPU_TYPE_TXLX) { + if (tvafe_cpu_type() == CPU_TYPE_TXLX || + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2) { if (port == TVIN_PORT_CVBS1) tvafe_avin_detect_ch1_anlog_enable(0); else if (port == TVIN_PORT_CVBS2) @@ -418,7 +424,9 @@ void tvafe_dec_stop(struct tvin_frontend_s *fe, enum tvin_port_e port) tvafe_cvd2_set_default_de(&tvafe->cvd2); } #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT - if (tvafe_cpu_type() == CPU_TYPE_TXLX) { + if (tvafe_cpu_type() == CPU_TYPE_TXLX || + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2) { if (port == TVIN_PORT_CVBS1) tvafe_avin_detect_ch1_anlog_enable(1); else if (port == TVIN_PORT_CVBS2) @@ -487,7 +495,8 @@ void tvafe_dec_close(struct tvin_frontend_s *fe) #endif #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AVDETECT if (tvafe_cpu_type() == CPU_TYPE_TXLX || - tvafe_cpu_type() == CPU_TYPE_TL1) { + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2) { /*avsync tip set 1 to resume av detect*/ if (tvafe->parm.port == TVIN_PORT_CVBS1) { avport_opened = 0; @@ -645,6 +654,17 @@ bool tvafe_is_nosig(struct tvin_frontend_s *fe) if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_CVBS3)) { ret = tvafe_cvd2_no_sig(&tvafe->cvd2, &devp->mem); + /*fix black side when config atv snow*/ + if (ret && (port == TVIN_PORT_CVBS3) && + (devp->flags & TVAFE_FLAG_DEV_SNOW_FLAG) && + (tvafe->cvd2.config_fmt == TVIN_SIG_FMT_CVBS_PAL_I) && + (tvafe->cvd2.info.state != TVAFE_CVD2_STATE_FIND)) + tvafe_snow_config_acd(); + else if ((tvafe->cvd2.config_fmt == TVIN_SIG_FMT_CVBS_PAL_I) && + (tvafe->cvd2.info.state == TVAFE_CVD2_STATE_FIND) && + (port == TVIN_PORT_CVBS3)) + tvafe_snow_config_acd_resume(); + /* normal sigal & adc reg error, reload source mux */ if (tvafe->cvd2.info.adc_reload_en && !ret) tvafe_set_source_muxing(port, devp->pinmux); @@ -808,6 +828,18 @@ static bool tvafe_cvbs_get_secam_phase(struct tvin_frontend_s *fe) } +bool tvafe_get_snow_cfg(void) +{ + return snow_cfg; +} +EXPORT_SYMBOL(tvafe_get_snow_cfg); + +void tvafe_set_snow_cfg(bool cfg) +{ + snow_cfg = cfg; +} +EXPORT_SYMBOL(tvafe_set_snow_cfg); + /**check frame skip,only for av input*/ static bool tvafe_cvbs_check_frame_skip(struct tvin_frontend_s *fe) { @@ -878,6 +910,7 @@ static long tvafe_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret = 0; + unsigned int snowcfg = 0; void __user *argp = (void __user *)arg; struct tvafe_dev_s *devp = file->private_data; struct tvafe_info_s *tvafe = &devp->tvafe; @@ -893,8 +926,8 @@ static long tvafe_ioctl(struct file *file, return -EPERM; mutex_lock(&devp->afe_mutex); - if (!(devp->flags & TVAFE_FLAG_DEV_OPENED)) { - + if (!(devp->flags & TVAFE_FLAG_DEV_OPENED) && + cmd != TVIN_IOC_S_AFE_SONWCFG) { tvafe_pr_info("%s, tvafe device is disable, ignore the command %d\n", __func__, cmd); mutex_unlock(&devp->afe_mutex); @@ -922,6 +955,20 @@ static long tvafe_ioctl(struct file *file, break; } + case TVIN_IOC_S_AFE_SONWCFG: + /*tl1/txhd tvconfig snow en/disable*/ + if (copy_from_user(&snowcfg, argp, + sizeof(unsigned int))) { + tvafe_pr_info("snowcfg: get param err\n"); + ret = -EINVAL; + break; + } + if (snowcfg == 1) + tvafe_set_snow_cfg(true); + else + tvafe_set_snow_cfg(false); + tvafe_pr_info("tvconfig snow:%d\n", snow_cfg); + break; case TVIN_IOC_S_AFE_SONWON: devp->flags |= TVAFE_FLAG_DEV_SNOW_FLAG; tvafe_snow_function_flag = true; @@ -963,6 +1010,8 @@ static long tvafe_ioctl(struct file *file, tvafe->cvd2.manual_fmt = fmt; tvafe_pr_info("%s: ioctl set cvd2 manual fmt:%s.\n", __func__, tvin_sig_fmt_str(fmt)); + if (fmt != TVIN_SIG_FMT_NULL) + manual_flag = 1; break; } default: @@ -1145,6 +1194,11 @@ struct meson_tvafe_data meson_tl1_tvafe_data = { .name = "meson-tl1-tvafe", }; +struct meson_tvafe_data meson_tm2_tvafe_data = { + .cpu_id = CPU_TYPE_TM2, + .name = "meson-tm2-tvafe", +}; + static const struct of_device_id meson_tvafe_dt_match[] = { { .compatible = "amlogic, tvafe-gxtvbb", @@ -1161,6 +1215,9 @@ static const struct of_device_id meson_tvafe_dt_match[] = { }, { .compatible = "amlogic, tvafe-tl1", .data = &meson_tl1_tvafe_data, + }, { + .compatible = "amlogic, tvafe-tm2", + .data = &meson_tm2_tvafe_data, }, {}, }; diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe.h b/drivers/amlogic/media/vin/tvin/tvafe/tvafe.h index 7fe836f..0c42042 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe.h +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe.h @@ -32,7 +32,7 @@ /* ************************************************* */ /* *** macro definitions ********************************************* */ /* *********************************************************** */ -#define TVAFE_VER "Ref.2018/06/27" +#define TVAFE_VER "Ref.2019/03/18" /* used to set the flag of tvafe_dev_s */ #define TVAFE_FLAG_DEV_OPENED 0x00000010 @@ -94,6 +94,9 @@ struct tvafe_dev_s { unsigned int sizeof_tvafe_dev_s; }; +bool tvafe_get_snow_cfg(void); +void tvafe_set_snow_cfg(bool cfg); + typedef int (*hook_func_t)(void); extern void aml_fe_hook_cvd(hook_func_t atv_mode, hook_func_t cvd_hv_lock, hook_func_t get_fmt); diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.c index 60759b1..b697da41 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.c @@ -933,12 +933,20 @@ struct meson_avin_data tl1_data = { .name = "meson-tl1-avin-detect", }; +struct meson_avin_data tm2_data = { + .cpu_id = AVIN_CPU_TYPE_TM2, + .name = "meson-tm2-avin-detect", +}; + static const struct of_device_id tvafe_avin_dt_match[] = { { .compatible = "amlogic, tvafe_avin_detect", }, { .compatible = "amlogic, tl1_tvafe_avin_detect", .data = &tl1_data, }, + { .compatible = "amlogic, tm2_tvafe_avin_detect", + .data = &tm2_data, + }, {}, }; #else diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.h b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.h index f95f06e..6c8c765 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.h +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.h @@ -136,6 +136,7 @@ enum avin_cpu_type { AVIN_CPU_TYPE_TXLX = 1, AVIN_CPU_TYPE_TXHD = 2, AVIN_CPU_TYPE_TL1 = 3, + AVIN_CPU_TYPE_TM2 = 4, AVIN_CPU_TYPE_MAX, }; diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c index 610992f..2e3ff29 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c @@ -27,6 +27,7 @@ #include #include "../tvin_global.h" #include "../tvin_format_table.h" +#include "tvafe.h" #include "tvafe_regs.h" #include "tvafe_cvd.h" #include "tvafe_debug.h" @@ -418,8 +419,10 @@ static void tvafe_cvd2_write_mode_reg(struct tvafe_cvd2_s *cvd2, } /*setting for txhd snow*/ - if (tvafe_cpu_type() == CPU_TYPE_TXHD || - tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_get_snow_cfg() && + (tvafe_cpu_type() == CPU_TYPE_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2)) { W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, 5, 2); W_APB_REG(ACD_REG_6C, 0x80500000); } @@ -1872,15 +1875,15 @@ static void tvafe_cvd2_auto_de(struct tvafe_cvd2_s *cvd2) W_APB_REG(ACD_REG_2E, tmp); scene_colorful_old = 0; if (cvd_dbg_en) - tvafe_pr_info("%s: vlines:%d, de_offset:%d tmp:%x\n", + tvafe_pr_info("%s: lrg vlines:%d, de_offset:%d tmp:%x\n", __func__, l_ave, lines->de_offset, tmp); } } else { if (lines->de_offset > 0) { tmp = ((TVAFE_CVD2_PAL_DE_START - - lines->de_offset) << 16) | + lines->de_offset + 1) << 16) | (288 + TVAFE_CVD2_PAL_DE_START - - lines->de_offset); + lines->de_offset + 1); W_APB_REG(ACD_REG_2E, tmp); scene_colorful_old = 0; if (cvd_dbg_en) @@ -1994,6 +1997,12 @@ static void tvafe_cvd2_reinit(struct tvafe_cvd2_s *cvd2) #ifdef TVAFE_SET_CVBS_PGA_EN tvafe_cvd2_reset_pga(); #endif + /*pali to nosignal,restore default vstart-end after auto de*/ + if (cvd2->config_fmt == TVIN_SIG_FMT_CVBS_PAL_I) { + W_APB_REG(ACD_REG_2E, 0x170137); + if (cvd_dbg_en) + pr_info("[tvafe..] %s: reset auto de.\n", __func__); + } /* init variable */ memset(&cvd2->info, 0, sizeof(struct tvafe_cvd2_info_s)); cvd2->cvd2_init_en = true; @@ -2320,6 +2329,15 @@ inline void tvafe_cvd2_adj_hs(struct tvafe_cvd2_s *cvd2, cvd2->info.hs_adj_level = 0; acd_h = acd_h_back; } + } else { + /*signal unstable,set default value*/ + W_APB_REG(ACD_REG_2D, acd_h_back); + W_APB_BIT(CVD2_ACTIVE_VIDEO_HSTART, cvd_2e, + HACTIVE_START_BIT, HACTIVE_START_WID); + W_APB_BIT(ACD_REG_28, acd_128, 16, 5); + cvd2->info.hs_adj_en = 0; + cvd2->info.hs_adj_level = 0; + acd_h = acd_h_back; } } @@ -2606,7 +2624,8 @@ void tvafe_snow_config(unsigned int onoff) { if (tvafe_snow_function_flag == 0 || tvafe_cpu_type() == CPU_TYPE_TXHD || - tvafe_cpu_type() == CPU_TYPE_TL1) + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2) return; if (onoff) W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, BLUE_MODE_BIT, BLUE_MODE_WID); @@ -2617,7 +2636,8 @@ void tvafe_snow_config(unsigned int onoff) void tvafe_snow_config_clamp(unsigned int onoff) { if (tvafe_cpu_type() == CPU_TYPE_TXHD || - tvafe_cpu_type() == CPU_TYPE_TL1) { + tvafe_cpu_type() == CPU_TYPE_TL1 || + tvafe_cpu_type() == CPU_TYPE_TM2) { if (onoff) vdin_adjust_tvafesnow_brightness(); return; @@ -2637,7 +2657,6 @@ void tvafe_snow_config_acd(void) /*0x8e035e is debug test result*/ if (acd_h_config) W_APB_REG(ACD_REG_2D, acd_h_config); - acd_h = acd_h_back; } /*only for pal-i*/ void tvafe_snow_config_acd_resume(void) diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_debug.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_debug.c index 44993fd..f6786fe 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_debug.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_debug.c @@ -256,6 +256,18 @@ static ssize_t tvafe_store(struct device *dev, } } else if (!strncmp(buff, "afe_ver", strlen("afe_ver"))) { tvafe_pr_info("tvafe version : %s\n", TVAFE_VER); + } else if (!strncmp(buff, "snowcfg", strlen("snowcfg"))) { + if (kstrtoul(parm[1], 10, &val) < 0) { + kfree(buf_orig); + return -EINVAL; + } + if (val) { + tvafe_set_snow_cfg(true); + tvafe_pr_info("[tvafe..]hadware snow cfg en\n"); + } else { + tvafe_set_snow_cfg(false); + tvafe_pr_info("[tvafe..]hadware snow cfg dis\n"); + } } else if (!strncmp(buff, "snowon", strlen("snowon"))) { if (kstrtoul(parm[1], 10, &val) < 0) { kfree(buf_orig); diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c index 70c8faa..3f7be31 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c @@ -247,21 +247,23 @@ static enum tvafe_adc_ch_e tvafe_adc_pin_muxing( if (tvafe_cpu_type() == CPU_TYPE_TXL || tvafe_cpu_type() == CPU_TYPE_TXLX || tvafe_cpu_type() == CPU_TYPE_TXHD || - tvafe_cpu_type() == CPU_TYPE_TL1) { + tvafe_cpu_type() >= CPU_TYPE_TL1) { tvafe_pr_info("[tvafe]%s:pin:%d\n", __func__, (unsigned int)pin); if (pin == TVAFE_CVBS_IN0) { W_APB_BIT(TVFE_VAFE_CTRL1, 1, VAFE_IN_SEL_BIT, VAFE_IN_SEL_WID); - W_APB_BIT(TVFE_VAFE_CTRL2, 3, 4, 3); + if (tvafe_cpu_type() < CPU_TYPE_TL1) + W_APB_BIT(TVFE_VAFE_CTRL2, 3, 4, 3); ret = TVAFE_ADC_CH_0; } else if (pin == TVAFE_CVBS_IN1) { W_APB_BIT(TVFE_VAFE_CTRL1, 2, VAFE_IN_SEL_BIT, VAFE_IN_SEL_WID); - W_APB_BIT(TVFE_VAFE_CTRL2, 5, 4, 3); + if (tvafe_cpu_type() < CPU_TYPE_TL1) + W_APB_BIT(TVFE_VAFE_CTRL2, 5, 4, 3); ret = TVAFE_ADC_CH_1; } else if (pin == TVAFE_CVBS_IN2) { @@ -384,7 +386,7 @@ static void tvafe_set_cvbs_default(struct tvafe_cvd2_s *cvd2, unsigned int i = 0; /**disable auto mode clock**/ - if (tvafe_cpu_type() != CPU_TYPE_TL1) + if (tvafe_cpu_type() < CPU_TYPE_TL1) W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0); /*config adc*/ @@ -400,7 +402,7 @@ static void tvafe_set_cvbs_default(struct tvafe_cvd2_s *cvd2, W_HIU_REG(HHI_DADC_CNTL, 0x00102038); W_HIU_REG(HHI_DADC_CNTL2, 0x00000401); W_HIU_REG(HHI_DADC_CNTL3, 0x00082183); - } else if (tvafe_cpu_type() == CPU_TYPE_TL1) { + } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) { /** DADC CNTL for LIF signal input **/ W_HIU_REG(HHI_DADC_CNTL, 0x0030303c); W_HIU_REG(HHI_DADC_CNTL2, 0x00003480); @@ -421,7 +423,7 @@ static void tvafe_set_cvbs_default(struct tvafe_cvd2_s *cvd2, W_HIU_REG(HHI_DADC_CNTL, 0x00102038); W_HIU_REG(HHI_DADC_CNTL2, 0x00000400); W_HIU_REG(HHI_DADC_CNTL3, 0x00082183); - } else if (tvafe_cpu_type() == CPU_TYPE_TL1) { + } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) { W_HIU_REG(HHI_DADC_CNTL, 0x0030303c); W_HIU_REG(HHI_DADC_CNTL2, 0x00003400); W_HIU_REG(HHI_DADC_CNTL3, 0x08300b83); @@ -440,8 +442,8 @@ static void tvafe_set_cvbs_default(struct tvafe_cvd2_s *cvd2, if (tvafe_cpu_type() == CPU_TYPE_TXL || tvafe_cpu_type() == CPU_TYPE_TXLX || tvafe_cpu_type() == CPU_TYPE_TXHD || - tvafe_cpu_type() == CPU_TYPE_TL1) { - if (tvafe_cpu_type() == CPU_TYPE_TL1) { + tvafe_cpu_type() >= CPU_TYPE_TL1) { + if (tvafe_cpu_type() >= CPU_TYPE_TL1) { if (port == TVIN_PORT_CVBS3) { W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710); W_APB_REG(TVFE_VAFE_CTRL1, 0x00003000); @@ -550,7 +552,7 @@ void tvafe_set_ddemod_default(void) W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710); W_APB_REG(TVFE_VAFE_CTRL1, 0x0); W_APB_REG(TVFE_VAFE_CTRL2, 0x1010eeb0); - } else if (tvafe_cpu_type() == CPU_TYPE_TL1) { + } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) { W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710); W_APB_REG(TVFE_VAFE_CTRL1, 0x3000); W_APB_REG(TVFE_VAFE_CTRL2, 0x1fe09e31); @@ -571,7 +573,7 @@ void tvafe_enable_avout(enum tvin_port_e port, bool enable) if (tvafe_cpu_type() == CPU_TYPE_TXL || tvafe_cpu_type() == CPU_TYPE_TXLX || tvafe_cpu_type() == CPU_TYPE_TXHD || - tvafe_cpu_type() == CPU_TYPE_TL1) { + tvafe_cpu_type() >= CPU_TYPE_TL1) { if (enable) { tvafe_clk_gate_ctrl(1); if (port == TVIN_PORT_CVBS3) { @@ -627,7 +629,7 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) break; } mutex_lock(&pll_mutex); - if (tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_cpu_type() >= CPU_TYPE_TL1) { do { W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0); W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0); @@ -690,7 +692,7 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) break; } mutex_lock(&pll_mutex); - if (tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_cpu_type() >= CPU_TYPE_TL1) { do { W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0); W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0); @@ -781,7 +783,7 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) break; } mutex_lock(&pll_mutex); - if (tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_cpu_type() >= CPU_TYPE_TL1) { do { W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0); W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0); @@ -888,7 +890,7 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) W_HIU_REG(HHI_DEMOD_CLK_CNTL, 0x1000502); adc_pll_lock_cnt = 1; - } else if (tvafe_cpu_type() == CPU_TYPE_TL1) { + } else if (tvafe_cpu_type() >= CPU_TYPE_TL1) { do {//25M W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x001104c8); W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x301104c8); @@ -973,7 +975,7 @@ void tvafe_init_reg(struct tvafe_cvd2_s *cvd2, if ((port >= TVIN_PORT_CVBS0) && (port <= TVIN_PORT_CVBS3)) { #ifdef CRYSTAL_25M - if (tvafe_cpu_type() != CPU_TYPE_TL1) + if (tvafe_cpu_type() < CPU_TYPE_TL1) W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0x703);/* can't write !!! */ #endif @@ -1033,7 +1035,7 @@ void tvafe_enable_module(bool enable) /* enable */ /* main clk up */ - if (tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_cpu_type() >= CPU_TYPE_TL1) { W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 1, VAFE_CLK_SELECT, VAFE_CLK_SELECT_WIDTH); W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 1, @@ -1076,7 +1078,7 @@ void tvafe_enable_module(bool enable) TVFE_ADC_CLK_DIV_WID); /* main clk down */ - if (tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_cpu_type() >= CPU_TYPE_TL1) { W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 0, VAFE_CLK_SELECT, VAFE_CLK_SELECT_WIDTH); W_HIU_BIT(HHI_ATV_DMD_SYS_CLK_CNTL, 0, diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h index 85d6a32..2fa4bcb 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h @@ -159,6 +159,7 @@ enum tvafe_cpu_type { CPU_TYPE_TXHD = 3, CPU_TYPE_GXLX = 4, CPU_TYPE_TL1 = 5, + CPU_TYPE_TM2 = 6, }; struct meson_tvafe_data { diff --git a/drivers/amlogic/media/vin/tvin/tvin_global.h b/drivers/amlogic/media/vin/tvin/tvin_global.h index c6d053b..78f4b40 100644 --- a/drivers/amlogic/media/vin/tvin/tvin_global.h +++ b/drivers/amlogic/media/vin/tvin/tvin_global.h @@ -116,6 +116,15 @@ static inline uint32_t R_APB_BIT(uint32_t reg, return val; } +static inline void W_VCBUS(uint32_t reg, const uint32_t value) +{ + aml_write_vcbus(reg, value); +} + +static inline uint32_t R_VCBUS(uint32_t reg) +{ + return aml_read_vcbus(reg); +} static inline void W_VCBUS_BIT(uint32_t reg, const uint32_t value, @@ -438,6 +447,19 @@ struct tvin_hdr_info_s { unsigned int hdr_check_cnt; }; +enum tvin_cn_type_e { + GRAPHICS, + PHOTO, + CINEMA, + GAME, +}; + +struct tvin_latency_s { + bool allm_mode; + bool it_content; + enum tvin_cn_type_e cn_type; +}; + struct tvin_sig_property_s { enum tvin_trans_fmt trans_fmt; enum tvin_color_fmt_e color_format; @@ -464,6 +486,7 @@ struct tvin_sig_property_s { bool low_latency;/*is low latency dolby mode*/ uint8_t fps; unsigned int skip_vf_num;/*skip pre vframe num*/ + struct tvin_latency_s latency; }; #define TVAFE_VF_POOL_SIZE 6 /* 8 */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/Makefile b/drivers/amlogic/media/vin/tvin/vdin/Makefile index 7f0c556..b8092e9 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/Makefile +++ b/drivers/amlogic/media/vin/tvin/vdin/Makefile @@ -1,6 +1,11 @@ # # Makefile for Vdin. # +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +ccflags-y := -DDEBUG_SUPPORT +else +ccflags-y := -DDEBUG +endif obj-$(CONFIG_AMLOGIC_MEDIA_VDIN) = tvin_vdin.o tvin_vdin-objs += vdin_v4l2.o tvin_vdin-objs += vdin_vf.o diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c index eaa9d73..50fbf47 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c @@ -57,352 +57,157 @@ #include "vdin_canvas.h" #include "vdin_afbce.h" -static unsigned int max_buf_num = VDIN_CANVAS_MAX_CNT; -static unsigned int min_buf_num = 4; -static unsigned int max_buf_width = VDIN_CANVAS_MAX_WIDTH_HD; -static unsigned int max_buf_height = VDIN_CANVAS_MAX_HEIGH; -/* one frame max metadata size:32x280 bits = 1120bytes(0x460) */ -unsigned int dolby_size_bytes = PAGE_SIZE; - -unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp) +/* fixed config mif by default */ +void vdin_mif_config_init(struct vdin_dev_s *devp) { - char vdin_name[6]; - unsigned int mem_size, h_size, v_size; - int flags = CODEC_MM_FLAGS_CMA_FIRST|CODEC_MM_FLAGS_CMA_CLEAR| - CODEC_MM_FLAGS_CPU; - unsigned int max_buffer_num = min_buf_num; - unsigned int i; - /*afbce head need 1036800 byte at most*/ - unsigned int afbce_head_size_byte = PAGE_SIZE * 300;/*1.2M*/ - /*afbce map_table need 218700 byte at most*/ - unsigned int afbce_table_size_byte = PAGE_SIZE * 60;/*0.3M*/ - unsigned int afbce_mem_used; - unsigned int frame_head_size; - unsigned int mmu_used; - //unsigned long afbce_head_phy_addr; - //unsigned long afbce_table_phy_addr; - unsigned long body_start_paddr; - - if (devp->rdma_enable) - max_buffer_num++; - /*todo: need update if vf_skip_cnt used by other port*/ - if (devp->vfp->skip_vf_num && - (((devp->parm.port >= TVIN_PORT_HDMI0) && - (devp->parm.port <= TVIN_PORT_HDMI7)) || - ((devp->parm.port >= TVIN_PORT_CVBS0) && - (devp->parm.port <= TVIN_PORT_CVBS3)))) - max_buffer_num += devp->vfp->skip_vf_num; - if (max_buffer_num > max_buf_num) - max_buffer_num = max_buf_num; - devp->vfmem_max_cnt = max_buffer_num; - devp->canvas_max_num = max_buffer_num; - - if ((devp->cma_config_en == 0) || - (devp->cma_mem_alloc == 1)) { - pr_info("\nvdin%d %s use_reserved mem or cma already alloced (%d,%d)!!!\n", - devp->index, __func__, devp->cma_config_en, - devp->cma_mem_alloc); - return 0; - } - h_size = devp->h_active; - v_size = devp->v_active; - if (devp->canvas_config_mode == 1) { - h_size = max_buf_width; - v_size = max_buf_height; - } - if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_RGB) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_GBR) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_BRG) || - (devp->force_yuv444_malloc == 1)) { - if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && - (devp->color_depth_mode != 1)) { - h_size = roundup(h_size * - VDIN_YUV444_10BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV444_10BIT_PER_PIXEL_BYTE; - } else { - h_size = roundup(h_size * - VDIN_YUV444_8BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV444_8BIT_PER_PIXEL_BYTE; - } - } else if ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_NV12) || - (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_NV21) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_NV12) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_NV21)) { - h_size = roundup(h_size, devp->canvas_align); - devp->canvas_alin_w = h_size; - /*todo change with canvas alloc!!*/ - /* nv21/nv12 only have 8bit mode */ + if (devp->index == 0) { + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_MIF_ENABLE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 0, VDIN0_OUT_AFBCE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_OUT_MIF_BIT, 1); } else { - /* txl new add mode yuv422 pack mode:canvas-w=h*2*10/8 - *canvas_w must ensure divided exact by 256bit(32byte - */ - if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && - ((devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422) || - (devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) && - (devp->color_depth_mode == 1)) { - h_size = roundup((h_size * 5)/2, devp->canvas_align); - devp->canvas_alin_w = (h_size * 2) / 5; - } else if ((devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH) && - (devp->color_depth_mode == 0)) { - h_size = roundup(h_size * - VDIN_YUV422_10BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV422_10BIT_PER_PIXEL_BYTE; - } else { - h_size = roundup(h_size * - VDIN_YUV422_8BIT_PER_PIXEL_BYTE, - devp->canvas_align); - devp->canvas_alin_w = h_size / - VDIN_YUV422_8BIT_PER_PIXEL_BYTE; - } + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN1_MIF_ENABLE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 0, VDIN1_OUT_AFBCE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN1_OUT_MIF_BIT, 1); } - mem_size = h_size * v_size; - if ((devp->format_convert >= VDIN_FORMAT_CONVERT_YUV_NV12) && - (devp->format_convert <= VDIN_FORMAT_CONVERT_RGB_NV21)) - mem_size = (mem_size * 3)/2; - devp->vfmem_size = PAGE_ALIGN(mem_size) + dolby_size_bytes; - devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE; - - mem_size = PAGE_ALIGN(mem_size) * max_buffer_num + - dolby_size_bytes * max_buffer_num; - mem_size = (mem_size/PAGE_SIZE + 1)*PAGE_SIZE; - if (mem_size > devp->cma_mem_size) - mem_size = devp->cma_mem_size; - if (devp->index == 0) - strcpy(vdin_name, "vdin0"); - else if (devp->index == 1) - strcpy(vdin_name, "vdin1"); - - - if (devp->cma_config_flag == 0x101) { - devp->afbce_info->head_paddr = codec_mm_alloc_for_dma( - vdin_name, afbce_head_size_byte/PAGE_SIZE, 0, flags); - devp->afbce_info->table_paddr = codec_mm_alloc_for_dma( - vdin_name, afbce_table_size_byte/PAGE_SIZE, 0, flags); - devp->afbce_info->head_size = afbce_head_size_byte; - devp->afbce_info->table_size = afbce_table_size_byte; - devp->afbce_info->frame_body_size = devp->vfmem_size; - - pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", - devp->index, devp->afbce_info->head_paddr, - devp->afbce_info->head_size); - pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", - devp->index, devp->afbce_info->table_paddr, - devp->afbce_info->table_size); - - /* set fm_body_paddr */ - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_body_paddr[i] = - codec_mm_alloc_for_dma(vdin_name, - devp->vfmem_size/PAGE_SIZE, 0, flags); - if (devp->afbce_info->fm_body_paddr[i] == 0) { - pr_err("\nvdin%d-afbce buf[%d]codec alloc fail!!!\n", - devp->index, i); - devp->cma_mem_alloc = 0; - } else { - devp->cma_mem_alloc = 1; - pr_info("vdin%d fm_body_paddr[%d] = 0x%lx, body_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_body_paddr[i], - devp->afbce_info->frame_body_size); - } - - if (devp->cma_mem_alloc == 0) - return 1; - } - pr_info("vdin%d-afbce codec cma alloc ok!\n", devp->index); - devp->mem_size = mem_size; - } else if (devp->cma_config_flag == 0) { - devp->venc_pages = dma_alloc_from_contiguous( - &(devp->this_pdev->dev), - devp->cma_mem_size >> PAGE_SHIFT, 0); - if (devp->venc_pages) { - devp->mem_start = - page_to_phys(devp->venc_pages); - devp->mem_size = mem_size; - devp->cma_mem_alloc = 1; - - devp->afbce_info->head_paddr = devp->mem_start; - devp->afbce_info->head_size = 2*SZ_1M;/*2M*/ - devp->afbce_info->table_paddr = - devp->mem_start + devp->afbce_info->head_paddr; - devp->afbce_info->table_size = 2*SZ_1M;/*2M*/ - devp->afbce_info->frame_body_size = devp->vfmem_size; - - body_start_paddr = devp->afbce_info->table_paddr + - devp->afbce_info->table_size; - - pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", - devp->index, devp->afbce_info->head_paddr, - devp->afbce_info->head_size); - pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", - devp->index, devp->afbce_info->table_paddr, - devp->afbce_info->table_size); - - /* set fm_body_paddr */ - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_body_paddr[i] = - body_start_paddr + (devp->vfmem_size * i); - - pr_info("vdin%d body[%d]_start = 0x%lx, body_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_body_paddr[i], - devp->afbce_info->frame_body_size); - } - - /*check memory over the boundary*/ - afbce_mem_used = - devp->afbce_info->fm_body_paddr[max_buffer_num] - + devp->afbce_info->frame_body_size - - devp->afbce_info->head_paddr; - if (afbce_mem_used > devp->cma_mem_size) { - pr_info("afbce mem: afbce_mem_used(%d) > cma_mem_size(%d)\n", - afbce_mem_used, devp->cma_mem_size); - return 1; - } - devp->cma_mem_alloc = 1; - pr_info("vdin%d cma alloc ok!\n", devp->index); - } else { - devp->cma_mem_alloc = 0; - pr_err("\nvdin%d-afbce cma mem undefined2.\n", - devp->index); - return 1; - } - } - - /* 1 block = 32 * 4 pixle = 128 pixel */ - /* there is a header in one block, a header has 4 bytes */ - /* set fm_head_paddr start */ - frame_head_size = roundup(devp->h_active * devp->v_active, 128); - /*h_active * v_active / 128 * 4 = frame_head_size*/ - frame_head_size = devp->h_active * devp->v_active / 32; - frame_head_size = PAGE_ALIGN(frame_head_size); - - devp->afbce_info->frame_head_size = frame_head_size; - - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_head_paddr[i] = - devp->afbce_info->head_paddr + (frame_head_size*i); - - pr_info("vdin%d fm_head_paddr[%d] = 0x%lx, frame_head_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_head_paddr[i], - frame_head_size); - } - /* set fm_head_paddr end */ - - /* set fm_table_paddr start */ - mmu_used = devp->afbce_info->frame_body_size >> 12; - mmu_used = mmu_used * 4; - mmu_used = PAGE_ALIGN(mmu_used); - devp->afbce_info->frame_table_size = mmu_used; - - for (i = 0; i < max_buffer_num; i++) { - devp->afbce_info->fm_table_paddr[i] = - devp->afbce_info->table_paddr + (mmu_used*i); - - pr_info("vdin%d fm_table_paddr[%d]=0x%lx, frame_table_size = 0x%x\n", - devp->index, i, - devp->afbce_info->fm_table_paddr[i], - devp->afbce_info->frame_table_size); - } - /* set fm_table_paddr end */ - - return 0; } -void vdin_afbce_cma_release(struct vdin_dev_s *devp) +/* only support init vdin0 mif/afbce */ +void vdin_write_mif_or_afbce_init(struct vdin_dev_s *devp) { - char vdin_name[6]; - unsigned int i; - - if ((devp->cma_config_en == 0) || - (devp->cma_mem_alloc == 0)) { - pr_err("\nvdin%d %s fail for (%d,%d)!!!\n", - devp->index, __func__, devp->cma_config_en, - devp->cma_mem_alloc); + enum vdin_output_mif_e sel; + + if ((devp->afbce_flag & VDIN_AFBCE_EN) == 0) return; + + if (devp->afbce_mode == 0) + sel = VDIN_OUTPUT_TO_MIF; + else + sel = VDIN_OUTPUT_TO_AFBCE; + + if (devp->index == 0) { + if (sel == VDIN_OUTPUT_TO_MIF) { + vdin_afbce_hw_disable(); + + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_MIF_ENABLE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 0, VDIN0_OUT_AFBCE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_OUT_MIF_BIT, 1); + } else if (sel == VDIN_OUTPUT_TO_AFBCE) { + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_MIF_ENABLE_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 0, VDIN0_OUT_MIF_BIT, 1); + W_VCBUS_BIT(VDIN_MISC_CTRL, + 1, VDIN0_OUT_AFBCE_BIT, 1); + + vdin_afbce_hw_enable(); + } } - if (devp->index == 0) - strcpy(vdin_name, "vdin0"); - else if (devp->index == 1) - strcpy(vdin_name, "vdin1"); - - if (devp->cma_config_flag == 0x101) { - codec_mm_free_for_dma(vdin_name, devp->afbce_info->head_paddr); - codec_mm_free_for_dma(vdin_name, devp->afbce_info->table_paddr); - for (i = 0; i < devp->vfmem_max_cnt; i++) - codec_mm_free_for_dma(vdin_name, - devp->afbce_info->fm_body_paddr[i]); - pr_info("vdin%d-afbce codec cma release ok!\n", devp->index); - } else if (devp->venc_pages - && devp->cma_mem_size - && (devp->cma_config_flag == 0)) { - dma_release_from_contiguous( - &(devp->this_pdev->dev), - devp->venc_pages, - devp->cma_mem_size >> PAGE_SHIFT); - pr_info("vdin%d-afbce cma release ok!\n", devp->index); - } else { - pr_err("\nvdin%d %s fail for (%d,0x%x,0x%lx)!!!\n", - devp->index, __func__, devp->cma_mem_size, - devp->cma_config_flag, devp->mem_start); - } - devp->mem_start = 0; - devp->mem_size = 0; - devp->cma_mem_alloc = 0; } +/* only support config vdin0 mif/afbce dynamically */ void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, enum vdin_output_mif_e sel) { - unsigned int offset = devp->addr_offset; - if (offset == 0) { - if (sel == VDIN_OUTPUT_TO_MIF) { - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_AFBCE_BIT, 1); - } else if (sel == VDIN_OUTPUT_TO_AFBCE) { - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_ENABLE_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1); - } - } else { - if (sel == VDIN_OUTPUT_TO_MIF) { - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_AFBCE_BIT, 1); - } else if (sel == VDIN_OUTPUT_TO_AFBCE) { - /*sel vdin1 afbce: not support in sw now, - *just reserved interface - */ - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_ENABLE_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_OUT_MIF_BIT, 1); - W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_OUT_AFBCE_BIT, 1); - } + if ((devp->afbce_flag & VDIN_AFBCE_EN) == 0) + return; + + if (sel == VDIN_OUTPUT_TO_MIF) { + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, 8, 1); + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 0, VDIN0_OUT_AFBCE_BIT, 1); + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 1, VDIN0_OUT_MIF_BIT, 1); + } else if (sel == VDIN_OUTPUT_TO_AFBCE) { + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 0, VDIN0_OUT_MIF_BIT, 1); + rdma_write_reg_bits(devp->rdma_handle, VDIN_MISC_CTRL, + 1, VDIN0_OUT_AFBCE_BIT, 1); + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1); } } - +/* static void afbce_wr(uint32_t reg, const uint32_t val) { wr(0, reg, val); } +*/ +#define VDIN_AFBCE_HOLD_LINE_NUM 4 +void vdin_afbce_update(struct vdin_dev_s *devp) +{ + int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM; + int reg_format_mode;/* 0:444 1:422 2:420 */ + int reg_fmt444_comb; + int sblk_num; + int uncmp_bits; + int uncmp_size; + + if (!devp->afbce_info) + return; + +#ifndef CONFIG_AMLOGIC_MEDIA_RDMA + pr_info("##############################################\n"); + pr_info("vdin afbce must use RDMA,but it not be opened\n"); + pr_info("##############################################\n"); +#endif + + if ((devp->prop.dest_cfmt == TVIN_YUV444) && (devp->h_active > 2048)) + reg_fmt444_comb = 1; + else + reg_fmt444_comb = 0; + + if ((devp->prop.dest_cfmt == TVIN_NV12) || + (devp->prop.dest_cfmt == TVIN_NV21)) { + reg_format_mode = 2; + sblk_num = 12; + } else if ((devp->prop.dest_cfmt == TVIN_YUV422) || + (devp->prop.dest_cfmt == TVIN_YUYV422) || + (devp->prop.dest_cfmt == TVIN_YVYU422) || + (devp->prop.dest_cfmt == TVIN_UYVY422) || + (devp->prop.dest_cfmt == TVIN_VYUY422)) { + reg_format_mode = 1; + sblk_num = 16; + } else { + reg_format_mode = 0; + sblk_num = 24; + } + uncmp_bits = devp->source_bitdepth; + + /* bit size of uncompression mode */ + uncmp_size = (((((16*uncmp_bits*sblk_num)+7)>>3)+31)/32)<<1; + /* + *pr_info("%s: dest_cfmt=%d, reg_format_mode=%d, uncmp_bits=%d, + * sblk_num=%d, uncmp_size=%d\n", + * __func__, devp->prop.dest_cfmt, reg_format_mode, + * uncmp_bits, sblk_num, uncmp_size); + */ + + rdma_write_reg(devp->rdma_handle, AFBCE_MODE, + (0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 | + (hold_line_num & 0x7f) << 16 | + (2 & 0x3) << 14 | (reg_fmt444_comb & 0x1)); + + rdma_write_reg_bits(devp->rdma_handle, + AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);/* uncmp_size */ + + rdma_write_reg(devp->rdma_handle, AFBCE_FORMAT, + (reg_format_mode & 0x3) << 8 | + (uncmp_bits & 0xf) << 4 | + (uncmp_bits & 0xf)); +} void vdin_afbce_config(struct vdin_dev_s *devp) { - unsigned int offset = devp->addr_offset; - int hold_line_num = 4; + int hold_line_num = VDIN_AFBCE_HOLD_LINE_NUM; int lbuf_depth = 256; int lossy_luma_en = 0; int lossy_chrm_en = 0; @@ -412,9 +217,9 @@ void vdin_afbce_config(struct vdin_dev_s *devp) int sblk_num; int uncmp_bits; int uncmp_size; - int def_color_0 = 0; - int def_color_1 = 0; - int def_color_2 = 0; + int def_color_0 = 4095; + int def_color_1 = 2048; + int def_color_2 = 2048; int def_color_3 = 0; int hblksize_out = (devp->h_active + 31) >> 5; int vblksize_out = (devp->v_active + 3) >> 2; @@ -427,10 +232,14 @@ void vdin_afbce_config(struct vdin_dev_s *devp) int enc_win_bgn_v;//input scope int enc_win_end_v;//input scope - if (offset != 0) { - pr_info("cat not use afbce on vdin1 at the moment\n"); + if (!devp->afbce_info) return; - } + +#ifndef CONFIG_AMLOGIC_MEDIA_RDMA + pr_info("##############################################\n"); + pr_info("vdin afbce must use RDMA,but it not be opened\n"); + pr_info("##############################################\n"); +#endif enc_win_bgn_h = 0; enc_win_end_h = devp->h_active - 1; @@ -470,7 +279,7 @@ void vdin_afbce_config(struct vdin_dev_s *devp) W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 3, 1);//vpu arb axi_enable W_VCBUS_BIT(VDIN_WRARB_REQEN_SLV, 0x1, 7, 1);//vpu arb axi_enable - afbce_wr(AFBCE_MODE, + W_VCBUS(AFBCE_MODE, (0 & 0x7) << 29 | (0 & 0x3) << 26 | (3 & 0x3) << 24 | (hold_line_num & 0x7f) << 16 | (2 & 0x3) << 14 | (reg_fmt444_comb & 0x1)); @@ -478,92 +287,139 @@ void vdin_afbce_config(struct vdin_dev_s *devp) W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_luma_en & 0x1), 0, 1);//loosy W_VCBUS_BIT(AFBCE_QUANT_ENABLE, (lossy_chrm_en & 0x1), 4, 1);//loosy - afbce_wr(AFBCE_SIZE_IN, + if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) { + W_VCBUS(AFBCE_QUANT_ENABLE, 0xc11); + pr_info("afbce use lossy compression mode\n"); + } + + W_VCBUS(AFBCE_SIZE_IN, ((devp->h_active & 0x1fff) << 16) | // hsize_in of afbc input ((devp->v_active & 0x1fff) << 0) // vsize_in of afbc input ); - afbce_wr(AFBCE_BLK_SIZE_IN, + W_VCBUS(AFBCE_BLK_SIZE_IN, ((hblksize_out & 0x1fff) << 16) | // out blk hsize ((vblksize_out & 0x1fff) << 0) // out blk vsize ); //head addr of compressed data - afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[0]); + W_VCBUS(AFBCE_HEAD_BADDR, + devp->afbce_info->fm_head_paddr[0]); W_VCBUS_BIT(AFBCE_MIF_SIZE, (uncmp_size & 0x1fff), 16, 5);//uncmp_size /* how to set reg when we use crop ? */ // scope of hsize_in ,should be a integer multipe of 32 // scope of vsize_in ,should be a integer multipe of 4 - afbce_wr(AFBCE_PIXEL_IN_HOR_SCOPE, + W_VCBUS(AFBCE_PIXEL_IN_HOR_SCOPE, ((enc_win_end_h & 0x1fff) << 16) | ((enc_win_bgn_h & 0x1fff) << 0)); // scope of hsize_in ,should be a integer multipe of 32 // scope of vsize_in ,should be a integer multipe of 4 - afbce_wr(AFBCE_PIXEL_IN_VER_SCOPE, + W_VCBUS(AFBCE_PIXEL_IN_VER_SCOPE, ((enc_win_end_v & 0x1fff) << 16) | ((enc_win_bgn_v & 0x1fff) << 0)); - afbce_wr(AFBCE_CONV_CTRL, lbuf_depth);//fix 256 + W_VCBUS(AFBCE_CONV_CTRL, lbuf_depth);//fix 256 - afbce_wr(AFBCE_MIF_HOR_SCOPE, + W_VCBUS(AFBCE_MIF_HOR_SCOPE, ((blk_out_bgn_h & 0x3ff) << 16) | // scope of out blk hsize ((blk_out_end_h & 0xfff) << 0) // scope of out blk vsize ); - afbce_wr(AFBCE_MIF_VER_SCOPE, + W_VCBUS(AFBCE_MIF_VER_SCOPE, ((blk_out_bgn_v & 0x3ff) << 16) | // scope of out blk hsize ((blk_out_end_v & 0xfff) << 0) // scope of out blk vsize ); - afbce_wr(AFBCE_FORMAT, + W_VCBUS(AFBCE_FORMAT, (reg_format_mode & 0x3) << 8 | (uncmp_bits & 0xf) << 4 | (uncmp_bits & 0xf)); - afbce_wr(AFBCE_DEFCOLOR_1, + W_VCBUS(AFBCE_DEFCOLOR_1, ((def_color_3 & 0xfff) << 12) | // def_color_a ((def_color_0 & 0xfff) << 0) // def_color_y ); - afbce_wr(AFBCE_DEFCOLOR_2, + W_VCBUS(AFBCE_DEFCOLOR_2, ((def_color_2 & 0xfff) << 12) | // def_color_v ((def_color_1 & 0xfff) << 0) // def_color_u ); - //cur_mmu_used += Rd(AFBCE_MMU_NUM); //4k addr have used in every frame; - W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4, devp->afbce_info->table_paddr, 0, 32); W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12); - W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1);//enable afbce + W_VCBUS_BIT(AFBCE_ENABLE, 1, 12, 1); //set afbce pulse mode + W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce } void vdin_afbce_maptable_init(struct vdin_dev_s *devp) { unsigned int i, j; - unsigned int *ptable = NULL; + unsigned int highmem_flag = 0; + unsigned long ptable = 0; unsigned int *vtable = NULL; unsigned int body; unsigned int size; + void *p = NULL; + + if (!devp->afbce_info) + return; size = roundup(devp->afbce_info->frame_body_size, 4096); + ptable = devp->afbce_info->fm_table_paddr[0]; + if (devp->cma_config_flag == 0x101) + highmem_flag = PageHighMem(phys_to_page(ptable)); + else + highmem_flag = PageHighMem(phys_to_page(ptable)); + for (i = 0; i < devp->vfmem_max_cnt; i++) { - ptable = (unsigned int *) - (devp->afbce_info->fm_table_paddr[i]&0xffffffff); - if (devp->cma_config_flag == 0x101) - vtable = codec_mm_phys_to_virt((unsigned long)ptable); - else if (devp->cma_config_flag == 0) - vtable = phys_to_virt((unsigned long)ptable); + ptable = devp->afbce_info->fm_table_paddr[i]; + if (highmem_flag == 0) { + if (devp->cma_config_flag == 0x101) + vtable = codec_mm_phys_to_virt(ptable); + else if (devp->cma_config_flag == 0) + vtable = phys_to_virt(ptable); + else + vtable = phys_to_virt(ptable); + } else { + vtable = (unsigned int *)vdin_vmap(ptable, + devp->afbce_info->frame_table_size); + if (vdin_dbg_en) { + pr_err("----vdin vmap v: %p, p: %lx, size: %d\n", + vtable, ptable, + devp->afbce_info->frame_table_size); + } + if (!vtable) { + pr_err("vmap fail, size: %d.\n", + devp->afbce_info->frame_table_size); + return; + } + } + + p = vtable; body = devp->afbce_info->fm_body_paddr[i]&0xffffffff; for (j = 0; j < size; j += 4096) { *vtable = ((j + body) >> 12) & 0x000fffff; vtable++; } + + /* clean tail data. */ + memset(vtable, 0, devp->afbce_info->frame_table_size - + ((char *)vtable - (char *)p)); + + vdin_dma_flush(devp, p, + devp->afbce_info->frame_table_size, + DMA_TO_DEVICE); + + if (highmem_flag) + vdin_unmap_phyaddr(p); + + vtable = NULL; } } @@ -571,20 +427,75 @@ void vdin_afbce_set_next_frame(struct vdin_dev_s *devp, unsigned int rdma_enable, struct vf_entry *vfe) { unsigned char i; - unsigned int cur_mmu_used; + + if (!devp->afbce_info) + return; i = vfe->af_num; - cur_mmu_used = devp->afbce_info->fm_table_paddr[i] / 4; - -#ifdef CONFIG_AML_RDMA - if (rdma_enable) - rdma_write_reg_bits(devp->rdma_handle, - AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]); - rdma_write_reg(devp->rdma_handle, - AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12); - else + vfe->vf.compHeadAddr = devp->afbce_info->fm_head_paddr[i]; + vfe->vf.compBodyAddr = devp->afbce_info->fm_body_paddr[i]; + +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + if (rdma_enable) { + rdma_write_reg(devp->rdma_handle, AFBCE_HEAD_BADDR, + devp->afbce_info->fm_head_paddr[i]); + rdma_write_reg_bits(devp->rdma_handle, AFBCE_MMU_RMIF_CTRL4, + devp->afbce_info->fm_table_paddr[i], 0, 32); + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 0, 1); + } else #endif - afbce_wr(AFBCE_HEAD_BADDR, devp->afbce_info->fm_head_paddr[i]); - W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12); + { + pr_info("afbce must use RDMA.\n"); + } + + vdin_afbce_clear_writedown_flag(devp); +} + +void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp) +{ + rdma_write_reg(devp->rdma_handle, AFBCE_CLR_FLAG, 1); +} + +/* return 1: write down*/ +int vdin_afbce_read_writedown_flag(void) +{ + int val1, val2; + + val1 = rd_bits(0, AFBCE_STA_FLAGT, 0, 1); + val2 = rd_bits(0, AFBCE_STA_FLAGT, 2, 2); + + if ((val1 == 1) || (val2 == 0)) + return 1; + else + return 0; +} + +void vdin_afbce_hw_disable(void) +{ + /*can not use RDMA*/ + W_VCBUS_BIT(AFBCE_ENABLE, 0, 8, 1);//disable afbce +} + +void vdin_afbce_hw_enable(void) +{ + W_VCBUS_BIT(AFBCE_ENABLE, 1, 8, 1); } +void vdin_afbce_hw_disable_rdma(struct vdin_dev_s *devp) +{ + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0, 8, 1); +} + +void vdin_afbce_hw_enable_rdma(struct vdin_dev_s *devp) +{ + if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) + rdma_write_reg(devp->rdma_handle, AFBCE_QUANT_ENABLE, 0xc11); + rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1, 8, 1); +} + +void vdin_afbce_soft_reset(void) +{ + W_VCBUS_BIT(AFBCE_MODE, 0, 30, 1); + W_VCBUS_BIT(AFBCE_MODE, 1, 30, 1); + W_VCBUS_BIT(AFBCE_MODE, 0, 30, 1); +} diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h index feb2d08..0ac61b5 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h @@ -300,14 +300,20 @@ #define AFBCE_MMU_RMIF_RO_STAT 0x41c6 +extern void vdin_write_mif_or_afbce_init(struct vdin_dev_s *devp); extern void vdin_write_mif_or_afbce(struct vdin_dev_s *devp, enum vdin_output_mif_e sel); -extern unsigned int vdin_afbce_cma_alloc(struct vdin_dev_s *devp); -extern void vdin_afbce_cma_release(struct vdin_dev_s *devp); +extern void vdin_afbce_update(struct vdin_dev_s *devp); extern void vdin_afbce_config(struct vdin_dev_s *devp); extern void vdin_afbce_maptable_init(struct vdin_dev_s *devp); extern void vdin_afbce_set_next_frame(struct vdin_dev_s *devp, -unsigned int rdma_enable, struct vf_entry *vfe); - + unsigned int rdma_enable, struct vf_entry *vfe); +extern void vdin_afbce_clear_writedown_flag(struct vdin_dev_s *devp); +extern int vdin_afbce_read_writedown_flag(void); +extern void vdin_afbce_hw_disable(void); +extern void vdin_afbce_hw_enable(void); +extern void vdin_afbce_hw_disable_rdma(struct vdin_dev_s *devp); +extern void vdin_afbce_hw_enable_rdma(struct vdin_dev_s *devp); +extern void vdin_afbce_soft_reset(void); #endif diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c index edfa775..1cfa6b1 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c @@ -328,6 +328,27 @@ void vdin_canvas_auto_config(struct vdin_dev_s *devp) devp->canvas_max_num = min(devp->canvas_max_num, canvas_num); devp->canvas_max_num = min(devp->canvas_max_num, max_buffer_num); + if (devp->canvas_max_num < devp->vfmem_max_cnt) { + pr_err("\nvdin%d canvas_max_num %d less than vfmem_max_cnt %d\n", + devp->index, devp->canvas_max_num, devp->vfmem_max_cnt); + } + + if (devp->set_canvas_manual == 1) { + for (i = 0; i < 4; i++) { + canvas_id = + vdin_canvas_ids[devp->index][i * canvas_step]; + canvas_addr = vdin_set_canvas_addr[i].paddr; + canvas_config(canvas_id, canvas_addr, + devp->canvas_w, devp->canvas_h, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + pr_info("canvas index=%d- %3d: 0x%lx-0x%lx %ux%u\n", + i, canvas_id, canvas_addr, + canvas_addr + devp->canvas_max_size, + devp->canvas_w, devp->canvas_h); + } + return; + } + if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100)) { /*use_reserved_mem or alloc_from_contiguous*/ devp->mem_start = roundup(devp->mem_start, devp->canvas_align); @@ -393,6 +414,7 @@ void vdin_canvas_auto_config(struct vdin_dev_s *devp) /* need to be static for pointer use in codec_mm */ static char vdin_name[6]; /* return val:1: fail;0: ok */ +/* combined canvas and afbce memory */ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) { unsigned int mem_size, h_size, v_size; @@ -400,6 +422,14 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) CODEC_MM_FLAGS_DMA; unsigned int max_buffer_num = min_buf_num; unsigned int i; + /*head_size:3840*2160*3*9/32*/ + unsigned int afbce_head_size_byte = PAGE_SIZE * 1712; + /*afbce map_table need 218700 byte at most*/ + unsigned int afbce_table_size_byte = PAGE_SIZE * 60;/*0.3M*/ + unsigned long ref_paddr; + unsigned int mem_used; + unsigned int frame_head_size; + unsigned int mmu_used; if (devp->rdma_enable) max_buffer_num++; @@ -490,17 +520,38 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) devp->vfmem_size = PAGE_ALIGN(mem_size) + dolby_size_byte; devp->vfmem_size = (devp->vfmem_size/PAGE_SIZE + 1)*PAGE_SIZE; + if (devp->set_canvas_manual == 1) { + for (i = 0; i < VDIN_CANVAS_MAX_CNT; i++) { + if (vdin_set_canvas_addr[i].dmabuff == NULL) + break; + + vdin_set_canvas_addr[i].paddr = + roundup(vdin_set_canvas_addr[i].paddr, + devp->canvas_align); + } + + devp->canvas_max_num = max_buffer_num = i; + devp->vfmem_max_cnt = max_buffer_num; + } + + mem_size = PAGE_ALIGN(mem_size) * max_buffer_num + dolby_size_byte * max_buffer_num; mem_size = (mem_size/PAGE_SIZE + 1)*PAGE_SIZE; - if (mem_size > devp->cma_mem_size) + + if (mem_size > devp->cma_mem_size) { mem_size = devp->cma_mem_size; + pr_err("\nvdin%d cma_mem_size is not enough!!!\n", devp->index); + devp->cma_mem_alloc = 0; + return 1; + } if (devp->index == 0) strcpy(vdin_name, "vdin0"); else if (devp->index == 1) strcpy(vdin_name, "vdin1"); if (devp->cma_config_flag == 0x101) { + /* canvas or afbce paddr */ for (i = 0; i < max_buffer_num; i++) { devp->vfmem_start[i] = codec_mm_alloc_for_dma(vdin_name, devp->vfmem_size/PAGE_SIZE, 0, flags); @@ -509,70 +560,185 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp) devp->index, i); devp->cma_mem_alloc = 0; return 1; - } else { - devp->cma_mem_alloc = 1; - pr_info("vdin%d buf[%d] mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, i, - devp->vfmem_start[i], devp->vfmem_size); } + if (devp->afbce_info) { + devp->afbce_info->fm_body_paddr[i] = + devp->vfmem_start[i]; + } + pr_info("vdin%d buf[%d] mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, i, + devp->vfmem_start[i], devp->vfmem_size); } - pr_info("vdin%d codec cma alloc ok!\n", devp->index); + if (devp->afbce_info) + devp->afbce_info->frame_body_size = devp->vfmem_size; devp->mem_size = mem_size; + + if (devp->afbce_info) { + devp->afbce_info->head_paddr = codec_mm_alloc_for_dma( + vdin_name, afbce_head_size_byte/PAGE_SIZE, + 0, flags); + if (devp->afbce_info->head_paddr == 0) { + pr_err("\nvdin%d header codec alloc fail!!!\n", + devp->index); + devp->cma_mem_alloc = 0; + return 1; + } + devp->afbce_info->table_paddr = codec_mm_alloc_for_dma( + vdin_name, afbce_table_size_byte/PAGE_SIZE, + 0, flags); + if (devp->afbce_info->table_paddr == 0) { + pr_err("\nvdin%d table codec alloc fail!!!\n", + devp->index); + codec_mm_free_for_dma(vdin_name, + devp->afbce_info->head_paddr); + devp->cma_mem_alloc = 0; + return 1; + } + devp->afbce_info->head_size = afbce_head_size_byte; + devp->afbce_info->table_size = afbce_table_size_byte; + + pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", + devp->index, devp->afbce_info->head_paddr, + devp->afbce_info->head_size); + pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", + devp->index, devp->afbce_info->table_paddr, + devp->afbce_info->table_size); + } + + devp->cma_mem_alloc = 1; } else if (devp->cma_config_flag == 0x1) { devp->mem_start = codec_mm_alloc_for_dma(vdin_name, mem_size/PAGE_SIZE, 0, flags); - devp->mem_size = mem_size; if (devp->mem_start == 0) { pr_err("\nvdin%d codec alloc fail!!!\n", devp->index); devp->cma_mem_alloc = 0; return 1; - } else { - devp->cma_mem_alloc = 1; - pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, devp->mem_start, devp->mem_size); - pr_info("vdin%d codec cma alloc ok!\n", devp->index); } + devp->mem_size = mem_size; + devp->cma_mem_alloc = 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, devp->mem_start, devp->mem_size); } else if (devp->cma_config_flag == 0x100) { for (i = 0; i < max_buffer_num; i++) { devp->vfvenc_pages[i] = dma_alloc_from_contiguous( &(devp->this_pdev->dev), devp->vfmem_size >> PAGE_SHIFT, 0); - if (devp->vfvenc_pages[i]) { - devp->vfmem_start[i] = - page_to_phys(devp->vfvenc_pages[i]); - pr_info("vdin%d buf[%d]mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, i, - devp->vfmem_start[i], devp->vfmem_size); - } else { + if (!devp->vfvenc_pages[i]) { devp->cma_mem_alloc = 0; pr_err("\nvdin%d cma mem undefined2.\n", devp->index); return 1; } + devp->vfmem_start[i] = + page_to_phys(devp->vfvenc_pages[i]); + pr_info("vdin%d buf[%d]mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, i, + devp->vfmem_start[i], devp->vfmem_size); } + devp->mem_size = mem_size; devp->cma_mem_alloc = 1; - devp->mem_size = mem_size; - pr_info("vdin%d cma alloc ok!\n", devp->index); } else { + /* canvas or afbce paddr */ devp->venc_pages = dma_alloc_from_contiguous( &(devp->this_pdev->dev), devp->cma_mem_size >> PAGE_SHIFT, 0); - if (devp->venc_pages) { - devp->mem_start = - page_to_phys(devp->venc_pages); - devp->mem_size = mem_size; - devp->cma_mem_alloc = 1; - pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", - devp->index, devp->mem_start, devp->mem_size); - pr_info("vdin%d cma alloc ok!\n", devp->index); - } else { + if (!devp->venc_pages) { devp->cma_mem_alloc = 0; pr_err("\nvdin%d cma mem undefined2.\n", devp->index); return 1; } + devp->mem_start = page_to_phys(devp->venc_pages); + devp->mem_size = mem_size; + + /* set fm_body_paddr */ + if (devp->afbce_info) { + ref_paddr = devp->mem_start; + devp->afbce_info->frame_body_size = devp->vfmem_size; + for (i = 0; i < max_buffer_num; i++) { + ref_paddr = devp->mem_start + + (devp->vfmem_size * i); + devp->afbce_info->fm_body_paddr[i] = ref_paddr; + + pr_info("vdin%d body[%d]_start = 0x%lx, body_size = 0x%x\n", + devp->index, i, + devp->afbce_info->fm_body_paddr[i], + devp->afbce_info->frame_body_size); + } + + /* afbce header & table paddr */ + devp->afbce_info->head_paddr = ref_paddr + + devp->vfmem_size; + devp->afbce_info->head_size = 2 * SZ_1M;/*2M*/ + devp->afbce_info->table_paddr = + devp->afbce_info->head_paddr + + devp->afbce_info->head_size; + devp->afbce_info->table_size = 2 * SZ_1M;/*2M*/ + + pr_info("vdin%d head_start = 0x%lx, head_size = 0x%x\n", + devp->index, devp->afbce_info->head_paddr, + devp->afbce_info->head_size); + pr_info("vdin%d table_start = 0x%lx, table_size = 0x%x\n", + devp->index, devp->afbce_info->table_paddr, + devp->afbce_info->table_size); + + /*check memory over the boundary*/ + mem_used = devp->afbce_info->table_paddr + + devp->afbce_info->table_size - + devp->afbce_info->fm_body_paddr[0]; + if (mem_used > devp->cma_mem_size) { + pr_err("vdin%d error: mem_used(%d) > cma_mem_size(%d)\n", + devp->index, mem_used, + devp->cma_mem_size); + return 1; + } + } + + devp->cma_mem_alloc = 1; + pr_info("vdin%d mem_start = 0x%lx, mem_size = 0x%x\n", + devp->index, devp->mem_start, devp->mem_size); } + + /* set afbce head paddr */ + if (devp->afbce_info) { + /* 1 block = 32 * 4 pixle = 128 pixel */ + /* there is a header in one block, a header has 4 bytes */ + frame_head_size = (int)roundup(devp->vfmem_size, 128); + /*h_active * v_active / 128 * 4 = frame_head_size*/ + frame_head_size = PAGE_ALIGN(frame_head_size / 32); + + devp->afbce_info->frame_head_size = frame_head_size; + + for (i = 0; i < max_buffer_num; i++) { + devp->afbce_info->fm_head_paddr[i] = + devp->afbce_info->head_paddr + + (frame_head_size*i); + + pr_info("vdin%d fm_head_paddr[%d] = 0x%lx, frame_head_size = 0x%x\n", + devp->index, i, + devp->afbce_info->fm_head_paddr[i], + frame_head_size); + } + + /* set afbce table paddr */ + mmu_used = devp->afbce_info->frame_body_size >> 12; + mmu_used = mmu_used * 4; + mmu_used = PAGE_ALIGN(mmu_used); + devp->afbce_info->frame_table_size = mmu_used; + + for (i = 0; i < max_buffer_num; i++) { + devp->afbce_info->fm_table_paddr[i] = + devp->afbce_info->table_paddr + (mmu_used*i); + + pr_info("vdin%d fm_table_paddr[%d]=0x%lx, frame_table_size = 0x%x\n", + devp->index, i, + devp->afbce_info->fm_table_paddr[i], + devp->afbce_info->frame_table_size); + } + } + + pr_info("vdin%d cma alloc ok!\n", devp->index); return 0; } @@ -599,6 +765,17 @@ void vdin_cma_release(struct vdin_dev_s *devp) strcpy(vdin_name, "vdin1"); if (devp->cma_config_flag == 0x101) { + if (devp->afbce_info) { + if (devp->afbce_info->head_paddr) { + codec_mm_free_for_dma(vdin_name, + devp->afbce_info->head_paddr); + } + if (devp->afbce_info->table_paddr) { + codec_mm_free_for_dma(vdin_name, + devp->afbce_info->table_paddr); + } + } + /* canvas or afbce paddr */ for (i = 0; i < devp->vfmem_max_cnt; i++) codec_mm_free_for_dma(vdin_name, devp->vfmem_start[i]); pr_info("vdin%d codec cma release ok!\n", devp->index); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h index 66aabab..d97d767 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h @@ -31,8 +31,8 @@ #define VDIN_MIN_SOURCE_BITDEPTH 8 -#define VDIN_YUV444_MAX_CMA_WIDTH 1920 -#define VDIN_YUV444_MAX_CMA_HEIGH 1080 +#define VDIN_YUV444_MAX_CMA_WIDTH 4096 +#define VDIN_YUV444_MAX_CMA_HEIGH 2160 extern const unsigned int vdin_canvas_ids[2][VDIN_CANVAS_MAX_CNT]; extern void vdin_canvas_init(struct vdin_dev_s *devp); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c index dc61bc0..c37ba4b 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c @@ -22,6 +22,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -159,6 +163,79 @@ static unsigned int vpu_reg_27af = 0x3; #define pr_info(fmt, ...) #endif +u8 *vdin_vmap(ulong addr, u32 size) +{ + u8 *vaddr = NULL; + struct page **pages = NULL; + u32 i, npages, offset = 0; + ulong phys, page_start; + /*pgprot_t pgprot = pgprot_noncached(PAGE_KERNEL);*/ + pgprot_t pgprot = PAGE_KERNEL; + + if (!PageHighMem(phys_to_page(addr))) + return phys_to_virt(addr); + + offset = offset_in_page(addr); + page_start = addr - offset; + npages = DIV_ROUND_UP(size + offset, PAGE_SIZE); + + pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + if (!pages) + return NULL; + + for (i = 0; i < npages; i++) { + phys = page_start + i * PAGE_SIZE; + pages[i] = pfn_to_page(phys >> PAGE_SHIFT); + } + + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + page_start, npages << PAGE_SHIFT); + kfree(pages); + return NULL; + } + + kfree(pages); + + if (vdin_dbg_en) { + pr_info("[vdin HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n", + __func__, page_start, vaddr, npages << PAGE_SHIFT); + } + + return vaddr + offset; +} + +void vdin_unmap_phyaddr(u8 *vaddr) +{ + void *addr = (void *)(PAGE_MASK & (ulong)vaddr); + + if (is_vmalloc_or_module_addr(vaddr)) { + if (vdin_dbg_en) + pr_info("----vdin unmap v: %p\n", addr); + vunmap(addr); + } +} + +void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr, + int size, enum dma_data_direction dir) +{ + ulong phy_addr; + + if (is_vmalloc_or_module_addr(vaddr)) { + phy_addr = page_to_phys(vmalloc_to_page(vaddr)) + + offset_in_page(vaddr); + if (phy_addr && PageHighMem(phys_to_page(phy_addr))) { + if (vdin_dbg_en) + pr_info("----vdin flush v: %p, p: %lx\n", + vaddr, phy_addr); + dma_sync_single_for_device(&devp->this_pdev->dev, + phy_addr, size, dir); + } + return; + } +} + /*reset reg mif value of vdin0: * VDIN_WR_CTRL \VDIN_COM_CTRL0\ VDIN_MISC_CTRL */ @@ -464,6 +541,8 @@ void vdin_get_format_convert(struct vdin_dev_s *devp) format_convert = VDIN_FORMAT_CONVERT_YUV_NV21; else if (devp->prop.dest_cfmt == TVIN_NV12) format_convert = VDIN_FORMAT_CONVERT_YUV_NV12; + else if (devp->prop.dest_cfmt == TVIN_YUV444) + format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; else format_convert = VDIN_FORMAT_CONVERT_YUV_YUV422; break; @@ -586,7 +665,9 @@ static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_, meas_mux = MEAS_MUX_656_B; else if ((is_meson_gxl_cpu() || is_meson_gxm_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu()) && (bt_path == BT_PATH_GPIO)) + is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) && + (bt_path == BT_PATH_GPIO)) meas_mux = MEAS_MUX_656; else pr_info("cpu not define or do not support bt656"); @@ -669,7 +750,7 @@ static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_, b.BT_PATH_GPIO_B:gxtvbb & gxbb c.txl and txlx don't support bt656 */ -void vdin_set_top(unsigned int offset, +void vdin_set_top(struct vdin_dev_s *devp, unsigned int offset, enum tvin_port_e port, enum tvin_color_fmt_e input_cfmt, unsigned int h, enum bt_path_e bt_path) @@ -697,7 +778,9 @@ void vdin_set_top(unsigned int offset, VDI9_ASFIFO_CTRL_BIT, VDI9_ASFIFO_CTRL_WID); } else if ((is_meson_gxm_cpu() || is_meson_gxl_cpu() || is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu()) && (bt_path == BT_PATH_GPIO)) { + is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) && + (bt_path == BT_PATH_GPIO)) { vdin_mux = VDIN_MUX_656; wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4, VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID); @@ -745,18 +828,36 @@ void vdin_set_top(unsigned int offset, if (port != TVIN_PORT_VIU1) wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, VDI6_ASFIFO_CTRL_BIT, VDI6_ASFIFO_CTRL_WID); - else - wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, - VDI6_ASFIFO_CTRL_BIT, VDI6_ASFIFO_CTRL_WID); + else { + if (/*is_meson_gxlx2_cpu() || */is_meson_g12b_cpu() + || is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4, + VDI6_ASFIFO_CTRL_BIT, + VDI6_ASFIFO_CTRL_WID); + else + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, + VDI6_ASFIFO_CTRL_BIT, + VDI6_ASFIFO_CTRL_WID); + } break; case 0xc0: /* viu2 */ vdin_mux = VDIN_MUX_VIU_2; if (port != TVIN_PORT_VIU2) wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, VDI8_ASFIFO_CTRL_BIT, VDI8_ASFIFO_CTRL_WID); - else - wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, - VDI8_ASFIFO_CTRL_BIT, VDI8_ASFIFO_CTRL_WID); + else { + if (/*is_meson_gxlx2_cpu() || */is_meson_g12b_cpu() + || is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4, + VDI6_ASFIFO_CTRL_BIT, + VDI6_ASFIFO_CTRL_WID); + else + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, + VDI6_ASFIFO_CTRL_BIT, + VDI6_ASFIFO_CTRL_WID); + } break; case 0x100:/* mipi in mybe need modify base on truth */ vdin_mux = VDIN_MUX_MIPI; @@ -772,6 +873,7 @@ void vdin_set_top(unsigned int offset, vdin_mux = VDIN_MUX_NULL; break; } + switch (input_cfmt) { case TVIN_YVYU422: vdin_data_bus_1 = VDIN_MAP_RCR; @@ -787,6 +889,14 @@ void vdin_set_top(unsigned int offset, vdin_data_bus_1 = VDIN_MAP_RCR; vdin_data_bus_2 = VDIN_MAP_Y_G; break; + case TVIN_RGB444: + /*RGB mapping*/ + if (devp->set_canvas_manual == 1) { + vdin_data_bus_0 = VDIN_MAP_RCR; + vdin_data_bus_1 = VDIN_MAP_BPB; + vdin_data_bus_2 = VDIN_MAP_Y_G; + } + break; default: break; } @@ -1453,9 +1563,10 @@ static void vdin_set_color_matrix0_g12a(unsigned int offset, VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID); wr(offset, - VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1); + VDIN_HDR2_MATRIXI_PRE_OFFSET0_1, + matrix_tbl->pre_offset0_1); wr(offset, - VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2); + VDIN_HDR2_MATRIXI_PRE_OFFSET2, matrix_tbl->pre_offset2); wr(offset, VDIN_HDR2_MATRIXI_COEF00_01, matrix_tbl->coef00_01); wr(offset, VDIN_HDR2_MATRIXI_COEF02_10, matrix_tbl->coef02_10); wr(offset, VDIN_HDR2_MATRIXI_COEF11_12, matrix_tbl->coef11_12); @@ -1491,7 +1602,8 @@ void vdin_set_matrix(struct vdin_dev_s *devp) */ wr_bits(offset, VDIN_MATRIX_CTRL, 0, VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID); - if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_sm1_cpu() || is_meson_tm2_cpu()) vdin_set_color_matrix0_g12a(devp->addr_offset, devp->fmt_info_p, devp->format_convert, @@ -1525,7 +1637,8 @@ void vdin_set_matrix(struct vdin_dev_s *devp) devp->prop.color_fmt_range, devp->prop.vdin_hdr_Flag, devp->color_range_mode); - if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_sm1_cpu() || is_meson_tm2_cpu()) vdin_set_color_matrix0_g12a(devp->addr_offset, devp->fmt_info_p, devp->format_convert, @@ -1563,7 +1676,8 @@ void vdin_set_matrixs(struct vdin_dev_s *devp, unsigned char id, { switch (id) { case 0: - if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_sm1_cpu() || is_meson_tm2_cpu()) vdin_set_color_matrix0_g12a(devp->addr_offset, devp->fmt_info_p, devp->format_convert, @@ -1613,7 +1727,8 @@ void vdin_set_prob_xy(unsigned int offset, devp->prop.color_fmt_range, devp->prop.vdin_hdr_Flag, devp->color_range_mode); - if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_sm1_cpu() || is_meson_tm2_cpu()) vdin_set_color_matrix0_g12a(devp->addr_offset, devp->fmt_info_p, devp->format_convert, @@ -1746,7 +1861,13 @@ static inline void vdin_set_hist_mux(struct vdin_dev_s *devp) /* use 11: form matrix1 din */ wr_bits(devp->addr_offset, VDIN_HIST_CTRL, 3, HIST_HIST_DIN_SEL_BIT, HIST_HIST_DIN_SEL_WID); + + /*for project get vdin1 hist*/ + //if (devp->index == 1) + // wr_bits(devp->addr_offset, VDIN_WR_CTRL2, 1, 8, 1); } + + /* urgent ctr config */ /*if vdin fifo over up_th,will trigger increase * urgent responds to vdin write, @@ -1888,7 +2009,14 @@ static inline void vdin_set_wr_ctrl(struct vdin_dev_s *devp, VDIN_WRCTRLREG_PAUSE_BIT, 1); /* swap the 2 64bits word in 128 words */ /*if (is_meson_gxbb_cpu())*/ - wr_bits(offset, VDIN_WR_CTRL, 1, 19, 1); + if (devp->set_canvas_manual == 1) { + /*not swap 2 64bits words in 128 words */ + wr_bits(offset, VDIN_WR_CTRL, 0, 19, 1); + /*little endian*/ + wr_bits(offset, VDIN_WR_H_START_END, 1, 30, 1); + } else + wr_bits(offset, VDIN_WR_CTRL, 1, 19, 1); + } void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp, unsigned int offset, enum vdin_format_convert_e format_convert, @@ -1938,7 +2066,7 @@ void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp, hconv_mode = 2; swap_cbcr = 0; } -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA if (rdma_enable) { rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL+devp->addr_offset, @@ -2032,9 +2160,10 @@ unsigned int vdin_get_total_v(unsigned int offset) void vdin_set_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, unsigned int canvas_id) { -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA if (rdma_enable) { - if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) { + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_sm1_cpu()) { rdma_write_reg_bits(devp->rdma_handle, VDIN_COM_CTRL0+devp->addr_offset, 1, VDIN_FORCEGOLINE_EN_BIT, 1); @@ -2058,7 +2187,7 @@ unsigned int vdin_get_canvas_id(unsigned int offset) void vdin_set_chma_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, unsigned int canvas_id) { -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA if (rdma_enable) rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL2+devp->addr_offset, @@ -2468,7 +2597,7 @@ void vdin_set_all_regs(struct vdin_dev_s *devp) devp->color_depth_mode, devp->source_bitdepth); /* top sub-module */ - vdin_set_top(devp->addr_offset, devp->parm.port, + vdin_set_top(devp, devp->addr_offset, devp->parm.port, devp->prop.color_format, devp->h_active, devp->bt_path); @@ -2476,7 +2605,6 @@ void vdin_set_all_regs(struct vdin_dev_s *devp) vdin_set_meas_mux(devp->addr_offset, devp->parm.port, devp->bt_path); - } static void vdin_delay_line(unsigned short num, unsigned int offset) @@ -2620,6 +2748,8 @@ void vdin_set_default_regmap(unsigned int offset) is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || is_meson_txlx_cpu() || is_meson_tl1_cpu()) wr(offset, VDIN_LFIFO_CTRL, 0x00000f00); + else if (is_meson_tm2_cpu()) + wr(offset, VDIN_LFIFO_CTRL, 0xc0020f00); else wr(offset, VDIN_LFIFO_CTRL, 0x00000780); /* [15:14] clkgate.bbar = 0/(auto, off, on, on) */ @@ -2858,6 +2988,18 @@ unsigned int vdin_get_field_type(unsigned int offset) { return rd_bits(offset, VDIN_COM_STATUS0, 0, 1); } + +bool vdin_check_vdi6_afifo_overflow(unsigned int offset) +{ + return rd_bits(offset, VDIN_COM_STATUS2, 15, 1); +} + +void vdin_clear_vdi6_afifo_overflow_flg(unsigned int offset) +{ + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0x1, 1, 1); + wr_bits(offset, VDIN_ASFIFO_CTRL3, 0x0, 1, 1); +} + static unsigned int vdin_reset_flag; inline int vdin_vsync_reset_mif(int index) { @@ -3485,6 +3627,7 @@ void vdin_force_gofiled(struct vdin_dev_s *devp) void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size) { unsigned int index, alloc_size; + int highmem_flag; alloc_size = dolby_size_byte*size; devp->dv.dv_dma_vaddr = dma_alloc_coherent(&devp->this_pdev->dev, @@ -3494,41 +3637,87 @@ void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size) return; } memset(devp->dv.dv_dma_vaddr, 0, alloc_size); + if (devp->cma_config_flag & 0x100) + highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); + else + highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + for (index = 0; index < size; index++) { devp->vfp->dv_buf_mem[index] = devp->dv.dv_dma_paddr + dolby_size_byte * index; devp->vfp->dv_buf_vmem[index] = devp->dv.dv_dma_vaddr + dolby_size_byte * index; - if ((devp->cma_config_flag & 0x100) && devp->cma_config_en) - devp->vfp->dv_buf_ori[index] = - phys_to_virt(devp->vfmem_start[index] + - devp->vfmem_size - - dolby_size_byte); - else - devp->vfp->dv_buf_ori[index] = - phys_to_virt(devp->mem_start + devp->mem_size - - dolby_size_byte * - (devp->canvas_max_num - index)); + + if (highmem_flag == 0) { + if ((devp->cma_config_flag & 0x100) + && devp->cma_config_en) + devp->vfp->dv_buf_ori[index] = + phys_to_virt(devp->vfmem_start[index] + + devp->vfmem_size - + dolby_size_byte); + else + devp->vfp->dv_buf_ori[index] = + phys_to_virt(devp->mem_start + + devp->mem_size - + dolby_size_byte * + (devp->canvas_max_num - index)); + } else { + if ((devp->cma_config_flag & 0x100) + && devp->cma_config_en) + devp->vfp->dv_buf_ori[index] = + vdin_vmap(devp->vfmem_start[index] + + devp->vfmem_size-dolby_size_byte, + dolby_size_byte); + else + devp->vfp->dv_buf_ori[index] = + vdin_vmap(devp->mem_start + + devp->mem_size - + dolby_size_byte * + (devp->canvas_max_num - index), + dolby_size_byte); + } pr_info("%s:dv_buf[%d]=0x%p(0x%x,0x%p)\n", __func__, index, devp->vfp->dv_buf_ori[index], devp->vfp->dv_buf_mem[index], devp->vfp->dv_buf_vmem[index]); } + devp->dv.dv_mem_alloced = 1; pr_info("%s:dv_dma_vaddr=0x%p,dv_dma_paddr=0x%lx\n", __func__, devp->dv.dv_dma_vaddr, (ulong)devp->dv.dv_dma_paddr); } void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size) { unsigned int alloc_size; + int highmem_flag; + int index; + + if (devp->dv.dv_mem_alloced == 0) + return; alloc_size = dolby_size_byte*size; if (devp->dv.dv_dma_vaddr) dma_free_coherent(&devp->this_pdev->dev, alloc_size, devp->dv.dv_dma_vaddr, devp->dv.dv_dma_paddr); devp->dv.dv_dma_vaddr = NULL; + + if (devp->cma_config_flag & 0x100) + highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); + else + highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + + if (highmem_flag) { + for (index = 0; index < size; index++) { + if (devp->vfp->dv_buf_ori[index]) { + vdin_unmap_phyaddr( + devp->vfp->dv_buf_ori[index]); + devp->vfp->dv_buf_ori[index] = NULL; + } + } + } + devp->dv.dv_mem_alloced = 0; } -static void vdin_dolby_metadata_swap(char *buf) +static void vdin_dolby_metadata_swap(struct vdin_dev_s *devp, char *buf) { char ext; unsigned int i, j; @@ -3540,6 +3729,8 @@ static void vdin_dolby_metadata_swap(char *buf) buf[i*16+15-j] = ext; } } + + vdin_dma_flush(devp, buf, dolby_size_byte, DMA_TO_DEVICE); } #define swap32(num) \ @@ -3637,7 +3828,8 @@ void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index) for (count = 0; count < META_RETRY_MAX; count++) { if (dv_dbg_mask & DV_READ_MODE_AXI) { memcpy(p, devp->vfp->dv_buf_vmem[index], 128); - vdin_dolby_metadata_swap(c); + vdin_dma_flush(devp, p, 128, DMA_TO_DEVICE); + vdin_dolby_metadata_swap(devp, c); } else { wr(offset, VDIN_DOLBY_DSC_CTRL3, 0); wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xd180c0d5); @@ -3650,7 +3842,9 @@ void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index) if ((i == 31) && (multimeta_flag == 0)) break; } + vdin_dma_flush(devp, p, 128, DMA_TO_DEVICE); } + meta_size = (c[3] << 8) | c[4]; crc = p[31]; crc_result = crc32(0, p, 124); @@ -3778,6 +3972,7 @@ void vdin_dolby_config(struct vdin_dev_s *devp) } } +unsigned int vdin0_afbce_debug_force; int vdin_event_cb(int type, void *data, void *op_arg) { unsigned long flags; @@ -3849,6 +4044,26 @@ int vdin_event_cb(int type, void *data, void *op_arg) pr_info("%s(type 0x%x vf index 0x%x)=>disp_mode %d,req_mode:%d\n", __func__, type, index_disp, req->disp_mode, req->req_mode); + } else if (type & VFRAME_EVENT_RECEIVER_NEED_NO_COMP) { + struct vdin_dev_s *devp = vdin_get_dev(0); + unsigned int *cnt; + + /* use for debug */ + if (vdin0_afbce_debug_force) + return 0; + + cnt = (unsigned int *)data; + if (*cnt) { + devp->afbce_mode = 0; + } else { + if (devp->afbce_valid) + devp->afbce_mode = 1; + } + + if (vdin_ctl_dbg&(1<<1)) + pr_info("%s(type 0x%x vdin%d) afbce_mode: %d, vpp_cnt: %d\n", + __func__, type, devp->index, + devp->afbce_mode, *cnt); } return 0; } @@ -4026,9 +4241,11 @@ u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) } format_convert = devp->format_convert; if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444) || - (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) + (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444)) { type |= VIDTYPE_VIU_444; - else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || + if (devp->afbce_mode_pre) + type |= VIDTYPE_COMB_MODE; + } else if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422) || (format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422)) type |= VIDTYPE_VIU_422; else if (devp->prop.dest_cfmt == TVIN_NV21) { @@ -4039,6 +4256,17 @@ u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) type &= (~VIDTYPE_VIU_SINGLE_PLANE); } + + if (devp->afbce_valid) + type |= VIDTYPE_SUPPORT_COMPRESS; + if (devp->afbce_mode_pre) { + type |= VIDTYPE_COMPRESS; + type |= VIDTYPE_NO_DW; + type |= VIDTYPE_SCATTER; + if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) + type |= VIDTYPE_COMPRESS_LOSS; + } + return type; } diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h index 178c74a..93ff0b3 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h @@ -17,7 +17,11 @@ #ifndef __TVIN_VDIN_CTL_H #define __TVIN_VDIN_CTL_H - +#include +#include +#include +#include +#include #include "vdin_drv.h" #define DV_SWAP_EN (1 << 0) @@ -111,10 +115,16 @@ struct ldim_max_s { #endif extern unsigned int game_mode; +extern bool vdin_dbg_en; /* ************************************************************************ */ /* ******** GLOBAL FUNCTION CLAIM ******** */ /* ************************************************************************ */ +extern u8 *vdin_vmap(ulong addr, u32 size); +extern void vdin_unmap_phyaddr(u8 *vaddr); +extern void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr, + int size, enum dma_data_direction dir); + extern void vdin_set_vframe_prop_info(struct vframe_s *vf, struct vdin_dev_s *devp); extern void LDIM_Initial_2(int pic_h, int pic_v, int BLK_Vnum, @@ -135,6 +145,8 @@ extern void vdin_hw_enable(unsigned int offset); extern void vdin_hw_disable(unsigned int offset); extern unsigned int vdin_get_field_type(unsigned int offset); extern int vdin_vsync_reset_mif(int index); +extern bool vdin_check_vdi6_afifo_overflow(unsigned int offset); +extern void vdin_clear_vdi6_afifo_overflow_flg(unsigned int offset); extern void vdin_set_cutwin(struct vdin_dev_s *devp); extern void vdin_set_decimation(struct vdin_dev_s *devp); extern void vdin_fix_nonstd_vsync(struct vdin_dev_s *devp); @@ -177,7 +189,7 @@ extern void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size); extern void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size); extern int vdin_event_cb(int type, void *data, void *op_arg); extern void vdin_hdmiin_patch(struct vdin_dev_s *devp); -extern void vdin_set_top(unsigned int offset, +extern void vdin_set_top(struct vdin_dev_s *devp, unsigned int offset, enum tvin_port_e port, enum tvin_color_fmt_e input_cfmt, unsigned int h, enum bt_path_e bt_path); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c index cf16fb1..475106b 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include /* Local Headers */ @@ -31,6 +32,7 @@ #include "vdin_drv.h" #include "vdin_ctl.h" #include "vdin_regs.h" +#include "vdin_afbce.h" /*2018-07-18 add debugfs*/ #include #include @@ -273,7 +275,11 @@ static void vdin_dump_one_buf_mem(char *path, struct vdin_dev_s *devp, struct file *filp = NULL; loff_t pos = 0; void *buf = NULL; - unsigned int i; + unsigned int i, j; + unsigned int span = 0, count = 0; + int highmem_flag; + unsigned long highaddr; + unsigned long phys; mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); @@ -288,7 +294,22 @@ static void vdin_dump_one_buf_mem(char *path, struct vdin_dev_s *devp, pr_info("%s:no cma alloc mem!!!\n", __func__); return; } - if (buf_num < devp->canvas_max_num) { + + if (buf_num >= devp->canvas_max_num) { + vfs_fsync(filp, 0); + filp_close(filp, NULL); + set_fs(old_fs); + pr_info("buf_num > canvas_max_num, vdin exit dump\n"); + return; + } + + if (devp->cma_config_flag & 0x100) + highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); + else + highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + + if (highmem_flag == 0) { + pr_info("low mem area\n"); if (devp->cma_config_flag == 0x1) buf = codec_mm_phys_to_virt(devp->mem_start + devp->canvas_max_size*buf_num); @@ -307,6 +328,34 @@ static void vdin_dump_one_buf_mem(char *path, struct vdin_dev_s *devp, /*vfs_write(filp, buf, devp->canvas_max_size, &pos);*/ pr_info("write buffer %2d of %2u to %s.\n", buf_num, devp->canvas_max_num, path); + } else { + pr_info("high mem area\n"); + count = devp->canvas_h; + span = devp->canvas_active_w; + + if (devp->cma_config_flag == 0x1) + phys = devp->mem_start + devp->canvas_max_size*buf_num; + else if (devp->cma_config_flag == 0x101) + phys = devp->vfmem_start[buf_num]; + else if (devp->cma_config_flag == 0x100) + phys = devp->vfmem_start[buf_num]; + else + phys = devp->mem_start + devp->canvas_max_size*buf_num; + + for (j = 0; j < count; j++) { + highaddr = phys + j * devp->canvas_w; + buf = vdin_vmap(highaddr, span); + if (!buf) { + pr_info("vdin_vmap error\n"); + return; + } + + vdin_dma_flush(devp, buf, span, DMA_FROM_DEVICE); + vfs_write(filp, buf, span, &pos); + vdin_unmap_phyaddr(buf); + } + pr_info("high-mem write buffer %2d of %2u to %s.\n", + buf_num, devp->canvas_max_num, path); } vfs_fsync(filp, 0); filp_close(filp, NULL); @@ -317,15 +366,20 @@ static void vdin_dump_mem(char *path, struct vdin_dev_s *devp) { struct file *filp = NULL; loff_t pos = 0; - loff_t i = 0, j = 0; - unsigned int mem_size = 0; + loff_t mem_size = 0; + unsigned int i = 0, j = 0; + unsigned int span = 0; + unsigned int count = 0; + unsigned long highaddr; + unsigned long phys; + int highmem_flag; void *buf = NULL; void *vfbuf[VDIN_CANVAS_MAX_CNT]; mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); filp = filp_open(path, O_RDWR|O_CREAT, 0666); - mem_size = devp->canvas_active_w * devp->canvas_h; + mem_size = (loff_t)devp->canvas_active_w * devp->canvas_h; for (i = 0; i < VDIN_CANVAS_MAX_CNT; i++) vfbuf[i] = NULL; if (IS_ERR(filp)) { @@ -337,33 +391,79 @@ static void vdin_dump_mem(char *path, struct vdin_dev_s *devp) pr_info("%s:no cma alloc mem!!!\n", __func__); return; } - for (i = 0; i < devp->canvas_max_num; i++) { - pos = mem_size * i; - if (devp->cma_config_flag == 0x1) - buf = codec_mm_phys_to_virt(devp->mem_start + - devp->canvas_max_size*i); - else if (devp->cma_config_flag == 0x101) - vfbuf[i] = codec_mm_phys_to_virt( - devp->vfmem_start[i]); - else if (devp->cma_config_flag == 0x100) - vfbuf[i] = phys_to_virt(devp->vfmem_start[i]); - else - buf = phys_to_virt(devp->mem_start + - devp->canvas_max_size*i); - /*only write active data*/ - for (j = 0; j < devp->canvas_h; j++) { - if (devp->cma_config_flag & 0x100) { - vfs_write(filp, vfbuf[i], - devp->canvas_active_w, &pos); - vfbuf[i] += devp->canvas_w; - } else { - vfs_write(filp, buf, - devp->canvas_active_w, &pos); - buf += devp->canvas_w; + + if (devp->cma_config_flag & 0x100) + highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); + else + highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + + if (highmem_flag == 0) { + /*low mem area*/ + pr_info("low mem area\n"); + for (i = 0; i < devp->canvas_max_num; i++) { + pos = mem_size * i; + if (devp->cma_config_flag == 0x1) + buf = codec_mm_phys_to_virt(devp->mem_start + + devp->canvas_max_size*i); + else if (devp->cma_config_flag == 0x101) + vfbuf[i] = codec_mm_phys_to_virt( + devp->vfmem_start[i]); + else if (devp->cma_config_flag == 0x100) + vfbuf[i] = phys_to_virt(devp->vfmem_start[i]); + else + buf = phys_to_virt(devp->mem_start + + devp->canvas_max_size*i); + /*only write active data*/ + for (j = 0; j < devp->canvas_h; j++) { + if (devp->cma_config_flag & 0x100) { + vfs_write(filp, vfbuf[i], + devp->canvas_active_w, &pos); + vfbuf[i] += devp->canvas_w; + } else { + vfs_write(filp, buf, + devp->canvas_active_w, &pos); + buf += devp->canvas_w; + } } + pr_info("write buffer %2d of %2u to %s.\n", + i, devp->canvas_max_num, path); + } + } else { + /*high mem area*/ + pr_info("high mem area\n"); + count = devp->canvas_h; + span = devp->canvas_active_w; + + for (i = 0; i < devp->canvas_max_num; i++) { + pos = mem_size * i; + if (devp->cma_config_flag == 0x1) { + phys = devp->mem_start + + devp->canvas_max_size*i; + } else if (devp->cma_config_flag == 0x101) + phys = devp->vfmem_start[i]; + else if (devp->cma_config_flag == 0x100) + phys = devp->vfmem_start[i]; + else { + phys = devp->mem_start + + devp->canvas_max_size*i; + } + + for (j = 0; j < count; j++) { + highaddr = phys + j * devp->canvas_w; + buf = vdin_vmap(highaddr, span); + if (!buf) { + pr_info("vdin_vmap error\n"); + return; + } + + vdin_dma_flush(devp, buf, span, + DMA_FROM_DEVICE); + vfs_write(filp, buf, span, &pos); + vdin_unmap_phyaddr(buf); + } + pr_info("high-mem write buffer %2d of %2u to %s.\n", + i, devp->canvas_max_num, path); } - pr_info("write buffer %lld of %2u to %s.\n", - i, devp->canvas_max_num, path); } vfs_fsync(filp, 0); filp_close(filp, NULL); @@ -378,6 +478,14 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, void *buf_head = NULL; void *buf_table = NULL; void *buf_body = NULL; + unsigned long highaddr; + unsigned long phys; + int highmem_flag = 0; + unsigned int span = 0; + unsigned int remain = 0; + unsigned int count = 0; + unsigned int j = 0; + void *vbuf = NULL; unsigned char buff[100]; mm_segment_t old_fs = get_fs(); @@ -392,27 +500,49 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, return; } - if (devp->cma_config_flag == 0x101) { - buf_head = codec_mm_phys_to_virt( - devp->afbce_info->fm_head_paddr[buf_num]); - buf_table = codec_mm_phys_to_virt( - devp->afbce_info->fm_table_paddr[buf_num]); - buf_body = codec_mm_phys_to_virt( - devp->afbce_info->fm_body_paddr[buf_num]); - - pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", + highmem_flag = PageHighMem( + phys_to_page(devp->afbce_info->fm_body_paddr[0])); + + if (highmem_flag == 0) { + /*low mem area*/ + pr_info("low mem area\n"); + if (devp->cma_config_flag == 0x101) { + buf_head = codec_mm_phys_to_virt( + devp->afbce_info->fm_head_paddr[buf_num]); + buf_table = codec_mm_phys_to_virt( + devp->afbce_info->fm_table_paddr[buf_num]); + buf_body = codec_mm_phys_to_virt( + devp->afbce_info->fm_body_paddr[buf_num]); + + pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", + devp->afbce_info->fm_head_paddr[buf_num], + (devp->afbce_info->fm_table_paddr[buf_num]), + devp->afbce_info->fm_body_paddr[buf_num]); + } else if (devp->cma_config_flag == 0) { + buf_head = phys_to_virt( + devp->afbce_info->fm_head_paddr[buf_num]); + buf_table = phys_to_virt( + devp->afbce_info->fm_table_paddr[buf_num]); + buf_body = phys_to_virt( + devp->afbce_info->fm_body_paddr[buf_num]); + + pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", + devp->afbce_info->fm_head_paddr[buf_num], + (devp->afbce_info->fm_table_paddr[buf_num]), + devp->afbce_info->fm_body_paddr[buf_num]); + } + } else { + /*high mem area*/ + pr_info("high mem area\n"); + buf_head = vdin_vmap( devp->afbce_info->fm_head_paddr[buf_num], - (devp->afbce_info->fm_table_paddr[buf_num]), - devp->afbce_info->fm_body_paddr[buf_num]); - } else if (devp->cma_config_flag == 0) { - buf_head = phys_to_virt( - devp->afbce_info->fm_head_paddr[buf_num]); - buf_table = phys_to_virt( - devp->afbce_info->fm_table_paddr[buf_num]); - buf_body = phys_to_virt( - devp->afbce_info->fm_body_paddr[buf_num]); + devp->afbce_info->frame_head_size); + + buf_table = vdin_vmap( + devp->afbce_info->fm_table_paddr[buf_num], + devp->afbce_info->frame_table_size); - pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", + pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", devp->afbce_info->fm_head_paddr[buf_num], (devp->afbce_info->fm_table_paddr[buf_num]), devp->afbce_info->fm_body_paddr[buf_num]); @@ -429,7 +559,12 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, return; } + vdin_dma_flush(devp, buf_head, + devp->afbce_info->frame_head_size, + DMA_FROM_DEVICE); vfs_write(filp, buf_head, devp->afbce_info->frame_head_size, &pos); + if (highmem_flag) + vdin_unmap_phyaddr(buf_head); pr_info("write buffer %2d of %2u head to %s.\n", buf_num, devp->canvas_max_num, buff); vfs_fsync(filp, 0); @@ -444,7 +579,12 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, pr_info("create %s table error.\n", buff); return; } + vdin_dma_flush(devp, buf_table, + devp->afbce_info->frame_table_size, + DMA_FROM_DEVICE); vfs_write(filp, buf_table, devp->afbce_info->frame_table_size, &pos); + if (highmem_flag) + vdin_unmap_phyaddr(buf_table); pr_info("write buffer %2d of %2u table to %s.\n", buf_num, devp->canvas_max_num, buff); vfs_fsync(filp, 0); @@ -459,124 +599,46 @@ static void vdin_dump_one_afbce_mem(char *path, struct vdin_dev_s *devp, pr_info("create %s body error.\n", buff); return; } - vfs_write(filp, buf_body, devp->afbce_info->frame_body_size, &pos); - pr_info("write buffer %2d of %2u body to %s.\n", - buf_num, devp->canvas_max_num, buff); - vfs_fsync(filp, 0); - filp_close(filp, NULL); - - set_fs(old_fs); -} - -static void vdin_dump_afbce_mem(char *path, struct vdin_dev_s *devp) -{ - struct file *filp = NULL; - loff_t pos = 0; - void *buf_head = NULL; - void *buf_table = NULL; - void *buf_body = NULL; - unsigned char buff[100]; - unsigned int i; - mm_segment_t old_fs = get_fs(); - - if ((devp->cma_config_flag & 0x1) && - (devp->cma_mem_alloc == 0)) { - pr_info("%s:no cma alloc mem!!!\n", __func__); - return; - } - - if (devp->cma_config_flag == 0x101) { - buf_head = codec_mm_phys_to_virt( - devp->afbce_info->head_paddr); - buf_table = codec_mm_phys_to_virt( - devp->afbce_info->table_paddr); - buf_body = codec_mm_phys_to_virt( - devp->afbce_info->fm_body_paddr[0]); - - pr_info(".head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", - devp->afbce_info->head_paddr, - (devp->afbce_info->table_paddr), - devp->afbce_info->fm_body_paddr[0]); - } else if (devp->cma_config_flag == 0) { - buf_head = phys_to_virt( - devp->afbce_info->head_paddr); - buf_table = phys_to_virt( - devp->afbce_info->table_paddr); - buf_body = phys_to_virt( - devp->afbce_info->fm_body_paddr[0]); - - pr_info("head_paddr=0x%lx,table_paddr=0x%lx,body_paddr=0x%lx\n", - devp->afbce_info->head_paddr, - (devp->afbce_info->table_paddr), - devp->afbce_info->fm_body_paddr[0]); - } - - set_fs(KERNEL_DS); - - /* write header bin start */ - strcpy(buff, path); - strcat(buff, "_header.bin"); - filp = filp_open(buff, O_RDWR|O_CREAT, 0666); - if (IS_ERR(filp)) { - pr_info("create %s header error.\n", buff); - return; - } - - for (i = 0; i < devp->vfmem_max_cnt; i++) { - vfs_write(filp, buf_head, - devp->afbce_info->frame_head_size, &pos); - buf_head += devp->afbce_info->frame_head_size; - pr_info("write buffer %2d(0x%x bytes) of %2u head to %s.\n", - i, devp->afbce_info->frame_head_size, - devp->canvas_max_num, buff); - } - vfs_fsync(filp, 0); - filp_close(filp, NULL); - /* write header bin end */ - - /* write table bin start */ - pos = 0; - strcpy(buff, path); - strcat(buff, "_table.bin"); - filp = filp_open(buff, O_RDWR|O_CREAT, 0666); - if (IS_ERR(filp)) { - pr_info("create %s table error.\n", buff); - return; - } + if (highmem_flag == 0) { + vfs_write(filp, buf_body, + devp->afbce_info->frame_body_size, &pos); + } else { + span = SZ_1M; + count = devp->afbce_info->frame_body_size/PAGE_ALIGN(span); + remain = devp->afbce_info->frame_body_size%PAGE_ALIGN(span); + phys = devp->afbce_info->fm_body_paddr[buf_num]; + + for (j = 0; j < count; j++) { + highaddr = phys + j * span; + vbuf = vdin_vmap(highaddr, span); + if (!vbuf) { + pr_info("vdin_vmap error\n"); + return; + } - for (i = 0; i < devp->vfmem_max_cnt; i++) { - vfs_write(filp, buf_table, - devp->afbce_info->frame_table_size, &pos); - buf_table += devp->afbce_info->frame_table_size; - pr_info("write buffer %2d(0x%x bytes) of %2u table to %s.\n", - i, devp->afbce_info->frame_table_size, - devp->canvas_max_num, buff); - } - vfs_fsync(filp, 0); - filp_close(filp, NULL); - /* write table bin end */ + vdin_dma_flush(devp, vbuf, span, DMA_FROM_DEVICE); + vfs_write(filp, vbuf, span, &pos); + vdin_unmap_phyaddr(vbuf); + } - /* write body bin start */ - pos = 0; - strcpy(buff, path); - strcat(buff, "_body.bin"); - filp = filp_open(buff, O_RDWR|O_CREAT, 0666); - if (IS_ERR(filp)) { - pr_info("create %s body error.\n", buff); - return; - } + if (remain) { + span = devp->afbce_info->frame_body_size - remain; + highaddr = phys + span; + vbuf = vdin_vmap(highaddr, remain); + if (!vbuf) { + pr_info("vdin_vmap1 error\n"); + return; + } - for (i = 0; i < devp->vfmem_max_cnt; i++) { - vfs_write(filp, buf_body, - devp->afbce_info->frame_body_size, &pos); - buf_body += devp->afbce_info->frame_body_size; - pr_info("write buffer %2d(0x%x bytes) of %2u body to %s.\n", - i, devp->afbce_info->frame_body_size, - devp->canvas_max_num, buff); + vdin_dma_flush(devp, vbuf, remain, DMA_FROM_DEVICE); + vfs_write(filp, vbuf, remain, &pos); + vdin_unmap_phyaddr(vbuf); + } } + pr_info("write buffer %2d of %2u body to %s.\n", + buf_num, devp->canvas_max_num, buff); vfs_fsync(filp, 0); filp_close(filp, NULL); - /* write body bin end */ set_fs(old_fs); } @@ -699,6 +761,7 @@ static void vdin_dump_state(struct vdin_dev_s *devp) pr_info("color_depth_support:0x%x\n", devp->color_depth_support); pr_info("cma_flag:0x%x\n", devp->cma_config_flag); pr_info("auto_cutwindow_en:%d\n", devp->auto_cutwindow_en); + pr_info("cutwindow_cfg:%d\n", devp->cutwindow_cfg); pr_info("auto_ratio_en:%d\n", devp->auto_ratio_en); pr_info("cma_mem_alloc:%d\n", devp->cma_mem_alloc); pr_info("cma_mem_size:0x%x\n", devp->cma_mem_size); @@ -745,7 +808,7 @@ static void vdin_dump_state(struct vdin_dev_s *devp) pr_info("vdin_irq_flag: %d, vdin_rest_flag: %d, irq_cnt: %d, rdma_irq_cnt: %d\n", devp->vdin_irq_flag, devp->vdin_reset_flag, devp->irq_cnt, devp->rdma_irq_cnt); - pr_info("rdma_enable : %d\n", devp->rdma_enable); + pr_info("game_mode : %d\n", devp->game_mode); pr_info("dolby_input : %d\n", devp->dv.dolby_input); if ((devp->cma_config_en != 1) || !(devp->cma_config_flag & 0x100)) pr_info("dolby_mem_start = %ld, dolby_mem_size = %d\n", @@ -766,6 +829,8 @@ static void vdin_dump_state(struct vdin_dev_s *devp) devp->dv.dv_flag, devp->dv.dv_config, devp->prop.dolby_vision); pr_info("size of struct vdin_dev_s: %d\n", devp->vdin_dev_ssize); + pr_info("afbce_flag: 0x%x\n", devp->afbce_flag); + pr_info("afbce_mode: %d\n", devp->afbce_mode); if (devp->afbce_mode == 1) { for (i = 0; i < devp->vfmem_max_cnt; i++) { pr_info("head(%d) addr:0x%lx, size:0x%x\n", @@ -789,13 +854,9 @@ static void vdin_dump_state(struct vdin_dev_s *devp) devp->afbce_info->frame_body_size); } } - pr_info("Vdin driver version : %s\n", VDIN_VER); } -/*2018-07-18 add debugfs*/ -struct vdin_dev_s *vdin_get_dev(unsigned int index); - /*same as vdin_dump_state*/ static int seq_file_vdin_state_show(struct seq_file *seq, void *v) { @@ -936,6 +997,140 @@ static void vdin_dump_histgram(struct vdin_dev_s *devp) } } +/*type: 1:nv21 2:yuv422 3:yuv444*/ +static void vdin_write_afbce_mem(struct vdin_dev_s *devp, char *type, + char *path) +{ + char md_path_head[100], md_path_body[100]; + unsigned int i, j; + int highmem_flag = 0; + unsigned int size = 0; + unsigned int span = 0; + unsigned int remain = 0; + unsigned int count = 0; + unsigned long highaddr; + unsigned long phys; + long val; + struct file *filp = NULL; + loff_t pos = 0; + mm_segment_t old_fs; + void *head_dts = NULL; + void *body_dts = NULL; + void *vbuf = NULL; + + if (kstrtol(type, 10, &val) < 0) + return; + if (!path) + return; + + if (!devp->curr_wr_vfe) { + devp->curr_wr_vfe = provider_vf_get(devp->vfp); + if (!devp->curr_wr_vfe) { + pr_info("no buffer to write.\n"); + return; + } + } + + sprintf(md_path_head, "%s_1header.bin", path); + sprintf(md_path_body, "%s_1body.bin", path); + + i = devp->curr_wr_vfe->af_num; + devp->curr_wr_vfe->vf.type = VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD | VIDTYPE_COMPRESS | VIDTYPE_SCATTER; + switch (val) { + case 1: + devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_NV21; + break; + case 2: + devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_422; + break; + case 3: + devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_444; + break; + default: + devp->curr_wr_vfe->vf.type |= VIDTYPE_VIU_422; + break; + } + + devp->curr_wr_vfe->vf.compHeadAddr = devp->afbce_info->fm_head_paddr[i]; + devp->curr_wr_vfe->vf.compBodyAddr = devp->afbce_info->fm_body_paddr[i]; + + highmem_flag = PageHighMem( + phys_to_page(devp->afbce_info->fm_body_paddr[0])); + if (highmem_flag == 0) { + pr_info("low mem area\n"); + head_dts = codec_mm_phys_to_virt( + devp->afbce_info->fm_head_paddr[i]); + } else { + pr_info("high mem area\n"); + head_dts = vdin_vmap( + devp->afbce_info->fm_head_paddr[i], + devp->afbce_info->frame_head_size); + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + pr_info("head bin file path = %s\n", md_path_head); + filp = filp_open(md_path_head, O_RDONLY, 0); + if (IS_ERR(filp)) { + pr_info("read %s error.\n", md_path_head); + return; + } + + size = vfs_read(filp, head_dts, + devp->afbce_info->frame_head_size, &pos); + if (highmem_flag) + vdin_unmap_phyaddr(head_dts); + + vfs_fsync(filp, 0); + filp_close(filp, NULL); + set_fs(old_fs); + + pos = 0; + old_fs = get_fs(); + set_fs(KERNEL_DS); + pr_info("body bin file path = %s\n", md_path_body); + filp = filp_open(md_path_body, O_RDONLY, 0); + if (IS_ERR(filp)) { + pr_info("read %s error.\n", md_path_body); + return; + } + + if (highmem_flag == 0) { + body_dts = codec_mm_phys_to_virt( + devp->afbce_info->fm_body_paddr[i]); + + size = vfs_read(filp, body_dts, + devp->afbce_info->frame_body_size, &pos); + } else { + span = SZ_1M; + count = devp->afbce_info->frame_body_size/PAGE_ALIGN(span); + remain = devp->afbce_info->frame_body_size%PAGE_ALIGN(span); + phys = devp->afbce_info->fm_body_paddr[i]; + + + for (j = 0; j < count; j++) { + highaddr = phys + j * span; + vbuf = vdin_vmap(highaddr, span); + if (!vbuf) { + pr_info("vdin_vmap error\n"); + return; + } + vfs_read(filp, vbuf, span, &pos); + vdin_unmap_phyaddr(vbuf); + } + } + + vfs_fsync(filp, 0); + filp_close(filp, NULL); + set_fs(old_fs); + + provider_vf_put(devp->curr_wr_vfe, devp->vfp); + devp->curr_wr_vfe = NULL; + vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); +} + static void vdin_write_mem( struct vdin_dev_s *devp, char *type, char *path, char *md_path) @@ -946,8 +1141,10 @@ static void vdin_write_mem( mm_segment_t old_fs; void *dts = NULL; long val; - int index; + int index, j, span; + int highmem_flag, count; unsigned long addr; + unsigned long highaddr; struct vf_pool *p = devp->vfp; /* vtype = simple_strtol(type, NULL, 10); */ @@ -996,15 +1193,43 @@ static void vdin_write_mem( addr = canvas_get_addr(devp->curr_wr_vfe->vf.canvas0Addr); /* dts = ioremap(canvas_get_addr(devp->curr_wr_vfe->vf.canvas0Addr), */ /* real_size); */ - dts = phys_to_virt(addr); - size = vfs_read(filp, dts, devp->canvas_max_size, &pos); - pr_info("warning: %s read %u < %u\n", - __func__, size, devp->canvas_max_size); - vfs_fsync(filp, 0); - iounmap(dts); - filp_close(filp, NULL); - set_fs(old_fs); + if (devp->cma_config_flag & 0x100) + highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); + else + highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); + + if (highmem_flag == 0) { + pr_info("low mem area\n"); + dts = phys_to_virt(addr); + for (j = 0; j < devp->canvas_h; j++) { + vfs_read(filp, dts+(devp->canvas_w*j), + devp->canvas_active_w, &pos); + } + vfs_fsync(filp, 0); + iounmap(dts); + filp_close(filp, NULL); + set_fs(old_fs); + } else { + pr_info("high mem area\n"); + count = devp->canvas_h; + span = devp->canvas_active_w; + for (j = 0; j < count; j++) { + highaddr = addr + j * devp->canvas_w; + dts = vdin_vmap(highaddr, span); + if (!dts) { + pr_info("vdin_vmap error\n"); + return; + } + vfs_read(filp, dts, span, &pos); + vdin_dma_flush(devp, dts, span, DMA_TO_DEVICE); + vdin_unmap_phyaddr(dts); + } + vfs_fsync(filp, 0); + filp_close(filp, NULL); + set_fs(old_fs); + } + if (vtype == 8) { old_fs = get_fs(); set_fs(KERNEL_DS); @@ -1020,7 +1245,7 @@ static void vdin_write_mem( u8 *c = devp->vfp->dv_buf_ori[index]; pos = 0; - size = vfs_read(md_flip, + size = (unsigned int)vfs_read(md_flip, devp->vfp->dv_buf_ori[index], 4096, &pos); p->dv_buf_size[index] = size; @@ -1352,6 +1577,9 @@ start_chk: } else if (!strcmp(parm[1], "video")) { param.port = TVIN_PORT_VIU1_VIDEO; pr_info(" port is TVIN_PORT_VIU_VIDEO\n"); + } else if (!strcmp(parm[1], "viu_wb0_vpp")) { + param.port = TVIN_PORT_VIU1_WB0_VPP; + pr_info(" port is TVIN_PORT_VIU1_WB0_VPP\n"); } else if (!strcmp(parm[1], "viu_wb0_vd1")) { param.port = TVIN_PORT_VIU1_WB0_VD1; pr_info(" port is TVIN_PORT_VIU_WB0_VD1\n"); @@ -1367,6 +1595,9 @@ start_chk: } else if (!strcmp(parm[1], "viu_wb0_post_blend")) { param.port = TVIN_PORT_VIU1_WB0_POST_BLEND; pr_info(" port is TVIN_PORT_VIU_WB0_POST_BLEND\n"); + } else if (!strcmp(parm[1], "viu_wb1_vpp")) { + param.port = TVIN_PORT_VIU1_WB1_VPP; + pr_info(" port is TVIN_PORT_VIU1_WB1_VPP\n"); } else if (!strcmp(parm[1], "viu_wb1_vd1")) { param.port = TVIN_PORT_VIU1_WB1_VD1; pr_info(" port is TVIN_PORT_VIU_WB1_VD1\n"); @@ -1388,6 +1619,9 @@ start_chk: } else if (!strcmp(parm[1], "video2")) { param.port = TVIN_PORT_VIU2_VIDEO; pr_info(" port is TVIN_PORT_VIU_VIDEO\n"); + } else if (!strcmp(parm[1], "viu2_wb0_vpp")) { + param.port = TVIN_PORT_VIU2_WB0_VPP; + pr_info(" port is TVIN_PORT_VIU2_WB0_VPP\n"); } else if (!strcmp(parm[1], "viu2_wb0_vd1")) { param.port = TVIN_PORT_VIU2_WB0_VD1; pr_info(" port is TVIN_PORT_VIU_WB0_VD1\n"); @@ -1403,6 +1637,9 @@ start_chk: } else if (!strcmp(parm[1], "viu2_wb0_post_blend")) { param.port = TVIN_PORT_VIU2_WB0_POST_BLEND; pr_info(" port is TVIN_PORT_VIU_WB0_POST_BLEND\n"); + } else if (!strcmp(parm[1], "viu2_wb1_vpp")) { + param.port = TVIN_PORT_VIU2_WB1_VPP; + pr_info(" port is TVIN_PORT_VIU2_WB1_VPP\n"); } else if (!strcmp(parm[1], "viu2_wb1_vd1")) { param.port = TVIN_PORT_VIU2_WB1_VD1; pr_info(" port is TVIN_PORT_VIU_WB1_VD1\n"); @@ -1509,6 +1746,11 @@ start_chk: #endif } else if (!strcmp(parm[0], "force_recycle")) { devp->flags |= VDIN_FLAG_FORCE_RECYCLE; + } else if (!strcmp(parm[0], "read_pic_afbce")) { + if (parm[1] && parm[2]) + vdin_write_afbce_mem(devp, parm[1], parm[2]); + else + pr_err("miss parameters.\n"); } else if (!strcmp(parm[0], "read_pic")) { if (parm[1] && parm[2]) vdin_write_mem(devp, parm[1], parm[2], parm[3]); @@ -1524,11 +1766,23 @@ start_chk: unsigned int offset = devp->addr_offset; pr_info("vdin%d addr offset:0x%x regs start----\n", devp->index, offset); - for (reg = VDIN_SCALE_COEF_IDX; reg <= 0x1273; reg++) - pr_info("[0x%x]reg:0x%x-0x%x\n", - (0xd0100000 + ((reg+offset)<<2)), - (reg+offset), rd(offset, reg)); - pr_info("vdin%d regs end----\n", devp->index); + for (reg = VDIN_SCALE_COEF_IDX; reg <= 0x1273; reg++) { + pr_info("0x%04x = 0x%08x\n", + (reg+offset), rd(offset, reg)); + } + pr_info("vdin%d regs end----\n", devp->index); + if (devp->afbce_flag & VDIN_AFBCE_EN) { + pr_info("vdin%d afbce regs start----\n", devp->index); + for (reg = AFBCE_ENABLE; reg <= AFBCE_MMU_RMIF_RO_STAT; + reg++) { + pr_info("0x%04x = 0x%08x\n", + (reg), R_VCBUS(reg)); + } + pr_info("vdin%d afbce regs end----\n", devp->index); + } + reg = VDIN_MISC_CTRL; + pr_info("0x%04x = 0x%08x\n", (reg), R_VCBUS(reg)); + pr_info("\n"); } else if (!strcmp(parm[0], "rgb_xy")) { unsigned int x = 0, y = 0; @@ -1847,15 +2101,9 @@ start_chk: pr_info("urgent_en (%d):%d\n", devp->index, devp->urgent_en); } - } else if (!strcmp(parm[0], "irq_flag")) { - if (!parm[1]) - pr_err("miss parameters .\n"); - else if (kstrtoul(parm[1], 10, &val) == 0) { - devp->vdin_irq_flag = val; - pr_info("vdin(%d) irq_flag: %d\n", devp->index, - devp->vdin_irq_flag); - } - } else if (!strcmp(parm[0], "skip_vf_num")) { + } else if (!strcmp(parm[0], "irq_cnt")) + pr_info("vdin(%d) irq_cnt: %d\n", devp->index, devp->irq_cnt); + else if (!strcmp(parm[0], "skip_vf_num")) { if (!parm[1]) pr_err("miss parameters .\n"); else if ((kstrtoul(parm[1], 10, &val) == 0) && (devp->vfp)) { @@ -1875,11 +2123,83 @@ start_chk: buf_num = val; vdin_dump_one_afbce_mem(parm[1], devp, buf_num); } else if (parm[1] != NULL) { - vdin_dump_afbce_mem(parm[1], devp); + vdin_dump_one_afbce_mem(parm[1], devp, 0); } - } else { + } else if (!strcmp(parm[0], "skip_frame_debug")) { + if (parm[1] != NULL) { + if (kstrtouint(parm[1], 10, &skip_frame_debug) == 0) + pr_info("set skip_frame_debug: %d\n", + skip_frame_debug); + } else { + pr_info("skip_frame_debug: %d\n", skip_frame_debug); + } + } else if (!strcmp(parm[0], "max_recycle_cnt")) { + if (parm[1] != NULL) { + if (kstrtouint(parm[1], 10, + &max_recycle_frame_cnt) == 0) + pr_info("set max_recycle_frame_cnt: %d\n", + max_recycle_frame_cnt); + } else { + pr_info("max_recycle_frame_cnt: %d\n", + max_recycle_frame_cnt); + } + } else if (!strcmp(parm[0], "max_ignore_cnt")) { + if (parm[1] != NULL) { + if (kstrtouint(parm[1], 10, &max_ignore_frame_cnt) == 0) + pr_info("set max_ignore_frame_cnt: %d\n", + max_ignore_frame_cnt); + } else { + pr_info("max_ignore_frame_cnt: %d\n", + max_ignore_frame_cnt); + } + } else if (!strcmp(parm[0], "afbce_flag")) { + if (parm[1] != NULL) { + if (kstrtouint(parm[1], 16, &devp->afbce_flag) == 0) { + pr_info("set vdin_afbce_flag: 0x%x\n", + devp->afbce_flag); + } + } else { + pr_info("vdin_afbce_flag: 0x%x\n", devp->afbce_flag); + } + } else if (!strcmp(parm[0], "afbce_mode")) { + unsigned int mode = 0, flag = 0; + + if (parm[2] != NULL) { + if ((kstrtouint(parm[1], 10, &mode) == 0) && + (kstrtouint(parm[2], 10, &flag) == 0)) { + vdin0_afbce_debug_force = flag; + if (devp->afbce_flag & VDIN_AFBCE_EN) + devp->afbce_mode = mode; + else + devp->afbce_mode = 0; + if (vdin0_afbce_debug_force) { + pr_info("set force vdin_afbce_mode: %d\n", + devp->afbce_mode); + } else { + pr_info("set vdin_afbce_mode: %d\n", + devp->afbce_mode); + } + } + } else if (parm[1] != NULL) { + if (kstrtouint(parm[1], 10, &mode) == 0) { + if (devp->afbce_flag & VDIN_AFBCE_EN) + devp->afbce_mode = mode; + else + devp->afbce_mode = 0; + pr_info("set vdin_afbce_mode: %d\n", + devp->afbce_mode); + } + } else { + pr_info("vdin_afbce_mode: %d\n", devp->afbce_mode); + } + } else if (!strcmp(parm[0], "vdi6_afifo_overflow")) + pr_info("%d\n", + vdin_check_vdi6_afifo_overflow(devp->addr_offset)); + else if (!strcmp(parm[0], "vdi6_afifo_clear")) + vdin_clear_vdi6_afifo_overflow_flg(devp->addr_offset); + else pr_info("unknown command\n"); - } + kfree(buf_orig); return len; } diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c index 74993dc..a0dd165 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c @@ -41,9 +41,13 @@ #include #include #include +#include +#include +#include #include #include #include +#include /* Amlogic Headers */ #include #include @@ -78,6 +82,10 @@ static unsigned int vdin_addr_offset[VDIN_MAX_DEVS] = {0, 0x80}; static struct vdin_dev_s *vdin_devp[VDIN_MAX_DEVS]; static unsigned long mem_start, mem_end; static unsigned int use_reserved_mem; +static unsigned int pr_times; + +struct vdin_set_canvas_addr_s vdin_set_canvas_addr[VDIN_CANVAS_MAX_CNT]; +static DECLARE_WAIT_QUEUE_HEAD(vframe_waitq); /* * canvas_config_mode * 0: canvas_config in driver probe @@ -86,13 +94,23 @@ static unsigned int use_reserved_mem; */ static int canvas_config_mode = 2; static bool work_mode_simple; -static int max_ignore_frames = 2; -static int ignore_frames; +static int phase_lock_flag; +/*game_mode_switch_frames:min num is 5 by 1080p60hz input test*/ +static int game_mode_switch_frames = 10; +static int game_mode_phlock_switch_frames = 60; static unsigned int dv_work_delby; + +static struct vf_entry *vfe_drop_force; + +unsigned int max_recycle_frame_cnt; +unsigned int max_ignore_frame_cnt = 2; +unsigned int skip_frame_debug; + /* viu isr select: * enable viu_hw_irq for the bandwidth is enough on gxbb/gxtvbb and laters ic */ static bool viu_hw_irq = 1; +static bool de_fmt_flag; #ifdef DEBUG_SUPPORT module_param(canvas_config_mode, int, 0664); @@ -101,20 +119,21 @@ MODULE_PARM_DESC(canvas_config_mode, "canvas configure mode"); module_param(work_mode_simple, bool, 0664); MODULE_PARM_DESC(work_mode_simple, "enable/disable simple work mode"); -module_param(max_ignore_frames, int, 0664); -MODULE_PARM_DESC(max_ignore_frames, "ignore first frames"); - -module_param(ignore_frames, int, 0664); -MODULE_PARM_DESC(ignore_frames, "ignore first frames"); +module_param(viu_hw_irq, bool, 0664); +MODULE_PARM_DESC(viu_hw_irq, "viu_hw_irq"); module_param(dv_work_delby, uint, 0664); MODULE_PARM_DESC(dv_work_delby, "dv_work_delby"); -module_param(viu_hw_irq, bool, 0664); -MODULE_PARM_DESC(viu_hw_irq, "viu_hw_irq"); +module_param(game_mode_switch_frames, int, 0664); +MODULE_PARM_DESC(game_mode_switch_frames, "game mode switch frames"); + +module_param(game_mode_phlock_switch_frames, int, 0664); +MODULE_PARM_DESC(game_mode_phlock_switch_frames, + "game mode switch frames for phase_lock"); #endif -static bool vdin_dbg_en; +bool vdin_dbg_en; module_param(vdin_dbg_en, bool, 0664); MODULE_PARM_DESC(vdin_dbg_en, "enable/disable vdin debug information"); @@ -134,6 +153,8 @@ static unsigned int vdin_drop_cnt; module_param(vdin_drop_cnt, uint, 0664); MODULE_PARM_DESC(vdin_drop_cnt, "vdin_drop_cnt"); +struct vdin_hist_s vdin1_hist; +struct vdin_v4l2_param_s vdin_v4l2_param; static int irq_max_count; @@ -266,11 +287,30 @@ static void vdin_game_mode_check(struct vdin_dev_s *devp) (devp->parm.port != TVIN_PORT_CVBS3)) { if (devp->h_active > 720 && ((devp->parm.info.fps == 50) || (devp->parm.info.fps == 60))) - devp->game_mode = 3; + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { + devp->game_mode = (VDIN_GAME_MODE_0 | + VDIN_GAME_MODE_1 | + VDIN_GAME_MODE_SWITCH_EN); + } else { + devp->game_mode = (VDIN_GAME_MODE_0 | + VDIN_GAME_MODE_1); + } else - devp->game_mode = 1; - } else + devp->game_mode = VDIN_GAME_MODE_0; + } else if (game_mode == 2)/*for debug force game mode*/ + devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1); + else if (game_mode == 3)/*for debug force game mode*/ + devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2); + else if (game_mode == 4)/*for debug force game mode*/ + devp->game_mode = VDIN_GAME_MODE_0; + else if (game_mode == 5)/*for debug force game mode*/ + devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1 | + VDIN_GAME_MODE_SWITCH_EN); + else devp->game_mode = 0; + + pr_info("%s: game_mode flag=%d, game_mode=%d\n", + __func__, game_mode, devp->game_mode); } /* *based on the bellow parameters: @@ -318,6 +358,7 @@ static void vdin_vf_init(struct vdin_dev_s *devp) #ifndef VDIN_DYNAMIC_DURATION vf->duration = devp->fmt_info_p->duration; #endif + /* init canvas config */ /*if output fmt is nv21 or nv12 , * use the two continuous canvas for one field */ @@ -325,14 +366,20 @@ static void vdin_vf_init(struct vdin_dev_s *devp) (devp->prop.dest_cfmt == TVIN_NV21)) { chromaid = (vdin_canvas_ids[index][(vf->index<<1)+1])<<8; - addr = - vdin_canvas_ids[index][vf->index<<1] | - chromaid; - } else + addr = vdin_canvas_ids[index][vf->index<<1] | chromaid; + } else { addr = vdin_canvas_ids[index][vf->index]; - + } vf->canvas0Addr = vf->canvas1Addr = addr; + /* init afbce config */ + if (devp->afbce_info) { + vf->compHeadAddr = devp->afbce_info->fm_head_paddr[i]; + vf->compBodyAddr = devp->afbce_info->fm_body_paddr[i]; + vf->compWidth = devp->h_active; + vf->compHeight = devp->v_active; + } + /* set source type & mode */ vdin_set_source_type(devp, vf); vdin_set_source_mode(devp, vf); @@ -367,7 +414,7 @@ static void vdin_vf_init(struct vdin_dev_s *devp) } } -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA static void vdin_rdma_irq(void *arg) { struct vdin_dev_s *devp = arg; @@ -376,12 +423,37 @@ static void vdin_rdma_irq(void *arg) return; } -static struct rdma_op_s vdin_rdma_op = { - vdin_rdma_irq, - NULL -}; +static struct rdma_op_s vdin_rdma_op[VDIN_MAX_DEVS]; #endif +static void vdin_afbce_mode_init(struct vdin_dev_s *devp) +{ + /* afbce_valid means can switch into afbce mode */ + devp->afbce_valid = 0; + if (devp->afbce_flag & VDIN_AFBCE_EN) { + if ((devp->h_active > 1920) && (devp->v_active > 1080)) { + if (devp->afbce_flag & VDIN_AFBCE_EN_4K) + devp->afbce_valid = 1; + } else if ((devp->h_active > 1280) && (devp->v_active > 720)) { + if (devp->afbce_flag & VDIN_AFBCE_EN_1080P) + devp->afbce_valid = 1; + } else if ((devp->h_active > 720) && (devp->v_active > 576)) { + if (devp->afbce_flag & VDIN_AFBCE_EN_720P) + devp->afbce_valid = 1; + } else { + if (devp->afbce_flag & VDIN_AFBCE_EN_SMALL) + devp->afbce_valid = 1; + } + } + + /* default non-afbce mode + * switch to afbce_mode if need by vpp notify + */ + devp->afbce_mode = 0; + devp->afbce_mode_pre = devp->afbce_mode; + pr_info("vdin%d init afbce_mode: %d\n", devp->index, devp->afbce_mode); +} + /* * 1. config canvas base on canvas_config_mode * 0: canvas_config in driver probe @@ -408,10 +480,10 @@ void vdin_start_dec(struct vdin_dev_s *devp) pr_info("[vdin]%s null error.\n", __func__); return; } + if (devp->frontend && devp->frontend->sm_ops) { sm_ops = devp->frontend->sm_ops; sm_ops->get_sig_property(devp->frontend, &devp->prop); - if (!(devp->flags & VDIN_FLAG_V4L2_DEBUG)) devp->parm.info.cfmt = devp->prop.color_format; if ((devp->parm.dest_width != 0) || @@ -434,7 +506,6 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->prop.ve = devp->debug.cutwin.ve; } } - /*gxbb/gxl/gxm use clkb as vdin clk, *for clkb is low speed,wich is enough for 1080p process, *gxtvbb/txl use vpu clk for process 4k @@ -452,6 +523,21 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->canvas_config_mode = canvas_config_mode; /* h_active/v_active will be recalculated by bellow calling */ vdin_set_decimation(devp); + if (de_fmt_flag == 1 && + (devp->prop.vs != 0 || + devp->prop.ve != 0 || + devp->prop.hs != 0 || + devp->prop.he != 0)) { + devp->prop.vs = 0; + devp->prop.ve = 0; + devp->prop.hs = 0; + devp->prop.he = 0; + devp->prop.pre_vs = 0; + devp->prop.pre_ve = 0; + devp->prop.pre_hs = 0; + devp->prop.pre_he = 0; + pr_info("ioctl start dec,restore the cutwin param.\n"); + } vdin_set_cutwin(devp); vdin_set_hvscale(devp); if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) @@ -460,37 +546,33 @@ void vdin_start_dec(struct vdin_dev_s *devp) if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) vdin_fix_nonstd_vsync(devp); - - /*reverse / disable reverse write buffer*/ + /*reverse / disable reverse write buffer*/ vdin_wr_reverse(devp->addr_offset, - devp->parm.h_reverse, - devp->parm.v_reverse); + devp->parm.h_reverse, devp->parm.v_reverse); + + /* check if need enable afbce */ + vdin_afbce_mode_init(devp); + #ifdef CONFIG_CMA vdin_cma_malloc_mode(devp); - if (devp->afbce_mode == 1) { - if (vdin_afbce_cma_alloc(devp)) { - pr_err("\nvdin%d-afbce %s fail for cma alloc fail!!!\n", - devp->index, __func__); - return; - } - } else if (devp->afbce_mode == 0) { - if (vdin_cma_alloc(devp)) { - pr_err("\nvdin%d %s fail for cma alloc fail!!!\n", - devp->index, __func__); - return; - } + if (vdin_cma_alloc(devp)) { + pr_err("\nvdin%d %s fail for cma alloc fail!!!\n", + devp->index, __func__); + return; } #endif + /* h_active/v_active will be used by bellow calling */ - if (devp->afbce_mode == 0) { - if (canvas_config_mode == 1) - vdin_canvas_start_config(devp); - else if (canvas_config_mode == 2) - vdin_canvas_auto_config(devp); - } else if (devp->afbce_mode == 1) { + if (canvas_config_mode == 1) + vdin_canvas_start_config(devp); + else if (canvas_config_mode == 2) + vdin_canvas_auto_config(devp); + + if (devp->afbce_info) { vdin_afbce_maptable_init(devp); vdin_afbce_config(devp); } + #if 0 if ((devp->prop.dest_cfmt == TVIN_NV12) || (devp->prop.dest_cfmt == TVIN_NV21)) @@ -505,7 +587,7 @@ void vdin_start_dec(struct vdin_dev_s *devp) else devp->duration = devp->fmt_info_p->duration; - devp->vfp->size = devp->canvas_max_num; + devp->vfp->size = devp->vfmem_max_cnt; /* canvas and afbce compatible */ vf_pool_init(devp->vfp, devp->vfp->size); vdin_game_mode_check(devp); vdin_vf_init(devp); @@ -523,6 +605,7 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->abnormal_cnt = 0; devp->last_wr_vfe = NULL; irq_max_count = 0; + vdin_drop_cnt = 0; /* devp->stamp_valid = false; */ devp->stamp = 0; devp->cycle = 0; @@ -537,13 +620,7 @@ void vdin_start_dec(struct vdin_dev_s *devp) vdin_hw_enable(devp->addr_offset); vdin_set_all_regs(devp); - - if (is_meson_tl1_cpu()) { - if (devp->afbce_mode == 0) - vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF); - else if (devp->afbce_mode == 1) - vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_AFBCE); - } + vdin_write_mif_or_afbce_init(devp); if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) && (devp->frontend) && @@ -554,7 +631,7 @@ void vdin_start_dec(struct vdin_dev_s *devp) devp->frontend->dec_ops->start(devp->frontend, devp->parm.info.fmt); -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA /*it is better put after all reg init*/ if (devp->rdma_enable && devp->rdma_handle > 0) devp->flags |= VDIN_FLAG_RDMA_ENABLE; @@ -576,14 +653,6 @@ void vdin_start_dec(struct vdin_dev_s *devp) #endif vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_START, NULL); - if ((devp->parm.port != TVIN_PORT_VIU1) || - (viu_hw_irq != 0)) { - /*enable irq */ - enable_irq(devp->irq); - if (vdin_dbg_en) - pr_info("****[%s]enable_irq ifdef VDIN_V2****\n", - __func__); - } if (vdin_dbg_en) pr_info("****[%s]ok!****\n", __func__); @@ -599,10 +668,16 @@ void vdin_start_dec(struct vdin_dev_s *devp) #endif devp->irq_cnt = 0; devp->rdma_irq_cnt = 0; + devp->frame_cnt = 0; + phase_lock_flag = 0; + if (time_en) pr_info("vdin.%d start time: %ums, run time:%ums.\n", devp->index, jiffies_to_msecs(jiffies), jiffies_to_msecs(jiffies)-devp->start_time); + + vfe_drop_force = NULL; + devp->recycle_frames = 0; } /* @@ -615,6 +690,9 @@ void vdin_start_dec(struct vdin_dev_s *devp) */ void vdin_stop_dec(struct vdin_dev_s *devp) { + int afbc_write_down_timeout = 500; /* 50ms to cover a 24Hz vsync */ + int i = 0; + /* avoid null pointer oops */ if (!devp || !devp->frontend) return; @@ -624,8 +702,21 @@ void vdin_stop_dec(struct vdin_dev_s *devp) return; } #endif + disable_irq_nosync(devp->irq); - vdin_hw_disable(devp->addr_offset); + + if (devp->afbce_mode == 1) { + while (i++ < afbc_write_down_timeout) { + if (vdin_afbce_read_writedown_flag()) + break; + usleep_range(100, 105); + } + if (i >= afbc_write_down_timeout) { + pr_info("vdin.%d afbc write done timeout\n", + devp->index); + } + } + if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) && devp->frontend->dec_ops && devp->frontend->dec_ops->stop && @@ -633,6 +724,8 @@ void vdin_stop_dec(struct vdin_dev_s *devp) ((devp->flags & VDIN_FLAG_SNOW_FLAG) == 0))) devp->frontend->dec_ops->stop(devp->frontend, devp->parm.port); + vdin_hw_disable(devp->addr_offset); + vdin_set_default_regmap(devp->addr_offset); /*only for vdin0*/ if (devp->urgent_en && (devp->index == 0)) @@ -649,24 +742,29 @@ void vdin_stop_dec(struct vdin_dev_s *devp) #endif vf_unreg_provider(&devp->vprov); devp->dv.dv_config = 0; -#ifdef CONFIG_CMA - if (devp->afbce_mode == 1) - vdin_afbce_cma_release(devp); - else if (devp->afbce_mode == 0) - vdin_cma_release(devp); -#endif - vdin_dolby_addr_release(devp, devp->vfp->size); + if (devp->afbce_mode == 1) { + vdin_afbce_hw_disable(); + vdin_afbce_soft_reset(); + } +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + vdin_dolby_addr_release(devp, devp->vfp->size); +#endif + +#ifdef CONFIG_CMA + vdin_cma_release(devp); +#endif switch_vpu_mem_pd_vmod(devp->addr_offset?VPU_VIU_VDIN1:VPU_VIU_VDIN0, VPU_MEM_POWER_DOWN); memset(&devp->prop, 0, sizeof(struct tvin_sig_property_s)); -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA rdma_clear(devp->rdma_handle); #endif devp->flags &= (~VDIN_FLAG_RDMA_ENABLE); - ignore_frames = 0; + devp->ignore_frames = 0; devp->cycle = 0; + /* clear color para*/ memset(&devp->prop, 0, sizeof(devp->prop)); if (time_en) @@ -694,6 +792,7 @@ int start_tvin_service(int no, struct vdin_parm_s *para) __func__, no); return -1; } + fmt = devp->parm.info.fmt; if (vdin_dbg_en) { pr_info("**[%s]cfmt:%d;dfmt:%d;dest_hactive:%d;", @@ -705,21 +804,24 @@ int start_tvin_service(int no, struct vdin_parm_s *para) pr_info("v_active:%d;scan_mode:%d**\n", para->v_active, para->scan_mode); } + + if (devp->index == 1) { + devp->parm.reserved |= para->reserved; + pr_info("vdin1 add reserved = 0x%lx\n", para->reserved); + pr_info("vdin1 all reserved = 0x%x\n", devp->parm.reserved); + } devp->start_time = jiffies_to_msecs(jiffies); if (devp->flags & VDIN_FLAG_DEC_STARTED) { pr_err("%s: port 0x%x, decode started already.\n", __func__, para->port); - ret = -EBUSY; - return ret; - } - if ((para->port != TVIN_PORT_VIU1) || - (viu_hw_irq != 0)) { - ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED, - devp->irq_name, (void *)devp); - devp->flags |= VDIN_FLAG_ISR_REQ; - /*disable vsync irq until vdin configured completely*/ - disable_irq_nosync(devp->irq); + if ((devp->parm.reserved & PARAM_STATE_SCREENCAP) && + (devp->parm.reserved & PARAM_STATE_HISTGRAM) && + (devp->index == 1)) + return 0; + else + return -EBUSY; } + vdin_clk_onoff(devp, true); /*config the vdin use default value*/ vdin_set_default_regmap(devp->addr_offset); @@ -778,6 +880,7 @@ int start_tvin_service(int no, struct vdin_parm_s *para) fe = tvin_get_frontend(para->port, 1); } else fe = tvin_get_frontend(para->port, 0); + if (fe) { fe->private_data = para; fe->port = para->port; @@ -801,6 +904,17 @@ int start_tvin_service(int no, struct vdin_parm_s *para) devp->flags |= VDIN_FLAG_DEC_OPENED; devp->flags |= VDIN_FLAG_DEC_STARTED; + if ((para->port != TVIN_PORT_VIU1) || + (viu_hw_irq != 0)) { + ret = request_irq(devp->irq, vdin_v4l2_isr, IRQF_SHARED, + devp->irq_name, (void *)devp); + + if (ret != 0) { + pr_info("vdin_v4l2_isr request irq error.\n"); + return -1; + } + devp->flags |= VDIN_FLAG_ISR_REQ; + } return 0; } EXPORT_SYMBOL(start_tvin_service); @@ -816,6 +930,14 @@ int stop_tvin_service(int no) unsigned int end_time; devp = vdin_devp[no]; + if ((devp->parm.reserved & PARAM_STATE_HISTGRAM) && + (devp->parm.reserved & PARAM_STATE_SCREENCAP) && + (devp->index == 1)) { + pr_info("stop vdin v4l2 screencap.\n"); + devp->parm.reserved &= ~PARAM_STATE_SCREENCAP; + return 0; + } + if (!(devp->flags&VDIN_FLAG_DEC_STARTED)) { pr_err("%s:decode hasn't started.\n", __func__); return -EBUSY; @@ -1171,6 +1293,77 @@ static u64 func_div(u64 cur, u32 divid) return cur; } +static void vdin_hist_tgt(struct vdin_dev_s *devp, struct vframe_s *vf) +{ + int ave_luma; + int pix_sum; + ulong flags; + + spin_lock_irqsave(&devp->hist_lock, flags); + vdin1_hist.sum = vf->prop.hist.luma_sum; + pix_sum = vf->prop.hist.pixel_sum; + vdin1_hist.height = vf->prop.hist.height; + vdin1_hist.width = vf->prop.hist.width; + + if ((vdin1_hist.height == 0) || (vdin1_hist.width == 0)) { + spin_unlock_irqrestore(&devp->hist_lock, flags); + return; + } + + vdin1_hist.ave = + vdin1_hist.sum/(vdin1_hist.height * vdin1_hist.width); + + ave_luma = vdin1_hist.ave; + ave_luma = (ave_luma - 16) < 0 ? 0 : (ave_luma - 16); + vdin1_hist.ave = ave_luma*255/(235-16); + if (vdin1_hist.ave > 255) + vdin1_hist.ave = 255; + + spin_unlock_irqrestore(&devp->hist_lock, flags); +} + +static bool vdin_recycle_frame_check(struct vdin_dev_s *devp) +{ + int skip_flag = 0; + + if (devp->index) + return false; + + if (devp->recycle_frames < max_recycle_frame_cnt) { + devp->recycle_frames++; + skip_flag = 1; + } + + if (skip_flag) { + vfe_drop_force = receiver_vf_get(devp->vfp); + if (vfe_drop_force) + receiver_vf_put(&vfe_drop_force->vf, devp->vfp); + else + pr_info("vdin.%d: skip vf get error\n", devp->index); + return true; + } + + return false; +} + +static void vdin_afbce_mode_update(struct vdin_dev_s *devp) +{ + /* vdin mif/afbce mode update */ + if (devp->afbce_mode) { + vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_AFBCE); + vdin_afbce_hw_enable_rdma(devp); + } else { + vdin_afbce_hw_disable_rdma(devp); + vdin_write_mif_or_afbce(devp, VDIN_OUTPUT_TO_MIF); + } + + if (vdin_dbg_en) { + pr_info("vdin.%d: change afbce_mode %d->%d\n", + devp->index, devp->afbce_mode_pre, devp->afbce_mode); + } + devp->afbce_mode_pre = devp->afbce_mode; +} + /* *VDIN_FLAG_RDMA_ENABLE=1 * provider_vf_put(devp->last_wr_vfe, devp->vfp); @@ -1209,12 +1402,21 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (!devp->frontend) { devp->vdin_irq_flag = 1; - goto irq_handled; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } + return IRQ_HANDLED; } /* ignore fake irq caused by sw reset*/ if (devp->vdin_reset_flag) { devp->vdin_reset_flag = 0; + devp->vdin_irq_flag = 10; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } return IRQ_HANDLED; } vf_drop_cnt = vdin_drop_cnt; @@ -1230,28 +1432,47 @@ irqreturn_t vdin_isr(int irq, void *dev_id) */ spin_lock_irqsave(&devp->isr_lock, flags); - /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */ - devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); + + if (devp->afbce_mode == 1) { + /* no need reset mif under afbc mode */ + devp->vdin_reset_flag = 0; + } else { + /* W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 0, 2); */ + devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); + } if ((devp->flags & VDIN_FLAG_DEC_STOP_ISR) && (!(isr_flag & VDIN_BYPASS_STOP_CHECK))) { vdin_hw_disable(offset); devp->flags &= ~VDIN_FLAG_DEC_STOP_ISR; devp->vdin_irq_flag = 2; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } goto irq_handled; } stamp = vdin_get_meas_vstamp(offset); if (!devp->curr_wr_vfe) { devp->curr_wr_vfe = provider_vf_get(devp->vfp); - devp->curr_wr_vfe->vf.ready_jiffies64 = jiffies_64; - devp->curr_wr_vfe->vf.ready_clock[0] = sched_clock(); + if (devp->curr_wr_vfe) { + devp->curr_wr_vfe->vf.ready_jiffies64 = jiffies_64; + devp->curr_wr_vfe->vf.ready_clock[0] = sched_clock(); + } /*save the first field stamp*/ devp->stamp = stamp; devp->vdin_irq_flag = 3; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } goto irq_handled; } + + /* use RDMA and not game mode */ if (devp->last_wr_vfe && (devp->flags&VDIN_FLAG_RDMA_ENABLE) && - !(devp->game_mode & (1 << 1))) { + !(devp->game_mode & VDIN_GAME_MODE_1) && + !(devp->game_mode & VDIN_GAME_MODE_2)) { /*dolby vision metadata process*/ if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK && devp->dv.dv_config) { @@ -1281,6 +1502,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) } } else { devp->vdin_irq_flag = 15; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } @@ -1295,15 +1520,33 @@ irqreturn_t vdin_isr(int irq, void *dev_id) (devp->dv.dv_config == true)) vf_notify_receiver("dv_vdin", VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - else + else { +#endif + if (vdin_recycle_frame_check(devp)) { + devp->vdin_irq_flag = 16; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, + devp->vdin_irq_flag); + } + vdin_drop_cnt++; + } else { + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + } +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + } #endif - vf_notify_receiver(devp->name, - VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); } /*check vs is valid base on the time during continuous vs*/ if (vdin_check_cycle(devp) && (!(isr_flag & VDIN_BYPASS_CYC_CHECK)) && (!(devp->flags & VDIN_FLAG_SNOW_FLAG))) { devp->vdin_irq_flag = 4; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } @@ -1329,6 +1572,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) (state != TVIN_SM_STATUS_STABLE)) && (!(devp->flags & VDIN_FLAG_SNOW_FLAG))) { devp->vdin_irq_flag = 6; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } @@ -1340,23 +1587,35 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) || (trans_fmt && (trans_fmt != TVIN_TFMT_3D_FP))) && ((last_field_type & VIDTYPE_INTERLACE_BOTTOM) == - VIDTYPE_INTERLACE_BOTTOM) - ) { + VIDTYPE_INTERLACE_BOTTOM)) { devp->vdin_irq_flag = 7; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } curr_wr_vfe = devp->curr_wr_vfe; curr_wr_vf = &curr_wr_vfe->vf; + /* change afbce mode */ + if (devp->afbce_mode_pre != devp->afbce_mode) + vdin_afbce_mode_update(devp); + /* change color matrix */ if (devp->csc_cfg != 0) { prop = &devp->prop; pre_prop = &devp->pre_prop; if ((prop->color_format != pre_prop->color_format) || (prop->vdin_hdr_Flag != pre_prop->vdin_hdr_Flag) || - (prop->color_fmt_range != pre_prop->color_fmt_range)) + (prop->color_fmt_range != pre_prop->color_fmt_range)) { vdin_set_matrix(devp); + if (skip_frame_debug) { + pr_info("vdin.%d color_format changed\n", + devp->index); + } + } if (prop->dest_cfmt != pre_prop->dest_cfmt) { vdin_set_bitdepth(devp); vdin_source_bitdepth_reinit(devp); @@ -1364,15 +1623,29 @@ irqreturn_t vdin_isr(int irq, void *dev_id) devp->format_convert, devp->color_depth_mode, devp->source_bitdepth, devp->flags&VDIN_FLAG_RDMA_ENABLE); - vdin_set_top(devp->addr_offset, devp->parm.port, + vdin_set_top(devp, devp->addr_offset, devp->parm.port, devp->prop.color_format, devp->h_active, devp->bt_path); + + if (devp->afbce_valid) + vdin_afbce_update(devp); + + if (skip_frame_debug) { + pr_info("vdin.%d dest_cfmt changed: %d->%d\n", + devp->index, + pre_prop->dest_cfmt, prop->dest_cfmt); + } } pre_prop->color_format = prop->color_format; pre_prop->vdin_hdr_Flag = prop->vdin_hdr_Flag; pre_prop->color_fmt_range = prop->color_fmt_range; pre_prop->dest_cfmt = prop->dest_cfmt; - ignore_frames = 0; + devp->ignore_frames = 0; + devp->vdin_irq_flag = 20; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } @@ -1398,6 +1671,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) decops = devp->frontend->dec_ops; if (decops->decode_isr(devp->frontend, devp->hcnt64) == TVIN_BUF_SKIP) { devp->vdin_irq_flag = 8; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } @@ -1406,10 +1683,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id) curr_wr_vf->phase = sm_ops->get_secam_phase(devp->frontend) ? VFRAME_PHASE_DB : VFRAME_PHASE_DR; - - if (ignore_frames < max_ignore_frames) { - ignore_frames++; + if (devp->ignore_frames < max_ignore_frame_cnt) { devp->vdin_irq_flag = 12; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } + devp->ignore_frames++; vdin_drop_cnt++; goto irq_handled; } @@ -1417,19 +1697,38 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (sm_ops->check_frame_skip && sm_ops->check_frame_skip(devp->frontend)) { devp->vdin_irq_flag = 13; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; if (devp->flags&VDIN_FLAG_RDMA_ENABLE) - ignore_frames = 0; + devp->ignore_frames = 0; goto irq_handled; } next_wr_vfe = provider_vf_peek(devp->vfp); if (!next_wr_vfe) { - devp->vdin_irq_flag = 14; - vdin_drop_cnt++; - vf_drop_cnt = vdin_drop_cnt;/*avoid do skip*/ - goto irq_handled; + /*add for force vdin buffer recycle*/ + if (devp->flags & VDIN_FLAG_FORCE_RECYCLE) { + next_wr_vfe = receiver_vf_get(devp->vfp); + if (next_wr_vfe) + receiver_vf_put(&next_wr_vfe->vf, devp->vfp); + else + pr_err("[vdin.%d]force recycle error,no buffer in ready list", + devp->index); + } else { + devp->vdin_irq_flag = 14; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } + vdin_drop_cnt++; + vf_drop_cnt = vdin_drop_cnt;/*avoid do skip*/ + goto irq_handled; + } } + #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (((devp->dv.dolby_input & (1 << devp->index)) || (devp->dv.dv_flag && is_dolby_vision_enable())) && @@ -1440,11 +1739,11 @@ irqreturn_t vdin_isr(int irq, void *dev_id) #endif vdin2nr = vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR, NULL); + /*if vdin-nr,di must get * vdin current field type which di pre will read */ - if ((vdin2nr || (devp->flags & VDIN_FLAG_RDMA_ENABLE)) && - !(devp->game_mode & (1 << 1))) + if (vdin2nr || (devp->flags & VDIN_FLAG_RDMA_ENABLE)) curr_wr_vf->type = devp->curr_field_type; else curr_wr_vf->type = last_field_type; @@ -1454,8 +1753,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) */ if (((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) || (curr_wr_vf->trans_fmt)) && - (last_field_type & VIDTYPE_INTERLACE) - ) { + (last_field_type & VIDTYPE_INTERLACE)) { curr_wr_vf->type &= ~VIDTYPE_INTERLACE_TOP; curr_wr_vf->type |= VIDTYPE_PROGRESSIVE; curr_wr_vf->type |= VIDTYPE_PRE_INTERLACE; @@ -1500,9 +1798,9 @@ irqreturn_t vdin_isr(int irq, void *dev_id) (devp->parm.port <= TVIN_PORT_CVBS3)) vdin_set_display_ratio(devp, curr_wr_vf); if ((devp->flags&VDIN_FLAG_RDMA_ENABLE) && - !(devp->game_mode & (1 << 1))) { + !(devp->game_mode & VDIN_GAME_MODE_1)) { devp->last_wr_vfe = curr_wr_vfe; - } else { + } else if (!(devp->game_mode & VDIN_GAME_MODE_2)) { /*dolby vision metadata process*/ if (dv_dbg_mask & DV_UPDATE_DATA_MODE_DELBY_WORK && devp->dv.dv_config) { @@ -1517,6 +1815,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id) vdin_dolby_addr_update(devp, next_wr_vfe->vf.index); } else devp->dv.dv_crc_check = true; + if ((devp->dv.dv_crc_check == true) || (!(dv_dbg_mask & DV_CRC_CHECK))) { provider_vf_put(curr_wr_vfe, devp->vfp); @@ -1529,6 +1828,10 @@ irqreturn_t vdin_isr(int irq, void *dev_id) } } else { devp->vdin_irq_flag = 15; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } vdin_drop_cnt++; goto irq_handled; } @@ -1536,49 +1839,127 @@ irqreturn_t vdin_isr(int irq, void *dev_id) if (devp->vfp->skip_vf_num > 0) vdin_vf_disp_mode_update(curr_wr_vfe, devp->vfp); } + /*switch to game mode 2 from game mode 1,otherwise may appear blink*/ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { + if (devp->game_mode & VDIN_GAME_MODE_SWITCH_EN) { + /* make sure phase lock for next few frames */ + if (vlock_get_phlock_flag()) + phase_lock_flag++; + if (phase_lock_flag >= game_mode_phlock_switch_frames) { + if (vdin_dbg_en) { + pr_info("switch game mode (%d-->5), frame_cnt=%d\n", + devp->game_mode, + devp->frame_cnt); + } + devp->game_mode = (VDIN_GAME_MODE_0 | + VDIN_GAME_MODE_2); + } + } +#if 0 + if (phase_lock_flag >= game_mode_phlock_switch_frames) { + if (!vlock_get_phlock_flag()) + phase_lock_flag = 0; + if (vdin_dbg_en) { + pr_info( + "switch game mode to %d, frame_cnt=%d\n", + devp->game_mode, devp->frame_cnt); + } + devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_1 | + VDIN_GAME_MODE_SWITCH_EN); + } +#endif + } else { + if ((devp->frame_cnt >= game_mode_switch_frames) && + (devp->game_mode & VDIN_GAME_MODE_SWITCH_EN)) { + if (vdin_dbg_en) { + pr_info("switch game mode (%d-->5), frame_cnt=%d\n", + devp->game_mode, devp->frame_cnt); + } + devp->game_mode = (VDIN_GAME_MODE_0 | VDIN_GAME_MODE_2); + } + } + /* prepare for next input data */ next_wr_vfe = provider_vf_get(devp->vfp); - if (devp->afbce_mode == 0) + if (devp->afbce_mode == 0) { vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE), (next_wr_vfe->vf.canvas0Addr&0xff)); - else if (devp->afbce_mode == 1) + + /* prepare for chroma canvas*/ + if ((devp->prop.dest_cfmt == TVIN_NV12) || + (devp->prop.dest_cfmt == TVIN_NV21)) + vdin_set_chma_canvas_id(devp, + (devp->flags&VDIN_FLAG_RDMA_ENABLE), + (next_wr_vfe->vf.canvas0Addr>>8)&0xff); + } else if (devp->afbce_mode == 1) { vdin_afbce_set_next_frame(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe); - - /* prepare for chroma canvas*/ - if ((devp->prop.dest_cfmt == TVIN_NV12) || - (devp->prop.dest_cfmt == TVIN_NV21)) - vdin_set_chma_canvas_id(devp, - (devp->flags&VDIN_FLAG_RDMA_ENABLE), - (next_wr_vfe->vf.canvas0Addr>>8)&0xff); + } devp->curr_wr_vfe = next_wr_vfe; + next_wr_vfe->vf.type = vdin_get_curr_field_type(devp); /* debug for video latency */ next_wr_vfe->vf.ready_jiffies64 = jiffies_64; next_wr_vfe->vf.ready_clock[0] = sched_clock(); if (!(devp->flags&VDIN_FLAG_RDMA_ENABLE) || - (devp->game_mode & (1 << 1))) { + (devp->game_mode & VDIN_GAME_MODE_1)) { + /* not RDMA, or game mode 1 */ #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (((devp->dv.dolby_input & (1 << devp->index)) || - (devp->dv.dv_flag && is_dolby_vision_enable())) && - (devp->dv.dv_config == true)) + (devp->dv.dv_flag && is_dolby_vision_enable())) + && (devp->dv.dv_config == true)) vf_notify_receiver("dv_vdin", VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); - else + else { +#endif + if (vdin_recycle_frame_check(devp)) { + devp->vdin_irq_flag = 17; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, + devp->vdin_irq_flag); + } + vdin_drop_cnt++; + } else { + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + } +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + } #endif + } else if (devp->game_mode & VDIN_GAME_MODE_2) { + /* game mode 2 */ + provider_vf_put(next_wr_vfe, devp->vfp); + if (vdin_recycle_frame_check(devp)) { + devp->vdin_irq_flag = 18; + if (skip_frame_debug) { + pr_info("vdin.%d: vdin_irq_flag=%d\n", + devp->index, devp->vdin_irq_flag); + } + vdin_drop_cnt++; + } else { vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + if (vdin_dbg_en) { + next_wr_vfe->vf.ready_clock[1] = sched_clock(); + pr_info("vdin put latency %lld us.first %lld us\n", + func_div(next_wr_vfe->vf.ready_clock[1], 1000), + func_div(next_wr_vfe->vf.ready_clock[0], 1000)); + } + } } + devp->frame_cnt++; irq_handled: - /*hdmi skip policy should adapt to all drop vframe case*/ + /*hdmi skip policy should adapt to all drop front vframe case*/ if ((devp->vfp->skip_vf_num > 0) && (vf_drop_cnt < vdin_drop_cnt)) vdin_vf_disp_mode_skip(devp->vfp); spin_unlock_irqrestore(&devp->isr_lock, flags); -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA if (devp->flags & VDIN_FLAG_RDMA_ENABLE) rdma_config(devp->rdma_handle, (devp->rdma_enable&1) ? @@ -1597,6 +1978,15 @@ module_param(skip_ratio, ushort, 0664); MODULE_PARM_DESC(skip_ratio, "\n vdin skip frame ratio 1/ratio will reserved.\n"); +static struct vf_entry *check_vdin_readlist(struct vdin_dev_s *devp) +{ + struct vf_entry *vfe; + + vfe = receiver_vf_peek(devp->vfp); + + return vfe; +} + irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) { ulong flags; @@ -1608,7 +1998,7 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) struct tvin_decoder_ops_s *decops; struct tvin_state_machine_ops_s *sm_ops; int ret = 0; - int offset; + unsigned int offset; if (!devp) return IRQ_HANDLED; @@ -1623,6 +2013,7 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) spin_lock_irqsave(&devp->isr_lock, flags); devp->vdin_reset_flag = vdin_vsync_reset_mif(devp->index); offset = devp->addr_offset; + if (devp) /* avoid null pointer oops */ stamp = vdin_get_meas_vstamp(offset); @@ -1646,12 +2037,21 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) } } + if ((devp->set_canvas_manual == 1) && check_vdin_readlist(devp)) { + devp->keystone_vframe_ready = 1; + wake_up_interruptible(&vframe_waitq); + } + if (devp->last_wr_vfe) { provider_vf_put(devp->last_wr_vfe, devp->vfp); devp->last_wr_vfe = NULL; - vf_notify_receiver(devp->name, + + if (devp->set_canvas_manual != 1) { + vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + } } + /*check vs is valid base on the time during continuous vs*/ vdin_check_cycle(devp); @@ -1680,6 +2080,7 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) vdin_set_vframe_prop_info(curr_wr_vf, devp); vdin_backup_histgram(curr_wr_vf, devp); + vdin_hist_tgt(devp, curr_wr_vf); if (devp->frontend && devp->frontend->dec_ops) { decops = devp->frontend->dec_ops; @@ -1727,6 +2128,7 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) goto irq_handled; } } + if (curr_wr_vfe) { curr_wr_vfe->flag |= VF_FLAG_NORMAL_FRAME; /* provider_vf_put(curr_wr_vfe, devp->vfp); */ @@ -1735,26 +2137,29 @@ irqreturn_t vdin_v4l2_isr(int irq, void *dev_id) /* prepare for next input data */ next_wr_vfe = provider_vf_get(devp->vfp); - if (devp->afbce_mode == 0) + if (devp->afbce_mode == 0) { vdin_set_canvas_id(devp, (devp->flags&VDIN_FLAG_RDMA_ENABLE), (next_wr_vfe->vf.canvas0Addr&0xff)); - else if (devp->afbce_mode == 1) - vdin_afbce_set_next_frame(devp, - (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe); - if ((devp->prop.dest_cfmt == TVIN_NV12) || + if ((devp->prop.dest_cfmt == TVIN_NV12) || (devp->prop.dest_cfmt == TVIN_NV21)) - vdin_set_chma_canvas_id(devp, - (devp->flags&VDIN_FLAG_RDMA_ENABLE), - (next_wr_vfe->vf.canvas0Addr>>8)&0xff); + vdin_set_chma_canvas_id(devp, + (devp->flags&VDIN_FLAG_RDMA_ENABLE), + (next_wr_vfe->vf.canvas0Addr>>8)&0xff); + } else if (devp->afbce_mode == 1) { + vdin_afbce_set_next_frame(devp, + (devp->flags&VDIN_FLAG_RDMA_ENABLE), next_wr_vfe); + } devp->curr_wr_vfe = next_wr_vfe; - vf_notify_receiver(devp->name, VFRAME_EVENT_PROVIDER_VFRAME_READY, - NULL); + + if (devp->set_canvas_manual != 1) + vf_notify_receiver(devp->name, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); irq_handled: spin_unlock_irqrestore(&devp->isr_lock, flags); -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA if (devp->flags & VDIN_FLAG_RDMA_ENABLE) rdma_config(devp->rdma_handle, (devp->rdma_enable&1) ? @@ -1813,6 +2218,9 @@ static int vdin_open(struct inode *inode, struct file *file) devp = container_of(inode->i_cdev, struct vdin_dev_s, cdev); file->private_data = devp; + if (devp->set_canvas_manual == 1) + return 0; + if (devp->index >= VDIN_MAX_DEVS) return -ENXIO; @@ -1823,6 +2231,9 @@ static int vdin_open(struct inode *inode, struct file *file) return 0; } + if ((is_meson_tl1_cpu() || is_meson_tm2_cpu())) + switch_vpu_mem_pd_vmod(VPU_AFBCE, VPU_MEM_POWER_ON); + devp->flags |= VDIN_FLAG_FS_OPENED; /* request irq */ @@ -1868,6 +2279,9 @@ static int vdin_release(struct inode *inode, struct file *file) return 0; } + if ((is_meson_tl1_cpu() || is_meson_tm2_cpu())) + switch_vpu_mem_pd_vmod(VPU_AFBCE, VPU_MEM_POWER_DOWN); + devp->flags &= (~VDIN_FLAG_FS_OPENED); if (devp->flags & VDIN_FLAG_DEC_STARTED) { devp->flags |= VDIN_FLAG_DEC_STOP_ISR; @@ -1912,9 +2326,17 @@ static int vdin_release(struct inode *inode, struct file *file) static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret = 0; + int i; int callmaster_status = 0; struct vdin_dev_s *devp = NULL; void __user *argp = (void __user *)arg; + struct vdin_parm_s param; + ulong flags; + struct vdin_hist_s vdin1_hist_temp; + struct page *page; + struct vdin_set_canvas_s vdinsetcanvas[VDIN_CANVAS_MAX_CNT]; + unsigned int idx = 0; + unsigned int recov_idx = 0; /* Get the per-device structure that contains this cdev */ devp = file->private_data; @@ -1995,11 +2417,14 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } if ((devp->parm.info.fmt == TVIN_SIG_FMT_NULL) && - (devp->parm.port == TVIN_PORT_CVBS3)) + (devp->parm.port == TVIN_PORT_CVBS3)) { + de_fmt_flag = 1; fmt = devp->parm.info.fmt = TVIN_SIG_FMT_CVBS_NTSC_M; - else + } else { + de_fmt_flag = 0; fmt = devp->parm.info.fmt = parm.info.fmt; - devp->fmt_info_p = + } + devp->fmt_info_p = (struct tvin_format_s *)tvin_get_fmt_info(fmt); if (!devp->fmt_info_p) { pr_err("TVIN_IOC_START_DEC(%d) error, fmt is null\n", @@ -2009,6 +2434,16 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; } vdin_start_dec(devp); + + if ((devp->parm.port != TVIN_PORT_VIU1) || + (viu_hw_irq != 0)) { + /*enable irq */ + enable_irq(devp->irq); + if (vdin_dbg_en) + pr_info("****[%s]enable_irq ifdef VDIN_V2****\n", + __func__); + } + devp->flags |= VDIN_FLAG_DEC_STARTED; if (vdin_dbg_en) pr_info("TVIN_IOC_START_DEC port %s, decode started ok\n\n", @@ -2018,6 +2453,7 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } case TVIN_IOC_STOP_DEC: { struct tvin_parm_s *parm = &devp->parm; + mutex_lock(&devp->fe_lock); if (!(devp->flags & VDIN_FLAG_DEC_STARTED)) { pr_err("TVIN_IOC_STOP_DEC(%d) decode havn't started\n", @@ -2040,6 +2476,7 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (vdin_dbg_en) pr_info("TVIN_IOC_STOP_DEC(%d) port %s, decode stop ok\n\n", parm->index, tvin_port_str(parm->port)); + mutex_unlock(&devp->fe_lock); reset_tvin_smr(parm->index); break; @@ -2073,6 +2510,7 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TVIN_IOC_CLOSE: { struct tvin_parm_s *parm = &devp->parm; enum tvin_port_e port = parm->port; + mutex_lock(&devp->fe_lock); if (!(devp->flags & VDIN_FLAG_DEC_OPENED)) { pr_err("TVIN_IOC_CLOSE(%d) you have not opened port\n", @@ -2090,6 +2528,7 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) pr_info("TVIN_IOC_CLOSE(%d) port %s closed ok\n\n", parm->index, tvin_port_str(port)); + mutex_unlock(&devp->fe_lock); break; } @@ -2132,6 +2571,28 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) mutex_unlock(&devp->fe_lock); break; } + case TVIN_IOC_G_FRONTEND_INFO: { + struct tvin_frontend_info_s info; + + if ((!devp) || (!devp->fmt_info_p) || (!devp->curr_wr_vfe)) { + ret = -EFAULT; + break; + } + + memset(&info, 0, sizeof(struct tvin_frontend_info_s)); + mutex_lock(&devp->fe_lock); + info.cfmt = devp->parm.info.cfmt; + info.fps = devp->parm.info.fps; + info.colordepth = devp->prop.colordepth; + info.scan_mode = devp->fmt_info_p->scan_mode; + info.height = devp->curr_wr_vfe->vf.height; + info.width = devp->curr_wr_vfe->vf.width; + if (copy_to_user(argp, &info, + sizeof(struct tvin_frontend_info_s))) + ret = -EFAULT; + mutex_unlock(&devp->fe_lock); + break; + } case TVIN_IOC_G_BUF_INFO: { struct tvin_buf_info_s buf_info; memset(&buf_info, 0, sizeof(buf_info)); @@ -2285,6 +2746,207 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) devp->auto_ratio_en); } break; + case TVIN_IOC_GET_LATENCY_MODE: + mutex_unlock(&devp->fe_lock); + if (copy_to_user(argp, + &(devp->prop.latency), + sizeof(struct tvin_latency_s))) { + mutex_unlock(&devp->fe_lock); + ret = -EFAULT; + pr_info("TVIN_IOC_GET_ALLM_MODE err\n\n"); + break; + } + pr_info("allm mode-%d,IT=%d,CN=%d\n\n", + devp->prop.latency.allm_mode, + devp->prop.latency.it_content, + devp->prop.latency.cn_type); + mutex_unlock(&devp->fe_lock); + break; + case TVIN_IOC_G_VDIN_HIST: + if (devp->index == 0) { + pr_info("TVIN_IOC_G_VDIN_HIST cann't be used at vdin0\n"); + break; + } + + spin_lock_irqsave(&devp->hist_lock, flags); + vdin1_hist_temp.sum = vdin1_hist.sum; + vdin1_hist_temp.width = vdin1_hist.width; + vdin1_hist_temp.height = vdin1_hist.height; + vdin1_hist_temp.ave = vdin1_hist.ave; + spin_unlock_irqrestore(&devp->hist_lock, flags); + if (vdin_dbg_en) { + if (pr_times++ > 10) { + pr_times = 0; + pr_info("-:h=%d,w=%d,a=%d\n", + vdin1_hist_temp.height, + vdin1_hist_temp.width, + vdin1_hist_temp.ave); + } + } + + if ((vdin1_hist.height == 0) || (vdin1_hist.width == 0)) + ret = -EFAULT; + else if (copy_to_user(argp, + &vdin1_hist_temp, + sizeof(struct vdin_hist_s))) { + pr_info("vdin1_hist copy fail\n"); + ret = -EFAULT; + } + break; + case TVIN_IOC_S_VDIN_V4L2START: + if (devp->index == 0) { + pr_info("TVIN_IOC_S_VDIN_V4L2START cann't be used at vdin0\n"); + break; + } + if (devp->flags & VDIN_FLAG_ISR_REQ) + free_irq(devp->irq, (void *)devp); + + if (copy_from_user(&vdin_v4l2_param, argp, + sizeof(struct vdin_v4l2_param_s))) { + pr_info("vdin_v4l2_param copy fail\n"); + return -EFAULT; + } + memset(¶m, 0, sizeof(struct vdin_parm_s)); + if (is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) + param.port = TVIN_PORT_VIU1_WB0_VPP; + else + param.port = TVIN_PORT_VIU1; + + param.h_active = vdin_v4l2_param.width; + param.v_active = vdin_v4l2_param.height; + + if (devp->set_canvas_manual != 1) { + param.reserved |= PARAM_STATE_HISTGRAM; + /* use 1280X720 for histgram*/ + if ((vdin_v4l2_param.width > 1280) && + (vdin_v4l2_param.height > 720)) { + devp->debug.scaler4w = 1280; + devp->debug.scaler4h = 720; + devp->debug.dest_cfmt = TVIN_YUV422; + devp->flags |= VDIN_FLAG_MANUAL_CONVERSION; + } + } + + param.frame_rate = vdin_v4l2_param.fps; + param.cfmt = TVIN_YUV422; + + if (devp->set_canvas_manual == 1) + param.dfmt = TVIN_RGB444; + else + param.dfmt = TVIN_YUV422; + + param.scan_mode = TVIN_SCAN_MODE_PROGRESSIVE; + param.fmt = TVIN_SIG_FMT_MAX; + //devp->flags |= VDIN_FLAG_V4L2_DEBUG; + devp->hist_bar_enable = 1; + start_tvin_service(devp->index, ¶m); + break; + + case TVIN_IOC_S_VDIN_V4L2STOP: + if (devp->index == 0) { + pr_info("TVIN_IOC_S_VDIN_V4L2STOP cann't be used at vdin0\n"); + break; + } + devp->parm.reserved &= ~PARAM_STATE_HISTGRAM; + devp->flags &= (~VDIN_FLAG_ISR_REQ); + devp->flags &= (~VDIN_FLAG_FS_OPENED); + stop_tvin_service(devp->index); + + /*release manual set dma-bufs*/ + if (devp->set_canvas_manual == 1) { + for (i = 0; i < 4; i++) { + if (vdin_set_canvas_addr[i].dmabuff == 0) + continue; + + dma_buf_unmap_attachment( + vdin_set_canvas_addr[i].dmabufattach, + vdin_set_canvas_addr[i].sgtable, + DMA_BIDIRECTIONAL); + dma_buf_detach( + vdin_set_canvas_addr[i].dmabuff, + vdin_set_canvas_addr[i].dmabufattach); + dma_buf_put(vdin_set_canvas_addr[i].dmabuff); + devp->keystone_entry[i] = NULL; + } + memset(vdin_set_canvas_addr, 0, + sizeof(struct vdin_set_canvas_addr_s) * + VDIN_CANVAS_MAX_CNT); + } + break; + + case TVIN_IOC_S_CANVAS_ADDR: + if (devp->index == 0) { + pr_info("TVIN_IOC_S_CANVAS_ADDR can't be used at vdin0\n"); + break; + } + + if (copy_from_user(vdinsetcanvas, argp, + sizeof(struct vdin_set_canvas_s) * 4)) { + pr_info("TVIN_IOC_S_CANVAS_ADDR copy fail\n"); + return -EFAULT; + } + + for (i = 0; i < 4; i++) { + /*when fd means, the canvas list reaches end*/ + if (vdinsetcanvas[i].fd < 0) + break; + + if (vdinsetcanvas[i].index >= VDIN_CANVAS_MAX_CNT) { + pr_err("vdin buf idx range (0 ~ %d), current idx is too big.\n ", + VDIN_CANVAS_MAX_CNT - 1); + continue; + } + + idx = vdinsetcanvas[i].index; + + vdin_set_canvas_addr[idx].dmabuff = + dma_buf_get(vdinsetcanvas[i].fd); + + vdin_set_canvas_addr[idx].dmabufattach = + dma_buf_attach( + vdin_set_canvas_addr[idx].dmabuff, + devp->dev); + vdin_set_canvas_addr[idx].sgtable = + dma_buf_map_attachment( + vdin_set_canvas_addr[idx].dmabufattach, + DMA_BIDIRECTIONAL); + + page = sg_page(vdin_set_canvas_addr[idx].sgtable->sgl); + vdin_set_canvas_addr[idx].paddr = + PFN_PHYS(page_to_pfn(page)); + vdin_set_canvas_addr[idx].size = + vdin_set_canvas_addr[idx].dmabuff->size; + + pr_info("TVIN_IOC_S_CANVAS_ADDR[%d] addr=0x%lx, len=0x%x.\n", + i, + vdin_set_canvas_addr[idx].paddr, + vdin_set_canvas_addr[idx].size); + + __close_fd(current->files, vdinsetcanvas[i].fd); + } + break; + + case TVIN_IOC_S_CANVAS_RECOVERY: + if (devp->index == 0) { + pr_info("TVIN_IOC_S_CANVAS_RECOVERY can't be used at vdin0\n"); + break; + } + + if (copy_from_user(&recov_idx, argp, sizeof(unsigned int))) { + pr_info("TVIN_IOC_S_CANVAS_RECOVERY copy fail\n"); + return -EFAULT; + } + + if (devp->keystone_entry[recov_idx]) { + receiver_vf_put(&devp->keystone_entry[recov_idx]->vf, + devp->vfp); + devp->keystone_entry[recov_idx] = NULL; + } else + pr_err("[vdin.%d] idx %d RECOVERY error\n", + devp->index, recov_idx); + break; + default: ret = -ENOIOCTLCMD; /* pr_info("%s %d is not supported command\n", __func__, cmd); */ @@ -2346,22 +3008,57 @@ static unsigned int vdin_poll(struct file *file, poll_table *wait) struct vdin_dev_s *devp = file->private_data; unsigned int mask = 0; - poll_wait(file, &devp->queue, wait); - mask = (POLLIN | POLLRDNORM); + if (devp->set_canvas_manual == 1) { + poll_wait(file, &vframe_waitq, wait); + + if (devp->keystone_vframe_ready == 1) + mask = (POLLIN | POLLRDNORM); + } else { + poll_wait(file, &devp->queue, wait); + mask = (POLLIN | POLLRDNORM); + } return mask; } +static ssize_t vdin_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + int index; + long ret; + struct vf_entry *vfe; + struct vdin_dev_s *devp = file->private_data; + + vfe = receiver_vf_peek(devp->vfp); + if (!vfe) + return 0; + + vfe = receiver_vf_get(devp->vfp); + /*index = report_canvas_index;*/ + index = vfe->vf.index; + devp->keystone_entry[index] = vfe; + ret = copy_to_user(buf, (void *)(&index), sizeof(int)); + if (ret) { + pr_info("vdin_read copy_to_user error\n"); + return -1; + } + + devp->keystone_vframe_ready = 0; + + return sizeof(int); +} + static const struct file_operations vdin_fops = { - .owner = THIS_MODULE, - .open = vdin_open, - .release = vdin_release, - .unlocked_ioctl = vdin_ioctl, + .owner = THIS_MODULE, + .open = vdin_open, + .read = vdin_read, + .release = vdin_release, + .unlocked_ioctl = vdin_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = vdin_compat_ioctl, #endif - .mmap = vdin_mmap, - .poll = vdin_poll, + .mmap = vdin_mmap, + .poll = vdin_poll, }; @@ -2423,9 +3120,10 @@ static int vdin_drv_probe(struct platform_device *pdev) } } vdin_devp[vdevp->index] = vdevp; -#ifdef CONFIG_AML_RDMA - vdin_rdma_op.arg = vdin_devp; - vdevp->rdma_handle = rdma_register(&vdin_rdma_op, +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + vdin_rdma_op[vdevp->index].irq_cb = vdin_rdma_irq; + vdin_rdma_op[vdevp->index].arg = vdevp; + vdevp->rdma_handle = rdma_register(&vdin_rdma_op[vdevp->index], NULL, RDMA_TABLE_SIZE); pr_info("%s:vdin.%d rdma hanld %d.\n", __func__, vdevp->index, vdevp->rdma_handle); @@ -2528,25 +3226,36 @@ static int vdin_drv_probe(struct platform_device *pdev) else vdevp->color_depth_mode = 0; - /*set afbce mode*/ - ret = of_property_read_u32(pdev->dev.of_node, - "afbce_bit_mode", &vdevp->afbce_mode); - if (ret) { - vdevp->afbce_mode = 0; - pr_info("no afbce mode found, use normal mode\n"); - } else { - if ((is_meson_tl1_cpu()) && (vdevp->index == 0)) { - /* just use afbce at vdin0 */ - pr_info("afbce mode = %d\n", vdevp->afbce_mode); + /*set afbce config*/ + vdevp->afbce_flag = 0; + if (vdevp->index == 0) { /* just use afbce at vdin0 */ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { vdevp->afbce_info = devm_kzalloc(vdevp->dev, sizeof(struct vdin_afbce_s), GFP_KERNEL); if (!vdevp->afbce_info) goto fail_kzalloc_vdev; - } else { - vdevp->afbce_mode = 0; - pr_info("get afbce from dts, but chip cannot support\n"); + + ret = of_property_read_u32(pdev->dev.of_node, + "afbce_bit_mode", &vdevp->afbce_flag); + if (ret) { + vdevp->afbce_flag = 0; + } else { + pr_info("afbce flag = 0x%x\n", + vdevp->afbce_flag); + } } } + + ret = of_property_read_u32(pdev->dev.of_node, + "set_canvas_manual", &vdevp->set_canvas_manual); + + if (ret) { + vdevp->set_canvas_manual = 0; + pr_info("set_canvas_manual = 0\n"); + } else { + pr_info("set_canvas_manual = %d\n", vdevp->set_canvas_manual); + } + /*vdin urgent en*/ ret = of_property_read_u32(pdev->dev.of_node, "urgent_en", &urgent_en); @@ -2560,18 +3269,18 @@ static int vdin_drv_probe(struct platform_device *pdev) vdevp->flags &= (~VDIN_FLAG_FS_OPENED); mutex_init(&vdevp->fe_lock); spin_lock_init(&vdevp->isr_lock); + spin_lock_init(&vdevp->hist_lock); vdevp->frontend = NULL; /* @todo vdin_addr_offset */ if (is_meson_gxbb_cpu() && vdevp->index) vdin_addr_offset[vdevp->index] = 0x70; - else if ((is_meson_g12a_cpu() || is_meson_g12b_cpu() || - is_meson_tl1_cpu()) && vdevp->index) + else if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && vdevp->index) vdin_addr_offset[vdevp->index] = 0x100; vdevp->addr_offset = vdin_addr_offset[vdevp->index]; vdevp->flags = 0; /*canvas align number*/ - if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_tl1_cpu()) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) vdevp->canvas_align = 64; else vdevp->canvas_align = 32; @@ -2675,6 +3384,7 @@ static int vdin_drv_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&vdevp->dv.dv_dwork, vdin_dv_dwork); INIT_DELAYED_WORK(&vdevp->vlock_dwork, vdin_vlock_dwork); + vdin_mif_config_init(vdevp); /* 2019-0425 add, ensure mif/afbc bit */ vdin_debugfs_init(vdevp);/*2018-07-18 add debugfs*/ pr_info("%s: driver initialized ok\n", __func__); return 0; @@ -2705,7 +3415,7 @@ static int vdin_drv_remove(struct platform_device *pdev) vdevp = platform_get_drvdata(pdev); ret = cancel_delayed_work(&vdevp->vlock_dwork); -#ifdef CONFIG_AML_RDMA +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA rdma_unregister(vdevp->rdma_handle); #endif mutex_destroy(&vdevp->fe_lock); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h index 43e719e..1c2b04f 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h @@ -36,8 +36,8 @@ #include #include #include -#ifdef CONFIG_AML_RDMA -#include +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +#include #endif /* Local Headers */ @@ -45,7 +45,10 @@ #include "vdin_vf.h" #include "vdin_regs.h" -#define VDIN_VER "Ref.2018/11/07a" +/* Ref.2019/04/25: tl1 vdin0 afbce dynamically switch support, + * vpp also should support this function + */ +#define VDIN_VER "Ref.2019/04/25" /*the counter of vdin*/ #define VDIN_MAX_DEVS 2 @@ -85,6 +88,12 @@ #define VDIN_BYPASS_VGA_CHECK 0x00000008 #define VDIN_CANVAS_MAX_CNT 9 +/*values of vdin game mode process flag */ +#define VDIN_GAME_MODE_0 (1 << 0) +#define VDIN_GAME_MODE_1 (1 << 1) +#define VDIN_GAME_MODE_2 (1 << 2) +#define VDIN_GAME_MODE_SWITCH_EN (1 << 3) + /*flag for flush vdin buff*/ #define VDIN_FLAG_BLACK_SCREEN_ON 1 #define VDIN_FLAG_BLACK_SCREEN_OFF 0 @@ -100,6 +109,13 @@ /*TXL new add*/ #define VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE (1 << 4) +/* vdin afbce flag */ +#define VDIN_AFBCE_EN (1 << 0) +#define VDIN_AFBCE_EN_LOOSY (1 << 1) +#define VDIN_AFBCE_EN_4K (1 << 4) +#define VDIN_AFBCE_EN_1080P (1 << 5) +#define VDIN_AFBCE_EN_720P (1 << 6) +#define VDIN_AFBCE_EN_SMALL (1 << 7) static inline const char *vdin_fmt_convert_str( enum vdin_format_convert_e fmt_cvt) @@ -141,6 +157,21 @@ static inline const char *vdin_fmt_convert_str( } } +struct vdin_set_canvas_s { + int fd; + int index; +}; + +struct vdin_set_canvas_addr_s { + long paddr; + int size; + + struct dma_buf *dmabuff; + struct dma_buf_attachment *dmabufattach; + struct sg_table *sgtable; +}; +extern struct vdin_set_canvas_addr_s vdin_set_canvas_addr[VDIN_CANVAS_MAX_CNT]; + /*******for debug **********/ struct vdin_debug_s { struct tvin_cutwin_s cutwin; @@ -160,6 +191,7 @@ struct vdin_dv_s { bool dv_flag; bool dv_config; bool dv_crc_check;/*0:fail;1:ok*/ + unsigned int dv_mem_alloced; }; struct vdin_afbce_s { @@ -199,6 +231,7 @@ struct vdin_dev_s { struct timer_list timer; spinlock_t isr_lock; + spinlock_t hist_lock; struct mutex fe_lock; struct clk *msr_clk; unsigned int msr_clk_val; @@ -312,6 +345,8 @@ struct vdin_dev_s { *game_mode: *bit0:enable/disable *bit1:for true bypas and put vframe in advance one vsync + *bit2:for true bypas and put vframe in advance two vsync, + *vdin & vpp read/write same buffer may happen */ unsigned int game_mode; unsigned int rdma_enable; @@ -320,25 +355,62 @@ struct vdin_dev_s { * 1: use afbce non-mmu mode: head/body addr set by code * 2: use afbce mmu mode: head set by code, body addr assigning by hw */ + /*afbce_flag: + *bit[0]: enable afbce + *bit[1]: enable afbce_loosy + *bit[4]: afbce enable for 4k + *bit[5]: afbce enable for 1080p + *bit[6]: afbce enable for 720p + *bit[7]: afbce enable for other small resolution + */ + unsigned int afbce_flag; + unsigned int afbce_mode_pre; unsigned int afbce_mode; + unsigned int afbce_valid; + + /*fot 'T correction' on projector*/ + unsigned int set_canvas_manual; + unsigned int keystone_vframe_ready; + struct vf_entry *keystone_entry[VDIN_CANVAS_MAX_CNT]; unsigned int canvas_config_mode; bool prehsc_en; bool vshrk_en; bool urgent_en; bool black_bar_enable; bool hist_bar_enable; + unsigned int ignore_frames; + unsigned int recycle_frames; /*use frame rate to cal duraton*/ unsigned int use_frame_rate; unsigned int irq_cnt; + unsigned int frame_cnt; unsigned int rdma_irq_cnt; unsigned int vdin_irq_flag; unsigned int vdin_reset_flag; unsigned int vdin_dev_ssize; wait_queue_head_t queue; - struct dentry *dbg_root; /*dbg_fs*/ }; +struct vdin_hist_s { + ulong sum; + int width; + int height; + int ave; +}; + +struct vdin_v4l2_param_s { + int width; + int height; + int fps; +}; + +extern unsigned int max_recycle_frame_cnt; +extern unsigned int max_ignore_frame_cnt; +extern unsigned int skip_frame_debug; + +extern unsigned int vdin0_afbce_debug_force; + extern struct vframe_provider_s *vf_get_provider_by_name( const char *provider_name); extern bool enable_reset; @@ -367,8 +439,6 @@ extern void ldim_get_matrix(int *data, int reg_sel); extern void ldim_set_matrix(int *data, int reg_sel); extern void tvafe_snow_config(unsigned int onoff); extern void tvafe_snow_config_clamp(unsigned int onoff); -extern void tvafe_snow_config_acd(void); -extern void tvafe_snow_config_acd_resume(void); extern void vdin_vf_reg(struct vdin_dev_s *devp); extern void vdin_vf_unreg(struct vdin_dev_s *devp); extern void vdin_pause_dec(struct vdin_dev_s *devp); @@ -378,5 +448,10 @@ extern bool is_dolby_vision_enable(void); extern void vdin_debugfs_init(struct vdin_dev_s *vdevp); extern void vdin_debugfs_exit(struct vdin_dev_s *vdevp); +extern bool vlock_get_phlock_flag(void); + +extern struct vdin_dev_s *vdin_get_dev(unsigned int index); +extern void vdin_mif_config_init(struct vdin_dev_s *devp); + #endif /* __TVIN_VDIN_DRV_H */ diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c index 252a3ab..1ac4fbe 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c @@ -92,9 +92,11 @@ static int atv_stable_fmt_check_enable; static int atv_prestable_out_cnt = 100; static int other_stable_out_cnt = EXIT_STABLE_MAX_CNT; static int other_unstable_out_cnt = BACK_STABLE_MAX_CNT; +static int manual_unstable_out_cnt = 30; static int other_unstable_in_cnt = UNSTABLE_MAX_CNT; static int nosig_in_cnt = NOSIG_MAX_CNT; static int nosig2_unstable_cnt = EXIT_NOSIG_MAX_CNT; +bool manual_flag; #ifdef DEBUG_SUPPORT module_param(back_nosig_max_cnt, int, 0664); @@ -332,11 +334,8 @@ void tvin_smr(struct vdin_dev_s *devp) ++sm_p->state_cnt; #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AFE if ((port == TVIN_PORT_CVBS3) && - (devp->flags & VDIN_FLAG_SNOW_FLAG)) { + (devp->flags & VDIN_FLAG_SNOW_FLAG)) tvafe_snow_config_clamp(1); - /*fix black side when config atv snow*/ - tvafe_snow_config_acd(); - } #endif if (sm_ops->nosig(devp->frontend)) { sm_p->exit_nosig_cnt = 0; @@ -411,6 +410,9 @@ void tvin_smr(struct vdin_dev_s *devp) (port == TVIN_PORT_CVBS0)) && (devp->flags & VDIN_FLAG_SNOW_FLAG)) unstb_in = sm_p->atv_unstable_out_cnt; + else if ((port == TVIN_PORT_CVBS3) && + manual_flag) + unstb_in = manual_unstable_out_cnt; else if ((port >= TVIN_PORT_HDMI0) && (port <= TVIN_PORT_HDMI7)) unstb_in = sm_p->hdmi_unstable_out_cnt; @@ -475,11 +477,8 @@ void tvin_smr(struct vdin_dev_s *devp) devp->unstable_flag = true; #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_AFE if ((port == TVIN_PORT_CVBS3) && - (devp->flags & VDIN_FLAG_SNOW_FLAG)) { + (devp->flags & VDIN_FLAG_SNOW_FLAG)) tvafe_snow_config_clamp(0); - /*fix black side when config atv snow*/ - tvafe_snow_config_acd_resume(); - } #endif if (sm_ops->nosig(devp->frontend)) { nosig = true; diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h index b300911..92fdd32 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h @@ -49,6 +49,9 @@ struct tvin_sm_s { int atv_stable_out_cnt; int hdmi_unstable_out_cnt; }; + +extern bool manual_flag; + void tvin_smr(struct vdin_dev_s *pdev); void tvin_smr_init(int index); void reset_tvin_smr(unsigned int index); diff --git a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c index afd3446..886ec35 100644 --- a/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c +++ b/drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c @@ -1018,9 +1018,11 @@ void vdin_vf_disp_mode_update(struct vf_entry *vfe, struct vf_pool *p) p->disp_index[0] = 0; vfe->vf.index_disp = p->disp_index[0]; - p->disp_mode[p->disp_index[p->skip_vf_num]] = VFRAME_DISP_MODE_OK; - for (i = p->skip_vf_num - 1; i < VFRAME_DISP_MAX_NUM; i--) - p->disp_mode[p->disp_index[i]] = VFRAME_DISP_MODE_UNKNOWN; + if (p->disp_mode[p->disp_index[p->skip_vf_num]] != + VFRAME_DISP_MODE_SKIP) + p->disp_mode[p->disp_index[p->skip_vf_num]] = + VFRAME_DISP_MODE_OK; + p->disp_mode[p->disp_index[0]] = VFRAME_DISP_MODE_UNKNOWN; } /*disp mode skip *skip_vf_num diff --git a/drivers/amlogic/media/vin/tvin/viu/viuin.c b/drivers/amlogic/media/vin/tvin/viu/viuin.c index 3fe16a6..c79f379 100644 --- a/drivers/amlogic/media/vin/tvin/viu/viuin.c +++ b/drivers/amlogic/media/vin/tvin/viu/viuin.c @@ -165,6 +165,9 @@ void viuin_check_venc_line(struct viuin_s *devp_local) pr_info("**************%s,vencv_line_cur:%d,cnt:%d***********\n", __func__, vencv_line_cur, cnt); } + +/*g12a/g12b and before: use viu_loop encl/encp*/ +/*tl1: use viu_loop vpp */ static int viuin_open(struct tvin_frontend_s *fe, enum tvin_port_e port) { struct viuin_s *devp = container_of(fe, struct viuin_s, frontend); @@ -178,8 +181,9 @@ static int viuin_open(struct tvin_frontend_s *fe, enum tvin_port_e port) /*open the venc to vdin path*/ switch (rd_bits_viu(VPU_VIU_VENC_MUX_CTRL, 0, 2)) { case 0: - if (is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu()) + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) viu_mux = 0x4; else viu_mux = 0x8; @@ -213,7 +217,7 @@ static int viuin_open(struct tvin_frontend_s *fe, enum tvin_port_e port) wr_viu(VPU_VIU2VDIN_HDN_CTRL, 0x40f00); } else wr_bits_viu(VPU_VIU2VDIN_HDN_CTRL, devp->parm.h_active, 0, 14); - if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || is_meson_tl1_cpu()) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { if (((port >= TVIN_PORT_VIU1_WB0_VD1) && (port <= TVIN_PORT_VIU1_WB0_POST_BLEND)) || ((port >= TVIN_PORT_VIU2_WB0_VD1) && @@ -256,8 +260,14 @@ static int viuin_open(struct tvin_frontend_s *fe, enum tvin_port_e port) else if ((port == TVIN_PORT_VIU1_WB0_POST_BLEND) || (port == TVIN_PORT_VIU2_WB0_POST_BLEND)) wr_bits_viu(VPP_WRBAK_CTRL, 5, 0, 3); - else + else if ((port == TVIN_PORT_VIU1_WB0_VPP) || + (port == TVIN_PORT_VIU2_WB0_VPP)) { + wr_bits_viu(VPP_WRBAK_CTRL, 6, 0, 3); + /*increase h banking in case vdin afifo overflow*/ + wr_bits_viu(VPP_WRBAK_CTRL, 0xff, 16, 8); + } else wr_bits_viu(VPP_WRBAK_CTRL, 0, 4, 3); + if ((port == TVIN_PORT_VIU1_WB1_VD1) || (port == TVIN_PORT_VIU2_WB1_VD1)) wr_bits_viu(VPP_WRBAK_CTRL, 1, 4, 3); @@ -273,8 +283,12 @@ static int viuin_open(struct tvin_frontend_s *fe, enum tvin_port_e port) else if ((port == TVIN_PORT_VIU1_WB1_POST_BLEND) || (port == TVIN_PORT_VIU2_WB1_POST_BLEND)) wr_bits_viu(VPP_WRBAK_CTRL, 5, 4, 3); + else if ((port == TVIN_PORT_VIU1_WB1_VPP) || + (port == TVIN_PORT_VIU2_WB1_VPP)) + wr_bits_viu(VPP_WRBAK_CTRL, 6, 4, 3); else wr_bits_viu(VPP_WRBAK_CTRL, 0, 4, 3); + /*wrback hsync en*/ if (((port >= TVIN_PORT_VIU1_WB0_VD1) && (port <= TVIN_PORT_VIU1_WB0_POST_BLEND)) || @@ -308,8 +322,9 @@ static void viuin_close(struct tvin_frontend_s *fe) if (open_cnt) open_cnt--; if (open_cnt == 0) { - if (is_meson_g12a_cpu() || is_meson_g12b_cpu() - || is_meson_tl1_cpu()) { + if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || + is_meson_tl1_cpu() || is_meson_sm1_cpu() || + is_meson_tm2_cpu()) { wr_viu(VPU_VIU_VDIN_IF_MUX_CTRL, 0); wr_viu(VPP_WRBAK_CTRL, 0); @@ -384,14 +399,27 @@ static void viuin_sig_property(struct tvin_frontend_s *fe, static const struct vinfo_s *vinfo; struct viuin_s *devp = container_of(fe, struct viuin_s, frontend); - if (devp->parm.port == TVIN_PORT_VIU1_VIDEO) + switch (devp->parm.port) { + case TVIN_PORT_VIU1_VIDEO: + case TVIN_PORT_VIU1_WB0_POST_BLEND: prop->color_format = TVIN_YUV444; - else if ((devp->parm.port == TVIN_PORT_VIU1) || - (devp->parm.port == TVIN_PORT_VIU2)) { + break; + + case TVIN_PORT_VIU1: + case TVIN_PORT_VIU2: + case TVIN_PORT_VIU1_WB0_VPP: + case TVIN_PORT_VIU1_WB1_VPP: + case TVIN_PORT_VIU2_WB0_VPP: + case TVIN_PORT_VIU2_WB1_VPP: vinfo = get_current_vinfo(); prop->color_format = vinfo->viu_color_fmt; - } else + break; + + default: prop->color_format = devp->parm.cfmt; + break; + } + prop->dest_cfmt = devp->parm.dfmt; prop->scaling4w = devp->parm.dest_hactive; diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out.c b/drivers/amlogic/media/vout/cvbs/cvbs_out.c index 9d0c118..23c1454 100644 --- a/drivers/amlogic/media/vout/cvbs/cvbs_out.c +++ b/drivers/amlogic/media/vout/cvbs/cvbs_out.c @@ -1479,6 +1479,12 @@ struct meson_cvbsout_data meson_sm1_cvbsout_data = { .name = "meson-sm1-cvbsout", }; +struct meson_cvbsout_data meson_tm2_cvbsout_data = { + .cntl0_val = 0x906001, + .cpu_id = CVBS_CPU_TYPE_TM2, + .name = "meson-tm2-cvbsout", +}; + static const struct of_device_id meson_cvbsout_dt_match[] = { { .compatible = "amlogic, cvbsout-gxl", @@ -1501,6 +1507,9 @@ static const struct of_device_id meson_cvbsout_dt_match[] = { }, { .compatible = "amlogic, cvbsout-sm1", .data = &meson_sm1_cvbsout_data, + }, { + .compatible = "amlogic, cvbsout-tm2", + .data = &meson_tm2_cvbsout_data, }, {}, }; diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out.h b/drivers/amlogic/media/vout/cvbs/cvbs_out.h index 05f6961..3016b70 100644 --- a/drivers/amlogic/media/vout/cvbs/cvbs_out.h +++ b/drivers/amlogic/media/vout/cvbs/cvbs_out.h @@ -53,6 +53,7 @@ enum cvbs_cpu_type { CVBS_CPU_TYPE_G12B = 5, CVBS_CPU_TYPE_TL1 = 6, CVBS_CPU_TYPE_SM1 = 7, + CVBS_CPU_TYPE_TM2 = 8, }; struct meson_cvbsout_data { diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h b/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h index be66ef4..268d7dc 100644 --- a/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h +++ b/drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h @@ -126,6 +126,13 @@ /*G12A*/ #define HHI_HDMI_PLL_CNTL7 0xce +/* TL1 */ +#define HHI_TCON_PLL_CNTL0 0x020 +#define HHI_TCON_PLL_CNTL1 0x021 +#define HHI_TCON_PLL_CNTL2 0x022 +#define HHI_TCON_PLL_CNTL3 0x023 +#define HHI_TCON_PLL_CNTL4 0x0df + #define HHI_GP0_PLL_CNTL0 0x10 #define HHI_GP0_PLL_CNTL1 0x11 #define HHI_GP0_PLL_CNTL2 0x12 diff --git a/drivers/amlogic/media/vout/cvbs/enc_clk_config.c b/drivers/amlogic/media/vout/cvbs/enc_clk_config.c index 379e19b..1f1a029 100644 --- a/drivers/amlogic/media/vout/cvbs/enc_clk_config.c +++ b/drivers/amlogic/media/vout/cvbs/enc_clk_config.c @@ -214,6 +214,28 @@ void set_vmode_clk(void) } if (ret) pr_info("[error]:hdmi_pll lock failed\n"); + } else if (cvbs_cpu_type() == CVBS_CPU_TYPE_TL1 || + cvbs_cpu_type() == CVBS_CPU_TYPE_TM2) { + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x202f04f7); + udelay(100); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x302f04f7); + udelay(100); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL1, 0x10110000); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL2, 0x00001108); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL3, 0x10051400); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL4, 0x010100c0); + udelay(100); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL4, 0x038300c0); + udelay(100); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x342f04f7); + udelay(100); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL0, 0x142f04f7); + udelay(100); + cvbs_out_hiu_write(HHI_TCON_PLL_CNTL2, 0x00003008); + udelay(100); + ret = pll_wait_lock(HHI_TCON_PLL_CNTL0, 31); + if (ret) + pr_info("[error]:tl1 tcon_pll lock failed\n"); } else { pr_info("config eqafter gxl hdmi pll\n"); cvbs_out_hiu_write(HHI_HDMI_PLL_CNTL, 0x4000027b); @@ -236,6 +258,12 @@ void set_vmode_clk(void) cvbs_set_vid1_clk(cvbs_clk_path & 0x1); else cvbs_set_vid2_clk(cvbs_clk_path & 0x1); + } else if (cvbs_cpu_type() == CVBS_CPU_TYPE_TL1 || + cvbs_cpu_type() == CVBS_CPU_TYPE_TM2) { + if (cvbs_clk_path & 0x2) + cvbs_set_vid1_clk(0); + else + cvbs_set_vid2_clk(0); } else { cvbs_set_vid2_clk(0); } diff --git a/drivers/amlogic/media/vout/vdac/vdac_dev.c b/drivers/amlogic/media/vout/vdac/vdac_dev.c index 361e7de..7e925f4 100644 --- a/drivers/amlogic/media/vout/vdac/vdac_dev.c +++ b/drivers/amlogic/media/vout/vdac/vdac_dev.c @@ -443,14 +443,16 @@ void vdac_enable(bool on, unsigned int module_sel) break; vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE); vdac_out_cntl0_bit10(1, VDAC_MODULE_TVAFE); - if (s_vdac_data->cpu_id == VDAC_CPU_TL1) { + if (s_vdac_data->cpu_id == VDAC_CPU_TL1 || + s_vdac_data->cpu_id == VDAC_CPU_TM2) { /*[6][8]bypass buffer enable*/ vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 6, 1); vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 8, 1); } } else { ana_ref_cntl0_bit9(0, VDAC_MODULE_TVAFE); - if (s_vdac_data->cpu_id == VDAC_CPU_TL1) { + if (s_vdac_data->cpu_id == VDAC_CPU_TL1 || + s_vdac_data->cpu_id == VDAC_CPU_TM2) { /*[6][8]bypass buffer disable*/ vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 6, 1); vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 8, 1); @@ -594,6 +596,11 @@ struct meson_vdac_data meson_sm1_vdac_data = { .name = "meson-sm1-vdac", }; +struct meson_vdac_data meson_tm2_vdac_data = { + .cpu_id = VDAC_CPU_TM2, + .name = "meson-tm2-vdac", +}; + static const struct of_device_id meson_vdac_dt_match[] = { { .compatible = "amlogic, vdac-gxtvbb", @@ -628,6 +635,9 @@ static const struct of_device_id meson_vdac_dt_match[] = { }, { .compatible = "amlogic, vdac-sm1", .data = &meson_sm1_vdac_data, + }, { + .compatible = "amlogic, vdac-tm2", + .data = &meson_tm2_vdac_data, }, {}, }; @@ -712,12 +722,19 @@ static int amvdac_drv_suspend(struct platform_device *pdev, if (s_vdac_data->cpu_id == VDAC_CPU_TXL || s_vdac_data->cpu_id == VDAC_CPU_TXLX) vdac_hiu_reg_write(HHI_VDAC_CNTL0, 0); + else if (s_vdac_data->cpu_id == VDAC_CPU_TL1 || + s_vdac_data->cpu_id == VDAC_CPU_TM2) + vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 7, 1); pr_info("%s: suspend module\n", __func__); return 0; } static int amvdac_drv_resume(struct platform_device *pdev) { + /*0xbc[7] for bandgap enable: 0:enable,1:disable*/ + if (s_vdac_data->cpu_id == VDAC_CPU_TL1 || + s_vdac_data->cpu_id == VDAC_CPU_TM2) + vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 7, 1); pr_info("%s: resume module\n", __func__); return 0; } diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h index 59e88fe..50b0f95 100644 --- a/include/linux/amlogic/media/amvecm/amvecm.h +++ b/include/linux/amlogic/media/amvecm/amvecm.h @@ -292,6 +292,29 @@ enum ve_pq_timing_e { TIMING_MAX, }; +enum vlock_hw_ver_e { + /*gxtvbb*/ + vlock_hw_org, + /* + *txl + *txlx + */ + vlock_hw_ver1, + /* tl1 later + * fix bug:i problem + * fix bug:affect ss function + * add: phase lock + */ + vlock_hw_ver2, +}; + +struct vecm_match_data_s { + u32 vlk_support; + u32 vlk_new_fsm; + enum vlock_hw_ver_e vlk_hwver; + u32 vlk_phlock_en; +}; + /*overscan: *length 0~31bit :number of crop; *src_timing: bit31: on: load/save all crop diff --git a/include/linux/amlogic/media/frame_provider/tvin/tvin.h b/include/linux/amlogic/media/frame_provider/tvin/tvin.h index 181796f..508585ac 100644 --- a/include/linux/amlogic/media/frame_provider/tvin/tvin.h +++ b/include/linux/amlogic/media/frame_provider/tvin/tvin.h @@ -64,11 +64,13 @@ enum tvin_port_e { TVIN_PORT_VIU1_WB0_VD2, TVIN_PORT_VIU1_WB0_OSD1, TVIN_PORT_VIU1_WB0_OSD2, + TVIN_PORT_VIU1_WB0_VPP, TVIN_PORT_VIU1_WB0_POST_BLEND, TVIN_PORT_VIU1_WB1_VD1, TVIN_PORT_VIU1_WB1_VD2, TVIN_PORT_VIU1_WB1_OSD1, TVIN_PORT_VIU1_WB1_OSD2, + TVIN_PORT_VIU1_WB1_VPP, TVIN_PORT_VIU1_WB1_POST_BLEND, TVIN_PORT_VIU2 = 0x0000C000, TVIN_PORT_VIU2_VIDEO, @@ -76,11 +78,13 @@ enum tvin_port_e { TVIN_PORT_VIU2_WB0_VD2, TVIN_PORT_VIU2_WB0_OSD1, TVIN_PORT_VIU2_WB0_OSD2, + TVIN_PORT_VIU2_WB0_VPP, TVIN_PORT_VIU2_WB0_POST_BLEND, TVIN_PORT_VIU2_WB1_VD1, TVIN_PORT_VIU2_WB1_VD2, TVIN_PORT_VIU2_WB1_OSD1, TVIN_PORT_VIU2_WB1_OSD2, + TVIN_PORT_VIU2_WB1_VPP, TVIN_PORT_VIU2_WB1_POST_BLEND, TVIN_PORT_MIPI = 0x00010000, TVIN_PORT_ISP = 0x00020000, @@ -312,6 +316,15 @@ struct tvin_info_s { unsigned int is_dvi; }; +struct tvin_frontend_info_s { + enum tvin_scan_mode_e scan_mode; + enum tvin_color_fmt_e cfmt; + unsigned int fps; + unsigned int width; + unsigned int height; + unsigned int colordepth; +}; + struct tvin_buf_info_s { unsigned int vf_size; unsigned int buf_count; @@ -432,7 +445,13 @@ struct tvafe_pin_mux_s { enum tvin_force_color_range_e) #define TVIN_IOC_GAME_MODE _IOW(_TM_T, 0x4b, unsigned int) #define TVIN_IOC_SET_AUTO_RATIO_EN _IOW(_TM_T, 0x4c, unsigned int) - +#define TVIN_IOC_GET_LATENCY_MODE _IOR(_TM_T, 0x4d,\ + struct tvin_latency_s) +#define TVIN_IOC_G_FRONTEND_INFO _IOR(_TM_T, 0x4e,\ + struct tvin_frontend_info_s) +#define TVIN_IOC_S_CANVAS_ADDR _IOW(_TM_T, 0x4f,\ + struct vdin_set_canvas_s) +#define TVIN_IOC_S_CANVAS_RECOVERY _IO(_TM_T, 0x0a) /* TVAFE */ #define TVIN_IOC_S_AFE_VGA_PARM _IOW(_TM_T, 0x16, struct tvafe_vga_parm_s) #define TVIN_IOC_G_AFE_VGA_PARM _IOR(_TM_T, 0x17, struct tvafe_vga_parm_s) @@ -444,6 +463,10 @@ struct tvafe_pin_mux_s { #define TVIN_IOC_LOAD_REG _IOW(_TM_T, 0x20, struct am_regs_s) #define TVIN_IOC_S_AFE_SONWON _IO(_TM_T, 0x22) #define TVIN_IOC_S_AFE_SONWOFF _IO(_TM_T, 0x23) +#define TVIN_IOC_G_VDIN_HIST _IOW(_TM_T, 0x24, struct vdin_hist_s) +#define TVIN_IOC_S_VDIN_V4L2START _IOW(_TM_T, 0x25, struct vdin_v4l2_param_s) +#define TVIN_IOC_S_VDIN_V4L2STOP _IO(_TM_T, 0x26) +#define TVIN_IOC_S_AFE_SONWCFG _IOW(_TM_T, 0x27, unsigned int) /* *function defined applied for other driver diff --git a/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h b/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h index 493bc9a..b1233fa 100644 --- a/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h +++ b/include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h @@ -742,6 +742,10 @@ enum cam_interface_e { CAM_MIPI, }; +#define PARAM_STATE_NULL 0x00000000 +#define PARAM_STATE_HISTGRAM 0x00000001 +#define PARAM_STATE_SCREENCAP 0x00000002 + /* *********************************************************************** */ /* *** IOCTL command definitions ***************************************** */ @@ -813,6 +817,7 @@ struct vdin_parm_s { unsigned short skip_count; /* for skip frame */ struct csi_parm_s csi_hw_info; + /*for reserved */ uintptr_t reserved; }; diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index 678a148..ce0ebbe8 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -44,8 +44,11 @@ #define VIDTYPE_COMPRESS 0x100000 #define VIDTYPE_PIC 0x200000 #define VIDTYPE_SCATTER 0x400000 -#define VIDTYPE_VD2 0x800000 +#define VIDTYPE_VD2 0x800000 #define VIDTYPE_COMPRESS_LOSS 0x1000000 +#define VIDTYPE_COMB_MODE 0x2000000 +#define VIDTYPE_NO_DW 0x4000000 +#define VIDTYPE_SUPPORT_COMPRESS 0x8000000 #define DISP_RATIO_FORCECONFIG 0x80000000 #define DISP_RATIO_FORCE_NORMALWIDE 0x40000000 diff --git a/include/linux/amlogic/media/vfm/vframe_provider.h b/include/linux/amlogic/media/vfm/vframe_provider.h index 014f163..f67776e 100644 --- a/include/linux/amlogic/media/vfm/vframe_provider.h +++ b/include/linux/amlogic/media/vfm/vframe_provider.h @@ -40,6 +40,7 @@ struct vframe_states { #define VFRAME_EVENT_RECEIVER_GET_AUX_DATA 0x80 #define VFRAME_EVENT_RECEIVER_DISP_MODE 0x100 #define VFRAME_EVENT_RECEIVER_DOLBY_BYPASS_EL 0x200 +#define VFRAME_EVENT_RECEIVER_NEED_NO_COMP 0x400 /* for VFRAME_EVENT_RECEIVER_GET_AUX_DATA*/ struct provider_aux_req_s { diff --git a/include/linux/amlogic/media/vout/vdac_dev.h b/include/linux/amlogic/media/vout/vdac_dev.h index 90e4096..fe9cb85 100644 --- a/include/linux/amlogic/media/vout/vdac_dev.h +++ b/include/linux/amlogic/media/vout/vdac_dev.h @@ -28,6 +28,7 @@ enum vdac_cpu_type { VDAC_CPU_G12AB = 6, VDAC_CPU_TL1 = 7, VDAC_CPU_SM1 = 8, + VDAC_CPU_TM2 = 9, VDAC_CPU_MAX, }; -- 2.7.4