mirror of
https://github.com/revyos/thead-kernel.git
synced 2026-06-21 17:22:24 +02:00
Compare commits
3 Commits
master
...
Linux_SDK_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
599b048690 | ||
|
|
b269dc8fa7 | ||
|
|
87e5c31f94 |
@@ -13,7 +13,8 @@ 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-tdm.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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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>;
|
||||
@@ -77,13 +55,4 @@
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
};
|
||||
125
arch/riscv/boot/dts/thead/light-a-val-audio-tdm.dts
Normal file
125
arch/riscv/boot/dts/thead/light-a-val-audio-tdm.dts
Normal file
@@ -0,0 +1,125 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include "light-a-val.dts"
|
||||
|
||||
&tdm_slot1 {
|
||||
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";
|
||||
};
|
||||
|
||||
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";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&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 { /* TDM - AUDIO SYS CODEC 7210*/
|
||||
reg = <1>;
|
||||
format = "dsp_b";
|
||||
cpu@0 {
|
||||
sound-dai = <&tdm_slot1 0>;
|
||||
};
|
||||
cpu@1 {
|
||||
sound-dai = <&tdm_slot2 1>;
|
||||
};
|
||||
cpu@2 {
|
||||
sound-dai = <&tdm_slot3 2>;
|
||||
};
|
||||
cpu@3 {
|
||||
sound-dai = <&tdm_slot4 3>;
|
||||
};
|
||||
cpu@4 {
|
||||
sound-dai = <&tdm_slot5 4>;
|
||||
};
|
||||
cpu@5 {
|
||||
sound-dai = <&tdm_slot6 5>;
|
||||
};
|
||||
cpu@6 {
|
||||
sound-dai = <&tdm_slot7 6>;
|
||||
};
|
||||
cpu@7 {
|
||||
sound-dai = <&tdm_slot8 7>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es7210_adc2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -10,9 +10,25 @@
|
||||
compatible = "thead,light-val-audio", "thead,light";
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
71
arch/riscv/boot/dts/thead/light-a-val-dsi0-hdmi-audio.dts
Normal file
71
arch/riscv/boot/dts/thead/light-a-val-dsi0-hdmi-audio.dts
Normal file
@@ -0,0 +1,71 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-a-val-dsi0-hdmi.dts"
|
||||
|
||||
&audio_i2c0 {
|
||||
status = "okay";
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
};
|
||||
|
||||
&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 = <&i2s3 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 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -93,9 +93,25 @@
|
||||
};
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
};
|
||||
|
||||
&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";
|
||||
@@ -106,7 +122,7 @@
|
||||
sound-dai = <&es8156_audio_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
simple-audio-card,dai-link@1 { /* I2S - AUDIO SYS CODEC 7210*/
|
||||
reg = <1>;
|
||||
format = "i2s";
|
||||
@@ -118,19 +134,19 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&light_i2s {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
&i2s0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
&i2s3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
&qspi0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -38,6 +38,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
&audio_i2c0 {
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
};
|
||||
|
||||
&lightsound {
|
||||
status = "okay";
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-a-val-dsi0-hdmi.dts"
|
||||
#include "light-a-val-dsi0-hdmi-audio.dts"
|
||||
|
||||
|
||||
&light_iopmp {
|
||||
|
||||
@@ -193,8 +193,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";
|
||||
};
|
||||
|
||||
@@ -561,12 +562,27 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
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";
|
||||
|
||||
pcal6408ahk_b: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -848,8 +864,27 @@
|
||||
|
||||
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_i2c1: audio_i2c1_grp {
|
||||
thead,pins = <
|
||||
FM_AUDIO_IO_PA6 0x2 0x008
|
||||
FM_AUDIO_IO_PA7 0x2 0x008
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
@@ -585,18 +586,21 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
@@ -2091,6 +2095,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";
|
||||
@@ -2118,7 +2127,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
@@ -592,18 +594,21 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
@@ -797,6 +802,12 @@
|
||||
FM_GPIO3_2 0x1 0x208 /* pwm0 */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_volume_up: volume_up_grp {
|
||||
thead,pins = <
|
||||
FM_GPIO2_25 0x0 0x238
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -842,9 +853,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 +2276,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";
|
||||
@@ -2292,7 +2308,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 0x40000000>;
|
||||
reg = <0x0 0x200000 0x0 0x3fe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -605,18 +606,21 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
@@ -880,8 +884,8 @@
|
||||
|
||||
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
|
||||
>;
|
||||
};
|
||||
};
|
||||
@@ -2313,6 +2317,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";
|
||||
@@ -2340,7 +2349,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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 {
|
||||
@@ -573,18 +574,21 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
@@ -2249,6 +2253,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";
|
||||
@@ -2276,7 +2285,7 @@
|
||||
sound-dai = <&light_i2s 1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec 2>;
|
||||
sound-dai = <&dummy_codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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,21 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x00000000 0x0 0x80000000>;
|
||||
reg = <0x0 0x200000 0x0 0x7fe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -186,9 +186,17 @@
|
||||
};
|
||||
|
||||
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 +204,7 @@
|
||||
regulator-name = "vref-1v8";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
status = "okay";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
reg_tp_pwr_en: regulator-pwr-en {
|
||||
@@ -558,6 +566,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 {
|
||||
@@ -611,18 +661,21 @@
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "everest,es8156";
|
||||
reg = <0x08>;
|
||||
sound-name-prefix = "ES8156";
|
||||
};
|
||||
|
||||
es7210_audio_codec: es7210@40 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "MicArray_0";
|
||||
reg = <0x40>;
|
||||
sound-name-prefix = "ES7210";
|
||||
};
|
||||
|
||||
audio_aw87519_pa@58 {
|
||||
audio_aw87519_pa: amp@58 {
|
||||
compatible = "awinic,aw87519_pa";
|
||||
reg = <0x58>;
|
||||
reset-gpio = <&pcal6408ahk_a 2 0x1>;
|
||||
sound-name-prefix = "AW87519";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -634,8 +687,8 @@
|
||||
};
|
||||
|
||||
pcal6408ahk_a: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -938,8 +991,8 @@
|
||||
status = "okay";
|
||||
|
||||
pcal6408ahk_b: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -950,8 +1003,8 @@
|
||||
status = "okay";
|
||||
|
||||
pcal6408ahk_c: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -967,8 +1020,8 @@
|
||||
status = "okay";
|
||||
|
||||
pcal6408ahk_d: gpio@20 {
|
||||
compatible = "nxp,pcal9554b";
|
||||
reg = <0x20>;
|
||||
compatible = "nxp,pca9557";
|
||||
reg = <0x18>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
@@ -1411,6 +1464,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";
|
||||
@@ -1454,6 +1512,13 @@
|
||||
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 {
|
||||
c910_0: cpu@0 {
|
||||
operating-points = <
|
||||
@@ -1461,12 +1526,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 +1542,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 +1559,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 +1576,14 @@
|
||||
300000 650000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
1848000 1000000
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
13
arch/riscv/boot/dts/thead/light-lpi4a-sec.dts
Normal file
13
arch/riscv/boot/dts/thead/light-lpi4a-sec.dts
Normal file
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "light-lpi4a.dts"
|
||||
|
||||
|
||||
&light_iopmp {
|
||||
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 = <0x1 0xe4000000 0 0x14000000>; // [0x1E400_0000 ~ 0x1F800_0000]
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#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/clock/light-fm-ap-clock.h>
|
||||
#include <dt-bindings/clock/light-vpsys.h>
|
||||
#include <dt-bindings/clock/light-vosys.h>
|
||||
@@ -94,6 +95,12 @@
|
||||
};
|
||||
};
|
||||
|
||||
aon_iram: aon-iram@ffffef8000 {
|
||||
compatible = "syscon";
|
||||
reg = <0xff 0xffef8000 0x0 0x10000>;
|
||||
};
|
||||
|
||||
|
||||
thermal-zones {
|
||||
cpu-thermal-zone {
|
||||
polling-delay-passive = <250>;
|
||||
@@ -383,7 +390,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 {
|
||||
@@ -855,6 +862,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>;
|
||||
@@ -1301,7 +1314,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 +1367,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 +1377,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 +1387,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";
|
||||
@@ -1573,6 +1583,174 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot1: audio_tdm_slot1@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot2: audio_tdm_slot2@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot3: audio_tdm_slot3@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot4: audio_tdm_slot4@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot5: audio_tdm_slot5@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot6: audio_tdm_slot6@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot7: audio_tdm_slot7@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tdm_slot8: audio_tdm_slot8@0xffcb012000 {
|
||||
#sound-dai-cells = <1>;
|
||||
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 = <&dummy_clock_apb>;
|
||||
clock-names = "pclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pvt: pvt@fffff4e000 {
|
||||
compatible = "moortec,mr75203";
|
||||
reg = <0xff 0xfff4e000 0x0 0x80>,
|
||||
@@ -2154,6 +2332,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>;
|
||||
|
||||
@@ -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
|
||||
@@ -20,6 +24,7 @@ CONFIG_SOC_THEAD=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_VECTOR=y
|
||||
CONFIG_VECTOR_0_7=y
|
||||
CONFIG_THEAD_ISA=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
@@ -91,6 +96,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 +271,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
|
||||
@@ -298,13 +305,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 +335,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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
struct dwcmshc_priv {
|
||||
struct clk *bus_clk;
|
||||
void __iomem *soc_base;
|
||||
bool is_emmc_card;
|
||||
bool pull_up_en;
|
||||
bool io_fixed_1v8;
|
||||
@@ -289,12 +288,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);
|
||||
@@ -604,9 +597,6 @@ 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;
|
||||
} else {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
@@ -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;
|
||||
|
||||
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 */
|
||||
@@ -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
|
||||
@@ -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) */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -69,5 +69,19 @@
|
||||
#define ES7210_MIC4_LP_REG4A 0x4A
|
||||
#define ES7210_MIC12_PDN_REG4B 0x4B
|
||||
#define ES7210_MIC34_PDN_REG4C 0x4C
|
||||
|
||||
|
||||
/* codec private data */
|
||||
struct es7210_priv {
|
||||
struct regmap *regmap;
|
||||
struct i2c_client *i2c_client;
|
||||
unsigned int dmic_enable;
|
||||
unsigned int sysclk;
|
||||
struct clk *mclk;
|
||||
struct snd_pcm_hw_constraint_list *sysclk_constraints;
|
||||
unsigned int tdm_mode;
|
||||
struct delayed_work pcm_pop_work;
|
||||
int mclk_lrck_ratio;
|
||||
int pcm_format;
|
||||
};
|
||||
|
||||
#endif /* _ES7210_H_ */
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#define GPIO_LOW 0
|
||||
#define GPIO_HIGH 1
|
||||
#define es8156_DEF_VOL 0xBF
|
||||
#define ES8156_VOL_MAX 0xBF
|
||||
/*
|
||||
* If your system doesn't have MCLK, define this to 0 or the
|
||||
* driver will crash.
|
||||
@@ -115,7 +116,7 @@ static const struct snd_kcontrol_new es8156_snd_controls[] = {
|
||||
4,0,15,0),
|
||||
/* DAC Digital controls */
|
||||
SOC_SINGLE_TLV("DAC Playback Volume", ES8156_VOLUME_CONTROL_REG14,
|
||||
0, 0xff, 0, dac_vol_tlv),
|
||||
0, ES8156_VOL_MAX, 0, dac_vol_tlv),
|
||||
SOC_SINGLE("HP Switch",ES8156_ANALOG_SYS3_REG22,3,1,0),
|
||||
|
||||
|
||||
@@ -123,7 +124,7 @@ static const struct snd_kcontrol_new es8156_snd_controls[] = {
|
||||
|
||||
|
||||
static const struct snd_soc_dapm_widget es8156_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_AIF_OUT("SDOUT", "I2S Capture", 0,
|
||||
SND_SOC_DAPM_AIF_OUT("AIFSDOUT", "I2S Capture", 0,
|
||||
ES8156_P2S_CONTROL_REG0D, 2, 0),
|
||||
|
||||
SND_SOC_DAPM_AIF_IN("SDIN", "I2S Playback", 0,
|
||||
@@ -279,7 +280,7 @@ static int es8156_set_bias_level(struct snd_soc_component *codec,
|
||||
snd_soc_component_write(codec, ES8156_ANALOG_SYS4_REG23,0x00);
|
||||
snd_soc_component_write(codec, ES8156_TIME_CONTROL1_REG0A,0x01);
|
||||
snd_soc_component_write(codec, ES8156_TIME_CONTROL2_REG0B,0x01);
|
||||
snd_soc_component_write(codec, ES8156_VOLUME_CONTROL_REG14,0xBF);
|
||||
//snd_soc_component_write(codec, ES8156_VOLUME_CONTROL_REG14,0xBF);
|
||||
snd_soc_component_write(codec, ES8156_MAINCLOCK_CTL_REG01,0x21);
|
||||
snd_soc_component_write(codec, ES8156_P2S_CONTROL_REG0D,0x14);
|
||||
snd_soc_component_write(codec, ES8156_MISC_CONTROL3_REG18,0x00);
|
||||
@@ -299,7 +300,7 @@ static int es8156_set_bias_level(struct snd_soc_component *codec,
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_OFF:
|
||||
snd_soc_component_write(codec, ES8156_VOLUME_CONTROL_REG14, 0x00);
|
||||
//snd_soc_component_write(codec, ES8156_VOLUME_CONTROL_REG14, 0x00);
|
||||
snd_soc_component_write(codec, ES8156_EQ_CONTROL1_REG19, 0x02);
|
||||
snd_soc_component_write(codec, ES8156_ANALOG_SYS2_REG21, 0x1F);
|
||||
snd_soc_component_write(codec, ES8156_ANALOG_SYS3_REG22, 0x02);
|
||||
@@ -489,6 +490,7 @@ const struct regmap_config es8156_regmap_config = {
|
||||
};
|
||||
|
||||
static struct snd_soc_component_driver soc_codec_dev_es8156 = {
|
||||
.name = "es8156",
|
||||
.probe = es8156_probe,
|
||||
.remove = es8156_remove,
|
||||
.suspend = es8156_suspend,
|
||||
|
||||
@@ -145,16 +145,19 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_card_name);
|
||||
|
||||
static int asoc_simple_clk_enable(struct asoc_simple_dai *dai)
|
||||
{
|
||||
if (dai)
|
||||
return clk_prepare_enable(dai->clk);
|
||||
|
||||
if (dai) {
|
||||
if (!IS_ERR_OR_NULL(dai->clk))
|
||||
return clk_prepare_enable(dai->clk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void asoc_simple_clk_disable(struct asoc_simple_dai *dai)
|
||||
{
|
||||
if (dai)
|
||||
clk_disable_unprepare(dai->clk);
|
||||
if (dai) {
|
||||
if (!IS_ERR_OR_NULL(dai->clk))
|
||||
clk_disable_unprepare(dai->clk);
|
||||
}
|
||||
}
|
||||
|
||||
int asoc_simple_parse_clk(struct device *dev,
|
||||
@@ -182,6 +185,7 @@ int asoc_simple_parse_clk(struct device *dev,
|
||||
clk = devm_get_clk_from_child(dev, dlc->of_node, NULL);
|
||||
if (!IS_ERR(clk))
|
||||
simple_dai->sysclk = clk_get_rate(clk);
|
||||
simple_dai->clk = NULL; // avoid invalid clk pointer like 0x00000000d
|
||||
}
|
||||
|
||||
if (of_property_read_bool(node, "system-clock-direction-out"))
|
||||
@@ -242,7 +246,11 @@ static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
|
||||
if (clk_get_rate(simple_dai->clk) == rate)
|
||||
return 0;
|
||||
|
||||
return clk_set_rate(simple_dai->clk, rate);
|
||||
if (!IS_ERR_OR_NULL(simple_dai->clk)) {
|
||||
return clk_set_rate(simple_dai->clk, rate);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int asoc_simple_hw_params(struct snd_pcm_substream *substream,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# CPU DAI drivers
|
||||
|
||||
obj-$(CONFIG_SND_SOC_THEAD_LIGHT) += light-i2s.o
|
||||
obj-$(CONFIG_SND_SOC_THEAD_LIGHT) += light-tdm.o
|
||||
obj-$(CONFIG_SND_SOC_THEAD_LIGHT) += light-pcm-dma.o
|
||||
obj-$(CONFIG_SND_SOC_THEAD_LIGHT) += light-dummy-pcm.o
|
||||
obj-$(CONFIG_SND_SOC_AW87519) += aw87519_audio.o
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "aw87519_audio.h"
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -140,7 +143,6 @@ unsigned char aw87519_audio_receiver(void)
|
||||
unsigned int i;
|
||||
unsigned int length;
|
||||
|
||||
pr_info("%s enter\n", __func__);
|
||||
if (aw87519 == NULL)
|
||||
return 2;
|
||||
|
||||
@@ -169,8 +171,6 @@ unsigned char aw87519_audio_speaker(void)
|
||||
unsigned int i;
|
||||
unsigned int length;
|
||||
|
||||
pr_info("%s enter\n", __func__);
|
||||
|
||||
if (aw87519 == NULL)
|
||||
return 2;
|
||||
|
||||
@@ -577,6 +577,79 @@ retry:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const DECLARE_TLV_DB_RANGE(aw87519_tlv,
|
||||
8, 12, TLV_DB_SCALE_ITEM(1200,150, 0)
|
||||
);
|
||||
|
||||
static const struct snd_kcontrol_new aw87519_controls[] = {
|
||||
SOC_SINGLE_TLV("Speaker Playback Volume", REG_PAGR, 0, 12, 0, aw87519_tlv),
|
||||
};
|
||||
|
||||
static int aw87519_component_probe(struct snd_soc_component* component)
|
||||
{
|
||||
struct aw87519 *pa = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return 0; // snd_soc_add_component_controls(component, aw87519_controls, ARRAY_SIZE(aw87519_controls));
|
||||
}
|
||||
|
||||
static int aw87519_power_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kctrl, int event)
|
||||
{
|
||||
struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
|
||||
struct aw87519 *pa = snd_soc_component_get_drvdata(c);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
/* Before widget power up: turn chip on, sync registers */
|
||||
aw87519_audio_speaker();
|
||||
} else {
|
||||
/* After widget power down: turn chip off */
|
||||
aw87519_audio_off();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget aw87519_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_INPUT("IN"),
|
||||
SND_SOC_DAPM_OUTPUT("VO"),
|
||||
SND_SOC_DAPM_PGA("PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Power", SND_SOC_NOPM, 0, 0,
|
||||
aw87519_power_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route aw87519_dapm_routes[] = {
|
||||
{ "PGA", NULL, "IN"},
|
||||
{ "VO", NULL, "PGA"},
|
||||
{ "PGA", NULL, "Power"},
|
||||
};
|
||||
|
||||
static const struct reg_default aw87519_reg_defaults[] = {
|
||||
{0x69, 0x80}, {0x69, 0xB7}, {0x01, 0xF0}, {0x02, 0x09},
|
||||
{0x03, 0xE8}, {0x04, 0x11}, {0x05, 0x10}, {0x06, 0x43},
|
||||
{0x07, 0x4E}, {0x08, 0x03}, {0x09, 0x08}, {0x0A, 0x4A},
|
||||
{0x60, 0x16}, {0x61, 0x20}, {0x62, 0x01}, {0x63, 0x0B},
|
||||
{0x64, 0xC5}, {0x65, 0xA4}, {0x66, 0x78}, {0x67, 0xC4},
|
||||
{0x68, 0XD0},
|
||||
};
|
||||
|
||||
const struct regmap_config aw87519_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xff,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.reg_defaults = aw87519_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(aw87519_reg_defaults),
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver aw87519_component_driver = {
|
||||
.name = "aw87519",
|
||||
.probe = aw87519_component_probe,
|
||||
.dapm_widgets = aw87519_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(aw87519_dapm_widgets),
|
||||
.dapm_routes = aw87519_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(aw87519_dapm_routes),
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* aw87519 i2c driver
|
||||
******************************************************************************/
|
||||
@@ -599,6 +672,13 @@ static int aw87519_i2c_probe(struct i2c_client *client,
|
||||
goto exit_devm_kzalloc_failed;
|
||||
}
|
||||
|
||||
aw87519->regmap = devm_regmap_init_i2c(client, &aw87519_regmap_config);
|
||||
if (IS_ERR(aw87519->regmap)) {
|
||||
ret = PTR_ERR(aw87519->regmap);
|
||||
dev_err(&client->dev, "Failed to init regmap: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
aw87519->i2c_client = client;
|
||||
i2c_set_clientdata(client, aw87519);
|
||||
|
||||
@@ -650,7 +730,7 @@ static int aw87519_i2c_probe(struct i2c_client *client,
|
||||
/* aw87519 hardware off */
|
||||
aw87519_hw_off(aw87519);
|
||||
|
||||
return 0;
|
||||
return devm_snd_soc_register_component(&client->dev, &aw87519_component_driver, NULL, 0);
|
||||
|
||||
exit_i2c_check_id_failed:
|
||||
exit_gpio_request_failed:
|
||||
@@ -711,7 +791,7 @@ static void __exit aw87519_pa_exit(void)
|
||||
i2c_del_driver(&aw87519_i2c_driver);
|
||||
}
|
||||
|
||||
late_initcall(aw87519_pa_init);
|
||||
module_init(aw87519_pa_init);
|
||||
module_exit(aw87519_pa_exit);
|
||||
|
||||
MODULE_DESCRIPTION("AWINIC AW87519 PA driver");
|
||||
|
||||
@@ -72,6 +72,9 @@ unsigned char aw87519_rcv_cfg_default[] = {
|
||||
#define REG_PAGC2PR 0x09
|
||||
#define REG_PAGC1PR 0x0A
|
||||
|
||||
#define AW87519_EN_SW_SHIFT 7
|
||||
#define AW87519_EN_PA_SHIFT 4
|
||||
|
||||
#define AW87519_CHIPID 0x59
|
||||
#define AW87519_REG_MAX 11
|
||||
|
||||
@@ -90,6 +93,7 @@ struct aw87519 {
|
||||
struct mutex cfg_lock;
|
||||
struct work_struct cfg_work;
|
||||
struct delayed_work ram_work;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
96
sound/soc/thead/light-dummy-pcm.c
Normal file
96
sound/soc/thead/light-dummy-pcm.c
Normal file
@@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Driver for ASoC dummy pcm dai
|
||||
* Copyright 2023 Yan Dong <nanli.yd@alibaba-inc.com>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <sound/soc.h>
|
||||
|
||||
static const struct snd_soc_dapm_widget light_dummy_pcm_widgets[] = {
|
||||
SND_SOC_DAPM_INPUT("RX"),
|
||||
SND_SOC_DAPM_OUTPUT("TX"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route light_dummy_pcm_routes[] = {
|
||||
{ "Capture", NULL, "RX" },
|
||||
{ "TX", NULL, "Playback" },
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver light_dummy_pcm_dai[] = {
|
||||
{
|
||||
.name = "dummy-pcm",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_light_dummy_pcm = {
|
||||
.dapm_widgets = light_dummy_pcm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(light_dummy_pcm_widgets),
|
||||
.dapm_routes = light_dummy_pcm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(light_dummy_pcm_routes),
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static int light_dummy_pcm_probe(struct platform_device *pdev)
|
||||
{
|
||||
return devm_snd_soc_register_component(&pdev->dev,
|
||||
&soc_component_dev_light_dummy_pcm,
|
||||
light_dummy_pcm_dai, ARRAY_SIZE(light_dummy_pcm_dai));
|
||||
}
|
||||
|
||||
static int light_dummy_pcm_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id light_dummy_pcm_driver_ids[] = {
|
||||
{
|
||||
.name = "light-dummy-pcm",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, light_dummy_pcm_driver_ids);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id light_dummy_pcm_codec_of_match[] = {
|
||||
{ .compatible = "thead,light-dummy-pcm", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_dummy_pcm_codec_of_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver light_dummy_pcm_driver = {
|
||||
.driver = {
|
||||
.name = "light-dummy-pcm",
|
||||
.of_match_table = of_match_ptr(light_dummy_pcm_codec_of_match),
|
||||
},
|
||||
.probe = light_dummy_pcm_probe,
|
||||
.remove = light_dummy_pcm_remove,
|
||||
.id_table = light_dummy_pcm_driver_ids,
|
||||
};
|
||||
|
||||
module_platform_driver(light_dummy_pcm_driver);
|
||||
|
||||
MODULE_AUTHOR("Yan Dong <nanli.yd@alibaba-inc.com>");
|
||||
MODULE_DESCRIPTION("ASoC dummy pcm dai driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -122,27 +122,11 @@ static inline void light_snd_txctrl(struct light_i2s_priv *chip, bool on)
|
||||
} else {
|
||||
dma_en &= ~DMACR_TDMAE_EN;
|
||||
i2s_en &= ~IISEN_I2SEN;
|
||||
i2s_status = readl(chip->regs + I2S_SR);
|
||||
while ((i2s_status & SR_TXBUSY_STATUS) || !(i2s_status & SR_TFNF_TX_FIFO_NOT_FULL)) {
|
||||
i2s_status = readl(chip->regs + I2S_SR);
|
||||
}
|
||||
|
||||
i2s_imr = readl(chip->regs + I2S_IMR);
|
||||
|
||||
i2s_imr &= ~(IMR_TXUIRM_INTR_MSK);
|
||||
i2s_imr &= ~(IMR_TXEIM_INTR_MSK);
|
||||
|
||||
writel(i2s_imr, chip->regs + I2S_IMR);
|
||||
i2s_imr = readl(chip->regs + I2S_IMR);
|
||||
|
||||
writel(dma_en, chip->regs + I2S_DMACR);
|
||||
|
||||
i2s_status = readl(chip->regs + I2S_SR);
|
||||
while ((i2s_status & SR_TXBUSY_STATUS) || !(i2s_status & SR_TFE_TX_FIFO_EMPTY)) {
|
||||
i2s_status = readl(chip->regs + I2S_SR);
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
writel(i2s_en, chip->regs + I2S_IISEN);
|
||||
}
|
||||
}
|
||||
@@ -205,14 +189,15 @@ static int light_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
light_snd_rxctrl(i2s_private, 1);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (tx)
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (tx) {
|
||||
dmaengine_terminate_async(snd_dmaengine_pcm_get_chan(substream)); // work around for DMAC stop issue
|
||||
light_snd_txctrl(i2s_private, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
629
sound/soc/thead/light-tdm.c
Normal file
629
sound/soc/thead/light-tdm.c
Normal file
@@ -0,0 +1,629 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/sh_fsi.h>
|
||||
#include "light-pcm.h"
|
||||
#include "light-tdm.h"
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <dt-bindings/pinctrl/light-fm-aon-pinctrl.h>
|
||||
|
||||
#define LIGHT_RATES SNDRV_PCM_RATE_8000_384000
|
||||
#define LIGHT_FMTS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8)
|
||||
|
||||
static int light_tdm_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct light_tdm_priv *tdm = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (tdm) {
|
||||
snd_soc_dai_init_dma_data(dai, NULL, &tdm->dma_params_rx);
|
||||
} else {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_tdm_dai_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void light_tdm_snd_rxctrl(struct light_tdm_priv *priv, char on)
|
||||
{
|
||||
if (priv->slot_num != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regmap, TDM_DMACTL,
|
||||
DMACTL_DMAEN_MSK, DMACTL_DMAEN_SEL(on));
|
||||
regmap_update_bits(priv->regmap, TDM_TDMEN,
|
||||
TDMCTL_TDMEN_MSK, TDMCTL_TDMEN_SEL(on));
|
||||
u32 dmactl;
|
||||
u32 tdmen;
|
||||
regmap_read(priv->regmap, TDM_DMACTL, &dmactl);
|
||||
regmap_read(priv->regmap, TDM_TDMEN, &tdmen);
|
||||
//printk("%s TDM_DMACTL=0x%x TDM_TDMEN=0x%x\n", __func__, dmactl, tdmen);
|
||||
return;
|
||||
}
|
||||
|
||||
static void light_tdm_dai_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct light_tdm_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
light_tdm_snd_rxctrl(priv, 0);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
}
|
||||
|
||||
static int light_tdm_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
int ret = 0;
|
||||
struct light_tdm_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
switch(cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
light_tdm_snd_rxctrl(priv, 1);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
light_tdm_snd_rxctrl(priv, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int light_tdm_set_fmt_dai(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct light_tdm_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
u32 cnfin = 0;
|
||||
|
||||
if (priv->slot_num != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
printk("%s fmt=%d\n", __func__, fmt);
|
||||
switch(fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown fmt dai\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regmap, TDM_TDMCTL,
|
||||
TDMCTL_MODE_MSK,
|
||||
TDMCTL_MODE_SEL(TDM_MODE_MASTER));
|
||||
regmap_update_bits(priv->regmap, TDM_TDMCTL,
|
||||
TDMCTL_SPEDGE_MSK,
|
||||
TDMCTL_SPEDGE_SEL(1));
|
||||
regmap_update_bits(priv->regmap, TDM_DMADL,
|
||||
DMACTL_DMADL_MSK, DMACTL_DMADL_SEL(0));
|
||||
u32 tdmctl;
|
||||
u32 dmadl;
|
||||
regmap_read(priv->regmap, TDM_TDMCTL, &tdmctl);
|
||||
regmap_read(priv->regmap, TDM_DMADL, &dmadl);
|
||||
printk("%s TDM_TDMCTL=0x%x TDM_DMADL=0x%x\n", __func__, tdmctl, dmadl);
|
||||
printk("%s %d\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 light_special_sample_rates[] = { 11025, 22050, 44100, 88200 };
|
||||
#define AUDIO_DIVCLK0 49152000
|
||||
#define AUDIO_DIVCLK1 135475200
|
||||
|
||||
static void light_tdm_set_div(struct light_tdm_priv *priv, struct snd_pcm_hw_params *params)
|
||||
{
|
||||
bool is_divclk1 = false; //audio_divclk1 for 44.1k...etc. audio_divclk0 for 48k....etc
|
||||
u32 src_clk;
|
||||
u32 div0, i, width;
|
||||
u32 sample_rate = params_rate(params);
|
||||
|
||||
switch(params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
width = 16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
width = 24;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
width = 32;
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown data format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(light_special_sample_rates); i++) {
|
||||
if (light_special_sample_rates[i] == sample_rate) {
|
||||
is_divclk1 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_divclk1 == false) { // audio_divclk0=49152000 for 48k
|
||||
regmap_update_bits(priv->audio_cpr_regmap,
|
||||
CPR_PERI_CLK_SEL_REG, CPR_TDM_SRC_SEL_MSK, CPR_TDM_SRC_SEL(0));
|
||||
src_clk = AUDIO_DIVCLK0;
|
||||
} else { // audio_divclk1=135475200 for 44.1k
|
||||
regmap_update_bits(priv->audio_cpr_regmap,
|
||||
CPR_PERI_CLK_SEL_REG, CPR_TDM_SRC_SEL_MSK, CPR_TDM_SRC_SEL(2));
|
||||
src_clk = AUDIO_DIVCLK1;
|
||||
}
|
||||
div0 = src_clk / (sample_rate * (width * priv->slots));
|
||||
regmap_update_bits(priv->regmap, TDM_DIV0_LEVEL,
|
||||
TDMCTL_DIV0_MASK, div0);
|
||||
//printk("src_clk=%d sample_rate=%d priv->slots=%d width=%d div0=%d\n", src_clk, sample_rate, priv->slots, width, div0);
|
||||
}
|
||||
|
||||
|
||||
static int light_tdm_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
|
||||
{
|
||||
struct light_tdm_priv *priv = snd_soc_dai_get_drvdata(dai);
|
||||
u32 datawth, chn_num;
|
||||
|
||||
if ( params_channels(params) != 1) {
|
||||
pr_err("Not support channel num\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->slot_num != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
datawth = TDMCTL_DATAWTH_16BIT_PACKED; // TDMCTL_DATAWTH_16BIT
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
datawth = TDMCTL_DATAWTH_24BIT;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
datawth = TDMCTL_DATAWTH_32BIT;
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown data format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch(priv->slots) {
|
||||
case 2:
|
||||
chn_num = TDMCTL_CHNUM_2;
|
||||
break;
|
||||
case 4:
|
||||
chn_num = TDMCTL_CHNUM_4;
|
||||
break;
|
||||
case 6:
|
||||
chn_num = TDMCTL_CHNUM_6;
|
||||
break;
|
||||
case 8:
|
||||
chn_num = TDMCTL_CHNUM_8;
|
||||
break;
|
||||
default:
|
||||
pr_err("Not support slot num\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_update_bits(priv->regmap, TDM_TDMCTL,
|
||||
TDMCTL_DATAWTH_MSK, TDMCTL_DATAWTH_SEL(datawth));
|
||||
regmap_update_bits(priv->regmap, TDM_TDMCTL,
|
||||
TDMCTL_CHNUM_MSK, TDMCTL_CHNUM_SEL(chn_num));
|
||||
u32 tdmctl;
|
||||
regmap_read(priv->regmap, TDM_TDMCTL, &tdmctl);
|
||||
//printk("%s TDM_TDMCTL=0x%x\n", __func__, tdmctl);
|
||||
light_tdm_set_div(priv, params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct snd_soc_dai_ops light_tdm_dai_ops = {
|
||||
.startup = light_tdm_dai_startup,
|
||||
.shutdown = light_tdm_dai_shutdown,
|
||||
.trigger = light_tdm_dai_trigger,
|
||||
.set_fmt = light_tdm_set_fmt_dai,
|
||||
.hw_params = light_tdm_dai_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver light_tdm_soc_dai[] = {
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot1",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot2",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot3",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot4",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot5",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot6",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot7",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
{
|
||||
.probe = light_tdm_dai_probe,
|
||||
.name = "light-tdm-dai-slot8",
|
||||
.capture = {
|
||||
.rates = LIGHT_RATES,
|
||||
.formats = LIGHT_FMTS,
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
},
|
||||
.ops = &light_tdm_dai_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver light_tdm_soc_component = {
|
||||
.name = "light_tdm",
|
||||
};
|
||||
|
||||
static void light_tdm_pinctrl(struct light_tdm_priv *tdm_priv)
|
||||
{
|
||||
//GPIO_SEL
|
||||
regmap_update_bits(tdm_priv->audio_pin_regmap,
|
||||
0x0,0x38000000, 0x38000000);
|
||||
//MUX
|
||||
regmap_update_bits(tdm_priv->audio_pin_regmap,
|
||||
0x8,0xFC00000, 0x5400000);
|
||||
//strength
|
||||
regmap_update_bits(tdm_priv->audio_pin_regmap,
|
||||
0x44,0x0f, 0x07); // AUDIO_PA28
|
||||
regmap_update_bits(tdm_priv->audio_pin_regmap,
|
||||
0x40,0xF0000, 0x70000); // AUDIO_PA27
|
||||
return;
|
||||
}
|
||||
|
||||
static const struct regmap_config light_tdm_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = TDM_DIV0_LEVEL,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static int light_tdm_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct light_tdm_priv *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (priv->slot_num != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
regcache_cache_only(priv->regmap, true);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_tdm_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct light_tdm_priv *priv = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
if (priv->slot_num != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "clock enable failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regcache_cache_only(priv->regmap, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id light_tdm_of_match[] = {
|
||||
{ .compatible = "light,light-tdm"},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_tdm_of_match);
|
||||
|
||||
irqreturn_t tdm_interrupt(int irq, void* dev_id)
|
||||
{
|
||||
struct light_tdm_priv* priv = (struct light_tdm_priv*)dev_id;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int light_tdm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const char *sprop;
|
||||
const uint32_t *iprop;
|
||||
struct light_tdm_priv *tdm_priv;
|
||||
struct resource *res;
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int irq;
|
||||
int data_register, ret = 0;
|
||||
|
||||
tdm_priv = devm_kzalloc(&pdev->dev, sizeof(struct light_tdm_priv), GFP_KERNEL);
|
||||
if (!tdm_priv) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tdm_priv->dev = dev;
|
||||
sprop = of_get_property(np, "light,mode", NULL);
|
||||
if (sprop) {
|
||||
if (!strcmp(sprop, "i2s-master")) {
|
||||
tdm_priv->mode = TDM_MODE_MASTER;
|
||||
} else if (!strcmp(sprop, "i2s-slave")) {
|
||||
tdm_priv->mode = TDM_MODE_SLAVE;
|
||||
} else {
|
||||
dev_err(dev, "invalid light,mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
iprop = of_get_property(np, "light,dma_maxburst", NULL);
|
||||
if (iprop)
|
||||
tdm_priv->dma_maxburst = be32_to_cpup(iprop);
|
||||
else
|
||||
tdm_priv->dma_maxburst = 8;
|
||||
|
||||
iprop = of_get_property(np, "light,tdm_slots", NULL);
|
||||
if (iprop) {
|
||||
if (be32_to_cpup(iprop) == 2 || be32_to_cpup(iprop) == 4 || be32_to_cpup(iprop) == 6 || be32_to_cpup(iprop) == 8) {
|
||||
tdm_priv->slots = be32_to_cpup(iprop);
|
||||
} else {
|
||||
dev_err(dev, "invalid light,tdm_slots\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
tdm_priv->slots = 8;
|
||||
}
|
||||
|
||||
iprop = of_get_property(np, "light,tdm_slot_num", NULL);
|
||||
if (iprop) {
|
||||
if (be32_to_cpup(iprop) >=1 && be32_to_cpup(iprop) <=8 ) {
|
||||
tdm_priv->slot_num = be32_to_cpup(iprop);
|
||||
} else {
|
||||
dev_err(dev, "invalid light,tdm_slot_num\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
dev_err(dev, "invalid light,tdm_slot_num\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, tdm_priv);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
tdm_priv->clk = devm_clk_get(&pdev->dev, "pclk");
|
||||
if (IS_ERR(tdm_priv->clk))
|
||||
return PTR_ERR(tdm_priv->clk);
|
||||
|
||||
if (tdm_priv->slot_num == 1) {
|
||||
tdm_priv->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(tdm_priv->regs)) {
|
||||
return PTR_ERR(tdm_priv->regs);
|
||||
}
|
||||
|
||||
tdm_priv->regmap = devm_regmap_init_mmio(dev, tdm_priv->regs,
|
||||
&light_tdm_regmap_config);
|
||||
if (IS_ERR(tdm_priv->regmap)) {
|
||||
dev_err(dev, "Failed to initialise managed register map\n");
|
||||
return PTR_ERR(tdm_priv->regmap);
|
||||
}
|
||||
|
||||
tdm_priv->audio_pin_regmap = syscon_regmap_lookup_by_phandle(np, "audio-pin-regmap");
|
||||
if (IS_ERR(tdm_priv->audio_pin_regmap)) {
|
||||
dev_err(dev, "cannot find regmap for audio system register\n");
|
||||
return -EINVAL;
|
||||
} else {
|
||||
light_tdm_pinctrl(tdm_priv);
|
||||
}
|
||||
|
||||
tdm_priv->audio_cpr_regmap = syscon_regmap_lookup_by_phandle(np, "audio-cpr-regmap");
|
||||
if (IS_ERR(tdm_priv->audio_cpr_regmap)) {
|
||||
dev_err(dev, "cannot find regmap for audio cpr register\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
//AUDIO_DIV1 set to 1/6. 812.8512MHz / 6 = 135.4752MHz
|
||||
regmap_update_bits(tdm_priv->audio_cpr_regmap,
|
||||
CPR_PERI_DIV_SEL_REG, CPR_AUDIO_DIV1_SEL_MSK, CPR_AUDIO_DIV1_SEL(5));
|
||||
//AUDIO_DIV0 set to 1/6. 294.912MHz / 6 = 49.152MHz
|
||||
regmap_update_bits(tdm_priv->audio_cpr_regmap,
|
||||
CPR_PERI_DIV_SEL_REG, CPR_AUDIO_DIV0_SEL_MSK, CPR_AUDIO_DIV0_SEL(5));
|
||||
//enable clock gate
|
||||
regmap_update_bits(tdm_priv->audio_cpr_regmap,
|
||||
CPR_IP_CG_REG, CPR_TDM_CG_SEL_MSK, CPR_TDM_CG_SEL(1));
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
if (!pm_runtime_enabled(&pdev->dev)) {
|
||||
ret = light_tdm_runtime_resume(&pdev->dev);
|
||||
if (ret) {
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(tdm_priv->clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
tdm_priv->irq = platform_get_irq(pdev, 0);
|
||||
if (tdm_priv->irq== 0) {
|
||||
dev_err(dev, "could not map IRQ.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
//ret = request_irq(tdm_priv->irq , tdm_interrupt,
|
||||
// IRQF_SHARED|IRQF_TRIGGER_RISING, "AUDIO_TDM_IRQ", (char *)tdm_priv);
|
||||
//if (ret) {
|
||||
// dev_err(dev, "%s[%d]:request irq error!\n", __func__, __LINE__);
|
||||
// return ret;
|
||||
//}
|
||||
}
|
||||
|
||||
switch(tdm_priv->slot_num) {
|
||||
case 1:
|
||||
data_register = TDM_LDR1;
|
||||
break;
|
||||
case 2:
|
||||
data_register = TDM_RDR1;
|
||||
break;
|
||||
case 3:
|
||||
data_register = TDM_LDR2;
|
||||
break;
|
||||
case 4:
|
||||
data_register = TDM_RDR2;
|
||||
break;
|
||||
case 5:
|
||||
data_register = TDM_LDR3;
|
||||
break;
|
||||
case 6:
|
||||
data_register = TDM_RDR3;
|
||||
break;
|
||||
case 7:
|
||||
data_register = TDM_LDR4;
|
||||
break;
|
||||
case 8:
|
||||
data_register = TDM_RDR4;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "invalid slot_num\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tdm_priv->dma_params_rx.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
tdm_priv->dma_params_rx.maxburst = tdm_priv->dma_maxburst;
|
||||
tdm_priv->dma_params_rx.addr = res->start + data_register;
|
||||
|
||||
ret = light_pcm_dma_init(pdev, LIGHT_TDM_DMABUF_SIZE);
|
||||
if (ret) {
|
||||
dev_err(dev, "light_pcm_dma_init error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = devm_snd_soc_register_component(dev, &light_tdm_soc_component,
|
||||
light_tdm_soc_dai, ARRAY_SIZE(light_tdm_soc_dai));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "cannot snd component register\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int light_tdm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct light_tdm_priv *tdm_priv = dev_get_drvdata(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
light_tdm_runtime_suspend(&pdev->dev);
|
||||
clk_disable_unprepare(tdm_priv->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops light_tdm_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(light_tdm_runtime_suspend, light_tdm_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver light_tdm_driver = {
|
||||
.driver = {
|
||||
.name = "light-tdm-audio",
|
||||
.pm = &light_tdm_pm_ops,
|
||||
.of_match_table = light_tdm_of_match,
|
||||
},
|
||||
.probe = light_tdm_probe,
|
||||
.remove = light_tdm_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(light_tdm_driver);
|
||||
|
||||
MODULE_AUTHOR("nanli.yd <nanli.yd@linux.alibaba.com>");
|
||||
MODULE_DESCRIPTION("Thead Light audio driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
125
sound/soc/thead/light-tdm.h
Normal file
125
sound/soc/thead/light-tdm.h
Normal file
@@ -0,0 +1,125 @@
|
||||
#ifndef _LIGHT_TDM_H
|
||||
#define _LIGHT_TDM_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "light-pcm.h"
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define TDM_TDMEN 0x00
|
||||
#define TDM_TDMCTL 0x04
|
||||
#define TDM_CHOFFSET1 0x08
|
||||
#define TDM_CHOFFSET2 0x0c
|
||||
#define TDM_CHOFFSET3 0x10
|
||||
#define TDM_CHOFFSET4 0x14
|
||||
#define TDM_FIFOTL1 0x18
|
||||
#define TDM_FIFOTL2 0x1C
|
||||
#define TDM_FIFOTL3 0x20
|
||||
#define TDM_FIFOTL4 0x24
|
||||
#define TDM_SR 0x28
|
||||
#define TDM_IMR 0x2C
|
||||
#define TDM_ISR 0x30
|
||||
#define TDM_RISR 0x34
|
||||
#define TDM_ICR 0x38
|
||||
#define TDM_DMACTL 0x3C
|
||||
#define TDM_DMADL 0x40
|
||||
#define TDM_LDR1 0x44
|
||||
#define TDM_RDR1 0x48
|
||||
#define TDM_LDR2 0x4C
|
||||
#define TDM_RDR2 0x50
|
||||
#define TDM_LDR3 0x54
|
||||
#define TDM_RDR3 0x58
|
||||
#define TDM_LDR4 0x5C
|
||||
#define TDM_RDR4 0x60
|
||||
#define TDM_DIV0_LEVEL 0x64
|
||||
|
||||
#define CPR_PERI_DIV_SEL_REG 0x004 /*audio sys i2s clock div Register*/
|
||||
#define CPR_PERI_CLK_SEL_REG 0x008 /*audio sys i2s clock selection Register*/
|
||||
#define CPR_IP_CG_REG 0x010 /* ip clock gate register */
|
||||
|
||||
/* AUDIO SYS DIV SEL REG, offset: 0x4 */
|
||||
#define CPR_AUDIO_DIV1_SEL_POS (12U)
|
||||
#define CPR_AUDIO_DIV1_SEL_MSK (0x1FU << CPR_AUDIO_DIV1_SEL_POS)
|
||||
#define CPR_AUDIO_DIV1_SEL(X) (X << CPR_AUDIO_DIV1_SEL_POS)
|
||||
#define CPR_AUDIO_DIV0_SEL_POS (4U)
|
||||
#define CPR_AUDIO_DIV0_SEL_MSK (0x1FU << CPR_AUDIO_DIV0_SEL_POS)
|
||||
#define CPR_AUDIO_DIV0_SEL(X) (X << CPR_AUDIO_DIV0_SEL_POS)
|
||||
#define CPR_TDM_CG_SEL_POS (21U)
|
||||
#define CPR_TDM_CG_SEL_MSK (0x1U << CPR_TDM_CG_SEL_POS)
|
||||
#define CPR_TDM_CG_SEL(X) (X << CPR_TDM_CG_SEL_POS)
|
||||
#define CPR_TDM_SRC_SEL_POS (16U)
|
||||
#define CPR_TDM_SRC_SEL_MSK (0x3U << CPR_TDM_SRC_SEL_POS)
|
||||
#define CPR_TDM_SRC_SEL(X) (X << CPR_TDM_SRC_SEL_POS)
|
||||
|
||||
#define TDM_MODE_MASTER 0x1
|
||||
#define TDM_MODE_SLAVE 0x0
|
||||
#define TDMCTL_MODE_POS (0U)
|
||||
#define TDMCTL_MODE_MSK (0x1U << TDMCTL_MODE_POS)
|
||||
#define TDMCTL_MODE_SEL(X) (X << TDMCTL_MODE_POS)
|
||||
#define TDMCTL_DATAWTH_POS (4U)
|
||||
#define TDMCTL_DATAWTH_MSK (0x3U << TDMCTL_DATAWTH_POS)
|
||||
#define TDMCTL_DATAWTH_SEL(X) (X << TDMCTL_DATAWTH_POS)
|
||||
#define TDMCTL_CHNUM_POS (8U)
|
||||
#define TDMCTL_CHNUM_MSK (0x3U << TDMCTL_CHNUM_POS)
|
||||
#define TDMCTL_CHNUM_SEL(X) (X << TDMCTL_CHNUM_POS)
|
||||
#define TDMCTL_CHNUM_2 0x0
|
||||
#define TDMCTL_CHNUM_4 0x1
|
||||
#define TDMCTL_CHNUM_6 0x2
|
||||
#define TDMCTL_CHNUM_8 0x3
|
||||
#define TDMCTL_SPEDGE_POS (13U)
|
||||
#define TDMCTL_SPEDGE_MSK (0x1U << TDMCTL_SPEDGE_POS)
|
||||
#define TDMCTL_SPEDGE_SEL(X) (X << TDMCTL_SPEDGE_POS)
|
||||
|
||||
#define TDMCTL_DATAWTH_16BIT_PACKED 0x0
|
||||
#define TDMCTL_DATAWTH_16BIT 0x1
|
||||
#define TDMCTL_DATAWTH_24BIT 0x2
|
||||
#define TDMCTL_DATAWTH_32BIT 0x3
|
||||
|
||||
#define TDMCTL_DIV0_MASK 0xFFF
|
||||
|
||||
#define DMACTL_DMAEN_POS (0U)
|
||||
#define DMACTL_DMAEN_MSK (0x1U << DMACTL_DMAEN_POS)
|
||||
#define DMACTL_DMAEN_SEL(X) (X << DMACTL_DMAEN_POS)
|
||||
|
||||
#define DMACTL_DMADL_POS (0U)
|
||||
#define DMACTL_DMADL_MSK (0x3U << DMACTL_DMADL_POS)
|
||||
#define DMACTL_DMADL_SEL(X) (X << DMACTL_DMADL_POS)
|
||||
|
||||
#define TDMCTL_TDMEN_POS (0U)
|
||||
#define TDMCTL_TDMEN_MSK (0x1U << TDMCTL_TDMEN_POS)
|
||||
#define TDMCTL_TDMEN_SEL(X) (X << TDMCTL_TDMEN_POS)
|
||||
|
||||
#define LIGHT_TDM_DMABUF_SIZE (64 * 1024)
|
||||
|
||||
struct light_tdm_priv {
|
||||
void __iomem *regs;
|
||||
struct regmap *regmap;
|
||||
struct regmap *audio_pin_regmap;
|
||||
struct regmap *audio_cpr_regmap;
|
||||
struct clk *clk;
|
||||
struct snd_dmaengine_dai_dma_data dma_params_rx;
|
||||
unsigned int dai_fmt;
|
||||
u32 dma_maxburst;
|
||||
unsigned int cfg_off;
|
||||
struct device *dev;
|
||||
char mode;
|
||||
char slots;
|
||||
char slot_num;
|
||||
unsigned int irq;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -5006,7 +5006,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) */
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#elif defined(__TARGET_ARCH_sparc)
|
||||
#define bpf_target_sparc
|
||||
#define bpf_target_defined
|
||||
#elif defined(__TARGET_ARCH_riscv)
|
||||
#define bpf_target_riscv
|
||||
#define bpf_target_defined
|
||||
#else
|
||||
#undef bpf_target_defined
|
||||
#endif
|
||||
@@ -44,6 +47,8 @@
|
||||
#define bpf_target_powerpc
|
||||
#elif defined(__sparc__)
|
||||
#define bpf_target_sparc
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
#define bpf_target_riscv
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -279,6 +284,32 @@ struct pt_regs;
|
||||
#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc)
|
||||
#endif
|
||||
|
||||
#elif defined(bpf_target_riscv)
|
||||
|
||||
struct pt_regs;
|
||||
#define PT_REGS_RV const volatile struct user_regs_struct
|
||||
#define PT_REGS_PARM1(x) (((PT_REGS_RV *)(x))->a0)
|
||||
#define PT_REGS_PARM2(x) (((PT_REGS_RV *)(x))->a1)
|
||||
#define PT_REGS_PARM3(x) (((PT_REGS_RV *)(x))->a2)
|
||||
#define PT_REGS_PARM4(x) (((PT_REGS_RV *)(x))->a3)
|
||||
#define PT_REGS_PARM5(x) (((PT_REGS_RV *)(x))->a4)
|
||||
#define PT_REGS_RET(x) (((PT_REGS_RV *)(x))->ra)
|
||||
#define PT_REGS_FP(x) (((PT_REGS_RV *)(x))->s0)
|
||||
#define PT_REGS_RC(x) (((PT_REGS_RV *)(x))->a0)
|
||||
#define PT_REGS_SP(x) (((PT_REGS_RV *)(x))->sp)
|
||||
#define PT_REGS_IP(x) (((PT_REGS_RV *)(x))->pc)
|
||||
|
||||
#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a0)
|
||||
#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a1)
|
||||
#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a2)
|
||||
#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a3)
|
||||
#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a4)
|
||||
#define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), ra)
|
||||
#define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), s0)
|
||||
#define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a0)
|
||||
#define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), sp)
|
||||
#define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), pc)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(bpf_target_powerpc)
|
||||
|
||||
@@ -224,7 +224,7 @@ $(RESOLVE_BTFIDS): $(BPFOBJ) | $(BUILD_DIR)/resolve_btfids \
|
||||
define get_sys_includes
|
||||
$(shell $(1) -v -E - </dev/null 2>&1 \
|
||||
| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \
|
||||
$(shell $(1) -dM -E - </dev/null | grep '#define __riscv_xlen ' | sed 's/#define /-D/' | sed 's/ /=/')
|
||||
$(shell $(1) -dM -E - </dev/null | grep '__riscv_xlen ' | awk '{printf("-D__riscv_xlen=%d -D__BITS_PER_LONG=%d", $$3, $$3)}')
|
||||
endef
|
||||
|
||||
# Determine target endianness.
|
||||
|
||||
@@ -231,7 +231,11 @@ int __on_event(struct bpf_raw_tracepoint_args *ctx)
|
||||
#ifdef NO_UNROLL
|
||||
#pragma clang loop unroll(disable)
|
||||
#else
|
||||
#ifdef UNROLL_COUNT
|
||||
#pragma clang loop unroll_count(UNROLL_COUNT)
|
||||
#else
|
||||
#pragma clang loop unroll(full)
|
||||
#endif
|
||||
#endif
|
||||
/* Unwind python stack */
|
||||
for (int i = 0; i < STACK_MAX_LEN; ++i) {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2019 Facebook
|
||||
#define STACK_MAX_LEN 600
|
||||
/* clang will not unroll the loop 600 times.
|
||||
* Instead it will unroll it to the amount it deemed
|
||||
* appropriate, but the loop will still execute 600 times.
|
||||
* Total program size is around 90k insns
|
||||
/* Full unroll of 600 iterations will have total
|
||||
* program size close to 298k insns and this may
|
||||
* cause BPF_JMP insn out of 16-bit integer range.
|
||||
* So limit the unroll size to 150 so the
|
||||
* total program size is around 80k insns but
|
||||
* the loop will still execute 600 times.
|
||||
*/
|
||||
#define UNROLL_COUNT 150
|
||||
#include "pyperf.h"
|
||||
|
||||
@@ -100,7 +100,7 @@ struct bpf_test {
|
||||
enum bpf_prog_type prog_type;
|
||||
uint8_t flags;
|
||||
void (*fill_helper)(struct bpf_test *self);
|
||||
uint8_t runs;
|
||||
int runs;
|
||||
#define bpf_testdata_struct_t \
|
||||
struct { \
|
||||
uint32_t retval, retval_unpriv; \
|
||||
@@ -1054,7 +1054,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
|
||||
|
||||
run_errs = 0;
|
||||
run_successes = 0;
|
||||
if (!alignment_prevented_execution && fd_prog >= 0) {
|
||||
if (!alignment_prevented_execution && fd_prog >= 0 && test->runs >= 0) {
|
||||
uint32_t expected_val;
|
||||
int i;
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@
|
||||
.result = ACCEPT,
|
||||
.prog_type = BPF_PROG_TYPE_SK_LOOKUP,
|
||||
.expected_attach_type = BPF_SK_LOOKUP,
|
||||
.runs = -1,
|
||||
},
|
||||
/* invalid 8-byte reads from a 4-byte fields in bpf_sk_lookup */
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user