Prepare to add Ingenic T40 (#737)

pull/738/head
cronyx 2023-04-21 22:59:53 +03:00 committed by GitHub
parent 20751cee07
commit 9dbeb31891
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
727 changed files with 192430 additions and 0 deletions

View File

@ -3,6 +3,7 @@ source "$BR2_EXTERNAL_INGENIC_PATH/package/ingenic-osdrv-t20/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/ingenic-osdrv-t21/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/ingenic-osdrv-t30/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/ingenic-osdrv-t31/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/ingenic-osdrv-t40/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/ingenic_patcher/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/aura-httpd/Config.in"
source "$BR2_EXTERNAL_INGENIC_PATH/package/comgt/Config.in"

View File

@ -0,0 +1,25 @@
diff -drupN a/Makefile b/Makefile
--- a/Makefile 2017-10-21 18:09:07.000000000 +0300
+++ b/Makefile 2022-06-09 05:02:26.000000000 +0300
@@ -252,7 +252,7 @@ SUBARCH := $(shell uname -m | sed -e s/i
# "make" in the configured kernel build directory always uses that.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
-ARCH ?= $(SUBARCH)
+ARCH ?= mips
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
# Architecture as present in compile.h
@@ -1195,10 +1195,10 @@ CLEAN_DIRS += $(MODVERDIR)
MRPROPER_DIRS += include/config usr/include include/generated \
arch/*/include/generated .tmp_objdiff
MRPROPER_FILES += .config .config.old .version .old_version \
- Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
+ Module.symvers TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
signing_key.pem signing_key.priv signing_key.x509 \
x509.genkey extra_certificates signing_key.x509.keyid \
- signing_key.x509.signer vmlinux-gdb.py
+ signing_key.x509.signer vmlinux-gdb.py #tags \
# clean - Delete most, but leave enough to build external modules
#

View File

@ -0,0 +1,12 @@
diff -drupN a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
--- a/arch/mips/Kbuild.platforms 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/Kbuild.platforms 2022-06-09 05:02:26.000000000 +0300
@@ -34,6 +34,8 @@ platforms += sni
platforms += txx9
platforms += vr41xx
platforms += xilfpga
+platforms += xburst
+platforms += xburst2
# include the platform specific files
include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))

View File

@ -0,0 +1,12 @@
diff -drupN a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
--- a/arch/mips/Kconfig.debug 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/Kconfig.debug 2022-06-09 05:02:26.000000000 +0300
@@ -8,7 +8,7 @@ source "lib/Kconfig.debug"
config EARLY_PRINTK
bool "Early printk" if EXPERT
- depends on SYS_HAS_EARLY_PRINTK
+ depends on SYS_HAS_EARLY_PRINTK && !FAST_BOOT
default y
help
This option enables special console drivers which allow the kernel

View File

@ -0,0 +1,101 @@
diff -drupN a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/Kconfig 2022-06-09 05:02:26.000000000 +0300
@@ -299,7 +299,7 @@ config MACH_JAZZ
Olivetti M700-10 workstations.
config MACH_INGENIC
- bool "Ingenic SoC based machines"
+ bool "Ingenic SoC based machines, only for jz4740,4780"
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_ZBOOT_UART16550
@@ -312,6 +312,53 @@ config MACH_INGENIC
select USE_OF
select LIBFDT
+config MACH_XBURST
+ bool "Ingenic Xburst based machines"
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select MIPS_EXTERNAL_TIMER
+ select DMA_NONCOHERENT
+ select HAVE_CLK
+ select ARCH_REQUIRE_GPIOLIB
+ select SYS_SUPPORTS_HIGHMEM
+ select XBURST_CPU_SCACHE
+ select DMA_INGENIC_HIGHMEM_FLUSH
+ select HAVE_KERNEL_LZMA
+ select IRQ_MIPS_CPU
+ select USE_OF
+ select LIBFDT
+ select COMMON_CLK
+
+config MACH_XBURST2
+ bool "Ingenic Xburst2 based machines"
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select MIPS_EXTERNAL_TIMER
+ select DMA_NONCOHERENT
+ select HAVE_CLK
+ select ARCH_REQUIRE_GPIOLIB
+ select SYS_SUPPORTS_HIGHMEM
+ select XBURST2_CPU_SCACHE
+ select DMA_INGENIC_HIGHMEM_FLUSH
+ select SYS_SUPPORTS_ZBOOT
+ select IRQ_MIPS_CPU
+ select USE_OF
+ select LIBFDT
+ select MIPS_O32_FP64_SUPPORT
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ select COMMON_CLK
+ select OF_RESERVED_MEM
+
+
config LANTIQ
bool "Lantiq based platforms"
select DMA_NONCOHERENT
@@ -994,6 +1041,8 @@ source "arch/mips/loongson64/Kconfig"
source "arch/mips/netlogic/Kconfig"
source "arch/mips/paravirt/Kconfig"
source "arch/mips/xilfpga/Kconfig"
+source "arch/mips/xburst/Kconfig"
+source "arch/mips/xburst2/Kconfig"
endmenu
@@ -1086,6 +1135,9 @@ config DMA_MAYBE_COHERENT
select DMA_NONCOHERENT
bool
+config DMA_INGENIC_HIGHMEM_FLUSH
+ bool
+
config DMA_COHERENT
bool
@@ -2119,6 +2171,15 @@ config MIPS_CPU_SCACHE
bool
select BOARD_SCACHE
+config XBURST_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+config XBURST2_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+ select CPU_SUPPORTS_CPUFREQ
+
config R5000_CPU_SCACHE
bool
select BOARD_SCACHE

View File

@ -0,0 +1,28 @@
diff -drupN a/arch/mips/Makefile b/arch/mips/Makefile
--- a/arch/mips/Makefile 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/Makefile 2022-06-09 05:02:26.000000000 +0300
@@ -342,6 +342,16 @@ $(boot-y): $(vmlinux-32) FORCE
$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) \
$(bootvars-y) arch/mips/boot/$@
+# zImage
+zImage: $(vmlinux-32) FORCE
+ $(Q)$(MAKE) $(build)=arch/mips/boot/zcompressed VMLINUX=$(vmlinux-32) $@
+ @cp arch/mips/boot/zcompressed/$@ arch/mips/boot/compressed/$@
+ @echo ' Kernel: arch/mips/boot/compressed/$@ is ready'
+xImage: $(vmlinux-32) FORCE
+ $(Q)$(MAKE) $(build)=arch/mips/boot/zcompressed VMLINUX=$(vmlinux-32) $@
+ @cp arch/mips/boot/zcompressed/$@ arch/mips/boot/compressed/$@
+ @echo ' Kernel: arch/mips/boot/compressed/$@ is ready'
+
ifdef CONFIG_SYS_SUPPORTS_ZBOOT
# boot/compressed
$(bootz-y): $(vmlinux-32) FORCE
@@ -409,6 +419,7 @@ define archhelp
echo ' uImage.gz - U-Boot image (gzip)'
echo ' uImage.lzma - U-Boot image (lzma)'
echo ' uImage.lzo - U-Boot image (lzo)'
+ echo ' xImage - U-Boot-spl xImage (ingenic spl boot)'
echo ' dtbs - Device-tree blobs for enabled boards'
echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)'
echo

View File

@ -0,0 +1,23 @@
diff -drupN a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
--- a/arch/mips/boot/Makefile 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/boot/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -75,7 +75,7 @@ $(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.b
# Compressed u-boot images
#
-targets += uImage
+#targets += uImage
targets += uImage.bin
targets += uImage.bz2
targets += uImage.gz
@@ -97,6 +97,9 @@ $(obj)/uImage.lzma: $(obj)/vmlinux.bin.l
$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo FORCE
$(call if_changed,uimage,lzo)
-$(obj)/uImage: $(obj)/uImage.$(suffix-y)
+
+
+targets += uImage
+$(obj)/uImage: $(obj)/uImage.lzma $(obj)/uImage.lzo FORCE
@ln -sf $(notdir $<) $@
@echo ' Image $@ is ready'

View File

@ -0,0 +1,18 @@
diff -drupN a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile
--- a/arch/mips/boot/dts/ingenic/Makefile 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -1,6 +1,14 @@
dtb-$(CONFIG_JZ4740_QI_LB60) += qi_lb60.dtb
dtb-$(CONFIG_JZ4780_CI20) += ci20.dtb
+dtb-$(CONFIG_DT_HALLEY2_V20) += halley2v20.dtb
+dtb-$(CONFIG_DT_SEAL) += seal.dtb
+dtb-$(CONFIG_DT_X2000_V12_FPGA) += x2000_v12_fpga.dtb
+ifdef CONFIG_FAST_BOOT
+dtb-$(CONFIG_DT_T40_SHARK) += shark_fast.dtb
+else
+dtb-$(CONFIG_DT_T40_SHARK) += shark.dtb
+endif
obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
# Force kbuild to make empty built-in.o if necessary

View File

@ -0,0 +1,370 @@
diff -drupN a/arch/mips/boot/dts/ingenic/halley2v20.dts b/arch/mips/boot/dts/ingenic/halley2v20.dts
--- a/arch/mips/boot/dts/ingenic/halley2v20.dts 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/halley2v20.dts 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,366 @@
+/dts-v1/;
+
+/memreserve/ 0x01f00000 0x00100000; /* dmic reserved */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "x1000.dtsi"
+
+&msc0 {
+ status = "okay";
+ pinctrl-names ="default";
+ pinctrl-0 = <&msc0_4bit_pa>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ cd-inverted;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ ingenic,sdio_clk = <0>;
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+ ingenic,removal-dontcare; /*removal-dontcare, removal-nonremovable, removal-removable, removal-manual*/
+};
+
+&msc1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "okay";
+ pinctrl-names ="default","enable", "disable";
+ pinctrl-0 = <&msc1_4bit_pc>;
+ pinctrl-1 = <&rtc32k_enable>;
+ pinctrl-2 = <&rtc32k_disable>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <48000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ non-removable;
+
+ ingenic,sdio_clk = <1>;
+ keep-power-in-suspend;
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+ ingenic,removal-manual; /*removal-dontcare, removal-nonremovable, removal-removable, removal-manual*/
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bcmdhd_wlan: bcmdhd_wlan {
+ compatible = "android,bcmdhd_wlan";
+ ingenic,sdio-irq = <&gpc 16 IRQ_TYPE_LEVEL_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,sdio-reset = <&gpc 17 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <100000>;
+ timeout = <1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pb>;
+
+ ov5640: ov5640@0x3c {
+ status = "disabled";
+ compatible = "ovti,ov5640";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cim_pa>;
+
+ resetb-gpios = <&gpd 5 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ pwdn-gpios = <&gpd 4 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ vcc-en-gpios = <&gpd 3 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+
+ /*gsensor-supply = <&LDO3>;*/
+ /*lcd-supply = <&LDO5>;*/
+ /*supplies-name = "vcc_gsensor", "lcd_3v3";*/
+
+ port {
+ ov5640_0: endpoint {
+ remote-endpoint = <&cim_0>;
+ };
+ };
+ };
+ gc2155: gc2155@0x3c {
+ status = "okay";
+ compatible = "ovti,gc2155";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cim_pa>;
+
+ resetb-gpios = <&gpd 5 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ pwdn-gpios = <&gpd 4 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ vcc-en-gpios = <&gpd 3 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+
+ /*gsensor-supply = <&LDO3>;*/
+ /*lcd-supply = <&LDO5>;*/
+ /*supplies-name = "vcc_gsensor", "lcd_3v3";*/
+
+ port {
+ gc2155_0: endpoint {
+ remote-endpoint = <&cim_0>;
+ };
+ };
+ };
+};
+
+&spi0 {
+ status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_pd>;
+
+ spi-max-frequency = <54000000>;
+ num-cs = <2>;
+ cs-gpios = <0>, <0>;
+/* cs-gpios = <&gpa 27 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>, <&gpa 27 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;*/
+ ingenic,chnl = <0>;
+ ingenic,allow_cs_same = <1>;
+ ingenic,bus_num = <0>;
+ ingenic,has_dma_support = <0>;
+ ingenic,spi-src-clk = <0>;/*0, ext; 1, sfc*/
+
+ dac0: dh2228@0 {
+ compatible = "spidev";
+ reg = <2>;
+ chip_select= <0>;
+ spi-max-frequency = <100000>;
+ };
+};
+
+&cim {
+ status = "okay";
+ port {
+ cim_0: endpoint@0 {
+ /*remote-endpoint = <&ov5640_0>;*/
+ remote-endpoint = <&gc2155_0>;
+ bus-width = <8>;
+ /*vsync-active = 1;*/
+ /*hsync-active = 1;*/
+ };
+ };
+};
+
+&lcd {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pa>, <&lcd_pb>;
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ timeout = <1000>;
+ status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pc>;
+};
+
+&i2c2 {
+ status = "disabled";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ status = "okay";
+ pinctrl-0 = <&uart0_pc_fc>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ status = "okay";
+ pinctrl-0 = <&uart2_pc>;
+};
+
+&pinctrl {
+ mac_rmii_p0: mac-rmii-p0 {
+ mac_rmii_p0_normal: mac-rmii-p0-normal {
+ ingenic,pinmux = <&gpb 7 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ mac_rmii_p0_rst: mac-rmii-p0-rst {
+ ingenic,pinmux = <&gpb 7 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCLOLVL>;
+ };
+ };
+ mac_rmii_p1: mac-rmii-p1 {
+ ingenic,pinmux = <&gpb 10 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ mac_rmii_nomdio_p1: mac-rmii-nomdio-p1 {
+ ingenic,pinmux = <&gpb 10 12>, <&gpb 15 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ gpiokeys: gpiokeys {
+ gpio_power_key:gpio_power_key {
+ ingenic,pinmux = <&gpb 31 31>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCLOLVL>;
+ };
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "reset";
+ /* pinctrl-0 = <&mac_rmii_p0_normal>, <&mac_rmii_p1>;
+ pinctrl-1 = <&mac_rmii_p0_rst>, <&mac_rmii_p1>;*/
+ pinctrl-0 = <&mac_rmii_p0_normal>, <&mac_rmii_nomdio_p1>;
+ pinctrl-1 = <&mac_rmii_p0_rst>, <&mac_rmii_nomdio_p1>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpb 3 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+};
+
+&sfc {
+ status = "okay";
+ ingenic,sfc-max-frequency = <150000000>;
+ ingenic,use_board_info = /bits/ 8 <0>;
+};
+
+&otg {
+ g-use-dma;
+ status = "okay";
+};
+
+&otg_phy {
+ dr_mode = "otg";
+ ingenic,drvvbus-gpio = <&gpb 25 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+};
+
+/ {
+ model = "halley2-v20";
+
+ memory {
+ device_type = "memory";
+ linux,usable-memory = <0x00000000 0x2000000>;
+ };
+
+ aliases: aliases {
+ };
+ dump_dmic_codec:dump_dmic_codec{
+ compatible = "ingenic,dmic-dump-codec";
+ status = "ok";
+ };
+ dump_spdif_codec:dump_spdif_codec{
+ compatible = "ingenic,spdif-dump-codec";
+ status = "ok";
+ };
+ dump_pcm_codec:dump_pcm_codec{
+ compatible = "ingenic,pcm-dump-codec";
+ status = "ok";
+ };
+ sound_halley2_icdc {
+ status = "ok";
+ compatible = "ingenic,x1000-sound";
+ ingenic,model = "halley2";
+ ingenic,dai-link = "i2s-icdc", "dmic", "pcm";
+ ingenic,stream = "main", "dmic", "pcm";
+ ingenic,cpu-dai = <&i2s>, <&dmic>, <&pcm>;
+ ingenic,platform = <&aic>, <&dmic>, <&pcm>;
+ ingenic,codec = <&codec>, <&dump_dmic_codec>, <&dump_pcm_codec>;
+ ingenic,codec-dai = "icdc-d3-hifi", "dmic-dump", "pcm-dump";
+ ingenic,audio-routing = "Speaker", "DO_LO_PWM",
+ "MICBIAS", "Mic Buildin",
+ "DMIC", "DMic";
+ /*ingenic,spken-gpio = <&gpb 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;*/
+ };
+ sound_halley2_spdif {
+ status = "disabled";
+ compatible = "ingenic,x1000-sound";
+ ingenic,model = "halley2";
+ ingenic,dai-link = "spdif", "dmic", "pcm";
+ ingenic,stream = "main", "dmic", "pcm";
+ ingenic,cpu-dai = <&spdif>, <&dmic>, <&pcm>;
+ ingenic,platform = <&aic>, <&dmic>, <&pcm>;
+ ingenic,codec = <&dump_spdif_codec>, <&dump_dmic_codec>, <&dump_pcm_codec>;
+ ingenic,codec-dai = "spdif-dump", "dmic-dump", "pcm-dump";
+ /*ingenic,spken-gpio = <&gpb 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;*/
+ };
+
+ panel_truly@0 {
+ compatible = "ingenic,truly_tft240240_2_e";
+ status = "okay";
+ ingenic,cs-gpio = <&gpb 18 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpd 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,blken-gpio = <&gpd 1 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ /*ingenic,pwmen-gpio = <&gpc 25 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;*/
+ };
+
+ backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwmz 0 500000>;
+ brightness-levels = <0 4 8 16 24 32 40 64 128 255>;
+ default-brightness-level = <5>;
+ };
+
+pwmz:pwm {
+ compatible = "ingenic,pwm";
+ #pwm-cells = <2>;
+ pinctrl-0 = <&pwm0_pc>;
+ pinctrl-names = "default";
+ pwm0:pwm@0 {
+ ingenic,timer-parent = <&channel0>;
+ status = "okay";
+ };
+ pwm1:pwm@1 {
+ ingenic,timer-parent = <&channel1>;
+ status = "okay";
+ };
+ pwm2:pwm@2 {
+ ingenic,timer-parent = <&channel2>;
+ status = "disabled";
+ };
+ pwm3:pwm@3 {
+ ingenic,timer-parent = <&channel3>;
+ status = "disabled";
+ };
+ pwm4:pwm@4 {
+ ingenic,timer-parent = <&channel4>;
+ status = "disabled";
+ };
+ };
+
+ extclk: extclk {
+ clock-frequency = <24000000>;
+ };
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpb 31 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ gpio-key,wakeup;
+ };
+ };
+ bt_power{
+ compatible = "ingenic,bt_power";
+ ingenic,reg-on-gpio = <&gpc 18 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,wake-gpio = <&gpc 20 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ };
+};
+
+&gpa {
+ ingenic,gpio-sleep-pull = <0 1 2 3 4 5 6 7 8 9 10 11
+ 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
+ 28 29 30 31>;
+ ingenic,gpio-sleep-high = <27>;
+};
+
+&gpb {
+ ingenic,gpio-sleep-pull = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+ 15 16 17 18 19 20 21 22 23 24 26>;
+ ingenic,gpio-sleep-npul = <28 29 30>;
+ ingenic,gpio-sleep-low = <25 27>;
+};
+
+&gpc {
+ ingenic,gpio-sleep-pull = <21 23 24 25 26 27>;
+ ingenic,gpio-sleep-npul = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 22>;
+};
+
+&gpd {
+ ingenic,gpio-sleep-pull = <0 1 2 3 4 5>;
+};
+

View File

@ -0,0 +1,305 @@
diff -drupN a/arch/mips/boot/dts/ingenic/seal.dts b/arch/mips/boot/dts/ingenic/seal.dts
--- a/arch/mips/boot/dts/ingenic/seal.dts 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/seal.dts 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,301 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "x2000.dtsi"
+
+/ {
+ compatible = "img,seal", "ingenic,x2000";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+
+&as_be_baic {
+ pinctrl-names = "default";
+ pinctrl-0 = <&baic1_tmclk_pb>, <&baic1_pb>, <&baic2_mclk_pb>, <&baic2_pb>,
+ <&baic3_mclk_pd>, <&baic3_pd>, <&baic4_pe>;
+ ingenic,dai-mode = <BAIC_3AND(BAIC_PCM_MODE, BAIC_DSP_MODE, BAIC_I2S_MODE)>,
+ <BAIC_3AND(BAIC_PCM_MODE, BAIC_DSP_MODE, BAIC_I2S_MODE)>,
+ <BAIC_4AND(BAIC_I2S_MODE, BAIC_TDM1_MODE, BAIC_TDM2_MODE, BAIC_NO_REPLAY)>,
+ <BAIC_4AND(BAIC_I2S_MODE, BAIC_TDM1_MODE, BAIC_TDM2_MODE, BAIC_NO_RECORD)>,
+ <BAIC_3AND(BAIC_PCM_MODE, BAIC_DSP_MODE, BAIC_I2S_MODE)>;
+};
+
+
+&as_spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_pb>;
+};
+
+&as_dmic {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dmic_pa>;
+};
+
+&sfc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sfc_pf>;
+ ingenic,use_board_info = /bits/ 8 <0>;
+
+ ingenic,sfc-max-frequency = <150000000>;
+};
+
+&otg {
+ g-use-dma;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&otg_phy {
+ dr_mode = "otg";
+ compatible = "ingenic,innophy", "syscon";
+ reg = <0x10000000 0x100>;
+ ingenic,drvvbus-gpio = <&gpf 26 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+};
+
+
+&pinctrl {
+ mac_rmii_p0: mac-rmii-p0 {
+ mac_rmii_p0_normal: mac-rmii-normal {
+ ingenic,pinmux = <&gpc 1 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ mac_rmii_p0_rst: mac-rmii-p0-rst {
+ ingenic,pinmux = <&gpc 1 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCHILVL>;
+ };
+ };
+
+ mac_rmii_p1: mac-rmii-p1 {
+ mac_rmii_p1_normal: mac-rmii-p1-normal {
+ ingenic,pinmux = <&gpc 0 0>, <&gpc 4 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+
+ mac_rmii_p1_nomdio: mac-rmii-p1-nomdio {
+ ingenic,pinmux = <&gpc 0 0>, <&gpc 4 7>, <&gpc 9 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+ pwm_pins: pwm-pins {
+ ingenic,pinmux = <&gpb 8 8>; /* pwm0 - pwm15 */
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+};
+
+&mac {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac_rmii_p0_normal>, <&mac_rmii_p1_normal>;
+ pinctrl-1 = <&mac_rmii_p0_rst>, <&mac_rmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpf 26 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RMII>;
+};
+
+&pwm {
+ ingenic,pwm-outputs = <0>; /* <1 2 3 4 5 6 7 8 9 10 11 12 ... 15>;Select which pwms are really used */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+};
+
+&msc0 {
+ status = "okay";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ non-removable;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ non-removable;
+ voltage-ranges = <1800 3300>;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+};
+
+&msc1 {
+ status = "okay";
+ pinctrl-names ="default","enable", "disable";
+ pinctrl-0 = <&msc1_4bit>;
+ pinctrl-1 = <&rtc32k_enable>;
+ pinctrl-2 = <&rtc32k_disable>;
+
+ max-frequency = <25000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ /*non-removable;*/
+
+ ingenic,sdio_clk = <1>;
+ ingenic,poc-v1.8;
+ keep-power-in-suspend;
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+ ingenic,removal-manual; /*removal-dontcare, removal-nonremovable, removal-removable, removal-manual*/
+
+ bcmdhd_wlan: bcmdhd_wlan {
+ compatible = "android,bcmdhd_wlan";
+ ingenic,sdio-irq = <&gpd 1 IRQ_TYPE_LEVEL_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,sdio-reset = <&gpd 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ };
+};
+
+&cim {
+ status = "okay";
+ port {
+ cim_0: endpoint@0 {
+ /*remote-endpoint = <&gc2155_0>;*/
+ remote-endpoint = <&ov9281_0>;
+ bus-width = <8>;
+ };
+ };
+};
+
+&i2c4 {
+ status = "okay";
+ clock-frequency = <100000>;
+ timeout = <1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pd>;
+
+ ov9281: ov9281@0x60 {
+ status = "okay";
+ compatible = "ovti,ov9281";
+ reg = <0x60>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cim_pd>;
+
+ pwdn-gpios = <&gpc 1 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ vcc-en-gpios = <&gpc 3 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+
+ port {
+ ov9281_0: endpoint {
+ remote-endpoint = <&cim_0>;
+ };
+ };
+ };
+
+ gc2155: gc2155@0x3c {
+ status = "okay";
+ compatible = "galaxycore,gc2155";
+ reg = <0x3c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cim_pd>;
+
+ resetb-gpios = <&gpb 13 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ pwdn-gpios = <&gpb 10 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ vcc-en-gpios = <&gpb 9 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+
+ port {
+ gc2155_0: endpoint {
+ remote-endpoint = <&cim_0>;
+ };
+ };
+ };
+
+ /* Audio */
+ ak4458: dac@0x10 {
+ compatible = "asahi-kasei,ak4458";
+ status = "okay";
+ reg = <0x10>;
+ reset-gpios = <&gpd 7 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ xxmute-gpios = <&gpc 4 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+ ak5558: adc@0x13 {
+ compatible = "asahi-kasei,ak5558";
+ status = "okay";
+ reg = <0x13>;
+ reset-gpios = <&gpd 9 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+
+};
+
+&dpu {
+ status = "okay";
+ port {
+ dpu_out_ep: endpoint {
+ remote-endpoint = <&panel_kd035hvfmd057_ep>;
+ /*remote-endpoint = <&panel_kd035hvfbd037_ep>;*/
+ };
+ };
+};
+
+/ {
+ display-dbi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_byd9158B@0 {
+ compatible = "ingenic,byd9158B";
+ status = "disable";
+ ingenic,cs-gpio = <&gpb 26 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpb 25 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ };
+ panel_kd035hvfmd057@0 {
+ compatible = "ingenic,kd035hvfmd057";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&tft_lcd_pb>;
+ ingenic,cs-gpio = <&gpc 5 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpb 11 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,ssi-clk-gpio = <&gpc 2 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,ssi-dt-gpio = <&gpc 4 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,pwm-gpio = <&gpb 8 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ port {
+ panel_kd035hvfmd057_ep: endpoint {
+ remote-endpoint = <&dpu_out_ep>;
+ };
+ };
+ };
+ panel_kd035hvfbd037@0 {
+ compatible = "ingenic,kd035hvfbd037";
+ status = "disable";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smart_lcd_pb>;
+ ingenic,cs-gpio = <&gpb 26 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpb 29 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,pwm-gpio = <&gpb 8 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,vdd-en-gpio = <&gpc 4 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ port {
+ panel_kd035hvfbd037_ep: endpoint {
+ remote-endpoint = <&dpu_out_ep>;
+ };
+ };
+ };
+ };
+
+
+ sound {
+ compatible = "ingenic,seal-sound";
+ ingenic,model = "seal";
+ };
+
+ extclk: extclk {
+ clock-frequency = <24000000>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpf 31 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ gpio-key,wakeup;
+ };
+ };
+};

View File

@ -0,0 +1,309 @@
diff -drupN a/arch/mips/boot/dts/ingenic/shark.dts b/arch/mips/boot/dts/ingenic/shark.dts
--- a/arch/mips/boot/dts/ingenic/shark.dts 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/shark.dts 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,305 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "t40.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "ingenic,shark", "ingenic,t40";
+
+ mmc0_pwrseq: mmc0_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpd 22 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ };
+};
+
+&uart0 {
+ status = "disable";
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pb>;
+};
+
+&uart2 {
+ status = "disable";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pa>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pa>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pc>;
+ pinctrl-names = "default";
+ status = "disable";
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3_pa>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&cpufreq {
+ status = "okay";
+ operating-points = <
+ /*KHZ uV */
+ 1200000 900000
+ 750000 900000
+ 600000 900000
+ 500000 900000
+ 400000 900000
+ 375000 900000
+ 300000 900000
+ 200000 900000
+ >;
+
+};
+
+//&pwm {
+// ingenic,pwm-outputs = <0>; /* <0 - 15> select which pwms are really used */
+//}
+
+&pdma {
+ status = "okay";
+};
+
+&msc0 {
+ status = "okay";
+ pinctrl-names = "default";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ max-frequency = <25000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ cd-inverted;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingenic,cd-gpios = <&gpc 6 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpios = <0>;
+ pinctrl-0 = <&msc0_pb>;
+ #mmc-pwrseq = <&mmc0_pwrseq>;
+};
+
+&msc1 {
+ status = "disable";
+ pinctrl-names = "default";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ non-removable;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+ pinctrl-0 = <&msc1_pb>;
+};
+
+&mac0 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac0_rmii_p0_normal>, <&mac0_rmii_p1_normal>;
+ pinctrl-1 = <&mac0_rmii_p0_rst>, <&mac0_rmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpc 7 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RMII>;
+ ingenic,mode-reg = <0xb00000e4>;
+ ingenic,phy-clk-freq = <50000000>;
+};
+
+&sfc {
+ status = "okay";
+ pinctrl-names = "default";
+ ingenic,sfc-max-frequency = <200000000>;
+ ingenic,use_board_info = /bits/ 8 <0>;
+ ingenic,spiflash_param_offset = <0>;
+ pinctrl-0 = <&sfc_pa>;
+};
+
+&spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pc>;
+
+ spi-max-frequency = <48000000>;
+ num-cs = <2>;
+ cs-gpios = <0>, <0>;
+ ingenic,chnl = <0>;
+ ingenic,allow_cs_same = <1>;
+ ingenic,bus_num = <0>;
+ ingenic,has_dma_support = <1>;
+};
+
+&spi1 {
+ status = "disable";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pb>;
+
+ spi-max-frequency = <48000000>;
+ num-cs = <2>;
+ cs-gpios = <0>, <0>;
+ ingenic,chnl = <0>;
+ ingenic,allow_cs_same = <1>;
+ ingenic,bus_num = <1>;
+ ingenic,has_dma_support = <1>;
+};
+
+&dtrng {
+ status = "okay";
+};
+
+&otg {
+ g-use-dma;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&otg_phy {
+ dr_mode = "otg";
+ compatible = "ingenic,innophy", "syscon";
+ ingenic,drvvbus-gpio = <&gpb 27 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+};
+
+/ {
+
+ extclk: extclk {
+ clock-frequency = <24000000>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpa 31 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ gpio-key,wakeup;
+ };
+ bootsel0 {
+ label = "bootsel0";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpc 0 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+
+ bootsel1 {
+ label = "bootsel1";
+ linux,code = <KEY_BACK>;
+ gpios = <&gpc 1 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+
+ };
+};
+
+&el150 {
+ status = "disable";
+};
+
+&dpu {
+ status = "okay";
+};
+
+/ {
+ display-dpi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_bm8766@0 {
+ compatible = "ingenic,bm8766";
+ pinctrl-names = "default";
+ pinctrl-0 = <&tft_lcd_pd>;
+ ingenic,bl-gpio = <&gpb 25 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ };
+};
+
+/ {
+ display-dbi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_truly240240@0 {
+ compatible = "ingenic,truly240240";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smart_lcd_pd>;
+ /*ingenic,rst-gpio = <&gpc 7 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;*/
+ ingenic,rst-gpio = <&gpd 9 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rd-gpio = <&gpd 12 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,cs-gpio = <&gpd 10 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_st7789v240320@0 {
+ compatible = "ingenic,st7789v240320";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smart_lcd_pd>;
+ /*ingenic,rst-gpio = <&gpc 7 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;*/
+ ingenic,rst-gpio = <&gpd 9 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rd-gpio = <&gpd 12 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,cs-gpio = <&gpd 10 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,bl-gpio = <&gpd 27 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ };
+};
+
+/ {
+ display-dsi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_ek79007@0 {
+ compatible = "ingenic,ek79007";
+ ingenic,bl-gpio = <&gpd 26 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ // ingenic,rst-gpio = <&gpd 17 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_st7703@0 {
+ compatible = "ingenic,st7703";
+ ingenic,bl-gpio = <&gpb 25 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpc 22 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_ma0060@0 {
+ compatible = "ingenic,ma0060";
+ ingenic,vdd-en-gpio = <&gpd 22 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpd 23 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,lcd-pwm-gpio = <&gpd 25 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_MTF070@0 {
+ compatible = "ingenic,mtf070";
+ status = "okay";
+ ingenic,bl-gpio = <&gpc 4 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpb 28 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,pw-gpio = <&gpb 29 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+ };
+
+};

View File

@ -0,0 +1,295 @@
diff -drupN a/arch/mips/boot/dts/ingenic/shark_fast.dts b/arch/mips/boot/dts/ingenic/shark_fast.dts
--- a/arch/mips/boot/dts/ingenic/shark_fast.dts 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/shark_fast.dts 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,291 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "t40.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ compatible = "ingenic,shark", "ingenic,t40";
+
+ mmc0_pwrseq: mmc0_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpd 22 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ };
+};
+
+&uart0 {
+ status = "disable";
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pb>;
+};
+
+&uart2 {
+ status = "disable";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pa>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pa>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2_pc>;
+ pinctrl-names = "default";
+ status = "disable";
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3_pa>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&cpufreq {
+ status = "okay";
+ operating-points = <
+ /*KHZ uV */
+ 1200000 900000
+ 750000 900000
+ 600000 900000
+ 500000 900000
+ 400000 900000
+ 375000 900000
+ 300000 900000
+ 200000 900000
+ >;
+
+};
+
+//&pwm {
+// ingenic,pwm-outputs = <0>; /* <0 - 15> select which pwms are really used */
+//}
+
+&pdma {
+ status = "okay";
+};
+
+&msc0 {
+ status = "okay";
+ pinctrl-names = "default";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ max-frequency = <25000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ cd-inverted;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingenic,cd-gpios = <&gpc 6 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpios = <0>;
+ pinctrl-0 = <&msc0_pb>;
+ mmc-pwrseq = <&mmc0_pwrseq>;
+};
+
+&msc1 {
+ status = "disable";
+ pinctrl-names = "default";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ voltage-ranges = <1800 3300>;
+ non-removable;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+ pinctrl-0 = <&msc1_pb>;
+};
+
+&mac0 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac0_rmii_p0_normal>, <&mac0_rmii_p1_normal>;
+ pinctrl-1 = <&mac0_rmii_p0_rst>, <&mac0_rmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <0>;//<&gpc 7 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RMII>;
+ ingenic,mode-reg = <0xb00000e4>;
+ ingenic,phy-clk-freq = <50000000>;
+};
+
+&sfc {
+ status = "okay";
+ pinctrl-names = "default";
+ ingenic,sfc-max-frequency = <200000000>;
+ ingenic,use_board_info = /bits/ 8 <0>;
+ ingenic,spiflash_param_offset = <0>;
+ pinctrl-0 = <&sfc_pa>;
+};
+
+&spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pc>;
+
+ spi-max-frequency = <48000000>;
+ num-cs = <2>;
+ cs-gpios = <0>, <0>;
+ ingenic,chnl = <0>;
+ ingenic,allow_cs_same = <1>;
+ ingenic,bus_num = <0>;
+ ingenic,has_dma_support = <1>;
+};
+
+&dtrng {
+ status = "okay";
+};
+
+&otg {
+ g-use-dma;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&otg_phy {
+ dr_mode = "otg";
+ compatible = "ingenic,innophy", "syscon";
+ ingenic,drvvbus-gpio = <&gpb 27 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+};
+
+/ {
+
+ extclk: extclk {
+ clock-frequency = <24000000>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpa 31 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ gpio-key,wakeup;
+ };
+ bootsel0 {
+ label = "bootsel0";
+ linux,code = <KEY_HOME>;
+ gpios = <&gpc 0 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+
+ bootsel1 {
+ label = "bootsel1";
+ linux,code = <KEY_BACK>;
+ gpios = <&gpc 1 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+
+ };
+};
+
+&el150 {
+ status = "disable";
+};
+
+&dpu {
+ status = "okay";
+};
+
+/ {
+ display-dpi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_bm8766@0 {
+ compatible = "ingenic,bm8766";
+ pinctrl-names = "default";
+ pinctrl-0 = <&tft_lcd_pd>;
+ ingenic,bl-gpio = <&gpb 25 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ };
+};
+
+/ {
+ display-dbi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_truly240240@0 {
+ compatible = "ingenic,truly240240";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smart_lcd_pd>;
+ /*ingenic,rst-gpio = <&gpc 7 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;*/
+ ingenic,rst-gpio = <&gpd 9 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rd-gpio = <&gpd 12 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,cs-gpio = <&gpd 10 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_st7789v240320@0 {
+ compatible = "ingenic,st7789v240320";
+ pinctrl-names = "default";
+ pinctrl-0 = <&smart_lcd_pd>;
+ /*ingenic,rst-gpio = <&gpc 7 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;*/
+ ingenic,rst-gpio = <&gpd 9 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rd-gpio = <&gpd 12 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,cs-gpio = <&gpd 10 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,bl-gpio = <&gpd 27 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ };
+};
+
+/ {
+ display-dsi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_ek79007@0 {
+ compatible = "ingenic,ek79007";
+ ingenic,bl-gpio = <&gpd 26 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ // ingenic,rst-gpio = <&gpd 17 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_st7703@0 {
+ compatible = "ingenic,st7703";
+ ingenic,bl-gpio = <&gpb 25 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpc 22 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_ma0060@0 {
+ compatible = "ingenic,ma0060";
+ ingenic,vdd-en-gpio = <&gpd 22 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpd 23 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,lcd-pwm-gpio = <&gpd 25 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ status = "okay";
+ };
+
+ panel_MTF070@0 {
+ compatible = "ingenic,mtf070";
+ status = "okay";
+ ingenic,bl-gpio = <&gpc 4 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-gpio = <&gpb 28 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,pw-gpio = <&gpb 29 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ };
+ };
+
+};

View File

@ -0,0 +1,268 @@
diff -drupN a/arch/mips/boot/dts/ingenic/t40-pinctrl.dtsi b/arch/mips/boot/dts/ingenic/t40-pinctrl.dtsi
--- a/arch/mips/boot/dts/ingenic/t40-pinctrl.dtsi 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/t40-pinctrl.dtsi 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,264 @@
+#include <dt-bindings/pinctrl/ingenic-pinctrl.h>
+
+&pinctrl {
+ uart0_pin: uart0-pin {
+ uart0_pc: uart0-pc {
+ ingenic,pinmux = <&gpc 2 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ uart0_pa: uart0-pa {
+ ingenic,pinmux = <&gpa 10 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ uart0_pc1: uart0-pc1 {
+ ingenic,pinmux = <&gpc 14 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+ uart1_pin: uart1-pin {
+ uart1_pb: uart1-pb {
+ ingenic,pinmux = <&gpb 23 24>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ uart1_pa: uart1-pa {
+ ingenic,pinmux = <&gpa 17 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ uart2_pin: uart2-pin {
+ uart2_pc: uart2-pc {
+ ingenic,pinmux = <&gpc 18 19>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ uart2_pb: uart2-pb {
+ ingenic,pinmux = <&gpb 28 29>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ uart2_pa: uart2-pa {
+ ingenic,pinmux = <&gpa 6 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ uart3_pin: uart3-pin {
+ uart3_pc: uart3-pc {
+ ingenic,pinmux = <&gpc 6 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ uart3_pd: uart3-pd {
+ ingenic,pinmux = <&gpd 22 25>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ uart3_pa: uart3-pa {
+ ingenic,pinmux = <&gpa 2 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ i2c0_pin: i2c0-pin {
+ i2c0_pa: i2c0-pa {
+ ingenic,pinmux = <&gpa 12 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ i2c0_pc: i2c0-pc {
+ ingenic,pinmux = <&gpc 16 17>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ i2c1_pin: i2c1-pin {
+ i2c1_pa: i2c1-pa {
+ ingenic,pinmux = <&gpa 17 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ i2c1_pb: i2c1-pb {
+ ingenic,pinmux = <&gpb 17 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ i2c1_pd: i2c1-pd {
+ ingenic,pinmux = <&gpd 26 27>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ i2c2_pin: i2c2-pin {
+ i2c2_pc: i2c2-pc {
+ ingenic,pinmux = <&gpc 14 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ i2c2_pb: i2c2-pb {
+ ingenic,pinmux = <&gpb 25 26>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ i2c3_pin: i2c3-pin {
+ i2c3_pb: i2c3-pb {
+ ingenic,pinmux = <&gpb 28 29>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ i2c3_pb1: i2c3-pb1 {
+ ingenic,pinmux = <&gpb 20 21>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ i2c3_pa: i2c3-pa {
+ ingenic,pinmux = <&gpa 21 22>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ msc0_pin: msc0-pin {
+ msc0_pb: msc0-pb {
+ ingenic,pinmux = <&gpb 0 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ msc1_pin: msc1-pin {
+ msc1_pb: msc1-pb {
+ ingenic,pinmux = <&gpb 17 22>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ msc1_pc: msc1-pc {
+ ingenic,pinmux = <&gpc 8 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ mac0_rmii_p0: mac0-rmii-p0 {
+ mac0_rmii_p0_normal: mac0-rmii-normal {
+ ingenic,pinmux = <&gpb 15 16>, <&gpb 9 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ mac0_rmii_p0_rst: mac0-rmii-p0-rst {
+ ingenic,pinmux = <&gpb 15 16>, <&gpb 9 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCHILVL>;
+ };
+ };
+
+ mac0_rmii_p1: mac0-rmii-p1 {
+ mac0_rmii_p1_normal: mac0-rmii-p1-normal {
+ ingenic,pinmux = <&gpb 7 7>, <&gpb 13 14>, <&gpb 8 8>, <&gpb 10 11>, <&gpb 6 6>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+
+ mac0_rmii_p1_nomdio: mac0-rmii-p1-nomdio {
+ ingenic,pinmux = <&gpb 7 7>, <&gpb 13 14>, <&gpb 8 8>, <&gpb 6 6>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+
+ pwm_pin: pwm-pin{
+ pwm_pc: pwm-pc{
+ ingenic,pinmux = <&gpc 2 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ sfc_pin: sfc-pin {
+ sfc_pa: sfc-pa {
+ ingenic,pinmux = <&gpa 23 28>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ vic_pin: vic-pin {
+ vic_pa_low_10bit: vic-pa-low-10bit {
+ ingenic,pinmux = <&gpa 0 9>, <&gpa 12 14>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ vic_pa_high_10bit: vic-pa-high-10bit {
+ ingenic,pinmux = <&gpa 2 14>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ vic_pa_12bit: vic-pa-12bit {
+ ingenic,pinmux = <&gpa 0 14>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+ cim_vic_mclk: cim-vic-mclk {
+ cim0_vic_mclk_pc: cim0-vic-mclk-pc {
+ ingenic,pinmux = <&gpc 31 31>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ cim1_vic_mclk_pc: cim1-vic-mclk-pc {
+ ingenic,pinmux = <&gpc 30 30>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ cim2_vic_mclk_pc: cim2-vic-mclk-pc {
+ ingenic,pinmux = <&gpc 29 29>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ lcd_pins: lcd-pins {
+ tft_lcd_pd: tft-lcd-pd {
+ ingenic,pinmux = <&gpd 0 21>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+
+ smart_lcd_pd: smart-lcd-pd {
+ ingenic,pinmux = <&gpd 0 8>, <&gpd 11 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ dmic_pc: dmic-pc {
+ ingenic,pinmux = <&gpc 24 26>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ spi0_pc: spi0-pc {
+ ingenic,pinmux = <&gpc 2 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ spi1_pin: spi1_pin {
+ spi1_pb: spi1-pb {
+ ingenic,pinmux = <&gpb 25 30>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ spi1_pc: spi1-pc {
+ ingenic,pinmux = <&gpc 8 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ pwm_pins: pwm-pins {
+ pwm0_pc: pwm0_pc {
+ ingenic,pinmux = <&gpc 2 2>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm1_pc: pwm1_pc {
+ ingenic,pinmux = <&gpc 3 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm2_pc: pwm2_pc {
+ ingenic,pinmux = <&gpc 4 4>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm3_pc: pwm3_pc {
+ ingenic,pinmux = <&gpc 5 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm4_pc: pwm4_pc {
+ ingenic,pinmux = <&gpc 6 6>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm5_pc: pwm5_pc {
+ ingenic,pinmux = <&gpc 7 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm6_pd: pwm6_pd {
+ ingenic,pinmux = <&gpd 22 22>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ pwm7_pd: pwm7_pd {
+ ingenic,pinmux = <&gpd 23 23>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+};
+

View File

@ -0,0 +1,559 @@
diff -drupN a/arch/mips/boot/dts/ingenic/t40.dtsi b/arch/mips/boot/dts/ingenic/t40.dtsi
--- a/arch/mips/boot/dts/ingenic/t40.dtsi 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/t40.dtsi 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,555 @@
+#include <dt-bindings/interrupt-controller/t40-irq.h>
+#include <dt-bindings/clock/ingenic-tcu.h>
+#include <dt-bindings/sound/ingenic-baic.h>
+#include <dt-bindings/net/ingenic_gmac.h>
+#include <dt-bindings/dma/ingenic-pdma.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ingenic,t40";
+
+ aliases: aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uart2 = &uart2;
+ uart3 = &uart3;
+ msc0 = &msc0;
+ msc1 = &msc1;
+ mac0 = &mac0;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ bscaler0 = &bscaler0;
+ };
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "ingenic,xburst2";
+ reg = <0x000>;
+ clock-frequency = <800000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "ingenic,xburst2";
+ reg = <0x001>;
+ clock-frequency = <800000000>;
+ };
+ };
+
+ cpufreq: cpufreq-dt {
+ compatible = "ingenic,t40-cpufreq";
+ status = "okay";
+ };
+
+ cpuintc: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "ingenic,cpu-interrupt-controller";
+
+ };
+
+ core_intc: core-intc@0x12300000 {
+ compatible = "ingenic,core-intc";
+ reg = <0x12300000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ cpu-intc-map = <0 0x000>,
+ <1 0x100>,
+ <2 0x200>,
+ <3 0x300>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <CORE_INTC_IRQ>;
+ interrupt-names ="intc";
+ };
+
+ core_ost: core-ost@0x12000000 {
+ compatible = "ingenic,core-ost";
+ reg = <0x12000000 0x10000>, /*Global ost*/
+ <0x12100000 0x10000>; /*Core ost*/
+ interrupt-parent = <&cpuintc>;
+ interrupt-names = "sys_ost";
+ interrupts = <CORE_SYS_OST_IRQ>;
+ cpu-ost-map = <0 0x000>,
+ <1 0x100>;
+ };
+
+ extclk: extclk {
+ compatible = "ingenic,fixed-clock";
+ clock-output-names ="ext";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+
+ rtcclk: rtcclk {
+ compatible = "ingenic,fixed-clock";
+ clock-output-names ="rtc_ext";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ clock: clock-controller@0x10000000 {
+ compatible = "ingenic,t40-clocks";
+ reg = <0x10000000 0x100>;
+ clocks = <&extclk>, <&rtcclk>;
+ clock-names = "ext", "rtc_ext";
+ #clock-cells = <1>;
+ little-endian;
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ tcu: tcu@0x10002000 {
+ compatible = "ingenic,tcu";
+ reg = <0x10002000 0x140>;
+ interrupt-parent = <&core_intc>;
+ interrupt-names = "tcu_int0", "tcu_int1", "tcu_int2";
+ interrupts = <IRQ_TCU0 IRQ_TCU1 IRQ_TCU2>;
+ interrupt-controller;
+ status = "ok";
+
+ channel0: channel0 {
+ compatible = "ingenic,tcu_chn0";
+ ingenic,channel-info = <CHANNEL_INFO(0, TCU_MODE1, PWM_FUNC, \
+ NO_PWM_IN)>;
+ };
+ channel1: channel1 {
+ compatible = "ingenic,tcu_chn1";
+ ingenic,channel-info = <CHANNEL_INFO(1, TCU_MODE2, PWM_FUNC, \
+ NO_PWM_IN)>;
+ };
+ channel2: channel2 {
+ compatible = "ingenic,tcu_chn2";
+ ingenic,channel-info = <CHANNEL_INFO(2, TCU_MODE2, PWM_FUNC, \
+ NO_PWM_IN)>;
+ };
+ channel3: channel3 {
+ compatible = "ingenic,tcu_chn3";
+ ingenic,channel-info = <CHANNEL_INFO(3, TCU_MODE1, \
+ PWM_FUNC, NO_PWM_IN)>;
+ };
+ channel4: channel4 {
+ compatible = "ingenic,tcu_chn4";
+ ingenic,channel-info = <CHANNEL_INFO(4, TCU_MODE1, \
+ PWM_FUNC, NO_PWM_IN)>;
+ };
+ channel5: channel5 {
+ compatible = "ingenic,tcu_chn5";
+ ingenic,channel-info = <CHANNEL_INFO(5, TCU_MODE1, \
+ PWM_FUNC, NO_PWM_IN)>;
+ };
+ channel6: channel6 {
+ compatible = "ingenic,tcu_chn6";
+ ingenic,channel-info = <CHANNEL_INFO(6, TCU_MODE1, \
+ PWM_FUNC, NO_PWM_IN)>;
+ };
+ channel7: channel7 {
+ compatible = "ingenic,tcu_chn7";
+ ingenic,channel-info = <CHANNEL_INFO(7, TCU_MODE1, \
+ PWM_FUNC, NO_PWM_IN)>;
+ };
+ channel15: channel15 {
+ compatible = "ingenic,tcu_chn15";
+ ingenic,channel-info = <CHANNEL_INFO(15, 0,0,0)>;
+ };
+ channel16: channel16 {
+ compatible = "ingenic,watchdog";
+ ingenic,channel-info = <CHANNEL_INFO(16, 0,0,0)>;
+ };
+ };
+
+ sadc: sadc@10070000 {
+ compatible = "ingenic,sadc";
+ reg = <0x10070000 0x32>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SADC>;
+ status = "okay";
+ };
+
+ watchdog: watchdog@0x10002000 {
+ compatible = "ingenic,watchdog";
+ reg = <0x10002000 0x40>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_TCU0>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl@0x10010000 {
+ compatible = "ingenic,t40-pinctrl";
+ reg = <0x10010000 0x1000>;
+ ingenic,num-chips = <6>;
+ ingenic,regs-offset = <0x100>;
+
+ gpa: gpa {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO0>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO1>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpc: gpc {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO2>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpd: gpd {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO3>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ };
+
+ uart0: serial@0x10030000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10030000 0x1000>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pc>;
+ status = "disabled";
+ };
+ uart1: serial@0x10031000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10031000 0x1000>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pb>;
+ status = "disabled";
+ };
+ uart2: serial@0x10032000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10032000 0x1000>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pc>;
+ status = "disabled";
+ };
+ uart3: serial@0x10033000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10033000 0x1000>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pc>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@0x10050000 {
+ compatible = "ingenic,t40-i2c";
+ reg = <0x10050000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ };
+
+ i2c1: i2c@0x10051000 {
+ compatible = "ingenic,t40-i2c";
+ reg = <0x10051000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ };
+
+ i2c2: i2c@0x10052000 {
+ compatible = "ingenic,t40-i2c";
+ reg = <0x10052000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@0x10053000 {
+ compatible = "ingenic,t40-i2c";
+ reg = <0x10053000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi0: spi0@0x10043000 {
+ compatible = "ingenic,spi";
+ reg = <0x10043000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SSI0>;
+ dmas = <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI0_TX)>,
+ <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI0_RX)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi1@0x10044000 {
+ compatible = "ingenic,spi";
+ reg = <0x10044000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SSI1>;
+ dmas = <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI1_TX)>,
+ <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI1_RX)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ dtrng: dtrng@0x10072000 {
+ compatible = "ingenic,dtrng";
+ reg = <0x10072000 0x100>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_DTRNG>;
+ status = "disabled";
+ };
+
+ des: des@0x10061000 {
+ compatible = "ingenic,des";
+ reg = <0x10043000 0x1000>;
+ dmas = <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_DES_TX)>,
+ <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_DES_RX)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ };
+
+ otg_phy: otg_phy {
+ compatible = "ingenic,innophy";
+ reg = <0x10000000 0x1000 0x10060000 0x1000>;
+ };
+ };
+
+ ahb2 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ aes: aes@0x13430000 {
+ compatible = "ingenic,aes";
+ reg = <0x13430000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_AES>;
+ status = "okay";
+ };
+
+ hash: hash@0x13480000 {
+ compatible = "ingenic,hash";
+ reg = <0x13480000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_HASH>;
+ status = "okay";
+ };
+
+ rsa: rsa@0x134c0000 {
+ compatible = "ingenic,rsa";
+ reg = <0x134c0000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_RSA>;
+ status = "okay";
+ };
+
+ mac0: mac@0x134b0000 {
+ compatible = "ingenic,t40-mac";
+ reg = <0x134b0000 0x2000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_GMAC0>;
+ status = "disabled";
+ ingenic,rst-ms = <10>;
+ };
+
+ sfc: sfc@0x13440000 {
+ compatible = "ingenic,sfc";
+ reg = <0x13440000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SFC>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sfc_pa>;
+ status = "disabled";
+ };
+
+ pdma: dma@13420000 {
+ compatible = "ingenic,t40-pdma";
+ reg = <0x13420000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupt-names = "pdma", "pdmam";
+ interrupts = <IRQ_PDMA>, <IRQ_PDMAM>;
+ #dma-channels = <32>;
+ #dma-cells = <1>;
+ ingenic,reserved-chs = <0x3>;
+ };
+
+ otg: otg@0x13500000 {
+ compatible = "ingenic,dwc2-hsotg";
+ reg = <0x13500000 0x40000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_OTG>;
+ ingenic,usbphy=<&otg_phy>;
+ status = "disabled";
+ };
+
+ efuse: efuse@0x13540000 {
+ compatible = "ingenic,t40-efuse";
+ reg = <0x13540000 0x10000>;
+ status = "okay";
+ };
+ };
+
+ ahb1 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ el150: el150@0x13200000 {
+ compatible = "ingenic,t40-el150";
+ reg = <0x13200000 0x100000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_EL150>;
+ status = "disabled";
+ };
+
+ };
+
+ ahb0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ dpu: dpu@0x13050000 {
+ compatible = "ingenic,t40-dpu";
+ reg = <0x13050000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_LCD>;
+ status = "disabled";
+ };
+
+ msc0: msc@0x13060000 {
+ compatible = "ingenic,sdhci";
+ reg = <0x13060000 0x10000>;
+ status = "disabled";
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_MSC0>;
+ pinctrl-names ="default";
+ pinctrl-0 = <&msc0_4bit>;
+ };
+
+ msc1: msc@0x13070000 {
+ compatible = "ingenic,sdhci";
+ reg = <0x13070000 0x10000>;
+ status = "disabled";
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_MSC1>;
+ pinctrl-names ="default";
+ pinctrl-0 = <&msc1_4bit>;
+ };
+
+ ipu: ipu@0x13080000 {
+ compatible = "ingenic,t40-ipu";
+ reg = <0x13080000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_IPU>;
+ status = "okay";
+ };
+
+ drawbox: drawbox@0x130d0000 {
+ compatible = "ingenic,t40-drawbox";
+ reg = <0x130d0000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_DRAW_BOX>;
+ status = "okay";
+ };
+
+ i2d: i2d@0x130b0000 {
+ compatible = "ingenic,t40-i2d";
+ reg = <0x130b0000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2D>;
+ status = "okay";
+ };
+
+ isp: isp@0x13300000 {
+ compatible = "ingenic,t40-isp";
+ reg = <0x13300000 0x100000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_ISP>;
+ status = "disabled";
+ };
+
+ bscaler0: bscaler@0x13090000 {
+ compatible = "ingenic,t40-bscaler";
+ reg = <0x13090000 0x100>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_BSCALER0>,
+ <IRQ_BSCALER1>;
+ status = "okay";
+ };
+ };
+
+};
+#include "t40-pinctrl.dtsi"

View File

@ -0,0 +1,129 @@
diff -drupN a/arch/mips/boot/dts/ingenic/t40_fpga.dts b/arch/mips/boot/dts/ingenic/t40_fpga.dts
--- a/arch/mips/boot/dts/ingenic/t40_fpga.dts 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/t40_fpga.dts 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,125 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "t40.dtsi"
+
+/ {
+ compatible = "img,fpga", "ingenic,t40";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "disable";
+};
+
+&uart2 {
+ status = "disable";
+};
+
+
+//&pwm {
+// ingenic,pwm-outputs = <0>; /* <0 - 15> select which pwms are really used */
+//}
+
+
+&msc0 {
+ status = "disable";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ non-removable;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ non-removable;
+ voltage-ranges = <1800 3300>;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+};
+
+&msc1 {
+ status = "okay";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ non-removable;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ non-removable;
+ voltage-ranges = <1800 3300>;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+};
+
+&mac0 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac0_rmii_p0_normal>, <&mac0_rmii_p1_normal>;
+ pinctrl-1 = <&mac0_rmii_p0_rst>, <&mac0_rmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpb 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RMII>;
+ ingenic,mode-reg = <0xb00000e4>;
+};
+
+&sfc {
+ status = "okay";
+ ingenic,sfc-max-frequency = <150000000>;
+ ingenic,use_board_info = /bits/ 8 <0>;
+ ingenic,spiflash_param_offset = <0>;
+};
+
+
+/ {
+
+ extclk: extclk {
+ clock-frequency = <24000000>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpa 31 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&radix {
+ status = "disable";
+};
+
+&el150 {
+ status = "disable";
+};
+
+&dpu {
+ status = "okay";
+};
+
+/ {
+ display-dbi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_bm8766@0 {
+ compatible = "ingenic,bm8766";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&tft_lcd_pb>;
+ };
+ };
+
+
+};

View File

@ -0,0 +1,512 @@
diff -drupN a/arch/mips/boot/dts/ingenic/x2000-v12-pinctrl.dtsi b/arch/mips/boot/dts/ingenic/x2000-v12-pinctrl.dtsi
--- a/arch/mips/boot/dts/ingenic/x2000-v12-pinctrl.dtsi 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/x2000-v12-pinctrl.dtsi 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,508 @@
+#include <dt-bindings/pinctrl/ingenic-pinctrl.h>
+
+&pinctrl {
+ uart0_pin: uart0-pin {
+ uart0_pd: uart0-pd {
+ ingenic,pinmux = <&gpd 23 26>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+ uart1_pin: uart1-pin {
+ uart1_pc: uart1-pc {
+ ingenic,pinmux = <&gpc 21 24>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ uart2_pin: uart2-pin {
+ uart2_pd: uart2-pd {
+ ingenic,pinmux = <&gpd 30 31>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ uart3_pin: uart3-pin {
+ uart3_pd: uart3-pd {
+ ingenic,pinmux = <&gpd 0 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ uart4_pin: uart4-pin {
+ uart4_pa: uart4-pa {
+ ingenic,pinmux = <&gpa 0 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ uart4_pc: uart4-pc {
+ ingenic,pinmux = <&gpc 9 12>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ uart5_pin: uart5-pin {
+ uart5_pa: uart5-pa {
+ ingenic,pinmux = <&gpa 4 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ uart5_pc: uart5-pc {
+ ingenic,pinmux = <&gpc 5 6>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ uart6_pin: uart6-pin {
+ uart6_pa: uart6-pa {
+ ingenic,pinmux = <&gpa 6 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ uart6_pc: uart6-pc {
+ ingenic,pinmux = <&gpc 7 8>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ uart7_pin: uart7-pin {
+ uart7_pa: uart7-pa {
+ ingenic,pinmux = <&gpa 8 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ uart7_pc: uart7-pc {
+ ingenic,pinmux = <&gpc 1 2>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ uart8_pin: uart8-pin {
+ uart8_pb: uart8-pb {
+ ingenic,pinmux = <&gpb 28 29>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ uart9_pin: uart9-pin {
+ uart9_pb: uart9-pb {
+ ingenic,pinmux = <&gpb 30 31>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ i2c0_pin: i2c0-pin {
+ i2c0_pc: i2c0-pc {
+ ingenic,pinmux = <&gpc 13 14>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ i2c1_pin: i2c1-pin {
+ i2c1_pc: i2c1-pc {
+ ingenic,pinmux = <&gpc 23 24>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ i2c2_pin: i2c2-pin {
+ i2c2_pb: i2c2-pb {
+ ingenic,pinmux = <&gpb 22 23>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ i2c3_pin: i2c3-pin {
+ i2c3_pd: i2c3-pd {
+ ingenic,pinmux = <&gpd 30 31>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ i2c4_pin: i2c4-pin {
+ i2c4_pd: i2c4-pd {
+ ingenic,pinmux = <&gpd 0 1>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ i2c5_pin: i2c5-pin {
+ i2c5_pd: i2c5-pd {
+ ingenic,pinmux = <&gpd 4 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ msc0_pin: msc0-pin {
+ msc0_4bit: msc0-4bit {
+ ingenic,pinmux = <&gpd 17 22>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ msc0_8bit: msc0-8bit {
+ ingenic,pinmux = <&gpd 17 26>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ msc1_pin: msc1-pin {
+ msc1_4bit: msc1-4bit {
+ ingenic,pinmux = <&gpd 8 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ msc2_pin: msc2-pin {
+ msc2_4bit: msc2-4bit {
+ ingenic,pinmux = <&gpe 0 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ mac0_rmii_p0: mac0-rmii-p0 {
+ mac0_rmii_p0_normal: mac0-rmii-normal {
+ ingenic,pinmux = <&gpc 6 7>, <&gpc 11 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ mac0_rmii_p0_rst: mac0-rmii-p0-rst {
+ ingenic,pinmux = <&gpc 6 7>, <&gpc 11 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCHILVL>;
+ };
+ };
+
+ mac0_rmii_p1: mac0-rmii-p1 {
+ mac0_rmii_p1_normal: mac0-rmii-p1-normal {
+ ingenic,pinmux = <&gpc 1 3>, <&gpc 10 10>, <&gpc 12 13>, <&gpc 15 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ mac0_rmii_p1_nomdio: mac0-rmii-p1-nomdio {
+ ingenic,pinmux = <&gpc 1 3>, <&gpc 10 10>, <&gpc 15 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+
+ mac0_rgmii_p0: mac0-rgmii-p0 {
+ mac0_rgmii_p0_normal: mac0-rgmii-normal {
+ ingenic,pinmux = <&gpc 6 9>, <&gpc 11 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ mac0_rgmii_p0_rst: mac0-rmii-p0-rst {
+ ingenic,pinmux = <&gpc 6 9>, <&gpc 11 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCHILVL>;
+ };
+ };
+
+ mac0_rgmii_p1: mac0-rgmii-p1 {
+ mac0_rgmii_p1_normal: mac0-rgmii-p1-normal {
+ ingenic,pinmux = <&gpc 1 5>, <&gpc 10 10>, <&gpc 12 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ mac0_rgmii_p1_nomdio: mac0-rmii-p1-nomdio {
+ ingenic,pinmux = <&gpc 1 5>, <&gpc 10 10>, <&gpc 14 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ mac1_rmii_p0: mac1-rmii-p0 {
+ mac1_rmii_p0_normal: mac1-rmii-normal {
+ ingenic,pinmux = <&gpb 12 13>, <&gpb 18 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ mac1_rmii_p0_rst: mac1-rmii-p0-rst {
+ ingenic,pinmux = <&gpb 12 13>, <&gpb 18 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCHILVL>;
+ };
+ };
+
+ mac1_rmii_p1: mac1-rmii-p1 {
+ mac1_rmii_p1_normal: mac1-rmii-p1-normal {
+ ingenic,pinmux = <&gpb 8 9>, <&gpb 17 17>, <&gpb 19 20>, <&gpb 22 23>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+
+ mac1_rmii_p1_nomdio: mac1-rmii-p1-nomdio {
+ ingenic,pinmux = <&gpb 8 9>, <&gpb 17 17>, <&gpb 22 23>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ mac1_rgmii_p0: mac1-rgmii-p0 {
+ mac1_rgmii_p0_normal: mac1-rgmii-normal {
+ ingenic,pinmux = <&gpb 12 15>, <&gpb 18 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ mac1_rgmii_p0_rst: mac1-rmii-p0-rst {
+ ingenic,pinmux = <&gpb 12 15>, <&gpb 18 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCHILVL>;
+ };
+ };
+
+ mac1_rgmii_p1: mac1-rgmii-p1 {
+ mac1_rgmii_p1_normal: mac1-rgmii-p1-normal {
+ ingenic,pinmux = <&gpb 8 11>, <&gpb 17 17>, <&gpb 19 23>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+
+ mac1_rgmii_p1_nomdio: mac1-rmii-p1-nomdio {
+ ingenic,pinmux = <&gpb 8 11>, <&gpb 17 17>, <&gpb 21 23>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+ };
+
+ pwm_pin: pwm-pin{
+ pwm_pc: pwm-pc{
+ ingenic,pinmux = <&gpc 0 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ sfc_pin: sfc-pin {
+ sfc_pd: sfc-pd {
+ ingenic,pinmux = <&gpd 17 26>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ sfc_pe: sfc-pe {
+ ingenic,pinmux = <&gpe 16 21>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ cim_pin: cim-pin {
+ cim_pa: cim-pa {
+ ingenic,pinmux = <&gpa 0 7>, <&gpa 12 16>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+ vic_pin: vic-pin {
+ vic_pa: vic-pa {
+ ingenic,pinmux = <&gpa 0 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ };
+
+ lcd_pins: lcd-pins {
+ tft_lcd_pb: tft-lcd-pb {
+ ingenic,pinmux = <&gpb 0 27>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ smart_lcd_pb: smart-lcd-pb {
+ ingenic,pinmux = <&gpb 0 15>, <&gpb 25 27>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ baic1_tmclk_pc: baic1-tmclk-pc {
+ ingenic,pinmux = <&gpc 8 8>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ baic1_rmclk_pc: baic1-rmclk-pc {
+ ingenic,pinmux = <&gpc 1 1>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ baic1_pin: baic1-pin {
+ baic1_pc: baic1-pin-pc {
+ ingenic,pinmux = <&gpc 2 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ baic1_combine_pc: baic1-cpin-pc {
+ ingenic,pinmux = <&gpc 4 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ baic2_mclk_pa: baic2-mclk-pa {
+ ingenic,pinmux = <&gpa 7 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ baic2_pa: baic2-pa {
+ ingenic,pinmux = <&gpa 8 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ baic3_mclk_pa: baic3-mclk-pa {
+ ingenic,pinmux = <&gpa 0 0>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ baic3_pa: baic3-pa {
+ ingenic,pinmux = <&gpa 1 6>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ baic4_pin: baic4-pin {
+ baic4_pe: baic4-pe {
+ ingenic,pinmux = <&gpe 0 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ baic4_pd: baic4-pd {
+ ingenic,pinmux = <&gpd 2 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+ };
+
+ spdif_pc: spdif-pc {
+ ingenic,pinmux = <&gpc 13 14>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ dmic_pc: dmic-pc {
+ ingenic,pinmux = <&gpc 20 24>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+
+ spi0_pb: spi0-pb {
+ ingenic,pinmux = <&gpb 28 31>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+
+ spi1_pc: spi0-pc {
+ ingenic,pinmux = <&gpc 9 12>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION2>;
+ };
+
+ pwm_pins: pwm-pins {
+ pwm0_pc: pwm0_pc {
+ ingenic,pinmux = <&gpc 0 0>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm1_pc: pwm1_pc {
+ ingenic,pinmux = <&gpc 1 1>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm2_pc: pwm2_pc {
+ ingenic,pinmux = <&gpc 2 2>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm3_pc: pwm3_pc {
+ ingenic,pinmux = <&gpc 3 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm4_pc: pwm4_pc {
+ ingenic,pinmux = <&gpc 4 4>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm5_pc: pwm5_pc {
+ ingenic,pinmux = <&gpc 5 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm6_pc: pwm6_pc {
+ ingenic,pinmux = <&gpc 6 6>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm7_pc: pwm7_pc {
+ ingenic,pinmux = <&gpc 7 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm8_pc: pwm8_pc {
+ ingenic,pinmux = <&gpc 8 8>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm9_pc: pwm9_pc {
+ ingenic,pinmux = <&gpc 9 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm10_pc: pwm10_pc {
+ ingenic,pinmux = <&gpc 10 10>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm10_pe: pwm10_pe {
+ ingenic,pinmux = <&gpe 16 16>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ pwm11_pc: pwm11_pc {
+ ingenic,pinmux = <&gpc 11 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm11_pe: pwm11_pe {
+ ingenic,pinmux = <&gpe 17 17>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ pwm12_pc: pwm12_pc {
+ ingenic,pinmux = <&gpc 12 12>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm12_pe: pwm12_pe {
+ ingenic,pinmux = <&gpe 18 18>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ pwm13_pc: pwm13_pc {
+ ingenic,pinmux = <&gpc 13 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm13_pe: pwm13_pe {
+ ingenic,pinmux = <&gpe 19 19>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ pwm14_pc: pwm14_pc {
+ ingenic,pinmux = <&gpc 14 14>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm14_pe: pwm14_pe {
+ ingenic,pinmux = <&gpe 20 20>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ pwm15_pc: pwm15_pc {
+ ingenic,pinmux = <&gpc 15 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ pwm15_pe: pwm15_pe {
+ ingenic,pinmux = <&gpe 21 21>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+ tcu_pin: tcu-pin {
+ tcu0_pc: tcu0_pc {
+ ingenic,pinmux = <&gpc 0 1>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu1_pc: tcu1_pc {
+ ingenic,pinmux = <&gpc 2 3>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu2_pc: tcu2_pc {
+ ingenic,pinmux = <&gpc 4 5>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu3_pc: tcu3_pc {
+ ingenic,pinmux = <&gpc 6 7>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu4_pc: tcu4_pc {
+ ingenic,pinmux = <&gpc 8 9>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu5_pc: tcu5_pc {
+ ingenic,pinmux = <&gpc 10 11>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu5_pe: tcu5_pe {
+ ingenic,pinmux = <&gpe 16 17>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ tcu6_pc: tcu6_pc {
+ ingenic,pinmux = <&gpc 12 13>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu6_pe: tcu6_pe {
+ ingenic,pinmux = <&gpe 18 19>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ tcu7_pc: tcu7_pc {
+ ingenic,pinmux = <&gpc 14 15>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION0>;
+ };
+ tcu7_pe: tcu7_pe {
+ ingenic,pinmux = <&gpe 20 21>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION1>;
+ };
+ };
+
+ scc_pc: scc-pc {
+ ingenic,pinmux = <&gpc 3 4>;
+ ingenic,pinmux-funcsel = <PINCTL_FUNCTION3>;
+ };
+};
+

View File

@ -0,0 +1,742 @@
diff -drupN a/arch/mips/boot/dts/ingenic/x2000-v12.dtsi b/arch/mips/boot/dts/ingenic/x2000-v12.dtsi
--- a/arch/mips/boot/dts/ingenic/x2000-v12.dtsi 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/x2000-v12.dtsi 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,738 @@
+#include <dt-bindings/interrupt-controller/x2000-v12-irq.h>
+#include <dt-bindings/clock/ingenic-tcu.h>
+#include <dt-bindings/sound/ingenic-baic.h>
+#include <dt-bindings/net/ingenic_gmac.h>
+#include <dt-bindings/dma/ingenic-pdma.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ingenic,x2000";
+
+ aliases: aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uart2 = &uart2;
+ uart3 = &uart3;
+ uart4 = &uart4;
+ uart5 = &uart5;
+ uart6 = &uart6;
+ uart7 = &uart7;
+ uart8 = &uart8;
+ msc0 = &msc0;
+ msc2 = &msc2;
+ mac0 = &mac0;
+ mac1 = &mac1;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ };
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "ingenic,xburst2";
+ reg = <0x000>;
+ clock-frequency = <800000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "ingenic,xburst2";
+ reg = <0x001>;
+ clock-frequency = <800000000>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "ingenic,xburst2";
+ reg = <0x002>;
+ clock-frequency = <800000000>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "ingenic,xburst2";
+ reg = <0x003>;
+ clock-frequency = <800000000>;
+ };
+ };
+
+ cpuintc: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "ingenic,cpu-interrupt-controller";
+
+ };
+
+ core_intc: core-intc@0x12300000 {
+ compatible = "ingenic,core-intc";
+ reg = <0x12300000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ cpu-intc-map = <0 0x000>,
+ <1 0x100>,
+ <2 0x200>,
+ <3 0x300>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <CORE_INTC_IRQ>;
+ interrupt-names ="intc";
+ };
+
+ core_ost: core-ost@0x12000000 {
+ compatible = "ingenic,core-ost";
+ reg = <0x12000000 0x10000>, /*Global ost*/
+ <0x12100000 0x10000>; /*Core ost*/
+ interrupt-parent = <&cpuintc>;
+ interrupt-names = "sys_ost";
+ interrupts = <CORE_SYS_OST_IRQ>;
+ cpu-ost-map = <0 0x000>,
+ <1 0x100>,
+ <2 0x200>,
+ <3 0x300>;
+ };
+
+ extclk: extclk {
+ compatible = "fixed-clock";
+ clock-output-names ="ext";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+
+ rtcclk: rtcclk {
+ compatible = "fixed-clock";
+ clock-output-names ="rtc_ext";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ clock: clock-controller@0x10000000 {
+ compatible = "ingenic,x2000-v12-fpga-clocks";
+ reg = <0x10000000 0x100>;
+ clocks = <&extclk>, <&rtcclk>;
+ clock-names = "ext", "rtc_ext";
+ #clock-cells = <1>;
+ little-endian;
+ };
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ tcu: tcu@0x10002000 {
+ compatible = "ingenic,tcu";
+ reg = <0x10002000 0x140>;
+ interrupt-parent = <&core_intc>;
+ interrupt-names = "tcu_int0", "tcu_int1", "tcu_int2";
+ interrupts = <IRQ_TCU0 IRQ_TCU1 IRQ_TCU2>;
+ interrupt-controller;
+ status = "ok";
+
+ channel0: channel0 {
+ compatible = "ingenic,tcu_chn0";
+ ingenic,channel-info = <CHANNEL_INFO(0, TCU_MODE1, PWM_FUNC, \
+ PWM_IN, NOWORK_SLEEP)>;
+ };
+ channel1: channel1 {
+ compatible = "ingenic,tcu_chn1";
+ ingenic,channel-info = <CHANNEL_INFO(1, TCU_MODE2, PWM_FUNC, \
+ NO_PWM_IN, WORK_SLEEP)>;
+ };
+ channel2: channel2 {
+ compatible = "ingenic,tcu_chn2";
+ ingenic,channel-info = <CHANNEL_INFO(2, TCU_MODE2, PWM_FUNC, \
+ NO_PWM_IN, WORK_SLEEP)>;
+ };
+ channel3: channel3 {
+ compatible = "ingenic,tcu_chn3";
+ ingenic,channel-info = <CHANNEL_INFO(3, TCU_MODE1, \
+ PWM_AND_TRACKBALL_FUNC, PWM_IN, NOWORK_SLEEP)>;
+ };
+ channel4: channel4 {
+ compatible = "ingenic,tcu_chn4";
+ ingenic,channel-info = <CHANNEL_INFO(4, TCU_MODE1, \
+ PWM_AND_TRACKBALL_FUNC, PWM_IN, NOWORK_SLEEP)>;
+ };
+ channel5: channel5 {
+ compatible = "ingenic,tcu_chn5";
+ ingenic,channel-info = <CHANNEL_INFO(5, TCU_MODE1, \
+ TRACKBALL_FUNC, NO_PWM_IN, NOWORK_SLEEP)>;
+ };
+ channel6: channel6 {
+ compatible = "ingenic,tcu_chn6";
+ ingenic,channel-info = <CHANNEL_INFO(6, TCU_MODE1, \
+ TRACKBALL_FUNC, NO_PWM_IN, NOWORK_SLEEP)>;
+ };
+ channel7: channel7 {
+ compatible = "ingenic,tcu_chn7";
+ ingenic,channel-info = <CHANNEL_INFO(7, TCU_MODE1, \
+ TRACKBALL_FUNC, NO_PWM_IN, NOWORK_SLEEP)>;
+ };
+ channel15: channel15 {
+ compatible = "ingenic,tcu_chn15";
+ ingenic,channel-info = <CHANNEL_INFO(15, 0,0,0,0)>;
+ };
+ channel16: channel16 {
+ compatible = "ingenic,watchdog";
+ ingenic,channel-info = <CHANNEL_INFO(16, 0,0,0,0)>;
+ };
+ };
+
+
+ rtc: rtc@0x10003000 {
+ compatible = "ingenic,rtc";
+ reg = <0x10003000 0x4c>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_RTC>;
+ system-power-controller;
+ power-on-press-ms = <1000>;
+ };
+
+ pinctrl: pinctrl@0x10010000 {
+ compatible = "ingenic,x2000-v12-pinctrl";
+ reg = <0x10010000 0x1000>;
+ ingenic,num-chips = <6>;
+ ingenic,regs-offset = <0x100>;
+
+ gpa: gpa {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO0>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <17>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpb: gpb {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO1>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55565555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpc: gpc {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO2>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <25>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpd: gpd {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO3>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ gpe: gpe {
+ gpio-controller;
+ #gpio-cells = <3>;
+ #ingenic,pincfg-cells = <3>;
+ #ingenic,pinmux-cells = <2>;
+ interrupts = <IRQ_GPIO4>;
+ interrupt-parent = <&core_intc>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ ingenic,num-gpios = <32>;
+ ingenic,pull-gpios-low = <0x55555555>;
+ ingenic,pull-gpios-high = <0x55555555>;
+ };
+
+ };
+
+ uart0: serial@0x10030000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10030000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pd>;
+ status = "disabled";
+ };
+ uart1: serial@0x10031000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10031000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pc>;
+ status = "disabled";
+ };
+ uart2: serial@0x10032000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10032000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pd>;
+ status = "disabled";
+ };
+ uart3: serial@0x10033000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10033000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pd>;
+ status = "disabled";
+ };
+
+ uart4: serial@0x10034000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10034000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART4>;
+ status = "disabled";
+ };
+ uart5: serial@0x10035000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10035000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART5>;
+ status = "disabled";
+ };
+ uart6: serial@0x10036000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10036000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART6>;
+ status = "disabled";
+ };
+ uart7: serial@0x10037000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10037000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART7>;
+ status = "disabled";
+ };
+
+ uart8: serial@0x10038000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10038000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart8_pb>;
+ status = "disabled";
+ };
+ uart9: serial@0x10039000 {
+ compatible = "ingenic,8250-uart";
+ reg = <0x10039000 0x100>;
+ reg-shift = <2>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_UART9>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart9_pb>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@0x10050000 {
+ compatible = "ingenic,x2000-i2c";
+ reg = <0x10050000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@0x10051000 {
+ compatible = "ingenic,x2000-i2c";
+ reg = <0x10051000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@0x10052000 {
+ compatible = "ingenic,x2000-i2c";
+ reg = <0x10052000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@0x10053000 {
+ compatible = "ingenic,x2000-i2c";
+ reg = <0x10053000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@0x10054000 {
+ compatible = "ingenic,x2000-i2c";
+ reg = <0x10054000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@0x10055000 {
+ compatible = "ingenic,x2000-i2c";
+ reg = <0x10055000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_I2C5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi0: spi0@0x10043000 {
+ compatible = "ingenic,spi";
+ reg = <0x10043000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SSI0>;
+ dmas = <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI0_TX)>,
+ <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI0_RX)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi1: spi1@0x10044000 {
+ compatible = "ingenic,spi";
+ reg = <0x10044000 0x1000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SSI1>;
+ dmas = <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI1_TX)>,
+ <&pdma INGENIC_DMA_TYPE(INGENIC_DMA_REQ_SSI1_RX)>;
+ dma-names = "tx", "rx";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ scc: scc@0x10040000 {
+ compatible = "ingenic,scc";
+ reg = <0x10040000 0x100>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SCC>;
+ status = "disabled";
+ };
+
+ dtrng: dtrng@0x10072000 {
+ compatible = "ingenic,dtrng";
+ reg = <0x10072000 0x100>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_DTRNG>;
+ status = "disabled";
+ };
+
+ otg_phy: otg_phy {
+ compatible = "ingenic,innophy";
+ };
+ };
+
+ ahb2 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ as:as {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ as_platform: as-platform {
+ compatible = "ingenic,as-platform";
+ reg = <0x134d0000 0x114>, <0x134d1000 0x100>;
+ reg-names = "dma", "fifo";
+ ingenic,fifo-size = <4096>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_AUDIO>;
+ ingenic,fth_quirk;
+ };
+ as_virtual_fe: as-virtual-fe {
+ compatible = "ingenic,as-vir-fe";
+ reg = <0x00000000 0x0>;
+ ingenic,cap-dai-bm = <0xc>;
+ ingenic,num-dais = <4>;
+ };
+ as_fmtcov: as-fmtcov {
+ compatible = "ingenic,as-fmtcov";
+ reg = <0x134d2000 0x28>;
+ };
+ as_fe_dsp: as-dsp {
+ compatible = "ingenic,as-dsp";
+ reg = <0x134d4000 0x30>;
+ ingenic,li-port = <0 1 2 3 4 6 7 8 9 10 11 12>;
+ ingenic,lo-port = <0 1 2 3 4 5 6 7 8 9 10 11>;
+ ingenic,cap-dai-bm = <0x3e0>;
+ ingenic,num-dais = <10>;
+ };
+ as_be_baic: as-baic {
+ compatible = "ingenic,as-baic";
+ reg = <0x134d5000 0x5000>;
+ ingenic,num-dais = <5>;
+ ingenic,dai-mode = <BAIC_3AND(BAIC_PCM_MODE, BAIC_DSP_MODE, BAIC_I2S_MODE)>,
+ <BAIC_3AND(BAIC_PCM_MODE, BAIC_DSP_MODE, BAIC_I2S_MODE)>,
+ <BAIC_4AND(BAIC_I2S_MODE, BAIC_TDM1_MODE, BAIC_TDM2_MODE, BAIC_NO_REPLAY)>,
+ <BAIC_4AND(BAIC_I2S_MODE, BAIC_TDM1_MODE, BAIC_TDM2_MODE, BAIC_NO_RECORD)>,
+ <BAIC_PCM_MODE>;
+ ingenic,dai-pin-num = <1>, <1>, <1>, <1>, <1>;
+ ingenic,dai-pin-split = <0>, <1>, <2>, <3>;
+ };
+ as_dmic: as-dmic {
+ compatible = "ingenic,as-dmic";
+ reg = <0x134da000 0x10>;
+ };
+ as_aux_mixer: as-mixer {
+ compatible = "ingenic,as-mixer";
+ reg = <0x134dc000 0x8>;
+ ingenic,num-mixers = <1>;
+ };
+ as_spdif: as-spdif {
+ compatible = "ingenic,as-spdif";
+ reg = <0x134db000 0x14>, <0x134db100 0x14>;
+ reg-names = "out", "in";
+ };
+ };
+
+ msc0: msc@0x13450000 {
+ compatible = "ingenic,sdhci";
+ reg = <0x13450000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_MSC0>;
+ pinctrl-names ="default";
+ pinctrl-0 = <&msc0_8bit>;
+ };
+
+ msc1: msc@0x13460000 {
+ compatible = "ingenic,sdhci";
+ reg = <0x13460000 0x10000>;
+ status = "disabled";
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_MSC1>;
+ pinctrl-names ="default";
+ pinctrl-0 = <&msc1_4bit>;
+ };
+
+ msc2: msc@0x13490000 {
+ compatible = "ingenic,sdhci";
+ reg = <0x13490000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_MSC2>;
+ pinctrl-names ="default";
+ pinctrl-0 = <&msc2_4bit>;
+ };
+
+ aes: aes@0x13430000 {
+ compatible = "ingenic,aes";
+ reg = <0x13430000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_AES>;
+ status = "ok";
+ };
+
+ hash: hash@0x13470000 {
+ compatible = "ingenic,hash";
+ reg = <0x13470000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_HASH>;
+ status = "ok";
+ };
+
+ rsa: rsa@0x13480000 {
+ compatible = "ingenic,rsa";
+ reg = <0x13480000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_RSA>;
+ status = "ok";
+ };
+
+ mac0: mac@0x134b0000 {
+ compatible = "ingenic,dwc-mac";
+ reg = <0x134b0000 0x2000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_GMAC0>;
+ status = "disabled";
+ ingenic,rst-ms = <10>;
+ };
+
+ mac1: mac@0x134a0000 {
+ compatible = "ingenic,dwc-mac";
+ reg = <0x134a0000 0x2000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_GMAC1>;
+ status = "disabled";
+ ingenic,rst-ms = <10>;
+ };
+
+ sfc: sfc@0x13440000 {
+ compatible = "ingenic,sfc";
+ reg = <0x13440000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_SFC>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sfc_pe>;
+ status = "disabled";
+ };
+
+ pdma: dma@13420000 {
+ compatible = "ingenic,x1000-pdma";
+ reg = <0x13420000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupt-names = "pdma", "pdmad";
+ interrupts = <IRQ_PDMA>, <IRQ_PDMAD>;
+ #dma-channels = <8>;
+ #dma-cells = <1>;
+ ingenic,reserved-chs = <0x3>;
+ };
+
+ pwm: pwm@0x134c0000 {
+ compatible = "ingenic,x2000-pwm";
+ reg = <0x134c0000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_PWM>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pc>;
+ status = "ok";
+ };
+
+ otg: otg@0x13500000 {
+ compatible = "ingenic,dwc2-hsotg";
+ reg = <0x13500000 0x40000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_OTG>;
+ ingenic,usbphy=<&otg_phy>;
+ status = "disabled";
+ };
+
+ efuse: efuse@0x13540000 {
+ compatible = "ingenic,x2000-efuse";
+ reg = <0x13540000 0x10000>;
+ status = "okay";
+ };
+ };
+
+ ahb1 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ };
+
+ ahb0 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+
+ cim: cim@0x13060000 {
+ compatible = "ingenic,cim";
+ reg = <0x13060000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_CIM>;
+ status = "disable";
+ };
+
+ dpu: dpu@0x13050000 {
+ compatible = "ingenic,x2000-dpu";
+ reg = <0x13050000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_LCD>;
+ status = "disabled";
+ };
+
+ rotate: rotate@0x13070000 {
+ compatible = "ingenic,x2000-rotate";
+ reg = <0x13070000 0x10000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_ROTATE>;
+ status = "okay";
+ };
+
+ helix: helix@0x13200000 {
+ compatible = "ingenic,x2000-helix";
+ reg = <0x13200000 0x100000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_HELIX>;
+ status = "disabled";
+ };
+
+ felix: felix@0x13300000 {
+ compatible = "ingenic,x2000-felix";
+ reg = <0x13300000 0x100000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_FELIX>;
+ status = "disabled";
+ };
+
+ isp0: isp0@0x13700000 {
+ compatible = "ingenic,x2000-isp0";
+ reg = <0x13700000 0x100000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_ISP0>;
+ status = "disabled";
+ };
+
+ isp1: isp1@0x13800000 {
+ compatible = "ingenic,x2000-isp1";
+ reg = <0x13800000 0x100000>;
+ interrupt-parent = <&core_intc>;
+ interrupts = <IRQ_ISP1>;
+ status = "disabled";
+ };
+ };
+
+};
+#include "x2000-v12-pinctrl.dtsi"

View File

@ -0,0 +1,197 @@
diff -drupN a/arch/mips/boot/dts/ingenic/x2000_v12_fpga.dts b/arch/mips/boot/dts/ingenic/x2000_v12_fpga.dts
--- a/arch/mips/boot/dts/ingenic/x2000_v12_fpga.dts 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/dts/ingenic/x2000_v12_fpga.dts 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,193 @@
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "x2000-v12.dtsi"
+
+/ {
+ compatible = "img,fpga", "ingenic,x2000";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "disable";
+};
+
+
+//&pwm {
+// ingenic,pwm-outputs = <0>; /* <0 - 15> select which pwms are really used */
+//}
+
+
+&msc0 {
+ status = "okay";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ non-removable;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ non-removable;
+ voltage-ranges = <1800 3300>;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+};
+
+&msc2 {
+ status = "disable";
+ /*mmc-hs200-1_8v;*/
+ cap-mmc-highspeed;
+ non-removable;
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ non-removable;
+ voltage-ranges = <1800 3300>;
+
+ /* special property */
+ ingenic,wp-gpios = <0>;
+ ingneic,cd-gpios = <0>;
+ ingenic,rst-gpios = <0>;
+};
+
+&mac0 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac0_rmii_p0_normal>, <&mac0_rmii_p1_normal>;
+ pinctrl-1 = <&mac0_rmii_p0_rst>, <&mac0_rmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpb 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RMII>;
+ ingenic,mode-reg = <0xb00000e4>;
+};
+
+&mac1 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac1_rmii_p0_normal>, <&mac1_rmii_p1_normal>;
+ pinctrl-1 = <&mac1_rmii_p0_rst>, <&mac1_rmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpb 1 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RMII>;
+ ingenic,mode-reg = <0xb00000e8>;
+};
+
+/*
+&mac0 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac0_rgmii_p0_normal>, <&mac0_rgmii_p1_normal>;
+ pinctrl-1 = <&mac0_rgmii_p0_rst>, <&mac0_rgmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpb 0 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RGMII>;
+ ingenic,mode-reg = <0xb00000e4>;
+};
+
+&mac1 {
+ pinctrl-names = "default", "reset";
+ pinctrl-0 = <&mac1_rgmii_p0_normal>, <&mac1_rgmii_p1_normal>;
+ pinctrl-1 = <&mac1_rgmii_p0_rst>, <&mac1_rgmii_p1_normal>;
+ status = "okay";
+ ingenic,rst-gpio = <&gpb 1 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ ingenic,rst-ms = <10>;
+ ingenic,mac-mode = <RGMII>;
+ ingenic,mode-reg = <0xb00000e8>;
+};
+*/
+
+&sfc {
+ status = "okay";
+ ingenic,sfc-max-frequency = <150000000>;
+ ingenic,use_board_info = /bits/ 8 <0>;
+ ingenic,spiflash_param_offset = <0>;
+
+
+};
+
+&cim {
+ status = "okay";
+ port {
+ cim_0: endpoint@0 {
+ remote-endpoint = <&mt9v022_0>;
+ bus-width = <8>;
+ };
+ };
+};
+
+
+&i2c4 {
+ status = "okay";
+ clock-frequency = <100000>;
+ timeout = <1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pd>;
+
+ mt9v022: mt9v022@0x5c {
+ status = "okay";
+ compatible = "micron,mt9v022";
+ reg = <0x5c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cim_pa>;
+
+ pwdn-gpios = <&gpe 4 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+ vcc-en-gpios = <&gpe 3 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;
+
+ port {
+ mt9v022_0: endpoint {
+ remote-endpoint = <&cim_0>;
+ };
+ };
+ };
+};
+
+/ {
+
+ extclk: extclk {
+ clock-frequency = <24000000>;
+ };
+
+ gpio_keys: gpio_keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpa 31 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
+ gpio-key,wakeup;
+ };
+ };
+};
+
+&felix {
+ status = "okay";
+};
+
+&helix {
+ status = "okay";
+};
+
+&dpu {
+ status = "okay";
+};
+
+/ {
+ display-dbi {
+ compatible = "simple-bus";
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <>;
+ panel_bm8766@0 {
+ compatible = "ingenic,bm8766";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&tft_lcd_pb>;
+ };
+ };
+
+
+};

View File

@ -0,0 +1,73 @@
diff -drupN a/arch/mips/boot/zcompressed/Makefile b/arch/mips/boot/zcompressed/Makefile
--- a/arch/mips/boot/zcompressed/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,69 @@
+#
+# linux/arch/mips/boot/compressed/Makefile
+#
+# create a compressed zImage from the original vmlinux
+#
+
+targets := zImage uImage vmlinuz vmlinux.bin.gz head.o misc.o piggy.o dummy.o
+
+OBJS := $(obj)/head.o $(obj)/misc.o
+
+LD_ARGS := -m elf32ltsmip -T $(obj)/ld.script -Ttext 0x80F00000 -Bstatic -EL
+OBJCOPY_ARGS := -O elf32-tradlittlemips
+
+ENTRY := $(obj)/entry
+FILESIZE := $(obj)/filesize
+
+KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
+KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS))
+KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
+
+
+drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags = $(addprefix --remove-section=,$(drop-sections))
+
+LOADADDR=0x80010000
+
+$(obj)/vmlinux.bin.gz: vmlinux
+ rm -f $(obj)/vmlinux.bin.gz
+ $(OBJCOPY) -O binary $(strip-flags) vmlinux $(obj)/vmlinux.bin
+ gzip -v9f $(obj)/vmlinux.bin
+
+$(obj)/head.o: $(obj)/head.S $(obj)/vmlinux.bin.gz vmlinux
+ echo $(CC)
+ $(CC) $(KBUILD_AFLAGS) $(a_flags) \
+ -DIMAGESIZE=$(shell sh $(FILESIZE) $(obj)/vmlinux.bin.gz) \
+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) vmlinux ) \
+ -DLOADADDR=0x80010000 \
+ -I./include \
+ -c -o $(obj)/head.o $<
+
+$(obj)/vmlinuz: $(OBJS) $(obj)/ld.script $(obj)/vmlinux.bin.gz $(obj)/dummy.o
+ $(OBJCOPY) \
+ --add-section=.image=$(obj)/vmlinux.bin.gz \
+ --set-section-flags=.image=contents,alloc,load,readonly,data \
+ $(obj)/dummy.o $(obj)/piggy.o
+ $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/piggy.o
+ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap
+
+zImage: $(obj)/vmlinuz
+ $(OBJCOPY) -O binary $(obj)/vmlinuz $(obj)/zImage
+ @rm -f $(obj)/vmlinuz
+
+vmlinux.bin: $(VMLINUX)
+ $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
+
+uImage: $(VMLINUX) vmlinux.bin
+ rm -f $(obj)/vmlinux.bin.gz
+ gzip -9 $(obj)/vmlinux.bin
+ mkimage -A mips -O linux -T kernel -C gzip \
+ -a $(LOADADDR) -e $(shell sh ./$(obj)/tools/entry $(NM) $(VMLINUX) ) \
+ -n 'Linux-$(KERNELRELEASE)' \
+ -d $(obj)/vmlinux.bin.gz $(obj)/uImage
+xImage: zImage
+ mkimage -A mips -O linux -T kernel -C none \
+ -a 0x80F00000 -e 0x80F00000 \
+ -n 'Linux-$(KERNELRELEASE)' \
+ -d $(obj)/zImage $(obj)/xImage
+ @rm -f $(obj)/zImage

View File

@ -0,0 +1,8 @@
diff -drupN a/arch/mips/boot/zcompressed/dummy.c b/arch/mips/boot/zcompressed/dummy.c
--- a/arch/mips/boot/zcompressed/dummy.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/dummy.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}

View File

@ -0,0 +1,16 @@
diff -drupN a/arch/mips/boot/zcompressed/entry b/arch/mips/boot/zcompressed/entry
--- a/arch/mips/boot/zcompressed/entry 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/entry 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# grab the kernel_entry address from the vmlinux elf image
+entry=`$1 $2 | grep kernel_entry` -w
+
+fs=`echo $entry | grep ffffffff` # check toolchain output
+
+if [ -n "$fs" ]; then
+ echo "0x"`$1 $2 | grep kernel_entry -w | cut -c9- | awk '{print $1}'`
+else
+ echo "0x"`$1 $2 | grep kernel_entry -w | cut -c1- | awk '{print $1}'`
+fi

View File

@ -0,0 +1,11 @@
diff -drupN a/arch/mips/boot/zcompressed/filesize b/arch/mips/boot/zcompressed/filesize
--- a/arch/mips/boot/zcompressed/filesize 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/filesize 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,7 @@
+#!/bin/sh
+HOSTNAME=`uname`
+if [ "$HOSTNAME" = "Linux" ]; then
+echo `ls -l $1 | awk '{print $5}'`
+else
+echo `ls -l $1 | awk '{print $6}'`
+fi

View File

@ -0,0 +1,91 @@
diff -drupN a/arch/mips/boot/zcompressed/head.S b/arch/mips/boot/zcompressed/head.S
--- a/arch/mips/boot/zcompressed/head.S 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/head.S 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,87 @@
+/*
+ * linux/arch/mips/boot/compressed/head.S
+ *
+ * Copyright (C) 2005-2008 Ingenic Semiconductor Inc.
+ */
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+#include <asm/cachectl.h>
+#include <asm/regdef.h>
+
+#define IndexInvalidate_I 0x00
+#define IndexWriteBack_D 0x01
+
+ .set noreorder
+ LEAF(startup)
+startup:
+
+ move s0, a0 /* Save the boot loader transfered args */
+ move s1, a1
+ move s2, a2
+ move s3, a3
+
+ la a0, _edata
+ la a1, _end
+1: sw zero, 0(a0) /* Clear BSS section */
+ bne a1, a0, 1b
+ addu a0, 4
+
+ la sp, (.stack + 8192)
+
+ la a0, __image_begin
+ la a1, IMAGESIZE
+ la a2, LOADADDR
+ la ra, 1f
+ la k0, decompress_kernel
+ jr k0
+ nop
+1:
+
+ move a0, s0
+ move a1, s1
+ move a2, s2
+ move a3, s3
+
+ li k0, KERNEL_ENTRY
+
+ jr k0
+ nop
+
+2:
+ b 2b
+
+ END(startup)
+
+
+ LEAF(flushcaches)
+ li k0, 0x80000000 # start address
+ li k1, 0x80008000 # end address (32KB I-Cache)
+ la t0, 1f
+ la t1, 0xa0000000
+ or t0, t0, t1
+ jr.hb t0
+ nop
+1:
+ cache IndexWriteBack_D, 0(k0)
+ cache IndexWriteBack_D, 32(k0)
+ cache IndexWriteBack_D, 64(k0)
+ cache IndexWriteBack_D, 96(k0)
+ cache IndexInvalidate_I, 0(k0)
+ cache IndexInvalidate_I, 32(k0)
+ cache IndexInvalidate_I, 64(k0)
+ cache IndexInvalidate_I, 96(k0)
+
+ addu k0, k0, 128
+ bne k0, k1, 1b
+ nop
+ sync
+ la t0, 3f
+ jr.hb t0
+ nop
+3:
+ jr ra
+ nop
+ END(flushcaches)
+
+ .comm .stack,4096*2,4

View File

@ -0,0 +1,155 @@
diff -drupN a/arch/mips/boot/zcompressed/ld.script b/arch/mips/boot/zcompressed/ld.script
--- a/arch/mips/boot/zcompressed/ld.script 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/ld.script 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,151 @@
+OUTPUT_ARCH(mips)
+ENTRY(startup)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+
+ .init : { *(.init) } =0
+ .text :
+ {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ .kstrtab : { *(.kstrtab) }
+
+ . = ALIGN(16); /* Exception table */
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ __start___dbe_table = .; /* Exception table for data bus errors */
+ __dbe_table : { *(__dbe_table) }
+ __stop___dbe_table = .;
+
+ __start___ksymtab = .; /* Kernel symbol table */
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
+
+ _etext = .;
+
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+
+ /* Startup code */
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+ . = ALIGN(4096); /* Align double page for init_task_union */
+ __init_end = .;
+
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ .fini : { *(.fini) } =0
+ .reginfo : { *(.reginfo) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = .;
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = .;
+ .data :
+ {
+ _fdata = . ;
+ *(.data)
+
+ /* Put the compressed image here, so bss is on the end. */
+ __image_begin = .;
+ *(.image)
+ __image_end = .;
+ /* Align the initial ramdisk image (INITRD) on page boundaries. */
+ . = ALIGN(4096);
+ __ramdisk_begin = .;
+ *(.initrd)
+ __ramdisk_end = .;
+ . = ALIGN(4096);
+
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ _gp = . + 0x8000;
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ . = ALIGN(4);
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __bss_start = .;
+ _fbss = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ _end = . ;
+ PROVIDE (end = .);
+ }
+
+ /* Sections to be discarded */
+ /DISCARD/ :
+ {
+ *(.text.exit)
+ *(.data.exit)
+ *(.exitcall.exit)
+ }
+
+ /* This is the MIPS specific mdebug section. */
+ .mdebug : { *(.mdebug) }
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ /* These must appear regardless of . */
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+ .comment : { *(.comment) }
+ .note : { *(.note) }
+}

View File

@ -0,0 +1,389 @@
diff -drupN a/arch/mips/boot/zcompressed/misc.c b/arch/mips/boot/zcompressed/misc.c
--- a/arch/mips/boot/zcompressed/misc.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/misc.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,385 @@
+/*
+ * linux/arch/mips/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for JZSOC by Peter Wei, 2008
+ *
+ */
+
+#include <soc/base.h>
+#include <asm/addrspace.h>
+#include <stdarg.h>
+
+#define size_t int
+#define NULL 0
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args) args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000 /* Window size must be at least 32k, */
+ /* and a power of two */
+
+static uch *inbuf; /* input buffer */
+static uch window[WSIZE]; /* Sliding window buffer */
+
+static unsigned insize = 0; /* valid bytes in inbuf */
+static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0; /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
+#define RESERVED 0xC0 /* bit 6,7: reserved */
+
+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+#if 0
+static void gzip_mark(void **);
+static void gzip_release(void **);
+#endif
+void* memset(void* s, int c, size_t n);
+void* memcpy(void* __dest, __const void* __src, size_t __n);
+
+extern void flushcaches(void); /* defined in head.S */
+
+char *input_data;
+int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+
+#if 1
+
+/*
+ * Add puts func just for debug.
+ * If it does not work,check the follows macro define.
+ * Have a pleasant debug day.
+ */
+
+static volatile int uart_base;
+
+#define OFF_LSR (0x14)
+#define OFF_LCR (0x0C)
+#define OFF_TDR (0x00)
+#define UART_OFF 0x1000
+#define UART_LSR_TDRQ (1 << 5) /* 1: transmit FIFO half "empty" */
+#define UART_LSR_TEMT (1 << 6) /* 1: transmit FIFO and shift registers empty */
+
+void check_uart(void)
+{
+ volatile char *base = (volatile char*)CKSEG1ADDR(UART0_IOBASE);
+ int i;
+ for(i=0; i<4; i++) {
+ if(base[OFF_LCR])
+ break;
+ base += UART_OFF;
+ }
+
+ uart_base = (int)base;
+}
+
+static void serial_putc (const char c)
+{
+ volatile char *uart_lsr = (volatile char *)(uart_base + OFF_LSR);
+ volatile char *uart_tdr = (volatile char *)(uart_base + OFF_TDR);
+
+ if (c == '\n') serial_putc ('\r');
+
+ /* Wait for fifo to shift out some bytes */
+ while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) );
+
+ *uart_tdr = (char)c;
+}
+static void puts(const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+static int hex2asc(int n)
+{
+ n &= 15;
+ if(n > 9){
+ return ('a' - 10) + n;
+ } else {
+ return '0' + n;
+ }
+}
+
+int printf(char *fmt,...)
+{
+ va_list ap;
+ char scratch[16];
+ va_start(ap,fmt);
+
+ for(;;){
+ switch(*fmt){
+ case 0:
+ va_end(ap);
+ return 0;
+ case '%':
+ switch(fmt[1]) {
+ case 'p':
+ case 'X':
+ case 'x': {
+ unsigned n = va_arg(ap, unsigned);
+ char *p = scratch + 15;
+ *p = 0;
+ do {
+ *--p = hex2asc(n);
+ n = n >> 4;
+ } while(n != 0);
+ while(p > (scratch + 7)) *--p = '0';
+ while (*p) serial_putc(*p++);
+ fmt += 2;
+ continue;
+ }
+ case 'd': {
+ int n = va_arg(ap, int);
+ char *p = scratch + 15;
+ *p = 0;
+ if(n < 0) {
+ serial_putc('-');
+ n = -n;
+ }
+ do {
+ *--p = (n % 10) + '0';
+ n /= 10;
+ } while(n != 0);
+ while (*p) serial_putc(*p++);
+ fmt += 2;
+ continue;
+ }
+ case 's': {
+ char *s = va_arg(ap, char*);
+ if(s == 0) s = "(null)";
+ while (*s) serial_putc(*s++);
+ fmt += 2;
+ continue;
+ }
+ }
+ serial_putc(*fmt++);
+ break;
+ case '\n':
+ serial_putc('\r');
+ default:
+ serial_putc(*fmt++);
+ }
+ }
+}
+
+
+#else
+static void puts(const char *str)
+{
+}
+#endif
+
+extern unsigned char _end[];
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE 0x10000
+
+#include "../../../../lib/inflate.c"
+
+#if 0
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size <0) error("Malloc error\n");
+ if (free_mem_ptr == 0) error("Memory error\n");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *)free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+ error("\nOut of memory\n");
+
+ return p;
+}
+
+static void free(void *where)
+{ /* Don't care */
+}
+
+
+static void gzip_mark(void **ptr)
+{
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ free_mem_ptr = (long) *ptr;
+}
+#endif
+void* memset(void* s, int c, size_t n)
+{
+ int i;
+ char *ss = (char*)s;
+
+ for (i=0;i<n;i++) ss[i] = c;
+ return s;
+}
+
+void* memcpy(void* __dest, __const void* __src, size_t __n)
+{
+ int i = 0;
+ unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
+
+ for (i = __n >> 3; i > 0; i--) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1 << 2) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1 << 1) {
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1)
+ *d++ = *s++;
+
+ return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+ if (insize != 0) {
+ error("ran out of input data\n");
+ }
+
+ inbuf = input_data;
+ insize = input_len;
+ inptr = 1;
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out++ = *in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+}
+
+static void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+void decompress_kernel(unsigned int imageaddr, unsigned int imagesize, unsigned int loadaddr)
+{
+ input_data = (char *)imageaddr;
+ input_len = imagesize;
+ output_ptr = 0;
+ output_data = (uch *)loadaddr;
+ free_mem_ptr = (unsigned long)_end;
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+ check_uart();
+ makecrc();
+ puts("Uncompressing Linux...\n");
+ gunzip();
+ flushcaches();
+ puts("Ok, booting the kernel.\n");
+#if 0
+ {
+ int i;
+ int *p = loadaddr;
+ for(i=0;i<512;i++)
+ {
+ if(i%4 == 0)
+ printf("\n");
+ printf("%x ",p[i]);
+ }
+ printf("\n");
+ }
+#endif
+}

View File

@ -0,0 +1,16 @@
diff -drupN a/arch/mips/boot/zcompressed/tools/entry b/arch/mips/boot/zcompressed/tools/entry
--- a/arch/mips/boot/zcompressed/tools/entry 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/tools/entry 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# grab the kernel_entry address from the vmlinux elf image
+entry=`$1 $2 | grep kernel_entry`
+
+fs=`echo $entry | grep ffffffff` # check toolchain output
+
+if [ -n "$fs" ]; then
+ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'`
+else
+ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'`
+fi

View File

@ -0,0 +1,11 @@
diff -drupN a/arch/mips/boot/zcompressed/tools/filesize b/arch/mips/boot/zcompressed/tools/filesize
--- a/arch/mips/boot/zcompressed/tools/filesize 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/boot/zcompressed/tools/filesize 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,7 @@
+#!/bin/sh
+HOSTNAME=`uname`
+if [ "$HOSTNAME" = "Linux" ]; then
+echo `ls -l $1 | awk '{print $5}'`
+else
+echo `ls -l $1 | awk '{print $6}'`
+fi

View File

@ -0,0 +1,12 @@
diff -drupN a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
--- a/arch/mips/include/asm/bootinfo.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/bootinfo.h 2022-06-09 05:02:27.000000000 +0300
@@ -79,6 +79,8 @@ enum loongson_machine_type {
*/
#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */
#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
+#define MACH_XBURST 2 /* Xburst based SOC */
+#define MACH_XBURST2 3 /* Xburst2 based SOC */
extern char *system_type;
const char *get_system_type(void);

View File

@ -0,0 +1,25 @@
diff -drupN a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h
--- a/arch/mips/include/asm/cacheflush.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/cacheflush.h 2022-06-09 05:02:27.000000000 +0300
@@ -58,7 +58,8 @@ static inline void flush_dcache_page(str
if (cpu_has_dc_aliases)
__flush_dcache_page(page);
else if (!cpu_has_ic_fills_f_dc)
- SetPageDcacheDirty(page);
+// SetPageDcacheDirty(page);
+ __flush_dcache_page(page);
}
#define flush_dcache_mmap_lock(mapping) do { } while (0)
@@ -125,7 +126,10 @@ static inline void kunmap_noncoherent(vo
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
static inline void flush_kernel_dcache_page(struct page *page)
{
- BUG_ON(cpu_has_dc_aliases && PageHighMem(page));
+// BUG_ON(cpu_has_dc_aliases && PageHighMem(page));
+ if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
+ __flush_dcache_page(page);
+
}
/*

View File

@ -0,0 +1,20 @@
diff -drupN a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
--- a/arch/mips/include/asm/cop2.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/cop2.h 2022-06-09 05:02:27.000000000 +0300
@@ -11,7 +11,15 @@
#include <linux/notifier.h>
-#if defined(CONFIG_CPU_CAVIUM_OCTEON)
+#if defined(CONFIG_XBURST_MXUV2)
+#define cop2_present 1
+extern void xburst_cop2_save(struct xburst_cop2_state *);
+extern void xburst_cop2_restore(struct xburst_cop2_state *);
+#define cop2_save(r) xburst_cop2_save(&(r)->thread.cp2)
+#define cop2_restore(r) xburst_cop2_restore(&(r)->thread.cp2)
+#define cop2_lazy_restore 0
+
+#elif defined(CONFIG_CPU_CAVIUM_OCTEON)
extern void octeon_cop2_save(struct octeon_cop2_state *);
extern void octeon_cop2_restore(struct octeon_cop2_state *);

View File

@ -0,0 +1,23 @@
diff -drupN a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
--- a/arch/mips/include/asm/cpu-features.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/cpu-features.h 2022-06-09 05:02:27.000000000 +0300
@@ -311,6 +311,19 @@
#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
#endif
+
+#if defined(CONFIG_MACH_XBURST) && !defined(cpu_has_mxu)
+#define cpu_has_mxu (cpu_data[0].ases & MIPS_ASE_CU2)
+#elif !defined(cpu_has_mxu)
+#define cpu_has_mxu 0
+#endif
+
+#if defined(CONFIG_MACH_XBURST2) && !defined(cpu_has_mxuv3)
+#define cpu_has_mxuv3 (cpu_data[0].ases & MIPS_ASE_CU2)
+#elif !defined(cpu_has_mxu)
+#define cpu_has_mxuv3 0
+#endif
+
#ifndef cpu_has_userlocal
#define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI)
#endif

View File

@ -0,0 +1,65 @@
diff -drupN a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
--- a/arch/mips/include/asm/cpu.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/cpu.h 2022-06-09 05:02:27.000000000 +0300
@@ -45,6 +45,7 @@
#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */
#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */
#define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */
+#define PRID_COMP_INGENIC_13 0x130000 /* X2000 */
/*
* Assigned Processor ID (implementation) values for bits 15:8 of the PRId
@@ -170,11 +171,42 @@
#define PRID_IMP_CAVIUM_CN78XX 0x9500
#define PRID_IMP_CAVIUM_CN70XX 0x9600
+
+
/*
- * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_*
+ * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
+ * 31:24, Company Options is reserved;
+ * 23:16, Company ID is 0xd0;
+ * 15:8, Processor ID;
+ * -- 15:13, is the Generation of INGENIC's core.
+ * 0x0 is XBurst1,
+ * 0x1 is XBurst2,
+ * others are reserved.
+ * -- 12:8, the encode of micro-architecture(uA).
+ * 7:0, Revision;
+ * -- 7:4, the encode of process.
+ * 0x0 is SMIC40LP,
+ * 0x1 is TSMC40LP,
+ * others are reserved.
+ * -- 3:0, the version of a chip's package or upgrades.
*/
+#define PRID_COMPANY_ID_MASK 0x00FF0000
+#define PRID_CPU_ARCH_MASK 0x00001F00
+#define PRID_CPU_FEATURE_MASK 0xFFFF0000
+#define PRID_CPU_CHIPS_MASK 0x000FF000
+#define PRID_IMP_PROCESSOR_ID_MSK 0x0000E000
+#define PRID_IMP_XBURST (0x0 << 13)
+#define PRID_IMP_XBURST2 (0x1 << 13)
+#define PRID_CPU_ISA_MASK 0x00000FFF
-#define PRID_IMP_JZRISC 0x0200
+#define PRID_IMP_JZRISC 0x00010000
+#define PRID_CPU_JZ4775S 0x2ed00000
+#define PRID_CPU_JZ4780 0x3ee00000
+#define PRID_CPU_M200 0x7ae00000
+#define PRID_CPU_X1000 0x2ed10000
+#define PRID_CPU_X1800 0x00d00000
+#define PRID_CPU_X2000 0x00130000
+#define PRID_IMP_ISA_R2 0x0000024f
/*
* These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
@@ -398,6 +430,6 @@ enum cpu_type_enum {
#define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */
#define MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */
#define MIPS_ASE_VZ 0x00000080 /* Virtualization ASE */
-#define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */
-
+#define MIPS_ASE_CU2 0x00000100 /* Coprocessor 2 implemented */
+#define MIPS_ASE_MSA 0x00080000 /* MIPS SIMD Architecture */
#endif /* _ASM_CPU_H */

View File

@ -0,0 +1,34 @@
diff -drupN a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
--- a/arch/mips/include/asm/fpu.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/fpu.h 2022-06-09 05:02:27.000000000 +0300
@@ -41,7 +41,7 @@ extern void _restore_fp(struct task_stru
*/
enum fpu_mode {
FPU_32BIT = 0, /* FR = 0 */
- FPU_64BIT, /* FR = 1, FRE = 0 */
+ FPU_64BIT, /* FR = 1 */
FPU_AS_IS,
FPU_HYBRID, /* FR = 1, FRE = 1 */
@@ -74,11 +74,17 @@ static inline int __enable_fpu(enum fpu_
goto fr_common;
case FPU_64BIT:
-#if !(defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) \
- || defined(CONFIG_64BIT))
- /* we only have a 32-bit FPU */
+ change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | ST0_FR);
+ enable_fpu_hazard();
+ /* check FR has the desired value */
+ if (read_c0_status() & ST0_FR)
+ return 0;
+
+ /* unsupported FR value */
+ __disable_fpu();
+ /* we only have a 32-bit FPU. not used for xburst2. qiao */
return SIGFPE;
-#endif
+
/* fall through */
case FPU_32BIT:
if (cpu_has_fre) {

View File

@ -0,0 +1,24 @@
diff -drupN a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
--- a/arch/mips/include/asm/irqflags.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/irqflags.h 2022-06-09 05:02:27.000000000 +0300
@@ -142,6 +142,20 @@ static inline void arch_local_irq_enable
: "memory");
}
+static inline unsigned long read_cp0_30_flags(void)
+{
+ unsigned long flags;
+
+ asm __volatile__(
+ " .set push \n"
+ " .set reorder \n"
+ " mfc0 %[flags], $30 \n"
+ " .set pop \n"
+ : [flags] "=r" (flags));
+
+ return flags;
+}
+
static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;

View File

@ -0,0 +1,21 @@
diff -drupN a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h
--- a/arch/mips/include/asm/msa.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/msa.h 2022-06-09 05:02:27.000000000 +0300
@@ -102,6 +102,8 @@ static inline void enable_msa(void)
{
if (cpu_has_msa) {
set_c0_config5(MIPS_CONF5_MSAEN);
+ set_c0_status(ST0_CU2);
+ KSTK_STATUS(current) |= ST0_CU2;
enable_fpu_hazard();
}
}
@@ -110,6 +112,8 @@ static inline void disable_msa(void)
{
if (cpu_has_msa) {
clear_c0_config5(MIPS_CONF5_MSAEN);
+ clear_c0_status(ST0_CU2);
+ KSTK_STATUS(current) &= ~ST0_CU2;
disable_fpu_hazard();
}
}

View File

@ -0,0 +1,21 @@
diff -drupN a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
--- a/arch/mips/include/asm/pgtable-bits.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/pgtable-bits.h 2022-06-09 05:02:27.000000000 +0300
@@ -249,6 +249,17 @@ static inline uint64_t pte_to_entrylo(un
/* Ingenic uses the WA bit to achieve write-combine memory writes */
#define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT)
+#elif defined(CONFIG_MACH_XBURST) || defined(CONFIG_MACH_XBURST2)
+
+#define _CACHE_CACHABLE_WT_WA (0<<_CACHE_SHIFT) /* R4600 only */
+#define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT) /* R4600 only */
+#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) /* R4[0246]00 */
+#define _CACHE_CACHABLE_WB_WA (3<<_CACHE_SHIFT) /* R4[0246]00 */
+#define _CACHE_CACHABLE_WT_WA_S (4<<_CACHE_SHIFT) /* R4[04]00MC only */
+#define _CACHE_CACHABLE_WB_WA_S (5<<_CACHE_SHIFT) /* R4[04]00MC only */
+#define _CACHE_CACHABLE_WA _CACHE_UNCACHED_ACCELERATED
+#define _CACHE_CACHABLE_NONCOHERENT _CACHE_CACHABLE_WB_WA
+
#endif
#ifndef _CACHE_CACHABLE_NO_WA

View File

@ -0,0 +1,155 @@
diff -drupN a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
--- a/arch/mips/include/asm/processor.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/processor.h 2022-06-09 05:02:27.000000000 +0300
@@ -19,6 +19,7 @@
#include <asm/cpu-info.h>
#include <asm/mipsregs.h>
#include <asm/prefetch.h>
+#include <asm/cpu-features.h>
/*
* Return current * instruction pointer ("program counter").
@@ -82,9 +83,19 @@ extern unsigned int vced_count, vcei_cou
*/
#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
-
#define NUM_FPU_REGS 32
+#if cpu_has_mxu
+#define NUM_MXU_VPR_REGS 16 //vpr0~15
+#define NUM_MXU_VSR_REGS 0
+#endif
+
+#if cpu_has_mxuv3
+#define NUM_MXU_VPR_REGS 32 //vpr0~31
+#define NUM_MXU_VSR_REGS 4 //vsr0~3
+#endif
+
+
#ifdef CONFIG_CPU_HAS_MSA
# define FPU_REG_WIDTH 128
#else
@@ -96,10 +107,30 @@ union fpureg {
__u64 val64[FPU_REG_WIDTH / 64];
};
+typedef union mxuvec {
+#if cpu_has_mxu
+ uint8_t val128[16]; //simd128
+#endif
+#if cpu_has_mxuv3
+ uint8_t val512[64]; //simd512
+#endif
+} mxuvec_t;
+
+
+//#ifdef CONFIG_MACH_XBURST
+struct xburst_mxu_struct {
+ mxuvec_t vpr[NUM_MXU_VPR_REGS];
+ mxuvec_t vsr[NUM_MXU_VSR_REGS];
+ uint32_t csr;
+};
+//#endif
+
+
+
#ifdef CONFIG_CPU_LITTLE_ENDIAN
# define FPR_IDX(width, idx) (idx)
#else
-# define FPR_IDX(width, idx) ((idx) ^ ((64 / (width)) - 1))
+# define FPR_IDX(width, idx) ((FPU_REG_WIDTH / (width)) - 1 - (idx))
#endif
#define BUILD_FPR_ACCESS(width) \
@@ -154,8 +185,20 @@ struct mips3264_watch_reg_state {
union mips_watch_reg_state {
struct mips3264_watch_reg_state mips3264;
};
+#if defined(CONFIG_XBURST_MXUV2)
+typedef union {
+ u64 val64[2];
+} vpr_t;
-#if defined(CONFIG_CPU_CAVIUM_OCTEON)
+struct xburst_cop2_state {
+ u32 mxu_csr;
+ vpr_t vr[32];
+};
+
+#define COP2_INIT \
+ .cp2 = {0,},
+
+#elif defined(CONFIG_CPU_CAVIUM_OCTEON)
struct octeon_cop2_state {
/* DMFC2 rt, 0x0201 */
@@ -224,6 +267,13 @@ struct nlm_cop2_state {
#define COP2_INIT
#endif
+#ifdef CONFIG_PMON_DEBUG
+struct xburst_perf_cnt {
+ u32 perfctrl;
+ u64 perfcnt;
+};
+#endif
+
typedef struct {
unsigned long seg;
} mm_segment_t;
@@ -262,6 +312,11 @@ struct thread_struct {
/* Saved state of the DSP ASE, if available. */
struct mips_dsp_state dsp;
+//#ifdef CONFIG_MACH_XBURST
+ /* Saved registers of the MXU, if available. */
+ struct xburst_mxu_struct mxu;
+//#endif
+
/* Saved watch register state, if available. */
union mips_watch_reg_state watch;
@@ -270,13 +325,18 @@ struct thread_struct {
unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
unsigned long error_code;
unsigned long trap_nr;
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#if defined(CONFIG_XBURST_MXUV2)
+ struct xburst_cop2_state cp2;
+#elif defined(CONFIG_CPU_CAVIUM_OCTEON)
struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
#endif
#ifdef CONFIG_CPU_XLP
struct nlm_cop2_state cp2;
#endif
+#ifdef CONFIG_PMON_DEBUG
+ struct xburst_perf_cnt pfc[2];
+#endif
struct mips_abi *abi;
};
@@ -288,6 +348,14 @@ struct thread_struct {
#define FPAFF_INIT
#endif /* CONFIG_MIPS_MT_FPAFF */
+#ifdef CONFIG_PMON_DEBUG
+#define PFC_INIT \
+ .pfc = {{0, 0}, {0, 0}},
+#else
+#define PFC_INIT
+#endif /* CONFIG_MACH_XBURST */
+
+
#define INIT_THREAD { \
/* \
* Saved main processor registers \
@@ -341,6 +409,7 @@ struct thread_struct {
* Platform specific cop2 registers(null if no COP2) \
*/ \
COP2_INIT \
+ PFC_INIT \
}
struct task_struct;

View File

@ -0,0 +1,101 @@
diff -drupN a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
--- a/arch/mips/include/asm/r4kcache.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/r4kcache.h 2022-06-09 05:02:27.000000000 +0300
@@ -48,6 +48,41 @@ extern void (*r4k_blast_icache)(void);
: \
: "i" (op), "R" (*(unsigned char *)(addr)))
+#ifdef CONFIG_MACH_XBURST
+#define __inv_btb() \
+ do { \
+ unsigned long tmp; \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ ".set mips32\n\t" \
+ "mfc0 %0, $16, 7\n\t" \
+ "nop\n\t" \
+ "ori %0, 2\n\t" \
+ "mtc0 %0, $16, 7\n\t" \
+ "nop\n\t" \
+ ".set pop\n\t" \
+ : "=&r" (tmp)); \
+ } while(0)
+#define __sync_wb() __sync()
+#define __bridge_sync_war() \
+ do { \
+ if (MIPS_BRIDGE_SYNC_WAR) \
+ __fast_iob(); \
+ } while (0)
+static inline void blast_inclusive_scache(void)
+{
+ __bridge_sync_war();
+}
+#else
+#define __inv_btb() do {} while(0)
+#define __sync_wb() do {} while(0)
+#define __bridge_sync_war() do {} while(0)
+static inline void blast_inclusive_scache(void)
+{
+}
+#endif
+
#ifdef CONFIG_MIPS_MT
#define __iflush_prologue \
@@ -76,13 +111,13 @@ extern void (*r4k_blast_icache)(void);
#else /* CONFIG_MIPS_MT */
#define __iflush_prologue {
-#define __iflush_epilogue }
+#define __iflush_epilogue __inv_btb(); } /*CONFIG_MACH_XBURST*/
#define __dflush_prologue {
-#define __dflush_epilogue }
+#define __dflush_epilogue __sync_wb(); } /*CONFIG_MACH_XBURST*/
#define __inv_dflush_prologue {
#define __inv_dflush_epilogue }
#define __sflush_prologue {
-#define __sflush_epilogue }
+#define __sflush_epilogue __bridge_sync_war(); } /*CONFIG_MACH_XBURST*/
#define __inv_sflush_prologue {
#define __inv_sflush_epilogue }
@@ -105,6 +140,7 @@ static inline void flush_dcache_line_ind
static inline void flush_scache_line_indexed(unsigned long addr)
{
cache_op(Index_Writeback_Inv_SD, addr);
+ __bridge_sync_war(); /*CONFIG_MACH_XBURST*/
}
static inline void flush_icache_line(unsigned long addr)
@@ -144,6 +180,7 @@ static inline void invalidate_scache_lin
static inline void flush_scache_line(unsigned long addr)
{
cache_op(Hit_Writeback_Inv_SD, addr);
+ __bridge_sync_war(); /*CONFIG_MACH_XBURST*/
}
#define protected_cache_op(op,addr) \
@@ -189,6 +226,7 @@ static inline void protected_flush_icach
#else
protected_cache_op(Hit_Invalidate_I, addr);
#endif
+ __inv_btb(); /*CONFIG_MACH_XBURST*/
break;
}
}
@@ -206,11 +244,14 @@ static inline void protected_writeback_d
#else
protected_cache_op(Hit_Writeback_Inv_D, addr);
#endif
+ __sync_wb(); /*CONFIG_MACH_XBURST*/
}
static inline void protected_writeback_scache_line(unsigned long addr)
{
protected_cache_op(Hit_Writeback_Inv_SD, addr);
+
+ __bridge_sync_war(); /*CONFIG_MACH_XBURST*/
}
/*

View File

@ -0,0 +1,60 @@
diff -drupN a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h
--- a/arch/mips/include/asm/switch_to.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/asm/switch_to.h 2022-06-09 05:02:27.000000000 +0300
@@ -15,8 +15,18 @@
#include <asm/cpu-features.h>
#include <asm/watch.h>
#include <asm/dsp.h>
+#include <mxuv3.h>
#include <asm/cop2.h>
#include <asm/fpu.h>
+#include <mxu.h>
+
+#ifdef CONFIG_PMON_DEBUG
+extern void save_perf_event_jz(void *tskvoid);
+extern void restore_perf_event_jz(void *tskvoid);
+#else
+#define save_perf_event_jz(tskvoid)
+#define restore_perf_event_jz(tskvoid)
+#endif
struct task_struct;
@@ -89,7 +99,24 @@ do { \
__save_dsp(prev); \
__restore_dsp(next); \
} \
- if (cop2_present) { \
+ if(cpu_has_mxu) { \
+ if (KSTK_STATUS(prev) & ST0_CU2) { \
+ __save_mxu(prev); \
+ } \
+ if (KSTK_STATUS(next) & ST0_CU2) { \
+ __restore_mxu(next); \
+ } \
+ } \
+ if (cpu_has_mxuv3) { \
+ if ((KSTK_STATUS(prev) & ST0_CU2)) { \
+ __save_mxuv3(prev); \
+ } \
+ if ((KSTK_STATUS(next) & ST0_CU2)) { \
+ set_c0_status(ST0_CU2); \
+ __restore_mxuv3(next); \
+ } \
+ } \
+ if (cop2_present) { \
set_c0_status(ST0_CU2); \
if ((KSTK_STATUS(prev) & ST0_CU2)) { \
if (cop2_lazy_restore) \
@@ -102,9 +129,11 @@ do { \
} \
clear_c0_status(ST0_CU2); \
} \
+ save_perf_event_jz(prev); \
__clear_software_ll_bit(); \
if (cpu_has_userlocal) \
write_c0_userlocal(task_thread_info(next)->tp_value); \
+ restore_perf_event_jz(next); \
__restore_watch(next); \
(last) = resume(prev, next, task_thread_info(next)); \
} while (0)

View File

@ -0,0 +1,24 @@
diff -drupN a/arch/mips/include/uapi/asm/sigcontext.h b/arch/mips/include/uapi/asm/sigcontext.h
--- a/arch/mips/include/uapi/asm/sigcontext.h 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/include/uapi/asm/sigcontext.h 2022-06-09 05:02:27.000000000 +0300
@@ -11,7 +11,9 @@
#include <linux/types.h>
#include <asm/sgidefs.h>
-
+#ifdef CONFIG_MACH_XBURST
+#include <asm/processor.h>
+#endif
/* scalar FP context was used */
#define USED_FP (1 << 0)
@@ -49,6 +51,9 @@ struct sigcontext {
unsigned long sc_lo2;
unsigned long sc_hi3;
unsigned long sc_lo3;
+#ifdef CONFIG_MACH_XBURST
+ unsigned long sc_mxu[NUM_MXU_REGS]; /* NUM_MXU_REGS = 16*/
+#endif
};
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */

View File

@ -0,0 +1,134 @@
diff -drupN a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
--- a/arch/mips/kernel/cpu-probe.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/cpu-probe.c 2022-06-09 05:02:27.000000000 +0300
@@ -17,6 +17,7 @@
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/export.h>
+#include <linux/kallsyms.h>
#include <asm/bugs.h>
#include <asm/cpu.h>
@@ -414,6 +415,7 @@ static inline unsigned int decode_config
config0 = read_c0_config();
+
/*
* Look for Standard TLB or Dual VTLB and FTLB
*/
@@ -471,6 +473,8 @@ static inline unsigned int decode_config
config1 = read_c0_config1();
+ if (config1 & MIPS_CONF1_C2)
+ c->ases |= MIPS_ASE_CU2;
if (config1 & MIPS_CONF1_MD)
c->ases |= MIPS_ASE_MDMX;
if (config1 & MIPS_CONF1_WR)
@@ -1332,18 +1336,65 @@ platform:
}
}
+#ifdef CONFIG_XBURST_MXUV2
+extern int soc_support_mxuv2(void);
+#endif
static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
{
+ unsigned int errorpc;
+ static unsigned int showerrorpc[NR_CPUS];
+ unsigned int config1;
+
+ if(showerrorpc[cpu] == 0) {
+ __asm__ __volatile__ (
+ "mfc0 %0, $30, 0 \n\t"
+ "nop \n\t"
+ :"=r"(errorpc)
+ :);
+
+ printk("CPU%d RESET ERROR PC:%08X\n", cpu,errorpc);
+ if(kernel_text_address(errorpc))
+ print_ip_sym(errorpc);
+ showerrorpc[cpu] = 1;
+ }
+
decode_configs(c);
/* JZRISC does not implement the CP0 counter. */
+ /* INGENIC RISC does not implement the CP0 counter. */
c->options &= ~MIPS_CPU_COUNTER;
BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
- switch (c->processor_id & PRID_IMP_MASK) {
- case PRID_IMP_JZRISC:
+
+ switch (c->processor_id & PRID_IMP_PROCESSOR_ID_MSK) {
+ case PRID_IMP_XBURST:
+ {
+ unsigned int config7;
c->cputype = CPU_JZRISC;
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
- __cpu_name[cpu] = "Ingenic JZRISC";
+ __cpu_name[cpu] = "Xburst";
+ /*
+ * When CPU enters the long cycle, it will reduce the CPU speed to save power.
+ * Set cp0 config7 bit 4 to disable this feature
+ * This feature will cause bogoMips and loops_per_jiffy calculate in error
+ */
+ config7 = read_c0_config7();
+ config7 |= (1 << 4);
+ write_c0_config7(config7);
+
+ config1 = read_c0_config1();
+#ifdef CONFIG_XBURST_MXUV2
+ if(soc_support_mxuv2()) {
+ c->ases |= MIPS_ASE_XBURSTMXUV2;
+ } else
+#endif
+ //c->ases |= MIPS_ASE_XBURSTMXU;
+ }
+ break;
+ case PRID_IMP_XBURST2:
+ {
+ c->cputype = CPU_JZRISC;
+ __cpu_name[cpu] = "Ingenic XBurst@II";
break;
+ }
default:
panic("Unknown Ingenic Processor ID!");
break;
@@ -1444,6 +1495,7 @@ void cpu_probe(void)
{
struct cpuinfo_mips *c = &current_cpu_data;
unsigned int cpu = smp_processor_id();
+ //unsigned long fpu_csr31 = 0;
c->processor_id = PRID_IMP_UNKNOWN;
c->fpu_id = FPIR_IMP_NONE;
@@ -1482,6 +1534,7 @@ void cpu_probe(void)
case PRID_COMP_INGENIC_D0:
case PRID_COMP_INGENIC_D1:
case PRID_COMP_INGENIC_E1:
+ case PRID_COMP_INGENIC_13:
cpu_probe_ingenic(c, cpu);
break;
case PRID_COMP_NETLOGIC:
@@ -1512,7 +1565,20 @@ void cpu_probe(void)
}
if (c->options & MIPS_CPU_FPU)
+ {
+ //fpu_fcr31 = cpu_test_fpu_csr31(FPU_CSR_DEFAULT);
cpu_set_fpu_opts(c);
+ #if 0
+ if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
+ MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
+ if (c->fpu_id & MIPS_FPIR_3D)
+ c->ases |= MIPS_ASE_MIPS3D;
+ if (c->fpu_id & MIPS_FPIR_HAS2008)
+ fpu_fcr31 = cpu_test_fpu_csr31(FPU_CSR_DEFAULT|FPU_CSR_MAC2008|FPU_CSR_ABS2008|FPU_CSR_NAN2008);
+ }
+ #endif
+
+ }
else
cpu_set_nofpu_opts(c);

View File

@ -0,0 +1,15 @@
diff -drupN a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
--- a/arch/mips/kernel/genex.S 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/genex.S 2022-06-09 05:02:27.000000000 +0300
@@ -506,7 +506,11 @@ NESTED(nmi_handler, PT_SIZE, sp)
BUILD_HANDLER tr tr sti silent /* #13 */
BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent /* #14 */
BUILD_HANDLER fpe fpe fpe silent /* #15 */
+#ifdef CONFIG_XBURST_MXUV2
+ BUILD_HANDLER mfpe mfpe none silent /* #16 */
+#else
BUILD_HANDLER ftlb ftlb none silent /* #16 */
+#endif
BUILD_HANDLER msa msa sti silent /* #21 */
BUILD_HANDLER mdmx mdmx sti silent /* #22 */
#ifdef CONFIG_HARDWARE_WATCHPOINTS

View File

@ -0,0 +1,55 @@
diff -drupN a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c
--- a/arch/mips/kernel/idle.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/idle.c 2022-06-09 05:02:27.000000000 +0300
@@ -52,6 +52,30 @@ void r4k_wait(void)
__r4k_wait();
}
+#ifdef X2000_IDLE_PD
+extern int x2000_pm_enter(void);
+static void ingenic_wait_irqoff_pd(void)
+{
+ WARN_ON_ONCE(!irqs_disabled());
+ x2000_pm_enter(PM_SUSPEND_STANDBY);
+ local_irq_enable();
+}
+#else
+void ingenic_wait_irqoff(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ __asm__(
+ " .set push \n"
+ " .set arch=r4000 \n"
+ " sync \n"
+ " wait \n"
+ " .set pop \n");
+ local_irq_enable();
+}
+#endif
+
+
/*
* This variant is preferable as it allows testing need_resched and going to
* sleep depending on the outcome atomically. Unfortunately the "It is
@@ -175,12 +199,19 @@ void __init check_wait(void)
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
- case CPU_JZRISC:
case CPU_LOONGSON1:
case CPU_XLR:
case CPU_XLP:
cpu_wait = r4k_wait;
break;
+ case CPU_JZRISC:
+#ifdef X2000_IDLE_PD
+ cpu_wait = ingenic_wait_irqoff_pd;
+#else
+ cpu_wait = ingenic_wait_irqoff;
+#endif
+
+ break;
case CPU_BMIPS5000:
cpu_wait = r4k_wait_irqoff;
break;

View File

@ -0,0 +1,137 @@
diff -drupN a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
--- a/arch/mips/kernel/perf_event_mipsxx.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/perf_event_mipsxx.c 2022-06-09 05:02:27.000000000 +0300
@@ -551,12 +551,33 @@ static atomic_t active_events = ATOMIC_I
static DEFINE_MUTEX(pmu_reserve_mutex);
static int (*save_perf_irq)(void);
+static void enable_interrupt(void *args)
+{
+ enable_percpu_irq(mipspmu.irq, IRQ_TYPE_LEVEL_HIGH);
+}
+static void disable_interrupt(void *args)
+{
+ disable_percpu_irq(mipspmu.irq);
+}
static int mipspmu_get_irq(void)
{
int err;
if (mipspmu.irq >= 0) {
/* Request my own irq handler. */
+#ifdef CONFIG_MACH_XBURST2
+ /* on ingenic xburst2 cpu, should request percpu interrupt. */
+ err = request_percpu_irq(mipspmu.irq, mipsxx_pmu_handle_irq,
+ "mips_perf_pmu", &mipspmu);
+
+ if (err) {
+ pr_warning("Unable to request IRQ%d for MIPS "
+ "performance counters!\n", mipspmu.irq);
+ } else {
+ /* enable all cpus interrtup here. */
+ on_each_cpu(enable_interrupt, NULL, 1);
+ }
+#else
err = request_irq(mipspmu.irq, mipsxx_pmu_handle_irq,
IRQF_PERCPU | IRQF_NOBALANCING |
IRQF_NO_THREAD | IRQF_NO_SUSPEND |
@@ -566,6 +587,8 @@ static int mipspmu_get_irq(void)
pr_warn("Unable to request IRQ%d for MIPS performance counters!\n",
mipspmu.irq);
}
+
+#endif
} else if (cp0_perfcount_irq < 0) {
/*
* We are sharing the irq number with the timer interrupt.
@@ -583,9 +606,15 @@ static int mipspmu_get_irq(void)
static void mipspmu_free_irq(void)
{
- if (mipspmu.irq >= 0)
- free_irq(mipspmu.irq, &mipspmu);
- else if (cp0_perfcount_irq < 0)
+ if (mipspmu.irq >= 0) {
+#ifdef CONFIG_MACH_XBURST2
+ /* disable interrupt on all cpus */
+ on_each_cpu(disable_interrupt, NULL, 1);
+ free_percpu_irq(mipspmu.irq, &mipspmu);
+#else
+ free_irq(mipspmu.irq, NULL);
+#endif
+ } else if (cp0_perfcount_irq < 0)
perf_irq = save_perf_irq;
}
@@ -858,6 +887,13 @@ static const struct mips_perf_event xlp_
[PERF_COUNT_HW_BRANCH_MISSES] = { 0x1c, CNTR_ALL }, /* PAPI_BR_MSP */
};
+static const struct mips_perf_event ingenic_event_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02, CNTR_EVEN, T },
+ [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
+};
+
/* 24K/34K/1004K/interAptiv/loongson1 cores share the same cache event map. */
static const struct mips_perf_event mipsxxcore_cache_map
[PERF_COUNT_HW_CACHE_MAX]
@@ -1227,6 +1263,45 @@ static const struct mips_perf_event xlp_
},
};
+static const struct mips_perf_event ingenic_cache_map
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+ /*
+ * Like some other architectures (e.g. ARM), the performance
+ * counters don't differentiate between read and write
+ * accesses/misses, so this isn't strictly correct, but it's the
+ * best we can do. Writes and reads get combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x07, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x07, CNTR_ODD, T },
+ },
+},
+[C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x08, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x08, CNTR_ODD, T },
+ },
+},
+};
#ifdef CONFIG_MIPS_MT_SMP
static void check_and_calc_range(struct perf_event *event,
const struct mips_perf_event *pev)
@@ -1767,6 +1842,11 @@ init_hw_perf_events(void)
mipspmu.cache_event_map = &xlp_cache_map;
mipspmu.map_raw_event = xlp_pmu_map_raw_event;
break;
+ case CPU_JZRISC:
+ mipspmu.name = "ingenic";
+ mipspmu.general_event_map = &ingenic_event_map;
+ mipspmu.cache_event_map = &ingenic_cache_map;
+ break;
default:
pr_cont("Either hardware does not support performance "
"counters, or not yet implemented.\n");

View File

@ -0,0 +1,12 @@
diff -drupN a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
--- a/arch/mips/kernel/proc.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/proc.c 2022-06-09 05:02:27.000000000 +0300
@@ -121,6 +121,8 @@ static int show_cpuinfo(struct seq_file
if (cpu_has_eva) seq_printf(m, "%s", " eva");
if (cpu_has_htw) seq_printf(m, "%s", " htw");
if (cpu_has_xpa) seq_printf(m, "%s", " xpa");
+ if (cpu_has_mxu) seq_printf(m, "%s", " mxu");
+ if (cpu_has_mxuv3) seq_printf(m, "%s", " mxuv3");
seq_printf(m, "\n");
if (cpu_has_mmips) {

View File

@ -0,0 +1,36 @@
diff -drupN a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
--- a/arch/mips/kernel/process.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/process.c 2022-06-09 05:02:27.000000000 +0300
@@ -45,6 +45,8 @@
#include <asm/inst.h>
#include <asm/stacktrace.h>
#include <asm/irq_regs.h>
+#include <mxu.h>
+#include <mxuv3.h>
#ifdef CONFIG_HOTPLUG_CPU
void arch_cpu_idle_dead(void)
@@ -63,12 +65,13 @@ void start_thread(struct pt_regs * regs,
unsigned long status;
/* New thread loses kernel privileges. */
- status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK);
+ status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_CU2|ST0_FR|KU_MASK);
status |= KU_USER;
regs->cp0_status = status;
clear_used_math();
clear_fpu_owner();
init_dsp();
+ init_mxu();
clear_thread_flag(TIF_USEDMSA);
clear_thread_flag(TIF_MSA_CTX_LIVE);
disable_msa();
@@ -102,6 +105,8 @@ int arch_dup_task_struct(struct task_str
save_dsp(current);
+ //save_mxu(current);
+
preempt_enable();
*dst = *src;

View File

@ -0,0 +1,172 @@
diff -drupN a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
--- a/arch/mips/kernel/setup.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/setup.c 2022-06-09 05:02:27.000000000 +0300
@@ -26,6 +26,7 @@
#include <linux/sizes.h>
#include <linux/device.h>
#include <linux/dma-contiguous.h>
+#include <linux/of_fdt.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
@@ -625,6 +626,89 @@ static void __init request_crashkernel(s
#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND)
+#ifdef CONFIG_LINUX_PMEM
+static unsigned long g_pmem_total_size=0;
+static unsigned long g_pmem_start=0;
+static int g_pmem_set_by_cmdline=0;
+
+#if 0
+/* called in arch/mips/xburst2/soc-x2000-v12/setup.c */
+unsigned long set_reserved_pmem_total_size(unsigned long size)
+{
+ g_pmem_total_size = size;
+ return 0;
+}
+#endif
+
+unsigned long get_reserved_pmem_size(void)
+{
+ return g_pmem_total_size;
+}
+
+unsigned long get_reserved_pmem_start(void)
+{
+ return g_pmem_start;
+}
+
+static int __init pmem_parse(char *str)
+{
+ char *retptr;
+ unsigned long pmem_size;
+ unsigned long pmem_base = -1;
+
+ pmem_size = memparse(str, &retptr);
+ if(pmem_size < 0) {
+ printk("pmem_size is error!\n");
+ /* pmem_size = 0x4000000; */
+ goto abort;
+ }
+
+ if (*retptr == '@')
+ pmem_base = memparse(retptr + 1, NULL);
+
+ if(pmem_base < 0) {
+ printk("pmem_base is error!\n");
+ /* pmem_base = 0xc000000; */
+ goto abort;
+ }
+
+ g_pmem_start = pmem_base;
+ g_pmem_total_size = pmem_size;
+ g_pmem_set_by_cmdline = 1;
+
+ return 1;
+abort:
+ return 0;
+}
+__setup("pmem=", pmem_parse);
+
+static unsigned int str2(unsigned int *i, const char *str, int v)
+{
+ unsigned int temp = 0;
+
+ while(*str != 0) {
+ if((*str>='0') && (*str<='9') && (v == 10))
+ temp = temp*v + (*str - '0');
+ else if ((*str>='A') && (*str<='F') && (v == 16))
+ temp = temp*v + (*str - 'A') + 10;
+ else
+ break;
+ str++;
+ }
+
+ *i = temp;
+
+ if (v == 10) {
+ if (*str == 'M')
+ return 1024 * 1024;
+ else if (*str == 'K')
+ return 1024;
+ }
+
+ return 1;
+}
+#endif /* CONFIG_LINUX_PMEM */
+
static void __init arch_mem_init(char **cmdline_p)
{
struct memblock_region *reg;
@@ -678,6 +762,59 @@ static void __init arch_mem_init(char **
pr_info("User-defined physical RAM map:\n");
print_memory_map();
}
+#ifdef CONFIG_LINUX_PMEM
+ /* reserve memory for pmem. */
+ if (g_pmem_set_by_cmdline == 0) {
+ char *str = CONFIG_PMEM_RESERVE_SIZE;
+ unsigned int size;
+
+ do {
+ if (strlen(str) == 1) {
+ g_pmem_total_size = 0;
+ break;
+ } else if ((*(str+1) == 'x') || (*(str+1) == 'X')) {
+ str2(&size, str+2, 16);
+ g_pmem_total_size = size;
+ break;
+ } else {
+ unsigned int f = str2(&size, str, 10);
+ g_pmem_total_size = size * f;
+ break;
+ }
+ } while(0);
+ }
+
+ printk(KERN_INFO "reserve memory for pmem, g_pmem_total_size: %#x\n", (unsigned int)g_pmem_total_size);
+ if ( g_pmem_total_size > 0x10000 ) {
+ int i;
+ const int field = 2 * sizeof(unsigned long);
+
+ for (i = boot_mem_map.nr_map-1; i>-1; i--) {
+
+ if (BOOT_MEM_RAM == boot_mem_map.map[i].type
+ && (unsigned long)boot_mem_map.map[i].size > g_pmem_total_size) {
+
+ printk(KERN_INFO " original, memory %d: %0*Lx @ %0*Lx \n", i,
+ field, (unsigned long long) boot_mem_map.map[i].size,
+ field, (unsigned long long) boot_mem_map.map[i].addr);
+
+ boot_mem_map.map[i].size -= g_pmem_total_size;
+ g_pmem_start = (unsigned long)boot_mem_map.map[i].addr + (unsigned long)boot_mem_map.map[i].size;
+
+ printk(KERN_INFO "after reserve pmem, memory %d: %0*Lx @ %0*Lx \n", i,
+ field, (unsigned long long) boot_mem_map.map[i].size,
+ field, (unsigned long long) boot_mem_map.map[i].addr);
+
+ printk(KERN_INFO " reserve memory for pmem: %0*Lx @ %0*Lx ",
+ field, (unsigned long long) g_pmem_total_size,
+ field, (unsigned long long) g_pmem_start);
+ printk(KERN_INFO "\n");
+
+ break;
+ }
+ }
+ }
+#endif /* CONFIG_LINUX_PMEM */
bootmem_init();
#ifdef CONFIG_PROC_VMCORE
@@ -701,6 +838,10 @@ static void __init arch_mem_init(char **
plat_swiotlb_setup();
paging_init();
+
+ early_init_fdt_reserve_self();
+ early_init_fdt_scan_reserved_mem();
+
dma_contiguous_reserve(PFN_PHYS(max_low_pfn));
/* Tell bootmem about cma reserved memblock section */
for_each_memblock(reserved, reg)

View File

@ -0,0 +1,43 @@
diff -drupN a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
--- a/arch/mips/kernel/signal.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/signal.c 2022-06-09 05:02:27.000000000 +0300
@@ -39,6 +39,7 @@
#include <asm/dsp.h>
#include <asm/inst.h>
#include <asm/msa.h>
+#include <mxu.h>
#include "signal-common.h"
@@ -440,6 +441,15 @@ int setup_sigcontext(struct pt_regs *reg
*/
err |= protected_save_fp_context(sc);
+#ifdef CONFIG_MACH_XBURST
+ if (cpu_has_mxu) {
+ unsigned int *regs;
+ regs = __get_mxu_regs(current);
+ for (i = 0; i < NUM_MXU_REGS; i++){
+ err |= __put_user(regs[i], &sc->sc_mxu[i]);
+ }
+ }
+#endif
return err;
}
@@ -513,6 +523,15 @@ int restore_sigcontext(struct pt_regs *r
for (i = 1; i < 32; i++)
err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
+#ifdef CONFIG_MACH_XBURST
+ if (cpu_has_mxu) {
+ unsigned int regs[NUM_MXU_REGS];
+ for (i = 0; i < NUM_MXU_REGS; i++){
+ err |= __get_user(regs[i], &sc->sc_mxu[i]);
+ }
+ __let_mxu_regs(current,regs);
+ }
+#endif
return err ?: protected_restore_fp_context(sc);
}

View File

@ -0,0 +1,23 @@
diff -drupN a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
--- a/arch/mips/kernel/smp.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/smp.c 2022-06-09 05:02:27.000000000 +0300
@@ -247,6 +247,8 @@ void smp_prepare_boot_cpu(void)
int __cpu_up(unsigned int cpu, struct task_struct *tidle)
{
+ unsigned int timeout = 0xff;
+
mp_ops->boot_secondary(cpu, tidle);
/*
@@ -256,6 +258,10 @@ int __cpu_up(unsigned int cpu, struct ta
udelay(100);
schedule();
}
+ while (!(cpumask_test_cpu(cpu, cpu_online_mask) || !timeout--)) {
+ udelay(100);
+ schedule();
+ }
synchronise_count_master(cpu);
return 0;

View File

@ -0,0 +1,137 @@
diff -drupN a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
--- a/arch/mips/kernel/traps.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/kernel/traps.c 2022-06-09 05:02:27.000000000 +0300
@@ -64,6 +64,8 @@
#include <asm/types.h>
#include <asm/stacktrace.h>
#include <asm/uasm.h>
+#include <asm/smp.h>
+
extern void check_wait(void);
extern asmlinkage void rollback_handle_int(void);
@@ -85,7 +87,11 @@ extern asmlinkage void handle_ov(void);
extern asmlinkage void handle_tr(void);
extern asmlinkage void handle_msa_fpe(void);
extern asmlinkage void handle_fpe(void);
+#ifdef CONFIG_XBURST_MXUV2
+extern asmlinkage void handle_mfpe(void);
+#else
extern asmlinkage void handle_ftlb(void);
+#endif
extern asmlinkage void handle_msa(void);
extern asmlinkage void handle_mdmx(void);
extern asmlinkage void handle_watch(void);
@@ -873,6 +879,14 @@ out:
exception_exit(prev_state);
}
+#ifdef CONFIG_MACH_XBURST
+asmlinkage void do_mfpe(struct pt_regs * regs)
+{
+ die_if_kernel("Kernel bug detected", regs);
+ force_sig(SIGILL, current);
+}
+#endif
+
void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
const char *str)
{
@@ -1077,6 +1091,21 @@ asmlinkage void do_ri(struct pt_regs *re
unsigned int opcode = 0;
int status = -1;
+ /* If Config1.CU2 is not set, the exc_code = 10 of cause reg */
+ if (cpu_has_mxuv3 && (1 == smp_processor_id())) {
+ printk("%s(%d):reschedule to cpu0 to smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid);
+ //resched_cpu(0);
+ write_c0_cache(0x2000ff0f);
+ smp_send_reschedule(0);
+ if (0 == smp_processor_id()) {
+ printk("%s(%d):open cu2 field to cpu0 to smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid);
+ set_c0_status(ST0_CU2);
+ KSTK_STATUS(current) |= ST0_CU2;
+ }
+ printk("%s(%d):no cu2 coprocessor to smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid);
+ return;
+ }
+
/*
* Avoid any kernel code. Just emulate the R2 instruction
* as quickly as possible.
@@ -1445,10 +1474,38 @@ asmlinkage void do_cpu(struct pt_regs *r
break;
case 2:
+#ifdef CONFIG_MACH_XBURST2
+#if 0
+ /* Processing of MXA instructions needs setting MSA enable. */
+ if (cpu_has_mxuv3 && (KSTK_STATUS(current) & ST0_CU2)) {
+ err = enable_restore_fp_context(0);
+ if (err) {
+ printk("===debug CU2 exception, KSTK_STATUS(current) & ST0_CU2=0x%lx\n", KSTK_STATUS(current) & ST0_CU2);
+ force_sig(SIGILL, current);
+ }
+ }
+
+#else
+
+ /* To Xburst2 T40, If Status.CU2 is not set and Config1.CU2 is set, the exc_code is 10 and CE field is 2 to Cause Reg
+ * So here only need to open the Status.CU2 field */
+ if (cpu_has_mxuv3 && (0 == smp_processor_id())) {
+ set_c0_status(ST0_CU2);
+ KSTK_STATUS(current) |= ST0_CU2;
+// printk("%s(%d):open cu2 field to cpu0 to smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid);
+ goto out;
+ } else if (1 == smp_processor_id()) {
+ printk("%s(%d):no cu2 coprocessor to smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid);
+ force_sig(SIGILL, current);
+ goto out;
+ }
+#endif
+#else
raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
- break;
+#endif
+ goto out;
}
-
+out:
exception_exit(prev_state);
}
@@ -2070,6 +2127,9 @@ static void configure_status(void)
status_set |= ST0_XX;
if (cpu_has_dsp)
status_set |= ST0_MX;
+ if (cpu_has_mxuv3 && (KSTK_STATUS(current) & ST0_CU2)) {
+ status_set |= ST0_CU2;
+ }
change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
status_set);
@@ -2087,7 +2147,7 @@ static void configure_hwrena(void)
hwrena |= (1 << 29);
if (hwrena)
- write_c0_hwrena(hwrena);
+ write_c0_hwrena(0x2000ff0f);
}
static void configure_exception_vector(void)
@@ -2321,8 +2381,14 @@ void __init trap_init(void)
if (cpu_has_fpu && !cpu_has_nofpuex)
set_except_vector(15, handle_fpe);
+#ifdef CONFIG_XBURST_MXUV2
+ if (cpu_has_mxu)
+ set_except_vector(16, handle_fpe);
+ if (cpu_has_mxuv3)
+ set_except_vector(16, handle_fpe);
+#else
set_except_vector(16, handle_ftlb);
-
+#endif
if (cpu_has_rixiex) {
set_except_vector(19, tlb_do_page_fault_0);
set_except_vector(20, tlb_do_page_fault_0);

View File

@ -0,0 +1,123 @@
diff -drupN a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
--- a/arch/mips/mm/c-r4k.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/mm/c-r4k.c 2022-06-09 05:02:27.000000000 +0300
@@ -60,8 +60,10 @@ static inline void r4k_on_each_cpu(void
* to restrict that call when a CM is not present because both
* CM-based SMP protocols (CMP & CPS) restrict index-based cache ops.
*/
+#ifndef CONFIG_MACH_XBURST2
if (!mips_cm_present())
smp_call_function_many(&cpu_foreign_map, func, info, 1);
+#endif
func(info);
preempt_enable();
}
@@ -378,9 +380,13 @@ static void r4k_blast_scache_page_setup(
{
unsigned long sc_lsize = cpu_scache_line_size();
- if (scache_size == 0)
+ if (scache_size == 0) {
+#ifdef MIPS_BRIDGE_SYNC_WAR
+ r4k_blast_scache_page = (void *)blast_inclusive_scache; /*CONFIG_MACH_XBURST*/
+#else
r4k_blast_scache_page = (void *)cache_noop;
- else if (sc_lsize == 16)
+#endif
+ } else if (sc_lsize == 16)
r4k_blast_scache_page = blast_scache16_page;
else if (sc_lsize == 32)
r4k_blast_scache_page = blast_scache32_page;
@@ -396,9 +402,13 @@ static void r4k_blast_scache_page_indexe
{
unsigned long sc_lsize = cpu_scache_line_size();
- if (scache_size == 0)
+ if (scache_size == 0) {
+#ifdef MIPS_BRIDGE_SYNC_WAR
+ r4k_blast_scache_page_indexed = (void *)blast_inclusive_scache; /*CONFIG_MACH_XBURST*/
+#else
r4k_blast_scache_page_indexed = (void *)cache_noop;
- else if (sc_lsize == 16)
+#endif
+ } else if (sc_lsize == 16)
r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
else if (sc_lsize == 32)
r4k_blast_scache_page_indexed = blast_scache32_page_indexed;
@@ -414,9 +424,13 @@ static void r4k_blast_scache_setup(void)
{
unsigned long sc_lsize = cpu_scache_line_size();
- if (scache_size == 0)
+ if (scache_size == 0) {
+#ifdef MIPS_BRIDGE_SYNC_WAR
+ r4k_blast_scache = (void *)blast_inclusive_scache; /*CONFIG_MACH_XBURST*/
+#else
r4k_blast_scache = (void *)cache_noop;
- else if (sc_lsize == 16)
+#endif
+ } else if (sc_lsize == 16)
r4k_blast_scache = blast_scache16;
else if (sc_lsize == 32)
r4k_blast_scache = blast_scache32;
@@ -770,7 +784,18 @@ static void r4k_dma_cache_inv(unsigned l
if (cpu_has_safe_index_cacheops && size >= dcache_size) {
r4k_blast_dcache();
} else {
+#if defined(CONFIG_MACH_XBURST) || defined(CONFIG_MACH_XBURST2)
+ unsigned long lsize = cpu_dcache_line_size();
+ unsigned long cmask = (lsize - 1);
+ unsigned long lmask = ~(cmask);
+#endif
R4600_HIT_CACHEOP_WAR_IMPL;
+#if defined(CONFIG_MACH_XBURST) || defined(CONFIG_MACH_XBURST2)
+ if (addr & cmask)
+ cache_op(Hit_Writeback_Inv_D, addr & lmask);
+ if ((addr + size) & cmask)
+ cache_op(Hit_Writeback_Inv_D, (addr + size - 1) & lmask);
+#endif
blast_inv_dcache_range(addr, addr + size);
}
preempt_enable();
@@ -797,6 +822,10 @@ static void local_r4k_flush_cache_sigtra
protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
if (!cpu_icache_snoops_remote_store && scache_size)
protected_writeback_scache_line(addr & ~(sc_lsize - 1));
+#ifdef MIPS_BRIDGE_SYNC_WAR
+ else if (!cpu_icache_snoops_remote_store && MIPS_BRIDGE_SYNC_WAR) /*CONFIG_MACH_XBURST*/
+ __fast_iob();
+#endif
if (ic_lsize)
protected_flush_icache_line(addr & ~(ic_lsize - 1));
if (MIPS4K_ICACHE_REFILL_WAR) {
@@ -1487,6 +1516,9 @@ static void setup_scache(void)
case CPU_LOONGSON3:
loongson3_sc_init();
return;
+ case CPU_JZRISC:
+ mips_sc_init();
+ return;
case CPU_CAVIUM_OCTEON3:
case CPU_XLP:
@@ -1497,7 +1529,7 @@ static void setup_scache(void)
if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 |
MIPS_CPU_ISA_M64R2 | MIPS_CPU_ISA_M64R6)) {
-#ifdef CONFIG_MIPS_CPU_SCACHE
+#if defined(CONFIG_MIPS_CPU_SCACHE)
if (mips_sc_init ()) {
scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n",
@@ -1590,7 +1622,10 @@ static void coherency_setup(void)
if (cca < 0 || cca > 7)
cca = read_c0_config() & CONF_CM_CMASK;
_page_cachable_default = cca << _CACHE_SHIFT;
-
+#ifdef CONFIG_MACH_XBURST
+ if (cca == CONF_CM_UNCACHED || cca == CONF_CM_CACHABLE_ACCELERATED)
+ pr_warn("WARNNIGG: Using Uncacheable Kseg0\n");
+#endif
pr_debug("Using cache attribute %d\n", cca);
change_c0_config(CONF_CM_CMASK, cca);

View File

@ -0,0 +1,120 @@
diff -drupN a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
--- a/arch/mips/mm/dma-default.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/mm/dma-default.c 2022-06-09 05:02:27.000000000 +0300
@@ -72,7 +72,8 @@ static inline int cpu_needs_post_dma_flu
return !plat_device_is_coherent(dev) &&
(boot_cpu_type() == CPU_R10000 ||
boot_cpu_type() == CPU_R12000 ||
- boot_cpu_type() == CPU_BMIPS5000);
+ boot_cpu_type() == CPU_BMIPS5000 ||
+ boot_cpu_type() == CPU_JZRISC);
}
static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
@@ -112,22 +113,6 @@ static gfp_t massage_gfp_flags(const str
return gfp | dma_flag;
}
-static void *mips_dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, gfp_t gfp)
-{
- void *ret;
-
- gfp = massage_gfp_flags(dev, gfp);
-
- ret = (void *) __get_free_pages(gfp, get_order(size));
-
- if (ret != NULL) {
- memset(ret, 0, size);
- *dma_handle = plat_map_dma_mem(dev, ret, size);
- }
-
- return ret;
-}
static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs)
@@ -136,12 +121,6 @@ static void *mips_dma_alloc_coherent(str
struct page *page = NULL;
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
- /*
- * XXX: seems like the coherent and non-coherent implementations could
- * be consolidated.
- */
- if (dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs))
- return mips_dma_alloc_noncoherent(dev, size, dma_handle, gfp);
gfp = massage_gfp_flags(dev, gfp);
@@ -157,6 +136,13 @@ static void *mips_dma_alloc_coherent(str
ret = page_address(page);
memset(ret, 0, size);
*dma_handle = plat_map_dma_mem(dev, ret, size);
+
+ /* non coherent memory.*/
+ if(dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) {
+ return ret;
+ }
+
+ /* coherent memory. */
if (!plat_device_is_coherent(dev)) {
dma_cache_wback_inv((unsigned long) ret, size);
if (!hw_coherentio)
@@ -167,12 +153,6 @@ static void *mips_dma_alloc_coherent(str
}
-static void mips_dma_free_noncoherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
- free_pages((unsigned long) vaddr, get_order(size));
-}
static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, struct dma_attrs *attrs)
@@ -181,15 +161,13 @@ static void mips_dma_free_coherent(struc
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
struct page *page = NULL;
- if (dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) {
- mips_dma_free_noncoherent(dev, size, vaddr, dma_handle);
- return;
- }
-
plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
- if (!plat_device_is_coherent(dev) && !hw_coherentio)
- addr = CAC_ADDR(addr);
+ if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) {
+ /* coherent dma memory.*/
+ if (!plat_device_is_coherent(dev) && !hw_coherentio)
+ addr = CAC_ADDR(addr);
+ }
page = virt_to_page((void *) addr);
@@ -273,8 +251,22 @@ static inline void __dma_sync(struct pag
if (offset >= PAGE_SIZE) {
page += offset >> PAGE_SHIFT;
offset &= ~PAGE_MASK;
+#ifdef CONFIG_DMA_INGENIC_HIGHMEM_FLUSH
+ /**
+ * Explain
+ * When offset + len is less than PAGE_SIZE,
+ * only need to flush the length of len;
+ * Rather than flush PAGE_SIZE
+ */
+ len = PAGE_SIZE - offset;
+ len = min(left, len);
+ } else {
+ len = PAGE_SIZE - offset;
+ }
+#else
}
len = PAGE_SIZE - offset;
+#endif
}
addr = kmap_atomic(page);

View File

@ -0,0 +1,31 @@
diff -drupN a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
--- a/arch/mips/mm/tlb-r4k.c 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/mm/tlb-r4k.c 2022-06-09 05:02:27.000000000 +0300
@@ -52,7 +52,7 @@ void local_flush_tlb_all(void)
{
unsigned long flags;
unsigned long old_ctx;
- int entry, ftlbhighset;
+ int entry;
local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
@@ -65,6 +65,8 @@ void local_flush_tlb_all(void)
/* Blast 'em all away. */
if (cpu_has_tlbinv) {
+#ifndef CONFIG_MACH_XBURST2
+ int ftlbhighset;
if (current_cpu_data.tlbsizevtlb) {
write_c0_index(0);
mtc0_tlbw_hazard();
@@ -79,6 +81,9 @@ void local_flush_tlb_all(void)
mtc0_tlbw_hazard();
tlbinvf(); /* invalidate one FTLB set */
}
+#else
+ tlbinvf(); /* invalide FTLB/VTLB set */
+#endif
} else {
while (entry < current_cpu_data.tlbsize) {
/* Make sure all entries differ. */

View File

@ -0,0 +1,129 @@
diff -drupN a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
--- a/arch/mips/vdso/Makefile 2017-10-21 18:09:07.000000000 +0300
+++ b/arch/mips/vdso/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -5,12 +5,10 @@ obj-vdso-y := elf.o gettimeofday.o sigre
ccflags-vdso := \
$(filter -I%,$(KBUILD_CFLAGS)) \
$(filter -E%,$(KBUILD_CFLAGS)) \
- $(filter -mmicromips,$(KBUILD_CFLAGS)) \
$(filter -march=%,$(KBUILD_CFLAGS))
cflags-vdso := $(ccflags-vdso) \
$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
- -O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
- -DDISABLE_BRANCH_PROFILING \
+ -O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
$(call cc-option, -fno-stack-protector)
aflags-vdso := $(ccflags-vdso) \
$(filter -I%,$(KBUILD_CFLAGS)) \
@@ -28,7 +26,7 @@ aflags-vdso := $(ccflags-vdso) \
# the comments on that file.
#
ifndef CONFIG_CPU_MIPSR6
- ifeq ($(call ld-ifversion, -lt, 22500000, y),y)
+ ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
$(warning MIPS VDSO requires binutils >= 2.25)
obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
ccflags-vdso += -DDISABLE_MIPS_VDSO
@@ -52,13 +50,17 @@ quiet_cmd_vdsold = VDSO $@
cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \
-Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@
+# Strip rule for the raw .so files
+$(obj)/%.so.raw: OBJCOPYFLAGS := -S
+$(obj)/%.so.raw: $(obj)/%.so.dbg.raw FORCE
+ $(call if_changed,objcopy)
+
hostprogs-y := genvdso
quiet_cmd_genvdso = GENVDSO $@
define cmd_genvdso
- cp $< $(<:%.dbg=%) && \
- $(OBJCOPY) -S $< $(<:%.dbg=%) && \
- $(obj)/genvdso $< $(<:%.dbg=%) $@ $(VDSO_NAME)
+ $(foreach file,$(filter %.raw,$^),cp $(file) $(file:%.raw=%) &&) \
+ $(obj)/genvdso $(<:%.raw=%) $(<:%.dbg.raw=%) $@ $(VDSO_NAME)
endef
#
@@ -68,19 +70,23 @@ endef
native-abi := $(filter -mabi=%,$(KBUILD_CFLAGS))
targets += $(obj-vdso-y)
-targets += vdso.lds vdso.so.dbg vdso.so vdso-image.c
+targets += vdso.lds
+targets += vdso.so.dbg.raw vdso.so.raw
+targets += vdso.so.dbg vdso.so
+targets += vdso-image.c
obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o)
$(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi)
$(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi)
-$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
+$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi)
-$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
+$(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
$(call if_changed,vdsold)
-$(obj)/vdso-image.c: $(obj)/vdso.so.dbg $(obj)/genvdso FORCE
+$(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \
+ $(obj)/genvdso FORCE
$(call if_changed,genvdso)
obj-y += vdso-image.o
@@ -91,7 +97,10 @@ obj-y += vdso-image.o
# Define these outside the ifdef to ensure they are picked up by clean.
targets += $(obj-vdso-y:%.o=%-o32.o)
-targets += vdso-o32.lds vdso-o32.so.dbg vdso-o32.so vdso-o32-image.c
+targets += vdso-o32.lds
+targets += vdso-o32.so.dbg.raw vdso-o32.so.raw
+targets += vdso-o32.so.dbg vdso-o32.so
+targets += vdso-o32-image.c
ifdef CONFIG_MIPS32_O32
@@ -111,11 +120,12 @@ $(obj)/vdso-o32.lds: KBUILD_CPPFLAGS :=
$(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
-$(obj)/vdso-o32.so.dbg: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
+$(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
$(call if_changed,vdsold)
$(obj)/vdso-o32-image.c: VDSO_NAME := o32
-$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg $(obj)/genvdso FORCE
+$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \
+ $(obj)/genvdso FORCE
$(call if_changed,genvdso)
obj-y += vdso-o32-image.o
@@ -127,7 +137,10 @@ endif
#
targets += $(obj-vdso-y:%.o=%-n32.o)
-targets += vdso-n32.lds vdso-n32.so.dbg vdso-n32.so vdso-n32-image.c
+targets += vdso-n32.lds
+targets += vdso-n32.so.dbg.raw vdso-n32.so.raw
+targets += vdso-n32.so.dbg vdso-n32.so
+targets += vdso-n32-image.c
ifdef CONFIG_MIPS32_N32
@@ -147,11 +160,12 @@ $(obj)/vdso-n32.lds: KBUILD_CPPFLAGS :=
$(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
-$(obj)/vdso-n32.so.dbg: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
+$(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
$(call if_changed,vdsold)
$(obj)/vdso-n32-image.c: VDSO_NAME := n32
-$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg $(obj)/genvdso FORCE
+$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \
+ $(obj)/genvdso FORCE
$(call if_changed,genvdso)
obj-y += vdso-n32-image.o

View File

@ -0,0 +1,87 @@
diff -drupN a/arch/mips/xburst2/Kconfig b/arch/mips/xburst2/Kconfig
--- a/arch/mips/xburst2/Kconfig 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/Kconfig 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,83 @@
+if MACH_XBURST2
+
+menu "SOC Type Selection"
+ depends on MACH_XBURST2
+
+
+choice
+ prompt "SOC types"
+ depends on MACH_XBURST2
+ default SOC_T40
+
+
+config SOC_T40
+ bool "t40"
+ select IRQ_INGENIC_CPU
+ select CLK_T40
+ select INGENIC_INTC_CHIP
+ select PINCTRL
+ select PINCTRL_INGENIC
+ select CLKSRC_OF
+ select CLKDEV_LOOKUP
+ select CLKSRC_INGENIC_CORE_OST
+
+
+config SOC_X2000_V12
+ bool "x2000-v12"
+ select IRQ_INGENIC_CPU
+ select CLK_X2000_V12
+ select INGENIC_INTC_CHIP
+ select PINCTRL
+ select PINCTRL_INGENIC
+ select CLKSRC_OF
+ select CLKDEV_LOOKUP
+ select CLKSRC_INGENIC_CORE_OST
+
+endchoice
+
+config INGENIC_BUILTIN_DTB
+ select BUILTIN_DTB
+ depends on MACH_XBURST2
+ bool "Ingenic Device Tree build into Kernel."
+ default y
+
+choice
+ prompt "device tree select"
+ default DT_NONE
+config DT_NONE
+
+if SOC_T40
+source "arch/mips/xburst2/soc-t40/Kconfig.DT"
+endif
+
+if SOC_X2000_V12
+source "arch/mips/xburst2/soc-x2000-v12/Kconfig.DT"
+endif
+
+endchoice
+
+config DT_T40_MODULE_BASE_DTS_FILE
+ string "dts file for T40 module driver"
+ depends on DT_T40_MODULE_BASE
+ default shark.dts
+ help
+ the dts file location is arch/mips/boot/dts/ingenic/
+
+config RAW_BOOT
+ bool "Raw Boot Kernel"
+ select BOOT_RAW
+ default n
+
+config EXTAL_CLOCK
+ depends on MACH_XBURST2
+ int "extal clock in MHz"
+ default 24
+
+config FPGA_TEST
+ depends on MACH_XBURST2
+ bool "FPGA_TEST"
+ default n
+
+endmenu
+
+endif

View File

@ -0,0 +1,9 @@
diff -drupN a/arch/mips/xburst2/Makefile b/arch/mips/xburst2/Makefile
--- a/arch/mips/xburst2/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,5 @@
+obj-y += core/
+obj-y += common/
+
+obj-$(CONFIG_SOC_T40) += soc-t40/
+obj-$(CONFIG_SOC_X2000_V12) += soc-x2000-v12/

View File

@ -0,0 +1,10 @@
diff -drupN a/arch/mips/xburst2/Platform b/arch/mips/xburst2/Platform
--- a/arch/mips/xburst2/Platform 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/Platform 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,6 @@
+platform-$(CONFIG_MACH_XBURST2) += xburst2/
+load-$(CONFIG_MACH_XBURST2) += 0xffffffff80010000
+cflags-$(CONFIG_MACH_XBURST2) += -I$(srctree)/arch/mips/xburst2/core/include
+
+cflags-$(CONFIG_SOC_T40) += -I$(srctree)/arch/mips/xburst2/soc-t40/include
+cflags-$(CONFIG_SOC_X2000_V12) += -I$(srctree)/arch/mips/xburst2/soc-x2000-v12/include

View File

@ -0,0 +1,14 @@
diff -drupN a/arch/mips/xburst2/common/Makefile b/arch/mips/xburst2/common/Makefile
--- a/arch/mips/xburst2/common/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,10 @@
+
+# add object if need
+
+#obj-y += prom.o
+obj-y += get-cpu-features.o
+obj-y += proc-exec.o
+obj-y += proc.o
+obj-y += mxuv3.o
+obj-y += jz_notifier.o
+obj-$(CONFIG_XBURST2_CPU_TEST) += cpu_ddr_test/

View File

@ -0,0 +1,15 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/Makefile b/arch/mips/xburst2/common/cpu_ddr_test/Makefile
--- a/arch/mips/xburst2/common/cpu_ddr_test/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,11 @@
+
+obj-y += multithread_test.o
+obj-y += ddr_bandwidth_monitor.o
+obj-y += ddr_change_freq.o
+obj-y += l2c_test.o
+obj-y += cpu_spinlock_test.o
+obj-y += cpu_ccu_test.o
+obj-y += raw_dma_test.o
+obj-y += cpu_dma_test.o
+obj-y += cpu_watch_test.o
+ccflags-y += -Wno-unused-function

View File

@ -0,0 +1,74 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/cpu_ccu_test.c b/arch/mips/xburst2/common/cpu_ddr_test/cpu_ccu_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/cpu_ccu_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/cpu_ccu_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,70 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/vmalloc.h>
+#include <linux/list.h>
+
+#include "multithread_test.h"
+#include <ccu.h>
+
+#define PALLADIUM_TRIGER_2() do {\
+ volatile unsigned int *a; \
+ a = (unsigned int *)0xAFFFFFFC; \
+ *a = *a; \
+ } while(0)
+
+struct cpu_ccu_test {
+ void* multithread;
+ unsigned int cnt;
+} cpu_ccu;
+
+
+static int cpu_ccu_test_func(void * param)
+{
+ struct cpu_ccu_test *p = (struct cpu_ccu_test *)param;
+ unsigned int cscr, cssr, csrr, rer;
+
+ cscr = get_ccu_cscr();
+
+ cssr = get_ccu_cssr();
+
+ csrr = get_ccu_csrr();
+
+ rer = get_ccu_rer();
+
+ p->cnt++;
+
+ if(p->cnt == 1000) {
+ p->cnt = 0;
+ printk("%s: cscr=0x%08x, cssr=0x%08x, csrr=0x%08x, rer=0x%08x\n", __func__, cscr, cssr, csrr, rer);
+ }
+#ifdef CONFIG_FPGA_TEST
+ mdelay(100);
+#endif
+ return 0;
+}
+
+static int __init cpu_ccu_test_init(void)
+{
+ cpu_ccu.multithread = multithread_test_init("cpu_ccu_test",1);
+
+ if(cpu_ccu.multithread){
+ multithread_test_add_func(cpu_ccu.multithread,"cpu_ccu_test",cpu_ccu_test_func,(void*)&cpu_ccu);
+ }
+ return 0;
+}
+static void __exit cpu_ccu_test_deinit(void)
+{
+}
+
+late_initcall(cpu_ccu_test_init);
+module_exit(cpu_ccu_test_deinit);

View File

@ -0,0 +1,266 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/cpu_dma_test.c b/arch/mips/xburst2/common/cpu_ddr_test/cpu_dma_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/cpu_dma_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/cpu_dma_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,262 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+//#include <mach/jzdma_v13.h>
+#include <linux/vmalloc.h>
+#include <linux/list.h>
+
+#include "multithread_test.h"
+#include "../../../../../drivers/dma/ingenic/ingenic_dma.h"
+
+struct cpu_dma_test{
+ void* multithread;
+ struct list_head dma_top;
+}cpu_dma;
+struct dma_channel {
+ struct list_head list;
+ struct dma_chan *chan;
+ struct hdma_desc *desc;
+ void *from;
+ unsigned long pfrom;
+ void *to;
+ unsigned long pto;
+ unsigned long test_len;
+ struct mutex lock;
+ unsigned long test_cnt;
+};
+static void init_buf(struct dma_channel *dc)
+{
+ int i;
+
+ unsigned long *p = dc->from;
+ for(i = 0;i < dc->test_len/4;i++){
+ p[i] = (unsigned int)p + i * 4;
+ }
+
+ p = dc->to;
+ for(i = 0;i < dc->test_len/4;i++){
+ p[i] = 0x5a5a5a5a;
+ }
+ dma_cache_sync(NULL,dc->from,dc->test_len,DMA_TO_DEVICE);
+ dma_cache_sync(NULL,dc->to,dc->test_len,DMA_FROM_DEVICE);
+}
+
+static int cpu_dma_test_func_nowait(void * param)
+{
+ struct dma_channel *dc = (struct dma_channel *)param;
+ int i;
+ mutex_lock(&dc->lock);
+ init_buf(dc);
+ {
+ struct ingenic_dma_chan *dmac = to_ingenic_dma_chan(dc->chan);
+ writel((unsigned int)virt_to_phys(dc->desc), dmac->iomem + CH_DDA);
+ /* initiate descriptor fetch */
+ writel(BIT(dmac->id), dmac->engine->iomem + DDRS);
+ writel(1 | (1 << 30),dmac->iomem + CH_DCS);
+ }
+
+ dc->test_cnt ++;
+ {
+ volatile unsigned long *p = (unsigned long *)CKSEG1ADDR(dc->to);
+ unsigned long e = (unsigned long)dc->from;
+ int timeout = 0x10000;
+ for(i = 0;i < dc->test_len/4;i++){
+ timeout = 0x10000;
+ while((p[i] != e) && --timeout);
+ if(timeout==0){
+ printk("xxxxxx error data is not ready! xxxxxx\n");
+ while(1);
+ }
+ e += 4;
+ }
+ }
+ mutex_unlock(&dc->lock);
+#ifdef CONFIG_FPGA_TEST
+ mdelay(100);
+#endif
+ return 0;
+}
+static int cpu_dma_test_func_wait(void * param)
+{
+ struct dma_channel *dc = (struct dma_channel *)param;
+ unsigned long *p = (unsigned long*)((unsigned long)dc->to + dc->test_len - 4);
+ unsigned long e = (unsigned long)dc->from + dc->test_len - 4;
+ unsigned long r;
+ int timeout = 0x10000;
+
+ mutex_lock(&dc->lock);
+ init_buf(dc);
+ {
+ struct ingenic_dma_chan *dmac = to_ingenic_dma_chan(dc->chan);
+
+ writel((unsigned int)virt_to_phys(dc->desc), dmac->iomem + CH_DDA);
+ /* initiate descriptor fetch */
+ writel(BIT(dmac->id), dmac->engine->iomem + DDRS);
+ writel(1 | (1 << 30),dmac->iomem + CH_DCS);
+ while(!(readl(dmac->iomem + CH_DCS) & (1 << 3)) && timeout--);
+ }
+
+ dc->test_cnt ++;
+
+ {
+ do
+ {
+ r = *p;
+ if(r != e){
+ unsigned long *uc = (unsigned long *)((unsigned long)p | 0xa0000000);
+
+ printk("error:from:%p to: %p data[%p] real: 0x%08lx, uc:0x%08lx expect: 0x%08lx, test_cnt: %ld\n",
+ dc->from, dc->to, p,r, *uc, e, dc->test_cnt);
+ break;
+ }
+ p--;
+ e -= 4;
+ }while((unsigned long)p != (unsigned long)dc->to - 4);
+ }
+ if(timeout==0){
+ printk("xxxxxx error dmac is not ready! xxxxxx\n");
+ while(1);
+ }
+
+ mutex_unlock(&dc->lock);
+#ifdef CONFIG_FPGA_TEST
+ mdelay(100);
+#endif
+ return 0;
+}
+static bool filter(struct dma_chan *chan, void *param)
+{
+#if 0
+ if (!((unsigned int)chan->private == 8))
+ return false;
+#endif
+ return true;
+}
+const static char dcm_tsz[8] = { 1, 2, 0, 0, 3, 4, 5, 6 };
+static inline unsigned int get_max_tsz(unsigned long val, unsigned long *dcmp)
+{
+
+ int ord;
+
+ ord = ffs(val) - 1;
+ if (ord < 0)
+ ord = 0;
+ else if (ord > 7)
+ ord = 7;
+
+ *dcmp &= ~DCM_TSZ_MSK;
+ *dcmp |= dcm_tsz[ord] << DCM_TSZ_SFT;
+
+ /* if tsz == 8, set it to 4 */
+ return ord == 3 ? 4 : 1 << ord;
+}
+static struct dma_channel *new_dma_channel(struct cpu_dma_test* cd)
+{
+ struct dma_channel *ch;
+ ch = (struct dma_channel *)vmalloc(sizeof(struct dma_channel));
+ memset(ch,0,sizeof(struct dma_channel));
+ if(ch == NULL){
+ printk("mem alloc failed! %s %d\n",__FILE__,__LINE__);
+ return 0;
+ }
+
+ mutex_init(&ch->lock);
+
+ ch->test_len = 4096;
+ ch->from = (void *)kmalloc(ch->test_len,GFP_KERNEL);
+ ch->to = (void *)kmalloc(ch->test_len,GFP_KERNEL);
+ if(ch->to == 0 || ch->from == 0){
+ printk("mem alloc failed! %s %d\n",__FILE__,__LINE__);
+ goto error_exit;
+ }
+ ch->pfrom = virt_to_phys(ch->from);
+ ch->pto = virt_to_phys(ch->to);
+
+ {
+ dma_cap_mask_t mask;
+ struct hdma_desc *desc;
+ unsigned long burst_len = 128;
+ unsigned long burst_bits = 0;
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+ ch->chan = dma_request_channel(mask, filter, 0);
+ if (!ch->chan) {
+ printk("dma channel request failed! %s %d\n",__FILE__,__LINE__);
+ goto error_exit;
+ }
+ ch->desc = (struct hdma_desc *)kmalloc(128,GFP_KERNEL);
+ if(!ch->desc){
+ printk("dma channel request desc failed! %s %d\n",__FILE__,__LINE__);
+ goto error_exit;
+ }
+ desc = ch->desc;
+ burst_len = get_max_tsz(burst_len,&burst_bits);
+ desc->dcm = DCM_SAI | DCM_DAI | burst_bits;
+ desc->dsa = ch->pfrom;
+ desc->dta = ch->pto;
+ desc->dtc = ch->test_len / burst_len;
+ desc->drt = 8;
+ dma_cache_sync(NULL,desc,128,DMA_TO_DEVICE);
+ }
+
+ list_add_tail(&ch->list,&cd->dma_top);
+ return ch;
+error_exit:
+ if(ch->desc)
+ kfree(ch->desc);
+ if(ch->from)
+ kfree(ch->from);
+ if(ch->to)
+ kfree(ch->to);
+ vfree(ch);
+ return 0;
+}
+static void free_dma_channel(struct dma_channel *dc)
+{
+ if(dc->desc)
+ kfree(dc->desc);
+ if(dc->from)
+ kfree(dc->from);
+ if(dc->to)
+ kfree(dc->to);
+ vfree(dc);
+}
+static int __init cpu_dma_test_init(void)
+{
+ struct dma_channel *dc;
+ INIT_LIST_HEAD(&cpu_dma.dma_top);
+ cpu_dma.multithread = multithread_test_init("cpu_dma_test",2);
+ if(cpu_dma.multithread){
+ dc = new_dma_channel(&cpu_dma);
+ if(dc)
+ multithread_test_add_func(cpu_dma.multithread,"cpu-dma-nowait",cpu_dma_test_func_nowait,(void*)dc);
+
+ dc = new_dma_channel(&cpu_dma);
+ if(dc)
+ multithread_test_add_func(cpu_dma.multithread,"cpu-dma-wait",cpu_dma_test_func_wait,(void*)dc);
+
+ printk("cpu_dma_test register ok.\n");
+ }
+ return 0;
+}
+static void __exit cpu_dma_test_deinit(void)
+{
+ struct dma_channel *dc,*_dc;
+
+ list_for_each_entry_safe(dc, _dc, &cpu_dma.dma_top, list) {
+ list_del(&dc->list);
+ free_dma_channel(dc);
+ }
+ multithread_test_deinit(cpu_dma.multithread);
+}
+late_initcall(cpu_dma_test_init);
+module_exit(cpu_dma_test_deinit);

View File

@ -0,0 +1,79 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/cpu_spinlock_test.c b/arch/mips/xburst2/common/cpu_ddr_test/cpu_spinlock_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/cpu_spinlock_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/cpu_spinlock_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,75 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/vmalloc.h>
+#include <linux/list.h>
+
+#include "multithread_test.h"
+
+#define PALLADIUM_TRIGER_2() do {\
+ volatile unsigned int *a; \
+ a = (unsigned int *)0xAFFFFFFC; \
+ *a = *a; \
+ } while(0)
+
+struct cpu_spinlock_test {
+ void* multithread;
+ spinlock_t lock;
+ unsigned int cnt;
+ atomic_t acnt;
+} cpu_spinlock;
+
+
+static int cpu_spinlock_test_func(void * param)
+{
+ struct cpu_spinlock_test *p = (struct cpu_spinlock_test *)param;
+ unsigned int c;
+
+ spin_lock(&p->lock);
+
+#if 1
+ c = atomic_read(&p->acnt);
+ if(p->cnt != c) {
+ // PALLADIUM_TRIGER_2();
+ printk("========= spinlock cnt %x != atomic cnt, %x\n",p->cnt, c);
+ return -1;
+ }
+#endif
+ p->cnt++;
+
+ udelay(10);
+
+ atomic_inc(&p->acnt);
+ spin_unlock(&p->lock);
+
+#ifdef CONFIG_FPGA_TEST
+ mdelay(100);
+#endif
+ return 0;
+}
+
+static int __init cpu_spinlock_test_init(void)
+{
+ cpu_spinlock.multithread = multithread_test_init("cpu_spinlock_test",1);
+ spin_lock_init(&cpu_spinlock.lock);
+
+ if(cpu_spinlock.multithread){
+ multithread_test_add_func(cpu_spinlock.multithread,"cpu_spinlock_test",cpu_spinlock_test_func,(void*)&cpu_spinlock);
+ }
+ return 0;
+}
+static void __exit cpu_spinlock_test_deinit(void)
+{
+}
+
+late_initcall(cpu_spinlock_test_init);
+module_exit(cpu_spinlock_test_deinit);

View File

@ -0,0 +1,20 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/cpu_tcsm.h b/arch/mips/xburst2/common/cpu_ddr_test/cpu_tcsm.h
--- a/arch/mips/xburst2/common/cpu_ddr_test/cpu_tcsm.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/cpu_tcsm.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,16 @@
+#ifndef __CPU_TCSM_H__
+#define __CPU_TCSM_H__
+
+#define CPU_TCSM_BASE (0xb2400000)
+
+#define CPU_TCSM_BANK0 CPU_TCSM_BASE
+#define CPU_TCSM_BANK0_SIZE (4096)
+#define CPU_TCSM_FUNC CPU_TCSM_BANK0
+#define CPU_TCSM_FUNC_SIZE 2048
+#define CPU_TCSM_DATA (CPU_TCSM_FUNC + CPU_TCSM_FUNC_SIZE)
+#define CPU_TCSM_SP (CPU_TCSM_BANK0 + CPU_TCSM_BANK0_SIZE)
+
+#define CPU_TCSM_DDR_CALIB (CPU_TCSM_DATA)
+#define CPU_TCSM_CPU_WAIT_STATUS (CPU_TCSM_DDR_CALIB + 0x4)
+
+#endif /* __CPU_TCSM_H__ */

View File

@ -0,0 +1,204 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/cpu_watch_test.c b/arch/mips/xburst2/common/cpu_ddr_test/cpu_watch_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/cpu_watch_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/cpu_watch_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,200 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+#include <linux/syscore_ops.h>
+#include <linux/debugfs.h>
+#include <linux/kthread.h>
+
+#include <linux/mfd/core.h>
+//#include <mach/jz_tcu.h>
+
+#include <asm/r4kcache.h>
+#include <asm/mmu_context.h>
+
+
+#include"../../../../../include/linux/mfd/ingenic-tcu.h"
+
+struct watch_struct
+{
+ struct task_struct *child;
+ unsigned int watchhi;
+ unsigned int watchlo;
+
+ /* debugfs */
+ struct dentry *root;
+};
+
+struct watch_struct _cwt; /* cpu watch test */
+struct watch_struct *cwt; /* cpu watch test */
+
+
+static struct task_struct *trace_get_task_struct(pid_t pid)
+{
+ struct task_struct *child;
+
+ rcu_read_lock();
+ child = find_task_by_vpid(pid);
+ if (child)
+ get_task_struct(child);
+ rcu_read_unlock();
+
+ if (!child)
+ return ERR_PTR(-ESRCH);
+ return child;
+}
+char g_buffer[256];
+
+static ssize_t cpu_watch_read_start(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf = g_buffer;
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+
+}
+
+static void local_set_watch(void *args) {
+ struct watch_struct *watch = (struct watch_struct *)args;
+ unsigned int cpu = smp_processor_id();
+ unsigned int hi = 0;
+// struct mips3264_watch_reg_state *watches =
+ //&watch->child->thread.watch.mips3264;
+
+ if(watch->watchhi & 0x40000000)
+ hi = watch->watchhi;
+ else
+ hi = (watch->watchhi & 0xffff) | (cpu_asid(cpu,watch->child->mm) << 16);
+ if(watch->watchlo == 0) hi = 0;
+// watches->watchlo[0][cpu] = watch->watchlo;
+// watches->watchhi[0][cpu] = hi;
+
+ printk("watchlo: %x, watchhi: %x, cpu; %d\n", watch->watchlo, hi, cpu);
+ write_c0_watchlo0(watch->watchlo);
+ write_c0_watchhi0(hi);
+
+}
+static inline void jz_on_each_cpu(void (*func) (void *info), void *info)
+{
+ preempt_disable();
+ smp_call_function(func, info, 1);
+ func(info);
+ preempt_enable();
+}
+
+static ssize_t cpu_watch_write_start(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char s[20];
+ char *s1,*s2;
+ pid_t pid;
+ unsigned int hi;
+ unsigned int lo;
+ struct task_struct *child = NULL;
+ struct watch_struct watch;
+// struct mips3264_watch_reg_state *watches;
+
+ copy_from_user(g_buffer,user_buf,count);
+
+ g_buffer[count] = 0;
+ printk("%s\n",g_buffer);
+ s1 = g_buffer;
+ s2 = strchr(s1,':');
+ printk("s1 = %p s2 = %p\n",s1,s2);
+ if(!s2 || count == 0) {
+ pid = simple_strtoul(s1,0,0);
+ child = trace_get_task_struct(pid);
+ watch.child = child;
+ watch.watchlo = 0;
+ watch.watchhi = 0;
+ jz_on_each_cpu(local_set_watch,&watch);
+ //watches = &child->thread.watch.mips3264;
+ //watches->trace_type = 0;
+ clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
+
+ return count;
+ }
+
+ memcpy(s,s1,s2 - s1);
+ s[s2 - s1] = 0;
+ pid = simple_strtoul(s,0,0);
+
+ s1 = s2 + 1;
+ s2 = strchr(s1,':');
+ printk("s1 = %p s2 = %p\n",s1,s2);
+ memcpy(s,s1,s2 - s1);
+ s[s2 - s1] = 0;
+ lo = simple_strtoul(s,0,0);
+
+ s1 = s2 + 1;
+ hi = simple_strtoul(s1,0,0);
+ printk("pid = %d lo = 0x%08x hi = %d\n",pid,lo,hi);
+ child = trace_get_task_struct(pid);
+ printk("child = %p\n",child);
+ //child->thread.watch.mips3264.watchlo[0] = lo;
+ //child->thread.watch.mips3264.watchhi[0] = hi;
+ watch.child = child;
+ watch.watchlo = lo;
+ watch.watchhi = hi;
+ jz_on_each_cpu(local_set_watch,&watch);
+ //watches = &child->thread.watch.mips3264;
+ //watches->trace_type = 1;
+
+ return count;
+}
+
+static const struct file_operations cpu_watch_start_ops = {
+ .read = cpu_watch_read_start,
+ .write = cpu_watch_write_start,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+
+static int create_debugfs(struct watch_struct *cwt)
+{
+ struct dentry *d;
+ d = debugfs_create_dir("cpu_watch", NULL);
+ if(IS_ERR(d)) {
+ pr_err("Create debugfs for tcu test failed!\n");
+ return PTR_ERR(d);
+ }
+
+ cwt->root = d;
+
+ d = debugfs_create_file("start", S_IWUSR| S_IRUGO, cwt->root, cwt, &cpu_watch_start_ops);
+ if(IS_ERR_OR_NULL(d)) {
+ pr_err("Debugfs create failed!\n");
+ goto err_node;
+ }
+
+ return 0;
+
+err_node:
+ debugfs_remove_recursive(cwt->root);
+ return -1;
+}
+
+static int __init cpu_watch_test_init(void)
+{
+ int ret;
+
+ cwt = &_cwt;
+
+ ret = create_debugfs(cwt);
+
+ printk("cpu watch test probe ok!\n");
+ return 0;
+}
+
+static void __exit cpu_watch_test_deinit(void)
+{
+
+}
+
+late_initcall(cpu_watch_test_init);
+module_exit(cpu_watch_test_deinit);

View File

@ -0,0 +1,475 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/ddr_bandwidth_monitor.c b/arch/mips/xburst2/common/cpu_ddr_test/ddr_bandwidth_monitor.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/ddr_bandwidth_monitor.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/ddr_bandwidth_monitor.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,471 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#define DDR_MONITOR_BASE 0x134F0000
+#define DDR_DYNAMIC_CLK 0x13012068
+#define DDR_DWCFG 0x13012000
+#define DDR_CMONC0 0x13012050
+
+#define DB_MONITOR_BASE_OFF 0x88// DDR bandwidth monitor base offset address.
+
+#define MAX_SUPPORTED_MONITORS 4
+
+struct dbw_channel_reg{
+ volatile unsigned int write;
+ unsigned int reserve1;
+ volatile unsigned int read;
+ unsigned int reserve2;
+};
+struct dbw_reg{
+ volatile unsigned int dbwcfg;
+ unsigned int reserve;
+ volatile unsigned int period;
+ unsigned int reserver;
+ struct dbw_channel_reg chan[4];
+};
+
+
+#define GMAC_MSC_CHANNEL 0 //DDR ch0
+#define VPU_CHANNEL 1 //DDR ch1
+#define DPU_VPU_CHANNEL 3 //DDR ch3
+#define AHB2_CHANNEL 5 //DDR ch5
+#define CPU_CHANNEL 6 //DDR ch6
+
+struct ddr_mon_chan {
+ int chn;
+ const char *desc;
+};
+
+static struct ddr_mon_chan mon_chans[] = {
+ {0, "gmac&msc"},
+ {1, "vpu&isp"},
+ {3, "dpu&cim"},
+ {5, "ahb2&audio&apb"},
+ {6, "cpu"}
+};
+
+static unsigned int default_monitor_chn[MAX_SUPPORTED_MONITORS] = {0, 3, 5, 6};
+
+struct ddr_dbw_monitor {
+ struct ddr_mon_chan *ch;
+ unsigned int read;
+ unsigned int write;
+};
+
+
+static inline struct ddr_mon_chan* get_mon_chn(int chn)
+{
+ int i;
+
+ for(i = 0; i < ARRAY_SIZE(mon_chans); i++) {
+ if(mon_chans[i].chn == chn)
+ return &mon_chans[i];
+ }
+
+ printk("Error find mon_chn, chn: %d\n", chn);
+ return NULL;
+}
+
+static int set_mon_chn(struct ddr_dbw_monitor *monitors, int chn)
+{
+ struct ddr_mon_chan *mon_chn = get_mon_chn(chn);
+
+ printk("set _mon_chn :%d\n", chn);
+
+ if(!mon_chn) {
+ return -EINVAL;
+ }
+
+ monitors->ch = mon_chn;
+
+ return 0;
+}
+
+
+struct ddr_statistics{
+ struct dentry *root;
+ unsigned int periods;
+ unsigned int output;
+ int run;
+
+ unsigned int ahb2_read_rate;
+ unsigned int ahb2_write_rate;
+ unsigned int cpu_read_rate;
+ unsigned int cpu_write_rate;
+
+ /* 1 package = 4 * 32 = 8 * 16 */
+ unsigned int pkg_cnt_to_cycle;
+
+ int poll_periods_ms;
+ struct dbw_reg *reg;
+
+ struct ddr_dbw_monitor dbw_monitors[4];
+
+ struct mutex lock;
+ struct timer_list timer;
+};
+static struct ddr_statistics ddr_statistics = {
+ .periods = 25 * 1000 * 1000,
+ .run = 0,
+ .poll_periods_ms = 40,
+ .output = 1,
+};
+#define BW_DONE (1 << 3)
+#define BW_INT_EN (1 << 2)
+#define BW_CLR (1 << 1)
+#define BW_EN (1 << 0)
+
+#define DDR_PACKAGE_TO_CYCLE 4
+static void ddr_stat_output(struct ddr_statistics *ddr)
+{
+ uint64_t period = (uint64_t)ddr->reg->period;
+#define occupancy_show(title,chn,id) do{ \
+ uint64_t w_occupancy = (uint64_t)ddr->dbw_monitors[id].write * ddr->pkg_cnt_to_cycle; \
+ uint64_t r_occupancy = (uint64_t)ddr->dbw_monitors[id].read * ddr->pkg_cnt_to_cycle; \
+ uint64_t d = 100000 * w_occupancy; \
+ uint64_t hi; \
+ do_div(d,period); \
+ hi = (uint32_t)d / 1000; \
+ printk("%s chn:%d write occupancy rate:%lld.%03lld%%\n",title,chn,hi,d - hi * 1000); \
+ d = 100000 * r_occupancy; \
+ do_div(d,period); \
+ hi = (uint32_t)d / 1000; \
+ printk("%s chn:%d read occupancy rate:%lld.%03lld%%\n",title,chn, hi,d - hi * 1000); \
+ }while(0)
+ occupancy_show(ddr->dbw_monitors[0].ch->desc, ddr->dbw_monitors[0].ch->chn, 0);
+ occupancy_show(ddr->dbw_monitors[1].ch->desc, ddr->dbw_monitors[1].ch->chn, 1);
+ occupancy_show(ddr->dbw_monitors[2].ch->desc, ddr->dbw_monitors[2].ch->chn, 2);
+ occupancy_show(ddr->dbw_monitors[3].ch->desc, ddr->dbw_monitors[3].ch->chn, 3);
+#undef occupancy_show
+}
+
+static struct ddr_dbw_monitor *get_dbw_monitor(struct ddr_statistics *ddr, int chn)
+{
+ struct ddr_dbw_monitor *m;
+ int i = 0;
+
+ for(i = 0; i < MAX_SUPPORTED_MONITORS; i++) {
+ m = &ddr->dbw_monitors[i];
+ if(m->ch->chn == chn)
+ return m;
+ }
+
+ return NULL;
+}
+
+static ssize_t ddr_read_run(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ddr_statistics *ddr = file->private_data;
+ char *buf;
+
+ mutex_lock(&ddr->lock);
+ if(ddr->reg->dbwcfg & BW_EN)
+ buf = "Runing\n";
+ else
+ buf = "Stop\n";
+ mutex_unlock(&ddr->lock);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t ddr_write_run(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ddr_statistics *ddr = file->private_data;
+ struct ddr_dbw_monitor *m;
+ char buf[16];
+ bool bv;
+ int ret = 0;
+ unsigned int val;
+ int i = 0;
+ if (copy_from_user(buf, user_buf, min(count, (sizeof(buf) - 1))))
+ return -EFAULT;
+
+ if (strtobool(buf, &bv) == 0) {
+ mutex_lock(&ddr->lock);
+
+ if(bv){
+ val = readl((void*)CKSEG1ADDR(DDR_DYNAMIC_CLK));
+ val &= ~(1 << 8);
+ writel(val,(void*)CKSEG1ADDR(DDR_DYNAMIC_CLK));
+
+ del_timer_sync(&ddr->timer);
+ if(ddr->reg->period != ddr->periods)
+ ddr->poll_periods_ms = 0;
+ ddr->run = 1;
+ ddr->reg->period = ddr->periods;
+ val = ddr->reg->period;
+
+ ddr->reg->dbwcfg = BW_EN | BW_CLR;
+ while((ddr->reg->dbwcfg & (BW_CLR | BW_EN)) != BW_EN);
+ printk("run!\n");
+ mod_timer(&ddr->timer,jiffies + msecs_to_jiffies(ddr->poll_periods_ms));
+ }else{
+
+ del_timer_sync(&ddr->timer);
+ ddr->run = 0;
+ for(i = 0; i < MAX_SUPPORTED_MONITORS; i++) {
+ ddr->dbw_monitors[i].write = ddr->reg->chan[i].write;
+ ddr->dbw_monitors[i].read = ddr->reg->chan[i].read;
+ }
+
+ if(ddr->output){
+ ddr_stat_output(ddr);
+ }
+
+ ddr->ahb2_write_rate = (m = get_dbw_monitor(ddr, AHB2_CHANNEL)) == NULL ? 0:m->write;
+ ddr->ahb2_read_rate = (m = get_dbw_monitor(ddr, AHB2_CHANNEL)) == NULL ? 0:m->read;
+ ddr->cpu_write_rate = (m = get_dbw_monitor(ddr, CPU_CHANNEL)) == NULL ? 0:m->write;
+ ddr->cpu_read_rate = (m = get_dbw_monitor(ddr, CPU_CHANNEL)) == NULL ? 0:m->read;
+
+
+ ddr->reg->dbwcfg = 0;
+ printk("stopping!\n");
+ }
+ mutex_unlock(&ddr->lock);
+ }
+
+ return ret ? ret : count;
+}
+
+static const struct file_operations ddr_run_fops = {
+ .read = ddr_read_run,
+ .write = ddr_write_run,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+static void ddr_stat_timer_handler(unsigned long data)
+{
+ struct ddr_statistics *ddr = (struct ddr_statistics *)data;
+ unsigned int dbwcfg = ddr->reg->dbwcfg;
+ struct ddr_dbw_monitor *m;
+ int i = 0;
+ if(dbwcfg & BW_DONE)
+ {
+ if(ddr->run){
+ for(i = 0; i < MAX_SUPPORTED_MONITORS; i++) {
+ ddr->dbw_monitors[i].write = ddr->reg->chan[i].write;
+ ddr->dbw_monitors[i].read = ddr->reg->chan[i].read;
+ }
+
+ if(ddr->output){
+ ddr_stat_output(ddr);
+ }
+ if(ddr->reg->dbwcfg != dbwcfg)
+ ddr->poll_periods_ms = 0;
+
+
+ ddr->ahb2_write_rate = (m = get_dbw_monitor(ddr, AHB2_CHANNEL)) == NULL ? 0:m->write;
+ ddr->ahb2_read_rate = (m = get_dbw_monitor(ddr, AHB2_CHANNEL)) == NULL ? 0:m->read;
+ ddr->cpu_write_rate = (m = get_dbw_monitor(ddr, CPU_CHANNEL)) == NULL ? 0:m->write;
+ ddr->cpu_read_rate = (m = get_dbw_monitor(ddr, CPU_CHANNEL)) == NULL ? 0:m->read;
+
+ dbwcfg |= BW_CLR;
+ ddr->reg->dbwcfg = dbwcfg;
+
+ while(ddr->reg->dbwcfg & BW_CLR);
+ mod_timer(&ddr->timer,jiffies + msecs_to_jiffies(ddr->poll_periods_ms));
+ }else{
+ ddr->reg->dbwcfg = 0;
+ }
+ } else {
+ mod_timer(&ddr->timer,jiffies + msecs_to_jiffies(10));
+ ddr->poll_periods_ms += 10;
+ }
+}
+
+static int dbw_monitors_init(struct ddr_statistics *ddr)
+{
+ unsigned int cmonc0;
+ int i;
+
+ for(i = 0; i < MAX_SUPPORTED_MONITORS; i++) {
+ ddr->dbw_monitors[i].ch = get_mon_chn(default_monitor_chn[i]);
+ }
+
+#if 0
+ ddr->dbw_monitors[0].ch = &mon_chans[0];
+ ddr->dbw_monitors[1].ch = &mon_chans[1];
+ ddr->dbw_monitors[2].ch = &mon_chans[2];
+ ddr->dbw_monitors[3].ch = &mon_chans[3];
+#endif
+ cmonc0 = readl((void *)CKSEG1ADDR(DDR_CMONC0));
+ /*cmonc0[15:4]*/
+ cmonc0 &= ~0xfff0;
+ cmonc0 |= (ddr->dbw_monitors[0].ch->chn << 13) \
+ | (ddr->dbw_monitors[1].ch->chn << 10) \
+ | (ddr->dbw_monitors[2].ch->chn << 7) \
+ | (ddr->dbw_monitors[3].ch->chn << 4);
+ writel(cmonc0, (void *)CKSEG1ADDR(DDR_CMONC0));
+
+ return 0;
+}
+static ssize_t ddr_read_monitors(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ddr_statistics *ddr = file->private_data;
+ struct ddr_dbw_monitor *m = NULL;
+ int i = 0;
+ int ret = 0;
+
+ unsigned char *buf = kzalloc(1024, GFP_KERNEL);
+ unsigned char *p = buf;
+
+ if(!buf) {
+ printk("Error alloc mem!\n");
+ return -ENOMEM;
+ }
+
+ for(i = 0; i < MAX_SUPPORTED_MONITORS; i++) {
+ m = &ddr->dbw_monitors[i];
+ ret = sprintf(p, "monitor:%d, chn:%d, desc:%s\n\t read:%d, write:%d\n",
+ i, m->ch->chn, m->ch->desc, m->read, m->write);
+ p += ret;
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t ddr_write_monitors(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+
+ struct ddr_statistics *ddr = file->private_data;
+ char buf[16];
+ int i = 0;
+ unsigned int val;
+ char *token, *cur = buf;
+ unsigned int cmonc0;
+
+ if (copy_from_user(buf, user_buf, min(count, (sizeof(buf) - 1))))
+ return -EFAULT;
+
+ for(i = 0; i < MAX_SUPPORTED_MONITORS; i++) {
+ token = strsep(&cur, ":");
+ if(!token) {
+ printk("Invalid monitor settings!\n");
+ return -EINVAL;
+ }
+ val = simple_strtoul(token, NULL, 10);
+
+ if(set_mon_chn(&ddr->dbw_monitors[i], val) < 0) {
+ return -EINVAL;
+ }
+ }
+
+ cmonc0 = readl((void *)CKSEG1ADDR(DDR_CMONC0));
+ /*cmonc0[15:4]*/
+ cmonc0 &= ~0xfff0;
+ cmonc0 |= (ddr->dbw_monitors[0].ch->chn << 13) \
+ | (ddr->dbw_monitors[1].ch->chn << 10) \
+ | (ddr->dbw_monitors[2].ch->chn << 7) \
+ | (ddr->dbw_monitors[3].ch->chn << 4);
+ writel(cmonc0, (void *)CKSEG1ADDR(DDR_CMONC0));
+
+ return count;
+}
+
+static const struct file_operations ddr_monitors_fops = {
+ .read = ddr_read_monitors,
+ .write = ddr_write_monitors,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+
+
+static int __init ddr_stat_init(void)
+{
+ struct dentry * d;
+ struct ddr_statistics *ddr = &ddr_statistics;
+
+ d = debugfs_create_dir("ddr", NULL);
+ if (IS_ERR(d)){
+ pr_err("create debugfs for ddr failed.\n");
+ return PTR_ERR(d);
+ }
+
+
+ ddr->root = d;
+
+ d = debugfs_create_file("monitors", S_IWUSR | S_IRUGO, ddr->root,
+ ddr, &ddr_monitors_fops);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+ d = debugfs_create_u32("periods", S_IWUSR | S_IRUGO, ddr->root,
+ (u32 *)&ddr->periods);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+ d = debugfs_create_u32("output", S_IWUSR | S_IRUGO, ddr->root,
+ (u32 *)&ddr->output);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+ d = debugfs_create_u32("ahb2_read_rate", S_IWUSR | S_IRUGO, ddr->root,
+ (u32 *)&ddr->ahb2_read_rate);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+ d = debugfs_create_u32("ahb2_write_rate", S_IWUSR | S_IRUGO, ddr->root,
+ (u32 *)&ddr->ahb2_write_rate);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+ d = debugfs_create_u32("cpu_read_rate", S_IWUSR | S_IRUGO, ddr->root,
+ (u32 *)&ddr->cpu_read_rate);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+ d = debugfs_create_u32("cpu_write_rate", S_IWUSR | S_IRUGO, ddr->root,
+ (u32 *)&ddr->cpu_write_rate);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+
+ d = debugfs_create_file("run", S_IWUSR | S_IRUGO, ddr->root,
+ ddr, &ddr_run_fops);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+ mutex_init(&ddr->lock);
+
+ ddr->reg = ioremap(DDR_MONITOR_BASE + DB_MONITOR_BASE_OFF,sizeof(struct dbw_reg));
+
+ if(readl((void *)CKSEG1ADDR(DDR_DWCFG)) & 1) {
+ /* 32bit ddr*/
+ ddr->pkg_cnt_to_cycle = 4;
+
+ } else {
+ ddr->pkg_cnt_to_cycle = 8;
+
+ }
+
+ dbw_monitors_init(ddr);
+
+
+
+ init_timer(&ddr->timer);
+ ddr->timer.function = ddr_stat_timer_handler;
+ ddr->timer.data = (unsigned long)ddr;
+
+ return 0;
+err_node:
+ debugfs_remove_recursive(ddr->root);
+
+ return -1;
+}
+
+static void __exit ddr_stat_deinit(void)
+{
+ struct ddr_statistics *ddr = &ddr_statistics;
+ debugfs_remove_recursive(ddr->root);
+}
+
+late_initcall(ddr_stat_init);
+module_exit(ddr_stat_deinit);

View File

@ -0,0 +1,527 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/ddr_change_freq.c b/arch/mips/xburst2/common/cpu_ddr_test/ddr_change_freq.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/ddr_change_freq.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/ddr_change_freq.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,523 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <asm/idle.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheops.h>
+#include <linux/interrupt.h>
+
+#include <soc/ddr.h>
+
+#include <ccu.h>
+#include "cpu_tcsm.h"
+
+/* #define ALL_OTHER_CPU_WAITE */
+struct ddr_calib_value {
+ unsigned int rate;
+ unsigned int refcnt;
+ unsigned char bypass_al;
+ unsigned char bypass_ah;
+};
+
+typedef void (*ddr_change_code)(unsigned int, unsigned int,
+ unsigned int,unsigned int);
+
+struct ddr_cfreq {
+ struct dentry *root;
+ spinlock_t lock;
+ struct timer_list timer;
+ struct clk *clk_ddr;
+
+ unsigned int ddr_cur_rate;
+ ddr_change_code tcsm_change_ddr_rate;
+};
+
+struct ddr_cfreq ddr_cfreq;
+
+#define CPM_DDRCDR (0xb000002c)
+
+static ssize_t ddr_read_rate(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[4];
+ int pos = 0;
+
+ pos = scnprintf(buf, 4, "%d\n", ddr_cfreq.ddr_cur_rate);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static unsigned int get_ddr_parent_rate(void)
+{
+ unsigned int val;
+ struct clk *pll;
+ unsigned int pll_rate;
+
+ val = REG32(CPM_DDRCDR);
+ switch(val >> 30) {
+ case 1:
+ pll = clk_get(NULL, "apll");
+ break;
+ case 2:
+ pll = clk_get(NULL, "mpll");
+ break;
+ default :
+ printk("not support\n");
+ return 0;
+ }
+
+ pll_rate = clk_get_rate(pll);
+ return pll_rate;
+}
+static unsigned int get_ddr_rate(void)
+{
+ unsigned int pll_rate, ddr_rate;
+ unsigned int val;
+
+ val = REG32(CPM_DDRCDR);
+
+ pll_rate = get_ddr_parent_rate();
+ ddr_rate = pll_rate / ((val & 0xf) + 1);
+ return ddr_rate;
+}
+
+static unsigned int pp_mask, ost_mask, mailbox_mask;
+#ifdef ALL_OTHER_CPU_WAITE
+static unsigned int pp_pend,ost_pend, mailbox_pend;
+#endif
+
+static inline void unmask_others_cpu(void);
+static void change_ddr_rate(unsigned char bal, unsigned char bah, unsigned int refcnt, int div)
+{
+ unsigned int val, cur_div;//, div;
+ unsigned int hregpro, pregpro;
+ unsigned int autoself_en;
+#ifdef ALL_OTHER_CPU_WAITE
+ unsigned int wait_cpu;
+ unsigned int timeout = 10000;
+
+ REG32(0xb0032000) = '0';
+
+ div = change_div & 0xffff;
+ wait_cpu = (change_div >> 16);
+ while(!REG32(0xb2407ff8) && timeout --)
+ ;
+ if(!timeout)
+ return;
+#endif
+ hregpro = ddr_readl(DDRC_HREGPRO);
+ pregpro = ddr_readl(DDRC_PREGPRO);
+ autoself_en = ddr_readl(DDRC_AUTOSR_EN);
+
+ ddr_writel(0, DDRC_HREGPRO);
+ ddr_writel(0, DDRC_PREGPRO);
+ ddr_writel(0, DDRC_AUTOSR_EN);
+
+ // Disable DFI lowpower handshake
+ /* val = ddr_readl(DDRC_DLP); */
+ /* val &= ~(1); */
+ /* ddr_writel(val, DDRC_DLP); */
+
+ val = REG32(CPM_DDRCDR);
+ cur_div = (val & 0xf);
+
+ if(cur_div > div) {
+ val = ddr_readl(DDRC_REFCNT);
+ val &= ~(0x3ffff << 8 | 0xe);
+ val |= refcnt;
+ ddr_writel(val, DDRC_REFCNT);
+ }
+ /**
+ * don't use AHB0/2 APB BUS before freq exit.
+ */
+ /**
+ * Set !change_en and ce
+ */
+ val = REG32(CPM_DDRCDR);
+ val |= ((1 << 29) | (1 << 25));
+ REG32(CPM_DDRCDR) = val;
+ /* while((REG32(CPM_DDRCDR) & (1 << 24))); */
+
+ /**
+ * Set clock divider
+ */
+ val = REG32(CPM_DDRCDR);
+ val &= ~(0xf);
+ val |= div;
+ REG32(CPM_DDRCDR) = val;
+// while((REG32(CPM_DDRCDR) & (1 << 28)));
+ /**
+ * Polling PHY_FREQ_DONE
+ */
+ while((ddr_readl(DDRC_DWSTATUS) & (1 << 3 | 1 << 1)) != 0xa)
+ ;
+
+ ddr_writel(DDRP_TRAINING_CTRL_DSCSE_BP, DDRP_INNOPHY_TRAINING_CTRL);
+ ddr_writel(bal, DDRP_INNOPHY_CALIB_BYPASS_AL);
+ ddr_writel(bah, DDRP_INNOPHY_CALIB_BYPASS_AH);
+
+ /**
+ * Set Controller Freq Exit
+ */
+ val = ddr_readl(DDRC_DWCFG);
+ val |= (1 << 2);
+ ddr_writel(val, DDRC_DWCFG);
+
+ /**
+ * Clear Controller Freq Exit
+ */
+ val = ddr_readl(DDRC_DWCFG);
+ val &= ~(1 << 2);
+ ddr_writel(val, DDRC_DWCFG);
+
+ /**
+ * clear change_en and ce
+ */
+ val = REG32(CPM_DDRCDR);
+ val &= ~((1 << 29) | (1 << 25));
+ REG32(CPM_DDRCDR) = val;
+
+ unmask_others_cpu();
+
+#ifdef ALL_OTHER_CPU_WAITE
+ if(ost_pend)
+ set_ccu_oipr(get_ccu_oipr() | (1 << wait_cpu));
+ if(pp_pend)
+ set_ccu_pipr(get_ccu_pipr() | (1 << wait_cpu));
+ if(mailbox_pend)
+ set_ccu_mipr(get_ccu_mipr() | (1 << wait_cpu));
+
+ if(ost_mask)
+ set_ccu_oimr(get_ccu_oimr() | (1 << wait_cpu));
+ if(pp_mask)
+ set_ccu_pimr(get_ccu_pimr() | (1 << wait_cpu));
+ if(mailbox_mask)
+ set_ccu_mimr(get_ccu_mimr() | (1 << wait_cpu));
+ /* REG32(0xb2407ff8) = 0; */
+#endif
+
+ if(cur_div < div) {
+ val = ddr_readl(DDRC_REFCNT);
+ val &= ~(0x3ffff << 8 | 0xe);
+ val |= refcnt;
+ ddr_writel(val, DDRC_REFCNT);
+ }
+
+ if(autoself_en)
+ ddr_writel(1, DDRC_AUTOSR_EN);
+ if(hregpro & (1 << 1))
+ ddr_writel(1, DDRC_HREGPRO);
+ if(pregpro & (1 << 1))
+ ddr_writel(1, DDRC_PREGPRO);
+}
+
+#define __read_32bit_register() \
+ ({ int __res; \
+ __asm__ __volatile__( \
+ "move \t %0, $29\n\t" \
+ : "=r" (__res)); \
+ __res; \
+ })
+
+#define __write_32bit_register(value) \
+ do { \
+ __asm__ __volatile__( \
+ "move \t $29, %0\n\t" \
+ : : "Jr" ((unsigned int)(value))); \
+ } while (0)
+
+#define read_sp_register() __read_32bit_register()
+#define write_sp_register(val) __write_32bit_register(val)
+static unsigned int change_count;
+static int try_and_lock_ccu(unsigned int cpu)
+{
+ int timeout = 1000;
+ unsigned int cslr;
+
+ do {
+ set_ccu_csar(cpu);
+ cslr = get_ccu_cslr();
+ if((cslr & 1 << 31) && ((cslr & ((1 << CONFIG_NR_CPUS) -1)) == cpu))
+ break;
+ } while(timeout --);
+ if(timeout < 0)
+ return -1;
+ return 0;
+}
+static void unlock_ccu(void)
+{
+ set_ccu_cslr(0);
+}
+static int mask_and_wait_others_cpu(unsigned int cur_cpu)
+{
+ unsigned int pp_mval, mb_mval, ost_mval;
+ unsigned int max_cpu_num = CONFIG_NR_CPUS;
+ unsigned int mask_cpus = ((1 << max_cpu_num) - 1);
+ unsigned int mask_other_cpus = (mask_cpus & (~(1 << cur_cpu)));
+ int timeout, ret = 0;
+
+ pp_mval = get_ccu_pimr();
+ mb_mval = get_ccu_mimr();
+ ost_mval = get_ccu_oimr();
+
+ pp_mask = pp_mval & (mask_cpus);
+ mailbox_mask = mb_mval & (mask_cpus);
+ ost_mask = ost_mval & (mask_cpus);
+
+ try_and_lock_ccu(cur_cpu);
+ if(ret < 0) {
+ printk("try to lock ccu failed\n");
+ return ret;
+ }
+
+ set_ccu_pimr(0);
+ set_ccu_mimr(0);
+ set_ccu_oimr(0);
+
+ timeout = 100000;
+ while(((get_ccu_cssr() & mask_other_cpus) != mask_other_cpus)
+ && timeout--);
+
+ if(!get_ccu_cssr() && timeout >= 0) {
+ printk("ERROR:get_ccu_cssr() %x timeout %d mask_other_cpus %x\n", get_ccu_cssr(), timeout, mask_other_cpus);
+ printk("ERROR:get_ccu_cssr() %x timeout %d mask_other_cpus %x\n", get_ccu_cssr(), timeout, mask_other_cpus);
+ printk("ERROR:get_ccu_cssr() %x timeout %d mask_other_cpus %x\n", get_ccu_cssr(), timeout, mask_other_cpus);
+ printk("ERROR:get_ccu_cssr() %x timeout %d mask_other_cpus %x\n", get_ccu_cssr(), timeout, mask_other_cpus);
+ printk("ERROR:get_ccu_cssr() %x timeout %d mask_other_cpus %x\n", get_ccu_cssr(), timeout, mask_other_cpus);
+ printk("get_ccu_cssr() %x timeout %d mask_other_cpus %x\n", get_ccu_cssr(), timeout, mask_other_cpus);
+ printk("SMP: ------------------wakeup--------CPU%d: cause %x\n", cur_cpu, read_c0_cause());
+ printk("SMP: ------------------wakeup--------CPU%d: pp pending %x\n", cur_cpu, REG32(0xb2200100));
+ printk("SMP: ------------------wakeup--------CPU%d: ost pending %x\n", cur_cpu, REG32(0xb2200180));
+ printk("SMP: ------------------wakeup--------CPU%d: mailbox pending %x\n", cur_cpu, REG32(0xb2200140));
+
+ printk("SMP: ------------------wakeup--------CPU%d: pp mask %x\n", cur_cpu, get_ccu_pimr());
+ printk("SMP: ------------------wakeup--------CPU%d: mailbox mask %x\n", cur_cpu, get_ccu_mimr());
+ printk("SMP: ------------------wakeup--------CPU%d: os mask %x\n", cur_cpu, get_ccu_oimr());
+ while(1);
+ }
+
+ if(timeout < 0) {
+ set_ccu_pimr(pp_mask);
+ set_ccu_mimr(mailbox_mask);
+ set_ccu_oimr(ost_mask);
+ ret = -1;
+ }
+ unlock_ccu();
+
+ return ret;
+}
+static inline void unmask_others_cpu(void)
+{
+ /* try_and_lock_ccu(cur_cpu); */
+ /* if(ret < 0) { */
+ /* printk("try to lock ccu failed\n"); */
+ /* return ret; */
+ /* } */
+ set_ccu_pimr(pp_mask);
+ set_ccu_mimr(mailbox_mask);
+ set_ccu_oimr(ost_mask);
+ /* unlock_ccu(); */
+}
+#ifdef ALL_OTHER_CPU_WAITE
+static void disable_interrupt(void *args)
+{
+ unsigned int cpu = smp_processor_id();
+ printk("SMP: --------------------------CPU%d is offline\n", cpu);
+
+ if(cpu != *(unsigned int *)args) {
+ unsigned int pp_mval, mb_mval, ost_mval;
+ unsigned int pp_pval, mb_pval, ost_pval;
+ pp_mval = get_ccu_pimr();
+ mb_mval = get_ccu_mimr();
+ ost_mval = get_ccu_oimr();
+
+ pp_mask = pp_mval & (1 << cpu);
+ mailbox_mask = mb_mval & (1 << cpu);
+ ost_mask = ost_mval & (1 << cpu);
+
+ set_ccu_pimr(pp_mval & (~(1 << cpu)));
+ set_ccu_mimr(mb_mval & (~(1 << cpu)));
+ set_ccu_oimr(ost_mval & (~(1 << cpu)));
+
+ pp_pval = get_ccu_pipr();
+ mb_pval = get_ccu_mipr();
+ ost_pval = get_ccu_oipr();
+
+ pp_pend = pp_pval & (1 << cpu);
+ mailbox_pend = mb_pval & (1 << cpu);
+ ost_pend = ost_pval & (1 << cpu);
+
+ set_ccu_pipr(pp_pval & (~(1 << cpu)));
+ set_ccu_mipr(mb_pval & (~(1 << cpu)));
+ set_ccu_oipr(ost_pval & (~(1 << cpu)));
+ }
+
+ REG32(0xb2407ff8) = 0xa5a5a5a5;
+ __asm__ __volatile__ ("wait \n\t");
+
+ printk("SMP: ------------------wakeup--------CPU%d: cause %x\n", cpu, read_c0_cause());
+ printk("SMP: ------------------wakeup--------CPU%d: pp pending %x\n", cpu, REG32(0xb2200100));
+ printk("SMP: ------------------wakeup--------CPU%d: ost pending %x\n", cpu, REG32(0xb2200180));
+ printk("SMP: ------------------wakeup--------CPU%d: mailbox pending %x\n", cpu, REG32(0xb2200140));
+}
+#endif
+
+static ssize_t ddr_write_rate(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[16];
+ unsigned int change_rate;
+ unsigned long flags;
+ unsigned int cpu = smp_processor_id();
+ unsigned int sp, change_div;
+ int ret;
+ struct ddr_calib_value *dcv, *curdcv;
+
+ dcv = (struct ddr_calib_value *)(CPU_TCSM_DDR_CALIB);
+
+ if (copy_from_user(buf, user_buf, min(count, (sizeof(buf) - 1))))
+ return -EFAULT;
+
+ change_rate = simple_strtoul(buf, NULL, 10) * 1000000;
+ printk("change_rate %d-----------------\n", change_rate);
+ if(change_rate == ddr_cfreq.ddr_cur_rate) {
+ printk("change rate equl current rate\n");
+ return count;
+ }
+
+ change_div = get_ddr_parent_rate() / change_rate - 1;
+ if(dcv[change_div].rate != change_rate) {
+ int i;
+ printk("rate %d not support %d\n", change_rate, dcv[change_div].rate);
+ for(i = 0; i< 6; i ++)
+ printk("div %d, rate %d\n", i, dcv[i].rate);
+ printk("change_div %d\n", change_div);
+ return count;
+ }
+ curdcv = &dcv[change_div];
+
+ change_count ++;
+ printk("------------cpu %d----------------%d------------------\n", cpu, change_count);
+
+#ifdef ALL_OTHER_CPU_WAITE
+ REG32(0xb2407ff8) = 0;
+ change_div |= ((cpu?0:1) << 16);
+// preempt_disable();
+ /* on_each_cpu(disable_interrupt, &cpu, 0); */
+ smp_call_function(disable_interrupt, &cpu, 0);
+#endif
+
+ spin_lock_irqsave(&ddr_cfreq.lock,flags);
+ ret = mask_and_wait_others_cpu(cpu);
+ if(ret < 0) {
+ printk("lock failed\n");
+ change_count --;
+ spin_unlock_irqrestore(&ddr_cfreq.lock,flags);
+ return ret;
+ }
+ sp = read_sp_register();
+ write_sp_register(CPU_TCSM_SP);
+ ddr_cfreq.tcsm_change_ddr_rate(curdcv->bypass_al,
+ curdcv->bypass_ah, curdcv->refcnt, change_div);
+ write_sp_register(sp);
+ spin_unlock_irqrestore(&ddr_cfreq.lock,flags);
+// preempt_enable();
+ printk("change succeed\n");
+
+ ddr_cfreq.ddr_cur_rate = get_ddr_rate();
+ clk_set_rate(ddr_cfreq.clk_ddr, ddr_cfreq.ddr_cur_rate);
+ /* ddr_cfreq.ddr_cur_rate = clk_get_rate(ddr_cfreq.clk_ddr); */
+ printk("clk_get_rate(ddr_cfreq.clk_ddr) %d\n", (unsigned int)clk_get_rate(ddr_cfreq.clk_ddr));
+
+ return count;
+}
+
+static const struct file_operations ddr_run_fops = {
+ .read = ddr_read_rate,
+ .write = ddr_write_rate,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+
+static void load_func_to_tcsm(unsigned int *tcsm_addr,unsigned int *f_addr,unsigned int size)
+{
+ unsigned int instr;
+ int offset;
+ int i;
+ for(i = 0;i < size / 4;i++) {
+ instr = f_addr[i];
+ if((instr >> 26) == 2){
+ offset = instr & 0x3ffffff;
+ offset = (offset << 2) - ((unsigned int)f_addr & 0xfffffff);
+ if(offset > 0) {
+ printk("f_addr[i]%x: %x--------------------------------------------------\n", (unsigned int)&f_addr[i], f_addr[i]);
+ offset = ((unsigned int)tcsm_addr & 0xfffffff) + offset;
+ /* offset = ((unsigned int)0xf4000000 & 0xfffffff) + offset; */
+ instr = (2 << 26) | (offset >> 2);
+ }
+ }
+ tcsm_addr[i] = instr;
+ }
+}
+
+static int __init ddr_init(void)
+{
+ struct dentry * d;
+ struct ddr_cfreq *cfreq = &ddr_cfreq;
+
+ cfreq->clk_ddr = clk_get(NULL, "div_ddr");
+ if(!cfreq->clk_ddr) {
+ printk("get ddr clk failed\n");
+ return -1;
+ }
+
+ cfreq->ddr_cur_rate = clk_get_rate(cfreq->clk_ddr);
+ {
+ unsigned int *tcsm_bank0 = (unsigned int *)CPU_TCSM_FUNC;
+ /* unsigned int *tcsm_bank0 = (unsigned int *)0xb3423000; */
+ unsigned int *func0 = (unsigned int *)change_ddr_rate;
+
+ load_func_to_tcsm(tcsm_bank0, func0, CPU_TCSM_FUNC_SIZE);
+ cfreq->tcsm_change_ddr_rate = (ddr_change_code)tcsm_bank0;
+ }
+
+
+ d = debugfs_create_dir("ddrfreq", NULL);
+ if (IS_ERR(d)){
+ pr_err("create debugfs for ddr failed.\n");
+ return PTR_ERR(d);
+ }
+ spin_lock_init(&cfreq->lock);
+
+ cfreq->root = d;
+ d = debugfs_create_u32("ddr_cur_rate", S_IWUSR | S_IRUGO, cfreq->root,
+ (u32 *)&cfreq->ddr_cur_rate);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+ d = debugfs_create_file("rate", S_IWUSR | S_IRUGO, cfreq->root,
+ cfreq, &ddr_run_fops);
+ if (IS_ERR_OR_NULL(d))
+ goto err_node;
+
+ return 0;
+err_node:
+ debugfs_remove_recursive(cfreq->root);
+
+ return -1;
+}
+
+static void __exit ddr_deinit(void)
+{
+ struct ddr_cfreq *cfreq = &ddr_cfreq;
+ debugfs_remove_recursive(cfreq->root);
+}
+
+late_initcall(ddr_init);
+module_exit(ddr_deinit);

View File

@ -0,0 +1,523 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/l2c_test.c b/arch/mips/xburst2/common/cpu_ddr_test/l2c_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/l2c_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/l2c_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,519 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+/**
+ 1. start address align: 0-63
+ 2. size align: 0-63
+ 3. max size: 512k
+ 4. invalid:
+ 5. writeback:
+ 6. blast:
+ 7. 8 thread.
+*/
+
+struct l2c_test_thread;
+typedef int (*TEST_FUNC)(struct l2c_test_thread *);
+struct l2c_test_thread{
+ struct list_head list;
+ struct task_struct *task;
+ TEST_FUNC test_func;
+ struct mutex *lock;
+ int id;
+ volatile int done;
+};
+#define TO_UNC(x) ((unsigned int)x | 0x20000000)
+//#define TO_UNC(x) ((unsigned int)x)
+
+#define L2C_SIZE (512 * 1024)
+#define L2C_LINESIZE (64)
+
+#define PALLADIUM_TRIGER() do{ \
+ void (*func)(void); \
+ func = (void(*)(void)) 0xbfc00000; \
+ func(); \
+ }while(0)
+
+#define info(x,y...) do{ \
+ printk(x,##y); \
+ }while(0)
+
+static __maybe_unused int writeback_align_address(struct l2c_test_thread *data)
+{
+ unsigned char *src;
+ unsigned char *src_org;
+ unsigned char *p;
+ unsigned char *unc_p;
+ int i,j;
+ src_org = (unsigned char*)kmalloc(L2C_LINESIZE * 4,GFP_KERNEL);
+
+ if(IS_ERR_OR_NULL(src_org)){
+ src = 0;
+ info("kmalloc error!\n");
+ }else{
+ src = src_org + L2C_LINESIZE;
+ info("%s test addr: %p\n",__func__,src);
+ for(j = 0;j<L2C_LINESIZE;j++) {
+ for(i = 0;i<L2C_LINESIZE * 2;i++){
+ src[i] = i & 255;
+ }
+
+ dma_cache_sync(NULL,&src[j],L2C_LINESIZE,DMA_TO_DEVICE);
+ p = src;
+ unc_p = (unsigned char*)TO_UNC(p);
+ //msleep(1);
+ for(i = 0;i<L2C_LINESIZE * 2;i++){
+ if(p >= &src[j] && p < (&src[j] + L2C_LINESIZE)){
+ if(*unc_p != (i & 255)){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,i & 255,*(unc_p));
+ return -1;
+ }
+ }else{
+ if(*p != (i & 255)){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,i & 255,*(p));
+ return -1;
+ }
+ }
+ p++;
+ unc_p++;
+ }
+ for(i = 0;i<L2C_LINESIZE * 2;i++){
+ src[i] = i & 255;
+ }
+ }
+ }
+ if(src_org)
+ kfree(src_org);
+ return 0;
+}
+
+static __maybe_unused int writeback_align_size(struct l2c_test_thread *data)
+{
+ unsigned char *src;
+ unsigned char *src_org;
+ unsigned char *p;
+ unsigned char *unc_p;
+ int i,j;
+ src_org = (unsigned char*)kmalloc(L2C_LINESIZE * 4,GFP_KERNEL);
+ if(IS_ERR_OR_NULL(src_org)){
+ src = 0;
+ info("kmalloc error!\n");
+ }else{
+ src = src_org + L2C_LINESIZE;
+ info("%s test addr: %p\n",__func__,src);
+ for(j = 0;j<L2C_LINESIZE;j++) {
+ unc_p = (unsigned char *)TO_UNC(src);
+ for(i = 0;i<L2C_LINESIZE * 2;i++){
+ unc_p[i] = i & 0xff;
+ __sync();
+ src[i] = i & 0xff;
+ }
+ p = src;
+ for(i = 0;i < L2C_LINESIZE*2-j;i++){
+ *p = 0xff - i;
+ p++;
+ }
+ dma_cache_sync(NULL,src,L2C_LINESIZE * 2 - j,DMA_TO_DEVICE);
+ p = src;
+ //msleep(1);
+ for(i = 0;i < L2C_LINESIZE * 2 - j;i++){
+ if(*p != 0xff - i){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,0xff - i,*p);
+ return -1;
+ }
+ p++;
+ }
+ for(;i < L2C_LINESIZE * 2;i++){
+ if(*p != (i & 255)){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,i & 255,*p);
+ return -1;
+ }
+ p++;
+ }
+ }
+ }
+ if(src_org)
+ kfree(src_org);
+ return 0;
+}
+static __maybe_unused int invalid_align_address(struct l2c_test_thread *data)
+{
+ unsigned char *src_org;
+ unsigned char *src;
+ unsigned char *p;
+ unsigned char *unc_p;
+ int i,j,n;
+ src_org = (unsigned char*)kmalloc(L2C_LINESIZE * 5,GFP_KERNEL);
+ if(IS_ERR_OR_NULL(src_org)){
+ src = 0;
+ info("kmalloc error!\n");
+ }else{
+ src = src_org + L2C_LINESIZE;
+ info("%s test addr: %p\n",__func__,src);
+ for(j = 0;j<L2C_LINESIZE;j++) {
+ unc_p = (unsigned char *)TO_UNC(src);
+ for(i = 0;i<L2C_LINESIZE * 3;i++){
+ unc_p[i] = i & 0xff;
+ __sync();
+ src[i] = i & 0xff;
+ }
+
+ dma_cache_sync(NULL,&src[j],L2C_LINESIZE * 2,DMA_FROM_DEVICE);
+ p = &src[j];
+ unc_p = (unsigned char*)TO_UNC(p);
+ for(i = 0;i < L2C_LINESIZE * 2;i++){
+ unc_p[i] = 0xff - i;
+ __sync();
+ }
+ //msleep(1);
+ p = src;
+ n = 0;
+ for(i = 0;i<L2C_LINESIZE * 3;i++){
+ if(p >= &src[j] && p < (&src[j] + L2C_LINESIZE * 2)){
+ if(*p != (0xff - n)){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,0xff - n,*p);
+ return -1;
+ }
+ n++;
+ }else{
+ if(*p != (i & 255)){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,i & 255,*p);
+ return -1;
+ }
+ }
+ p++;
+ }
+ for(i = 0;i<L2C_LINESIZE * 3;i++){
+ src[i] = i & 255;
+ }
+ }
+ }
+ if(src_org)
+ kfree(src_org);
+ return 0;
+}
+static __maybe_unused int invalid_align_size(struct l2c_test_thread *data)
+{
+ unsigned char *src;
+ unsigned char *src_org;
+ unsigned char *p;
+ unsigned char *unc_p;
+ int i,j;
+
+ src_org = (unsigned char*)kmalloc(L2C_LINESIZE * 5,GFP_KERNEL);
+ if(IS_ERR_OR_NULL(src_org)){
+ src = 0;
+ info("kmalloc error!\n");
+ }else{
+ src = src_org + L2C_LINESIZE;
+ info("%s test addr: %p\n",__func__,src);
+ for(j = 0;j < L2C_LINESIZE;j++) {
+ for(i = 0;i<L2C_LINESIZE * 3;i++){
+ src[i] = i & 255;
+ }
+ dma_cache_sync(NULL,src,L2C_LINESIZE * 3 - j,DMA_FROM_DEVICE);
+ p = src;
+ unc_p = (unsigned char*)TO_UNC(p);
+ for(i = 0;i < L2C_LINESIZE*3-j;i++){
+ *unc_p = 0xff - i;
+ __sync();
+ unc_p++;
+ }
+ //msleep(1);
+ for(i = 0;i < L2C_LINESIZE * 3 - j;i++){
+ if(*p != 0xff - i){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,0xff - i,*p);
+ return -1;
+ }
+ p++;
+ }
+ for(;i < L2C_LINESIZE * 3;i++){
+ if(*p != (i & 255)){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p offset:%d e:0x%02x r:0x%02x\n",src,p-src,i & 255,*p);
+ return -1;
+ }
+ p++;
+ }
+ }
+ }
+ if(src_org)
+ kfree(src_org);
+ return 0;
+}
+static __maybe_unused int blast_invalid_all(struct l2c_test_thread *data)
+{
+ unsigned char *src;
+ unsigned char *src_org;
+ unsigned char *p;
+ unsigned char *unc_p;
+ unsigned char eq;
+ int i,j;
+ src_org = (unsigned char*)kmalloc(L2C_SIZE * 2 + L2C_LINESIZE * 2,GFP_KERNEL);
+ if(IS_ERR_OR_NULL(src_org)){
+ src = 0;
+ info("kmalloc error!\n");
+ }else{
+ src = src_org + L2C_LINESIZE;
+ info("%s test addr: %p\n",__func__,src);
+ for(i = 0;i < L2C_SIZE * 2;i++){
+ src[i] = i & 0xff;
+ }
+ dma_cache_sync(NULL,src,L2C_SIZE * 2,DMA_FROM_DEVICE);
+ p = src;
+ unc_p = (unsigned char *)TO_UNC(p);
+ for(i = 0;i < L2C_SIZE;i++){
+ unc_p[L2C_SIZE / 2 + i] = 0xff - (i & 0xff);
+ __sync();
+ }
+ //msleep(1);
+ j = 0;
+ for(i = 0;i < L2C_SIZE * 2;i++){
+
+ if((i >= L2C_SIZE / 2) && (i < L2C_SIZE / 2 + L2C_SIZE))
+ {
+ eq = 0xff - (j & 0xff);
+ j++;
+ }else {
+ eq = i & 0xff;
+ }
+ if(p[i] != eq){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p e:0x%02x r:0x%02x\n",p,eq,p[i]);
+ return -1;
+ }
+ }
+ }
+ if(src_org)
+ kfree(src_org);
+ return 0;
+}
+static __maybe_unused int blast_writeback_all(struct l2c_test_thread *data)
+{
+ unsigned char *src;
+ unsigned char *src_org;
+ unsigned char *p;
+ unsigned char *unc_p;
+ int i;
+ unsigned char eq;
+ src_org = (unsigned char*)kmalloc(L2C_SIZE * 2 + L2C_LINESIZE * 2,GFP_KERNEL);
+ if(IS_ERR_OR_NULL(src_org)){
+ src = 0;
+ info("kmalloc error!\n");
+ }else{
+ src = src_org + L2C_LINESIZE;
+ info("%s test addr: %p\n",__func__,src);
+ p = src;
+ unc_p = (unsigned char *)TO_UNC(p);
+ for(i = 0;i < L2C_SIZE;i++){
+ unc_p[L2C_SIZE / 2 + i] = 0xff - (i & 0xff);
+ __sync();
+ }
+ for(i = 0;i < L2C_SIZE * 2;i++){
+ src[i] = i & 0xff;
+ }
+ dma_cache_sync(NULL,src,L2C_SIZE * 2,DMA_TO_DEVICE);
+
+ for(i = 0;i < L2C_SIZE * 2;i++){
+ eq = i & 0xff;
+ if(p[i] != eq){
+ PALLADIUM_TRIGER();
+ info("Err:addr:%p e:0x%02x r:0x%02x\n",p,eq,p[i]);
+ return -1;
+ }
+ }
+ }
+ if(src_org)
+ kfree(src_org);
+ return 0;
+}
+
+struct l2c_test{
+ struct dentry *root;
+ int run;
+ struct mutex lock;
+ struct mutex resultlock;
+ struct list_head top;
+ unsigned int thread_count;
+};
+static TEST_FUNC g_test_func[] ={
+ writeback_align_address,
+ writeback_align_size,
+ invalid_align_address,
+ invalid_align_size,
+ blast_invalid_all,
+ blast_writeback_all
+};
+static int g_thread_id = 0;
+
+
+static int l2c_test_func(void *data)
+{
+ struct l2c_test_thread *thread = data;
+ int index;
+ while (!kthread_should_stop())
+ {
+ printk("d:%p\n",thread->test_func);
+ thread->test_func(thread);
+ index = prandom_u32() % ARRAY_SIZE(g_test_func);
+ thread->test_func = g_test_func[index];
+ }
+ thread->done = 0;
+ return 0;
+}
+
+
+
+static int l2c_test_add_threads(struct l2c_test *l2ctest)
+{
+ struct l2c_test_thread *thread;
+ unsigned int index;
+ thread = (struct l2c_test_thread *)kmalloc(sizeof(struct l2c_test_thread), GFP_KERNEL);
+ if(IS_ERR_OR_NULL(thread)){
+ printk("thread kmalloc failed!\n");
+ return -1;
+ }
+ memset(thread,0,sizeof(struct l2c_test_thread));
+ thread->done = -1;
+ index = prandom_u32() % ARRAY_SIZE(g_test_func);
+ thread->test_func = g_test_func[index];
+ thread->id = g_thread_id;
+ thread->lock = &l2ctest->resultlock;
+ thread->task = kthread_run(l2c_test_func, thread, "l2c_test%d-func%u",g_thread_id++,index);
+ if (IS_ERR(thread->task)) {
+ info("l2c_test: Failed to run thread l2c_test%d-func%u\n",g_thread_id,index);
+ kfree(thread);
+ return -1;
+ }
+ list_add_tail(&thread->list, &l2ctest->top);
+ return 0;
+}
+static void stop_threaded_test(struct l2c_test *l2ctest)
+{
+ struct l2c_test_thread *thread,*_thread;
+
+ list_for_each_entry_safe(thread, _thread, &l2ctest->top, list) {
+ list_del(&thread->list);
+ kthread_stop(thread->task);
+ while(thread->done);
+ kfree(thread);
+ }
+}
+
+static int run_l2c_test(struct l2c_test *l2c)
+{
+ int i = 0;
+ if(l2c->thread_count > 0){
+ for(i = 0;i < l2c->thread_count;i++){
+ l2c_test_add_threads(l2c);
+ }
+ }
+ return 0;
+}
+
+static ssize_t l2c_test_read_run(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct l2c_test *l2c = file->private_data;
+ char *buf;
+ mutex_lock(&l2c->lock);
+ if(!list_empty(&l2c->top))
+ buf = "Runing\n";
+ else
+ buf = "Stop\n";
+ mutex_unlock(&l2c->lock);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+}
+static ssize_t l2c_test_write_run(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct l2c_test *l2c = file->private_data;
+ char buf[16];
+ bool bv;
+ int ret = 0;
+ if (copy_from_user(buf, user_buf, min(count, (sizeof(buf) - 1))))
+ return -EFAULT;
+
+ if (strtobool(buf, &bv) == 0) {
+ mutex_lock(&l2c->lock);
+ if(bv){
+ run_l2c_test(l2c);
+ }else{
+ stop_threaded_test(l2c);
+ }
+ mutex_unlock(&l2c->lock);
+ }
+
+ return ret ? ret : count;
+}
+
+static const struct file_operations l2c_test_run_fops = {
+ .read = l2c_test_read_run,
+ .write = l2c_test_write_run,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+struct l2c_test g_l2c_test;
+
+static int __init l2c_test_init(void)
+{
+ struct dentry * d;
+ struct l2c_test *l2c= &g_l2c_test;
+
+ memset(l2c,0,sizeof(struct l2c_test));
+ mutex_init(&l2c->lock);
+ mutex_init(&l2c->resultlock);
+ INIT_LIST_HEAD(&l2c->top);
+ l2c->thread_count = 1;
+
+ d = debugfs_create_dir("l2c_test", NULL);
+ if (IS_ERR(d)){
+ pr_err("create debugfs for l2c_test failed.\n");
+ return PTR_ERR(d);
+ }
+ l2c->root = d;
+
+ d = debugfs_create_u32("thread_count", S_IWUSR | S_IRUGO, l2c->root,
+ (u32 *)&l2c->thread_count);
+ if (IS_ERR_OR_NULL(d)){
+ pr_err("debugfs create thread_count node failed\n");
+ goto err_node;
+ }
+
+ d = debugfs_create_file("run", S_IWUSR | S_IRUGO, l2c->root,
+ l2c, &l2c_test_run_fops);
+ if (IS_ERR_OR_NULL(d)){
+ pr_err("debugfs create run node failed\n");
+ goto err_node;
+ }
+ pr_info("l2c_test debugfs init ok.\n");
+ return 0;
+err_node:
+ debugfs_remove_recursive(l2c->root);
+ pr_err("l2c_test debugfs init failed.\n");
+ return -1;
+}
+late_initcall(l2c_test_init);
+
+static void __exit l2c_test_deinit(void)
+{
+ struct l2c_test *l2c= &g_l2c_test;
+ stop_threaded_test(l2c);
+ debugfs_remove_recursive(l2c->root);
+}
+module_exit(l2c_test_deinit);

View File

@ -0,0 +1,266 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.c b/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,262 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include "multithread_test.h"
+struct multithread_test{
+ struct dentry *root;
+ const char *name;
+ int run;
+ struct mutex lock;
+ struct mutex resultlock;
+ struct list_head thread_top;
+ unsigned int thread_count;
+ struct list_head func_top;
+};
+struct func_list {
+ struct list_head list;
+ const char *test_name;
+ TEST_FUNC testfunc;
+ void *param;
+ atomic_t testcount;
+};
+struct thread_test{
+ struct multithread_test *mt;
+ struct list_head list;
+ struct task_struct *task;
+ char thread_name[20];
+ TEST_FUNC test_func;
+ void* param;
+ struct mutex *lock;
+ volatile int done;
+};
+static int mt_test_func(void *data);
+static int mt_test_add_threads(struct multithread_test *mt)
+{
+ struct thread_test *thread;
+ struct func_list *l_func;
+ struct func_list *min_func = NULL;
+ unsigned int testcount;
+ int retry = 100000;
+
+ if(list_empty(&mt->func_top))
+ {
+ printk("test func list is empty,please add func for multithread test.\n");
+ return -1;
+ }
+
+ thread = (struct thread_test *)vmalloc(sizeof(struct thread_test));
+ if(IS_ERR_OR_NULL(thread)){
+ printk("%s:thread kmalloc failed!\n",mt->name);
+ return -1;
+ }
+ memset(thread,0,sizeof(struct thread_test));
+ thread->done = -1;
+
+ testcount = 0xffffffff;
+ list_for_each_entry(l_func,&mt->func_top,list){
+ unsigned int tc;
+ tc = atomic_read(&l_func->testcount);
+ if(testcount >= tc){
+ min_func = l_func;
+ testcount = tc;
+ }
+ }
+ if(!min_func)
+ {
+ printk("Not find func %s %d\n",__FILE__,__LINE__);
+ goto err_exit;
+ }
+ atomic_inc(&min_func->testcount);
+
+ thread->mt = mt;
+ thread->test_func = min_func->testfunc;
+ thread->param = min_func->param;
+ thread->lock = &mt->resultlock;
+ snprintf(thread->thread_name,sizeof(thread->thread_name),"%s-%d\n",min_func->test_name,atomic_read(&min_func->testcount));
+
+ do {
+ if(retry <= 0) {
+ break;
+ }
+ thread->task = kthread_run(mt_test_func, thread, thread->thread_name);
+ msleep(1);
+
+ retry--;
+
+ } while ((int)thread->task == -EAGAIN);
+
+ if (IS_ERR(thread->task) || (retry == 0)) {
+ printk("%s: Failed to run thread func:%s, retry: %d\n",mt->name,thread->thread_name, retry);
+ goto err_exit;
+ }
+ list_add_tail(&thread->list, &mt->thread_top);
+ return 0;
+err_exit:
+ kfree(thread);
+ return -1;
+}
+
+static int mt_test_func(void *data)
+{
+ struct thread_test *thread = data;
+ while (!kthread_should_stop())
+ {
+ if(thread->test_func(thread->param) == 0)
+ {
+ mutex_lock(&thread->mt->lock);
+ mt_test_add_threads(thread->mt);
+ mutex_unlock(&thread->mt->lock);
+ }
+ break;
+ }
+
+ mutex_lock(&thread->mt->lock);
+ list_del(&thread->list);
+ thread->done = 0;
+ mutex_unlock(&thread->mt->lock);
+
+ vfree(thread);
+ return 0;
+}
+
+static int run_mt_test(struct multithread_test *mt)
+{
+ int i = 0;
+ if(mt->thread_count > 0){
+ for(i = 0;i < mt->thread_count;i++){
+ mt_test_add_threads(mt);
+ }
+ }
+ return 0;
+}
+static void stop_threaded_test(struct multithread_test *mt)
+{
+ struct thread_test *thread,*_thread;
+
+ list_for_each_entry_safe(thread, _thread, &mt->thread_top, list) {
+ list_del(&thread->list);
+ kthread_stop(thread->task);
+ while(thread->done);
+ vfree(thread);
+ }
+}
+
+static ssize_t mt_test_read_run(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct multithread_test *mt = file->private_data;
+ char *buf;
+ mutex_lock(&mt->lock);
+ if(!list_empty(&mt->thread_top))
+ buf = "Runing\n";
+ else
+ buf = "Stop\n";
+ mutex_unlock(&mt->lock);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+}
+static ssize_t mt_test_write_run(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct multithread_test *mt = file->private_data;
+ char buf[16];
+ bool bv;
+ int ret = 0;
+ if (copy_from_user(buf, user_buf, min(count, (sizeof(buf) - 1))))
+ return -EFAULT;
+
+ if (strtobool(buf, &bv) == 0) {
+ mutex_lock(&mt->lock);
+ if(bv){
+ run_mt_test(mt);
+ }else{
+ stop_threaded_test(mt);
+ }
+ mutex_unlock(&mt->lock);
+ }
+ return ret ? ret : count;
+}
+static const struct file_operations mt_test_run_fops = {
+ .read = mt_test_read_run,
+ .write = mt_test_write_run,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+int multithread_test_add_func(void *handle,const char *name,TEST_FUNC testfunc,void *param)
+{
+ struct multithread_test *mt = (struct multithread_test *)handle;
+ struct func_list *funclist = vmalloc(sizeof(struct multithread_test));
+ if(funclist == NULL){
+ printk("add func failed,%s %d\n",__FILE__,__LINE__);
+ return -1;
+ }
+ funclist->test_name = name;
+ funclist->testfunc = testfunc;
+ funclist->param = param;
+ atomic_set(&funclist->testcount,0);
+ list_add_tail(&funclist->list,&mt->func_top);
+ return 0;
+}
+void* multithread_test_init(const char *name,int threadcount)
+{
+ struct dentry * d;
+ struct multithread_test *mt = vmalloc(sizeof(struct multithread_test));
+ if(!mt){
+ pr_err("%s:%s %d alloc struct multithread_test failed!\n",name,__FILE__,__LINE__);
+ return NULL;
+ }
+ memset(mt,0,sizeof(struct multithread_test));
+ mutex_init(&mt->lock);
+ mutex_init(&mt->resultlock);
+ INIT_LIST_HEAD(&mt->thread_top);
+ INIT_LIST_HEAD(&mt->func_top);
+ mt->thread_count = threadcount;
+ mt->name = name;
+ d = debugfs_create_dir(name, NULL);
+ if (IS_ERR(d)){
+ pr_err("create debugfs for %s failed.\n",name);
+ return NULL;
+ }
+ mt->root = d;
+
+ d = debugfs_create_u32("thread_count", S_IWUSR | S_IRUGO, mt->root,
+ (u32 *)&mt->thread_count);
+ if (IS_ERR_OR_NULL(d)){
+ pr_err("%s:debugfs create thread_count node failed\n",name);
+ goto err_node;
+ }
+
+ d = debugfs_create_file("run", S_IWUSR | S_IRUGO, mt->root,
+ mt, &mt_test_run_fops);
+ if (IS_ERR_OR_NULL(d)){
+ pr_err("%s:debugfs create run node failed\n",name);
+ goto err_node;
+ }
+ pr_info("%s:debugfs init ok.\n",name);
+ return (void*)mt;
+err_node:
+ debugfs_remove_recursive(mt->root);
+ pr_err("%s:debugfs init failed.\n",name);
+ return NULL;
+}
+
+void multithread_test_deinit(void *handle)
+{
+ struct multithread_test *mt = (struct multithread_test *)handle;
+ struct func_list *funclist,*_funclist;
+ stop_threaded_test(mt);
+ debugfs_remove_recursive(mt->root);
+ list_for_each_entry_safe(funclist, _funclist, &mt->thread_top, list) {
+ list_del(&funclist->list);
+ vfree(funclist);
+ }
+ vfree(mt);
+}

View File

@ -0,0 +1,13 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.h b/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.h
--- a/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/multithread_test.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,9 @@
+#ifndef _MULTITHREAD_TEST_H_
+#define _MULTITHREAD_TEST_H_
+
+typedef int (*TEST_FUNC)(void *);
+int multithread_test_add_func(void *handle,const char *name,TEST_FUNC testfunc,void *param);
+void* multithread_test_init(const char *name,int threadcount);
+void multithread_test_deinit(void* handle);
+
+#endif /* _MULTITHREAD_TEST_H_ */

View File

@ -0,0 +1,270 @@
diff -drupN a/arch/mips/xburst2/common/cpu_ddr_test/raw_dma_test.c b/arch/mips/xburst2/common/cpu_ddr_test/raw_dma_test.c
--- a/arch/mips/xburst2/common/cpu_ddr_test/raw_dma_test.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/cpu_ddr_test/raw_dma_test.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,266 @@
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/random.h>
+//#include <mach/jzdma_v13.h>
+
+#include "../../../../../drivers/dma/ingenic/ingenic_dma.h"
+
+const int dma_test_burst_len[] = {1,4,8,16,32,64,128};
+
+struct dma_channel{
+ struct list_head list;
+ struct dma_chan *chan;
+ unsigned char *desc;
+ unsigned int blen_per_desc;
+};
+
+struct cycle_raw_dma_test{
+ struct dentry *root;
+ int run;
+ struct mutex lock;
+ struct list_head top;
+};
+
+static struct cycle_raw_dma_test g_raw_cycle_dma;
+
+static bool filter(struct dma_chan *chan, void *param)
+{
+#if 0
+ if (!((unsigned int)chan->private == 8)) {
+ return false;
+ }
+#endif
+ return true;
+}
+const static char dcm_tsz[8] = { 1, 2, 0, 0, 3, 4, 5, 6 };
+static inline unsigned int get_max_tsz(unsigned long val, unsigned long *dcmp)
+{
+
+ int ord;
+
+ ord = ffs(val) - 1;
+ if (ord < 0)
+ ord = 0;
+ else if (ord > 7)
+ ord = 7;
+
+ *dcmp &= ~DCM_TSZ_MSK;
+ *dcmp |= dcm_tsz[ord] << DCM_TSZ_SFT;
+
+ /* if tsz == 8, set it to 4 */
+ return ord == 3 ? 4 : 1 << ord;
+}
+static void dump_desc(char *title,struct hdma_desc *desc)
+{
+ printk("=========== %s =========== \n",title);
+ printk("dcm:0x%08lx\n",desc->dcm);
+ printk("dsa:0x%08x\n",(unsigned int)desc->dsa);
+ printk("dta:0x%08x\n",(unsigned int)desc->dta);
+ printk("dtc:0x%08lx\n",desc->dtc);
+ printk("drt:0x%08lx\n",desc->drt);
+
+}
+static void build_desc(unsigned char *desc,int burst,int len)
+{
+ /**
+ * 4 series A B A' B' desc.
+ * A desc is transmite (A B) to (A' B')
+ * A next desc is B'
+ * B desc is transmite (A' B') to (A B)
+ * B next desc is A
+ */
+ unsigned long burst_bits = 0;
+ struct hdma_desc *A = (struct hdma_desc *)desc;
+ struct hdma_desc *B = (struct hdma_desc *)(desc + len * 1);
+ struct hdma_desc *A1 = (struct hdma_desc *)(desc + len * 2);
+ struct hdma_desc *B1 = (struct hdma_desc *)(desc + len * 3);
+
+ burst = get_max_tsz(burst,&burst_bits);
+ A->dcm = DCM_SAI | DCM_DAI | DCM_LINK | burst_bits;
+ A->dsa = virt_to_phys(A);
+ A->dta = virt_to_phys(A1);
+ A->dtc = (len * 2 / burst) | ((((unsigned int)B1 & 0xff0) >> 4) << 24);
+ A->drt = 8;
+
+ B->dcm = DCM_SAI | DCM_DAI | DCM_LINK | burst_bits;
+ B->dsa = virt_to_phys(A1);
+ B->dta = virt_to_phys(A);
+ B->dtc = (len * 2 / burst) | ((((unsigned int)A & 0xff0) >> 4) << 24);
+ B->drt = 8;
+
+ dump_desc("A",A);
+ dump_desc("B",B);
+ dma_cache_sync(NULL,A,len*4,DMA_TO_DEVICE);
+}
+static void start_dma_chans(struct cycle_raw_dma_test *dma)
+{
+ struct dma_channel *ch;
+ list_for_each_entry(ch,&dma->top,list){
+ struct ingenic_dma_chan *dmac = to_ingenic_dma_chan(ch->chan);
+ writel((unsigned int)virt_to_phys(ch->desc), dmac->iomem + CH_DDA);
+ printk("dda:%p->0x%08lx\n",dmac->iomem + CH_DDA,virt_to_phys(ch->desc));
+ /* initiate descriptor fetch */
+ writel(BIT(dmac->id), dmac->engine->iomem + DDRS);
+ printk("ddrs:%p->0x%08lx\n",dmac->engine->iomem + DDRS,BIT(dmac->id));
+ writel(1 | (1 << 30),dmac->iomem + CH_DCS);
+ }
+}
+static void stop_dma_chans(struct cycle_raw_dma_test *dma)
+{
+ struct dma_channel *ch;
+ list_for_each_entry(ch,&dma->top,list){
+ struct hdma_desc *A,*B;
+ struct ingenic_dma_chan *dmac = to_ingenic_dma_chan(ch->chan);
+ int len = ch->blen_per_desc;
+ A = (struct hdma_desc *)(ch->desc);
+ B = (struct hdma_desc *)(ch->desc + len * 1);
+ A->dtc &= ~(0xff << 24);
+ B->dtc &= ~(0xff << 24);
+ dma_cache_sync(NULL,A,len*4,DMA_TO_DEVICE);
+ while(readl(dmac->iomem + CH_DCS) & (1 << 3));
+ writel(0,dmac->iomem + CH_DCS);
+ }
+
+}
+static void start_cycle_raw_dma(struct cycle_raw_dma_test *dma)
+{
+ int i;
+ int max;
+ struct dma_channel *ch;
+ struct dma_chan *chan;
+ dma_cap_mask_t mask;
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_MEMCPY, mask);
+ for(i = 0;i < ARRAY_SIZE(dma_test_burst_len);i++){
+ chan = dma_request_channel(mask, filter, dma);
+ if (!chan) {
+ printk("dma channel request failed! curid = %d, burstlen: %d ignored\n",i,dma_test_burst_len[i]);
+// break;
+ continue;
+ }
+ if(dma_test_burst_len[i] < 32)
+ max = 32;
+ else
+ max = dma_test_burst_len[i];
+
+ //extra add 16 byte for descriptor align.
+ ch = kmalloc(sizeof(struct dma_channel) + max * 4 + 16,GFP_KERNEL); // max * 4 is (4's descs)
+ if(IS_ERR_OR_NULL(ch)){
+ pr_err("dma request channel failed!\n");
+ dma_release_channel(chan);
+ break;
+ }
+ ch->chan = chan;
+ ch->desc = (unsigned char*)(((unsigned int)(ch + 1) + 15) / 16 * 16); // aligned 16 byte for dma descriptor
+ ch->blen_per_desc = max;
+ build_desc(ch->desc,dma_test_burst_len[i],max);
+ list_add_tail(&ch->list,&dma->top);
+ }
+ start_dma_chans(dma);
+}
+static void stop_cycle_raw_dma(struct cycle_raw_dma_test *dma)
+{
+
+ struct list_head *pos;
+ struct list_head *next;
+ struct dma_channel *ch;
+ stop_dma_chans(dma);
+ list_for_each_safe(pos,next,&dma->top){
+ ch = list_entry(pos,struct dma_channel,list);
+ dma_release_channel(ch->chan);
+ list_del(pos);
+ kfree(ch);
+ }
+}
+static int is_stop_cycle_raw_dma(struct cycle_raw_dma_test *dma)
+{
+ return list_empty(&dma->top);
+}
+static ssize_t cycle_raw_dma_test_read_run(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct cycle_raw_dma_test *dma = file->private_data;
+ char *buf;
+ mutex_lock(&dma->lock);
+ if(!is_stop_cycle_raw_dma(dma))
+ buf = "Runing\n";
+ else
+ buf = "Stop\n";
+ mutex_unlock(&dma->lock);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+}
+static ssize_t cycle_raw_dma_test_write_run(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct cycle_raw_dma_test *dma = file->private_data;
+ char buf[16];
+ bool bv;
+ int ret = 0;
+ if (copy_from_user(buf, user_buf, min(count, (sizeof(buf) - 1))))
+ return -EFAULT;
+
+ if (strtobool(buf, &bv) == 0) {
+ mutex_lock(&dma->lock);
+ if(bv){
+ start_cycle_raw_dma(dma);
+ }else{
+ stop_cycle_raw_dma(dma);
+ }
+ mutex_unlock(&dma->lock);
+ }
+
+ return ret ? ret : count;
+}
+
+static const struct file_operations cycle_raw_dma_test_run_fops = {
+ .read = cycle_raw_dma_test_read_run,
+ .write = cycle_raw_dma_test_write_run,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+static int __init cycle_raw_dma_test_init(void)
+{
+ struct dentry * d;
+
+ struct cycle_raw_dma_test *dma= &g_raw_cycle_dma;
+
+ memset(dma,0,sizeof(struct cycle_raw_dma_test));
+ INIT_LIST_HEAD(&dma->top);
+ mutex_init(&dma->lock);
+ d = debugfs_create_dir("cycle_raw_dma_test", NULL);
+ if (IS_ERR(d)){
+ pr_err("create debugfs for cycle_raw_dma_test failed.\n");
+ return PTR_ERR(d);
+ }
+ dma->root = d;
+
+ d = debugfs_create_file("run", S_IWUSR | S_IRUGO, dma->root,
+ dma, &cycle_raw_dma_test_run_fops);
+ if (IS_ERR_OR_NULL(d)){
+ pr_err("debugfs create run node failed\n");
+ goto err_node;
+ }
+ pr_info("cycle raw dma_test debugfs init ok.\n");
+ return 0;
+err_node:
+ debugfs_remove_recursive(dma->root);
+ pr_err("cycle_raw_dma_test debugfs init failed.\n");
+ return -1;
+}
+late_initcall(cycle_raw_dma_test_init);
+
+static void __exit cycle_raw_dma_test_deinit(void)
+{
+ struct cycle_raw_dma_test *dma= &g_raw_cycle_dma;
+ debugfs_remove_recursive(dma->root);
+}
+module_exit(cycle_raw_dma_test_deinit);

View File

@ -0,0 +1,102 @@
diff -drupN a/arch/mips/xburst2/common/get-cpu-features.c b/arch/mips/xburst2/common/get-cpu-features.c
--- a/arch/mips/xburst2/common/get-cpu-features.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/get-cpu-features.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,98 @@
+/*
+ * Use this function to generate cpu-feature-override.h head file.
+ * Make sure of that, here is no cpu-feature-override.h in mach-xxx directory.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#define __ASM_MACH_INGENIC_CPU_FEATURE_OVERRIDES_H__
+#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+
+static int cpu_proc_show(struct seq_file *m, void *v)
+{
+
+#define PRINT(ARGS...) seq_printf (m, ##ARGS)
+
+#define PRT0(X,Y) PRINT("#define " "%s()\t(%d * 1024)\n",#X,(Y)/1024)
+#define PRT1(X,Y) PRINT("#define " "%s()\t%d\n",#X,(Y))
+ PRT0(cpu_dcache_size,(1<<current_cpu_data.dcache.waybit)*current_cpu_data.dcache.ways);
+ PRT1(cpu_dcache_ways,current_cpu_data.dcache.ways);
+ PRT1(cpu_dcache_line_size,current_cpu_data.dcache.linesz);
+
+ PRT0(cpu_icache_size,(1<<current_cpu_data.icache.waybit)*current_cpu_data.icache.ways);
+ PRT1(cpu_icache_ways,current_cpu_data.icache.ways);
+ PRT1(cpu_icache_line_size,current_cpu_data.icache.linesz);
+
+#define PRT2(X) PRINT("#define " "%-30s\t%d\n",#X,X? 1: 0)
+ PRT2(cpu_has_tlb);
+ PRT2(cpu_has_4kex);
+ PRT2(cpu_has_3k_cache);
+ PRT2(cpu_has_4k_cache);
+ PRT2(cpu_has_tx39_cache);
+ PRT2(cpu_has_fpu);
+ PRT2(cpu_has_32fpr);
+ PRT2(cpu_has_counter);
+ PRT2(cpu_has_watch);
+ PRT2(cpu_has_divec);
+ PRT2(cpu_has_vce);
+ PRT2(cpu_has_cache_cdex_p);
+ PRT2(cpu_has_cache_cdex_s);
+ PRT2(cpu_has_prefetch);
+ PRT2(cpu_has_mcheck);
+ PRT2(cpu_has_ejtag);
+ PRT2(cpu_has_llsc);
+ PRT2(cpu_has_mips16);
+ PRT2(cpu_has_mdmx);
+ PRT2(cpu_has_mips3d);
+ PRT2(cpu_has_smartmips);
+ PRT2(cpu_has_vtag_icache);
+ PRT2(cpu_has_dc_aliases);
+ PRT2(cpu_has_ic_fills_f_dc);
+ PRT2(cpu_has_pindexed_dcache);
+ PRT2(cpu_icache_snoops_remote_store);
+ PRT2(cpu_has_mips32r1);
+ PRT2(cpu_has_mips32r2);
+ PRT2(cpu_has_mips64r1);
+ PRT2(cpu_has_mips64r2);
+ PRT2(cpu_has_dsp);
+ PRT2(cpu_has_mipsmt);
+ PRT2(cpu_has_userlocal);
+ PRT2(cpu_has_nofpuex);
+ PRT2(cpu_has_64bits);
+ PRT2(cpu_has_64bit_zero_reg);
+ PRT2(cpu_has_vint);
+ PRT2(cpu_has_veic);
+ PRT2(cpu_has_inclusive_pcaches);
+
+ PRINT("\n");
+ PRINT("cp0 prid:\t%08x\n",read_c0_prid());
+ PRINT("cp0 config0:\t%08x\n",read_c0_config());
+ PRINT("cp0 config1:\t%08x\n",read_c0_config1());
+ PRINT("cp0 config2:\t%08x\n",read_c0_config2());
+ PRINT("cp0 config3:\t%08x\n",read_c0_config3());
+ PRINT("cp0 config4:\t%08x\n",read_c0_config4());
+
+ return 0;
+}
+
+static int cpu_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cpu_proc_show, PDE_DATA(inode));
+}
+static const struct file_operations cpu_proc_fops ={
+ .read = seq_read,
+ .open = cpu_open,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+static int __init init_cpu_features(void)
+{
+ proc_create("cpu-feature-override",0444,NULL,&cpu_proc_fops);
+
+ return 0;
+}
+
+module_init(init_cpu_features);

View File

@ -0,0 +1,87 @@
diff -drupN a/arch/mips/xburst2/common/jz_notifier.c b/arch/mips/xburst2/common/jz_notifier.c
--- a/arch/mips/xburst2/common/jz_notifier.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/jz_notifier.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,83 @@
+#include <jz_notifier.h>
+
+static BLOCKING_NOTIFIER_HEAD(jz_notifier_chain_high);
+static BLOCKING_NOTIFIER_HEAD(jz_notifier_chain_normal);
+static BLOCKING_NOTIFIER_HEAD(jz_notifier_chain_low);
+static int jz_notifier(struct notifier_block *nb, unsigned long cmd, void *data)
+{
+ struct jz_notifier *jz_nb = container_of(nb,struct jz_notifier,nb);
+ int ret = 0;
+ if(jz_nb->msg == cmd) {
+ ret = jz_nb->jz_notify(jz_nb,data);
+ }
+ return ret;
+}
+
+int jz_notifier_register(struct jz_notifier *notify, unsigned int priority)
+{
+ unsigned int ret = 0;
+
+ if((notify->level < NOTEFY_PROI_START) && (notify->level >= NOTEFY_PROI_END))
+ {
+ printk("notify level can not support this %d\n",notify->level);
+ dump_stack();
+ return -1;
+ }
+ if((int)notify->msg >= JZ_CMD_END && (int)notify->msg <= JZ_CMD_START)
+ {
+ printk("notify msg can not support this %d\n",notify->msg);
+ dump_stack();
+ return -1;
+ }
+ if(notify->jz_notify == NULL)
+ {
+ printk("notify function(jz_notify) cand not support NULL\n");
+ dump_stack();
+ return -1;
+ }
+ notify->nb.priority = notify->level;
+ notify->nb.notifier_call = jz_notifier;
+
+ if(priority == NOTEFY_PROI_HIGH)
+ ret = blocking_notifier_chain_register(&jz_notifier_chain_high, &notify->nb);
+ else if(priority == NOTEFY_PROI_NORMAL)
+ ret = blocking_notifier_chain_register(&jz_notifier_chain_normal, &notify->nb);
+ else if(priority == NOTEFY_PROI_LOW)
+ ret = blocking_notifier_chain_register(&jz_notifier_chain_low, &notify->nb);
+ else
+ printk("not support\n");
+ return ret;
+}
+EXPORT_SYMBOL(jz_notifier_register);
+
+int jz_notifier_unregister(struct jz_notifier *notify, unsigned int priority)
+{
+ unsigned int ret = 0;
+
+ if(priority == NOTEFY_PROI_HIGH)
+ ret = blocking_notifier_chain_unregister(&jz_notifier_chain_high, &notify->nb);
+ else if(priority == NOTEFY_PROI_NORMAL)
+ ret = blocking_notifier_chain_unregister(&jz_notifier_chain_normal, &notify->nb);
+ else if(priority == NOTEFY_PROI_LOW)
+ ret = blocking_notifier_chain_unregister(&jz_notifier_chain_low, &notify->nb);
+ else
+ printk("not support\n");
+ return ret;
+}
+EXPORT_SYMBOL(jz_notifier_unregister);
+
+int jz_notifier_call(unsigned int priority, unsigned long val, void *v)
+{
+ unsigned int ret = 0;
+
+ if(priority == NOTEFY_PROI_HIGH)
+ ret = blocking_notifier_call_chain(&jz_notifier_chain_high, val, v);
+ else if(priority == NOTEFY_PROI_NORMAL)
+ ret = blocking_notifier_call_chain(&jz_notifier_chain_normal, val, v);
+ else if(priority == NOTEFY_PROI_LOW)
+ ret = blocking_notifier_call_chain(&jz_notifier_chain_low, val, v);
+ else
+ printk("not support\n");
+ return ret;
+}
+EXPORT_SYMBOL(jz_notifier_call);

View File

@ -0,0 +1,698 @@
diff -drupN a/arch/mips/xburst2/common/mxuv3.c b/arch/mips/xburst2/common/mxuv3.c
--- a/arch/mips/xburst2/common/mxuv3.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/mxuv3.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,694 @@
+#include <asm/processor.h>
+#include <linux/sched.h>
+#include <mxuv3.h>
+
+#define WORDCODE
+
+__attribute__((optimize("O0")))
+void __init_mxuv3(void)
+{
+ unsigned int register val asm("t0");
+ val = 0;
+ /* open mxuv3 and set thread status ST0_CU2 */
+ set_c0_status(ST0_CU2);
+ KSTK_STATUS(current) |= ST0_CU2;
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid);
+
+ /* dump mxuv3 control and status register */
+#ifdef WORDCODE
+ //asm volatile(".word 0x70100203 | (0x0 << 11)\n\t":"=r"(val));
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d, mir=0x%x\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), KSTK_STATUS(current), current->tgid, current->pid, val);
+ //asm volatile(".word 0x70100203 | (0x1 << 11) \n\t":"=r"(val));
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d, mscr=0x%x\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), KSTK_STATUS(current), current->tgid, current->pid, val);
+ //dump_stack();
+#else
+ CFCMXU(val, 0);
+ printk("mir=0x%x\n", val);
+ CFCMXU(val, 1);
+ printk("mcsr=0x%x\n", val);
+#endif
+}
+
+__attribute__((optimize("O0")))
+void __save_mxuv3(void *tsk_void)
+{
+ register void *base asm("t0");
+#ifndef WORDCODE
+ register void *base1 asm("t1");
+#endif
+ struct task_struct *tsk = tsk_void;
+ struct xburst_mxu_struct *mxu = &tsk->thread.mxu;
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d, , KSTK_STATUS(tsk)=0x%lx, task->tgid=%d, task->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), KSTK_STATUS(current), current->tgid, current->pid, KSTK_STATUS(tsk), tsk->tgid, tsk->pid);
+ //dump_stack();
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d, task_cpu(p)=%d, KSTK_STATUS(p)=0x%lx, p->tgid=%d, p->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid, task_cpu(tsk), KSTK_STATUS(tsk), tsk->tgid, tsk->pid);
+#ifdef WORDCODE
+ /**
+ * sao ins: hex(0x700000d5 | 8 << 21 | 1 << 16 | 0 << 11 | 1 << 9)
+ * 0x700000d5 ->sa0
+ * 8 ->t0
+ * 1 ->32>>5
+ * 0 ->vpr0
+ * 1 ->nn // o means to be divided by 512/256=2, so n=[0,1]
+ * because t0 is fixed, so 0x700000d5 | 8 << 21 = 0x710000d5
+ * so the word format as follows:
+ * asm volatile(".word 0x710000d5 | offset << 16 | vprn << 11 | n << 9 \n\t");
+ * mfsum ins: hex(0x4a60000f | vss << 11 | vrd << 7)
+ * for we fixed vrd to 0, so the word format as follows:
+ * asm volatile(".word 0x4a60000f | vss << 11 \n\t");
+ */
+ base = &mxu->vpr[0];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 0 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 0 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[1];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 1 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 1 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[2];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 2 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 2 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[3];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 3 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 3 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[4];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 4 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 4 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[5];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 5 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 5 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[6];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 6 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 6 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[7];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 7 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 7 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[8];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 8 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 8 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[9];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 9 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 9 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[10];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 10 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 10 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[11];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 11 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 11 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[12];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 12 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 12 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[13];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 13 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 13 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[14];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 14 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 14 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[15];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 15 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 15 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[16];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 16 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 16 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[17];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 17 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 17 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[18];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 18 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 18 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[19];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 19 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 19 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[20];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 20 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 20 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[21];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 21 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 21 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[22];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 22 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 22 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[23];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 23 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 23 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[24];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 24 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 24 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[25];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 25 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 25 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[26];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 26 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 26 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[27];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 27 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 27 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[28];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 28 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 28 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[29];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 29 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 29 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[30];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 30 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 30 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vpr[31];
+ asm volatile(".word 0x710000d5 | 0 << 16 | 31 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 31 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vsr[0];
+ asm volatile(".word 0x4a60000f | 0 << 11 \n\t");
+ asm volatile(".word 0x710000d5 | 0 << 16 | 0 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 0 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vsr[1];
+ asm volatile(".word 0x4a60000f | 1 << 11 \n\t");
+ asm volatile(".word 0x710000d5 | 0 << 16 | 0 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 0 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vsr[2];
+ asm volatile(".word 0x4a60000f | 2 << 11 \n\t");
+ asm volatile(".word 0x710000d5 | 0 << 16 | 0 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 0 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->vsr[3];
+ asm volatile(".word 0x4a60000f | 3 << 11 \n\t");
+ asm volatile(".word 0x710000d5 | 0 << 16 | 0 << 11 | 0 << 9 \n\t");
+ asm volatile(".word 0x710000d5 | 1 << 16 | 0 << 11 | 1 << 9 \n\t");
+
+ base = &mxu->csr;
+ asm volatile(".word 0x7010f803 | 9 << 6 \n\t"); // t1 <- mxu.csr
+ asm volatile(".word 0xac000000 | 8 << 21 | 9 << 16 \n\t"); // sw $t1 0($t0)
+#else
+ base = &mxu->vpr[0];
+ SA(o, VR0, 0, base, 0);
+ SA(o, VR0, 1, base, 32);
+
+ base = &mxu->vpr[1];
+ SA(o, VR1, 0, base, 0);
+ SA(o, VR1, 1, base, 32);
+
+ base = &mxu->vpr[2];
+ SA(o, VR2, 0, base, 0);
+ SA(o, VR2, 1, base, 32);
+
+ base = &mxu->vpr[3];
+ SA(o, VR3, 0, base, 0);
+ SA(o, VR3, 1, base, 32);
+
+ base = &mxu->vpr[4];
+ SA(o, VR4, 0, base, 0);
+ SA(o, VR4, 1, base, 32);
+
+ base = &mxu->vpr[5];
+ SA(o, VR5, 0, base, 0);
+ SA(o, VR5, 1, base, 32);
+
+ base = &mxu->vpr[6];
+ SA(o, VR6, 0, base, 0);
+ SA(o, VR6, 1, base, 32);
+
+ base = &mxu->vpr[7];
+ SA(o, VR7, 0, base, 0);
+ SA(o, VR7, 1, base, 32);
+
+ base = &mxu->vpr[8];
+ SA(o, VR8, 0, base, 0);
+ SA(o, VR8, 1, base, 32);
+
+ base = &mxu->vpr[9];
+ SA(o, VR9, 0, base, 0);
+ SA(o, VR9, 1, base, 32);
+
+ base = &mxu->vpr[10];
+ SA(o, VR10, 0, base, 0);
+ SA(o, VR10, 1, base, 32);
+
+ base = &mxu->vpr[11];
+ SA(o, VR11, 0, base, 0);
+ SA(o, VR11, 1, base, 32);
+
+ base = &mxu->vpr[12];
+ SA(o, VR12, 0, base, 0);
+ SA(o, VR12, 1, base, 32);
+
+ base = &mxu->vpr[13];
+ SA(o, VR13, 0, base, 0);
+ SA(o, VR13, 1, base, 32);
+
+ base = &mxu->vpr[14];
+ SA(o, VR14, 0, base, 0);
+ SA(o, VR14, 1, base, 32);
+
+ base = &mxu->vpr[15];
+ SA(o, VR15, 0, base, 0);
+ SA(o, VR15, 1, base, 32);
+
+ base = &mxu->vpr[16];
+ SA(o, VR16, 0, base, 0);
+ SA(o, VR16, 1, base, 32);
+
+ base = &mxu->vpr[17];
+ SA(o, VR17, 0, base, 0);
+ SA(o, VR17, 1, base, 32);
+
+ base = &mxu->vpr[18];
+ SA(o, VR18, 0, base, 0);
+ SA(o, VR18, 1, base, 32);
+
+ base = &mxu->vpr[19];
+ SA(o, VR19, 0, base, 0);
+ SA(o, VR19, 1, base, 32);
+
+ base = &mxu->vpr[20];
+ SA(o, VR20, 0, base, 0);
+ SA(o, VR20, 1, base, 32);
+
+ base = &mxu->vpr[21];
+ SA(o, VR21, 0, base, 0);
+ SA(o, VR21, 1, base, 32);
+
+ base = &mxu->vpr[22];
+ SA(o, VR22, 0, base, 0);
+ SA(o, VR22, 1, base, 32);
+
+ base = &mxu->vpr[23];
+ SA(o, VR23, 0, base, 0);
+ SA(o, VR23, 1, base, 32);
+
+ base = &mxu->vpr[24];
+ SA(o, VR24, 0, base, 0);
+ SA(o, VR24, 1, base, 32);
+
+ base = &mxu->vpr[25];
+ SA(o, VR25, 0, base, 0);
+ SA(o, VR25, 1, base, 32);
+
+ base = &mxu->vpr[26];
+ SA(o, VR26, 0, base, 0);
+ SA(o, VR26, 1, base, 32);
+
+ base = &mxu->vpr[27];
+ SA(o, VR27, 0, base, 0);
+ SA(o, VR27, 1, base, 32);
+
+ base = &mxu->vpr[28];
+ SA(o, VR28, 0, base, 0);
+ SA(o, VR28, 1, base, 32);
+
+ base = &mxu->vpr[29];
+ SA(o, VR29, 0, base, 0);
+ SA(o, VR29, 1, base, 32);
+
+ base = &mxu->vpr[30];
+ SA(o, VR30, 0, base, 0);
+ SA(o, VR30, 1, base, 32);
+
+ base = &mxu->vpr[31];
+ SA(o, VR31, 0, base, 0);
+ SA(o, VR31, 1, base, 32);
+
+ base = &mxu->vsr[0];
+ MFSUM(VR0, VS0);
+ SA(o, VR0, 0, base, 0);
+ SA(o, VR0, 1, base, 32);
+
+ base = &mxu->vsr[1];
+ MFSUM(VR0, VS1);
+ SA(o, VR0, 0, base, 0);
+ SA(o, VR0, 1, base, 32);
+
+ base = &mxu->vsr[2];
+ MFSUM(VR0, VS2);
+ SA(o, VR0, 0, base, 0);
+ SA(o, VR0, 1, base, 32);
+
+ base = &mxu->vsr[3];
+ MFSUM(VR0, VS3);
+ SA(o, VR0, 0, base, 0);
+ SA(o, VR0, 1, base, 32);
+
+ base = &mxu->csr;
+ CFCMXU(base1, 31);
+ asm volatile("sw $t1, 0($t0)\n\t");
+#endif
+}
+
+__attribute__((optimize("O0")))
+void __restore_mxuv3(void * tsk_void)
+{
+ register void *base asm("t0");
+ struct task_struct *tsk = tsk_void;
+ struct xburst_mxu_struct *mxu = &tsk->thread.mxu;
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d, , KSTK_STATUS(tsk)=0x%lx, task->tgid=%d, task->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), KSTK_STATUS(current), current->tgid, current->pid, KSTK_STATUS(tsk), tsk->tgid, tsk->pid);
+ //dump_stack();
+ //printk("%s(%d):smp_processor_id()=%d, read_c0_status()=0x%x, task_cpu(current)=%d, KSTK_STATUS(current)=0x%lx, current->tgid=%d, current->pid=%d, task_cpu(p)=%d, KSTK_STATUS(p)=0x%lx, p->tgid=%d, p->pid=%d\n", __func__, __LINE__, smp_processor_id(), read_c0_status(), task_cpu(current), KSTK_STATUS(current), current->tgid, current->pid, task_cpu(tsk), KSTK_STATUS(tsk), tsk->tgid, tsk->pid);
+#ifdef WORDCODE
+ /**
+ * lao ins: hex(0x70001811 | 8 << 21 | 1 << 16 | 1 << 14 | 0 << 6)
+ * cmd: 0x70001811 ->la0
+ * base: 8 ->t0
+ * offset: 1 ->32>>5
+ * nn: 1 ->nn // o means to be divided by 512/256=2, so n=[0,1]
+ * vpr: 0 ->vpr0
+ * because t0 is fixed, so 0x70001811 | 8 << 21 = 0x71001811
+ * so the word format as follows:
+ * asm volatile(".word 0x71001811 | offset << 16 | n << 14 | vprn << 6 \n\t");
+ *
+ * mtsum ins: hex(0x4a60001d | vrs << 16 | vsd << 6)
+ * for we fixed vrs to 0, so the word format as follows:
+ * asm volatile(".word 0x4a60001d | vss << 6 \n\t");
+ */
+ base = &mxu->csr;
+ asm volatile(".word 0x8c000000 | 8 << 21 | 9 << 16\n\t");// lw $t1, 0($t0)
+ asm volatile(".word 0x7011f803 | 9 << 21 \n\t");// mxu.csr <- t1
+
+ base = &mxu->vsr[0];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x4a60001d | 0 << 6 \n\t");
+
+ base = &mxu->vsr[1];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x4a60001d | 1 << 6 \n\t");
+
+ base = &mxu->vsr[2];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x4a60001d | 2 << 6 \n\t");
+
+ base = &mxu->vsr[3];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x4a60001d | 3 << 6 \n\t");
+
+ base = &mxu->vpr[0];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 0 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 0 << 6 \n\t");
+
+ base = &mxu->vpr[1];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 1 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 1 << 6 \n\t");
+
+ base = &mxu->vpr[2];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 2 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 2 << 6 \n\t");
+
+ base = &mxu->vpr[3];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 3 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 3 << 6 \n\t");
+
+ base = &mxu->vpr[4];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 4 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 4 << 6 \n\t");
+
+ base = &mxu->vpr[5];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 5 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 5 << 6 \n\t");
+
+ base = &mxu->vpr[6];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 6 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 6 << 6 \n\t");
+
+ base = &mxu->vpr[7];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 7 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 7 << 6 \n\t");
+
+ base = &mxu->vpr[8];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 8 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 8 << 6 \n\t");
+
+ base = &mxu->vpr[9];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 9 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 9 << 6 \n\t");
+
+ base = &mxu->vpr[10];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 10 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 10 << 6 \n\t");
+
+ base = &mxu->vpr[11];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 11 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 11 << 6 \n\t");
+
+ base = &mxu->vpr[12];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 12 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 12 << 6 \n\t");
+
+ base = &mxu->vpr[13];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 13 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 13 << 6 \n\t");
+
+ base = &mxu->vpr[14];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 14 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 14 << 6 \n\t");
+
+ base = &mxu->vpr[15];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 15 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 15 << 6 \n\t");
+
+ base = &mxu->vpr[16];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 16 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 16 << 6 \n\t");
+
+ base = &mxu->vpr[17];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 17 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 17 << 6 \n\t");
+
+ base = &mxu->vpr[18];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 18 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 18 << 6 \n\t");
+
+ base = &mxu->vpr[19];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 19 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 19 << 6 \n\t");
+
+ base = &mxu->vpr[20];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 20 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 20 << 6 \n\t");
+
+ base = &mxu->vpr[21];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 21 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 21 << 6 \n\t");
+
+ base = &mxu->vpr[22];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 22 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 22 << 6 \n\t");
+
+ base = &mxu->vpr[23];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 23 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 23 << 6 \n\t");
+
+ base = &mxu->vpr[24];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 24 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 24 << 6 \n\t");
+
+ base = &mxu->vpr[25];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 25 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 25 << 6 \n\t");
+
+ base = &mxu->vpr[26];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 26 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 26 << 6 \n\t");
+
+ base = &mxu->vpr[27];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 27 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 27 << 6 \n\t");
+
+ base = &mxu->vpr[28];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 28 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 28 << 6 \n\t");
+
+ base = &mxu->vpr[29];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 29 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 29 << 6 \n\t");
+
+ base = &mxu->vpr[30];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 30 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 30 << 6 \n\t");
+
+ base = &mxu->vpr[31];
+ asm volatile(".word 0x71001811 | 0 << 16 | 0 << 14 | 31 << 6 \n\t");
+ asm volatile(".word 0x71001811 | 1 << 16 | 1 << 14 | 31 << 6 \n\t");
+#else
+ base = &mxu->csr;
+ asm volatile("lw $t1, 0($t0)\n\t");
+ CTCMXU(31, base1);
+
+ base = &mxu->vsr[0];
+ LA(o, VR0, 0, base, 0);
+ LA(o, VR0, 1, base, 32);
+ MTSUM(VS0, VR0);
+
+ base = &mxu->vsr[1];
+ LA(o, VR0, 0, base, 0);
+ LA(o, VR0, 1, base, 32);
+ MTSUM(VS1, VR0);
+
+ base = &mxu->vsr[2];
+ LA(o, VR0, 0, base, 0);
+ LA(o, VR0, 1, base, 32);
+ MTSUM(VS2, VR0);
+
+ base = &mxu->vsr[3];
+ LA(o, VR0, 0, base, 0);
+ LA(o, VR0, 1, base, 32);
+ MTSUM(VS3, VR0);
+
+ base = &mxu->vpr[0];
+ LA(o, VR0, 0, base, 0);
+ LA(o, VR0, 1, base, 32);
+
+ base = &mxu->vpr[1];
+ LA(o, VR1, 0, base, 0);
+ LA(o, VR1, 1, base, 32);
+
+ base = &mxu->vpr[2];
+ LA(o, VR2, 0, base, 0);
+ LA(o, VR2, 1, base, 32);
+
+ base = &mxu->vpr[3];
+ LA(o, VR3, 0, base, 0);
+ LA(o, VR3, 1, base, 32);
+
+ base = &mxu->vpr[4];
+ LA(o, VR4, 0, base, 0);
+ LA(o, VR4, 1, base, 32);
+
+ base = &mxu->vpr[5];
+ LA(o, VR5, 0, base, 0);
+ LA(o, VR5, 1, base, 32);
+
+ base = &mxu->vpr[6];
+ LA(o, VR6, 0, base, 0);
+ LA(o, VR6, 1, base, 32);
+
+ base = &mxu->vpr[7];
+ LA(o, VR7, 0, base, 0);
+ LA(o, VR7, 1, base, 32);
+
+ base = &mxu->vpr[8];
+ LA(o, VR8, 0, base, 0);
+ LA(o, VR8, 1, base, 32);
+
+ base = &mxu->vpr[9];
+ LA(o, VR9, 0, base, 0);
+ LA(o, VR9, 1, base, 32);
+
+ base = &mxu->vpr[10];
+ LA(o, VR10, 0, base, 0);
+ LA(o, VR10, 1, base, 32);
+
+ base = &mxu->vpr[11];
+ LA(o, VR11, 0, base, 0);
+ LA(o, VR11, 1, base, 32);
+
+ base = &mxu->vpr[12];
+ LA(o, VR12, 0, base, 0);
+ LA(o, VR12, 1, base, 32);
+
+ base = &mxu->vpr[13];
+ LA(o, VR13, 0, base, 0);
+ LA(o, VR13, 1, base, 32);
+
+ base = &mxu->vpr[14];
+ LA(o, VR14, 0, base, 0);
+ LA(o, VR14, 1, base, 32);
+
+ base = &mxu->vpr[15];
+ LA(o, VR15, 0, base, 0);
+ LA(o, VR15, 1, base, 32);
+
+ base = &mxu->vpr[16];
+ LA(o, VR16, 0, base, 0);
+ LA(o, VR16, 1, base, 32);
+
+ base = &mxu->vpr[17];
+ LA(o, VR17, 0, base, 0);
+ LA(o, VR17, 1, base, 32);
+
+ base = &mxu->vpr[18];
+ LA(o, VR18, 0, base, 0);
+ LA(o, VR18, 1, base, 32);
+
+ base = &mxu->vpr[19];
+ LA(o, VR19, 0, base, 0);
+ LA(o, VR19, 1, base, 32);
+
+ base = &mxu->vpr[20];
+ LA(o, VR20, 0, base, 0);
+ LA(o, VR20, 1, base, 32);
+
+ base = &mxu->vpr[21];
+ LA(o, VR21, 0, base, 0);
+ LA(o, VR21, 1, base, 32);
+
+ base = &mxu->vpr[22];
+ LA(o, VR22, 0, base, 0);
+ LA(o, VR22, 1, base, 32);
+
+ base = &mxu->vpr[23];
+ LA(o, VR23, 0, base, 0);
+ LA(o, VR23, 1, base, 32);
+
+ base = &mxu->vpr[24];
+ LA(o, VR24, 0, base, 0);
+ LA(o, VR24, 1, base, 32);
+
+ base = &mxu->vpr[25];
+ LA(o, VR25, 0, base, 0);
+ LA(o, VR25, 1, base, 32);
+
+ base = &mxu->vpr[26];
+ LA(o, VR26, 0, base, 0);
+ LA(o, VR26, 1, base, 32);
+
+ base = &mxu->vpr[27];
+ LA(o, VR27, 0, base, 0);
+ LA(o, VR27, 1, base, 32);
+
+ base = &mxu->vpr[28];
+ LA(o, VR28, 0, base, 0);
+ LA(o, VR28, 1, base, 32);
+
+ base = &mxu->vpr[29];
+ LA(o, VR29, 0, base, 0);
+ LA(o, VR29, 1, base, 32);
+
+ base = &mxu->vpr[30];
+ LA(o, VR30, 0, base, 0);
+ LA(o, VR30, 1, base, 32);
+
+ base = &mxu->vpr[31];
+ LA(o, VR31, 0, base, 0);
+ LA(o, VR31, 1, base, 32);
+#endif
+}

View File

@ -0,0 +1,70 @@
diff -drupN a/arch/mips/xburst2/common/proc-exec.c b/arch/mips/xburst2/common/proc-exec.c
--- a/arch/mips/xburst2/common/proc-exec.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/proc-exec.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,66 @@
+#include <linux/proc_fs.h>
+#include <linux/syscalls.h>
+#include <linux/kmod.h>
+#include <asm/uaccess.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+static int exec_write_proc(struct file *file, const char __user *buffer, size_t count, loff_t *data)
+{
+ char buf[128];
+ char tmp[3][64];
+ char* argv[4];
+ char* envp[] = {"HOME=/", "PATH=/sbin:/bin:/system/bin", NULL};
+ char tmp_one;
+ int i,j=0,k=0;
+
+ memset(buf, 0, sizeof(buf));
+ memset(tmp, 0, sizeof(tmp));
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+ for (i = 0; i < count; i++) {
+ strncpy(&tmp_one, &buf[i], 1);
+ if (!strncmp(&tmp_one, ":", 1)) {
+ if (j == 0)
+ strncpy(&tmp[j][0], buf, i);
+ else
+ strncpy(&tmp[j][0], &buf[i+1], (i - k));
+ k = i;
+ j++;
+ } else if (i == (count - 1)) {
+ if (j == 0)
+ strncpy(tmp[j], buf, i);
+ else
+ strncpy(&tmp[j][0], &buf[k+1], (i - k));
+ }
+ }
+ argv[0] = &tmp[0][0];
+ argv[3] = NULL;
+
+ if (j == 0) {
+ argv[1] = NULL;
+ argv[2] = NULL;
+ } else if (j == 1) {
+ argv[1] = &tmp[1][0];
+ argv[2] = NULL;
+ } else if (j == 2) {
+ argv[1] = &tmp[1][0];
+ argv[2] = &tmp[2][0];
+ }
+
+ call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+ return count;
+}
+
+static const struct file_operations exec_proc_fops ={
+ .write = exec_write_proc,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+static int __init init_proc_exec(void)
+{
+ proc_create("proc-exec",0600,NULL,&exec_proc_fops);
+ return 0;
+}
+
+module_init(init_proc_exec);
+

View File

@ -0,0 +1,97 @@
diff -drupN a/arch/mips/xburst2/common/proc.c b/arch/mips/xburst2/common/proc.c
--- a/arch/mips/xburst2/common/proc.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/common/proc.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,93 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/page-flags.h>
+#include <asm/uaccess.h>
+#include <jz_proc.h>
+static struct proc_dir_entry *proc_jz_root;
+struct proc_dir_entry * jz_proc_mkdir(char *s)
+{
+ struct proc_dir_entry *p;
+ if(!proc_jz_root) {
+ proc_jz_root = proc_mkdir("jz", 0);
+ if(!proc_jz_root)
+ return NULL;
+ }
+ p = proc_mkdir(s,proc_jz_root);
+ return p;
+}
+
+EXPORT_SYMBOL(jz_proc_mkdir);
+
+static int jz_proc_show(struct seq_file *filq, void *v)
+{
+ int ret = 1;
+ struct jz_single_file_ops *proc_fops = filq->private;
+ filq->private = proc_fops->data;
+
+ if(proc_fops->read)
+ ret = proc_fops->read(filq, v);
+
+ filq->private = proc_fops;
+ return ret;
+}
+static int jz_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, jz_proc_show, PDE_DATA(inode));
+}
+static ssize_t jz_proc_write(struct file *file, const char __user *buffer, size_t usize, loff_t *off)
+{
+ size_t ret;
+ struct jz_single_file_ops *proc_fops = ((struct seq_file *)file->private_data)->private;
+ ((struct seq_file *)file->private_data)->private = proc_fops->data;
+
+ ret = proc_fops->write(file, buffer, usize, off);
+ ((struct seq_file *)file->private_data)->private = proc_fops;
+
+ return ret;
+}
+
+struct proc_dir_entry *jz_proc_create_data(
+ const char *name, umode_t mode, struct proc_dir_entry *parent,
+ struct jz_single_file_ops *proc_fops, void *data)
+{
+ struct file_operations *jz_proc_fops;
+
+ jz_proc_fops = kmalloc(sizeof(struct file_operations), GFP_KERNEL);
+ if(!jz_proc_fops) {
+ return NULL;
+ }
+
+ jz_proc_fops->owner = THIS_MODULE;
+ jz_proc_fops->read = seq_read;
+ jz_proc_fops->llseek = seq_lseek;
+ jz_proc_fops->release = single_release;
+ jz_proc_fops->open = jz_proc_open;
+ jz_proc_fops->write = jz_proc_write;
+ proc_fops->data = data;
+
+ return proc_create_data(name, mode, parent, jz_proc_fops, proc_fops);
+}
+
+struct proc_dir_entry *jz_proc_create(
+ const char *name, umode_t mode, struct proc_dir_entry *parent,
+ struct jz_single_file_ops *proc_fops)
+{
+ return jz_proc_create_data(name, mode, parent, proc_fops, NULL);
+}
+
+struct proc_dir_entry * get_jz_proc_root(void)
+{
+ if(!proc_jz_root) {
+ proc_jz_root = proc_mkdir("jz", 0);
+ if(!proc_jz_root)
+ return NULL;
+ }
+ return proc_jz_root;
+}

View File

@ -0,0 +1,10 @@
diff -drupN a/arch/mips/xburst2/core/Makefile b/arch/mips/xburst2/core/Makefile
--- a/arch/mips/xburst2/core/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,6 @@
+obj-y += prom.o
+
+obj-$(CONFIG_XBURST2_CPU_SCACHE) += sc.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_PMON_DEBUG) += perf_proc_jz.o perf_event_jz.o
+

View File

@ -0,0 +1,46 @@
diff -drupN a/arch/mips/xburst2/core/include/ccu.h b/arch/mips/xburst2/core/include/ccu.h
--- a/arch/mips/xburst2/core/include/ccu.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/ccu.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,42 @@
+
+#ifndef __CCU_H__
+#define __CCU_H__
+
+#include <core_base.h>
+#define CCU_RESET_ENTRY 0xbfc00000
+
+#define get_ccu_cscr() inl(CCU_IO_BASE + 0)
+#define set_ccu_cscr(val) outl(val, CCU_IO_BASE + 0)
+
+#define get_ccu_cssr() inl(CCU_IO_BASE + 0x20)
+
+#define get_ccu_csrr() inl(CCU_IO_BASE + 0x40)
+#define set_ccu_csrr(val) outl(val, CCU_IO_BASE + 0x40)
+
+#define get_ccu_pipr() inl(CCU_IO_BASE + 0x100)
+
+#define get_ccu_pimr() inl(CCU_IO_BASE + 0x120)
+#define set_ccu_pimr(val) outl(val, CCU_IO_BASE + 0x120)
+
+#define get_ccu_mipr() inl(CCU_IO_BASE + 0x140)
+
+#define get_ccu_mimr() inl(CCU_IO_BASE + 0x160)
+#define set_ccu_mimr(val) outl(val, CCU_IO_BASE + 0x160)
+
+#define get_ccu_oipr() inl(CCU_IO_BASE + 0x180)
+
+#define get_ccu_oimr() inl(CCU_IO_BASE + 0x1a0)
+#define set_ccu_oimr(val) outl(val, CCU_IO_BASE + 0x1a0)
+
+#define get_ccu_rer() inl(CCU_IO_BASE + 0xf00)
+#define set_ccu_rer(val) outl(val, CCU_IO_BASE + 0xf00)
+
+#define get_ccu_cslr() inl(CCU_IO_BASE + 0xff8)
+#define set_ccu_cslr(val) outl(val, CCU_IO_BASE + 0xff8)
+
+#define get_ccu_csar() inl(CCU_IO_BASE + 0xffc)
+#define set_ccu_csar(val) outl(val, CCU_IO_BASE + 0xffc)
+
+//#define get_ccu_mbr(cpu_id) inl(CCU_IO_BASE + 0x1000 + cpu_id*4)
+//#define set_ccu_mbr(cpu_id, val) outl(val, CCU_IO_BASE + 0x1000 + cpu_id*4)
+#endif

View File

@ -0,0 +1,19 @@
diff -drupN a/arch/mips/xburst2/core/include/core_base.h b/arch/mips/xburst2/core/include/core_base.h
--- a/arch/mips/xburst2/core/include/core_base.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/core_base.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,15 @@
+#ifndef __CORE_BASE_H__
+#define __CORE_BASE_H__
+
+/* for xburst2 INTC base 0x12300000*/
+#define INTC_IOBASE 0x12300000
+/* CCU IO base address */
+//#define CCU_IO_BASE (read_c0_config7 & 0xffff0000)
+#define CCU_IO_BASE 0x12200000
+
+/* core system ost interrupte timer. core system ost. xburst2 */
+#define CORE_OST_IOBASE 0x12100000
+/* global system ost timer for jiffies. xburst2 */
+#define G_OST_IOBASE 0x12000000
+
+#endif /* __CORE_BASE_H__ */

View File

@ -0,0 +1,10 @@
diff -drupN a/arch/mips/xburst2/core/include/irq_cpu.h b/arch/mips/xburst2/core/include/irq_cpu.h
--- a/arch/mips/xburst2/core/include/irq_cpu.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/irq_cpu.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,6 @@
+#ifndef IRQ_CPU_H
+#define IRQ_CPU_H
+
+void ingenic_irq_migration(int lock);
+void ingenic_irq_cpumask_idle(int idle);
+#endif /* IRQ_CPU_H */

View File

@ -0,0 +1,49 @@
diff -drupN a/arch/mips/xburst2/core/include/jz_notifier.h b/arch/mips/xburst2/core/include/jz_notifier.h
--- a/arch/mips/xburst2/core/include/jz_notifier.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/jz_notifier.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,45 @@
+#ifndef _JZ_NOTIFIER_H_
+#define _JZ_NOTIFIER_H_
+
+#include <linux/notifier.h>
+
+/*
+ * Hibernation and suspend events
+ */
+enum jz_notif_cmd {
+ JZ_CMD_START = 0,
+ JZ_CLK_PRECHANGE,
+ JZ_CLK_CHANGING,
+ JZ_CLK_CHANGED,
+ JZ_CLKGATE_CHANGE,
+ JZ_POST_HIBERNATION, /* Hibernation finished */
+ JZ_PM_SUSPEND_STANDBY, /* Hibernation finished */
+ MMU_CONTEXT_EXIT_MMAP,
+ JZ_CMD_END
+};
+enum {
+ NOTEFY_PROI_START=1,
+ NOTEFY_PROI_HIGH,
+ NOTEFY_PROI_NORMAL,
+ NOTEFY_PROI_LOW,
+ NOTEFY_PROI_END
+};
+
+struct clk_notify_data
+{
+ unsigned long current_rate;
+ unsigned long target_rate;
+};
+
+struct jz_notifier {
+ struct notifier_block nb;
+ int (*jz_notify)(struct jz_notifier *notify,void *d);
+ int level;
+ enum jz_notif_cmd msg;
+};
+
+int jz_notifier_register(struct jz_notifier *notify, unsigned int priority);
+int jz_notifier_unregister(struct jz_notifier *notify, unsigned int priority);
+int jz_notifier_call(unsigned int priority, unsigned long val, void *v);
+
+#endif /* _JZ_NOTIFIER_H_ */

View File

@ -0,0 +1,22 @@
diff -drupN a/arch/mips/xburst2/core/include/jz_proc.h b/arch/mips/xburst2/core/include/jz_proc.h
--- a/arch/mips/xburst2/core/include/jz_proc.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/jz_proc.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,18 @@
+#ifndef _JZ_PROC_H_
+#define _JZ_PROC_H_
+
+struct jz_single_file_ops {
+ ssize_t (*read) (struct seq_file *, void *);
+ ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
+ void *data;
+};
+
+struct proc_dir_entry * jz_proc_mkdir(char *s);
+struct proc_dir_entry *jz_proc_create_data(
+ const char *name, umode_t mode, struct proc_dir_entry *parent,
+ struct jz_single_file_ops *proc_fops, void *data);
+struct proc_dir_entry *jz_proc_create(
+ const char *name, umode_t mode, struct proc_dir_entry *parent,
+ struct jz_single_file_ops *proc_fops);
+struct proc_dir_entry * get_jz_proc_root(void);
+#endif /* _JZ_PROC_H_ */

View File

@ -0,0 +1,57 @@
diff -drupN a/arch/mips/xburst2/core/include/mxu.h b/arch/mips/xburst2/core/include/mxu.h
--- a/arch/mips/xburst2/core/include/mxu.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/mxu.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2005 Mips Technologies
+ * Author: Chris Dearman, chris@mips.com derived from fpu.h
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_MXU_H
+#define _ASM_MXU_H
+
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+#include <mxu_media.h>
+
+#define NUM_MXU_REGS (0)
+
+/* There is no mxu implement in XBURST2, leave empty */
+static inline void __init_mxu(void)
+{
+}
+static inline void __save_mxu(void * tsk_void)
+{
+}
+static inline void __restore_mxu(void * tsk_void)
+{
+}
+
+static inline void init_mxu(void)
+{
+ if(cpu_has_mxu)
+ __init_mxu();
+}
+
+
+#define save_mxu(tsk) \
+ do { \
+ if (cpu_has_mxu) \
+ __save_mxu(tsk); \
+ } while (0)
+
+#define restore_mxu(tsk) \
+ do { \
+ if (cpu_has_mxu) \
+ __restore_mxu(tsk); \
+ } while (0)
+
+
+#endif /* _ASM_MXU_H */

View File

@ -0,0 +1,46 @@
diff -drupN a/arch/mips/xburst2/core/include/mxuv3.h b/arch/mips/xburst2/core/include/mxuv3.h
--- a/arch/mips/xburst2/core/include/mxuv3.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/include/mxuv3.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005 Mips Technologies
+ * Author: Chris Dearman, chris@mips.com derived from fpu.h
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_MXU_V3_H
+#define _ASM_MXU_V3_H
+
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+#include <linux/printk.h>
+
+void __init_mxuv3(void);
+void __save_mxuv3(void *tsk_void);
+void __restore_mxuv3(void *tsk_void);
+
+static inline void init_mxuv3(void)
+{
+ if(cpu_has_mxuv3)
+ __init_mxuv3();
+}
+
+
+#define save_mxuv3(tsk) \
+ do { \
+ if (cpu_has_mxuv3) \
+ __save_mxuv3(tsk); \
+ } while (0)
+
+#define restore_mxuv3(tsk) \
+ do { \
+ if (cpu_has_mxuv3) \
+ __restore_mxuv3(tsk); \
+ } while (0)
+
+#endif /* _ASM_MXU_V3_H */

View File

@ -0,0 +1,83 @@
diff -drupN a/arch/mips/xburst2/core/prom.c b/arch/mips/xburst2/core/prom.c
--- a/arch/mips/xburst2/core/prom.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/prom.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC prom code
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+#include <linux/of_fdt.h>
+
+#include <soc/base.h>
+
+static __init void prom_init_cmdline(int argc, char *argv[])
+{
+ unsigned int count = COMMAND_LINE_SIZE - 1;
+ int i;
+ char *dst = &(arcs_cmdline[0]);
+ char *src;
+
+ for (i = 1; i < argc && count; ++i) {
+ src = argv[i];
+ while (*src && count) {
+ *dst++ = *src++;
+ --count;
+ }
+ *dst++ = ' ';
+ }
+ if (i > 1)
+ --dst;
+
+ *dst = 0;
+}
+extern struct plat_smp_ops xburst2_smp_ops;
+static void *_fw_fdt_addr;
+
+void __init prom_init(void)
+{
+ prom_init_cmdline((int)fw_arg0, (char **)fw_arg1);
+
+ if (fw_arg0 == 0 && fw_arg1 == 0xffffffffUL)
+ _fw_fdt_addr = phys_to_virt(fw_arg2);
+ else if ((int)fw_arg0 == -2) /*UHI*/
+ _fw_fdt_addr = (void *)fw_arg1;
+ else if (__dtb_start != __dtb_end)
+ _fw_fdt_addr = __dtb_start;
+ else
+ panic("no dtb found!\n");
+
+ mips_machtype = MACH_XBURST2;
+#ifdef CONFIG_SMP
+ register_smp_ops(&xburst2_smp_ops);
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+const char *get_system_type(void)
+{
+// return CONFIG_BOARD_NAME;
+ return "xburst2-based";
+}
+void __init *get_fdt_addr(void)
+{
+ return _fw_fdt_addr;
+}

View File

@ -0,0 +1,203 @@
diff -drupN a/arch/mips/xburst2/core/sc.c b/arch/mips/xburst2/core/sc.c
--- a/arch/mips/xburst2/core/sc.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/sc.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2006 Chris Dearman (chris@mips.com),
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcache.h>
+
+/*
+ * MIPS32/MIPS64 L2 cache handling
+ */
+static unsigned long scache_size __read_mostly;
+/*
+ * Writeback and invalidate the secondary cache before DMA.
+ */
+static void mips_sc_wback_inv(unsigned long addr, unsigned long size)
+{
+ __sync();
+ if (size >= scache_size) {
+ unsigned long lsize = cpu_scache_line_size();
+ if (lsize == 64)
+ blast_scache64();
+ else if (lsize == 32)
+ blast_scache32();
+ else
+ printk("Error: Second CacheLine size.\n");
+ } else {
+ blast_scache_range(addr, addr + size);
+ }
+#ifdef MIPS_BRIDGE_SYNC_WAR
+ if (MIPS_BRIDGE_SYNC_WAR)
+ __fast_iob();
+#endif
+}
+
+/*
+ * Invalidate the secondary cache before DMA.
+ */
+static void mips_sc_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long lsize = cpu_scache_line_size();
+ unsigned long almask = ~(lsize - 1);
+
+ if (size >= scache_size) {
+ if (lsize == 64)
+ blast_scache64();
+ else if (lsize == 32)
+ blast_scache32();
+ else
+ printk("Error: Second CacheLine size.\n");
+ }else {
+ cache_op(Hit_Writeback_Inv_SD, addr & almask);
+ cache_op(Hit_Writeback_Inv_SD, (addr + size - 1) & almask);
+ blast_inv_scache_range(addr, addr + size);
+ }
+#ifdef MIPS_BRIDGE_SYNC_WAR
+ if (MIPS_BRIDGE_SYNC_WAR)
+ __fast_iob();
+#endif
+}
+
+static void mips_sc_enable(void)
+{
+ /* L2 cache is permanently enabled */
+}
+
+static void mips_sc_disable(void)
+{
+ /* L2 cache is permanently enabled */
+}
+
+static struct bcache_ops mips_sc_ops = {
+ .bc_enable = mips_sc_enable,
+ .bc_disable = mips_sc_disable,
+ .bc_wback_inv = mips_sc_wback_inv,
+ .bc_inv = mips_sc_inv
+};
+
+/*
+ * Check if the L2 cache controller is activated on a particular platform.
+ * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS
+ * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the
+ * cache being disabled. However there is no guarantee for this to be
+ * true on all platforms. In an act of stupidity the spec defined bits
+ * 12..15 as implementation defined so below function will eventually have
+ * to be replaced by a platform specific probe.
+ */
+//static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
+//{
+// unsigned int config2 = read_c0_config2();
+// unsigned int tmp;
+//
+// /* Check the bypass bit (L2B) */
+// /*switch (c->cputype) {
+// case CPU_34K:
+// case CPU_74K:
+// case CPU_1004K:
+// case CPU_BMIPS5000:
+// if (config2 & (1 << 12))
+// return 0;
+// }*/
+//
+// tmp = (config2 >> 4) & 0x0f;
+// if (0 < tmp && tmp <= 7)
+// c->scache.linesz = 2 << tmp;
+// else
+// return 0;
+// return 1;
+//}
+
+static inline int __init mips_sc_probe(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config1, config2;
+ unsigned int tmp;
+
+ /* Mark as not present until probe completed */
+ c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
+
+ /* Ignore anything but MIPSxx processors */
+ if((c->isa_level & (MIPS_CPU_ISA_M32R1
+ | MIPS_CPU_ISA_M32R1
+ | MIPS_CPU_ISA_M64R1
+ | MIPS_CPU_ISA_M64R2)) == 0) {
+ return 0;
+ }
+
+ switch (c->processor_id & PRID_CPU_FEATURE_MASK) {
+ case PRID_CPU_X2000:
+ break;
+ default:
+ printk("pls check processor_id[0x%08x],sc_jz not support!\n",c->processor_id);
+ }
+
+ /* Does this MIPS32/MIPS64 CPU have a config2 register? */
+ config1 = read_c0_config1();
+ if (!(config1 & MIPS_CONF_M))
+ return 0;
+
+ config2 = read_c0_config2();
+
+ //if (!mips_sc_is_activated(c))
+ tmp = (config2 >> 4) & 0x0f;
+ if (0 < tmp && tmp <= 7)
+ c->scache.linesz = 2 << tmp;
+ else
+ return 0;
+
+ tmp = (config2 >> 8) & 0x0f;
+ if (0 <= tmp && tmp <= 7)
+ c->scache.sets = 64 << tmp;
+ else
+ return 0;
+
+ tmp = (config2 >> 0) & 0x0f;
+ if ((tmp == 7) || (tmp == 15))
+ c->scache.ways = tmp + 1;
+ else
+ return 0;
+
+ c->scache.waysize = c->scache.sets * c->scache.linesz;
+ c->scache.waybit = __ffs(c->scache.waysize);
+
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+ scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
+ //write_c0_ecc(0x0);//verify xburst2 whether CP0-$26-0 is implemented.
+ return 1;
+}
+
+static char *way_string[] = { NULL, "direct mapped", "2-way",
+ "3-way", "4-way", "5-way", "6-way", "7-way", "8-way",
+ "9-way", "10-way", "11-way", "12-way",
+ "13-way", "14-way", "15-way", "16-way",
+};
+
+int mips_sc_init(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ int found = mips_sc_probe();
+ printk("=======found ...... ingenic sc cache ops ...!, found: %d\n\n", found);
+ if (found) {
+ mips_sc_enable();
+ bcops = &mips_sc_ops;
+ }
+
+ printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
+
+ c->options |= MIPS_CPU_INCLUSIVE_CACHES;
+ return found;
+}

View File

@ -0,0 +1,503 @@
diff -drupN a/arch/mips/xburst2/core/smp.c b/arch/mips/xburst2/core/smp.c
--- a/arch/mips/xburst2/core/smp.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/smp.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+//#define DEBUG
+//#define SMP_DEBUG
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/uasm.h>
+#include <asm/r4kcache.h>
+
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+
+
+#include <dt-bindings/interrupt-controller/mips-irq.h>
+
+#include <core_base.h>
+#include <ccu.h>
+
+#ifdef SMP_DEBUG
+static void xburst2_ccu_showregs(void)
+{
+ int cpu = smp_processor_id();
+ unsigned int val;
+ printk("CPU%d:\n",cpu);
+#define P(reg) do { \
+ val = get_ccu_##reg(); \
+ printk(#reg ":\t%08x\n", val); \
+ } while(0)
+
+ P(cscr); P(cssr); P(csrr); P(pipr); P(pimr);
+ P(mipr); P(mimr); P(oipr); P(oimr); P(rer);
+ P(cslr); P(csar);
+ //P(val); P(lock);
+ printk("cp0 status:\t%08x\n", read_c0_status());
+ printk("cp0 cause:\t%08x\n", read_c0_cause());
+}
+static void dump_code(const unsigned int *handler, const int count)
+{
+ int i;
+ pr_info("\t.set push\n");
+ pr_info("\t.set noreorder\n");
+
+ for (i = 0; i < count; i++)
+ pr_info("\t.word\t0x%08x\t\t# %p\n", handler[i], &handler[i]);
+
+ pr_info("\t.set\tpop\n");
+}
+#else
+static inline void xburst2_ccu_showregs(void) {}
+static inline void dump_code(const unsigned int *handler, const int count) {}
+#endif
+struct xburst2_mailbox{
+ raw_spinlock_t lock;
+ void *__iomem *iobase;
+};
+struct xburst2_smp {
+ unsigned long context_sp, context_gp;
+ unsigned long entry_base;
+ struct xburst2_mailbox mailbox[NR_CPUS];
+ struct xburst2_mailbox * __percpu* percpu_mailbox;
+};
+static struct xburst2_smp smp_core;
+void ingenic_percpu_timerevent_init(unsigned int cpu_num);
+void ingenic_percpu_irq_init(unsigned int cpu_num);
+
+static irqreturn_t xburst2_mbox_interrupt(int irq, void *data)
+{
+ unsigned int action = 0;
+ struct xburst2_mailbox *mailbox = *(struct xburst2_mailbox **)data;
+ raw_spin_lock(&mailbox->lock);
+ action = readl(mailbox->iobase);
+ writel(0,mailbox->iobase);
+ raw_spin_unlock(&mailbox->lock);
+ if (!action) {
+ pr_err("SMP[%d]:invalid mailboxes action is NULL\n",smp_processor_id());
+ goto ipi_finish;
+ }
+ if (action & SMP_CALL_FUNCTION) {
+ generic_smp_call_function_interrupt();
+ }
+
+ if (action & SMP_RESCHEDULE_YOURSELF) {
+ scheduler_ipi();
+ }
+ipi_finish:
+ return IRQ_HANDLED;
+}
+
+void percpu_mailbox_init(int cpu)
+{
+ smp_core.mailbox[cpu].iobase = ioremap(CCU_IO_BASE + cpu * 4 + 0x1000,4);
+ raw_spin_lock_init(&smp_core.mailbox[cpu].lock);
+ *this_cpu_ptr(smp_core.percpu_mailbox) = &smp_core.mailbox[cpu];
+ writel(0, smp_core.mailbox[cpu].iobase);
+ enable_percpu_irq(CORE_MAILBOX_IRQ, IRQ_TYPE_NONE);
+}
+/*
+ * Code to run on secondary just after probing the CPU
+ */
+static void xburst2_init_secondary(void)
+{
+ int cpu = smp_processor_id();
+ unsigned int mb_msk = get_ccu_mimr();
+ unsigned int pmsk = get_ccu_pimr();
+ unsigned int cpu_num = read_c0_ebase() & 0x1ff;
+// unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2;
+// int ret;
+ if(cpu == 0){
+ pr_info("BUG: cpu0 is booted.\n");
+ dump_stack();
+ while(1);
+ }
+ pr_info("#### now starting init for cpu : %d\n", cpu);
+ clear_c0_cause(CAUSEF_IP);
+ clear_c0_status(ST0_IM);
+ mb_msk |= 1 << cpu;
+ set_ccu_mimr(mb_msk);
+ percpu_mailbox_init(cpu);
+ pr_debug("percpu %x\n",read_c0_status());
+ ingenic_percpu_irq_init(cpu_num);
+ pmsk |= (1 << cpu);
+ set_ccu_pimr(pmsk);
+
+ /* jzcpu_timer_setup(); */
+
+ xburst2_ccu_showregs();
+ ingenic_percpu_timerevent_init(cpu_num);
+ set_ccu_oimr((1<<cpu) | get_ccu_oimr());
+}
+static bool migrate_one_irq(int cpu,struct irq_desc *desc)
+{
+ struct irq_data *d = irq_desc_get_irq_data(desc);
+ const struct cpumask *affinity = d->common->affinity;
+ struct irq_chip *c;
+ bool ret = false;
+
+ if (irqd_is_per_cpu(d) || !cpumask_test_cpu(cpu, affinity))
+ return false;
+
+ c = irq_data_get_irq_chip(d);
+ if(!c->irq_set_affinity)
+ return false;
+ if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+ affinity = cpu_online_mask;
+ ret = true;
+ }
+
+ if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret)
+ cpumask_copy(d->common->affinity, affinity);
+
+ return ret;
+}
+
+static void migrate_irqs(int cpu)
+{
+ unsigned int i;
+ struct irq_desc *desc;
+ for_each_irq_desc(i, desc) {
+ raw_spin_lock(&desc->lock);
+ migrate_one_irq(cpu,desc);
+ raw_spin_unlock(&desc->lock);
+ }
+}
+
+/*
+ * Do any tidying up before marking online and running the idle
+ * loop
+ */
+static void xburst2_smp_finish(void)
+{
+ int cpu = smp_processor_id();
+ migrate_irqs(cpu);
+ xburst2_ccu_showregs();
+ local_irq_enable();
+ pr_info("[SMP] slave cpu%d start up finished.\n",smp_processor_id());
+}
+static void build_bounce_code(struct xburst2_smp *smp)
+{
+ unsigned long *spp,*gpp;
+ unsigned int entry = (unsigned int)smp_bootstrap;
+ unsigned int *p;
+ p = (unsigned int*)__get_free_pages(GFP_KERNEL, 0);
+ spp = (unsigned long *)&smp->context_sp;
+ gpp = (unsigned long *)&smp->context_gp;
+ smp->entry_base = (unsigned int)p;
+
+#define STATUS_BITS (ST0_CU0)
+#define CAUSE_BITS (1 << 27)
+#define C0_CAUSE 13,0
+#define C0_STATUS 12,0
+#define C0_COUNT 9,0
+
+
+#define C0_CONFIG_0 16,0
+#define V0 2
+#define V1 3
+#define GP 28
+#define SP 29
+#define RA 31
+ /* the instructions'max size is 128 byte */
+
+ /* Disable IFU Small Buffer, system low power opt. */
+ UASM_i_MFC0(&p, V0, 16, 7);
+ uasm_i_ori(&p, V0, V0, 7 << 3);
+ UASM_i_MTC0(&p, V0, 16, 7);
+
+ /* kseg0 cache attribute */
+ UASM_i_MFC0(&p,V0,C0_CONFIG_0);
+ UASM_i_LA(&p,V1,~7);
+ uasm_i_and(&p,V0,V0,V1);
+ uasm_i_ori(&p,V0,V0,3);
+ UASM_i_MTC0(&p,V0,C0_CONFIG_0);
+
+ /* cause to DC disable. and status regitster reset */
+ UASM_i_LA(&p,V0,CAUSE_BITS);
+ UASM_i_MTC0(&p,V0,C0_CAUSE);
+
+ UASM_i_MTC0(&p,0,C0_COUNT);
+
+ UASM_i_LA(&p,V0,STATUS_BITS);
+ UASM_i_MTC0(&p,V0,C0_STATUS);
+
+ UASM_i_LA(&p, SP, (unsigned long)spp);
+ UASM_i_LW(&p, SP, 0,SP);
+ UASM_i_LA(&p, GP, (unsigned long)gpp);
+ UASM_i_LW(&p, GP, 0,GP);
+ UASM_i_LA(&p, RA, entry);
+ uasm_i_jr(&p, RA);
+ uasm_i_nop(&p);
+ dump_code((const unsigned int*)smp->entry_base,24);
+ //the code in ddr should be sure.
+ dma_cache_wback_inv(smp->entry_base,128);
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ */
+static void xburst2_boot_secondary(int cpu, struct task_struct *idle)
+{
+ unsigned int reset;//,mb_msk;
+//TODO: clk enable.
+ /* set soft reset. */
+ pr_info("[SMP] Booting CPU%d ...\n", cpu);
+ /* set reset entry! */
+ set_ccu_rer(smp_core.entry_base);
+
+ reset = get_ccu_csrr();
+ reset |= 1 << cpu;
+ set_ccu_csrr(reset);
+ smp_core.context_sp = __KSTK_TOS(idle);
+ smp_core.context_gp = (unsigned long)task_thread_info(idle);
+ wmb();
+/* clear soft reset. */
+ reset &= ~(1 << cpu);
+ set_ccu_csrr(reset);
+ pr_debug("percpu %x\n",read_c0_status());
+}
+
+// prepare smp all core register but core0 should be hold.
+// the code is initialise core ccu register.
+
+static void __init xburst2_smp_setup(void)
+{
+ int i, num;
+ //set smp all core register disable.
+ set_ccu_mimr(0);
+ //note:core reset register and core0 shouldn't be set.
+ set_ccu_csrr(0xfffe);
+
+
+ cpumask_clear_cpu(NR_CPUS, (struct cpumask *)cpu_possible_mask);
+ cpumask_clear_cpu(NR_CPUS, (struct cpumask *)cpu_present_mask);
+
+ //initial core0 register.
+
+ cpumask_set_cpu(0, (struct cpumask *)cpu_possible_mask);
+ cpumask_set_cpu(0, (struct cpumask *)cpu_present_mask);
+
+ __cpu_number_map[0] = 0;
+ __cpu_logical_map[0] = 0;
+
+ for (i = 1, num = 0; i < NR_CPUS; i++) {
+ cpumask_set_cpu(i, (struct cpumask *)cpu_possible_mask);
+ cpumask_set_cpu(i, (struct cpumask *)cpu_present_mask);
+
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+
+ pr_info("[SMP] Slave CPU(s) %i available.\n", num);
+}
+
+//prepare initial code for every core.
+static void __init xburst2_prepare_cpus(unsigned int max_cpus)
+{
+ int ret;
+ pr_info("[SMP] Prepare %d cores., cpu: %d\n", max_cpus, smp_processor_id());//qiao
+
+ if (max_cpus <= 1)
+ return;
+
+ smp_core.percpu_mailbox = alloc_percpu(struct xburst2_mailbox*);
+ if(!smp_core.percpu_mailbox)
+ pr_err("ERROR:alloc mailbox percpu fail!\n");
+
+ ret = request_percpu_irq(CORE_MAILBOX_IRQ,xburst2_mbox_interrupt,"jz-mailbox",
+ smp_core.percpu_mailbox);
+ if(ret) {
+ pr_err("ERROR: cpu%d request ost error\n",smp_processor_id());
+ }
+ percpu_mailbox_init(0);
+ set_ccu_mimr(1 << 0);
+ /* prepare slave cpus entry code */
+ build_bounce_code(&smp_core);
+ /* set reset entry point */
+ set_ccu_rer(smp_core.entry_base);//qiao
+ pr_debug("smp_bounce.base: %08lx\n", smp_core.entry_base);
+}
+
+static void xburst2_send_ipi_single(int cpu, unsigned int action)
+{
+ //unsigned int timeout=0x1000000;
+
+ struct xburst2_mailbox *mailbox = per_cpu(*smp_core.percpu_mailbox,cpu);
+ unsigned int val;
+ unsigned long flags;
+#if 0
+ while((readl(mailbox->iobase) & action) && (--timeout));
+ if(timeout == 0){
+ pr_err("SMP[%d] action:%d will reenter\n",cpu,action);
+ }
+#endif
+
+ raw_spin_lock_irqsave(&mailbox->lock,flags);
+ val = readl(mailbox->iobase);
+ writel(action | val,mailbox->iobase);
+ raw_spin_unlock_irqrestore(&mailbox->lock,flags);
+}
+
+static void xburst2_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ int i;
+ for(i = 0; i < NR_CPUS;i++){
+ if(cpumask_test_cpu(i,(struct cpumask *)mask)){
+ xburst2_send_ipi_single(i,action);
+ }
+ }
+}
+/**
+ * all cpu finish
+ */
+void xburst2_cpus_done(void)
+{
+// FIXME: will remove this code.
+ pr_debug("[SMP]: xburst2_cpus_done\n");
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+void ingenic_percpu_timerevent_deinit(void);
+void ingenic_percpu_irq_deinit(void);
+static int xburst2_cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned int val;
+ if (cpu == 0)
+ return -EBUSY;
+ pr_info("SMP: CPU%d is offline\n", cpu);
+ set_cpu_online(cpu, false);
+ cpumask_clear_cpu(cpu, &cpu_callin_map);
+
+ val = get_ccu_pimr();
+ val &= ~(1 << cpu);
+ set_ccu_pimr(val);
+
+ val = get_ccu_oimr();
+ val &= ~(1 << cpu);
+ set_ccu_oimr(val);
+
+ //val = get_ccu_mimr();
+ //val &= ~(1 << cpu);
+ //set_ccu_mimr(val);
+
+ ingenic_percpu_irq_deinit();
+ ingenic_percpu_timerevent_deinit();
+ migrate_irqs(cpu);
+ clear_tasks_mm_cpumask(cpu);
+
+ pr_debug("disabled cpu %d\n",cpu);
+ return 0;
+}
+
+void xburst2_cpu_die(unsigned int cpu)
+{
+ unsigned int timeout = 0x100000;
+ unsigned int reset;
+ if (cpu == 0)
+ return;
+
+ while((get_ccu_cssr() & (1<<cpu)) == 0 && --timeout);
+ if(timeout == 0){
+ pr_err("SMP[%d] disabled failed!\n",cpu);
+ BUG_ON(1);
+ }
+
+ reset = get_ccu_csrr();
+ reset |= 1 << cpu;
+ set_ccu_csrr(reset); // keep reset state.
+
+ //TODO: clk disable.
+ pr_info("SMP[%d] is disabled\n",cpu);
+}
+#endif
+//cpu idle loop will enter it.
+void play_dead(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ unsigned int val;
+ pr_debug("---%s, cpu: %d\n", __func__, cpu);
+
+ val = get_ccu_mimr();
+ val &= ~(1 << cpu);
+ set_ccu_mimr(val);
+ idle_task_exit();
+ local_irq_disable();
+ local_flush_tlb_all();
+ // Isn't smt thread core.
+ if(!cpu_online(((cpu + 1) & 1) | (cpu & (~1))))
+ {
+ blast_dcache32();
+ }
+
+ __asm__ __volatile__ ( ".set push \n\t"
+ ".set mips32r2 \n\t"
+ "sync \n\t"
+ "wait \n\t"
+ "nop \n\t"
+ ".set pop \n\t"
+ );
+ pr_err("ERROR:SMP[%d]: shouldn't run here.",cpu);
+ while(1){
+ __asm__ __volatile__ ( ".set push \n\t"
+ ".set mips32r2 \n\t"
+ "wait \n\t"
+ "nop \n\t"
+ ".set pop \n\t"
+ );
+ }
+}
+
+struct plat_smp_ops xburst2_smp_ops = {
+ .send_ipi_single = xburst2_send_ipi_single,
+ .send_ipi_mask = xburst2_send_ipi_mask,
+
+ .init_secondary = xburst2_init_secondary,
+ .smp_finish = xburst2_smp_finish,
+ .boot_secondary = xburst2_boot_secondary,
+
+//kernel init
+ .smp_setup = xburst2_smp_setup, //platfor init
+// .cpus_done = xburst2_cpus_done,
+ .prepare_cpus = xburst2_prepare_cpus, //main init
+
+
+#ifdef CONFIG_HOTPLUG_CPU
+ /* Ensure this CPU doesn't handle any more interrupts. */
+ .cpu_disable = xburst2_cpu_disable,
+ /* This actually kills the CPU. */
+ .cpu_die = xburst2_cpu_die,
+
+#endif
+};

View File

@ -0,0 +1,48 @@
diff -drupN a/arch/mips/xburst2/core/xburst_pmon.h b/arch/mips/xburst2/core/xburst_pmon.h
--- a/arch/mips/xburst2/core/xburst_pmon.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/core/xburst_pmon.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#define OPENPMON \
+ char perf_array[256] = {0}; \
+ int fperf = open("/proc/jz/pmon/perform",O_RDWR); \
+ if(fperf <= 0) \
+ printf("open pmon error!\n"); \
+
+#define CLOSEFS close(fperf)
+
+#define START0 memset(perf_array,0,255); write(fperf,"perf0",5);
+#define START1 memset(perf_array,0,255); write(fperf,"perf1",5);
+#define START2 memset(perf_array,0,255); write(fperf,"perf2",5);
+#define START3 memset(perf_array,0,255); write(fperf,"perf3",5);
+#define START4 memset(perf_array,0,255); write(fperf,"perf4",5);
+#define START5 memset(perf_array,0,255); write(fperf,"perf5",5);
+#define START6 memset(perf_array,0,255); write(fperf,"perf6",5);
+#define START7 memset(perf_array,0,255); write(fperf,"perf7",5);
+#define START8 memset(perf_array,0,255); write(fperf,"perf8",5);
+#define START9 memset(perf_array,0,255); write(fperf,"perf9",5);
+#define START10 memset(perf_array,0,255); write(fperf,"perf10",6);
+#define START48 memset(perf_array,0,255); write(fperf,"perf48",6);
+#define START49 memset(perf_array,0,255); write(fperf,"perf49",6);
+#define START50 memset(perf_array,0,255); write(fperf,"perf50",6);
+#define START51 memset(perf_array,0,255); write(fperf,"perf51",6);
+#define START52 memset(perf_array,0,255); write(fperf,"perf52",6);
+#define START53 memset(perf_array,0,255); write(fperf,"perf53",6);
+#define START54 memset(perf_array,0,255); write(fperf,"perf54",6);
+#define START55 memset(perf_array,0,255); write(fperf,"perf55",6);
+#define START56 memset(perf_array,0,255); write(fperf,"perf56",6);
+#define START57 memset(perf_array,0,255); write(fperf,"perf57",6);
+#define START58 memset(perf_array,0,255); write(fperf,"perf58",6);
+#define START59 memset(perf_array,0,255); write(fperf,"perf59",6);
+#define STOP \
+ lseek(fperf,0,SEEK_SET); \
+ read(fperf,perf_array,255); \
+ write(fperf,"perfstop",8); \
+ printf("%s",perf_array);
+

View File

@ -0,0 +1,6 @@
diff -drupN a/arch/mips/xburst2/soc-t40/Kconfig.DT b/arch/mips/xburst2/soc-t40/Kconfig.DT
--- a/arch/mips/xburst2/soc-t40/Kconfig.DT 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/Kconfig.DT 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,2 @@
+config DT_T40_SHARK
+ bool "t40 shark"

View File

@ -0,0 +1,12 @@
diff -drupN a/arch/mips/xburst2/soc-t40/Makefile b/arch/mips/xburst2/soc-t40/Makefile
--- a/arch/mips/xburst2/soc-t40/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/Makefile 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,8 @@
+obj-y += setup.o
+obj-y += serial.o
+
+obj-y += pm.o
+obj-y += regs_save_restore.o
+obj-y += libdmmu.o
+obj-y += gpio.o
+obj-y += reset.o

View File

@ -0,0 +1,127 @@
diff -drupN a/arch/mips/xburst2/soc-t40/gpio.c b/arch/mips/xburst2/soc-t40/gpio.c
--- a/arch/mips/xburst2/soc-t40/gpio.c 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/gpio.c 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,123 @@
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/io.h>
+#include <soc/base.h>
+#include <soc/gpio.h>
+
+#define GPIO_PORT_OFF 0x1000
+#define GPIO_SHADOW_OFF 0x7000
+
+#define PXPIN 0x00 /* PIN Level Register */
+#define PXINT 0x10 /* Port Interrupt Register */
+#define PXINTS 0x14 /* Port Interrupt Set Register */
+#define PXINTC 0x18 /* Port Interrupt Clear Register */
+#define PXMSK 0x20 /* Port Interrupt Mask Reg */
+#define PXMSKS 0x24 /* Port Interrupt Mask Set Reg */
+#define PXMSKC 0x28 /* Port Interrupt Mask Clear Reg */
+#define PXPAT1 0x30 /* Port Pattern 1 Set Reg. */
+#define PXPAT1S 0x34 /* Port Pattern 1 Set Reg. */
+#define PXPAT1C 0x38 /* Port Pattern 1 Clear Reg. */
+#define PXPAT0 0x40 /* Port Pattern 0 Register */
+#define PXPAT0S 0x44 /* Port Pattern 0 Set Register */
+#define PXPAT0C 0x48 /* Port Pattern 0 Clear Register */
+#define PXFLG 0x50 /* Port Flag Register */
+#define PXFLGC 0x58 /* Port Flag clear Register */
+#define PXPU 0x110 /* Port PULL-UP State Register */
+#define PXPUS 0x114 /* Port PULL-UP State Set Register */
+#define PXPUC 0x118 /* Port PULL-UP State Clear Register */
+#define PXPD 0x120 /* Port PULL-DOWN State Register */
+#define PXPDS 0x124 /* Port PULL-DOWN State Set Register */
+#define PXPDC 0x128 /* Port PULL-DOWN State Clear Register */
+
+#define PZGID2LD 0xF0 /* GPIOZ Group ID to load */
+
+#define SHADOW 5
+
+static const unsigned long gpiobase[] = {
+ [0] = (unsigned long)CKSEG1ADDR(GPIO_IOBASE + 0 * GPIO_PORT_OFF),
+ [1] = (unsigned long)CKSEG1ADDR(GPIO_IOBASE + 1 * GPIO_PORT_OFF),
+ [2] = (unsigned long)CKSEG1ADDR(GPIO_IOBASE + 2 * GPIO_PORT_OFF),
+ [3] = (unsigned long)CKSEG1ADDR(GPIO_IOBASE + 3 * GPIO_PORT_OFF),
+ [4] = (unsigned long)CKSEG1ADDR(GPIO_IOBASE + 4 * GPIO_PORT_OFF),
+
+ [SHADOW] = (unsigned long)CKSEG1ADDR(GPIO_IOBASE + GPIO_SHADOW_OFF),
+};
+
+#define GPIO_ADDR(port, reg) ((volatile unsigned long *)(gpiobase[port] + reg))
+
+static inline void gpio_write(int port, unsigned int reg, int val)
+{
+ *GPIO_ADDR(port, reg) = val;
+}
+
+static inline unsigned int gpio_read(int port, unsigned int reg)
+{
+ return *GPIO_ADDR(port, reg);
+}
+
+static void hal_gpio_port_set_func(int port, unsigned int pins, enum gpio_function func)
+{
+ /* func option */
+ if (func & 0x10) {
+ if (func & 0x8)
+ gpio_write(SHADOW, PXINTS, pins);
+ else
+ gpio_write(SHADOW, PXINTC, pins);
+
+ if (func & 0x4)
+ gpio_write(SHADOW, PXMSKS, pins);
+ else
+ gpio_write(SHADOW, PXMSKC, pins);
+
+ if (func & 0x2)
+ gpio_write(SHADOW, PXPAT1S, pins);
+ else
+ gpio_write(SHADOW, PXPAT1C, pins);
+
+ if (func & 0x1)
+ gpio_write(SHADOW, PXPAT0S, pins);
+ else
+ gpio_write(SHADOW, PXPAT0C, pins);
+
+ /* configure PzGID2LD to specify which port group to load */
+ gpio_write(SHADOW, PZGID2LD, port);
+ }
+
+ if (func & 0x80) {
+ int pull = (func >> 5) & 0x3;
+ if (pull == 0) { // no pull
+ gpio_write(port, PXPUC, pins);
+ gpio_write(port, PXPDC, pins);
+ }
+ if (pull == 1) { // pull up
+ gpio_write(port, PXPDC, pins);
+ gpio_write(port, PXPUS, pins);
+ }
+ if (pull == 2) { // pull down
+ gpio_write(port, PXPUC, pins);
+ gpio_write(port, PXPDS, pins);
+ }
+ }
+}
+
+unsigned long ingenic_pinctrl_lock(int port);
+void ingenic_pinctrl_unlock(int port, unsigned long flags);
+
+int jzgpio_set_func(int port, enum gpio_function func, unsigned long pins)
+{
+ unsigned long flags;
+
+ if (port < 0 || port > 4) {
+ printk(KERN_ERR "gpio: invalid gpio port for x2000: %d\n", port);
+ return -EINVAL;
+ }
+
+ flags = ingenic_pinctrl_lock(port);
+
+ hal_gpio_port_set_func(port, pins, func);
+
+ ingenic_pinctrl_unlock(port, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(jzgpio_set_func);

View File

@ -0,0 +1,70 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/cpu-feature-overrides.h b/arch/mips/xburst2/soc-t40/include/cpu-feature-overrides.h
--- a/arch/mips/xburst2/soc-t40/include/cpu-feature-overrides.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/cpu-feature-overrides.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <zpzhong@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_INGENIC_CPU_FEATURE_OVERRIDES_H__
+#define __ASM_MACH_INGENIC_CPU_FEATURE_OVERRIDES_H__
+
+
+#define cpu_dcache_size() (32 * 1024)
+#define cpu_dcache_ways() 8
+#define cpu_dcache_line_size() 32
+#define cpu_icache_size() (32 * 1024)
+#define cpu_icache_ways() 8
+#define cpu_icache_line_size() 32
+#define cpu_has_xpa 0
+#define cpu_has_tlb 1
+#define cpu_has_tlbinv 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 0
+#define cpu_has_counter 0
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 0
+#define cpu_has_llsc 1
+#define kernel_uses_llsc cpu_has_llsc
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_pindexed_dcache 0
+#define cpu_icache_snoops_remote_store 0
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 1
+#define cpu_has_rixi 1
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_vint 0
+#define cpu_has_veic 0
+#define cpu_has_inclusive_pcaches 0
+#define kernel_uses_smartmips_rixi 0
+#define cpu_has_mxuv3 1
+#endif

View File

@ -0,0 +1,44 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/irq.h b/arch/mips/xburst2/soc-t40/include/irq.h
--- a/arch/mips/xburst2/soc-t40/include/irq.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/irq.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Ingenic Semiconductor Inc.
+ *
+ * Author: <zpzhong@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_INGENIC_IRQ_H__
+#define __ASM_MACH_INGENIC_IRQ_H__
+#include <irq_cpu.h>
+#include <dt-bindings/interrupt-controller/mips-irq.h>
+
+enum {
+#define GPIO_NR_IRQS (32 * 5 + 16)
+ IRQ_GPIO_BASE = (IRQ_INTC_END + 1),
+ IRQ_GPIO_END = IRQ_GPIO_BASE + GPIO_NR_IRQS - 1,
+
+#define TCU_NR_IRQS (8)
+ IRQ_TCU_BASE,
+ IRQ_TCU_END = IRQ_TCU_BASE + TCU_NR_IRQS - 1,
+
+#define MCU_NR_IRQS (5)
+ IRQ_MCU_BASE,
+ IRQ_MCU_END = IRQ_MCU_BASE + MCU_NR_IRQS - 1,
+
+#define SADC_NR_IRQS (8)
+ IRQ_SADC_BASE,
+ IRQ_SADC_END = IRQ_SADC_BASE + SADC_NR_IRQS - 1,
+
+#define RESERVED_NR_IRQS (150)
+ IRQ_RESERVED_BASE,
+ IRQ_RESERVED_END = IRQ_RESERVED_BASE + RESERVED_NR_IRQS - 1,
+
+ NR_IRQS,
+};
+
+#endif

View File

@ -0,0 +1,18 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/libdmmu.h b/arch/mips/xburst2/soc-t40/include/libdmmu.h
--- a/arch/mips/xburst2/soc-t40/include/libdmmu.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/libdmmu.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,14 @@
+#ifndef _LIBDMMU_
+#define _LIBDMMU_
+
+#include <linux/device.h>
+
+unsigned long dmmu_map(struct device *dev,unsigned long vaddr,unsigned long len);
+int dmmu_flush_cache(unsigned long vaddr, unsigned long len);
+int dmmu_unmap(struct device *dev,unsigned long vaddr, int len);
+int dmmu_unmap_all(struct device *dev);
+void dmmu_dump_vaddr(unsigned long vaddr);
+int dmmu_memory_smash(unsigned long vaddr, int smash_mode);
+int dmmu_dump_map(unsigned long vaddr);
+
+#endif

View File

@ -0,0 +1,101 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/soc/base.h b/arch/mips/xburst2/soc-t40/include/soc/base.h
--- a/arch/mips/xburst2/soc-t40/include/soc/base.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/soc/base.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,97 @@
+
+#ifndef __JZSOC_SOC_DEV_H__
+#define __JZSOC_SOC_DEV_H__
+
+/*
+ * Define the module base addresses
+ */
+
+/* AHB0 BUS Devices Base */
+#define HARB0_IOBASE 0x13000000
+#define DDRC_BASE 0xb34f0000
+#define DDRC1_IOBASE 0x13010000 /*DDR_APB_BASE*/
+#define DDRC_IOBASE 0x134f0000 /*TODO:*/
+#define DDRPHY_IOBASE 0x13011000 /*TODO:*/
+#define AXI_ARB1_IOBASE 0x13013000 /*TODO:*/
+#define AXI_ARB2_IOBASE 0x13014000 /*TODO:*/
+#define LCDC_IOBASE 0x13050000
+#define MSC0_IOBASE 0x13060000
+#define MSC1_IOBASE 0x13070000
+#define IPU_IOBASE 0x13080000
+#define BSCALER_IOBASE 0x13090000
+#define MONITOR_IOBASE 0x130a0000
+#define I2D_IOBASE 0x130b0000
+#define VO_IOBASE 0x130c0000
+#define DRAW_BOX_IOBASE 0x130d0000
+#define ISP_IOBASE 0x13300000
+#define LZMA_IOBASE 0x13090000
+
+/* AHB1 BUS Devices Base */
+#define RTC_IOBASE 0x132a0000
+#define EL150_IOBASE 0x13200000
+#define RADIX_IOBASE 0x13100000
+#define RADIX_IOBASE_UNIT(ID) (RADIX_IOBASE + 0x400000 * ID)
+#define AVPU_IOBASE 0x13200000
+#define AVPU_IOBASE_UNIT(ID) (AVPU_IOBASE + 0x400000 * ID)
+
+/* AHB2 BUS Devices Base */
+#define HARB2_IOBASE 0x13400000
+#define NEMC_IOBASE 0x13410000
+#define PDMA_IOBASE 0x13420000
+#define AES_IOBASE 0x13430000
+#define SFC_IOBASE 0x13440000
+#define HASH_IOBASE 0x13480000
+#define GMAC_IOBASE 0x134b0000
+#define RSA_IOBASE 0x134c0000
+#define OTG_IOBASE 0x13500000
+#define EFUSE_IOBASE 0x13540000
+#define INTC_IOBASE 0x10001000
+
+/* CPU and OST */
+#define G_OST_IOBASE 0x12000000 /* G_OST_BASE */
+#define N_OST_IOBASE 0x12100000 /* N_OST_BASE */
+#define CCU_IOBASE 0x12200000
+#define INTCN_IOBASE 0x12300000
+#define SRAM_IOBASE 0x12400000
+#define NNDMA_IOBASE 0x12500000
+#define LEPOST_IOBASE 0x12600000 /* RISC-V OST */
+#define LEPCCU_IOBASE 0x12700000 /* RISC-V CCU */
+
+/* APB BUS Devices Base */
+#define CPM_IOBASE 0x10000000
+#define TCU_IOBASE 0x10002000
+#define MIPI_DSI_TX_IOBASE 0x10003000
+#define MIPI_DSI_PHY_IOBASE 0x10004000
+#define GPIO_IOBASE 0x10010000
+#define AIC0_IOBASE 0x10020000
+#define CODEC_IOBASE 0x10021000
+#define MIPI_PHY_IOBASE 0x10022000
+#define MIPI_CSI_IOBASE 0x10023000
+#define UART0_IOBASE 0x10030000
+#define UART1_IOBASE 0x10031000
+#define UART2_IOBASE 0x10032000
+#define UART3_IOBASE 0x10033000
+#define DMIC_IOBASE 0x10034000
+#define SSISLV_IOBASE 0x10040000
+#define SSI0_IOBASE 0x10043000
+#define SSI1_IOBASE 0x10044000
+#define I2C0_IOBASE 0x10050000
+#define I2C1_IOBASE 0x10051000
+#define I2C2_IOBASE 0x10052000
+#define I2C3_IOBASE 0x10053000
+#define MIPI_RX_4L_IOBASE 0x10054000
+#define USB_IOBASE 0x10060000
+#define DES_IOBASE 0x10061000
+#define SADC_IOBASE 0x10070000
+#define DTRNG_IOBASE 0x10072000
+#define WDT_IOBASE 0x10002000
+
+/* NAND CHIP Base Address*/
+#define NEMC_CS1_IOBASE 0X1b000000
+#define NEMC_CS2_IOBASE 0X1a000000
+#define NEMC_CS3_IOBASE 0X19000000
+#define NEMC_CS4_IOBASE 0X18000000
+#define NEMC_CS5_IOBASE 0X17000000
+#define NEMC_CS6_IOBASE 0X16000000
+
+#endif

View File

@ -0,0 +1,77 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/soc/cache.h b/arch/mips/xburst2/soc-t40/include/soc/cache.h
--- a/arch/mips/xburst2/soc-t40/include/soc/cache.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/soc/cache.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,73 @@
+#ifndef __CHIP_CACHE_H__
+#define __CHIP_CACHE_H__
+#include <asm/cacheops.h>
+#include <asm/r4kcache.h>
+
+#define Index_Prefetch_I 0x1c
+
+
+#define cache_prefetch(label,size) \
+do{ \
+ unsigned long addr,end; \
+ /* Prefetch codes from label */ \
+ addr = (unsigned long)(&&label) & ~(32 - 1); \
+ end = (unsigned long)(&&label + size) & ~(32 - 1); \
+ end += 32; \
+ for (; addr < end; addr += 32) { \
+ __asm__ volatile ( \
+ ".set push \n\t" \
+ ".set mips32 \n\t" \
+ " cache %0, 0(%1)\n\t" \
+ ".set pop \n\t" \
+ : \
+ : "I" (Index_Prefetch_I), "r"(addr)); \
+ } \
+} \
+while(0)
+
+#define K0BASE KSEG0
+#define CFG_DCACHE_SIZE 32768
+#define CFG_ICACHE_SIZE 32768
+#define CFG_CACHELINE_SIZE 32
+
+#define CFG_SDCACHE_SIZE (512*1024)
+#define CFG_SDCACHELINE_SIZE 64
+
+static inline void __jz_flush_cache_all(void)
+{
+ register unsigned long addr;
+ /* Clear CP0 TagLo */
+ for (addr = K0BASE; addr < (K0BASE + CFG_DCACHE_SIZE); addr += CFG_CACHELINE_SIZE) {
+ asm volatile (".set mips32\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips32\n\t"
+ :
+ : "I" (Index_Writeback_Inv_D), "r"(addr));
+ }
+
+ for (addr = K0BASE; addr < (K0BASE + CFG_ICACHE_SIZE); addr += CFG_CACHELINE_SIZE) {
+ asm volatile (".set mips32\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips32\n\t"
+ :
+ : "I" (Index_Invalidate_I), "r"(addr));
+ }
+
+ asm volatile ("sync\n\t"
+ "lw $0,0(%0)"
+ ::"r" (0xa0000000));
+ /* 2nd cache */
+ for (addr = K0BASE; addr < (K0BASE + CFG_SDCACHE_SIZE); addr += CFG_SDCACHELINE_SIZE) {
+ asm volatile (".set mips32\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips32\n\t"
+ :
+ : "I" (Index_Writeback_Inv_SD), "r"(addr));
+ }
+
+ asm volatile ("sync\n\t"
+ "lw $0,0(%0)"
+ ::"r" (0xa0000000));
+}
+
+#endif /* __CHIP_CACHE_H__ */

View File

@ -0,0 +1,146 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/soc/cpm.h b/arch/mips/xburst2/soc-t40/include/soc/cpm.h
--- a/arch/mips/xburst2/soc-t40/include/soc/cpm.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/soc/cpm.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,142 @@
+/*
+ * JZSOC CPM register definition.
+ *
+ * CPM (Clock reset and Power control Management)
+ *
+ * Copyright (C) 2019 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __CPM_H__
+#define __CPM_H__
+
+#define CPM_CPCCR (0x00)
+#define CPM_CPPCR (0x0c)
+#define CPM_CPAPCR (0x10)
+#define CPM_CPMPCR (0x14)
+#define CPM_CPAPACR (0x18)
+#define CPM_CPMPACR (0x1c)
+#define CPM_DDRCDR (0x2c)
+#define CPM_EL150CDR (0x30)
+#define CPM_CPPSR (0x34)
+#define CPM_CPSPPR (0x38)
+#define CPM_USBPCR (0x3c)
+#define CPM_USBRDT (0x40)
+#define CPM_USBVBFIL (0x44)
+#define CPM_USBPCR1 (0x48)
+#define CPM_RSACDR (0x4c)
+#define CPM_MACCDR (0x54)
+#define CPM_CPEPCR (0x58)
+#define CPM_CPEPACR (0x5c)
+#define CPM_SFCCDR (0x60)
+#define CPM_LPCDR (0x64)
+#define CPM_MSC0CDR (0x68)
+#define CPM_MSC1CDR (0x6c)
+#define CPM_I2STCDR (0x70)
+#define CPM_I2STCDR1 (0x78)
+#define CPM_SSICDR (0x74)
+#define CPM_ISPCDR (0x80)
+#define CPM_I2SRCDR (0x84)
+#define CPM_I2SRCDR1 (0x88)
+#define CPM_BSCALERCDR (0xa0)
+#define CPM_EXCLKDS (0x8c)
+#define CPM_CIM0CDR (0x90)
+#define CPM_CIM1CDR (0x94)
+#define CPM_CIM2CDR (0x98)
+#define CPM_SOFTAPP (0x9c)
+#define CPM_BSCALERCDR (0xa0)
+#define CPM_RADIXCDR (0xa4)
+#define CPM_INTR (0xb0)
+#define CPM_INTRE (0xb4)
+#define CPM_BT0CDR (0xb8)
+#define CPM_DRCG (0xd0)
+#define CPM_CPCSR (0xd4)
+#define CPM_CPVPCR (0xe0)
+#define CPM_CPVPACR (0xe4)
+#define CPM_MACPHY (0xe8)
+
+
+#define CPM_LCR (0x04)
+#define CPM_CLKGR (0x20)/* def changed*/
+#define CPM_OPCR (0x24)
+#define CPM_CLKGR1 (0x28)/* def changed*/
+#define CPM_SRBC (0xc4)
+#define SRBC_USB_SR BIT (12)
+#define CPM_MESTSEL (0xec)
+
+#define CPM_MEMCTRL_MA0 (0xf0)
+#define CPM_MEMCTRL_MA1 (0xf4)
+#define CPM_MEMCTRL_MA2 (0xf8)
+
+#define CPM_RSR (0x08)
+
+#ifndef BIT
+#define BIT(nr) (1UL << nr)
+#endif
+
+/*USB Parameter Control Register*/
+#define USBPCR_USB_MODE BIT(31)
+#define USBPCR_AVLD_REG BIT(30)
+#define USBPCR_IDPULLUP_MASK_BIT 28
+#define USBPCR_IDPULLUP_MASK (0x3 << USBPCR_IDPULLUP_MASK_BIT)
+#define USBPCR_IDPULLUP_OTG (0x0 << USBPCR_IDPULLUP_MASK_BIT)
+#define USBPCR_IDPULLUP_ALWAYS_SUSPEND (0x1 << USBPCR_IDPULLUP_MASK_BIT)
+#define USBPCR_IDPULLUP_ALWAYS (0x2 << USBPCR_IDPULLUP_MASK_BIT)
+#define USBPCR_INCR_MASK BIT(27)
+#define USBPCR_POR_BIT 22
+#define USBPCR_POR BIT(USBPCR_POR_BIT)
+
+/*USB Reset Detect Timer Register*/
+#define USBRDT_RESUME_INTEEN BIT(31) /*RW*/
+#define USBRDT_RESUME_INTERCLR BIT(30) /*W0*/
+#define USBRDT_RESUME_SPEED_BIT 28 /*RW*/
+#define USBRDT_RESUME_SPEED_MSK (0x3 << USBRDT_RESUME_SPEED_BIT)
+#define USBRDT_RESUME_SPEED_HIGH (0x0 << USBRDT_RESUME_SPEED_BIT)
+#define USBRDT_RESUME_SPEED_FULL (0x1 << USBRDT_RESUME_SPEED_BIT)
+#define USBRDT_RESUME_SPEED_LOW (0x2 << USBRDT_RESUME_SPEED_BIT)
+#define USBRDT_RESUME_STATUS BIT(27) /*RO*/
+#define USBRDT_HB_MASK BIT(26)
+#define USBRDT_VBFIL_LD_EN BIT(25)
+#define USBRDT_IDDIG_EN 24
+#define USBRDT_IDDIG_REG 23
+#define USBRDT_USBRDT_MSK (0x7fffff)
+#define USBRDT_USBRDT(x) ((x) & USBRDT_USBRDT_MSK)
+#define USBRDT_UTMI_RST BIT(27)
+
+/*USB VBUS Jitter Filter Register*/
+#define USBVBFIL_USBVBFIL(x) ((x) & 0xffff)
+#define USBVBFIL_IDDIGFIL(x) ((x) & (0xffff << 16))
+
+/*USB Parameter Control Register1*/
+#define USBPCR1_BVLD_REG BIT(31)
+#define USBPCR1_DPPULLDOWN BIT(29)
+#define USBPCR1_DMPULLDOWN BIT(28)
+#define USBPCR1_PORT_RST BIT(21)
+
+/*Oscillator and Power Control Register*/
+#define OPCR_USB_SPENDN BIT(7)
+#define OPCR_USB_PHY_GATE BIT(23)
+
+#define LCR_LPM_MASK (0x3)
+#define LCR_LPM_SLEEP (0x1)
+
+#define CPM_LCR_PD_X2D (0x1<<31)
+#define CPM_LCR_PD_VPU (0x1<<30)
+#define CPM_LCR_PD_MASK (0x3<<30)
+#define CPM_LCR_X2DS (0x1<<27)
+#define CPM_LCR_VPUS (0x1<<26)
+#define CPM_LCR_STATUS_MASK (0x3<<26)
+
+#define OPCR_ERCS (0x1<<2)
+#define OPCR_PD (0x1<<3) //T31 delete
+#define OPCR_IDLE (0x1<<31)
+
+#define CLKGR1_VPU (0x1<<0)
+
+#define cpm_inl(off) inl(CPM_IOBASE + (off))
+#define cpm_outl(val,off) outl(val,CPM_IOBASE + (off))
+#define cpm_clear_bit(val,off) do{cpm_outl((cpm_inl(off) & ~(1 << (val))),off);}while(0)
+#define cpm_set_bit(val,off) do{cpm_outl((cpm_inl(off) | (1 << (val))),off);}while(0)
+#define cpm_test_bit(val,off) (cpm_inl(off) & (0x1 << (val)))
+
+#endif
+/* __CPM_H__ */

View File

@ -0,0 +1,104 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/soc/ddr.h b/arch/mips/xburst2/soc-t40/include/soc/ddr.h
--- a/arch/mips/xburst2/soc-t40/include/soc/ddr.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/soc/ddr.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,100 @@
+#ifndef _DDR_H_
+#define _DDR_H_
+#define DDRP_PIR_INIT (1 << 0)
+#define DDRP_PIR_DLLSRST (1 << 1)
+#define DDRP_PIR_DLLLOCK (1 << 2)
+#define DDRP_PIR_ZCAL (1 << 3)
+#define DDRP_PIR_ITMSRST (1 << 4)
+#define DDRP_PIR_DRAMRST (1 << 5)
+#define DDRP_PIR_DRAMINT (1 << 6)
+#define DDRP_PIR_QSTRN (1 << 7)
+#define DDRP_PIR_EYETRN (1 << 8)
+#define DDRP_PIR_DLLBYP (1 << 17)
+#define DDRP_PIR_LOCKBYP (1 << 29)
+#define DDRP_PGSR_IDONE (1 << 0)
+#define DDRP_PGSR_DLDONE (1 << 1)
+#define DDRP_PGSR_ZCDONE (1 << 2)
+#define DDRP_PGSR_DIDONE (1 << 3)
+#define DDRP_PGSR_DTDONE (1 << 4)
+#define DDRP_PGSR_DTERR (1 << 5)
+#define DDRP_PGSR_DTIERR (1 << 6)
+#define DDRP_PGSR_DFTEERR (1 << 7)
+#define DDRC_AUTOSR_ENABLE (1 << 0)
+
+
+#define DDR_PHY_OFFSET (-0x4e0000 + 0x1000)
+
+#define DDRP_PIR (DDR_PHY_OFFSET + 0x4) /* PHY Initialization Register */
+#define DDRP_PGCR (DDR_PHY_OFFSET + 0x8) /* PHY General Configuration Register*/
+#define DDRP_PGSR (DDR_PHY_OFFSET + 0xc) /* PHY General Status Register*/
+#define DDRP_DLLGCR (DDR_PHY_OFFSET + 0x10) /* DLL General Control Register*/
+#define DDRP_ACDLLCR (DDR_PHY_OFFSET + 0x14) /* AC DLL Control Register*/
+#define DDRP_PTR0 (DDR_PHY_OFFSET + 0x18) /* PHY Timing Register 0 */
+#define DDRP_PTR1 (DDR_PHY_OFFSET + 0x1c) /* PHY Timing Register 1 */
+#define DDRP_PTR2 (DDR_PHY_OFFSET + 0x20) /* PHY Timing Register 2 */
+#define DDRP_ACIOCR (DDR_PHY_OFFSET + 0x24) /* AC I/O Configuration Register */
+#define DDRP_DXCCR (DDR_PHY_OFFSET + 0x28) /* DATX8 Common Configuration Register */
+#define DDRP_DSGCR (DDR_PHY_OFFSET + 0x2c) /* DDR System General Configuration Register */
+#define DDRP_DCR (DDR_PHY_OFFSET + 0x30) /* DRAM Configuration Register*/
+
+#define DDRP_DTPR0 (DDR_PHY_OFFSET + 0x34) /* DRAM Timing Parameters Register 0 */
+#define DDRP_DTPR1 (DDR_PHY_OFFSET + 0x38) /* DRAM Timing Parameters Register 1 */
+#define DDRP_DTPR2 (DDR_PHY_OFFSET + 0x3c) /* DRAM Timing Parameters Register 2 */
+#define DDRP_MR0 (DDR_PHY_OFFSET + 0x40) /* Mode Register 0 */
+#define DDRP_MR1 (DDR_PHY_OFFSET + 0x44) /* Mode Register 1 */
+#define DDRP_MR2 (DDR_PHY_OFFSET + 0x48) /* Mode Register 2 */
+#define DDRP_MR3 (DDR_PHY_OFFSET + 0x4c) /* Mode Register 3 */
+#define DDRP_ODTCR (DDR_PHY_OFFSET + 0x50) /* ODT Configure Register */
+#define DDRP_DTAR (DDR_PHY_OFFSET + 0x54) /* Data Training Address Register */
+#define DDRP_DTDR0 (DDR_PHY_OFFSET + 0x58) /* Data Training Data Register 0 */
+#define DDRP_DTDR1 (DDR_PHY_OFFSET + 0x5c) /* Data Training Data Register 1 */
+
+#define DDRP_DCUAR (DDR_PHY_OFFSET + 0xc0) /* DCU Address Register */
+#define DDRP_DCUDR (DDR_PHY_OFFSET + 0xc4) /* DCU Data Register */
+#define DDRP_DCURR (DDR_PHY_OFFSET + 0xc8) /* DCU Run Register */
+#define DDRP_DCULR (DDR_PHY_OFFSET + 0xcc) /* DCU Loop Register */
+#define DDRP_DCUGCR (DDR_PHY_OFFSET + 0xd0) /* DCU Gerneral Configuration Register */
+#define DDRP_DCUTPR (DDR_PHY_OFFSET + 0xd4) /* DCU Timing Parameters Register */
+#define DDRP_DCUSR0 (DDR_PHY_OFFSET + 0xd8) /* DCU Status Register 0 */
+#define DDRP_DCUSR1 (DDR_PHY_OFFSET + 0xdc) /* DCU Status Register 1 */
+
+#define DDRP_DXGCR(n) (DDR_PHY_OFFSET + 0x1c0 + n * 0x40) /* DATX8 n General Configuration Register */
+#define DDRP_DXGSR0(n) (DDR_PHY_OFFSET + 0x1c4 + n * 0x40) /* DATX8 n General Status Register */
+#define DDRP_DXGSR1(n) (DDR_PHY_OFFSET + 0x1c8 + n * 0x40) /* DATX8 n General Status Register */
+#define DDRP_DXDLLCR(n) (DDR_PHY_OFFSET + 0x1cc + n * 0x40) /* DATX8 n General Status Register */
+#define DDRP_DXDQSTR(n) (DDR_PHY_OFFSET + 0x1d4 + n * 0x40) /* DATX8 n DQS Timing Register */
+#define DDRP_ZQXCR0(n) (DDR_PHY_OFFSET + 0x180 + n * 0x10) /* ZQ impedance Control Register 0 */
+#define DDRP_ZQXCR1(n) (DDR_PHY_OFFSET + 0x184 + n * 0x10) /* ZQ impedance Control Register 1 */
+#define DDRP_ZQXSR0(n) (DDR_PHY_OFFSET + 0x188 + n * 0x10) /* ZQ impedance Status Register 0 */
+#define DDRP_ZQXSR1(n) (DDR_PHY_OFFSET + 0x18c + n * 0x10) /* ZQ impedance Status Register 1 */
+
+#define DDRP_DX0GSR (DDR_PHY_OFFSET + 0x71 * 4)
+
+#define DDRC_STATUS 0x0
+#define DDRC_CFG 0x4
+#define DDRC_CTRL 0x8
+#define DDRC_LMR 0xc
+#define DDRC_REFCNT 0x18
+#define DDRC_MMAP0 0x24
+#define DDRC_MMAP1 0x28
+#define DDRC_DLP 0xbc
+#define DDRC_STRB 0x34
+#define DDRC_AUTOSR_CNT 0x308
+#define DDRC_AUTOSR_EN 0x304
+#define DDRC_TIMING(n) (0x60 + 4 * (n - 1))
+#define DDRC_REMAP(n) (0x9c + 4 * (n - 1))
+
+
+#define DDRP_DXnDQSTR(n) (DDR_PHY_OFFSET + (0x10 * n + 0x75) * 4)
+#define DDRP_DXnDQTR(n) (DDR_PHY_OFFSET + (0x10 * n + 0x74) * 4)
+
+#ifndef REG32
+#define REG32(x) *(volatile unsigned int *)(x)
+#endif
+
+#define ddr_writel(value, reg) REG32(DDRC_BASE + reg) = (value)
+#define ddr_readl(reg) REG32(DDRC_BASE + reg)
+
+
+
+#endif /* _DDR_H_ */

View File

@ -0,0 +1,12 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/soc/extal.h b/arch/mips/xburst2/soc-t40/include/soc/extal.h
--- a/arch/mips/xburst2/soc-t40/include/soc/extal.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/soc/extal.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,8 @@
+
+#ifndef __JZSOC_EXTAL_H__
+#define __JZSOC_EXTAL_H__
+
+#define JZ_EXTAL_RTC 32768 /* RTC extal freq: 32.768 KHz */
+#define JZ_EXTAL (CONFIG_EXTAL_CLOCK * 1000000)
+
+#endif

View File

@ -0,0 +1,44 @@
diff -drupN a/arch/mips/xburst2/soc-t40/include/soc/gpio.h b/arch/mips/xburst2/soc-t40/include/soc/gpio.h
--- a/arch/mips/xburst2/soc-t40/include/soc/gpio.h 1970-01-01 03:00:00.000000000 +0300
+++ b/arch/mips/xburst2/soc-t40/include/soc/gpio.h 2022-06-09 05:02:27.000000000 +0300
@@ -0,0 +1,40 @@
+#ifndef _SOC_GPIO_H_
+#define _SOC_GPIO_H_
+
+enum gpio_function {
+ GPIO_FUNC_0 = 0x10, //0000, GPIO as function 0 / device 0
+ GPIO_FUNC_1 = 0x11, //0001, GPIO as function 1 / device 1
+ GPIO_FUNC_2 = 0x12, //0010, GPIO as function 2 / device 2
+ GPIO_FUNC_3 = 0x13, //0011, GPIO as function 3 / device 3
+ GPIO_OUTPUT0 = 0x14, //0100, GPIO output low level
+ GPIO_OUTPUT1 = 0x15, //0101, GPIO output high level
+ GPIO_INPUT = 0x16, //0110, GPIO as input.7 also.
+ GPIO_INT_LO = 0x18, //1000, Low Level trigger interrupt
+ GPIO_INT_HI = 0x19, //1001, High Level trigger interrupt
+ GPIO_INT_FE = 0x1a, //1010, Fall Edge trigger interrupt
+ GPIO_INT_RE = 0x1b, //1011, Rise Edge trigger interrupt
+ GPIO_INT_MASK_LO = 0x1c, //1100, Port is low level triggered interrupt input. Interrupt is masked.
+ GPIO_INT_MASK_HI = 0x1d, //1101, Port is high level triggered interrupt input. Interrupt is masked.
+ GPIO_INT_MASK_FE = 0x1e, //1110, Port is fall edge triggered interrupt input. Interrupt is masked.
+ GPIO_INT_MASK_RE = 0x1f, //1111, Port is rise edge triggered interrupt input. Interrupt is masked.
+
+ GPIO_PULL_HIZ = 0x80, //no pull
+ GPIO_PULL_UP = 0xa0, //pull high
+ GPIO_PULL_DOWN = 0xc0, //pull low
+};
+
+#define GPIO_PA(n) (0 * 32 + (n))
+#define GPIO_PB(n) (1 * 32 + (n))
+#define GPIO_PC(n) (2 * 32 + (n))
+#define GPIO_PD(n) (3 * 32 + (n))
+
+enum gpio_port {
+ GPIO_PORT_A, GPIO_PORT_B,
+ GPIO_PORT_C, GPIO_PORT_D,
+ /* this must be last */
+ GPIO_NR_PORTS,
+};
+
+int jzgpio_set_func(int port, enum gpio_function func, unsigned long pins);
+
+#endif /* _SOC_GPIO_H_ */

Some files were not shown because too many files have changed in this diff Show More