From fa23e550ed424e05d6b1712154708f06e03804e1 Mon Sep 17 00:00:00 2001 From: Gaspare Date: Tue, 4 Aug 2020 14:41:38 -0300 Subject: [PATCH] Add Support for RTL8196E RTL8197D RTL8197F --- target/linux/realtek/Makefile | 27 + .../realtek/base-files/etc/board.d/01_leds | 65 + .../realtek/base-files/etc/board.d/02_network | 53 + .../base-files/etc/uci-defaults/09_fix-header | 47 + .../01_preinit_do_realtek_board_detection | 9 + .../linux/realtek/base-files/lib/realtek.sh | 50 + .../base-files/lib/upgrade/platform.sh | 16 + target/linux/realtek/dts/ACTIONRF1200.dts | 112 ++ target/linux/realtek/dts/ACTIONRG1200.dts | 102 ++ target/linux/realtek/dts/DIR815D1.dts | 113 ++ target/linux/realtek/dts/DIR822C1.dts | 25 + target/linux/realtek/dts/GWR1200ACV1.dts | 72 + target/linux/realtek/dts/GWR1200ACV2.dts | 88 + target/linux/realtek/dts/GWR300.dts | 96 ++ target/linux/realtek/dts/RE172.dts | 52 + target/linux/realtek/dts/RE707.dts | 48 + target/linux/realtek/dts/RE708.dts | 72 + target/linux/realtek/dts/RTL8197F.dtsi | 91 + target/linux/realtek/dts/RTL8197FVG.dtsi | 17 + target/linux/realtek/dts/RTL819X.dtsi | 141 ++ .../arch/mips/boot/dts/realtek/Makefile | 12 + .../arch/mips/boot/dts/realtek/RTL8197F.dtsi | 91 + .../arch/mips/boot/dts/realtek/rtl8196e.dts | 48 + .../arch/mips/boot/dts/realtek/rtl8197d.dts | 25 + .../arch/mips/boot/dts/realtek/rtl8197f.dts | 41 + .../arch/mips/boot/dts/realtek/rtl819x.dtsi | 81 + .../mips/include/asm/mach-realtek/lxregs.h | 197 +++ .../include/asm/mach-realtek/realtek_mem.h | 18 + .../rtl8196e/cpu-feature-overrides.h | 60 + .../rtl8197d/cpu-feature-overrides.h | 60 + .../realtek/files-4.14/arch/mips/mm/c-lexra.c | 441 +++++ .../files-4.14/arch/mips/pci/pci-realtek.c | 469 ++++++ .../files-4.14/arch/mips/realtek/Kconfig | 70 + .../files-4.14/arch/mips/realtek/Makefile | 6 + .../files-4.14/arch/mips/realtek/Platform | 13 + .../files-4.14/arch/mips/realtek/gpio.c | 302 ++++ .../files-4.14/arch/mips/realtek/irq.c | 297 ++++ .../files-4.14/arch/mips/realtek/prom.c | 55 + .../arch/mips/realtek/rtl819x-timer.c | 219 +++ .../files-4.14/arch/mips/realtek/setup.c | 132 ++ .../files-4.14/drivers/spi/spi-realtek.c | 340 ++++ .../files-4.14/drivers/spi/spi-sheipa.c | 1467 +++++++++++++++++ .../files-4.14/drivers/spi/spi-sheipa.h | 511 ++++++ target/linux/realtek/image/Makefile | 299 ++++ .../linux/realtek/image/lzma-loader/Makefile | 63 + .../image/lzma-loader/src/LzmaDecode.c | 584 +++++++ .../image/lzma-loader/src/LzmaDecode.h | 113 ++ .../realtek/image/lzma-loader/src/LzmaTypes.h | 45 + .../realtek/image/lzma-loader/src/Makefile | 102 ++ .../realtek/image/lzma-loader/src/board.c | 47 + .../realtek/image/lzma-loader/src/cache.c | 65 + .../realtek/image/lzma-loader/src/cache.h | 17 + .../realtek/image/lzma-loader/src/cacheops.h | 50 + .../realtek/image/lzma-loader/src/head.S | 164 ++ .../realtek/image/lzma-loader/src/loader.c | 192 +++ .../realtek/image/lzma-loader/src/loader.lds | 34 + .../realtek/image/lzma-loader/src/loader2.lds | 10 + .../image/lzma-loader/src/lzma-data.lds | 8 + .../realtek/image/lzma-loader/src/printf.c | 350 ++++ .../realtek/image/lzma-loader/src/printf.h | 18 + .../patches-4.14/0001-add-lexra-cpu.patch | 509 ++++++ .../0002-add-realtek-targets.patch | 58 + .../patches-4.14/0003-spi-drivers.patch | 38 + .../patches-4.14/0004-rtl8197f-dw-uart.patch | 129 ++ .../patches-4.14/0005-pci-realtek.patch | 10 + target/linux/realtek/rtl8196e/config-4.14 | 252 +++ .../realtek/rtl8196e/profiles/00-Default.mk | 17 + target/linux/realtek/rtl8196e/target.mk | 15 + target/linux/realtek/rtl8197d/config-4.14 | 241 +++ .../realtek/rtl8197d/profiles/00-Default.mk | 17 + target/linux/realtek/rtl8197d/target.mk | 15 + target/linux/realtek/rtl8197f/config-4.14 | 265 +++ .../realtek/rtl8197f/profiles/00-Default.mk | 17 + target/linux/realtek/rtl8197f/target.mk | 15 + 74 files changed, 10010 insertions(+) create mode 100644 target/linux/realtek/Makefile create mode 100755 target/linux/realtek/base-files/etc/board.d/01_leds create mode 100755 target/linux/realtek/base-files/etc/board.d/02_network create mode 100644 target/linux/realtek/base-files/etc/uci-defaults/09_fix-header create mode 100644 target/linux/realtek/base-files/lib/preinit/01_preinit_do_realtek_board_detection create mode 100755 target/linux/realtek/base-files/lib/realtek.sh create mode 100644 target/linux/realtek/base-files/lib/upgrade/platform.sh create mode 100644 target/linux/realtek/dts/ACTIONRF1200.dts create mode 100644 target/linux/realtek/dts/ACTIONRG1200.dts create mode 100644 target/linux/realtek/dts/DIR815D1.dts create mode 100644 target/linux/realtek/dts/DIR822C1.dts create mode 100644 target/linux/realtek/dts/GWR1200ACV1.dts create mode 100644 target/linux/realtek/dts/GWR1200ACV2.dts create mode 100644 target/linux/realtek/dts/GWR300.dts create mode 100644 target/linux/realtek/dts/RE172.dts create mode 100644 target/linux/realtek/dts/RE707.dts create mode 100644 target/linux/realtek/dts/RE708.dts create mode 100644 target/linux/realtek/dts/RTL8197F.dtsi create mode 100644 target/linux/realtek/dts/RTL8197FVG.dtsi create mode 100644 target/linux/realtek/dts/RTL819X.dtsi create mode 100644 target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/Makefile create mode 100644 target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/RTL8197F.dtsi create mode 100644 target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8196e.dts create mode 100644 target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197d.dts create mode 100644 target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197f.dts create mode 100644 target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl819x.dtsi create mode 100644 target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/lxregs.h create mode 100644 target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/realtek_mem.h create mode 100644 target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8196e/cpu-feature-overrides.h create mode 100644 target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8197d/cpu-feature-overrides.h create mode 100644 target/linux/realtek/files-4.14/arch/mips/mm/c-lexra.c create mode 100644 target/linux/realtek/files-4.14/arch/mips/pci/pci-realtek.c create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/Kconfig create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/Makefile create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/Platform create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/gpio.c create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/irq.c create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/prom.c create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/rtl819x-timer.c create mode 100644 target/linux/realtek/files-4.14/arch/mips/realtek/setup.c create mode 100644 target/linux/realtek/files-4.14/drivers/spi/spi-realtek.c create mode 100644 target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.c create mode 100644 target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.h create mode 100644 target/linux/realtek/image/Makefile create mode 100644 target/linux/realtek/image/lzma-loader/Makefile create mode 100644 target/linux/realtek/image/lzma-loader/src/LzmaDecode.c create mode 100644 target/linux/realtek/image/lzma-loader/src/LzmaDecode.h create mode 100644 target/linux/realtek/image/lzma-loader/src/LzmaTypes.h create mode 100644 target/linux/realtek/image/lzma-loader/src/Makefile create mode 100644 target/linux/realtek/image/lzma-loader/src/board.c create mode 100644 target/linux/realtek/image/lzma-loader/src/cache.c create mode 100644 target/linux/realtek/image/lzma-loader/src/cache.h create mode 100644 target/linux/realtek/image/lzma-loader/src/cacheops.h create mode 100644 target/linux/realtek/image/lzma-loader/src/head.S create mode 100644 target/linux/realtek/image/lzma-loader/src/loader.c create mode 100644 target/linux/realtek/image/lzma-loader/src/loader.lds create mode 100644 target/linux/realtek/image/lzma-loader/src/loader2.lds create mode 100644 target/linux/realtek/image/lzma-loader/src/lzma-data.lds create mode 100644 target/linux/realtek/image/lzma-loader/src/printf.c create mode 100644 target/linux/realtek/image/lzma-loader/src/printf.h create mode 100644 target/linux/realtek/patches-4.14/0001-add-lexra-cpu.patch create mode 100644 target/linux/realtek/patches-4.14/0002-add-realtek-targets.patch create mode 100644 target/linux/realtek/patches-4.14/0003-spi-drivers.patch create mode 100644 target/linux/realtek/patches-4.14/0004-rtl8197f-dw-uart.patch create mode 100644 target/linux/realtek/patches-4.14/0005-pci-realtek.patch create mode 100644 target/linux/realtek/rtl8196e/config-4.14 create mode 100644 target/linux/realtek/rtl8196e/profiles/00-Default.mk create mode 100644 target/linux/realtek/rtl8196e/target.mk create mode 100644 target/linux/realtek/rtl8197d/config-4.14 create mode 100644 target/linux/realtek/rtl8197d/profiles/00-Default.mk create mode 100644 target/linux/realtek/rtl8197d/target.mk create mode 100644 target/linux/realtek/rtl8197f/config-4.14 create mode 100644 target/linux/realtek/rtl8197f/profiles/00-Default.mk create mode 100644 target/linux/realtek/rtl8197f/target.mk diff --git a/target/linux/realtek/Makefile b/target/linux/realtek/Makefile new file mode 100644 index 0000000000000..b8f0f9a837fea --- /dev/null +++ b/target/linux/realtek/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2008-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mips +BOARD:=realtek +BOARDNAME:=Realtek +SUBTARGETS:=rtl8197d rtl8196e rtl8197f +FEATURES:=squashfs gpio +MAINTAINER:=Anlix + +KERNEL_PATCHVER:=4.14 + +define Target/Description + Build firmware images for Realtek based boards. +endef + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES += \ + kmod-gpio-button-hotplug swconfig + +$(eval $(call BuildTarget)) diff --git a/target/linux/realtek/base-files/etc/board.d/01_leds b/target/linux/realtek/base-files/etc/board.d/01_leds new file mode 100755 index 0000000000000..7f04eb019d875 --- /dev/null +++ b/target/linux/realtek/base-files/etc/board.d/01_leds @@ -0,0 +1,65 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh + +board_config_update + +board=$(cat /tmp/sysinfo/board_name) + +case $board in + dir-815-d1) + ucidef_set_led_switch "lan1" "lan1" "rtl819x:green:lan1" "switch0" "0x1" + ucidef_set_led_switch "lan2" "lan2" "rtl819x:green:lan2" "switch0" "0x2" + ucidef_set_led_switch "lan3" "lan3" "rtl819x:green:lan3" "switch0" "0x4" + ucidef_set_led_switch "lan4" "lan4" "rtl819x:green:lan4" "switch0" "0x8" + ucidef_set_led_switch "wan" "wan" "rtl819x:green:wan" "switch0" "0x10" + ucidef_set_led_netdev "wifi_led_2g" "wifi_2g" "rtl8192cd:green:wifi2" "wlan0" + ucidef_set_led_netdev "wifi_led_5g" "wifi_5g" "rtl8192cd:green:wifi5" "wlan1" + ;; + gwr-300n-v1|\ + re172-v1) + ucidef_set_led_switch "lan1" "lan1" "rtl819x:green:lan1" "switch0" "0x1" + ucidef_set_led_switch "lan2" "lan2" "rtl819x:green:lan2" "switch0" "0x2" + ucidef_set_led_switch "lan3" "lan3" "rtl819x:green:lan3" "switch0" "0x4" + ucidef_set_led_switch "lan4" "lan4" "rtl819x:green:lan4" "switch0" "0x8" + ucidef_set_led_switch "wan" "wan" "rtl819x:green:wan" "switch0" "0x10" + ucidef_set_led_netdev "wifi_led_2g" "wifi_2g" "rtl8192cd:green:wifi2" "wlan0" + ;; + actionrg1200-v1) + ucidef_set_led_netdev "lan" "lan" "actionrg1200:blue:lan" "eth0" "tx rx" + ucidef_set_led_netdev "wan" "wan" "actionrg1200:blue:wan" "eth1" "tx rx" + ucidef_set_led_netdev "wifi0" "wifi0" "actionrg1200:blue:wifi0" "wlan0" "link tx rx" + ucidef_set_led_default "sys" "sys" "actionrg1200:blue:sys" "1" + ;; + actionrf1200-v1) + ucidef_set_led_netdev "wifi0" "wifi0" "actionrf1200:blue:wifi0" "wlan0" "link tx rx" + ucidef_set_led_default "sys" "sys" "actionrf1200:blue:sys" "1" + ;; + re708-v1) + ucidef_set_led_switch "wan" "wan" "rtl8367r:green:wan" "switch0" "0x10" + ucidef_set_led_switch "lan1" "lan1" "rtl8367r:green:lan1" "switch0" "0x1" + ucidef_set_led_switch "lan2" "lan2" "rtl8367r:green:lan2" "switch0" "0x2" + ucidef_set_led_switch "lan3" "lan3" "rtl8367r:green:lan3" "switch0" "0x4" + ucidef_set_led_switch "lan4" "lan4" "rtl8367r:green:lan4" "switch0" "0x8" + ucidef_set_led_netdev "wifi0" "wifi0" "rtl8192cd:green:wifi0" "wlan0" "link tx rx" + ucidef_set_led_netdev "wifi1" "wifi1" "rtl8192cd:green:wifi1" "wlan1" "link tx rx" + # Breaks device switch. Still needs fix before using it + # ucidef_set_led_default "wps" "wps" "re708:green:wps" "0" + ;; + gwr1200ac-v1) + ucidef_set_led_netdev "wifi0" "wifi0" "rtl8192cd:green:wifi0" "wlan0" "link tx rx" + ucidef_set_led_netdev "wifi1" "wifi1" "rtl8192cd:green:wifi1" "wlan1" "link tx rx" + # Breaks device switch. Still needs fix before using it + # ucidef_set_led_default "wps" "wps" "gwr1200ac:green:wps" "0" + ;; + gwr1200ac-v2) + ucidef_set_led_default "wifi0" "wifi0" "rtl8192cd:green:wifi0" "1" + ucidef_set_led_default "wifi1" "wifi1" "rtl8192cd:green:wifi1" "1" + # Breaks device switch. Still needs fix before using it + # ucidef_set_led_default "wps" "wps" "gwr1200ac:green:wps" "0" + ;; +esac + +board_config_flush + +exit 0 diff --git a/target/linux/realtek/base-files/etc/board.d/02_network b/target/linux/realtek/base-files/etc/board.d/02_network new file mode 100755 index 0000000000000..2b63d1db9dc23 --- /dev/null +++ b/target/linux/realtek/base-files/etc/board.d/02_network @@ -0,0 +1,53 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/uci-defaults.sh +. /lib/functions/system.sh + +board_config_update +board=$(cat /tmp/sysinfo/board_name) + +ucidef_set_interfaces_lan_wan "eth0" "eth1" + +lan_mac="" +wan_mac="" + +case $board in + dir-815-d1) + offset=$(strings -t x "$(find_mtd_part boot)" | grep llconfig | head -n 1 | awk '{ print "0x"$1 }') + offset=$((offset+53)) + wan_mac=$(mtd_get_mac_binary boot $offset) + lan_mac=$(macaddr_add "$wan_mac" 1) + ;; + re708-v1) + wan_mac=$(mtd_get_mac_binary boot 131079) + lan_mac=$(macaddr_add "$wan_mac" 1) + ;; + gwr1200ac-v1) + wan_mac=$(mtd_get_mac_binary boot 131091) + lan_mac=$(macaddr_add "$wan_mac" 1) + ;; + gwr1200ac-v2) + wan_mac=$(mtd_get_mac_binary boot 131091) + lan_mac=$(macaddr_add "$wan_mac" 1) + ;; + actionrg1200-v1 | \ + actionrf1200-v1) + wan_mac=$(mtd_get_mac_ascii boot HW_NIC0_ADDR) + lan_mac=$(macaddr_add "$wan_mac" 1) + ;; + gwr-300n-v1) + wan_mac=$(mtd_get_mac_binary boot 24595) + lan_mac=$(mtd_get_mac_binary boot 24583) + ;; + re172-v1) + wan_mac=$(mtd_get_mac_binary boot 24583) + lan_mac=$(mtd_get_mac_binary boot 24595) +esac + +[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac +[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac + +board_config_flush + +exit 0 diff --git a/target/linux/realtek/base-files/etc/uci-defaults/09_fix-header b/target/linux/realtek/base-files/etc/uci-defaults/09_fix-header new file mode 100644 index 0000000000000..2f215901a007c --- /dev/null +++ b/target/linux/realtek/base-files/etc/uci-defaults/09_fix-header @@ -0,0 +1,47 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/system.sh + +fix_header() { + mtdblock_path=$(find_mtd_part firmware) + mtdblockroot_path=$(find_mtd_part rootfs) + mtdblockfs_path=$(find_mtd_part rootfs_data) + mtdblockroot_size=$(mtd_get_part_size rootfs) + mtdblockfs_size=$(mtd_get_part_size rootfs_data) + mtdblockfsdiff_size=$((mtdblockroot_size-mtdblockfs_size)) + + imgsize_after_format=$(dd if=$mtdblockroot_path bs=1 skip=$((mtdblockfsdiff_size-16)) count=4 2> /dev/null | \ + hexdump -C | awk 'NR==1 {printf $2$3$4$5}') + + imutable_hex=$(dd if=$mtdblock_path bs=1 count=12 2> /dev/null | \ + hexdump -C | awk 'NR==1 {printf $2$3$4$5$6$7$8$9$10$11$12$13}') + + size_discounted_hex= + imutable_hex_concat= + + for i in `seq 0 2 6` + do + draw="${imgsize_after_format:i:2}" + size_discounted_hex=$size_discounted_hex'\x'$draw + done + + for i in `seq 0 2 22` + do + dimun="${imutable_hex:i:2}" + imutable_hex_concat=$imutable_hex_concat'\x'$dimun + done + + printf $imutable_hex_concat$size_discounted_hex > /tmp/newcvimgheader.bin + dd if=/tmp/newcvimgheader.bin bs=1 count=16 of=$mtdblock_path 2> /dev/null + rm /tmp/newcvimgheader.bin +} + +board=$(board_name) + +case "$board" in +actionrg1200-v1 | \ +actionrf1200-v1) + fix_header + ;; +esac diff --git a/target/linux/realtek/base-files/lib/preinit/01_preinit_do_realtek_board_detection b/target/linux/realtek/base-files/lib/preinit/01_preinit_do_realtek_board_detection new file mode 100644 index 0000000000000..48fbeedd0ef6b --- /dev/null +++ b/target/linux/realtek/base-files/lib/preinit/01_preinit_do_realtek_board_detection @@ -0,0 +1,9 @@ +#!/bin/sh + +do_realtek_board_detection() { + . /lib/realtek.sh + + realtek_board_detect +} + +boot_hook_add preinit_main do_realtek_board_detection diff --git a/target/linux/realtek/base-files/lib/realtek.sh b/target/linux/realtek/base-files/lib/realtek.sh new file mode 100755 index 0000000000000..71bf22a088a24 --- /dev/null +++ b/target/linux/realtek/base-files/lib/realtek.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# Copyright (C) 2009-2011 OpenWrt.org +# + +realtek_board_detect() { + local machine + local name + + machine=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /machine/ {print $2}' /proc/cpuinfo) + + case "$machine" in + "GENERIC") + name="rlx" + ;; + *"DIR-815 D1") + name="dir-815-d1" + ;; + *"GWR-300N V1") + name="gwr-300n-v1" + ;; + *"RE172 V1") + name="re172-v1" + ;; + *"RE708 V1") + name="re708-v1" + ;; + *"GWR1200AC V1") + name="gwr1200ac-v1" + ;; + *"GWR1200AC V2") + name="gwr1200ac-v2" + ;; + *"ACTIONRG1200 V1") + name="actionrg1200-v1" + ;; + *"ACTIONRF1200 V1") + name="actionrf1200-v1" + ;; + esac + + # use generic board detect if no name is set + [ -z "$name" ] && return + + [ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/" + + echo "$name" > /tmp/sysinfo/board_name + echo "$machine" > /tmp/sysinfo/model +} + diff --git a/target/linux/realtek/base-files/lib/upgrade/platform.sh b/target/linux/realtek/base-files/lib/upgrade/platform.sh new file mode 100644 index 0000000000000..5875ce8db33c9 --- /dev/null +++ b/target/linux/realtek/base-files/lib/upgrade/platform.sh @@ -0,0 +1,16 @@ +# +# Copyright (C) 2011 OpenWrt.org +# + +. /lib/functions/system.sh +. /lib/realtek.sh + +PART_NAME=firmware + +platform_do_upgrade() { + default_do_upgrade "$1" +} + +platform_check_image() { + return 0 +} diff --git a/target/linux/realtek/dts/ACTIONRF1200.dts b/target/linux/realtek/dts/ACTIONRF1200.dts new file mode 100644 index 0000000000000..59447384c1664 --- /dev/null +++ b/target/linux/realtek/dts/ACTIONRF1200.dts @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197F.dtsi" + +#include +#include + +/ { + compatible = "intelbras,actionrf1200", "realtek,rtl8197f-soc"; + model = "Intelbras ACTIONRF1200 V1"; + + aliases { + led-boot = &led_status; + led-failsafe = &led_status; + led-running = &led_status; + led-upgrade = &led_status; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_status: sys { + label = "actionrf1200:blue:sys"; + gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; + }; + + wifi0 { + label = "actionrf1200:blue:wifi0"; + gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + }; + + wan { + label = "actionrf1200:blue:wan"; + gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; + }; + + lan0 { + label = "actionrf1200:blue:lan0"; + gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "actionrf1200:blue:lan1"; + gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "actionrf1200:blue:lan2"; + gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <41000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "firmware"; + reg = <0x30000 0x7B0000>; + }; + + partition@7E0000 { + label = "config"; + reg = <0x7E0000 0x20000>; + read-only; + }; + }; +}; diff --git a/target/linux/realtek/dts/ACTIONRG1200.dts b/target/linux/realtek/dts/ACTIONRG1200.dts new file mode 100644 index 0000000000000..36e79b4c6792d --- /dev/null +++ b/target/linux/realtek/dts/ACTIONRG1200.dts @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197F.dtsi" + +#include +#include + +/ { + compatible = "intelbras,actionrg1200", "realtek,rtl8197f-soc"; + model = "Intelbras ACTIONRG1200 V1"; + + aliases { + led-boot = &led_status; + led-failsafe = &led_status; + led-running = &led_status; + led-upgrade = &led_status; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_status: sys { + label = "actionrg1200:blue:sys"; + gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + }; + + wan { + label = "actionrg1200:blue:wan"; + gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + }; + + lan { + label = "actionrg1200:blue:lan"; + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + }; + + wifi0 { + label = "actionrg1200:blue:wifi0"; + gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <41000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "firmware"; + reg = <0x30000 0x7B0000>; + }; + + partition@7E0000 { + label = "config"; + reg = <0x7E0000 0x20000>; + read-only; + }; + }; +}; diff --git a/target/linux/realtek/dts/DIR815D1.dts b/target/linux/realtek/dts/DIR815D1.dts new file mode 100644 index 0000000000000..aa839886c69e8 --- /dev/null +++ b/target/linux/realtek/dts/DIR815D1.dts @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL819X.dtsi" + +#include +#include + +/ { + compatible = "D-Link,dir-815-d1", "realtek,rtl819x-soc"; + model = "D-Link DIR-815 D1"; + + cpus { + cpu@0 { + compatible = "realtek,rlx5281"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + wps { + label = "dir815:green:wps"; + gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + }; + + wan { + label = "dir815:green:wan"; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "dir815:green:lan1"; + gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "dir815:green:lan2"; + gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; + + lan3 { + label = "dir815:green:lan3"; + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + }; + + lan4 { + label = "dir815:green:lan4"; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x30000>; + read-only; + }; + kernel: partition@30000 { + label = "kernel"; + reg = <0x30000 0x1D0000>; + }; + partition@200000 { + label = "rootfs"; + reg = <0x200000 0x5E0000>; + }; + factory: partition@7E0000 { + label = "factory"; + reg = <0x7E0000 0x20000>; + read-only; + }; + firmware@30000 { + label = "firmware"; + reg = <0x30000 0x7B0000>; + }; + }; +}; diff --git a/target/linux/realtek/dts/DIR822C1.dts b/target/linux/realtek/dts/DIR822C1.dts new file mode 100644 index 0000000000000..797d503ae4155 --- /dev/null +++ b/target/linux/realtek/dts/DIR822C1.dts @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL819X.dtsi" + +/ { + compatible = "D-Link,dir-822-c1", "realtek,rtl819x-soc"; + model = "D-Link DIR-822 C1"; + + cpus { + cpu@0 { + compatible = "realtek,rlx5281"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; + +}; diff --git a/target/linux/realtek/dts/GWR1200ACV1.dts b/target/linux/realtek/dts/GWR1200ACV1.dts new file mode 100644 index 0000000000000..530a03696c12c --- /dev/null +++ b/target/linux/realtek/dts/GWR1200ACV1.dts @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197F.dtsi" + +#include +#include + +/ { + compatible = "greatek,gwr1200ac", "realtek,rtl8197f-soc"; + model = "Greatek GWR1200AC V1"; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + // Breaks device switch. Still needs fix before using it + // gpio-leds { + // compatible = "gpio-leds"; + + // wps { + // label = "gwr1200ac:green:wps"; + // gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + // }; + // }; + +}; + +&gpio1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <41000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "firmware"; + reg = <0x30000 0x7C0000>; + }; + }; +}; diff --git a/target/linux/realtek/dts/GWR1200ACV2.dts b/target/linux/realtek/dts/GWR1200ACV2.dts new file mode 100644 index 0000000000000..3d53fcbb88d50 --- /dev/null +++ b/target/linux/realtek/dts/GWR1200ACV2.dts @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197FVG.dtsi" + +#include +#include + +/ { + compatible = "greatek,gwr1200ac", "realtek,rtl8197f-soc"; + model = "Greatek GWR1200AC V2"; + + aliases { + led-boot = &led_status; + led-failsafe = &led_status; + led-running = &led_status; + led-upgrade = &led_status; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + led_status: power { + label = "gwr1200ac:green:power"; + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; + }; + + // Breaks device switch. Still needs fix before using it + // wps { + // label = "gwr1200ac:green:wps"; + // gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + // }; + + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <41000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "firmware"; + reg = <0x30000 0x7C0000>; + }; + }; +}; diff --git a/target/linux/realtek/dts/GWR300.dts b/target/linux/realtek/dts/GWR300.dts new file mode 100644 index 0000000000000..e1634df4dc727 --- /dev/null +++ b/target/linux/realtek/dts/GWR300.dts @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL819X.dtsi" + +#include +#include + +/ { + compatible = "greatek,gwr300", "realtek,rtl819x-soc"; + model = "Greatek GWR-300N V1"; + + cpus { + cpu@0 { + compatible = "realtek,rlx4181"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x2000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + wan { + label = "gwr300:green:wan"; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + }; + + lan1 { + label = "gwr300:green:lan1"; + gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; + }; + + lan2 { + label = "gwr300:green:lan2"; + gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + }; + + lan3 { + label = "gwr300:green:lan3"; + gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; + + lan4 { + label = "gwr300:green:lan4"; + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x18000>; + read-only; + }; + + partition@18000 { + label = "firmware"; + reg = <0x18000 0x3E8000>; + }; + }; +}; diff --git a/target/linux/realtek/dts/RE172.dts b/target/linux/realtek/dts/RE172.dts new file mode 100644 index 0000000000000..18f0503aedf7e --- /dev/null +++ b/target/linux/realtek/dts/RE172.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL819X.dtsi" + +/ { + compatible = "multilaser,re172", "realtek,rtl819x-soc"; + model = "Multilaser RE172 V1"; + + cpus { + cpu@0 { + compatible = "realtek,rlx4181"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x2000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; +}; + + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x10000>; + read-only; + }; + + partition@10000 { + label = "firmware"; + reg = <0x10000 0x3F0000>; + }; + }; +}; + +&pcie0 { + status = "okay"; +}; diff --git a/target/linux/realtek/dts/RE707.dts b/target/linux/realtek/dts/RE707.dts new file mode 100644 index 0000000000000..535ef51246d78 --- /dev/null +++ b/target/linux/realtek/dts/RE707.dts @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL819X.dtsi" + +/ { + compatible = "multilaser,re707", "realtek,rtl819x-soc"; + model = "Multilaser RE707 V1"; + + cpus { + cpu@0 { + compatible = "realtek,rlx4181"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x2000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; +}; + + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x20000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x20000 0x3E0000>; + }; + }; +}; diff --git a/target/linux/realtek/dts/RE708.dts b/target/linux/realtek/dts/RE708.dts new file mode 100644 index 0000000000000..9757efcf1c238 --- /dev/null +++ b/target/linux/realtek/dts/RE708.dts @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197F.dtsi" + +#include +#include + +/ { + compatible = "multilaser,re708", "realtek,rtl8197f-soc"; + model = "Multilaser RE708 V1"; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + + reset { + label = "reset"; + gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + // Breaks device switch. Still needs fix before using it + // gpio-leds { + // compatible = "gpio-leds"; + + // wps { + // label = "re708:green:wps"; + // gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + // }; + // }; + +}; + +&gpio1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <41000000>; + + partition@0 { + label = "boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "firmware"; + reg = <0x30000 0x7C0000>; + }; + }; +}; diff --git a/target/linux/realtek/dts/RTL8197F.dtsi b/target/linux/realtek/dts/RTL8197F.dtsi new file mode 100644 index 0000000000000..7ec8a40e2cdd3 --- /dev/null +++ b/target/linux/realtek/dts/RTL8197F.dtsi @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "realtek,rtl8197f-soc"; + + cpus { + cpu@0 { + compatible = "mips,mips24KEc"; + }; + }; + + cpuintc: cpuintc { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + soc { + compatible = "simple-bus"; + ranges = <0x0 0x18000000 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "realtek,rtl819x-sysc"; + reg = <0x0 0x1000>; + }; + + memc: memory-controller@1000 { + compatible = "realtek,rtl819x-memc"; + reg = <0x1000 0x100>; + }; + + intc: intc@3000 { + compatible = "realtek,rtl819x-intc"; + reg = <0x3000 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + gpio0: gpio-controller@3500 { + compatible = "realtek,rtl8197f-gpio"; + reg = <0x3500 0x1c>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio1: gpio-controller@351C { + compatible = "realtek,rtl8197f-gpio"; + reg = <0x351C 0x1c>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + }; + + serial0: serial@18147000 { + compatible = "realtek,rtl8197f-uart", "snps,dw-apb-uart"; + reg = <0x18147000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <9>; + + reg-io-width = <4>; + reg-shift = <2>; + clock-frequency = <100000000>; + }; + + spi0: spi@18143000 { + compatible = "realtek,sheipa-spi"; + reg = <0x18143000 0x1000 + 0x10000000 0x2000000>; + + #address-cells = <1>; + #size-cells = <0>; + + clock-frequency = <100000000>; + + status = "disabled"; + }; +}; diff --git a/target/linux/realtek/dts/RTL8197FVG.dtsi b/target/linux/realtek/dts/RTL8197FVG.dtsi new file mode 100644 index 0000000000000..09f9ca3a7f362 --- /dev/null +++ b/target/linux/realtek/dts/RTL8197FVG.dtsi @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197F.dtsi" + +&serial0 { + compatible = "ns16550a"; + reg = <0x18147000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <9>; + + reg-io-width = <4>; + reg-shift = <2>; + clock-frequency = <100000000>; +}; + diff --git a/target/linux/realtek/dts/RTL819X.dtsi b/target/linux/realtek/dts/RTL819X.dtsi new file mode 100644 index 0000000000000..4b843acc1b121 --- /dev/null +++ b/target/linux/realtek/dts/RTL819X.dtsi @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0 +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "realtek,rtl819x-soc"; + + cpuintc: cpuintc { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + refclk: refclk { + /* 25Mhz default clock */ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <25000000>; + }; + + clk40: clk40 { + /* 40Mhz alternative clock */ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <40000000>; + }; + + soc { + compatible = "simple-bus"; + ranges = <0x0 0x18000000 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "realtek,rtl819x-sysc"; + reg = <0x0 0x1000>; + }; + + memc: memory-controller@1000 { + compatible = "realtek,rtl819x-memc"; + reg = <0x1000 0x100>; + }; + + uartlite: serial@2000 { + compatible = "realtek,rtl819x-uart", "ns16550a"; + reg = <0x2000 0x20>; + + interrupt-parent = <&intc>; + interrupts = <12>; + + reg-shift = <2>; + clock-frequency = <200000000>; + }; + + intc: intc@3000 { + compatible = "realtek,rtl819x-intc"; + reg = <0x3000 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + timer: timer-controller@3100 { + compatible = "realtek,rtl819x-timer"; + reg = <0x3100 0x20>; + + interrupt-parent = <&cpuintc>; + interrupts = <7>; + + clocks = <&refclk>; + }; + + gpio0: gpio-controller@3500 { + compatible = "realtek,realtek-gpio"; + reg = <0x3500 0x1c>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio1: gpio-controller@351C { + compatible = "realtek,realtek-gpio"; + reg = <0x351C 0x1c>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + spi0: spi@1200 { + compatible = "realtek,rtl819x-spi"; + reg = <0x1200 0x10>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + pcie0: pcie-controller@18b00000 { + compatible = "realtek,rtl8196b-pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0 255>; + reg = <0x18b00000 0x1000>, /* RC CFG */ + <0x18b01000 0x1000>, /* RC CFG EXT */ + <0x18b10000 0x1000>, /* DEV CFG0 (EP) */ + <0x18b11000 0x1000>; /* DEV CFG1 (EP) */ + reg-names = "rc_cfg_base", "rc_ext_base", "dev_cfg0_base", "dev_cfg1_base"; + ranges = <0x02000000 0 0x00000000 0x19000000 0 0x01000000 /* pci memory */ + 0x01000000 0 0x00000000 0x18c00000 0 0x00200000>; /* io space */ + interrupt-parent = <&cpuintc>; + interrupts = <5>; + clocks = <&refclk>; + + status = "disabled"; + }; + + pcie1: pcie-controller@18b20000 { + compatible = "realtek,rtl8196b-pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0 255>; + reg = <0x18b20000 0x1000>, /* RC CFG */ + <0x18b21000 0x1000>, /* RC CFG EXT */ + <0x18b30000 0x1000>, /* DEV CFG0 (EP) */ + <0x18b31000 0x1000>; /* DEV CFG1 (EP) */ + reg-names = "rc_cfg_base", "rc_ext_base", "dev_cfg0_base", "dev_cfg1_base"; + ranges = <0x02000000 0 0x00000000 0x1a000000 0 0x01000000 /* pci memory */ + 0x01000000 0 0x00000000 0x18e00000 0 0x00200000>; /* io space */ + interrupt-parent = <&cpuintc>; + interrupts = <6>; + clocks = <&refclk>; + + status = "disabled"; + }; +}; diff --git a/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/Makefile b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/Makefile new file mode 100644 index 0000000000000..64fd2607b1b10 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_DTB_RTL8197F_GEN) += rtl8197f.dtb +dtb-$(CONFIG_DTB_RTL8197D_GEN) += rtl8197d.dtb +dtb-$(CONFIG_DTB_RTL8196E_GEN) += rtl8196e.dtb + +obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) + +# Force kbuild to make empty built-in.o if necessary +obj- += dummy.o + +always := $(dtb-y) +clean-files := *.dtb *.dtb.S diff --git a/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/RTL8197F.dtsi b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/RTL8197F.dtsi new file mode 100644 index 0000000000000..7ec8a40e2cdd3 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/RTL8197F.dtsi @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "realtek,rtl8197f-soc"; + + cpus { + cpu@0 { + compatible = "mips,mips24KEc"; + }; + }; + + cpuintc: cpuintc { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + soc { + compatible = "simple-bus"; + ranges = <0x0 0x18000000 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "realtek,rtl819x-sysc"; + reg = <0x0 0x1000>; + }; + + memc: memory-controller@1000 { + compatible = "realtek,rtl819x-memc"; + reg = <0x1000 0x100>; + }; + + intc: intc@3000 { + compatible = "realtek,rtl819x-intc"; + reg = <0x3000 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + gpio0: gpio-controller@3500 { + compatible = "realtek,rtl8197f-gpio"; + reg = <0x3500 0x1c>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + + gpio1: gpio-controller@351C { + compatible = "realtek,rtl8197f-gpio"; + reg = <0x351C 0x1c>; + gpio-controller; + #gpio-cells = <2>; + status = "disabled"; + }; + }; + + serial0: serial@18147000 { + compatible = "realtek,rtl8197f-uart", "snps,dw-apb-uart"; + reg = <0x18147000 0x100>; + + interrupt-parent = <&intc>; + interrupts = <9>; + + reg-io-width = <4>; + reg-shift = <2>; + clock-frequency = <100000000>; + }; + + spi0: spi@18143000 { + compatible = "realtek,sheipa-spi"; + reg = <0x18143000 0x1000 + 0x10000000 0x2000000>; + + #address-cells = <1>; + #size-cells = <0>; + + clock-frequency = <100000000>; + + status = "disabled"; + }; +}; diff --git a/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8196e.dts b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8196e.dts new file mode 100644 index 0000000000000..38607b083f6bb --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8196e.dts @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "rtl819x.dtsi" + +/ { + compatible = "realtek,rtl8196e-generic", "realtek,rtl819x-soc"; + model = "Realtek RTL8196E Generic Board"; + + cpus { + cpu@0 { + compatible = "realtek,rlx4181"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x2000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; +}; + + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12000000>; + + partition@0 { + label = "bootloader"; + reg = <0x0 0x20000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x20000 0x3E0000>; + }; + }; +}; diff --git a/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197d.dts b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197d.dts new file mode 100644 index 0000000000000..2762dc373d1ae --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197d.dts @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +/include/ "rtl819x.dtsi" + +/ { + compatible = "realtek,rtl8197d-generic", "realtek,rtl819x-soc"; + model = "Realtek RTL8197D Generic Board"; + + cpus { + cpu@0 { + compatible = "realtek,rlx5281"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + +}; diff --git a/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197f.dts b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197f.dts new file mode 100644 index 0000000000000..6e20ee49dade7 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl8197f.dts @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "RTL8197F.dtsi" + +/ { + compatible = "realtek,rtl8197f-generic", "realtek,rtl8197f-soc"; + model = "Realtek RTL8197F Generic Board"; + + memory { + device_type = "memory"; + reg = <0x0 0x4000000>; + }; + + chosen { + bootargs = "console=ttyS0,38400"; + }; +}; + +&spi0 { + status = "okay"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <41000000>; + + partition@0 { + label = "bootloader"; + reg = <0x0 0x20000>; + read-only; + }; + + partition@20000 { + label = "firmware"; + reg = <0x20000 0x3E0000>; + }; + }; +}; diff --git a/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl819x.dtsi b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl819x.dtsi new file mode 100644 index 0000000000000..c021b4273106d --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/boot/dts/realtek/rtl819x.dtsi @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "realtek,rtl819x-soc"; + + cpuintc: cpuintc { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + refclk: refclk { + /* 25Mhz default clock */ + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <25000000>; + }; + + soc { + compatible = "simple-bus"; + ranges = <0x0 0x18000000 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "realtek,rtl819x-sysc"; + reg = <0x0 0x1000>; + }; + + memc: memory-controller@1000 { + compatible = "realtek,rtl819x-memc"; + reg = <0x1000 0x100>; + }; + + uartlite: serial@2000 { + compatible = "realtek,rtl819x-uart", "ns16550a"; + reg = <0x2000 0x20>; + + interrupt-parent = <&intc>; + interrupts = <12>; + + reg-shift = <2>; + clock-frequency = <200000000>; + }; + + intc: intc@3000 { + compatible = "realtek,rtl819x-intc"; + reg = <0x3000 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + }; + + timer: timer-controller@3100 { + compatible = "realtek,rtl819x-timer"; + reg = <0x3100 0x20>; + + interrupt-parent = <&cpuintc>; + interrupts = <7>; + + clocks = <&refclk>; + }; + + spi0: spi@1200 { + compatible = "realtek,rtl819x-spi"; + reg = <0x1200 0x10>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + }; +}; diff --git a/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/lxregs.h b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/lxregs.h new file mode 100644 index 0000000000000..5dc61af3808e0 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/lxregs.h @@ -0,0 +1,197 @@ +/* + * Lexra specific register definitions + * + * Copyright (C) 2017 Weijie Gao + * + * 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_LXREGS_H +#define _ASM_LXREGS_H + +/* + * Lexra specific CP0 register names + */ +#define LXCP0_ESTATUS $0 +#define LXCP0_ECAUSE $1 +#define LXCP0_INTVEC $2 + +#define CP0_CCTL $20 +#define CCTL_DInval 0x00000001 +#define CCTL_IInval 0x00000002 +#define CCTL_ILock 0x000000c0 +#define CCTL_IMEMFILL 0x00000010 +#define CCTL_IMEMOFF 0x00000020 +#define CCTL_IROM0ON 0x00000040 +#define CCTL_IROM0OFF 0x00000080 +#define CCTL_DWB 0x00000100 +#define CCTL_DWBInval 0x00000200 +#define CCTL_DMEMON 0x00000400 +#define CCTL_DMEMOFF 0x00000800 + +/* + * Lexra specific CP3 register names + */ +#define CP3_IMEMBASE $0 +#define CP3_IMEMTOP $1 +#define CP3_IMEM1BASE $2 +#define CP3_IMEM1TOP $3 +#define CP3_DMEMBASE $4 +#define CP3_DMEMTOP $5 +#define CP3_DMEM1BASE $6 +#define CP3_DMEM1TOP $7 + + +/* + * Lexra specific status register bits + */ +#define EST0_IM 0x00ff0000 +#define ESTATUSF_IP0 (_ULCAST_(1) << 16) +#define ESTATUSF_IP1 (_ULCAST_(1) << 17) +#define ESTATUSF_IP2 (_ULCAST_(1) << 18) +#define ESTATUSF_IP3 (_ULCAST_(1) << 19) +#define ESTATUSF_IP4 (_ULCAST_(1) << 20) +#define ESTATUSF_IP5 (_ULCAST_(1) << 21) +#define ESTATUSF_IP6 (_ULCAST_(1) << 22) +#define ESTATUSF_IP7 (_ULCAST_(1) << 23) + +#define ECAUSEF_IP (_ULCAST_(255) << 16) +#define ECAUSEF_IP0 (_ULCAST_(1) << 16) +#define ECAUSEF_IP1 (_ULCAST_(1) << 17) +#define ECAUSEF_IP2 (_ULCAST_(1) << 18) +#define ECAUSEF_IP3 (_ULCAST_(1) << 19) +#define ECAUSEF_IP4 (_ULCAST_(1) << 20) +#define ECAUSEF_IP5 (_ULCAST_(1) << 21) +#define ECAUSEF_IP6 (_ULCAST_(1) << 22) +#define ECAUSEF_IP7 (_ULCAST_(1) << 23) + + +#ifndef __ASSEMBLY__ + +/* + * Macros to access the system control coprocessor + */ +#define __read_32bit_lxc0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + "mflxc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_lxc0_register(register, value) \ +do { \ + __asm__ __volatile__( \ + "mtlxc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define __read_32bit_c3_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set push\n" \ + ".set mips1\n" \ + "mfc3\t%0, " #source "\n\t" \ + ".set pop\n" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c3_register(register, value) \ +do { \ + __asm__ __volatile__( \ + ".set push\n" \ + ".set mips1\n" \ + "mtc3\t%z0, " #register "\n\t" \ + ".set pop\n" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + + +#define read_c0_cctl() __read_32bit_c0_register($20, 0) +#define write_c0_cctl(val) __write_32bit_c0_register($20, 0, val) + +#define read_c0_cctl1() __read_32bit_c0_register($20, 1) +#define write_c0_cctl1(val) __write_32bit_c0_register($20, 1, val) + +#define read_c3_imembase() __read_32bit_c3_register($0) +#define write_c3_imembase(val) __write_32bit_c3_register($0, val) + +#define read_c3_imemtop() __read_32bit_c3_register($1) +#define write_c3_imemtop(val) __write_32bit_c3_register($1, val) + +#define read_c3_imem1base() __read_32bit_c3_register($2) +#define write_c3_imem1base(val) __write_32bit_c3_register($2, val) + +#define read_c3_imem1top() __read_32bit_c3_register($3) +#define write_c3_imem1top(val) __write_32bit_c3_register($3, val) + +#define read_c3_dmembase() __read_32bit_c3_register($4) +#define write_c3_dmembase(val) __write_32bit_c3_register($4, val) + +#define read_c3_dmemtop() __read_32bit_c3_register($5) +#define write_c3_dmemtop(val) __write_32bit_c3_register($5, val) + +#define read_c3_dmem1base() __read_32bit_c3_register($6) +#define write_c3_dmem1base(val) __write_32bit_c3_register($6, val) + +#define read_c3_dmem1top() __read_32bit_c3_register($7) +#define write_c3_dmem1top(val) __write_32bit_c3_register($7, val) + + +#define read_lxc0_estatus() __read_32bit_lxc0_register($0) +#define read_lxc0_ecause() __read_32bit_lxc0_register($1) +#define read_lxc0_intvec() __read_32bit_lxc0_register($2) +#define write_lxc0_estatus(val) __write_32bit_lxc0_register($0, val) +#define write_lxc0_ecause(val) __write_32bit_lxc0_register($1, val) +#define write_lxc0_intvec(val) __write_32bit_lxc0_register($2, val) + +/* + * Manipulate bits in a lxc0 register. + */ +#define __BUILD_SET_LXC0(name) \ +static inline unsigned int \ +set_lxc0_##name(unsigned int set) \ +{ \ + unsigned int res, new; \ + \ + res = read_lxc0_##name(); \ + new |= set; \ + write_lxc0_##name(new); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_lxc0_##name(unsigned int clear) \ +{ \ + unsigned int res, new; \ + \ + res = read_lxc0_##name(); \ + new = res & ~clear; \ + write_lxc0_##name(new); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_lxc0_##name(unsigned int change, unsigned int val) \ +{ \ + unsigned int res, new; \ + \ + res = read_lxc0_##name(); \ + new = res & ~change; \ + new |= (val & change); \ + write_lxc0_##name(new); \ + \ + return res; \ +} + +__BUILD_SET_LXC0(estatus) +__BUILD_SET_LXC0(ecause) +__BUILD_SET_LXC0(intvec) + +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_LXREGS_H */ diff --git a/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/realtek_mem.h b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/realtek_mem.h new file mode 100644 index 0000000000000..af2c910bd6a15 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/realtek_mem.h @@ -0,0 +1,18 @@ + +#ifndef __REALTEK_MEMMAP__ +#define __REALTEK_MEMMAP__ + +extern __iomem void *_sys_membase; + +// System registers +#define REALTEK_SR_REG_ID 0x00 +#define REALTEK_SR_REG_BOOTSTRAP 0x08 +#define REALTEK_SR_CLKMANAGE 0x10 +#define REALTEK_SR_PCIE_PHY0 0x50 +#define REALTEK_SR_PCIE_PHY1 0x54 +#define REALTEK_SR_BS_40MHZ BIT(24) // Crystal clock at 40Mhz + +#define sr_w32(val, reg) __raw_writel(val, _sys_membase + reg) +#define sr_r32(reg) __raw_readl(_sys_membase + reg) + +#endif \ No newline at end of file diff --git a/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8196e/cpu-feature-overrides.h b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8196e/cpu-feature-overrides.h new file mode 100644 index 0000000000000..5fd8039ac4ff2 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8196e/cpu-feature-overrides.h @@ -0,0 +1,60 @@ +/* + * Ralink MT7620 specific CPU feature overrides + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This file was derived from: include/asm-mips/cpu-features.h + * Copyright (C) 2003, 2004 Ralf Baechle + * Copyright (C) 2004 Maciej W. Rozycki + * + * 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 _RTL8196E_CPU_FEATURE_OVERRIDES_H +#define _RTL8196E_CPU_FEATURE_OVERRIDES_H + +#define cpu_has_tlb 1 +#define cpu_has_4kex 0 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 0 +#define cpu_has_lexra_cache 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_sb1_cache 0 +#define cpu_has_fpu 0 +#define cpu_has_32fpr 0 +#define cpu_has_counter 0 +#define cpu_has_watch 0 +#define cpu_has_divec 0 + +#define cpu_has_prefetch 0 +#define cpu_has_ejtag 0 +#define cpu_has_llsc 0 + +#define cpu_has_mips16 1 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 + +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 + +#define cpu_has_dsp 0 +#define cpu_has_dsp2 0 +#define cpu_has_mipsmt 0 + +#define cpu_has_64bits 0 +#define cpu_has_64bit_zero_reg 0 +#define cpu_has_64bit_gp_regs 0 +#define cpu_has_64bit_addresses 0 + +#define cpu_has_userlocal 0 + +#define cpu_dcache_line_size() 16 +#define cpu_icache_line_size() 16 + +#endif /* _RTL8196E_CPU_FEATURE_OVERRIDES_H */ diff --git a/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8197d/cpu-feature-overrides.h b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8197d/cpu-feature-overrides.h new file mode 100644 index 0000000000000..49a7bcea7cd69 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/include/asm/mach-realtek/rtl8197d/cpu-feature-overrides.h @@ -0,0 +1,60 @@ +/* + * Ralink MT7620 specific CPU feature overrides + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * This file was derived from: include/asm-mips/cpu-features.h + * Copyright (C) 2003, 2004 Ralf Baechle + * Copyright (C) 2004 Maciej W. Rozycki + * + * 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 _RTL8197D_CPU_FEATURE_OVERRIDES_H +#define _RTL8197D_CPU_FEATURE_OVERRIDES_H + +#define cpu_has_tlb 1 +#define cpu_has_4kex 0 +#define cpu_has_3k_cache 0 +#define cpu_has_4k_cache 0 +#define cpu_has_lexra_cache 1 +#define cpu_has_tx39_cache 0 +#define cpu_has_sb1_cache 0 +#define cpu_has_fpu 0 +#define cpu_has_32fpr 0 +#define cpu_has_counter 0 +#define cpu_has_watch 0 +#define cpu_has_divec 0 + +#define cpu_has_prefetch 0 +#define cpu_has_ejtag 0 +#define cpu_has_llsc 1 + +#define cpu_has_mips16 1 +#define cpu_has_mdmx 0 +#define cpu_has_mips3d 0 +#define cpu_has_smartmips 0 + +#define cpu_has_mips32r1 0 +#define cpu_has_mips32r2 0 +#define cpu_has_mips64r1 0 +#define cpu_has_mips64r2 0 + +#define cpu_has_dsp 0 +#define cpu_has_dsp2 0 +#define cpu_has_mipsmt 0 + +#define cpu_has_64bits 0 +#define cpu_has_64bit_zero_reg 0 +#define cpu_has_64bit_gp_regs 0 +#define cpu_has_64bit_addresses 0 + +#define cpu_has_userlocal 1 + +#define cpu_dcache_line_size() 32 +#define cpu_icache_line_size() 32 + +#endif /* _RTL8197d_CPU_FEATURE_OVERRIDES_H */ diff --git a/target/linux/realtek/files-4.14/arch/mips/mm/c-lexra.c b/target/linux/realtek/files-4.14/arch/mips/mm/c-lexra.c new file mode 100644 index 0000000000000..0e9568073a5ae --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/mm/c-lexra.c @@ -0,0 +1,441 @@ +/* + * Lexra specific mmu/cache code. + * + * Copyright (C) 2017 Weijie Gao + * + * 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. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LEXRA_CCTL_BARRIER \ + do { \ + __asm__ __volatile__ ( "" : : : "memory"); \ + } while (0) + +unsigned long lexra_icache_size, lexra_dcache_size; /* Size in bytes */ +unsigned long lexra_icache_lsize, lexra_dcache_lsize; /* Size in bytes */ + +int lexra_has_dcacheop; +int lexra_has_wb_dcache; + +int lexra_imem0_size = SZ_4K; +int lexra_imem1_size = SZ_4K; +int lexra_has_dual_cmem = 0; + +extern char __iram; +extern char __dram_start; +extern char __dram_end; + +static void lexra_cmem_init(void) +{ + u32 iram_base = CPHYSADDR(((u32) &__iram) & ~(SZ_16K - 1)); + u32 dram_base = CPHYSADDR(((u32) &__dram_start) & ~(SZ_8K - 1)); + + /* XXX: do not use it at present */ + return; + + /* enable co-processor 3 */ + write_c0_status(read_c0_status() | ST0_CU3); + + /* I-MEM off */ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IMEMOFF); + + /* I-Cache/D-Cache invalidate */ + if (lexra_has_wb_dcache) { + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IInval | CCTL_DWBInval); + } else { + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IInval | CCTL_DInval); + } + + if (!lexra_has_dual_cmem) { + /* set I-MEM base and size */ + write_c3_imembase(iram_base); +#if 0 + if (soc_is_rtl819xd()) + write_c3_imemtop(iram_base + SZ_8K - 1); + else +#endif + write_c3_imemtop(iram_base + SZ_16K - 1); + + /* I-MEM refill */ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IMEMFILL); + + if (&__dram_start < &__dram_end) { + /* set D-MEM base and size */ + write_c3_dmembase(dram_base); + write_c3_dmemtop(dram_base + SZ_8K - 1); + + /* D-MEM on */ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DMEMON); + } + } else { + /* set I-MEM0 base and size */ + write_c3_imembase(iram_base); + write_c3_imemtop(iram_base + lexra_imem0_size - 1); + + /* I-MEM0 refill */ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IMEMFILL); + + /* set I-MEM1 base and size */ + write_c3_imem1base(iram_base + lexra_imem0_size); + write_c3_imem1top(iram_base + lexra_imem0_size + lexra_imem1_size - 1); + + /* I-MEM1 refill */ + write_c0_cctl1(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl1(CCTL_IMEMFILL); + + if (&__dram_start < &__dram_end) { + /* set D-MEM0 base and size */ + write_c3_dmembase(dram_base); + write_c3_dmemtop(dram_base + SZ_4K - 1); + + /* D-MEM0 on */ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DMEMON); + + /* set D-MEM1 base and size */ + write_c3_dmem1base(dram_base + SZ_4K); + write_c3_dmem1top(dram_base + SZ_8K - 1); + + /* D-MEM1 on */ + write_c0_cctl1(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl1(CCTL_DMEMON); + } + } + + /* flush */ + write_c0_cctl(0); +} + +static void lexra_wb_inv_dcache_all(void) +{ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DWBInval); +} + +static void lexra_inv_dcache_all(void) +{ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DInval); +} + +static void lexra_wb_dcache_all(void) +{ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DWB); +} + +static void lexra_inv_icache_all(void) +{ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IInval); +} + +static void lexra_wb_inv_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long size, p, flags; + + start &= ~(lexra_dcache_lsize - 1); + size = end - start; + + if (!lexra_has_dcacheop || (size >= lexra_dcache_size * 2)) { + lexra_wb_inv_dcache_all(); + return; + } + + flags = read_c0_status(); + + /* disable interrupt */ + write_c0_status(flags & ~ST0_IEC); + + for (p = start; p < end; p += lexra_dcache_lsize) { + __asm__ __volatile__ ( + ".set\tpush\n" + ".set\tmips3\n" + "cache\t%0, 0(%1)\n" + ".set\tpop" + : : "i" (Hit_Writeback_Inv_D), "r" (p) + ); + } + + /* restore interrupt */ + write_c0_status(flags); +} + +static void lexra_inv_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long size, p, flags; + + start &= ~(lexra_dcache_lsize - 1); + size = end - start; + + if (!lexra_has_dcacheop || (size >= lexra_dcache_size * 2)) { + lexra_inv_dcache_all(); + return; + } + + flags = read_c0_status(); + + /* disable interrupt */ + write_c0_status(flags & ~ST0_IEC); + + for (p = start; p < end; p += lexra_dcache_lsize) { + __asm__ __volatile__ ( + ".set\tpush\n" + ".set\tmips3\n" + "cache\t%0, 0(%1)\n" + ".set\tpop" + : : "i" (Hit_Invalidate_D), "r" (p) + ); + } + + /* restore interrupt */ + write_c0_status(flags); +} + +static void lexra_wb_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long size, p, flags; + + start &= ~(lexra_dcache_lsize - 1); + size = end - start; + + if (!lexra_has_dcacheop || (size >= lexra_dcache_size * 2)) { + lexra_wb_dcache_all(); + return; + } + + flags = read_c0_status(); + + /* disable interrupt */ + write_c0_status(flags & ~ST0_IEC); + + for (p = start; p < end; p += lexra_dcache_lsize) { + __asm__ __volatile__ ( + ".set\tpush\n" + ".set\tmips3\n" + "cache\t%0, 0(%1)\n" + ".set\tpop" + : : "i" (Hit_Writeback_D), "r" (p) + ); + } + + /* restore interrupt */ + write_c0_status(flags); +} + +static void lexra_flush_dcache_range(unsigned long start, unsigned long end) +{ + if (lexra_has_wb_dcache) + lexra_wb_inv_dcache_range(start, end); + else + lexra_inv_dcache_range(start, end); +} + +static void lexra_wback_dcache_range(unsigned long start, unsigned long end) +{ + if (lexra_has_wb_dcache) + lexra_wb_dcache_range(start, end); +} + +static void lexra_flush_dcache_all(void) +{ + if (lexra_has_wb_dcache) + lexra_wb_inv_dcache_all(); + else + lexra_inv_dcache_all(); +} + +static void lexra_flush_icache_range(unsigned long start, unsigned long end) +{ + lexra_wback_dcache_range(start, end); + lexra_inv_icache_all(); +} + + +static inline void lexra_flush_cache_all(void) +{ +} + +static inline void lexra___flush_cache_all(void) +{ + lexra_flush_dcache_all(); + lexra_inv_icache_all(); +} + +static void lexra_flush_cache_mm(struct mm_struct *mm) +{ +} + +static void lexra_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ +} + +static void lexra_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn) +{ + unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT); + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pud_t *pudp; + pmd_t *pmdp; + pte_t *ptep; + + pr_debug("cpage[%08llx,%08lx]\n", + cpu_context(smp_processor_id(), mm), addr); + + /* No ASID => no such page in the cache. */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + pgdp = pgd_offset(mm, addr); + pudp = pud_offset(pgdp, addr); + pmdp = pmd_offset(pudp, addr); + ptep = pte_offset(pmdp, addr); + + /* Invalid => no such page in the cache. */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + lexra_flush_dcache_range(kaddr, kaddr + PAGE_SIZE); + if (exec) + lexra_inv_icache_all(); +} + +static void local_lexra_flush_data_cache_page(void *addr) +{ +} + +static void lexra_flush_data_cache_page(unsigned long addr) +{ +} + +static void lexra_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long flags; + + pr_debug("csigtramp[%08lx]\n", addr); + + flags = read_c0_status(); + + write_c0_status(flags & ~ST0_IEC); + + /* Fill the TLB to avoid an exception with caches isolated. */ + lexra_flush_icache_range(addr, lexra_icache_lsize); + + write_c0_status(flags); +} + +static void lexra_flush_kernel_vmap_range(unsigned long vaddr, int size) +{ + BUG(); +} + +static void lexra_dma_cache_wback_inv(unsigned long start, unsigned long size) +{ + /* Catch bad driver code */ + BUG_ON(size == 0); + + iob(); + lexra_flush_dcache_range(start, start + size); +} + +static void lexra_probe_cache(void) +{ + /* Set default values */ + lexra_dcache_lsize = 16; + lexra_icache_lsize = 16; + lexra_dcache_size = SZ_8K; + lexra_icache_size = SZ_16K; + + lexra_has_dcacheop = 1; + lexra_has_wb_dcache = 1; + + switch (current_cpu_type()) { + case CPU_RLX4181: + break; + case CPU_RLX5281: + lexra_dcache_lsize = 32; + lexra_icache_lsize = 32; + lexra_dcache_size = SZ_32K; + lexra_icache_size = SZ_64K; + break; + default: + BUG(); + } + + cpu_data[0].dcache.linesz = lexra_dcache_lsize; + cpu_data[0].icache.linesz = lexra_icache_lsize; +} + +void lexra_cache_init(void) +{ + extern void build_clear_page(void); + extern void build_copy_page(void); + + lexra_probe_cache(); + + flush_cache_all = lexra_flush_cache_all; + __flush_cache_all = lexra___flush_cache_all; + flush_cache_mm = lexra_flush_cache_mm; + flush_cache_range = lexra_flush_cache_range; + flush_cache_page = lexra_flush_cache_page; + flush_icache_range = lexra_flush_icache_range; + local_flush_icache_range = lexra_flush_icache_range; + + __flush_kernel_vmap_range = lexra_flush_kernel_vmap_range; + + flush_cache_sigtramp = lexra_flush_cache_sigtramp; + local_flush_data_cache_page = local_lexra_flush_data_cache_page; + flush_data_cache_page = lexra_flush_data_cache_page; + + _dma_cache_wback_inv = lexra_dma_cache_wback_inv; + _dma_cache_wback = lexra_dma_cache_wback_inv; + _dma_cache_inv = lexra_dma_cache_wback_inv; + + printk("Primary instruction cache %ldkB, linesize %ld bytes.\n", + lexra_icache_size >> 10, lexra_icache_lsize); + printk("Primary write-%s data cache %ldkB, linesize %ld bytes.\n", + lexra_has_wb_dcache ? "back" : "through", + lexra_dcache_size >> 10, lexra_dcache_lsize); + + lexra_cmem_init(); + + build_clear_page(); + build_copy_page(); +} diff --git a/target/linux/realtek/files-4.14/arch/mips/pci/pci-realtek.c b/target/linux/realtek/files-4.14/arch/mips/pci/pci-realtek.c new file mode 100644 index 0000000000000..eadeae9b221e4 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/pci/pci-realtek.c @@ -0,0 +1,469 @@ +/* + * Realtek RLX based SoC PCI host controller driver + * + * Copyright (C) 2019 Gaspare Bruno + * Copyright (C) 2017 Weijie Gao + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct realtek_pci_controller { + void __iomem *rc_cfg_base; + void __iomem *rc_ext_base; + void __iomem *dev_cfg0_base; + void __iomem *dev_cfg1_base; + + int link_up; + + u32 bus_number; + struct device_node *np; + struct pci_controller pci_controller; + struct resource io_res; + struct resource mem_res; + struct clk *clk; +}; + +static inline struct realtek_pci_controller * +pci_bus_to_realtek_pci_controller(struct pci_bus *bus) +{ + struct pci_controller *hose; + + hose = (struct pci_controller *) bus->sysdata; + return container_of(hose, struct realtek_pci_controller, pci_controller); +} + +static inline void realtek_pcie_mdio_write(struct realtek_pci_controller *rpc, u32 reg, u32 data) +{ + u32 val; + + val = ((reg&0x1f)<<8) | ((data&0xffff)<<16) | BIT(0); + __raw_writel(val, rpc->rc_ext_base); + mdelay(2); +} + +static inline +#if defined(CONFIG_CPU_RLX) +__attribute__ ((section(".iram"))) +#endif +int realtek_pci_raw_read(void __iomem *mem, int where, int size, uint32_t *value){ + u32 data; + int s; + + data = __raw_readl(mem + (where & ~3)); + switch (size) { + case 1: + case 2: + s = ((where & 3) * 8); + data >>= s; + data &= (size==1?0xff:0xffff); + break; + case 4: + break; + default: + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + if (value) + *value = data; + + return PCIBIOS_SUCCESSFUL; +} + +static +#if defined(CONFIG_CPU_RLX) +__attribute__ ((section(".iram"))) +#endif +int realtek_pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t *value) +{ + struct realtek_pci_controller *rpc; + + rpc = pci_bus_to_realtek_pci_controller(bus); + if (!rpc->link_up) + return PCIBIOS_DEVICE_NOT_FOUND; + + if(bus && rpc->bus_number == 0xff) + rpc->bus_number = bus->number; + + if(bus->number == rpc->bus_number) { + /* PCIE host controller */ + if (PCI_SLOT(devfn) == 0) { + if (value) + realtek_pci_raw_read(rpc->rc_cfg_base, where, size, value); + } + else return PCIBIOS_DEVICE_NOT_FOUND; + } + else + if(bus->number == rpc->bus_number+1) { + /* PCIE devices directly connected */ + if (PCI_SLOT(devfn) == 0){ + if(value) + realtek_pci_raw_read(rpc->dev_cfg0_base + (PCI_FUNC(devfn) << 12), where, size, value); + } + else return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + /* Devices connected through bridge (Max 4 devices in SDK)*/ + if (PCI_SLOT(devfn) < 4){ + // (0xc = PCIE0 IPCFG) + __raw_writel(((bus->number) << 8) | (PCI_SLOT(devfn) << 3) | PCI_FUNC(devfn), rpc->rc_ext_base+0x0c); + if(value) + realtek_pci_raw_read(rpc->dev_cfg1_base, where, size, value); + } + } + + return PCIBIOS_SUCCESSFUL; +} + +static inline +#if defined(CONFIG_CPU_RLX) +__attribute__ ((section(".iram"))) +#endif +int realtek_pci_raw_write(void __iomem *mem, int where, int size, uint32_t value){ + u32 data; + int s,v; + + switch (size) { + case 1: + case 2: + data = __raw_readl(mem + (where & ~3)); + s = ((where & 3) * 8); + v = ~(size==1?0xff:0xffff) << s; + data = (data & v) | (value << s); + break; + case 4: + data = value; + break; + default: + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + __raw_writel(data, mem + (where & ~3)); + + return PCIBIOS_SUCCESSFUL; +} + +static +#if defined(CONFIG_CPU_RLX) +__attribute__ ((section(".iram"))) +#endif +int realtek_pci_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, uint32_t value) +{ + struct realtek_pci_controller *rpc; + + rpc = pci_bus_to_realtek_pci_controller(bus); + if (!rpc->link_up) + return PCIBIOS_DEVICE_NOT_FOUND; + + if(bus && rpc->bus_number == 0xff) + rpc->bus_number = bus->number; + + if(bus->number == rpc->bus_number) { + /* PCIE host controller */ + if (PCI_SLOT(devfn) == 0) { + realtek_pci_raw_write(rpc->rc_cfg_base, where, size, value); + } + else return PCIBIOS_DEVICE_NOT_FOUND; + } + else + if(bus->number == rpc->bus_number+1) { + /* PCIE devices directly connected */ + if (PCI_SLOT(devfn) == 0){ + realtek_pci_raw_write(rpc->dev_cfg0_base + (PCI_FUNC(devfn) << 12), where, size, value); + } + else return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + /* Devices connected through bridge (Max 4 devices in SDK)*/ + if (PCI_SLOT(devfn) < 4){ + // (0xc = PCIE0 IPCFG) + __raw_writel(((bus->number) << 8) | (PCI_SLOT(devfn) << 3) | PCI_FUNC(devfn), rpc->rc_ext_base+0x0c); + realtek_pci_raw_write(rpc->dev_cfg1_base, where, size, value); + } + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops realtek_pci_ops = { + .read = realtek_pci_read, + .write = realtek_pci_write, +}; + + +static int realtek_pcie_check_link(struct realtek_pci_controller *rpc) +{ + int i = 20; + u32 val = 0; + + do + { + val = __raw_readl(rpc->rc_cfg_base + 0x728); + if((val & 0x1f) == 0x11) + return 1; + + mdelay(100); + } while (i--); + + return 0; +} + +static inline void realtek_pcie_device_reset(struct realtek_pci_controller *rpc) +{ + u32 val; + + val = sr_r32(REALTEK_SR_CLKMANAGE); + val &= (~BIT(26)); // PERST=0 for PCI port0 + sr_w32(val, REALTEK_SR_CLKMANAGE); + mdelay(100); // SDK wait 1s! too much? + val = sr_r32(REALTEK_SR_CLKMANAGE); + val |= BIT(26); // PERST=1 for PCI port0 + sr_w32(val, REALTEK_SR_CLKMANAGE); + + //TODO: Need reset for second card (97D)! +} + +static inline void realtek_pcie_mdio_reset(struct realtek_pci_controller *rpc) +{ + sr_w32(BIT(3), REALTEK_SR_PCIE_PHY0); // mdio reset 0 + sr_w32(BIT(3)|BIT(0), REALTEK_SR_PCIE_PHY0); // mdio reset 1 + sr_w32(BIT(3)|BIT(1)|BIT(0), REALTEK_SR_PCIE_PHY0); // load done +} + +static inline void realtek_pcie_phy_reset(struct realtek_pci_controller *rpc) +{ + //(0x8 = PCIE0 PWRCR) + __raw_writel(0x01, rpc->rc_ext_base+0x8); //bit7:PHY reset=0 bit0: Enable LTSSM=1 + __raw_writel(0x81, rpc->rc_ext_base+0x8); //bit7:PHY reset=1 bit0: Enable LTSSM=1 +} + +static void realtek_pcie_reset(struct realtek_pci_controller *rpc) +{ + u32 val; + + //first, Turn On PCIE IP + val = sr_r32(REALTEK_SR_CLKMANAGE); + val |= BIT(14); + sr_w32(val, REALTEK_SR_CLKMANAGE); + + val = sr_r32(REALTEK_SR_CLKMANAGE); + val |= BIT(26); + sr_w32(val, REALTEK_SR_CLKMANAGE); + + val = sr_r32(REALTEK_SR_CLKMANAGE); + val |= BIT(12)|BIT(13)|BIT(18)|BIT(19)|BIT(20); + sr_w32(val, REALTEK_SR_CLKMANAGE); + + mdelay(100); + + realtek_pcie_mdio_reset(rpc); + + // wait to stabilize (SDK use 500 here. too much?) + mdelay(100); + + // Configure mdio + realtek_pcie_mdio_write(rpc, 0x00, 0xd087); + realtek_pcie_mdio_write(rpc, 0x01, 0x0003); + realtek_pcie_mdio_write(rpc, 0x02, 0x4d19); //0x4d18); + realtek_pcie_mdio_write(rpc, 0x04, 0x5000); + + if (clk_get_rate(rpc->clk) == 40000000) { + // 40MHz PCI clock + realtek_pcie_mdio_write(rpc, 0x05, 0x0bcb); + realtek_pcie_mdio_write(rpc, 0x06, 0x2148); //0xf148); + realtek_pcie_mdio_write(rpc, 0x07, 0x41ff); // From wireless driver + realtek_pcie_mdio_write(rpc, 0x08, 0x13f6); + } else { + // 25MHz PCI clock + realtek_pcie_mdio_write(rpc, 0x06, 0xf848); + realtek_pcie_mdio_write(rpc, 0x07, 0xa7ff); + realtek_pcie_mdio_write(rpc, 0x08, 0x0c56); + } + + realtek_pcie_mdio_write(rpc, 0x09, 0x539c); + realtek_pcie_mdio_write(rpc, 0x0a, 0x20eb); + realtek_pcie_mdio_write(rpc, 0x0d, 0x1766); + realtek_pcie_mdio_write(rpc, 0x0b, 0x0711); + +#ifdef CONFIG_SOC_RTL8196E + realtek_pcie_mdio_write(rpc, 0x0f, 0x0f0f); +#else + realtek_pcie_mdio_write(rpc, 0x0f, 0x0a00); +#endif + + realtek_pcie_mdio_write(rpc, 0x19, 0xfce0); + realtek_pcie_mdio_write(rpc, 0x1a, 0x7e40); //0x7e4f); + realtek_pcie_mdio_write(rpc, 0x1b, 0xfc01); + realtek_pcie_mdio_write(rpc, 0x1e, 0xc280); + + realtek_pcie_device_reset(rpc); + realtek_pcie_phy_reset(rpc); + mdelay(200); +} + +static void load_ranges(struct pci_controller *hose, struct device_node *node) +{ + struct of_pci_range range; + struct of_pci_range_parser parser; + + hose->of_node = node; + + if (of_pci_range_parser_init(&parser, node)) + return; + + for_each_of_pci_range(&parser, &range) { + switch (range.flags & IORESOURCE_TYPE_BITS) { + case IORESOURCE_IO: + hose->io_map_base = + (unsigned long)ioremap(range.cpu_addr, range.size); + hose->io_resource->flags = range.flags; + hose->io_resource->name = node->full_name; + hose->io_resource->start = range.cpu_addr; + hose->io_resource->end = range.cpu_addr + range.size - 1; + break; + case IORESOURCE_MEM: + hose->mem_resource->flags = range.flags; + hose->mem_resource->name = node->full_name; + hose->mem_resource->start = range.cpu_addr; + hose->mem_resource->end = range.cpu_addr + range.size - 1; + break; + } + } +} + +static int realtek_pci_probe(struct platform_device *pdev) +{ + struct realtek_pci_controller *rpc; + struct resource *res; + int id; + u32 val; + u16 cmd; + u8 v8; + + id = pdev->id; + if (id == -1) + id = 0; + + rpc = devm_kzalloc(&pdev->dev, sizeof(struct realtek_pci_controller), + GFP_KERNEL); + if (!rpc) + return -ENOMEM; + rpc->bus_number=0xff; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_cfg_base"); + rpc->rc_cfg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rpc->rc_cfg_base)) + return PTR_ERR(rpc->rc_cfg_base); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_ext_base"); + rpc->rc_ext_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rpc->rc_ext_base)) + return PTR_ERR(rpc->rc_ext_base); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dev_cfg0_base"); + rpc->dev_cfg0_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rpc->dev_cfg0_base)) + return PTR_ERR(rpc->dev_cfg0_base); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dev_cfg1_base"); + rpc->dev_cfg1_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rpc->dev_cfg1_base)) + return PTR_ERR(rpc->dev_cfg1_base); + + rpc->clk = devm_clk_get(&pdev->dev, NULL); + if(!rpc->clk) + return PTR_ERR(rpc->clk); + + iomem_resource.start = 0; + iomem_resource.end = ~0; + ioport_resource.start = 0; + ioport_resource.end = ~0; + + rpc->np = pdev->dev.of_node; + rpc->pci_controller.pci_ops = &realtek_pci_ops; + rpc->pci_controller.io_resource = &rpc->io_res; + rpc->pci_controller.mem_resource = &rpc->mem_res; + load_ranges(&rpc->pci_controller, pdev->dev.of_node); + + realtek_pcie_reset(rpc); + + rpc->link_up = realtek_pcie_check_link(rpc); + if (!rpc->link_up) + dev_warn(&pdev->dev, "PCIe link is down\n"); + + cmd = __raw_readw(rpc->rc_cfg_base + PCI_COMMAND); + cmd = PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + __raw_writew(cmd, rpc->rc_cfg_base + PCI_COMMAND); + + // Set MAX_PAYLOAD_SIZE to 128B,default + v8 = __raw_readb(rpc->dev_cfg0_base + 0x78); + v8 &= ~(PCI_EXP_DEVCTL_PAYLOAD); + __raw_writeb(v8, rpc->rc_cfg_base + 0x78); + + mdelay(100); + + register_pci_controller(&rpc->pci_controller); + + return 0; +} + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + struct realtek_pci_controller *rpc; + u16 cmd; + int irq = 5; + + rpc = pci_bus_to_realtek_pci_controller(dev->bus); + if(!rpc) + return 0; + + //TODO: Implement second pcie (get irq from dt) + // Bus:1 Slot:0 Pin:1 -> first wireless card + + /* setup the slot */ + cmd = PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_write_config_word(dev, PCI_COMMAND, cmd); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); + + return irq; +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + +static const struct of_device_id realtek_pci_ids[] = { + { .compatible = "realtek,rtl8196b-pci" }, + {}, +}; + +static struct platform_driver realtek_pci_driver = { + .probe = realtek_pci_probe, + .driver = { + .name = "realtek-pci", + .of_match_table = of_match_ptr(realtek_pci_ids), + }, +}; + +static int __init realtek_pci_init(void) +{ + return platform_driver_register(&realtek_pci_driver); +} + +postcore_initcall(realtek_pci_init); diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/Kconfig b/target/linux/realtek/files-4.14/arch/mips/realtek/Kconfig new file mode 100644 index 0000000000000..034b1c835ee49 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/Kconfig @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: GPL-2.0 +if REALTEK + +choice + prompt "Realtek SoC selection" + default SOC_RTL8197D + help + Select Realtek SoC type. + + config SOC_RTL8196E + bool "RTL8196E" + select USE_GENERIC_EARLY_PRINTK_8250 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_HAS_CPU_RLX4181 + select HW_HAS_PCI + select GPIOLIB + select GPIO_GENERIC + select GPIOLIB_IRQCHIP + + config SOC_RTL8197D + bool "RTL8197D" + select USE_GENERIC_EARLY_PRINTK_8250 + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_HAS_CPU_RLX5281 + select HW_HAS_PCI + select GPIOLIB + select GPIO_GENERIC + select GPIOLIB_IRQCHIP + + config SOC_RTL8197F + bool "RTL8197F" + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select HW_HAS_PCI + select GPIOLIB + select GPIO_GENERIC + select GPIOLIB_IRQCHIP + select CEVT_R4K + select CSRC_R4K + +endchoice + +choice + prompt "Devicetree selection" + default DTB_RTK_NONE + help + Select the devicetree. + + config DTB_RTK_NONE + bool "None" + + config DTB_RTL8196E_GEN + bool "RTL8196E generic" + depends on SOC_RTL8196E + select BUILTIN_DTB + + config DTB_RTL8197D_GEN + bool "RTL8197D generic" + depends on SOC_RTL8197D + select BUILTIN_DTB + + config DTB_RTL8197F_GEN + bool "RTL8197F generic" + depends on SOC_RTL8197F + select BUILTIN_DTB + +endchoice + +endif diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/Makefile b/target/linux/realtek/files-4.14/arch/mips/realtek/Makefile new file mode 100644 index 0000000000000..502ddb8e548ee --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/Makefile @@ -0,0 +1,6 @@ + + +obj-y := prom.o setup.o irq.o gpio.o + +obj-$(CONFIG_SOC_RTL8197D) += rtl819x-timer.o +obj-$(CONFIG_SOC_RTL8196E) += rtl819x-timer.o diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/Platform b/target/linux/realtek/files-4.14/arch/mips/realtek/Platform new file mode 100644 index 0000000000000..479f13139ef6b --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/Platform @@ -0,0 +1,13 @@ +# +# Realtek SoCs +# + +platform-$(CONFIG_REALTEK) += realtek/ +cflags-$(CONFIG_SOC_RTL8197D) += -I$(srctree)/arch/mips/include/asm/mach-realtek/rtl8197d +load-$(CONFIG_SOC_RTL8197D) = 0xffffffff80010000 + +cflags-$(CONFIG_SOC_RTL8196E) += -I$(srctree)/arch/mips/include/asm/mach-realtek/rtl8196e +load-$(CONFIG_SOC_RTL8196E) = 0xffffffff80000000 + +cflags-$(CONFIG_SOC_RTL8197F) += -I$(srctree)/arch/mips/include/asm/mach-realtek/rtl8197f +load-$(CONFIG_SOC_RTL8197F) = 0xffffffff80000000 \ No newline at end of file diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/gpio.c b/target/linux/realtek/files-4.14/arch/mips/realtek/gpio.c new file mode 100644 index 0000000000000..e78515f26b790 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/gpio.c @@ -0,0 +1,302 @@ +/* + * Realtek GPIO Driver support + * Based on Atheros AR71XX GPIO API support + * + * Copyright (C) 2019 Gaspare Bruno + * Copyright (C) 2015 Alban Bedel + * Copyright (C) 2010-2011 Jaiganesh Narayanan + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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. + */ + +#include +#include +#include +#include +#include + +struct realtek_gpio_ctrl { + struct gpio_chip gc; + void __iomem *base; + char gpio_pin_int_masks[32]; +}; + +static u32 realtek_gpio_read(struct realtek_gpio_ctrl *ctrl, unsigned reg) +{ + return readl(ctrl->base + reg); +} + +static void realtek_gpio_write(struct realtek_gpio_ctrl *ctrl, unsigned reg, u32 val) +{ + return writel(val, ctrl->base + reg); +} + +static int realtek_gpio_request(struct gpio_chip *chip, unsigned gpio_pin) +{ + unsigned long flags; + unsigned long pinmask; + struct realtek_gpio_ctrl *ctrl = container_of(chip, struct realtek_gpio_ctrl, gc); + + if (gpio_pin >= chip->ngpio) + return -EINVAL; + + spin_lock_irqsave(&chip->bgpio_lock, flags); + pinmask = realtek_gpio_read(ctrl, 0x0); + pinmask &= ~(BIT(gpio_pin)); + realtek_gpio_write(ctrl, 0x0, pinmask); + spin_unlock_irqrestore(&chip->bgpio_lock, flags); + return 0; +} + +static void realtek_gpio_irq_mask(struct irq_data *data) +{ + unsigned int irq = data->irq; + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct realtek_gpio_ctrl *ctrl = container_of(gc, struct realtek_gpio_ctrl, gc); + unsigned int pin = irq_linear_revmap(gc->irqdomain, irq); + unsigned int pinmask = 0; + unsigned int pinreg = 0; + u32 mask; + + if(pin<16){ + pinreg = 0x14; // Interrupt Mask (0-15) + pinmask = pin; + } + else { + pinreg = 0x18; // Interrupt Mask (16-31) + pinmask = pin-16; + } + + mask = realtek_gpio_read(ctrl, pinreg); + + mask |= (ctrl->gpio_pin_int_masks[pin] << pinmask); + + realtek_gpio_write(ctrl, pinreg, mask); +} + +static void realtek_gpio_irq_unmask(struct irq_data *data) +{ + unsigned int irq = data->irq; + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct realtek_gpio_ctrl *ctrl = container_of(gc, struct realtek_gpio_ctrl, gc); + unsigned int pin = irq_linear_revmap(gc->irqdomain, irq); + unsigned int pinmask = 0; + unsigned int pinreg = 0; + u32 mask; + + if(pin<16){ + pinreg = 0x14; // Interrupt Mask (0-15) + pinmask = pin; + } + else { + pinreg = 0x18; // Interrupt Mask (16-31) + pinmask = pin-16; + } + + mask = realtek_gpio_read(ctrl, pinreg); + + ctrl->gpio_pin_int_masks[pin] = (mask >> pinmask) & 0x3; + mask &= ~(0x3 << pinmask); + + realtek_gpio_write(ctrl, pinreg, mask); +} + +static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int type) +{ + unsigned int irq = data->irq; + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct realtek_gpio_ctrl *ctrl = container_of(gc, struct realtek_gpio_ctrl, gc); + unsigned int pin = irq_linear_revmap(gc->irqdomain, irq); + unsigned int pinmask = 0; + unsigned int pinreg = 0; + unsigned int newvalue = 0; + u32 mask; + + if(pin<16){ + pinreg = 0x14; // Interrupt Mask (0-15) + pinmask = pin; + } + else { + pinreg = 0x18; // Interrupt Mask (16-31) + pinmask = pin-16; + } + + mask = realtek_gpio_read(ctrl, pinreg); + + switch(type) { + case IRQ_TYPE_EDGE_RISING: + newvalue = 0x2; + break; + case IRQ_TYPE_EDGE_FALLING: + newvalue = 0x1; + break; + case IRQ_TYPE_EDGE_BOTH: + newvalue = 0x3; + break; + default: + printk(KERN_ERR "No such irq type %d", type); + return -EINVAL; + } + + ctrl->gpio_pin_int_masks[pin] = newvalue; + mask &= ~(0x3 << (pinmask*2)); + mask |= (newvalue << (pinmask*2)); + + realtek_gpio_write(ctrl, pinreg, mask); + + return 0; +} + +static struct irq_chip realtek_gpio_irqchip = { + .name = "gpio-realtek", +// .irq_enable = realtek_gpio_irq_enable, +// .irq_disable = realtek_gpio_irq_disable, + .irq_mask = realtek_gpio_irq_mask, + .irq_unmask = realtek_gpio_irq_unmask, + .irq_set_type = realtek_gpio_irq_set_type, + .flags = IRQCHIP_SET_TYPE_MASKED, +}; + +static void realtek_gpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct irq_chip *irqchip = irq_desc_get_chip(desc); + struct realtek_gpio_ctrl *ctrl = container_of(gc, struct realtek_gpio_ctrl, gc); + u32 status, mask1, mask2, mask3 = 0; + unsigned long pending; + int irq, i; + + chained_irq_enter(irqchip, desc); + + status = realtek_gpio_read(ctrl, 0x10); // Interrupt Status + mask1 = realtek_gpio_read(ctrl, 0x14); // Interrupt Mask (0-15) + mask2 = realtek_gpio_read(ctrl, 0x18); // Interrupt Mask (16-31) + + /* get the mask for interrupt status register by ourself */ + for(i = 0; i < 16; i++) + mask3 |= ((0x3 << (i*2)) & mask1 ? 1 : 0) << i; + for(i = 16; i < 32; i++) + mask3 |= ((0x3 << ((i-16)*2)) & mask2 ? 1 : 0) << i; + + /* mask the pins which don't have interrupt */ + pending = status & mask3; + + if (pending) { + for_each_set_bit(irq, &pending, 32) + generic_handle_irq(irq_linear_revmap(gc->irqdomain, irq)); + } + + chained_irq_exit(irqchip, desc); +} + +static const struct of_device_id realtek_gpio_of_match[] = { + { .compatible = "realtek,realtek-gpio" }, + { .compatible = "realtek,rtl8197f-gpio" }, + {}, +}; +MODULE_DEVICE_TABLE(of, realtek_gpio_of_match); + +static int realtek_gpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct realtek_gpio_ctrl *ctrl; + struct resource *res; + int err, irq=0; + + ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + platform_set_drvdata(pdev, ctrl); + + if (!np) { + dev_err(&pdev->dev, "No DT node or platform data found\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ctrl->base = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); + if (!ctrl->base) + return -ENOMEM; + + err = bgpio_init(&ctrl->gc, &pdev->dev, 4, + ctrl->base + 0x0C, // DAT Register + NULL, + NULL, + ctrl->base + 0x08, // DIRECTION OUT + NULL, // DIRECTION IN + 0); + if (err) { + dev_err(&pdev->dev, "bgpio_init failed\n"); + return err; + } + + ctrl->gc.request = realtek_gpio_request; + if(np && of_property_read_bool(np, "base")) + { + u8 base=0; + of_property_read_u8(np, "base", &base); + ctrl->gc.base = base; + } else { + // use autodetect + ctrl->gc.base = -1; + } + + memset(ctrl->gpio_pin_int_masks, 0, sizeof(ctrl->gpio_pin_int_masks)); + + err = gpiochip_add_data(&ctrl->gc, ctrl); + if (err) { + dev_err(&pdev->dev,"cannot add Realtek GPIO chip, error=%d", err); + return err; + } + + if (np && !of_property_read_bool(np, "interrupt-controller")) + { + printk("%s: Realtek GPIO controller driver\n", ctrl->gc.label); + return 0; + } else { + irq = platform_get_irq(pdev, 0); + printk("%s: Realtek GPIO controller driver at IRQ %d\n", ctrl->gc.label, irq); + } + + err = gpiochip_irqchip_add(&ctrl->gc, &realtek_gpio_irqchip, 0, + handle_edge_irq, IRQ_TYPE_NONE); + if (err) { + dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n"); + goto gpiochip_remove; + } + + gpiochip_set_chained_irqchip(&ctrl->gc, &realtek_gpio_irqchip, + platform_get_irq(pdev, 0), realtek_gpio_irq_handler); + + return 0; + +gpiochip_remove: + gpiochip_remove(&ctrl->gc); + return err; +} + +static int realtek_gpio_remove(struct platform_device *pdev) +{ + struct realtek_gpio_ctrl *ctrl = platform_get_drvdata(pdev); + + gpiochip_remove(&ctrl->gc); + return 0; +} + +static struct platform_driver realtek_gpio_driver = { + .driver = { + .name = "realtek-gpio", + .of_match_table = realtek_gpio_of_match, + }, + .probe = realtek_gpio_probe, + .remove = realtek_gpio_remove, +}; + +module_platform_driver(realtek_gpio_driver); + +MODULE_DESCRIPTION("Realtek GPIO Driver"); +MODULE_LICENSE("GPL v2"); \ No newline at end of file diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/irq.c b/target/linux/realtek/files-4.14/arch/mips/realtek/irq.c new file mode 100644 index 0000000000000..e3315977d8a4d --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/irq.c @@ -0,0 +1,297 @@ +/* + * 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. + * + * Copyright (C) 2019 Gaspare Bruno + * + * Realtek IRQ handler + * This IRQ driver have the 8 common MIPS CPU irqs + * RLX driver have an aditional 8 hardware irqs + * TODO: Implement the RLX additional irqs + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +__iomem void *_intc_membase; +static u32 mips_chip_irqs; + +#define ic_w32(val, reg) __raw_writel(val, _intc_membase + reg) +#define ic_r32(reg) __raw_readl(_intc_membase + reg) + +// Interrupt Registers and bits +#define REALTEK_IC_REG_MASK 0x00 +#define REALTEK_IC_REG_STATUS 0x04 +#define REALTEK_IC_REG2_MASK 0x20 +#define REALTEK_IC_REG2_STATUS 0x24 + +#define REALTEK_IC_REG_IRR0 0x08 +#define REALTEK_IC_REG_IRR1 0x0C +#define REALTEK_IC_REG_IRR2 0x10 +#define REALTEK_IC_REG_IRR3 0x14 +#define REALTEK_IC_REG_IRR4 0x28 +#define REALTEK_IC_REG_IRR5 0x2C +#define REALTEK_IC_REG_IRR6 0x30 +#define REALTEK_IC_REG_IRR7 0x34 + +#define REALTEK_INTC_IRQ_COUNT 32 + +#define REALTEK_IRQ_GENERIC 2 + +#define REALTEK_IRQ_TIMER 7 +#define REALTEK_IRQ_NET 4 +#define REALTEK_IRQ_WIFI 6 +#define REALTEK_IRQ_PCI0 5 +#define REALTEK_IRQ_PCI1 REALTEK_IRQ_WIFI +#define REALTEK_IRQ_UART0 REALTEK_IRQ_GENERIC +#define REALTEK_IRQ_GPIO1 REALTEK_IRQ_GENERIC +#define REALTEK_IRQ_GPIO2 REALTEK_IRQ_GENERIC + +/* Definition for SoCs + RTL8196E and RTL8197D have a RLX chipset + They use 32 SoC IRQs abose the hardware + RTL8197F Have 64 SoC IRQs, but dont have + the additional 8 hardware irqs +*/ + +#ifdef CONFIG_SOC_RTL8197F + +#define REALTEK_INTC_IRQ_BASE 8 + +u32 realtek_soc_irq_init(void) +{ + ic_w32((0), + REALTEK_IC_REG_IRR0); + + ic_w32((REALTEK_IRQ_NET << 28) | + (REALTEK_IRQ_UART0 << 4), + REALTEK_IC_REG_IRR1); + + ic_w32((REALTEK_IRQ_PCI0 << 20) | + (REALTEK_IRQ_GPIO2 << 4) | + (REALTEK_IRQ_GPIO1 << 0), + REALTEK_IC_REG_IRR2); + + ic_w32((REALTEK_IRQ_WIFI << 20), + REALTEK_IC_REG_IRR3); + + ic_w32((0), + REALTEK_IC_REG_IRR4); + + ic_w32((REALTEK_IRQ_TIMER << 28), + REALTEK_IC_REG_IRR5); + + ic_w32((0), + REALTEK_IC_REG_IRR6); + + ic_w32((0), + REALTEK_IC_REG_IRR7); + + // map high priority interrupts to mips irq controler + // BIT 15 on MASK1 is network switch + // BIT 21 on MASK1 is PCIE (wifi5g) + // BIT 29 on MASK1 is wifi 2.4G + // BIT 15 on MASK2 is R4K Timer + ic_w32(BIT(15)|BIT(21)|BIT(29), REALTEK_IC_REG_MASK); + ic_w32(BIT(15), REALTEK_IC_REG2_MASK); + + // Return only MARK1 + return BIT(15)|BIT(21)|BIT(29); +} + +#else + +// Above RLX driver (8 for Mips + 8 for hardware RLX) +#define REALTEK_INTC_IRQ_BASE 16 + +u32 realtek_soc_irq_init(void) +{ + ic_w32((0), + REALTEK_IC_REG_IRR0); + + ic_w32((REALTEK_IRQ_TIMER << 0 | + REALTEK_IRQ_UART0 << 16 | + REALTEK_IRQ_NET << 28 ), + REALTEK_IC_REG_IRR1); + + + ic_w32(( + REALTEK_IRQ_PCI0 << 20 +#ifdef CONFIG_SOC_RTL8197D + | REALTEK_IRQ_PCI1 << 24 +#endif + ), + REALTEK_IC_REG_IRR2); + + ic_w32((0), + REALTEK_IC_REG_IRR3); + + // map high priority interrupts to mips irq controler + // TC0 (Timer) (BIT8) to mips + // Network Switch (BIT15) + // PCIE0 (wifi0) (BIT21) + ic_w32(BIT(8)|BIT(15)|BIT(21) +#ifdef CONFIG_SOC_RTL8197D + |BIT(22) +#endif + , REALTEK_IC_REG_MASK); + + return BIT(8)|BIT(15)|BIT(21) +#ifdef CONFIG_SOC_RTL8197D + |BIT(22) +#endif + ; +} + +#endif + +static void realtek_soc_irq_unmask(struct irq_data *d) +{ + u32 t; + + t = ic_r32(REALTEK_IC_REG_MASK); + ic_w32(t | BIT(d->hwirq), REALTEK_IC_REG_MASK); +} + +static void realtek_soc_irq_mask(struct irq_data *d) +{ + u32 t; + + t = ic_r32(REALTEK_IC_REG_MASK); + ic_w32(t & ~BIT(d->hwirq), REALTEK_IC_REG_MASK); +} + +static struct irq_chip realtek_soc_irq_chip = { + .name = "SOC", + .irq_unmask = realtek_soc_irq_unmask, + .irq_mask = realtek_soc_irq_mask, +}; + +static void realtek_soc_irq_handler(struct irq_desc *desc) +{ + u32 pending; + struct irq_domain *domain; + + pending = ic_r32(REALTEK_IC_REG_MASK) & + ic_r32(REALTEK_IC_REG_STATUS); + + if (pending & mips_chip_irqs) { + /* + * interrupts routed to mips core found here + * clear these bits as they can't be handled here + */ + ic_w32(mips_chip_irqs, REALTEK_IC_REG_STATUS); + pending &= ~mips_chip_irqs; + + if (!pending) + return; + } + + if (!pending) { + spurious_interrupt(); + return; + } + + domain = irq_desc_get_handler_data(desc); + while (pending) { + int bit = __ffs(pending); + generic_handle_irq(irq_find_mapping(domain, bit)); + pending &= ~BIT(bit); + } +} + +static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +{ + irq_set_chip_and_handler(irq, &realtek_soc_irq_chip, handle_level_irq); + + return 0; +} + +static const struct irq_domain_ops irq_domain_ops = { + .xlate = irq_domain_xlate_onecell, + .map = intc_map, +}; + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned long pending; + + pending = read_c0_status() & read_c0_cause() & ST0_IM; + + if (pending & STATUSF_IP7) + do_IRQ(REALTEK_IRQ_TIMER); + + else if (pending & STATUSF_IP4) + do_IRQ(REALTEK_IRQ_NET); + + else if (pending & STATUSF_IP5) + do_IRQ(REALTEK_IRQ_PCI0); + + else if (pending & STATUSF_IP6) + do_IRQ(REALTEK_IRQ_PCI1); + + else if (pending & STATUSF_IP2) + do_IRQ(REALTEK_IRQ_GENERIC); + + else + spurious_interrupt(); +} + +static int __init intc_of_init(struct device_node *node, + struct device_node *parent) +{ + struct resource res; + struct irq_domain *domain; + + if (of_address_to_resource(node, 0, &res)) + panic("Failed to get resource for %s", node->name); + + _intc_membase = ioremap_nocache(res.start, resource_size(&res)); + if(!_intc_membase) + panic("Failed to map memory for %s", node->name); + +#ifdef CONFIG_SOC_RTL8197F + // 8197F uses CEVT and Timers from 4K + // Just need to redirect the right irq... + cp0_compare_irq = REALTEK_IRQ_TIMER; + cp0_perfcount_irq = REALTEK_IRQ_TIMER; + + mips_hpt_frequency = 1000000000 / 2; +#endif + + // Map Interrupts according to SoC + mips_chip_irqs = realtek_soc_irq_init(); + + domain = irq_domain_add_legacy(node, REALTEK_INTC_IRQ_COUNT, + REALTEK_INTC_IRQ_BASE, 0, &irq_domain_ops, NULL); + if (!domain) + panic("Failed to add irqdomain"); + + irq_set_chained_handler_and_data(REALTEK_IRQ_GENERIC, realtek_soc_irq_handler, domain); + + return 0; +} + +static struct of_device_id __initdata of_irq_ids[] = { + { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, + { .compatible = "realtek,rtl819x-intc", .data = intc_of_init }, + {}, +}; + +void __init arch_init_irq(void) +{ + of_irq_init(of_irq_ids); +} + diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/prom.c b/target/linux/realtek/files-4.14/arch/mips/realtek/prom.c new file mode 100644 index 0000000000000..1773f58be64e3 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/prom.c @@ -0,0 +1,55 @@ +#include +#include +#include + +/* RTL8197F Uses a non standard uart from + DesignWare APB (Synopsys) + Basicly, UART0_TX is 0x24, not 0x0 +*/ + +#ifdef CONFIG_SOC_RTL8197F +#define READREG(r) *(volatile unsigned int *)(r) + +#define REALTEK_UART0_BASE 0xB8147000 +#define UART_TX (((READREG(0xB8000000) & 0xFFFFF000) == 0x8197F000) ? 0x024 : 0x0) + +#define BSP_UART0_FCR ((volatile void *)(REALTEK_UART0_BASE + 0x008)) +#define BSP_UART0_LSR ((volatile void *)(REALTEK_UART0_BASE + 0x014)) +#define BSP_UART0_TX ((volatile void *)(REALTEK_UART0_BASE + UART_TX)) + +#define BSP_TXRST 0x04 +#define BSP_LSR_THRE 0x20 + +void prom_putchar(char c) +{ + unsigned int busy_cnt = 0; + do + { + /* Prevent Hanging */ + if (busy_cnt++ >= 30000) + { + /* Reset Tx FIFO */ + writeb(BSP_TXRST | 0xC0, BSP_UART0_FCR); + return; + } + } while ((readb(BSP_UART0_LSR) & BSP_LSR_THRE) == 0); + /* Send Character */ + writeb(c, BSP_UART0_TX); + return; +} + +#else +#define REALTEK_UART0_BASE 0xB8002000 +#endif + +void __init prom_init(void) +{ +#ifndef CONFIG_SOC_RTL8197F + // Standard uart only for 8196E and 8197D + setup_8250_early_printk_port((unsigned long)REALTEK_UART0_BASE, 2, 30000); +#endif +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/rtl819x-timer.c b/target/linux/realtek/files-4.14/arch/mips/realtek/rtl819x-timer.c new file mode 100644 index 0000000000000..d088eedae4307 --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/rtl819x-timer.c @@ -0,0 +1,219 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2019 - Gaspare Bruno + * + * Realtek RTL8196E and RTL8197D have two clocks of 28 bits + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +__iomem void *_timer_membase; +#define tc_w32(val, reg) __raw_writel(val, _timer_membase + reg) +#define tc_r32(reg) __raw_readl(_timer_membase + reg) + +// Timer Registers and bits +#define REALTEK_TC_REG_DATA0 0x00 +#define REALTEK_TC_REG_DATA1 0x04 +#define REALTEK_TC_REG_COUNT0 0x08 +#define REALTEK_TC_REG_COUNT1 0x0c +#define REALTEK_TC_REG_CTRL 0x10 +#define REALTEK_TC_CTRL_TC0_EN BIT(31) // Enable Timer0 +#define REALTEK_TC_CTRL_TC0_MODE BIT(30) // 0 Counter, 1 Timer +#define REALTEK_TC_CTRL_TC1_EN BIT(29) // Enable Timer1 +#define REALTEK_TC_CTRL_TC1_MODE BIT(28) // 0 Counter, 1 Timer +#define REALTEK_TC_REG_IR 0x14 +#define REALTEK_TC_IR_TC0_EN BIT(31) // Enable Timer Interrupts +#define REALTEK_TC_IR_TC1_EN BIT(30) +#define REALTEK_TC_IR_TC0_PENDING BIT(29) +#define REALTEK_TC_IR_TC1_PENDING BIT(28) +#define REALTEK_TC_REG_CLOCK_DIV 0x18 // Clock Divider N TimerClock=(BaseClock/N) + +// Only the 28 higher bits are valid in the timer register counter +#define REALTEK_TIMER_RESOLUTION 28 +#define RTLADJ_TICK(x) (x>>(32-REALTEK_TIMER_RESOLUTION)) + +static u64 rtl819x_tc1_count_read(struct clocksource *cs) +{ + return RTLADJ_TICK(tc_r32(REALTEK_TC_REG_COUNT1)); +} + +static u64 __maybe_unused notrace rtl819x_read_sched_clock(void) +{ + return RTLADJ_TICK(tc_r32(REALTEK_TC_REG_COUNT1)); +} + +static struct clocksource rtl819x_clocksource = { + .name = "RTL819X counter", + .read = rtl819x_tc1_count_read, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +void rtl819x_clocksource_init(unsigned long freq) +{ + u32 val; + + // Use Second clock as monotonic + tc_w32(0xfffffff0, REALTEK_TC_REG_DATA1); + + val = tc_r32(REALTEK_TC_REG_CTRL); + val |= REALTEK_TC_CTRL_TC1_EN | REALTEK_TC_CTRL_TC1_MODE; + tc_w32(val, REALTEK_TC_REG_CTRL); + + val = tc_r32(REALTEK_TC_REG_IR); + val |= REALTEK_TC_IR_TC1_PENDING; + val &= ~REALTEK_TC_IR_TC1_EN; + tc_w32(val, REALTEK_TC_REG_IR); + + rtl819x_clocksource.rating = 200; + rtl819x_clocksource.mask = CLOCKSOURCE_MASK(REALTEK_TIMER_RESOLUTION), + + clocksource_register_hz(&rtl819x_clocksource, freq); + +#ifndef CONFIG_CPU_FREQ + sched_clock_register(rtl819x_read_sched_clock, REALTEK_TIMER_RESOLUTION, freq); +#endif +} + + +static int rtl819x_set_state_shutdown(struct clock_event_device *cd) +{ + u32 val; + + // Disable Timer + val = tc_r32(REALTEK_TC_REG_CTRL); + val &= ~(REALTEK_TC_CTRL_TC0_EN); + tc_w32(val, REALTEK_TC_REG_CTRL); + + // Disable Interrupts + val = tc_r32(REALTEK_TC_REG_IR); + val &= ~REALTEK_TC_IR_TC0_EN; + tc_w32(val, REALTEK_TC_REG_IR); + return 0; +} + +static int rtl819x_set_state_oneshot(struct clock_event_device *cd) +{ + u32 val; + + // Disable Timer and Set as Counter (It will be auto enabled) + val = tc_r32(REALTEK_TC_REG_CTRL); + val &= ~(REALTEK_TC_CTRL_TC0_EN | REALTEK_TC_CTRL_TC0_MODE); + tc_w32(val, REALTEK_TC_REG_CTRL); + + // Enable Interrupts + val = tc_r32(REALTEK_TC_REG_IR); + val |= REALTEK_TC_IR_TC0_EN | REALTEK_TC_IR_TC0_PENDING; + tc_w32(val, REALTEK_TC_REG_IR); + return 0; +} + +static int rtl819x_timer_set_next_event(unsigned long delta, struct clock_event_device *evt) +{ + u32 val; + + // Disable Timer + val = tc_r32(REALTEK_TC_REG_CTRL); + val &= ~REALTEK_TC_CTRL_TC0_EN; + tc_w32(val, REALTEK_TC_REG_CTRL); + + tc_w32(delta<<(32-REALTEK_TIMER_RESOLUTION), REALTEK_TC_REG_DATA0); + + // Reenable Timer + val |= REALTEK_TC_CTRL_TC0_EN; + tc_w32(val, REALTEK_TC_REG_CTRL); + + return 0; +} + +static irqreturn_t rtl819x_timer_interrupt(int irq, void *dev_id) +{ + u32 tc0_irs; + struct clock_event_device *cd = dev_id; + + /* TC0 interrupt acknowledge */ + tc0_irs = tc_r32(REALTEK_TC_REG_IR); + tc0_irs |= REALTEK_TC_IR_TC0_PENDING; + tc_w32(tc0_irs, REALTEK_TC_REG_IR); + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct clock_event_device rtl819x_clockevent = { + .rating = 100, + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = rtl819x_timer_set_next_event, + .set_state_oneshot = rtl819x_set_state_oneshot, + .set_state_shutdown = rtl819x_set_state_shutdown, +}; + +static struct irqaction rtl819x_timer_irqaction = { + .handler = rtl819x_timer_interrupt, + .flags = IRQF_TIMER, + .dev_id = &rtl819x_clockevent, +}; + +static int __init rtl819x_timer_init(struct device_node *np) +{ + struct resource res; + struct clk *clk; + unsigned long timer_rate; + u32 div_fac; + + if (of_address_to_resource(np, 0, &res)) + panic("Failed to get resource for %s", np->name); + + _timer_membase = ioremap_nocache(res.start, resource_size(&res)); + if(!_timer_membase) + panic("Failed to map memory for %s", np->name); + + rtl819x_clockevent.name = np->name; + rtl819x_timer_irqaction.name = np->name; + + rtl819x_clockevent.irq = irq_of_parse_and_map(np, 0); + rtl819x_clockevent.cpumask = cpumask_of(0); + + clk = of_clk_get(np, 0); + if(!clk) + panic("Cant find reference clock for timer!\n"); + + timer_rate = clk_get_rate(clk); + + // Realtek use a default bus rate of 200MHz + div_fac = 200000000/timer_rate; + + // Higher 16 bits are the divider factor + tc_w32(div_fac<<16, REALTEK_TC_REG_CLOCK_DIV); + + rtl819x_clocksource_init(timer_rate); + + clockevents_config_and_register(&rtl819x_clockevent, timer_rate, 0x300, 0x7fffffff); + + setup_irq(rtl819x_clockevent.irq, &rtl819x_timer_irqaction); + + pr_info("%s: running - mult: %d, shift: %d, IRQ: %d, CLK: %lu.%03luMHz\n", + np->name, rtl819x_clockevent.mult, rtl819x_clockevent.shift, + rtl819x_clockevent.irq, timer_rate / 1000000, (timer_rate / 1000) % 1000); + + return 0; +} + +TIMER_OF_DECLARE(rtl819x_timer, "realtek,rtl819x-timer", rtl819x_timer_init); diff --git a/target/linux/realtek/files-4.14/arch/mips/realtek/setup.c b/target/linux/realtek/files-4.14/arch/mips/realtek/setup.c new file mode 100644 index 0000000000000..228f70158edfc --- /dev/null +++ b/target/linux/realtek/files-4.14/arch/mips/realtek/setup.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define REALTEK_WATCHDOG_TIMER_REG 0x311C + +const char *get_system_type(void) +{ +#ifdef CONFIG_SOC_RTL8196E + return "Realtek RTL8196E"; +#endif + +#ifdef CONFIG_SOC_RTL8197D + return "Realtek RTL8197D"; +#endif + +#ifdef CONFIG_SOC_RTL8197F + return "Realtek RTL8197F"; +#endif +} + +static inline void wait_instruction(void) +{ +#ifndef CONFIG_SOC_RTL8197F + __asm__( + " .set push \n" + " sleep \n" + " .set pop \n"); +#endif +} + +void realtek_machine_restart(char *command) +{ + /* Disable all interrupts */ + local_irq_disable(); + + /* Use watchdog to reset the system */ + sr_w32(0x00, REALTEK_WATCHDOG_TIMER_REG); + + for (;;) + wait_instruction(); +} + +void realtek_wait(void) +{ + if (!need_resched()) + wait_instruction(); + local_irq_enable(); +} + +void realtek_halt(void) +{ + while (1) + wait_instruction(); +} + +void __init plat_mem_setup(void) +{ + void *dtb = NULL; + + _machine_restart = realtek_machine_restart; + _machine_halt = realtek_halt; + +#ifndef CONFIG_SOC_RTL8197F + // 8197F uses the r4k wait + cpu_wait = realtek_wait; +#endif + + // Initialize DTB + if (fw_passed_dtb) + dtb = (void *)fw_passed_dtb; + else if (__dtb_start != __dtb_end) + dtb = (void *)__dtb_start; + + __dt_setup_arch(dtb); +} + +__iomem void *_sys_membase; + +void __init device_tree_init(void) +{ + struct device_node *np; + struct resource res; + + unflatten_and_copy_device_tree(); + + np = of_find_compatible_node(NULL, NULL, "realtek,rtl819x-sysc"); + if (!np) + panic("Failed to find realtek,rtl819x-sysc node"); + + if (of_address_to_resource(np, 0, &res)) + panic("Failed to get resource for realtek,rtl819x-sysc"); + + _sys_membase = ioremap_nocache(res.start, resource_size(&res)); + if(!_sys_membase) + panic("Failed to map memory for rtl819x-sysc"); + + pr_info("BOOTSTRAP = %x %x %x %x\n", sr_r32(0x00), sr_r32(0x04), sr_r32(0x08), sr_r32(0x10)); + +#ifdef CONFIG_SOC_RTL8197D + /* Voodoo from SDK */ + if((sr_r32(0x00)&0xf)<3) + { + sr_w32((sr_r32(0x88) & ( ~(3<<5)&~(0xF<<0))), 0x88); + sr_w32((sr_r32(0x88)|(1<<4)), 0x88); + sr_w32(sr_r32(0x88) & (~(3<<7)), 0x88); + } +#endif +} + +void __init plat_time_init(void) +{ + of_clk_init(NULL); + timer_probe(); +} + diff --git a/target/linux/realtek/files-4.14/drivers/spi/spi-realtek.c b/target/linux/realtek/files-4.14/drivers/spi/spi-realtek.c new file mode 100644 index 0000000000000..5a57d4003da44 --- /dev/null +++ b/target/linux/realtek/files-4.14/drivers/spi/spi-realtek.c @@ -0,0 +1,340 @@ +/* + * SPI controller driver for the Realtek SoCs + * + * Copyright (C) 2017 Weijie Gao + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "realtek-spi" + +#define RTK_SPI_CONFIG_OFFSET 0x00 + +#define RTK_SPI_CLK_DIV_SHIFT 29 + +#define RTK_SPI_READ_BYTE_ORDER BIT(28) +#define RTK_SPI_WRITE_BYTE_ORDER BIT(27) + +#define RTK_SPI_CS_DESELECT_TIME_SHIFT 22 + + +#define RTK_SPI_CONTROL_STATUS_OFFSET 0x08 + +#define RTK_SPI_CS_0_HIGH BIT(31) +#define RTK_SPI_CS_1_HIGH BIT(30) +#define RTK_SPI_CS_ALL_HIGH (RTK_SPI_CS_0_HIGH | RTK_SPI_CS_1_HIGH) + +#define RTK_SPI_DATA_LENGTH_SHIFT 28 +#define RTK_SPI_DATA_LENGTH_MASK 0x3 + +#define RTK_SPI_READY BIT(27) + + +#define RTK_SPI_DATA_OFFSET 0x0c + + +#define RTK_SPI_DEFAULT_CLOCK_DIVIDER_INDEX 3 + +struct realtek_spi_data { + struct spi_master *master; + u32 ioc_base; + void __iomem *base; +}; + +static const u32 realtek_spi_clk_div_table[] = {2, 4, 6, 8, 10, 12, 14, 16}; + +#ifdef CONFIG_CPU_BIG_ENDIAN +static inline u32 realtek_spi_make_data(u32 data, u32 bytes) +{ + return data << ((4 - bytes) << 3); +} + +static inline u32 realtek_spi_resolve_data(u32 data, u32 bytes) +{ + return data >> ((4 - bytes) << 3); +} +#else +static inline u32 realtek_spi_make_data(u32 data, u32 bytes) +{ + return data; +} + +static inline u32 realtek_spi_resolve_data(u32 data, u32 bytes) +{ + return data; +} +#endif /* CONFIG_CPU_BIG_ENDIAN */ + +static inline u32 realtek_spi_rr(struct realtek_spi_data *rsd, unsigned reg) +{ + return ioread32(rsd->base + reg); +} + +static inline void realtek_spi_wr(struct realtek_spi_data *rsd, unsigned reg, u32 val) +{ + iowrite32(val, rsd->base + reg); +} + +static void realtek_spi_set_speed_default(struct realtek_spi_data *rsd) +{ + realtek_spi_wr(rsd, RTK_SPI_CONFIG_OFFSET, + (7 << RTK_SPI_CLK_DIV_SHIFT) | + (31 << RTK_SPI_CS_DESELECT_TIME_SHIFT) +#ifdef CONFIG_CPU_BIG_ENDIAN + | RTK_SPI_READ_BYTE_ORDER | RTK_SPI_WRITE_BYTE_ORDER +#endif +); +} + +static void realtek_spi_poll(struct realtek_spi_data *rsd) +{ + while ((realtek_spi_rr(rsd, RTK_SPI_CONTROL_STATUS_OFFSET) & RTK_SPI_READY) == 0); +} + +static void realtek_spi_set_cs(struct spi_device *spi, bool cs_high) +{ + struct realtek_spi_data *rsd = spi_master_get_devdata(spi->master); + + cs_high = (spi->mode & SPI_CS_HIGH) ? !cs_high : cs_high; + + if (cs_high) { + switch (spi->chip_select) { + case 0: + rsd->ioc_base = RTK_SPI_CS_0_HIGH; + break; + case 1: + rsd->ioc_base = RTK_SPI_CS_1_HIGH; + break; + default: + rsd->ioc_base = 0; + } + } else { + switch (spi->chip_select) { + case 0: + rsd->ioc_base = RTK_SPI_CS_1_HIGH; + break; + case 1: + rsd->ioc_base = RTK_SPI_CS_0_HIGH; + break; + default: + rsd->ioc_base = RTK_SPI_CS_ALL_HIGH; + } + } + + rsd->ioc_base |= RTK_SPI_READY; + + realtek_spi_wr(rsd, RTK_SPI_CONTROL_STATUS_OFFSET, rsd->ioc_base); +} + +static void realtek_spi_set_txrx_size(struct realtek_spi_data *rsd, u32 size) +{ + realtek_spi_wr(rsd, RTK_SPI_CONTROL_STATUS_OFFSET, + rsd->ioc_base | ((size - 1) << RTK_SPI_DATA_LENGTH_SHIFT)); +} + +static void realtek_spi_read(struct realtek_spi_data *rsd, u8 *buf, unsigned len) +{ + if ((size_t) buf % 4) + { + realtek_spi_set_txrx_size(rsd, 1); + + while (((size_t) buf % 4) && len) + { + realtek_spi_poll(rsd); + *buf = realtek_spi_resolve_data(realtek_spi_rr(rsd, RTK_SPI_DATA_OFFSET), 1); + buf++; + len--; + } + } + + realtek_spi_set_txrx_size(rsd, 4); + + while (len >= 4) + { + realtek_spi_poll(rsd); + *(u32 *) buf = realtek_spi_resolve_data(realtek_spi_rr(rsd, RTK_SPI_DATA_OFFSET), 4); + buf += 4; + len -= 4; + } + + realtek_spi_set_txrx_size(rsd, 1); + + while (len) + { + realtek_spi_poll(rsd); + *buf = realtek_spi_resolve_data(realtek_spi_rr(rsd, RTK_SPI_DATA_OFFSET), 1); + buf++; + len--; + } +} + +static void realtek_spi_write(struct realtek_spi_data *rsd, const u8 *buf, unsigned len) +{ + if ((size_t) buf % 4) + { + realtek_spi_set_txrx_size(rsd, 1); + + while (((size_t) buf % 4) && len) + { + realtek_spi_wr(rsd, RTK_SPI_DATA_OFFSET, realtek_spi_make_data(*buf, 1)); + realtek_spi_poll(rsd); + buf++; + len--; + } + } + + realtek_spi_set_txrx_size(rsd, 4); + + while (len >= 4) + { + realtek_spi_wr(rsd, RTK_SPI_DATA_OFFSET, realtek_spi_make_data(*(const u32 *) buf, 4)); + realtek_spi_poll(rsd); + buf += 4; + len -= 4; + } + + realtek_spi_set_txrx_size(rsd, 1); + + while (len) + { + realtek_spi_wr(rsd, RTK_SPI_DATA_OFFSET, realtek_spi_make_data(*buf, 1)); + realtek_spi_poll(rsd); + buf++; + len--; + } +} + +static int realtek_spi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct realtek_spi_data *rsd = spi_master_get_devdata(spi->master); + + realtek_spi_set_speed_default(rsd); + + if (xfer->tx_buf && xfer->rx_buf) { + dev_err(&spi->dev, "Read and write operation cannot be performed simultaneously\n"); + return -EPERM; + } + + if (xfer->tx_buf) + realtek_spi_write(rsd, (const u8 *) xfer->tx_buf, xfer->len); + + if (xfer->rx_buf) + realtek_spi_read(rsd, (u8 *) xfer->rx_buf, xfer->len); + + return 0; +} + +static int realtek_spi_probe(struct platform_device *pdev) +{ + struct realtek_spi_data *rsd; + struct spi_master *master; + struct resource *res; + int ret; + + master = spi_alloc_master(&pdev->dev, sizeof(*rsd)); + if (!master) + return -ENOMEM; + + rsd = spi_master_get_devdata(master); + platform_set_drvdata(pdev, rsd); + + rsd->master = master; + + master->dev.of_node = pdev->dev.of_node; + master->bus_num = 0; + master->num_chipselect = 2; + master->mode_bits = SPI_CPOL | SPI_CPHA; + master->flags = SPI_MASTER_HALF_DUPLEX; + master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) | + SPI_BPW_MASK(16) | SPI_BPW_MASK(8); + + master->transfer_one = realtek_spi_transfer_one; + master->set_cs = realtek_spi_set_cs; + + master->min_speed_hz = 190000000/16; //realtek_spi_calc_speed(rsd, RTK_SPI_CLK_DIV_MAX_INDEX); + master->max_speed_hz = 190000000/2; //realtek_spi_calc_speed(rsd, 0); + + dev_set_drvdata(&pdev->dev, master); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rsd->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rsd->base)) { + ret = PTR_ERR(rsd->base); + goto err_out; + } + + /* Set default operation clock */ + realtek_spi_set_speed_default(rsd); + + /* Deassert all chip selects */ + realtek_spi_wr(rsd, RTK_SPI_CONTROL_STATUS_OFFSET, RTK_SPI_CS_ALL_HIGH | RTK_SPI_READY); + + ret = devm_spi_register_master(&pdev->dev, master); + if (ret) + goto err_out; + + return 0; + +err_out: + spi_master_put(master); + + return ret; +} + +static int realtek_spi_remove(struct platform_device *pdev) +{ + struct realtek_spi_data *rsd = platform_get_drvdata(pdev); + + /* Reset to default operation clock */ + realtek_spi_set_speed_default(rsd); + + /* Deassert all chip selects */ + realtek_spi_wr(rsd, RTK_SPI_CONTROL_STATUS_OFFSET, RTK_SPI_CS_ALL_HIGH | RTK_SPI_READY); + + spi_master_put(rsd->master); + + return 0; +} + +static void realtek_spi_shutdown(struct platform_device *pdev) +{ + realtek_spi_remove(pdev); +} + +static const struct of_device_id realtek_spi_match[] = { + { .compatible = "realtek,rtl819x-spi" }, + {}, +}; +MODULE_DEVICE_TABLE(of, realtek_spi_match); + +static struct platform_driver realtek_spi_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = realtek_spi_match, + }, + .probe = realtek_spi_probe, + .remove = realtek_spi_remove, + .shutdown = realtek_spi_shutdown, +}; +module_platform_driver(realtek_spi_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Weijie Gao "); +MODULE_DESCRIPTION("Realtek SoC SPI controller driver"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.c b/target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.c new file mode 100644 index 0000000000000..4848ddf19f159 --- /dev/null +++ b/target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.c @@ -0,0 +1,1467 @@ +/* + * SHEIPA SPI controller driver + * + * Author: Realtek PSP Group + * + * Copyright 2015, Realtek Semiconductor Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* SPIC FLASH Headder */ +#include "spi-sheipa.h" + +#define DRIVER_NAME "spi-sheipa" +#define CMD_ADDR_FORMAT(cmd, addr) (((cmd) & 0x000000ff) | \ + ((addr & 0x000000ff) << 24) | \ + ((addr & 0x0000ff00) << 8) | \ + ((addr & 0x00ff0000) >> 8)) + +#define CMD_FORMAT(cmd) (cmd & 0x000000ff) +#define ADDR_4BYTE_FORMAT(addr) (((addr & 0x000000ff) << 24) | \ + ((addr & 0x0000ff00) << 8) | \ + ((addr & 0x00ff0000) >> 8) | \ + (addr & 0xff000000) >> 24) +/* The mode value 0 is user mode and 1 is auto mode */ +static uint32_t mode; +/* Enter 4-byte address mode */ +static uint32_t enable_addr_4byte_mode; +static uint32_t addr_offset; +static uint32_t first_dummy_xfer; +static uint32_t first_flash_mode_xfer; +static uint32_t first_type_xfer; +static uint8_t first_cmd_xfer; + +struct spi_flash_param ps_para = CC_DEFINE_SPI_FLASH_PARAMS(ps_); + +/* SPIC Driver */ +static uint32_t spi_flash_setser(struct sheipa_spi *dev, uint32_t ser_num) +{ + struct spi_flash_portmap *spi_flash_map; + struct spi_flash_param *spi_flash_para; + + spi_flash_map = dev->regs; + spi_flash_para = dev->comp_param; + + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + if (ser_num >= (1 << (spi_flash_para->spi_flash_num_slaves))) + return DW_EINVAL; + + spi_flash_map->ser = 1 << ser_num; + return 0; + +} + +/* + * This function is used to set the control register. + */ +static void spi_flash_set_tx_mode(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + spi_flash_map->ctrlr0 = spi_flash_map->ctrlr0 & 0xfffffcff; +} + +/* + * This function is used to set the control register. + */ +static void spi_flash_set_rx_mode(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 | 0x0300); +} + +/* + * This function is used to set the ctrlr1 controller. + */ +static uint32_t spi_flash_setctrlr1(struct sheipa_spi *dev, uint32_t num_frame) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + spi_flash_map->ssienr = 0; + if (num_frame > 0x00010000) + return DW_ENODATA; + + spi_flash_map->ctrlr1 = num_frame; + return 0; +} + +/* + * This function is used to set the ctrlr1 controller. + */ +static uint32_t spi_flash_setdr(struct sheipa_spi *dev, + uint32_t dr_num, + uint32_t data, enum spi_flash_byte_num byte_num) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t wr_data; + + spi_flash_map = dev->regs; + + if (byte_num == DATA_BYTE) + wr_data = (data & 0x000000ff); + else if (byte_num == DATA_HALF) + wr_data = cpu_to_le16(data); + else if (byte_num == DATA_WORD) + wr_data = cpu_to_le32(data); + + if (dr_num > 31) + return DW_EINVAL; + else if (byte_num == DATA_BYTE) + spi_flash_map->dr[dr_num].byte = wr_data; + else if (byte_num == DATA_HALF) + spi_flash_map->dr[dr_num].half = wr_data; + else if (byte_num == DATA_WORD) + spi_flash_map->dr[dr_num].word = wr_data; + else + return DW_EINVAL; + + return 0; +} + +/* + * This function is used to set the baud rate register. + */ +static uint32_t spi_flash_setbaudr(struct sheipa_spi *dev, uint32_t baudrate) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + if ((baudrate & 0xffff0000) || (baudrate == 0)) + return DW_ENODATA; + + spi_flash_map->baudr = baudrate; + return 0; +} + +/* + * This function is used to set the fast baud rate register for fast read cmd. + */ +static uint32_t spi_flash_setfbaudr(struct sheipa_spi *dev, uint32_t fbaudrate) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + if ((fbaudrate & 0xffff0000) || (fbaudrate == 0)) + return DW_ENODATA; + + spi_flash_map->fbaudr = fbaudrate; + return 0; +} + +/* + * This function is used to set the Baudr controller. + */ +static uint32_t spi_flash_set_dummy_cycle(struct sheipa_spi *dev, + uint32_t dum_cycle) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t cycle; + + cycle = 0; + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* if using fast_read baud_rate */ + if (((spi_flash_map->ctrlr0) & 0x00100000)) + cycle = (spi_flash_map->fbaudr); + else + cycle = (spi_flash_map->baudr); + + cycle = (cycle * dum_cycle * 2) + DEF_RD_TUNING_DUMMY_CYCLE; + if (cycle > 0x10000) + return DW_ECHRNG; + + DW_BITS_SET_VAL(spi_flash_map->auto_length, bfoSPI_FLASH_AUTO_LEN_DUM, + cycle, bfwSPI_FLASH_AUTO_LEN_DUM); + + return 0; +} + +/* + * This function is used to read the ctrlr1 controller. + */ +static uint32_t spi_flash_getdr(struct sheipa_spi *dev, + uint32_t dr_num, + enum spi_flash_byte_num byte_num) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t rd_data; + uint32_t data; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + + if (dr_num > 31) + return DW_ECHRNG; + else if (byte_num == DATA_BYTE) + data = spi_flash_map->dr[dr_num].byte & 0x000000ff; + else if (byte_num == DATA_HALF) { + rd_data = spi_flash_map->dr[dr_num].half & 0x0000ffff; + data = le16_to_cpu(rd_data); + } else if (byte_num == DATA_WORD) { + rd_data = spi_flash_map->dr[dr_num].word; + data = le32_to_cpu(rd_data); + } else + return DW_EIO; + + return data; +} + +/* + * This function is used to wait the spi_flash is not at busy state. + */ +void spi_flash_wait_busy(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + + while (1) { + if (DW_BIT_GET_UNSHIFTED + (spi_flash_map->sr, bfoSPI_FLASH_SR_TXE)) { + pr_info("spi_flash: transfer error.\n"); + break; + } + + if ((!DW_BIT_GET_UNSHIFTED + (spi_flash_map->sr, bfoSPI_FLASH_SR_BUSY))) + break; + } +} + +/* + * The function is used to set + * cmd(1 byte) + address (3 byte) or + * cmd(1 byte) + address (4 byte) according to + * enable 4 byte address mode(EN4B) + */ +static void spi_flash_set_cmd_addr(struct sheipa_spi *dev, uint32_t wr_addr, + uint8_t wr_cmd) +{ + uint32_t wr_cmd_addr; + + /* set flash cmd and addr */ + if (!enable_addr_4byte_mode) { + wr_cmd_addr = CMD_ADDR_FORMAT(wr_cmd, wr_addr); + /* Write cmd, addr, data into FIFO */ + spi_flash_setdr(dev, 0, wr_cmd_addr, DATA_WORD); + } else { + wr_cmd = CMD_FORMAT(wr_cmd); + wr_addr = ADDR_4BYTE_FORMAT(wr_addr); + spi_flash_setdr(dev, 0, wr_cmd, DATA_BYTE); + spi_flash_setdr(dev, 1, wr_addr, DATA_WORD); + } +} + +/* + * This function is used to set tx command such as WREN, CE command. + */ +static void flash_tx_cmd(struct sheipa_spi *dev, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + + /* Disble SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* set ctrlr0: TX mode */ + spi_flash_set_tx_mode(dev); + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 & 0xfff0ffff); + /* set flash_cmd: wren to fifo */ + spi_flash_setdr(dev, 0, cmd, DATA_BYTE); + /* Enable SPI_FLASH */ + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); + flash_wait_busy(dev); +} + +/* + * This function is used to set tx command such as RDID, RDSR command. + */ +static void flash_rx_cmd(struct sheipa_spi *dev, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + + /* Disble SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* set ctrlr0: RX_mode */ + spi_flash_set_rx_mode(dev); + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 & 0xfff0ffff); + /* set flash_cmd: write cmd to fifo */ + spi_flash_setdr(dev, 0, cmd, DATA_BYTE); +} + +/* + * This function is used to set flash status register. + */ +static void flash_set_status(struct sheipa_spi *dev, uint32_t addr, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t info; + uint32_t data; + + spi_flash_map = dev->regs; + info = spi_flash_map->addr_length; + /* Set flash_cmd: WREN to FIFO */ + if (!enable_addr_4byte_mode) + data = (uint32_t) (addr >> 16); + else + /* for 4-byte address mode */ + data = (uint32_t) (addr >> 24); + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* set ctrlr0: TX mode */ + spi_flash_set_tx_mode(dev); + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 & 0xfff0ffff); + spi_flash_map->addr_length = 1; + /* Set flash_cmd: WRSR to FIFO */ + spi_flash_setdr(dev, 0, cmd, DATA_BYTE); + /* Set data FIFO */ + spi_flash_setdr(dev, 0, data, DATA_BYTE); + + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); + + spi_flash_map->ssienr = 0; + spi_flash_map->addr_length = info; + + flash_wait_busy(dev); +} + +/* + * This function is used to get flash status for flash_wait_busy. + */ +static uint8_t flash_get_status(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* Set Ctrlr1; 1 byte data frames */ + spi_flash_map->ctrlr1 = 1; + + /* Set tuning dummy cycles */ + DW_BITS_SET_VAL(spi_flash_map->auto_length, bfoSPI_FLASH_AUTO_LEN_DUM, + DEF_RD_TUNING_DUMMY_CYCLE, bfwSPI_FLASH_AUTO_LEN_DUM); + + /* Set flash_cmd: RDSR to FIFO */ + flash_rx_cmd(dev, RDSR); + + /* Enable SPI_FLASH */ + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); + + return spi_flash_getdr(dev, 0, DATA_BYTE); +} + +/* + * this function is used to read status for mtd. + */ +static void flash_read_status(struct sheipa_spi *dev, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* Set tuning dummy cycles */ + DW_BITS_SET_VAL(spi_flash_map->auto_length, bfoSPI_FLASH_AUTO_LEN_DUM, + DEF_RD_TUNING_DUMMY_CYCLE, bfwSPI_FLASH_AUTO_LEN_DUM); + + /* Set flash_cmd: RDSR to FIFO */ + flash_rx_cmd(dev, cmd); +} + +static void flash_wait_busy(struct sheipa_spi *dev) +{ + /* Check flash is in write progress or not */ + while ((flash_get_status(dev) & 0x1)) + ; +} + +/* + * this function is used to chip erase. + */ +static void flash_chip_erase(struct sheipa_spi *dev, uint8_t cmd) +{ + flash_tx_cmd(dev, cmd); +} + +/* + * this function is used to sector erase 4kBi. + */ +static void flash_be_4k_erase(struct sheipa_spi *dev, uint32_t addr, + uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* set ctrlr0: TX_mode */ + DW_BITS_SET_VAL(spi_flash_map->ctrlr0, bfoSPI_FLASH_CTRLR0_TMOD, + 0, bfwSPI_FLASH_CTRLR0_TMOD); + + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); + flash_wait_busy(dev); +} + +static void flash_se_erase(struct sheipa_spi *dev, uint32_t addr, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* set ctrlr0: TX_mode */ + DW_BITS_SET_VAL(spi_flash_map->ctrlr0, bfoSPI_FLASH_CTRLR0_TMOD, + 0, bfwSPI_FLASH_CTRLR0_TMOD); + + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); + flash_wait_busy(dev); +} + +static void flash_write_disable(struct sheipa_spi *dev) +{ + flash_tx_cmd(dev, WRDI); +} + +static void flash_write_enable(struct sheipa_spi *dev) +{ + flash_tx_cmd(dev, WREN); +} + +static void flash_read_id(struct sheipa_spi *dev, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* Set Ctrlr1; 3 byte data frames */ + spi_flash_setctrlr1(dev, 3); + spi_flash_set_dummy_cycle(dev, 0); + flash_rx_cmd(dev, cmd); +} + +/* + * this function is used to send single write command. + */ +static void flash_write(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* set ctrlr0: TX mode, data_ch, addr_ch */ + spi_flash_set_tx_mode(dev); + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 & 0xfff0ffff); + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); +} + +/* + * this function is used to send data to SPIC FIFO. + */ +static void flash_write_data(struct sheipa_spi *dev, uint32_t data, + enum spi_flash_byte_num byte_num) +{ + if (byte_num == DATA_BYTE) + spi_flash_setdr(dev, 0, data, DATA_BYTE); + else if (byte_num == DATA_HALF) + spi_flash_setdr(dev, 0, data, DATA_HALF); + else if (byte_num == DATA_WORD) + spi_flash_setdr(dev, 0, data, DATA_WORD); +} + +/* + * this function is used to send single read command. + */ +static void flash_read(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* set ctrlr0: RX mode, data_ch, addr_ch */ + spi_flash_set_rx_mode(dev); + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 & 0xfff0ffff); + + /* Set tuning dummy cycles */ + DW_BITS_SET_VAL(spi_flash_map->auto_length, bfoSPI_FLASH_AUTO_LEN_DUM, + DEF_RD_TUNING_DUMMY_CYCLE, bfwSPI_FLASH_AUTO_LEN_DUM); + + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); +} + +/* + * this function is used to send fast read command. + */ +static void flash_fastread(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, + uint32_t dummy, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + spi_flash_set_dummy_cycle(dev, dummy); + /* set ctrlr0: RX mode, data_ch, addr_ch */ + spi_flash_set_rx_mode(dev); + spi_flash_map->ctrlr0 = (spi_flash_map->ctrlr0 & 0xfff0ffff); + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); +} + +/* + * this function is used to send 2-channel write command. + */ +static uint32_t flash_writex2(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, + uint32_t type, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t init_data; + + spi_flash_map = dev->regs; + /* Not support writex2 */ + if (type == WR_MULTI_NONE) { + pr_info("Not support Writex2 command.\n"); + return DW_EPERM; + } + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* set ctrlr0: TX mode */ + init_data = spi_flash_map->ctrlr0; + + if (type == WR_DUAL_II) + spi_flash_map->ctrlr0 = (init_data & 0xfff0fcff) | (0x00050000); + else if (type == WR_DUAL_I) + spi_flash_map->ctrlr0 = (init_data & 0xfff0fcff) | (0x00040000); + else { + pr_info("Not support Writex2 command.\n"); + return DW_EPERM; + } + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); + + return 0; +} + +/* + * this function is used to send 2-channel read command. + */ +static uint32_t flash_readx2(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, + uint32_t dummy, uint32_t type, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t ctrlr0; + + spi_flash_map = dev->regs; + spi_flash_set_dummy_cycle(dev, dummy); + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* set ctrlr0: RX_mode */ + ctrlr0 = spi_flash_map->ctrlr0; + + if (type == RD_DUAL_IO) + spi_flash_map->ctrlr0 = (ctrlr0 & 0xfff0fcff) | (0x00050300); + else if (type == RD_DUAL_O) + spi_flash_map->ctrlr0 = (ctrlr0 & 0xfff0fcff) | (0x00040300); + else { + pr_info("Not support readx2 command.\n"); + return DW_EPERM; + } + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); + + return 0; +} + +/* + * this function is used to send 4-channel write command. + */ +static uint32_t flash_writex4(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, + uint32_t type, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t init_data; + + spi_flash_map = dev->regs; + /* Not support writex4 */ + if (type == WR_MULTI_NONE) { + pr_info("INFO:Not support Writex4 command.\n"); + return DW_EPERM; + } + + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* set ctrlr0: TX mode, data_ch, addr_ch */ + init_data = spi_flash_map->ctrlr0; + + if (type == WR_QUAD_II) + spi_flash_map->ctrlr0 = (init_data & 0xfff0fcff) | (0x000a0000); + else if (type == WR_QUAD_I) + spi_flash_map->ctrlr0 = (init_data & 0xfff0fcff) | (0x00080000); + else { + pr_info("INFO:Not support Writex4 command.\n"); + return DW_EPERM; + } + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); + + return 0; +} + +/* + * this function is used to send 4-channel read command. + */ +static uint32_t flash_readx4(struct sheipa_spi *dev, uint32_t addr, + enum spi_flash_byte_num byte_num, + uint32_t dummy, uint32_t type, uint8_t cmd) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t ctrlr0; + + spi_flash_map = dev->regs; + spi_flash_set_dummy_cycle(dev, dummy); + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + + /* set ctrlr0: RX_mode */ + ctrlr0 = spi_flash_map->ctrlr0; + + if (type == RD_QUAD_IO) + spi_flash_map->ctrlr0 = (ctrlr0 & 0xfff0fcff) | (0x000a0300); + else if (type == RD_QUAD_O) + spi_flash_map->ctrlr0 = (ctrlr0 & 0xfff0fcff) | (0x00080300); + else { + pr_info("INFO:Not support readx4 command\n"); + return DW_EPERM; + } + /* set flash cmd + addr and write to fifo */ + spi_flash_set_cmd_addr(dev, addr, cmd); + + return 0; +} + +/* + * this function is used to spic and flash initialization. + */ +static void flash_init(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + /* Set baud_rate */ + spi_flash_setbaudr(dev, 8); + /* Set fast baudr rate */ + spi_flash_setfbaudr(dev, 8); + /* Set slave(FLASH) num */ + spi_flash_setser(dev, 0); + /* init addr length 3 byte */ + spi_flash_map->addr_length = 3; + /* using to init write signal */ + flash_write_disable(dev); +} + +/* auto mode initial setting */ +static void auto_init(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + uint32_t info; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + info = 0; + /* Disable SPI_FLASH */ + spi_flash_map->ssienr = 0; + /* Set valid_cmd_reg: auto_cmd */ + if (DEF_WR_QUAD_TYPE == WR_QUAD_II) { + info = 0x100; + spi_flash_map->wr_quad_ii = PPX4_II; + } else if (DEF_WR_QUAD_TYPE == WR_QUAD_I) { + info = 0x080; + spi_flash_map->wr_quad_i = PPX4_I; + } else if (DEF_WR_DUAL_TYPE == WR_DUAL_II) { + info = 0x040; + spi_flash_map->wr_dual_ii = PPX2_II; + } else if (DEF_WR_DUAL_TYPE == WR_DUAL_I) { + info = 0x020; + spi_flash_map->wr_dual_i = PPX2_I; + } + + if (DEF_RD_QUAD_TYPE == RD_QUAD_IO) { + info = info | 0x010; + spi_flash_map->rd_quad_io = READX4_IO; + } else if (DEF_RD_QUAD_TYPE == RD_QUAD_O) { + info = info | 0x008; + spi_flash_map->rd_quad_o = READX4_I; + } else if (DEF_RD_DUAL_TYPE == RD_DUAL_IO) { + info = info | 0x004; + spi_flash_map->rd_dual_io = READX2_IO; + } else if (DEF_RD_DUAL_TYPE == RD_DUAL_O) { + info = info | 0x002; + spi_flash_map->rd_dual_o = READX2_I; + } + spi_flash_map->valid_cmd = (spi_flash_map->valid_cmd | info | 0x200); +} + +static void auto_write(struct sheipa_spi *dev, const u8 *buf, uint32_t len, + uint32_t offset) +{ + uint32_t *addr; + uint32_t i; + uint32_t data; + uint32_t cnt; + + i = 0; + addr = (uint32_t *) (dev->auto_regs + offset); + cnt = len / 4; + + for (i = 0; i < cnt; i++) { + memcpy(&data, buf, 4); + buf += 4; + *addr = data; + flash_wait_busy(dev); + addr++; + } + cnt = len % 4; + if (cnt > 0) { + memcpy(&data, buf, cnt); + buf += cnt; + *addr = data; + flash_wait_busy(dev); + addr++; + } +} + +static void auto_read(struct sheipa_spi *dev, u8 *buf, uint32_t len, + uint32_t offset) +{ + + uint32_t *addr; + uint32_t data; + uint32_t i; + uint32_t cnt; + + i = 0; + addr = (uint32_t *) (dev->auto_regs + offset); + /* set read dummy cycle */ + if (DEF_RD_QUAD_TYPE != RD_MULTI_NONE) + spi_flash_set_dummy_cycle(dev, DEF_RD_QUAD_DUMMY_CYCLE); + else if (DEF_RD_DUAL_TYPE != RD_MULTI_NONE) + spi_flash_set_dummy_cycle(dev, DEF_RD_DUAL_DUMMY_CYCLE); + else + spi_flash_set_dummy_cycle(dev, DEF_RD_TUNING_DUMMY_CYCLE); + + cnt = len / 4; + for (i = 0; i < cnt; i++) { + data = *addr; + memcpy(buf, &data, 4); + addr++; + buf += 4; + } + + cnt = len % 4; + if (cnt > 0) { + data = *addr; + memcpy(buf, &data, 4); + addr++; + buf += cnt; + } +} + +/* Setting auto mode auto_length reg */ +static void set_auto_length(struct sheipa_spi *dev) +{ + + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + spi_flash_map->ssienr = 0; + if (!enable_addr_4byte_mode) { + /* setting auto mode CS_H_WR_LEN, address length(3 byte) */ + spi_flash_map->auto_length = + ((spi_flash_map->auto_length & 0xfffcffff) + | 0x00030000); + } else { + /* setting auto mode CS_H_WR_LEN, address length(4 byte) */ + spi_flash_map->auto_length = + (spi_flash_map->auto_length & 0x0ffcffff) + | 0x50000000; + } +} + +static void set_auto_addr_length(struct sheipa_spi *dev) +{ + + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + spi_flash_map->ssienr = 0; + if (!enable_addr_4byte_mode) { + /* setting AUTO_ADDR_LENGTH (3 byte) */ + spi_flash_map->auto_length = + ((spi_flash_map->auto_length & 0xfffcffff) + | 0x00030000); + } else { + /* setting AUTO_ADDR_LENGTH (4 byte) */ + spi_flash_map->auto_length = + (spi_flash_map->auto_length & 0xfffcffff); + } +} + +/* Setting addr length 4 byte reg for user mode */ +static void set_addr_length(struct sheipa_spi *dev) +{ + + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = (struct spi_flash_portmap *)dev->regs; + spi_flash_map->ssienr = 0; + /* address length(4 byte) */ + spi_flash_map->addr_length = ((spi_flash_map->addr_length & 0xfffffff0) + | 0x00000000); +} + +/* Enable 4 byte address mode */ +static void flash_en4b(struct sheipa_spi *dev, uint8_t cmd) +{ + flash_tx_cmd(dev, cmd); +} + +/* Exit 4 byte address mode */ +static void flash_ex4b(struct sheipa_spi *dev, uint8_t cmd) +{ + flash_tx_cmd(dev, cmd); +} + +/* Enable chip select */ +static void enable_cs_write(struct sheipa_spi *dev) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* Enable SPI_FLASH */ + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); + flash_wait_busy(dev); +} + +static void enable_cs_read(struct sheipa_spi *dev, uint32_t len) +{ + struct spi_flash_portmap *spi_flash_map; + + spi_flash_map = dev->regs; + /* set receive data length */ + spi_flash_setctrlr1(dev, len); + /* Enable SPI_FLASH */ + spi_flash_map->ssienr = 1; + spi_flash_wait_busy(dev); +} + +static inline void select_extend_op(struct sheipa_spi *dws, uint32_t addr, + uint32_t dummy, + enum flash_mode_type flash_mode, + uint32_t type, uint8_t cmd) +{ + switch (flash_mode) { + case M25P80_NORMAL: + case M25P80_FAST: + case M25P80_AUTO: + case M25P80_NORMAL_WRITE: + case M25P80_AUTO_WRITE: + pr_info("INFO: flash mode error, cmd 0x%02X, flash_mode %d\n", + cmd, flash_mode); + break; + case M25P80_QUAD: + flash_readx4(dws, addr, DATA_WORD, dummy, type, cmd); + break; + case M25P80_DUAL: + flash_readx2(dws, addr, DATA_WORD, dummy, type, cmd); + break; + case M25P80_QUAD_WRITE: + flash_writex4(dws, addr, DATA_WORD, type, cmd); + break; + case M25P80_DUAL_WRITE: + flash_writex2(dws, addr, DATA_WORD, type, cmd); + break; + default: + pr_info("INFO:No support flash cmd:0x%x\n", cmd); + break; + } +} + +static inline void select_op(struct sheipa_spi *dws, uint32_t addr, + uint32_t dummy, enum flash_mode_type flash_mode, + uint32_t type, uint8_t cmd) +{ + mode = 0; + switch (cmd) { + case PP: + case PP_4B: /* for Spansion */ + flash_write(dws, addr, DATA_WORD, cmd); + break; + case WREN: + flash_write_enable(dws); + break; + case WRSR: + flash_set_status(dws, addr, cmd); + break; + case RDSR: + flash_read_status(dws, cmd); + break; + case RDID: + flash_read_id(dws, cmd); + break; + case NORM_READ: + case 0x13: /* NORM_READ_4B */ + flash_read(dws, addr, DATA_WORD, cmd); + break; + case FAST_READ: + case 0x0C: /* FAST_READ_4B */ + flash_fastread(dws, addr, DATA_WORD, dummy, cmd); + break; + case CE: + flash_chip_erase(dws, cmd); + break; + case BE_4K: + flash_be_4k_erase(dws, addr, cmd); + break; + case SE: + case SE_4B: /* for Spansion */ + flash_se_erase(dws, addr, cmd); + break; + case AUTO_MODE: + mode = 1; + set_auto_length(dws); + break; + /* supprot for address 4 byte mdoe */ + case EN4B: + case BRWR: /* for Spansion */ + flash_en4b(dws, cmd); + enable_addr_4byte_mode = 1; + set_addr_length(dws); + set_auto_addr_length(dws); + break; + case EX4B: + flash_ex4b(dws, cmd); + enable_addr_4byte_mode = 0; + break; + default: + select_extend_op(dws, addr, dummy, flash_mode, type, cmd); + break; + } + +} + +/* send cmd(1 byte) + addr(3 byte or 4 byte) to spi fifo */ +static inline void do_spi_cmd(struct sheipa_spi *dws, const u8 *buf, + uint32_t len) +{ + uint32_t addr; + uint32_t dummy; + enum flash_mode_type flash_mode; + uint32_t type; + uint8_t cmd; + + cmd = buf[0]; + if (!enable_addr_4byte_mode) { + addr = (uint32_t) ((buf[1] << 16) | (buf[2] << 8) | (buf[3])); + } else { + addr = (uint32_t) ((buf[1] << 24) | (buf[2] << 16) | + (buf[3] << 8) | (buf[4])); + } + + flash_mode = buf[5]; + dummy = buf[6]; + type = buf[7]; + addr_offset = addr; + first_cmd_xfer = cmd; + first_dummy_xfer = dummy; + first_flash_mode_xfer = flash_mode; + first_type_xfer = type; + select_op(dws, addr, dummy, flash_mode, type, cmd); +} + +static inline void do_spi_send(struct sheipa_spi *dws, const u8 *buf, + uint32_t len) +{ + uint32_t i; + uint32_t cnt; + uint32_t tmp; + uint32_t data; + uint32_t t; + uint32_t addr; + uint32_t dummy; + uint32_t type; + enum flash_mode_type flash_mode; + uint8_t cmd; + + if (!mode) { + if (len <= FIFO_HALF_SIZE) { + cnt = len / 4; + for (i = 0; i < cnt; i++) { + memcpy(&data, buf, 4); + buf += 4; + flash_write_data(dws, data, DATA_WORD); + } + cnt = len % 4; + if (cnt > 0) { + if (cnt == 3) { + memcpy(&data, buf, 2); + buf += 2; + flash_write_data(dws, data, DATA_HALF); + memcpy(&data, buf, 1); + buf += 1; + flash_write_data(dws, data, DATA_BYTE); + } + else { + memcpy(&data, buf, cnt); + buf += cnt; + if (cnt == 1) + flash_write_data(dws, data, DATA_BYTE); + else + flash_write_data(dws, data, DATA_HALF); + } + } + enable_cs_write(dws); + } else { + /* first transfer data (half fifo size) */ + cnt = FIFO_HALF_SIZE / 4; + for (i = 0; i < cnt; i++) { + memcpy(&data, buf, 4); + buf += 4; + flash_write_data(dws, data, DATA_WORD); + } + enable_cs_write(dws); + /* record first transfer cmd and addr */ + addr = addr_offset; + cmd = first_cmd_xfer; + dummy = first_dummy_xfer; + flash_mode = first_flash_mode_xfer; + type = first_type_xfer; + /* t is transfer data times, + * t = (len - first xfer data) / fifo half size + */ + t = (len - FIFO_HALF_SIZE) / FIFO_HALF_SIZE; + /* addr = base addr + offset */ + addr = addr + FIFO_HALF_SIZE; + while (t > 0) { + flash_write_enable(dws); + select_op(dws, addr, dummy, flash_mode, type, + cmd); + cnt = FIFO_HALF_SIZE / 4; + for (i = 0; i < cnt; i++) { + memcpy(&data, buf, 4); + buf += 4; + flash_write_data(dws, data, DATA_WORD); + } + enable_cs_write(dws); + addr = addr + FIFO_HALF_SIZE; + t--; + } + tmp = len % FIFO_HALF_SIZE; + if (tmp > 0) { + flash_write_enable(dws); + select_op(dws, addr, dummy, flash_mode, type, + cmd); + cnt = tmp / 4; + for (i = 0; i < cnt; i++) { + memcpy(&data, buf, 4); + buf += 4; + flash_write_data(dws, data, DATA_WORD); + } + cnt = tmp % 4; + if (cnt > 0) { + if (cnt == 3) { + memcpy(&data, buf, 2); + buf += 2; + flash_write_data(dws, data, DATA_HALF); + memcpy(&data, buf, 1); + buf += 1; + flash_write_data(dws, data, DATA_BYTE); + } + else { + memcpy(&data, buf, cnt); + buf += cnt; + if (cnt == 1) + flash_write_data(dws, data, DATA_BYTE); + else + flash_write_data(dws, data, DATA_HALF); + } + } + enable_cs_write(dws); + } + } + } else { + auto_write(dws, buf, len, addr_offset); + } +} + +/* receive data from spi fifo */ +static inline void do_spi_recv(struct sheipa_spi *dws, u8 *buf, uint32_t len) +{ + uint32_t i; + uint32_t cnt; + uint32_t tmp; + uint32_t data; + uint32_t t; + uint32_t addr; + uint32_t dummy; + uint32_t type; + enum flash_mode_type flash_mode; + uint8_t cmd; + + if (!mode) { + if (len <= FIFO_SIZE) { + enable_cs_read(dws, len); + cnt = len / 4; + for (i = 0; i < cnt; i++) { + data = spi_flash_getdr(dws, 0, DATA_WORD); + memcpy(buf, &data, 4); + buf += 4; + } + cnt = len % 4; + if (cnt > 0) { + data = spi_flash_getdr(dws, 0, DATA_WORD); + memcpy(buf, &data, cnt); + buf += cnt; + } + } else { + enable_cs_read(dws, FIFO_SIZE); + cnt = FIFO_SIZE / 4; + for (i = 0; i < cnt; i++) { + data = spi_flash_getdr(dws, 0, DATA_WORD); + memcpy(buf, &data, 4); + buf += 4; + } + /* record first transfer cmd and addr */ + addr = addr_offset; + cmd = first_cmd_xfer; + dummy = first_dummy_xfer; + flash_mode = first_flash_mode_xfer; + type = first_type_xfer; + /* t is transfer data times, + * t = (len - first xfer data) / fifo size + */ + t = (len - FIFO_SIZE) / FIFO_SIZE; + addr = addr + FIFO_SIZE; + while (t > 0) { + select_op(dws, addr, dummy, flash_mode, type, + cmd); + enable_cs_read(dws, FIFO_SIZE); + for (i = 0; i < cnt; i++) { + data = + spi_flash_getdr(dws, 0, + DATA_WORD); + memcpy(buf, &data, 4); + buf += 4; + } + addr = addr + FIFO_SIZE; + t--; + } + tmp = len % FIFO_SIZE; + if (tmp > 0) { + select_op(dws, addr, dummy, flash_mode, type, + cmd); + enable_cs_read(dws, tmp); + cnt = tmp / 4; + for (i = 0; i < cnt; i++) { + data = + spi_flash_getdr(dws, 0, + DATA_WORD); + memcpy(buf, &data, 4); + buf += 4; + } + cnt = tmp % 4; + if (cnt > 0) { + data = + spi_flash_getdr(dws, 0, + DATA_WORD); + memcpy(buf, &data, cnt); + buf += cnt; + } + } + } + } else { + auto_read(dws, buf, len, addr_offset); + } +} + +static int dw_spi_transfer(struct spi_master *master, struct spi_message *msg) +{ + struct spi_transfer *t; + struct spi_device *spi; + unsigned long flags; + struct sheipa_spi *dws = spi_master_get_devdata(master); + struct spi_flash_param *spi_flash_para = dws->comp_param; + u16 clk_div = 0; + + struct spi_statistics *statm = &master->statistics; + struct spi_statistics *stats = &msg->spi->statistics; + + msg->actual_length = 0; + spi = msg->spi; + + SPI_STATISTICS_INCREMENT_FIELD(statm, messages); + SPI_STATISTICS_INCREMENT_FIELD(stats, messages); + + spin_lock_irqsave(&master->bus_lock_spinlock, flags); + + list_for_each_entry(t, &msg->transfers, transfer_list) { + + if (spi->max_speed_hz != spi_flash_para->spi_flash_sclk) { + if (spi->max_speed_hz > dws->max_freq) { + dev_err(&spi->dev, "unsupported freq %dHz\n", + spi->max_speed_hz); + return -EIO; + } + clk_div = + (dws->max_freq % + spi->max_speed_hz) ? dws->max_freq / + spi->max_speed_hz + + 1 : dws->max_freq / spi->max_speed_hz; + spi_flash_para->spi_flash_sclk = spi->max_speed_hz; + dev_info(&spi->dev, "change speed to %dHz, div %d\n", + spi->max_speed_hz, clk_div); + spi_flash_setbaudr(dws, clk_div); + } + + if (t->tx_buf) { + // first xfer is the cmd + if (msg->actual_length == 0) + do_spi_cmd(dws, t->tx_buf, t->len); + else + do_spi_send(dws, t->tx_buf, t->len); + } + if (t->rx_buf) + do_spi_recv(dws, t->rx_buf, t->len); + + msg->actual_length += t->len; + } + + spin_unlock_irqrestore(&master->bus_lock_spinlock, flags); + spi_res_release(master, msg); + msg->status = 0; + spi_finalize_current_message(master); + + return 0; +} + +static int dw_spi_setup(struct spi_device *spi) +{ + struct sheipa_spi *dws = spi_master_get_devdata(spi->master); + + /* iniitialize Flash_Device_information */ + dws->comp_param = &ps_para; + /* user mode init setting */ + flash_init(dws); + /* auto mode init setting */ + auto_init(dws); + + return 0; +} + +static int sheipa_spi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct sheipa_spi *spi; + struct resource *mem; + struct resource *auto_mem; + int status; + struct clk *clk; + + master = spi_alloc_master(&pdev->dev, sizeof(*spi)); + if (master == NULL) { + dev_dbg(&pdev->dev, "master allocation failed\n"); + return -ENOMEM; + } + + spi = spi_master_get_devdata(master); + spi->master = master; + + master->dev.of_node = pdev->dev.of_node; + master->mode_bits = SPI_CPHA | SPI_CPOL; + master->bus_num = 0; + master->num_chipselect = 1; + master->setup = dw_spi_setup; + master->transfer_one_message = dw_spi_transfer; + + /* for spi user mode */ + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem == NULL) { + status = -ENODEV; + goto err_put_master; + } + + spi->regs = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(spi->regs)) { + status = PTR_ERR(spi->regs); + goto err_put_master; + } + + /* for auto mode */ + auto_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (mem == NULL) { + status = -ENODEV; + goto err_unmap; + } + + spi->auto_regs = devm_ioremap_resource(&pdev->dev, auto_mem); + if (IS_ERR(spi->auto_regs)) { + status = PTR_ERR(spi->auto_regs); + goto err_unmap; + } + + spi->max_freq = 0; + /* Always ask for fixed clock rate from a property. */ + device_property_read_u32(&pdev->dev, "clock-frequency", &spi->max_freq); + + /* If there is separate clock, get the rate from it. */ + clk = devm_clk_get(&pdev->dev, NULL); + if (!IS_ERR_OR_NULL(clk)) { + /* Use the clock from clock source */ + status = clk_prepare_enable(clk); + if (status) + dev_warn(&pdev->dev, "could not enable clock source: %d\n", status); + else + spi->max_freq = clk_get_rate(clk); + } + + /* If no clock rate is defined, fail. */ + if (!spi->max_freq) { + dev_err(&pdev->dev, "clock rate not defined\n"); + status = -EINVAL; + goto err_clk; + } + + master->min_speed_hz = spi->max_freq/8; + master->max_speed_hz = spi->max_freq; + + platform_set_drvdata(pdev, spi); + dev_set_drvdata(&pdev->dev, master); + + status = devm_spi_register_master(&pdev->dev, master); + if (status < 0) + goto err_clk; + + return 0; + +err_clk: + if (!IS_ERR(clk)) + clk_disable_unprepare(clk); + iounmap(spi->auto_regs); +err_unmap: + iounmap(spi->regs); +err_put_master: + spi_master_put(master); + + return status; +} + +static int sheipa_spi_remove(struct platform_device *pdev) +{ + struct sheipa_spi *spi; + struct resource *mem; + + spi = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); + + iounmap(spi->regs); + spi_unregister_master(spi->master); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem->start, resource_size(mem)); + + return 0; +} + +static const struct of_device_id spi_sheipa_of_match[] = { + { .compatible = "realtek,sheipa-spi", }, + { /* end of table */} +}; +MODULE_DEVICE_TABLE(of, spi_sheipa_of_match); + +static struct platform_driver sheipa_spi_driver = { + .probe = sheipa_spi_probe, + .remove = sheipa_spi_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = spi_sheipa_of_match, + }, +}; + +static int __init sheipa_spi_init(void) +{ + return platform_driver_probe(&sheipa_spi_driver, sheipa_spi_probe); +} + +subsys_initcall(sheipa_spi_init); + +static void __exit sheipa_spi_exit(void) +{ + platform_driver_unregister(&sheipa_spi_driver); +} + +module_exit(sheipa_spi_exit); + +MODULE_DESCRIPTION("Sheipa SPI controller driver"); +MODULE_AUTHOR("Realtek PSP Group"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.h b/target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.h new file mode 100644 index 0000000000000..7236fcc2b348f --- /dev/null +++ b/target/linux/realtek/files-4.14/drivers/spi/spi-sheipa.h @@ -0,0 +1,511 @@ +/* + * SHEIPA SPI controller driver + * + * Author: Realtek PSP Group + * + * Copyright 2015, Realtek Semiconductor Corp. + * + * 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 _SPI_SHEIPA_H +#define _SPI_SHEIPA_H + +#include +#include + +/* SPIC config */ +#define ps_DW_APB_SPI_FLASH_BASE BSP_PS_I_SSI_BASE + +#define ps_CC_SPI_FLASH_NUM_SLAVES 1 +#define ps_CC_SPI_FLASH_HAS_DMA 0 +#define ps_CC_SPI_FLASH_DMA_TX_SGL_STATUS 1 +#define ps_CC_SPI_FLASH_DMA_RX_SGL_STATUS 1 +#define ps_CC_SPI_FLASH_RX_FIFO_DEPTH 0x20 +#define ps_CC_SPI_FLASH_TX_FIFO_DEPTH 0x20 +#define ps_CC_SPI_FLASH_RX_ABW 6 +#define ps_CC_SPI_FLASH_TX_ABW 6 +#define ps_CC_SPI_FLASH_INTR_POL 1 +#define ps_CC_SPI_FLASH_INTR_IO 1 +#define ps_CC_SPI_FLASH_INDIVIDUAL 0 +#define ps_CC_SPI_FLASH_ID 0x0 +#define ps_CC_SPI_FLASH_HC_FRF 0 +#define ps_CC_SPI_FLASH_DFLT_FRF 0x0 +#define ps_CC_SPI_FLASH_DFLT_SCPOL 0x0 +#define ps_CC_SPI_FLASH_DFLT_SCPH 0x0 +#define ps_CC_SPI_FLASH_CLK_PERIOD 400 +#define ps_CC_SPI_FLASH_VERSION_ID 0x0 +#define ps_CC_SPI_FLASH_DFLT_SCLK 0x0 + +/* DW error code*/ + +#define DW_EPERM 1 /* operation not permitted */ +#define DW_EIO 5 /* I/O error */ +#define DW_ENXIO 6 /* no such device or address */ +#define DW_ENOMEM 12 /* out of memory */ +#define DW_EACCES 13 /* permission denied */ +#define DW_EBUSY 16 /* device or resource busy */ +#define DW_ENODEV 19 /* no such device */ +#define DW_EINVAL 22 /* invalid argument */ +#define DW_ENOSPC 28 /* no space left on device */ +#define DW_ENOSYS 38 /* function not implemented/supported */ +#define DW_ECHRNG 44 /* channel number out of range */ +#define DW_ENODATA 61 /* no data available */ +#define DW_ETIME 62 /* timer expired */ +#define DW_EPROTO 71 /* protocol error */ + +/* Returns the width of the specified bit-field. */ +#define DW_BIT_WIDTH(__bfws) ((uint32_t) (bfw ## __bfws)) + +/* Returns the offset of the specified bit-field. */ +#define DW_BIT_OFFSET(__bfws) ((uint32_t) (bfo ## __bfws)) + +/* Returns a mask with the bits to be addressed set and all others cleared. */ +#define DW_BITS_MASK(__bfws, __bits) ((uint32_t) ((__bfws) == 32) ? \ + 0x0 : (((0xffffffff) >> (32 - __bits)) << (__bfws))) + +#define DW_BIT_MASK(__bfws) ((uint32_t) ((__bfws) == 32) ? \ + 0x0 : (0x1 << (__bfws))) + +#define DW_BIT_MASK_WIDTH(__bfws, __bits) ((uint32_t) ((__bfws) == 32) ? \ + 0xFFFFFFFF : (((1 << (__bits)) - 1) << (__bfws))) + +/* Clear the specified bits. */ +#define DW_BITS_CLEAR(__datum, __bfws, __bits) \ + ((__datum) = ((uint32_t) (__datum) & ~DW_BITS_MASK(__bfws, __bits))) + +#define DW_BIT_CLEAR(__datum, __bfws) \ + ((__datum) = ((uint32_t) (__datum) & ~DW_BIT_MASK(__bfws))) + +/* + * Returns the relevant bits masked from the data word, still at their + * original offset. + */ +#define DW_BIT_GET_UNSHIFTED(__datum, __bfws) \ + ((uint32_t) ((__datum) & DW_BIT_MASK(__bfws))) + +/* + * Returns the relevant bits masked from the data word shifted to bit + * zero (i.e. access the specifed bits from a word of data as an + * integer value). + */ +#define DW_BIT_GET(__datum, __bfws) \ + ((uint32_t) (((__datum) & DW_BIT_MASK(__bfws)) >> \ + (__bfws))) + +/* + * Place the specified value into the specified bits of a word of data + * (first the data is read, and the non-specified bits are re-written). + */ +#define DW_BITS_SET(__datum, __bfws, __bits) \ + ((__datum) = ((uint32_t) (__datum) & \ + ~DW_BITS_MASK(__bfws, __bits)) | \ + (DW_BITS_MASK(__bfws, __bits))) + +#define DW_BIT_SET(__datum, __bfws) \ + ((__datum) = ((uint32_t) (__datum) & ~DW_BIT_MASK(__bfws)) | \ + (DW_BIT_MASK(__bfws))) + +#define DW_BITS_SET_VAL(__datum, __bfws, __val, bit_num) \ + ((__datum) = ((uint32_t) (__datum) & \ + ~DW_BIT_MASK_WIDTH(__bfws, bit_num)) | \ + ((__val << (__bfws)) & DW_BIT_MASK_WIDTH(__bfws, bit_num))) + +/* + * Place the specified value into the specified bits of a word of data + * without reading first - for sensitive interrupt type registers + */ +#define DW_BIT_SET_NOREAD(__datum, __bfws, __val) \ + ((uint32_t) ((__datum) = (((__val) << (bfo ## __bfws)) & \ + DW_BIT_MASK(__bfws)))) + +/* Shift the specified value into the desired bits. */ +#define DW_BIT_BUILD(__bfws, __val) \ + ((uint32_t) (((__val) << (bfo ## __bfws)) & DW_BIT_MASK(__bfws))) + +/* system endian */ +// #define BIG_ENDIAN 0 + +/* FLASH base address for auto mode */ +#define FIFO_SIZE 64 +#define FIFO_HALF_SIZE (FIFO_SIZE / 2) + +/* Soc tunning dummy cycle only. */ +#define DEF_RD_TUNING_DUMMY_CYCLE 0x2 +#define DEF_WR_BLOCK_BOUND 256 + +/* General flash opcode. */ +#define WRSR 0x01 +#define PP 0x02 +#define NORM_READ 0x03 +#define WRDI 0x04 /* write disable */ +#define RDSR 0x05 +#define WREN 0x06 +#define FAST_READ 0x0b +#define RDID 0x9f +#define CE 0xc7 /* chip erase */ +#define BE_4K 0x20 /* erase 4KiB Block */ +#define SE 0xd8 /* sector erase(usually 64KiB) */ + +/*Spansion 4byte op code*/ +#define PP_4B 0x12 /* Spansion Page Program (4-byte Address) */ +#define SE_4B 0xdc /* Spansion Erase 256 kB (4-byte Address) */ +#define BRWR 0x17 /* Spansion Bank Register Write */ + +/* Support auto mode flash dummy and type info only. */ +#define DEF_RD_DUAL_TYPE RD_DUAL_IO +#define DEF_RD_QUAD_TYPE RD_QUAD_IO +#define DEF_WR_DUAL_TYPE WR_MULTI_NONE +#define DEF_WR_QUAD_TYPE WR_QUAD_II +#define DEF_RD_DUAL_DUMMY_CYCLE 0x4 +#define DEF_RD_QUAD_DUMMY_CYCLE 0x6 +#define DEF_RD_FAST_DUMMY_CYCLE 0x8 + +/* Support auto mode flash opcode only. */ +#define PPX2_I 0x02 +#define PPX2_II 0x02 +#define PPX4_I 0x02 +#define PPX4_II 0x38 +#define READX2_I 0x03 +#define READX2_IO 0xbb /* data and addr channel */ +#define READX4_I 0x03 +#define READX4_IO 0xeb + +/* support auto mode */ +#define AUTO_MODE 0xf5 + +/* Support address 4 byte opcode for large size flash */ +#define EN4B 0xb7 /* Enter 4 byte mode */ +#define EX4B 0xe9 /* Exit 4 byte mode */ +/* + * Used in conjunction with bitops.h to access register bitfields. + * They are defined as bit offset/mask pairs for each DMA register + * bitfield. + */ +#define bfoSPI_FLASH_CTRLR0_FAST_RD ((uint32_t) 20) +#define bfwSPI_FLASH_CTRLR0_FAST_RD ((uint32_t) 1) +#define bfoSPI_FLASH_CTRLR0_DATA_CH ((uint32_t) 18) +#define bfwSPI_FLASH_CTRLR0_DATA_CH ((uint32_t) 2) +#define bfoSPI_FLASH_CTRLR0_ADDR_CH ((uint32_t) 16) +#define bfwSPI_FLASH_CTRLR0_ADDR_CH ((uint32_t) 2) +#define bfoSPI_FLASH_CTRLR0_CFS ((uint32_t) 12) +#define bfwSPI_FLASH_CTRLR0_CFS ((uint32_t) 3) +#define bfoSPI_FLASH_CTRLR0_SRL ((uint32_t) 11) +#define bfwSPI_FLASH_CTRLR0_SRL ((uint32_t) 1) +#define bfoSPI_FLASH_CTRLR0_SLV_OE ((uint32_t) 10) +#define bfwSPI_FLASH_CTRLR0_SLV_OE ((uint32_t) 1) +#define bfoSPI_FLASH_CTRLR0_TMOD ((uint32_t) 8) +#define bfwSPI_FLASH_CTRLR0_TMOD ((uint32_t) 2) +#define bfoSPI_FLASH_CTRLR0_SCPOL ((uint32_t) 7) +#define bfwSPI_FLASH_CTRLR0_SCPOL ((uint32_t) 1) +#define bfoSPI_FLASH_CTRLR0_FRF ((uint32_t) 4) +#define bfwSPI_FLASH_CTRLR0_FRF ((uint32_t) 2) +#define bfoSPI_FLASH_CTRLR0_DFS ((uint32_t) 0) +#define bfwSPI_FLASH_CTRLR0_DFS ((uint32_t) 4) +#define bfoSPI_FLASH_CTRLR1_NDF ((uint32_t) 0) +#define bfwSPI_FLASH_CTRLR1_NDF ((uint32_t) 16) +#define bfoSPI_FLASH_SSIENR_SSI_EN ((uint32_t) 0) +#define bfwSPI_FLASH_SSIENR_SSI_EN ((uint32_t) 1) +#define bfoSPI_FLASH_MWCR_MHS ((uint32_t) 2) +#define bfwSPI_FLASH_MWCR_MHS ((uint32_t) 1) +#define bfoSPI_FLASH_MWCR_MDD ((uint32_t) 1) +#define bfwSPI_FLASH_MWCR_MDD ((uint32_t) 1) +#define bfoSPI_FLASH_MWCR_MWMOD ((uint32_t) 0) +#define bfwSPI_FLASH_MWCR_MWMOD ((uint32_t) 1) +#define bfoSPI_FLASH_SER ((uint32_t) 0) +#define bfwSPI_FLASH_SER ((uint32_t) 4) +#define bfoSPI_FLASH_BAUDR_SCKDV ((uint32_t) 0) +#define bfwSPI_FLASH_BAUDR_SCKDV ((uint32_t) 16) +#define bfoSPI_FLASH_TXFTLR_TFT ((uint32_t) 0) +#define bfwSPI_FLASH_TXFTLR_TFT ((uint32_t) 3) +#define bfoSPI_FLASH_RXFTLR_RFT ((uint32_t) 0) +#define bfwSPI_FLASH_RXFTLR_RFT ((uint32_t) 3) +#define bfoSPI_FLASH_TXFLR_TXTFL ((uint32_t) 0) +#define bfwSPI_FLASH_TXFLR_TXTFL ((uint32_t) 3) +#define bfoSPI_FLASH_RXFLR_RXTFL ((uint32_t) 0) +#define bfwSPI_FLASH_RXFLR_RXTFL ((uint32_t) 3) +#define bfoSPI_FLASH_SR_BUSY ((uint32_t) 0) +#define bfwSPI_FLASH_SR_BUSY ((uint32_t) 1) +#define bfoSPI_FLASH_SR_TFNF ((uint32_t) 1) +#define bfwSPI_FLASH_SR_TFNF ((uint32_t) 1) +#define bfoSPI_FLASH_SR_TFE ((uint32_t) 2) +#define bfwSPI_FLASH_SR_TFE ((uint32_t) 1) +#define bfoSPI_FLASH_SR_RFNE ((uint32_t) 3) +#define bfwSPI_FLASH_SR_RFNE ((uint32_t) 1) +#define bfoSPI_FLASH_SR_RFF ((uint32_t) 4) +#define bfwSPI_FLASH_SR_RFF ((uint32_t) 1) +#define bfoSPI_FLASH_SR_TXE ((uint32_t) 5) +#define bfwSPI_FLASH_SR_TXE ((uint32_t) 1) +#define bfoSPI_FLASH_SR_DCOL ((uint32_t) 6) +#define bfwSPI_FLASH_SR_DCOL ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_TXEIM ((uint32_t) 0) +#define bfwSPI_FLASH_IMR_TXEIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_TXOIM ((uint32_t) 1) +#define bfwSPI_FLASH_IMR_TXOIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_RXUIM ((uint32_t) 2) +#define bfwSPI_FLASH_IMR_RXUIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_RXOIM ((uint32_t) 3) +#define bfwSPI_FLASH_IMR_RXOIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_RXFIM ((uint32_t) 4) +#define bfwSPI_FLASH_IMR_RXFIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_FSEIM ((uint32_t) 5) +#define bfwSPI_FLASH_IMR_FSEIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_WBEIM ((uint32_t) 6) +#define bfwSPI_FLASH_IMR_WBEIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_BYEIM ((uint32_t) 7) +#define bfwSPI_FLASH_IMR_BYEIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_ACTIM ((uint32_t) 8) +#define bfwSPI_FLASH_IMR_ACTIM ((uint32_t) 1) +#define bfoSPI_FLASH_IMR_TXEIM_PEND ((uint32_t) 9) +#define bfwSPI_FLASH_IMR_TXEIM_PEND ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_TXEIS ((uint32_t) 0) +#define bfwSPI_FLASH_ISR_TXEIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_TXOIS ((uint32_t) 1) +#define bfwSPI_FLASH_ISR_TXOIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_RXUIS ((uint32_t) 2) +#define bfwSPI_FLASH_ISR_RXUIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_RXOIS ((uint32_t) 3) +#define bfwSPI_FLASH_ISR_RXOIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_RXFIS ((uint32_t) 4) +#define bfwSPI_FLASH_ISR_RXFIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_FSEIS ((uint32_t) 5) +#define bfwSPI_FLASH_ISR_FSEIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_WBEIS ((uint32_t) 6) +#define bfwSPI_FLASH_ISR_WBEIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_BYEIS ((uint32_t) 7) +#define bfwSPI_FLASH_ISR_BYEIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_ACTIS ((uint32_t) 8) +#define bfwSPI_FLASH_ISR_ACTIS ((uint32_t) 1) +#define bfoSPI_FLASH_ISR_TXEIS_PEND ((uint32_t) 9) +#define bfwSPI_FLASH_ISR_TXEIS_PEND ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_TXEIR ((uint32_t) 0) +#define bfwSPI_FLASH_RISR_TXEIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_TXOIR ((uint32_t) 1) +#define bfwSPI_FLASH_RISR_TXOIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_RXUIR ((uint32_t) 2) +#define bfwSPI_FLASH_RISR_RXUIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_RXOIR ((uint32_t) 3) +#define bfwSPI_FLASH_RISR_RXOIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_RXFIR ((uint32_t) 4) +#define bfwSPI_FLASH_RISR_RXFIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_FSEIR ((uint32_t) 5) +#define bfwSPI_FLASH_RISR_FSEIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_WBEIR ((uint32_t) 6) +#define bfwSPI_FLASH_RISR_WBEIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_BYEIR ((uint32_t) 7) +#define bfwSPI_FLASH_RISR_BYEIR ((uint32_t) 1) +#define bfoSPI_FLASH_RISR_ACTIR ((uint32_t) 8) +#define bfwSPI_FLASH_RISR_ACTIR ((uint32_t) 1) +#define bfoSPI_FLASH_TXOICR_TXOICR ((uint32_t) 0) +#define bfwSPI_FLASH_TXOICR_TXOICR ((uint32_t) 1) +#define bfoSPI_FLASH_RXOICR_RXOICR ((uint32_t) 0) +#define bfwSPI_FLASH_RXOICR_RXOICR ((uint32_t) 1) +#define bfoSPI_FLASH_RXUICR_RXUICR ((uint32_t) 0) +#define bfwSPI_FLASH_RXUICR_RXUICR ((uint32_t) 1) +#define bfoSPI_FLASH_MSTICR_MSTICR ((uint32_t) 0) +#define bfwSPI_FLASH_MSTICR_MSTICR ((uint32_t) 1) +#define bfoSPI_FLASH_ICR_ICR ((uint32_t) 0) +#define bfwSPI_FLASH_ICR_ICR ((uint32_t) 1) +#define bfoSPI_FLASH_DMACR_RDMAE ((uint32_t) 0) +#define bfwSPI_FLASH_DMACR_RDMAE ((uint32_t) 1) +#define bfoSPI_FLASH_DMACR_TDMAE ((uint32_t) 1) +#define bfwSPI_FLASH_DMACR_TDMAE ((uint32_t) 1) +#define bfoSPI_FLASH_DMATDLR_DMATDL ((uint32_t) 0) +#define bfwSPI_FLASH_DMATDLR_DMATDL ((uint32_t) 3) +#define bfoSPI_FLASH_DMARDLR_DMARDL ((uint32_t) 0) +#define bfwSPI_FLASH_DMARDLR_DMARDL ((uint32_t) 3) +#define bfoSPI_FLASH_DR0_dr0 ((uint32_t) 0) +#define bfwSPI_FLASH_DR0_dr0 ((uint32_t) 16) +#define bfoSPI_FLASH_DR1_dr1 ((uint32_t) 0) +#define bfwSPI_FLASH_DR1_dr1 ((uint32_t) 16) +#define bfoSPI_FLASH_DR2_dr2 ((uint32_t) 0) +#define bfwSPI_FLASH_DR2_dr2 ((uint32_t) 16) +#define bfoSPI_FLASH_DR3_dr3 ((uint32_t) 0) +#define bfwSPI_FLASH_DR3_dr3 ((uint32_t) 16) +#define bfoSPI_FLASH_DR4_dr4 ((uint32_t) 0) +#define bfwSPI_FLASH_DR4_dr4 ((uint32_t) 16) +#define bfoSPI_FLASH_DR5_dr5 ((uint32_t) 0) +#define bfwSPI_FLASH_DR5_dr5 ((uint32_t) 16) +#define bfoSPI_FLASH_DR6_dr6 ((uint32_t) 0) +#define bfwSPI_FLASH_DR6_dr6 ((uint32_t) 16) +#define bfoSPI_FLASH_DR7_dr7 ((uint32_t) 0) +#define bfwSPI_FLASH_DR7_dr7 ((uint32_t) 16) +#define bfoSPI_FLASH_DR8_dr8 ((uint32_t) 0) +#define bfwSPI_FLASH_DR8_dr8 ((uint32_t) 16) +#define bfoSPI_FLASH_DR9_dr9 ((uint32_t) 0) +#define bfwSPI_FLASH_DR9_dr9 ((uint32_t) 16) +#define bfoSPI_FLASH_DR10_dr10 ((uint32_t) 0) +#define bfwSPI_FLASH_DR10_dr10 ((uint32_t) 16) +#define bfoSPI_FLASH_DR11_dr11 ((uint32_t) 0) +#define bfwSPI_FLASH_DR11_dr11 ((uint32_t) 16) +#define bfoSPI_FLASH_DR12_dr12 ((uint32_t) 0) +#define bfwSPI_FLASH_DR12_dr12 ((uint32_t) 16) +#define bfoSPI_FLASH_DR13_dr13 ((uint32_t) 0) +#define bfwSPI_FLASH_DR13_dr13 ((uint32_t) 16) +#define bfoSPI_FLASH_DR14_dr14 ((uint32_t) 0) +#define bfwSPI_FLASH_DR14_dr14 ((uint32_t) 16) +#define bfoSPI_FLASH_DR15_dr15 ((uint32_t) 0) +#define bfwSPI_FLASH_DR15_dr15 ((uint32_t) 16) +#define bfoSPI_FLASH_AUTO_LEN_ADDR ((uint32_t) 16) +#define bfwSPI_FLASH_AUTO_LEN_ADDR ((uint32_t) 2) +#define bfoSPI_FLASH_AUTO_LEN_DUM ((uint32_t) 0) +#define bfwSPI_FLASH_AUTO_LEN_DUM ((uint32_t) 16) + +/* This macro is used to initialize a spi_flash_param structure. To use + * this macro, the relevant C header file must also be included. This + * is generated when a DesignWare device is synthesized. + */ +#define CC_DEFINE_SPI_FLASH_PARAMS(prefix) { \ + prefix ## CC_SPI_FLASH_NUM_SLAVES ,\ + prefix ## CC_SPI_FLASH_TX_FIFO_DEPTH ,\ + prefix ## CC_SPI_FLASH_RX_FIFO_DEPTH ,\ + prefix ## CC_SPI_FLASH_ID ,\ + prefix ## CC_SPI_FLASH_DFLT_SCPOL ,\ + prefix ## CC_SPI_FLASH_DFLT_SCPH ,\ + prefix ## CC_SPI_FLASH_CLK_PERIOD ,\ + prefix ## CC_SPI_FLASH_VERSION_ID ,\ + prefix ## CC_SPI_FLASH_DFLT_SCLK \ +} + +/* + * This data type is used to describe read type with multi_channel + */ +enum spi_flash_byte_num { + DATA_BYTE = 0, + DATA_HALF = 1, + DATA_WORD = 2 +}; + +enum flash_rd_multi_type { + RD_MULTI_NONE = 0x00, + RD_DUAL_O = 0x01, + RD_DUAL_IO = 0x02, + RD_QUAD_O = 0x03, + RD_QUAD_IO = 0x04 +}; + +/* + * This data type is used to describe write type with multi_channel + */ +enum flash_wr_multi_type { + WR_MULTI_NONE = 0x00, + WR_DUAL_I = 0x01, + WR_DUAL_II = 0x02, + WR_QUAD_I = 0x03, + WR_QUAD_II = 0x04 +}; + +/* + * This data type is used to describe m25p80 mode type + */ +enum flash_mode_type { + M25P80_NORMAL = 0, + M25P80_FAST, + M25P80_QUAD, + M25P80_DUAL, + M25P80_AUTO, + M25P80_QUAD_WRITE, + M25P80_DUAL_WRITE, + M25P80_NORMAL_WRITE, + M25P80_AUTO_WRITE +}; + +struct sheipa_spi { + struct spi_master *master; + void __iomem *regs; + void __iomem *auto_regs; + void *comp_param; + u32 max_freq; +}; + +/* + * This is the structure used for accessing the spi_flash register + * portmap. + */ +struct spi_flash_portmap { +/* Channel registers + * The offset address for each of the channel registers + * is shown for channel 0. For other channel numbers + * use the following equation. + * offset = (channel_num * 0x058) + channel_0 offset + */ + struct { + volatile uint32_t ctrlr0; /* Control Reg 0 (0x000) */ + volatile uint32_t ctrlr1; + volatile uint32_t ssienr; /* SPIC enable Reg1 (0x008) */ + volatile uint32_t mwcr; + volatile uint32_t ser; /* Slave enable Reg (0x010) */ + volatile uint32_t baudr; + volatile uint32_t txftlr; /* TX_FIFO threshold level (0x018) */ + volatile uint32_t rxftlr; + volatile uint32_t txflr; /* TX_FIFO threshold level (0x020) */ + volatile uint32_t rxflr; + volatile uint32_t sr; /* Destination Status Reg (0x028) */ + volatile uint32_t imr; + volatile uint32_t isr; /* Interrupt Stauts Reg (0x030) */ + volatile uint32_t risr; + + /* TX_FIFO overflow_INT clear (0x038) */ + volatile uint32_t txoicr; + volatile uint32_t rxoicr; + /* RX_FIFO underflow_INT clear (0x040) */ + volatile uint32_t rxuicr; + volatile uint32_t msticr; + volatile uint32_t icr; /* Interrupt clear Reg (0x048) */ + volatile uint32_t dmacr; + volatile uint32_t dmatdlr; /* DMA TX_data level (0x050) */ + volatile uint32_t dmardlr; + volatile uint32_t idr; /* Identiation Scatter Reg (0x058) */ + volatile uint32_t spi_flash_version; + union { + volatile uint8_t byte; + volatile uint16_t half; + volatile uint32_t word; + } dr[32]; + volatile uint32_t rd_fast_single; + /* Read dual data cmd Reg (0x0e4) */ + volatile uint32_t rd_dual_o; + volatile uint32_t rd_dual_io; + /* Read quad data cnd Reg (0x0ec) */ + volatile uint32_t rd_quad_o; + volatile uint32_t rd_quad_io; + volatile uint32_t wr_single; /* write single cmd Reg (0x0f4) */ + volatile uint32_t wr_dual_i; + /* write dual addr/data cmd(0x0fc) */ + volatile uint32_t wr_dual_ii; + volatile uint32_t wr_quad_i; + /* write quad addr/data cnd(0x104) */ + volatile uint32_t wr_quad_ii; + volatile uint32_t wr_enable; + volatile uint32_t rd_status; /* read status cmd Reg (0x10c) */ + volatile uint32_t ctrlr2; + volatile uint32_t fbaudr; /* fast baud rate Reg (0x114) */ + volatile uint32_t addr_length; + /* Auto addr length Reg (0x11c) */ + volatile uint32_t auto_length; + volatile uint32_t valid_cmd; + volatile uint32_t flash_size; /* Flash size Reg (0x124) */ + volatile uint32_t flush_fifo; + }; +}; + +struct spi_flash_param { + uint32_t spi_flash_num_slaves; /* slaves number */ + uint32_t spi_flash_tx_fifo_depth; /* TX fifo depth number */ + uint32_t spi_flash_rx_fifo_depth; /* RX fifo depth number */ + uint32_t spi_flash_idr; /* ID code */ + uint32_t spi_flash_scpol; /* Serial clock polarity */ + uint32_t spi_flash_scph; /* Serial clock phase */ + uint32_t spi_flash_clk_period; /* serial clock period */ + uint32_t spi_flash_version_id; /* spi flash ID */ + uint32_t spi_flash_sclk; /* Serial clock */ +}; + +/* This function is used to wait the SSI is not at busy state. */ +static void flash_wait_busy(struct sheipa_spi *dev); +/* This function is used to read status of flash. */ +static uint8_t flash_get_status(struct sheipa_spi *dev); + +#endif diff --git a/target/linux/realtek/image/Makefile b/target/linux/realtek/image/Makefile new file mode 100644 index 0000000000000..88511c7a3a0c9 --- /dev/null +++ b/target/linux/realtek/image/Makefile @@ -0,0 +1,299 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +DEVICE_VARS += IMAGE_SIZE CVIMG_KERNEL_BURN_ADDR CVIMG_LOADER_START_ADDR CVIMG_ROOTFS_BURN_ADDR + +define Build/loader-common + rm -rf $@.src + $(MAKE) -C lzma-loader \ + PKG_BUILD_DIR="$@.src" \ + TARGET_DIR="$(dir $@)" LOADER_NAME="$(notdir $@)" \ + BOARD="$(DEV_PROFILE)" \ + SUBTARGET="$(SUBTARGET)" \ + LZMA_TEXT_START=0x81000000 LOADADDR=0x80000000 \ + $(1) compile loader.bin + mv "$@.bin" "$@" + rm -rf $@.src +endef + +define Build/loader-cmdline-compile + $(call Build/loader-common,LOADER_DATA="$@" KERNEL_CMDLINE="$(CMDLINE)") +endef + +define Build/cvimg + $(STAGING_DIR_HOST)/bin/cvimg \ + -i $@ \ + -o $@.new \ + $(1) && mv $@.new $@ || rm -f $@ +endef + +define Build/cvimg-kernel + $(call Build/cvimg, \ + -e $(CVIMG_LOADER_START_ADDR) \ + -b $(CVIMG_KERNEL_BURN_ADDR) \ + -c new \ + -t kernel \ + $(1)) +endef + +define Build/cvimg-fw + $(call Build/cvimg, \ + -e $(CVIMG_LOADER_START_ADDR) \ + -b $(CVIMG_KERNEL_BURN_ADDR) \ + -c new \ + -t fw \ + $(1)) +endef + +define Build/cvimg-custom + $(call Build/cvimg, \ + -e $(CVIMG_LOADER_START_ADDR) \ + -b $(CVIMG_KERNEL_BURN_ADDR) \ + -s $(CVIMG_CUSTOM_SIGNATURE) \ + $(1)) +endef + +define Build/cvimg-rootfs + $(call Build/cvimg, \ + -e $(CVIMG_ROOTFS_BURN_ADDR) \ + -b $(CVIMG_ROOTFS_BURN_ADDR) \ + -c new \ + -t rootfs \ + $(1)) +endef + +define Build/append-cvimg-rootfs + cp $(IMAGE_ROOTFS) $(IMAGE_ROOTFS).new && \ + $(STAGING_DIR_HOST)/bin/padjffs2 $(IMAGE_ROOTFS).new \ + $(if $(BLOCKSIZE),$(BLOCKSIZE:%k=%),4 8 16 64 128 256) && \ + $(STAGING_DIR_HOST)/bin/cvimg \ + -i $(IMAGE_ROOTFS).new \ + -o $(IMAGE_ROOTFS).new \ + -e $(CVIMG_ROOTFS_BURN_ADDR) \ + -b $(CVIMG_ROOTFS_BURN_ADDR) \ + -c new \ + -t rootfs \ + $(1) && (dd if=$(IMAGE_ROOTFS).new >> $@ && \ + rm -f $(IMAGE_ROOTFS).new) || rm -f $@ $(IMAGE_ROOTFS).new +endef + +define Build/append-fake-rootfs + $(call Build/cvimg, \ + -a $(BLOCKSIZE) \ + -f) +endef + +define Build/cvimg-pad-rootfs + $(call Build/cvimg, \ + -b $(CVIMG_KERNEL_BURN_ADDR) \ + -c new \ + -a $(BLOCKSIZE) \ + -t rootfs \ + -j) +endef + +define Build/tbs_dlink_big + $(STAGING_DIR_HOST)/bin/tbs_dlink -b $(1) $@ +endef + +define Device/Default + BLOCKSIZE := 4k + PROFILES := Default $$(DEV_PROFILE) + CVIMG_ROOTFS_BURN_ADDR := 0 +endef + +define Device/RealtekDTS + PROFILES = Default $$(DTS) + DEVICE_DTS_DIR := ../dts + KERNEL := kernel-bin | append-dtb | lzma +endef + +ifeq ($(SUBTARGET),rtl8197d) +define Device/DIR815D1 + $(Device/RealtekDTS) + DEVICE_DTS := DIR815D1 + DEV_PROFILE := DIR815D1 + IMAGE_SIZE := 7936k + DEVICE_TITLE := D-Link DIR-815 D1 + SUPPORTED_DEVICES := dir-815-d1 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin := append-kernel | pad-to 1900544 | append-rootfs | pad-rootfs | \ + tbs_dlink_big -k 0x197400 -r 0x4DFF70 -g BR -m DIR825G1 -p RTL8197DL_AC1200 + IMAGE/sysupgrade.bin := append-kernel | pad-to 1900544 | append-rootfs | \ + pad-rootfs | append-metadata +endef +TARGET_DEVICES += DIR815D1 + +define Device/DIR822C1 + $(Device/RealtekDTS) + BLOCKSIZE := 64k + DEVICE_DTS := DIR822C1 + DEVICE_TITLE := D-Link DIR-822 C1 + SUPPORTED_DEVICES := dir-822-c1 + IMAGE_SIZE := 7936k + DEV_PROFILE := DIR822C1 + CMDLINE := console=ttyS0,38400 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x30000 + CVIMG_LOADER_START_ADDR := 0x81000000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | cvimg-pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | pad-rootfs +endef +TARGET_DEVICES += DIR822C1 + +endif + +ifeq ($(SUBTARGET),rtl8197f) +define Device/RE708 + $(Device/RealtekDTS) + BLOCKSIZE := 64k + DEVICE_DTS := RE708 + DEVICE_TITLE := Multilaser RE708 V1 + SUPPORTED_DEVICES := re708v1 re708-v1 + IMAGE_SIZE := 7936k + DEV_PROFILE := RE708 + CMDLINE := console=ttyS0,38400 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x30000 + CVIMG_LOADER_START_ADDR := 0x81000000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | cvimg-pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | pad-rootfs +endef +TARGET_DEVICES += RE708 + +define Device/GWR1200AC + $(Device/RealtekDTS) + BLOCKSIZE := 64k + DEVICE_TITLE := Greatek GWR1200AC V1 + SUPPORTED_DEVICES := gwr1200ac-v1 + IMAGE_SIZE := 7936k + DEV_PROFILE := GWR1200AC + CMDLINE := console=ttyS0,38400 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x30000 + CVIMG_LOADER_START_ADDR := 0x80A00000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | cvimg-pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | pad-rootfs +endef + +define Device/GWR1200AC-V1 + $(Device/GWR1200AC) + DEVICE_DTS := GWR1200ACV1 + DEVICE_TITLE := Greatek GWR1200AC V1 + SUPPORTED_DEVICES := gwr1200ac-v1 +endef +TARGET_DEVICES += GWR1200AC-V1 + +define Device/GWR1200AC-V2 + $(Device/GWR1200AC) + DEVICE_DTS := GWR1200ACV2 + DEVICE_TITLE := Greatek GWR1200AC V2 + SUPPORTED_DEVICES := gwr1200ac-v2 +endef +TARGET_DEVICES += GWR1200AC-V2 + +define Device/ACTIONRG1200 + $(Device/RealtekDTS) + BLOCKSIZE := 64k + DEVICE_DTS := ACTIONRG1200 + DEVICE_TITLE := Intelbras ACTIONRG1200 V1 + SUPPORTED_DEVICES := actionrg1200v1 + IMAGE_SIZE := 7872k + DEV_PROFILE := ACTIONRG1200 + CMDLINE := console=ttyS0,115200 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x30000 + CVIMG_LOADER_START_ADDR := 0x80A00000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | pad-offset 64k 16 | append-rootfs | pad-rootfs -x 16 | cvimg-kernel -T + IMAGE/sysupgrade.bin = append-kernel | pad-offset 64k 16 | append-rootfs | pad-rootfs -x 16 | cvimg-kernel -S +endef +TARGET_DEVICES += ACTIONRG1200 + +define Device/ACTIONRF1200 + $(Device/RealtekDTS) + BLOCKSIZE := 64k + DEVICE_DTS := ACTIONRF1200 + DEVICE_TITLE := Intelbras ACTIONRF1200 V1 + SUPPORTED_DEVICES := actionrf1200v1 + IMAGE_SIZE := 7872k + DEV_PROFILE := ACTIONRF1200 + CMDLINE := console=ttyS0,115200 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x30000 + CVIMG_LOADER_START_ADDR := 0x80A00000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | pad-offset 64k 16 | append-rootfs | pad-rootfs -x 16 | cvimg-kernel -T + IMAGE/sysupgrade.bin = append-kernel | pad-offset 64k 16 | append-rootfs | pad-rootfs -x 16 | cvimg-kernel -S +endef +TARGET_DEVICES += ACTIONRF1200 +endif + +ifeq ($(SUBTARGET),rtl8196e) +define Device/GWR300N + $(Device/RealtekDTS) + DEVICE_DTS := GWR300 + DEVICE_TITLE := Greatek GWR 300N + SUPPORTED_DEVICES := gwr300v1 gwr300-v1 + IMAGE_SIZE := 3904k + DEV_PROFILE := GWR300N + CMDLINE := console=ttyS0,38400 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x18000 + CVIMG_LOADER_START_ADDR := 0x81000000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | cvimg-pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | pad-rootfs +endef +TARGET_DEVICES += GWR300N + +define Device/RE172 + $(Device/RealtekDTS) + DEVICE_DTS := RE172 + DEVICE_TITLE := Multilaser RE172 V1 + SUPPORTED_DEVICES := re172v1 re172-v1 + IMAGE_SIZE := 4032k + DEV_PROFILE := RE172 + CMDLINE := console=ttyS0,38400 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x10000 + CVIMG_LOADER_START_ADDR := 0x81000000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | cvimg-pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | pad-rootfs +endef +TARGET_DEVICES += RE172 + +define Device/RE707 + $(Device/RealtekDTS) + DEVICE_DTS := RE707 + DEVICE_TITLE := Multilaser RE707 V1 + SUPPORTED_DEVICES := re707v1 re707-v1 + IMAGE_SIZE := 3904k + DEV_PROFILE := RE707 + CMDLINE := console=ttyS0,38400 + KERNEL := kernel-bin | append-dtb | lzma | loader-cmdline-compile + CVIMG_KERNEL_BURN_ADDR := 0x20000 + CVIMG_LOADER_START_ADDR := 0x81000000 + IMAGES := factory.bin sysupgrade.bin + IMAGE/factory.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | cvimg-pad-rootfs + IMAGE/sysupgrade.bin = append-kernel | append-fake-rootfs | append-rootfs | cvimg-kernel | pad-rootfs +endef +TARGET_DEVICES += RE707 + +endif + +define Image/Build/Initramfs + $(call Image/Build/Profile/$(PROFILE),initramfs) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/realtek/image/lzma-loader/Makefile b/target/linux/realtek/image/lzma-loader/Makefile new file mode 100644 index 0000000000000..28916829e7612 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (C) 2011 OpenWrt.org +# Copyright (C) 2011 Gabor Juhos +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +LZMA_TEXT_START := 0x80500000 +LOADADDR := 0x80000000 +LOADER := loader.bin +LOADER_NAME := $(basename $(notdir $(LOADER))) +LOADER_DATA := +TARGET_DIR := +BOARD := + +ifeq ($(TARGET_DIR),) +TARGET_DIR := $(KDIR) +endif + +LOADER_BIN := $(TARGET_DIR)/$(LOADER_NAME).bin +LOADER_GZ := $(TARGET_DIR)/$(LOADER_NAME).gz +LOADER_ELF := $(TARGET_DIR)/$(LOADER_NAME).elf + +PKG_NAME := lzma-loader +PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME) + +.PHONY : loader-compile loader.bin loader.elf loader.gz + +$(PKG_BUILD_DIR)/.prepared: + mkdir $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ + touch $@ + +loader-compile: $(PKG_BUILD_DIR)/.prepared + $(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \ + LZMA_TEXT_START=$(LZMA_TEXT_START) \ + LOADADDR=$(LOADADDR) \ + LOADER_DATA=$(LOADER_DATA) \ + BOARD="$(BOARD)" \ + SUBTARGET="$(SUBTARGET)" \ + clean all + +loader.gz: $(PKG_BUILD_DIR)/loader.bin + gzip -nc9 $< > $(LOADER_GZ) + +loader.elf: $(PKG_BUILD_DIR)/loader.elf + $(CP) $< $(LOADER_ELF) + +loader.bin: $(PKG_BUILD_DIR)/loader.bin + $(CP) $< $(LOADER_BIN) + +download: +prepare: $(PKG_BUILD_DIR)/.prepared +compile: loader-compile + +install: + +clean: + rm -rf $(PKG_BUILD_DIR) + diff --git a/target/linux/realtek/image/lzma-loader/src/LzmaDecode.c b/target/linux/realtek/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 0000000000000..cb8345377ea8a --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,584 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#ifdef _LZMA_IN_CB + +#define RC_TEST { if (Buffer == BufferLim) \ + { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ + BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} + +#define RC_INIT Buffer = BufferLim = 0; RC_INIT2 + +#else + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#endif + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + #ifdef _LZMA_OUT_READ + { + int i; + propsRes->DictionarySize = 0; + for (i = 0; i < 4; i++) + propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); + if (propsRes->DictionarySize == 0) + propsRes->DictionarySize = 1; + } + #endif + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + + #ifdef _LZMA_OUT_READ + + UInt32 Range = vs->Range; + UInt32 Code = vs->Code; + #ifdef _LZMA_IN_CB + const Byte *Buffer = vs->Buffer; + const Byte *BufferLim = vs->BufferLim; + #else + const Byte *Buffer = inStream; + const Byte *BufferLim = inStream + inSize; + #endif + int state = vs->State; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + UInt32 distanceLimit = vs->DistanceLimit; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->Properties.DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + Byte tempDictionary[4]; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + if (len == kLzmaStreamWasFinishedId) + return LZMA_RESULT_OK; + + if (dictionarySize == 0) + { + dictionary = tempDictionary; + dictionarySize = 1; + tempDictionary[0] = vs->TempDictionary[0]; + } + + if (len == kLzmaNeedInitId) + { + { + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + UInt32 i; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + rep0 = rep1 = rep2 = rep3 = 1; + state = 0; + globalPos = 0; + distanceLimit = 0; + dictionaryPos = 0; + dictionary[dictionarySize - 1] = 0; + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + } + len = 0; + } + while(len != 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; + + #else /* if !_LZMA_OUT_READ */ + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + #ifndef _LZMA_IN_CB + *inSizeProcessed = 0; + #endif + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + #ifdef _LZMA_IN_CB + RC_INIT; + #else + RC_INIT(inStream, inSize); + #endif + + #endif /* _LZMA_OUT_READ */ + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + UpdateBit0(prob); + + #ifdef _LZMA_OUT_READ + if (distanceLimit == 0) + #else + if (nowPos == 0) + #endif + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + if (distanceLimit < dictionarySize) + distanceLimit++; + #endif + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + #ifdef _LZMA_OUT_READ + if (rep0 > distanceLimit) + #else + if (rep0 > nowPos) + #endif + return LZMA_RESULT_DATA_ERROR; + + #ifdef _LZMA_OUT_READ + if (dictionarySize - distanceLimit > (UInt32)len) + distanceLimit += len; + else + distanceLimit = dictionarySize; + #endif + + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + #ifdef _LZMA_OUT_READ + vs->Range = Range; + vs->Code = Code; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + (UInt32)nowPos; + vs->DistanceLimit = distanceLimit; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->RemainLen = len; + vs->TempDictionary[0] = tempDictionary[0]; + #endif + + #ifdef _LZMA_IN_CB + vs->Buffer = Buffer; + vs->BufferLim = BufferLim; + #else + *inSizeProcessed = (SizeT)(Buffer - inStream); + #endif + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/target/linux/realtek/image/lzma-loader/src/LzmaDecode.h b/target/linux/realtek/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 0000000000000..2870eeb9c9c11 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,113 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +#include "LzmaTypes.h" + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb UInt16 +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; + #ifdef _LZMA_OUT_READ + UInt32 DictionarySize; + #endif +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + + #ifdef _LZMA_IN_CB + const unsigned char *Buffer; + const unsigned char *BufferLim; + #endif + + #ifdef _LZMA_OUT_READ + unsigned char *Dictionary; + UInt32 Range; + UInt32 Code; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 DistanceLimit; + UInt32 Reps[4]; + int State; + int RemainLen; + unsigned char TempDictionary[4]; + #endif +} CLzmaDecoderState; + +#ifdef _LZMA_OUT_READ +#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; } +#endif + +int LzmaDecode(CLzmaDecoderState *vs, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + #endif + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/target/linux/realtek/image/lzma-loader/src/LzmaTypes.h b/target/linux/realtek/image/lzma-loader/src/LzmaTypes.h new file mode 100644 index 0000000000000..9c27290757c4f --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/LzmaTypes.h @@ -0,0 +1,45 @@ +/* +LzmaTypes.h + +Types for LZMA Decoder + +This file written and distributed to public domain by Igor Pavlov. +This file is part of LZMA SDK 4.40 (2006-05-01) +*/ + +#ifndef __LZMATYPES_H +#define __LZMATYPES_H + +#ifndef _7ZIP_BYTE_DEFINED +#define _7ZIP_BYTE_DEFINED +typedef unsigned char Byte; +#endif + +#ifndef _7ZIP_UINT16_DEFINED +#define _7ZIP_UINT16_DEFINED +typedef unsigned short UInt16; +#endif + +#ifndef _7ZIP_UINT32_DEFINED +#define _7ZIP_UINT32_DEFINED +#ifdef _LZMA_UINT32_IS_ULONG +typedef unsigned long UInt32; +#else +typedef unsigned int UInt32; +#endif +#endif + +/* #define _LZMA_NO_SYSTEM_SIZE_T */ +/* You can use it, if you don't want */ + +#ifndef _7ZIP_SIZET_DEFINED +#define _7ZIP_SIZET_DEFINED +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +#include +typedef size_t SizeT; +#endif +#endif + +#endif diff --git a/target/linux/realtek/image/lzma-loader/src/Makefile b/target/linux/realtek/image/lzma-loader/src/Makefile new file mode 100644 index 0000000000000..d5cfa2764476a --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/Makefile @@ -0,0 +1,102 @@ +# +# Makefile for the LZMA compressed kernel loader for +# Realtek SoCs based boards +# +# Copyright (C) 2011 Gabor Juhos +# +# Some parts of this file was based on the OpenWrt specific lzma-loader +# for the BCM47xx and ADM5120 based boards: +# Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) +# Copyright (C) 2005 Mineharu Takahara +# Copyright (C) 2005 by Oleg I. Vdovikin +# +# 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. +# + +LOADADDR := +LZMA_TEXT_START := 0x80500000 +LOADER_DATA := +BOARD := + +CC := $(CROSS_COMPILE)gcc +LD := $(CROSS_COMPILE)ld +OBJCOPY := $(CROSS_COMPILE)objcopy +OBJDUMP := $(CROSS_COMPILE)objdump + +BIN_FLAGS := -O binary -R .reginfo -R .note -R .comment -R .mdebug \ + -R .MIPS.abiflags -S + +CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \ + -mno-abicalls -fno-pic -ffunction-sections -pipe -mlong-calls \ + -fno-common -ffreestanding \ + -mabi=32 -Wa,-32 + +ifeq ($(SUBTARGET),rtl8197f) +CFLAGS += -march=mips32r2 -Wa,-march=mips32r2 +else +CFLAGS += -march=lx4380 -Wa,-march=lx4380 -D__RLX__ +endif + +CFLAGS += -D_LZMA_PROB32 + +ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ + +LDFLAGS = -static --gc-sections -no-warn-mismatch +LDFLAGS += -e startup -T loader.lds -Ttext $(LZMA_TEXT_START) + +O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) + +OBJECTS := head.o loader.o cache.o board.o printf.o LzmaDecode.o + +ifneq ($(strip $(LOADER_DATA)),) +OBJECTS += data.o +CFLAGS += -DLZMA_WRAPPER=1 -DLOADADDR=$(LOADADDR) +endif + +ifneq ($(strip $(KERNEL_CMDLINE)),) +CFLAGS += -DCONFIG_KERNEL_CMDLINE='"$(KERNEL_CMDLINE)"' +endif + +BOARD_DEF := $(shell echo $(strip $(BOARD)) | tr a-z A-Z | tr - _) +ifneq ($(BOARD_DEF),) +CFLAGS += -DCONFIG_BOARD_$(BOARD_DEF) +endif + +all: loader.elf + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +install: + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o : %.S + $(CC) $(ASFLAGS) -c -o $@ $< + +data.o: $(LOADER_DATA) + $(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $< + +loader: $(OBJECTS) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) + +loader.bin: loader + $(OBJCOPY) $(BIN_FLAGS) $< $@ + +loader2.o: loader.bin + $(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $< + +loader.elf: loader2.o + $(LD) -e startup -T loader2.lds -Ttext $(LOADADDR) -o $@ $< + +mrproper: clean + +clean: + rm -f loader *.elf *.bin *.o + + + diff --git a/target/linux/realtek/image/lzma-loader/src/board.c b/target/linux/realtek/image/lzma-loader/src/board.c new file mode 100644 index 0000000000000..08629d3ad0835 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/board.c @@ -0,0 +1,47 @@ +/* + * LZMA compressed kernel loader for Realtek SoCs based boards + * + * Copyright (C) 2011 Gabor Juhos + * Copyright (C) 2017 Weijie Gao + * Copyright (C) 2019 Gaspare Bruno + * + * 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. + */ + +#include + +#define READREG(r) *(volatile unsigned int *)(r) +#define WRITEREG(r,v) *(volatile unsigned int *)(r) = (v) + +#define KSEG1ADDR(_x) (((_x) & 0x1fffffff) | 0xa0000000) + +#ifdef __RLX__ +#define UART_BASE 0xb8002000 +#define UART_TX 0x0 +#define UART_SHIFT 24 +#else +// For mips RTL8197F +#define UART_BASE 0xb8147000 +#define UART_TX (((READREG(0xB8000000) & 0xFFFFF000) == 0x8197F000) ? 0x024 : 0x0) +#define UART_SHIFT 0 +#endif + +#define UART_LSR 0x14 +#define UART_LSR_THRE 0x20 + +#define UART_READ(r) (READREG(UART_BASE + (r)) >> UART_SHIFT) +#define UART_WRITE(r,v) WRITEREG(UART_BASE + (r), (v) << UART_SHIFT) + +void board_putc(int ch) +{ + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); + UART_WRITE(UART_TX, ch); + while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0); +} + +void board_init(void) +{ + +} diff --git a/target/linux/realtek/image/lzma-loader/src/cache.c b/target/linux/realtek/image/lzma-loader/src/cache.c new file mode 100644 index 0000000000000..6a4c28f4fa485 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/cache.c @@ -0,0 +1,65 @@ +/* + * LZMA compressed kernel loader for Realtek SoCs based boards + * + * Copyright (C) 2011 Gabor Juhos + * Copyright (C) 2017 Weijie Gao + * + * 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. + * + */ + +#include "cacheops.h" + +#ifdef __RLX__ + +#define LEXRA_CCTL_BARRIER \ + do { \ + __asm__ __volatile__ ( "" : : : "memory"); \ + } while (0) + +void flush_cache(unsigned long start_addr, unsigned long size) +{ + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DWB); + LEXRA_CCTL_BARRIER; + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_DInval); + LEXRA_CCTL_BARRIER; + write_c0_cctl(0); + LEXRA_CCTL_BARRIER; + write_c0_cctl(CCTL_IInval); +} + +#else + +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +void flush_cache(unsigned long start_addr, unsigned long size) +{ + unsigned long lsize = 32; + unsigned long addr = start_addr & ~(lsize - 1); + unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); + + while (1) { + cache_op(Hit_Writeback_Inv_D, addr); + cache_op(Hit_Invalidate_I, addr); + if (addr == aend) + break; + addr += lsize; + } +} + +#endif + diff --git a/target/linux/realtek/image/lzma-loader/src/cache.h b/target/linux/realtek/image/lzma-loader/src/cache.h new file mode 100644 index 0000000000000..62ef143292caf --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/cache.h @@ -0,0 +1,17 @@ +/* + * LZMA compressed kernel loader for Realtek SoCs based boards + * + * Copyright (C) 2011 Gabor Juhos + * + * 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 __CACHE_H +#define __CACHE_H + +void flush_cache(unsigned long start_addr, unsigned long size); + +#endif /* __CACHE_H */ diff --git a/target/linux/realtek/image/lzma-loader/src/cacheops.h b/target/linux/realtek/image/lzma-loader/src/cacheops.h new file mode 100644 index 0000000000000..c0085d380315c --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/cacheops.h @@ -0,0 +1,50 @@ +/* + * Cache operations for the cache instruction. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H + +#ifdef __RLX__ +// for RLX8196E and RLX8197D + +#define CP0_CCTL $20 +#define CCTL_DInval 0x00000001 +#define CCTL_IInval 0x00000002 +#define CCTL_DWB 0x00000100 +#define CCTL_DWBInval 0x00000200 + +#ifndef __ASSEMBLY__ + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define write_c0_cctl(val) __write_32bit_c0_register($20, 0, val) + +#endif /* __ASSEMBLY__ */ + +#else +// For RLX8197F (MIPS32R2) + +#define Hit_Invalidate_I 0x10 +#define Hit_Writeback_Inv_D 0x15 + +#endif + +#endif /* __ASM_CACHEOPS_H */ + diff --git a/target/linux/realtek/image/lzma-loader/src/head.S b/target/linux/realtek/image/lzma-loader/src/head.S new file mode 100644 index 0000000000000..491b8f10050d9 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/head.S @@ -0,0 +1,164 @@ +/* + * LZMA compressed kernel loader for Realtek SoCs based boards + * + * Copyright (C) 2011 Gabor Juhos + * Copyright (C) 2017 Weijie Gao + * Copyright (C) 2019 Gaspare Bruno + * + * Some parts of this code was based on the OpenWrt specific lzma-loader + * for the BCM47xx and ADM5120 based boards: + * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * 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. + */ + +#include +#include +#include "cacheops.h" + +#define KSEG0 0x80000000 + +#define CP0_COUNT $9 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_CAUSE $13 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 + + .text + +LEAF(startup) + .set noreorder +#ifdef __RLX__ + .set mips1 + + mtc0 zero, CP0_CAUSE # clear before writing status register + + mfc0 t0, CP0_STATUS + li t1, 0x1000003f + or t0, t1 + xori t0, 0x3f + mtc0 t0, CP0_STATUS + nop + nop +#else +// Mips32r2 + .set mips32 + + mtc0 zero, CP0_WATCHLO # clear watch registers + mtc0 zero, CP0_WATCHHI + mtc0 zero, CP0_CAUSE # clear before writing status register + + mfc0 t0, CP0_STATUS + li t1, 0x1000001f + or t0, t1 + xori t0, 0x1f + mtc0 t0, CP0_STATUS + sll zero, 3 + + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_COMPARE + sll zero, 3 +#endif + + la t0, __reloc_label # get linked address of label + bal __reloc_label # branch and link to label to + nop # get actual address +__reloc_label: + subu t0, ra, t0 # get reloc_delta + + beqz t0, __reloc_done # if delta is 0 we are in the right place + nop + + /* Copy our code to the right place */ + la t1, _code_start # get linked address of _code_start + la t2, _code_end # get linked address of _code_end + addu t0, t0, t1 # calculate actual address of _code_start + +__reloc_copy: + lw t3, 0(t0) + nop + sw t3, 0(t1) + add t1, 4 + blt t1, t2, __reloc_copy + add t0, 4 + +#ifdef __RLX__ + /* flush cache */ + mtc0 zero, CP0_CCTL + nop + li t2, CCTL_DWB + mtc0 t2, CP0_CCTL + nop + + mtc0 zero, CP0_CCTL + nop + li t2, CCTL_DInval + mtc0 t2, CP0_CCTL + nop + + mtc0 zero, CP0_CCTL + nop + li t2, CCTL_IInval + mtc0 t2, CP0_CCTL + nop +#else + /* flush cache */ + la t0, _code_start + la t1, _code_end + +// CACHELINE_SIZE 32 + li t2, ~(31) + and t0, t2 + and t1, t2 + li t2, 32 + + b __flush_check + nop + +__flush_line: + cache Hit_Writeback_Inv_D, 0(t0) + cache Hit_Invalidate_I, 0(t0) + add t0, t2 + +__flush_check: + bne t0, t1, __flush_line + nop + + sync +#endif + +__reloc_done: + + /* clear bss */ + la t0, _bss_start + la t1, _bss_end + b __bss_check + nop + +__bss_fill: + sw zero, 0(t0) + addi t0, 4 + +__bss_check: + bne t0, t1, __bss_fill + nop + + /* Setup new "C" stack */ + la sp, _stack + nop + + /* reserve stack space for a0-a3 registers */ + subu sp, 16 + + /* jump to the decompressor routine */ + la t0, loader_main + nop + jr t0 + nop + + .set reorder +END(startup) diff --git a/target/linux/realtek/image/lzma-loader/src/loader.c b/target/linux/realtek/image/lzma-loader/src/loader.c new file mode 100644 index 0000000000000..443c16a76fe52 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/loader.c @@ -0,0 +1,192 @@ +/* + * LZMA compressed kernel loader for Realtek SoCs based boards + * + * Copyright (C) 2011 Gabor Juhos + * Copyright (C) 2017 Weijie Gao + * + * Some parts of this code was based on the OpenWrt specific lzma-loader + * for the BCM47xx and ADM5120 based boards: + * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org) + * Copyright (C) 2005 Mineharu Takahara + * Copyright (C) 2005 by Oleg I. Vdovikin + * + * 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. + */ + +#include +#include + +#include "cache.h" +#include "printf.h" +#include "LzmaDecode.h" + +#undef LZMA_DEBUG + +#ifdef LZMA_DEBUG +# define DBG(f, a...) printf(f, ## a) +#else +# define DBG(f, a...) do {} while (0) +#endif + +/* beyond the image end, size not known in advance */ +extern unsigned char workspace[]; +extern void board_init(void); + +static CLzmaDecoderState lzma_state; +static unsigned char *lzma_data; +static unsigned long lzma_datasize; +static unsigned long lzma_outsize; +static unsigned long kernel_la; + +#ifdef CONFIG_KERNEL_CMDLINE +#define kernel_argc 2 +static const char kernel_cmdline[] = CONFIG_KERNEL_CMDLINE; +static const char *kernel_argv[] = { + NULL, + kernel_cmdline, + NULL, +}; +#endif /* CONFIG_KERNEL_CMDLINE */ + +static void halt(void) +{ + printf("\nSystem halted!\n"); + for(;;); +} + +static __inline__ unsigned long get_be32(void *buf) +{ + unsigned char *p = buf; + + return (((unsigned long) p[0] << 24) + + ((unsigned long) p[1] << 16) + + ((unsigned long) p[2] << 8) + + (unsigned long) p[3]); +} + +static __inline__ unsigned char lzma_get_byte(void) +{ + unsigned char c; + + lzma_datasize--; + c = *lzma_data++; + + return c; +} + +static int lzma_init_props(void) +{ + unsigned char props[LZMA_PROPERTIES_SIZE]; + int res; + int i; + + /* read lzma properties */ + for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) + props[i] = lzma_get_byte(); + + /* read the lower half of uncompressed size in the header */ + lzma_outsize = ((SizeT) lzma_get_byte()) + + ((SizeT) lzma_get_byte() << 8) + + ((SizeT) lzma_get_byte() << 16) + + ((SizeT) lzma_get_byte() << 24); + + /* skip rest of the header (upper half of uncompressed size) */ + for (i = 0; i < 4; i++) + lzma_get_byte(); + + res = LzmaDecodeProperties(&lzma_state.Properties, props, + LZMA_PROPERTIES_SIZE); + return res; +} + +static int lzma_decompress(unsigned char *outStream) +{ + SizeT ip, op; + int ret; + + lzma_state.Probs = (CProb *) workspace; + + ret = LzmaDecode(&lzma_state, lzma_data, lzma_datasize, &ip, outStream, + lzma_outsize, &op); + + if (ret != LZMA_RESULT_OK) { + int i; + + DBG("LzmaDecode error %d at %08x, osize:%d ip:%d op:%d\n", + ret, lzma_data + ip, lzma_outsize, ip, op); + + for (i = 0; i < 16; i++) + DBG("%02x ", lzma_data[ip + i]); + + DBG("\n"); + } + + return ret; +} + +static void lzma_init_data(void) +{ + extern unsigned char _lzma_data_start[]; + extern unsigned char _lzma_data_end[]; + + kernel_la = LOADADDR; + lzma_data = _lzma_data_start; + lzma_datasize = _lzma_data_end - _lzma_data_start; +} + +void loader_main(unsigned long reg_a0, unsigned long reg_a1, + unsigned long reg_a2, unsigned long reg_a3) +{ + void (*kernel_entry) (unsigned long, unsigned long, unsigned long, + unsigned long); + int res; + + board_init(); + + printf("\n\nOpenWrt kernel loader for Realtek RTL819X\n"); + printf("Copyright (C) 2011 Gabor Juhos \n"); + printf("Copyright (C) 2017 Weijie Gao \n"); + printf("Copyright (C) 2019 Gaspare Bruno \n"); + + lzma_init_data(); + + res = lzma_init_props(); + if (res != LZMA_RESULT_OK) { + printf("Incorrect LZMA stream properties!\n"); + halt(); + } + + printf("Decompressing kernel... "); + + res = lzma_decompress((unsigned char *) kernel_la); + if (res != LZMA_RESULT_OK) { + printf("failed, "); + switch (res) { + case LZMA_RESULT_DATA_ERROR: + printf("data error!\n"); + break; + default: + printf("unknown error %d!\n", res); + } + halt(); + } else { + printf("done!\n"); + } + + flush_cache(kernel_la, lzma_outsize); + + printf("Starting kernel at %08x...\n\n", kernel_la); + +#ifdef CONFIG_KERNEL_CMDLINE + reg_a0 = kernel_argc; + reg_a1 = (unsigned long) kernel_argv; + reg_a2 = 0; + reg_a3 = 0; +#endif + + kernel_entry = (void *) kernel_la; + kernel_entry(reg_a0, reg_a1, reg_a2, reg_a3); +} + diff --git a/target/linux/realtek/image/lzma-loader/src/loader.lds b/target/linux/realtek/image/lzma-loader/src/loader.lds new file mode 100644 index 0000000000000..01ff85236147d --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/loader.lds @@ -0,0 +1,34 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .text : { + _code_start = .; + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.data.lzma) + } + + . = ALIGN(32); + .data : { + *(.data) + *(.data.*) + } + + . = ALIGN(32); + _code_end = .; + + _bss_start = .; + .bss : { + *(.bss) + *(.bss.*) + } + + . = ALIGN(32); + _bss_end = .; + + . = . + 8192; + _stack = .; + + workspace = .; +} diff --git a/target/linux/realtek/image/lzma-loader/src/loader2.lds b/target/linux/realtek/image/lzma-loader/src/loader2.lds new file mode 100644 index 0000000000000..db0bb464242fb --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/loader2.lds @@ -0,0 +1,10 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .text : { + startup = .; + *(.text) + *(.text.*) + *(.data) + *(.data.*) + } +} diff --git a/target/linux/realtek/image/lzma-loader/src/lzma-data.lds b/target/linux/realtek/image/lzma-loader/src/lzma-data.lds new file mode 100644 index 0000000000000..abf756ba13a58 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/lzma-data.lds @@ -0,0 +1,8 @@ +OUTPUT_ARCH(mips) +SECTIONS { + .data.lzma : { + _lzma_data_start = .; + *(.data) + _lzma_data_end = .; + } +} diff --git a/target/linux/realtek/image/lzma-loader/src/printf.c b/target/linux/realtek/image/lzma-loader/src/printf.c new file mode 100644 index 0000000000000..7bb5a86e187d4 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/printf.c @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +#include "printf.h" + +extern void board_putc(int ch); + +/* this is the maximum width for a variable */ +#define LP_MAX_BUF 256 + +/* macros */ +#define IsDigit(x) ( ((x) >= '0') && ((x) <= '9') ) +#define Ctod(x) ( (x) - '0') + +/* forward declaration */ +static int PrintChar(char *, char, int, int); +static int PrintString(char *, char *, int, int); +static int PrintNum(char *, unsigned long, int, int, int, int, char, int); + +/* private variable */ +static const char theFatalMsg[] = "fatal error in lp_Print!"; + +/* -*- + * A low level printf() function. + */ +static void +lp_Print(void (*output)(void *, char *, int), + void * arg, + char *fmt, + va_list ap) +{ + +#define OUTPUT(arg, s, l) \ + { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \ + (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \ + } else { \ + (*output)(arg, s, l); \ + } \ + } + + char buf[LP_MAX_BUF]; + + char c; + char *s; + long int num; + + int longFlag; + int negFlag; + int width; + int prec; + int ladjust; + char padc; + + int length; + + for(;;) { + { + /* scan for the next '%' */ + char *fmtStart = fmt; + while ( (*fmt != '\0') && (*fmt != '%')) { + fmt ++; + } + + /* flush the string found so far */ + OUTPUT(arg, fmtStart, fmt-fmtStart); + + /* are we hitting the end? */ + if (*fmt == '\0') break; + } + + /* we found a '%' */ + fmt ++; + + /* check for long */ + if (*fmt == 'l') { + longFlag = 1; + fmt ++; + } else { + longFlag = 0; + } + + /* check for other prefixes */ + width = 0; + prec = -1; + ladjust = 0; + padc = ' '; + + if (*fmt == '-') { + ladjust = 1; + fmt ++; + } + + if (*fmt == '0') { + padc = '0'; + fmt++; + } + + if (IsDigit(*fmt)) { + while (IsDigit(*fmt)) { + width = 10 * width + Ctod(*fmt++); + } + } + + if (*fmt == '.') { + fmt ++; + if (IsDigit(*fmt)) { + prec = 0; + while (IsDigit(*fmt)) { + prec = prec*10 + Ctod(*fmt++); + } + } + } + + + /* check format flag */ + negFlag = 0; + switch (*fmt) { + case 'b': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'd': + case 'D': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + if (num < 0) { + num = - num; + negFlag = 1; + } + length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'o': + case 'O': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'u': + case 'U': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'x': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0); + OUTPUT(arg, buf, length); + break; + + case 'X': + if (longFlag) { + num = va_arg(ap, long int); + } else { + num = va_arg(ap, int); + } + length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1); + OUTPUT(arg, buf, length); + break; + + case 'c': + c = (char)va_arg(ap, int); + length = PrintChar(buf, c, width, ladjust); + OUTPUT(arg, buf, length); + break; + + case 's': + s = (char*)va_arg(ap, char *); + length = PrintString(buf, s, width, ladjust); + OUTPUT(arg, buf, length); + break; + + case '\0': + fmt --; + break; + + default: + /* output this char as it is */ + OUTPUT(arg, fmt, 1); + } /* switch (*fmt) */ + + fmt ++; + } /* for(;;) */ + + /* special termination call */ + OUTPUT(arg, "\0", 1); +} + + +/* --------------- local help functions --------------------- */ +static int +PrintChar(char * buf, char c, int length, int ladjust) +{ + int i; + + if (length < 1) length = 1; + if (ladjust) { + *buf = c; + for (i=1; i< length; i++) buf[i] = ' '; + } else { + for (i=0; i< length-1; i++) buf[i] = ' '; + buf[length - 1] = c; + } + return length; +} + +static int +PrintString(char * buf, char* s, int length, int ladjust) +{ + int i; + int len=0; + char* s1 = s; + while (*s1++) len++; + if (length < len) length = len; + + if (ladjust) { + for (i=0; i< len; i++) buf[i] = s[i]; + for (i=len; i< length; i++) buf[i] = ' '; + } else { + for (i=0; i< length-len; i++) buf[i] = ' '; + for (i=length-len; i < length; i++) buf[i] = s[i-length+len]; + } + return length; +} + +static int +PrintNum(char * buf, unsigned long u, int base, int negFlag, + int length, int ladjust, char padc, int upcase) +{ + /* algorithm : + * 1. prints the number from left to right in reverse form. + * 2. fill the remaining spaces with padc if length is longer than + * the actual length + * TRICKY : if left adjusted, no "0" padding. + * if negtive, insert "0" padding between "0" and number. + * 3. if (!ladjust) we reverse the whole string including paddings + * 4. otherwise we only reverse the actual string representing the num. + */ + + int actualLength =0; + char *p = buf; + int i; + + do { + int tmp = u %base; + if (tmp <= 9) { + *p++ = '0' + tmp; + } else if (upcase) { + *p++ = 'A' + tmp - 10; + } else { + *p++ = 'a' + tmp - 10; + } + u /= base; + } while (u != 0); + + if (negFlag) { + *p++ = '-'; + } + + /* figure out actual length and adjust the maximum length */ + actualLength = p - buf; + if (length < actualLength) length = actualLength; + + /* add padding */ + if (ladjust) { + padc = ' '; + } + if (negFlag && !ladjust && (padc == '0')) { + for (i = actualLength-1; i< length-1; i++) buf[i] = padc; + buf[length -1] = '-'; + } else { + for (i = actualLength; i< length; i++) buf[i] = padc; + } + + + /* prepare to reverse the string */ + { + int begin = 0; + int end; + if (ladjust) { + end = actualLength - 1; + } else { + end = length -1; + } + + while (end > begin) { + char tmp = buf[begin]; + buf[begin] = buf[end]; + buf[end] = tmp; + begin ++; + end --; + } + } + + /* adjust the string pointer */ + return length; +} + +static void printf_output(void *arg, char *s, int l) +{ + int i; + + // special termination call + if ((l==1) && (s[0] == '\0')) return; + + for (i=0; i< l; i++) { + board_putc(s[i]); + if (s[i] == '\n') board_putc('\r'); + } +} + +void printf(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + lp_Print(printf_output, 0, fmt, ap); + va_end(ap); +} diff --git a/target/linux/realtek/image/lzma-loader/src/printf.h b/target/linux/realtek/image/lzma-loader/src/printf.h new file mode 100644 index 0000000000000..9b1c1df232861 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/printf.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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 _printf_h_ +#define _printf_h_ + +#include +void printf(char *fmt, ...); + +#endif /* _printf_h_ */ diff --git a/target/linux/realtek/patches-4.14/0001-add-lexra-cpu.patch b/target/linux/realtek/patches-4.14/0001-add-lexra-cpu.patch new file mode 100644 index 0000000000000..a43efab62c8d0 --- /dev/null +++ b/target/linux/realtek/patches-4.14/0001-add-lexra-cpu.patch @@ -0,0 +1,509 @@ +Index: linux-4.14.131/arch/mips/Kconfig +=================================================================== +--- linux-4.14.131.orig/arch/mips/Kconfig ++++ linux-4.14.131/arch/mips/Kconfig +@@ -1571,6 +1571,20 @@ config CPU_R3000 + might be a safe bet. If the resulting kernel does not work, + try to recompile with R3000. + ++config CPU_RLX4181 ++ bool "RLX4181" ++ depends on SYS_HAS_CPU_RLX4181 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select CPU_RLX ++ ++config CPU_RLX5281 ++ bool "RLX5281" ++ depends on SYS_HAS_CPU_RLX5281 ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ select CPU_RLX ++ + config CPU_TX39XX + bool "R39XX" + depends on SYS_HAS_CPU_TX39XX +@@ -1844,6 +1858,11 @@ config SYS_SUPPORTS_ZBOOT_UART_PROM + bool + select SYS_SUPPORTS_ZBOOT + ++config CPU_RLX ++ bool ++ select CPU_SUPPORTS_32BIT_KERNEL ++ select CPU_SUPPORTS_HIGHMEM ++ + config CPU_LOONGSON2 + bool + select CPU_SUPPORTS_32BIT_KERNEL +@@ -1934,6 +1953,12 @@ config SYS_HAS_CPU_MIPS64_R6 + config SYS_HAS_CPU_R3000 + bool + ++config SYS_HAS_CPU_RLX4181 ++ bool ++ ++config SYS_HAS_CPU_RLX5281 ++ bool ++ + config SYS_HAS_CPU_TX39XX + bool + +@@ -2166,7 +2191,7 @@ config PAGE_SIZE_8KB + + config PAGE_SIZE_16KB + bool "16kB" +- depends on !CPU_R3000 && !CPU_TX39XX ++ depends on !CPU_R3000 && !CPU_TX39XX && !CPU_RLX + help + Using 16kB page size will result in higher performance kernel at + the price of higher memory consumption. This option is available on +@@ -2185,7 +2210,7 @@ config PAGE_SIZE_32KB + + config PAGE_SIZE_64KB + bool "64kB" +- depends on !CPU_R3000 && !CPU_TX39XX ++ depends on !CPU_R3000 && !CPU_TX39XX && !CPU_RLX + help + Using 64kB page size will result in higher performance kernel at + the price of higher memory consumption. This option is available on +@@ -2253,15 +2278,15 @@ config CPU_HAS_PREFETCH + + config CPU_GENERIC_DUMP_TLB + bool +- default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX) ++ default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX || CPU_RLX) + + config CPU_R4K_FPU + bool +- default y if !(CPU_R3000 || CPU_TX39XX) ++ default y if !(CPU_R3000 || CPU_TX39XX || CPU_RLX) + + config CPU_R4K_CACHE_TLB + bool +- default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON) ++ default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON || CPU_RLX) + + config MIPS_MT_SMP + bool "MIPS MT SMP support (1 TC on each available VPE)" +@@ -2488,7 +2513,7 @@ config CPU_MIPSR2_IRQ_EI + + config CPU_HAS_SYNC + bool +- depends on !CPU_R3000 ++ depends on !(CPU_R3000 || CPU_RLX4181) + default y + + # +@@ -2506,14 +2531,14 @@ config CPU_R4400_WORKAROUNDS + + config MIPS_ASID_SHIFT + int +- default 6 if CPU_R3000 || CPU_TX39XX ++ default 6 if CPU_R3000 || CPU_TX39XX || CPU_RLX + default 4 if CPU_R8000 + default 0 + + config MIPS_ASID_BITS + int + default 0 if MIPS_ASID_BITS_VARIABLE +- default 6 if CPU_R3000 || CPU_TX39XX ++ default 6 if CPU_R3000 || CPU_TX39XX || CPU_RLX + default 8 + + config MIPS_ASID_BITS_VARIABLE +Index: linux-4.14.131/arch/mips/Makefile +=================================================================== +--- linux-4.14.131.orig/arch/mips/Makefile ++++ linux-4.14.131/arch/mips/Makefile +@@ -189,6 +189,9 @@ endif + cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 + cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap + ++cflags-$(CONFIG_CPU_RLX4181) += -march=lx4380 ++cflags-$(CONFIG_CPU_RLX5281) += -march=lx5380 ++ + cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) + cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) + cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,) +Index: linux-4.14.131/arch/mips/lib/Makefile +=================================================================== +--- linux-4.14.131.orig/arch/mips/lib/Makefile ++++ linux-4.14.131/arch/mips/lib/Makefile +@@ -14,6 +14,7 @@ lib-$(CONFIG_GENERIC_CSUM) := $(filter-o + obj-$(CONFIG_CPU_GENERIC_DUMP_TLB) += dump_tlb.o + obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o + obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o ++obj-$(CONFIG_CPU_RLX) += r3k_dump_tlb.o + + # libgcc-style stuff needed in the kernel + obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o multi3.o \ +Index: linux-4.14.131/arch/mips/kernel/entry.S +=================================================================== +--- linux-4.14.131.orig/arch/mips/kernel/entry.S ++++ linux-4.14.131/arch/mips/kernel/entry.S +@@ -98,7 +98,7 @@ restore_partial: # restore partial fram + SAVE_AT + SAVE_TEMP + LONG_L v0, PT_STATUS(sp) +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + and v0, ST0_IEP + #else + and v0, ST0_IE +Index: linux-4.14.131/arch/mips/kernel/genex.S +=================================================================== +--- linux-4.14.131.orig/arch/mips/kernel/genex.S ++++ linux-4.14.131/arch/mips/kernel/genex.S +@@ -165,7 +165,7 @@ NESTED(handle_int, PT_SIZE, sp) + .set push + .set noat + mfc0 k0, CP0_STATUS +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + and k0, ST0_IEP + bnez k0, 1f + +@@ -584,7 +584,7 @@ isrdhwr: + get_saved_sp /* k1 := current_thread_info */ + .set noreorder + MFC0 k0, CP0_EPC +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + ori k1, _THREAD_MASK + xori k1, _THREAD_MASK + LONG_L v1, TI_TP_VALUE(k1) +Index: linux-4.14.131/arch/mips/include/asm/cpu-features.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/cpu-features.h ++++ linux-4.14.131/arch/mips/include/asm/cpu-features.h +@@ -74,6 +74,9 @@ + #ifndef cpu_has_octeon_cache + #define cpu_has_octeon_cache 0 + #endif ++#ifndef cpu_has_lexra_cache ++#define cpu_has_lexra_cache 0 ++#endif + /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work. */ + #ifndef cpu_has_fpu + #define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU) +Index: linux-4.14.131/arch/mips/include/asm/cpu-type.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/cpu-type.h ++++ linux-4.14.131/arch/mips/include/asm/cpu-type.h +@@ -105,6 +105,14 @@ static inline int __pure __get_cpu_type( + case CPU_TX3927: + #endif + ++#ifdef CONFIG_SYS_HAS_CPU_RLX4181 ++ case CPU_RLX4181: ++#endif ++ ++#ifdef CONFIG_SYS_HAS_CPU_RLX5281 ++ case CPU_RLX5281: ++#endif ++ + #ifdef CONFIG_SYS_HAS_CPU_VR41XX + case CPU_VR41XX: + case CPU_VR4111: +Index: linux-4.14.131/arch/mips/include/asm/cpu.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/cpu.h ++++ linux-4.14.131/arch/mips/include/asm/cpu.h +@@ -91,6 +91,16 @@ + #define PRID_IMP_R5500 0x5500 + #define PRID_IMP_LOONGSON_64 0x6300 /* Loongson-2/3 */ + ++#define PRID_IMP_LX4180 0xc100 ++#define PRID_IMP_LX4280 0xc200 ++#define PRID_IMP_LX4189 0xc400 ++#define PRID_IMP_LX5180 0xc500 ++#define PRID_IMP_LX5280 0xc600 ++#define PRID_IMP_LX8000 0xc700 ++#define PRID_IMP_LX4380 0xcd00 /* Lexra LX4380 / RLX4181 */ ++#define PRID_IMP_LX5380 0xdc00 /* Lexra LX5380 / RLX5281 */ ++#define PRID_IMP_LX8380 0xce00 ++ + #define PRID_IMP_UNKNOWN 0xff00 + + /* +@@ -286,6 +296,9 @@ enum cpu_type_enum { + CPU_R2000, CPU_R3000, CPU_R3000A, CPU_R3041, CPU_R3051, CPU_R3052, + CPU_R3081, CPU_R3081E, + ++ /* Lexra / Realtek */ ++ CPU_RLX4181, CPU_RLX5281, ++ + /* + * R4000 class processors + */ +Index: linux-4.14.131/arch/mips/include/asm/isadep.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/isadep.h ++++ linux-4.14.131/arch/mips/include/asm/isadep.h +@@ -10,7 +10,7 @@ + #ifndef __ASM_ISADEP_H + #define __ASM_ISADEP_H + +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + /* + * R2000 or R3000 + */ +Index: linux-4.14.131/arch/mips/include/asm/module.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/module.h ++++ linux-4.14.131/arch/mips/include/asm/module.h +@@ -104,6 +104,8 @@ search_module_dbetables(unsigned long ad + #define MODULE_PROC_FAMILY "MIPS64_R6 " + #elif defined CONFIG_CPU_R3000 + #define MODULE_PROC_FAMILY "R3000 " ++#elif defined CONFIG_CPU_RLX ++#define MODULE_PROC_FAMILY "RLX " + #elif defined CONFIG_CPU_TX39XX + #define MODULE_PROC_FAMILY "TX39XX " + #elif defined CONFIG_CPU_VR41XX +Index: linux-4.14.131/arch/mips/include/asm/pgtable-32.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/pgtable-32.h ++++ linux-4.14.131/arch/mips/include/asm/pgtable-32.h +@@ -175,7 +175,7 @@ static inline pte_t pfn_pte(unsigned lon + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) + #define pte_unmap(pte) ((void)(pte)) + +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + + /* Swap entries must have VALID bit cleared. */ + #define __swp_type(x) (((x).val >> 10) & 0x1f) +Index: linux-4.14.131/arch/mips/include/asm/pgtable-bits.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/pgtable-bits.h ++++ linux-4.14.131/arch/mips/include/asm/pgtable-bits.h +@@ -80,7 +80,7 @@ enum pgtable_bits { + _PAGE_MODIFIED_SHIFT, + }; + +-#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + + /* Page table bits used for r3k systems */ + enum pgtable_bits { +@@ -146,7 +146,7 @@ enum pgtable_bits { + #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) + #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) + #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + # define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) + # define _CACHE_MASK _CACHE_UNCACHED + # define _PFN_SHIFT PAGE_SHIFT +@@ -204,7 +204,7 @@ static inline uint64_t pte_to_entrylo(un + /* + * Cache attributes + */ +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + + #define _CACHE_CACHABLE_NONCOHERENT 0 + #define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED +Index: linux-4.14.131/arch/mips/include/asm/pgtable.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/pgtable.h ++++ linux-4.14.131/arch/mips/include/asm/pgtable.h +@@ -197,7 +197,7 @@ static inline void pte_clear(struct mm_s + static inline void set_pte(pte_t *ptep, pte_t pteval) + { + *ptep = pteval; +-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) ++#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) && !defined(CONFIG_CPU_RLX) + if (pte_val(pteval) & _PAGE_GLOBAL) { + pte_t *buddy = ptep_buddy(ptep); + /* +@@ -256,7 +256,7 @@ static inline void set_pte(pte_t *ptep, + static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) + { + htw_stop(); +-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) ++#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) && !defined(CONFIG_CPU_RLX) + /* Preserve global status for the pair */ + if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL) + set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL)); +Index: linux-4.14.131/arch/mips/include/asm/stackframe.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/stackframe.h ++++ linux-4.14.131/arch/mips/include/asm/stackframe.h +@@ -42,7 +42,7 @@ + cfi_restore \reg \offset \docfi + .endm + +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + #define STATMASK 0x3f + #else + #define STATMASK 0x1f +@@ -349,7 +349,7 @@ + cfi_ld sp, PT_R29, \docfi + .endm + +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + + .macro RESTORE_SOME docfi=0 + .set push +@@ -477,7 +477,7 @@ + .macro KMODE + mfc0 t0, CP0_STATUS + li t1, ST0_CU0 | (STATMASK & ~1) +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + andi t2, t0, ST0_IEP + srl t2, 2 + or t0, t2 +Index: linux-4.14.131/arch/mips/include/asm/string.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/string.h ++++ linux-4.14.131/arch/mips/include/asm/string.h +@@ -84,7 +84,7 @@ static __inline__ int strcmp(__const__ c + "addiu\t%1,1\n\t" + "bnez\t%2,1b\n\t" + "lbu\t%2,(%0)\n\t" +-#if defined(CONFIG_CPU_R3000) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_RLX4181) + "nop\n\t" + #endif + "move\t%2,$1\n" +@@ -117,7 +117,7 @@ strncmp(__const__ char *__cs, __const__ + "bnez\t%3,1b\n\t" + "addiu\t%1,1\n" + "2:\n\t" +-#if defined(CONFIG_CPU_R3000) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_RLX4181) + "nop\n\t" + #endif + "move\t%3,$1\n" +Index: linux-4.14.131/arch/mips/kernel/Makefile +=================================================================== +--- linux-4.14.131.orig/arch/mips/kernel/Makefile ++++ linux-4.14.131/arch/mips/kernel/Makefile +@@ -39,6 +39,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount. + sw-y := r4k_switch.o + sw-$(CONFIG_CPU_R3000) := r2300_switch.o + sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o ++sw-$(CONFIG_CPU_RLX) := r2300_switch.o + sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o + obj-y += $(sw-y) + +Index: linux-4.14.131/arch/mips/kernel/cpu-probe.c +=================================================================== +--- linux-4.14.131.orig/arch/mips/kernel/cpu-probe.c ++++ linux-4.14.131/arch/mips/kernel/cpu-probe.c +@@ -1504,7 +1504,25 @@ static inline void cpu_probe_legacy(stru + __cpu_name[cpu] = "Loongson 1B"; + break; + } ++ break; + ++ case PRID_IMP_LX4380: ++ case PRID_IMP_LX5380: ++ /* Lexra Processors */ ++ c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; ++ c->ases = MIPS_ASE_MIPS16; ++ c->tlbsize = 32; ++ switch (c->processor_id & PRID_IMP_MASK) { ++ case PRID_IMP_LX4380: ++ c->cputype = CPU_RLX4181; ++ __cpu_name[cpu] = "Lexra LX4380 / RLX4181"; ++ break; ++ case PRID_IMP_LX5380: ++ c->cputype = CPU_RLX5281; ++ c->options |= MIPS_CPU_LLSC; ++ __cpu_name[cpu] = "Lexra LX5380 / RLX5281"; ++ break; ++ } + break; + } + } +Index: linux-4.14.131/arch/mips/kernel/process.c +=================================================================== +--- linux-4.14.131.orig/arch/mips/kernel/process.c ++++ linux-4.14.131/arch/mips/kernel/process.c +@@ -140,7 +140,7 @@ int copy_thread_tls(unsigned long clone_ + p->thread.reg17 = kthread_arg; + p->thread.reg29 = childksp; + p->thread.reg31 = (unsigned long) ret_from_kernel_thread; +-#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) ++#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_RLX) + status = (status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) | + ((status & (ST0_KUC | ST0_IEC)) << 2); + #else +Index: linux-4.14.131/arch/mips/mm/Makefile +=================================================================== +--- linux-4.14.131.orig/arch/mips/mm/Makefile ++++ linux-4.14.131/arch/mips/mm/Makefile +@@ -20,6 +20,7 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag + + obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o + obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o ++obj-$(CONFIG_CPU_RLX) += c-lexra.o tlb-r3k.o + obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o + obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o + obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o +Index: linux-4.14.131/arch/mips/mm/cache.c +=================================================================== +--- linux-4.14.131.orig/arch/mips/mm/cache.c ++++ linux-4.14.131/arch/mips/mm/cache.c +@@ -241,6 +241,12 @@ void cpu_cache_init(void) + octeon_cache_init(); + } + ++ if (cpu_has_lexra_cache) { ++ extern void __weak lexra_cache_init(void); ++ ++ lexra_cache_init(); ++ } ++ + setup_protection_map(); + } + +Index: linux-4.14.131/arch/mips/mm/tlbex.c +=================================================================== +--- linux-4.14.131.orig/arch/mips/mm/tlbex.c ++++ linux-4.14.131/arch/mips/mm/tlbex.c +@@ -2616,6 +2616,8 @@ void build_tlb_refill_handler(void) + case CPU_TX3912: + case CPU_TX3922: + case CPU_TX3927: ++ case CPU_RLX4181: ++ case CPU_RLX5281: + #ifndef CONFIG_MIPS_PGD_C0_CONTEXT + if (cpu_has_local_ebase) + build_r3000_tlb_refill_handler(); +Index: linux-4.14.131/arch/mips/include/asm/mipsregs.h +=================================================================== +--- linux-4.14.131.orig/arch/mips/include/asm/mipsregs.h ++++ linux-4.14.131/arch/mips/include/asm/mipsregs.h +@@ -18,6 +18,10 @@ + #include + #include + ++#if defined(CONFIG_CPU_RLX) ++#include ++#endif ++ + /* + * The following macros are especially useful for __asm__ + * inline assembler. +@@ -1468,8 +1472,13 @@ do { \ + #define read_c0_contextconfig() __read_32bit_c0_register($4, 1) + #define write_c0_contextconfig(val) __write_32bit_c0_register($4, 1, val) + ++#if defined(CONFIG_CPU_RLX5281) ++#define read_c0_userlocal() __read_32bit_lxc0_register($8) ++#define write_c0_userlocal(val) __write_32bit_lxc0_register($8, val) ++#else + #define read_c0_userlocal() __read_ulong_c0_register($4, 2) + #define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) ++#endif + + #define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3) + #define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val) diff --git a/target/linux/realtek/patches-4.14/0002-add-realtek-targets.patch b/target/linux/realtek/patches-4.14/0002-add-realtek-targets.patch new file mode 100644 index 0000000000000..8852b5a16f0d7 --- /dev/null +++ b/target/linux/realtek/patches-4.14/0002-add-realtek-targets.patch @@ -0,0 +1,58 @@ +Index: linux-4.14.131/arch/mips/Kbuild.platforms +=================================================================== +--- linux-4.14.131.orig/arch/mips/Kbuild.platforms ++++ linux-4.14.131/arch/mips/Kbuild.platforms +@@ -27,6 +27,7 @@ platforms += pmcs-msp71xx + platforms += pnx833x + platforms += ralink + platforms += rb532 ++platforms += realtek + platforms += sgi-ip22 + platforms += sgi-ip27 + platforms += sgi-ip32 +Index: linux-4.14.131/arch/mips/Kconfig +=================================================================== +--- linux-4.14.131.orig/arch/mips/Kconfig ++++ linux-4.14.131/arch/mips/Kconfig +@@ -630,6 +630,21 @@ config RALINK + select ARCH_HAS_RESET_CONTROLLER + select RESET_CONTROLLER + ++config REALTEK ++ bool "Realtek RLX based SoC support" ++ select BOOT_RAW ++ select DMA_NONCOHERENT ++ select IRQ_MIPS_CPU ++ select USE_OF ++ select SYS_SUPPORTS_MIPS16 ++ select SYS_SUPPORTS_32BIT_KERNEL ++ select SYS_HAS_EARLY_PRINTK ++ select COMMON_CLK ++ select TIMER_OF ++ select CLKSRC_MMIO ++ help ++ Support for Realtek RLX SoC based boards ++ + config SGI_IP22 + bool "SGI IP22 (Indy/Indigo2)" + select FW_ARC +@@ -1032,6 +1048,7 @@ source "arch/mips/pic32/Kconfig" + source "arch/mips/pistachio/Kconfig" + source "arch/mips/pmcs-msp71xx/Kconfig" + source "arch/mips/ralink/Kconfig" ++source "arch/mips/realtek/Kconfig" + source "arch/mips/sgi-ip27/Kconfig" + source "arch/mips/sibyte/Kconfig" + source "arch/mips/txx9/Kconfig" +Index: linux-4.14.131/arch/mips/boot/dts/Makefile +=================================================================== +--- linux-4.14.131.orig/arch/mips/boot/dts/Makefile ++++ linux-4.14.131/arch/mips/boot/dts/Makefile +@@ -10,6 +10,7 @@ dts-dirs += ni + dts-dirs += pic32 + dts-dirs += qca + dts-dirs += ralink ++dts-dirs += realtek + dts-dirs += xilfpga + + obj-y := $(addsuffix /, $(dts-dirs)) diff --git a/target/linux/realtek/patches-4.14/0003-spi-drivers.patch b/target/linux/realtek/patches-4.14/0003-spi-drivers.patch new file mode 100644 index 0000000000000..8275b4d5ad883 --- /dev/null +++ b/target/linux/realtek/patches-4.14/0003-spi-drivers.patch @@ -0,0 +1,38 @@ +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -527,6 +527,11 @@ + config SPI_PXA2XX_PCI + def_tristate SPI_PXA2XX && PCI && COMMON_CLK + ++config SPI_REALTEK ++ tristate "Realtek RTL819x SPI controller driver" ++ help ++ This selects a driver for Realtek RTL8196E and RTL8197D SoC ++ + config SPI_ROCKCHIP + tristate "Rockchip SPI controller driver" + help +@@ -619,6 +624,11 @@ + help + SPI driver for SuperH HSPI blocks. + ++config SPI_SHEIPA ++ tristate "Sheipa SPI controller" ++ help ++ SPI driver for Sheipa Controller ++ + config SPI_SIRF + tristate "CSR SiRFprimaII SPI controller" + depends on SIRF_DMA +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -109,6 +109,9 @@ + obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o + obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o + ++obj-$(CONFIG_SPI_REALTEK) += spi-realtek.o ++obj-$(CONFIG_SPI_SHEIPA) += spi-sheipa.o ++ + # SPI slave protocol handlers + obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o + obj-$(CONFIG_SPI_SLAVE_SYSTEM_CONTROL) += spi-slave-system-control.o \ No newline at end of file diff --git a/target/linux/realtek/patches-4.14/0004-rtl8197f-dw-uart.patch b/target/linux/realtek/patches-4.14/0004-rtl8197f-dw-uart.patch new file mode 100644 index 0000000000000..c22c53478461e --- /dev/null +++ b/target/linux/realtek/patches-4.14/0004-rtl8197f-dw-uart.patch @@ -0,0 +1,129 @@ +--- linux-4.14.131.orig/drivers/tty/serial/8250/8250_dw.c ++++ linux-4.14.131/drivers/tty/serial/8250/8250_dw.c +@@ -58,6 +58,8 @@ + + struct dw8250_data { + u8 usr_reg; ++ u8 tx_reg; ++ u8 rx_reg; + int line; + int msr_mask_on; + int msr_mask_off; +@@ -68,6 +70,7 @@ + + unsigned int skip_autocfg:1; + unsigned int uart_16550_compatible:1; ++ unsigned int adjlcr:1; + }; + + static inline int dw8250_modify_msr(struct uart_port *p, int offset, int value) +@@ -95,6 +98,13 @@ + { + void __iomem *offset = p->membase + (UART_LCR << p->regshift); + int tries = 1000; ++ struct dw8250_data *d = p->private_data; ++ ++ if(d->adjlcr) ++ { ++ if(value == UART_LCR_WLEN7 || value == UART_LCR_WLEN8) ++ value -= 2; ++ } + + /* Make sure LCR write wasn't ignored */ + while (tries--) { +@@ -123,10 +133,21 @@ + */ + } + ++static int dw_change_offset(struct uart_port *p, int offset) ++{ ++ struct dw8250_data *d = p->private_data; ++ if(offset == UART_TX) ++ return d->tx_reg; ++ if(offset == UART_RX) ++ return d->rx_reg; ++ return offset; ++} ++ + static void dw8250_serial_out(struct uart_port *p, int offset, int value) + { + struct dw8250_data *d = p->private_data; + ++ offset = dw_change_offset(p, offset); + writeb(value, p->membase + (offset << p->regshift)); + + if (offset == UART_LCR && !d->uart_16550_compatible) +@@ -135,6 +156,7 @@ + + static unsigned int dw8250_serial_in(struct uart_port *p, int offset) + { ++ offset = dw_change_offset(p, offset); + unsigned int value = readb(p->membase + (offset << p->regshift)); + + return dw8250_modify_msr(p, offset, value); +@@ -168,6 +190,7 @@ + { + struct dw8250_data *d = p->private_data; + ++ offset = dw_change_offset(p, offset); + writel(value, p->membase + (offset << p->regshift)); + + if (offset == UART_LCR && !d->uart_16550_compatible) +@@ -176,6 +199,7 @@ + + static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) + { ++ offset = dw_change_offset(p, offset); + unsigned int value = readl(p->membase + (offset << p->regshift)); + + return dw8250_modify_msr(p, offset, value); +@@ -185,6 +209,7 @@ + { + struct dw8250_data *d = p->private_data; + ++ offset = dw_change_offset(p, offset); + iowrite32be(value, p->membase + (offset << p->regshift)); + + if (offset == UART_LCR && !d->uart_16550_compatible) +@@ -193,6 +218,7 @@ + + static unsigned int dw8250_serial_in32be(struct uart_port *p, int offset) + { ++ offset = dw_change_offset(p, offset); + unsigned int value = ioread32be(p->membase + (offset << p->regshift)); + + return dw8250_modify_msr(p, offset, value); +@@ -338,6 +364,15 @@ + data->skip_autocfg = true; + } + #endif ++ if (of_device_is_compatible(np, "realtek,rtl8197f-uart")) { ++ p->type = PORT_16550A; ++ p->flags = UPF_SKIP_TEST| UPF_FIXED_TYPE; ++ data->tx_reg = 9; ++ data->rx_reg = 9; ++ data->adjlcr=true; ++ data->skip_autocfg = true; ++ } ++ + if (of_device_is_big_endian(p->dev->of_node)) { + p->iotype = UPIO_MEM32BE; + p->serial_in = dw8250_serial_in32be; +@@ -452,6 +487,9 @@ + + data->dma.fn = dw8250_fallback_dma_filter; + data->usr_reg = DW_UART_USR; ++ data->tx_reg = UART_TX; ++ data->rx_reg = UART_RX; ++ data->adjlcr=false; + p->private_data = data; + + data->uart_16550_compatible = device_property_read_bool(dev, +@@ -658,6 +696,7 @@ + static const struct of_device_id dw8250_of_match[] = { + { .compatible = "snps,dw-apb-uart" }, + { .compatible = "cavium,octeon-3860-uart" }, ++ { .compatible = "realtek,rtl8197f-uart" }, + { /* Sentinel */ } + }; + MODULE_DEVICE_TABLE(of, dw8250_of_match); diff --git a/target/linux/realtek/patches-4.14/0005-pci-realtek.patch b/target/linux/realtek/patches-4.14/0005-pci-realtek.patch new file mode 100644 index 0000000000000..020d4ce5aaede --- /dev/null +++ b/target/linux/realtek/patches-4.14/0005-pci-realtek.patch @@ -0,0 +1,10 @@ +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -49,6 +49,7 @@ + obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o + obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o + obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o ++obj-$(CONFIG_REALTEK) += pci-realtek.o + obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o + obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o + obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o diff --git a/target/linux/realtek/rtl8196e/config-4.14 b/target/linux/realtek/rtl8196e/config-4.14 new file mode 100644 index 0000000000000..e60fcfa070760 --- /dev/null +++ b/target/linux/realtek/rtl8196e/config-4.14 @@ -0,0 +1,252 @@ +# CONFIG_AIO is not set +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set +# CONFIG_ARCH_HAS_SG_CHAIN is not set +# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set +# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_ARCH_MMAP_RND_BITS_MAX=15 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_BLK_MQ_PCI=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_NONE is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +# CONFIG_CGROUPS is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +# CONFIG_COMMON_CLK_BOSTON is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_RLX=y +CONFIG_CPU_RLX4181=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CRC_CCITT=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DTB_RTK_NONE=y +# CONFIG_DTB_RTL8196E_GEN is not set +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_8250=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_SYSFS=y +# CONFIG_GRO_CELLS is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +# CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_HAVE_ARCH_COMPILER_H=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_HAVE_CBPF_JIT=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DEBUG_STACKOVERFLOW=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HW_HAS_PCI=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_HZ_PERIODIC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPV6=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_PIMSM_V2 is not set +CONFIG_IPV6_SUBTREES=y +CONFIG_IP_MROUTE=y +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +# CONFIG_MDIO_BUS is not set +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=6 +CONFIG_MIPS_ASID_SHIFT=6 +CONFIG_MIPS_CBPF_JIT=y +# CONFIG_MIPS_CLOCK_VSYSCALL is not set +# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +# CONFIG_MIPS_ELF_APPENDED_DTB is not set +# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_MIPS_MACHINE is not set +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_RTCACHE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_LOG_COMMON=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_LOG_IPV6=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_REDIRECT=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +# CONFIG_NO_IOPORT_MAP is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_ADDRESS_PCI=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PRINTK_TIME=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +# CONFIG_RCU_NEED_SEGCBLIST is not set +# CONFIG_RCU_STALL_COMMON is not set +CONFIG_REALTEK=y +# CONFIG_SCHED_INFO is not set +# CONFIG_SCSI_DMA is not set +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_FSL is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SLHC=m +CONFIG_SOC_RTL8196E=y +# CONFIG_SOC_RTL8197D is not set +# CONFIG_SOC_RTL8197F is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_REALTEK=y +# CONFIG_SPI_SHEIPA is not set +CONFIG_SRCU=y +# CONFIG_SWAP is not set +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYS_HAS_CPU_RLX4181=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y +CONFIG_USE_OF=y diff --git a/target/linux/realtek/rtl8196e/profiles/00-Default.mk b/target/linux/realtek/rtl8196e/profiles/00-Default.mk new file mode 100644 index 0000000000000..300f714b5755c --- /dev/null +++ b/target/linux/realtek/rtl8196e/profiles/00-Default.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Default + NAME:=Generic RTL8196E without WiFi + PACKAGES:=-wpad-mini +endef + +define Profile/Default/Description + Realtek RTL8196E SOC +endef + +$(eval $(call Profile,Default)) diff --git a/target/linux/realtek/rtl8196e/target.mk b/target/linux/realtek/rtl8196e/target.mk new file mode 100644 index 0000000000000..8650f3f678f91 --- /dev/null +++ b/target/linux/realtek/rtl8196e/target.mk @@ -0,0 +1,15 @@ +# +# Copyright (C) 2019 OpenWrt.org +# + +SUBTARGET:=rtl8196e +BOARDNAME:=RTL8196e based boards +ARCH_PACKAGES:=realtek_lx43 +CPU_TYPE:=lx43 +KERNEL_PATCHVER:=4.14 + +define Target/Description + Build firmware images for Realtek RTL8196E based boards. +endef + + diff --git a/target/linux/realtek/rtl8197d/config-4.14 b/target/linux/realtek/rtl8197d/config-4.14 new file mode 100644 index 0000000000000..75cb436a0c245 --- /dev/null +++ b/target/linux/realtek/rtl8197d/config-4.14 @@ -0,0 +1,241 @@ +# CONFIG_AIO is not set +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set +# CONFIG_ARCH_HAS_SG_CHAIN is not set +# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set +# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_ARCH_MMAP_RND_BITS_MAX=15 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_NONE is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +# CONFIG_COMMON_CLK_BOSTON is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_RLX=y +CONFIG_CPU_RLX5281=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CRC_CCITT=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DTB_RTK_NONE=y +# CONFIG_DTB_RTL8197D_GEN is not set +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_8250=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +# CONFIG_GRO_CELLS is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +# CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_HAVE_ARCH_COMPILER_H=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_HAVE_CBPF_JIT=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DEBUG_STACKOVERFLOW=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_HZ_PERIODIC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPV6=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_PIMSM_V2 is not set +CONFIG_IPV6_SUBTREES=y +CONFIG_IP_MROUTE=y +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +# CONFIG_MDIO_BUS is not set +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=6 +CONFIG_MIPS_ASID_SHIFT=6 +# CONFIG_MIPS_CLOCK_VSYSCALL is not set +# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +# CONFIG_MIPS_ELF_APPENDED_DTB is not set +# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_MIPS_MACHINE is not set +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPLIT_CVIMG_FW=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_RTCACHE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_LOG_COMMON=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_LOG_IPV6=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_REDIRECT=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +# CONFIG_NO_IOPORT_MAP is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PRINTK_TIME=y +CONFIG_RATIONAL=y +# CONFIG_RCU_NEED_SEGCBLIST is not set +# CONFIG_RCU_STALL_COMMON is not set +CONFIG_REALTEK=y +# CONFIG_SCHED_INFO is not set +# CONFIG_SCSI_DMA is not set +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_FSL is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SLHC=m +# CONFIG_SOC_RTL8196E is not set +CONFIG_SOC_RTL8197D=y +# CONFIG_SOC_RTL8197F is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_REALTEK=y +# CONFIG_SPI_SHEIPA is not set +CONFIG_SRCU=y +# CONFIG_SWAP is not set +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYS_HAS_CPU_RLX5281=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y +CONFIG_USE_OF=y diff --git a/target/linux/realtek/rtl8197d/profiles/00-Default.mk b/target/linux/realtek/rtl8197d/profiles/00-Default.mk new file mode 100644 index 0000000000000..7ca7b4ac70a33 --- /dev/null +++ b/target/linux/realtek/rtl8197d/profiles/00-Default.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Default + NAME:=Generic RTL8197D + PACKAGES:=-wpad-mini +endef + +define Profile/Default/Description + Realtek RTL8197D SOC +endef + +$(eval $(call Profile,Default)) diff --git a/target/linux/realtek/rtl8197d/target.mk b/target/linux/realtek/rtl8197d/target.mk new file mode 100644 index 0000000000000..cc8a73bac7564 --- /dev/null +++ b/target/linux/realtek/rtl8197d/target.mk @@ -0,0 +1,15 @@ +# +# Copyright (C) 2019 OpenWrt.org +# + +SUBTARGET:=rtl8197d +BOARDNAME:=RTL8197d based boards +ARCH_PACKAGES:=realtek_lx53 +CPU_TYPE:=lx53 +KERNEL_PATCHVER:=4.14 + +define Target/Description + Build firmware images for Realtek RTL8197D based boards. +endef + + diff --git a/target/linux/realtek/rtl8197f/config-4.14 b/target/linux/realtek/rtl8197f/config-4.14 new file mode 100644 index 0000000000000..b8226e7796467 --- /dev/null +++ b/target/linux/realtek/rtl8197f/config-4.14 @@ -0,0 +1,265 @@ +# CONFIG_AIO is not set +CONFIG_ARCH_BINFMT_ELF_STATE=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set +# CONFIG_ARCH_HAS_SG_CHAIN is not set +# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set +# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_ARCH_MMAP_RND_BITS_MAX=15 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set +# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_ARCH_USE_QUEUED_RWLOCKS=y +CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_NONE is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_CEVT_R4K=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_COMMON_CLK=y +# CONFIG_COMMON_CLK_BOSTON is not set +CONFIG_CPU_GENERIC_DUMP_TLB=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_RIXI=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_R4K_FPU=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRC_CCITT=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DTB_RTK_NONE=y +# CONFIG_DTB_RTL8197F_GEN is not set +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_FIXED_PHY=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_IO=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_SYSFS=y +# CONFIG_GRO_CELLS is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +# CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_HAVE_ARCH_COMPILER_H=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_HAVE_CBPF_JIT=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_COPY_THREAD_TLS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_HAVE_DEBUG_STACKOVERFLOW=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_MOD_ARCH_SPECIFIC=y +CONFIG_HAVE_NET_DSA=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_HZ_PERIODIC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPV6=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_PIMSM_V2 is not set +CONFIG_IPV6_SUBTREES=y +CONFIG_IP_MROUTE=y +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LED_TRIGGER_PHY=y +CONFIG_LIBFDT=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +# CONFIG_MIPS_ELF_APPENDED_DTB is not set +# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_MIPS_MACHINE is not set +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MIPS_SPRAM=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_SPLIT_CVIMG_FW=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_RTCACHE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_LOG_COMMON=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_LOG_IPV6=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_REDIRECT=m +CONFIG_NF_REJECT_IPV4=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +# CONFIG_NO_IOPORT_MAP is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PRINTK_TIME=y +CONFIG_RATIONAL=y +# CONFIG_RCU_NEED_SEGCBLIST is not set +# CONFIG_RCU_STALL_COMMON is not set +CONFIG_REALTEK=y +# CONFIG_RTL8367S_GSW is not set +# CONFIG_SCHED_INFO is not set +# CONFIG_SCSI_DMA is not set +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_FSL is not set +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SLHC=m +# CONFIG_SOC_RTL8196E is not set +# CONFIG_SOC_RTL8197D is not set +CONFIG_SOC_RTL8197F=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +# CONFIG_SPI_REALTEK is not set +CONFIG_SPI_SHEIPA=y +CONFIG_SRCU=y +# CONFIG_SWAP is not set +CONFIG_SWCONFIG=y +CONFIG_SWCONFIG_LEDS=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_USE_OF=y diff --git a/target/linux/realtek/rtl8197f/profiles/00-Default.mk b/target/linux/realtek/rtl8197f/profiles/00-Default.mk new file mode 100644 index 0000000000000..ec25a60d5e84c --- /dev/null +++ b/target/linux/realtek/rtl8197f/profiles/00-Default.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Default + NAME:=Generic RTL8197F + PACKAGES:=-wpad-mini +endef + +define Profile/Default/Description + Realtek RTL8197F SOC +endef + +$(eval $(call Profile,Default)) diff --git a/target/linux/realtek/rtl8197f/target.mk b/target/linux/realtek/rtl8197f/target.mk new file mode 100644 index 0000000000000..cc3e6ad46b4b1 --- /dev/null +++ b/target/linux/realtek/rtl8197f/target.mk @@ -0,0 +1,15 @@ +# +# Copyright (C) 2019 OpenWrt.org +# + +ARCH:=mipsel +SUBTARGET:=rtl8197f +BOARDNAME:=RTL8197f based boards +CPU_TYPE:=24kc +KERNEL_PATCHVER:=4.14 + +define Target/Description + Build firmware images for Realtek RTL8197F based boards. +endef + +