diff --git a/Documentation/devicetree/bindings/sound/tas5805.txt b/Documentation/devicetree/bindings/sound/tas5805.txt new file mode 100644 index 000000000000..05ff201dfcef --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tas5805.txt @@ -0,0 +1,18 @@ +Texas Instruments TAS5805 Audio amplifier + +The TAS5805 serial control bus communicates through the I2C protocol only. The +serial bus is also used for periodic codec fault checking/reporting during +audio playback. For more product information please see the links below: + +Required properties: + +- compatible : "ti, tas5805" +- reg : I2C slave address + +Example: + +tas5805: tas5805@7c { + status = "okay"; + compatible = "ti,tas5805"; + reg = <0x2d>; +}; diff --git a/MAINTAINERS b/MAINTAINERS index d8e0a4dd26f2..556bb97e52b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13525,6 +13525,8 @@ AMLOGIC driver for memory extend M: Tao Zeng F: drivers/amlogic/memory_ext/* F: include/linux/amlogic/ramdump.h +F: include/linux/amlogic/vmap_stack.h +F: drivers/amlogic/memory_ext/vmap_stack.c AMLOGIC driver for memory extend M: Tao Zeng @@ -13979,6 +13981,14 @@ F: sound/soc/codecs/amlogic/Makefile F: sound/soc/codecs/amlogic/tas5707.c F: sound/soc/codecs/amlogic/tas5707.h +AMLOGIC Audio codec driver +M: Yonghao Jiao +F: arch/arm/configs/meson32_deconfig +F: sound/soc/codecs/amlogic/Kconfig +F: sound/soc/codecs/amlogic/Makefile +F: sound/soc/codecs/amlogic/tas5805.c +F: sound/soc/codecs/amlogic/tas5805.h + AMLOGIC AXG ADD DTS FOR A113D SOCKET AND DEVELOPMENT BOARDS M: Yun Cai F: arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts @@ -14482,15 +14492,19 @@ F: drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c F: drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.h AMLOGIC DTV DEMOD DRIVER -M: Jihong Sui -F: include/uapi/linux/dvb/aml_demod.h -F: drivers/amlogic/media/amldemod/* +M: Jihong Sui +F: include/uapi/linux/dvb/aml_demod.h +F: drivers/amlogic/media/amldemod/* AMLOGIC DTV DEMOD DRIVER M: Jihong Sui F: drivers/amlogic/media/amldemod/* F: drivers/amlogic/media/dtv_demod/* +AMLOGIC DTV DEMOD DRIVER +M: Zhiwei Yuan +F: drivers/amlogic/media/dtv_demod/include/addr_atsc*.h + AMLOGIC DEFENDKEY DRIVER M: Zhongfu Luo F: drivers/amlogic/defendkey/* @@ -14662,15 +14676,15 @@ M: Luan Yuan F: arch/arm/boot/dts/amlogic/partition_mbox_p241_P.dtsi AMLOGIC TL1 SOUND CARD -M: Xing Wang F: drivers/amlogic/media/vout/backlight/aml_ldim/ldim_spi.c +AMLOGIC CAMERA DRIVER +M: Guosong Zhou +F: arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts +F: arch/arm/boot/dts/amlogic/g12a_s905d2_u200.dts +F: arch/arm64/configs/meson64_defconfig +F: arch/arm/configs/meson64_a32_defconfig +F: drivers/amlogic/media/Kconfig +F: drivers/amlogic/media/Makefile +F: drivers/amlogic/media/camera/* +F: drivers/amlogic/media/common/canvas/canvas_mgr.c +F: drivers/amlogic/media/common/vfm/vfm.c +F: include/linux/amlogic/media/camera/* + HARDKERNEL S922D odroidn2 M: Joy Cho F: arch/arm64/configs/odroidn2_defconfig diff --git a/arch/arm/boot/dts/amlogic/atom.dts b/arch/arm/boot/dts/amlogic/atom.dts index e60f6ee8ed10..0b453304c69e 100644 --- a/arch/arm/boot/dts/amlogic/atom.dts +++ b/arch/arm/boot/dts/amlogic/atom.dts @@ -666,13 +666,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_a113x_skt.dts b/arch/arm/boot/dts/amlogic/axg_a113x_skt.dts index 23aac380ea3e..1902ef3d8ac0 100644 --- a/arch/arm/boot/dts/amlogic/axg_a113x_skt.dts +++ b/arch/arm/boot/dts/amlogic/axg_a113x_skt.dts @@ -452,13 +452,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s400.dts b/arch/arm/boot/dts/amlogic/axg_s400.dts index 7f3b84f0fffe..3884ee3256c9 100644 --- a/arch/arm/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm/boot/dts/amlogic/axg_s400.dts @@ -631,13 +631,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s400_v03.dts b/arch/arm/boot/dts/amlogic/axg_s400_v03.dts index 002962aa404f..d8cf6fd0d07b 100644 --- a/arch/arm/boot/dts/amlogic/axg_s400_v03.dts +++ b/arch/arm/boot/dts/amlogic/axg_s400_v03.dts @@ -612,13 +612,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s400_v03gva.dts b/arch/arm/boot/dts/amlogic/axg_s400_v03gva.dts index fb3949ba2e63..38895bcc911d 100644 --- a/arch/arm/boot/dts/amlogic/axg_s400_v03gva.dts +++ b/arch/arm/boot/dts/amlogic/axg_s400_v03gva.dts @@ -616,13 +616,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s400emmc_512m.dts b/arch/arm/boot/dts/amlogic/axg_s400emmc_512m.dts index d9655703c2d6..da16137a1c10 100644 --- a/arch/arm/boot/dts/amlogic/axg_s400emmc_512m.dts +++ b/arch/arm/boot/dts/amlogic/axg_s400emmc_512m.dts @@ -640,13 +640,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s420.dts b/arch/arm/boot/dts/amlogic/axg_s420.dts index 1b6a532f03fc..104e35fa2746 100644 --- a/arch/arm/boot/dts/amlogic/axg_s420.dts +++ b/arch/arm/boot/dts/amlogic/axg_s420.dts @@ -466,13 +466,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s420_128m.dts b/arch/arm/boot/dts/amlogic/axg_s420_128m.dts index d9be9f0cf117..440bff05ddf7 100644 --- a/arch/arm/boot/dts/amlogic/axg_s420_128m.dts +++ b/arch/arm/boot/dts/amlogic/axg_s420_128m.dts @@ -458,13 +458,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s420_v03.dts b/arch/arm/boot/dts/amlogic/axg_s420_v03.dts index 9a308bb12da3..f9da32c0821a 100644 --- a/arch/arm/boot/dts/amlogic/axg_s420_v03.dts +++ b/arch/arm/boot/dts/amlogic/axg_s420_v03.dts @@ -470,13 +470,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/axg_s420_v03gva.dts b/arch/arm/boot/dts/amlogic/axg_s420_v03gva.dts index 2a72e9d254cf..594190f2d64b 100644 --- a/arch/arm/boot/dts/amlogic/axg_s420_v03gva.dts +++ b/arch/arm/boot/dts/amlogic/axg_s420_v03gva.dts @@ -475,13 +475,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_skt.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_skt.dts index 0a8dec07a064..c511bb41f9a4 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_skt.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_skt.dts @@ -215,13 +215,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -273,7 +273,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -289,6 +289,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -368,6 +369,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts index 1e4897abef31..6955c4592030 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts @@ -202,13 +202,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -260,7 +260,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -276,6 +276,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -355,6 +356,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200.dts index 3b95f4c8c5d8..03a40b29b100 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x100000 0x7ff00000>; + linux,usable-memory = <0x000000 0x80000000>; }; reserved-memory { @@ -151,6 +151,12 @@ size = <0x04000000>; alignment = <0x400000>; }; + vm0_cma_reserved:linux,vm0_cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x2000000>; + alignment = <0x400000>; + }; }; gpioleds { @@ -230,13 +236,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -284,6 +290,54 @@ dev_name = "ionvideo"; status = "okay"; }; + vm0 { + compatible = "amlogic, vm"; + memory-region = <&vm0_cma_reserved>; + dev_name = "vm0"; + status = "disabled"; + vm_id = <0>; + }; + + amvdec_656in { + /*bt656 gpio conflict with i2c0*/ + compatible = "amlogic, amvdec_656in"; + dev_name = "amvdec_656in"; + status = "disabled"; + reg = <0xffe02000 0x7c>; + clocks = <&clkc CLKID_BT656_COMP>, + <&clkc CLKID_BT656>; + clock-names = "cts_bt656_clk1", + "clk_gate_bt656"; + /* bt656in1, bt656in2 */ + bt656in1 { + bt656_id = <1>; + status = "disabled"; + }; + }; + + aml_cams { + compatible = "amlogic, cams_prober"; + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&cam_dvp_pins &gen_clk_ee_z>; + clocks = <&clkc CLKID_GEN_CLK>; + clock-names = "g12a_24m"; + cam_0{ + cam_name = "gc2145"; + front_back = <0>; + /*u200 i2c2 gpio conflict with ethmac*/ + camera-i2c-bus = <&i2c2>; + gpio_pwdn-gpios = <&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>; + gpio_rst-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH>; + mirror_flip = <1>; + vertical_flip = <1>; + spread_spectrum = <0>; + bt_path = "gpio"; + bt_path_count = <1>; + vdin_path = <0>; + status = "okay"; + }; + }; gpio_keypad{ compatible = "amlogic, gpio_keypad"; @@ -312,7 +366,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -329,6 +383,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -413,6 +468,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -783,6 +843,13 @@ }; }; +&i2c2 { + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_master_pins2>; + clock-frequency = <100000>; +}; + &i2c3 { status = "okay"; pinctrl-names="default"; @@ -1118,6 +1185,32 @@ }; }; + clk12_24_z_pins:clk12_24_z_pins { + mux { + groups = "clk12_24_z"; + function = "clk12_24_ee"; + drive-strength = <3>; + }; + }; + + gen_clk_ee_z: gen_clk_ee_z { + mux { + groups="gen_clk_ee_z"; + function="gen_clk_ee"; + drive-strength = <3>; + }; + }; + + cam_dvp_pins:cam_dvp_pins { + mux { + groups = "bt656_a_vs", "bt656_a_hs", "bt656_a_clk", + "bt656_a_din0", "bt656_a_din1", "bt656_a_din2", + "bt656_a_din3", "bt656_a_din4", "bt656_a_din5", + "bt656_a_din6", "bt656_a_din7"; + function = "bt656"; + }; + }; + }; /* end of pinctrl_periphs */ &pinctrl_aobus { diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_1g.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_1g.dts index 39f49da3102a..70a6efda37fc 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_1g.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_1g.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x100000 0x3ff00000>; + linux,usable-memory = <0x000000 0x40000000>; }; reserved-memory { @@ -155,6 +155,12 @@ alignment = <0x400000>; alloc-ranges = <0x0 0x30000000>; }; + vm0_cma_reserved:linux,vm0_cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x2000000>; + alignment = <0x400000>; + }; }; gpioleds { @@ -234,13 +240,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -288,6 +294,54 @@ dev_name = "ionvideo"; status = "okay"; }; + vm0 { + compatible = "amlogic, vm"; + memory-region = <&vm0_cma_reserved>; + dev_name = "vm0"; + status = "disabled"; + vm_id = <0>; + }; + + amvdec_656in { + /*bt656 gpio conflict with i2c0*/ + compatible = "amlogic, amvdec_656in"; + dev_name = "amvdec_656in"; + status = "disabled"; + reg = <0xffe02000 0x7c>; + clocks = <&clkc CLKID_BT656_COMP>, + <&clkc CLKID_BT656>; + clock-names = "cts_bt656_clk1", + "clk_gate_bt656"; + /* bt656in1, bt656in2 */ + bt656in1 { + bt656_id = <1>; + status = "disabled"; + }; + }; + + aml_cams { + compatible = "amlogic, cams_prober"; + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&cam_dvp_pins &gen_clk_ee_z>; + clocks = <&clkc CLKID_GEN_CLK>; + clock-names = "g12a_24m"; + cam_0{ + cam_name = "gc2145"; + front_back = <0>; + /*u200 i2c2 gpio conflict with ethmac*/ + camera-i2c-bus = <&i2c2>; + gpio_pwdn-gpios = <&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>; + gpio_rst-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH>; + mirror_flip = <1>; + vertical_flip = <1>; + spread_spectrum = <0>; + bt_path = "gpio"; + bt_path_count = <1>; + vdin_path = <0>; + status = "okay"; + }; + }; gpio_keypad{ compatible = "amlogic, gpio_keypad"; @@ -316,7 +370,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -333,6 +387,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -417,6 +472,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -787,6 +847,13 @@ }; }; +&i2c2 { + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_master_pins2>; + clock-frequency = <100000>; +}; + &i2c3 { status = "okay"; pinctrl-names="default"; @@ -1122,6 +1189,32 @@ }; }; + clk12_24_z_pins:clk12_24_z_pins { + mux { + groups = "clk12_24_z"; + function = "clk12_24_ee"; + drive-strength = <3>; + }; + }; + + gen_clk_ee_z: gen_clk_ee_z { + mux { + groups="gen_clk_ee_z"; + function="gen_clk_ee"; + drive-strength = <3>; + }; + }; + + cam_dvp_pins:cam_dvp_pins { + mux { + groups = "bt656_a_vs", "bt656_a_hs", "bt656_a_clk", + "bt656_a_din0", "bt656_a_din1", "bt656_a_din2", + "bt656_a_din3", "bt656_a_din4", "bt656_a_din5", + "bt656_a_din6", "bt656_a_din7"; + function = "bt656"; + }; + }; + }; /* end of pinctrl_periphs */ &pinctrl_aobus { diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts index cecbd8078153..4441fcc9b185 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts @@ -213,13 +213,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -383,7 +383,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -398,6 +398,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -472,6 +473,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts index 8815f0730bb8..a960b7439f0e 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts @@ -214,13 +214,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -384,7 +384,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -399,6 +399,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -473,6 +474,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts index 9f3f0a5f0e57..f533037eb344 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts @@ -214,13 +214,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -384,7 +384,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -399,6 +399,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -473,6 +474,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211.dts index 76e20d2762dd..c3e236146c7b 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211.dts @@ -252,13 +252,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -318,7 +318,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -334,6 +334,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -413,6 +414,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_1g.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_1g.dts index 74ec44c01106..cd970a2bbb0c 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_1g.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_1g.dts @@ -246,13 +246,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -312,7 +312,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -328,6 +328,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -407,6 +408,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_512m.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_512m.dts index 17c90661cdce..231f350a8064 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_512m.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_512m.dts @@ -241,13 +241,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -307,7 +307,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -323,6 +323,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -402,6 +403,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts index ba27ad58f4e2..a3ae0f1f1cfb 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts @@ -225,13 +225,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -372,7 +372,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -388,6 +388,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -467,6 +468,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u212.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u212.dts index 1004379dd191..58073e20078b 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u212.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u212.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x100000 0x7ff00000>; + linux,usable-memory = <0x000000 0x80000000>; }; reserved-memory { @@ -252,13 +252,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -306,19 +306,47 @@ dev_name = "ionvideo"; status = "okay"; }; - dvb{ - compatible = "amlogic, dvb"; - dev_name = "dvb"; - status = "ok"; - /*"parallel","serial","disable"*/ - ts2 = "parallel"; - ts2_control = <0>; - ts2_invert = <0>; - }; + /*dvb { + * compatible = "amlogic, dvb"; + * dev_name = "dvb"; + * + * fe0_mode = "external"; + * fe0_demod = "Atbm8881"; + * fe0_i2c_adap_id = <&i2c2>; + * fe0_demod_i2c_addr = <0xc0>; + * fe0_ts = <1>; + * fe0_reset_value = <0>; + * fe0_reset_gpio = <&gpio GPIOZ_1 GPIO_ACTIVE_HIGH>; + * + * ts1 = "parallel"; + * ts1_control = <0>; + * ts1_invert = <0>; + * interrupts = <0 23 1 + * 0 5 1 + * 0 21 1 + * 0 19 1 + * 0 25 1 + * 0 18 1 + * 0 24 1>; + * interrupt-names = "demux0_irq", + * "demux1_irq", + * "demux2_irq", + * "dvr0_irq", + * "dvr1_irq", + * "dvrfill0_fill", + * "dvrfill1_flush"; + * pinctrl-names = "p_ts1"; + * pinctrl-0 = <&dvb_p_ts1_pins>; + * clocks = <&clkc CLKID_DEMUX + * &clkc CLKID_AHB_ARB0 + * &clkc CLKID_DOS_PARSER>; + * clock-names = "demux", "ahbarb0", "parser_top"; + *}; + */ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -334,7 +362,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; - + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; key-device = "normal"; @@ -413,6 +441,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -783,6 +816,19 @@ }; }; +/* + *if use i2c2_master_pins2 + *please disable internal_eth_pins + *in case pinmux conflict + */ +/*&i2c2 { + * status = "okay"; + * pinctrl-names="default"; + * pinctrl-0=<&i2c2_master_pins2>; + * clock-frequency = <300000>; + *}; + */ + &i2c3 { status = "disabled"; pinctrl-names="default"; diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_1g.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_1g.dts index 547e68b264fc..aed00d038bc7 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_1g.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_1g.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x100000 0x3ff00000>; + linux,usable-memory = <0x000000 0x40000000>; }; @@ -250,13 +250,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -304,19 +304,47 @@ dev_name = "ionvideo"; status = "okay"; }; - dvb{ - compatible = "amlogic, dvb"; - dev_name = "dvb"; - status = "ok"; - /*"parallel","serial","disable"*/ - ts2 = "parallel"; - ts2_control = <0>; - ts2_invert = <0>; - }; + /*dvb { + * compatible = "amlogic, dvb"; + * dev_name = "dvb"; + * + * fe0_mode = "external"; + * fe0_demod = "Atbm8881"; + * fe0_i2c_adap_id = <&i2c2>; + * fe0_demod_i2c_addr = <0xc0>; + * fe0_ts = <1>; + * fe0_reset_value = <0>; + * fe0_reset_gpio = <&gpio GPIOZ_1 GPIO_ACTIVE_HIGH>; + * + * ts1 = "parallel"; + * ts1_control = <0>; + * ts1_invert = <0>; + * interrupts = <0 23 1 + * 0 5 1 + * 0 21 1 + * 0 19 1 + * 0 25 1 + * 0 18 1 + * 0 24 1>; + * interrupt-names = "demux0_irq", + * "demux1_irq", + * "demux2_irq", + * "dvr0_irq", + * "dvr1_irq", + * "dvrfill0_fill", + * "dvrfill1_flush"; + * pinctrl-names = "p_ts1"; + * pinctrl-0 = <&dvb_p_ts1_pins>; + * clocks = <&clkc CLKID_DEMUX + * &clkc CLKID_AHB_ARB0 + * &clkc CLKID_DOS_PARSER>; + * clock-names = "demux", "ahbarb0", "parser_top"; + *}; + */ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -332,6 +360,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -411,6 +440,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -778,6 +812,19 @@ }; }; +/* + *if use i2c2_master_pins2 + *please disable internal_eth_pins + *in case pinmux conflict + */ +/*&i2c2 { + * status = "okay"; + * pinctrl-names="default"; + * pinctrl-0=<&i2c2_master_pins2>; + * clock-frequency = <300000>; + *}; + */ + &i2c3 { status = "disabled"; pinctrl-names="default"; diff --git a/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts b/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts index f70de86ef708..f3fd8d376006 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts @@ -225,13 +225,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -372,7 +372,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -388,6 +388,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -467,6 +468,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905y2_u220.dts b/arch/arm/boot/dts/amlogic/g12a_s905y2_u220.dts index 0322b9c3fe69..a734db686b5f 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905y2_u220.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905y2_u220.dts @@ -209,13 +209,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -291,7 +291,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -307,6 +307,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -386,6 +387,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12a_s905y2_u221.dts b/arch/arm/boot/dts/amlogic/g12a_s905y2_u221.dts index 9317cf0a3b92..caadd28dbe5d 100644 --- a/arch/arm/boot/dts/amlogic/g12a_s905y2_u221.dts +++ b/arch/arm/boot/dts/amlogic/g12a_s905y2_u221.dts @@ -44,7 +44,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x100000 0x7ff00000>; + linux,usable-memory = <0x000000 0x80000000>; }; reserved-memory { @@ -201,13 +201,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -259,7 +259,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -275,6 +275,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -354,6 +355,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12b-sched-energy.dtsi b/arch/arm/boot/dts/amlogic/g12b-sched-energy.dtsi index 1c5fe160b001..796f592ae9f7 100644 --- a/arch/arm/boot/dts/amlogic/g12b-sched-energy.dtsi +++ b/arch/arm/boot/dts/amlogic/g12b-sched-energy.dtsi @@ -29,7 +29,7 @@ 221 54 332 78 399 92 - 465 11 + 465 116 503 135 535 162 567 184 diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_skt.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_skt.dts index a448a5a6957b..d707eb07f111 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_skt.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_skt.dts @@ -239,13 +239,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -322,7 +322,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -338,6 +338,8 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; + keysn_0: key_0{ key-name = "usid"; @@ -417,6 +419,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts index b858e07da5dd..af55b1cb15e4 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x100000 0x7ff00000>; + linux,usable-memory = <0x000000 0x80000000>; }; reserved-memory { @@ -148,6 +148,16 @@ }; }; + gpioleds { + compatible = "gpio-leds"; + status = "okay"; + sys_led { + label="sys_led"; + gpios=<&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; + default-state ="on"; + }; + }; + cvbsout { compatible = "amlogic, cvbsout-g12b"; dev_name = "cvbsout"; @@ -206,13 +216,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -281,7 +291,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -297,6 +307,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -376,6 +387,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -497,7 +513,7 @@ aml-audio-card,dai-link@1 { format = "i2s"; mclk-fs = <256>; - //continuous-clock; + continuous-clock; //bitclock-inversion; //frame-inversion; bitclock-master = <&aml_tdmb>; @@ -563,6 +579,7 @@ aml-audio-card,dai-link@4 { mclk-fs = <128>; + continuous-clock; /* suffix-name, sync with android audio hal * what's the dai link used for */ diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts index fe7d3a49a431..83937103b82e 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts @@ -250,13 +250,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -422,7 +422,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -437,6 +437,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -511,6 +512,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey amlvecm { @@ -604,7 +610,7 @@ aml-audio-card,dai-link@1 { format = "i2s"; mclk-fs = <256>; - //continuous-clock; + continuous-clock; //bitclock-inversion; //frame-inversion; bitclock-master = <&aml_tdmb>; @@ -670,6 +676,7 @@ aml-audio-card,dai-link@4 { mclk-fs = <128>; + continuous-clock; /* suffix-name, sync with android audio hal * what's the dai link used for */ diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts index 27936bd825ef..b1b2676c8b2b 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts @@ -216,13 +216,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -388,7 +388,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -403,6 +403,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -477,6 +478,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey amlvecm { diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts b/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts index 6712e7731504..0edc32403125 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts @@ -176,13 +176,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -426,7 +426,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -440,7 +440,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -477,17 +477,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1095,7 +1095,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1112,6 +1112,8 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; + keysn_0: key_0{ key-name = "usid"; @@ -1196,6 +1198,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts index 2105b028b50a..e7333d8637ae 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts @@ -151,13 +151,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -401,7 +401,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -415,7 +415,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -452,17 +452,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1137,7 +1137,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1153,6 +1153,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1232,6 +1233,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts b/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts index 1c9feacbf504..868fa5d4d2a2 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts @@ -162,13 +162,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1081,7 +1081,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1097,6 +1097,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1176,6 +1177,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts b/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts index 04e17f3a95f2..c03256ed4713 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts @@ -182,13 +182,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -520,7 +520,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -534,7 +534,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -571,17 +571,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1102,7 +1102,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1119,6 +1119,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1203,6 +1204,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts index d3c1a0fc2e63..f8abcbe4568d 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts @@ -152,13 +152,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -479,7 +479,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -493,7 +493,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -530,17 +530,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1137,7 +1137,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1153,6 +1153,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1232,6 +1233,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_p230_2g.dts b/arch/arm/boot/dts/amlogic/gxl_p230_2g.dts index 5c8314d53d9a..c1944cc88ba5 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p230_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p230_2g.dts @@ -171,13 +171,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1127,7 +1127,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1144,6 +1144,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1228,6 +1229,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey dvb { compatible = "amlogic, dvb"; diff --git a/arch/arm/boot/dts/amlogic/gxl_p230_2g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p230_2g_buildroot.dts index 4213a292a4b3..bdb46750131d 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p230_2g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p230_2g_buildroot.dts @@ -169,13 +169,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1188,7 +1188,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1204,6 +1204,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1283,6 +1284,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_p231_1g.dts b/arch/arm/boot/dts/amlogic/gxl_p231_1g.dts index 8ca654332e4d..5fdbc780e00e 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p231_1g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p231_1g.dts @@ -171,13 +171,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1016,7 +1016,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1032,6 +1032,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1111,6 +1112,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_p231_2g.dts b/arch/arm/boot/dts/amlogic/gxl_p231_2g.dts index 95e97dbd9967..0a35a0dfe4f7 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p231_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p231_2g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1015,7 +1015,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1031,6 +1031,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1110,6 +1111,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_p231_2g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p231_2g_buildroot.dts index 658cb5b7ed32..2365af310a9a 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p231_2g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p231_2g_buildroot.dts @@ -162,13 +162,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1084,7 +1084,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1100,6 +1100,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1179,6 +1180,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_p241_1g.dts b/arch/arm/boot/dts/amlogic/gxl_p241_1g.dts index 590b3c0198f8..feab09e7e205 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p241_1g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p241_1g.dts @@ -110,7 +110,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x4C00000>; + size = <0x2400000>; alignment = <0x400000>; alloc-ranges = <0x0 0x30000000>; }; @@ -257,13 +257,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1166,7 +1166,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1183,6 +1183,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1267,6 +1268,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p241_1g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p241_1g_buildroot.dts index f68d359c54d3..af46fd2edaec 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p241_1g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p241_1g_buildroot.dts @@ -235,13 +235,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1224,7 +1224,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1240,6 +1240,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1319,6 +1320,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p241_v2-1g.dts b/arch/arm/boot/dts/amlogic/gxl_p241_v2-1g.dts index f7cf504250b0..aa85f76b0ef2 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p241_v2-1g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p241_v2-1g.dts @@ -111,7 +111,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x4C00000>; + size = <0x2400000>; alignment = <0x400000>; alloc-ranges = <0x0 0x30000000>; }; @@ -257,13 +257,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1166,7 +1166,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1183,6 +1183,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1267,6 +1268,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts index 70808ebaf1f1..bd8fa63f3cc1 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts @@ -234,13 +234,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1223,7 +1223,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1239,6 +1239,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1318,6 +1319,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p400_2g.dts b/arch/arm/boot/dts/amlogic/gxl_p400_2g.dts index 8300389f44a1..46a4b3276009 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p400_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p400_2g.dts @@ -91,13 +91,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -743,7 +743,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -759,6 +759,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -838,6 +839,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_p401_2g.dts b/arch/arm/boot/dts/amlogic/gxl_p401_2g.dts index 6fa99b61e3f3..2bb9708797db 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p401_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p401_2g.dts @@ -91,13 +91,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -831,7 +831,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -847,6 +847,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -926,6 +927,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_sei210_1g.dts b/arch/arm/boot/dts/amlogic/gxl_sei210_1g.dts index d3220d565d5c..2f447c3deff0 100644 --- a/arch/arm/boot/dts/amlogic/gxl_sei210_1g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_sei210_1g.dts @@ -162,13 +162,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1075,7 +1075,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1092,6 +1092,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1176,6 +1177,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxl_sei210_2g.dts b/arch/arm/boot/dts/amlogic/gxl_sei210_2g.dts index 8f36cb84457e..f68747e8b572 100644 --- a/arch/arm/boot/dts/amlogic/gxl_sei210_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_sei210_2g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1085,7 +1085,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1102,6 +1102,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1186,6 +1187,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxl_skt.dts b/arch/arm/boot/dts/amlogic/gxl_skt.dts index 44914a81580e..5ace41afcb84 100644 --- a/arch/arm/boot/dts/amlogic/gxl_skt.dts +++ b/arch/arm/boot/dts/amlogic/gxl_skt.dts @@ -172,13 +172,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1081,7 +1081,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1098,6 +1098,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1182,6 +1183,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm/boot/dts/amlogic/gxm_q200_2g.dts b/arch/arm/boot/dts/amlogic/gxm_q200_2g.dts index 24022e74c347..722771f0e370 100644 --- a/arch/arm/boot/dts/amlogic/gxm_q200_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxm_q200_2g.dts @@ -162,13 +162,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1110,7 +1110,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1126,6 +1126,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1205,6 +1206,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxm_q200_2g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxm_q200_2g_buildroot.dts index acb411acd524..e695359c349b 100644 --- a/arch/arm/boot/dts/amlogic/gxm_q200_2g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxm_q200_2g_buildroot.dts @@ -154,13 +154,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1182,7 +1182,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1197,6 +1197,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -1271,6 +1272,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxm_q201_1g.dts b/arch/arm/boot/dts/amlogic/gxm_q201_1g.dts index e96da973279d..c1ac3945fdd6 100644 --- a/arch/arm/boot/dts/amlogic/gxm_q201_1g.dts +++ b/arch/arm/boot/dts/amlogic/gxm_q201_1g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1112,7 +1112,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1129,6 +1129,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1213,6 +1214,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/gxm_q201_2g.dts b/arch/arm/boot/dts/amlogic/gxm_q201_2g.dts index 12f3dc75b8c6..b70073f2e5c6 100644 --- a/arch/arm/boot/dts/amlogic/gxm_q201_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxm_q201_2g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1115,7 +1115,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1132,6 +1132,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1216,6 +1217,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm/boot/dts/amlogic/mesong12a.dtsi b/arch/arm/boot/dts/amlogic/mesong12a.dtsi index 900c68e57157..1be1e4e34299 100644 --- a/arch/arm/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm/boot/dts/amlogic/mesong12a.dtsi @@ -1240,6 +1240,7 @@ &clkc CLKID_DEMUX &clkc CLKID_AHB_ARB0 &clkc CLKID_DOS + &clkc CLKID_CLK81 &clkc CLKID_VDEC_MUX &clkc CLKID_HCODEC_MUX &clkc CLKID_HEVC_MUX @@ -1248,6 +1249,7 @@ "demux", "ahbarb0", "vdec", + "clk_81", "clk_vdec_mux", "clk_hcodec_mux", "clk_hevc_mux", @@ -2324,6 +2326,24 @@ }; }; + /*dvb_p_ts1_pins: dvb_p_ts1_pins { + * tsin_b { + * groups = "tsin_b_sop_z", + * "tsin_b_valid_z", + * "tsin_b_clk_z", + * "tsin_b_din0_z", + * "tsin_b_din1", + * "tsin_b_din2", + * "tsin_b_din3", + * "tsin_b_din4", + * "tsin_b_din5", + * "tsin_b_din6", + * "tsin_b_din7"; + * function = "tsin_b"; + * }; + *}; + */ + pwm_a_pins: pwm_a { mux { groups = "pwm_a"; diff --git a/arch/arm/boot/dts/amlogic/mesong12b.dtsi b/arch/arm/boot/dts/amlogic/mesong12b.dtsi index 78954ae8afd7..0ef83d40bf6a 100644 --- a/arch/arm/boot/dts/amlogic/mesong12b.dtsi +++ b/arch/arm/boot/dts/amlogic/mesong12b.dtsi @@ -1862,6 +1862,7 @@ reg-names = "ISP"; interrupts = <0 142 4>; interrupt-names = "ISP"; + temper-buf-size = <24>; clocks = <&clkc CLKID_MIPI_ISP_CLK_COMP>, <&clkc CLKID_MIPI_CSI_PHY_CLK0_COMP>; clock-names = "cts_mipi_isp_clk_composite", diff --git a/arch/arm/boot/dts/amlogic/mesontl1.dtsi b/arch/arm/boot/dts/amlogic/mesontl1.dtsi index 4cb13274269d..ed116df1b2bb 100644 --- a/arch/arm/boot/dts/amlogic/mesontl1.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontl1.dtsi @@ -1082,6 +1082,58 @@ compatible = "amlogic, vdac-tl1"; status = "okay"; }; + + dmc_monitor { + compatible = "amlogic, dmc_monitor"; + status = "okay"; + reg_base = <0xff638800>; + interrupts = ; + }; + + efuse: efuse{ + compatible = "amlogic, efuse"; + read_cmd = <0x82000030>; + write_cmd = <0x82000031>; + get_max_cmd = <0x82000033>; + key = <&efusekey>; + clocks = <&clkc CLKID_EFUSE>; + clock-names = "efuse_clk"; + status = "disabled"; + }; + + efusekey:efusekey{ + keynum = <4>; + key0 = <&key_0>; + key1 = <&key_1>; + key2 = <&key_2>; + key3 = <&key_3>; + key_0:key_0{ + keyname = "mac"; + offset = <0>; + size = <6>; + }; + key_1:key_1{ + keyname = "mac_bt"; + offset = <6>; + size = <6>; + }; + key_2:key_2{ + keyname = "mac_wifi"; + offset = <12>; + size = <6>; + }; + key_3:key_3{ + keyname = "usid"; + offset = <18>; + size = <16>; + }; + }; + + audio_data: audio_data { + compatible = "amlogic, audio_data"; + query_licence_cmd = <0x82000050>; + status = "disabled"; + }; }; /* end of / */ &pinctrl_aobus { diff --git a/arch/arm/boot/dts/amlogic/tl1_pxp.dts b/arch/arm/boot/dts/amlogic/tl1_pxp.dts index 2df2461aae66..aacb76768dc4 100644 --- a/arch/arm/boot/dts/amlogic/tl1_pxp.dts +++ b/arch/arm/boot/dts/amlogic/tl1_pxp.dts @@ -144,6 +144,32 @@ status = "disabled"; reg = <0xff632000 0x1c>; tdmout_index = <1>; + tdmin_index = <1>; + }; + + aml_dtv_demod { + compatible = "amlogic, ddemod-tl1"; + dev_name = "aml_dtv_demod"; + status = "okay"; + + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + reg = <0xff650000 0x4000 /*dtv demod base*/ + 0xff63c000 0x2000 /*hiu reg base*/ + 0xff800000 0x1000 /*io_aobus_base*/ + 0xffd01000 0x1000 /*reset*/ + >; + + /*move from dvbfe*/ + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + //memory-region = <&demod_cma_reserved>;//<&demod_reserved>; }; auge_sound { @@ -259,7 +285,7 @@ /* suffix-name, sync with android audio hal used for */ suffix-name = "alsaPORT-spdif"; cpu { - sound-dai = <&spdif_a>; + sound-dai = <&spdifa>; system-clock-frequency = <6144000>; }; codec { @@ -270,7 +296,7 @@ aml-audio-card,dai-link@5 { mclk-fs = <128>; cpu { - sound-dai = <&spdif_b>; + sound-dai = <&spdifb>; system-clock-frequency = <6144000>; }; codec { @@ -448,7 +474,7 @@ }; /* end of / */ &audiobus { - tdma:tdm { + tdma:tdm@0 { compatible = "amlogic, tl1-snd-tdma"; #sound-dai-cells = <0>; @@ -466,7 +492,7 @@ status = "okay"; }; - tdmb:tdm { + tdmb:tdm@1 { compatible = "amlogic, tl1-snd-tdmb"; #sound-dai-cells = <0>; @@ -481,7 +507,7 @@ status = "okay"; }; - tdmc:tdm { + tdmc:tdm@2 { compatible = "amlogic, tl1-snd-tdmc"; #sound-dai-cells = <0>; @@ -499,16 +525,16 @@ status = "okay"; }; - spdif_a:spdif { + spdifa:spdif@0 { compatible = "amlogic, tl1-snd-spdif-a"; #sound-dai-cells = <0>; clocks = <&clkc CLKID_MPLL0 &clkc CLKID_FCLK_DIV4 + &clkaudio CLKID_AUDIO_GATE_SPDIFIN + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A &clkaudio CLKID_AUDIO_SPDIFIN - &clkaudio CLKID_AUDIO_SPDIFOUT - &clkaudio CLKID_AUDIO_SPDIFIN_CTRL - &clkaudio CLKID_AUDIO_SPDIFOUT_CTRL>; + &clkaudio CLKID_AUDIO_SPDIFOUT_A>; clock-names = "sysclk", "fixed_clk", "gate_spdifin", "gate_spdifout", "clk_spdifin", "clk_spdifout"; @@ -519,16 +545,31 @@ pinctrl-names = "spdif_pins"; pinctrl-0 = <&spdifout_a &spdifin_a>; + /* + * whether do asrc for pcm and resample a or b + * if raw data, asrc is disabled automatically + * 0: "Disable", + * 1: "Enable:32K", + * 2: "Enable:44K", + * 3: "Enable:48K", + * 4: "Enable:88K", + * 5: "Enable:96K", + * 6: "Enable:176K", + * 7: "Enable:192K", + */ + asrc_id = <0>; + auto_asrc = <0>; + status = "okay"; }; - spdif_b:spdif { + spdifb:spdif@1 { compatible = "amlogic, tl1-snd-spdif-b"; #sound-dai-cells = <0>; clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/ - &clkaudio CLKID_AUDIO_SPDIFOUTB - &clkaudio CLKID_AUDIO_SPDIFOUTB_CTRL>; + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B + &clkaudio CLKID_AUDIO_SPDIFOUT_B>; clock-names = "sysclk", "gate_spdifout", "clk_spdifout"; @@ -539,7 +580,7 @@ compatible = "amlogic, tl1-snd-pdm"; #sound-dai-cells = <0>; - clocks = <&clkaudio CLKID_AUDIO_PDM + clocks = <&clkaudio CLKID_AUDIO_GATE_PDM &clkc CLKID_FCLK_DIV3 &clkc CLKID_MPLL3 &clkaudio CLKID_AUDIO_PDMIN0 @@ -570,6 +611,78 @@ status = "okay"; }; + aed:effect { + compatible = "amlogic, snd-effect-v2"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_EQDRC>; + clock-names = "gate", "clk_srcpll", "eqdrc"; + + eq_enable = <1>; + multiband_drc_enable = <0>; + fullband_drc_enable = <0>; + /* + * 0:tdmout_a + * 1:tdmout_b + * 2:tdmout_c + * 3:spdifout + * 4:spdifout_b + */ + eqdrc_module = <1>; + /* max 0xf, each bit for one lane, usually one lane */ + lane_mask = <0x1>; + /* max 0xff, each bit for one channel */ + channel_mask = <0x3>; + + status = "disabled"; + }; + + asrca: resample@0 { + compatible = "amlogic, tl1-resample-a"; + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_A>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + + asrcb: resample@1 { + compatible = "amlogic, tl1-resample-b"; + + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_B>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + }; /* end of audiobus */ &pinctrl_periphs { diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts new file mode 100644 index 000000000000..140070b93c3c --- /dev/null +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts @@ -0,0 +1,1419 @@ +/* + * arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +/dts-v1/; + +#include "mesontl1.dtsi" +#include "partition_mbox_normal_P_32.dtsi" +#include "mesontl1_skt-panel.dtsi" + +/ { + model = "Amlogic TL1 T962X2 SKT"; + amlogic-dt-id = "tl1_t962x2_skt"; + compatible = "amlogic, tl1_t962x2_skt"; + + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; + serial2 = &uart_B; + serial3 = &uart_C; + serial4 = &uart_AO_B; + tsensor0 = &p_tsensor; + tsensor1 = &d_tsensor; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c_AO; + }; + + memory@00000000 { + device_type = "memory"; + linux,usable-memory = <0x100000 0x7ff00000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + /* global autoconfigured region for contiguous allocations */ + secmon_reserved: linux,secmon { + compatible = "shared-dma-pool"; + reusable; + size = <0x400000>; + alignment = <0x400000>; + alloc-ranges = <0x05000000 0x400000>; + }; + + codec_mm_cma:linux,codec_mm_cma { + compatible = "shared-dma-pool"; + reusable; + /* ion_codec_mm max can alloc size 80M*/ + size = <0x13400000>; + alignment = <0x400000>; + linux,contiguous-region; + alloc-ranges = <0x12000000 0x13400000>; + }; + + /* codec shared reserved */ + codec_mm_reserved:linux,codec_mm_reserved { + compatible = "amlogic, codec-mm-reserved"; + size = <0x0>; + alignment = <0x100000>; + //no-map; + }; + + logo_reserved:linux,meson-fb { + compatible = "shared-dma-pool"; + reusable; + size = <0x800000>; + alignment = <0x400000>; + alloc-ranges = <0x7f800000 0x800000>; + }; + + ion_cma_reserved:linux,ion-dev { + compatible = "shared-dma-pool"; + reusable; + size = <0x8000000>; + alignment = <0x400000>; + }; + + /* vdin0 CMA pool */ + //vdin0_cma_reserved:linux,vdin0_cma { + // compatible = "shared-dma-pool"; + // reusable; + /* 3840x2160x4x4 ~=128 M */ + // size = <0xc400000>; + // alignment = <0x400000>; + //}; + + /* vdin1 CMA pool */ + vdin1_cma_reserved:linux,vdin1_cma { + compatible = "shared-dma-pool"; + reusable; + /* 1920x1080x2x4 =16 M */ + size = <0x1400000>; + alignment = <0x400000>; + }; + + /* for hdmi rx emp use */ + hdmirx_emp_cma_reserved:linux,emp_cma { + compatible = "shared-dma-pool"; + /*linux,phandle = <5>;*/ + reusable; + /* 4M for emp to ddr */ + /* 32M for tmds to ddr */ + size = <0x2000000>; + alignment = <0x400000>; + /* alloc-ranges = <0x400000 0x2000000>; */ + }; + + /* POST PROCESS MANAGER */ + ppmgr_reserved:linux,ppmgr { + compatible = "amlogic, ppmgr_memory"; + size = <0x0>; + }; + }; /* end of reserved-memory */ + + codec_mm { + compatible = "amlogic, codec, mm"; + status = "okay"; + memory-region = <&codec_mm_cma &codec_mm_reserved>; + }; + + ppmgr { + compatible = "amlogic, ppmgr"; + memory-region = <&ppmgr_reserved>; + status = "okay"; + }; + + vout { + compatible = "amlogic, vout"; + status = "okay"; + fr_auto_policy = <0>; + }; + + /* Audio Related start */ + pdm_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, pdm_dummy_codec"; + status = "okay"; + }; + + dummy_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, aml_dummy_codec"; + status = "okay"; + }; + + tl1_codec:codec { + #sound-dai-cells = <0>; + compatible = "amlogic, tl1_acodec"; + status = "okay"; + reg = <0xff632000 0x1c>; + tdmout_index = <0>; + tdmin_index = <0>; + }; + + auge_sound { + compatible = "amlogic, tl1-sound-card"; + aml-audio-card,name = "AML-AUGESOUND"; + + aml-audio-card,dai-link@0 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdma>; + frame-master = <&tdma>; + /* slave mode */ + /* + * bitclock-master = <&tdmacodec>; + * frame-master = <&tdmacodec>; + */ + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pcm"; + tdmacpu: cpu { + sound-dai = <&tdma>; + dai-tdm-slot-tx-mask = + <1 1>; + dai-tdm-slot-rx-mask = + <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmacodec: codec { + //sound-dai = <&dummy_codec>; + sound-dai = <&tl1_codec>; + }; + }; + + aml-audio-card,dai-link@1 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmb>; + frame-master = <&tdmb>; + /* slave mode */ + //bitclock-master = <&tdmbcodec>; + //frame-master = <&tdmbcodec>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-i2s"; + cpu { + sound-dai = <&tdmb>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + /* + * dai-tdm-slot-tx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-rx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-num = <8>; + */ + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmbcodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@2 { + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmc>; + frame-master = <&tdmc>; + /* slave mode */ + //bitclock-master = <&tdmccodec>; + //frame-master = <&tdmccodec>; + /* suffix-name, sync with android audio hal used for */ + //suffix-name = "alsaPORT-tdm"; + cpu { + sound-dai = <&tdmc>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmccodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@3 { + mclk-fs = <64>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pdm"; + cpu { + sound-dai = <&pdm>; + }; + codec { + sound-dai = <&pdm_codec>; + }; + }; + + aml-audio-card,dai-link@4 { + mclk-fs = <128>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-spdif"; + cpu { + sound-dai = <&spdifa>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@5 { + mclk-fs = <128>; + cpu { + sound-dai = <&spdifb>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@6 { + mclk-fs = <256>; + cpu { + sound-dai = <&extn>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + }; + + /* Audio Related end */ + dvb { + compatible = "amlogic, dvb"; + status = "okay"; + fe0_mode = "internal"; + fe0_tuner = <&tuner>; + + /*"parallel","serial","disable"*/ + ts2 = "parallel"; + ts2_control = <0>; + ts2_invert = <0>; + interrupts = <0 23 1 + 0 5 1 + 0 53 1 + 0 19 1 + 0 25 1 + 0 17 1>; + interrupt-names = "demux0_irq", + "demux1_irq", + "demux2_irq", + "dvr0_irq", + "dvr1_irq", + "dvr2_irq"; + clocks = <&clkc CLKID_DEMUX + &clkc CLKID_ASYNC_FIFO + &clkc CLKID_AHB_ARB0 + /*&clkc CLKID_DOS_PARSER>;*/ + &clkc CLKID_U_PARSER>; + clock-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; + }; + + tvafe_avin_detect { + compatible = "amlogic, tl1_tvafe_avin_detect"; + status = "okay"; + device_mask = <1>;/*bit0:ch1;bit1:ch2*/ + interrupts = <0 12 1>, + <0 13 1>; + }; + + amlvecm { + compatible = "amlogic, vecm"; + dev_name = "aml_vecm"; + status = "okay"; + gamma_en = <1>;/*1:enabel ;0:disable*/ + wb_en = <1>;/*1:enabel ;0:disable*/ + cm_en = <1>;/*1:enabel ;0:disable*/ + wb_sel = <1>;/*1:mtx ;0:gainoff*/ + vlock_en = <1>;/*1:enable;0:disable*/ + vlock_mode = <0x4>; + /* vlock work mode: + *bit0:auto ENC + *bit1:auto PLL + *bit2:manual PLL + *bit3:manual ENC + *bit4:manual soft ENC + *bit5:manual MIX PLL ENC + */ + vlock_pll_m_limit = <1>; + vlock_line_limit = <3>; + }; + + vdin@0 { + compatible = "amlogic, vdin"; + /*memory-region = <&vdin0_cma_reserved>;*/ + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0x101>; + /*MByte, if 10bit disable: 64M(YUV422), + *if 10bit enable: 64*1.5 = 96M(YUV422) + *if support 4K2K-YUV444-10bit-WR:3840*2160*4*4 ~= 128M + *if support 4K2K-YUV422-10bit-wr:3840*2160*3*4 ~= 96M + *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M + *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M + */ + cma_size = <190>; + interrupts = <0 83 1>; + rdma-irq = <2>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <0>; + /*vdin write mem color depth support: + * bit0:support 8bit + * bit1:support 9bit + * bit2:support 10bit + * bit3:support 12bit + * bit4:support yuv422 10bit full pack mode (from txl new add) + * bit8:use 8bit at 4k_50/60hz_10bit + * bit9:use 10bit at 4k_50/60hz_10bit + */ + tv_bit_mode = <0x215>; + /* afbce_bit_mode: (amlogic frame buff compression encoder) + * 0: normal mode, not use afbce + * 1: use afbce non-mmu mode + * 2: use afbce mmu mode + */ + afbce_bit_mode = <0>; + }; + + vdin@1 { + compatible = "amlogic, vdin"; + memory-region = <&vdin1_cma_reserved>; + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0>; + interrupts = <0 85 1>; + rdma-irq = <4>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <1>; + /*vdin write mem color depth support: + *bit0:support 8bit + *bit1:support 9bit + *bit2:support 10bit + *bit3:support 12bit + */ + tv_bit_mode = <0x15>; + }; + + unifykey { + compatible = "amlogic, unifykey"; + status = "okay"; + + unifykey-num = <19>; + unifykey-index-0 = <&keysn_0>; + unifykey-index-1 = <&keysn_1>; + unifykey-index-2 = <&keysn_2>; + unifykey-index-3 = <&keysn_3>; + unifykey-index-4 = <&keysn_4>; + unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; + unifykey-index-7 = <&keysn_7>; + unifykey-index-8 = <&keysn_8>; + unifykey-index-9 = <&keysn_9>; + unifykey-index-10= <&keysn_10>; + unifykey-index-11 = <&keysn_11>; + unifykey-index-12 = <&keysn_12>; + unifykey-index-13 = <&keysn_13>; + unifykey-index-14 = <&keysn_14>; + unifykey-index-15 = <&keysn_15>; + unifykey-index-16 = <&keysn_16>; + unifykey-index-17 = <&keysn_17>; + unifykey-index-18 = <&keysn_18>; + + keysn_0: key_0{ + key-name = "usid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_1:key_1{ + key-name = "mac"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_2:key_2{ + key-name = "hdcp"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_3:key_3{ + key-name = "secure_boot_set"; + key-device = "efuse"; + key-permit = "write"; + }; + keysn_4:key_4{ + key-name = "mac_bt"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_5:key_5{ + key-name = "mac_wifi"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_6:key_6{ + key-name = "hdcp2_tx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_7:key_7{ + key-name = "hdcp2_rx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_8:key_8{ + key-name = "widevinekeybox"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_9:key_9{ + key-name = "deviceid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_10:key_10{ + key-name = "hdcp22_fw_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_11:key_11{ + key-name = "hdcp22_rx_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_12:key_12{ + key-name = "hdcp22_rx_fw"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_13:key_13{ + key-name = "hdcp14_rx"; + key-device = "normal"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_14:key_14{ + key-name = "prpubkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_15:key_15{ + key-name = "prprivkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_16:key_16{ + key-name = "lcd"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_17:key_17{ + key-name = "lcd_extern"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_18:key_18{ + key-name = "backlight"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + }; /* End unifykey */ + + hdmirx { + compatible = "amlogic, hdmirx_tl1"; + #address-cells=<1>; + #size-cells=<1>; + memory-region = <&hdmirx_emp_cma_reserved>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmirx_a_mux &hdmirx_b_mux + &hdmirx_c_mux>; + repeat = <0>; + interrupts = <0 56 1>; + clocks = <&clkc CLKID_HDMIRX_MODET_COMP>, + <&clkc CLKID_HDMIRX_CFG_COMP>, + <&clkc CLKID_HDMIRX_ACR_COMP>, + <&clkc CLKID_HDMIRX_METER_COMP>, + <&xtal>, + <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV7>, + <&clkc CLKID_HDCP22_SKP_COMP>, + <&clkc CLKID_HDCP22_ESM_COMP>; + // <&clkc CLK_AUD_PLL2FS>, + // <&clkc CLK_AUD_PLL4FS>, + // <&clkc CLK_AUD_OUT>; + clock-names = "hdmirx_modet_clk", + "hdmirx_cfg_clk", + "hdmirx_acr_ref_clk", + "cts_hdmirx_meter_clk", + "xtal", + "fclk_div5", + "fclk_div7", + "hdcp_rx22_skp", + "hdcp_rx22_esm"; + // "hdmirx_aud_pll2fs", + // "hdmirx_aud_pll4f", + // "clk_aud_out"; + hdmirx_id = <0>; + en_4k_2_2k = <0>; + hpd_low_cec_off = <1>; + /* bit4: enable feature, bit3~0: port number */ + disable_port = <0x0>; + /* MAP_ADDR_MODULE_CBUS */ + /* MAP_ADDR_MODULE_HIU */ + /* MAP_ADDR_MODULE_HDMIRX_CAPB3 */ + /* MAP_ADDR_MODULE_SEC_AHB */ + /* MAP_ADDR_MODULE_SEC_AHB2 */ + /* MAP_ADDR_MODULE_APB4 */ + /* MAP_ADDR_MODULE_TOP */ + reg = < 0x0 0x0 + 0xff63C000 0x2000 + 0xffe0d000 0x2000 + 0x0 0x0 + 0x0 0x0 + 0x0 0x0 + 0xff610000 0xa000>; + }; + + aocec: aocec { + compatible = "amlogic, aocec-tl1"; + /*device_name = "aocec";*/ + status = "okay"; + vendor_name = "Amlogic"; /* Max Chars: 8 */ + /* Refer to the following URL at: + * http://standards.ieee.org/develop/regauth/oui/oui.txt + */ + vendor_id = <0x000000>; + product_desc = "TL1"; /* Max Chars: 16 */ + cec_osd_string = "AML_TV"; /* Max Chars: 14 */ + port_num = <3>; + ee_cec; + arc_port_mask = <0x2>; + interrupts = <0 205 1 + 0 199 1>; + interrupt-names = "hdmi_aocecb","hdmi_aocec"; + pinctrl-names = "default","hdmitx_aocecb","cec_pin_sleep"; + pinctrl-0=<&aoceca_mux>; + pinctrl-1=<&aocecb_mux>; + pinctrl-2=<&aoceca_mux>; + reg = <0xFF80023c 0x4 + 0xFF800000 0x400>; + reg-names = "ao_exit","ao"; + }; + + p_tsensor: p_tsensor@ff634800 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634800 0x50>, + <0xff800268 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 35 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + d_tsensor: d_tsensor@ff634c00 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634c00 0x50>, + <0xff800230 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 36 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + meson_cooldev: meson-cooldev@0 { + status = "okay"; + compatible = "amlogic, meson-cooldev"; + cooling_devices { + cpufreq_cool_cluster0 { + min_state = <1000000>; + dyn_coeff = <115>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpufreq_cool0"; + device_type = "cpufreq"; + }; + cpucore_cool_cluster0 { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpucore_cool0"; + device_type = "cpucore"; + }; + gpufreq_cool { + min_state = <400>; + dyn_coeff = <358>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpufreq_cool0"; + device_type = "gpufreq"; + }; + gpucore_cool { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpucore_cool0"; + device_type = "gpucore"; + }; + }; + cpufreq_cool0:cpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + cpucore_cool0:cpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpufreq_cool0:gpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpucore_cool0:gpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + };/*meson cooling devices end*/ + + thermal-zones { + pll_thermal: pll_thermal { + polling-delay = <1000>; + polling-delay-passive = <100>; + sustainable-power = <1410>; + thermal-sensors = <&p_tsensor 0>; + trips { + pswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + pcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + phot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + pcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + cooling-maps { + cpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&cpufreq_cool0 0 4>; + contribution = <1024>; + }; + gpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&gpufreq_cool0 0 4>; + contribution = <1024>; + }; + }; + }; + ddr_thermal: ddr_thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + sustainable-power = <1460>; + thermal-sensors = <&d_tsensor 1>; + trips { + dswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + dcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + dhot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + dcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + };/*thermal zone end*/ + + /*DCDC for MP8756GD*/ + cpu_opp_table0: cpu_opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + opp01 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + opp02 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + opp03 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <761000>; + }; + opp04 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <791000>; + }; + opp05 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <801000>; + }; + opp06 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <831000>; + }; + opp07 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <861000>; + }; + opp08 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <891000>; + }; + opp09 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <921000>; + }; + opp10 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <981000>; + }; + opp11 { + opp-hz = /bits/ 64 <1908000000>; + opp-microvolt = <1011000>; + }; + }; + + cpufreq-meson { + compatible = "amlogic, cpufreq-meson"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_ao_d_pins3>; + status = "okay"; + }; + + tuner: tuner { + status = "okay"; + tuner_name = "mxl661_tuner"; + tuner_i2c_adap = <&i2c0>; + tuner_i2c_addr = <0x60>; + tuner_xtal = <1>; /* 0: 16MHz, 1: 24MHz */ + tuner_xtal_mode = <3>; + /* NO_SHARE_XTAL(0) + * SLAVE_XTAL_SHARE(3) + */ + tuner_xtal_cap = <25>; /* when tuner_xtal_mode = 3, set 25 */ + }; + + bt-dev{ + compatible = "amlogic, bt-dev"; + status = "okay"; + gpio_reset = <&gpio GPIOC_13 GPIO_ACTIVE_HIGH>; + }; + + wifi{ + compatible = "amlogic, aml_wifi"; + status = "okay"; + interrupt_pin = <&gpio GPIOC_12 GPIO_ACTIVE_HIGH>; + irq_trigger_type = "GPIO_IRQ_LOW"; + dhd_static_buf; //dhd_static_buf support + power_on_pin = <&gpio GPIOC_11 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_b_pins1>; + pwm_config = <&wifi_pwm_conf>; + }; + + wifi_pwm_conf:wifi_pwm_conf{ + pwm_channel1_conf { + pwms = <&pwm_ab MESON_PWM_1 30040 0>; + duty-cycle = <15020>; + times = <8>; + }; + pwm_channel2_conf { + pwms = <&pwm_ab MESON_PWM_3 30030 0>; + duty-cycle = <15015>; + times = <12>; + }; + }; + +}; /* end of / */ + +&i2c0 { + status = "okay"; + clock-frequency = <300000>; + pinctrl-names="default"; + pinctrl-0=<&i2c0_dv_pins>; +}; + +&audiobus { + tdma:tdm@0 { + compatible = "amlogic, tl1-snd-tdma"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0>; + dai-tdm-lane-slot-mask-out = <1 0>; + dai-tdm-clk-sel = <0>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_A + &clkc CLKID_MPLL0>; + clock-names = "mclk", "clk_srcpll"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdma_mclk &tdmout_a &tdmin_a>; + + status = "okay"; + }; + + tdmb:tdm@1 { + compatible = "amlogic, tl1-snd-tdmb"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <1>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_B + &clkc CLKID_MPLL1>; + clock-names = "mclk", "clk_srcpll"; + + status = "okay"; + }; + + tdmc:tdm@2 { + compatible = "amlogic, tl1-snd-tdmc"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <2>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdmout_c &tdmin_c>; + + status = "okay"; + }; + + spdifa:spdif@0 { + compatible = "amlogic, tl1-snd-spdif-a"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 + &clkc CLKID_FCLK_DIV4 + &clkaudio CLKID_AUDIO_GATE_SPDIFIN + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A + &clkaudio CLKID_AUDIO_SPDIFIN + &clkaudio CLKID_AUDIO_SPDIFOUT_A>; + clock-names = "sysclk", "fixed_clk", "gate_spdifin", + "gate_spdifout", "clk_spdifin", "clk_spdifout"; + + interrupts = + ; + interrupt-names = "irq_spdifin"; + + pinctrl-names = "spdif_pins"; + pinctrl-0 = <&spdifout_a &spdifin_a>; + + /* + * whether do asrc for pcm and resample a or b + * if raw data, asrc is disabled automatically + * 0: "Disable", + * 1: "Enable:32K", + * 2: "Enable:44K", + * 3: "Enable:48K", + * 4: "Enable:88K", + * 5: "Enable:96K", + * 6: "Enable:176K", + * 7: "Enable:192K", + */ + asrc_id = <0>; + auto_asrc = <0>; + + status = "okay"; + }; + + spdifb:spdif@1 { + compatible = "amlogic, tl1-snd-spdif-b"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/ + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B + &clkaudio CLKID_AUDIO_SPDIFOUT_B>; + clock-names = "sysclk", + "gate_spdifout", "clk_spdifout"; + + status = "okay"; + }; + + pdm:pdm { + compatible = "amlogic, tl1-snd-pdm"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_PDM + &clkc CLKID_FCLK_DIV3 + &clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_PDMIN0 + &clkaudio CLKID_AUDIO_PDMIN1>; + clock-names = "gate", + "sysclk_srcpll", + "dclk_srcpll", + "pdm_dclk", + "pdm_sysclk"; + + pinctrl-names = "pdm_pins"; + pinctrl-0 = <&pdmin>; + + /* mode 0~4, defalut:1 */ + filter_mode = <1>; + + status = "okay"; + }; + + extn:extn { + compatible = "amlogic, snd-extn"; + #sound-dai-cells = <0>; + + interrupts = + ; + interrupt-names = "irq_frhdmirx"; + + status = "okay"; + }; + + aed:effect { + compatible = "amlogic, snd-effect-v2"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_EQDRC>; + clock-names = "gate", "srcpll", "eqdrc"; + + eq_enable = <1>; + multiband_drc_enable = <0>; + fullband_drc_enable = <0>; + /* + * 0:tdmout_a + * 1:tdmout_b + * 2:tdmout_c + * 3:spdifout + * 4:spdifout_b + */ + eqdrc_module = <0>; + /* max 0xf, each bit for one lane, usually one lane */ + lane_mask = <0x1>; + /* max 0xff, each bit for one channel */ + channel_mask = <0x3>; + + status = "okay"; + }; + + asrca: resample@0 { + compatible = "amlogic, tl1-resample-a"; + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_A>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + + asrcb: resample@1 { + compatible = "amlogic, tl1-resample-b"; + + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_B>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + + vad:vad { + compatible = "amlogic, snd-vad"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_VAD>; + clock-names = "gate", "pll", "clk"; + + interrupts = ; + interrupt-names = "irq_wakeup", "irq_frame_sync"; + + /* + * Data src sel: + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + * 5: loopback_b; + * 6: tdmin_lb; + * 7: loopback_a; + */ + src = <4>; + + status = "disabled"; + }; +}; /* end of audiobus */ + +&pinctrl_periphs { + /* audio pin mux */ + + tdma_mclk: tdma_mclk { + mux { /* GPIOZ_0 */ + groups = "mclk0_z"; + function = "mclk0"; + }; + }; + + tdmout_a: tdmout_a { + mux { /* GPIOZ_1, GPIOZ_2, GPIOZ_3, GPIOZ_5, GPIOZ_6 */ + groups = "tdma_sclk_z", + "tdma_fs_z", + "tdma_dout0_z", + "tdma_dout2_z", + "tdma_dout3_z"; + function = "tdma_out"; + }; + }; + + tdmin_a: tdmin_a { + mux { /* GPIOZ_9 */ + groups = "tdma_din2_z"; + function = "tdma_in"; + }; + }; +#if 0 //verify tdm/i2s in + tdmin_a: tdmin_a { + mux { /* GPIOZ_7 */ + groups = "tdma_din0_z"; + function = "tdma_in"; + }; + }; +#endif + tdmout_c: tdmout_c { + mux { /* GPIODV_7, GPIODV_8, GPIODV_9 */ + groups = "tdmc_sclk", + "tdmc_fs", + "tdmc_dout0"; + function = "tdmc_out"; + }; + }; + + tdmin_c: tdmin_c { + mux { /* GPIODV_10 */ + groups = "tdmc_din1"; + function = "tdmc_in"; + }; + }; + + spdifin_a: spdifin_a { + mux { /* GPIODV_5 */ + groups = "spdif_in"; + function = "spdif_in"; + }; + }; + + spdifout_a: spdifout_a { + mux { /* GPIODV_4 */ + groups = "spdif_out_dv4"; + function = "spdif_out"; + }; + }; + + pdmin: pdmin { + mux { /* GPIOZ_7, GPIOZ_8, pdm_din2_z4 */ + groups = "pdm_dclk_z", + "pdm_din0_z", + "pdm_din2_z4"; + function = "pdm"; + }; + }; + + +}; /* end of pinctrl_periphs */ + +&pinctrl_aobus { + spdifout: spdifout { + mux { /* gpiao_10 */ + groups = "spdif_out_ao"; + function = "spdif_out_ao"; + }; + }; +}; /* end of pinctrl_aobus */ + +&audio_data{ + status = "okay"; +}; + +&sd_emmc_c { + status = "okay"; + emmc { + caps = "MMC_CAP_8_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", + /* "MMC_CAP_1_8V_DDR", */ + "MMC_CAP_HW_RESET", + "MMC_CAP_ERASE", + "MMC_CAP_CMD23"; + caps2 = "MMC_CAP2_HS200"; + /* "MMC_CAP2_HS400";*/ + f_min = <400000>; + f_max = <200000000>; + }; +}; + +&sd_emmc_b { + status = "okay"; + sd { + caps = "MMC_CAP_4_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE"; /**ptm debug */ + f_min = <400000>; + f_max = <200000000>; + }; +}; + +&spifc { + status = "disabled"; + spi-nor@0 { + cs_gpios = <&gpio BOOT_13 GPIO_ACTIVE_HIGH>; + }; +}; + +&slc_nand { + status = "disabled"; + plat-names = "bootloader", "nandnormal"; + plat-num = <2>; + plat-part-0 = <&bootloader>; + plat-part-1 = <&nandnormal>; + bootloader: bootloader{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <1>; + part_num = <0>; + rb_detect = <1>; + }; + nandnormal: nandnormal{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + plane_mode = "twoplane"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <2>; + part_num = <3>; + partition = <&nand_partitions>; + rb_detect = <1>; + }; + nand_partitions:nand_partition{ + /* + * if bl_mode is 1, tpl size was generate by + * fip_copies * fip_size which + * will not skip bad when calculating + * the partition size; + * + * if bl_mode is 0, + * tpl partition must be comment out. + */ + tpl{ + offset=<0x0 0x0>; + size=<0x0 0x0>; + }; + logo{ + offset=<0x0 0x0>; + size=<0x0 0x200000>; + }; + recovery{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + boot{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + system{ + offset=<0x0 0x0>; + size=<0x0 0x4000000>; + }; + data{ + offset=<0xffffffff 0xffffffff>; + size=<0x0 0x0>; + }; + }; +}; + +ðmac { + status = "okay"; + pinctrl-names = "internal_eth_pins"; + pinctrl-0 = <&internal_eth_pins>; + mc_val = <0x4be04>; + + internal_phy=<1>; +}; + +&uart_A { + status = "okay"; +}; + +&dwc3 { + status = "okay"; +}; + +&usb2_phy_v2 { + status = "okay"; + portnum = <3>; +}; + +&usb3_phy_v2 { + status = "okay"; + portnum = <0>; + otg = <0>; +}; + +&dwc2_a { + status = "okay"; + /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ + controller-type = <1>; +}; + +&spicc0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spicc0_pins_h>; + cs-gpios = <&gpio GPIOH_20 0>; +}; + +&meson_fb { + status = "okay"; + display_size_default = <1920 1080 1920 2160 32>; + mem_size = <0x00800000 0x1980000 0x100000 0x800000>; + logo_addr = "0x7f800000"; + mem_alloc = <0>; + pxp_mode = <0>; /** 0:normal mode 1:pxp mode */ +}; + +&pwm_AO_cd { + status = "okay"; +}; + +&saradc { + status = "okay"; +}; + +&pwm_ab { + status = "okay"; +}; + +&efuse { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts new file mode 100644 index 000000000000..355d25ee4d92 --- /dev/null +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts @@ -0,0 +1,1776 @@ +/* + * arch/arm/boot/dts/amlogic/tl1_t962x2_t309.dts + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +/dts-v1/; + +#include "mesontl1.dtsi" +#include "partition_mbox_normal_P_32.dtsi" +#include "mesontl1_t309-panel.dtsi" + +/ { + model = "Amlogic TL1 T962X2 T309"; + amlogic-dt-id = "tl1_t962x2_t309"; + compatible = "amlogic, tl1_t962x2_t309"; + + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; + serial2 = &uart_B; + serial3 = &uart_C; + serial4 = &uart_AO_B; + tsensor0 = &p_tsensor; + tsensor1 = &d_tsensor; + tsensor2 = &s_tsensor; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c_AO; + }; + + memory@00000000 { + device_type = "memory"; + linux,usable-memory = <0x100000 0x7ff00000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + /* global autoconfigured region for contiguous allocations */ + secmon_reserved: linux,secmon { + compatible = "shared-dma-pool"; + reusable; + size = <0x400000>; + alignment = <0x400000>; + alloc-ranges = <0x05000000 0x400000>; + }; + + codec_mm_cma:linux,codec_mm_cma { + compatible = "shared-dma-pool"; + reusable; + /* ion_codec_mm max can alloc size 80M*/ + size = <0x13400000>; + alignment = <0x400000>; + linux,contiguous-region; + alloc-ranges = <0x12000000 0x13400000>; + }; + + /* codec shared reserved */ + codec_mm_reserved:linux,codec_mm_reserved { + compatible = "amlogic, codec-mm-reserved"; + size = <0x0>; + alignment = <0x100000>; + //no-map; + }; + + logo_reserved:linux,meson-fb { + compatible = "shared-dma-pool"; + reusable; + size = <0x800000>; + alignment = <0x400000>; + alloc-ranges = <0x7f800000 0x800000>; + }; + + lcd_tcon_reserved:linux,lcd_tcon { + compatible = "shared-dma-pool"; + reusable; + size = <0xc00000>; + alignment = <0x400000>; + alloc-ranges = <0x71000000 0xc00000>; + }; + + ion_cma_reserved:linux,ion-dev { + compatible = "shared-dma-pool"; + reusable; + size = <0x8000000>; + alignment = <0x400000>; + }; + + /* vdin0 CMA pool */ + //vdin0_cma_reserved:linux,vdin0_cma { + // compatible = "shared-dma-pool"; + // reusable; + /* 3840x2160x4x4 ~=128 M */ + // size = <0xc400000>; + // alignment = <0x400000>; + //}; + + /* vdin1 CMA pool */ + vdin1_cma_reserved:linux,vdin1_cma { + compatible = "shared-dma-pool"; + reusable; + /* 1920x1080x2x4 =16 M */ + size = <0x1400000>; + alignment = <0x400000>; + }; + + /*demod_reserved:linux,demod { + * compatible = "amlogic, demod-mem"; + * size = <0x800000>; //8M //100m 0x6400000 + * alloc-ranges = <0x0 0x30000000>; + * //multi-use; + * //no-map; + *}; + */ + + demod_cma_reserved:linux,demod_cma { + compatible = "shared-dma-pool"; + reusable; + /* 8M */ + size = <0x0800000>; + alignment = <0x400000>; + }; + + /*vbi reserved mem*/ + vbi_reserved:linux,vbi { + compatible = "amlogic, vbi-mem"; + size = <0x100000>; + alloc-ranges = <0x0e000000 0x800000>; + }; + + /*di CMA pool */ + di_cma_reserved:linux,di_cma { + compatible = "shared-dma-pool"; + reusable; + /* buffer_size = 3621952(yuv422 8bit) + * | 4736064(yuv422 10bit) + * | 4074560(yuv422 10bit full pack mode) + * 10x3621952=34.6M(0x23) support 8bit + * 10x4736064=45.2M(0x2e) support 12bit + * 10x4074560=40M(0x28) support 10bit + */ + size = <0x02800000>; + alignment = <0x400000>; + }; + + /* for hdmi rx emp use */ + hdmirx_emp_cma_reserved:linux,emp_cma { + compatible = "shared-dma-pool"; + /*linux,phandle = <5>;*/ + reusable; + /* 4M for emp to ddr */ + /* 32M for tmds to ddr */ + size = <0x2000000>; + alignment = <0x400000>; + /* alloc-ranges = <0x400000 0x2000000>; */ + }; + + /* POST PROCESS MANAGER */ + ppmgr_reserved:linux,ppmgr { + compatible = "amlogic, ppmgr_memory"; + size = <0x0>; + }; + }; /* end of reserved-memory */ + + codec_mm { + compatible = "amlogic, codec, mm"; + status = "okay"; + memory-region = <&codec_mm_cma &codec_mm_reserved>; + }; + + ppmgr { + compatible = "amlogic, ppmgr"; + memory-region = <&ppmgr_reserved>; + status = "okay"; + }; + + deinterlace { + compatible = "amlogic, deinterlace"; + status = "okay"; + /* 0:use reserved; 1:use cma; 2:use cma as reserved */ + flag_cma = <1>; + //memory-region = <&di_reserved>; + memory-region = <&di_cma_reserved>; + interrupts = <0 46 1 + 0 40 1>; + interrupt-names = "pre_irq", "post_irq"; + clocks = <&clkc CLKID_VPU_CLKB_TMP_COMP>, + <&clkc CLKID_VPU_CLKB_COMP>; + clock-names = "vpu_clkb_tmp_composite", + "vpu_clkb_composite"; + clock-range = <334 667>; + /* buffer-size = <3621952>;(yuv422 8bit) */ + buffer-size = <4074560>;/*yuv422 fullpack*/ + /* reserve-iomap = "true"; */ + /* if enable nr10bit, set nr10bit-support to 1 */ + post-wr-support = <1>; + nr10bit-support = <1>; + nrds-enable = <1>; + pps-enable = <1>; + }; + + vout { + compatible = "amlogic, vout"; + status = "okay"; + fr_auto_policy = <0>; + }; + + /* Audio Related start */ + pdm_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, pdm_dummy_codec"; + status = "okay"; + }; + + dummy_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, aml_dummy_codec"; + status = "okay"; + }; + + tl1_codec:codec { + #sound-dai-cells = <0>; + compatible = "amlogic, tl1_acodec"; + status = "okay"; + reg = <0xff632000 0x1c>; + tdmout_index = <0>; + tdmin_index = <0>; + dat1_ch_sel = <1>; + }; + + aml_dtv_demod { + compatible = "amlogic, ddemod-tl1"; + dev_name = "aml_dtv_demod"; + status = "okay"; + + //pinctrl-names="dtvdemod_agc"; + //pinctrl-0=<&dtvdemod_agc>; + + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + + reg = <0xff650000 0x4000 /*dtv demod base*/ + 0xff63c000 0x2000 /*hiu reg base*/ + 0xff800000 0x1000 /*io_aobus_base*/ + 0xffd01000 0x1000 /*reset*/ + >; + + dtv_demod0_mem = <0>; // need move to aml_dtv_demod ? + spectrum = <1>; + cma_flag = <1>; + cma_mem_size = <8>; + memory-region = <&demod_cma_reserved>;//<&demod_reserved>; + }; + + auge_sound { + compatible = "amlogic, tl1-sound-card"; + aml-audio-card,name = "AML-AUGESOUND"; + + avout_mute-gpios = <&gpio GPIODV_3 GPIO_ACTIVE_HIGH>; + + aml-audio-card,dai-link@0 { + format = "i2s"; + mclk-fs = <256>; + continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdma>; + frame-master = <&tdma>; + /* slave mode */ + /* + * bitclock-master = <&tdmacodec>; + * frame-master = <&tdmacodec>; + */ + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-i2s"; + tdmacpu: cpu { + sound-dai = <&tdma>; + dai-tdm-slot-tx-mask = + <1 1>; + dai-tdm-slot-rx-mask = + <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmacodec: codec { + //sound-dai = <&dummy_codec>; + sound-dai = <&ad82584f &tl1_codec>; + }; + }; + + aml-audio-card,dai-link@1 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmb>; + frame-master = <&tdmb>; + /* slave mode */ + //bitclock-master = <&tdmbcodec>; + //frame-master = <&tdmbcodec>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pcm"; + cpu { + sound-dai = <&tdmb>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + /* + * dai-tdm-slot-tx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-rx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-num = <8>; + */ + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmbcodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@2 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmc>; + frame-master = <&tdmc>; + /* slave mode */ + //bitclock-master = <&tdmccodec>; + //frame-master = <&tdmccodec>; + /* suffix-name, sync with android audio hal used for */ + //suffix-name = "alsaPORT-tdm"; + cpu { + sound-dai = <&tdmc>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmccodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@3 { + mclk-fs = <64>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pdm"; + cpu { + sound-dai = <&pdm>; + }; + codec { + sound-dai = <&pdm_codec>; + }; + }; + + aml-audio-card,dai-link@4 { + mclk-fs = <128>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-spdif"; + cpu { + sound-dai = <&spdifa>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@5 { + mclk-fs = <128>; + cpu { + sound-dai = <&spdifb>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@6 { + mclk-fs = <256>; + suffix-name = "alsaPORT-tv"; + cpu { + sound-dai = <&extn>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + }; + /* Audio Related end */ + + dvb { + compatible = "amlogic, dvb"; + status = "okay"; + fe0_mode = "internal"; + fe0_tuner = <&tuner>; + + /*"parallel","serial","disable"*/ + ts2 = "parallel"; + ts2_control = <0>; + ts2_invert = <0>; + interrupts = <0 23 1 + 0 5 1 + 0 53 1 + 0 19 1 + 0 25 1 + 0 17 1>; + interrupt-names = "demux0_irq", + "demux1_irq", + "demux2_irq", + "dvr0_irq", + "dvr1_irq", + "dvr2_irq"; + clocks = <&clkc CLKID_DEMUX + &clkc CLKID_ASYNC_FIFO + &clkc CLKID_AHB_ARB0 +/* &clkc CLKID_DOS_PARSER>;*/ + &clkc CLKID_U_PARSER>; + clock-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; + }; + + tvafe_avin_detect { + compatible = "amlogic, tl1_tvafe_avin_detect"; + status = "okay"; + device_mask = <1>;/*bit0:ch1;bit1:ch2*/ + interrupts = <0 12 1>, + <0 13 1>; + }; + + amlvecm { + compatible = "amlogic, vecm"; + dev_name = "aml_vecm"; + status = "okay"; + gamma_en = <1>;/*1:enabel ;0:disable*/ + wb_en = <1>;/*1:enabel ;0:disable*/ + cm_en = <1>;/*1:enabel ;0:disable*/ + wb_sel = <1>;/*1:mtx ;0:gainoff*/ + vlock_en = <1>;/*1:enable;0:disable*/ + vlock_mode = <0x4>; + /* vlock work mode: + *bit0:auto ENC + *bit1:auto PLL + *bit2:manual PLL + *bit3:manual ENC + *bit4:manual soft ENC + *bit5:manual MIX PLL ENC + */ + vlock_pll_m_limit = <1>; + vlock_line_limit = <3>; + }; + + vdin@0 { + compatible = "amlogic, vdin"; + /*memory-region = <&vdin0_cma_reserved>;*/ + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0x101>; + /*MByte, if 10bit disable: 64M(YUV422), + *if 10bit enable: 64*1.5 = 96M(YUV422) + *if support 4K2K-YUV444-10bit-WR:3840*2160*4*4 ~= 128M + *if support 4K2K-YUV422-10bit-wr:3840*2160*3*4 ~= 96M + *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M + *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M + */ + cma_size = <190>; + interrupts = <0 83 1>; + rdma-irq = <2>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <0>; + /*vdin write mem color depth support: + * bit0:support 8bit + * bit1:support 9bit + * bit2:support 10bit + * bit3:support 12bit + * bit4:support yuv422 10bit full pack mode (from txl new add) + * bit8:use 8bit at 4k_50/60hz_10bit + * bit9:use 10bit at 4k_50/60hz_10bit + */ + tv_bit_mode = <0x215>; + /* afbce_bit_mode: (amlogic frame buff compression encoder) + * bit 0~3: + * 0 -- normal mode, not use afbce + * 1 -- use afbce non-mmu mode + * 2 -- use afbce mmu mode + * bit 4: + * 0 -- afbce compression-lossy disable + * 1 -- afbce compression-lossy enable + */ + afbce_bit_mode = <0>; + }; + + vdin@1 { + compatible = "amlogic, vdin"; + memory-region = <&vdin1_cma_reserved>; + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0>; + interrupts = <0 85 1>; + rdma-irq = <4>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <1>; + /*vdin write mem color depth support: + *bit0:support 8bit + *bit1:support 9bit + *bit2:support 10bit + *bit3:support 12bit + */ + tv_bit_mode = <0x15>; + }; + + tvafe { + compatible = "amlogic, tvafe-tl1"; + /*memory-region = <&tvafe_cma_reserved>;*/ + status = "okay"; + flag_cma = <1>;/*1:share with codec_mm;0:cma alone*/ + cma_size = <5>;/*MByte*/ + reg = <0xff654000 0x2000>;/*tvafe reg base*/ + reserve-iomap = "true"; + tvafe_id = <0>; + //pinctrl-names = "default"; + /*!!particular sequence, no more and no less!!!*/ + tvafe_pin_mux = < + 3 /* TVAFE_CVBS_IN2, CVBS_IN0 = 0 */ + 1 /* TVAFE_CVBS_IN0, CVBS_IN1 */ + 2 /* TVAFE_CVBS_IN1, CVBS_IN2 */ + 4 /* TVAFE_CVBS_IN3, CVBS_IN3 */ + >; + clocks = <&clkc CLKID_DAC_CLK>; + clock-names = "vdac_clk_gate"; + }; + + vbi { + compatible = "amlogic, vbi"; + memory-region = <&vbi_reserved>; + status = "okay"; + interrupts = <0 83 1>; + reserve-iomap = "true"; + }; + + cvbsout { + compatible = "amlogic, cvbsout-tl1"; + status = "disabled"; + clocks = <&clkc CLKID_VCLK2_ENCI + &clkc CLKID_VCLK2_VENCI0 + &clkc CLKID_VCLK2_VENCI1 + &clkc CLKID_DAC_CLK>; + clock-names = "venci_top_gate", + "venci_0_gate", + "venci_1_gate", + "vdac_clk_gate"; + /* clk path */ + /* 0:vid_pll vid2_clk */ + /* 1:gp0_pll vid2_clk */ + /* 2:vid_pll vid1_clk */ + /* 3:gp0_pll vid1_clk */ + clk_path = <0>; + + /* performance: reg_address, reg_value */ + /* tl1 */ + performance = <0x1bf0 0x9 + 0x1b56 0x333 + 0x1b12 0x8080 + 0x1b05 0xfd + 0x1c59 0xf850 + 0xffff 0x0>; /* ending flag */ + performance_sarft = <0x1bf0 0x9 + 0x1b56 0x333 + 0x1b12 0x0 + 0x1b05 0x9 + 0x1c59 0xfc48 + 0xffff 0x0>; /* ending flag */ + performance_revB_telecom = <0x1bf0 0x9 + 0x1b56 0x546 + 0x1b12 0x8080 + 0x1b05 0x9 + 0x1c59 0xf850 + 0xffff 0x0>; /* ending flag */ + }; + + /* for external keypad */ + adc_keypad { + compatible = "amlogic, adc_keypad"; + status = "okay"; + key_name = "power","up","down","enter","left","right","home"; + key_num = <7>; + io-channels = <&saradc SARADC_CH2>,<&saradc SARADC_CH3>; + io-channel-names = "key-chan-2", "key-chan-3"; + key_chan = ; + key_code = <116 103 108 28 105 106 102>; + key_val = <0 143 266 389 512 143 266>; //val=voltage/1800mV*1023 + key_tolerance = <40 40 40 40 40 40 40>; +}; + + unifykey { + compatible = "amlogic, unifykey"; + status = "okay"; + + unifykey-num = <21>; + unifykey-index-0 = <&keysn_0>; + unifykey-index-1 = <&keysn_1>; + unifykey-index-2 = <&keysn_2>; + unifykey-index-3 = <&keysn_3>; + unifykey-index-4 = <&keysn_4>; + unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; + unifykey-index-7 = <&keysn_7>; + unifykey-index-8 = <&keysn_8>; + unifykey-index-9 = <&keysn_9>; + unifykey-index-10= <&keysn_10>; + unifykey-index-11 = <&keysn_11>; + unifykey-index-12 = <&keysn_12>; + unifykey-index-13 = <&keysn_13>; + unifykey-index-14 = <&keysn_14>; + unifykey-index-15 = <&keysn_15>; + unifykey-index-16 = <&keysn_16>; + unifykey-index-17 = <&keysn_17>; + unifykey-index-18 = <&keysn_18>; + unifykey-index-19 = <&keysn_19>; + unifykey-index-20 = <&keysn_20>; + + keysn_0: key_0{ + key-name = "usid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_1:key_1{ + key-name = "mac"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_2:key_2{ + key-name = "hdcp"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_3:key_3{ + key-name = "secure_boot_set"; + key-device = "efuse"; + key-permit = "write"; + }; + keysn_4:key_4{ + key-name = "mac_bt"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_5:key_5{ + key-name = "mac_wifi"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_6:key_6{ + key-name = "hdcp2_tx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_7:key_7{ + key-name = "hdcp2_rx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_8:key_8{ + key-name = "widevinekeybox"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_9:key_9{ + key-name = "deviceid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_10:key_10{ + key-name = "hdcp22_fw_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_11:key_11{ + key-name = "hdcp22_rx_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_12:key_12{ + key-name = "hdcp22_rx_fw"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_13:key_13{ + key-name = "hdcp14_rx"; + key-device = "normal"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_14:key_14{ + key-name = "prpubkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_15:key_15{ + key-name = "prprivkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_16:key_16{ + key-name = "lcd"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_17:key_17{ + key-name = "lcd_extern"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_18:key_18{ + key-name = "backlight"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_19:key_19{ + key-name = "lcd_tcon"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_20:key_20{ + key-name = "attestationkeybox";// attestation key + key-device = "secure"; + key-permit = "read","write","del"; + }; + }; /* End unifykey */ + + hdmirx { + compatible = "amlogic, hdmirx_tl1"; + #address-cells=<1>; + #size-cells=<1>; + memory-region = <&hdmirx_emp_cma_reserved>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmirx_a_mux &hdmirx_b_mux + &hdmirx_c_mux>; + repeat = <0>; + interrupts = <0 41 1>; + clocks = <&clkc CLKID_HDMIRX_MODET_COMP>, + <&clkc CLKID_HDMIRX_CFG_COMP>, + <&clkc CLKID_HDMIRX_ACR_COMP>, + <&clkc CLKID_HDMIRX_METER_COMP>, + <&clkc CLKID_HDMIRX_AXI_COMP>, + <&xtal>, + <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV7>, + <&clkc CLKID_HDCP22_SKP_COMP>, + <&clkc CLKID_HDCP22_ESM_COMP>; + // <&clkc CLK_AUD_PLL2FS>, + // <&clkc CLK_AUD_PLL4FS>, + // <&clkc CLK_AUD_OUT>; + clock-names = "hdmirx_modet_clk", + "hdmirx_cfg_clk", + "hdmirx_acr_ref_clk", + "cts_hdmirx_meter_clk", + "cts_hdmi_axi_clk", + "xtal", + "fclk_div5", + "fclk_div7", + "hdcp_rx22_skp", + "hdcp_rx22_esm"; + // "hdmirx_aud_pll2fs", + // "hdmirx_aud_pll4f", + // "clk_aud_out"; + hdmirx_id = <0>; + en_4k_2_2k = <0>; + hpd_low_cec_off = <1>; + /* bit4: enable feature, bit3~0: port number */ + disable_port = <0x0>; + /* MAP_ADDR_MODULE_CBUS */ + /* MAP_ADDR_MODULE_HIU */ + /* MAP_ADDR_MODULE_HDMIRX_CAPB3 */ + /* MAP_ADDR_MODULE_SEC_AHB */ + /* MAP_ADDR_MODULE_SEC_AHB2 */ + /* MAP_ADDR_MODULE_APB4 */ + /* MAP_ADDR_MODULE_TOP */ + reg = < 0x0 0x0 + 0xff63C000 0x2000 + 0xffe0d000 0x2000 + 0x0 0x0 + 0x0 0x0 + 0x0 0x0 + 0xff610000 0xa000>; + }; + + aocec: aocec { + compatible = "amlogic, aocec-tl1"; + /*device_name = "aocec";*/ + status = "okay"; + vendor_name = "Amlogic"; /* Max Chars: 8 */ + /* Refer to the following URL at: + * http://standards.ieee.org/develop/regauth/oui/oui.txt + */ + vendor_id = <0x000000>; + product_desc = "TL1"; /* Max Chars: 16 */ + cec_osd_string = "AML_TV"; /* Max Chars: 14 */ + port_num = <3>; + ee_cec; + arc_port_mask = <0x2>; + interrupts = <0 205 1 + 0 199 1>; + interrupt-names = "hdmi_aocecb","hdmi_aocec"; + pinctrl-names = "default","hdmitx_aocecb","cec_pin_sleep"; + pinctrl-0=<&aoceca_mux>; + pinctrl-1=<&aocecb_mux>; + pinctrl-2=<&aoceca_mux>; + reg = <0xFF80023c 0x4 + 0xFF800000 0x400>; + reg-names = "ao_exit","ao"; + }; + + p_tsensor: p_tsensor@ff634800 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634800 0x50>, + <0xff800268 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 35 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + d_tsensor: d_tsensor@ff634c00 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634c00 0x50>, + <0xff800230 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 36 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + s_tsensor: s_tsensor@ff635000 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff635000 0x50>, + <0xff80026c 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 38 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + meson_cooldev: meson-cooldev@0 { + status = "okay"; + compatible = "amlogic, meson-cooldev"; + cooling_devices { + cpufreq_cool_cluster0 { + min_state = <1000000>; + dyn_coeff = <140>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpufreq_cool0"; + device_type = "cpufreq"; + }; + cpucore_cool_cluster0 { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpucore_cool0"; + device_type = "cpucore"; + }; + gpufreq_cool { + min_state = <400>; + dyn_coeff = <358>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpufreq_cool0"; + device_type = "gpufreq"; + }; + gpucore_cool { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpucore_cool0"; + device_type = "gpucore"; + }; + }; + cpufreq_cool0:cpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + cpucore_cool0:cpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpufreq_cool0:gpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpucore_cool0:gpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + };/*meson cooling devices end*/ + + thermal-zones { + pll_thermal: pll_thermal { + polling-delay = <1000>; + polling-delay-passive = <100>; + sustainable-power = <1680>; + thermal-sensors = <&p_tsensor 0>; + trips { + pswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + pcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + phot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + pcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + cooling-maps { + cpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&cpufreq_cool0 0 11>; + contribution = <1024>; + }; + cpucore_cooling_map { + trip = <&pcontrol>; + cooling-device = <&cpucore_cool0 0 4>; + contribution = <1024>; + }; + gpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&gpufreq_cool0 0 4>; + contribution = <1024>; + }; + }; + }; + ddr_thermal: ddr_thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + sustainable-power = <1680>; + thermal-sensors = <&d_tsensor 1>; + trips { + dswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + dcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + dhot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + dcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + sar_thermal: sar_thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + sustainable-power = <1680>; + thermal-sensors = <&s_tsensor 2>; + trips { + sswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + scontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + shot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + scritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; /*thermal zone end*/ + + /*DCDC for MP8756GD*/ + cpu_opp_table0: cpu_opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + opp01 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + opp02 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + opp03 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <761000>; + }; + opp04 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <791000>; + }; + opp05 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <801000>; + }; + opp06 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <831000>; + }; + opp07 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <861000>; + }; + opp08 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <891000>; + }; + opp09 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <921000>; + }; + opp10 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <981000>; + }; + opp11 { + opp-hz = /bits/ 64 <1908000000>; + opp-microvolt = <1011000>; + }; + }; + + cpufreq-meson { + compatible = "amlogic, cpufreq-meson"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_ao_d_pins3>; + status = "okay"; + }; + + tuner: tuner { + status = "okay"; + tuner_name = "mxl661_tuner"; + tuner_i2c_adap = <&i2c0>; + tuner_i2c_addr = <0x60>; + tuner_xtal = <1>; /* 0: 16MHz, 1: 24MHz */ + tuner_xtal_mode = <3>; + /* NO_SHARE_XTAL(0) + * SLAVE_XTAL_SHARE(3) + */ + tuner_xtal_cap = <25>; /* when tuner_xtal_mode = 3, set 25 */ + }; + + atv-demod { + compatible = "amlogic, atv-demod"; + status = "okay"; + tuner = <&tuner>; + btsc_sap_mode = <1>; + /* pinctrl-names="atvdemod_agc_pins"; */ + /* pinctrl-0=<&atvdemod_agc_pins>; */ + reg = <0xff656000 0x2000 /* demod reg */ + 0xff63c000 0x2000 /* hiu reg */ + 0xff634000 0x2000 /* periphs reg */ + 0xff64a000 0x2000>; /* audio reg */ + reg_23cf = <0x88188832>; + /*default:0x88188832;r840 on haier:0x48188832*/ + }; + + bt-dev{ + compatible = "amlogic, bt-dev"; + status = "okay"; + gpio_reset = <&gpio GPIOC_13 GPIO_ACTIVE_HIGH>; + }; + + wifi{ + compatible = "amlogic, aml_wifi"; + status = "okay"; + interrupt_pin = <&gpio GPIOC_12 GPIO_ACTIVE_HIGH>; + irq_trigger_type = "GPIO_IRQ_LOW"; + dhd_static_buf; //dhd_static_buf support + power_on_pin = <&gpio GPIOC_11 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_b_pins1>; + pwm_config = <&wifi_pwm_conf>; + }; + + wifi_pwm_conf:wifi_pwm_conf{ + pwm_channel1_conf { + pwms = <&pwm_ab MESON_PWM_1 30541 0>; + duty-cycle = <15270>; + times = <8>; + }; + pwm_channel2_conf { + pwms = <&pwm_ab MESON_PWM_3 30500 0>; + duty-cycle = <15250>; + times = <12>; + }; + }; + + sd_emmc_b: sdio@ffe05000 { + status = "okay"; + compatible = "amlogic, meson-mmc-tl1"; + reg = <0xffe05000 0x800>; + interrupts = <0 190 4>; + + pinctrl-names = "sdio_all_pins", + "sdio_clk_cmd_pins"; + pinctrl-0 = <&sdio_all_pins>; + pinctrl-1 = <&sdio_clk_cmd_pins>; + + clocks = <&clkc CLKID_SD_EMMC_B>, + <&clkc CLKID_SD_EMMC_B_P0_COMP>, + <&clkc CLKID_FCLK_DIV2>, + <&clkc CLKID_FCLK_DIV5>, + <&xtal>; + clock-names = "core", "clkin0", "clkin1", "clkin2", "xtal"; + + bus-width = <4>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <100000000>; + disable-wp; + sdio { + pinname = "sdio"; + ocr_avail = <0x200080>; /**VDD voltage 3.3 ~ 3.4 */ + caps = "MMC_CAP_4_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", /**ptm debug */ + "MMC_CAP_UHS_SDR12", + "MMC_CAP_UHS_SDR25", + "MMC_CAP_UHS_SDR50", + "MMC_CAP_UHS_SDR104", + "MMC_PM_KEEP_POWER", + "MMC_CAP_SDIO_IRQ"; + f_min = <400000>; + f_max = <200000000>; + max_req_size = <0x20000>; /**128KB*/ + card_type = <3>; + /* 3:sdio device(ie:sdio-wifi), + * 4:SD combo (IO+mem) card + */ + }; + }; +}; /* end of / */ + +&i2c0 { + status = "okay"; + clock-frequency = <300000>; + pinctrl-names="default"; + pinctrl-0=<&i2c0_dv_pins>; +}; + +&audiobus { + tdma:tdm@0 { + compatible = "amlogic, tl1-snd-tdma"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <0>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_A + &clkc CLKID_MPLL0 + &clkc CLKID_MPLL0>; + clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdma_mclk &tdmout_a>; + + /* + * 0: tdmout_a; + * 1: tdmout_b; + * 2: tdmout_c; + * 3: spdifout; + * 4: spdifout_b; + */ + samesource_sel = <3>; + + /* In for ACODEC_ADC */ + acodec_adc = <1>; + + status = "okay"; + }; + + tdmb:tdm@1 { + compatible = "amlogic, tl1-snd-tdmb"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <1>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_B + &clkc CLKID_MPLL1>; + clock-names = "mclk", "clk_srcpll"; + + status = "okay"; + }; + + tdmc:tdm@2 { + compatible = "amlogic, tl1-snd-tdmc"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <2>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdmout_c &tdmin_c>; + + status = "okay"; + }; + + spdifa:spdif@0 { + compatible = "amlogic, tl1-snd-spdif-a"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 + &clkc CLKID_FCLK_DIV4 + &clkaudio CLKID_AUDIO_GATE_SPDIFIN + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A + &clkaudio CLKID_AUDIO_SPDIFIN + &clkaudio CLKID_AUDIO_SPDIFOUT_A>; + clock-names = "sysclk", "fixed_clk", "gate_spdifin", + "gate_spdifout", "clk_spdifin", "clk_spdifout"; + + interrupts = + ; + interrupt-names = "irq_spdifin"; + + pinctrl-names = "spdif_pins"; + pinctrl-0 = <&spdifout_a>; + + /* + * whether do asrc for pcm and resample a or b + * if raw data, asrc is disabled automatically + * 0: "Disable", + * 1: "Enable:32K", + * 2: "Enable:44K", + * 3: "Enable:48K", + * 4: "Enable:88K", + * 5: "Enable:96K", + * 6: "Enable:176K", + * 7: "Enable:192K", + */ + asrc_id = <0>; + auto_asrc = <3>; + + status = "okay"; + }; + + spdifb:spdif@1 { + compatible = "amlogic, tl1-snd-spdif-b"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/ + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B + &clkaudio CLKID_AUDIO_SPDIFOUT_B>; + clock-names = "sysclk", + "gate_spdifout", "clk_spdifout"; + + status = "okay"; + }; + + pdm:pdm { + compatible = "amlogic, tl1-snd-pdm"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_PDM + &clkc CLKID_FCLK_DIV3 + &clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_PDMIN0 + &clkaudio CLKID_AUDIO_PDMIN1>; + clock-names = "gate", + "sysclk_srcpll", + "dclk_srcpll", + "pdm_dclk", + "pdm_sysclk"; + + pinctrl-names = "pdm_pins"; + pinctrl-0 = <&pdmin>; + + /* mode 0~4, defalut:1 */ + filter_mode = <1>; + + status = "okay"; + }; + + extn:extn { + compatible = "amlogic, snd-extn"; + #sound-dai-cells = <0>; + + interrupts = + ; + interrupt-names = "irq_frhdmirx"; + + status = "okay"; + }; + + aed:effect { + compatible = "amlogic, snd-effect-v2"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_EQDRC>; + clock-names = "gate", "srcpll", "eqdrc"; + + eq_enable = <1>; + multiband_drc_enable = <0>; + fullband_drc_enable = <0>; + /* + * 0:tdmout_a + * 1:tdmout_b + * 2:tdmout_c + * 3:spdifout + * 4:spdifout_b + */ + eqdrc_module = <0>; + /* max 0xf, each bit for one lane, usually one lane */ + lane_mask = <0x1>; + /* max 0xff, each bit for one channel */ + channel_mask = <0x3>; + + status = "okay"; + }; + + asrca: resample@0 { + compatible = "amlogic, tl1-resample-a"; + clocks = <&clkc CLKID_MPLL0 + &clkaudio CLKID_AUDIO_MCLK_A + &clkaudio CLKID_AUDIO_RESAMPLE_A>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "okay"; + }; + + asrcb: resample@1 { + compatible = "amlogic, tl1-resample-b"; + + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_B>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + +}; /* end of audiobus */ + +&pinctrl_periphs { + /* audio pin mux */ + + tdma_mclk: tdma_mclk { + mux { /* GPIOZ_0 */ + groups = "mclk0_z"; + function = "mclk0"; + }; + }; + + tdmout_a: tdmout_a { + mux { /* GPIOZ_1, GPIOZ_2, GPIOZ_3 */ + groups = "tdma_sclk_z", + "tdma_fs_z", + "tdma_dout0_z"; + function = "tdma_out"; + }; + }; + + tdmin_a: tdmin_a { + mux { /* GPIOZ_9 */ + groups = "tdma_din2_z"; + function = "tdma_in"; + }; + }; + + tdmout_c: tdmout_c { + mux { /* GPIODV_7, GPIODV_8, GPIODV_9 */ + groups = "tdmc_sclk", + "tdmc_fs", + "tdmc_dout0"; + function = "tdmc_out"; + }; + }; + + tdmin_c: tdmin_c { + mux { /* GPIODV_10 */ + groups = "tdmc_din1"; + function = "tdmc_in"; + }; + }; + + spdifin_a: spdifin_a { + mux { /* GPIODV_5 */ + groups = "spdif_in"; + function = "spdif_in"; + }; + }; + + spdifout_a: spdifout_a { + mux { /* GPIODV_4 */ + groups = "spdif_out_dv4"; + function = "spdif_out"; + }; + }; + + pdmin: pdmin { + mux { /* GPIOZ_7, GPIOZ_8, pdm_din2_z4 */ + groups = "pdm_dclk_z", + "pdm_din0_z", + "pdm_din2_z4"; + function = "pdm"; + }; + }; + + /*backlight*/ + bl_pwm_vs_on_pins:bl_pwm_vs_on_pin { + mux { + groups = "pwm_vs_z5"; + function = "pwm_vs"; + }; + }; + bl_pwm_off_pins:bl_pwm_off_pin { + mux { + groups = "GPIOZ_5"; + function = "gpio_periphs"; + output-low; + }; + }; + bl_pwm_combo_0_vs_on_pins:bl_pwm_combo_0_vs_on_pin { + mux { + groups = "pwm_vs_z5"; + function = "pwm_vs"; + }; + }; + bl_pwm_combo_1_vs_on_pins:bl_pwm_combo_1_vs_on_pin { + mux { + groups = "pwm_vs_z6"; + function = "pwm_vs"; + }; + }; + bl_pwm_combo_off_pins:bl_pwm_combo_off_pin { + mux { + groups = "GPIOZ_5", + "GPIOZ_6"; + function = "gpio_periphs"; + output-low; + }; + }; + +}; /* end of pinctrl_periphs */ + +&audio_data{ + status = "okay"; +}; + +&i2c2 { + status = "okay"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_z_pins>; + clock-frequency = <400000>; + + ad82584f: ad82584f@62 { + compatible = "ESMT, ad82584f"; + #sound-dai-cells = <0>; + reg = <0x31>; + status = "okay"; + reset_pin = <&gpio_ao GPIOAO_6 0>; + }; + +}; + +&sd_emmc_c { + status = "okay"; + emmc { + caps = "MMC_CAP_8_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", + "MMC_CAP_1_8V_DDR", + "MMC_CAP_HW_RESET", + "MMC_CAP_ERASE", + "MMC_CAP_CMD23"; + caps2 = "MMC_CAP2_HS200"; + /* "MMC_CAP2_HS400";*/ + f_min = <400000>; + f_max = <200000000>; + }; +}; + + + +&spifc { + status = "disabled"; + spi-nor@0 { + cs_gpios = <&gpio BOOT_13 GPIO_ACTIVE_HIGH>; + }; +}; + +&slc_nand { + status = "disabled"; + plat-names = "bootloader", "nandnormal"; + plat-num = <2>; + plat-part-0 = <&bootloader>; + plat-part-1 = <&nandnormal>; + bootloader: bootloader{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <1>; + part_num = <0>; + rb_detect = <1>; + }; + nandnormal: nandnormal{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + plane_mode = "twoplane"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <2>; + part_num = <3>; + partition = <&nand_partitions>; + rb_detect = <1>; + }; + nand_partitions:nand_partition{ + /* + * if bl_mode is 1, tpl size was generate by + * fip_copies * fip_size which + * will not skip bad when calculating + * the partition size; + * + * if bl_mode is 0, + * tpl partition must be comment out. + */ + tpl{ + offset=<0x0 0x0>; + size=<0x0 0x0>; + }; + logo{ + offset=<0x0 0x0>; + size=<0x0 0x200000>; + }; + recovery{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + boot{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + system{ + offset=<0x0 0x0>; + size=<0x0 0x4000000>; + }; + data{ + offset=<0xffffffff 0xffffffff>; + size=<0x0 0x0>; + }; + }; +}; + +ðmac { + status = "okay"; + pinctrl-names = "internal_eth_pins"; + pinctrl-0 = <&internal_eth_pins>; + mc_val = <0x4be04>; + + internal_phy=<1>; +}; + +&uart_A { + status = "okay"; +}; + +&dwc3 { + status = "okay"; +}; + +&usb2_phy_v2 { + status = "okay"; + portnum = <3>; +}; + +&usb3_phy_v2 { + status = "okay"; + portnum = <0>; + otg = <0>; +}; + +&dwc2_a { + status = "okay"; + /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ + controller-type = <1>; +}; + +&spicc0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spicc0_pins_h>; + cs-gpios = <&gpio GPIOH_20 0>; +}; + +&meson_fb { + status = "okay"; + display_size_default = <1920 1080 1920 2160 32>; + mem_size = <0x00800000 0x1980000 0x100000 0x800000>; + logo_addr = "0x7f800000"; + mem_alloc = <0>; + pxp_mode = <0>; /** 0:normal mode 1:pxp mode */ +}; + +&pwm_AO_cd { + status = "okay"; +}; + +&saradc { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <300000>; + pinctrl-names="default"; + pinctrl-0=<&i2c1_h_pins>; + + lcd_extern_i2c0: lcd_extern_i2c@0 { + compatible = "lcd_ext, i2c"; + dev_name = "i2c_T5800Q"; + reg = <0x1c>; + status = "okay"; + }; + + lcd_extern_i2c1: lcd_extern_i2c@1 { + compatible = "lcd_ext, i2c"; + dev_name = "i2c_ANX6862"; + reg = <0x20>; + status = "okay"; + }; + + lcd_extern_i2c2: lcd_extern_i2c@2 { + compatible = "lcd_ext, i2c"; + dev_name = "i2c_ANX7911"; + reg = <0x74>; + status = "okay"; + }; +}; + +&pwm_ab { + status = "okay"; +}; + +&pwm_cd { + status = "okay"; +}; + +&efuse { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts new file mode 100644 index 000000000000..6ddf8823143f --- /dev/null +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts @@ -0,0 +1,1454 @@ +/* + * arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +/dts-v1/; + +#include "mesontl1.dtsi" +#include "partition_mbox_normal_P_32.dtsi" +#include "mesontl1_skt-panel.dtsi" + +/ { + model = "Amlogic TL1 T962X2 X301"; + amlogic-dt-id = "tl1_t962x2_x301"; + compatible = "amlogic, tl1_t962x2_x301"; + + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; + serial2 = &uart_B; + serial3 = &uart_C; + serial4 = &uart_AO_B; + tsensor0 = &p_tsensor; + tsensor1 = &d_tsensor; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c_AO; + }; + + memory@00000000 { + device_type = "memory"; + linux,usable-memory = <0x100000 0x7ff00000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + /* global autoconfigured region for contiguous allocations */ + secmon_reserved: linux,secmon { + compatible = "shared-dma-pool"; + reusable; + size = <0x400000>; + alignment = <0x400000>; + alloc-ranges = <0x05000000 0x400000>; + }; + + codec_mm_cma:linux,codec_mm_cma { + compatible = "shared-dma-pool"; + reusable; + /* ion_codec_mm max can alloc size 80M*/ + size = <0x13400000>; + alignment = <0x400000>; + linux,contiguous-region; + alloc-ranges = <0x12000000 0x13400000>; + }; + + /* codec shared reserved */ + codec_mm_reserved:linux,codec_mm_reserved { + compatible = "amlogic, codec-mm-reserved"; + size = <0x0>; + alignment = <0x100000>; + //no-map; + }; + + logo_reserved:linux,meson-fb { + compatible = "shared-dma-pool"; + reusable; + size = <0x800000>; + alignment = <0x400000>; + alloc-ranges = <0x7f800000 0x800000>; + }; + + ion_cma_reserved:linux,ion-dev { + compatible = "shared-dma-pool"; + reusable; + size = <0x8000000>; + alignment = <0x400000>; + }; + + /* vdin0 CMA pool */ + //vdin0_cma_reserved:linux,vdin0_cma { + // compatible = "shared-dma-pool"; + // reusable; + /* 3840x2160x4x4 ~=128 M */ + // size = <0xc400000>; + // alignment = <0x400000>; + //}; + + /* vdin1 CMA pool */ + vdin1_cma_reserved:linux,vdin1_cma { + compatible = "shared-dma-pool"; + reusable; + /* 1920x1080x2x4 =16 M */ + size = <0x1400000>; + alignment = <0x400000>; + }; + + /* for hdmi rx emp use */ + hdmirx_emp_cma_reserved:linux,emp_cma { + compatible = "shared-dma-pool"; + /*linux,phandle = <5>;*/ + reusable; + /* 4M for emp to ddr */ + /* 32M for tmds to ddr */ + size = <0x2000000>; + alignment = <0x400000>; + /* alloc-ranges = <0x400000 0x2000000>; */ + }; + + /* POST PROCESS MANAGER */ + ppmgr_reserved:linux,ppmgr { + compatible = "amlogic, ppmgr_memory"; + size = <0x0>; + }; + }; /* end of reserved-memory */ + + codec_mm { + compatible = "amlogic, codec, mm"; + status = "okay"; + memory-region = <&codec_mm_cma &codec_mm_reserved>; + }; + + ppmgr { + compatible = "amlogic, ppmgr"; + memory-region = <&ppmgr_reserved>; + status = "okay"; + }; + + vout { + compatible = "amlogic, vout"; + status = "okay"; + fr_auto_policy = <0>; + }; + + /* Audio Related start */ + pdm_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, pdm_dummy_codec"; + status = "okay"; + }; + + dummy_codec:dummy { + #sound-dai-cells = <0>; + compatible = "amlogic, aml_dummy_codec"; + status = "okay"; + }; + + tl1_codec:codec { + #sound-dai-cells = <0>; + compatible = "amlogic, tl1_acodec"; + status = "okay"; + reg = <0xff632000 0x1c>; + tdmout_index = <0>; + tdmin_index = <0>; + dat1_ch_sel = <1>; + }; + + auge_sound { + compatible = "amlogic, tl1-sound-card"; + aml-audio-card,name = "AML-AUGESOUND"; + + avout_mute-gpios = <&gpio GPIODV_3 GPIO_ACTIVE_HIGH>; + + aml-audio-card,dai-link@0 { + format = "i2s"; + mclk-fs = <256>; + continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdma>; + frame-master = <&tdma>; + /* slave mode */ + /* + * bitclock-master = <&tdmacodec>; + * frame-master = <&tdmacodec>; + */ + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-i2s"; + tdmacpu: cpu { + sound-dai = <&tdma>; + dai-tdm-slot-tx-mask = + <1 1>; + dai-tdm-slot-rx-mask = + <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmacodec: codec { + //sound-dai = <&dummy_codec>; + sound-dai = <&ad82584f &tl1_codec>; + }; + }; + + aml-audio-card,dai-link@1 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmb>; + frame-master = <&tdmb>; + /* slave mode */ + //bitclock-master = <&tdmbcodec>; + //frame-master = <&tdmbcodec>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pcm"; + cpu { + sound-dai = <&tdmb>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + /* + * dai-tdm-slot-tx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-rx-mask = + * <1 1 1 1 1 1 1 1>; + * dai-tdm-slot-num = <8>; + */ + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmbcodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@2 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + //continuous-clock; + //bitclock-inversion; + //frame-inversion; + /* master mode */ + bitclock-master = <&tdmc>; + frame-master = <&tdmc>; + /* slave mode */ + //bitclock-master = <&tdmccodec>; + //frame-master = <&tdmccodec>; + /* suffix-name, sync with android audio hal used for */ + //suffix-name = "alsaPORT-tdm"; + cpu { + sound-dai = <&tdmc>; + dai-tdm-slot-tx-mask = <1 1>; + dai-tdm-slot-rx-mask = <1 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + system-clock-frequency = <12288000>; + }; + tdmccodec: codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@3 { + mclk-fs = <64>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-pdm"; + cpu { + sound-dai = <&pdm>; + }; + codec { + sound-dai = <&pdm_codec>; + }; + }; + + aml-audio-card,dai-link@4 { + mclk-fs = <128>; + /* suffix-name, sync with android audio hal used for */ + suffix-name = "alsaPORT-spdif"; + cpu { + sound-dai = <&spdifa>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@5 { + mclk-fs = <128>; + cpu { + sound-dai = <&spdifb>; + system-clock-frequency = <6144000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + aml-audio-card,dai-link@6 { + mclk-fs = <256>; + suffix-name = "alsaPORT-tv"; + cpu { + sound-dai = <&extn>; + system-clock-frequency = <12288000>; + }; + codec { + sound-dai = <&dummy_codec>; + }; + }; + + }; + /* Audio Related end */ + + dvb { + compatible = "amlogic, dvb"; + status = "okay"; + fe0_mode = "internal"; + fe0_tuner = <&tuner>; + + /*"parallel","serial","disable"*/ + ts2 = "parallel"; + ts2_control = <0>; + ts2_invert = <0>; + interrupts = <0 23 1 + 0 5 1 + 0 53 1 + 0 19 1 + 0 25 1 + 0 17 1>; + interrupt-names = "demux0_irq", + "demux1_irq", + "demux2_irq", + "dvr0_irq", + "dvr1_irq", + "dvr2_irq"; + clocks = <&clkc CLKID_DEMUX + &clkc CLKID_ASYNC_FIFO + &clkc CLKID_AHB_ARB0 +/* &clkc CLKID_DOS_PARSER>;*/ + &clkc CLKID_U_PARSER>; + clock-names = "demux", "asyncfifo", "ahbarb0", "uparsertop"; + }; + + tvafe_avin_detect { + compatible = "amlogic, tl1_tvafe_avin_detect"; + status = "okay"; + device_mask = <1>;/*bit0:ch1;bit1:ch2*/ + interrupts = <0 12 1>, + <0 13 1>; + }; + + amlvecm { + compatible = "amlogic, vecm"; + dev_name = "aml_vecm"; + status = "okay"; + gamma_en = <1>;/*1:enabel ;0:disable*/ + wb_en = <1>;/*1:enabel ;0:disable*/ + cm_en = <1>;/*1:enabel ;0:disable*/ + wb_sel = <1>;/*1:mtx ;0:gainoff*/ + vlock_en = <1>;/*1:enable;0:disable*/ + vlock_mode = <0x4>; + /* vlock work mode: + *bit0:auto ENC + *bit1:auto PLL + *bit2:manual PLL + *bit3:manual ENC + *bit4:manual soft ENC + *bit5:manual MIX PLL ENC + */ + vlock_pll_m_limit = <1>; + vlock_line_limit = <3>; + }; + + vdin@0 { + compatible = "amlogic, vdin"; + /*memory-region = <&vdin0_cma_reserved>;*/ + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0x101>; + /*MByte, if 10bit disable: 64M(YUV422), + *if 10bit enable: 64*1.5 = 96M(YUV422) + *if support 4K2K-YUV444-10bit-WR:3840*2160*4*4 ~= 128M + *if support 4K2K-YUV422-10bit-wr:3840*2160*3*4 ~= 96M + *if support 4K2K-YUV422-8BIT-WR:3840*2160*2*4 ~= 64M + *if support 1080p-YUV422-8BIT-WR:1920*1080*2*4 ~= 16M + */ + cma_size = <190>; + interrupts = <0 83 1>; + rdma-irq = <2>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <0>; + /*vdin write mem color depth support: + * bit0:support 8bit + * bit1:support 9bit + * bit2:support 10bit + * bit3:support 12bit + * bit4:support yuv422 10bit full pack mode (from txl new add) + * bit8:use 8bit at 4k_50/60hz_10bit + * bit9:use 10bit at 4k_50/60hz_10bit + */ + tv_bit_mode = <0x215>; + /* afbce_bit_mode: (amlogic frame buff compression encoder) + * 0: normal mode, not use afbce + * 1: use afbce non-mmu mode + * 2: use afbce mmu mode + */ + afbce_bit_mode = <0>; + }; + + vdin@1 { + compatible = "amlogic, vdin"; + memory-region = <&vdin1_cma_reserved>; + status = "okay"; + /*bit0:(1:share with codec_mm;0:cma alone) + *bit8:(1:alloc in discontinus way;0:alone in continuous way) + */ + flag_cma = <0>; + interrupts = <0 85 1>; + rdma-irq = <4>; + clocks = <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_VDIN_MEAS_COMP>; + clock-names = "fclk_div5", "cts_vdin_meas_clk"; + vdin_id = <1>; + /*vdin write mem color depth support: + *bit0:support 8bit + *bit1:support 9bit + *bit2:support 10bit + *bit3:support 12bit + */ + tv_bit_mode = <0x15>; + }; + + unifykey { + compatible = "amlogic, unifykey"; + status = "okay"; + + unifykey-num = <19>; + unifykey-index-0 = <&keysn_0>; + unifykey-index-1 = <&keysn_1>; + unifykey-index-2 = <&keysn_2>; + unifykey-index-3 = <&keysn_3>; + unifykey-index-4 = <&keysn_4>; + unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; + unifykey-index-7 = <&keysn_7>; + unifykey-index-8 = <&keysn_8>; + unifykey-index-9 = <&keysn_9>; + unifykey-index-10= <&keysn_10>; + unifykey-index-11 = <&keysn_11>; + unifykey-index-12 = <&keysn_12>; + unifykey-index-13 = <&keysn_13>; + unifykey-index-14 = <&keysn_14>; + unifykey-index-15 = <&keysn_15>; + unifykey-index-16 = <&keysn_16>; + unifykey-index-17 = <&keysn_17>; + unifykey-index-18 = <&keysn_18>; + + keysn_0: key_0{ + key-name = "usid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_1:key_1{ + key-name = "mac"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_2:key_2{ + key-name = "hdcp"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_3:key_3{ + key-name = "secure_boot_set"; + key-device = "efuse"; + key-permit = "write"; + }; + keysn_4:key_4{ + key-name = "mac_bt"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_5:key_5{ + key-name = "mac_wifi"; + key-device = "normal"; + key-permit = "read","write","del"; + key-type = "mac"; + }; + keysn_6:key_6{ + key-name = "hdcp2_tx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_7:key_7{ + key-name = "hdcp2_rx"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_8:key_8{ + key-name = "widevinekeybox"; + key-device = "secure"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_9:key_9{ + key-name = "deviceid"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_10:key_10{ + key-name = "hdcp22_fw_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_11:key_11{ + key-name = "hdcp22_rx_private"; + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_12:key_12{ + key-name = "hdcp22_rx_fw"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_13:key_13{ + key-name = "hdcp14_rx"; + key-device = "normal"; + key-type = "sha1"; + key-permit = "read","write","del"; + }; + keysn_14:key_14{ + key-name = "prpubkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_15:key_15{ + key-name = "prprivkeybox";// PlayReady + key-device = "secure"; + key-permit = "read","write","del"; + }; + keysn_16:key_16{ + key-name = "lcd"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_17:key_17{ + key-name = "lcd_extern"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + keysn_18:key_18{ + key-name = "backlight"; + key-device = "normal"; + key-permit = "read","write","del"; + }; + }; /* End unifykey */ + + hdmirx { + compatible = "amlogic, hdmirx_tl1"; + #address-cells=<1>; + #size-cells=<1>; + memory-region = <&hdmirx_emp_cma_reserved>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmirx_a_mux &hdmirx_b_mux + &hdmirx_c_mux>; + repeat = <0>; + interrupts = <0 56 1>; + clocks = <&clkc CLKID_HDMIRX_MODET_COMP>, + <&clkc CLKID_HDMIRX_CFG_COMP>, + <&clkc CLKID_HDMIRX_ACR_COMP>, + <&clkc CLKID_HDMIRX_METER_COMP>, + <&xtal>, + <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV7>, + <&clkc CLKID_HDCP22_SKP_COMP>, + <&clkc CLKID_HDCP22_ESM_COMP>; + // <&clkc CLK_AUD_PLL2FS>, + // <&clkc CLK_AUD_PLL4FS>, + // <&clkc CLK_AUD_OUT>; + clock-names = "hdmirx_modet_clk", + "hdmirx_cfg_clk", + "hdmirx_acr_ref_clk", + "cts_hdmirx_meter_clk", + "xtal", + "fclk_div5", + "fclk_div7", + "hdcp_rx22_skp", + "hdcp_rx22_esm"; + // "hdmirx_aud_pll2fs", + // "hdmirx_aud_pll4f", + // "clk_aud_out"; + hdmirx_id = <0>; + en_4k_2_2k = <0>; + hpd_low_cec_off = <1>; + /* bit4: enable feature, bit3~0: port number */ + disable_port = <0x0>; + /* MAP_ADDR_MODULE_CBUS */ + /* MAP_ADDR_MODULE_HIU */ + /* MAP_ADDR_MODULE_HDMIRX_CAPB3 */ + /* MAP_ADDR_MODULE_SEC_AHB */ + /* MAP_ADDR_MODULE_SEC_AHB2 */ + /* MAP_ADDR_MODULE_APB4 */ + /* MAP_ADDR_MODULE_TOP */ + reg = < 0x0 0x0 + 0xff63C000 0x2000 + 0xffe0d000 0x2000 + 0x0 0x0 + 0x0 0x0 + 0x0 0x0 + 0xff610000 0xa000>; + }; + + aocec: aocec { + compatible = "amlogic, aocec-tl1"; + /*device_name = "aocec";*/ + status = "okay"; + vendor_name = "Amlogic"; /* Max Chars: 8 */ + /* Refer to the following URL at: + * http://standards.ieee.org/develop/regauth/oui/oui.txt + */ + vendor_id = <0x000000>; + product_desc = "TL1"; /* Max Chars: 16 */ + cec_osd_string = "AML_TV"; /* Max Chars: 14 */ + port_num = <3>; + ee_cec; + arc_port_mask = <0x2>; + interrupts = <0 205 1 + 0 199 1>; + interrupt-names = "hdmi_aocecb","hdmi_aocec"; + pinctrl-names = "default","hdmitx_aocecb","cec_pin_sleep"; + pinctrl-0=<&aoceca_mux>; + pinctrl-1=<&aocecb_mux>; + pinctrl-2=<&aoceca_mux>; + reg = <0xFF80023c 0x4 + 0xFF800000 0x400>; + reg-names = "ao_exit","ao"; + }; + + p_tsensor: p_tsensor@ff634800 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634800 0x50>, + <0xff800268 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 35 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + d_tsensor: d_tsensor@ff634c00 { + compatible = "amlogic, r1p1-tsensor"; + status = "okay"; + reg = <0xff634c00 0x50>, + <0xff800230 0x4>; + cal_type = <0x1>; + cal_a = <324>; + cal_b = <424>; + cal_c = <3159>; + cal_d = <9411>; + rtemp = <115000>; + interrupts = <0 36 0>; + clocks = <&clkc CLKID_TS_CLK_COMP>; /* CLKID_TS_COMP>;*/ + clock-names = "ts_comp"; + #thermal-sensor-cells = <1>; + }; + + meson_cooldev: meson-cooldev@0 { + status = "okay"; + compatible = "amlogic, meson-cooldev"; + cooling_devices { + cpufreq_cool_cluster0 { + min_state = <1000000>; + dyn_coeff = <115>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpufreq_cool0"; + device_type = "cpufreq"; + }; + cpucore_cool_cluster0 { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "cpucore_cool0"; + device_type = "cpucore"; + }; + gpufreq_cool { + min_state = <400>; + dyn_coeff = <358>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpufreq_cool0"; + device_type = "gpufreq"; + }; + gpucore_cool { + min_state = <1>; + dyn_coeff = <0>; + gpu_pp = <2>; + cluster_id = <0>; + node_name = "gpucore_cool0"; + device_type = "gpucore"; + }; + }; + cpufreq_cool0:cpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + cpucore_cool0:cpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpufreq_cool0:gpufreq_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + gpucore_cool0:gpucore_cool0 { + #cooling-cells = <2>; /* min followed by max */ + }; + };/*meson cooling devices end*/ + + thermal-zones { + pll_thermal: pll_thermal { + polling-delay = <1000>; + polling-delay-passive = <100>; + sustainable-power = <1410>; + thermal-sensors = <&p_tsensor 0>; + trips { + pswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + pcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + phot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + pcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + cooling-maps { + cpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&cpufreq_cool0 0 4>; + contribution = <1024>; + }; + gpufreq_cooling_map { + trip = <&pcontrol>; + cooling-device = <&gpufreq_cool0 0 4>; + contribution = <1024>; + }; + }; + }; + ddr_thermal: ddr_thermal { + polling-delay = <1000>; + polling-delay-passive = <250>; + sustainable-power = <1460>; + thermal-sensors = <&d_tsensor 1>; + trips { + dswitch_on: trip-point@0 { + temperature = <60000>; + hysteresis = <5000>; + type = "passive"; + }; + dcontrol: trip-point@1 { + temperature = <75000>; + hysteresis = <5000>; + type = "passive"; + }; + dhot: trip-point@2 { + temperature = <85000>; + hysteresis = <5000>; + type = "hot"; + }; + dcritical: trip-point@3 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + }; /*thermal zone end*/ + + /*DCDC for MP8756GD*/ + cpu_opp_table0: cpu_opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <731000>; + }; + opp01 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <731000>; + }; + opp02 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <731000>; + }; + opp03 { + opp-hz = /bits/ 64 <667000000>; + opp-microvolt = <761000>; + }; + opp04 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <791000>; + }; + opp05 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <801000>; + }; + opp06 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <831000>; + }; + opp07 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <861000>; + }; + opp08 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <891000>; + }; + opp09 { + opp-hz = /bits/ 64 <1704000000>; + opp-microvolt = <921000>; + }; + opp10 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <981000>; + }; + opp11 { + opp-hz = /bits/ 64 <1908000000>; + opp-microvolt = <1011000>; + }; + }; + + cpufreq-meson { + compatible = "amlogic, cpufreq-meson"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_ao_d_pins3>; + status = "okay"; + }; + + tuner: tuner { + status = "okay"; + tuner_name = "mxl661_tuner"; + tuner_i2c_adap = <&i2c0>; + tuner_i2c_addr = <0x60>; + tuner_xtal = <1>; /* 0: 16MHz, 1: 24MHz */ + tuner_xtal_mode = <3>; + /* NO_SHARE_XTAL(0) + * SLAVE_XTAL_SHARE(3) + */ + tuner_xtal_cap = <25>; /* when tuner_xtal_mode = 3, set 25 */ + }; + + bt-dev{ + compatible = "amlogic, bt-dev"; + status = "okay"; + gpio_reset = <&gpio GPIOC_13 GPIO_ACTIVE_HIGH>; + }; + + wifi{ + compatible = "amlogic, aml_wifi"; + status = "okay"; + interrupt_pin = <&gpio GPIOC_12 GPIO_ACTIVE_HIGH>; + irq_trigger_type = "GPIO_IRQ_LOW"; + dhd_static_buf; //dhd_static_buf support + power_on_pin = <&gpio GPIOC_11 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_b_pins1>; + pwm_config = <&wifi_pwm_conf>; + }; + + wifi_pwm_conf:wifi_pwm_conf{ + pwm_channel1_conf { + pwms = <&pwm_ab MESON_PWM_1 30040 0>; + duty-cycle = <15020>; + times = <8>; + }; + pwm_channel2_conf { + pwms = <&pwm_ab MESON_PWM_3 30030 0>; + duty-cycle = <15015>; + times = <12>; + }; + }; + +}; /* end of / */ + +&i2c0 { + status = "okay"; + clock-frequency = <300000>; + pinctrl-names="default"; + pinctrl-0=<&i2c0_dv_pins>; +}; + +&audiobus { + tdma:tdm@0 { + compatible = "amlogic, tl1-snd-tdma"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0>; + dai-tdm-lane-slot-mask-out = <1 1 1 1>; + dai-tdm-clk-sel = <0>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_A + &clkc CLKID_MPLL0 + &clkc CLKID_MPLL0>; + clock-names = "mclk", "clk_srcpll", "samesource_sysclk"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdma_mclk &tdmout_a>; + + /* + * 0: tdmout_a; + * 1: tdmout_b; + * 2: tdmout_c; + * 3: spdifout; + * 4: spdifout_b; + */ + samesource_sel = <3>; + + /* In for ACODEC_ADC */ + acodec_adc = <1>; + + status = "okay"; + }; + + tdmb:tdm@1 { + compatible = "amlogic, tl1-snd-tdmb"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <1>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_B + &clkc CLKID_MPLL1>; + clock-names = "mclk", "clk_srcpll"; + + status = "okay"; + }; + + tdmc:tdm@2 { + compatible = "amlogic, tl1-snd-tdmc"; + #sound-dai-cells = <0>; + + dai-tdm-lane-slot-mask-in = <1 0 0 0>; + dai-tdm-lane-slot-mask-out = <1 0 0 0>; + dai-tdm-clk-sel = <2>; + + clocks = <&clkaudio CLKID_AUDIO_MCLK_C + &clkc CLKID_MPLL2>; + clock-names = "mclk", "clk_srcpll"; + + pinctrl-names = "tdm_pins"; + pinctrl-0 = <&tdmout_c &tdmin_c>; + + status = "okay"; + }; + + spdifa:spdif@0 { + compatible = "amlogic, tl1-snd-spdif-a"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 + &clkc CLKID_FCLK_DIV4 + &clkaudio CLKID_AUDIO_GATE_SPDIFIN + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_A + &clkaudio CLKID_AUDIO_SPDIFIN + &clkaudio CLKID_AUDIO_SPDIFOUT_A>; + clock-names = "sysclk", "fixed_clk", "gate_spdifin", + "gate_spdifout", "clk_spdifin", "clk_spdifout"; + + interrupts = + ; + interrupt-names = "irq_spdifin"; + + pinctrl-names = "spdif_pins"; + pinctrl-0 = <&spdifout_a>; + + /* + * whether do asrc for pcm and resample a or b + * if raw data, asrc is disabled automatically + * 0: "Disable", + * 1: "Enable:32K", + * 2: "Enable:44K", + * 3: "Enable:48K", + * 4: "Enable:88K", + * 5: "Enable:96K", + * 6: "Enable:176K", + * 7: "Enable:192K", + */ + asrc_id = <0>; + auto_asrc = <3>; + + status = "okay"; + }; + + spdifb:spdif@1 { + compatible = "amlogic, tl1-snd-spdif-b"; + #sound-dai-cells = <0>; + + clocks = <&clkc CLKID_MPLL0 /*CLKID_HIFI_PLL*/ + &clkaudio CLKID_AUDIO_GATE_SPDIFOUT_B + &clkaudio CLKID_AUDIO_SPDIFOUT_B>; + clock-names = "sysclk", + "gate_spdifout", "clk_spdifout"; + + status = "okay"; + }; + + pdm:pdm { + compatible = "amlogic, tl1-snd-pdm"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_PDM + &clkc CLKID_FCLK_DIV3 + &clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_PDMIN0 + &clkaudio CLKID_AUDIO_PDMIN1>; + clock-names = "gate", + "sysclk_srcpll", + "dclk_srcpll", + "pdm_dclk", + "pdm_sysclk"; + + pinctrl-names = "pdm_pins"; + pinctrl-0 = <&pdmin>; + + /* mode 0~4, defalut:1 */ + filter_mode = <1>; + + status = "okay"; + }; + + extn:extn { + compatible = "amlogic, snd-extn"; + #sound-dai-cells = <0>; + + interrupts = + ; + interrupt-names = "irq_frhdmirx"; + + status = "okay"; + }; + + aed:effect { + compatible = "amlogic, snd-effect-v2"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_EQDRC + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_EQDRC>; + clock-names = "gate", "srcpll", "eqdrc"; + + eq_enable = <1>; + multiband_drc_enable = <0>; + fullband_drc_enable = <0>; + /* + * 0:tdmout_a + * 1:tdmout_b + * 2:tdmout_c + * 3:spdifout + * 4:spdifout_b + */ + eqdrc_module = <0>; + /* max 0xf, each bit for one lane, usually one lane */ + lane_mask = <0x1>; + /* max 0xff, each bit for one channel */ + channel_mask = <0x3>; + + status = "okay"; + }; + + asrca: resample@0 { + compatible = "amlogic, tl1-resample-a"; + clocks = <&clkc CLKID_MPLL0 + &clkaudio CLKID_AUDIO_MCLK_A + &clkaudio CLKID_AUDIO_RESAMPLE_A>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "okay"; + }; + + asrcb: resample@1 { + compatible = "amlogic, tl1-resample-b"; + + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_B>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + + /*same with toddr_src + * TDMIN_A, 0 + * TDMIN_B, 1 + * TDMIN_C, 2 + * SPDIFIN, 3 + * PDMIN, 4 + * NONE, + * TDMIN_LB, 6 + * LOOPBACK, 7 + */ + resample_module = <3>; + + status = "disabled"; + }; + + vad:vad { + compatible = "amlogic, snd-vad"; + #sound-dai-cells = <0>; + + clocks = <&clkaudio CLKID_AUDIO_GATE_TOVAD + &clkc CLKID_FCLK_DIV5 + &clkaudio CLKID_AUDIO_VAD>; + clock-names = "gate", "pll", "clk"; + + interrupts = ; + interrupt-names = "irq_wakeup", "irq_frame_sync"; + + /* + * Data src sel: + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + * 5: loopback_b; + * 6: tdmin_lb; + * 7: loopback_a; + */ + src = <4>; + + /* + * deal with hot word in user space or kernel space + * 0: in user space + * 1: in kernel space + */ + level = <0>; + + status = "disabled"; + }; +}; /* end of audiobus */ + +&pinctrl_periphs { + /* audio pin mux */ + + tdma_mclk: tdma_mclk { + mux { /* GPIOZ_0 */ + groups = "mclk0_z"; + function = "mclk0"; + }; + }; + + tdmout_a: tdmout_a { + mux { /* GPIOZ_1, GPIOZ_2, GPIOZ_3 */ + groups = "tdma_sclk_z", + "tdma_fs_z", + "tdma_dout0_z"; + function = "tdma_out"; + }; + }; + + tdmin_a: tdmin_a { + mux { /* GPIOZ_9 */ + groups = "tdma_din2_z"; + function = "tdma_in"; + }; + }; + + tdmout_c: tdmout_c { + mux { /* GPIODV_7, GPIODV_8, GPIODV_9 */ + groups = "tdmc_sclk", + "tdmc_fs", + "tdmc_dout0"; + function = "tdmc_out"; + }; + }; + + tdmin_c: tdmin_c { + mux { /* GPIODV_10 */ + groups = "tdmc_din1"; + function = "tdmc_in"; + }; + }; + + spdifin_a: spdifin_a { + mux { /* GPIODV_5 */ + groups = "spdif_in"; + function = "spdif_in"; + }; + }; + + spdifout_a: spdifout_a { + mux { /* GPIODV_4 */ + groups = "spdif_out_dv4"; + function = "spdif_out"; + }; + }; + + pdmin: pdmin { + mux { /* GPIOZ_7, GPIOZ_8, pdm_din2_z4 */ + groups = "pdm_dclk_z", + "pdm_din0_z", + "pdm_din2_z4"; + function = "pdm"; + }; + }; + + +}; /* end of pinctrl_periphs */ + +&audio_data{ + status = "okay"; +}; + +&i2c2 { + status = "okay"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_z_pins>; + clock-frequency = <400000>; + + tas5805: tas5805@36 { + compatible = "ti,tas5805"; + #sound-dai-cells = <0>; + codec_name = "tas5805"; + reg = <0x2d>; + status = "disable"; + }; + + ad82584f: ad82584f@62 { + compatible = "ESMT, ad82584f"; + #sound-dai-cells = <0>; + reg = <0x31>; + status = "okay"; + reset_pin = <&gpio_ao GPIOAO_6 0>; + }; + +}; + +&sd_emmc_c { + status = "okay"; + emmc { + caps = "MMC_CAP_8_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE", + /* "MMC_CAP_1_8V_DDR", */ + "MMC_CAP_HW_RESET", + "MMC_CAP_ERASE", + "MMC_CAP_CMD23"; + caps2 = "MMC_CAP2_HS200"; + /* "MMC_CAP2_HS400";*/ + f_min = <400000>; + f_max = <200000000>; + }; +}; + +&sd_emmc_b { + status = "okay"; + sd { + caps = "MMC_CAP_4_BIT_DATA", + "MMC_CAP_MMC_HIGHSPEED", + "MMC_CAP_SD_HIGHSPEED", + "MMC_CAP_NONREMOVABLE"; /**ptm debug */ + f_min = <400000>; + f_max = <200000000>; + }; +}; + +&spifc { + status = "disabled"; + spi-nor@0 { + cs_gpios = <&gpio BOOT_13 GPIO_ACTIVE_HIGH>; + }; +}; + +&slc_nand { + status = "disabled"; + plat-names = "bootloader", "nandnormal"; + plat-num = <2>; + plat-part-0 = <&bootloader>; + plat-part-1 = <&nandnormal>; + bootloader: bootloader{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <1>; + part_num = <0>; + rb_detect = <1>; + }; + nandnormal: nandnormal{ + enable_pad = "ce0"; + busy_pad = "rb0"; + timming_mode = "mode5"; + bch_mode = "bch8_1k"; + plane_mode = "twoplane"; + t_rea = <20>; + t_rhoh = <15>; + chip_num = <2>; + part_num = <3>; + partition = <&nand_partitions>; + rb_detect = <1>; + }; + nand_partitions:nand_partition{ + /* + * if bl_mode is 1, tpl size was generate by + * fip_copies * fip_size which + * will not skip bad when calculating + * the partition size; + * + * if bl_mode is 0, + * tpl partition must be comment out. + */ + tpl{ + offset=<0x0 0x0>; + size=<0x0 0x0>; + }; + logo{ + offset=<0x0 0x0>; + size=<0x0 0x200000>; + }; + recovery{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + boot{ + offset=<0x0 0x0>; + size=<0x0 0x1000000>; + }; + system{ + offset=<0x0 0x0>; + size=<0x0 0x4000000>; + }; + data{ + offset=<0xffffffff 0xffffffff>; + size=<0x0 0x0>; + }; + }; +}; + +ðmac { + status = "okay"; + pinctrl-names = "internal_eth_pins"; + pinctrl-0 = <&internal_eth_pins>; + mc_val = <0x4be04>; + + internal_phy=<1>; +}; + +&uart_A { + status = "okay"; +}; + +&dwc3 { + status = "okay"; +}; + +&usb2_phy_v2 { + status = "okay"; + portnum = <3>; +}; + +&usb3_phy_v2 { + status = "okay"; + portnum = <0>; + otg = <0>; +}; + +&dwc2_a { + status = "okay"; + /** 0: normal, 1: otg+dwc3 host only, 2: otg+dwc3 device only*/ + controller-type = <1>; +}; + +&spicc0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spicc0_pins_h>; + cs-gpios = <&gpio GPIOH_20 0>; +}; + +&meson_fb { + status = "okay"; + display_size_default = <1920 1080 1920 2160 32>; + mem_size = <0x00800000 0x1980000 0x100000 0x800000>; + logo_addr = "0x7f800000"; + mem_alloc = <0>; + pxp_mode = <0>; /** 0:normal mode 1:pxp mode */ +}; + +&pwm_AO_cd { + status = "okay"; +}; + +&saradc { + status = "okay"; +}; + +&pwm_ab { + status = "okay"; +}; + +&efuse { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/amlogic/txl_t962_p321_720p.dts b/arch/arm/boot/dts/amlogic/txl_t962_p321_720p.dts index 5548335d502f..d961b2423ba8 100644 --- a/arch/arm/boot/dts/amlogic/txl_t962_p321_720p.dts +++ b/arch/arm/boot/dts/amlogic/txl_t962_p321_720p.dts @@ -97,7 +97,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x4C00000>; + size = <0x2400000>; alignment = <0x400000>; /* alloc by self */ alloc-ranges = <0x0 0x30000000>; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts index 36f67ec2d3b2..3d8cb6352dac 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962e_r321.dts @@ -682,13 +682,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts b/arch/arm/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts index 89eee0fc8c10..48ac144d59e7 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts @@ -726,13 +726,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts index 7e057d94586d..8a65f4161541 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -692,13 +692,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts index e5f94bfd022c..95753b5f5542 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -689,13 +689,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_720p.dts index 970ae170f83a..eccb9cb8b13f 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_720p.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_720p.dts @@ -95,7 +95,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x4C00000>; + size = <0x2400000>; alignment = <0x400000>; alloc-ranges = <0x0 0x30000000>; }; @@ -685,13 +685,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962x_r314.dts b/arch/arm/boot/dts/amlogic/txlx_t962x_r314.dts index dd614f178f72..53cc709a26a9 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962x_r314.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962x_r314.dts @@ -692,13 +692,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm/configs/meson64_a32_defconfig b/arch/arm/configs/meson64_a32_defconfig index db75074efec6..9cb58f83311c 100644 --- a/arch/arm/configs/meson64_a32_defconfig +++ b/arch/arm/configs/meson64_a32_defconfig @@ -325,6 +325,9 @@ CONFIG_AMLOGIC_MEDIA_ENHANCEMENT=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y CONFIG_AMLOGIC_MEDIA_GDC=y +CONFIG_AMLOGIC_VIDEO_CAPTURE=y +CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER=y +CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145=y CONFIG_AMLOGIC_DTV_DEMOD=y CONFIG_AMLOGIC_MMC=y CONFIG_AMLOGIC_NAND=y @@ -482,6 +485,7 @@ CONFIG_AMLOGIC_SND_CODEC_AMLT9015S=y CONFIG_AMLOGIC_SND_CODEC_TXLX_ACODEC=y CONFIG_AMLOGIC_SND_CODEC_TL1_ACODEC=y CONFIG_AMLOGIC_SND_SOC_TAS5707=y +CONFIG_AMLOGIC_SND_SOC_TAS5805=y CONFIG_AMLOGIC_SND_SOC_TLV320ADC3101=y CONFIG_AMLOGIC_SND_SOC_PCM186X=y CONFIG_AMLOGIC_SND_SOC_SSM3525=y diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 76cbd9c674df..bde40c41c574 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -238,21 +238,41 @@ static inline unsigned long __phys_to_virt(phys_addr_t x) #define PHYS_OFFSET PLAT_PHYS_OFFSET #define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT)) +#ifdef CONFIG_AMLOGIC_MODIFY +extern unsigned long phys_check(phys_addr_t x); +extern unsigned long virt_check(unsigned long x); +extern int scheduler_running; +#endif static inline phys_addr_t __virt_to_phys(unsigned long x) { +#ifdef CONFIG_AMLOGIC_MODIFY + return virt_check(x); +#else return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; +#endif } static inline unsigned long __phys_to_virt(phys_addr_t x) { +#ifdef CONFIG_AMLOGIC_MODIFY + return phys_check(x); +#else return x - PHYS_OFFSET + PAGE_OFFSET; +#endif } #endif +#ifdef CONFIG_AMLOGIC_MODIFY +#define virt_to_pfn(kaddr) \ + ({virt_check((unsigned long)kaddr); \ + ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \ + PHYS_PFN_OFFSET); }) +#else #define virt_to_pfn(kaddr) \ ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \ PHYS_PFN_OFFSET) +#endif /* * These are *only* valid on the kernel direct mapped RAM memory. diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 07b0812a0109..3aeacde7e50f 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -25,6 +25,9 @@ #include #include +#ifdef CONFIG_AMLOGIC_MODIFY +#include +#endif /* * cpu capacity scale management */ @@ -281,6 +284,7 @@ void store_cpu_topology(unsigned int cpuid) cpu_topology[cpuid].socket_id, mpidr); } +#ifndef CONFIG_AMLOGIC_MODIFY /* * ARM TC2 specific energy cost model data. There are no unit requirements for * the data. Data can be normalized to any reference point, but the @@ -386,7 +390,66 @@ static struct sched_group_energy energy_core_a15 = { .nr_cap_states = ARRAY_SIZE(cap_states_core_a15), .cap_states = cap_states_core_a15, }; +#endif /* CONFIG_AMLOGIC_MODIFY */ +#ifdef CONFIG_AMLOGIC_MODIFY +/* sd energy functions */ +static inline +const struct sched_group_energy * const cpu_cluster_energy(int cpu) +{ + struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL1]; + + if (!sge) { + pr_debug("Invalid sched_group_energy for Cluster%d\n", cpu); + return NULL; + } + + return sge; +} + +static inline +const struct sched_group_energy * const cpu_core_energy(int cpu) +{ + struct sched_group_energy *sge = sge_array[cpu][SD_LEVEL0]; + + if (!sge) { + pr_debug("Invalid sched_group_energy for Cluster%d\n", cpu); + return NULL; + } + + return sge; +} + +static int cpu_cpu_flags(void) +{ + return SD_ASYM_CPUCAPACITY; +} + +static inline int cpu_corepower_flags(void) +{ + return SD_SHARE_PKG_RESOURCES | SD_SHARE_POWERDOMAIN | + SD_SHARE_CAP_STATES; +} + +static struct sched_domain_topology_level arm_topology[] = { +#ifdef CONFIG_SCHED_MC + { + cpu_coregroup_mask, + cpu_corepower_flags, + cpu_core_energy, + SD_INIT_NAME(MC) + }, +#endif + { + cpu_cpu_mask, + cpu_cpu_flags, + cpu_cluster_energy, + SD_INIT_NAME(DIE) + }, + { NULL, }, +}; + +#else /* sd energy functions */ static inline const struct sched_group_energy * const cpu_cluster_energy(int cpu) @@ -415,6 +478,7 @@ static struct sched_domain_topology_level arm_topology[] = { { cpu_cpu_mask, NULL, cpu_cluster_energy, SD_INIT_NAME(DIE) }, { NULL, }, }; +#endif /* CONFIG_AMLOGIC_MODIFY */ /* * init_cpu_topology is called at boot when only one cpu is running @@ -440,4 +504,8 @@ void __init init_cpu_topology(void) /* Set scheduler topology descriptor */ set_sched_topology(arm_topology); + +#ifdef CONFIG_AMLOGIC_MODIFY + init_sched_energy_costs(); +#endif } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 6a32470ccc72..95cf506501e5 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -491,6 +491,10 @@ die_sig: if (user_debug & UDBG_UNDEFINED) { pr_info("%s (%d): undefined instruction: pc=%p\n", current->comm, task_pid_nr(current), pc); +#ifdef CONFIG_AMLOGIC_USER_FAULT + if (user_fault_debug_ratelimited()) + show_all_pfn(current, regs); +#endif __show_regs(regs); dump_instr(KERN_INFO, regs); } diff --git a/arch/arm/mach-meson/meson-secure.c b/arch/arm/mach-meson/meson-secure.c index d47b4583ef18..d7931ed33f65 100644 --- a/arch/arm/mach-meson/meson-secure.c +++ b/arch/arm/mach-meson/meson-secure.c @@ -24,6 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include #include @@ -45,7 +47,7 @@ #define TZDBG(fmt, ...) #endif -#define MESON_SECURE_FLAG_REG 0xC11081F0 +#define MESON_SECURE_FLAG_REG_OFFS 0x81F0 #define MESON_SECURE_FLAG_VALUE_DISABLED 0x0 #define MESON_SECURE_FLAG_VALUE_ENABLED 0x1 #define MESON_SECURE_FLAG_VALUE_INVALID 0xFFFFFFFF @@ -62,14 +64,23 @@ static void __iomem *secure_flag_base; bool meson_secure_enabled(void) { bool ret = false; + struct device_node *np; if (secure_flag == MESON_SECURE_FLAG_VALUE_INVALID) { - secure_flag_base = ioremap(MESON_SECURE_FLAG_REG, 4); - if (!secure_flag_base) { - TZDBG("iomap(0x%x) error.", MESON_SECURE_FLAG_REG); + np = of_find_compatible_node(NULL, NULL, "amlogic, iomap"); + if (!np) { + TZDBG("find iomap node fail."); return false; } - secure_flag = readl_relaxed(secure_flag_base); + + secure_flag_base = of_iomap(np, 0); + if (!secure_flag_base) { + TZDBG("of_iomap error."); + return false; + } + + secure_flag = readl_relaxed(secure_flag_base + + MESON_SECURE_FLAG_REG_OFFS); } TZDBG("secure_flag: 0x%x\n", secure_flag); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index f7c741358f37..4d3da37cb798 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1640,3 +1640,39 @@ void __init paging_init(const struct machine_desc *mdesc) empty_zero_page = virt_to_page(zero_page); __flush_dcache_page(NULL, empty_zero_page); } + +#ifdef CONFIG_AMLOGIC_MODIFY +unsigned long notrace phys_check(phys_addr_t x) +{ + unsigned long addr; + struct page *page; + + addr = x - PHYS_OFFSET + PAGE_OFFSET; + if (scheduler_running) { + page = phys_to_page(x); + + /* + * if physical address is not in linear mapping range, + * then this will cause BUG + */ + if (is_vmalloc_or_module_addr((const void *)addr) || + PageHighMem(page)) { + pr_err("BAD USING of phys_to_virt, addr:%x, page:%lx\n", + x, page_to_pfn(page)); + dump_stack(); + } + } + return addr; +} +EXPORT_SYMBOL(phys_check); + +unsigned long notrace virt_check(unsigned long x) +{ + if (scheduler_running && (x >= VMALLOC_START || x < PAGE_OFFSET)) { + pr_err("bad input of virt:%lx\n", x); + dump_stack(); + } + return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; +} +EXPORT_SYMBOL(virt_check); +#endif diff --git a/arch/arm64/boot/dts/amlogic/atom.dts b/arch/arm64/boot/dts/amlogic/atom.dts index 1a17056270e4..2fa541ea61b0 100644 --- a/arch/arm64/boot/dts/amlogic/atom.dts +++ b/arch/arm64/boot/dts/amlogic/atom.dts @@ -665,13 +665,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts b/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts index 42e01bcd04b9..d3407d8dd797 100644 --- a/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts +++ b/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts @@ -452,13 +452,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index 4c8de2963a9e..4098f87e1557 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -631,13 +631,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts index 9eb474a08714..25d394141807 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts @@ -612,13 +612,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts index 945d4fb5b223..f805271bbd23 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts @@ -616,13 +616,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -854,6 +854,7 @@ unifykey-index-3 = <&keysn_3>; unifykey-index-4 = <&keysn_4>; unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; keysn_0: key_0{ key-name = "usid"; @@ -887,6 +888,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_6:key_6{ + key-name = "gva_certs"; + key-device = "normal"; + key-permit = "read","write","del"; + }; };//End unifykey audio_data: audio_data { compatible = "amlogic, audio_data"; @@ -1111,7 +1117,7 @@ #sound-dai-cells = <0>; clocks = <&clkaudio CLKID_AUDIO_PDM &clkc CLKID_FCLK_DIV3 - &clkc CLKID_MPLL3 + &clkc CLKID_MPLL2 &clkaudio CLKID_AUDIO_PDMIN0 &clkaudio CLKID_AUDIO_PDMIN1>; clock-names = "gate", diff --git a/arch/arm64/boot/dts/amlogic/axg_s400emmc_512m.dts b/arch/arm64/boot/dts/amlogic/axg_s400emmc_512m.dts index 9feeb0719bc7..6b30d540f730 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400emmc_512m.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400emmc_512m.dts @@ -640,13 +640,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420.dts b/arch/arm64/boot/dts/amlogic/axg_s420.dts index e9470dee9998..ddc988d71ee9 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420.dts @@ -467,13 +467,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts b/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts index c47a2bc34242..c5232e1a467f 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts @@ -458,13 +458,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts index 02eae18db174..b2ce78745814 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts @@ -470,13 +470,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts b/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts index 80262564dac6..1b2300f0f4ef 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts @@ -475,13 +475,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ab MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ab MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ab MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ab MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -668,13 +668,14 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <6>; + unifykey-num = <7>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; unifykey-index-3 = <&keysn_3>; unifykey-index-4 = <&keysn_4>; unifykey-index-5 = <&keysn_5>; + unifykey-index-6 = <&keysn_6>; keysn_0: key_0{ key-name = "usid"; @@ -708,6 +709,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_6:key_6{ + key-name = "gva_certs"; + key-device = "normal"; + key-permit = "read","write","del"; + }; };//End unifykey audio_data: audio_data { compatible = "amlogic, audio_data"; @@ -934,7 +940,7 @@ #sound-dai-cells = <0>; clocks = <&clkaudio CLKID_AUDIO_PDM &clkc CLKID_FCLK_DIV3 - &clkc CLKID_MPLL3 + &clkc CLKID_MPLL2 &clkaudio CLKID_AUDIO_PDMIN0 &clkaudio CLKID_AUDIO_PDMIN1>; clock-names = "gate", @@ -992,6 +998,26 @@ status = "okay"; }; + + audioresample: resample { + compatible = "amlogic, axg-resample"; + clocks = <&clkc CLKID_MPLL3 + &clkaudio CLKID_AUDIO_MCLK_F + &clkaudio CLKID_AUDIO_RESAMPLE_CTRL>; + clock-names = "resample_pll", "resample_src", "resample_clk"; + /*same with toddr_src + * TDMIN_A, + * TDMIN_B, + * TDMIN_C, + * SPDIFIN, + * PDMIN, + * NONE, + * TDMIN_LB, + * LOOPBACK, + */ + resample_module = <3>; + status = "okay"; + }; }; /* end of audiobus */ &pinctrl_periphs { diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts index e3e4c2f3fc65..5700547f0188 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts @@ -215,13 +215,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -273,7 +273,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -289,6 +289,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -368,6 +369,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts index acb0a415ae5d..5c48f26ba772 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts @@ -202,13 +202,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -260,7 +260,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -276,6 +276,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -355,6 +356,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts index 71dfa8473acf..bda0c8a24e39 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x0 0x100000 0x0 0x7ff00000>; + linux,usable-memory = <0x0 0x000000 0x0 0x80000000>; }; reserved-memory { @@ -149,6 +149,12 @@ size = <0x0 0x04000000>; alignment = <0x0 0x400000>; }; + vm0_cma_reserved:linux,vm0_cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x2000000>; + alignment = <0x0 0x400000>; + }; }; gpioleds { @@ -228,13 +234,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -282,6 +288,54 @@ dev_name = "ionvideo"; status = "okay"; }; + vm0 { + compatible = "amlogic, vm"; + memory-region = <&vm0_cma_reserved>; + dev_name = "vm0"; + status = "disabled"; + vm_id = <0>; + }; + + amvdec_656in { + /*bt656 gpio conflict with i2c0*/ + compatible = "amlogic, amvdec_656in"; + dev_name = "amvdec_656in"; + status = "disabled"; + reg = <0x0 0xffe02000 0x0 0x7c>; + clocks = <&clkc CLKID_BT656_COMP>, + <&clkc CLKID_BT656>; + clock-names = "cts_bt656_clk1", + "clk_gate_bt656"; + /* bt656in1, bt656in2 */ + bt656in1 { + bt656_id = <1>; + status = "disabled"; + }; + }; + + aml_cams { + compatible = "amlogic, cams_prober"; + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&cam_dvp_pins &gen_clk_ee_z>; + clocks = <&clkc CLKID_GEN_CLK>; + clock-names = "g12a_24m"; + cam_0{ + cam_name = "gc2145"; + front_back = <0>; + /*u200 i2c2 gpio conflict with ethmac*/ + camera-i2c-bus = <&i2c2>; + gpio_pwdn-gpios = <&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>; + gpio_rst-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH>; + mirror_flip = <1>; + vertical_flip = <1>; + spread_spectrum = <0>; + bt_path = "gpio"; + bt_path_count = <1>; + vdin_path = <0>; + status = "okay"; + }; + }; gpio_keypad{ compatible = "amlogic, gpio_keypad"; @@ -310,7 +364,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -327,6 +381,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -411,6 +466,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -781,6 +841,13 @@ }; }; +&i2c2 { + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_master_pins2>; + clock-frequency = <100000>; +}; + &i2c3 { status = "okay"; pinctrl-names="default"; @@ -1116,6 +1183,32 @@ }; }; + clk12_24_z_pins:clk12_24_z_pins { + mux { + groups = "clk12_24_z"; + function = "clk12_24_ee"; + drive-strength = <3>; + }; + }; + + gen_clk_ee_z: gen_clk_ee_z { + mux { + groups="gen_clk_ee_z"; + function="gen_clk_ee"; + drive-strength = <3>; + }; + }; + + cam_dvp_pins:cam_dvp_pins { + mux { + groups = "bt656_a_vs", "bt656_a_hs", "bt656_a_clk", + "bt656_a_din0", "bt656_a_din1", "bt656_a_din2", + "bt656_a_din3", "bt656_a_din4", "bt656_a_din5", + "bt656_a_din6", "bt656_a_din7"; + function = "bt656"; + }; + }; + }; /* end of pinctrl_periphs */ &pinctrl_aobus { diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_1g.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_1g.dts index 9bb668dce0bf..1fe4278e5257 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_1g.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_1g.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x0 0x100000 0x0 0x3ff00000>; + linux,usable-memory = <0x0 0x000000 0x0 0x40000000>; }; reserved-memory { @@ -149,6 +149,12 @@ size = <0x0 0x04000000>; alignment = <0x0 0x400000>; }; + vm0_cma_reserved:linux,vm0_cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x2000000>; + alignment = <0x0 0x400000>; + }; }; gpioleds { @@ -228,13 +234,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -282,6 +288,54 @@ dev_name = "ionvideo"; status = "okay"; }; + vm0 { + compatible = "amlogic, vm"; + memory-region = <&vm0_cma_reserved>; + dev_name = "vm0"; + status = "disabled"; + vm_id = <0>; + }; + + amvdec_656in { + /*bt656 gpio conflict with i2c0*/ + compatible = "amlogic, amvdec_656in"; + dev_name = "amvdec_656in"; + status = "disabled"; + reg = <0x0 0xffe02000 0x0 0x7c>; + clocks = <&clkc CLKID_BT656_COMP>, + <&clkc CLKID_BT656>; + clock-names = "cts_bt656_clk1", + "clk_gate_bt656"; + /* bt656in1, bt656in2 */ + bt656in1 { + bt656_id = <1>; + status = "disabled"; + }; + }; + + aml_cams { + compatible = "amlogic, cams_prober"; + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&cam_dvp_pins &gen_clk_ee_z>; + clocks = <&clkc CLKID_GEN_CLK>; + clock-names = "g12a_24m"; + cam_0{ + cam_name = "gc2145"; + front_back = <0>; + /*u200 i2c2 gpio conflict with ethmac*/ + camera-i2c-bus = <&i2c2>; + gpio_pwdn-gpios = <&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>; + gpio_rst-gpios = <&gpio GPIOZ_12 GPIO_ACTIVE_HIGH>; + mirror_flip = <1>; + vertical_flip = <1>; + spread_spectrum = <0>; + bt_path = "gpio"; + bt_path_count = <1>; + vdin_path = <0>; + status = "okay"; + }; + }; gpio_keypad{ compatible = "amlogic, gpio_keypad"; @@ -310,7 +364,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -327,6 +381,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -411,6 +466,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -781,6 +841,13 @@ }; }; +&i2c2 { + status = "disabled"; + pinctrl-names="default"; + pinctrl-0=<&i2c2_master_pins2>; + clock-frequency = <100000>; +}; + &i2c3 { status = "okay"; pinctrl-names="default"; @@ -1116,6 +1183,32 @@ }; }; + clk12_24_z_pins:clk12_24_z_pins { + mux { + groups = "clk12_24_z"; + function = "clk12_24_ee"; + drive-strength = <3>; + }; + }; + + gen_clk_ee_z: gen_clk_ee_z { + mux { + groups="gen_clk_ee_z"; + function="gen_clk_ee"; + drive-strength = <3>; + }; + }; + + cam_dvp_pins:cam_dvp_pins { + mux { + groups = "bt656_a_vs", "bt656_a_hs", "bt656_a_clk", + "bt656_a_din0", "bt656_a_din1", "bt656_a_din2", + "bt656_a_din3", "bt656_a_din4", "bt656_a_din5", + "bt656_a_din6", "bt656_a_din7"; + function = "bt656"; + }; + }; + }; /* end of pinctrl_periphs */ &pinctrl_aobus { diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts index 496f964fb237..1b5bb0f0155b 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts @@ -213,13 +213,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -383,7 +383,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -398,6 +398,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -472,6 +473,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts index a17f04e32db3..bbbbb344343b 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot_vccktest.dts @@ -214,13 +214,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -384,7 +384,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -399,6 +399,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -473,6 +474,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts index 151b2bb48312..927ef1bb2e29 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_drm_buildroot.dts @@ -214,13 +214,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -384,7 +384,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -399,6 +399,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -473,6 +474,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts index 6d415887c84e..d45f54b86f3d 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211.dts @@ -252,13 +252,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -318,7 +318,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -334,6 +334,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -413,6 +414,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_1g.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_1g.dts index e0564dd2943f..c463f06ac21a 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_1g.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_1g.dts @@ -246,13 +246,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -312,7 +312,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -328,6 +328,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -407,6 +408,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_512m.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_512m.dts index 1af94581e631..88edd7a1e77a 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_512m.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_512m.dts @@ -241,13 +241,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -307,7 +307,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -323,6 +323,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -402,6 +403,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts index 84330840e39d..c2ac3e54fafe 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u211_buildroot.dts @@ -225,13 +225,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -372,7 +372,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -388,6 +388,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -467,6 +468,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212.dts index bcd08a225109..83da45b4fdb6 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x0 0x100000 0x0 0x7ff00000>; + linux,usable-memory = <0x0 0x000000 0x0 0x80000000>; }; reserved-memory { @@ -252,13 +252,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -306,19 +306,47 @@ dev_name = "ionvideo"; status = "okay"; }; - dvb{ - compatible = "amlogic, dvb"; - dev_name = "dvb"; - status = "ok"; - /*"parallel","serial","disable"*/ - ts2 = "parallel"; - ts2_control = <0>; - ts2_invert = <0>; - }; + /*dvb { + * compatible = "amlogic, dvb"; + * dev_name = "dvb"; + * + * fe0_mode = "external"; + * fe0_demod = "Atbm8881"; + * fe0_i2c_adap_id = <&i2c2>; + * fe0_demod_i2c_addr = <0xc0>; + * fe0_ts = <1>; + * fe0_reset_value = <0>; + * fe0_reset_gpio = <&gpio GPIOZ_1 GPIO_ACTIVE_HIGH>; + * + * ts1 = "parallel"; + * ts1_control = <0>; + * ts1_invert = <0>; + * interrupts = <0 23 1 + * 0 5 1 + * 0 21 1 + * 0 19 1 + * 0 25 1 + * 0 18 1 + * 0 24 1>; + * interrupt-names = "demux0_irq", + * "demux1_irq", + * "demux2_irq", + * "dvr0_irq", + * "dvr1_irq", + * "dvrfill0_fill", + * "dvrfill1_flush"; + * pinctrl-names = "p_ts1"; + * pinctrl-0 = <&dvb_p_ts1_pins>; + * clocks = <&clkc CLKID_DEMUX + * &clkc CLKID_AHB_ARB0 + * &clkc CLKID_DOS_PARSER>; + * clock-names = "demux", "ahbarb0", "parser_top"; + *}; + */ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -334,7 +362,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; - + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; key-device = "normal"; @@ -413,6 +441,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -783,6 +816,19 @@ }; }; +/* + *if use i2c2_master_pins2 + *please disable internal_eth_pins + *in case pinmux conflict + */ +/*&i2c2 { + * status = "okay"; + * pinctrl-names="default"; + * pinctrl-0=<&i2c2_master_pins2>; + * clock-frequency = <300000>; + *}; + */ + &i2c3 { status = "disabled"; pinctrl-names="default"; diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_1g.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_1g.dts index 6f414af19619..80821091057e 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_1g.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_1g.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x0 0x100000 0x0 0x3ff00000>; + linux,usable-memory = <0x0 0x000000 0x0 0x40000000>; }; @@ -246,13 +246,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -300,19 +300,47 @@ dev_name = "ionvideo"; status = "okay"; }; - dvb{ - compatible = "amlogic, dvb"; - dev_name = "dvb"; - status = "ok"; - /*"parallel","serial","disable"*/ - ts2 = "parallel"; - ts2_control = <0>; - ts2_invert = <0>; - }; + /*dvb { + * compatible = "amlogic, dvb"; + * dev_name = "dvb"; + * + * fe0_mode = "external"; + * fe0_demod = "Atbm8881"; + * fe0_i2c_adap_id = <&i2c2>; + * fe0_demod_i2c_addr = <0xc0>; + * fe0_ts = <1>; + * fe0_reset_value = <0>; + * fe0_reset_gpio = <&gpio GPIOZ_1 GPIO_ACTIVE_HIGH>; + * + * ts1 = "parallel"; + * ts1_control = <0>; + * ts1_invert = <0>; + * interrupts = <0 23 1 + * 0 5 1 + * 0 21 1 + * 0 19 1 + * 0 25 1 + * 0 18 1 + * 0 24 1>; + * interrupt-names = "demux0_irq", + * "demux1_irq", + * "demux2_irq", + * "dvr0_irq", + * "dvr1_irq", + * "dvrfill0_fill", + * "dvrfill1_flush"; + * pinctrl-names = "p_ts1"; + * pinctrl-0 = <&dvb_p_ts1_pins>; + * clocks = <&clkc CLKID_DEMUX + * &clkc CLKID_AHB_ARB0 + * &clkc CLKID_DOS_PARSER>; + * clock-names = "demux", "ahbarb0", "parser_top"; + *}; + */ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -328,6 +356,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -407,6 +436,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ @@ -774,6 +808,19 @@ }; }; +/* + *if use i2c2_master_pins2 + *please disable internal_eth_pins + *in case pinmux conflict + */ +/*&i2c2 { + * status = "okay"; + * pinctrl-names="default"; + * pinctrl-0=<&i2c2_master_pins2>; + * clock-frequency = <300000>; + *}; + */ + &i2c3 { status = "disabled"; pinctrl-names="default"; diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts index c78baf374f49..0d3a73079a8e 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905x2_u212_buildroot.dts @@ -225,13 +225,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -372,7 +372,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -388,6 +388,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -467,6 +468,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905y2_u220.dts b/arch/arm64/boot/dts/amlogic/g12a_s905y2_u220.dts index 13f8bc2ce316..1af01b2b46d7 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905y2_u220.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905y2_u220.dts @@ -209,13 +209,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -291,7 +291,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -307,6 +307,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -386,6 +387,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts b/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts index 270c6b9e540d..cec20dd0bf39 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905y2_u221.dts @@ -44,7 +44,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x0 0x100000 0x0 0x7ff00000>; + linux,usable-memory = <0x0 0x000000 0x0 0x80000000>; }; reserved-memory { @@ -199,13 +199,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -257,7 +257,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -273,6 +273,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -352,6 +353,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12b-sched-energy.dtsi b/arch/arm64/boot/dts/amlogic/g12b-sched-energy.dtsi index 1c5fe160b001..796f592ae9f7 100644 --- a/arch/arm64/boot/dts/amlogic/g12b-sched-energy.dtsi +++ b/arch/arm64/boot/dts/amlogic/g12b-sched-energy.dtsi @@ -29,7 +29,7 @@ 221 54 332 78 399 92 - 465 11 + 465 116 503 135 535 162 567 184 diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts index 4786033940b4..fa545c35feed 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts @@ -163,7 +163,7 @@ compatible = "shared-dma-pool"; reusable; status = "okay"; - size = <0x0 0x1f000000>; + size = <0x0 0x10000000>; alignment = <0x0 0x400000>; }; @@ -239,13 +239,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -322,7 +322,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -338,6 +338,8 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; + keysn_0: key_0{ key-name = "usid"; @@ -417,6 +419,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts index 089b9bb11aa3..30a09e5013bf 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts @@ -45,7 +45,7 @@ memory@00000000 { device_type = "memory"; - linux,usable-memory = <0x0 0x100000 0x0 0x7ff00000>; + linux,usable-memory = <0x0 0x000000 0x0 0x80000000>; }; reserved-memory { @@ -149,6 +149,16 @@ }; }; + gpioleds { + compatible = "gpio-leds"; + status = "okay"; + sys_led { + label="sys_led"; + gpios=<&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; + default-state ="on"; + }; + }; + cvbsout { compatible = "amlogic, cvbsout-g12b"; dev_name = "cvbsout"; @@ -207,13 +217,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -282,7 +292,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -298,6 +308,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -377,6 +388,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey efusekey:efusekey{ diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts index 68f596fea553..5d81dd3c4217 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot.dts @@ -250,13 +250,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -422,7 +422,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -437,6 +437,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -511,6 +512,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey amlvecm { diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts index e2bc49b9e71b..6a304e48ccf0 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400_buildroot_vccktest.dts @@ -216,13 +216,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -388,7 +388,7 @@ unifykey{ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -403,6 +403,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -477,6 +478,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey amlvecm { diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts index d26cd2bb3bf3..c4767fccfc99 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts @@ -171,13 +171,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -421,7 +421,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -435,7 +435,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -472,17 +472,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1091,7 +1091,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1108,6 +1108,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1192,6 +1193,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts index edac4180ab4e..46a3d5aadf14 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts @@ -150,13 +150,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -400,7 +400,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -414,7 +414,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -451,17 +451,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1136,7 +1136,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1152,6 +1152,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1231,6 +1232,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts index b43f41ae6066..85f64e4ca09b 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts @@ -161,13 +161,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1080,7 +1080,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1096,6 +1096,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1175,6 +1176,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts index cb0d7e1433d0..df862e17defe 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts @@ -180,13 +180,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -518,7 +518,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -532,7 +532,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -569,17 +569,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1100,7 +1100,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1117,6 +1117,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1201,6 +1202,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts index b2a48e90b5a3..353e3d077d64 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts @@ -152,13 +152,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -479,7 +479,7 @@ #thermal-sensor-cells = <1>; cooling_devices { cpufreq_cool_cluster0 { - min_state = <1000000>; + min_state = <1200000>; dyn_coeff = <140>; cluster_id = <0>; node_name = "cpufreq_cool0"; @@ -493,7 +493,7 @@ device_type = "cpucore"; }; gpufreq_cool { - min_state = <400>; + min_state = <500>; dyn_coeff = <437>; cluster_id = <0>; node_name = "gpufreq_cool0"; @@ -530,17 +530,17 @@ trips { switch_on: trip-point@0 { - temperature = <70000>; - hysteresis = <1000>; - type = "passive"; - }; - control: trip-point@1 { temperature = <80000>; hysteresis = <1000>; type = "passive"; }; + control: trip-point@1 { + temperature = <90000>; + hysteresis = <1000>; + type = "passive"; + }; hot: trip-point@2 { - temperature = <85000>; + temperature = <100000>; hysteresis = <5000>; type = "hot"; }; @@ -1137,7 +1137,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1153,6 +1153,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1232,6 +1233,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts index b2c34e74162f..101ad78b2091 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p230_2g.dts @@ -169,13 +169,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1125,7 +1125,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1142,6 +1142,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1226,6 +1227,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey dvb { compatible = "amlogic, dvb"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts index bb8c58114048..5c38487443f2 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p230_2g_buildroot.dts @@ -169,13 +169,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1188,7 +1188,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1204,6 +1204,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1283,6 +1284,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey dvb { compatible = "amlogic, dvb"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts index d054fa4b35e4..7d8d55ab43b9 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p231_1g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1015,7 +1015,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1031,6 +1031,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1110,6 +1111,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts index b5702a6db52b..ba85a853779d 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p231_2g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1015,7 +1015,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1031,6 +1031,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1110,6 +1111,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts index 800114c56de8..92f6e7d9ceef 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p231_2g_buildroot.dts @@ -162,13 +162,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1084,7 +1084,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1100,6 +1100,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1179,6 +1180,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts index 078e772e2391..dadb59aed48a 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_1g.dts @@ -100,7 +100,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x0 0x4C00000>; + size = <0x0 0x2400000>; alignment = <0x0 0x400000>; }; @@ -253,13 +253,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1162,7 +1162,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1179,6 +1179,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1263,6 +1264,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts index def676aa8249..2a7245aff17a 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_1g_buildroot.dts @@ -234,13 +234,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1223,7 +1223,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1239,6 +1239,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1318,6 +1319,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts index 71f920896bbd..f569d0799fc5 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts @@ -101,7 +101,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x0 0x4C00000>; + size = <0x0 0x2400000>; alignment = <0x0 0x400000>; }; @@ -254,13 +254,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1163,7 +1163,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1180,6 +1180,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1264,6 +1265,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts index 0e68cccd5139..6bfe499fead6 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p241_v2_1g_buildroot.dts @@ -233,13 +233,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1222,7 +1222,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1238,6 +1238,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1317,6 +1318,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts index ab695abaef22..bb6cc479e20c 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts @@ -91,13 +91,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -743,7 +743,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -759,6 +759,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -838,6 +839,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts index 593c77612282..f316571920da 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts @@ -91,13 +91,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -831,7 +831,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -847,6 +847,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -926,6 +927,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_sei210_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_sei210_1g.dts index d3086aa44071..916f139309e5 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_sei210_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_sei210_1g.dts @@ -161,13 +161,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1074,7 +1074,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1091,6 +1091,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1175,6 +1176,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxl_sei210_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_sei210_2g.dts index 41e52477e181..5140780d2f7f 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_sei210_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_sei210_2g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1085,7 +1085,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1102,6 +1102,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1186,6 +1187,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxl_skt.dts b/arch/arm64/boot/dts/amlogic/gxl_skt.dts index 56ecf91888ef..b78105139352 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_skt.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_skt.dts @@ -171,13 +171,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1080,7 +1080,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1097,6 +1097,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1181,6 +1182,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; diff --git a/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts b/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts index 38214b182158..d3bc6cd8c294 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts @@ -162,13 +162,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1110,7 +1110,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <15>; + unifykey-num = <16>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1126,6 +1126,7 @@ unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; + unifykey-index-15= <&keysn_15>; keysn_0: key_0{ key-name = "usid"; @@ -1205,6 +1206,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_15:key_15{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxm_q200_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxm_q200_2g_buildroot.dts index 20d0c1361eb4..e8dcafa47c2e 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_q200_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_q200_2g_buildroot.dts @@ -154,13 +154,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1182,7 +1182,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <14>; + unifykey-num = <15>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1197,6 +1197,7 @@ unifykey-index-11= <&keysn_11>; unifykey-index-12= <&keysn_12>; unifykey-index-13= <&keysn_13>; + unifykey-index-14= <&keysn_14>; keysn_0: key_0{ key-name = "usid"; @@ -1271,6 +1272,11 @@ key-device = "secure"; key-permit = "read","write","del"; }; + keysn_14:key_14{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxm_q201_1g.dts b/arch/arm64/boot/dts/amlogic/gxm_q201_1g.dts index 7aadc21335b7..a9043e836c4c 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_q201_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_q201_1g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1112,7 +1112,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1129,6 +1129,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1213,6 +1214,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/gxm_q201_2g.dts b/arch/arm64/boot/dts/amlogic/gxm_q201_2g.dts index 0b0bf702b7b9..0b9e93620866 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_q201_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_q201_2g.dts @@ -170,13 +170,13 @@ wifi_pwm_conf:wifi_pwm_conf{ pwm_channel1_conf { - pwms = <&pwm_ef MESON_PWM_0 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_ef MESON_PWM_0 30541 0>; + duty-cycle = <15270>; times = <8>; }; pwm_channel2_conf { - pwms = <&pwm_ef MESON_PWM_2 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_ef MESON_PWM_2 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; @@ -1115,7 +1115,7 @@ compatible = "amlogic, unifykey"; status = "ok"; - unifykey-num = <16>; + unifykey-num = <17>; unifykey-index-0 = <&keysn_0>; unifykey-index-1 = <&keysn_1>; unifykey-index-2 = <&keysn_2>; @@ -1132,6 +1132,7 @@ unifykey-index-13= <&keysn_13>; unifykey-index-14= <&keysn_14>; unifykey-index-15= <&keysn_15>; + unifykey-index-16= <&keysn_16>; keysn_0: key_0{ key-name = "usid"; @@ -1216,6 +1217,11 @@ key-device = "normal"; key-permit = "read","write","del"; }; + keysn_16:key_16{ + key-name = "netflix_mgkid"; + key-device = "secure"; + key-permit = "read","write","del"; + }; };//End unifykey }; &efuse { diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index 6dc1e489f4f7..99ca2a93b95e 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -1240,6 +1240,7 @@ &clkc CLKID_DEMUX &clkc CLKID_AHB_ARB0 &clkc CLKID_DOS + &clkc CLKID_CLK81 &clkc CLKID_VDEC_MUX &clkc CLKID_HCODEC_MUX &clkc CLKID_HEVC_MUX @@ -1248,6 +1249,7 @@ "demux", "ahbarb0", "vdec", + "clk_81", "clk_vdec_mux", "clk_hcodec_mux", "clk_hevc_mux", @@ -2324,6 +2326,24 @@ }; }; + /*dvb_p_ts1_pins: dvb_p_ts1_pins { + * tsin_b { + * groups = "tsin_b_sop_z", + * "tsin_b_valid_z", + * "tsin_b_clk_z", + * "tsin_b_din0_z", + * "tsin_b_din1", + * "tsin_b_din2", + * "tsin_b_din3", + * "tsin_b_din4", + * "tsin_b_din5", + * "tsin_b_din6", + * "tsin_b_din7"; + * function = "tsin_b"; + * }; + *}; + */ + pwm_a_pins: pwm_a { mux { groups = "pwm_a"; diff --git a/arch/arm64/boot/dts/amlogic/mesong12b.dtsi b/arch/arm64/boot/dts/amlogic/mesong12b.dtsi index 96c9b7060c2c..23463453873f 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12b.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12b.dtsi @@ -1862,6 +1862,7 @@ reg-names = "ISP"; interrupts = <0 142 4>; interrupt-names = "ISP"; + temper-buf-size = <24>; clocks = <&clkc CLKID_MIPI_ISP_CLK_COMP>, <&clkc CLKID_MIPI_CSI_PHY_CLK0_COMP>; clock-names = "cts_mipi_isp_clk_composite", diff --git a/arch/arm64/boot/dts/amlogic/txl_t962_p321_720p.dts b/arch/arm64/boot/dts/amlogic/txl_t962_p321_720p.dts index 8e154af23a53..ce7bea90cd69 100644 --- a/arch/arm64/boot/dts/amlogic/txl_t962_p321_720p.dts +++ b/arch/arm64/boot/dts/amlogic/txl_t962_p321_720p.dts @@ -86,7 +86,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x0 0x4C00000>; + size = <0x0 0x2400000>; alignment = <0x0 0x400000>; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts index 752a88c61a29..abf3c56be82f 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts @@ -681,13 +681,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts index b11a5fbb6774..71ae1696fa1c 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts @@ -725,13 +725,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts index c3f97d50c934..fbe808f93aef 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -686,13 +686,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index f1aa69e21e45..b3b9a8acf7b4 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -686,13 +686,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts index f1ab9ec83930..b838d0966d7b 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts @@ -97,7 +97,7 @@ ion_reserved:linux,ion-dev { compatible = "shared-dma-pool"; reusable; - size = <0x0 0x4C00000>; + size = <0x0 0x2400000>; alignment = <0x0 0x400000>; }; @@ -685,13 +685,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r314.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r314.dts index efc13a566b46..8cc857ebfb41 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r314.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r314.dts @@ -687,13 +687,13 @@ wifi_pwm_conf: wifi_pwm_conf { pwm_channel1_conf { - pwms = <&pwm_cd MESON_PWM_1 30040 0>; - duty-cycle = <15020>; + pwms = <&pwm_cd MESON_PWM_1 30541 0>; + duty-cycle = <15270>; times = <10>; }; pwm_channel2_conf { - pwms = <&pwm_cd MESON_PWM_3 30030 0>; - duty-cycle = <15015>; + pwms = <&pwm_cd MESON_PWM_3 30500 0>; + duty-cycle = <15250>; times = <12>; }; }; diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 8858f736c91a..ca232ac0b3f7 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -30,7 +30,6 @@ CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_JUMP_LABEL=y -CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y @@ -322,6 +321,9 @@ CONFIG_AMLOGIC_MEDIA_ENHANCEMENT=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM=y CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION=y CONFIG_AMLOGIC_MEDIA_GDC=y +CONFIG_AMLOGIC_VIDEO_CAPTURE=y +CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER=y +CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145=y CONFIG_AMLOGIC_DTV_DEMOD=y CONFIG_AMLOGIC_MMC=y CONFIG_AMLOGIC_NAND=y diff --git a/arch/arm64/configs/meson64_smarthome_defconfig b/arch/arm64/configs/meson64_smarthome_defconfig index 25a809f0654e..88013c6871c5 100644 --- a/arch/arm64/configs/meson64_smarthome_defconfig +++ b/arch/arm64/configs/meson64_smarthome_defconfig @@ -309,6 +309,7 @@ CONFIG_AMLOGIC_PCIE=y CONFIG_AMLOGIC_IRBLASTER=y CONFIG_AMLOGIC_IIO=y CONFIG_AMLOGIC_SARADC=y +CONFIG_AMLOGIC_DDR_TOOL=y CONFIG_AMLOGIC_DDR_WINDOW_TOOL=m CONFIG_AMLOGIC_LEDRING=y CONFIG_AMLOGIC_PCA9557_KEYPAD=y diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index fead7137c8d2..8c075154b8e9 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -189,7 +189,11 @@ alternative_else_nop_endif */ .endm +#ifdef CONFIG_AMLOGIC_VMAP + .macro kernel_exit, el, swap = 0 +#else .macro kernel_exit, el +#endif /* CONFIG_AMLOGIC_VMAP */ .if \el != 0 /* Restore the task's original addr_limit. */ ldr x20, [sp, #S_ORIG_ADDR_LIMIT] @@ -271,6 +275,18 @@ alternative_else_nop_endif ldp x26, x27, [sp, #16 * 13] ldp x28, x29, [sp, #16 * 14] ldr lr, [sp, #S_LR] +#ifdef CONFIG_AMLOGIC_VMAP + /* restore context sp and per-cpu vmap stack */ + .if \swap == 1 + stp x19, x20, [sp] + mov x20, sp + add x19, x20, #S_FRAME_SIZE + msr DBGWVR3_EL1, x19 + mrs x19, DBGWVR2_EL1 + mov sp, x19 + ldp x19, x20, [x20] + .endif +#endif /* CONFIG_AMLOGIC_VMAP */ add sp, sp, #S_FRAME_SIZE // restore sp .if \el == 0 @@ -313,8 +329,10 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 * Add a dummy stack frame, this non-standard format is fixed up * by unwind_frame() */ +#ifndef CONFIG_AMLOGIC_VMAP /* we need get right stack of el1_preempt */ stp x29, x19, [sp, #-16]! mov x29, sp +#endif /* !CONFIG_AMLOGIC_VMAP */ 9998: .endm @@ -447,6 +465,26 @@ ENDPROC(el1_error_invalid) */ .align 6 el1_sync: +#ifdef CONFIG_AMLOGIC_VMAP + /* + * register using: + * DBGWVR2_EL1: temp register and back up for sp_el1 of exception + * DBGWVR3_EL1: always point to per-cpu vmap stack + * switch sp_el1 to per-cpu vmap stack and using DBGWVR2_EL1 + * to back up sp_el1 under exception + */ + msr DBGWVR2_EL1, x29 + mrs x29, DBGWVR3_EL1 + sub x29, x29, #S_FRAME_SIZE + msr DBGWVR3_EL1, x29 + stp x19, x20, [x29] + mov x19, sp + mrs x20, DBGWVR2_EL1 + msr DBGWVR2_EL1, x19 + mov sp, x29 + mov x29, x20 + ldp x19, x20, [sp] +#endif /* CONFIG_AMLOGIC_VMAP */ kernel_entry 1 mrs x1, esr_el1 // read the syndrome register lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class @@ -474,6 +512,38 @@ el1_da: /* * Data abort handling */ +#ifdef CONFIG_AMLOGIC_VMAP + /* + * first handle vmap page fault, if result is not ok(eg, fault address + * is not in vmap range), then do normal data abort + */ + mrs x0, far_el1 + mov x2, sp + stp x29, x30, [sp, #-16]! /* add a stack frame for backtrace */ + mov x29, sp + bl handle_vmap_fault + ldp x29, x22, [sp], #16 + cmp x0, #0 + b.ne 888888f + kernel_exit 1, 1 /* exit for vmap fault */ +888888: + /* + * Not a vmap fault, copy context saved in per-cpu vmap stack + * to task stack, then switch stack back to task stack under + * exception + */ + mrs x0, DBGWVR2_EL1 + mov x1, sp + mov x2, #S_FRAME_SIZE + bl memcpy + add x17, x0, #S_FRAME_SIZE + str x17, [x0, #S_SP] + mrs x1, esr_el1 /* rebuild parameter for normal handler */ + mrs x18, DBGWVR3_EL1 + add x18, x18, #S_FRAME_SIZE + msr DBGWVR3_EL1, x18 + mov sp, x0 +#endif /* CONFIG_AMLOGIC_VMAP */ mrs x3, far_el1 enable_dbg // re-enable interrupts if they were enabled in the aborted context @@ -503,6 +573,20 @@ el1_undef: mov x0, sp b do_undefinstr el1_dbg: +#ifdef CONFIG_AMLOGIC_VMAP + /* switch back to task stack pointer */ + mrs x0, DBGWVR2_EL1 + mov x1, sp + mov x2, #S_FRAME_SIZE + bl memcpy + add x17, x0, #S_FRAME_SIZE + str x17, [x0, #S_SP] + mrs x1, esr_el1 /* rebuild parameter for normal handler */ + mrs x18, DBGWVR3_EL1 + add x18, x18, #S_FRAME_SIZE + msr DBGWVR3_EL1, x18 + mov sp, x0 +#endif /* CONFIG_AMLOGIC_VMAP */ /* * Debug exception handling */ @@ -527,7 +611,36 @@ ENDPROC(el1_sync) .align 6 el1_irq: +#ifdef CONFIG_AMLOGIC_VMAP + /* switch stack to avoid ELR lost if el1_da + * happen when saving context + */ + msr DBGWVR2_EL1, x29 + mrs x29, DBGWVR3_EL1 + sub x29, x29, #S_FRAME_SIZE + msr DBGWVR3_EL1, x29 + stp x19, x20, [x29] + mov x19, sp + mrs x20, DBGWVR2_EL1 + msr DBGWVR2_EL1, x19 + mov sp, x29 + mov x29, x20 + ldp x19, x20, [sp] +#endif /* CONFIG_AMLOGIC_VMAP */ kernel_entry 1 +#ifdef CONFIG_AMLOGIC_VMAP + /* switch back to task stack pointer */ + mrs x0, DBGWVR2_EL1 + mov x1, sp + mov x2, #S_FRAME_SIZE + mov sp, x0 + bl memcpy + add x17, sp, #S_FRAME_SIZE + str x17, [sp, #S_SP] + mrs x18, DBGWVR3_EL1 + add x18, x18, #S_FRAME_SIZE + msr DBGWVR3_EL1, x18 +#endif /* CONFIG_AMLOGIC_VMAP */ enable_dbg #ifdef CONFIG_TRACE_IRQFLAGS bl trace_hardirqs_off @@ -1035,3 +1148,20 @@ ENTRY(sys_rt_sigreturn_wrapper) mov x0, sp b sys_rt_sigreturn ENDPROC(sys_rt_sigreturn_wrapper) + +#ifdef CONFIG_AMLOGIC_VMAP +ENTRY(__setup_vmap_stack) + ldr x18, =vmap_stack + add x18, x18, x0 + mov x0, x18 + mov x1, #0 + mov x2, #THREAD_SIZE + mov x17, lr + bl memset /* clear stack buffer */ + mov lr, x17 + mov x0, #THREAD_START_SP + add x18, x18, x0 /* set stack top */ + msr DBGWVR3_EL1, x18 + ret +ENDPROC(__setup_vmap_stack) +#endif /* CONFIG_AMLOGIC_VMAP */ diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index fb0082ab40a7..0798abd4d692 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c @@ -133,6 +133,11 @@ NOKPROBE_SYMBOL(read_wb_reg); static void write_wb_reg(int reg, int n, u64 val) { +#ifdef CONFIG_AMLOGIC_VMAP + /* avoid write DBGWVR since we use it for special purpose */ + if (reg >= AARCH64_DBG_REG_WVR && reg < AARCH64_DBG_REG_WCR) + return; +#endif switch (reg + n) { GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_BVR, AARCH64_DBG_REG_NAME_BVR, val); GEN_WRITE_WB_REG_CASES(AARCH64_DBG_REG_BCR, AARCH64_DBG_REG_NAME_BCR, val); diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 4097031ea407..0185f898dced 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -59,6 +59,10 @@ #include #endif +#ifdef CONFIG_AMLOGIC_VMAP +#include +#endif + #define CREATE_TRACE_POINTS #include @@ -226,6 +230,9 @@ asmlinkage void secondary_start_kernel(void) cpu = task_cpu(current); set_my_cpu_offset(per_cpu_offset(cpu)); +#ifdef CONFIG_AMLOGIC_VMAP + __setup_vmap_stack(my_cpu_offset); +#endif /* * All kernel threads share the same mm context; grab a @@ -446,6 +453,9 @@ void __init smp_cpus_done(unsigned int max_cpus) void __init smp_prepare_boot_cpu(void) { set_my_cpu_offset(per_cpu_offset(smp_processor_id())); +#ifdef CONFIG_AMLOGIC_VMAP + __setup_vmap_stack(my_cpu_offset); +#endif /* * Initialise the static keys early as they may be enabled by the * cpufeature code. diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 5201bebcec07..28dee26114bb 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -25,6 +25,10 @@ #include #include +#ifdef CONFIG_AMLOGIC_VMAP +#include +#endif + /* * AArch64 PCS assigns the frame pointer to x29. * @@ -117,6 +121,15 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) return -EINVAL; } } +#ifdef CONFIG_AMLOGIC_VMAP + /* + * keep search stack for task + */ + if (on_vmap_stack(frame->sp, raw_smp_processor_id()) && + !on_vmap_stack(frame->fp, raw_smp_processor_id())) { + frame->sp = frame->fp; + } +#endif return 0; } diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 1e3be9064cfa..db2089aad9a3 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -12,6 +12,9 @@ #include #include #include +#ifdef CONFIG_AMLOGIC_VMAP +#include +#endif /* * This is allocated by cpu_suspend_init(), and used to store a pointer to @@ -39,6 +42,9 @@ void notrace __cpu_suspend_exit(void) { unsigned int cpu = smp_processor_id(); +#ifdef CONFIG_AMLOGIC_VMAP + __setup_vmap_stack(my_cpu_offset); +#endif /* * We are resuming from reset with the idmap active in TTBR0_EL1. * We must uninstall the idmap and restore the expected MMU diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index b2b036beb019..5f2f08594cea 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -97,6 +97,21 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, set_fs(fs); } +#ifdef CONFIG_AMLOGIC_VMAP +static void dump_backtrace_entry(unsigned long ip, unsigned long fp) +{ + unsigned long fp_size = 0; + + if (fp >= VMALLOC_START) { + fp_size = *((unsigned long *)fp) - fp; + /* fp cross IRQ or vmap stack */ + if (fp_size >= THREAD_SIZE) + fp_size = 0; + } + printk("[%016lx+%4ld][<%p>] %pS\n", + fp, fp_size, (void *) ip, (void *) ip); +} +#else static void dump_backtrace_entry(unsigned long where) { /* @@ -104,6 +119,7 @@ static void dump_backtrace_entry(unsigned long where) */ print_ip_sym(where); } +#endif static void __dump_instr(const char *lvl, struct pt_regs *regs) { @@ -186,7 +202,11 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) /* skip until specified stack frame */ if (!skip) { + #ifdef CONFIG_AMLOGIC_VMAP + dump_backtrace_entry(where, frame.fp); + #else dump_backtrace_entry(where); + #endif } else if (frame.fp == regs->regs[29]) { skip = 0; /* @@ -196,7 +216,11 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) * at which an exception has taken place, use regs->pc * instead. */ + #ifdef CONFIG_AMLOGIC_VMAP + dump_backtrace_entry(regs->pc, frame.fp); + #else dump_backtrace_entry(regs->pc); + #endif } ret = unwind_frame(tsk, &frame); if (ret < 0) @@ -394,6 +418,10 @@ static void force_signal_inject(int signal, int code, struct pt_regs *regs, show_unhandled_signals_ratelimited()) { pr_info("%s[%d]: %s: pc=%p\n", current->comm, task_pid_nr(current), desc, pc); +#ifdef CONFIG_AMLOGIC_USER_FAULT + show_all_pfn(current, regs); + show_regs(regs); +#endif dump_instr(KERN_INFO, regs); } diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 2a976fc4299c..df09e9860621 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -662,6 +662,20 @@ static const struct fault_info fault_info[] = { { do_bad, SIGBUS, 0, "unknown 63" }, }; +#ifdef CONFIG_AMLOGIC_VMAP +asmlinkage static void die_wrap(const struct fault_info *inf, + struct pt_regs *regs, unsigned int esr, + unsigned long addr) +{ + struct siginfo info; + + info.si_signo = inf->sig; + info.si_errno = 0; + info.si_code = inf->code; + info.si_addr = (void __user *)addr; + arm64_notify_die("", regs, &info, esr); +} +#endif /* * Dispatch a data abort to the relevant handler. */ @@ -669,7 +683,9 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { const struct fault_info *inf = esr_to_fault_info(esr); +#ifndef CONFIG_AMLOGIC_VMAP struct siginfo info; +#endif if (!inf->fn(addr, esr, regs)) return; @@ -677,11 +693,15 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n", inf->name, esr, addr); +#ifndef CONFIG_AMLOGIC_VMAP info.si_signo = inf->sig; info.si_errno = 0; info.si_code = inf->code; info.si_addr = (void __user *)addr; arm64_notify_die("", regs, &info, esr); +#else + die_wrap(inf, regs, esr, addr); +#endif } asmlinkage void __exception do_el0_irq_bp_hardening(void) diff --git a/drivers/amlogic/bluetooth/bt_device.c b/drivers/amlogic/bluetooth/bt_device.c index 594a14b99598..c926f13f7f6f 100644 --- a/drivers/amlogic/bluetooth/bt_device.c +++ b/drivers/amlogic/bluetooth/bt_device.c @@ -281,8 +281,13 @@ static int bt_probe(struct platform_device *pdev) #else pdata = (struct bt_dev_data *)(pdev->dev.platform_data); #endif - bt_device_init(pdata); + if (pdata->power_down_disable == 1) { + pdata->power_down_disable = 0; + bt_device_on(pdata); + pdata->power_down_disable = 1; + } + /* default to bluetooth off */ /* rfkill_switch_all(RFKILL_TYPE_BLUETOOTH, 1); */ /* bt_device_off(pdata); */ diff --git a/drivers/amlogic/cec/hdmi_ao_cec.c b/drivers/amlogic/cec/hdmi_ao_cec.c index 68a27b512fb9..3c0af63145b3 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.c +++ b/drivers/amlogic/cec/hdmi_ao_cec.c @@ -483,9 +483,9 @@ void cecb_irq_handle(void) /* clear start */ hdmirx_cec_write(DWC_CEC_TX_CNT, 0); hdmirx_set_bits_dwc(DWC_CEC_CTRL, 0, 0, 3); - CEC_ERR("warning:ARB_LOST\n"); + CEC_INFO("warning:ARB_LOST\n"); } else if (intr_cec & CEC_IRQ_TX_ERR_INITIATOR) { - CEC_ERR("warning:INITIATOR\n"); + CEC_INFO("warning:INITIATOR\n"); cec_tx_result = CEC_FAIL_OTHER; } else cec_tx_result = CEC_FAIL_OTHER; @@ -494,7 +494,7 @@ void cecb_irq_handle(void) /* RX error irq flag */ if (intr_cec & CEC_IRQ_RX_ERR_FOLLOWER) { - CEC_ERR("warning:FOLLOWER\n"); + CEC_INFO("warning:FOLLOWER\n"); hdmirx_cec_write(DWC_CEC_LOCK, 0); /* TODO: need reset cec hw logic? */ } @@ -2540,7 +2540,7 @@ static ssize_t hdmitx_cec_write(struct file *f, const char __user *buf, static void init_cec_port_info(struct hdmi_port_info *port, struct ao_cec_dev *cec_dev) { - unsigned int a, b, c, d, e = 0; + unsigned int a, b, c = 0, d, e = 0; unsigned int phy_head = 0xf000, phy_app = 0x1000, phy_addr; struct hdmitx_dev *tx_dev; @@ -2592,7 +2592,7 @@ static void init_cec_port_info(struct hdmi_port_info *port, port[e].type = HDMI_OUTPUT; } else { port[e].type = HDMI_INPUT; - port[e].port_id = a + 1; + port[e].port_id = c;/*a + 1; phy port - ui id*/ } port[e].cec_supported = 1; /* set ARC feature according mask */ @@ -2680,7 +2680,7 @@ static long hdmitx_cec_ioctl(struct file *f, void __user *argp = (void __user *)arg; unsigned int tmp; struct hdmi_port_info *port; - unsigned int a, b, c, d; + unsigned int a, b, c, d, i = 0; struct hdmitx_dev *tx_dev; /*unsigned int tx_hpd;*/ @@ -2815,8 +2815,14 @@ static long hdmitx_cec_ioctl(struct file *f, /* mixed for rx & tx */ /* a is current port idx, 0: tx device */ if (a != 0) { - tmp = hdmirx_get_connect_info(); - if (tmp & (1 << (a - 1))) + tmp = hdmirx_get_connect_info() & 0xF; + for (i = 0; i < CEC_PHY_PORT_NUM; i++) { + if (((cec_dev->port_seq >> i*4) & 0xF) == a) + break; + } + CEC_INFO("phy port:%d, ui port:%d\n", i, a); + + if ((tmp & (1 << i)) && (a != 0xF)) tmp = 1; else tmp = 0; diff --git a/drivers/amlogic/cec/hdmi_ao_cec.h b/drivers/amlogic/cec/hdmi_ao_cec.h index e256b617b017..aafc7d91f56c 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.h +++ b/drivers/amlogic/cec/hdmi_ao_cec.h @@ -19,14 +19,14 @@ #define __AO_CEC_H__ -#define CEC_DRIVER_VERSION "Ver 2018/11/21\n" +#define CEC_DRIVER_VERSION "Ver 2019/1/7\n" #define CEC_FRAME_DELAY msecs_to_jiffies(400) #define CEC_DEV_NAME "cec" #define CEC_EARLY_SUSPEND (1 << 0) #define CEC_DEEP_SUSPEND (1 << 1) - +#define CEC_PHY_PORT_NUM 4 #define HR_DELAY(n) (ktime_set(0, n * 1000 * 1000)) enum cecbver { diff --git a/drivers/amlogic/clk/g12a/g12a.c b/drivers/amlogic/clk/g12a/g12a.c index 9cf950f9f241..1364835d50c5 100644 --- a/drivers/amlogic/clk/g12a/g12a.c +++ b/drivers/amlogic/clk/g12a/g12a.c @@ -560,6 +560,55 @@ static struct clk_gate g12a_12m_gate = { }, }; +static u32 mux_table_gen_clk[] = { 0, 5, 6, 7, 20, 21, 22, + 23, 24, 25, 26, 27, 28, }; +static const char * const gen_clk_parent_names[] = { + "xtal", "gp0_pll", "gp1_pll", "hifi_pll", "fclk_div2", "fclk_div3", + "fclk_div4", "fclk_div5", "fclk_div7", "mpll0", "mpll1", + "mpll2", "mpll3" +}; + +static struct clk_mux g12a_gen_clk_sel = { + .reg = (void *)HHI_GEN_CLK_CNTL, + .mask = 0x1f, + .shift = 12, + .table = mux_table_gen_clk, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "gen_clk_sel", + .ops = &clk_mux_ops, + .parent_names = gen_clk_parent_names, + .num_parents = ARRAY_SIZE(gen_clk_parent_names), + }, +}; + +static struct clk_divider g12a_gen_clk_div = { + .reg = (void *)HHI_GEN_CLK_CNTL, + .shift = 0, + .width = 11, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "gen_clk_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "gen_clk_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_gate g12a_gen_clk = { + .reg = (void *)HHI_GEN_CLK_CNTL, + .bit_idx = 11, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "gen_clk", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "gen_clk_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + /* Everything Else (EE) domain gates */ static struct clk_gate g12a_spicc_0 = { @@ -752,6 +801,10 @@ static struct clk_hw *g12a_clk_hws[] = { [CLKID_24M] = &g12a_24m.hw, [CLKID_12M_DIV] = &g12a_12m_div.hw, [CLKID_12M_GATE] = &g12a_12m_gate.hw, + [CLKID_GEN_CLK_SEL] = &g12a_gen_clk_sel.hw, + [CLKID_GEN_CLK_DIV] = &g12a_gen_clk_div.hw, + [CLKID_GEN_CLK] = &g12a_gen_clk.hw, + }; /* Convenience tables to populate base addresses in .probe */ @@ -838,6 +891,7 @@ static struct clk_gate *g12a_clk_gates[] = { &g12a_efuse, &g12a_24m, &g12a_12m_gate, + &g12a_gen_clk, }; static void __init g12a_clkc_init(struct device_node *np) @@ -892,7 +946,10 @@ static void __init g12a_clkc_init(struct device_node *np) g12a_12m_div.reg = clk_base + (unsigned long)g12a_12m_div.reg; - + g12a_gen_clk_sel.reg = clk_base + + (unsigned long)g12a_gen_clk_sel.reg; + g12a_gen_clk_div.reg = clk_base + + (unsigned long)g12a_gen_clk_div.reg; /* Populate base address for gates */ for (i = 0; i < ARRAY_SIZE(g12a_clk_gates); i++) g12a_clk_gates[i]->reg = clk_base + diff --git a/drivers/amlogic/clk/gxl/clk_misc.c b/drivers/amlogic/clk/gxl/clk_misc.c index 26e495c979ec..47b74d7cc640 100644 --- a/drivers/amlogic/clk/gxl/clk_misc.c +++ b/drivers/amlogic/clk/gxl/clk_misc.c @@ -486,7 +486,7 @@ void amlogic_init_misc(void) &clk_divider_ops, saradc_hws[CLKID_SARADC_GATE - CLKID_SARADC_MUX], &clk_gate_ops, 0); - if (IS_ERR(clks[CLKID_PDM_COMP])) + if (IS_ERR(clks[CLKID_SARADC_COMP])) pr_err("%s: %d clk_register_composite saradc_composite error\n", __func__, __LINE__); diff --git a/drivers/amlogic/ddr_tool/Kconfig b/drivers/amlogic/ddr_tool/Kconfig index 7e5f0f902a54..d211eee189a1 100644 --- a/drivers/amlogic/ddr_tool/Kconfig +++ b/drivers/amlogic/ddr_tool/Kconfig @@ -9,8 +9,8 @@ config AMLOGIC_DDR_TOOL Please see folllowing configs config AMLOGIC_DDR_WINDOW_TOOL - bool "Meson ddr window tool" - default n + tristate "Meson ddr window tool" + default m depends on AMLOGIC_DDR_TOOL help This config enables test for ddr window. diff --git a/drivers/amlogic/ddr_tool/ddr_band_op_g12.c b/drivers/amlogic/ddr_tool/ddr_band_op_g12.c index ec0f50f526ee..b49770daf3d2 100644 --- a/drivers/amlogic/ddr_tool/ddr_band_op_g12.c +++ b/drivers/amlogic/ddr_tool/ddr_band_op_g12.c @@ -40,12 +40,18 @@ static void g12_dmc_port_config(struct ddr_bandwidth *db, int channel, int port) DMC_MON_G12_CTRL6, DMC_MON_G12_CTRL8}; int subport = -1; + /* clear all port mask */ + if (port < 0) { + writel(0, db->ddr_reg + rp[channel]); + writel(0, db->ddr_reg + rs[channel]); + return; + } + if (port >= PORT_MAJOR) subport = port - PORT_MAJOR; if (subport < 0) { val = readl(db->ddr_reg + rp[channel]); - val &= ~(0xffffff << 0); val |= (1 << port); writel(val, db->ddr_reg + rp[channel]); val = 0xffff; @@ -54,7 +60,6 @@ static void g12_dmc_port_config(struct ddr_bandwidth *db, int channel, int port) val = (0x1 << 23); /* select device */ writel(val, db->ddr_reg + rp[channel]); val = readl(db->ddr_reg + rs[channel]); - val &= ~(0xffff); val |= (1 << subport); writel(val, db->ddr_reg + rs[channel]); } @@ -124,7 +129,7 @@ static void g12_dmc_bandwidth_init(struct ddr_bandwidth *db) g12_dmc_bandwidth_enable(db); for (i = 0; i < db->channels; i++) - g12_dmc_port_config(db, i, db->port[i]); + g12_dmc_port_config(db, i, -1); } static int g12_handle_irq(struct ddr_bandwidth *db, struct ddr_grant *dg) diff --git a/drivers/amlogic/ddr_tool/ddr_band_op_gx.c b/drivers/amlogic/ddr_tool/ddr_band_op_gx.c index 387dd5534fe5..88b9f6e564af 100644 --- a/drivers/amlogic/ddr_tool/ddr_band_op_gx.c +++ b/drivers/amlogic/ddr_tool/ddr_band_op_gx.c @@ -37,6 +37,12 @@ static void gx_dmc_port_config(struct ddr_bandwidth *db, int channel, int port) unsigned int val; int subport = -1; + /* set to a unused port to clear bandwidth */ + if (port < 0) { + writel(0x8016ffff, db->ddr_reg + DMC_MON_CTRL2); + return; + } + if (port >= PORT_MAJOR) subport = port - PORT_MAJOR; @@ -89,7 +95,7 @@ static void gx_dmc_bandwidth_init(struct ddr_bandwidth *db) writel(db->clock_count, db->ddr_reg + DMC_MON_CTRL3); gx_dmc_bandwidth_enable(db); - gx_dmc_port_config(db, 0, db->port[0]); + gx_dmc_port_config(db, 0, -1); } static int gx_handle_irq(struct ddr_bandwidth *db, struct ddr_grant *dg) diff --git a/drivers/amlogic/ddr_tool/ddr_band_op_gxl.c b/drivers/amlogic/ddr_tool/ddr_band_op_gxl.c index c03b7b544205..b92a59a2ba25 100644 --- a/drivers/amlogic/ddr_tool/ddr_band_op_gxl.c +++ b/drivers/amlogic/ddr_tool/ddr_band_op_gxl.c @@ -44,9 +44,14 @@ static void gxl_dmc_port_config(struct ddr_bandwidth *db, int channel, int port) if (port >= PORT_MAJOR) subport = port - PORT_MAJOR; + /* clear all port mask */ + if (port < 0) { + writel(0, db->ddr_reg + port_reg[channel]); + return; + } + val = readl(db->ddr_reg + port_reg[channel]); if (port < 16) { - val &= ~(0xffff << 16); val |= ((1 << (16 + port)) | 0xffff); } else if (subport > 0) { val &= ~(0xffffffff); @@ -94,7 +99,7 @@ static void gxl_dmc_bandwidth_init(struct ddr_bandwidth *db) gxl_dmc_bandwidth_enable(db); for (i = 0; i < db->channels; i++) - gxl_dmc_port_config(db, i, db->port[i]); + gxl_dmc_port_config(db, i, -1); } diff --git a/drivers/amlogic/ddr_tool/ddr_bandwidth.c b/drivers/amlogic/ddr_tool/ddr_bandwidth.c index d15b0ebd8727..513ed839bc68 100644 --- a/drivers/amlogic/ddr_tool/ddr_bandwidth.c +++ b/drivers/amlogic/ddr_tool/ddr_bandwidth.c @@ -133,15 +133,34 @@ static char *find_port_name(int id) return NULL; } +static int format_port(char *buf, u64 port_mask) +{ + u64 t; + int i, size = 0; + char *name; + + for (i = 0; i < sizeof(u64) * 8; i++) { + t = 1ULL << i; + if (port_mask & t) { + name = find_port_name(i); + if (!name) + continue; + size += sprintf(buf + size, " %s\n", name); + } + } + return size; +} + static ssize_t ddr_channel_show(struct class *cla, struct class_attribute *attr, char *buf) { int size = 0, i; - for (i = 0; i < aml_db->channels; i++) - size += sprintf(buf + size, "ch %d:%3d, %s\n", - i, aml_db->port[i], - find_port_name(aml_db->port[i])); + for (i = 0; i < aml_db->channels; i++) { + size += sprintf(buf + size, "ch %d:%16llx: ports:\n", + i, aml_db->port[i]); + size += format_port(buf + size, aml_db->port[i]); + } return size; } @@ -156,8 +175,8 @@ static ssize_t ddr_channel_store(struct class *cla, return count; } - if (ch >= MAX_CHANNEL || - (ch && aml_db->cpu_type < MESON_CPU_MAJOR_ID_GXTVBB) || + if (ch >= MAX_CHANNEL || ch < 0 || + aml_db->cpu_type < MESON_CPU_MAJOR_ID_GXTVBB || port > MAX_PORTS) { pr_info("invalid channel %d or port %d\n", ch, port); return count; @@ -165,7 +184,10 @@ static ssize_t ddr_channel_store(struct class *cla, if (aml_db->ops && aml_db->ops->config_port) { aml_db->ops->config_port(aml_db, ch, port); - aml_db->port[ch] = port; + if (port < 0) /* clear port set */ + aml_db->port[ch] = 0; + else + aml_db->port[ch] |= 1ULL << port; } return count; @@ -226,11 +248,11 @@ static ssize_t mode_store(struct class *cla, if (val == MODE_AUTODETECT && aml_db->ops && aml_db->ops->config_port) { if (aml_db->mali_port[0] >= 0) { - aml_db->port[0] = aml_db->mali_port[0]; + aml_db->port[0] = (1ULL << aml_db->mali_port[0]); aml_db->ops->config_port(aml_db, 0, aml_db->port[0]); } if (aml_db->mali_port[1] >= 0) { - aml_db->port[1] = aml_db->mali_port[1]; + aml_db->port[1] = (1ULL << aml_db->mali_port[1]); aml_db->ops->config_port(aml_db, 1, aml_db->port[1]); } } @@ -282,8 +304,8 @@ static ssize_t clock_count_store(struct class *cla, static ssize_t bandwidth_show(struct class *cla, struct class_attribute *attr, char *buf) { - size_t s = 0, i; - int percent, rem; + size_t s = 0; + int percent, rem, i; #define BANDWIDTH_PREFIX "Total bandwidth: %8d KB/s, usage: %2d.%02d%%\n" if (aml_db->mode != MODE_ENABLE) @@ -295,8 +317,8 @@ static ssize_t bandwidth_show(struct class *cla, aml_db->total_bandwidth, percent, rem); for (i = 0; i < aml_db->channels; i++) { - s += sprintf(buf + s, "port%d: %8d KB/s\n", - aml_db->port[i], aml_db->bandwidth[i]); + s += sprintf(buf + s, "ch:%d port bit:%16llx: %8d KB/s\n", + i, aml_db->port[i], aml_db->bandwidth[i]); } return s; } @@ -592,6 +614,9 @@ static int __ref ddr_bandwidth_probe(struct platform_device *pdev) goto inval; } + if (!aml_db->ops->config_port) + goto inval; + r = class_register(&aml_ddr_class); if (r) pr_info("%s, class regist failed\n", __func__); diff --git a/drivers/amlogic/defendkey/defendkey.c b/drivers/amlogic/defendkey/defendkey.c index 1a7162326793..1ee1a1c4a1b5 100644 --- a/drivers/amlogic/defendkey/defendkey.c +++ b/drivers/amlogic/defendkey/defendkey.c @@ -52,6 +52,7 @@ struct defendkey_mem defendkey_rmem; #define CMD_SECURE_CHECK _IO('d', 0x01) #define CMD_DECRYPT_DTB _IO('d', 0x02) +#define DEFENDKEY_LIMIT_ADDR 0x0F000000 enum e_defendkey_type { e_upgrade_check = 0, @@ -134,38 +135,44 @@ static long defendkey_compat_ioctl(struct file *filp, static ssize_t defendkey_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - int i, ret; - unsigned long copy_base, copy_size; + ssize_t ret_value = ret_error; + int ret = -EINVAL; + unsigned long mem_base_phy, check_offset; - switch (decrypt_dtb) { - case e_upgrade_check: - case e_decrypt_dtb: - return ret_error; - case e_decrypt_dtb_success: - { - for (i = 0; i <= count/mem_size; i++) { - copy_size = mem_size; - copy_base = (unsigned long)buf+i*mem_size; - if ((i+1)*mem_size > count) - copy_size = count - mem_size*i; - ret = copy_to_user((void __user *)copy_base, - (const void *)mem_base_virt, copy_size); - if (ret) { - pr_err("%s:copy_to_user fail! ret:%d\n", - __func__, ret); - return ret_fail; - } - //__dma_flush_area((const void *)mem_base_virt, copy_size); + if (decrypt_dtb == e_decrypt_dtb_success) { + mem_base_phy = virt_to_phys(mem_base_virt); + + check_offset = aml_sec_boot_check(AML_D_Q_IMG_SIG_HDR_SIZE, + mem_base_phy, mem_size, 0); + if (AML_D_Q_IMG_SIG_HDR_SIZE == (check_offset & 0xFFFF)) + check_offset = (check_offset >> 16) & 0xFFFF; + else + check_offset = 0; + + if (mem_size < count) { + pr_err("%s:data size overflow!\n", __func__); + ret_value = ret_fail; + goto exit; } - if (!ret) { + + ret = copy_to_user((void __user *)buf, + (const void *)(mem_base_virt + check_offset), count); + if (ret) { + pr_err("%s:copy_to_user fail! ret:%d\n", + __func__, ret); + ret_value = ret_fail; + } else { pr_info("%s: copy data to user successfully!\n", __func__); - return ret_success; + ret_value = ret_success; } - } - default: - return ret_error; - } + + decrypt_dtb = e_upgrade_check; + } else + ret_value = ret_error; + +exit: + return ret_value; } static ssize_t defendkey_write(struct file *file, @@ -368,6 +375,11 @@ static int __init early_defendkey_para(char *buf) return -EINVAL; } + if (defendkey_rmem.base > DEFENDKEY_LIMIT_ADDR) { + pr_err("defendkey reserved memory base overflow!\n"); + return -EINVAL; + } + pr_info("%s, base:%lx, size:%lx\n", __func__, defendkey_rmem.base, defendkey_rmem.size); diff --git a/drivers/amlogic/defendkey/securekey.h b/drivers/amlogic/defendkey/securekey.h index 717352c2afaf..1473a5914e79 100644 --- a/drivers/amlogic/defendkey/securekey.h +++ b/drivers/amlogic/defendkey/securekey.h @@ -18,6 +18,7 @@ #if (defined CONFIG_ARM64) || (defined CONFIG_ARM64_A32) #define AML_D_P_UPGRADE_CHECK (0x80) #define AML_D_P_IMG_DECRYPT (0x40) +#define AML_D_Q_IMG_SIG_HDR_SIZE (0x100) #define AML_DATA_PROCESS (0x820000FF) #define GET_SHARE_MEM_INPUT_BASE 0x82000020 diff --git a/drivers/amlogic/ethernet/phy/amlogic.c b/drivers/amlogic/ethernet/phy/amlogic.c index d32ecbd93d90..e94026241a55 100644 --- a/drivers/amlogic/ethernet/phy/amlogic.c +++ b/drivers/amlogic/ethernet/phy/amlogic.c @@ -31,6 +31,7 @@ #include #include #include +#include #define SMI_ADDR_TSTWRITE 23 @@ -105,7 +106,76 @@ void internal_config(struct phy_device *phydev) phy_write(phydev, 0x14, 0x441A); /* A8_CONFIG */ pr_info("internal phy init\n"); } +/*fetch tx_amp from uboot*/ +#if 0 +int myAtoi(char *str) +{ + int i = 0; + int res = 0; + for (i = 0; str[i] != '\0'; ++i) + res = res*10 + str[i] - '0'; + return res; +} +#endif +unsigned int tx_amp; + +module_param_named(tx_amp, tx_amp, + uint, 0644); + +static char tx_amp_str[5] = "0"; +static int __init get_tx_amp(char *s) +{ + int ret = 0; + + if (s != NULL) + sprintf(tx_amp_str, "%s", s); + if (strcmp(tx_amp_str, "0") == 0) + tx_amp = 0; + else + ret = kstrtouint(tx_amp_str, 0, &tx_amp); + + return 0; +} +__setup("tx_amp=", get_tx_amp); + +void custom_internal_config(struct phy_device *phydev) +{ + unsigned int efuse_valid = 0; + unsigned int env_valid = 0; + unsigned int efuse_amp = 0; + unsigned int setup_amp = 0; + /*we will setup env tx_amp first to debug, + *if env tx_amp ==0 we will use the efuse + */ + efuse_amp = scpi_get_ethernet_calc(); + efuse_valid = (efuse_amp >> 3); + env_valid = (tx_amp >> 7); + if (env_valid || efuse_valid) { + + /*env valid use env tx_amp*/ + if (env_valid) { + /*debug mode use env tx_amp*/ + setup_amp = tx_amp & (~0x80); + pr_info("debug mode tx_amp = %d\n", setup_amp); + } else { + /* efuse is valid but env not*/ + setup_amp = efuse_amp; + pr_info("use efuse tx_amp = %d\n", setup_amp); + } + /*Enable Analog and DSP register Bank access by*/ + phy_write(phydev, 0x14, 0x0000); + phy_write(phydev, 0x14, 0x0400); + phy_write(phydev, 0x14, 0x0000); + phy_write(phydev, 0x14, 0x0400); + phy_write(phydev, 0x17, setup_amp); + phy_write(phydev, 0x14, 0x4418); + pr_info("set phy setup_amp = %d\n", setup_amp); + } else { + /*env not set, efuse not valid return*/ + pr_info("env not set, efuse also invalid\n"); + } +} void reset_internal_phy(struct phy_device *phydev) { int value; @@ -243,6 +313,11 @@ static int internal_config_init(struct phy_device *phydev) return genphy_config_init(phydev); } +static int custom_internal_config_init(struct phy_device *phydev) +{ + custom_internal_config(phydev); + return genphy_config_init(phydev); +} unsigned int support_internal_phy_wol; int internal_phy_suspend(struct phy_device *phydev) { @@ -284,7 +359,8 @@ void internal_phy_remove(struct phy_device *phydev) value = phy_read(phydev, 0x18); phy_write(phydev, 0x18, value | 0x1); } -static struct phy_driver amlogic_internal_driver[] = { { +static struct phy_driver amlogic_internal_driver[] = { +{ .phy_id = 0x01814400, .name = "amlogic internal phy", .phy_id_mask = 0x0fffffff, @@ -297,12 +373,27 @@ static struct phy_driver amlogic_internal_driver[] = { { .suspend = internal_phy_suspend, .resume = internal_phy_resume, .remove = internal_phy_remove, +}, { + + .phy_id = 0x01803301, + .name = "custom internal phy", + .phy_id_mask = 0x0fffffff, + .config_init = custom_internal_config_init, + /*1 means power down reset, 0 means marm reset*/ + /*bit 0-7,value f:count_sec=15*/ + .features = 0x10f, + .config_aneg = genphy_config_aneg, + .read_status = genphy_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, + .remove = internal_phy_remove, } }; module_phy_driver(amlogic_internal_driver); static struct mdio_device_id __maybe_unused amlogic_tbl[] = { { 0x01814400, 0xfffffff0 }, + { 0x01803301, 0xfffffff0 }, { } }; diff --git a/drivers/amlogic/mailbox/scpi_protocol.c b/drivers/amlogic/mailbox/scpi_protocol.c index f8592adedb27..20f05c10b454 100644 --- a/drivers/amlogic/mailbox/scpi_protocol.c +++ b/drivers/amlogic/mailbox/scpi_protocol.c @@ -541,3 +541,21 @@ int scpi_get_cec_val(enum scpi_std_cmd index, u32 *p_cec) } EXPORT_SYMBOL_GPL(scpi_get_cec_val); +u8 scpi_get_ethernet_calc(void) +{ + struct scpi_data_buf sdata; + struct mhu_data_buf mdata; + u8 temp = 0; + + struct __packed { + u32 status; + u8 eth_calc; + } buf; + + SCPI_SETUP_DBUF(sdata, mdata, SCPI_CL_NONE, + SCPI_CMD_GET_ETHERNET_CALC, temp, buf); + if (scpi_execute_cmd(&sdata)) + return -EPERM; + return buf.eth_calc; +} +EXPORT_SYMBOL_GPL(scpi_get_ethernet_calc); diff --git a/drivers/amlogic/media/Kconfig b/drivers/amlogic/media/Kconfig index bc316278ce43..ded82c05b026 100644 --- a/drivers/amlogic/media/Kconfig +++ b/drivers/amlogic/media/Kconfig @@ -94,6 +94,7 @@ source "drivers/amlogic/media/video_processor/Kconfig" source "drivers/amlogic/media/enhancement/Kconfig" source "drivers/amlogic/media/gdc/Kconfig" source "drivers/amlogic/media/algorithm/Kconfig" +source "drivers/amlogic/media/camera/Kconfig" endif source "drivers/amlogic/media/dtv_demod/Kconfig" endmenu diff --git a/drivers/amlogic/media/Makefile b/drivers/amlogic/media/Makefile index dfb73164f565..12f643b1e1d9 100644 --- a/drivers/amlogic/media/Makefile +++ b/drivers/amlogic/media/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_AMLOGIC_DTV_DEMOD) += dtv_demod/ obj-$(CONFIG_AMLOGIC_MEDIA_GDC) += gdc/ obj-$(CONFIG_AMLOGIC_MEDIA_ALGORITHM) += algorithm/ +obj-$(CONFIG_AMLOGIC_VIDEO_CAPTURE) += camera/ \ No newline at end of file diff --git a/drivers/amlogic/media/camera/Kconfig b/drivers/amlogic/media/camera/Kconfig new file mode 100644 index 000000000000..41d08be16cb7 --- /dev/null +++ b/drivers/amlogic/media/camera/Kconfig @@ -0,0 +1,559 @@ +menu "Amlogic Camera Support" + +config AMLOGIC_VIDEO_CAPTURE + tristate "Amlogic Platform Capture Driver" + depends on !SPARC32 && !SPARC64 &&!AMLOGIC_CAMERA_ENABLE + select VIDEOBUF_VMALLOC + depends on MEDIA_SUPPORT + select VIDEO_DEV + select VIDEO_V4L2 + default n + ---help--- + Amlogic capture driver interface in v4l style. + it can not work well together with + AMLOGIC_CAMERA_ENABLE + Say Y here if you want this driver. + +config AMLOGIC_CAPTURE_FRAME_ROTATE + bool "Enable function to support frame rotation" + depends on AMLOGIC_VIDEO_CAPTURE + default n + ---help--- + It will support frame rotation when enable this config + It will support frame rotation when enable this config + It will support frame rotation when enable this config + It will support frame rotation when enable this config + +config AMLOGIC_VM_DISABLE_VIDEOLAYER + bool "Force disable Videolayer when use vm" + depends on AMLOGIC_VIDEO_CAPTURE + default n + ---help--- + It will disable amvideo provider when enable this config + It will disable amvideo provider when enable this config + It will disable amvideo provider when enable this config + It will disable amvideo provider when enable this config + +config AMLOGIC_VIDEO_CAPTURE_PROBE + bool "Force check whether camera devices exist" + depends on AMLOGIC_VIDEO_CAPTURE + default n + ---help--- + Probe whether the camera devices exist by trying to read its + i2c port. It may cost some time, say Y here if you want it. + Probe whether the camera devices exist by trying to read its + i2c port. It may cost some time, say Y here if you want it. + +config AMLCAP_LOG_TIME_USEFORFRAMES + bool "Print Out The Time(ms) For Process A Frame" + depends on AMLOGIC_VIDEO_CAPTURE + default n + ---help--- + Print out the time used for process a frame, only for developers. + Print out the time used for process a frame, only for developers. + Print out the time used for process a frame, only for developers. + Print out the time used for process a frame, only for developers. + +config AMLOGIC_VIDEO_CAPTURE_GT2005 + tristate "Amlogic Platform Capture Driver for GT2005" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC0307 + tristate "Amlogic Platform Capture Driver for GC0307" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC0308 + tristate "Amlogic Platform Capture Driver for GC0308" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC0328 + tristate "Amlogic Platform Capture Driver for GC0328" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN_BT656IN + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC0329 + tristate "Amlogic Platform Capture Driver for GC0329" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC2015 + tristate "Amlogic Platform Capture Driver for GC2015" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC2035 + tristate "Amlogic Platform Capture Driver for GC2035" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC2155 + tristate "Amlogic Platform Capture Driver for GC2155" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_GC2145 + tristate "Amlogic Platform Capture Driver for GC2145" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_OV5640 + tristate "Amlogic Platform Capture Driver for OV5640" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_OV5642 + tristate "Amlogic Platform Capture Driver for OV5642" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +choice + prompt "OV5642 AUTO FOCUS FIRMWARE" + depends on AMLOGIC_VIDEO_CAPTURE_OV5642 + default NO_AUTO_FUCOS + +config NO_AUTO_FUCOS + bool "NONE" + ---help--- + no auto focus + no auto focus + no auto focus + no auto focus + +config AD5820 + bool "AD5820" + ---help--- + AD5820 + AD5820 + AD5820 + AD5820 + +config DW9714 + bool "DW9714" + ---help--- + DW9714 + DW9714 + DW9714 + DW9714 + +config AP5120 + bool "AP5120" + ---help--- + AP5120 + AP5120 + AP5120 + AP5120 + +endchoice + +config AMLOGIC_VIDEO_CAPTURE_OV7675 + tristate "Amlogic Platform Capture Driver for OV7675" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_OV2655 + tristate "Amlogic Platform Capture Driver for OV2655" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_SP0838 + tristate "Amlogic Platform Capture Driver for SP0838" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select VIDEOBUF_RESOURCE + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_SP2518 + tristate "Amlogic Platform Capture Driver for SP2518" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select VIDEOBUF_RESOURCE + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_SP0A19 + tristate "Amlogic Platform Capture Driver for SP0A19" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_SP1628 + tristate "Amlogic Platform Capture Driver for SP1628" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_HI253 + tristate "Amlogic Platform Capture Driver for HI253" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_HI704 + tristate "Amlogic Platform Capture Driver for HI704" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_HM2057 + tristate "Amlogic Platform Capture Driver for HM2057" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_HM5065 + tristate "Amlogic Platform Capture Driver for HM5065" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_HM1375 + tristate "Amlogic Platform Capture Driver for HM1375" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_OV3660 + tristate "Amlogic Platform Capture Driver for OV3660" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_OV5647 + tristate "Amlogic Platform Capture Driver for OV5647" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + + +config AMLOGIC_VIDEO_CAPTURE_HI2056 + tristate "Amlogic Platform Capture Driver for HI2056" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_MIPI + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_NT99250 + tristate "Amlogic Platform Capture Driver for NT99250" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_NT99252 + tristate "Amlogic Platform Capture Driver for NT99252" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_NT99340 + tristate "Amlogic Platform Capture Driver for NT99340" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_AR0543 + tristate "Amlogic Platform Capture Driver for AR0543" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEO_CAPTURE_AR0833 + tristate "Amlogic Platform Capture Driver for AR0833" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + + +config AMLOGIC_VIDEO_CAPTURE_BF3720 + tristate "Amlogic Platform Capture Driver for BF3720" + depends on AMLOGIC_VIDEO_CAPTURE + select VIDEOBUF_VMALLOC + select AMLOGIC_VIDEOIN_MANAGER + select TVIN + select TVIN_BT656 + select TVIN_VDIN + default n + ---help--- + Amlogic capture driver. + Say Y here if you want this driver. + Amlogic capture driver. + Say Y here if you want this driver. + +config AMLOGIC_VIDEOIN_MANAGER + tristate "amlogic video manager" + default n + ---help--- + this a test for video manager + +endmenu diff --git a/drivers/amlogic/media/camera/Makefile b/drivers/amlogic/media/camera/Makefile new file mode 100644 index 000000000000..04fb18c468d9 --- /dev/null +++ b/drivers/amlogic/media/camera/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for the amlogic platform camera interface device drivers. +# +amlflash-objs := common/flashlight.o +amlcamera-objs := common/plat_ctrl.o +#common/util.o +amlvm-objs := common/vm.o +cam_prober-objs := common/cam_prober.o common/config_parser.o +gc2145dri-objs := gc2145.o + +obj-y += amlflash.o +obj-y += amlvm.o +obj-y += amlcamera.o +obj-y += cam_prober.o +obj-$(CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145) += gc2145dri.o diff --git a/drivers/amlogic/media/camera/common/cam_prober.c b/drivers/amlogic/media/camera/common/cam_prober.c new file mode 100644 index 000000000000..98fe53121c85 --- /dev/null +++ b/drivers/amlogic/media/camera/common/cam_prober.c @@ -0,0 +1,1792 @@ +/* + * drivers/amlogic/media/camera/common/cam_prober.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONFIG_ARCH_MESON8 + +static struct platform_device *cam_pdev; +static struct clk *cam_clk; +static unsigned int bt_path_count; + +static unsigned int camera0_pwdn_pin; +static unsigned int camera0_rst_pin; +static unsigned int camera1_pwdn_pin; +static unsigned int camera1_rst_pin; + +static struct aml_cam_info_s *temp_cam; + +static int aml_camera_read_buff(struct i2c_adapter *adapter, + unsigned short dev_addr, char *buf, + int addr_len, int data_len) +{ + int i2c_flag = -1; + struct i2c_msg msgs[] = {{ + .addr = dev_addr, .flags = 0, + .len = addr_len, .buf = buf, + }, { + .addr = dev_addr, .flags = I2C_M_RD, + .len = data_len, .buf = buf, + } + }; + + i2c_flag = i2c_transfer(adapter, msgs, 2); + + return i2c_flag; +} + +static int aml_camera_write_buff(struct i2c_adapter *adapter, + unsigned short dev_addr, char *buf, int len) +{ + struct i2c_msg msg[] = {{ + .addr = dev_addr, .flags = 0, /*I2C_M_TEN*/ + .len = len, .buf = buf, + } + }; + + if (i2c_transfer(adapter, msg, 1) < 0) + return -1; + else + return 0; +} + +static int aml_i2c_get_byte(struct i2c_adapter *adapter, + unsigned short dev_addr, unsigned short addr) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + + if (aml_camera_read_buff(adapter, dev_addr, buff, 2, 1) < 0) + return -1; + return buff[0]; +} + +static int aml_i2c_put_byte(struct i2c_adapter *adapter, + unsigned short dev_addr, unsigned short addr, + unsigned char data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + buff[2] = data; + if (aml_camera_write_buff(adapter, dev_addr, buff, 3) < 0) + return -1; + return 0; +} + +static int aml_i2c_get_byte_add8(struct i2c_adapter *adapter, + unsigned short dev_addr, + unsigned short addr) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)(addr & 0xff); + + if (aml_camera_read_buff(adapter, dev_addr, buff, 1, 1) < 0) + return -1; + return buff[0]; +} + +static int aml_i2c_put_byte_add8(struct i2c_adapter *adapter, + unsigned short dev_addr, + unsigned short addr, unsigned char data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)(addr & 0xff); + buff[1] = data; + if (aml_camera_write_buff(adapter, dev_addr, buff, 2) < 0) + return -1; + return 0; +} + +int aml_i2c_put_word(struct i2c_adapter *adapter, unsigned short dev_addr, + unsigned short addr, unsigned short data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + buff[2] = (unsigned char)((data >> 8) & 0xff); + buff[3] = (unsigned char)(data & 0xff); + if (aml_camera_write_buff(adapter, dev_addr, buff, 4) < 0) + return -1; + return 0; +} + +static int aml_i2c_get_word(struct i2c_adapter *adapter, + unsigned short dev_addr, unsigned short addr) +{ + int ret; + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + if (aml_camera_read_buff(adapter, dev_addr, buff, 2, 2) < 0) + return -1; + ret = (buff[0] << 8) | (buff[1]); + return ret; +} + +static int aml_i2c_get_word_add8(struct i2c_adapter *adapter, + unsigned short dev_addr, + unsigned short addr) +{ + int ret; + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + if (aml_camera_read_buff(adapter, dev_addr, buff, 2, 2) < 0) + return -1; + ret = buff[0] | (buff[1] << 8); + return ret; +} + +static int aml_i2c_put_word_add8(struct i2c_adapter *adapter, + unsigned short dev_addr, unsigned char addr, + unsigned short data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)(addr & 0xff); + buff[1] = (unsigned char)(data >> 8 & 0xff); + buff[2] = (unsigned char)(data & 0xff); + if (aml_camera_write_buff(adapter, dev_addr, buff, 3) < 0) + return -1; + return 0; +} + + +extern struct i2c_client * +i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info); + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0307 +int gc0307_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x21, 0x00); + if (reg == 0x99) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0308 +int gc0308_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x21, 0x00); + if (reg == 0x9b) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0328 +int gc0328_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x21, 0xf0); + if (reg == 0x9d) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0329 +int gc0329_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + aml_i2c_put_byte_add8(adapter, 0x31, 0xfc, 0x16); /*select page 0*/ + reg = aml_i2c_get_byte_add8(adapter, 0x31, 0x00); + if (reg == 0xc0) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2015 +int gc2015_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x30, 0x00); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x30, 0x01); + if (reg[0] == 0x20 && reg[1] == 0x05) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HM2057 +int hm2057_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x24, 0x0001); + reg[1] = aml_i2c_get_byte(adapter, 0x24, 0x0002); + if (reg[0] == 0x20 && reg[1] == 0x56) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2035 +int gc2035_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xf0); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xf1); + if (reg[0] == 0x20 && reg[1] == 0x35) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2155 +int gc2155_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xf0); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xf1); + if (reg[0] == 0x21 && reg[1] == 0x55) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GT2005 +int gt2005_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x3c, 0x0000); + reg[1] = aml_i2c_get_byte(adapter, 0x3c, 0x0001); + if (reg[0] == 0x51 && reg[1] == 0x38) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV2659 +int ov2659_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x30, 0x300a); + reg[1] = aml_i2c_get_byte(adapter, 0x30, 0x300b); + if (reg[0] == 0x26 && reg[1] == 0x56) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV3640 +int ov3640_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x3c, 0x300a); + reg[1] = aml_i2c_get_byte(adapter, 0x3c, 0x300b); + if (reg[0] == 0x36 && reg[1] == 0x4c) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV3660 +int ov3660_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x3c, 0x300a); + reg[1] = aml_i2c_get_byte(adapter, 0x3c, 0x300b); + if (reg[0] == 0x36 && reg[1] == 0x60) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5640 +int ov5640_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x3c, 0x300a); + reg[1] = aml_i2c_get_byte(adapter, 0x3c, 0x300b); + if (reg[0] == 0x56 && reg[1] == 0x40) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5642 +int ov5642_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x3c, 0x300a); + reg[1] = aml_i2c_get_byte(adapter, 0x3c, 0x300b); + if (reg[0] == 0x56 && reg[1] == 0x42) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV7675 +int ov7675_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x21, 0x0a); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x21, 0x0b); + if (reg[0] == 0x76 && reg[1] == 0x73) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP0A19 +int sp0a19_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x21, 0x02); + if (reg == 0xa6) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP2518 +int sp2518_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x30, 0x02); + pr_info("sp2518 chip id reg = %x .\n", reg); + if (reg == 0x53) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP0838 +int sp0838_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x18, 0x02); + if (reg == 0x27) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HI253 +int hi253_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg; + + reg = aml_i2c_get_byte_add8(adapter, 0x20, 0x04); + if (reg == 0x92) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HM5065 +int hm5065_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x1F, 0x0000); + reg[1] = aml_i2c_get_byte(adapter, 0x1F, 0x0001); + if (reg[0] == 0x03 && reg[1] == 0x9e) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HM1375 +int hm1375_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x24, 0x0001); + reg[1] = aml_i2c_get_byte(adapter, 0x24, 0x0002); + pr_info("hm1375_v4l2_probe: device ID: 0x%x%x", reg[0], reg[1]); + if ((reg[0] == 0x13 || reg[0] == 0x03) && reg[1] == 0x75) + ret = 1; + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HI2056 +int hi2056_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x24, 0x0001); + reg[1] = aml_i2c_get_byte(adapter, 0x24, 0x0002); + pr_info("reg[0]=%x, reg[1]=%x\n", reg[0], reg[1]); + if (reg[0] == 0x20 && reg[1] == 0x56) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5647 +int ov5647_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte(adapter, 0x36, 0x300a); + reg[1] = aml_i2c_get_byte(adapter, 0x36, 0x300b); + pr_info("reg[0]:%x,reg[1]:%x\n", reg[0], reg[1]); + if (reg[0] == 0x56 && reg[1] == 0x47) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_AR0543 +int ar0543_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0, reg_val; + + reg_val = aml_i2c_get_word(adapter, 0x36, 0x3000); + pr_info("reg:0x%x\n", reg_val); + if (reg_val == 0x4800) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_AR0833 +int ar0833_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0, reg_val; + + reg_val = aml_i2c_get_word(adapter, 0x36, 0x3000); + pr_info("reg:0x%x\n", reg_val); + if (reg_val == 0x4B03) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP1628 +int sp1628_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x3c, 0x02); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xa0); + if (reg[0] == 0x16 && reg[1] == 0x28) + ret = 1; + return ret; +} +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_BF3720 +int bf3720_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x6e, 0xfc); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x6e, 0xfd); + if (reg[0] == 0x37 && reg[1] == 0x20) + ret = 1; + return ret; +} +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_BF3703 +int __init bf3703_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x6e, 0xfc); /*i2c addr:0x6f*/ + reg[1] = aml_i2c_get_byte_add8(adapter, 0x6e, 0xfd); + if (reg[0] == 0x37 && reg[1] == 0x03) + ret = 1; + return ret; +} +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_BF3920 +int __init bf3920_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x6e, 0xfc); /*i2c addr:0x6f*/ + reg[1] = aml_i2c_get_byte_add8(adapter, 0x6e, 0xfd); + if (reg[0] == 0x39 && reg[1] == 0x20) + ret = 1; + return ret; +} +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145 +int __init gc2145_v4l2_probe(struct i2c_adapter *adapter) +{ + int ret = 0; + unsigned char reg[2]; + + reg[0] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xf0); + reg[1] = aml_i2c_get_byte_add8(adapter, 0x3c, 0xf1); + /*datasheet chip id is error*/ + if (reg[0] == 0x21 && reg[1] == 0x45) + ret = 1; + pr_info("%s, ret = %d\n", __func__, ret); + return ret; +} +#endif + +struct aml_cam_dev_info_s { + unsigned char addr; + char *name; + unsigned char pwdn; + enum resolution_size max_cap_size; + aml_cam_probe_fun_t probe_func; +}; + +static const struct aml_cam_dev_info_s cam_devs[] = { +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0307 + { + .addr = 0x21, + .name = "gc0307", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = gc0307_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0308 + { + .addr = 0x21, + .name = "gc0308", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = gc0308_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0328 + { + .addr = 0x21, + .name = "gc0328", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = gc0328_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC0329 + { + .addr = 0x31, + .name = "gc0329", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = gc0329_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2015 + { + .addr = 0x30, + .name = "gc2015", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = gc2015_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HM2057 + { + .addr = 0x24, + .name = "hm2057", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = hm2057_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2035 + { + .addr = 0x3c, + .name = "gc2035", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = gc2035_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2155 + { + .addr = 0x3c, + .name = "gc2155", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = gc2155_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GT2005 + { + .addr = 0x3c, + .name = "gt2005", + .pwdn = 0, + .max_cap_size = SIZE_1600X1200, + .probe_func = gt2005_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV2659 + { + .addr = 0x30, + .name = "ov2659", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = ov2659_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV3640 + { + .addr = 0x3c, + .name = "ov3640", + .pwdn = 1, + .max_cap_size = SIZE_2048X1536; + .probe_func = ov3640_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV3660 + { + .addr = 0x3c, + .name = "ov3660", + .pwdn = 1, + .max_cap_size = SIZE_2048X1536, + .probe_func = ov3660_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5640 + { + .addr = 0x3c, + .name = "ov5640", + .pwdn = 1, + .max_cap_size = SIZE_2592X1944, + .probe_func = ov5640_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5642 + { + .addr = 0x3c, + .name = "ov5642", + .pwdn = 1, + .max_cap_size = SIZE_2592X1944, + .probe_func = ov5642_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV5647 + { + .addr = 0x36, /* really value should be 0x6c */ + .name = "ov5647", .pwdn = 1, .max_cap_size = SIZE_2592X1944, + .probe_func = ov5647_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_OV7675 + { + .addr = 0x21, + .name = "ov7675", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = ov7675_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP0A19 + { + .addr = 0x21, + .name = "sp0a19", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = sp0a19_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP0838 + { + .addr = 0x18, + .name = "sp0838", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = sp0838_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP2518 + { + .addr = 0x30, + .name = "sp2518", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = sp2518_v4l2_probe, + }, +#endif + +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HI253 + { + .addr = 0x20, + .name = "hi253", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = hi253_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HM5065 + { + .addr = 0x1f, + .name = "hm5065", + .pwdn = 0, + .max_cap_size = SIZE_2592X1944, + .probe_func = hm5065_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HM1375 + { + .addr = 0x24, + .name = "hm1375", + .pwdn = 1, + .max_cap_size = SIZE_1280X1024, + .probe_func = hm1375_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_HI2056 + { + .addr = 0x24, + .name = "mipi-hi2056", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = hi2056_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_AR0543 + { + .addr = 0x36, + .name = "ar0543", + .pwdn = 0, + .max_cap_size = SIZE_2592X1944, + .probe_func = ar0543_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_AR0833 + { + .addr = 0x36, + .name = "ar0833", + .pwdn = 0, + .max_cap_size = SIZE_2592X1944, + .probe_func = ar0833_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_SP1628 + { + .addr = 0x3c, + .name = "sp1628", + .pwdn = 1, + .max_cap_size = SIZE_1280X960, + .probe_func = sp1628_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_BF3720 + { + .addr = 0x6e, + .name = "bf3720", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = bf3720_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_BF3703 + { + .addr = 0x6e, + .name = "bf3703", + .pwdn = 1, + .max_cap_size = SIZE_640X480, + .probe_func = bf3703_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_BF3920 + { + .addr = 0x6e, + .name = "bf3920", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = bf3920_v4l2_probe, + }, +#endif +#ifdef CONFIG_AMLOGIC_VIDEO_CAPTURE_GC2145 + { + .addr = 0x3c, + .name = "gc2145", + .pwdn = 1, + .max_cap_size = SIZE_1600X1200, + .probe_func = gc2145_v4l2_probe, + }, +#endif +}; + +static const struct aml_cam_dev_info_s *get_cam_info_by_name(const char *name) +{ + int i; + + if (!name) + return NULL; + /*pr_info("cam_devs num is %d\n", ARRAY_SIZE(cam_devs));*/ + for (i = 0; i < ARRAY_SIZE(cam_devs); i++) { + if (!strcmp(name, cam_devs[i].name)) { + pr_info("camera dev %s found\n", cam_devs[i].name); + pr_info("camera i2c addr: 0x%x\n", cam_devs[i].addr); + return &cam_devs[i]; + } + } + return NULL; +} + +struct res_item { + enum resolution_size size; + char *name; +}; + +static const struct res_item res_item_array[] = { + {SIZE_320X240, "320X240"}, { + SIZE_640X480, "640X480" + }, {SIZE_720X405, "720X405"}, { + SIZE_800X600, "800X600" + }, {SIZE_960X540, "960X540"}, { + SIZE_1024X576, "1024X576" + }, {SIZE_960X720, "960X720"}, { + SIZE_1024X768, "1024X768" + }, {SIZE_1280X720, "1280X720"}, { + SIZE_1152X864, "1152X864" + }, {SIZE_1366X768, "1366X768"}, { + SIZE_1280X960, "1280X960" + }, {SIZE_1280X1024, "1280X1024"}, { + SIZE_1400X1050, "1400X1050" + }, {SIZE_1600X900, "1600X900"}, { + SIZE_1600X1200, "1600X1200" + }, {SIZE_1920X1080, "1920X1080"}, { + SIZE_1792X1344, "1792X1344" + }, {SIZE_2048X1152, "2048X1152"}, { + SIZE_2048X1536, "2048X1536" + }, {SIZE_2304X1728, "2304X1728"}, { + SIZE_2560X1440, "2560X1440" + }, {SIZE_2592X1944, "2592X1944"}, { + SIZE_3072X1728, "3072X1728" + }, {SIZE_2816X2112, "2816X2112"}, { + SIZE_3072X2304, "3072X2304" + }, {SIZE_3200X2400, "3200X2400"}, { + SIZE_3264X2448, "3264X2448" + }, {SIZE_3840X2160, "3840X2160"}, { + SIZE_3456X2592, "3456X2592" + }, {SIZE_3600X2700, "3600X2700"}, { + SIZE_4096X2304, "4096X2304" + }, {SIZE_3672X2754, "3672X2754"}, { + SIZE_3840X2880, "3840X2880" + }, {SIZE_4000X3000, "4000X3000"}, { + SIZE_4608X2592, "4608X2592" + }, {SIZE_4096X3072, "4096X3072"}, { + SIZE_4800X3200, "4800X3200" + }, {SIZE_5120X2880, "5120X2880"}, { + SIZE_5120X3840, "5120X3840" + }, {SIZE_6400X4800, "6400X480"}, + +}; + +static enum resolution_size get_res_size(const char *res_str) +{ + enum resolution_size ret = SIZE_NULL; + const struct res_item *item; + int i; + + if (!res_str) + return SIZE_NULL; + for (i = 0; i < ARRAY_SIZE(res_item_array); i++) { + item = &res_item_array[i]; + if (!strcmp(item->name, res_str)) { + ret = item->size; + return ret; + } + } + + return ret; +} + +static inline void GXBB_cam_enable_clk(void) +{ + struct clk *clk; + + clk = clk_get(&cam_pdev->dev, "clk_camera_24"); + if (IS_ERR(clk)) { + pr_info("cannot get camera m-clock\n"); + clk = NULL; + } else { + cam_clk = clk; + clk_prepare_enable(clk); + } +} + +static inline void GXBB_cam_disable_clk(int spread_spectrum) +{ + if (cam_clk) { + clk_disable_unprepare(cam_clk); + clk_put(cam_clk); + } +} + +static inline void GX12_cam_enable_clk(void) +{ + struct clk *clk; + unsigned long clk_rate; + + clk = devm_clk_get(&cam_pdev->dev, "g12a_24m"); + if (IS_ERR(clk)) { + pr_info("cannot get camera m-clock\n"); + clk = NULL; + } else { + cam_clk = clk; + clk_set_rate(clk, 24000000); + clk_prepare_enable(clk); + clk_rate = clk_get_rate(clk); + } +} + +static inline void GX12_cam_disable_clk(int spread_spectrum) +{ + if (cam_clk) { + clk_disable_unprepare(cam_clk); + devm_clk_put(&cam_pdev->dev, cam_clk); + pr_info("Success disable mclk\n"); + } +} + +static inline void cam_enable_clk(int clk, int spread_spectrum) +{ + pr_err("camera mclk enable failed, unsupport chip\n"); +} + +static inline void cam_disable_clk(int spread_spectrum) +{ + pr_err("camera mclk disable failed, unsupport chip\n"); +} + +/*static struct platform_device *cam_pdev;*/ + +void aml_cam_init(struct aml_cam_info_s *cam_dev) +{ + /*select XTAL as camera clock*/ + if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) + GXBB_cam_enable_clk(); + else if ((get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) || + (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B)) + GX12_cam_enable_clk(); + else + cam_enable_clk(cam_dev->mclk, cam_dev->spread_spectrum); + + /*coding style need: msleep < 20ms can sleep for up to 20ms*/ + msleep(20); + /*set camera power enable*/ + if (!cam_dev->front_back) { + cam_dev->pwdn_pin = camera0_pwdn_pin; + cam_dev->rst_pin = camera0_rst_pin; + } else { + cam_dev->pwdn_pin = camera1_pwdn_pin; + cam_dev->rst_pin = camera1_rst_pin; + } + + gpio_direction_output(cam_dev->pwdn_pin, cam_dev->pwdn_act); + + msleep(20); + + gpio_direction_output(cam_dev->pwdn_pin, !(cam_dev->pwdn_act)); + + msleep(20); + + gpio_direction_output(cam_dev->rst_pin, 0); + + msleep(20); + + gpio_direction_output(cam_dev->rst_pin, 1); + + msleep(20); + + pr_info("aml_cams: %s init OK\n", cam_dev->name); + +} + +void aml_cam_uninit(struct aml_cam_info_s *cam_dev) +{ + int ret; + + pr_info("aml_cams: %s uninit.\n", cam_dev->name); + /*set camera power disable*/ + /*coding style need: msleep < 20ms can sleep for up to 20ms*/ + /*msleep(20);*/ + + ret = gpio_direction_output(cam_dev->pwdn_pin, cam_dev->pwdn_act); + if (ret < 0) + pr_info("aml_cam_uninit pwdn_pin output pwdn_act failed\n"); + + msleep(20); + + ret = gpio_direction_output(cam_dev->rst_pin, 0); + if (ret < 0) + pr_info("aml_cam_uninit rst_pin output rst_pin failed\n"); + + msleep(20); + + if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) + GXBB_cam_disable_clk(cam_dev->spread_spectrum); + else if ((get_cpu_type() == MESON_CPU_MAJOR_ID_G12A) || + (get_cpu_type() == MESON_CPU_MAJOR_ID_G12B)) + GX12_cam_disable_clk(cam_dev->spread_spectrum); + else + cam_disable_clk(cam_dev->spread_spectrum); +} + +void aml_cam_flash(struct aml_cam_info_s *cam_dev, int is_on) +{ + int ret; + + if (cam_dev->flash_support) { + pr_info("aml_cams: %s flash %s.\n", + cam_dev->name, is_on ? "on" : "off"); + + ret = gpio_direction_output(cam_dev->flash_ctrl_pin, + cam_dev->flash_ctrl_level ? is_on : !is_on); + if (ret < 0) + pr_info("aml_cam_flash flash_ctrl_pin output failed\n"); + } +} + +void aml_cam_torch(struct aml_cam_info_s *cam_dev, int is_on) +{ + int ret; + + if (cam_dev->torch_support) { + pr_info("aml_cams: %s torch %s.\n", + cam_dev->name, is_on ? "on" : "off"); + + ret = gpio_direction_output(cam_dev->torch_ctrl_pin, + cam_dev->torch_ctrl_level ? is_on : !is_on); + if (ret < 0) + pr_info("aml_cam_torch torch_ctrl_pin output failed\n"); + } +} + +static struct list_head cam_head = LIST_HEAD_INIT(cam_head); + +#define DEBUG_DUMP_CAM_INFO + +static int fill_csi_dev(struct device_node *p_node, + struct aml_cam_info_s *cam_dev) +{ + const char *str; + int ret = 0; + + ret = of_property_read_string(p_node, "clk_channel", &str); + if (ret) { + pr_info("failed to read clock channel, \"a or b\"\n"); + cam_dev->clk_channel = CLK_CHANNEL_A; + } else { + pr_info("clock channel:clk %s\n", str); + if (strncmp("a", str, 1) == 0) + cam_dev->clk_channel = CLK_CHANNEL_A; + else + cam_dev->clk_channel = CLK_CHANNEL_B; + } + + return ret; + +} +static int fill_cam_dev(struct device_node *p_node, + struct aml_cam_info_s *cam_dev) +{ + const char *str; + int ret = 0; + const struct aml_cam_dev_info_s *cam_info = NULL; + struct device_node *adapter_node = NULL; + struct i2c_adapter *adapter = NULL; + unsigned int mclk = 0; + unsigned int vcm_mode = 0; + + if (!p_node || !cam_dev) + return -1; + + ret = of_property_read_u32(p_node, "front_back", &cam_dev->front_back); + if (ret) { + pr_info("get camera name failed!\n"); + goto err_out; + } + + ret = of_property_read_string(p_node, "cam_name", &cam_dev->name); + if (ret) { + pr_info("get camera name failed!\n"); + goto err_out; + } + + cam_dev->pwdn_pin = of_get_named_gpio(p_node, "gpio_pwdn-gpios", 0); + if (cam_dev->pwdn_pin == 0) { + pr_info("%s: failed to map gpio_pwdn !\n", cam_dev->name); + goto err_out; + } + + ret = gpio_request(cam_dev->pwdn_pin, "camera"); + if (ret < 0) + pr_info("aml_cam_init pwdn_pin request failed\n"); + + if (!cam_dev->front_back) + camera0_pwdn_pin = cam_dev->pwdn_pin; + else + camera1_pwdn_pin = cam_dev->pwdn_pin; + + cam_dev->rst_pin = of_get_named_gpio(p_node, "gpio_rst-gpios", 0); + if (cam_dev->rst_pin == 0) { + pr_info("%s: failed to map gpio_rst !\n", cam_dev->name); + goto err_out; + } + ret = gpio_request(cam_dev->rst_pin, "camera"); + if (ret < 0) + pr_info("aml_cam_init rst_pin request failed\n"); + + if (!cam_dev->front_back) + camera0_rst_pin = cam_dev->rst_pin; + else + camera1_rst_pin = cam_dev->rst_pin; + + cam_info = get_cam_info_by_name(cam_dev->name); + if (cam_info == NULL) { + pr_info("camera %s is not support\n", cam_dev->name); + ret = -1; + goto err_out; + } + + of_property_read_u32(p_node, "spread_spectrum", + &cam_dev->spread_spectrum); + + ret = of_property_read_string(p_node, "bt_path", &str); + if (ret) { + pr_info("failed to read bt_path\n"); + cam_dev->bt_path = BT_PATH_GPIO; + } else { + pr_info("bt_path :%d\n", cam_dev->bt_path); + if (strncmp("csi", str, 3) == 0) + cam_dev->bt_path = BT_PATH_CSI2; + else if (strncmp("gpio_b", str, 6) == 0) + cam_dev->bt_path = BT_PATH_GPIO_B; + else + cam_dev->bt_path = BT_PATH_GPIO; + } + of_property_read_u32(p_node, "bt_path_count", &cam_dev->bt_path_count); + bt_path_count = cam_dev->bt_path_count; + + cam_dev->pwdn_act = cam_info->pwdn; + cam_dev->i2c_addr = cam_info->addr; + pr_info("camer addr: 0x%x\n", cam_dev->i2c_addr); + pr_info("camer i2c bus: %d\n", cam_dev->i2c_bus_num); + + adapter_node = of_parse_phandle(p_node, "camera-i2c-bus", 0); + if (adapter_node) { + adapter = of_find_i2c_adapter_by_node(adapter_node); + of_node_put(adapter_node); + if (adapter == NULL) { + pr_err("%s, failed parse camera-i2c-bus\n", + __func__); + return -1; + } + } + + if (adapter && cam_info->probe_func) { + aml_cam_init(cam_dev); + if (cam_info->probe_func(adapter) != 1) { + pr_info("camera %s not on board\n", cam_dev->name); + ret = -1; + aml_cam_uninit(cam_dev); + goto err_out; + } + aml_cam_uninit(cam_dev); + } else { + pr_err("can not do probe function\n"); + ret = -1; + goto err_out; + } + + of_property_read_u32(p_node, "mirror_flip", &cam_dev->m_flip); + of_property_read_u32(p_node, "vertical_flip", &cam_dev->v_flip); + of_property_read_u32(p_node, "vdin_path", &cam_dev->vdin_path); + + ret = of_property_read_string(p_node, "max_cap_size", &str); + if (ret) + pr_info("failed to read max_cap_size\n"); + else { + pr_info("max_cap_size :%s\n", str); + cam_dev->max_cap_size = get_res_size(str); + } + if (cam_dev->max_cap_size == SIZE_NULL) + cam_dev->max_cap_size = cam_info->max_cap_size; + + ret = of_property_read_u32(p_node, "mclk", &mclk); + if (ret) + cam_dev->mclk = 24000; + else + cam_dev->mclk = mclk; + + ret = of_property_read_u32(p_node, "vcm_mode", &vcm_mode); + if (ret) + cam_dev->vcm_mode = 0; + else + cam_dev->vcm_mode = vcm_mode; + pr_info("vcm mode is %d\n", cam_dev->vcm_mode); + + ret = of_property_read_u32(p_node, "flash_support", + &cam_dev->flash_support); + if (cam_dev->flash_support) { + of_property_read_u32(p_node, "flash_ctrl_level", + &cam_dev->flash_ctrl_level); + ret = of_property_read_string(p_node, "flash_ctrl_pin", &str); + if (ret) { + pr_info("%s: failed to get flash_ctrl_pin!\n", + cam_dev->name); + cam_dev->flash_support = 0; + } else { + cam_dev->flash_ctrl_pin = of_get_named_gpio(p_node, + "flash_ctrl_pin", 0); + if (cam_dev->flash_ctrl_pin == 0) { + pr_info("%s: failed to map flash_ctrl_pin !\n", + cam_dev->name); + cam_dev->flash_support = 0; + cam_dev->flash_ctrl_level = 0; + } + ret = gpio_request(cam_dev->flash_ctrl_pin, "camera"); + if (ret < 0) + pr_info("camera flash_ctrl_pin request failed\n"); + } + } + + ret = of_property_read_u32(p_node, "torch_support", + &cam_dev->torch_support); + if (cam_dev->torch_support) { + of_property_read_u32(p_node, "torch_ctrl_level", + &cam_dev->torch_ctrl_level); + ret = of_property_read_string(p_node, "torch_ctrl_pin", &str); + if (ret) { + pr_info("%s: failed to get torch_ctrl_pin!\n", + cam_dev->name); + cam_dev->torch_support = 0; + } else { + cam_dev->torch_ctrl_pin = of_get_named_gpio(p_node, + "torch_ctrl_level", 0); + ret = gpio_request(cam_dev->torch_ctrl_pin, "camera"); + if (ret < 0) + pr_info("camera torch_ctrl_pin request failed\n"); + } + } + + ret = of_property_read_string(p_node, "interface", &str); + if (ret) { + pr_info("failed to read camera interface \"mipi or dvp\"\n"); + cam_dev->interface = CAM_DVP; + } else { + pr_info("camera interface:%s\n", str); + if (strncmp("dvp", str, 1) == 0) + cam_dev->interface = CAM_DVP; + else + cam_dev->interface = CAM_MIPI; + } + if (cam_dev->interface == CAM_MIPI) { + ret = fill_csi_dev(p_node, cam_dev); + if (ret < 0) + goto err_out; + } + + ret = of_property_read_string(p_node, "bayer_fmt", &str); + if (ret) { + pr_info("failed to read camera bayer fmt\n"); + cam_dev->bayer_fmt = TVIN_GBRG; + } else { + pr_info("color format:%s\n", str); + if (strncmp("BGGR", str, 4) == 0) + cam_dev->bayer_fmt = TVIN_BGGR; + else if (strncmp("RGGB", str, 4) == 0) + cam_dev->bayer_fmt = TVIN_RGGB; + else if (strncmp("GBRG", str, 4) == 0) + cam_dev->bayer_fmt = TVIN_GBRG; + else if (strncmp("GRBG", str, 4) == 0) + cam_dev->bayer_fmt = TVIN_GRBG; + else + cam_dev->bayer_fmt = TVIN_GBRG; + } + + ret = of_property_read_string(p_node, "config_path", &cam_dev->config); + if (ret) + pr_info("failed to read config_file path\n"); + else + pr_info("config path :%s\n", cam_dev->config); + +#ifdef DEBUG_DUMP_CAM_INFO + pr_info("=======cam %s info=======\n" + "i2c_bus_num: %d\n" + "pwdn_act: %d\n" + "front_back: %d\n" + "m_flip: %d\n" + "v_flip: %d\n" + "i2c_addr: 0x%x\n" + "config path:%s\n" + "bt_path:%d\n", + cam_dev->name, cam_dev->i2c_bus_num, cam_dev->pwdn_act, + cam_dev->front_back, cam_dev->m_flip, cam_dev->v_flip, + cam_dev->i2c_addr, cam_dev->config, cam_dev->bt_path); +#endif /* DEBUG_DUMP_CAM_INFO */ + + ret = 0; + +err_out: + return ret; +} + +static int do_read_work(char argn, char **argv) +{ + unsigned int dev_addr, reg_addr, data_len = 1, result; + unsigned int i2c_bus; + struct i2c_adapter *adapter; + + if (argn < 4) { + pr_err("args num error"); + return -1; + } + + if (!strncmp(argv[1], "i2c_bus_ao", 9)) + i2c_bus = 4; + else if (!strncmp(argv[1], "i2c_bus_0", 9)) + i2c_bus = 0; + else if (!strncmp(argv[1], "i2c_bus_1", 9)) + i2c_bus = 1; + else if (!strncmp(argv[1], "i2c_bus_2", 9)) + i2c_bus = 2; + else if (!strncmp(argv[1], "i2c_bus_3", 9)) + i2c_bus = 3; + else { + pr_err("bus name error!\n"); + return -1; + } + + adapter = i2c_get_adapter(i2c_bus); + + if (adapter == NULL) { + pr_info("no adapter!\n"); + return -1; + } + + dev_addr = kstrtol(argv[2], 16, NULL); + reg_addr = kstrtol(argv[3], 16, NULL); + if (argn == 5) { + pr_info("argv[4] is %s\n", argv[4]); + data_len = kstrtol(argv[4], 16, NULL); + } + + if (reg_addr > 256) { + if (data_len != 2) { + result = aml_i2c_get_byte(adapter, dev_addr, reg_addr); + pr_info("register [0x%04x]=0x%02x\n", reg_addr, result); + } else { + result = aml_i2c_get_word(adapter, dev_addr, reg_addr); + pr_info("register [0x%04x]=0x%04x\n", reg_addr, result); + } + } else { + if (data_len != 2) { + result = aml_i2c_get_byte_add8(adapter, + dev_addr, reg_addr); + pr_info("register [0x%02x]=0x%02x\n", reg_addr, result); + } else { + result = aml_i2c_get_word_add8(adapter, + dev_addr, reg_addr); + pr_info("register [0x%02x]=0x%04x\n", reg_addr, result); + } + } + + return 0; +} + +static int do_write_work(char argn, char **argv) +{ + unsigned int dev_addr, reg_addr, reg_val, data_len = 1, ret = 0; + unsigned int i2c_bus; + struct i2c_adapter *adapter; + + if (argn < 5) { + pr_err("args num error"); + return -1; + } + + if (!strncmp(argv[1], "i2c_bus_0", 9)) + i2c_bus = 0; + else if (!strncmp(argv[1], "i2c_bus_1", 9)) + i2c_bus = 1; + else if (!strncmp(argv[1], "i2c_bus_2", 9)) + i2c_bus = 2; + else if (!strncmp(argv[1], "i2c_bus_3", 9)) + i2c_bus = 3; + else if (!strncmp(argv[1], "i2c_bus_ao", 9)) + i2c_bus = 4; + else { + pr_err("bus name error!\n"); + return -1; + } + + adapter = i2c_get_adapter(i2c_bus); + + if (adapter == NULL) { + pr_info("no adapter!\n"); + return -1; + } + + dev_addr = kstrtol(argv[2], 16, NULL); + reg_addr = kstrtol(argv[3], 16, NULL); + reg_val = kstrtol(argv[4], 16, NULL); + if (argn == 6) + data_len = kstrtol(argv[5], 16, NULL); + if (reg_addr > 256) { + if (data_len != 2) { + if (aml_i2c_put_byte(adapter, dev_addr, + reg_addr, reg_val) < 0) { + pr_err("write error\n"); + ret = -1; + } else { + pr_info("write ok\n"); + ret = 0; + } + } else { + if (aml_i2c_put_word(adapter, dev_addr, + reg_addr, reg_val) < 0) { + pr_err("write error\n"); + ret = -1; + } else { + pr_info("write ok\n"); + ret = 0; + } + } + } else { + if (data_len != 2) { + if (aml_i2c_put_byte_add8(adapter, dev_addr, + reg_addr, reg_val) < 0) { + pr_err("write error\n"); + ret = -1; + } else { + pr_info("write ok\n"); + ret = 0; + } + } else { + if (aml_i2c_put_word_add8(adapter, dev_addr, + reg_addr, reg_val) < 0) { + pr_err("write error\n"); + ret = -1; + } else { + pr_info("write ok\n"); + ret = 0; + } + } + } + + return ret; +} + +static struct class *cam_clsp; + +static ssize_t show_help(struct class *class, struct class_attribute *attr, + char *buf) +{ + ssize_t size = 0; + + pr_info( + "echo [read | write] i2c_bus_type device_address register_address [value] [data_len] > i2c_debug\n" + "i2c_bus_type are: i2c_bus_ao, i2c_bus_a, i2c_bus_b, i2c_bus_c, i2c_bus_d\n" + "e.g.: echo read i2c_bus_ao 0x3c 0x18 1\n" + " echo write i2c_bus_ao 0x3c 0x18 0x24 1\n"); + return size; +} + +static ssize_t store_i2c_debug(struct class *class, + struct class_attribute *attr, const char *buf, + size_t count) +{ + int argn; + char *buf_work, *p, *para; + char cmd; + char *argv[6]; + + buf_work = kstrdup(buf, GFP_KERNEL); + p = buf_work; + + for (argn = 0; argn < 6; argn++) { + para = strsep(&p, " "); + if (para == NULL) + break; + argv[argn] = para; + pr_info("argv[%d] = %s\n", argn, para); + } + + if (argn < 4 || argn > 6) + goto end; + + cmd = argv[0][0]; + switch (cmd) { + case 'r': + case 'R': + do_read_work(argn, argv); + break; + case 'w': + case 'W': + do_write_work(argn, argv); + break; + } + return count; +end: + pr_err("error command!\n"); + kfree(buf_work); + return -EINVAL; +} + +static LIST_HEAD(info_head); + +static ssize_t cam_info_show(struct class *class, struct class_attribute *attr, + char *buf) +{ + struct list_head *p; + struct aml_cam_info_s *cam_info = NULL; + int count = 0; + + if (!list_empty(&info_head)) { + count += sprintf(&buf[count], + "name\t\tversion\t\t\t\tface_dir\t" + "i2c_addr\n"); + list_for_each(p, &info_head) { + cam_info = list_entry(p, struct aml_cam_info_s, + info_entry); + } + } + return count; +} + +static struct class_attribute aml_cam_attrs[] = { + __ATTR(i2c_debug, 0644, show_help, store_i2c_debug), + __ATTR_RO(cam_info), __ATTR(help, 0644, show_help, NULL), + __ATTR_NULL, +}; + +int aml_cam_info_reg(struct aml_cam_info_s *cam_info) +{ + int ret = -1; + + if (cam_info) { + list_add(&cam_info->info_entry, &info_head); + ret = 0; + } + return ret; +} + +int aml_cam_info_unreg(struct aml_cam_info_s *cam_info) +{ + int ret = -1; + struct list_head *p, *n; + struct aml_cam_info_s *tmp_info = NULL; + + if (cam_info) { + list_for_each_safe(p, n, &info_head) { + tmp_info = list_entry(p, struct aml_cam_info_s, + info_entry); + if (tmp_info == cam_info) { + list_del(p); + return 0; + } + } + } + return ret; +} + +static int aml_cams_probe(struct platform_device *pdev) +{ + struct device_node *cams_node = pdev->dev.of_node; + struct device_node *child; + struct i2c_board_info board_info; + struct i2c_adapter *adapter = NULL; + struct device_node *adapter_node = NULL; + struct timeval camera_start; + struct timeval camera_end; + int i; + unsigned long time_use = 0; + + temp_cam = kzalloc(sizeof(struct aml_cam_info_s), GFP_KERNEL); + if (!temp_cam) + return -ENOMEM; + + cam_pdev = pdev; + do_gettimeofday(&camera_start); + for_each_child_of_node(cams_node, child) { + + memset(temp_cam, 0, sizeof(struct aml_cam_info_s)); + + if (fill_cam_dev(child, temp_cam)) + continue; + + /*register exist camera*/ + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, temp_cam->name, I2C_NAME_SIZE); + + adapter_node = of_parse_phandle(child, "camera-i2c-bus", 0); + if (adapter_node) { + adapter = of_get_i2c_adapter_by_node(adapter_node); + of_node_put(adapter_node); + if (adapter == NULL) { + pr_err("%s, failed parse camera-i2c-bus\n", + __func__); + return -1; + } + } else { + pr_err("adapter node is NULL.\n"); + return -1; + } + board_info.addr = temp_cam->i2c_addr; + board_info.platform_data = temp_cam; + pr_info("new i2c device\n"); + /*i2c_new_existing_device(adapter, &board_info)*/ + i2c_new_device(adapter, &board_info); + } + do_gettimeofday(&camera_end); + time_use = (camera_end.tv_sec - camera_start.tv_sec) * 1000 + + (camera_end.tv_usec - camera_start.tv_usec) / 1000; + pr_info("camera probe cost time = %ldms\n", time_use); + + pr_info("aml probe finish\n"); + cam_clsp = class_create(THIS_MODULE, "aml_camera"); + for (i = 0; aml_cam_attrs[i].attr.name; i++) { + if (class_create_file(cam_clsp, &aml_cam_attrs[i]) < 0) + return -1; + } + + return 0; +} + +static int aml_cams_remove(struct platform_device *pdev) +{ + if (camera0_pwdn_pin != 0) + gpio_free(camera0_pwdn_pin); + if (camera0_rst_pin != 0) + gpio_free(camera0_rst_pin); + if (camera1_pwdn_pin != 0) + gpio_free(camera1_pwdn_pin); + if (camera1_rst_pin != 0) + gpio_free(camera1_rst_pin); + + kfree(temp_cam); + temp_cam = NULL; + + return 0; +} + +static const struct of_device_id cams_prober_dt_match[] = {{ + .compatible = + "amlogic, cams_prober", + }, {}, +}; + +static struct platform_driver aml_cams_prober_driver = { + .probe = aml_cams_probe, .remove = aml_cams_remove, .driver = { + .name = + "aml_cams_prober", .owner = THIS_MODULE, .of_match_table = + cams_prober_dt_match, + }, +}; + +static int __init aml_cams_prober_init(void) +{ + if (platform_driver_register(&aml_cams_prober_driver)) { + pr_err("aml_cams_probre_driver register failed\n"); + return -ENODEV; + } + + return 0; +} + +static void __exit aml_cams_prober_exit(void) +{ + bt_path_count = 0; + platform_driver_unregister(&aml_cams_prober_driver); +} + +module_init(aml_cams_prober_init); +module_exit(aml_cams_prober_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Amlogic Cameras prober driver"); + diff --git a/drivers/amlogic/media/camera/common/config_parser.c b/drivers/amlogic/media/camera/common/config_parser.c new file mode 100644 index 000000000000..9ee62e745702 --- /dev/null +++ b/drivers/amlogic/media/camera/common/config_parser.c @@ -0,0 +1,1822 @@ +/* + * drivers/amlogic/media/camera/common/config_parser.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include "config_parser.h" +#include +#include +#include +#include + +static struct file *fp; +mm_segment_t fs; + +char *aet_key = "aet_start"; +char *hw_key = "hw_start"; +char *effect_key = "effect_start"; +char *capture_key = "capture_start"; +char *scenes_key = "scenes_start"; +char *wb_key = "wb_start"; +char *wave_key = "wave_start"; +char *lens_key = "lens_start"; +char *gamma_key = "gamma_start"; +char *wb_sensor_key = "mwb_sensor_start"; +char *version_key = "version_start"; +char *cm_key = "cm_start"; +char *nr_key = "nr_start"; +char *peaking_key = "peaking_start"; + +struct buffer_para_s { + char *buffer; + int data_start; + int data_size; + int buffer_len; +}; + +void *realloc_mem(char *buffer, int new_size, int *old_size) +{ + char *tmp = vmalloc(new_size); + + if (*old_size >= new_size) { + vfree(tmp); + return buffer; + } + + if (tmp != NULL) { + memcpy(tmp, buffer, *old_size); + *old_size = new_size; + vfree(buffer); + return tmp; + } else + return NULL; +} + +/* + *************************************** + *Name : camera_open_config + *Input : *config_file + *Output : file size + *function : open the firware file, and return total size + *************************************** + */ + +int camera_open_config(const char *config_file) +{ + loff_t file_size; + struct inode *inode = NULL; + + fp = filp_open(config_file, O_RDONLY, 0); + if (IS_ERR(fp)) { + pr_err("read config file error"); + return -1; + } + + inode = fp->f_path.dentry->d_inode; + file_size = inode->i_size; + fs = get_fs(); + set_fs(KERNEL_DS); + + return file_size; + +} + +/* + *********************************** + *Name : camera_read_config + *Input : offset + *length, read length + *buf, return buffer + *Output : + *function : read data to buffer + *********************************** + */ + +int camera_read_config(int offset, int length, char *buf) +{ + loff_t pos = offset; + + vfs_read(fp, buf, length, &pos); + return 0; +} + +/* + ********************************** + *Name : camera_close_config + *Input : + *Output : + *function : close file + ********************************** + */ + +int camera_close_config(void) +{ + set_fs(fs); + filp_close(fp, NULL); + return 0; +} + +static int camera_read_buff(struct i2c_adapter *adapter, + unsigned short i2c_addr, char *buf, int addr_len, + int data_len) +{ + int i2c_flag = -1; + + struct i2c_msg msgs[] = {{ + .addr = i2c_addr, .flags = 0, + .len = addr_len, .buf = buf, + }, { + .addr = i2c_addr, .flags = I2C_M_RD, + .len = data_len, .buf = buf, + } + }; + + i2c_flag = i2c_transfer(adapter, msgs, 2); + + return i2c_flag; +} + +static int camera_write_buff(struct i2c_adapter *adapter, + unsigned short i2c_addr, char *buf, int len) +{ + struct i2c_msg msg[] = {{ + .addr = i2c_addr, .flags = 0, /* |I2C_M_TEN, */ + .len = len, .buf = buf, + } + + }; + + if (i2c_transfer(adapter, msg, 1) < 0) + return -1; + else + return 0; +} + +int my_i2c_put_byte(struct i2c_adapter *adapter, unsigned short i2c_addr, + unsigned short addr, unsigned char data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + buff[2] = data; + if (camera_write_buff(adapter, i2c_addr, buff, 3) < 0) + return -1; + return 0; +} + +int my_i2c_put_byte_add8(struct i2c_adapter *adapter, unsigned short i2c_addr, + char *buf, int len) +{ + if (camera_write_buff(adapter, i2c_addr, buf, len) < 0) + return -1; + return 0; +} + +int my_i2c_get_byte(struct i2c_adapter *adapter, unsigned short i2c_addr, + unsigned short addr) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + + if (camera_read_buff(adapter, i2c_addr, buff, 2, 1) < 0) + return -1; + return buff[0]; +} + +int my_i2c_get_word(struct i2c_adapter *adapter, unsigned short i2c_addr) +{ + unsigned char buff[4]; + unsigned short data; + + buff[0] = 0; + + if (camera_read_buff(adapter, i2c_addr, buff, 1, 2) < 0) + return -1; + + data = buff[0]; + data = (data << 8) | buff[1]; + + return data; +} + +char *search_string(struct buffer_para_s *buf_para, int *offset, int *remained, + char *start, char *end) +{ + char *iter, *pter, *buffer; + int data_start, data_size, buffer_len; + int add = 0; + + buffer = buf_para->buffer; + data_start = buf_para->data_start; + data_size = buf_para->data_size; + buffer_len = buf_para->buffer_len; + iter = strstr(buffer + data_start, start); + while (iter == NULL) { + if (iter == NULL && *remained < strlen(start)) { + pr_err("wrong config file"); + return NULL; + } + memset(buffer, 0, buffer_len); + if (*remained < BUFFER_SIZE) { + camera_read_config(*offset - strlen(start), + *remained, buffer); /* check bounds */ + *offset += *remained - strlen(start); + data_size = *remained; + *remained = 0; + data_start = 0; + } else { + camera_read_config(*offset - strlen(start), + BUFFER_SIZE, buffer);/* check bounds */ + *offset += BUFFER_SIZE - strlen(start); + data_size = BUFFER_SIZE; + *remained -= BUFFER_SIZE; + data_start = 0; + } + iter = strstr(buffer, start); + } + data_start = iter - buffer; + /*** check **/ + if (data_start > 512) { + data_size -= data_start; + memmove(buffer, iter, data_size); + *(buffer + data_size) = '\0'; + iter = buffer; + data_start = 0; + } + pter = strstr(iter + strlen(start), end); + while (pter == NULL) { + if (pter == NULL && *remained < strlen(end)) { + pr_err("wrong config file"); + return NULL; + } + buffer = + (char *)realloc_mem(buffer, data_size + BUFFER_SIZE + 1, + &buffer_len); + if (buffer == NULL) { + pr_err("realloc failed\n"); + return NULL; + } + if (*remained < BUFFER_SIZE) { + camera_read_config(*offset, *remained, + buffer + data_size); /* check bounds */ + add = *remained; + *offset += *remained; + *remained = 0; + } else { + camera_read_config(*offset, BUFFER_SIZE, + buffer + data_size); /* check bounds */ + add = BUFFER_SIZE; + *remained -= BUFFER_SIZE; + *offset += BUFFER_SIZE; + } + *(buffer + data_size + add) = '\0'; + pter = strstr(buffer + data_size - strlen(end), end); + data_size += add; + } + /* if realloc ,iter is invalid,so recalculate */ + iter = buffer + data_start; + data_start = pter - buffer; + + buf_para->buffer = buffer; + buf_para->data_start = data_start; + buf_para->data_size = data_size; + buf_para->buffer_len = buffer_len; + return iter; +} + +char *search_key(struct buffer_para_s *buf_para, int *offset, int *remained) +{ + char *iter, *buffer; + int data_start, data_size, buffer_len; + int add = 0; + + buffer = buf_para->buffer; + data_start = buf_para->data_start; + data_size = buf_para->data_size; + buffer_len = buf_para->buffer_len; + + iter = strstr(buffer + data_start, "["); + while (iter == NULL) { + if (iter == NULL && *remained < 20) { + pr_err("file end\n"); + return NULL; + } + memset(buffer, 0, buffer_len); + if (*remained < BUFFER_SIZE) { + camera_read_config(*offset, + *remained, buffer); /* check bounds */ + *offset += *remained; + data_size = *remained; + *remained = 0; + data_start = 0; + } else { + camera_read_config(*offset, + BUFFER_SIZE, buffer); /* check bounds */ + *offset += BUFFER_SIZE; + data_size = BUFFER_SIZE; + *remained -= BUFFER_SIZE; + data_start = 0; + } + iter = strstr(buffer, "["); + } + data_start = iter - buffer; + /*** check **/ + if (data_start + 20 > data_size) { /* ensure we have an complete key */ + buffer = + (char *)realloc_mem(buffer, data_size + BUFFER_SIZE + 1, + &buffer_len); + if (buffer == NULL) { + pr_err("realloc failed\n"); + return NULL; + } + if (*remained < BUFFER_SIZE) { + camera_read_config(*offset, *remained, + buffer + data_size); /* check bounds */ + add = *remained; + *offset += *remained; + *remained = 0; + + } else { + camera_read_config(*offset, BUFFER_SIZE, + buffer + data_size); /* check bounds */ + add = BUFFER_SIZE; + *remained -= BUFFER_SIZE; + *offset += BUFFER_SIZE; + } + *(buffer + data_size + add) = '\0'; + data_size += add; + } +/* if realloc ,iter is invalid,so recalculate */ + iter = buffer + data_start; + + buf_para->buffer = buffer; + buf_para->data_start = data_start; + buf_para->data_size = data_size; + buf_para->buffer_len = buffer_len; + return iter; +} + +int parse_head(char *buffer, int *sum) +{ + int ret; + char *iter; + + iter = strstr(buffer, "sum"); + if (iter == NULL) + return -WRONG_FORMAT; + iter += 4; /* point to value */ + ret = kstrtoint(iter, 10, sum); + return 0; +} + +int parse_body_head(char *buffer, int *no, int check, char *name) +{ + int ret; + char *iter; + + iter = strstr(buffer, "no"); + iter += 3; + ret = kstrtoint(iter, 10, no); + iter = strstr(iter, "name"); + iter += 5; + ret = kstrtos8(name, 16, iter); + return 0; +} +int parse_aet_element_info(char **iter, struct sensor_aet_info_s *info) +{ + int ret; + + *iter = strstr(*iter, "export"); + *iter += 7; + ret = kstrtouint(*iter, 16, &(info->fmt_main_fr)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->fmt_capture)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->fmt_hactive)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->fmt_vactive)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->fmt_rated_fr)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->fmt_min_fr)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->tbl_max_step)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->tbl_rated_step)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->tbl_max_gain)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(info->tbl_min_gain)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, + 16, &(info->format_transfer_parameter)); + *iter = strstr(*iter, ","); + *iter += 1; + return 0; + +} + +int parse_aet_element_tbl(char **iter, struct sensor_aet_s *tbl) +{ + int ret; + + ret = kstrtouint(*iter, 16, &(tbl->exp)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->ag)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->vts)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->gain)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->fr)); + *iter = strstr(*iter, ","); + *iter += 1; + return 0; +} + +int parse_last_aet_element_tbl(char **iter, struct sensor_aet_s *tbl) +{ + int ret; + + ret = kstrtouint(*iter, 16, &(tbl->exp)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->ag)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->vts)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->gain)); + *iter = strstr(*iter, ","); + *iter += 1; + ret = kstrtouint(*iter, 16, &(tbl->fr)); + return 0; +} + +int parse_effect(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int ret1, ret2, ret3, sum, check, i; + char *iter; + + iter = search_string(buf_para, offset, remained, "effect_start]", + "[effect]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (ret1 != 0) + return -HEAD_FAILED; + cf->eff.sum = sum; + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, + remained, "[effect]", "[effect"); + if (iter == NULL) + return -WRONG_FORMAT; + ret2 = parse_body_head(iter, &(cf->eff.eff[check].num), check, + cf->eff.eff[check].name); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + i = 0; + while (i < EFFECT_MAX && iter != NULL) { + ret3 = kstrtouint(iter, + 16, &(cf->eff.eff[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != EFFECT_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; +} + +int parse_aet(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int sum, ret, check, i; + char *iter; + + iter = search_string(buf_para, offset, remained, "aet_start]", "[aet]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret = parse_head(iter, &sum); + if (sum <= 0) + return -HEAD_FAILED; + cf->aet.sum = sum; + /**parser body***/ + for (i = 0; i < sum; i++) { + cf->aet.aet[i].info = + kmalloc(sizeof(struct sensor_aet_info_s), 0); + if ((cf->aet.aet[i].info) == NULL) { + while (i-- > 0) + kfree(cf->aet.aet[i].info); + return -NO_MEM; + } + } /* alloc head */ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, + remained, "[aet]", "[aet"); + if (iter == NULL) { + pr_err("aet wrong config format\n"); + ret = -WRONG_FORMAT; + goto clean; + } + ret = parse_body_head(iter, &(cf->aet.aet[check].num), check, + cf->aet.aet[check].name); + if (ret != 0) { + ret = -HEAD_FAILED; + goto clean; + } + ret = parse_aet_element_info(&iter, cf->aet.aet[check].info); + if (ret != 0) { + ret = -BODY_ELEMENT_FAILED; + goto clean; + } + + cf->aet.aet[check].aet_table = + vmalloc(sizeof(struct sensor_aet_s) * + (cf->aet.aet[check].info->tbl_max_step + 1)); + if ((cf->aet.aet[check].aet_table) == NULL) { + for (i = 0; i < check; i++) + vfree(cf->aet.aet[i].aet_table); + ret = -NO_MEM; + goto clean; + } + for (i = 0; i <= cf->aet.aet[check].info->tbl_max_step; i++) { + if (i == cf->aet.aet[check].info->tbl_max_step) { + ret = parse_last_aet_element_tbl( + &iter, &(cf->aet.aet[check].aet_table[i])); + } else + ret = parse_aet_element_tbl(&iter, + &(cf->aet.aet[check].aet_table[i])); + if (ret != 0) { + ret = -BODY_ELEMENT_FAILED; + goto clean_table; + } + } + check++; + } + return 0; + +clean_table: + for (i = 0; i <= check; i++) + vfree(cf->aet.aet[i].aet_table); +clean: + for (i = 0; i < sum; i++) + kfree(cf->aet.aet[i].info); + return ret; +} + +int parse_hw(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int ret1, ret2, ret3, sum, check, i; + char *iter = NULL; + char *eter = NULL; + + iter = search_string(buf_para, offset, remained, "hw_start]", "[hw]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (ret1 != 0) + return -HEAD_FAILED; + cf->hw.sum = sum; + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, remained, "[hw]", "[hw"); + if (iter == NULL) + return -WRONG_FORMAT; + ret2 = parse_body_head(iter, &(cf->hw.hw[check].num), check, + cf->hw.hw[check].name); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + eter = strstr(iter, ";"); + if (eter == NULL) + return -WRONG_FORMAT; + i = 0; + while (iter < eter) { + ret3 = kstrtouint(iter, + 16, &(cf->hw.hw[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; +} + +int parse_wb(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int ret1, ret2, ret3, sum, check, i; + char *iter = NULL; + char *eter = NULL; + + iter = search_string(buf_para, offset, remained, "wb_start]", "[wb]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (ret1 != 0) + return -HEAD_FAILED; + cf->wb.sum = sum; + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, remained, "[wb]", "[wb"); + if (iter == NULL) + return -WRONG_FORMAT; + ret2 = parse_body_head(iter, &(cf->wb.wb[check].num), check, + cf->wb.wb[check].name); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + eter = strstr(iter, ";"); + if (eter == NULL) + return -WRONG_FORMAT; + i = 0; + while (iter < eter) { + ret3 = kstrtouint(iter, + 16, &(cf->wb.wb[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + + } + if (i != WB_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; + +} + +int parse_capture(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int ret1, ret2, ret3, sum, check, i; + char *iter = NULL; + char *eter = NULL; + + iter = search_string(buf_para, offset, remained, "capture_start]", + "[capture]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (ret1 != 0) + return -HEAD_FAILED; + cf->capture.sum = sum; + /* pr_err("capture sum:%d\n",sum); */ + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, remained, "[capture]", + "[capture"); + if (iter == NULL) { + pr_err("search wrong\n"); + return -WRONG_FORMAT; + } + ret2 = parse_body_head(iter, + &(cf->capture.capture[check].num), check, + cf->capture.capture[check].name); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + /* pr_err("name:%s\n",cf->capture.capture[check].name); */ + iter = strstr(iter, "export"); + if (iter == NULL) { + pr_err("iter is NULL\n"); + return -WRONG_FORMAT; + } + iter += 7; + eter = strstr(iter, ";"); + if (eter == NULL) + return -WRONG_FORMAT; + i = 0; + while (iter < eter) { + ret3 = kstrtouint(iter, + 16, &(cf->capture.capture[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != CAPTURE_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; + +} + +int parse_wave(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int i, ret; + char *iter = NULL; + char *eter = NULL; + + iter = search_string(buf_para, offset, remained, "wave_start]", + "[wave_end]"); + if (iter == NULL) + return -WRONG_FORMAT; + iter = strstr(iter, "export"); + iter += 7; + eter = strstr(iter, ";"); + if (eter == NULL) + return -WRONG_FORMAT; + i = 0; + while (iter < eter) { + ret = kstrtouint(iter, 16, &(cf->wave.export[i])); + /* pr_err("wave:%x\n",cf->wave.export[i]); */ + iter = strstr(iter, ","); + i++; + if (iter == NULL) + break; + iter += 1; + } + if (i != WAVE_MAX) + return -CHECK_LEN_FAILED; + return 0; +} + +int parse_scene(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int sum, ret1, ret2, ret3, check, i; + char *iter = NULL; + char *eter = NULL; + + iter = search_string(buf_para, offset, remained, "scenes_start]", + "[scenes]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (sum <= 0) + return -HEAD_FAILED; + cf->scene.sum = sum; + + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, + remained, "[scenes]", "[scenes"); + if (iter == NULL) { + pr_err("scene wrong config format\n"); + return -WRONG_FORMAT; + } + ret2 = parse_body_head(iter, &((cf->scene.scene[check]).num), + check, (cf->scene.scene[check].name)); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + eter = strstr(iter, ";"); + if (eter == NULL) + return -WRONG_FORMAT; + i = 0; + while (iter < eter) { + ret3 = kstrtouint(iter, + 16, &(cf->scene.scene[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != SCENE_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; +} + +int parse_lens(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int sum, ret1, ret2, ret3, check, i; + char *iter = NULL; + char *eter = NULL; + + iter = search_string(buf_para, offset, + remained, "lens_start]", "[lens]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (sum <= 0) + return -HEAD_FAILED; + cf->lens.sum = sum; + + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, + remained, "[lens]", "[lens"); + if (iter == NULL) { + pr_err("lens wrong config format\n"); + return -WRONG_FORMAT; + } + ret2 = parse_body_head(iter, + &((cf->lens.lens[check]).num), + check, + (cf->lens.lens[check].name)); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + eter = strstr(iter, ";"); + if (eter == NULL) + return -WRONG_FORMAT; + i = 0; + while (iter < eter) { + ret3 = kstrtouint(iter, + 16, &(cf->lens.lens[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != LENS_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; +} + +int parse_gamma(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int i, ret; + char *iter; + + iter = search_string(buf_para, offset, remained, "gamma_start]", + "[gamma_end]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + iter = strstr(iter, "export"); + iter += 7; + for (i = 0; i < GAMMA_MAX && iter != NULL;) { + ret = kstrtouint(iter, 16, &(cf->gamma.gamma_r[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != GAMMA_MAX) + return -CHECK_LEN_FAILED; + for (i = 0; i < GAMMA_MAX && iter != NULL;) { + ret = kstrtouint(iter, 16, &(cf->gamma.gamma_g[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != GAMMA_MAX) + return -CHECK_LEN_FAILED; + for (i = 0; i < GAMMA_MAX && iter != NULL;) { + ret = kstrtouint(iter, + 16, &(cf->gamma.gamma_b[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != GAMMA_MAX) + return -CHECK_LEN_FAILED; + return 0; +} + +int parse_wb_sensor(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int i, ret; + char *iter; + + iter = search_string(buf_para, offset, remained, "mwb_sensor_start]", + "[mwb_sensor_end]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + iter = strstr(iter, "export"); + iter += 7; + i = 0; + while (i < WB_SENSOR_MAX && iter != NULL) { + ret = kstrtouint(iter, 16, &(cf->wb_sensor_data.export[i])); + /* pr_err("wb sensor:%x\n",cf->wb_sensor_data.export[i]); */ + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != WB_SENSOR_MAX) + return -CHECK_LEN_FAILED; + return 0; +} + +int parse_version(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + char *iter, *end; + int len = 0; + + iter = search_string(buf_para, offset, remained, "version_start]", + "[version_end]"); + if (iter == NULL) + return -WRONG_FORMAT; + iter = strstr(iter, "Date"); + iter += 5; + end = strstr(iter, "Module"); + if (end == NULL) + return -WRONG_FORMAT; + len = end - iter; + memcpy(cf->version.date, iter, len); + cf->version.date[len] = '\0'; + + iter = end + 7; + end = strstr(iter, "Version"); + if (end == NULL) + return -WRONG_FORMAT; + len = end - iter; + memcpy(cf->version.module, iter, len); + cf->version.module[len] = '\0'; + + iter = end + 8; + end = strstr(iter, "[version"); + if (end == NULL) + return -WRONG_FORMAT; + len = end - iter; + memcpy(cf->version.version, iter, len); + cf->version.version[len] = '\0'; + pr_info("version:%s", cf->version.version); + return 0; +} + +int parse_cm(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int i; + int ret; + char *iter; + + iter = search_string(buf_para, offset, + remained, "cm_start]", "[cm_end]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser body***/ + iter = strstr(iter, "export"); + iter += 7; + i = 0; + while (i < CM_MAX && iter != NULL) { + ret = kstrtouint(iter, 16, &(cf->cm.export[i])); + /* pr_err("cm:%x\n",cf->cm.export[i]); */ + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != CM_MAX) + return -CHECK_LEN_FAILED; + return 0; +} + +int parse_nr(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int ret1, ret2, ret3, sum, check, i; + char *iter; + + iter = search_string(buf_para, offset, remained, "nr_start]", "[nr]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (ret1 != 0) + return -HEAD_FAILED; + cf->nr.sum = sum; + /* pr_err("nr sum:%d\n",sum); */ + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, remained, "[nr]", "[nr"); + if (iter == NULL) { + pr_err("search wrong\n"); + return -WRONG_FORMAT; + } + ret2 = parse_body_head(iter, &(cf->nr.nr[check].num), check, + cf->nr.nr[check].name); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + i = 0; + while (i < NR_MAX && iter != NULL) { + ret3 = kstrtouint(iter, 16, + &(cf->nr.nr[check].export[i])); + /* pr_err("nr:%x\n",cf->nr.nr[check].export[i]); */ + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != NR_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; +} + +int parse_peaking(struct configure_s *cf, struct buffer_para_s *buf_para, + int *remained, int *offset) +{ + int ret1, ret2, ret3, sum, check, i; + char *iter; + + iter = search_string(buf_para, offset, remained, "peaking_start]", + "[peaking]"); + if (iter == NULL) + return -WRONG_FORMAT; + /***parser head***/ + ret1 = parse_head(iter, &sum); + if (ret1 != 0) + return -HEAD_FAILED; + cf->peaking.sum = sum; + /* pr_err("peaking sum:%d\n",sum); */ + /**parser body***/ + check = 0; + while (check < sum) { + iter = search_string(buf_para, offset, remained, "[peaking]", + "[peaking"); + if (iter == NULL) { + pr_err("search wrong\n"); + return -WRONG_FORMAT; + } + ret2 = parse_body_head(iter, + &(cf->peaking.peaking[check].num), check, + cf->peaking.peaking[check].name); + if (ret2 != 0) + return -BODY_HEAD_FAILED; + iter = strstr(iter, "export"); + iter += 7; + i = 0; + while (i < PEAKING_MAX && iter != NULL) { + ret3 = kstrtouint(iter, + 16, &(cf->peaking.peaking[check].export[i])); + i++; + iter = strstr(iter, ","); + if (iter == NULL) + break; + iter += 1; + } + if (i != PEAKING_MAX) + return -CHECK_LEN_FAILED; + check++; + } + if (check != sum) + return -CHECK_FAILED; + return 0; +} + +int parse_config(const char *path, struct configure_s *cf) +{ + char *buffer, *iter; + int file_size; + int remained_size; + int read_offset = 0; + int ret = 0; + struct buffer_para_s buf_para; + + buffer = vmalloc(BUFFER_SIZE + 1);/*(char *)*/ + if (buffer == NULL) + return -NO_MEM; + + buf_para.buffer = buffer; + + memset(cf, 0, sizeof(struct configure_s)); + file_size = camera_open_config(path); + if (file_size < 0) { + pr_err("open failed :%d\n", file_size); + ret = -READ_ERROR; + goto clean_mem; + } else if (file_size == 0) { + pr_err("file is null\n"); + ret = -READ_ERROR; + goto clean_all; + } else { + if (file_size < BUFFER_SIZE) { + camera_read_config(0, file_size, buffer); + remained_size = 0; + read_offset = file_size; + *(buffer + file_size) = '\0'; + } else { + camera_read_config(0, BUFFER_SIZE, buffer); + remained_size = file_size - BUFFER_SIZE; + read_offset = BUFFER_SIZE; + *(buffer + BUFFER_SIZE) = '\0'; + } + } + buf_para.data_start = 0; + buf_para.data_size = read_offset; + buf_para.buffer_len = BUFFER_SIZE; + + while (read_offset <= file_size) { + iter = search_key(&buf_para, &read_offset, &remained_size); + if (iter == NULL) { + pr_info("finish parse file\n"); + return 0; + } + iter += 1; + buf_para.data_start += 1; + switch (*iter) { + case 'a': + if (memcmp(iter, aet_key, strlen(aet_key)) == 0) { + cf->aet_valid = 1; + ret = parse_aet(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->aet_valid = 0; + pr_err("aet invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(aet_key); + break; + case 'h': + if (memcmp(iter, hw_key, strlen(hw_key)) == 0) { + cf->hw_valid = 1; + ret = parse_hw(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->hw_valid = 0; + pr_err("hw invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(hw_key); + break; + case 'e': + if (memcmp(iter, effect_key, strlen(effect_key)) == 0) { + cf->effect_valid = 1; + ret = parse_effect(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->effect_valid = 0; + pr_err("effect invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(effect_key); + break; + case 'w': + if (*(iter + 1) == 'b') { + if (memcmp(iter, wb_key, strlen(wb_key)) == 0) { + cf->wb_valid = 1; + ret = parse_wb(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->wb_valid = 0; + pr_err("wb invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(wb_key); + } else if (*(iter + 1) == 'a') { + if (memcmp(iter, wave_key, + strlen(wave_key)) == 0) { + cf->wave_valid = 1; + ret = parse_wave(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->wave_valid = 0; + pr_err("wave invalid :%d\n", + ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(wave_key); + } else + buf_para.data_start += 1; + + break; + case 's': + if (memcmp(iter, scenes_key, + strlen(scenes_key)) == 0) { + cf->scene_valid = 1; + ret = parse_scene(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->scene_valid = 0; + pr_err("scene invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(scenes_key); + break; + case 'c': + if (*(iter + 1) == 'a') { + if (memcmp(iter, capture_key, + strlen(capture_key)) == 0) { + cf->capture_valid = 1; + ret = parse_capture(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->capture_valid = 0; + pr_err("capture invalid :%d\n", + ret); + goto clean_all; + } + } else + buf_para.data_start += + strlen(capture_key); + } else if (*(iter + 1) == 'm') { + if (memcmp(iter, cm_key, strlen(cm_key)) == 0) { + cf->cm_valid = 1; + ret = parse_cm(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->cm_valid = 0; + pr_err("cm invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(cm_key); + } else + buf_para.data_start += 1; + break; + case 'l': + if (memcmp(iter, lens_key, strlen(lens_key)) == 0) { + cf->lens_valid = 1; + ret = parse_lens(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->lens_valid = 0; + pr_err("lens invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(lens_key); + break; + case 'g': + if (memcmp(iter, gamma_key, strlen(gamma_key)) == 0) { + cf->gamma_valid = 1; + ret = parse_gamma(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->gamma_valid = 0; + pr_err("gamma invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(gamma_key); + break; + case 'm': + if (memcmp(iter, wb_sensor_key, + strlen(wb_sensor_key)) == 0) { + cf->wb_sensor_data_valid = 1; + ret = parse_wb_sensor(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->wb_sensor_data_valid = 0; + pr_err("wb sensor data invalid :%d\n", + ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(wb_sensor_key); + break; + case 'v': + if (memcmp(iter, version_key, + strlen(version_key)) == 0) { + cf->version_info_valid = 1; + ret = parse_version(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->version_info_valid = 0; + pr_err("version info invalid :%d\n", + ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(version_key); + break; + case 'n': + if (memcmp(iter, nr_key, strlen(nr_key)) == 0) { + cf->nr_valid = 1; + ret = parse_nr(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->nr_valid = 0; + pr_err("nr invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(nr_key); + break; + case 'p': + if (memcmp(iter, peaking_key, + strlen(peaking_key)) == 0) { + cf->peaking_valid = 1; + ret = parse_peaking(cf, &buf_para, + &remained_size, &read_offset); + if (ret != 0) { + cf->peaking_valid = 0; + pr_err("peaking invalid :%d\n", ret); + goto clean_all; + } + } else + buf_para.data_start += strlen(peaking_key); + break; + default: + buf_para.data_start += 1; + break; + } + } + ret = 0; + +clean_all: + camera_close_config(); +clean_mem: + vfree(buf_para.buffer); + return ret; +} + +struct hw_para_s { + char name[20]; + int size; + int *array; +}; + +struct hw_para_s hw_para[] = { + {"TOP", XML_TOP, NULL}, {"TP", XML_TP, NULL}, {"CG", XML_CG, NULL}, { + "LENS_SHADING", XML_LS, NULL + }, {"DFT", XML_DP, NULL}, { + "DMS", XML_DM, NULL + }, {"MATRIX", XML_CSC, NULL}, { + "PEAKING", XML_SH, NULL + }, {"NR", XML_NR, NULL}, {"AWB", XML_AWB, NULL}, + {"AE", XML_AE, NULL}, {"AF", XML_AF, NULL}, {"BLNR", XML_BN, NULL}, { + "DBG", XML_DBG, NULL + }, {"GC", XML_GC, NULL}, {"", 0, NULL} +}; + +void init_hw_para(struct xml_default_regs_s *reg) +{ + hw_para[0].array = &(reg->top.reg_map[0]); + hw_para[1].array = &(reg->tp.reg_map[0]); + hw_para[2].array = &(reg->cg.reg_map[0]); + hw_para[3].array = &(reg->ls.reg_map[0]); + hw_para[4].array = &(reg->dp.reg_map[0]); + hw_para[5].array = &(reg->dm.reg_map[0]); + hw_para[6].array = &(reg->csc.reg_map[0]); + hw_para[7].array = &(reg->sharp.reg_map[0]); + hw_para[8].array = &(reg->nr.reg_map[0]); + hw_para[9].array = &(reg->awb_reg.reg_map[0]); + hw_para[10].array = &(reg->ae_reg.reg_map[0]); + hw_para[11].array = &(reg->af_reg.reg_map[0]); + hw_para[12].array = &(reg->bn.reg_map[0]); + hw_para[13].array = &(reg->dbg.reg_map[0]); + hw_para[14].array = &(reg->gc.reg_map[0]); +} + +/* call back functions */ + +unsigned int get_aet_max_step(void *priv) +{ + struct camera_priv_data_s *camera_priv_data = + (struct camera_priv_data_s *)priv; + if (camera_priv_data == NULL || + camera_priv_data->sensor_aet_info == NULL) { + pr_err("get_aet_max_step null\n"); + WARN_ON((!camera_priv_data) || + (!camera_priv_data->sensor_aet_info)); + } + return camera_priv_data->sensor_aet_info->tbl_max_step; +} + +unsigned int get_aet_max_gain(void *priv) +{ + struct camera_priv_data_s *camera_priv_data = + (struct camera_priv_data_s *)priv; + if (camera_priv_data == NULL || + camera_priv_data->sensor_aet_info == NULL) { + pr_err("get_aet_max_gain null\n"); + WARN_ON((!camera_priv_data) || + (!camera_priv_data->sensor_aet_info)); + } + return camera_priv_data->sensor_aet_info->tbl_max_gain; +} + +unsigned int get_aet_min_gain(void *priv) +{ + struct camera_priv_data_s *camera_priv_data = + (struct camera_priv_data_s *)priv; + if (camera_priv_data == NULL || + camera_priv_data->sensor_aet_info == NULL) { + pr_err("get_aet_min_gain null\n"); + WARN_ON((!camera_priv_data) || + (!camera_priv_data->sensor_aet_info)); + } + return camera_priv_data->sensor_aet_info->tbl_min_gain; +} + +unsigned int get_aet_current_step(void *priv) +{ + struct camera_priv_data_s *camera_priv_data = + (struct camera_priv_data_s *)priv; + if (camera_priv_data == NULL || + camera_priv_data->sensor_aet_info == NULL) { + pr_err("get_aet_current_step null\n"); + WARN_ON((!camera_priv_data) || + (!camera_priv_data->sensor_aet_info)); + } + return camera_priv_data->sensor_aet_step; +} + +unsigned int get_aet_current_gain(void *priv) +{ + struct sensor_aet_s *sensor_aet_table; + unsigned int sensor_aet_step; + struct camera_priv_data_s *camera_priv_data = + (struct camera_priv_data_s *)priv; + if (camera_priv_data == NULL) + WARN_ON(!camera_priv_data); + + sensor_aet_table = + camera_priv_data->sensor_aet_table; + sensor_aet_step = camera_priv_data->sensor_aet_step; + + if (sensor_aet_table == NULL) { + pr_err("get_aet_current_gain null\n"); + WARN_ON(!sensor_aet_table); + } + return sensor_aet_table[sensor_aet_step].gain; +} + +unsigned int get_aet_new_gain(void *priv, unsigned int new_step) +{ + struct camera_priv_data_s *camera_priv_data = + (struct camera_priv_data_s *)priv; + struct sensor_aet_s *sensor_aet_table; + + if (camera_priv_data == NULL) + WARN_ON(!camera_priv_data); + sensor_aet_table = + camera_priv_data->sensor_aet_table; + if (sensor_aet_table == NULL) { + pr_err("get_aet_current_gain null\n"); + WARN_ON(!sensor_aet_table); + } + return sensor_aet_table[new_step].gain; +} + +int generate_para(struct cam_parameter_s *para, struct para_index_s pindex, + struct configure_s *cf) +{ + int i = 0; + int j = 0; + struct xml_scenes_s *scene; + struct xml_default_regs_s *reg; + struct xml_effect_manual_s *effect; + struct xml_wb_manual_s *wb; + struct xml_capture_s *capture; + struct wave_s *wave; + + /**init callback func**/ + para->cam_function.set_af_new_step = NULL; + if (cf->aet_valid == 1) { + para->cam_function.get_aet_current_step = get_aet_current_step; + para->cam_function.get_aet_max_step = get_aet_max_step; + para->cam_function.get_aet_current_gain = get_aet_current_gain; + para->cam_function.get_aet_min_gain = get_aet_min_gain; + para->cam_function.get_aet_max_gain = get_aet_max_gain; + para->cam_function.get_aet_gain_by_step = get_aet_new_gain; + + } + /**init scenes**/ + if (cf->scene_valid == 1) { + para->xml_scenes = + vmalloc(sizeof(struct xml_scenes_s)); + if (para->xml_scenes == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + scene = para->xml_scenes; + memcpy(&(scene->ae), + cf->scene.scene[pindex.scenes_index].export, + AE_LEN * sizeof(unsigned int)); + memcpy(&(scene->awb), + cf->scene.scene[pindex.scenes_index].export + AE_LEN, + AWB_LEN * sizeof(unsigned int)); + memcpy(&(scene->af), + cf->scene.scene[pindex.scenes_index].export + + (AE_LEN + AWB_LEN), + AF_LEN * sizeof(unsigned int)); + } else + para->xml_scenes = NULL; + + /**init hw**/ + if (cf->hw_valid == 1) { + para->xml_regs_map = vmalloc(sizeof(struct xml_default_regs_s)); + if (para->xml_regs_map == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + reg = para->xml_regs_map; + init_hw_para(reg); + for (i = 0; i < cf->hw.sum; i++) { + if ((strcmp(hw_para[i].name, cf->hw.hw[i].name)) == 0) { + for (j = 0; j < hw_para[i].size; j++) + hw_para[i].array[j] = + cf->hw.hw[i].export[j]; + } + } + + } else + para->xml_regs_map = NULL; + /** init gamma **/ + if (cf->gamma_valid == 1) { + if (para->xml_regs_map == NULL) { + para->xml_regs_map = + vmalloc(sizeof(struct xml_default_regs_s)); + if (para->xml_regs_map == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + } + reg = para->xml_regs_map; + memcpy(reg->lut_gc.gamma_r, cf->gamma.gamma_r, + GAMMA_MAX * sizeof(unsigned short)); + memcpy(reg->lut_gc.gamma_g, cf->gamma.gamma_g, + GAMMA_MAX * sizeof(unsigned short)); + memcpy(reg->lut_gc.gamma_b, cf->gamma.gamma_b, + GAMMA_MAX * sizeof(unsigned short)); + } + /**init effect**/ + if (cf->effect_valid == 1) { + para->xml_effect_manual = + kmalloc(sizeof(struct xml_effect_manual_s), 0); + if (para->xml_effect_manual == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + effect = para->xml_effect_manual; + memcpy(effect->csc.reg_map, + cf->eff.eff[pindex.effect_index].export, + EFFECT_MAX * sizeof(unsigned int)); + } else + para->xml_effect_manual = NULL; + /**init wb**/ + if (cf->wb_valid == 1) { + para->xml_wb_manual = + kmalloc(sizeof(struct xml_wb_manual_s), 0); + if (para->xml_wb_manual == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + wb = para->xml_wb_manual; + memcpy(wb->reg_map, cf->wb.wb[pindex.wb_index].export, + 2 * sizeof(unsigned int)); + } else + para->xml_wb_manual = NULL; + + /**init capture**/ + if (cf->capture_valid == 1) { + para->xml_capture = vmalloc(sizeof(struct xml_capture_s)); + if (para->xml_capture == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + capture = para->xml_capture; + capture->ae_try_max_cnt = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[0]); + capture->sigle_count = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[3]); + capture->skip_step = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[4]); + capture->multi_capture_num = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[5]); + capture->af_mode = (enum cam_scanmode_e)(cf->capture. + capture[pindex.capture_index].export[2]); + capture->eyetime = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[6]); + capture->pretime = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[7]); + capture->postime = (unsigned int)(cf->capture. + capture[pindex.capture_index].export[8]); + } else + para->xml_capture = NULL; + /**init wave**/ + if (cf->wave_valid == 1) { + para->xml_wave = kmalloc(sizeof(struct wave_s), 0); + if (para->xml_wave == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + wave = para->xml_wave; + memcpy(wave, cf->wave.export, WAVE_MAX * sizeof(unsigned int)); + } else + para->xml_wave = NULL; + return 0; +} + +void free_para(struct cam_parameter_s *para) +{ + if (para->xml_peripheral != NULL) { + kfree(para->xml_peripheral); + para->xml_peripheral = NULL; + } + if (para->xml_scenes != NULL) { + vfree(para->xml_scenes); + para->xml_scenes = NULL; + } + if (para->xml_regs_map != NULL) { + vfree(para->xml_regs_map); + para->xml_regs_map = NULL; + } + if (para->xml_effect_manual != NULL) { + kfree(para->xml_effect_manual); + para->xml_effect_manual = NULL; + } + if (para->xml_wb_manual != NULL) { + kfree(para->xml_wb_manual); + para->xml_wb_manual = NULL; + } + if (para->xml_capture != NULL) { + vfree(para->xml_capture); + para->xml_capture = NULL; + } + if (para->xml_wave != NULL) { + kfree(para->xml_wave); + para->xml_wave = NULL; + } +} + +int update_fmt_para(int width, int height, struct cam_parameter_s *para, + struct para_index_s *pindex, struct configure_s *cf) +{ + int i = 0; + struct xml_default_regs_s *reg; + + if (cf->lens_valid == 1) { + while (i < cf->lens.sum) { + if (cf->lens.lens[i].export[0] == width && + cf->lens.lens[i].export[1] == height) + break; + i++; + } + if (i < cf->lens.sum) + pindex->lens_index = i; + else { + pr_info("width:%x,height:%x no match lens param\n", + width, height); + pindex->lens_index = 0; + } + /** init lens **/ + if (para->xml_regs_map == NULL) { + para->xml_regs_map = + vmalloc(sizeof(struct xml_default_regs_s)); + if (para->xml_regs_map == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + } + reg = para->xml_regs_map; + memcpy(reg->lnsd.reg_map, + cf->lens.lens[pindex->lens_index].export + 2, + (LENS_MAX - 2) * sizeof(unsigned int)); + } + + i = 0; + if (cf->nr_valid == 1) { + while (i < cf->nr.sum) { + if (cf->nr.nr[i].export[0] == width && + cf->nr.nr[i].export[1] == height) + break; + i++; + } + if (i < cf->nr.sum) + pindex->nr_index = i; + else { + pr_info("width:%x,height:%x no match nr param\n", + width, height); + pindex->nr_index = 0; + } + /** init nr **/ + if (para->xml_regs_map == NULL) { + para->xml_regs_map = + vmalloc(sizeof(struct xml_default_regs_s)); + if (para->xml_regs_map == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + } + reg = para->xml_regs_map; + memcpy(reg->nr.reg_map, cf->nr.nr[pindex->nr_index].export + 2, + (NR_MAX - 2) * sizeof(unsigned int)); + } + + i = 0; + if (cf->peaking_valid == 1) { + while (i < cf->peaking.sum) { + if (cf->peaking.peaking[i].export[0] == width && + cf->peaking.peaking[i].export[1] == height) + break; + i++; + } + if (i < cf->peaking.sum) + pindex->peaking_index = i; + else { + pr_info("width:%x,height:%x no match peaking param\n", + width, height); + pindex->peaking_index = 0; + } + /** init sharp **/ + if (para->xml_regs_map == NULL) { + para->xml_regs_map = + vmalloc(sizeof(struct xml_default_regs_s)); + if (para->xml_regs_map == NULL) { + pr_err("alloc mem failed\n"); + return -ENOMEM; + } + } + reg = para->xml_regs_map; + memcpy(reg->sharp.reg_map, + cf->peaking.peaking[pindex->peaking_index].export + 2, + (PEAKING_MAX - 2) * sizeof(unsigned int)); + } + return 0; +} diff --git a/drivers/amlogic/media/camera/common/config_parser.h b/drivers/amlogic/media/camera/common/config_parser.h new file mode 100644 index 000000000000..c5e78026e9fe --- /dev/null +++ b/drivers/amlogic/media/camera/common/config_parser.h @@ -0,0 +1,301 @@ +/* + * drivers/amlogic/media/camera/common/config_parser.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef CONFIG_PARSER +#define CONFIG_PARSER + +#include +#include +#include +#include +#include +#include + +#define EFFECT_ITEM_MAX 16 +#define AET_ITEM_MAX 32 +#define HW_ITEM_MAX 16 +#define WB_ITEM_MAX 10 +#define CAPTURE_ITEM_MAX 9 +#define NR_ITEM_MAX 5 +#define PEAKING_ITEM_MAX 5 +#define LENS_ITEM_MAX 5 +#define SCENE_ITEM_MAX 1 +#define EFFECT_MAX 18 +#define HW_MAX 64 +#define WB_MAX 2 +#define GAMMA_MAX 257 +#define SCENE_MAX 281 +#define WB_SENSOR_MAX 4 +#define CAPTURE_MAX 8 +#define LENS_MAX 1027 +#define WAVE_MAX 12 +#define CM_MAX 188 +#define NR_MAX 15 +#define PEAKING_MAX 35 +#define AE_LEN 119 +#define AWB_LEN 120 +#define AF_LEN 42 +#define BUFFER_SIZE 1024 + +enum error_code { + NO_MEM = 1, + READ_ERROR, + WRONG_FORMAT, + CHECK_LEN_FAILED, + CHECK_FAILED, + HEAD_FAILED, + BODY_HEAD_FAILED, + BODY_ELEMENT_FAILED, +}; + +struct effect_type { + int num; + char name[40]; + unsigned int export[EFFECT_MAX]; +}; + +struct effect_struct { + int sum; + struct effect_type eff[EFFECT_ITEM_MAX]; +}; + +struct hw_type { + int num; + char name[40]; + int export[HW_MAX]; +}; + +struct hw_struct { + int sum; + struct hw_type hw[HW_ITEM_MAX]; +}; + +struct wb_type { + int num; + char name[40]; + int export[2]; +}; + +struct wb_struct { + int sum; + struct wb_type wb[WB_ITEM_MAX]; +}; + +struct scene_type { + int num; + char name[40]; + int export[SCENE_MAX]; +}; + +struct scene_struct { + int sum; + struct scene_type scene[SCENE_ITEM_MAX]; +}; + +struct capture_type { + int num; + char name[40]; + int export[CAPTURE_ITEM_MAX]; +}; + +struct capture_struct { + int sum; + struct capture_type capture[CAPTURE_MAX]; +}; + +struct sensor_aet_s { + unsigned int exp; + unsigned int ag; + unsigned int vts; + unsigned int gain; + unsigned int fr; +}; +/* sensor_aet_t */ + +struct sensor_aet_info_s { + unsigned int fmt_main_fr; + unsigned int fmt_capture; /* false: preview, true: capture */ + unsigned int fmt_hactive; + unsigned int fmt_vactive; + unsigned int fmt_rated_fr; + unsigned int fmt_min_fr; + unsigned int tbl_max_step; + unsigned int tbl_rated_step; + unsigned int tbl_max_gain; + unsigned int tbl_min_gain; + unsigned int format_transfer_parameter; +}; +/* sensor_aet_info_t */ + +struct aet_type { + int num; + char name[40]; + struct sensor_aet_info_s *info; + struct sensor_aet_s *aet_table; +}; + +struct aet_struct { + int sum; + struct aet_type aet[AET_ITEM_MAX]; +}; + +struct wave_struct { + int export[WAVE_MAX]; +}; + +struct lens_type { + int num; + char name[40]; + int export[LENS_MAX]; +}; + +struct lens_struct { + int sum; + struct lens_type lens[LENS_ITEM_MAX]; +}; + +struct gamma_struct { + unsigned int gamma_r[GAMMA_MAX]; + unsigned int gamma_g[GAMMA_MAX]; + unsigned int gamma_b[GAMMA_MAX]; +}; + +struct wb_sensor_struct { + int export[WB_SENSOR_MAX]; +}; + +struct version_struct { + char date[40]; + char module[30]; + char version[30]; +}; + +struct cm_struct { + int export[CM_MAX]; +}; + +struct nr_type { + int num; + char name[40]; + int export[NR_MAX]; +}; + +struct nr_struct { + int sum; + struct nr_type nr[NR_ITEM_MAX]; +}; + +struct peaking_type { + int num; + char name[40]; + int export[PEAKING_MAX]; +}; + +struct peaking_struct { + int sum; + struct peaking_type peaking[PEAKING_ITEM_MAX]; +}; + +struct configure_s { + struct effect_struct eff; + int effect_valid; + struct hw_struct hw; + int hw_valid; + struct aet_struct aet; + int aet_valid; + struct capture_struct capture; + int capture_valid; + struct scene_struct scene; + int scene_valid; + struct wb_struct wb; + int wb_valid; + struct wave_struct wave; + int wave_valid; + struct lens_struct lens; + int lens_valid; + struct gamma_struct gamma; + int gamma_valid; + struct wb_sensor_struct wb_sensor_data; + int wb_sensor_data_valid; + struct version_struct version; + int version_info_valid; + struct cm_struct cm; + int cm_valid; + struct nr_struct nr; + int nr_valid; + struct peaking_struct peaking; + int peaking_valid; +}; + +struct para_index_s { + unsigned int effect_index; + unsigned int scenes_index; + unsigned int wb_index; + unsigned int capture_index; + unsigned int nr_index; + unsigned int peaking_index; + unsigned int lens_index; +}; + +struct wb_pair_t { + enum camera_wb_flip_e wb; + char *name; +}; + +struct effect_pair_t { + enum camera_special_effect_e effect; + char *name; +}; + +struct sensor_dg_s { + unsigned short r; + unsigned short g; + unsigned short b; + unsigned short dg_default; +}; + +struct camera_priv_data_s { + struct sensor_aet_info_s + *sensor_aet_info; /* point to 1 of up to 16 aet information */ + struct sensor_aet_s *sensor_aet_table; + unsigned int sensor_aet_step; /* current step of the current aet */ + struct configure_s *configure; +}; + +int parse_config(const char *path, struct configure_s *cf); +int generate_para(struct cam_parameter_s *para, struct para_index_s pindex, + struct configure_s *cf); +void free_para(struct cam_parameter_s *para); +int update_fmt_para(int width, int height, struct cam_parameter_s *para, + struct para_index_s *pindex, struct configure_s *cf); + +unsigned int get_aet_current_step(void *priv); +unsigned int get_aet_current_gain(void *pirv); +unsigned int get_aet_min_gain(void *priv); +unsigned int get_aet_max_gain(void *priv); +unsigned int get_aet_max_step(void *priv); +unsigned int get_aet_gain_by_step(void *priv, unsigned int new_step); + +int my_i2c_put_byte(struct i2c_adapter *adapter, unsigned short i2c_addr, + unsigned short addr, unsigned char data); +int my_i2c_put_byte_add8(struct i2c_adapter *adapter, unsigned short i2c_addr, + char *buf, int len); +int my_i2c_get_byte(struct i2c_adapter *adapter, unsigned short i2c_addr, + unsigned short addr); +int my_i2c_get_word(struct i2c_adapter *adapter, unsigned short i2c_addr); +#endif + diff --git a/drivers/amlogic/media/camera/common/flashlight.c b/drivers/amlogic/media/camera/common/flashlight.c new file mode 100644 index 000000000000..51018d997832 --- /dev/null +++ b/drivers/amlogic/media/camera/common/flashlight.c @@ -0,0 +1,249 @@ +/* + * drivers/amlogic/media/camera/common/flashlight.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define FLASHLIGHT_MODULE_NAME "flashlight" +#define FLASHLIGHT_DRIVER_NAME "flashlight" +#define FLASHLIGHT_DEVICE_NAME "flashlight" +#define FLASHLIGHT_CLASS_NAME "flashlight" + +static dev_t flashlight_devno; +static struct cdev *flashlight_cdev; +static struct device *devp; + +static enum aml_plat_flashlight_status_s flashlight_flag = FLASHLIGHT_OFF; + +static ssize_t flashlight_ctrl_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count); +static ssize_t flashlightflag_show(struct class *cla, + struct class_attribute *attr, char *buf); +static ssize_t flashlightflag_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count); +static int flashlight_open(struct inode *inode, struct file *file); +static int flashlight_release(struct inode *inode, struct file *file); +static int flashlight_probe(struct platform_device *pdev); +static int flashlight_remove(struct platform_device *pdev); + +static struct platform_driver flashlight_driver = { + .probe = flashlight_probe, .remove = flashlight_remove, .driver = { + .name = + FLASHLIGHT_DRIVER_NAME, .owner = THIS_MODULE, + }, +}; + +static const struct file_operations flashlight_fops = { + .open = flashlight_open, .release = flashlight_release, +}; + +static struct class_attribute flashlight_class_attrs[] = { + __ATTR(flashlight_ctrl, 0644, NULL, flashlight_ctrl_store), + __ATTR(flashlightflag, 0644, flashlightflag_show, + flashlightflag_store), + __ATTR_NULL +}; +static struct class flashlight_class = { + .name = FLASHLIGHT_CLASS_NAME, + .class_attrs = flashlight_class_attrs, + .owner = THIS_MODULE, + }; + +static ssize_t flashlight_ctrl_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + struct aml_plat_flashlight_data_s *pdata = NULL; + struct device *dev = NULL; + + dev = devp; + pdata = (struct aml_plat_flashlight_data_s *)dev->platform_data; + if (pdata == NULL) { + pr_err("%s platform data is required!\n", __func__); + return -1; + } + if (!strncmp(buf, "0", 1)) { + if (pdata->flashlight_off) + pdata->flashlight_off(); + } else if (!strncmp(buf, "1", 1)) { + if (pdata->flashlight_on) + pdata->flashlight_on(); + } else { + pr_err("%s:%s error!Not support this parameter\n", + FLASHLIGHT_MODULE_NAME, __func__); + return -EINVAL; + } + return count; +} + +static ssize_t flashlightflag_show(struct class *cla, + struct class_attribute *attr, char *buf) +{ + sprintf(buf, "%d", (int)flashlight_flag); + return strlen(buf); +} + +static ssize_t flashlightflag_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + if (!strlen(buf)) + pr_info("%s parameter is required!\n", __func__); + flashlight_flag = (enum aml_plat_flashlight_status_s)(buf[0] - '0'); + return count; +} + +static int flashlight_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int flashlight_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static int flashlight_probe(struct platform_device *pdev) +{ + int ret; + struct aml_plat_flashlight_data_s *pdata = NULL; + + ret = alloc_chrdev_region(&flashlight_devno, 0, + 1, FLASHLIGHT_DRIVER_NAME); + if (ret < 0) { + pr_err("%s:%s failed to allocate major number\n", + FLASHLIGHT_MODULE_NAME, __func__); + ret = -ENODEV; + goto out; + } + ret = class_register(&flashlight_class); + if (ret < 0) { + pr_err("%s:%s failed to register class\n", + FLASHLIGHT_MODULE_NAME, __func__); + goto error1; + } + flashlight_cdev = cdev_alloc(); + if (!flashlight_cdev) { + pr_err("%s:%s: failed to allocate memory\n", + FLASHLIGHT_MODULE_NAME, __func__); + ret = -ENOMEM; + goto error2; + } + cdev_init(flashlight_cdev, &flashlight_fops); + flashlight_cdev->owner = THIS_MODULE; + ret = cdev_add(flashlight_cdev, flashlight_devno, 1); + if (ret) { + pr_err("%s:%s: failed to add device\n", + FLASHLIGHT_MODULE_NAME, __func__); + goto error3; + } + devp = device_create(&flashlight_class, NULL, flashlight_devno, NULL, + FLASHLIGHT_DEVICE_NAME); + if (IS_ERR(devp)) { + pr_err("%s:%s failed to create device node\n", + FLASHLIGHT_MODULE_NAME, __func__); + ret = PTR_ERR(devp); + goto error3; + } + pr_info("%s:%s device %s created\n", FLASHLIGHT_MODULE_NAME, + __func__, FLASHLIGHT_DEVICE_NAME); + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "platform data is required!\n"); + ret = -EINVAL; + goto error4; + } + devp->platform_data = pdata; + return 0; +error4: + device_destroy(NULL, flashlight_devno); +error3: + cdev_del(flashlight_cdev); +error2: + class_unregister(&flashlight_class); +error1: + unregister_chrdev_region(flashlight_devno, 1); +out: + return ret; +} + +static int flashlight_remove(struct platform_device *pdev) +{ + unregister_chrdev_region(flashlight_devno, 1); + class_unregister(&flashlight_class); + device_destroy(NULL, flashlight_devno); + cdev_del(flashlight_cdev); + return 0; +} + +int set_flashlight(bool mode) +{ + struct aml_plat_flashlight_data_s *pdata = NULL; + + if (devp && devp->platform_data) { + pdata = devp->platform_data; + if (!mode) { + if (pdata->flashlight_off) + pdata->flashlight_off(); + } else { + if (pdata->flashlight_on) + pdata->flashlight_on(); + } + } + return 0; +} +EXPORT_SYMBOL(set_flashlight); + +enum aml_plat_flashlight_status_s get_flashlightflag(void) +{ + return flashlight_flag; +} +EXPORT_SYMBOL(get_flashlightflag); + +static int __init flashlight_init(void) +{ + int ret = -1; + + ret = platform_driver_register(&flashlight_driver); + if (ret != 0) { + pr_err("failed to register flashlight driver,error %d\n", ret); + return -ENODEV; + } + return ret; +} + +static void __exit flashlight_exit(void) +{ + platform_driver_unregister(&flashlight_driver); +} + +module_init(flashlight_init); +module_exit(flashlight_exit); + +MODULE_DESCRIPTION("AMLOGIC flashlight driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("amlogic"); diff --git a/drivers/amlogic/media/camera/common/plat_ctrl.c b/drivers/amlogic/media/camera/common/plat_ctrl.c new file mode 100644 index 000000000000..44aa8bd8e8b9 --- /dev/null +++ b/drivers/amlogic/media/camera/common/plat_ctrl.c @@ -0,0 +1,208 @@ +/* + * drivers/amlogic/media/camera/common/plat_ctrl.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "plat_ctrl.h" + +/**************************************************************** + * i2c functions + * **************************************************************/ +static int camera_read_buff(struct i2c_client *client, char *buf, int addr_len, + int data_len) +{ + int i2c_flag = -1; + struct i2c_msg msgs[] = {{ + .addr = client->addr, .flags = 0, + .len = addr_len, .buf = buf, + }, { + .addr = client->addr, .flags = I2C_M_RD, + .len = data_len, .buf = buf, + } + }; + + i2c_flag = i2c_transfer(client->adapter, msgs, 2); + + return i2c_flag; +} + +static int camera_write_buff(struct i2c_client *client, char *buf, int len) +{ + struct i2c_msg msg[] = {{ + .addr = client->addr, .flags = 0, /* |I2C_M_TEN, */ + .len = len, .buf = buf, + } + + }; + + if (i2c_transfer(client->adapter, msg, 1) < 0) { + pr_err("i2c error\n"); + return -1; + } else + return 0; +} + +int i2c_get_byte(struct i2c_client *client, unsigned short addr) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + + if (camera_read_buff(client, buff, 2, 1) < 0) + return -1; + return buff[0]; +} + +int i2c_get_byte_add8(struct i2c_client *client, unsigned char addr) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)(addr & 0xff); + + if (camera_read_buff(client, buff, 1, 1) < 0) + return -1; + return buff[0]; +} + +int i2c_get_word(struct i2c_client *client, unsigned short addr) +{ + unsigned short data; + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + + if (camera_read_buff(client, buff, 2, 2) < 0) + return -1; + + data = buff[0]; + data = (data << 8) | buff[1]; + return data; +} + +int i2c_put_byte(struct i2c_client *client, unsigned short addr, + unsigned char data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + buff[2] = data; + if (camera_write_buff(client, buff, 3) < 0) + return -1; + return 0; +} + +int i2c_put_word(struct i2c_client *client, unsigned short addr, + unsigned short data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)((addr >> 8) & 0xff); + buff[1] = (unsigned char)(addr & 0xff); + buff[2] = (unsigned char)((data >> 8) & 0xff); + buff[3] = (unsigned char)(data & 0xff); + + if (camera_write_buff(client, buff, 4) < 0) + return -1; + return 0; +} + +int i2c_put_byte_add8_new(struct i2c_client *client, unsigned char addr, + unsigned char data) +{ + unsigned char buff[4]; + + buff[0] = (unsigned char)(addr & 0xff); + buff[1] = (unsigned char)(data & 0xff); + if (camera_write_buff(client, buff, 2) < 0) + return -1; + return 0; +} + +int i2c_put_byte_add8(struct i2c_client *client, char *buf, int len) +{ + if (camera_write_buff(client, buf, len) < 0) + return -1; + return 0; +} + +int cam_i2c_send_msg(struct i2c_client *client, struct cam_i2c_msg_s i2c_msg) +{ + unsigned char buff[4]; + + switch (i2c_msg.type) { + case ADDR16_DATA16: + buff[0] = (unsigned char)((i2c_msg.addr >> 8) & 0xff); + buff[1] = (unsigned char)(i2c_msg.addr & 0xff); + buff[2] = (unsigned char)((i2c_msg.data >> 8) & 0xff); + buff[3] = (unsigned char)(i2c_msg.data & 0xff); + if (camera_write_buff(client, buff, 4) < 0) + return -1; + break; + case ADDR16_DATA8: + buff[0] = (unsigned char)((i2c_msg.addr >> 8) & 0xff); + buff[1] = (unsigned char)(i2c_msg.addr & 0xff); + buff[2] = (unsigned char)(i2c_msg.data & 0xff); + if (camera_write_buff(client, buff, 3) < 0) + return -1; + break; + case ADDR8_DATA16: + buff[0] = (unsigned char)(i2c_msg.addr & 0xff); + buff[1] = (unsigned char)((i2c_msg.data >> 8) & 0xff); + buff[2] = (unsigned char)(i2c_msg.data & 0xff); + if (camera_write_buff(client, buff, 3) < 0) + return -1; + break; + case ADDR8_DATA8: + buff[0] = (unsigned char)(i2c_msg.addr & 0xff); + buff[1] = (unsigned char)(i2c_msg.data & 0xff); + if (camera_write_buff(client, buff, 2) < 0) + return -1; + break; + case TIME_DELAY: + msleep(i2c_msg.data); + break; + default: + break; + } + return 0; +} + diff --git a/drivers/amlogic/media/camera/common/plat_ctrl.h b/drivers/amlogic/media/camera/common/plat_ctrl.h new file mode 100644 index 000000000000..6bcb6cbfc264 --- /dev/null +++ b/drivers/amlogic/media/camera/common/plat_ctrl.h @@ -0,0 +1,47 @@ +/* + * drivers/amlogic/media/camera/common/plat_ctrl.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _AMLOGIC_CAMERA_PLAT_CTRL_H +#define _AMLOGIC_CAMERA_PLAT_CTRL_H + +#define ADDR8_DATA8 0 +#define ADDR16_DATA8 1 +#define ADDR16_DATA16 2 +#define ADDR8_DATA16 3 +#define TIME_DELAY 0xfe +#define END_OF_SCRIPT 0xff + +struct cam_i2c_msg_s { + unsigned char type; + unsigned short addr; + unsigned short data; +}; + +extern int i2c_get_byte(struct i2c_client *client, unsigned short addr); +extern int i2c_get_word(struct i2c_client *client, unsigned short addr); +extern int i2c_get_byte_add8(struct i2c_client *client, unsigned char addr); +extern int i2c_put_byte(struct i2c_client *client, unsigned short addr, + unsigned char data); +extern int i2c_put_word(struct i2c_client *client, unsigned short addr, + unsigned short data); +extern int i2c_put_byte_add8_new(struct i2c_client *client, unsigned char addr, + unsigned char data); +extern int i2c_put_byte_add8(struct i2c_client *client, char *buf, int len); +extern int cam_i2c_send_msg(struct i2c_client *client, + struct cam_i2c_msg_s i2c_msg); + +#endif /* _AMLOGIC_CAMERA_PLAT_CTRL_H. */ diff --git a/drivers/amlogic/media/camera/common/vm.c b/drivers/amlogic/media/camera/common/vm.c new file mode 100644 index 000000000000..b5ceeabd83ff --- /dev/null +++ b/drivers/amlogic/media/camera/common/vm.c @@ -0,0 +1,2320 @@ +/* + * drivers/amlogic/media/camera/common/vm.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vm_log.h" +#include "vm.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/*class property info.*/ +#include "vmcls.h" + +/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ +#if 1 +#define GE2D_NV +#endif + +#if 0 +static unsigned int amlvm_time_log_enable; +module_param(amlvm_time_log_enable, uint, 0644); +MODULE_PARM_DESC(amlvm_time_log_enable, "enable vm time log when get frames"); +#endif + +#define MAX_VF_POOL_SIZE 8 + +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +/*same as tvin pool*/ +static int VM_POOL_SIZE = 6; +static int VF_POOL_SIZE = 6; +static int VM_CANVAS_ID = 24; +/*same as tvin pool*/ +#endif + + +/*the counter of VM*/ +#define VM_MAX_DEVS 2 + +static struct vm_device_s *vm_device[VM_MAX_DEVS]; + +/* static bool isvmused; */ + +static void vm_cache_this_flush(unsigned int buf_start, + unsigned int buf_size, + struct vm_init_s *info); + +static inline void vm_vf_put_from_provider(struct vframe_s *vf, + unsigned int vdin_id); +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +#define INCPTR(p) ptr_atomic_wrap_inc(&p) +#endif + +#ifdef CONFIG_AMLOGIC_CAPTURE_FRAME_ROTATE +static int vmdecbuf_size[] = { + 0x13B3000,/* 5M */ + 0xc00000,/* 3M */ + 0x753000,/* 2M */ + 0x4b0000,/* 1M3 */ + 0x300000,/* 1M */ + 0x12c000,/* VGA */ + 0x4b000,/* QVGA */ +}; +static struct v4l2_frmsize_discrete canvas_config_wh[] = { + {2624, 2624}, + {2048, 2048}, + {1600, 1600}, + {1280, 1280}, + {1024, 1024}, + {640, 640}, + {320, 320}, +}; +#else +static int vmdecbuf_size[] = { + 0xEE5000,/* 5M */ + 0x900000,/* 3M */ + 0x591000,/* 2M */ + 0x384000,/* 1M3 */ + 0x240000,/* 1M */ + 0xF0000,/* VGA */ + 0x3C000,/* QVGA */ +}; +static struct v4l2_frmsize_discrete canvas_config_wh[] = { + {2624, 1984}, + {2048, 1536}, + {1600, 1216}, + {1280, 960}, + {1024, 768}, + {640, 512}, + {320, 256}, +}; +#endif +#define GE2D_ENDIAN_SHIFT 24 +#define GE2D_ENDIAN_MASK (0x1 << GE2D_ENDIAN_SHIFT) +#define GE2D_BIG_ENDIAN (0 << GE2D_ENDIAN_SHIFT) +#define GE2D_LITTLE_ENDIAN (1 << GE2D_ENDIAN_SHIFT) + +#define PROVIDER_NAME "vm" + +static dev_t vm_devno; +static struct class *vm_clsp; + +#define VM_DEV_NAME "vm" +#define RECEIVER_NAME "vm" +#define VM_CLS_NAME "vm" + +static DEFINE_SPINLOCK(lock); + +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +static inline void ptr_atomic_wrap_inc(u32 *ptr) +{ + u32 i = *ptr; + + i++; + if (i >= VM_POOL_SIZE) + i = 0; + *ptr = i; +} +#endif + +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +static struct vframe_s vfpool[MAX_VF_POOL_SIZE]; +static s32 vfbuf_use[MAX_VF_POOL_SIZE]; +static s32 fill_ptr, get_ptr, putting_ptr, put_ptr; +#endif + +atomic_t waiting_flag = ATOMIC_INIT(0); + +static inline struct vframe_s *vm_vf_get_from_provider(unsigned int vdin_id); +static inline struct vframe_s *vm_vf_peek_from_provider(unsigned int vdin_id); +static inline void vm_vf_put_from_provider(struct vframe_s *vf, + unsigned int vdin_id); +static struct vframe_receiver_op_s *vf_vm_unreg_provider( + struct vm_device_s *vdevp); +static struct vframe_receiver_op_s *vf_vm_reg_provider(struct vm_device_s + *vdevp); +static void stop_vm_task(struct vm_device_s *vdevp); +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +static int prepare_vframe(struct vframe_s *vf); +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/* + *********************************************** + * + * buffer op for video sink. + * + *********************************************** + */ + +#ifdef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +static struct vframe_s *local_vf_peek(unsigned int vdin_id) +{ + struct vframe_s *vf = NULL; + + vf = vm_vf_peek_from_provider(vdin_id); + if (vf) { + if (vm_device[vdin_id]->vm_skip_count > 0) { + vm_device[vdin_id]->vm_skip_count--; + vm_vf_get_from_provider(vdin_id); + vm_vf_put_from_provider(vf, vdin_id); + vf = NULL; + } + } + return vf; +} + +static struct vframe_s *local_vf_get(unsigned int vdin_id) +{ + return vm_vf_get_from_provider(vdin_id); +} + +static void local_vf_put(struct vframe_s *vf, unsigned int vdin_id) +{ + if (vf) + vm_vf_put_from_provider(vf, vdin_id); +} +#else + +static inline u32 index2canvas(u32 index) +{ + int i; + int start_canvas, count; + u32 canvas_tab[6]; + struct vdin_v4l2_ops_s *vops = get_vdin_v4l2_ops(); + + vops->get_tvin_canvas_info(&start_canvas, &count); + VM_POOL_SIZE = count; + VF_POOL_SIZE = count; + VM_CANVAS_ID = start_canvas; + for (i = 0; i < count; i++) + canvas_tab[i] = VM_CANVAS_INDEX + i; + return canvas_tab[index]; +} + +static struct vframe_s *vm_vf_peek(void *op_arg, unsigned int vdin_id) +{ + struct vframe_s *vf = NULL; + + vf = vm_vf_peek_from_provider(vdin_id); + if (vf) { + if (vm_device[vdin_id]->vm_skip_count > 0) { + vm_device[vdin_id]->vm_skip_count--; + vm_vf_get_from_provider(vdin_id); + vm_vf_put_from_provider(vf, vdin_id); + vf = NULL; + } + } + return vf; +} + +static struct vframe_s *vm_vf_get(void *op_arg, unsigned int vdin_id) +{ + return vm_vf_get_from_provider(vdin_id); +} + +static void vm_vf_put(struct vframe_s *vf, void *op_arg) +{ + prepare_vframe(vf); +} + +static int vm_vf_states(struct vframe_states *states, void *op_arg) +{ + return 0; +} + +static struct vframe_s *local_vf_peek(void) +{ + if (get_ptr == fill_ptr) + return NULL; + return &vfpool[get_ptr]; +} + +static struct vframe_s *local_vf_get(unsigned int vdin_id) +{ + struct vframe_s *vf; + + if (get_ptr == fill_ptr) + return NULL; + vf = &vfpool[get_ptr]; + INCPTR(get_ptr); + return vf; +} + +static void local_vf_put(struct vframe_s *vf, unsigned int vdin_id) +{ + int i; + int canvas_addr; + + if (!vf) + return; + INCPTR(putting_ptr); + for (i = 0; i < VF_POOL_SIZE; i++) { + canvas_addr = index2canvas(i); + if (vf->canvas0Addr == canvas_addr) { + vfbuf_use[i] = 0; + vm_vf_put_from_provider(vf, vdin_id); + } + } +} +#endif + +#if 0 +static int local_vf_states(struct vframe_states *states) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&lock, flags); + states->vf_pool_size = VF_POOL_SIZE; + + i = put_ptr - fill_ptr; + if (i < 0) + i += VF_POOL_SIZE; + states->buf_free_num = i; + + i = putting_ptr - put_ptr; + if (i < 0) + i += VF_POOL_SIZE; + states->buf_recycle_num = i; + + i = fill_ptr - get_ptr; + if (i < 0) + i += VF_POOL_SIZE; + states->buf_avail_num = i; + + spin_unlock_irqrestore(&lock, flags); + return 0; +} +#endif + +static int vm_receiver_event_fun(int type, void *data, void *private_data) +{ + struct vm_device_s *vdevp = (struct vm_device_s *)private_data; + + switch (type) { + case VFRAME_EVENT_PROVIDER_VFRAME_READY: + /* if (atomic_read(&waiting_flag)) { */ + wake_up_interruptible(&vdevp->frame_ready); + /* atomic_set(&waiting_flag, 0); */ + /* } */ + /* up(&vb_start_sema); */ + /* printk("vdin %d frame ready !!!!!\n", vdevp->index); */ + break; + case VFRAME_EVENT_PROVIDER_START: + /* printk("vm register!!!!!\n"); */ + vf_vm_reg_provider(vdevp); + vdevp->vm_skip_count = 0; + vdevp->test_zoom = 0; + break; + case VFRAME_EVENT_PROVIDER_UNREG: + /* printk("vm unregister!!!!!\n"); */ + vm_local_init(); + vf_vm_unreg_provider(vdevp); + /* printk("vm unregister succeed!!!!!\n"); */ + break; + default: + break; + } + return 0; +} + +static struct vframe_receiver_op_s vm_vf_receiver = { + .event_cb = vm_receiver_event_fun +}; + +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +static const struct vframe_operations_s vm_vf_provider = { + .peek = vm_vf_peek, + .get = vm_vf_get, + .put = vm_vf_put, + .vf_states = vm_vf_states, +}; + +static struct vframe_provider_s vm_vf_prov; +#endif + + +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +int get_unused_vm_index(void) +{ + int i; + + for (i = 0; i < VF_POOL_SIZE; i++) { + if (vfbuf_use[i] == 0) + return i; + } + return -1; +} +static int prepare_vframe(struct vframe_s *vf) +{ + struct vframe_s *new_vf; + int index; + + index = get_unused_vm_index(); + if (index < 0) + return -1; + new_vf = &vfpool[fill_ptr]; + memcpy(new_vf, vf, sizeof(struct vframe_s)); + vfbuf_use[index]++; + INCPTR(fill_ptr); + return 0; +} +#endif + +/* + ************************************************ + * + * buffer op for decoder, camera, etc. + * + ************************************************** + */ + +/* static const vframe_provider_t *vfp = NULL; */ + +void vm_local_init(void) +{ +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + int i; + + for (i = 0; i < MAX_VF_POOL_SIZE; i++) + vfbuf_use[i] = 0; + fill_ptr = get_ptr = putting_ptr = put_ptr = 0; +#endif +} + +static struct vframe_receiver_op_s *vf_vm_unreg_provider( + struct vm_device_s *vdevp) +{ + /* ulong flags; */ +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + vf_unreg_provider(&vm_vf_prov); +#endif + stop_vm_task(vdevp); + /* spin_lock_irqsave(&lock, flags); */ + /* vfp = NULL; */ + /* spin_unlock_irqrestore(&lock, flags); */ + return (struct vframe_receiver_op_s *)NULL; +} +EXPORT_SYMBOL(vf_vm_unreg_provider); + +static struct vframe_receiver_op_s *vf_vm_reg_provider(struct vm_device_s + *vdevp) +{ + ulong flags; + /* int ret; */ + spin_lock_irqsave(&lock, flags); + spin_unlock_irqrestore(&lock, flags); + vm_buffer_init(vdevp); +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + vf_reg_provider(&vm_vf_prov); +#endif + start_vm_task(vdevp); +#if 0 + start_simulate_task(); +#endif + return &vm_vf_receiver; +} +EXPORT_SYMBOL(vf_vm_reg_provider); + +static inline struct vframe_s *vm_vf_peek_from_provider(unsigned int vdin_id) +{ + struct vframe_provider_s *vfp; + struct vframe_s *vf; + char name[20]; + + sprintf(name, "%s%d", RECEIVER_NAME, vdin_id); + vfp = vf_get_provider(name); + if (!(vfp && vfp->ops && vfp->ops->peek)) + return NULL; + vf = vfp->ops->peek(vfp->op_arg); + return vf; +} + +static inline struct vframe_s *vm_vf_get_from_provider(unsigned int vdin_id) +{ + struct vframe_provider_s *vfp; + char name[20]; + + sprintf(name, "%s%d", RECEIVER_NAME, vdin_id); + vfp = vf_get_provider(name); + if (!(vfp && vfp->ops && vfp->ops->peek)) + return NULL; + return vfp->ops->get(vfp->op_arg); +} + +static inline void vm_vf_put_from_provider(struct vframe_s *vf, + unsigned int vdin_id) +{ + struct vframe_provider_s *vfp; + char name[20]; + + sprintf(name, "%s%d", RECEIVER_NAME, vdin_id); + vfp = vf_get_provider(name); + if (!(vfp && vfp->ops && vfp->ops->peek)) + return; + vfp->ops->put(vf, vfp->op_arg); +} + +/* + *********************************************** + * + * main task functions. + * + *********************************************** + */ + +static unsigned int print_ifmt; +/* module_param(print_ifmt, unsigned int, 0644); */ +/* MODULE_PARM_DESC(print_ifmt, "print input format\n"); */ + +static int get_input_format(struct vframe_s *vf) +{ + int format = GE2D_FORMAT_M24_NV21; + + if (vf->type & VIDTYPE_VIU_422) { + if (vf->type & VIDTYPE_INTERLACE_BOTTOM) + format = GE2D_FORMAT_S16_YUV422 | + (GE2D_FORMAT_S16_YUV422B & (3 << 3)); + else if (vf->type & VIDTYPE_INTERLACE_TOP) + format = GE2D_FORMAT_S16_YUV422 | + (GE2D_FORMAT_S16_YUV422T & (3 << 3)); + else + format = GE2D_FORMAT_S16_YUV422; + } else if (vf->type & VIDTYPE_VIU_NV21) { + if (vf->type & VIDTYPE_INTERLACE_BOTTOM) + format = GE2D_FORMAT_M24_NV21 | + (GE2D_FORMAT_M24_NV21B & (3 << 3)); + else if (vf->type & VIDTYPE_INTERLACE_TOP) + format = GE2D_FORMAT_M24_NV21 | + (GE2D_FORMAT_M24_NV21T & (3 << 3)); + else + format = GE2D_FORMAT_M24_NV21; + } else { + if (vf->type & VIDTYPE_INTERLACE_BOTTOM) + format = GE2D_FORMAT_M24_YUV420 | + (GE2D_FMT_M24_YUV420B & (3 << 3)); + else if (vf->type & VIDTYPE_INTERLACE_TOP) + format = GE2D_FORMAT_M24_YUV420 | + (GE2D_FORMAT_M24_YUV420T & (3 << 3)); + else + format = GE2D_FORMAT_M24_YUV420; + } + if (print_ifmt == 1) { + pr_debug("VIDTYPE_VIU_NV21=%x, vf->type=%x\n", + VIDTYPE_VIU_NV21, vf->type); + pr_debug("format=%x, w=%d, h=%d\n", + format, vf->width, vf->height); + print_ifmt = 0; + } + return format; +} + +#ifdef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER +static int calc_zoom(int *top, int *left, int *bottom, int *right, int zoom) +{ + u32 screen_width, screen_height; + s32 start, end; + s32 video_top, video_left, temp; + u32 video_width, video_height; + u32 ratio_x = 0; + u32 ratio_y = 0; + + if (zoom < 100) + zoom = 100; + + video_top = *top; + video_left = *left; + video_width = *right - *left + 1; + video_height = *bottom - *top + 1; + + screen_width = video_width * zoom / 100; + screen_height = video_height * zoom / 100; + + ratio_x = (video_width << 18) / screen_width; + if (ratio_x * screen_width < (video_width << 18)) + ratio_x++; + ratio_y = (video_height << 18) / screen_height; + + /* vertical */ + start = video_top + video_height / 2 - (video_height << 17) / ratio_y; + end = (video_height << 18) / ratio_y + start - 1; + + if (start < video_top) { + temp = ((video_top - start) * ratio_y) >> 18; + *top = temp; + } else + *top = 0; + + temp = *top + (video_height * ratio_y >> 18); + *bottom = (temp <= (video_height - 1)) ? temp : (video_height - 1); + + /* horizontal */ + start = video_left + video_width / 2 - (video_width << 17) / ratio_x; + end = (video_width << 18) / ratio_x + start - 1; + if (start < video_left) { + temp = ((video_left - start) * ratio_x) >> 18; + *left = temp; + } else + *left = 0; + + temp = *left + (video_width * ratio_x >> 18); + *right = (temp <= (video_width - 1)) ? temp : (video_width - 1); + return 0; +} +#endif + +static int get_input_frame(struct display_frame_s *frame, struct vframe_s *vf, + int zoom) +{ + int ret = 0; + int top, left, bottom, right; + + if (!vf) + return -1; + + frame->frame_top = 0; + frame->frame_left = 0; + frame->frame_width = vf->width; + frame->frame_height = vf->height; + top = 0; + left = 0; + bottom = vf->height - 1; + right = vf->width - 1; +#ifdef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + ret = calc_zoom(&top, &left, &bottom, &right, zoom); +#else + ret = get_curren_frame_para(&top, &left, &bottom, &right); +#endif + if (ret >= 0) { + frame->content_top = top & (~1); + frame->content_left = left & (~1); + frame->content_width = vf->width - 2 * frame->content_left; + frame->content_height = vf->height - 2 * frame->content_top; + } else { + frame->content_top = 0; + frame->content_left = 0; + frame->content_width = vf->width; + frame->content_height = vf->height; + } + return 0; +} + +static int get_output_format(int v4l2_format) +{ + int format = GE2D_FORMAT_S24_YUV444; + + switch (v4l2_format) { + case V4L2_PIX_FMT_RGB565X: + format = GE2D_FORMAT_S16_RGB_565; + break; + case V4L2_PIX_FMT_YUV444: + format = GE2D_FORMAT_S24_YUV444; + break; + case V4L2_PIX_FMT_VYUY: + format = GE2D_FORMAT_S16_YUV422; + break; + case V4L2_PIX_FMT_BGR24: + format = GE2D_FORMAT_S24_RGB; + break; + case V4L2_PIX_FMT_RGB24: + format = GE2D_FORMAT_S24_BGR; + break; + case V4L2_PIX_FMT_NV12: +#ifdef GE2D_NV + format = GE2D_FORMAT_M24_NV12; + break; +#endif + case V4L2_PIX_FMT_NV21: +#ifdef GE2D_NV + format = GE2D_FORMAT_M24_NV21; + break; +#endif + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + format = GE2D_FORMAT_S8_Y; + break; + default: + break; + } + return format; +} + + +struct vm_dma_contig_memory { + u32 magic; + void *vaddr; + dma_addr_t dma_handle; + unsigned long size; + int is_userptr; +}; + +int is_need_ge2d_pre_process(struct vm_output_para output_para) +{ + int ret = 0; + + switch (output_para.v4l2_format) { + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_YUV444: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + ret = 1; + break; + default: + break; + } + return ret; +} + +int is_need_sw_post_process(struct vm_output_para output_para) +{ + int ret = 0; + + switch (output_para.v4l2_memory) { + case MAGIC_DC_MEM: + case MAGIC_RE_MEM: + goto exit; + case MAGIC_SG_MEM: + case MAGIC_VMAL_MEM: + default: + ret = 1; + break; + } +exit: + return ret; +} + +int get_canvas_index(int v4l2_format, int *depth) +{ + int canvas = vm_device[0]->vm_canvas[0]; + *depth = 16; + switch (v4l2_format) { + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_VYUY: + canvas = vm_device[0]->vm_canvas[0]; + *depth = 16; + break; + case V4L2_PIX_FMT_YUV444: + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + canvas = vm_device[0]->vm_canvas[1]; + *depth = 24; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: +#ifdef GE2D_NV + canvas = vm_device[0]->vm_canvas[2] | + (vm_device[0]->vm_canvas[3] << 8); +#else + canvas = vm_device[0]->vm_canvas[2] | + (vm_device[0]->vm_canvas[3] << 8) | + (vm_device[0]->vm_canvas[4] << 16); +#endif + *depth = 12; + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + canvas = vm_device[0]->vm_canvas[5] | + (vm_device[0]->vm_canvas[6] << 8) | + (vm_device[0]->vm_canvas[7] << 16); + *depth = 12; + break; + default: + break; + } + return canvas; +} + +int get_canvas_index_res(int ext_canvas, int v4l2_format, int *depth, int width, + int height, unsigned int buf) +{ + int canvas = ext_canvas; + *depth = 16; + switch (v4l2_format) { + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_VYUY: + canvas = ext_canvas & 0xff; + *depth = 16; + canvas_config(canvas, + (unsigned long)buf, + width * 2, height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + break; + case V4L2_PIX_FMT_YUV444: + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + canvas = ext_canvas & 0xff; + *depth = 24; + canvas_config(canvas, + (unsigned long)buf, + width * 3, height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + canvas_config(ext_canvas & 0xff, + (unsigned long)buf, + width, height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config((ext_canvas & 0xff00) >> 8, + (unsigned long)(buf + width * height), + width, height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas = ext_canvas & 0xffff; + *depth = 12; + break; + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YUV420: + canvas_config(ext_canvas & 0xff, + (unsigned long)buf, + width, height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config((ext_canvas & 0xff00) >> 8, + (unsigned long)(buf + width * height), + width / 2, height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config((ext_canvas & 0xff0000) >> 16, + (unsigned long)(buf + width * height * 5 / 4), + width / 2, height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas = ext_canvas & 0xffffff; + *depth = 12; + break; + default: + break; + } + return canvas; +} + +#if 0 +static void vm_dump_mem(char *path, void *phy_addr, struct vm_output_para *para) +{ + struct file *filp = NULL; + loff_t pos = 0; + void *buf = NULL; + unsigned int size = para->bytesperline * para->height; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + filp = filp_open(path, O_RDWR | O_CREAT, 0666); + + if (IS_ERR(filp)) { + pr_err("create %s error.\n", path); + return; + } + + + buf = phys_to_virt((unsigned long)phy_addr); + vfs_write(filp, buf, size, &pos); + + vfs_fsync(filp, 0); + filp_close(filp, NULL); + set_fs(old_fs); +} + +static void vm_x_mem(char *path, struct vm_output_para *para) +{ + struct file *filp = NULL; + loff_t pos = 0; + void *buf = NULL; + unsigned int size = para->bytesperline * para->height; + unsigned int canvas_index = para->index; + struct canvas_s cv; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + filp = filp_open(path, O_CREAT | O_RDWR | O_APPEND, 0666); + + if (IS_ERR(filp)) { + pr_err("failed to create %s, error %p.\n", + path, filp); + return; + } + + for (; canvas_index != 0; canvas_index >>= 8) { + canvas_read(canvas_index & 0xff, &cv); + /* printk("index=%lx,canvas.addr=%lx, w=%d, h=%d\n", */ + /* canvas_index, cv.addr, cv.width, cv.height); */ + + buf = phys_to_virt(cv.addr); + + size = cv.width * cv.height; + + vfs_write(filp, buf, size, &pos); + vfs_fsync(filp, 0); + } + filp_close(filp, NULL); + set_fs(old_fs); +} +#endif + +int vm_fill_this_buffer(struct videobuf_buffer *vb, + struct vm_output_para *para, struct vm_init_s *info) + +{ + int depth = 0; + int ret = 0; + int canvas_index = -1; + int v4l2_format = V4L2_PIX_FMT_YUV444; + int magic = 0; + int ext_canvas; + struct videobuf_buffer buf = {0}; + + if (!info) + return -1; + if (info->vdin_id >= VM_MAX_DEVS) { + pr_err("beyond the device array bound .\n"); + return -1; + } + /* if (info->isused == false) */ + /* return -2; */ +#if 0 + if (!vb) + goto exit; +#else + if (!vb) { + buf.width = 640; + buf.height = 480; + v4l2_format = V4L2_PIX_FMT_YUV444; + vb = &buf; + } + + if (!vm_device[info->vdin_id]->task_running) + return -1; +#endif + + v4l2_format = para->v4l2_format; + magic = para->v4l2_memory; + switch (magic) { + case MAGIC_DC_MEM: + /* mem = vb->priv; */ + canvas_config(vm_device[0]->vm_canvas[11], + (dma_addr_t)para->vaddr, + vb->bytesperline, vb->height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_index = vm_device[0]->vm_canvas[11]; + depth = (vb->bytesperline << 3) / vb->width; + break; + case MAGIC_RE_MEM: + if (para->ext_canvas != 0) + canvas_index = get_canvas_index_res( + para->ext_canvas, v4l2_format, + &depth, vb->width, + (para->height == 0) ? vb->height : para->height, + (unsigned int)para->vaddr); + else if (info->vdin_id == 0) { + ext_canvas = ((vm_device[0]->vm_canvas[3]) | + (vm_device[0]->vm_canvas[4] << 8) | + (vm_device[0]->vm_canvas[5] << 16)); + canvas_index = + get_canvas_index_res(ext_canvas, + v4l2_format, &depth, vb->width, + vb->height, (unsigned int)para->vaddr); + } else { + ext_canvas = ((vm_device[1]->vm_canvas[0]) | + (vm_device[1]->vm_canvas[1] << 8) | + (vm_device[1]->vm_canvas[2] << 16)); + canvas_index = + get_canvas_index_res(ext_canvas, + v4l2_format, &depth, vb->width, + vb->height, (unsigned int)para->vaddr); + } + break; + case MAGIC_SG_MEM: + case MAGIC_VMAL_MEM: + if (vm_device[info->vdin_id]->buffer_start && + vm_device[info->vdin_id]->buffer_size) + canvas_index = get_canvas_index(v4l2_format, &depth); + break; + default: + canvas_index = vm_device[0]->vm_canvas[0]; + break; + } + vm_device[info->vdin_id]->output_para.width = vb->width; + vm_device[info->vdin_id]->output_para.height = vb->height; + vm_device[info->vdin_id]->output_para.bytesperline = + (vb->width * depth) >> 3; + vm_device[info->vdin_id]->output_para.index = canvas_index; + vm_device[info->vdin_id]->output_para.v4l2_format = v4l2_format; + vm_device[info->vdin_id]->output_para.v4l2_memory = magic; + vm_device[info->vdin_id]->output_para.mirror = para->mirror; + vm_device[info->vdin_id]->output_para.zoom = para->zoom; + vm_device[info->vdin_id]->output_para.angle = para->angle; + vm_device[info->vdin_id]->output_para.vaddr = para->vaddr; + vm_device[info->vdin_id]->output_para.ext_canvas = + (magic == MAGIC_RE_MEM) ? para->ext_canvas : 0; + complete(&vm_device[info->vdin_id]->vb_start_sema); + wait_for_completion(&vm_device[info->vdin_id]->vb_done_sema); + if (magic == MAGIC_RE_MEM) + vm_cache_this_flush((unsigned int)para->vaddr, + para->bytesperline * + para->height, info); + + return ret; +} + +/* + *for decoder input processing + * 1. output window should 1:1 as source frame size + * 2. keep the frame ratio + * 3. input format should be YUV420 , output format should be YUV444 + */ + +int vm_ge2d_pre_process(struct vframe_s *vf, + struct ge2d_context_s *context, + struct config_para_ex_s *ge2d_config, + struct vm_output_para output_para, + unsigned int index) +{ + int ret; + int src_top, src_left, src_width, src_height; + struct canvas_s cs0, cs1, cs2, cd; + int current_mirror = 0; + int cur_angle = 0; + struct display_frame_s input_frame = {0}; + + ret = get_input_frame(&input_frame, vf, output_para.zoom); + src_top = input_frame.content_top; + src_left = input_frame.content_left; + src_width = input_frame.content_width; + src_height = input_frame.content_height; + if (vm_device[index]->test_zoom) { + vm_device[index]->test_zoom = 0; + pr_debug("top is %d , left is %d\n", + input_frame.content_top, + input_frame.content_left); + pr_debug("width is %d , height is %d\n", + input_frame.content_width, + input_frame.content_height); + } +#ifdef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + current_mirror = output_para.mirror; + if (current_mirror < 0) + current_mirror = 0; +#else + current_mirror = camera_mirror_flag; +#endif + + cur_angle = output_para.angle; + if (current_mirror == 1) + cur_angle = (360 - cur_angle % 360); + else + cur_angle = cur_angle % 360; + + /* data operating. */ + ge2d_config->alu_const_color = 0; /* 0x000000ff; */ + ge2d_config->bitmask_en = 0; + ge2d_config->src1_gb_alpha = 0;/* 0xff; */ + ge2d_config->dst_xy_swap = 0; + + canvas_read(vf->canvas0Addr & 0xff, &cs0); + canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1); + canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2); + ge2d_config->src_planes[0].addr = cs0.addr; + ge2d_config->src_planes[0].w = cs0.width; + ge2d_config->src_planes[0].h = cs0.height; + ge2d_config->src_planes[1].addr = cs1.addr; + ge2d_config->src_planes[1].w = cs1.width; + ge2d_config->src_planes[1].h = cs1.height; + ge2d_config->src_planes[2].addr = cs2.addr; + ge2d_config->src_planes[2].w = cs2.width; + ge2d_config->src_planes[2].h = cs2.height; + canvas_read(output_para.index & 0xff, &cd); + ge2d_config->dst_planes[0].addr = cd.addr; + ge2d_config->dst_planes[0].w = cd.width; + ge2d_config->dst_planes[0].h = cd.height; + ge2d_config->src_key.key_enable = 0; + ge2d_config->src_key.key_mask = 0; + ge2d_config->src_key.key_mode = 0; + ge2d_config->src_para.canvas_index = vf->canvas0Addr; + ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID; + ge2d_config->src_para.format = get_input_format(vf); + ge2d_config->src_para.fill_color_en = 0; + ge2d_config->src_para.fill_mode = 0; + ge2d_config->src_para.x_rev = 0; + ge2d_config->src_para.y_rev = 0; + ge2d_config->src_para.color = 0xffffffff; + ge2d_config->src_para.top = 0; + ge2d_config->src_para.left = 0; + ge2d_config->src_para.width = vf->width; + ge2d_config->src_para.height = vf->height; + ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID; + ge2d_config->dst_para.canvas_index = output_para.index & 0xff; +#ifdef GE2D_NV + if ((output_para.v4l2_format != V4L2_PIX_FMT_YUV420) + && (output_para.v4l2_format != V4L2_PIX_FMT_YVU420)) + ge2d_config->dst_para.canvas_index = output_para.index; +#endif + ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID; + ge2d_config->dst_para.format = + get_output_format(output_para.v4l2_format) | + GE2D_LITTLE_ENDIAN; + ge2d_config->dst_para.fill_color_en = 0; + ge2d_config->dst_para.fill_mode = 0; + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 0; + ge2d_config->dst_para.color = 0; + ge2d_config->dst_para.top = 0; + ge2d_config->dst_para.left = 0; + ge2d_config->dst_para.width = output_para.width; + ge2d_config->dst_para.height = output_para.height; + + if (current_mirror == 1) { + ge2d_config->dst_para.x_rev = 1; + ge2d_config->dst_para.y_rev = 0; + } else if (current_mirror == 2) { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 1; + } else { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 0; + } + + if (cur_angle == 90) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.x_rev ^= 1; + } else if (cur_angle == 180) { + ge2d_config->dst_para.x_rev ^= 1; + ge2d_config->dst_para.y_rev ^= 1; + } else if (cur_angle == 270) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.y_rev ^= 1; + } + + if (ge2d_context_config_ex(context, ge2d_config) < 0) { + pr_err("++ge2d configing error.\n"); + return -1; + } + stretchblt_noalpha(context, src_left, src_top, + src_width, src_height, 0, 0, + output_para.width, output_para.height); + + /* for cr of yuv420p or yuv420sp. */ + if ((output_para.v4l2_format == V4L2_PIX_FMT_YUV420) + || (output_para.v4l2_format == V4L2_PIX_FMT_YVU420)) { + /* for cb. */ + canvas_read((output_para.index >> 8) & 0xff, &cd); + ge2d_config->dst_planes[0].addr = cd.addr; + ge2d_config->dst_planes[0].w = cd.width; + ge2d_config->dst_planes[0].h = cd.height; + ge2d_config->dst_para.canvas_index = + (output_para.index >> 8) & 0xff; +#ifndef GE2D_NV + ge2d_config->dst_para.format = + GE2D_FORMAT_S8_CB | GE2D_LITTLE_ENDIAN; +#else + ge2d_config->dst_para.format = + GE2D_FORMAT_S8_CR | GE2D_LITTLE_ENDIAN; +#endif + ge2d_config->dst_para.width = output_para.width / 2; + ge2d_config->dst_para.height = output_para.height / 2; + ge2d_config->dst_xy_swap = 0; + + if (current_mirror == 1) { + ge2d_config->dst_para.x_rev = 1; + ge2d_config->dst_para.y_rev = 0; + } else if (current_mirror == 2) { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 1; + } else { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 0; + } + + if (cur_angle == 90) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.x_rev ^= 1; + } else if (cur_angle == 180) { + ge2d_config->dst_para.x_rev ^= 1; + ge2d_config->dst_para.y_rev ^= 1; + } else if (cur_angle == 270) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.y_rev ^= 1; + } + + if (ge2d_context_config_ex(context, ge2d_config) < 0) { + pr_err("++ge2d configing error.\n"); + return -1; + } + stretchblt_noalpha(context, src_left, src_top, + src_width, src_height, + 0, 0, ge2d_config->dst_para.width, + ge2d_config->dst_para.height); + } +#ifndef GE2D_NV + else if (output_para.v4l2_format == V4L2_PIX_FMT_NV12 || + output_para.v4l2_format == V4L2_PIX_FMT_NV21) { + canvas_read((output_para.index >> 8) & 0xff, &cd); + ge2d_config->dst_planes[0].addr = cd.addr; + ge2d_config->dst_planes[0].w = cd.width; + ge2d_config->dst_planes[0].h = cd.height; + ge2d_config->dst_para.canvas_index = + (output_para.index >> 8) & 0xff; + ge2d_config->dst_para.format = + GE2D_FORMAT_S8_CB | GE2D_LITTLE_ENDIAN; + ge2d_config->dst_para.width = output_para.width / 2; + ge2d_config->dst_para.height = output_para.height / 2; + ge2d_config->dst_xy_swap = 0; + + if (current_mirror == 1) { + ge2d_config->dst_para.x_rev = 1; + ge2d_config->dst_para.y_rev = 0; + } else if (current_mirror == 2) { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 1; + } else { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 0; + } + + if (cur_angle == 90) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.x_rev ^= 1; + } else if (cur_angle == 180) { + ge2d_config->dst_para.x_rev ^= 1; + ge2d_config->dst_para.y_rev ^= 1; + } else if (cur_angle == 270) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.y_rev ^= 1; + } + + if (ge2d_context_config_ex(context, ge2d_config) < 0) { + pr_err("++ge2d configing error.\n"); + return -1; + } + stretchblt_noalpha(context, src_left, src_top, + src_width, src_height, 0, 0, + ge2d_config->dst_para.width, + ge2d_config->dst_para.height); + } +#endif + + /* for cb of yuv420p or yuv420sp. */ + if (output_para.v4l2_format == V4L2_PIX_FMT_YUV420 || + output_para.v4l2_format == V4L2_PIX_FMT_YVU420 +#ifndef GE2D_NV + || output_para.v4l2_format == V4L2_PIX_FMT_NV12 || + output_para.v4l2_format == V4L2_PIX_FMT_NV21 +#endif + ) { + canvas_read((output_para.index >> 16) & 0xff, &cd); + ge2d_config->dst_planes[0].addr = cd.addr; + ge2d_config->dst_planes[0].w = cd.width; + ge2d_config->dst_planes[0].h = cd.height; + ge2d_config->dst_para.canvas_index = + (output_para.index >> 16) & 0xff; +#ifndef GE2D_NV + ge2d_config->dst_para.format = + GE2D_FORMAT_S8_CR | GE2D_LITTLE_ENDIAN; +#else + ge2d_config->dst_para.format = + GE2D_FORMAT_S8_CB | GE2D_LITTLE_ENDIAN; +#endif + ge2d_config->dst_para.width = output_para.width / 2; + ge2d_config->dst_para.height = output_para.height / 2; + ge2d_config->dst_xy_swap = 0; + + if (current_mirror == 1) { + ge2d_config->dst_para.x_rev = 1; + ge2d_config->dst_para.y_rev = 0; + } else if (current_mirror == 2) { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 1; + } else { + ge2d_config->dst_para.x_rev = 0; + ge2d_config->dst_para.y_rev = 0; + } + + if (cur_angle == 90) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.x_rev ^= 1; + } else if (cur_angle == 180) { + ge2d_config->dst_para.x_rev ^= 1; + ge2d_config->dst_para.y_rev ^= 1; + } else if (cur_angle == 270) { + ge2d_config->dst_xy_swap = 1; + ge2d_config->dst_para.y_rev ^= 1; + } + + if (ge2d_context_config_ex(context, ge2d_config) < 0) { + pr_err("++ge2d configing error.\n"); + return -1; + } + stretchblt_noalpha(context, src_left, + src_top, src_width, src_height, + 0, 0, ge2d_config->dst_para.width, + ge2d_config->dst_para.height); + } + return output_para.index; +} + +int vm_sw_post_process(int canvas, uintptr_t addr, unsigned int index) +{ + int poss = 0, posd = 0; + int i = 0; + void __iomem *buffer_y_start; + void __iomem *buffer_u_start; + void __iomem *buffer_v_start = 0; + struct io_mapping *mapping_wc; + int offset = 0; + struct canvas_s canvas_work_y; + struct canvas_s canvas_work_u; + struct canvas_s canvas_work_v; + struct vm_output_para output_para = vm_device[index]->output_para; + + if (!addr) + return -1; + mapping_wc = io_mapping_create_wc(vm_device[index]->buffer_start, + vm_device[index]->buffer_size); + if (!mapping_wc) + return -1; + canvas_read(canvas & 0xff, &canvas_work_y); + offset = 0; + buffer_y_start = io_mapping_map_atomic_wc(mapping_wc, offset); + if (buffer_y_start == NULL) { + pr_err(" vm.postprocess:mapping buffer error\n"); + io_mapping_free(mapping_wc); + return -1; + } + if (output_para.v4l2_format == V4L2_PIX_FMT_BGR24 || + output_para.v4l2_format == V4L2_PIX_FMT_RGB24 || + output_para.v4l2_format == V4L2_PIX_FMT_RGB565X) { + for (i = 0; i < output_para.height; i++) { + memcpy((void *)(addr + poss), + (void *)(buffer_y_start + posd), + output_para.bytesperline); + poss += output_para.bytesperline; + posd += canvas_work_y.width; + } + io_mapping_unmap_atomic(buffer_y_start); + + } else if (output_para.v4l2_format == V4L2_PIX_FMT_NV12 || + output_para.v4l2_format == V4L2_PIX_FMT_NV21) { +#ifdef GE2D_NV + unsigned int uv_width = output_para.width; + unsigned int uv_height = output_para.height >> 1; + + posd = 0; + for (i = output_para.height; i > 0; i--) { /* copy y */ + memcpy((void *)(addr + poss), + (void *)(buffer_y_start + posd), + output_para.width); + poss += output_para.width; + posd += canvas_work_y.width; + } + io_mapping_unmap_atomic(buffer_y_start); + + posd = 0; + canvas_read((canvas >> 8) & 0xff, &canvas_work_u); + offset = canvas_work_u.addr - canvas_work_y.addr; + buffer_u_start = io_mapping_map_atomic_wc(mapping_wc, offset); + for (i = uv_height; i > 0; i--) { /* copy uv */ + memcpy((void *)(addr + poss), + (void *)(buffer_u_start + posd), uv_width); + poss += uv_width; + posd += canvas_work_u.width; + } + + io_mapping_unmap_atomic(buffer_u_start); +#else + char *dst_buff = NULL; + char *src_buff = NULL; + char *src2_buff = NULL; + + canvas_read((canvas >> 8) & 0xff, &canvas_work_u); + poss = posd = 0; + for (i = 0; i < output_para.height; i += 2) { /* copy y */ + memcpy((void *)(addr + poss), + (void *)(buffer_y_start + posd), + output_para.width); + poss += output_para.width; + posd += canvas_work_y.width; + memcpy((void *)(addr + poss), + (void *)(buffer_y_start + posd), + output_para.width); + poss += output_para.width; + posd += canvas_work_y.width; + } + io_mapping_unmap_atomic(buffer_y_start); + + posd = 0; + canvas_read((canvas >> 16) & 0xff, &canvas_work_v); + offset = canvas_work_u.addr - canvas_work_y.addr; + buffer_u_start = io_mapping_map_atomic_wc(mapping_wc, offset); + offset = canvas_work_v.addr - canvas_work_y.addr; + buffer_v_start = io_mapping_map_atomic_wc(mapping_wc, offset); + + dst_buff = (char *)addr + + output_para.width * output_para.height; + src_buff = (char *)buffer_u_start; + src2_buff = (char *)buffer_v_start; + if (output_para.v4l2_format == V4L2_PIX_FMT_NV12) { + for (i = 0 ; i < output_para.height / 2; i++) { + interleave_uv(src_buff, src2_buff, + dst_buff, output_para.width / 2); + src_buff += canvas_work_u.width; + src2_buff += canvas_work_v.width; + dst_buff += output_para.width; + } + } else { + for (i = 0 ; i < output_para.height / 2; i++) { + interleave_uv(src2_buff, src_buff, + dst_buff, output_para.width / 2); + src_buff += canvas_work_u.width; + src2_buff += canvas_work_v.width; + dst_buff += output_para.width; + } + } + + + io_mapping_unmap_atomic(buffer_u_start); + io_mapping_unmap_atomic(buffer_v_start); +#endif + } else if ((output_para.v4l2_format == V4L2_PIX_FMT_YUV420) + || (output_para.v4l2_format == V4L2_PIX_FMT_YVU420)) { + int uv_width = output_para.width >> 1; + int uv_height = output_para.height >> 1; + + posd = 0; + for (i = output_para.height; i > 0; i--) { /* copy y */ + memcpy((void *)(addr + poss), + (void *)(buffer_y_start + posd), + output_para.width); + poss += output_para.width; + posd += canvas_work_y.width; + } + io_mapping_unmap_atomic(buffer_y_start); + + posd = 0; + canvas_read((canvas >> 8) & 0xff, &canvas_work_u); + offset = canvas_work_u.addr - canvas_work_y.addr; + buffer_u_start = io_mapping_map_atomic_wc(mapping_wc, offset); + + canvas_read((canvas >> 16) & 0xff, &canvas_work_v); + offset = canvas_work_v.addr - canvas_work_y.addr; + buffer_v_start = io_mapping_map_atomic_wc(mapping_wc, offset); + +#ifndef GE2D_NV + if (output_para.v4l2_format == V4L2_PIX_FMT_YUV420) +#else + if (output_para.v4l2_format == V4L2_PIX_FMT_YVU420) { +#endif + for (i = uv_height; i > 0; i--) { /* copy y */ + memcpy((void *)(addr + poss), + (void *)(buffer_u_start + posd), + uv_width); + poss += uv_width; + posd += canvas_work_u.width; + } + posd = 0; + for (i = uv_height; i > 0; i--) { /* copy y */ + memcpy((void *)(addr + poss), + (void *)(buffer_v_start + posd), + uv_width); + poss += uv_width; + posd += canvas_work_v.width; + } + } else { + for (i = uv_height; i > 0; i--) { /* copy v */ + memcpy((void *)(addr + poss), + (void *)(buffer_v_start + posd), + uv_width); + poss += uv_width; + posd += canvas_work_v.width; + } + posd = 0; + for (i = uv_height; i > 0; i--) { /* copy u */ + memcpy((void *)(addr + poss), + (void *)(buffer_u_start + posd), + uv_width); + poss += uv_width; + posd += canvas_work_u.width; + } + } + io_mapping_unmap_atomic(buffer_u_start); + io_mapping_unmap_atomic(buffer_v_start); +} + + if (mapping_wc) + io_mapping_free(mapping_wc); + + return 0; +} + +static struct task_struct *simulate_task_fd; + +static bool is_vf_available(unsigned int vdin_id) +{ + bool ret = ((local_vf_peek(vdin_id) != NULL) || + (!vm_device[vdin_id]->task_running)); + return ret; +} + +/* static int reset_frame = 1; */ +static int vm_task(void *data) +{ + int ret = 0; + struct vframe_s *vf; + int src_canvas; + struct vm_device_s *devp = (struct vm_device_s *) data; + struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 }; + struct ge2d_context_s *context = create_ge2d_work_queue(); + struct config_para_ex_s ge2d_config; + +#ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES + struct timeval start; + struct timeval end; + unsigned long time_use = 0; +#endif + memset(&ge2d_config, 0, sizeof(struct config_para_ex_s)); + sched_setscheduler(current, SCHED_FIFO, ¶m); + allow_signal(SIGTERM); + while (1) { + ret = wait_for_completion_interruptible( + &devp->vb_start_sema); + + if (kthread_should_stop()) { + complete(&devp->vb_done_sema); + break; + } + + /* wait for frame from 656 provider until 500ms runs out */ + wait_event_interruptible_timeout(devp->frame_ready, + is_vf_available(devp->index), + msecs_to_jiffies(2000)); + + if (!devp->task_running) { + ret = -1; + goto vm_exit; + } + + /* start to convert frame. */ +#ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES + do_gettimeofday(&start); +#endif + vf = local_vf_get(devp->index); + + if (vf) { + src_canvas = vf->canvas0Addr; + + /* step1 convert 422 format to other format.*/ + if (is_need_ge2d_pre_process(devp->output_para)) + src_canvas = vm_ge2d_pre_process(vf, context, + &ge2d_config, devp->output_para, + devp->index); +#if 0 + if (devp->dump == 2) { + vm_dump_mem(devp->dump_path, + (void *)output_para.vaddr, &output_para); + devp->dump = 0; + } +#endif + local_vf_put(vf, devp->index); +#ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES + do_gettimeofday(&end); + time_use = (end.tv_sec - start.tv_sec) * 1000 + + (end.tv_usec - start.tv_usec) / 1000; + pr_debug("step 1, ge2d use: %ldms\n", time_use); + do_gettimeofday(&start); +#endif + + /* step2 copy to user memory. */ + + if (is_need_sw_post_process(devp->output_para)) + vm_sw_post_process(src_canvas, + devp->output_para.vaddr, devp->index); + +#ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES + do_gettimeofday(&end); + time_use = (end.tv_sec - start.tv_sec) * 1000 + + (end.tv_usec - start.tv_usec) / 1000; + pr_debug("step 2, memcpy use: %ldms\n", time_use); +#endif + } + if (kthread_should_stop()) { + complete(&devp->vb_done_sema); + break; + } + complete(&devp->vb_done_sema); + } +vm_exit: + destroy_ge2d_work_queue(context); + while (!kthread_should_stop()) { + /*may not call stop, wait.. + *it is killed by SIGTERM,eixt on + *down_interruptible. + *if not call stop,this thread + *may on do_exit and + *kthread_stop may not work good; + */ + msleep(20);/*default 10ms*/ + } + return ret; +} + +/*simulate v4l2 device to request*/ +/*filling buffer,only for test use*/ +static int simulate_task(void *data) +{ + while (1) { + msleep(50); + pr_debug("simulate succeed\n"); + } + return 0; +} + +/* + *********************************************** + * + * init functions. + * + *********************************************** + */ + +int alloc_vm_canvas(struct vm_device_s *vdevp) +{ + int j; + if (vdevp->index == 0) { + for (j = 0; j < MAX_CANVAS_INDEX; j++) { + memset(&(vdevp->vm_canvas[j]), -1, sizeof(int)); + vdevp->vm_canvas[j] = + canvas_pool_map_alloc_canvas("vm0"); + if (vdevp->vm_canvas[j] < 0) { + pr_err("alloc vm0_canvas %d failed\n", j); + return -1; + } + } + } else { + for (j = 0; j < MAX_CANVAS_INDEX; j++) { + memset(&(vdevp->vm_canvas[j]), -1, sizeof(int)); + vdevp->vm_canvas[j] = + canvas_pool_map_alloc_canvas("vm1"); + if (vdevp->vm_canvas[j] < 0) { + pr_err("alloc vm1_canvas %d failed\n", j); + return -1; + } + } + } + + return 0; +} + +int vm_buffer_init(struct vm_device_s *vdevp) +{ + int i; + u32 canvas_width, canvas_height; + u32 decbuf_size; + resource_size_t buf_start; + unsigned int buf_size; + int buf_num = 0; + int local_pool_size = 0; + + init_completion(&vdevp->vb_start_sema); + init_completion(&vdevp->vb_done_sema); + + buf_start = vdevp->buffer_start; + buf_size = vdevp->buffer_size; + + if (!buf_start || !buf_size) + goto exit; + + for (i = 0; i < ARRAY_SIZE(vmdecbuf_size); i++) { + if (buf_size >= vmdecbuf_size[i]) + break; + } + if (i == ARRAY_SIZE(vmdecbuf_size)) { + pr_debug("vmbuf size=%d less than the smallest vmbuf size%d\n", + buf_size, vmdecbuf_size[i - 1]); + return -1; + } + + canvas_width = canvas_config_wh[i].width;/* 1920; */ + canvas_height = canvas_config_wh[i].height;/* 1200; */ + decbuf_size = vmdecbuf_size[i];/* 0x700000; */ + buf_num = buf_size / decbuf_size; + + if (buf_num > 0) + local_pool_size = 1; + else { + local_pool_size = 0; + pr_debug("need at least one buffer to handle 1920*1080 data.\n"); + } + + for (i = 0; i < local_pool_size; i++) { + canvas_config((vdevp->vm_canvas[0] + i), + (unsigned long)(buf_start + i * decbuf_size), + canvas_width * 2, canvas_height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config((vdevp->vm_canvas[2] + i), + (unsigned long)(buf_start + i * decbuf_size), + canvas_width * 3, canvas_height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config((vdevp->vm_canvas[4] + i), + (unsigned long)(buf_start + i * decbuf_size / 2), + canvas_width, canvas_height, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config(vdevp->vm_canvas[6] + i, + (unsigned long)(buf_start + + (i + 1)*decbuf_size / 2), + canvas_width, canvas_height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + + canvas_config((vdevp->vm_canvas[8] + i), + (unsigned long)(buf_start + + (i + 1)*decbuf_size / 2), + canvas_width / 2, canvas_height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + canvas_config((vdevp->vm_canvas[10] + i), + (unsigned long)(buf_start + + (i + 3)*decbuf_size / 4), + canvas_width / 2, canvas_height / 2, + CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + vfbuf_use[i] = 0; +#endif + } + +exit: + return 0; + +} + +int start_vm_task(struct vm_device_s *vdevp) +{ + /* init the device. */ + vm_local_init(); + if (!vdevp->task) { + vdevp->task = kthread_create(vm_task, vdevp, vdevp->name); + if (IS_ERR(vdevp->task)) { + pr_err("thread creating error.\n"); + return -1; + } + init_waitqueue_head(&vdevp->frame_ready); + wake_up_process(vdevp->task); + } + vdevp->task_running = 1; + return 0; +} + +int start_simulate_task(void) +{ + if (!simulate_task_fd) { + simulate_task_fd = kthread_create(simulate_task, 0, "vm"); + if (IS_ERR(simulate_task_fd)) { + pr_err("thread creating error.\n"); + return -1; + } + wake_up_process(simulate_task_fd); + } + return 0; +} + + +void stop_vm_task(struct vm_device_s *vdevp) +{ + if (vdevp->task) { + vdevp->task_running = 0; + send_sig(SIGTERM, vdevp->task, 1); + complete(&vdevp->vb_start_sema); + wake_up_interruptible(&vdevp->frame_ready); + kthread_stop(vdevp->task); + vdevp->task = NULL; + } + vm_local_init(); +} + + +/* + ********************************************************************** + * + * global status. + * + ********************************************************************** + */ + +static int vm_enable_flag; + +int get_vm_status(void) +{ + return vm_enable_flag; +} + +void set_vm_status(int flag) +{ + if (flag >= 0) + vm_enable_flag = flag; + else + vm_enable_flag = 0; +} + +/* + ********************************************************************** + * + * file op section. + * + ********************************************************************** + */ + +void unset_vm_buf_res(struct vm_init_s *info) +{ + info->buffer_start = 0; +} + +static void vm_cache_this_flush(unsigned int buf_start, unsigned int buf_size, + struct vm_init_s *info) +{ + struct vm_device_s *devp = vm_device[info->vdin_id]; + + if (devp->dev) { + if ((buf_start >= info->buffer_start) && + ((buf_start + buf_size) <= (info->buffer_start + + info->vm_buf_size))) + dma_sync_single_for_cpu(devp->dev, + buf_start, buf_size, DMA_FROM_DEVICE); + } +} + +static int vm_open(struct inode *inode, struct file *file) +{ + struct ge2d_context_s *context = NULL; + + pr_info("open one vm device\n"); + file->private_data = context; + /* vm_device.open_count++; */ + return 0; +} + +static long vm_ioctl(struct file *filp, unsigned int cmd, unsigned long args) +{ + int ret = 0; + struct ge2d_context_s *context; + void __user *argp; + + context = (struct ge2d_context_s *)filp->private_data; + argp = (void __user *)args; + switch (cmd) { + case VM_IOC_2OSD0: + break; + case VM_IOC_ENABLE_PP: + break; + case VM_IOC_CONFIG_FRAME: + break; + default: + return -ENOIOCTLCMD; + } + return ret; +} + +static int vm_release(struct inode *inode, struct file *file) +{ + struct ge2d_context_s *context = + (struct ge2d_context_s *)file->private_data; + + if (context && (destroy_ge2d_work_queue(context) == 0)) { + /* vm_device.open_count--; */ + return 0; + } + pr_info("release one vm device\n"); + return -1; +} + +/* + ********************************************************************** + * + * file op init section. + * + ********************************************************************** + */ + +static const struct file_operations vm_fops = { + .owner = THIS_MODULE, + .open = vm_open, + .unlocked_ioctl = vm_ioctl, + .release = vm_release, +}; + +static ssize_t vm_attr_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ssize_t len = 0; + struct vm_device_s *devp; + + devp = dev_get_drvdata(dev); + if (devp->task_running == 0) { + len += sprintf(buf + len, "vm does not start\n"); + return len; + } + + len += sprintf((char *)buf + len, "vm parameters below\n"); + + return len; +} + +static ssize_t vm_attr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + struct vm_device_s *devp; + unsigned int n = 0; + char *buf_orig, *ps, *token; + char *parm[6] = {NULL}; + + if (!buf) + return len; + + buf_orig = kstrdup(buf, GFP_KERNEL); + /* printk(KERN_INFO "input cmd : %s",buf_orig); */ + devp = dev_get_drvdata(dev); + if (devp->task_running == 0) { + len += sprintf((char *)buf + len, "vm does not start\n"); + return len; + } + + ps = buf_orig; + while (1) { + if (n >= ARRAY_SIZE(parm)) { + pr_err("parm array overflow.\n"); +#if 0 + pr_err("n=%d,ARRAY_SIZE(parm)=%d\n", + n, ARRAY_SIZE(parm)); +#endif + return len; + } + token = strsep(&ps, "\n"); + if (token == NULL) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } + + if (strcmp(parm[0], "before") == 0) { + devp->dump = 1; + devp->dump_path = parm[1]; + pr_debug("this not support\n"); + } else if (strcmp(parm[0], "after") == 0) { + devp->dump = 2; + devp->dump_path = parm[1]; + pr_debug("after ge2d processed, store to %s\n", parm[1]); + } + + kfree(buf_orig); + return len; +} + +static DEVICE_ATTR(dump, 0664, vm_attr_show, vm_attr_store); + +static int vm_add_cdev(struct cdev *cdevp, + const struct file_operations *fops, + int minor) +{ + int ret; + dev_t devno = MKDEV(MAJOR(vm_devno), minor); + + cdev_init(cdevp, fops); + cdevp->owner = THIS_MODULE; + ret = cdev_add(cdevp, devno, 1); + return ret; +} + +int init_vm_device(struct vm_device_s *vdevp, struct platform_device *pdev) +{ + int ret = 0; + + ret = vm_add_cdev(&vdevp->cdev, &vm_fops, vdevp->index); + if (ret) { + pr_err("%s: failed to add cdev. !\n", __func__); + goto fail_add_cdev; + } + vdevp->dev = device_create(vm_clsp, &pdev->dev, MKDEV(MAJOR(vm_devno), + vdevp->index), + NULL, "%s%d", VM_DEV_NAME, vdevp->index); + if (IS_ERR(vdevp->dev)) { + pr_err("%s: failed to create device. !\n", __func__); + ret = PTR_ERR(vdevp->dev); + goto fail_create_device; + } + ret = device_create_file(vdevp->dev, &dev_attr_dump); + if (ret < 0) { + pr_err("%s: fail to create vdin attribute files.\n", __func__); + goto fail_create_dev_file; + } + + dev_set_drvdata(vdevp->dev, vdevp); + platform_set_drvdata(pdev, vdevp); + + /* if (vm_buffer_init(vdevp) < 0) */ + /* goto unregister_dev; */ +#ifndef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER + vf_provider_init(&vm_vf_prov, PROVIDER_NAME, &vm_vf_provider, NULL); +#endif + /* vf_reg_provider(&vm_vf_prov); */ + vdevp->task = NULL; + vdevp->task_running = 0; + memset(&vdevp->output_para, 0, sizeof(struct vm_output_para)); + sprintf(vdevp->name, "%s%d", RECEIVER_NAME, vdevp->index); + sprintf(vdevp->vf_provider_name, "%s%d", "vdin", vdevp->index); + + snprintf(vdevp->vfm_map_chain, VM_MAP_NAME_SIZE, + "%s %s", vdevp->vf_provider_name, + vdevp->name); + snprintf(vdevp->vfm_map_id, VM_MAP_NAME_SIZE, + "vm-map-%d", vdevp->index); + if (vfm_map_add(vdevp->vfm_map_id, + vdevp->vfm_map_chain) < 0) { + pr_err("vm pipeline map creation failed %s.\n", + vdevp->vfm_map_id); + goto fail_create_dev_file; + } + + vf_receiver_init(&vdevp->vm_vf_recv, vdevp->name, + &vm_vf_receiver, vdevp); + + vf_reg_receiver(&vdevp->vm_vf_recv); + return 0; + + /* unregister_dev: */ +fail_create_dev_file: + device_destroy(vm_clsp, MKDEV(MAJOR(vm_devno), vdevp->index)); +fail_create_device: + cdev_del(&vdevp->cdev); +fail_add_cdev: + kfree(vdevp); + return ret; + +} + +int uninit_vm_device(struct platform_device *plat_dev) +{ + struct vm_device_s *vdevp; + + vdevp = platform_get_drvdata(plat_dev); + /* stop_vm_task(vdevp); */ + device_remove_file(vdevp->dev, &dev_attr_dump); + device_destroy(vm_clsp, MKDEV(MAJOR(vm_devno), vdevp->index)); + cdev_del(&vdevp->cdev); + vm_device[vdevp->index] = NULL; + + /* free drvdata */ + dev_set_drvdata(vdevp->dev, NULL); + platform_set_drvdata(plat_dev, NULL); + kfree(vdevp); + return 0; +} + +int vm_init_resource(size_t size, struct vm_init_s *info) +{ + struct vm_device_s *devp; +#ifdef CONFIG_CMA + devp = vm_device[info->vdin_id]; + if (size == 0) + return -1; + if (info->vm_pages && info->vm_buf_size != 0) { + + dma_release_from_contiguous(&devp->pdev->dev, + info->vm_pages, + info->vm_buf_size / PAGE_SIZE); + } + info->vm_pages = dma_alloc_from_contiguous(&devp->pdev->dev, + size / PAGE_SIZE, 0); + if (info->vm_pages) { + dma_addr_t phys; + + phys = page_to_phys(info->vm_pages); + info->buffer_start = phys; + info->vm_buf_size = size; + if (info->bt_path_count == 1) { + if (info->vdin_id == 0) + info->isused = true; + else + info->isused = false; + } else { + info->isused = true; + } + info->mem_alloc_succeed = true; + return 0; + } + + info->mem_alloc_succeed = false; + pr_err("CMA failed to allocate dma buffer\n"); + return -ENOMEM; +#else + if (size == 0) + return -1; + info->buffer_start = vm_device[info->vdin_id]->buffer_start; + info->vm_buf_size = vm_device[info->vdin_id]->buffer_size; + info->mem_alloc_succeed = true; + info->isused = true; + return 0; +#endif +} +EXPORT_SYMBOL(vm_init_resource); + +void vm_deinit_resource(struct vm_init_s *info) +{ +#ifdef CONFIG_CMA + struct vm_device_s *devp; + + devp = vm_device[info->vdin_id]; + if (info->vm_buf_size == 0) { + pr_warn("vm buf size equals 0\n"); + return; + } + unset_vm_buf_res(info); + + if (info->vm_pages) { + dma_release_from_contiguous(&devp->pdev->dev, + info->vm_pages, + info->vm_buf_size / PAGE_SIZE); + info->vm_buf_size = 0; + info->vm_pages = NULL; + info->isused = false; + info->mem_alloc_succeed = false; + } +#else + if (info->vm_buf_size) { + info->buffer_start = 0; + info->vm_buf_size = 0; + info->isused = false; + info->mem_alloc_succeed = false; + } +#endif +} +EXPORT_SYMBOL(vm_deinit_resource); + + +/******************************************************************* + * + * interface for Linux driver + * + * ******************************************************************/ + +static int vm_mem_device_init(struct reserved_mem *rmem, struct device *dev) +{ + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); + struct vm_device_s *vdevp = platform_get_drvdata(pdev); + unsigned long mem_start, mem_end; + + vdevp->buffer_start = rmem->base; + vdevp->buffer_size = rmem->size; + mem_start = rmem->base; + mem_end = rmem->base + rmem->size - 1; + pr_info("init vm memsource %lx->%lx\n", mem_start, mem_end); + return 0; +} + +static const struct reserved_mem_ops rmem_vm_ops = { + .device_init = vm_mem_device_init, +}; + +static int __init vm_mem_setup(struct reserved_mem *rmem) +{ + rmem->ops = &rmem_vm_ops; + pr_info("vm share mem setup\n"); + return 0; +} + +/* MODULE_AMLOG(AMLOG_DEFAULT_LEVEL, 0xff, LOG_LEVEL_DESC, LOG_MASK_DESC); */ + + +/* for driver. */ +static int vm_driver_probe(struct platform_device *pdev) +{ + int idx; + int ret; + struct vm_device_s *vdevp; + + pr_info("vm memory init\n"); + /* malloc vdev */ + vdevp = kmalloc(sizeof(struct vm_device_s), GFP_KERNEL); + if (!vdevp) + return -ENOMEM; + + memset(vdevp, 0, sizeof(struct vm_device_s)); + + if (pdev->dev.of_node) { + ret = of_property_read_u32(pdev->dev.of_node, + "vm_id", &(vdevp->index)); + if (ret) + pr_err("don't find vm id.\n"); + } + vm_device[vdevp->index] = vdevp; + vdevp->pdev = pdev; + platform_set_drvdata(pdev, vdevp); + ret = alloc_vm_canvas(vdevp); + if (ret != 0) { + pr_err("alloc vm canvas failed\n"); + return ret; + } + vm_buffer_init(vdevp); + ret = init_vm_device(vdevp, pdev); + if (ret != 0) + return ret; + idx = of_reserved_mem_device_init(&pdev->dev); + if (idx == 0) + pr_info("vm probe done\n"); + else + pr_info("malloc reserved memory failed !\n"); + + /* init_vm_device(vdevp, pdev); */ + return 0; +} + +static int vm_drv_remove(struct platform_device *plat_dev) +{ + int i; + struct vm_device_s *vdevp; + + vdevp = platform_get_drvdata(plat_dev); + + for (i = 0; i < MAX_CANVAS_INDEX; i++) { + if ((vdevp != NULL) && + (vdevp->vm_canvas[i] >= 0)) { + canvas_pool_map_free_canvas( + vdevp->vm_canvas[i]); + memset(&(vdevp->vm_canvas[i]), + -1, sizeof(int)); + } + } + + if (vdevp->vfm_map_id[0]) { + vfm_map_remove(vdevp->vfm_map_id); + vdevp->vfm_map_id[0] = 0; + } + + uninit_vm_device(plat_dev); + return 0; +} + +static const struct of_device_id amlogic_vm_dt_match[] = { + { + .compatible = "amlogic, vm", + }, + {}, +}; + +/* general interface for a linux driver .*/ +static struct platform_driver vm_drv = { + .probe = vm_driver_probe, + .remove = vm_drv_remove, + .driver = { + .name = "vm", + .owner = THIS_MODULE, + .of_match_table = amlogic_vm_dt_match, + } +}; + +static int __init +vm_init_module(void) +{ + int ret = 0; + + pr_info("vm_init .\n"); + ret = alloc_chrdev_region(&vm_devno, 0, VM_MAX_DEVS, VM_DEV_NAME); + if (ret < 0) { + pr_err("%s: failed to allocate major number\n", __func__); + goto fail_alloc_cdev_region; + } + vm_clsp = class_create(THIS_MODULE, VM_CLS_NAME); + if (IS_ERR(vm_clsp)) { + ret = PTR_ERR(vm_clsp); + pr_err("%s: failed to create class\n", __func__); + goto fail_class_create; + } + ret = platform_driver_register(&vm_drv); + if (ret) { + pr_err("Failed to register vm driver (error=%d\n", + ret); + goto fail_pdrv_register; + } + return 0; + +fail_pdrv_register: + class_destroy(vm_clsp); +fail_class_create: + unregister_chrdev_region(vm_devno, VM_MAX_DEVS); +fail_alloc_cdev_region: + return ret; +} + +static void __exit +vm_remove_module(void) +{ + /* class_remove_file(vm_clsp, &class_attr_dump); */ + class_destroy(vm_clsp); + unregister_chrdev_region(vm_devno, VM_MAX_DEVS); + platform_driver_unregister(&vm_drv); + pr_info("vm module removed.\n"); +} + +module_init(vm_init_module); +module_exit(vm_remove_module); +RESERVEDMEM_OF_DECLARE(vm, "amlogic, vm_memory", vm_mem_setup); + +MODULE_DESCRIPTION("Amlogic Video Input Manager"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Simon Zheng "); diff --git a/drivers/amlogic/media/camera/common/vm.h b/drivers/amlogic/media/camera/common/vm.h new file mode 100644 index 000000000000..9c297e25da7f --- /dev/null +++ b/drivers/amlogic/media/camera/common/vm.h @@ -0,0 +1,140 @@ +/* + * drivers/amlogic/media/camera/common/vm.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _VM_INCLUDE__ +#define _VM_INCLUDE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************* + ** + ** macro define + ** + *************************************/ + +#define VM_IOC_MAGIC 'P' +#define VM_IOC_2OSD0 _IOW(VM_IOC_MAGIC, 0x00, unsigned int) +#define VM_IOC_ENABLE_PP _IOW(VM_IOC_MAGIC, 0X01, unsigned int) +#define VM_IOC_CONFIG_FRAME _IOW(VM_IOC_MAGIC, 0X02, unsigned int) +#define MAX_CANVAS_INDEX 12 + +#define VM_MAP_NAME_SIZE 100 +#define VM_PROVIDER_NAME_SIZE 10 + +struct vm_device_s { + unsigned int index; + char name[20]; + struct platform_device *pdev; + int dump; + char *dump_path; + unsigned int open_count; + int major; + unsigned int dbg_enable; + /* struct class *cla; */ + struct cdev cdev; + struct device *dev; + resource_size_t buffer_start; + unsigned int buffer_size; +#ifdef CONFIG_CMA + ulong cma_pool_size; +#endif + struct vframe_receiver_s vm_vf_recv; + struct task_struct *task; + wait_queue_head_t frame_ready; + int task_running; + int vm_skip_count; + int test_zoom; + struct vm_output_para output_para; + struct completion vb_start_sema; + struct completion vb_done_sema; + char vf_provider_name[VM_PROVIDER_NAME_SIZE]; + char vfm_map_id[VM_MAP_NAME_SIZE]; + char vfm_map_chain[VM_MAP_NAME_SIZE]; + int vm_canvas[MAX_CANVAS_INDEX]; +}; + +struct display_frame_s { + int frame_top; + int frame_left; + int frame_width; + int frame_height; + int content_top; + int content_left; + int content_width; + int content_height; +}; + +int start_vm_task(struct vm_device_s *vdevp); +int start_simulate_task(void); +int alloc_vm_canvas(struct vm_device_s *vdevp); + +extern int get_vm_status(void); +extern void set_vm_status(int flag); + +/* for vm device op. */ +extern int init_vm_device(struct vm_device_s *vdevp, + struct platform_device *pdev); +extern int uninit_vm_device(struct platform_device *plat_dev); + +/* for vm device class op. */ +extern struct class *init_vm_cls(void); + +/* for thread of vm. */ +extern int start_vpp_task(void); +extern void stop_vpp_task(void); + +/* for vm private member. */ +extern void set_vm_buf_info(resource_size_t start, unsigned int size); +extern void get_vm_buf_info(resource_size_t *start, unsigned int *size, + struct io_mapping **mapping); + +/* vm buffer op. */ +extern int vm_buffer_init(struct vm_device_s *vdevp); +extern void vm_local_init(void); + +extern void vm_deinit_resource(struct vm_init_s *info); + +static DEFINE_MUTEX(vm_mutex); + +/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TV */ +#if 1 +#define CANVAS_WIDTH_ALIGN 32 +#else +#define CANVAS_WIDTH_ALIGN 8 +#endif + +#define MAGIC_SG_MEM 0x17890714 +#define MAGIC_DC_MEM 0x0733ac61 +#define MAGIC_VMAL_MEM 0x18221223 +#define MAGIC_RE_MEM 0x123039dc + +#endif /* _VM_INCLUDE__ */ diff --git a/drivers/amlogic/media/camera/common/vm_log.h b/drivers/amlogic/media/camera/common/vm_log.h new file mode 100644 index 000000000000..4733cad79af5 --- /dev/null +++ b/drivers/amlogic/media/camera/common/vm_log.h @@ -0,0 +1,44 @@ +/* + * drivers/amlogic/media/camera/common/vm_log.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef VM_LOG_H +#define VM_LOG_H + +#define DEBUG +#ifdef DEBUG +#define AMLOG 1 +#define LOG_LEVEL_VAR amlog_level_ppmgr +#define LOG_MASK_VAR amlog_mask_ppmgr +#endif + +#define LOG_LEVEL_HIGH 0x00f +#define LOG_LEVEL_1 0x001 +#define LOG_LEVEL_LOW 0x000 + +#define LOG_LEVEL_DESC \ +"[0x00]LOW[0X01]LEVEL1[0xf]HIGH" + +#define LOG_MASK_INIT 0x001 +#define LOG_MASK_IOCTL 0x002 +#define LOG_MASK_HARDWARE 0x004 +#define LOG_MASK_CONFIG 0x008 +#define LOG_MASK_WORK 0x010 +#define LOG_MASK_DESC \ +"[0x01]:INIT,[0x02]:IOCTL,[0x04]:HARDWARE,[0x08]LOG_MASK_CONFIG[0x10]LOG_MASK_WORK" + +#endif + diff --git a/drivers/amlogic/media/camera/common/vmcls.h b/drivers/amlogic/media/camera/common/vmcls.h new file mode 100644 index 000000000000..3e81c379225a --- /dev/null +++ b/drivers/amlogic/media/camera/common/vmcls.h @@ -0,0 +1,189 @@ +/* + * drivers/amlogic/media/camera/common/vmcls.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#define VM_CLASS_NAME "vm" + +extern void interleave_uv(unsigned char *pU, unsigned char *pV, + unsigned char *pUV, unsigned int size_u_or_v); + +static ssize_t show_vm_info(struct class *cla, struct class_attribute *attr, + char *buf) +{ +#if 0 + resource_size_t bstart; + unsigned int bsize; + + get_vm_buf_info(&bstart, &bsize, NULL); + return snprintf(buf, 80, "buffer:\n start:%x.\tsize:%d\n", + (unsigned int)bstart, bsize / (1024 * 1024)); +#endif + return 0; +} + +static char attr_dat0[3] = "-1"; +static ssize_t read_attr0(struct class *cla, struct class_attribute *attr, + char *buf) +{ + return snprintf(buf, 3, "%s", attr_dat0); +} + +static ssize_t write_attr0(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + /* struct display_device *dsp = dev_get_drvdata(dev); */ + ssize_t ret = -EINVAL; + + if (count <= 2) { + int i = 0; + + if (buf[0] == '-') { + attr_dat0[0] = '-'; + i = 1; + ret++; + } + if ((buf[i] >= '0') && (buf[i] <= '9')) { + attr_dat0[i] = buf[i]; + attr_dat0[i + 1] = '\0'; + ret++; + } else { + attr_dat0[0] = '-'; + attr_dat0[1] = '1'; /* default -1; */ + ret = -EINVAL; + } + } + + return ret; +} + +static char attr_dat1[3] = "-1"; +static ssize_t read_attr1(struct class *cla, struct class_attribute *attr, + char *buf) +{ + return snprintf(buf, 3, "%s", attr_dat1); +} + +static ssize_t write_attr1(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + /* struct display_device *dsp = dev_get_drvdata(dev); */ + ssize_t ret = -EINVAL; + + if (count <= 2) { + int i = 0; + + if (buf[0] == '-') { + attr_dat1[0] = '-'; + i = 1; + ret++; + } + if ((buf[i] >= '0') && (buf[i] <= '9')) { + attr_dat1[i] = buf[i]; + attr_dat1[i + 1] = '\0'; + ret++; + } else { + attr_dat1[0] = '-'; + attr_dat1[1] = '1'; /* default -1; */ + ret = -EINVAL; + } + } + + return ret; +} +int disable_gt2005; + +static ssize_t read_attr2(struct class *cla, struct class_attribute *attr, + char *buf) +{ + return disable_gt2005; +} + +static ssize_t write_attr2(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + /* struct display_device *dsp = dev_get_drvdata(dev); */ + ssize_t ret = -EINVAL; + + if (count <= 2) + disable_gt2005 = buf[0]; + + return ret; +} + +int camera_mirror_flag; /* 0: disable, 1: l&r mirror,2 t-b mirror */ + +static ssize_t mirror_read(struct class *cla, struct class_attribute *attr, + char *buf) +{ + if (camera_mirror_flag == 1) + return snprintf(buf, 80, + "currnet mirror mode is l-r mirror mode. value is: %d.\n", + camera_mirror_flag); + else if (camera_mirror_flag == 2) + return snprintf(buf, 80, + "currnet mirror mode is t-b mirror mode. value is: %d.\n", + camera_mirror_flag); + else + return snprintf(buf, 80, + "currnet mirror mode is normal mode. value is: %d.\n", + camera_mirror_flag); +} + +static ssize_t mirror_write(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + ssize_t size; + char *endp = "1"; + + camera_mirror_flag = kstrtoul(buf, 0, (unsigned long *)endp); + size = endp - buf; + return count; +} + +static struct class_attribute vm_class_attrs[] = { + __ATTR(info, 0644, + show_vm_info, NULL), + __ATTR(attr0, 0644, + read_attr0, write_attr0), + __ATTR(attr1, 0644, + read_attr1, write_attr1), + __ATTR(attr2, 0644, + read_attr2, write_attr2), + __ATTR(mirror, 0644, + mirror_read, mirror_write), + __ATTR_NULL +}; + +static struct class vm_class = { + .name = VM_CLASS_NAME, + .class_attrs = vm_class_attrs, + }; + +struct class *init_vm_cls() + { + int ret = 0; + + ret = class_register(&vm_class); + if (ret < 0) { + pr_err("error create vm class\n"); + return NULL; + } + return &vm_class; + } diff --git a/drivers/amlogic/media/camera/gc2145.c b/drivers/amlogic/media/camera/gc2145.c new file mode 100644 index 000000000000..b194a8577078 --- /dev/null +++ b/drivers/amlogic/media/camera/gc2145.c @@ -0,0 +1,3455 @@ +/* + * drivers/amlogic/media/camera/gc2145.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_WAKELOCK +#include +#endif +#include +#include +#include +#include +#include +#include "common/plat_ctrl.h" +#include +#include +#include +#include "common/vm.h" + +#define GC2145_CAMERA_MODULE_NAME "gc2145" + +/* Wake up at about 30 fps */ +#define WAKE_NUMERATOR 30 +#define WAKE_DENOMINATOR 1001 +#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ + +#define MAGIC_RE_MEM 0x123039dc +#define CAMERA_USER_CANVAS_INDEX 0x4e + +#define GC2145_CAMERA_MAJOR_VERSION 0 +#define GC2145_CAMERA_MINOR_VERSION 7 +#define GC2145_CAMERA_RELEASE 0 +#define GC2145_CAMERA_VERSION \ + KERNEL_VERSION(GC2145_CAMERA_MAJOR_VERSION, \ + GC2145_CAMERA_MINOR_VERSION, \ + GC2145_CAMERA_RELEASE) + +#define GC2145_DRIVER_VERSION "GC2145-COMMON-01-140722" + +/*unsigned short DGain_shutter,AGain_shutter,*/ +/*DGain_shutterH,DGain_shutterL,AGain_shutterH,*/ +/*AGain_shutterL,shutterH,shutterL,shutter;*/ +/*unsigned short UXGA_Cap = 0;*/ + +static struct i2c_client *g_i2c_client; +static u32 cur_reg; +static u8 cur_val; +static u8 is_first_time_open; + +enum DCAMERA_FLICKER { + + DCAMERA_FLICKER_50HZ = 0, + + DCAMERA_FLICKER_60HZ, + + FLICKER_MAX + +}; + +/*static unsigned short Antiflicker = DCAMERA_FLICKER_50HZ;*/ + +#define GC2145_NORMAL_Y0ffset 0x08 +#define GC2145_LOWLIGHT_Y0ffset 0x20 + +MODULE_DESCRIPTION("gc2145 On Board"); +MODULE_AUTHOR("amlogic-sh"); +MODULE_LICENSE("GPL v2"); + +static unsigned int video_nr = -1; /* videoX start number, -1 is autodetect. */ + +static unsigned int debug; +/* module_param(debug, uint, 0644); */ +/* MODULE_PARM_DESC(debug, "activates debug info"); */ + +static unsigned int vid_limit = 16; +/* module_param(vid_limit, uint, 0644); */ +/* MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); */ + +//static int vidio_set_fmt_ticks; + +static int GC2145_h_active = 640; /* 800; */ +static int GC2145_v_active = 480; /* 600; */ + +static int gc2145_have_open; + +static struct v4l2_fract gc2145_frmintervals_active = { + .numerator = 1, + .denominator = 15, +}; + +static int gc2145_night_or_normal; /* add by sp_yjp,20120905 */ +static struct vdin_v4l2_ops_s *vops; +/* supported controls */ +static struct v4l2_queryctrl gc2145_qctrl[] = { + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "white balance", + .minimum = CAM_WB_AUTO, + .maximum = CAM_WB_FLUORESCENT, + .step = 0x1, + .default_value = CAM_WB_AUTO, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = 0, + .maximum = 8, + .step = 0x1, + .default_value = 4, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_COLORFX, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "effect", + .minimum = 0, + .maximum = 6, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "banding", + .minimum = CAM_BANDING_50HZ, + .maximum = CAM_BANDING_60HZ, + .step = 0x1, + .default_value = CAM_BANDING_50HZ, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "scene mode", + .minimum = 0, + .maximum = 1, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "flip on horizontal", + .minimum = 0, + .maximum = 1, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "flip on vertical", + .minimum = 0, + .maximum = 1, + .step = 0x1, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Zoom, Absolute", + .minimum = 100, + .maximum = 300, + .step = 20, + .default_value = 100, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_ROTATE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Rotate", + .minimum = 0, + .maximum = 270, + .step = 90, + .default_value = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, + } +}; +struct v4l2_querymenu gc2145_qmenu_wbmode[] = { + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_AUTO, + .name = "auto", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_CLOUD, + .name = "cloudy-daylight", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_INCANDESCENCE, + .name = "incandescent", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_DAYLIGHT, + .name = "daylight", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_FLUORESCENT, + .name = "fluorescent", + .reserved = 0, + }, { + .id = V4L2_CID_DO_WHITE_BALANCE, + .index = CAM_WB_WARM_FLUORESCENT, + .name = "warm-fluorescent", + .reserved = 0, + }, +}; + +struct v4l2_querymenu gc2145_qmenu_anti_banding_mode[] = { + { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .index = CAM_BANDING_50HZ, + .name = "50hz", + .reserved = 0, + }, { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .index = CAM_BANDING_60HZ, + .name = "60hz", + .reserved = 0, + }, +}; +static struct v4l2_frmivalenum gc2145_frmivalenum[] = { + { + .index = 0, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 352, + .height = 288, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 30,/* 15 */ + } + } + }, { + .index = 0, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 640, + .height = 480, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 30,/* 15 */ + } + } + }, { + .index = 1, + .pixel_format = V4L2_PIX_FMT_NV21, + .width = 1600, + .height = 1200, + .type = V4L2_FRMIVAL_TYPE_DISCRETE, + { + .discrete = { + .numerator = 1, + .denominator = 5, + } + } + }, +}; + + +struct gc2145_qmenu_set_s { + __u32 id; + int num; + struct v4l2_querymenu *gc2145_qmenu; +}; + +struct gc2145_qmenu_set_s gc2145_qmenu_set[] = { + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .num = ARRAY_SIZE(gc2145_qmenu_wbmode), + .gc2145_qmenu = gc2145_qmenu_wbmode, + }, { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .num = ARRAY_SIZE(gc2145_qmenu_anti_banding_mode), + .gc2145_qmenu = gc2145_qmenu_anti_banding_mode, + }, +}; + +static int vidioc_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *a) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(gc2145_qmenu_set); i++) { + if (a->id && a->id == gc2145_qmenu_set[i].id) { + for (j = 0; j < gc2145_qmenu_set[i].num; j++) { + if (a->index == + gc2145_qmenu_set[i].gc2145_qmenu[j].index) { + memcpy(a, + &(gc2145_qmenu_set[i].gc2145_qmenu[j]), + sizeof(*a)); + return 0; + } + } + } + } + return -EINVAL; +} + +#define dprintk(dev, level, fmt, arg...) \ + v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) + +/* + * ------------------------------------------------------------------ + * Basic structures + * ------------------------------------------------------------------ + */ + +struct gc2145_fmt { + char *name; + u32 fourcc; /* v4l2 format id */ + int depth; +}; + +static struct gc2145_fmt formats[] = { + { + .name = "RGB565 (BE)", + .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ + .depth = 16, + }, { + .name = "RGB888 (24)", + .fourcc = V4L2_PIX_FMT_RGB24, /* 24 RGB-8-8-8 */ + .depth = 24, + }, { + .name = "BGR888 (24)", + .fourcc = V4L2_PIX_FMT_BGR24, /* 24 BGR-8-8-8 */ + .depth = 24, + }, { + .name = "12 Y/CbCr 4:2:0", + .fourcc = V4L2_PIX_FMT_NV12, + .depth = 12, + }, { + .name = "12 Y/CbCr 4:2:0", + .fourcc = V4L2_PIX_FMT_NV21, + .depth = 12, + }, { + .name = "YUV420P", + .fourcc = V4L2_PIX_FMT_YUV420, + .depth = 12, + }, { + .name = "YVU420P", + .fourcc = V4L2_PIX_FMT_YVU420, + .depth = 12, + } +}; + +static struct gc2145_fmt *get_format(struct v4l2_format *f) +{ + struct gc2145_fmt *fmt; + unsigned int k; + + for (k = 0; k < ARRAY_SIZE(formats); k++) { + fmt = &formats[k]; + if (fmt->fourcc == f->fmt.pix.pixelformat) + break; + } + + if (k == ARRAY_SIZE(formats)) + return NULL; + + return &formats[k]; +} + +struct sg_to_addr { + int pos; + struct scatterlist *sg; +}; + +/* buffer for one video frame */ +struct gc2145_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + struct gc2145_fmt *fmt; + + unsigned int canvas_id; +}; + +struct gc2145_dmaqueue { + struct list_head active; + + /* thread for generating video stream*/ + struct task_struct *kthread; + wait_queue_head_t wq; + /* Counters to control fps rate */ + int frame; + int ini_jiffies; +}; + +static LIST_HEAD(gc2145_devicelist); + +struct gc2145_device { + struct list_head gc2145_devicelist; + struct v4l2_subdev sd; + struct v4l2_device v4l2_dev; + + spinlock_t slock; + struct mutex mutex; + + int users; + + /* various device info */ + struct video_device *vdev; + + struct gc2145_dmaqueue vidq; + + /* Several counters */ + unsigned long jiffies; + + /* Input Number */ + int input; + + /* platform device data from board initting. */ + struct aml_cam_info_s cam_info; + +#ifdef CONFIG_HAS_WAKELOCK + /* wake lock */ + struct wake_lock wake_lock; +#endif + + /* Control 'registers' */ + int qctl_regs[ARRAY_SIZE(gc2145_qctrl)]; + struct vm_init_s vminfo; +}; + +static inline struct gc2145_device *to_dev(struct v4l2_subdev *sd) +{ + return container_of(sd, struct gc2145_device, sd); +} + +struct gc2145_fh { + struct gc2145_device *dev; + + /* video capture */ + struct gc2145_fmt *fmt; + unsigned int width, height; + struct videobuf_queue vb_vidq; + + struct videobuf_res_privdata res; + enum v4l2_buf_type type; + int input; /* Input Number on bars */ + int stream_on; + unsigned int f_flags; +}; + +/* + *static inline struct gc2145_fh *to_fh(struct gc2145_device *dev) + *{ + * return container_of(dev, struct gc2145_fh, dev); + *} + */ + +static struct v4l2_frmsize_discrete + gc2145_prev_resolution[] = { + /* should include 352x288 and 640x480,*/ + /*those two size are used for recording*/ + {352, 288}, + {640, 480}, +}; + +static struct v4l2_frmsize_discrete gc2145_pic_resolution[] = { + {1600, 1200}, + {800, 600}, + {640, 480} +}; + +#ifndef GC2145_MIRROR +#define GC2145_MIRROR 0 +#endif +#ifndef GC2145_FLIP +#define GC2145_FLIP 0 +#endif + +/* + *------------------------------------------------------------------ + * reg spec of GC2145 + * ------------------------------------------------------------------ + */ + +struct aml_camera_i2c_fig_s GC2145_script[] = { + /*SENSORDB("GC2145_Sensor_Init"}*/ + {0xfe, 0xf0}, + {0xfe, 0xf0}, + {0xfe, 0xf0}, + {0xfc, 0x06}, + {0xf6, 0x00}, + {0xf7, 0x1d}, + {0xf8, 0x84}, + {0xfa, 0x00}, + {0xf9, 0xfe}, + {0xf2, 0x00}, + /*ISP reg*/ + {0xfe, 0x00}, + {0x03, 0x04}, + {0x04, 0xe2}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x04}, + {0x0e, 0xc0}, + {0x0f, 0x06}, + {0x10, 0x52}, + {0x12, 0x2e}, + {0x17, 0x14}, /*mirror*/ + {0x18, 0x22}, + {0x19, 0x0e}, + {0x1a, 0x01}, + {0x1b, 0x4b}, + {0x1c, 0x07}, + {0x1d, 0x10}, + {0x1e, 0x88}, + {0x1f, 0x78}, + {0x20, 0x03}, + {0x21, 0x40}, + {0x22, 0xa0}, + {0x24, 0x16}, + {0x25, 0x01}, + {0x26, 0x10}, + {0x2d, 0x60}, + {0x30, 0x01}, + {0x31, 0x90}, + {0x33, 0x06}, + {0x34, 0x01}, + /*ISP reg*/ + {0xfe, 0x00}, + {0x80, 0x7f}, + {0x81, 0x26}, + {0x82, 0xfa}, + {0x83, 0x00}, + {0x84, 0x02}, + {0x86, 0x01},/*0x03*/ + {0x88, 0x03}, + {0x89, 0x03}, + {0x85, 0x08}, + {0x8a, 0x00}, + {0x8b, 0x00}, + {0xb0, 0x55}, + {0xc3, 0x00}, + {0xc4, 0x80}, + {0xc5, 0x90}, + {0xc6, 0x3b}, + {0xc7, 0x46}, + {0xec, 0x06}, + {0xed, 0x04}, + {0xee, 0x60}, + {0xef, 0x90}, + {0xb6, 0x01}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x04}, + {0x96, 0xb0}, + {0x97, 0x06}, + {0x98, 0x40}, + /*BLK*/ + {0xfe, 0x00}, + {0x40, 0x42}, + {0x41, 0x00}, + {0x43, 0x5b}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x20}, + {0x67, 0x20}, + {0x68, 0x20}, + {0x69, 0x20}, + {0x76, 0x00}, + {0x6a, 0x08}, + {0x6b, 0x08}, + {0x6c, 0x08}, + {0x6d, 0x08}, + {0x6e, 0x08}, + {0x6f, 0x08}, + {0x70, 0x08}, + {0x71, 0x08}, + {0x76, 0x00}, + {0x72, 0xf0}, + {0x7e, 0x3c}, + {0x7f, 0x00}, + {0xfe, 0x02}, + {0x48, 0x15}, + {0x49, 0x00}, + {0x4b, 0x0b}, + {0xfe, 0x00}, + /*AEC*/ + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0xc0}, + {0x03, 0x04}, + {0x04, 0x90}, + {0x05, 0x30}, + {0x06, 0x90}, + {0x07, 0x30}, + {0x08, 0x80}, + {0x09, 0x00}, + {0x0a, 0x82}, + {0x0b, 0x11}, + {0x0c, 0x10}, + {0x11, 0x10}, + {0x13, 0x7b}, + {0x17, 0x00}, + {0x1c, 0x11}, + {0x1e, 0x61}, + {0x1f, 0x35}, + {0x20, 0x40}, + {0x22, 0x40}, + {0x23, 0x20}, + {0xfe, 0x02}, + {0x0f, 0x04}, + {0xfe, 0x01}, + {0x12, 0x35}, + {0x15, 0xb0}, + {0x10, 0x31}, + {0x3e, 0x28}, + {0x3f, 0xb0}, + {0x40, 0x90}, + {0x41, 0x0f}, + /*INTPEE*/ + {0xfe, 0x02}, + {0x90, 0x6c}, + {0x91, 0x03}, + {0x92, 0xcb}, + {0x94, 0x33}, + {0x95, 0x84}, + {0x97, 0x65}, + {0xa2, 0x11}, + {0xfe, 0x00}, + /*DNDD*/ + {0xfe, 0x02}, + {0x80, 0xc1}, + {0x81, 0x08}, + {0x82, 0x05}, + {0x83, 0x08}, + {0x84, 0x0a}, + {0x86, 0xf0}, + {0x87, 0x50}, + {0x88, 0x15}, + {0x89, 0xb0}, + {0x8a, 0x30}, + {0x8b, 0x10}, + /*ASDE*/ + {0xfe, 0x01}, + {0x21, 0x04}, + {0xfe, 0x02}, + {0xa3, 0x50}, + {0xa4, 0x20}, + {0xa5, 0x40}, + {0xa6, 0x80}, + {0xab, 0x40}, + {0xae, 0x0c}, + {0xb3, 0x46}, + {0xb4, 0x64}, + {0xb6, 0x38}, + {0xb7, 0x01}, + {0xb9, 0x2b}, + {0x3c, 0x04}, + {0x3d, 0x15}, + {0x4b, 0x06}, + {0x4c, 0x20}, + {0xfe, 0x00}, + + /*gamma1*/ +#if 1 + {0xfe, 0x02}, + {0x10, 0x09}, + {0x11, 0x0d}, + {0x12, 0x13}, + {0x13, 0x19}, + {0x14, 0x27}, + {0x15, 0x37}, + {0x16, 0x45}, + {0x17, 0x53}, + {0x18, 0x69}, + {0x19, 0x7d}, + {0x1a, 0x8f}, + {0x1b, 0x9d}, + {0x1c, 0xa9}, + {0x1d, 0xbd}, + {0x1e, 0xcd}, + {0x1f, 0xd9}, + {0x20, 0xe3}, + {0x21, 0xea}, + {0x22, 0xef}, + {0x23, 0xf5}, + {0x24, 0xf9}, + {0x25, 0xff}, +#else + {0xfe, 0x02}, + {0x10, 0x0a}, + {0x11, 0x12}, + {0x12, 0x19}, + {0x13, 0x1f}, + {0x14, 0x2c}, + {0x15, 0x38}, + {0x16, 0x42}, + {0x17, 0x4e}, + {0x18, 0x63}, + {0x19, 0x76}, + {0x1a, 0x87}, + {0x1b, 0x96}, + {0x1c, 0xa2}, + {0x1d, 0xb8}, + {0x1e, 0xcb}, + {0x1f, 0xd8}, + {0x20, 0xe2}, + {0x21, 0xe9}, + {0x22, 0xf0}, + {0x23, 0xf8}, + {0x24, 0xfd}, + {0x25, 0xff}, + {0xfe, 0x00}, +#endif + {0xfe, 0x00}, + {0xc6, 0x20}, + {0xc7, 0x2b}, + /*gamma2*/ +#if 1 + {0xfe, 0x02}, + {0x26, 0x0f}, + {0x27, 0x14}, + {0x28, 0x19}, + {0x29, 0x1e}, + {0x2a, 0x27}, + {0x2b, 0x33}, + {0x2c, 0x3b}, + {0x2d, 0x45}, + {0x2e, 0x59}, + {0x2f, 0x69}, + {0x30, 0x7c}, + {0x31, 0x89}, + {0x32, 0x98}, + {0x33, 0xae}, + {0x34, 0xc0}, + {0x35, 0xcf}, + {0x36, 0xda}, + {0x37, 0xe2}, + {0x38, 0xe9}, + {0x39, 0xf3}, + {0x3a, 0xf9}, + {0x3b, 0xff}, +#else + /*Gamma outdoor*/ + {0xfe, 0x02}, + {0x26, 0x17}, + {0x27, 0x18}, + {0x28, 0x1c}, + {0x29, 0x20}, + {0x2a, 0x28}, + {0x2b, 0x34}, + {0x2c, 0x40}, + {0x2d, 0x49}, + {0x2e, 0x5b}, + {0x2f, 0x6d}, + {0x30, 0x7d}, + {0x31, 0x89}, + {0x32, 0x97}, + {0x33, 0xac}, + {0x34, 0xc0}, + {0x35, 0xcf}, + {0x36, 0xda}, + {0x37, 0xe5}, + {0x38, 0xec}, + {0x39, 0xf8}, + {0x3a, 0xfd}, + {0x3b, 0xff}, +#endif + /*YCP*/ + {0xfe, 0x02}, + {0xd1, 0x32}, + {0xd2, 0x32}, + {0xd3, 0x40}, + {0xd6, 0xf0}, + {0xd7, 0x10}, + {0xd8, 0xda}, + {0xdd, 0x14}, + {0xde, 0x86}, + {0xed, 0x80}, + {0xee, 0x00}, + {0xef, 0x3f}, + {0xd8, 0xd8}, + /*abs*/ + {0xfe, 0x01}, + {0x9f, 0x40}, + /*LSC*/ + {0xfe, 0x01}, + {0xc2, 0x14}, + {0xc3, 0x0d}, + {0xc4, 0x0c}, + {0xc8, 0x15}, + {0xc9, 0x0d}, + {0xca, 0x0a}, + {0xbc, 0x24}, + {0xbd, 0x10}, + {0xbe, 0x0b}, + {0xb6, 0x25}, + {0xb7, 0x16}, + {0xb8, 0x15}, + {0xc5, 0x00}, + {0xc6, 0x00}, + {0xc7, 0x00}, + {0xcb, 0x00}, + {0xcc, 0x00}, + {0xcd, 0x00}, + {0xbf, 0x07}, + {0xc0, 0x00}, + {0xc1, 0x00}, + {0xb9, 0x00}, + {0xba, 0x00}, + {0xbb, 0x00}, + {0xaa, 0x01}, + {0xab, 0x01}, + {0xac, 0x00}, + {0xad, 0x05}, + {0xae, 0x06}, + {0xaf, 0x0e}, + {0xb0, 0x0b}, + {0xb1, 0x07}, + {0xb2, 0x06}, + {0xb3, 0x17}, + {0xb4, 0x0e}, + {0xb5, 0x0e}, + {0xd0, 0x09}, + {0xd1, 0x00}, + {0xd2, 0x00}, + {0xd6, 0x08}, + {0xd7, 0x00}, + {0xd8, 0x00}, + {0xd9, 0x00}, + {0xda, 0x00}, + {0xdb, 0x00}, + {0xd3, 0x0a}, + {0xd4, 0x00}, + {0xd5, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x77}, + {0xa7, 0x77}, + {0xa8, 0x77}, + {0xa9, 0x77}, + {0xa1, 0x80}, + {0xa2, 0x80}, + {0xfe, 0x01}, + {0xdf, 0x0d}, + {0xdc, 0x25}, + {0xdd, 0x30}, + {0xe0, 0x77}, + {0xe1, 0x80}, + {0xe2, 0x77}, + {0xe3, 0x90}, + {0xe6, 0x90}, + {0xe7, 0xa0}, + {0xe8, 0x90}, + {0xe9, 0xa0}, + {0xfe, 0x00}, + /*AWB*/ + {0xfe, 0x01}, + {0x4f, 0x00}, + {0x4f, 0x00}, + {0x4b, 0x01}, + {0x4f, 0x00}, + {0x4c, 0x01}, /*D75*/ + {0x4d, 0x71}, + {0x4e, 0x01}, + {0x4c, 0x01}, + {0x4d, 0x91}, + {0x4e, 0x01}, + {0x4c, 0x01}, + {0x4d, 0x70}, + {0x4e, 0x01}, + {0x4c, 0x01}, /*D65*/ + {0x4d, 0x90}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xb0}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0x8f}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0x6f}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xaf}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xd0}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xf0}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xcf}, + {0x4e, 0x02}, + {0x4c, 0x01}, + {0x4d, 0xef}, + {0x4e, 0x02}, + {0x4c, 0x01},/*D50*/ + {0x4d, 0x6e}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8e}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xae}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xce}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x4d}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x6d}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8d}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xad}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xcd}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x4c}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x6c}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8c}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xac}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xcc}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xcb}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x4b}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x6b}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0x8b}, + {0x4e, 0x03}, + {0x4c, 0x01}, + {0x4d, 0xab}, + {0x4e, 0x03}, + {0x4c, 0x01},/*CWF*/ + {0x4d, 0x8a}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xaa}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xca}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xca}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xc9}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0x8a}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0x89}, + {0x4e, 0x04}, + {0x4c, 0x01}, + {0x4d, 0xa9}, + {0x4e, 0x04}, + {0x4c, 0x02},/*tl84*/ + {0x4d, 0x0b}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x0a}, + {0x4e, 0x05}, + {0x4c, 0x01}, + {0x4d, 0xeb}, + {0x4e, 0x05}, + {0x4c, 0x01}, + {0x4d, 0xea}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x09}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x29}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x2a}, + {0x4e, 0x05}, + {0x4c, 0x02}, + {0x4d, 0x4a}, + {0x4e, 0x05}, + /*{0x4c , 0x02},*/ + /*{0x4d , 0x6a},*/ + /*{0x4e , 0x06},*/ + {0x4c, 0x02}, + {0x4d, 0x8a}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x49}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x69}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x89}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0xa9}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x48}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x68}, + {0x4e, 0x06}, + {0x4c, 0x02}, + {0x4d, 0x69}, + {0x4e, 0x06}, + {0x4c, 0x02},/*H*/ + {0x4d, 0xca}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xc9}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xe9}, + {0x4e, 0x07}, + {0x4c, 0x03}, + {0x4d, 0x09}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xc8}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xe8}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xa7}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xc7}, + {0x4e, 0x07}, + {0x4c, 0x02}, + {0x4d, 0xe7}, + {0x4e, 0x07}, + {0x4c, 0x03}, + {0x4d, 0x07}, + {0x4e, 0x07}, + {0x4f, 0x01}, + {0x50, 0x80}, + {0x51, 0xa8}, + {0x52, 0x47}, + {0x53, 0x38}, + {0x54, 0xc7}, + {0x56, 0x0e}, + {0x58, 0x08}, + {0x5b, 0x00}, + {0x5c, 0x74}, + {0x5d, 0x8b}, + {0x61, 0xdb}, + {0x62, 0xb8}, + {0x63, 0x86}, + {0x64, 0xc0}, + {0x65, 0x04}, + {0x67, 0xa8}, + {0x68, 0xb0}, + {0x69, 0x00}, + {0x6a, 0xa8}, + {0x6b, 0xb0}, + {0x6c, 0xaf}, + {0x6d, 0x8b}, + {0x6e, 0x50}, + {0x6f, 0x18}, + {0x73, 0xf0}, + {0x70, 0x0d}, + {0x71, 0x60}, + {0x72, 0x80}, + {0x74, 0x01}, + {0x75, 0x01}, + {0x7f, 0x0c}, + {0x76, 0x70}, + {0x77, 0x58}, + {0x78, 0xa0}, + {0x79, 0x5e}, + {0x7a, 0x54}, + {0x7b, 0x58}, + {0xfe, 0x00}, + /*CC*/ + {0xfe, 0x02}, + {0xc0, 0x01}, + {0xc1, 0x44}, + {0xc2, 0xfd}, + {0xc3, 0x04}, + {0xc4, 0xF0}, + {0xc5, 0x48}, + {0xc6, 0xfd}, + {0xc7, 0x46}, + {0xc8, 0xfd}, + {0xc9, 0x02}, + {0xca, 0xe0}, + {0xcb, 0x45}, + {0xcc, 0xec}, + {0xcd, 0x48}, + {0xce, 0xf0}, + {0xcf, 0xf0}, + {0xe3, 0x0c}, + {0xe4, 0x4b}, + {0xe5, 0xe0}, + /*ABS*/ + {0xfe, 0x01}, + {0x9f, 0x40}, + {0xfe, 0x00}, + /*OUTPUT*/ + {0xfe, 0x00}, + {0xf2, 0x0f}, + /*dark sun*/ + {0xfe, 0x02}, + {0x40, 0xbf}, + {0x46, 0xcf}, + {0xfe, 0x00}, + /*frame rate 50Hz*/ + {0xfe, 0x00}, + {0x05, 0x01}, + {0x06, 0x56}, + {0x07, 0x00}, + {0x08, 0x32}, + {0xfe, 0x01}, + {0x25, 0x00}, + {0x26, 0xfa}, + {0x27, 0x04}, + {0x28, 0xe2}, /*20fps*/ + {0x29, 0x06}, + {0x2a, 0xd6}, /*14fps*/ + {0x2b, 0x07}, + {0x2c, 0xd0}, /*12fps*/ + {0x2d, 0x0b}, + {0x2e, 0xb8}, /*8fps*/ + {0xfe, 0x00}, + + /*SENSORDB("GC2145_Sensor_SVGA"},*/ + + {0xfe, 0x00}, + {0xfd, 0x01}, + {0xfa, 0x00}, + /*crop window*/ + {0xfe, 0x00}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x02}, + {0x96, 0x58}, + {0x97, 0x03}, + {0x98, 0x20}, + {0x99, 0x11}, + {0x9a, 0x06}, + /*AWB*/ + {0xfe, 0x00}, + {0xec, 0x02}, + {0xed, 0x02}, + {0xee, 0x30}, + {0xef, 0x48}, + {0xfe, 0x02}, + {0x9d, 0x08}, + {0xfe, 0x01}, + {0x74, 0x00}, + /*AEC*/ + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0x60}, + {0x03, 0x02}, + {0x04, 0x48}, + {0x05, 0x18}, + {0x06, 0x50}, + {0x07, 0x10}, + {0x08, 0x38}, + {0x0a, 0x80}, + {0x21, 0x04}, + {0xfe, 0x00}, + {0x20, 0x03}, + {0xfe, 0x00}, + {0xff, 0xff}, +}; + +struct aml_camera_i2c_fig_s gc2145_svga[] = { + {0xfe, 0x00}, + {0xb6, 0x01}, + {0xfd, 0x01}, + {0xfa, 0x11}, + /*crop window*/ + {0xfe, 0x00}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x02}, + {0x96, 0x5a}, + {0x97, 0x03}, + {0x98, 0x22}, + {0x99, 0x11}, + {0x9a, 0x06}, + /*AWB*/ + {0xfe, 0x00}, + {0xec, 0x02}, + {0xed, 0x02}, + {0xee, 0x30}, + {0xef, 0x48}, + {0xfe, 0x02}, + {0x9d, 0x08}, + {0xfe, 0x01}, + {0x74, 0x00}, + /*AEC*/ + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0x60}, + {0x03, 0x02}, + {0x04, 0x48}, + {0x05, 0x18}, + {0x06, 0x50}, + {0x07, 0x10}, + {0x08, 0x38}, + {0x0a, 0x80}, + {0x21, 0x04}, + {0xfe, 0x00}, + {0x20, 0x03}, + {0xfe, 0x00}, + {0xff, 0xff}, +}; + +struct aml_camera_i2c_fig_s gc2145_uxga[] = { + {0xfe, 0x00}, + {0xfd, 0x00}, + {0xfa, 0x11}, + /*crop window*/ + {0xfe, 0x00}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x04}, + {0x96, 0xb2}, + {0x97, 0x06}, + {0x98, 0x42}, + {0x99, 0x11}, + {0x9a, 0x06}, + /*AWB*/ + {0xfe, 0x00}, + {0xec, 0x06}, + {0xed, 0x04}, + {0xee, 0x60}, + {0xef, 0x90}, + {0xfe, 0x01}, + {0x74, 0x01}, + /*AEC*/ + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0xc0}, + {0x03, 0x04}, + {0x04, 0x90}, + {0x05, 0x30}, + {0x06, 0x90}, + {0x07, 0x30}, + {0x08, 0x80}, + {0x0a, 0x82}, + {0xfe, 0x01}, + {0x21, 0x15}, + {0xfe, 0x00}, + {0x20, 0x15}, + {0xfe, 0x00}, + {0xff, 0xff}, +}; + +struct aml_camera_i2c_fig_s gc2145_1280x960[] = { + /*1280X960*/ + {0xfe, 0x00}, + {0xfa, 0x11}, + {0xfd, 0x00}, + {0x1c, 0x05}, + /*crop window*/ + {0xfe, 0x00}, + {0x99, 0x55}, + {0x9a, 0x06}, + {0x9b, 0x00}, + {0x9c, 0x00}, + {0x9d, 0x01}, + {0x9e, 0x23}, + {0x9f, 0x00}, + {0xa0, 0x00}, + {0xa1, 0x01}, + {0xa2, 0x23}, + {0x90, 0x01}, + {0x91, 0x00}, + {0x92, 0x00}, + {0x93, 0x00}, + {0x94, 0x00}, + {0x95, 0x03}, + {0x96, 0xc0}, + {0x97, 0x05}, + {0x98, 0x00}, + + /*AWB*/ + {0xfe, 0x00}, + {0xec, 0x06}, + {0xed, 0x04}, + {0xee, 0x60}, + {0xef, 0x90}, + {0xfe, 0x01}, + {0x74, 0x01}, + /*AEC*/ + {0xfe, 0x01}, + {0x01, 0x04}, + {0x02, 0xc0}, + {0x03, 0x04}, + {0x04, 0x90}, + {0x05, 0x30}, + {0x06, 0x90}, + {0x07, 0x30}, + {0x08, 0x80}, + {0x0a, 0x82}, + {0x21, 0x15}, + {0xfe, 0x00}, + {0x20, 0x15}, + {0xfe, 0x00}, +}; + +struct aml_camera_i2c_fig_s gc2145_FLICKER_50HZ[] = { + {0xfe, 0x00}, + {0x05, 0x01}, + {0x06, 0x56}, + {0x07, 0x00}, + {0x08, 0x32}, + {0xfe, 0x01}, + {0x25, 0x00}, + {0x26, 0xfa}, + {0x27, 0x04}, + {0x28, 0xe2}, /*20fps*/ + {0x29, 0x06}, + {0x2a, 0xd6}, /*14fps*/ + {0x2b, 0x07}, + {0x2c, 0xd0}, /*12fps*/ + {0x2d, 0x0b}, + {0x2e, 0xb8}, /*8fps*/ + {0xfe, 0x00}, + {0xff, 0xff}, +}; +struct aml_camera_i2c_fig_s gc2145_FLICKER_60HZ[] = { + {0x05, 0x01},/*hb*/ + {0x06, 0x58}, + {0x07, 0x00},/*vb*/ + {0x08, 0x32}, + {0xfe, 0x01}, + {0x25, 0x00},/*step*/ + {0x26, 0xd0}, + {0x27, 0x04},/*level1*/ + {0x28, 0xe0}, + {0x29, 0x06},/*level2*/ + {0x2a, 0x80}, + {0x2b, 0x08},/*level3*/ + {0x2c, 0x20}, + {0x2d, 0x0b},/*level4*/ + {0x2e, 0x60}, + {0xfe, 0x00}, + {0xff, 0xff}, +}; + +/* load GC2145 parameters */ +void GC2145_init_regs(struct gc2145_device *dev) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + int i = 0; + + if (!dev->vminfo.isused) + return; + + while (1) { + if (GC2145_script[i].val == 0xff && + GC2145_script[i].addr == 0xff) { + pr_info("GC2145_write_regs success in initial.\n"); + break; + } + if ((i2c_put_byte_add8_new(client, GC2145_script[i].addr, + GC2145_script[i].val)) < 0) { + pr_err("fail in initial GC2145.\n"); + return; + } + i++; + } +} + +/* + ************************************************************************ + * FUNCTION + * GC2145_set_param_wb + * + * DESCRIPTION + * wb setting. + * + * PARAMETERS + * none + * + * RETURNS + * None + * + * GLOBALS AFFECTED + * + ************************************************************************ + */ + +void GC2145_set_param_wb(struct gc2145_device *dev, + enum camera_wb_flip_e para) /* white balance */ +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + unsigned int temp = 0; + + if (!dev->vminfo.isused) + return; + + i2c_put_byte_add8_new(client, 0xfe, 0x00); + temp = i2c_get_byte_add8(client, 0x82); + + switch (para) { + + case CAM_WB_AUTO:/* auto */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0xb3, 0x61); + i2c_put_byte_add8_new(client, 0xb4, 0x40); + i2c_put_byte_add8_new(client, 0xb5, 0x61); + i2c_put_byte_add8_new(client, 0x82, temp|0x2); + break; + + case CAM_WB_CLOUD: /* cloud */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x82, temp&(~0x02)); + i2c_put_byte_add8_new(client, 0xb3, 0x58); + i2c_put_byte_add8_new(client, 0xb4, 0x40); + i2c_put_byte_add8_new(client, 0xb5, 0x50); + break; + + case CAM_WB_DAYLIGHT: /* */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x82, temp&(~0x02)); + i2c_put_byte_add8_new(client, 0xb3, 0x70); + i2c_put_byte_add8_new(client, 0xb4, 0x40); + i2c_put_byte_add8_new(client, 0xb5, 0x50); + break; + + case CAM_WB_INCANDESCENCE: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x82, temp&(~0x02)); + i2c_put_byte_add8_new(client, 0xb3, 0x50); + i2c_put_byte_add8_new(client, 0xb4, 0x40); + i2c_put_byte_add8_new(client, 0xb5, 0xa8); + break; + + case CAM_WB_TUNGSTEN: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x82, temp&(~0x02)); + i2c_put_byte_add8_new(client, 0xb3, 0xa0); + i2c_put_byte_add8_new(client, 0xb4, 0x45); + i2c_put_byte_add8_new(client, 0xb5, 0x40); + break; + + case CAM_WB_FLUORESCENT: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x82, temp&(~0x02)); + i2c_put_byte_add8_new(client, 0xb3, 0x72); + i2c_put_byte_add8_new(client, 0xb4, 0x40); + i2c_put_byte_add8_new(client, 0xb5, 0x5b); + break; + + case CAM_WB_MANUAL: + /* TODO */ + break; + default: + break; + } + + +} /* GC2145_set_param_wb */ + +/* + ************************************************************************ + * FUNCTION + * GC2145_set_param_exposure + * + * DESCRIPTION + * exposure setting. + * + * PARAMETERS + * none + * + * RETURNS + * None + * + * GLOBALS AFFECTED + * + ************************************************************************ + */ + +void GC2145_set_param_exposure(struct gc2145_device *dev, + enum camera_exposure_e para) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + if (!dev->vminfo.isused) + return; + + switch (para) { + + case EXPOSURE_N4_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x55); /*target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + + + case EXPOSURE_N3_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x60); /*target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + + case EXPOSURE_N2_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x65); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + + case EXPOSURE_N1_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x70); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + case EXPOSURE_0_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x7b); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + case EXPOSURE_P1_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x85); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + case EXPOSURE_P2_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x90); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + case EXPOSURE_P3_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x95); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + case EXPOSURE_P4_STEP: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0xa0); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + + default: + i2c_put_byte_add8_new(client, 0xfe, 0x01); + i2c_put_byte_add8_new(client, 0x13, 0x7b); /* target_y */ + i2c_put_byte_add8_new(client, 0xfe, 0x00); + break; + /* break; */ + + } + +} /* GC2145_set_param_exposure */ + +/* + ************************************************************************ + * FUNCTION + * GC2145_set_param_effect + * + * DESCRIPTION + * effect setting. + * + * PARAMETERS + * none + * + * RETURNS + * None + * + * GLOBALS AFFECTED + * + ************************************************************************ + */ + +void GC2145_set_param_effect(struct gc2145_device *dev, + enum camera_effect_flip_e para) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + if (!dev->vminfo.isused) + return; + + switch (para) { + case CAM_EFFECT_ENC_NORMAL: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x83, 0xe0); + break; + + case CAM_EFFECT_ENC_GRAYSCALE: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x83, 0x12); + break; + + case CAM_EFFECT_ENC_SEPIA: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x83, 0x82); + break; + + case CAM_EFFECT_ENC_SEPIAGREEN: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x43, 0x52); + break; + + case CAM_EFFECT_ENC_SEPIABLUE: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x43, 0x62); + break; + + case CAM_EFFECT_ENC_COLORINV: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x83, 0x01); + break; + + default: + i2c_put_byte_add8_new(client, 0xfe, 0x00); + i2c_put_byte_add8_new(client, 0x83, 0xe0); + break; + } + +} /* GC2145_set_param_effect */ + +/* + ************************************************************************ + * FUNCTION + * GC2145_NightMode + * + * DESCRIPTION + * This function night mode of GC2145. + * + * PARAMETERS + * none + * + * RETURNS + * None + * + * GLOBALS AFFECTED + * + ************************************************************************ + */ + +void GC2145_set_night_mode(struct gc2145_device *dev, + enum camera_night_mode_flip_e enable) +{ + +} + +void GC2145_set_param_banding(struct gc2145_device *dev, + enum camera_banding_flip_e banding) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + unsigned char buf[4]; + int i = 0; + + switch (banding) { + case CAM_BANDING_50HZ: + while (1) { + buf[0] = gc2145_FLICKER_50HZ[i].addr; + buf[1] = gc2145_FLICKER_50HZ[i].val; + if (gc2145_FLICKER_50HZ[i].val == 0xff && + gc2145_FLICKER_50HZ[i].addr == 0xff) { + pr_err("success in gc2145_FLICKER_50HZ gc2145\n"); + break; + } + if ((i2c_put_byte_add8(client, buf, 2)) < 0) { + pr_err("fail in gc2145_FLICKER_50HZ gc2145\n"); + return; + } + i++; + } + break; + case CAM_BANDING_60HZ: + while (1) { + buf[0] = gc2145_FLICKER_60HZ[i].addr; + buf[1] = gc2145_FLICKER_60HZ[i].val; + if (gc2145_FLICKER_60HZ[i].val == 0xff && + gc2145_FLICKER_60HZ[i].addr == 0xff) { + pr_err("success in gc2145_FLICKER_60HZ gc2145\n"); + break; + } + if ((i2c_put_byte_add8(client, buf, 2)) < 0) { + pr_err("fail in gc2145_FLICKER_60HZ gc2145\n"); + return; + } + i++; + } + break; + default: + break; + } + +} + +static int set_flip(struct gc2145_device *dev) +{ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + unsigned char temp; + unsigned char buf[2]; + + if (!dev->vminfo.isused) + return 0; + + i2c_put_byte_add8_new(client, 0xfe, 0x00); + + temp = i2c_get_byte_add8(client, 0x17); + temp &= 0xfc; + temp |= dev->cam_info.m_flip << 0; + temp |= dev->cam_info.v_flip << 1; + buf[0] = 0x17; + buf[1] = temp; + if ((i2c_put_byte_add8(client, buf, 2)) < 0) { + pr_err("fail in setting sensor orientation\n"); + return -1; + } + + return 0; +} + +void GC2145_set_resolution(struct gc2145_device *dev, int height, int width) +{ + unsigned char buf[4]; + unsigned int value; + unsigned int pid = 0, shutter; + unsigned int i = 0; + static unsigned int shutter_l; + static unsigned int shutter_h; + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + pr_info("%s :wxh = %d x %d\n", __func__, width, height); + + if (!dev->vminfo.isused) + return; + + if ((width * height < 1600 * 1200)) { + while (1) { + buf[0] = gc2145_uxga[i].addr; + buf[1] = gc2145_uxga[i].val; + if (gc2145_uxga[i].val == 0xff && + gc2145_uxga[i].addr == 0xff) { + pr_info("success in gc2145_uxga.\n"); + break; + } + if ((i2c_put_byte_add8(client, buf, 2)) < 0) { + pr_err("fail in gc2145_uxga.\n"); + return; + } + i++; + } + gc2145_frmintervals_active.numerator = 1; + gc2145_frmintervals_active.denominator = 15; + GC2145_h_active = 1600; + GC2145_v_active = 1200; + mdelay(80); + } else if (width * height >= 1200 * 1600) { + buf[0] = 0xfe; + buf[1] = 0x00; + i2c_put_byte_add8(client, buf, 2); + + buf[0] = 0xb6; + buf[1] = 0x00; + i2c_put_byte_add8(client, buf, 2); + + buf[0] = 0x03; + value = i2c_get_byte_add8(client, 0x03); + shutter_l = value; + /*printk(KERN_INFO"set camera 0x03=0x%x\n", value);*/ + pid |= (value << 8); + + buf[0] = 0x04; + value = i2c_get_byte_add8(client, 0x04); + shutter_h = value; + /*printk(KERN_INFO"set camera 0x04=0x%x\n", value);*/ + pid |= (value & 0x1f); + + shutter = pid; + /*printk(KERN_INFO "set camera shutter=0x%x\n", shutter);*/ + + while (1) { + buf[0] = gc2145_uxga[i].addr; + buf[1] = gc2145_uxga[i].val; + if (gc2145_uxga[i].val == 0xff && + gc2145_uxga[i].addr == 0xff) { + pr_info("gc2145_write_regs success in gc2145_uxga.\n"); + break; + } + if ((i2c_put_byte_add8(client, buf, 2)) < 0) { + pr_err("fail in gc2145_uxga.\n"); + return; + } + i++; + } + + shutter = shutter / 2; + if (shutter < 1) + shutter = 1; + + buf[0] = 0x03; + buf[1] = ((shutter >> 8) & 0xff); + i2c_put_byte_add8(client, buf, 2); + + buf[0] = 0x04; + buf[1] = (shutter & 0x1f); + i2c_put_byte_add8(client, buf, 2); + + gc2145_frmintervals_active.denominator = 5; + gc2145_frmintervals_active.numerator = 1; + GC2145_h_active = 1600; + GC2145_v_active = 1200; + mdelay(130); + } + set_flip(dev); +} /* GC2145_set_resolution */ + +unsigned char v4l_2_gc2145(int val) +{ + int ret = val / 0x20; + + if (ret < 4) + return ret * 0x20 + 0x80; + else if (ret < 8) + return ret * 0x20 + 0x20; + else + return 0; +} + +static int convert_canvas_index(unsigned int v4l2_format, + unsigned int start_canvas) +{ + int canvas = start_canvas; + + switch (v4l2_format) { + case V4L2_PIX_FMT_RGB565X: + case V4L2_PIX_FMT_VYUY: + canvas = start_canvas; + break; + case V4L2_PIX_FMT_YUV444: + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + canvas = start_canvas; + break; + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + canvas = start_canvas | ((start_canvas + 1) << 8); + break; + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YUV420: + if (v4l2_format == V4L2_PIX_FMT_YUV420) + canvas = start_canvas | ((start_canvas + 1) << 8) | + ((start_canvas + 2) << 16); + else + canvas = start_canvas | ((start_canvas + 2) << 8) | + ((start_canvas + 1) << 16); + break; + default: + break; + } + return canvas; +} + +static int gc2145_setting(struct gc2145_device *dev, int PROP_ID, int value) +{ + int ret = 0; + /* unsigned char cur_val; */ + struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); + + if (!dev->vminfo.isused) + return 0; + /*here register not finished */ + switch (PROP_ID) { + + case V4L2_CID_BRIGHTNESS: + dprintk(dev, 1, "setting brightned:%d\n", v4l_2_gc2145(value)); + ret = i2c_put_byte_add8_new(client, 0xdc, v4l_2_gc2145(value)); + break; + case V4L2_CID_CONTRAST: + ret = i2c_put_byte_add8_new(client, 0xde, value); + break; + case V4L2_CID_SATURATION: + ret = i2c_put_byte_add8_new(client, 0xd9, value); + break; + case V4L2_CID_DO_WHITE_BALANCE: + if (gc2145_qctrl[0].default_value != value) { + gc2145_qctrl[0].default_value = value; + GC2145_set_param_wb(dev, value); + pr_info("set camera white_balance=%d.\n ", + value); + } + break; + case V4L2_CID_EXPOSURE: + if (gc2145_qctrl[1].default_value != value) { + gc2145_qctrl[1].default_value = value; + GC2145_set_param_exposure(dev, value); + pr_info("set camera exposure=%d.\n", + value); + } + break; + case V4L2_CID_COLORFX: + if (gc2145_qctrl[2].default_value != value) { + gc2145_qctrl[2].default_value = value; + /* GC2145_set_param_effect(dev,value); */ + pr_info("set camera effect=%d.\n", + value); + } + break; + case V4L2_CID_WHITENESS: + if (gc2145_qctrl[3].default_value != value) { + gc2145_qctrl[3].default_value = value; + pr_info("@@@SP_000:GC2145_set_param_banding,value=%d\n", + value); + GC2145_set_param_banding(dev, value); + pr_info("@@@SP_111:gc2145_night_or_normal = %d", + gc2145_night_or_normal); + GC2145_set_night_mode(dev, gc2145_night_or_normal); + pr_info("set camera banding=%d.\n", + value); + } + break; + case V4L2_CID_BLUE_BALANCE: + if (gc2145_qctrl[4].default_value != value) { + gc2145_qctrl[4].default_value = value; + pr_info("@@@SP_222:GC2145_set_night_mode,night mode=%d\n", + value); + pr_info("@@@SP_333:gc2145_night_or_normal = %d", + gc2145_night_or_normal); + GC2145_set_night_mode(dev, value); + pr_info("set camera scene mode=%d.\n", + value); + } + break; + case V4L2_CID_HFLIP: /* set flip on H. */ + value = value & 0x3; + if (gc2145_qctrl[5].default_value != value) { + gc2145_qctrl[5].default_value = value; + pr_info(" set camera h filp =%d.\n ", value); + } + break; + case V4L2_CID_VFLIP: /* set flip on V. */ + break; + case V4L2_CID_ZOOM_ABSOLUTE: + if (gc2145_qctrl[7].default_value != value) + gc2145_qctrl[7].default_value = value; + break; + case V4L2_CID_ROTATE: + if (gc2145_qctrl[8].default_value != value) { + gc2145_qctrl[8].default_value = value; + pr_info(" set camera rotate =%d.\n ", value); + } + break; + default: + ret = -1; + break; + } + return ret; +} + +static void power_down_gc2145(struct gc2145_device *dev) +{ + +} + +/* + *------------------------------------------------------------------ + * DMA and thread functions + * ------------------------------------------------------------------ + */ + +#define TSTAMP_MIN_Y 24 +#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15) +#define TSTAMP_INPUT_X 10 +#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) + +static void gc2145_fillbuff(struct gc2145_fh *fh, struct gc2145_buffer *buf) +{ + int ret; + void *vbuf; + struct vm_output_para para = {0}; + struct gc2145_device *dev = fh->dev; + + if (dev->vminfo.mem_alloc_succeed) + vbuf = (void *)videobuf_to_res(&buf->vb); + else + vbuf = videobuf_to_vmalloc(&buf->vb); + dprintk(dev, 1, "%s\n", __func__); + if (!vbuf) + return; + /* 0x18221223 indicate the memory type is MAGIC_VMAL_MEM*/ + if (dev->vminfo.mem_alloc_succeed) { + if (buf->canvas_id == 0) + buf->canvas_id = convert_canvas_index(fh->fmt->fourcc, + CAMERA_USER_CANVAS_INDEX + buf->vb.i * 3); + para.v4l2_memory = MAGIC_RE_MEM; + } else + para.v4l2_memory = MAGIC_VMAL_MEM; + para.mirror = gc2145_qctrl[5].default_value & 3;/* not set */ + para.v4l2_format = fh->fmt->fourcc; + para.zoom = gc2145_qctrl[7].default_value; + para.angle = gc2145_qctrl[8].default_value; + para.vaddr = (uintptr_t)vbuf; + /* para.ext_canvas = buf->canvas_id; */ + para.ext_canvas = 0; + para.width = buf->vb.width; + para.height = buf->vb.height; + dev->vminfo.vdin_id = dev->cam_info.vdin_path; + ret = vm_fill_this_buffer(&buf->vb, ¶, &dev->vminfo); + /*if the vm is not used by sensor ,*/ + /*we let vm_fill_this_buffer() return -2*/ + if (ret == -2) + msleep(40); + buf->vb.state = VIDEOBUF_DONE; +} + +static void gc2145_thread_tick(struct gc2145_fh *fh) +{ + struct gc2145_buffer *buf; + struct gc2145_device *dev = fh->dev; + struct gc2145_dmaqueue *dma_q = &dev->vidq; + + unsigned long flags = 0; + + dprintk(dev, 1, "Thread tick\n"); + if (!fh->stream_on) { + dprintk(dev, 1, "sensor doesn't stream on\n"); + return; + } + spin_lock_irqsave(&dev->slock, flags); + if (list_empty(&dma_q->active)) { + dprintk(dev, 1, "No active queue to serve\n"); + goto unlock; + } + + buf = list_entry(dma_q->active.next, + struct gc2145_buffer, vb.queue); + dprintk(dev, 1, "%s\n", __func__); + dprintk(dev, 1, "list entry get buf is %p\n", buf); + + if (!(fh->f_flags & O_NONBLOCK)) { + /* Nobody is waiting on this buffer, return */ + if (!waitqueue_active(&buf->vb.done)) + goto unlock; + } + buf->vb.state = VIDEOBUF_ACTIVE; + + list_del(&buf->vb.queue); + + do_gettimeofday(&buf->vb.ts); + + /* Fill buffer */ + spin_unlock_irqrestore(&dev->slock, flags); + gc2145_fillbuff(fh, buf); + dprintk(dev, 1, "filled buffer %p\n", buf); + + wake_up(&buf->vb.done); + dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); + return; +unlock: + spin_unlock_irqrestore(&dev->slock, flags); +} + +#define frames_to_ms(frames) \ + ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR) + +static void gc2145_sleep(struct gc2145_fh *fh) +{ + struct gc2145_device *dev = fh->dev; + struct gc2145_dmaqueue *dma_q = &dev->vidq; + + DECLARE_WAITQUEUE(wait, current); + + dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__, + (unsigned long)dma_q); + + add_wait_queue(&dma_q->wq, &wait); + if (kthread_should_stop()) + goto stop_task; + + /* Calculate time to wake up */ + /* timeout = msecs_to_jiffies(frames_to_ms(1)); */ + + gc2145_thread_tick(fh); + + schedule_timeout_interruptible(2); + +stop_task: + remove_wait_queue(&dma_q->wq, &wait); + try_to_freeze(); +} + +static int gc2145_thread(void *data) +{ + struct gc2145_fh *fh = data; + struct gc2145_device *dev = fh->dev; + + dprintk(dev, 1, "thread started\n"); + + set_freezable(); + + for (; ;) { + gc2145_sleep(fh); + + if (kthread_should_stop()) + break; + } + dprintk(dev, 1, "thread: exit\n"); + return 0; +} + +static int gc2145_start_thread(struct gc2145_fh *fh) +{ + struct gc2145_device *dev = fh->dev; + struct gc2145_dmaqueue *dma_q = &dev->vidq; + + dma_q->frame = 0; + dma_q->ini_jiffies = jiffies; + + dprintk(dev, 1, "%s\n", __func__); + + dma_q->kthread = kthread_run(gc2145_thread, fh, "gc2145"); + + if (IS_ERR(dma_q->kthread)) { + v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); + return PTR_ERR(dma_q->kthread); + } + /* Wakes thread */ + wake_up_interruptible(&dma_q->wq); + + dprintk(dev, 1, "returning from %s\n", __func__); + return 0; +} + +static void gc2145_stop_thread(struct gc2145_dmaqueue *dma_q) +{ + struct gc2145_device *dev = + container_of(dma_q, struct gc2145_device, vidq); + + dprintk(dev, 1, "%s\n", __func__); + /* shutdown control thread */ + if (dma_q->kthread) { + kthread_stop(dma_q->kthread); + dma_q->kthread = NULL; + } +} + +/* + *------------------------------------------------------------------ + * Videobuf operations + * ------------------------------------------------------------------ + */ + +static int +vmall_buffer_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct gc2145_fh *fh = vq->priv_data; + struct gc2145_device *dev = fh->dev; + /* int bytes = fh->fmt->depth >> 3 ; */ + *size = (fh->width * fh->height * fh->fmt->depth) >> 3; + if (*count == 0) + *count = 32; + + while (*size * *count > vid_limit * 1024 * 1024) + (*count)--; + + dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, + *count, *size); + + return 0; +} + +static int +res_buffer_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct videobuf_res_privdata *res = vq->priv_data; + struct gc2145_fh *fh = container_of(res, struct gc2145_fh, res); + struct gc2145_device *dev = fh->dev; + /* int bytes = fh->fmt->depth >> 3 ; */ + int height = fh->height; + + if (height == 1080) + height = 1088; + *size = (fh->width * height * fh->fmt->depth) >> 3; + if (*count == 0) + *count = 32; + + while (*size * *count > vid_limit * 1024 * 1024) + (*count)--; + + dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, + *count, *size); + + return 0; +} + +static void free_vmall_buffer(struct videobuf_queue *vq, + struct gc2145_buffer *buf) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + + fh = vq->priv_data; + dev = fh->dev; + + dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); + + videobuf_waiton(vq, &buf->vb, 0, 0); + if (in_interrupt()) + WARN_ON(1); + videobuf_vmalloc_free(&buf->vb); + dprintk(dev, 1, "free_vmall_buffer: freed\n"); + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +static void free_res_buffer(struct videobuf_queue *vq, + struct gc2145_buffer *buf) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct videobuf_res_privdata *res = vq->priv_data; + + fh = container_of(res, struct gc2145_fh, res); + dev = fh->dev; + + dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); + + videobuf_waiton(vq, &buf->vb, 0, 0); + if (in_interrupt()) + WARN_ON(1); + videobuf_res_free(vq, &buf->vb); + dprintk(dev, 1, "free_res_buffer: freed\n"); + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +#define norm_maxw() 1920 +#define norm_maxh() 1600 +static int +vmall_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct gc2145_buffer *buf; + int rc; + + fh = vq->priv_data; + dev = fh->dev; + buf = container_of(vb, struct gc2145_buffer, vb); + /* int bytes = fh->fmt->depth >> 3 ; */ + dprintk(dev, 1, "%s, field=%d\n", __func__, field); + + WARN_ON(fh->fmt == NULL); + + if (fh->width < 48 || fh->width > norm_maxw() || + fh->height < 32 || fh->height > norm_maxh()) + return -EINVAL; + + buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; + if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) + return -EINVAL; + + /* These properties only change when queue is idle, see s_fmt */ + buf->fmt = fh->fmt; + buf->vb.width = fh->width; + buf->vb.height = fh->height; + buf->vb.field = field; + + /* precalculate_bars(fh); */ + + if (buf->vb.state == VIDEOBUF_NEEDS_INIT) { + rc = videobuf_iolock(vq, &buf->vb, NULL); + if (rc < 0) + goto fail; + } + + buf->vb.state = VIDEOBUF_PREPARED; + + return 0; + +fail: + free_vmall_buffer(vq, buf); + return rc; +} + +static int +res_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct gc2145_buffer *buf; + int rc; + struct videobuf_res_privdata *res = vq->priv_data; + + fh = container_of(res, struct gc2145_fh, res); + dev = fh->dev; + buf = container_of(vb, struct gc2145_buffer, vb); + dprintk(dev, 1, "%s, field=%d\n", __func__, field); + + WARN_ON(fh->fmt == NULL); + + if (fh->width < 48 || fh->width > norm_maxw() || + fh->height < 32 || fh->height > norm_maxh()) + return -EINVAL; + + buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; + if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) + return -EINVAL; + + /* These properties only change when queue is idle, see s_fmt */ + buf->fmt = fh->fmt; + buf->vb.width = fh->width; + buf->vb.height = fh->height; + buf->vb.field = field; + + /* precalculate_bars(fh); */ + + if (buf->vb.state == VIDEOBUF_NEEDS_INIT) { + rc = videobuf_iolock(vq, &buf->vb, NULL); + if (rc < 0) + goto fail; + } + + buf->vb.state = VIDEOBUF_PREPARED; + + return 0; + +fail: + free_res_buffer(vq, buf); + return rc; +} + +static void +res_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct gc2145_dmaqueue *vidq; + struct gc2145_buffer *buf = container_of(vb, struct gc2145_buffer, vb); + struct videobuf_res_privdata *res = vq->priv_data; + + fh = container_of(res, struct gc2145_fh, res); + dev = fh->dev; + vidq = &dev->vidq; + + dprintk(dev, 1, "%s\n", __func__); + buf->vb.state = VIDEOBUF_QUEUED; + list_add_tail(&buf->vb.queue, &vidq->active); +} + +static void +vmall_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct gc2145_dmaqueue *vidq; + struct gc2145_buffer *buf = container_of(vb, struct gc2145_buffer, vb); + + fh = vq->priv_data; + dev = fh->dev; + vidq = &dev->vidq; + + dprintk(dev, 1, "%s\n", __func__); + buf->vb.state = VIDEOBUF_QUEUED; + list_add_tail(&buf->vb.queue, &vidq->active); +} + +static void res_buffer_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct gc2145_buffer *buf = + container_of(vb, struct gc2145_buffer, vb); + struct videobuf_res_privdata *res = vq->priv_data; + + fh = container_of(res, struct gc2145_fh, res); + dev = (struct gc2145_device *)fh->dev; + + dprintk(dev, 1, "%s\n", __func__); + + free_res_buffer(vq, buf); +} + +static void vmall_buffer_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct gc2145_fh *fh; + struct gc2145_device *dev; + struct gc2145_buffer *buf = + container_of(vb, struct gc2145_buffer, vb); + fh = vq->priv_data; + dev = (struct gc2145_device *)fh->dev; + + dprintk(dev, 1, "%s\n", __func__); + + free_vmall_buffer(vq, buf); +} + +static struct videobuf_queue_ops gc2145_video_vmall_qops = { + .buf_setup = vmall_buffer_setup, + .buf_prepare = vmall_buffer_prepare, + .buf_queue = vmall_buffer_queue, + .buf_release = vmall_buffer_release, +}; + +static struct videobuf_queue_ops gc2145_video_res_qops = { + .buf_setup = res_buffer_setup, + .buf_prepare = res_buffer_prepare, + .buf_queue = res_buffer_queue, + .buf_release = res_buffer_release, +}; + +/* + *------------------------------------------------------------------ + * IOCTL vidioc handling + * ------------------------------------------------------------------ + */ + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + + strcpy(cap->driver, "gc2145"); + strcpy(cap->card, "gc2145.canvas"); + if (dev->cam_info.front_back == 0) + strcat(cap->card, "back"); + else + strcat(cap->card, "front"); + + strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); + cap->version = GC2145_CAMERA_VERSION; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING + | V4L2_CAP_READWRITE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + return 0; +} + +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct gc2145_fmt *fmt; + + if (f->index >= ARRAY_SIZE(formats)) + return -EINVAL; + + fmt = &formats[f->index]; + + strlcpy(f->description, fmt->name, sizeof(f->description)); + f->pixelformat = fmt->fourcc; + return 0; +} +static int vidioc_enum_frameintervals(struct file *file, void *priv, + struct v4l2_frmivalenum *fival) +{ + unsigned int k; + + if (fival->index > ARRAY_SIZE(gc2145_frmivalenum)) + return -EINVAL; + + for (k = 0; k < ARRAY_SIZE(gc2145_frmivalenum); k++) { + if ((fival->index == gc2145_frmivalenum[k].index) && + (fival->pixel_format == + gc2145_frmivalenum[k].pixel_format) && + (fival->width == gc2145_frmivalenum[k].width) && + (fival->height == gc2145_frmivalenum[k].height)) { + memcpy(fival, &gc2145_frmivalenum[k], + sizeof(struct v4l2_frmivalenum)); + return 0; + } + } + + return -EINVAL; + +} + +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct gc2145_fh *fh = priv; + + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; + f->fmt.pix.field = fh->vb_vidq.field; + f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fh->fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; +} + +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + struct gc2145_fmt *fmt; + enum v4l2_field field; + unsigned int maxw, maxh; + + fmt = get_format(f); + if (!fmt) { + dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n", + f->fmt.pix.pixelformat); + return -EINVAL; + } + + field = f->fmt.pix.field; + + if (field == V4L2_FIELD_ANY) + field = V4L2_FIELD_INTERLACED; + else if (field != V4L2_FIELD_INTERLACED) { + dprintk(dev, 1, "Field type invalid.\n"); + return -EINVAL; + } + + maxw = norm_maxw(); + maxh = norm_maxh(); + + f->fmt.pix.field = field; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; +} + +/*FIXME: This seems to be generic enough to be at videodev2 */ +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct gc2145_fh *fh = priv; + struct videobuf_queue *q = &fh->vb_vidq; + struct gc2145_device *dev = fh->dev; + int ret; + + f->fmt.pix.width = (f->fmt.pix.width + + (CANVAS_WIDTH_ALIGN - 1)) & + (~(CANVAS_WIDTH_ALIGN - 1)); + if ((f->fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) || + (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)) + f->fmt.pix.width = (f->fmt.pix.width + + (CANVAS_WIDTH_ALIGN * 2 - 1)) & + (~(CANVAS_WIDTH_ALIGN * 2 - 1)); + + ret = vidioc_try_fmt_vid_cap(file, fh, f); + if (ret < 0) + return ret; + + mutex_lock(&q->vb_lock); + + if (videobuf_queue_is_busy(&fh->vb_vidq)) { + dprintk(fh->dev, 1, "%s queue busy\n", __func__); + ret = -EBUSY; + goto out; + } + + fh->fmt = get_format(f); + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->vb_vidq.field = f->fmt.pix.field; + fh->type = f->type; +#if 0 + set_flip(dev); + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { + vidio_set_fmt_ticks = 1; + GC2145_set_resolution(dev, fh->height, fh->width); + } else if (vidio_set_fmt_ticks == 1) + GC2145_set_resolution(dev, fh->height, fh->width); +#else + GC2145_set_resolution(dev, fh->height, fh->width); +#endif + ret = 0; +out: + mutex_unlock(&q->vb_lock); + + return ret; +} + +static int vidioc_g_parm(struct file *file, void *priv, + struct v4l2_streamparm *parms) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + struct v4l2_captureparm *cp = &parms->parm.capture; + + dprintk(dev, 3, "vidioc_g_parm\n"); + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(cp, 0, sizeof(struct v4l2_captureparm)); + cp->capability = V4L2_CAP_TIMEPERFRAME; + + cp->timeperframe = gc2145_frmintervals_active; + pr_debug("g_parm,deno=%d, numerator=%d\n", + cp->timeperframe.denominator, + cp->timeperframe.numerator); + return 0; +} + + +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct gc2145_fh *fh = priv; + + return videobuf_reqbufs(&fh->vb_vidq, p); +} + +static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct gc2145_fh *fh = priv; + int ret = videobuf_querybuf(&fh->vb_vidq, p); + + if (get_cpu_type() == MESON_CPU_MAJOR_ID_M8) { + if (ret == 0) + p->reserved = convert_canvas_index(fh->fmt->fourcc, + CAMERA_USER_CANVAS_INDEX + + p->index * 3); + else + p->reserved = 0; + } + return ret; +} + +static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct gc2145_fh *fh = priv; + + return videobuf_qbuf(&fh->vb_vidq, p); +} + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + struct gc2145_fh *fh = priv; + + return videobuf_dqbuf(&fh->vb_vidq, p, + file->f_flags & O_NONBLOCK); +} + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) +{ + struct gc2145_fh *fh = priv; + + return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); +} +#endif + +static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct gc2145_fh *fh = priv; + struct vdin_parm_s para; + unsigned int vdin_path; + int ret = 0; + + pr_info("vidioc_streamon+++\n "); + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (i != fh->type) + return -EINVAL; + + memset(¶, 0, sizeof(para)); + para.port = TVIN_PORT_CAMERA; + para.fmt = TVIN_SIG_FMT_MAX; + para.frame_rate = gc2145_frmintervals_active.denominator; + para.h_active = GC2145_h_active; + para.v_active = GC2145_v_active; + para.hsync_phase = 1; + para.vsync_phase = 1; + para.hs_bp = 0; + para.vs_bp = 3; + para.bt_path = fh->dev->cam_info.bt_path; + vdin_path = fh->dev->cam_info.vdin_path; + para.cfmt = TVIN_YUV422; + para.dfmt = TVIN_NV21; + para.scan_mode = TVIN_SCAN_MODE_PROGRESSIVE; + + if (is_first_time_open == 0) { + para.skip_count = 4; + is_first_time_open = 1; + } else + para.skip_count = 0; + + ret = videobuf_streamon(&fh->vb_vidq); + if (ret == 0) { + if (fh->dev->vminfo.isused) { + vops->start_tvin_service(vdin_path, ¶); + fh->stream_on = 1; + } + } + + return ret; +} + +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct gc2145_fh *fh = priv; + unsigned int vdin_path; + int ret = 0; + + pr_info("vidioc_streamoff+++\n "); + vdin_path = fh->dev->cam_info.vdin_path; + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (i != fh->type) + return -EINVAL; + ret = videobuf_streamoff(&fh->vb_vidq); + if (ret == 0) { + if (fh->dev->vminfo.isused) + vops->stop_tvin_service(vdin_path); + fh->stream_on = 0; + } + return ret; +} + +static int vidioc_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + int ret = 0, i = 0; + struct gc2145_fmt *fmt = NULL; + struct v4l2_frmsize_discrete *frmsize = NULL; + + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].fourcc == fsize->pixel_format) { + fmt = &formats[i]; + break; + } + } + if (fmt == NULL) + return -EINVAL; + if ((fmt->fourcc == V4L2_PIX_FMT_NV21) + || (fmt->fourcc == V4L2_PIX_FMT_NV12) + || (fmt->fourcc == V4L2_PIX_FMT_YVU420) + || (fmt->fourcc == V4L2_PIX_FMT_YUV420)) { + if (fsize->index >= ARRAY_SIZE(gc2145_prev_resolution)) + return -EINVAL; + frmsize = &gc2145_prev_resolution[fsize->index]; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = frmsize->width; + fsize->discrete.height = frmsize->height; + } else if (fmt->fourcc == V4L2_PIX_FMT_RGB24) { + if (fsize->index >= ARRAY_SIZE(gc2145_pic_resolution)) + return -EINVAL; + frmsize = &gc2145_pic_resolution[fsize->index]; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = frmsize->width; + fsize->discrete.height = frmsize->height; + } + return ret; +} + +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i) +{ + return 0; +} + +/* only one input in this sample driver */ +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + /* if (inp->index >= NUM_INPUTS) */ + /* return -EINVAL; */ + + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_525_60; + sprintf(inp->name, "Camera %u", inp->index); + + return 0; +} + +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + + *i = dev->input; + + return 0; +} + +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + + /* if (i >= NUM_INPUTS) */ + /* return -EINVAL; */ + + dev->input = i; + /* precalculate_bars(fh); */ + + return 0; +} + +/* --- controls ---------------------------------------------- */ +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(gc2145_qctrl); i++) + if (qc->id && qc->id == gc2145_qctrl[i].id) { + memcpy(qc, &(gc2145_qctrl[i]), + sizeof(*qc)); + return 0; + } + + return -EINVAL; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(gc2145_qctrl); i++) + if (ctrl->id == gc2145_qctrl[i].id) { + ctrl->value = dev->qctl_regs[i]; + return 0; + } + + return -EINVAL; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct gc2145_fh *fh = priv; + struct gc2145_device *dev = fh->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(gc2145_qctrl); i++) + if (ctrl->id == gc2145_qctrl[i].id) { + if (ctrl->value < gc2145_qctrl[i].minimum || + ctrl->value > gc2145_qctrl[i].maximum || + gc2145_setting(dev, ctrl->id, ctrl->value) < 0) + return -ERANGE; + dev->qctl_regs[i] = ctrl->value; + return 0; + } + return -EINVAL; +} + +/* + *------------------------------------------------------------------ + * File operations for the device + * ----------------------------------------------------------------- + */ + +static int gc2145_open(struct file *file) +{ + struct gc2145_device *dev = video_drvdata(file); + struct gc2145_fh *fh = NULL; + int retval = 0; + + dev->vminfo.vdin_id = dev->cam_info.vdin_path; + dev->vminfo.bt_path_count = dev->cam_info.bt_path_count; + +#if CONFIG_CMA + vm_init_resource(16 * SZ_1M, &dev->vminfo); +#endif + if (dev->vminfo.isused) { + pr_info("%s, front_back = %d\n", + __func__, dev->cam_info.front_back); + aml_cam_init(&dev->cam_info); + } + + GC2145_init_regs(dev); + msleep(40); + mutex_lock(&dev->mutex); + dev->users++; + if (dev->users > 1) { + dev->users--; + pr_err("gc2145 device is opened, device is busy\n"); + mutex_unlock(&dev->mutex); + return -EBUSY; + } + + dprintk(dev, 1, "open %s type=%s users=%d\n", + video_device_node_name(dev->vdev), + v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); + + /* init video dma queues */ + INIT_LIST_HEAD(&dev->vidq.active); + init_waitqueue_head(&dev->vidq.wq); + spin_lock_init(&dev->slock); + /* allocate + initialize per filehandle data */ + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (fh == NULL) { + dev->users--; + retval = -ENOMEM; + } + mutex_unlock(&dev->mutex); + + if (retval) + return retval; + +#ifdef CONFIG_HAS_WAKELOCK + wake_lock(&(dev->wake_lock)); +#endif + + file->private_data = fh; + fh->dev = dev; + + fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fh->fmt = &formats[0]; + fh->width = 1600;/* 640//zyy */ + fh->height = 1198;/* 1200;//480 */ + fh->stream_on = 0; + fh->f_flags = file->f_flags; + /* Resets frame counters */ + /*dev->jiffies = jiffies;*/ + + /* TVIN_SIG_FMT_CAMERA_640X480P_30Hz, */ + /* TVIN_SIG_FMT_CAMERA_800X600P_30Hz, */ + /* TVIN_SIG_FMT_CAMERA_1024X768P_30Hz, // 190 */ + /* TVIN_SIG_FMT_CAMERA_1920X1080P_30Hz, */ + /* TVIN_SIG_FMT_CAMERA_1280X720P_30Hz, */ + + if (dev->vminfo.mem_alloc_succeed) { + fh->res.start = dev->vminfo.buffer_start; + fh->res.end = dev->vminfo.buffer_start + + dev->vminfo.vm_buf_size - 1; + fh->res.magic = MAGIC_RE_MEM; + fh->res.priv = NULL; + videobuf_queue_res_init(&fh->vb_vidq, + &gc2145_video_res_qops, NULL, + &dev->slock, fh->type, + V4L2_FIELD_INTERLACED, + sizeof(struct gc2145_buffer), + (void *)&fh->res, NULL); + } else { + videobuf_queue_vmalloc_init(&fh->vb_vidq, + &gc2145_video_vmall_qops, NULL, + &dev->slock, fh->type, + V4L2_FIELD_INTERLACED, + sizeof(struct gc2145_buffer), fh, NULL); + } + + gc2145_start_thread(fh); + gc2145_have_open = 1; + return 0; +} + +static ssize_t +gc2145_read(struct file *file, char __user *data, size_t count, loff_t *ppos) +{ + struct gc2145_fh *fh = file->private_data; + + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0, + file->f_flags & O_NONBLOCK); + } + return 0; +} + +static unsigned int +gc2145_poll(struct file *file, struct poll_table_struct *wait) +{ + struct gc2145_fh *fh = file->private_data; + struct gc2145_device *dev = fh->dev; + struct videobuf_queue *q = &fh->vb_vidq; + + dprintk(dev, 1, "%s\n", __func__); + + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return POLLERR; + + return videobuf_poll_stream(file, q, wait); +} + +static int gc2145_close(struct file *file) +{ + struct gc2145_fh *fh = file->private_data; + struct gc2145_device *dev = fh->dev; + struct gc2145_dmaqueue *vidq = &dev->vidq; + struct video_device *vdev = video_devdata(file); + unsigned int vdin_path; + + vdin_path = fh->dev->cam_info.vdin_path; + gc2145_have_open = 0; + is_first_time_open = 0; + + gc2145_stop_thread(vidq); + videobuf_stop(&fh->vb_vidq); + if (fh->stream_on) { + if (dev->vminfo.isused) { + pr_info("%s, vdin_path = %d\n", + __func__, vdin_path); + vops->stop_tvin_service(vdin_path); + } + } + videobuf_mmap_free(&fh->vb_vidq); + kfree(fh); + + mutex_lock(&dev->mutex); + dev->users--; + mutex_unlock(&dev->mutex); + + dprintk(dev, 1, "close called (dev=%s, users=%d)\n", + video_device_node_name(vdev), dev->users); +#if 1 + GC2145_h_active = 640; /* 800//zyy */ + GC2145_v_active = 480; /* 1200;//600 */ + gc2145_qctrl[0].default_value = 0; + gc2145_qctrl[1].default_value = 4; + gc2145_qctrl[2].default_value = 0; + gc2145_qctrl[3].default_value = 0; + gc2145_qctrl[4].default_value = 0; + + gc2145_qctrl[5].default_value = 0; + gc2145_qctrl[7].default_value = 100; + gc2145_qctrl[8].default_value = 0; + gc2145_frmintervals_active.numerator = 1; + gc2145_frmintervals_active.denominator = 15; + power_down_gc2145(dev); +#endif + aml_cam_uninit(&dev->cam_info); +#ifdef CONFIG_HAS_WAKELOCK + wake_unlock(&(dev->wake_lock)); +#endif +#ifdef CONFIG_CMA + vm_deinit_resource(&dev->vminfo); +#endif + return 0; +} + +static int gc2145_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct gc2145_fh *fh = file->private_data; + struct gc2145_device *dev = fh->dev; + int ret; + + dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); + + ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); + + dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, + ret); + + return ret; +} + +static const struct v4l2_file_operations gc2145_fops = { + .owner = THIS_MODULE, + .open = gc2145_open, + .release = gc2145_close, + .read = gc2145_read, + .poll = gc2145_poll, + .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ + .mmap = gc2145_mmap, +}; + +static const struct v4l2_ioctl_ops gc2145_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_s_std = vidioc_s_std, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_querymenu = vidioc_querymenu, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, + .vidioc_enum_framesizes = vidioc_enum_framesizes, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = vidiocgmbuf, +#endif +}; + +static struct video_device gc2145_template = { + .name = "gc2145_v4l", + .fops = &gc2145_fops, + .ioctl_ops = &gc2145_ioctl_ops, + .release = video_device_release, + .tvnorms = V4L2_STD_525_60, +}; + +static const struct v4l2_subdev_core_ops gc2145_core_ops = { + /*.g_chip_ident = gc2145_g_chip_ident,*/ +}; + +static const struct v4l2_subdev_ops gc2145_ops = { + .core = &gc2145_core_ops, +}; + +static ssize_t gc2145_show(struct device *dev, struct device_attribute *attr, + char *_buf) +{ + return sprintf(_buf, "0x%02x=0x%02x\n", cur_reg, cur_val); +} + +static u32 strtol(const char *nptr, int base) +{ + u32 ret; + + if (!nptr || (base != 16 && base != 10 && base != 8)) { + pr_err("%s(): NULL pointer input\n", __func__); + return -1; + } + for (ret = 0; *nptr; nptr++) { + if ((base == 16 && *nptr >= 'A' && *nptr <= 'F') || + (base == 16 && *nptr >= 'a' && *nptr <= 'f') || + (base >= 10 && *nptr >= '0' && *nptr <= '9') || + (base >= 8 && *nptr >= '0' && *nptr <= '7')) { + ret *= base; + if (base == 16 && *nptr >= 'A' && *nptr <= 'F') + ret += *nptr - 'A' + 10; + else if (base == 16 && *nptr >= 'a' && *nptr <= 'f') + ret += *nptr - 'a' + 10; + else if (base >= 10 && *nptr >= '0' && *nptr <= '9') + ret += *nptr - '0'; + else if (base >= 8 && *nptr >= '0' && *nptr <= '7') + ret += *nptr - '0'; + } else + return ret; + } + return ret; +} + +static ssize_t gc2145_store(struct device *dev, + struct device_attribute *attr, + const char *_buf, size_t _count) +{ + const char *p = _buf; + u16 reg; + u8 val; + + if (!strncmp(_buf, "get", strlen("get"))) { + p += strlen("get"); + cur_reg = (u32)strtol(p, 16); + val = i2c_get_byte_add8(g_i2c_client, cur_reg); + pr_info("%s(): get 0x%04x=0x%02x\n", + __func__, cur_reg, val); + cur_val = val; + } else if (!strncmp(_buf, "put", strlen("put"))) { + p += strlen("put"); + reg = strtol(p, 16); + p = strchr(_buf, '='); + if (p) { + ++p; + val = strtol(p, 16); + i2c_put_byte_add8_new(g_i2c_client, reg, val); + pr_info("%s(): set 0x%04x=0x%02x\n", + __func__, reg, val); + } else + pr_info("%s(): Bad string format input!\n", __func__); + } else + pr_info("%s(): Bad string format input!\n", __func__); + + return _count; +} + +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, + char *_buf) +{ + strcpy(_buf, "GC2145"); + return 4; +} + +static struct device *gc2145_dev; +static struct class *gc2145_class; +static DEVICE_ATTR(gc2145, 0444, gc2145_show, gc2145_store);/*0666*/ +static DEVICE_ATTR(name, 0444, name_show, NULL); + +#define EMDOOR_DEBUG_GC2145 1 +#ifdef EMDOOR_DEBUG_GC2145 +unsigned int gc2145_reg_addr; +static struct i2c_client *gc2145_client; + +static ssize_t gc2145_show_mine(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + unsigned char dat; + + dat = i2c_get_byte_add8(gc2145_client, gc2145_reg_addr); + return sprintf(buf, "REG[0x%x]=0x%x\n", gc2145_reg_addr, dat); +} + +static ssize_t gc2145_store_mine(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int tmp; + unsigned short reg; + unsigned char val; + + tmp = kstrtoul(buf, 16, NULL); + /* sscanf(buf, "%du", &tmp); */ + if (tmp < 0xff) + gc2145_reg_addr = tmp; + else { + reg = (tmp >> 8) & 0xFFFF; /* reg */ + gc2145_reg_addr = reg; + val = tmp & 0xFF; /* val */ + i2c_put_byte_add8_new(gc2145_client, reg, val); + } + + return count; +} + + +static struct kobj_attribute gc2145_attribute = __ATTR(gc2145, 0444, + gc2145_show_mine, gc2145_store_mine); + + +static struct attribute *gc2145_attrs[] = { + &gc2145_attribute.attr, + NULL, +}; + + +static const struct attribute_group gc2145_group = { + .attrs = gc2145_attrs, +}; +#endif + +static int gc2145_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + struct gc2145_device *t; + struct v4l2_subdev *sd; + struct aml_cam_info_s *plat_dat; + int ret; + + vops = get_vdin_v4l2_ops(); + v4l_info(client, "chip found @ 0x%x (%s)\n", + client->addr << 1, client->adapter->name); + t = kzalloc(sizeof(*t), GFP_KERNEL); + /* modify correct i2c addr--- 0x30 */ + client->addr = 0x3c; + if (t == NULL) { + pr_err("%s, no memory", __func__); + return -ENOMEM; + } + snprintf(t->v4l2_dev.name, sizeof(t->v4l2_dev.name), + "%s-%03d", "gc2145", 0); + ret = v4l2_device_register(NULL, &t->v4l2_dev); + if (ret) { + pr_info("%s, v4l2 device register failed", __func__); + kfree(t); + kfree(client); + return ret; + } + + sd = &t->sd; + v4l2_i2c_subdev_init(sd, client, &gc2145_ops); + + plat_dat = (struct aml_cam_info_s *)client->dev.platform_data; + /* test if devices exist. */ + memset(&t->vminfo, 0, sizeof(struct vm_init_s)); + /* Now create a video4linux device */ + mutex_init(&t->mutex); + + /* Now create a video4linux device */ + t->vdev = video_device_alloc(); + if (t->vdev == NULL) { + kfree(t); + kfree(client); + return -ENOMEM; + } + memcpy(t->vdev, &gc2145_template, sizeof(*t->vdev)); + t->vdev->v4l2_dev = &t->v4l2_dev; + video_set_drvdata(t->vdev, t); + +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_init(&(t->wake_lock), WAKE_LOCK_SUSPEND, "gc2145"); +#endif + + /* Register it */ + if (plat_dat) { + memcpy(&t->cam_info, plat_dat, sizeof(struct aml_cam_info_s)); + pr_info("%s, front_back = %d\n", + __func__, plat_dat->front_back); + video_nr = plat_dat->front_back; + } else { + pr_err("camera gc2145: have no platform data\n"); + kfree(t); + return -1; + } + + t->cam_info.version = GC2145_DRIVER_VERSION; + if (aml_cam_info_reg(&t->cam_info) < 0) + pr_err("reg caminfo error\n"); + err = video_register_device(t->vdev, VFL_TYPE_GRABBER, video_nr); + if (err < 0) { + video_device_release(t->vdev); + kfree(t); + return err; + } + + gc2145_class = class_create(THIS_MODULE, "gc2145"); + if (IS_ERR(gc2145_class)) { + pr_err("Create class gc2145 fail.\n"); + return -ENOMEM; + } + + gc2145_dev = device_create(gc2145_class, NULL, + MKDEV(0, 1), NULL, "dev"); + device_create_file(gc2145_dev, &dev_attr_gc2145); + device_create_file(gc2145_dev, &dev_attr_name); + + g_i2c_client = client; + +#ifdef EMDOOR_DEBUG_GC2145 + gc2145_client = client; + err = sysfs_create_group(&client->dev.kobj, &gc2145_group); +#endif + + return 0; +} + +static int gc2145_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct gc2145_device *t = to_dev(sd); + + video_unregister_device(t->vdev); + v4l2_device_unregister_subdev(sd); +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_destroy(&(t->wake_lock)); +#endif + aml_cam_info_unreg(&t->cam_info); + kfree(t); + return 0; +} + + +static const struct i2c_device_id gc2145_id[] = { + { "gc2145", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, gc2145_id); + +static struct i2c_driver gc2145_i2c_driver = { + .driver = { + .name = "gc2145", + }, + .probe = gc2145_probe, + .remove = gc2145_remove, + .id_table = gc2145_id, +}; + +module_i2c_driver(gc2145_i2c_driver); + diff --git a/drivers/amlogic/media/common/canvas/canvas_mgr.c b/drivers/amlogic/media/common/canvas/canvas_mgr.c index 455b512e2518..56ab75ddb3c3 100644 --- a/drivers/amlogic/media/common/canvas/canvas_mgr.c +++ b/drivers/amlogic/media/common/canvas/canvas_mgr.c @@ -521,9 +521,6 @@ static void canvas_pool_config(void) canvas_pool_register_const_canvas(0x70, 0x77, "ppmgr"); canvas_pool_register_const_canvas(0xe4, 0xef, "encoder"); canvas_pool_register_const_canvas(0x40, 0x48, "osd"); -#ifdef CONFIG_AMLOGIC_VIDEOIN_MANAGER - canvas_pool_register_const_canvas(0x4e, 0x5f, "vm"); -#endif canvas_pool_register_const_canvas(0xc0, 0xd7, "amlvideo2"); /*please add static canvas later. */ } diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm.c b/drivers/amlogic/media/common/codec_mm/codec_mm.c index f613c06c5b2d..c6dabedcb13f 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm.c @@ -270,6 +270,31 @@ static int codec_mm_alloc_pre_check_in( return have_space; } +static ulong codec_mm_search_phy_addr(char *vaddr) +{ + struct codec_mm_mgt_s *mgt = get_mem_mgt(); + struct codec_mm_s *mem = NULL; + ulong phy_addr = 0; + unsigned long flags; + + spin_lock_irqsave(&mgt->lock, flags); + + list_for_each_entry(mem, &mgt->mem_list, list) { + if (vaddr - mem->vbuffer >= 0 && + vaddr - mem->vbuffer < mem->buffer_size) { + + if (mem->phy_addr) + phy_addr = mem->phy_addr + + (vaddr - mem->vbuffer); + break; + } + } + + spin_unlock_irqrestore(&mgt->lock, flags); + + return phy_addr; +} + static void *codec_mm_search_vaddr(unsigned long phy_addr) { struct codec_mm_mgt_s *mgt = get_mem_mgt(); @@ -841,7 +866,19 @@ void codec_mm_dma_flush(void *vaddr, { struct codec_mm_mgt_s *mgt = get_mem_mgt(); dma_addr_t dma_addr; + ulong phy_addr; + if (is_vmalloc_or_module_addr(vaddr)) { + phy_addr = codec_mm_search_phy_addr(vaddr); + if (!phy_addr) + phy_addr = page_to_phys(vmalloc_to_page(vaddr)) + + offset_in_page(vaddr); + if (phy_addr && PageHighMem(phys_to_page(phy_addr))) + flush_cache_vunmap(phy_addr, phy_addr + size); + return; + } + + /* only apply to the lowmem. */ dma_addr = dma_map_single(mgt->dev, vaddr, size, dir); if (dma_addr) dma_unmap_single(mgt->dev, dma_addr, size, dir); diff --git a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c index 7976d837b8a4..f36336aa9a0d 100644 --- a/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c +++ b/drivers/amlogic/media/common/codec_mm/codec_mm_scatter.c @@ -2205,6 +2205,14 @@ int codec_mm_scatter_update_config(struct codec_mm_scatter_mgt *smgt) smgt->no_alloc_from_sys = g_scatter.no_alloc_from_sys; return 0; } +int codec_mm_scatter_size(int is_tvp) +{ + struct codec_mm_scatter_mgt *smgt; + smgt = codec_mm_get_scatter_mgt(is_tvp ? 1 : 0); + + return smgt->total_page_num; +} +EXPORT_SYMBOL(codec_mm_scatter_size); int codec_mm_scatter_mgt_delay_free_swith( int on, @@ -2213,7 +2221,6 @@ int codec_mm_scatter_mgt_delay_free_swith( int is_tvp) { struct codec_mm_scatter_mgt *smgt; - unsigned long ret = 0; smgt = codec_mm_get_scatter_mgt(is_tvp); codec_mm_list_lock(smgt); @@ -2231,14 +2238,12 @@ int codec_mm_scatter_mgt_delay_free_swith( } codec_mm_list_unlock(smgt); if (on && wait_size_M > 0 && !is_tvp) { - u64 start_time = get_jiffies_64(); - int try_max = 10; - smgt->force_cache_on = 1; smgt->force_cache_page_cnt = wait_size_M >> PAGE_SHIFT; smgt->delay_free_timeout_jiffies64 = get_jiffies_64() + 10000 * HZ/1000; codec_mm_schedule_delay_work(smgt, 0, 1);/*start cache*/ +#if 0 while (smgt->total_page_num < smgt->force_cache_page_cnt) { if (smgt->cache_sc && (smgt->cached_pages >= @@ -2263,6 +2268,7 @@ int codec_mm_scatter_mgt_delay_free_swith( smgt->force_cache_on = 0; smgt->delay_free_timeout_jiffies64 = get_jiffies_64() + delay_ms * HZ/1000; +#endif } else if (on) { codec_mm_schedule_delay_work(smgt, 0, 1); } else { @@ -2288,8 +2294,11 @@ static void codec_mm_scatter_cache_manage( (smgt->no_cache_size_M * (SZ_1M >> PAGE_SHIFT)))) { /*have enough pages for most movies.*/ /*don't cache more.*/ - if (smgt->force_cache_on) - complete(&smgt->complete); + if (smgt->force_cache_on) { + smgt->force_cache_on = 0; + smgt->delay_free_timeout_jiffies64 = + get_jiffies_64() + 2000 * HZ/1000; + } } else if ((smgt->cached_pages < smgt->keep_size_PAGE) || (smgt->force_cache_on &&/*on star cache*/ (smgt->total_page_num < smgt->force_cache_page_cnt)) @@ -2333,7 +2342,9 @@ static void codec_mm_scatter_cache_manage( smgt->force_cache_on && (smgt->cached_pages >= smgt->force_cache_page_cnt)) { - complete(&smgt->complete); + smgt->force_cache_on = 0; + smgt->delay_free_timeout_jiffies64 = + get_jiffies_64() + 2000 * HZ/1000; } } else if ((smgt->cached_pages > (smgt->keep_size_PAGE + 1000)) && diff --git a/drivers/amlogic/media/common/ge2d/ge2d_wq.c b/drivers/amlogic/media/common/ge2d/ge2d_wq.c index ac4761a70df3..a35947df88de 100644 --- a/drivers/amlogic/media/common/ge2d/ge2d_wq.c +++ b/drivers/amlogic/media/common/ge2d/ge2d_wq.c @@ -1858,7 +1858,7 @@ int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) { struct ge2d_queue_item_s *pitem, *tmp; struct list_head *head; - int empty; + int empty, timeout = 0; if (ge2d_work_queue) { /* first detatch it from the process queue,then delete it . */ @@ -1870,9 +1870,11 @@ int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue) if ((ge2d_manager.current_wq == ge2d_work_queue) && (ge2d_manager.ge2d_state == GE2D_STATE_RUNNING)) { ge2d_work_queue->ge2d_request_exit = 1; - wait_for_completion_timeout( - &ge2d_manager.event.process_complete, - msecs_to_jiffies(500)); + timeout = wait_for_completion_timeout( + &ge2d_manager.event.process_complete, + msecs_to_jiffies(500)); + if (!timeout) + ge2d_log_err("wait timeout\n"); /* condition so complex ,simplify it . */ ge2d_manager.last_wq = NULL; } /* else we can delete it safely. */ diff --git a/drivers/amlogic/media/common/vfm/vfm.c b/drivers/amlogic/media/common/vfm/vfm.c index eaea9136f63d..a64c1808139c 100644 --- a/drivers/amlogic/media/common/vfm/vfm.c +++ b/drivers/amlogic/media/common/vfm/vfm.c @@ -368,17 +368,6 @@ static void vfm_init(void) #ifdef CONFIG_TVIN_VIUIN char def_ext_id[] = "default_ext"; char def_ext_name_chain[] = "vdin amvideo2"; -#else /**/ -#ifdef CONFIG_AMLOGIC_VIDEOIN_MANAGER - char def_ext_id0[] = "default_ext0"; - char def_ext_id1[] = "default_ext1"; -#ifdef CONFIG_AMLOGIC_VM_DISABLE_VIDEOLAYER - char def_ext_name_chain0[] = "vdin0 vm0"; - char def_ext_name_chain1[] = "vdin1 vm1"; -#else /**/ - char def_ext_name_chain[] = "vdin0 vm amvideo"; -#endif /**/ -#endif /**/ #endif /**/ #ifdef CONFIG_VDIN_MIPI char def_mipi_id[] = "default_mipi"; @@ -417,10 +406,7 @@ static void vfm_init(void) #ifdef CONFIG_VDIN_MIPI vfm_map_add(def_mipi_id, def_mipi_name_chain); #endif /**/ -#ifdef CONFIG_AMLOGIC_VIDEOIN_MANAGER - vfm_map_add(def_ext_id0, def_ext_name_chain0); - vfm_map_add(def_ext_id1, def_ext_name_chain1); -#endif /**/ + #if (defined CONFIG_TVIN_AFE) || (defined CONFIG_TVIN_HDMI) vfm_map_add(tvpath_id, tvpath_chain); #endif /**/ diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index bfb137868b30..4a0afc00e6e7 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -129,7 +129,7 @@ static di_dev_t *de_devp; static dev_t di_devno; static struct class *di_clsp; -static const char version_s[] = "2018-11-28b"; +static const char version_s[] = "2018-12-04a"; static int bypass_state = 1; static int bypass_all; @@ -263,7 +263,7 @@ static long same_field_bot_count; * 1, keep 4 buffers in pre_ready_list for checking; */ -static int post_hold_line = 17;/* for m8 1080i/50 output */ +static int post_hold_line = 8; /*2019-01-10: from VLSI feijun from 17 to 8*/ static int post_urgent = 1; /*pre process speed debug */ @@ -3383,6 +3383,8 @@ static unsigned char pre_de_buf_config(void) #endif ) return 0; + + di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); } else if (di_pre_stru.prog_proc_type == 2) { di_linked_buf_idx = peek_free_linked_buf(); if (di_linked_buf_idx == -1 && @@ -3923,14 +3925,17 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); di_pre_stru.madi_enable = 0; di_pre_stru.mcdi_enable = 0; di_buf->post_proc_flag = 0; + di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); } else if (bypass_post_state) { di_pre_stru.madi_enable = 0; di_pre_stru.mcdi_enable = 0; di_buf->post_proc_flag = 0; + di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); } else { di_pre_stru.madi_enable = (pre_enable_mask&1); di_pre_stru.mcdi_enable = ((pre_enable_mask>>1)&1); di_buf->post_proc_flag = 1; + di_patch_post_update_mc_sw(DI_MC_SW_OTHER, mcpre_en);//en } if ((di_pre_stru.di_mem_buf_dup_p == di_pre_stru.di_wr_buf) || (di_pre_stru.di_chan2_buf_dup_p == di_pre_stru.di_wr_buf)) { @@ -5903,7 +5908,7 @@ static void di_unreg_process_irq(void) #if (defined ENABLE_SPIN_LOCK_ALWAYS) spin_unlock_irqrestore(&plist_lock, flags); #endif - + di_patch_post_update_mc_sw(DI_MC_SW_REG, false); di_pre_stru.force_unreg_req_flag = 0; di_pre_stru.disable_req_flag = 0; recovery_flag = 0; @@ -6100,6 +6105,7 @@ static void di_reg_process_irq(void) vframe->width, vframe->height, vframe->type); } di_pre_stru.bypass_flag = true; + di_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); return; } else { di_pre_stru.bypass_flag = false; @@ -6198,6 +6204,8 @@ static void di_reg_process_irq(void) (vframe->source_type), is_progressive(vframe), vframe->sig_fmt); + + di_patch_post_update_mc_sw(DI_MC_SW_REG, true); if (de_devp->flags & DI_LOAD_REG_FLAG) up(&di_sema); init_flag = 1; @@ -6474,6 +6482,7 @@ static enum hrtimer_restart di_pre_hrtimer_func(struct hrtimer *timer) if (!di_pre_stru.bypass_flag) di_pre_trigger_work(&di_pre_stru); hrtimer_forward_now(&di_pre_hrtimer, ms_to_ktime(10)); + di_patch_post_update_mc(); return HRTIMER_RESTART; } /* @@ -7396,6 +7405,7 @@ static void set_di_flag(void) post_hold_line = (is_meson_g12a_cpu() || is_meson_g12b_cpu())?10:17; } else { + post_hold_line = 8; /*2019-01-10: from VLSI feijun*/ mcpre_en = false; pulldown_enable = false; di_pre_rdma_enable = false; @@ -7480,7 +7490,10 @@ static int di_probe(struct platform_device *pdev) di_devp->flags |= DI_SUSPEND_FLAG; cdev_init(&(di_devp->cdev), &di_fops); di_devp->cdev.owner = THIS_MODULE; - cdev_add(&(di_devp->cdev), di_devno, DI_COUNT); + ret = cdev_add(&(di_devp->cdev), di_devno, DI_COUNT); + if (ret) + goto fail_cdev_add; + di_devp->devt = MKDEV(MAJOR(di_devno), 0); di_devp->dev = device_create(di_clsp, &pdev->dev, di_devp->devt, di_devp, "di%d", 0); @@ -7630,6 +7643,15 @@ static int di_probe(struct platform_device *pdev) if (IS_ERR(di_devp->task)) pr_err("%s create kthread error.\n", __func__); di_debugfs_init(); /*2018-07-18 add debugfs*/ + di_patch_post_update_mc_sw(DI_MC_SW_IC, true); + + pr_info("%s:ok\n", __func__); + return ret; + +fail_cdev_add: + pr_info("%s:fail_cdev_add\n", __func__); + kfree(di_devp); + fail_kmalloc_dev: return ret; } diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index c59725886348..31b8fefd460a 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -2453,6 +2453,52 @@ mif->chroma_x_end0 - mif->chroma_x_start0 + 1, /* c length */ } } +static unsigned int di_mc_update; +void di_patch_post_update_mc(void) +{ + if (di_mc_update == DI_MC_SW_ON_MASK) { +// if (di_mc_update) { + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1); + } +} + + +void di_patch_post_update_mc_sw(unsigned int cmd, bool on) +{ + unsigned int l_flg = di_mc_update; + + switch (cmd) { + case DI_MC_SW_IC: + if (is_meson_gxtvbb_cpu() || + is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_txhd_cpu()) { + di_mc_update |= DI_MC_SW_IC; + } + break; + case DI_MC_SW_REG: + if (on) { + di_mc_update |= cmd; + di_mc_update &= ~DI_MC_SW_OTHER; + } else { + di_mc_update &= ~(cmd|DI_MC_SW_OTHER); + } + break; + case DI_MC_SW_OTHER: + +// case DI_MC_SW_POST: + if (on) + di_mc_update |= cmd; + else + di_mc_update &= ~cmd; + + break; + } + + if (l_flg != di_mc_update) + pr_debug("%s:0x%x->0x%x\n", __func__, l_flg, di_mc_update); + +} void initial_di_post_2(int hsize_post, int vsize_post, int hold_line, bool post_write_en) { @@ -2894,6 +2940,7 @@ void di_hw_disable(bool mc_enable) /* DI inp(current data) switch to memory */ DI_Wr_reg_bits(VIUB_MISC_CTRL0, 0, 16, 1); } + DI_Wr(DI_POST_CTRL, 0); } /* * old pulldown windows share below ctrl diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index 8d8b95d66a73..d6b44d529836 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -187,4 +187,14 @@ extern u8 *di_vmap(ulong addr, u32 size, bool *bflg); extern void di_unmap_phyaddr(u8 *vaddr); extern int di_print(const char *fmt, ...); +#define DI_MC_SW_OTHER (1<<0) +#define DI_MC_SW_REG (1<<1) +//#define DI_MC_SW_POST (1<<2) +#define DI_MC_SW_IC (1<<2) + +#define DI_MC_SW_ON_MASK (DI_MC_SW_REG | DI_MC_SW_OTHER | DI_MC_SW_IC) + +extern void di_patch_post_update_mc(void); +extern void di_patch_post_update_mc_sw(unsigned int cmd, bool on); + #endif diff --git a/drivers/amlogic/media/dtv_demod/aml_demod.c b/drivers/amlogic/media/dtv_demod/aml_demod.c index 285f1550e01a..ea2b742f3585 100644 --- a/drivers/amlogic/media/dtv_demod/aml_demod.c +++ b/drivers/amlogic/media/dtv_demod/aml_demod.c @@ -39,6 +39,7 @@ /* #include */ #include #include +#include /* #include */ #include @@ -269,6 +270,9 @@ static long aml_demod_ioctl(struct file *file, int strength = 0; struct dvb_frontend *dvbfe; struct aml_tuner_sys *tuner; + //struct aml_tuner_sys tuner_para = {0}; + struct aml_demod_reg arg_t; + //static unsigned int tuner_attach_flg; switch (cmd) { case AML_DEMOD_GET_RSSI: @@ -290,12 +294,37 @@ static long aml_demod_ioctl(struct file *file, case AML_DEMOD_SET_TUNER: pr_dbg("Ioctl Demod Set Tuner.\n"); dvbfe = aml_get_fe();/*get_si2177_tuner();*/ + #if 0 + if (copy_from_user(&tuner_para, (void __user *)arg, + sizeof(struct aml_tuner_sys))) { + pr_dbg("copy error AML_DEMOD_SET_REG\n"); + } else { + //pr_dbg("dvbfe = %p\n",dvbfe); + pr_dbg("tuner mode = %d\n", tuner_para.mode); + if (tuner_attach_flg == 0) { + attach_tuner_demod(); + tuner_attach_flg = 1; + } + + tuner_set_freq(tuner_para.ch_freq); + + if (tuner_para.mode == FE_ATSC) { + tuner_config_atsc(); + tuner_set_atsc_para(); + } else if (tuner_para.mode == FE_DTMB) { + tuner_config_dtmb(); + tuner_set_dtmb_para(); + } else if (tuner_para.mode == FE_QAM) { + tuner_config_qam(); + tuner_set_qam_para(); + } + } + #endif #if 0 /*ary temp for my_tool:*/ - if (dvbfe != NULL) - dvbfe->ops.tuner_ops.set_tuner(dvbfe, &demod_sta, - &demod_i2c, - (struct aml_tuner_sys *) - arg); + if (dvbfe != NULL) { + pr_dbg("calling tuner ops\n"); + dvbfe->ops.tuner_ops.set_params(dvbfe); + } #endif break; @@ -385,12 +414,27 @@ static long aml_demod_ioctl(struct file *file, case AML_DEMOD_SET_REG: /* pr_dbg("Ioctl Set Register\n"); */ - demod_set_reg((struct aml_demod_reg *)arg); + if (copy_from_user(&arg_t, (void __user *)arg, + sizeof(struct aml_demod_reg))) { + pr_dbg("copy error AML_DEMOD_SET_REG\n"); + } else + demod_set_reg(&arg_t); + + //demod_set_reg((struct aml_demod_reg *)arg); break; case AML_DEMOD_GET_REG: /* pr_dbg("Ioctl Get Register\n"); */ - demod_get_reg((struct aml_demod_reg *)arg); + if (copy_from_user(&arg_t, (void __user *)arg, + sizeof(struct aml_demod_reg))) + pr_dbg("copy error AML_DEMOD_GET_REG\n"); + else + demod_get_reg(&arg_t); + + if (copy_to_user((void __user *)arg, &arg_t, + sizeof(struct aml_demod_reg))) { + pr_dbg("copy_to_user copy error AML_DEMOD_GET_REG\n"); + } break; /* case AML_DEMOD_SET_REGS: */ @@ -449,6 +493,288 @@ static const struct file_operations aml_demod_fops = { #endif }; +#if 0 +static int aml_demod_dbg_open(struct inode *inode, struct file *file) +{ + pr_dbg("Amlogic Demod debug Open\n"); + return 0; +} + +static int aml_demod_dbg_release(struct inode *inode, struct file *file) +{ + pr_dbg("Amlogic Demod debug Release\n"); + return 0; +} + +static unsigned int addr_for_read; +static unsigned int register_val; +static unsigned int symb_rate; +static unsigned int ch_freq; +static unsigned int modulation; +static char *dbg_name[] = { + "demod top r/w", + "dvbc r/w", + "atsc r/w", + "dtmb r/w", + "front r/w", + "isdbt r/w", + "dvbc init", + "atsc init", + "dtmb init", +}; + +unsigned int get_symbol_rate(void) +{// / 1000 + return symb_rate; +} + +unsigned int get_ch_freq(void) +{// / 1000 + return ch_freq; +} + +unsigned int get_modu(void) +{ + return modulation; +} + +/* + *TVFE_VAFE_CTRL0 0x000d0710 + *TVFE_VAFE_CTRL1 0x00003000 + *TVFE_VAFE_CTRL2 0x1fe09e31 + *HHI_DADC_CNTL 0x0030303c + *HHI_DADC_CNTL2 0x00003480 + *HHI_DADC_CNTL3 0x08700b83 + *HHI_VDAC_CNTL1 0x0000000 + + *ADC_PLL_CNTL0 0X012004e0 + *ADC_PLL_CNTL0 0X312004e0 + *ADC_PLL_CNTL1 0X05400000 + *ADC_PLL_CNTL2 0xe1800000 + *ADC_PLL_CNTL3 0x48681c00 + *ADC_PLL_CNTL4 0x88770290 + *ADC_PLL_CNTL5 0x39272000 + *ADC_PLL_CNTL6 0x56540000 + *ADC_PLL_CNTL0 0X111104e0 + */ +static void aml_demod_adc_init(void) +{ + PR_INFO("%s\n", __func__); + demod_init_mutex(); + demod_power_switch(PWR_ON); + //TVFE_VAFE_CTRL0 + demod_set_tvfe_reg(0x000d0710, 0xff654ec0); + //TVFE_VAFE_CTRL1 + demod_set_tvfe_reg(0x00003000, 0xff654ec4); + //TVFE_VAFE_CTRL2 + demod_set_tvfe_reg(0x1fe09e31, 0xff654ec8); + //HHI_DADC_CNTL + dd_tvafe_hiu_reg_write(0x9c, 0x0030303c); + //HHI_DADC_CNTL2 + dd_tvafe_hiu_reg_write(0xa0, 0x00003480); + //HHI_DADC_CNTL3 + //dd_tvafe_hiu_reg_write(0xa8, 0x08700b83); + dd_tvafe_hiu_reg_write(0xa8, 0x08300b83); + //HHI_VDAC_CNTL1 + dd_tvafe_hiu_reg_write(0x2f0, 0x0000000); + //ADC_PLL_CNTL0 + dd_tvafe_hiu_reg_write(0x2c0, 0X012004e0); + dd_tvafe_hiu_reg_write(0x2c0, 0X312004e0); + //ADC_PLL_CNTL1 + dd_tvafe_hiu_reg_write(0x2c4, 0X05400000); + //ADC_PLL_CNTL2 + //dd_tvafe_hiu_reg_write(0x2c8, 0xe1800000); + dd_tvafe_hiu_reg_write(0x2c8, 0xE0800000);//shijie modify, crystal 24M + //dd_tvafe_hiu_reg_write(0x2c8, 0xe9800000); + //ADC_PLL_CNTL3 + dd_tvafe_hiu_reg_write(0x2cc, 0x48681c00); + //ADC_PLL_CNTL4 + dd_tvafe_hiu_reg_write(0x2d0, 0x88770290); + //ADC_PLL_CNTL5 + dd_tvafe_hiu_reg_write(0x2d4, 0x39272000); + //ADC_PLL_CNTL6 + dd_tvafe_hiu_reg_write(0x2d8, 0x56540000); + //ADC_PLL_CNTL0 + dd_tvafe_hiu_reg_write(0x2c0, 0X111104e0); + //zou weihua + dd_tvafe_hiu_reg_write(0x3cc, 0x00800000); + //shijie + dd_tvafe_hiu_reg_write(0x1d0, 0x501);//0x705 + //shixi, switch to demod mode, enable pclk + //demod_write_reg(DEMOD_TOP_REG0, 0x11); + dtvpll_init_flag(1); +} + +static ssize_t aml_demod_dbg_show(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[80]; + ssize_t len = 0; + + #if 1 + len = snprintf(buf, sizeof(buf), "%s :0x%x = %i\n", + dbg_name[addr_for_read >> 28], addr_for_read & 0xff, + register_val); + #else + len = snprintf(buf, sizeof(buf), "%s\n", __func__); + #endif + //demod_read_reg(DEMOD_TOP_REGC); + //dtmb_read_reg(0); + //dd_tvafe_hiu_reg_write(0x9c, 0x0030303c); + PR_INFO("%s\n", __func__); + //PR_INFO("0xec0 = 0x%x\n", dd_tvafe_hiu_reg_read(0x9c)); + //dvbt_read_reg(0x38); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +/*echo dbg_md [0xaddr] [val] > /sys/kernel/debug/demod/xxxx*/ +static ssize_t aml_demod_dbg_store(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + char buf[80]; + unsigned int reg, val, dbg_md; + int ret; + + count = min_t(size_t, count, (sizeof(buf)-1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%d %x %i", &dbg_md, ®, &val); + aml_demod_adc_init(); + + switch (ret) { + case 1://cmd + switch (dbg_md) { + case AML_DBG_DVBC_INIT: + Gxtv_Demod_Dvbc_v4_Init(); + break; + case AML_DBG_ATSC_INIT: + demod_set_sys_atsc_v4(); + break; + case AML_DBG_DTMB_INIT: + break; + default: + break; + } + + PR_INFO("%s\n", dbg_name[dbg_md]); + break; + case 2://read register, set param + switch (dbg_md) { + case AML_DBG_DEMOD_TOP_RW: + addr_for_read = (AML_DBG_DEMOD_TOP_RW << 28) | reg; + register_val = demod_read_reg(reg); + break; + case AML_DBG_DVBC_RW: + addr_for_read = (AML_DBG_DVBC_RW << 28) | reg; + register_val = dvbc_read_reg(reg); + break; + case AML_DBG_ATSC_RW: + addr_for_read = (AML_DBG_ATSC_RW << 28) | reg; + register_val = atsc_read_reg_v4(reg); + break; + case AML_DBG_DTMB_RW: + addr_for_read = (AML_DBG_DTMB_RW << 28) | reg; + register_val = dtmb_read_reg(reg); + break; + case AML_DBG_FRONT_RW: + addr_for_read = (AML_DBG_FRONT_RW << 28) | reg; + register_val = front_read_reg_v4(reg); + break; + case AML_DBG_ISDBT_RW: + addr_for_read = (AML_DBG_ISDBT_RW << 28) | reg; + register_val = isdbt_read_reg_v4(reg); + break; + case AML_DBG_DEMOD_SYMB_RATE: + symb_rate = reg; + break; + case AML_DBG_DEMOD_CH_FREQ: + ch_freq = reg; + break; + case AML_DBG_DEMOD_MODUL: + modulation = reg; + break; + default: + break; + } + + PR_INFO("%s reg:0x%x\n", dbg_name[dbg_md], reg); + break; + case 3://write register + switch (dbg_md) { + case AML_DBG_DEMOD_TOP_RW: + demod_write_reg(reg, val); + break; + case AML_DBG_DVBC_RW: + dvbc_write_reg(reg, val); + break; + case AML_DBG_ATSC_RW: + atsc_write_reg_v4(reg, val); + break; + case AML_DBG_DTMB_RW: + dtmb_write_reg(reg, val); + break; + case AML_DBG_FRONT_RW: + front_write_reg_v4(reg, val); + break; + case AML_DBG_ISDBT_RW: + isdbt_write_reg_v4(reg, val); + break; + default: + break; + } + + PR_INFO("%s reg:0x%x,val=%d\n", dbg_name[dbg_md], reg, val); + break; + default: + return -EINVAL; + } + + return count; +} + +static const struct file_operations aml_demod_dvbc_dbg_fops = { + .owner = THIS_MODULE, + .open = aml_demod_dbg_open, + .release = aml_demod_dbg_release, + //.unlocked_ioctl = aml_demod_ioctl, + .read = aml_demod_dbg_show, + .write = aml_demod_dbg_store, +}; + +static void aml_demod_dbg_init(void) +{ + struct dentry *root_entry = dtvdd_devp->demod_root; + struct dentry *entry; + + PR_INFO("%s\n", __func__); + + root_entry = debugfs_create_dir("frontend", NULL); + if (!root_entry) { + PR_INFO("Can't create debugfs dir frontend.\n"); + return; + } + + entry = debugfs_create_file("demod", S_IFREG | 0644, root_entry, NULL, + &aml_demod_dvbc_dbg_fops); + if (!entry) { + PR_INFO("Can't create debugfs file demod.\n"); + return; + } +} + +static void aml_demod_dbg_exit(void) +{ + struct dentry *root_entry = dtvdd_devp->demod_root; + + if (dtvdd_devp && root_entry) + debugfs_remove_recursive(root_entry); +} +#endif + static int aml_demod_ui_open(struct inode *inode, struct file *file) { pr_dbg("Amlogic aml_demod_ui_open Open\n"); @@ -662,6 +988,7 @@ static int __init aml_demod_init(void) sdio_init(); #endif aml_demod_ui_init(); + //aml_demod_dbg_init(); return 0; @@ -701,6 +1028,7 @@ static void __exit aml_demod_exit(void) class_unregister(&aml_demod_class); aml_demod_exit_ui(); + //aml_demod_dbg_exit(); } #ifndef CONFIG_AM_DEMOD_DVBAPI diff --git a/drivers/amlogic/media/dtv_demod/amlfrontend.c b/drivers/amlogic/media/dtv_demod/amlfrontend.c index 8337e0b04734..0e9f226f8531 100644 --- a/drivers/amlogic/media/dtv_demod/amlfrontend.c +++ b/drivers/amlogic/media/dtv_demod/amlfrontend.c @@ -39,7 +39,6 @@ #include #include - #ifdef ARC_700 #include #else @@ -78,7 +77,7 @@ module_param(std_lock_timeout, int, 0644); static char *demod_version = "V0.03"; -int aml_demod_debug = DBG_INFO|DBG_ATSC; +int aml_demod_debug = DBG_INFO; #if 0 @@ -158,6 +157,7 @@ const char *name_ic[] = { "txlx", "gxlx", "txhd", + "tl1", }; #define END_SYS_DELIVERY 19 @@ -197,7 +197,6 @@ static void dtvdemod_set_agc_pinmux(int on); static int Gxtv_Demod_Dvbc_Init(/*struct aml_fe_dev *dev, */int mode); - static ssize_t dvbc_auto_sym_show(struct class *cls, struct class_attribute *attr, char *buf) { @@ -709,11 +708,16 @@ static int amdemod_stat_islock(/*struct aml_fe_dev *dev,*/ int mode) if ((atsc_read_iqr_reg() >> 16) == 0x1f) ret = 1; } else if (atsc_mode == VSB_8) { + if (is_ic_ver(IC_VER_TL1)) { + if (atsc_read_reg_v4(0x2e) >= 0x76) + ret = 1; + } else { atsc_fsm = atsc_read_reg(0x0980); PR_DBGL("atsc status [%x]\n", atsc_fsm); /*return atsc_read_reg(0x0980) >= 0x79;*/ if (atsc_read_reg(0x0980) >= 0x79) ret = 1; + } } else { atsc_fsm = atsc_read_reg(0x0980); PR_DBGL("atsc status [%x]\n", atsc_fsm); @@ -726,7 +730,6 @@ static int amdemod_stat_islock(/*struct aml_fe_dev *dev,*/ int mode) } else if (mode == 4) { /*DTMB*/ - /*return (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1;*/ return dtmb_reg_r_fec_lock(); } @@ -919,7 +922,10 @@ int timer_tuner_not_enough(void) } - +unsigned int demod_get_adc_clk(void) +{ + return demod_status.adc_freq; +} static int gxtv_demod_dvbc_read_status_timer (struct dvb_frontend *fe, enum fe_status *status) @@ -1028,12 +1034,17 @@ static int gxtv_demod_dvbc_set_frontend(struct dvb_frontend *fe) param.mode = amdemod_qam(c->modulation); param.symb_rate = c->symbol_rate / 1000; store_dvbc_qam_mode(c->modulation, param.symb_rate); - if ((param.mode == 3) && (demod_status.tmp != Adc_mode)) { - Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode); - /*pr_dbg("Gxtv_Demod_Dvbc_Init,Adc_mode\n");*/ - } else { - /*Gxtv_Demod_Dvbc_Init(dev,Cry_mode);*/ + + if (!is_ic_ver(IC_VER_TL1)) { + if ((param.mode == 3) && (demod_status.tmp != Adc_mode)) { + Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode); + /*pr_dbg("Gxtv_Demod_Dvbc_Init,Adc_mode\n");*/ + } else { + /*Gxtv_Demod_Dvbc_Init(dev,Cry_mode);*/ + } } + + if (autoflags == 0) { /*pr_dbg("QAM_TUNING mode\n");*/ /*flag=0;*/ @@ -1108,6 +1119,13 @@ static int Gxtv_Demod_Dvbc_Init(/*struct aml_fe_dev *dev, */int mode) sys.demod_clk = Demod_Clk_72M; demod_status.tmp = Cry_mode; } + + if (is_ic_ver(IC_VER_TL1)) { + sys.adc_clk = Adc_Clk_24M; + sys.demod_clk = Demod_Clk_167M; + demod_status.tmp = Cry_mode; + } + demod_status.ch_if = Si2176_5M_If * 1000; PR_DBG("[%s]adc_clk is %d,demod_clk is %d\n", __func__, sys.adc_clk, sys.demod_clk); @@ -1118,6 +1136,194 @@ static int Gxtv_Demod_Dvbc_Init(/*struct aml_fe_dev *dev, */int mode) return 0; } +#if 0 +/*TL1*/ +void Gxtv_Demod_Dvbc_v4_Init(void) +{ + //struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct aml_demod_dvbc dvbc; + int nco_rate; + int tmp; + + //printf("frequency point is(KHz):"); + //scanf("%d", &tmp); + //dvbc.ch_freq = tmp; + //dvbc.ch_freq = 474000; + dvbc.ch_freq = 474000; + //dvbc.mode = tmp; + dvbc.mode = 4;// 0=16QAM, 1=32QAM, 2 = 64QAM, 3 = 128QAM, 4 = 256QAM + //dvbc.symb_rate = tmp; + dvbc.symb_rate = 5360;//6875;5056(J.83b 64QAM),5360(J.83b 256QAM) + //ioctl(fd, AML_DEMOD_DVBC_SET_CH, &dvbc); + dvbc.dat0 = 24000; + nco_rate = (24*256)/250+2; + + //app_apb_write_reg(0xf00*4,0x88); + demod_write_reg(DEMOD_TOP_REG0, 0x88); + //app_apb_write_reg(0xf08*4,0x201); + demod_write_reg(DEMOD_TOP_REG8, 0x201); + //app_apb_write_reg(0xf0c*4,0x11); //open write enable + demod_write_reg(DEMOD_TOP_REGC, 0x11); + //app_apb_write_reg(0xe20, + //((app_apb_read_reg(0xe20) &~ 0xff) | (nco_rate & 0xff))); + //app_apb_write_reg(0xe20, (app_apb_read_reg(0xe20) | (1 << 8))); + front_write_reg_v4(0x20, + ((front_read_reg_v4(0x20) & ~0xff) | (nco_rate & 0xff))); + front_write_reg_v4(0x20, (front_read_reg_v4(0x20) | (1 << 8))); + + //dvbc_reg_initial_tmp(&dvbc); + dvbc_reg_initial_tmp_v4(&dvbc); + + //printf("set J.83B(1) OR DVBC(2)"); + tmp = 2; + if (tmp == 1) { + //app_apb_write_reg(reg_reset,0x10f33); + qam_write_reg(0x7, 0x10f33); + //set_j83b_filter_reg(); + set_j83b_filter_reg_v4(); + } else { + //app_apb_write_reg(reg_reset,0xf33); + qam_write_reg(0x7, 0xf33); + } + + #if 0 + printf("select 0~3 mode:"); + scanf("%d", &tmp); + if (tmp == 0) { + //set_dvbc_reg_1(); + set_dvbc_reg_1_v4(); + //set_dvbc_reg_2(); + set_dvbc_reg_2_v4(); + } else if (tmp == 1) { + //set_dvbc_reg_1(); + set_dvbc_reg_1_v4(); + //set_j83b_reg_2(); + set_j83b_reg_2_v4(); + } else if (tmp == 2) { + //set_j83b_reg_1(); + set_j83b_reg_1_v4(); + //set_dvbc_reg_2(); + set_dvbc_reg_2_v4(); + } else if (tmp == 3) { + //set_j83b_reg_1(); + set_j83b_reg_1_v4(); + //set_j83b_reg_2(); + set_j83b_reg_2_v4(); + } + #endif + + #if 0 + app_apb_write_reg(0x48, 0x50e1000); + app_apb_write_reg(0xc0, 0x41f2f69); + #else + qam_write_reg(0x12, 0x50e1000); + qam_write_reg(0x30, 0x41f2f69); + #endif +} + +int uart_error_confirm(int a_0, int a_1) +{ + int flag_out_of_range; + int flag_error; + int flag_zero; + int flag_sta_check; + int st[2]; + int out; + + st[0] = a_0&0xf; + st[1] = (a_0>>4)&0xf; + if (st[1] == 0) + flag_sta_check = ((st[0] == 1) || (st[0] == 2)) ? 0 : 1; + if (st[1] == 1) + flag_sta_check = ((st[0] == 2) || (st[0] == 3)) ? 0 : 1; + if (st[1] == 2) + flag_sta_check = (st[0] == 3) ? 0 : 1; + if (st[1] == 3) + flag_sta_check = (st[0] == 4) ? 0 : 1; + if (st[1] == 4) + flag_sta_check = (st[0] == 6) ? 0 : 1; + if (st[1] == 6) + flag_sta_check = ((st[0] == 4) || (st[0] == 5)) ? 0 : 1; + + flag_zero = (a_0 == 0) ? 1 : 0; + flag_out_of_range = ((a_0 & 0xf) > 6) ? 1 : 0; + flag_error = (((a_0 >> 4) & 0x0fffffff) == (a_1 & 0x0fffffff)) ? 0 : 1; + out = ((flag_out_of_range == 1) || (flag_error == 1) + || (flag_zero == 1)) ? 1 : 0; + return out; +} + +void print_dvbc_result(void) +{ + //int timer1, + int time; + int i, tmp; + //float ftmp; + //struct aml_demod_sts sts; + int status[2], uart_error; + int record = 6, cnt = 0, cur_res = 0; + + //timer1 = read_time_usecond(); + status[0] = status[1] = 0; + time = 1; + i = 0; + while (i < time) { + status[0] = qam_read_reg(0x31); + //if((status[0]&0xf) == 5){ + // timer2=read_time_usecond(); + // printf("\n\n\n\n[sync timer]%d\n",timer2-timer1); + // break; + //} + uart_error = uart_error_confirm(status[0], status[1]); + usleep_range(10000, 10001); + status[1] = status[0]; + i = i + 1; + + //lg add state cnt + cur_res = status[1] & 0xf; + if (cur_res != 6) { + record = cur_res; + } else { + if (record != cur_res) + cnt++; + record = cur_res; + } + + // ioctl(fd, AML_DEMOD_DVBC_GET_CH, &sts); + //tmp = sts.ch_sts; + PR_INFO("sta %08x ulock_n %d ", qam_read_reg(0x6), cnt); + //ftmp = sts.ch_snr; + //ftmp /= 100.0; + //ftmp=(app_apb_read_reg(0x174)&0xfff0)/16/32; + //ftmp=(dvbc_read_reg(0x174)&0xfff0)/16/32; + //PR_INFO("snr %5.2f dB ", ftmp); + PR_INFO("eq status is %d ", qam_read_reg(0x5d)&0xf); + PR_INFO("npn_det %d impdet %d imp_n %d ", + qam_read_reg(0x58)>>20&0x1, qam_read_reg(0x58)>>16&0x3, + qam_read_reg(0x58)&0xffff); + // ftmp = sts.ch_ber; + // ftmp /= 1e6; + // printf("ber %.2e ", ftmp); + // if(ber_avg == 0) + // ber_avg = ftmp; + // ber_avg = ber_avg + (ftmp-ber_avg)/32; + // printf("beravg %.2e ", ber_avg); + tmp = (qam_read_reg(0x33)&0xffff); + //tmp = sts.ch_per; + PR_INFO("per %d ", tmp); + //ftmp=(dvbc_read_reg(0x34)&0xffff)/1e3; + // ftmp = sts.symb_rate; + //PR_INFO("srate %.3f ", ftmp); + //ftmp = (dvbc_read_reg(0x28)&0x7fffff)/1e3; + //PR_INFO("freqoff %.3f kHz ", ftmp); + tmp = (qam_read_reg(0x27)); + //PR_INFO("power %ddb,gain %.3d ", + //((tmp>>22) & 0x1ff)/16.0, tmp & 0x7ff); + PR_INFO("lock sta %x\n", qam_read_reg(0x6)); + } +} +#endif + static void gxtv_demod_dvbt_release(struct dvb_frontend *fe) { @@ -1385,10 +1591,13 @@ static int gxtv_demod_atsc_read_status && (atsc_flag == VSB_8)) { /*atsc_thread();*/ s = amdemod_atsc_stat_islock(); - if ((s == 0) && (last_lock == 1) - && (atsc_read_reg(0x0980) >= 0x76)) { - s = 1; - PR_ATSC("[rsj] unlock,but fsm >= 0x76\n"); + + if (!is_ic_ver(IC_VER_TL1)) { + if ((s == 0) && (last_lock == 1) + && (atsc_read_reg(0x0980) >= 0x76)) { + s = 1; + PR_ATSC("[rsj] unlock,but fsm >= 0x76\n"); + } } } #if 0 /*debug only move to end*/ @@ -1408,8 +1617,17 @@ static int gxtv_demod_atsc_read_status FE_HAS_VITERBI | FE_HAS_SYNC; } else { ilock = 0; - - *status = FE_TIMEDOUT; + if (is_ic_ver(IC_VER_TL1)) { + if (timer_not_enough(D_TIMER_DETECT)) { + *status = 0; + PR_DBG("s=0\n"); + } else { + *status = FE_TIMEDOUT; + timer_disable(D_TIMER_DETECT); + } + } else { + *status = FE_TIMEDOUT; + } #if 0 if (ats_thread_flg) *status = FE_TIMEDOUT; @@ -1418,9 +1636,9 @@ static int gxtv_demod_atsc_read_status #endif } -#if 0 /*debug only*/ +#if 1 /*debug only*/ if (last_lock != ilock) { - pr_error("%s.\n", + PR_INFO("%s.\n", ilock ? "!! >> LOCK << !!" : "!! >> UNLOCK << !!"); last_lock = ilock; } @@ -1518,6 +1736,9 @@ static int gxtv_demod_atsc_set_frontend(struct dvb_frontend *fe) struct aml_demod_atsc param_atsc; struct aml_demod_dvbc param_j83b; int temp_freq = 0; + union ATSC_DEMOD_REG_0X6A_BITS Val_0x6a; + union ATSC_CNTR_REG_0X20_BITS Val_0x20; + int nco_rate; memset(¶m_atsc, 0, sizeof(param_atsc)); memset(¶m_j83b, 0, sizeof(param_j83b)); @@ -1534,7 +1755,9 @@ static int gxtv_demod_atsc_set_frontend(struct dvb_frontend *fe) if (atsc_flag != QAM_AUTO) atsc_flag = QAM_AUTO; /* demod_set_demod_reg(0x502, TXLX_ADC_REG6);*/ - dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x502); + if (!is_ic_ver(IC_VER_TL1)) + dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x502); + demod_set_mode_ts(Gxtv_Dvbc); param_j83b.ch_freq = c->frequency / 1000; param_j83b.mode = amdemod_qam(c->modulation); @@ -1544,17 +1767,71 @@ static int gxtv_demod_atsc_set_frontend(struct dvb_frontend *fe) param_j83b.symb_rate = 5361; else param_j83b.symb_rate = 5361; + + if (is_ic_ver(IC_VER_TL1)) { + //for timeshift mosaic + demod_status.clk_freq = Demod_Clk_167M; + nco_rate = (demod_status.adc_freq * 256) + / demod_status.clk_freq + 2; + front_write_reg_v4(0x20, + ((front_read_reg_v4(0x20) & ~0xff) + | (nco_rate & 0xff))); + front_write_reg_v4(0x2f, 0x5);//for timeshift mosaic + dd_tvafe_hiu_reg_write(0x1d0, 0x502);//sys_clk=167M + } + dvbc_set_ch(&demod_status, /*&demod_i2c, */¶m_j83b); + + if (is_ic_ver(IC_VER_TL1)) { + qam_write_reg(0x7, 0x10f33); + set_j83b_filter_reg_v4(); + qam_write_reg(0x12, 0x50e1000); + qam_write_reg(0x30, 0x41f2f69); + //for timeshift mosaic issue + //qam_write_reg(0x84, 0x2190000); + } + } else if (c->modulation > QAM_AUTO) { - if (atsc_flag != VSB_8) - atsc_flag = VSB_8; - /*demod_set_demod_reg(0x507, TXLX_ADC_REG6);*/ - dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x507); - demod_set_mode_ts(Gxtv_Atsc); - param_atsc.ch_freq = c->frequency / 1000; - param_atsc.mode = c->modulation; - atsc_set_ch(&demod_status, /*&demod_i2c,*/ ¶m_atsc); + if (is_ic_ver(IC_VER_TL1)) { + //demod_set_sys_atsc_v4(); + Val_0x6a.bits = atsc_read_reg_v4(ATSC_DEMOD_REG_0X6A); + Val_0x6a.b.peak_thd = 0x6;//Let CCFO Quality over 6 + atsc_write_reg_v4(ATSC_DEMOD_REG_0X6A, Val_0x6a.bits); + atsc_write_reg_v4(ATSC_EQ_REG_0XA5, 0x8c); + + if (demod_status.adc_freq == Adc_Clk_24M) { + atsc_write_reg_v4(ATSC_DEMOD_REG_0X54, + 0x1aaaaa); + + atsc_write_reg_v4(ATSC_DEMOD_REG_0X55, + 0x3ae28d); + + atsc_write_reg_v4(ATSC_DEMOD_REG_0X6E, + 0x16e3600); + } + + atsc_write_reg_v4(0x12, 0x18);//for timeshift mosaic + Val_0x20.bits = atsc_read_reg_v4(ATSC_CNTR_REG_0X20); + Val_0x20.b.cpu_rst = 1; + atsc_write_reg_v4(ATSC_CNTR_REG_0X20, Val_0x20.bits); + Val_0x20.b.cpu_rst = 0; + atsc_write_reg_v4(ATSC_CNTR_REG_0X20, Val_0x20.bits); + usleep_range(5000, 5001); + } else { + if (atsc_flag != VSB_8) + atsc_flag = VSB_8; + /*demod_set_demod_reg(0x507, TXLX_ADC_REG6);*/ + dd_tvafe_hiu_reg_write(D_HHI_DEMOD_CLK_CNTL, 0x507); + demod_set_mode_ts(Gxtv_Atsc); + param_atsc.ch_freq = c->frequency / 1000; + param_atsc.mode = c->modulation; + atsc_set_ch(&demod_status, /*&demod_i2c,*/ ¶m_atsc); + } } + + if (is_ic_ver(IC_VER_TL1)) + return 0; + if ((auto_search_std == 1) && ((c->modulation <= QAM_AUTO) && (c->modulation != QPSK))) { unsigned char s = 0; @@ -1661,10 +1938,16 @@ void atsc_detect_first(struct dvb_frontend *fe, enum fe_status *status) check_ok = 0; for (cnt = 0; cnt < CNT_FIRST_ATSC; cnt++) { - gxtv_demod_atsc_read_ucblocks(fe, &ucblocks); + if (!is_ic_ver(IC_VER_TL1)) + gxtv_demod_atsc_read_ucblocks(fe, &ucblocks); gxtv_demod_atsc_read_status(fe, &s); + if (is_ic_ver(IC_VER_TL1)) { + *status = s; + break; + } + // *status = s; if (s != 0x1f) { @@ -1720,6 +2003,11 @@ static int atsc_j83b_detect_first(struct dvb_frontend *fe, enum fe_status *s) for (cnt = 0; cnt < CNT_FIRST; cnt++) { gxtv_demod_atsc_read_status(fe, &cs); + if (is_ic_ver(IC_VER_TL1)) { + *s = cs; + return 0; + } + if (cs != 0x1f) { /*msleep(200);*/ PR_DBG("[j.83b] 1\n"); @@ -1821,7 +2109,6 @@ void atsc_polling(struct dvb_frontend *fe, enum fe_status *status) } - static int gxtv_demod_atsc_tune(struct dvb_frontend *fe, bool re_tune, unsigned int mode_flags, unsigned int *delay, enum fe_status *status) { @@ -1843,6 +2130,9 @@ static int gxtv_demod_atsc_tune(struct dvb_frontend *fe, bool re_tune, /*PR_ATSC("delivery_system=%d\n", aml_demod_delivery_sys);*/ gxtv_demod_atsc_set_frontend(fe); + if (is_ic_ver(IC_VER_TL1)) + timer_begain(D_TIMER_DETECT); + if (c->modulation == QPSK) { PR_ATSC("modulation is QPSK do nothing!"); } else if (c->modulation <= QAM_AUTO) { @@ -1860,7 +2150,15 @@ static int gxtv_demod_atsc_tune(struct dvb_frontend *fe, bool re_tune, return 0; } #endif - atsc_polling(fe, status); + if (is_ic_ver(IC_VER_TL1)) { + if (c->modulation > QAM_AUTO) + atsc_detect_first(fe, status); + else if (c->modulation <= QAM_AUTO && + (c->modulation != QPSK)) + atsc_j83b_detect_first(fe, status); + } else { + atsc_polling(fe, status); + } return 0; @@ -1930,7 +2228,10 @@ int Gxtv_Demod_Atsc_Init(void/*struct aml_fe_dev *dev*/) /* 0 -DVBC, 1-DVBT, ISDBT, 2-ATSC*/ demod_status.dvb_mode = Gxtv_Atsc; sys.adc_clk = Adc_Clk_24M; /*Adc_Clk_26M;*/ - sys.demod_clk = Demod_Clk_225M; /*Demod_Clk_71M;//Demod_Clk_78M;*/ + if (is_ic_ver(IC_VER_TL1)) + sys.demod_clk = Demod_Clk_250M; + else + sys.demod_clk = Demod_Clk_225M; demod_status.ch_if = 5000; demod_status.tmp = Adc_mode; /*demod_set_sys(&demod_status, &i2c, &sys);*/ @@ -1967,6 +2268,7 @@ void dtmb_save_status(unsigned int s) pollm->last_s = FE_TIMEDOUT; } } + void dtmb_poll_start(void) { struct poll_machie_s *pollm = &dtvdd_devp->poll_machie; @@ -2212,7 +2514,8 @@ static int gxtv_demod_dtmb_read_status_old if (is_dtmb_ver(IC_DTMB_V2)) { s = dtmb_check_status_gxtv(fe); } else if (is_dtmb_ver(IC_DTMB_V3)) { - s = dtmb_check_status_txl(fe); + if (!is_ic_ver(IC_VER_TL1)) + s = dtmb_check_status_txl(fe); } else { PR_ERR("%s:not support %d!\n", __func__, get_dtmb_ver()); @@ -2240,6 +2543,7 @@ static int gxtv_demod_dtmb_read_status_old static int gxtv_demod_dtmb_read_ber(struct dvb_frontend *fe, u32 *ber) { + *ber = 0; return 0; } @@ -2288,6 +2592,7 @@ static int gxtv_demod_dtmb_set_frontend(struct dvb_frontend *fe) tuner_set_params(fe); /*aml_fe_analog_set_frontend(fe);*/ msleep(100); /* demod_power_switch(PWR_ON); */ + dtmb_set_ch(&demod_status, /*&demod_i2c,*/ ¶m); return 0; @@ -2320,6 +2625,9 @@ int Gxtv_Demod_Dtmb_Init(struct amldtvdemod_device_s *dev) if (is_ic_ver(IC_VER_TXL)) { sys.adc_clk = Adc_Clk_25M; sys.demod_clk = Demod_Clk_225M; + } else if (is_ic_ver(IC_VER_TL1)) { + sys.adc_clk = Adc_Clk_24M; + sys.demod_clk = Demod_Clk_250M; } else { sys.adc_clk = Adc_Clk_24M; sys.demod_clk = Demod_Clk_225M; @@ -2373,6 +2681,11 @@ static int gxtv_demod_dvbc_tune(struct dvb_frontend *fe, bool re_tune, gxtv_demod_dvbc_read_status_timer(fe, status); + #if 0 + if (is_ic_ver(IC_VER_TL1)) + return ret; + #endif + if (*status & FE_HAS_LOCK) { timer_disable(D_TIMER_SET); } else { @@ -2406,6 +2719,7 @@ static int gxtv_demod_dtmb_tune(struct dvb_frontend *fe, bool re_tune, *delay = HZ / 4; gxtv_demod_dtmb_set_frontend(fe); firstdetet = dtmb_detect_first(); + if (firstdetet == 1) { *status = FE_TIMEDOUT; /*polling mode*/ @@ -2439,6 +2753,13 @@ static int gxtv_demod_dtmb_tune(struct dvb_frontend *fe, bool re_tune, #if 1 /**/ *delay = HZ / 4; gxtv_demod_dtmb_read_status_old(fe, status); + + if (*status == (FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC)) + dtmb_poll_start_tune(DTMBM_HV_SIGNEL_CHECK); + else + dtmb_poll_start_tune(DTMBM_NO_SIGNEL_CHECK); + #else /*try polling*/ /*pr_dbg("+");*/ @@ -2533,6 +2854,7 @@ static bool enter_mode(int mode) /*mem_buf = (long *)phys_to_virt(memstart);*/ if (mode == AM_FE_DTMB_N) { Gxtv_Demod_Dtmb_Init(devn); + if (devn->cma_flag == 1) { PR_DBG("CMA MODE, cma flag is %d,mem size is %d", devn->cma_flag, devn->cma_mem_size); @@ -2550,16 +2872,21 @@ static bool enter_mode(int mode) devn->act_dtmb = true; dtmb_set_mem_st(memstart_dtmb); - demod_write_reg(DEMOD_REG4, 0x8); - + //?, already set in Gxtv_Demod_Dtmb_Init() + if (!is_ic_ver(IC_VER_TL1)) + demod_write_reg(DEMOD_TOP_REGC, 0x8); } else if (mode == AM_FE_QAM_N) { Gxtv_Demod_Dvbc_Init(/*dev,*/ Adc_mode); + /*The maximum time of signal detection is 3s*/ timer_set_max(D_TIMER_DETECT, 3000); /*reset is 4s*/ timer_set_max(D_TIMER_SET, 4000); } else if (mode == AM_FE_ATSC_N) { Gxtv_Demod_Atsc_Init(); + + if (is_ic_ver(IC_VER_TL1)) + timer_set_max(D_TIMER_DETECT, 4000); } else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) { Gxtv_Demod_Dvbt_Init(); /*The maximum time of signal detection is 2s */ @@ -2606,7 +2933,7 @@ static int leave_mode(int mode) dtmb_poll_stop(); /*polling mode*/ /* close arbit */ - demod_write_reg(DEMOD_REG4, 0x0); + demod_write_reg(DEMOD_TOP_REGC, 0x0); if (devn->cma_flag == 1) dtmb_cma_release(devn); } @@ -2614,7 +2941,7 @@ static int leave_mode(int mode) if (dtvdd_devp->act_dtmb) { dtmb_poll_stop(); /*polling mode*/ /* close arbit */ - demod_write_reg(DEMOD_REG4, 0x0); + demod_write_reg(DEMOD_TOP_REGC, 0x0); dtvdd_devp->act_dtmb = false; } if ((devn->cma_flag == 1) && dtvdd_devp->flg_cma_allc) { @@ -2706,6 +3033,20 @@ const struct meson_ddemod_data data_txhd = { }; +const struct meson_ddemod_data data_tl1 = { + .name = "ddmode_tl1", + .icver = { + .atsc = IC_ATSC_V2, + .dvbt = IC_MD_NONE, + .dtmb = IC_DTMB_V3, + .dvbc = IC_DVBC_V3, + .reserved = 0, + .offset = IC_OFFS_V4, + .ic = IC_VER_TL1, + }, + +}; + static const struct of_device_id meson_ddemod_match[] = { { .compatible = "amlogic, ddemod-gxtvbb", @@ -2722,6 +3063,9 @@ static const struct of_device_id meson_ddemod_match[] = { }, { .compatible = "amlogic, ddemod-txhd", .data = &data_txhd, + }, { + .compatible = "amlogic, ddemod-tl1", + .data = &data_tl1, }, {}, }; @@ -2888,7 +3232,7 @@ int dtvdemod_set_iccfg_by_dts(struct platform_device *pdev) return 0; } -#if (defined CONFIG_AM_DTVDEMOD) /*move to aml_dtv_demod*/ +#if (defined CONFIG_AMLOGIC_DTV_DEMOD) /*move to aml_dtv_demod*/ static int rmem_demod_device_init(struct reserved_mem *rmem, struct device *dev) { unsigned int demod_mem_start; @@ -2946,28 +3290,36 @@ int dtvdemod_init_regaddr_byversion(struct platform_device *pdev) int ret = 0; /*clear*/ - ireg->off_demod = 0x00; + ireg->off_demod_top = 0x00; ireg->off_dvbc = 0x00; ireg->off_dtmb = 0x00; ireg->off_dvbt = 0x00; ireg->off_atsc = 0x00; + ireg->off_front = 0x00; + ireg->off_isdbt = 0x00; if (is_offset_ver(IC_OFFS_V2)) { - ireg->off_demod = 0xc00; - + ireg->off_demod_top = 0xc00; ireg->off_dvbc = 0x400; ireg->off_dtmb = 0x00; } else if (is_offset_ver(IC_OFFS_V3)) { - ireg->off_demod = 0xf00; - + ireg->off_demod_top = 0xf00; ireg->off_dvbc = 0xc00; ireg->off_dtmb = 0x000; ireg->off_dvbt = 0x400; + ireg->off_isdbt = ireg->off_dvbt; ireg->off_atsc = 0x800; + } else if (is_offset_ver(IC_OFFS_V4)) { + ireg->off_demod_top = 0x3c00; + ireg->off_dvbc = 0x1000; + ireg->off_dtmb = 0x0000; + ireg->off_dvbt = 0x0400; + ireg->off_isdbt = 0x0800; + ireg->off_atsc = 0x0c00; + ireg->off_front = 0x3800; } else { PR_ERR("ic_offset_version[%d] is not support!\n", off_ver); - ireg->off_demod = 0xf00; - + ireg->off_demod_top = 0xf00; ireg->off_dvbc = 0xc00; ireg->off_dtmb = 0x000; ireg->off_dvbt = 0x400; @@ -3016,11 +3368,13 @@ void dbg_reg_addr(void) PR_INFO("%s\n", __func__); PR_INFO("reg address offset:\n"); - PR_INFO("\tdemod:\t0x%x\n", ireg->off_demod); + PR_INFO("\tdemod top:\t0x%x\n", ireg->off_demod_top); PR_INFO("\tdvbc:\t0x%x\n", ireg->off_dvbc); PR_INFO("\tdtmb:\t0x%x\n", ireg->off_dtmb); PR_INFO("\tdvbt:\t0x%x\n", ireg->off_dvbt); + PR_INFO("\tisdbt:\t0x%x\n", ireg->off_isdbt); PR_INFO("\tatsc:\t0x%x\n", ireg->off_atsc); + PR_INFO("\tfront:\t0x%x\n", ireg->off_front); PR_INFO("virtual addr:\n"); for (i = 0; i < ES_MAP_ADDR_NUM; i++) @@ -3108,9 +3462,6 @@ static void dtvdemod_vdac_enable(bool on) } } - - - /* platform driver*/ static int aml_dtvdemod_probe(struct platform_device *pdev) { @@ -3119,7 +3470,6 @@ static int aml_dtvdemod_probe(struct platform_device *pdev) PR_INFO("%s\n", __func__); /*memory*/ - dtvdd_devp = kzalloc(sizeof(struct amldtvdemod_device_s), GFP_KERNEL); @@ -3561,12 +3911,15 @@ static int delsys_set(struct dvb_frontend *fe, unsigned int delsys) PR_INFO("info type:%d", fe->ops.info.type); if (mode == AM_FE_ATSC_N) fe->ops.info.type = FE_ATSC; - else if (mode == AM_FE_OFDM_N || mode == AM_FE_ISDBT_N) + else if (mode == AM_FE_OFDM_N) fe->ops.info.type = FE_OFDM; else if (mode == AM_FE_DTMB_N) fe->ops.info.type = FE_DTMB; else if (mode == AM_FE_QAM_N) fe->ops.info.type = FE_QAM; + else if (mode == AM_FE_ISDBT_N) + fe->ops.info.type = FE_ISDBT; + fe->ops.tuner_ops.set_config(fe, NULL); #endif @@ -4005,6 +4358,7 @@ static int aml_dtvdm_tune(struct dvb_frontend *fe, bool re_tune, *status = 0; return 0; } + if (is_not_active(fe)) { *status = 0; PR_DBGL("tune :not active\n"); @@ -4150,7 +4504,7 @@ static struct dvb_frontend_ops aml_dtvdm_txl_ops = { static struct dvb_frontend_ops aml_dtvdm_txlx_ops = { #ifdef CONFIG_AMLOGIC_DVB_COMPAT .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT, - SYS_ANALOG}, + SYS_ANALOG, SYS_ISDBT}, #else .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT}, #endif @@ -4187,6 +4541,7 @@ static struct dvb_frontend_ops aml_dtvdm_txlx_ops = { .get_frontend_algo = gxtv_demod_txlx_get_frontend_algo, }; + static struct dvb_frontend_ops aml_dtvdm_gxlx_ops = { .delsys = { SYS_DVBC_ANNEX_A }, .info = { @@ -4259,9 +4614,48 @@ static struct dvb_frontend_ops aml_dtvdm_txhd_ops = { }; +static struct dvb_frontend_ops aml_dtvdm_tl1_ops = { +#ifdef CONFIG_AMLOGIC_DVB_COMPAT + .delsys = {SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_ATSC, SYS_DTMB, + SYS_ANALOG}, +#else + .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_A, SYS_DVBT}, +#endif + .info = { + /*in aml_fe, it is 'amlogic dvb frontend' */ + .name = "amlogic dtv demod tl1", + .frequency_min = 51000000, + .frequency_max = 900000000, + .frequency_stepsize = 0, + .frequency_tolerance = 0, /**/ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | + FE_CAN_RECOVER | FE_CAN_MUTE_TS + }, + .init = aml_dtvdm_init, + .sleep = aml_dtvdm_sleep, + .set_frontend = aml_dtvdm_set_parameters, + .get_frontend = aml_dtvdm_get_frontend, + .get_tune_settings = aml_dtvdm_get_tune_settings, + .read_status = aml_dtvdm_read_status, + .read_ber = aml_dtvdm_read_ber, + .read_signal_strength = aml_dtvdm_read_signal_strength, + .read_snr = aml_dtvdm_read_snr, + .read_ucblocks = aml_dtvdm_read_ucblocks, + .release = aml_dtvdm_release, + .set_property = aml_dtvdm_set_property, + .get_property = aml_dtvdm_get_property, + +/*-------------*/ + .tune = aml_dtvdm_tune, + .get_frontend_algo = gxtv_demod_txlx_get_frontend_algo, + +}; + struct dvb_frontend *aml_dtvdm_attach(const struct amlfe_exp_config *config) - - { int ic_version = get_ic_ver(); @@ -4294,6 +4688,10 @@ struct dvb_frontend *aml_dtvdm_attach(const struct amlfe_exp_config *config) memcpy(&fe->ops, &aml_dtvdm_txhd_ops, sizeof(struct dvb_frontend_ops)); break; + case IC_VER_TL1: + memcpy(&fe->ops, &aml_dtvdm_tl1_ops, + sizeof(struct dvb_frontend_ops)); + break; default: PR_ERR("attach fail! ic=%d\n", ic_version); /*return NULL;*/ diff --git a/drivers/amlogic/media/dtv_demod/atsc_func.c b/drivers/amlogic/media/dtv_demod/atsc_func.c index f2dd86a418f0..d95b1ef53ad2 100644 --- a/drivers/amlogic/media/dtv_demod/atsc_func.c +++ b/drivers/amlogic/media/dtv_demod/atsc_func.c @@ -1196,8 +1196,6 @@ void atsc_thread(void) } - - #if 0 static dtmb_cfg_t list_dtmb_v1[99] = { {0x00000000, 0x01, 0}, diff --git a/drivers/amlogic/media/dtv_demod/demod_func.c b/drivers/amlogic/media/dtv_demod/demod_func.c index 42f38f0b7cf4..6f394bc8dc4b 100644 --- a/drivers/amlogic/media/dtv_demod/demod_func.c +++ b/drivers/amlogic/media/dtv_demod/demod_func.c @@ -21,10 +21,11 @@ #include #include #include +#include +#include /*#include "acf_filter_coefficient.h"*/ #include - #include @@ -37,21 +38,10 @@ MODULE_PARM_DESC(debug_demod, "\n\t\t Enable frontend debug information"); static int debug_demod; module_param(debug_demod, int, 0644); - - - - - - - - MODULE_PARM_DESC(demod_mobile_power, "\n\t\t demod_mobile_power debug information"); static int demod_mobile_power = 100; module_param(demod_mobile_power, int, 0644); - - - static struct mutex mp; static struct mutex dtvpll_init_lock; static int dtvpll_init; @@ -142,6 +132,15 @@ void adc_dpll_setup(int clk_a, int clk_b, int clk_sys, int dvb_mode) struct dfe_adcpll_para ddemod_pll; int sts_pll; + if (is_ic_ver(IC_VER_TL1)) { + if (clk_b == Adc_Clk_24M) { + dtvpll_init_flag(1); + return; + } else if (clk_b == Adc_Clk_25M) { + //going on to set 25M clk + } + } + adc_pll_cntl.d32 = 0; adc_pll_cntl2.d32 = 0; adc_pll_cntl3.d32 = 0; @@ -406,12 +405,12 @@ void adc_dpll_setup(int clk_a, int clk_b, int clk_sys, int dvb_mode) demod_read_demod_reg(ADC_REGD)); PR_DBG("[adc][%x]%x\n", ADC_REGE, demod_read_demod_reg(ADC_REGE)); - PR_DBG("[demod][%x]%x\n", DEMOD_REG1, - demod_read_demod_reg(DEMOD_REG1)); - PR_DBG("[demod][%x]%x\n", DEMOD_REG2, - demod_read_demod_reg(DEMOD_REG2)); - PR_DBG("[demod][%x]%x\n", DEMOD_REG3, - demod_read_demod_reg(DEMOD_REG3)); + PR_DBG("[demod][%x]%x\n", DEMOD_TOP_REG0, + demod_read_demod_reg(DEMOD_TOP_REG0)); + PR_DBG("[demod][%x]%x\n", DEMOD_TOP_REG4, + demod_read_demod_reg(DEMOD_TOP_REG4)); + PR_DBG("[demod][%x]%x\n", DEMOD_TOP_REG8, + demod_read_demod_reg(DEMOD_TOP_REG8)); } else if (is_meson_gxlx_cpu()) { /*demod_set_demod_reg(TXLX_ADC_RESET_VALUE, ADC_REG3);*/ /*demod_set_demod_reg(adc_pll_cntl.d32, ADC_REG1);*/ @@ -467,12 +466,12 @@ void adc_dpll_setup(int clk_a, int clk_b, int clk_sys, int dvb_mode) demod_read_demod_reg(ADC_REG4)); PR_DBG("[adc][%x]%x\n", ADC_REG6, demod_read_demod_reg(ADC_REG6)); - PR_DBG("[demod][%x]%x\n", DEMOD_REG1, - demod_read_demod_reg(DEMOD_REG1)); - PR_DBG("[demod][%x]%x\n", DEMOD_REG2, - demod_read_demod_reg(DEMOD_REG2)); - PR_DBG("[demod][%x]%x\n", DEMOD_REG3, - demod_read_demod_reg(DEMOD_REG3)); + PR_DBG("[demod][%x]%x\n", DEMOD_TOP_REG0, + demod_read_demod_reg(DEMOD_TOP_REG0)); + PR_DBG("[demod][%x]%x\n", DEMOD_TOP_REG4, + demod_read_demod_reg(DEMOD_TOP_REG4)); + PR_DBG("[demod][%x]%x\n", DEMOD_TOP_REG8, + demod_read_demod_reg(DEMOD_TOP_REG8)); } #endif ddemod_pll.adcpllctl = adc_pll_cntl.d32; @@ -547,6 +546,17 @@ void demod_set_demod_reg(unsigned int data, unsigned int addr) { void __iomem *vaddr; + mutex_lock(&mp); + vaddr = ioremap((addr), 0x4); + writel(data, vaddr); + iounmap(vaddr); + mutex_unlock(&mp); +} + +void demod_set_tvfe_reg(unsigned int data, unsigned int addr) +{ + void __iomem *vaddr; + mutex_lock(&mp); /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ vaddr = ioremap((addr), 0x4); @@ -565,18 +575,27 @@ unsigned int demod_read_demod_reg(unsigned int addr) tmp = readl(vaddr); iounmap(vaddr); mutex_unlock(&mp); -/* printk("[demod][read]%x,data is %x\n",(addr),tmp); */ + return tmp; } void power_sw_hiu_reg(int on) { if (on == PWR_ON) { - dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, - (dd_tvafe_hiu_reg_read(HHI_DEMOD_MEM_PD_REG) & (~0x2fff))); + if (is_ic_ver(IC_VER_TL1)) + dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, 0); + else + dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, + (dd_tvafe_hiu_reg_read(HHI_DEMOD_MEM_PD_REG) + & (~0x2fff))); } else { - dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, - (dd_tvafe_hiu_reg_read(HHI_DEMOD_MEM_PD_REG) | 0x2fff)); + if (is_ic_ver(IC_VER_TL1)) + dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, + 0xffffffff); + else + dd_tvafe_hiu_reg_write(HHI_DEMOD_MEM_PD_REG, + (dd_tvafe_hiu_reg_read + (HHI_DEMOD_MEM_PD_REG) | 0x2fff)); } } @@ -643,6 +662,50 @@ if (is_ic_ver(IC_VER_TXLX) || is_ic_ver(IC_VER_TXHD)) { PR_DBG("[PWR]: GXLX not support power switch,power mem\n"); power_sw_hiu_reg(PWR_ON); +} else if (is_ic_ver(IC_VER_TL1)) { + + if (pwr_cntl == PWR_ON) { + PR_DBG("[PWR]: Power on demod_comp %x,%x\n", + AO_RTI_GEN_PWR_SLEEP0, AO_RTI_GEN_PWR_ISO0); + /* Powerup demod_comb */ + reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); + demod_set_ao_reg((reg_data & (~(0x1 << 10))), + AO_RTI_GEN_PWR_SLEEP0); + /* [10] power on */ + /*PR_DBG("[PWR]: Power on demod_comp %x,%x\n",*/ + /* TXLX_HHI_DEMOD_MEM_PD_REG, TXLX_RESET0_LEVEL);*/ + + /* Power up memory */ + power_sw_hiu_reg(PWR_ON); + /* reset */ + power_sw_reset_reg(1); /*reset*/ + /* msleep(20);*/ + + /* remove isolation */ + demod_set_ao_reg( + (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) & + (~(0x3 << 14))), AO_RTI_GEN_PWR_ISO0); + + /* pull up reset */ + power_sw_reset_reg(0); /*reset*/ +/* *P_RESET0_LEVEL |= (0x1<<8); */ + } else { + PR_DBG("[PWR]: Power off demod_comp\n"); + + /* add isolation */ + demod_set_ao_reg( + (demod_read_ao_reg(AO_RTI_GEN_PWR_ISO0) | + (0x3 << 14)), AO_RTI_GEN_PWR_ISO0); + + /* power down memory */ + power_sw_hiu_reg(PWR_OFF); + /* power down demod_comb */ + reg_data = demod_read_ao_reg(AO_RTI_GEN_PWR_SLEEP0); + demod_set_ao_reg((reg_data | (0x1 << 10)), + AO_RTI_GEN_PWR_SLEEP0); + /* [10] power on */ + } + /*} else if (is_meson_gxlx_cpu()) {*/ } else { if (pwr_cntl == PWR_ON) { PR_DBG("[PWR]: Power on demod_comp %x,%x\n", @@ -697,6 +760,10 @@ void demod_set_mode_ts(unsigned char dvb_mode) if (dvb_mode == Gxtv_Dtmb) { cfg0.b.ts_sel = 1; cfg0.b.mode = 1; + if (is_ic_ver(IC_VER_TL1)) { + cfg0.b.adc_format = 0; + cfg0.b.adc_regout = 0; + } } else if (dvb_mode == Gxtv_Dvbt_Isdbt) { cfg0.b.ts_sel = 1<<1; cfg0.b.mode = 1<<1; @@ -706,8 +773,10 @@ void demod_set_mode_ts(unsigned char dvb_mode) cfg0.b.ts_sel = 1<<2; cfg0.b.mode = 1<<2; cfg0.b.adc_format = 0; - cfg0.b.adc_regout = 1; - cfg0.b.adc_regadj = 2; + if (!is_ic_ver(IC_VER_TL1)) { + cfg0.b.adc_regout = 1; + cfg0.b.adc_regadj = 2; + } } else if (dvb_mode == Gxtv_Dvbc) { if (is_dvbc_ver(IC_DVBC_V2)) { cfg0.b.ts_sel = 2; @@ -722,8 +791,7 @@ void demod_set_mode_ts(unsigned char dvb_mode) } } - demod_write_reg(DEMOD_REG1, cfg0.d32); - + demod_write_reg(DEMOD_TOP_REG0, cfg0.d32); } void clocks_set_sys_defaults(unsigned char dvb_mode) @@ -735,19 +803,19 @@ void clocks_set_sys_defaults(unsigned char dvb_mode) tvafe_set_ddemod_default(); demod_set_demod_default(); - sts_pll = adc_set_pll_cntl(1, 0x04, NULL); + if (sts_pll < 0) { /*set pll fail*/ PR_ERR("%s:set pll default fail! please check!\n", __func__); } + demod_set_mode_ts(dvb_mode); cfg2.b.biasgen_en = 1; cfg2.b.en_adc = 1; - - demod_write_reg(DEMOD_REG3, cfg2.d32); + demod_write_reg(DEMOD_TOP_REG8, cfg2.d32); PR_DBG("dvb_mode is %d\n", dvb_mode); - debug_check_reg_val(REG_M_DEMOD, DEMOD_REG1); + debug_check_reg_val(REG_M_DEMOD, DEMOD_TOP_REG0); } #if 0 @@ -774,6 +842,7 @@ void dtmb_write_reg(int reg_addr, int reg_data) { if (!get_dtvpll_init_flag()) return; + mutex_lock(&mp); /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ @@ -791,7 +860,9 @@ unsigned int dtmb_read_reg(unsigned int reg_addr) return 0; mutex_lock(&mp); + tmp = readl(gbase_dtmb() + reg_addr); + mutex_unlock(&mp); return tmp; @@ -802,6 +873,9 @@ unsigned int dtmb_read_reg(unsigned int reg_addr) void dvbt_write_reg(unsigned int addr, unsigned int data) { + if (!get_dtvpll_init_flag()) + return; + mutex_lock(&mp); /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ @@ -814,6 +888,9 @@ unsigned int dvbt_read_reg(unsigned int addr) { unsigned int tmp; + if (!get_dtvpll_init_flag()) + return 0; + mutex_lock(&mp); tmp = readl(gbase_dvbt() + addr); @@ -855,6 +932,36 @@ unsigned int atsc_read_reg(unsigned int reg_addr) return tmp & 0xff; } +/*TL1*/ +void atsc_write_reg_v4(unsigned int addr, unsigned int data) +{ + if (!get_dtvpll_init_flag()) + return; + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_atsc() + (addr << 2)); + + mutex_unlock(&mp); +} + +unsigned int atsc_read_reg_v4(unsigned int addr) +{ + unsigned int tmp; + + if (!get_dtvpll_init_flag()) + return 0; + + mutex_lock(&mp); + + tmp = readl(gbase_atsc() + (addr << 2)); + + mutex_unlock(&mp); + + return tmp; +} + unsigned int atsc_read_iqr_reg(void) { unsigned int tmp; @@ -872,8 +979,12 @@ unsigned int atsc_read_iqr_reg(void) return tmp & 0xffffffff; } - - +#if 0 +void demod_init_mutex(void) +{ + mutex_init(&mp); +} +#endif int demod_set_sys(struct aml_demod_sta *demod_sta, struct aml_demod_sys *demod_sys) @@ -882,12 +993,14 @@ int demod_set_sys(struct aml_demod_sta *demod_sta, /* demod_sta->tmp=Adc_mode; */ unsigned char dvb_mode; int clk_adc, clk_dem; + int nco_rate; /* int gpioDV_2;*/ /*int gpiW_2;*/ dvb_mode = demod_sta->dvb_mode; clk_adc = demod_sys->adc_clk; clk_dem = demod_sys->demod_clk; + nco_rate = (clk_adc * 256) / clk_dem + 2; PR_DBG ("demod_set_sys,clk_adc is %d,clk_demod is %d\n", clk_adc, clk_dem); @@ -933,13 +1046,24 @@ int demod_set_sys(struct aml_demod_sta *demod_sta, demod_set_reg_rlt(TXLX_DEMOD_REG4, 0x8); } else if (!is_meson_txlx_cpu()) { /* open arbit */ - /* demod_set_demod_reg(0x8, DEMOD_REG4);*/ + /* demod_set_demod_reg(0x8, DEMOD_TOP_REGC);*/ demod_set_reg_rlt(GXBB_DEMOD_REG4, 0x8); PR_DBG("[open arbit]dtmb\n"); } #else - demod_write_reg(DEMOD_REG4, 0x8); - PR_DBG("[open arbit]dtmb\n"); + if (is_ic_ver(IC_VER_TL1)) { + demod_write_reg(DEMOD_TOP_REGC, 0x11); + front_write_reg_v4(0x20, + ((front_read_reg_v4(0x20) & ~0xff) + | (nco_rate & 0xff))); + front_write_reg_v4(0x20, + (front_read_reg_v4(0x20) | (1 << 8))); + front_write_reg_v4(0x39, + (front_read_reg_v4(0x39) | (1 << 30))); + } else { + demod_write_reg(DEMOD_TOP_REGC, 0x8); + PR_DBG("[open arbit]dtmb\n"); + } #endif /* } else if ((dvb_mode == Gxtv_Dvbt_Isdbt) && is_meson_txlx_cpu()) {*/ } else if ((dvb_mode == Gxtv_Dvbt_Isdbt) && is_ic_ver(IC_VER_TXLX)) { @@ -948,15 +1072,510 @@ int demod_set_sys(struct aml_demod_sta *demod_sta, /*demod_set_demod_reg(0x8, TXLX_DEMOD_REG4);*/ demod_set_reg_rlt(TXLX_DEMOD_REG4, 0x8); #else - demod_write_reg(DEMOD_REG4, 0x8); + demod_write_reg(DEMOD_TOP_REGC, 0x8); #endif PR_DBG("[open arbit]dvbt,txlx\n"); + } else if (is_ic_ver(IC_VER_TL1) && (dvb_mode == Gxtv_Atsc)) { + demod_write_reg(DEMOD_TOP_REGC, 0x11); + front_write_reg_v4(0x20, ((front_read_reg_v4(0x20) & ~0xff) + | (nco_rate & 0xff))); + front_write_reg_v4(0x20, (front_read_reg_v4(0x20) | (1 << 8))); + } else if (is_ic_ver(IC_VER_TL1) && (dvb_mode == Gxtv_Dvbc)) { + nco_rate = (clk_adc * 256) / clk_dem + 2; + demod_write_reg(DEMOD_TOP_REGC, 0x11); + front_write_reg_v4(0x20, ((front_read_reg_v4(0x20) & ~0xff) + | (nco_rate & 0xff))); + front_write_reg_v4(0x20, (front_read_reg_v4(0x20) | (1 << 8))); + front_write_reg_v4(0x2f, 0x5);//for timsshift mosaic + dd_tvafe_hiu_reg_write(0x1d0, 0x502);//sys_clk=167M } + demod_sta->adc_freq = clk_adc; demod_sta->clk_freq = clk_dem; return 0; } +//#ifdef HIGH_MEM +#if 0 +int memorystart = 0x29c00000;//0x35100000;//0x1ef00000;0x9300000 7ca00000 +#endif + +/*TL1*/ +void demod_set_sys_atsc_v4(void) +{ + //int nco_rate; + #if 0//move to gxtv_demod_atsc_set_frontend() + union ATSC_DEMOD_REG_0X6A_BITS Val_0x6a; + union ATSC_EQ_REG_0XA5_BITS Val_0xa5; + union ATSC_CNTR_REG_0X20_BITS Val_0x20; + union ATSC_DEMOD_REG_0X54_BITS Val_0x54; + union ATSC_DEMOD_REG_0X55_BITS Val_0x55; + union ATSC_DEMOD_REG_0X6E_BITS Val_0x6e; + #endif + + //PR_INFO("%s\n", __func__); + //nco_rate = (24*256)/224+2;// 24 | 25 + //hardware_reset(); + //app_apb_write_reg(0xf0c, 0x10); + //demod_write_reg(DEMOD_TOP_REGC, 0x10);//apb write enable + + #if 0//move to clocks_set_sys_defaults() + //demod_front_init_cmd(); + //app_apb_write_reg(0xf00*4,0x44 ); + demod_write_reg(DEMOD_TOP_REG0, 0x44); + //app_apb_write_reg(0xf08*4,0x201); + demod_write_reg(DEMOD_TOP_REG8, 0x201); + #endif + + #if 0//move to demod_set_sys() + //app_apb_write_reg(0xf0c*4,0x11); + demod_write_reg(DEMOD_TOP_REGC, 0x11); + //app_apb_write_reg(0xe20*4,((app_apb_read_reg(0xe20*4) &~ 0xff) + //| (nco_rate & 0xff))); + front_write_reg_v4(0x20, ((front_read_reg_v4(0x20) & ~0xff) + | (nco_rate & 0xff))); + //app_apb_write_reg(0xe20*4, (app_apb_read_reg(0xe20*4) | (1 << 8))); + front_write_reg_v4(0x20, (front_read_reg_v4(0x20) | (1 << 8))); + #endif + + #if 0//move to gxtv_demod_atsc_set_frontend() + //set_cr_ck_rate(); + //Read Reg + Val_0x6a.bits = atsc_read_reg_v4(ATSC_DEMOD_REG_0X6A); + Val_0xa5.bits = atsc_read_reg_v4(ATSC_EQ_REG_0XA5); + + //24M begin + Val_0x54.bits = atsc_read_reg_v4(ATSC_DEMOD_REG_0X54); + Val_0x55.bits = atsc_read_reg_v4(ATSC_DEMOD_REG_0X55); + Val_0x6e.bits = atsc_read_reg_v4(ATSC_DEMOD_REG_0X6E); + //24M end + + //Set Reg + Val_0x6a.b.peak_thd = 0x6;//Let CCFO Quality over 6 + Val_0xa5.bits = 0x8c;//increase state 2 to state 3 + + //24M begin + Val_0x54.bits = 0x1aaaaa;//24m 5m if + Val_0x55.bits = 0x3ae28d;//24m + Val_0x6e.bits = 0x16e3600; + //24M end + + //Write Reg + atsc_write_reg_v4(ATSC_DEMOD_REG_0X6A, Val_0x6a.bits); + atsc_write_reg_v4(ATSC_EQ_REG_0XA5, Val_0xa5.bits); + + //24M begin + atsc_write_reg_v4(ATSC_DEMOD_REG_0X54, Val_0x54.bits); + atsc_write_reg_v4(ATSC_DEMOD_REG_0X55, Val_0x55.bits); + atsc_write_reg_v4(ATSC_DEMOD_REG_0X6E, Val_0x6e.bits); + //24M end + + //atsc_reset(); + Val_0x20.bits = atsc_read_reg_v4(ATSC_CNTR_REG_0X20); + Val_0x20.b.cpu_rst = 1; + atsc_write_reg_v4(ATSC_CNTR_REG_0X20, Val_0x20.bits); + Val_0x20.b.cpu_rst = 0; + atsc_write_reg_v4(ATSC_CNTR_REG_0X20, Val_0x20.bits); + usleep_range(5000, 5001); + #endif +} + +/*TL1*/ +void set_j83b_filter_reg_v4(void) +{ + //j83_1 + qam_write_reg(0x40, 0x36333c0d); + qam_write_reg(0x41, 0xa110d01); + qam_write_reg(0x42, 0xf0e4ea7a); + qam_write_reg(0x43, 0x3c0010); + qam_write_reg(0x44, 0x7e0065); + + + //j83_2 + qam_write_reg(0x45, 0xb3a1905); + qam_write_reg(0x46, 0x1c396e07); + qam_write_reg(0x47, 0x3801cc08); + qam_write_reg(0x48, 0x10800a2); + + + qam_write_reg(0x49, 0x53b1f03); + qam_write_reg(0x4a, 0x18377407); + qam_write_reg(0x4b, 0x3401cf0b); + qam_write_reg(0x4c, 0x10d00a1); +} + +#if 0 +/*TL1*/ +void dvbc_reg_initial_tmp_v4(struct aml_demod_dvbc *demod_dvbc) +{ + int clk_freq; + int adc_freq; + int ch_mode; + int agc_mode; + int ch_freq; + int ch_if; + int ch_bw; + int symb_rate; + int phs_cfg; + int afifo_ctr; + int max_frq_off, tmp; + + agc_mode = 1; + ch_if = 5000; + ch_bw = 8000; // kHz + //==important: Chip or FPGA Combo need to change======= + clk_freq = 250000; + adc_freq = 24000; + ch_mode = demod_dvbc->mode; + symb_rate = demod_dvbc->symb_rate; + ch_freq = demod_dvbc->ch_freq; + + //printf("in dvbc_func, clk_freq is %d, adc_freq is %d\n", + //clk_freq, adc_freq); + PR_DBG("in dvbc_func, clk_freq is %d, adc_freq is %d\n", + clk_freq, adc_freq); + + // disable irq + //app_apb_write_reg(0xd0, 0); + qam_write_reg(0x34, 0); + + // reset + //dvbc_reset(); + //app_apb_write_reg(reg_reset, + //app_apb_read_reg(reg_reset) & ~(1 << 4)); // disable fsm_en + qam_write_reg(0x7, + qam_read_reg(0x7) & ~(1 << 4)); // disable fsm_en + //app_apb_write_reg(reg_reset, + //app_apb_read_reg(reg_reset) & ~(1 << 0)); // Sw disable demod + qam_write_reg(0x7, + qam_read_reg(0x7) & ~(1 << 0)); // Sw disable demod + //app_apb_write_reg(reg_reset, + //app_apb_read_reg(reg_reset) | (1 << 0)); // Sw enable demod + qam_write_reg(0x7, + qam_read_reg(0x7) | (1 << 0)); // Sw enable demod + + + //app_apb_write_reg(0x000, 0x00000000); // QAM_STATUS + qam_write_reg(0x000, 0x00000000); // QAM_STATUS + //app_apb_write_reg(reg_reset, 0x00000f00); // QAM_GCTL0 + qam_write_reg(0x7, 0x00000f00); // QAM_GCTL0 + //tmp = app_apb_read_reg(0x008); + tmp = qam_read_reg(0x2); + tmp = (tmp & 0xfffffff8) | ch_mode; + //app_apb_write_reg(0x008, tmp); // qam mode + qam_write_reg(0x2, tmp); // qam mode + + switch (ch_mode) { + case 0: // 16 QAM + #if 0 + app_apb_write_reg(0x1c4, 0xa2200); + app_apb_write_reg(0x1c8, 0xc2b0c49); + app_apb_write_reg(0x1cc, 0x2020000); + app_apb_write_reg(0x1d4, 0xe9178); + app_apb_write_reg(0x1d8, 0x1c100); + app_apb_write_reg(0x1e8, 0x2ab7ff); + app_apb_write_reg(0x24c, 0x641a180c); + app_apb_write_reg(0x250, 0xc141400); + #else + qam_write_reg(0x71, 0xa2200); + qam_write_reg(0x72, 0xc2b0c49); + qam_write_reg(0x73, 0x2020000); + qam_write_reg(0x75, 0xe9178); + qam_write_reg(0x76, 0x1c100); + qam_write_reg(0x7a, 0x2ab7ff); + qam_write_reg(0x93, 0x641a180c); + qam_write_reg(0x94, 0xc141400); + #endif + break; + + case 1: // 32 QAM + #if 0 + app_apb_write_reg(0x1c4, 0x61200); + app_apb_write_reg(0x1c8, 0x99301ae); + app_apb_write_reg(0x1cc, 0x8080000); + app_apb_write_reg(0x1d4, 0xbf10c); + app_apb_write_reg(0x1d8, 0xa05c); + app_apb_write_reg(0x1dc, 0x1000d6); + app_apb_write_reg(0x1e8, 0x19a7ff); + app_apb_write_reg(0x1f0, 0x111222); + app_apb_write_reg(0x1f4, 0x2020305); + app_apb_write_reg(0x1f8, 0x3000d0d); + app_apb_write_reg(0x24c, 0x641f1d0c); + app_apb_write_reg(0x250, 0xc1a1a00); + #else + qam_write_reg(0x71, 0x61200); + qam_write_reg(0x72, 0x99301ae); + qam_write_reg(0x73, 0x8080000); + qam_write_reg(0x75, 0xbf10c); + qam_write_reg(0x76, 0xa05c); + qam_write_reg(0x77, 0x1000d6); + qam_write_reg(0x7a, 0x19a7ff); + qam_write_reg(0x7c, 0x111222); + qam_write_reg(0x7d, 0x2020305); + qam_write_reg(0x7e, 0x3000d0d); + qam_write_reg(0x93, 0x641f1d0c); + qam_write_reg(0x94, 0xc1a1a00); + #endif + break; + + case 2: // 64 QAM + //app_apb_write_reg(0x150, 0x606050d); + // app_apb_write_reg(0x148, 0x346dc); + break; + + case 3: // 128 QAM + #if 0 + app_apb_write_reg(0x1c4, 0x2c200); + app_apb_write_reg(0x1c8, 0xa6e0059); + app_apb_write_reg(0x1cc, 0x8080000); + app_apb_write_reg(0x1d4, 0xa70e9); + app_apb_write_reg(0x1d8, 0x2013); + app_apb_write_reg(0x1dc, 0x35068); + app_apb_write_reg(0x1e0, 0xab100); + app_apb_write_reg(0x1e8, 0xba7ff); + app_apb_write_reg(0x1f0, 0x111222); + app_apb_write_reg(0x1f4, 0x2020305); + app_apb_write_reg(0x1f8, 0x3000d0d); + app_apb_write_reg(0x24c, 0x642a240c); + app_apb_write_reg(0x250, 0xc262600); + #else + qam_write_reg(0x71, 0x2c200); + qam_write_reg(0x72, 0xa6e0059); + qam_write_reg(0x73, 0x8080000); + qam_write_reg(0x75, 0xa70e9); + qam_write_reg(0x76, 0x2013); + qam_write_reg(0x77, 0x35068); + qam_write_reg(0x78, 0xab100); + qam_write_reg(0x7a, 0xba7ff); + qam_write_reg(0x7c, 0x111222); + qam_write_reg(0x7d, 0x2020305); + qam_write_reg(0x7e, 0x3000d0d); + qam_write_reg(0x93, 0x642a240c); + qam_write_reg(0x94, 0xc262600); + #endif + break; + + case 4: // 256 QAM + #if 0 + app_apb_write_reg(0x270, 0x2a232100); + app_apb_write_reg(0x15c, 0x606040d); + #else + qam_write_reg(0x9c, 0x2a232100); + qam_write_reg(0x57, 0x606040d); + #endif + break; + } + + //app_apb_write_reg(0x00c, 0xffff8ffe); // adc_cnt, symb_cnt + qam_write_reg(0x3, 0xffff8ffe); + + #if 0//impossible condition + if (clk_freq == 0) + afifo_ctr = 0; + else + #endif + afifo_ctr = (adc_freq * 256 / clk_freq) + 2; + + #if 0//impossible condition + if (afifo_ctr > 255) + afifo_ctr = 255; + #endif + + #if 0 + app_apb_write_reg(0x010, (afifo_ctr<<16) | 8000); // afifo, rs_cnt_cfg + + app_apb_write_reg(0xe20*4, afifo_ctr | 0x100);//front_end afifo nco rate + app_apb_write_reg(0xe2f*4, 0x0); //front_end sfifo out len + app_apb_write_reg(0x188, 0x2000); //ffe/fbe taps 88/72 + + app_apb_write_reg(0x020, 0x61b53e54);//modified by qiancheng by raymond + #else + qam_write_reg(0x4, (afifo_ctr<<16) | 8000); // afifo, rs_cnt_cfg + + //front_end afifo nco rate + //front_write_reg_v4(0x20, afifo_ctr | 0x100); + //front_write_reg_v4(0x2f, 0x0); //front_end sfifo out len + //dvbc_write_reg(0x188, 0x2000); //ffe/fbe taps 88/72 + + qam_write_reg(0x8, 0x61b53e54); //modified by qiancheng by raymond + #endif + + #if 0//impossible condition + if (adc_freq == 0) { + phs_cfg = 0; + } else { + #endif + // 8*fo/fs*2^20 fo=36.125, fs = 28.57114, = 21d775 + phs_cfg = (1<<31) / adc_freq * ch_if / (1<<8); + //} + + // printk("phs_cfg = %x\n", phs_cfg); + //app_apb_write_reg(0x024, + //0x4c000000 | (phs_cfg&0x7fffff)); // PHS_OFFSET, IF offset, + qam_write_reg(0x9, + 0x4c000000 | (phs_cfg&0x7fffff)); // PHS_OFFSET, IF offset, + + #if 0//impossible condition + if (adc_freq == 0) { + max_frq_off = 0; + } else { + #endif + // max_frq_off = (400KHz * 2^29) / (AD=25 * symbol_rate=68750) + max_frq_off = (1<<29) / symb_rate; + tmp = 40000000 / adc_freq; + max_frq_off = tmp * max_frq_off; + //} + + #if 0 + app_apb_write_reg(0x030, 0x245cf450); //MODIFIED BY QIANCHENG + app_apb_write_reg(0x034, + ((adc_freq & 0xffff) << 16) | (symb_rate&0xffff)); + #else + qam_write_reg(0xc, 0x245cf450); //MODIFIED BY QIANCHENG + qam_write_reg(0xd, + ((adc_freq & 0xffff) << 16) | (symb_rate&0xffff)); + #endif + + //app_apb_write_reg(0x038, 0x00200000); // TIM_SWEEP_RANGE 16000 + + /************* hw state machine config **********/ + //apb_write_reg(0, 0x040, 0x003c); // configure symbol rate step step 0 + + // modified 0x44 0x48 + #if 0 + // blind search, configure max symbol_rate for 7218 fb=3.6M + app_apb_write_reg(0x044, (symb_rate&0xffff)*256); + // configure min symbol_rate fb = 6.95M + app_apb_write_reg(0x048, + ((app_apb_read_reg(0x048)&~(0xff<<8))|3400*256)); + app_apb_write_reg(0x144, (app_apb_read_reg(0x144)&~(0x1<<28))); + #else + // blind search, configure max symbol_rate for 7218 fb=3.6M + qam_write_reg(0x011, (symb_rate&0xffff)*256); + // configure min symbol_rate fb = 6.95M + qam_write_reg(0x12, + ((qam_read_reg(0x12)&~(0xff<<8))|3400*256)); + qam_write_reg(0x51, (qam_read_reg(0x51)&~(0x1<<28))); + #endif + + #if 0//impossible condition + if ((agc_mode & 1) == 0) + // freeze if agc + //app_apb_write_reg(0x094, + //app_apb_read_reg(0x94) | (0x1 << 10)); + // freeze if agc + dvbc_write_reg(0x094, dvbc_read_reg(0x94) | (0x1 << 10)); + #endif + + if ((agc_mode & 2) == 0) // IF control + qam_write_reg(0x25, qam_read_reg(0x25) | (0x1 << 13)); + //app_apb_write_reg(0x098, 0x9fcc8190);//AGC_IFGAIN_CTRL + /* + * AGC_RFGAIN_CTRL 0x0e020800 by raymond, + * if Adjcent channel test, maybe it need change. + */ + //app_apb_write_reg(0x0a0, 0x0e03cd11); + // IMQ, QAM Enable + //app_apb_write_reg(reg_reset, app_apb_read_reg(reg_reset)|0x33); + // IMQ, QAM Enable + qam_write_reg(0x7, qam_read_reg(0x7)|0x33); + + // start hardware machine + //dvbc_sw_reset(0x004, 4); + #if 0 + app_apb_write_reg(reg_reset, app_apb_read_reg(reg_reset) | (1 << 4)); + app_apb_write_reg(0x0e8, (app_apb_read_reg(0x0e8)|(1<<2))); + + // clear irq status + app_apb_read_reg(0xd4); + + // enable irq + app_apb_write_reg(0xd0, 0x7fff<<3); + #else + qam_write_reg(0x7, qam_read_reg(0x7) | (1 << 4)); + qam_write_reg(0x3a, (qam_read_reg(0x3a)|(1<<2))); + + // clear irq status + qam_read_reg(0x35); + + // enable irq + qam_write_reg(0x34, 0x7fff<<3); + #endif +} + +/*TL1*/ +void set_dvbc_reg_1_v4(void) +{ + //dvbc_1 + #if 0 + app_apb_write_reg(0x100, 0x3d3d0002); + app_apb_write_reg(0x104, 0x747f0603); + app_apb_write_reg(0x108, 0xf4130f7a); + app_apb_write_reg(0x10c, 0x1f801d5); + app_apb_write_reg(0x110, 0xc60063); + #else + dvbc_write_reg(0x100, 0x3d3d0002); + dvbc_write_reg(0x104, 0x747f0603); + dvbc_write_reg(0x108, 0xf4130f7a); + dvbc_write_reg(0x10c, 0x1f801d5); + dvbc_write_reg(0x110, 0xc60063); + #endif +} + +/*TL1*/ +void set_dvbc_reg_2_v4(void) +{ + //dvbc_2 + #if 0 + app_apb_write_reg(0x114, 0xc381b06); + app_apb_write_reg(0x118, 0x25346b0a); + app_apb_write_reg(0x11c, 0x3101b90e); + app_apb_write_reg(0x120, 0x17900e5); + #else + dvbc_write_reg(0x114, 0xc381b06); + dvbc_write_reg(0x118, 0x25346b0a); + dvbc_write_reg(0x11c, 0x3101b90e); + dvbc_write_reg(0x120, 0x17900e5); + #endif +} + +/*TL1*/ +void set_j83b_reg_1_v4(void) +{ + //j83_1 + #if 0 + app_apb_write_reg(0x100, 0x3e010201); + app_apb_write_reg(0x104, 0x0b033c3a); + app_apb_write_reg(0x108, 0xe2ecff0c); + app_apb_write_reg(0x10c, 0x002a01f6); + app_apb_write_reg(0x110, 0x0097006a); + #else + dvbc_write_reg(0x100, 0x3e010201); + dvbc_write_reg(0x104, 0x0b033c3a); + dvbc_write_reg(0x108, 0xe2ecff0c); + dvbc_write_reg(0x10c, 0x002a01f6); + dvbc_write_reg(0x110, 0x0097006a); + #endif +} + +/*TL1*/ +void set_j83b_reg_2_v4(void) +{ + //j83_2 + #if 0 + app_apb_write_reg(0x114, 0xb3a1905); + app_apb_write_reg(0x118, 0x1c396e07); + app_apb_write_reg(0x11c, 0x3801cc08); + app_apb_write_reg(0x120, 0x10800a2); + #else + dvbc_write_reg(0x114, 0xb3a1905); + dvbc_write_reg(0x118, 0x1c396e07); + dvbc_write_reg(0x11c, 0x3801cc08); + dvbc_write_reg(0x120, 0x10800a2); + #endif +} +#endif + void demod_set_reg(struct aml_demod_reg *demod_reg) { if (fpga_version == 1) { @@ -1240,7 +1859,6 @@ unsigned int dvbc_read_reg(unsigned int addr) #else void dvbc_write_reg(unsigned int addr, unsigned int data) { - mutex_lock(&mp); /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ @@ -1261,6 +1879,29 @@ unsigned int dvbc_read_reg(unsigned int addr) return tmp; } +void dvbc_write_reg_v4(unsigned int addr, unsigned int data) +{ + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_dvbc() + (addr << 2)); + + mutex_unlock(&mp); +} +unsigned int dvbc_read_reg_v4(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_dvbc() + (addr << 2)); + + mutex_unlock(&mp); + + return tmp; +} + #endif void demod_write_reg(unsigned int addr, unsigned int data) { @@ -1268,7 +1909,10 @@ void demod_write_reg(unsigned int addr, unsigned int data) mutex_lock(&mp); /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ - writel(data, gbase_demod() + addr); + if (is_ic_ver(IC_VER_TL1)) + writel(data, gbase_demod() + (addr << 2)); + else + writel(data, gbase_demod() + addr); mutex_unlock(&mp); } @@ -1278,13 +1922,71 @@ unsigned int demod_read_reg(unsigned int addr) mutex_lock(&mp); - tmp = readl(gbase_demod() + addr); + if (is_ic_ver(IC_VER_TL1)) + tmp = readl(gbase_demod() + (addr << 2)); + else + tmp = readl(gbase_demod() + addr); mutex_unlock(&mp); return tmp; } +/*TL1*/ +void front_write_reg_v4(unsigned int addr, unsigned int data) +{ + if (!get_dtvpll_init_flag()) + return; + + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_front() + (addr << 2)); + + mutex_unlock(&mp); +} + +unsigned int front_read_reg_v4(unsigned int addr) +{ + unsigned int tmp; + + if (!get_dtvpll_init_flag()) + return 0; + + mutex_lock(&mp); + + tmp = readl(gbase_front() + (addr << 2)); + + mutex_unlock(&mp); + + return tmp; + +} + +void isdbt_write_reg_v4(unsigned int addr, unsigned int data) +{ + mutex_lock(&mp); + /* printk("[demod][write]%x,data is %x\n",(addr),data);*/ + + writel(data, gbase_isdbt() + addr); + + mutex_unlock(&mp); +} + +unsigned int isdbt_read_reg_v4(unsigned int addr) +{ + unsigned int tmp; + + mutex_lock(&mp); + + tmp = readl(gbase_isdbt() + addr); + + mutex_unlock(&mp); + + return tmp; + +} + /*dvbc v3:*/ void qam_write_reg(unsigned int reg_addr, unsigned int reg_data) { @@ -1392,24 +2094,26 @@ unsigned int dd_tvafe_reg_read(unsigned int addr) void demod_set_demod_default(void) { + if (is_ic_ver(IC_VER_TL1)) + return; + #if 0 if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) { - demod_set_reg_rlt(GXBB_DEMOD_REG1, DEMOD_REG1_VALUE); - demod_set_reg_rlt(GXBB_DEMOD_REG2, DEMOD_REG2_VALUE); - demod_set_reg_rlt(GXBB_DEMOD_REG3, DEMOD_REG3_VALUE); + demod_set_reg_rlt(GXBB_DEMOD_REG1, DEMOD_REG0_VALUE); + demod_set_reg_rlt(GXBB_DEMOD_REG2, DEMOD_REG4_VALUE); + demod_set_reg_rlt(GXBB_DEMOD_REG3, DEMOD_REG8_VALUE); } else if (is_meson_txlx_cpu() || is_meson_gxlx_cpu() || is_meson_txhd_cpu()) { - demod_set_reg_rlt(TXLX_DEMOD_REG1, DEMOD_REG1_VALUE); - demod_set_reg_rlt(TXLX_DEMOD_REG2, DEMOD_REG2_VALUE); - demod_set_reg_rlt(TXLX_DEMOD_REG3, DEMOD_REG3_VALUE); + demod_set_reg_rlt(TXLX_DEMOD_REG1, DEMOD_REG0_VALUE); + demod_set_reg_rlt(TXLX_DEMOD_REG2, DEMOD_REG4_VALUE); + demod_set_reg_rlt(TXLX_DEMOD_REG3, DEMOD_REG8_VALUE); } #else - demod_write_reg(DEMOD_REG1, DEMOD_REG1_VALUE); - demod_write_reg(DEMOD_REG2, DEMOD_REG2_VALUE); - demod_write_reg(DEMOD_REG3, DEMOD_REG3_VALUE); - + demod_write_reg(DEMOD_TOP_REG0, DEMOD_REG0_VALUE); + demod_write_reg(DEMOD_TOP_REG4, DEMOD_REG4_VALUE); + demod_write_reg(DEMOD_TOP_REG8, DEMOD_REG8_VALUE); #endif } @@ -1477,28 +2181,28 @@ const unsigned int adc_check_tab_gxtvbb[] = { REG_M_HIU, D_HHI_ADC_PLL_CNTL4, /* REG_M_HIU, D_HHI_HDMI_CLK_CNTL, */ - REG_M_DEMOD, DEMOD_REG1, - REG_M_DEMOD, DEMOD_REG2, - REG_M_DEMOD, DEMOD_REG3, - REG_M_DEMOD, DEMOD_REG4, + REG_M_DEMOD, DEMOD_TOP_REG0, + REG_M_DEMOD, DEMOD_TOP_REG4, + REG_M_DEMOD, DEMOD_TOP_REG8, + REG_M_DEMOD, DEMOD_TOP_REGC, /* end */ TABLE_FLG_END, TABLE_FLG_END, }; const unsigned int adc_check_tab_demod_txlx[] = { - REG_M_DEMOD, DEMOD_REG1, - REG_M_DEMOD, DEMOD_REG2, - REG_M_DEMOD, DEMOD_REG3, - REG_M_DEMOD, DEMOD_REG4, + REG_M_DEMOD, DEMOD_TOP_REG0, + REG_M_DEMOD, DEMOD_TOP_REG4, + REG_M_DEMOD, DEMOD_TOP_REG8, + REG_M_DEMOD, DEMOD_TOP_REGC, /* end */ TABLE_FLG_END, TABLE_FLG_END, }; const unsigned int adc_check_tab_demod_gxbb[] = { - REG_M_DEMOD, DEMOD_REG1, - REG_M_DEMOD, DEMOD_REG2, - REG_M_DEMOD, DEMOD_REG3, - REG_M_DEMOD, DEMOD_REG4, + REG_M_DEMOD, DEMOD_TOP_REG0, + REG_M_DEMOD, DEMOD_TOP_REG4, + REG_M_DEMOD, DEMOD_TOP_REG8, + REG_M_DEMOD, DEMOD_TOP_REGC, /* end */ TABLE_FLG_END, TABLE_FLG_END, }; diff --git a/drivers/amlogic/media/dtv_demod/dtmb_func.c b/drivers/amlogic/media/dtv_demod/dtmb_func.c index 13b98ab96f57..784690961b0a 100644 --- a/drivers/amlogic/media/dtv_demod/dtmb_func.c +++ b/drivers/amlogic/media/dtv_demod/dtmb_func.c @@ -140,6 +140,19 @@ void dtmb_all_reset(void) dtmb_write_reg(DTMB_FRONT_46_CONFIG, 0x1a000f0f); dtmb_write_reg(DTMB_FRONT_ST_FREQ, 0xf2400000); dtmb_clk_set(Adc_Clk_24M); + } else if (is_ic_ver(IC_VER_TL1)) { + if (demod_get_adc_clk() == Adc_Clk_24M) { + dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x6aaaaa); + dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, 0x13196596); + dtmb_write_reg(0x5b << 2, 0x50a30a25); + } else if (demod_get_adc_clk() == Adc_Clk_25M) { + dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x62c1a5); + dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, 0x131a747d); + dtmb_write_reg(0x5b << 2, 0x4d6a0a25); + } + + //for timeshift issue(chuangcheng test) + dtmb_write_reg(0x4e << 2, 0x256cf604); } else { dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x10127); dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG6, 0x943228cc); @@ -194,7 +207,6 @@ void dtmb_initial(struct aml_demod_sta *demod_sta) dtmb_spectrum = demod_sta->spectrum; dtmb_register_reset(); dtmb_all_reset(); - } int check_dtmb_fec_lock(void) @@ -730,6 +742,7 @@ unsigned int dtmb_detect_first(void) has_signal = 0x1; } } + if (has_signal == 0x1) { /*fsm status is 6,digital signal*/ /*fsm (1->4) 30ms,(4->5) 20ms,*/ diff --git a/drivers/amlogic/media/dtv_demod/dvbc_func.c b/drivers/amlogic/media/dtv_demod/dvbc_func.c index e4775ca1117f..ca2ac4e98827 100644 --- a/drivers/amlogic/media/dtv_demod/dvbc_func.c +++ b/drivers/amlogic/media/dtv_demod/dvbc_func.c @@ -350,7 +350,7 @@ int dvbc_set_ch(struct aml_demod_sta *demod_sta, if (demod_sta->ch_if == 0) demod_sta->ch_if = 5000; demod_sta->symb_rate = symb_rate; - if (is_dvbc_ver(IC_DVBC_V3)) + if ((!is_ic_ver(IC_VER_TL1)) && is_dvbc_ver(IC_DVBC_V3)) demod_sta->adc_freq = demod_dvbc->dat0; #if 0 diff --git a/drivers/amlogic/media/dtv_demod/dvbc_v3.c b/drivers/amlogic/media/dtv_demod/dvbc_v3.c index a459920a9f1c..92bd3ccc007a 100644 --- a/drivers/amlogic/media/dtv_demod/dvbc_v3.c +++ b/drivers/amlogic/media/dtv_demod/dvbc_v3.c @@ -196,7 +196,10 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) clk_freq = demod_sta->clk_freq; /* kHz */ /*no use adc_freq = demod_sta->adc_freq;*/ /* kHz */ - adc_freq = get_adc_freq();/*24000*/; + if (is_ic_ver(IC_VER_TL1)) + adc_freq = demod_sta->adc_freq; + else + adc_freq = get_adc_freq();/*24000*/; adc_format = 1; /*ary no use tuner = demod_sta->tuner;*/ ch_mode = demod_sta->ch_mode; @@ -229,7 +232,12 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) switch (ch_mode) { case 0: /*16qam*/ qam_write_reg(0x71, 0x000a2200); - qam_write_reg(0x72, 0x0c2b04a9); + + if (is_ic_ver(IC_VER_TL1)) + qam_write_reg(0x72, 0xc2b0c49); + else + qam_write_reg(0x72, 0x0c2b04a9); + qam_write_reg(0x73, 0x02020000); qam_write_reg(0x75, 0x000e9178); qam_write_reg(0x76, 0x0001c100); @@ -246,7 +254,12 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) qam_write_reg(0x77, 0x001000d6); qam_write_reg(0x7a, 0x0019a7ff); qam_write_reg(0x7c, 0x00111222); - qam_write_reg(0x7d, 0x05050505); + + if (is_ic_ver(IC_VER_TL1)) + qam_write_reg(0x7d, 0x2020305); + else + qam_write_reg(0x7d, 0x05050505); + qam_write_reg(0x7e, 0x03000d0d); qam_write_reg(0x93, 0x641f1d0c); qam_write_reg(0x94, 0x0c1a1a00); @@ -261,14 +274,28 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) qam_write_reg(0x76, 0x00002013); qam_write_reg(0x77, 0x00035068); qam_write_reg(0x78, 0x000ab100); - qam_write_reg(0x7a, 0x002ba7ff); + + if (is_ic_ver(IC_VER_TL1)) + qam_write_reg(0x7a, 0xba7ff); + else + qam_write_reg(0x7a, 0x002ba7ff); + qam_write_reg(0x7c, 0x00111222); - qam_write_reg(0x7d, 0x05050505); + + if (is_ic_ver(IC_VER_TL1)) + qam_write_reg(0x7d, 0x2020305); + else + qam_write_reg(0x7d, 0x05050505); + qam_write_reg(0x7e, 0x03000d0d); qam_write_reg(0x93, 0x642a240c); qam_write_reg(0x94, 0x0c262600); break; case 4: + if (is_ic_ver(IC_VER_TL1)) { + qam_write_reg(0x9c, 0x2a232100); + qam_write_reg(0x57, 0x606040d); + } break; } /*dvbc_write_reg(QAM_BASE+0x00c, 0xfffffffe);*/ @@ -311,7 +338,11 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) max_frq_off = tmp * max_frq_off; } PR_DVBC("max_frq_off is %x,\n", max_frq_off); - qam_write_reg(0xb, max_frq_off & 0x3fffffff); + + if (is_ic_ver(IC_VER_TL1)) + qam_write_reg(0xc, 0x245cf450); //MODIFIED BY QIANCHENG + else + qam_write_reg(0xb, max_frq_off & 0x3fffffff); /* max frequency offset, by raymond 20121208 */ /*dvbc_write_reg(QAM_BASE+0x030, 0x011bf400);*/ @@ -335,6 +366,9 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) /*dvbc_write_reg(QAM_BASE+0x048, 3600*256);*/ /* // configure min symbol_rate fb = 6.95M*/ qam_write_reg(0x12, (qam_read_reg(0x12) & ~(0xff<<8)) | 3400 * 256); + + if (is_ic_ver(IC_VER_TL1)) + qam_write_reg(0x51, (qam_read_reg(0x51)&~(0x1<<28))); /* configure min symbol_rate fb = 6.95M */ /*dvbc_write_reg(QAM_BASE+0x0c0, 0xffffff68); // threshold */ @@ -378,8 +412,9 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) /* if Adjcent channel test, maybe it need change.*/ /*20121208 ad invert*/ /*rsj//qam_write_reg(0x28, 0x0603cd10);*/ - qam_write_reg(0x28, - qam_read_reg(0x28) | (adc_format << 27)); + if (!is_ic_ver(IC_VER_TL1)) + qam_write_reg(0x28, + qam_read_reg(0x28) | (adc_format << 27)); /* AGC_RFGAIN_CTRL 0x0e020800 by raymond,*/ /* if Adjcent channel test, maybe it need change.*/ /* 20121208 ad invert,20130221, suit for two path channel.*/ @@ -425,16 +460,21 @@ void dvbc_reg_initial(struct aml_demod_sta *demod_sta) qam_auto_scan(1); } #endif - qam_write_reg(0x7, 0x10f23); - qam_write_reg(0x3a, 0x0); - qam_write_reg(0x7, 0x10f33); - qam_write_reg(0x3a, 0x4); + if (!is_ic_ver(IC_VER_TL1)) { + qam_write_reg(0x7, 0x10f23); + qam_write_reg(0x3a, 0x0); + qam_write_reg(0x7, 0x10f33); + qam_write_reg(0x3a, 0x4); + } /*auto track*/ /* dvbc_set_auto_symtrack(); */ } u32 dvbc_set_auto_symtrack(void) { + if (is_ic_ver(IC_VER_TL1)) + return 0; + qam_write_reg(0xc, 0x245bf45c); /*open track */ qam_write_reg(0x8, 0x61b2bf5c); qam_write_reg(0x11, (7000 & 0xffff) * 256); @@ -512,6 +552,11 @@ void dvbc_init_reg_ext(void) { /*ary move from amlfrontend.c */ qam_write_reg(0x7, 0xf33); + + if (is_ic_ver(IC_VER_TL1)) { + qam_write_reg(0x12, 0x50e1000); + qam_write_reg(0x30, 0x41f2f69); + } } u32 dvbc_get_ch_sts(void) diff --git a/drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr.h b/drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr.h new file mode 100644 index 000000000000..700a16286e50 --- /dev/null +++ b/drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr.h @@ -0,0 +1,38 @@ +/* + * drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __ADDR_ATSC_CNTR_H__ +#define __ADDR_ATSC_CNTR_H__ + +#include "addr_atsc_cntr_bit.h" + +#define MOD_ATSC_CNTR 0x0 +#define ATSC_CNTR_ADDR(x) (MOD_ATSC_CNTR+(x)) + +#define ATSC_CNTR_REG_0X20 ATSC_CNTR_ADDR(0x20) +#define ATSC_CNTR_REG_0X21 ATSC_CNTR_ADDR(0x21) +#define ATSC_CNTR_REG_0X22 ATSC_CNTR_ADDR(0x22) +#define ATSC_CNTR_REG_0X23 ATSC_CNTR_ADDR(0x23) +#define ATSC_CNTR_REG_0X24 ATSC_CNTR_ADDR(0x24) +#define ATSC_CNTR_REG_0X29 ATSC_CNTR_ADDR(0x29) +#define ATSC_CNTR_REG_0X2A ATSC_CNTR_ADDR(0x2a) +#define ATSC_CNTR_REG_0X2B ATSC_CNTR_ADDR(0x2b) +#define ATSC_CNTR_REG_0X2C ATSC_CNTR_ADDR(0x2c) +#define ATSC_CNTR_REG_0X2D ATSC_CNTR_ADDR(0x2d) +#define ATSC_CNTR_REG_0X2E ATSC_CNTR_ADDR(0x2e) + +#endif diff --git a/drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr_bit.h b/drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr_bit.h new file mode 100644 index 000000000000..87d8e47fdeaa --- /dev/null +++ b/drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr_bit.h @@ -0,0 +1,89 @@ +/* + * drivers/amlogic/media/dtv_demod/include/addr_atsc_cntr_bit.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __ADDR_ATSC_CNTR_BIT_H__ +#define __ADDR_ATSC_CNTR_BIT_H__ + +union ATSC_CNTR_REG_0X20_BITS { + unsigned int bits; + struct { + unsigned int cpu_rst :1, + reserved0 :3, + cr_pilot_only :1, + reserved1 :27; + } b; +}; + +struct ATSC_CNTR_REG_0X21_BITS { + unsigned int sys_sm_ow_ctrl :10, + reserved2 :6, + nco_loop_close_dly :10, + reserved3 :6; +}; +struct ATSC_CNTR_REG_0X22_BITS { + unsigned int flock_to_cnt :8, + no_crlock_to :1, + reserved4 :3, + no_snr_to :1, + reserved5 :3, + no_ddm_to :1, + reserved6 :15; +}; +struct ATSC_CNTR_REG_0X23_BITS { + unsigned int flock_cnt_limit :6, + reserved7 :2, + flock_th :6, + reserved8 :2, + pn511_acum_th :16; +}; +struct ATSC_CNTR_REG_0X24_BITS { + unsigned int crdet_mode_sel_div :8, + crdet_mode_sel_ndiv :8, + ffe_tap_pwr_th :10, + reserved9 :6; +}; +struct ATSC_CNTR_REG_0X29_BITS { + unsigned int cw_rg0 :25, + reserved10 :7; +}; +struct ATSC_CNTR_REG_0X2A_BITS { + unsigned int cw_rg1 :25, + reserved11 :7; +}; +struct ATSC_CNTR_REG_0X2B_BITS { + unsigned int cw_rg2 :25, + reserved12 :7; +}; +struct ATSC_CNTR_REG_0X2C_BITS { + unsigned int cw_rg3 :25, + reserved13 :3, + cw_exists :1, + reserved14 :3; +}; +struct ATSC_CNTR_REG_0X2D_BITS { + unsigned int inband_pwr_avg_out :16, + inband_pwr_out :14, + reserved15 :1, + inband_pwr_low_flag :1; +}; +struct ATSC_CNTR_REG_0X2E_BITS { + unsigned int sys_states :4, + eq_states :4, + reserved16 :24; +}; + +#endif diff --git a/drivers/amlogic/media/dtv_demod/include/addr_atsc_demod.h b/drivers/amlogic/media/dtv_demod/include/addr_atsc_demod.h new file mode 100644 index 000000000000..561b3092d380 --- /dev/null +++ b/drivers/amlogic/media/dtv_demod/include/addr_atsc_demod.h @@ -0,0 +1,79 @@ +/* + * drivers/amlogic/media/dtv_demod/include/addr_atsc_demod.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __ADDR_ATSC_DEMOD_H__ +#define __ADDR_ATSC_DEMOD_H__ +#include "addr_atsc_demod_bit.h" + +#define MOD_ATSC_DEMOD 0x0 +#define ATSC_DEMOD_ADDR(x) (MOD_ATSC_DEMOD+(x)) + +#define ATSC_DEMOD_REG_0X52 ATSC_DEMOD_ADDR(0x52) +#define ATSC_DEMOD_REG_0X53 ATSC_DEMOD_ADDR(0x53) +#define ATSC_DEMOD_REG_0X54 ATSC_DEMOD_ADDR(0x54) +#define ATSC_DEMOD_REG_0X55 ATSC_DEMOD_ADDR(0x55) +#define ATSC_DEMOD_REG_0X56 ATSC_DEMOD_ADDR(0x56) +#define ATSC_DEMOD_REG_0X58 ATSC_DEMOD_ADDR(0x58) +#define ATSC_DEMOD_REG_0X59 ATSC_DEMOD_ADDR(0x59) +#define ATSC_DEMOD_REG_0X5A ATSC_DEMOD_ADDR(0x5a) +#define ATSC_DEMOD_REG_0X5B ATSC_DEMOD_ADDR(0x5b) +#define ATSC_DEMOD_REG_0X5C ATSC_DEMOD_ADDR(0x5c) +#define ATSC_DEMOD_REG_0X5D ATSC_DEMOD_ADDR(0x5d) +#define ATSC_DEMOD_REG_0X5E ATSC_DEMOD_ADDR(0x5e) +#define ATSC_DEMOD_REG_0X5F ATSC_DEMOD_ADDR(0x5f) +#define ATSC_DEMOD_REG_0X60 ATSC_DEMOD_ADDR(0x60) +#define ATSC_DEMOD_REG_0X61 ATSC_DEMOD_ADDR(0x61) +#define ATSC_DEMOD_REG_0X62 ATSC_DEMOD_ADDR(0x62) +#define ATSC_DEMOD_REG_0X63 ATSC_DEMOD_ADDR(0x63) +#define ATSC_DEMOD_REG_0X64 ATSC_DEMOD_ADDR(0x64) +#define ATSC_DEMOD_REG_0X65 ATSC_DEMOD_ADDR(0x65) +#define ATSC_DEMOD_REG_0X66 ATSC_DEMOD_ADDR(0x66) +#define ATSC_DEMOD_REG_0X67 ATSC_DEMOD_ADDR(0x67) +#define ATSC_DEMOD_REG_0X68 ATSC_DEMOD_ADDR(0x68) +#define ATSC_DEMOD_REG_0X69 ATSC_DEMOD_ADDR(0x69) +#define ATSC_DEMOD_REG_0X6A ATSC_DEMOD_ADDR(0x6a) +#define ATSC_DEMOD_REG_0X6B ATSC_DEMOD_ADDR(0x6b) +#define ATSC_DEMOD_REG_0X6C ATSC_DEMOD_ADDR(0x6c) +#define ATSC_DEMOD_REG_0X6D ATSC_DEMOD_ADDR(0x6d) +#define ATSC_DEMOD_REG_0X6E ATSC_DEMOD_ADDR(0x6e) +#define ATSC_DEMOD_REG_0X70 ATSC_DEMOD_ADDR(0x70) +#define ATSC_DEMOD_REG_0X71 ATSC_DEMOD_ADDR(0x71) +#define ATSC_DEMOD_REG_0X72 ATSC_DEMOD_ADDR(0x72) +#define ATSC_DEMOD_REG_0X73 ATSC_DEMOD_ADDR(0x73) +#define ATSC_DEMOD_REG_0X74 ATSC_DEMOD_ADDR(0x74) +#define ATSC_DEMOD_REG_0X75 ATSC_DEMOD_ADDR(0x75) +#define ATSC_DEMOD_REG_0X76 ATSC_DEMOD_ADDR(0x76) +#define ATSC_DEMOD_REG_0X77 ATSC_DEMOD_ADDR(0x77) +#define ATSC_DEMOD_REG_0X78 ATSC_DEMOD_ADDR(0x78) +#define ATSC_DEMOD_REG_0X79 ATSC_DEMOD_ADDR(0x79) +#define ATSC_DEMOD_REG_0X7A ATSC_DEMOD_ADDR(0x7a) +#define ATSC_DEMOD_REG_0X7B ATSC_DEMOD_ADDR(0x7b) +#define ATSC_DEMOD_REG_0X7C ATSC_DEMOD_ADDR(0x7c) +#define ATSC_DEMOD_REG_0X7D ATSC_DEMOD_ADDR(0x7d) +#define ATSC_DEMOD_REG_0X7E ATSC_DEMOD_ADDR(0x7e) +#define ATSC_DEMOD_REG_0X7F ATSC_DEMOD_ADDR(0x7f) +#define ATSC_DEMOD_REG_0X80 ATSC_DEMOD_ADDR(0x80) +#define ATSC_DEMOD_REG_0X81 ATSC_DEMOD_ADDR(0x81) +#define ATSC_DEMOD_REG_0X82 ATSC_DEMOD_ADDR(0x82) +#define ATSC_DEMOD_REG_0X83 ATSC_DEMOD_ADDR(0x83) +#define ATSC_DEMOD_REG_0X84 ATSC_DEMOD_ADDR(0x84) +#define ATSC_DEMOD_REG_0X85 ATSC_DEMOD_ADDR(0x85) +#define ATSC_DEMOD_REG_0X86 ATSC_DEMOD_ADDR(0x86) +#define ATSC_DEMOD_REG_0X87 ATSC_DEMOD_ADDR(0x87) +#define ATSC_DEMOD_REG_0X88 ATSC_DEMOD_ADDR(0x88) + +#endif diff --git a/drivers/amlogic/media/dtv_demod/include/addr_atsc_demod_bit.h b/drivers/amlogic/media/dtv_demod/include/addr_atsc_demod_bit.h new file mode 100644 index 000000000000..be7532876239 --- /dev/null +++ b/drivers/amlogic/media/dtv_demod/include/addr_atsc_demod_bit.h @@ -0,0 +1,363 @@ +/* + * drivers/amlogic/media/dtv_demod/include/addr_atsc_demod_bit.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __ADDR_ATSC_DEMOD_BIT_H__ +#define __ADDR_ATSC_DEMOD_BIT_H__ + +struct ATSC_DEMOD_REG_0X52_BITS { + unsigned int lpf_crgn_3 :5, + reserved0 :3, + lpf_crgn_4 :5, + reserved1 :3, + lpf_crgn_5 :5, + reserved2 :3, + lpf_crgn_6 :5, + reserved3 :3; +}; +struct ATSC_DEMOD_REG_0X53_BITS { + unsigned int lpf_crgn_0 :5, + reserved4 :3, + lpf_crgn_1 :5, + reserved5 :3, + lpf_crgn_2 :5, + reserved6 :11; +}; + +union ATSC_DEMOD_REG_0X54_BITS { + unsigned int bits; + struct { + unsigned int cr_rate :23, + reserved7 :9; + } b; +}; +union ATSC_DEMOD_REG_0X55_BITS { + unsigned int bits; + struct { + unsigned int ck_rate :24, + reserved8 :8; + } b; +}; +struct ATSC_DEMOD_REG_0X56_BITS { + unsigned int dc_frz :1, + fagc_frz :1, + inv_spectrum :1, + qam_vsr_frz :1, + ck_rate_frz :1, + no_sym_en_ctrl :1, + cr_open_loop :1, + qam_vsr_sel :1, + dc_rmv_bw :4, + reserved9 :20; +}; +struct ATSC_DEMOD_REG_0X58_BITS { + unsigned int fagc_bw :4, + reserved10 :4, + fagc_ref_level :20, + fagc_ref_level_sel :1, + reserved11 :3; +}; +struct ATSC_DEMOD_REG_0X59_BITS { + unsigned int fs_dly_num :10, + reserved12 :22; +}; +struct ATSC_DEMOD_REG_0X5A_BITS { + unsigned int pk512_th :12, + reserved13 :4, + prescale :3, + reserved14 :13; +}; +struct ATSC_DEMOD_REG_0X5B_BITS { + unsigned int fagc_fix_gain :12, + reserved15 :4, + fcorv_th :8, + reserved16 :8; +}; +struct ATSC_DEMOD_REG_0X5C_BITS { + unsigned int m1m2rate_1 :8, + m1m2rate_2 :8, + m1m2rate_3 :8, + m1m2rate_4 :8; +}; +union ATSC_DEMOD_REG_0X5D_BITS { + unsigned int bits; + struct { + unsigned int fld_conf_cnt :8, + clk_conf_cnt :8, + clk_conf_cnt_limit :8; + } b; +}; +struct ATSC_DEMOD_REG_0X5E_BITS { + unsigned int balance_track_bw :8, + balance_track_dir :1, + reserved17 :3, + balance_track :3, + reserved18 :17; +}; +struct ATSC_DEMOD_REG_0X5F_BITS { + unsigned int div_mix_rate :4, + div_mix_en :1, + reserved19 :27; +}; +struct ATSC_DEMOD_REG_0X60_BITS { + unsigned int cr_stepsize :4, + cr_dc_sum_cnt :4, + cr_enable :1, + reserved20 :23; +}; +union ATSC_DEMOD_REG_0X61_BITS { + unsigned int bits; + struct { + unsigned int cr_bin_freq1 :11, + reserved21 :5, + cr_bin_freq2 :11, + reserved22 :5; + } b; +}; +struct ATSC_DEMOD_REG_0X62_BITS { + unsigned int coef0 :6, + reserved23 :2, + coef1 :6, + reserved24 :2, + coef2 :6, + reserved25 :2, + coef3 :6, + reserved26 :2; +}; +struct ATSC_DEMOD_REG_0X63_BITS { + unsigned int coef4 :6, + reserved27 :2, + coef5 :6, + reserved28 :2, + coef6 :6, + reserved29 :2, + coef7 :6, + reserved30 :2; +}; +struct ATSC_DEMOD_REG_0X64_BITS { + unsigned int coef8 :6, + reserved31 :2, + coef9 :6, + reserved32 :2, + coef10 :6, + reserved33 :2, + coef11 :6, + reserved34 :2; +}; +struct ATSC_DEMOD_REG_0X65_BITS { + unsigned int coef12 :6, + reserved35 :2, + coef13 :7, + reserved36 :1, + coef14 :7, + reserved37 :1, + coef15 :8; +}; +struct ATSC_DEMOD_REG_0X66_BITS { + unsigned int coef16 :8, + reserved38 :24; +}; +struct ATSC_DEMOD_REG_0X67_BITS { + unsigned int coef17 :9, + reserved39 :7, + coef18 :9, + reserved40 :7; +}; +struct ATSC_DEMOD_REG_0X68_BITS { + unsigned int coef19 :10, + reserved41 :6, + coef20 :10, + reserved42 :6; +}; +struct ATSC_DEMOD_REG_0X69_BITS { + unsigned int cf_rnd_bits :2, + reserved43 :30; +}; +union ATSC_DEMOD_REG_0X6A_BITS { + unsigned int bits; + struct{ + unsigned int peak_thd :4, + cfo_alpha :4, + ccfo_intv2 :6, + reserved44 :2, + ccfo_intv1 :6, + reserved45 :2, + ccfo_intv0 :6, + ccfo_do_disable :1, + ccfo_enable :1; + } b; +}; +struct ATSC_DEMOD_REG_0X6B_BITS { + unsigned int ccfo_freq_coef1 :10, + reserved46 :6, + ccfo_freq_coef2 :10, + reserved47 :6; +}; +struct ATSC_DEMOD_REG_0X6C_BITS { + unsigned int ccfo_freq_coef3 :10, + reserved48 :6, + ccfo_freq_coef4 :10, + reserved49 :6; +}; +struct ATSC_DEMOD_REG_0X6D_BITS { + unsigned int ccfo_fs :10, + reserved50 :22; +}; +union ATSC_DEMOD_REG_0X6E_BITS { + unsigned int bits; + struct { + unsigned int adc_fs :26, + reserved51 :6; + } b; +}; +struct ATSC_DEMOD_REG_0X70_BITS { + unsigned int gain_step :8, + gain_step_er :8, + soft_gain_in :12, + reserved52 :4; +}; +struct ATSC_DEMOD_REG_0X71_BITS { + unsigned int dagc_mode :2, + reserved53 :2, + dagc_power_alpha :2, + reserved54 :2, + dagc_out_mux :1, + reserved55 :23; +}; +union ATSC_DEMOD_REG_0X72_BITS { + unsigned int bits; + struct { + unsigned int avg_power :8, + gain_result :12, + dagc_ready :1, + reserved56 :11; + } b; +}; +struct ATSC_DEMOD_REG_0X73_BITS { + unsigned int cr_err_lpf1 :24, + reserved57 :8; +}; +struct ATSC_DEMOD_REG_0X74_BITS { + unsigned int cr_err_lpf2 :19, + reserved58 :13; +}; +struct ATSC_DEMOD_REG_0X75_BITS { + unsigned int clk_offset :21, + reserved59 :11; +}; +struct ATSC_DEMOD_REG_0X76_BITS { + unsigned int agc_sat1 :1, + reserved60 :3, + agc_sat2 :1, + reserved61 :27; +}; +struct ATSC_DEMOD_REG_0X77_BITS { + unsigned int i_dc_out1 :12, + reserved62 :4, + q_dc_out1 :12, + reserved63 :4; +}; +struct ATSC_DEMOD_REG_0X78_BITS { + unsigned int i_dc_out2 :12, + reserved64 :4, + q_dc_out2 :12, + reserved65 :4; +}; +struct ATSC_DEMOD_REG_0X79_BITS { + unsigned int cr_avg_cw1_i :12, + reserved66 :4, + cr_avg_cw1_q :12, + reserved67 :4; +}; +struct ATSC_DEMOD_REG_0X7A_BITS { + unsigned int cr_avg_cw2_i :12, + reserved68 :4, + cr_avg_cw2_q :12, + reserved69 :4; +}; +struct ATSC_DEMOD_REG_0X7B_BITS { + unsigned int phase_shift :23, + reserved70 :1, + qam_phase_err_ctrl :2, + reserved71 :6; +}; +struct ATSC_DEMOD_REG_0X7C_BITS { + unsigned int cr_ofst_gna :15, + reserved72 :17; +}; +struct ATSC_DEMOD_REG_0X7D_BITS { + unsigned int cr_ofst_a2 :17, + reserved73 :15; +}; +struct ATSC_DEMOD_REG_0X7E_BITS { + unsigned int cr_ofst_a1 :18, + reserved74 :14; +}; +struct ATSC_DEMOD_REG_0X7F_BITS { + unsigned int ru_ofst_gna :15, + reserved75 :17; +}; +struct ATSC_DEMOD_REG_0X80_BITS { + unsigned int ru_ofst_a2 :17, + reserved76 :15; +}; +struct ATSC_DEMOD_REG_0X81_BITS { + unsigned int ru_ofst_a1 :18, + reserved77 :14; +}; +struct ATSC_DEMOD_REG_0X82_BITS { + unsigned int fagc_ref_l_eqst0 :8, + fagc_ref_l_eqst1 :8, + fagc_ref_l_eqst2 :8, + fagc_ref_l_eqst3 :8; +}; +struct ATSC_DEMOD_REG_0X83_BITS { + unsigned int fagc_ref_l_eqst4 :8, + fagc_ref_l_eqst5 :8, + fagc_ref_l_eqst6 :8, + fagc_ref_l_eqst7 :8; +}; +struct ATSC_DEMOD_REG_0X84_BITS { + unsigned int fagc_ref_l_eqst8 :8, + fagc_ref_l_eqst9 :8, + reserved78 :16; +}; +struct ATSC_DEMOD_REG_0X85_BITS { + unsigned int fagc_ref_h_eqst0 :8, + fagc_ref_h_eqst1 :8, + fagc_ref_h_eqst2 :8, + fagc_ref_h_eqst3 :8; +}; +struct ATSC_DEMOD_REG_0X86_BITS { + unsigned int fagc_ref_h_eqst4 :8, + fagc_ref_h_eqst5 :8, + fagc_ref_h_eqst6 :8, + fagc_ref_h_eqst7 :8; +}; +struct ATSC_DEMOD_REG_0X87_BITS { + unsigned int fagc_ref_h_eqst8 :8, + fagc_ref_h_eqst9 :8, + reserved79 :16; +}; +union ATSC_DEMOD_REG_0X88_BITS { + unsigned int bits; + struct{ + unsigned int ccfo_pow_peak :16, + ccfo_avg_peak :16; + } b; +}; + +#endif diff --git a/drivers/amlogic/media/dtv_demod/include/addr_atsc_eq.h b/drivers/amlogic/media/dtv_demod/include/addr_atsc_eq.h new file mode 100644 index 000000000000..2cc1348e9d20 --- /dev/null +++ b/drivers/amlogic/media/dtv_demod/include/addr_atsc_eq.h @@ -0,0 +1,98 @@ +/* + * drivers/amlogic/media/dtv_demod/include/addr_atsc_eq.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __ADDR_ATSC_EQ_H__ +#define __ADDR_ATSC_EQ_H__ +#include "addr_atsc_eq_bit.h" + +#define MOD_ATSC_EQ 0x0 +#define ATSC_EQ_ADDR(x) (MOD_ATSC_EQ+(x)) + +#define ATSC_EQ_REG_0X90 ATSC_EQ_ADDR(0x90) +#define ATSC_EQ_REG_0X91 ATSC_EQ_ADDR(0x91) +#define ATSC_EQ_REG_0X92 ATSC_EQ_ADDR(0x92) +#define ATSC_EQ_REG_0X93 ATSC_EQ_ADDR(0x93) +#define ATSC_EQ_REG_0X94 ATSC_EQ_ADDR(0x94) +#define ATSC_EQ_REG_0X95 ATSC_EQ_ADDR(0x95) +#define ATSC_EQ_REG_0X96 ATSC_EQ_ADDR(0x96) +#define ATSC_EQ_REG_0X97 ATSC_EQ_ADDR(0x97) +#define ATSC_EQ_REG_0X98 ATSC_EQ_ADDR(0x98) +#define ATSC_EQ_REG_0X99 ATSC_EQ_ADDR(0x99) +#define ATSC_EQ_REG_0X9A ATSC_EQ_ADDR(0x9a) +#define ATSC_EQ_REG_0X9B ATSC_EQ_ADDR(0x9b) +#define ATSC_EQ_REG_0X9C ATSC_EQ_ADDR(0x9c) +#define ATSC_EQ_REG_0X9D ATSC_EQ_ADDR(0x9d) +#define ATSC_EQ_REG_0X9E ATSC_EQ_ADDR(0x9e) +#define ATSC_EQ_REG_0X9F ATSC_EQ_ADDR(0x9f) +#define ATSC_EQ_REG_0XA0 ATSC_EQ_ADDR(0xa0) +#define ATSC_EQ_REG_0XA1 ATSC_EQ_ADDR(0xa1) +#define ATSC_EQ_REG_0XA2 ATSC_EQ_ADDR(0xa2) +#define ATSC_EQ_REG_0XA3 ATSC_EQ_ADDR(0xa3) +#define ATSC_EQ_REG_0XA4 ATSC_EQ_ADDR(0xa4) +#define ATSC_EQ_REG_0XA5 ATSC_EQ_ADDR(0xa5) +#define ATSC_EQ_REG_0XA6 ATSC_EQ_ADDR(0xa6) +#define ATSC_EQ_REG_0XA7 ATSC_EQ_ADDR(0xa7) +#define ATSC_EQ_REG_0XA8 ATSC_EQ_ADDR(0xa8) +#define ATSC_EQ_REG_0XA9 ATSC_EQ_ADDR(0xa9) +#define ATSC_EQ_REG_0XAA ATSC_EQ_ADDR(0xaa) +#define ATSC_EQ_REG_0XAB ATSC_EQ_ADDR(0xab) +#define ATSC_EQ_REG_0XAC ATSC_EQ_ADDR(0xac) +#define ATSC_EQ_REG_0XAD ATSC_EQ_ADDR(0xad) +#define ATSC_EQ_REG_0XAE ATSC_EQ_ADDR(0xae) +#define ATSC_EQ_REG_0XAF ATSC_EQ_ADDR(0xaf) +#define ATSC_EQ_REG_0XB0 ATSC_EQ_ADDR(0xb0) +#define ATSC_EQ_REG_0XB1 ATSC_EQ_ADDR(0xb1) +#define ATSC_EQ_REG_0XB2 ATSC_EQ_ADDR(0xb2) +#define ATSC_EQ_REG_0XB3 ATSC_EQ_ADDR(0xb3) +#define ATSC_EQ_REG_0XB4 ATSC_EQ_ADDR(0xb4) +#define ATSC_EQ_REG_0XB5 ATSC_EQ_ADDR(0xb5) +#define ATSC_EQ_REG_0XB6 ATSC_EQ_ADDR(0xb6) +#define ATSC_EQ_REG_0XB7 ATSC_EQ_ADDR(0xb7) +#define ATSC_EQ_REG_0XB8 ATSC_EQ_ADDR(0xb8) +#define ATSC_EQ_REG_0XB9 ATSC_EQ_ADDR(0xb9) +#define ATSC_EQ_REG_0XBA ATSC_EQ_ADDR(0xba) +#define ATSC_EQ_REG_0XBB ATSC_EQ_ADDR(0xbb) +#define ATSC_EQ_REG_0XBC ATSC_EQ_ADDR(0xbc) +#define ATSC_EQ_REG_0XBD ATSC_EQ_ADDR(0xbd) +#define ATSC_EQ_REG_0XBE ATSC_EQ_ADDR(0xbe) +#define ATSC_EQ_REG_0XBF ATSC_EQ_ADDR(0xbf) +#define ATSC_EQ_REG_0XC0 ATSC_EQ_ADDR(0xc0) +#define ATSC_EQ_REG_0XC1 ATSC_EQ_ADDR(0xc1) +#define ATSC_EQ_REG_0XC2 ATSC_EQ_ADDR(0xc2) +#define ATSC_EQ_REG_0XC3 ATSC_EQ_ADDR(0xc3) +#define ATSC_EQ_REG_0XC4 ATSC_EQ_ADDR(0xc4) +#define ATSC_EQ_REG_0XC5 ATSC_EQ_ADDR(0xc5) +#define ATSC_EQ_REG_0XC6 ATSC_EQ_ADDR(0xc6) +#define ATSC_EQ_REG_0XC7 ATSC_EQ_ADDR(0xc7) +#define ATSC_EQ_REG_0XC8 ATSC_EQ_ADDR(0xc8) +#define ATSC_EQ_REG_0XC9 ATSC_EQ_ADDR(0xc9) +#define ATSC_EQ_REG_0XCA ATSC_EQ_ADDR(0xca) +#define ATSC_EQ_REG_0XCB ATSC_EQ_ADDR(0xcb) +#define ATSC_EQ_REG_0XCC ATSC_EQ_ADDR(0xcc) +#define ATSC_EQ_REG_0XCD ATSC_EQ_ADDR(0xcd) +#define ATSC_EQ_REG_0XD0 ATSC_EQ_ADDR(0xd0) +#define ATSC_EQ_REG_0XD1 ATSC_EQ_ADDR(0xd1) +#define ATSC_EQ_REG_0XD2 ATSC_EQ_ADDR(0xd2) +#define ATSC_EQ_REG_0XD3 ATSC_EQ_ADDR(0xd3) +#define ATSC_EQ_REG_0XD4 ATSC_EQ_ADDR(0xd4) +#define ATSC_EQ_REG_0XD5 ATSC_EQ_ADDR(0xd5) +#define ATSC_EQ_REG_0XD6 ATSC_EQ_ADDR(0xd6) +#define ATSC_EQ_REG_0XD7 ATSC_EQ_ADDR(0xd7) +#define ATSC_EQ_REG_0XD8 ATSC_EQ_ADDR(0xd8) +#define ATSC_EQ_REG_0XD9 ATSC_EQ_ADDR(0xd9) + +#endif diff --git a/drivers/amlogic/media/dtv_demod/include/addr_atsc_eq_bit.h b/drivers/amlogic/media/dtv_demod/include/addr_atsc_eq_bit.h new file mode 100644 index 000000000000..4714ef4955ca --- /dev/null +++ b/drivers/amlogic/media/dtv_demod/include/addr_atsc_eq_bit.h @@ -0,0 +1,516 @@ +/* + * drivers/amlogic/media/dtv_demod/include/addr_atsc_eq_bit.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __ADDR_ATSC_EQ_BIT_H__ +#define __ADDR_ATSC_EQ_BIT_H__ + +struct ATSC_EQ_REG_0X90_BITS { + unsigned int eq_sm_ow_ctrl :10, + reserved0 :22; +}; +union ATSC_EQ_REG_0X91_BITS { + unsigned int bits; + struct { + unsigned int pn63_err_gen_en :1, + reserved1 :3, + ffe_out_sft_left_one :1, + reserved2 :3, + fft_leak_type_sel :1, + reserved3 :3, + iir_limit_sel :1, + reserved4 :3, + iir_tap_rw_en :1, + reserved5 :3, + div_path_sel :1, + reserved6 :3, + div_en :1, + reserved7 :3, + dfe_tap_wr_en :1, + reserved8 :3; + } b; +}; +union ATSC_EQ_REG_0X92_BITS { + unsigned int bits; + struct { + unsigned int dec_stage_sel :4, + nco_trk_phs_rnd :4, + eq_ph_loop_open :8, + dfe_dly_sym_slicer_sel :3, + reserved9 :1, + err_gen_sel :2, + reserved10 :2, + eq_err_rot_en :1, + reserved11 :5, + cwrmv_enable :1, + reserved12 :1; + } b; +}; + +union ATSC_EQ_REG_0X93_BITS { + unsigned int bits; + struct { + unsigned int eq_out_start_dly :11, + reserved13 :5, + eq_ffe_symb_thr :8, + fir_out_exp :5, + reserved14 :3; + } b; +}; +struct ATSC_EQ_REG_0X94_BITS { + unsigned int snr_calc_num :16, + err_fft_start_cnt :16; +}; + +struct ATSC_EQ_REG_0X95_BITS { + unsigned int stswthup1 :8, + stswthup2 :8, + stswthup3 :8, + stswthup4 :8; +}; +struct ATSC_EQ_REG_0X96_BITS { + unsigned int stswthup5 :8, + stswthup6 :8, + stswthup7 :8, + stswthup8 :8; +}; +struct ATSC_EQ_REG_0X97_BITS { + unsigned int stswthdn1 :8, + stswthdn2 :8, + stswthdn3 :8, + stswthdn4 :8; +}; +struct ATSC_EQ_REG_0X98_BITS { + unsigned int stswthdn5 :8, + stswthdn6 :8, + stswthdn7 :8, + stswthdn8 :8; +}; +struct ATSC_EQ_REG_0X99_BITS { + unsigned int fir_step_1t :5, + reserved15 :3, + fir_step_2t :5, + reserved16 :3, + fir_step_3t :5, + reserved17 :3, + fir_step_4t :5, + reserved18 :3; +}; +struct ATSC_EQ_REG_0X9A_BITS { + unsigned int fir_step_5t :5, + reserved19 :3, + fir_step_6t :5, + reserved20 :3, + fir_step_7t :5, + reserved21 :3, + fir_step_8t :5, + reserved22 :3; +}; +struct ATSC_EQ_REG_0X9B_BITS { + unsigned int fir_step_1d :5, + reserved23 :3, + fir_step_2d :5, + reserved24 :3, + fir_step_3d :5, + reserved25 :3, + fir_step_4d :5, + reserved26 :3; +}; +struct ATSC_EQ_REG_0X9C_BITS { + unsigned int fir_step_5d :5, + reserved27 :3, + fir_step_6d :5, + reserved28 :3, + fir_step_7d :5, + reserved29 :3, + fir_step_8d :5, + reserved30 :3; +}; +struct ATSC_EQ_REG_0X9D_BITS { + unsigned int step_size_exp5_1 :5, + reserved31 :3, + step_size_exp5_2 :5, + reserved32 :3, + step_size_exp5_3 :5, + reserved33 :3, + step_size_exp5_4 :5, + reserved34 :3; +}; +struct ATSC_EQ_REG_0X9E_BITS { + unsigned int step_size_exp5_5 :5, + reserved35 :3, + step_size_exp5_6 :5, + reserved36 :3, + step_size_exp5_7 :5, + reserved37 :3, + step_size_exp5_8 :5, + reserved38 :3; +}; +struct ATSC_EQ_REG_0X9F_BITS { + unsigned int iir_gn4 :7, + reserved39 :1, + iir_gn5 :7, + reserved40 :1, + iir_gn6 :7, + reserved41 :1, + iir_gn7 :7, + reserved42 :1; +}; +struct ATSC_EQ_REG_0XA0_BITS { + unsigned int iir_gn8 :7, + reserved43 :25; +}; +struct ATSC_EQ_REG_0XA1_BITS { + unsigned int iir_gn4t :7, + reserved44 :1, + iir_gn5t :7, + reserved45 :1, + iir_gn6t :7, + reserved46 :1, + iir_gn7t :7, + reserved47 :1; +}; +struct ATSC_EQ_REG_0XA2_BITS { + unsigned int iir_gn8t :7, + reserved48 :25; +}; +struct ATSC_EQ_REG_0XA3_BITS { + unsigned int ft_step_size5 :4, + ft_step_size6 :4, + ft_step_size7 :4, + ft_step_size8 :4, + pt_step_size5 :4, + pt_step_size6 :4, + pt_step_size7 :4, + pt_step_size8 :4; +}; +struct ATSC_EQ_REG_0XA4_BITS { + unsigned int pt_gain_size5 :5, + reserved49 :3, + pt_gain_size6 :5, + reserved50 :3, + pt_gain_size7 :5, + reserved51 :3, + pt_gain_size8 :5, + reserved52 :3; +}; +union ATSC_EQ_REG_0XA5_BITS { + unsigned int bits; + struct{ + unsigned int eqst2_up_cnt :8, + eqst3_up_cnt :8, + eqst4_up_cnt :8, + eqst5_up_cnt :8; + } b; +}; +struct ATSC_EQ_REG_0XA6_BITS { + unsigned int eqst6_up_cnt :8, + eqst7_up_cnt :8, + eqst8_up_cnt :8, + eqst9_up_cnt :8; +}; +struct ATSC_EQ_REG_0XA7_BITS { + unsigned int eqst2_to_cnt :7, + reserved53 :1, + eqst3_to_cnt :7, + reserved54 :1, + eqst4_to_cnt :7, + reserved55 :1, + eqst5_to_cnt :7, + reserved56 :1; +}; +struct ATSC_EQ_REG_0XA8_BITS { + unsigned int eqst6_to_cnt :7, + reserved57 :1, + eqst7_to_cnt :7, + reserved58 :1, + eqst8_to_cnt :7, + reserved59 :1, + eqst9_to_cnt :7, + reserved60 :1; +}; +union ATSC_EQ_REG_0XA9_BITS { + unsigned int bits; + struct{ + unsigned int iir_err_range_sel4 :3, + reserved61 :1, + iir_err_range_sel5 :3, + reserved62 :1, + iir_err_range_sel6 :3, + reserved63 :1, + iir_err_range_sel7 :3, + reserved64 :1, + iir_err_range_sel8 :3, + reserved65 :13; + } b; +}; +struct ATSC_EQ_REG_0XAA_BITS { + unsigned int eq_ctrl0 :10, + reserved66 :6, + eq_ctrl1 :10, + reserved67 :6; +}; +struct ATSC_EQ_REG_0XAB_BITS { + unsigned int eq_ctrl2 :10, + reserved68 :6, + eq_ctrl3 :10, + reserved69 :6; +}; +struct ATSC_EQ_REG_0XAC_BITS { + unsigned int eq_ctrl4 :10, + reserved70 :6, + eq_ctrl5 :10, + reserved71 :6; +}; +union ATSC_EQ_REG_0XAD_BITS { + unsigned int bits; + struct { + unsigned int eq_ctrl6 :10, + reserved72 :6, + eq_ctrl7 :10, + reserved73 :6; + } b; +}; +struct ATSC_EQ_REG_0XAE_BITS { + unsigned int eq_ctrl8 :10, + reserved74 :6, + eq_ctrl9 :10, + reserved75 :6; +}; +struct ATSC_EQ_REG_0XAF_BITS { + unsigned int ffe_leak_set_rca1 :12, + reserved76 :4, + ffe_leak_set_train :12, + reserved77 :4; +}; +struct ATSC_EQ_REG_0XB0_BITS { + unsigned int ffe_leak_set_ddm :12, + reserved78 :4, + ffe_leak_set_rca2 :12, + reserved79 :4; +}; +struct ATSC_EQ_REG_0XB1_BITS { + unsigned int ffe_slope_leak_set_rca1 :12, + reserved80 :4, + ffe_slope_leak_set_train :12, + reserved81 :4; +}; +struct ATSC_EQ_REG_0XB2_BITS { + unsigned int ffe_slope_leak_set_ddm :12, + reserved82 :4, + ffe_slope_leak_set_rca2 :12, + reserved83 :4; +}; +struct ATSC_EQ_REG_0XB3_BITS { + unsigned int ffe_leak_rate_set_ddm :8, + ffe_leak_rate_set_rca2 :8, + ffe_leak_rate_set_rca1 :8, + ffe_leak_rate_set_train :8; +}; +struct ATSC_EQ_REG_0XB4_BITS { + unsigned int err_limit_set_ddm_rca :4, + err_limit_set_rca2_rca :4, + err_limit_set_rca1_rca :4, + err_limit_set_train_rca :4, + err_limit_set_ddm_cma :4, + err_limit_set_rca2_cma :4, + err_limit_set_rca1_cma :4, + err_limit_set_train_cma :4; +}; +struct ATSC_EQ_REG_0XB5_BITS { + unsigned int ffe_tap_update_limit_set_ddm :4, + ffe_tap_update_limit_set_rca2 :4, + ffe_tap_update_limit_set_rca1 :4, + ffe_tap_update_limit_set_train :4, + ffe_stepsizexerr_limit_set_ddm :4, + ffe_stepsizexerr_limit_set_rca2 :4, + ffe_stepsizexerr_limit_set_rca1 :4, + ffe_stepsizexerr_limit_set_train :4; +}; +struct ATSC_EQ_REG_0XB6_BITS { + unsigned int ffe_conj_data_limit_set_ddm :5, + reserved84 :3, + ffe_conj_data_limit_set_rca2 :5, + reserved85 :3, + ffe_conj_data_limit_set_rca1 :5, + reserved86 :3, + ffe_conj_data_limit_set_train :5, + reserved87 :3; +}; +struct ATSC_EQ_REG_0XB7_BITS { + unsigned int iir_leak_rate_ddm :16, + iir_leak_rate_blind :16; +}; +struct ATSC_EQ_REG_0XB8_BITS { + unsigned int iir_leak_rate1_ddm :16, + iir_leak_rate1_blind :16; +}; +struct ATSC_EQ_REG_0XB9_BITS { + unsigned int iir1_st0_tap_limit_up4 :8, + iir1_st0_tap_limit_up5 :8, + iir1_st0_tap_limit_up6 :8, + iir1_st0_tap_limit_up7 :8; +}; +struct ATSC_EQ_REG_0XBA_BITS { + unsigned int iir1_st0_tap_limit_up8 :8, + iir1_st0_tap_limit_low4 :8, + iir1_st0_tap_limit_low5 :8, + iir1_st0_tap_limit_low6 :8; +}; +struct ATSC_EQ_REG_0XBB_BITS { + unsigned int iir1_st0_tap_limit_low7 :8, + iir1_st0_tap_limit_low8 :8, + iir1_st1_tap_limit_up4 :8, + iir1_st1_tap_limit_up5 :8; +}; +struct ATSC_EQ_REG_0XBC_BITS { + unsigned int iir1_st1_tap_limit_up6 :8, + iir1_st1_tap_limit_up7 :8, + iir1_st1_tap_limit_up8 :8, + iir1_st1_tap_limit_low4 :8; +}; +struct ATSC_EQ_REG_0XBD_BITS { + unsigned int iir1_st1_tap_limit_low5 :8, + iir1_st1_tap_limit_low6 :8, + iir1_st1_tap_limit_low7 :8, + iir1_st1_tap_limit_low8 :8; +}; +struct ATSC_EQ_REG_0XBE_BITS { + unsigned int iir2_st0_tap_limit_up4 :8, + iir2_st0_tap_limit_up5 :8, + iir2_st0_tap_limit_up6 :8, + iir2_st0_tap_limit_up7 :8; +}; +struct ATSC_EQ_REG_0XBF_BITS { + unsigned int iir2_st0_tap_limit_up8 :8, + iir2_st0_tap_limit_low4 :8, + iir2_st0_tap_limit_low5 :8, + iir2_st0_tap_limit_low6 :8; +}; +struct ATSC_EQ_REG_0XC0_BITS { + unsigned int iir2_st0_tap_limit_low7 :8, + iir2_st0_tap_limit_low8 :8, + reserved88 :16; +}; +struct ATSC_EQ_REG_0XC1_BITS { + unsigned int bm_acum_min_diff_ctrl :24, + reserved89 :8; +}; +struct ATSC_EQ_REG_0XC2_BITS { + unsigned int pt_err_limit :16, + reserved90 :16; +}; +struct ATSC_EQ_REG_0XC3_BITS { + unsigned int snr :16, + reserved91 :16; +}; +struct ATSC_EQ_REG_0XC4_BITS { + unsigned int bm_acum_diff :21, + reserved92 :11; +}; +struct ATSC_EQ_REG_0XC5_BITS { + unsigned int cwth_exp :10, + reserved93 :6, + pwr_avgw :8, + reserved94 :8; +}; +struct ATSC_EQ_REG_0XC6_BITS { + unsigned int cwth_man :24, + reserved95 :8; +}; +struct ATSC_EQ_REG_0XC7_BITS { + unsigned int inband_pwr_th :16, + reserved96 :16; +}; +union ATSC_EQ_REG_0XC8_BITS { + unsigned int bits; + struct { + unsigned int timing_adjust_thd :16, + timing_adjust_eqst :2, + reserved97 :6, + timing_adjust_bypass :1, + reserved98 :7; + } b; +}; +struct ATSC_EQ_REG_0XC9_BITS { + unsigned int timing_adjust_snr_thd :16, + timing_adjust_thd_1 :16; +}; +union ATSC_EQ_REG_0XCA_BITS { + unsigned int bits; + struct { + unsigned int timing_offset :9, + reserved99 :7, + timing_direct :1, + reserved100 :15; + } b; +}; +struct ATSC_EQ_REG_0XCB_BITS { + unsigned int timing_adjust_sum :22, + reserved101 :10; +}; +struct ATSC_EQ_REG_0XCC_BITS { + unsigned int timing_adjust_max :22, + reserved102 :10; +}; +struct ATSC_EQ_REG_0XCD_BITS { + unsigned int timing_adjust_ori :22, + reserved103 :10; +}; +struct ATSC_EQ_REG_0XD0_BITS { + unsigned int tap_fd_step1 :8, + tap_fd_ctrl :8, + ar_stop_st :4, + reserved104 :12; +}; +struct ATSC_EQ_REG_0XD2_BITS { + unsigned int tap_shift_ctrl0 :8, + tap_shift_ctrl1 :8, + tap_shift_ctrl2 :8, + tap_shift_ctrl3 :8; +}; +struct ATSC_EQ_REG_0XD3_BITS { + unsigned int tap_shift_ctrl4 :8, + tap_shift_ctrl5 :8, + tap_shift_ctrl6 :8, + tap_shift_ctrl7 :8; +}; +struct ATSC_EQ_REG_0XD4_BITS { + unsigned int tap_shift_ctrl8 :8, + tap_shift_ctrl9 :8, + tap_shift_ctrla :8, + tap_shift_ctrlb :8; +}; +struct ATSC_EQ_REG_0XD5_BITS { + unsigned int tap_shift_ctrlc :8, + tap_shift_ctrld :8, + tap_shift_ctrle :8, + tap_shift_ctrlf :8; +}; +struct ATSC_EQ_REG_0XD6_BITS { + unsigned int tap_mask_adr :16, + reserved105 :16; +}; +struct ATSC_EQ_REG_0XD7_BITS { + unsigned int tap_dfe_abs :21, + reserved106 :11; +}; +struct ATSC_EQ_REG_0XD9_BITS { + unsigned int tap_snr :16, + reserved107 :16; +}; + +#endif diff --git a/drivers/amlogic/media/dtv_demod/include/amlfrontend.h b/drivers/amlogic/media/dtv_demod/include/amlfrontend.h index e5708856d028..5d43cab27040 100644 --- a/drivers/amlogic/media/dtv_demod/include/amlfrontend.h +++ b/drivers/amlogic/media/dtv_demod/include/amlfrontend.h @@ -57,9 +57,11 @@ enum Gxtv_Demod_Dvb_Mode { #define Adc_Clk_25M 25000 /* dtmb */ #define Demod_Clk_100M 100000 /* */ +#define Demod_Clk_167M 167000 /* */ #define Demod_Clk_180M 180000 /* */ #define Demod_Clk_200M 200000 /* */ #define Demod_Clk_225M 225000 +#define Demod_Clk_250M 250000 #define Adc_Clk_27M 27777 /* atsc */ #define Demod_Clk_83M 83333 /* */ @@ -93,7 +95,8 @@ struct ss_reg_vt { /* rigister offset page */ #define IC_OFFS_V2 (0x02) /*MG9TV, GXTVBB, TXL*/ -#define IC_OFFS_V3 (0x03) /*TXLX, GXLX...*/ +#define IC_OFFS_V3 (0x03) /*TXLX, GXLX, TXHD*/ +#define IC_OFFS_V4 (0x04) /*TL1*/ @@ -108,17 +111,15 @@ struct ss_reg_vt { #define IC_DVBT_V2 (0x02) /*TXLX*/ #define IC_ATSC_V2 (0x02) /*TXLX*/ -#define IC_OFFS_V2 (0x02) /*MG9TV, GXTVBB, TXL*/ -#define IC_OFFS_V3 (0x03) /*TXLX, GXLX, TXHD*/ - /*-----------------------*/ #define IC_VER_GTVBB (0x00) #define IC_VER_TXL (0x01) #define IC_VER_TXLX (0x02) #define IC_VER_GXLX (0x03) #define IC_VER_TXHD (0x04) +#define IC_VER_TL1 (0x05) -#define IC_VER_NUB (0x05) +#define IC_VER_NUB (0x06) /*-----------------------*/ @@ -154,11 +155,13 @@ struct ic_ver { }; struct ddemod_reg_off { /* register address offset for demod*/ - unsigned int off_demod; + unsigned int off_demod_top; unsigned int off_dvbc; unsigned int off_dtmb; unsigned int off_dvbt; unsigned int off_atsc; + unsigned int off_front; + unsigned int off_isdbt; #if 0 /*vertual address for dtv demod*/ @@ -263,7 +266,7 @@ struct amldtvdemod_device_s { struct dvb_frontend frontend; /**/ #endif const struct amlfe_exp_config *afe_cfg; - + struct dentry *demod_root; }; extern struct amldtvdemod_device_s *dtvdd_devp; /**/ @@ -393,7 +396,19 @@ static inline void __iomem *gbase_atsc(void) static inline void __iomem *gbase_demod(void) { return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v - + dtvdd_devp->ireg.off_demod; + + dtvdd_devp->ireg.off_demod_top; +} + +static inline void __iomem *gbase_isdbt(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_isdbt; +} + +static inline void __iomem *gbase_front(void) +{ + return dtvdd_devp->reg_v[ES_MAP_ADDR_DEMOD].v + + dtvdd_devp->ireg.off_front; } static inline void __iomem *gbase_aobus(void) @@ -417,7 +432,7 @@ static inline unsigned int gphybase_demod(void) static inline unsigned int gphybase_demodcfg(void) { return dtvdd_devp->reg_p[ES_MAP_ADDR_DEMOD].phy_addr - + dtvdd_devp->ireg.off_demod; + + dtvdd_devp->ireg.off_demod_top; } static inline unsigned int gphybase_hiu(void) diff --git a/drivers/amlogic/media/dtv_demod/include/atsc_func.h b/drivers/amlogic/media/dtv_demod/include/atsc_func.h index 77b10c59f16f..5ead9ab63cb9 100644 --- a/drivers/amlogic/media/dtv_demod/include/atsc_func.h +++ b/drivers/amlogic/media/dtv_demod/include/atsc_func.h @@ -53,6 +53,8 @@ int check_atsc_fsm_status(void); void atsc_write_reg(unsigned int reg_addr, unsigned int reg_data); unsigned int atsc_read_reg(unsigned int reg_addr); +extern void atsc_write_reg_v4(unsigned int addr, unsigned int data); +extern unsigned int atsc_read_reg_v4(unsigned int addr); unsigned int atsc_read_iqr_reg(void); diff --git a/drivers/amlogic/media/dtv_demod/include/demod_func.h b/drivers/amlogic/media/dtv_demod/include/demod_func.h index 9be8d2e42a30..3329c30f0b56 100644 --- a/drivers/amlogic/media/dtv_demod/include/demod_func.h +++ b/drivers/amlogic/media/dtv_demod/include/demod_func.h @@ -26,6 +26,10 @@ #include "dvb_frontend.h" /**/ #include "amlfrontend.h" #include "addr_dtmb_top.h" +#include "addr_atsc_demod.h" +#include "addr_atsc_eq.h" +#include "addr_atsc_cntr.h" + /*#include "c_stb_define.h"*/ /*#include "c_stb_regs_define.h"*/ #include @@ -117,10 +121,13 @@ /* demod register */ -#define DEMOD_REG1 (0x00) -#define DEMOD_REG2 (0x04) -#define DEMOD_REG3 (0x08) -#define DEMOD_REG4 (0x0C) +#define DEMOD_TOP_REG0 (0x00) +#define DEMOD_TOP_REG4 (0x04) +#define DEMOD_TOP_REG8 (0x08) +#define DEMOD_TOP_REGC (0x0C) + +/*reset register*/ +#define reg_reset (0x1c) #if 0 /* demod register: */ @@ -254,9 +261,9 @@ #define ADC_REG6 0x1074 #endif -#define DEMOD_REG1_VALUE 0x0000d007 -#define DEMOD_REG2_VALUE 0x2e805400 -#define DEMOD_REG3_VALUE 0x201 +#define DEMOD_REG0_VALUE 0x0000d007 +#define DEMOD_REG4_VALUE 0x2e805400 +#define DEMOD_REG8_VALUE 0x201 /* for table end */ #define TABLE_FLG_END 0xffffffff @@ -548,6 +555,7 @@ int app_apb_read_reg(int addr); void demod_set_cbus_reg(unsigned int data, unsigned int addr); unsigned int demod_read_cbus_reg(unsigned int addr); void demod_set_demod_reg(unsigned int data, unsigned int addr); +extern void demod_set_tvfe_reg(unsigned int data, unsigned int addr); unsigned int demod_read_demod_reg(unsigned int addr); /* extern int clk_measure(char index); */ @@ -571,6 +579,8 @@ void demod_get_reg(struct aml_demod_reg *demod_reg); int demod_set_sys(struct aml_demod_sta *demod_sta, /*struct aml_demod_i2c *demod_i2c,*/ struct aml_demod_sys *demod_sys); +extern void demod_set_sys_atsc_v4(void); +extern void set_j83b_filter_reg_v4(void); /* for g9tv */ @@ -799,9 +809,15 @@ extern unsigned int demod_read_reg_rlt(unsigned int addr); #endif extern void dvbc_write_reg(unsigned int addr, unsigned int data); extern unsigned int dvbc_read_reg(unsigned int addr); +extern void dvbc_write_reg_v4(unsigned int addr, unsigned int data); +extern unsigned int dvbc_read_reg_v4(unsigned int addr); extern void demod_write_reg(unsigned int addr, unsigned int data); extern unsigned int demod_read_reg(unsigned int addr); - +//extern void demod_init_mutex(void); +extern void front_write_reg_v4(unsigned int addr, unsigned int data); +extern unsigned int front_read_reg_v4(unsigned int addr); +extern unsigned int isdbt_read_reg_v4(unsigned int addr); +extern void isdbt_write_reg_v4(unsigned int addr, unsigned int data); extern int dd_tvafe_hiu_reg_write(unsigned int reg, unsigned int val); extern unsigned int dd_tvafe_hiu_reg_read(unsigned int addr); @@ -811,6 +827,7 @@ extern unsigned int reset_reg_read(unsigned int addr); extern void clocks_set_sys_defaults(unsigned char dvb_mode); extern void demod_set_demod_default(void); +extern unsigned int demod_get_adc_clk(void); extern void debug_adc_pll(void); extern void debug_check_reg_val(unsigned int reg_mode, unsigned int reg); diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index f95d7170cc06..d4d1c5861d7b 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -1660,7 +1660,7 @@ static int dolby_core1_set( } if (dolby_vision_on_count - < dolby_vision_run_mode_delay) { + <= dolby_vision_run_mode_delay) { VSYNC_WR_MPEG_REG( VPP_VD1_CLIP_MISC0, (0x200 << 10) | 0x200); @@ -2166,7 +2166,7 @@ static void apply_stb_core_settings( 24, 256 * 5, (uint32_t *)&new_dovi_setting.dm_reg2, (uint32_t *)&new_dovi_setting.dm_lut2, - graphics_w, graphics_h, 1, 1); + graphics_h, graphics_w, 1, 1); v_size = vinfo->height; if (((vinfo->width == 720) && (vinfo->height == 480) && @@ -3503,9 +3503,29 @@ static int dolby_vision_policy_process( *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; mode_change = 1; } + } else if (src_format == FORMAT_HDR10 + && (!(dolby_vision_hdr10_policy & 1))) { + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_BYPASS) { + /* HDR bypass */ + pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; + mode_change = 1; + } + } else if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) { + /*g12 has a hardware bug. Therefore, dv cores + *must keep working even if under sdr mode + */ + if (dolby_vision_mode != + DOLBY_VISION_OUTPUT_MODE_SDR8) { + /* SDR to SDR */ + pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_SDR8\n"); + *mode = DOLBY_VISION_OUTPUT_MODE_SDR8; + mode_change = 1; + } } else if (dolby_vision_mode != - DOLBY_VISION_OUTPUT_MODE_BYPASS) { - /* HDR/SDR bypass */ + DOLBY_VISION_OUTPUT_MODE_BYPASS) { + /* SDR bypass */ pr_dolby_dbg("dovi output -> DOLBY_VISION_OUTPUT_MODE_BYPASS\n"); *mode = DOLBY_VISION_OUTPUT_MODE_BYPASS; mode_change = 1; @@ -3757,7 +3777,6 @@ static int parse_sei_and_meta( || (req->aux_size == 0)) return 1; - p = req->aux_buf; while (p < req->aux_buf + req->aux_size - 8) { size = *p++; @@ -3859,6 +3878,11 @@ static int parse_sei_and_meta( ret = 2; break; } + /*dolby type just appears once in metadata + *after parsing dolby type,breaking the + *circulation directly + */ + break; } p += size; } @@ -5098,7 +5122,9 @@ int dolby_vision_parse_metadata( dst_format = FORMAT_SDR; #ifdef V2_4 if ((src_format != dovi_setting.src_format) - || (dst_format != dovi_setting.dst_format)) + || (dst_format != dovi_setting.dst_format) || + ((!(dolby_vision_flags & FLAG_CERTIFICAION)) + && (frame_count == 0))) p_funcs->control_path( FORMAT_INVALID, 0, comp_buf[currentId], 0, @@ -5961,11 +5987,10 @@ int register_dv_functions(const struct dolby_vision_func_s *func) ("efuse_mode=%d reg_value = 0x%x\n", efuse_mode, reg_value); - /* r321 stb core doesn't need run mode*/ + /*stb core doesn't need run mode*/ /*TV core need run mode and the value is 2*/ - if (is_meson_gxm() || is_meson_g12()) - dolby_vision_run_mode_delay = 3; - else if (force_stb_mode || is_meson_txlx_stbmode()) + if (is_meson_gxm() || is_meson_g12() || + is_meson_txlx_stbmode() || force_stb_mode) dolby_vision_run_mode_delay = 0; else dolby_vision_run_mode_delay = RUN_MODE_DELAY; diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.c b/drivers/amlogic/media/enhancement/amvecm/amcsc.c index 4b3792173d44..08953ccfe8ec 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.c +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.c @@ -5948,10 +5948,8 @@ static void hdr_support_process(struct vinfo_s *vinfo) if (sdr_mode == 2) { /* auto */ if ((vinfo->hdr_info.hdr_support & 0x4) && - ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXL) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_GXLX) || - (get_cpu_type() == MESON_CPU_MAJOR_ID_G12A))) + ((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) && + (vinfo->viu_color_fmt != COLOR_FMT_RGB444))) sdr_process_mode = 1; /*box sdr->hdr*/ else if ((vinfo->viu_color_fmt == COLOR_FMT_RGB444) && ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) || diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 2b9c3c2b93ae..027c4d0ca4da 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -1801,7 +1801,7 @@ static ssize_t amvecm_dnlp_debug_store(struct class *cla, pr_info("%d\n", dnlp_scurv_mid1_copy[val]); } - } else if (!strcmp(parm[1], "scu v_mid2")) { + } else if (!strcmp(parm[1], "scurv_mid2")) { if (parm[2] == NULL) { pr_info("error cmd\n"); goto free_buf; @@ -5421,7 +5421,10 @@ void init_pq_setting(void) } /*probe close sr0 peaking for switch on video*/ WRITE_VPP_REG_BITS(VPP_SRSHARP0_CTRL, 1, 0, 1); - WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 0, 0, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) + WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 0, 0, 1); + else + WRITE_VPP_REG_BITS(VPP_SRSHARP1_CTRL, 1, 0, 1); /*default dnlp off*/ WRITE_VPP_REG_BITS(SRSHARP0_PK_NR_ENABLE + sr_offset[0], 0, 1, 1); @@ -5832,13 +5835,14 @@ static int aml_vecm_probe(struct platform_device *pdev) /* box sdr_mode:auto, tv sdr_mode:off */ /* disable contrast and saturation adjustment for HDR on TV */ /* disable SDR to HDR convert on TV */ - if (is_meson_gxl_cpu() || is_meson_gxm_cpu()) { - sdr_mode = 0; + if (is_meson_gxl_cpu() || is_meson_gxm_cpu()) hdr_flag = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); - } else { - sdr_mode = 0; + else hdr_flag = (1 << 0) | (1 << 1) | (0 << 2) | (0 << 3); - } + + 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*/ diff --git a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c index 0ede3980fdab..79b40afc160f 100644 --- a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c +++ b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c @@ -55,6 +55,17 @@ int cgain_lut1[65] = { module_param_array(cgain_lut1, int, &num_cgain_lut, 0664); MODULE_PARM_DESC(cgain_lut1, "\n knee_setting, 256=1.0\n"); +int cgain_lut_bypass[65] = { + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x400, + 0x400, 0x400 +}; + // sdr to hdr 10bit (gamma to peak) int cgain_lut2[65] = { 0xc00, 0xc00, 0xc00, 0xc00, 0xc00, 0xc00, 0xc00, 0xc00, 0xc00, @@ -127,6 +138,25 @@ int eo_y_lut_sdr[143] = { 520474, 521003, 521537, 522077, 522622, 523172, 523727, 524287 }; +int eo_y_lut_bypass[143] = { + 0, 360448, 376832, 385024, 393216, 397312, 401408, 405504, 409600, + 411648, 413696, 415744, 417792, 419840, 421888, 423936, 425984, 434176, + 442368, 446464, 450560, 454656, 458752, 460800, 462848, 464896, 466944, + 468992, 471040, 473088, 475136, 476160, 477184, 478208, 479232, 480256, + 481280, 482304, 483328, 484352, 485376, 486400, 487424, 488448, 489472, + 490496, 491520, 492032, 492544, 493056, 493568, 494080, 494592, 495104, + 495616, 496128, 496640, 497152, 497664, 498176, 498688, 499200, 499712, + 500224, 500736, 501248, 501760, 502272, 502784, 503296, 503808, 504320, + 504832, 505344, 505856, 506368, 506880, 507392, 507904, 508160, 508416, + 508672, 508928, 509184, 509440, 509696, 509952, 510208, 510464, 510720, + 510976, 511232, 511488, 511744, 512000, 512256, 512512, 512768, 513024, + 513280, 513536, 513792, 514048, 514304, 514560, 514816, 515072, 515328, + 515584, 515840, 516096, 516352, 516608, 516864, 517120, 517376, 517632, + 517888, 518144, 518400, 518656, 518912, 519168, 519424, 519680, 519936, + 520192, 520448, 520704, 520960, 521216, 521472, 521728, 521984, 522240, + 522496, 522752, 523008, 523264, 523520, 523776, 524032, 524287 +}; + int oe_y_lut_hdr[149] = {0, 3, 5, 8, 12, 19, 28, 41, 60, 67, 74, 80, 85, 96, 105, 113, 120, 134, 146, 157, 167, 184, 200, 214, 227, 250, 270, 288, 304, 332, 357, 380, 400, 435, 465, 492, 517, 559, 595, 628, 656, @@ -171,6 +201,19 @@ int oe_y_lut_sdr[149] = {0, 1, 1, 2, 2, 3, 5, 7, 9, 10, 11, 12, 12, 13, module_param_array(oe_y_lut_sdr, int, &num_oe_y_lut_sdr, 0664); MODULE_PARM_DESC(oe_y_lut_sdr, "\n eo_y_lut_hdr\n"); +static int oe_y_lut_bypass[149] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, + 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, + 26, 28, 30, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88, 96, + 104, 112, 120, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, + 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 832, 896, + 960, 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1920, 2048, 2176, + 2304, 2432, 2560, 2688, 2816, 2944, 3072, 3200, 3328, 3456, 3584, + 3712, 3840, 3968, 4095 +}; + int oo_y_lut_hdr_hlg[149] = { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, @@ -205,6 +248,21 @@ int oo_y_lut_hdr_sdr[149] = { module_param_array(oo_y_lut_hdr_sdr, int, &num_hdr_sdr_lut, 0664); MODULE_PARM_DESC(oo_y_lut_hdr_sdr, "\n num_hdr_sdr_lut\n"); +int oo_y_lut_bypass[149] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255 +}; + int oo_y_lut_hlg_hdr[149] = { 4, 8, 9, 11, 12, 14, 16, 19, 22, 23, 24, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 40, 42, 43, 44, 46, 48, 49, 51, @@ -1117,14 +1175,28 @@ void set_hdr_matrix( for (i = 0; i < 9; i++) gmut_coef[i/3][i%3] = hdr_mtx_param->mtx_gamut[i]; - gmut_shift = 11; + /*for g12a/g12b osd blend shift rtl bug*/ + if ((is_meson_g12a_cpu() || + is_meson_g12b_cpu()) && + (hdr_mtx_param->p_sel & HDR_BYPASS) && + (module_sel & OSD1_HDR)) + gmut_shift = 10; + else + gmut_shift = 11; + for (i = 0; i < 3; i++) c_gain_lim_coef[i] = hdr_mtx_param->mtx_cgain[i] << 2; /*0, nolinear input, 1, max linear, 2, adpscl mode*/ adpscl_mode = 1; for (i = 0; i < 3; i++) { - adpscl_enable[i] = 0; + if ((is_meson_g12a_cpu() || + is_meson_g12b_cpu()) && + (hdr_mtx_param->p_sel & HDR_BYPASS) && + (module_sel & OSD1_HDR)) + adpscl_enable[i] = 1; + else + adpscl_enable[i] = 0; if (hdr_mtx_param->p_sel & HDR_SDR) adpscl_alpha[i] = (1 << adp_scal_shift); @@ -1512,17 +1584,39 @@ void hdr_func(enum hdr_module_sel module_sel, #else /*lut parameters*/ if (hdr_process_select & HDR_BYPASS) { - for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { - hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; - hdr_lut_param.ogain_lut[i] = oo_y_lut_hdr_sdr[i]; - if (i < HDR2_EOTF_LUT_SIZE) - hdr_lut_param.eotf_lut[i] = eo_y_lut_hdr[i]; - if (i < HDR2_CGAIN_LUT_SIZE) - hdr_lut_param.cgain_lut[i] = cgain_lut1[i] - 1; + /*for g12a/g12b osd blend shift rtl bug*/ + if ((is_meson_g12a_cpu() || + is_meson_g12b_cpu()) && + (module_sel & OSD1_HDR)) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_bypass[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_bypass[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = + eo_y_lut_bypass[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; + } + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_ON; + } else { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; + hdr_lut_param.ogain_lut[i] = + oo_y_lut_hdr_sdr[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = + eo_y_lut_hdr[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut1[i] - 1; + } + hdr_lut_param.lut_on = LUT_OFF; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_OFF; } - hdr_lut_param.lut_on = LUT_OFF; - hdr_lut_param.bitdepth = bit_depth; - hdr_lut_param.cgain_en = LUT_OFF; } else if (hdr_process_select & HDR_SDR) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; @@ -1542,11 +1636,18 @@ void hdr_func(enum hdr_module_sel module_sel, if (i < HDR2_EOTF_LUT_SIZE) hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i]; if (i < HDR2_CGAIN_LUT_SIZE) - hdr_lut_param.cgain_lut[i] = cgain_lut0[i] - 1; + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; } hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; - hdr_lut_param.cgain_en = LUT_OFF; + /*for g12a/g12b osd blend shift rtl bug*/ + if ((is_meson_g12a_cpu() || + is_meson_g12b_cpu()) && + (module_sel & OSD1_HDR)) + hdr_lut_param.cgain_en = LUT_ON; + else + hdr_lut_param.cgain_en = LUT_OFF; } else if (hdr_process_select & HLG_BYPASS) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; @@ -1590,27 +1691,53 @@ void hdr_func(enum hdr_module_sel module_sel, if (i < HDR2_EOTF_LUT_SIZE) hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i]; if (i < HDR2_CGAIN_LUT_SIZE) - hdr_lut_param.cgain_lut[i] = cgain_lut0[i] - 1; + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; } hdr_lut_param.lut_on = LUT_ON; hdr_lut_param.bitdepth = bit_depth; - hdr_lut_param.cgain_en = LUT_OFF; + /*for g12a/g12b osd blend shift rtl bug*/ + if ((is_meson_g12a_cpu() || + is_meson_g12b_cpu()) && + (module_sel & OSD1_HDR)) + hdr_lut_param.cgain_en = LUT_ON; + else + hdr_lut_param.cgain_en = LUT_OFF; } else return; #endif /*mtx parameters*/ if (hdr_process_select & (HDR_BYPASS | HLG_BYPASS)) { hdr_mtx_param.mtx_only = HDR_ONLY; - for (i = 0; i < 15; i++) { - hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; - hdr_mtx_param.mtx_out[i] = bypass_coeff[i]; - if (i < 9) - hdr_mtx_param.mtx_gamut[i] = bypass_coeff[i]; + /*for g12a/g12b osd blend shift rtl bug*/ + if ((is_meson_g12a_cpu() || + is_meson_g12b_cpu()) && + (hdr_process_select & HDR_BYPASS) && + (module_sel & OSD1_HDR)) { + for (i = 0; i < 15; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_709[i]; + hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + bypass_coeff[i]; + } + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = HDR_BYPASS; + } else { + for (i = 0; i < 15; i++) { + hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_out[i] = bypass_coeff[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + bypass_coeff[i]; + } + hdr_mtx_param.mtx_on = MTX_OFF; + hdr_mtx_param.p_sel = HDR_BYPASS; } - hdr_mtx_param.mtx_on = MTX_OFF; - hdr_mtx_param.p_sel = HDR_BYPASS; } else if (hdr_process_select & (HDR_SDR | HLG_SDR)) { hdr_mtx_param.mtx_only = HDR_ONLY; for (i = 0; i < 15; i++) { diff --git a/drivers/amlogic/media/gdc/app/gdc_module.c b/drivers/amlogic/media/gdc/app/gdc_module.c index e48c1d2680bd..040218d9ac0e 100644 --- a/drivers/amlogic/media/gdc/app/gdc_module.c +++ b/drivers/amlogic/media/gdc/app/gdc_module.c @@ -31,7 +31,7 @@ #include #include #include - +#include #include #include @@ -273,6 +273,216 @@ static void meson_gdc_cache_flush(struct device *dev, dma_sync_single_for_cpu(dev, addr, size, DMA_FROM_DEVICE); } +static long meson_gdc_dma_map(struct gdc_dma_cfg *cfg) +{ + long ret = -1; + int fd = -1; + struct dma_buf *dbuf = NULL; + struct dma_buf_attachment *d_att = NULL; + struct sg_table *sg = NULL; + void *vaddr = NULL; + struct device *dev = NULL; + enum dma_data_direction dir; + + if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL) { + LOG(LOG_ERR, "Error input param"); + return -EINVAL; + } + + fd = cfg->fd; + dev = cfg->dev; + dir = cfg->dir; + + dbuf = dma_buf_get(fd); + if (dbuf == NULL) { + LOG(LOG_ERR, "Failed to get dma buffer"); + return -EINVAL; + } + + d_att = dma_buf_attach(dbuf, dev); + if (d_att == NULL) { + LOG(LOG_ERR, "Failed to set dma attach"); + goto attach_err; + } + + sg = dma_buf_map_attachment(d_att, dir); + if (sg == NULL) { + LOG(LOG_ERR, "Failed to get dma sg"); + goto map_attach_err; + } + + ret = dma_buf_begin_cpu_access(dbuf, dir); + if (ret != 0) { + LOG(LOG_ERR, "Failed to access dma buff"); + goto access_err; + } + + vaddr = dma_buf_vmap(dbuf); + if (vaddr == NULL) { + LOG(LOG_ERR, "Failed to vmap dma buf"); + goto vmap_err; + } + + cfg->dbuf = dbuf; + cfg->attach = d_att; + cfg->vaddr = vaddr; + cfg->sg = sg; + + return ret; + +vmap_err: + dma_buf_end_cpu_access(dbuf, dir); + +access_err: + dma_buf_unmap_attachment(d_att, sg, dir); + +map_attach_err: + dma_buf_detach(dbuf, d_att); + +attach_err: + dma_buf_put(dbuf); + + return ret; +} + + +static void meson_gdc_dma_unmap(struct gdc_dma_cfg *cfg) +{ + int fd = -1; + struct dma_buf *dbuf = NULL; + struct dma_buf_attachment *d_att = NULL; + struct sg_table *sg = NULL; + void *vaddr = NULL; + struct device *dev = NULL; + enum dma_data_direction dir; + + if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL + || cfg->dbuf == NULL || cfg->vaddr == NULL + || cfg->attach == NULL || cfg->sg == NULL) { + LOG(LOG_ERR, "Error input param"); + return; + } + + fd = cfg->fd; + dev = cfg->dev; + dir = cfg->dir; + dbuf = cfg->dbuf; + vaddr = cfg->vaddr; + d_att = cfg->attach; + sg = cfg->sg; + + dma_buf_vunmap(dbuf, vaddr); + + dma_buf_end_cpu_access(dbuf, dir); + + dma_buf_unmap_attachment(d_att, sg, dir); + + dma_buf_detach(dbuf, d_att); + + dma_buf_put(dbuf); +} + +static long meson_gdc_init_dma_addr(struct gdc_settings *gs) +{ + long ret = -1; + struct gdc_dma_cfg *dma_cfg = NULL; + struct gdc_config *gc = NULL; + struct mgdc_fh_s *fh = NULL; + + if (gs == NULL || gs->fh == NULL) { + LOG(LOG_ERR, "Error input param\n"); + return -EINVAL; + } + + gc = &gs->gdc_config; + fh = gs->fh; + + switch (gc->format) { + case NV12: + dma_cfg = &fh->y_dma_cfg; + memset(dma_cfg, 0, sizeof(*dma_cfg)); + dma_cfg->dir = DMA_TO_DEVICE; + dma_cfg->dev = &fh->gdev->pdev->dev; + dma_cfg->fd = gs->y_base_fd; + + ret = meson_gdc_dma_map(dma_cfg); + if (ret != 0) { + LOG(LOG_ERR, "Failed to get map dma buff"); + return ret; + } + + gs->y_base_addr = virt_to_phys(dma_cfg->vaddr); + + dma_cfg = &fh->uv_dma_cfg; + memset(dma_cfg, 0, sizeof(*dma_cfg)); + dma_cfg->dir = DMA_TO_DEVICE; + dma_cfg->dev = &fh->gdev->pdev->dev; + dma_cfg->fd = gs->uv_base_fd; + + ret = meson_gdc_dma_map(dma_cfg); + if (ret != 0) { + LOG(LOG_ERR, "Failed to get map dma buff"); + return ret; + } + + gs->uv_base_addr = virt_to_phys(dma_cfg->vaddr); + break; + case Y_GREY: + dma_cfg = &fh->y_dma_cfg; + memset(dma_cfg, 0, sizeof(*dma_cfg)); + dma_cfg->dir = DMA_TO_DEVICE; + dma_cfg->dev = &fh->gdev->pdev->dev; + dma_cfg->fd = gs->y_base_fd; + + ret = meson_gdc_dma_map(dma_cfg); + if (ret != 0) { + LOG(LOG_ERR, "Failed to get map dma buff"); + return ret; + } + + gs->y_base_addr = virt_to_phys(dma_cfg->vaddr); + gs->uv_base_addr = 0; + break; + default: + LOG(LOG_ERR, "Error image format"); + break; + } + + return ret; +} + +static void meson_gdc_deinit_dma_addr(struct gdc_settings *gs) +{ + struct gdc_dma_cfg *dma_cfg = NULL; + struct gdc_config *gc = NULL; + struct mgdc_fh_s *fh = NULL; + + if (gs == NULL || gs->fh == NULL) { + LOG(LOG_ERR, "Error input param\n"); + return; + } + + gc = &gs->gdc_config; + fh = gs->fh; + + switch (gc->format) { + case NV12: + dma_cfg = &fh->y_dma_cfg; + meson_gdc_dma_unmap(dma_cfg); + + dma_cfg = &fh->uv_dma_cfg; + meson_gdc_dma_unmap(dma_cfg); + break; + case Y_GREY: + dma_cfg = &fh->y_dma_cfg; + meson_gdc_dma_unmap(dma_cfg); + break; + default: + LOG(LOG_ERR, "Error image format"); + break; + } +} + static long meson_gdc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -404,6 +614,12 @@ static long meson_gdc_ioctl(struct file *file, unsigned int cmd, gs->fh = fh; mutex_lock(&fh->gdev->d_mutext); + ret = meson_gdc_init_dma_addr(gs); + if (ret != 0) { + mutex_unlock(&fh->gdev->d_mutext); + LOG(LOG_ERR, "Failed to init dma addr"); + return ret; + } meson_gdc_dma_flush(&fh->gdev->pdev->dev, fh->c_paddr, fh->c_len); ret = gdc_run(gs); @@ -418,6 +634,7 @@ static long meson_gdc_ioctl(struct file *file, unsigned int cmd, gdc_stop(gs); meson_gdc_cache_flush(&fh->gdev->pdev->dev, fh->o_paddr, fh->o_len); + meson_gdc_deinit_dma_addr(gs); mutex_unlock(&fh->gdev->d_mutext); break; case GDC_REQUEST_BUFF: diff --git a/drivers/amlogic/media/gdc/inc/api/gdc_api.h b/drivers/amlogic/media/gdc/inc/api/gdc_api.h index 30554c2fd5b9..2f3fb8feec64 100644 --- a/drivers/amlogic/media/gdc/inc/api/gdc_api.h +++ b/drivers/amlogic/media/gdc/inc/api/gdc_api.h @@ -19,6 +19,7 @@ #define __GDC_API_H__ #include +#include struct gdc_buf_cfg { uint32_t type; @@ -79,6 +80,12 @@ struct gdc_settings { uint32_t y_line_offset, uint32_t uv_line_offset); void *fh; + int32_t y_base_fd; + union { + int32_t uv_base_fd; + int32_t u_base_fd; + }; + int32_t v_base_fd; }; #define GDC_IOC_MAGIC 'G' @@ -104,6 +111,16 @@ enum { FMT_MAX }; +struct gdc_dma_cfg { + int fd; + void *dev; + void *vaddr; + struct dma_buf *dbuf; + struct dma_buf_attachment *attach; + struct sg_table *sg; + enum dma_data_direction dir; +}; + /** * Configure the output gdc configuration * diff --git a/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h b/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h index 02c969767865..db8c9b7fb94e 100644 --- a/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h +++ b/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h @@ -54,6 +54,8 @@ struct mgdc_fh_s { unsigned long i_len; unsigned long o_len; unsigned long c_len; + struct gdc_dma_cfg y_dma_cfg; + struct gdc_dma_cfg uv_dma_cfg; }; irqreturn_t interrupt_handler_next(int irq, void *param); diff --git a/drivers/amlogic/media/osd/osd.h b/drivers/amlogic/media/osd/osd.h index 161e504bac8b..751fdc06a5f0 100644 --- a/drivers/amlogic/media/osd/osd.h +++ b/drivers/amlogic/media/osd/osd.h @@ -437,6 +437,7 @@ struct osd_fence_map_s { u32 afbc_inter_format; u32 background_w; u32 background_h; + size_t afbc_len; struct fence *in_fence; }; @@ -464,6 +465,7 @@ struct layer_fence_map_s { u32 plane_alpha; u32 dim_layer; u32 dim_color; + size_t afbc_len; struct file *buf_file; struct fence *in_fence; }; @@ -621,7 +623,8 @@ struct hw_list_s { typedef int (*sync_render_fence)(u32 index, u32 yres, struct sync_req_render_s *request, - u32 phys_addr); + u32 phys_addr, + size_t len); typedef void (*osd_toggle_buffer_op)( struct kthread_work *work); struct osd_fence_fun_s { @@ -730,11 +733,10 @@ struct hw_para_s { u32 osd_fps; u32 osd_fps_start; u32 osd_display_debug; - char __iomem *screen_base[HW_OSD_COUNT]; - u32 screen_size[HW_OSD_COUNT]; - char __iomem *screen_base_backup[HW_OSD_COUNT]; - u32 screen_size_backup[HW_OSD_COUNT]; - u32 osd_clear[HW_OSD_COUNT]; + ulong screen_base[HW_OSD_COUNT]; + ulong screen_size[HW_OSD_COUNT]; + ulong screen_base_backup[HW_OSD_COUNT]; + ulong screen_size_backup[HW_OSD_COUNT]; u32 vinfo_width; u32 vinfo_height; u32 fb_drvier_probe; diff --git a/drivers/amlogic/media/osd/osd_debug.c b/drivers/amlogic/media/osd/osd_debug.c index 58d8261b8edf..701da240af6e 100644 --- a/drivers/amlogic/media/osd/osd_debug.c +++ b/drivers/amlogic/media/osd/osd_debug.c @@ -570,7 +570,7 @@ static void osd_test_rect(void) color = 0x0; osd_log_info("- BLACK -"); osd_log_info("- (%d, %d)-(%d, %d) -\n", x, y, w, h); - fillrect(context, x, y, h, w, color); + fillrect(context, x, y, w, h, color); msleep(OSD_TEST_DURATION); x = 100; @@ -580,21 +580,21 @@ static void osd_test_rect(void) color = 0xFF0000FF; osd_log_info("- RED -\n"); osd_log_info("- (%d, %d)-(%d, %d) -\n", x, y, w, h); - fillrect(context, x, y, h, w, color); + fillrect(context, x, y, w, h, color); msleep(OSD_TEST_DURATION); x += 100; color = 0x00FF00FF; osd_log_info("- GREEN -\n"); osd_log_info("- (%d, %d)-(%d, %d) -\n", x, y, w, h); - fillrect(context, x, y, h, w, color); + fillrect(context, x, y, w, h, color); msleep(OSD_TEST_DURATION); x += 100; color = 0x0000FFFF; osd_log_info("- BlUE -\n"); osd_log_info("- (%d, %d)-(%d, %d) -\n", x, y, w, h); - fillrect(context, x, y, h, w, color); + fillrect(context, x, y, w, h, color); msleep(OSD_TEST_DURATION); memset(cfg_ex, 0, sizeof(struct config_para_ex_s)); diff --git a/drivers/amlogic/media/osd/osd_drm.c b/drivers/amlogic/media/osd/osd_drm.c index 86083a85535c..d2cb62783e21 100644 --- a/drivers/amlogic/media/osd/osd_drm.c +++ b/drivers/amlogic/media/osd/osd_drm.c @@ -115,6 +115,36 @@ static ssize_t loglevel_write_file( return count; } +static ssize_t logmodule_read_file(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[128]; + ssize_t len; + + len = snprintf(buf, 128, "%d\n", osd_log_module); + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static ssize_t logmodule_write_file( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int log_module; + char buf[128]; + int ret = 0; + + if (count > sizeof(buf) || count <= 0) + return -EINVAL; + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + if (buf[count - 1] == '\n') + buf[count - 1] = '\0'; + ret = kstrtoint(buf, 0, &log_module); + osd_log_info("log_level: %d->%d\n", osd_log_module, log_module); + osd_log_module = log_module; + return count; +} + static ssize_t debug_read_file(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -442,7 +472,8 @@ static ssize_t osd_clear_write_file(struct file *file, return -EFAULT; buf[count] = 0; ret = kstrtoint(buf, 0, &osd_clear); - osd_set_clear(osd_id, osd_clear); + if (osd_clear) + osd_set_clear(osd_id); return count; } @@ -450,12 +481,12 @@ static ssize_t osd_dump_read_file(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - char __iomem *buf; + u8 __iomem *buf = NULL; struct seq_file *s = file->private_data; int osd_id = *(int *)s; - unsigned long len; + unsigned long len = 0; - osd_restore_screen_info(osd_id, &buf, &len); + len = get_vmap_addr(osd_id, &buf); if (buf && len) return simple_read_from_buffer(userbuf, count, ppos, buf, len); else @@ -466,7 +497,14 @@ static ssize_t osd_dump_write_file(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { +#if 1 return 0; +#else + struct seq_file *s = file->private_data; + int osd_id = *(int *)s; + + return dd_vmap_write(osd_id, userbuf, count, ppos); +#endif } static void parse_param(char *buf_orig, char **parm) @@ -577,6 +615,12 @@ static const struct file_operations loglevel_file_ops = { .write = loglevel_write_file, }; +static const struct file_operations logmodule_file_ops = { + .open = simple_open, + .read = logmodule_read_file, + .write = logmodule_write_file, +}; + static const struct file_operations debug_file_ops = { .open = simple_open, .read = debug_read_file, @@ -671,6 +715,7 @@ struct osd_drm_debugfs_files_s { static struct osd_drm_debugfs_files_s osd_drm_debugfs_files[] = { {"loglevel", S_IFREG | 0640, &loglevel_file_ops}, + {"logmodule", S_IFREG | 0640, &logmodule_file_ops}, {"debug", S_IFREG | 0640, &debug_file_ops}, {"osd_display_debug", S_IFREG | 0640, &osd_display_debug_file_ops}, {"reset_status", S_IFREG | 0440, &reset_status_file_ops}, diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 965de8e10b28..53c4b86a2abd 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -356,6 +356,8 @@ static struct delayed_work osd_dwork; static int osd_shutdown_flag; unsigned int osd_log_level; +unsigned int osd_log_module = 1; + int int_viu_vsync = -ENXIO; int int_viu2_vsync = -ENXIO; int int_rdma = INT_RDMA; @@ -553,7 +555,7 @@ _find_color_format(struct fb_var_screeninfo *var) || (var->blue.length == 0) || var->bits_per_pixel != (var->red.length + var->green.length + var->blue.length + var->transp.length)) { - osd_log_dbg("not provide color length, use default color\n"); + osd_log_dbg(MODULE_BASE, "not provide color length, use default color\n"); found = &default_color_format_array[upper_margin]; } else { for (i = upper_margin; i >= lower_margin; i--) { @@ -623,7 +625,7 @@ static int osd_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (color_format_pt == NULL || color_format_pt->color_index == 0) return -EFAULT; - osd_log_dbg("select color format :index %d, bpp %d\n", + osd_log_dbg(MODULE_BASE, "select color format :index %d, bpp %d\n", color_format_pt->color_index, color_format_pt->bpp); fbdev->color = color_format_pt; @@ -640,7 +642,7 @@ static int osd_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->transp.length = color_format_pt->transp_length; var->transp.msb_right = color_format_pt->transp_msb_right; var->bits_per_pixel = color_format_pt->bpp; - osd_log_dbg("rgba(L/O):%d/%d-%d/%d-%d/%d-%d/%d\n", + osd_log_dbg(MODULE_BASE, "rgba(L/O):%d/%d-%d/%d-%d/%d-%d/%d\n", var->red.length, var->red.offset, var->green.length, var->green.offset, var->blue.length, var->blue.offset, @@ -648,7 +650,7 @@ static int osd_check_var(struct fb_var_screeninfo *var, struct fb_info *info) fix->visual = color_format_pt->color_type; /* adjust memory length. */ fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; - osd_log_dbg("xvirtual=%d, bpp:%d, line_length=%d\n", + osd_log_dbg(MODULE_BASE, "xvirtual=%d, bpp:%d, line_length=%d\n", var->xres_virtual, var->bits_per_pixel, fix->line_length); if (var->xres_virtual < var->xres) @@ -884,7 +886,8 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) case COLOR_INDEX_24_888_B: case COLOR_INDEX_24_RGB: case COLOR_INDEX_YUV_422: - osd_log_dbg("set osd color key 0x%x\n", src_colorkey); + osd_log_dbg(MODULE_BASE, + "set osd color key 0x%x\n", src_colorkey); fbdev->color_key = src_colorkey; osd_set_color_key_hw(info->node, fbdev->color->color_index, src_colorkey); @@ -901,7 +904,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) case COLOR_INDEX_24_888_B: case COLOR_INDEX_24_RGB: case COLOR_INDEX_YUV_422: - osd_log_dbg("set osd color key %s\n", + osd_log_dbg(MODULE_BASE, "set osd color key %s\n", srckey_enable ? "enable" : "disable"); if (srckey_enable != 0) { fbdev->enable_key_flag |= KEYCOLOR_FLAG_TARGET; @@ -1024,8 +1027,8 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) sync_request_render->out_fen_fd = osd_sync_request_render(info->node, info->var.yres, - sync_request_render, phys_addr); - osd_restore_screen_info(info->node, + sync_request_render, phys_addr, len); + osd_get_screen_info(info->node, &info->screen_base, &info->screen_size); ret = copy_to_user(argp, &sync_request, @@ -1280,7 +1283,7 @@ static int malloc_osd_memory(struct fb_info *info) osd_log_err("fb[%d] ioremap error", fb_index); pr_info("%s, reserved mem\n", __func__); #endif - osd_log_dbg("fb_index=%d dma_alloc=%zu\n", + osd_log_dbg(MODULE_BASE, "fb_index=%d dma_alloc=%zu\n", fb_index, fb_rmem_size[fb_index]); } } else { @@ -1415,8 +1418,10 @@ static int malloc_osd_memory(struct fb_info *info) fix->smem_len = fbdev->fb_len; info->screen_base = (char __iomem *)fbdev->fb_mem_vaddr; info->screen_size = fix->smem_len; + osd_hw.screen_base[fb_index] = fbdev->fb_mem_paddr; + osd_hw.screen_size[fb_index] = fix->smem_len; osd_backup_screen_info(fb_index, - info->screen_base, info->screen_size); + osd_hw.screen_base[fb_index], osd_hw.screen_size[fb_index]); logo_index = osd_get_logo_index(); osd_log_info("logo_index=%x,fb_index=%d\n", logo_index, fb_index); @@ -1465,7 +1470,7 @@ static int osd_open(struct fb_info *info, int arg) fbdev = (struct osd_fb_dev_s *)info->par; fbdev->open_count++; - osd_log_dbg("osd_open index=%d,open_count=%d\n", + osd_log_dbg(MODULE_BASE, "osd_open index=%d,open_count=%d\n", fbdev->fb_index, fbdev->open_count); if (info->screen_base != NULL) return 0; @@ -1507,7 +1512,7 @@ static int osd_open(struct fb_info *info, int arg) fb_ion_client = meson_ion_client_create(-1, "meson-fb"); } if (get_logo_loaded()) { - u32 logo_index; + s32 logo_index; logo_index = osd_get_logo_index(); if (logo_index < 0) { @@ -1554,6 +1559,275 @@ static int osd_mmap(struct fb_info *info, struct vm_area_struct *vma) return vm_iomap_memory(vma, start, len); } +static int is_new_page(unsigned long addr, unsigned long pos) +{ + static ulong pre_addr; + u32 offset; + int ret = 0; + + /* ret == 0 : in same page*/ + if (pos == 0) + ret = 1; + else { + offset = pre_addr & ~PAGE_MASK; + if ((offset + addr - pre_addr) >= PAGE_SIZE) + ret = 1; + } + pre_addr = addr; + return ret; +} + +static ssize_t osd_read(struct fb_info *info, char __user *buf, + size_t count, loff_t *ppos) +{ + u32 fb_index; + struct osd_fb_dev_s *fbdev; + unsigned long p = *ppos; + unsigned long total_size; + static u8 *vaddr; + ulong phys; + u32 offset, npages; + struct page **pages = NULL; + struct page *pages_array[2] = {}; + pgprot_t pgprot; + u8 *buffer, *dst; + u8 __iomem *src; + int i, c, cnt = 0, err = 0; + + fbdev = (struct osd_fb_dev_s *)info->par; + fb_index = fbdev->fb_index; + total_size = osd_hw.screen_size[fb_index]; + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p >= total_size) + return 0; + + if (count >= total_size) + count = total_size; + + if (count + p > total_size) + count = total_size - p; + if (count <= PAGE_SIZE) { + /* small than one page, need not vmalloc */ + npages = PAGE_ALIGN(count) / PAGE_SIZE; + phys = osd_hw.screen_base[fb_index] + p; + if (is_new_page(phys, p)) { + /* new page, need call vmap*/ + offset = phys & ~PAGE_MASK; + if ((offset + count) > PAGE_SIZE) + npages++; + for (i = 0; i < npages; i++) { + pages_array[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages_array, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + return -ENOMEM; + } + src = (u8 __iomem *) (vaddr); + } else { + /* in same page just get vaddr + p*/ + src = (u8 __iomem *) (vaddr + (p & ~PAGE_MASK)); + } + } else { + npages = PAGE_ALIGN(count) / PAGE_SIZE; + phys = osd_hw.screen_base[fb_index] + p; + offset = phys & ~PAGE_MASK; + if ((offset + count) > PAGE_SIZE) + npages++; + pages = vmalloc(sizeof(struct page *) * npages); + if (!pages) + return -ENOMEM; + for (i = 0; i < npages; i++) { + pages[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + if (vaddr) { + /*unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + vfree(pages); + return -ENOMEM; + } + vfree(pages); + src = (u8 __iomem *) (vaddr); + } + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); + if (!buffer) + return -ENOMEM; + /* osd_sync(info); */ + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + dst = buffer; + fb_memcpy_fromfb(dst, src, c); + dst += c; + src += c; + + if (copy_to_user(buf, buffer, c)) { + err = -EFAULT; + break; + } + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (err) ? err : cnt; + +} + +static ssize_t osd_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + u32 fb_index; + struct osd_fb_dev_s *fbdev; + unsigned long p = *ppos; + unsigned long total_size; + static u8 *vaddr; + ulong phys; + u32 offset, npages; + struct page **pages = NULL; + struct page *pages_array[2] = {}; + pgprot_t pgprot; + u8 *buffer, *src; + u8 __iomem *dst; + int i, c, cnt = 0, err = 0; + + fbdev = (struct osd_fb_dev_s *)info->par; + fb_index = fbdev->fb_index; + total_size = osd_hw.screen_size[fb_index]; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + if (count <= PAGE_SIZE) { + /* small than one page, need not vmalloc */ + npages = PAGE_ALIGN(count) / PAGE_SIZE; + phys = osd_hw.screen_base[fb_index] + p; + if (is_new_page(phys, p)) { + /* new page, need call vmap*/ + offset = phys & ~PAGE_MASK; + if ((offset + count) > PAGE_SIZE) + npages++; + for (i = 0; i < npages; i++) { + pages_array[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages_array, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + return -ENOMEM; + } + dst = (u8 __iomem *) (vaddr); + } else { + /* in same page just get vaddr + p*/ + dst = (u8 __iomem *) (vaddr + (p & ~PAGE_MASK)); + } + } else { + npages = PAGE_ALIGN(count) / PAGE_SIZE; + phys = osd_hw.screen_base[fb_index] + p; + offset = phys & ~PAGE_MASK; + if ((offset + count) > PAGE_SIZE) + npages++; + pages = vmalloc(sizeof(struct page *) * npages); + if (!pages) + return -ENOMEM; + for (i = 0; i < npages; i++) { + pages[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + vfree(pages); + return -ENOMEM; + } + vfree(pages); + dst = (u8 __iomem *) (vaddr); + + } + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + /* osd_sync() */ + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + src = buffer; + + if (copy_from_user(src, buf, c)) { + err = -EFAULT; + break; + } + + fb_memcpy_tofb(dst, src, c); + dst += c; + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + + kfree(buffer); + + return (cnt) ? cnt : err; + +} static int osd_release(struct fb_info *info, int arg) { @@ -1575,21 +1849,6 @@ static int osd_release(struct fb_info *info, int arg) done: return err; } -static ssize_t osd_clear(struct device *device, struct device_attribute *attr, - const char *buf, size_t count) -{ - u32 res = 0; - int ret = 0; - - ret = kstrtoint(buf, 0, &res); - osd_log_info("clear: osd %d\n", res); - - memset(fb_rmem_vaddr[res], - 0x0, - fb_rmem_size[res]); - - return count; -} int osd_blank(int blank_mode, struct fb_info *info) { @@ -1601,7 +1860,7 @@ static int osd_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { osd_pan_display_hw(fbi->node, var->xoffset, var->yoffset); - osd_log_dbg("osd_pan_display:=>osd%d xoff=%d, yoff=%d\n", + osd_log_dbg(MODULE_BASE, "osd_pan_display:=>osd%d xoff=%d, yoff=%d\n", fbi->node, var->xoffset, var->yoffset); return 0; } @@ -1615,8 +1874,16 @@ static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var) startx = fb_dev->osd_ctl.disp_start_x; starty = fb_dev->osd_ctl.disp_start_y; } - osd_cursor_hw(fbi->node, (s16)var->hot.x, (s16)var->hot.y, (s16)startx, - (s16)starty, fbi->var.xres, fbi->var.yres); + + if (osd_hw.hwc_enable) + osd_cursor_hw_no_scale(fbi->node, (s16)var->hot.x, + (s16)var->hot.y, (s16)startx, (s16)starty, + fbi->var.xres, fbi->var.yres); + else + osd_cursor_hw(fbi->node, (s16)var->hot.x, + (s16)var->hot.y, (s16)startx, (s16)starty, + fbi->var.xres, fbi->var.yres); + return 0; } @@ -1646,6 +1913,8 @@ static struct fb_ops osd_ops = { #endif .fb_open = osd_open, .fb_mmap = osd_mmap, + .fb_read = osd_read, + .fb_write = osd_write, .fb_blank = osd_blank, .fb_pan_display = osd_pan_display, .fb_sync = osd_sync, @@ -1750,7 +2019,7 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, */ fb_dev->osd_ctl.disp_start_x = disp_rect->x; fb_dev->osd_ctl.disp_start_y = disp_rect->y; - osd_log_dbg("set disp axis: x:%d y:%d w:%d h:%d\n", + osd_log_dbg(MODULE_BASE, "set disp axis: x:%d y:%d w:%d h:%d\n", disp_rect->x, disp_rect->y, disp_rect->w, disp_rect->h); if (disp_rect->x + disp_rect->w > vinfo->width) @@ -1766,7 +2035,7 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd, fb_dev->osd_ctl.disp_start_y + disp_rect->h - 1; disp_rect++; - osd_log_dbg("new disp axis: x0:%d y0:%d x1:%d y1:%d\n", + osd_log_dbg(MODULE_BASE, "new disp axis: x0:%d y0:%d x1:%d y1:%d\n", fb_dev->osd_ctl.disp_start_x, fb_dev->osd_ctl.disp_start_y, fb_dev->osd_ctl.disp_end_x, @@ -1939,7 +2208,7 @@ int osd_notify_callback_viu2(struct notifier_block *block, unsigned long cmd, */ fb_dev->osd_ctl.disp_start_x = disp_rect->x; fb_dev->osd_ctl.disp_start_y = disp_rect->y; - osd_log_dbg("set disp axis: x:%d y:%d w:%d h:%d\n", + osd_log_dbg(MODULE_BASE, "set disp axis: x:%d y:%d w:%d h:%d\n", disp_rect->x, disp_rect->y, disp_rect->w, disp_rect->h); if (disp_rect->x + disp_rect->w > vinfo->width) @@ -1954,7 +2223,7 @@ int osd_notify_callback_viu2(struct notifier_block *block, unsigned long cmd, fb_dev->osd_ctl.disp_end_y = fb_dev->osd_ctl.disp_start_y + disp_rect->h - 1; - osd_log_dbg("new disp axis: x0:%d y0:%d x1:%d y1:%d\n", + osd_log_dbg(MODULE_BASE, "new disp axis: x0:%d y0:%d x1:%d y1:%d\n", fb_dev->osd_ctl.disp_start_x, fb_dev->osd_ctl.disp_start_y, fb_dev->osd_ctl.disp_end_x, @@ -2154,13 +2423,11 @@ static int parse_para(const char *para, int para_num, int *result) token++; len--; } - if (len == 0) + if ((len == 0) || (!token)) break; ret = kstrtoint(token, 0, &res); if (ret < 0) break; - if (!token) - return 0; len = strlen(token); *out++ = res; count++; @@ -2402,6 +2669,22 @@ static ssize_t store_afbcd(struct device *device, struct device_attribute *attr, return count; } +static ssize_t osd_clear(struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + u32 res = 0; + int ret = 0; + struct fb_info *fb_info = dev_get_drvdata(device); + + ret = kstrtoint(buf, 0, &res); + osd_log_info("clear: osd %d\n", fb_info->node); + + if (res) + osd_set_clear(fb_info->node); + + return count; +} + static ssize_t show_log_level(struct device *device, struct device_attribute *attr, char *buf) @@ -2423,6 +2706,27 @@ static ssize_t store_log_level(struct device *device, return count; } +static ssize_t show_log_module(struct device *device, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, 40, "0x%x\n", osd_log_module); +} + +static ssize_t store_log_module(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int res = 0; + int ret = 0; + + ret = kstrtoint(buf, 0, &res); + osd_log_info("log_module: 0x%x->0x%x\n", osd_log_module, res); + osd_log_module = res; + + return count; +} + static ssize_t store_order(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { @@ -3049,6 +3353,15 @@ static ssize_t store_osd_plane_alpha( return count; } +static ssize_t show_osd_status(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct fb_info *fb_info = dev_get_drvdata(device); + + return snprintf(buf, PAGE_SIZE, "osd[%d] enable: %d\n", + fb_info->node, osd_hw.enable[fb_info->node]); +} static inline int str2lower(char *str) { @@ -3204,6 +3517,8 @@ static struct device_attribute osd_attrs[] = { show_debug, store_debug), __ATTR(log_level, 0644, show_log_level, store_log_level), + __ATTR(log_module, 0644, + show_log_module, store_log_module), __ATTR(window_axis, 0664, show_window_axis, store_window_axis), __ATTR(freescale_mode, 0664, @@ -3256,6 +3571,8 @@ static struct device_attribute osd_attrs[] = { show_osd_dimm, store_osd_dimm), __ATTR(osd_plane_alpha, 0644, show_osd_plane_alpha, store_osd_plane_alpha), + __ATTR(osd_status, 0444, + show_osd_status, NULL), }; @@ -3274,6 +3591,8 @@ static struct device_attribute osd_attrs_viu2[] = { show_debug, store_debug), __ATTR(log_level, 0644, show_log_level, store_log_level), + __ATTR(log_module, 0644, + show_log_module, store_log_module), __ATTR(flush_rate, 0444, show_flush_rate, NULL), __ATTR(osd_reverse, 0644, @@ -3302,6 +3621,8 @@ static struct device_attribute osd_attrs_viu2[] = { show_osd_afbc_format, store_osd_afbc_format), __ATTR(osd_rotate, 0644, show_osd_rotate, store_osd_rotate), + __ATTR(osd_status, 0444, + show_osd_status, NULL), }; #ifdef CONFIG_PM @@ -3715,7 +4036,6 @@ static int osd_probe(struct platform_device *pdev) } else osd_log_info("viu2 vsync irq: %d\n", int_viu2_vsync); } - if (osd_meson_dev.has_rdma) { int_rdma = platform_get_irq_byname(pdev, "rdma"); if (int_viu_vsync == -ENXIO) { @@ -3769,8 +4089,8 @@ static int osd_probe(struct platform_device *pdev) b_reserved_mem = true; #ifdef CONFIG_CMA cma = dev_get_cma_area(&pdev->dev); - base_addr = cma_get_base(cma); if (cma) { + base_addr = cma_get_base(cma); pr_info("reserved memory base:%pa, size:%lx\n", &base_addr, cma_get_size(cma)); if (fb_memsize[0] > 0) { @@ -3782,7 +4102,7 @@ static int osd_probe(struct platform_device *pdev) pr_err("allocate buffer failed:%d\n", fb_memsize[0]); } - osd_log_dbg("logo dma_alloc=%d\n", + osd_log_dbg(MODULE_BASE, "logo dma_alloc=%d\n", fb_memsize[0]); } } else diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index c3e4a1c5385b..44482063bcbd 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include /* Android Headers */ @@ -82,8 +85,6 @@ #define OSD_TYPE_BOT_FIELD 1 #define OSD_DISP_DEBUG 1 -#define ENCP_LINE_VSYNC 15 -#define ENCP_LINE 16 #define OSD_OLD_HWC (0x01 << 0) #define OSD_OTHER_NEW_HWC (0x01 << 1) #define OSD_G12A_NEW_HWC (0x01 << 2) @@ -985,7 +986,8 @@ int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request) static int sync_render_single_fence(u32 index, u32 yres, struct sync_req_render_s *request, - u32 phys_addr) + u32 phys_addr, + size_t len) { int out_fence_fd = -1; int buf_num = 0; @@ -1021,6 +1023,7 @@ static int sync_render_single_fence(u32 index, u32 yres, fence_map->byte_stride = request->byte_stride; fence_map->pxiel_stride = request->pxiel_stride; fence_map->afbc_inter_format = request->afbc_inter_format; + fence_map->afbc_len = len; } fence_map->format = request->format; fence_map->compose_type = request->type; @@ -1041,7 +1044,8 @@ static int sync_render_single_fence(u32 index, u32 yres, static int sync_render_layers_fence(u32 index, u32 yres, struct sync_req_render_s *request, - u32 phys_addr) + u32 phys_addr, + size_t len) { int out_fence_fd = -1; s32 in_fence_fd; @@ -1085,13 +1089,14 @@ static int sync_render_layers_fence(u32 index, u32 yres, request->plane_alpha; fence_map->layer_map[index].dim_layer = request->dim_layer; fence_map->layer_map[index].dim_color = request->dim_color; + fence_map->layer_map[index].afbc_len = len; /* just return out_fd,but not signal */ /* no longer put list, will put them via do_hwc */ fence_map->layer_map[index].in_fence = osd_get_fenceobj(in_fence_fd); fence_map->layer_map[index].out_fd = out_fence_create(&out_fence_fd); mutex_unlock(&post_fence_list_lock); - osd_log_dbg("sync_render_layers_fence:osd%d: ind_fd=%d,out_fd=%d\n", + osd_log_dbg(MODULE_FENCE, "sync_render_layers_fence:osd%d: ind_fd=%d,out_fd=%d\n", fence_map->layer_map[index].fb_index, fence_map->layer_map[index].in_fd, fence_map->layer_map[index].out_fd); @@ -1103,14 +1108,14 @@ static int sync_render_layers_fence(u32 index, u32 yres, int osd_sync_request_render(u32 index, u32 yres, struct sync_req_render_s *request, - u32 phys_addr) + u32 phys_addr, + size_t len) { int line; cnt++; line = get_encp_line(); - if (osd_hw.osd_display_debug == ENCP_LINE) - osd_log_info( + osd_log_dbg2(MODULE_RENDER, "enter osd_sync_request_render:cnt=%d,encp line=%d\n", cnt, line); if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V1) @@ -1122,7 +1127,7 @@ int osd_sync_request_render(u32 index, u32 yres, else osd_hw.viu_type = VIU1; osd_hw.osd_fence[osd_hw.hwc_enable].sync_fence_handler( - index, yres, request, phys_addr); + index, yres, request, phys_addr, len); return request->out_fen_fd; } @@ -1133,10 +1138,9 @@ int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) int line; line = get_encp_line(); - if (osd_hw.osd_display_debug == ENCP_LINE) - osd_log_info( - "enter osd_sync_do_hwc:cnt=%d,encp line=%d\n", - cnt, line); + osd_log_dbg2(MODULE_RENDER, + "enter osd_sync_do_hwc:cnt=%d,encp line=%d\n", + cnt, line); fence_map = kzalloc( sizeof(struct osd_layers_fence_map_s), GFP_KERNEL); if (!fence_map) @@ -1183,7 +1187,7 @@ int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd) set_logo_loaded(); } } - osd_log_dbg("osd_sync_do_hwc :out_fence_fd=%d\n", + osd_log_dbg(MODULE_FENCE, "osd_sync_do_hwc :out_fence_fd=%d\n", out_fence_fd); return out_fence_fd; } @@ -1225,7 +1229,7 @@ static int osd_wait_buf_ready_combine(struct layer_fence_map_s *layer_map) else ret = 1; - osd_log_dbg("osd_wait_buf_ready_combine:osd%d,in_fd=%d\n", + osd_log_dbg(MODULE_FENCE, "osd_wait_buf_ready_combine:osd%d,in_fd=%d\n", layer_map->fb_index, layer_map->in_fd); return ret; } @@ -1240,7 +1244,8 @@ int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request) int osd_sync_request_render(u32 index, u32 yres, struct sync_req_render_s *request, - u32 phys_addr) + u32 phys_addr, + size_t len) { osd_log_err("osd_sync_request_render not supported\n"); return -5566; @@ -1269,7 +1274,7 @@ void osd_set_enable_hw(u32 index, u32 enable) map_layers.layer_map[index].enable = enable; map_layers.cmd = BLANK_CMD; mutex_unlock(&post_fence_list_lock); - osd_log_dbg("osd_set_enable_hw: osd%d,enable=%d\n", + osd_log_dbg(MODULE_BASE, "osd_set_enable_hw: osd%d,enable=%d\n", index, enable); #endif } @@ -1612,7 +1617,7 @@ static bool mali_afbc_get_error(void) status = VSYNCOSD_RD_MPEG_REG(VPU_MAFBC_IRQ_RAW_STATUS); if (status & 0x3c) { - osd_log_dbg("afbc error happened\n"); + osd_log_dbg(MODULE_BASE, "afbc error happened\n"); osd_hw.afbc_err_cnt++; error = true; } @@ -2098,8 +2103,9 @@ void osd_set_color_key_hw(u32 index, u32 color_index, u32 colorkey) data32 = r << 24 | g << 16 | b << 8 | a; if (osd_hw.color_key[index] != data32) { osd_hw.color_key[index] = data32; - osd_log_dbg2("bpp:%d--r:0x%x g:0x%x b:0x%x ,a:0x%x\n", - color_index, r, g, b, a); + osd_log_dbg2(MODULE_BASE, + "bpp:%d--r:0x%x g:0x%x b:0x%x ,a:0x%x\n", + color_index, r, g, b, a); add_to_update_list(index, OSD_COLOR_KEY); osd_wait_vsync_hw(); } @@ -2888,7 +2894,7 @@ void osd_clone_pan(u32 index, u32 yoffset, int debug_flag) osd_hw.pandata[OSD2].y_end = offset + height_osd1 - 1; if (osd_hw.angle[OSD2]) { if (debug_flag) - osd_log_dbg("++ osd_clone_pan start when enable clone\n"); + osd_log_dbg(MODULE_BASE, "++ osd_clone_pan start when enable clone\n"); osd_clone_update_pan(osd0_buffer_number); } add_to_update_list(OSD2, DISP_GEOMETRY); @@ -3540,7 +3546,6 @@ static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map) { u32 index = fence_map->fb_index; bool free_scale_set = false; - void *vaddr = NULL; canvas_config(osd_hw.fb_gem[index].canvas_idx, fence_map->ext_addr, @@ -3548,12 +3553,10 @@ static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map) (osd_hw.color_info[index]->bpp >> 3)), fence_map->height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - vaddr = phys_to_virt(fence_map->ext_addr); - osd_hw.screen_base[index] = vaddr; + osd_hw.screen_base[index] = fence_map->ext_addr; osd_hw.screen_size[index] = CANVAS_ALIGNED(fence_map->width * osd_hw.color_info[index]->bpp) * fence_map->height; - osd_hw.pandata[index].x_start = 0; osd_hw.pandata[index].x_end = fence_map->width - 1; osd_hw.pandata[index].y_start = 0; @@ -3618,10 +3621,8 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) u32 x_start, x_end, y_start, y_end; bool freescale_update = false; struct pandata_s freescale_dst[HW_OSD_COUNT]; - void *vaddr = NULL; ext_addr = ext_addr + fence_map->byte_stride * fence_map->yoffset; - vaddr = phys_to_virt(ext_addr); if (!osd_hw.osd_afbcd[index].enable) { canvas_config(osd_hw.fb_gem[index].canvas_idx, @@ -3629,6 +3630,9 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) fence_map->byte_stride, fence_map->height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + osd_hw.screen_base[index] = ext_addr; + osd_hw.screen_size[index] = + fence_map->byte_stride * fence_map->height; } else { osd_hw.osd_afbcd[index].phy_addr = ext_addr; osd_hw.osd_afbcd[index].frame_width = @@ -3649,6 +3653,8 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) else osd_hw.osd_afbcd[index].conv_lbuf_len = 1024; } + osd_hw.screen_base[index] = ext_addr; + osd_hw.screen_size[index] = fence_map->afbc_len; } width_dst = osd_hw.free_dst_data_backup[index].x_end - osd_hw.free_dst_data_backup[index].x_start + 1; @@ -3659,8 +3665,6 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_hw.free_dst_data_backup[index].y_start + 1; height_src = osd_hw.free_src_data_backup[index].y_end - osd_hw.free_src_data_backup[index].y_start + 1; - osd_hw.screen_base[index] = vaddr; - osd_hw.screen_size[index] = fence_map->byte_stride * fence_map->height; if (osd_hw.free_scale_enable[index] || (width_src != width_dst) || (height_src != height_dst) || @@ -3748,17 +3752,20 @@ static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map) osd_set_dummy_data(index, 0); else osd_set_dummy_data(index, 0xff); - osd_log_dbg("direct pandata x=%d,x_end=%d,y=%d,y_end=%d,width=%d,height=%d\n", + osd_log_dbg(MODULE_BASE, + "direct pandata x=%d,x_end=%d,y=%d,y_end=%d,width=%d,height=%d\n", osd_hw.pandata[index].x_start, osd_hw.pandata[index].x_end, osd_hw.pandata[index].y_start, osd_hw.pandata[index].y_end, fence_map->width, fence_map->height); - osd_log_dbg("fence_map:xoffset=%d,yoffset=%d\n", + osd_log_dbg(MODULE_BASE, + "fence_map:xoffset=%d,yoffset=%d\n", fence_map->xoffset, fence_map->yoffset); - osd_log_dbg("fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d,byte_stride=%d\n", + osd_log_dbg(MODULE_BASE, + "fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d,byte_stride=%d\n", fence_map->dst_x, fence_map->dst_y, fence_map->dst_w, @@ -3831,7 +3838,7 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) if (timeline_created) { /* out fence created success. */ ret = osd_wait_buf_ready(fence_map); if (ret < 0) - osd_log_dbg("fence wait ret %d\n", ret); + osd_log_dbg(MODULE_BASE, "fence wait ret %d\n", ret); } if (ret) { osd_hw.buffer_alloc[index] = 1; @@ -3958,7 +3965,8 @@ static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map) &osd_hw.free_dst_data_backup[index], sizeof(struct pandata_s)); osd_set_dummy_data(index, 0xff); - osd_log_dbg("switch back dispdata_backup x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_log_dbg(MODULE_BASE, + "switch back dispdata_backup x=%d,x_end=%d,y=%d,y_end=%d\n", osd_hw.dispdata_backup[index].x_start, osd_hw.dispdata_backup[index].x_end, osd_hw.dispdata_backup[index].y_start, @@ -4068,7 +4076,6 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) u32 index = layer_map->fb_index; const struct color_bit_define_s *color = NULL; u32 ext_addr = 0; - void *vaddr = NULL; u32 format = 0; if (index > OSD_MAX) @@ -4138,7 +4145,6 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) layer_map->byte_stride * layer_map->src_y; #endif - vaddr = phys_to_virt(ext_addr); if (!osd_hw.osd_afbcd[index].enable) { /*ext_addr is no crop, so height = * layer_map->src_h + layer_map->src_y @@ -4149,6 +4155,9 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) layer_map->src_h + layer_map->src_y, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); + osd_hw.screen_base[index] = ext_addr; + osd_hw.screen_size[index] = + layer_map->byte_stride * layer_map->src_h; } else { osd_hw.osd_afbcd[index].phy_addr = ext_addr; if (osd_hw.osd_meson_dev.afbc_type == @@ -4175,6 +4184,9 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) else osd_hw.osd_afbcd[index] .conv_lbuf_len = 1024; + osd_hw.screen_base[index] = ext_addr; + osd_hw.screen_size[index] = + layer_map->afbc_len; } else if (osd_hw.osd_meson_dev .afbc_type == MALI_AFBC) { osd_hw.osd_afbcd[index].frame_width = @@ -4182,11 +4194,11 @@ static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map) //BYTE_32_ALIGNED(layer_map->src_w); osd_hw.osd_afbcd[index].frame_height = BYTE_8_ALIGNED(layer_map->src_h); + osd_hw.screen_base[index] = ext_addr; + osd_hw.screen_size[index] = + layer_map->afbc_len; } } - osd_hw.screen_base[index] = vaddr; - osd_hw.screen_size[index] = - layer_map->byte_stride * layer_map->src_h; /* just get para, need update via do_hwc */ osd_hw.order[index] = layer_map->zorder; switch (layer_map->blend_mode) { @@ -4265,7 +4277,7 @@ static void osd_pan_display_layers_fence( layer_map = &fence_map->layer_map[i]; index = layer_map->fb_index; if (i != layer_map->fb_index) { - osd_hw.screen_base[i] = NULL; + osd_hw.screen_base[i] = 0; osd_hw.screen_size[i] = 0; osd_hw.enable[i] = 0; continue; @@ -4275,7 +4287,8 @@ static void osd_pan_display_layers_fence( && (fence_map->cmd == LAYER_SYNC)) { ret = osd_wait_buf_ready_combine(layer_map); if (ret < 0) - osd_log_dbg("fence wait ret %d\n", ret); + osd_log_dbg(MODULE_FENCE, + "fence wait ret %d\n", ret); } osd_pan_display_update_info(layer_map); save_layer_info(layer_map); @@ -4289,7 +4302,7 @@ static void osd_pan_display_layers_fence( /* single step mode */ if (osd_hw.osd_debug.osd_single_step > 0) { osd_timeline_increase(); - osd_log_dbg("signal out fence\n"); + osd_log_dbg(MODULE_FENCE, "signal out fence\n"); osd_hw.osd_debug.osd_single_step--; } else osd_hw.osd_debug.wait_fence_release = true; @@ -4343,7 +4356,7 @@ void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset) #ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT osd_ext_clone_pan(index); #endif - osd_log_dbg2("offset[%d-%d]x[%d-%d]y[%d-%d]\n", + osd_log_dbg2(MODULE_BASE, "offset[%d-%d]x[%d-%d]y[%d-%d]\n", xoffset, yoffset, osd_hw.pandata[index].x_start, osd_hw.pandata[index].x_end, @@ -4554,6 +4567,9 @@ static void osd_update_disp_freescale_enable(u32 index) if (osd_hw.scale_workaround) data32 |= 1 << 21; data32 |= 1 << 24; + if (osd_hw.osd_meson_dev.cpu_id >= + __MESON_CPU_MAJOR_ID_G12B) + data32 |= 1 << 25; } VSYNCOSD_WR_MPEG_REG(osd_reg->osd_vsc_ctrl0, data32); data32 = 0x0; @@ -5348,7 +5364,7 @@ static void exchange_din0_din2(struct hw_osd_blending_s *blending) { int temp1 = 0, temp2 = 0; - osd_log_dbg("need exchange osd din0 and din2 order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange osd din0 and din2 order\n"); temp1 = blending->din_reoder_sel & 0x000f; temp2 = blending->din_reoder_sel & 0x0f00; blending->din_reoder_sel &= ~0x0f0f; @@ -5358,7 +5374,7 @@ static void exchange_din0_din2(struct hw_osd_blending_s *blending) temp2 = blending->osd_to_bdin_table[2]; blending->osd_to_bdin_table[2] = temp1; blending->osd_to_bdin_table[0] = temp2; - osd_log_dbg("din_reoder_sel%x\n", + osd_log_dbg(MODULE_BLEND, "din_reoder_sel%x\n", blending->din_reoder_sel); } @@ -5366,7 +5382,7 @@ static void exchange_din2_din3(struct hw_osd_blending_s *blending) { int temp1 = 0, temp2 = 0; - osd_log_dbg("need exchange osd din2 and din3 order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange osd din2 and din3 order\n"); temp1 = blending->din_reoder_sel & 0x0f00; temp2 = blending->din_reoder_sel & 0xf000; blending->din_reoder_sel &= ~0xff00; @@ -5376,14 +5392,14 @@ static void exchange_din2_din3(struct hw_osd_blending_s *blending) temp2 = blending->osd_to_bdin_table[3]; blending->osd_to_bdin_table[3] = temp1; blending->osd_to_bdin_table[2] = temp2; - osd_log_dbg("din_reoder_sel%x\n", + osd_log_dbg(MODULE_BLEND, "din_reoder_sel%x\n", blending->din_reoder_sel); } static void exchange_vpp_order(struct hw_osd_blending_s *blending) { blending->b_exchange_blend_in = true; - osd_log_dbg("need exchange vpp order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n"); } static void generate_blend_din_table(struct hw_osd_blending_s *blending) @@ -5422,9 +5438,9 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) j++; } } - osd_log_dbg("blend_din4==%d\n", + osd_log_dbg(MODULE_BLEND, "blend_din4==%d\n", blending->reorder[temp_index[0]]); - osd_log_dbg("blend_din1==%d\n", + osd_log_dbg(MODULE_BLEND, "blend_din1==%d\n", blending->reorder[temp_index[1]]); /* mode A_C */ if (blending->osd_blend_mode == OSD_BLEND_A_C) { @@ -5440,7 +5456,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) if (blending->reorder[temp_index[0]] < blending->reorder[temp_index[1]]) { blending->b_exchange_blend_in = true; - osd_log_dbg("need exchange vpp order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n"); } } else { if (blending->reorder[temp_index[0]] < @@ -5456,7 +5472,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) /* blend_din1 -- osdx */ blending->osd_to_bdin_table[0] = temp_index[1]; blending->b_exchange_din = true; - osd_log_dbg("need exchange osd din order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n"); } else { /* blend_din1 */ blending->din_reoder_sel |= @@ -5474,7 +5490,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) } case 3: /* blend_din1 is bottom, blend_din4 is top layer */ - osd_log_dbg("reorder:%d,%d,%d\n", + osd_log_dbg(MODULE_BLEND, "reorder:%d,%d,%d\n", blending->reorder[OSD1], blending->reorder[OSD2], blending->reorder[OSD3]); @@ -5497,7 +5513,8 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) if ((blending->reorder[OSD1] == LAYER_3) && (blending->reorder[OSD2] == LAYER_2) && (blending->reorder[OSD3] == LAYER_1)) { - osd_log_dbg2("use default order\n"); + osd_log_dbg2(MODULE_BLEND, + "use default order\n"); } else if ((blending->reorder[OSD1] == LAYER_2) && (blending->reorder[OSD2] == LAYER_3) && (blending->reorder[OSD3] == LAYER_1)) { @@ -5552,7 +5569,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) temp2 |= (0x04 << (i*4)); } blending->din_reoder_sel |= temp2; - osd_log_dbg("osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", + osd_log_dbg(MODULE_BLEND, "osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", blending->osd_to_bdin_table[0], blending->osd_to_bdin_table[1], blending->osd_to_bdin_table[2], @@ -5597,9 +5614,9 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) j++; } } - osd_log_dbg("blend_din4==%d\n", + osd_log_dbg(MODULE_BLEND, "blend_din4==%d\n", blending->reorder[temp_index[0]]); - osd_log_dbg("blend_din1==%d\n", + osd_log_dbg(MODULE_BLEND, "blend_din1==%d\n", blending->reorder[temp_index[1]]); /* mode A_C */ if (blending->osd_blend_mode == OSD_BLEND_A_C) { @@ -5615,7 +5632,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) if (blending->reorder[temp_index[0]] < blending->reorder[temp_index[1]]) { blending->b_exchange_blend_in = true; - osd_log_dbg("need exchange vpp order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n"); } } else { if (blending->reorder[temp_index[0]] < @@ -5631,7 +5648,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) /* blend_din1 -- osdx */ blending->osd_to_bdin_table[0] = temp_index[1]; blending->b_exchange_din = true; - osd_log_dbg("need exchange osd din order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n"); } else { /* blend_din1 */ blending->din_reoder_sel |= @@ -5680,12 +5697,12 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) if (blending->reorder[OSD1] < blending->reorder[OSD3]) { if (blending->osd_blend_mode == OSD_BLEND_A_BC) { blending->b_exchange_blend_in = true; - osd_log_dbg("need exchange vpp order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n"); } else { u32 temp1, temp2; blending->b_exchange_din = true; - osd_log_dbg("need exchange osd din order\n"); + osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n"); temp1 = blending->osd_to_bdin_table[2]; temp2 = blending->osd_to_bdin_table[3]; blending->osd_to_bdin_table[3] = @@ -5701,7 +5718,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) } break; } - osd_log_dbg("osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", + osd_log_dbg(MODULE_BLEND, "osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", blending->osd_to_bdin_table[0], blending->osd_to_bdin_table[1], blending->osd_to_bdin_table[2], @@ -5756,13 +5773,13 @@ static int osd_setting_blending_scope(u32 index) osd_hw.dst_data[index].y + osd_hw.dst_data[index].h - 1; - osd_log_dbg("osd%d_hw.dst_data:%d,%d,%d,%d\n", + osd_log_dbg(MODULE_BLEND, "osd%d_hw.dst_data:%d,%d,%d,%d\n", index, osd_hw.dst_data[index].x, osd_hw.dst_data[index].y, osd_hw.dst_data[index].w, osd_hw.dst_data[index].h); - osd_log_dbg("h,v axis:%d,%d,%d,%d\n", + osd_log_dbg(MODULE_BLEND, "h,v axis:%d,%d,%d,%d\n", bld_osd_h_start, bld_osd_h_end, bld_osd_v_start, @@ -5786,7 +5803,7 @@ static int vpp_blend_setting_default(u32 index) u32 osd1_h_start = 0, osd1_h_end = 0; u32 osd1_v_start = 0, osd1_v_end = 0; - osd_log_dbg("vpp_blend_setting_default\n"); + osd_log_dbg(MODULE_BASE, "vpp_blend_setting_default\n"); if (index > OSD3) { osd_log_err("error osd index=%d\n", index); @@ -5844,7 +5861,7 @@ static void set_blend_order(struct hw_osd_blending_s *blending) } insert_sort(order, osd_count); //check_order_continuous(order); - osd_log_dbg2("after sort:zorder:%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "after sort:zorder:%d,%d,%d\n", order[0], order[1], order[2]); /* reorder[i] = osd[i]'s display layer */ @@ -5859,7 +5876,7 @@ static void set_blend_order(struct hw_osd_blending_s *blending) } } } - osd_log_dbg2("after reorder:zorder:%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "after reorder:zorder:%d,%d,%d\n", blending->reorder[0], blending->reorder[1], blending->reorder[2]); @@ -5927,7 +5944,7 @@ static void set_blend_mode(struct hw_osd_blending_s *blending) break; } blending->osd_blend_mode = osd_blend_mode; - osd_log_dbg2("osd_blend_mode=%d\n", + osd_log_dbg2(MODULE_BLEND, "osd_blend_mode=%d\n", blending->osd_blend_mode); } @@ -5941,12 +5958,12 @@ static void calc_max_output(struct hw_osd_blending_s *blending) if (!blending) return; layer_blend = &(blending->layer_blend); - osd_log_dbg2("calc_max_output input1_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "calc_max_output input1_data:%d,%d,%d,%d\n", layer_blend->input1_data.x, layer_blend->input1_data.y, layer_blend->input1_data.w, layer_blend->input1_data.h); - osd_log_dbg2("calc_max_output input2_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "calc_max_output input2_data:%d,%d,%d,%d\n", layer_blend->input2_data.x, layer_blend->input2_data.y, layer_blend->input2_data.w, @@ -6029,13 +6046,15 @@ static void osd_setting_blend0(struct hw_osd_blending_s *blending) + layer_blend->input1_data.w; layer_blend->output_data.h = layer_blend->input1_data.y + layer_blend->input1_data.h; - osd_log_dbg2("blend0:input1_data[osd%d]:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "blend0:input1_data[osd%d]:%d,%d,%d,%d\n", index, layer_blend->input1_data.x, layer_blend->input1_data.y, layer_blend->input1_data.w, layer_blend->input1_data.h); - osd_log_dbg2("blend0:layer_blend->output_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "blend0:layer_blend->output_data:%d,%d,%d,%d\n", layer_blend->output_data.x, layer_blend->output_data.y, layer_blend->output_data.w, @@ -6105,7 +6124,8 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) bld_osd_h_end << 16 | bld_osd_h_start; blend_reg->osd_blend_din_scope_v[index] = bld_osd_v_end << 16 | bld_osd_v_start; - osd_log_dbg2("blend1:input1_data(osd%d):%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "blend1:input1_data(osd%d):%d,%d,%d,%d\n", index, layer_blend->input1_data.x, layer_blend->input1_data.y, @@ -6131,7 +6151,8 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) bld_osd_h_end << 16 | bld_osd_h_start; blend_reg->osd_blend_din_scope_v[index] = bld_osd_v_end << 16 | bld_osd_v_start; - osd_log_dbg2("layer_blend->input2_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "layer_blend->input2_data:%d,%d,%d,%d\n", layer_blend->input2_data.x, layer_blend->input2_data.y, layer_blend->input2_data.w, @@ -6167,7 +6188,7 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) blend_reg->osd_blend_blend1_size = blend_vsize << 16 | blend_hsize; - osd_log_dbg2("layer_blend1->output_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "layer_blend1->output_data:%d,%d,%d,%d\n", layer_blend->output_data.x, layer_blend->output_data.y, layer_blend->output_data.w, @@ -6232,7 +6253,7 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending) blend_reg->osd_blend_blend0_size; #endif } - osd_log_dbg2("layer_blend2->output_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "layer_blend2->output_data:%d,%d,%d,%d\n", layer_blend->output_data.x, layer_blend->output_data.y, layer_blend->output_data.w, @@ -6331,10 +6352,12 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending) blend_reg->postbld_osd2_premult = 0; break; } - osd_log_dbg2("vpp_osd1_blend_h_scope=%x, vpp_osd1_blend_v_scope=%x\n", + osd_log_dbg2(MODULE_BLEND, + "vpp_osd1_blend_h_scope=%x, vpp_osd1_blend_v_scope=%x\n", blend_reg->vpp_osd1_blend_h_scope, blend_reg->vpp_osd1_blend_v_scope); - osd_log_dbg2("vpp_osd2_blend_h_scope=%x, vpp_osd2_blend_v_scope=%x\n", + osd_log_dbg2(MODULE_BLEND, + "vpp_osd2_blend_h_scope=%x, vpp_osd2_blend_v_scope=%x\n", blend_reg->vpp_osd2_blend_h_scope, blend_reg->vpp_osd2_blend_v_scope); } @@ -6409,7 +6432,7 @@ static void osd_set_freescale(u32 index, if (width > FREE_SCALE_MAX_WIDTH) width = FREE_SCALE_MAX_WIDTH; } else if (blending->osd_blend_mode == OSD_BLEND_AB_C) { - osd_log_dbg("blending->blend_din=%d\n", + osd_log_dbg(MODULE_BLEND, "blending->blend_din=%d\n", blending->blend_din); if (blending->blend_din != BLEND_DIN4) { /* combine mode, need uniformization */ @@ -6465,20 +6488,17 @@ static void osd_set_freescale(u32 index, osd_hw.free_src_data[index].x_start + 1; if ((osd_hw.osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_G12A) && - (height != src_height)) { - osd_hw.osd_meson_dev.dummy_data = 0x000000; + (height != src_height)) osd_set_dummy_data(index, 0); - } else { - osd_hw.osd_meson_dev.dummy_data = 0x808000; + else osd_set_dummy_data(index, 0xff); - } - osd_log_dbg2("osd%d:free_src_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "osd%d:free_src_data:%d,%d,%d,%d\n", index, osd_hw.free_src_data[index].x_start, osd_hw.free_src_data[index].y_start, osd_hw.free_src_data[index].x_end, osd_hw.free_src_data[index].y_end); - osd_log_dbg2("osd%d:free_dst_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "osd%d:free_dst_data:%d,%d,%d,%d\n", index, osd_hw.free_dst_data[index].x_start, osd_hw.free_dst_data[index].y_start, @@ -6518,7 +6538,8 @@ static void osd_setting_blend0_input(u32 index, osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; } - osd_log_dbg2("blend0_input:input0_data[osd%d]:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "blend0_input:input0_data[osd%d]:%d,%d,%d,%d\n", index, layer_blend->input1_data.x, layer_blend->input1_data.y, @@ -6570,7 +6591,8 @@ static void osd_setting_blend1_input(u32 index, osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; } - osd_log_dbg2("blend1_input:input_data[osd%d]:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "blend1_input:input_data[osd%d]:%d,%d,%d,%d\n", index, layer_blend->output_data.x, layer_blend->output_data.y, @@ -6625,8 +6647,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_setting_blend2(blending); } /* osd1 freescale,output is vinfo.w/h */ - osd_log_dbg2("after blend: set osd%d freescale\n", - index); + osd_log_dbg2(MODULE_BLEND, + "after blend: set osd%d freescale\n", index); osd_set_freescale(index, blending); layer_blend->input1 = BLEND2_DIN; @@ -6645,7 +6667,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; } else { - osd_log_dbg2("first: set osd%d freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "first: set osd%d freescale\n", index); osd_set_freescale(index, blending); osd_hw.free_dst_data[index].x_start += osd_hw.disp_info.position_x; @@ -6705,7 +6728,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) #endif if (index != OSD1) { /* here used freescale osd1/osd2 */ - osd_log_dbg2("before blend0: set osd%d freescale\n", + osd_log_dbg2(MODULE_BLEND, + "before blend0: set osd%d freescale\n", index); osd_set_freescale(index, blending); } @@ -6720,7 +6744,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) if (index >= OSD_MAX) return; if (index != OSD1) { - osd_log_dbg2("before blend1: set osd%d freescale\n", + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); } @@ -6801,7 +6826,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_setting_blend2(blending); } /* here freescale osd0 used */ - osd_log_dbg2("after blend: set osd%d freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "after blend: set osd%d freescale\n", index); osd_set_freescale(index, blending); /* save freescale output */ output1_data.x = @@ -6817,7 +6843,7 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; - osd_log_dbg2("position_x=%d, y=%d\n", + osd_log_dbg2(MODULE_BLEND, "position_x=%d, y=%d\n", osd_hw.disp_info.position_x, osd_hw.disp_info.position_y); @@ -6825,7 +6851,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) if (index >= OSD_MAX) return; /* here freescale osd1/osd2 used */ - osd_log_dbg2("before blend1: set osd%d freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); #ifdef OSD_BLEND_SHIFT_WORKAROUND layer_blend->input1 = BLEND_NO_DIN; @@ -6895,7 +6922,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) if (index >= OSD_MAX) return; if (index != OSD1) { - osd_log_dbg2("index=%d, need set freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "index=%d, need set freescale\n", index); osd_set_freescale(index, blending); } osd_setting_blend0_input(index, blending); @@ -6907,7 +6935,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input2 = input2; index = blend_din_to_osd(layer_blend->input1, blending); if (index != OSD1) { - osd_log_dbg2("blend1 input1: set osd%d freescale\n", + osd_log_dbg2(MODULE_BLEND, + "blend1 input1: set osd%d freescale\n", index); osd_set_freescale(index, blending); } @@ -6920,7 +6949,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) if (index >= OSD_MAX) return; if (index != OSD1) { - osd_log_dbg2("blend1 input2: set osd%d freescale\n", + osd_log_dbg2(MODULE_BLEND, + "blend1 input2: set osd%d freescale\n", index); osd_set_freescale(index, blending); } @@ -6981,7 +7011,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_setting_blend2(blending); } - osd_log_dbg("after blend2: set osd%d freescale\n", index); + osd_log_dbg(MODULE_BLEND, + "after blend2: set osd%d freescale\n", index); osd_set_freescale(index, blending); /* save freescale output */ output1_data.x = @@ -6999,7 +7030,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) index = blend_din_to_osd(BLEND_DIN3, blending); if (index >= OSD_MAX) return; - osd_log_dbg2("before blend1: set osd%d freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); layer_blend->input1_data.x = osd_hw.free_dst_data[index].x_start + @@ -7017,7 +7049,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) index = blend_din_to_osd(BLEND_DIN4, blending); if (index >= OSD_MAX) return; - osd_log_dbg2("before blend1: set osd%d freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); layer_blend->input2_data.x = osd_hw.free_dst_data[index].x_start + @@ -7084,7 +7117,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) blending->blend_din = BLEND_DIN3; index = blend_din_to_osd(BLEND_DIN3, blending); if (index != OSD1) { - osd_log_dbg2("before blend1: set osd%d freescale\n", + osd_log_dbg2(MODULE_BLEND, + "before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); } @@ -7117,7 +7151,7 @@ static void set_blend_path(struct hw_osd_blending_s *blending) output1_data.h = osd_hw.free_dst_data[OSD1].y_end - osd_hw.free_dst_data[OSD1].y_start + 1; - osd_log_dbg2("output1_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n", output1_data.x, output1_data.w, output1_data.y, @@ -7127,7 +7161,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) /* din4 ==> vpp */ index = blend_din_to_osd(BLEND_DIN4, blending); blending->blend_din = BLEND_DIN4; - osd_log_dbg2("bypass blend1: set osd%d freescale\n", index); + osd_log_dbg2(MODULE_BLEND, + "bypass blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending); layer_blend->input2_data.x = @@ -7248,18 +7283,18 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg) } #endif } - dv_core2_vsize = (blend_reg->vpp_osd1_blend_v_scope & 0xfff) - - ((blend_reg->vpp_osd1_blend_v_scope >> 16) & 0xfff) + 1; - dv_core2_hsize = (blend_reg->vpp_osd1_blend_h_scope & 0xfff) - - ((blend_reg->vpp_osd1_blend_h_scope >> 16) & 0xfff) + 1; + + dv_core2_vsize = (blend_reg->osd_blend_blend0_size >> 16) & 0xfff; + dv_core2_hsize = blend_reg->osd_blend_blend0_size & 0xfff; + if (osd_hw.osd_meson_dev.has_dolby_vision) { VSYNCOSD_WR_MPEG_REG( DOLBY_CORE2A_SWAP_CTRL1, - ((dv_core2_vsize + 0x40) << 16) - | (dv_core2_hsize + 0x80 + 0)); + ((dv_core2_hsize + 0x40) << 16) + | (dv_core2_vsize + 0x80 + 0)); VSYNCOSD_WR_MPEG_REG( DOLBY_CORE2A_SWAP_CTRL2, - (dv_core2_vsize << 16) | (dv_core2_hsize + 0)); + (dv_core2_hsize << 16) | (dv_core2_vsize + 0)); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION update_graphic_width_height(dv_core2_vsize, dv_core2_hsize); #endif @@ -7289,7 +7324,8 @@ static void uniformization_fb(u32 index, blending->dst_data.w + blending->dst_data.x, osd_hw.disp_info.background_w); } - osd_log_dbg2("uniformization:osd%d:dst_data:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "uniformization:osd%d:dst_data:%d,%d,%d,%d\n", index, blending->dst_data.x, blending->dst_data.y, @@ -7312,7 +7348,8 @@ static void adjust_dst_position(void) osd_hw.dst_data[i].x = 0; if (osd_hw.dst_data[i].y < 0) osd_hw.dst_data[i].y = 0; - osd_log_dbg2("adjust dst_data:osd%d:%d,%d,%d,%d\n", + osd_log_dbg2(MODULE_BLEND, + "adjust dst_data:osd%d:%d,%d,%d,%d\n", i, osd_hw.dst_data[i].x, osd_hw.dst_data[i].y, @@ -7349,7 +7386,8 @@ static int osd_setting_order(void) blending->layer_cnt = get_available_layers(); set_blend_order(blending); - osd_log_dbg("layer_cnt:%d\n", blending->layer_cnt); + osd_log_dbg(MODULE_BLEND, "layer_cnt:%d\n", + blending->layer_cnt); blending->b_exchange_din = false; blending->b_exchange_blend_in = false; @@ -7369,10 +7407,9 @@ static int osd_setting_order(void) vinfo_height = osd_hw.field_out_en ? (osd_hw.vinfo_height * 2) : osd_hw.vinfo_height; if (line1 >= vinfo_height) { - if (osd_hw.osd_display_debug == ENCP_LINE_VSYNC) - osd_log_info( - "enter osd_setting_order:cnt=%d,encp line=%d\n", - cnt, line1); + osd_log_dbg(MODULE_RENDER, + "enter osd_setting_order:cnt=%d,encp line=%d\n", + cnt, line1); osd_wait_vsync_hw(); line1 = get_enter_encp_line(); } @@ -7437,10 +7474,9 @@ static int osd_setting_order(void) save_blend_reg(blend_reg); spin_unlock_irqrestore(&osd_lock, lock_flags); line2 = get_exit_encp_line(); - if (osd_hw.osd_display_debug == ENCP_LINE) - osd_log_info( - "enter osd_setting_order:cnt=%d,encp line=%d\n", - cnt, line2); + osd_log_dbg2(MODULE_RENDER, + "enter osd_setting_order:cnt=%d,encp line=%d\n", + cnt, line2); if (line2 < line1) osd_log_info("osd line %d,%d\n", line1, line2); osd_wait_vsync_hw(); @@ -7463,7 +7499,7 @@ static void osd_setting_default_hwc(void) u32 postbld_src3_sel = 3, postbld_src4_sel = 0; u32 postbld_osd1_premult = 0, postbld_osd2_premult = 0; - osd_log_dbg("osd_setting_default_hwc\n"); + osd_log_dbg(MODULE_BASE, "osd_setting_default_hwc\n"); /* depend on din0_premult_en */ postbld_osd1_premult = 1; /* depend on din_premult_en bit 4 */ @@ -7550,12 +7586,6 @@ static bool set_old_hwc_freescale(u32 index) osd_hw.free_dst_data[index].y_start = y_start; osd_hw.free_dst_data[index].y_end = y_end; } - osd_log_dbg("free_dst_data: %x,%x,%x,%x\n", - osd_hw.free_dst_data[index].x_start, - osd_hw.free_dst_data[index].x_end, - osd_hw.free_dst_data[index].y_start, - osd_hw.free_dst_data[index].y_end); - /* set dummy_data alpha */ height_dst = osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; @@ -8488,7 +8518,6 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, osd_hw.free_src_data_backup[idx].y_end = 0; osd_hw.free_scale_mode[idx] = 0; osd_hw.buffer_alloc[idx] = 0; - osd_hw.osd_clear[idx] = 0; osd_hw.osd_afbcd[idx].enable = 0; osd_hw.use_h_filter_mode[idx] = -1; osd_hw.use_v_filter_mode[idx] = -1; @@ -8653,7 +8682,7 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, if (index != 1) return; - osd_log_dbg2("cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n", + osd_log_dbg(MODULE_CURSOR, "cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n", x, y, xstart, ystart, osd_w, osd_h); if (osd_hw.free_scale_mode[OSD1]) { @@ -8709,7 +8738,7 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, osd_hw.pandata[OSD2].y_end = osd_h - 1; x -= osd_w; y -= osd_h; - osd_log_dbg2("x=%d,y=%d\n", x, y); + osd_log_dbg(MODULE_CURSOR, "x=%d,y=%d\n", x, y); } /* * Use pandata to show a partial cursor when it is at the edge because @@ -8786,7 +8815,152 @@ void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start; add_to_update_list(OSD2, OSD_COLOR_MODE); add_to_update_list(OSD2, DISP_GEOMETRY); - osd_log_dbg2("dispdata: %d,%d,%d,%d\n", + osd_log_dbg(MODULE_CURSOR, "dispdata: %d,%d,%d,%d\n", + osd_hw.dispdata[OSD2].x_start, osd_hw.dispdata[OSD2].x_end, + osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end); +} + +void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, + u32 osd_w, u32 osd_h) +{ + struct pandata_s disp_tmp; + struct vinfo_s *vinfo = NULL; + int w = 0, h = 0; + int w_diff = 0; + + if (index != 1) + return; + + osd_log_dbg(MODULE_CURSOR, "cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n", + x, y, xstart, ystart, osd_w, osd_h); + + if (osd_hw.free_scale_mode[OSD1]) { + if (osd_hw.free_scale_enable[OSD1]) + memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1], + sizeof(struct pandata_s)); + else + memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], + sizeof(struct pandata_s)); + } else + memcpy(&disp_tmp, &osd_hw.dispdata[OSD1], + sizeof(struct pandata_s)); + + if (osd_hw.field_out_en) { + disp_tmp.y_start *= 2; + disp_tmp.y_end *= 2; + } + + if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { + vinfo = get_current_vinfo(); + + if ((vinfo == NULL) || (vinfo->mode == VMODE_INIT_NULL)) + return; + + w = vinfo->width; + h = vinfo->height; + + x = w - x; + y = h - y; + } + + x += xstart; + y += ystart; + + if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { + if (osd_w >= osd_h) + w_diff = osd_w - osd_h; + else + w_diff = 0; + osd_hw.pandata[OSD2].x_start = w_diff; + osd_hw.pandata[OSD2].x_end = osd_w - 1; + osd_hw.pandata[OSD2].y_start = 0; + osd_hw.pandata[OSD2].y_end = osd_h - 1; + x -= osd_w; + y -= osd_h; + osd_log_dbg(MODULE_CURSOR, "x=%d,y=%d\n", x, y); + } + + + /* + * Use pandata to show a partial cursor when it is at the edge because + * the registers can't have negative values and because we need to + * manually clip the cursor when it is past the edge. The edge is + * hardcoded to the OSD0 area. + */ + osd_hw.dispdata[OSD2].x_start = x; + osd_hw.dispdata[OSD2].y_start = y; + if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) { + if (x < disp_tmp.x_start) { + /* if negative position, set osd x pan. */ + if ((disp_tmp.x_start - x) < osd_w) { + osd_hw.pandata[OSD2].x_start = + w_diff; + osd_hw.pandata[OSD2].x_end = + osd_w - 1 - (disp_tmp.x_start - x); + } + /* set osd x to disp_tmp.x_start */ + osd_hw.dispdata[OSD2].x_start = disp_tmp.x_start; + } + if (y < disp_tmp.y_start) { + /* if negative position, set osd y pan. */ + if ((disp_tmp.y_start - y) < osd_h) { + osd_hw.pandata[OSD2].y_start = 0; + osd_hw.pandata[OSD2].y_end = + osd_h - 1 - (disp_tmp.y_start - y); + } + /* set osd y to disp_tmp.y_start */ + osd_hw.dispdata[OSD2].y_start = disp_tmp.y_start; + } + } else { + if (x < disp_tmp.x_start) { + /* if negative position, set osd to 0,y and pan. */ + if ((disp_tmp.x_start - x) < osd_w) { + osd_hw.pandata[OSD2].x_start = + disp_tmp.x_start - x; + osd_hw.pandata[OSD2].x_end = osd_w - 1; + } + osd_hw.dispdata[OSD2].x_start = 0; + } else { + osd_hw.pandata[OSD2].x_start = 0; + if (x + osd_w > disp_tmp.x_end) { + /* + * if past positive edge, + * set osd to inside of the edge and pan. + */ + if (x < disp_tmp.x_end) + osd_hw.pandata[OSD2].x_end = + disp_tmp.x_end - x; + } else + osd_hw.pandata[OSD2].x_end = osd_w - 1; + } + if (y < disp_tmp.y_start) { + if ((disp_tmp.y_start - y) < osd_h) { + osd_hw.pandata[OSD2].y_start = + disp_tmp.y_start - y; + osd_hw.pandata[OSD2].y_end = osd_h - 1; + } + osd_hw.dispdata[OSD2].y_start = 0; + } else { + osd_hw.pandata[OSD2].y_start = 0; + if (y + osd_h > disp_tmp.y_end) { + if (y < disp_tmp.y_end) + osd_hw.pandata[OSD2].y_end = + disp_tmp.y_end - y; + } else + osd_hw.pandata[OSD2].y_end = osd_h - 1; + } + } + + if (osd_hw.field_out_en) + osd_hw.dispdata[OSD2].y_start /= 2; + + osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start + + osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start; + osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start + + osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start; + add_to_update_list(OSD2, OSD_COLOR_MODE); + add_to_update_list(OSD2, DISP_GEOMETRY); + osd_log_dbg(MODULE_CURSOR, "dispdata: %d,%d,%d,%d\n", osd_hw.dispdata[OSD2].x_start, osd_hw.dispdata[OSD2].x_end, osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end); } @@ -8996,28 +9170,255 @@ void osd_get_blending_para(struct hw_osd_blending_s **para) } void osd_backup_screen_info( u32 index, - char __iomem *screen_base, - u32 screen_size) + unsigned long screen_base, + unsigned long screen_size) { osd_hw.screen_base_backup[index] = screen_base; osd_hw.screen_size_backup[index] = screen_size; - osd_hw.screen_base[index] = screen_base; - osd_hw.screen_size[index] = screen_size; } -void osd_restore_screen_info( +void osd_get_screen_info( u32 index, char __iomem **screen_base, unsigned long *screen_size) { - *screen_base = osd_hw.screen_base[index]; - *screen_size = (unsigned long)osd_hw.screen_size[index]; - + *screen_base = (char __iomem *)osd_hw.screen_base[index]; + *screen_size = osd_hw.screen_size[index]; } -void osd_set_clear(u32 index, u32 osd_clear) +int get_vmap_addr(u32 index, u8 __iomem **buf) { - osd_hw.osd_clear[index] = osd_clear; + unsigned long total_size; + ulong phys; + u32 offset, npages; + struct page **pages = NULL; + pgprot_t pgprot; + static u8 *vaddr; + int i; + + total_size = osd_hw.screen_size[index]; + + npages = PAGE_ALIGN(total_size) / PAGE_SIZE; + phys = osd_hw.screen_base[index]; + offset = phys & ~PAGE_MASK; + if (offset) + npages++; + pages = vmalloc(sizeof(struct page *) * npages); + if (!pages) + return -ENOMEM; + for (i = 0; i < npages; i++) { + pages[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + vfree(pages); + return -ENOMEM; + } + vfree(pages); + *buf = (u8 __iomem *) (vaddr); + + return osd_hw.screen_size[index]; +} +#if 0 +static int is_new_page(unsigned long addr, unsigned long pos) +{ + static ulong pre_addr; + u32 offset; + int ret = 0; + + /* ret == 0 : in same page*/ + if (pos == 0) + ret = 1; + else { + offset = pre_addr & ~PAGE_MASK; + if ((offset + addr - pre_addr) >= PAGE_SIZE) + ret = 1; + } + pre_addr = addr; + return ret; +} + +ssize_t dd_vmap_write(u32 index, const char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + unsigned long total_size; + static u8 *vaddr; + ulong phys; + u32 offset, npages; + struct page **pages = NULL; + struct page *pages_array[2] = {}; + pgprot_t pgprot; + u8 *buffer, *src; + u8 __iomem *dst; + int i, c, cnt = 0, err = 0; + + total_size = osd_hw.screen_size[index]; + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + if (count < PAGE_SIZE) { + /* small than one page, need not vmalloc */ + npages = PAGE_ALIGN(count) / PAGE_SIZE; + phys = osd_hw.screen_base[index] + p; + if (is_new_page(phys, p)) { + /* new page, need call vmap*/ + offset = phys & ~PAGE_MASK; + if ((offset + count) > PAGE_SIZE) + npages++; + for (i = 0; i < npages; i++) { + pages_array[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages_array, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + return -ENOMEM; + } + dst = (u8 __iomem *) (vaddr); + } else { + /* in same page just get vaddr + p*/ + dst = (u8 __iomem *) (vaddr + (p & ~PAGE_MASK)); + } + } else { + npages = PAGE_ALIGN(count) / PAGE_SIZE; + phys = osd_hw.screen_base[index] + p; + offset = phys & ~PAGE_MASK; + if ((offset + count) > PAGE_SIZE) + npages++; + pages = vmalloc(sizeof(struct page *) * npages); + if (!pages) + return -ENOMEM; + for (i = 0; i < npages; i++) { + pages[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + //pgprot = PAGE_KERNEL; + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + vfree(pages); + return -ENOMEM; + } + vfree(pages); + dst = (u8 __iomem *) (vaddr); + } + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + /* osd_sync() */ + + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + src = buffer; + + if (copy_from_user(src, buf, c)) { + err = -EFAULT; + break; + } + + fb_memcpy_tofb(dst, src, c); + dst += c; + *ppos += c; + buf += c; + cnt += c; + count -= c; + } + kfree(buffer); + return (cnt) ? cnt : err; +} +#endif +int osd_set_clear(u32 index) +{ + unsigned long total_size; + ulong phys; + u32 offset, npages; + struct page **pages = NULL; + pgprot_t pgprot; + static u8 *vaddr; + u8 __iomem *dst; + int i, c, count, cnt = 0; + + total_size = osd_hw.screen_size[index]; + npages = PAGE_ALIGN(total_size) / PAGE_SIZE; + phys = osd_hw.screen_base[index]; + offset = phys & (~PAGE_MASK); + if (offset) + npages++; + pages = vmalloc(sizeof(struct page *) * npages); + if (!pages) + return -ENOMEM; + for (i = 0; i < npages; i++) { + pages[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + pr_err("the phy(%lx) vmaped fail, size: %d\n", + phys, npages << PAGE_SHIFT); + vfree(pages); + return -ENOMEM; + } + vfree(pages); + dst = (u8 __iomem *) (vaddr); + + count = total_size; + while (count) { + c = (count > PAGE_SIZE) ? PAGE_SIZE : count; + memset(dst, 0, c); + dst += c; + cnt += c; + count -= c; + } + if (vaddr) { + /* unmap prevois vaddr */ + vunmap(vaddr); + vaddr = NULL; + } + + return cnt; } static const struct color_bit_define_s *convert_panel_format(u32 format) @@ -9065,19 +9466,12 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) u32 x_start, x_end, y_start, y_end; bool freescale_update = false; struct pandata_s freescale_dst[HW_OSD_COUNT]; - void *vaddr = NULL; phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y; - vaddr = phys_to_virt(phy_addr); - osd_hw.screen_base[index] = vaddr; + osd_hw.screen_base[index] = phy_addr; osd_hw.screen_size[index] = plane_map->byte_stride * plane_map->src_h; - if (osd_hw.osd_clear[index]) { - if (vaddr) - memset(vaddr, 0x0, - plane_map->byte_stride*plane_map->src_h); - } - osd_log_dbg("canvas_id=%x, phy_addr=%x\n", + osd_log_dbg(MODULE_RENDER, "canvas_id=%x, phy_addr=%x\n", osd_hw.fb_gem[index].canvas_idx, phy_addr); canvas_config(osd_hw.fb_gem[index].canvas_idx, phy_addr, @@ -9110,12 +9504,14 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) osd_hw.dst_data[index].y = plane_map->dst_y; osd_hw.dst_data[index].w = plane_map->dst_w; osd_hw.dst_data[index].h = plane_map->dst_h; - osd_log_dbg2("index=%d\n", index); - osd_log_dbg2("order=%d\n", osd_hw.order[index]); - osd_log_dbg2("premult_en=%d\n", osd_hw.premult_en[index]); - osd_log_dbg2("osd_afbcd_en=%d\n", + osd_log_dbg2(MODULE_RENDER, "index=%d\n", index); + osd_log_dbg2(MODULE_RENDER, "order=%d\n", + osd_hw.order[index]); + osd_log_dbg2(MODULE_RENDER, "premult_en=%d\n", + osd_hw.premult_en[index]); + osd_log_dbg2(MODULE_RENDER, "osd_afbcd_en=%d\n", osd_hw.osd_afbcd[index].enable); - osd_log_dbg2("osd_afbcd_inter_format=%d\n", + osd_log_dbg2(MODULE_RENDER, "osd_afbcd_inter_format=%d\n", osd_hw.osd_afbcd[index].inter_format); return 0; } @@ -9232,17 +9628,20 @@ static bool osd_direct_render(struct osd_plane_map_s *plane_map) else osd_set_dummy_data(index, 0xff); } - osd_log_dbg2("pandata x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_log_dbg2(MODULE_RENDER, + "pandata x=%d,x_end=%d,y=%d,y_end=%d\n", osd_hw.pandata[index].x_start, osd_hw.pandata[index].x_end, osd_hw.pandata[index].y_start, osd_hw.pandata[index].y_end); - osd_log_dbg2("plane_map:src_x=%d,src_y=%d,src_w=%d,src_h=%d\n", + osd_log_dbg2(MODULE_RENDER, + "plane_map:src_x=%d,src_y=%d,src_w=%d,src_h=%d\n", plane_map->src_x, plane_map->src_y, plane_map->src_w, plane_map->src_h); - osd_log_dbg2("fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d\n", + osd_log_dbg2(MODULE_RENDER, + "fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d\n", plane_map->dst_x, plane_map->dst_y, plane_map->dst_w, @@ -9309,22 +9708,15 @@ static void osd_cursor_move(struct osd_plane_map_s *plane_map) u32 phy_addr = plane_map->phy_addr; u32 x_start, x_end, y_start, y_end; u32 x, y; - void *vaddr = NULL; struct pandata_s disp_tmp; struct pandata_s free_dst_data_backup; if (index != OSD2) return; phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y; - vaddr = phys_to_virt(phy_addr); - osd_hw.screen_base[index] = vaddr; + osd_hw.screen_base[index] = phy_addr; osd_hw.screen_size[index] = plane_map->byte_stride * plane_map->src_h; - if (osd_hw.osd_clear[index]) { - if (vaddr) - memset(vaddr, 0x0, - plane_map->byte_stride*plane_map->src_h); - } canvas_config(osd_hw.fb_gem[index].canvas_idx, phy_addr, plane_map->byte_stride, @@ -9445,22 +9837,26 @@ static void osd_cursor_move(struct osd_plane_map_s *plane_map) osd_hw.dispdata[index].y_start = y_start; osd_hw.dispdata[index].y_end = y_end; } - osd_log_dbg2("plane_map:src_x=%d,src_y=%d,src_w=%d,src_h=%d\n", + osd_log_dbg2(MODULE_CURSOR, + "plane_map:src_x=%d,src_y=%d,src_w=%d,src_h=%d\n", plane_map->src_x, plane_map->src_y, plane_map->src_w, plane_map->src_h); - osd_log_dbg2("fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d\n", + osd_log_dbg2(MODULE_CURSOR, + "fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d\n", plane_map->dst_x, plane_map->dst_y, plane_map->dst_w, plane_map->dst_h); - osd_log_dbg2("cursor pandata x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_log_dbg2(MODULE_CURSOR, + "cursor pandata x=%d,x_end=%d,y=%d,y_end=%d\n", osd_hw.pandata[index].x_start, osd_hw.pandata[index].x_end, osd_hw.pandata[index].y_start, osd_hw.pandata[index].y_end); - osd_log_dbg2("cursor dispdata x=%d,x_end=%d,y=%d,y_end=%d\n", + osd_log_dbg2(MODULE_CURSOR, + "cursor dispdata x=%d,x_end=%d,y=%d,y_end=%d\n", osd_hw.dispdata[index].x_start, osd_hw.dispdata[index].x_end, osd_hw.dispdata[index].y_start, diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 4b2680fd288b..61c14dc12b84 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -123,11 +123,14 @@ extern int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request); extern int osd_sync_request_render(u32 index, u32 yres, struct sync_req_render_s *request, - u32 phys_addr); + u32 phys_addr, + size_t len); extern int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd); extern s64 osd_wait_vsync_event(void); extern void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w, u32 osd_h); +extern void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, + s16 ystart, u32 osd_w, u32 osd_h); extern void osd_init_scan_mode(void); extern void osd_suspend_hw(void); extern void osd_resume_hw(void); @@ -188,13 +191,16 @@ void osd_do_hwc(void); int osd_get_capbility(u32 index); void osd_backup_screen_info( u32 index, - char __iomem *screen_base, - u32 screen_size); -void osd_restore_screen_info( + unsigned long screen_base, + unsigned long screen_size); +void osd_get_screen_info( u32 index, char __iomem **screen_base, unsigned long *screen_size); -void osd_set_clear(u32 index, u32 osd_clear); +int get_vmap_addr(u32 index, u8 __iomem **buf); +ssize_t dd_vmap_write(u32 index, const char __user *buf, + size_t count, loff_t *ppos); +int osd_set_clear(u32 index); void osd_page_flip(struct osd_plane_map_s *plane_map); void walk_through_update_list(void); int osd_setting_blend(void); diff --git a/drivers/amlogic/media/osd/osd_io.c b/drivers/amlogic/media/osd/osd_io.c index 351937b761d5..c4dc7cf4979b 100644 --- a/drivers/amlogic/media/osd/osd_io.c +++ b/drivers/amlogic/media/osd/osd_io.c @@ -72,7 +72,7 @@ uint32_t osd_cbus_read(uint32_t reg) } else ret = (uint32_t)aml_read_cbus(reg); - osd_log_dbg3("%s(0x%x)=0x%x\n", __func__, reg, ret); + osd_log_dbg3(MODULE_BASE, "%s(0x%x)=0x%x\n", __func__, reg, ret); return ret; }; @@ -87,7 +87,7 @@ void osd_cbus_write(uint32_t reg, writel(val, osd_reg_map.vir_addr + addr); } else aml_write_cbus(reg, val); - osd_log_dbg3("%s(0x%x, 0x%x)\n", __func__, reg, val); + osd_log_dbg3(MODULE_BASE, "%s(0x%x, 0x%x)\n", __func__, reg, val); }; @@ -104,7 +104,7 @@ uint32_t osd_reg_read(uint32_t reg) } else ret = (uint32_t)aml_read_vcbus(reg); - osd_log_dbg3("%s(0x%x)=0x%x\n", __func__, reg, ret); + osd_log_dbg3(MODULE_BASE, "%s(0x%x)=0x%x\n", __func__, reg, ret); return ret; }; @@ -120,7 +120,7 @@ void osd_reg_write(uint32_t reg, } else aml_write_vcbus(reg, val); update_backup_reg(reg, val); - osd_log_dbg3("%s(0x%x, 0x%x)\n", __func__, reg, val); + osd_log_dbg3(MODULE_BASE, "%s(0x%x, 0x%x)\n", __func__, reg, val); }; void osd_reg_set_mask(uint32_t reg, diff --git a/drivers/amlogic/media/osd/osd_log.h b/drivers/amlogic/media/osd/osd_log.h index 003654c2e57e..d3412cac7852 100644 --- a/drivers/amlogic/media/osd/osd_log.h +++ b/drivers/amlogic/media/osd/osd_log.h @@ -26,7 +26,14 @@ #define OSD_LOG_LEVEL_DEBUG2 2 #define OSD_LOG_LEVEL_DEBUG3 3 +#define MODULE_BASE (1 << 0) +#define MODULE_RENDER (1 << 1) +#define MODULE_FENCE (1 << 2) +#define MODULE_BLEND (1 << 3) +#define MODULE_CURSOR (1 << 4) + extern unsigned int osd_log_level; +extern unsigned int osd_log_module; #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -37,25 +44,30 @@ extern unsigned int osd_log_level; #define osd_log_err(fmt, ...) \ pr_err(fmt, ##__VA_ARGS__) -#define osd_log_dbg(fmt, ...) \ +#define osd_log_dbg(moudle, fmt, ...) \ do { \ if (osd_log_level >= OSD_LOG_LEVEL_DEBUG) { \ - pr_info(fmt, ##__VA_ARGS__); \ + if (moudle & osd_log_module) { \ + pr_info(fmt, ##__VA_ARGS__); \ + } \ } \ } while (0) -#define osd_log_dbg2(fmt, ...) \ +#define osd_log_dbg2(moudle, fmt, ...) \ do { \ if (osd_log_level >= OSD_LOG_LEVEL_DEBUG2) { \ - pr_info(fmt, ##__VA_ARGS__); \ + if (moudle & osd_log_module) { \ + pr_info(fmt, ##__VA_ARGS__); \ + } \ } \ } while (0) -#define osd_log_dbg3(fmt, ...) \ +#define osd_log_dbg3(moudle, fmt, ...) \ do { \ if (osd_log_level >= OSD_LOG_LEVEL_DEBUG3) { \ - pr_info(fmt, ##__VA_ARGS__); \ + if (moudle & osd_log_module) { \ + pr_info(fmt, ##__VA_ARGS__); \ + } \ } \ } while (0) - #endif diff --git a/drivers/amlogic/media/osd/osd_rdma.c b/drivers/amlogic/media/osd/osd_rdma.c index 15b2043a579f..f1d08ca33e4a 100644 --- a/drivers/amlogic/media/osd/osd_rdma.c +++ b/drivers/amlogic/media/osd/osd_rdma.c @@ -405,6 +405,17 @@ static inline int wrtie_reg_internal(u32 addr, u32 val) /* TODO remove the Done write operation to save the time */ request_item.addr = OSD_RDMA_FLAG_REG; request_item.val = OSD_RDMA_STATUS_MARK_TBL_DONE; + /* afbc start before afbc reset will cause afbc decode error */ + if (addr == VIU_SW_RESET) { + int i = 0; + + for (i = 0; i < item_count; i++) { + if (rdma_table[i].addr == VPU_MAFBC_COMMAND) { + rdma_table[i].addr = VIU_OSD1_TEST_RDDATA; + rdma_table[i].val = 0x0; + } + } + } osd_rdma_mem_cpy( &rdma_table[item_count], &request_item, 8); diff --git a/drivers/amlogic/media/osd_ext/osd_fb.c b/drivers/amlogic/media/osd_ext/osd_fb.c index da16b2cae0fe..d6320c8d6c40 100644 --- a/drivers/amlogic/media/osd_ext/osd_fb.c +++ b/drivers/amlogic/media/osd_ext/osd_fb.c @@ -175,7 +175,7 @@ _find_color_format(struct fb_var_screeninfo *var) || (var->blue.length == 0) || var->bits_per_pixel != (var->red.length + var->green.length + var->blue.length + var->transp.length)) { - osd_log_dbg("not provide color length, use default color\n"); + osd_log_dbg(MODULE_BASE, "not provide color length, use default color\n"); found = &default_color_format_array[upper_margin]; } else { for (i = upper_margin; i >= lower_margin; i--) { @@ -216,7 +216,7 @@ static int osd_ext_check_var(struct fb_var_screeninfo *var, color_format_pt = _find_color_format(var); if (color_format_pt == NULL || color_format_pt->color_index == 0) return -EFAULT; - osd_log_dbg("select color format :index %d, bpp %d\n", + osd_log_dbg(MODULE_BASE, "select color format :index %d, bpp %d\n", color_format_pt->color_index, color_format_pt->bpp); fbdev->color = color_format_pt; @@ -233,7 +233,7 @@ static int osd_ext_check_var(struct fb_var_screeninfo *var, var->transp.length = color_format_pt->transp_length; var->transp.msb_right = color_format_pt->transp_msb_right; var->bits_per_pixel = color_format_pt->bpp; - osd_log_dbg("rgba(L/O):%d/%d-%d/%d-%d/%d-%d/%d\n", + osd_log_dbg(MODULE_BASE, "rgba(L/O):%d/%d-%d/%d-%d/%d-%d/%d\n", var->red.length, var->red.offset, var->green.length, var->green.offset, var->blue.length, var->blue.offset, @@ -431,7 +431,8 @@ static int osd_ext_ioctl(struct fb_info *info, unsigned int cmd, case COLOR_INDEX_24_888_B: case COLOR_INDEX_24_RGB: case COLOR_INDEX_YUV_422: - osd_log_dbg("set osd color key 0x%x\n", src_colorkey); + osd_log_dbg(MODULE_BASE, + "set osd color key 0x%x\n", src_colorkey); fbdev->color_key = src_colorkey; osd_ext_set_color_key_hw(info->node - 2, fbdev->color->color_index, src_colorkey); @@ -448,7 +449,7 @@ static int osd_ext_ioctl(struct fb_info *info, unsigned int cmd, case COLOR_INDEX_24_888_B: case COLOR_INDEX_24_RGB: case COLOR_INDEX_YUV_422: - osd_log_dbg("set osd color key %s\n", + osd_log_dbg(MODULE_BASE, "set osd color key %s\n", srckey_enable ? "enable" : "disable"); if (srckey_enable != 0) { fbdev->enable_key_flag |= KEYCOLOR_FLAG_TARGET; @@ -1408,7 +1409,8 @@ osd_ext_probe(struct platform_device *pdev) osd_log_err("not found mem_size from dt\n"); osd_ext_memory = 0; } else { - osd_log_dbg("mem_size: 0x%x, 0x%x\n", memsize[0], memsize[1]); + osd_log_dbg(MODULE_BASE, + "mem_size: 0x%x, 0x%x\n", memsize[0], memsize[1]); fb_rmem_size[0] = memsize[0]; fb_rmem_paddr[0] = fb_rmem.base; if ((OSD_COUNT == 2) && ((memsize[0] + memsize[1]) <= diff --git a/drivers/amlogic/media/osd_ext/osd_hw.c b/drivers/amlogic/media/osd_ext/osd_hw.c index e19e7bbabca1..0cc29a365076 100644 --- a/drivers/amlogic/media/osd_ext/osd_hw.c +++ b/drivers/amlogic/media/osd_ext/osd_hw.c @@ -285,8 +285,8 @@ static int out_ext_fence_create(int *release_fence_fd, u32 *val, u32 buf_num) } sync_fence_install(outer_fence, out_fence_fd); - osd_log_dbg("---------------------------------------\n"); - osd_log_dbg("return out fence fd:%d\n", out_fence_fd); + osd_log_dbg(MODULE_FENCE, "---------------------------------------\n"); + osd_log_dbg(MODULE_FENCE, "return out fence fd:%d\n", out_fence_fd); *release_fence_fd = out_fence_fd; return out_fence_fd; @@ -1229,7 +1229,7 @@ void osd_ext_pan_display_fence(struct osd_fence_map_s *fence_map) ret = osd_ext_wait_buf_ready(fence_map); if (ret < 0) - osd_log_dbg("fence wait ret %d\n", ret); + osd_log_dbg(MODULE_FENCE, "fence wait ret %d\n", ret); } if (ret) { @@ -1254,7 +1254,7 @@ void osd_ext_pan_display_fence(struct osd_fence_map_s *fence_map) osd_log_err("------NOT signal out_fence ERROR\n"); } - osd_log_dbg("offset[%d-%d]x[%d-%d]y[%d-%d]\n", + osd_log_dbg(MODULE_FENCE, "offset[%d-%d]x[%d-%d]y[%d-%d]\n", xoffset, yoffset, osd_ext_hw.pandata[index].x_start, osd_ext_hw.pandata[index].x_end, osd_ext_hw.pandata[index].y_start, diff --git a/drivers/amlogic/media/video_processor/pic_dev/picdec.c b/drivers/amlogic/media/video_processor/pic_dev/picdec.c index e96758fdb05c..7d28ea390ed1 100644 --- a/drivers/amlogic/media/video_processor/pic_dev/picdec.c +++ b/drivers/amlogic/media/video_processor/pic_dev/picdec.c @@ -60,6 +60,7 @@ static int dump_file_flag; static int p2p_mode = 2; static int output_format_mode = 1; static int txlx_output_format_mode = 1; +static int cma_layout_flag = 1; #define NO_TASK_MODE @@ -339,8 +340,10 @@ static int render_frame(struct ge2d_context_s *context, new_vf->index = index; new_vf->pts = 0; new_vf->pts_us64 = 0; + /* new_vf->ratio_control = DISP_RATIO_FORCECONFIG | DISP_RATIO_FORCE_NORMALWIDE; + */ new_vf->ratio_control = 0; vfbuf_use[index]++; picdec_fill_buffer(new_vf, context, ge2d_config); @@ -540,7 +543,7 @@ static int picdec_start(void) if (picdec_device.use_reserved) { picdec_device.mapping = io_mapping_create_wc(map_start, map_size); - if (picdec_device.mapping <= 0) { + if (picdec_device.mapping == NULL) { aml_pr_info(1, "mapping failed!!!!!!!!!!!!\n"); return -1; } @@ -548,7 +551,8 @@ static int picdec_start(void) map_start, picdec_device.mapping, map_size); } else{ picdec_device.mapping = NULL; - picdec_device.vir_addr = phys_to_virt(map_start); + if (!cma_layout_flag) + picdec_device.vir_addr = phys_to_virt(map_start); } vf_provider_init(&picdec_vf_prov, PROVIDER_NAME, &picdec_vf_provider, NULL); @@ -761,6 +765,24 @@ int fill_black_color_by_ge2d(struct vframe_s *vf, return 0; } +static int picdec_memset_phyaddr(ulong phys, u32 size, u32 val) +{ + u32 i, span = SZ_1M; + u32 count = size / PAGE_ALIGN(span); + ulong addr = phys; + u8 *p; + + for (i = 0; i < count; i++) { + addr = phys + i * span; + p = codec_mm_vmap(addr, span); + if (!p) + return -1; + memset(p, val, span); + codec_mm_unmap_phyaddr(p); + } + return 0; +} + int fill_color(struct vframe_s *vf, struct ge2d_context_s *context, struct config_para_ex_s *ge2d_config) { @@ -795,10 +817,17 @@ int fill_color(struct vframe_s *vf, struct ge2d_context_s *context, if (ret < 0) pr_err("fill black color by ge2d failed\n"); } else { - p = phys_to_virt(cs0.addr); - memset(p, 0, cs0.width * cs0.height); - p = phys_to_virt(cs1.addr); - memset(p, 0x80, cs1.width * cs1.height); + if (!cma_layout_flag) { + p = phys_to_virt(cs0.addr); + memset(p, 0, cs0.width * cs0.height); + p = phys_to_virt(cs1.addr); + memset(p, 0x80, cs1.width * cs1.height); + } else { + picdec_memset_phyaddr(cs0.addr, + (cs0.width * cs0.height), 0); + picdec_memset_phyaddr(cs1.addr, + (cs1.width * cs1.height), 0x80); + } } } do_gettimeofday(&end); @@ -845,6 +874,27 @@ static void rotate_adjust(int w_in, int h_in, int *w_out, int *h_out, int angle) *h_out = h; } +static int copy_phybuf_to_file(ulong phys, u32 size, + struct file *fp, loff_t pos) +{ + u32 i, span = SZ_1M; + u32 count = size / PAGE_ALIGN(span); + ulong addr = phys; + u8 *p; + + for (i = 0; i < count; i++) { + addr = phys + i * span; + p = codec_mm_vmap(addr, span); + if (!p) + return -1; + vfs_write(fp, (char *)p, + span, &pos); + pos += span; + codec_mm_unmap_phyaddr(p); + } + return 0; +} + int picdec_fill_buffer(struct vframe_s *vf, struct ge2d_context_s *context, struct config_para_ex_s *ge2d_config) { @@ -857,6 +907,7 @@ int picdec_fill_buffer(struct vframe_s *vf, struct ge2d_context_s *context, int dst_top, dst_left, dst_width, dst_height; struct file *filp = NULL; loff_t pos = 0; + int ret = 0; void __iomem *p; mm_segment_t old_fs = get_fs(); @@ -865,9 +916,14 @@ int picdec_fill_buffer(struct vframe_s *vf, struct ge2d_context_s *context, (ulong)(picdec_device.assit_buf_start), canvas_width * 3, canvas_height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); - aml_pr_info(1, "picdec_pre_process start\n"); - picdec_pre_process(); - aml_pr_info(1, "picdec_pre_process finish\n"); + if (!cma_layout_flag) { + aml_pr_info(1, "picdec_pre_process start\n"); + picdec_pre_process(); + aml_pr_info(1, "picdec_pre_process finish\n"); + } else { + dma_flush(picdec_device.assit_buf_start, + (canvas_width * picdec_device.origin_height * 3)); + } ge2d_config->alu_const_color = 0; /* 0x000000ff; */ ge2d_config->bitmask_en = 0; ge2d_config->src1_gb_alpha = 0; /* 0xff; */ @@ -998,9 +1054,17 @@ int picdec_fill_buffer(struct vframe_s *vf, struct ge2d_context_s *context, if (IS_ERR(filp)) { aml_pr_info(0, "open file failed\n"); } else { - p = phys_to_virt(cs0.addr); - vfs_write(filp, (char *)p, - cs0.width * cs0.height, &pos); + if (!cma_layout_flag) { + p = phys_to_virt(cs0.addr); + vfs_write(filp, (char *)p, + cs0.width * cs0.height, &pos); + } else { + ret = copy_phybuf_to_file(cs0.addr, + cs0.width * cs0.height, + filp, 0); + if (ret < 0) + pr_err("write yuv444 file failed.\n"); + } vfs_fsync(filp, 0); filp_close(filp, NULL); set_fs(old_fs); @@ -1012,13 +1076,29 @@ int picdec_fill_buffer(struct vframe_s *vf, struct ge2d_context_s *context, if (IS_ERR(filp)) { aml_pr_info(0, "open file failed\n"); } else { - p = phys_to_virt(cs0.addr); - vfs_write(filp, (char *)p, - cs0.width * cs0.height, &pos); - pos = cs0.width * cs0.height; - p = phys_to_virt(cs1.addr); - vfs_write(filp, (char *)p, - cs1.width * cs1.height, &pos); + if (!cma_layout_flag) { + p = phys_to_virt(cs0.addr); + vfs_write(filp, (char *)p, + cs0.width * cs0.height, &pos); + } else { + ret = copy_phybuf_to_file(cs0.addr, + cs0.width * cs0.height, + filp, 0); + if (ret < 0) + pr_err("write NV21 Y to file failed\n"); + } + pos = (loff_t)cs0.width * cs0.height; + if (!cma_layout_flag) { + p = phys_to_virt(cs1.addr); + vfs_write(filp, (char *)p, + cs1.width * cs1.height, &pos); + } else { + ret = copy_phybuf_to_file(cs1.addr, + cs1.width * cs1.height, + filp, pos); + if (ret < 0) + pr_err("write NV21 UV to file failed\n"); + } vfs_fsync(filp, 0); filp_close(filp, NULL); set_fs(old_fs); @@ -1109,7 +1189,7 @@ int picdec_cma_buf_init(void) picdec_device.cma_pages); picdec_device.buffer_size = (72*SZ_1M); } else{ - flags = CODEC_MM_FLAGS_DMA_CPU | + flags = CODEC_MM_FLAGS_DMA | CODEC_MM_FLAGS_CMA_CLEAR; picdec_device.buffer_start = codec_mm_alloc_for_dma("picdec", @@ -1126,7 +1206,7 @@ int picdec_cma_buf_init(void) picdec_device.cma_pages); picdec_device.buffer_size = (48*SZ_1M); } else{ - flags = CODEC_MM_FLAGS_DMA_CPU | + flags = CODEC_MM_FLAGS_DMA | CODEC_MM_FLAGS_CMA_CLEAR; picdec_device.buffer_start = codec_mm_alloc_for_dma("picdec", @@ -1267,6 +1347,7 @@ int picdec_buffer_init(void) vfbuf_use[i] = 0; } } + if (picdec_device.output_format_mode) picdec_device.assit_buf_start = buf_start + canvas_width * canvas_height * 6; @@ -1364,24 +1445,82 @@ void get_picdec_buf_info(resource_size_t *start, unsigned int *size, static int picdec_open(struct inode *inode, struct file *file) { - struct ge2d_context_s *context = NULL; int ret = 0; + if (!cma_layout_flag) { + struct ge2d_context_s *context = NULL; - aml_pr_info(1, "open one picdec device\n"); - file->private_data = context; - picdec_device.open_count++; - ret = picdec_start(); + aml_pr_info(1, "open one picdec device\n"); + file->private_data = context; + picdec_device.open_count++; + ret = picdec_start(); + } else { + struct picdec_private_s *priv; + + aml_pr_info(1, "open one picdec device\n"); + priv = kmalloc(sizeof(struct picdec_private_s), GFP_KERNEL); + if (!priv) { + pr_err("alloc memory failed for amvideo cap\n"); + return -ENOMEM; + } + memset(priv, 0, sizeof(struct picdec_private_s)); + picdec_device.open_count++; + ret = picdec_start(); + priv->context = NULL; + priv->phyaddr = (unsigned long)picdec_device.assit_buf_start; + priv->buf_len = (picdec_device.buffer_size/3); + file->private_data = priv; + } return ret; } +static int picdec_mmap(struct file *file, + struct vm_area_struct *vma) +{ + struct picdec_private_s *priv = file->private_data; + unsigned long off = vma->vm_pgoff << PAGE_SHIFT; + unsigned int vm_size = vma->vm_end - vma->vm_start; + + if (!priv->phyaddr) + return -EIO; + + aml_pr_info(1, "priv->phyaddr = %lx , vm_size = %d\n", + priv->phyaddr, vm_size); + + if (vm_size == 0) + return -EAGAIN; + + off += priv->phyaddr; + + if ((off + vm_size) > (priv->phyaddr + priv->buf_len)) + return -ENOMEM; + + /*vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);*/ + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO; + + if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + pr_err("set_cached: failed remap_pfn_range\n"); + return -EAGAIN; + } + aml_pr_info(1, "picdec_mmap ok\n"); + return 0; +} + static long picdec_ioctl(struct file *filp, unsigned int cmd, unsigned long args) { int ret = 0; - struct ge2d_context_s *context; void __user *argp; + struct ge2d_context_s *context; + struct picdec_private_s *priv; - context = (struct ge2d_context_s *) filp->private_data; + if (!cma_layout_flag) { + context = (struct ge2d_context_s *) filp->private_data; + } else { + priv = filp->private_data; + context = (struct ge2d_context_s *) priv->context; + } argp = (void __user *)args; switch (cmd) { #ifdef CONFIG_COMPAT @@ -1445,8 +1584,13 @@ static long picdec_compat_ioctl(struct file *filp, static int picdec_release(struct inode *inode, struct file *file) { - struct ge2d_context_s *context = - (struct ge2d_context_s *) file->private_data; + struct ge2d_context_s *context; + struct picdec_private_s *priv = file->private_data; + + if (!cma_layout_flag) + context = (struct ge2d_context_s *) file->private_data; + else + context = (struct ge2d_context_s *) priv->context; aml_pr_info(1, "picdec stop start"); picdec_stop(); @@ -1454,6 +1598,10 @@ static int picdec_release(struct inode *inode, struct file *file) picdec_device.open_count--; return 0; } + if (cma_layout_flag) { + kfree(priv); + priv = NULL; + } aml_pr_info(0, "release one picdec device\n"); return -1; } @@ -1472,6 +1620,7 @@ static long picdec_compat_ioctl(struct file *filp, unsigned int cmd, static const struct file_operations picdec_fops = { .owner = THIS_MODULE, .open = picdec_open, + .mmap = picdec_mmap, .unlocked_ioctl = picdec_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = picdec_compat_ioctl, @@ -1501,7 +1650,7 @@ static int parse_para(const char *para, int para_num, int *result) token++; len--; } - if (len == 0) + if ((len == 0) || (!token)) break; ret = kstrtoint(token, 0, &res); if (ret < 0) @@ -1528,8 +1677,10 @@ static ssize_t frame_render_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ int parsed[4]; if (likely(parse_para(buf, 4, parsed) == 4)) { @@ -1549,7 +1700,7 @@ static ssize_t frame_render_write(struct class *cla, #else up(&pic_vb_start_sema); #endif - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -1592,8 +1743,10 @@ static ssize_t test_color_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ int parsed[3]; if (likely(parse_para(buf, 3, parsed) == 3)) { @@ -1602,7 +1755,7 @@ static ssize_t test_color_write(struct class *cla, test_b = parsed[2]; } else return count; - size = endp - buf; + /*size = endp - buf;*/ return count; } @@ -1823,6 +1976,9 @@ MODULE_PARM_DESC(output_format_mode, "\n picdec output fomat mode\n"); module_param(txlx_output_format_mode, uint, 0664); MODULE_PARM_DESC(txlx_output_format_mode, "\n txlx picdec output fomat mode\n"); +module_param(cma_layout_flag, uint, 0664); +MODULE_PARM_DESC(cma_layout_flag, "\n cma layout change flag\n"); + MODULE_DESCRIPTION("Amlogic picture decoder driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Simon Zheng "); diff --git a/drivers/amlogic/media/video_processor/pic_dev/picdec.h b/drivers/amlogic/media/video_processor/pic_dev/picdec.h index b619d37d30b8..1f058bf8e213 100644 --- a/drivers/amlogic/media/video_processor/pic_dev/picdec.h +++ b/drivers/amlogic/media/video_processor/pic_dev/picdec.h @@ -97,6 +97,12 @@ struct compat_source_input_s) #endif +struct picdec_private_s { + struct ge2d_context_s *context; + unsigned long phyaddr; + unsigned int buf_len; +}; + #define PICDEC_IOC_MAGIC 'P' #define PICDEC_IOC_FRAME_RENDER _IOW(PICDEC_IOC_MAGIC, 0x00, \ struct source_input_s) diff --git a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c index f47aafe0d046..d33d14898795 100644 --- a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c +++ b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_drv.c @@ -239,44 +239,41 @@ static ssize_t _ppmgr_angle_write(unsigned long val) #define PPMGR_CLASS_NAME "ppmgr" static int parse_para(const char *para, int para_num, int *result) { - char *endp = NULL; - const char *startp = para; + char *token = NULL; + char *params, *params_base; int *out = result; int len = 0, count = 0; - long tmp; - int ret; + int res = 0; + int ret = 0; - if (!startp) + if (!para) return 0; - len = strlen(startp); - + params = kstrdup(para, GFP_KERNEL); + params_base = params; + token = params; + len = strlen(token); do { - /*filter space out*/ - while (startp && (isspace(*startp) || !isgraph(*startp)) - && len) { - startp++; + token = strsep(¶ms, " "); + while (token && (isspace(*token) + || !isgraph(*token)) && len) { + token++; len--; } - - if (len == 0) + if ((len == 0) || (!token)) + break; + ret = kstrtoint(token, 0, &res); + if (ret < 0) { + PPMGRDRV_ERR("ERR convert %s to long int!\n", token); break; - - /* *out++ = simple_strtol(startp, &endp, 0); */ - - ret = kstrtol(startp, 0, &tmp); - if (ret != 0) { - PPMGRDRV_ERR("ERR convert %s to long int!\n", startp); - return ret; } - *out++ = tmp; - len -= endp - startp; - startp = endp; + len = strlen(token); + *out++ = res; count++; + } while ((token) && (count < para_num) && (len > 0)); - } while ((endp) && (count < para_num) && (len > 0)); - + kfree(params_base); return count; } @@ -304,10 +301,12 @@ static ssize_t angle_read(struct class *cla, struct class_attribute *attr, static ssize_t angle_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; - /* unsigned long angle = simple_strtoul(buf, &endp, 0); */ - unsigned long angle; + unsigned long angle = simple_strtoul(buf, &endp, 0); + */ + long angle; int ret = kstrtoul(buf, 0, &angle); if (ret != 0) { @@ -315,14 +314,14 @@ static ssize_t angle_write(struct class *cla, struct class_attribute *attr, return ret; } if (angle > 3 || angle < 0) { - size = endp - buf; + /* size = endp - buf; */ return count; } if (_ppmgr_angle_write(angle) < 0) return -EINVAL; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -368,8 +367,8 @@ static ssize_t orientation_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { - ssize_t ret = -EINVAL, size; - char *endp; + ssize_t ret = -EINVAL; /* , size; */ + /* char *endp; */ unsigned long tmp; /* unsigned angle = simple_strtoul(buf, &endp, 0); */ unsigned int angle; @@ -403,7 +402,7 @@ static ssize_t orientation_write(struct class *cla, PPMGRDRV_INFO("angle:%d,orientation:%d,videoangle:%d\n", ppmgr_device.angle, ppmgr_device.orientation, ppmgr_device.videoangle); - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -417,8 +416,10 @@ static ssize_t bypass_read(struct class *cla, struct class_attribute *attr, static ssize_t bypass_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ long tmp; /* ppmgr_device.bypass = simple_strtoul(buf, &endp, 0); */ @@ -429,7 +430,7 @@ static ssize_t bypass_write(struct class *cla, struct class_attribute *attr, return ret; } ppmgr_device.bypass = tmp; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -539,8 +540,10 @@ static ssize_t ppscaler_read(struct class *cla, struct class_attribute *attr, static ssize_t ppscaler_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ long tmp; /* int flag simple_strtoul(buf, &endp, 0); */ int flag; @@ -560,7 +563,7 @@ static ssize_t ppscaler_write(struct class *cla, struct class_attribute *attr, if (ppmgr_device.ppscaler_flag == 0) set_scaler_pos_reset(true); } - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -617,8 +620,10 @@ static ssize_t receiver_read(struct class *cla, struct class_attribute *attr, static ssize_t receiver_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ long tmp; int ret; @@ -636,7 +641,7 @@ static ssize_t receiver_write(struct class *cla, struct class_attribute *attr, } ppmgr_device.receiver = tmp; vf_ppmgr_reset(0); - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -657,8 +662,10 @@ static ssize_t platform_type_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ long tmp; /* platform_type = simple_strtoul(buf, &endp, 0); */ int ret = kstrtoul(buf, 0, &tmp); @@ -668,7 +675,7 @@ static ssize_t platform_type_write(struct class *cla, return ret; } platform_type = tmp; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -685,8 +692,10 @@ static ssize_t tb_detect_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ unsigned long tmp; int ret = kstrtoul(buf, 0, &tmp); @@ -695,7 +704,7 @@ static ssize_t tb_detect_write(struct class *cla, return ret; } ppmgr_device.tb_detect = tmp; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -712,8 +721,10 @@ static ssize_t tb_detect_period_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ unsigned long tmp; /* platform_type = simple_strtoul(buf, &endp, 0); */ int ret = kstrtoul(buf, 0, &tmp); @@ -723,7 +734,7 @@ static ssize_t tb_detect_period_write(struct class *cla, return ret; } ppmgr_device.tb_detect_period = tmp; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -740,8 +751,10 @@ static ssize_t tb_detect_len_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ unsigned long tmp; /* platform_type = simple_strtoul(buf, &endp, 0); */ int ret = kstrtoul(buf, 0, &tmp); @@ -756,7 +769,7 @@ static ssize_t tb_detect_len_write(struct class *cla, tmp = 6; } ppmgr_device.tb_detect_buf_len = tmp; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -773,8 +786,10 @@ static ssize_t tb_detect_mute_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ unsigned long tmp; /* platform_type = simple_strtoul(buf, &endp, 0); */ int ret = kstrtoul(buf, 0, &tmp); @@ -787,7 +802,7 @@ static ssize_t tb_detect_mute_write(struct class *cla, PPMGRDRV_INFO( "tb detect init mute is %ld\n", tmp); ppmgr_device.tb_detect_init_mute = tmp; - size = endp - buf; + /* size = endp - buf; */ return count; } @@ -1185,8 +1200,10 @@ static ssize_t mirror_read(struct class *cla, struct class_attribute *attr, static ssize_t mirror_write(struct class *cla, struct class_attribute *attr, const char *buf, size_t count) { + /* ssize_t size; char *endp; + */ long tmp; int ret = kstrtol(buf, 0, &tmp); /* ppmgr_device.mirror_flag = simple_strtoul(buf, &endp, 0); */ @@ -1197,7 +1214,7 @@ static ssize_t mirror_write(struct class *cla, struct class_attribute *attr, ppmgr_device.mirror_flag = tmp; if (ppmgr_device.mirror_flag > 2) ppmgr_device.mirror_flag = 0; - size = endp - buf; + /* size = endp - buf; */ return count; } diff --git a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c index 4f7e0665273f..d9560b43fd9e 100644 --- a/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c +++ b/drivers/amlogic/media/video_processor/ppmgr/ppmgr_vpp.c @@ -169,6 +169,7 @@ static u8 tb_detect_last_flag; static u32 tb_buff_wptr; static u32 tb_buff_rptr; static s32 tb_canvas = -1; +static u32 tb_src_canvas; static s8 tb_buffer_status; static u32 tb_buffer_start; static u32 tb_buffer_size; @@ -387,9 +388,11 @@ static int get_input_format(struct vframe_s *vf) static void dma_flush(u32 buf_start, u32 buf_size) { return; + /* dma_sync_single_for_device( &ppmgr_device.pdev->dev, buf_start, buf_size, DMA_TO_DEVICE); + */ } /* extern int get_property_change(void); */ @@ -841,6 +844,7 @@ static int process_vf_tb_detect(struct vframe_s *vf, { struct canvas_s cs0, cs1, cs2, cd; int interlace_mode; + struct vframe_s src_vf; u32 format = GE2D_FORMAT_M24_YUV420; u32 h_scale_coef_type = context->config.h_scale_coef_type; @@ -887,9 +891,35 @@ static int process_vf_tb_detect(struct vframe_s *vf, ge2d_config->src1_gb_alpha = 0;/* 0xff; */ ge2d_config->dst_xy_swap = 0; - canvas_read(vf->canvas0Addr & 0xff, &cs0); - canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1); - canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2); + src_vf = *vf; + if (vf->canvas0Addr == (u32)-1) { + canvas_config_config( + tb_src_canvas & 0xff, + &src_vf.canvas0_config[0]); + canvas_config_config( + (tb_src_canvas >> 8) & 0xff, + &src_vf.canvas0_config[1]); + if (src_vf.plane_num == 2) { + src_vf.canvas0Addr = + tb_src_canvas & 0xffff; + } else if (src_vf.plane_num == 3) { + canvas_config_config( + (tb_src_canvas >> 16) & 0xff, + &src_vf.canvas0_config[2]); + src_vf.canvas0Addr = + tb_src_canvas & 0xffffff; + } + canvas_read( + src_vf.canvas0Addr & 0xff, &cs0); + canvas_read( + (src_vf.canvas0Addr >> 8) & 0xff, &cs1); + canvas_read( + (src_vf.canvas0Addr >> 16) & 0xff, &cs2); + } else { + canvas_read(vf->canvas0Addr & 0xff, &cs0); + canvas_read((vf->canvas0Addr >> 8) & 0xff, &cs1); + canvas_read((vf->canvas0Addr >> 16) & 0xff, &cs2); + } ge2d_config->src_planes[0].addr = cs0.addr; ge2d_config->src_planes[0].w = cs0.width; ge2d_config->src_planes[0].h = cs0.height; @@ -906,7 +936,7 @@ static int process_vf_tb_detect(struct vframe_s *vf, ge2d_config->src_key.key_enable = 0; ge2d_config->src_key.key_mask = 0; ge2d_config->src_key.key_mode = 0; - ge2d_config->src_para.canvas_index = vf->canvas0Addr; + ge2d_config->src_para.canvas_index = src_vf.canvas0Addr; ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID; ge2d_config->src_para.format = format; ge2d_config->src_para.fill_color_en = 0; @@ -3601,9 +3631,23 @@ static int tb_buffer_init(void) if (tb_buffer_status) return tb_buffer_status; + if (tb_src_canvas == 0) { + if (canvas_pool_alloc_canvas_table( + "tb_detect_src", + &tb_src_canvas, 1, + CANVAS_MAP_TYPE_YUV)) { + pr_err( + "%s alloc tb src canvas error.\n", + __func__); + return -1; + } + pr_info("alloc tb src canvas 0x%x.\n", + tb_src_canvas); + } + if (tb_canvas < 0) tb_canvas = - canvas_pool_map_alloc_canvas("tb_detect"); + canvas_pool_map_alloc_canvas("tb_detect_dst"); if (tb_canvas < 0) return -1; @@ -3647,6 +3691,19 @@ static int tb_buffer_init(void) static int tb_buffer_uninit(void) { + if (tb_src_canvas) { + if (tb_src_canvas & 0xff) + canvas_pool_map_free_canvas( + tb_src_canvas & 0xff); + if ((tb_src_canvas >> 8) & 0xff) + canvas_pool_map_free_canvas( + (tb_src_canvas >> 8) & 0xff); + if ((tb_src_canvas >> 16) & 0xff) + canvas_pool_map_free_canvas( + (tb_src_canvas >> 16) & 0xff); + } + tb_src_canvas = 0; + if (tb_canvas >= 0) canvas_pool_map_free_canvas(tb_canvas); tb_canvas = -1; diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 08b1fca43bf3..0ce1e76116b6 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -88,6 +88,9 @@ MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC); #include "../common/vfm/vfm.h" #include +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND +#include +#endif static u32 osd_vpp_misc; static u32 osd_vpp_misc_mask; static bool update_osd_vpp_misc; @@ -123,8 +126,12 @@ static u32 omx_pts; static u32 omx_pts_set_index; static bool omx_run; static u32 omx_version = 3; +#define OMX_PTS_DV_DEFAULT_UPPER 2500 +#define OMX_PTS_DV_DEFAULT_LOWER -1600 static int omx_pts_interval_upper = 11000; static int omx_pts_interval_lower = -5500; +static int omx_pts_dv_upper = OMX_PTS_DV_DEFAULT_UPPER; +static int omx_pts_dv_lower = OMX_PTS_DV_DEFAULT_LOWER; static int omx_pts_set_from_hwc_count; static bool omx_check_previous_session; static u32 omx_cur_session = 0xffffffff; @@ -136,6 +143,7 @@ static int omx_need_drop_frame_num; static bool omx_drop_done; static bool video_start_post; static bool videopeek; +static bool nopostvideostart; /*----omx_info bit0: keep_last_frame, bit1~31: unused----*/ static u32 omx_info = 0x1; @@ -580,6 +588,7 @@ static int pts_pattern_enter_cnt[3] = {0, 0, 0}; static int pts_pattern_exit_cnt[3] = {0, 0, 0}; static int pts_log_enable[3] = {0, 0, 0}; static int pre_pts_trace; +static int pts_escape_vsync = -1; #define PTS_41_PATTERN_SINK_MAX 4 static int pts_41_pattern_sink[PTS_41_PATTERN_SINK_MAX]; @@ -945,6 +954,8 @@ static u32 force_blackout; static u32 disable_video = VIDEO_DISABLE_NONE; static u32 video_enabled __nosavedata; static u32 video_status_saved __nosavedata; +static u32 hold_video; + u32 get_video_enabled(void) { return video_enabled; @@ -999,6 +1010,11 @@ static u32 vsync_pts_112; static u32 vsync_pts_101; static u32 vsync_pts_100; static u32 vsync_freerun; +/* extend this value to support both slow and fast playback + * 0,1: normal playback + * [2,1000]: speed/vsync_slow_factor + * >1000: speed*(vsync_slow_factor/1000000) + */ static u32 vsync_slow_factor = 1; /* pts alignment */ @@ -1014,6 +1030,8 @@ static u32 toggle_count; static u32 last_frame_time; static u32 timer_count; static u32 vsync_count; +static u64 last_frame_duration; + static struct vpp_frame_par_s *cur_frame_par, *next_frame_par; static struct vpp_frame_par_s frame_parms[2]; @@ -1381,7 +1399,16 @@ static void vpp_settings_h(struct vpp_frame_par_s *framePtr) ((framePtr->VPP_hsc_endp & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT)); } else{ - + if (!legacy_vpp) { + x_lines = (zoom_end_x_lines - + zoom_start_x_lines + 1) + / (framePtr->hscale_skip_count + 1); + VSYNC_WR_MPEG_REG( + VPP_PREBLEND_VD1_H_START_END, + ((0 & VPP_VD_SIZE_MASK) << + VPP_VD1_START_BIT) | (((x_lines - 1) & + VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT)); + } VSYNC_WR_MPEG_REG(VPP_POSTBLEND_VD1_H_START_END + cur_dev->vpp_off, ((framePtr->VPP_hsc_startp & VPP_VD_SIZE_MASK) @@ -2458,6 +2485,10 @@ static void vsync_toggle_frame(struct vframe_s *vf) #endif #ifdef PTS_LOGGING + if (pts_escape_vsync == 1) { + pts_trace++; + pts_escape_vsync = 0; + } vsync_video_pattern(); pre_pts_trace = pts_trace; #endif @@ -2472,8 +2503,18 @@ static void vsync_toggle_frame(struct vframe_s *vf) ori_start_y_lines = 0; ori_end_y_lines = ((vf->type & VIDTYPE_COMPRESS) ? vf->compHeight : vf->height) - 1; - if (debug_flag & DEBUG_FLAG_PRINT_TOGGLE_FRAME) - pr_info("%s()\n", __func__); + if (debug_flag & DEBUG_FLAG_PRINT_TOGGLE_FRAME) { + u32 pcr = timestamp_pcrscr_get(); + u32 vpts = timestamp_vpts_get(); + u32 apts = timestamp_apts_get(); + + pr_info("%s pts:%d.%06d pcr:%d.%06d vpts:%d.%06d apts:%d.%06d\n", + __func__, (vf->pts) / 90000, + ((vf->pts) % 90000) * 1000 / 90, (pcr) / 90000, + ((pcr) % 90000) * 1000 / 90, (vpts) / 90000, + ((vpts) % 90000) * 1000 / 90, (apts) / 90000, + ((apts) % 90000) * 1000 / 90); + } if (trickmode_i || trickmode_fffb) trickmode_duration_count = trickmode_duration; @@ -2503,6 +2544,42 @@ static void vsync_toggle_frame(struct vframe_s *vf) "Video: invalid frame dimension\n"); return; } + + if (hold_video) { + if ((cur_dispbuf != vf) + && (vf->source_type != VFRAME_SOURCE_TYPE_OSD)) { + new_frame_count++; + if (vf->pts != 0) { + amlog_mask(LOG_MASK_TIMESTAMP, + "vpts to: 0x%x, scr: 0x%x, abs_scr: 0x%x\n", + vf->pts, timestamp_pcrscr_get(), + READ_MPEG_REG(SCR_HIU)); + + timestamp_vpts_set(vf->pts); + last_frame_duration = vf->duration; + } else if (last_frame_duration) { + amlog_mask(LOG_MASK_TIMESTAMP, + "vpts inc: 0x%x, scr: 0x%x, abs_scr: 0x%x\n", + timestamp_vpts_get() + + DUR2PTS(cur_dispbuf->duration), + timestamp_pcrscr_get(), + READ_MPEG_REG(SCR_HIU)); + + timestamp_vpts_inc(DUR2PTS + (last_frame_duration)); + + vpts_remainder += + DUR2PTS_RM(last_frame_duration); + if (vpts_remainder >= 0xf) { + vpts_remainder -= 0xf; + timestamp_vpts_inc(-1); + } + } + video_vf_put(vf); + return; + } + } + if ((cur_dispbuf) && (cur_dispbuf != &vf_local) && (cur_dispbuf != vf) && (video_property_changed != 2)) { if (cur_dispbuf->source_type == VFRAME_SOURCE_TYPE_OSD) { @@ -2932,8 +3009,9 @@ static void vsync_toggle_frame(struct vframe_s *vf) #endif if ((abs(timestamp_pcrscr_get() - vf->pts) <= (vsync_pts_inc)) && ((int)(timestamp_pcrscr_get() - vf->pts) >= 0)) { - vsync_pts_align = vsync_pts_inc / 4 - - (timestamp_pcrscr_get() - vf->pts); + /*vsync_pts_align = vsync_pts_inc / 4 - */ + /* (timestamp_pcrscr_get() - vf->pts);*/ + vsync_pts_align = 0; vsync_pts_aligned = true; #ifdef PTS_TRACE_DEBUG pts_trace_his_rd = 0; @@ -4095,6 +4173,10 @@ static inline bool duration_expire(struct vframe_s *cur_vf, static s32 rpt_tab_idx; static const u32 rpt_tab[4] = { 0x100, 0x100, 0x300, 0x300 }; + /* do not switch to new frames in none-normal speed */ + if (vsync_slow_factor > 1000) + return false; + if ((cur_vf == NULL) || (cur_dispbuf == &vf_local)) return true; @@ -4159,35 +4241,54 @@ static inline void vpts_perform_pulldown(struct vframe_s *next_vf, if (*expired) { if (pts_trace < expected_curr_interval) { - /* 232323...223 -> 232323...232 */ + /* 2323232323..2233..2323, prev=2, curr=3,*/ + /* check if next frame will toggle after 3 vsyncs */ + /* 22222...22222 -> 222..2213(2)22...22 */ /* check if next frame will toggle after 3 vsyncs */ int nextPts = timestamp_pcrscr_get() + vsync_pts_align; - if (((int)(nextPts + expected_prev_interval * - vsync_pts_inc - next_vf->next_vf_pts) < 0) && - ((int)(nextPts + expected_curr_interval * + if (/*((int)(nextPts + expected_prev_interval * */ + /*vsync_pts_inc - next_vf->next_vf_pts) < 0) && */ + ((int)(nextPts + (expected_prev_interval + 1) * vsync_pts_inc - next_vf->next_vf_pts) >= 0)) { *expired = false; - if (pts_log_enable[PTS_32_PATTERN]) + if (pts_log_enable[PTS_32_PATTERN] + || pts_log_enable[PTS_22_PATTERN]) pr_info("hold frame for pattern: %d", pts_pattern_detected); } + + /* here need to escape a vsync */ + if (timestamp_pcrscr_get() > + (next_vf->pts + vsync_pts_inc)) { + *expired = true; + pts_escape_vsync = 1; + if (pts_log_enable[PTS_32_PATTERN] + || pts_log_enable[PTS_22_PATTERN]) + pr_info("escape a vsync pattern: %d", + pts_pattern_detected); + } } } else { if (pts_trace == expected_curr_interval) { - /* 232323...332 -> 232323...323 */ + /* 23232323..233223...2323 curr=2, prev=3 */ + /* check if this frame will expire next vsyncs and */ + /* next frame will expire after 3 vsyncs */ + /* 22222...22222 -> 222..223122...22 */ /* check if this frame will expire next vsyncs and */ /* next frame will expire after 2 vsyncs */ int nextPts = timestamp_pcrscr_get() + vsync_pts_align; if (((int)(nextPts + vsync_pts_inc - next_vf->pts) >= 0) && - ((int)(nextPts + vsync_pts_inc - - next_vf->next_vf_pts) < 0) && - ((int)(nextPts + expected_curr_interval * + ((int)(nextPts + + vsync_pts_inc * (expected_prev_interval - 1) + - next_vf->next_vf_pts) < 0) && + ((int)(nextPts + expected_prev_interval * vsync_pts_inc - next_vf->next_vf_pts) >= 0)) { *expired = true; - if (pts_log_enable[PTS_32_PATTERN]) + if (pts_log_enable[PTS_32_PATTERN] + || pts_log_enable[PTS_22_PATTERN]) pr_info("pull frame for pattern: %d", pts_pattern_detected); } @@ -5187,11 +5288,18 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) if (vsync_slow_factor == 1) { timestamp_pcrscr_inc_scale(vsync_pts_inc_scale, - vsync_pts_inc_scale_base); - } else - timestamp_pcrscr_inc( - vsync_pts_inc / vsync_slow_factor); - timestamp_apts_inc(vsync_pts_inc / vsync_slow_factor); + vsync_pts_inc_scale_base); + timestamp_apts_inc(vsync_pts_inc / vsync_slow_factor); + } else if (vsync_slow_factor > 1000) { + u32 inc = (vsync_slow_factor / 1000) + * vsync_pts_inc / 1000; + + timestamp_pcrscr_inc(inc); + timestamp_apts_inc(inc); + } else { + timestamp_pcrscr_inc(vsync_pts_inc / vsync_slow_factor); + timestamp_apts_inc(vsync_pts_inc / vsync_slow_factor); + } } if (omx_secret_mode == true) { u32 system_time = timestamp_pcrscr_get(); @@ -5208,6 +5316,10 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) /*1500(60fps) 3000(30fps) 3750(24fps) for some video*/ /*that pts is not evenly*/ timestamp_pcrscr_set(omx_pts + DURATION_GCD); + } else if (is_dolby_vision_enable() + && ((diff - omx_pts_dv_upper) > 0 + || (diff - omx_pts_dv_lower) < 0)) { + timestamp_pcrscr_set(omx_pts + DURATION_GCD); } } else omx_pts = 0; @@ -5285,9 +5397,10 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) if (vf) { if (hdmi_in_onvideo == 0) { - tsync_avevent_locked(VIDEO_START, - (vf->pts) ? vf->pts : - timestamp_vpts_get()); + if (nopostvideostart == false) + tsync_avevent_locked(VIDEO_START, + (vf->pts) ? vf->pts : + timestamp_vpts_get()); video_start_post = true; } @@ -5360,12 +5473,14 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) } while (vf) { if (vpts_expire(cur_dispbuf, vf, toggle_cnt) || show_nosync) { - amlog_mask(LOG_MASK_TIMESTAMP, - "vpts = 0x%x, c.dur=0x%x, n.pts=0x%x, scr = 0x%x\n", - timestamp_vpts_get(), - (cur_dispbuf) ? cur_dispbuf->duration : 0, - vf->pts, timestamp_pcrscr_get()); - + if (debug_flag & DEBUG_FLAG_PTS_TRACE) + pr_info("vpts = 0x%x, c.dur=0x%x, n.pts=0x%x, scr = 0x%x, pcr-pts-diff=%d, ptstrace=%d\n", + timestamp_vpts_get(), + (cur_dispbuf) ? + cur_dispbuf->duration : 0, + vf->pts, timestamp_pcrscr_get(), + timestamp_pcrscr_get() - vf->pts, + pts_trace); amlog_mask_if(toggle_cnt > 0, LOG_MASK_FRAMESKIP, "skipped\n"); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -6305,8 +6420,11 @@ SET_FILTER: vpp_misc_set &= ~(VPP_VD2_PREBLEND | VPP_VD2_POSTBLEND | VPP_PREBLEND_EN); /*auto disable sr when video off*/ - VSYNC_WR_MPEG_REG(VPP_SRSHARP0_CTRL, 0); - VSYNC_WR_MPEG_REG(VPP_SRSHARP1_CTRL, 0); + if (!is_meson_txl_cpu() && + !is_meson_txlx_cpu()) { + VSYNC_WR_MPEG_REG(VPP_SRSHARP0_CTRL, 0); + VSYNC_WR_MPEG_REG(VPP_SRSHARP1_CTRL, 0); + } video_onoff_state = VIDEO_ENABLE_STATE_IDLE; video_onoff_time = jiffies_to_msecs(jiffies); vpu_delay_work_flag |= @@ -6400,7 +6518,7 @@ SET_FILTER: VPP_VD1_POSTBLEND | VPP_PREBLEND_EN | VPP_POSTBLEND_EN | - 7); + 0xf); vpp_misc_save &= ((1 << 29) | VPP_CM_ENABLE | (0x1ff << VPP_VD2_ALPHA_BIT) | @@ -6410,7 +6528,7 @@ SET_FILTER: VPP_VD1_POSTBLEND | VPP_PREBLEND_EN | VPP_POSTBLEND_EN | - 7); + 0xf); if (vpp_misc_set != vpp_misc_save) { /* vd1 need always enable pre bld */ if (vpp_misc_set & VPP_VD1_POSTBLEND) @@ -6687,6 +6805,7 @@ static void video_vf_unreg_provider(void) new_frame_count = 0; first_frame_toggled = 0; videopeek = 0; + nopostvideostart = false; atomic_set(&video_unreg_flag, 1); while (atomic_read(&video_inirq_flag) > 0) @@ -6789,6 +6908,7 @@ static void video_vf_unreg_provider(void) memset(&pts_41_pattern_sink[0], 0, PTS_41_PATTERN_SINK_MAX); pts_pattern_detected = -1; pre_pts_trace = 0; + pts_escape_vsync = 0; } #endif } @@ -6942,13 +7062,19 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) } } else if (type == VFRAME_EVENT_PROVIDER_FR_HINT) { #ifdef CONFIG_AM_VOUT - if ((data != NULL) && (video_seek_flag == 0)) + if ((data != NULL) && (video_seek_flag == 0)) { set_vframe_rate_hint((unsigned long)data); + omx_pts_dv_upper = DUR2PTS((unsigned long)data) * 3 / 2; + omx_pts_dv_lower = 0 - DUR2PTS((unsigned long)data); + } #endif } else if (type == VFRAME_EVENT_PROVIDER_FR_END_HINT) { #ifdef CONFIG_AM_VOUT - if (video_seek_flag == 0) + if (video_seek_flag == 0) { set_vframe_rate_end_hint(); + omx_pts_dv_upper = OMX_PTS_DV_DEFAULT_UPPER; + omx_pts_dv_lower = OMX_PTS_DV_DEFAULT_LOWER; + } #endif } else if (type == VFRAME_EVENT_PROVIDER_QUREY_DISPLAY_INFO) { get_display_info(data); @@ -7175,6 +7301,9 @@ static void set_omx_pts(u32 *p) return; } } + if (debug_flag & DEBUG_FLAG_PTS_TRACE) + pr_info("[set_omx_pts]tmp_pts:%d, set_from_hwc:%d,frame_num=%d, not_reset=%d\n", + tmp_pts, set_from_hwc, frame_num, not_reset); if (not_reset == 0) omx_pts = tmp_pts; @@ -7631,8 +7760,13 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg) break; } + case AMSTREAM_IOC_GET_FIRST_FRAME_TOGGLED: + put_user(first_frame_toggled, (u32 __user *)argp); + break; + case AMSTREAM_IOC_SET_VIDEOPEEK: videopeek = true; + nopostvideostart = true; break; default: return -EINVAL; @@ -8773,6 +8907,28 @@ static ssize_t video_global_output_store(struct class *cla, return count; } +static ssize_t video_hold_show(struct class *cla, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hold_video); +} + +static ssize_t video_hold_store(struct class *cla, + struct class_attribute *attr, + const char *buf, size_t count) +{ + int r; + + if (debug_flag & DEBUG_FLAG_BLACKOUT) + pr_info("%s(%s)\n", __func__, buf); + + r = kstrtoint(buf, 0, &hold_video); + if (r < 0) + return -EINVAL; + + return count; +} + static ssize_t video_freerun_mode_show(struct class *cla, struct class_attribute *attr, char *buf) { @@ -9549,6 +9705,10 @@ static struct class_attribute amvideo_class_attrs[] = { 0664, video_global_output_show, video_global_output_store), + __ATTR(hold_video, + 0664, + video_hold_show, + video_hold_store), __ATTR(zoom, 0664, video_zoom_show, @@ -10219,6 +10379,25 @@ static struct mconfig video_configs[] = { #endif }; +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND +static void video_early_suspend(struct early_suspend *h) +{ + DisableVideoLayer(); + DisableVideoLayer2(); + pr_info("video_early_suspend ok\n"); +} + +static void video_late_resume(struct early_suspend *h) +{ + pr_info("video_late_resume ok\n"); +}; + +static struct early_suspend video_early_suspend_handler = { + .suspend = video_early_suspend, + .resume = video_late_resume, +}; +#endif + static int amvideom_probe(struct platform_device *pdev) { int ret = 0; @@ -10238,11 +10417,17 @@ static int amvideom_probe(struct platform_device *pdev) pr_info("amvideom vsync irq: %d\n", video_vsync); +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND + register_early_suspend(&video_early_suspend_handler); +#endif return ret; } static int amvideom_remove(struct platform_device *pdev) { +#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND + unregister_early_suspend(&video_early_suspend_handler); +#endif return 0; } diff --git a/drivers/amlogic/media/video_sink/video_priv.h b/drivers/amlogic/media/video_sink/video_priv.h index 3bc513dda568..cca1ddf66398 100644 --- a/drivers/amlogic/media/video_sink/video_priv.h +++ b/drivers/amlogic/media/video_sink/video_priv.h @@ -27,6 +27,7 @@ #define DEBUG_FLAG_VSYNC_DONONE 0x80000 #define DEBUG_FLAG_GOFIELD_MANUL 0x100000 #define DEBUG_FLAG_LATENCY 0x200000 +#define DEBUG_FLAG_PTS_TRACE 0x400000 /*for video.c's static int debug_flag;*/ #define VOUT_TYPE_TOP_FIELD 0 diff --git a/drivers/amlogic/media/video_sink/vpp.c b/drivers/amlogic/media/video_sink/vpp.c index b663469a5593..f165f4305455 100644 --- a/drivers/amlogic/media/video_sink/vpp.c +++ b/drivers/amlogic/media/video_sink/vpp.c @@ -643,6 +643,8 @@ vpp_process_speed_check(s32 width_in, if (vf) cur_vf_type = vf->type; + else + return 0; if (force_vskip_cnt == 0xff)/*for debug*/ return SPEED_CHECK_DONE; if (next_frame_par->vscale_skip_count < force_vskip_cnt) @@ -1536,14 +1538,12 @@ RESTART: } /* force overwrite filter setting */ - if ((vert_scaler_filter >= COEF_BICUBIC) && - (vert_scaler_filter <= COEF_3D_FILTER)) { + if (vert_scaler_filter <= COEF_3D_FILTER) { filter->vpp_vert_coeff = filter_table[vert_scaler_filter]; filter->vpp_vert_filter = vert_scaler_filter; } if (vert_chroma_filter_force_en && - (vert_chroma_scaler_filter >= COEF_BICUBIC) && - (vert_chroma_scaler_filter <= COEF_3D_FILTER)) { + vert_chroma_scaler_filter <= COEF_3D_FILTER) { cur_vert_chroma_filter = vert_chroma_scaler_filter; filter->vpp_vert_chroma_coeff = filter_table[cur_vert_chroma_filter]; @@ -1553,8 +1553,7 @@ RESTART: filter->vpp_vert_chroma_filter_en = false; } - if ((horz_scaler_filter >= COEF_BICUBIC) && - (horz_scaler_filter <= COEF_3D_FILTER)) { + if (horz_scaler_filter <= COEF_3D_FILTER) { filter->vpp_horz_coeff = filter_table[horz_scaler_filter]; filter->vpp_horz_filter = horz_scaler_filter; } diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c index de1b1c746bd8..f9e2416f1aa6 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe.c @@ -258,7 +258,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) { + if (tvafe_cpu_type() == CPU_TYPE_TXLX || + tvafe_cpu_type() == CPU_TYPE_TL1) { /*synctip set to 0 when tvafe working&&av connected*/ /*enable clamp if av connected*/ if (port == TVIN_PORT_CVBS1) { @@ -485,7 +486,8 @@ void tvafe_dec_close(struct tvin_frontend_s *fe) tvafe_cma_release(devp); #endif #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) { /*avsync tip set 1 to resume av detect*/ if (tvafe->parm.port == TVIN_PORT_CVBS1) { avport_opened = 0; @@ -1138,6 +1140,11 @@ struct meson_tvafe_data meson_txhd_tvafe_data = { .name = "meson-txhd-tvafe", }; +struct meson_tvafe_data meson_tl1_tvafe_data = { + .cpu_id = CPU_TYPE_TL1, + .name = "meson-tl1-tvafe", +}; + static const struct of_device_id meson_tvafe_dt_match[] = { { .compatible = "amlogic, tvafe-gxtvbb", @@ -1151,6 +1158,9 @@ static const struct of_device_id meson_tvafe_dt_match[] = { }, { .compatible = "amlogic, tvafe-txhd", .data = &meson_txhd_tvafe_data, + }, { + .compatible = "amlogic, tvafe-tl1", + .data = &meson_tl1_tvafe_data, }, {}, }; diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c index 5ad6e4b3d836..610992f3afd4 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_cvd.c @@ -418,7 +418,8 @@ static void tvafe_cvd2_write_mode_reg(struct tvafe_cvd2_s *cvd2, } /*setting for txhd snow*/ - if (tvafe_cpu_type() == CPU_TYPE_TXHD) { + if (tvafe_cpu_type() == CPU_TYPE_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1) { W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, 5, 2); W_APB_REG(ACD_REG_6C, 0x80500000); } @@ -2604,7 +2605,8 @@ void tvafe_cvd2_rf_ntsc50_en(bool v) void tvafe_snow_config(unsigned int onoff) { if (tvafe_snow_function_flag == 0 || - tvafe_cpu_type() == CPU_TYPE_TXHD) + tvafe_cpu_type() == CPU_TYPE_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1) return; if (onoff) W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, BLUE_MODE_BIT, BLUE_MODE_WID); @@ -2614,7 +2616,8 @@ void tvafe_snow_config(unsigned int onoff) void tvafe_snow_config_clamp(unsigned int onoff) { - if (tvafe_cpu_type() == CPU_TYPE_TXHD) { + if (tvafe_cpu_type() == CPU_TYPE_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1) { if (onoff) vdin_adjust_tvafesnow_brightness(); return; diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c index 363d252222d2..70c8faacf8e1 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.c @@ -35,6 +35,13 @@ /* edid config reg value */ #define TVAFE_EDID_CONFIG 0x03804050/* 0x03800050 */ +#define HHI_ATV_DMD_SYS_CLK_CNTL 0xf3 +#define VAFE_CLK_EN 23 +#define VAFE_CLK_EN_WIDTH 1 +#define VAFE_CLK_SELECT 24 +#define VAFE_CLK_SELECT_WIDTH 2 + + static unsigned int adc_pll_chg; @@ -239,7 +246,8 @@ 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_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1) { tvafe_pr_info("[tvafe]%s:pin:%d\n", __func__, (unsigned int)pin); if (pin == TVAFE_CVBS_IN0) { @@ -376,7 +384,8 @@ static void tvafe_set_cvbs_default(struct tvafe_cvd2_s *cvd2, unsigned int i = 0; /**disable auto mode clock**/ - W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0); + if (tvafe_cpu_type() != CPU_TYPE_TL1) + W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0); /*config adc*/ if (port == TVIN_PORT_CVBS3) { @@ -391,6 +400,11 @@ 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) { + /** DADC CNTL for LIF signal input **/ + W_HIU_REG(HHI_DADC_CNTL, 0x0030303c); + W_HIU_REG(HHI_DADC_CNTL2, 0x00003480); + W_HIU_REG(HHI_DADC_CNTL3, 0x08300b83); } else { /** DADC CNTL for LIF signal input **/ W_HIU_REG(HHI_DADC_CNTL, 0x1411036); @@ -407,6 +421,10 @@ 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) { + W_HIU_REG(HHI_DADC_CNTL, 0x0030303c); + W_HIU_REG(HHI_DADC_CNTL2, 0x00003400); + W_HIU_REG(HHI_DADC_CNTL3, 0x08300b83); } } /** enable tv_decoder mem clk **/ @@ -421,46 +439,61 @@ 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) { - W_APB_REG(TVFE_VAFE_CTRL0, 0x00090b00); - W_APB_REG(TVFE_VAFE_CTRL1, 0x00000110); - W_APB_REG(TVFE_VAFE_CTRL2, 0x0010ef93); - if (tvafe_cpu_type() == CPU_TYPE_TXHD) { + tvafe_cpu_type() == CPU_TYPE_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1) { + if (tvafe_cpu_type() == CPU_TYPE_TL1) { if (port == TVIN_PORT_CVBS3) { - /*enable fitler for atv/dtv*/ - W_APB_BIT(TVFE_VAFE_CTRL0, 1, + W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710); + W_APB_REG(TVFE_VAFE_CTRL1, 0x00003000); + W_APB_REG(TVFE_VAFE_CTRL2, 0x1fe09e31); + } else if ((port == TVIN_PORT_CVBS1) || + (port == TVIN_PORT_CVBS2)) { + W_APB_REG(TVFE_VAFE_CTRL0, 0x00490710); + W_APB_REG(TVFE_VAFE_CTRL1, 0x0000110e); + W_APB_REG(TVFE_VAFE_CTRL2, 0x1fe09fd3); + } + } else { + W_APB_REG(TVFE_VAFE_CTRL0, 0x00090b00); + W_APB_REG(TVFE_VAFE_CTRL1, 0x00000110); + W_APB_REG(TVFE_VAFE_CTRL2, 0x0010ef93); + if (tvafe_cpu_type() == CPU_TYPE_TXHD) { + if (port == TVIN_PORT_CVBS3) { + /*enable fitler for atv/dtv*/ + W_APB_BIT(TVFE_VAFE_CTRL0, 1, VAFE_FILTER_EN_BIT, VAFE_FILTER_EN_WID); - /*increase current*/ - W_APB_BIT(TVFE_VAFE_CTRL0, 2, - VAFE_FILTER_BIAS_ADJ_BIT, - VAFE_FILTER_BIAS_ADJ_WID); - /*increase band for atv/dtv*/ - W_APB_BIT(TVFE_VAFE_CTRL0, 7, + /*increase current*/ + W_APB_BIT(TVFE_VAFE_CTRL0, 2, + VAFE_FILTER_BIAS_ADJ_BIT, + VAFE_FILTER_BIAS_ADJ_WID); + /*increase band for atv/dtv*/ + W_APB_BIT(TVFE_VAFE_CTRL0, 7, VAFE_BW_SEL_BIT, VAFE_BW_SEL_WID); - W_APB_BIT(TVFE_VAFE_CTRL0, 0x10, - VAFE_FILTER_RESV_BIT, - VAFE_FILTER_RESV_WID); - /*disable pga for atv/dtv*/ - W_APB_BIT(TVFE_VAFE_CTRL1, 0, + W_APB_BIT(TVFE_VAFE_CTRL0, 0x10, + VAFE_FILTER_RESV_BIT, + VAFE_FILTER_RESV_WID); + /*disable pga for atv/dtv*/ + W_APB_BIT(TVFE_VAFE_CTRL1, 0, VAFE_PGA_EN_BIT, VAFE_PGA_EN_WID); - /*config from vlsi-xiaoniu for atv/dtv*/ - /*disable afe buffer(bit0),*/ - /*enable vafe buffer(bit28)*/ - W_APB_REG(TVFE_VAFE_CTRL2, 0x1010eeb0); + /*config from vlsi-xiaoniu for atv/dtv*/ + /*disable afe buffer(bit0),*/ + /*enable vafe buffer(bit28)*/ + W_APB_REG(TVFE_VAFE_CTRL2, 0x1010eeb0); /*W_APB_BIT(TVFE_VAFE_CTRL2, 1, 28, 1);*/ /*W_APB_BIT(TVFE_VAFE_CTRL2, 0, 0, 1);*/ - } else if ((port == TVIN_PORT_CVBS1) || - (port == TVIN_PORT_CVBS2)) { - W_APB_BIT(TVFE_VAFE_CTRL0, 1, + } else if ((port == TVIN_PORT_CVBS1) || + (port == TVIN_PORT_CVBS2)) { + W_APB_BIT(TVFE_VAFE_CTRL0, 1, VAFE_FILTER_EN_BIT, VAFE_FILTER_EN_WID); - W_APB_BIT(TVFE_VAFE_CTRL1, 1, + W_APB_BIT(TVFE_VAFE_CTRL1, 1, VAFE_PGA_EN_BIT, VAFE_PGA_EN_WID); - /*enable Vref buffer*/ - W_APB_BIT(TVFE_VAFE_CTRL2, 1, 28, 1); - /*enable afe buffer*/ - W_APB_BIT(TVFE_VAFE_CTRL2, 1, 0, 1); + /*enable Vref buffer*/ + W_APB_BIT(TVFE_VAFE_CTRL2, 1, 28, 1); + /*enable afe buffer*/ + W_APB_BIT(TVFE_VAFE_CTRL2, 1, 0, 1); + } } } + #if (defined(CONFIG_ADC_DOUBLE_SAMPLING_FOR_CVBS) && defined(CRYSTAL_24M)) if ((port != TVIN_PORT_CVBS3) && (port != TVIN_PORT_CVBS0)) { W_APB_REG(TVFE_TOP_CTRL, 0x010c4d6c); @@ -517,6 +550,17 @@ 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) { + W_APB_REG(TVFE_VAFE_CTRL0, 0x000d0710); + W_APB_REG(TVFE_VAFE_CTRL1, 0x3000); + W_APB_REG(TVFE_VAFE_CTRL2, 0x1fe09e31); + + W_HIU_REG(HHI_DADC_CNTL, 0x0030303c); + W_HIU_REG(HHI_DADC_CNTL2, 0x00003480); + W_HIU_REG(HHI_DADC_CNTL3, 0x08300b83); + + //HHI_VDAC_CNTL1 + W_HIU_REG(0xbc, 0x0); } } @@ -526,7 +570,8 @@ 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_TXHD || + tvafe_cpu_type() == CPU_TYPE_TL1) { if (enable) { tvafe_clk_gate_ctrl(1); if (port == TVIN_PORT_CVBS3) { @@ -582,7 +627,24 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) break; } mutex_lock(&pll_mutex); - do { + 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); + W_HIU_REG(HHI_ADC_PLL_CNTL1_TL1, 0x05400000); + W_HIU_REG(HHI_ADC_PLL_CNTL2_TL1, 0xe1800000); + W_HIU_REG(HHI_ADC_PLL_CNTL3_TL1, 0x48681c00); + W_HIU_REG(HHI_ADC_PLL_CNTL4_TL1, 0x88770290); + W_HIU_REG(HHI_ADC_PLL_CNTL5_TL1, 0x39272000); + W_HIU_REG(HHI_ADC_PLL_CNTL6_TL1, 0x56540000); + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x111104e0); + + udelay(100); + adc_pll_lock_cnt++; + } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL0_TL1, 31, 1) && + (adc_pll_lock_cnt < 10)); + } else { + do { if (tvafe_cpu_type() == CPU_TYPE_TXL || tvafe_cpu_type() == CPU_TYPE_TXLX || tvafe_cpu_type() == CPU_TYPE_TXHD) { @@ -609,8 +671,9 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) } udelay(100); adc_pll_lock_cnt++; - } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL, 31, 1) && - (adc_pll_lock_cnt < 10)); + } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL, 31, 1) && + (adc_pll_lock_cnt < 10)); + } adc_pll_chg |= ADC_EN_ATV_DEMOD; mutex_unlock(&pll_mutex); if (adc_pll_lock_cnt == 10) @@ -627,7 +690,39 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) break; } mutex_lock(&pll_mutex); - do { + 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); + W_HIU_REG(HHI_ADC_PLL_CNTL1_TL1, 0x05400000); + W_HIU_REG(HHI_ADC_PLL_CNTL2_TL1, 0xe0800000); + W_HIU_REG(HHI_ADC_PLL_CNTL3_TL1, 0x48681c00); + W_HIU_REG(HHI_ADC_PLL_CNTL4_TL1, 0x88770290); + W_HIU_REG(HHI_ADC_PLL_CNTL5_TL1, 0x39272000); + W_HIU_REG(HHI_ADC_PLL_CNTL6_TL1, 0x56540000); + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x111104e0); + + udelay(100); + adc_pll_lock_cnt++; + } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL0_TL1, 31, 1) && + (adc_pll_lock_cnt < 10)); + tvafe_pr_info("b0=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL0_TL1)); + tvafe_pr_info("b1=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL1_TL1)); + tvafe_pr_info("b2=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL2_TL1)); + tvafe_pr_info("b3=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL3_TL1)); + tvafe_pr_info("b4=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL4_TL1)); + tvafe_pr_info("b5=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL5_TL1)); + tvafe_pr_info("b6=0x%x", + R_HIU_REG(HHI_ADC_PLL_CNTL6_TL1)); + + } else { + do { if (tvafe_cpu_type() == CPU_TYPE_TXL || tvafe_cpu_type() == CPU_TYPE_TXLX) { W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x4a6a2110); @@ -666,8 +761,9 @@ int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara) } udelay(100); adc_pll_lock_cnt++; - } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL, 31, 1) && - (adc_pll_lock_cnt < 10)); + } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL, 31, 1) && + (adc_pll_lock_cnt < 10)); + } adc_pll_chg |= ADC_EN_TVAFE; mutex_unlock(&pll_mutex); if (adc_pll_lock_cnt == 10) @@ -685,8 +781,28 @@ 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) { + do { + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x012004e0); + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x312004e0); + W_HIU_REG(HHI_ADC_PLL_CNTL1_TL1, 0x05400000); + W_HIU_REG(HHI_ADC_PLL_CNTL2_TL1, 0xe0800000); + W_HIU_REG(HHI_ADC_PLL_CNTL3_TL1, 0x48681c00); + W_HIU_REG(HHI_ADC_PLL_CNTL4_TL1, 0x88770290); + W_HIU_REG(HHI_ADC_PLL_CNTL5_TL1, 0x39272000); + W_HIU_REG(HHI_ADC_PLL_CNTL6_TL1, 0x56540000); + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x111104e0); - if (tvafe_cpu_type() == CPU_TYPE_TXL || + udelay(100); + adc_pll_lock_cnt++; + } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL0_TL1, 31, 1) && + (adc_pll_lock_cnt < 10)); + + W_HIU_REG(0xf3, 0x00800000); + //HHI_AUDPLL_CLK_OUT_CNTL + W_HIU_REG(0x74, 0x501); + + } else if (tvafe_cpu_type() == CPU_TYPE_TXL || tvafe_cpu_type() == CPU_TYPE_TXLX || tvafe_cpu_type() == CPU_TYPE_TXHD) { do { @@ -772,6 +888,23 @@ 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) { + do {//25M + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x001104c8); + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x301104c8); + W_HIU_REG(HHI_ADC_PLL_CNTL1_TL1, 0x03000000); + W_HIU_REG(HHI_ADC_PLL_CNTL2_TL1, 0xe1800000); + W_HIU_REG(HHI_ADC_PLL_CNTL3_TL1, 0x48681c00); + W_HIU_REG(HHI_ADC_PLL_CNTL4_TL1, 0x88770290); + W_HIU_REG(HHI_ADC_PLL_CNTL5_TL1, 0x39272000); + W_HIU_REG(HHI_ADC_PLL_CNTL6_TL1, 0x56540000); + W_HIU_REG(HHI_ADC_PLL_CNTL0_TL1, 0x101104c8); + + udelay(100); + adc_pll_lock_cnt++; + } while (!R_HIU_BIT(HHI_ADC_PLL_CNTL0_TL1, 31, 1) && + (adc_pll_lock_cnt < 10)); + } else { /*is_meson_gxtvbb_cpu()*/ W_HIU_REG(HHI_ADC_PLL_CNTL3, 0x8a2a2110);/*reset*/ @@ -840,6 +973,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) W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0x703);/* can't write !!! */ #endif @@ -899,12 +1033,18 @@ void tvafe_enable_module(bool enable) /* enable */ /* main clk up */ - W_HIU_REG(HHI_VAFE_CLKXTALIN_CNTL, 0x100); - W_HIU_REG(HHI_VAFE_CLKOSCIN_CNTL, 0x100); - W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0x100); - W_HIU_REG(HHI_VAFE_CLKPI_CNTL, 0x100); - W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0x100); - + 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, + VAFE_CLK_EN, VAFE_CLK_EN_WIDTH); + } else { + W_HIU_REG(HHI_VAFE_CLKXTALIN_CNTL, 0x100); + W_HIU_REG(HHI_VAFE_CLKOSCIN_CNTL, 0x100); + W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0x100); + W_HIU_REG(HHI_VAFE_CLKPI_CNTL, 0x100); + W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0x100); + } /* tvfe power up */ W_APB_BIT(TVFE_TOP_CTRL, 1, COMP_CLK_ENABLE_BIT, COMP_CLK_ENABLE_WID); W_APB_BIT(TVFE_TOP_CTRL, 1, EDID_CLK_EN_BIT, EDID_CLK_EN_WID); @@ -936,11 +1076,18 @@ void tvafe_enable_module(bool enable) TVFE_ADC_CLK_DIV_WID); /* main clk down */ - W_HIU_REG(HHI_VAFE_CLKXTALIN_CNTL, 0); - W_HIU_REG(HHI_VAFE_CLKOSCIN_CNTL, 0); - W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0); - W_HIU_REG(HHI_VAFE_CLKPI_CNTL, 0); - W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0); + 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, + VAFE_CLK_EN, VAFE_CLK_EN_WIDTH); + } else { + W_HIU_REG(HHI_VAFE_CLKXTALIN_CNTL, 0); + W_HIU_REG(HHI_VAFE_CLKOSCIN_CNTL, 0); + W_HIU_REG(HHI_VAFE_CLKIN_CNTL, 0); + W_HIU_REG(HHI_VAFE_CLKPI_CNTL, 0); + W_HIU_REG(HHI_TVFE_AUTOMODE_CLK_CNTL, 0); + } } } diff --git a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h index 07d184187de1..85d6a32f9829 100644 --- a/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h +++ b/drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h @@ -124,6 +124,14 @@ #define P_HHI_ADC_PLL_CNTL1 CBUS_REG_ADDR(HHI_ADC_PLL_CNTL1) #define HHI_GCLK_OTHER 0x54 +#define HHI_ADC_PLL_CNTL0_TL1 0xb0 +#define HHI_ADC_PLL_CNTL1_TL1 0xb1 +#define HHI_ADC_PLL_CNTL2_TL1 0xb2 +#define HHI_ADC_PLL_CNTL3_TL1 0xb3 +#define HHI_ADC_PLL_CNTL4_TL1 0xb4 +#define HHI_ADC_PLL_CNTL5_TL1 0xb5 +#define HHI_ADC_PLL_CNTL6_TL1 0xb6 + /* adc pll ctl, atv demod & tvafe use the same adc module*/ /* module index: atv demod:0x01; tvafe:0x2*/ #define ADC_EN_ATV_DEMOD 0x1 @@ -150,6 +158,7 @@ enum tvafe_cpu_type { CPU_TYPE_TXLX = 2, CPU_TYPE_TXHD = 3, CPU_TYPE_GXLX = 4, + CPU_TYPE_TL1 = 5, }; struct meson_tvafe_data { diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index 7cc8610d8fc6..fea8cc5c5c83 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -84,7 +84,9 @@ static struct vinfo_s *hdmitx_get_current_vinfo(void); static DEFINE_MUTEX(setclk_mutex); static DEFINE_MUTEX(getedid_mutex); -static struct hdmitx_dev hdmitx_device; +static struct hdmitx_dev hdmitx_device = { + .frac_rate_policy = 1, +}; struct vout_device_s hdmitx_vdev = { .dv_info = &(hdmitx_device.RXCap.dv_info), @@ -472,7 +474,7 @@ static int set_disp_mode_auto(void) hdev->para = hdmi_get_fmt_name("invalid", hdev->fmt_attr); return -1; } - memcpy(mode, info->name, sizeof(mode)); + strncpy(mode, info->name, sizeof(mode)); if (strstr(mode, "fp")) { int i = 0; @@ -4010,7 +4012,10 @@ static int get_dt_vend_init_data(struct device_node *np, static void hdmitx_init_fmt_attr(struct hdmitx_dev *hdev) { - memset(hdev->fmt_attr, 0, sizeof(hdev->fmt_attr)); + if (strlen(hdev->fmt_attr) >= 8) { + pr_info(SYS "fmt_attr %s\n", hdev->fmt_attr); + return; + } if ((hdev->para->cd == COLORDEPTH_RESERVED) && (hdev->para->cs == COLORSPACE_RESERVED)) { strcpy(hdev->fmt_attr, "default"); @@ -4782,22 +4787,63 @@ static char *next_token_ex(char *separator, char *buf, unsigned int size, return pToken; } +/* check the colorattribute from uboot */ +static void check_hdmiuboot_attr(char *token) +{ + char attr[16] = {0}; + const char * const cs[] = { + "444", "422", "rgb", "420", NULL}; + const char * const cd[] = { + "8bit", "10bit", "12bit", "16bit", NULL}; + int i; + + if (hdmitx_device.fmt_attr[0] != 0) + return; + + if (!token) + return; + + for (i = 0; cs[i] != NULL; i++) { + if (strstr(token, cs[i])) { + if (strlen(cs[i]) < sizeof(attr)) + strncpy(attr, cs[i], strlen(cs[i])); + strcat(attr, ","); + break; + } + } + for (i = 0; cd[i] != NULL; i++) { + if (strstr(token, cd[i])) { + if (strlen(cd[i]) < (sizeof(attr) - strlen(attr))) + strncat(attr, cd[i], strlen(cd[i])); + strncpy(hdmitx_device.fmt_attr, attr, + sizeof(hdmitx_device.fmt_attr)); + hdmitx_device.fmt_attr[15] = '\0'; + break; + } + } +} + static int __init hdmitx_boot_para_setup(char *s) { char separator[] = {' ', ',', ';', 0x0}; char *token; - unsigned int token_len, token_offset, offset = 0; + unsigned int token_len = 0; + unsigned int token_offset = 0; + unsigned int offset = 0; int size = strlen(s); + memset(hdmitx_device.fmt_attr, 0, sizeof(hdmitx_device.fmt_attr)); + do { token = next_token_ex(separator, s, size, offset, &token_len, &token_offset); - if (token) { - if ((token_len == 3) - && (strncmp(token, "off", token_len) == 0)) { - init_flag |= INIT_FLAG_NOT_LOAD; + if (token) { + if ((token_len == 3) + && (strncmp(token, "off", token_len) == 0)) { + init_flag |= INIT_FLAG_NOT_LOAD; + } + check_hdmiuboot_attr(token); } - } offset = token_offset; } while (token); return 0; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_gxl.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_gxl.c index 73b22de81102..e89fcc02b56a 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_gxl.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_gxl.c @@ -253,23 +253,6 @@ void set_hpll_sspll_gxl(enum hdmi_vic vic) case HDMI_1920x1080i50_16x9: hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 0x64348c4, 0, 30); break; - case HDMI_3840x2160p50_16x9: - case HDMI_3840x2160p60_16x9: - case HDMI_4096x2160p50_256x135: - case HDMI_4096x2160p60_256x135: - break; - case HDMI_3840x2160p50_16x9_Y420: - case HDMI_3840x2160p60_16x9_Y420: - case HDMI_4096x2160p50_256x135_Y420: - case HDMI_4096x2160p60_256x135_Y420: - case HDMI_3840x2160p30_16x9: - case HDMI_3840x2160p25_16x9: - case HDMI_3840x2160p24_16x9: - case HDMI_4096x2160p30_256x135: - case HDMI_4096x2160p25_256x135: - case HDMI_4096x2160p24_256x135: - hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL2, 0x62b44c4, 0, 30); - break; default: break; } diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c index b08e16a59bb1..49d701a50533 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c @@ -497,7 +497,7 @@ static void dsi_phy_init(struct dsi_phy_s *dphy, unsigned char lane_num) /* 0x05210f08);//0x03211c08 */ dsi_phy_write(MIPI_DSI_CLK_TIM, - (dphy->clk_trail | (dphy->clk_post << 8) | + (dphy->clk_trail | ((dphy->clk_post+dphy->hs_trail) << 8) | (dphy->clk_zero << 16) | (dphy->clk_prepare << 24))); dsi_phy_write(MIPI_DSI_CLK_TIM1, dphy->clk_pre); /* ?? */ /* 0x050f090d */ @@ -1584,7 +1584,7 @@ static void mipi_dsi_phy_config(struct dsi_phy_s *dphy, unsigned int dsi_ui) if ((dphy->clk_trail * temp) < t_req_min) dphy->clk_trail += 1; - t_req_min = 60 * 100 + 52 * t_ui + 10 * 100; + t_req_min = 60 * 100 + 52 * t_ui + 30 * 100; dphy->clk_post = t_req_min / temp; if ((dphy->clk_post * temp) < t_req_min) dphy->clk_post += 1; diff --git a/drivers/amlogic/media/vout/vdac/vdac_dev.c b/drivers/amlogic/media/vout/vdac/vdac_dev.c index 5f50dc9d4a64..b5b3533c20ad 100644 --- a/drivers/amlogic/media/vout/vdac/vdac_dev.c +++ b/drivers/amlogic/media/vout/vdac/vdac_dev.c @@ -443,8 +443,18 @@ 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) { + /*[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) { + /*[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); + } pri_flag &= ~VDAC_MODULE_TVAFE; if (pri_flag & VDAC_MODULE_CVBS_OUT) break; diff --git a/drivers/amlogic/memory_ext/Kconfig b/drivers/amlogic/memory_ext/Kconfig index cef724ab3cf4..fc411738cb5a 100644 --- a/drivers/amlogic/memory_ext/Kconfig +++ b/drivers/amlogic/memory_ext/Kconfig @@ -39,6 +39,18 @@ config AMLOGIC_CMA Amlogic CMA optimization for cma alloc/free problems Including policy change of CMA usage +config AMLOGIC_VMAP + bool "Amlogic kernel stack" + depends on AMLOGIC_MEMORY_EXTEND + depends on !KASAN + depends on 64BIT + default y + help + This config is used to enable amlogic kernel stack + usage optimization with vmalloc. It depends on + AMLOGIC_MEMORY_EXTEND. This config only opened + on 64 bit platform. + config AMLOGIC_SLUB_DEBUG bool "Amlogic debug for trace all slub objects" depends on AMLOGIC_PAGE_TRACE diff --git a/drivers/amlogic/memory_ext/Makefile b/drivers/amlogic/memory_ext/Makefile index f3c121638eb0..8d3c2666ac00 100644 --- a/drivers/amlogic/memory_ext/Makefile +++ b/drivers/amlogic/memory_ext/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_AMLOGIC_PAGE_TRACE) += page_trace.o obj-$(CONFIG_AMLOGIC_CMA) += aml_cma.o obj-$(CONFIG_AMLOGIC_SLUB_DEBUG) += aml_slub_debug.o obj-$(CONFIG_AMLOGIC_RAMDUMP) += ram_dump.o +obj-$(CONFIG_AMLOGIC_VMAP) += vmap_stack.o diff --git a/drivers/amlogic/memory_ext/aml_cma.c b/drivers/amlogic/memory_ext/aml_cma.c index 55546198df0f..450af9a1439a 100644 --- a/drivers/amlogic/memory_ext/aml_cma.c +++ b/drivers/amlogic/memory_ext/aml_cma.c @@ -152,15 +152,17 @@ EXPORT_SYMBOL(cma_page); static void update_cma_page_trace(struct page *page, unsigned long cnt) { long i; + unsigned long fun; if (page == NULL) return; + fun = find_back_trace(); if (cma_alloc_trace) pr_info("%s alloc page:%lx, count:%ld, func:%pf\n", __func__, - page_to_pfn(page), cnt, (void *)find_back_trace()); + page_to_pfn(page), cnt, (void *)fun); for (i = 0; i < cnt; i++) { - set_page_trace(page, 0, __GFP_BDEV); + set_page_trace(page, 0, __GFP_BDEV, (void *)fun); page++; } } diff --git a/drivers/amlogic/memory_ext/page_trace.c b/drivers/amlogic/memory_ext/page_trace.c index 7af3ac0faac0..1c2f8ba34694 100644 --- a/drivers/amlogic/memory_ext/page_trace.c +++ b/drivers/amlogic/memory_ext/page_trace.c @@ -38,7 +38,7 @@ #define DEBUG_PAGE_TRACE 0 #endif -#define COMMON_CALLER_SIZE 24 +#define COMMON_CALLER_SIZE 32 /* * this is a driver which will hook during page alloc/free and @@ -83,8 +83,11 @@ static struct fun_symbol common_func[] __initdata = { {"dma_alloc_from_contiguous", 1}, {"aml_cma_alloc_post_hook", 1}, {"__dma_alloc", 1}, + {"arm_dma_alloc", 1}, {"__kmalloc_track_caller", 1}, {"kmem_cache_alloc_trace", 1}, + {"__alloc_from_contiguous", 1}, + {"cma_allocator_alloc", 1}, {"alloc_pages_exact", 1}, {"get_zeroed_page", 1}, {"__vmalloc_node_range", 1}, @@ -581,7 +584,7 @@ unsigned int pack_ip(unsigned long ip, int order, gfp_t flag) } EXPORT_SYMBOL(pack_ip); -void set_page_trace(struct page *page, int order, gfp_t flag) +void set_page_trace(struct page *page, int order, gfp_t flag, void *func) { unsigned long ip; struct page_trace *base; @@ -592,7 +595,10 @@ void set_page_trace(struct page *page, int order, gfp_t flag) #else if (page && trace_buffer) { #endif - ip = find_back_trace(); + if (!func) + ip = find_back_trace(); + else + ip = (unsigned long)func; if (!ip) { pr_debug("can't find backtrace for page:%lx\n", page_to_pfn(page)); diff --git a/drivers/amlogic/memory_ext/vmap_stack.c b/drivers/amlogic/memory_ext/vmap_stack.c new file mode 100644 index 000000000000..511cfc73616a --- /dev/null +++ b/drivers/amlogic/memory_ext/vmap_stack.c @@ -0,0 +1,542 @@ +/* + * drivers/amlogic/memory_ext/vmap_stack.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 + +#define D(format, args...) \ + { if (DEBUG) \ + pr_info("VMAP:%s "format, __func__, ##args); \ + } + +#define E(format, args...) pr_err("VMAP:%s "format, __func__, ##args) + +static unsigned long stack_shrink_jiffies; +static unsigned char vmap_shrink_enable; +static atomic_t vmap_stack_size; +static struct aml_vmap *avmap; + +DEFINE_PER_CPU(unsigned long [THREAD_SIZE/sizeof(long)], vmap_stack) + __aligned(16); + +void update_vmap_stack(int diff) +{ + atomic_add(diff, &vmap_stack_size); +} +EXPORT_SYMBOL(update_vmap_stack); + +int get_vmap_stack_size(void) +{ + return atomic_read(&vmap_stack_size); +} +EXPORT_SYMBOL(get_vmap_stack_size); + +static int is_vmap_addr(unsigned long addr) +{ + unsigned long start, end; + + start = (unsigned long)avmap->root_vm->addr; + end = (unsigned long)avmap->root_vm->addr + avmap->root_vm->size; + if ((addr >= start) && (addr < end)) + return 1; + else + return 0; +} + +static struct page *get_vmap_cached_page(int *remain) +{ + unsigned long flags; + struct page *page; + + spin_lock_irqsave(&avmap->page_lock, flags); + if (unlikely(!avmap->cached_pages)) { + spin_unlock_irqrestore(&avmap->page_lock, flags); + return NULL; + } + page = list_first_entry(&avmap->list, struct page, lru); + list_del(&page->lru); + avmap->cached_pages--; + *remain = avmap->cached_pages; + spin_unlock_irqrestore(&avmap->page_lock, flags); + + return page; +} + +static int vmap_mmu_set(struct page *page, unsigned long addr, int set) +{ + pgd_t *pgd = NULL; + pud_t *pud = NULL; + pmd_t *pmd = NULL; + pte_t *pte = NULL; + + pgd = pgd_offset_k(addr); + pud = pud_alloc(&init_mm, pgd, addr); + if (!pud) + goto nomem; + + if (pud_none(*pud)) { + pmd = pmd_alloc(&init_mm, pud, addr); + if (!pmd) + goto nomem; + } + + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) { + pte = pte_alloc_kernel(pmd, addr); + if (!pte) + goto nomem; + } + + pte = pte_offset_map(pmd, addr); + if (set) + set_pte_at(&init_mm, addr, pte, mk_pte(page, PAGE_KERNEL)); + else + pte_clear(&init_mm, addr, pte); + pte_unmap(pte); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE); + D("add:%lx, pgd:%p %llx, pmd:%p %llx, pte:%p %llx\n", + addr, pgd, pgd_val(*pgd), pmd, pmd_val(*pmd), + pte, pte_val(*pte)); + return 0; +nomem: + E("allocation page talbe failed, G:%p, U:%p, M:%p, T:%p", + pgd, pud, pmd, pte); + return -ENOMEM; +} + +static int stack_floor_page(unsigned long addr) +{ + /* + * stack address must align to THREAD_SIZE + */ + return ((addr & (THREAD_SIZE - 1)) < PAGE_SIZE); +} + +static int check_addr_up_flow(unsigned long addr) +{ + /* + * It's the first page of 4 contigours virtual address + * rage(aligned to THREAD_SIZE) but next page of this + * addr is not mapped + */ + if (stack_floor_page(addr) && + !vmalloc_to_page((const void *)(addr + PAGE_SIZE))) + return 1; + return 0; +} + +#if DEBUG +static void dump_backtrace_entry(unsigned long ip, unsigned long fp) +{ + unsigned long fp_size = 0; + + if (fp >= VMALLOC_START) { + fp_size = *((unsigned long *)fp) - fp; + /* fp cross IRQ or vmap stack */ + if (fp_size >= THREAD_SIZE) + fp_size = 0; + } + pr_info("[%016lx+%4ld][<%p>] %pS\n", + fp, fp_size, (void *) ip, (void *) ip); +} + +static void show_fault_stack(unsigned long addr, struct pt_regs *regs) +{ + struct stackframe frame; + + frame.fp = regs->regs[29]; + frame.sp = addr; + frame.pc = (unsigned long)regs->regs[30]; + + pr_info("Call trace:\n"); + pr_info("[%016lx+%4ld][<%p>] %pS\n", + addr, frame.fp - addr, (void *)regs->pc, (void *) regs->pc); + while (1) { + int ret; + + dump_backtrace_entry(frame.pc, frame.fp); + ret = unwind_frame(current, &frame); + if (ret < 0) + break; + } +} +#endif + +/* + * IRQ should *NEVER* been opened in this handler + */ +int handle_vmap_fault(unsigned long addr, unsigned int esr, + struct pt_regs *regs) +{ + struct page *page; + int cache = 0; + + if (!is_vmap_addr(addr)) + return -EINVAL; + + D("addr:%lx, esr:%x, task:%5d %s\n", + addr, esr, current->pid, current->comm); + D("pc:%pf, %llx, lr:%pf, %llx, sp:%llx, %lx\n", + (void *)regs->pc, regs->pc, + (void *)regs->regs[30], regs->regs[30], regs->sp, + current_stack_pointer); + + if (check_addr_up_flow(addr)) { + E("address %lx out of range\n", addr); + E("PC is:%llx, %pf, LR is:%llx %pf\n", + regs->pc, (void *)regs->pc, + regs->regs[30], (void *)regs->regs[30]); + E("task:%d %s, stack:%p, %lx\n", + current->pid, current->comm, current->stack, + current_stack_pointer); + dump_stack(); + return -ERANGE; + } + + /* + * allocate a new page for vmap + */ + page = get_vmap_cached_page(&cache); + WARN_ON(!page); + vmap_mmu_set(page, addr, 1); + update_vmap_stack(1); + if ((THREAD_SIZE_ORDER > 1) && stack_floor_page(addr)) { + E("task:%d %s, stack near overflow, addr:%lx\n", + current->pid, current->comm, addr); + dump_stack(); + } + + /* cache is not enough */ + if (cache <= (VMAP_CACHE_PAGE / 2)) + mod_delayed_work(system_highpri_wq, &avmap->mwork, 0); + + D("map page:%5lx for addr:%lx\n", page_to_pfn(page), addr); +#if DEBUG + show_fault_stack(addr, regs); +#endif + + return 0; +} +EXPORT_SYMBOL(handle_vmap_fault); + +static unsigned long vmap_shrink_count(struct shrinker *s, + struct shrink_control *sc) +{ + return global_page_state(NR_KERNEL_STACK_KB); +} + +static int shrink_vm_stack(unsigned long low, unsigned long high) +{ + int pages = 0; + struct page *page; + + for (; low < (high & PAGE_MASK); low += PAGE_SIZE) { + page = vmalloc_to_page((const void *)low); + vmap_mmu_set(page, low, 0); + update_vmap_stack(-1); + __free_page(page); + pages++; + } + return pages; +} + +static unsigned long get_task_stack_floor(unsigned long sp) +{ + unsigned long end; + + end = sp & (THREAD_SIZE - 1); + while (sp > end) { + if (!vmalloc_to_page((const void *)sp)) + break; + sp -= PAGE_SIZE; + } + return PAGE_ALIGN(sp); +} + +static unsigned long vmap_shrink_scan(struct shrinker *s, + struct shrink_control *sc) +{ + struct task_struct *tsk; + unsigned long thread_sp; + unsigned long stack_floor; + unsigned long rem = 0; + + if (!vmap_shrink_enable) + return 0; + + /* + * sleep for a while if shrink too ofen + */ + if (jiffies - stack_shrink_jiffies <= STACK_SHRINK_SLEEP) + return 0; + + rcu_read_lock(); + for_each_process(tsk) { + thread_sp = thread_saved_sp(tsk); + stack_floor = get_task_stack_floor(thread_sp); + /* + * Make sure selected task is sleeping + */ + D("r:%3ld, sp:[%lx-%lx], s:%5ld, tsk:%lx %d %s\n", + rem, thread_sp, stack_floor, + thread_sp - stack_floor, + tsk->state, tsk->pid, tsk->comm); + task_lock(tsk); + if (tsk->state == TASK_RUNNING) { + task_unlock(tsk); + continue; + } + if (thread_sp - stack_floor >= STACK_SHRINK_THRESHOLD) + rem += shrink_vm_stack(stack_floor, thread_sp); + task_unlock(tsk); + } + rcu_read_unlock(); + stack_shrink_jiffies = jiffies; + + return rem; +} + +static struct shrinker vmap_shrinker = { + .scan_objects = vmap_shrink_scan, + .count_objects = vmap_shrink_count, + .seeks = DEFAULT_SEEKS * 16 +}; + +/* FOR debug */ +static unsigned long vmap_debug_jiff; + +void aml_account_task_stack(struct task_struct *tsk, int account) +{ + unsigned long stack = (unsigned long)task_stack_page(tsk); + struct page *first_page; + + stack += STACK_TOP_PAGE_OFF; + first_page = vmalloc_to_page((void *)stack); + mod_zone_page_state(page_zone(first_page), NR_KERNEL_STACK_KB, + THREAD_SIZE / 1024 * account); + + memcg_kmem_update_page_stat(first_page, MEMCG_KERNEL_STACK_KB, + account * (THREAD_SIZE / 1024)); + if (time_after(jiffies, vmap_debug_jiff + HZ * 5)) { + int ratio, rem; + + vmap_debug_jiff = jiffies; + ratio = ((get_vmap_stack_size() << (PAGE_SHIFT - 10)) * 10000) / + global_page_state(NR_KERNEL_STACK_KB); + rem = ratio % 100; + D("STACK:%ld KB, vmap:%d KB, cached:%d KB, rate:%2d.%02d%%\n", + global_page_state(NR_KERNEL_STACK_KB), + get_vmap_stack_size() << (PAGE_SHIFT - 10), + avmap->cached_pages << (PAGE_SHIFT - 10), + ratio / 100, rem); + } +} + +void *aml_stack_alloc(int node, struct task_struct *tsk) +{ + unsigned long bitmap_no, raw_start; + struct page *page; + unsigned long addr, map_addr, flags; + + spin_lock_irqsave(&avmap->vmap_lock, flags); + raw_start = avmap->start_bit; + bitmap_no = find_next_zero_bit(avmap->bitmap, MAX_TASKS, + avmap->start_bit); + avmap->start_bit = bitmap_no + 1; /* next idle address space */ + if (bitmap_no >= MAX_TASKS) { + spin_unlock_irqrestore(&avmap->vmap_lock, flags); + E("BITMAP FULL!!!\n"); + return NULL; + } + bitmap_set(avmap->bitmap, bitmap_no, 1); + spin_unlock_irqrestore(&avmap->vmap_lock, flags); + + page = alloc_page(THREADINFO_GFP | __GFP_ZERO); + if (!page) { + spin_lock_irqsave(&avmap->vmap_lock, flags); + bitmap_clear(avmap->bitmap, bitmap_no, 1); + spin_unlock_irqrestore(&avmap->vmap_lock, flags); + E("alloction page failed\n"); + return NULL; + } + /* + * map first page only + */ + addr = (unsigned long)avmap->root_vm->addr + THREAD_SIZE * bitmap_no; + map_addr = addr + STACK_TOP_PAGE_OFF; + vmap_mmu_set(page, map_addr, 1); + update_vmap_stack(1); + D("bit idx:%5ld, start:%5ld, addr:%lx, page:%lx\n", + bitmap_no, raw_start, addr, page_to_pfn(page)); + + return (void *)addr; +} + +void aml_stack_free(struct task_struct *tsk) +{ + unsigned long stack = (unsigned long)tsk->stack; + unsigned long addr, bitmap_no; + struct page *page; + unsigned long flags; + + addr = stack + STACK_TOP_PAGE_OFF; + for (; addr >= stack; addr -= PAGE_SIZE) { + page = vmalloc_to_page((const void *)addr); + if (!page) + break; + vmap_mmu_set(page, addr, 0); + /* supplement for stack page cache first */ + spin_lock_irqsave(&avmap->page_lock, flags); + if (avmap->cached_pages < VMAP_CACHE_PAGE) { + list_add_tail(&page->lru, &avmap->list); + avmap->cached_pages++; + spin_unlock_irqrestore(&avmap->page_lock, flags); + clear_highpage(page); /* clear for next use */ + } else { + spin_unlock_irqrestore(&avmap->page_lock, flags); + __free_page(page); + } + update_vmap_stack(-1); + } + bitmap_no = (stack - (unsigned long)avmap->root_vm->addr) / THREAD_SIZE; + spin_lock_irqsave(&avmap->vmap_lock, flags); + bitmap_clear(avmap->bitmap, bitmap_no, 1); + if (bitmap_no < avmap->start_bit) + avmap->start_bit = bitmap_no; + spin_unlock_irqrestore(&avmap->vmap_lock, flags); +} + +static void page_cache_maintain_work(struct work_struct *work) +{ + struct page *page; + struct list_head head; + int i, cnt; + unsigned long flags; + + spin_lock_irqsave(&avmap->page_lock, flags); + cnt = avmap->cached_pages; + spin_unlock_irqrestore(&avmap->page_lock, flags); + if (cnt >= VMAP_CACHE_PAGE) { + D("cache full cnt:%d\n", cnt); + schedule_delayed_work(&avmap->mwork, CACHE_MAINTAIN_DELAY); + return; + } + + INIT_LIST_HEAD(&head); + for (i = 0; i < VMAP_CACHE_PAGE - cnt; i++) { + page = alloc_page(GFP_KERNEL | __GFP_HIGH); + if (!page) { + E("get page failed, allocated:%d, cnt:%d\n", i, cnt); + break; + } + list_add(&page->lru, &head); + } + spin_lock_irqsave(&avmap->page_lock, flags); + list_splice(&head, &avmap->list); + avmap->cached_pages += i; + spin_unlock_irqrestore(&avmap->page_lock, flags); + D("add %d pages, cnt:%d\n", i, cnt); + schedule_delayed_work(&avmap->mwork, CACHE_MAINTAIN_DELAY); +} + +int __init start_thread_work(void) +{ + schedule_delayed_work(&avmap->mwork, CACHE_MAINTAIN_DELAY); + return 0; +} +arch_initcall(start_thread_work); + +void __init thread_stack_cache_init(void) +{ + int i; + unsigned long addr; + struct page *page; + + page = alloc_pages(GFP_KERNEL, VMAP_CACHE_PAGE_ORDER); + if (!page) + return; + + avmap = kzalloc(sizeof(struct aml_vmap), GFP_KERNEL); + if (!avmap) { + __free_pages(page, VMAP_CACHE_PAGE_ORDER); + return; + } + + avmap->bitmap = kzalloc(MAX_TASKS / 8, GFP_KERNEL); + if (!avmap->bitmap) { + __free_pages(page, VMAP_CACHE_PAGE_ORDER); + kfree(avmap); + return; + } + pr_info("%s, vmap:%p, bitmap:%p, cache page:%lx\n", + __func__, avmap, avmap->bitmap, page_to_pfn(page)); + avmap->root_vm = __get_vm_area_node(VM_STACK_AREA_SIZE, + VM_STACK_AREA_SIZE, + 0, VMALLOC_START, VMALLOC_END, + NUMA_NO_NODE, GFP_KERNEL, + __builtin_return_address(0)); + if (!avmap->root_vm) { + __free_pages(page, VMAP_CACHE_PAGE_ORDER); + kfree(avmap->bitmap); + kfree(avmap); + return; + } + pr_info("%s, allocation vm area:%p, addr:%p, size:%lx\n", __func__, + avmap->root_vm, avmap->root_vm->addr, + avmap->root_vm->size); + + INIT_LIST_HEAD(&avmap->list); + spin_lock_init(&avmap->page_lock); + spin_lock_init(&avmap->vmap_lock); + + for (i = 0; i < VMAP_CACHE_PAGE; i++) { + list_add(&page->lru, &avmap->list); + page++; + } + avmap->cached_pages = VMAP_CACHE_PAGE; + INIT_DELAYED_WORK(&avmap->mwork, page_cache_maintain_work); + + for_each_possible_cpu(i) { + addr = (unsigned long)per_cpu_ptr(vmap_stack, i); + pr_info("cpu %d, vmap_stack:[%lx-%lx]\n", + i, addr, addr + THREAD_START_SP); + addr = (unsigned long)per_cpu_ptr(irq_stack, i); + pr_info("cpu %d, irq_stack: [%lx-%lx]\n", + i, addr, addr + THREAD_START_SP); + } + register_shrinker(&vmap_shrinker); +} diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index e5e2fec1e1f3..71a5a47a80e1 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -1877,52 +1877,45 @@ static void aml_sd_emmc_enable_sdio_irq(struct mmc_host *mmc, int enable) { struct amlsd_platform *pdata = mmc_priv(mmc); struct amlsd_host *host = pdata->host; - unsigned long flags; + unsigned long flags = 0; /* u32 vstat = 0; */ u32 vclkc = 0; struct sd_emmc_clock *pclock = NULL; struct sd_emmc_clock_v3 *pclock_v3 = NULL; - u32 vconf = 0; - struct sd_emmc_config *pconf = (struct sd_emmc_config *)&vconf; u32 virqc = 0; struct sd_emmc_irq_en *irqc = (struct sd_emmc_irq_en *)&virqc; host->sdio_irqen = enable; - if (host->xfer_step == XFER_START) + if (host->data->tdma_f && (host->xfer_step == XFER_START)) return; - if (enable) spin_lock_irqsave(&host->mrq_lock, flags); - vconf = readl(host->base + SD_EMMC_CFG); - virqc = readl(host->base + SD_EMMC_IRQ_EN); - - pconf->irq_ds = 0; /* vstat = sd_emmc_regs->gstatus&SD_EMMC_IRQ_ALL; */ + virqc = readl(host->base + SD_EMMC_IRQ_EN); if (enable) irqc->irq_sdio = 1; else irqc->irq_sdio = 0; - writel(virqc, host->base + SD_EMMC_IRQ_EN); - writel(vconf, host->base + SD_EMMC_CFG); - if (host->ctrl_ver >= 3) { - pclock_v3 = (struct sd_emmc_clock_v3 *)&vclkc; - vclkc = readl(host->base + SD_EMMC_CLOCK_V3); - pclock_v3->irq_sdio_sleep = 1; - pclock_v3->irq_sdio_sleep_ds = 0; - writel(vclkc, host->base + SD_EMMC_CLOCK_V3); - } else { - pclock = (struct sd_emmc_clock *)&vclkc; - vclkc = readl(host->base + SD_EMMC_CLOCK); - pclock->irq_sdio_sleep = 1; - pclock->irq_sdio_sleep_ds = 0; - writel(vclkc, host->base + SD_EMMC_CLOCK); + if (!pdata->irq_sdio_sleep) { + if (host->ctrl_ver >= 3) { + pclock_v3 = (struct sd_emmc_clock_v3 *)&vclkc; + vclkc = readl(host->base + SD_EMMC_CLOCK_V3); + pclock_v3->irq_sdio_sleep = 1; + pclock_v3->irq_sdio_sleep_ds = 0; + writel(vclkc, host->base + SD_EMMC_CLOCK_V3); + } else { + pclock = (struct sd_emmc_clock *)&vclkc; + vclkc = readl(host->base + SD_EMMC_CLOCK); + pclock->irq_sdio_sleep = 1; + pclock->irq_sdio_sleep_ds = 0; + writel(vclkc, host->base + SD_EMMC_CLOCK); + } + pdata->irq_sdio_sleep = 1; } - pdata->irq_sdio_sleep = 1; - if (enable) spin_unlock_irqrestore(&host->mrq_lock, flags); /* check if irq already occurred */ @@ -2476,9 +2469,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) if (WARN_ON(!host)) return IRQ_NONE; - if (host->data->tdma_f) - spin_lock_irqsave(&host->mrq_lock, flags); - virqc = readl(host->base + SD_EMMC_IRQ_EN) & 0xffff; vstat = readl(host->base + SD_EMMC_STATUS) & 0xffffffff; host->ista = vstat; @@ -2494,35 +2484,22 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) && (!atomic_read( &sdio_host->sdio_irq_thread_abort))) { mmc_signal_sdio_irq(sdio_host); - if (!(vstat & 0x3fff)) { - spin_unlock_irqrestore(&host->mrq_lock, - flags); + if (!(vstat & 0x3fff)) return IRQ_HANDLED; - } } } else { if ((host->mmc->sdio_irq_thread) && (!atomic_read( &host->mmc->sdio_irq_thread_abort))) { mmc_signal_sdio_irq(host->mmc); - if (!(vstat & 0x3fff)) { - if (host->data->tdma_f) - spin_unlock_irqrestore( - &host->mrq_lock, - flags); + if (!(vstat & 0x3fff)) return IRQ_HANDLED; - } } } - } else if (!(vstat & 0x3fff)) { - if (host->data->tdma_f) - spin_unlock_irqrestore(&host->mrq_lock, flags); + } else if (!(vstat & 0x3fff)) return IRQ_HANDLED; - } - - if (!host->data->tdma_f) - spin_lock_irqsave(&host->mrq_lock, flags); + spin_lock_irqsave(&host->mrq_lock, flags); mrq = host->mrq; mmc = host->mmc; pdata = mmc_priv(mmc); @@ -2621,6 +2598,10 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) mrq->cmd->opcode, mrq->cmd->arg, mrq->data, host->cmd_is_stop, host->status); + if (aml_card_type_sdio(pdata)) + pr_err("@ mrq blksz %d, cfg = %x\n", + mrq->data->blksz, + readl(host->base + SD_EMMC_CFG)); } } else if (ista->desc_err) { if (host->is_tunning == 0) @@ -3206,9 +3187,6 @@ static int meson_mmc_probe(struct platform_device *pdev) if (pdata->caps & MMC_CAP_NONREMOVABLE) pdata->is_in = 1; - if (pdata->caps & MMC_PM_KEEP_POWER) - mmc->pm_caps |= MMC_PM_KEEP_POWER; - /* data desc buffer */ #ifdef CFG_SDEMMC_PIO pr_err(">>>>>>>>hostbase %p, dmode %s\n", @@ -3269,6 +3247,7 @@ static int meson_mmc_probe(struct platform_device *pdev) mmc->ocr_avail = pdata->ocr_avail; mmc->caps = pdata->caps; mmc->caps2 = pdata->caps2; + mmc->pm_caps = pdata->pm_caps; mmc->f_min = pdata->f_min; mmc->f_max = pdata->f_max; mmc->max_current_180 = 300; /* 300 mA in 1.8V */ diff --git a/drivers/amlogic/mmc/amlsd_of.c b/drivers/amlogic/mmc/amlsd_of.c index 0f943790cf40..fc093edddbb5 100644 --- a/drivers/amlogic/mmc/amlsd_of.c +++ b/drivers/amlogic/mmc/amlsd_of.c @@ -113,11 +113,29 @@ static int amlsd_get_host_caps2(struct device_node *of_node, caps |= host_caps2[i].caps; } }; + pdata->caps2 = caps; pr_debug("%s:pdata->caps2 = %x\n", pdata->pinname, pdata->caps2); return 0; } +static int amlsd_get_host_pm_caps(struct device_node *of_node, + struct amlsd_platform *pdata) +{ + const char *str_caps; + struct property *prop; + u32 caps = 0; + + of_property_for_each_string(of_node, "caps", prop, str_caps) { + if (!strcasecmp("MMC_PM_KEEP_POWER", str_caps)) + caps |= MMC_PM_KEEP_POWER; + }; + + pdata->pm_caps = caps; + pr_debug("%s:pdata->pm_caps = %x\n", pdata->pinname, pdata->pm_caps); + return 0; +} + int amlsd_get_platform_data(struct platform_device *pdev, struct amlsd_platform *pdata, struct mmc_host *mmc, u32 index) @@ -211,6 +229,7 @@ int amlsd_get_platform_data(struct platform_device *pdev, amlsd_get_host_caps(child, pdata); amlsd_get_host_caps2(child, pdata); + amlsd_get_host_pm_caps(child, pdata); pdata->port_init = of_amlsd_init; #ifdef CARD_DETECT_IRQ pdata->irq_init = of_amlsd_irq_init; diff --git a/drivers/amlogic/mtd/rsv_manage.c b/drivers/amlogic/mtd/rsv_manage.c index 343a7f50829d..79699363a573 100644 --- a/drivers/amlogic/mtd/rsv_manage.c +++ b/drivers/amlogic/mtd/rsv_manage.c @@ -42,16 +42,14 @@ static struct free_node_t *get_free_node(struct mtd_info *mtd) pr_info("%s %d: bitmap=%llx\n", __func__, __LINE__, aml_chip->freeNodeBitmask); - index = find_first_zero_bit((void *)&aml_chip->freeNodeBitmask, 64); + index = find_first_zero_bit((void *)&aml_chip->freeNodeBitmask, + RESERVED_BLOCK_NUM); if (index > RESERVED_BLOCK_NUM) { pr_info("%s %d: index is greater than max! error", __func__, __LINE__); return NULL; } - if (test_and_set_bit(index, (void *)&aml_chip->freeNodeBitmask)) { - pr_info("%s %d: error!!!\n", __func__, __LINE__); - return NULL; - } + WARN_ON(test_and_set_bit(index, (void *)&aml_chip->freeNodeBitmask)); pr_info("%s %d: bitmap=%llx\n", __func__, __LINE__, aml_chip->freeNodeBitmask); @@ -73,9 +71,8 @@ static void release_free_node(struct mtd_info *mtd, pr_info("%s %d: index=%d is greater than max! error", __func__, __LINE__, free_node->index); - if (test_and_clear_bit(free_node->index, - (void *)&aml_chip->freeNodeBitmask)) - return; + WARN_ON(!test_and_clear_bit(free_node->index, + (void *)&aml_chip->freeNodeBitmask)); /*memset zero to protect from dead-loop*/ memset(free_node, 0, sizeof(struct free_node_t)); diff --git a/drivers/amlogic/pinctrl/pinctrl-meson-g12a.c b/drivers/amlogic/pinctrl/pinctrl-meson-g12a.c index 177550ada304..d4c207b750ff 100644 --- a/drivers/amlogic/pinctrl/pinctrl-meson-g12a.c +++ b/drivers/amlogic/pinctrl/pinctrl-meson-g12a.c @@ -458,6 +458,10 @@ static const unsigned int tdmc_dout1_z_pins[] = {GPIOZ_3}; static const unsigned int tdmc_dout2_z_pins[] = {GPIOZ_4}; static const unsigned int tdmc_dout3_z_pins[] = {GPIOZ_5}; +/* gen_clk_ee */ +static const unsigned int gen_clk_ee_x_pins[] = {GPIOX_19}; +static const unsigned int gen_clk_ee_z_pins[] = {GPIOZ_13}; + /* introduce extra ee pin-groups for G12B based on G12A */ /* ir_out */ @@ -678,6 +682,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = { GROUP(pwm_d_z, 2), GROUP(pwm_f_z, 5), GROUP(clk12_24_z, 2), + GROUP(gen_clk_ee_z, 7), /* bank GPIOX */ GROUP(sdio_d0, 1), @@ -733,6 +738,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = { GROUP(tdma_dout0, 1), GROUP(tdma_dout1, 1), GROUP(mclk1_x, 2), + GROUP(gen_clk_ee_x, 7), /* bank GPIOC */ GROUP(sdcard_d0_c, 1), @@ -923,6 +929,12 @@ static const unsigned int tdmb_slv_sclk_ao_pins[] = {GPIOAO_8}; /* mclk0_ao */ static const unsigned int mclk0_ao_pins[] = {GPIOAO_9}; +/* gen_clk_ee_ao */ +static const unsigned int gen_clk_ee_ao_pins[] = {GPIOAO_11}; + +/* gen_clk_ao */ +static const unsigned int gen_clk_ao_pins[] = {GPIOAO_11}; + /* introduce extra ao pin-groups for G12B based on G12A */ /* ir_out */ @@ -1003,6 +1015,8 @@ static struct meson_pmx_group meson_g12a_aobus_groups[] = { GROUP(pwm_a_e2, 3), GROUP(clk12_24_ao, 7), GROUP(clk12_24_e, 2), + GROUP(gen_clk_ee_ao, 4), + GROUP(gen_clk_ao, 5), }; static const char * const gpio_periphs_groups[] = { @@ -1256,6 +1270,10 @@ static const char * const remote_out_groups[] = { "remote_out_h", "remote_out_z", }; +static const char * const gen_clk_ee_groups[] = { + "gen_clk_ee_x", "gen_clk_ee_z", +}; + static const char * const gpio_aobus_groups[] = { "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", @@ -1351,6 +1369,14 @@ static const char * const clk12_24_ao_groups[] = { "clk12_24_ao", "clk12_24_e", }; +static const char * const gen_clk_ee_ao_groups[] = { + "gen_clk_ee_ao", +}; + +static const char * const gen_clk_ao_groups[] = { + "gen_clk_ao", +}; + static struct meson_pmx_func meson_g12a_periphs_functions[] = { FUNCTION(gpio_periphs), FUNCTION(emmc), @@ -1395,6 +1421,7 @@ static struct meson_pmx_func meson_g12a_periphs_functions[] = { FUNCTION(tdmc_out), FUNCTION(remote_out), FUNCTION(clk12_24_ee), + FUNCTION(gen_clk_ee), }; static struct meson_pmx_func meson_g12a_aobus_functions[] = { @@ -1418,6 +1445,8 @@ static struct meson_pmx_func meson_g12a_aobus_functions[] = { FUNCTION(mclk0_ao), FUNCTION(pwm_a_gpioe), FUNCTION(clk12_24_ao), + FUNCTION(gen_clk_ee_ao), + FUNCTION(gen_clk_ao), }; static struct meson_bank meson_g12a_periphs_banks[] = { diff --git a/drivers/amlogic/thermal/aml_thermal_hw.c b/drivers/amlogic/thermal/aml_thermal_hw.c index 15bd241ffffd..04fdada7eaa7 100644 --- a/drivers/amlogic/thermal/aml_thermal_hw.c +++ b/drivers/amlogic/thermal/aml_thermal_hw.c @@ -67,6 +67,7 @@ struct aml_thermal_sensor { }; static struct aml_thermal_sensor soc_sensor; +static struct gpufreq_cooling_device *gf_cdev_s; int thermal_firmware_init(void) { @@ -175,10 +176,13 @@ int aml_thermal_min_update(struct thermal_cooling_device *cdev) gc_cdev = (struct gpucore_cooling_device *)cdev->devdata; cdev->ops->get_max_state(cdev, &min_state); min_state = min_state - cool->min_state; + if (gf_cdev_s != NULL) + gf_cdev_s->max_pp = gc_cdev->max_gpu_core_num; break; case COOL_DEV_TYPE_GPU_FREQ: gf_cdev = (struct gpufreq_cooling_device *)cdev->devdata; + gf_cdev_s = (struct gpufreq_cooling_device *)cdev->devdata; min_state = gf_cdev->get_gpu_freq_level(cool->min_state); break; diff --git a/drivers/amlogic/thermal/cpucore_cooling.c b/drivers/amlogic/thermal/cpucore_cooling.c index 0c67c32c4e61..0b0c7fc3c701 100644 --- a/drivers/amlogic/thermal/cpucore_cooling.c +++ b/drivers/amlogic/thermal/cpucore_cooling.c @@ -197,7 +197,7 @@ static int cpucore_notify_state(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, enum thermal_trip_type type) { - unsigned long ins_upper; + unsigned long ins_upper, target_upper = 0; long cur_state; long upper = -1; int i; @@ -206,8 +206,11 @@ static int cpucore_notify_state(struct thermal_cooling_device *cdev, case THERMAL_TRIP_HOT: for (i = 0; i < tz->trips; i++) { ins_upper = thermal_get_upper(tz, cdev, i); - if (ins_upper > upper) - upper = ins_upper; + if (!IS_ERR_VALUE(ins_upper) + && (ins_upper >= target_upper)) { + target_upper = ins_upper; + upper = target_upper; + } } cur_state = tz->hot_step; /* do not exceed levels */ diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index aa34713b44a4..e42024d68152 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -1965,7 +1965,63 @@ static int dtv_property_process_set(struct dvb_frontend *fe, return r; } +static void dtv_property_32to64(struct dtv_property *dest, + struct dtv_property_32 *src) +{ + int i = 0; + long tmp = 0; + dest->cmd = src->cmd; +// printk("%s cmd:%d\n",__func__,dest->cmd); + + for (i = 0; i < 3; i++) + dest->reserved[i] = src->reserved[i]; + + dest->u.data = src->u.data; + dest->u.st.len = src->u.st.len; + + for (i = 0; i < MAX_DTV_STATS; i++) { + dest->u.st.stat[i].scale = src->u.st.stat[i].scale; + dest->u.st.stat[i].uvalue = src->u.st.stat[i].uvalue; + dest->u.st.stat[i].svalue = src->u.st.stat[i].svalue; + } + for (i = 0; i < 32; i++) + dest->u.buffer.data[i] = src->u.buffer.data[i]; + dest->u.buffer.len = src->u.buffer.len; + for (i = 0; i < 3; i++) + dest->u.buffer.reserved1[i] = src->u.buffer.reserved1[i]; + tmp = (long)(src->u.buffer.reserved2); + dest->u.buffer.reserved2 = (void *)tmp; + dest->result = src->result; +} + +static void dtv_property_64to32(struct dtv_property_32 *dest, + struct dtv_property *src) +{ + int i = 0; + long tmp = 0; + + dest->cmd = src->cmd; +// printk("%s cmd:%d\n",__func__,dest->cmd); + for (i = 0; i < 3; i++) + dest->reserved[i] = src->reserved[i]; + dest->u.data = src->u.data; +// printk("%s data:%d\n",__func__,dest->u.data); + dest->u.st.len = src->u.st.len; + for (i = 0; i < MAX_DTV_STATS; i++) { + dest->u.st.stat[i].scale = src->u.st.stat[i].scale; + dest->u.st.stat[i].uvalue = src->u.st.stat[i].uvalue; + dest->u.st.stat[i].svalue = src->u.st.stat[i].svalue; + } + for (i = 0; i < 32; i++) + dest->u.buffer.data[i] = src->u.buffer.data[i]; + dest->u.buffer.len = src->u.buffer.len; + for (i = 0; i < 3; i++) + dest->u.buffer.reserved1[i] = src->u.buffer.reserved1[i]; + tmp = (long)(src->u.buffer.reserved2); + dest->u.buffer.reserved2 = (__u32)tmp; + dest->result = src->result; +} static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg) { @@ -1991,7 +2047,9 @@ static int dvb_frontend_ioctl(struct file *file, return -EPERM; } - if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) + if ((cmd == FE_SET_PROPERTY_32) || (cmd == FE_GET_PROPERTY_32) + || (cmd == FE_SET_PROPERTY_64) + || (cmd == FE_GET_PROPERTY_64)) err = dvb_frontend_ioctl_properties(file, cmd, parg); else { c->state = DTV_UNDEFINED; @@ -2012,12 +2070,45 @@ static int dvb_frontend_ioctl_properties(struct file *file, int err = 0; struct dtv_properties *tvps = parg; + struct dtv_properties_32 *tvps_32_tmp = parg; + struct dtv_properties tvps_tmp; struct dtv_property *tvp = NULL; + struct dtv_property_32 *tvp_32 = NULL; int i; + int prop = 0; + int convert = 0; dev_dbg(fe->dvb->device, "%s:\n", __func__); + if ((cmd == FE_SET_PROPERTY_32) || (cmd == FE_SET_PROPERTY_64) + || (cmd == FE_GET_PROPERTY_32) + || (cmd == FE_GET_PROPERTY_64)) { + prop = 1; - if (cmd == FE_SET_PROPERTY) { + if ((cmd == FE_SET_PROPERTY_32) || + (cmd == FE_GET_PROPERTY_32)) { + if (FE_SET_PROPERTY == FE_SET_PROPERTY_64) + convert = 1; + } + } + if (prop) { + if (convert) { + tvps_tmp.num = tvps_32_tmp->num; + tvps_tmp.props = (struct dtv_property *)(long)(tvps_32_tmp->props); + tvps = &tvps_tmp; + + tvp_32 = memdup_user(tvps->props, + tvps->num * sizeof(struct dtv_property_32)); + if (IS_ERR(tvp_32)) { + err = -EFAULT; + goto out; + } + } + } +#ifdef CONFIG_COMPAT + tvps->props = compat_ptr((unsigned long)tvps->props); +#endif + + if ((cmd == FE_SET_PROPERTY_32) || (cmd == FE_SET_PROPERTY_64)) { dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num); dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props); @@ -2026,9 +2117,22 @@ static int dvb_frontend_ioctl_properties(struct file *file, if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; - tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); - if (IS_ERR(tvp)) - return PTR_ERR(tvp); + if (convert) { + tvp = kmalloc_array(tvps->num, + sizeof(*tvp), GFP_KERNEL); + if (IS_ERR(tvp)) { + err = -EFAULT; + goto out; + } + + for (i = 0; i < tvps->num; i++) + dtv_property_32to64(tvp + i, tvp_32+i); + } else { + tvp = memdup_user(tvps->props, + tvps->num * sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + } for (i = 0; i < tvps->num; i++) { err = dtv_property_process_set(fe, tvp + i, file); @@ -2040,7 +2144,7 @@ static int dvb_frontend_ioctl_properties(struct file *file, if (c->state == DTV_TUNE) dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__); - } else if (cmd == FE_GET_PROPERTY) { + } else if ((cmd == FE_GET_PROPERTY_32) || (cmd == FE_GET_PROPERTY_64)) { struct dtv_frontend_properties getp = fe->dtv_property_cache; dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num); @@ -2051,9 +2155,20 @@ static int dvb_frontend_ioctl_properties(struct file *file, if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; - tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); - if (IS_ERR(tvp)) - return PTR_ERR(tvp); + if (convert) { + tvp = kmalloc_array(tvps->num, + sizeof(*tvp), GFP_KERNEL); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + + for (i = 0; i < tvps->num; i++) + dtv_property_32to64(tvp + i, tvp_32+i); + } else { + tvp = memdup_user(tvps->props, + tvps->num * sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + } /* * Let's use our own copy of property cache, in order to @@ -2073,16 +2188,28 @@ static int dvb_frontend_ioctl_properties(struct file *file, (tvp + i)->result = err; } - if (copy_to_user((void __user *)tvps->props, tvp, - tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } + if (convert) { + for (i = 0; i < tvps->num; i++) + dtv_property_64to32(tvp_32 + i, + (struct dtv_property *)(tvp+i)); + if (copy_to_user((void __user *)tvps->props, tvp_32, + tvps->num * sizeof(struct dtv_property_32))) { + err = -EFAULT; + goto out; + } + } else { + if (copy_to_user((void __user *)tvps->props, tvp, + tvps->num * sizeof(struct dtv_property))) { + err = -EFAULT; + goto out; + } + } } else err = -EOPNOTSUPP; out: + kfree(tvp_32); kfree(tvp); return err; } @@ -2663,24 +2790,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) static long dvb_frontend_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long args) { - unsigned long ret; - struct dtv_properties tvps; + long ret; + #ifdef CONFIG_COMPAT args = (unsigned long)compat_ptr(args); #endif - if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) { - if (copy_from_user(&tvps, (void *)args, - sizeof(struct dtv_properties))) - return -EFAULT; -#ifdef CONFIG_COMPAT - tvps.props = compat_ptr((unsigned long)tvps.props); -#endif - if (copy_to_user((void *)args, (void *)&tvps, - sizeof(struct dtv_properties))) - return -EFAULT; - } ret = dvb_generic_ioctl(filp, cmd, args); + return ret; } #endif diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c index f00d82f50ed4..d3073cdb03db 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c @@ -233,7 +233,7 @@ static int dwmac_meson_cfg_ctrl(void __iomem *base_addr) /*config phyid should between a 0~0xffffffff*/ /*please don't use 44000181, this has been used by internal phy*/ - writel(0x33000180, ETH_PHY_config_addr + ETH_PHY_CNTL0); + writel(0x33010180, ETH_PHY_config_addr + ETH_PHY_CNTL0); /*use_phy_smi | use_phy_ip | co_clkin from eth_phy_top*/ writel(0x260, ETH_PHY_config_addr + ETH_PHY_CNTL2); @@ -286,6 +286,7 @@ static int dwmac_meson_cfg_analog(void __iomem *base_addr, } /*for newer then g12a use this dts architecture for dts*/ +void __iomem *phy_analog_config_addr; static void __iomem *g12a_network_interface_setup(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -330,7 +331,7 @@ static void __iomem *g12a_network_interface_setup(struct platform_device *pdev) } ETH_PHY_config_addr = addr; - + phy_analog_config_addr = addr; /*PRG_ETH_REG0*/ if (of_property_read_u32(np, "mc_val", &mc_val)) pr_info("Miss mc_val for REG0\n"); @@ -384,17 +385,8 @@ static void __iomem *g12a_network_interface_setup(struct platform_device *pdev) return REG_ETH_reg0_addr; } -void __iomem *phy_analog_config_addr; static int dwmac_meson_disable_analog(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - void __iomem *phy_analog_config_addr = NULL; - - /*map ETH_PLL address*/ - phy_analog_config_addr = devm_ioremap_nocache - (&pdev->dev, - (resource_size_t)0xff64c000, 4); - writel(0x00000000, phy_analog_config_addr + 0x0); writel(0x003e0000, phy_analog_config_addr + 0x4); writel(0x12844008, phy_analog_config_addr + 0x8); @@ -408,13 +400,6 @@ static int dwmac_meson_disable_analog(struct device *dev) static int dwmac_meson_recover_analog(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - void __iomem *phy_analog_config_addr = NULL; - - /*map ETH_PLL address*/ - phy_analog_config_addr = devm_ioremap_nocache - (&pdev->dev, - (resource_size_t)0xff64c000, 4); pr_info("recover %p\n", phy_analog_config_addr); writel(0x19c0040a, phy_analog_config_addr + 0x44); diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index 9a978d21785e..86d6ad560208 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -189,6 +189,11 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case ION_IOC_SYNC: return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +#ifdef CONFIG_AMLOGIC_MODIFY + case ION_IOC_INVALID_CACHE: + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); +#endif default: return -ENOIOCTLCMD; } diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c index 2b700e8455c6..0ae2f1031d15 100644 --- a/drivers/staging/android/ion/ion-ioctl.c +++ b/drivers/staging/android/ion/ion-ioctl.c @@ -55,6 +55,10 @@ static unsigned int ion_ioctl_dir(unsigned int cmd) case ION_IOC_FREE: case ION_IOC_CUSTOM: return _IOC_WRITE; +#ifdef CONFIG_AMLOGIC_MODIFY + case ION_IOC_INVALID_CACHE: + return _IOC_WRITE; +#endif default: return _IOC_DIR(cmd); } @@ -153,6 +157,13 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = ion_sync_for_device(client, data.fd.fd); break; } +#ifdef CONFIG_AMLOGIC_MODIFY + case ION_IOC_INVALID_CACHE: + { + ret = ion_sync_for_cpu(client, data.fd.fd); + break; + } +#endif case ION_IOC_CUSTOM: { if (!dev->custom_ioctl) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index e015d84e0c58..e19f66e6aaad 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -40,6 +40,9 @@ #include "ion.h" #include "ion_priv.h" #include "compat_ion.h" +#ifdef CONFIG_AMLOGIC_MODIFY +#include +#endif bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer) { @@ -1155,6 +1158,38 @@ int ion_sync_for_device(struct ion_client *client, int fd) return 0; } +#ifdef CONFIG_AMLOGIC_MODIFY +int ion_sync_for_cpu(struct ion_client *client, int fd) +{ + struct dma_buf *dmabuf; + struct ion_buffer *buffer; + struct miscdevice *mdev; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + /* if this memory came from ion */ + if (dmabuf->ops != &dma_buf_ops) { + pr_err("%s: can not sync dmabuf from another exporter\n", + __func__); + dma_buf_put(dmabuf); + return -EINVAL; + } + buffer = dmabuf->priv; + mdev = &client->dev->dev; + + dma_sync_sg_for_cpu(mdev->this_device, + buffer->sg_table->sgl, + buffer->sg_table->nents, + DMA_FROM_DEVICE); + + dma_buf_put(dmabuf); + + return 0; +} +#endif + int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query) { struct ion_device *dev = client->dev; @@ -1426,7 +1461,9 @@ struct ion_device *ion_device_create(long (*custom_ioctl) { struct ion_device *idev; int ret; - +#ifdef CONFIG_AMLOGIC_MODIFY + struct miscdevice *mdev; +#endif idev = kzalloc(sizeof(*idev), GFP_KERNEL); if (!idev) return ERR_PTR(-ENOMEM); @@ -1441,7 +1478,10 @@ struct ion_device *ion_device_create(long (*custom_ioctl) kfree(idev); return ERR_PTR(ret); } - +#ifdef CONFIG_AMLOGIC_MODIFY + mdev = &idev->dev; + of_dma_configure(mdev->this_device, mdev->this_device->of_node); +#endif idev->debug_root = debugfs_create_dir("ion", NULL); if (!idev->debug_root) { pr_err("ion: failed to create debugfs root directory.\n"); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index 0dd87813ab32..57a52d91652b 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -469,6 +469,10 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); int ion_sync_for_device(struct ion_client *client, int fd); +#ifdef CONFIG_AMLOGIC_MODIFY +int ion_sync_for_cpu(struct ion_client *client, int fd); +#endif + struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client, int id); diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h index 14cd8738ecfc..a98902354ba1 100644 --- a/drivers/staging/android/uapi/ion.h +++ b/drivers/staging/android/uapi/ion.h @@ -233,4 +233,13 @@ struct ion_heap_query { #define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ struct ion_heap_query) +#ifdef CONFIG_AMLOGIC_MODIFY +/** + * DOC: ION_IOC_INVALID_CACHE - invalid cache before + * cpu read the memory and after device write the memory. + * this will make the buffer in memory coherent. + */ +#define ION_IOC_INVALID_CACHE _IOWR(ION_IOC_MAGIC, 9, struct ion_fd_data) +#endif + #endif /* _UAPI_LINUX_ION_H */ diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 35d66f5ff9f6..32c29992ab8f 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -294,10 +294,8 @@ struct ffs_data_buffer *ffs_retry_malloc_buffer(struct ffs_data *ffs) pr_info("ffs_retry_malloc_buffer\n"); for (i = 0; i < FFS_BUFFER_MAX; i++) { if (ffs->buffer[i].data_state == -1) { - spin_unlock_irq(&ffs->eps_lock); ffs->buffer[i].data_ep - = kzalloc(MAX_PAYLOAD_EPS, GFP_KERNEL); - spin_lock_irq(&ffs->eps_lock); + = kzalloc(MAX_PAYLOAD_EPS, GFP_ATOMIC); if (!ffs->buffer[i].data_ep) return NULL; ffs->buffer[i].data_state = 1; @@ -317,7 +315,7 @@ static void ffs_free_buffer(struct ffs_data *ffs) if (ffs->buffer[i].data_state != -1) { kfree(ffs->buffer[i].data_ep); ffs->buffer[i].data_ep = NULL; - ffs->buffer[i].data_state = 0; + ffs->buffer[i].data_state = -1; } } } @@ -342,6 +340,11 @@ static void release_ffs_buffer(struct ffs_data *ffs, struct ffs_data_buffer *buffer_temp = buffer; spin_lock_irq(&ffs->eps_lock); + if (buffer_temp->data_ep == NULL) { + buffer_temp->data_state = -1; + spin_unlock_irq(&ffs->eps_lock); + return; + } memset(buffer_temp->data_ep, 0, MAX_PAYLOAD_EPS); buffer_temp->data_state = 0; spin_unlock_irq(&ffs->eps_lock); @@ -872,6 +875,10 @@ static void ffs_user_copy_worker(struct work_struct *work) if (io_data->buf == buffer->data_ep) { break; } + if (i == FFS_BUFFER_MAX - 1) { + pr_info("io_data->buf is missing, i=%d-\n", i); + buffer = NULL; + } } #endif if (io_data->read && ret > 0) { diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 949499dfda56..5543cdfe864a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1172,6 +1172,38 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, } #endif +#ifdef CONFIG_AMLOGIC_VMAP +noinline void trace_android_fs_datawrite_wrap(struct inode *inode, + loff_t pos, unsigned int len) +{ + if (trace_android_fs_datawrite_start_enabled()) { + char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; + + path = android_fstrace_get_pathname(pathbuf, + MAX_TRACE_PATHBUF_LEN, + inode); + trace_android_fs_datawrite_start(inode, pos, len, + current->pid, path, + current->comm); + } +} + +noinline void trace_android_fs_dataread_wrap(struct inode *inode, + loff_t pos, unsigned int len) +{ + if (trace_android_fs_dataread_start_enabled()) { + char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; + + path = android_fstrace_get_pathname(pathbuf, + MAX_TRACE_PATHBUF_LEN, + inode); + trace_android_fs_dataread_start(inode, pos, len, + current->pid, path, + current->comm); + } +} +#endif + static int ext4_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) @@ -1184,6 +1216,9 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, pgoff_t index; unsigned from, to; +#ifdef CONFIG_AMLOGIC_VMAP + trace_android_fs_datawrite_wrap(inode, pos, len); +#else if (trace_android_fs_datawrite_start_enabled()) { char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; @@ -1194,6 +1229,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, current->pid, path, current->comm); } +#endif trace_ext4_write_begin(inode, pos, len, flags); /* * Reserve one block more for addition to orphan list in case @@ -2937,6 +2973,9 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, len, flags, pagep, fsdata); } *fsdata = (void *)0; +#ifdef CONFIG_AMLOGIC_VMAP + trace_android_fs_datawrite_wrap(inode, pos, len); +#else if (trace_android_fs_datawrite_start_enabled()) { char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; @@ -2947,6 +2986,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, current->pid, path, current->comm); } +#endif trace_ext4_da_write_begin(inode, pos, len, flags); if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { @@ -3646,6 +3686,12 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter) if (ext4_has_inline_data(inode)) return 0; +#ifdef CONFIG_AMLOGIC_VMAP + if (rw == READ) + trace_android_fs_dataread_wrap(inode, offset, count); + if (rw == WRITE) + trace_android_fs_datawrite_wrap(inode, offset, count); +#else if (trace_android_fs_dataread_start_enabled() && (rw == READ)) { char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; @@ -3668,6 +3714,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter) current->pid, path, current->comm); } +#endif trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); if (iov_iter_rw(iter) == READ) ret = ext4_direct_IO_read(iocb, iter); diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c index c39a12d6d2d6..483c22b3f705 100644 --- a/fs/ext4/readpage.c +++ b/fs/ext4/readpage.c @@ -117,6 +117,12 @@ ext4_submit_bio_read(struct bio *bio) struct page *first_page = bio->bi_io_vec[0].bv_page; if (first_page != NULL) { + #ifdef CONFIG_AMLOGIC_VMAP + trace_android_fs_dataread_wrap( + first_page->mapping->host, + page_offset(first_page), + bio->bi_iter.bi_size); + #else char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; path = android_fstrace_get_pathname(pathbuf, @@ -129,6 +135,7 @@ ext4_submit_bio_read(struct bio *bio) current->pid, path, current->comm); + #endif } } submit_bio(bio); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a481dde24870..9c87753d0a8e 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2243,6 +2243,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, block_t blkaddr = NULL_ADDR; int err = 0; +#ifdef CONFIG_AMLOGIC_VMAP + trace_android_fs_datawrite_wrap(inode, pos, len); +#else if (trace_android_fs_datawrite_start_enabled()) { char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; @@ -2253,6 +2256,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, current->pid, path, current->comm); } +#endif trace_f2fs_write_begin(inode, pos, len, flags); if (f2fs_is_atomic_file(inode) && @@ -2413,6 +2417,12 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) trace_f2fs_direct_IO_enter(inode, offset, count, rw); +#ifdef CONFIG_AMLOGIC_VMAP + if (rw == READ) + trace_android_fs_dataread_wrap(inode, offset, count); + if (rw == WRITE) + trace_android_fs_datawrite_wrap(inode, offset, count); +#else if (trace_android_fs_dataread_start_enabled() && (rw == READ)) { char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; @@ -2435,6 +2445,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) current->pid, path, current->comm); } +#endif if (rw == WRITE && whint_mode == WHINT_MODE_OFF) iocb->ki_hint = WRITE_LIFE_NOT_SET; diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 156ac4ff491a..aed9c0d63f2b 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -86,6 +86,9 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) { struct page *ipage; +#ifdef CONFIG_AMLOGIC_VMAP + trace_android_fs_dataread_wrap(inode, page_offset(page), PAGE_SIZE); +#else if (trace_android_fs_dataread_start_enabled()) { char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; @@ -96,6 +99,7 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) PAGE_SIZE, current->pid, path, current->comm); } +#endif ipage = get_node_page(F2FS_I_SB(inode), inode->i_ino); if (IS_ERR(ipage)) { diff --git a/fs/mpage.c b/fs/mpage.c index d4e17c88ce08..dc0e05228174 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -80,6 +80,12 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio) struct page *first_page = bio->bi_io_vec[0].bv_page; if (first_page != NULL) { + #ifdef CONFIG_AMLOGIC_VMAP + trace_android_fs_dataread_wrap( + first_page->mapping->host, + page_offset(first_page), + bio->bi_iter.bi_size); + #else char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; path = android_fstrace_get_pathname(pathbuf, @@ -92,6 +98,7 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio) current->pid, path, current->comm); + #endif } } bio->bi_end_io = mpage_end_io; diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 8a428498d6b2..58bd1745012b 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -15,6 +15,9 @@ #ifdef CONFIG_CMA #include #endif +#ifdef CONFIG_AMLOGIC_VMAP +#include +#endif #include #include #include "internal.h" @@ -153,6 +156,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) show_val_kb(m, "CmaFree: ", global_page_state(NR_FREE_CMA_PAGES)); #endif +#ifdef CONFIG_AMLOGIC_VMAP + show_val_kb(m, "VmapStack: ", get_vmap_stack_size()); +#endif hugetlb_report_meminfo(m); diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c index 81fe9e61a792..84df23ac0d5f 100644 --- a/fs/sdcardfs/inode.c +++ b/fs/sdcardfs/inode.c @@ -694,6 +694,153 @@ static int sdcardfs_setattr_wrn(struct dentry *dentry, struct iattr *ia) return -EINVAL; } +#ifdef CONFIG_AMLOGIC_VMAP +/* a save stack version */ +static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, + struct iattr *ia) +{ + int err; + struct dentry *lower_dentry; + struct vfsmount *lower_mnt; + struct inode *inode; + struct inode *lower_inode; + struct path lower_path; + struct iattr lower_ia; + struct dentry *parent; + struct inode *tmp; + struct dentry *tmp_d; + struct sdcardfs_inode_data *top; + + const struct cred *saved_cred = NULL; + + inode = d_inode(dentry); + top = top_data_get(SDCARDFS_I(inode)); + + if (!top) + return -EINVAL; + + tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + tmp_d = kzalloc(sizeof(*tmp_d), GFP_KERNEL); + if (!tmp_d) { + kfree(tmp); + return -ENOMEM; + } + /* + * Permission check on sdcardfs inode. + * Calling process should have AID_SDCARD_RW permission + * Since generic_permission only needs i_mode, i_uid, + * i_gid, and i_sb, we can create a fake inode to pass + * this information down in. + * + * The underlying code may attempt to take locks in some + * cases for features we're not using, but if that changes, + * locks must be dealt with to avoid undefined behavior. + * + */ + copy_attrs(tmp, inode); + tmp->i_uid = make_kuid(&init_user_ns, top->d_uid); + tmp->i_gid = make_kgid(&init_user_ns, get_gid(mnt, dentry->d_sb, top)); + tmp->i_mode = (inode->i_mode & S_IFMT) + | get_mode(mnt, SDCARDFS_I(inode), top); + tmp->i_size = i_size_read(inode); + data_put(top); + tmp->i_sb = inode->i_sb; + tmp_d->d_inode = tmp; + + /* + * Check if user has permission to change dentry. We don't check if + * this user can change the lower inode: that should happen when + * calling notify_change on the lower inode. + */ + /* prepare our own lower struct iattr (with the lower file) */ + memcpy(&lower_ia, ia, sizeof(lower_ia)); + /* Allow touch updating timestamps. A previous permission check ensures + * we have write access. Changes to mode, owner, and group are ignored + */ + ia->ia_valid |= ATTR_FORCE; + err = setattr_prepare(tmp_d, ia); + + if (!err) { + /* check the Android group ID */ + parent = dget_parent(dentry); + if (!check_caller_access_to_name(d_inode(parent), + &dentry->d_name)) + err = -EACCES; + dput(parent); + } + + if (err) + goto out_err; + + /* save current_cred and override it */ + OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode)); + + sdcardfs_get_lower_path(dentry, &lower_path); + lower_dentry = lower_path.dentry; + lower_mnt = lower_path.mnt; + lower_inode = sdcardfs_lower_inode(inode); + + if (ia->ia_valid & ATTR_FILE) + lower_ia.ia_file = sdcardfs_lower_file(ia->ia_file); + + lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE); + + /* + * If shrinking, first truncate upper level to cancel writing dirty + * pages beyond the new eof; and also if its' maxbytes is more + * limiting (fail with -EFBIG before making any change to the lower + * level). There is no need to vmtruncate the upper level + * afterwards in the other cases: we fsstack_copy_inode_size from + * the lower level. + */ + if (ia->ia_valid & ATTR_SIZE) { + err = inode_newsize_ok(tmp, ia->ia_size); + if (err) + goto out; + truncate_setsize(inode, ia->ia_size); + } + + /* + * mode change is for clearing setuid/setgid bits. Allow lower fs + * to interpret this in its own way. + */ + if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) + lower_ia.ia_valid &= ~ATTR_MODE; + + /* notify the (possibly copied-up) lower inode */ + /* + * Note: we use d_inode(lower_dentry), because lower_inode may be + * unlinked (no inode->i_sb and i_ino==0. This happens if someone + * tries to open(), unlink(), then ftruncate() a file. + */ + inode_lock(d_inode(lower_dentry)); + err = notify_change2(lower_mnt, lower_dentry, &lower_ia, + NULL); + inode_unlock(d_inode(lower_dentry)); + if (err) + goto out; + + /* get attributes from the lower inode and update derived permissions */ + sdcardfs_copy_and_fix_attrs(inode, lower_inode); + + /* + * Not running fsstack_copy_inode_size(inode, lower_inode), because + * VFS should update our inode size, and notify_change on + * lower_inode should update its size. + */ + +out: + sdcardfs_put_lower_path(dentry, &lower_path); + REVERT_CRED(saved_cred); +out_err: + kfree(tmp); + kfree(tmp_d); + return err; +} +#else static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct iattr *ia) { int err; @@ -826,6 +973,7 @@ out: out_err: return err; } +#endif static int sdcardfs_fillattr(struct vfsmount *mnt, struct inode *inode, struct kstat *lower_stat, struct kstat *stat) diff --git a/include/dt-bindings/clock/amlogic,g12a-clkc.h b/include/dt-bindings/clock/amlogic,g12a-clkc.h index 6cf7109d2397..8812a2dec8ab 100644 --- a/include/dt-bindings/clock/amlogic,g12a-clkc.h +++ b/include/dt-bindings/clock/amlogic,g12a-clkc.h @@ -265,9 +265,13 @@ #define CLKID_24M (CLKID_MISC_BASE + 9) #define CLKID_12M_DIV (CLKID_MISC_BASE + 10) #define CLKID_12M_GATE (CLKID_MISC_BASE + 11) +/* gen clock */ +#define CLKID_GEN_CLK_SEL (CLKID_MISC_BASE + 12) +#define CLKID_GEN_CLK_DIV (CLKID_MISC_BASE + 13) +#define CLKID_GEN_CLK (CLKID_MISC_BASE + 14) /*G12B clk*/ -#define CLKID_G12B_ADD_BASE (CLKID_MISC_BASE + 12) +#define CLKID_G12B_ADD_BASE (CLKID_MISC_BASE + 15) #define CLKID_CPUB_FCLK_P (CLKID_G12B_ADD_BASE + 0) #define CLKID_CPUB_CLK (CLKID_G12B_ADD_BASE + 1) /*G12B gate*/ diff --git a/include/dt-bindings/clock/amlogic,tl1-audio-clk.h b/include/dt-bindings/clock/amlogic,tl1-audio-clk.h index a000dee9c4e3..c466c02e1aef 100644 --- a/include/dt-bindings/clock/amlogic,tl1-audio-clk.h +++ b/include/dt-bindings/clock/amlogic,tl1-audio-clk.h @@ -15,45 +15,45 @@ * */ -#ifndef __TL1_AUDIO_CLK_H -#define __TL1_AUDIO_CLK_H +#ifndef __TL1_AUDIO_CLK_H__ +#define __TL1_AUDIO_CLK_H__ /* * CLKID audio index values */ -#define CLKID_AUDIO_DDR_ARB 0 -#define CLKID_AUDIO_PDM 1 -#define CLKID_AUDIO_TDMINA 2 -#define CLKID_AUDIO_TDMINB 3 -#define CLKID_AUDIO_TDMINC 4 -#define CLKID_AUDIO_TDMINLB 5 -#define CLKID_AUDIO_TDMOUTA 6 -#define CLKID_AUDIO_TDMOUTB 7 -#define CLKID_AUDIO_TDMOUTC 8 -#define CLKID_AUDIO_FRDDRA 9 -#define CLKID_AUDIO_FRDDRB 10 -#define CLKID_AUDIO_FRDDRC 11 -#define CLKID_AUDIO_TODDRA 12 -#define CLKID_AUDIO_TODDRB 13 -#define CLKID_AUDIO_TODDRC 14 -#define CLKID_AUDIO_LOOPBACKA 15 -#define CLKID_AUDIO_SPDIFIN 16 -#define CLKID_AUDIO_SPDIFOUT 17 -#define CLKID_AUDIO_RESAMPLEA 18 -#define CLKID_AUDIO_RESERVED0 19 -#define CLKID_AUDIO_RESERVED1 20 -#define CLKID_AUDIO_SPDIFOUTB 21 -#define CLKID_AUDIO_EQDRC 22 -#define CLKID_AUDIO_RESAMPLEB 23 -#define CLKID_AUDIO_TOVAD 24 -#define CLKID_AUDIO_AUDIOLOCKER 25 -#define CLKID_AUDIO_SPDIFIN_LB 26 -#define CLKID_AUDIO_FRATV 27 -#define CLKID_AUDIO_FRHDMIRX 28 -#define CLKID_AUDIO_FRDDRD 29 -#define CLKID_AUDIO_TODDRD 30 -#define CLKID_AUDIO_LOOPBACKB 31 +#define CLKID_AUDIO_GATE_DDR_ARB 0 +#define CLKID_AUDIO_GATE_PDM 1 +#define CLKID_AUDIO_GATE_TDMINA 2 +#define CLKID_AUDIO_GATE_TDMINB 3 +#define CLKID_AUDIO_GATE_TDMINC 4 +#define CLKID_AUDIO_GATE_TDMINLB 5 +#define CLKID_AUDIO_GATE_TDMOUTA 6 +#define CLKID_AUDIO_GATE_TDMOUTB 7 +#define CLKID_AUDIO_GATE_TDMOUTC 8 +#define CLKID_AUDIO_GATE_FRDDRA 9 +#define CLKID_AUDIO_GATE_FRDDRB 10 +#define CLKID_AUDIO_GATE_FRDDRC 11 +#define CLKID_AUDIO_GATE_TODDRA 12 +#define CLKID_AUDIO_GATE_TODDRB 13 +#define CLKID_AUDIO_GATE_TODDRC 14 +#define CLKID_AUDIO_GATE_LOOPBACKA 15 +#define CLKID_AUDIO_GATE_SPDIFIN 16 +#define CLKID_AUDIO_GATE_SPDIFOUT_A 17 +#define CLKID_AUDIO_GATE_RESAMPLEA 18 +#define CLKID_AUDIO_GATE_RESERVED0 19 +#define CLKID_AUDIO_GATE_RESERVED1 20 +#define CLKID_AUDIO_GATE_SPDIFOUT_B 21 +#define CLKID_AUDIO_GATE_EQDRC 22 +#define CLKID_AUDIO_GATE_RESAMPLEB 23 +#define CLKID_AUDIO_GATE_TOVAD 24 +#define CLKID_AUDIO_GATE_AUDIOLOCKER 25 +#define CLKID_AUDIO_GATE_SPDIFIN_LB 26 +#define CLKID_AUDIO_GATE_FRATV 27 +#define CLKID_AUDIO_GATE_FRHDMIRX 28 +#define CLKID_AUDIO_GATE_FRDDRD 29 +#define CLKID_AUDIO_GATE_TODDRD 30 +#define CLKID_AUDIO_GATE_LOOPBACKB 31 #define MCLK_BASE 32 #define CLKID_AUDIO_MCLK_A (MCLK_BASE + 0) @@ -63,14 +63,18 @@ #define CLKID_AUDIO_MCLK_E (MCLK_BASE + 4) #define CLKID_AUDIO_MCLK_F (MCLK_BASE + 5) -#define CLKID_AUDIO_SPDIFIN_CTRL (MCLK_BASE + 6) -#define CLKID_AUDIO_SPDIFOUT_CTRL (MCLK_BASE + 7) -#define CLKID_AUDIO_PDMIN0 (MCLK_BASE + 8) -#define CLKID_AUDIO_PDMIN1 (MCLK_BASE + 9) -#define CLKID_AUDIO_SPDIFOUTB_CTRL (MCLK_BASE + 10) -#define CLKID_AUDIO_LOCKER_OUT (MCLK_BASE + 11) -#define CLKID_AUDIO_LOCKER_IN (MCLK_BASE + 12) -#define CLKID_AUDIO_RESAMPLE_CTRL (MCLK_BASE + 13) +#define CLKID_AUDIO_SPDIFIN (MCLK_BASE + 6) +#define CLKID_AUDIO_SPDIFOUT_A (MCLK_BASE + 7) +#define CLKID_AUDIO_RESAMPLE_A (MCLK_BASE + 8) +#define CLKID_AUDIO_LOCKER_OUT (MCLK_BASE + 9) +#define CLKID_AUDIO_LOCKER_IN (MCLK_BASE + 10) +#define CLKID_AUDIO_PDMIN0 (MCLK_BASE + 11) +#define CLKID_AUDIO_PDMIN1 (MCLK_BASE + 12) +#define CLKID_AUDIO_SPDIFOUT_B (MCLK_BASE + 13) +#define CLKID_AUDIO_RESAMPLE_B (MCLK_BASE + 14) +#define CLKID_AUDIO_SPDIFIN_LB (MCLK_BASE + 15) +#define CLKID_AUDIO_EQDRC (MCLK_BASE + 16) +#define CLKID_AUDIO_VAD (MCLK_BASE + 17) -#define NUM_AUDIO_CLKS (MCLK_BASE + 14) -#endif /* __G12A_AUDIO_CLK_H */ +#define NUM_AUDIO_CLKS (MCLK_BASE + 18) +#endif /* __TL1_AUDIO_CLK_H__ */ diff --git a/include/linux/amlogic/aml_ddr_bandwidth.h b/include/linux/amlogic/aml_ddr_bandwidth.h index 1235d1ee0a9c..bde095b91e8a 100644 --- a/include/linux/amlogic/aml_ddr_bandwidth.h +++ b/include/linux/amlogic/aml_ddr_bandwidth.h @@ -130,25 +130,25 @@ struct ddr_bandwidth_ops { }; struct ddr_bandwidth { - void __iomem *ddr_reg; - void __iomem *pll_reg; - struct class *class; unsigned short cpu_type; unsigned short real_ports; char busy; char mode; int mali_port[2]; unsigned int threshold; - struct work_struct work_bandwidth; unsigned int irq_num; unsigned int clock_count; unsigned int channels; - unsigned int port[MAX_CHANNEL]; unsigned int bandwidth[MAX_CHANNEL]; unsigned int total_usage; unsigned int total_bandwidth; + u64 port[MAX_CHANNEL]; + void __iomem *ddr_reg; + void __iomem *pll_reg; + struct class *class; struct ddr_port_desc *port_desc; struct ddr_bandwidth_ops *ops; + struct work_struct work_bandwidth; }; #ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH diff --git a/include/linux/amlogic/ddr_port.h b/include/linux/amlogic/ddr_port.h index a50755f189f5..4f0b5c4af79c 100644 --- a/include/linux/amlogic/ddr_port.h +++ b/include/linux/amlogic/ddr_port.h @@ -18,7 +18,7 @@ #ifndef __DDR_PORT_DESC_H__ #define __DDR_PORT_DESC_H__ -#define MAX_PORTS 256 +#define MAX_PORTS 63 #define MAX_NAME 15 #define PORT_MAJOR 32 diff --git a/include/linux/amlogic/major.h b/include/linux/amlogic/major.h index 4d2f9c2becad..1ce50430bb88 100644 --- a/include/linux/amlogic/major.h +++ b/include/linux/amlogic/major.h @@ -29,6 +29,7 @@ #define AMAUDIO2_MAJOR (13+(AML_BASE)) #define VFM_MAJOR (14+(AML_BASE)) #define IONVIDEO_MAJOR (15+(AML_BASE)) +#define VAD_MAJOR (16+(AML_BASE)) /* *#define UIO_MAJOR 4+(AML_BASE) *#define USB_DEV_EP_MAJOR 5+(AML_BASE) diff --git a/include/linux/amlogic/media/camera/aml_cam_info.h b/include/linux/amlogic/media/camera/aml_cam_info.h new file mode 100644 index 000000000000..b669ef4f466a --- /dev/null +++ b/include/linux/amlogic/media/camera/aml_cam_info.h @@ -0,0 +1,142 @@ +/* + * include/linux/amlogic/media/camera/aml_cam_info.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __AML_CAM_DEV__ +#define __AML_CAM_DEV__ +#include +#include +#include +#include +#include +#include + +#define FRONT_CAM 0 +#define BACK_CAM 1 + +enum resolution_size { + SIZE_NULL = 0, SIZE_176X144, /* 4:3 */ + SIZE_320X240, /* 4:3 */ + SIZE_352X288, /* 4:3 */ + SIZE_640X480, /* 0.3M 4:3 */ + SIZE_720X405, /* 0.3M 16:9 */ + SIZE_800X600, /* 0.5M 4:3 */ + SIZE_960X540, /* 0.5M 16:9 */ + SIZE_1024X576, /* 0.6M 16:9 */ + SIZE_960X720, /* 0.7M 4:3 */ + SIZE_1024X768, /* 0.8M 4:3 */ + SIZE_1280X720, /* 0.9M 16:9 */ + SIZE_1152X864, /* 1M 4:3 */ + SIZE_1366X768, /* 1M 16:9 */ + SIZE_1280X960, /* 1.2M 4:3 */ + SIZE_1280X1024, /* 1.3M 16:9. */ + SIZE_1400X1050, /* 1.5M 4:3 */ + SIZE_1600X900, /* 1.5M 16:9 */ + SIZE_1600X1200, /* 2M 4:3 */ + SIZE_1920X1080, /* 2M 16:9 */ + SIZE_1792X1344, /* 2.4M 4:3 */ + SIZE_2048X1152, /* 2.4M 16:9 */ + SIZE_2048X1536, /* 3.2M 4:3 */ + SIZE_2304X1728, /* 4M 4:3 */ + SIZE_2560X1440, /* 4M 16:9 */ + SIZE_2592X1944, /* 5M 4:3 */ + SIZE_3072X1728, /* 5M 16:9 */ + SIZE_2816X2112, /* 6M 4:3 */ + SIZE_3264X1836, /* 6m 16:9 */ + SIZE_3072X2304, /* 7M 4:3 */ + SIZE_3200X2400, /* 7.5M 4:3 */ + SIZE_3264X2448, /* 8M 4:3 */ + SIZE_3840X2160, /* 8M 16:9 */ + SIZE_3456X2592, /* 9M 4:3 */ + SIZE_3600X2700, /* 9.5M 4:3 */ + SIZE_4096X2304, /* 9.5M 16:9 */ + SIZE_3672X2754, /* 10M 4:3 */ + SIZE_3840X2880, /* 11M 4:3 */ + SIZE_4000X3000, /* 12M 4:3 */ + SIZE_4608X2592, /* 12M 16:9 */ + SIZE_4096X3072, /* 12.5M 4:3 */ + SIZE_4800X3200, /* 15M 4:3 */ + SIZE_5120X2880, /* 15M 16:9 */ + SIZE_5120X3840, /* 20M 4:3 */ + SIZE_6400X4800, /* 30M 4:3 */ +}; + +typedef int (*aml_cam_probe_fun_t)(struct i2c_adapter *); + +struct aml_cam_info_s { + struct list_head info_entry; + const char *name; + unsigned int i2c_bus_num; + unsigned int pwdn_act; + unsigned int front_back; /* front is 0, back is 1 */ + unsigned int m_flip; + unsigned int v_flip; + unsigned int flash; + unsigned int auto_focus; + unsigned int i2c_addr; + const char *motor_driver; + const char *resolution; + const char *version; + unsigned int mclk; + unsigned int flash_support; + unsigned int flash_ctrl_level; + unsigned int torch_support; + unsigned int torch_ctrl_level; + unsigned int vcm_mode; + unsigned int spread_spectrum; + unsigned int vdin_path; + unsigned int bt_path_count; + enum bt_path_e bt_path; + enum cam_interface_e interface; + enum clk_channel_e clk_channel; + /* gpio_t pwdn_pin; */ + /* gpio_t rst_pin; */ + /* gpio_t flash_ctrl_pin; */ + /* gpio_t torch_ctrl_pin; */ + unsigned int pwdn_pin; + unsigned int rst_pin; + unsigned int flash_ctrl_pin; + unsigned int torch_ctrl_pin; + enum resolution_size max_cap_size; + enum tvin_color_fmt_e bayer_fmt; + const char *config; + struct pinctrl *camera_pin_ctrl; +}; +/* aml_cam_info_t */ + +struct aml_camera_i2c_fig_s { + unsigned short addr; + unsigned char val; +}; + +struct aml_camera_i2c_fig0_s { + unsigned short addr; + unsigned short val; +}; + +struct aml_camera_i2c_fig1_s { + unsigned char addr; + unsigned char val; +}; + +extern void aml_cam_init(struct aml_cam_info_s *cam_dev); +extern void aml_cam_uninit(struct aml_cam_info_s *cam_dev); +extern void aml_cam_flash(struct aml_cam_info_s *cam_dev, int is_on); +extern void aml_cam_torch(struct aml_cam_info_s *cam_dev, int is_on); +extern int aml_cam_info_reg(struct aml_cam_info_s *cam_info); +extern int aml_cam_info_unreg(struct aml_cam_info_s *cam_info); + +#endif /* __AML_CAM_DEV__ */ diff --git a/include/linux/amlogic/media/camera/flashlight.h b/include/linux/amlogic/media/camera/flashlight.h new file mode 100644 index 000000000000..d59437251385 --- /dev/null +++ b/include/linux/amlogic/media/camera/flashlight.h @@ -0,0 +1,34 @@ +/* + * include/linux/amlogic/media/camera/flashlight.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _VIDEO_AMLOGIC_FLASHLIGHT_INCLUDE_ +#define _VIDEO_AMLOGIC_FLASHLIGHT_INCLUDE_ +struct aml_plat_flashlight_data_s { + void (*flashlight_on)(void); + void (*flashlight_off)(void); +}; + +enum aml_plat_flashlight_status_s { + FLASHLIGHT_AUTO = 0, + FLASHLIGHT_ON, + FLASHLIGHT_OFF, + FLASHLIGHT_TORCH, + FLASHLIGHT_RED_EYE, +}; + +#endif + diff --git a/include/linux/amlogic/media/camera/vmapi.h b/include/linux/amlogic/media/camera/vmapi.h new file mode 100644 index 000000000000..b1d832eda9db --- /dev/null +++ b/include/linux/amlogic/media/camera/vmapi.h @@ -0,0 +1,63 @@ +/* + * include/linux/amlogic/media/camera/vmapi.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef VM_API_INCLUDE_ +#define VM_API_INCLUDE_ + +struct vm_output_para { + int width; + int height; + int bytesperline; + int v4l2_format; + int index; + int v4l2_memory; + int zoom; /* set -1 as invalid */ + int mirror; /* set -1 as invalid */ + int angle; + uintptr_t vaddr;/*unsigned*/ + unsigned int ext_canvas; +}; +/*struct vm_output_para*/ +struct videobuf_buffer; +struct vb2_buffer; + +struct vm_init_s { + size_t vm_buf_size; + struct page *vm_pages; + resource_size_t buffer_start; + unsigned int vdin_id; + unsigned int bt_path_count; + bool isused; + bool mem_alloc_succeed; +}; +/*struct vm_init_s*/ + +int vm_fill_this_buffer(struct videobuf_buffer *vb, struct vm_output_para *para, + struct vm_init_s *info); +int vm_fill_buffer(struct videobuf_buffer *vb, struct vm_output_para *para); + +int vm_fill_buffer2(struct vb2_buffer *vb, struct vm_output_para *para); + +#ifdef CONFIG_CMA +int vm_init_buf(size_t size); +int vm_init_resource(size_t size, struct vm_init_s *info); +void vm_deinit_buf(void); +void vm_deinit_resource(struct vm_init_s *info); +void vm_reserve_cma(void); +#endif + +#endif /* VM_API_INCLUDE_ */ diff --git a/include/linux/amlogic/media/codec_mm/codec_mm_scatter.h b/include/linux/amlogic/media/codec_mm/codec_mm_scatter.h index 5e02182e3f75..5a84e3c3a0c8 100644 --- a/include/linux/amlogic/media/codec_mm/codec_mm_scatter.h +++ b/include/linux/amlogic/media/codec_mm/codec_mm_scatter.h @@ -60,6 +60,7 @@ struct codec_mm_scatter *codec_mm_scatter_alloc(int max_page, int page_num, int istvp); int codec_mm_scatter_alloc_want_pages(struct codec_mm_scatter *mms, int want_pages); +int codec_mm_scatter_size(int is_tvp); int codec_mm_scatter_mgt_delay_free_swith(int on, int delay_ms, int wait_size_M, int istvp); int codec_mm_dump_scatter(struct codec_mm_scatter *mms, void *buf, int size); diff --git a/include/linux/amlogic/media/frame_provider/tvin/tvin.h b/include/linux/amlogic/media/frame_provider/tvin/tvin.h index 2127da5c6d50..3fa257f72802 100644 --- a/include/linux/amlogic/media/frame_provider/tvin/tvin.h +++ b/include/linux/amlogic/media/frame_provider/tvin/tvin.h @@ -490,4 +490,6 @@ extern int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara); extern void tvafe_set_ddemod_default(void);/* add for dtv demod*/ extern void rx_get_audio_status(struct rx_audio_stat_s *aud_sts); +extern void rx_set_atmos_flag(bool en); +extern bool rx_get_atmos_flag(void); #endif diff --git a/include/linux/amlogic/media/sound/misc.h b/include/linux/amlogic/media/sound/misc.h new file mode 100644 index 000000000000..7f3edbfb5bcd --- /dev/null +++ b/include/linux/amlogic/media/sound/misc.h @@ -0,0 +1,67 @@ +/* + * include/linux/amlogic/media/sound/misc.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __MISC_H__ +#define __MISC_H__ + +#include +#include +#include + +#ifdef CONFIG_AMLOGIC_ATV_DEMOD +extern const struct soc_enum atv_audio_status_enum; + +int aml_get_atv_audio_stable( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +#endif + +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +extern int update_spdifin_audio_type(int audio_type); + +extern const struct soc_enum hdmi_in_status_enum[]; + +extern int get_hdmi_sample_rate_index(void); + +extern int aml_get_hdmiin_audio_stable( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +extern int aml_get_hdmiin_audio_samplerate( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +extern int aml_get_hdmiin_audio_channels( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +extern int aml_get_hdmiin_audio_format( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +extern int aml_set_atmos_audio_edid( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +extern int aml_get_atmos_audio_edid( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +#endif + +#endif diff --git a/include/linux/amlogic/media/sound/spdif_info.h b/include/linux/amlogic/media/sound/spdif_info.h index 68a11ebb319d..e9fec1776202 100644 --- a/include/linux/amlogic/media/sound/spdif_info.h +++ b/include/linux/amlogic/media/sound/spdif_info.h @@ -18,7 +18,9 @@ #ifndef __SPDIF_INFO_H__ #define __SPDIF_INFO_H__ +#include #include +#include struct iec958_chsts { unsigned short chstat0_l; @@ -34,4 +36,13 @@ extern void spdif_get_channel_status_info(struct iec958_chsts *chsts, extern void spdif_notify_to_hdmitx(struct snd_pcm_substream *substream); +extern const struct soc_enum spdif_format_enum; + +extern int spdif_format_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + +extern int spdif_format_set_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); #endif diff --git a/include/linux/amlogic/media/utils/amstream.h b/include/linux/amlogic/media/utils/amstream.h index 3dfe61d64c7e..5b44f40ec3b6 100644 --- a/include/linux/amlogic/media/utils/amstream.h +++ b/include/linux/amlogic/media/utils/amstream.h @@ -176,6 +176,7 @@ #define AMSTREAM_IOC_GET_OMX_VERSION _IOW((_A_M), 0xb1, int) #define AMSTREAM_IOC_GET_OMX_INFO _IOR((_A_M), 0xb2, unsigned int) #define AMSTREAM_IOC_SET_HDR_INFO _IOW((_A_M), 0xb3, int) +#define AMSTREAM_IOC_GET_FIRST_FRAME_TOGGLED _IOR(_A_M, 0xbe, unsigned int) #define AMSTREAM_IOC_SET_VIDEOPEEK _IOW(_A_M, 0xbf, unsigned int) #define AMSTREAM_IOC_GET_TRICK_VPTS _IOR((_A_M), 0xf0, int) @@ -233,6 +234,7 @@ enum FRAME_BASE_VIDEO_PATH { FRAME_BASE_PATH_AMVIDEO, FRAME_BASE_PATH_AMVIDEO2, FRAME_BASE_PATH_V4L_VIDEO, + FRAME_BASE_PATH_TUNNEL_MODE, FRAME_BASE_PATH_MAX }; @@ -578,6 +580,7 @@ struct userdata_param_t { #define AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS 0x811 #define AMSTREAM_GET_ION_ID 0x812 #define AMSTREAM_GET_NEED_MORE_DATA 0x813 +#define AMSTREAM_GET_FREED_HANDLE 0x814 /* video get cmd */ #define AMSTREAM_GET_OMX_VPTS 0x860 #define AMSTREAM_GET_TRICK_STAT 0x861 diff --git a/include/linux/amlogic/page_trace.h b/include/linux/amlogic/page_trace.h index b3e93f85a94d..7d724303841c 100644 --- a/include/linux/amlogic/page_trace.h +++ b/include/linux/amlogic/page_trace.h @@ -66,7 +66,8 @@ struct page_trace { extern unsigned int cma_alloc_trace; extern unsigned long unpack_ip(struct page_trace *trace); extern unsigned int pack_ip(unsigned long ip, int order, gfp_t flag); -extern void set_page_trace(struct page *page, int order, gfp_t gfp_flags); +extern void set_page_trace(struct page *page, int order, + gfp_t gfp_flags, void *func); extern void reset_page_trace(struct page *page, int order); extern void page_trace_mem_init(void); extern struct page_trace *find_page_base(struct page *page); diff --git a/include/linux/amlogic/scpi_protocol.h b/include/linux/amlogic/scpi_protocol.h index c0c9de6b9583..771b2bfbb255 100644 --- a/include/linux/amlogic/scpi_protocol.h +++ b/include/linux/amlogic/scpi_protocol.h @@ -67,6 +67,8 @@ enum scpi_std_cmd { SCPI_CMD_OSCRING_VALUE = 0x43, SCPI_CMD_WAKEUP_REASON_GET = 0x30, SCPI_CMD_WAKEUP_REASON_CLR = 0X31, + SCPI_CMD_GET_ETHERNET_CALC = 0x32, + SCPI_CMD_GET_CEC1 = 0xB4, SCPI_CMD_GET_CEC2 = 0xB5, SCPI_CMD_COUNT @@ -98,4 +100,5 @@ int scpi_get_ring_value(unsigned char *val); int scpi_get_wakeup_reason(u32 *wakeup_reason); int scpi_clr_wakeup_reason(void); int scpi_get_cec_val(enum scpi_std_cmd index, u32 *p_cec); +u8 scpi_get_ethernet_calc(void); #endif /*_SCPI_PROTOCOL_H_*/ diff --git a/include/linux/amlogic/sd.h b/include/linux/amlogic/sd.h index 0d4e24ddb05f..9fa73a8a99bf 100644 --- a/include/linux/amlogic/sd.h +++ b/include/linux/amlogic/sd.h @@ -264,6 +264,7 @@ struct amlsd_platform { struct delayed_work cd_detect; unsigned int caps; unsigned int caps2; + unsigned int pm_caps; unsigned int card_capacity; unsigned int tx_phase; unsigned int tx_delay; diff --git a/include/linux/amlogic/vmap_stack.h b/include/linux/amlogic/vmap_stack.h new file mode 100644 index 000000000000..1b4081ed2461 --- /dev/null +++ b/include/linux/amlogic/vmap_stack.h @@ -0,0 +1,66 @@ +/* + * include/linux/amlogic/vmap_stack.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __VMAP_STACK_H__ +#define __VMAP_STACK_H__ + +#define STACK_SHRINK_THRESHOLD (PAGE_SIZE + 1024) +#define STACK_SHRINK_SLEEP (HZ) +#define VM_STACK_AREA_SIZE SZ_512M + +#define STACK_TOP_PAGE_OFF (THREAD_SIZE - PAGE_SIZE) + +#define MAX_TASKS (VM_STACK_AREA_SIZE / THREAD_SIZE) + +#define VMAP_PAGE_FLAG (__GFP_ZERO | __GFP_HIGH |\ + __GFP_ATOMIC | __GFP_REPEAT) + +#define VMAP_CACHE_PAGE_ORDER 5 +#define VMAP_CACHE_PAGE (1 << VMAP_CACHE_PAGE_ORDER) +#define CACHE_MAINTAIN_DELAY (HZ) + +struct aml_vmap { + unsigned int start_bit; + int cached_pages; + struct vm_struct *root_vm; + unsigned long *bitmap; + struct list_head list; + spinlock_t vmap_lock; + spinlock_t page_lock; + struct delayed_work mwork; +}; + +extern int handle_vmap_fault(unsigned long addr, + unsigned int esr, struct pt_regs *regs); + +extern DEFINE_PER_CPU(unsigned long [THREAD_SIZE/sizeof(long)], vmap_stack); +static inline bool on_vmap_stack(unsigned long sp, int cpu) +{ + /* variable names the same as kernel/stacktrace.c */ + unsigned long low = (unsigned long)per_cpu(vmap_stack, cpu); + unsigned long high = low + THREAD_START_SP; + + return (low <= sp && sp <= high); +} + +extern void __setup_vmap_stack(unsigned long off); +extern void update_vmap_stack(int diff); +extern int get_vmap_stack_size(void); +extern void aml_stack_free(struct task_struct *tsk); +extern void *aml_stack_alloc(int node, struct task_struct *tsk); +extern void aml_account_task_stack(struct task_struct *tsk, int account); +#endif /* __VMAP_STACK_H__ */ diff --git a/include/linux/kasan.h b/include/linux/kasan.h index b37afd197eed..ecd57cf676e5 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -54,6 +54,9 @@ void kasan_poison_object_data(struct kmem_cache *cache, void *object); void kasan_init_slab_obj(struct kmem_cache *cache, const void *object); void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags); +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND +void kasan_kmalloc_save(const void *ptr, size_t size, gfp_t flags); +#endif void kasan_kfree_large(const void *ptr); void kasan_poison_kfree(void *ptr); void kasan_kmalloc(struct kmem_cache *s, const void *object, size_t size, @@ -106,6 +109,12 @@ static inline void kasan_init_slab_obj(struct kmem_cache *cache, const void *object) {} static inline void kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) {} +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND +static inline void kasan_kmalloc_save(const void *ptr, size_t size, + gfp_t flags) +{ +} +#endif static inline void kasan_kfree_large(const void *ptr) {} static inline void kasan_poison_kfree(void *ptr) {} static inline void kasan_kmalloc(struct kmem_cache *s, const void *object, diff --git a/include/linux/sched.h b/include/linux/sched.h index 3e3f559f9a39..9ab2bf1de373 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -3377,8 +3377,12 @@ static inline void *try_get_task_stack(struct task_struct *tsk) static inline void put_task_stack(struct task_struct *tsk) {} #endif +#ifdef CONFIG_AMLOGIC_VMAP +#define task_stack_end_corrupted(task) (false) +#else #define task_stack_end_corrupted(task) \ (*(end_of_stack(task)) != STACK_END_MAGIC) +#endif static inline int object_is_on_stack(void *obj) { diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 3d9d786a943c..2f4fc62a7bd6 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -192,4 +192,10 @@ pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) int register_vmap_purge_notifier(struct notifier_block *nb); int unregister_vmap_purge_notifier(struct notifier_block *nb); +#ifdef CONFIG_AMLOGIC_VMAP +extern struct vm_struct *__get_vm_area_node(unsigned long size, + unsigned long align, unsigned long flags, unsigned long start, + unsigned long end, int node, + gfp_t gfp_mask, const void *caller); +#endif #endif /* _LINUX_VMALLOC_H */ diff --git a/include/trace/events/android_fs.h b/include/trace/events/android_fs.h index 49509533d3fa..9fc55340ba08 100644 --- a/include/trace/events/android_fs.h +++ b/include/trace/events/android_fs.h @@ -63,3 +63,9 @@ android_fstrace_get_pathname(char *buf, int buflen, struct inode *inode) return path; } #endif +#ifdef CONFIG_AMLOGIC_VMAP +extern void trace_android_fs_datawrite_wrap(struct inode *inode, + loff_t pos, unsigned int len); +extern void trace_android_fs_dataread_wrap(struct inode *inode, + loff_t pos, unsigned int len); +#endif diff --git a/include/uapi/linux/dvb/aml_demod.h b/include/uapi/linux/dvb/aml_demod.h index 342e69019f54..cc0b31d31d8b 100644 --- a/include/uapi/linux/dvb/aml_demod.h +++ b/include/uapi/linux/dvb/aml_demod.h @@ -176,6 +176,20 @@ struct aml_demod_para { u32_t dtmb_coderate; }; +//cmd +#define AML_DBG_DEMOD_TOP_RW 0 +#define AML_DBG_DVBC_RW 1 +#define AML_DBG_ATSC_RW 2 +#define AML_DBG_DTMB_RW 3 +#define AML_DBG_FRONT_RW 4 +#define AML_DBG_ISDBT_RW 5 +#define AML_DBG_DVBC_INIT 6 +#define AML_DBG_ATSC_INIT 7 +#define AML_DBG_DTMB_INIT 8 +#define AML_DBG_DEMOD_SYMB_RATE 9 +#define AML_DBG_DEMOD_CH_FREQ 10 +#define AML_DBG_DEMOD_MODUL 11 + #define AML_DEMOD_SET_SYS _IOW('D', 0, struct aml_demod_sys) #define AML_DEMOD_GET_SYS _IOR('D', 1, struct aml_demod_sys) @@ -219,5 +233,16 @@ int read_memory_to_file(struct aml_cap_data *cap); int read_reg(int addr); void wait_capture(int cap_cur_addr, int depth_MB, int start); int cap_adc_data(struct aml_cap_data *cap); +extern unsigned int get_symbol_rate(void); +extern unsigned int get_ch_freq(void); +extern unsigned int get_modu(void); +extern void tuner_set_atsc_para(void); +extern void tuner_set_dtmb_para(void); +extern void tuner_set_qam_para(void); +extern void tuner_config_atsc(void); +extern void attach_tuner_demod(void); +extern void tuner_set_freq(unsigned int freq); +extern void tuner_config_dtmb(void); +extern void tuner_config_qam(void); #endif /* AML_DEMOD_H */ diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index e851a304aee6..0b32aa331dbd 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -541,16 +541,38 @@ struct dtv_property { __u32 reserved1[3]; void *reserved2; } buffer; -#if 0 -#ifdef CONFIG_AMLOGIC_DVB_COMPAT + } u; + int result; +} __attribute__ ((packed)); + +struct dtv_property_32 { + __u32 cmd; + __u32 reserved[3]; + union { + __u32 data; + struct dtv_fe_stats st; struct { __u8 data[32]; __u32 len; __u32 reserved1[3]; - __u64 reserved; - } reserved; -#endif -#endif + __u32 reserved2; + } buffer; + } u; + int result; +} __attribute__ ((packed)); + +struct dtv_property_64 { + __u32 cmd; + __u32 reserved[3]; + union { + __u32 data; + struct dtv_fe_stats st; + struct { + __u8 data[32]; + __u32 len; + __u32 reserved1[3]; + __u64 reserved2; + } buffer; } u; int result; } __attribute__ ((packed)); @@ -560,14 +582,17 @@ struct dtv_property { struct dtv_properties { __u32 num; -#if 0 && defined(CONFIG_AMLOGIC_DVB_COMPAT) - union { - struct dtv_property *props; - __u64 reserved; - }; -#else struct dtv_property *props; -#endif +}; + +struct dtv_properties_32 { + __u32 num; + __u32 props; +}; + +struct dtv_properties_64 { + __u32 num; + __u64 props; }; #if defined(__DVB_CORE__) || !defined (__KERNEL__) @@ -722,6 +747,12 @@ struct dvbsx_blindscanevent { #define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) #define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) +#define FE_SET_PROPERTY_32 _IOW('o', 82, struct dtv_properties_32) +#define FE_GET_PROPERTY_32 _IOR('o', 83, struct dtv_properties_32) + +#define FE_SET_PROPERTY_64 _IOW('o', 82, struct dtv_properties_64) +#define FE_GET_PROPERTY_64 _IOR('o', 83, struct dtv_properties_64) + #ifdef CONFIG_AMLOGIC_DVB_COMPAT /*for atv*/ struct tuner_status_s { diff --git a/kernel/fork.c b/kernel/fork.c index 24ce22c41f21..232244644042 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -86,6 +86,10 @@ #include #include +#ifdef CONFIG_AMLOGIC_VMAP +#include +#endif + #include #define CREATE_TRACE_POINTS @@ -206,15 +210,22 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) tsk->stack_vm_area = find_vm_area(stack); return stack; #else +#ifdef CONFIG_AMLOGIC_VMAP + return aml_stack_alloc(node, tsk); +#else /* CONFIG_AMLOGIC_VMAP */ struct page *page = alloc_pages_node(node, THREADINFO_GFP, THREAD_SIZE_ORDER); return page ? page_address(page) : NULL; +#endif /* CONFIG_AMLOGIC_VMAP */ #endif } static inline void free_thread_stack(struct task_struct *tsk) { +#ifdef CONFIG_AMLOGIC_VMAP + aml_stack_free(tsk); +#else /* CONFIG_AMLOGIC_VMAP */ kaiser_unmap_thread_stack(tsk->stack); #ifdef CONFIG_VMAP_STACK if (task_stack_vm_area(tsk)) { @@ -238,6 +249,7 @@ static inline void free_thread_stack(struct task_struct *tsk) #endif __free_pages(virt_to_page(tsk->stack), THREAD_SIZE_ORDER); +#endif /* CONFIG_AMLOGIC_VMAP */ } # else static struct kmem_cache *thread_stack_cache; @@ -282,6 +294,9 @@ static struct kmem_cache *mm_cachep; static void account_kernel_stack(struct task_struct *tsk, int account) { +#ifdef CONFIG_AMLOGIC_VMAP + aml_account_task_stack(tsk, account); +#else void *stack = task_stack_page(tsk); struct vm_struct *vm = task_stack_vm_area(tsk); @@ -314,6 +329,7 @@ static void account_kernel_stack(struct task_struct *tsk, int account) memcg_kmem_update_page_stat(first_page, MEMCG_KERNEL_STACK_KB, account * (THREAD_SIZE / 1024)); } +#endif /* CONFIG_AMLOGIC_VMAP*/ } static void release_task_stack(struct task_struct *tsk) @@ -465,12 +481,23 @@ int __weak arch_dup_task_struct(struct task_struct *dst, return 0; } +#ifdef CONFIG_AMLOGIC_VMAP +static bool first_magic __read_mostly; +#endif + void set_task_stack_end_magic(struct task_struct *tsk) { unsigned long *stackend; stackend = end_of_stack(tsk); +#ifdef CONFIG_AMLOGIC_VMAP + if (unlikely(!first_magic)) { + *stackend = STACK_END_MAGIC; /* for overflow detection */ + first_magic = 1; + } +#else *stackend = STACK_END_MAGIC; /* for overflow detection */ +#endif } static struct task_struct *dup_task_struct(struct task_struct *orig, int node) diff --git a/mm/compaction.c b/mm/compaction.c index 2d9ee59ff2b1..e35f49150e2b 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -637,7 +637,11 @@ isolate_freepages_range(struct compact_control *cc, /* Similar to reclaim, but different enough that they don't share logic */ static bool too_many_isolated(struct zone *zone) { +#ifdef CONFIG_AMLOGIC_CMA + signed long active, inactive, isolated; +#else unsigned long active, inactive, isolated; +#endif inactive = node_page_state(zone->zone_pgdat, NR_INACTIVE_FILE) + node_page_state(zone->zone_pgdat, NR_INACTIVE_ANON); @@ -646,6 +650,13 @@ static bool too_many_isolated(struct zone *zone) isolated = node_page_state(zone->zone_pgdat, NR_ISOLATED_FILE) + node_page_state(zone->zone_pgdat, NR_ISOLATED_ANON); +#ifdef CONFIG_AMLOGIC_CMA + isolated -= global_page_state(NR_CMA_ISOLATED); + WARN_ONCE(isolated > (inactive + active) / 2, + "isolated:%ld, cma:%ld, inactive:%ld, active:%ld\n", + isolated, global_page_state(NR_CMA_ISOLATED), + inactive, active); +#endif /* CONFIG_AMLOGIC_CMA */ return isolated > (inactive + active) / 2; } #ifdef CONFIG_AMLOGIC_CMA diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c index 7d78b5f5908b..8622541037b4 100644 --- a/mm/kasan/kasan.c +++ b/mm/kasan/kasan.c @@ -632,6 +632,31 @@ void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags) KASAN_PAGE_REDZONE); } +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND +void kasan_kmalloc_save(const void *ptr, size_t size, gfp_t flags) +{ + struct page *page; + unsigned long redzone_start; + unsigned long redzone_end; + + if (gfpflags_allow_blocking(flags)) + quarantine_reduce(); + + if (unlikely(ptr == NULL)) + return; + + page = virt_to_page(ptr); + redzone_start = round_up((unsigned long)(ptr + size), + KASAN_SHADOW_SCALE_SIZE); + redzone_end = (unsigned long)ptr + PAGE_ALIGN(size); + + kasan_unpoison_shadow(ptr, size); + kasan_poison_shadow((void *)redzone_start, redzone_end - redzone_start, + KASAN_PAGE_REDZONE); +} + +#endif + void kasan_krealloc(const void *object, size_t size, gfp_t flags) { struct page *page; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a361ce219f48..d30cb0c5a6c9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4095,7 +4095,7 @@ out: trace_mm_page_alloc(page, order, alloc_mask, ac.migratetype); #ifdef CONFIG_AMLOGIC_PAGE_TRACE - set_page_trace(page, order, gfp_mask); + set_page_trace(page, order, gfp_mask, NULL); #endif /* CONFIG_AMLOGIC_PAGE_TRACE */ return page; diff --git a/mm/slab_common.c b/mm/slab_common.c index b9cace005148..45b23eb5c77d 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1029,6 +1029,59 @@ void __init create_kmalloc_caches(unsigned long flags) } #endif /* !CONFIG_SLOB */ +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND +#ifdef CONFIG_AMLOGIC_PAGE_TRACE +#include +#endif + +static inline void *aml_slub_alloc_large(size_t size, gfp_t flags, int order) +{ + struct page *page, *p; + + flags &= ~__GFP_COMP; + page = alloc_pages(flags, order); + if (page) { + unsigned long used_pages = PAGE_ALIGN(size) / PAGE_SIZE; + unsigned long total_pages = 1 << order; + unsigned long saved = 0; + #ifdef CONFIG_AMLOGIC_PAGE_TRACE + unsigned long fun; + #endif + int i; + + /* record how many pages in first page*/ + __SetPageHead(page); + SetPageOwnerPriv1(page); /* special flag */ + + #ifdef CONFIG_AMLOGIC_PAGE_TRACE + fun = get_page_trace(page); + #endif + + for (i = 1; i < used_pages; i++) { + p = page + i; + set_compound_head(p, page); + #ifdef CONFIG_AMLOGIC_PAGE_TRACE + set_page_trace(page, 0, flags, (void *)fun); + #endif + } + page->index = used_pages; + split_page(page, order); + p = page + used_pages; + while (used_pages < total_pages) { + __free_pages(p, 0); + used_pages++; + p++; + saved++; + } + pr_debug("%s, page:%p, all:%5ld, size:%5ld, save:%5ld, f:%pf\n", + __func__, page_address(page), total_pages * PAGE_SIZE, + (long)size, saved * PAGE_SIZE, (void *)fun); + return page; + } else + return NULL; +} +#endif + /* * To avoid unnecessary overhead, we pass through large allocation requests * directly to the page allocator. We use __GFP_COMP, because we will need to @@ -1038,12 +1091,31 @@ void *kmalloc_order(size_t size, gfp_t flags, unsigned int order) { void *ret; struct page *page; +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND + int saved = 0; +#endif flags |= __GFP_COMP; +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND + if (size < (PAGE_SIZE * (1 << order))) { + page = aml_slub_alloc_large(size, flags, order); + saved = 1; + } else + page = alloc_pages(flags, order); +#else page = alloc_pages(flags, order); +#endif ret = page ? page_address(page) : NULL; kmemleak_alloc(ret, size, 1, flags); +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND + /* only need poison used pages */ + if (saved && ret) + kasan_kmalloc_save(ret, size, flags); + else + kasan_kmalloc_large(ret, size, flags); +#else kasan_kmalloc_large(ret, size, flags); +#endif return ret; } EXPORT_SYMBOL(kmalloc_order); diff --git a/mm/slub.c b/mm/slub.c index edc79ca3c6d5..59ec52723860 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3721,6 +3721,26 @@ static int __init setup_slub_min_objects(char *str) __setup("slub_min_objects=", setup_slub_min_objects); +#ifdef CONFIG_AMLOGIC_MEMORY_EXTEND +static void aml_slub_free_large(struct page *page, const void *obj) +{ + unsigned int nr_pages, i; + + if (page) { + __ClearPageHead(page); + ClearPageOwnerPriv1(page); + nr_pages = page->index; + pr_debug("%s, page:%p, pages:%d, obj:%p\n", + __func__, page_address(page), nr_pages, obj); + for (i = 0; i < nr_pages; i++) { + __free_pages(page, 0); + kasan_free_pages(page, 0); + page++; + } + } +} +#endif + void *__kmalloc(size_t size, gfp_t flags) { struct kmem_cache *s; @@ -3841,7 +3861,17 @@ static size_t __ksize(const void *object) if (unlikely(!PageSlab(page))) { WARN_ON(!PageCompound(page)); + #ifdef CONFIG_AMLOGIC_MEMORY_EXTEND + if (unlikely(PageOwnerPriv1(page))) { + pr_debug("%s, obj:%p, page:%p, index:%ld, size:%ld\n", + __func__, object, page_address(page), + page->index, PAGE_SIZE * page->index); + return PAGE_SIZE * page->index; + } else + return PAGE_SIZE << compound_order(page); + #else return PAGE_SIZE << compound_order(page); + #endif } return slab_ksize(page->slab_cache); @@ -3871,9 +3901,20 @@ void kfree(const void *x) page = virt_to_head_page(x); if (unlikely(!PageSlab(page))) { BUG_ON(!PageCompound(page)); + #ifdef CONFIG_AMLOGIC_MEMORY_EXTEND + kmemleak_free(x); + if (unlikely(PageOwnerPriv1(page))) + aml_slub_free_large(page, x); + else { + __free_pages(page, compound_order(page)); + kasan_kfree_large(x); + } + return; + #else kfree_hook(x); __free_pages(page, compound_order(page)); return; + #endif /* CONFIG_AMLOGIC_MEMORY_EXTEND */ } slab_free(page->slab_cache, page, object, NULL, 1, _RET_IP_); } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 195de42bea1f..1323e1af39fd 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1361,9 +1361,15 @@ static void clear_vm_uninitialized_flag(struct vm_struct *vm) vm->flags &= ~VM_UNINITIALIZED; } +#ifdef CONFIG_AMLOGIC_VMAP +struct vm_struct *__get_vm_area_node(unsigned long size, + unsigned long align, unsigned long flags, unsigned long start, + unsigned long end, int node, gfp_t gfp_mask, const void *caller) +#else static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long align, unsigned long flags, unsigned long start, unsigned long end, int node, gfp_t gfp_mask, const void *caller) +#endif { struct vmap_area *va; struct vm_struct *area; diff --git a/sound/soc/amlogic/auge/Makefile b/sound/soc/amlogic/auge/Makefile index 6ebfb6271c83..4cf47bec8853 100644 --- a/sound/soc/amlogic/auge/Makefile +++ b/sound/soc/amlogic/auge/Makefile @@ -23,8 +23,13 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE) += audio_controller.o \ resample_hw.o \ effects.o \ effects_hw.o \ + effects_v2.o \ + effects_hw_v2.o \ pwrdet.o \ pwrdet_hw.o \ sharebuffer.o \ extn.o \ - frhdmirx_hw.o + frhdmirx_hw.o \ + vad.o \ + vad_hw.o \ + vad_dev.o diff --git a/sound/soc/amlogic/auge/audio_controller.c b/sound/soc/amlogic/auge/audio_controller.c index c625269190e2..1b50eacb3ff0 100644 --- a/sound/soc/amlogic/auge/audio_controller.c +++ b/sound/soc/amlogic/auge/audio_controller.c @@ -103,7 +103,7 @@ static int register_audio_controller(struct platform_device *pdev, platform_set_drvdata(pdev, actrl); /* gate on all clks on bringup stage, need gate separately */ - aml_audiobus_write(actrl, EE_AUDIO_CLK_GATE_EN0, 0xffffff); + aml_audiobus_write(actrl, EE_AUDIO_CLK_GATE_EN0, 0xffffffff); return 0; } diff --git a/sound/soc/amlogic/auge/audio_utils.c b/sound/soc/amlogic/auge/audio_utils.c index 53e8fb98d3d2..32dca83e41c3 100644 --- a/sound/soc/amlogic/auge/audio_utils.c +++ b/sound/soc/amlogic/auge/audio_utils.c @@ -24,7 +24,10 @@ #include "tdm_hw.h" #include "ddr_mngr.h" #include "resample.h" +#include "effects_v2.h" +#include "vad.h" +#include #include #include @@ -943,6 +946,16 @@ int snd_card_add_kcontrols(struct snd_soc_card *card) return ret; } + ret = card_add_effect_v2_kcontrols(card); + if (ret < 0) { + pr_err("Failed to add AED v2 controls\n"); + return ret; + } + + ret = card_add_vad_kcontrols(card); + if (ret < 0) + pr_warn_once("Failed to add VAD controls\n"); + return snd_soc_add_card_controls(card, snd_auge_controls, ARRAY_SIZE(snd_auge_controls)); @@ -1505,3 +1518,10 @@ void fratv_src_select(int src) { audiobus_update_bits(EE_AUDIO_FRATV_CTRL0, 0x1 << 20, (bool)src << 20); } + +void cec_arc_enable(int src, bool enable) +{ + aml_hiubus_update_bits(HHI_HDMIRX_ARC_CNTL, + 0x1f << 0, + src << 2 | enable << 1 | 0x0 << 0); +} diff --git a/sound/soc/amlogic/auge/audio_utils.h b/sound/soc/amlogic/auge/audio_utils.h index c08470fe013d..d0444473a788 100644 --- a/sound/soc/amlogic/auge/audio_utils.h +++ b/sound/soc/amlogic/auge/audio_utils.h @@ -162,4 +162,6 @@ extern int audio_locker_get(void); extern void fratv_enable(bool enable); extern void fratv_src_select(int src); + +extern void cec_arc_enable(int src, bool enable); #endif diff --git a/sound/soc/amlogic/auge/card.c b/sound/soc/amlogic/auge/card.c index 1bf5aa6d69cf..6d71f8fcccef 100644 --- a/sound/soc/amlogic/auge/card.c +++ b/sound/soc/amlogic/auge/card.c @@ -982,12 +982,11 @@ static int aml_card_probe(struct platform_device *pdev) } if (priv->chipinfo && priv->chipinfo->eqdrc_fn) { - pr_info("eq/drc function enable\n"); + pr_info("eq/drc v1 function enable\n"); ret = card_add_effects_init(&priv->snd_card); if (ret < 0) - pr_warn_once("Failed to add audio effects controls\n"); - } else - pr_info("not support eq/drc function\n"); + pr_warn_once("Failed to add audio effects v1 controls\n"); + } if (priv->hp_det_enable == 1 || priv->mic_det_enable == 1) { audio_jack_detect(priv); diff --git a/sound/soc/amlogic/auge/ddr_mngr.c b/sound/soc/amlogic/auge/ddr_mngr.c index 6d3199fe429e..4d70dec390cd 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.c +++ b/sound/soc/amlogic/auge/ddr_mngr.c @@ -14,6 +14,7 @@ * more details. * */ +#define DEBUG #undef pr_fmt #define pr_fmt(fmt) "audio_ddr_mngr: " fmt @@ -23,132 +24,44 @@ #include #include +#include +#include + #include "regs.h" #include "ddr_mngr.h" #include "audio_utils.h" +#include "resample.h" #include "resample_hw.h" #include "effects_hw.h" +#include "effects_hw_v2.h" +#include "effects_v2.h" #include "pwrdet_hw.h" +#include "vad.h" #define DRV_NAME "audio-ddr-manager" static DEFINE_MUTEX(ddr_mutex); -#if 0 -struct ddr_desc { - /* start address of DDR */ - unsigned int start; - /* finish address of DDR */ - unsigned int finish; - /* interrupt address or counts of DDR blocks */ - unsigned int intrpt; - /* fifo total counts */ - unsigned int fifo_depth; - /* fifo start threshold */ - unsigned int fifo_thr; - enum ddr_types data_type; - unsigned int edian; - unsigned int pp_mode; - //unsigned int reg_base; - struct clk *ddr; - struct clk *ddr_arb; -}; -#endif - -struct ddr_chipinfo { - /* INT and Start address is same or separated */ - bool int_start_same_addr; - /* force finished */ - bool force_finished; - /* same source */ - bool same_src_fn; - /* insert channel number */ - bool insert_chnum; - /* source sel switch to ctrl1 - * for toddr, 0: source sel is controlled by ctrl0 - * 1: source sel is controlled by ctrl1 - * for frddr, 0: source sel is controlled by ctrl0 - * 1: source sel is controlled by ctrl2 - */ - bool src_sel_ctrl; - /* toddr number max - * 0: default, 3 toddr, axg, g12a, g12b - * 4: 4 toddr, tl1 - */ - int fifo_num; -}; - -struct toddr { - //struct ddr_desc dscrpt; - struct device *dev; - unsigned int resample: 1; - unsigned int ext_signed: 1; - unsigned int msb_bit; - unsigned int lsb_bit; - unsigned int reg_base; - unsigned int bitdepth; - unsigned int channels; - unsigned int rate; - enum toddr_src src; - unsigned int fifo_id; - - int is_lb; /* check whether for loopback */ - int irq; - bool in_use: 1; - struct aml_audio_controller *actrl; - struct ddr_chipinfo *chipinfo; -}; - -enum status { - DISABLED, - READY, /* controls has set enable, but ddr is not in running */ - RUNNING, -}; - -struct toddr_attach { - bool enable; - int status; - /* which module should be attached, - * check which toddr in use should be attached - */ - enum toddr_src attach_module; -}; - -struct frddr_attach { - bool enable; - int status; - /* which module for attach , - * check which frddr in use should be added - */ - enum frddr_dest attach_module; -}; - -struct frddr { - //struct ddr_desc dscrpt; - struct device *dev; - enum frddr_dest dest; - struct aml_audio_controller *actrl; - unsigned int reg_base; - unsigned int fifo_id; - int irq; - bool in_use; - struct ddr_chipinfo *chipinfo; -}; #define DDRMAX 4 static struct frddr frddrs[DDRMAX]; static struct toddr toddrs[DDRMAX]; /* resample */ -static struct toddr_attach attach_resample; -static void aml_check_resample(bool enable); -static bool aml_check_resample_module(int src); +static struct toddr_attach attach_resample_a; +static struct toddr_attach attach_resample_b; +static void aml_check_resample(struct toddr *to, bool enable); /* power detect */ static struct toddr_attach attach_pwrdet; static void aml_check_pwrdet(bool enable); static bool aml_check_pwrdet_module(int src); +/* VAD */ +static struct toddr_attach attach_vad; +static void aml_check_vad(struct toddr *to, bool enable); + + /* Audio EQ DRC */ static struct frddr_attach attach_aed; static void aml_check_aed(bool enable, int dst); @@ -189,7 +102,7 @@ static struct toddr *register_toddr_l(struct device *dev, to->dev = dev; to->actrl = actrl; to->in_use = true; - pr_info("toddrs[%d] registered by device %s\n", i, dev_name(dev)); + pr_debug("toddrs[%d] registered by device %s\n", i, dev_name(dev)); return to; } @@ -235,7 +148,7 @@ static int unregister_toddr_l(struct device *dev, void *data) to->dev = NULL; to->actrl = NULL; to->in_use = false; - pr_info("toddrs[%d] released by device %s\n", i, dev_name(dev)); + pr_debug("toddrs[%d] released by device %s\n", i, dev_name(dev)); return 0; } @@ -251,8 +164,6 @@ int fetch_toddr_index_by_src(int toddr_src) } } - pr_err("invalid toddr src\n"); - return -1; } @@ -267,8 +178,6 @@ struct toddr *fetch_toddr_by_src(int toddr_src) } } - pr_err("invalid toddr src\n"); - return NULL; } @@ -308,6 +217,9 @@ int aml_toddr_set_buf(struct toddr *to, unsigned int start, unsigned int reg_base = to->reg_base; unsigned int reg; + to->start_addr = start; + to->end_addr = end; + reg = calc_toddr_address(EE_AUDIO_TODDR_A_START_ADDR, reg_base); aml_audiobus_write(actrl, reg, start); reg = calc_toddr_address(EE_AUDIO_TODDR_A_FINISH_ADDR, reg_base); @@ -323,6 +235,41 @@ int aml_toddr_set_buf(struct toddr *to, unsigned int start, return 0; } +int aml_toddr_set_buf_startaddr(struct toddr *to, unsigned int start) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + to->start_addr = start; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_START_ADDR, reg_base); + aml_audiobus_write(actrl, reg, start); + + /* int address */ + if (to->chipinfo + && (!to->chipinfo->int_start_same_addr)) { + reg = calc_toddr_address(EE_AUDIO_TODDR_A_INIT_ADDR, reg_base); + aml_audiobus_write(actrl, reg, start); + } + + return 0; +} + +int aml_toddr_set_buf_endaddr(struct toddr *to, unsigned int end) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + to->end_addr = end; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_FINISH_ADDR, reg_base); + aml_audiobus_write(actrl, reg, end); + + return 0; +} + int aml_toddr_set_intrpt(struct toddr *to, unsigned int intrpt) { struct aml_audio_controller *actrl = to->actrl; @@ -347,6 +294,34 @@ unsigned int aml_toddr_get_position(struct toddr *to) return aml_audiobus_read(actrl, reg); } +unsigned int aml_toddr_get_addr(struct toddr *to, enum status_sel sel) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg_sel, reg, addr; + + reg_sel = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + aml_audiobus_update_bits(actrl, reg_sel, + 0xf << 8, + sel << 8); + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_STATUS2, reg_base); + addr = aml_audiobus_read(actrl, reg); + + if (sel == VAD_WAKEUP_ADDR) { + /* clear VAD addr/cnt */ + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base); + aml_audiobus_update_bits(actrl, reg, 0x1 << 1, 0x1 << 1); + } + + /* reset to default, current write addr */ + aml_audiobus_update_bits(actrl, reg_sel, + 0xf << 8, + 0x0 << 8); + + return addr; +} + void aml_toddr_enable(struct toddr *to, bool enable) { struct aml_audio_controller *actrl = to->actrl; @@ -357,12 +332,18 @@ void aml_toddr_enable(struct toddr *to, bool enable) aml_audiobus_update_bits(actrl, reg, 1<<31, enable<<31); /* check resample */ - if (aml_check_resample_module(to->src)) - aml_check_resample(enable); + aml_check_resample(to, enable); - /* check power detect */ - if (aml_check_pwrdet_module(to->src)) - aml_check_pwrdet(enable); + if (to->chipinfo + && to->chipinfo->wakeup) { + if (to->chipinfo->wakeup == 1) { + /* check power detect */ + if (aml_check_pwrdet_module(to->src)) + aml_check_pwrdet(enable); + } else if (to->chipinfo->wakeup == 2) + /* check VAD */ + aml_check_vad(to, enable); + } if (!enable) aml_audiobus_write(actrl, reg, 0x0); @@ -381,7 +362,7 @@ void aml_toddr_select_src(struct toddr *to, enum toddr_src src) if (loopback_check_enable(src)) { loopback_set_status(1); to->is_lb = 1; /* in loopback */ - src = LOOPBACK; + src = LOOPBACK_A; } if (to->chipinfo @@ -414,6 +395,40 @@ void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh) } aml_audiobus_update_bits(actrl, reg, mask, val); + + if (to->chipinfo && to->chipinfo->ugt) { + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base); + aml_audiobus_update_bits(actrl, reg, 0x0 << 0, 0x1 << 0); + } +} + +void aml_toddr_update_fifos_rd_th(struct toddr *to, int th) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg, mask, val; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + if (to->chipinfo + && to->chipinfo->src_sel_ctrl) { + mask = 0xfff << 12; + val = (th - 1) << 12; + } else { + mask = 0xff << 16; + val = (th - 1) << 16; + } + aml_audiobus_update_bits(actrl, reg, mask, val); +} + +void aml_toddr_force_finish(struct toddr *to) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + aml_audiobus_update_bits(actrl, reg, 1 << 25, 1 << 25); + aml_audiobus_update_bits(actrl, reg, 1 << 25, 0 << 25); } void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt) @@ -471,19 +486,62 @@ void aml_toddr_set_resample(struct toddr *to, bool enable) unsigned int reg_base = to->reg_base; unsigned int reg; - pr_info("toddr selects data to %s resample\n", - enable ? "enable" : "disable"); reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL0, reg_base); aml_audiobus_update_bits(actrl, reg, 1<<30, enable<<30); } -static void aml_set_resample(struct toddr *to, +void aml_toddr_set_resample_ab(struct toddr *to, int asrc_src_sel, bool enable) +{ + struct aml_audio_controller *actrl = to->actrl; + unsigned int reg_base = to->reg_base; + unsigned int reg; + + reg = calc_toddr_address(EE_AUDIO_TODDR_A_CTRL1, reg_base); + if (asrc_src_sel == 0) + aml_audiobus_update_bits(actrl, reg, 1 << 27, enable << 27); + else + aml_audiobus_update_bits(actrl, reg, 1 << 26, enable << 26); +} + +static void aml_resample_enable( + struct toddr_attach *p_attach_resample, bool enable) { + struct toddr *to = fetch_toddr_by_src(p_attach_resample->attach_module); + + if (!to) + return; + + if (to->chipinfo + && to->chipinfo->asrc_src_sel_ctrl) { + /* fix asrc_src_sel */ + switch (p_attach_resample->attach_module) { + case LOOPBACK_A: + to->asrc_src_sel = ASRC_LOOPBACK_A; + break; + case LOOPBACK_B: + to->asrc_src_sel = ASRC_LOOPBACK_B; + break; + default: + to->asrc_src_sel = to->fifo_id; + break; + } + } + + pr_info("toddr %d selects data to %s resample_%c for module:%s\n", + to->fifo_id, + enable ? "enable" : "disable", + (p_attach_resample->id == 0) ? 'a' : 'b', + toddr_src_get_str(p_attach_resample->attach_module) + ); + if (enable) { int bitwidth = to->bitdepth; /* channels and bit depth for resample */ - if ((to->src == SPDIFIN) && (bitwidth == 32)) { + if (to->chipinfo + && to->chipinfo->asrc_only_left_j + && (to->src == SPDIFIN) + && (bitwidth == 32)) { struct aml_audio_controller *actrl = to->actrl; unsigned int reg_base = to->reg_base; unsigned int reg; @@ -502,85 +560,103 @@ static void aml_set_resample(struct toddr *to, 0x7 << 24 | 0x7 << 13, endian << 24 | toddr_type << 13); } - resample_format_set(to->channels, bitwidth); + + resample_format_set(p_attach_resample->id, + to->channels, bitwidth); /* toddr index for resample */ - resample_src_select(to->fifo_id); + if (to->chipinfo + && to->chipinfo->asrc_src_sel_ctrl) + resample_src_select_ab(p_attach_resample->id, + to->asrc_src_sel); + else + resample_src_select(to->fifo_id); } /* resample enable or not */ - resample_enable(enable); + resample_enable(p_attach_resample->id, enable); + /* select reample data */ - aml_toddr_set_resample(to, enable); + if (to->chipinfo + && to->chipinfo->asrc_src_sel_ctrl) + aml_toddr_set_resample_ab(to, p_attach_resample->id, enable); + else + aml_toddr_set_resample(to, enable); } -void aml_resample_enable(bool enable, int resample_module) +void aml_set_resample(int id, bool enable, int resample_module) { - attach_resample.enable = enable; - attach_resample.attach_module = resample_module; + struct toddr_attach *p_attach_resample; - aml_check_resample(enable); -} + bool update_running = false; -static bool aml_check_resample_module(int src) -{ - bool is_module_resample = false; + if (id == 0) + p_attach_resample = &attach_resample_a; + else + p_attach_resample = &attach_resample_b; - if (attach_resample.enable - && (src == attach_resample.attach_module)) - is_module_resample = true; + p_attach_resample->enable = enable; + p_attach_resample->id = id; + p_attach_resample->attach_module = resample_module; - return is_module_resample; + if (enable) { + if ((p_attach_resample->status == DISABLED) + || (p_attach_resample->status == READY)) { + struct toddr *to = fetch_toddr_by_src( + p_attach_resample->attach_module); + + if (!to) { + p_attach_resample->status = READY; + } else { + p_attach_resample->status = RUNNING; + update_running = true; + pr_info("Capture with resample\n"); + } + } + } else { + if (p_attach_resample->status == RUNNING) + update_running = true; + + p_attach_resample->status = DISABLED; + } + + if (update_running) + aml_resample_enable(p_attach_resample, enable); } /* * when try to enable resample, if toddr is not in used, * set resample status as ready */ -static void aml_check_resample(bool enable) +static void aml_check_resample(struct toddr *to, bool enable) { + struct toddr_attach *p_attach_resample; + bool is_module_resample; + bool resample_b_check = false; + + p_attach_resample = &attach_resample_a; + +start_check: + is_module_resample = false; + if (p_attach_resample->enable + && (to->src == p_attach_resample->attach_module)) + is_module_resample = true; + /* resample in enable */ - if (attach_resample.enable) { - if (enable) { - /* check whether ready ? */ - if ((attach_resample.status == DISABLED) - || (attach_resample.status == READY)) { - struct toddr *to = fetch_toddr_by_src( - attach_resample.attach_module); + if (is_module_resample) { + if (enable) + p_attach_resample->status = RUNNING; + else + p_attach_resample->status = DISABLED; - if (!to) { - attach_resample.status = READY; - pr_info("not in capture, Resample is ready\n"); - } else { - attach_resample.status = RUNNING; - aml_set_resample(to, enable); - pr_info("Resample in running, module:%d, toddr:%d\n", - attach_resample.attach_module, - to->fifo_id); - } - } - } else { - if (attach_resample.status == RUNNING) { - struct toddr *to = fetch_toddr_by_src( - attach_resample.attach_module); + aml_resample_enable(p_attach_resample, enable); + } - aml_set_resample(to, enable); - attach_resample.status = DISABLED; - } - } - } else { - /* ensure resample is disabled */ - struct toddr *to = fetch_toddr_by_src( - attach_resample.attach_module); - - if (to) { - pr_info("Resample in running, disable it\n"); - - /* select reample data */ - aml_toddr_set_resample(to, false); - /* update resample status */ - attach_resample.status = DISABLED; - } + if ((!resample_b_check) + && (get_resample_module_num() == 2)) { + p_attach_resample = &attach_resample_b; + resample_b_check = true; + goto start_check; } } @@ -615,17 +691,18 @@ void aml_pwrdet_enable(bool enable, int pwrdet_module) if (!to) { attach_pwrdet.status = READY; - pr_info("not in capture, power detect is ready\n"); } else { attach_pwrdet.status = RUNNING; aml_set_pwrdet(to, enable); + pr_info("Capture with power detect\n"); } } } else { if (attach_pwrdet.status == RUNNING) { struct toddr *to = fetch_toddr_by_src(pwrdet_module); - aml_set_pwrdet(to, enable); + if (to) + aml_set_pwrdet(to, enable); } attach_pwrdet.status = DISABLED; } @@ -658,6 +735,79 @@ static void aml_check_pwrdet(bool enable) } } +static void aml_vad_enable( + struct toddr_attach *p_attach_vad, + bool enable) +{ + struct toddr *to = fetch_toddr_by_src(p_attach_vad->attach_module); + + if (!to) + return; + + vad_set_toddr_info(enable ? to : NULL); + + /* vad enable or not */ + vad_enable(enable); +} + +void aml_set_vad(bool enable, int module) +{ + struct toddr_attach *p_attach_vad = &attach_vad; + bool update_running = false; + + p_attach_vad->enable = enable; + p_attach_vad->attach_module = module; + + if (enable) { + if ((p_attach_vad->status == DISABLED) + || (p_attach_vad->status == READY)) { + struct toddr *to = fetch_toddr_by_src( + p_attach_vad->attach_module); + + if (!to) { + p_attach_vad->status = READY; + } else { + p_attach_vad->status = RUNNING; + update_running = true; + pr_info("Capture with VAD\n"); + } + } + } else { + if (p_attach_vad->status == RUNNING) + update_running = true; + + p_attach_vad->status = DISABLED; + } + + if (update_running) + aml_vad_enable(p_attach_vad, enable); +} + +/* + * when try to enable vad, if toddr is not in used, + * set vad status as ready + */ +static void aml_check_vad(struct toddr *to, bool enable) +{ + struct toddr_attach *p_attach_vad = &attach_vad; + bool is_vad = false; + + if (p_attach_vad->enable + && (to->src == p_attach_vad->attach_module)) + is_vad = true; + + /* vad in enable */ + if (is_vad) { + if (enable) + p_attach_vad->status = RUNNING; + else + p_attach_vad->status = DISABLED; + + aml_vad_enable(p_attach_vad, enable); + } +} + + /* from DDRS */ static struct frddr *register_frddr_l(struct device *dev, struct aml_audio_controller *actrl, @@ -693,7 +843,7 @@ static struct frddr *register_frddr_l(struct device *dev, from->dev = dev; from->actrl = actrl; from->in_use = true; - pr_info("frddrs[%d] registered by device %s\n", i, dev_name(dev)); + pr_debug("frddrs[%d] registered by device %s\n", i, dev_name(dev)); return from; } @@ -733,7 +883,7 @@ static int unregister_frddr_l(struct device *dev, void *data) from->dev = NULL; from->actrl = NULL; from->in_use = false; - pr_info("frddrs[%d] released by device %s\n", i, dev_name(dev)); + pr_debug("frddrs[%d] released by device %s\n", i, dev_name(dev)); return 0; } @@ -748,7 +898,6 @@ int fetch_frddr_index_by_src(int frddr_src) } } - pr_err("invalid frdd_src\n"); return -1; } @@ -763,8 +912,6 @@ struct frddr *fetch_frddr_by_src(int frddr_src) } } - pr_err("invalid frddr src\n"); - return NULL; } @@ -784,7 +931,8 @@ int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel) && (frddrs[i].fifo_id != current_fifo_id) && (frddrs[i].dest == ss_sel)) { - pr_info("ss_sel:%d used, invalid for share buffer\n", + pr_info(" frddr:%d, ss_sel:%d used, invalid for share buffer\n", + i, ss_sel); ret = 0; break; @@ -878,9 +1026,18 @@ void aml_frddr_enable(struct frddr *fr, bool enable) /* ensure disable before enable frddr */ aml_audiobus_update_bits(actrl, reg, 1<<31, enable<<31); - if (!enable) + if (!enable) { aml_audiobus_write(actrl, reg, 0x0); + /* clr src sel and its en */ + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + aml_audiobus_write(actrl, reg, 0x0); + } + } + /* check for Audio EQ/DRC */ if (aml_check_aed_module(fr->dest)) aml_check_aed(enable, fr->dest); @@ -926,8 +1083,6 @@ void aml_frddr_select_dst_ss(struct frddr *fr, unsigned int reg_base = fr->reg_base; unsigned int reg, ss_valid; - reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base); - ss_valid = aml_check_sharebuffer_valid(fr, dst); /* same source en */ @@ -936,21 +1091,54 @@ void aml_frddr_select_dst_ss(struct frddr *fr, && ss_valid) { int s_v = 0, s_m = 0; - switch (sel) { - case 1: - s_m = 0xf << 4; - s_v = enable ? (dst << 4 | 1 << 7) : 0 << 4; - break; - case 2: - s_m = 0xf << 8; - s_v = enable ? (dst << 8 | 1 << 11) : 0 << 8; - break; - default: - pr_warn_once("sel :%d is not supported for same source\n", - sel); - break; + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + + switch (sel) { + case 1: + s_m = 0x17 << 8; + s_v = enable ? + (dst << 8 | 1 << 12) : 0 << 8; + break; + case 2: + s_m = 0x17 << 16; + s_v = enable ? + (dst << 16 | 1 << 20) : 0 << 16; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } + s_m |= 0xff << 24; + if (enable) + s_v |= (fr->channels - 1) << 24; + else + s_v |= 0x0 << 24; + } else { + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL0, + reg_base); + + switch (sel) { + case 1: + s_m = 0xf << 4; + s_v = enable ? + (dst << 4 | 1 << 7) : 0 << 4; + break; + case 2: + s_m = 0xf << 8; + s_v = enable ? + (dst << 8 | 1 << 11) : 0 << 8; + break; + default: + pr_warn_once("sel :%d is not supported for same source\n", + sel); + break; + } } - pr_info("%s sel:%d, dst_src:%d\n", + pr_debug("%s sel:%d, dst_src:%d\n", __func__, sel, dst); aml_audiobus_update_bits(actrl, reg, s_m, s_v); } @@ -967,6 +1155,11 @@ void aml_frddr_set_fifos(struct frddr *fr, aml_audiobus_update_bits(actrl, reg, 0xffff<<16 | 0xf<<8, (depth - 1)<<24 | (thresh - 1)<<16 | 2<<8); + + if (fr->chipinfo && fr->chipinfo->ugt) { + reg = calc_toddr_address(EE_AUDIO_FRDDR_A_CTRL0, reg_base); + aml_audiobus_update_bits(actrl, reg, 0x0 << 0, 0x1 << 0); + } } unsigned int aml_frddr_get_fifo_id(struct frddr *fr) @@ -974,23 +1167,57 @@ unsigned int aml_frddr_get_fifo_id(struct frddr *fr) return fr->fifo_id; } -static void aml_set_aed(struct frddr *fr, bool enable) +void aml_frddr_set_format(struct frddr *fr, + unsigned int chnum, + unsigned int msb, + unsigned int frddr_type) { - if (enable) { - /* frddr type and bit depth for AED */ - aml_aed_format_set(fr->dest); - } - aed_src_select(enable, fr->dest, fr->fifo_id); + fr->channels = chnum; + fr->msb = msb; + fr->type = frddr_type; } -void aml_aed_enable(bool enable, int aed_module) +static void aml_aed_enable(struct frddr_attach *p_attach_aed, bool enable) { + struct frddr *fr = fetch_frddr_by_src(p_attach_aed->attach_module); + + + if (check_aed_v2()) { + if (fr->chipinfo + && fr->chipinfo->src_sel_ctrl) { + struct aml_audio_controller *actrl = fr->actrl; + unsigned int reg_base = fr->reg_base; + unsigned int reg; + + reg = calc_frddr_address(EE_AUDIO_FRDDR_A_CTRL2, + reg_base); + aml_audiobus_update_bits(actrl, + reg, 0x1 << 3, enable << 3); + } + + aed_set_ctrl(enable, 0, p_attach_aed->attach_module); + aed_set_format(fr->msb, fr->type); + aed_enable(enable, fr->dest, fr->fifo_id); + } else { + if (enable) { + /* frddr type and bit depth for AED */ + aml_aed_format_set(fr->dest); + } + aed_src_select(enable, fr->dest, fr->fifo_id); + } +} + +void aml_set_aed(bool enable, int aed_module) +{ + bool update_running = false; + /* when try to enable AED, if frddr is not in used, * set AED status as ready */ attach_aed.enable = enable; attach_aed.attach_module = aed_module; + if (enable) { if ((attach_aed.status == DISABLED) || (attach_aed.status == READY)) { @@ -998,20 +1225,21 @@ void aml_aed_enable(bool enable, int aed_module) if (!fr) { attach_aed.status = READY; - pr_info("not in playback, AED is ready"); } else { attach_aed.status = RUNNING; - aml_set_aed(fr, enable); + update_running = true; + pr_info("Playback with AED\n"); } } } else { - if (attach_aed.status == RUNNING) { - struct frddr *fr = fetch_frddr_by_src(aed_module); + if (attach_aed.status == RUNNING) + update_running = true; - aml_set_aed(fr, enable); - } attach_aed.status = DISABLED; } + + if (update_running) + aml_aed_enable(&attach_aed, enable); } static bool aml_check_aed_module(int dst) @@ -1033,14 +1261,12 @@ static void aml_check_aed(bool enable, int dst) /* AED in enable */ if (attach_aed.enable) { - if (enable) { - /* check whether ready ? */ - if (attach_aed.status == READY) - aml_aed_enable(true, attach_aed.attach_module); - } else { - if (attach_aed.status == RUNNING) - attach_aed.status = READY; - } + if (enable) + attach_aed.status = RUNNING; + else + attach_aed.status = DISABLED; + + aml_aed_enable(&attach_aed, enable); } } @@ -1142,7 +1368,7 @@ static int toddr_src_enum_set(struct snd_kcontrol *kcontrol, static int frddr_src_idx = -1; static const char *const frddr_src_sel_texts[] = { - "TDMOUT_A", "TDMOUT_B", "TDMOUT_C", "SPDIFOUT", "SPDIFOUT_B" + "TDMOUT_A", "TDMOUT_B", "TDMOUT_C", "SPDIFOUT_A", "SPDIFOUT_B" }; static const struct soc_enum frddr_output_source_enum = @@ -1207,16 +1433,23 @@ int card_add_ddr_kcontrols(struct snd_soc_card *card) static struct ddr_chipinfo axg_ddr_chipinfo = { .int_start_same_addr = true, + .asrc_only_left_j = true, + .wakeup = 1, }; static struct ddr_chipinfo g12a_ddr_chipinfo = { .same_src_fn = true, + .asrc_only_left_j = true, + .wakeup = 1, }; static struct ddr_chipinfo tl1_ddr_chipinfo = { .same_src_fn = true, + .ugt = true, .src_sel_ctrl = true, + .asrc_src_sel_ctrl = true, .fifo_num = 4, + .wakeup = 2, }; static const struct of_device_id aml_ddr_mngr_device_id[] = { @@ -1236,11 +1469,45 @@ static const struct of_device_id aml_ddr_mngr_device_id[] = { }; MODULE_DEVICE_TABLE(of, aml_ddr_mngr_device_id); +static bool pm_audio_in_suspend; + +void pm_audio_set_suspend(bool is_suspend) +{ + pm_audio_in_suspend = is_suspend; +} + +bool pm_audio_is_suspend(void) +{ + return pm_audio_in_suspend; +} + +/* Detects a suspend and resume event */ +static int ddr_pm_event(struct notifier_block *notifier, + unsigned long pm_event, void *unused) +{ + pr_info("%s, pm_event:%lu\n", __func__, pm_event); + + switch (pm_event) { + case PM_SUSPEND_PREPARE: + pm_audio_set_suspend(true); + break; + case PM_POST_SUSPEND: + break; + default: + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block ddr_pm_notifier_block = { + .notifier_call = ddr_pm_event, +}; + static int aml_ddr_mngr_platform_probe(struct platform_device *pdev) { struct ddr_chipinfo *p_ddr_chipinfo; int ddr_num = 3; /* early chipset support max 3 ddr num */ - int i; + int i, ret; p_ddr_chipinfo = (struct ddr_chipinfo *) of_device_get_match_data(&pdev->dev); @@ -1304,6 +1571,12 @@ static int aml_ddr_mngr_platform_probe(struct platform_device *pdev) frddrs[DDR_D].fifo_id = DDR_D; } } + + ret = register_pm_notifier(&ddr_pm_notifier_block); + if (ret) + pr_warn("[%s] failed to register PM notifier %d\n", + __func__, ret); + return 0; } diff --git a/sound/soc/amlogic/auge/ddr_mngr.h b/sound/soc/amlogic/auge/ddr_mngr.h index 461ee9f7b978..ab1c795b64b1 100644 --- a/sound/soc/amlogic/auge/ddr_mngr.h +++ b/sound/soc/amlogic/auge/ddr_mngr.h @@ -49,21 +49,40 @@ enum toddr_src { PDMIN, FRATV, /* NONE for axg, g12a, g12b */ TDMIN_LB, - LOOPBACK, + LOOPBACK_A, FRHDMIRX, /* from tl1 chipset*/ LOOPBACK_B, SPDIFIN_LB, VAD, }; +enum resample_src { + ASRC_TODDR_A, + ASRC_TODDR_B, + ASRC_TODDR_C, + ASRC_TODDR_D, /* from tl1 chipset */ + ASRC_LOOPBACK_A, + ASRC_LOOPBACK_B, +}; + enum frddr_dest { TDMOUT_A, TDMOUT_B, TDMOUT_C, - SPDIFOUT, + SPDIFOUT_A, SPDIFOUT_B, }; +enum status_sel { + CURRENT_DDR_ADDR, + NEXT_FINISH_ADDR, + COUNT_CURRENT_DDR_ACK, + COUNT_NEXT_FINISH_DDR_ACK, + VAD_WAKEUP_ADDR, /* from tl1, vad */ + VAD_FS_ADDR, + VAD_FIFO_CNT, +}; + struct toddr_fmt { unsigned int type; unsigned int msb; @@ -74,6 +93,140 @@ struct toddr_fmt { unsigned int rate; }; +#if 0 +struct ddr_desc { + /* start address of DDR */ + unsigned int start; + /* finish address of DDR */ + unsigned int finish; + /* interrupt address or counts of DDR blocks */ + unsigned int intrpt; + /* fifo total counts */ + unsigned int fifo_depth; + /* fifo start threshold */ + unsigned int fifo_thr; + enum ddr_types data_type; + unsigned int edian; + unsigned int pp_mode; + //unsigned int reg_base; + struct clk *ddr; + struct clk *ddr_arb; +}; +#endif + +struct ddr_chipinfo { + /* INT and Start address is same or separated */ + bool int_start_same_addr; + /* force finished */ + bool force_finished; + /* same source */ + bool same_src_fn; + /* insert channel number */ + bool insert_chnum; + + /* ddr bus in urgent */ + bool ugt; + + /* source sel switch to ctrl1 + * for toddr, 0: source sel is controlled by ctrl0 + * 1: source sel is controlled by ctrl1 + * for frddr, 0: source sel is controlled by ctrl0 + * 1: source sel is controlled by ctrl2 + */ + bool src_sel_ctrl; + + /* + * resample source sel switch + * resample : from ctrl0 to ctrl3 + * toddr : from ctrl0 to ctrl1 + */ + bool asrc_src_sel_ctrl; + /* spdif in 32bit, only support left justified */ + bool asrc_only_left_j; + + /* toddr number max + * 0: default, 3 toddr, axg, g12a, g12b + * 4: 4 toddr, tl1 + */ + int fifo_num; + + /* power detect or VAD + * 0: disabled + * 1: power detect + * 2: vad + */ + int wakeup; +}; + +struct toddr { + //struct ddr_desc dscrpt; + struct device *dev; + unsigned int resample: 1; + unsigned int ext_signed: 1; + unsigned int msb_bit; + unsigned int lsb_bit; + unsigned int reg_base; + unsigned int bitdepth; + unsigned int channels; + unsigned int rate; + + unsigned int start_addr; + unsigned int end_addr; + + enum toddr_src src; + unsigned int fifo_id; + + unsigned int asrc_src_sel; + + int is_lb; /* check whether for loopback */ + int irq; + bool in_use: 1; + struct aml_audio_controller *actrl; + struct ddr_chipinfo *chipinfo; +}; + +enum status { + DISABLED, + READY, /* controls has set enable, but ddr is not in running */ + RUNNING, +}; + +struct toddr_attach { + bool enable; + int id; + int status; + /* which module should be attached, + * check which toddr in use should be attached + */ + enum toddr_src attach_module; +}; + +struct frddr_attach { + bool enable; + int status; + /* which module for attach , + * check which frddr in use should be added + */ + enum frddr_dest attach_module; +}; + +struct frddr { + //struct ddr_desc dscrpt; + struct device *dev; + enum frddr_dest dest; + struct aml_audio_controller *actrl; + unsigned int reg_base; + unsigned int fifo_id; + + unsigned int channels; + unsigned int msb; + unsigned int type; + + int irq; + bool in_use; + struct ddr_chipinfo *chipinfo; +}; + /* to ddrs */ int fetch_toddr_index_by_src(int toddr_src); struct toddr *fetch_toddr_by_src(int toddr_src); @@ -83,20 +236,28 @@ struct toddr *aml_audio_register_toddr(struct device *dev, int aml_audio_unregister_toddr(struct device *dev, void *data); int aml_toddr_set_buf(struct toddr *to, unsigned int start, unsigned int end); +int aml_toddr_set_buf_startaddr(struct toddr *to, unsigned int start); +int aml_toddr_set_buf_endaddr(struct toddr *to, unsigned int end); + int aml_toddr_set_intrpt(struct toddr *to, unsigned int intrpt); unsigned int aml_toddr_get_position(struct toddr *to); +unsigned int aml_toddr_get_addr(struct toddr *to, enum status_sel sel); void aml_toddr_select_src(struct toddr *to, enum toddr_src); void aml_toddr_enable(struct toddr *to, bool enable); void aml_toddr_set_fifos(struct toddr *to, unsigned int thresh); +void aml_toddr_update_fifos_rd_th(struct toddr *to, int th); +void aml_toddr_force_finish(struct toddr *to); void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt); void aml_toddr_insert_chanum(struct toddr *to); unsigned int aml_toddr_read(struct toddr *to); void aml_toddr_write(struct toddr *to, unsigned int val); /* resample */ -void aml_resample_enable(bool enable, int resample_module); +void aml_set_resample(int id, bool enable, int resample_module); /* power detect */ void aml_pwrdet_enable(bool enable, int pwrdet_module); +/* Voice Activity Detection */ +void aml_set_vad(bool enable, int module); /* from ddrs */ int fetch_frddr_index_by_src(int frddr_src); @@ -120,8 +281,12 @@ int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel); void aml_frddr_set_fifos(struct frddr *fr, unsigned int depth, unsigned int thresh); unsigned int aml_frddr_get_fifo_id(struct frddr *fr); +void aml_frddr_set_format(struct frddr *fr, + unsigned int chnum, + unsigned int msb, + unsigned int frddr_type); /* audio eq drc */ -void aml_aed_enable(bool enable, int aed_module); +void aml_set_aed(bool enable, int aed_module); void frddr_init_without_mngr(unsigned int frddr_index, unsigned int src0_sel); void frddr_deinit_without_mngr(unsigned int frddr_index); @@ -133,5 +298,8 @@ const char *frddr_src_get_str(int idx); int card_add_ddr_kcontrols(struct snd_soc_card *card); +void pm_audio_set_suspend(bool is_suspend); +bool pm_audio_is_suspend(void); + #endif diff --git a/sound/soc/amlogic/auge/effects.c b/sound/soc/amlogic/auge/effects.c index 5ce778d820dd..dc3744438ead 100644 --- a/sound/soc/amlogic/auge/effects.c +++ b/sound/soc/amlogic/auge/effects.c @@ -65,7 +65,7 @@ static const char *const aed_req_module_texts[] = { "TDMOUT_A", "TDMOUT_B", "TDMOUT_C", - "SPDIFOUT", + "SPDIFOUT_A", "SPDIFOUT_B", }; @@ -145,7 +145,7 @@ static int mixer_set_EQ(struct snd_kcontrol *kcontrol, aed_set_eq(value, aml_EQ_param_length, &aml_EQ_param[0]); eqdrc_module = aed_get_req_sel(0); - aml_aed_enable(value, eqdrc_module); + aml_set_aed(value, eqdrc_module); return 0; } @@ -160,7 +160,7 @@ static int mixer_set_DRC_params(struct snd_kcontrol *kcontrol, aml_DRC_param_length, &aml_drc_tko_table[0]); eqdrc_module = aed_get_req_sel(0); - aml_aed_enable(value, eqdrc_module); + aml_set_aed(value, eqdrc_module); return 0; } @@ -198,15 +198,15 @@ static const struct snd_kcontrol_new snd_eqdrc_controls[] = { mixer_eqdrc_read, mixer_eqdrc_write), SOC_SINGLE_EXT("EQ/DRC Channel Mask", - AED_TOP_CTL, 18, 0xff, 0, + AED_TOP_CTL_G12X, 18, 0xff, 0, mixer_eqdrc_read, mixer_eqdrc_write), SOC_SINGLE_EXT("EQ/DRC Lane Mask", - AED_TOP_CTL, 14, 0xf, 0, + AED_TOP_CTL_G12X, 14, 0xf, 0, mixer_eqdrc_read, mixer_eqdrc_write), SOC_SINGLE_EXT("EQ/DRC Req Module", - AED_TOP_REQ_CTL, 0, 0x7, 0, + AED_TOP_REQ_CTL_G12X, 0, 0x7, 0, mixer_eqdrc_read, mixer_set_AED_req_ctrl), SOC_SINGLE_EXT("EQ enable", @@ -243,8 +243,7 @@ int card_add_effects_init(struct snd_soc_card *card) audio_effect_np = of_parse_phandle(card->dev->of_node, "aml-audio-card,effect", 0); if (audio_effect_np == NULL) { - pr_err("error: failed to find node %s for eq/drc info!\n", - "audio_effect"); + pr_warn("no node %s for eq/drc info!\n", "audio_effect"); return -EINVAL; } diff --git a/sound/soc/amlogic/auge/effects_hw.c b/sound/soc/amlogic/auge/effects_hw.c index a2d26770c1ab..a54b89396033 100644 --- a/sound/soc/amlogic/auge/effects_hw.c +++ b/sound/soc/amlogic/auge/effects_hw.c @@ -82,13 +82,13 @@ void aed_req_sel(bool enable, int sel, int req_module) return; } - eqdrc_update_bits(AED_TOP_REQ_CTL, mask_offset, val_offset); + eqdrc_update_bits(AED_TOP_REQ_CTL_G12X, mask_offset, val_offset); } /* get eq/drc module */ int aed_get_req_sel(int sel) { - int val = eqdrc_read(AED_TOP_REQ_CTL); + int val = eqdrc_read(AED_TOP_REQ_CTL_G12X); int mask_off; switch (sel) { @@ -170,7 +170,7 @@ int aml_aed_format_set(int frddr_dst) return -EINVAL; } - eqdrc_update_bits(AED_TOP_CTL, 0x7 << 11 | 0x1f << 6, + eqdrc_update_bits(AED_TOP_CTL_G12X, 0x7 << 11 | 0x1f << 6, frddr_type << 11 | width << 6); return 0; @@ -192,17 +192,17 @@ void aed_src_select(bool enable, int frddr_dst, int fifo_id) aed_req_sel(enable, 0, frddr_dst); /* AED module, sel & enable */ - eqdrc_update_bits(AED_TOP_CTL, + eqdrc_update_bits(AED_TOP_CTL_G12X, 0x3 << 4 | 0x1 << 0, fifo_id << 4 | enable << 0); } void aed_set_lane(int lane_mask) { - eqdrc_update_bits(AED_TOP_CTL, 0xf << 14, lane_mask << 14); + eqdrc_update_bits(AED_TOP_CTL_G12X, 0xf << 14, lane_mask << 14); } void aed_set_channel(int channel_mask) { - eqdrc_update_bits(AED_TOP_CTL, 0xff << 18, channel_mask << 18); + eqdrc_update_bits(AED_TOP_CTL_G12X, 0xff << 18, channel_mask << 18); } diff --git a/sound/soc/amlogic/auge/effects_hw_v2.c b/sound/soc/amlogic/auge/effects_hw_v2.c new file mode 100644 index 000000000000..6c1e1a60013f --- /dev/null +++ b/sound/soc/amlogic/auge/effects_hw_v2.c @@ -0,0 +1,236 @@ +/* + * sound/soc/amlogic/auge/effect_hw_v2.c + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#include + +#include "effects_hw_v2.h" +#include "regs.h" +#include "iomap.h" + +#include "tdm_hw.h" +#include "spdif_hw.h" + +void aed_set_ram_coeff(int len, int *params) +{ + int i, ctrl_v; + + for (i = 0; i < len; i++) { + ctrl_v = (i << 2) | (0x1 << 1) | (0x1 << 0); + eqdrc_write(AED_COEF_RAM_DATA, params[i]); + eqdrc_write(AED_COEF_RAM_CNTL, ctrl_v); + } +} + +void aed_set_multiband_drc_coeff(int len, int *params) +{ + int band_len = len / 3, i, j; + int offset = AED_MDRC_RMS_COEF10 - AED_MDRC_RMS_COEF00; + int reg = AED_MDRC_RMS_COEF00; + + for (i = 0; i < 3; i++) + for (j = 0; j < band_len; j++) + eqdrc_write(reg + i * offset + j, + params[i * band_len + j]); + + eqdrc_write(AED_MDRC_THD0, 0xf6000000); + eqdrc_write(AED_MDRC_K0, 0x20000); + eqdrc_write(AED_MDRC_OFFSET0, 0x200); + eqdrc_write(AED_MDRC_LOW_GAIN, 0x40000); + + eqdrc_write(AED_MDRC_THD1, 0xfb000000); + eqdrc_write(AED_MDRC_K1, 0x26666); + eqdrc_write(AED_MDRC_OFFSET1, 0x200); + eqdrc_write(AED_MDRC_MID_GAIN, 0x40000); + + eqdrc_write(AED_MDRC_THD2, 0xf1000000); + eqdrc_write(AED_MDRC_K2, 0x2cccc); + eqdrc_write(AED_MDRC_OFFSET2, 0x200); + eqdrc_write(AED_MDRC_HIGH_GAIN, 0x40000); +} + +void aed_set_fullband_drc_coeff(int len, int *params) +{ + int i; + + for (i = 0; i < len; i++) + eqdrc_write(AED_DRC_RELEASE_COEF00 + i, + params[i]); + + eqdrc_write(AED_DRC_RMS_COEF0, 0x34ebb); + eqdrc_write(AED_DRC_RMS_COEF1, 0x7cb145); + eqdrc_write(AED_DRC_THD0, 0xf7000000); + eqdrc_write(AED_DRC_THD1, 0xf6000000); + eqdrc_write(AED_DRC_THD2, 0xec000000); + eqdrc_write(AED_DRC_THD3, 0xe2000000); + eqdrc_write(AED_DRC_THD4, 0xce000000); + eqdrc_write(AED_DRC_K0, 0x20000); + eqdrc_write(AED_DRC_K1, 0x46666); + eqdrc_write(AED_DRC_K2, 0x40000); + eqdrc_write(AED_DRC_K3, 0x39999); + eqdrc_write(AED_DRC_K4, 0x33333); + eqdrc_write(AED_DRC_K5, 0x4cccc); + eqdrc_write(AED_DRC_THD_OUT0, 0xf5e66667); + eqdrc_write(AED_DRC_THD_OUT1, 0xebe66667); + eqdrc_write(AED_DRC_THD_OUT2, 0xe2e66667); + eqdrc_write(AED_DRC_THD_OUT3, 0xd2e66667); + eqdrc_write(AED_DRC_OFFSET, 0x100); + eqdrc_write(AED_DRC_LOOPBACK_CNTL, (144 << 0)); +} + +static void aed_set_mixer_params(void) +{ + eqdrc_write(AED_MIX0_LL, 0x40000); + eqdrc_write(AED_MIX0_RL, 0x0); + eqdrc_write(AED_MIX0_LR, 0x0); + eqdrc_write(AED_MIX0_RR, 0x40000); + eqdrc_write(AED_CLIP_THD, 0x7fffff); +} + +void aed_dc_enable(bool enable) +{ + eqdrc_write(AED_DC_EN, enable << 0); +} + +void aed_nd_enable(bool enable) +{ + if (enable) { + eqdrc_write(AED_ND_LOW_THD, 0x100); + eqdrc_write(AED_ND_HIGH_THD, 0x200); + eqdrc_write(AED_ND_CNT_THD, 0x100); + eqdrc_write(AED_ND_SUM_NUM, 0x200); + eqdrc_write(AED_ND_CZ_NUM, 0x800); + eqdrc_write(AED_ND_SUM_THD0, 0x20000); + eqdrc_write(AED_ND_SUM_THD1, 0x30000); + eqdrc_write(AED_ND_CZ_THD0, 0x200); + eqdrc_write(AED_ND_CZ_THD1, 0x100); + eqdrc_write(AED_ND_COND_CNTL, 0x3f); + eqdrc_write(AED_ND_RELEASE_COEF0, 0x3263a); + eqdrc_write(AED_ND_RELEASE_COEF1, 0x7cd9c6); + eqdrc_write(AED_ND_ATTACK_COEF0, 0x5188); + eqdrc_write(AED_ND_ATTACK_COEF1, 0x7fae78); + } + + eqdrc_write(AED_ND_CNTL, (enable << 0)|(3 << 1)); +} + +void aed_eq_enable(int idx, bool enable) +{ + eqdrc_update_bits(AED_EQ_EN, 0x1 << idx, enable << idx); + eqdrc_update_bits(AED_EQ_TAP_CNTL, 0x1f << (5 * idx), 10 << (5 * idx)); +} + +void aed_multiband_drc_enable(bool enable) +{ + eqdrc_write(AED_MDRC_CNTL, + (1 << 16) | /* mdrc_pow_sel */ + (enable << 8) | /* mdrc_all_en */ + (7 << 3) | /* mdrc_rms_mode[2:0] */ + (7 << 0) /* mdrc_en[2:0] */ + ); +} + +void aed_fullband_drc_enable(bool enable) +{ + eqdrc_write(AED_DRC_CNTL, + (5 << 3) | /* drc_tap */ + (enable << 0) /* drc_en */ + ); +} + +void aed_set_EQ_volume( + unsigned int master_vol, + unsigned int Lch_vol, + unsigned int Rch_vol) +{ + eqdrc_write(AED_EQ_VOLUME, + (0 << 30) | /* volume step: 0.125dB */ + (master_vol << 16) | /* master volume: 0dB */ + (Rch_vol << 8) | /* channel 2 volume: 0dB */ + (Lch_vol << 0) /* channel 1 volume: 0dB */ + ); + eqdrc_write(AED_EQ_VOLUME_SLEW_CNT, 0x40); + eqdrc_write(AED_MUTE, 0); +} + +void aed_set_lane_and_channels(int lane_mask, int ch_mask) +{ + eqdrc_update_bits(AED_TOP_CTL, + 0xff << 18 | 0xf << 14, + ch_mask << 18 | lane_mask << 14); +} + +void aed_set_ctrl(bool enable, int sel, int module) +{ + int mask = 0, val = 0; + + switch (sel) { + case 0: /* REQ_SEL0 */ + mask = 0xf << 0; + val = 0x1 << 3 | module << 0; + break; + case 1: /* REQ_SEL1 */ + mask = 0xf << 4; + val = 0x1 << 7 | module << 4; + break; + case 2: /* REQ_SEL2 */ + mask = 0xf << 8; + val = 0x1 << 11 | module << 8; + break; + default: + pr_err("unknown AED req_sel:%d, module:%d\n", + sel, module); + return; + } + eqdrc_update_bits(AED_TOP_REQ_CTL, mask, val); + + /* Effect Module */ + if (module >= 3) { + /* SPDIFOUT A/B */ + aml_spdifout_select_aed(enable, module - 3); + } else if (module < 3 && module >= 0) { + /* TDMOUT A/B/C */ + aml_tdmout_select_aed(enable, module); + } else + pr_err("unknown module:%d for AED\n", module); + +} + +void aed_set_format(int msb, int frddr_type) +{ + eqdrc_update_bits(AED_TOP_CTL, + 0x7 << 11 | 0x1f << 6, + frddr_type << 11 | msb << 6); +} + +void aed_enable(bool enable, int frddr_dst, int fifo_id) +{ + if (enable) { + eqdrc_write(AED_ED_CNTL, 0x1); + eqdrc_write(AED_ED_CNTL, 0x0); + + eqdrc_update_bits(AED_TOP_CTL, 0x1 << 1, 0x1 << 1); + eqdrc_update_bits(AED_TOP_CTL, 0x1 << 2, 0x1 << 2); + + aed_set_mixer_params(); + } else + eqdrc_update_bits(AED_TOP_CTL, 0x3 << 1, 0x0 << 1); + + eqdrc_update_bits(AED_TOP_CTL, 0x1 << 0, enable << 0); + + /* start en */ + if (enable) + eqdrc_update_bits(AED_TOP_CTL, 0x1 << 31, 0x1 << 31); +} diff --git a/sound/soc/amlogic/auge/effects_hw_v2.h b/sound/soc/amlogic/auge/effects_hw_v2.h new file mode 100644 index 000000000000..7c13e7fe6436 --- /dev/null +++ b/sound/soc/amlogic/auge/effects_hw_v2.h @@ -0,0 +1,37 @@ +/* + * sound/soc/amlogic/auge/effects_hw_v2.h + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#ifndef __EFFECTS_HW_V2_H__ +#define __EFFECTS_HW_V2_H__ +#include + +void aed_set_ram_coeff(int len, int *params); +void aed_set_multiband_drc_coeff(int len, int *params); +void aed_set_fullband_drc_coeff(int len, int *params); +void aed_dc_enable(bool enable); +void aed_nd_enable(bool enable); +void aed_eq_enable(int idx, bool enable); +void aed_multiband_drc_enable(bool enable); +void aed_fullband_drc_enable(bool enable); +void aed_set_EQ_volume( + unsigned int master_volume, + unsigned int Lch_vol, + unsigned int Rch_vol); +void aed_set_lane_and_channels(int lane_mask, int ch_mask); +void aed_set_ctrl(bool enable, int sel, int module); +void aed_set_format(int msb, int frddr_type); +void aed_enable(bool enable, int frddr_dst, int fifo_id); +#endif diff --git a/sound/soc/amlogic/auge/effects_hw_v2_coeff.c b/sound/soc/amlogic/auge/effects_hw_v2_coeff.c new file mode 100644 index 000000000000..903883f4c97c --- /dev/null +++ b/sound/soc/amlogic/auge/effects_hw_v2_coeff.c @@ -0,0 +1,298 @@ +/* + * sound/soc/amlogic/auge/effects_hw_v2_coeff.c + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#define AED_EQ_LENGTH 225 +#define AED_MULTIBAND_DRC_LENGTH 18 +#define AED_FULLBAND_DRC_LENGTH 24 + +static int eq_coeff[] = { + /* 0 */ 0x7fd51b, + /* 1 */ 0x30055c9, + /* 2 */ 0x7fd51b, + /* 3 */ 0x30055e6, + /* 4 */ 0x7faa53, + /* 5 */ 0x7ed219, + /* 6 */ 0x3025bce, + /* 7 */ 0x7ed219, + /* 8 */ 0x3025e96, + /* 9 */ 0x7da6fb, + /* 10 */ 0x7ed219, + /* 11 */ 0x3025bce, + /* 12 */ 0x7ed219, + /* 13 */ 0x3025e96, + /* 14 */ 0x7da6fb, + /* 15 */ 0xdf71e0, + /* 16 */ 0x2411c40, + /* 17 */ 0xdf71e0, + /* 18 */ 0x304bd12, + /* 19 */ 0x7b58fb, + /* 20 */ 0x7d8252, + /* 21 */ 0x30bb7df, + /* 22 */ 0x771ba1, + /* 23 */ 0x30bb7df, + /* 24 */ 0x749df4, + /* 25 */ 0x79f87b, + /* 26 */ 0x31971e4, + /* 27 */ 0x6ddabe, + /* 28 */ 0x31971e4, + /* 29 */ 0x67d339, + /* 30 */ 0x84f8f3, + /* 31 */ 0x31d2c91, + /* 32 */ 0x62ebbf, + /* 33 */ 0x31d2c91, + /* 34 */ 0x67e4b1, + /* 35 */ 0x711f0e, + /* 36 */ 0x3543f10, + /* 37 */ 0x4ae2f0, + /* 38 */ 0x3543f10, + /* 39 */ 0x3c01ff, + /* 40 */ 0xaaf457, + /* 41 */ 0x3831bd5, + /* 42 */ 0xfb150, + /* 43 */ 0x3831bd5, + /* 44 */ 0x3aa5a8, + /* 45 */ 0x65b5d1, + /* 46 */ 0xe3390, + /* 47 */ 0x2226c8, + /* 48 */ 0xe3390, + /* 49 */ 0x7dc99, + /* 50 */ 0x358660, + /* 51 */ 0x6b0cc1, + /* 52 */ 0x358660, + /* 53 */ 0x3b418e, + /* 54 */ 0x1ad7f4, + /* 55 */ 0x800000, + /* 56 */ 0x0, + /* 57 */ 0x0, + /* 58 */ 0x0, + /* 59 */ 0x0, + /* 60 */ 0x800000, + /* 61 */ 0x0, + /* 62 */ 0x0, + /* 63 */ 0x0, + /* 64 */ 0x0, + /* 65 */ 0x800000, + /* 66 */ 0x0, + /* 67 */ 0x0, + /* 68 */ 0x0, + /* 69 */ 0x0, + /* 70 */ 0x800000, + /* 71 */ 0x0, + /* 72 */ 0x0, + /* 73 */ 0x0, + /* 74 */ 0x0, + /* 75 */ 0x800000, + /* 76 */ 0x0, + /* 77 */ 0x0, + /* 78 */ 0x0, + /* 79 */ 0x0, + /* 80 */ 0x800000, + /* 81 */ 0x0, + /* 82 */ 0x0, + /* 83 */ 0x0, + /* 84 */ 0x0, + /* 85 */ 0x800000, + /* 86 */ 0x0, + /* 87 */ 0x0, + /* 88 */ 0x0, + /* 89 */ 0x0, + /* 90 */ 0x800000, + /* 91 */ 0x0, + /* 92 */ 0x0, + /* 93 */ 0x0, + /* 94 */ 0x0, + /* 95 */ 0x800000, + /* 96 */ 0x0, + /* 97 */ 0x0, + /* 98 */ 0x0, + /* 99 */ 0x0, + /* 100 */ 0x800000, + /* 101 */ 0x0, + /* 102 */ 0x0, + /* 103 */ 0x0, + /* 104 */ 0x0, + /* 105 */ 0x7ed219, + /* 106 */ 0x3025bce, + /* 107 */ 0x7ed219, + /* 108 */ 0x3025e96, + /* 109 */ 0x7da6fb, + /* 110 */ 0x7ed219, + /* 111 */ 0x3025bce, + /* 112 */ 0x7ed219, + /* 113 */ 0x3025e96, + /* 114 */ 0x7da6fb, + /* 115 */ 0xdf71e0, + /* 116 */ 0x2411c40, + /* 117 */ 0xdf71e0, + /* 118 */ 0x304bd12, + /* 119 */ 0x7b58fb, + /* 120 */ 0x7d8252, + /* 121 */ 0x30bb7df, + /* 122 */ 0x771ba1, + /* 123 */ 0x30bb7df, + /* 124 */ 0x749df4, + /* 125 */ 0x79f87b, + /* 126 */ 0x31971e4, + /* 127 */ 0x6ddabe, + /* 128 */ 0x31971e4, + /* 129 */ 0x67d339, + /* 130 */ 0x84f8f3, + /* 131 */ 0x31d2c91, + /* 132 */ 0x62ebbf, + /* 133 */ 0x31d2c91, + /* 134 */ 0x67e4b1, + /* 135 */ 0x711f0e, + /* 136 */ 0x3543f10, + /* 137 */ 0x4ae2f0, + /* 138 */ 0x3543f10, + /* 139 */ 0x3c01ff, + /* 140 */ 0xaaf457, + /* 141 */ 0x3831bd5, + /* 142 */ 0xfb150, + /* 143 */ 0x3831bd5, + /* 144 */ 0x3aa5a8, + /* 145 */ 0x65b5d1, + /* 146 */ 0xe3390, + /* 147 */ 0x2226c8, + /* 148 */ 0xe3390, + /* 149 */ 0x7dc99, + /* 150 */ 0x358660, + /* 151 */ 0x6b0cc1, + /* 152 */ 0x358660, + /* 153 */ 0x3b418e, + /* 154 */ 0x1ad7f4, + /* 155 */ 0x800000, + /* 156 */ 0x0, + /* 157 */ 0x0, + /* 158 */ 0x0, + /* 159 */ 0x0, + /* 160 */ 0x800000, + /* 161 */ 0x0, + /* 162 */ 0x0, + /* 163 */ 0x0, + /* 164 */ 0x0, + /* 165 */ 0x800000, + /* 166 */ 0x0, + /* 167 */ 0x0, + /* 168 */ 0x0, + /* 169 */ 0x0, + /* 170 */ 0x800000, + /* 171 */ 0x0, + /* 172 */ 0x0, + /* 173 */ 0x0, + /* 174 */ 0x0, + /* 175 */ 0x800000, + /* 176 */ 0x0, + /* 177 */ 0x0, + /* 178 */ 0x0, + /* 179 */ 0x0, + /* 180 */ 0x800000, + /* 181 */ 0x0, + /* 182 */ 0x0, + /* 183 */ 0x0, + /* 184 */ 0x0, + /* 185 */ 0x800000, + /* 186 */ 0x0, + /* 187 */ 0x0, + /* 188 */ 0x0, + /* 189 */ 0x0, + /* 190 */ 0x800000, + /* 191 */ 0x0, + /* 192 */ 0x0, + /* 193 */ 0x0, + /* 194 */ 0x0, + /* 195 */ 0x800000, + /* 196 */ 0x0, + /* 197 */ 0x0, + /* 198 */ 0x0, + /* 199 */ 0x0, + /* 200 */ 0x800000, + /* 201 */ 0x0, + /* 202 */ 0x0, + /* 203 */ 0x0, + /* 204 */ 0x0, + /* 205 */ 0x25b, + /* 206 */ 0x4b5, + /* 207 */ 0x25b, + /* 208 */ 0x3045701, + /* 209 */ 0x7bb269, + /* 210 */ 0x7dd6da, + /* 211 */ 0x304524c, + /* 212 */ 0x7dd6da, + /* 213 */ 0x3045701, + /* 214 */ 0x7bb269, + /* 215 */ 0x7f3ee, + /* 216 */ 0xfe7dc, + /* 217 */ 0x7f3ee, + /* 218 */ 0x37f9f4a, + /* 219 */ 0x20306d, + /* 220 */ 0x482449, + /* 221 */ 0x36fb76e, + /* 222 */ 0x482449, + /* 223 */ 0x37f9f4a, + /* 224 */ 0x20306d, +}; + +static int multiband_drc_coeff[] = { + 0x34ebb, /* Low SMS coeff0 */ + 0x7f54e0, /* Low SMS coeff1 */ + 0x5188, /* Low RELEASE coeff0 */ + 0x7fae78, /* Low RELEASE coeff1 */ + 0x3263a, /* Low ATTACK coeff0 */ + 0x7cd9c6, /* Low ATTACK coeff1 */ + + 0x34ebb, /* Mid */ + 0x7f54e0, + 0x5188, + 0x7fae78, + 0x3263a, + 0x7cd9c6, + + 0x34ebb, /* High */ + 0x7f54e0, + 0x5188, + 0x7fae78, + 0x3263a, + 0x7cd9c6, +}; + +static int fullband_drc_coeff[] = { + 0x5188, /* RELEASE_COEF00 */ + 0x7fae78, /* RELEASE_COEF01 */ + 0x5188, + 0x7fae78, + 0x5188, + 0x7fae78, + 0x5188, + 0x7fae78, + 0x5188, + 0x7fae78, + 0x5188, /* RELEASE_COEF50 */ + 0x7fae78, /* RELEASE_COEF51 */ + 0x3263a, /* ATTACK_COEF00 */ + 0x7cd9c6, /* ATTACK_COEF01 */ + 0x3263a, + 0x7cd9c6, + 0x3263a, + 0x7cd9c6, + 0x3263a, + 0x7cd9c6, + 0x3263a, + 0x7cd9c6, + 0x3263a, /* ATTACK_COEF50 */ + 0x7cd9c6, /* ATTACK_COEF51 */ +}; diff --git a/sound/soc/amlogic/auge/effects_v2.c b/sound/soc/amlogic/auge/effects_v2.c new file mode 100644 index 000000000000..13e4184be61a --- /dev/null +++ b/sound/soc/amlogic/auge/effects_v2.c @@ -0,0 +1,698 @@ +/* + * sound/soc/amlogic/auge/effects_v2.c + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "effects_v2.h" +#include "effects_hw_v2.h" +#include "effects_hw_v2_coeff.c" +#include "ddr_mngr.h" +#include "regs.h" +#include "iomap.h" + +#define DRV_NAME "Effects" + +/* + * AED Diagram + * DC -- ND -- MIX -- EQ -- Mutiband DRC -- LR Vol + * -- Fullband DRC -- Master Volume + */ + +enum { + AED_DC, + AED_ND, + AED_EQ, + AED_MDRC, + AED_FDRC +}; + +struct effect_chipinfo { + /* v1 is for G12X(g12a, g12b) + * v2 is for tl1 + */ + bool v2; +}; + +struct audioeffect { + struct device *dev; + + /* gate */ + struct clk *gate; + /* source mpll */ + struct clk *srcpll; + /* eqdrc clk */ + struct clk *clk; + + struct effect_chipinfo *chipinfo; + + bool dc_en; + bool nd_en; + bool eq_en; + bool multiband_drc_en; + bool fullband_drc_en; + int mask_en; + + int lane_mask; + int ch_mask; + + /*which module should be effected */ + int effect_module; +}; + +struct audioeffect *s_effect; + +static struct audioeffect *get_audioeffects(void) +{ + if (!s_effect) { + pr_info("Not init audio effects\n"); + return NULL; + } + + return s_effect; +} + +bool check_aed_v2(void) +{ + struct audioeffect *p_effect = get_audioeffects(); + + if (!p_effect) + return false; + + if (p_effect->chipinfo && p_effect->chipinfo->v2) + return true; + + return false; +} + +static int eqdrc_clk_set(struct audioeffect *p_effect) +{ + int ret = 0; + + ret = clk_prepare_enable(p_effect->clk); + if (ret) { + pr_err("Can't enable eqdrc clock: %d\n", + ret); + return -EINVAL; + } + + ret = clk_prepare_enable(p_effect->srcpll); + if (ret) { + pr_err("Can't enable eqdrc src pll clock: %d\n", + ret); + return -EINVAL; + } + + /* defaule clk */ + clk_set_rate(p_effect->clk, 200000000); + + pr_info("%s, src pll:%lu, clk:%lu\n", + __func__, + clk_get_rate(p_effect->srcpll), + clk_get_rate(p_effect->clk)); + + return 0; +} + +static int mixer_aed_read(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + unsigned int max = mc->max; + unsigned int invert = mc->invert; + unsigned int value = + (((unsigned int)eqdrc_read(reg)) >> shift) & max; + + if (invert) + value = (~value) & max; + ucontrol->value.integer.value[0] = value; + + return 0; +} + +static int mixer_aed_write(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + unsigned int shift = mc->shift; + unsigned int max = mc->max; + unsigned int invert = mc->invert; + unsigned int value = ucontrol->value.integer.value[0]; + unsigned int new_val = (unsigned int)eqdrc_read(reg); + + if (invert) + value = (~value) & max; + max = ~(max << shift); + new_val &= max; + new_val |= (value << shift); + + eqdrc_write(reg, new_val); + + return 0; +} + +static void check_set_aed_top( + struct audioeffect *p_effect, + int mask_new, bool enable) +{ + int mask_last = p_effect->mask_en; + bool update_aed_top = false; + + pr_info("%s, mask:0x%x\n", __func__, mask_new); + + if (enable) + p_effect->mask_en |= mask_new; + else + p_effect->mask_en &= ~mask_new; + + if (enable && (!mask_last) && p_effect->mask_en) + update_aed_top = true; /* to enable */ + else if ((!enable) && mask_last && (!p_effect->mask_en)) + update_aed_top = true; /* to disable */ + + if (update_aed_top) + aml_set_aed(enable, p_effect->effect_module); +} + +static int mixer_aed_enable_DC(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + + p_effect->dc_en = ucontrol->value.integer.value[0]; + + aed_dc_enable(p_effect->dc_en); + + check_set_aed_top(p_effect, + 0x1 << AED_DC, + p_effect->dc_en); + + return 0; +} + +static int mixer_aed_enable_ND(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + + p_effect->nd_en = ucontrol->value.integer.value[0]; + + aed_nd_enable(p_effect->nd_en); + + check_set_aed_top(p_effect, + 0x1 << AED_ND, + p_effect->nd_en); + + return 0; +} + +static int mixer_aed_enable_EQ(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + int *p_eq_coeff = eq_coeff; + int len = ARRAY_SIZE(eq_coeff); + + p_effect->eq_en = ucontrol->value.integer.value[0]; + + aed_set_ram_coeff(len, p_eq_coeff); + aed_eq_enable(0, p_effect->eq_en); + + check_set_aed_top(p_effect, + 0x1 << AED_EQ, + p_effect->eq_en); + + return 0; +} + +static int mixer_aed_enable_multiband_DRC(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + int *p_multiband_coeff = multiband_drc_coeff; + int len = ARRAY_SIZE(multiband_drc_coeff); + + if (!p_effect) + return -EINVAL; + + p_effect->multiband_drc_en = ucontrol->value.integer.value[0]; + + aed_set_multiband_drc_coeff(len, p_multiband_coeff); + aed_multiband_drc_enable(p_effect->multiband_drc_en); + + check_set_aed_top(p_effect, + 0x1 << AED_MDRC, + p_effect->multiband_drc_en); + + return 0; +} + +static int mixer_aed_enable_fullband_DRC(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + int *p_fullband_coeff = fullband_drc_coeff; + int len = ARRAY_SIZE(fullband_drc_coeff); + + if (!p_effect) + return -EINVAL; + + p_effect->fullband_drc_en = ucontrol->value.integer.value[0]; + + aed_set_fullband_drc_coeff(len, p_fullband_coeff); + aed_fullband_drc_enable(p_effect->fullband_drc_en); + + check_set_aed_top(p_effect, + 0x1 << AED_FDRC, + p_effect->fullband_drc_en); + + return 0; +} + +static int mixer_get_EQ_params(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int *val = (int *)ucontrol->value.bytes.data; + int *p = &eq_coeff[0]; + + memcpy(val, p, AED_EQ_LENGTH); + + return 0; +} + + +static int mixer_set_EQ_params(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *params = (void *)kcontrol->private_value; + void *data; + int *val, *p = &eq_coeff[0]; + + data = kmemdup(ucontrol->value.bytes.data, + params->max, GFP_KERNEL | GFP_DMA); + if (!data) + return -ENOMEM; + + val = (int *)data; + memcpy(p, val, params->max / sizeof(int)); + + kfree(data); + + return 0; +} + +static int mixer_get_multiband_DRC_params(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int *val = (int *)ucontrol->value.bytes.data; + int *p = &multiband_drc_coeff[0]; + + memcpy(val, p, AED_MULTIBAND_DRC_LENGTH); + + return 0; +} + +static int mixer_set_multiband_DRC_params(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *params = (void *)kcontrol->private_value; + void *data; + int *val, *p = &multiband_drc_coeff[0]; + + data = kmemdup(ucontrol->value.bytes.data, + params->max, GFP_KERNEL | GFP_DMA); + if (!data) + return -ENOMEM; + + val = (int *)data; + memcpy(p, val, params->max / sizeof(int)); + + kfree(data); + + return 0; +} + +static int mixer_get_fullband_DRC_params(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int *val = (int *)ucontrol->value.bytes.data; + int *p = &fullband_drc_coeff[0]; + + memcpy(val, p, AED_FULLBAND_DRC_LENGTH); + + return 0; +} + +static int mixer_set_fullband_DRC_params(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_bytes_ext *params = (void *)kcontrol->private_value; + void *data; + int *val, *p = &fullband_drc_coeff[0]; + + data = kmemdup(ucontrol->value.bytes.data, + params->max, GFP_KERNEL | GFP_DMA); + if (!data) + return -ENOMEM; + + val = (int *)data; + memcpy(p, val, params->max / sizeof(int)); + + kfree(data); + + return 0; +} + +/* aed module + * check to sync with enum frddr_dest in ddr_mngr.h + */ +static const char *const aed_module_texts[] = { + "TDMOUT_A", + "TDMOUT_B", + "TDMOUT_C", + "SPDIFIN", + "SPDIFOUT_A", + "SPDIFOUT_B", +}; + +static const struct soc_enum aed_module_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(aed_module_texts), + aed_module_texts); + +static int aed_module_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + + if (!p_effect) + return -EINVAL; + + ucontrol->value.enumerated.item[0] = p_effect->effect_module; + + return 0; +} + +static int aed_module_set_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct audioeffect *p_effect = snd_kcontrol_chip(kcontrol); + + if (!p_effect) + return -EINVAL; + + p_effect->effect_module = ucontrol->value.enumerated.item[0]; + + /* update info to ddr and modules */ + aed_set_ctrl( + p_effect->eq_en | + p_effect->multiband_drc_en | + p_effect->fullband_drc_en, + 0, + p_effect->effect_module); + + return 0; +} + +static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12276, 12, 1); +static const DECLARE_TLV_DB_SCALE(lr_vol_tlv, -12750, 50, 1); + +static const struct snd_kcontrol_new snd_effect_controls[] = { + + SOC_SINGLE_EXT("AED DC cut enable", + AED_DC_EN, 0, 0x1, 0, + mixer_aed_read, mixer_aed_enable_DC), + + SOC_SINGLE_EXT("AED Noise Detect enable", + AED_ND_CNTL, 0, 0x1, 0, + mixer_aed_read, mixer_aed_enable_ND), + + SOC_SINGLE_EXT("AED EQ enable", + AED_EQ_EN, 0, 0x1, 0, + mixer_aed_read, mixer_aed_enable_EQ), + + SOC_SINGLE_EXT("AED Multi-band DRC enable", + AED_MDRC_CNTL, 8, 0x1, 0, + mixer_aed_read, mixer_aed_enable_multiband_DRC), + + SOC_SINGLE_EXT("AED Full-band DRC enable", + AED_DRC_CNTL, 0, 0x1, 0, + mixer_aed_read, mixer_aed_enable_fullband_DRC), + + SND_SOC_BYTES_EXT("AED EQ Parameters", + AED_EQ_LENGTH, + mixer_get_EQ_params, + mixer_set_EQ_params), + + SND_SOC_BYTES_EXT("AED Multi-band DRC Parameters", + AED_MULTIBAND_DRC_LENGTH, + mixer_get_multiband_DRC_params, + mixer_set_multiband_DRC_params), + + SND_SOC_BYTES_EXT("AED Full-band DRC Parameters", + AED_FULLBAND_DRC_LENGTH, + mixer_get_fullband_DRC_params, + mixer_set_fullband_DRC_params), + + SOC_ENUM_EXT("AED module", + aed_module_enum, + aed_module_get_enum, + aed_module_set_enum), + + SOC_SINGLE_EXT("AED Lane mask", + AED_TOP_CTL, 14, 0xF, 0, + mixer_aed_read, mixer_aed_write), + + SOC_SINGLE_EXT("AED Channel mask", + AED_TOP_CTL, 18, 0xFF, 0, + mixer_aed_read, mixer_aed_write), + + SOC_SINGLE_EXT_TLV("AED Lch volume", + AED_EQ_VOLUME, 0, 0xFF, 1, + mixer_aed_read, mixer_aed_write, + lr_vol_tlv), + + SOC_SINGLE_EXT_TLV("AED Rch volume", + AED_EQ_VOLUME, 8, 0xFF, 1, + mixer_aed_read, mixer_aed_write, + lr_vol_tlv), + + SOC_SINGLE_EXT_TLV("AED master volume", + AED_EQ_VOLUME, 16, 0x3FF, 1, + mixer_aed_read, mixer_aed_write, + master_vol_tlv), +}; + +int card_add_effect_v2_kcontrols(struct snd_soc_card *card) +{ + unsigned int idx; + int err; + + if (!s_effect) { + pr_info("effect_v2 is not init\n"); + return 0; + } + + for (idx = 0; idx < ARRAY_SIZE(snd_effect_controls); idx++) { + err = snd_ctl_add(card->snd_card, + snd_ctl_new1(&snd_effect_controls[idx], + s_effect)); + if (err < 0) + return err; + } + + return 0; +} + +#if 0 +static const struct snd_soc_component_driver effect_component_drv = { + .name = DRV_NAME, + + .controls = snd_effect_controls, + .num_controls = ARRAY_SIZE(snd_effect_controls), +}; +#endif + +static struct effect_chipinfo tl1_effect_chipinfo = { + .v2 = true, +}; + +static const struct of_device_id effect_device_id[] = { + { + .compatible = "amlogic, snd-effect-v1" + }, + { + .compatible = "amlogic, snd-effect-v2", + .data = &tl1_effect_chipinfo, + }, + { + .compatible = "amlogic, tl1-effect", + .data = &tl1_effect_chipinfo, + }, + {} +}; +MODULE_DEVICE_TABLE(of, effect_device_id); + +static int effect_platform_probe(struct platform_device *pdev) +{ + struct audioeffect *p_effect; + struct device *dev = &pdev->dev; + struct effect_chipinfo *p_chipinfo; + bool eq_enable = false; + bool multiband_drc_enable = false; + bool fullband_drc_enable = false; + int lane_mask = -1, channel_mask = -1, eqdrc_module = -1; + + int ret; + + pr_info("%s, line:%d\n", __func__, __LINE__); + + p_effect = devm_kzalloc(&pdev->dev, + sizeof(struct audioeffect), + GFP_KERNEL); + if (!p_effect) { + dev_err(&pdev->dev, "Can't allocate pcm_p\n"); + return -ENOMEM; + } + + /* match data */ + p_chipinfo = (struct effect_chipinfo *) + of_device_get_match_data(dev); + if (!p_chipinfo) + dev_warn_once(dev, "check whether to update effect chipinfo\n"); + p_effect->chipinfo = p_chipinfo; + + p_effect->gate = devm_clk_get(&pdev->dev, "gate"); + if (IS_ERR(p_effect->gate)) { + dev_err(&pdev->dev, + "Can't retrieve eqdrc gate clock\n"); + ret = PTR_ERR(p_effect->gate); + return ret; + } + + p_effect->srcpll = devm_clk_get(&pdev->dev, "srcpll"); + if (IS_ERR(p_effect->srcpll)) { + dev_err(&pdev->dev, + "Can't retrieve source mpll clock\n"); + ret = PTR_ERR(p_effect->srcpll); + return ret; + } + + p_effect->clk = devm_clk_get(&pdev->dev, "eqdrc"); + if (IS_ERR(p_effect->clk)) { + dev_err(&pdev->dev, + "Can't retrieve eqdrc clock\n"); + ret = PTR_ERR(p_effect->clk); + return ret; + } + + ret = clk_set_parent(p_effect->clk, p_effect->srcpll); + if (ret) { + dev_err(&pdev->dev, + "Can't set eqdrc clock parent clock\n"); + ret = PTR_ERR(p_effect->clk); + return ret; + } + + eqdrc_clk_set(p_effect); + + eq_enable = of_property_read_bool(pdev->dev.of_node, + "eq_enable"); + + multiband_drc_enable = of_property_read_bool(pdev->dev.of_node, + "multiband_drc_enable"); + + fullband_drc_enable = of_property_read_bool(pdev->dev.of_node, + "fullband_drc_enable"); + + ret = of_property_read_u32(pdev->dev.of_node, + "eqdrc_module", + &eqdrc_module); + if (ret < 0) { + dev_err(&pdev->dev, "Can't retrieve eqdrc_module\n"); + return -EINVAL; + } + + ret = of_property_read_u32(pdev->dev.of_node, + "lane_mask", + &lane_mask); + if (ret < 0) { + dev_err(&pdev->dev, "Can't retrieve lane_mask\n"); + return -EINVAL; + } + + ret = of_property_read_u32(pdev->dev.of_node, + "channel_mask", + &channel_mask); + if (ret < 0) { + dev_err(&pdev->dev, "Can't retrieve channel_mask\n"); + return -EINVAL; + } + + pr_info("%s \t eq_en:%d, multi-band drc en:%d, full-band drc en:%d, module:%d, lane_mask:%d, ch_mask:%d\n", + __func__, + eq_enable, + multiband_drc_enable, + fullband_drc_enable, + eqdrc_module, + lane_mask, + channel_mask + ); + + /* config from dts */ + p_effect->eq_en = eq_enable; + p_effect->multiband_drc_en = multiband_drc_enable; + p_effect->fullband_drc_en = fullband_drc_enable; + p_effect->lane_mask = lane_mask; + p_effect->ch_mask = channel_mask; + p_effect->effect_module = eqdrc_module; + + aed_set_lane_and_channels(lane_mask, channel_mask); + aed_set_EQ_volume(0xc0, 0x30, 0x30); + + p_effect->dev = dev; + s_effect = p_effect; + dev_set_drvdata(&pdev->dev, p_effect); + + return 0; +} + +static struct platform_driver effect_platform_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(effect_device_id), + }, + .probe = effect_platform_probe, +}; +module_platform_driver(effect_platform_driver); + +MODULE_AUTHOR("AMLogic, Inc."); +MODULE_DESCRIPTION("Amlogic Audio Effects driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/amlogic/auge/effects_v2.h b/sound/soc/amlogic/auge/effects_v2.h new file mode 100644 index 000000000000..9c5051ae9996 --- /dev/null +++ b/sound/soc/amlogic/auge/effects_v2.h @@ -0,0 +1,23 @@ +/* + * sound/soc/amlogic/auge/effects_v2.h + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#ifndef __EFFECTS_V2_H__ +#define __EFFECTS_V2_H__ + +extern bool check_aed_v2(void); +extern int card_add_effect_v2_kcontrols(struct snd_soc_card *card); + +#endif diff --git a/sound/soc/amlogic/auge/extn.c b/sound/soc/amlogic/auge/extn.c index c437e9f1de78..55d3e46ec438 100644 --- a/sound/soc/amlogic/auge/extn.c +++ b/sound/soc/amlogic/auge/extn.c @@ -38,20 +38,40 @@ #include "audio_utils.h" #include "frhdmirx_hw.h" +#include + #define DRV_NAME "EXTN" struct extn { struct aml_audio_controller *actrl; struct device *dev; - unsigned int sysclk_freq; - - int irq_frhdmirx; struct toddr *tddr; struct frddr *fddr; + + int sysclk_freq; + + int irq_frhdmirx; + + /* + * 0: select spdif lane; + * 1: select PAO mode; + */ + int hdmirx_mode; + + /* + * arc source sel: + * 0: hi_hdmirx_arc_cntl[5] + * 1: audio_spdif_a + * 2: audio_spdif_b + * 4: hdmir_aud_spdif + */ + int arc_src; + int arc_en; + }; -#define PREALLOC_BUFFER (32 * 1024) +#define PREALLOC_BUFFER (128 * 1024) #define PREALLOC_BUFFER_MAX (256 * 1024) #define EXTN_RATES (SNDRV_PCM_RATE_8000_192000) @@ -320,37 +340,58 @@ static int extn_dai_prepare( aml_frddr_set_fifos(fr, 0x40, 0x20); } else { struct toddr *to = p_extn->tddr; - unsigned int msb = 32 - 1; - unsigned int lsb = 32 - bit_depth; - unsigned int toddr_type; + unsigned int msb = 0, lsb = 0, toddr_type = 0; unsigned int src = toddr_src_get(); struct toddr_fmt fmt; - switch (bit_depth) { - case 8: - case 16: - case 32: - toddr_type = 0; - break; - case 24: + if (bit_depth == 24) toddr_type = 4; - break; - default: - pr_err("invalid bit_depth: %d\n", bit_depth); - return -EINVAL; - } + else + toddr_type = 0; pr_info("%s Expected toddr src:%s\n", __func__, toddr_src_get_str(src)); - if (src == FRATV) - fratv_src_select(0); - else if (src == FRHDMIRX) { - frhdmirx_ctrl(runtime->channels, 0); - frhdmirx_src_select(0); + if (src == FRATV) { + /* Now tv supports 48k, 16bits */ + if ((bit_depth != 16) || (runtime->rate != 48000)) { + pr_err("not support sample rate:%d, bits:%d\n", + runtime->rate, bit_depth); + return -EINVAL; + } + + msb = 15; + lsb = 0; + + fratv_src_select(1); + } else if (src == FRHDMIRX) { + if (p_extn->hdmirx_mode) { /* PAO */ + + if (bit_depth == 32) + toddr_type = 3; + else if (bit_depth == 24) + toddr_type = 4; + else + toddr_type = 0; + + msb = 28 - 1 - 4; + if (bit_depth == 16) + lsb = 24 - bit_depth; + else + lsb = 4; + } + + frhdmirx_ctrl(runtime->channels, p_extn->hdmirx_mode); + frhdmirx_src_select(p_extn->hdmirx_mode); + } else { + pr_info("Not support toddr src:%s\n", + toddr_src_get_str(src)); + return -EINVAL; } + pr_info("%s m:%d, n:%d\n", __func__, msb, lsb); + fmt.type = toddr_type; fmt.msb = msb; fmt.lsb = lsb; @@ -486,7 +527,220 @@ static struct snd_soc_dai_driver extn_dai[] = { }, }; +static const char *const arc_src_txt[] = { + "HI_HDMIRX_ARC_CNTL[5]", + "AUDIO_SPDIF_A", + "AUDIO_SPDIF_B", + "HDMIR_AUD_SPDIF", +}; + +const struct soc_enum arc_src_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(arc_src_txt), + arc_src_txt); + +static int arc_get_src( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct extn *p_extn = dev_get_drvdata(component->dev); + + ucontrol->value.integer.value[0] = p_extn->arc_src; + + return 0; +} + +static int arc_set_src( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct extn *p_extn = dev_get_drvdata(component->dev); + + p_extn->arc_src = ucontrol->value.integer.value[0]; + + cec_arc_enable(p_extn->arc_src, p_extn->arc_en); + + return 0; +} + +static int arc_get_enable( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct extn *p_extn = dev_get_drvdata(component->dev); + + ucontrol->value.integer.value[0] = p_extn->arc_en; + + return 0; +} + +static int arc_set_enable( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct extn *p_extn = dev_get_drvdata(component->dev); + + p_extn->arc_en = ucontrol->value.integer.value[0]; + + cec_arc_enable(p_extn->arc_src, p_extn->arc_en); + + return 0; +} + +static int frhdmirx_get_mode( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct extn *p_extn = dev_get_drvdata(component->dev); + + ucontrol->value.integer.value[0] = p_extn->hdmirx_mode; + + return 0; +} + +static int frhdmirx_set_mode( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct extn *p_extn = dev_get_drvdata(component->dev); + + p_extn->hdmirx_mode = ucontrol->value.integer.value[0]; + + return 0; +} +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +/* spdif in audio format detect: LPCM or NONE-LPCM */ +struct sppdif_audio_info { + unsigned char aud_type; + /*IEC61937 package presamble Pc value*/ + short pc; + char *aud_type_str; +}; + +static const char *const spdif_audio_type_texts[] = { + "LPCM", + "AC3", + "EAC3", + "DTS", + "DTS-HD", + "TRUEHD", + "PAUSE" +}; + +static const struct sppdif_audio_info type_texts[] = { + {0, 0, "LPCM"}, + {1, 0x1, "AC3"}, + {2, 0x15, "EAC3"}, + {3, 0xb, "DTS-I"}, + {3, 0x0c, "DTS-II"}, + {3, 0x0d, "DTS-III"}, + {3, 0x11, "DTS-IV"}, + {4, 0, "DTS-HD"}, + {5, 0x16, "TRUEHD"}, + {6, 0x103, "PAUSE"}, + {6, 0x003, "PAUSE"}, + {6, 0x100, "PAUSE"}, +}; + +static const struct soc_enum hdmirx_audio_type_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_audio_type_texts), + spdif_audio_type_texts); + +static int hdmiin_check_audio_type(void) +{ + int total_num = sizeof(type_texts)/sizeof(struct sppdif_audio_info); + int pc = frhdmirx_get_chan_status_pc(); + int audio_type = 0; + int i; + + for (i = 0; i < total_num; i++) { + if (pc == type_texts[i].pc) { + audio_type = type_texts[i].aud_type; + break; + } + } + + pr_debug("%s audio type:%d\n", __func__, audio_type); + + return audio_type; +} + +static int hdmirx_audio_type_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = + hdmiin_check_audio_type(); + return 0; +} +#endif + +static const struct snd_kcontrol_new extn_controls[] = { + /* Out */ + SOC_ENUM_EXT("HDMI ARC Source", + arc_src_enum, + arc_get_src, + arc_set_src), + + SOC_SINGLE_BOOL_EXT("HDMI ARC Switch", + 0, + arc_get_enable, + arc_set_enable), + + /* In */ + SOC_SINGLE_BOOL_EXT("SPDIFIN PAO", + 0, + frhdmirx_get_mode, + frhdmirx_set_mode), + +#ifdef CONFIG_AMLOGIC_ATV_DEMOD + SOC_ENUM_EXT("ATV audio stable", + atv_audio_status_enum, + aml_get_atv_audio_stable, + NULL), +#endif + +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI + SOC_ENUM_EXT("HDMIIN audio stable", + hdmi_in_status_enum[0], + aml_get_hdmiin_audio_stable, + NULL), + + SOC_ENUM_EXT("HDMIIN audio samplerate", + hdmi_in_status_enum[1], + aml_get_hdmiin_audio_samplerate, + NULL), + + SOC_ENUM_EXT("HDMIIN audio channels", + hdmi_in_status_enum[2], + aml_get_hdmiin_audio_channels, + NULL), + + SOC_ENUM_EXT("HDMIIN audio format", + hdmi_in_status_enum[3], + aml_get_hdmiin_audio_format, + NULL), + + SOC_SINGLE_BOOL_EXT("HDMI ATMOS EDID Switch", + 0, + aml_get_atmos_audio_edid, + aml_set_atmos_audio_edid), + SOC_ENUM_EXT("HDMIIN Audio Type", + hdmirx_audio_type_enum, + hdmirx_audio_type_get_enum, + NULL), +#endif + +}; + static const struct snd_soc_component_driver extn_component = { + .controls = extn_controls, + .num_controls = ARRAY_SIZE(extn_controls), .name = DRV_NAME, }; @@ -506,16 +760,16 @@ static int extn_platform_probe(struct platform_device *pdev) struct platform_device *pdev_parent; struct device *dev = &pdev->dev; struct aml_audio_controller *actrl = NULL; - struct extn *extn = NULL; + struct extn *p_extn = NULL; int ret = 0; - extn = devm_kzalloc(dev, sizeof(struct extn), GFP_KERNEL); - if (!extn) + p_extn = devm_kzalloc(dev, sizeof(struct extn), GFP_KERNEL); + if (!p_extn) return -ENOMEM; - extn->dev = dev; - dev_set_drvdata(dev, extn); + p_extn->dev = dev; + dev_set_drvdata(dev, p_extn); /* get audio controller */ node_prt = of_get_parent(node); @@ -526,16 +780,22 @@ static int extn_platform_probe(struct platform_device *pdev) of_node_put(node_prt); actrl = (struct aml_audio_controller *) platform_get_drvdata(pdev_parent); - extn->actrl = actrl; + p_extn->actrl = actrl; /* irqs */ - extn->irq_frhdmirx = platform_get_irq_byname(pdev, "irq_frhdmirx"); - if (extn->irq_frhdmirx < 0) { + p_extn->irq_frhdmirx = platform_get_irq_byname(pdev, "irq_frhdmirx"); + if (p_extn->irq_frhdmirx < 0) { dev_err(dev, "Failed to get irq_frhdmirx:%d\n", - extn->irq_frhdmirx); + p_extn->irq_frhdmirx); return -ENXIO; } + /* Default ARC SRC */ + p_extn->arc_src = 1; + + /* Default: SPDIF in mode */ + p_extn->hdmirx_mode = 0; + ret = snd_soc_register_component(&pdev->dev, &extn_component, extn_dai, diff --git a/sound/soc/amlogic/auge/frhdmirx_hw.c b/sound/soc/amlogic/auge/frhdmirx_hw.c index ca24d6a10006..19c55f480522 100644 --- a/sound/soc/amlogic/auge/frhdmirx_hw.c +++ b/sound/soc/amlogic/auge/frhdmirx_hw.c @@ -81,6 +81,17 @@ void frhdmirx_ctrl(int channels, int src) { int lane, lane_mask = 0, i; + /* PAO mode */ + if (src) { + audiobus_write(EE_AUDIO_FRHDMIRX_CTRL0, + 0x1 << 23 | /* slect pao mode */ + 0x1 << 22 | /* capture input by fall edge*/ + 0x1 << 7 | /* start sending ch num info out */ + 0x1 << 8 | /* start detect PAPB */ + 0x1 << 6 /* chan status sel: pao pc/pd value */); + return; + } + if (channels % 2) lane = channels / 2 + 1; else @@ -90,10 +101,11 @@ void frhdmirx_ctrl(int channels, int src) lane_mask |= (1 << i); audiobus_update_bits(EE_AUDIO_FRHDMIRX_CTRL0, - 0x1 << 30 | 0xf << 24 | 0x3 << 11, + 0x1 << 30 | 0xf << 24 | 0x1 << 22 | 0x3 << 11, 0x1 << 30 | /* chnum_sel */ lane_mask << 24 | /* chnum_sel */ - 0x0 << 11 /* req_sel, Sync 4 spdifin by which */ + 0x1 << 22 | /* clk_inv */ + 0x0 << 11 /* req_sel, Sync 4 spdifin by which */ ); /* nonpcm2pcm_th */ @@ -102,3 +114,14 @@ void frhdmirx_ctrl(int channels, int src) /* enable irq bits */ frhdmirx_enable_irq_bits(channels, src); } + +unsigned int frhdmirx_get_chan_status_pc(void) +{ + unsigned int val; + + val = audiobus_read(EE_AUDIO_FRHDMIRX_STAT1); + return (val >> 16) & 0xff; +} + + + diff --git a/sound/soc/amlogic/auge/frhdmirx_hw.h b/sound/soc/amlogic/auge/frhdmirx_hw.h index ce51e13242cd..e0ebfe46323e 100644 --- a/sound/soc/amlogic/auge/frhdmirx_hw.h +++ b/sound/soc/amlogic/auge/frhdmirx_hw.h @@ -20,5 +20,5 @@ extern void frhdmirx_enable(bool enable); extern void frhdmirx_src_select(int src); extern void frhdmirx_ctrl(int channels, int src); - +extern unsigned int frhdmirx_get_chan_status_pc(void); #endif diff --git a/sound/soc/amlogic/auge/iomap.c b/sound/soc/amlogic/auge/iomap.c index f3aa05e0482d..58bef78704ad 100644 --- a/sound/soc/amlogic/auge/iomap.c +++ b/sound/soc/amlogic/auge/iomap.c @@ -204,6 +204,33 @@ void audioreset_update_bits(unsigned int reg, } EXPORT_SYMBOL(audioreset_update_bits); +int vad_read(unsigned int reg) +{ + int ret, val = 0; + + ret = aml_snd_read(IO_VAD, reg, &val); + + if (ret) { + pr_err("read audio reg %x error %d\n", reg, ret); + return -1; + } + return val; +} +EXPORT_SYMBOL(vad_read); + +void vad_write(unsigned int reg, unsigned int val) +{ + aml_snd_write(IO_VAD, reg, val); +} +EXPORT_SYMBOL(vad_write); + +void vad_update_bits(unsigned int reg, + unsigned int mask, unsigned int val) +{ + aml_snd_update_bits(IO_VAD, reg, mask, val); +} +EXPORT_SYMBOL(vad_update_bits); + static int snd_iomap_probe(struct platform_device *pdev) { struct resource res; diff --git a/sound/soc/amlogic/auge/iomap.h b/sound/soc/amlogic/auge/iomap.h index 574fd2e35668..ae3c9287cc48 100644 --- a/sound/soc/amlogic/auge/iomap.h +++ b/sound/soc/amlogic/auge/iomap.h @@ -24,6 +24,7 @@ enum{ IO_AUDIO_LOCKER, IO_EQDRC_BUS, IO_RESET, + IO_VAD, IO_MAX, }; @@ -52,4 +53,9 @@ extern int audioreset_read(unsigned int reg); extern void audioreset_write(unsigned int reg, unsigned int val); extern void audioreset_update_bits(unsigned int reg, unsigned int mask, unsigned int val); + +extern int vad_read(unsigned int reg); +extern void vad_write(unsigned int reg, unsigned int val); +extern void vad_update_bits(unsigned int reg, + unsigned int mask, unsigned int val); #endif diff --git a/sound/soc/amlogic/auge/locker.c b/sound/soc/amlogic/auge/locker.c index bfbe0075ee65..d41cc4ab6ca7 100644 --- a/sound/soc/amlogic/auge/locker.c +++ b/sound/soc/amlogic/auge/locker.c @@ -14,6 +14,8 @@ * more details. * */ +#define DEBUG + #include #include @@ -181,7 +183,7 @@ static DEVICE_ATTR(locker_enable, 0644, void audio_locker_set(int enable) { if (!s_locker) { - pr_err("audio locker is not init\n"); + pr_debug("audio locker is not init\n"); return; } @@ -192,7 +194,7 @@ void audio_locker_set(int enable) int audio_locker_get(void) { if (!s_locker) { - pr_err("audio locker is not init\n"); + pr_debug("audio locker is not init\n"); return -1; } diff --git a/sound/soc/amlogic/auge/pdm.c b/sound/soc/amlogic/auge/pdm.c index e05c24ba8a7c..d4ef74f0e7b1 100644 --- a/sound/soc/amlogic/auge/pdm.c +++ b/sound/soc/amlogic/auge/pdm.c @@ -34,6 +34,7 @@ #include "iomap.h" #include "regs.h" #include "ddr_mngr.h" +#include "vad.h" /*#define __PTM_PDM_CLK__*/ @@ -55,8 +56,8 @@ static struct snd_pcm_hardware aml_pdm_hardware = { .channels_min = PDM_CHANNELS_MIN, .channels_max = PDM_CHANNELS_MAX, - .buffer_bytes_max = 32 * 1024, - .period_bytes_max = 16 * 1024, + .buffer_bytes_max = 512 * 1024, + .period_bytes_max = 256 * 1024, .period_bytes_min = 32, .periods_min = 2, .periods_max = 1024, @@ -592,6 +593,10 @@ static int aml_pdm_dai_prepare( unsigned int bitwidth; unsigned int toddr_type, lsb; + if (vad_pdm_is_running() + && pm_audio_is_suspend()) + return 0; + /* set bclk */ bitwidth = snd_pcm_format_width(runtime->format); lsb = 32 - bitwidth; @@ -676,6 +681,9 @@ static int aml_pdm_dai_prepare( } p_pdm->filter_mode = s_pdm_filter_mode; aml_pdm_filter_ctrl(osr, p_pdm->filter_mode); + + if (p_pdm->chipinfo && p_pdm->chipinfo->truncate_data) + pdm_init_truncate_data(runtime->rate); } return 0; @@ -687,12 +695,21 @@ static int aml_pdm_dai_trigger( { struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai); - pr_info("%s\n", __func__); + pr_info("%s, cmd:%d\n", __func__, cmd); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + + if (vad_pdm_is_running() + && pm_audio_is_suspend()) { + pm_audio_set_suspend(false); + /* VAD switch to alsa buffer */ + vad_update_buffer(0); + break; + } + pdm_fifo_reset(); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { @@ -706,6 +723,13 @@ static int aml_pdm_dai_trigger( case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (vad_pdm_is_running() + && pm_audio_is_suspend()) { + /* switch to VAD buffer */ + vad_update_buffer(1); + break; + } + dev_info(substream->pcm->card->dev, "pdm capture stop\n"); pdm_enable(0); aml_toddr_enable(p_pdm->tddr, 0); @@ -874,7 +898,7 @@ static struct pdm_chipinfo g12a_pdm_chipinfo = { static struct pdm_chipinfo tl1_pdm_chipinfo = { .mute_fn = true, - .truncate_data = true, + .truncate_data = false, }; static const struct of_device_id aml_pdm_device_id[] = { diff --git a/sound/soc/amlogic/auge/pdm_hw.c b/sound/soc/amlogic/auge/pdm_hw.c index 585d27166d80..d870dd0336c5 100644 --- a/sound/soc/amlogic/auge/pdm_hw.c +++ b/sound/soc/amlogic/auge/pdm_hw.c @@ -452,3 +452,13 @@ void pdm_set_mute_channel(int mute_chmask) (0xff << 20 | 0x1 << 17), (mute_chmask << 20 | mute_en << 17)); } + +void pdm_init_truncate_data(int freq) +{ + int mask_val; + + /* assume mask 1.05ms */ + mask_val = ((freq / 1000) * 1050) / 1000 - 1; + + aml_pdm_write(PDM_MASK_NUM, mask_val); +} diff --git a/sound/soc/amlogic/auge/pdm_hw.h b/sound/soc/amlogic/auge/pdm_hw.h index a7461d6a46a8..b7d19c025c71 100644 --- a/sound/soc/amlogic/auge/pdm_hw.h +++ b/sound/soc/amlogic/auge/pdm_hw.h @@ -38,6 +38,8 @@ extern void pdm_set_mute_value(int val); extern int pdm_get_mute_channel(void); extern void pdm_set_mute_channel(int mute_chmask); +extern void pdm_init_truncate_data(int freq); + extern int pdm_hcic_shift_gain; extern int pdm_dclk; diff --git a/sound/soc/amlogic/auge/regs.h b/sound/soc/amlogic/auge/regs.h index f3394be11099..7bf3d4ed5690 100644 --- a/sound/soc/amlogic/auge/regs.h +++ b/sound/soc/amlogic/auge/regs.h @@ -270,16 +270,27 @@ enum clk_sel { #define EE_AUDIO_SPDIFIN_STAT2 0x109 #define EE_AUDIO_SPDIFIN_MUTE_VAL 0x10a -#define EE_AUDIO_RESAMPLE_CTRL0 0x110 -#define EE_AUDIO_RESAMPLE_CTRL1 0x111 -#define EE_AUDIO_RESAMPLE_CTRL2 0x112 -#define EE_AUDIO_RESAMPLE_CTRL3 0x113 -#define EE_AUDIO_RESAMPLE_COEF0 0x114 -#define EE_AUDIO_RESAMPLE_COEF1 0x115 -#define EE_AUDIO_RESAMPLE_COEF2 0x116 -#define EE_AUDIO_RESAMPLE_COEF3 0x117 -#define EE_AUDIO_RESAMPLE_COEF4 0x118 -#define EE_AUDIO_RESAMPLE_STATUS1 0x119 +#define EE_AUDIO_RESAMPLEA_CTRL0 0x110 +#define EE_AUDIO_RESAMPLEA_CTRL1 0x111 +#define EE_AUDIO_RESAMPLEA_CTRL2 0x112 +#define EE_AUDIO_RESAMPLEA_CTRL3 0x113 +#define EE_AUDIO_RESAMPLEA_COEF0 0x114 +#define EE_AUDIO_RESAMPLEA_COEF1 0x115 +#define EE_AUDIO_RESAMPLEA_COEF2 0x116 +#define EE_AUDIO_RESAMPLEA_COEF3 0x117 +#define EE_AUDIO_RESAMPLEA_COEF4 0x118 +#define EE_AUDIO_RESAMPLEA_STATUS1 0x119 + +#define EE_AUDIO_RESAMPLEB_CTRL0 0x1e0 +#define EE_AUDIO_RESAMPLEB_CTRL1 0x1e1 +#define EE_AUDIO_RESAMPLEB_CTRL2 0x1e2 +#define EE_AUDIO_RESAMPLEB_CTRL3 0x1e3 +#define EE_AUDIO_RESAMPLEB_COEF0 0x1e4 +#define EE_AUDIO_RESAMPLEB_COEF1 0x1e5 +#define EE_AUDIO_RESAMPLEB_COEF2 0x1e6 +#define EE_AUDIO_RESAMPLEB_COEF3 0x1e7 +#define EE_AUDIO_RESAMPLEB_COEF4 0x1e8 +#define EE_AUDIO_RESAMPLEB_STATUS1 0x1e9 #define EE_AUDIO_SPDIFOUT_STAT 0x120 #define EE_AUDIO_SPDIFOUT_GAIN0 0x121 @@ -403,6 +414,11 @@ enum clk_sel { */ #define EE_RESET1 0x002 +/* + * HIU, ARC + */ +#define HHI_HDMIRX_ARC_CNTL 0xe8 + /* * AUDIO MUX CONTROLS */ @@ -411,17 +427,6 @@ enum clk_sel { #define EE_AUDIO_TOVAD_CTRL0 0x1d2 #define EE_AUDIO_FRATV_CTRL0 0x1d3 -#define EE_AUDIO_RESAMPLEB_CTRL0 0x1e0 -#define EE_AUDIO_RESAMPLEB_CTRL1 0x1e1 -#define EE_AUDIO_RESAMPLEB_CTRL2 0x1e2 -#define EE_AUDIO_RESAMPLEB_CTRL3 0x1e3 -#define EE_AUDIO_RESAMPLEB_COEF0 0x1e4 -#define EE_AUDIO_RESAMPLEB_COEF1 0x1e5 -#define EE_AUDIO_RESAMPLEB_COEF2 0x1e6 -#define EE_AUDIO_RESAMPLEB_COEF3 0x1e7 -#define EE_AUDIO_RESAMPLEB_COEF4 0x1e8 -#define EE_AUDIO_RESAMPLEB_STATUS1 0x1e9 - #define EE_AUDIO_SPDIFIN_LB_CTRL0 0x1f0 #define EE_AUDIO_SPDIFIN_LB_CTRL1 0x1f1 #define EE_AUDIO_SPDIFIN_LB_CTRL6 0x1f6 @@ -507,7 +512,7 @@ enum clk_sel { #define RO_AUD_LOCK_INT_STATUS 0x01b /* - * EQ DRC, g12a, g12b + * EQ DRC, G12X means g12a, g12b */ #define AED_EQ_CH1_COEF00 0x00 #define AED_EQ_CH1_COEF01 0x01 @@ -645,6 +650,10 @@ enum clk_sel { #define AED_DRC_AD_1M_H 0x85 #define AED_NG_CNT 0x86 #define AED_NG_STEP 0x87 + +#define AED_TOP_CTL_G12X 0x88 +#define AED_TOP_REQ_CTL_G12X 0x89 + /* * EQ DRC, New ARCH, from tl1 */ @@ -780,8 +789,9 @@ enum clk_sel { #define AED_MASTER_VOLUME_STATE 0x81 #define AED_MASTER_VOLUME_GAIN 0x82 -#define AED_TOP_CTL 0x88 -#define AED_TOP_REQ_CTL 0x89 +#define AED_TOP_CTL 0x83 +#define AED_TOP_REQ_CTL 0x84 + /* * VAD, Voice activity detection diff --git a/sound/soc/amlogic/auge/resample.c b/sound/soc/amlogic/auge/resample.c index e8812c52dd8b..7c56eb1cc200 100644 --- a/sound/soc/amlogic/auge/resample.c +++ b/sound/soc/amlogic/auge/resample.c @@ -14,6 +14,8 @@ * more details. * */ +#define DEBUG + #include #include #include @@ -34,7 +36,15 @@ #define CLK_RATIO 256 +/*#define __PTM_RESAMPLE_CLK__*/ + +#define RESAMPLE_A 0 +#define RESAMPLE_B 1 + struct resample_chipinfo { + int num; /* support resample a/b */ + int id; + bool dividor_fn; }; @@ -50,18 +60,46 @@ struct audioresample { struct resample_chipinfo *chipinfo; + int id; + /*which module should be resampled */ int resample_module; /* resample to the rate */ int out_rate; /* sync with auge_resample_texts */ - int asr_idx; + int asrc_rate_idx; bool enable; }; -struct audioresample *s_resample; +struct audioresample *s_resample_a; + +struct audioresample *s_resample_b; + +static struct audioresample *get_audioresample(int id) +{ + struct audioresample *p_resample; + + p_resample = ((id == 0) ? s_resample_a : s_resample_b); + + if (!p_resample) { + pr_debug("Not init audio resample\n"); + return NULL; + } + + return p_resample; +} + +int get_resample_module_num(void) +{ + struct audioresample *p_resample = get_audioresample(0); + + if (p_resample && p_resample->chipinfo) + return p_resample->chipinfo->num; + + return 1; +} static int resample_clk_set(struct audioresample *p_resample) { @@ -69,23 +107,15 @@ static int resample_clk_set(struct audioresample *p_resample) /* enable clock */ if (p_resample->enable) { - ret = clk_prepare_enable(p_resample->clk); - if (ret) { - pr_err("Can't enable resample_clk clock: %d\n", - ret); - return -EINVAL; - } - - ret = clk_prepare_enable(p_resample->sclk); - if (ret) { - pr_err("Can't enable resample_src clock: %d\n", - ret); - return -EINVAL; - } if (p_resample->out_rate) { +#ifdef __PTM_RESAMPLE_CLK__ + clk_set_rate(p_resample->pll, + p_resample->out_rate * CLK_RATIO * 2 * 14); +#else clk_set_rate(p_resample->pll, p_resample->out_rate * CLK_RATIO * 2); +#endif clk_set_rate(p_resample->sclk, p_resample->out_rate * CLK_RATIO); clk_set_rate(p_resample->clk, @@ -103,6 +133,20 @@ static int resample_clk_set(struct audioresample *p_resample) return -EINVAL; } + ret = clk_prepare_enable(p_resample->sclk); + if (ret) { + pr_err("Can't enable resample_src clock: %d\n", + ret); + return -EINVAL; + } + + ret = clk_prepare_enable(p_resample->clk); + if (ret) { + pr_err("Can't enable resample_clk clock: %d\n", + ret); + return -EINVAL; + } + pr_info("%s, resample_pll:%lu, sclk:%lu, clk:%lu\n", __func__, clk_get_rate(p_resample->pll), @@ -121,20 +165,20 @@ static void audio_resample_init(struct audioresample *p_resample) { resample_clk_set(p_resample); - aml_resample_enable(p_resample->enable, + aml_set_resample(p_resample->id, p_resample->enable, p_resample->resample_module); } -static int audio_resample_set(int enable, int rate) +static int audio_resample_set( + struct audioresample *p_resample, + bool enable, int rate) { - if (!s_resample) { - pr_err("audio resample is not init\n"); - return -EINVAL; - } + if (!p_resample) + return 0; - s_resample->enable = (bool)enable; - s_resample->out_rate = rate; - audio_resample_init(s_resample); + p_resample->enable = enable; + p_resample->out_rate = rate; + audio_resample_init(p_resample); return 0; } @@ -185,42 +229,42 @@ static int resample_get_enum( struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); if (!p_resample) { - pr_info("audio resample is not init\n"); - return -EINVAL; + pr_debug("audio resample is not init\n"); + return 0; } - ucontrol->value.enumerated.item[0] = p_resample->asr_idx; + ucontrol->value.enumerated.item[0] = p_resample->asrc_rate_idx; return 0; } -int resample_set(int index) +int resample_set(int id, int index) { int resample_rate = resample_idx2rate(index); + struct audioresample *p_resample = get_audioresample(id); - if (!s_resample) { - pr_info("audio resample is not init\n"); - return -EINVAL; - } - - if (index == s_resample->asr_idx) + if (!p_resample) return 0; - s_resample->asr_idx = index; + if (index == p_resample->asrc_rate_idx) + return 0; - pr_info("%s %s\n", + p_resample->asrc_rate_idx = index; + + pr_info("%s resample_%c %s\n", __func__, + (id == 0) ? 'a' : 'b', auge_resample_texts[index]); - if (audio_resample_set(index, resample_rate)) + if (audio_resample_set(p_resample, (bool)index, resample_rate)) return 0; if ((index == 0) || (resample_rate == 0)) - resample_disable(); + resample_disable(p_resample->id); else { - resample_init(resample_rate); + resample_init(p_resample->id, resample_rate); - resample_set_hw_param(index - 1); + resample_set_hw_param(p_resample->id, index - 1); } return 0; @@ -230,9 +274,15 @@ static int resample_set_enum( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); int index = ucontrol->value.enumerated.item[0]; - resample_set(index); + if (!p_resample) { + pr_debug("audio resample is not init\n"); + return 0; + } + + resample_set(p_resample->id, index); return 0; } @@ -289,9 +339,13 @@ static const char *const auge_resample_module_texts[] = { "TDMIN_C", "SPDIFIN", "PDMIN", - "NONE", + "FRATV", /* NONE for axg, g12a, g12b */ "TDMIN_LB", - "LOOPBACK", + "LOOPBACK_A", + "FRHDMIRX", /* from tl1 chipset*/ + "LOOPBACK_B", + "SPDIFIN_LB", + "VAD", }; static const struct soc_enum auge_resample_module_enum = @@ -305,8 +359,8 @@ static int resample_module_get_enum( struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); if (!p_resample) { - pr_info("audio resample is not init\n"); - return -EINVAL; + pr_debug("audio resample is not init\n"); + return 0; } ucontrol->value.enumerated.item[0] = p_resample->resample_module; @@ -321,33 +375,53 @@ static int resample_module_set_enum( struct audioresample *p_resample = snd_kcontrol_chip(kcontrol); if (!p_resample) { - pr_info("audio resample is not init\n"); - return -EINVAL; + pr_debug("audio resample is not init\n"); + return 0; } p_resample->resample_module = ucontrol->value.enumerated.item[0]; /* update info to ddr */ - aml_resample_enable(p_resample->enable, + aml_set_resample(p_resample->id, + p_resample->enable, p_resample->resample_module); return 0; } -static const struct snd_kcontrol_new snd_resample_controls[] = { +static const struct snd_kcontrol_new asrc_a_controls[] = { SOC_ENUM_EXT("Hardware resample enable", auge_resample_enum, resample_get_enum, resample_set_enum), SOC_SINGLE_EXT_TLV("Hw resample pause enable", - EE_AUDIO_RESAMPLE_CTRL2, 24, 0x1, 0, + EE_AUDIO_RESAMPLEA_CTRL2, 24, 0x1, 0, mixer_audiobus_read, mixer_audiobus_write, NULL), SOC_SINGLE_EXT_TLV("Hw resample pause thd", - EE_AUDIO_RESAMPLE_CTRL2, 0, 0xffffff, 0, + EE_AUDIO_RESAMPLEA_CTRL2, 0, 0xffffff, 0, mixer_audiobus_read, mixer_audiobus_write, NULL), - SOC_ENUM_EXT("Hardware resample module", + SOC_ENUM_EXT("Hw resample module", + auge_resample_module_enum, + resample_module_get_enum, + resample_module_set_enum), +}; + +static const struct snd_kcontrol_new asrc_b_controls[] = { + SOC_ENUM_EXT("Hardware resample b enable", + auge_resample_enum, + resample_get_enum, + resample_set_enum), + SOC_SINGLE_EXT_TLV("Hw resample b pause enable", + EE_AUDIO_RESAMPLEB_CTRL2, 24, 0x1, 0, + mixer_audiobus_read, mixer_audiobus_write, + NULL), + SOC_SINGLE_EXT_TLV("Hw resample b pause thd", + EE_AUDIO_RESAMPLEB_CTRL2, 0, 0xffffff, 0, + mixer_audiobus_read, mixer_audiobus_write, + NULL), + SOC_ENUM_EXT("Hw resample b module", auge_resample_module_enum, resample_module_get_enum, resample_module_set_enum), @@ -358,12 +432,24 @@ int card_add_resample_kcontrols(struct snd_soc_card *card) unsigned int idx; int err; - for (idx = 0; idx < ARRAY_SIZE(snd_resample_controls); idx++) { - err = snd_ctl_add(card->snd_card, - snd_ctl_new1(&snd_resample_controls[idx], - s_resample)); - if (err < 0) - return err; + if (s_resample_a) { + for (idx = 0; idx < ARRAY_SIZE(asrc_a_controls); idx++) { + err = snd_ctl_add(card->snd_card, + snd_ctl_new1(&asrc_a_controls[idx], + s_resample_a)); + if (err < 0) + return err; + } + } + + if (s_resample_b) { + for (idx = 0; idx < ARRAY_SIZE(asrc_b_controls); idx++) { + err = snd_ctl_add(card->snd_card, + snd_ctl_new1(&asrc_b_controls[idx], + s_resample_b)); + if (err < 0) + return err; + } } return 0; @@ -373,6 +459,18 @@ static struct resample_chipinfo g12a_resample_chipinfo = { .dividor_fn = true, }; +static struct resample_chipinfo tl1_resample_a_chipinfo = { + .num = 2, + .id = RESAMPLE_A, + .dividor_fn = true, +}; + +static struct resample_chipinfo tl1_resample_b_chipinfo = { + .num = 2, + .id = RESAMPLE_B, + .dividor_fn = true, +}; + static const struct of_device_id resample_device_id[] = { { .compatible = "amlogic, axg-resample", @@ -381,6 +479,14 @@ static const struct of_device_id resample_device_id[] = { .compatible = "amlogic, g12a-resample", .data = &g12a_resample_chipinfo, }, + { + .compatible = "amlogic, tl1-resample-a", + .data = &tl1_resample_a_chipinfo, + }, + { + .compatible = "amlogic, tl1-resample-b", + .data = &tl1_resample_b_chipinfo, + }, {} }; MODULE_DEVICE_TABLE(of, resample_device_id); @@ -408,6 +514,9 @@ static int resample_platform_probe(struct platform_device *pdev) of_device_get_match_data(dev); if (!p_chipinfo) dev_warn_once(dev, "check whether to update resample chipinfo\n"); + else + p_resample->id = p_chipinfo->id; + p_resample->chipinfo = p_chipinfo; ret = of_property_read_u32(pdev->dev.of_node, "resample_module", @@ -458,8 +567,11 @@ static int resample_platform_probe(struct platform_device *pdev) } p_resample->dev = dev; - s_resample = p_resample; - dev_set_drvdata(&pdev->dev, p_resample); + + if (p_chipinfo && p_chipinfo->id == 1) + s_resample_b = p_resample; + else + s_resample_a = p_resample; return 0; } @@ -474,4 +586,3 @@ static struct platform_driver resample_platform_driver = { .probe = resample_platform_probe, }; module_platform_driver(resample_platform_driver); - diff --git a/sound/soc/amlogic/auge/resample.h b/sound/soc/amlogic/auge/resample.h index d0bb722b3f5d..a86c8c0de831 100644 --- a/sound/soc/amlogic/auge/resample.h +++ b/sound/soc/amlogic/auge/resample.h @@ -19,5 +19,8 @@ extern int card_add_resample_kcontrols(struct snd_soc_card *card); -extern int resample_set(int index); +extern int resample_set(int id, int index); + +extern int get_resample_module_num(void); + #endif diff --git a/sound/soc/amlogic/auge/resample_hw.c b/sound/soc/amlogic/auge/resample_hw.c index 0c40fea0e905..1722ce8eb82d 100644 --- a/sound/soc/amlogic/auge/resample_hw.c +++ b/sound/soc/amlogic/auge/resample_hw.c @@ -40,35 +40,43 @@ static u32 resample_coef_parameters_table[7][5] = { {0x00800000, 0x0, 0x0, 0x0, 0x0}, }; -void resample_enable(bool enable) +void resample_enable(int id, bool enable) { - audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0, + int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0; + int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id; + + audiobus_update_bits(reg, 0x1 << 31, 1 << 31); - audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0, + audiobus_update_bits(reg, 0x1 << 31, 0 << 31); - audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0, + audiobus_update_bits(reg, 0x1 << 28, enable << 28); } -int resample_init(int input_sr) +int resample_init(int id, int input_sr) { u16 Avg_cnt_init = 0; unsigned int clk_rate = 167000000;//clk81; + int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0; + int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id; if (input_sr) Avg_cnt_init = (u16)(clk_rate * 4 / input_sr); else pr_err("unsupport input sample rate:%d\n", input_sr); - pr_info("clk_rate = %u, input_sr = %d, Avg_cnt_init = %u\n", - clk_rate, input_sr, Avg_cnt_init); + pr_info("resample id:%c, clk_rate = %u, input_sr = %d, Avg_cnt_init = %u\n", + (id == 0) ? 'a' : 'b', + clk_rate, + input_sr, + Avg_cnt_init); - audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0, + audiobus_update_bits(reg, 0x3 << 26 | 0x3ff << 16 | 0xffff << 0, 0x0 << 26 | /* method0 */ RESAMPLE_CNT_CONTROL << 16 | @@ -77,23 +85,30 @@ int resample_init(int input_sr) return 0; } -int resample_disable(void) +int resample_disable(int id) { - audiobus_write(EE_AUDIO_RESAMPLE_CTRL0, 0); + int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0; + int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id; + + audiobus_write(reg, 0); return 0; } -int resample_set_hw_param(int index) +int resample_set_hw_param(int id, int index) { - int i; + int i, reg, offset; + offset = EE_AUDIO_RESAMPLEB_COEF0 - EE_AUDIO_RESAMPLEA_COEF0; + reg = EE_AUDIO_RESAMPLEA_COEF0 + offset * id; for (i = 0; i < 5; i++) { - audiobus_write((EE_AUDIO_RESAMPLE_COEF0 + i), + audiobus_write((reg + i), resample_coef_parameters_table[index][i]); } - audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL2, + offset = EE_AUDIO_RESAMPLEB_CTRL2 - EE_AUDIO_RESAMPLEA_CTRL2; + reg = EE_AUDIO_RESAMPLEA_CTRL2 + offset * id; + audiobus_update_bits(reg, 1 << 25, 1 << 25); return 0; @@ -101,23 +116,42 @@ int resample_set_hw_param(int index) void resample_src_select(int src) { - audiobus_update_bits(EE_AUDIO_RESAMPLE_CTRL0, + audiobus_update_bits(EE_AUDIO_RESAMPLEA_CTRL0, 0x3 << 29, src << 29); } -void resample_format_set(int ch_num, int bits) +void resample_src_select_ab(int id, int src) { - audiobus_write(EE_AUDIO_RESAMPLE_CTRL3, + int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3; + int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id; + + audiobus_update_bits(reg, + 0x7 << 16, + src << 16); +} + +void resample_format_set(int id, int ch_num, int bits) +{ + int offset = EE_AUDIO_RESAMPLEB_CTRL3 - EE_AUDIO_RESAMPLEA_CTRL3; + int reg = EE_AUDIO_RESAMPLEA_CTRL3 + offset * id; + + audiobus_write(reg, ch_num << 8 | (bits - 1) << 0); } -int resample_ctrl_read(int idx) +int resample_ctrl_read(int id) { - return audiobus_read(EE_AUDIO_RESAMPLE_CTRL0); + int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0; + int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id; + + return audiobus_read(reg); } -void resample_ctrl_write(int idx, int value) +void resample_ctrl_write(int id, int value) { - audiobus_write(EE_AUDIO_RESAMPLE_CTRL0, value); + int offset = EE_AUDIO_RESAMPLEB_CTRL0 - EE_AUDIO_RESAMPLEA_CTRL0; + int reg = EE_AUDIO_RESAMPLEA_CTRL0 + offset * id; + + audiobus_write(reg, value); } diff --git a/sound/soc/amlogic/auge/resample_hw.h b/sound/soc/amlogic/auge/resample_hw.h index e78be7350e83..1ec4b16c871a 100644 --- a/sound/soc/amlogic/auge/resample_hw.h +++ b/sound/soc/amlogic/auge/resample_hw.h @@ -17,14 +17,15 @@ #ifndef __AML_AUDIO_RESAMPLE_HW_H__ #define __AML_AUDIO_RESAMPLE_HW_H__ -extern void resample_enable(bool enable); -extern int resample_init(int input_sr); -extern int resample_disable(void); -extern int resample_set_hw_param(int index); +extern void resample_enable(int id, bool enable); +extern int resample_init(int id, int input_sr); +extern int resample_disable(int id); +extern int resample_set_hw_param(int id, int index); extern void resample_src_select(int src); -extern void resample_format_set(int ch_num, int bits); +extern void resample_src_select_ab(int id, int src); +extern void resample_format_set(int id, int ch_num, int bits); -extern int resample_ctrl_read(int idx); -extern void resample_ctrl_write(int idx, int value); +extern int resample_ctrl_read(int id); +extern void resample_ctrl_write(int id, int value); #endif diff --git a/sound/soc/amlogic/auge/sharebuffer.c b/sound/soc/amlogic/auge/sharebuffer.c index 1ca66ad386fb..f94fd2a03b0c 100644 --- a/sound/soc/amlogic/auge/sharebuffer.c +++ b/sound/soc/amlogic/auge/sharebuffer.c @@ -34,7 +34,9 @@ static int sharebuffer_spdifout_prepare(struct snd_pcm_substream *substream, spdifout_samesource_set(spdif_id, aml_frddr_get_fifo_id(fr), - bit_depth, true); + bit_depth, + runtime->channels, + true); /* spdif to hdmitx */ spdifout_to_hdmitx_ctrl(spdif_id); @@ -59,7 +61,9 @@ static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream, if (spdif_id != 1) spdifout_samesource_set(spdif_id, aml_frddr_get_fifo_id(fr), - bit_depth, false); + bit_depth, + runtime->channels, + false); return 0; } @@ -90,7 +94,8 @@ int sharebuffer_prepare(struct snd_pcm_substream *substream, // TODO: same with tdm } else if (samesource_sel < 5) { /* same source with spdif a/b */ - sharebuffer_spdifout_prepare(substream, fr, samesource_sel - 3); + sharebuffer_spdifout_prepare(substream, + fr, samesource_sel - 3); } /* frddr, share buffer, src_sel1 */ diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 2aa663b53a33..b28d920a6e1f 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -14,7 +14,7 @@ * more details. * */ - +#define DEBUG #include #include #include @@ -51,6 +51,8 @@ /* for debug */ /*#define __SPDIFIN_INSERT_CHNUM__*/ +/*#define __SPDIFIN_AUDIO_TYPE_HW__*/ + struct spdif_chipinfo { unsigned int id; @@ -68,6 +70,8 @@ struct spdif_chipinfo { bool hold_start; /* eq/drc */ bool eq_drc_en; + /* pc, pd interrupt is separated. */ + bool pcpd_separated; }; struct aml_spdif { @@ -93,10 +97,15 @@ struct aml_spdif { struct spdif_chipinfo *chipinfo; unsigned int clk_cont; /* CONTINUOUS CLOCK */ + /* + * resample a/b do asrc for spdif in + */ + unsigned int asrc_id; /* spdif in do asrc for pcm, * if raw data, disable it automatically. */ - unsigned int auto_asrc; + unsigned int auto_asrc; + /* check spdifin channel status for pcm or nonpcm */ struct timer_list timer; struct work_struct work; @@ -113,6 +122,9 @@ struct aml_spdif { int is_reset; int last_sample_rate_mode; + /* last value for pc, pd */ + int pc_last; + int pd_last; }; static const struct snd_pcm_hardware aml_spdif_hardware = { @@ -226,7 +238,7 @@ static int spdifin_check_audio_type(void) } } - pr_info("%s audio type:%d\n", __func__, audio_type); + /*pr_debug("%s audio type:%d\n", __func__, audio_type);*/ return audio_type; } @@ -241,9 +253,58 @@ static int spdifin_audio_type_get_enum( return 0; } +/* For fake */ +static bool is_mute; +static int spdifin_src; +static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + is_mute = + ucontrol->value.integer.value[0]; + return 0; +} + +static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = is_mute; + + return 0; +} +static const char *const spdifin_src_texts[] = { + "spdifin pad", "spdifout", "N/A", "HDMIRX" +}; + +const struct soc_enum spdifin_src_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdifin_src_texts), + spdifin_src_texts); + +int spdifin_source_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = spdifin_src; + return 0; +} + +int spdifin_source_set_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int src = ucontrol->value.enumerated.item[0]; + + if (src > 3) { + pr_err("bad parameter for spdifin src set\n"); + return -1; + } + spdifin_set_src(src); + spdifin_src = src; + return 0; +} + static const struct snd_kcontrol_new snd_spdif_controls[] = { - SOC_ENUM_EXT("SPDIFIN Sample Rate", spdifin_sample_rate_enum, + SOC_ENUM_EXT("SPDIFIN audio samplerate", spdifin_sample_rate_enum, spdifin_samplerate_get_enum, NULL), @@ -251,6 +312,20 @@ static const struct snd_kcontrol_new snd_spdif_controls[] = { spdif_audio_type_enum, spdifin_audio_type_get_enum, NULL), + + SOC_ENUM_EXT("Audio spdif format", + spdif_format_enum, + spdif_format_get_enum, + spdif_format_set_enum), + + SOC_SINGLE_BOOL_EXT("Audio spdif mute", + 0, aml_audio_get_spdif_mute, + aml_audio_set_spdif_mute), + SOC_ENUM_EXT("Audio spdifin source", + spdifin_src_enum, + spdifin_source_get_enum, + spdifin_source_set_enum), + }; static bool spdifin_check_audiotype_by_sw(struct aml_spdif *p_spdif) @@ -296,12 +371,16 @@ static void spdifin_audio_type_work_func(struct work_struct *work) if (!p_spdif->auto_asrc) return; +#ifdef __PTM_SPDIF_CLK__ + return; +#endif + if (val & 0x2) /* nonpcm, resample disable */ - resample_set(0); + resample_set(p_spdif->asrc_id, 0); else /* pcm, resample which rate ? */ - resample_set(p_spdif->auto_asrc); + resample_set(p_spdif->asrc_id, p_spdif->auto_asrc); } static void spdifin_audio_type_detect_init(struct aml_spdif *p_spdif) @@ -334,13 +413,13 @@ static void spdifin_fast_reset(struct aml_spdif *p_spdif) /* resample disable and reset */ if (p_spdif->auto_asrc) { - asr_ctrl_val = resample_ctrl_read(0); + asr_ctrl_val = resample_ctrl_read(p_spdif->asrc_id); asr_ctrl_val &= ~(1 << 28); - resample_ctrl_write(0, asr_ctrl_val); + resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val); asr_ctrl_val |= (1 << 31); - resample_ctrl_write(0, asr_ctrl_val); + resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val); asr_ctrl_val &= ~(1 << 31); - resample_ctrl_write(0, asr_ctrl_val); + resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val); } /* spdif in disable and reset */ @@ -364,7 +443,7 @@ static void spdifin_fast_reset(struct aml_spdif *p_spdif) /* resample enable */ if (p_spdif->auto_asrc) { asr_ctrl_val |= (1 << 28); - resample_ctrl_write(0, asr_ctrl_val); + resample_ctrl_write(p_spdif->asrc_id, asr_ctrl_val); } /* spdif in enable */ @@ -483,10 +562,12 @@ static void spdifin_status_event(struct aml_spdif *p_spdif) pr_info("Event: EXTCON_SPDIFIN_SAMPLERATE, new sample rate:%s\n", spdifin_samplerate[mode + 1]); +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample enable, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) - resample_set(p_spdif->auto_asrc); - + resample_set(p_spdif->asrc_id, + p_spdif->auto_asrc); +#endif extcon_set_state(p_spdif->edev, EXTCON_SPDIFIN_SAMPLERATE, 1); } @@ -495,26 +576,54 @@ static void spdifin_status_event(struct aml_spdif *p_spdif) } - if (intrpt_status & 0x8) { - pr_info("Pc changed, try to read spdifin audio type\n"); + if (p_spdif->chipinfo + && p_spdif->chipinfo->pcpd_separated) { + if (intrpt_status & 0x8) { + pr_info("Pc changed, try to read spdifin audio type\n"); - extcon_set_state(p_spdif->edev, - EXTCON_SPDIFIN_AUDIOTYPE, 1); + extcon_set_state(p_spdif->edev, + EXTCON_SPDIFIN_AUDIOTYPE, 1); - /* resample disable, by hw */ - if (!spdifin_check_audiotype_by_sw(p_spdif)) - resample_set(0); +#ifdef __PTM_SPDIF_CLK__ +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ + /* resample disable, by hw */ + if (!spdifin_check_audiotype_by_sw(p_spdif)) + resample_set(p_spdif->asrc_id, 0); +#endif +#endif + } + if (intrpt_status & 0x10) + pr_info("Pd changed\n"); + } else { + if (intrpt_status & 0x8) + pr_debug("CH status changed\n"); + + if (intrpt_status & 0x10) { + int val = spdifin_get_ch_status0to31(); + int pc_v = (val >> 16) & 0xffff; + int pd_v = val & 0xffff; + + if (pc_v != p_spdif->pc_last) { + p_spdif->pc_last = pc_v; + pr_info("Pc changed\n"); + } + if (pd_v != p_spdif->pd_last) { + p_spdif->pd_last = pd_v; + pr_info("Pd changed\n"); + } + } } - if (intrpt_status & 0x10) - pr_info("Pd changed\n"); + if (intrpt_status & 0x20) { pr_info("nonpcm to pcm\n"); extcon_set_state(p_spdif->edev, EXTCON_SPDIFIN_AUDIOTYPE, 0); +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample to 48k, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) - resample_set(p_spdif->auto_asrc); + resample_set(p_spdif->asrc_id, p_spdif->auto_asrc); +#endif } if (intrpt_status & 0x40) pr_info("valid changed\n"); @@ -751,7 +860,7 @@ static struct snd_pcm_ops aml_spdif_ops = { .mmap = aml_spdif_mmap, }; -#define PREALLOC_BUFFER (32 * 1024) +#define PREALLOC_BUFFER (128 * 1024) #define PREALLOC_BUFFER_MAX (256 * 1024) static int aml_spdif_new(struct snd_soc_pcm_runtime *rtd) { @@ -760,7 +869,7 @@ static int aml_spdif_new(struct snd_soc_pcm_runtime *rtd) p_spdif = (struct aml_spdif *)dev_get_drvdata(dev); - pr_info("%s spdif_%s, clk continuous:%d\n", + pr_debug("%s spdif_%s, clk continuous:%d\n", __func__, (p_spdif->id == 0) ? "a":"b", p_spdif->clk_cont); @@ -814,10 +923,6 @@ static int aml_dai_spdif_startup( struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai); int ret; - pr_info("%s stream:%d\n", - __func__, - substream->stream); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (p_spdif->clk_cont) { @@ -871,9 +976,12 @@ static int aml_dai_spdif_startup( pr_err("Can't enable pcm clk_spdifin clock: %d\n", ret); goto err; } + +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample to 48k in default, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) - resample_set(p_spdif->auto_asrc); + resample_set(p_spdif->asrc_id, p_spdif->auto_asrc); +#endif } return 0; @@ -888,10 +996,6 @@ static void aml_dai_spdif_shutdown( { struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai); - pr_info("%s, stream:%d\n", - __func__, - substream->stream); - /* disable clock and gate */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (p_spdif->clk_cont) { @@ -904,10 +1008,11 @@ static void aml_dai_spdif_shutdown( clk_disable_unprepare(p_spdif->sysclk); clk_disable_unprepare(p_spdif->gate_spdifout); } else { +#ifdef __SPDIFIN_AUDIO_TYPE_HW__ /* resample disabled, by hw */ if (!spdifin_check_audiotype_by_sw(p_spdif)) - resample_set(0); - + resample_set(p_spdif->asrc_id, 0); +#endif clk_disable_unprepare(p_spdif->clk_spdifin); clk_disable_unprepare(p_spdif->fixed_clk); clk_disable_unprepare(p_spdif->gate_spdifin); @@ -933,7 +1038,7 @@ static int aml_dai_spdif_prepare( switch (p_spdif->id) { case 0: - dst = SPDIFOUT; + dst = SPDIFOUT_A; break; case 1: dst = SPDIFOUT_B; @@ -944,6 +1049,10 @@ static int aml_dai_spdif_prepare( } fifo_id = aml_frddr_get_fifo_id(fr); + aml_frddr_set_format(fr, + runtime->channels, + bit_depth - 1, + spdifout_get_frddr_type(bit_depth)); aml_frddr_select_dst(fr, dst); aml_frddr_set_fifos(fr, 0x40, 0x20); @@ -1110,7 +1219,7 @@ static int aml_dai_spdif_hw_params(struct snd_pcm_substream *substream, static int aml_dai_set_spdif_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - pr_info("%s , fmt %#x\n", __func__, fmt); + pr_debug("%s , fmt %#x\n", __func__, fmt); return 0; } @@ -1119,29 +1228,22 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif) { unsigned int mpll_freq = 0; - pr_info("%s, sys freq:%d\n", - __func__, - p_spdif->sysclk_freq); - if (p_spdif->sysclk_freq) { unsigned int mul = 4; int ret; if (spdif_is_4x_clk()) { - pr_info("set 4x audio clk for 958\n"); + pr_debug("set 4x audio clk for 958\n"); p_spdif->sysclk_freq *= 4; } else { - pr_info("set normal 512 fs /4 fs\n"); + pr_debug("set normal 512 fs /4 fs\n"); } mpll_freq = p_spdif->sysclk_freq * mul; #ifdef __PTM_SPDIF_CLK__ - mpll_freq = p_spdif->sysclk_freq * 58; + /* mpll_freq = p_spdif->sysclk_freq * 58; */ /* 48k */ + mpll_freq = p_spdif->sysclk_freq * 58 / 2; /* 96k */ #endif - pr_info("\t finally sys freq:%d, mpll freq:%d\n", - p_spdif->sysclk_freq, - mpll_freq); - clk_set_rate(p_spdif->sysclk, mpll_freq); clk_set_rate(p_spdif->clk_spdifout, p_spdif->sysclk_freq); @@ -1156,18 +1258,18 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif) pr_err("Can't enable clk_spdifout clock: %d\n", ret); return; } + pr_debug("\t set spdifout clk:%d, mpll:%d\n", + p_spdif->sysclk_freq, + mpll_freq); + pr_debug("\t get spdifout clk:%lu, mpll:%lu\n", + clk_get_rate(p_spdif->clk_spdifout), + clk_get_rate(p_spdif->sysclk)); } } static int aml_dai_set_spdif_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { - pr_info("%s, clk_id:%d, freq:%d, dir:%d\n", - __func__, - clk_id, - freq, - dir); - if (clk_id == 0) { struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai); @@ -1297,12 +1399,19 @@ static int aml_spdif_parse_of(struct platform_device *pdev) if (ret < 0) pr_err("SPDIF IN extcon failed to register!!, ignore it\n"); + ret = of_property_read_u32(pdev->dev.of_node, + "asrc_id", &p_spdif->asrc_id); + if (ret < 0) + p_spdif->asrc_id = 0; + ret = of_property_read_u32(pdev->dev.of_node, "auto_asrc", &p_spdif->auto_asrc); if (ret < 0) p_spdif->auto_asrc = 0; - pr_info("SPDIF id %d auto_asrc:%d\n", + + pr_debug("SPDIF id %d asrc_id:%d auto_asrc:%d\n", p_spdif->id, + p_spdif->asrc_id, p_spdif->auto_asrc); } @@ -1333,20 +1442,23 @@ struct spdif_chipinfo axg_spdif_chipinfo = { .id = SPDIF_A, .irq_no_papb = true, .clr_irq_all_bits = true, + .pcpd_separated = true, }; struct spdif_chipinfo g12a_spdif_a_chipinfo = { - .id = SPDIF_A, - .chnum_en = true, - .hold_start = true, - .eq_drc_en = true, + .id = SPDIF_A, + .chnum_en = true, + .hold_start = true, + .eq_drc_en = true, + .pcpd_separated = true, }; struct spdif_chipinfo g12a_spdif_b_chipinfo = { - .id = SPDIF_B, - .chnum_en = true, - .hold_start = true, - .eq_drc_en = true, + .id = SPDIF_B, + .chnum_en = true, + .hold_start = true, + .eq_drc_en = true, + .pcpd_separated = true, }; struct spdif_chipinfo tl1_spdif_a_chipinfo = { @@ -1422,7 +1534,7 @@ static int aml_spdif_platform_probe(struct platform_device *pdev) dev_warn_once(dev, "check whether to update spdif chipinfo\n"); - pr_info("%s, spdif ID = %u\n", __func__, aml_spdif->id); + pr_debug("%s, spdif ID = %u\n", __func__, aml_spdif->id); /* get audio controller */ node_prt = of_get_parent(node); diff --git a/sound/soc/amlogic/auge/spdif_hw.c b/sound/soc/amlogic/auge/spdif_hw.c index fedbac29d5c0..65b4d4703950 100644 --- a/sound/soc/amlogic/auge/spdif_hw.c +++ b/sound/soc/amlogic/auge/spdif_hw.c @@ -14,7 +14,7 @@ * more details. * */ - +#define DEBUG #include #include "iomap.h" @@ -64,7 +64,7 @@ void aml_spdifin_chnum_en(struct aml_audio_controller *actrl, reg = EE_AUDIO_SPDIFIN_CTRL0; aml_audiobus_update_bits(actrl, reg, 1 << 26, is_enable << 26); - pr_info("%s spdifin ctrl0:0x%x\n", + pr_debug("%s spdifin ctrl0:0x%x\n", __func__, aml_audiobus_read(actrl, reg)); } @@ -179,6 +179,32 @@ void aml_spdif_fifo_reset( } } +int spdifout_get_frddr_type(int bitwidth) +{ + unsigned int frddr_type = 0; + + switch (bitwidth) { + case 8: + frddr_type = 0; + break; + case 16: + frddr_type = 1; + break; + case 24: + frddr_type = 4; + break; + case 32: + frddr_type = 3; + break; + default: + pr_err("runtime format invalid bitwidth: %d\n", + bitwidth); + break; + } + + return frddr_type; +} + void aml_spdif_fifo_ctrl( struct aml_audio_controller *actrl, int bitwidth, @@ -186,23 +212,20 @@ void aml_spdif_fifo_ctrl( int index, unsigned int fifo_id) { - unsigned int frddr_type, toddr_type; + unsigned int toddr_type; + unsigned int frddr_type = spdifout_get_frddr_type(bitwidth); switch (bitwidth) { case 8: - frddr_type = 0; toddr_type = 0; break; case 16: - frddr_type = 1; toddr_type = 1; break; case 24: - frddr_type = 4; toddr_type = 4; break; case 32: - frddr_type = 3; toddr_type = 3; break; default: @@ -211,7 +234,7 @@ void aml_spdif_fifo_ctrl( return; } - pr_info("%s, bit depth:%d, frddr type:%d, toddr:type:%d\n", + pr_debug("%s, bit depth:%d, frddr type:%d, toddr:type:%d\n", __func__, bitwidth, frddr_type, @@ -336,7 +359,7 @@ void aml_spdifout_select_aed(bool enable, int spdifout_id) /* select eq_drc output */ offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1; reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdifout_id; - audiobus_update_bits(reg, 0x1 << 31, enable << 31); + audiobus_update_bits(reg, 0x1 << 21, enable << 21); } void aml_spdifout_get_aed_info(int spdifout_id, @@ -380,31 +403,16 @@ void spdifout_clk_ctrl(int spdif_id, bool is_enable) audiobus_write(reg, is_enable << 31 | 0x0 << 24 | 0x3 << 0); } -void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth) +static void spdifout_fifo_ctrl(int spdif_id, + int fifo_id, int bitwidth, int channels) { - unsigned int frddr_type; - unsigned int offset, reg; + unsigned int frddr_type = spdifout_get_frddr_type(bitwidth); + unsigned int offset, reg, i, chmask = 0; - switch (bitwidth) { - case 8: - frddr_type = 0; - break; - case 16: - frddr_type = 1; - break; - case 24: - frddr_type = 4; - break; - case 32: - frddr_type = 3; - break; - default: - pr_err("runtime format invalid bitwidth: %d\n", - bitwidth); - return; - } + for (i = 0; i < channels; i++) + chmask |= (1 << i); - pr_info("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n", + pr_debug("spdif_%s fifo ctrl, frddr:%d type:%d, %d bits\n", (spdif_id == 0) ? "a":"b", fifo_id, frddr_type, @@ -415,7 +423,7 @@ void spdifout_fifo_ctrl(int spdif_id, int fifo_id, int bitwidth) reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id; audiobus_update_bits(reg, 0x3<<21|0x1<<20|0x1<<19|0xff<<4, - 0x0<<21|0<<20|0<<19|0x3<<4); + 0x0<<21|0<<20|0<<19|chmask<<4); offset = EE_AUDIO_SPDIFOUT_B_CTRL1 - EE_AUDIO_SPDIFOUT_CTRL1; reg = EE_AUDIO_SPDIFOUT_CTRL1 + offset * spdif_id; @@ -450,7 +458,7 @@ void spdifout_enable(int spdif_id, bool is_enable) { unsigned int offset, reg; - pr_info("spdif_%s is set to %s\n", + pr_debug("spdif_%s is set to %s\n", (spdif_id == 0) ? "a":"b", is_enable ? "enable":"disable"); @@ -467,7 +475,7 @@ void spdifout_enable(int spdif_id, bool is_enable) } void spdifout_samesource_set(int spdif_index, int fifo_id, - int bitwidth, bool is_enable) + int bitwidth, int channels, bool is_enable) { int spdif_id; @@ -481,7 +489,7 @@ void spdifout_samesource_set(int spdif_index, int fifo_id, spdifout_clk_ctrl(spdif_id, /*is_enable*/true); if (is_enable) - spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth); + spdifout_fifo_ctrl(spdif_id, fifo_id, bitwidth, channels); } int spdifin_get_sample_rate(void) @@ -524,6 +532,11 @@ int spdifin_get_audio_type(void) return (val >> 16) & 0xff; } +void spdifin_set_src(int src) +{ + audiobus_update_bits(EE_AUDIO_SPDIFIN_CTRL0, 0x3 << 4, src << 4); +} + void spdif_set_channel_status_info( struct iec958_chsts *chsts, int spdif_id) { @@ -585,7 +598,7 @@ void spdif_set_channel_status_info( void spdifout_play_with_zerodata(unsigned int spdif_id) { - pr_info("%s, spdif id:%d enable:%d\n", + pr_debug("%s, spdif id:%d enable:%d\n", __func__, spdif_id, spdifout_is_enable(spdif_id)); @@ -615,7 +628,8 @@ void spdifout_play_with_zerodata(unsigned int spdif_id) spdifout_to_hdmitx_ctrl(spdif_id); /* spdif ctrl */ - spdifout_fifo_ctrl(spdif_id, frddr_index, bitwidth); + spdifout_fifo_ctrl(spdif_id, + frddr_index, bitwidth, runtime.channels); /* channel status info */ spdif_get_channel_status_info(&chsts, sample_rate); @@ -634,7 +648,7 @@ void spdifout_play_with_zerodata(unsigned int spdif_id) void spdifout_play_with_zerodata_free(unsigned int spdif_id) { - pr_info("%s, spdif id:%d\n", + pr_debug("%s, spdif id:%d\n", __func__, spdif_id); diff --git a/sound/soc/amlogic/auge/spdif_hw.h b/sound/soc/amlogic/auge/spdif_hw.h index c2e529c8ef2e..3e133f620fba 100644 --- a/sound/soc/amlogic/auge/spdif_hw.h +++ b/sound/soc/amlogic/auge/spdif_hw.h @@ -51,6 +51,8 @@ extern void aml_spdif_fifo_reset( struct aml_audio_controller *actrl, int stream, int index); +extern int spdifout_get_frddr_type(int bitwidth); + extern void aml_spdif_fifo_ctrl( struct aml_audio_controller *actrl, int bitwidth, @@ -72,7 +74,7 @@ extern void aml_spdifout_get_aed_info(int spdifout_id, extern void spdifout_to_hdmitx_ctrl(int spdif_index); extern void spdifout_samesource_set(int spdif_index, int fifo_id, - int bitwidth, bool is_enable); + int bitwidth, int channels, bool is_enable); extern void spdifout_enable(int spdif_id, bool is_enable); extern int spdifin_get_sample_rate(void); @@ -86,4 +88,5 @@ extern void spdif_set_channel_status_info( extern void spdifout_play_with_zerodata(unsigned int spdif_id); extern void spdifout_play_with_zerodata_free(unsigned int spdif_id); +extern void spdifin_set_src(int src); #endif diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 139a92fe8aeb..f227be4751dd 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -14,7 +14,7 @@ * more details. * */ - +#define DEBUG #include #include #include @@ -38,10 +38,11 @@ #include "ddr_mngr.h" #include "tdm_hw.h" +#include "sharebuffer.h" +#include "vad.h" /*#define __PTM_TDM_CLK__*/ -#include "sharebuffer.h" #define DRV_NAME "aml_tdm" @@ -55,22 +56,22 @@ static void dump_pcm_setting(struct pcm_setting *setting) if (setting == NULL) return; - pr_info("dump_pcm_setting(%p)\n", setting); - pr_info("\tpcm_mode(%d)\n", setting->pcm_mode); - pr_info("\tsysclk(%d)\n", setting->sysclk); - pr_info("\tsysclk_bclk_ratio(%d)\n", setting->sysclk_bclk_ratio); - pr_info("\tbclk(%d)\n", setting->bclk); - pr_info("\tbclk_lrclk_ratio(%d)\n", setting->bclk_lrclk_ratio); - pr_info("\tlrclk(%d)\n", setting->lrclk); - pr_info("\ttx_mask(%#x)\n", setting->tx_mask); - pr_info("\trx_mask(%#x)\n", setting->rx_mask); - pr_info("\tslots(%d)\n", setting->slots); - pr_info("\tslot_width(%d)\n", setting->slot_width); - pr_info("\tlane_mask_in(%#x)\n", setting->lane_mask_in); - pr_info("\tlane_mask_out(%#x)\n", setting->lane_mask_out); - pr_info("\tlane_oe_mask_in(%#x)\n", setting->lane_oe_mask_in); - pr_info("\tlane_oe_mask_out(%#x)\n", setting->lane_oe_mask_out); - pr_info("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in); + pr_debug("dump_pcm_setting(%p)\n", setting); + pr_debug("\tpcm_mode(%d)\n", setting->pcm_mode); + pr_debug("\tsysclk(%d)\n", setting->sysclk); + pr_debug("\tsysclk_bclk_ratio(%d)\n", setting->sysclk_bclk_ratio); + pr_debug("\tbclk(%d)\n", setting->bclk); + pr_debug("\tbclk_lrclk_ratio(%d)\n", setting->bclk_lrclk_ratio); + pr_debug("\tlrclk(%d)\n", setting->lrclk); + pr_debug("\ttx_mask(%#x)\n", setting->tx_mask); + pr_debug("\trx_mask(%#x)\n", setting->rx_mask); + pr_debug("\tslots(%d)\n", setting->slots); + pr_debug("\tslot_width(%d)\n", setting->slot_width); + pr_debug("\tlane_mask_in(%#x)\n", setting->lane_mask_in); + pr_debug("\tlane_mask_out(%#x)\n", setting->lane_mask_out); + pr_debug("\tlane_oe_mask_in(%#x)\n", setting->lane_oe_mask_in); + pr_debug("\tlane_oe_mask_out(%#x)\n", setting->lane_oe_mask_out); + pr_debug("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in); } struct tdm_chipinfo { @@ -88,6 +89,9 @@ struct tdm_chipinfo { /* same source */ bool same_src_fn; + + /* ACODEC_ADC function */ + bool adc_fn; }; struct aml_tdm { @@ -111,6 +115,10 @@ struct aml_tdm { int samesource_sel; /* virtual link for i2s to hdmitx */ int i2s2hdmitx; + int acodec_adc; + uint last_mpll_freq; + uint last_mclk_freq; + uint last_fmt; }; static const struct snd_pcm_hardware aml_tdm_hardware = { @@ -349,7 +357,7 @@ static struct snd_pcm_ops aml_tdm_ops = { .mmap = aml_tdm_mmap, }; -#define PREALLOC_BUFFER (32 * 1024) +#define PREALLOC_BUFFER (128 * 1024) #define PREALLOC_BUFFER_MAX (256 * 1024) static int aml_tdm_new(struct snd_soc_pcm_runtime *rtd) { @@ -363,33 +371,6 @@ struct snd_soc_platform_driver aml_tdm_platform = { .pcm_new = aml_tdm_new, }; -static int aml_dai_tdm_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai) -{ - struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - - ret = clk_prepare_enable(p_tdm->mclk); - if (ret) { - pr_err("Can't enable mclk: %d\n", ret); - goto err; - } - - return ret; -err: - pr_err("failed enable clock\n"); - return ret; -} - -static void aml_dai_tdm_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *cpu_dai) -{ - struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - - /* disable clock and gate */ - clk_disable_unprepare(p_tdm->mclk); -} - static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { @@ -399,7 +380,6 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, bit_depth = snd_pcm_format_width(runtime->format); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { struct frddr *fr = p_tdm->fddr; enum frddr_dest dst; @@ -444,6 +424,10 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, p_tdm->id); return -EINVAL; } + aml_frddr_set_format(fr, + runtime->channels, + bit_depth - 1, + tdmout_get_frddr_type(bit_depth)); aml_frddr_select_dst(fr, dst); aml_frddr_set_fifos(fr, 0x40, 0x20); } else { @@ -453,6 +437,10 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, unsigned int toddr_type; struct toddr_fmt fmt; + if (vad_tdm_is_running(p_tdm->id) + && pm_audio_is_suspend()) + return 0; + switch (bit_depth) { case 8: case 16: @@ -488,8 +476,15 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, if (toddr_src_get() == FRHDMIRX) { src = FRHDMIRX; - tdm_update_slot_in(p_tdm->actrl, p_tdm->id, HDMIRX_I2S); - } + aml_update_tdmin_src(p_tdm->actrl, + p_tdm->id, + HDMIRX_I2S); + } else if (p_tdm->chipinfo + && p_tdm->chipinfo->adc_fn + && p_tdm->acodec_adc) + aml_update_tdmin_src(p_tdm->actrl, + p_tdm->id, + ACODEC_ADC); pr_info("%s Expected toddr src:%s\n", __func__, @@ -529,6 +524,16 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && vad_tdm_is_running(p_tdm->id) + && pm_audio_is_suspend()) { + pm_audio_set_suspend(false); + /* VAD switch to alsa buffer */ + vad_update_buffer(0); + break; + } + /* reset fifo here. * If not, xrun will cause channel mapping mismatch */ @@ -548,6 +553,14 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && vad_tdm_is_running(p_tdm->id) + && pm_audio_is_suspend()) { + /* switch to VAD buffer */ + vad_update_buffer(1); + break; + } + aml_tdm_enable(p_tdm->actrl, substream->stream, p_tdm->id, false); @@ -714,6 +727,11 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, return ret; } + /* Must enabe channel number for VAD */ + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && (vad_tdm_is_running(p_tdm->id))) + tdmin_set_chnum_en(p_tdm->actrl, p_tdm->id, true); + /* share buffer trigger */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && p_tdm->chipinfo @@ -731,6 +749,15 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, rate * ratio * mux); } + if (!p_tdm->contns_clk && !IS_ERR(p_tdm->mclk)) { + pr_debug("%s(), enable mclk for %s", __func__, cpu_dai->name); + ret = clk_prepare_enable(p_tdm->mclk); + if (ret) { + pr_err("Can't enable mclk: %d\n", ret); + return ret; + } + } + return 0; } @@ -745,6 +772,11 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream, aml_tdm_set_channel_mask(p_tdm->actrl, substream->stream, p_tdm->id, i, 0); + /* Disable channel number for VAD */ + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) + && (vad_tdm_is_running(p_tdm->id))) + tdmin_set_chnum_en(p_tdm->actrl, p_tdm->id, false); + /* share buffer free */ if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) && p_tdm->chipinfo @@ -756,6 +788,12 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream, fr, p_tdm->samesource_sel); } + /* disable clock and gate */ + if (!p_tdm->contns_clk && !IS_ERR(p_tdm->mclk)) { + pr_info("%s(), disable mclk for %s", __func__, cpu_dai->name); + clk_disable_unprepare(p_tdm->mclk); + } + return 0; } @@ -763,8 +801,14 @@ static int aml_dai_set_tdm_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); - pr_info("asoc aml_dai_set_tdm_fmt, %#x, %p, id(%d), clksel(%d)\n", + pr_debug("asoc aml_dai_set_tdm_fmt, %#x, %p, id(%d), clksel(%d)\n", fmt, p_tdm, p_tdm->id, p_tdm->clk_sel); + if (p_tdm->last_fmt == fmt) { + pr_debug("%s(), fmt not change\n", __func__); + goto capture; + } else + p_tdm->last_fmt = fmt; + switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { case SND_SOC_DAIFMT_CONT: p_tdm->contns_clk = true; @@ -781,8 +825,17 @@ static int aml_dai_set_tdm_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) aml_tdm_set_format(p_tdm->actrl, &(p_tdm->setting), p_tdm->clk_sel, p_tdm->id, fmt, - cpu_dai->capture_active, - cpu_dai->playback_active); + 1, 1); + +capture: + /* update skew for ACODEC_ADC */ + if (cpu_dai->capture_active + && p_tdm->chipinfo + && p_tdm->chipinfo->adc_fn + && p_tdm->acodec_adc){ + aml_update_tdmin_skew(p_tdm->actrl, p_tdm->id, 4); + aml_update_tdmin_rev_ws(p_tdm->actrl, p_tdm->id, 0); + } return 0; } @@ -810,9 +863,7 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai, { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); unsigned int ratio = aml_mpll_mclk_ratio(freq); - - pr_info("aml_dai_set_tdm_sysclk freq(%d), mpll/mclk(%d)\n", - freq, ratio); + unsigned int mpll_freq = 0; p_tdm->setting.sysclk = freq; @@ -825,8 +876,26 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai, ratio = 20; #endif - clk_set_rate(p_tdm->clk, freq * ratio); - clk_set_rate(p_tdm->mclk, freq); + mpll_freq = freq * ratio; + if (mpll_freq != p_tdm->last_mpll_freq) { + clk_set_rate(p_tdm->clk, mpll_freq); + p_tdm->last_mpll_freq = mpll_freq; + } else { + pr_debug("%s(), mpll no change, keep clk\n", __func__); + } + + if (freq != p_tdm->last_mclk_freq) { + clk_set_rate(p_tdm->mclk, freq); + p_tdm->last_mclk_freq = freq; + } else { + pr_debug("%s(), mclk no change, keep clk\n", __func__); + } + + pr_debug("set mclk:%d, mpll:%d, get mclk:%lu, mpll:%lu\n", + freq, + freq * ratio, + clk_get_rate(p_tdm->mclk), + clk_get_rate(p_tdm->clk)); return 0; } @@ -843,10 +912,10 @@ static int aml_dai_set_bclk_ratio(struct snd_soc_dai *cpu_dai, if (p_tdm->setting.pcm_mode == SND_SOC_DAIFMT_I2S || p_tdm->setting.pcm_mode == SND_SOC_DAIFMT_LEFT_J) { - pr_info("aml_dai_set_bclk_ratio, select I2S mode\n"); + pr_debug("aml_dai_set_bclk_ratio, select I2S mode\n"); lrclk_hi = bclk_ratio / 2; } else { - pr_info("aml_dai_set_bclk_ratio, select TDM mode\n"); + pr_debug("aml_dai_set_bclk_ratio, select TDM mode\n"); } aml_tdm_set_bclk_ratio(p_tdm->actrl, p_tdm->clk_sel, lrclk_hi, bclk_ratio); @@ -889,15 +958,15 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, lanes_oe_in_cnt = pop_count(p_tdm->setting.lane_oe_mask_in); lanes_lb_cnt = pop_count(p_tdm->setting.lane_lb_mask_in); - pr_info("%s(), txmask(%#x), rxmask(%#x)\n", + pr_debug("%s(), txmask(%#x), rxmask(%#x)\n", __func__, tx_mask, rx_mask); - pr_info("\tlanes_out_cnt(%d), lanes_in_cnt(%d)\n", + pr_debug("\tlanes_out_cnt(%d), lanes_in_cnt(%d)\n", lanes_out_cnt, lanes_in_cnt); - pr_info("\tlanes_oe_out_cnt(%d), lanes_oe_in_cnt(%d)\n", + pr_debug("\tlanes_oe_out_cnt(%d), lanes_oe_in_cnt(%d)\n", lanes_oe_out_cnt, lanes_oe_in_cnt); - pr_info("\tlanes_lb_cnt(%d)\n", + pr_debug("\tlanes_lb_cnt(%d)\n", lanes_lb_cnt); - pr_info("\tslots(%d), slot_width(%d)\n", + pr_debug("\tslots(%d), slot_width(%d)\n", slots, slot_width); p_tdm->setting.tx_mask = tx_mask; p_tdm->setting.rx_mask = rx_mask; @@ -946,7 +1015,7 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, } else { if (lanes_lb_cnt) in_src = p_tdm->id + 3; - if (lanes_in_cnt && lanes_in_cnt <= 3) + if (lanes_in_cnt && lanes_in_cnt <= 4) in_src = p_tdm->id; if (in_src > 5) { pr_err("unknown src(%d) for tdmin\n", in_src); @@ -956,9 +1025,17 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, out_lanes = lanes_out_cnt + lanes_oe_out_cnt; in_lanes = lanes_in_cnt + lanes_oe_in_cnt + lanes_lb_cnt; + + if (p_tdm->chipinfo + && p_tdm->chipinfo->adc_fn + && p_tdm->acodec_adc) { + in_src = ACODEC_ADC; + } + if (in_lanes >= 0 && in_lanes <= 4) aml_tdm_set_slot_in(p_tdm->actrl, p_tdm->id, in_src, slot_width); + if (out_lanes >= 0 && out_lanes <= 4) aml_tdm_set_slot_out(p_tdm->actrl, p_tdm->id, slots, slot_width, @@ -987,9 +1064,22 @@ static int aml_dai_tdm_remove(struct snd_soc_dai *cpu_dai) return 0; } +static int aml_dai_tdm_mute_stream(struct snd_soc_dai *cpu_dai, + int mute, int stream) +{ + struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + pr_debug("tdm playback mute: %d\n", mute); + aml_tdm_mute_playback(p_tdm->actrl, p_tdm->id, mute); + } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { + pr_debug("tdm capture mute: %d\n", mute); + aml_tdm_mute_capture(p_tdm->actrl, p_tdm->id, mute); + } + return 0; +} + static struct snd_soc_dai_ops aml_dai_tdm_ops = { - .startup = aml_dai_tdm_startup, - .shutdown = aml_dai_tdm_shutdown, .prepare = aml_dai_tdm_prepare, .trigger = aml_dai_tdm_trigger, .hw_params = aml_dai_tdm_hw_params, @@ -999,6 +1089,7 @@ static struct snd_soc_dai_ops aml_dai_tdm_ops = { .set_bclk_ratio = aml_dai_set_bclk_ratio, .set_clkdiv = aml_dai_set_clkdiv, .set_tdm_slot = aml_dai_set_tdm_slot, + .mute_stream = aml_dai_tdm_mute_stream, }; #define AML_DAI_TDM_RATES (SNDRV_PCM_RATE_8000_384000) @@ -1069,7 +1160,7 @@ static struct snd_soc_dai_driver aml_tdm_dai[] = { }; static const struct snd_soc_component_driver aml_tdm_component = { - .name = DRV_NAME, + .name = DRV_NAME, }; struct tdm_chipinfo axg_tdma_chipinfo = { @@ -1114,6 +1205,7 @@ struct tdm_chipinfo tl1_tdma_chipinfo = { .oe_fn = true, .clk_pad_ctl = true, .same_src_fn = true, + .adc_fn = true, }; struct tdm_chipinfo tl1_tdmb_chipinfo = { @@ -1122,6 +1214,7 @@ struct tdm_chipinfo tl1_tdmb_chipinfo = { .oe_fn = true, .clk_pad_ctl = true, .same_src_fn = true, + .adc_fn = true, }; struct tdm_chipinfo tl1_tdmc_chipinfo = { @@ -1130,6 +1223,7 @@ struct tdm_chipinfo tl1_tdmc_chipinfo = { .oe_fn = true, .clk_pad_ctl = true, .same_src_fn = true, + .adc_fn = true, }; static const struct of_device_id aml_tdm_device_id[] = { @@ -1234,10 +1328,21 @@ static int aml_tdm_platform_probe(struct platform_device *pdev) "Can't retrieve samesrc_sysclk clock\n"); return PTR_ERR(p_tdm->samesrc_sysclk); } + pr_info("TDM id %d samesource_sel:%d\n", + p_tdm->id, + p_tdm->samesource_sel); } - pr_info("TDM id %d samesource_sel:%d\n", - p_tdm->id, - p_tdm->samesource_sel); + } + /* default no acodec_adc */ + if (p_tdm->chipinfo && + p_tdm->chipinfo->adc_fn) { + + ret = of_property_read_u32(node, "acodec_adc", + &p_tdm->acodec_adc); + if (ret < 0) + p_tdm->acodec_adc = 0; + else + pr_info("TDM id %d supports ACODEC_ADC\n", p_tdm->id); } ret = of_property_read_u32(node, "i2s2hdmi", diff --git a/sound/soc/amlogic/auge/tdm_hw.c b/sound/soc/amlogic/auge/tdm_hw.c index c720947b8c40..f8f89bc40264 100644 --- a/sound/soc/amlogic/auge/tdm_hw.c +++ b/sound/soc/amlogic/auge/tdm_hw.c @@ -141,13 +141,9 @@ void tdm_fifo_enable(int tdm_index, int is_enable) } } -void aml_tdm_fifo_ctrl( - struct aml_audio_controller *actrl, - int bitwidth, int stream, - int index, unsigned int fifo_id) +int tdmout_get_frddr_type(int bitwidth) { - unsigned int frddr_type; - unsigned int reg, offset; + unsigned int frddr_type = 0; switch (bitwidth) { case 8: @@ -163,9 +159,20 @@ void aml_tdm_fifo_ctrl( default: pr_err("invalid bit_depth: %d\n", bitwidth); - return; + break; } + return frddr_type; +} + +void aml_tdm_fifo_ctrl( + struct aml_audio_controller *actrl, + int bitwidth, int stream, + int index, unsigned int fifo_id) +{ + unsigned int frddr_type = tdmout_get_frddr_type(bitwidth); + unsigned int reg, offset; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { pr_debug("tdm prepare----playback\n"); // from ddr, 63bit split into 2 samples @@ -181,6 +188,72 @@ void aml_tdm_fifo_ctrl( } +static void aml_clk_set_tdmout_by_id( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + unsigned int sclk_sel, + unsigned int lrclk_sel, + bool sclk_ws_inv, + bool is_master, + bool binv) +{ + unsigned int val_sclk_ws_inv = 0; + unsigned int reg = EE_AUDIO_CLK_TDMOUT_A_CTRL + tdm_index; + + /* This is just a copy from previous setting. WHY??? */ + val_sclk_ws_inv = sclk_ws_inv && is_master; + if (val_sclk_ws_inv) + aml_audiobus_update_bits(actrl, reg, + 0x3<<30|1<<28|0xf<<24|0xf<<20, + 0x3<<30|val_sclk_ws_inv<<28| + sclk_sel<<24|lrclk_sel<<20); + else + aml_audiobus_update_bits(actrl, reg, + 0x3<<30|1<<29|0xf<<24|0xf<<20, + 0x3<<30|binv<<29| + sclk_sel<<24|lrclk_sel<<20); +} + +static void aml_clk_set_tdmin_by_id( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + unsigned int sclk_sel, + unsigned int lrclk_sel) +{ + unsigned int reg = + EE_AUDIO_CLK_TDMIN_A_CTRL + tdm_index; + aml_audiobus_update_bits(actrl, + reg, + 0xff<<20, + sclk_sel<<24|lrclk_sel<<20); +} + +static void aml_tdmout_invert_lrclk( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + bool finv) +{ + unsigned int off_set = + EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1; + unsigned int reg_out = + EE_AUDIO_TDMOUT_A_CTRL1 + off_set * tdm_index; + aml_audiobus_update_bits(actrl, + reg_out, 0x1<<28, finv<<28); +} + +static void aml_tdmout_bclk_skew( + struct aml_audio_controller *actrl, + unsigned int tdm_index, + unsigned int bclkout_skew) +{ + unsigned int off_set = + EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0; + unsigned int reg_out = + EE_AUDIO_TDMOUT_A_CTRL0 + off_set * tdm_index; + aml_audiobus_update_bits(actrl, + reg_out, 0x1f<<15, bclkout_skew<<15); +} + void aml_tdm_set_format( struct aml_audio_controller *actrl, struct pcm_setting *p_config, @@ -216,24 +289,7 @@ void aml_tdm_set_format( default: return; } - - //TODO: clk tree - reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id; - reg_in = EE_AUDIO_CLK_TDMIN_A_CTRL + id; - aml_audiobus_update_bits(actrl, - reg_out, - 0xff<<20, - valb<<24|valf<<20); - aml_audiobus_update_bits(actrl, - reg_in, - 0xff<<20, - valb<<24|valf<<20); - - if (p_config->sclk_ws_inv) - aml_audiobus_update_bits(actrl, - reg_out, - 1 << 28, - 0 << 28); + aml_clk_set_tdmin_by_id(actrl, id, valb, valf); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: @@ -348,27 +404,11 @@ void aml_tdm_set_format( /* TDM out */ if (playback_active) { - - reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id; - aml_audiobus_update_bits(actrl, reg_out, - 0x3<<30, 0x3<<30); - - if (p_config->sclk_ws_inv && master_mode) - aml_audiobus_update_bits(actrl, reg_out, - 0x1 << 28, - 0x1 << 28); - else - aml_audiobus_update_bits(actrl, reg_out, - 0x1<<29, binv<<29); - - off_set = EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1; - reg_out = EE_AUDIO_TDMOUT_A_CTRL1 + off_set * id; - aml_audiobus_update_bits(actrl, reg_out, 0x1<<28, finv<<28); - - off_set = EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0; - reg_out = EE_AUDIO_TDMOUT_A_CTRL0 + off_set * id; - aml_audiobus_update_bits(actrl, reg_out, - 0x1f<<15, bclkout_skew<<15); + aml_clk_set_tdmout_by_id(actrl, + id, valb, valf, + p_config->sclk_ws_inv, master_mode, binv); + aml_tdmout_invert_lrclk(actrl, id, finv); + aml_tdmout_bclk_skew(actrl, id, bclkout_skew); } /* TDM in */ @@ -396,6 +436,28 @@ void aml_tdm_set_format( } } +void aml_update_tdmin_skew(struct aml_audio_controller *actrl, + int idx, int skew) +{ + unsigned int reg_in, off_set; + + off_set = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL; + reg_in = EE_AUDIO_TDMIN_A_CTRL + off_set * idx; + aml_audiobus_update_bits(actrl, reg_in, + 0x7 << 16, skew << 16); +} + +void aml_update_tdmin_rev_ws(struct aml_audio_controller *actrl, + int idx, int is_rev) +{ + unsigned int reg_in, off_set; + + off_set = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL; + reg_in = EE_AUDIO_TDMIN_A_CTRL + off_set * idx; + aml_audiobus_update_bits(actrl, reg_in, + 0x1 << 25, is_rev << 25); +} + void aml_tdm_set_slot_out( struct aml_audio_controller *actrl, int index, int slots, int slot_width, @@ -450,7 +512,7 @@ else 0xf << 20 | 0x1f, in_src << 20 | (slot_width-1)); } -void tdm_update_slot_in( +void aml_update_tdmin_src( struct aml_audio_controller *actrl, int index, int in_src) { @@ -463,6 +525,19 @@ void tdm_update_slot_in( 0xf << 20, in_src << 20); } +void tdmin_set_chnum_en( + struct aml_audio_controller *actrl, + int index, bool enable) +{ + unsigned int reg, offset; + + offset = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL; + reg = EE_AUDIO_TDMIN_A_CTRL + offset * index; + + aml_audiobus_update_bits(actrl, reg, + 0x1 << 6, enable << 6); +} + void aml_tdm_set_channel_mask( struct aml_audio_controller *actrl, int stream, int index, int lane, int mask) @@ -618,3 +693,44 @@ void i2s_to_hdmitx_ctrl(int tdm_index) | tdm_index << 4 /* Bclk_sel */ ); } + +void aml_tdm_mute_playback( + struct aml_audio_controller *actrl, + int tdm_index, + bool mute) +{ + unsigned int offset, reg; + unsigned int mute_mask = 0xffffffff; + unsigned int mute_val = 0; + int i = 0, lanes = 4; + + if (mute) + mute_val = 0xffffffff; + + offset = EE_AUDIO_TDMOUT_B_MUTE0 + - EE_AUDIO_TDMOUT_A_MUTE0; + reg = EE_AUDIO_TDMOUT_A_MUTE0 + offset * tdm_index; + for (i = 0; i < lanes; i++) + aml_audiobus_update_bits(actrl, reg + i, mute_mask, mute_val); +} + +void aml_tdm_mute_capture( + struct aml_audio_controller *actrl, + int tdm_index, + bool mute) +{ + unsigned int offset, reg; + unsigned int mute_mask = 0xffffffff; + unsigned int mute_val = 0; + int i = 0, lanes = 4; + + if (mute) + mute_val = 0xffffffff; + + offset = EE_AUDIO_TDMIN_B_MUTE0 + - EE_AUDIO_TDMIN_A_MUTE0; + reg = EE_AUDIO_TDMIN_A_MUTE0 + offset * tdm_index; + for (i = 0; i < lanes; i++) + aml_audiobus_update_bits(actrl, reg + i, mute_mask, mute_val); +} + diff --git a/sound/soc/amlogic/auge/tdm_hw.h b/sound/soc/amlogic/auge/tdm_hw.h index fc5bcabfecf9..85fe6303434f 100644 --- a/sound/soc/amlogic/auge/tdm_hw.h +++ b/sound/soc/amlogic/auge/tdm_hw.h @@ -26,11 +26,11 @@ enum tdmin_src { PAD_TDMINA_DIN = 0, PAD_TDMINB_DIN = 1, PAD_TDMINC_DIN = 2, - PAD_TDMINA_D = 4, - PAD_TDMINB_D = 5, - PAD_TDMINC_D = 6, - HDMIRX_I2S = 7, - ACODEC_ADC = 8, + PAD_TDMINA_D = 3, + PAD_TDMINB_D = 4, + PAD_TDMINC_D = 5, + HDMIRX_I2S = 6, + ACODEC_ADC = 7, TDMOUTA = 13, TDMOUTB = 14, TDMOUTC = 15, @@ -72,6 +72,8 @@ extern void aml_tdm_fifo_reset( struct aml_audio_controller *actrl, int stream, int index); +extern int tdmout_get_frddr_type(int bitwidth); + extern void aml_tdm_fifo_ctrl( struct aml_audio_controller *actrl, int bitwidth, int stream, @@ -86,6 +88,12 @@ extern void aml_tdm_set_format( unsigned int capture_active, unsigned int playback_active); +extern void aml_update_tdmin_skew(struct aml_audio_controller *actrl, + int idx, int skew); + +extern void aml_update_tdmin_rev_ws(struct aml_audio_controller *actrl, + int idx, int is_rev); + extern void aml_tdm_set_slot_out( struct aml_audio_controller *actrl, int index, int slots, int slot_width, @@ -95,10 +103,14 @@ extern void aml_tdm_set_slot_in( struct aml_audio_controller *actrl, int index, int in_src, int slot_width); -extern void tdm_update_slot_in( +extern void aml_update_tdmin_src( struct aml_audio_controller *actrl, int index, int in_src); +extern void tdmin_set_chnum_en( + struct aml_audio_controller *actrl, + int index, bool enable); + extern void aml_tdm_set_channel_mask( struct aml_audio_controller *actrl, int stream, int index, int lanes, int mask); @@ -130,4 +142,12 @@ extern void aml_tdm_clk_pad_select( int tdm_index, int clk_sel); extern void i2s_to_hdmitx_ctrl(int tdm_index); +void aml_tdm_mute_playback( + struct aml_audio_controller *actrl, + int index, + bool mute); +void aml_tdm_mute_capture( + struct aml_audio_controller *actrl, + int tdm_index, + bool mute); #endif diff --git a/sound/soc/amlogic/auge/tl1,clocks.c b/sound/soc/amlogic/auge/tl1,clocks.c index c4e9817ff4d2..f8d4c7da307a 100644 --- a/sound/soc/amlogic/auge/tl1,clocks.c +++ b/sound/soc/amlogic/auge/tl1,clocks.c @@ -24,8 +24,9 @@ static spinlock_t aclk_lock; -static const char *const mclk_parent_names[] = {"mpll0", "mpll1", - "mpll2", "mpll3", "hifi_pll", "fclk_div3", "fclk_div4", "gp0_pll"}; +static const char *const mclk_parent_names[] = { + "mpll0", "mpll1", "mpll2", "mpll3", "hifi_pll", + "fclk_div3", "fclk_div4", "fclk_div5"}; static const char *const audioclk_parent_names[] = { "mclk_a", "mclk_b", "mclk_c", "mclk_d", "mclk_e", @@ -105,38 +106,38 @@ static struct clk_gate *tl1_audio_clk_gates[] = { /* Array of all clocks provided by this provider */ static struct clk_hw *tl1_audio_clk_hws[] = { - [CLKID_AUDIO_DDR_ARB] = &audio_ddr_arb.hw, - [CLKID_AUDIO_PDM] = &audio_pdm.hw, - [CLKID_AUDIO_TDMINA] = &audio_tdmina.hw, - [CLKID_AUDIO_TDMINB] = &audio_tdminb.hw, - [CLKID_AUDIO_TDMINC] = &audio_tdminc.hw, - [CLKID_AUDIO_TDMINLB] = &audio_tdminlb.hw, - [CLKID_AUDIO_TDMOUTA] = &audio_tdmouta.hw, - [CLKID_AUDIO_TDMOUTB] = &audio_tdmoutb.hw, - [CLKID_AUDIO_TDMOUTC] = &audio_tdmoutc.hw, - [CLKID_AUDIO_FRDDRA] = &audio_frddra.hw, - [CLKID_AUDIO_FRDDRB] = &audio_frddrb.hw, - [CLKID_AUDIO_FRDDRC] = &audio_frddrc.hw, - [CLKID_AUDIO_TODDRA] = &audio_toddra.hw, - [CLKID_AUDIO_TODDRB] = &audio_toddrb.hw, - [CLKID_AUDIO_TODDRC] = &audio_toddrc.hw, - [CLKID_AUDIO_LOOPBACKA] = &audio_loopbacka.hw, - [CLKID_AUDIO_SPDIFIN] = &audio_spdifin.hw, - [CLKID_AUDIO_SPDIFOUT] = &audio_spdifout.hw, - [CLKID_AUDIO_RESAMPLEA] = &audio_resamplea.hw, - [CLKID_AUDIO_RESERVED0] = &audio_reserved0.hw, - [CLKID_AUDIO_RESERVED1] = &audio_reserved1.hw, - [CLKID_AUDIO_SPDIFOUTB] = &audio_spdifoutb.hw, - [CLKID_AUDIO_EQDRC] = &audio_eqdrc.hw, - [CLKID_AUDIO_RESAMPLEB] = &audio_resampleb.hw, - [CLKID_AUDIO_TOVAD] = &audio_tovad.hw, - [CLKID_AUDIO_AUDIOLOCKER] = &audio_audiolocker.hw, - [CLKID_AUDIO_SPDIFIN_LB] = &audio_spdifin_lb.hw, - [CLKID_AUDIO_FRATV] = &audio_fratv.hw, - [CLKID_AUDIO_FRHDMIRX] = &audio_frhdmirx.hw, - [CLKID_AUDIO_FRDDRD] = &audio_frddrd.hw, - [CLKID_AUDIO_TODDRD] = &audio_toddrd.hw, - [CLKID_AUDIO_LOOPBACKB] = &audio_loopbackb.hw, + [CLKID_AUDIO_GATE_DDR_ARB] = &audio_ddr_arb.hw, + [CLKID_AUDIO_GATE_PDM] = &audio_pdm.hw, + [CLKID_AUDIO_GATE_TDMINA] = &audio_tdmina.hw, + [CLKID_AUDIO_GATE_TDMINB] = &audio_tdminb.hw, + [CLKID_AUDIO_GATE_TDMINC] = &audio_tdminc.hw, + [CLKID_AUDIO_GATE_TDMINLB] = &audio_tdminlb.hw, + [CLKID_AUDIO_GATE_TDMOUTA] = &audio_tdmouta.hw, + [CLKID_AUDIO_GATE_TDMOUTB] = &audio_tdmoutb.hw, + [CLKID_AUDIO_GATE_TDMOUTC] = &audio_tdmoutc.hw, + [CLKID_AUDIO_GATE_FRDDRA] = &audio_frddra.hw, + [CLKID_AUDIO_GATE_FRDDRB] = &audio_frddrb.hw, + [CLKID_AUDIO_GATE_FRDDRC] = &audio_frddrc.hw, + [CLKID_AUDIO_GATE_TODDRA] = &audio_toddra.hw, + [CLKID_AUDIO_GATE_TODDRB] = &audio_toddrb.hw, + [CLKID_AUDIO_GATE_TODDRC] = &audio_toddrc.hw, + [CLKID_AUDIO_GATE_LOOPBACKA] = &audio_loopbacka.hw, + [CLKID_AUDIO_GATE_SPDIFIN] = &audio_spdifin.hw, + [CLKID_AUDIO_GATE_SPDIFOUT_A] = &audio_spdifout.hw, + [CLKID_AUDIO_GATE_RESAMPLEA] = &audio_resamplea.hw, + [CLKID_AUDIO_GATE_RESERVED0] = &audio_reserved0.hw, + [CLKID_AUDIO_GATE_RESERVED1] = &audio_reserved1.hw, + [CLKID_AUDIO_GATE_SPDIFOUT_B] = &audio_spdifoutb.hw, + [CLKID_AUDIO_GATE_EQDRC] = &audio_eqdrc.hw, + [CLKID_AUDIO_GATE_RESAMPLEB] = &audio_resampleb.hw, + [CLKID_AUDIO_GATE_TOVAD] = &audio_tovad.hw, + [CLKID_AUDIO_GATE_AUDIOLOCKER] = &audio_audiolocker.hw, + [CLKID_AUDIO_GATE_SPDIFIN_LB] = &audio_spdifin_lb.hw, + [CLKID_AUDIO_GATE_FRATV] = &audio_fratv.hw, + [CLKID_AUDIO_GATE_FRHDMIRX] = &audio_frhdmirx.hw, + [CLKID_AUDIO_GATE_FRDDRD] = &audio_frddrd.hw, + [CLKID_AUDIO_GATE_TODDRD] = &audio_toddrd.hw, + [CLKID_AUDIO_GATE_LOOPBACKB] = &audio_loopbackb.hw, }; static int tl1_clk_gates_init(struct clk **clks, void __iomem *iobase) @@ -189,6 +190,19 @@ CLOCK_COM_GATE(spdifin, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFIN_CTRL), 31); CLOCK_COM_MUX(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 0x7, 24); CLOCK_COM_DIV(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 0, 10); CLOCK_COM_GATE(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 31); +/* audio resample_a */ +CLOCK_COM_MUX(resample_a, + AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0xf, 24); +CLOCK_COM_DIV(resample_a, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0, 8); +CLOCK_COM_GATE(resample_a, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 31); +/* audio locker_out */ +CLOCK_COM_MUX(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 24); +CLOCK_COM_DIV(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 16, 8); +CLOCK_COM_GATE(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 31); +/* audio locker_in */ +CLOCK_COM_MUX(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 8); +CLOCK_COM_DIV(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 8); +CLOCK_COM_GATE(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 15); /* pdmin0 */ CLOCK_COM_MUX(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 0x7, 24); CLOCK_COM_DIV(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 0, 16); @@ -202,18 +216,24 @@ CLOCK_COM_MUX(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0x7, 24); CLOCK_COM_DIV(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0, 10); CLOCK_COM_GATE(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 31); -/* audio locker_out */ -CLOCK_COM_MUX(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 24); -CLOCK_COM_DIV(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 16, 8); -CLOCK_COM_GATE(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 31); -/* audio locker_in */ -CLOCK_COM_MUX(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 8); -CLOCK_COM_DIV(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 8); -CLOCK_COM_GATE(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 15); -/* audio resample */ -CLOCK_COM_MUX(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0xf, 24); -CLOCK_COM_DIV(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0, 8); -CLOCK_COM_GATE(resample, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 31); +/* audio resample_b */ +CLOCK_COM_MUX(resample_b, + AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 0xf, 24); +CLOCK_COM_DIV(resample_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 0, 8); +CLOCK_COM_GATE(resample_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 31); +/* spdifin_lb, div is a fake */ +CLOCK_COM_MUX(spdifin_lb, + AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0x1, 30); +CLOCK_COM_DIV(spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0, 29); +CLOCK_COM_GATE(spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 31); +/* audio eqdrc */ +CLOCK_COM_MUX(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0x7, 24); +CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16); +CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31); +/* audio vad */ +CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0x7, 24); +CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0, 16); +CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 31); static int tl1_clks_init(struct clk **clks, void __iomem *iobase) { @@ -242,12 +262,24 @@ static int tl1_clks_init(struct clk **clks, void __iomem *iobase) WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_F])); IOMAP_COM_CLK(spdifin, iobase); - clks[CLKID_AUDIO_SPDIFIN_CTRL] = REGISTER_CLK_COM(spdifin); - WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN_CTRL])); + clks[CLKID_AUDIO_SPDIFIN] = REGISTER_CLK_COM(spdifin); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN])); IOMAP_COM_CLK(spdifout, iobase); - clks[CLKID_AUDIO_SPDIFOUT_CTRL] = REGISTER_CLK_COM(spdifout); - WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_CTRL])); + clks[CLKID_AUDIO_SPDIFOUT_A] = REGISTER_CLK_COM(spdifout); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_A])); + + IOMAP_COM_CLK(resample_a, iobase); + clks[CLKID_AUDIO_RESAMPLE_A] = REGISTER_AUDIOCLK_COM(resample_a); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_A])); + + IOMAP_COM_CLK(locker_out, iobase); + clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_AUDIOCLK_COM(locker_out); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_OUT])); + + IOMAP_COM_CLK(locker_in, iobase); + clks[CLKID_AUDIO_LOCKER_IN] = REGISTER_AUDIOCLK_COM(locker_in); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_IN])); IOMAP_COM_CLK(pdmin0, iobase); clks[CLKID_AUDIO_PDMIN0] = REGISTER_CLK_COM(pdmin0); @@ -258,20 +290,24 @@ static int tl1_clks_init(struct clk **clks, void __iomem *iobase) WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_PDMIN1])); IOMAP_COM_CLK(spdifout_b, iobase); - clks[CLKID_AUDIO_SPDIFOUTB_CTRL] = REGISTER_CLK_COM(spdifout_b); - WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUTB_CTRL])); + clks[CLKID_AUDIO_SPDIFOUT_B] = REGISTER_CLK_COM(spdifout_b); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_B])); - IOMAP_COM_CLK(locker_out, iobase); - clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_AUDIOCLK_COM(locker_out); - WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_OUT])); + IOMAP_COM_CLK(resample_b, iobase); + clks[CLKID_AUDIO_RESAMPLE_B] = REGISTER_AUDIOCLK_COM(resample_b); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_B])); - IOMAP_COM_CLK(locker_in, iobase); - clks[CLKID_AUDIO_LOCKER_IN] = REGISTER_AUDIOCLK_COM(locker_in); - WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_IN])); + IOMAP_COM_CLK(spdifin_lb, iobase); + clks[CLKID_AUDIO_SPDIFIN_LB] = REGISTER_CLK_COM(spdifin_lb); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN_LB])); - IOMAP_COM_CLK(resample, iobase); - clks[CLKID_AUDIO_RESAMPLE_CTRL] = REGISTER_AUDIOCLK_COM(resample); - WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_CTRL])); + IOMAP_COM_CLK(eqdrc, iobase); + clks[CLKID_AUDIO_EQDRC] = REGISTER_CLK_COM(eqdrc); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_EQDRC])); + + IOMAP_COM_CLK(vad, iobase); + clks[CLKID_AUDIO_VAD] = REGISTER_CLK_COM(vad); + WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_VAD])); return 0; } diff --git a/sound/soc/amlogic/auge/vad.c b/sound/soc/amlogic/auge/vad.c new file mode 100644 index 000000000000..6738fdf63b97 --- /dev/null +++ b/sound/soc/amlogic/auge/vad.c @@ -0,0 +1,786 @@ +/* + * sound/soc/amlogic/auge/vad.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "vad_hw_coeff.c" +#include "vad_hw.h" +#include "vad.h" + +#define DRV_NAME "VAD" + +#define DMA_BUFFER_BYTES_MAX (2 * 1024 * 1024) + +enum vad_level { + LEVEL_USER, + LEVEL_KERNEL, +}; + +struct vad { + struct aml_audio_controller *actrl; + struct device *dev; + + struct clk *gate; + struct clk *pll; + struct clk *clk; + + struct toddr *tddr; + + struct tasklet_struct tasklet; + + struct snd_dma_buffer dma_buffer; + unsigned int start_last; + unsigned int end_last; + unsigned int addr; + + int switch_buffer; + + /* vad flag interrupt */ + int irq_wakeup; + /* frame sync interrupt */ + int irq_fs; + /* data source select + * Data src sel: + * 0: tdmin_a; + * 1: tdmin_b; + * 2: tdmin_c; + * 3: spdifin; + * 4: pdmin; + * 5: loopback_b; + * 6: tdmin_lb; + * 7: loopback_a; + */ + int src; + /* Enable */ + int en; + + /* user space or kernel space to check hot word + * 1: check hot word in kernel + * 0: check hot word in user space + */ + enum vad_level level; +}; + +static struct vad *s_vad; + +static struct vad *get_vad(void) +{ + struct vad *p_vad; + + p_vad = s_vad; + + if (!p_vad) { + pr_debug("Not init vad\n"); + return NULL; + } + + return p_vad; +} + +static bool vad_is_enable(void) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad) + return false; + + return p_vad->en; +} + +static bool vad_src_check(enum vad_src src) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad) + return false; + + if (p_vad->src == src) + return true; + + return false; +} + +bool vad_tdm_is_running(int tdm_idx) +{ + enum vad_src src; + + if (tdm_idx > 2) + return false; + + src = (enum vad_src)tdm_idx; + + if (vad_is_enable() && vad_src_check(src)) + return true; + + return false; +} + +bool vad_pdm_is_running(void) +{ + if (vad_is_enable() && vad_src_check(VAD_SRC_PDMIN)) + return true; + + return false; +} + +static void vad_notify_user_space(struct device *dev) +{ + pr_info("Notify to wake up user space\n"); + + pm_wakeup_event(dev, 2000); +} + +static int vad_engine_check(void) +{ + return 1; +} + +/* Check buffer in kernel for VAD */ +static void vad_transfer_buffer_output(struct vad *p_vad) +{ + + for (;;) { + if (vad_engine_check()) { + vad_notify_user_space(p_vad->dev); + break; + } + } +} + +static void vad_tasklet(unsigned long data) +{ + struct vad *p_vad = (struct vad *)data; + + vad_transfer_buffer_output(p_vad); +} + +static irqreturn_t vad_wakeup_isr(int irq, void *data) +{ + struct vad *p_vad = (struct vad *)data; + + pr_info("%s\n", __func__); + + if (p_vad->level == LEVEL_KERNEL) + tasklet_schedule(&p_vad->tasklet); + + return IRQ_HANDLED; +} + +static irqreturn_t vad_fs_isr(int irq, void *data) +{ + return IRQ_HANDLED; +} + +static int vad_set_clks(struct vad *p_vad, bool enable) +{ + if (enable) { + int ret = 0; + + /* enable clock gate */ + ret = clk_prepare_enable(p_vad->gate); + + /* enable clock */ + ret = clk_prepare_enable(p_vad->pll); + if (ret) { + pr_err("Can't enable vad pll: %d\n", ret); + return -EINVAL; + } + + clk_set_rate(p_vad->clk, 25000000); + ret = clk_prepare_enable(p_vad->clk); + if (ret) { + pr_err("Can't enable vad clk: %d\n", ret); + return -EINVAL; + } + } else { + /* disable clock and gate */ + clk_disable_unprepare(p_vad->clk); + clk_disable_unprepare(p_vad->pll); + clk_disable_unprepare(p_vad->gate); + } + + return 0; +} + +static int vad_init(struct vad *p_vad) +{ + int ret = 0, flag = 0; + + /* malloc buffer */ + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, + p_vad->dev, + DMA_BUFFER_BYTES_MAX, + &p_vad->dma_buffer); + if (ret) { + dev_err(p_vad->dev, "Cannot allocate buffer(s)\n"); + return ret; + } + + /* register irq */ + if (p_vad->level == LEVEL_KERNEL) { + flag = IRQF_SHARED | IRQF_NO_SUSPEND; + + tasklet_init(&p_vad->tasklet, vad_tasklet, + (unsigned long)p_vad); + + } else if (p_vad->level == LEVEL_USER) + flag = IRQF_SHARED; + + ret = request_irq(p_vad->irq_wakeup, + vad_wakeup_isr, flag, "vad_wakeup", + p_vad); + if (ret) { + dev_err(p_vad->dev, "failed to claim irq_wakeup %u\n", + p_vad->irq_wakeup); + return -ENXIO; + } + + ret = request_irq(p_vad->irq_fs, + vad_fs_isr, 0, "vad_fs", + p_vad); + if (ret) { + dev_err(p_vad->dev, "failed to claim irq_fs %u\n", + p_vad->irq_fs); + return -ENXIO; + } + + /* clock ready */ + vad_set_clks(p_vad, true); + + return ret; +} + +static void vad_deinit(struct vad *p_vad) +{ + if (p_vad->level == LEVEL_KERNEL) + tasklet_kill(&p_vad->tasklet); + + /* free irq */ + free_irq(p_vad->irq_wakeup, p_vad); + free_irq(p_vad->irq_fs, p_vad); + + /* free buffer */ + snd_dma_free_pages(&p_vad->dma_buffer); + + /* clock disabled */ + vad_set_clks(p_vad, false); +} + +void vad_update_buffer(int isvad) +{ + struct vad *p_vad = get_vad(); + unsigned int start, end, addr; + unsigned int rd_th; + + if (!p_vad || !p_vad->en || !p_vad->tddr) + return; + + addr = aml_toddr_get_position(p_vad->tddr); + + if (isvad) { /* switch to vad buffer */ + struct toddr *tddr = p_vad->tddr; + + p_vad->start_last = tddr->start_addr; + p_vad->end_last = tddr->end_addr; + + rd_th = 0x100; + + pr_debug("Switch to VAD buffer\n"); + pr_debug("\t ASAL start:%d, end:%d, bytes:%d, current:%d\n", + tddr->start_addr, tddr->end_addr, + tddr->end_addr - tddr->start_addr, addr); + + start = p_vad->dma_buffer.addr; + end = start + p_vad->dma_buffer.bytes - 8; + + pr_debug("\t VAD start:%d, end:%d, bytes:%d\n", + start, end, + end - start); + } else { + pr_debug("Switch to ALSA buffer\n"); + + //addr = aml_toddr_get_addr(p_vad->tddr, VAD_WAKEUP_ADDR); + addr = aml_toddr_get_position(p_vad->tddr); + + start = p_vad->start_last; + end = p_vad->end_last; + + rd_th = 0x40; + + vad_set_trunk_data_readable(true); + } + + p_vad->addr = addr; + aml_toddr_set_buf(p_vad->tddr, start, end); + aml_toddr_force_finish(p_vad->tddr); + aml_toddr_update_fifos_rd_th(p_vad->tddr, rd_th); +} + +int vad_transfer_chunk_data(unsigned long data, int frames) +{ + struct vad *p_vad = get_vad(); + char __user *buf = (char __user *)data; + unsigned char *hwbuf; + int bytes; + int start, end, addr, size; + int chnum, bytes_per_sample; + + if (!buf || !p_vad || !p_vad->en || !p_vad->tddr) + return 0; + + size = p_vad->dma_buffer.bytes; + start = p_vad->dma_buffer.addr; + end = start + size - 8; + addr = p_vad->addr; + hwbuf = p_vad->dma_buffer.area; + + if (addr < start || addr > end) + return 0; + + chnum = p_vad->tddr->channels; + /* bytes for each sample */ + bytes_per_sample = p_vad->tddr->bitdepth >> 3; + + bytes = frames * chnum * bytes_per_sample < size ? + frames * chnum * bytes_per_sample : size; + + pr_debug("%s dma bytes:%d, wanted bytes:%d, actual bytes:%d\n", + __func__, + size, + frames * chnum * bytes_per_sample, + bytes); + + pr_debug("%s dma bytes:%d, start:%d, end:%d, current:%d\n", + __func__, + size, + start, + end, + addr); + + if (addr - start >= bytes) { + if (copy_to_user(buf, + hwbuf + addr - bytes - start, + bytes)) + return 0; + } else { + int tmp_bytes = bytes - (addr - start); + int tmp_offset = (end - tmp_bytes) - start; + + if (copy_to_user(buf, + hwbuf + tmp_offset, + tmp_bytes)) + return 0; + + if (copy_to_user(buf + tmp_bytes, + hwbuf, + addr - start)) + return 0; + } + + /* After data copied, reset dma buffer */ + memset(hwbuf, 0x0, size); + + return bytes / (chnum * bytes_per_sample); +} + +void vad_set_toddr_info(struct toddr *to) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad || !p_vad->en) + return; + + pr_debug("%s update vad toddr:%p\n", __func__, to); + + p_vad->tddr = to; +} + +void vad_enable(bool enable) +{ + struct vad *p_vad = get_vad(); + + if (!p_vad || !p_vad->en) + return; + + /* Force VAD enable to set parameters */ + if (enable) { + int *p_de_coeff = vad_de_coeff; + int len_de = ARRAY_SIZE(vad_de_coeff); + int *p_win_coeff = vad_ram_coeff; + int len_ram = ARRAY_SIZE(vad_ram_coeff); + + vad_set_enable(true); + vad_set_ram_coeff(len_ram, p_win_coeff); + vad_set_de_params(len_de, p_de_coeff); + vad_set_pwd(); + vad_set_cep(); + vad_set_src(p_vad->src); + vad_set_in(); + + /* reset then enable VAD */ + vad_set_enable(false); + } + vad_set_enable(enable); +} + +static int vad_get_enable_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + ucontrol->value.integer.value[0] = p_vad->en; + + return 0; +} + +static int vad_set_enable_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + p_vad->en = ucontrol->value.integer.value[0]; + + if (p_vad->en) { + vad_init(p_vad); + + aml_set_vad(p_vad->en, p_vad->src); + } else { + aml_set_vad(p_vad->en, p_vad->src); + + vad_deinit(p_vad); + } + + return 0; +} + + +static const char *const vad_src_txt[] = { + "TDMIN_A", + "TDMIN_B", + "TDMIN_C", + "SPDIFIN", + "PDMIN", + "LOOPBACK_B", + "TDMIN_LB", + "LOOPBACK_A", +}; + +const struct soc_enum vad_src_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(vad_src_txt), + vad_src_txt); + +static int vad_get_src_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + ucontrol->value.integer.value[0] = p_vad->src; + + return 0; +} + +static int vad_set_src_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + p_vad->src = ucontrol->value.integer.value[0]; + + if (p_vad->en) + aml_set_vad(p_vad->en, p_vad->src); + + return 0; +} + +static int vad_get_switch_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + ucontrol->value.integer.value[0] = p_vad->switch_buffer; + + return 0; +} + +static int vad_set_switch_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct vad *p_vad = snd_kcontrol_chip(kcontrol); + + if (!p_vad) { + pr_debug("VAD is not inited\n"); + return 0; + } + + p_vad->switch_buffer = ucontrol->value.integer.value[0]; + + if (p_vad->en) + vad_update_buffer(p_vad->switch_buffer); + + return 0; +} + +static const struct snd_kcontrol_new vad_controls[] = { + SOC_SINGLE_BOOL_EXT("VAD enable", + 0, + vad_get_enable_enum, + vad_set_enable_enum), + + SOC_ENUM_EXT("VAD Source sel", + vad_src_enum, + vad_get_src_enum, + vad_set_src_enum), + + SOC_SINGLE_BOOL_EXT("VAD Switch", + 0, + vad_get_switch_enum, + vad_set_switch_enum), + +}; + +int card_add_vad_kcontrols(struct snd_soc_card *card) +{ + unsigned int idx; + int err; + + struct vad *p_vad = get_vad(); + + if (!p_vad) + return -ENODEV; + + for (idx = 0; idx < ARRAY_SIZE(vad_controls); idx++) { + err = snd_ctl_add(card->snd_card, + snd_ctl_new1(&vad_controls[idx], + p_vad)); + if (err < 0) + return err; + } + + return 0; +} + +static const struct of_device_id vad_device_id[] = { + { + .compatible = "amlogic, snd-vad", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, vad_device_id); + +static int vad_platform_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct device_node *node_prt = NULL; + struct platform_device *pdev_parent; + struct device *dev = &pdev->dev; + struct aml_audio_controller *actrl = NULL; + struct vad *p_vad = NULL; + int ret = 0; + + p_vad = devm_kzalloc(&pdev->dev, sizeof(struct vad), GFP_KERNEL); + if (!p_vad) + return -ENOMEM; + + p_vad->dev = dev; + dev_set_drvdata(dev, p_vad); + + /* get audio controller */ + node_prt = of_get_parent(node); + if (node_prt == NULL) + return -ENXIO; + + pdev_parent = of_find_device_by_node(node_prt); + of_node_put(node_prt); + actrl = (struct aml_audio_controller *) + platform_get_drvdata(pdev_parent); + p_vad->actrl = actrl; + + /* clock */ + p_vad->gate = devm_clk_get(&pdev->dev, "gate"); + if (IS_ERR(p_vad->gate)) { + dev_err(&pdev->dev, + "Can't get vad clock gate\n"); + return PTR_ERR(p_vad->gate); + } + p_vad->pll = devm_clk_get(&pdev->dev, "pll"); + if (IS_ERR(p_vad->pll)) { + dev_err(&pdev->dev, + "Can't retrieve vad pll clock\n"); + return PTR_ERR(p_vad->pll); + } + p_vad->clk = devm_clk_get(&pdev->dev, "clk"); + if (IS_ERR(p_vad->clk)) { + dev_err(&pdev->dev, + "Can't retrieve vad clock\n"); + return PTR_ERR(p_vad->clk); + } + ret = clk_set_parent(p_vad->clk, p_vad->pll); + if (ret) { + dev_err(&pdev->dev, + "Can't set p_vad->clk parent clock\n"); + return PTR_ERR(p_vad->clk); + } + + /* irqs */ + p_vad->irq_wakeup = platform_get_irq_byname(pdev, "irq_wakeup"); + if (p_vad->irq_wakeup < 0) { + dev_err(dev, "Failed to get irq_wakeup:%d\n", + p_vad->irq_wakeup); + return -ENXIO; + } + p_vad->irq_fs = platform_get_irq_byname(pdev, "irq_frame_sync"); + if (p_vad->irq_fs < 0) { + dev_err(dev, "Failed to get irq_frame_sync:%d\n", + p_vad->irq_fs); + return -ENXIO; + } + + /* data source select */ + ret = of_property_read_u32(node, "src", + &p_vad->src); + if (ret < 0) { + dev_err(dev, "Failed to get vad data src select:%d\n", + p_vad->src); + return -EINVAL; + } + /* to deal with hot word in user space or kernel space */ + ret = of_property_read_u32(node, "level", + &p_vad->level); + if (ret < 0) { + dev_info(dev, + "Failed to get vad level, default in user space\n"); + p_vad->level = 0; + } + + pr_info("%s vad data source sel:%d, level:%d\n", + __func__, + p_vad->src, + p_vad->level); + + s_vad = p_vad; + + device_init_wakeup(dev, 1); + + return 0; +} + +int vad_platform_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct device *dev = &pdev->dev; + struct vad *p_vad = dev_get_drvdata(dev); + + pr_info("%s\n", __func__); + + /* whether in freeze */ + if (is_pm_freeze_mode() + && vad_is_enable()) { + pr_info("%s, Entry in freeze\n", __func__); + + if (p_vad->level == LEVEL_USER) + dev_pm_set_wake_irq(dev, p_vad->irq_wakeup); + } + + return 0; +} + +int vad_platform_resume(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct vad *p_vad = dev_get_drvdata(dev); + + pr_info("%s\n", __func__); + + /* whether in freeze mode */ + if (is_pm_freeze_mode() + && vad_is_enable()) { + pr_info("%s, Exist from freeze\n", __func__); + + if (p_vad->level == LEVEL_USER) + dev_pm_clear_wake_irq(dev); + } + + return 0; +} + +struct platform_driver vad_driver = { + .driver = { + .name = DRV_NAME, + .of_match_table = vad_device_id, + }, + .probe = vad_platform_probe, + .suspend = vad_platform_suspend, + .resume = vad_platform_resume, +}; + +module_platform_driver(vad_driver); + +MODULE_AUTHOR("Amlogic, Inc."); +MODULE_DESCRIPTION("Amlogic Voice Activity Detection ASoc driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("Platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, vad_device_id); diff --git a/sound/soc/amlogic/auge/vad.h b/sound/soc/amlogic/auge/vad.h new file mode 100644 index 000000000000..cd094682eb15 --- /dev/null +++ b/sound/soc/amlogic/auge/vad.h @@ -0,0 +1,47 @@ +/* + * sound/soc/amlogic/auge/vad.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __VAD_H__ +#define __VAD_H__ + +#include "ddr_mngr.h" + +enum vad_src { + VAD_SRC_TDMIN_A, + VAD_SRC_TDMIN_B, + VAD_SRC_TDMIN_C, + VAD_SRC_SPDIFIN, + VAD_SRC_PDMIN, + VAD_SRC_LOOPBACK_B, + VAD_SRC_TDMIN_LB, + VAD_SRC_LOOPBACK_A, +}; + +extern void vad_update_buffer(int isvad); +extern int vad_transfer_chunk_data(unsigned long data, int frames); + +extern bool vad_tdm_is_running(int tdm_idx); +extern bool vad_pdm_is_running(void); + +extern void vad_enable(bool enable); +extern void vad_set_toddr_info(struct toddr *to); + +extern void vad_set_trunk_data_readable(bool en); + +extern int card_add_vad_kcontrols(struct snd_soc_card *card); + +#endif diff --git a/sound/soc/amlogic/auge/vad_dev.c b/sound/soc/amlogic/auge/vad_dev.c new file mode 100644 index 000000000000..9af68606481a --- /dev/null +++ b/sound/soc/amlogic/auge/vad_dev.c @@ -0,0 +1,175 @@ +/* + * sound/soc/amlogic/auge/vad_dev.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#define DEBUG + +#include +#include +#include +#include + +#include +#include + +#include + +#include "vad.h" + +#define DRV_NAME "vad" + +#define IOCTL_READI_SUSPENDED_FRAMES _IOR('Z', 0x0, struct snd_xferi) + +static bool readable; + +bool vad_is_trunk_data_readable(void) +{ + return readable; +} + +void vad_set_trunk_data_readable(bool en) +{ + readable = en; +} + +static ssize_t readable_show(struct class *cla, struct class_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", readable); +} + +static struct class_attribute vad_attrs[] = { + __ATTR_RO(readable), + + __ATTR_NULL +}; + +static struct class vad_class = { + .name = DRV_NAME, + .class_attrs = vad_attrs, +}; + +static int vad_open(struct inode *inode, struct file *file) +{ + pr_info("%s\n", __func__); + + return 0; +} + +static long vad_unlocked_ioctl( + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + if (cmd == IOCTL_READI_SUSPENDED_FRAMES) { + struct snd_xferi xferi; + struct snd_xferi __user *_xferi = + (struct snd_xferi __user *)arg; + int result; + + if (!vad_is_trunk_data_readable()) + return 0; + + if (put_user(0, &_xferi->result)) + return 0; + if (copy_from_user(&xferi, _xferi, sizeof(xferi))) + return 0; + + result = vad_transfer_chunk_data( + (unsigned long)xferi.buf, + xferi.frames); + + __put_user(result, &_xferi->result); + + pr_debug("VAD resume trunk data, frames:%lu, result:%d\n", + xferi.frames, + result); + + /* if audio data is read, waiting for next time */ + vad_set_trunk_data_readable(false); + + return result; + } + + return -ENOTTY; +} + + +#ifdef CONFIG_COMPAT +static long vad_ioctl_compat( + struct file *file, + unsigned int cmd, + unsigned long arg) +{ + pr_info("%s\n", __func__); + return -ENOIOCTLCMD; +} +#else +#define vad_ioctl_compat NULL +#endif + +static const struct file_operations vad_fops = { + .owner = THIS_MODULE, + .open = vad_open, + .unlocked_ioctl = vad_unlocked_ioctl, + .compat_ioctl = vad_ioctl_compat, +}; + +static int __init vad_init(void) +{ + struct device *vad_dev; + struct class *p_vad_class; + int ret = 0; + + ret = register_chrdev(VAD_MAJOR, DRV_NAME, &vad_fops); + if (ret) { + pr_err("Can't register char devie for " DRV_NAME "\n"); + goto err0; + } + + ret = class_register(&vad_class); + if (ret < 0) { + pr_err("Create vad class failed\n"); + ret = -EEXIST; + goto err1; + } + + p_vad_class = &vad_class; + vad_dev = device_create(p_vad_class, + NULL, MKDEV(VAD_MAJOR, 0), + NULL, DRV_NAME); + if (vad_dev == NULL) { + ret = -EEXIST; + goto err2; + } + + pr_info("Register %s", DRV_NAME); + + return 0; +err2: + class_destroy(p_vad_class); +err1: + unregister_chrdev(VAD_MAJOR, DRV_NAME); +err0: + return ret; +} + +static void __exit vad_exit(void) +{ + unregister_chrdev(VAD_MAJOR, DRV_NAME); +} + +module_init(vad_init); +module_exit(vad_exit); diff --git a/sound/soc/amlogic/auge/vad_hw.c b/sound/soc/amlogic/auge/vad_hw.c new file mode 100644 index 000000000000..c122dd074b39 --- /dev/null +++ b/sound/soc/amlogic/auge/vad_hw.c @@ -0,0 +1,109 @@ +/* + * sound/soc/amlogic/auge/vad_hw.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include "vad_hw.h" + + +void vad_set_ram_coeff(int len, int *params) +{ + int i, ctrl_v; + + for (i = 0; i < len; i++) { + ctrl_v = 0x1 << 31 | (i << 0); + vad_write(VAD_LUT_WR, params[i]); + vad_write(VAD_LUT_CTRL, ctrl_v); + } +} + +/* parameters for downsample and emphasis filter */ +void vad_set_de_params(int len, int *params) +{ + int i; + + for (i = 0; i < len; i++) + vad_write(VAD_FIR_CTRL + i, params[i]); +} + +/* Power detection */ +void vad_set_pwd(void) +{ + /* frame for 32 ms */ + vad_write(VAD_FRAME_CTRL0, + 0x2 << 30 | + 0x1 << 24 | + 0x1 << 16); + + vad_write(VAD_FRAME_CTRL1, 0x00000d65); + vad_write(VAD_FRAME_CTRL2, 0xd00103ff); +} + +void vad_set_cep(void) +{ + vad_write(VAD_CEP_CTRL0, 0x11050000); + vad_write(VAD_CEP_CTRL1, 0x0000001b); + vad_write(VAD_CEP_CTRL2, 0xc001fd); + vad_write(VAD_CEP_CTRL3, 0x137f0000); + vad_write(VAD_CEP_CTRL4, 0x186d0000); + vad_write(VAD_CEP_CTRL5, 0xfd00f61); + vad_write(VAD_DEC_CTRL, 0x10030001); +} + +void vad_set_src(int src) +{ + audiobus_update_bits(EE_AUDIO_TOVAD_CTRL0, + 0x7 << 12, + src << 12); +} + +void vad_set_in(void) +{ + /* two channel enable */ + vad_write(VAD_IN_SEL0, 0x00000001); + vad_write(VAD_IN_SEL1, 0x00000002); + + vad_write(VAD_TO_DDR, 0xa0000719); +} + +void vad_set_enable(bool enable) +{ + audiobus_update_bits(EE_AUDIO_TOVAD_CTRL0, + 0x1 << 31 | 0x1 << 30, + enable << 31 | 0x1 << 30); + + if (enable) { + vad_write(VAD_TOP_CTRL0, 0x7ff); + vad_write(VAD_TOP_CTRL0, 0x0); + + vad_write(VAD_TOP_CTRL1, 0xff); + vad_write(VAD_TOP_CTRL1, 0x0); + + vad_update_bits(VAD_TOP_CTRL0, + 0xfff << 20, + 1 << 31 | /* vad_en */ + 1 << 30 | /* dec_fir_en */ + 1 << 29 | /* pre_emp_en */ + 1 << 28 | /* pre_ram_en */ + 1 << 27 | /* frame_his_en */ + 1 << 23 | /* ceps_ceps_en */ + 1 << 22 | /* ceps_spec_en */ + 0 << 20 /* two_channel_en */ + ); + } else { + vad_write(VAD_TOP_CTRL0, 0x0); + + vad_write(VAD_TOP_CTRL1, 0x0); + } +} diff --git a/sound/soc/amlogic/auge/vad_hw.h b/sound/soc/amlogic/auge/vad_hw.h new file mode 100644 index 000000000000..44a1224aeabc --- /dev/null +++ b/sound/soc/amlogic/auge/vad_hw.h @@ -0,0 +1,38 @@ +/* + * sound/soc/amlogic/auge/vad_hw.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#ifndef __VAD_HW_H__ +#define __VAD_HW_H__ +#include + +#include "regs.h" +#include "iomap.h" + +extern void vad_set_ram_coeff(int len, int *params); + + +extern void vad_set_de_params(int len, int *params); + +extern void vad_set_pwd(void); + +extern void vad_set_cep(void); + +extern void vad_set_src(int src); + +extern void vad_set_in(void); + +extern void vad_set_enable(bool enable); +#endif diff --git a/sound/soc/amlogic/auge/vad_hw_coeff.c b/sound/soc/amlogic/auge/vad_hw_coeff.c new file mode 100644 index 000000000000..e521b9883375 --- /dev/null +++ b/sound/soc/amlogic/auge/vad_hw_coeff.c @@ -0,0 +1,167 @@ +/* + * sound/soc/amlogic/auge/vad_hw_coeff.c + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +/* parameters for downsample and emphasis filter */ +static int vad_de_coeff[] = { + 0x31007f05, + 0x000003e6, + 0x0000070c, + 0x0716071a, + 0x071207fa, + 0x07d407b1, + 0x07a907d0, + 0x0728064c, + 0x06750671, + 0x075906b1, + 0x059404b4, + 0x04be0785, + 0x044c0361, + 0x024d0263, + 0x026a0000, +}; + +static int vad_ram_coeff[] = { + 0x00003A3D, + 0x00003A42, + 0x00003A50, + 0x00003A67, + 0x00003A87, + 0x00003AB0, + 0x00003AE2, + 0x00003B1D, + 0x00003B61, + 0x00003BAF, + 0x00003C05, + 0x00003C64, + 0x00003CCC, + 0x00003D3C, + 0x00003DB5, + 0x00003E37, + 0x00003EC2, + 0x00003F55, + 0x00003FF0, + 0x0000284A, + 0x0000289F, + 0x000028F9, + 0x00002957, + 0x000029B9, + 0x00002A1F, + 0x00002A88, + 0x00002AF5, + 0x00002B66, + 0x00002BDA, + 0x00002C52, + 0x00002CCE, + 0x00002D4D, + 0x00002DCF, + 0x00002E54, + 0x00002EDC, + 0x00002F68, + 0x00002FF6, + 0x00001844, + 0x0000188E, + 0x000018D9, + 0x00001926, + 0x00001974, + 0x000019C3, + 0x00001A14, + 0x00001A65, + 0x00001AB8, + 0x00001B0C, + 0x00001B60, + 0x00001BB6, + 0x00001C0C, + 0x00001C63, + 0x00001CBB, + 0x00001D14, + 0x00001D6D, + 0x00001DC7, + 0x00001E22, + 0x00001E7C, + 0x00001ED8, + 0x00001F34, + 0x00001F90, + 0x00001FEC, + 0x00000824, + 0x00000853, + 0x00000881, + 0x000008AF, + 0x000008DE, + 0x0000090C, + 0x0000093B, + 0x00000969, + 0x00000997, + 0x000009C5, + 0x000009F3, + 0x00000A20, + 0x00000A4E, + 0x00000A7B, + 0x00000AA7, + 0x00000AD4, + 0x00000B00, + 0x00000B2C, + 0x00000B57, + 0x00000B82, + 0x00000BAD, + 0x00000BD7, + 0x00000C00, + 0x00000C29, + 0x00000C52, + 0x00000C7A, + 0x00000CA1, + 0x00000CC8, + 0x00000CEE, + 0x00000D13, + 0x00000D38, + 0x00000D5C, + 0x00000D7F, + 0x00000DA2, + 0x00000DC3, + 0x00000DE4, + 0x00000E05, + 0x00000E24, + 0x00000E42, + 0x00000E60, + 0x00000E7C, + 0x00000E98, + 0x00000EB3, + 0x00000ECD, + 0x00000EE6, + 0x00000EFE, + 0x00000F15, + 0x00000F2B, + 0x00000F40, + 0x00000F54, + 0x00000F66, + 0x00000F78, + 0x00000F89, + 0x00000F99, + 0x00000FA7, + 0x00000FB5, + 0x00000FC1, + 0x00000FCD, + 0x00000FD7, + 0x00000FE0, + 0x00000FE8, + 0x00000FEF, + 0x00000FF4, + 0x00000FF9, + 0x00000FFC, + 0x00000FFF, + 0x00000FFF +}; + diff --git a/sound/soc/amlogic/common/Makefile b/sound/soc/amlogic/common/Makefile index aea732a5d4bf..41087df65185 100644 --- a/sound/soc/amlogic/common/Makefile +++ b/sound/soc/amlogic/common/Makefile @@ -1 +1,3 @@ -obj-y += notify.o spdif_info.o +obj-y += notify.o \ + spdif_info.o \ + misc.o diff --git a/sound/soc/amlogic/common/misc.c b/sound/soc/amlogic/common/misc.c new file mode 100644 index 000000000000..42d7e23438d1 --- /dev/null +++ b/sound/soc/amlogic/common/misc.c @@ -0,0 +1,248 @@ +/* + * sound/soc/amlogic/common/misc.c + * + * Copyright (C) 2018 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ +#include + +#ifdef CONFIG_AMLOGIC_ATV_DEMOD +#include +#endif + +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +#include +#endif + +static const char *const audio_is_stable[] = { + "false", + "true" +}; + +#ifdef CONFIG_AMLOGIC_ATV_DEMOD + +const struct soc_enum atv_audio_status_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(audio_is_stable), + audio_is_stable); + +int aml_get_atv_audio_stable( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int state = 0; + + aml_fe_get_atvaudio_state(&state); + ucontrol->value.integer.value[0] = state; + return 0; +} +#endif /* CONFIG_AMLOGIC_ATV_DEMOD */ + +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +int hdmiin_fifo_disable_count; + +int get_hdmi_sample_rate_index(void) +{ + struct rx_audio_stat_s aud_sts; + int val = 0; + + rx_get_audio_status(&aud_sts); + switch (aud_sts.aud_sr) { + case 0: + val = 0; + break; + case 32000: + val = 1; + break; + case 44100: + val = 2; + break; + case 48000: + val = 3; + break; + case 88200: + val = 4; + break; + case 96000: + val = 5; + break; + case 176400: + val = 6; + break; + case 192000: + val = 7; + break; + default: + pr_err("HDMIRX samplerate not support: %d\n", + aud_sts.aud_sr); + break; + } + return val; +} + +int update_spdifin_audio_type(int audio_type) +{ + struct rx_audio_stat_s aud_sts; + + rx_get_audio_status(&aud_sts); + if (aud_sts.afifo_thres_pass == true) + hdmiin_fifo_disable_count = 0; + else + hdmiin_fifo_disable_count++; + if (hdmiin_fifo_disable_count > 200) + audio_type = 6/*PAUSE*/; + + return audio_type; +} + +static const char *const hdmi_in_samplerate[] = { + "N/A", + "32000", + "44100", + "48000", + "88200", + "96000", + "176400", + "192000" +}; + +static const char *const hdmi_in_channels[] = { + "NONE", + "2", + "3", + "4", + "5", + "6", + "7", + "8" +}; + +enum HDMIIN_format { + REFER_TO_HEADER = 0, + LPCM = 1, + AC3, + MPEG1, + MP3, + MPEG2, + AAC, + DTS, + ATRAC, + ONE_BIT_AUDIO, + DDP, + DTS_HD, + MAT, + DST, + WMA_PRO +}; + +static const char * const hdmi_in_format[] = { + "REFER_TO_HEADER", + "LPCM", + "AC3", + "MPEG1", + "MP3", + "MPEG2", + "AAC", + "DTS", + "ATRAC", + "ONE_BIT_AUDIO", + "DDP", + "DTS_HD", + "MAT", + "DST", + "WMA_PRO" +}; + +const struct soc_enum hdmi_in_status_enum[] = { + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(audio_is_stable), + audio_is_stable), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_samplerate), + hdmi_in_samplerate), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_channels), + hdmi_in_channels), + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_format), + hdmi_in_format) +}; + +int aml_get_hdmiin_audio_stable( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct rx_audio_stat_s aud_sts; + + rx_get_audio_status(&aud_sts); + ucontrol->value.integer.value[0] = aud_sts.aud_rcv_flag; + + return 0; +} + +int aml_get_hdmiin_audio_samplerate( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int val = get_hdmi_sample_rate_index(); + + ucontrol->value.integer.value[0] = val; + + return 0; +} + +int aml_get_hdmiin_audio_channels( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct rx_audio_stat_s aud_sts; + + rx_get_audio_status(&aud_sts); + if (aud_sts.aud_channel_cnt <= 7) + ucontrol->value.integer.value[0] = aud_sts.aud_channel_cnt; + + return 0; +} + +int aml_get_hdmiin_audio_format( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct rx_audio_stat_s aud_sts; + + rx_get_audio_status(&aud_sts); + if (aud_sts.aud_type <= 14) + ucontrol->value.integer.value[0] = aud_sts.aud_type; + + return 0; +} + +/* call HDMI CEC API to enable arc audio */ +int aml_set_atmos_audio_edid( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + bool enable = ucontrol->value.integer.value[0]; + + rx_set_atmos_flag(enable); + + return 0; +} + +int aml_get_atmos_audio_edid( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + bool flag = rx_get_atmos_flag(); + + ucontrol->value.integer.value[0] = flag; + + return 0; +} + +#endif diff --git a/sound/soc/amlogic/common/spdif_info.c b/sound/soc/amlogic/common/spdif_info.c index 32830a0115d8..85bd5e2bb092 100644 --- a/sound/soc/amlogic/common/spdif_info.c +++ b/sound/soc/amlogic/common/spdif_info.c @@ -14,6 +14,7 @@ * more details. * */ +#define DEBUG #undef pr_fmt #define pr_fmt(fmt) "spdif_info: " fmt @@ -111,7 +112,7 @@ void spdif_get_channel_status_info( chsts->chstat1_r = 0xe00; } } - pr_info("rate: %d, channel status ch0_l:0x%x, ch0_r:0x%x, ch1_l:0x%x, ch1_r:0x%x\n", + pr_debug("rate: %d, channel status ch0_l:0x%x, ch0_r:0x%x, ch1_l:0x%x, ch1_r:0x%x\n", rate, chsts->chstat0_l, chsts->chstat0_r, @@ -158,3 +159,35 @@ void spdif_notify_to_hdmitx(struct snd_pcm_substream *substream) substream); } } + +static const char *const spdif_format_texts[10] = { + "2 CH PCM", "DTS RAW Mode", "Dolby Digital", "DTS", + "DD+", "DTS-HD", "Multi-channel LPCM", "TrueHD", "DTS-HD MA", + "HIGH SR Stereo LPCM" +}; + +const struct soc_enum spdif_format_enum = + SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_format_texts), + spdif_format_texts); + +int spdif_format_get_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = IEC958_mode_codec; + return 0; +} + +int spdif_format_set_enum( + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int index = ucontrol->value.enumerated.item[0]; + + if (index >= 10) { + pr_err("bad parameter for spdif format set\n"); + return -1; + } + IEC958_mode_codec = index; + return 0; +} diff --git a/sound/soc/amlogic/meson/spdif_codec.c b/sound/soc/amlogic/meson/spdif_codec.c index 6dc6751e3d53..299c46c43a02 100644 --- a/sound/soc/amlogic/meson/spdif_codec.c +++ b/sound/soc/amlogic/meson/spdif_codec.c @@ -29,6 +29,7 @@ #include #endif #include "spdif_dai.h" +#include #define DRV_NAME "spdif-dit" @@ -164,38 +165,6 @@ static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol, return 0; } -static const char *const spdif_format_texts[10] = { - "2 CH PCM", "DTS RAW Mode", "Dolby Digital", "DTS", - "DD+", "DTS-HD", "Multi-channel LPCM", "TrueHD", "DTS-HD MA", - "HIGH SR Stereo LPCM" -}; - -static const struct soc_enum spdif_format_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_format_texts), - spdif_format_texts); - -static int spdif_format_get_enum( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = IEC958_mode_codec; - return 0; -} - -static int spdif_format_set_enum( - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int index = ucontrol->value.enumerated.item[0]; - - if (index >= 10) { - pr_err("bad parameter for spdif format set\n"); - return -1; - } - IEC958_mode_codec = index; - return 0; -} - #ifdef CONFIG_AMLOGIC_HDMITX /* call HDMITX API to enable/disable internal audio out */ static int aml_get_hdmi_out_audio(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/amlogic/meson/tv.c b/sound/soc/amlogic/meson/tv.c index 137c178ad330..6c184fd8497a 100644 --- a/sound/soc/amlogic/meson/tv.c +++ b/sound/soc/amlogic/meson/tv.c @@ -50,9 +50,8 @@ #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI #include #endif -#ifdef CONFIG_AMLOGIC_ATV_DEMOD -#include -#endif + +#include #include "i2s.h" #include "audio_hw.h" @@ -63,34 +62,6 @@ #define AML_EQ_PARAM_LENGTH 100 #define AML_DRC_PARAM_LENGTH 12 #define AML_REG_BYTES 4 -#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI -static int hdmiin_fifo_disable_count; - -/* copy from drivers/amlogic/tvin/hdmirx/hdmirx_drv.h */ -struct hdmi_in_audio_status { - /*audio packets received*/ - bool aud_rcv_flag; - /*audio stable status*/ - bool aud_stb_flag; - /*audio sample rate*/ - int aud_sr; - /*audio channel count*/ - /*0: refer to stream header,*/ - /*1: 2ch, 2: 3ch, 3: 4ch, 4: 5ch,*/ - /*5: 6ch, 6: 7ch, 7: 8ch*/ - int aud_channel_cnt; - /*audio coding type*/ - /*0: refer to stream header, 1: IEC60958 PCM,*/ - /*2: AC-3, 3: MPEG1 (Layers 1 and 2),*/ - /*4: MP3 (MPEG1 Layer 3), 5: MPEG2 (multichannel),*/ - /*6: AAC, 7: DTS, 8: ATRAC, 9: One Bit Audio,*/ - /*10: Dolby Digital Plus, 11: DTS-HD,*/ - /*12: MAT (MLP), 13: DST, 14: WMA Pro*/ - int aud_type; - /* indicate if audio FIFO start threshold is crossed */ - bool afifo_thres_pass; -}; -#endif static u32 aml_EQ_table[AML_EQ_PARAM_LENGTH] = { /*channel 1 param*/ @@ -189,48 +160,6 @@ static int get_spdif_sample_rate_index(void) return index; } -#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI -static int get_hdmi_sample_rate_index(void) -{ - struct hdmi_in_audio_status aud_sts; - struct rx_audio_stat_s *rx_aud_sts; - int val = 0; - - rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts; - rx_get_audio_status(rx_aud_sts); - switch (aud_sts.aud_sr) { - case 0: - val = 0; - break; - case 32000: - val = 1; - break; - case 44100: - val = 2; - break; - case 48000: - val = 3; - break; - case 88200: - val = 4; - break; - case 96000: - val = 5; - break; - case 176400: - val = 6; - break; - case 192000: - val = 7; - break; - default: - pr_err("HDMIRX samplerate not support: %d\n", aud_sts.aud_sr); - break; - } - return val; -} -#endif - static const char *const audio_in_source_texts[] = { "LINEIN", "ATV", "HDMI", "SPDIFIN" }; @@ -372,18 +301,9 @@ static int aml_get_spdif_audio_type( /* HDMI in,also check the hdmirx fifo status*/ #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI if (audio_in_source == 2) { - struct hdmi_in_audio_status aud_sts; - struct rx_audio_stat_s *rx_aud_sts; int index = 0; - rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts; - rx_get_audio_status(rx_aud_sts); - if (aud_sts.afifo_thres_pass == true) - hdmiin_fifo_disable_count = 0; - else - hdmiin_fifo_disable_count++; - if (hdmiin_fifo_disable_count > 200) - audio_type = 6/*PAUSE*/; + update_spdifin_audio_type(audio_type); index = get_hdmi_sample_rate_index(); if (p_aml_audio && @@ -642,161 +562,6 @@ static int aml_set_arc_audio(struct snd_kcontrol *kcontrol, } #endif -#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI -/* call HDMI CEC API to enable arc audio */ -static int aml_set_atmos_audio_edid(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - struct aml_audio_private_data *p_aml_audio; - bool enable = ucontrol->value.integer.value[0]; - - p_aml_audio = snd_soc_card_get_drvdata(card); - rx_set_atmos_flag(enable); - p_aml_audio->atmos_edid_enable = enable; - return 0; -} -static int aml_get_atmos_audio_edid(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - struct aml_audio_private_data *p_aml_audio; - - p_aml_audio = snd_soc_card_get_drvdata(card); - ucontrol->value.integer.value[0] = p_aml_audio->atmos_edid_enable; - return 0; -} -; -static const char *const hdmi_in_is_stable[] = { - "false", - "true" -}; -static const char *const hdmi_in_samplerate[] = { - "N/A", - "32000", - "44100", - "48000", - "88200", - "96000", - "176400", - "192000" -}; -static const char *const hdmi_in_channels[] = { - "NONE", - "2", - "3", - "4", - "5", - "6", - "7", - "8" -}; -enum HDMIIN_format { - REFER_TO_HEADER = 0, - LPCM = 1, - AC3, - MPEG1, - MP3, - MPEG2, - AAC, - DTS, - ATRAC, - ONE_BIT_AUDIO, - DDP, - DTS_HD, - MAT, - DST, - WMA_PRO -}; -static const char * const hdmi_in_format[] = { - "REFER_TO_HEADER", - "LPCM", - "AC3", - "MPEG1", - "MP3", - "MPEG2", - "AAC", - "DTS", - "ATRAC", - "ONE_BIT_AUDIO", - "DDP", - "DTS_HD", - "MAT", - "DST", - "WMA_PRO" -}; -static const struct soc_enum hdmi_in_status_enum[] = { - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_is_stable), - hdmi_in_is_stable), - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_samplerate), - hdmi_in_samplerate), - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_channels), - hdmi_in_channels), - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_format), - hdmi_in_format) -}; -static int aml_get_hdmiin_audio_stable(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdmi_in_audio_status aud_sts; - struct rx_audio_stat_s *rx_aud_sts; - - rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts; - rx_get_audio_status(rx_aud_sts); - ucontrol->value.integer.value[0] = aud_sts.aud_rcv_flag; - return 0; -} -static int aml_get_hdmiin_audio_samplerate(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int val = get_hdmi_sample_rate_index(); - ucontrol->value.integer.value[0] = val; - return 0; -} -static int aml_get_hdmiin_audio_channels(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rx_audio_stat_s *rx_aud_sts; - struct hdmi_in_audio_status aud_sts; - - rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts; - rx_get_audio_status(rx_aud_sts); - if (aud_sts.aud_channel_cnt <= 7) - ucontrol->value.integer.value[0] = aud_sts.aud_channel_cnt; - return 0; -} -static int aml_get_hdmiin_audio_format(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct rx_audio_stat_s *rx_aud_sts; - struct hdmi_in_audio_status aud_sts; - - rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts; - rx_get_audio_status(rx_aud_sts); - if (aud_sts.aud_type <= 14) - ucontrol->value.integer.value[0] = aud_sts.aud_type; - return 0; -} -#endif - -#ifdef CONFIG_AMLOGIC_ATV_DEMOD -static const char *const atv_audio_is_stable[] = { - "false", - "true" -}; -static const struct soc_enum atv_audio_status_enum = - SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(atv_audio_is_stable), - atv_audio_is_stable); -static int aml_get_atv_audio_stable(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int state = 0; - - aml_fe_get_atvaudio_state(&state); - ucontrol->value.integer.value[0] = state; - return 0; -} -#endif /* CONFIG_AMLOGIC_ATV_DEMOD */ #ifdef CONFIG_TVIN_VDIN static const char *const av_audio_is_stable[] = { "false", diff --git a/sound/soc/amlogic/meson/tv.h b/sound/soc/amlogic/meson/tv.h index cdd6017f8394..401f75edcc33 100644 --- a/sound/soc/amlogic/meson/tv.h +++ b/sound/soc/amlogic/meson/tv.h @@ -70,9 +70,6 @@ struct aml_audio_private_data { struct aml_card_info *cardinfo; #ifdef CONFIG_AMLOGIC_AO_CEC int arc_enable; -#endif -#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI - int atmos_edid_enable; #endif int Hardware_resample_enable; int spdif_sample_rate_index; @@ -100,6 +97,4 @@ extern int External_Mute(int mute_flag); #else int External_Mute(int mute_flag) { return 0; } #endif -extern void rx_set_atmos_flag(bool en); -extern void rx_get_atmos_flag(void); #endif diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 218ec12314d6..35a7a500f58f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -136,6 +136,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TAS571X if I2C select SND_SOC_TAS5720 if I2C select SND_SOC_TFA9879 if I2C + select SND_SOC_TAS5805 if I2C select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_SPI if SPI_MASTER select SND_SOC_TLV320AIC26 if SPI_MASTER @@ -812,6 +813,15 @@ config SND_SOC_TAS5720 Enable support for Texas Instruments TAS5720L/M high-efficiency mono Class-D audio power amplifiers. +config SND_SOC_TAS5805 + tristate "Texas Instruments TAS5805 amplifiers" + depends on I2C + help + Enable support for Texas Instruments TAS5805 + Class-D audio power amplifiers. + control by I2C + Select this if your TAS5805 is connected to I2C bus. + config SND_SOC_TFA9879 tristate "NXP Semiconductors TFA9879 amplifier" depends on I2C diff --git a/sound/soc/codecs/amlogic/Kconfig b/sound/soc/codecs/amlogic/Kconfig index ac0d8467953e..b4cd38258572 100644 --- a/sound/soc/codecs/amlogic/Kconfig +++ b/sound/soc/codecs/amlogic/Kconfig @@ -68,6 +68,17 @@ config AMLOGIC_SND_CODEC_PMU3 AML PMU3 codec, this codec is internal +config AMLOGIC_SND_SOC_TAS5805 + bool "Texas Instruments TAS5805 amplifier" + depends on AMLOGIC_SND_SOC_CODECS + depends on I2C + default n + help + Enable support for Texas Instruments TAS5805 CODEC. + Select this if your TAS5805 is connected via an I2C bus. + Enable support for Texas Instruments TAS5805 CODEC. + Select this if your TAS5805 is connected via an I2C bus. + config AMLOGIC_SND_CODEC_TXLX_ACODEC bool "Amlogic Audio txlx acodec" depends on AMLOGIC_SND_SOC_CODECS diff --git a/sound/soc/codecs/amlogic/Makefile b/sound/soc/codecs/amlogic/Makefile index 915e6461f554..e1fdb3b653d7 100644 --- a/sound/soc/codecs/amlogic/Makefile +++ b/sound/soc/codecs/amlogic/Makefile @@ -18,6 +18,7 @@ snd-soc-pcm186x-objs := pcm186x.o pcm186x-i2c.o pcm186x-spi.o snd-soc-ssm3515-objs := ssm3515.o snd-soc-ssm3525-objs := ssm3525.o snd-soc-ad82584f-objs := ad82584f.o +snd-soc-tas5805-objs := tas5805.o # Amlogic obj-$(CONFIG_AMLOGIC_SND_CODEC_DUMMY_CODEC) += snd-soc-dummy_codec.o @@ -39,3 +40,4 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_TAS575X) += tas575x.o obj-$(CONFIG_AMLOGIC_SND_SOC_ES7243) += es7243.o obj-$(CONFIG_AMLOGIC_SND_SOC_AD82584F) += ad82584f.o obj-$(CONFIG_AMLOGIC_SND_SOC_CS42528) += cs42528.o +obj-$(CONFIG_AMLOGIC_SND_SOC_TAS5805) += snd-soc-tas5805.o diff --git a/sound/soc/codecs/amlogic/ad82584f.c b/sound/soc/codecs/amlogic/ad82584f.c index b30cf815b38f..88fea3497960 100644 --- a/sound/soc/codecs/amlogic/ad82584f.c +++ b/sound/soc/codecs/amlogic/ad82584f.c @@ -36,12 +36,15 @@ static const DECLARE_TLV_DB_SCALE(mvol_tlv, -10300, 50, 1); static const DECLARE_TLV_DB_SCALE(chvol_tlv, -10300, 50, 1); static const struct snd_kcontrol_new ad82584f_snd_controls[] = { - SOC_SINGLE_TLV("Master Volume", MVOL, 0, + SOC_SINGLE_TLV("AMP Master Volume", MVOL, 0, 0xff, 1, mvol_tlv), - SOC_SINGLE_TLV("Ch1 Volume", C1VOL, 0, + SOC_SINGLE_TLV("AMP Ch1 Volume", C1VOL, 0, 0xff, 1, chvol_tlv), - SOC_SINGLE_TLV("Ch2 Volume", C2VOL, 0, + SOC_SINGLE_TLV("AMP Ch2 Volume", C2VOL, 0, 0xff, 1, chvol_tlv), + + SOC_SINGLE("AMP Ch1 Switch", MUTE, 5, 1, 1), + SOC_SINGLE("AMP Ch2 Switch", MUTE, 4, 1, 1), }; static int ad82584f_reg_init(struct snd_soc_codec *codec); @@ -52,7 +55,7 @@ static const struct reg_default ad82584f_reg_defaults[AD82584F_REGISTER_COUNT] = { {0x00, 0x00},//##State_Control_1 {0x01, 0x04},//##State_Control_2 - {0x02, 0x00},//##State_Control_3 + {0x02, 0x30},//##State_Control_3 {0x03, 0x4e},//##Master_volume_control {0x04, 0x00},//##Channel_1_volume_control {0x05, 0x00},//##Channel_2_volume_control @@ -190,7 +193,7 @@ struct reg_default ad82584f_reg_defaults[AD82584F_REGISTER_COUNT] = { static const int m_reg_tab[AD82584F_REGISTER_COUNT][2] = { {0x00, 0x00},//##State_Control_1 {0x01, 0x04},//##State_Control_2 - {0x02, 0x00},//##State_Control_3 + {0x02, 0x30},//##State_Control_3 {0x03, 0x4e},//##Master_volume_control {0x04, 0x00},//##Channel_1_volume_control {0x05, 0x00},//##Channel_2_volume_control @@ -591,6 +594,12 @@ struct ad82584f_priv { struct regmap *regmap; struct snd_soc_codec *codec; struct ad82584f_platform_data *pdata; + + unsigned char Ch1_vol; + unsigned char Ch2_vol; + unsigned char master_vol; + unsigned char mute_val; + #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend early_suspend; #endif @@ -809,7 +818,7 @@ static int ad82584f_init(struct snd_soc_codec *codec) ad82584f_set_eq_drc(codec); /*unmute,default power-on is mute.*/ - snd_soc_write(codec, 0x02, 0x00); + /*snd_soc_write(codec, 0x02, 0x00);*/ return 0; } @@ -844,8 +853,16 @@ static int ad82584f_remove(struct snd_soc_codec *codec) #ifdef CONFIG_PM static int ad82584f_suspend(struct snd_soc_codec *codec) { + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + dev_info(codec->dev, "ad82584f_suspend!\n"); + /* save volume */ + ad82584f->Ch1_vol = snd_soc_read(codec, C1VOL); + ad82584f->Ch2_vol = snd_soc_read(codec, C2VOL); + ad82584f->master_vol = snd_soc_read(codec, MVOL); + ad82584f->mute_val = snd_soc_read(codec, MUTE); + ad82584f_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -853,9 +870,17 @@ static int ad82584f_suspend(struct snd_soc_codec *codec) static int ad82584f_resume(struct snd_soc_codec *codec) { + struct ad82584f_priv *ad82584f = snd_soc_codec_get_drvdata(codec); + dev_info(codec->dev, "ad82584f_resume!\n"); ad82584f_init(codec); + + snd_soc_write(codec, C1VOL, ad82584f->Ch1_vol); + snd_soc_write(codec, C2VOL, ad82584f->Ch2_vol); + snd_soc_write(codec, MVOL, ad82584f->master_vol); + snd_soc_write(codec, MUTE, ad82584f->mute_val); + ad82584f_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; diff --git a/sound/soc/codecs/amlogic/ad82584f.h b/sound/soc/codecs/amlogic/ad82584f.h index f363938a84f2..fd149b8bbf0c 100644 --- a/sound/soc/codecs/amlogic/ad82584f.h +++ b/sound/soc/codecs/amlogic/ad82584f.h @@ -1,6 +1,7 @@ #ifndef _AD82584F_H #define _AD82584F_H +#define MUTE 0x02 #define MVOL 0x03 #define C1VOL 0x04 #define C2VOL 0x05 diff --git a/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c b/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c index 4869c6f645da..174babef5a71 100644 --- a/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c +++ b/sound/soc/codecs/amlogic/aml_codec_tl1_acodec.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -37,21 +38,43 @@ #include #include -#include +#include "../../../soc/amlogic/auge/iomap.h" +#include "../../../soc/amlogic/auge/regs.h" #include "aml_codec_tl1_acodec.h" +struct tl1_acodec_chipinfo { + int id; + bool is_bclk_cap_inv; //default true + bool is_bclk_o_inv; //default false + bool is_lrclk_inv; //default false + bool is_dac_phase_differ_exist; + bool is_adc_phase_differ_exist; + int mclk_sel; +}; + struct tl1_acodec_priv { struct snd_soc_codec *codec; struct snd_pcm_hw_params *params; struct regmap *regmap; - + struct tl1_acodec_chipinfo *chipinfo; int tdmout_index; + int dat0_ch_sel; + int dat1_ch_sel; + + int tdmin_index; + int adc_output_sel; + //int input_data_sel; //tdmouta,tdmoutb, + //tdmouta,tdmoutb,tdmoutc,tdmina,tdminb,tdminc + //int clk_sel; + //tdmouta,tdmoutb,tdmoutc,none,tdmina,tdminb,tdminc + int dac1_input_sel; + int dac2_input_sel; }; static const struct reg_default tl1_acodec_init_list[] = { {ACODEC_0, 0x3403BFCF}, - {ACODEC_1, 0x50502929}, + {ACODEC_1, 0x50503030}, {ACODEC_2, 0xFBFB0000}, {ACODEC_3, 0x00002222}, {ACODEC_4, 0x00010000}, @@ -59,6 +82,18 @@ static const struct reg_default tl1_acodec_init_list[] = { {ACODEC_6, 0x0}, {ACODEC_7, 0x0} }; +static struct tl1_acodec_chipinfo tl1_acodec_cinfo = { + .id = 0, + .is_bclk_cap_inv = true, //default true + .is_bclk_o_inv = false, //default false + .is_lrclk_inv = false, + + .is_dac_phase_differ_exist = false, + .is_adc_phase_differ_exist = true, + //if is_adc_phase_differ=true,modified tdmin_in_rev_ws,revert ws(lrclk); + //0 :disable; 1: enable; + //.mclk_sel = 1, +}; static int tl1_acodec_reg_init(struct snd_soc_codec *codec) { @@ -94,7 +129,8 @@ static int aml_DAC_Gain_set_enum( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); u32 reg_addr = ACODEC_1; u32 val = snd_soc_read(codec, reg_addr); @@ -115,7 +151,7 @@ static int aml_DAC_Gain_set_enum( pr_info("It has risk of distortion!\n"); } - snd_soc_write(codec, val, reg_addr); + snd_soc_write(codec, reg_addr, val); return 0; } @@ -142,7 +178,8 @@ static int aml_DAC2_Gain_set_enum( struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); u32 reg_addr = ACODEC_7; u32 val = snd_soc_read(codec, reg_addr); @@ -163,7 +200,7 @@ static int aml_DAC2_Gain_set_enum( pr_info("It has risk of distortion!\n"); } - snd_soc_write(codec, val, reg_addr); + snd_soc_write(codec, reg_addr, val); return 0; } @@ -519,34 +556,34 @@ static int tl1_acodec_dai_mute_stream(struct snd_soc_dai *dai, int mute, struct tl1_acodec_priv *aml_acodec = snd_soc_codec_get_drvdata(dai->codec); u32 reg_val; + int ret; pr_debug("%s, mute:%d\n", __func__, mute); if (stream == SNDRV_PCM_STREAM_PLAYBACK) { /* DAC 1 */ - regmap_read(aml_acodec->regmap, + ret = regmap_read(aml_acodec->regmap, ACODEC_2, ®_val); if (mute) - reg_val |= DAC_SOFT_MUTE; + reg_val |= (0x1<regmap, + ret = regmap_write(aml_acodec->regmap, ACODEC_2, reg_val); - /* DAC 2 */ - regmap_read(aml_acodec->regmap, + ret = regmap_read(aml_acodec->regmap, ACODEC_6, ®_val); if (mute) - reg_val |= DAC2_SOFT_MUTE; + reg_val |= (0x1<regmap, + ret = regmap_write(aml_acodec->regmap, ACODEC_6, reg_val); } @@ -577,12 +614,9 @@ static int tl1_acodec_probe(struct snd_soc_codec *codec) tl1_acodec_start_up(codec); tl1_acodec_reg_init(codec); - if (aml_acodec) - auge_toacodec_ctrl(aml_acodec->tdmout_index); - aml_acodec->codec = codec; tl1_acodec_dai_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - + pr_info("%s\n", __func__); return 0; } @@ -667,10 +701,50 @@ struct snd_soc_dai_driver aml_tl1_acodec_dai = { }, .ops = &tl1_acodec_dai_ops, }; +static int tl1_acodec_set_toacodec(struct tl1_acodec_priv *aml_acodec) +{ + int dat0_sel, dat1_sel, lrclk_sel, bclk_sel, mclk_sel; + unsigned int update_bits_msk = 0x0, update_bits = 0x0; + + update_bits_msk = 0x80FF7777; + if (aml_acodec->chipinfo->is_bclk_cap_inv == true) + update_bits |= (0x1<<9); + if (aml_acodec->chipinfo->is_bclk_o_inv == true) + update_bits |= (0x1<<8); + if (aml_acodec->chipinfo->is_lrclk_inv == true) + update_bits |= (0x1<<10); + + dat0_sel = (aml_acodec->tdmout_index<<2)+aml_acodec->dat0_ch_sel; + dat0_sel = dat0_sel<<16; + dat1_sel = (aml_acodec->tdmout_index<<2)+aml_acodec->dat1_ch_sel; + dat1_sel = dat1_sel<<20; + lrclk_sel = (aml_acodec->tdmout_index)<<12; + bclk_sel = (aml_acodec->tdmout_index)<<4; + + //mclk_sel = aml_acodec->chipinfo->mclk_sel; + mclk_sel = aml_acodec->tdmin_index; + + update_bits |= dat0_sel|dat1_sel|lrclk_sel|bclk_sel|mclk_sel; + update_bits |= 0x1<<31; + + audiobus_update_bits(EE_AUDIO_TOACODEC_CTRL0, update_bits_msk, + update_bits); + pr_info("%s, is_bclk_cap_inv %s\n", __func__, + aml_acodec->chipinfo->is_bclk_cap_inv?"true":"false"); + pr_info("%s, is_bclk_o_inv %s\n", __func__, + aml_acodec->chipinfo->is_bclk_o_inv?"true":"false"); + pr_info("%s, is_lrclk_inv %s\n", __func__, + aml_acodec->chipinfo->is_lrclk_inv?"true":"false"); + pr_info("%s read EE_AUDIO_TOACODEC_CTRL0=0x%08x\n", __func__, + audiobus_read(EE_AUDIO_TOACODEC_CTRL0)); + + return 0; +} static int aml_tl1_acodec_probe(struct platform_device *pdev) { struct tl1_acodec_priv *aml_acodec; + struct tl1_acodec_chipinfo *p_chipinfo; struct resource *res_mem; struct device_node *np; void __iomem *regs; @@ -684,6 +758,13 @@ static int aml_tl1_acodec_probe(struct platform_device *pdev) GFP_KERNEL); if (!aml_acodec) return -ENOMEM; + /* match data */ + p_chipinfo = (struct tl1_acodec_chipinfo *) + of_device_get_match_data(&pdev->dev); + if (!p_chipinfo) + dev_warn_once(&pdev->dev, "check whether to update tl1_acodec_chipinfo\n"); + + aml_acodec->chipinfo = p_chipinfo; res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res_mem) @@ -695,24 +776,42 @@ static int aml_tl1_acodec_probe(struct platform_device *pdev) aml_acodec->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tl1_acodec_regmap_config); + if (IS_ERR(aml_acodec->regmap)) + return PTR_ERR(aml_acodec->regmap); of_property_read_u32( pdev->dev.of_node, "tdmout_index", &aml_acodec->tdmout_index); - - pr_info("aml_tl1_acodec is used by tdmout:%d\n", + pr_info("aml_tl1_acodec tdmout_index=%d\n", aml_acodec->tdmout_index); - if (IS_ERR(aml_acodec->regmap)) - return PTR_ERR(aml_acodec->regmap); + of_property_read_u32( + pdev->dev.of_node, + "dat1_ch_sel", + &aml_acodec->dat1_ch_sel); + pr_info("aml_tl1_acodec dat1_ch_sel=%d\n", + aml_acodec->dat1_ch_sel); + of_property_read_u32( + pdev->dev.of_node, + "tdmin_index", + &aml_acodec->tdmin_index); + pr_info("aml_tl1_acodec tdmin_index=%d\n", + aml_acodec->tdmin_index); + + tl1_acodec_set_toacodec(aml_acodec); platform_set_drvdata(pdev, aml_acodec); ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tl1_acodec, &aml_tl1_acodec_dai, 1); - + if (ret) + pr_info("%s call snd_soc_register_codec error\n", __func__); + else + pr_info("%s over\n", __func__); + pr_info("%s read EE_AUDIO_TOACODEC_CTRL0=0x%08x\n", __func__, + audiobus_read(EE_AUDIO_TOACODEC_CTRL0)); return ret; } @@ -735,13 +834,16 @@ static void aml_tl1_acodec_shutdown(struct platform_device *pdev) } static const struct of_device_id aml_tl1_acodec_dt_match[] = { - {.compatible = "amlogic, tl1_codec",}, + { + .compatible = "amlogic, tl1_acodec", + .data = &tl1_acodec_cinfo, + }, {}, }; static struct platform_driver aml_tl1_acodec_platform_driver = { .driver = { - .name = "tl1_codec", + .name = "tl1_acodec", .owner = THIS_MODULE, .of_match_table = aml_tl1_acodec_dt_match, }, diff --git a/sound/soc/codecs/amlogic/tas5707.c b/sound/soc/codecs/amlogic/tas5707.c index 38c9d5d1c2e3..a8d765401baf 100644 --- a/sound/soc/codecs/amlogic/tas5707.c +++ b/sound/soc/codecs/amlogic/tas5707.c @@ -185,6 +185,7 @@ static const struct snd_kcontrol_new tas5707_snd_controls[] = { 0xff, 1, chvol_tlv), SOC_SINGLE("Ch1 Switch", DDX_SOFT_MUTE, 0, 1, 1), SOC_SINGLE("Ch2 Switch", DDX_SOFT_MUTE, 1, 1, 1), + SOC_SINGLE("Shutdown Switch", DDX_SYS_CTL_2, 6, 1, 1), SOC_SINGLE_RANGE("Fine Master Volume", DDX_CHANNEL3_VOL, 0, 0x80, 0x83, 0), SOC_SINGLE_BOOL_EXT("Set EQ Enable", 0, diff --git a/sound/soc/codecs/amlogic/tas5805.c b/sound/soc/codecs/amlogic/tas5805.c new file mode 100644 index 000000000000..36f11cf2c519 --- /dev/null +++ b/sound/soc/codecs/amlogic/tas5805.c @@ -0,0 +1,547 @@ +/* + * Driver for the TAS5805M Audio Amplifier + * + * Author: Andy Liu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tas5805.h" + +#define TAS5805M_DRV_NAME "tas5805m" + +#define TAS5805M_RATES (SNDRV_PCM_RATE_8000 | \ + SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000) +#define TAS5805M_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define TAS5805M_REG_00 (0x00) +#define TAS5805M_REG_03 (0x03) +#define TAS5805M_REG_24 (0x24) +#define TAS5805M_REG_25 (0x25) +#define TAS5805M_REG_26 (0x26) +#define TAS5805M_REG_27 (0x27) +#define TAS5805M_REG_28 (0x28) +#define TAS5805M_REG_29 (0x29) +#define TAS5805M_REG_2A (0x2a) +#define TAS5805M_REG_2B (0x2b) +#define TAS5805M_REG_35 (0x35) +#define TAS5805M_REG_7F (0x7f) + +#define TAS5805M_PAGE_00 (0x00) +#define TAS5805M_PAGE_2A (0x2a) + +#define TAS5805M_BOOK_00 (0x00) +#define TAS5805M_BOOK_8C (0x8c) + +#define TAS5805M_VOLUME_MAX (158) +#define TAS5805M_VOLUME_MIN (0) + +const uint32_t tas5805m_volume[] = { + 0x0000001B, //0, -110dB + 0x0000001E, //1, -109dB + 0x00000021, //2, -108dB + 0x00000025, //3, -107dB + 0x0000002A, //4, -106dB + 0x0000002F, //5, -105dB + 0x00000035, //6, -104dB + 0x0000003B, //7, -103dB + 0x00000043, //8, -102dB + 0x0000004B, //9, -101dB + 0x00000054, //10, -100dB + 0x0000005E, //11, -99dB + 0x0000006A, //12, -98dB + 0x00000076, //13, -97dB + 0x00000085, //14, -96dB + 0x00000095, //15, -95dB + 0x000000A7, //16, -94dB + 0x000000BC, //17, -93dB + 0x000000D3, //18, -92dB + 0x000000EC, //19, -91dB + 0x00000109, //20, -90dB + 0x0000012A, //21, -89dB + 0x0000014E, //22, -88dB + 0x00000177, //23, -87dB + 0x000001A4, //24, -86dB + 0x000001D8, //25, -85dB + 0x00000211, //26, -84dB + 0x00000252, //27, -83dB + 0x0000029A, //28, -82dB + 0x000002EC, //29, -81dB + 0x00000347, //30, -80dB + 0x000003AD, //31, -79dB + 0x00000420, //32, -78dB + 0x000004A1, //33, -77dB + 0x00000532, //34, -76dB + 0x000005D4, //35, -75dB + 0x0000068A, //36, -74dB + 0x00000756, //37, -73dB + 0x0000083B, //38, -72dB + 0x0000093C, //39, -71dB + 0x00000A5D, //40, -70dB + 0x00000BA0, //41, -69dB + 0x00000D0C, //42, -68dB + 0x00000EA3, //43, -67dB + 0x0000106C, //44, -66dB + 0x0000126D, //45, -65dB + 0x000014AD, //46, -64dB + 0x00001733, //47, -63dB + 0x00001A07, //48, -62dB + 0x00001D34, //49, -61dB + 0x000020C5, //50, -60dB + 0x000024C4, //51, -59dB + 0x00002941, //52, -58dB + 0x00002E49, //53, -57dB + 0x000033EF, //54, -56dB + 0x00003A45, //55, -55dB + 0x00004161, //56, -54dB + 0x0000495C, //57, -53dB + 0x0000524F, //58, -52dB + 0x00005C5A, //59, -51dB + 0x0000679F, //60, -50dB + 0x00007444, //61, -49dB + 0x00008274, //62, -48dB + 0x0000925F, //63, -47dB + 0x0000A43B, //64, -46dB + 0x0000B845, //65, -45dB + 0x0000CEC1, //66, -44dB + 0x0000E7FB, //67, -43dB + 0x00010449, //68, -42dB + 0x0001240C, //69, -41dB + 0x000147AE, //70, -40dB + 0x00016FAA, //71, -39dB + 0x00019C86, //72, -38dB + 0x0001CEDC, //73, -37dB + 0x00020756, //74, -36dB + 0x000246B5, //75, -35dB + 0x00028DCF, //76, -34dB + 0x0002DD96, //77, -33dB + 0x00033718, //78, -32dB + 0x00039B87, //79, -31dB + 0x00040C37, //80, -30dB + 0x00048AA7, //81, -29dB + 0x00051884, //82, -28dB + 0x0005B7B1, //83, -27dB + 0x00066A4A, //84, -26dB + 0x000732AE, //85, -25dB + 0x00081385, //86, -24dB + 0x00090FCC, //87, -23dB + 0x000A2ADB, //88, -22dB + 0x000B6873, //89, -21dB + 0x000CCCCD, //90, -20dB + 0x000E5CA1, //91, -19dB + 0x00101D3F, //92, -18dB + 0x0012149A, //93, -17dB + 0x00144961, //94, -16dB + 0x0016C311, //95, -15dB + 0x00198A13, //96, -14dB + 0x001CA7D7, //97, -13dB + 0x002026F3, //98, -12dB + 0x00241347, //99, -11dB + 0x00287A27, //100, -10dB + 0x002D6A86, //101, -9dB + 0x0032F52D, //102, -8dB + 0x00392CEE, //103, -7dB + 0x004026E7, //104, -6dB + 0x0047FACD, //105, -5dB + 0x0050C336, //106, -4dB + 0x005A9DF8, //107, -3dB + 0x0065AC8C, //108, -2dB + 0x00721483, //109, -1dB + 0x00800000, //110, 0dB + 0x008F9E4D, //111, 1dB + 0x00A12478, //112, 2dB + 0x00B4CE08, //113, 3dB + 0x00CADDC8, //114, 4dB + 0x00E39EA9, //115, 5dB + 0x00FF64C1, //116, 6dB + 0x011E8E6A, //117, 7dB + 0x0141857F, //118, 8dB + 0x0168C0C6, //119, 9dB + 0x0194C584, //120, 10dB + 0x01C62940, //121, 11dB + 0x01FD93C2, //122, 12dB + 0x023BC148, //123, 13dB + 0x02818508, //124, 14dB + 0x02CFCC01, //125, 15dB + 0x0327A01A, //126, 16dB + 0x038A2BAD, //127, 17dB + 0x03F8BD7A, //128, 18dB + 0x0474CD1B, //129, 19dB + 0x05000000, //130, 20dB + 0x059C2F02, //131, 21dB + 0x064B6CAE, //132, 22dB + 0x07100C4D, //133, 23dB + 0x07ECA9CD, //134, 24dB + 0x08E43299, //135, 25dB + 0x09F9EF8E, //136, 26dB + 0x0B319025, //137, 27dB + 0x0C8F36F2, //138, 28dB + 0x0E1787B8, //139, 29dB + 0x0FCFB725, //140, 30dB + 0x11BD9C84, //141, 31dB + 0x13E7C594, //142, 32dB + 0x16558CCB, //143, 33dB + 0x190F3254, //144, 34dB + 0x1C1DF80E, //145, 35dB + 0x1F8C4107, //146, 36dB + 0x2365B4BF, //147, 37dB + 0x27B766C2, //148, 38dB + 0x2C900313, //149, 39dB + 0x32000000, //150, 40dB + 0x3819D612, //151, 41dB + 0x3EF23ECA, //152, 42dB + 0x46A07B07, //153, 43dB + 0x4F3EA203, //154, 44dB + 0x58E9F9F9, //155, 45dB + 0x63C35B8E, //156, 46dB + 0x6FEFA16D, //157, 47dB + 0x7D982575, //158, 48dB +}; + +struct tas5805m_priv { + struct regmap *regmap; + + struct mutex lock; + + int vol; + int mute; +}; + +const struct regmap_config tas5805m_regmap = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, +}; + +static int tas5805m_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->access = + (SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE); + uinfo->count = 1; + + uinfo->value.integer.min = TAS5805M_VOLUME_MIN; + uinfo->value.integer.max = TAS5805M_VOLUME_MAX; + uinfo->value.integer.step = 1; + + return 0; +} + +static int tas5805m_mute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->access = + (SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE); + uinfo->count = 1; + + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + uinfo->value.integer.step = 1; + + return 0; +} + +static int tas5805m_vol_locked_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + ucontrol->value.integer.value[0] = tas5805m->vol; + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static inline int get_volume_index(int vol) +{ + int index; + + index = vol; + + if (index < TAS5805M_VOLUME_MIN) + index = TAS5805M_VOLUME_MIN; + + if (index > TAS5805M_VOLUME_MAX) + index = TAS5805M_VOLUME_MAX; + + return index; +} + +static void tas5805m_set_volume(struct snd_soc_codec *codec, int vol) +{ + unsigned int index; + uint32_t volume_hex; + uint8_t byte4; + uint8_t byte3; + uint8_t byte2; + uint8_t byte1; + + index = get_volume_index(vol); + volume_hex = tas5805m_volume[index]; + + byte4 = ((volume_hex >> 24) & 0xFF); + byte3 = ((volume_hex >> 16) & 0xFF); + byte2 = ((volume_hex >> 8) & 0xFF); + byte1 = ((volume_hex >> 0) & 0xFF); + + //w 58 00 00 + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + //w 58 7f 8c + snd_soc_write(codec, TAS5805M_REG_7F, TAS5805M_BOOK_8C); + //w 58 00 2a + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_2A); + //w 58 24 xx xx xx xx + snd_soc_write(codec, TAS5805M_REG_24, byte4); + snd_soc_write(codec, TAS5805M_REG_25, byte3); + snd_soc_write(codec, TAS5805M_REG_26, byte2); + snd_soc_write(codec, TAS5805M_REG_27, byte1); + //w 58 28 xx xx xx xx + snd_soc_write(codec, TAS5805M_REG_28, byte4); + snd_soc_write(codec, TAS5805M_REG_29, byte3); + snd_soc_write(codec, TAS5805M_REG_2A, byte2); + snd_soc_write(codec, TAS5805M_REG_2B, byte1); +} + +static int tas5805m_vol_locked_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + + tas5805m->vol = ucontrol->value.integer.value[0]; + tas5805m_set_volume(codec, tas5805m->vol); + + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static int tas5805m_mute(struct snd_soc_codec *codec, int mute) +{ + u8 reg03_value = 0; + u8 reg35_value = 0; +// struct snd_soc_codec *codec = dai->codec; + + if (mute) { + //mute both left & right channels + reg03_value = 0x0b; + reg35_value = 0x00; + } else { + //unmute + reg03_value = 0x03; + reg35_value = 0x11; + } + + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_REG_7F, TAS5805M_BOOK_00); + snd_soc_write(codec, TAS5805M_REG_00, TAS5805M_PAGE_00); + snd_soc_write(codec, TAS5805M_REG_03, reg03_value); + snd_soc_write(codec, TAS5805M_REG_35, reg35_value); + + return 0; +} + +static int tas5805m_mute_locked_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + + tas5805m->mute = ucontrol->value.integer.value[0]; + tas5805m_mute(codec, tas5805m->mute); + + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static int tas5805m_mute_locked_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct tas5805m_priv *tas5805m = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&tas5805m->lock); + ucontrol->value.integer.value[0] = tas5805m->mute; + mutex_unlock(&tas5805m->lock); + + return 0; +} + +static const struct snd_kcontrol_new tas5805m_vol_control[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Volume", + .info = tas5805m_vol_info, + .get = tas5805m_vol_locked_get, + .put = tas5805m_vol_locked_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Maser Volume Mute", + .info = tas5805m_mute_info, + .get = tas5805m_mute_locked_get, + .put = tas5805m_mute_locked_put, + } +}; + +static int tas5805m_snd_probe(struct snd_soc_codec *codec) +{ + int ret; + + ret = snd_soc_add_codec_controls(codec, tas5805m_vol_control, 2); + + return ret; +} + +static struct snd_soc_codec_driver soc_codec_tas5805m = { + .probe = tas5805m_snd_probe, +}; + +static const struct snd_soc_dai_ops tas5805m_dai_ops = { + //.digital_mute = tas5805m_mute, +}; + +static struct snd_soc_dai_driver tas5805m_dai = { + .name = "tas5805m-amplifier", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, + .rates = TAS5805M_RATES, + .formats = TAS5805M_FORMATS, + }, + .ops = &tas5805m_dai_ops, +}; + +static int tas5805m_probe(struct device *dev, struct regmap *regmap) +{ + struct tas5805m_priv *tas5805m; + int ret; + + tas5805m = devm_kzalloc(dev, sizeof(struct tas5805m_priv), GFP_KERNEL); + if (!tas5805m) + return -ENOMEM; + + dev_set_drvdata(dev, tas5805m); + tas5805m->regmap = regmap; + tas5805m->vol = 100; //100, -10dB + + mutex_init(&tas5805m->lock); + + ret = + regmap_register_patch(regmap, tas5805m_init_sequence, + ARRAY_SIZE(tas5805m_init_sequence)); + if (ret != 0) { + dev_err(dev, "Failed to initialize TAS5805M: %d\n", ret); + goto err; + + } + + ret = + snd_soc_register_codec(dev, &soc_codec_tas5805m, &tas5805m_dai, 1); + if (ret != 0) { + dev_err(dev, "Failed to register CODEC: %d\n", ret); + goto err; + } + + return 0; + +err: + return ret; + +} + +static int tas5805m_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + struct regmap_config config = tas5805m_regmap; + + regmap = devm_regmap_init_i2c(i2c, &config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return tas5805m_probe(&i2c->dev, regmap); +} + +static int tas5805m_remove(struct device *dev) +{ + snd_soc_unregister_codec(dev); + + return 0; +} + +static int tas5805m_i2c_remove(struct i2c_client *i2c) +{ + tas5805m_remove(&i2c->dev); + + return 0; +} + +static const struct i2c_device_id tas5805m_i2c_id[] = { + {"tas5805",}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tas5805m_i2c_id); + +#ifdef CONFIG_OF +static const struct of_device_id tas5805m_of_match[] = { + {.compatible = "ti,tas5805",}, + {} +}; + +MODULE_DEVICE_TABLE(of, tas5805m_of_match); +#endif + +static struct i2c_driver tas5805m_i2c_driver = { + .probe = tas5805m_i2c_probe, + .remove = tas5805m_i2c_remove, + .id_table = tas5805m_i2c_id, + .driver = { + .name = TAS5805M_DRV_NAME, + .of_match_table = tas5805m_of_match, + }, +}; + +module_i2c_driver(tas5805m_i2c_driver); + +MODULE_AUTHOR("Andy Liu "); +MODULE_DESCRIPTION("TAS5805M Audio Amplifier Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/amlogic/tas5805.h b/sound/soc/codecs/amlogic/tas5805.h new file mode 100644 index 000000000000..ba6066204b12 --- /dev/null +++ b/sound/soc/codecs/amlogic/tas5805.h @@ -0,0 +1,1880 @@ +#include +static const struct reg_sequence tas5805m_init_sequence[] = { + {0x00, 0x00}, + {0x7f, 0x00}, + {0x03, 0x02}, + {0x01, 0x11}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x29, 0x7c}, + {0x03, 0x02}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x29, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x46, 0x11}, + {0x03, 0x0f}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x66, 0x85}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x24, 0x00}, + {0x25, 0x28}, + {0x26, 0x7a}, + {0x27, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x28, 0x00}, + {0x29, 0x28}, + {0x2a, 0x7a}, + {0x2b, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x0b}, + {0x28, 0x00}, + {0x29, 0x80}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x0b}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x18, 0x00}, + {0x19, 0x80}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x29}, + {0x24, 0x00}, + {0x25, 0x80}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x24, 0x00}, + {0x25, 0x28}, + {0x26, 0x7a}, + {0x27, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x28, 0x00}, + {0x29, 0x28}, + {0x2a, 0x7a}, + {0x2b, 0x27}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2a}, + {0x30, 0x00}, + {0x31, 0xe2}, + {0x32, 0xc4}, + {0x33, 0x6b}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x14, 0x00}, + {0x15, 0x80}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x1c, 0x00}, + {0x1d, 0x80}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x2c, 0x00}, + {0x2d, 0x80}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x34, 0x00}, + {0x35, 0x80}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x4c, 0x00}, + {0x4d, 0x80}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x57}, + {0x5f, 0x62}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x60, 0x00}, + {0x61, 0x03}, + {0x62, 0x69}, + {0x63, 0xd0}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x64, 0x00}, + {0x65, 0xce}, + {0x66, 0xc0}, + {0x67, 0x8a}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x68, 0x40}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2c}, + {0x6c, 0x05}, + {0x6d, 0x1f}, + {0x6e, 0x97}, + {0x6f, 0x37}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x18, 0x7a}, + {0x19, 0xe0}, + {0x1a, 0x68}, + {0x1b, 0xc9}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0xae}, + {0x1f, 0xc3}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x2c, 0x00}, + {0x2d, 0x80}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x31}, + {0x48, 0x40}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x32}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x33}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x34}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x35}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x24}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x25}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x26}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x27}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x18, 0x08}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x20, 0x00}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x2c, 0x08}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x34, 0x00}, + {0x35, 0x00}, + {0x36, 0x00}, + {0x37, 0x00}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x40, 0x08}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x54, 0x08}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x68, 0x08}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x00}, + {0x71, 0x00}, + {0x72, 0x00}, + {0x73, 0x00}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x28}, + {0x7c, 0x08}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x29}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x08, 0x00}, + {0x09, 0x80}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x0c, 0x00}, + {0x0d, 0x00}, + {0x0e, 0x00}, + {0x0f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x48, 0x7f}, + {0x49, 0xff}, + {0x4a, 0xff}, + {0x4b, 0xff}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x58, 0x00}, + {0x59, 0x06}, + {0x5a, 0xd3}, + {0x5b, 0x72}, + {0x5c, 0x00}, + {0x5d, 0x02}, + {0x5e, 0xbb}, + {0x5f, 0x06}, + {0x60, 0x00}, + {0x61, 0x03}, + {0x62, 0x69}, + {0x63, 0xc5}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0xf9}, + {0x71, 0xda}, + {0x72, 0xbc}, + {0x73, 0x21}, + {0x74, 0xfc}, + {0x75, 0x58}, + {0x76, 0x8b}, + {0x77, 0x89}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2b}, + {0x34, 0x00}, + {0x35, 0x06}, + {0x36, 0xd3}, + {0x37, 0x72}, + {0x38, 0x00}, + {0x39, 0x02}, + {0x3a, 0xbb}, + {0x3b, 0x06}, + {0x3c, 0x00}, + {0x3d, 0x03}, + {0x3e, 0x69}, + {0x3f, 0xc5}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0xf9}, + {0x4d, 0xda}, + {0x4e, 0xbc}, + {0x4f, 0x21}, + {0x50, 0xfc}, + {0x51, 0x58}, + {0x52, 0x8b}, + {0x53, 0x89}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x34, 0x7f}, + {0x35, 0xff}, + {0x36, 0xff}, + {0x37, 0xff}, + {0x38, 0x00}, + {0x39, 0x00}, + {0x3a, 0x00}, + {0x3b, 0x00}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2d}, + {0x30, 0x00}, + {0x31, 0x06}, + {0x32, 0xd3}, + {0x33, 0x72}, + {0x34, 0x00}, + {0x35, 0x02}, + {0x36, 0xbb}, + {0x37, 0x06}, + {0x38, 0x00}, + {0x39, 0x03}, + {0x3a, 0x69}, + {0x3b, 0xc5}, + {0x3c, 0x00}, + {0x3d, 0x00}, + {0x3e, 0x00}, + {0x3f, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x00}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0xf9}, + {0x49, 0xda}, + {0x4a, 0xbc}, + {0x4b, 0x21}, + {0x4c, 0xfc}, + {0x4d, 0x58}, + {0x4e, 0x8b}, + {0x4f, 0x89}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x56, 0x00}, + {0x57, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x5c, 0x7f}, + {0x5d, 0xff}, + {0x5e, 0xff}, + {0x5f, 0xff}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x68, 0x00}, + {0x69, 0x00}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x00}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2a}, + {0x70, 0x7f}, + {0x71, 0xff}, + {0x72, 0xff}, + {0x73, 0xff}, + {0x74, 0x00}, + {0x75, 0x00}, + {0x76, 0x00}, + {0x77, 0x00}, + {0x78, 0x00}, + {0x79, 0x00}, + {0x7a, 0x00}, + {0x7b, 0x00}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7e, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2b}, + {0x08, 0x00}, + {0x09, 0x00}, + {0x0a, 0x00}, + {0x0b, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2b}, + {0x0c, 0x7f}, + {0x0d, 0xff}, + {0x0e, 0xff}, + {0x0f, 0xff}, + {0x10, 0x00}, + {0x11, 0x00}, + {0x12, 0x00}, + {0x13, 0x00}, + {0x14, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x17, 0x00}, + {0x18, 0x00}, + {0x19, 0x00}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2b}, + {0x20, 0x7f}, + {0x21, 0xff}, + {0x22, 0xff}, + {0x23, 0xff}, + {0x24, 0x00}, + {0x25, 0x00}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x00}, + {0x29, 0x00}, + {0x2a, 0x00}, + {0x2b, 0x00}, + {0x2c, 0x00}, + {0x2d, 0x00}, + {0x2e, 0x00}, + {0x2f, 0x00}, + {0x30, 0x00}, + {0x31, 0x00}, + {0x32, 0x00}, + {0x33, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2e}, + {0x40, 0x7f}, + {0x41, 0xff}, + {0x42, 0xff}, + {0x43, 0xff}, + {0x44, 0x00}, + {0x45, 0x00}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0x00}, + {0x4d, 0x00}, + {0x4e, 0x00}, + {0x4f, 0x00}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x00, 0x00}, + {0x7f, 0xaa}, + {0x00, 0x2e}, + {0x54, 0x7f}, + {0x55, 0xff}, + {0x56, 0xff}, + {0x57, 0xff}, + {0x58, 0x00}, + {0x59, 0x00}, + {0x5a, 0x00}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e, 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + {0x63, 0x00}, + {0x64, 0x00}, + {0x65, 0x00}, + {0x66, 0x00}, + {0x67, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x18, 0x00}, + {0x19, 0x80}, + {0x1a, 0x00}, + {0x1b, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x1c, 0x40}, + {0x1d, 0x00}, + {0x1e, 0x00}, + {0x1f, 0x00}, + {0x00, 0x00}, + {0x7f, 0x8c}, + {0x00, 0x2e}, + {0x20, 0x40}, + {0x21, 0x00}, + {0x22, 0x00}, + {0x23, 0x00}, +//Register Tuning + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x30, 0x00}, + {0x60, 0x00}, + {0x62, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x4c, 0x30}, + {0x4d, 0x30}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x02, 0x00}, + {0x00, 0x00}, + {0x7f, 0x00}, + {0x00, 0x00}, + {0x03, 0x03}, + {0x35, 0x11}, +};