mirror of
https://github.com/revyos/thead-kernel.git
synced 2026-06-21 17:22:24 +02:00
Compare commits
4 Commits
huiwei
...
Linux_SDK_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4327ba402 | ||
|
|
599b048690 | ||
|
|
b269dc8fa7 | ||
|
|
87e5c31f94 |
@@ -21,7 +21,6 @@ config RISCV
|
||||
select ARCH_HAS_GCOV_PROFILE_ALL
|
||||
select ARCH_HAS_GIGANTIC_PAGE
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_MMIOWB
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
select ARCH_HAS_SET_DIRECT_MAP
|
||||
select ARCH_HAS_SET_MEMORY
|
||||
@@ -35,6 +34,7 @@ config RISCV
|
||||
select ARCH_KEEP_MEMBLOCK
|
||||
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
|
||||
select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
|
||||
@@ -12,15 +12,17 @@ dtb-$(CONFIG_SOC_THEAD) += light-a-val-ddr2G.dtb light-a-val-ddr1G.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-npu-fce.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-iso7816.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-nand.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-audio.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-dsi0.dtb light-a-val-dsi1.dtb light-a-val-hdmi.dtb light-a-val-dsi0-dsi1.dtb light-a-val-dsi0-hdmi.dtb light-a-val-dpi0.dtb light-a-val-dpi0-dpi1.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-audio.dtb light-a-val-audio-i2s-8ch.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-audio-tdm.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-audio-spdif.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-dsi0.dtb light-a-val-dsi1.dtb light-a-val-hdmi.dtb light-a-val-dsi0-dsi1.dtb light-a-val-dsi0-hdmi.dtb light-a-val-dsi0-hdmi-audio.dtb light-a-val-dpi0.dtb light-a-val-dpi0-dpi1.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-wcn.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-gpio-keys.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-khv.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-sec.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-miniapp-hdmi.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-product.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-b-product.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-b-product.dtb light-b-product-sec.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-b-product-ddr1G.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-b-product-miniapp-hdmi.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-a-val-full.dtb
|
||||
@@ -37,3 +39,4 @@ dtb-$(CONFIG_SOC_THEAD) += light-a-val-android.dtb
|
||||
|
||||
dtb-$(CONFIG_SOC_THEAD) += fire-emu.dtb fire-emu-crash.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += fire-emu-soc-base.dtb fire-emu-soc-c910x4.dtb fire-emu-gpu-dpu-dsi0.dtb fire-emu-vi-dsp-vo.dtb fire-emu-vi-vp-vo.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += fire-emu-soc-base-sec.dtb
|
||||
|
||||
@@ -523,7 +523,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
|
||||
13
arch/riscv/boot/dts/thead/fire-emu-soc-base-sec.dts
Normal file
13
arch/riscv/boot/dts/thead/fire-emu-soc-base-sec.dts
Normal file
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/* #include "fire-emu.dts" */
|
||||
#include "fire-emu-soc-base.dts"
|
||||
|
||||
&light_iopmp {
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -338,16 +338,18 @@
|
||||
clock-frequency = <100000>;
|
||||
status = "disabled";
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
};
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -488,7 +490,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
|
||||
@@ -373,7 +373,7 @@
|
||||
entry-cnt = <4>;
|
||||
control-reg = <0xff 0xff015004>;
|
||||
control-val = <0x1c>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc 0x7ce>;
|
||||
};
|
||||
|
||||
clint0: clint@ffdc000000 {
|
||||
@@ -1335,8 +1335,7 @@
|
||||
|
||||
emmc: sdhci@ffe7080000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe7080000 0x0 0x10000
|
||||
0xff 0xef014060 0x0 0x4>;
|
||||
reg = <0xff 0xe7080000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <62>;
|
||||
interrupt-names = "sdhciirq";
|
||||
@@ -1346,8 +1345,7 @@
|
||||
|
||||
sdhci0: sd@ffe7090000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe7090000 0x0 0x10000
|
||||
0xff 0xef014064 0x0 0x4>;
|
||||
reg = <0xff 0xe7090000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <64>;
|
||||
interrupt-names = "sdhci0irq";
|
||||
@@ -1357,8 +1355,7 @@
|
||||
|
||||
sdhci1: sd@ffe70a0000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe70a0000 0x0 0x10000
|
||||
0xff 0xef014064 0x0 0x4>;
|
||||
reg = <0xff 0xe70a0000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <71>;
|
||||
interrupt-names = "sdhci1irq";
|
||||
@@ -1433,7 +1430,7 @@
|
||||
compatible = "light,light-i2s";
|
||||
reg = <0xff 0xe7034000 0x0 0x4000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_i2s0>;
|
||||
pinctrl-0 = <&pinctrl_light_i2s0>;
|
||||
light,mode = "i2s-master";
|
||||
light,sel = "ap_i2s";
|
||||
interrupt-parent = <&intc>;
|
||||
|
||||
@@ -687,6 +687,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -729,7 +730,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-a-val.dts"
|
||||
#include "light-a-val-audio.dts"
|
||||
|
||||
/ {
|
||||
display-subsystem {
|
||||
@@ -40,28 +40,6 @@
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s0 0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es8156_audio_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@1 { /* I2S - AUDIO SYS CODEC 7210*/
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@2 { /* I2S - HDMI */
|
||||
reg = <2>;
|
||||
@@ -70,7 +48,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -78,12 +56,3 @@
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
100
arch/riscv/boot/dts/thead/light-a-val-audio-i2s-8ch.dts
Normal file
100
arch/riscv/boot/dts/thead/light-a-val-audio-i2s-8ch.dts
Normal file
@@ -0,0 +1,100 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include "light-a-val-audio.dts"
|
||||
|
||||
/ {
|
||||
model = "T-HEAD Light FM Audio VAL board";
|
||||
compatible = "thead,light-val-audio-i2s-8ch", "thead,light";
|
||||
};
|
||||
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
|
||||
simple-audio-card,dai-link@1 { /* I2S - AUDIO SYS CODEC 7210*/
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
mclk-fs = <512>;
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@2 { /* I2S - AUDIO SYS CODEC 7210*/
|
||||
reg = <2>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s_8ch_sd3 3>;
|
||||
};
|
||||
codec {
|
||||
mclk-fs = <512>;
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@3 { /* I2S - AUDIO SYS CODEC 7210_1*/
|
||||
reg = <3>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s_8ch_sd0 0>;
|
||||
};
|
||||
codec {
|
||||
mclk-fs = <512>;
|
||||
sound-dai = <&es7210_audio_codec_adc1>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@4 { /* I2S - AUDIO SYS CODEC 7210_1*/
|
||||
reg = <4>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s_8ch_sd1 1>;
|
||||
};
|
||||
codec {
|
||||
mclk-fs = <512>;
|
||||
sound-dai = <&es7210_audio_codec_adc1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2s_8ch_sd0 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa4>,
|
||||
<&pinctrl_audio_i2s_8ch_sd0>,
|
||||
<&pinctrl_audiopa2>,
|
||||
<&pinctrl_audiopa3>,
|
||||
<&pinctrl_audiopa8>,
|
||||
<&pinctrl_audio_i2s_8ch_bus>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa0>,
|
||||
<&pinctrl_audio_i2s_8ch_sd2>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc0 {
|
||||
status = "okay";
|
||||
channels-max = <8>;
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc1 {
|
||||
status = "okay";
|
||||
channels-max = <8>;
|
||||
};
|
||||
42
arch/riscv/boot/dts/thead/light-a-val-audio-spdif.dts
Normal file
42
arch/riscv/boot/dts/thead/light-a-val-audio-spdif.dts
Normal file
@@ -0,0 +1,42 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include "light-a-val.dts"
|
||||
|
||||
&spdif0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_spdif0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spdif1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_spdif1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,dai-link@0 { /* SPDIF0 */
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&spdif0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
simple-audio-card,dai-link@1 { /* SPDIF1 */
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&spdif1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
182
arch/riscv/boot/dts/thead/light-a-val-audio-tdm.dts
Normal file
182
arch/riscv/boot/dts/thead/light-a-val-audio-tdm.dts
Normal file
@@ -0,0 +1,182 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include "light-a-val.dts"
|
||||
|
||||
&tdm_slot1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_tdm>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot4 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot5 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot6 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot7 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tdm_slot8 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es7210_adc2: es7210@42 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x42>;
|
||||
work-mode = "ES7210_TDM_1LRCK_DSPB";
|
||||
channels-max = <8>;
|
||||
sound-name-prefix = "ES7210_ADC2";
|
||||
MVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
PVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
};
|
||||
|
||||
es7210_adc3: es7210@43 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_1";
|
||||
reg = <0x43>;
|
||||
work-mode = "ES7210_TDM_1LRCK_DSPB";
|
||||
channels-max = <8>;
|
||||
sound-name-prefix = "ES7210_ADC3";
|
||||
MVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
PVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
};
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"AW87519 IN", "ES8156 ROUT",
|
||||
"Speaker", "AW87519 VO";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s0 0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es8156_audio_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@1 { /* TDM - AUDIO SYS CODEC 7210*/
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@2 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@3 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot3>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@4 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot4>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@5 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot5>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@6 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot6>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@7 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot7>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@8 {
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu {
|
||||
sound-dai = <&tdm_slot8>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -11,8 +11,12 @@
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
@@ -28,22 +32,24 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x40000000>;
|
||||
reg = <0x0 0x200000 0x0 0x3fe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
64
arch/riscv/boot/dts/thead/light-a-val-dsi0-hdmi-audio.dts
Normal file
64
arch/riscv/boot/dts/thead/light-a-val-dsi0-hdmi-audio.dts
Normal file
@@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-a-val-dsi0-hdmi.dts"
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s0 0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es8156_audio_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
simple-audio-card,dai-link@1 { /* I2S - AUDIO SYS CODEC 7210*/
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
simple-audio-card,dai-link@2 { /* I2S - HDMI */
|
||||
reg = <2>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc0 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -95,7 +95,11 @@
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
@@ -111,23 +115,27 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -74,6 +74,26 @@
|
||||
};
|
||||
};
|
||||
|
||||
&padctrl_audiosys {
|
||||
status = "okay";
|
||||
|
||||
light-audio-padctrl {
|
||||
/*
|
||||
* Pin Configuration Node:
|
||||
* Format: <pin_id mux_node config>
|
||||
*/
|
||||
|
||||
pinctrl_audio_i2s_8ch: audio_i2s_8ch_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA0 0x2 0x008
|
||||
FM_AUDIO_IO_PA2 0x2 0x008
|
||||
FM_AUDIO_IO_PA3 0x2 0x008
|
||||
FM_AUDIO_IO_PA8 0x2 0x008
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
|
||||
@@ -92,15 +112,14 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -109,7 +128,11 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -56,10 +56,10 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
sound-dai = <&es7210_audio_codec_adc0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -73,7 +73,11 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&es7210_audio_codec_adc0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-a-val-dsi0-hdmi.dts"
|
||||
#include "light-a-val-audio-hdmi.dts"
|
||||
|
||||
|
||||
&light_iopmp {
|
||||
status = "disabled";
|
||||
};
|
||||
&qspi1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
@@ -179,7 +179,8 @@
|
||||
compatible = "thead,light-mbox-client";
|
||||
mbox-names = "906";
|
||||
mboxes = <&mbox_910t 2 0>;
|
||||
status = "disabled";
|
||||
audio-mbox-regmap = <&audio_mbox>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
lightsound: lightsound@1 {
|
||||
@@ -192,9 +193,24 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
light_rpmsg: light_rpmsg {
|
||||
compatible = "light,rpmsg-bus", "simple-bus";
|
||||
memory-region = <&rpmsgmem>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
rpmsg: rpmsg{
|
||||
vdev-nums = <1>;
|
||||
reg = <0x0 0x1E000000 0 0x10000>;
|
||||
compatible = "light,light-rpmsg";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
sound-name-prefix = "DUMMY";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -262,6 +278,24 @@
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
soc_aud_adc_3v3_en_reg: soc-aud-adc-3v3-en {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "soc_aud_adc_3v3_en";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&pcal6408ahk_b 1 1>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
soc_aud_dac_3v3_en_reg: soc-aud-dac-3v3-en {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "soc_aud_dac_3v3_en";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&pcal6408ahk_b 2 1>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
wcn_wifi: wireless-wlan {
|
||||
compatible = "wlan-platdata";
|
||||
clock-names = "clk_wifi";
|
||||
@@ -512,7 +546,14 @@
|
||||
reg = <0x0 0x22000000 0x0 0x10000000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
audio_mem: memory@32000000 {
|
||||
reg = <0x0 0x32000000 0x0 0x6400000>;
|
||||
no-map;
|
||||
};
|
||||
rpmsgmem: memory@1E000000 {
|
||||
reg = <0x0 0x1E000000 0x0 0x10000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
@@ -556,17 +597,74 @@
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa6>,
|
||||
<&pinctrl_audiopa7>,
|
||||
<&pinctrl_audio_i2c0>;
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
};
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
AVDD-supply = <&soc_aud_dac_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
PVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
mclk-sclk-ratio = <4>;
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
es7210_audio_codec_adc0: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
status = "disabled";
|
||||
work-mode = "ES7210_NORMAL_I2S";
|
||||
channels-max = <2>;
|
||||
mclk-sclk-ratio = <4>;
|
||||
sound-name-prefix = "ES7210_ADC0";
|
||||
MVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
PVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
};
|
||||
|
||||
es7210_audio_codec_adc1: es7210@41 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_1";
|
||||
reg = <0x41>;
|
||||
status = "disabled";
|
||||
work-mode = "ES7210_NORMAL_I2S";
|
||||
channels-max = <2>;
|
||||
mclk-sclk-ratio = <4>;
|
||||
sound-name-prefix = "ES7210_ADC1";
|
||||
MVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_adc_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
PVDD-supply = <&soc_dvdd18_aon_reg>;
|
||||
};
|
||||
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&pcal6408ahk_b 3 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&audio_i2c1 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa13>,
|
||||
<&pinctrl_audiopa16>,
|
||||
<&pinctrl_audio_i2c1>;
|
||||
|
||||
pcal6408ahk_b: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -717,6 +815,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -759,7 +858,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -834,22 +933,151 @@
|
||||
* Format: <pin_id mux_node config>
|
||||
*/
|
||||
|
||||
pinctrl_audiopa1: audiopa1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_PA1 0x3 0x72
|
||||
>;
|
||||
pinctrl_audiopa0: audiopa0 {
|
||||
thead,pins = < FM_AUDIO_PA0 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
|
||||
pinctrl_audiopa2: audiopa2_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_PA2 0x0 0x72
|
||||
>;
|
||||
pinctrl_audiopa1: audiopa1 {
|
||||
thead,pins = < FM_AUDIO_PA1 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa2: audiopa2 {
|
||||
thead,pins = < FM_AUDIO_PA2 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa3: audiopa3 {
|
||||
thead,pins = < FM_AUDIO_PA3 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa4: audiopa4 {
|
||||
thead,pins = < FM_AUDIO_PA4 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa5: audiopa5 {
|
||||
thead,pins = < FM_AUDIO_PA5 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa6: audiopa6 {
|
||||
thead,pins = < FM_AUDIO_PA6 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa7: audiopa7 {
|
||||
thead,pins = < FM_AUDIO_PA7 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa8: audiopa8 {
|
||||
thead,pins = < FM_AUDIO_PA8 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa9: audiopa9 {
|
||||
thead,pins = < FM_AUDIO_PA9 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa10: audiopa10 {
|
||||
thead,pins = < FM_AUDIO_PA10 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa11: audiopa11 {
|
||||
thead,pins = < FM_AUDIO_PA11 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa12: audiopa12 {
|
||||
thead,pins = < FM_AUDIO_PA12 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa13: audiopa13 {
|
||||
thead,pins = < FM_AUDIO_PA13 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa14: audiopa14 {
|
||||
thead,pins = < FM_AUDIO_PA14 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa15: audiopa15 {
|
||||
thead,pins = < FM_AUDIO_PA15 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa16: audiopa16 {
|
||||
thead,pins = < FM_AUDIO_PA16 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa17: audiopa17 {
|
||||
thead,pins = < FM_AUDIO_PA17 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
|
||||
pinctrl_volume: volume_grp {
|
||||
thead,pins = <
|
||||
FM_CPU_JTG_TDI 0x3 0x208
|
||||
FM_CPU_JTG_TDO 0x3 0x208
|
||||
FM_CPU_JTG_TDI 0x3 0x238
|
||||
FM_CPU_JTG_TDO 0x3 0x238
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&padctrl_audiosys {
|
||||
|
||||
status = "okay";
|
||||
|
||||
light-audio-padctrl {
|
||||
/*
|
||||
* Pin Configuration Node:
|
||||
* Format: <pin_id mux_node config>
|
||||
*/
|
||||
|
||||
pinctrl_audio_i2c0: audio_i2c0_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA6 LIGHT_PIN_FUNC_0 0x004
|
||||
FM_AUDIO_IO_PA7 LIGHT_PIN_FUNC_0 0x004
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2c1: audio_i2c1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA13 LIGHT_PIN_FUNC_1 0x004
|
||||
FM_AUDIO_IO_PA16 LIGHT_PIN_FUNC_3 0x004
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s0: audio_i2s0_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA9 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA10 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA11 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA12 LIGHT_PIN_FUNC_0 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s1: audio_i2s1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA14 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA15 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA17 LIGHT_PIN_FUNC_0 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_bus: audio_i2s_8ch_bus_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA2 LIGHT_PIN_FUNC_3 0x008
|
||||
FM_AUDIO_IO_PA3 LIGHT_PIN_FUNC_3 0x008
|
||||
FM_AUDIO_IO_PA8 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_sd0: audio_i2s_8ch_sd0_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA4 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_sd1: audio_i2s_8ch_sd1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA5 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_sd2: audio_i2s_8ch_sd2_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA0 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_sd3: audio_i2s_8ch_sd3_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA1 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_tdm: audio_tdm_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA27 LIGHT_PIN_FUNC_1 0x007
|
||||
FM_AUDIO_IO_PA28 LIGHT_PIN_FUNC_1 0x007
|
||||
FM_AUDIO_IO_PA29 LIGHT_PIN_FUNC_1 0x000
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_spdif0: audio_spdif0_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA21 LIGHT_PIN_FUNC_1 0x000
|
||||
FM_AUDIO_IO_PA22 LIGHT_PIN_FUNC_1 0x007
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_spdif1: audio_spdif1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA23 LIGHT_PIN_FUNC_1 0x007
|
||||
FM_AUDIO_IO_PA24 LIGHT_PIN_FUNC_1 0x000
|
||||
>;
|
||||
};
|
||||
};
|
||||
@@ -989,6 +1217,24 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
&vvcam_sensor1 {
|
||||
sensor_name = "OV5693";
|
||||
sensor_regulators = "DOVDD18_RGB", "DVDD12_RGB", "AVDD28_RGB";
|
||||
sensor_regulator_voltage_uV = <1800000 1200000 2800000>;
|
||||
sensor_regulator_timing_us = <70 50 20>;
|
||||
sensor_rst = <&gpio1_porta 16 0>;
|
||||
sensor_pdn_delay_us = <4000>; //powerdown pin / shutdown pin actived till I2C ready
|
||||
DOVDD18_RGB-supply = <&soc_dovdd18_rgb_reg>;
|
||||
DVDD12_RGB-supply = <&soc_dvdd12_rgb_reg>;
|
||||
AVDD28_RGB-supply = <&soc_avdd28_rgb_reg>;
|
||||
i2c_reg_width = /bits/ 8 <2>;
|
||||
i2c_data_width = /bits/ 8 <1>;
|
||||
i2c_addr = /bits/ 8 <0x36>;
|
||||
i2c_bus = /bits/ 8 <3>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vvcam_sensor2 {
|
||||
sensor_name = "GC5035";
|
||||
sensor_regulators = "DOVDD18_SCAN", "DVDD12_SCAN", "AVDD28_SCAN";
|
||||
@@ -1073,6 +1319,22 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vvcam_sensor7 {
|
||||
sensor_name = "IMX334";
|
||||
sensor_regulators = "DOVDD18_RGB", "DVDD12_RGB", "AVDD28_RGB";
|
||||
sensor_regulator_timing_us = <70 50 20>;
|
||||
sensor_rst = <&gpio1_porta 16 0>;
|
||||
sensor_pdn_delay_us = <1000>; //powerdown pin / shutdown pin actived till I2C ready
|
||||
DOVDD18_RGB-supply = <&soc_dovdd18_rgb_reg>;
|
||||
DVDD12_RGB-supply = <&soc_dvdd12_rgb_reg>;
|
||||
AVDD28_RGB-supply = <&soc_avdd28_rgb_reg>;
|
||||
i2c_reg_width = /bits/ 8 <2>;
|
||||
i2c_data_width = /bits/ 8 <1>;
|
||||
i2c_addr = /bits/ 8 <0x1a>;
|
||||
i2c_bus = /bits/ 8 <3>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video0{
|
||||
vi_mem_pool_region = <2>; // vi_mem: framebuffer, region[2]
|
||||
channel0 {
|
||||
@@ -1279,13 +1541,20 @@
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_1600x1200_RAW10_LINER";
|
||||
};
|
||||
sensor2 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <7>; //imx334
|
||||
csi_idx = <0>; //<0>=CSI2
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_3840x2180_RAW12_LINER";
|
||||
};
|
||||
isp {
|
||||
subdev_name = "isp";
|
||||
idx = <1>;
|
||||
path_type = "ISP_MI_PATH_MP";
|
||||
output {
|
||||
max_width = <1920>;
|
||||
max_height = <1088>;
|
||||
max_width = <3840>;
|
||||
max_height = <2180>;
|
||||
bit_per_pixel = <16>;
|
||||
frame_count = <3>;
|
||||
};
|
||||
@@ -2138,6 +2407,44 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa9>,
|
||||
<&pinctrl_audiopa10>,
|
||||
<&pinctrl_audiopa11>,
|
||||
<&pinctrl_audiopa12>,
|
||||
<&pinctrl_audio_i2s0>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa4>,
|
||||
<&pinctrl_audio_i2s_8ch_sd0>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa5>,
|
||||
<&pinctrl_audio_i2s_8ch_sd1>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa0>,
|
||||
<&pinctrl_audio_i2s_8ch_sd2>,
|
||||
<&pinctrl_audiopa2>,
|
||||
<&pinctrl_audiopa3>,
|
||||
<&pinctrl_audiopa8>,
|
||||
<&pinctrl_audio_i2s_8ch_bus>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa1>,
|
||||
<&pinctrl_audio_i2s_8ch_sd3>;
|
||||
};
|
||||
|
||||
|
||||
&cpus {
|
||||
c910_0: cpu@0 {
|
||||
operating-points = <
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -194,9 +194,10 @@
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
status = "okay";
|
||||
sound-name-prefix = "DUMMY";
|
||||
};
|
||||
|
||||
reg_vref_1v8: regulator-adc-verf {
|
||||
@@ -581,24 +582,31 @@
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
};
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
status = "okay";
|
||||
};
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
@@ -731,6 +739,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -773,7 +782,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -2091,6 +2100,11 @@
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
@@ -2105,7 +2119,7 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
@@ -2118,7 +2132,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -2135,7 +2149,7 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -194,9 +194,10 @@
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
status = "okay";
|
||||
sound-name-prefix = "DUMMY";
|
||||
};
|
||||
|
||||
reg_vref_1v8: regulator-adc-verf {
|
||||
@@ -238,7 +239,8 @@
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&pinctrl_volume>;
|
||||
pinctrl-0 = <&pinctrl_volume_up
|
||||
&pinctrl_volume_down>;
|
||||
pinctrl-names = "default";
|
||||
key-volumedown {
|
||||
label = "Volume Down Key";
|
||||
@@ -588,24 +590,31 @@
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
};
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
status = "okay";
|
||||
};
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
@@ -738,6 +747,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -780,7 +790,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -797,6 +807,12 @@
|
||||
FM_GPIO3_2 0x1 0x208 /* pwm0 */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_volume_up: volume_up_grp {
|
||||
thead,pins = <
|
||||
FM_GPIO2_25 0x0 0x238
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -842,9 +858,9 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_volume: volume_grp {
|
||||
pinctrl_volume_down: volume_down_grp {
|
||||
thead,pins = <
|
||||
FM_CLK_OUT_2 0x3 0x208
|
||||
FM_CLK_OUT_2 0x3 0x238
|
||||
>;
|
||||
};
|
||||
};
|
||||
@@ -2265,6 +2281,11 @@
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
@@ -2279,7 +2300,7 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
@@ -2292,7 +2313,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -2309,7 +2330,7 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
2515
arch/riscv/boot/dts/thead/light-b-audio-hdmi.dts
Normal file
2515
arch/riscv/boot/dts/thead/light-b-audio-hdmi.dts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x40000000>;
|
||||
reg = <0x0 0x200000 0x0 0x3fe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-b-product.dts"
|
||||
#include "light-b-audio-hdmi.dts"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -180,7 +180,8 @@
|
||||
compatible = "thead,light-mbox-client";
|
||||
mbox-names = "906";
|
||||
mboxes = <&mbox_910t 2 0>;
|
||||
status = "disabled";
|
||||
audio-mbox-regmap = <&audio_mbox>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
lightsound: lightsound@1 {
|
||||
@@ -193,10 +194,25 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
light_rpmsg: light_rpmsg {
|
||||
compatible = "light,rpmsg-bus", "simple-bus";
|
||||
memory-region = <&rpmsgmem>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
rpmsg: rpmsg{
|
||||
vdev-nums = <1>;
|
||||
reg = <0x0 0x1E000000 0 0x10000>;
|
||||
compatible = "light,light-rpmsg";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
status = "okay";
|
||||
sound-name-prefix = "DUMMY";
|
||||
};
|
||||
|
||||
reg_vref_1v8: regulator-adc-verf {
|
||||
@@ -270,6 +286,8 @@
|
||||
regulator-name = "soc_aud_3v3_en";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_3v3_en>;
|
||||
gpio = <&ao_gpio_porta 7 1>;
|
||||
enable-active-high;
|
||||
regulator-always-on;
|
||||
@@ -280,6 +298,8 @@
|
||||
regulator-name = "soc_aud_1v8_en";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_1v8_en>;
|
||||
gpio = <&ao_gpio_porta 8 1>;
|
||||
enable-active-high;
|
||||
regulator-always-on;
|
||||
@@ -569,7 +589,14 @@
|
||||
reg = <0x0 0x17000000 0 0x02000000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
audio_mem: memory@32000000 {
|
||||
reg = <0x0 0x32000000 0x0 0x6400000>;
|
||||
no-map;
|
||||
};
|
||||
rpmsgmem: memory@1E000000 {
|
||||
reg = <0x0 0x1E000000 0x0 0x10000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -600,23 +627,43 @@
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa6>,
|
||||
<&pinctrl_audiopa7>,
|
||||
<&pinctrl_audio_i2c0>;
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
};
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
mclk-sclk-ratio = <4>;
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
work-mode = "ES7210_NORMAL_I2S";
|
||||
channels-max = <2>;
|
||||
mclk-sclk-ratio = <4>;
|
||||
sound-name-prefix = "ES7210_ADC0";
|
||||
MVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
pingctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_pa_rst0>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
@@ -750,6 +797,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -792,7 +840,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -866,27 +914,103 @@
|
||||
* Format: <pin_id mux_node config>
|
||||
*/
|
||||
|
||||
pinctrl_audiopa1: audiopa1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_PA1 0x3 0x72
|
||||
>;
|
||||
pinctrl_audiopa0: audiopa0 {
|
||||
thead,pins = < FM_AUDIO_PA0 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
|
||||
pinctrl_audiopa2: audiopa2_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_PA2 0x0 0x72
|
||||
>;
|
||||
pinctrl_audiopa1: audiopa1 {
|
||||
thead,pins = < FM_AUDIO_PA1 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa2: audiopa2 {
|
||||
thead,pins = < FM_AUDIO_PA2 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa3: audiopa3 {
|
||||
thead,pins = < FM_AUDIO_PA3 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa6: audiopa6 {
|
||||
thead,pins = < FM_AUDIO_PA6 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa7: audiopa7 {
|
||||
thead,pins = < FM_AUDIO_PA7 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa8: audiopa8 {
|
||||
thead,pins = < FM_AUDIO_PA8 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audio_pa_rst0: audio_pa_rst0 {
|
||||
thead,pins = < FM_AUDIO_PA9 LIGHT_PIN_FUNC_3 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa13: audiopa13 {
|
||||
thead,pins = < FM_AUDIO_PA13 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa14: audiopa14 {
|
||||
thead,pins = < FM_AUDIO_PA14 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa15: audiopa15 {
|
||||
thead,pins = < FM_AUDIO_PA15 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa17: audiopa17 {
|
||||
thead,pins = < FM_AUDIO_PA17 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audio_3v3_en: audio_3v3_en {
|
||||
thead,pins = < FM_AOGPIO_7 LIGHT_PIN_FUNC_3 0x008 >;
|
||||
};
|
||||
pinctrl_audio_1v8_en: audio_1v8_en {
|
||||
thead,pins = < FM_AOGPIO_8 LIGHT_PIN_FUNC_3 0x008 >;
|
||||
};
|
||||
|
||||
pinctrl_volume: volume_grp {
|
||||
thead,pins = <
|
||||
FM_AOGPIO_11 0x0 0x208
|
||||
FM_AOGPIO_10 0x3 0x208
|
||||
FM_AOGPIO_11 0x0 0x238
|
||||
FM_AOGPIO_10 0x3 0x238
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&padctrl_audiosys {
|
||||
|
||||
status = "okay";
|
||||
|
||||
light-audio-padctrl {
|
||||
/*
|
||||
* Pin Configuration Node:
|
||||
* Format: <pin_id mux_node config>
|
||||
*/
|
||||
|
||||
pinctrl_audio_i2c0: audio_i2c0_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA6 LIGHT_PIN_FUNC_0 0x004
|
||||
FM_AUDIO_IO_PA7 LIGHT_PIN_FUNC_0 0x004
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s1: audio_i2s1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA13 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA14 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA15 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA17 LIGHT_PIN_FUNC_0 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_bus: audio_i2s_8ch_bus_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA2 LIGHT_PIN_FUNC_3 0x008
|
||||
FM_AUDIO_IO_PA3 LIGHT_PIN_FUNC_3 0x008
|
||||
FM_AUDIO_IO_PA8 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_sd2: audio_i2s_8ch_sd2_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA0 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s_8ch_sd3: audio_i2s_8ch_sd3_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA1 LIGHT_PIN_FUNC_3 0x008
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&i2c0 {
|
||||
clock-frequency = <400000>;
|
||||
status = "okay";
|
||||
@@ -1000,30 +1124,21 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/*
|
||||
&vvcam_sensor0 {
|
||||
sensor_name = "IMX334";
|
||||
sensor_regulators = "DOVDD18_RGB", "DVDD12_RGB", "AVDD28_RGB";
|
||||
sensor_regulator_timing_us = <70 50 20>;
|
||||
sensor_rst = <&gpio1_porta 16 0>;
|
||||
sensor_pdn_delay_us = <1000>; //powerdown pin / shutdown pin actived till I2C ready
|
||||
DOVDD18_RGB-supply = <&soc_dovdd18_rgb_reg>;
|
||||
DVDD12_RGB-supply = <&soc_dvdd12_rgb_reg>;
|
||||
AVDD28_RGB-supply = <&soc_avdd28_rgb_reg>;
|
||||
&vvcam_sensor1 {
|
||||
sensor_name = "OV5693";
|
||||
sensor_regulators = "DOVDD18_RGB", "DVDD12_RGB", "AVDD28_RGB";
|
||||
sensor_regulator_voltage_uV = <1800000 1200000 2800000>;
|
||||
sensor_regulator_timing_us = <70 50 20>;
|
||||
sensor_rst = <&gpio1_porta 16 0>;
|
||||
sensor_pdn_delay_us = <4000>; //powerdown pin / shutdown pin actived till I2C ready
|
||||
DOVDD18_RGB-supply = <&soc_dovdd18_rgb_reg>;
|
||||
DVDD12_RGB-supply = <&soc_dvdd12_rgb_reg>;
|
||||
AVDD28_RGB-supply = <&soc_avdd28_rgb_reg>;
|
||||
i2c_reg_width = /bits/ 8 <2>;
|
||||
i2c_data_width = /bits/ 8 <1>;
|
||||
i2c_addr = /bits/ 8 <0x1a>;
|
||||
i2c_bus = /bits/ 8 <3>;
|
||||
status = "okay";
|
||||
};
|
||||
*/
|
||||
|
||||
&vvcam_sensor1 {
|
||||
sensor_name = "OV5693";
|
||||
i2c_bus = /bits/ 8 <3>;
|
||||
i2c_reg_width = /bits/ 8 <1>;
|
||||
i2c_data_width = /bits/ 8 <1>;
|
||||
status = "disabled";
|
||||
i2c_addr = /bits/ 8 <0x36>;
|
||||
i2c_bus = /bits/ 8 <3>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vvcam_sensor2 {
|
||||
@@ -1108,6 +1223,22 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vvcam_sensor7 {
|
||||
sensor_name = "IMX334";
|
||||
sensor_regulators = "DOVDD18_RGB", "DVDD12_RGB", "AVDD28_RGB";
|
||||
sensor_regulator_timing_us = <70 50 20>;
|
||||
sensor_rst = <&gpio1_porta 16 0>;
|
||||
sensor_pdn_delay_us = <1000>; //powerdown pin / shutdown pin actived till I2C ready
|
||||
DOVDD18_RGB-supply = <&soc_dovdd18_rgb_reg>;
|
||||
DVDD12_RGB-supply = <&soc_dvdd12_rgb_reg>;
|
||||
AVDD28_RGB-supply = <&soc_avdd28_rgb_reg>;
|
||||
i2c_reg_width = /bits/ 8 <2>;
|
||||
i2c_data_width = /bits/ 8 <1>;
|
||||
i2c_addr = /bits/ 8 <0x1a>;
|
||||
i2c_bus = /bits/ 8 <3>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video0{
|
||||
vi_mem_pool_region = <2>; // vi_mem: framebuffer, region[2]
|
||||
channel0 {
|
||||
@@ -1314,13 +1445,20 @@
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_1600x1200_RAW10_LINER";
|
||||
};
|
||||
sensor2 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <7>; //imx334
|
||||
csi_idx = <0>; //<0>=CSI2
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_3840x2180_RAW12_LINER";
|
||||
};
|
||||
isp {
|
||||
subdev_name = "isp";
|
||||
idx = <1>;
|
||||
path_type = "ISP_MI_PATH_MP";
|
||||
output {
|
||||
max_width = <1920>;
|
||||
max_height = <1088>;
|
||||
max_width = <3840>;
|
||||
max_height = <2180>;
|
||||
bit_per_pixel = <16>;
|
||||
frame_count = <3>;
|
||||
};
|
||||
@@ -2313,6 +2451,11 @@
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
@@ -2327,7 +2470,7 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
@@ -2340,7 +2483,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -2355,10 +2498,29 @@
|
||||
|
||||
&i2s1 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa13>,
|
||||
<&pinctrl_audiopa14>,
|
||||
<&pinctrl_audiopa15>,
|
||||
<&pinctrl_audiopa17>,
|
||||
<&pinctrl_audio_i2s1>;
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa0>,
|
||||
<&pinctrl_audio_i2s_8ch_sd2>,
|
||||
<&pinctrl_audiopa2>,
|
||||
<&pinctrl_audiopa3>,
|
||||
<&pinctrl_audiopa8>,
|
||||
<&pinctrl_audio_i2s_8ch_bus>;
|
||||
};
|
||||
|
||||
&i2s_8ch_sd3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa1>,
|
||||
<&pinctrl_audio_i2s_8ch_sd3>;
|
||||
};
|
||||
|
||||
&cpus {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -194,9 +194,10 @@
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
status = "okay";
|
||||
sound-name-prefix = "DUMMY";
|
||||
};
|
||||
|
||||
reg_vref_1v8: regulator-adc-verf {
|
||||
@@ -569,24 +570,34 @@
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
};
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
MVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
status = "okay";
|
||||
};
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
@@ -719,6 +730,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -761,7 +773,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -2249,6 +2261,11 @@
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
simple-audio-card,widgets = "Speaker", "Speaker";
|
||||
simple-audio-card,routing =
|
||||
"Speaker", "AW87519 VO",
|
||||
"AW87519 IN", "ES8156 ROUT";
|
||||
simple-audio-card,aux-devs = <&audio_aw87519_pa>;
|
||||
simple-audio-card,dai-link@0 { /* I2S - AUDIO SYS CODEC 8156*/
|
||||
reg = <0>;
|
||||
format = "i2s";
|
||||
@@ -2263,7 +2280,7 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s3 0>;
|
||||
sound-dai = <&i2s_8ch_sd2 2>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
@@ -2276,7 +2293,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -2293,7 +2310,7 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
&i2s_8ch_sd2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -191,8 +191,9 @@
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
sound-name-prefix = "DUMMY";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -341,18 +342,23 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&ao_gpio4_porta 9 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
@@ -488,6 +494,7 @@
|
||||
no-mmc;
|
||||
non-removable;
|
||||
io_fixed_1v8;
|
||||
rxclk-sample-delay = <80>;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
@@ -530,7 +537,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -862,22 +869,6 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&khvhost {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
entry-cnt = <4>;
|
||||
control-reg = <0xff 0xff015004>;
|
||||
control-val = <0x1c>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc 0x7ce>;
|
||||
};
|
||||
|
||||
clint0: clint@ffdc000000 {
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
entry-cnt = <4>;
|
||||
control-reg = <0xff 0xff015004>;
|
||||
control-val = <0x1c>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc 0x7ce>;
|
||||
};
|
||||
|
||||
clint0: clint@ffdc000000 {
|
||||
@@ -1193,8 +1193,7 @@
|
||||
|
||||
emmc: sdhci@ffe7080000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe7080000 0x0 0x10000
|
||||
0xff 0xef014060 0x0 0x4>;
|
||||
reg = <0xff 0xe7080000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <62>;
|
||||
interrupt-names = "sdhciirq";
|
||||
@@ -1204,8 +1203,7 @@
|
||||
|
||||
sdhci0: sd@ffe7090000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe7090000 0x0 0x10000
|
||||
0xff 0xef014064 0x0 0x4>;
|
||||
reg = <0xff 0xe7090000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <64>;
|
||||
interrupt-names = "sdhci0irq";
|
||||
@@ -1215,8 +1213,7 @@
|
||||
|
||||
sdhci1: sd@ffe70a0000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe70a0000 0x0 0x10000
|
||||
0xff 0xef014064 0x0 0x4>;
|
||||
reg = <0xff 0xe70a0000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <71>;
|
||||
interrupt-names = "sdhci1irq";
|
||||
@@ -1302,7 +1299,7 @@
|
||||
compatible = "light,light-i2s";
|
||||
reg = <0xff 0xe7034000 0x0 0x4000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_i2s0>;
|
||||
pinctrl-0 = <&pinctrl_light_i2s0>;
|
||||
light,mode = "i2s-master";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <70>;
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
sound-dai = <&light_i2s 0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -172,7 +172,8 @@
|
||||
compatible = "thead,light-mbox-client";
|
||||
mbox-names = "906";
|
||||
mboxes = <&mbox_910t 2 0>;
|
||||
status = "disabled";
|
||||
audio-mbox-regmap = <&audio_mbox>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
lightsound: lightsound@1 {
|
||||
@@ -185,10 +186,32 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
light_rpmsg: light_rpmsg {
|
||||
compatible = "light,rpmsg-bus", "simple-bus";
|
||||
memory-region = <&rpmsgmem>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
rpmsg: rpmsg{
|
||||
vdev-nums = <1>;
|
||||
reg = <0x0 0x1E000000 0 0x10000>;
|
||||
compatible = "light,light-rpmsg";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
dummy_codec: dummy_codec {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "linux,bt-sco";
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "thead,light-dummy-pcm";
|
||||
status = "okay";
|
||||
sound-name-prefix = "DUMMY";
|
||||
};
|
||||
|
||||
fan: pwm-fan {
|
||||
compatible = "pwm-fan";
|
||||
#cooling-cells = <2>;
|
||||
pwms = <&pwm 1 10000000 0>;
|
||||
cooling-levels = <0 64 192 255>;
|
||||
};
|
||||
|
||||
reg_vref_1v8: regulator-adc-verf {
|
||||
@@ -196,7 +219,7 @@
|
||||
regulator-name = "vref-1v8";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
status = "okay";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
reg_tp_pwr_en: regulator-pwr-en {
|
||||
@@ -281,7 +304,6 @@
|
||||
regulator-name = "soc_aud_3v3_en";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&pcal6408ahk_a 1 1>;
|
||||
enable-active-high;
|
||||
regulator-always-on;
|
||||
};
|
||||
@@ -291,7 +313,6 @@
|
||||
regulator-name = "soc_aud_1v8_en";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
gpio = <&pcal6408ahk_a 0 1>;
|
||||
enable-active-high;
|
||||
regulator-always-on;
|
||||
};
|
||||
@@ -361,6 +382,7 @@
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
gpio = <&pcal6408ahk_b 1 1>;
|
||||
regulator-always-on;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
@@ -370,6 +392,7 @@
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
gpio = <&pcal6408ahk_b 2 1>;
|
||||
regulator-always-on;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
@@ -379,6 +402,7 @@
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
gpio = <&pcal6408ahk_b 0 1>;
|
||||
regulator-always-on;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
@@ -558,6 +582,48 @@
|
||||
};
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu-thermal-zone {
|
||||
trips {
|
||||
fan_config0: fan-trip0 {
|
||||
temperature = <40000>;
|
||||
hysteresis = <5000>;
|
||||
type = "active";
|
||||
};
|
||||
|
||||
fan_config1: fan-trip1 {
|
||||
temperature = <50000>;
|
||||
hysteresis = <5000>;
|
||||
type = "active";
|
||||
};
|
||||
|
||||
fan_config2: fan-trip2 {
|
||||
temperature = <60000>;
|
||||
hysteresis = <5000>;
|
||||
type = "active";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
fan-on {
|
||||
trip = <&fan_config0>;
|
||||
cooling-device =
|
||||
<&fan 1 1>;
|
||||
};
|
||||
fan-faster {
|
||||
trip = <&fan_config1>;
|
||||
cooling-device =
|
||||
<&fan 2 2>;
|
||||
};
|
||||
fan-full {
|
||||
trip = <&fan_config2>;
|
||||
cooling-device =
|
||||
<&fan 3 3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&resmem {
|
||||
@@ -594,6 +660,14 @@
|
||||
reg = <0x0 0x17000000 0 0x02000000>;
|
||||
no-map;
|
||||
};
|
||||
audio_mem: memory@32000000 {
|
||||
reg = <0x0 0x32000000 0x0 0x6400000>;
|
||||
no-map;
|
||||
};
|
||||
rpmsgmem: memory@1E000000 {
|
||||
reg = <0x0 0x1E000000 0x0 0x10000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -606,44 +680,53 @@
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa29>,
|
||||
<&pinctrl_audiopa30>,
|
||||
<&pinctrl_audio_i2c0>;
|
||||
|
||||
es8156_audio_codec: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
MVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
AVDD-supply = <&soc_aud_3v3_en_reg>;
|
||||
DVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
PVDD-supply = <&soc_aud_1v8_en_reg>;
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&pcal6408ahk_a 2 0x1>;
|
||||
status = "okay";
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio_aw87519_pa1@5b {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x5b>;
|
||||
reset-gpio = <&pcal6408ahk_a 3 0x1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcal6408ahk_a: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
&audio_i2c1 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
pinctrl-0 = <&pinctrl_audiopa6>,
|
||||
<&pinctrl_audiopa7>,
|
||||
<&pinctrl_audio_i2c1>;
|
||||
|
||||
es8156_audio_codec_1: es8156@8 {
|
||||
#sound-dai-cells = <0>;
|
||||
@@ -662,14 +745,12 @@
|
||||
audio_aw87519_pa2@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&pcal6408ahk_a 4 0x1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio_aw87519_pa3@5b {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x5b>;
|
||||
reset-gpio = <&pcal6408ahk_a 5 0x1>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
@@ -706,7 +787,7 @@
|
||||
num-cs = <1>;
|
||||
cs-gpios = <&gpio2_porta 3 0>;
|
||||
rx-sample-dly = <4>;
|
||||
status = "okay";
|
||||
status = "disabled";
|
||||
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
@@ -841,7 +922,7 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audio_i2s0: i2s0grp {
|
||||
pinctrl_light_i2s0: i2s0grp {
|
||||
thead,pins = <
|
||||
FM_QSPI0_SCLK 0x2 0x208
|
||||
FM_QSPI0_CSN0 0x2 0x238
|
||||
@@ -929,17 +1010,94 @@
|
||||
FM_AUDIO_PA2 0x0 0x72
|
||||
>;
|
||||
};
|
||||
pinctrl_audiopa6: audiopa6 {
|
||||
thead,pins = < FM_AUDIO_PA6 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa7: audiopa7 {
|
||||
thead,pins = < FM_AUDIO_PA7 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa14: audiopa14 {
|
||||
thead,pins = < FM_AUDIO_PA14 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa15: audiopa15 {
|
||||
thead,pins = < FM_AUDIO_PA15 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa16: audiopa16 {
|
||||
thead,pins = < FM_AUDIO_PA16 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa17: audiopa17 {
|
||||
thead,pins = < FM_AUDIO_PA17 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa18: audiopa18 {
|
||||
thead,pins = < FM_AOGPIO_7 LIGHT_PIN_FUNC_1 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa19: audiopa19 {
|
||||
thead,pins = < FM_AOGPIO_8 LIGHT_PIN_FUNC_1 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa21: audiopa21 {
|
||||
thead,pins = < FM_AOGPIO_10 LIGHT_PIN_FUNC_1 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa22: audiopa22 {
|
||||
thead,pins = < FM_AOGPIO_11 LIGHT_PIN_FUNC_1 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa29: audiopa29 {
|
||||
thead,pins = < FM_AUDIO_PA29 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
pinctrl_audiopa30: audiopa30 {
|
||||
thead,pins = < FM_AUDIO_PA30 LIGHT_PIN_FUNC_0 0x000 >;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
&padctrl_audiosys {
|
||||
|
||||
status = "okay";
|
||||
|
||||
light-audio-padctrl {
|
||||
/*
|
||||
* Pin Configuration Node:
|
||||
* Format: <pin_id mux_node config>
|
||||
*/
|
||||
|
||||
pinctrl_audio_i2c0: audio_i2c0_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA29 LIGHT_PIN_FUNC_2 0x004
|
||||
FM_AUDIO_IO_PA30 LIGHT_PIN_FUNC_2 0x004
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2c1: audio_i2c1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA6 LIGHT_PIN_FUNC_2 0x004
|
||||
FM_AUDIO_IO_PA7 LIGHT_PIN_FUNC_2 0x004
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s1: audio_i2s1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA14 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA15 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA16 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA17 LIGHT_PIN_FUNC_0 0x008
|
||||
>;
|
||||
};
|
||||
pinctrl_audio_i2s2: audio_i2s2_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA18 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA19 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA21 LIGHT_PIN_FUNC_0 0x008
|
||||
FM_AUDIO_IO_PA22 LIGHT_PIN_FUNC_0 0x008
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
clock-frequency = <400000>;
|
||||
status = "okay";
|
||||
|
||||
pcal6408ahk_b: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -950,8 +1108,8 @@
|
||||
status = "okay";
|
||||
|
||||
pcal6408ahk_c: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -967,8 +1125,8 @@
|
||||
status = "okay";
|
||||
|
||||
pcal6408ahk_d: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -1093,6 +1251,24 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vvcam_sensor3 {//cam3 csi0 modified
|
||||
sensor_name = "OV5693";
|
||||
sensor_regulators = "soc_dovdd18_rgb", "soc_dvdd12_rgb", "soc_avdd28_rgb";
|
||||
sensor_regulator_voltage_uV = <1800000 1200000 2800000>;
|
||||
sensor_regulator_timing_us = <70 50 20>;
|
||||
sensor_pdn = <&gpio1_porta 28 0>; //powerdown pin / shutdown pin
|
||||
sensor_rst = <&pcal6408ahk_c 1 0>;
|
||||
sensor_pdn_delay_us = <4000>; //powerdown pin / shutdown pin actived till I2C ready
|
||||
DOVDD18_RGB-supply = <&soc_dovdd18_rgb_reg>;
|
||||
DVDD12_RGB-supply = <&soc_dvdd12_rgb_reg>;
|
||||
AVDD28_RGB-supply = <&soc_avdd28_rgb_reg>;
|
||||
i2c_reg_width = /bits/ 8 <2>;
|
||||
i2c_data_width = /bits/ 8 <1>;
|
||||
i2c_addr = /bits/ 8 <0x36>;
|
||||
i2c_bus = /bits/ 8 <0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&video2 {
|
||||
vi_mem_pool_region = <0>; // vi_mem: framebuffer, region[0]
|
||||
status = "okay";
|
||||
@@ -1101,11 +1277,18 @@
|
||||
status = "okay";
|
||||
sensor0 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <0>;
|
||||
idx = <0>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <1>;
|
||||
path_type = "SENSOR_2592x1944_LINER";
|
||||
};
|
||||
dma {
|
||||
subdev_name = "vipre";
|
||||
idx = <0>;
|
||||
@@ -1116,8 +1299,8 @@
|
||||
idx = <1>;
|
||||
path_type = "ISP_MI_PATH_MP";
|
||||
output {
|
||||
max_width = <1920>;
|
||||
max_height = <1088>;
|
||||
max_width = <2600>;
|
||||
max_height = <2000>;
|
||||
bit_per_pixel = <12>;
|
||||
frame_count = <3>;
|
||||
};
|
||||
@@ -1138,6 +1321,13 @@
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <1>;
|
||||
path_type = "SENSOR_2592x1944_LINER";
|
||||
};
|
||||
dma {
|
||||
subdev_name = "vipre";
|
||||
idx = <0>;
|
||||
@@ -1275,15 +1465,22 @@
|
||||
status = "okay";
|
||||
sensor0 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <2>;
|
||||
csi_idx = <1>; //csi_b
|
||||
idx = <0>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_1080X1280_30FPS_RAW10_LINER";
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <1>;
|
||||
path_type = "SENSOR_2592x1944_LINER";
|
||||
};
|
||||
dma {
|
||||
subdev_name = "vipre";
|
||||
idx = <0>;
|
||||
path_type = "VIPRE_CSI1_DDR";
|
||||
path_type = "VIPRE_CSI0_DDR";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1425,12 +1622,22 @@
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&i2s1 1>;
|
||||
sound-dai = <&i2s1 0>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_audio_codec>;
|
||||
};
|
||||
};
|
||||
simple-audio-card,dai-link@2 { /* I2S - HDMI*/
|
||||
reg = <2>;
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&light_i2s {
|
||||
@@ -1444,14 +1651,29 @@
|
||||
&i2s1 {
|
||||
status = "okay";
|
||||
dmas = <&dmac2 11>, <&dmac2 10>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa14>,
|
||||
<&pinctrl_audiopa15>,
|
||||
<&pinctrl_audiopa16>,
|
||||
<&pinctrl_audiopa17>,
|
||||
<&pinctrl_audio_i2s1>;
|
||||
};
|
||||
|
||||
&i2s2 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audiopa18>,
|
||||
<&pinctrl_audiopa19>,
|
||||
<&pinctrl_audiopa21>,
|
||||
<&pinctrl_audiopa22>,
|
||||
<&pinctrl_audio_i2s2>;
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
&usb_1 {
|
||||
hubswitch-gpio = <&ao_gpio_porta 4 0>;
|
||||
vbus-supply = <&soc_vbus_en_reg>;
|
||||
hub1v2-supply = <®_usb_hub_vdd1v2>;
|
||||
hub5v-supply = <®_usb_hub_vcc5v>;
|
||||
};
|
||||
|
||||
&cpus {
|
||||
@@ -1461,12 +1683,14 @@
|
||||
300000 650000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
};
|
||||
c910_1: cpu@1 {
|
||||
@@ -1475,12 +1699,14 @@
|
||||
300000 650000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
};
|
||||
c910_2: cpu@2 {
|
||||
@@ -1490,12 +1716,14 @@
|
||||
300000 650000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
};
|
||||
c910_3: cpu@3 {
|
||||
@@ -1505,12 +1733,14 @@
|
||||
300000 650000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
18
arch/riscv/boot/dts/thead/light-lpi4a-sec.dts
Normal file
18
arch/riscv/boot/dts/thead/light-lpi4a-sec.dts
Normal file
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-lpi4a.dts"
|
||||
|
||||
|
||||
&light_iopmp {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&qspi1 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -6,22 +6,15 @@
|
||||
#include "light-lpi4a-ref.dts"
|
||||
|
||||
/ {
|
||||
model = "T-HEAD Light Lichee Pi 4A configuration for 4GB DDR board";
|
||||
model = "T-HEAD Light Lichee Pi 4A configuration for 8GB DDR board";
|
||||
compatible = "thead,light-val", "thead,light-lpi4a", "thead,light";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x1 0x00000000>;
|
||||
reg = <0x0 0x200000 0x1 0xffe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
&cmamem {
|
||||
alloc-ranges = <0 0xe4000000 0 0x14000000>; // [0xE400_0000 ~ 0xF800_0000]
|
||||
};
|
||||
|
||||
&usb_1 {
|
||||
hubswitch-gpio = <&ao_gpio_porta 4 0>;
|
||||
vbus-supply = <&soc_vbus_en_reg>;
|
||||
hub1v2-supply = <®_usb_hub_vdd1v2>;
|
||||
hub5v-supply = <®_usb_hub_vcc5v>;
|
||||
alloc-ranges = <0 0xe4000000 0 0x14000000>; // [0x0E400_0000 ~ 0x0F800_0000]
|
||||
};
|
||||
|
||||
@@ -199,6 +199,12 @@
|
||||
csi_idx = <0xff>;
|
||||
path_type = "SENSOR_VGA_RAW10_LINER";
|
||||
};
|
||||
sensor2 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <0xff>; // invalid
|
||||
csi_idx = <0xff>;
|
||||
path_type = "SENSOR_VGA_RAW10_LINER";
|
||||
};
|
||||
dma {
|
||||
subdev_name = "vipre";
|
||||
idx = <0>;
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
#include <dt-bindings/pinctrl/light-fm-left-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-right-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-aon-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-audio-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-pinctrl-def.h>
|
||||
#include <dt-bindings/clock/light-fm-ap-clock.h>
|
||||
#include <dt-bindings/clock/light-vpsys.h>
|
||||
#include <dt-bindings/clock/light-vosys.h>
|
||||
#include <dt-bindings/clock/light-visys.h>
|
||||
#include <dt-bindings/clock/light-dspsys.h>
|
||||
#include <dt-bindings/clock/light-audiosys.h>
|
||||
#include <dt-bindings/firmware/thead/rsrc.h>
|
||||
#include <dt-bindings/soc/thead,light-iopmp.h>
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
@@ -34,7 +37,7 @@
|
||||
i2c3 = &i2c3;
|
||||
i2c4 = &i2c4;
|
||||
audio_i2c0 = &audio_i2c0;
|
||||
audio_i2c1 = &audio_i2c1;
|
||||
audio_i2c1 = &audio_i2c1;
|
||||
mmc0 = &emmc;
|
||||
mmc1 = &sdhci0;
|
||||
serial0 = &uart0;
|
||||
@@ -55,6 +58,7 @@
|
||||
vivcam4 = &vvcam_sensor4;
|
||||
vivcam5 = &vvcam_sensor5;
|
||||
vivcam6 = &vvcam_sensor6;
|
||||
vivcam7 = &vvcam_sensor7;
|
||||
|
||||
viv_video0 = &video0;
|
||||
viv_video1 = &video1;
|
||||
@@ -94,6 +98,11 @@
|
||||
};
|
||||
};
|
||||
|
||||
aon_iram: aon-iram@ffffef8000 {
|
||||
compatible = "syscon";
|
||||
reg = <0xff 0xffef8000 0x0 0x10000>;
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu-thermal-zone {
|
||||
polling-delay-passive = <250>;
|
||||
@@ -383,7 +392,7 @@
|
||||
entry-cnt = <4>;
|
||||
control-reg = <0xff 0xff015004>;
|
||||
control-val = <0x1c>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc>;
|
||||
csr-copy = <0x7f3 0x7c0 0x7c1 0x7c2 0x7c3 0x7c5 0x7cc 0x7ce>;
|
||||
};
|
||||
|
||||
clint0: clint@ffdc000000 {
|
||||
@@ -634,6 +643,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
audio_mbox: audio_mbox@0xffefc48000 {
|
||||
compatible = "thead,light-audio-mbox-reg", "syscon";
|
||||
reg = <0xff 0xefc48000 0x0 0x1000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nvmem_controller: efuse@ffff210000 {
|
||||
compatible = "thead,light-fm-efuse", "syscon";
|
||||
reg = <0xff 0xff210000 0x0 0x10000>;
|
||||
@@ -855,6 +870,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
padctrl_audiosys: padctrl-audiosys@ffcb01d000 {
|
||||
compatible = "thead,light-fm-audio-pinctrl";
|
||||
reg = <0xff 0xcb01d000 0x0 0x1000>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
timer4: timer@ffffc33000 {
|
||||
compatible = "snps,dw-apb-timer";
|
||||
reg = <0xff 0xffc33000 0x0 0x14>;
|
||||
@@ -1248,6 +1269,13 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
vpsys_rst: vpsys-reset-controller@ffecc30000 {
|
||||
compatible = "thead,light-vpsys-reset-src","syscon";
|
||||
reg = <0xff 0xecc30000 0x0 0x1000>;
|
||||
#reset-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
sys_reg: sys_reg@ffef010100 {
|
||||
compatible = "thead,light_sys_reg";
|
||||
reg = <0xff 0xef010100 0x0 0x100>;
|
||||
@@ -1301,7 +1329,7 @@
|
||||
65536 65536 65536 65536
|
||||
65536 65536 65536 65536
|
||||
65536 65536 65536 65536>;
|
||||
snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
|
||||
snps,priority = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; // <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
|
||||
snps,dma-masters = <1>;
|
||||
snps,data-width = <4>;
|
||||
snps,axi-max-burst-len = <16>;
|
||||
@@ -1354,8 +1382,7 @@
|
||||
|
||||
emmc: sdhci@ffe7080000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe7080000 0x0 0x10000
|
||||
0xff 0xef014060 0x0 0x4>;
|
||||
reg = <0xff 0xe7080000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <62>;
|
||||
interrupt-names = "sdhciirq";
|
||||
@@ -1365,8 +1392,7 @@
|
||||
|
||||
sdhci0: sd@ffe7090000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe7090000 0x0 0x10000
|
||||
0xff 0xef014064 0x0 0x4>;
|
||||
reg = <0xff 0xe7090000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <64>;
|
||||
interrupt-names = "sdhci0irq";
|
||||
@@ -1376,8 +1402,7 @@
|
||||
|
||||
sdhci1: sd@ffe70a0000 {
|
||||
compatible = "snps,dwcmshc-sdhci";
|
||||
reg = <0xff 0xe70a0000 0x0 0x10000
|
||||
0xff 0xef014064 0x0 0x4>;
|
||||
reg = <0xff 0xe70a0000 0x0 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <71>;
|
||||
interrupt-names = "sdhci1irq";
|
||||
@@ -1403,7 +1428,8 @@
|
||||
clock-names = "pclk", "aclk";
|
||||
vha_clk_rate = <1000000000>;
|
||||
ldo_vha-supply = <&npu>;
|
||||
dma-mask = <0xf 0xffffffff>;
|
||||
dma-mask = <0xff 0xffffffff>;
|
||||
resets = <&rst LIGHT_RESET_NPU>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -1432,6 +1458,7 @@
|
||||
clocks = <&vpsys_clk_gate LIGHT_VPSYS_FCE_ACLK>,
|
||||
<&vpsys_clk_gate LIGHT_VPSYS_FCE_PCLK>;
|
||||
clock-names = "aclk", "pclk";
|
||||
resets = <&vpsys_rst LIGHT_RESET_FCE>;
|
||||
dma-mask = <0xf 0xffffffff>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -1481,7 +1508,7 @@
|
||||
compatible = "light,light-i2s";
|
||||
reg = <0xff 0xe7034000 0x0 0x4000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audio_i2s0>;
|
||||
pinctrl-0 = <&pinctrl_light_i2s0>;
|
||||
light,mode = "i2s-master";
|
||||
light,sel = "ap_i2s";
|
||||
interrupt-parent = <&intc>;
|
||||
@@ -1506,7 +1533,7 @@
|
||||
light,sel = "i2s0";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <174>;
|
||||
dmas = <&dmac2 9>, <&dmac2 16>;
|
||||
dmas = <&dmac2 9>, <&dmac2 8>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
@@ -1555,16 +1582,17 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2s3: audio_i2s3@0xffcb017000 {
|
||||
i2s_8ch_sd0: audio_i2s_8ch_sd0@0xffcb017000 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "light,light-i2s";
|
||||
compatible = "light,light-i2s-8ch";
|
||||
reg = <0xff 0xcb017000 0x0 0x1000>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,sel = "i2s3";
|
||||
light,sel = "i2s_8ch_sd0";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <177>;
|
||||
dmas = <&dmac2 14>, <&dmac2 16>;
|
||||
dmas = <&dmac2 36>, <&dmac2 14>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
@@ -1573,6 +1601,267 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2s_8ch_sd1: audio_i2s_8ch_sd1@0xffcb017000 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "light,light-i2s-8ch";
|
||||
reg = <0xff 0xcb017000 0x0 0x1000>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,sel = "i2s_8ch_sd1";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <177>;
|
||||
dmas = <&dmac2 37>, <&dmac2 15>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2s_8ch_sd2: audio_i2s_8ch_sd2@0xffcb017000 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "light,light-i2s-8ch";
|
||||
reg = <0xff 0xcb017000 0x0 0x1000>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,sel = "i2s_8ch_sd2";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <177>;
|
||||
dmas = <&dmac2 38>, <&dmac2 16>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2s_8ch_sd3: audio_i2s_8ch_sd3@0xffcb017000 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "light,light-i2s-8ch";
|
||||
reg = <0xff 0xcb017000 0x0 0x1000>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,sel = "i2s_8ch_sd3";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <177>;
|
||||
dmas = <&dmac2 39>, <&dmac2 17>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot1: audio_tdm_slot1@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <1>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 28>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot2: audio_tdm_slot2@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <2>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 29>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot3: audio_tdm_slot3@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <3>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 30>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot4: audio_tdm_slot4@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <4>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 31>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot5: audio_tdm_slot5@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <5>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 32>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot6: audio_tdm_slot6@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <6>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 33>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot7: audio_tdm_slot7@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <7>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 34>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot8: audio_tdm_slot8@0xffcb012000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-tdm";
|
||||
reg = <0xff 0xcb012000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
light,mode = "i2s-master";
|
||||
light,tdm_slots = <8>;
|
||||
light,tdm_slot_num = <8>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <178>;
|
||||
dmas = <&dmac2 35>;
|
||||
dma-names = "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_TDM>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdif0: audio_spdif0@0xffcb018000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-spdif";
|
||||
reg = <0xff 0xcb018000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <179>;
|
||||
dmas = <&dmac2 25>, <&dmac2 24>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_SPDIF0>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spdif1: audio_spdif1@0xffcb019000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "light,light-spdif";
|
||||
reg = <0xff 0xcb019000 0x0 0x1000>;
|
||||
audio-pin-regmap = <&audio_ioctrl>;
|
||||
audio-cpr-regmap = <&audio_cpr>;
|
||||
pinctrl-names = "default";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <180>;
|
||||
dmas = <&dmac2 27>, <&dmac2 26>;
|
||||
dma-names = "tx", "rx";
|
||||
light,dma_maxburst = <4>;
|
||||
#dma-cells = <1>;
|
||||
clocks = <&audiosys_clk_gate LIGHT_CLKGEN_AUDIO_SPDIF1>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pvt: pvt@fffff4e000 {
|
||||
compatible = "moortec,mr75203";
|
||||
reg = <0xff 0xfff4e000 0x0 0x80>,
|
||||
@@ -1592,6 +1881,10 @@
|
||||
interrupts = <44>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac0 12>, <&dmac0 13>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x104>;
|
||||
ss_lcnt = /bits/ 16 <0xec>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
@@ -1611,6 +1904,10 @@
|
||||
interrupts = <45>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac0 14>, <&dmac0 15>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x104>;
|
||||
ss_lcnt = /bits/ 16 <0xec>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
@@ -1630,6 +1927,10 @@
|
||||
interrupts = <46>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac0 16>, <&dmac0 17>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x104>;
|
||||
ss_lcnt = /bits/ 16 <0xec>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
@@ -1651,6 +1952,10 @@
|
||||
interrupts = <47>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac0 18>, <&dmac0 19>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x104>;
|
||||
ss_lcnt = /bits/ 16 <0xec>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
@@ -1672,6 +1977,10 @@
|
||||
interrupts = <48>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac0 20>, <&dmac0 21>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x104>;
|
||||
ss_lcnt = /bits/ 16 <0xec>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
@@ -1693,6 +2002,10 @@
|
||||
interrupts = <182>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac2 21>, <&dmac2 20>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x82>;
|
||||
ss_lcnt = /bits/ 16 <0x78>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
@@ -1705,26 +2018,30 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
audio_i2c1: i2c@0xffcb01b000 {
|
||||
compatible = "snps,designware-i2c";
|
||||
reg = <0xff 0xcb01b000 0x0 0x1000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <183>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
ss_hcnt = /bits/ 16 <0x82>;
|
||||
ss_lcnt = /bits/ 16 <0x78>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
fs_lcnt = /bits/ 16 <0x42>;
|
||||
fp_hcnt = /bits/ 16 <0x14>;
|
||||
fp_lcnt = /bits/ 16 <0x1a>;
|
||||
hs_hcnt = /bits/ 16 <0x5>;
|
||||
hs_lcnt = /bits/ 16 <0x15>;
|
||||
status = "disabled";
|
||||
audio_i2c1: i2c@0xffcb01b000 {
|
||||
compatible = "snps,designware-i2c";
|
||||
reg = <0xff 0xcb01b000 0x0 0x1000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <183>;
|
||||
clocks = <&dummy_clock_apb>;
|
||||
clock-frequency = <100000>;
|
||||
i2c_mode = "dma";
|
||||
dmas = <&dmac2 23>, <&dmac2 22>;
|
||||
dma-names = "tx", "rx";
|
||||
#dma-cells = <1>;
|
||||
ss_hcnt = /bits/ 16 <0x82>;
|
||||
ss_lcnt = /bits/ 16 <0x78>;
|
||||
fs_hcnt = /bits/ 16 <0x37>;
|
||||
fs_lcnt = /bits/ 16 <0x42>;
|
||||
fp_hcnt = /bits/ 16 <0x14>;
|
||||
fp_lcnt = /bits/ 16 <0x1a>;
|
||||
hs_hcnt = /bits/ 16 <0x5>;
|
||||
hs_lcnt = /bits/ 16 <0x15>;
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
isp0: isp@ffe4100000 {
|
||||
compatible = "thead,light-isp";
|
||||
@@ -2005,6 +2322,11 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vvcam_sensor7: vvcam_sensor@7 {
|
||||
compatible = "thead,light-vvcam-sensor";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
xtensa_dsp: dsp@01{
|
||||
compatible = "thead,dsp-hw-common";
|
||||
reg = <0xff 0xef040000 0x0 0x001000 >; /*DSP_SYSREG(0x0000-0xFFF) */
|
||||
@@ -2154,6 +2476,12 @@
|
||||
interrupts = <215>; /* TEE INT SRC_7 */
|
||||
};
|
||||
|
||||
light_event: light-event {
|
||||
compatible = "thead,light-event";
|
||||
aon-iram-regmap = <&aon_iram>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
visys_clk_gate: visys-clk-gate { /* VI_SYSREG_R */
|
||||
compatible = "thead,visys-gate-controller";
|
||||
visys-regmap = <&visys_reg>;
|
||||
@@ -2181,6 +2509,13 @@
|
||||
#clock-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
audiosys_clk_gate: audiosys-clk-gate {
|
||||
compatible = "thead,audiosys-gate-controller";
|
||||
audiosys-regmap = <&audio_cpr>;
|
||||
#clock-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -251,6 +251,7 @@ CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_LIGHT=y
|
||||
CONFIG_HWSPINLOCK_LIGHT_TEST=m
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_IIO_SW_DEVICE=y
|
||||
CONFIG_PWM=y
|
||||
|
||||
@@ -252,6 +252,7 @@ CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_LIGHT=y
|
||||
CONFIG_HWSPINLOCK_LIGHT_TEST=m
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_IIO_SW_DEVICE=y
|
||||
CONFIG_PWM=y
|
||||
|
||||
@@ -3,6 +3,10 @@ CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUPS=y
|
||||
@@ -91,6 +95,7 @@ CONFIG_TUN=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_MACB=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_STMMAC_RX_ZERO_COPY=y
|
||||
CONFIG_DWMAC_LIGHT=y
|
||||
CONFIG_MICROSEMI_PHY=y
|
||||
CONFIG_REALTEK_PHY=y
|
||||
@@ -265,6 +270,11 @@ CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_LIGHT=y
|
||||
CONFIG_HWSPINLOCK_LIGHT_TEST=m
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_RPMSG=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_VIRTIO=y
|
||||
CONFIG_RPMSG_THEAD_LIGHT=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_IIO_SW_DEVICE=y
|
||||
CONFIG_PWM=y
|
||||
@@ -298,13 +308,21 @@ CONFIG_CRYPTO_AUTHENC=y
|
||||
CONFIG_CRYPTO_DH=y
|
||||
CONFIG_CRYPTO_CURVE25519=y
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=y
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_CTR=y
|
||||
CONFIG_CRYPTO_OFB=y
|
||||
CONFIG_CRYPTO_MD5=y
|
||||
CONFIG_CRYPTO_SHA512=y
|
||||
CONFIG_CRYPTO_SHA3=y
|
||||
CONFIG_CRYPTO_SM3=y
|
||||
CONFIG_CRYPTO_DES=y
|
||||
CONFIG_CRYPTO_SM4=y
|
||||
CONFIG_CRYPTO_USER=y
|
||||
CONFIG_CRYPTO_USER_API_HASH=y
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=y
|
||||
CONFIG_CRYPTO_USER_API_RNG=y
|
||||
# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set
|
||||
CONFIG_CRYPTO_USER_API_AEAD=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_DMA_PERNUMA_CMA=y
|
||||
CONFIG_CMA_SIZE_MBYTES=32
|
||||
@@ -320,6 +338,7 @@ CONFIG_OVERLAY_FS=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
|
||||
CONFIG_SCHED_INFO=y
|
||||
CONFIG_PM=y
|
||||
# CONFIG_SUSPEND is not set
|
||||
# CONFIG_PM_SLEEP is not set
|
||||
|
||||
@@ -3,7 +3,8 @@ generic-y += early_ioremap.h
|
||||
generic-y += extable.h
|
||||
generic-y += flat.h
|
||||
generic-y += kvm_para.h
|
||||
generic-y += mcs_spinlock.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += qrwlock.h
|
||||
generic-y += qrwlock_types.h
|
||||
generic-y += user.h
|
||||
generic-y += vmlinux.lds.h
|
||||
|
||||
@@ -11,12 +11,36 @@
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/fence.h>
|
||||
|
||||
static inline ulong __xchg16_relaxed(ulong new, void *ptr)
|
||||
{
|
||||
ulong ret, tmp;
|
||||
ulong shif = ((ulong)ptr & 2) ? 16 : 0;
|
||||
ulong mask = 0xffff << shif;
|
||||
ulong *__ptr = (ulong *)((ulong)ptr & ~2);
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"0: lr.w %0, %2\n"
|
||||
" and %1, %0, %z3\n"
|
||||
" or %1, %1, %z4\n"
|
||||
" sc.w %1, %1, %2\n"
|
||||
" bnez %1, 0b\n"
|
||||
: "=&r" (ret), "=&r" (tmp), "+A" (*__ptr)
|
||||
: "rJ" (~mask), "rJ" (new << shif)
|
||||
: "memory");
|
||||
|
||||
return (ulong)((ret & mask) >> shif);
|
||||
}
|
||||
|
||||
#define __xchg_relaxed(ptr, new, size) \
|
||||
({ \
|
||||
__typeof__(ptr) __ptr = (ptr); \
|
||||
__typeof__(new) __new = (new); \
|
||||
__typeof__(*(ptr)) __ret; \
|
||||
switch (size) { \
|
||||
case 2: { \
|
||||
__ret = (__typeof__(*(ptr))) \
|
||||
__xchg16_relaxed((ulong)__new, __ptr); \
|
||||
break;} \
|
||||
case 4: \
|
||||
__asm__ __volatile__ ( \
|
||||
" amoswap.w %0, %2, %1\n" \
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/pgtable.h>
|
||||
#include <asm/mmiowb.h>
|
||||
#include <asm/early_ioremap.h>
|
||||
|
||||
/*
|
||||
|
||||
@@ -133,7 +133,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
|
||||
#define __io_br() do {} while (0)
|
||||
#define __io_ar(v) __asm__ __volatile__ ("fence i,r" : : : "memory")
|
||||
#define __io_bw() __asm__ __volatile__ ("fence w,o" : : : "memory")
|
||||
#define __io_aw() mmiowb_set_pending()
|
||||
#define __io_aw() __asm__ __volatile__ ("fence o,w" : : : "memory")
|
||||
|
||||
#define readb(c) ({ u8 __v; __io_br(); __v = readb_cpu(c); __io_ar(__v); __v; })
|
||||
#define readw(c) ({ u16 __v; __io_br(); __v = readw_cpu(c); __io_ar(__v); __v; })
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _ASM_RISCV_MMIOWB_H
|
||||
#define _ASM_RISCV_MMIOWB_H
|
||||
|
||||
/*
|
||||
* "o,w" is sufficient to ensure that all writes to the device have completed
|
||||
* before the write to the spinlock is allowed to commit.
|
||||
*/
|
||||
#define mmiowb() __asm__ __volatile__ ("fence o,w" : : : "memory");
|
||||
|
||||
#include <linux/smp.h>
|
||||
#include <asm-generic/mmiowb.h>
|
||||
|
||||
#endif /* _ASM_RISCV_MMIOWB_H */
|
||||
@@ -1,92 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
/*
|
||||
* 'Generic' ticket-lock implementation.
|
||||
*
|
||||
* It relies on atomic_fetch_add() having well defined forward progress
|
||||
* guarantees under contention. If your architecture cannot provide this, stick
|
||||
* to a test-and-set lock.
|
||||
*
|
||||
* It also relies on atomic_fetch_add() being safe vs smp_store_release() on a
|
||||
* sub-word of the value. This is generally true for anything LL/SC although
|
||||
* you'd be hard pressed to find anything useful in architecture specifications
|
||||
* about this. If your architecture cannot do this you might be better off with
|
||||
* a test-and-set.
|
||||
*
|
||||
* It further assumes atomic_*_release() + atomic_*_acquire() is RCpc and hence
|
||||
* uses atomic_fetch_add() which is RCsc to create an RCsc hot path, along with
|
||||
* a full fence after the spin to upgrade the otherwise-RCpc
|
||||
* atomic_cond_read_acquire().
|
||||
*
|
||||
* The implementation uses smp_cond_load_acquire() to spin, so if the
|
||||
* architecture has WFE like instructions to sleep instead of poll for word
|
||||
* modifications be sure to implement that (see ARM64 for example).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ASM_GENERIC_SPINLOCK_H
|
||||
#define __ASM_GENERIC_SPINLOCK_H
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/spinlock_types.h>
|
||||
|
||||
static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 val = atomic_fetch_add(1<<16, lock);
|
||||
u16 ticket = val >> 16;
|
||||
|
||||
if (ticket == (u16)val)
|
||||
return;
|
||||
|
||||
/*
|
||||
* atomic_cond_read_acquire() is RCpc, but rather than defining a
|
||||
* custom cond_read_rcsc() here we just emit a full fence. We only
|
||||
* need the prior reads before subsequent writes ordering from
|
||||
* smb_mb(), but as atomic_cond_read_acquire() just emits reads and we
|
||||
* have no outstanding writes due to the atomic_fetch_add() the extra
|
||||
* orderings are free.
|
||||
*/
|
||||
atomic_cond_read_acquire(lock, ticket == (u16)VAL);
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
static __always_inline bool arch_spin_trylock(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 old = atomic_read(lock);
|
||||
|
||||
if ((old >> 16) != (old & 0xffff))
|
||||
return false;
|
||||
|
||||
return atomic_try_cmpxchg(lock, &old, old + (1<<16)); /* SC, for RCsc */
|
||||
}
|
||||
|
||||
static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
|
||||
{
|
||||
u16 *ptr = (u16 *)lock + IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
|
||||
u32 val = atomic_read(lock);
|
||||
|
||||
smp_store_release(ptr, (u16)val + 1);
|
||||
}
|
||||
|
||||
static __always_inline int arch_spin_is_locked(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 val = atomic_read(lock);
|
||||
|
||||
return ((val >> 16) != (val & 0xffff));
|
||||
}
|
||||
|
||||
static __always_inline int arch_spin_is_contended(arch_spinlock_t *lock)
|
||||
{
|
||||
u32 val = atomic_read(lock);
|
||||
|
||||
return (s16)((val >> 16) - (val & 0xffff)) > 1;
|
||||
}
|
||||
|
||||
static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
|
||||
{
|
||||
return !arch_spin_is_locked(&lock);
|
||||
}
|
||||
|
||||
#include <asm-generic/qspinlock.h>
|
||||
#include <asm/qrwlock.h>
|
||||
|
||||
#endif /* __ASM_GENERIC_SPINLOCK_H */
|
||||
|
||||
@@ -3,15 +3,7 @@
|
||||
#ifndef __ASM_GENERIC_SPINLOCK_TYPES_H
|
||||
#define __ASM_GENERIC_SPINLOCK_TYPES_H
|
||||
|
||||
#include <linux/types.h>
|
||||
typedef atomic_t arch_spinlock_t;
|
||||
|
||||
/*
|
||||
* qrwlock_types depends on arch_spinlock_t, so we must typedef that before the
|
||||
* include.
|
||||
*/
|
||||
#include <asm/qrwlock_types.h>
|
||||
|
||||
#define __ARCH_SPIN_LOCK_UNLOCKED ATOMIC_INIT(0)
|
||||
#include <asm-generic/qspinlock_types.h>
|
||||
#include <asm-generic/qrwlock_types.h>
|
||||
|
||||
#endif /* __ASM_GENERIC_SPINLOCK_TYPES_H */
|
||||
|
||||
@@ -38,11 +38,10 @@ riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api)
|
||||
RISCV_INSN_REJECTED(c_ebreak, insn);
|
||||
#endif
|
||||
|
||||
RISCV_INSN_REJECTED(auipc, insn);
|
||||
RISCV_INSN_REJECTED(branch, insn);
|
||||
|
||||
RISCV_INSN_SET_SIMULATE(jal, insn);
|
||||
RISCV_INSN_SET_SIMULATE(jalr, insn);
|
||||
RISCV_INSN_SET_SIMULATE(auipc, insn);
|
||||
RISCV_INSN_SET_SIMULATE(branch, insn);
|
||||
|
||||
return INSN_GOOD;
|
||||
}
|
||||
|
||||
@@ -83,3 +83,115 @@ bool __kprobes simulate_jalr(u32 opcode, unsigned long addr, struct pt_regs *reg
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define auipc_rd_idx(opcode) \
|
||||
((opcode >> 7) & 0x1f)
|
||||
|
||||
#define auipc_imm(opcode) \
|
||||
((((opcode) >> 12) & 0xfffff) << 12)
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#define auipc_offset(opcode) sign_extend64(auipc_imm(opcode), 31)
|
||||
#elif __riscv_xlen == 32
|
||||
#define auipc_offset(opcode) auipc_imm(opcode)
|
||||
#else
|
||||
#error "Unexpected __riscv_xlen"
|
||||
#endif
|
||||
|
||||
bool __kprobes simulate_auipc(u32 opcode, unsigned long addr, struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* auipc instruction:
|
||||
* 31 12 11 7 6 0
|
||||
* | imm[31:12] | rd | opcode |
|
||||
* 20 5 7
|
||||
*/
|
||||
|
||||
u32 rd_idx = auipc_rd_idx(opcode);
|
||||
unsigned long rd_val = addr + auipc_offset(opcode);
|
||||
|
||||
if (!rv_insn_reg_set_val(regs, rd_idx, rd_val))
|
||||
return false;
|
||||
|
||||
instruction_pointer_set(regs, addr + 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define branch_rs1_idx(opcode) \
|
||||
(((opcode) >> 15) & 0x1f)
|
||||
|
||||
#define branch_rs2_idx(opcode) \
|
||||
(((opcode) >> 20) & 0x1f)
|
||||
|
||||
#define branch_funct3(opcode) \
|
||||
(((opcode) >> 12) & 0x7)
|
||||
|
||||
#define branch_imm(opcode) \
|
||||
(((((opcode) >> 8) & 0xf ) << 1) | \
|
||||
((((opcode) >> 25) & 0x3f) << 5) | \
|
||||
((((opcode) >> 7) & 0x1 ) << 11) | \
|
||||
((((opcode) >> 31) & 0x1 ) << 12))
|
||||
|
||||
#define branch_offset(opcode) \
|
||||
sign_extend32((branch_imm(opcode)), 12)
|
||||
|
||||
#define BRANCH_BEQ 0x0
|
||||
#define BRANCH_BNE 0x1
|
||||
#define BRANCH_BLT 0x4
|
||||
#define BRANCH_BGE 0x5
|
||||
#define BRANCH_BLTU 0x6
|
||||
#define BRANCH_BGEU 0x7
|
||||
|
||||
bool __kprobes simulate_branch(u32 opcode, unsigned long addr, struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* branch instructions:
|
||||
* 31 30 25 24 20 19 15 14 12 11 8 7 6 0
|
||||
* | imm[12] | imm[10:5] | rs2 | rs1 | funct3 | imm[4:1] | imm[11] | opcode |
|
||||
* 1 6 5 5 3 4 1 7
|
||||
* imm[12|10:5] rs2 rs1 000 imm[4:1|11] 1100011 BEQ
|
||||
* imm[12|10:5] rs2 rs1 001 imm[4:1|11] 1100011 BNE
|
||||
* imm[12|10:5] rs2 rs1 100 imm[4:1|11] 1100011 BLT
|
||||
* imm[12|10:5] rs2 rs1 101 imm[4:1|11] 1100011 BGE
|
||||
* imm[12|10:5] rs2 rs1 110 imm[4:1|11] 1100011 BLTU
|
||||
* imm[12|10:5] rs2 rs1 111 imm[4:1|11] 1100011 BGEU
|
||||
*/
|
||||
|
||||
s32 offset;
|
||||
s32 offset_tmp;
|
||||
unsigned long rs1_val;
|
||||
unsigned long rs2_val;
|
||||
|
||||
if (!rv_insn_reg_get_val(regs, branch_rs1_idx(opcode), &rs1_val) ||
|
||||
!rv_insn_reg_get_val(regs, branch_rs2_idx(opcode), &rs2_val))
|
||||
return false;
|
||||
|
||||
offset_tmp = branch_offset(opcode);
|
||||
switch (branch_funct3(opcode)) {
|
||||
case BRANCH_BEQ:
|
||||
offset = (rs1_val == rs2_val) ? offset_tmp : 4;
|
||||
break;
|
||||
case BRANCH_BNE:
|
||||
offset = (rs1_val != rs2_val) ? offset_tmp : 4;
|
||||
break;
|
||||
case BRANCH_BLT:
|
||||
offset = ((long)rs1_val < (long)rs2_val) ? offset_tmp : 4;
|
||||
break;
|
||||
case BRANCH_BGE:
|
||||
offset = ((long)rs1_val >= (long)rs2_val) ? offset_tmp : 4;
|
||||
break;
|
||||
case BRANCH_BLTU:
|
||||
offset = (rs1_val < rs2_val) ? offset_tmp : 4;
|
||||
break;
|
||||
case BRANCH_BGEU:
|
||||
offset = (rs1_val >= rs2_val) ? offset_tmp : 4;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
instruction_pointer_set(regs, addr + offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_CLK_LIGHT_FM) += thead-gate.o visys-gate.o vpsys-gate.o vosys-gate.o dspsys-gate.o
|
||||
obj-$(CONFIG_CLK_LIGHT_FM) += thead-gate.o visys-gate.o vpsys-gate.o vosys-gate.o dspsys-gate.o audiosys-gate.o
|
||||
|
||||
124
drivers/clk/thead/gate/audiosys-gate.c
Normal file
124
drivers/clk/thead/gate/audiosys-gate.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/light-fm-ap-clock.h>
|
||||
#include <dt-bindings/clock/light-audiosys.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include "clk-gate.h"
|
||||
#include "../clk.h"
|
||||
|
||||
static struct clk *gates[LIGHT_CLKGEN_AUDIO_CLK_END];
|
||||
static struct clk_onecell_data clk_gate_data;
|
||||
|
||||
static int light_audiosys_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *audiosys_regmap;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
int ret;
|
||||
|
||||
audiosys_regmap = syscon_regmap_lookup_by_phandle(np, "audiosys-regmap");
|
||||
if (IS_ERR(audiosys_regmap)) {
|
||||
dev_err(&pdev->dev, "cannot find regmap for vi system register\n");
|
||||
return PTR_ERR(audiosys_regmap);
|
||||
}
|
||||
|
||||
printk("%s audiosys_regmap=0x%px\n", __func__, audiosys_regmap);
|
||||
|
||||
/* we assume that the gate clock is a root clock */
|
||||
gates[LIGHT_CLKGEN_AUDIO_CPU] = thead_gate_clk_register("clkgen_audiosys_cpu_clk", NULL,
|
||||
audiosys_regmap, 0x10, 0, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_SRAM0] = thead_gate_clk_register("clkgen_audiosys_sram0_clk", NULL,
|
||||
audiosys_regmap, 0x10, 1, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_SRAM1] = thead_gate_clk_register("clkgen_audiosys_sram1_clk", NULL,
|
||||
audiosys_regmap, 0x10, 2, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_DMA] = thead_gate_clk_register("clkgen_audiosys_dma_clk", NULL,
|
||||
audiosys_regmap, 0x10, 3, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_BSM] = thead_gate_clk_register("clkgen_audiosys_bsm_clk", NULL,
|
||||
audiosys_regmap, 0x10, 4, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_TIMER] = thead_gate_clk_register("clkgen_audiosys_timer_clk", NULL,
|
||||
audiosys_regmap, 0x10, 8, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_TIMER_CNT1] = thead_gate_clk_register("clkgen_audiosys_timer_cnt1_clk", NULL,
|
||||
audiosys_regmap, 0x10, 9, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_TIMER_CNT2] = thead_gate_clk_register("clkgen_audiosys_timer_cnt2_clk", NULL,
|
||||
audiosys_regmap, 0x10, 10, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_TIMER_CNT3] = thead_gate_clk_register("clkgen_audiosys_timer_cnt3_clk", NULL,
|
||||
audiosys_regmap, 0x10, 11, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_TIMER_CNT4] = thead_gate_clk_register("clkgen_audiosys_timer_cnt4_clk", NULL,
|
||||
audiosys_regmap, 0x10, 12, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_WDR] = thead_gate_clk_register("clkgen_audiosys_wdr_clk", NULL,
|
||||
audiosys_regmap, 0x10, 13, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_I2C0] = thead_gate_clk_register("clkgen_audiosys_i2c0_clk", NULL,
|
||||
audiosys_regmap, 0x10, 14, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_I2C1] = thead_gate_clk_register("clkgen_audiosys_i2c1_clk", NULL,
|
||||
audiosys_regmap, 0x10, 15, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_UART] = thead_gate_clk_register("clkgen_audiosys_uart_clk", NULL,
|
||||
audiosys_regmap, 0x10, 16, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_I2S0] = thead_gate_clk_register("clkgen_audiosys_i2s0_clk", NULL,
|
||||
audiosys_regmap, 0x10, 17, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_I2S1] = thead_gate_clk_register("clkgen_audiosys_i2s1_clk", NULL,
|
||||
audiosys_regmap, 0x10, 18, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_I2S2] = thead_gate_clk_register("clkgen_audiosys_i2s2_clk", NULL,
|
||||
audiosys_regmap, 0x10, 19, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_I2S8CH] = thead_gate_clk_register("clkgen_audiosys_i2s8ch_clk", NULL,
|
||||
audiosys_regmap, 0x10, 20, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_TDM] = thead_gate_clk_register("clkgen_audiosys_tdm_clk", NULL,
|
||||
audiosys_regmap, 0x10, 21, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_GPIO] = thead_gate_clk_register("clkgen_audiosys_gpio_clk", NULL,
|
||||
audiosys_regmap, 0x10, 22, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_SPDIF0] = thead_gate_clk_register("clkgen_audiosys_spdif0_clk", NULL,
|
||||
audiosys_regmap, 0x10, 23, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_SPDIF1] = thead_gate_clk_register("clkgen_audiosys_spdif1_clk", NULL,
|
||||
audiosys_regmap, 0x10, 24, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_VAD] = thead_gate_clk_register("clkgen_audiosys_vad_clk", NULL,
|
||||
audiosys_regmap, 0x10, 25, GATE_NOT_SHARED, NULL, dev);
|
||||
gates[LIGHT_CLKGEN_AUDIO_IOMUX] = thead_gate_clk_register("clkgen_audiosys_iomux_clk", NULL,
|
||||
audiosys_regmap, 0x10, 26, GATE_NOT_SHARED, NULL, dev);
|
||||
|
||||
clk_gate_data.clks = gates;
|
||||
clk_gate_data.clk_num = ARRAY_SIZE(gates);
|
||||
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_gate_data);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to register gate clks for light audiosys\n");
|
||||
goto unregister_clks;
|
||||
}
|
||||
|
||||
dev_info(dev, "succeed to register audiosys gate clock provider\n");
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_clks:
|
||||
thead_unregister_clocks(gates, ARRAY_SIZE(gates));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id audiosys_clk_gate_of_match[] = {
|
||||
{ .compatible = "thead,audiosys-gate-controller" },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, audiosys_clk_gate_of_match);
|
||||
|
||||
static struct platform_driver light_audiosys_clk_driver = {
|
||||
.probe = light_audiosys_clk_probe,
|
||||
.driver = {
|
||||
.name = "audiosys-clk-gate-provider",
|
||||
.of_match_table = of_match_ptr(audiosys_clk_gate_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(light_audiosys_clk_driver);
|
||||
MODULE_AUTHOR("nanli.yd <nanli.yd@linux.alibaba.com>");
|
||||
MODULE_DESCRIPTION("Thead Light Fullmask audiosys clock gate provider");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -335,7 +335,7 @@ _ConvertLogical2Physical(
|
||||
OUT gctPHYS_ADDR_T * Physical
|
||||
);
|
||||
|
||||
gctBOOL
|
||||
gceSTATUS
|
||||
_QuerySignal(
|
||||
IN gckOS Os,
|
||||
IN gctSIGNAL Signal
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
|
||||
* Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
*/
|
||||
#include <linux/extcon-provider.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
@@ -103,6 +104,11 @@ static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = {
|
||||
{ 0x0000, 0x0000, 0x1b7c, 0x0020 }
|
||||
};
|
||||
|
||||
static const unsigned int hdmi_extcon_cable[] = {
|
||||
EXTCON_DISP_HDMI,
|
||||
EXTCON_NONE,
|
||||
};
|
||||
|
||||
struct hdmi_vmode {
|
||||
bool mdataenablepolarity;
|
||||
|
||||
@@ -160,6 +166,7 @@ struct dw_hdmi {
|
||||
struct clk *pix_clk;
|
||||
struct clk *i2s_clk;
|
||||
struct dw_hdmi_i2c *i2c;
|
||||
struct extcon_dev *edev;
|
||||
|
||||
struct hdmi_data_info hdmi_data;
|
||||
const struct dw_hdmi_plat_data *plat_data;
|
||||
@@ -3117,6 +3124,10 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
|
||||
dev_dbg(hdmi->dev, "EVENT=%s\n",
|
||||
status == connector_status_connected ?
|
||||
"plugin" : "plugout");
|
||||
if (status == connector_status_connected)
|
||||
extcon_set_state_sync(hdmi->edev, EXTCON_DISP_HDMI, true);
|
||||
else
|
||||
extcon_set_state_sync(hdmi->edev, EXTCON_DISP_HDMI, false);
|
||||
|
||||
if (hdmi->bridge.dev) {
|
||||
drm_helper_hpd_irq_event(hdmi->bridge.dev);
|
||||
@@ -3423,6 +3434,19 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
|
||||
|
||||
dw_hdmi_init_hw(hdmi);
|
||||
|
||||
hdmi->edev = devm_extcon_dev_allocate(dev, hdmi_extcon_cable);
|
||||
if (IS_ERR(hdmi->edev)) {
|
||||
dev_err(dev, "failed to allocate extcon device\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_res;
|
||||
}
|
||||
|
||||
ret = devm_extcon_dev_register(dev, hdmi->edev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to register extcon device\n");
|
||||
goto err_res;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
|
||||
@@ -50,6 +50,7 @@ obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
|
||||
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
|
||||
obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o
|
||||
i2c-designware-core-y := i2c-designware-common.o
|
||||
i2c-designware-core-y += i2c-designware-master_dma.o
|
||||
i2c-designware-core-y += i2c-designware-master.o
|
||||
i2c-designware-core-$(CONFIG_I2C_DESIGNWARE_SLAVE) += i2c-designware-slave.o
|
||||
obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
|
||||
I2C_FUNC_SMBUS_BYTE | \
|
||||
@@ -234,6 +235,18 @@ struct reset_control;
|
||||
* values than the one computed based only on the input clock frequency.
|
||||
* Leave them to be %0 if not used.
|
||||
*/
|
||||
struct i2c_dw_dma {
|
||||
struct dma_chan *dma_chan;
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
dma_cookie_t cookie;
|
||||
dma_addr_t dma_addr; //phy addr
|
||||
u32 *buf; //Store the virtual address of the data to be transferred by dma
|
||||
u32 buf_size;
|
||||
u32 transfer_len; //dma transfer data num
|
||||
//volatile int dma_complete;
|
||||
struct completion dma_complete;
|
||||
};
|
||||
|
||||
struct dw_i2c_dev {
|
||||
struct device *dev;
|
||||
struct regmap *map;
|
||||
@@ -257,6 +270,7 @@ struct dw_i2c_dev {
|
||||
u8 *rx_buf;
|
||||
int msg_err;
|
||||
unsigned int status;
|
||||
unsigned int tx_status;
|
||||
u32 abort_source;
|
||||
int irq;
|
||||
u32 flags;
|
||||
@@ -287,6 +301,10 @@ struct dw_i2c_dev {
|
||||
int mode;
|
||||
struct i2c_bus_recovery_info rinfo;
|
||||
bool suspended;
|
||||
struct i2c_dw_dma dma;
|
||||
u32 laststat;
|
||||
u32 laststatus;
|
||||
int dw_i2c_enable_dma;
|
||||
};
|
||||
|
||||
#define ACCESS_INTR_MASK 0x00000001
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include "i2c-designware-core.h"
|
||||
#include "i2c-designware-master_dma.h"
|
||||
|
||||
static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
|
||||
{
|
||||
@@ -257,7 +258,13 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
|
||||
|
||||
/* Clear and enable interrupts */
|
||||
regmap_read(dev->map, DW_IC_CLR_INTR, &dummy);
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK);
|
||||
|
||||
if (dev->dw_i2c_enable_dma) {
|
||||
i2c_dw_xfer_dma_init(dev);
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK & (~DW_IC_INTR_TX_EMPTY));
|
||||
} else {
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -289,9 +296,9 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
|
||||
* adapter when we are done with this transfer.
|
||||
*/
|
||||
if (msgs[dev->msg_write_idx].addr != addr) {
|
||||
dev_err(dev->dev,
|
||||
"%s: invalid target address\n", __func__);
|
||||
dev->msg_err = -EINVAL;
|
||||
dev_err(dev->dev,
|
||||
"%s: invalid target address\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -476,6 +483,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
dev->msg_read_idx = 0;
|
||||
dev->msg_err = 0;
|
||||
dev->status = STATUS_IDLE;
|
||||
dev->tx_status = STATUS_IDLE;
|
||||
dev->abort_source = 0;
|
||||
dev->rx_outstanding = 0;
|
||||
|
||||
@@ -491,6 +499,16 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
i2c_dw_xfer_init(dev);
|
||||
|
||||
/* Wait for tx to complete */
|
||||
if (dev->dw_i2c_enable_dma) {
|
||||
if(i2c_dw_dma_tx_transfer(dev, adap->timeout) != 0) {
|
||||
dev_err(dev->dev, "i2c dw dma transfer error\n");
|
||||
i2c_recover_bus(&dev->adapter);
|
||||
i2c_dw_init_master(dev);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wait_for_completion_timeout(&dev->cmd_complete, adap->timeout)) {
|
||||
dev_err(dev->dev, "controller timed out\n");
|
||||
/* i2c_dw_init implicitly disables the adapter */
|
||||
@@ -527,15 +545,21 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (dev->status)
|
||||
dev_err(dev->dev,
|
||||
"transfer terminated early - interrupt latency too high?\n");
|
||||
if (dev->status || dev->tx_status) {
|
||||
dev_err(dev->dev, "transfer terminated early - interrupt latency too high? sta 0x%x\n", dev->status);
|
||||
|
||||
dev_err(dev->dev, "laststa 0x%x, laststatus 0x%x\n", dev->laststat, dev->laststatus);
|
||||
dev_err(dev->dev, "dev->tx_status 0x%x\n", dev->tx_status);
|
||||
dev_err(dev->dev, "dev->rx_outstanding %d\n", dev->rx_outstanding);
|
||||
}
|
||||
|
||||
ret = -EIO;
|
||||
|
||||
done:
|
||||
if (dev->dw_i2c_enable_dma) {
|
||||
i2c_dw_xfer_dma_deinit(dev);
|
||||
}
|
||||
i2c_dw_release_lock(dev);
|
||||
|
||||
done_nolock:
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
@@ -631,8 +655,9 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
|
||||
if (stat & DW_IC_INTR_RX_FULL)
|
||||
i2c_dw_read(dev);
|
||||
|
||||
if (stat & DW_IC_INTR_TX_EMPTY)
|
||||
if (stat & DW_IC_INTR_TX_EMPTY) {
|
||||
i2c_dw_xfer_msg(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to modify or disable the interrupt mask here.
|
||||
@@ -645,9 +670,11 @@ tx_aborted:
|
||||
if ((stat & DW_IC_INTR_TX_ABRT) || dev->msg_err ||
|
||||
((status & DW_IC_STATUS_TFE) &&
|
||||
(!(status & DW_IC_STATUS_RFNE)) &&
|
||||
(!(status & DW_IC_STATUS_MASTER_ACTIVITY))))
|
||||
(!(status & DW_IC_STATUS_MASTER_ACTIVITY)))) {
|
||||
complete(&dev->cmd_complete);
|
||||
else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
|
||||
dev->laststat = stat;
|
||||
dev->laststatus = status;
|
||||
} else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
|
||||
/* Workaround to trigger pending interrupt */
|
||||
regmap_read(dev->map, DW_IC_INTR_MASK, &stat);
|
||||
i2c_dw_disable_int(dev);
|
||||
@@ -747,9 +774,25 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_adapter *adap = &dev->adapter;
|
||||
unsigned long irq_flags;
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
const char *i2c_mode;
|
||||
|
||||
//default used interrupt mode
|
||||
dev->dw_i2c_enable_dma = 0;
|
||||
|
||||
np = dev->dev->of_node;
|
||||
ret = of_property_read_string(np, "i2c_mode", &i2c_mode);
|
||||
if (ret == 0) {
|
||||
if (strcmp(i2c_mode, "dma") == 0) {
|
||||
dev->dw_i2c_enable_dma = 1;
|
||||
}
|
||||
}
|
||||
|
||||
init_completion(&dev->cmd_complete);
|
||||
if (dev->dw_i2c_enable_dma) {
|
||||
init_completion(&dev->dma.dma_complete);
|
||||
}
|
||||
|
||||
dev->init = i2c_dw_init_master;
|
||||
dev->disable = i2c_dw_disable;
|
||||
@@ -787,10 +830,10 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
|
||||
|
||||
i2c_dw_disable_int(dev);
|
||||
ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags,
|
||||
dev_name(dev->dev), dev);
|
||||
dev_name(dev->dev), dev);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "failure requesting irq %i: %d\n",
|
||||
dev->irq, ret);
|
||||
dev->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
318
drivers/i2c/busses/i2c-designware-master_dma.c
Normal file
318
drivers/i2c/busses/i2c-designware-master_dma.c
Normal file
@@ -0,0 +1,318 @@
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include "i2c-designware-core.h"
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#define DW_IC_DMA_CR (0x88)
|
||||
#define DW_IC_DMA_TDLR (0x8c)
|
||||
#define DW_IC_DMA_RDLR (0x90)
|
||||
#define DW_IC_DMA_CR_TXEN (0x2)
|
||||
#define DW_IC_DMA_CR_DIS (0x0)
|
||||
|
||||
//Because the fifo register bit width is 32bits, each transfer data is 4byte
|
||||
#define DW_IC_DMA_DATA_BLOCK_BYTES (0x4)
|
||||
|
||||
//#define __dev_vdgb dev_dbg
|
||||
#define __dev_vdgb(fmt, ...)
|
||||
|
||||
static int i2c_dw_hwparams_to_dma_slave_config(struct dw_i2c_dev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct dma_slave_config slave_config;
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
struct platform_device *pdev;
|
||||
struct resource *iores_mem;
|
||||
phys_addr_t reg_addr;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
memset(&slave_config, 0, sizeof(slave_config));
|
||||
|
||||
//get i2c fifo addr
|
||||
pdev = to_platform_device(dev->dev);
|
||||
iores_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_addr = iores_mem->start + DW_IC_DATA_CMD;
|
||||
slave_config.direction = DMA_MEM_TO_DEV;
|
||||
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
slave_config.dst_addr = reg_addr;
|
||||
//for light only support "false"
|
||||
slave_config.device_fc = false;
|
||||
|
||||
ret = dmaengine_slave_config(dma->dma_chan, &slave_config);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "dmaengine_slave_config failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_dw_dma_callback(void *data)
|
||||
{
|
||||
struct dw_i2c_dev *dev = (struct dw_i2c_dev *)data;
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
|
||||
dev->tx_status &= ~STATUS_WRITE_IN_PROGRESS;
|
||||
complete(&dma->dma_complete);
|
||||
dmaengine_terminate_async(dma->dma_chan);
|
||||
}
|
||||
|
||||
static int get_msg_size(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_msg *msgs = dev->msgs;
|
||||
u32 addr = msgs[dev->msg_write_idx].addr;
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
for (i = dev->msg_write_idx; i < dev->msgs_num; i++) {
|
||||
if (msgs[i].addr != addr) {
|
||||
dev_err(dev->dev, "%s: invalid target address\n", __func__);
|
||||
dev->msg_err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
len += msgs[i].len;
|
||||
}
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int alloc_dma_buf(struct dw_i2c_dev *dev, int size)
|
||||
{
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
|
||||
dma->buf = dma_alloc_coherent(dev->dev, size, &dma->dma_addr, GFP_KERNEL);
|
||||
if (!dma->buf) {
|
||||
dev_err(dev->dev, "i2c alloc dma buf failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dma->buf_size = size;
|
||||
dma->transfer_len = 0;
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_dw_release_tx_packets(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
|
||||
if(dma->buf && dma->dma_addr && dma->buf_size) {
|
||||
dma_free_coherent(dev->dev, dma->buf_size, dma->buf, dma->dma_addr);
|
||||
}
|
||||
|
||||
dma->buf = 0;
|
||||
dma->dma_addr = 0;
|
||||
dma->buf_size = 0;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_dw_synthetic_tx_packets(struct dw_i2c_dev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
struct i2c_msg *msgs = dev->msgs;
|
||||
bool need_restart = false;
|
||||
uint32_t *tx_buf;
|
||||
int dma_tx_buf_size;
|
||||
u32 addr = msgs[dev->msg_write_idx].addr;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
|
||||
dma_tx_buf_size = get_msg_size(dev) * 4;
|
||||
if (dma_tx_buf_size <= 0) {
|
||||
dev_err(dev->dev, "i2c get_msg_size size is error %d\n", dma_tx_buf_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = alloc_dma_buf(dev, dma_tx_buf_size);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "i2c alloc_dma_buf failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tx_buf = dma->buf;
|
||||
|
||||
for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
|
||||
unsigned char *buf;
|
||||
int buf_len;
|
||||
u32 flags = msgs[dev->msg_write_idx].flags;
|
||||
|
||||
if (msgs[dev->msg_write_idx].addr != addr) {
|
||||
dev_err(dev->dev, "%s: invalid target address\n", __func__);
|
||||
dev->msg_err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* new i2c_msg */
|
||||
buf = msgs[dev->msg_write_idx].buf;
|
||||
buf_len = msgs[dev->msg_write_idx].len;
|
||||
|
||||
if ((dev->master_cfg & DW_IC_CON_RESTART_EN) &&
|
||||
(dev->msg_write_idx > 0))
|
||||
need_restart = true;
|
||||
|
||||
//dev_err(dev->dev, " msg_buf_len %d\n", buf_len);
|
||||
while (buf_len > 0) {
|
||||
u32 cmd = 0;
|
||||
|
||||
if (dev->msg_write_idx == dev->msgs_num - 1 &&
|
||||
buf_len == 1 && !(flags & I2C_M_RECV_LEN))
|
||||
cmd |= BIT(9);
|
||||
|
||||
if (need_restart) {
|
||||
cmd |= BIT(10);
|
||||
need_restart = false;
|
||||
}
|
||||
|
||||
if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
|
||||
*tx_buf = cmd | 0x100;
|
||||
dev->rx_outstanding++;
|
||||
} else {
|
||||
*tx_buf = cmd | *buf++;
|
||||
}
|
||||
tx_buf++;
|
||||
dma->transfer_len++;
|
||||
buf_len--;
|
||||
}
|
||||
}
|
||||
|
||||
dma_sync_single_for_device(dev->dev, dma->dma_addr, dma->buf_size, DMA_TO_DEVICE);
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_dw_xfer_dma_deinit(struct dw_i2c_dev *dev);
|
||||
|
||||
int i2c_dw_dma_tx_transfer(struct dw_i2c_dev *dev, unsigned int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
unsigned long start_jiffies = 0;
|
||||
u32 stat;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
if (dma->dma_chan == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = i2c_dw_hwparams_to_dma_slave_config(dev);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat);
|
||||
if (stat & DW_IC_INTR_TX_ABRT) {
|
||||
dev->cmd_err |= DW_IC_ERR_TX_ABRT;
|
||||
dev->tx_status = STATUS_IDLE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = i2c_dw_synthetic_tx_packets(dev);
|
||||
if (ret != 0) {
|
||||
dev_err(dev->dev, "%s: i2c_dw_synthetic_tx_packets failed\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev->tx_status |= STATUS_WRITE_IN_PROGRESS;
|
||||
dma->desc = dmaengine_prep_slave_single(dma->dma_chan, dma->dma_addr,
|
||||
dma->transfer_len * DW_IC_DMA_DATA_BLOCK_BYTES,
|
||||
DMA_MEM_TO_DEV,
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
if (dma->desc == NULL) {
|
||||
dev_err(dev->dev, "%s: dmaengine_prep_slave_single failed\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dma->desc->callback = i2c_dw_dma_callback;
|
||||
dma->desc->callback_param = dev;
|
||||
dma->cookie = dmaengine_submit(dma->desc);
|
||||
dma_async_issue_pending(dma->dma_chan);
|
||||
|
||||
//wait dma transfer complete
|
||||
if (!wait_for_completion_timeout(&dma->dma_complete, timeout)) {
|
||||
dev_err(dev->dev, "i2c dma_ch%d write timed out\n", dma->dma_chan->chan_id);
|
||||
ret = dmaengine_terminate_async(dma->dma_chan);
|
||||
if (ret !=0) {
|
||||
dev_err(dev->dev, "i2c dma dmaengine_terminate_async failed,\
|
||||
dma_ch is %d\n", dma->dma_chan->chan_id);
|
||||
}
|
||||
dmaengine_synchronize(dma->dma_chan);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dmaengine_synchronize(dma->dma_chan);
|
||||
|
||||
//Release the dma channel immediately after the dma transfer is completed,
|
||||
//reducing the dma occupation time
|
||||
//i2c_dw_xfer_dma_init(dev);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
//i2c_dw_xfer_dma_init(dev);
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i2c_dw_xfer_dma_init(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
|
||||
// i2c dma set tx data level
|
||||
regmap_write(dev->map, DW_IC_DMA_TDLR, dev->tx_fifo_depth / 2);
|
||||
|
||||
// i2c dma tx enable
|
||||
regmap_write(dev->map, DW_IC_DMA_CR, DW_IC_DMA_CR_TXEN);
|
||||
|
||||
if (dma->dma_chan == NULL) {
|
||||
//Alloc i2c dma channel.
|
||||
//The function is to configure the handshake number in i2c dts into the channel
|
||||
dma->dma_chan = dma_request_slave_channel(dev->dev, "tx");
|
||||
if (!dma->dma_chan) {
|
||||
dev_err(dev->dev, "Failed to request dma channel");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
__dev_vdgb(dev->dev,"i2c request dma_ch %d\n", dma->dma_chan->chan_id);
|
||||
}
|
||||
|
||||
__dev_vdgb(dev->dev,"i2c dma_ch %d\n", dma->dma_chan->chan_id);
|
||||
reinit_completion(&dma->dma_complete);
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_dw_xfer_dma_deinit(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
|
||||
i2c_dw_release_tx_packets(dev);
|
||||
if (dma->dma_chan != NULL) {
|
||||
dma_release_channel(dma->dma_chan);
|
||||
}
|
||||
dma->dma_chan = NULL;
|
||||
|
||||
// i2c dma disable
|
||||
regmap_write(dev->map, DW_IC_DMA_CR, DW_IC_DMA_CR_DIS);
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
6
drivers/i2c/busses/i2c-designware-master_dma.h
Normal file
6
drivers/i2c/busses/i2c-designware-master_dma.h
Normal file
@@ -0,0 +1,6 @@
|
||||
//#include "i2c-designware-core.h"
|
||||
|
||||
int i2c_dw_dma_tx_transfer(struct dw_i2c_dev *dev, unsigned int timeout);
|
||||
int i2c_dw_xfer_dma_init(struct dw_i2c_dev *dev);
|
||||
int i2c_dw_xfer_dma_deinit(struct dw_i2c_dev *dev);
|
||||
|
||||
@@ -56,7 +56,7 @@ obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox.o
|
||||
obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
|
||||
|
||||
obj-$(CONFIG_THEAD_LIGHT_MBOX) += light-mailbox.o
|
||||
obj-$(CONFIG_THEAD_LIGHT_MBOX) += light-mailbox-client.o
|
||||
#obj-$(CONFIG_THEAD_LIGHT_MBOX) += light-mailbox-client.o
|
||||
|
||||
obj-$(CONFIG_VIRTIO_MAILBOX) += virtio-mailbox.o
|
||||
obj-$(CONFIG_VIRTIO_MAILBOX_TEST) += virtio-mailbox-test.o
|
||||
|
||||
@@ -28,17 +28,20 @@
|
||||
|
||||
struct dwcmshc_priv {
|
||||
struct clk *bus_clk;
|
||||
void __iomem *soc_base;
|
||||
bool is_emmc_card;
|
||||
bool pull_up_en;
|
||||
bool io_fixed_1v8;
|
||||
bool wprtn_ignore;
|
||||
long reset_cnt;
|
||||
uint32_t delay_line[MMC_TIMING_MMC_HS400+1];
|
||||
uint32_t clk_delay_set;
|
||||
bool rxclk_sw_tune_en;
|
||||
uint32_t rxclk_delay_set;
|
||||
};
|
||||
|
||||
#define HS400_DELAY_LINE 24
|
||||
|
||||
static uint32_t delay_line = 50;
|
||||
//static uint32_t delay_line = 50;
|
||||
|
||||
static void sdhci_phy_1_8v_init_no_pull(struct sdhci_host *host)
|
||||
{
|
||||
@@ -114,12 +117,13 @@ static void snps_phy_1_8v_init(struct sdhci_host *host)
|
||||
//disable delay lane
|
||||
sdhci_writeb(host, 1 << UPDATE_DC, PHY_SDCLKDL_CNFG_R);
|
||||
//set delay lane
|
||||
sdhci_writeb(host, delay_line, PHY_SDCLKDL_DC_R);
|
||||
sdhci_writeb(host, priv->clk_delay_set, PHY_SDCLKDL_DC_R);
|
||||
sdhci_writeb(host, 0xa, PHY_DLL_CNFG2_R);
|
||||
//enable delay lane
|
||||
val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R);
|
||||
val &= ~(1 << UPDATE_DC);
|
||||
sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R);
|
||||
pr_debug("%s: snps_phy_1_8v_init clk delay %d\n",host->hw_name,priv->clk_delay_set);
|
||||
|
||||
val = (1 << RXSEL) | (1 << WEAKPULL_EN) | (3 << TXSLEW_CTRL_P) | (3 << TXSLEW_CTRL_N);
|
||||
sdhci_writew(host, val, PHY_CMDPAD_CNFG_R);
|
||||
@@ -156,12 +160,13 @@ static void snps_phy_3_3v_init(struct sdhci_host *host)
|
||||
//disable delay lane
|
||||
sdhci_writeb(host, 1 << UPDATE_DC, PHY_SDCLKDL_CNFG_R);
|
||||
//set delay lane
|
||||
sdhci_writeb(host, delay_line, PHY_SDCLKDL_DC_R);
|
||||
sdhci_writeb(host, priv->clk_delay_set, PHY_SDCLKDL_DC_R);
|
||||
sdhci_writeb(host, 0xa, PHY_DLL_CNFG2_R);
|
||||
//enable delay lane
|
||||
val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R);
|
||||
val &= ~(1 << UPDATE_DC);
|
||||
sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R);
|
||||
pr_debug("%s: snps_phy_3_3v_init clk delay %d\n",host->hw_name,priv->clk_delay_set);
|
||||
|
||||
val = (2 << RXSEL) | (1 << WEAKPULL_EN) | (3 << TXSLEW_CTRL_P) | (3 << TXSLEW_CTRL_N);
|
||||
sdhci_writew(host, val, PHY_CMDPAD_CNFG_R);
|
||||
@@ -255,6 +260,61 @@ static int snps_execute_tuning(struct sdhci_host *host, u32 opcode)
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int snps_rxclk_sw_tuned_sample_delay_set(struct sdhci_host *host, u32 sample_delay,u32 timeout)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host;
|
||||
struct dwcmshc_priv *priv;
|
||||
u32 reg_val;
|
||||
u32 tune_clk_set;
|
||||
u16 ctrl_2;
|
||||
u32 i=0;
|
||||
pltfm_host = sdhci_priv(host);
|
||||
priv = sdhci_pltfm_priv(pltfm_host);
|
||||
/*0x320:SMPLDL_CNFG
|
||||
0x540:AT_CTRL
|
||||
0x544:AT_STAT */
|
||||
reg_val = sdhci_readb(host, PHY_SMPLDL_CNFG_R);
|
||||
if(sample_delay >= 0x80){
|
||||
/*if larger than 128,DelayLine works with extended delay range setting*/
|
||||
reg_val |= (1 << SMPLDL_CNFG_EXTDLY_EN);
|
||||
}else{
|
||||
reg_val &= ~(1 << SMPLDL_CNFG_EXTDLY_EN);
|
||||
}
|
||||
sdhci_writeb(host, reg_val, PHY_SMPLDL_CNFG_R);
|
||||
|
||||
reg_val = sdhci_readl(host, AT_CTRL_R);
|
||||
reg_val |= (1 << TUNE_CLK_STOP_EN);
|
||||
reg_val |= (1 << SW_TUNE_EN);
|
||||
sdhci_writel(host, reg_val, AT_CTRL_R);
|
||||
|
||||
if(sample_delay >= 0x80){
|
||||
tune_clk_set = (sample_delay - 0x80) & 0xff;
|
||||
}
|
||||
else {
|
||||
tune_clk_set = sample_delay ;
|
||||
}
|
||||
reg_val = sdhci_readl(host, AT_STAT_R);
|
||||
reg_val &= ~(0xff<<AT_STAT_CENTER_PH_CODE);
|
||||
reg_val |= tune_clk_set;
|
||||
sdhci_writel(host,reg_val, AT_STAT_R);
|
||||
|
||||
for(i = 0; i < timeout; i += 10){
|
||||
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
|
||||
if(ctrl_2 & SDHCI_CTRL_TUNED_CLK)
|
||||
return 0;
|
||||
udelay(10);
|
||||
}
|
||||
pr_warn("%s: _rxclk_sw_tuned_sample_delay_set timeout %d\n",host->hw_name,timeout);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void snps_rxclk_sw_tuned_sample_delay_dump(struct sdhci_host *host)
|
||||
{
|
||||
pr_info("PHY_SMPLDL_CNFG_R = %x\n",sdhci_readb(host, PHY_SMPLDL_CNFG_R));
|
||||
pr_info("AT_CTRL_R = %x\n", sdhci_readl(host, AT_CTRL_R));
|
||||
pr_info("AT_STAT_R = %x\n", sdhci_readl(host, AT_STAT_R));
|
||||
pr_info("SDHCI_HOST_CONTROL2 = %x\n",sdhci_readw(host, SDHCI_HOST_CONTROL2));
|
||||
}
|
||||
|
||||
static void snps_sdhci_set_phy(struct sdhci_host *host)
|
||||
{
|
||||
@@ -289,12 +349,6 @@ static void snps_sdhci_reset(struct sdhci_host *host, u8 mask)
|
||||
pltfm_host = sdhci_priv(host);
|
||||
priv = sdhci_pltfm_priv(pltfm_host);
|
||||
|
||||
/*soc reset, fix host reset error*/
|
||||
//soc_reg = readl( priv->soc_base);
|
||||
//soc_reg &= ~1;
|
||||
//writel(soc_reg, priv->soc_base);
|
||||
//soc_reg |= 1;
|
||||
//writel(soc_reg, priv->soc_base);
|
||||
|
||||
/*host reset*/
|
||||
sdhci_reset(host, mask);
|
||||
@@ -390,7 +444,7 @@ static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
|
||||
ctrl_2 |= SDHCI_CTRL_VDD_180;
|
||||
|
||||
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
|
||||
|
||||
pr_debug("%s: %s timing %d\n",host->hw_name,__func__,timing);
|
||||
if (timing == MMC_TIMING_MMC_HS400) {
|
||||
// //disable delay lane
|
||||
// sdhci_writeb(host, 1 << UPDATE_DC, PHY_SDCLKDL_CNFG_R);
|
||||
@@ -406,10 +460,18 @@ static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
|
||||
reg &= ~1;
|
||||
sdhci_writel(host, reg, AT_CTRL_R);
|
||||
|
||||
delay_line = HS400_DELAY_LINE;
|
||||
priv->clk_delay_set = priv->delay_line[MMC_TIMING_MMC_HS400];
|
||||
snps_sdhci_set_phy(host); /* update tx delay*/
|
||||
} else if(timing == MMC_TIMING_UHS_SDR104){
|
||||
priv->clk_delay_set = priv->delay_line[MMC_TIMING_UHS_SDR104];
|
||||
snps_sdhci_set_phy(host); /* update tx delay*/
|
||||
} else {
|
||||
sdhci_writeb(host, 0, PHY_DLLDL_CNFG_R);
|
||||
}else {
|
||||
sdhci_writeb(host, 0, PHY_DLLDL_CNFG_R);
|
||||
if(priv->rxclk_sw_tune_en && (timing == MMC_TIMING_SD_HS)){
|
||||
snps_rxclk_sw_tuned_sample_delay_set(host,priv->rxclk_delay_set,10000);
|
||||
//snps_rxclk_sw_tuned_sample_delay_dump(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +533,8 @@ static void dwcmshc_set_power_noreg(struct sdhci_host *host, unsigned char mode,
|
||||
unsigned short vdd)
|
||||
{
|
||||
u8 pwr = 0;
|
||||
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
|
||||
if (mode != MMC_POWER_OFF) {
|
||||
switch (1 << vdd) {
|
||||
case MMC_VDD_165_195:
|
||||
@@ -509,6 +572,8 @@ static void dwcmshc_set_power_noreg(struct sdhci_host *host, unsigned char mode,
|
||||
return;
|
||||
|
||||
host->pwr = pwr;
|
||||
pr_debug("%s: %s set pwr %d\n",host->hw_name,__func__,pwr);
|
||||
priv->clk_delay_set = priv->delay_line[0];
|
||||
snps_sdhci_set_phy(host);
|
||||
|
||||
if (pwr == 0) {
|
||||
@@ -579,6 +644,20 @@ static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = {
|
||||
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
|
||||
};
|
||||
|
||||
static int device_property_get_clk_delay(struct device *dev,
|
||||
const char *propname, u32 *val)
|
||||
{
|
||||
int ret = device_property_read_u32(dev, propname, val);
|
||||
if(ret < 0){
|
||||
return ret;
|
||||
}
|
||||
if(*val > 0xff){
|
||||
pr_info("Note: invalid clk delay property :%s, val: %u\n",propname,*val);
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dwcmshc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host;
|
||||
@@ -604,13 +683,31 @@ static int dwcmshc_probe(struct platform_device *pdev)
|
||||
pltfm_host = sdhci_priv(host);
|
||||
priv = sdhci_pltfm_priv(pltfm_host);
|
||||
|
||||
/*used fix sdhci reset error*/
|
||||
priv->soc_base = devm_platform_ioremap_resource(pdev, 1);
|
||||
|
||||
if (device_property_present(&pdev->dev, "is_emmc")) {
|
||||
priv->is_emmc_card = 1;
|
||||
|
||||
if(device_property_get_clk_delay(&pdev->dev, "clk-delay-default", &(priv->delay_line[0]) ) < 0 )
|
||||
priv->delay_line[0] = 50;
|
||||
if(device_property_get_clk_delay(&pdev->dev, "clk-delay-mmc-hs400", &(priv->delay_line[MMC_TIMING_MMC_HS400]) ) < 0 )
|
||||
priv->delay_line[MMC_TIMING_MMC_HS400] = HS400_DELAY_LINE;
|
||||
} else {
|
||||
priv->is_emmc_card = 0;
|
||||
|
||||
if(device_property_get_clk_delay(&pdev->dev, "clk-delay-default", &(priv->delay_line[0]) ) < 0 )
|
||||
priv->delay_line[0] = 0x7d;
|
||||
if(device_property_get_clk_delay(&pdev->dev, "clk-delay-uhs-sdr104", &(priv->delay_line[MMC_TIMING_UHS_SDR104]) ) < 0 )
|
||||
priv->delay_line[MMC_TIMING_UHS_SDR104] = 0x32;
|
||||
|
||||
|
||||
if(device_property_get_clk_delay(&pdev->dev, "rxclk-sample-delay", &(priv->rxclk_delay_set) ) == 0 ){
|
||||
priv->rxclk_sw_tune_en = 1;
|
||||
dev_info(&pdev->dev,"rxclk-sample-delay get val = 0x%x\n",priv->rxclk_delay_set);
|
||||
|
||||
}
|
||||
else {
|
||||
priv->rxclk_sw_tune_en = 0;
|
||||
priv->rxclk_delay_set = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (device_property_present(&pdev->dev, "pull_up")) {
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#define PHY_SDCLKDL_DC_R (DWC_MSHC_PTR_PHY_R + 0x1e)
|
||||
#define PHY_SMPLDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x20)
|
||||
#define SMPLDL_CNFG_EXTDLY_EN 0x0 //1bit
|
||||
|
||||
#define PHY_ATDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x21)
|
||||
#define INPSEL_CNFG 2 //2bit
|
||||
|
||||
@@ -72,4 +74,6 @@
|
||||
#define POST_CHANGE_DLY 0x13 //2bit
|
||||
#define SWIN_TH_VAL 0x18 //9bit
|
||||
|
||||
#define AT_STAT_R (P_VENDOR_SPECIFIC_AREA + 0x44) // 32bit
|
||||
#define AT_STAT_CENTER_PH_CODE 0x0 //0-7bit
|
||||
#endif /* _SDHCI_OF_DWCMSHC_H_*/
|
||||
|
||||
@@ -25,6 +25,16 @@ config STMMAC_SELFTESTS
|
||||
feature if you are facing problems with your HW and submit the test
|
||||
results to the netdev Mailing List.
|
||||
|
||||
config STMMAC_RX_ZERO_COPY
|
||||
bool "Support for STMMAC Zero Copy in Recv"
|
||||
default n
|
||||
help
|
||||
This adds support for STMMAC reduce memcpy packet ring_buffer data
|
||||
to skb data in stmmac_rx. Enable this feature will alloc skb in filling
|
||||
ring buffer, mapping skb->data to ring buffer DMA addr.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config STMMAC_PLATFORM
|
||||
tristate "STMMAC Platform bus support"
|
||||
depends on STMMAC_ETH
|
||||
|
||||
@@ -67,12 +67,18 @@ struct stmmac_rx_buffer {
|
||||
dma_addr_t addr;
|
||||
dma_addr_t sec_addr;
|
||||
};
|
||||
|
||||
struct stmmac_rx_skbuffer {
|
||||
struct sk_buff *rx_skbuff;
|
||||
struct page *sec_page;
|
||||
dma_addr_t addr;
|
||||
dma_addr_t sec_addr;
|
||||
};
|
||||
struct stmmac_rx_queue {
|
||||
u32 rx_count_frames;
|
||||
u32 queue_index;
|
||||
struct page_pool *page_pool;
|
||||
struct stmmac_rx_buffer *buf_pool;
|
||||
struct stmmac_rx_skbuffer *skbuf_pool;
|
||||
struct stmmac_priv *priv_data;
|
||||
struct dma_extended_desc *dma_erx;
|
||||
struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
|
||||
@@ -210,6 +216,7 @@ struct stmmac_priv {
|
||||
unsigned int mode;
|
||||
unsigned int chain_mode;
|
||||
int extend_desc;
|
||||
bool extend_stat_need;
|
||||
struct hwtstamp_config tstamp_config;
|
||||
struct ptp_clock *ptp_clock;
|
||||
struct ptp_clock_info ptp_clock_ops;
|
||||
|
||||
@@ -1324,7 +1324,7 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv)
|
||||
for (queue = 0; queue < tx_queue_cnt; queue++)
|
||||
stmmac_clear_tx_descriptors(priv, queue);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
/**
|
||||
* stmmac_init_rx_buffers - init the RX descriptor buffer.
|
||||
* @priv: driver private structure
|
||||
@@ -1335,18 +1335,21 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv)
|
||||
* Description: this function is called to allocate a receive buffer, perform
|
||||
* the DMA mapping and init the descriptor.
|
||||
*/
|
||||
static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
|
||||
static int __stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
|
||||
int i, gfp_t flags, u32 queue)
|
||||
{
|
||||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
|
||||
gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
|
||||
if (priv->dma_cap.addr64 <= 32)
|
||||
gfp |= GFP_DMA32;
|
||||
|
||||
buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->page = page_pool_alloc_pages(rx_q->page_pool,gfp);
|
||||
if (!buf->page)
|
||||
return -ENOMEM;
|
||||
|
||||
if (priv->sph) {
|
||||
buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->sec_page = page_pool_alloc_pages(rx_q->page_pool,gfp);
|
||||
if (!buf->sec_page)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1364,14 +1367,13 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_free_rx_buffer - free RX dma buffers
|
||||
* @priv: private structure
|
||||
* @queue: RX queue index
|
||||
* @i: buffer index.
|
||||
*/
|
||||
static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i)
|
||||
static void __stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i)
|
||||
{
|
||||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
|
||||
@@ -1385,6 +1387,122 @@ static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i)
|
||||
buf->sec_page = NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline unsigned int stmmac_get_rx_buf_frsize(struct stmmac_priv *priv)
|
||||
{
|
||||
return priv->dma_buf_sz;
|
||||
}
|
||||
|
||||
#define STMMAC_RX_ALIGN 0x3f
|
||||
static int
|
||||
stmmac_get_skb_dma_addr(struct stmmac_priv *priv,struct sk_buff *skb,dma_addr_t *dma_addr)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = ((unsigned long)skb->data) & STMMAC_RX_ALIGN;
|
||||
if (off)
|
||||
skb_reserve(skb, STMMAC_RX_ALIGN + 1 - off);
|
||||
*dma_addr = dma_map_single(priv->device,skb->data,stmmac_get_rx_buf_frsize(priv) - off,DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(priv->device, *dma_addr)) {
|
||||
//if (net_ratelimit())
|
||||
netdev_err(priv->dev, "Rx DMA memory map failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* stmmac_init_rx_skbuffers - init the RX descriptor buffer.
|
||||
* @priv: driver private structure
|
||||
* @p: descriptor pointer
|
||||
* @i: descriptor index
|
||||
* @flags: gfp flag
|
||||
* @queue: RX queue index
|
||||
* Description: this function is called to allocate a receive buffer, perform
|
||||
* the DMA mapping and init the descriptor.
|
||||
*/
|
||||
static int __stmmac_init_rx_skbuffers(struct stmmac_priv *priv, struct dma_desc *p,
|
||||
int i, gfp_t flags, u32 queue)
|
||||
{
|
||||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
struct stmmac_rx_skbuffer *buf = &rx_q->skbuf_pool[i];
|
||||
struct sk_buff *skb = NULL;
|
||||
gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
|
||||
if (priv->dma_cap.addr64 <= 32)
|
||||
gfp |= GFP_DMA32;
|
||||
|
||||
skb = netdev_alloc_skb(priv->dev, stmmac_get_rx_buf_frsize(priv));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
if(stmmac_get_skb_dma_addr(priv,skb,&buf->addr) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (priv->sph) {
|
||||
buf->sec_page = page_pool_alloc_pages(rx_q->page_pool,gfp);
|
||||
if (!buf->sec_page)
|
||||
return -ENOMEM;
|
||||
|
||||
buf->sec_addr = page_pool_get_dma_addr(buf->sec_page);
|
||||
stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true);
|
||||
} else {
|
||||
buf->sec_page = NULL;
|
||||
stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false);
|
||||
}
|
||||
stmmac_set_desc_addr(priv, p, buf->addr);
|
||||
if (priv->dma_buf_sz == BUF_SIZE_16KiB)
|
||||
stmmac_init_desc3(priv, p);
|
||||
buf->rx_skbuff = skb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_free_rx_skbuffer - free RX dma buffers
|
||||
* @priv: private structure
|
||||
* @queue: RX queue index
|
||||
* @i: buffer index.
|
||||
*/
|
||||
static void __stmmac_free_rx_skbuffer(struct stmmac_priv *priv, u32 queue, int i)
|
||||
{
|
||||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
struct stmmac_rx_skbuffer *buf = &rx_q->skbuf_pool[i];
|
||||
|
||||
if (buf->rx_skbuff){
|
||||
dma_unmap_single(priv->device,
|
||||
buf->addr,
|
||||
stmmac_get_rx_buf_frsize(priv) - STMMAC_RX_ALIGN,
|
||||
DMA_FROM_DEVICE);
|
||||
dev_kfree_skb(buf->rx_skbuff);
|
||||
buf->rx_skbuff = NULL;
|
||||
}
|
||||
|
||||
if (buf->sec_page)
|
||||
page_pool_put_full_page(rx_q->page_pool, buf->sec_page, false);
|
||||
buf->sec_page = NULL;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
|
||||
int i, gfp_t flags, u32 queue)
|
||||
{
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
return __stmmac_init_rx_buffers(priv,p,i,flags,queue);
|
||||
#else
|
||||
return __stmmac_init_rx_skbuffers(priv,p,i,flags,queue);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i)
|
||||
{
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
__stmmac_free_rx_buffer(priv,queue,i);
|
||||
#else
|
||||
__stmmac_free_rx_skbuffer(priv,queue,i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_free_tx_buffer - free RX dma buffers
|
||||
* @priv: private structure
|
||||
@@ -1644,8 +1762,11 @@ static void free_dma_rx_desc_resources(struct stmmac_priv *priv)
|
||||
dma_free_coherent(priv->device, priv->dma_rx_size *
|
||||
sizeof(struct dma_extended_desc),
|
||||
rx_q->dma_erx, rx_q->dma_rx_phy);
|
||||
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
kfree(rx_q->buf_pool);
|
||||
#else
|
||||
kfree(rx_q->skbuf_pool);
|
||||
#endif
|
||||
if (rx_q->page_pool)
|
||||
page_pool_destroy(rx_q->page_pool);
|
||||
}
|
||||
@@ -1711,7 +1832,6 @@ static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv)
|
||||
|
||||
rx_q->queue_index = queue;
|
||||
rx_q->priv_data = priv;
|
||||
|
||||
pp_params.flags = PP_FLAG_DMA_MAP;
|
||||
pp_params.pool_size = priv->dma_rx_size;
|
||||
num_pages = DIV_ROUND_UP(priv->dma_buf_sz, PAGE_SIZE);
|
||||
@@ -1726,13 +1846,19 @@ static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv)
|
||||
rx_q->page_pool = NULL;
|
||||
goto err_dma;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
rx_q->buf_pool = kcalloc(priv->dma_rx_size,
|
||||
sizeof(*rx_q->buf_pool),
|
||||
GFP_KERNEL);
|
||||
if (!rx_q->buf_pool)
|
||||
goto err_dma;
|
||||
|
||||
#else
|
||||
rx_q->skbuf_pool = kcalloc(priv->dma_rx_size,
|
||||
sizeof(*rx_q->skbuf_pool),
|
||||
GFP_KERNEL);
|
||||
if (!rx_q->skbuf_pool)
|
||||
goto err_dma;
|
||||
#endif
|
||||
if (priv->extend_desc) {
|
||||
rx_q->dma_erx = dma_alloc_coherent(priv->device,
|
||||
priv->dma_rx_size *
|
||||
@@ -3664,27 +3790,37 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
|
||||
struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
|
||||
int len, dirty = stmmac_rx_dirty(priv, queue);
|
||||
unsigned int entry = rx_q->dirty_rx;
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
struct stmmac_rx_buffer *buf;
|
||||
#else
|
||||
struct stmmac_rx_skbuffer *buf ;
|
||||
struct sk_buff *skb = NULL;
|
||||
#endif
|
||||
gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
|
||||
|
||||
if (priv->dma_cap.addr64 <= 32)
|
||||
gfp |= GFP_DMA32;
|
||||
|
||||
len = DIV_ROUND_UP(priv->dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
|
||||
|
||||
while (dirty-- > 0) {
|
||||
struct stmmac_rx_buffer *buf = &rx_q->buf_pool[entry];
|
||||
struct dma_desc *p;
|
||||
bool use_rx_wd;
|
||||
|
||||
if (priv->extend_desc)
|
||||
p = (struct dma_desc *)(rx_q->dma_erx + entry);
|
||||
else
|
||||
p = rx_q->dma_rx + entry;
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
buf = &rx_q->buf_pool[entry];
|
||||
|
||||
if (!buf->page) {
|
||||
buf->page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->page = page_pool_alloc_pages(rx_q->page_pool,gfp);
|
||||
if (!buf->page)
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->sph && !buf->sec_page) {
|
||||
buf->sec_page = page_pool_dev_alloc_pages(rx_q->page_pool);
|
||||
buf->sec_page = page_pool_alloc_pages(rx_q->page_pool,gfp);
|
||||
if (!buf->sec_page)
|
||||
break;
|
||||
|
||||
@@ -3695,12 +3831,47 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
|
||||
}
|
||||
|
||||
buf->addr = page_pool_get_dma_addr(buf->page);
|
||||
/* Sync whole allocation to device. This will invalidate old
|
||||
* data.
|
||||
*/
|
||||
dma_sync_single_for_device(priv->device, buf->addr, len,
|
||||
DMA_FROM_DEVICE);
|
||||
#else
|
||||
buf = &rx_q->skbuf_pool[entry];
|
||||
|
||||
if(likely(!buf->rx_skbuff)){
|
||||
len = stmmac_get_rx_buf_frsize(priv);
|
||||
skb = netdev_alloc_skb(priv->dev, len);
|
||||
if (!skb){
|
||||
//priv->dev->stats.rx_dropped += (1ul<<32);
|
||||
netdev_err(priv->dev, "%s: dalloc_skb failed,dirty ring %d :\n", __func__,dirty);
|
||||
break;
|
||||
}
|
||||
if(stmmac_get_skb_dma_addr(priv,skb,&buf->addr) < 0){
|
||||
//priv->dev->stats.rx_dropped += (1ul<<32);
|
||||
break;
|
||||
}
|
||||
buf->rx_skbuff = skb;
|
||||
}
|
||||
|
||||
/* Sync whole allocation to device. This will invalidate old
|
||||
* data.
|
||||
*/
|
||||
dma_sync_single_for_device(priv->device, buf->addr, len,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
if (priv->sph && !buf->sec_page) {
|
||||
buf->sec_page = page_pool_alloc_pages(rx_q->page_pool,gfp);
|
||||
if (!buf->sec_page)
|
||||
break;
|
||||
|
||||
buf->sec_addr = page_pool_get_dma_addr(buf->sec_page);
|
||||
|
||||
dma_sync_single_for_device(priv->device, buf->sec_addr,
|
||||
len, DMA_FROM_DEVICE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
stmmac_set_desc_addr(priv, p, buf->addr);
|
||||
if (priv->sph)
|
||||
@@ -3815,7 +3986,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
|
||||
while (count < limit) {
|
||||
unsigned int buf1_len = 0, buf2_len = 0;
|
||||
enum pkt_hash_types hash_type;
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
struct stmmac_rx_buffer *buf;
|
||||
#else
|
||||
struct stmmac_rx_skbuffer *skbuf;
|
||||
#endif
|
||||
struct dma_desc *np, *p;
|
||||
int entry;
|
||||
u32 hash;
|
||||
@@ -3838,8 +4013,11 @@ read_again:
|
||||
buf1_len = 0;
|
||||
buf2_len = 0;
|
||||
entry = next_entry;
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
buf = &rx_q->buf_pool[entry];
|
||||
|
||||
#else
|
||||
skbuf = &rx_q->skbuf_pool[entry];
|
||||
#endif
|
||||
if (priv->extend_desc)
|
||||
p = (struct dma_desc *)(rx_q->dma_erx + entry);
|
||||
else
|
||||
@@ -3863,12 +4041,14 @@ read_again:
|
||||
|
||||
prefetch(np);
|
||||
|
||||
if (priv->extend_desc)
|
||||
if (priv->extend_desc && priv->extend_stat_need)
|
||||
stmmac_rx_extended_status(priv, &priv->dev->stats,
|
||||
&priv->xstats, rx_q->dma_erx + entry);
|
||||
if (unlikely(status == discard_frame)) {
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
page_pool_recycle_direct(rx_q->page_pool, buf->page);
|
||||
buf->page = NULL;
|
||||
#endif
|
||||
error = 1;
|
||||
if (!priv->hwts_rx_en)
|
||||
priv->dev->stats.rx_errors++;
|
||||
@@ -3884,11 +4064,14 @@ read_again:
|
||||
}
|
||||
|
||||
/* Buffer is good. Go on. */
|
||||
|
||||
#ifndef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
prefetch(page_address(buf->page));
|
||||
if (buf->sec_page)
|
||||
prefetch(page_address(buf->sec_page));
|
||||
|
||||
#else
|
||||
skb = skbuf->rx_skbuff;
|
||||
prefetch(skb->data);
|
||||
#endif
|
||||
buf1_len = stmmac_rx_buf1_len(priv, p, status, len);
|
||||
len += buf1_len;
|
||||
buf2_len = stmmac_rx_buf2_len(priv, p, status, len);
|
||||
@@ -3911,7 +4094,30 @@ read_again:
|
||||
|
||||
len -= ETH_FCS_LEN;
|
||||
}
|
||||
#ifdef CONFIG_STMMAC_RX_ZERO_COPY
|
||||
skb = skbuf->rx_skbuff;
|
||||
if (!skb) {
|
||||
priv->dev->stats.rx_dropped++;
|
||||
count++;
|
||||
goto drain_data;
|
||||
}
|
||||
dma_sync_single_for_cpu(priv->device, skbuf->addr,
|
||||
buf1_len, DMA_FROM_DEVICE);
|
||||
skb_put(skb, buf1_len);
|
||||
skbuf->rx_skbuff = NULL;
|
||||
|
||||
if (buf2_len) {
|
||||
dma_sync_single_for_cpu(priv->device, skbuf->sec_addr,
|
||||
buf2_len, DMA_FROM_DEVICE);
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
|
||||
skbuf->sec_page, 0, buf2_len,
|
||||
priv->dma_buf_sz);
|
||||
|
||||
/* Data payload appended into SKB */
|
||||
page_pool_release_page(rx_q->page_pool, skbuf->sec_page);
|
||||
skbuf->sec_page = NULL;
|
||||
}
|
||||
#else
|
||||
if (!skb) {
|
||||
skb = napi_alloc_skb(&ch->rx_napi, buf1_len);
|
||||
if (!skb) {
|
||||
@@ -3952,7 +4158,7 @@ read_again:
|
||||
page_pool_release_page(rx_q->page_pool, buf->sec_page);
|
||||
buf->sec_page = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
drain_data:
|
||||
if (likely(status & rx_not_ls))
|
||||
goto read_again;
|
||||
@@ -4104,8 +4310,12 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
|
||||
new_mtu = STMMAC_ALIGN(new_mtu);
|
||||
|
||||
/* If condition true, FIFO is too small or MTU too large */
|
||||
if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB))
|
||||
if ((txfifosz && txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)){
|
||||
netdev_err(priv->dev,"FIFO is too small or MTU too large\n");
|
||||
printk("new_mtu %d -- %d,%d,%d \n",new_mtu,txfifosz,priv->plat->tx_fifo_size,priv->dma_cap.tx_fifo_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
dev->mtu = mtu;
|
||||
|
||||
@@ -5083,6 +5293,11 @@ int stmmac_dvr_probe(struct device *device,
|
||||
priv->dma_cap.addr64 = 32;
|
||||
}
|
||||
}
|
||||
if(priv->dma_cap.addr64 <= 32){
|
||||
skb_set_alloc_dma32(GFP_DMA32);
|
||||
}
|
||||
dev_info(priv->device, "Using %d bits DMA width,skb alloc dma32 flag %x\n",
|
||||
priv->dma_cap.addr64,skb_get_alloc_dma32());
|
||||
|
||||
ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
|
||||
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
|
||||
|
||||
@@ -18,9 +18,18 @@
|
||||
#include <dt-bindings/pinctrl/light-fm-right-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-left-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-aon-pinctrl.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-audio-pinctrl.h>
|
||||
|
||||
#include "../core.h"
|
||||
|
||||
enum light_pinctrl_type {
|
||||
LIGHT_MPW,
|
||||
LIGHT_FM_RIGHT,
|
||||
LIGHT_FM_LEFT,
|
||||
LIGHT_FM_AON,
|
||||
LIGHT_FM_AUDIO,
|
||||
};
|
||||
|
||||
struct light_pin {
|
||||
unsigned int pin_id;
|
||||
unsigned int mux_mode;
|
||||
@@ -50,6 +59,8 @@ struct light_pinctrl_soc_info {
|
||||
unsigned int grp_index;
|
||||
struct light_pmx_func *functions;
|
||||
unsigned int nfunctions;
|
||||
char *label;
|
||||
enum light_pinctrl_type type;
|
||||
|
||||
unsigned int cfg_off;
|
||||
unsigned int mux_off;
|
||||
@@ -66,6 +77,7 @@ struct light_pinctrl {
|
||||
#define LIGHT_PINCTRL_PIN(pin) PINCTRL_PIN(pin, #pin)
|
||||
#define LIGHT_PAD_CONFIG(idx) (priv->info->cfg_off + (idx >> 1) * 4)
|
||||
#define LIGHT_PAD_MUX(idx) (priv->info->mux_off + ((idx >> 3) * 4))
|
||||
#define LIGHT_AUDIO_PAD_MUX(idx) (priv->info->mux_off + ((idx >> 4) * 4))
|
||||
|
||||
static const char *pin_get_name_from_info(struct light_pinctrl_soc_info *info,
|
||||
const unsigned int pin_id)
|
||||
@@ -247,13 +259,31 @@ static int light_pmx_set(struct pinctrl_dev *pctldev, unsigned int selector,
|
||||
continue;
|
||||
}
|
||||
|
||||
mux = readl(priv->base + LIGHT_PAD_MUX(pin_id));
|
||||
shift = ((pin_id % 8) << 2);
|
||||
mux &= ~(0xF << shift); /* 4 mux bits for one pad */
|
||||
mux |= (pin->mux_mode << shift);
|
||||
writel(mux, priv->base + LIGHT_PAD_MUX(pin_id));
|
||||
dev_dbg(priv->dev, "write: offset 0x%x val 0x%x\n",
|
||||
LIGHT_PAD_MUX(pin_id), mux);
|
||||
if (info->type == LIGHT_FM_AUDIO) {
|
||||
if (pin->mux_mode == AUDIO_IO_GPIO) {
|
||||
mux = ~(1 << pin_id) & readl(priv->base);
|
||||
writel(mux, priv->base); /* Controlled by GPIO under AUDIO_SUBSYS */
|
||||
continue;
|
||||
}
|
||||
mux = (1 << pin_id) | readl(priv->base);
|
||||
writel(mux, priv->base);
|
||||
|
||||
mux = readl(priv->base + LIGHT_AUDIO_PAD_MUX(pin_id));
|
||||
shift = ((pin_id % 16) << 1);
|
||||
mux &= ~(0x3 << shift); /* 2 mux bits for one pad */
|
||||
mux |= (pin->mux_mode << shift);
|
||||
writel(mux, priv->base + LIGHT_AUDIO_PAD_MUX(pin_id));
|
||||
dev_dbg(priv->dev, "write: offset 0x%x val 0x%x\n",
|
||||
LIGHT_AUDIO_PAD_MUX(pin_id), mux);
|
||||
} else {
|
||||
mux = readl(priv->base + LIGHT_PAD_MUX(pin_id));
|
||||
shift = ((pin_id % 8) << 2);
|
||||
mux &= ~(0xF << shift); /* 4 mux bits for one pad */
|
||||
mux |= (pin->mux_mode << shift);
|
||||
writel(mux, priv->base + LIGHT_PAD_MUX(pin_id));
|
||||
dev_dbg(priv->dev, "write: offset 0x%x val 0x%x\n",
|
||||
LIGHT_PAD_MUX(pin_id), mux);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -430,7 +460,15 @@ static int light_pinctrl_parse_groups(struct device_node *np,
|
||||
struct light_pin *pin = &grp->pins[i];
|
||||
|
||||
pin->pin_id = be32_to_cpu(*list++);
|
||||
pin->mux_mode = be32_to_cpu(*list++) & 0xF;
|
||||
if (info->type == LIGHT_FM_AUDIO) {
|
||||
pin->mux_mode = be32_to_cpu(*list++);
|
||||
if (pin->mux_mode != AUDIO_IO_GPIO){
|
||||
pin->mux_mode &= 0x3;
|
||||
}
|
||||
} else {
|
||||
pin->mux_mode = be32_to_cpu(*list++) & 0xF;
|
||||
|
||||
}
|
||||
pin->config = be32_to_cpu(*list++) & 0xFFFF;
|
||||
grp->pin_ids[i] = grp->pins[i].pin_id;
|
||||
|
||||
@@ -841,6 +879,40 @@ static const struct pinctrl_pin_desc light_fm_aon_pinctrl_pads[] = {
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_PA30),
|
||||
};
|
||||
|
||||
static const struct pinctrl_pin_desc light_fm_audio_pinctrl_pads[] = {
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA0),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA1),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA2),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA3),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA4),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA5),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA6),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA7),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA8),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA9),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA10),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA11),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA12),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA13),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA14),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA15),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA16),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA17),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA18),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA19),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA20),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA21),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA22),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA23),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA24),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA25),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA26),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA27),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA28),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA29),
|
||||
LIGHT_PINCTRL_PIN(FM_AUDIO_IO_PA30),
|
||||
};
|
||||
|
||||
static int light_pinctrl_mpw_convert_pin_off(const unsigned int pin_id)
|
||||
{
|
||||
unsigned int cov_pin_id = pin_id;
|
||||
@@ -865,6 +937,7 @@ static int light_pinctrl_fm_aon_covert_pin_off(const unsigned int pin_id)
|
||||
static struct light_pinctrl_soc_info light_mpw_pinctrl_info = {
|
||||
.pins = light_mpw_pinctrl_pads,
|
||||
.npins = ARRAY_SIZE(light_mpw_pinctrl_pads),
|
||||
.type = LIGHT_MPW,
|
||||
.cfg_off = 0x4c,
|
||||
.mux_off = 0x404,
|
||||
.covert_pin_off = light_pinctrl_mpw_convert_pin_off,
|
||||
@@ -873,6 +946,7 @@ static struct light_pinctrl_soc_info light_mpw_pinctrl_info = {
|
||||
static struct light_pinctrl_soc_info light_fm_right_pinctrl_info = {
|
||||
.pins = light_fm_right_pinctrl_pads,
|
||||
.npins = ARRAY_SIZE(light_fm_right_pinctrl_pads),
|
||||
.type = LIGHT_FM_RIGHT,
|
||||
.cfg_off = 0x0,
|
||||
.mux_off = 0x400,
|
||||
};
|
||||
@@ -880,6 +954,7 @@ static struct light_pinctrl_soc_info light_fm_right_pinctrl_info = {
|
||||
static struct light_pinctrl_soc_info light_fm_left_pinctrl_info = {
|
||||
.pins = light_fm_left_pinctrl_pads,
|
||||
.npins = ARRAY_SIZE(light_fm_left_pinctrl_pads),
|
||||
.type = LIGHT_FM_LEFT,
|
||||
.cfg_off = 0x0,
|
||||
.mux_off = 0x400,
|
||||
};
|
||||
@@ -887,16 +962,27 @@ static struct light_pinctrl_soc_info light_fm_left_pinctrl_info = {
|
||||
static struct light_pinctrl_soc_info light_fm_aon_pinctrl_info = {
|
||||
.pins = light_fm_aon_pinctrl_pads,
|
||||
.npins = ARRAY_SIZE(light_fm_aon_pinctrl_pads),
|
||||
.type = LIGHT_FM_AON,
|
||||
.cfg_off = 0x0,
|
||||
.mux_off = 0x400,
|
||||
.covert_pin_off = light_pinctrl_fm_aon_covert_pin_off,
|
||||
};
|
||||
|
||||
static struct light_pinctrl_soc_info light_fm_audio_pinctrl_info = {
|
||||
.pins = light_fm_audio_pinctrl_pads,
|
||||
.npins = ARRAY_SIZE(light_fm_audio_pinctrl_pads),
|
||||
.label = "LIGHT-AUDIO-IO",
|
||||
.type = LIGHT_FM_AUDIO,
|
||||
.cfg_off = 0x0C,
|
||||
.mux_off = 0x4,
|
||||
};
|
||||
|
||||
static const struct of_device_id light_pinctrl_of_match[] = {
|
||||
{ .compatible = "thead,light-mpw-pinctrl", .data = &light_mpw_pinctrl_info},
|
||||
{ .compatible = "thead,light-fm-right-pinctrl", .data = &light_fm_right_pinctrl_info},
|
||||
{ .compatible = "thead,light-fm-left-pinctrl", .data = &light_fm_left_pinctrl_info},
|
||||
{ .compatible = "thead,light-fm-aon-pinctrl", .data = &light_fm_aon_pinctrl_info},
|
||||
{ .compatible = "thead,light-fm-audio-pinctrl", .data = &light_fm_audio_pinctrl_info},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_pinctrl_of_match);
|
||||
|
||||
@@ -34,6 +34,11 @@ struct light_src {
|
||||
enum light_src_registers {
|
||||
SRC_WDT0 = 0x0034,
|
||||
SRC_WDT1 = 0x0038,
|
||||
SRC_NPU = 0x01b0,
|
||||
};
|
||||
|
||||
enum light_vpsys_src_registers {
|
||||
SRC_FCE = 0x0004,
|
||||
};
|
||||
|
||||
static int light_reset_update(struct light_src *lightsrc,
|
||||
@@ -48,6 +53,11 @@ static int light_reset_update(struct light_src *lightsrc,
|
||||
static const struct light_src_signal light_src_signals[] = {
|
||||
[LIGHT_RESET_WDT0] = { SRC_WDT0, BIT(0) },
|
||||
[LIGHT_RESET_WDT1] = { SRC_WDT1, BIT(0) },
|
||||
[LIGHT_RESET_NPU] = { SRC_NPU, BIT(0) },
|
||||
};
|
||||
|
||||
static const struct light_src_signal light_vpsys_src_signals[] = {
|
||||
[LIGHT_RESET_FCE] = { SRC_FCE, BIT(0)|BIT(1)|BIT(4)|BIT(5) },
|
||||
};
|
||||
|
||||
static struct light_src *to_light_src(struct reset_controller_dev *rcdev)
|
||||
@@ -94,6 +104,15 @@ static const struct light_src_variant variant_light = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct light_src_variant variant_light_vpsys = {
|
||||
.signals = light_vpsys_src_signals,
|
||||
.signals_num = ARRAY_SIZE(light_vpsys_src_signals),
|
||||
.ops = {
|
||||
.assert = light_reset_assert,
|
||||
.deassert = light_reset_deassert,
|
||||
},
|
||||
};
|
||||
|
||||
static int light_reset_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct light_src *lightsrc;
|
||||
@@ -123,6 +142,7 @@ static int light_reset_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id light_reset_dt_ids[] = {
|
||||
{ .compatible = "thead,light-reset-src", .data = &variant_light },
|
||||
{ .compatible = "thead,light-vpsys-reset-src", .data = &variant_light_vpsys },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_reset_dt_ids);
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ config RPMSG_QCOM_SMD
|
||||
providing communication channels to remote processors in Qualcomm
|
||||
platforms.
|
||||
|
||||
config RPMSG_THEAD_LIGHT
|
||||
tristate "THEAD Light RPM Driver"
|
||||
depends on RPMSG
|
||||
|
||||
config RPMSG_VIRTIO
|
||||
tristate "Virtio RPMSG bus driver"
|
||||
depends on HAS_DMA
|
||||
|
||||
@@ -8,3 +8,4 @@ obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
|
||||
obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
|
||||
obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o
|
||||
obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o
|
||||
obj-$(CONFIG_RPMSG_THEAD_LIGHT) += light_rpmsg.o
|
||||
|
||||
763
drivers/rpmsg/light_rpmsg.c
Normal file
763
drivers/rpmsg/light_rpmsg.c
Normal file
@@ -0,0 +1,763 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited.
|
||||
*
|
||||
* derived from the omap-rpmsg implementation.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/virtio.h>
|
||||
#include <linux/virtio_config.h>
|
||||
#include <linux/virtio_ids.h>
|
||||
#include <linux/virtio_ring.h>
|
||||
#include <linux/light_rpmsg.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/light_rpmsg.h>
|
||||
|
||||
#define MBOX_MAX_MSG_LEN 28
|
||||
#define WJ_MBOX_SEND_MAX_MESSAGE_LENGTH 28
|
||||
#define HEXDUMP_BYTES_PER_LINE 28
|
||||
#define HEXDUMP_LINE_LEN ((HEXDUMP_BYTES_PER_LINE * 4) + 2)
|
||||
#define HEXDUMP_MAX_LEN (HEXDUMP_LINE_LEN * \
|
||||
(MBOX_MAX_MSG_LEN / HEXDUMP_BYTES_PER_LINE))
|
||||
|
||||
//extern struct light_rpmsg_vproc *pri_rpdev;
|
||||
static struct dentry *root_debugfs_dir;
|
||||
|
||||
struct mbox_client_light_device {
|
||||
struct device *dev;
|
||||
void __iomem *tx_mmio;
|
||||
void __iomem *rx_mmio;
|
||||
struct mbox_chan *tx_channel;
|
||||
struct mbox_chan *rx_channel;
|
||||
char *rx_buffer;
|
||||
struct regmap *audio_mbox_regmap;
|
||||
char *message;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct mbox_client_light_device *tdev_priv;
|
||||
|
||||
static volatile uint32_t *p_mbox_reg;
|
||||
static volatile uint32_t *p_mbox_reg1;
|
||||
static volatile uint32_t *p_mbox_reg2;
|
||||
|
||||
/*
|
||||
* For now, allocate 256 buffers of 512 bytes for each side. each buffer
|
||||
* will then have 16B for the msg header and 496B for the payload.
|
||||
* This will require a total space of 256KB for the buffers themselves, and
|
||||
* 3 pages for every vring (the size of the vring depends on the number of
|
||||
* buffers it supports).
|
||||
*/
|
||||
#define RPMSG_NUM_BUFS (512)
|
||||
//#define RPMSG_BUF_SIZE (512)
|
||||
//#define RPMSG_BUFS_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
|
||||
|
||||
/*
|
||||
* The alignment between the consumer and producer parts of the vring.
|
||||
* Note: this is part of the "wire" protocol. If you change this, you need
|
||||
* to update your BIOS image as well
|
||||
*/
|
||||
#define RPMSG_VRING_ALIGN (4096)
|
||||
|
||||
/* With 256 buffers, our vring will occupy 3 pages */
|
||||
#define RPMSG_RING_SIZE ((DIV_ROUND_UP(vring_size(RPMSG_NUM_BUFS / 2, \
|
||||
RPMSG_VRING_ALIGN), PAGE_SIZE)) * PAGE_SIZE)
|
||||
|
||||
#define to_light_virdev(vd) container_of(vd, struct light_virdev, vdev)
|
||||
#define to_light_rpdev(vd, id) container_of(vd, struct light_rpmsg_vproc, ivdev[id])
|
||||
|
||||
struct light_rpmsg_vq_info {
|
||||
__u16 num; /* number of entries in the virtio_ring */
|
||||
__u16 vq_id; /* a globaly unique index of this virtqueue */
|
||||
void *addr; /* address where we mapped the virtio ring */
|
||||
struct light_rpmsg_vproc *rpdev;
|
||||
};
|
||||
|
||||
static u64 light_rpmsg_get_features(struct virtio_device *vdev)
|
||||
{
|
||||
/* VIRTIO_RPMSG_F_NS has been made private */
|
||||
return 1 << 0;
|
||||
}
|
||||
|
||||
static int light_rpmsg_finalize_features(struct virtio_device *vdev)
|
||||
{
|
||||
/* Give virtio_ring a chance to accept features */
|
||||
vring_transport_features(vdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* kick the remote processor, and let it know which virtqueue to poke at */
|
||||
static bool light_rpmsg_notify(struct virtqueue *vq)
|
||||
{
|
||||
unsigned int mu_rpmsg = 0;
|
||||
int ret;
|
||||
struct light_rpmsg_vq_info *rpvq = vq->priv;
|
||||
|
||||
mu_rpmsg = rpvq->vq_id << 16;
|
||||
mutex_lock(&rpvq->rpdev->lock);
|
||||
|
||||
//pr_info("light rpmsg: notify %d\n", rpvq->rpdev->first_notify);
|
||||
if (unlikely(rpvq->rpdev->first_notify > 0)) {
|
||||
rpvq->rpdev->first_notify--;
|
||||
if (!tdev_priv->tx_channel) {
|
||||
dev_err(tdev_priv->dev, "Channel cannot do Tx+++\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = mbox_send_message(tdev_priv->tx_channel, "Hello, Queue!");
|
||||
} else {
|
||||
*p_mbox_reg1 |= 1 << 0;
|
||||
*p_mbox_reg2 |= 1 << 0;
|
||||
}
|
||||
mutex_unlock(&rpvq->rpdev->lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int light_mu_rpmsg_callback(struct notifier_block *this,
|
||||
unsigned long index, void *data)
|
||||
{
|
||||
u32 mu_msg = (phys_addr_t) data;
|
||||
struct light_virdev *virdev;
|
||||
|
||||
virdev = container_of(this, struct light_virdev, nb);
|
||||
|
||||
pr_debug("light rpmsg: %s notifier_call mu_msg: 0x%x\n", __func__, mu_msg);
|
||||
/* ignore vq indices which are clearly not for us */
|
||||
mu_msg = mu_msg >> 16;
|
||||
if (mu_msg < virdev->base_vq_id || mu_msg > virdev->base_vq_id + 1) {
|
||||
pr_debug("light rpmsg: mu_msg 0x%x is invalid\n", mu_msg);
|
||||
//return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
mu_msg -= virdev->base_vq_id;
|
||||
pr_debug("%smu_msg 0x%xbase_vq_id 0x%xvirdev num_of_vqs0x%x\n", __func__, mu_msg, virdev->base_vq_id, virdev->num_of_vqs);
|
||||
|
||||
/*
|
||||
* Currently both PENDING_MSG and explicit-virtqueue-index
|
||||
* messaging are supported.
|
||||
* Whatever approach is taken, at this point 'mu_msg' contains
|
||||
* the index of the vring which was just triggered.
|
||||
*/
|
||||
//if (mu_msg < virdev->num_of_vqs)
|
||||
vring_interrupt(mu_msg, virdev->vq[mu_msg]);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int light_mu_rpmsg_register_nb(struct light_rpmsg_vproc *rpdev,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
if ((rpdev == NULL) || (nb == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
blocking_notifier_chain_register(&(rpdev->notifier), nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_mu_rpmsg_unregister_nb(struct light_rpmsg_vproc *rpdev,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
if ((rpdev == NULL) || (nb == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
blocking_notifier_chain_unregister(&(rpdev->notifier), nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
|
||||
unsigned int index,
|
||||
void (*callback)(struct virtqueue *vq),
|
||||
const char *name,
|
||||
bool ctx)
|
||||
{
|
||||
struct light_virdev *virdev = to_light_virdev(vdev);
|
||||
struct light_rpmsg_vproc *rpdev = to_light_rpdev(virdev,
|
||||
virdev->base_vq_id / 2);
|
||||
struct light_rpmsg_vq_info *rpvq;
|
||||
struct virtqueue *vq;
|
||||
int err;
|
||||
//static void __iomem *brd_io;
|
||||
|
||||
rpvq = kmalloc(sizeof(*rpvq), GFP_KERNEL);
|
||||
if (!rpvq)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* ioremap'ing normal memory, so we cast away sparse's complaints */
|
||||
//rpvq->addr = (__force void *) ioremap_nocache(virdev->vring[index],
|
||||
// RPMSG_RING_SIZE);
|
||||
rpvq->addr = (__force void *) ioremap(virdev->vring[index],
|
||||
RPMSG_RING_SIZE);
|
||||
if (!rpvq->addr) {
|
||||
err = -ENOMEM;
|
||||
goto free_rpvq;
|
||||
}
|
||||
|
||||
p_mbox_reg = ioremap(0xffefc48000,25);
|
||||
p_mbox_reg1 = p_mbox_reg + 4;
|
||||
p_mbox_reg2 = p_mbox_reg + 5;
|
||||
|
||||
memset_io(rpvq->addr, 0, RPMSG_RING_SIZE);
|
||||
|
||||
pr_debug("vring%d: phys 0x%x, virt 0x%p\n", index, virdev->vring[index],
|
||||
rpvq->addr);
|
||||
|
||||
vq = vring_new_virtqueue(index, RPMSG_NUM_BUFS / 2, RPMSG_VRING_ALIGN,
|
||||
vdev, true, ctx,
|
||||
rpvq->addr,
|
||||
light_rpmsg_notify, callback,
|
||||
name);
|
||||
if (!vq) {
|
||||
pr_err("light rpmsg: vring_new_virtqueue failed\n");
|
||||
err = -ENOMEM;
|
||||
goto unmap_vring;
|
||||
}
|
||||
|
||||
virdev->vq[index] = vq;
|
||||
vq->priv = rpvq;
|
||||
/* system-wide unique id for this virtqueue */
|
||||
rpvq->vq_id = virdev->base_vq_id + index;
|
||||
rpvq->rpdev = rpdev;
|
||||
mutex_init(&rpdev->lock);
|
||||
|
||||
return vq;
|
||||
|
||||
unmap_vring:
|
||||
/* iounmap normal memory, so make sparse happy */
|
||||
iounmap((__force void __iomem *) rpvq->addr);
|
||||
free_rpvq:
|
||||
kfree(rpvq);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static void light_rpmsg_del_vqs(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtqueue *vq, *n;
|
||||
struct light_virdev *virdev = to_light_virdev(vdev);
|
||||
struct light_rpmsg_vproc *rpdev = to_light_rpdev(virdev,
|
||||
virdev->base_vq_id / 2);
|
||||
|
||||
list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
|
||||
struct light_rpmsg_vq_info *rpvq = vq->priv;
|
||||
|
||||
iounmap(rpvq->addr);
|
||||
vring_del_virtqueue(vq);
|
||||
kfree(rpvq);
|
||||
}
|
||||
|
||||
if (&virdev->nb)
|
||||
light_mu_rpmsg_unregister_nb(rpdev, &virdev->nb);
|
||||
}
|
||||
|
||||
static int light_rpmsg_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
|
||||
struct virtqueue *vqs[],
|
||||
vq_callback_t *callbacks[],
|
||||
const char * const names[],
|
||||
const bool *ctx,
|
||||
struct irq_affinity *desc)
|
||||
{
|
||||
struct light_virdev *virdev = to_light_virdev(vdev);
|
||||
struct light_rpmsg_vproc *rpdev = to_light_rpdev(virdev,
|
||||
virdev->base_vq_id / 2);
|
||||
int i, err;
|
||||
|
||||
/* we maintain two virtqueues per remote processor (for RX and TX) */
|
||||
if (nvqs != 2)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < nvqs; ++i) {
|
||||
vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i],
|
||||
ctx ? ctx[i] : false);
|
||||
if (IS_ERR(vqs[i])) {
|
||||
err = PTR_ERR(vqs[i]);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
virdev->num_of_vqs = nvqs;
|
||||
|
||||
virdev->nb.notifier_call = light_mu_rpmsg_callback;
|
||||
light_mu_rpmsg_register_nb(rpdev, &virdev->nb);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
light_rpmsg_del_vqs(vdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void light_rpmsg_reset(struct virtio_device *vdev)
|
||||
{
|
||||
dev_dbg(&vdev->dev, "reset!\n");
|
||||
}
|
||||
|
||||
static u8 light_rpmsg_get_status(struct virtio_device *vdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void light_rpmsg_set_status(struct virtio_device *vdev, u8 status)
|
||||
{
|
||||
dev_dbg(&vdev->dev, "%s new status: %d\n", __func__, status);
|
||||
}
|
||||
|
||||
static void light_rpmsg_vproc_release(struct device *dev)
|
||||
{
|
||||
/* this handler is provided so driver core doesn't yell at us */
|
||||
}
|
||||
|
||||
static struct virtio_config_ops light_rpmsg_config_ops = {
|
||||
.get_features = light_rpmsg_get_features,
|
||||
.finalize_features = light_rpmsg_finalize_features,
|
||||
.find_vqs = light_rpmsg_find_vqs,
|
||||
.del_vqs = light_rpmsg_del_vqs,
|
||||
.reset = light_rpmsg_reset,
|
||||
.set_status = light_rpmsg_set_status,
|
||||
.get_status = light_rpmsg_get_status,
|
||||
};
|
||||
|
||||
static struct light_rpmsg_vproc light_rpmsg_vprocs[] = {
|
||||
{
|
||||
.rproc_name = "m4",
|
||||
},
|
||||
{
|
||||
.rproc_name = "m4",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct of_device_id light_rpmsg_dt_ids[] = {
|
||||
{ .compatible = "light,light-rpmsg", .data = (void *)LIGHT_RPMSG, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_rpmsg_dt_ids);
|
||||
|
||||
static int set_vring_phy_buf(struct platform_device *pdev,
|
||||
struct light_rpmsg_vproc *rpdev, int vdev_nums)
|
||||
{
|
||||
struct resource *res;
|
||||
resource_size_t size;
|
||||
unsigned int start, end;
|
||||
int i, ret = 0;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res) {
|
||||
size = resource_size(res);
|
||||
start = res->start;
|
||||
end = res->start + size;
|
||||
for (i = 0; i < vdev_nums; i++) {
|
||||
rpdev->ivdev[i].vring[0] = start;
|
||||
rpdev->ivdev[i].vring[1] = start +
|
||||
0x8000;
|
||||
start += 0x10000;
|
||||
if (start > end) {
|
||||
pr_err("Too small memory size %x!\n",
|
||||
(u32)size);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rpmsg_work_handler(struct work_struct *work)
|
||||
{
|
||||
u32 message = 0;
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct light_rpmsg_vproc *rpdev = container_of(dwork,
|
||||
struct light_rpmsg_vproc, rpmsg_work);
|
||||
|
||||
//spin_lock_irqsave(&rpdev->mu_lock, flags);
|
||||
blocking_notifier_call_chain(&(rpdev->notifier), 4,
|
||||
(void *)(phys_addr_t)message);
|
||||
//spin_unlock_irqrestore(&rpdev->mu_lock, flags);
|
||||
}
|
||||
|
||||
struct light_rpmsg_vproc *pri_rpdev;
|
||||
EXPORT_SYMBOL_GPL(pri_rpdev);
|
||||
|
||||
static int light_rpmsg_probe(struct platform_device *pdev)
|
||||
{
|
||||
int core_id, j, ret = 0;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct light_rpmsg_vproc *rpdev;
|
||||
|
||||
if (of_property_read_u32(np, "multi-core-id", &core_id))
|
||||
core_id = 0;
|
||||
rpdev = &light_rpmsg_vprocs[core_id];
|
||||
rpdev->core_id = core_id;
|
||||
rpdev->variant = (enum light_rpmsg_variants)of_device_get_match_data(dev);
|
||||
|
||||
spin_lock_init(&rpdev->mu_lock);
|
||||
|
||||
pri_rpdev = rpdev;
|
||||
|
||||
INIT_DELAYED_WORK(&(rpdev->rpmsg_work), rpmsg_work_handler);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&(rpdev->notifier));
|
||||
|
||||
pr_info("light rpmsg: Ready for cross core communication!\n");
|
||||
|
||||
ret = of_property_read_u32(np, "vdev-nums", &rpdev->vdev_nums);
|
||||
if (ret) {
|
||||
rpdev->vdev_nums = 1;
|
||||
}
|
||||
|
||||
if (rpdev->vdev_nums > MAX_VDEV_NUMS) {
|
||||
pr_err("light rpmsg: vdev-nums exceed the max %d\n", MAX_VDEV_NUMS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rpdev->first_notify = rpdev->vdev_nums;
|
||||
|
||||
pr_info("light rpmsg: rproc_name = %s",rpdev->rproc_name);
|
||||
if (!strcmp(rpdev->rproc_name, "m4")) {
|
||||
ret = set_vring_phy_buf(pdev, rpdev,
|
||||
rpdev->vdev_nums);
|
||||
if (ret) {
|
||||
pr_err("light rpmsg: No vring buffer.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
pr_err("light rpmsg: No remote processor.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (j = 0; j < rpdev->vdev_nums; j++) {
|
||||
pr_debug("%s rpdev%d vdev%d: vring0 0x%x, vring1 0x%x\n",
|
||||
__func__, rpdev->core_id, rpdev->vdev_nums,
|
||||
rpdev->ivdev[j].vring[0],
|
||||
rpdev->ivdev[j].vring[1]);
|
||||
rpdev->ivdev[j].vdev.id.device = VIRTIO_ID_RPMSG;
|
||||
rpdev->ivdev[j].vdev.config = &light_rpmsg_config_ops;
|
||||
rpdev->ivdev[j].vdev.dev.parent = &pdev->dev;
|
||||
rpdev->ivdev[j].vdev.dev.release = light_rpmsg_vproc_release;
|
||||
rpdev->ivdev[j].base_vq_id = j * 2;
|
||||
|
||||
ret = register_virtio_device(&rpdev->ivdev[j].vdev);
|
||||
if (ret) {
|
||||
pr_err("light rpmsg: %s failed to register rpdev: %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
platform_set_drvdata(pdev, rpdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int light_rpmsg_suspend(struct device *dev)
|
||||
{
|
||||
struct light_rpmsg_vproc *rpdev = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(rpdev->mu_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_rpmsg_resume(struct device *dev)
|
||||
{
|
||||
struct light_rpmsg_vproc *rpdev = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(rpdev->mu_clk);
|
||||
if (ret) {
|
||||
pr_err("unable to enable mu clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(light_rpmsg_pm_ops, light_rpmsg_suspend, light_rpmsg_resume);
|
||||
|
||||
static struct platform_driver light_rpmsg_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "light-rpmsg",
|
||||
.of_match_table = light_rpmsg_dt_ids,
|
||||
.pm = &light_rpmsg_pm_ops,
|
||||
},
|
||||
.probe = light_rpmsg_probe,
|
||||
};
|
||||
|
||||
static int __init light_rpmsg_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&light_rpmsg_driver);
|
||||
if (ret)
|
||||
pr_err("light rpmsg: Unable to initialize\n");
|
||||
else
|
||||
pr_info("light rpmsg: driver is registered.\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MODULE_AUTHOR(",Inc.");
|
||||
MODULE_DESCRIPTION("remote processor messaging virtio device");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
late_initcall(light_rpmsg_init);
|
||||
|
||||
static ssize_t mbox_client_light_message_write(struct file *filp,
|
||||
const char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct mbox_client_light_device *tdev = filp->private_data;
|
||||
void *data;
|
||||
int ret;
|
||||
|
||||
if (!tdev->tx_channel) {
|
||||
dev_err(tdev->dev, "Channel cannot do Tx\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (count > WJ_MBOX_SEND_MAX_MESSAGE_LENGTH)
|
||||
count = WJ_MBOX_SEND_MAX_MESSAGE_LENGTH;
|
||||
|
||||
tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
|
||||
if (!tdev->message)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = copy_from_user(tdev->message, userbuf, count);
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data = tdev->message;
|
||||
print_hex_dump(KERN_INFO, __func__, DUMP_PREFIX_NONE, 16, 1, tdev->message, MBOX_MAX_MSG_LEN, true);
|
||||
|
||||
ret = mbox_send_message(tdev->tx_channel, data);
|
||||
if (ret < 0)
|
||||
dev_err(tdev->dev, "Failed to send message via mailbox\n");
|
||||
|
||||
out:
|
||||
kfree(tdev->message);
|
||||
return ret < 0 ? ret : count;
|
||||
}
|
||||
|
||||
static ssize_t mbox_client_light_message_read(struct file *filp,
|
||||
char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct mbox_client_light_device *tdev = filp->private_data;
|
||||
unsigned long flags;
|
||||
|
||||
print_hex_dump(KERN_INFO, __func__, DUMP_PREFIX_NONE, 16, 1, tdev->rx_buffer, MBOX_MAX_MSG_LEN, true);
|
||||
spin_lock_irqsave(&tdev->lock, flags);
|
||||
memset(tdev->rx_buffer, 0, MBOX_MAX_MSG_LEN);
|
||||
spin_unlock_irqrestore(&tdev->lock, flags);
|
||||
|
||||
return MBOX_MAX_MSG_LEN;
|
||||
}
|
||||
|
||||
static const struct file_operations mbox_client_light_message_ops = {
|
||||
.write = mbox_client_light_message_write,
|
||||
.read = mbox_client_light_message_read,
|
||||
.open = simple_open,
|
||||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
static int index_names = 0;
|
||||
static bool debugfs_dir_created = false;
|
||||
static const char* file_names[] = {"mbox-client0", "mbox-client1"};
|
||||
|
||||
static int mbox_client_light_add_debugfs(struct platform_device *pdev,
|
||||
struct mbox_client_light_device *tdev)
|
||||
{
|
||||
if (!debugfs_initialized())
|
||||
return 0;
|
||||
|
||||
if (index_names > 2) {
|
||||
dev_err(&pdev->dev, "Max device index is 2\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!debugfs_dir_created) {
|
||||
root_debugfs_dir = debugfs_create_dir("mailbox",NULL);
|
||||
if (!root_debugfs_dir) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to create mailbox debugfs\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
debugfs_dir_created = true;
|
||||
}
|
||||
|
||||
debugfs_create_file(file_names[index_names], 0600, root_debugfs_dir,
|
||||
tdev, &mbox_client_light_message_ops);
|
||||
|
||||
index_names++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mbox_client_light_receive_message(struct mbox_client *client,
|
||||
void *message)
|
||||
{
|
||||
struct mbox_client_light_device *tdev = dev_get_drvdata(client->dev);
|
||||
char *data = message;
|
||||
|
||||
spin_lock(&tdev->lock);
|
||||
memcpy(tdev->rx_buffer, data, MBOX_MAX_MSG_LEN);
|
||||
spin_unlock(&tdev->lock);
|
||||
|
||||
//printk("mbox_client receive rpmsg_work\n");
|
||||
schedule_delayed_work(&(pri_rpdev->rpmsg_work), 0);
|
||||
|
||||
//print_hex_dump(KERN_INFO, __func__, DUMP_PREFIX_NONE, 16, 1, tdev->rx_buffer, MBOX_MAX_MSG_LEN, true);
|
||||
}
|
||||
|
||||
static struct mbox_chan *
|
||||
mbox_client_light_request_channel(struct platform_device *pdev,
|
||||
const char *name)
|
||||
{
|
||||
struct mbox_client *client;
|
||||
struct mbox_chan *channel;
|
||||
|
||||
client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
|
||||
if (!client)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
client->dev = &pdev->dev;
|
||||
client->tx_block = true;
|
||||
client->knows_txdone = false;
|
||||
client->tx_tout = 500;
|
||||
client->rx_callback = mbox_client_light_receive_message;
|
||||
|
||||
channel = mbox_request_channel_byname(client, name);
|
||||
if (IS_ERR(channel)) {
|
||||
devm_kfree(&pdev->dev, client);
|
||||
dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static int mbox_client_light_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mbox_client_light_device *tdev;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
int ret;
|
||||
|
||||
static int chan_idx = 1;
|
||||
|
||||
tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
|
||||
if (!tdev)
|
||||
return -ENOMEM;
|
||||
|
||||
tdev_priv = tdev;
|
||||
|
||||
if (!chan_idx)
|
||||
tdev->tx_channel = mbox_client_light_request_channel(pdev, "902");
|
||||
else
|
||||
tdev->tx_channel = mbox_client_light_request_channel(pdev, "906");
|
||||
|
||||
if (!tdev->tx_channel) {
|
||||
dev_err(&pdev->dev, "Request channel failed\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
chan_idx++;
|
||||
|
||||
/* In fact, rx_channel is same with tx_channel in C-SKY's mailbox */
|
||||
tdev->rx_channel = tdev->tx_channel;
|
||||
|
||||
tdev->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, tdev);
|
||||
|
||||
tdev->audio_mbox_regmap = syscon_regmap_lookup_by_phandle(np, "audio-mbox-regmap");
|
||||
if (IS_ERR(tdev->audio_mbox_regmap)) {
|
||||
dev_err(&pdev->dev, "cannot find regmap for audio mbox register\n");
|
||||
} else {
|
||||
dev_dbg(&pdev->dev, "audio_mbox_regmap ok\n");
|
||||
}
|
||||
|
||||
spin_lock_init(&tdev->lock);
|
||||
|
||||
tdev->rx_buffer = devm_kzalloc(&pdev->dev,
|
||||
MBOX_MAX_MSG_LEN, GFP_KERNEL);
|
||||
if (!tdev->rx_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mbox_client_light_add_debugfs(pdev, tdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_err(&pdev->dev, "Successfully registered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbox_client_light_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mbox_client_light_device *tdev = platform_get_drvdata(pdev);
|
||||
|
||||
debugfs_remove_recursive(root_debugfs_dir);
|
||||
|
||||
if (tdev->tx_channel)
|
||||
mbox_free_channel(tdev->tx_channel);
|
||||
|
||||
if (tdev->rx_channel && tdev->rx_channel != tdev->tx_channel)
|
||||
mbox_free_channel(tdev->rx_channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mbox_client_light_match[] = {
|
||||
{ .compatible = "thead,light-mbox-client" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver mbox_client_light_driver = {
|
||||
.driver = {
|
||||
.name = "thead,light-mbox-client",
|
||||
.of_match_table = mbox_client_light_match,
|
||||
},
|
||||
.probe = mbox_client_light_probe,
|
||||
.remove = mbox_client_light_remove,
|
||||
};
|
||||
module_platform_driver(mbox_client_light_driver);
|
||||
|
||||
MODULE_AUTHOR("Alibaba Group Holding Limited");
|
||||
MODULE_DESCRIPTION("Thead Light mailbox IPC client driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -521,7 +521,16 @@ static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev)
|
||||
put_device(&ctrldev->dev);
|
||||
}
|
||||
|
||||
static struct rpmsg_device_id rpmsg_driver_char_id_table[] = {
|
||||
{ .name = "rpmsg-virtual-char-channel-1" },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
||||
MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_char_id_table);
|
||||
|
||||
static struct rpmsg_driver rpmsg_chrdev_driver = {
|
||||
.id_table = rpmsg_driver_char_id_table,
|
||||
.probe = rpmsg_chrdev_probe,
|
||||
.remove = rpmsg_chrdev_remove,
|
||||
.drv = {
|
||||
|
||||
@@ -158,7 +158,7 @@ struct virtio_rpmsg_channel {
|
||||
* processor.
|
||||
*/
|
||||
#define MAX_RPMSG_NUM_BUFS (512)
|
||||
#define MAX_RPMSG_BUF_SIZE (512)
|
||||
#define MAX_RPMSG_BUF_SIZE (4096)
|
||||
|
||||
/*
|
||||
* Local addresses are dynamically allocated on-demand.
|
||||
|
||||
@@ -16,6 +16,12 @@ config LIGHT_SUSPEND
|
||||
help
|
||||
This driver supports system suspend low power feature in Light FM platform
|
||||
|
||||
config LIGHT_REBOOTMODE
|
||||
bool "Thead light rebootmode support"
|
||||
default y
|
||||
help
|
||||
This driver supports check rebootmode feature in Light FM platform
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_LIGHT_IOPMP) += light-iopmp.o
|
||||
obj-$(CONFIG_LIGHT_SUSPEND) += pm-light.o
|
||||
obj-$(CONFIG_LIGHT_REBOOTMODE) += light_event.o
|
||||
|
||||
278
drivers/soc/thead/light_event.c
Normal file
278
drivers/soc/thead/light_event.c
Normal file
@@ -0,0 +1,278 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/firmware/thead/ipc.h>
|
||||
#include <linux/firmware/thead/light_event.h>
|
||||
|
||||
/*
|
||||
* AON SRAM total size is 0x10000, reserve 0x100 for event.
|
||||
* Notice: c902 *.ld also need resize.
|
||||
* -------------- 0xff_ffef8000
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | c902 |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* -------------- 0xff_fff07f00
|
||||
* | reserve |
|
||||
* | |
|
||||
* --------------
|
||||
*/
|
||||
#define LIGHT_AON_SRAM_LEN 0x10000
|
||||
#define LIGHT_AON_SRAM_RESERV (LIGHT_AON_SRAM_LEN - 0x100)
|
||||
#define LIGHT_EVENT_OFFSET (LIGHT_AON_SRAM_RESERV + 0x10)
|
||||
#define LIGHT_EVENT_CHECK (LIGHT_EVENT_OFFSET + 0x4)
|
||||
|
||||
#define LIGHT_EVENT_MAGIC 0x5A5A5A5A
|
||||
|
||||
struct light_aon_msg_event_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u32 reserve_offset;
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct light_event {
|
||||
struct device *dev;
|
||||
|
||||
struct light_aon_ipc *ipc_handle;
|
||||
struct light_aon_msg_event_ctrl msg;
|
||||
|
||||
struct regmap *aon_iram;
|
||||
bool init;
|
||||
};
|
||||
|
||||
struct light_event *light_event;
|
||||
|
||||
static void light_event_msg_hdr_fill(struct light_aon_rpc_msg_hdr *hdr, enum light_aon_misc_func func)
|
||||
{
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->func = (uint8_t)func;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
}
|
||||
|
||||
static int light_event_aon_reservemem(struct light_event *event)
|
||||
{
|
||||
struct light_aon_ipc *ipc = event->ipc_handle;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(light_event->dev, "aon reservemem...\n");
|
||||
|
||||
light_event_msg_hdr_fill(&event->msg.hdr, LIGHT_AON_MISC_FUNC_AON_RESERVE_MEM);
|
||||
event->msg.reserve_offset = LIGHT_EVENT_OFFSET;
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &event->msg, true);
|
||||
if (ret)
|
||||
dev_err(light_event->dev, "failed to set aon reservemem\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int light_event_set_rebootmode(enum light_rebootmode_index mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!light_event->init)
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_write(light_event->aon_iram, LIGHT_EVENT_OFFSET, mode);
|
||||
if (ret) {
|
||||
dev_err(light_event->dev, "set rebootmode failed,ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(light_event->dev, "set rebootmode:0x%x\n", mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(light_event_set_rebootmode);
|
||||
|
||||
int light_event_get_rebootmode(enum light_rebootmode_index *mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!light_event->init)
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_read(light_event->aon_iram, LIGHT_EVENT_OFFSET, mode);
|
||||
if (ret) {
|
||||
dev_err(light_event->dev, "get rebootmode failed,ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
dev_dbg(light_event->dev, "%s get rebootmode:0x%x\n", __func__, *mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(light_event_get_rebootmode);
|
||||
|
||||
static int light_event_check_powerup(void)
|
||||
{
|
||||
enum light_rebootmode_index mode;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
if (!light_event->init)
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_read(light_event->aon_iram, LIGHT_EVENT_CHECK, &val);
|
||||
if (ret) {
|
||||
dev_err(light_event->dev, "get magicnum failed,ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = regmap_read(light_event->aon_iram, LIGHT_EVENT_OFFSET, &mode);
|
||||
if (ret) {
|
||||
dev_err(light_event->dev, "get rebootmode failed,ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
dev_info(light_event->dev, "magicnum:0x%x mode:0x%x\n", val, mode);
|
||||
|
||||
/* powerup means SRAM data is randam */
|
||||
if (val != LIGHT_EVENT_MAGIC && mode != LIGHT_EVENT_PMIC_ONKEY)
|
||||
light_event_set_rebootmode(LIGHT_EVENT_PMIC_POWERUP);
|
||||
|
||||
ret = regmap_write(light_event->aon_iram, LIGHT_EVENT_CHECK, LIGHT_EVENT_MAGIC);
|
||||
if (ret) {
|
||||
dev_err(light_event->dev, "set magicnum failed,ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rebootmode_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
enum light_rebootmode_index mode;
|
||||
|
||||
if (kstrtouint(buf, 0, &mode) < 0)
|
||||
return -EINVAL;
|
||||
light_event_set_rebootmode(mode);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
rebootmode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
enum light_rebootmode_index mode;
|
||||
|
||||
light_event_get_rebootmode(&mode);
|
||||
|
||||
return sprintf(buf, "0x%x\n", mode);
|
||||
}
|
||||
static DEVICE_ATTR_RW(rebootmode);
|
||||
|
||||
static struct attribute *event_attrs[] = {
|
||||
&dev_attr_rebootmode.attr,
|
||||
NULL
|
||||
};
|
||||
ATTRIBUTE_GROUPS(event);
|
||||
|
||||
static int light_event_open(struct inode *inode, struct file *f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_event_release(struct inode *inode, struct file *f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long light_event_ioctl(struct file *f, unsigned int ioctl,
|
||||
unsigned long arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations light_event_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.release = light_event_release,
|
||||
.open = light_event_open,
|
||||
.unlocked_ioctl = light_event_ioctl,
|
||||
};
|
||||
|
||||
static struct miscdevice light_event_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "light-event",
|
||||
.fops = &light_event_fops,
|
||||
};
|
||||
|
||||
static int light_event_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct light_event *thead;
|
||||
int ret;
|
||||
|
||||
thead = devm_kzalloc(&pdev->dev, sizeof(*thead), GFP_KERNEL);
|
||||
if (!thead)
|
||||
return -ENOMEM;
|
||||
light_event = thead;
|
||||
|
||||
ret = light_aon_get_handle(&(thead->ipc_handle));
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, thead);
|
||||
thead->dev = &pdev->dev;
|
||||
|
||||
thead->aon_iram = syscon_regmap_lookup_by_phandle(np, "aon-iram-regmap");
|
||||
if (IS_ERR(thead->aon_iram))
|
||||
return PTR_ERR(thead->aon_iram);
|
||||
|
||||
ret = misc_register(&light_event_misc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = light_event_aon_reservemem(thead);
|
||||
if (ret) {
|
||||
dev_err(dev, "set aon reservemem failed!\n");
|
||||
return -EPERM;
|
||||
}
|
||||
thead->init = true;
|
||||
|
||||
ret = light_event_check_powerup();
|
||||
if (ret) {
|
||||
dev_err(dev, "check powerup failed!\n");
|
||||
return -EPERM;
|
||||
}
|
||||
dev_info(dev, "light-event driver init successfully\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_event_remove(struct platform_device *pdev)
|
||||
{
|
||||
misc_deregister(&light_event_misc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id light_event_of_match[] = {
|
||||
{ .compatible = "thead,light-event" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_event_of_match);
|
||||
|
||||
static struct platform_driver light_event_driver = {
|
||||
.probe = light_event_probe,
|
||||
.remove = light_event_remove,
|
||||
.driver = {
|
||||
.name = "light-event",
|
||||
.dev_groups = event_groups,
|
||||
.of_match_table = light_event_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(light_event_driver);
|
||||
|
||||
MODULE_DESCRIPTION("light-event driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -73,6 +73,14 @@
|
||||
#define USB3_DRD_PRST BIT(0)
|
||||
#define USB3_DRD_MASK GENMASK(2, 0)
|
||||
|
||||
/* USB as host or device*/
|
||||
#define USB_AS_HOST (true)
|
||||
#define USB_AS_DEVICE (false)
|
||||
|
||||
static bool usb_role = USB_AS_HOST;
|
||||
module_param(usb_role, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(usb_role, "USB role");
|
||||
|
||||
struct dwc3_thead {
|
||||
struct device *dev;
|
||||
struct platform_device *dwc3;
|
||||
@@ -255,9 +263,10 @@ static int dwc3_thead_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, thead);
|
||||
thead->dev = &pdev->dev;
|
||||
|
||||
thead->hubswitch = devm_gpiod_get(dev, "hubswitch", GPIOD_OUT_HIGH);
|
||||
thead->hubswitch = devm_gpiod_get(dev, "hubswitch", (usb_role == USB_AS_DEVICE) ? GPIOD_OUT_LOW : GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(thead->hubswitch))
|
||||
dev_dbg(dev, "no need to get hubswitch GPIO\n");
|
||||
dev_info(dev, "hubswitch usb_role = %d\n", usb_role);
|
||||
|
||||
thead->vbus = devm_regulator_get(dev, "vbus");
|
||||
if (IS_ERR(thead->vbus))
|
||||
|
||||
@@ -1226,6 +1226,12 @@ static int virtio_vdmabuf_create_dmabuf(struct virtio_vdmabuf *vdmabuf,
|
||||
exp_info.flags = O_RDWR;
|
||||
exp_info.priv = exp_buf;
|
||||
|
||||
unsigned int gfp = GFP_KERNEL;
|
||||
if(attr->flags & VIRTIO_VDAMBUF_DMA32)
|
||||
{
|
||||
gfp |= __GFP_DMA32;
|
||||
}
|
||||
|
||||
switch (heap_type) {
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_USER:
|
||||
return -EINVAL; /* Not support currently */
|
||||
@@ -1235,7 +1241,7 @@ static int virtio_vdmabuf_create_dmabuf(struct virtio_vdmabuf *vdmabuf,
|
||||
exp_buf->bp_num = npages;
|
||||
|
||||
for (i = 0; i < npages; i++) {
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
page = alloc_page(gfp);
|
||||
if (!page) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc;
|
||||
@@ -1253,7 +1259,7 @@ static int virtio_vdmabuf_create_dmabuf(struct virtio_vdmabuf *vdmabuf,
|
||||
/* only need 1 bp to record Compound Page */
|
||||
exp_buf->bp_num = 1;
|
||||
|
||||
page = alloc_pages(GFP_KERNEL, get_order(exp_buf->size));
|
||||
page = alloc_pages(gfp, get_order(exp_buf->size));
|
||||
if (!page) {
|
||||
ret = -ENOMEM;
|
||||
goto err_exp;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/reset.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/firmware/thead/light_event.h>
|
||||
|
||||
#define WDOG_CONTROL_REG_OFFSET 0x00
|
||||
#define WDOG_CONTROL_REG_WDT_EN_MASK 0x01
|
||||
@@ -376,6 +377,7 @@ static irqreturn_t dw_wdt_irq(int irq, void *devid)
|
||||
pr_warn("watchdog irq enter. however status is 0\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
light_event_set_rebootmode(LIGHT_EVENT_SW_WATCHDOG);
|
||||
|
||||
WARN(1, "watchdog app was stuck! watchdog pretimeout event\n");
|
||||
watchdog_notify_pretimeout(&dw_wdt->wdd);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/firmware/thead/ipc.h>
|
||||
#include <linux/firmware/thead/light_event.h>
|
||||
|
||||
#define DRV_NAME "light-wdt"
|
||||
|
||||
@@ -189,6 +190,7 @@ static int light_wdt_restart(struct watchdog_device *wdd, unsigned long action,
|
||||
|
||||
pr_debug("[%s,%d]: Inform aon to restart the whole system....\n", __func__, __LINE__);
|
||||
|
||||
light_event_set_rebootmode(LIGHT_EVENT_SW_REBOOT);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#define __WRITE_ONCE(x, val) \
|
||||
do { \
|
||||
*(volatile typeof(x) *)&(x) = (val); \
|
||||
smp_mb(); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_ONCE(x, val) \
|
||||
|
||||
35
include/dt-bindings/clock/light-audiosys.h
Normal file
35
include/dt-bindings/clock/light-audiosys.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#ifndef _LIGHT_AUDIOSYS_H_
|
||||
#define _LIGHT_AUDIOSYS_H_
|
||||
|
||||
#define LIGHT_CLKGEN_AUDIO_CPU 0
|
||||
#define LIGHT_CLKGEN_AUDIO_SRAM0 1
|
||||
#define LIGHT_CLKGEN_AUDIO_SRAM1 2
|
||||
#define LIGHT_CLKGEN_AUDIO_DMA 3
|
||||
#define LIGHT_CLKGEN_AUDIO_BSM 4
|
||||
#define LIGHT_CLKGEN_AUDIO_TIMER 5
|
||||
#define LIGHT_CLKGEN_AUDIO_TIMER_CNT1 6
|
||||
#define LIGHT_CLKGEN_AUDIO_TIMER_CNT2 7
|
||||
#define LIGHT_CLKGEN_AUDIO_TIMER_CNT3 8
|
||||
#define LIGHT_CLKGEN_AUDIO_TIMER_CNT4 9
|
||||
#define LIGHT_CLKGEN_AUDIO_WDR 10
|
||||
#define LIGHT_CLKGEN_AUDIO_I2C0 11
|
||||
#define LIGHT_CLKGEN_AUDIO_I2C1 12
|
||||
#define LIGHT_CLKGEN_AUDIO_UART 13
|
||||
#define LIGHT_CLKGEN_AUDIO_I2S0 14
|
||||
#define LIGHT_CLKGEN_AUDIO_I2S1 15
|
||||
#define LIGHT_CLKGEN_AUDIO_I2S2 16
|
||||
#define LIGHT_CLKGEN_AUDIO_I2S8CH 17
|
||||
#define LIGHT_CLKGEN_AUDIO_TDM 18
|
||||
#define LIGHT_CLKGEN_AUDIO_GPIO 19
|
||||
#define LIGHT_CLKGEN_AUDIO_SPDIF0 20
|
||||
#define LIGHT_CLKGEN_AUDIO_SPDIF1 21
|
||||
#define LIGHT_CLKGEN_AUDIO_VAD 22
|
||||
#define LIGHT_CLKGEN_AUDIO_IOMUX 23
|
||||
#define LIGHT_CLKGEN_AUDIO_CLK_END 24
|
||||
|
||||
#endif
|
||||
38
include/dt-bindings/pinctrl/light-fm-audio-pinctrl.h
Normal file
38
include/dt-bindings/pinctrl/light-fm-audio-pinctrl.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef _LIGHT_FM_AUDIO_IO_PINCTRL_H
|
||||
#define _LIGHT_FM_AUDIO_IO_PINCTRL_H
|
||||
|
||||
#define FM_AUDIO_IO_PA0 0
|
||||
#define FM_AUDIO_IO_PA1 1
|
||||
#define FM_AUDIO_IO_PA2 2
|
||||
#define FM_AUDIO_IO_PA3 3
|
||||
#define FM_AUDIO_IO_PA4 4
|
||||
#define FM_AUDIO_IO_PA5 5
|
||||
#define FM_AUDIO_IO_PA6 6
|
||||
#define FM_AUDIO_IO_PA7 7
|
||||
#define FM_AUDIO_IO_PA8 8
|
||||
#define FM_AUDIO_IO_PA9 9
|
||||
#define FM_AUDIO_IO_PA10 10
|
||||
#define FM_AUDIO_IO_PA11 11
|
||||
#define FM_AUDIO_IO_PA12 12
|
||||
#define FM_AUDIO_IO_PA13 13
|
||||
#define FM_AUDIO_IO_PA14 14
|
||||
#define FM_AUDIO_IO_PA15 15
|
||||
#define FM_AUDIO_IO_PA16 16
|
||||
#define FM_AUDIO_IO_PA17 17
|
||||
#define FM_AUDIO_IO_PA18 18
|
||||
#define FM_AUDIO_IO_PA19 19
|
||||
#define FM_AUDIO_IO_PA20 20
|
||||
#define FM_AUDIO_IO_PA21 21
|
||||
#define FM_AUDIO_IO_PA22 22
|
||||
#define FM_AUDIO_IO_PA23 23
|
||||
#define FM_AUDIO_IO_PA24 24
|
||||
#define FM_AUDIO_IO_PA25 25
|
||||
#define FM_AUDIO_IO_PA26 26
|
||||
#define FM_AUDIO_IO_PA27 27
|
||||
#define FM_AUDIO_IO_PA28 28
|
||||
#define FM_AUDIO_IO_PA29 29
|
||||
#define FM_AUDIO_IO_PA30 30
|
||||
|
||||
#define AUDIO_IO_GPIO 0xF /* Flag set to gpio */
|
||||
|
||||
#endif /* _LIGHT_FM_AUDIO_IO_PINCTRL_H */
|
||||
36
include/dt-bindings/pinctrl/light-fm-pinctrl-def.h
Normal file
36
include/dt-bindings/pinctrl/light-fm-pinctrl-def.h
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
#ifndef __DT_BINDINGS_LIGHT_FM_PINCTRL_DEF_H__
|
||||
#define __DT_BINDINGS_LIGHT_FM_PINCTRL_DEF_H__
|
||||
|
||||
#define LIGHT_PIN_PULL_NONE 0
|
||||
#define LIGHT_PIN_PULL_DOWN 1
|
||||
#define LIGHT_PIN_PULL_UP 2
|
||||
|
||||
#define LIGHT_PIN_DRV_LV0 0
|
||||
#define LIGHT_PIN_DRV_LV1 1
|
||||
#define LIGHT_PIN_DRV_LV2 2
|
||||
#define LIGHT_PIN_DRV_LV3 3
|
||||
#define LIGHT_PIN_DRV_LV4 4
|
||||
#define LIGHT_PIN_DRV_LV5 5
|
||||
#define LIGHT_PIN_DRV_LV6 6
|
||||
#define LIGHT_PIN_DRV_LV7 7
|
||||
#define LIGHT_PIN_DRV_LV8 8
|
||||
#define LIGHT_PIN_DRV_LV9 9
|
||||
#define LIGHT_PIN_DRV_LV10 10
|
||||
#define LIGHT_PIN_DRV_LV11 11
|
||||
#define LIGHT_PIN_DRV_LV12 12
|
||||
#define LIGHT_PIN_DRV_LV13 13
|
||||
#define LIGHT_PIN_DRV_LV14 14
|
||||
#define LIGHT_PIN_DRV_LV15 15
|
||||
|
||||
#define LIGHT_PIN_FUNC_0 0
|
||||
#define LIGHT_PIN_FUNC_1 1
|
||||
#define LIGHT_PIN_FUNC_2 2
|
||||
#define LIGHT_PIN_FUNC_3 3
|
||||
#define LIGHT_PIN_FUNC_4 4
|
||||
#define LIGHT_PIN_FUNC_5 5
|
||||
#define LIGHT_PIN_FUNC_6 6
|
||||
#define LIGHT_PIN_FUNC_7 7
|
||||
|
||||
#endif // __DT_BINDINGS_LIGHT_FM_PINCTRL_DEF_H__
|
||||
@@ -10,5 +10,10 @@
|
||||
|
||||
#define LIGHT_RESET_WDT0 0
|
||||
#define LIGHT_RESET_WDT1 1
|
||||
#define LIGHT_RESET_NPU 2
|
||||
|
||||
// vpsys reset
|
||||
#define LIGHT_RESET_FCE 100
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1472,6 +1472,9 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
|
||||
int bpf_prog_test_run_raw_tp(struct bpf_prog *prog,
|
||||
const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr);
|
||||
int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog,
|
||||
const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr);
|
||||
bool btf_ctx_access(int off, int size, enum bpf_access_type type,
|
||||
const struct bpf_prog *prog,
|
||||
struct bpf_insn_access_aux *info);
|
||||
@@ -1686,6 +1689,13 @@ static inline int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog,
|
||||
const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void bpf_map_put(struct bpf_map *map)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ enum light_aon_misc_func {
|
||||
LIGHT_AON_MISC_FUNC_WDG_POWER_OFF = 9,
|
||||
LIGHT_AON_MISC_FUNC_AON_WDT_ON = 10,
|
||||
LIGHT_AON_MISC_FUNC_AON_WDT_OFF = 11,
|
||||
LIGHT_AON_MISC_FUNC_AON_RESERVE_MEM = 12,
|
||||
};
|
||||
|
||||
enum light_aon_pm_func {
|
||||
|
||||
35
include/linux/firmware/thead/light_event.h
Normal file
35
include/linux/firmware/thead/light_event.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _LIGHT_EVENT_H
|
||||
#define _LIGHT_EVENT_H
|
||||
|
||||
enum light_rebootmode_index {
|
||||
/* C902 event rebootmode */
|
||||
LIGHT_EVENT_PMIC_RESET = 0x0,
|
||||
LIGHT_EVENT_PMIC_ONKEY,
|
||||
LIGHT_EVENT_PMIC_POWERUP,
|
||||
|
||||
/* C910 event rebootmode */
|
||||
LIGHT_EVENT_SW_REBOOT = 0x20,
|
||||
LIGHT_EVENT_SW_WATCHDOG,
|
||||
LIGHT_EVENT_SW_PANIC,
|
||||
LIGHT_EVENT_SW_HANG,
|
||||
LIGHT_EVENT_MAX,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_LIGHT_REBOOTMODE)
|
||||
extern int light_event_set_rebootmode(enum light_rebootmode_index mode);
|
||||
extern int light_event_get_rebootmode(enum light_rebootmode_index *mode);
|
||||
#else
|
||||
static int light_event_set_rebootmode(enum light_rebootmode_index mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int light_event_get_rebootmode(enum light_rebootmode_index *mode)
|
||||
{
|
||||
*mode = LIGHT_EVENT_MAX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
88
include/linux/light_rpmsg.h
Normal file
88
include/linux/light_rpmsg.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The code contained herein is licensed under the GNU Lesser General
|
||||
* Public License. You may obtain a copy of the GNU Lesser General
|
||||
* Public License Version 2.1 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/lgpl-license.html
|
||||
* http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file linux/light_rpmsg.h
|
||||
*
|
||||
* @brief Global header file for imx RPMSG
|
||||
*
|
||||
* @ingroup RPMSG
|
||||
*/
|
||||
#ifndef __LINUX_LIGHT_RPMSG_H__
|
||||
#define __LINUX_LIGHT_RPMSG_H__
|
||||
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/virtio.h>
|
||||
#include <linux/virtio_config.h>
|
||||
#include <linux/virtio_ids.h>
|
||||
#include <linux/virtio_ring.h>
|
||||
|
||||
/* Category define */
|
||||
#define LIGHT_RMPSG_LIFECYCLE 1
|
||||
#define LIGHT_RPMSG_PMIC 2
|
||||
#define LIGHT_RPMSG_AUDIO 3
|
||||
#define LIGHT_RPMSG_KEY 4
|
||||
#define LIGHT_RPMSG_GPIO 5
|
||||
#define LIGHT_RPMSG_RTC 6
|
||||
#define LIGHT_RPMSG_SENSOR 7
|
||||
/* rpmsg version */
|
||||
#define LIGHT_RMPSG_MAJOR 1
|
||||
#define LIGHT_RMPSG_MINOR 0
|
||||
|
||||
enum light_rpmsg_variants {
|
||||
LIGHTA,
|
||||
LIGHTB,
|
||||
LIGHT_RPMSG,
|
||||
};
|
||||
|
||||
struct light_virdev {
|
||||
struct virtio_device vdev;
|
||||
unsigned int vring[2];
|
||||
struct virtqueue *vq[2];
|
||||
int base_vq_id;
|
||||
int num_of_vqs;
|
||||
struct notifier_block nb;
|
||||
};
|
||||
|
||||
struct light_rpmsg_vproc {
|
||||
char *rproc_name;
|
||||
struct mutex lock;
|
||||
struct clk *mu_clk;
|
||||
enum light_rpmsg_variants variant;
|
||||
int vdev_nums;
|
||||
int first_notify;
|
||||
#define MAX_VDEV_NUMS 8
|
||||
struct light_virdev ivdev[MAX_VDEV_NUMS];
|
||||
void __iomem *mu_base;
|
||||
struct delayed_work rpmsg_work;
|
||||
struct blocking_notifier_head notifier;
|
||||
#define MAX_NUM 10 /* enlarge it if overflow happen */
|
||||
u32 m4_message[MAX_NUM];
|
||||
u32 in_idx;
|
||||
u32 out_idx;
|
||||
u32 core_id;
|
||||
spinlock_t mu_lock;
|
||||
};
|
||||
|
||||
struct light_rpmsg_head {
|
||||
u8 cate;
|
||||
u8 major;
|
||||
u8 minor;
|
||||
u8 type;
|
||||
u8 cmd;
|
||||
u8 reserved[5];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* __LINUX_LIGHT_RPMSG_H__*/
|
||||
|
||||
@@ -1088,6 +1088,8 @@ struct sk_buff *build_skb(void *data, unsigned int frag_size);
|
||||
struct sk_buff *build_skb_around(struct sk_buff *skb,
|
||||
void *data, unsigned int frag_size);
|
||||
|
||||
void skb_set_alloc_dma32(gfp_t gfp_dma32);
|
||||
gfp_t skb_get_alloc_dma32(void);
|
||||
/**
|
||||
* alloc_skb - allocate a network buffer
|
||||
* @size: size to allocate
|
||||
|
||||
@@ -5007,7 +5007,10 @@ struct bpf_pidns_info {
|
||||
|
||||
/* User accessible data for SK_LOOKUP programs. Add new fields at the end. */
|
||||
struct bpf_sk_lookup {
|
||||
__bpf_md_ptr(struct bpf_sock *, sk); /* Selected socket */
|
||||
union {
|
||||
__bpf_md_ptr(struct bpf_sock *, sk); /* Selected socket */
|
||||
__u64 cookie; /* Non-zero if socket was selected in PROG_TEST_RUN */
|
||||
};
|
||||
|
||||
__u32 family; /* Protocol family (AF_INET, AF_INET6) */
|
||||
__u32 protocol; /* IP protocol (IPPROTO_TCP, IPPROTO_UDP) */
|
||||
|
||||
@@ -17,7 +17,8 @@ _IOC(_IOC_NONE, 'G', 2, sizeof(struct virtio_vdmabuf_alloc))
|
||||
_IOC(_IOC_NONE, 'G', 3, sizeof(struct virtio_vdmabuf_import))
|
||||
|
||||
/* dmabuf flag */
|
||||
#define VIRTIO_VDAMBUF_NONCACHED 0x1
|
||||
#define VIRTIO_VDAMBUF_NONCACHED 0x1
|
||||
#define VIRTIO_VDAMBUF_DMA32 0x4
|
||||
|
||||
/*
|
||||
* Max single alloc size is (768 * PAGE_SIZE) only for
|
||||
|
||||
@@ -94,7 +94,7 @@ struct qnode {
|
||||
* progress.
|
||||
*/
|
||||
#ifndef _Q_PENDING_LOOPS
|
||||
#define _Q_PENDING_LOOPS 1
|
||||
#define _Q_PENDING_LOOPS 9
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <asm/sections.h>
|
||||
#include <linux/firmware/thead/light_event.h>
|
||||
|
||||
#define PANIC_TIMER_STEP 100
|
||||
#define PANIC_BLINK_SPD 18
|
||||
@@ -182,7 +183,11 @@ void panic(const char *fmt, ...)
|
||||
int state = 0;
|
||||
int old_cpu, this_cpu;
|
||||
bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
|
||||
enum light_rebootmode_index mode;
|
||||
|
||||
if (!light_event_get_rebootmode(&mode) &&
|
||||
mode != LIGHT_EVENT_SW_WATCHDOG)
|
||||
light_event_set_rebootmode(LIGHT_EVENT_SW_PANIC);
|
||||
/*
|
||||
* Disable local interrupts. This will prevent panic_smp_self_stop
|
||||
* from deadlocking the first cpu that invokes the panic, since
|
||||
|
||||
@@ -435,7 +435,7 @@ static bool rcu_preempt_has_tasks(struct rcu_node *rnp)
|
||||
* be quite short, for example, in the case of the call from
|
||||
* rcu_read_unlock_special().
|
||||
*/
|
||||
static void
|
||||
static notrace void
|
||||
rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
|
||||
{
|
||||
bool empty_exp;
|
||||
@@ -556,7 +556,7 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags)
|
||||
* is disabled. This function cannot be expected to understand these
|
||||
* nuances, so the caller must handle them.
|
||||
*/
|
||||
static bool rcu_preempt_need_deferred_qs(struct task_struct *t)
|
||||
static notrace bool rcu_preempt_need_deferred_qs(struct task_struct *t)
|
||||
{
|
||||
return (__this_cpu_read(rcu_data.exp_deferred_qs) ||
|
||||
READ_ONCE(t->rcu_read_unlock_special.s)) &&
|
||||
@@ -570,7 +570,7 @@ static bool rcu_preempt_need_deferred_qs(struct task_struct *t)
|
||||
* evaluate safety in terms of interrupt, softirq, and preemption
|
||||
* disabling.
|
||||
*/
|
||||
static void rcu_preempt_deferred_qs(struct task_struct *t)
|
||||
static notrace void rcu_preempt_deferred_qs(struct task_struct *t)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -897,11 +897,11 @@ static bool rcu_preempt_has_tasks(struct rcu_node *rnp)
|
||||
* Because there is no preemptible RCU, there can be no deferred quiescent
|
||||
* states.
|
||||
*/
|
||||
static bool rcu_preempt_need_deferred_qs(struct task_struct *t)
|
||||
static notrace bool rcu_preempt_need_deferred_qs(struct task_struct *t)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static void rcu_preempt_deferred_qs(struct task_struct *t) { }
|
||||
static notrace void rcu_preempt_deferred_qs(struct task_struct *t) { }
|
||||
|
||||
/*
|
||||
* Because there is no preemptible RCU, there can be no readers blocked,
|
||||
|
||||
@@ -328,10 +328,9 @@ restart:
|
||||
goto restart;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT_SOFTINT_OPTIMIZATION
|
||||
if (pending | deferred)
|
||||
wakeup_softirqd();
|
||||
#endif
|
||||
|
||||
lockdep_softirq_end(in_hardirq);
|
||||
account_irq_exit_time(current);
|
||||
__local_bh_enable(SOFTIRQ_OFFSET);
|
||||
|
||||
@@ -10,20 +10,86 @@
|
||||
#include <net/bpf_sk_storage.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <linux/error-injection.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/sock_diag.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/bpf_test_run.h>
|
||||
|
||||
struct bpf_test_timer {
|
||||
enum { NO_PREEMPT, NO_MIGRATE } mode;
|
||||
u32 i;
|
||||
u64 time_start, time_spent;
|
||||
};
|
||||
|
||||
static void bpf_test_timer_enter(struct bpf_test_timer *t)
|
||||
__acquires(rcu)
|
||||
{
|
||||
rcu_read_lock();
|
||||
if (t->mode == NO_PREEMPT)
|
||||
preempt_disable();
|
||||
else
|
||||
migrate_disable();
|
||||
|
||||
t->time_start = ktime_get_ns();
|
||||
}
|
||||
|
||||
static void bpf_test_timer_leave(struct bpf_test_timer *t)
|
||||
__releases(rcu)
|
||||
{
|
||||
t->time_start = 0;
|
||||
|
||||
if (t->mode == NO_PREEMPT)
|
||||
preempt_enable();
|
||||
else
|
||||
migrate_enable();
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static bool bpf_test_timer_continue(struct bpf_test_timer *t, u32 repeat, int *err, u32 *duration)
|
||||
__must_hold(rcu)
|
||||
{
|
||||
t->i++;
|
||||
if (t->i >= repeat) {
|
||||
/* We're done. */
|
||||
t->time_spent += ktime_get_ns() - t->time_start;
|
||||
do_div(t->time_spent, t->i);
|
||||
*duration = t->time_spent > U32_MAX ? U32_MAX : (u32)t->time_spent;
|
||||
*err = 0;
|
||||
goto reset;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
/* During iteration: we've been cancelled, abort. */
|
||||
*err = -EINTR;
|
||||
goto reset;
|
||||
}
|
||||
|
||||
if (need_resched()) {
|
||||
/* During iteration: we need to reschedule between runs. */
|
||||
t->time_spent += ktime_get_ns() - t->time_start;
|
||||
bpf_test_timer_leave(t);
|
||||
cond_resched();
|
||||
bpf_test_timer_enter(t);
|
||||
}
|
||||
|
||||
/* Do another round. */
|
||||
return true;
|
||||
|
||||
reset:
|
||||
t->i = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
|
||||
u32 *retval, u32 *time, bool xdp)
|
||||
{
|
||||
struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = { NULL };
|
||||
struct bpf_test_timer t = { NO_MIGRATE };
|
||||
enum bpf_cgroup_storage_type stype;
|
||||
u64 time_start, time_spent = 0;
|
||||
int ret = 0;
|
||||
u32 i;
|
||||
int ret;
|
||||
|
||||
for_each_cgroup_storage_type(stype) {
|
||||
storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
|
||||
@@ -38,10 +104,8 @@ static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
|
||||
if (!repeat)
|
||||
repeat = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
migrate_disable();
|
||||
time_start = ktime_get_ns();
|
||||
for (i = 0; i < repeat; i++) {
|
||||
bpf_test_timer_enter(&t);
|
||||
do {
|
||||
ret = bpf_cgroup_storage_set(storage);
|
||||
if (ret)
|
||||
break;
|
||||
@@ -53,29 +117,8 @@ static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
|
||||
|
||||
bpf_cgroup_storage_unset();
|
||||
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (need_resched()) {
|
||||
time_spent += ktime_get_ns() - time_start;
|
||||
migrate_enable();
|
||||
rcu_read_unlock();
|
||||
|
||||
cond_resched();
|
||||
|
||||
rcu_read_lock();
|
||||
migrate_disable();
|
||||
time_start = ktime_get_ns();
|
||||
}
|
||||
}
|
||||
time_spent += ktime_get_ns() - time_start;
|
||||
migrate_enable();
|
||||
rcu_read_unlock();
|
||||
|
||||
do_div(time_spent, repeat);
|
||||
*time = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
|
||||
} while (bpf_test_timer_continue(&t, repeat, &ret, time));
|
||||
bpf_test_timer_leave(&t);
|
||||
|
||||
for_each_cgroup_storage_type(stype)
|
||||
bpf_cgroup_storage_free(storage[stype]);
|
||||
@@ -688,18 +731,17 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
|
||||
const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr)
|
||||
{
|
||||
struct bpf_test_timer t = { NO_PREEMPT };
|
||||
u32 size = kattr->test.data_size_in;
|
||||
struct bpf_flow_dissector ctx = {};
|
||||
u32 repeat = kattr->test.repeat;
|
||||
struct bpf_flow_keys *user_ctx;
|
||||
struct bpf_flow_keys flow_keys;
|
||||
u64 time_start, time_spent = 0;
|
||||
const struct ethhdr *eth;
|
||||
unsigned int flags = 0;
|
||||
u32 retval, duration;
|
||||
void *data;
|
||||
int ret;
|
||||
u32 i;
|
||||
|
||||
if (prog->type != BPF_PROG_TYPE_FLOW_DISSECTOR)
|
||||
return -EINVAL;
|
||||
@@ -735,39 +777,15 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
|
||||
ctx.data = data;
|
||||
ctx.data_end = (__u8 *)data + size;
|
||||
|
||||
rcu_read_lock();
|
||||
preempt_disable();
|
||||
time_start = ktime_get_ns();
|
||||
for (i = 0; i < repeat; i++) {
|
||||
retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
|
||||
size, flags);
|
||||
bpf_test_timer_enter(&t);
|
||||
do {
|
||||
retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
|
||||
size, flags);
|
||||
} while (bpf_test_timer_continue(&t, repeat, &ret, &duration));
|
||||
bpf_test_timer_leave(&t);
|
||||
|
||||
if (signal_pending(current)) {
|
||||
preempt_enable();
|
||||
rcu_read_unlock();
|
||||
|
||||
ret = -EINTR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (need_resched()) {
|
||||
time_spent += ktime_get_ns() - time_start;
|
||||
preempt_enable();
|
||||
rcu_read_unlock();
|
||||
|
||||
cond_resched();
|
||||
|
||||
rcu_read_lock();
|
||||
preempt_disable();
|
||||
time_start = ktime_get_ns();
|
||||
}
|
||||
}
|
||||
time_spent += ktime_get_ns() - time_start;
|
||||
preempt_enable();
|
||||
rcu_read_unlock();
|
||||
|
||||
do_div(time_spent, repeat);
|
||||
duration = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = bpf_test_finish(kattr, uattr, &flow_keys, sizeof(flow_keys),
|
||||
retval, duration);
|
||||
@@ -780,3 +798,106 @@ out:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bpf_prog_test_run_sk_lookup(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
union bpf_attr __user *uattr)
|
||||
{
|
||||
struct bpf_test_timer t = { NO_PREEMPT };
|
||||
struct bpf_prog_array *progs = NULL;
|
||||
struct bpf_sk_lookup_kern ctx = {};
|
||||
u32 repeat = kattr->test.repeat;
|
||||
struct bpf_sk_lookup *user_ctx;
|
||||
u32 retval, duration;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (prog->type != BPF_PROG_TYPE_SK_LOOKUP)
|
||||
return -EINVAL;
|
||||
|
||||
if (kattr->test.flags || kattr->test.cpu)
|
||||
return -EINVAL;
|
||||
|
||||
if (kattr->test.data_in || kattr->test.data_size_in || kattr->test.data_out ||
|
||||
kattr->test.data_size_out)
|
||||
return -EINVAL;
|
||||
|
||||
if (!repeat)
|
||||
repeat = 1;
|
||||
|
||||
user_ctx = bpf_ctx_init(kattr, sizeof(*user_ctx));
|
||||
if (IS_ERR(user_ctx))
|
||||
return PTR_ERR(user_ctx);
|
||||
|
||||
if (!user_ctx)
|
||||
return -EINVAL;
|
||||
|
||||
if (user_ctx->sk)
|
||||
goto out;
|
||||
|
||||
if (!range_is_zero(user_ctx, offsetofend(typeof(*user_ctx), local_port), sizeof(*user_ctx)))
|
||||
goto out;
|
||||
|
||||
if (user_ctx->local_port > U16_MAX || user_ctx->remote_port > U16_MAX) {
|
||||
ret = -ERANGE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx.family = (u16)user_ctx->family;
|
||||
ctx.protocol = (u16)user_ctx->protocol;
|
||||
ctx.dport = (u16)user_ctx->local_port;
|
||||
ctx.sport = (__force __be16)user_ctx->remote_port;
|
||||
|
||||
switch (ctx.family) {
|
||||
case AF_INET:
|
||||
ctx.v4.daddr = (__force __be32)user_ctx->local_ip4;
|
||||
ctx.v4.saddr = (__force __be32)user_ctx->remote_ip4;
|
||||
break;
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case AF_INET6:
|
||||
ctx.v6.daddr = (struct in6_addr *)user_ctx->local_ip6;
|
||||
ctx.v6.saddr = (struct in6_addr *)user_ctx->remote_ip6;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ret = -EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
progs = bpf_prog_array_alloc(1, GFP_KERNEL);
|
||||
if (!progs) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
progs->items[0].prog = prog;
|
||||
|
||||
bpf_test_timer_enter(&t);
|
||||
do {
|
||||
ctx.selected_sk = NULL;
|
||||
retval = BPF_PROG_SK_LOOKUP_RUN_ARRAY(progs, ctx, BPF_PROG_RUN);
|
||||
} while (bpf_test_timer_continue(&t, repeat, &ret, &duration));
|
||||
bpf_test_timer_leave(&t);
|
||||
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
user_ctx->cookie = 0;
|
||||
if (ctx.selected_sk) {
|
||||
if (ctx.selected_sk->sk_reuseport && !ctx.no_reuseport) {
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
user_ctx->cookie = sock_gen_cookie(ctx.selected_sk);
|
||||
}
|
||||
|
||||
ret = bpf_test_finish(kattr, uattr, NULL, 0, retval, duration);
|
||||
if (!ret)
|
||||
ret = bpf_ctx_finish(kattr, uattr, user_ctx, sizeof(*user_ctx));
|
||||
|
||||
out:
|
||||
bpf_prog_array_free(progs);
|
||||
kfree(user_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -10295,6 +10295,7 @@ static u32 sk_lookup_convert_ctx_access(enum bpf_access_type type,
|
||||
}
|
||||
|
||||
const struct bpf_prog_ops sk_lookup_prog_ops = {
|
||||
.test_run = bpf_prog_test_run_sk_lookup,
|
||||
};
|
||||
|
||||
const struct bpf_verifier_ops sk_lookup_verifier_ops = {
|
||||
|
||||
@@ -87,6 +87,21 @@ static struct kmem_cache *skbuff_ext_cache __ro_after_init;
|
||||
#endif
|
||||
int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
|
||||
EXPORT_SYMBOL(sysctl_max_skb_frags);
|
||||
gfp_t skb_gfp_dma32 = 0;
|
||||
|
||||
void skb_set_alloc_dma32(gfp_t gfp_dma32)
|
||||
{
|
||||
if(gfp_dma32 | GFP_DMA32)
|
||||
skb_gfp_dma32 = __GFP_DMA32;
|
||||
else
|
||||
skb_gfp_dma32 = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(skb_set_alloc_dma32);
|
||||
gfp_t skb_get_alloc_dma32(void)
|
||||
{
|
||||
return skb_gfp_dma32;
|
||||
}
|
||||
EXPORT_SYMBOL(skb_get_alloc_dma32);
|
||||
|
||||
/**
|
||||
* skb_panic - private function for out-of-line support
|
||||
@@ -379,7 +394,7 @@ static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
|
||||
{
|
||||
struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
|
||||
|
||||
return page_frag_alloc(&nc->page, fragsz, gfp_mask);
|
||||
return page_frag_alloc(&nc->page, fragsz, gfp_mask | skb_gfp_dma32);
|
||||
}
|
||||
|
||||
void *napi_alloc_frag(unsigned int fragsz)
|
||||
@@ -405,10 +420,10 @@ void *netdev_alloc_frag(unsigned int fragsz)
|
||||
fragsz = SKB_DATA_ALIGN(fragsz);
|
||||
if (in_irq() || irqs_disabled()) {
|
||||
nc = this_cpu_ptr(&netdev_alloc_cache);
|
||||
data = page_frag_alloc(nc, fragsz, GFP_ATOMIC);
|
||||
data = page_frag_alloc(nc, fragsz, GFP_ATOMIC | skb_gfp_dma32);
|
||||
} else {
|
||||
local_bh_disable();
|
||||
data = __napi_alloc_frag(fragsz, GFP_ATOMIC);
|
||||
data = __napi_alloc_frag(fragsz, GFP_ATOMIC | skb_gfp_dma32);
|
||||
local_bh_enable();
|
||||
}
|
||||
return data;
|
||||
@@ -458,12 +473,12 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len,
|
||||
|
||||
if (in_irq() || irqs_disabled()) {
|
||||
nc = this_cpu_ptr(&netdev_alloc_cache);
|
||||
data = page_frag_alloc(nc, len, gfp_mask);
|
||||
data = page_frag_alloc(nc, len, gfp_mask | skb_gfp_dma32);
|
||||
pfmemalloc = nc->pfmemalloc;
|
||||
} else {
|
||||
local_bh_disable();
|
||||
nc = this_cpu_ptr(&napi_alloc_cache.page);
|
||||
data = page_frag_alloc(nc, len, gfp_mask);
|
||||
data = page_frag_alloc(nc, len, gfp_mask | skb_gfp_dma32);
|
||||
pfmemalloc = nc->pfmemalloc;
|
||||
local_bh_enable();
|
||||
}
|
||||
@@ -531,7 +546,7 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len,
|
||||
if (sk_memalloc_socks())
|
||||
gfp_mask |= __GFP_MEMALLOC;
|
||||
|
||||
data = page_frag_alloc(&nc->page, len, gfp_mask);
|
||||
data = page_frag_alloc(&nc->page, len, gfp_mask | skb_gfp_dma32);
|
||||
if (unlikely(!data))
|
||||
return NULL;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user