mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-15 11:44:11 +00:00
[board]:Init board config for JH7110
This commit is contained in:
parent
2555693dd8
commit
be5046fcbf
20 changed files with 2287 additions and 1 deletions
|
@ -19,6 +19,82 @@ config SOC_SIFIVE
|
|||
help
|
||||
This enables support for SiFive SoC platform hardware.
|
||||
|
||||
config SOC_STARFIVE
|
||||
bool "StarFive Socs"
|
||||
select SOC_SIFIVE
|
||||
select OF_RESERVED_MEM
|
||||
select SIFIVE_L2
|
||||
select SIFIVE_L2_FLUSH
|
||||
select DW_AXI_DMAC_STARFIVE
|
||||
help
|
||||
StarFive JH SOC platform
|
||||
|
||||
choice
|
||||
prompt "StarFive JH SOCs"
|
||||
help
|
||||
choice StarFive JH SOC platform
|
||||
|
||||
config SOC_STARFIVE_VIC7100
|
||||
bool "VIC7100"
|
||||
select HW_RANDOM_STARFIVE_VIC
|
||||
depends on SOC_STARFIVE
|
||||
help
|
||||
This enables support for StarFive VIC7100 SoC Platform Hardware.
|
||||
|
||||
config SOC_STARFIVE_JH7110
|
||||
bool "JH7110"
|
||||
select HW_RANDOM_STARFIVE_TRNG
|
||||
depends on SOC_STARFIVE
|
||||
help
|
||||
This enables support for StarFive JH7110 SoC Platform Hardware.
|
||||
endchoice
|
||||
|
||||
menu "StarFive JH SoC Debug Option"
|
||||
depends on SOC_STARFIVE
|
||||
|
||||
choice
|
||||
prompt "JH SOC GMAC Speed"
|
||||
depends on SOC_STARFIVE
|
||||
default FPGA_GMAC_SPEED_AUTO
|
||||
help
|
||||
choice VIC7100 GMAC speed.
|
||||
(GMAC only works well on 10M/duple, for FPGA board.)
|
||||
|
||||
config FPGA_GMAC_SPEED10
|
||||
bool "GMAC works on 10M mode"
|
||||
config FPGA_GMAC_SPEED100
|
||||
bool "GMAC works on 100M mode"
|
||||
config FPGA_GMAC_SPEED_AUTO
|
||||
bool "GMAC works on auto mode"
|
||||
endchoice
|
||||
|
||||
config FPGA_GMAC_FLUSH_DDR
|
||||
bool "VIC7100 SOC GMAC description and packet buffer flush"
|
||||
depends on SOC_STARFIVE_VIC7100
|
||||
depends on STMMAC_ETH
|
||||
default y if SOC_STARFIVE_VIC7100
|
||||
help
|
||||
enable VIC7100 GMAC description and packet buffer flush
|
||||
|
||||
config MMC_DW_FLUSH_DDR
|
||||
bool "VIC7100 SOC DW MMC buffer flush"
|
||||
depends on SOC_STARFIVE_VIC7100
|
||||
depends on MMC_DW
|
||||
default y if SOC_STARFIVE_VIC7100
|
||||
help
|
||||
enable VIC7100 DW MMC description and data buffer flush
|
||||
|
||||
config USB_CDNS3_HOST_FLUSH_DMA
|
||||
bool "Cadence USB3 host controller flush dma memery"
|
||||
depends on USB
|
||||
depends on USB_CDNS3
|
||||
depends on SOC_STARFIVE_VIC7100
|
||||
default y if SOC_STARFIVE_VIC7100
|
||||
help
|
||||
enable VIC7100 DW USB CDNS3 driver data buffer flush
|
||||
|
||||
endmenu
|
||||
|
||||
config SOC_VIRT
|
||||
bool "QEMU Virt Machine"
|
||||
select CLINT_TIMER if RISCV_M_MODE
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
subdir-y += sifive
|
||||
subdir-$(CONFIG_SOC_CANAAN_K210_DTB_BUILTIN) += canaan
|
||||
subdir-y += microchip
|
||||
subdir-y += starfive
|
||||
|
||||
obj-$(CONFIG_BUILTIN_DTB) := $(addsuffix /, $(subdir-y))
|
||||
|
|
2
arch/riscv/boot/dts/starfive/Makefile
Normal file
2
arch/riscv/boot/dts/starfive/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
dtb-$(CONFIG_SOC_STARFIVE_JH7110) += starfive_jh7110.dtb
|
432
arch/riscv/boot/dts/starfive/starfive_jh7110.dts
Normal file
432
arch/riscv/boot/dts/starfive/starfive_jh7110.dts
Normal file
|
@ -0,0 +1,432 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/dts-v1/;
|
||||
#include "starfive_jh7110_clk.dtsi"
|
||||
|
||||
/ {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
compatible = "sifive,freedom-u74-arty";
|
||||
model = "sifive,freedom-u74-arty";
|
||||
|
||||
chosen {
|
||||
linux,initrd-start = <0x0 0x46100000>;
|
||||
linux,initrd-end = <0x0 0x4c000000>;
|
||||
stdout-path = "/soc/serial@10000000:115200";
|
||||
#bootargs = "debug console=ttyS0 rootwait";
|
||||
};
|
||||
aliases {
|
||||
spi0="/soc/spi@13010000";
|
||||
gpio0="/soc/gpio@13040000";
|
||||
ethernet0="/soc/gmac0@16030000";
|
||||
mmc0="/soc/sdio0@16010000";
|
||||
mmc1="/soc/sdio1@16020000";
|
||||
};
|
||||
cpus: cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
timebase-frequency = <2000000>;
|
||||
compatible = "starfive,fu74-g000";
|
||||
cpu@0 {
|
||||
clock-frequency = <0>;
|
||||
compatible = "starfive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <40>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <40>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <&cachectrl>;
|
||||
reg = <0>;
|
||||
riscv,isa = "rv64imac";
|
||||
status = "disabled";
|
||||
tlb-split;
|
||||
cpu0intctrl: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu@1 {
|
||||
clock-frequency = <0>;
|
||||
compatible = "starfive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <40>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <40>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <&cachectrl>;
|
||||
reg = <1>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
cpu1intctrl: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu@2 {
|
||||
clock-frequency = <0>;
|
||||
compatible = "starfive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <40>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <40>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <&cachectrl>;
|
||||
reg = <2>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
cpu2intctrl: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu@3 {
|
||||
clock-frequency = <0>;
|
||||
compatible = "starfive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <40>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <40>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <&cachectrl>;
|
||||
reg = <3>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
cpu3intctrl: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
cpu@4 {
|
||||
clock-frequency = <0>;
|
||||
compatible = "starfive,rocket0", "riscv";
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-sets = <64>;
|
||||
d-cache-size = <32768>;
|
||||
d-tlb-sets = <1>;
|
||||
d-tlb-size = <40>;
|
||||
device_type = "cpu";
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-sets = <64>;
|
||||
i-cache-size = <32768>;
|
||||
i-tlb-sets = <1>;
|
||||
i-tlb-size = <40>;
|
||||
mmu-type = "riscv,sv39";
|
||||
next-level-cache = <&cachectrl>;
|
||||
reg = <4>;
|
||||
riscv,isa = "rv64imafdc";
|
||||
status = "okay";
|
||||
tlb-split;
|
||||
cpu4intctrl: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
};
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x40000000 0x1 0x0>;
|
||||
};
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
linux,cma {
|
||||
compatible = "shared-dma-pool";
|
||||
reusable;
|
||||
size = <0x0 0x20000000>;
|
||||
alignment = <0x0 0x1000>;
|
||||
alloc-ranges = <0x0 0xa0000000 0x0 0x20000000>;
|
||||
linux,cma-default;
|
||||
};
|
||||
};
|
||||
|
||||
soc: soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
#clock-cells = <1>;
|
||||
compatible = "starfive,freedom-u74-arty", "simple-bus", "arm,amba-bus";
|
||||
ranges;
|
||||
|
||||
cachectrl: cache-controller@2010000 {
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-sets = <2048>;
|
||||
cache-size = <2097152>;
|
||||
cache-unified;
|
||||
compatible = "sifive,fu540-c000-ccache", "starfive,ccache0", "cache";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <1 3 4 2>;
|
||||
/*next-level-cache = <&L40 &L36>;*/
|
||||
reg = <0x0 0x2010000 0x0 0x4000 0x0 0x8000000 0x0 0x2000000>;
|
||||
reg-names = "control", "sideband";
|
||||
};
|
||||
clint: clint@2000000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,clint0";
|
||||
/*interrupts-extended = <&cpu0intctrl 3 &cpu0intctrl 7 &cpu1intctrl 3 &cpu1intctrl 7 >;*/
|
||||
interrupts-extended = <&cpu0intctrl 3 &cpu0intctrl 7 &cpu1intctrl 3 &cpu1intctrl 7 &cpu2intctrl 3 &cpu2intctrl 7 &cpu3intctrl 3 &cpu3intctrl 7 &cpu4intctrl 3 &cpu4intctrl 7>;
|
||||
reg = <0x0 0x2000000 0x0 0x10000>;
|
||||
reg-names = "control";
|
||||
};
|
||||
plic: plic@c000000 {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,plic0";
|
||||
interrupt-controller;
|
||||
/*interrupts-extended = <&cpu0intctrl 11 &cpu0intctrl 9 &cpu1intctrl 11 &cpu1intctrl 9 >;*/
|
||||
interrupts-extended = <&cpu0intctrl 11 &cpu1intctrl 11 &cpu1intctrl 9 &cpu2intctrl 11 &cpu2intctrl 9 &cpu3intctrl 11 &cpu3intctrl 9 &cpu4intctrl 11 &cpu4intctrl 9>;
|
||||
reg = <0x0 0xc000000 0x0 0x4000000>;
|
||||
reg-names = "control";
|
||||
riscv,max-priority = <7>;
|
||||
riscv,ndev = <136>;
|
||||
};
|
||||
|
||||
uart0: serial@10000000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <32>;
|
||||
reg = <0x0 0x10000000 0x0 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
clocks = <&oscclk>, <&apb0clk>;
|
||||
clock-names = "baudclk", "apb_pclk";
|
||||
status = "okay";
|
||||
};
|
||||
uart1: serial@10010000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <33>;
|
||||
reg = <0x0 0x10010000 0x0 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
clocks = <&oscclk>, <&apb0clk>;
|
||||
clock-names = "baudclk", "apb_pclk";
|
||||
status = "okay";
|
||||
};
|
||||
uart2: serial@10020000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <34>;
|
||||
reg = <0x0 0x10020000 0x0 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
clocks = <&oscclk>, <&apb0clk>;
|
||||
clock-names = "baudclk", "apb_pclk";
|
||||
status = "okay";
|
||||
};
|
||||
uart3: serial@12000000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <45>;
|
||||
reg = <0x0 0x12000000 0x0 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
clocks = <&uartclk>, <&apb0clk>;
|
||||
clock-names = "baudclk", "apb_pclk";
|
||||
status = "okay";
|
||||
};
|
||||
uart4: serial@12010000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <46>;
|
||||
reg = <0x0 0x12010000 0x0 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
clocks = <&uartclk>, <&apb0clk>;
|
||||
clock-names = "baudclk", "apb_pclk";
|
||||
status = "okay";
|
||||
};
|
||||
uart5: serial@12020000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <47>;
|
||||
reg = <0x0 0x12020000 0x0 0x10000>;
|
||||
reg-io-width = <4>;
|
||||
reg-shift = <2>;
|
||||
clocks = <&uartclk>, <&apb0clk>;
|
||||
clock-names = "baudclk", "apb_pclk";
|
||||
status = "okay";
|
||||
};
|
||||
gpio: gpio@13040000 {
|
||||
compatible = "starfive,gpio7110";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <91>;
|
||||
reg = <0x0 0x13040000 0x0 0x10000>;
|
||||
reg-names = "control";
|
||||
interrupt-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <64>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/*emmc*/
|
||||
sdio0:sdio0@16010000{
|
||||
compatible = "snps,dw-mshc";
|
||||
reg = <0x0 0x16010000 0x0 0x10000>;
|
||||
interrupts = <74>;
|
||||
interrupt-parent = <&plic>;
|
||||
clocks = <&dwmmc_biuclk>,<&dwmmc_ciuclk>;
|
||||
clock-names = "biu","ciu";
|
||||
clock-frequency = <4000000>;
|
||||
max-frequency = <1000000>;
|
||||
fifo-depth = <32>;
|
||||
card-detect-delay = <300>;
|
||||
fifo-watermark-aligned;
|
||||
data-addr = <0>;
|
||||
bus-width = <8>;
|
||||
cap-sd-highspeed;
|
||||
/*broken-cd;*/
|
||||
cap-sdio-irq;
|
||||
cap-mmc-hw-reset;
|
||||
non-removable;
|
||||
enable-sdio-wakeup;
|
||||
keep-power-in-suspend;
|
||||
/*cap-power-off-card;*/
|
||||
cap-mmc-highspeed;
|
||||
/*fixed-emmc-driver-type;*/
|
||||
post-power-on-delay-ms = <200>;
|
||||
|
||||
};
|
||||
/*SD*/
|
||||
sdio1:sdio1@16020000{
|
||||
compatible = "snps,dw-mshc";
|
||||
reg = <0x0 0x16020000 0x0 0x10000>;
|
||||
interrupts = <75>;
|
||||
interrupt-parent = <&plic>;
|
||||
clocks = <&dwmmc_biuclk>,<&dwmmc_ciuclk>;
|
||||
clock-names = "biu","ciu";
|
||||
clock-frequency = <4000000>;
|
||||
max-frequency = <1000000>;
|
||||
fifo-depth = <32>;
|
||||
card-detect-delay = <300>;
|
||||
fifo-watermark-aligned;
|
||||
data-addr = <0>;
|
||||
bus-width = <4>;
|
||||
cap-sd-highspeed;
|
||||
/*broken-cd;*/
|
||||
cap-sdio-irq;
|
||||
cap-mmc-hw-reset;
|
||||
non-removable;
|
||||
enable-sdio-wakeup;
|
||||
keep-power-in-suspend;
|
||||
/*cap-power-off-card;*/
|
||||
cap-mmc-highspeed;
|
||||
/*fixed-emmc-driver-type;*/
|
||||
post-power-on-delay-ms = <200>;
|
||||
};
|
||||
jpu: jpu@11900000 {
|
||||
compatible = "cm,codaj12-jpu";
|
||||
reg = <0x0 0x13090000 0x0 0x300>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <14>;
|
||||
clocks = <&jpuclk>;
|
||||
clock-names = "jpege";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
vpu_dec: vpu_dec@130A0000 {
|
||||
compatible = "c&m,cm511-vpu";
|
||||
reg = <0 0x130A0000 0 0x10000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <13>;
|
||||
clocks = <&vdec_rootclk>;
|
||||
clock-names = "vcodec";
|
||||
status = "okay";
|
||||
};
|
||||
vpu_enc:vpu_enc@130B0000 {
|
||||
compatible = "cnm,cnm420l-vpu";
|
||||
reg = <0x0 0x130B0000 0x0 0x10000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <15>;
|
||||
clocks = <&venc_rootclk>;
|
||||
clock-names = "vcodec";
|
||||
reg-names = "control";
|
||||
};
|
||||
rst: reset-controller {
|
||||
compatible = "starfive,jh7110-reset";
|
||||
#reset-cells = <1>;
|
||||
reset-controller;
|
||||
};
|
||||
|
||||
/*gmac device configuration*/
|
||||
stmmac_axi_setup: stmmac-axi-config {
|
||||
snps,wr_osr_lmt = <0xf>;
|
||||
snps,rd_osr_lmt = <0xf>;
|
||||
snps,blen = <256 128 64 32 0 0 0>;
|
||||
};
|
||||
gmac0:gmac0@16030000{
|
||||
compatible = "snps,dwc-qos-ethernet-5.10a";
|
||||
reg = <0x0 0x16030000 0x0 0x10000>;
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <7>;
|
||||
phy-reset-gpios = <&gpio 63 0>;
|
||||
max-frame-size = <9000>;
|
||||
phy-mode = "rgmii-id";
|
||||
snps,multicast-filter-bins = <256>;
|
||||
snps,perfect-filter-entries = <128>;
|
||||
rx-fifo-depth = <262144>;
|
||||
tx-fifo-depth = <131072>;
|
||||
clock-names = "stmmaceth","phy_ref_clk", "apb_pclk","ptp_ref";
|
||||
clocks = <&gmac_bus_clk>, <&gmac_rxtx_clk>, <&gmac_bus_clk>,<&gmac_ptp_clk>;
|
||||
snps,fixed-burst;
|
||||
snps,no-pbl-x8;
|
||||
/*snps,force_sf_dma_mode;*/
|
||||
snps,force_thresh_dma_mode;
|
||||
snps,axi-config = <&stmmac_axi_setup>;
|
||||
snps,tso;
|
||||
snps,en-tx-lpi-clockgating;
|
||||
snps,en-lpi;
|
||||
snps,write-requests = <2>;
|
||||
snps,read-requests = <16>;
|
||||
snps,burst-map = <0x7>;
|
||||
snps,txpbl = <16>;
|
||||
snps,rxpbl = <16>;
|
||||
};
|
||||
|
||||
gpu:gpu@18000000{
|
||||
compatible = "img-gpu";
|
||||
interrupt-parent = <&plic>;
|
||||
interrupts = <87>;
|
||||
reg = <0x0 0x18000000 0x0 0x100000 0x0 0x130C000 0x0 0x10000>;
|
||||
clocks = <&gpu_core_clk>, <&gpu_sys_clk>;
|
||||
clock-names = "gpu_core_clk","gpu_sys_clk";
|
||||
current-clock = <8000000>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
88
arch/riscv/boot/dts/starfive/starfive_jh7110_audio.dtsi
Normal file
88
arch/riscv/boot/dts/starfive/starfive_jh7110_audio.dtsi
Normal file
|
@ -0,0 +1,88 @@
|
|||
&soc{
|
||||
sound_pwmdac:snd-card_pwmdac{
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "Starfive-Pwmdac-Sound-Card";
|
||||
simple-audio-card,bitclock-master = <&pwmdac_dailink_master>;
|
||||
simple-audio-card,frame-master = <&pwmdac_dailink_master>;
|
||||
simple-audio-card,format = "left_j";
|
||||
pwmdac_dailink_master:simple-audio-card,cpu {
|
||||
sound-dai = <&pwmdac>;
|
||||
};
|
||||
|
||||
simple-audio-card,codec {
|
||||
sound-dai = <&pwmdac_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
sound_wm8960:snd-card-wm8960{
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "Starfive-wm8960-Sound-Card";
|
||||
/* i2s + wm8960 */
|
||||
simple-audio-card,dai-link@0 {
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
format = "i2s";
|
||||
bitclock-master = <&sndcodec0>;
|
||||
frame-master = <&sndcodec0>;
|
||||
|
||||
widgets =
|
||||
"Microphone", "Mic Jack",
|
||||
"Line", "Line In",
|
||||
"Line", "Line Out",
|
||||
"Speaker", "Speaker",
|
||||
"Headphone", "Headphone Jack";
|
||||
routing =
|
||||
"Headphone Jack", "HP_L",
|
||||
"Headphone Jack", "HP_R",
|
||||
"Speaker", "SPK_LP",
|
||||
"Speaker", "SPK_LN",
|
||||
"LINPUT1", "Mic Jack",
|
||||
"LINPUT3", "Mic Jack",
|
||||
"RINPUT1", "Mic Jack",
|
||||
"RINPUT2", "Mic Jack";
|
||||
cpu0 {
|
||||
sound-dai = <&i2stx_4ch1>;
|
||||
};
|
||||
cpu1 {
|
||||
sound-dai = <&i2srx_3ch>;
|
||||
};
|
||||
|
||||
sndcodec0:codec {
|
||||
sound-dai = <&wm8960>;
|
||||
clocks = <&audioclk>;
|
||||
clock-names = "mclk";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sound_spdif:snd-card-spdif{
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "SF-SPDIF-Sound-Card";
|
||||
simple-audio-card,bitclock-master = <&spdif_dailink_master>;
|
||||
simple-audio-card,frame-master = <&spdif_dailink_master>;
|
||||
simple-audio-card,format = "left_j";
|
||||
spdif_dailink_master:simple-audio-card,cpu {
|
||||
sound-dai = <&spdif0>;
|
||||
};
|
||||
|
||||
simple-audio-card,codec {
|
||||
sound-dai = <&spdif_transmitter>;
|
||||
};
|
||||
};
|
||||
|
||||
sound_pdm:snd-card-pdm{
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,format = "i2s";
|
||||
simple-audio-card,name = "SF-PDM-Sound-Card";
|
||||
simple-audio-card,bitclock-master = <&pdm_dailink_master>;
|
||||
simple-audio-card,frame-master = <&pdm_dailink_master>;
|
||||
status = "okay";
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&i2srx_3ch>;
|
||||
};
|
||||
|
||||
pdm_dailink_master:simple-audio-card,codec {
|
||||
sound-dai = <&pdm>;
|
||||
};
|
||||
};
|
||||
};
|
149
arch/riscv/boot/dts/starfive/starfive_jh7110_clk.dtsi
Normal file
149
arch/riscv/boot/dts/starfive/starfive_jh7110_clk.dtsi
Normal file
|
@ -0,0 +1,149 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/ {
|
||||
oscclk:oscclk{
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24000000>;
|
||||
clock-output-names = "oscclk";
|
||||
};
|
||||
pll0clk:pll0clk{
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <1000000000>;
|
||||
clock-output-names = "pll0clk";
|
||||
};
|
||||
pll1clk:pll1clk{
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <1066000000>;
|
||||
clock-output-names = "pll1clk";
|
||||
};
|
||||
pll2clk:pll2clk{
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <1228800000>;
|
||||
clock-output-names = "pll2clk";
|
||||
};
|
||||
rtcclk: rtcclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <4000000>;
|
||||
clock-output-names = "rtcclk";
|
||||
};
|
||||
perh_rootclk: perh_rootclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <500000000>;
|
||||
};
|
||||
ahb0clk: ahb0clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <204800000>;
|
||||
};
|
||||
ahb1clk: ahb1clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <204800000>;
|
||||
};
|
||||
apb0clk: apb0clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <512000000>;
|
||||
};
|
||||
apb2clk: apb2clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <49500000>;
|
||||
};
|
||||
apb12clk: apb12clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <49500000>;
|
||||
};
|
||||
jpuclk: jpuclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <204800000>;
|
||||
};
|
||||
vdec_rootclk: vdec_rootclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <400000000>;
|
||||
};
|
||||
venc_rootclk: venc_rootclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <245760000>;
|
||||
};
|
||||
gmac_bus_clk: gmac_bus_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <4000000>;
|
||||
};
|
||||
gmac_rxtx_clk: gmac_rxtx_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <2500000>;
|
||||
};
|
||||
gmac_ptp_clk: gmac_ptp_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <2500000>;
|
||||
};
|
||||
qspi_clk: qspi-clk@0 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <50000000>;
|
||||
};
|
||||
uartclk: uartclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <51200000>;
|
||||
};
|
||||
dwmmc_biuclk: dwmmc_biuclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <4000000>;
|
||||
};
|
||||
dwmmc_ciuclk: dwmmc_ciuclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <4000000>;
|
||||
};
|
||||
stg_axiahb_clk: stg_axiahb_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <204800000>;
|
||||
};
|
||||
stg_apbclk: stg_apbclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <51200000>;
|
||||
};
|
||||
|
||||
gpu_core_clk: gpu_core_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
gpu_sys_clk: gpu_sys_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
pwmclk: pwmclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <125000000>;
|
||||
};
|
||||
audioclk: audioclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <12288000>;
|
||||
};
|
||||
canclk: canclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
};
|
235
arch/riscv/configs/starfive_jh7110_defconfig
Normal file
235
arch/riscv/configs/starfive_jh7110_defconfig
Normal file
|
@ -0,0 +1,235 @@
|
|||
CONFIG_DEFAULT_HOSTNAME="StarFive"
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_USELIB=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CFS_BANDWIDTH=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_EXPERT=y
|
||||
CONFIG_SOC_STARFIVE=y
|
||||
CONFIG_SOC_STARFIVE_JH7110=y
|
||||
CONFIG_FPGA_GMAC_SPEED10=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_SECCOMP is not set
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_PAGE_REPORTING=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
# CONFIG_IPV6 is not set
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NETFILTER_NETLINK_ACCT=y
|
||||
CONFIG_NETFILTER_NETLINK_QUEUE=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_TABLES=y
|
||||
CONFIG_NFT_CT=y
|
||||
CONFIG_NFT_COMPAT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPCOMP=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_NF_TABLES_IPV4=y
|
||||
CONFIG_NFT_DUP_IPV4=y
|
||||
CONFIG_NFT_FIB_IPV4=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_NAT=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
CONFIG_NETLINK_DIAG=y
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_RFCOMM=y
|
||||
CONFIG_BT_RFCOMM_TTY=y
|
||||
CONFIG_BT_BNEP=y
|
||||
CONFIG_BT_BNEP_MC_FILTER=y
|
||||
CONFIG_BT_BNEP_PROTO_FILTER=y
|
||||
CONFIG_BT_HCIUART=y
|
||||
CONFIG_BT_HCIUART_H4=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_NET_9P=y
|
||||
CONFIG_NET_9P_VIRTIO=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
CONFIG_SCSI_VIRTIO=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_VIRTIO_NET=y
|
||||
# CONFIG_NET_VENDOR_ALACRITECH is not set
|
||||
# CONFIG_NET_VENDOR_AMAZON is not set
|
||||
# CONFIG_NET_VENDOR_AQUANTIA is not set
|
||||
# CONFIG_NET_VENDOR_ARC is not set
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_NET_VENDOR_CADENCE is not set
|
||||
# CONFIG_NET_VENDOR_CAVIUM is not set
|
||||
# CONFIG_NET_VENDOR_CORTINA is not set
|
||||
# CONFIG_NET_VENDOR_EZCHIP is not set
|
||||
# CONFIG_NET_VENDOR_GOOGLE is not set
|
||||
# CONFIG_NET_VENDOR_HUAWEI is not set
|
||||
# CONFIG_NET_VENDOR_INTEL is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_MELLANOX is not set
|
||||
# CONFIG_NET_VENDOR_MICREL is not set
|
||||
# CONFIG_NET_VENDOR_MICROCHIP is not set
|
||||
# CONFIG_NET_VENDOR_MICROSEMI is not set
|
||||
# CONFIG_NET_VENDOR_NATSEMI is not set
|
||||
# CONFIG_NET_VENDOR_NETRONOME is not set
|
||||
# CONFIG_NET_VENDOR_NI is not set
|
||||
# CONFIG_NET_VENDOR_PENSANDO is not set
|
||||
# CONFIG_NET_VENDOR_QUALCOMM is not set
|
||||
CONFIG_R8169=y
|
||||
# CONFIG_NET_VENDOR_RENESAS is not set
|
||||
# CONFIG_NET_VENDOR_ROCKER is not set
|
||||
# CONFIG_NET_VENDOR_SAMSUNG is not set
|
||||
# CONFIG_NET_VENDOR_SEEQ is not set
|
||||
# CONFIG_NET_VENDOR_SOLARFLARE is not set
|
||||
# CONFIG_NET_VENDOR_SOCIONEXT is not set
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_STMMAC_SELFTESTS=y
|
||||
CONFIG_DWMAC_DWC_QOS_ETH=y
|
||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
|
||||
# CONFIG_NET_VENDOR_VIA is not set
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
# CONFIG_NET_VENDOR_XILINX is not set
|
||||
CONFIG_MARVELL_PHY=y
|
||||
CONFIG_MICREL_PHY=y
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_SERIO_LIBPS2=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=6
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
|
||||
CONFIG_HVC_RISCV_SBI=y
|
||||
CONFIG_TTY_PRINTK=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_VIRTIO=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_SIFIVE=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
# CONFIG_PTP_1588_CLOCK is not set
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_STARFIVE_JH7110=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_UAS=y
|
||||
CONFIG_USB_CDNS_SUPPORT=y
|
||||
CONFIG_USB_CDNS3=y
|
||||
CONFIG_USB_CDNS3_HOST=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_DEBUG=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_OF_DWCMSHC=y
|
||||
CONFIG_MMC_SPI=y
|
||||
CONFIG_MMC_DW=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_GOLDFISH=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DW_AXI_DMAC=y
|
||||
CONFIG_DMATEST=m
|
||||
CONFIG_SYNC_FILE=y
|
||||
# CONFIG_VIRTIO_MENU is not set
|
||||
# CONFIG_VHOST_MENU is not set
|
||||
CONFIG_GOLDFISH=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_VIRTIO=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_VIRTIO_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_FAT_DEFAULT_UTF8=y
|
||||
CONFIG_EXFAT_FS=y
|
||||
CONFIG_NTFS_FS=y
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NFS_V4=y
|
||||
CONFIG_NFS_V4_1=y
|
||||
CONFIG_NFS_V4_2=y
|
||||
CONFIG_ROOT_NFS=y
|
||||
CONFIG_CRYPTO_USER=y
|
||||
# CONFIG_CRYPTO_AES is not set
|
||||
CONFIG_CRYPTO_USER_API_HASH=y
|
||||
CONFIG_CRYPTO_USER_API_SKCIPHER=y
|
||||
CONFIG_CRYPTO_USER_API_RNG=y
|
||||
CONFIG_CRYPTO_USER_API_AEAD=y
|
||||
CONFIG_CRYPTO_DEV_VIRTIO=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||
CONFIG_WQ_WATCHDOG=y
|
||||
CONFIG_DEBUG_TIMEKEEPING=y
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
CONFIG_DEBUG_RWSEMS=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_STACKTRACE=y
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_DEBUG_PLIST=y
|
||||
CONFIG_DEBUG_SG=y
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
CONFIG_RCU_EQS_DEBUG=y
|
||||
# CONFIG_FTRACE is not set
|
||||
# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
CONFIG_MEMTEST=y
|
|
@ -549,6 +549,13 @@ config GPIO_SIFIVE
|
|||
select REGMAP_MMIO
|
||||
help
|
||||
Say yes here to support the GPIO device on SiFive SoCs.
|
||||
config GPIO_STARFIVE_JH7110
|
||||
bool "Starfive JH7110 GPIO support"
|
||||
depends on SOC_STARFIVE_JH7110
|
||||
depends on OF_GPIO
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
Say yes here to support the GPIO device on Starfive VIC7110 SoCs.
|
||||
|
||||
config GPIO_SIOX
|
||||
tristate "SIOX GPIO support"
|
||||
|
|
|
@ -133,6 +133,7 @@ obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
|
|||
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
|
||||
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
|
||||
obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o
|
||||
obj-$(CONFIG_GPIO_STARFIVE_JH7110) += gpio-starfive-jh7110.o
|
||||
obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o
|
||||
obj-$(CONFIG_GPIO_SL28CPLD) += gpio-sl28cpld.o
|
||||
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
|
||||
|
|
792
drivers/gpio/gpio-starfive-jh7110.c
Normal file
792
drivers/gpio/gpio-starfive-jh7110.c
Normal file
|
@ -0,0 +1,792 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* @file gpio-starfive-vic7110.c
|
||||
* @author StarFive Technology
|
||||
* @version V1.0
|
||||
* @date 08/13/2020
|
||||
* @brief
|
||||
******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqchip/chained_irq.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define GPIO_EN 0xe0
|
||||
#define GPIO_IS_LOW 0xe4
|
||||
#define GPIO_IS_HIGH 0xe8
|
||||
#define GPIO_IBE_LOW 0xf4
|
||||
#define GPIO_IBE_HIGH 0xf8
|
||||
#define GPIO_IEV_LOW 0xfc
|
||||
#define GPIO_IEV_HIGH 0x100
|
||||
#define GPIO_IE_LOW 0x104
|
||||
#define GPIO_IE_HIGH 0x108
|
||||
#define GPIO_IC_LOW 0xec
|
||||
#define GPIO_IC_HIGH 0xf0
|
||||
//read only
|
||||
#define GPIO_RIS_LOW 0x10c
|
||||
#define GPIO_RIS_HIGH 0x110
|
||||
#define GPIO_MIS_LOW 0x114
|
||||
#define GPIO_MIS_HIGH 0x118
|
||||
#define GPIO_DIN_LOW 0x11C
|
||||
#define GPIO_DIN_HIGH 0x120
|
||||
|
||||
#define GPIO_DOUT_X_REG 0x0
|
||||
#define GPIO_DOEN_X_REG 0x40
|
||||
|
||||
#define GPIO_INPUT_ENABLE_X_REG 0x124
|
||||
|
||||
#define MAX_GPIO 64
|
||||
|
||||
#define PROC_VIC "vic_gpio7110"
|
||||
|
||||
struct sfvic7110_gpio {
|
||||
raw_spinlock_t lock;
|
||||
void __iomem *base;
|
||||
struct gpio_chip gc;
|
||||
unsigned long enabled;
|
||||
unsigned trigger[MAX_GPIO];
|
||||
unsigned int irq_parent[MAX_GPIO];
|
||||
struct sfvic7110_gpio *self_ptr[MAX_GPIO];
|
||||
};
|
||||
|
||||
/* lock for procfs read access */
|
||||
static DEFINE_MUTEX(read_lock);
|
||||
|
||||
/* lock for procfs write access */
|
||||
static DEFINE_MUTEX(write_lock);
|
||||
|
||||
static DEFINE_SPINLOCK(sfg_lock);
|
||||
|
||||
static void __iomem *gpio_base = NULL;
|
||||
|
||||
static int sfvic7110_direction_input(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
unsigned int v;
|
||||
|
||||
if (offset >= gc->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||
v = readl_relaxed(chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
|
||||
v &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
v |= 1 << ((offset & 0x3) * 8);
|
||||
writel_relaxed(v, chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
|
||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfvic7110_direction_output(struct gpio_chip *gc, unsigned offset, int value)
|
||||
{
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
unsigned int v;
|
||||
|
||||
if (offset >= gc->ngpio)
|
||||
return -EINVAL;
|
||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||
v = readl_relaxed(chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
|
||||
v &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
writel_relaxed(v, chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
|
||||
|
||||
v = readl_relaxed(chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
|
||||
v &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
v |= value << ((offset & 0x3) * 8);
|
||||
writel_relaxed(v, chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
|
||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sfvic7110_get_direction(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
unsigned int v;
|
||||
|
||||
if (offset >= gc->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
v = readl_relaxed(chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
|
||||
return !!(v & (0x3f << ((offset & 0x3) * 8)));
|
||||
}
|
||||
|
||||
static int sfvic7110_get_value(struct gpio_chip *gc, unsigned offset)
|
||||
{
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
int value;
|
||||
|
||||
if (offset >= gc->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
if(offset < 32){
|
||||
value = readl_relaxed(chip->base + GPIO_DIN_LOW);
|
||||
return (value >> offset) & 0x1;
|
||||
} else {
|
||||
value = readl_relaxed(chip->base + GPIO_DIN_HIGH);
|
||||
return (value >> (offset - 32)) & 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sfvic7110_set_value(struct gpio_chip *gc, unsigned offset, int value)
|
||||
{
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
unsigned int v;
|
||||
|
||||
if (offset >= gc->ngpio)
|
||||
return;
|
||||
|
||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||
v = readl_relaxed(chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
|
||||
v &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
v |= value << ((offset & 0x3) * 8);
|
||||
writel_relaxed(v, chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
|
||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||
}
|
||||
|
||||
static void sfvic7110_set_ie(struct sfvic7110_gpio *chip, int offset)
|
||||
{
|
||||
unsigned long flags;
|
||||
int old_value, new_value;
|
||||
int reg_offset, index;
|
||||
|
||||
if(offset < 32) {
|
||||
reg_offset = 0;
|
||||
index = offset;
|
||||
} else {
|
||||
reg_offset = 4;
|
||||
index = offset - 32;
|
||||
}
|
||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||
old_value = readl_relaxed(chip->base + GPIO_IE_LOW + reg_offset);
|
||||
new_value = old_value | ( 1 << index);
|
||||
writel_relaxed(new_value, chip->base + GPIO_IE_LOW + reg_offset);
|
||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||
}
|
||||
|
||||
static int sfvic7110_irq_set_type(struct irq_data *d, unsigned trigger)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
int offset = irqd_to_hwirq(d);
|
||||
unsigned int reg_is, reg_ibe, reg_iev;
|
||||
int reg_offset, index;
|
||||
|
||||
if (offset < 0 || offset >= gc->ngpio)
|
||||
return -EINVAL;
|
||||
|
||||
if(offset < 32) {
|
||||
reg_offset = 0;
|
||||
index = offset;
|
||||
} else {
|
||||
reg_offset = 4;
|
||||
index = offset - 32;
|
||||
}
|
||||
switch(trigger) {
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
|
||||
reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
|
||||
reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
|
||||
reg_is &= (~(0x1<< index));
|
||||
reg_ibe &= (~(0x1<< index));
|
||||
reg_iev |= (0x1<< index);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
|
||||
reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
|
||||
reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
|
||||
reg_is &= (~(0x1<< index));
|
||||
reg_ibe &= (~(0x1<< index));
|
||||
reg_iev &= (0x1<< index);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
|
||||
reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
|
||||
//reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
|
||||
reg_is |= (~(0x1<< index));
|
||||
reg_ibe |= (~(0x1<< index));
|
||||
//reg_iev |= (0x1<< index);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
//writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
|
||||
reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
|
||||
reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
|
||||
reg_is |= (~(0x1<< index));
|
||||
reg_ibe &= (~(0x1<< index));
|
||||
reg_iev |= (0x1<< index);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
|
||||
reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
|
||||
reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
|
||||
reg_is |= (~(0x1<< index));
|
||||
reg_ibe &= (~(0x1<< index));
|
||||
reg_iev &= (0x1<< index);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
chip->trigger[offset] = trigger;
|
||||
sfvic7110_set_ie(chip, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* chained_irq_{enter,exit} already mask the parent */
|
||||
static void sfvic7110_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
unsigned int value;
|
||||
int offset = irqd_to_hwirq(d);
|
||||
int reg_offset, index;
|
||||
|
||||
if (offset < 0 || offset >= gc->ngpio)
|
||||
return;
|
||||
|
||||
if(offset < 32) {
|
||||
reg_offset = 0;
|
||||
index = offset;
|
||||
} else {
|
||||
reg_offset = 4;
|
||||
index = offset - 32;
|
||||
}
|
||||
|
||||
value = readl_relaxed(chip->base + GPIO_IE_LOW + reg_offset);
|
||||
value &= ~(0x1 << index);
|
||||
writel_relaxed(value,chip->base + GPIO_IE_LOW + reg_offset);
|
||||
}
|
||||
|
||||
static void sfvic7110_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
unsigned int value;
|
||||
int offset = irqd_to_hwirq(d);
|
||||
int reg_offset, index;
|
||||
|
||||
if (offset < 0 || offset >= gc->ngpio)
|
||||
return;
|
||||
|
||||
if(offset < 32) {
|
||||
reg_offset = 0;
|
||||
index = offset;
|
||||
} else {
|
||||
reg_offset = 4;
|
||||
index = offset - 32;
|
||||
}
|
||||
|
||||
value = readl_relaxed(chip->base + GPIO_IE_LOW + reg_offset);
|
||||
value |= (0x1 << index);
|
||||
writel_relaxed(value,chip->base + GPIO_IE_LOW + reg_offset);
|
||||
}
|
||||
|
||||
static void sfvic7110_irq_enable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
int offset = irqd_to_hwirq(d);
|
||||
|
||||
sfvic7110_irq_unmask(d);
|
||||
assign_bit(offset, &chip->enabled, 1);
|
||||
}
|
||||
|
||||
static void sfvic7110_irq_disable(struct irq_data *d)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
int offset = irqd_to_hwirq(d) % MAX_GPIO; // must not fail
|
||||
|
||||
assign_bit(offset, &chip->enabled, 0);
|
||||
sfvic7110_set_ie(chip, offset);
|
||||
}
|
||||
|
||||
static struct irq_chip sfvic7110_irqchip = {
|
||||
.name = "sfvic7110-gpio",
|
||||
.irq_set_type = sfvic7110_irq_set_type,
|
||||
.irq_mask = sfvic7110_irq_mask,
|
||||
.irq_unmask = sfvic7110_irq_unmask,
|
||||
.irq_enable = sfvic7110_irq_enable,
|
||||
.irq_disable = sfvic7110_irq_disable,
|
||||
};
|
||||
|
||||
|
||||
static int starfive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
|
||||
unsigned int child,
|
||||
unsigned int child_type,
|
||||
unsigned int *parent,
|
||||
unsigned int *parent_type)
|
||||
{
|
||||
struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
|
||||
struct irq_data *d = irq_get_irq_data(chip->irq_parent[child]);
|
||||
|
||||
*parent_type = IRQ_TYPE_NONE;
|
||||
*parent = irqd_to_hwirq(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t sfvic7110_irq_handler(int irq, void *gc)
|
||||
{
|
||||
int offset;
|
||||
// = self_ptr - &chip->self_ptr[0];
|
||||
int reg_offset, index;
|
||||
unsigned int value;
|
||||
unsigned long flags;
|
||||
struct sfvic7110_gpio *chip = gc;
|
||||
|
||||
for (offset = 0; offset < 64; offset++) {
|
||||
if(offset < 32) {
|
||||
reg_offset = 0;
|
||||
index = offset;
|
||||
} else {
|
||||
reg_offset = 4;
|
||||
index = offset - 32;
|
||||
}
|
||||
|
||||
raw_spin_lock_irqsave(&chip->lock, flags);
|
||||
value = readl_relaxed(chip->base + GPIO_MIS_LOW + reg_offset);
|
||||
if(value & BIT(index))
|
||||
writel_relaxed(BIT(index), chip->base + GPIO_IC_LOW +
|
||||
reg_offset);
|
||||
|
||||
//generic_handle_irq(irq_find_mapping(chip->gc.irq.domain,
|
||||
// offset));
|
||||
raw_spin_unlock_irqrestore(&chip->lock, flags);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void sf_vic_gpio_dout_reverse(int gpio,int en)
|
||||
{
|
||||
unsigned int value;
|
||||
int offset;
|
||||
|
||||
if(!gpio_base)
|
||||
return;
|
||||
|
||||
offset = GPIO_DOUT_X_REG + (gpio & ~0x3);
|
||||
|
||||
spin_lock(&sfg_lock);
|
||||
value = ioread32(gpio_base + offset);
|
||||
value &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
value |= (en & 0x1) << ((offset & 0x3) * 8);
|
||||
iowrite32(value, gpio_base + offset);
|
||||
spin_unlock(&sfg_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_dout_reverse);
|
||||
|
||||
void sf_vic_gpio_dout_value(int gpio,int v)
|
||||
{
|
||||
unsigned int value;
|
||||
int offset;
|
||||
|
||||
if(!gpio_base)
|
||||
return;
|
||||
|
||||
offset = GPIO_DOUT_X_REG + (gpio & ~0x3);
|
||||
|
||||
spin_lock(&sfg_lock);
|
||||
value = ioread32(gpio_base + offset);
|
||||
value &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
value |= (v & 0x3f) << ((offset & 0x3) * 8);
|
||||
iowrite32(value,gpio_base + offset);
|
||||
spin_unlock(&sfg_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_dout_value);
|
||||
|
||||
void sf_vic_gpio_dout_low(int gpio)
|
||||
{
|
||||
sf_vic_gpio_dout_value(gpio, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_dout_low);
|
||||
|
||||
void sf_vic_gpio_dout_high(int gpio)
|
||||
{
|
||||
sf_vic_gpio_dout_value(gpio, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_dout_high);
|
||||
|
||||
void sf_vic_gpio_doen_reverse(int gpio,int en)
|
||||
{
|
||||
unsigned int value;
|
||||
int offset;
|
||||
|
||||
if(!gpio_base)
|
||||
return;
|
||||
|
||||
offset = GPIO_DOEN_X_REG + (gpio & ~0x3);
|
||||
|
||||
spin_lock(&sfg_lock);
|
||||
value = ioread32(gpio_base + offset);
|
||||
value &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
value |= (en & 0x1) << ((offset & 0x3) * 8);
|
||||
iowrite32(value,gpio_base + offset);
|
||||
spin_unlock(&sfg_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_doen_reverse);
|
||||
|
||||
void sf_vic_gpio_doen_value(int gpio,int v)
|
||||
{
|
||||
unsigned int value;
|
||||
int offset;
|
||||
|
||||
if(!gpio_base)
|
||||
return;
|
||||
|
||||
offset = GPIO_DOEN_X_REG + (gpio & ~0x3);
|
||||
|
||||
spin_lock(&sfg_lock);
|
||||
value = ioread32(gpio_base + offset);
|
||||
value &= ~(0x3f << ((offset & 0x3) * 8));
|
||||
value |= (v & 0x3f) << ((offset & 0x3) * 8);
|
||||
iowrite32(value,gpio_base + offset);
|
||||
spin_unlock(&sfg_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_doen_value);
|
||||
|
||||
void sf_vic_gpio_doen_low(int gpio)
|
||||
{
|
||||
sf_vic_gpio_doen_value(gpio, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_doen_low);
|
||||
|
||||
void sf_vic_gpio_doen_high(int gpio)
|
||||
{
|
||||
sf_vic_gpio_doen_value(gpio, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_doen_high);
|
||||
|
||||
void sf_vic_gpio_manual(int offset,int v)
|
||||
{
|
||||
unsigned int value;
|
||||
|
||||
if(!gpio_base)
|
||||
return ;
|
||||
|
||||
spin_lock(&sfg_lock);
|
||||
value = ioread32(gpio_base + offset);
|
||||
value &= ~(0xFF);
|
||||
value |= (v&0xFF);
|
||||
iowrite32(value,gpio_base + offset);
|
||||
spin_unlock(&sfg_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sf_vic_gpio_manual);
|
||||
|
||||
static int str_to_num(char *str)
|
||||
{
|
||||
char *p = str;
|
||||
int value = 0;
|
||||
|
||||
if((*p == '0') && (*(p + 1) == 'x' || *(p + 1) == 'X')) {
|
||||
p = p + 2;
|
||||
while(((*p >= '0') && (*p <= '9')) ||
|
||||
((*p >= 'a') && (*p <= 'f')) ||
|
||||
((*p >= 'A') && (*p <= 'F'))) {
|
||||
if((*p >= '0') && (*p <= '9'))
|
||||
value = value * 16 + (*p - '0');
|
||||
if((*p >= 'a') && (*p <= 'f'))
|
||||
value = value * 16 + 10 + (*p - 'a');
|
||||
if((*p >= 'A') && (*p <= 'F'))
|
||||
value = value * 16 + 10 + (*p - 'A');
|
||||
p = p + 1;
|
||||
}
|
||||
} else {
|
||||
while((*p >= '0') && (*p <= '9')) {
|
||||
value = value * 10 + (*p - '0');
|
||||
p = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(*p != '\0')
|
||||
return -EFAULT;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static ssize_t vic_gpio_proc_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
char message[64], cmd[8],gnum[8],v[8];
|
||||
int gpionum, value;
|
||||
|
||||
if (mutex_lock_interruptible(&write_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = copy_from_user(message, buf, count);
|
||||
mutex_unlock(&write_lock);
|
||||
if(ret)
|
||||
return -EFAULT;
|
||||
sscanf(message, "%s %s %s", cmd, gnum, v);
|
||||
gpionum = str_to_num(gnum);
|
||||
if(gpionum < 0)
|
||||
return -EFAULT;
|
||||
value = str_to_num(v);
|
||||
if(value < 0)
|
||||
return -EFAULT;
|
||||
|
||||
if(!strcmp(cmd,"dout")) {
|
||||
if(gpionum < 0 || gpionum > 63){
|
||||
printk(KERN_ERR "vic-gpio: dout gpionum (0-63) value (0/1) invalid: gpionum = %d value = %d\n",
|
||||
gpionum,value);
|
||||
return -EFAULT;
|
||||
}
|
||||
sf_vic_gpio_dout_value(gpionum, value);
|
||||
}else if(!strcmp(cmd,"doen")) {
|
||||
if(gpionum < 0 || gpionum > 63){
|
||||
printk(KERN_ERR "vic-gpio: doen gpionum (0-63) value (0/1) invalid: gpionum = %d value = %d\n",
|
||||
gpionum,value);
|
||||
return -EFAULT;
|
||||
}
|
||||
sf_vic_gpio_doen_value(gpionum,value);
|
||||
}else if(!strcmp(cmd,"utrv")) {
|
||||
if(gpionum < 0 || gpionum > 63){
|
||||
printk(KERN_ERR "vic-gpio: utrv gpionum (0-63) is invalid: %d\n",gpionum);
|
||||
return -EFAULT;
|
||||
}
|
||||
sf_vic_gpio_doen_reverse(gpionum,value);
|
||||
}else if(!strcmp(cmd,"enrv")) {
|
||||
if(gpionum < 0 || gpionum > 63){
|
||||
printk(KERN_ERR "vic-gpio: enrv gpionum (0-63) is invalid: %d\n",gpionum);
|
||||
return -EFAULT;
|
||||
}
|
||||
sf_vic_gpio_doen_reverse(gpionum, value);
|
||||
}else if(!strcmp(cmd,"manu")) {
|
||||
if(gpionum < 0x250 || gpionum > 0x378 || (gpionum & 0x3)){
|
||||
printk(KERN_ERR "vic-gpio: manu offset (0x250-0x378 & mod 4) is invalid: %d\n",gpionum);
|
||||
return -EFAULT;
|
||||
}
|
||||
sf_vic_gpio_manual(gpionum, value);
|
||||
}else {
|
||||
printk(KERN_ERR "vic-gpio: cmd (dout doen utrv enrv manu) invalid: %s\n",cmd);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t vic_gpio_proc_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
unsigned int copied;
|
||||
char message[256];
|
||||
|
||||
sprintf(message, "Usage: echo 'cmd gpionum value' >/proc/vic_gpio\n\t"
|
||||
"cmd: dout doen utrv enrv or manu\n\t"
|
||||
"gpionum: gpionum or address offset for manu\n\t"
|
||||
"value: 0/1 for utrv/enrv, value for dout/doen/manual\n");
|
||||
copied = strlen(message);
|
||||
|
||||
if(*ppos >= copied)
|
||||
return 0;
|
||||
|
||||
if (mutex_lock_interruptible(&read_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = copy_to_user(buf, message, copied);
|
||||
if(ret) {
|
||||
mutex_unlock(&read_lock);
|
||||
}
|
||||
*ppos += copied;
|
||||
|
||||
mutex_unlock(&read_lock);
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
static const struct file_operations vic_gpio_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = vic_gpio_proc_read,
|
||||
.write = vic_gpio_proc_write,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static int sfvic7110_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct sfvic7110_gpio *chip;
|
||||
struct resource *res;
|
||||
int irq, ret, ngpio;
|
||||
int loop;
|
||||
struct gpio_irq_chip *girq;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct device_node *irq_parent;
|
||||
struct irq_domain *parent;
|
||||
|
||||
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip) {
|
||||
dev_err(dev, "out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
chip->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(chip->base)) {
|
||||
dev_err(dev, "failed to allocate device memory\n");
|
||||
return PTR_ERR(chip->base);
|
||||
}
|
||||
gpio_base = chip->base ;
|
||||
|
||||
ngpio = 64;
|
||||
|
||||
raw_spin_lock_init(&chip->lock);
|
||||
chip->gc.direction_input = sfvic7110_direction_input;
|
||||
chip->gc.direction_output = sfvic7110_direction_output;
|
||||
chip->gc.get_direction = sfvic7110_get_direction;
|
||||
chip->gc.get = sfvic7110_get_value;
|
||||
chip->gc.set = sfvic7110_set_value;
|
||||
chip->gc.base = 0;
|
||||
chip->gc.ngpio = ngpio;
|
||||
chip->gc.label = dev_name(dev);
|
||||
chip->gc.parent = dev;
|
||||
chip->gc.owner = THIS_MODULE;
|
||||
|
||||
irq_parent = of_irq_find_parent(node);
|
||||
if (!irq_parent) {
|
||||
dev_err(dev, "no IRQ parent node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
parent = irq_find_host(irq_parent);
|
||||
if (!parent) {
|
||||
dev_err(dev, "no IRQ parent domain\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
girq = &chip->gc.irq;
|
||||
girq->chip = &sfvic7110_irqchip;
|
||||
girq->fwnode = of_node_to_fwnode(node);
|
||||
girq->parent_domain = parent;
|
||||
girq->child_to_parent_hwirq = starfive_gpio_child_to_parent_hwirq;
|
||||
girq->handler = handle_simple_irq;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
|
||||
/* Disable all GPIO interrupts before enabling parent interrupts */
|
||||
iowrite32(0, chip->base + GPIO_IE_HIGH);
|
||||
iowrite32(0, chip->base + GPIO_IE_LOW);
|
||||
chip->enabled = 0;
|
||||
|
||||
platform_set_drvdata(pdev, chip);
|
||||
ret = gpiochip_add_data(&chip->gc, chip);
|
||||
if (ret){
|
||||
dev_err(dev, "gpiochip_add_data ret=%d!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Disable all GPIO interrupts before enabling parent interrupts */
|
||||
iowrite32(0, chip->base + GPIO_IE_HIGH);
|
||||
iowrite32(0, chip->base + GPIO_IE_LOW);
|
||||
chip->enabled = 0;
|
||||
|
||||
ret = gpiochip_gpiochip_add(&chip->gc, &sfvic7110_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not add irqchip\n");
|
||||
gpiochip_remove(&chip->gc);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "Cannot get IRQ resource\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
chip->irq_parent[0] = irq;
|
||||
|
||||
ret = devm_request_irq(dev, irq, sfvic7110_irq_handler, IRQF_SHARED,
|
||||
dev_name(dev), chip);
|
||||
if (ret) {
|
||||
dev_err(dev, "IRQ handler registering failed (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
writel_relaxed(1, chip->base + GPIO_EN);
|
||||
|
||||
for(loop = 0; loop < MAX_GPIO; loop++) {
|
||||
unsigned int v;
|
||||
v = readl_relaxed(chip->base + GPIO_INPUT_ENABLE_X_REG + (loop << 2));
|
||||
v |= 0x1;
|
||||
writel_relaxed(v, chip->base + GPIO_INPUT_ENABLE_X_REG + (loop << 2));
|
||||
}
|
||||
|
||||
if (proc_create(PROC_VIC, 0, NULL, (void *)&vic_gpio_fops) == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev_info(dev, "SiFive GPIO chip registered %d GPIOs\n", ngpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sfvic7110_gpio_match[] = {
|
||||
{ .compatible = "starfive,gpio7110", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver sfvic7110_gpio_driver = {
|
||||
.probe = sfvic7110_gpio_probe,
|
||||
.driver = {
|
||||
.name = "sfvic7110_gpio",
|
||||
.of_match_table = of_match_ptr(sfvic7110_gpio_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sfvic7110_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&sfvic7110_gpio_driver);
|
||||
}
|
||||
subsys_initcall(sfvic7110_gpio_init);
|
||||
|
||||
static void __exit sfvic7110_gpio_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sfvic7110_gpio_driver);
|
||||
}
|
||||
module_exit(sfvic7110_gpio_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
|
||||
MODULE_DESCRIPTION("Starfive VIC GPIO generator driver");
|
|
@ -493,6 +493,7 @@ static int dwc_eth_dwmac_remove(struct platform_device *pdev)
|
|||
|
||||
static const struct of_device_id dwc_eth_dwmac_match[] = {
|
||||
{ .compatible = "snps,dwc-qos-ethernet-4.10", .data = &dwc_qos_data },
|
||||
{ .compatible = "snps,dwc-qos-ethernet-5.10a", .data = &dwc_qos_data },
|
||||
{ .compatible = "nvidia,tegra186-eqos", .data = &tegra_eqos_data },
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -213,6 +213,24 @@ static const struct stmmac_hwif_entry {
|
|||
.mmc = &dwmac_mmc_ops,
|
||||
.setup = dwmac4_setup,
|
||||
.quirks = NULL,
|
||||
}, {
|
||||
.gmac = false,
|
||||
.gmac4 = true,
|
||||
.xgmac = false,
|
||||
.min_id = DWMAC_CORE_5_20,
|
||||
.regs = {
|
||||
.ptp_off = PTP_GMAC4_OFFSET,
|
||||
.mmc_off = MMC_GMAC4_OFFSET,
|
||||
},
|
||||
.desc = &dwmac4_desc_ops,
|
||||
.dma = &dwmac410_dma_ops,
|
||||
.mac = &dwmac510_ops,
|
||||
.hwtimestamp = &stmmac_ptp,
|
||||
.mode = &dwmac4_ring_mode_ops,
|
||||
.tc = &dwmac510_tc_ops,
|
||||
.mmc = &dwmac_mmc_ops,
|
||||
.setup = dwmac4_setup,
|
||||
.quirks = NULL,
|
||||
}, {
|
||||
.gmac = false,
|
||||
.gmac4 = false,
|
||||
|
|
|
@ -551,9 +551,20 @@ static int m88e1121_config_aneg_rgmii_delays(struct phy_device *phydev)
|
|||
else
|
||||
mscr = 0;
|
||||
|
||||
#if defined(CONFIG_FPGA_GMAC_SPEED10)
|
||||
return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
|
||||
MII_88E1121_PHY_MSCR_REG,
|
||||
MII_88E1121_PHY_MSCR_DELAY_MASK|BIT(6)|BIT(13),
|
||||
mscr);
|
||||
#elif defined(CONFIG_FPGA_GMAC_SPEED100)
|
||||
return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
|
||||
MII_88E1121_PHY_MSCR_REG,
|
||||
MII_88E1121_PHY_MSCR_DELAY_MASK|BIT(13), mscr);
|
||||
#else
|
||||
return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE,
|
||||
MII_88E1121_PHY_MSCR_REG,
|
||||
MII_88E1121_PHY_MSCR_DELAY_MASK, mscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int m88e1121_config_aneg(struct phy_device *phydev)
|
||||
|
|
|
@ -894,6 +894,48 @@ static int ksz9031_config_init(struct phy_device *phydev)
|
|||
goto err_force_master;
|
||||
}
|
||||
}
|
||||
#if defined(CONFIG_FPGA_GMAC_SPEED10)
|
||||
/* set to 10M
|
||||
bit [6, 13]
|
||||
[1,1] = Reserved
|
||||
[1,0] = 1000 Mbps
|
||||
[0,1] = 100 Mbps
|
||||
[0,0] = 10 Mbps
|
||||
*/
|
||||
result = phy_read(phydev, MII_BMCR);
|
||||
result &=~(BIT(6)|BIT(13));
|
||||
result = phy_write(phydev, MII_BMCR, result);
|
||||
if (result < 0)
|
||||
goto err_force_master;
|
||||
|
||||
/* remove Auto-Negotiation advertisements for 1000 Mbps full-/half-duplex*/
|
||||
result = phy_read(phydev, MII_CTRL1000);
|
||||
result &=~(BIT(8)|BIT(9));
|
||||
result = phy_write(phydev, MII_CTRL1000, result);
|
||||
if (result < 0)
|
||||
goto err_force_master;
|
||||
#elif defined(CONFIG_FPGA_GMAC_SPEED100)
|
||||
/* set to 100M
|
||||
bit [6, 13]
|
||||
[1,1] = Reserved
|
||||
[1,0] = 1000 Mbps
|
||||
[0,1] = 100 Mbps
|
||||
[0,0] = 10 Mbps
|
||||
*/
|
||||
result = phy_read(phydev, MII_BMCR);
|
||||
result &=~BIT(6);
|
||||
result |=BIT(13);
|
||||
result = phy_write(phydev, MII_BMCR, result);
|
||||
if (result < 0)
|
||||
goto err_force_master;
|
||||
|
||||
/* remove Auto-Negotiation advertisements for 1000 Mbps full-/half-duplex*/
|
||||
result = phy_read(phydev, MII_CTRL1000);
|
||||
result &=~(BIT(8)|BIT(9));
|
||||
result = phy_write(phydev, MII_CTRL1000, result);
|
||||
if (result < 0)
|
||||
goto err_force_master;
|
||||
#endif
|
||||
|
||||
return ksz9031_center_flp_timing(phydev);
|
||||
|
||||
|
|
|
@ -589,13 +589,24 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
|
|||
mdiodev->device_free = phy_mdio_device_free;
|
||||
mdiodev->device_remove = phy_mdio_device_remove;
|
||||
|
||||
#if defined(CONFIG_FPGA_GMAC_SPEED10)
|
||||
dev->speed = SPEED_10;
|
||||
dev->duplex = DUPLEX_FULL;
|
||||
dev->interface = PHY_INTERFACE_MODE_RGMII;
|
||||
#elif defined(CONFIG_FPGA_GMAC_SPEED100)
|
||||
dev->speed = SPEED_100;
|
||||
dev->duplex = DUPLEX_FULL;
|
||||
dev->interface = PHY_INTERFACE_MODE_RGMII;
|
||||
#else
|
||||
dev->speed = SPEED_UNKNOWN;
|
||||
dev->duplex = DUPLEX_UNKNOWN;
|
||||
dev->interface = PHY_INTERFACE_MODE_GMII;
|
||||
#endif
|
||||
dev->pause = 0;
|
||||
dev->asym_pause = 0;
|
||||
dev->link = 0;
|
||||
dev->port = PORT_TP;
|
||||
dev->interface = PHY_INTERFACE_MODE_GMII;
|
||||
// dev->interface = PHY_INTERFACE_MODE_GMII;
|
||||
|
||||
dev->autoneg = AUTONEG_ENABLE;
|
||||
|
||||
|
@ -1910,6 +1921,13 @@ static int genphy_config_advert(struct phy_device *phydev)
|
|||
if (err > 0)
|
||||
changed = 1;
|
||||
|
||||
#if defined(CONFIG_FPGA_GMAC_SPEED10)
|
||||
err = phy_write(phydev, MII_ADVERTISE, 0x61);
|
||||
//Auto-Negotiation Advertisement 10M
|
||||
#elif defined(CONFIG_FPGA_GMAC_SPEED100)
|
||||
err = phy_write(phydev, MII_ADVERTISE, 0x181);
|
||||
//Auto-Negotiation Advertisement 100M
|
||||
#endif
|
||||
bmsr = phy_read(phydev, MII_BMSR);
|
||||
if (bmsr < 0)
|
||||
return bmsr;
|
||||
|
@ -1923,9 +1941,19 @@ static int genphy_config_advert(struct phy_device *phydev)
|
|||
|
||||
adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
|
||||
|
||||
#if defined(CONFIG_FPGA_GMAC_SPEED10)
|
||||
err = phy_modify_changed(phydev, MII_CTRL1000,
|
||||
ADVERTISE_1000FULL | ADVERTISE_1000HALF,
|
||||
0);
|
||||
#elif defined(CONFIG_FPGA_GMAC_SPEED100)
|
||||
err = phy_modify_changed(phydev, MII_CTRL1000,
|
||||
ADVERTISE_1000FULL | ADVERTISE_1000HALF,
|
||||
0);
|
||||
#else
|
||||
err = phy_modify_changed(phydev, MII_CTRL1000,
|
||||
ADVERTISE_1000FULL | ADVERTISE_1000HALF,
|
||||
adv);
|
||||
#endif
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (err > 0)
|
||||
|
|
|
@ -7,4 +7,20 @@ config SIFIVE_L2
|
|||
help
|
||||
Support for the L2 cache controller on SiFive platforms.
|
||||
|
||||
config SIFIVE_L2_FLUSH
|
||||
bool "Support Level 2 Cache Controller Flush operation of SiFive Soc"
|
||||
|
||||
if SIFIVE_L2_FLUSH
|
||||
|
||||
config SIFIVE_L2_FLUSH_START
|
||||
hex "Level 2 Cache Flush operation start"
|
||||
default 0x80000000
|
||||
default 0x40000000 if SOC_STARFIVE_JH7110
|
||||
|
||||
config SIFIVE_L2_FLUSH_SIZE
|
||||
hex "Level 2 Cache Flush operation size"
|
||||
default 0x800000000
|
||||
default 0x400000000 if SOC_STARFIVE_JH7110
|
||||
|
||||
endif # SIFIVE_L2_FLUSH
|
||||
endif
|
||||
|
|
|
@ -29,12 +29,15 @@
|
|||
#define SIFIVE_L2_DATECCFAIL_HIGH 0x164
|
||||
#define SIFIVE_L2_DATECCFAIL_COUNT 0x168
|
||||
|
||||
#define SIFIVE_L2_FLUSH64 0x200
|
||||
|
||||
#define SIFIVE_L2_CONFIG 0x00
|
||||
#define SIFIVE_L2_WAYENABLE 0x08
|
||||
#define SIFIVE_L2_ECCINJECTERR 0x40
|
||||
|
||||
#define SIFIVE_L2_MAX_ECCINTR 4
|
||||
|
||||
#define SIFIVE_L2_FLUSH64_LINE_LEN 64
|
||||
static void __iomem *l2_base;
|
||||
static int g_irq[SIFIVE_L2_MAX_ECCINTR];
|
||||
static struct riscv_cacheinfo_ops l2_cache_ops;
|
||||
|
@ -116,6 +119,41 @@ int unregister_sifive_l2_error_notifier(struct notifier_block *nb)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_sifive_l2_error_notifier);
|
||||
|
||||
#ifdef CONFIG_SIFIVE_L2_FLUSH
|
||||
void sifive_l2_flush64_range(unsigned long start, unsigned long len)
|
||||
{
|
||||
unsigned long line;
|
||||
|
||||
if(!l2_base) {
|
||||
pr_warn("L2CACHE: base addr invalid, skipping flush\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: if (len == 0), skipping flush or going on? */
|
||||
if(!len) {
|
||||
pr_debug("L2CACHE: flush64 range @ 0x%lx(len:0)\n", start);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure the address is in the range */
|
||||
if(start < CONFIG_SIFIVE_L2_FLUSH_START ||
|
||||
(start + len) > (CONFIG_SIFIVE_L2_FLUSH_START +
|
||||
CONFIG_SIFIVE_L2_FLUSH_SIZE)) {
|
||||
pr_warn("L2CACHE: flush64 out of range: %lx(%lx), skip flush\n",
|
||||
start, len);
|
||||
return;
|
||||
}
|
||||
|
||||
mb(); /* sync */
|
||||
for (line = start; line < start + len;
|
||||
line += SIFIVE_L2_FLUSH64_LINE_LEN) {
|
||||
writeq(line, l2_base + SIFIVE_L2_FLUSH64);
|
||||
mb();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sifive_l2_flush64_range);
|
||||
#endif
|
||||
|
||||
static int l2_largest_wayenabled(void)
|
||||
{
|
||||
return readl(l2_base + SIFIVE_L2_WAYENABLE) & 0xFF;
|
||||
|
|
|
@ -13,4 +13,8 @@ extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb);
|
|||
#define SIFIVE_L2_ERR_TYPE_CE 0
|
||||
#define SIFIVE_L2_ERR_TYPE_UE 1
|
||||
|
||||
#ifdef CONFIG_SIFIVE_L2_FLUSH
|
||||
void sifive_l2_flush64_range(unsigned long start, unsigned long len);
|
||||
#endif
|
||||
|
||||
#endif /* __SOC_SIFIVE_L2_CACHE_H */
|
||||
|
|
17
include/soc/starfive/vic7100.h
Normal file
17
include/soc/starfive/vic7100.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef STARFIVE_VIC7100_H
|
||||
#define STARFIVE_VIC7100_H
|
||||
#include <asm/io.h>
|
||||
#include <soc/sifive/sifive_l2_cache.h>
|
||||
|
||||
/*cache.c*/
|
||||
#define starfive_flush_dcache(start, len) \
|
||||
sifive_l2_flush64_range(start, len)
|
||||
|
||||
void *dw_phys_to_virt(dma_addr_t phys);
|
||||
dma_addr_t dw_virt_to_phys(void *vaddr);
|
||||
|
||||
int async_memcpy_single(dma_addr_t dst_dma, dma_addr_t src_dma, size_t size);
|
||||
int async_memcpy_single_virt(void *dst, void *src, size_t size);
|
||||
int async_memcpy_test(size_t size);
|
||||
|
||||
#endif /*STARFIVE_VIC7100_H*/
|
328
usr/gen_initramfs_list.sh
Executable file
328
usr/gen_initramfs_list.sh
Executable file
|
@ -0,0 +1,328 @@
|
|||
#!/bin/sh
|
||||
# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
|
||||
# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
|
||||
#
|
||||
# Released under the terms of the GNU GPL
|
||||
#
|
||||
# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
|
||||
# the cpio archive, and then compresses it.
|
||||
# The script may also be used to generate the inputfile used for gen_init_cpio
|
||||
# This script assumes that gen_init_cpio is located in usr/ directory
|
||||
|
||||
# error out on errors
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage:
|
||||
$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
|
||||
-o <file> Create compressed initramfs file named <file> using
|
||||
gen_init_cpio and compressor depending on the extension
|
||||
-u <uid> User ID to map to user ID 0 (root).
|
||||
<uid> is only meaningful if <cpio_source> is a
|
||||
directory. "squash" forces all files to uid 0.
|
||||
-g <gid> Group ID to map to group ID 0 (root).
|
||||
<gid> is only meaningful if <cpio_source> is a
|
||||
directory. "squash" forces all files to gid 0.
|
||||
<cpio_source> File list or directory for cpio archive.
|
||||
If <cpio_source> is a .cpio file it will be used
|
||||
as direct input to initramfs.
|
||||
-d Output the default cpio list.
|
||||
|
||||
All options except -o and -l may be repeated and are interpreted
|
||||
sequentially and immediately. -u and -g states are preserved across
|
||||
<cpio_source> options so an explicit "-u 0 -g 0" is required
|
||||
to reset the root/group mapping.
|
||||
EOF
|
||||
}
|
||||
|
||||
# awk style field access
|
||||
# $1 - field number; rest is argument string
|
||||
field() {
|
||||
shift $1 ; echo $1
|
||||
}
|
||||
|
||||
list_default_initramfs() {
|
||||
# echo usr/kinit/kinit
|
||||
:
|
||||
}
|
||||
|
||||
default_initramfs() {
|
||||
cat <<-EOF >> ${output}
|
||||
# This is a very simple, default initramfs
|
||||
|
||||
dir /dev 0755 0 0
|
||||
nod /dev/console 0600 0 0 c 5 1
|
||||
dir /root 0700 0 0
|
||||
# file /kinit usr/kinit/kinit 0755 0 0
|
||||
# slink /init kinit 0755 0 0
|
||||
EOF
|
||||
}
|
||||
|
||||
filetype() {
|
||||
local argv1="$1"
|
||||
|
||||
# symlink test must come before file test
|
||||
if [ -L "${argv1}" ]; then
|
||||
echo "slink"
|
||||
elif [ -f "${argv1}" ]; then
|
||||
echo "file"
|
||||
elif [ -d "${argv1}" ]; then
|
||||
echo "dir"
|
||||
elif [ -b "${argv1}" -o -c "${argv1}" ]; then
|
||||
echo "nod"
|
||||
elif [ -p "${argv1}" ]; then
|
||||
echo "pipe"
|
||||
elif [ -S "${argv1}" ]; then
|
||||
echo "sock"
|
||||
else
|
||||
echo "invalid"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
list_print_mtime() {
|
||||
:
|
||||
}
|
||||
|
||||
print_mtime() {
|
||||
local my_mtime="0"
|
||||
|
||||
if [ -e "$1" ]; then
|
||||
my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
|
||||
fi
|
||||
|
||||
echo "# Last modified: ${my_mtime}" >> ${output}
|
||||
echo "" >> ${output}
|
||||
}
|
||||
|
||||
list_parse() {
|
||||
if [ -L "$1" ]; then
|
||||
return
|
||||
fi
|
||||
echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
|
||||
}
|
||||
|
||||
# for each file print a line in following format
|
||||
# <filetype> <name> <path to file> <octal mode> <uid> <gid>
|
||||
# for links, devices etc the format differs. See gen_init_cpio for details
|
||||
parse() {
|
||||
local location="$1"
|
||||
local name="/${location#${srcdir}}"
|
||||
# change '//' into '/'
|
||||
name=$(echo "$name" | sed -e 's://*:/:g')
|
||||
local mode="$2"
|
||||
local uid="$3"
|
||||
local gid="$4"
|
||||
local ftype=$(filetype "${location}")
|
||||
# remap uid/gid to 0 if necessary
|
||||
[ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
|
||||
[ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
|
||||
local str="${mode} ${uid} ${gid}"
|
||||
|
||||
[ "${ftype}" = "invalid" ] && return 0
|
||||
[ "${location}" = "${srcdir}" ] && return 0
|
||||
|
||||
case "${ftype}" in
|
||||
"file")
|
||||
str="${ftype} ${name} ${location} ${str}"
|
||||
;;
|
||||
"nod")
|
||||
local dev=`LC_ALL=C ls -l "${location}"`
|
||||
local maj=`field 5 ${dev}`
|
||||
local min=`field 6 ${dev}`
|
||||
maj=${maj%,}
|
||||
|
||||
[ -b "${location}" ] && dev="b" || dev="c"
|
||||
|
||||
str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
|
||||
;;
|
||||
"slink")
|
||||
local target=`readlink "${location}"`
|
||||
str="${ftype} ${name} ${target} ${str}"
|
||||
;;
|
||||
*)
|
||||
str="${ftype} ${name} ${str}"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "${str}" >> ${output}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
unknown_option() {
|
||||
printf "ERROR: unknown option \"$arg\"\n" >&2
|
||||
printf "If the filename validly begins with '-', " >&2
|
||||
printf "then it must be prefixed\n" >&2
|
||||
printf "by './' so that it won't be interpreted as an option." >&2
|
||||
printf "\n" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
list_header() {
|
||||
:
|
||||
}
|
||||
|
||||
header() {
|
||||
printf "\n#####################\n# $1\n" >> ${output}
|
||||
}
|
||||
|
||||
# process one directory (incl sub-directories)
|
||||
dir_filelist() {
|
||||
${dep_list}header "$1"
|
||||
|
||||
srcdir=$(echo "$1" | sed -e 's://*:/:g')
|
||||
dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort)
|
||||
|
||||
# If $dirlist is only one line, then the directory is empty
|
||||
if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
|
||||
${dep_list}print_mtime "$1"
|
||||
|
||||
echo "${dirlist}" | \
|
||||
while read x; do
|
||||
${dep_list}parse ${x}
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# if only one file is specified and it is .cpio file then use it direct as fs
|
||||
# if a directory is specified then add all files in given direcotry to fs
|
||||
# if a regular file is specified assume it is in gen_initramfs format
|
||||
input_file() {
|
||||
source="$1"
|
||||
if [ -f "$1" ]; then
|
||||
${dep_list}header "$1"
|
||||
is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
|
||||
if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
|
||||
cpio_file=$1
|
||||
echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
|
||||
[ ! -z ${dep_list} ] && echo "$1"
|
||||
return 0
|
||||
fi
|
||||
if [ -z ${dep_list} ]; then
|
||||
print_mtime "$1" >> ${output}
|
||||
cat "$1" >> ${output}
|
||||
else
|
||||
echo "$1 \\"
|
||||
cat "$1" | while read type dir file perm ; do
|
||||
if [ "$type" = "file" ]; then
|
||||
echo "$file \\";
|
||||
fi
|
||||
done
|
||||
fi
|
||||
elif [ -d "$1" ]; then
|
||||
dir_filelist "$1"
|
||||
else
|
||||
echo " ${prog}: Cannot open '$1'" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
prog=$0
|
||||
root_uid=0
|
||||
root_gid=0
|
||||
dep_list=
|
||||
cpio_file=
|
||||
cpio_list=
|
||||
output="/dev/stdout"
|
||||
output_file=""
|
||||
is_cpio_compressed=
|
||||
compr="gzip -n -9 -f"
|
||||
|
||||
arg="$1"
|
||||
case "$arg" in
|
||||
"-l") # files included in initramfs - used by kbuild
|
||||
dep_list="list_"
|
||||
echo "deps_initramfs := $0 \\"
|
||||
shift
|
||||
;;
|
||||
"-o") # generate compressed cpio image named $1
|
||||
shift
|
||||
output_file="$1"
|
||||
cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
|
||||
output=${cpio_list}
|
||||
echo "$output_file" | grep -q "\.gz$" \
|
||||
&& [ -x "`which gzip 2> /dev/null`" ] \
|
||||
&& compr="gzip -n -9 -f"
|
||||
echo "$output_file" | grep -q "\.bz2$" \
|
||||
&& [ -x "`which bzip2 2> /dev/null`" ] \
|
||||
&& compr="bzip2 -9 -f"
|
||||
echo "$output_file" | grep -q "\.lzma$" \
|
||||
&& [ -x "`which lzma 2> /dev/null`" ] \
|
||||
&& compr="lzma -9 -f"
|
||||
echo "$output_file" | grep -q "\.xz$" \
|
||||
&& [ -x "`which xz 2> /dev/null`" ] \
|
||||
&& compr="xz --check=crc32 --lzma2=dict=1MiB"
|
||||
echo "$output_file" | grep -q "\.lzo$" \
|
||||
&& [ -x "`which lzop 2> /dev/null`" ] \
|
||||
&& compr="lzop -9 -f"
|
||||
echo "$output_file" | grep -q "\.lz4$" \
|
||||
&& [ -x "`which lz4 2> /dev/null`" ] \
|
||||
&& compr="lz4 -l -9 -f"
|
||||
echo "$output_file" | grep -q "\.cpio$" && compr="cat"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
while [ $# -gt 0 ]; do
|
||||
arg="$1"
|
||||
shift
|
||||
case "$arg" in
|
||||
"-u") # map $1 to uid=0 (root)
|
||||
root_uid="$1"
|
||||
[ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
|
||||
shift
|
||||
;;
|
||||
"-g") # map $1 to gid=0 (root)
|
||||
root_gid="$1"
|
||||
[ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
|
||||
shift
|
||||
;;
|
||||
"-d") # display default initramfs list
|
||||
default_list="$arg"
|
||||
${dep_list}default_initramfs
|
||||
;;
|
||||
"-h")
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
case "$arg" in
|
||||
"-"*)
|
||||
unknown_option
|
||||
;;
|
||||
*) # input file/dir - process it
|
||||
input_file "$arg" "$#"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If output_file is set we will generate cpio archive and compress it
|
||||
# we are careful to delete tmp files
|
||||
if [ ! -z ${output_file} ]; then
|
||||
if [ -z ${cpio_file} ]; then
|
||||
timestamp=
|
||||
if test -n "$KBUILD_BUILD_TIMESTAMP"; then
|
||||
timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
|
||||
if test -n "$timestamp"; then
|
||||
timestamp="-t $timestamp"
|
||||
fi
|
||||
fi
|
||||
cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
|
||||
usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
|
||||
else
|
||||
cpio_tfile=${cpio_file}
|
||||
fi
|
||||
rm ${cpio_list}
|
||||
if [ "${is_cpio_compressed}" = "compressed" ]; then
|
||||
cat ${cpio_tfile} > ${output_file}
|
||||
else
|
||||
(cat ${cpio_tfile} | ${compr} - > ${output_file}) \
|
||||
|| (rm -f ${output_file} ; false)
|
||||
fi
|
||||
[ -z ${cpio_file} ] && rm ${cpio_tfile}
|
||||
fi
|
||||
exit 0
|
Loading…
Add table
Reference in a new issue