tvin: vdin: tl1 improve vdin afbce function [1/1]
authorXuhua Zhang <xuhua.zhang@amlogic.com>
Fri, 16 Nov 2018 06:23:10 +0000 (14:23 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:43:57 +0000 (14:43 +0800)
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <dezhi.kong@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <nian.jing@amlogic.com>
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 <yicheng.shen@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <nian.jing@amlogic.com>
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 <nian.jing@amlogic.com>
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 <yong.qin@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <yong.qin@amlogic.com>
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 <yong.qin@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <xuhua.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <nanxin.qin@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <nian.jing@amlogic.com>
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 <nian.jing@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <evoke.zhang@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <zhiwei.yuan@amlogic.com>
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 <zhiwei.yuan@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <zhiwei.yuan@amlogic.com>
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 <evoke.zhang@amlogic.com>
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 <nian.jing@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
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 <nian.jing@amlogic.com>
Signed-off-by: Luan Yuan <luan.yuan@amlogic.com>
54 files changed:
arch/arm/boot/dts/amlogic/mesontm2.dtsi
arch/arm/boot/dts/amlogic/tl1_pxp.dts
arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts
arch/arm64/boot/dts/amlogic/mesontm2.dtsi
drivers/amlogic/clk/tl1/tl1.h
drivers/amlogic/media/enhancement/amvecm/amvecm.c
drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h
drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h
drivers/amlogic/media/enhancement/amvecm/vlock.c
drivers/amlogic/media/enhancement/amvecm/vlock.h
drivers/amlogic/media/video_processor/pic_dev/picdec.c
drivers/amlogic/media/video_processor/video_dev/amlvideo2.c
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/vin/tvin/bt656/bt656_601_in.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.h
drivers/amlogic/media/vin/tvin/tvafe/tvafe.c
drivers/amlogic/media/vin/tvin/tvafe/tvafe.h
drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.c
drivers/amlogic/media/vin/tvin/tvafe/tvafe_avin_detect.h
drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c
drivers/amlogic/media/vin/tvin/tvafe/tvafe_debug.c
drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c
drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h
drivers/amlogic/media/vin/tvin/tvin_global.h
drivers/amlogic/media/vin/tvin/vdin/Makefile
drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.c
drivers/amlogic/media/vin/tvin/vdin/vdin_afbce.h
drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.c
drivers/amlogic/media/vin/tvin/vdin/vdin_canvas.h
drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.c
drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h
drivers/amlogic/media/vin/tvin/vdin/vdin_debug.c
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h
drivers/amlogic/media/vin/tvin/vdin/vdin_sm.c
drivers/amlogic/media/vin/tvin/vdin/vdin_sm.h
drivers/amlogic/media/vin/tvin/vdin/vdin_vf.c
drivers/amlogic/media/vin/tvin/viu/viuin.c
drivers/amlogic/media/vout/cvbs/cvbs_out.c
drivers/amlogic/media/vout/cvbs/cvbs_out.h
drivers/amlogic/media/vout/cvbs/cvbs_out_reg.h
drivers/amlogic/media/vout/cvbs/enc_clk_config.c
drivers/amlogic/media/vout/vdac/vdac_dev.c
include/linux/amlogic/media/amvecm/amvecm.h
include/linux/amlogic/media/frame_provider/tvin/tvin.h
include/linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h
include/linux/amlogic/media/vfm/vframe.h
include/linux/amlogic/media/vfm/vframe_provider.h
include/linux/amlogic/media/vout/vdac_dev.h

index 0ff7ebf..2d642da 100644 (file)
        };
 
        vdac {
-               compatible = "amlogic, vdac-tl1";
+               compatible = "amlogic, vdac-tm2";
                status = "okay";
        };
 
index 92a55d7..e90bb20 100644 (file)
                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>;
                };
 
index dc3014d..8824a55 100644 (file)
                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>;
                };
 
index 356d181..980cd4b 100644 (file)
        };
 
        vdac {
-               compatible = "amlogic, vdac-tl1";
+               compatible = "amlogic, vdac-tm2";
                status = "okay";
        };
 
index e3a7b56..bc67643 100644 (file)
 #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 */
index 078a35b..4a54c83 100644 (file)
@@ -31,6 +31,8 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 /* #include <linux/amlogic/aml_common.h> */
 #include <linux/ctype.h>/* for parse_para_pq */
 #include <linux/vmalloc.h>
@@ -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);
 }
 
index bdd4737..292827d 100644 (file)
@@ -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
 
index ec7f639..37afb66 100644 (file)
 #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
 
 /*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
 #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 */
index 8ce8c0c..752bdf4 100644 (file)
 #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*/
 
index 96784fb..a91b1c5 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/amlogic/media/vfm/vframe.h>
 #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);
 
index 7673c1f..c9604eb 100644 (file)
@@ -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;
index 8a58211..78a15aa 100644 (file)
@@ -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) {
index 6f54df4..61ecf76 100644 (file)
@@ -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);
 
index 0feac45..4f02b42 100644 (file)
@@ -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;
index f05772e..ca523b0 100644 (file)
@@ -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;
 }
 
index 02fcd27..fb3d89a 100644 (file)
@@ -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
index f231444..d0394cf 100644 (file)
@@ -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 =
index 8c64f4e..e221be7 100644 (file)
 #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 */
index 953e819..d9cdd8d 100644 (file)
@@ -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) {
index c9fcc1a..8a7f020 100644 (file)
@@ -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;
 
index f9e2416..630042c 100644 (file)
@@ -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,
        },
        {},
 };
index 7fe836f..0c42042 100644 (file)
@@ -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);
index 60759b1..b697da4 100644 (file)
@@ -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
index f95f06e..6c8c765 100644 (file)
@@ -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,
 };
 
index 610992f..2e3ff29 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/amlogic/media/frame_provider/tvin/tvin.h>
 #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)
index 44993fd..f6786fe 100644 (file)
@@ -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);
index 70c8faa..3f7be31 100644 (file)
@@ -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,
index 85d6a32..2fa4bcb 100644 (file)
@@ -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 {
index c6d053b..78f4b40 100644 (file)
@@ -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 */
index 7f0c556..b8092e9 100644 (file)
@@ -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
index eaa9d73..50fbf47 100644 (file)
 #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);
+}
index feb2d08..0ac61b5 100644 (file)
 
 #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
 
index edfa775..1cfa6b1 100644 (file)
@@ -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);
index 66aabab..d97d767 100644 (file)
@@ -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);
index dc61bc0..c37ba4b 100644 (file)
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/amlogic/media/codec_mm/codec_mm.h>
+#include <linux/highmem.h>
+#include <linux/page-flags.h>
+#include <linux/vmalloc.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-contiguous.h>
 #include <linux/amlogic/media/video_sink/video.h>
@@ -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;
 }
 
index 178c74a..93ff0b3 100644 (file)
 
 #ifndef __TVIN_VDIN_CTL_H
 #define __TVIN_VDIN_CTL_H
-
+#include <linux/highmem.h>
+#include <linux/page-flags.h>
+#include <linux/vmalloc.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-contiguous.h>
 #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);
index cf16fb1..475106b 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
 /* 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 <linux/seq_file.h>
 #include <linux/debugfs.h>
@@ -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;
 }
index 74993dc..a0dd165 100644 (file)
 #include <linux/of_reserved_mem.h>
 #include <linux/of_irq.h>
 #include <linux/cma.h>
+#include <linux/dma-buf.h>
+#include <linux/scatterlist.h>
+#include <linux/mm_types.h>
 #include <linux/amlogic/media/codec_mm/codec_mm.h>
 #include <linux/dma-contiguous.h>
 #include <linux/amlogic/iomap.h>
+#include <linux/fdtable.h>
 /* Amlogic Headers */
 #include <linux/amlogic/media/vpu/vpu.h>
 #include <linux/amlogic/media/vfm/vframe.h>
@@ -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 <n> frames");
-
-module_param(ignore_frames, int, 0664);
-MODULE_PARM_DESC(ignore_frames, "ignore first <n> 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 <n> frames");
+
+module_param(game_mode_phlock_switch_frames, int, 0664);
+MODULE_PARM_DESC(game_mode_phlock_switch_frames,
+               "game mode switch <n> 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(&param, 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, &param);
+               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);
index 43e719e..1c2b04f 100644 (file)
@@ -36,8 +36,8 @@
 #include <linux/amlogic/media/vfm/vframe_receiver.h>
 #include <linux/amlogic/media/vfm/vframe_provider.h>
 #include <linux/amlogic/media/frame_provider/tvin/tvin_v4l2.h>
-#ifdef CONFIG_AML_RDMA
-#include <linux/amlogic/rdma/rdma_mgr.h>
+#ifdef CONFIG_AMLOGIC_MEDIA_RDMA
+#include <linux/amlogic/media/rdma/rdma_mgr.h>
 #endif
 
 /* Local Headers */
 #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
 #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
 /*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 */
 
index 252a3ab..1ac4fbe 100644 (file)
@@ -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;
index b300911..92fdd32 100644 (file)
@@ -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);
index afd3446..886ec35 100644 (file)
@@ -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
index 3fe16a6..c79f379 100644 (file)
@@ -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;
index 9d0c118..23c1454 100644 (file)
@@ -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,
        },
        {},
 };
index 05f6961..3016b70 100644 (file)
@@ -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 {
index be66ef4..268d7dc 100644 (file)
 /*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
index 379e19b..1f1a029 100644 (file)
@@ -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);
        }
index 361e7de..7e925f4 100644 (file)
@@ -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;
 }
index 59e88fe..50b0f95 100644 (file)
@@ -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
index 181796f..508585a 100644 (file)
@@ -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
index 493bc9a..b1233fa 100644 (file)
@@ -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;
 };
index 678a148..ce0ebbe 100644 (file)
 #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
index 014f163..f67776e 100644 (file)
@@ -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 {
index 90e4096..fe9cb85 100644 (file)
@@ -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,
 };