mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-18 17:33:31 +00:00
switch ramips to kernel 4.14
This commit is contained in:
parent
033411d5f4
commit
accfddd339
@ -13,7 +13,7 @@ SUBTARGETS:=mt7620 mt7621 mt76x8 rt288x rt305x rt3883
|
||||
FEATURES:=squashfs gpio
|
||||
MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
KERNEL_PATCHVER:=4.9
|
||||
KERNEL_PATCHVER:=4.14
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Ralink RT288x/RT3xxx based boards.
|
||||
|
@ -60,6 +60,9 @@ alfa-network,ac1200rm)
|
||||
set_wifi_led "$boardname:green:wlan2g" "wlan1"
|
||||
ucidef_set_led_default "wps" "wps" "$boardname:green:wps" "0"
|
||||
;;
|
||||
alfa-network,awusfree1)
|
||||
set_wifi_led "$boardname:blue:wlan"
|
||||
;;
|
||||
all0256n-4M|\
|
||||
all0256n-8M)
|
||||
ucidef_set_rssimon "wlan0" "200000" "1"
|
||||
@ -91,12 +94,6 @@ c108)
|
||||
ucidef_set_led_netdev "lan" "lan" "$boardname:green:lan" "eth0"
|
||||
ucidef_set_led_netdev "modem" "modem" "$boardname:green:modem" "wwan0"
|
||||
;;
|
||||
c20)
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:blue:lan" "switch0" "0x1e"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:blue:wan" "switch0" "0x01"
|
||||
set_usb_led "$boardname:blue:usb"
|
||||
ucidef_set_led_netdev "wlan2g" "wlan2g" "$boardname:blue:wlan2g" "wlan0"
|
||||
;;
|
||||
c20i)
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:blue:lan" "switch0" "0x1e"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:blue:wan" "switch0" "0x01"
|
||||
@ -161,9 +158,15 @@ dir-615-h1)
|
||||
set_wifi_led "rt2800pci-phy0::radio"
|
||||
;;
|
||||
dir-620-d1|\
|
||||
dlink,dwr-116-a1|\
|
||||
mzk-ex300np)
|
||||
set_wifi_led "$boardname:green:wifi"
|
||||
;;
|
||||
dlink,dwr-921-c1)
|
||||
set_wifi_led "$boardname:green:wifi"
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x0f"
|
||||
ucidef_set_led_default "sigstrength" "Signal Strength" "$boardname:green:sigstrength" "0"
|
||||
;;
|
||||
dir-810l|\
|
||||
mzk-750dhp|\
|
||||
mzk-dp150n|\
|
||||
@ -193,7 +196,8 @@ fonera20n)
|
||||
set_usb_led "$boardname:orange:usb"
|
||||
set_wifi_led "$boardname:orange:wifi"
|
||||
;;
|
||||
gb-pc1)
|
||||
gb-pc1|\
|
||||
gnubee,gb-pc2)
|
||||
ucidef_set_led_switch "lan1" "lan1" "$boardname:green:lan1" "switch0" "0x01"
|
||||
ucidef_set_led_switch "lan2" "lan2" "$boardname:green:lan2" "switch0" "0x10"
|
||||
;;
|
||||
@ -367,6 +371,10 @@ rt-n14u)
|
||||
set_wifi_led "$boardname:blue:air"
|
||||
set_usb_led "$boardname:blue:usb"
|
||||
;;
|
||||
tama,w06)
|
||||
ucidef_set_led_netdev "wan" "WAN" "$boardname:green:wan" "eth0"
|
||||
ucidef_set_led_wlan "wlan" "WLAN" "$boardname:green:wlan" "phy0tpt"
|
||||
;;
|
||||
tew-714tru)
|
||||
set_usb_led "$boardname:red:usb"
|
||||
set_wifi_led "$boardname:green:wifi"
|
||||
@ -388,12 +396,34 @@ tl-wr841n-v13)
|
||||
ucidef_set_led_switch "lan4" "lan4" "$boardname:green:lan4" "switch0" "0x10"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x01"
|
||||
;;
|
||||
tplink,c20-v1)
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:blue:lan" "switch0" "0x1e"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:blue:wan" "switch0" "0x01"
|
||||
set_usb_led "$boardname:blue:usb"
|
||||
ucidef_set_led_netdev "wlan2g" "wlan2g" "$boardname:blue:wlan2g" "wlan0"
|
||||
;;
|
||||
tplink,c20-v4)
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x1e"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x01"
|
||||
ucidef_set_led_netdev "wlan2g" "wlan2g" "$boardname:green:wlan2g" "wlan0"
|
||||
;;
|
||||
tplink,c50-v3)
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x1e"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x01"
|
||||
ucidef_set_led_netdev "wlan2g" "wlan2g" "$boardname:green:wlan2g" "wlan1"
|
||||
set_wifi_led "$boardname:green:wlan5g"
|
||||
;;
|
||||
tplink,tl-mr3420-v5)
|
||||
set_usb_led "$boardname:green:usb"
|
||||
set_wifi_led "$boardname:green:wlan"
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x1e"
|
||||
ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x01"
|
||||
;;
|
||||
tplink,tl-wr902ac-v3)
|
||||
set_usb_led "$boardname:green:usb"
|
||||
ucidef_set_led_netdev "wlan2g" "wlan2g" "$boardname:green:wlan" "wlan0"
|
||||
ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x10"
|
||||
;;
|
||||
u25awf-h1)
|
||||
set_wifi_led "u25awf:red:wifi"
|
||||
ucidef_set_led_netdev "eth" "eth" "u25awf:green:lan" "eth0"
|
||||
@ -486,6 +516,12 @@ zbt-we826-32M)
|
||||
set_wifi_led "zbt-we826:green:wifi"
|
||||
set_usb_led "zbt-we826:green:usb"
|
||||
;;
|
||||
zbtlink,zbt-we1226)
|
||||
set_wifi_led "$boardname:green:wlan"
|
||||
ucidef_set_led_switch "lan1" "LAN1" "$boardname:green:lan1" "switch0" "0x01"
|
||||
ucidef_set_led_switch "lan2" "LAN2" "$boardname:green:lan2" "switch0" "0x02"
|
||||
ucidef_set_led_switch "wan" "WAN" "$boardname:green:wan" "switch0" "0x10"
|
||||
;;
|
||||
zbt-wr8305rt)
|
||||
ucidef_set_led_default "power" "power" "$boardname:green:sys" "1"
|
||||
set_usb_led "$boardname:green:usb"
|
||||
|
@ -57,7 +57,8 @@ ramips_setup_interfaces()
|
||||
omega2p | \
|
||||
timecloud|\
|
||||
w150m|\
|
||||
widora-neo|\
|
||||
widora,neo-16m|\
|
||||
widora,neo-32m|\
|
||||
wnce2001|\
|
||||
zbt-cpe102|\
|
||||
zte-q7)
|
||||
@ -72,12 +73,15 @@ ramips_setup_interfaces()
|
||||
3g-6200n|\
|
||||
ai-br100|\
|
||||
alfa-network,ac1200rm|\
|
||||
mediatek,ap-mt7621a-v60|\
|
||||
d240|\
|
||||
db-wrt01|\
|
||||
dir-300-b7|\
|
||||
dir-320-b1|\
|
||||
dir-610-a1|\
|
||||
dir-615-h1|\
|
||||
dlink,dwr-116-a1|\
|
||||
dlink,dwr-921-c1|\
|
||||
ew1200|\
|
||||
firewrt|\
|
||||
hc5661a|\
|
||||
@ -107,11 +111,10 @@ ramips_setup_interfaces()
|
||||
u7621-06-256M-16M|\
|
||||
vr500|\
|
||||
wf-2881|\
|
||||
whr-g300n|\
|
||||
witi|\
|
||||
wl-wn575a3|\
|
||||
wndr3700v5|\
|
||||
wt1520-4M|\
|
||||
wt1520-8M|\
|
||||
youku-yk1|\
|
||||
zbt-ape522ii|\
|
||||
zbt-we1326|\
|
||||
@ -125,6 +128,27 @@ ramips_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0"
|
||||
;;
|
||||
alfa-network,awusfree1|\
|
||||
cs-qr10|\
|
||||
d105|\
|
||||
dlink,dap-1522-a1|\
|
||||
dch-m225|\
|
||||
ex2700|\
|
||||
ex3700|\
|
||||
hpm|\
|
||||
mzk-ex300np|\
|
||||
mzk-ex750np|\
|
||||
na930|\
|
||||
pbr-d1|\
|
||||
tama,w06|\
|
||||
u25awf-h1|\
|
||||
wli-tx4-ag300n|\
|
||||
wmdr-143n|\
|
||||
wmr-300|\
|
||||
wn3000rpv3|\
|
||||
wrh-300cr)
|
||||
ucidef_set_interface_lan "eth0"
|
||||
;;
|
||||
mir3g)
|
||||
ucidef_add_switch "switch0" \
|
||||
"2:lan:2" "3:lan:1" "1:wan" "6t@eth0"
|
||||
@ -173,6 +197,8 @@ ramips_setup_interfaces()
|
||||
mzk-wdpr|\
|
||||
rb750gr3|\
|
||||
rt-n14u|\
|
||||
tplink,c20-v4|\
|
||||
tplink,c50-v3|\
|
||||
tplink,tl-mr3420-v5|\
|
||||
tl-wr840n-v4|\
|
||||
tl-wr840n-v5|\
|
||||
@ -184,14 +210,12 @@ ramips_setup_interfaces()
|
||||
wrtnode|\
|
||||
wrtnode2p | \
|
||||
wrtnode2r | \
|
||||
wt3020-4M|\
|
||||
wt3020-8M|\
|
||||
zbt-wa05)
|
||||
ucidef_add_switch "switch0" \
|
||||
"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
|
||||
;;
|
||||
c20|\
|
||||
c50)
|
||||
c50|\
|
||||
tplink,c20-v1)
|
||||
ucidef_add_switch "switch0" \
|
||||
"1:lan:3" "2:lan:4" "3:lan:1" "4:lan:2" "0:wan" "6@eth0"
|
||||
;;
|
||||
@ -199,7 +223,8 @@ ramips_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "0:wan" "6@eth0"
|
||||
;;
|
||||
gb-pc1)
|
||||
gb-pc1|\
|
||||
gnubee,gb-pc2)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan" "4:lan" "6@eth0"
|
||||
;;
|
||||
@ -233,24 +258,6 @@ ramips_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "9@eth0"
|
||||
;;
|
||||
cs-qr10|\
|
||||
d105|\
|
||||
dch-m225|\
|
||||
ex2700|\
|
||||
ex3700|\
|
||||
hpm|\
|
||||
mzk-ex300np|\
|
||||
mzk-ex750np|\
|
||||
na930|\
|
||||
pbr-d1|\
|
||||
u25awf-h1|\
|
||||
wli-tx4-ag300n|\
|
||||
wmdr-143n|\
|
||||
wmr-300|\
|
||||
wn3000rpv3|\
|
||||
wrh-300cr)
|
||||
ucidef_set_interface_lan "eth0"
|
||||
;;
|
||||
duzun-dm06)
|
||||
ucidef_add_switch "switch0" \
|
||||
"1:lan" "0:wan" "6@eth0"
|
||||
@ -315,7 +322,13 @@ ramips_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0@eth0"
|
||||
;;
|
||||
vonets,var11n-300)
|
||||
tplink,tl-wr902ac-v3)
|
||||
ucidef_add_switch "switch0" \
|
||||
"4:lan" "6@eth0"
|
||||
;;
|
||||
vonets,var11n-300|\
|
||||
wt1520-4M|\
|
||||
wt1520-8M)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan" "4:wan" "6@eth0"
|
||||
;;
|
||||
@ -348,6 +361,12 @@ ramips_setup_interfaces()
|
||||
ucidef_add_switch "switch0" \
|
||||
"1:lan" "2:lan" "0:wan" "6@eth0"
|
||||
;;
|
||||
wt3020-4M|\
|
||||
wt3020-8M)
|
||||
ucidef_add_switch "switch0" \
|
||||
"4:lan" "0:wan" "6@eth0"
|
||||
;;
|
||||
zbtlink,zbt-we1226|\
|
||||
y1)
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan:2" "1:lan:1" "4:wan" "6@eth0"
|
||||
@ -416,10 +435,16 @@ ramips_setup_macs()
|
||||
lan_mac=$(mtd_get_mac_ascii factory lanmac)
|
||||
wan_mac=$(mtd_get_mac_ascii factory wanmac)
|
||||
;;
|
||||
dlink,dwr-116-a1|\
|
||||
dlink,dwr-921-c1)
|
||||
wan_mac=$(jboot_config_read -m -i $(find_mtd_part "config") -o 0xE000)
|
||||
lan_mac=$(macaddr_add "$wan_mac" 1)
|
||||
;;
|
||||
e1700)
|
||||
wan_mac=$(mtd_get_mac_ascii config WAN_MAC_ADDR)
|
||||
;;
|
||||
gl-mt300n-v2)
|
||||
gl-mt300n-v2|\
|
||||
whr-g300n)
|
||||
wan_mac=$(mtd_get_mac_binary factory 4)
|
||||
;;
|
||||
hc5*61|\
|
||||
|
@ -38,7 +38,10 @@ get_status_led() {
|
||||
nbg-419n2|\
|
||||
pwh2004|\
|
||||
r6220|\
|
||||
tplink,c20-v4|\
|
||||
tplink,c50-v3|\
|
||||
tplink,tl-mr3420-v5|\
|
||||
tplink,tl-wr902ac-v3|\
|
||||
tl-wr840n-v4|\
|
||||
tl-wr840n-v5|\
|
||||
tl-wr841n-v13|\
|
||||
@ -76,6 +79,9 @@ get_status_led() {
|
||||
wrh-300cr)
|
||||
status_led="$boardname:green:wps"
|
||||
;;
|
||||
alfa-network,awusfree1)
|
||||
status_led="$boardname:orange:system"
|
||||
;;
|
||||
all0239-3g|\
|
||||
dcs-930|\
|
||||
dir-300-b1|\
|
||||
@ -88,7 +94,9 @@ get_status_led() {
|
||||
dir-620-a1|\
|
||||
dir-620-d1|\
|
||||
dwr-512-b|\
|
||||
dlink,dwr-116-a1|\
|
||||
gb-pc1|\
|
||||
gnubee,gb-pc2|\
|
||||
hpm|\
|
||||
hw550-3g|\
|
||||
mac1200rv2|\
|
||||
@ -100,6 +108,9 @@ get_status_led() {
|
||||
zbt-wg2626)
|
||||
status_led="$boardname:green:status"
|
||||
;;
|
||||
dlink,dwr-921-c1)
|
||||
status_led="$boardname:green:sigstrength"
|
||||
;;
|
||||
asl26555-8M|\
|
||||
asl26555-16M)
|
||||
status_led="asl26555:green:power"
|
||||
@ -124,7 +135,6 @@ get_status_led() {
|
||||
w502u)
|
||||
status_led="$boardname:blue:wps"
|
||||
;;
|
||||
c20|\
|
||||
d240|\
|
||||
dap-1350|\
|
||||
na930|\
|
||||
@ -136,6 +146,7 @@ get_status_led() {
|
||||
rt-n14u|\
|
||||
rt-n15|\
|
||||
rt-n56u|\
|
||||
tplink,c20-v1|\
|
||||
wl-330n|\
|
||||
wl-330n3g|\
|
||||
wli-tx4-ag300n|\
|
||||
@ -144,6 +155,13 @@ get_status_led() {
|
||||
youku-yk1)
|
||||
status_led="$boardname:blue:power"
|
||||
;;
|
||||
dlink,dap-1522-a1|\
|
||||
k2p|\
|
||||
m3|\
|
||||
mir3g|\
|
||||
miwifi-nano)
|
||||
status_led="$boardname:blue:status"
|
||||
;;
|
||||
db-wrt01|\
|
||||
esr-9753|\
|
||||
pbr-d1)
|
||||
@ -171,11 +189,6 @@ get_status_led() {
|
||||
hc5962)
|
||||
status_led="$boardname:white:status"
|
||||
;;
|
||||
k2p|\
|
||||
m3|\
|
||||
miwifi-nano)
|
||||
status_led="$boardname:blue:status"
|
||||
;;
|
||||
linkits7688)
|
||||
status_led="linkit-smart-7688:orange:wifi"
|
||||
;;
|
||||
@ -183,15 +196,12 @@ get_status_led() {
|
||||
status_led="$boardname:blue:wifi"
|
||||
;;
|
||||
gl-mt300n-v2)
|
||||
status_led="$boardname:red:wlan"
|
||||
status_led="$boardname:green:power"
|
||||
;;
|
||||
m4-4M|\
|
||||
m4-8M)
|
||||
status_led="m4:blue:status"
|
||||
;;
|
||||
mir3g)
|
||||
status_led="$boardname:yellow:status"
|
||||
;;
|
||||
miwifi-mini|\
|
||||
zte-q7)
|
||||
status_led="$boardname:red:status"
|
||||
@ -286,7 +296,8 @@ get_status_led() {
|
||||
zbt-we2026)
|
||||
status_led="$boardname:red:power"
|
||||
;;
|
||||
widora-neo)
|
||||
widora,neo-16m|\
|
||||
widora,neo-32m)
|
||||
status_led="widora:orange:wifi"
|
||||
;;
|
||||
wzr-agl300nh)
|
||||
@ -315,6 +326,9 @@ get_status_led() {
|
||||
zbt-we826-32M)
|
||||
status_led="zbt-we826:green:power"
|
||||
;;
|
||||
zbtlink,zbt-we1226)
|
||||
status_led="$boardname:green:wlan"
|
||||
;;
|
||||
zbt-wg3526-16M|\
|
||||
zbt-wg3526-32M)
|
||||
status_led="zbt-wg3526:green:status"
|
||||
|
@ -19,6 +19,19 @@ rt2x00_eeprom_extract() {
|
||||
rt2x00_eeprom_die "failed to extract from $mtd"
|
||||
}
|
||||
|
||||
jboot_eeprom_extract() {
|
||||
local part=$1
|
||||
local offset=$2
|
||||
local mtd
|
||||
|
||||
mtd=$(find_mtd_part $part)
|
||||
[ -n "$mtd" ] || \
|
||||
rt2x00_eeprom_die "no mtd device found for partition $part"
|
||||
|
||||
jboot_config_read -i $mtd -o $offset -e /lib/firmware/$FIRMWARE 2>/dev/null || \
|
||||
rt2x00_eeprom_die "failed to extract from $mtd"
|
||||
}
|
||||
|
||||
rt2x00_eeprom_set_macaddr() {
|
||||
local macaddr=$1
|
||||
|
||||
@ -41,6 +54,13 @@ board=$(board_name)
|
||||
case "$FIRMWARE" in
|
||||
"soc_wmac.eeprom")
|
||||
case $board in
|
||||
dlink,dwr-116-a1|\
|
||||
dlink,dwr-921-c1)
|
||||
wan_mac=$(jboot_config_read -m -i $(find_mtd_part "config") -o 0xE000)
|
||||
wifi_mac=$(macaddr_add "$wan_mac" 1)
|
||||
jboot_eeprom_extract "config" 0xE000
|
||||
rt2x00_eeprom_set_macaddr $wifi_mac
|
||||
;;
|
||||
tiny-ac)
|
||||
wifi_mac=$(mtd_get_mac_ascii u-boot-env INIC_MAC_ADDR)
|
||||
rt2x00_eeprom_extract "factory" 0 512
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
fix_seama_header() {
|
||||
fix_checksum() {
|
||||
local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"kernel".*/\1/p' /proc/mtd)
|
||||
|
||||
[ "$kernel_size" ] && mtd -c 0x$kernel_size fixseama firmware
|
||||
[ "$kernel_size" ] && mtd -c 0x$kernel_size fix$1 firmware
|
||||
}
|
||||
|
||||
board=$(board_name)
|
||||
@ -18,6 +18,9 @@ cy-swr1100 | \
|
||||
dch-m225 | \
|
||||
dir-645 | \
|
||||
dir-860l-b1)
|
||||
fix_seama_header
|
||||
fix_checksum seama
|
||||
;;
|
||||
dlink,dap-1522-a1)
|
||||
fix_checksum wrg
|
||||
;;
|
||||
esac
|
@ -85,9 +85,6 @@ ramips_board_detect() {
|
||||
*"C108")
|
||||
name="c108"
|
||||
;;
|
||||
*"C20")
|
||||
name="c20"
|
||||
;;
|
||||
*"C20i")
|
||||
name="c20i"
|
||||
;;
|
||||
@ -580,9 +577,6 @@ ramips_board_detect() {
|
||||
*"WHR-G300N")
|
||||
name="whr-g300n"
|
||||
;;
|
||||
*"Widora-NEO")
|
||||
name="widora-neo"
|
||||
;;
|
||||
*"WiTi")
|
||||
name="witi"
|
||||
;;
|
||||
|
@ -17,11 +17,13 @@ platform_check_image() {
|
||||
ai-br100|\
|
||||
air3gii|\
|
||||
alfa-network,ac1200rm|\
|
||||
alfa-network,awusfree1|\
|
||||
all0239-3g|\
|
||||
all0256n-4M|\
|
||||
all0256n-8M|\
|
||||
all5002|\
|
||||
all5003|\
|
||||
mediatek,ap-mt7621a-v60|\
|
||||
ar725w|\
|
||||
asl26555-8M|\
|
||||
asl26555-16M|\
|
||||
@ -61,6 +63,7 @@ platform_check_image() {
|
||||
fonera20n|\
|
||||
freestation5|\
|
||||
gb-pc1|\
|
||||
gnubee,gb-pc2|\
|
||||
gl-mt300a|\
|
||||
gl-mt300n|\
|
||||
gl-mt750|\
|
||||
@ -140,6 +143,7 @@ platform_check_image() {
|
||||
sap-g3200u3|\
|
||||
sk-wb8|\
|
||||
sl-r7205|\
|
||||
tama,w06|\
|
||||
tew-638apb-v2|\
|
||||
tew-691gr|\
|
||||
tew-692gr|\
|
||||
@ -167,7 +171,8 @@ platform_check_image() {
|
||||
whr-300hp2|\
|
||||
whr-600d|\
|
||||
whr-g300n|\
|
||||
widora-neo|\
|
||||
widora,neo-16m|\
|
||||
widora,neo-32m|\
|
||||
witi|\
|
||||
wizfi630a|\
|
||||
wl-330n|\
|
||||
@ -203,6 +208,7 @@ platform_check_image() {
|
||||
zbt-ape522ii|\
|
||||
zbt-cpe102|\
|
||||
zbt-wa05|\
|
||||
zbtlink,zbt-we1226|\
|
||||
zbt-we1326|\
|
||||
zbt-we2026|\
|
||||
zbtlink,zbt-we3526|\
|
||||
@ -237,11 +243,14 @@ platform_check_image() {
|
||||
}
|
||||
return 0
|
||||
;;
|
||||
c20|\
|
||||
c20i|\
|
||||
c50|\
|
||||
mr200|\
|
||||
tplink,c20-v1|\
|
||||
tplink,c20-v4|\
|
||||
tplink,c50-v3|\
|
||||
tplink,tl-mr3420-v5|\
|
||||
tplink,tl-wr902ac-v3|\
|
||||
tl-wr840n-v4|\
|
||||
tl-wr840n-v5|\
|
||||
tl-wr841n-v13)
|
||||
@ -262,11 +271,21 @@ platform_check_image() {
|
||||
}
|
||||
return 0
|
||||
;;
|
||||
dlink,dwr-116-a1|\
|
||||
dlink,dwr-921-c1)
|
||||
[ "$magic" != "0404242b" ] && {
|
||||
echo "Invalid image type."
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
;;
|
||||
hc5962|\
|
||||
mir3g|\
|
||||
r6220)
|
||||
# these boards use metadata images
|
||||
return 0
|
||||
r6220|\
|
||||
ubnt-erx|\
|
||||
ubnt-erx-sfp)
|
||||
nand_do_platform_check "$board" "$1"
|
||||
return $?;
|
||||
;;
|
||||
re350-v1)
|
||||
[ "$magic" != "01000000" ] && {
|
||||
@ -275,11 +294,6 @@ platform_check_image() {
|
||||
}
|
||||
return 0
|
||||
;;
|
||||
ubnt-erx|\
|
||||
ubnt-erx-sfp)
|
||||
nand_do_platform_check "$board" "$1"
|
||||
return $?;
|
||||
;;
|
||||
wcr-1166ds|\
|
||||
wsr-1166)
|
||||
[ "$magic" != "48445230" ] && {
|
||||
@ -322,17 +336,8 @@ platform_do_upgrade() {
|
||||
esac
|
||||
}
|
||||
|
||||
disable_watchdog() {
|
||||
killall watchdog
|
||||
( ps | grep -v 'grep' | grep '/dev/watchdog' ) && {
|
||||
echo 'Could not disable watchdog'
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
blink_led() {
|
||||
. /etc/diag.sh; set_state upgrade
|
||||
}
|
||||
|
||||
append sysupgrade_pre_upgrade disable_watchdog
|
||||
append sysupgrade_pre_upgrade blink_led
|
||||
|
@ -148,8 +148,13 @@
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x1000>;
|
||||
};
|
||||
|
||||
partition@031000 {
|
||||
label = "config";
|
||||
reg = <0x30000 0x10000>;
|
||||
reg = <0x31000 0xf000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
|
127
target/linux/ramips/dts/AP-MT7621A-V60.dts
Normal file
127
target/linux/ramips/dts/AP-MT7621A-V60.dts
Normal file
@ -0,0 +1,127 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7621.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,ap-mt7621a-v60", "mediatek,mt7621-soc";
|
||||
model = "Mediatek AP-MT7621A-V60 EVB";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x8000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,57600";
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "Audio-I2S";
|
||||
simple-audio-card,format = "i2s";
|
||||
simple-audio-card,bitclock-master = <&dailink0_master>;
|
||||
simple-audio-card,frame-master = <&dailink0_master>;
|
||||
simple-audio-card,widgets =
|
||||
"Microphone", "Microphone Jack",
|
||||
"Headphone", "Headphone Jack";
|
||||
simple-audio-card,routing =
|
||||
"LINPUT1", "Microphone Jack",
|
||||
"RINPUT1", "Microphone Jack",
|
||||
"Headphone Jack", "HP_L",
|
||||
"Headphone Jack", "HP_R";
|
||||
simple-audio-card,mclk-fs = <256>;
|
||||
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&i2s>;
|
||||
};
|
||||
|
||||
dailink0_master: simple-audio-card,codec {
|
||||
sound-dai = <&codec>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "uart2", "rgmii2";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
i2s_pins: i2s {
|
||||
i2s {
|
||||
ralink,group = "uart3";
|
||||
ralink,function = "i2s";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c {
|
||||
status = "okay";
|
||||
|
||||
codec: wm8960@1a {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "wlf,wm8960";
|
||||
reg = <0x1a>;
|
||||
wlf,shared-lrclk;
|
||||
};
|
||||
};
|
||||
|
||||
&gdma {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2s {
|
||||
#sound-dai-cells = <0>;
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2s_pins>;
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
mx25l6405d@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "mx25l6405d","jedec,spi-nor";
|
||||
reg = <0 0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
m25p,chunked-io = <32>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x7b0000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mtd-mac-address = <&factory 0x5>;
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
};
|
164
target/linux/ramips/dts/AWUSFREE1.dts
Normal file
164
target/linux/ramips/dts/AWUSFREE1.dts
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (C) 2018 Piotr Dymacz <pepe2k@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of any
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7628an.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "alfa-network,awusfree1", "mediatek,mt7628an-soc";
|
||||
model = "ALFA Network AWUSFREE1";
|
||||
|
||||
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 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
system {
|
||||
label = "awusfree1:orange:system";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan {
|
||||
label = "awusfree1:blue:wlan";
|
||||
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x4000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&esw {
|
||||
mediatek,portdisable = <0x1e>;
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mtd-mac-address = <&factory 0x2e>;
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "p0led_an", "wdt", "wled_an";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
|
||||
ext_lna {
|
||||
ralink,group = "uart1";
|
||||
ralink,function = "sw_r";
|
||||
};
|
||||
|
||||
ext_pa {
|
||||
ralink,group = "i2s";
|
||||
ralink,function = "antenna";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
m25p,chunked-io = <32>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x1000>;
|
||||
};
|
||||
|
||||
partition@031000 {
|
||||
label = "config";
|
||||
reg = <0x31000 0xf000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x7b0000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wmac {
|
||||
status = "okay";
|
||||
mediatek,mtd-eeprom = <&factory 0x0>;
|
||||
};
|
@ -6,8 +6,8 @@
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
compatible = "tplink,c20", "ralink,mt7620a-soc";
|
||||
model = "TP-Link Archer C20";
|
||||
compatible = "tplink,c20-v1", "ralink,mt7620a-soc";
|
||||
model = "TP-Link Archer C20 v1";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200";
|
||||
@ -17,43 +17,43 @@
|
||||
compatible = "gpio-leds";
|
||||
|
||||
lan {
|
||||
label = "c20:blue:lan";
|
||||
label = "c20-v1:blue:lan";
|
||||
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
power {
|
||||
label = "c20:blue:power";
|
||||
label = "c20-v1:blue:power";
|
||||
gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
|
||||
default-state = "keep";
|
||||
};
|
||||
|
||||
usb {
|
||||
label = "c20:blue:usb";
|
||||
label = "c20-v1:blue:usb";
|
||||
gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "c20:blue:wan";
|
||||
label = "c20-v1:blue:wan";
|
||||
gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
wan_orange {
|
||||
label = "c20:orange:wan";
|
||||
label = "c20-v1:orange:wan";
|
||||
gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
wlan5g {
|
||||
label = "c20:blue:wlan5g";
|
||||
label = "c20-v1:blue:wlan5g";
|
||||
gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan2g {
|
||||
label = "c20:blue:wlan2g";
|
||||
label = "c20-v1:blue:wlan2g";
|
||||
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wps {
|
||||
label = "c20:blue:wps";
|
||||
label = "c20-v1:blue:wps";
|
||||
gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
@ -74,7 +74,8 @@
|
||||
label = "rfkill";
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RFKILL>;
|
||||
}; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
@ -178,7 +179,7 @@
|
||||
mt76@0,0 {
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
device_type = "pci";
|
||||
mediatek,mtd-eeprom = <&radio 32768>;
|
||||
mediatek,mtd-eeprom = <&radio 0x8000>;
|
||||
ieee80211-freq-limit = <5000000 6000000>;
|
||||
mtd-mac-address = <&rom 0xf100>;
|
||||
mtd-mac-address-increment = <(-1)>;
|
101
target/linux/ramips/dts/ArcherC20v4.dts
Normal file
101
target/linux/ramips/dts/ArcherC20v4.dts
Normal file
@ -0,0 +1,101 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "TPLINK-8M.dtsi"
|
||||
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
compatible = "tplink,c20-v4", "mediatek,mt7628an-soc";
|
||||
model = "TP-Link Archer C20 v4";
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
lan {
|
||||
label = "c20-v4:green:lan";
|
||||
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
power {
|
||||
label = "c20-v4:green:power";
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "c20-v4:green:wan";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan_orange {
|
||||
label = "c20-v4:orange:wan";
|
||||
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan5g {
|
||||
label = "c20-v4:green:wlan5g";
|
||||
gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan2g {
|
||||
label = "c20-v4:green:wlan2g";
|
||||
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wps {
|
||||
label = "c20-v4:green:wps";
|
||||
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
|
||||
rfkill {
|
||||
label = "rfkill";
|
||||
gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RFKILL>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wmac {
|
||||
mtd-mac-address-increment = <(-2)>;
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mediatek,portmap = "wllll";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "i2s", "refclk", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "wdt";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
|
||||
pcie-bridge {
|
||||
mt76@0,0 {
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
device_type = "pci";
|
||||
mediatek,mtd-eeprom = <&factory 0x28000>;
|
||||
ieee80211-freq-limit = <5000000 6000000>;
|
||||
mtd-mac-address = <&factory 0xf100>;
|
||||
mtd-mac-address-increment = <(-1)>;
|
||||
};
|
||||
};
|
||||
};
|
94
target/linux/ramips/dts/ArcherC50V3.dts
Normal file
94
target/linux/ramips/dts/ArcherC50V3.dts
Normal file
@ -0,0 +1,94 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "TPLINK-8M.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "tplink,c50-v3", "mediatek,mt7628an-soc";
|
||||
model = "TP-Link Archer C50 v3";
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
|
||||
rfkill {
|
||||
label = "rfkill";
|
||||
gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RFKILL>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
lan {
|
||||
label = "c50-v3:green:lan";
|
||||
gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
power {
|
||||
label = "c50-v3:green:power";
|
||||
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "c50-v3:green:wan";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan_orange {
|
||||
label = "c50-v3:orange:wan";
|
||||
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan {
|
||||
label = "c50-v3:green:wlan2g";
|
||||
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan5 {
|
||||
label = "c50-v3:green:wlan5g";
|
||||
gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wps {
|
||||
label = "c50-v3:green:wps";
|
||||
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "i2c", "gpio", "p0led_an", "p1led_an", "p2led_an",
|
||||
"p3led_an", "p4led_an", "wdt", "wled_an";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
|
||||
pcie-bridge {
|
||||
mt76@0,0 {
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
device_type = "pci";
|
||||
mediatek,mtd-eeprom = <&factory 0x28000>;
|
||||
ieee80211-freq-limit = <5000000 6000000>;
|
||||
mtd-mac-address = <&factory 0xf100>;
|
||||
mtd-mac-address-increment = <(-1)>;
|
||||
};
|
||||
};
|
||||
};
|
139
target/linux/ramips/dts/DAP-1522-A1.dts
Normal file
139
target/linux/ramips/dts/DAP-1522-A1.dts
Normal file
@ -0,0 +1,139 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "rt2880.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "dlink,dap-1522-a1", "ralink,rt2880-soc";
|
||||
model = "D-Link DAP-1522 A1";
|
||||
|
||||
cfi@bc400000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0xbc400000 0x800000>;
|
||||
bank-width = <2>;
|
||||
device-width = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "uboot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
factory: partition@30000 {
|
||||
label = "factory";
|
||||
reg = <0x30000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@40000 {
|
||||
label = "firmware";
|
||||
reg = <0x40000 0x3a0000>;
|
||||
};
|
||||
};
|
||||
|
||||
rtl8366s {
|
||||
compatible = "realtek,rtl8366s";
|
||||
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
|
||||
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <100>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
|
||||
wps {
|
||||
label = "wps";
|
||||
gpios = <&gpio2 16 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_WPS_BUTTON>;
|
||||
};
|
||||
|
||||
ap {
|
||||
label = "ap";
|
||||
gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <BTN_0>;
|
||||
linux,input-type = <EV_SW>;
|
||||
};
|
||||
|
||||
bridge {
|
||||
label = "bridge";
|
||||
gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <BTN_1>;
|
||||
linux,input-type = <EV_SW>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
wps {
|
||||
label = "dap-1522-a1:blue:wps";
|
||||
gpios = <&gpio2 17 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
ap {
|
||||
label = "dap-1522-a1:blue:ap";
|
||||
gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
sta {
|
||||
label = "dap-1522-a1:red:sta";
|
||||
gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
status {
|
||||
label = "dap-1522-a1:blue:status";
|
||||
gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "i2c", "uartlite", "pci";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ðernet {
|
||||
status = "okay";
|
||||
mtd-mac-address = <&factory 0x2004>;
|
||||
|
||||
port@0 {
|
||||
mediatek,fixed-link = <1000 1 1 1>;
|
||||
};
|
||||
|
||||
mdio-bus {
|
||||
status = "okay";
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
phy-mode = "mii";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wmac {
|
||||
ralink,mtd-eeprom = <&factory 0x2000>;
|
||||
};
|
104
target/linux/ramips/dts/DWR-116-A1.dts
Normal file
104
target/linux/ramips/dts/DWR-116-A1.dts
Normal file
@ -0,0 +1,104 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7620n.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "dlink,dwr-116-a1", "ralink,mt7620n-soc";
|
||||
model = "D-Link DWR-116 A1/A2";
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
wps {
|
||||
label = "wps";
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_WPS_BUTTON>;
|
||||
};
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
status {
|
||||
label = "dwr-116-a1:green:status";
|
||||
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
wifi {
|
||||
label = "dwr-116-a1:green:wifi";
|
||||
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <50000000>;
|
||||
|
||||
partition@0 {
|
||||
label = "jboot";
|
||||
reg = <0x0 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@10000 {
|
||||
label = "firmware";
|
||||
reg = <0x10000 0x7e0000>;
|
||||
};
|
||||
|
||||
config: partition@7f0000 {
|
||||
label = "config";
|
||||
reg = <0x7f0000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
default {
|
||||
ralink,group = "i2c", "wled";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mediatek,portmap = "llllw";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ephy_pins>;
|
||||
};
|
144
target/linux/ramips/dts/DWR-921-C1.dts
Normal file
144
target/linux/ramips/dts/DWR-921-C1.dts
Normal file
@ -0,0 +1,144 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7620n.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "dlink,dwr-921-c1", "ralink,mt7620n-soc";
|
||||
model = "D-Link DWR-921 C1";
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
wps {
|
||||
label = "wps";
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_WPS_BUTTON>;
|
||||
};
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
sms {
|
||||
label = "dwr-921-c1:green:sms";
|
||||
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan {
|
||||
label = "dwr-921-c1:green:lan";
|
||||
gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
sstrengthg {
|
||||
label = "dwr-921-c1:green:sigstrength";
|
||||
gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
sstrengthr {
|
||||
label = "dwr-921-c1:red:sigstrength";
|
||||
gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
4g {
|
||||
label = "dwr-921-c1:green:4g";
|
||||
gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
3g {
|
||||
label = "dwr-921-c1:green:3g";
|
||||
gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wifi {
|
||||
label = "dwr-921-c1:green:wifi";
|
||||
gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio_export {
|
||||
compatible = "gpio-export";
|
||||
#size-cells = <0>;
|
||||
|
||||
lte_modem_enable {
|
||||
gpio-export,name = "lte_modem_enable";
|
||||
gpio-export,output = <1>;
|
||||
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
|
||||
partition@0 {
|
||||
label = "jboot";
|
||||
reg = <0x0 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@10000 {
|
||||
label = "firmware";
|
||||
reg = <0x10000 0xfe0000>;
|
||||
};
|
||||
|
||||
config: partition@ff0000 {
|
||||
label = "config";
|
||||
reg = <0xff0000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ðernet {
|
||||
port@4 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
default {
|
||||
ralink,group = "spi refclk", "i2c", "ephy", "wled";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
@ -104,7 +104,7 @@
|
||||
|
||||
&cpuclock {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <90000000>;
|
||||
clock-frequency = <900000000>;
|
||||
};
|
||||
|
||||
&pcie {
|
||||
|
134
target/linux/ramips/dts/GB-PC2.dts
Normal file
134
target/linux/ramips/dts/GB-PC2.dts
Normal file
@ -0,0 +1,134 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7621.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "gnubee,gb-pc2", "mediatek,mt7621-soc";
|
||||
model = "GB-PC2";
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x1c000000>, <0x20000000 0x4000000>;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,57600";
|
||||
};
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
system {
|
||||
label = "gb-pc2:green:system";
|
||||
gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
status {
|
||||
label = "gb-pc2:green:status";
|
||||
gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan1 {
|
||||
label = "gb-pc2:green:lan1";
|
||||
gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan2 {
|
||||
label = "gb-pc2:green:lan2";
|
||||
gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan3-yellow {
|
||||
label = "gb-pc2:yellow:lan3";
|
||||
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan3-green {
|
||||
label = "gb-pc2:green:lan3";
|
||||
gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
&sdhci {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sdhci_pins>;
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
m25p,chunked-io = <32>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x1fb0000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&cpuclock {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <900000000>;
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mtd-mac-address = <&factory 0xe000>;
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "jtag", "rgmii3", "uart3", "wdt";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -21,6 +21,12 @@
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
power {
|
||||
label = "gl-mt300n-v2:green:power";
|
||||
default-state = "on";
|
||||
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "gl-mt300n-v2:blue:wan";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
@ -73,7 +79,7 @@
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "wdt", "gpio", "wled_an", "p0led_an", "i2s";
|
||||
ralink,group = "wdt", "gpio", "wled_an", "p0led_an", "p1led_an", "i2s";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
@ -124,6 +130,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "TL-WR84XN.dtsi"
|
||||
#include "TPLINK-8M.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "TL-WR84XN.dtsi"
|
||||
#include "TPLINK-8M.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
@ -65,13 +65,7 @@
|
||||
|
||||
partition@20000 {
|
||||
label = "firmware";
|
||||
reg = <0x20000 0x3c0000>;
|
||||
};
|
||||
|
||||
partition@3e0000 {
|
||||
label = "config";
|
||||
reg = <0x3e0000 0x10000>;
|
||||
read-only;
|
||||
reg = <0x20000 0x3d0000>;
|
||||
};
|
||||
|
||||
factory: partition@3f0000 {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "TL-WR84XN.dtsi"
|
||||
#include "TPLINK-8M.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
102
target/linux/ramips/dts/TL-WR902ACV3.dts
Normal file
102
target/linux/ramips/dts/TL-WR902ACV3.dts
Normal file
@ -0,0 +1,102 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "TPLINK-8M.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "tplink,tl-wr902ac-v3", "mediatek,mt7628an-soc";
|
||||
model = "TP-Link TL-WR902AC v3";
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
|
||||
sw1 {
|
||||
label = "sw1";
|
||||
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <BTN_0>;
|
||||
};
|
||||
|
||||
sw2 {
|
||||
label = "sw2";
|
||||
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <BTN_1>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
lan {
|
||||
label = "tl-wr902ac-v3:green:lan";
|
||||
gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
power {
|
||||
label = "tl-wr902ac-v3:green:power";
|
||||
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
usb {
|
||||
label = "tl-wr902ac-v3:green:usb";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "tl-wr902ac-v3:green:wan";
|
||||
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan {
|
||||
label = "tl-wr902ac-v3:green:wlan";
|
||||
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wps {
|
||||
label = "tl-wr902ac-v3:green:wps";
|
||||
gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "i2c", "i2s", "p0led_an", "p4led_an", "uart1", "wdt", "wled_an";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie {
|
||||
status = "okay";
|
||||
|
||||
pcie-bridge {
|
||||
mt76@1,0 {
|
||||
reg = <0x0000 0 0 0 0>;
|
||||
device_type = "pci";
|
||||
mediatek,mtd-eeprom = <&factory 0x28000>;
|
||||
ieee80211-freq-limit = <5000000 6000000>;
|
||||
mtd-mac-address = <&factory 0xf100>;
|
||||
mtd-mac-address-increment = <(-1)>;
|
||||
};
|
||||
};
|
||||
};
|
115
target/linux/ramips/dts/W06.dts
Normal file
115
target/linux/ramips/dts/W06.dts
Normal file
@ -0,0 +1,115 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7628an.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
compatible = "tama,w06", "mediatek,mt7628an-soc";
|
||||
model = "Tama W06";
|
||||
|
||||
memory@0{
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x4000000>;
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
wps {
|
||||
label = "w06:green:wps";
|
||||
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan {
|
||||
label = "w06:green:wan";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wireless {
|
||||
label = "w06:green:wlan";
|
||||
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ehci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mtd-mac-address = <&factory 0x28>;
|
||||
};
|
||||
|
||||
&ohci {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "uart1", "p0led_an", "wdt";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
m25p,chunked-io = <32>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0xeb0000>;
|
||||
};
|
||||
|
||||
partition@f00000 {
|
||||
label = "user-data";
|
||||
reg = <0xf00000 0x100000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wmac {
|
||||
status = "okay";
|
||||
};
|
@ -107,6 +107,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mtd-mac-address = <&factory 0x4>;
|
||||
};
|
||||
|
||||
&esw {
|
||||
mediatek,portmap = <0x2f>;
|
||||
};
|
||||
|
54
target/linux/ramips/dts/WIDORA-NEO-16M.dts
Normal file
54
target/linux/ramips/dts/WIDORA-NEO-16M.dts
Normal file
@ -0,0 +1,54 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "WIDORA-NEO.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "widora,neo-16m", "widora,neo", "mediatek,mt7628an-soc";
|
||||
model = "Widora-NEO (16M)";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <40000000>;
|
||||
m25p,chunked-io = <31>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x0fb0000>;
|
||||
};
|
||||
};
|
||||
|
||||
spidev@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "linux,spidev";
|
||||
reg = <1>;
|
||||
spi-max-frequency = <40000000>;
|
||||
};
|
||||
};
|
54
target/linux/ramips/dts/WIDORA-NEO-32M.dts
Normal file
54
target/linux/ramips/dts/WIDORA-NEO-32M.dts
Normal file
@ -0,0 +1,54 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "WIDORA-NEO.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "widora,neo-32m", "widora,neo", "mediatek,mt7628an-soc";
|
||||
model = "Widora-NEO (32M)";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <40000000>;
|
||||
m25p,chunked-io = <31>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x1fb0000>;
|
||||
};
|
||||
};
|
||||
|
||||
spidev@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "linux,spidev";
|
||||
reg = <1>;
|
||||
spi-max-frequency = <40000000>;
|
||||
};
|
||||
};
|
@ -1,5 +1,3 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "mt7628an.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
@ -7,7 +5,6 @@
|
||||
|
||||
/ {
|
||||
compatible = "widora,neo", "mediatek,mt7628an-soc";
|
||||
model = "Widora-NEO";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200";
|
||||
@ -94,53 +91,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <40000000>;
|
||||
m25p,chunked-io = <31>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x0fb0000>;
|
||||
};
|
||||
};
|
||||
|
||||
spidev@1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "linux,spidev";
|
||||
reg = <1>;
|
||||
spi-max-frequency = <40000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c {
|
||||
status = "okay";
|
||||
};
|
111
target/linux/ramips/dts/ZBT-WE1226.dts
Normal file
111
target/linux/ramips/dts/ZBT-WE1226.dts
Normal file
@ -0,0 +1,111 @@
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
#include "mt7628an.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "zbtlink,zbt-we1226", "mediatek,mt7628an-soc";
|
||||
model = "Zbtlink ZBT-WE1226";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200";
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x4000000>;
|
||||
};
|
||||
|
||||
gpio-keys-polled {
|
||||
compatible = "gpio-keys-polled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
poll-interval = <20>;
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
wan {
|
||||
label = "zbt-we1226:green:wan";
|
||||
gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan1 {
|
||||
label = "zbt-we1226:green:lan1";
|
||||
gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan2 {
|
||||
label = "zbt-we1226:green:lan2";
|
||||
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wlan {
|
||||
label = "zbt-we1226:green:wlan";
|
||||
gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
state_default: pinctrl0 {
|
||||
gpio {
|
||||
ralink,group = "p0led_an", "p1led_an", "p4led_an", "wdt", "wled_an";
|
||||
ralink,function = "gpio";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
m25p80@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
m25p,chunked-io = <32>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x30000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@30000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x30000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
factory: partition@40000 {
|
||||
label = "factory";
|
||||
reg = <0x40000 0x10000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@50000 {
|
||||
label = "firmware";
|
||||
reg = <0x50000 0x7b0000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&wmac {
|
||||
status = "okay";
|
||||
ralink,mtd-eeprom = <&factory 0x4>;
|
||||
};
|
||||
|
||||
ðernet {
|
||||
mtd-mac-address = <&factory 0x2e>;
|
||||
mediatek,portmap = "llllw";
|
||||
};
|
@ -35,7 +35,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,mt7620a-sysc", "ralink,rt3050-sysc";
|
||||
compatible = "ralink,mt7620a-sysc", "ralink,rt3050-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -427,8 +427,9 @@
|
||||
|
||||
usbphy: usbphy {
|
||||
compatible = "mediatek,mt7620-usbphy";
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22 &rstctrl 25>;
|
||||
reset-names = "host", "device";
|
||||
|
||||
@ -501,7 +502,7 @@
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <18>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
status = "disabled";
|
||||
@ -514,7 +515,7 @@
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <18>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
status = "disabled";
|
||||
|
@ -35,7 +35,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,mt7620a-sysc", "ralink,rt3050-sysc";
|
||||
compatible = "ralink,mt7620a-sysc", "ralink,rt3050-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -269,8 +269,9 @@
|
||||
|
||||
usbphy: usbphy {
|
||||
compatible = "mediatek,mt7620-usbphy";
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22 &rstctrl 25>;
|
||||
reset-names = "host", "device";
|
||||
|
||||
@ -299,6 +300,13 @@
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
port@4 {
|
||||
compatible = "mediatek,mt7620a-gsw-port", "mediatek,eth-port";
|
||||
reg = <4>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
gsw: gsw@10110000 {
|
||||
@ -310,7 +318,7 @@
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <17>;
|
||||
mediatek,port4 = "gmac";
|
||||
mediatek,port4 = "ephy";
|
||||
};
|
||||
|
||||
ehci: ehci@101c0000 {
|
||||
@ -320,7 +328,7 @@
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <18>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
status = "disabled";
|
||||
@ -330,7 +338,7 @@
|
||||
compatible = "generic-ohci";
|
||||
reg = <0x101c1000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
|
@ -342,6 +342,7 @@
|
||||
compatible = "mediatek,mt8173-xhci";
|
||||
reg = <0x1e1c0000 0x1000
|
||||
0x1e1d0700 0x0100>;
|
||||
reg-names = "mac", "ippc";
|
||||
|
||||
clocks = <&sysclock>;
|
||||
clock-names = "sys_ck";
|
||||
@ -377,6 +378,16 @@
|
||||
#size-cells = <1>;
|
||||
};
|
||||
|
||||
hnat: hnat@1e100000 {
|
||||
compatible = "mediatek,mt7623-hnat";
|
||||
reg = <0x1e100000 0x10000>;
|
||||
mtketh-ppd = "eth0";
|
||||
mtketh-lan = "eth0";
|
||||
mtketh-wan = "eth0";
|
||||
resets = <&rstctrl 0>;
|
||||
reset-names = "mtketh";
|
||||
};
|
||||
|
||||
ethernet: ethernet@1e100000 {
|
||||
compatible = "mediatek,mt7621-eth";
|
||||
reg = <0x1e100000 0x10000>;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,mt7620a-sysc";
|
||||
compatible = "ralink,mt7620a-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -375,8 +375,9 @@
|
||||
usbphy: usbphy@10120000 {
|
||||
compatible = "ralink,mt7628an-usbphy", "mediatek,mt7620-usbphy";
|
||||
reg = <0x10120000 0x1000>;
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22 &rstctrl 25>;
|
||||
reset-names = "host", "device";
|
||||
clocks = <&clkctrl 22 &clkctrl 25>;
|
||||
@ -400,7 +401,7 @@
|
||||
compatible = "generic-ehci";
|
||||
reg = <0x101c0000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
@ -411,7 +412,7 @@
|
||||
compatible = "generic-ohci";
|
||||
reg = <0x101c1000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
|
@ -34,7 +34,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,rt3050-sysc";
|
||||
compatible = "ralink,rt3050-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -287,6 +287,9 @@
|
||||
|
||||
usbphy: usbphy {
|
||||
compatible = "ralink,rt3050-usbphy";
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22>;
|
||||
reset-names = "host";
|
||||
clocks = <&clkctrl 18>;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,rt3352-sysc", "ralink,rt3050-sysc";
|
||||
compatible = "ralink,rt3352-sysc", "ralink,rt3050-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -334,8 +334,9 @@
|
||||
|
||||
usbphy: usbphy {
|
||||
compatible = "ralink,rt3352-usbphy";
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22 &rstctrl 25>;
|
||||
reset-names = "host", "device";
|
||||
clocks = <&clkctrl 18 &clkctrl 20>;
|
||||
@ -356,7 +357,7 @@
|
||||
compatible = "generic-ehci";
|
||||
reg = <0x101c0000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
@ -369,7 +370,7 @@
|
||||
compatible = "generic-ohci";
|
||||
reg = <0x101c1000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,rt3883-sysc", "ralink,rt3050-sysc";
|
||||
compatible = "ralink,rt3883-sysc", "ralink,rt3050-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -427,8 +427,9 @@
|
||||
|
||||
usbphy: usbphy {
|
||||
compatible = "ralink,rt3352-usbphy";
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22 &rstctrl 25>;
|
||||
reset-names = "host", "device";
|
||||
clocks = <&clkctrl 22 &clkctrl 25>;
|
||||
@ -449,7 +450,7 @@
|
||||
compatible = "generic-ehci";
|
||||
reg = <0x101c0000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
@ -462,7 +463,7 @@
|
||||
compatible = "generic-ohci";
|
||||
reg = <0x101c1000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#size-cells = <1>;
|
||||
|
||||
sysc: sysc@0 {
|
||||
compatible = "ralink,rt5350-sysc", "ralink,rt3050-sysc";
|
||||
compatible = "ralink,rt5350-sysc", "ralink,rt3050-sysc", "syscon";
|
||||
reg = <0x0 0x100>;
|
||||
};
|
||||
|
||||
@ -324,8 +324,9 @@
|
||||
|
||||
usbphy: usbphy {
|
||||
compatible = "ralink,rt3352-usbphy";
|
||||
#phy-cells = <1>;
|
||||
#phy-cells = <0>;
|
||||
|
||||
ralink,sysctl = <&sysc>;
|
||||
resets = <&rstctrl 22 &rstctrl 25>;
|
||||
reset-names = "host", "device";
|
||||
clocks = <&clkctrl 18>;
|
||||
@ -370,7 +371,7 @@
|
||||
compatible = "generic-ehci";
|
||||
reg = <0x101c0000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
@ -381,7 +382,7 @@
|
||||
compatible = "generic-ohci";
|
||||
reg = <0x101c1000 0x1000>;
|
||||
|
||||
phys = <&usbphy 1>;
|
||||
phys = <&usbphy>;
|
||||
phy-names = "usb";
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
|
@ -0,0 +1,16 @@
|
||||
config MTK_MMC
|
||||
tristate "MTK SD/MMC"
|
||||
depends on !MTD_NAND_RALINK
|
||||
|
||||
config MTK_AEE_KDUMP
|
||||
bool "MTK AEE KDUMP"
|
||||
depends on MTK_MMC
|
||||
|
||||
config MTK_MMC_CD_POLL
|
||||
bool "Card Detect with Polling"
|
||||
depends on MTK_MMC
|
||||
|
||||
config MTK_MMC_EMMC_8BIT
|
||||
bool "eMMC 8-bit support"
|
||||
depends on MTK_MMC && RALINK_MT7628
|
||||
|
@ -0,0 +1,42 @@
|
||||
# Copyright Statement:
|
||||
#
|
||||
# This software/firmware and related documentation ("MediaTek Software") are
|
||||
# protected under relevant copyright laws. The information contained herein
|
||||
# is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
||||
# Without the prior written permission of MediaTek inc. and/or its licensors,
|
||||
# any reproduction, modification, use or disclosure of MediaTek Software,
|
||||
# and information contained herein, in whole or in part, shall be strictly prohibited.
|
||||
#
|
||||
# MediaTek Inc. (C) 2010. All rights reserved.
|
||||
#
|
||||
# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
||||
# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
||||
# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
|
||||
# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
|
||||
# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
|
||||
# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
|
||||
# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
|
||||
# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
|
||||
# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
|
||||
# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
|
||||
# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
|
||||
# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
|
||||
# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
|
||||
# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
|
||||
# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
|
||||
# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
|
||||
#
|
||||
# The following software/firmware and/or related documentation ("MediaTek Software")
|
||||
# have been modified by MediaTek Inc. All revisions are subject to any receiver's
|
||||
# applicable license agreements with MediaTek Inc.
|
||||
|
||||
obj-$(CONFIG_MTK_MMC) += mtk_sd.o
|
||||
mtk_sd-objs := sd.o dbg.o
|
||||
ifeq ($(CONFIG_MTK_AEE_KDUMP),y)
|
||||
EXTRA_CFLAGS += -DMT6575_SD_DEBUG
|
||||
endif
|
||||
|
||||
clean:
|
||||
@rm -f *.o modules.order .*.cmd
|
137
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/board.h
Normal file
137
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/board.h
Normal file
@ -0,0 +1,137 @@
|
||||
/* Copyright Statement:
|
||||
*
|
||||
* This software/firmware and related documentation ("MediaTek Software") are
|
||||
* protected under relevant copyright laws. The information contained herein
|
||||
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
||||
* Without the prior written permission of MediaTek inc. and/or its licensors,
|
||||
* any reproduction, modification, use or disclosure of MediaTek Software,
|
||||
* and information contained herein, in whole or in part, shall be strictly prohibited.
|
||||
*/
|
||||
/* MediaTek Inc. (C) 2010. All rights reserved.
|
||||
*
|
||||
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
||||
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
||||
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
|
||||
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
|
||||
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
|
||||
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
|
||||
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
|
||||
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
|
||||
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
|
||||
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
|
||||
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
|
||||
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
|
||||
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
|
||||
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
|
||||
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
|
||||
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
|
||||
*
|
||||
* The following software/firmware and/or related documentation ("MediaTek Software")
|
||||
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
|
||||
* applicable license agreements with MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_BOARD_H
|
||||
#define __ARCH_ARM_MACH_BOARD_H
|
||||
|
||||
#include <generated/autoconf.h>
|
||||
#include <linux/pm.h>
|
||||
/* --- chhung */
|
||||
// #include <mach/mt6575.h>
|
||||
// #include <board-custom.h>
|
||||
/* end of chhung */
|
||||
|
||||
typedef void (*sdio_irq_handler_t)(void*); /* external irq handler */
|
||||
typedef void (*pm_callback_t)(pm_message_t state, void *data);
|
||||
|
||||
#define MSDC_CD_PIN_EN (1 << 0) /* card detection pin is wired */
|
||||
#define MSDC_WP_PIN_EN (1 << 1) /* write protection pin is wired */
|
||||
#define MSDC_RST_PIN_EN (1 << 2) /* emmc reset pin is wired */
|
||||
#define MSDC_SDIO_IRQ (1 << 3) /* use internal sdio irq (bus) */
|
||||
#define MSDC_EXT_SDIO_IRQ (1 << 4) /* use external sdio irq */
|
||||
#define MSDC_REMOVABLE (1 << 5) /* removable slot */
|
||||
#define MSDC_SYS_SUSPEND (1 << 6) /* suspended by system */
|
||||
#define MSDC_HIGHSPEED (1 << 7) /* high-speed mode support */
|
||||
#define MSDC_UHS1 (1 << 8) /* uhs-1 mode support */
|
||||
#define MSDC_DDR (1 << 9) /* ddr mode support */
|
||||
|
||||
|
||||
#define MSDC_SMPL_RISING (0)
|
||||
#define MSDC_SMPL_FALLING (1)
|
||||
|
||||
#define MSDC_CMD_PIN (0)
|
||||
#define MSDC_DAT_PIN (1)
|
||||
#define MSDC_CD_PIN (2)
|
||||
#define MSDC_WP_PIN (3)
|
||||
#define MSDC_RST_PIN (4)
|
||||
|
||||
enum {
|
||||
MSDC_CLKSRC_48MHZ = 0,
|
||||
// MSDC_CLKSRC_26MHZ = 0,
|
||||
// MSDC_CLKSRC_197MHZ = 1,
|
||||
// MSDC_CLKSRC_208MHZ = 2
|
||||
};
|
||||
|
||||
struct msdc_hw {
|
||||
unsigned char clk_src; /* host clock source */
|
||||
unsigned char cmd_edge; /* command latch edge */
|
||||
unsigned char data_edge; /* data latch edge */
|
||||
unsigned char clk_drv; /* clock pad driving */
|
||||
unsigned char cmd_drv; /* command pad driving */
|
||||
unsigned char dat_drv; /* data pad driving */
|
||||
unsigned long flags; /* hardware capability flags */
|
||||
unsigned long data_pins; /* data pins */
|
||||
unsigned long data_offset; /* data address offset */
|
||||
|
||||
/* config gpio pull mode */
|
||||
void (*config_gpio_pin)(int type, int pull);
|
||||
|
||||
/* external power control for card */
|
||||
void (*ext_power_on)(void);
|
||||
void (*ext_power_off)(void);
|
||||
|
||||
/* external sdio irq operations */
|
||||
void (*request_sdio_eirq)(sdio_irq_handler_t sdio_irq_handler, void *data);
|
||||
void (*enable_sdio_eirq)(void);
|
||||
void (*disable_sdio_eirq)(void);
|
||||
|
||||
/* external cd irq operations */
|
||||
void (*request_cd_eirq)(sdio_irq_handler_t cd_irq_handler, void *data);
|
||||
void (*enable_cd_eirq)(void);
|
||||
void (*disable_cd_eirq)(void);
|
||||
int (*get_cd_status)(void);
|
||||
|
||||
/* power management callback for external module */
|
||||
void (*register_pm)(pm_callback_t pm_cb, void *data);
|
||||
};
|
||||
|
||||
extern struct msdc_hw msdc0_hw;
|
||||
extern struct msdc_hw msdc1_hw;
|
||||
extern struct msdc_hw msdc2_hw;
|
||||
extern struct msdc_hw msdc3_hw;
|
||||
|
||||
/*GPS driver*/
|
||||
#define GPS_FLAG_FORCE_OFF 0x0001
|
||||
struct mt3326_gps_hardware {
|
||||
int (*ext_power_on)(int);
|
||||
int (*ext_power_off)(int);
|
||||
};
|
||||
extern struct mt3326_gps_hardware mt3326_gps_hw;
|
||||
|
||||
/* NAND driver */
|
||||
struct mt6575_nand_host_hw {
|
||||
unsigned int nfi_bus_width; /* NFI_BUS_WIDTH */
|
||||
unsigned int nfi_access_timing; /* NFI_ACCESS_TIMING */
|
||||
unsigned int nfi_cs_num; /* NFI_CS_NUM */
|
||||
unsigned int nand_sec_size; /* NAND_SECTOR_SIZE */
|
||||
unsigned int nand_sec_shift; /* NAND_SECTOR_SHIFT */
|
||||
unsigned int nand_ecc_size;
|
||||
unsigned int nand_ecc_bytes;
|
||||
unsigned int nand_ecc_mode;
|
||||
};
|
||||
extern struct mt6575_nand_host_hw mt6575_nand_hw;
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_BOARD_H */
|
||||
|
348
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.c
Normal file
348
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.c
Normal file
@ -0,0 +1,348 @@
|
||||
/* Copyright Statement:
|
||||
*
|
||||
* This software/firmware and related documentation ("MediaTek Software") are
|
||||
* protected under relevant copyright laws. The information contained herein
|
||||
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
||||
* Without the prior written permission of MediaTek inc. and/or its licensors,
|
||||
* any reproduction, modification, use or disclosure of MediaTek Software,
|
||||
* and information contained herein, in whole or in part, shall be strictly prohibited.
|
||||
*
|
||||
* MediaTek Inc. (C) 2010. All rights reserved.
|
||||
*
|
||||
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
||||
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
||||
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
|
||||
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
|
||||
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
|
||||
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
|
||||
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
|
||||
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
|
||||
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
|
||||
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
|
||||
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
|
||||
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
|
||||
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
|
||||
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
|
||||
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
|
||||
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
|
||||
*
|
||||
* The following software/firmware and/or related documentation ("MediaTek Software")
|
||||
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
|
||||
* applicable license agreements with MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/uaccess.h>
|
||||
// #include <mach/mt6575_gpt.h> /* --- by chhung */
|
||||
#include "dbg.h"
|
||||
#include "mt6575_sd.h"
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
/* mode select */
|
||||
u32 dma_size[4]={
|
||||
512,
|
||||
512,
|
||||
512,
|
||||
512
|
||||
};
|
||||
msdc_mode drv_mode[4]={
|
||||
MODE_SIZE_DEP, /* using DMA or not depend on the size */
|
||||
MODE_SIZE_DEP,
|
||||
MODE_SIZE_DEP,
|
||||
MODE_SIZE_DEP
|
||||
};
|
||||
|
||||
#if defined (MT6575_SD_DEBUG)
|
||||
static char cmd_buf[256];
|
||||
|
||||
/* for debug zone */
|
||||
static unsigned int sd_debug_zone[4]={
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* for driver profile */
|
||||
#define TICKS_ONE_MS (13000)
|
||||
u32 gpt_enable = 0;
|
||||
u32 sdio_pro_enable = 0; /* make sure gpt is enabled */
|
||||
u32 sdio_pro_time = 0; /* no more than 30s */
|
||||
struct sdio_profile sdio_perfomance = {0};
|
||||
|
||||
#if 0 /* --- chhung */
|
||||
void msdc_init_gpt(void)
|
||||
{
|
||||
GPT_CONFIG config;
|
||||
|
||||
config.num = GPT6;
|
||||
config.mode = GPT_FREE_RUN;
|
||||
config.clkSrc = GPT_CLK_SRC_SYS;
|
||||
config.clkDiv = GPT_CLK_DIV_1; /* 13MHz GPT6 */
|
||||
|
||||
if (GPT_Config(config) == FALSE )
|
||||
return;
|
||||
|
||||
GPT_Start(GPT6);
|
||||
}
|
||||
#endif /* end of --- */
|
||||
|
||||
u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
if (new_H32 == old_H32) {
|
||||
ret = new_L32 - old_L32;
|
||||
} else if(new_H32 == (old_H32 + 1)) {
|
||||
if (new_L32 > old_L32) {
|
||||
printk("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32);
|
||||
}
|
||||
ret = (0xffffffff - old_L32);
|
||||
ret += new_L32;
|
||||
} else {
|
||||
printk("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void msdc_sdio_profile(struct sdio_profile* result)
|
||||
{
|
||||
struct cmd_profile* cmd;
|
||||
u32 i;
|
||||
|
||||
printk("sdio === performance dump ===\n");
|
||||
printk("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n",
|
||||
result->total_tc, result->total_tc / TICKS_ONE_MS,
|
||||
result->total_tx_bytes, result->total_rx_bytes);
|
||||
|
||||
/* CMD52 Dump */
|
||||
cmd = &result->cmd52_rx;
|
||||
printk("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc,
|
||||
cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count);
|
||||
cmd = &result->cmd52_tx;
|
||||
printk("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc,
|
||||
cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count);
|
||||
|
||||
/* CMD53 Rx bytes + block mode */
|
||||
for (i=0; i<512; i++) {
|
||||
cmd = &result->cmd53_rx_byte[i];
|
||||
if (cmd->count) {
|
||||
printk("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
|
||||
cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count,
|
||||
cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10));
|
||||
}
|
||||
}
|
||||
for (i=0; i<100; i++) {
|
||||
cmd = &result->cmd53_rx_blk[i];
|
||||
if (cmd->count) {
|
||||
printk("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
|
||||
cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count,
|
||||
cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10));
|
||||
}
|
||||
}
|
||||
|
||||
/* CMD53 Tx bytes + block mode */
|
||||
for (i=0; i<512; i++) {
|
||||
cmd = &result->cmd53_tx_byte[i];
|
||||
if (cmd->count) {
|
||||
printk("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
|
||||
cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count,
|
||||
cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10));
|
||||
}
|
||||
}
|
||||
for (i=0; i<100; i++) {
|
||||
cmd = &result->cmd53_tx_blk[i];
|
||||
if (cmd->count) {
|
||||
printk("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
|
||||
cmd->max_tc, cmd->min_tc, cmd->tot_tc/cmd->count,
|
||||
cmd->tot_bytes, (cmd->tot_bytes/10)*13 / (cmd->tot_tc/10));
|
||||
}
|
||||
}
|
||||
|
||||
printk("sdio === performance dump done ===\n");
|
||||
}
|
||||
|
||||
//========= sdio command table ===========
|
||||
void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks)
|
||||
{
|
||||
struct sdio_profile* result = &sdio_perfomance;
|
||||
struct cmd_profile* cmd;
|
||||
u32 block;
|
||||
|
||||
if (sdio_pro_enable == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (opcode == 52) {
|
||||
cmd = bRx ? &result->cmd52_rx : &result->cmd52_tx;
|
||||
} else if (opcode == 53) {
|
||||
if (sizes < 512) {
|
||||
cmd = bRx ? &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes];
|
||||
} else {
|
||||
block = sizes / 512;
|
||||
if (block >= 99) {
|
||||
printk("cmd53 error blocks\n");
|
||||
while(1);
|
||||
}
|
||||
cmd = bRx ? &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block];
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
/* update the members */
|
||||
if (ticks > cmd->max_tc){
|
||||
cmd->max_tc = ticks;
|
||||
}
|
||||
if (cmd->min_tc == 0 || ticks < cmd->min_tc) {
|
||||
cmd->min_tc = ticks;
|
||||
}
|
||||
cmd->tot_tc += ticks;
|
||||
cmd->tot_bytes += sizes;
|
||||
cmd->count ++;
|
||||
|
||||
if (bRx) {
|
||||
result->total_rx_bytes += sizes;
|
||||
} else {
|
||||
result->total_tx_bytes += sizes;
|
||||
}
|
||||
result->total_tc += ticks;
|
||||
|
||||
/* dump when total_tc > 30s */
|
||||
if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) {
|
||||
msdc_sdio_profile(result);
|
||||
memset(result, 0 , sizeof(struct sdio_profile));
|
||||
}
|
||||
}
|
||||
|
||||
//========== driver proc interface ===========
|
||||
static int msdc_debug_proc_read(struct seq_file *s, void *p)
|
||||
{
|
||||
seq_printf(s, "\n=========================================\n");
|
||||
seq_printf(s, "Index<0> + Id + Zone\n");
|
||||
seq_printf(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n");
|
||||
seq_printf(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n");
|
||||
seq_printf(s, "-> MSDC[0] Zone: 0x%.8x\n", sd_debug_zone[0]);
|
||||
seq_printf(s, "-> MSDC[1] Zone: 0x%.8x\n", sd_debug_zone[1]);
|
||||
seq_printf(s, "-> MSDC[2] Zone: 0x%.8x\n", sd_debug_zone[2]);
|
||||
seq_printf(s, "-> MSDC[3] Zone: 0x%.8x\n", sd_debug_zone[3]);
|
||||
|
||||
seq_printf(s, "Index<1> + ID:4|Mode:4 + DMA_SIZE\n");
|
||||
seq_printf(s, "-> 0)PIO 1)DMA 2)SIZE\n");
|
||||
seq_printf(s, "-> echo 1 22 0x200 >msdc_bebug -> host[2] size mode, dma when >= 512\n");
|
||||
seq_printf(s, "-> MSDC[0] mode<%d> size<%d>\n", drv_mode[0], dma_size[0]);
|
||||
seq_printf(s, "-> MSDC[1] mode<%d> size<%d>\n", drv_mode[1], dma_size[1]);
|
||||
seq_printf(s, "-> MSDC[2] mode<%d> size<%d>\n", drv_mode[2], dma_size[2]);
|
||||
seq_printf(s, "-> MSDC[3] mode<%d> size<%d>\n", drv_mode[3], dma_size[3]);
|
||||
|
||||
seq_printf(s, "Index<3> + SDIO_PROFILE + TIME\n");
|
||||
seq_printf(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n");
|
||||
seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time);
|
||||
seq_printf(s, "=========================================\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t msdc_debug_proc_write(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
int cmd, p1, p2;
|
||||
int id, zone;
|
||||
int mode, size;
|
||||
|
||||
if (count == 0)return -1;
|
||||
if(count > 255)count = 255;
|
||||
|
||||
ret = copy_from_user(cmd_buf, buf, count);
|
||||
if (ret < 0)return -1;
|
||||
|
||||
cmd_buf[count] = '\0';
|
||||
printk("msdc Write %s\n", cmd_buf);
|
||||
|
||||
sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2);
|
||||
|
||||
if(cmd == SD_TOOL_ZONE) {
|
||||
id = p1; zone = p2; zone &= 0x3ff;
|
||||
printk("msdc host_id<%d> zone<0x%.8x>\n", id, zone);
|
||||
if(id >=0 && id<=3){
|
||||
sd_debug_zone[id] = zone;
|
||||
}
|
||||
else if(id == 4){
|
||||
sd_debug_zone[0] = sd_debug_zone[1] = zone;
|
||||
sd_debug_zone[2] = sd_debug_zone[3] = zone;
|
||||
}
|
||||
else{
|
||||
printk("msdc host_id error when set debug zone\n");
|
||||
}
|
||||
} else if (cmd == SD_TOOL_DMA_SIZE) {
|
||||
id = p1>>4; mode = (p1&0xf); size = p2;
|
||||
if(id >=0 && id<=3){
|
||||
drv_mode[id] = mode;
|
||||
dma_size[id] = p2;
|
||||
}
|
||||
else if(id == 4){
|
||||
drv_mode[0] = drv_mode[1] = mode;
|
||||
drv_mode[2] = drv_mode[3] = mode;
|
||||
dma_size[0] = dma_size[1] = p2;
|
||||
dma_size[2] = dma_size[3] = p2;
|
||||
}
|
||||
else{
|
||||
printk("msdc host_id error when select mode\n");
|
||||
}
|
||||
} else if (cmd == SD_TOOL_SDIO_PROFILE) {
|
||||
if (p1 == 1) { /* enable profile */
|
||||
if (gpt_enable == 0) {
|
||||
// msdc_init_gpt(); /* --- by chhung */
|
||||
gpt_enable = 1;
|
||||
}
|
||||
sdio_pro_enable = 1;
|
||||
if (p2 == 0) p2 = 1; if (p2 >= 30) p2 = 30;
|
||||
sdio_pro_time = p2 ;
|
||||
} else if (p1 == 0) {
|
||||
/* todo */
|
||||
sdio_pro_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int msdc_debug_show(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, msdc_debug_proc_read, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations msdc_debug_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = msdc_debug_show,
|
||||
.read = seq_read,
|
||||
.write = msdc_debug_proc_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
int msdc_debug_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *de = proc_create("msdc_debug", 0667, NULL, &msdc_debug_fops);
|
||||
|
||||
if (!de || IS_ERR(de))
|
||||
printk("!! Create MSDC debug PROC fail !!\n");
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(msdc_debug_proc_init);
|
||||
#endif
|
156
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.h
Normal file
156
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/dbg.h
Normal file
@ -0,0 +1,156 @@
|
||||
/* Copyright Statement:
|
||||
*
|
||||
* This software/firmware and related documentation ("MediaTek Software") are
|
||||
* protected under relevant copyright laws. The information contained herein
|
||||
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
|
||||
* Without the prior written permission of MediaTek inc. and/or its licensors,
|
||||
* any reproduction, modification, use or disclosure of MediaTek Software,
|
||||
* and information contained herein, in whole or in part, shall be strictly prohibited.
|
||||
*
|
||||
* MediaTek Inc. (C) 2010. All rights reserved.
|
||||
*
|
||||
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
|
||||
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
|
||||
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
|
||||
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
|
||||
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
|
||||
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
|
||||
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
|
||||
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
|
||||
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
|
||||
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
|
||||
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
|
||||
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
|
||||
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
|
||||
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
|
||||
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
|
||||
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
|
||||
*
|
||||
* The following software/firmware and/or related documentation ("MediaTek Software")
|
||||
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
|
||||
* applicable license agreements with MediaTek Inc.
|
||||
*/
|
||||
#ifndef __MT_MSDC_DEUBG__
|
||||
#define __MT_MSDC_DEUBG__
|
||||
|
||||
//==========================
|
||||
extern u32 sdio_pro_enable;
|
||||
/* for a type command, e.g. CMD53, 2 blocks */
|
||||
struct cmd_profile {
|
||||
u32 max_tc; /* Max tick count */
|
||||
u32 min_tc;
|
||||
u32 tot_tc; /* total tick count */
|
||||
u32 tot_bytes;
|
||||
u32 count; /* the counts of the command */
|
||||
};
|
||||
|
||||
/* dump when total_tc and total_bytes */
|
||||
struct sdio_profile {
|
||||
u32 total_tc; /* total tick count of CMD52 and CMD53 */
|
||||
u32 total_tx_bytes; /* total bytes of CMD53 Tx */
|
||||
u32 total_rx_bytes; /* total bytes of CMD53 Rx */
|
||||
|
||||
/*CMD52*/
|
||||
struct cmd_profile cmd52_tx;
|
||||
struct cmd_profile cmd52_rx;
|
||||
|
||||
/*CMD53 in byte unit */
|
||||
struct cmd_profile cmd53_tx_byte[512];
|
||||
struct cmd_profile cmd53_rx_byte[512];
|
||||
|
||||
/*CMD53 in block unit */
|
||||
struct cmd_profile cmd53_tx_blk[100];
|
||||
struct cmd_profile cmd53_rx_blk[100];
|
||||
};
|
||||
|
||||
//==========================
|
||||
typedef enum {
|
||||
SD_TOOL_ZONE = 0,
|
||||
SD_TOOL_DMA_SIZE = 1,
|
||||
SD_TOOL_PM_ENABLE = 2,
|
||||
SD_TOOL_SDIO_PROFILE = 3,
|
||||
} msdc_dbg;
|
||||
|
||||
typedef enum {
|
||||
MODE_PIO = 0,
|
||||
MODE_DMA = 1,
|
||||
MODE_SIZE_DEP = 2,
|
||||
} msdc_mode;
|
||||
extern msdc_mode drv_mode[4];
|
||||
extern u32 dma_size[4];
|
||||
|
||||
/* Debug message event */
|
||||
#define DBG_EVT_NONE (0) /* No event */
|
||||
#define DBG_EVT_DMA (1 << 0) /* DMA related event */
|
||||
#define DBG_EVT_CMD (1 << 1) /* MSDC CMD related event */
|
||||
#define DBG_EVT_RSP (1 << 2) /* MSDC CMD RSP related event */
|
||||
#define DBG_EVT_INT (1 << 3) /* MSDC INT event */
|
||||
#define DBG_EVT_CFG (1 << 4) /* MSDC CFG event */
|
||||
#define DBG_EVT_FUC (1 << 5) /* Function event */
|
||||
#define DBG_EVT_OPS (1 << 6) /* Read/Write operation event */
|
||||
#define DBG_EVT_FIO (1 << 7) /* FIFO operation event */
|
||||
#define DBG_EVT_WRN (1 << 8) /* Warning event */
|
||||
#define DBG_EVT_PWR (1 << 9) /* Power event */
|
||||
#define DBG_EVT_ALL (0xffffffff)
|
||||
|
||||
#define DBG_EVT_MASK (DBG_EVT_ALL)
|
||||
|
||||
extern unsigned int sd_debug_zone[4];
|
||||
#define TAG "msdc"
|
||||
#if 0 /* +++ chhung */
|
||||
#define BUG_ON(x) \
|
||||
do { \
|
||||
if (x) { \
|
||||
printk("[BUG] %s LINE:%d FILE:%s\n", #x, __LINE__, __FILE__); \
|
||||
while(1); \
|
||||
} \
|
||||
}while(0)
|
||||
#endif /* end of +++ */
|
||||
|
||||
#define N_MSG(evt, fmt, args...)
|
||||
/*
|
||||
do { \
|
||||
if ((DBG_EVT_##evt) & sd_debug_zone[host->id]) { \
|
||||
printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
|
||||
host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \
|
||||
} \
|
||||
} while(0)
|
||||
*/
|
||||
|
||||
#define ERR_MSG(fmt, args...) \
|
||||
do { \
|
||||
printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
|
||||
host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \
|
||||
} while(0);
|
||||
|
||||
#if 1
|
||||
//defined CONFIG_MTK_MMC_CD_POLL
|
||||
#define INIT_MSG(fmt, args...)
|
||||
#define IRQ_MSG(fmt, args...)
|
||||
#else
|
||||
#define INIT_MSG(fmt, args...) \
|
||||
do { \
|
||||
printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
|
||||
host->id, ##args , __FUNCTION__, __LINE__, current->comm, current->pid); \
|
||||
} while(0);
|
||||
|
||||
/* PID in ISR in not corrent */
|
||||
#define IRQ_MSG(fmt, args...) \
|
||||
do { \
|
||||
printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \
|
||||
host->id, ##args , __FUNCTION__, __LINE__); \
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
int msdc_debug_proc_init(void);
|
||||
|
||||
#if 0 /* --- chhung */
|
||||
void msdc_init_gpt(void);
|
||||
extern void GPT_GetCounter64(UINT32 *cntL32, UINT32 *cntH32);
|
||||
#endif /* end of --- */
|
||||
u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32);
|
||||
void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks);
|
||||
|
||||
#endif
|
1002
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/mt6575_sd.h
Normal file
1002
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/mt6575_sd.h
Normal file
File diff suppressed because it is too large
Load Diff
3056
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/sd.c
Normal file
3056
target/linux/ramips/files-4.14/drivers/mmc/host/mtk-mmc/sd.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,70 @@
|
||||
config NET_VENDOR_MEDIATEK
|
||||
tristate "Mediatek/Ralink ethernet driver"
|
||||
depends on RALINK
|
||||
help
|
||||
This driver supports the ethernet mac inside the Mediatek and Ralink WiSoCs
|
||||
|
||||
config NET_MEDIATEK_SOC
|
||||
def_tristate NET_VENDOR_MEDIATEK
|
||||
|
||||
if NET_MEDIATEK_SOC
|
||||
choice
|
||||
prompt "MAC type"
|
||||
|
||||
config NET_MEDIATEK_RT2880
|
||||
bool "RT2882"
|
||||
depends on MIPS && SOC_RT288X
|
||||
|
||||
config NET_MEDIATEK_RT3050
|
||||
bool "RT3050/MT7628"
|
||||
depends on MIPS && (SOC_RT305X || SOC_MT7620)
|
||||
|
||||
config NET_MEDIATEK_RT3883
|
||||
bool "RT3883"
|
||||
depends on MIPS && SOC_RT3883
|
||||
|
||||
config NET_MEDIATEK_MT7620
|
||||
bool "MT7620"
|
||||
depends on MIPS && SOC_MT7620
|
||||
|
||||
config NET_MEDIATEK_MT7621
|
||||
bool "MT7621"
|
||||
depends on MIPS && SOC_MT7621
|
||||
|
||||
endchoice
|
||||
|
||||
config NET_MEDIATEK_OFFLOAD
|
||||
def_bool NET_MEDIATEK_SOC
|
||||
depends on NET_MEDIATEK_MT7621
|
||||
|
||||
config NET_MEDIATEK_HW_QOS
|
||||
def_bool NET_MEDIATEK_SOC
|
||||
depends on NET_MEDIATEK_MT7623
|
||||
|
||||
config NET_MEDIATEK_MDIO
|
||||
def_bool NET_MEDIATEK_SOC
|
||||
depends on (NET_MEDIATEK_RT2880 || NET_MEDIATEK_RT3883 || NET_MEDIATEK_MT7620 || NET_MEDIATEK_MT7621)
|
||||
select PHYLIB
|
||||
|
||||
config NET_MEDIATEK_MDIO_RT2880
|
||||
def_bool NET_MEDIATEK_SOC
|
||||
depends on (NET_MEDIATEK_RT2880 || NET_MEDIATEK_RT3883)
|
||||
select NET_MEDIATEK_MDIO
|
||||
|
||||
config NET_MEDIATEK_MDIO_MT7620
|
||||
def_bool NET_MEDIATEK_SOC
|
||||
depends on (NET_MEDIATEK_MT7620 || NET_MEDIATEK_MT7621)
|
||||
select NET_MEDIATEK_MDIO
|
||||
|
||||
config NET_MEDIATEK_ESW_RT3050
|
||||
def_tristate NET_MEDIATEK_SOC
|
||||
depends on NET_MEDIATEK_RT3050
|
||||
|
||||
config NET_MEDIATEK_GSW_MT7620
|
||||
def_tristate NET_MEDIATEK_SOC
|
||||
depends on NET_MEDIATEK_MT7620
|
||||
|
||||
config NET_MEDIATEK_GSW_MT7621
|
||||
def_tristate NET_MEDIATEK_SOC
|
||||
depends on NET_MEDIATEK_MT7621
|
||||
endif
|
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Makefile for the Ralink SoCs built-in ethernet macs
|
||||
#
|
||||
|
||||
mtk-eth-soc-y += mtk_eth_soc.o ethtool.o
|
||||
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MDIO) += mdio.o
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MDIO_RT2880) += mdio_rt2880.o
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MDIO_MT7620) += mdio_mt7620.o
|
||||
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_OFFLOAD) += mtk_offload.o mtk_debugfs.o
|
||||
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_RT2880) += soc_rt2880.o
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_RT3050) += soc_rt3050.o
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_RT3883) += soc_rt3883.o
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MT7620) += soc_mt7620.o
|
||||
mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MT7621) += soc_mt7621.o
|
||||
|
||||
obj-$(CONFIG_NET_MEDIATEK_ESW_RT3050) += esw_rt3050.o
|
||||
obj-$(CONFIG_NET_MEDIATEK_GSW_MT7620) += gsw_mt7620.o mt7530.o
|
||||
obj-$(CONFIG_NET_MEDIATEK_GSW_MT7621) += gsw_mt7621.o mt7530.o
|
||||
obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk-eth-soc.o
|
1461
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/esw_rt3050.c
Normal file
1461
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/esw_rt3050.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,29 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _RALINK_ESW_RT3052_H__
|
||||
#define _RALINK_ESW_RT3052_H__
|
||||
|
||||
#ifdef CONFIG_NET_MEDIATEK_ESW_RT3052
|
||||
|
||||
int __init mtk_switch_init(void);
|
||||
void mtk_switch_exit(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline int __init mtk_switch_init(void) { return 0; }
|
||||
static inline void mtk_switch_exit(void) { }
|
||||
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,230 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
|
||||
static const char fe_gdma_str[][ETH_GSTRING_LEN] = {
|
||||
#define _FE(x...) # x,
|
||||
FE_STAT_REG_DECLARE
|
||||
#undef _FE
|
||||
};
|
||||
|
||||
static int fe_get_link_ksettings(struct net_device *ndev,
|
||||
struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(ndev);
|
||||
|
||||
if (!priv->phy_dev)
|
||||
return -ENODEV;
|
||||
|
||||
if (priv->phy_flags == FE_PHY_FLAG_ATTACH) {
|
||||
if (phy_read_status(priv->phy_dev))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
phy_ethtool_ksettings_get(ndev->phydev, cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fe_set_link_ksettings(struct net_device *ndev,
|
||||
const struct ethtool_link_ksettings *cmd)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(ndev);
|
||||
|
||||
if (!priv->phy_dev)
|
||||
goto out_sset;
|
||||
|
||||
if (cmd->base.phy_address != priv->phy_dev->mdio.addr) {
|
||||
if (priv->phy->phy_node[cmd->base.phy_address]) {
|
||||
priv->phy_dev = priv->phy->phy[cmd->base.phy_address];
|
||||
priv->phy_flags = FE_PHY_FLAG_PORT;
|
||||
} else if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, cmd->base.phy_address)) {
|
||||
priv->phy_dev = mdiobus_get_phy(priv->mii_bus, cmd->base.phy_address);
|
||||
priv->phy_flags = FE_PHY_FLAG_ATTACH;
|
||||
} else {
|
||||
goto out_sset;
|
||||
}
|
||||
}
|
||||
|
||||
return phy_ethtool_ksettings_set(ndev->phydev, cmd);
|
||||
|
||||
out_sset:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void fe_get_drvinfo(struct net_device *dev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
struct fe_soc_data *soc = priv->soc;
|
||||
|
||||
strlcpy(info->driver, priv->dev->driver->name, sizeof(info->driver));
|
||||
strlcpy(info->version, MTK_FE_DRV_VERSION, sizeof(info->version));
|
||||
strlcpy(info->bus_info, dev_name(priv->dev), sizeof(info->bus_info));
|
||||
|
||||
if (soc->reg_table[FE_REG_FE_COUNTER_BASE])
|
||||
info->n_stats = ARRAY_SIZE(fe_gdma_str);
|
||||
}
|
||||
|
||||
static u32 fe_get_msglevel(struct net_device *dev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
return priv->msg_enable;
|
||||
}
|
||||
|
||||
static void fe_set_msglevel(struct net_device *dev, u32 value)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
priv->msg_enable = value;
|
||||
}
|
||||
|
||||
static int fe_nway_reset(struct net_device *dev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
if (!priv->phy_dev)
|
||||
goto out_nway_reset;
|
||||
|
||||
return genphy_restart_aneg(priv->phy_dev);
|
||||
|
||||
out_nway_reset:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static u32 fe_get_link(struct net_device *dev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
if (!priv->phy_dev)
|
||||
goto out_get_link;
|
||||
|
||||
if (priv->phy_flags == FE_PHY_FLAG_ATTACH) {
|
||||
err = genphy_update_link(priv->phy_dev);
|
||||
if (err)
|
||||
goto out_get_link;
|
||||
}
|
||||
|
||||
return priv->phy_dev->link;
|
||||
|
||||
out_get_link:
|
||||
return ethtool_op_get_link(dev);
|
||||
}
|
||||
|
||||
static int fe_set_ringparam(struct net_device *dev,
|
||||
struct ethtool_ringparam *ring)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
if ((ring->tx_pending < 2) ||
|
||||
(ring->rx_pending < 2) ||
|
||||
(ring->rx_pending > MAX_DMA_DESC) ||
|
||||
(ring->tx_pending > MAX_DMA_DESC))
|
||||
return -EINVAL;
|
||||
|
||||
dev->netdev_ops->ndo_stop(dev);
|
||||
|
||||
priv->tx_ring.tx_ring_size = BIT(fls(ring->tx_pending) - 1);
|
||||
priv->rx_ring.rx_ring_size = BIT(fls(ring->rx_pending) - 1);
|
||||
|
||||
dev->netdev_ops->ndo_open(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fe_get_ringparam(struct net_device *dev,
|
||||
struct ethtool_ringparam *ring)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
|
||||
ring->rx_max_pending = MAX_DMA_DESC;
|
||||
ring->tx_max_pending = MAX_DMA_DESC;
|
||||
ring->rx_pending = priv->rx_ring.rx_ring_size;
|
||||
ring->tx_pending = priv->tx_ring.tx_ring_size;
|
||||
}
|
||||
|
||||
static void fe_get_strings(struct net_device *dev, u32 stringset, u8 *data)
|
||||
{
|
||||
switch (stringset) {
|
||||
case ETH_SS_STATS:
|
||||
memcpy(data, *fe_gdma_str, sizeof(fe_gdma_str));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int fe_get_sset_count(struct net_device *dev, int sset)
|
||||
{
|
||||
switch (sset) {
|
||||
case ETH_SS_STATS:
|
||||
return ARRAY_SIZE(fe_gdma_str);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static void fe_get_ethtool_stats(struct net_device *dev,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
struct fe_hw_stats *hwstats = priv->hw_stats;
|
||||
u64 *data_src, *data_dst;
|
||||
unsigned int start;
|
||||
int i;
|
||||
|
||||
if (netif_running(dev) && netif_device_present(dev)) {
|
||||
if (spin_trylock(&hwstats->stats_lock)) {
|
||||
fe_stats_update(priv);
|
||||
spin_unlock(&hwstats->stats_lock);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
data_src = &hwstats->tx_bytes;
|
||||
data_dst = data;
|
||||
start = u64_stats_fetch_begin_irq(&hwstats->syncp);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fe_gdma_str); i++)
|
||||
*data_dst++ = *data_src++;
|
||||
|
||||
} while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
|
||||
}
|
||||
|
||||
static struct ethtool_ops fe_ethtool_ops = {
|
||||
.get_link_ksettings = fe_get_link_ksettings,
|
||||
.set_link_ksettings = fe_set_link_ksettings,
|
||||
.get_drvinfo = fe_get_drvinfo,
|
||||
.get_msglevel = fe_get_msglevel,
|
||||
.set_msglevel = fe_set_msglevel,
|
||||
.nway_reset = fe_nway_reset,
|
||||
.get_link = fe_get_link,
|
||||
.set_ringparam = fe_set_ringparam,
|
||||
.get_ringparam = fe_get_ringparam,
|
||||
};
|
||||
|
||||
void fe_set_ethtool_ops(struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
struct fe_soc_data *soc = priv->soc;
|
||||
|
||||
if (soc->reg_table[FE_REG_FE_COUNTER_BASE]) {
|
||||
fe_ethtool_ops.get_strings = fe_get_strings;
|
||||
fe_ethtool_ops.get_sset_count = fe_get_sset_count;
|
||||
fe_ethtool_ops.get_ethtool_stats = fe_get_ethtool_stats;
|
||||
}
|
||||
|
||||
netdev->ethtool_ops = &fe_ethtool_ops;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef FE_ETHTOOL_H
|
||||
#define FE_ETHTOOL_H
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
void fe_set_ethtool_ops(struct net_device *netdev);
|
||||
|
||||
#endif /* FE_ETHTOOL_H */
|
@ -0,0 +1,260 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <ralink_regs.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "gsw_mt7620.h"
|
||||
|
||||
void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg)
|
||||
{
|
||||
iowrite32(val, gsw->base + reg);
|
||||
}
|
||||
|
||||
u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg)
|
||||
{
|
||||
return ioread32(gsw->base + reg);
|
||||
}
|
||||
|
||||
static irqreturn_t gsw_interrupt_mt7620(int irq, void *_priv)
|
||||
{
|
||||
struct fe_priv *priv = (struct fe_priv *)_priv;
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
u32 status;
|
||||
int i, max = (gsw->port4 == PORT4_EPHY) ? (4) : (3);
|
||||
|
||||
status = mtk_switch_r32(gsw, GSW_REG_ISR);
|
||||
if (status & PORT_IRQ_ST_CHG)
|
||||
for (i = 0; i <= max; i++) {
|
||||
u32 status = mtk_switch_r32(gsw, GSW_REG_PORT_STATUS(i));
|
||||
int link = status & 0x1;
|
||||
|
||||
if (link != priv->link[i])
|
||||
mt7620_print_link_state(priv, i, link,
|
||||
(status >> 2) & 3,
|
||||
(status & 0x2));
|
||||
|
||||
priv->link[i] = link;
|
||||
}
|
||||
mt7620_handle_carrier(priv);
|
||||
mtk_switch_w32(gsw, status, GSW_REG_ISR);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void mt7620_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
|
||||
{
|
||||
u32 is_BGA = (rt_sysc_r32(0x0c) >> 16) & 1;
|
||||
|
||||
rt_sysc_w32(rt_sysc_r32(SYSC_REG_CFG1) | BIT(8), SYSC_REG_CFG1);
|
||||
mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_CKGCR) & ~(0x3 << 4), GSW_REG_CKGCR);
|
||||
|
||||
/* Enable MIB stats */
|
||||
mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_MIB_CNT_EN) | (1 << 1), GSW_REG_MIB_CNT_EN);
|
||||
|
||||
if (of_property_read_bool(np, "mediatek,mt7530")) {
|
||||
u32 val;
|
||||
|
||||
/* turn off ephy and set phy base addr to 12 */
|
||||
mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_GPC1) |
|
||||
(0x1f << 24) | (0xc << 16),
|
||||
GSW_REG_GPC1);
|
||||
|
||||
/* set MT7530 central align */
|
||||
val = mt7530_mdio_r32(gsw, 0x7830);
|
||||
val &= ~BIT(0);
|
||||
val |= BIT(1);
|
||||
mt7530_mdio_w32(gsw, 0x7830, val);
|
||||
|
||||
val = mt7530_mdio_r32(gsw, 0x7a40);
|
||||
val &= ~BIT(30);
|
||||
mt7530_mdio_w32(gsw, 0x7a40, val);
|
||||
|
||||
mt7530_mdio_w32(gsw, 0x7a78, 0x855);
|
||||
} else {
|
||||
/* global page 4 */
|
||||
_mt7620_mii_write(gsw, 1, 31, 0x4000);
|
||||
|
||||
_mt7620_mii_write(gsw, 1, 17, 0x7444);
|
||||
if (is_BGA)
|
||||
_mt7620_mii_write(gsw, 1, 19, 0x0114);
|
||||
else
|
||||
_mt7620_mii_write(gsw, 1, 19, 0x0117);
|
||||
|
||||
_mt7620_mii_write(gsw, 1, 22, 0x10cf);
|
||||
_mt7620_mii_write(gsw, 1, 25, 0x6212);
|
||||
_mt7620_mii_write(gsw, 1, 26, 0x0777);
|
||||
_mt7620_mii_write(gsw, 1, 29, 0x4000);
|
||||
_mt7620_mii_write(gsw, 1, 28, 0xc077);
|
||||
_mt7620_mii_write(gsw, 1, 24, 0x0000);
|
||||
|
||||
/* global page 3 */
|
||||
_mt7620_mii_write(gsw, 1, 31, 0x3000);
|
||||
_mt7620_mii_write(gsw, 1, 17, 0x4838);
|
||||
|
||||
/* global page 2 */
|
||||
_mt7620_mii_write(gsw, 1, 31, 0x2000);
|
||||
if (is_BGA) {
|
||||
_mt7620_mii_write(gsw, 1, 21, 0x0515);
|
||||
_mt7620_mii_write(gsw, 1, 22, 0x0053);
|
||||
_mt7620_mii_write(gsw, 1, 23, 0x00bf);
|
||||
_mt7620_mii_write(gsw, 1, 24, 0x0aaf);
|
||||
_mt7620_mii_write(gsw, 1, 25, 0x0fad);
|
||||
_mt7620_mii_write(gsw, 1, 26, 0x0fc1);
|
||||
} else {
|
||||
_mt7620_mii_write(gsw, 1, 21, 0x0517);
|
||||
_mt7620_mii_write(gsw, 1, 22, 0x0fd2);
|
||||
_mt7620_mii_write(gsw, 1, 23, 0x00bf);
|
||||
_mt7620_mii_write(gsw, 1, 24, 0x0aab);
|
||||
_mt7620_mii_write(gsw, 1, 25, 0x00ae);
|
||||
_mt7620_mii_write(gsw, 1, 26, 0x0fff);
|
||||
}
|
||||
/* global page 1 */
|
||||
_mt7620_mii_write(gsw, 1, 31, 0x1000);
|
||||
_mt7620_mii_write(gsw, 1, 17, 0xe7f8);
|
||||
}
|
||||
|
||||
/* global page 0 */
|
||||
_mt7620_mii_write(gsw, 1, 31, 0x8000);
|
||||
_mt7620_mii_write(gsw, 0, 30, 0xa000);
|
||||
_mt7620_mii_write(gsw, 1, 30, 0xa000);
|
||||
_mt7620_mii_write(gsw, 2, 30, 0xa000);
|
||||
_mt7620_mii_write(gsw, 3, 30, 0xa000);
|
||||
|
||||
_mt7620_mii_write(gsw, 0, 4, 0x05e1);
|
||||
_mt7620_mii_write(gsw, 1, 4, 0x05e1);
|
||||
_mt7620_mii_write(gsw, 2, 4, 0x05e1);
|
||||
_mt7620_mii_write(gsw, 3, 4, 0x05e1);
|
||||
|
||||
/* global page 2 */
|
||||
_mt7620_mii_write(gsw, 1, 31, 0xa000);
|
||||
_mt7620_mii_write(gsw, 0, 16, 0x1111);
|
||||
_mt7620_mii_write(gsw, 1, 16, 0x1010);
|
||||
_mt7620_mii_write(gsw, 2, 16, 0x1515);
|
||||
_mt7620_mii_write(gsw, 3, 16, 0x0f0f);
|
||||
|
||||
/* CPU Port6 Force Link 1G, FC ON */
|
||||
mtk_switch_w32(gsw, 0x5e33b, GSW_REG_PORT_PMCR(6));
|
||||
|
||||
/* Set Port 6 as CPU Port */
|
||||
mtk_switch_w32(gsw, 0x7f7f7fe0, 0x0010);
|
||||
|
||||
/* setup port 4 */
|
||||
if (gsw->port4 == PORT4_EPHY) {
|
||||
u32 val = rt_sysc_r32(SYSC_REG_CFG1);
|
||||
|
||||
val |= 3 << 14;
|
||||
rt_sysc_w32(val, SYSC_REG_CFG1);
|
||||
_mt7620_mii_write(gsw, 4, 30, 0xa000);
|
||||
_mt7620_mii_write(gsw, 4, 4, 0x05e1);
|
||||
_mt7620_mii_write(gsw, 4, 16, 0x1313);
|
||||
_mt7620_mii_write(gsw, 4, 0, 0x3100);
|
||||
pr_info("gsw: setting port4 to ephy mode\n");
|
||||
}
|
||||
}
|
||||
|
||||
static const struct of_device_id mediatek_gsw_match[] = {
|
||||
{ .compatible = "mediatek,mt7620-gsw" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mediatek_gsw_match);
|
||||
|
||||
int mtk_gsw_init(struct fe_priv *priv)
|
||||
{
|
||||
struct device_node *np = priv->switch_np;
|
||||
struct platform_device *pdev = of_find_device_by_node(np);
|
||||
struct mt7620_gsw *gsw;
|
||||
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!of_device_is_compatible(np, mediatek_gsw_match->compatible))
|
||||
return -EINVAL;
|
||||
|
||||
gsw = platform_get_drvdata(pdev);
|
||||
priv->soc->swpriv = gsw;
|
||||
|
||||
mt7620_hw_init(gsw, np);
|
||||
|
||||
if (gsw->irq) {
|
||||
request_irq(gsw->irq, gsw_interrupt_mt7620, 0,
|
||||
"gsw", priv);
|
||||
mtk_switch_w32(gsw, ~PORT_IRQ_ST_CHG, GSW_REG_IMR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7620_gsw_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
const char *port4 = NULL;
|
||||
struct mt7620_gsw *gsw;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
gsw = devm_kzalloc(&pdev->dev, sizeof(struct mt7620_gsw), GFP_KERNEL);
|
||||
if (!gsw)
|
||||
return -ENOMEM;
|
||||
|
||||
gsw->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (!gsw->base)
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
gsw->dev = &pdev->dev;
|
||||
|
||||
of_property_read_string(np, "mediatek,port4", &port4);
|
||||
if (port4 && !strcmp(port4, "ephy"))
|
||||
gsw->port4 = PORT4_EPHY;
|
||||
else if (port4 && !strcmp(port4, "gmac"))
|
||||
gsw->port4 = PORT4_EXT;
|
||||
else
|
||||
gsw->port4 = PORT4_EPHY;
|
||||
|
||||
gsw->irq = platform_get_irq(pdev, 0);
|
||||
|
||||
platform_set_drvdata(pdev, gsw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7620_gsw_remove(struct platform_device *pdev)
|
||||
{
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver gsw_driver = {
|
||||
.probe = mt7620_gsw_probe,
|
||||
.remove = mt7620_gsw_remove,
|
||||
.driver = {
|
||||
.name = "mt7620-gsw",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mediatek_gsw_match,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(gsw_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
MODULE_DESCRIPTION("GBit switch driver for Mediatek MT7620 SoC");
|
||||
MODULE_VERSION(MTK_FE_DRV_VERSION);
|
@ -0,0 +1,127 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _RALINK_GSW_MT7620_H__
|
||||
#define _RALINK_GSW_MT7620_H__
|
||||
|
||||
#define GSW_REG_PHY_TIMEOUT (5 * HZ)
|
||||
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
#define MT7620A_GSW_REG_PIAC 0x0004
|
||||
#else
|
||||
#define MT7620A_GSW_REG_PIAC 0x7004
|
||||
#endif
|
||||
|
||||
#define GSW_NUM_VLANS 16
|
||||
#define GSW_NUM_VIDS 4096
|
||||
#define GSW_NUM_PORTS 7
|
||||
#define GSW_PORT6 6
|
||||
|
||||
#define GSW_MDIO_ACCESS BIT(31)
|
||||
#define GSW_MDIO_READ BIT(19)
|
||||
#define GSW_MDIO_WRITE BIT(18)
|
||||
#define GSW_MDIO_START BIT(16)
|
||||
#define GSW_MDIO_ADDR_SHIFT 20
|
||||
#define GSW_MDIO_REG_SHIFT 25
|
||||
|
||||
#define GSW_REG_MIB_CNT_EN 0x4000
|
||||
|
||||
#define GSW_REG_PORT_PMCR(x) (0x3000 + (x * 0x100))
|
||||
#define GSW_REG_PORT_STATUS(x) (0x3008 + (x * 0x100))
|
||||
#define GSW_REG_SMACCR0 0x3fE4
|
||||
#define GSW_REG_SMACCR1 0x3fE8
|
||||
#define GSW_REG_CKGCR 0x3ff0
|
||||
|
||||
#define GSW_REG_IMR 0x7008
|
||||
#define GSW_REG_ISR 0x700c
|
||||
#define GSW_REG_GPC1 0x7014
|
||||
|
||||
#define GSW_REG_MAC_P0_MCR 0x100
|
||||
#define GSW_REG_MAC_P1_MCR 0x200
|
||||
|
||||
// Global MAC control register
|
||||
#define GSW_REG_GMACCR 0x30E0
|
||||
|
||||
#define SYSC_REG_CHIP_REV_ID 0x0c
|
||||
#define SYSC_REG_CFG1 0x14
|
||||
#define RST_CTRL_MCM BIT(2)
|
||||
#define SYSC_PAD_RGMII2_MDIO 0x58
|
||||
#define SYSC_GPIO_MODE 0x60
|
||||
|
||||
#define PORT_IRQ_ST_CHG 0x7f
|
||||
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
#define ESW_PHY_POLLING 0x0000
|
||||
#else
|
||||
#define ESW_PHY_POLLING 0x7000
|
||||
#endif
|
||||
|
||||
#define PMCR_IPG BIT(18)
|
||||
#define PMCR_MAC_MODE BIT(16)
|
||||
#define PMCR_FORCE BIT(15)
|
||||
#define PMCR_TX_EN BIT(14)
|
||||
#define PMCR_RX_EN BIT(13)
|
||||
#define PMCR_BACKOFF BIT(9)
|
||||
#define PMCR_BACKPRES BIT(8)
|
||||
#define PMCR_RX_FC BIT(5)
|
||||
#define PMCR_TX_FC BIT(4)
|
||||
#define PMCR_SPEED(_x) (_x << 2)
|
||||
#define PMCR_DUPLEX BIT(1)
|
||||
#define PMCR_LINK BIT(0)
|
||||
|
||||
#define PHY_AN_EN BIT(31)
|
||||
#define PHY_PRE_EN BIT(30)
|
||||
#define PMY_MDC_CONF(_x) ((_x & 0x3f) << 24)
|
||||
|
||||
|
||||
enum {
|
||||
/* Global attributes. */
|
||||
GSW_ATTR_ENABLE_VLAN,
|
||||
/* Port attributes. */
|
||||
GSW_ATTR_PORT_UNTAG,
|
||||
};
|
||||
|
||||
enum {
|
||||
PORT4_EPHY = 0,
|
||||
PORT4_EXT,
|
||||
};
|
||||
|
||||
struct mt7620_gsw {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
int port4;
|
||||
unsigned long int autopoll;
|
||||
};
|
||||
|
||||
void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg);
|
||||
u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg);
|
||||
int mtk_gsw_init(struct fe_priv *priv);
|
||||
|
||||
int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
|
||||
int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
|
||||
void mt7620_mdio_link_adjust(struct fe_priv *priv, int port);
|
||||
int mt7620_has_carrier(struct fe_priv *priv);
|
||||
void mt7620_print_link_state(struct fe_priv *priv, int port, int link,
|
||||
int speed, int duplex);
|
||||
|
||||
void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val);
|
||||
u32 mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg);
|
||||
|
||||
u32 _mt7620_mii_write(struct mt7620_gsw *gsw, u32 phy_addr,
|
||||
u32 phy_register, u32 write_data);
|
||||
u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg);
|
||||
void mt7620_handle_carrier(struct fe_priv *priv);
|
||||
|
||||
#endif
|
@ -0,0 +1,281 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <ralink_regs.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "gsw_mt7620.h"
|
||||
|
||||
void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg)
|
||||
{
|
||||
iowrite32(val, gsw->base + reg);
|
||||
}
|
||||
|
||||
u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg)
|
||||
{
|
||||
return ioread32(gsw->base + reg);
|
||||
}
|
||||
|
||||
static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv)
|
||||
{
|
||||
struct fe_priv *priv = (struct fe_priv *)_priv;
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
u32 reg, i;
|
||||
|
||||
reg = mt7530_mdio_r32(gsw, 0x700c);
|
||||
mt7530_mdio_w32(gsw, 0x700c, reg);
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
if (reg & BIT(i)) {
|
||||
unsigned int link;
|
||||
|
||||
link = mt7530_mdio_r32(gsw,
|
||||
0x3008 + (i * 0x100)) & 0x1;
|
||||
|
||||
if (link != priv->link[i]) {
|
||||
priv->link[i] = link;
|
||||
if (link)
|
||||
netdev_info(priv->netdev,
|
||||
"port %d link up\n", i);
|
||||
else
|
||||
netdev_info(priv->netdev,
|
||||
"port %d link down\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
mt7620_handle_carrier(priv);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
|
||||
{
|
||||
u32 i;
|
||||
u32 val;
|
||||
|
||||
/* wardware reset the switch */
|
||||
fe_reset(RST_CTRL_MCM);
|
||||
mdelay(10);
|
||||
|
||||
/* reduce RGMII2 PAD driving strength */
|
||||
rt_sysc_m32(3 << 4, 0, SYSC_PAD_RGMII2_MDIO);
|
||||
|
||||
/* gpio mux - RGMII1=Normal mode */
|
||||
rt_sysc_m32(BIT(14), 0, SYSC_GPIO_MODE);
|
||||
|
||||
/* set GMAC1 RGMII mode */
|
||||
rt_sysc_m32(3 << 12, 0, SYSC_REG_CFG1);
|
||||
|
||||
/* enable MDIO to control MT7530 */
|
||||
rt_sysc_m32(3 << 12, 0, SYSC_GPIO_MODE);
|
||||
|
||||
/* turn off all PHYs */
|
||||
for (i = 0; i <= 4; i++) {
|
||||
val = _mt7620_mii_read(gsw, i, 0x0);
|
||||
val |= BIT(11);
|
||||
_mt7620_mii_write(gsw, i, 0x0, val);
|
||||
}
|
||||
|
||||
/* reset the switch */
|
||||
mt7530_mdio_w32(gsw, 0x7000, 0x3);
|
||||
usleep_range(10, 20);
|
||||
|
||||
if ((rt_sysc_r32(SYSC_REG_CHIP_REV_ID) & 0xFFFF) == 0x0101) {
|
||||
/* (GE1, Force 1000M/FD, FC ON, MAX_RX_LENGTH 1536) */
|
||||
mtk_switch_w32(gsw, 0x2305e30b, GSW_REG_MAC_P0_MCR);
|
||||
mt7530_mdio_w32(gsw, 0x3600, 0x5e30b);
|
||||
} else {
|
||||
/* (GE1, Force 1000M/FD, FC ON, MAX_RX_LENGTH 1536) */
|
||||
mtk_switch_w32(gsw, 0x2305e33b, GSW_REG_MAC_P0_MCR);
|
||||
mt7530_mdio_w32(gsw, 0x3600, 0x5e33b);
|
||||
}
|
||||
|
||||
/* (GE2, Link down) */
|
||||
mtk_switch_w32(gsw, 0x8000, GSW_REG_MAC_P1_MCR);
|
||||
|
||||
/* Set switch max RX frame length to 2k */
|
||||
mt7530_mdio_w32(gsw, GSW_REG_GMACCR, 0x3F0B);
|
||||
|
||||
/* Enable Port 6, P5 as GMAC5, P5 disable */
|
||||
val = mt7530_mdio_r32(gsw, 0x7804);
|
||||
val &= ~BIT(8);
|
||||
val |= BIT(6) | BIT(13) | BIT(16);
|
||||
mt7530_mdio_w32(gsw, 0x7804, val);
|
||||
|
||||
val = rt_sysc_r32(0x10);
|
||||
val = (val >> 6) & 0x7;
|
||||
if (val >= 6) {
|
||||
/* 25Mhz Xtal - do nothing */
|
||||
} else if (val >= 3) {
|
||||
/* 40Mhz */
|
||||
|
||||
/* disable MT7530 core clock */
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x1f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x410);
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x401f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x0);
|
||||
|
||||
/* disable MT7530 PLL */
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x1f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x40d);
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x401f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x2020);
|
||||
|
||||
/* for MT7530 core clock = 500Mhz */
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x1f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x40e);
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x401f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x119);
|
||||
|
||||
/* enable MT7530 PLL */
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x1f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x40d);
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x401f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x2820);
|
||||
|
||||
usleep_range(20, 40);
|
||||
|
||||
/* enable MT7530 core clock */
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x1f);
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x410);
|
||||
_mt7620_mii_write(gsw, 0, 13, 0x401f);
|
||||
} else {
|
||||
/* 20Mhz Xtal - TODO */
|
||||
}
|
||||
|
||||
/* RGMII */
|
||||
_mt7620_mii_write(gsw, 0, 14, 0x1);
|
||||
|
||||
/* set MT7530 central align */
|
||||
val = mt7530_mdio_r32(gsw, 0x7830);
|
||||
val &= ~BIT(0);
|
||||
val |= BIT(1);
|
||||
mt7530_mdio_w32(gsw, 0x7830, val);
|
||||
val = mt7530_mdio_r32(gsw, 0x7a40);
|
||||
val &= ~BIT(30);
|
||||
mt7530_mdio_w32(gsw, 0x7a40, val);
|
||||
mt7530_mdio_w32(gsw, 0x7a78, 0x855);
|
||||
|
||||
/* delay setting for 10/1000M */
|
||||
mt7530_mdio_w32(gsw, 0x7b00, 0x102);
|
||||
mt7530_mdio_w32(gsw, 0x7b04, 0x14);
|
||||
|
||||
/* lower Tx Driving*/
|
||||
mt7530_mdio_w32(gsw, 0x7a54, 0x44);
|
||||
mt7530_mdio_w32(gsw, 0x7a5c, 0x44);
|
||||
mt7530_mdio_w32(gsw, 0x7a64, 0x44);
|
||||
mt7530_mdio_w32(gsw, 0x7a6c, 0x44);
|
||||
mt7530_mdio_w32(gsw, 0x7a74, 0x44);
|
||||
mt7530_mdio_w32(gsw, 0x7a7c, 0x44);
|
||||
|
||||
/* turn on all PHYs */
|
||||
for (i = 0; i <= 4; i++) {
|
||||
val = _mt7620_mii_read(gsw, i, 0);
|
||||
val &= ~BIT(11);
|
||||
_mt7620_mii_write(gsw, i, 0, val);
|
||||
}
|
||||
|
||||
/* enable irq */
|
||||
mt7530_mdio_w32(gsw, 0x7008, 0x1f);
|
||||
val = mt7530_mdio_r32(gsw, 0x7808);
|
||||
val |= 3 << 16;
|
||||
mt7530_mdio_w32(gsw, 0x7808, val);
|
||||
}
|
||||
|
||||
static const struct of_device_id mediatek_gsw_match[] = {
|
||||
{ .compatible = "mediatek,mt7621-gsw" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mediatek_gsw_match);
|
||||
|
||||
int mtk_gsw_init(struct fe_priv *priv)
|
||||
{
|
||||
struct device_node *np = priv->switch_np;
|
||||
struct platform_device *pdev = of_find_device_by_node(np);
|
||||
struct mt7620_gsw *gsw;
|
||||
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!of_device_is_compatible(np, mediatek_gsw_match->compatible))
|
||||
return -EINVAL;
|
||||
|
||||
gsw = platform_get_drvdata(pdev);
|
||||
priv->soc->swpriv = gsw;
|
||||
|
||||
if (gsw->irq) {
|
||||
request_irq(gsw->irq, gsw_interrupt_mt7621, 0,
|
||||
"gsw", priv);
|
||||
disable_irq(gsw->irq);
|
||||
}
|
||||
|
||||
mt7621_hw_init(gsw, np);
|
||||
|
||||
if (gsw->irq)
|
||||
enable_irq(gsw->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_gsw_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
struct mt7620_gsw *gsw;
|
||||
|
||||
gsw = devm_kzalloc(&pdev->dev, sizeof(struct mt7620_gsw), GFP_KERNEL);
|
||||
if (!gsw)
|
||||
return -ENOMEM;
|
||||
|
||||
gsw->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (!gsw->base)
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
gsw->dev = &pdev->dev;
|
||||
gsw->irq = platform_get_irq(pdev, 0);
|
||||
|
||||
platform_set_drvdata(pdev, gsw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_gsw_remove(struct platform_device *pdev)
|
||||
{
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver gsw_driver = {
|
||||
.probe = mt7621_gsw_probe,
|
||||
.remove = mt7621_gsw_remove,
|
||||
.driver = {
|
||||
.name = "mt7621-gsw",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mediatek_gsw_match,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(gsw_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
MODULE_DESCRIPTION("GBit switch driver for Mediatek MT7621 SoC");
|
||||
MODULE_VERSION(MTK_FE_DRV_VERSION);
|
259
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mdio.c
Normal file
259
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mdio.c
Normal file
@ -0,0 +1,259 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_mdio.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "mdio.h"
|
||||
|
||||
static int fe_mdio_reset(struct mii_bus *bus)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fe_phy_link_adjust(struct net_device *dev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&priv->phy->lock, flags);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (priv->phy->phy_node[i]) {
|
||||
struct phy_device *phydev = priv->phy->phy[i];
|
||||
int status_change = 0;
|
||||
|
||||
if (phydev->link)
|
||||
if (priv->phy->duplex[i] != phydev->duplex ||
|
||||
priv->phy->speed[i] != phydev->speed)
|
||||
status_change = 1;
|
||||
|
||||
if (phydev->link != priv->link[i])
|
||||
status_change = 1;
|
||||
|
||||
switch (phydev->speed) {
|
||||
case SPEED_1000:
|
||||
case SPEED_100:
|
||||
case SPEED_10:
|
||||
priv->link[i] = phydev->link;
|
||||
priv->phy->duplex[i] = phydev->duplex;
|
||||
priv->phy->speed[i] = phydev->speed;
|
||||
|
||||
if (status_change &&
|
||||
priv->soc->mdio_adjust_link)
|
||||
priv->soc->mdio_adjust_link(priv, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node)
|
||||
{
|
||||
const __be32 *_port = NULL;
|
||||
struct phy_device *phydev;
|
||||
int phy_mode, port;
|
||||
|
||||
_port = of_get_property(phy_node, "reg", NULL);
|
||||
|
||||
if (!_port || (be32_to_cpu(*_port) >= 0x20)) {
|
||||
pr_err("%s: invalid port id\n", phy_node->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
port = be32_to_cpu(*_port);
|
||||
phy_mode = of_get_phy_mode(phy_node);
|
||||
if (phy_mode < 0) {
|
||||
dev_err(priv->dev, "incorrect phy-mode %d\n", phy_mode);
|
||||
priv->phy->phy_node[port] = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
phydev = of_phy_connect(priv->netdev, phy_node, fe_phy_link_adjust,
|
||||
0, phy_mode);
|
||||
if (IS_ERR(phydev)) {
|
||||
dev_err(priv->dev, "could not connect to PHY\n");
|
||||
priv->phy->phy_node[port] = NULL;
|
||||
return PTR_ERR(phydev);
|
||||
}
|
||||
|
||||
phydev->supported &= PHY_GBIT_FEATURES;
|
||||
phydev->advertising = phydev->supported;
|
||||
phydev->no_auto_carrier_off = 1;
|
||||
|
||||
dev_info(priv->dev,
|
||||
"connected port %d to PHY at %s [uid=%08x, driver=%s]\n",
|
||||
port, dev_name(&phydev->mdio.dev), phydev->phy_id,
|
||||
phydev->drv->name);
|
||||
|
||||
priv->phy->phy[port] = phydev;
|
||||
priv->link[port] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void phy_init(struct fe_priv *priv, struct phy_device *phy)
|
||||
{
|
||||
phy_attach(priv->netdev, dev_name(&phy->mdio.dev), PHY_INTERFACE_MODE_MII);
|
||||
|
||||
phy->autoneg = AUTONEG_ENABLE;
|
||||
phy->speed = 0;
|
||||
phy->duplex = 0;
|
||||
phy->supported &= PHY_BASIC_FEATURES;
|
||||
phy->advertising = phy->supported | ADVERTISED_Autoneg;
|
||||
|
||||
phy_start_aneg(phy);
|
||||
}
|
||||
|
||||
static int fe_phy_connect(struct fe_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (priv->phy->phy_node[i]) {
|
||||
if (!priv->phy_dev) {
|
||||
priv->phy_dev = priv->phy->phy[i];
|
||||
priv->phy_flags = FE_PHY_FLAG_PORT;
|
||||
}
|
||||
} else if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, i)) {
|
||||
phy_init(priv, mdiobus_get_phy(priv->mii_bus, i));
|
||||
if (!priv->phy_dev) {
|
||||
priv->phy_dev = mdiobus_get_phy(priv->mii_bus, i);
|
||||
priv->phy_flags = FE_PHY_FLAG_ATTACH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fe_phy_disconnect(struct fe_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (priv->phy->phy_fixed[i]) {
|
||||
spin_lock_irqsave(&priv->phy->lock, flags);
|
||||
priv->link[i] = 0;
|
||||
if (priv->soc->mdio_adjust_link)
|
||||
priv->soc->mdio_adjust_link(priv, i);
|
||||
spin_unlock_irqrestore(&priv->phy->lock, flags);
|
||||
} else if (priv->phy->phy[i]) {
|
||||
phy_disconnect(priv->phy->phy[i]);
|
||||
} else if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, i)) {
|
||||
phy_detach(mdiobus_get_phy(priv->mii_bus, i));
|
||||
}
|
||||
}
|
||||
|
||||
static void fe_phy_start(struct fe_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (priv->phy->phy_fixed[i]) {
|
||||
spin_lock_irqsave(&priv->phy->lock, flags);
|
||||
priv->link[i] = 1;
|
||||
if (priv->soc->mdio_adjust_link)
|
||||
priv->soc->mdio_adjust_link(priv, i);
|
||||
spin_unlock_irqrestore(&priv->phy->lock, flags);
|
||||
} else if (priv->phy->phy[i]) {
|
||||
phy_start(priv->phy->phy[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fe_phy_stop(struct fe_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (priv->phy->phy_fixed[i]) {
|
||||
spin_lock_irqsave(&priv->phy->lock, flags);
|
||||
priv->link[i] = 0;
|
||||
if (priv->soc->mdio_adjust_link)
|
||||
priv->soc->mdio_adjust_link(priv, i);
|
||||
spin_unlock_irqrestore(&priv->phy->lock, flags);
|
||||
} else if (priv->phy->phy[i]) {
|
||||
phy_stop(priv->phy->phy[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static struct fe_phy phy_ralink = {
|
||||
.connect = fe_phy_connect,
|
||||
.disconnect = fe_phy_disconnect,
|
||||
.start = fe_phy_start,
|
||||
.stop = fe_phy_stop,
|
||||
};
|
||||
|
||||
int fe_mdio_init(struct fe_priv *priv)
|
||||
{
|
||||
struct device_node *mii_np;
|
||||
int err;
|
||||
|
||||
if (!priv->soc->mdio_read || !priv->soc->mdio_write)
|
||||
return 0;
|
||||
|
||||
spin_lock_init(&phy_ralink.lock);
|
||||
priv->phy = &phy_ralink;
|
||||
|
||||
mii_np = of_get_child_by_name(priv->dev->of_node, "mdio-bus");
|
||||
if (!mii_np) {
|
||||
dev_err(priv->dev, "no %s child node found", "mdio-bus");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(mii_np)) {
|
||||
err = 0;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
priv->mii_bus = mdiobus_alloc();
|
||||
if (!priv->mii_bus) {
|
||||
err = -ENOMEM;
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
priv->mii_bus->name = "mdio";
|
||||
priv->mii_bus->read = priv->soc->mdio_read;
|
||||
priv->mii_bus->write = priv->soc->mdio_write;
|
||||
priv->mii_bus->reset = fe_mdio_reset;
|
||||
priv->mii_bus->priv = priv;
|
||||
priv->mii_bus->parent = priv->dev;
|
||||
|
||||
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
|
||||
err = of_mdiobus_register(priv->mii_bus, mii_np);
|
||||
if (err)
|
||||
goto err_free_bus;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_bus:
|
||||
kfree(priv->mii_bus);
|
||||
err_put_node:
|
||||
of_node_put(mii_np);
|
||||
priv->mii_bus = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
void fe_mdio_cleanup(struct fe_priv *priv)
|
||||
{
|
||||
if (!priv->mii_bus)
|
||||
return;
|
||||
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
of_node_put(priv->mii_bus->dev.of_node);
|
||||
kfree(priv->mii_bus);
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _RALINK_MDIO_H__
|
||||
#define _RALINK_MDIO_H__
|
||||
|
||||
#ifdef CONFIG_NET_MEDIATEK_MDIO
|
||||
int fe_mdio_init(struct fe_priv *priv);
|
||||
void fe_mdio_cleanup(struct fe_priv *priv);
|
||||
int fe_connect_phy_node(struct fe_priv *priv,
|
||||
struct device_node *phy_node);
|
||||
#else
|
||||
static inline int fe_mdio_init(struct fe_priv *priv) { return 0; }
|
||||
static inline void fe_mdio_cleanup(struct fe_priv *priv) {}
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,168 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "gsw_mt7620.h"
|
||||
#include "mdio.h"
|
||||
|
||||
static int mt7620_mii_busy_wait(struct mt7620_gsw *gsw)
|
||||
{
|
||||
unsigned long t_start = jiffies;
|
||||
|
||||
while (1) {
|
||||
if (!(mtk_switch_r32(gsw, MT7620A_GSW_REG_PIAC) & GSW_MDIO_ACCESS))
|
||||
return 0;
|
||||
if (time_after(jiffies, t_start + GSW_REG_PHY_TIMEOUT))
|
||||
break;
|
||||
}
|
||||
|
||||
dev_err(gsw->dev, "mdio: MDIO timeout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 _mt7620_mii_write(struct mt7620_gsw *gsw, u32 phy_addr,
|
||||
u32 phy_register, u32 write_data)
|
||||
{
|
||||
if (mt7620_mii_busy_wait(gsw))
|
||||
return -1;
|
||||
|
||||
write_data &= 0xffff;
|
||||
|
||||
mtk_switch_w32(gsw, GSW_MDIO_ACCESS | GSW_MDIO_START | GSW_MDIO_WRITE |
|
||||
(phy_register << GSW_MDIO_REG_SHIFT) |
|
||||
(phy_addr << GSW_MDIO_ADDR_SHIFT) | write_data,
|
||||
MT7620A_GSW_REG_PIAC);
|
||||
|
||||
if (mt7620_mii_busy_wait(gsw))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg)
|
||||
{
|
||||
u32 d;
|
||||
|
||||
if (mt7620_mii_busy_wait(gsw))
|
||||
return 0xffff;
|
||||
|
||||
mtk_switch_w32(gsw, GSW_MDIO_ACCESS | GSW_MDIO_START | GSW_MDIO_READ |
|
||||
(phy_reg << GSW_MDIO_REG_SHIFT) |
|
||||
(phy_addr << GSW_MDIO_ADDR_SHIFT),
|
||||
MT7620A_GSW_REG_PIAC);
|
||||
|
||||
if (mt7620_mii_busy_wait(gsw))
|
||||
return 0xffff;
|
||||
|
||||
d = mtk_switch_r32(gsw, MT7620A_GSW_REG_PIAC) & 0xffff;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
|
||||
{
|
||||
struct fe_priv *priv = bus->priv;
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
|
||||
return _mt7620_mii_write(gsw, phy_addr, phy_reg, val);
|
||||
}
|
||||
|
||||
int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||
{
|
||||
struct fe_priv *priv = bus->priv;
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
|
||||
return _mt7620_mii_read(gsw, phy_addr, phy_reg);
|
||||
}
|
||||
|
||||
void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val)
|
||||
{
|
||||
_mt7620_mii_write(gsw, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
|
||||
_mt7620_mii_write(gsw, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
|
||||
_mt7620_mii_write(gsw, 0x1f, 0x10, val >> 16);
|
||||
}
|
||||
|
||||
u32 mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg)
|
||||
{
|
||||
u16 high, low;
|
||||
|
||||
_mt7620_mii_write(gsw, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
|
||||
low = _mt7620_mii_read(gsw, 0x1f, (reg >> 2) & 0xf);
|
||||
high = _mt7620_mii_read(gsw, 0x1f, 0x10);
|
||||
|
||||
return (high << 16) | (low & 0xffff);
|
||||
}
|
||||
|
||||
static unsigned char *fe_speed_str(int speed)
|
||||
{
|
||||
switch (speed) {
|
||||
case 2:
|
||||
case SPEED_1000:
|
||||
return "1000";
|
||||
case 1:
|
||||
case SPEED_100:
|
||||
return "100";
|
||||
case 0:
|
||||
case SPEED_10:
|
||||
return "10";
|
||||
}
|
||||
|
||||
return "? ";
|
||||
}
|
||||
|
||||
int mt7620_has_carrier(struct fe_priv *priv)
|
||||
{
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GSW_PORT6; i++)
|
||||
if (mtk_switch_r32(gsw, GSW_REG_PORT_STATUS(i)) & 0x1)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void mt7620_handle_carrier(struct fe_priv *priv)
|
||||
{
|
||||
if (!priv->phy)
|
||||
return;
|
||||
|
||||
if (mt7620_has_carrier(priv))
|
||||
netif_carrier_on(priv->netdev);
|
||||
else
|
||||
netif_carrier_off(priv->netdev);
|
||||
}
|
||||
|
||||
void mt7620_print_link_state(struct fe_priv *priv, int port, int link,
|
||||
int speed, int duplex)
|
||||
{
|
||||
if (link)
|
||||
netdev_info(priv->netdev, "port %d link up (%sMbps/%s duplex)\n",
|
||||
port, fe_speed_str(speed),
|
||||
(duplex) ? "Full" : "Half");
|
||||
else
|
||||
netdev_info(priv->netdev, "port %d link down\n", port);
|
||||
}
|
||||
|
||||
void mt7620_mdio_link_adjust(struct fe_priv *priv, int port)
|
||||
{
|
||||
mt7620_print_link_state(priv, port, priv->link[port],
|
||||
priv->phy->speed[port],
|
||||
(priv->phy->duplex[port] == DUPLEX_FULL));
|
||||
mt7620_handle_carrier(priv);
|
||||
}
|
@ -0,0 +1,222 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_mdio.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "mdio_rt2880.h"
|
||||
#include "mdio.h"
|
||||
|
||||
#define FE_MDIO_RETRY 1000
|
||||
|
||||
static unsigned char *rt2880_speed_str(struct fe_priv *priv)
|
||||
{
|
||||
switch (priv->phy->speed[0]) {
|
||||
case SPEED_1000:
|
||||
return "1000";
|
||||
case SPEED_100:
|
||||
return "100";
|
||||
case SPEED_10:
|
||||
return "10";
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
void rt2880_mdio_link_adjust(struct fe_priv *priv, int port)
|
||||
{
|
||||
u32 mdio_cfg;
|
||||
|
||||
if (!priv->link[0]) {
|
||||
netif_carrier_off(priv->netdev);
|
||||
netdev_info(priv->netdev, "link down\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mdio_cfg = FE_MDIO_CFG_TX_CLK_SKEW_200 |
|
||||
FE_MDIO_CFG_RX_CLK_SKEW_200 |
|
||||
FE_MDIO_CFG_GP1_FRC_EN;
|
||||
|
||||
if (priv->phy->duplex[0] == DUPLEX_FULL)
|
||||
mdio_cfg |= FE_MDIO_CFG_GP1_DUPLEX;
|
||||
|
||||
if (priv->phy->tx_fc[0])
|
||||
mdio_cfg |= FE_MDIO_CFG_GP1_FC_TX;
|
||||
|
||||
if (priv->phy->rx_fc[0])
|
||||
mdio_cfg |= FE_MDIO_CFG_GP1_FC_RX;
|
||||
|
||||
switch (priv->phy->speed[0]) {
|
||||
case SPEED_10:
|
||||
mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_10;
|
||||
break;
|
||||
case SPEED_100:
|
||||
mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_100;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_1000;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
fe_w32(mdio_cfg, FE_MDIO_CFG);
|
||||
|
||||
netif_carrier_on(priv->netdev);
|
||||
netdev_info(priv->netdev, "link up (%sMbps/%s duplex)\n",
|
||||
rt2880_speed_str(priv),
|
||||
(priv->phy->duplex[0] == DUPLEX_FULL) ? "Full" : "Half");
|
||||
}
|
||||
|
||||
static int rt2880_mdio_wait_ready(struct fe_priv *priv)
|
||||
{
|
||||
int retries;
|
||||
|
||||
retries = FE_MDIO_RETRY;
|
||||
while (1) {
|
||||
u32 t;
|
||||
|
||||
t = fe_r32(FE_MDIO_ACCESS);
|
||||
if ((t & BIT(31)) == 0)
|
||||
return 0;
|
||||
|
||||
if (retries-- == 0)
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
dev_err(priv->dev, "MDIO operation timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||
{
|
||||
struct fe_priv *priv = bus->priv;
|
||||
int err;
|
||||
u32 t;
|
||||
|
||||
err = rt2880_mdio_wait_ready(priv);
|
||||
if (err)
|
||||
return 0xffff;
|
||||
|
||||
t = (phy_addr << 24) | (phy_reg << 16);
|
||||
fe_w32(t, FE_MDIO_ACCESS);
|
||||
t |= BIT(31);
|
||||
fe_w32(t, FE_MDIO_ACCESS);
|
||||
|
||||
err = rt2880_mdio_wait_ready(priv);
|
||||
if (err)
|
||||
return 0xffff;
|
||||
|
||||
pr_debug("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
|
||||
phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
|
||||
|
||||
return fe_r32(FE_MDIO_ACCESS) & 0xffff;
|
||||
}
|
||||
|
||||
int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
|
||||
{
|
||||
struct fe_priv *priv = bus->priv;
|
||||
int err;
|
||||
u32 t;
|
||||
|
||||
pr_debug("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
|
||||
phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
|
||||
|
||||
err = rt2880_mdio_wait_ready(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
t = (1 << 30) | (phy_addr << 24) | (phy_reg << 16) | val;
|
||||
fe_w32(t, FE_MDIO_ACCESS);
|
||||
t |= BIT(31);
|
||||
fe_w32(t, FE_MDIO_ACCESS);
|
||||
|
||||
return rt2880_mdio_wait_ready(priv);
|
||||
}
|
||||
|
||||
void rt2880_port_init(struct fe_priv *priv, struct device_node *np)
|
||||
{
|
||||
const __be32 *id = of_get_property(np, "reg", NULL);
|
||||
const __be32 *link;
|
||||
int size;
|
||||
int phy_mode;
|
||||
|
||||
if (!id || (be32_to_cpu(*id) != 0)) {
|
||||
pr_err("%s: invalid port id\n", np->name);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->phy->phy_fixed[0] = of_get_property(np,
|
||||
"mediatek,fixed-link", &size);
|
||||
if (priv->phy->phy_fixed[0] &&
|
||||
(size != (4 * sizeof(*priv->phy->phy_fixed[0])))) {
|
||||
pr_err("%s: invalid fixed link property\n", np->name);
|
||||
priv->phy->phy_fixed[0] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
phy_mode = of_get_phy_mode(np);
|
||||
switch (phy_mode) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
break;
|
||||
default:
|
||||
if (!priv->phy->phy_fixed[0])
|
||||
dev_err(priv->dev, "port %d - invalid phy mode\n",
|
||||
priv->phy->speed[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
priv->phy->phy_node[0] = of_parse_phandle(np, "phy-handle", 0);
|
||||
if (!priv->phy->phy_node[0] && !priv->phy->phy_fixed[0])
|
||||
return;
|
||||
|
||||
if (priv->phy->phy_fixed[0]) {
|
||||
link = priv->phy->phy_fixed[0];
|
||||
priv->phy->speed[0] = be32_to_cpup(link++);
|
||||
priv->phy->duplex[0] = be32_to_cpup(link++);
|
||||
priv->phy->tx_fc[0] = be32_to_cpup(link++);
|
||||
priv->phy->rx_fc[0] = be32_to_cpup(link++);
|
||||
|
||||
priv->link[0] = 1;
|
||||
switch (priv->phy->speed[0]) {
|
||||
case SPEED_10:
|
||||
break;
|
||||
case SPEED_100:
|
||||
break;
|
||||
case SPEED_1000:
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->dev, "invalid link speed: %d\n",
|
||||
priv->phy->speed[0]);
|
||||
priv->phy->phy_fixed[0] = 0;
|
||||
return;
|
||||
}
|
||||
dev_info(priv->dev, "using fixed link parameters\n");
|
||||
rt2880_mdio_link_adjust(priv, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->phy->phy_node[0] && mdiobus_get_phy(priv->mii_bus, 0))
|
||||
fe_connect_phy_node(priv, priv->phy->phy_node[0]);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _RALINK_MDIO_RT2880_H__
|
||||
#define _RALINK_MDIO_RT2880_H__
|
||||
|
||||
void rt2880_mdio_link_adjust(struct fe_priv *priv, int port);
|
||||
int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
|
||||
int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
|
||||
void rt2880_port_init(struct fe_priv *priv, struct device_node *np);
|
||||
|
||||
#endif
|
979
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mt7530.c
Normal file
979
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mt7530.c
Normal file
@ -0,0 +1,979 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2016 Vitaly Chekryzhev <13hakta@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/if.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <linux/switch.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include "mt7530.h"
|
||||
|
||||
#define MT7530_CPU_PORT 6
|
||||
#define MT7530_NUM_PORTS 8
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
#define MT7530_NUM_VLANS 4095
|
||||
#else
|
||||
#define MT7530_NUM_VLANS 16
|
||||
#endif
|
||||
#define MT7530_MAX_VID 4095
|
||||
#define MT7530_MIN_VID 0
|
||||
|
||||
#define MT7530_PORT_MIB_TXB_ID 2 /* TxGOC */
|
||||
#define MT7530_PORT_MIB_RXB_ID 6 /* RxGOC */
|
||||
|
||||
#define MT7621_PORT_MIB_TXB_ID 18 /* TxByte */
|
||||
#define MT7621_PORT_MIB_RXB_ID 37 /* RxByte */
|
||||
|
||||
/* registers */
|
||||
#define REG_ESW_VLAN_VTCR 0x90
|
||||
#define REG_ESW_VLAN_VAWD1 0x94
|
||||
#define REG_ESW_VLAN_VAWD2 0x98
|
||||
#define REG_ESW_VLAN_VTIM(x) (0x100 + 4 * ((x) / 2))
|
||||
|
||||
#define REG_ESW_VLAN_VAWD1_IVL_MAC BIT(30)
|
||||
#define REG_ESW_VLAN_VAWD1_VTAG_EN BIT(28)
|
||||
#define REG_ESW_VLAN_VAWD1_VALID BIT(0)
|
||||
|
||||
/* vlan egress mode */
|
||||
enum {
|
||||
ETAG_CTRL_UNTAG = 0,
|
||||
ETAG_CTRL_TAG = 2,
|
||||
ETAG_CTRL_SWAP = 1,
|
||||
ETAG_CTRL_STACK = 3,
|
||||
};
|
||||
|
||||
#define REG_ESW_PORT_PCR(x) (0x2004 | ((x) << 8))
|
||||
#define REG_ESW_PORT_PVC(x) (0x2010 | ((x) << 8))
|
||||
#define REG_ESW_PORT_PPBV1(x) (0x2014 | ((x) << 8))
|
||||
|
||||
#define REG_HWTRAP 0x7804
|
||||
|
||||
#define MIB_DESC(_s , _o, _n) \
|
||||
{ \
|
||||
.size = (_s), \
|
||||
.offset = (_o), \
|
||||
.name = (_n), \
|
||||
}
|
||||
|
||||
struct mt7xxx_mib_desc {
|
||||
unsigned int size;
|
||||
unsigned int offset;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct mt7xxx_mib_desc mt7620_mibs[] = {
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_BCNT0, "PPE_AC_BCNT0"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_PCNT0, "PPE_AC_PCNT0"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_BCNT63, "PPE_AC_BCNT63"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_PCNT63, "PPE_AC_PCNT63"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PPE_MTR_CNT0, "PPE_MTR_CNT0"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PPE_MTR_CNT63, "PPE_MTR_CNT63"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_GBCNT, "GDM1_TX_GBCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_GPCNT, "GDM1_TX_GPCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_SKIPCNT, "GDM1_TX_SKIPCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_COLCNT, "GDM1_TX_COLCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_GBCNT1, "GDM1_RX_GBCNT1"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_GPCNT1, "GDM1_RX_GPCNT1"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_OERCNT, "GDM1_RX_OERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_FERCNT, "GDM1_RX_FERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_SERCNT, "GDM1_RX_SERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_LERCNT, "GDM1_RX_LERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_CERCNT, "GDM1_RX_CERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_FCCNT, "GDM1_RX_FCCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_GBCNT, "GDM2_TX_GBCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_GPCNT, "GDM2_TX_GPCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_SKIPCNT, "GDM2_TX_SKIPCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_COLCNT, "GDM2_TX_COLCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_GBCNT, "GDM2_RX_GBCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_GPCNT, "GDM2_RX_GPCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_OERCNT, "GDM2_RX_OERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_FERCNT, "GDM2_RX_FERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_SERCNT, "GDM2_RX_SERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_LERCNT, "GDM2_RX_LERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_CERCNT, "GDM2_RX_CERCNT"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_FCCNT, "GDM2_RX_FCCNT")
|
||||
};
|
||||
|
||||
static const struct mt7xxx_mib_desc mt7620_port_mibs[] = {
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_TGPCN, "TxGPC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_TBOCN, "TxBOC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_TGOCN, "TxGOC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_TEPCN, "TxEPC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_RGPCN, "RxGPC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_RBOCN, "RxBOC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_RGOCN, "RxGOC"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_REPC1N, "RxEPC1"),
|
||||
MIB_DESC(1, MT7620_MIB_STATS_PORT_REPC2N, "RxEPC2")
|
||||
};
|
||||
|
||||
static const struct mt7xxx_mib_desc mt7621_mibs[] = {
|
||||
MIB_DESC(1, MT7621_STATS_TDPC, "TxDrop"),
|
||||
MIB_DESC(1, MT7621_STATS_TCRC, "TxCRC"),
|
||||
MIB_DESC(1, MT7621_STATS_TUPC, "TxUni"),
|
||||
MIB_DESC(1, MT7621_STATS_TMPC, "TxMulti"),
|
||||
MIB_DESC(1, MT7621_STATS_TBPC, "TxBroad"),
|
||||
MIB_DESC(1, MT7621_STATS_TCEC, "TxCollision"),
|
||||
MIB_DESC(1, MT7621_STATS_TSCEC, "TxSingleCol"),
|
||||
MIB_DESC(1, MT7621_STATS_TMCEC, "TxMultiCol"),
|
||||
MIB_DESC(1, MT7621_STATS_TDEC, "TxDefer"),
|
||||
MIB_DESC(1, MT7621_STATS_TLCEC, "TxLateCol"),
|
||||
MIB_DESC(1, MT7621_STATS_TXCEC, "TxExcCol"),
|
||||
MIB_DESC(1, MT7621_STATS_TPPC, "TxPause"),
|
||||
MIB_DESC(1, MT7621_STATS_TL64PC, "Tx64Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_TL65PC, "Tx65Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_TL128PC, "Tx128Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_TL256PC, "Tx256Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_TL512PC, "Tx512Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_TL1024PC, "Tx1024Byte"),
|
||||
MIB_DESC(2, MT7621_STATS_TOC, "TxByte"),
|
||||
MIB_DESC(1, MT7621_STATS_RDPC, "RxDrop"),
|
||||
MIB_DESC(1, MT7621_STATS_RFPC, "RxFiltered"),
|
||||
MIB_DESC(1, MT7621_STATS_RUPC, "RxUni"),
|
||||
MIB_DESC(1, MT7621_STATS_RMPC, "RxMulti"),
|
||||
MIB_DESC(1, MT7621_STATS_RBPC, "RxBroad"),
|
||||
MIB_DESC(1, MT7621_STATS_RAEPC, "RxAlignErr"),
|
||||
MIB_DESC(1, MT7621_STATS_RCEPC, "RxCRC"),
|
||||
MIB_DESC(1, MT7621_STATS_RUSPC, "RxUnderSize"),
|
||||
MIB_DESC(1, MT7621_STATS_RFEPC, "RxFragment"),
|
||||
MIB_DESC(1, MT7621_STATS_ROSPC, "RxOverSize"),
|
||||
MIB_DESC(1, MT7621_STATS_RJEPC, "RxJabber"),
|
||||
MIB_DESC(1, MT7621_STATS_RPPC, "RxPause"),
|
||||
MIB_DESC(1, MT7621_STATS_RL64PC, "Rx64Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_RL65PC, "Rx65Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_RL128PC, "Rx128Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_RL256PC, "Rx256Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_RL512PC, "Rx512Byte"),
|
||||
MIB_DESC(1, MT7621_STATS_RL1024PC, "Rx1024Byte"),
|
||||
MIB_DESC(2, MT7621_STATS_ROC, "RxByte"),
|
||||
MIB_DESC(1, MT7621_STATS_RDPC_CTRL, "RxCtrlDrop"),
|
||||
MIB_DESC(1, MT7621_STATS_RDPC_ING, "RxIngDrop"),
|
||||
MIB_DESC(1, MT7621_STATS_RDPC_ARL, "RxARLDrop")
|
||||
};
|
||||
|
||||
enum {
|
||||
/* Global attributes. */
|
||||
MT7530_ATTR_ENABLE_VLAN,
|
||||
};
|
||||
|
||||
struct mt7530_port_entry {
|
||||
u16 pvid;
|
||||
};
|
||||
|
||||
struct mt7530_vlan_entry {
|
||||
u16 vid;
|
||||
u8 member;
|
||||
u8 etags;
|
||||
};
|
||||
|
||||
struct mt7530_priv {
|
||||
void __iomem *base;
|
||||
struct mii_bus *bus;
|
||||
struct switch_dev swdev;
|
||||
|
||||
bool global_vlan_enable;
|
||||
struct mt7530_vlan_entry vlan_entries[MT7530_NUM_VLANS];
|
||||
struct mt7530_port_entry port_entries[MT7530_NUM_PORTS];
|
||||
};
|
||||
|
||||
struct mt7530_mapping {
|
||||
char *name;
|
||||
u16 pvids[MT7530_NUM_PORTS];
|
||||
u8 members[MT7530_NUM_VLANS];
|
||||
u8 etags[MT7530_NUM_VLANS];
|
||||
u16 vids[MT7530_NUM_VLANS];
|
||||
} mt7530_defaults[] = {
|
||||
{
|
||||
.name = "llllw",
|
||||
.pvids = { 1, 1, 1, 1, 2, 1, 1 },
|
||||
.members = { 0, 0x6f, 0x50 },
|
||||
.etags = { 0, 0x40, 0x40 },
|
||||
.vids = { 0, 1, 2 },
|
||||
}, {
|
||||
.name = "wllll",
|
||||
.pvids = { 2, 1, 1, 1, 1, 1, 1 },
|
||||
.members = { 0, 0x7e, 0x41 },
|
||||
.etags = { 0, 0x40, 0x40 },
|
||||
.vids = { 0, 1, 2 },
|
||||
}, {
|
||||
.name = "lwlll",
|
||||
.pvids = { 1, 2, 1, 1, 1, 1, 1 },
|
||||
.members = { 0, 0x7d, 0x42 },
|
||||
.etags = { 0, 0x40, 0x40 },
|
||||
.vids = { 0, 1, 2 },
|
||||
},
|
||||
};
|
||||
|
||||
struct mt7530_mapping*
|
||||
mt7530_find_mapping(struct device_node *np)
|
||||
{
|
||||
const char *map;
|
||||
int i;
|
||||
|
||||
if (of_property_read_string(np, "mediatek,portmap", &map))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt7530_defaults); i++)
|
||||
if (!strcmp(map, mt7530_defaults[i].name))
|
||||
return &mt7530_defaults[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7530_apply_mapping(struct mt7530_priv *mt7530, struct mt7530_mapping *map)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
mt7530->port_entries[i].pvid = map->pvids[i];
|
||||
|
||||
for (i = 0; i < MT7530_NUM_VLANS; i++) {
|
||||
mt7530->vlan_entries[i].member = map->members[i];
|
||||
mt7530->vlan_entries[i].etags = map->etags[i];
|
||||
mt7530->vlan_entries[i].vid = map->vids[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_reset_switch(struct switch_dev *dev)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
int i;
|
||||
|
||||
memset(priv->port_entries, 0, sizeof(priv->port_entries));
|
||||
memset(priv->vlan_entries, 0, sizeof(priv->vlan_entries));
|
||||
|
||||
/* set default vid of each vlan to the same number of vlan, so the vid
|
||||
* won't need be set explicitly.
|
||||
*/
|
||||
for (i = 0; i < MT7530_NUM_VLANS; i++) {
|
||||
priv->vlan_entries[i].vid = i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_get_vlan_enable(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
|
||||
val->value.i = priv->global_vlan_enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_set_vlan_enable(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
|
||||
priv->global_vlan_enable = val->value.i != 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32
|
||||
mt7530_r32(struct mt7530_priv *priv, u32 reg)
|
||||
{
|
||||
u32 val;
|
||||
if (priv->bus) {
|
||||
u16 high, low;
|
||||
|
||||
mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
|
||||
low = mdiobus_read(priv->bus, 0x1f, (reg >> 2) & 0xf);
|
||||
high = mdiobus_read(priv->bus, 0x1f, 0x10);
|
||||
|
||||
return (high << 16) | (low & 0xffff);
|
||||
}
|
||||
|
||||
val = ioread32(priv->base + reg);
|
||||
pr_debug("MT7530 MDIO Read [%04x]=%08x\n", reg, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7530_w32(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
if (priv->bus) {
|
||||
mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
|
||||
mdiobus_write(priv->bus, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
|
||||
mdiobus_write(priv->bus, 0x1f, 0x10, val >> 16);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("MT7530 MDIO Write[%04x]=%08x\n", reg, val);
|
||||
iowrite32(val, priv->base + reg);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7530_vtcr(struct mt7530_priv *priv, u32 cmd, u32 val)
|
||||
{
|
||||
int i;
|
||||
|
||||
mt7530_w32(priv, REG_ESW_VLAN_VTCR, BIT(31) | (cmd << 12) | val);
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
u32 val = mt7530_r32(priv, REG_ESW_VLAN_VTCR);
|
||||
|
||||
if ((val & BIT(31)) == 0)
|
||||
break;
|
||||
|
||||
udelay(1000);
|
||||
}
|
||||
if (i == 20)
|
||||
printk("mt7530: vtcr timeout\n");
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
|
||||
if (port >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
*val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(port));
|
||||
*val &= 0xfff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_set_port_pvid(struct switch_dev *dev, int port, int pvid)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
|
||||
if (port >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
if (pvid < MT7530_MIN_VID || pvid > MT7530_MAX_VID)
|
||||
return -EINVAL;
|
||||
|
||||
priv->port_entries[port].pvid = pvid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
u32 member;
|
||||
u32 etags;
|
||||
int i;
|
||||
|
||||
val->len = 0;
|
||||
|
||||
if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS)
|
||||
return -EINVAL;
|
||||
|
||||
mt7530_vtcr(priv, 0, val->port_vlan);
|
||||
|
||||
member = mt7530_r32(priv, REG_ESW_VLAN_VAWD1);
|
||||
member >>= 16;
|
||||
member &= 0xff;
|
||||
|
||||
etags = mt7530_r32(priv, REG_ESW_VLAN_VAWD2);
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
struct switch_port *p;
|
||||
int etag;
|
||||
|
||||
if (!(member & BIT(i)))
|
||||
continue;
|
||||
|
||||
p = &val->value.ports[val->len++];
|
||||
p->id = i;
|
||||
|
||||
etag = (etags >> (i * 2)) & 0x3;
|
||||
|
||||
if (etag == ETAG_CTRL_TAG)
|
||||
p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
|
||||
else if (etag != ETAG_CTRL_UNTAG)
|
||||
printk("vlan egress tag control neither untag nor tag.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
u8 member = 0;
|
||||
u8 etags = 0;
|
||||
int i;
|
||||
|
||||
if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS ||
|
||||
val->len > MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < val->len; i++) {
|
||||
struct switch_port *p = &val->value.ports[i];
|
||||
|
||||
if (p->id >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
member |= BIT(p->id);
|
||||
|
||||
if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
|
||||
etags |= BIT(p->id);
|
||||
}
|
||||
priv->vlan_entries[val->port_vlan].member = member;
|
||||
priv->vlan_entries[val->port_vlan].etags = etags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
int vlan;
|
||||
u16 vid;
|
||||
|
||||
vlan = val->port_vlan;
|
||||
vid = (u16)val->value.i;
|
||||
|
||||
if (vlan < 0 || vlan >= MT7530_NUM_VLANS)
|
||||
return -EINVAL;
|
||||
|
||||
if (vid < MT7530_MIN_VID || vid > MT7530_MAX_VID)
|
||||
return -EINVAL;
|
||||
|
||||
priv->vlan_entries[vlan].vid = vid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7621_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
val->value.i = val->port_vlan;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
u32 vid;
|
||||
int vlan;
|
||||
|
||||
vlan = val->port_vlan;
|
||||
|
||||
vid = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
|
||||
if (vlan & 1)
|
||||
vid = vid >> 12;
|
||||
vid &= 0xfff;
|
||||
|
||||
val->value.i = vid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7530_write_vlan_entry(struct mt7530_priv *priv, int vlan, u16 vid,
|
||||
u8 ports, u8 etags)
|
||||
{
|
||||
int port;
|
||||
u32 val;
|
||||
|
||||
#ifndef CONFIG_SOC_MT7621
|
||||
/* vid of vlan */
|
||||
val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
|
||||
if (vlan % 2 == 0) {
|
||||
val &= 0xfff000;
|
||||
val |= vid;
|
||||
} else {
|
||||
val &= 0xfff;
|
||||
val |= (vid << 12);
|
||||
}
|
||||
mt7530_w32(priv, REG_ESW_VLAN_VTIM(vlan), val);
|
||||
#endif
|
||||
|
||||
/* vlan port membership */
|
||||
if (ports)
|
||||
mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
|
||||
REG_ESW_VLAN_VAWD1_VTAG_EN | (ports << 16) |
|
||||
REG_ESW_VLAN_VAWD1_VALID);
|
||||
else
|
||||
mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
|
||||
|
||||
/* egress mode */
|
||||
val = 0;
|
||||
for (port = 0; port < MT7530_NUM_PORTS; port++) {
|
||||
if (etags & BIT(port))
|
||||
val |= ETAG_CTRL_TAG << (port * 2);
|
||||
else
|
||||
val |= ETAG_CTRL_UNTAG << (port * 2);
|
||||
}
|
||||
mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
|
||||
|
||||
/* write to vlan table */
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
mt7530_vtcr(priv, 1, vid);
|
||||
#else
|
||||
mt7530_vtcr(priv, 1, vlan);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_apply_config(struct switch_dev *dev)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
int i, j;
|
||||
u8 tag_ports;
|
||||
u8 untag_ports;
|
||||
|
||||
if (!priv->global_vlan_enable) {
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00400000);
|
||||
|
||||
mt7530_w32(priv, REG_ESW_PORT_PCR(MT7530_CPU_PORT), 0x00ff0000);
|
||||
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
mt7530_w32(priv, REG_ESW_PORT_PVC(i), 0x810000c0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set all ports as security mode */
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++)
|
||||
mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00ff0003);
|
||||
|
||||
/* check if a port is used in tag/untag vlan egress mode */
|
||||
tag_ports = 0;
|
||||
untag_ports = 0;
|
||||
|
||||
for (i = 0; i < MT7530_NUM_VLANS; i++) {
|
||||
u8 member = priv->vlan_entries[i].member;
|
||||
u8 etags = priv->vlan_entries[i].etags;
|
||||
|
||||
if (!member)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MT7530_NUM_PORTS; j++) {
|
||||
if (!(member & BIT(j)))
|
||||
continue;
|
||||
|
||||
if (etags & BIT(j))
|
||||
tag_ports |= 1u << j;
|
||||
else
|
||||
untag_ports |= 1u << j;
|
||||
}
|
||||
}
|
||||
|
||||
/* set all untag-only ports as transparent and the rest as user port */
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
u32 pvc_mode = 0x81000000;
|
||||
|
||||
if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
|
||||
pvc_mode = 0x810000c0;
|
||||
|
||||
mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
|
||||
}
|
||||
|
||||
/* first clear the swtich vlan table */
|
||||
for (i = 0; i < MT7530_NUM_VLANS; i++)
|
||||
mt7530_write_vlan_entry(priv, i, i, 0, 0);
|
||||
|
||||
/* now program only vlans with members to avoid
|
||||
clobbering remapped entries in later iterations */
|
||||
for (i = 0; i < MT7530_NUM_VLANS; i++) {
|
||||
u16 vid = priv->vlan_entries[i].vid;
|
||||
u8 member = priv->vlan_entries[i].member;
|
||||
u8 etags = priv->vlan_entries[i].etags;
|
||||
|
||||
if (member)
|
||||
mt7530_write_vlan_entry(priv, i, vid, member, etags);
|
||||
}
|
||||
|
||||
/* Port Default PVID */
|
||||
for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
int vlan = priv->port_entries[i].pvid;
|
||||
u16 pvid = 0;
|
||||
u32 val;
|
||||
|
||||
if (vlan < MT7530_NUM_VLANS && priv->vlan_entries[vlan].member)
|
||||
pvid = priv->vlan_entries[vlan].vid;
|
||||
|
||||
val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(i));
|
||||
val &= ~0xfff;
|
||||
val |= pvid;
|
||||
mt7530_w32(priv, REG_ESW_PORT_PPBV1(i), val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7530_get_port_link(struct switch_dev *dev, int port,
|
||||
struct switch_port_link *link)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
u32 speed, pmsr;
|
||||
|
||||
if (port < 0 || port >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
pmsr = mt7530_r32(priv, 0x3008 + (0x100 * port));
|
||||
|
||||
link->link = pmsr & 1;
|
||||
link->duplex = (pmsr >> 1) & 1;
|
||||
speed = (pmsr >> 2) & 3;
|
||||
|
||||
switch (speed) {
|
||||
case 0:
|
||||
link->speed = SWITCH_PORT_SPEED_10;
|
||||
break;
|
||||
case 1:
|
||||
link->speed = SWITCH_PORT_SPEED_100;
|
||||
break;
|
||||
case 2:
|
||||
case 3: /* forced gige speed can be 2 or 3 */
|
||||
link->speed = SWITCH_PORT_SPEED_1000;
|
||||
break;
|
||||
default:
|
||||
link->speed = SWITCH_PORT_SPEED_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 get_mib_counter(struct mt7530_priv *priv, int i, int port)
|
||||
{
|
||||
unsigned int port_base;
|
||||
u64 lo;
|
||||
|
||||
port_base = MT7621_MIB_COUNTER_BASE +
|
||||
MT7621_MIB_COUNTER_PORT_OFFSET * port;
|
||||
|
||||
lo = mt7530_r32(priv, port_base + mt7621_mibs[i].offset);
|
||||
if (mt7621_mibs[i].size == 2) {
|
||||
u64 hi;
|
||||
|
||||
hi = mt7530_r32(priv, port_base + mt7621_mibs[i].offset + 4);
|
||||
lo |= hi << 32;
|
||||
}
|
||||
|
||||
return lo;
|
||||
}
|
||||
|
||||
static int mt7621_sw_get_port_mib(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
static char buf[4096];
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
int i, len = 0;
|
||||
|
||||
if (val->port_vlan >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"Port %d MIB counters\n", val->port_vlan);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt7621_mibs); ++i) {
|
||||
u64 counter;
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%-11s: ", mt7621_mibs[i].name);
|
||||
counter = get_mib_counter(priv, i, val->port_vlan);
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
|
||||
counter);
|
||||
}
|
||||
|
||||
val->value.s = buf;
|
||||
val->len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 get_mib_counter_7620(struct mt7530_priv *priv, int i)
|
||||
{
|
||||
return mt7530_r32(priv, MT7620_MIB_COUNTER_BASE + mt7620_mibs[i].offset);
|
||||
}
|
||||
|
||||
static u64 get_mib_counter_port_7620(struct mt7530_priv *priv, int i, int port)
|
||||
{
|
||||
return mt7530_r32(priv,
|
||||
MT7620_MIB_COUNTER_BASE_PORT +
|
||||
(MT7620_MIB_COUNTER_PORT_OFFSET * port) +
|
||||
mt7620_port_mibs[i].offset);
|
||||
}
|
||||
|
||||
static int mt7530_sw_get_mib(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
static char buf[4096];
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
int i, len = 0;
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "Switch MIB counters\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt7620_mibs); ++i) {
|
||||
u64 counter;
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%-11s: ", mt7620_mibs[i].name);
|
||||
counter = get_mib_counter_7620(priv, i);
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
|
||||
counter);
|
||||
}
|
||||
|
||||
val->value.s = buf;
|
||||
val->len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7530_sw_get_port_mib(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
static char buf[4096];
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
int i, len = 0;
|
||||
|
||||
if (val->port_vlan >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"Port %d MIB counters\n", val->port_vlan);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt7620_port_mibs); ++i) {
|
||||
u64 counter;
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%-11s: ", mt7620_port_mibs[i].name);
|
||||
counter = get_mib_counter_port_7620(priv, i, val->port_vlan);
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
|
||||
counter);
|
||||
}
|
||||
|
||||
val->value.s = buf;
|
||||
val->len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7530_get_port_stats(struct switch_dev *dev, int port,
|
||||
struct switch_port_stats *stats)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
|
||||
if (port < 0 || port >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
stats->tx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_TXB_ID, port);
|
||||
stats->rx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_RXB_ID, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7621_get_port_stats(struct switch_dev *dev, int port,
|
||||
struct switch_port_stats *stats)
|
||||
{
|
||||
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
|
||||
|
||||
if (port < 0 || port >= MT7530_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
stats->tx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_TXB_ID, port);
|
||||
stats->rx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_RXB_ID, port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct switch_attr mt7530_global[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_INT,
|
||||
.name = "enable_vlan",
|
||||
.description = "VLAN mode (1:enabled)",
|
||||
.max = 1,
|
||||
.id = MT7530_ATTR_ENABLE_VLAN,
|
||||
.get = mt7530_get_vlan_enable,
|
||||
.set = mt7530_set_vlan_enable,
|
||||
}, {
|
||||
.type = SWITCH_TYPE_STRING,
|
||||
.name = "mib",
|
||||
.description = "Get MIB counters for switch",
|
||||
.get = mt7530_sw_get_mib,
|
||||
.set = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct switch_attr mt7621_port[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_STRING,
|
||||
.name = "mib",
|
||||
.description = "Get MIB counters for port",
|
||||
.get = mt7621_sw_get_port_mib,
|
||||
.set = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct switch_attr mt7621_vlan[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_INT,
|
||||
.name = "vid",
|
||||
.description = "VLAN ID (0-4094)",
|
||||
.set = mt7530_set_vid,
|
||||
.get = mt7621_get_vid,
|
||||
.max = 4094,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct switch_attr mt7530_port[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_STRING,
|
||||
.name = "mib",
|
||||
.description = "Get MIB counters for port",
|
||||
.get = mt7530_sw_get_port_mib,
|
||||
.set = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct switch_attr mt7530_vlan[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_INT,
|
||||
.name = "vid",
|
||||
.description = "VLAN ID (0-4094)",
|
||||
.set = mt7530_set_vid,
|
||||
.get = mt7530_get_vid,
|
||||
.max = 4094,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct switch_dev_ops mt7621_ops = {
|
||||
.attr_global = {
|
||||
.attr = mt7530_global,
|
||||
.n_attr = ARRAY_SIZE(mt7530_global),
|
||||
},
|
||||
.attr_port = {
|
||||
.attr = mt7621_port,
|
||||
.n_attr = ARRAY_SIZE(mt7621_port),
|
||||
},
|
||||
.attr_vlan = {
|
||||
.attr = mt7621_vlan,
|
||||
.n_attr = ARRAY_SIZE(mt7621_vlan),
|
||||
},
|
||||
.get_vlan_ports = mt7530_get_vlan_ports,
|
||||
.set_vlan_ports = mt7530_set_vlan_ports,
|
||||
.get_port_pvid = mt7530_get_port_pvid,
|
||||
.set_port_pvid = mt7530_set_port_pvid,
|
||||
.get_port_link = mt7530_get_port_link,
|
||||
.get_port_stats = mt7621_get_port_stats,
|
||||
.apply_config = mt7530_apply_config,
|
||||
.reset_switch = mt7530_reset_switch,
|
||||
};
|
||||
|
||||
static const struct switch_dev_ops mt7530_ops = {
|
||||
.attr_global = {
|
||||
.attr = mt7530_global,
|
||||
.n_attr = ARRAY_SIZE(mt7530_global),
|
||||
},
|
||||
.attr_port = {
|
||||
.attr = mt7530_port,
|
||||
.n_attr = ARRAY_SIZE(mt7530_port),
|
||||
},
|
||||
.attr_vlan = {
|
||||
.attr = mt7530_vlan,
|
||||
.n_attr = ARRAY_SIZE(mt7530_vlan),
|
||||
},
|
||||
.get_vlan_ports = mt7530_get_vlan_ports,
|
||||
.set_vlan_ports = mt7530_set_vlan_ports,
|
||||
.get_port_pvid = mt7530_get_port_pvid,
|
||||
.set_port_pvid = mt7530_set_port_pvid,
|
||||
.get_port_link = mt7530_get_port_link,
|
||||
.get_port_stats = mt7530_get_port_stats,
|
||||
.apply_config = mt7530_apply_config,
|
||||
.reset_switch = mt7530_reset_switch,
|
||||
};
|
||||
|
||||
int
|
||||
mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan)
|
||||
{
|
||||
struct switch_dev *swdev;
|
||||
struct mt7530_priv *mt7530;
|
||||
struct mt7530_mapping *map;
|
||||
int ret;
|
||||
|
||||
mt7530 = devm_kzalloc(dev, sizeof(struct mt7530_priv), GFP_KERNEL);
|
||||
if (!mt7530)
|
||||
return -ENOMEM;
|
||||
|
||||
mt7530->base = base;
|
||||
mt7530->bus = bus;
|
||||
mt7530->global_vlan_enable = vlan;
|
||||
|
||||
swdev = &mt7530->swdev;
|
||||
if (bus) {
|
||||
swdev->alias = "mt7530";
|
||||
swdev->name = "mt7530";
|
||||
} else if (IS_ENABLED(CONFIG_SOC_MT7621)) {
|
||||
swdev->alias = "mt7621";
|
||||
swdev->name = "mt7621";
|
||||
} else {
|
||||
swdev->alias = "mt7620";
|
||||
swdev->name = "mt7620";
|
||||
}
|
||||
swdev->cpu_port = MT7530_CPU_PORT;
|
||||
swdev->ports = MT7530_NUM_PORTS;
|
||||
swdev->vlans = MT7530_NUM_VLANS;
|
||||
if (IS_ENABLED(CONFIG_SOC_MT7621))
|
||||
swdev->ops = &mt7621_ops;
|
||||
else
|
||||
swdev->ops = &mt7530_ops;
|
||||
|
||||
ret = register_switch(swdev, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register mt7530\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
map = mt7530_find_mapping(dev->of_node);
|
||||
if (map)
|
||||
mt7530_apply_mapping(mt7530, map);
|
||||
mt7530_apply_config(swdev);
|
||||
|
||||
/* magic vodoo */
|
||||
if (!IS_ENABLED(CONFIG_SOC_MT7621) && bus && mt7530_r32(mt7530, REG_HWTRAP) != 0x1117edf) {
|
||||
dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
|
||||
mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf);
|
||||
}
|
||||
dev_info(dev, "loaded %s driver\n", swdev->name);
|
||||
|
||||
return 0;
|
||||
}
|
186
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mt7530.h
Normal file
186
target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/mt7530.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2016 Vitaly Chekryzhev <13hakta@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT7530_H__
|
||||
#define _MT7530_H__
|
||||
|
||||
#define MT7620_MIB_COUNTER_BASE_PORT 0x4000
|
||||
#define MT7620_MIB_COUNTER_PORT_OFFSET 0x100
|
||||
#define MT7620_MIB_COUNTER_BASE 0x1010
|
||||
|
||||
/* PPE Accounting Group #0 Byte Counter */
|
||||
#define MT7620_MIB_STATS_PPE_AC_BCNT0 0x000
|
||||
|
||||
/* PPE Accounting Group #0 Packet Counter */
|
||||
#define MT7620_MIB_STATS_PPE_AC_PCNT0 0x004
|
||||
|
||||
/* PPE Accounting Group #63 Byte Counter */
|
||||
#define MT7620_MIB_STATS_PPE_AC_BCNT63 0x1F8
|
||||
|
||||
/* PPE Accounting Group #63 Packet Counter */
|
||||
#define MT7620_MIB_STATS_PPE_AC_PCNT63 0x1FC
|
||||
|
||||
/* PPE Meter Group #0 */
|
||||
#define MT7620_MIB_STATS_PPE_MTR_CNT0 0x200
|
||||
|
||||
/* PPE Meter Group #63 */
|
||||
#define MT7620_MIB_STATS_PPE_MTR_CNT63 0x2FC
|
||||
|
||||
/* Transmit good byte count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_TX_GBCNT 0x300
|
||||
|
||||
/* Transmit good packet count for CPU GDM (exclude flow control frames) */
|
||||
#define MT7620_MIB_STATS_GDM1_TX_GPCNT 0x304
|
||||
|
||||
/* Transmit abort count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_TX_SKIPCNT 0x308
|
||||
|
||||
/* Transmit collision count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_TX_COLCNT 0x30C
|
||||
|
||||
/* Received good byte count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_GBCNT1 0x320
|
||||
|
||||
/* Received good packet count for CPU GDM (exclude flow control frame) */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_GPCNT1 0x324
|
||||
|
||||
/* Received overflow error packet count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_OERCNT 0x328
|
||||
|
||||
/* Received FCS error packet count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_FERCNT 0x32C
|
||||
|
||||
/* Received too short error packet count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_SERCNT 0x330
|
||||
|
||||
/* Received too long error packet count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_LERCNT 0x334
|
||||
|
||||
/* Received IP/TCP/UDP checksum error packet count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_CERCNT 0x338
|
||||
|
||||
/* Received flow control pkt count for CPU GDM */
|
||||
#define MT7620_MIB_STATS_GDM1_RX_FCCNT 0x33C
|
||||
|
||||
/* Transmit good byte count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_TX_GBCNT 0x340
|
||||
|
||||
/* Transmit good packet count for PPE GDM (exclude flow control frames) */
|
||||
#define MT7620_MIB_STATS_GDM2_TX_GPCNT 0x344
|
||||
|
||||
/* Transmit abort count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_TX_SKIPCNT 0x348
|
||||
|
||||
/* Transmit collision count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_TX_COLCNT 0x34C
|
||||
|
||||
/* Received good byte count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_GBCNT 0x360
|
||||
|
||||
/* Received good packet count for PPE GDM (exclude flow control frame) */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_GPCNT 0x364
|
||||
|
||||
/* Received overflow error packet count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_OERCNT 0x368
|
||||
|
||||
/* Received FCS error packet count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_FERCNT 0x36C
|
||||
|
||||
/* Received too short error packet count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_SERCNT 0x370
|
||||
|
||||
/* Received too long error packet count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_LERCNT 0x374
|
||||
|
||||
/* Received IP/TCP/UDP checksum error packet count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_CERCNT 0x378
|
||||
|
||||
/* Received flow control pkt count for PPE GDM */
|
||||
#define MT7620_MIB_STATS_GDM2_RX_FCCNT 0x37C
|
||||
|
||||
/* Tx Packet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_TGPCN 0x10
|
||||
|
||||
/* Tx Bad Octet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_TBOCN 0x14
|
||||
|
||||
/* Tx Good Octet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_TGOCN 0x18
|
||||
|
||||
/* Tx Event Packet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_TEPCN 0x1C
|
||||
|
||||
/* Rx Packet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_RGPCN 0x20
|
||||
|
||||
/* Rx Bad Octet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_RBOCN 0x24
|
||||
|
||||
/* Rx Good Octet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_RGOCN 0x28
|
||||
|
||||
/* Rx Event Packet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_REPC1N 0x2C
|
||||
|
||||
/* Rx Event Packet Counter of Port n */
|
||||
#define MT7620_MIB_STATS_PORT_REPC2N 0x30
|
||||
|
||||
#define MT7621_MIB_COUNTER_BASE 0x4000
|
||||
#define MT7621_MIB_COUNTER_PORT_OFFSET 0x100
|
||||
#define MT7621_STATS_TDPC 0x00
|
||||
#define MT7621_STATS_TCRC 0x04
|
||||
#define MT7621_STATS_TUPC 0x08
|
||||
#define MT7621_STATS_TMPC 0x0C
|
||||
#define MT7621_STATS_TBPC 0x10
|
||||
#define MT7621_STATS_TCEC 0x14
|
||||
#define MT7621_STATS_TSCEC 0x18
|
||||
#define MT7621_STATS_TMCEC 0x1C
|
||||
#define MT7621_STATS_TDEC 0x20
|
||||
#define MT7621_STATS_TLCEC 0x24
|
||||
#define MT7621_STATS_TXCEC 0x28
|
||||
#define MT7621_STATS_TPPC 0x2C
|
||||
#define MT7621_STATS_TL64PC 0x30
|
||||
#define MT7621_STATS_TL65PC 0x34
|
||||
#define MT7621_STATS_TL128PC 0x38
|
||||
#define MT7621_STATS_TL256PC 0x3C
|
||||
#define MT7621_STATS_TL512PC 0x40
|
||||
#define MT7621_STATS_TL1024PC 0x44
|
||||
#define MT7621_STATS_TOC 0x48
|
||||
#define MT7621_STATS_RDPC 0x60
|
||||
#define MT7621_STATS_RFPC 0x64
|
||||
#define MT7621_STATS_RUPC 0x68
|
||||
#define MT7621_STATS_RMPC 0x6C
|
||||
#define MT7621_STATS_RBPC 0x70
|
||||
#define MT7621_STATS_RAEPC 0x74
|
||||
#define MT7621_STATS_RCEPC 0x78
|
||||
#define MT7621_STATS_RUSPC 0x7C
|
||||
#define MT7621_STATS_RFEPC 0x80
|
||||
#define MT7621_STATS_ROSPC 0x84
|
||||
#define MT7621_STATS_RJEPC 0x88
|
||||
#define MT7621_STATS_RPPC 0x8C
|
||||
#define MT7621_STATS_RL64PC 0x90
|
||||
#define MT7621_STATS_RL65PC 0x94
|
||||
#define MT7621_STATS_RL128PC 0x98
|
||||
#define MT7621_STATS_RL256PC 0x9C
|
||||
#define MT7621_STATS_RL512PC 0xA0
|
||||
#define MT7621_STATS_RL1024PC 0xA4
|
||||
#define MT7621_STATS_ROC 0xA8
|
||||
#define MT7621_STATS_RDPC_CTRL 0xB0
|
||||
#define MT7621_STATS_RDPC_ING 0xB4
|
||||
#define MT7621_STATS_RDPC_ARL 0xB8
|
||||
|
||||
int mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan);
|
||||
|
||||
#endif
|
@ -0,0 +1,115 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
|
||||
* Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include "mtk_offload.h"
|
||||
|
||||
static const char *mtk_foe_entry_state_str[] = {
|
||||
"INVALID",
|
||||
"UNBIND",
|
||||
"BIND",
|
||||
"FIN"
|
||||
};
|
||||
|
||||
static const char *mtk_foe_packet_type_str[] = {
|
||||
"IPV4_HNAPT",
|
||||
"IPV4_HNAT",
|
||||
"IPV6_1T_ROUTE",
|
||||
"IPV4_DSLITE",
|
||||
"IPV6_3T_ROUTE",
|
||||
"IPV6_5T_ROUTE",
|
||||
"IPV6_6RD",
|
||||
};
|
||||
|
||||
#define IPV4_HNAPT 0
|
||||
#define IPV4_HNAT 1
|
||||
#define IS_IPV4_HNAPT(x) (((x)->bfib1.pkt_type == IPV4_HNAPT) ? 1: 0)
|
||||
struct mtk_eth *_eth;
|
||||
#define es(entry) (mtk_foe_entry_state_str[entry->bfib1.state])
|
||||
//#define ei(entry, end) (MTK_PPE_TBL_SZ - (int)(end - entry))
|
||||
#define ei(entry, end) (MTK_PPE_ENTRY_CNT - (int)(end - entry))
|
||||
#define pt(entry) (mtk_foe_packet_type_str[entry->ipv4_hnapt.bfib1.pkt_type])
|
||||
|
||||
static int mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private)
|
||||
{
|
||||
struct mtk_eth *eth = _eth;
|
||||
struct mtk_foe_entry *entry, *end;
|
||||
int i = 0;
|
||||
|
||||
entry = eth->foe_table;
|
||||
end = eth->foe_table + MTK_PPE_ENTRY_CNT;
|
||||
|
||||
while (entry < end) {
|
||||
if (IS_IPV4_HNAPT(entry)) {
|
||||
__be32 saddr = htonl(entry->ipv4_hnapt.sip);
|
||||
__be32 daddr = htonl(entry->ipv4_hnapt.dip);
|
||||
__be32 nsaddr = htonl(entry->ipv4_hnapt.new_sip);
|
||||
__be32 ndaddr = htonl(entry->ipv4_hnapt.new_dip);
|
||||
unsigned char h_dest[ETH_ALEN];
|
||||
unsigned char h_source[ETH_ALEN];
|
||||
|
||||
*((u32*) h_source) = swab32(entry->ipv4_hnapt.smac_hi);
|
||||
*((u16*) &h_source[4]) = swab16(entry->ipv4_hnapt.smac_lo);
|
||||
*((u32*) h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
|
||||
*((u16*) &h_dest[4]) = swab16(entry->ipv4_hnapt.dmac_lo);
|
||||
seq_printf(m,
|
||||
"(%x)0x%05x|state=%s|type=%s|"
|
||||
"%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|"
|
||||
"etype=0x%04x|info1=0x%x|info2=0x%x|"
|
||||
"vlan1=%d|vlan2=%d\n",
|
||||
i,
|
||||
ei(entry, end), es(entry), pt(entry),
|
||||
&saddr, entry->ipv4_hnapt.sport,
|
||||
&daddr, entry->ipv4_hnapt.dport,
|
||||
&nsaddr, entry->ipv4_hnapt.new_sport,
|
||||
&ndaddr, entry->ipv4_hnapt.new_dport, h_source,
|
||||
h_dest, ntohs(entry->ipv4_hnapt.etype),
|
||||
entry->ipv4_hnapt.info_blk1,
|
||||
entry->ipv4_hnapt.info_blk2,
|
||||
entry->ipv4_hnapt.vlan1,
|
||||
entry->ipv4_hnapt.vlan2);
|
||||
} else
|
||||
seq_printf(m, "0x%05x state=%s\n",
|
||||
ei(entry, end), es(entry));
|
||||
entry++;
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ppe_debugfs_foe_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, mtk_ppe_debugfs_foe_show, file->private_data);
|
||||
}
|
||||
|
||||
static const struct file_operations mtk_ppe_debugfs_foe_fops = {
|
||||
.open = mtk_ppe_debugfs_foe_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
int mtk_ppe_debugfs_init(struct mtk_eth *eth)
|
||||
{
|
||||
struct dentry *root;
|
||||
|
||||
_eth = eth;
|
||||
|
||||
root = debugfs_create_dir("mtk_ppe", NULL);
|
||||
if (!root)
|
||||
return -ENOMEM;
|
||||
|
||||
debugfs_create_file("all_entry", S_IRUGO, root, eth, &mtk_ppe_debugfs_foe_fops);
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,539 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef FE_ETH_H
|
||||
#define FE_ETH_H
|
||||
|
||||
#include <linux/mii.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
enum fe_reg {
|
||||
FE_REG_PDMA_GLO_CFG = 0,
|
||||
FE_REG_PDMA_RST_CFG,
|
||||
FE_REG_DLY_INT_CFG,
|
||||
FE_REG_TX_BASE_PTR0,
|
||||
FE_REG_TX_MAX_CNT0,
|
||||
FE_REG_TX_CTX_IDX0,
|
||||
FE_REG_TX_DTX_IDX0,
|
||||
FE_REG_RX_BASE_PTR0,
|
||||
FE_REG_RX_MAX_CNT0,
|
||||
FE_REG_RX_CALC_IDX0,
|
||||
FE_REG_RX_DRX_IDX0,
|
||||
FE_REG_FE_INT_ENABLE,
|
||||
FE_REG_FE_INT_STATUS,
|
||||
FE_REG_FE_DMA_VID_BASE,
|
||||
FE_REG_FE_COUNTER_BASE,
|
||||
FE_REG_FE_RST_GL,
|
||||
FE_REG_FE_INT_STATUS2,
|
||||
FE_REG_COUNT
|
||||
};
|
||||
|
||||
enum fe_work_flag {
|
||||
FE_FLAG_RESET_PENDING,
|
||||
FE_FLAG_MAX
|
||||
};
|
||||
|
||||
#define MTK_FE_DRV_VERSION "0.1.2"
|
||||
|
||||
/* power of 2 to let NEXT_TX_DESP_IDX work */
|
||||
#define NUM_DMA_DESC BIT(10)
|
||||
#define MAX_DMA_DESC 0xfff
|
||||
|
||||
#define FE_DELAY_EN_INT 0x80
|
||||
#define FE_DELAY_MAX_INT 0x04
|
||||
#define FE_DELAY_MAX_TOUT 0x04
|
||||
#define FE_DELAY_TIME 20
|
||||
#define FE_DELAY_CHAN (((FE_DELAY_EN_INT | FE_DELAY_MAX_INT) << 8) | \
|
||||
FE_DELAY_MAX_TOUT)
|
||||
#define FE_DELAY_INIT ((FE_DELAY_CHAN << 16) | FE_DELAY_CHAN)
|
||||
#define FE_PSE_FQFC_CFG_INIT 0x80504000
|
||||
#define FE_PSE_FQFC_CFG_256Q 0xff908000
|
||||
|
||||
/* interrupt bits */
|
||||
#define FE_CNT_PPE_AF BIT(31)
|
||||
#define FE_CNT_GDM_AF BIT(29)
|
||||
#define FE_PSE_P2_FC BIT(26)
|
||||
#define FE_PSE_BUF_DROP BIT(24)
|
||||
#define FE_GDM_OTHER_DROP BIT(23)
|
||||
#define FE_PSE_P1_FC BIT(22)
|
||||
#define FE_PSE_P0_FC BIT(21)
|
||||
#define FE_PSE_FQ_EMPTY BIT(20)
|
||||
#define FE_GE1_STA_CHG BIT(18)
|
||||
#define FE_TX_COHERENT BIT(17)
|
||||
#define FE_RX_COHERENT BIT(16)
|
||||
#define FE_TX_DONE_INT3 BIT(11)
|
||||
#define FE_TX_DONE_INT2 BIT(10)
|
||||
#define FE_TX_DONE_INT1 BIT(9)
|
||||
#define FE_TX_DONE_INT0 BIT(8)
|
||||
#define FE_RX_DONE_INT0 BIT(2)
|
||||
#define FE_TX_DLY_INT BIT(1)
|
||||
#define FE_RX_DLY_INT BIT(0)
|
||||
|
||||
#define FE_RX_DONE_INT FE_RX_DONE_INT0
|
||||
#define FE_TX_DONE_INT (FE_TX_DONE_INT0 | FE_TX_DONE_INT1 | \
|
||||
FE_TX_DONE_INT2 | FE_TX_DONE_INT3)
|
||||
|
||||
#define RT5350_RX_DLY_INT BIT(30)
|
||||
#define RT5350_TX_DLY_INT BIT(28)
|
||||
#define RT5350_RX_DONE_INT1 BIT(17)
|
||||
#define RT5350_RX_DONE_INT0 BIT(16)
|
||||
#define RT5350_TX_DONE_INT3 BIT(3)
|
||||
#define RT5350_TX_DONE_INT2 BIT(2)
|
||||
#define RT5350_TX_DONE_INT1 BIT(1)
|
||||
#define RT5350_TX_DONE_INT0 BIT(0)
|
||||
|
||||
#define RT5350_RX_DONE_INT (RT5350_RX_DONE_INT0 | RT5350_RX_DONE_INT1)
|
||||
#define RT5350_TX_DONE_INT (RT5350_TX_DONE_INT0 | RT5350_TX_DONE_INT1 | \
|
||||
RT5350_TX_DONE_INT2 | RT5350_TX_DONE_INT3)
|
||||
|
||||
/* registers */
|
||||
#define FE_FE_OFFSET 0x0000
|
||||
#define FE_GDMA_OFFSET 0x0020
|
||||
#define FE_PSE_OFFSET 0x0040
|
||||
#define FE_GDMA2_OFFSET 0x0060
|
||||
#define FE_CDMA_OFFSET 0x0080
|
||||
#define FE_DMA_VID0 0x00a8
|
||||
#define FE_PDMA_OFFSET 0x0100
|
||||
#define FE_PPE_OFFSET 0x0200
|
||||
#define FE_CMTABLE_OFFSET 0x0400
|
||||
#define FE_POLICYTABLE_OFFSET 0x1000
|
||||
|
||||
#define RT5350_PDMA_OFFSET 0x0800
|
||||
#define RT5350_SDM_OFFSET 0x0c00
|
||||
|
||||
#define FE_MDIO_ACCESS (FE_FE_OFFSET + 0x00)
|
||||
#define FE_MDIO_CFG (FE_FE_OFFSET + 0x04)
|
||||
#define FE_FE_GLO_CFG (FE_FE_OFFSET + 0x08)
|
||||
#define FE_FE_RST_GL (FE_FE_OFFSET + 0x0C)
|
||||
#define FE_FE_INT_STATUS (FE_FE_OFFSET + 0x10)
|
||||
#define FE_FE_INT_ENABLE (FE_FE_OFFSET + 0x14)
|
||||
#define FE_MDIO_CFG2 (FE_FE_OFFSET + 0x18)
|
||||
#define FE_FOC_TS_T (FE_FE_OFFSET + 0x1C)
|
||||
|
||||
#define FE_GDMA1_FWD_CFG (FE_GDMA_OFFSET + 0x00)
|
||||
#define FE_GDMA1_SCH_CFG (FE_GDMA_OFFSET + 0x04)
|
||||
#define FE_GDMA1_SHPR_CFG (FE_GDMA_OFFSET + 0x08)
|
||||
#define FE_GDMA1_MAC_ADRL (FE_GDMA_OFFSET + 0x0C)
|
||||
#define FE_GDMA1_MAC_ADRH (FE_GDMA_OFFSET + 0x10)
|
||||
|
||||
#define FE_GDMA2_FWD_CFG (FE_GDMA2_OFFSET + 0x00)
|
||||
#define FE_GDMA2_SCH_CFG (FE_GDMA2_OFFSET + 0x04)
|
||||
#define FE_GDMA2_SHPR_CFG (FE_GDMA2_OFFSET + 0x08)
|
||||
#define FE_GDMA2_MAC_ADRL (FE_GDMA2_OFFSET + 0x0C)
|
||||
#define FE_GDMA2_MAC_ADRH (FE_GDMA2_OFFSET + 0x10)
|
||||
|
||||
#define FE_PSE_FQ_CFG (FE_PSE_OFFSET + 0x00)
|
||||
#define FE_CDMA_FC_CFG (FE_PSE_OFFSET + 0x04)
|
||||
#define FE_GDMA1_FC_CFG (FE_PSE_OFFSET + 0x08)
|
||||
#define FE_GDMA2_FC_CFG (FE_PSE_OFFSET + 0x0C)
|
||||
|
||||
#define FE_CDMA_CSG_CFG (FE_CDMA_OFFSET + 0x00)
|
||||
#define FE_CDMA_SCH_CFG (FE_CDMA_OFFSET + 0x04)
|
||||
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
#define MT7620A_GDMA_OFFSET 0x0500
|
||||
#else
|
||||
#define MT7620A_GDMA_OFFSET 0x0600
|
||||
#endif
|
||||
#define MT7620A_GDMA1_FWD_CFG (MT7620A_GDMA_OFFSET + 0x00)
|
||||
#define MT7620A_FE_GDMA1_SCH_CFG (MT7620A_GDMA_OFFSET + 0x04)
|
||||
#define MT7620A_FE_GDMA1_SHPR_CFG (MT7620A_GDMA_OFFSET + 0x08)
|
||||
#define MT7620A_FE_GDMA1_MAC_ADRL (MT7620A_GDMA_OFFSET + 0x0C)
|
||||
#define MT7620A_FE_GDMA1_MAC_ADRH (MT7620A_GDMA_OFFSET + 0x10)
|
||||
|
||||
#define RT5350_TX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x00)
|
||||
#define RT5350_TX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x04)
|
||||
#define RT5350_TX_CTX_IDX0 (RT5350_PDMA_OFFSET + 0x08)
|
||||
#define RT5350_TX_DTX_IDX0 (RT5350_PDMA_OFFSET + 0x0C)
|
||||
#define RT5350_TX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x10)
|
||||
#define RT5350_TX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x14)
|
||||
#define RT5350_TX_CTX_IDX1 (RT5350_PDMA_OFFSET + 0x18)
|
||||
#define RT5350_TX_DTX_IDX1 (RT5350_PDMA_OFFSET + 0x1C)
|
||||
#define RT5350_TX_BASE_PTR2 (RT5350_PDMA_OFFSET + 0x20)
|
||||
#define RT5350_TX_MAX_CNT2 (RT5350_PDMA_OFFSET + 0x24)
|
||||
#define RT5350_TX_CTX_IDX2 (RT5350_PDMA_OFFSET + 0x28)
|
||||
#define RT5350_TX_DTX_IDX2 (RT5350_PDMA_OFFSET + 0x2C)
|
||||
#define RT5350_TX_BASE_PTR3 (RT5350_PDMA_OFFSET + 0x30)
|
||||
#define RT5350_TX_MAX_CNT3 (RT5350_PDMA_OFFSET + 0x34)
|
||||
#define RT5350_TX_CTX_IDX3 (RT5350_PDMA_OFFSET + 0x38)
|
||||
#define RT5350_TX_DTX_IDX3 (RT5350_PDMA_OFFSET + 0x3C)
|
||||
#define RT5350_RX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x100)
|
||||
#define RT5350_RX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x104)
|
||||
#define RT5350_RX_CALC_IDX0 (RT5350_PDMA_OFFSET + 0x108)
|
||||
#define RT5350_RX_DRX_IDX0 (RT5350_PDMA_OFFSET + 0x10C)
|
||||
#define RT5350_RX_BASE_PTR1 (RT5350_PDMA_OFFSET + 0x110)
|
||||
#define RT5350_RX_MAX_CNT1 (RT5350_PDMA_OFFSET + 0x114)
|
||||
#define RT5350_RX_CALC_IDX1 (RT5350_PDMA_OFFSET + 0x118)
|
||||
#define RT5350_RX_DRX_IDX1 (RT5350_PDMA_OFFSET + 0x11C)
|
||||
#define RT5350_PDMA_GLO_CFG (RT5350_PDMA_OFFSET + 0x204)
|
||||
#define RT5350_PDMA_RST_CFG (RT5350_PDMA_OFFSET + 0x208)
|
||||
#define RT5350_DLY_INT_CFG (RT5350_PDMA_OFFSET + 0x20c)
|
||||
#define RT5350_FE_INT_STATUS (RT5350_PDMA_OFFSET + 0x220)
|
||||
#define RT5350_FE_INT_ENABLE (RT5350_PDMA_OFFSET + 0x228)
|
||||
#define RT5350_PDMA_SCH_CFG (RT5350_PDMA_OFFSET + 0x280)
|
||||
|
||||
#define FE_PDMA_GLO_CFG (FE_PDMA_OFFSET + 0x00)
|
||||
#define FE_PDMA_RST_CFG (FE_PDMA_OFFSET + 0x04)
|
||||
#define FE_PDMA_SCH_CFG (FE_PDMA_OFFSET + 0x08)
|
||||
#define FE_DLY_INT_CFG (FE_PDMA_OFFSET + 0x0C)
|
||||
#define FE_TX_BASE_PTR0 (FE_PDMA_OFFSET + 0x10)
|
||||
#define FE_TX_MAX_CNT0 (FE_PDMA_OFFSET + 0x14)
|
||||
#define FE_TX_CTX_IDX0 (FE_PDMA_OFFSET + 0x18)
|
||||
#define FE_TX_DTX_IDX0 (FE_PDMA_OFFSET + 0x1C)
|
||||
#define FE_TX_BASE_PTR1 (FE_PDMA_OFFSET + 0x20)
|
||||
#define FE_TX_MAX_CNT1 (FE_PDMA_OFFSET + 0x24)
|
||||
#define FE_TX_CTX_IDX1 (FE_PDMA_OFFSET + 0x28)
|
||||
#define FE_TX_DTX_IDX1 (FE_PDMA_OFFSET + 0x2C)
|
||||
#define FE_RX_BASE_PTR0 (FE_PDMA_OFFSET + 0x30)
|
||||
#define FE_RX_MAX_CNT0 (FE_PDMA_OFFSET + 0x34)
|
||||
#define FE_RX_CALC_IDX0 (FE_PDMA_OFFSET + 0x38)
|
||||
#define FE_RX_DRX_IDX0 (FE_PDMA_OFFSET + 0x3C)
|
||||
#define FE_TX_BASE_PTR2 (FE_PDMA_OFFSET + 0x40)
|
||||
#define FE_TX_MAX_CNT2 (FE_PDMA_OFFSET + 0x44)
|
||||
#define FE_TX_CTX_IDX2 (FE_PDMA_OFFSET + 0x48)
|
||||
#define FE_TX_DTX_IDX2 (FE_PDMA_OFFSET + 0x4C)
|
||||
#define FE_TX_BASE_PTR3 (FE_PDMA_OFFSET + 0x50)
|
||||
#define FE_TX_MAX_CNT3 (FE_PDMA_OFFSET + 0x54)
|
||||
#define FE_TX_CTX_IDX3 (FE_PDMA_OFFSET + 0x58)
|
||||
#define FE_TX_DTX_IDX3 (FE_PDMA_OFFSET + 0x5C)
|
||||
#define FE_RX_BASE_PTR1 (FE_PDMA_OFFSET + 0x60)
|
||||
#define FE_RX_MAX_CNT1 (FE_PDMA_OFFSET + 0x64)
|
||||
#define FE_RX_CALC_IDX1 (FE_PDMA_OFFSET + 0x68)
|
||||
#define FE_RX_DRX_IDX1 (FE_PDMA_OFFSET + 0x6C)
|
||||
|
||||
/* Switch DMA configuration */
|
||||
#define RT5350_SDM_CFG (RT5350_SDM_OFFSET + 0x00)
|
||||
#define RT5350_SDM_RRING (RT5350_SDM_OFFSET + 0x04)
|
||||
#define RT5350_SDM_TRING (RT5350_SDM_OFFSET + 0x08)
|
||||
#define RT5350_SDM_MAC_ADRL (RT5350_SDM_OFFSET + 0x0C)
|
||||
#define RT5350_SDM_MAC_ADRH (RT5350_SDM_OFFSET + 0x10)
|
||||
#define RT5350_SDM_TPCNT (RT5350_SDM_OFFSET + 0x100)
|
||||
#define RT5350_SDM_TBCNT (RT5350_SDM_OFFSET + 0x104)
|
||||
#define RT5350_SDM_RPCNT (RT5350_SDM_OFFSET + 0x108)
|
||||
#define RT5350_SDM_RBCNT (RT5350_SDM_OFFSET + 0x10C)
|
||||
#define RT5350_SDM_CS_ERR (RT5350_SDM_OFFSET + 0x110)
|
||||
|
||||
#define RT5350_SDM_ICS_EN BIT(16)
|
||||
#define RT5350_SDM_TCS_EN BIT(17)
|
||||
#define RT5350_SDM_UCS_EN BIT(18)
|
||||
|
||||
/* MDIO_CFG register bits */
|
||||
#define FE_MDIO_CFG_AUTO_POLL_EN BIT(29)
|
||||
#define FE_MDIO_CFG_GP1_BP_EN BIT(16)
|
||||
#define FE_MDIO_CFG_GP1_FRC_EN BIT(15)
|
||||
#define FE_MDIO_CFG_GP1_SPEED_10 (0 << 13)
|
||||
#define FE_MDIO_CFG_GP1_SPEED_100 (1 << 13)
|
||||
#define FE_MDIO_CFG_GP1_SPEED_1000 (2 << 13)
|
||||
#define FE_MDIO_CFG_GP1_DUPLEX BIT(12)
|
||||
#define FE_MDIO_CFG_GP1_FC_TX BIT(11)
|
||||
#define FE_MDIO_CFG_GP1_FC_RX BIT(10)
|
||||
#define FE_MDIO_CFG_GP1_LNK_DWN BIT(9)
|
||||
#define FE_MDIO_CFG_GP1_AN_FAIL BIT(8)
|
||||
#define FE_MDIO_CFG_MDC_CLK_DIV_1 (0 << 6)
|
||||
#define FE_MDIO_CFG_MDC_CLK_DIV_2 (1 << 6)
|
||||
#define FE_MDIO_CFG_MDC_CLK_DIV_4 (2 << 6)
|
||||
#define FE_MDIO_CFG_MDC_CLK_DIV_8 (3 << 6)
|
||||
#define FE_MDIO_CFG_TURBO_MII_FREQ BIT(5)
|
||||
#define FE_MDIO_CFG_TURBO_MII_MODE BIT(4)
|
||||
#define FE_MDIO_CFG_RX_CLK_SKEW_0 (0 << 2)
|
||||
#define FE_MDIO_CFG_RX_CLK_SKEW_200 (1 << 2)
|
||||
#define FE_MDIO_CFG_RX_CLK_SKEW_400 (2 << 2)
|
||||
#define FE_MDIO_CFG_RX_CLK_SKEW_INV (3 << 2)
|
||||
#define FE_MDIO_CFG_TX_CLK_SKEW_0 0
|
||||
#define FE_MDIO_CFG_TX_CLK_SKEW_200 1
|
||||
#define FE_MDIO_CFG_TX_CLK_SKEW_400 2
|
||||
#define FE_MDIO_CFG_TX_CLK_SKEW_INV 3
|
||||
|
||||
/* uni-cast port */
|
||||
#define FE_GDM1_JMB_LEN_MASK 0xf
|
||||
#define FE_GDM1_JMB_LEN_SHIFT 28
|
||||
#define FE_GDM1_ICS_EN BIT(22)
|
||||
#define FE_GDM1_TCS_EN BIT(21)
|
||||
#define FE_GDM1_UCS_EN BIT(20)
|
||||
#define FE_GDM1_JMB_EN BIT(19)
|
||||
#define FE_GDM1_STRPCRC BIT(16)
|
||||
#define FE_GDM1_UFRC_P_CPU (0 << 12)
|
||||
#define FE_GDM1_UFRC_P_GDMA1 (1 << 12)
|
||||
#define FE_GDM1_UFRC_P_PPE (6 << 12)
|
||||
|
||||
/* checksums */
|
||||
#define FE_ICS_GEN_EN BIT(2)
|
||||
#define FE_UCS_GEN_EN BIT(1)
|
||||
#define FE_TCS_GEN_EN BIT(0)
|
||||
|
||||
/* dma ring */
|
||||
#define FE_PST_DRX_IDX0 BIT(16)
|
||||
#define FE_PST_DTX_IDX3 BIT(3)
|
||||
#define FE_PST_DTX_IDX2 BIT(2)
|
||||
#define FE_PST_DTX_IDX1 BIT(1)
|
||||
#define FE_PST_DTX_IDX0 BIT(0)
|
||||
|
||||
#define FE_RX_2B_OFFSET BIT(31)
|
||||
#define FE_TX_WB_DDONE BIT(6)
|
||||
#define FE_RX_DMA_BUSY BIT(3)
|
||||
#define FE_TX_DMA_BUSY BIT(1)
|
||||
#define FE_RX_DMA_EN BIT(2)
|
||||
#define FE_TX_DMA_EN BIT(0)
|
||||
|
||||
#define FE_PDMA_SIZE_4DWORDS (0 << 4)
|
||||
#define FE_PDMA_SIZE_8DWORDS (1 << 4)
|
||||
#define FE_PDMA_SIZE_16DWORDS (2 << 4)
|
||||
|
||||
#define FE_US_CYC_CNT_MASK 0xff
|
||||
#define FE_US_CYC_CNT_SHIFT 0x8
|
||||
#define FE_US_CYC_CNT_DIVISOR 1000000
|
||||
|
||||
/* rxd2 */
|
||||
#define RX_DMA_DONE BIT(31)
|
||||
#define RX_DMA_LSO BIT(30)
|
||||
#define RX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16)
|
||||
#define RX_DMA_GET_PLEN0(_x) (((_x) >> 16) & 0x3fff)
|
||||
#define RX_DMA_TAG BIT(15)
|
||||
/* rxd3 */
|
||||
#define RX_DMA_TPID(_x) (((_x) >> 16) & 0xffff)
|
||||
#define RX_DMA_VID(_x) ((_x) & 0xffff)
|
||||
/* rxd4 */
|
||||
#define RX_DMA_L4VALID BIT(30)
|
||||
|
||||
struct fe_rx_dma {
|
||||
unsigned int rxd1;
|
||||
unsigned int rxd2;
|
||||
unsigned int rxd3;
|
||||
unsigned int rxd4;
|
||||
} __packed __aligned(4);
|
||||
|
||||
#define TX_DMA_BUF_LEN 0x3fff
|
||||
#define TX_DMA_PLEN0_MASK (TX_DMA_BUF_LEN << 16)
|
||||
#define TX_DMA_PLEN0(_x) (((_x) & TX_DMA_BUF_LEN) << 16)
|
||||
#define TX_DMA_PLEN1(_x) ((_x) & TX_DMA_BUF_LEN)
|
||||
#define TX_DMA_GET_PLEN0(_x) (((_x) >> 16) & TX_DMA_BUF_LEN)
|
||||
#define TX_DMA_GET_PLEN1(_x) ((_x) & TX_DMA_BUF_LEN)
|
||||
#define TX_DMA_LS1 BIT(14)
|
||||
#define TX_DMA_LS0 BIT(30)
|
||||
#define TX_DMA_DONE BIT(31)
|
||||
|
||||
#define TX_DMA_INS_VLAN_MT7621 BIT(16)
|
||||
#define TX_DMA_INS_VLAN BIT(7)
|
||||
#define TX_DMA_INS_PPPOE BIT(12)
|
||||
#define TX_DMA_QN(_x) ((_x) << 16)
|
||||
#define TX_DMA_PN(_x) ((_x) << 24)
|
||||
#define TX_DMA_QN_MASK TX_DMA_QN(0x7)
|
||||
#define TX_DMA_PN_MASK TX_DMA_PN(0x7)
|
||||
#define TX_DMA_UDF BIT(20)
|
||||
#define TX_DMA_CHKSUM (0x7 << 29)
|
||||
#define TX_DMA_TSO BIT(28)
|
||||
|
||||
/* frame engine counters */
|
||||
#define FE_PPE_AC_BCNT0 (FE_CMTABLE_OFFSET + 0x00)
|
||||
#define FE_GDMA1_TX_GBCNT (FE_CMTABLE_OFFSET + 0x300)
|
||||
#define FE_GDMA2_TX_GBCNT (FE_GDMA1_TX_GBCNT + 0x40)
|
||||
|
||||
/* phy device flags */
|
||||
#define FE_PHY_FLAG_PORT BIT(0)
|
||||
#define FE_PHY_FLAG_ATTACH BIT(1)
|
||||
|
||||
struct fe_tx_dma {
|
||||
unsigned int txd1;
|
||||
unsigned int txd2;
|
||||
unsigned int txd3;
|
||||
unsigned int txd4;
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct fe_priv;
|
||||
|
||||
struct fe_phy {
|
||||
/* make sure that phy operations are atomic */
|
||||
spinlock_t lock;
|
||||
|
||||
struct phy_device *phy[8];
|
||||
struct device_node *phy_node[8];
|
||||
const __be32 *phy_fixed[8];
|
||||
int duplex[8];
|
||||
int speed[8];
|
||||
int tx_fc[8];
|
||||
int rx_fc[8];
|
||||
int (*connect)(struct fe_priv *priv);
|
||||
void (*disconnect)(struct fe_priv *priv);
|
||||
void (*start)(struct fe_priv *priv);
|
||||
void (*stop)(struct fe_priv *priv);
|
||||
};
|
||||
|
||||
struct fe_soc_data {
|
||||
const u16 *reg_table;
|
||||
|
||||
void (*init_data)(struct fe_soc_data *data, struct net_device *netdev);
|
||||
void (*reset_fe)(void);
|
||||
void (*set_mac)(struct fe_priv *priv, unsigned char *mac);
|
||||
int (*fwd_config)(struct fe_priv *priv);
|
||||
void (*tx_dma)(struct fe_tx_dma *txd);
|
||||
int (*switch_init)(struct fe_priv *priv);
|
||||
int (*switch_config)(struct fe_priv *priv);
|
||||
void (*port_init)(struct fe_priv *priv, struct device_node *port);
|
||||
int (*has_carrier)(struct fe_priv *priv);
|
||||
int (*mdio_init)(struct fe_priv *priv);
|
||||
void (*mdio_cleanup)(struct fe_priv *priv);
|
||||
int (*mdio_write)(struct mii_bus *bus, int phy_addr, int phy_reg,
|
||||
u16 val);
|
||||
int (*mdio_read)(struct mii_bus *bus, int phy_addr, int phy_reg);
|
||||
void (*mdio_adjust_link)(struct fe_priv *priv, int port);
|
||||
|
||||
void *swpriv;
|
||||
u32 pdma_glo_cfg;
|
||||
u32 rx_int;
|
||||
u32 tx_int;
|
||||
u32 status_int;
|
||||
u32 checksum_bit;
|
||||
};
|
||||
|
||||
#define FE_FLAG_PADDING_64B BIT(0)
|
||||
#define FE_FLAG_PADDING_BUG BIT(1)
|
||||
#define FE_FLAG_JUMBO_FRAME BIT(2)
|
||||
#define FE_FLAG_RX_2B_OFFSET BIT(3)
|
||||
#define FE_FLAG_RX_SG_DMA BIT(4)
|
||||
#define FE_FLAG_RX_VLAN_CTAG BIT(5)
|
||||
#define FE_FLAG_NAPI_WEIGHT BIT(6)
|
||||
#define FE_FLAG_CALIBRATE_CLK BIT(7)
|
||||
#define FE_FLAG_HAS_SWITCH BIT(8)
|
||||
|
||||
#define FE_STAT_REG_DECLARE \
|
||||
_FE(tx_bytes) \
|
||||
_FE(tx_packets) \
|
||||
_FE(tx_skip) \
|
||||
_FE(tx_collisions) \
|
||||
_FE(rx_bytes) \
|
||||
_FE(rx_packets) \
|
||||
_FE(rx_overflow) \
|
||||
_FE(rx_fcs_errors) \
|
||||
_FE(rx_short_errors) \
|
||||
_FE(rx_long_errors) \
|
||||
_FE(rx_checksum_errors) \
|
||||
_FE(rx_flow_control_packets)
|
||||
|
||||
struct fe_hw_stats {
|
||||
/* make sure that stats operations are atomic */
|
||||
spinlock_t stats_lock;
|
||||
|
||||
struct u64_stats_sync syncp;
|
||||
#define _FE(x) u64 x;
|
||||
FE_STAT_REG_DECLARE
|
||||
#undef _FE
|
||||
};
|
||||
|
||||
enum fe_tx_flags {
|
||||
FE_TX_FLAGS_SINGLE0 = 0x01,
|
||||
FE_TX_FLAGS_PAGE0 = 0x02,
|
||||
FE_TX_FLAGS_PAGE1 = 0x04,
|
||||
};
|
||||
|
||||
struct fe_tx_buf {
|
||||
struct sk_buff *skb;
|
||||
u32 flags;
|
||||
DEFINE_DMA_UNMAP_ADDR(dma_addr0);
|
||||
DEFINE_DMA_UNMAP_LEN(dma_len0);
|
||||
DEFINE_DMA_UNMAP_ADDR(dma_addr1);
|
||||
DEFINE_DMA_UNMAP_LEN(dma_len1);
|
||||
};
|
||||
|
||||
struct fe_tx_ring {
|
||||
struct fe_tx_dma *tx_dma;
|
||||
struct fe_tx_buf *tx_buf;
|
||||
dma_addr_t tx_phys;
|
||||
u16 tx_ring_size;
|
||||
u16 tx_free_idx;
|
||||
u16 tx_next_idx;
|
||||
u16 tx_thresh;
|
||||
};
|
||||
|
||||
struct fe_rx_ring {
|
||||
struct fe_rx_dma *rx_dma;
|
||||
u8 **rx_data;
|
||||
dma_addr_t rx_phys;
|
||||
u16 rx_ring_size;
|
||||
u16 frag_size;
|
||||
u16 rx_buf_size;
|
||||
u16 rx_calc_idx;
|
||||
};
|
||||
|
||||
struct fe_priv {
|
||||
/* make sure that register operations are atomic */
|
||||
spinlock_t page_lock;
|
||||
|
||||
struct fe_soc_data *soc;
|
||||
struct net_device *netdev;
|
||||
struct device_node *switch_np;
|
||||
u32 msg_enable;
|
||||
u32 flags;
|
||||
|
||||
struct device *dev;
|
||||
unsigned long sysclk;
|
||||
|
||||
struct fe_rx_ring rx_ring;
|
||||
struct napi_struct rx_napi;
|
||||
|
||||
struct fe_tx_ring tx_ring;
|
||||
|
||||
struct fe_phy *phy;
|
||||
struct mii_bus *mii_bus;
|
||||
struct phy_device *phy_dev;
|
||||
u32 phy_flags;
|
||||
|
||||
int link[8];
|
||||
|
||||
struct fe_hw_stats *hw_stats;
|
||||
unsigned long vlan_map;
|
||||
struct work_struct pending_work;
|
||||
DECLARE_BITMAP(pending_flags, FE_FLAG_MAX);
|
||||
|
||||
struct reset_control *rst_ppe;
|
||||
struct mtk_foe_entry *foe_table;
|
||||
dma_addr_t foe_table_phys;
|
||||
struct flow_offload __rcu **foe_flow_table;
|
||||
};
|
||||
|
||||
extern const struct of_device_id of_fe_match[];
|
||||
|
||||
void fe_w32(u32 val, unsigned reg);
|
||||
void fe_m32(struct fe_priv *priv, u32 clear, u32 set, unsigned reg);
|
||||
u32 fe_r32(unsigned reg);
|
||||
|
||||
int fe_set_clock_cycle(struct fe_priv *priv);
|
||||
void fe_csum_config(struct fe_priv *priv);
|
||||
void fe_stats_update(struct fe_priv *priv);
|
||||
void fe_fwd_config(struct fe_priv *priv);
|
||||
void fe_reg_w32(u32 val, enum fe_reg reg);
|
||||
u32 fe_reg_r32(enum fe_reg reg);
|
||||
|
||||
void fe_reset(u32 reset_bits);
|
||||
|
||||
static inline void *priv_netdev(struct fe_priv *priv)
|
||||
{
|
||||
return (char *)priv - ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
|
||||
}
|
||||
|
||||
int mtk_ppe_probe(struct fe_priv *eth);
|
||||
void mtk_ppe_remove(struct fe_priv *eth);
|
||||
int mtk_flow_offload(struct fe_priv *eth,
|
||||
enum flow_offload_type type,
|
||||
struct flow_offload *flow,
|
||||
struct flow_offload_hw_path *src,
|
||||
struct flow_offload_hw_path *dest);
|
||||
int mtk_offload_check_rx(struct fe_priv *eth, struct sk_buff *skb, u32 rxd4);
|
||||
|
||||
|
||||
#endif /* FE_ETH_H */
|
@ -0,0 +1,526 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2018 John Crispin <john@phrozen.org>
|
||||
*/
|
||||
|
||||
#include "mtk_offload.h"
|
||||
|
||||
#define INVALID 0
|
||||
#define UNBIND 1
|
||||
#define BIND 2
|
||||
#define FIN 3
|
||||
|
||||
#define IPV4_HNAPT 0
|
||||
#define IPV4_HNAT 1
|
||||
|
||||
static u32
|
||||
mtk_flow_hash_v4(struct flow_offload_tuple *tuple)
|
||||
{
|
||||
u32 ports = ntohs(tuple->src_port) << 16 | ntohs(tuple->dst_port);
|
||||
u32 src = ntohl(tuple->dst_v4.s_addr);
|
||||
u32 dst = ntohl(tuple->src_v4.s_addr);
|
||||
u32 hash = (ports & src) | ((~ports) & dst);
|
||||
u32 hash_23_0 = hash & 0xffffff;
|
||||
u32 hash_31_24 = hash & 0xff000000;
|
||||
|
||||
hash = ports ^ src ^ dst ^ ((hash_23_0 << 8) | (hash_31_24 >> 24));
|
||||
hash = ((hash & 0xffff0000) >> 16 ) ^ (hash & 0xfffff);
|
||||
hash &= 0x7ff;
|
||||
hash *= 2;;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static int
|
||||
mtk_foe_prepare_v4(struct mtk_foe_entry *entry,
|
||||
struct flow_offload_tuple *tuple,
|
||||
struct flow_offload_tuple *dest_tuple,
|
||||
struct flow_offload_hw_path *src,
|
||||
struct flow_offload_hw_path *dest)
|
||||
{
|
||||
int is_mcast = !!is_multicast_ether_addr(dest->eth_dest);
|
||||
|
||||
if (tuple->l4proto == IPPROTO_UDP)
|
||||
entry->ipv4_hnapt.bfib1.udp = 1;
|
||||
|
||||
entry->ipv4_hnapt.etype = htons(ETH_P_IP);
|
||||
entry->ipv4_hnapt.bfib1.pkt_type = IPV4_HNAPT;
|
||||
entry->ipv4_hnapt.iblk2.fqos = 0;
|
||||
entry->ipv4_hnapt.bfib1.ttl = 1;
|
||||
entry->ipv4_hnapt.bfib1.cah = 1;
|
||||
entry->ipv4_hnapt.bfib1.ka = 1;
|
||||
entry->ipv4_hnapt.iblk2.mcast = is_mcast;
|
||||
entry->ipv4_hnapt.iblk2.dscp = 0;
|
||||
entry->ipv4_hnapt.iblk2.port_mg = 0x3f;
|
||||
entry->ipv4_hnapt.iblk2.port_ag = 0x1f;
|
||||
#ifdef CONFIG_NET_MEDIATEK_HW_QOS
|
||||
entry->ipv4_hnapt.iblk2.qid = 1;
|
||||
entry->ipv4_hnapt.iblk2.fqos = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_RALINK
|
||||
entry->ipv4_hnapt.iblk2.dp = 1;
|
||||
if ((dest->flags & FLOW_OFFLOAD_PATH_VLAN) && (dest->vlan_id > 1))
|
||||
entry->ipv4_hnapt.iblk2.qid += 8;
|
||||
#else
|
||||
entry->ipv4_hnapt.iblk2.dp = (dest->dev->name[3] - '0') + 1;
|
||||
#endif
|
||||
|
||||
entry->ipv4_hnapt.sip = ntohl(tuple->src_v4.s_addr);
|
||||
entry->ipv4_hnapt.dip = ntohl(tuple->dst_v4.s_addr);
|
||||
entry->ipv4_hnapt.sport = ntohs(tuple->src_port);
|
||||
entry->ipv4_hnapt.dport = ntohs(tuple->dst_port);
|
||||
|
||||
entry->ipv4_hnapt.new_sip = ntohl(dest_tuple->dst_v4.s_addr);
|
||||
entry->ipv4_hnapt.new_dip = ntohl(dest_tuple->src_v4.s_addr);
|
||||
entry->ipv4_hnapt.new_sport = ntohs(dest_tuple->dst_port);
|
||||
entry->ipv4_hnapt.new_dport = ntohs(dest_tuple->src_port);
|
||||
|
||||
entry->bfib1.state = BIND;
|
||||
|
||||
if (dest->flags & FLOW_OFFLOAD_PATH_PPPOE) {
|
||||
entry->bfib1.psn = 1;
|
||||
entry->ipv4_hnapt.etype = htons(ETH_P_PPP_SES);
|
||||
entry->ipv4_hnapt.pppoe_id = dest->pppoe_sid;
|
||||
}
|
||||
|
||||
if (dest->flags & FLOW_OFFLOAD_PATH_VLAN) {
|
||||
entry->ipv4_hnapt.vlan1 = dest->vlan_id;
|
||||
entry->bfib1.vlan_layer = 1;
|
||||
|
||||
switch (dest->vlan_proto) {
|
||||
case htons(ETH_P_8021Q):
|
||||
entry->ipv4_hnapt.bfib1.vpm = 1;
|
||||
break;
|
||||
case htons(ETH_P_8021AD):
|
||||
entry->ipv4_hnapt.bfib1.vpm = 2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mtk_foe_set_mac(struct mtk_foe_entry *entry, u8 *smac, u8 *dmac)
|
||||
{
|
||||
entry->ipv4_hnapt.dmac_hi = swab32(*((u32*) dmac));
|
||||
entry->ipv4_hnapt.dmac_lo = swab16(*((u16*) &dmac[4]));
|
||||
entry->ipv4_hnapt.smac_hi = swab32(*((u32*) smac));
|
||||
entry->ipv4_hnapt.smac_lo = swab16(*((u16*) &smac[4]));
|
||||
}
|
||||
|
||||
static void
|
||||
mtk_foe_write(struct mtk_eth *eth, u32 hash,
|
||||
struct mtk_foe_entry *entry)
|
||||
{
|
||||
struct mtk_foe_entry *table = (struct mtk_foe_entry *)eth->foe_table;
|
||||
|
||||
memcpy(&table[hash], entry, sizeof(*entry));
|
||||
}
|
||||
|
||||
int mtk_flow_offload(struct mtk_eth *eth,
|
||||
enum flow_offload_type type,
|
||||
struct flow_offload *flow,
|
||||
struct flow_offload_hw_path *src,
|
||||
struct flow_offload_hw_path *dest)
|
||||
{
|
||||
struct flow_offload_tuple *otuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple;
|
||||
struct flow_offload_tuple *rtuple = &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple;
|
||||
u32 time_stamp = mtk_r32(eth, 0x0010) & (0x7fff);
|
||||
u32 ohash, rhash;
|
||||
struct mtk_foe_entry orig = {
|
||||
.bfib1.time_stamp = time_stamp,
|
||||
.bfib1.psn = 0,
|
||||
};
|
||||
struct mtk_foe_entry reply = {
|
||||
.bfib1.time_stamp = time_stamp,
|
||||
.bfib1.psn = 0,
|
||||
};
|
||||
|
||||
if (otuple->l4proto != IPPROTO_TCP && otuple->l4proto != IPPROTO_UDP)
|
||||
return -EINVAL;
|
||||
|
||||
switch (otuple->l3proto) {
|
||||
case AF_INET:
|
||||
if (mtk_foe_prepare_v4(&orig, otuple, rtuple, src, dest) ||
|
||||
mtk_foe_prepare_v4(&reply, rtuple, otuple, dest, src))
|
||||
return -EINVAL;
|
||||
|
||||
ohash = mtk_flow_hash_v4(otuple);
|
||||
rhash = mtk_flow_hash_v4(rtuple);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type == FLOW_OFFLOAD_DEL) {
|
||||
orig.bfib1.state = INVALID;
|
||||
reply.bfib1.state = INVALID;
|
||||
flow = NULL;
|
||||
goto write;
|
||||
}
|
||||
|
||||
mtk_foe_set_mac(&orig, dest->eth_src, dest->eth_dest);
|
||||
mtk_foe_set_mac(&reply, src->eth_src, src->eth_dest);
|
||||
|
||||
write:
|
||||
mtk_foe_write(eth, ohash, &orig);
|
||||
mtk_foe_write(eth, rhash, &reply);
|
||||
rcu_assign_pointer(eth->foe_flow_table[ohash], flow);
|
||||
rcu_assign_pointer(eth->foe_flow_table[rhash], flow);
|
||||
|
||||
if (type == FLOW_OFFLOAD_DEL)
|
||||
synchronize_rcu();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_MEDIATEK_HW_QOS
|
||||
|
||||
#define QDMA_TX_SCH_TX 0x1a14
|
||||
|
||||
static void mtk_ppe_scheduler(struct mtk_eth *eth, int id, u32 rate)
|
||||
{
|
||||
int exp = 0, shift = 0;
|
||||
u32 reg = mtk_r32(eth, QDMA_TX_SCH_TX);
|
||||
u32 val = 0;
|
||||
|
||||
if (rate)
|
||||
val = BIT(11);
|
||||
|
||||
while (rate > 127) {
|
||||
rate /= 10;
|
||||
exp++;
|
||||
}
|
||||
|
||||
val |= (rate & 0x7f) << 4;
|
||||
val |= exp & 0xf;
|
||||
if (id)
|
||||
shift = 16;
|
||||
reg &= ~(0xffff << shift);
|
||||
reg |= val << shift;
|
||||
mtk_w32(eth, val, QDMA_TX_SCH_TX);
|
||||
}
|
||||
|
||||
#define QTX_CFG(x) (0x1800 + (x * 0x10))
|
||||
#define QTX_SCH(x) (0x1804 + (x * 0x10))
|
||||
|
||||
static void mtk_ppe_queue(struct mtk_eth *eth, int id, int sched, int weight, int resv, u32 min_rate, u32 max_rate)
|
||||
{
|
||||
int max_exp = 0, min_exp = 0;
|
||||
u32 reg;
|
||||
|
||||
if (id >= 16)
|
||||
return;
|
||||
|
||||
reg = mtk_r32(eth, QTX_SCH(id));
|
||||
reg &= 0x70000000;
|
||||
|
||||
if (sched)
|
||||
reg |= BIT(31);
|
||||
|
||||
if (min_rate)
|
||||
reg |= BIT(27);
|
||||
|
||||
if (max_rate)
|
||||
reg |= BIT(11);
|
||||
|
||||
while (max_rate > 127) {
|
||||
max_rate /= 10;
|
||||
max_exp++;
|
||||
}
|
||||
|
||||
while (min_rate > 127) {
|
||||
min_rate /= 10;
|
||||
min_exp++;
|
||||
}
|
||||
|
||||
reg |= (min_rate & 0x7f) << 20;
|
||||
reg |= (min_exp & 0xf) << 16;
|
||||
reg |= (weight & 0xf) << 12;
|
||||
reg |= (max_rate & 0x7f) << 4;
|
||||
reg |= max_exp & 0xf;
|
||||
mtk_w32(eth, reg, QTX_SCH(id));
|
||||
|
||||
resv &= 0xff;
|
||||
reg = mtk_r32(eth, QTX_CFG(id));
|
||||
reg &= 0xffff0000;
|
||||
reg |= (resv << 8) | resv;
|
||||
mtk_w32(eth, reg, QTX_CFG(id));
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mtk_init_foe_table(struct mtk_eth *eth)
|
||||
{
|
||||
if (eth->foe_table)
|
||||
return 0;
|
||||
|
||||
eth->foe_flow_table = devm_kcalloc(eth->dev, MTK_PPE_ENTRY_CNT,
|
||||
sizeof(*eth->foe_flow_table),
|
||||
GFP_KERNEL);
|
||||
if (!eth->foe_flow_table)
|
||||
return -EINVAL;
|
||||
|
||||
/* map the FOE table */
|
||||
eth->foe_table = dmam_alloc_coherent(eth->dev, MTK_PPE_TBL_SZ,
|
||||
ð->foe_table_phys, GFP_KERNEL);
|
||||
if (!eth->foe_table) {
|
||||
dev_err(eth->dev, "failed to allocate foe table\n");
|
||||
kfree(eth->foe_flow_table);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ppe_start(struct mtk_eth *eth)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mtk_init_foe_table(eth);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* tell the PPE about the tables base address */
|
||||
mtk_w32(eth, eth->foe_table_phys, MTK_REG_PPE_TB_BASE);
|
||||
|
||||
/* flush the table */
|
||||
memset(eth->foe_table, 0, MTK_PPE_TBL_SZ);
|
||||
|
||||
/* setup hashing */
|
||||
mtk_m32(eth,
|
||||
MTK_PPE_TB_CFG_HASH_MODE_MASK | MTK_PPE_TB_CFG_TBL_SZ_MASK,
|
||||
MTK_PPE_TB_CFG_HASH_MODE1 | MTK_PPE_TB_CFG_TBL_SZ_4K,
|
||||
MTK_REG_PPE_TB_CFG);
|
||||
|
||||
/* set the default hashing seed */
|
||||
mtk_w32(eth, MTK_PPE_HASH_SEED, MTK_REG_PPE_HASH_SEED);
|
||||
|
||||
/* each foe entry is 64bytes and is setup by cpu forwarding*/
|
||||
mtk_m32(eth, MTK_PPE_CAH_CTRL_X_MODE | MTK_PPE_TB_CFG_ENTRY_SZ_MASK |
|
||||
MTK_PPE_TB_CFG_SMA_MASK,
|
||||
MTK_PPE_TB_CFG_ENTRY_SZ_64B | MTK_PPE_TB_CFG_SMA_FWD_CPU,
|
||||
MTK_REG_PPE_TB_CFG);
|
||||
|
||||
/* set ip proto */
|
||||
mtk_w32(eth, 0xFFFFFFFF, MTK_REG_PPE_IP_PROT_CHK);
|
||||
|
||||
/* setup caching */
|
||||
mtk_m32(eth, 0, MTK_PPE_CAH_CTRL_X_MODE, MTK_REG_PPE_CAH_CTRL);
|
||||
mtk_m32(eth, MTK_PPE_CAH_CTRL_X_MODE, MTK_PPE_CAH_CTRL_EN,
|
||||
MTK_REG_PPE_CAH_CTRL);
|
||||
|
||||
/* enable FOE */
|
||||
mtk_m32(eth, 0, MTK_PPE_FLOW_CFG_IPV4_NAT_FRAG_EN |
|
||||
MTK_PPE_FLOW_CFG_IPV4_NAPT_EN | MTK_PPE_FLOW_CFG_IPV4_NAT_EN |
|
||||
MTK_PPE_FLOW_CFG_IPV4_GREK_EN,
|
||||
MTK_REG_PPE_FLOW_CFG);
|
||||
|
||||
/* setup flow entry un/bind aging */
|
||||
mtk_m32(eth, 0,
|
||||
MTK_PPE_TB_CFG_UNBD_AGE | MTK_PPE_TB_CFG_NTU_AGE |
|
||||
MTK_PPE_TB_CFG_FIN_AGE | MTK_PPE_TB_CFG_UDP_AGE |
|
||||
MTK_PPE_TB_CFG_TCP_AGE,
|
||||
MTK_REG_PPE_TB_CFG);
|
||||
|
||||
mtk_m32(eth, MTK_PPE_UNB_AGE_MNP_MASK | MTK_PPE_UNB_AGE_DLTA_MASK,
|
||||
MTK_PPE_UNB_AGE_MNP | MTK_PPE_UNB_AGE_DLTA,
|
||||
MTK_REG_PPE_UNB_AGE);
|
||||
mtk_m32(eth, MTK_PPE_BND_AGE0_NTU_DLTA_MASK |
|
||||
MTK_PPE_BND_AGE0_UDP_DLTA_MASK,
|
||||
MTK_PPE_BND_AGE0_NTU_DLTA | MTK_PPE_BND_AGE0_UDP_DLTA,
|
||||
MTK_REG_PPE_BND_AGE0);
|
||||
mtk_m32(eth, MTK_PPE_BND_AGE1_FIN_DLTA_MASK |
|
||||
MTK_PPE_BND_AGE1_TCP_DLTA_MASK,
|
||||
MTK_PPE_BND_AGE1_FIN_DLTA | MTK_PPE_BND_AGE1_TCP_DLTA,
|
||||
MTK_REG_PPE_BND_AGE1);
|
||||
|
||||
/* setup flow entry keep alive */
|
||||
mtk_m32(eth, MTK_PPE_TB_CFG_KA_MASK, MTK_PPE_TB_CFG_KA,
|
||||
MTK_REG_PPE_TB_CFG);
|
||||
mtk_w32(eth, MTK_PPE_KA_UDP | MTK_PPE_KA_TCP | MTK_PPE_KA_T, MTK_REG_PPE_KA);
|
||||
|
||||
/* setup flow entry rate limit */
|
||||
mtk_w32(eth, (0x3fff << 16) | 0x3fff, MTK_REG_PPE_BIND_LMT_0);
|
||||
mtk_w32(eth, MTK_PPE_NTU_KA | 0x3fff, MTK_REG_PPE_BIND_LMT_1);
|
||||
mtk_m32(eth, MTK_PPE_BNDR_RATE_MASK, 1, MTK_REG_PPE_BNDR);
|
||||
|
||||
/* enable the PPE */
|
||||
mtk_m32(eth, 0, MTK_PPE_GLO_CFG_EN, MTK_REG_PPE_GLO_CFG);
|
||||
|
||||
#ifdef CONFIG_RALINK
|
||||
/* set the default forwarding port to QDMA */
|
||||
mtk_w32(eth, 0x0, MTK_REG_PPE_DFT_CPORT);
|
||||
#else
|
||||
/* set the default forwarding port to QDMA */
|
||||
mtk_w32(eth, 0x55555555, MTK_REG_PPE_DFT_CPORT);
|
||||
#endif
|
||||
|
||||
/* drop packets with TTL=0 */
|
||||
mtk_m32(eth, 0, MTK_PPE_GLO_CFG_TTL0_DROP, MTK_REG_PPE_GLO_CFG);
|
||||
|
||||
/* send all traffic from gmac to the ppe */
|
||||
mtk_m32(eth, 0xffff, 0x4444, MTK_GDMA_FWD_CFG(0));
|
||||
mtk_m32(eth, 0xffff, 0x4444, MTK_GDMA_FWD_CFG(1));
|
||||
|
||||
dev_info(eth->dev, "PPE started\n");
|
||||
|
||||
#ifdef CONFIG_NET_MEDIATEK_HW_QOS
|
||||
mtk_ppe_scheduler(eth, 0, 500000);
|
||||
mtk_ppe_scheduler(eth, 1, 500000);
|
||||
mtk_ppe_queue(eth, 0, 0, 7, 32, 250000, 0);
|
||||
mtk_ppe_queue(eth, 1, 0, 7, 32, 250000, 0);
|
||||
mtk_ppe_queue(eth, 8, 1, 7, 32, 250000, 0);
|
||||
mtk_ppe_queue(eth, 9, 1, 7, 32, 250000, 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ppe_busy_wait(struct mtk_eth *eth)
|
||||
{
|
||||
unsigned long t_start = jiffies;
|
||||
u32 r = 0;
|
||||
|
||||
while (1) {
|
||||
r = mtk_r32(eth, MTK_REG_PPE_GLO_CFG);
|
||||
if (!(r & MTK_PPE_GLO_CFG_BUSY))
|
||||
return 0;
|
||||
if (time_after(jiffies, t_start + HZ))
|
||||
break;
|
||||
usleep_range(10, 20);
|
||||
}
|
||||
|
||||
dev_err(eth->dev, "ppe: table busy timeout - resetting\n");
|
||||
reset_control_reset(eth->rst_ppe);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int mtk_ppe_stop(struct mtk_eth *eth)
|
||||
{
|
||||
u32 r1 = 0, r2 = 0;
|
||||
int i;
|
||||
|
||||
/* discard all traffic while we disable the PPE */
|
||||
mtk_m32(eth, 0xffff, 0x7777, MTK_GDMA_FWD_CFG(0));
|
||||
mtk_m32(eth, 0xffff, 0x7777, MTK_GDMA_FWD_CFG(1));
|
||||
|
||||
if (mtk_ppe_busy_wait(eth))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* invalidate all flow table entries */
|
||||
for (i = 0; i < MTK_PPE_ENTRY_CNT; i++)
|
||||
eth->foe_table[i].bfib1.state = FOE_STATE_INVALID;
|
||||
|
||||
/* disable caching */
|
||||
mtk_m32(eth, 0, MTK_PPE_CAH_CTRL_X_MODE, MTK_REG_PPE_CAH_CTRL);
|
||||
mtk_m32(eth, MTK_PPE_CAH_CTRL_X_MODE | MTK_PPE_CAH_CTRL_EN, 0,
|
||||
MTK_REG_PPE_CAH_CTRL);
|
||||
|
||||
/* flush cache has to be ahead of hnat diable --*/
|
||||
mtk_m32(eth, MTK_PPE_GLO_CFG_EN, 0, MTK_REG_PPE_GLO_CFG);
|
||||
|
||||
/* disable FOE */
|
||||
mtk_m32(eth,
|
||||
MTK_PPE_FLOW_CFG_IPV4_NAT_FRAG_EN |
|
||||
MTK_PPE_FLOW_CFG_IPV4_NAPT_EN | MTK_PPE_FLOW_CFG_IPV4_NAT_EN |
|
||||
MTK_PPE_FLOW_CFG_FUC_FOE | MTK_PPE_FLOW_CFG_FMC_FOE,
|
||||
0, MTK_REG_PPE_FLOW_CFG);
|
||||
|
||||
/* disable FOE aging */
|
||||
mtk_m32(eth, 0,
|
||||
MTK_PPE_TB_CFG_FIN_AGE | MTK_PPE_TB_CFG_UDP_AGE |
|
||||
MTK_PPE_TB_CFG_TCP_AGE | MTK_PPE_TB_CFG_UNBD_AGE |
|
||||
MTK_PPE_TB_CFG_NTU_AGE, MTK_REG_PPE_TB_CFG);
|
||||
|
||||
r1 = mtk_r32(eth, 0x100);
|
||||
r2 = mtk_r32(eth, 0x10c);
|
||||
|
||||
dev_info(eth->dev, "0x100 = 0x%x, 0x10c = 0x%x\n", r1, r2);
|
||||
|
||||
if (((r1 & 0xff00) >> 0x8) >= (r1 & 0xff) ||
|
||||
((r1 & 0xff00) >> 0x8) >= (r2 & 0xff)) {
|
||||
dev_info(eth->dev, "reset pse\n");
|
||||
mtk_w32(eth, 0x1, 0x4);
|
||||
}
|
||||
|
||||
/* set the foe entry base address to 0 */
|
||||
mtk_w32(eth, 0, MTK_REG_PPE_TB_BASE);
|
||||
|
||||
if (mtk_ppe_busy_wait(eth))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* send all traffic back to the DMA engine */
|
||||
#ifdef CONFIG_RALINK
|
||||
mtk_m32(eth, 0xffff, 0x0, MTK_GDMA_FWD_CFG(0));
|
||||
mtk_m32(eth, 0xffff, 0x0, MTK_GDMA_FWD_CFG(1));
|
||||
#else
|
||||
mtk_m32(eth, 0xffff, 0x5555, MTK_GDMA_FWD_CFG(0));
|
||||
mtk_m32(eth, 0xffff, 0x5555, MTK_GDMA_FWD_CFG(1));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_offload_keepalive(struct fe_priv *eth, unsigned int hash)
|
||||
{
|
||||
struct flow_offload *flow;
|
||||
|
||||
rcu_read_lock();
|
||||
flow = rcu_dereference(eth->foe_flow_table[hash]);
|
||||
if (flow)
|
||||
flow->timeout = jiffies + 30 * HZ;
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
int mtk_offload_check_rx(struct fe_priv *eth, struct sk_buff *skb, u32 rxd4)
|
||||
{
|
||||
unsigned int hash;
|
||||
|
||||
switch (FIELD_GET(MTK_RXD4_CPU_REASON, rxd4)) {
|
||||
case MTK_CPU_REASON_KEEPALIVE_UC_OLD_HDR:
|
||||
case MTK_CPU_REASON_KEEPALIVE_MC_NEW_HDR:
|
||||
case MTK_CPU_REASON_KEEPALIVE_DUP_OLD_HDR:
|
||||
hash = FIELD_GET(MTK_RXD4_FOE_ENTRY, rxd4);
|
||||
mtk_offload_keepalive(eth, hash);
|
||||
return -1;
|
||||
case MTK_CPU_REASON_PACKET_SAMPLING:
|
||||
return -1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int mtk_ppe_probe(struct mtk_eth *eth)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mtk_ppe_start(eth);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mtk_ppe_debugfs_init(eth);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mtk_ppe_remove(struct mtk_eth *eth)
|
||||
{
|
||||
mtk_ppe_stop(eth);
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
|
||||
* Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/netfilter/nf_flow_table.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
|
||||
#ifdef CONFIG_RALINK
|
||||
/* ramips compat */
|
||||
#define mtk_eth fe_priv
|
||||
#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
|
||||
#define mtk_m32 fe_m32
|
||||
|
||||
static inline u32
|
||||
mtk_r32(struct mtk_eth *eth, u32 reg)
|
||||
{
|
||||
return fe_r32(reg);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mtk_w32(struct mtk_eth *eth, u32 val, u32 reg)
|
||||
{
|
||||
fe_w32(val, reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MTK_REG_PPE_GLO_CFG 0xe00
|
||||
#define MTK_PPE_GLO_CFG_BUSY BIT(31)
|
||||
#define MTK_PPE_GLO_CFG_TTL0_DROP BIT(4)
|
||||
#define MTK_PPE_GLO_CFG_EN BIT(0)
|
||||
|
||||
#define MTK_REG_PPE_FLOW_CFG 0xe04
|
||||
#define MTK_PPE_FLOW_CFG_IPV4_GREK_EN BIT(19)
|
||||
#define MTK_PPE_FLOW_CFG_IPV4_NAT_FRAG_EN BIT(17)
|
||||
#define MTK_PPE_FLOW_CFG_IPV4_NAPT_EN BIT(13)
|
||||
#define MTK_PPE_FLOW_CFG_IPV4_NAT_EN BIT(12)
|
||||
#define MTK_PPE_FLOW_CFG_FUC_FOE BIT(2)
|
||||
#define MTK_PPE_FLOW_CFG_FMC_FOE BIT(1)
|
||||
|
||||
#define MTK_REG_PPE_IP_PROT_CHK 0xe08
|
||||
|
||||
#define MTK_REG_PPE_TB_BASE 0xe20
|
||||
|
||||
#define MTK_REG_PPE_BNDR 0xe28
|
||||
#define MTK_PPE_BNDR_RATE_MASK 0xffff
|
||||
|
||||
#define MTK_REG_PPE_BIND_LMT_0 0xe2C
|
||||
|
||||
#define MTK_REG_PPE_BIND_LMT_1 0xe30
|
||||
#define MTK_PPE_NTU_KA BIT(16)
|
||||
|
||||
#define MTK_REG_PPE_KA 0xe34
|
||||
#define MTK_PPE_KA_T BIT(0)
|
||||
#define MTK_PPE_KA_TCP BIT(16)
|
||||
#define MTK_PPE_KA_UDP BIT(24)
|
||||
|
||||
#define MTK_REG_PPE_UNB_AGE 0xe38
|
||||
#define MTK_PPE_UNB_AGE_MNP_MASK (0xffff << 16)
|
||||
#define MTK_PPE_UNB_AGE_MNP (1000 << 16)
|
||||
#define MTK_PPE_UNB_AGE_DLTA_MASK 0xff
|
||||
#define MTK_PPE_UNB_AGE_DLTA 3
|
||||
|
||||
#define MTK_REG_PPE_BND_AGE0 0xe3c
|
||||
#define MTK_PPE_BND_AGE0_NTU_DLTA_MASK (0xffff << 16)
|
||||
#define MTK_PPE_BND_AGE0_NTU_DLTA (5 << 16)
|
||||
#define MTK_PPE_BND_AGE0_UDP_DLTA_MASK 0xffff
|
||||
#define MTK_PPE_BND_AGE0_UDP_DLTA 5
|
||||
|
||||
#define MTK_REG_PPE_BND_AGE1 0xe40
|
||||
#define MTK_PPE_BND_AGE1_FIN_DLTA_MASK (0xffff << 16)
|
||||
#define MTK_PPE_BND_AGE1_FIN_DLTA (5 << 16)
|
||||
#define MTK_PPE_BND_AGE1_TCP_DLTA_MASK 0xffff
|
||||
#define MTK_PPE_BND_AGE1_TCP_DLTA 5
|
||||
|
||||
#define MTK_REG_PPE_DFT_CPORT 0xe48
|
||||
|
||||
#define MTK_REG_PPE_TB_CFG 0xe1c
|
||||
#define MTK_PPE_TB_CFG_X_MODE_MASK (3 << 18)
|
||||
#define MTK_PPE_TB_CFG_HASH_MODE1 BIT(14)
|
||||
#define MTK_PPE_TB_CFG_HASH_MODE_MASK (0x3 << 14)
|
||||
#define MTK_PPE_TB_CFG_KA (3 << 12)
|
||||
#define MTK_PPE_TB_CFG_KA_MASK (0x3 << 12)
|
||||
#define MTK_PPE_TB_CFG_FIN_AGE BIT(11)
|
||||
#define MTK_PPE_TB_CFG_UDP_AGE BIT(10)
|
||||
#define MTK_PPE_TB_CFG_TCP_AGE BIT(9)
|
||||
#define MTK_PPE_TB_CFG_UNBD_AGE BIT(8)
|
||||
#define MTK_PPE_TB_CFG_NTU_AGE BIT(7)
|
||||
#define MTK_PPE_TB_CFG_SMA_FWD_CPU (0x3 << 4)
|
||||
#define MTK_PPE_TB_CFG_SMA_MASK (0x3 << 4)
|
||||
#define MTK_PPE_TB_CFG_ENTRY_SZ_64B 0
|
||||
#define MTK_PPE_TB_CFG_ENTRY_SZ_MASK BIT(3)
|
||||
#define MTK_PPE_TB_CFG_TBL_SZ_4K 2
|
||||
#define MTK_PPE_TB_CFG_TBL_SZ_MASK 0x7
|
||||
|
||||
#define MTK_REG_PPE_HASH_SEED 0xe44
|
||||
#define MTK_PPE_HASH_SEED 0x12345678
|
||||
|
||||
|
||||
#define MTK_REG_PPE_CAH_CTRL 0xf20
|
||||
#define MTK_PPE_CAH_CTRL_X_MODE BIT(9)
|
||||
#define MTK_PPE_CAH_CTRL_EN BIT(0)
|
||||
|
||||
struct mtk_foe_unbind_info_blk {
|
||||
u32 time_stamp:8;
|
||||
u32 pcnt:16; /* packet count */
|
||||
u32 preb:1;
|
||||
u32 pkt_type:3;
|
||||
u32 state:2;
|
||||
u32 udp:1;
|
||||
u32 sta:1; /* static entry */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct mtk_foe_bind_info_blk {
|
||||
u32 time_stamp:15;
|
||||
u32 ka:1; /* keep alive */
|
||||
u32 vlan_layer:3;
|
||||
u32 psn:1; /* egress packet has PPPoE session */
|
||||
#ifdef CONFIG_RALINK
|
||||
u32 vpm:2; /* 0:ethertype remark, 1:0x8100(CR default) */
|
||||
#else
|
||||
u32 vpm:1; /* 0:ethertype remark, 1:0x8100(CR default) */
|
||||
u32 ps:1; /* packet sampling */
|
||||
#endif
|
||||
u32 cah:1; /* cacheable flag */
|
||||
u32 rmt:1; /* remove tunnel ip header (6rd/dslite only) */
|
||||
u32 ttl:1;
|
||||
u32 pkt_type:3;
|
||||
u32 state:2;
|
||||
u32 udp:1;
|
||||
u32 sta:1; /* static entry */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct mtk_foe_info_blk2 {
|
||||
u32 qid:4; /* QID in Qos Port */
|
||||
u32 fqos:1; /* force to PSE QoS port */
|
||||
u32 dp:3; /* force to PSE port x
|
||||
0:PSE,1:GSW, 2:GMAC,4:PPE,5:QDMA,7=DROP */
|
||||
u32 mcast:1; /* multicast this packet to CPU */
|
||||
u32 pcpl:1; /* OSBN */
|
||||
u32 mlen:1; /* 0:post 1:pre packet length in meter */
|
||||
u32 alen:1; /* 0:post 1:pre packet length in accounting */
|
||||
u32 port_mg:6; /* port meter group */
|
||||
u32 port_ag:6; /* port account group */
|
||||
u32 dscp:8; /* DSCP value */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct mtk_foe_ipv4_hnapt {
|
||||
union {
|
||||
struct mtk_foe_bind_info_blk bfib1;
|
||||
struct mtk_foe_unbind_info_blk udib1;
|
||||
u32 info_blk1;
|
||||
};
|
||||
u32 sip;
|
||||
u32 dip;
|
||||
u16 dport;
|
||||
u16 sport;
|
||||
union {
|
||||
struct mtk_foe_info_blk2 iblk2;
|
||||
u32 info_blk2;
|
||||
};
|
||||
u32 new_sip;
|
||||
u32 new_dip;
|
||||
u16 new_dport;
|
||||
u16 new_sport;
|
||||
u32 resv1;
|
||||
u32 resv2;
|
||||
u32 resv3:26;
|
||||
u32 act_dp:6; /* UDF */
|
||||
u16 vlan1;
|
||||
u16 etype;
|
||||
u32 dmac_hi;
|
||||
u16 vlan2;
|
||||
u16 dmac_lo;
|
||||
u32 smac_hi;
|
||||
u16 pppoe_id;
|
||||
u16 smac_lo;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct mtk_foe_entry {
|
||||
union {
|
||||
struct mtk_foe_unbind_info_blk udib1;
|
||||
struct mtk_foe_bind_info_blk bfib1;
|
||||
struct mtk_foe_ipv4_hnapt ipv4_hnapt;
|
||||
};
|
||||
};
|
||||
|
||||
enum mtk_foe_entry_state {
|
||||
FOE_STATE_INVALID = 0,
|
||||
FOE_STATE_UNBIND = 1,
|
||||
FOE_STATE_BIND = 2,
|
||||
FOE_STATE_FIN = 3
|
||||
};
|
||||
|
||||
|
||||
#define MTK_RXD4_FOE_ENTRY GENMASK(13, 0)
|
||||
#define MTK_RXD4_CPU_REASON GENMASK(18, 14)
|
||||
#define MTK_RXD4_SRC_PORT GENMASK(21, 19)
|
||||
#define MTK_RXD4_ALG GENMASK(31, 22)
|
||||
|
||||
enum mtk_foe_cpu_reason {
|
||||
MTK_CPU_REASON_TTL_EXCEEDED = 0x02,
|
||||
MTK_CPU_REASON_OPTION_HEADER = 0x03,
|
||||
MTK_CPU_REASON_NO_FLOW = 0x07,
|
||||
MTK_CPU_REASON_IPV4_FRAG = 0x08,
|
||||
MTK_CPU_REASON_IPV4_DSLITE_FRAG = 0x09,
|
||||
MTK_CPU_REASON_IPV4_DSLITE_NO_TCP_UDP = 0x0a,
|
||||
MTK_CPU_REASON_IPV6_6RD_NO_TCP_UDP = 0x0b,
|
||||
MTK_CPU_REASON_TCP_FIN_SYN_RST = 0x0c,
|
||||
MTK_CPU_REASON_UN_HIT = 0x0d,
|
||||
MTK_CPU_REASON_HIT_UNBIND = 0x0e,
|
||||
MTK_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f,
|
||||
MTK_CPU_REASON_HIT_BIND_TCP_FIN = 0x10,
|
||||
MTK_CPU_REASON_HIT_TTL_1 = 0x11,
|
||||
MTK_CPU_REASON_HIT_BIND_VLAN_VIOLATION = 0x12,
|
||||
MTK_CPU_REASON_KEEPALIVE_UC_OLD_HDR = 0x13,
|
||||
MTK_CPU_REASON_KEEPALIVE_MC_NEW_HDR = 0x14,
|
||||
MTK_CPU_REASON_KEEPALIVE_DUP_OLD_HDR = 0x15,
|
||||
MTK_CPU_REASON_HIT_BIND_FORCE_CPU = 0x16,
|
||||
MTK_CPU_REASON_TUNNEL_OPTION_HEADER = 0x17,
|
||||
MTK_CPU_REASON_MULTICAST_TO_CPU = 0x18,
|
||||
MTK_CPU_REASON_MULTICAST_TO_GMAC1_CPU = 0x19,
|
||||
MTK_CPU_REASON_HIT_PRE_BIND = 0x1a,
|
||||
MTK_CPU_REASON_PACKET_SAMPLING = 0x1b,
|
||||
MTK_CPU_REASON_EXCEED_MTU = 0x1c,
|
||||
MTK_CPU_REASON_PPE_BYPASS = 0x1e,
|
||||
MTK_CPU_REASON_INVALID = 0x1f,
|
||||
};
|
||||
|
||||
|
||||
/* our table size is 4K */
|
||||
#define MTK_PPE_ENTRY_CNT 0x1000
|
||||
#define MTK_PPE_TBL_SZ \
|
||||
(MTK_PPE_ENTRY_CNT * sizeof(struct mtk_foe_entry))
|
||||
|
||||
int mtk_ppe_debugfs_init(struct mtk_eth *eth);
|
||||
|
||||
|
@ -0,0 +1,335 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/of_net.h>
|
||||
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include <mt7620.h>
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "gsw_mt7620.h"
|
||||
#include "mt7530.h"
|
||||
#include "mdio.h"
|
||||
|
||||
#define MT7620A_CDMA_CSG_CFG 0x400
|
||||
#define MT7620_DMA_VID (MT7620A_CDMA_CSG_CFG | 0x30)
|
||||
#define MT7621_CDMP_IG_CTRL (MT7620A_CDMA_CSG_CFG + 0x00)
|
||||
#define MT7621_CDMP_EG_CTRL (MT7620A_CDMA_CSG_CFG + 0x04)
|
||||
#define MT7620A_RESET_FE BIT(21)
|
||||
#define MT7621_RESET_FE BIT(6)
|
||||
#define MT7620A_RESET_ESW BIT(23)
|
||||
#define MT7620_L4_VALID BIT(23)
|
||||
#define MT7621_L4_VALID BIT(24)
|
||||
|
||||
#define MT7620_TX_DMA_UDF BIT(15)
|
||||
#define MT7621_TX_DMA_UDF BIT(19)
|
||||
#define TX_DMA_FP_BMAP ((0xff) << 19)
|
||||
|
||||
#define CDMA_ICS_EN BIT(2)
|
||||
#define CDMA_UCS_EN BIT(1)
|
||||
#define CDMA_TCS_EN BIT(0)
|
||||
|
||||
#define GDMA_ICS_EN BIT(22)
|
||||
#define GDMA_TCS_EN BIT(21)
|
||||
#define GDMA_UCS_EN BIT(20)
|
||||
|
||||
/* frame engine counters */
|
||||
#define MT7620_REG_MIB_OFFSET 0x1000
|
||||
#define MT7620_PPE_AC_BCNT0 (MT7620_REG_MIB_OFFSET + 0x00)
|
||||
#define MT7620_GDM1_TX_GBCNT (MT7620_REG_MIB_OFFSET + 0x300)
|
||||
#define MT7620_GDM2_TX_GBCNT (MT7620_GDM1_TX_GBCNT + 0x40)
|
||||
|
||||
#define MT7621_REG_MIB_OFFSET 0x2000
|
||||
#define MT7621_PPE_AC_BCNT0 (MT7621_REG_MIB_OFFSET + 0x00)
|
||||
#define MT7621_GDM1_TX_GBCNT (MT7621_REG_MIB_OFFSET + 0x400)
|
||||
#define MT7621_GDM2_TX_GBCNT (MT7621_GDM1_TX_GBCNT + 0x40)
|
||||
|
||||
#define GSW_REG_GDMA1_MAC_ADRL 0x508
|
||||
#define GSW_REG_GDMA1_MAC_ADRH 0x50C
|
||||
|
||||
#define MT7621_FE_RST_GL (FE_FE_OFFSET + 0x04)
|
||||
#define MT7620_FE_INT_STATUS2 (FE_FE_OFFSET + 0x08)
|
||||
|
||||
/* FE_INT_STATUS reg on mt7620 define CNT_GDM1_AF at BIT(29)
|
||||
* but after test it should be BIT(13).
|
||||
*/
|
||||
#define MT7620_FE_GDM1_AF BIT(13)
|
||||
#define MT7621_FE_GDM1_AF BIT(28)
|
||||
#define MT7621_FE_GDM2_AF BIT(29)
|
||||
|
||||
static const u16 mt7620_reg_table[FE_REG_COUNT] = {
|
||||
[FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
|
||||
[FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
|
||||
[FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
|
||||
[FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
|
||||
[FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
|
||||
[FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
|
||||
[FE_REG_TX_DTX_IDX0] = RT5350_TX_DTX_IDX0,
|
||||
[FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
|
||||
[FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
|
||||
[FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
|
||||
[FE_REG_RX_DRX_IDX0] = RT5350_RX_DRX_IDX0,
|
||||
[FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
|
||||
[FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
|
||||
[FE_REG_FE_DMA_VID_BASE] = MT7620_DMA_VID,
|
||||
[FE_REG_FE_COUNTER_BASE] = MT7620_GDM1_TX_GBCNT,
|
||||
[FE_REG_FE_RST_GL] = MT7621_FE_RST_GL,
|
||||
[FE_REG_FE_INT_STATUS2] = MT7620_FE_INT_STATUS2,
|
||||
};
|
||||
|
||||
static int mt7620_gsw_config(struct fe_priv *priv)
|
||||
{
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
|
||||
|
||||
/* is the mt7530 internal or external */
|
||||
if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, 0x1f)) {
|
||||
mt7530_probe(priv->dev, gsw->base, NULL, 0);
|
||||
mt7530_probe(priv->dev, NULL, priv->mii_bus, 1);
|
||||
} else {
|
||||
mt7530_probe(priv->dev, gsw->base, NULL, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac)
|
||||
{
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->page_lock, flags);
|
||||
mtk_switch_w32(gsw, (mac[0] << 8) | mac[1], GSW_REG_SMACCR1);
|
||||
mtk_switch_w32(gsw, (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
|
||||
GSW_REG_SMACCR0);
|
||||
spin_unlock_irqrestore(&priv->page_lock, flags);
|
||||
}
|
||||
|
||||
static void mt7620_auto_poll(struct mt7620_gsw *gsw)
|
||||
{
|
||||
int phy;
|
||||
int lsb = -1, msb = 0;
|
||||
|
||||
for_each_set_bit(phy, &gsw->autopoll, 32) {
|
||||
if (lsb < 0)
|
||||
lsb = phy;
|
||||
msb = phy;
|
||||
}
|
||||
|
||||
if (lsb == msb)
|
||||
lsb--;
|
||||
|
||||
mtk_switch_w32(gsw, PHY_AN_EN | PHY_PRE_EN | PMY_MDC_CONF(5) |
|
||||
(msb << 8) | lsb, ESW_PHY_POLLING);
|
||||
}
|
||||
|
||||
static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
|
||||
{
|
||||
struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
|
||||
const __be32 *_id = of_get_property(np, "reg", NULL);
|
||||
int phy_mode, size, id;
|
||||
int shift = 12;
|
||||
u32 val, mask = 0;
|
||||
int min = (gsw->port4 == PORT4_EPHY) ? (5) : (4);
|
||||
|
||||
if (!_id || (be32_to_cpu(*_id) < min) || (be32_to_cpu(*_id) > 5)) {
|
||||
if (_id)
|
||||
pr_err("%s: invalid port id %d\n", np->name,
|
||||
be32_to_cpu(*_id));
|
||||
else
|
||||
pr_err("%s: invalid port id\n", np->name);
|
||||
return;
|
||||
}
|
||||
|
||||
id = be32_to_cpu(*_id);
|
||||
|
||||
if (id == 4)
|
||||
shift = 14;
|
||||
|
||||
priv->phy->phy_fixed[id] = of_get_property(np, "mediatek,fixed-link",
|
||||
&size);
|
||||
if (priv->phy->phy_fixed[id] &&
|
||||
(size != (4 * sizeof(*priv->phy->phy_fixed[id])))) {
|
||||
pr_err("%s: invalid fixed link property\n", np->name);
|
||||
priv->phy->phy_fixed[id] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
phy_mode = of_get_phy_mode(np);
|
||||
switch (phy_mode) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
mask = 0;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_MII:
|
||||
mask = 1;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
mask = 2;
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->dev, "port %d - invalid phy mode\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->phy->phy_node[id] = of_parse_phandle(np, "phy-handle", 0);
|
||||
if (!priv->phy->phy_node[id] && !priv->phy->phy_fixed[id])
|
||||
return;
|
||||
|
||||
val = rt_sysc_r32(SYSC_REG_CFG1);
|
||||
val &= ~(3 << shift);
|
||||
val |= mask << shift;
|
||||
rt_sysc_w32(val, SYSC_REG_CFG1);
|
||||
|
||||
if (priv->phy->phy_fixed[id]) {
|
||||
const __be32 *link = priv->phy->phy_fixed[id];
|
||||
int tx_fc, rx_fc;
|
||||
u32 val = 0;
|
||||
|
||||
priv->phy->speed[id] = be32_to_cpup(link++);
|
||||
tx_fc = be32_to_cpup(link++);
|
||||
rx_fc = be32_to_cpup(link++);
|
||||
priv->phy->duplex[id] = be32_to_cpup(link++);
|
||||
priv->link[id] = 1;
|
||||
|
||||
switch (priv->phy->speed[id]) {
|
||||
case SPEED_10:
|
||||
val = 0;
|
||||
break;
|
||||
case SPEED_100:
|
||||
val = 1;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
val = 2;
|
||||
break;
|
||||
default:
|
||||
dev_err(priv->dev, "invalid link speed: %d\n",
|
||||
priv->phy->speed[id]);
|
||||
priv->phy->phy_fixed[id] = 0;
|
||||
return;
|
||||
}
|
||||
val = PMCR_SPEED(val);
|
||||
val |= PMCR_LINK | PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
|
||||
PMCR_TX_EN | PMCR_FORCE | PMCR_MAC_MODE | PMCR_IPG;
|
||||
if (tx_fc)
|
||||
val |= PMCR_TX_FC;
|
||||
if (rx_fc)
|
||||
val |= PMCR_RX_FC;
|
||||
if (priv->phy->duplex[id])
|
||||
val |= PMCR_DUPLEX;
|
||||
mtk_switch_w32(gsw, val, GSW_REG_PORT_PMCR(id));
|
||||
dev_info(priv->dev, "using fixed link parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->phy->phy_node[id] && mdiobus_get_phy(priv->mii_bus, id)) {
|
||||
u32 val = PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
|
||||
PMCR_TX_EN | PMCR_MAC_MODE | PMCR_IPG;
|
||||
|
||||
mtk_switch_w32(gsw, val, GSW_REG_PORT_PMCR(id));
|
||||
fe_connect_phy_node(priv, priv->phy->phy_node[id]);
|
||||
gsw->autopoll |= BIT(id);
|
||||
mt7620_auto_poll(gsw);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void mt7620_fe_reset(void)
|
||||
{
|
||||
fe_reset(MT7620A_RESET_FE | MT7620A_RESET_ESW);
|
||||
}
|
||||
|
||||
static void mt7620_rxcsum_config(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) | (GDMA_ICS_EN |
|
||||
GDMA_TCS_EN | GDMA_UCS_EN),
|
||||
MT7620A_GDMA1_FWD_CFG);
|
||||
else
|
||||
fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~(GDMA_ICS_EN |
|
||||
GDMA_TCS_EN | GDMA_UCS_EN),
|
||||
MT7620A_GDMA1_FWD_CFG);
|
||||
}
|
||||
|
||||
static void mt7620_txcsum_config(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
fe_w32(fe_r32(MT7620A_CDMA_CSG_CFG) | (CDMA_ICS_EN |
|
||||
CDMA_UCS_EN | CDMA_TCS_EN),
|
||||
MT7620A_CDMA_CSG_CFG);
|
||||
else
|
||||
fe_w32(fe_r32(MT7620A_CDMA_CSG_CFG) & ~(CDMA_ICS_EN |
|
||||
CDMA_UCS_EN | CDMA_TCS_EN),
|
||||
MT7620A_CDMA_CSG_CFG);
|
||||
}
|
||||
|
||||
static int mt7620_fwd_config(struct fe_priv *priv)
|
||||
{
|
||||
struct net_device *dev = priv_netdev(priv);
|
||||
|
||||
fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~7, MT7620A_GDMA1_FWD_CFG);
|
||||
|
||||
mt7620_txcsum_config((dev->features & NETIF_F_IP_CSUM));
|
||||
mt7620_rxcsum_config((dev->features & NETIF_F_RXCSUM));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7620_tx_dma(struct fe_tx_dma *txd)
|
||||
{
|
||||
}
|
||||
|
||||
static void mt7620_init_data(struct fe_soc_data *data,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_RX_2B_OFFSET |
|
||||
FE_FLAG_RX_SG_DMA | FE_FLAG_HAS_SWITCH;
|
||||
|
||||
netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_HW_VLAN_CTAG_TX;
|
||||
if (mt7620_get_eco() >= 5)
|
||||
netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
|
||||
NETIF_F_IPV6_CSUM;
|
||||
}
|
||||
|
||||
static struct fe_soc_data mt7620_data = {
|
||||
.init_data = mt7620_init_data,
|
||||
.reset_fe = mt7620_fe_reset,
|
||||
.set_mac = mt7620_set_mac,
|
||||
.fwd_config = mt7620_fwd_config,
|
||||
.tx_dma = mt7620_tx_dma,
|
||||
.switch_init = mtk_gsw_init,
|
||||
.switch_config = mt7620_gsw_config,
|
||||
.port_init = mt7620_port_init,
|
||||
.reg_table = mt7620_reg_table,
|
||||
.pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS,
|
||||
.rx_int = RT5350_RX_DONE_INT,
|
||||
.tx_int = RT5350_TX_DONE_INT,
|
||||
.status_int = MT7620_FE_GDM1_AF,
|
||||
.checksum_bit = MT7620_L4_VALID,
|
||||
.has_carrier = mt7620_has_carrier,
|
||||
.mdio_read = mt7620_mdio_read,
|
||||
.mdio_write = mt7620_mdio_write,
|
||||
.mdio_adjust_link = mt7620_mdio_link_adjust,
|
||||
};
|
||||
|
||||
const struct of_device_id of_fe_match[] = {
|
||||
{ .compatible = "mediatek,mt7620-eth", .data = &mt7620_data },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_fe_match);
|
@ -0,0 +1,185 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/of_net.h>
|
||||
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "gsw_mt7620.h"
|
||||
#include "mt7530.h"
|
||||
#include "mdio.h"
|
||||
|
||||
#define MT7620A_CDMA_CSG_CFG 0x400
|
||||
#define MT7621_CDMP_IG_CTRL (MT7620A_CDMA_CSG_CFG + 0x00)
|
||||
#define MT7621_CDMP_EG_CTRL (MT7620A_CDMA_CSG_CFG + 0x04)
|
||||
#define MT7621_RESET_FE BIT(6)
|
||||
#define MT7621_L4_VALID BIT(24)
|
||||
|
||||
#define MT7621_TX_DMA_UDF BIT(19)
|
||||
#define MT7621_TX_DMA_FPORT BIT(25)
|
||||
|
||||
#define CDMA_ICS_EN BIT(2)
|
||||
#define CDMA_UCS_EN BIT(1)
|
||||
#define CDMA_TCS_EN BIT(0)
|
||||
|
||||
#define GDMA_ICS_EN BIT(22)
|
||||
#define GDMA_TCS_EN BIT(21)
|
||||
#define GDMA_UCS_EN BIT(20)
|
||||
|
||||
/* frame engine counters */
|
||||
#define MT7621_REG_MIB_OFFSET 0x2000
|
||||
#define MT7621_PPE_AC_BCNT0 (MT7621_REG_MIB_OFFSET + 0x00)
|
||||
#define MT7621_GDM1_TX_GBCNT (MT7621_REG_MIB_OFFSET + 0x400)
|
||||
#define MT7621_GDM2_TX_GBCNT (MT7621_GDM1_TX_GBCNT + 0x40)
|
||||
|
||||
#define GSW_REG_GDMA1_MAC_ADRL 0x508
|
||||
#define GSW_REG_GDMA1_MAC_ADRH 0x50C
|
||||
|
||||
#define MT7621_FE_RST_GL (FE_FE_OFFSET + 0x04)
|
||||
#define MT7620_FE_INT_STATUS2 (FE_FE_OFFSET + 0x08)
|
||||
|
||||
/* FE_INT_STATUS reg on mt7620 define CNT_GDM1_AF at BIT(29)
|
||||
* but after test it should be BIT(13).
|
||||
*/
|
||||
#define MT7620_FE_GDM1_AF BIT(13)
|
||||
#define MT7621_FE_GDM1_AF BIT(28)
|
||||
#define MT7621_FE_GDM2_AF BIT(29)
|
||||
|
||||
static const u16 mt7621_reg_table[FE_REG_COUNT] = {
|
||||
[FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
|
||||
[FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
|
||||
[FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
|
||||
[FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
|
||||
[FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
|
||||
[FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
|
||||
[FE_REG_TX_DTX_IDX0] = RT5350_TX_DTX_IDX0,
|
||||
[FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
|
||||
[FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
|
||||
[FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
|
||||
[FE_REG_RX_DRX_IDX0] = RT5350_RX_DRX_IDX0,
|
||||
[FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
|
||||
[FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
|
||||
[FE_REG_FE_DMA_VID_BASE] = 0,
|
||||
[FE_REG_FE_COUNTER_BASE] = MT7621_GDM1_TX_GBCNT,
|
||||
[FE_REG_FE_RST_GL] = MT7621_FE_RST_GL,
|
||||
[FE_REG_FE_INT_STATUS2] = MT7620_FE_INT_STATUS2,
|
||||
};
|
||||
|
||||
static int mt7621_gsw_config(struct fe_priv *priv)
|
||||
{
|
||||
if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, 0x1f))
|
||||
mt7530_probe(priv->dev, NULL, priv->mii_bus, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7621_fe_reset(void)
|
||||
{
|
||||
fe_reset(MT7621_RESET_FE);
|
||||
}
|
||||
|
||||
static void mt7621_rxcsum_config(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) | (GDMA_ICS_EN |
|
||||
GDMA_TCS_EN | GDMA_UCS_EN),
|
||||
MT7620A_GDMA1_FWD_CFG);
|
||||
else
|
||||
fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~(GDMA_ICS_EN |
|
||||
GDMA_TCS_EN | GDMA_UCS_EN),
|
||||
MT7620A_GDMA1_FWD_CFG);
|
||||
}
|
||||
|
||||
static void mt7621_rxvlan_config(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
fe_w32(1, MT7621_CDMP_EG_CTRL);
|
||||
else
|
||||
fe_w32(0, MT7621_CDMP_EG_CTRL);
|
||||
}
|
||||
|
||||
static int mt7621_fwd_config(struct fe_priv *priv)
|
||||
{
|
||||
struct net_device *dev = priv_netdev(priv);
|
||||
|
||||
fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~0xffff,
|
||||
MT7620A_GDMA1_FWD_CFG);
|
||||
|
||||
/* mt7621 doesn't have txcsum config */
|
||||
mt7621_rxcsum_config((dev->features & NETIF_F_RXCSUM));
|
||||
mt7621_rxvlan_config(priv->flags & FE_FLAG_RX_VLAN_CTAG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7621_tx_dma(struct fe_tx_dma *txd)
|
||||
{
|
||||
txd->txd4 = MT7621_TX_DMA_FPORT;
|
||||
}
|
||||
|
||||
static void mt7621_init_data(struct fe_soc_data *data,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_RX_2B_OFFSET |
|
||||
FE_FLAG_RX_SG_DMA | FE_FLAG_NAPI_WEIGHT |
|
||||
FE_FLAG_HAS_SWITCH | FE_FLAG_JUMBO_FRAME;
|
||||
|
||||
netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
||||
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_SG | NETIF_F_TSO |
|
||||
NETIF_F_TSO6 | NETIF_F_IPV6_CSUM;
|
||||
}
|
||||
|
||||
static void mt7621_set_mac(struct fe_priv *priv, unsigned char *mac)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->page_lock, flags);
|
||||
fe_w32((mac[0] << 8) | mac[1], GSW_REG_GDMA1_MAC_ADRH);
|
||||
fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
|
||||
GSW_REG_GDMA1_MAC_ADRL);
|
||||
spin_unlock_irqrestore(&priv->page_lock, flags);
|
||||
}
|
||||
|
||||
static struct fe_soc_data mt7621_data = {
|
||||
.init_data = mt7621_init_data,
|
||||
.reset_fe = mt7621_fe_reset,
|
||||
.set_mac = mt7621_set_mac,
|
||||
.fwd_config = mt7621_fwd_config,
|
||||
.tx_dma = mt7621_tx_dma,
|
||||
.switch_init = mtk_gsw_init,
|
||||
.switch_config = mt7621_gsw_config,
|
||||
.reg_table = mt7621_reg_table,
|
||||
.pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS,
|
||||
.rx_int = RT5350_RX_DONE_INT,
|
||||
.tx_int = RT5350_TX_DONE_INT,
|
||||
.status_int = (MT7621_FE_GDM1_AF | MT7621_FE_GDM2_AF),
|
||||
.checksum_bit = MT7621_L4_VALID,
|
||||
.has_carrier = mt7620_has_carrier,
|
||||
.mdio_read = mt7620_mdio_read,
|
||||
.mdio_write = mt7620_mdio_write,
|
||||
.mdio_adjust_link = mt7620_mdio_link_adjust,
|
||||
};
|
||||
|
||||
const struct of_device_id of_fe_match[] = {
|
||||
{ .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_fe_match);
|
@ -0,0 +1,76 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "mdio_rt2880.h"
|
||||
|
||||
#define RT2880_RESET_FE BIT(18)
|
||||
|
||||
static void rt2880_init_data(struct fe_soc_data *data,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_PADDING_BUG |
|
||||
FE_FLAG_JUMBO_FRAME | FE_FLAG_CALIBRATE_CLK;
|
||||
netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_TX;
|
||||
/* this should work according to the datasheet but actually does not*/
|
||||
/* netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; */
|
||||
}
|
||||
|
||||
void rt2880_fe_reset(void)
|
||||
{
|
||||
fe_reset(RT2880_RESET_FE);
|
||||
}
|
||||
|
||||
static int rt2880_fwd_config(struct fe_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fe_set_clock_cycle(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fe_fwd_config(priv);
|
||||
fe_w32(FE_PSE_FQFC_CFG_INIT, FE_PSE_FQ_CFG);
|
||||
fe_csum_config(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct fe_soc_data rt2880_data = {
|
||||
.init_data = rt2880_init_data,
|
||||
.reset_fe = rt2880_fe_reset,
|
||||
.fwd_config = rt2880_fwd_config,
|
||||
.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
|
||||
.checksum_bit = RX_DMA_L4VALID,
|
||||
.rx_int = FE_RX_DONE_INT,
|
||||
.tx_int = FE_TX_DONE_INT,
|
||||
.status_int = FE_CNT_GDM_AF,
|
||||
.mdio_read = rt2880_mdio_read,
|
||||
.mdio_write = rt2880_mdio_write,
|
||||
.mdio_adjust_link = rt2880_mdio_link_adjust,
|
||||
.port_init = rt2880_port_init,
|
||||
};
|
||||
|
||||
const struct of_device_id of_fe_match[] = {
|
||||
{ .compatible = "ralink,rt2880-eth", .data = &rt2880_data },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_fe_match);
|
@ -0,0 +1,158 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "mdio_rt2880.h"
|
||||
|
||||
#define RT305X_RESET_FE BIT(21)
|
||||
#define RT305X_RESET_ESW BIT(23)
|
||||
|
||||
static const u16 rt5350_reg_table[FE_REG_COUNT] = {
|
||||
[FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
|
||||
[FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
|
||||
[FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
|
||||
[FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
|
||||
[FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
|
||||
[FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
|
||||
[FE_REG_TX_DTX_IDX0] = RT5350_TX_DTX_IDX0,
|
||||
[FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
|
||||
[FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
|
||||
[FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
|
||||
[FE_REG_RX_DRX_IDX0] = RT5350_RX_DRX_IDX0,
|
||||
[FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
|
||||
[FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
|
||||
[FE_REG_FE_RST_GL] = 0,
|
||||
[FE_REG_FE_DMA_VID_BASE] = 0,
|
||||
};
|
||||
|
||||
static void rt305x_init_data(struct fe_soc_data *data,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_PADDING_BUG |
|
||||
FE_FLAG_CALIBRATE_CLK | FE_FLAG_HAS_SWITCH;
|
||||
netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
|
||||
NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX;
|
||||
}
|
||||
|
||||
static int rt3050_fwd_config(struct fe_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ralink_soc != RT305X_SOC_RT3052) {
|
||||
ret = fe_set_clock_cycle(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
fe_fwd_config(priv);
|
||||
if (ralink_soc != RT305X_SOC_RT3352)
|
||||
fe_w32(FE_PSE_FQFC_CFG_INIT, FE_PSE_FQ_CFG);
|
||||
fe_csum_config(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt305x_fe_reset(void)
|
||||
{
|
||||
fe_reset(RT305X_RESET_FE);
|
||||
}
|
||||
|
||||
static void rt5350_init_data(struct fe_soc_data *data,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->flags = FE_FLAG_HAS_SWITCH;
|
||||
netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM;
|
||||
}
|
||||
|
||||
static void rt5350_set_mac(struct fe_priv *priv, unsigned char *mac)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->page_lock, flags);
|
||||
fe_w32((mac[0] << 8) | mac[1], RT5350_SDM_MAC_ADRH);
|
||||
fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
|
||||
RT5350_SDM_MAC_ADRL);
|
||||
spin_unlock_irqrestore(&priv->page_lock, flags);
|
||||
}
|
||||
|
||||
static void rt5350_rxcsum_config(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
fe_w32(fe_r32(RT5350_SDM_CFG) | (RT5350_SDM_ICS_EN |
|
||||
RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN),
|
||||
RT5350_SDM_CFG);
|
||||
else
|
||||
fe_w32(fe_r32(RT5350_SDM_CFG) & ~(RT5350_SDM_ICS_EN |
|
||||
RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN),
|
||||
RT5350_SDM_CFG);
|
||||
}
|
||||
|
||||
static int rt5350_fwd_config(struct fe_priv *priv)
|
||||
{
|
||||
struct net_device *dev = priv_netdev(priv);
|
||||
|
||||
rt5350_rxcsum_config((dev->features & NETIF_F_RXCSUM));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt5350_tx_dma(struct fe_tx_dma *txd)
|
||||
{
|
||||
txd->txd4 = 0;
|
||||
}
|
||||
|
||||
static void rt5350_fe_reset(void)
|
||||
{
|
||||
fe_reset(RT305X_RESET_FE | RT305X_RESET_ESW);
|
||||
}
|
||||
|
||||
static struct fe_soc_data rt3050_data = {
|
||||
.init_data = rt305x_init_data,
|
||||
.reset_fe = rt305x_fe_reset,
|
||||
.fwd_config = rt3050_fwd_config,
|
||||
.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
|
||||
.checksum_bit = RX_DMA_L4VALID,
|
||||
.rx_int = FE_RX_DONE_INT,
|
||||
.tx_int = FE_TX_DONE_INT,
|
||||
.status_int = FE_CNT_GDM_AF,
|
||||
};
|
||||
|
||||
static struct fe_soc_data rt5350_data = {
|
||||
.init_data = rt5350_init_data,
|
||||
.reg_table = rt5350_reg_table,
|
||||
.reset_fe = rt5350_fe_reset,
|
||||
.set_mac = rt5350_set_mac,
|
||||
.fwd_config = rt5350_fwd_config,
|
||||
.tx_dma = rt5350_tx_dma,
|
||||
.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
|
||||
.checksum_bit = RX_DMA_L4VALID,
|
||||
.rx_int = RT5350_RX_DONE_INT,
|
||||
.tx_int = RT5350_TX_DONE_INT,
|
||||
};
|
||||
|
||||
const struct of_device_id of_fe_match[] = {
|
||||
{ .compatible = "ralink,rt3050-eth", .data = &rt3050_data },
|
||||
{ .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_fe_match);
|
@ -0,0 +1,75 @@
|
||||
/* 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; version 2 of the License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
|
||||
* Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/mach-ralink/ralink_regs.h>
|
||||
|
||||
#include "mtk_eth_soc.h"
|
||||
#include "mdio_rt2880.h"
|
||||
|
||||
#define RT3883_RSTCTRL_FE BIT(21)
|
||||
|
||||
static void rt3883_fe_reset(void)
|
||||
{
|
||||
fe_reset(RT3883_RSTCTRL_FE);
|
||||
}
|
||||
|
||||
static int rt3883_fwd_config(struct fe_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fe_set_clock_cycle(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fe_fwd_config(priv);
|
||||
fe_w32(FE_PSE_FQFC_CFG_256Q, FE_PSE_FQ_CFG);
|
||||
fe_csum_config(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rt3883_init_data(struct fe_soc_data *data,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct fe_priv *priv = netdev_priv(netdev);
|
||||
|
||||
priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_PADDING_BUG |
|
||||
FE_FLAG_JUMBO_FRAME | FE_FLAG_CALIBRATE_CLK;
|
||||
netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
|
||||
NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX;
|
||||
}
|
||||
|
||||
static struct fe_soc_data rt3883_data = {
|
||||
.init_data = rt3883_init_data,
|
||||
.reset_fe = rt3883_fe_reset,
|
||||
.fwd_config = rt3883_fwd_config,
|
||||
.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
|
||||
.rx_int = FE_RX_DONE_INT,
|
||||
.tx_int = FE_TX_DONE_INT,
|
||||
.status_int = FE_CNT_GDM_AF,
|
||||
.checksum_bit = RX_DMA_L4VALID,
|
||||
.mdio_read = rt2880_mdio_read,
|
||||
.mdio_write = rt2880_mdio_write,
|
||||
.mdio_adjust_link = rt2880_mdio_link_adjust,
|
||||
.port_init = rt2880_port_init,
|
||||
};
|
||||
|
||||
const struct of_device_id of_fe_match[] = {
|
||||
{ .compatible = "ralink,rt3883-eth", .data = &rt3883_data },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_fe_match);
|
@ -111,6 +111,26 @@ define Build/wrg-header
|
||||
mv $@.new $@
|
||||
endef
|
||||
|
||||
# combine kernel and rootfs into one image
|
||||
# mkdlinkfw <type> <optional extra arguments to mkdlinkfw binary>
|
||||
|
||||
define Build/mkdlinkfw
|
||||
-$(STAGING_DIR_HOST)/bin/mkdlinkfw \
|
||||
-k $(IMAGE_KERNEL) \
|
||||
-r $(IMAGE_ROOTFS) \
|
||||
-o $@ \
|
||||
-s $(DLINK_FIRMWARE_SIZE)
|
||||
endef
|
||||
|
||||
define Build/mkdlinkfw-factory
|
||||
-$(STAGING_DIR_HOST)/bin/mkdlinkfw \
|
||||
-m $(DLINK_ROM_ID) -f $(DLINK_FAMILY_MEMBER) \
|
||||
-F $@ \
|
||||
-o $@.new \
|
||||
-s $(DLINK_FIRMWARE_SIZE)
|
||||
mv $@.new $@
|
||||
endef
|
||||
|
||||
#
|
||||
# The real magic happens inside these templates
|
||||
#
|
||||
@ -118,7 +138,7 @@ endef
|
||||
# $(2), filename of image data
|
||||
# $(3), output filename
|
||||
define MkImage
|
||||
$(eval imagename=$(if $(4),$(4),MIPS OpenWrt Linux-$(LINUX_VERSION)))
|
||||
$(eval imagename=$(if $(4),$(4),MIPS $(VERSION_DIST) Linux-$(LINUX_VERSION)))
|
||||
-mkimage -A mips -O linux -T kernel -C $(1) -a $(loadaddr-y) -e $(loadaddr-y) \
|
||||
-n "$(imagename)" \
|
||||
-d $(2) $(3)
|
||||
|
@ -2,7 +2,8 @@
|
||||
# MT7620A Profiles
|
||||
#
|
||||
|
||||
DEVICE_VARS += TPLINK_FLASHLAYOUT TPLINK_HWID TPLINK_HWREV TPLINK_HWREVADD TPLINK_HVERSION
|
||||
DEVICE_VARS += TPLINK_FLASHLAYOUT TPLINK_HWID TPLINK_HWREV TPLINK_HWREVADD TPLINK_HVERSION \
|
||||
DLINK_ROM_ID DLINK_FAMILY_MEMBER DLINK_FIRMWARE_SIZE
|
||||
|
||||
define Build/elecom-header
|
||||
cp $@ $(KDIR)/v_0.0.0.bin
|
||||
@ -31,8 +32,7 @@ define Device/alfa-network_ac1200rm
|
||||
DTS := AC1200RM
|
||||
IMAGE_SIZE := 16064k
|
||||
DEVICE_TITLE := ALFA Network AC1200RM
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
|
||||
SUPPORTED_DEVICES := $(subst _,$(comma),$(1))
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci uboot-envtools
|
||||
endef
|
||||
TARGET_DEVICES += alfa-network_ac1200rm
|
||||
|
||||
@ -45,20 +45,6 @@ define Device/Archer
|
||||
IMAGE/sysupgrade.bin := tplink-v2-image -s -e | append-metadata
|
||||
endef
|
||||
|
||||
define Device/ArcherC20
|
||||
$(Device/Archer)
|
||||
DTS := ArcherC20
|
||||
SUPPORTED_DEVICES := c20
|
||||
TPLINK_FLASHLAYOUT := 8Mmtk
|
||||
TPLINK_HWID := 0xc2000001
|
||||
TPLINK_HWREV := 0x44
|
||||
TPLINK_HWREVADD := 0x1
|
||||
IMAGES += factory.bin
|
||||
DEVICE_TITLE := TP-Link ArcherC20
|
||||
DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport
|
||||
endef
|
||||
TARGET_DEVICES += ArcherC20
|
||||
|
||||
define Device/ArcherC20i
|
||||
$(Device/Archer)
|
||||
DTS := ArcherC20i
|
||||
@ -161,6 +147,44 @@ define Device/dir-810l
|
||||
endef
|
||||
TARGET_DEVICES += dir-810l
|
||||
|
||||
define Device/dlink_dwr-116-a1
|
||||
DTS := DWR-116-A1
|
||||
DEVICE_TITLE := D-Link DWR-116 A1/A2
|
||||
DEVICE_PACKAGES := kmod-usb2 jboot-tools
|
||||
DLINK_ROM_ID := DLK6E3803001
|
||||
DLINK_FAMILY_MEMBER := 0x6E38
|
||||
DLINK_FIRMWARE_SIZE := 0x7E0000
|
||||
KERNEL := $(KERNEL_DTB)
|
||||
IMAGES += factory.bin
|
||||
IMAGE/sysupgrade.bin := mkdlinkfw | pad-rootfs | append-metadata
|
||||
IMAGE/factory.bin := mkdlinkfw | pad-rootfs | mkdlinkfw-factory
|
||||
endef
|
||||
TARGET_DEVICES += dlink_dwr-116-a1
|
||||
|
||||
define Device/dlink_dwr-921-c1
|
||||
DTS := DWR-921-C1
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_16M)
|
||||
DEVICE_TITLE := D-Link DWR-921 C1
|
||||
DLINK_ROM_ID := DLK6E2414001
|
||||
DLINK_FAMILY_MEMBER := 0x6E24
|
||||
DLINK_FIRMWARE_SIZE := 0xFE0000
|
||||
KERNEL := $(KERNEL_DTB)
|
||||
IMAGES += factory.bin
|
||||
IMAGE/sysupgrade.bin := mkdlinkfw | pad-rootfs | append-metadata
|
||||
IMAGE/factory.bin := mkdlinkfw | pad-rootfs | mkdlinkfw-factory
|
||||
DEVICE_PACKAGES := jboot-tools \
|
||||
kmod-usb2 kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
|
||||
endef
|
||||
TARGET_DEVICES += dlink_dwr-921-c1
|
||||
|
||||
define Device/dlink_dwr-921-c3
|
||||
$(Device/dlink_dwr-921-c1)
|
||||
DEVICE_TITLE := D-Link DWR-921 C3
|
||||
DLINK_ROM_ID := DLK6E2414009
|
||||
SUPPORTED_DEVICES := dlink,dwr-921-c1
|
||||
endef
|
||||
TARGET_DEVICES += dlink_dwr-921-c3
|
||||
|
||||
define Device/e1700
|
||||
DTS := E1700
|
||||
IMAGES += factory.bin
|
||||
@ -433,6 +457,20 @@ define Device/tiny-ac
|
||||
endef
|
||||
TARGET_DEVICES += tiny-ac
|
||||
|
||||
define Device/tplink_c20-v1
|
||||
$(Device/Archer)
|
||||
DTS := ArcherC20v1
|
||||
SUPPORTED_DEVICES := c20v1
|
||||
TPLINK_FLASHLAYOUT := 8Mmtk
|
||||
TPLINK_HWID := 0xc2000001
|
||||
TPLINK_HWREV := 0x44
|
||||
TPLINK_HWREVADD := 0x1
|
||||
IMAGES += factory.bin
|
||||
DEVICE_TITLE := TP-Link ArcherC20 v1
|
||||
DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport
|
||||
endef
|
||||
TARGET_DEVICES += tplink_c20-v1
|
||||
|
||||
define Device/vonets_var11n-300
|
||||
DTS := VAR11N-300
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_4M)
|
||||
|
@ -57,6 +57,14 @@ define Device/dir-860l-b1
|
||||
endef
|
||||
TARGET_DEVICES += dir-860l-b1
|
||||
|
||||
define Device/mediatek_ap-mt7621a-v60
|
||||
DTS := AP-MT7621A-V60
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_8M)
|
||||
DEVICE_TITLE := Mediatek AP-MT7621A-V60 EVB
|
||||
DEVICE_PACKAGES := kmod-usb3 kmod-sdhci-mt7620 kmod-sound-mt7620
|
||||
endef
|
||||
TARGET_DEVICES += mediatek_ap-mt7621a-v60
|
||||
|
||||
define Device/ew1200
|
||||
DTS := EW1200
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_16M)
|
||||
@ -83,6 +91,14 @@ define Device/gb-pc1
|
||||
endef
|
||||
TARGET_DEVICES += gb-pc1
|
||||
|
||||
define Device/gnubee_gb-pc2
|
||||
DTS := GB-PC2
|
||||
DEVICE_TITLE := GnuBee Personal Cloud Two
|
||||
DEVICE_PACKAGES := kmod-ata-core kmod-ata-ahci kmod-usb3 kmod-sdhci-mt7620
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_32M)
|
||||
endef
|
||||
TARGET_DEVICES += gnubee_gb-pc2
|
||||
|
||||
define Device/hc5962
|
||||
DTS := HC5962
|
||||
BLOCKSIZE := 128k
|
||||
|
@ -19,6 +19,22 @@ endef
|
||||
DEVICE_VARS += TPLINK_FLASHLAYOUT TPLINK_HWID TPLINK_HWREV TPLINK_HWREVADD TPLINK_HVERSION
|
||||
|
||||
|
||||
define Device/alfa-network_awusfree1
|
||||
DTS := AWUSFREE1
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_8M)
|
||||
DEVICE_TITLE := ALFA Network AWUSFREE1
|
||||
DEVICE_PACKAGES := uboot-envtools
|
||||
endef
|
||||
TARGET_DEVICES += alfa-network_awusfree1
|
||||
|
||||
define Device/tama_w06
|
||||
DTS := W06
|
||||
IMAGE_SIZE := 15040k
|
||||
DEVICE_TITLE := Tama W06
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
|
||||
endef
|
||||
TARGET_DEVICES += tama_w06
|
||||
|
||||
define Device/duzun-dm06
|
||||
DTS := DUZUN-DM06
|
||||
DEVICE_TITLE := DuZun DM06
|
||||
@ -112,7 +128,7 @@ TARGET_DEVICES += tl-wr840n-v4
|
||||
|
||||
define Device/tl-wr840n-v5
|
||||
DTS := TL-WR840NV5
|
||||
IMAGE_SIZE := 3840k
|
||||
IMAGE_SIZE := 3904k
|
||||
DEVICE_TITLE := TP-Link TL-WR840N v5
|
||||
TPLINK_FLASHLAYOUT := 4Mmtk
|
||||
TPLINK_HWID := 0x08400005
|
||||
@ -139,6 +155,32 @@ define Device/tl-wr841n-v13
|
||||
endef
|
||||
TARGET_DEVICES += tl-wr841n-v13
|
||||
|
||||
define Device/tplink_c20-v4
|
||||
$(Device/tplink)
|
||||
DTS := ArcherC20v4
|
||||
IMAGE_SIZE := 7808k
|
||||
DEVICE_TITLE := TP-Link ArcherC20 v4
|
||||
TPLINK_FLASHLAYOUT := 8Mmtk
|
||||
TPLINK_HWID := 0xc200004
|
||||
TPLINK_HWREV := 0x1
|
||||
TPLINK_HWREVADD := 0x4
|
||||
TPLINK_HVERSION := 3
|
||||
endef
|
||||
TARGET_DEVICES += tplink_c20-v4
|
||||
|
||||
define Device/tplink_c50-v3
|
||||
$(Device/tplink)
|
||||
DTS := ArcherC50V3
|
||||
IMAGE_SIZE := 7808k
|
||||
DEVICE_TITLE := TP-Link ArcherC50 v3
|
||||
TPLINK_FLASHLAYOUT := 8Mmtk
|
||||
TPLINK_HWID := 0x001D9BA4
|
||||
TPLINK_HWREV := 0x79
|
||||
TPLINK_HWREVADD := 0x1
|
||||
TPLINK_HVERSION := 3
|
||||
endef
|
||||
TARGET_DEVICES += tplink_c50-v3
|
||||
|
||||
define Device/tplink_tl-mr3420-v5
|
||||
$(Device/tplink)
|
||||
DTS := TL-MR3420V5
|
||||
@ -153,6 +195,21 @@ define Device/tplink_tl-mr3420-v5
|
||||
endef
|
||||
TARGET_DEVICES += tplink_tl-mr3420-v5
|
||||
|
||||
define Device/tplink_tl-wr902ac-v3
|
||||
$(Device/tplink)
|
||||
DTS := TL-WR902ACV3
|
||||
IMAGE_SIZE := 7808k
|
||||
DEVICE_TITLE := TP-Link TL-WR902AC v3
|
||||
TPLINK_FLASHLAYOUT := 8Mmtk
|
||||
TPLINK_HWID := 0x000dc88f
|
||||
TPLINK_HWREV := 0x89
|
||||
TPLINK_HWREVADD := 0x1
|
||||
TPLINK_HVERSION := 3
|
||||
IMAGES += factory.bin
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
|
||||
endef
|
||||
TARGET_DEVICES += tplink_tl-wr902ac-v3
|
||||
|
||||
define Device/u7628-01-128M-16M
|
||||
DTS := U7628-01-128M-16M
|
||||
IMAGE_SIZE := 16064k
|
||||
@ -202,13 +259,22 @@ define Device/wl-wn575a3
|
||||
endef
|
||||
TARGET_DEVICES += wl-wn575a3
|
||||
|
||||
define Device/widora-neo
|
||||
DTS := WIDORA-NEO
|
||||
define Device/widora_neo-16m
|
||||
DTS := WIDORA-NEO-16M
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_16M)
|
||||
DEVICE_TITLE := Widora-NEO
|
||||
DEVICE_TITLE := Widora-NEO (16M)
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
|
||||
SUPPORTED_DEVICES += widora-neo
|
||||
endef
|
||||
TARGET_DEVICES += widora_neo-16m
|
||||
|
||||
define Device/widora_neo-32m
|
||||
DTS := WIDORA-NEO-32M
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_32M)
|
||||
DEVICE_TITLE := Widora-NEO (32M)
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
|
||||
endef
|
||||
TARGET_DEVICES += widora-neo
|
||||
TARGET_DEVICES += widora_neo-32m
|
||||
|
||||
define Device/wrtnode2p
|
||||
DTS := WRTNODE2P
|
||||
@ -225,3 +291,10 @@ define Device/wrtnode2r
|
||||
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
|
||||
endef
|
||||
TARGET_DEVICES += wrtnode2r
|
||||
|
||||
define Device/zbtlink_zbt-we1226
|
||||
DTS := ZBT-WE1226
|
||||
IMAGE_SIZE := $(ralink_default_fw_size_8M)
|
||||
DEVICE_TITLE := ZBTlink ZBT-WE1226
|
||||
endef
|
||||
TARGET_DEVICES += zbtlink_zbt-we1226
|
||||
|
@ -30,6 +30,22 @@ define Device/ar725w
|
||||
endef
|
||||
TARGET_DEVICES += ar725w
|
||||
|
||||
define Device/dlink_dap-1522-a1
|
||||
DTS := DAP-1522-A1
|
||||
BLOCKSIZE := 64k
|
||||
IMAGE_SIZE := 3801088
|
||||
DEVICE_TITLE := D-Link DAP-1522 A1
|
||||
DEVICE_PACKAGES := kmod-switch-rtl8366s
|
||||
KERNEL := $(KERNEL_DTB)
|
||||
IMAGES += factory.bin
|
||||
IMAGE/factory.bin := \
|
||||
append-kernel | pad-offset $$$$(BLOCKSIZE) 96 | \
|
||||
append-rootfs | pad-rootfs -x 96 | \
|
||||
wrg-header wapnd01_dlink_dap1522 | \
|
||||
check-size $$$$(IMAGE_SIZE)
|
||||
endef
|
||||
TARGET_DEVICES += dlink_dap-1522-a1
|
||||
|
||||
define Device/f5d8235-v1
|
||||
IMAGE_SIZE := 7744k
|
||||
DEVICE_TITLE := Belkin F5D8235 V1
|
||||
|
@ -18,41 +18,6 @@ define BuildFirmware/DCS930/squashfs
|
||||
endef
|
||||
BuildFirmware/DCS930/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3))
|
||||
|
||||
# sign Buffalo images
|
||||
define BuildFirmware/Buffalo
|
||||
if [ -e "$(call sysupname,$(1),$(2))" ]; then \
|
||||
buffalo-enc -p $(3) -v 1.76 \
|
||||
-i $(KDIR)/vmlinux-$(2).uImage \
|
||||
-o $(KDIR)/vmlinux-$(2).uImage.enc; \
|
||||
buffalo-enc -p $(3) -v 1.76 \
|
||||
-i $(KDIR)/root.$(1) \
|
||||
-o $(KDIR)/root.$(2).enc; \
|
||||
buffalo-tag -b $(3) -p $(3) -a ram -v 1.76 -m 1.01 \
|
||||
-l mlang8 -f 1 -r EU \
|
||||
-i $(KDIR)/vmlinux-$(2).uImage.enc \
|
||||
-i $(KDIR)/root.$(2).enc \
|
||||
-o $(call imgname,$(1),$(2))-factory-EU.bin; \
|
||||
fi
|
||||
endef
|
||||
|
||||
# FIXME: this looks broken
|
||||
buffalo_whrg300n_mtd_size=3801088
|
||||
define BuildFirmware/WHRG300N/squashfs
|
||||
$(call BuildFirmware/Default4M/$(1),$(1),whr-g300n,WHR-G300N)
|
||||
# the following line has a bad argument 3 ... the old Makefile was already broken
|
||||
$(call BuildFirmware/Buffalo,$(1),whr-g300n,whr-g300n)
|
||||
if [ -e "$(call sysupname,$(1),$(2))" ]; then \
|
||||
( \
|
||||
echo -n -e "# Airstation FirmWare\nrun u_fw\nreset\n\n" | \
|
||||
dd bs=512 count=1 conv=sync; \
|
||||
dd if=$(call sysupname,$(1),whr-g300n); \
|
||||
) > $(KDIR)/whr-g300n-tftp.tmp && \
|
||||
buffalo-tftp -i $(KDIR)/whr-g300n-tftp.tmp \
|
||||
-o $(call imgname,$(1),whr-g300n)-tftp.bin; \
|
||||
fi
|
||||
endef
|
||||
BuildFirmware/WHRG300N/initramfs=$(call BuildFirmware/OF/initramfs,$(1),whr-g300n,WHR-G300N)
|
||||
|
||||
kernel_size_wl341v3=917504
|
||||
rootfs_size_wl341v3=2949120
|
||||
define BuildFirmware/WL-341V3/squashfs
|
||||
@ -84,7 +49,6 @@ endef
|
||||
Image/Build/Profile/DCS930=$(call BuildFirmware/DCS930/$(1),$(1),dcs-930,DCS-930)
|
||||
Image/Build/Profile/DCS930LB1=$(call BuildFirmware/DCS930/$(1),$(1),dcs-930l-b1,DCS-930L-B1)
|
||||
Image/Build/Profile/WL-341V3=$(call BuildFirmware/WL-341V3/$(1),$(1))
|
||||
Image/Build/Profile/WHRG300N=$(call BuildFirmware/WHRG300N/$(1),$(1))
|
||||
|
||||
define LegacyDevice/ALL02393G
|
||||
DEVICE_TITLE := Allnet ALL0239-3G
|
||||
@ -110,9 +74,3 @@ define LegacyDevice/WL-341V3
|
||||
DEVICE_TITLE := Sitecom WL-341 v3
|
||||
endef
|
||||
LEGACY_DEVICES += WL-341V3
|
||||
|
||||
|
||||
define LegacyDevice/WHRG300N
|
||||
DEVICE_TITLE := Buffalo WHR-G300N
|
||||
endef
|
||||
LEGACY_DEVICES += WHRG300N
|
||||
|
@ -1,6 +1,16 @@
|
||||
#
|
||||
# RT305X Profiles
|
||||
#
|
||||
define Build/buffalo-tftp-header
|
||||
( \
|
||||
echo -n -e "# Airstation FirmWare\nrun u_fw\nreset\n\n" | \
|
||||
dd bs=512 count=1 conv=sync; \
|
||||
dd if=$@; \
|
||||
) > $@.tmp && \
|
||||
$(STAGING_DIR_HOST)/bin/buffalo-tftp -i $@.tmp -o $@.new
|
||||
mv $@.new $@
|
||||
endef
|
||||
|
||||
define Build/dap-header
|
||||
$(STAGING_DIR_HOST)/bin/mkdapimg $(1) -i $@ -o $@.new
|
||||
mv $@.new $@
|
||||
@ -745,6 +755,17 @@ define Device/wcr-150gn
|
||||
endef
|
||||
TARGET_DEVICES += wcr-150gn
|
||||
|
||||
define Device/whr-g300n
|
||||
DTS := WHR-G300N
|
||||
BLOCKSIZE := 64k
|
||||
IMAGE_SIZE := 3801088
|
||||
DEVICE_TITLE := Buffalo WHR-G300N
|
||||
IMAGES += tftp.bin
|
||||
IMAGE/tftp.bin := $$(sysupgrade_bin) | \
|
||||
check-size $$$$(IMAGE_SIZE) | buffalo-tftp-header
|
||||
endef
|
||||
TARGET_DEVICES += whr-g300n
|
||||
|
||||
define Device/wizard8800
|
||||
DTS := WIZARD8800
|
||||
UIMAGE_NAME:= Linux Kernel Image
|
||||
|
@ -5,22 +5,31 @@ CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
|
||||
# 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_WANTS_THP_SWAP is not set
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
CONFIG_CEVT_SYSTICK_QUIRK=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKEVT_RT3352=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLKSRC_OF=y
|
||||
CONFIG_CLKSRC_PROBE=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
@ -45,16 +54,25 @@ CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_DEBUG_PINCTRL=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
# CONFIG_DMA_NOOP_OPS is not set
|
||||
# CONFIG_DMA_VIRT_OPS is not set
|
||||
# CONFIG_DRM_LIB_RANDOM is not set
|
||||
# CONFIG_DTB_MT7620A_EVAL is not set
|
||||
# CONFIG_DTB_OMEGA2P is not set
|
||||
CONFIG_DTB_RT_NONE=y
|
||||
# CONFIG_DTB_VOCORE2 is not set
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_EXPORTFS=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FUTEX_PI=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_PHY=y
|
||||
@ -65,6 +83,7 @@ CONFIG_GPIOLIB=y
|
||||
# CONFIG_GPIO_MT7621 is not set
|
||||
CONFIG_GPIO_RALINK=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
# CONFIG_GRO_CELLS is not set
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
@ -81,6 +100,7 @@ CONFIG_HAVE_CBPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=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
|
||||
@ -116,7 +136,9 @@ CONFIG_IRQ_INTC=y
|
||||
CONFIG_IRQ_MIPS_CPU=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
@ -137,12 +159,12 @@ CONFIG_MODULES_USE_ELF_REL=y
|
||||
# CONFIG_MTD_CFI_INTELEXT is not set
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_NAND_MT7620=y
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
|
||||
CONFIG_MTD_SPLIT_FIRMWARE=y
|
||||
CONFIG_MTD_SPLIT_JIMAGE_FW=y
|
||||
CONFIG_MTD_SPLIT_SEAMA_FW=y
|
||||
CONFIG_MTD_SPLIT_TPLINK_FW=y
|
||||
CONFIG_MTD_SPLIT_UIMAGE_FW=y
|
||||
@ -180,7 +202,10 @@ CONFIG_PINCTRL_RT2880=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_RALINK=y
|
||||
CONFIG_RALINK_WDT=y
|
||||
# CONFIG_RCU_NEED_SEGCBLIST is not set
|
||||
# CONFIG_RCU_STALL_COMMON is not set
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
@ -208,7 +233,11 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||
CONFIG_THIN_ARCHIVES=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
@ -26,6 +26,7 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
# CONFIG_CMDLINE_OVERRIDE is not set
|
||||
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
|
@ -5,22 +5,31 @@ CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
|
||||
# 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_WANTS_THP_SWAP is not set
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
CONFIG_CEVT_SYSTICK_QUIRK=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKEVT_RT3352=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLKSRC_OF=y
|
||||
CONFIG_CLKSRC_PROBE=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
@ -45,16 +54,25 @@ CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_DEBUG_PINCTRL=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
# CONFIG_DMA_NOOP_OPS is not set
|
||||
# CONFIG_DMA_VIRT_OPS is not set
|
||||
# CONFIG_DRM_LIB_RANDOM is not set
|
||||
# CONFIG_DTB_MT7620A_EVAL is not set
|
||||
# CONFIG_DTB_OMEGA2P is not set
|
||||
CONFIG_DTB_RT_NONE=y
|
||||
# CONFIG_DTB_VOCORE2 is not set
|
||||
CONFIG_DTC=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_EXPORTFS=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FUTEX_PI=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_PHY=y
|
||||
@ -65,6 +83,7 @@ CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_MT7621=y
|
||||
# CONFIG_GPIO_RALINK is not set
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
# CONFIG_GRO_CELLS is not set
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
@ -81,6 +100,7 @@ CONFIG_HAVE_CBPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=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
|
||||
@ -116,7 +136,9 @@ CONFIG_IRQ_INTC=y
|
||||
CONFIG_IRQ_MIPS_CPU=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_ASID_BITS=8
|
||||
CONFIG_MIPS_ASID_SHIFT=0
|
||||
@ -175,7 +197,10 @@ CONFIG_PINCTRL_RT2880=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_RALINK=y
|
||||
# CONFIG_RALINK_WDT is not set
|
||||
# CONFIG_RCU_NEED_SEGCBLIST is not set
|
||||
# CONFIG_RCU_STALL_COMMON is not set
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
@ -204,7 +229,11 @@ CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MIPS16=y
|
||||
CONFIG_THIN_ARCHIVES=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TINY_SRCU=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
@ -0,0 +1,861 @@
|
||||
From fec11d4e8dc5cc79bcd7c8fd55038ac21ac39965 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 16 Mar 2014 05:22:39 +0000
|
||||
Subject: [PATCH 04/53] MIPS: ralink: add MT7621 pcie driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/pci/Makefile | 1 +
|
||||
arch/mips/pci/pci-mt7621.c | 813 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 814 insertions(+)
|
||||
create mode 100644 arch/mips/pci/pci-mt7621.c
|
||||
|
||||
--- a/arch/mips/pci/Makefile
|
||||
+++ b/arch/mips/pci/Makefile
|
||||
@@ -47,6 +47,7 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops
|
||||
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
|
||||
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
|
||||
obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
|
||||
+obj-$(CONFIG_SOC_MT7621) += pci-mt7621.o
|
||||
obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
|
||||
obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
|
||||
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/pci/pci-mt7621.c
|
||||
@@ -0,0 +1,836 @@
|
||||
+/**************************************************************************
|
||||
+ *
|
||||
+ * BRIEF MODULE DESCRIPTION
|
||||
+ * PCI init for Ralink RT2880 solution
|
||||
+ *
|
||||
+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw)
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License as published by the
|
||||
+ * Free Software Foundation; either version 2 of the License, or (at your
|
||||
+ * option) any later version.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License along
|
||||
+ * with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
+ *
|
||||
+ *
|
||||
+ **************************************************************************
|
||||
+ * May 2007 Bruce Chang
|
||||
+ * Initial Release
|
||||
+ *
|
||||
+ * May 2009 Bruce Chang
|
||||
+ * support RT2880/RT3883 PCIe
|
||||
+ *
|
||||
+ * May 2011 Bruce Chang
|
||||
+ * support RT6855/MT7620 PCIe
|
||||
+ *
|
||||
+ **************************************************************************
|
||||
+ */
|
||||
+
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/version.h>
|
||||
+#include <asm/pci.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <asm/mips-cm.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_pci.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include <ralink_regs.h>
|
||||
+
|
||||
+extern void pcie_phy_init(void);
|
||||
+extern void chk_phy_pll(void);
|
||||
+
|
||||
+/*
|
||||
+ * These functions and structures provide the BIOS scan and mapping of the PCI
|
||||
+ * devices.
|
||||
+ */
|
||||
+
|
||||
+#define CONFIG_PCIE_PORT0
|
||||
+#define CONFIG_PCIE_PORT1
|
||||
+#define CONFIG_PCIE_PORT2
|
||||
+#define RALINK_PCIE0_CLK_EN (1<<24)
|
||||
+#define RALINK_PCIE1_CLK_EN (1<<25)
|
||||
+#define RALINK_PCIE2_CLK_EN (1<<26)
|
||||
+
|
||||
+#define RALINK_PCI_CONFIG_ADDR 0x20
|
||||
+#define RALINK_PCI_CONFIG_DATA_VIRTUAL_REG 0x24
|
||||
+#define RALINK_INT_PCIE0 pcie_irq[0]
|
||||
+#define RALINK_INT_PCIE1 pcie_irq[1]
|
||||
+#define RALINK_INT_PCIE2 pcie_irq[2]
|
||||
+#define RALINK_PCI_MEMBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x0028)
|
||||
+#define RALINK_PCI_IOBASE *(volatile u32 *)(RALINK_PCI_BASE + 0x002C)
|
||||
+#define RALINK_PCIE0_RST (1<<24)
|
||||
+#define RALINK_PCIE1_RST (1<<25)
|
||||
+#define RALINK_PCIE2_RST (1<<26)
|
||||
+#define RALINK_SYSCTL_BASE 0xBE000000
|
||||
+
|
||||
+#define RALINK_PCI_PCICFG_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x0000)
|
||||
+#define RALINK_PCI_PCIMSK_ADDR *(volatile u32 *)(RALINK_PCI_BASE + 0x000C)
|
||||
+#define RALINK_PCI_BASE 0xBE140000
|
||||
+
|
||||
+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000)
|
||||
+#define RT6855_PCIE0_OFFSET 0x2000
|
||||
+#define RT6855_PCIE1_OFFSET 0x3000
|
||||
+#define RT6855_PCIE2_OFFSET 0x4000
|
||||
+
|
||||
+#define RALINK_PCI0_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0010)
|
||||
+#define RALINK_PCI0_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0018)
|
||||
+#define RALINK_PCI0_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0030)
|
||||
+#define RALINK_PCI0_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0034)
|
||||
+#define RALINK_PCI0_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0038)
|
||||
+#define RALINK_PCI0_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0050)
|
||||
+#define RALINK_PCI0_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0060)
|
||||
+#define RALINK_PCI0_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE0_OFFSET + 0x0064)
|
||||
+
|
||||
+#define RALINK_PCI1_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0010)
|
||||
+#define RALINK_PCI1_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0018)
|
||||
+#define RALINK_PCI1_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0030)
|
||||
+#define RALINK_PCI1_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0034)
|
||||
+#define RALINK_PCI1_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0038)
|
||||
+#define RALINK_PCI1_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0050)
|
||||
+#define RALINK_PCI1_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0060)
|
||||
+#define RALINK_PCI1_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE1_OFFSET + 0x0064)
|
||||
+
|
||||
+#define RALINK_PCI2_BAR0SETUP_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0010)
|
||||
+#define RALINK_PCI2_IMBASEBAR0_ADDR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0018)
|
||||
+#define RALINK_PCI2_ID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0030)
|
||||
+#define RALINK_PCI2_CLASS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0034)
|
||||
+#define RALINK_PCI2_SUBID *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0038)
|
||||
+#define RALINK_PCI2_STATUS *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0050)
|
||||
+#define RALINK_PCI2_DERR *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0060)
|
||||
+#define RALINK_PCI2_ECRC *(volatile u32 *)(RALINK_PCI_BASE + RT6855_PCIE2_OFFSET + 0x0064)
|
||||
+
|
||||
+#define RALINK_PCIEPHY_P0P1_CTL_OFFSET (RALINK_PCI_BASE + 0x9000)
|
||||
+#define RALINK_PCIEPHY_P2_CTL_OFFSET (RALINK_PCI_BASE + 0xA000)
|
||||
+
|
||||
+
|
||||
+#define MV_WRITE(ofs, data) \
|
||||
+ *(volatile u32 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le32(data)
|
||||
+#define MV_READ(ofs, data) \
|
||||
+ *(data) = le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs)))
|
||||
+#define MV_READ_DATA(ofs) \
|
||||
+ le32_to_cpu(*(volatile u32 *)(RALINK_PCI_BASE+(ofs)))
|
||||
+
|
||||
+#define MV_WRITE_16(ofs, data) \
|
||||
+ *(volatile u16 *)(RALINK_PCI_BASE+(ofs)) = cpu_to_le16(data)
|
||||
+#define MV_READ_16(ofs, data) \
|
||||
+ *(data) = le16_to_cpu(*(volatile u16 *)(RALINK_PCI_BASE+(ofs)))
|
||||
+
|
||||
+#define MV_WRITE_8(ofs, data) \
|
||||
+ *(volatile u8 *)(RALINK_PCI_BASE+(ofs)) = data
|
||||
+#define MV_READ_8(ofs, data) \
|
||||
+ *(data) = *(volatile u8 *)(RALINK_PCI_BASE+(ofs))
|
||||
+
|
||||
+
|
||||
+
|
||||
+#define RALINK_PCI_MM_MAP_BASE 0x60000000
|
||||
+#define RALINK_PCI_IO_MAP_BASE 0x1e160000
|
||||
+
|
||||
+#define RALINK_SYSTEM_CONTROL_BASE 0xbe000000
|
||||
+#define GPIO_PERST
|
||||
+#define ASSERT_SYSRST_PCIE(val) do { \
|
||||
+ if (*(unsigned int *)(0xbe00000c) == 0x00030101) \
|
||||
+ RALINK_RSTCTRL |= val; \
|
||||
+ else \
|
||||
+ RALINK_RSTCTRL &= ~val; \
|
||||
+ } while(0)
|
||||
+#define DEASSERT_SYSRST_PCIE(val) do { \
|
||||
+ if (*(unsigned int *)(0xbe00000c) == 0x00030101) \
|
||||
+ RALINK_RSTCTRL &= ~val; \
|
||||
+ else \
|
||||
+ RALINK_RSTCTRL |= val; \
|
||||
+ } while(0)
|
||||
+#define RALINK_SYSCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x14)
|
||||
+#define RALINK_CLKCFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x30)
|
||||
+#define RALINK_RSTCTRL *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x34)
|
||||
+#define RALINK_GPIOMODE *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x60)
|
||||
+#define RALINK_PCIE_CLK_GEN *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x7c)
|
||||
+#define RALINK_PCIE_CLK_GEN1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x80)
|
||||
+#define PPLL_CFG1 *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0x9c)
|
||||
+#define PPLL_DRV *(unsigned int *)(RALINK_SYSTEM_CONTROL_BASE + 0xa0)
|
||||
+//RALINK_SYSCFG1 bit
|
||||
+#define RALINK_PCI_HOST_MODE_EN (1<<7)
|
||||
+#define RALINK_PCIE_RC_MODE_EN (1<<8)
|
||||
+//RALINK_RSTCTRL bit
|
||||
+#define RALINK_PCIE_RST (1<<23)
|
||||
+#define RALINK_PCI_RST (1<<24)
|
||||
+//RALINK_CLKCFG1 bit
|
||||
+#define RALINK_PCI_CLK_EN (1<<19)
|
||||
+#define RALINK_PCIE_CLK_EN (1<<21)
|
||||
+//RALINK_GPIOMODE bit
|
||||
+#define PCI_SLOTx2 (1<<11)
|
||||
+#define PCI_SLOTx1 (2<<11)
|
||||
+//MTK PCIE PLL bit
|
||||
+#define PDRV_SW_SET (1<<31)
|
||||
+#define LC_CKDRVPD_ (1<<19)
|
||||
+
|
||||
+#define MEMORY_BASE 0x0
|
||||
+static int pcie_link_status = 0;
|
||||
+
|
||||
+#define PCI_ACCESS_READ_1 0
|
||||
+#define PCI_ACCESS_READ_2 1
|
||||
+#define PCI_ACCESS_READ_4 2
|
||||
+#define PCI_ACCESS_WRITE_1 3
|
||||
+#define PCI_ACCESS_WRITE_2 4
|
||||
+#define PCI_ACCESS_WRITE_4 5
|
||||
+
|
||||
+static int pcie_irq[3];
|
||||
+
|
||||
+static int config_access(unsigned char access_type, struct pci_bus *bus,
|
||||
+ unsigned int devfn, unsigned int where, u32 * data)
|
||||
+{
|
||||
+ unsigned int slot = PCI_SLOT(devfn);
|
||||
+ u8 func = PCI_FUNC(devfn);
|
||||
+ uint32_t address_reg, data_reg;
|
||||
+ unsigned int address;
|
||||
+
|
||||
+ address_reg = RALINK_PCI_CONFIG_ADDR;
|
||||
+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
|
||||
+
|
||||
+ address = (((where&0xF00)>>8)<<24) |(bus->number << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | 0x80000000;
|
||||
+ MV_WRITE(address_reg, address);
|
||||
+
|
||||
+ switch(access_type) {
|
||||
+ case PCI_ACCESS_WRITE_1:
|
||||
+ MV_WRITE_8(data_reg+(where&0x3), *data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_WRITE_2:
|
||||
+ MV_WRITE_16(data_reg+(where&0x3), *data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_WRITE_4:
|
||||
+ MV_WRITE(data_reg, *data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_READ_1:
|
||||
+ MV_READ_8( data_reg+(where&0x3), data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_READ_2:
|
||||
+ MV_READ_16(data_reg+(where&0x3), data);
|
||||
+ break;
|
||||
+ case PCI_ACCESS_READ_4:
|
||||
+ MV_READ(data_reg, data);
|
||||
+ break;
|
||||
+ default:
|
||||
+ printk("no specify access type\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
|
||||
+{
|
||||
+ return config_access(PCI_ACCESS_READ_1, bus, devfn, (unsigned int)where, (u32 *)val);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
|
||||
+{
|
||||
+ return config_access(PCI_ACCESS_READ_2, bus, devfn, (unsigned int)where, (u32 *)val);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
|
||||
+{
|
||||
+ return config_access(PCI_ACCESS_READ_4, bus, devfn, (unsigned int)where, (u32 *)val);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
|
||||
+{
|
||||
+ if (config_access(PCI_ACCESS_WRITE_1, bus, devfn, (unsigned int)where, (u32 *)&val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
|
||||
+{
|
||||
+ if (config_access(PCI_ACCESS_WRITE_2, bus, devfn, where, (u32 *)&val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
|
||||
+{
|
||||
+ if (config_access(PCI_ACCESS_WRITE_4, bus, devfn, where, &val))
|
||||
+ return -1;
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
|
||||
+{
|
||||
+ switch (size) {
|
||||
+ case 1:
|
||||
+ return read_config_byte(bus, devfn, where, (u8 *) val);
|
||||
+ case 2:
|
||||
+ return read_config_word(bus, devfn, where, (u16 *) val);
|
||||
+ default:
|
||||
+ return read_config_dword(bus, devfn, where, val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
|
||||
+{
|
||||
+ switch (size) {
|
||||
+ case 1:
|
||||
+ return write_config_byte(bus, devfn, where, (u8) val);
|
||||
+ case 2:
|
||||
+ return write_config_word(bus, devfn, where, (u16) val);
|
||||
+ default:
|
||||
+ return write_config_dword(bus, devfn, where, val);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+struct pci_ops mt7621_pci_ops= {
|
||||
+ .read = pci_config_read,
|
||||
+ .write = pci_config_write,
|
||||
+};
|
||||
+
|
||||
+static struct resource mt7621_res_pci_mem1 = {
|
||||
+ .name = "PCI MEM1",
|
||||
+ .start = RALINK_PCI_MM_MAP_BASE,
|
||||
+ .end = (u32)((RALINK_PCI_MM_MAP_BASE + (unsigned char *)0x0fffffff)),
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+static struct resource mt7621_res_pci_io1 = {
|
||||
+ .name = "PCI I/O1",
|
||||
+ .start = RALINK_PCI_IO_MAP_BASE,
|
||||
+ .end = (u32)((RALINK_PCI_IO_MAP_BASE + (unsigned char *)0x0ffff)),
|
||||
+ .flags = IORESOURCE_IO,
|
||||
+};
|
||||
+
|
||||
+static struct pci_controller mt7621_controller = {
|
||||
+ .pci_ops = &mt7621_pci_ops,
|
||||
+ .mem_resource = &mt7621_res_pci_mem1,
|
||||
+ .io_resource = &mt7621_res_pci_io1,
|
||||
+ .mem_offset = 0x00000000UL,
|
||||
+ .io_offset = 0x00000000UL,
|
||||
+ .io_map_base = 0xa0000000,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+read_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long *val)
|
||||
+{
|
||||
+ unsigned int address_reg, data_reg, address;
|
||||
+
|
||||
+ address_reg = RALINK_PCI_CONFIG_ADDR;
|
||||
+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
|
||||
+ address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ;
|
||||
+ MV_WRITE(address_reg, address);
|
||||
+ MV_READ(data_reg, val);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+write_config(unsigned long bus, unsigned long dev, unsigned long func, unsigned long reg, unsigned long val)
|
||||
+{
|
||||
+ unsigned int address_reg, data_reg, address;
|
||||
+
|
||||
+ address_reg = RALINK_PCI_CONFIG_ADDR;
|
||||
+ data_reg = RALINK_PCI_CONFIG_DATA_VIRTUAL_REG;
|
||||
+ address = (((reg & 0xF00)>>8)<<24) | (bus << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000 ;
|
||||
+ MV_WRITE(address_reg, address);
|
||||
+ MV_WRITE(data_reg, val);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int
|
||||
+pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
+{
|
||||
+ u16 cmd;
|
||||
+ u32 val;
|
||||
+ int irq = 0;
|
||||
+
|
||||
+ if ((dev->bus->number == 0) && (slot == 0)) {
|
||||
+ write_config(0, 0, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ read_config(0, 0, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
|
||||
+ printk("BAR0 at slot 0 = %x\n", val);
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ } else if((dev->bus->number == 0) && (slot == 0x1)) {
|
||||
+ write_config(0, 1, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ read_config(0, 1, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
|
||||
+ printk("BAR0 at slot 1 = %x\n", val);
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ } else if((dev->bus->number == 0) && (slot == 0x2)) {
|
||||
+ write_config(0, 2, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ read_config(0, 2, 0, PCI_BASE_ADDRESS_0, (unsigned long *)&val);
|
||||
+ printk("BAR0 at slot 2 = %x\n", val);
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ } else if ((dev->bus->number == 1) && (slot == 0x0)) {
|
||||
+ switch (pcie_link_status) {
|
||||
+ case 2:
|
||||
+ case 6:
|
||||
+ irq = RALINK_INT_PCIE1;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ irq = RALINK_INT_PCIE0;
|
||||
+ }
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number == 2) && (slot == 0x0)) {
|
||||
+ switch (pcie_link_status) {
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ irq = RALINK_INT_PCIE1;
|
||||
+ }
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number == 2) && (slot == 0x1)) {
|
||||
+ switch (pcie_link_status) {
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ break;
|
||||
+ default:
|
||||
+ irq = RALINK_INT_PCIE1;
|
||||
+ }
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number ==3) && (slot == 0x0)) {
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number ==3) && (slot == 0x1)) {
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else if ((dev->bus->number ==3) && (slot == 0x2)) {
|
||||
+ irq = RALINK_INT_PCIE2;
|
||||
+ printk("bus=0x%x, slot = 0x%x, irq=0x%x\n",dev->bus->number, slot, dev->irq);
|
||||
+ } else {
|
||||
+ printk("bus=0x%x, slot = 0x%x\n",dev->bus->number, slot);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14); //configure cache line size 0x14
|
||||
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF); //configure latency timer 0x10
|
||||
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
+ cmd = 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;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+set_pcie_phy(u32 *addr, int start_b, int bits, int val)
|
||||
+{
|
||||
+// printk("0x%p:", addr);
|
||||
+// printk(" %x", *addr);
|
||||
+ *(unsigned int *)(addr) &= ~(((1<<bits) - 1)<<start_b);
|
||||
+ *(unsigned int *)(addr) |= val << start_b;
|
||||
+// printk(" -> %x\n", *addr);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+bypass_pipe_rst(void)
|
||||
+{
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ /* PCIe Port 0 */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4]
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ /* PCIe Port 1 */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 12, 1, 0x01); // rg_pe1_pipe_rst_b
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x12c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4]
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ /* PCIe Port 2 */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 12, 1, 0x01); // rg_pe1_pipe_rst_b
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x02c), 4, 1, 0x01); // rg_pe1_pipe_cmd_frc[4]
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+set_phy_for_ssc(void)
|
||||
+{
|
||||
+ unsigned long reg = (*(volatile u32 *)(RALINK_SYSCTL_BASE + 0x10));
|
||||
+
|
||||
+ reg = (reg >> 6) & 0x7;
|
||||
+#if defined (CONFIG_PCIE_PORT0) || defined (CONFIG_PCIE_PORT1)
|
||||
+ /* Set PCIe Port0 & Port1 PHY to disable SSC */
|
||||
+ /* Debug Xtal Type */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 1 enable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x00); // rg_pe1_phy_en //Port 1 disable
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ printk("***** Xtal 40MHz *****\n");
|
||||
+ } else { // 25MHz | 20MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ if (reg >= 6) {
|
||||
+ printk("***** Xtal 25MHz *****\n");
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode)
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial
|
||||
+ } else {
|
||||
+ printk("***** Xtal 20MHz *****\n");
|
||||
+ }
|
||||
+ }
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv
|
||||
+ }
|
||||
+ /* Enable PHY and disable force mode */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 5, 1, 0x01); // rg_pe1_phy_en //Port 1 enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P0P1_CTL_OFFSET + 0x100), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 1 disable control
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ /* Set PCIe Port2 PHY to disable SSC */
|
||||
+ /* Debug Xtal Type */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 8, 1, 0x01); // rg_pe1_frc_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x400), 9, 2, 0x00); // rg_pe1_h_xtal_type
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x01); // rg_pe1_frc_phy_en //Force Port 0 enable control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x00); // rg_pe1_phy_en //Port 0 disable
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x01); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ } else { // 25MHz | 20MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 6, 2, 0x00); // RG_PE1_H_PLL_PREDIV //Pre-divider ratio (for host mode)
|
||||
+ if (reg >= 6) { // 25MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4bc), 4, 2, 0x01); // RG_PE1_H_PLL_FBKSEL //Feedback clock select
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x49c), 0,31, 0x18000000); // RG_PE1_H_LCDDS_PCW_NCPO //DDS NCPO PCW (for host mode)
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a4), 0,16, 0x18d); // RG_PE1_H_LCDDS_SSC_PRD //DDS SSC dither period control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 0,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA //DDS SSC dither amplitude control
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a8), 16,12, 0x4a); // RG_PE1_H_LCDDS_SSC_DELTA1 //DDS SSC dither amplitude control for initial
|
||||
+ }
|
||||
+ }
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4a0), 5, 1, 0x01); // RG_PE1_LCDDS_CLK_PH_INV //DDS clock inversion
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 22, 2, 0x02); // RG_PE1_H_PLL_BC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 18, 4, 0x06); // RG_PE1_H_PLL_BP
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 12, 4, 0x02); // RG_PE1_H_PLL_IR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 8, 4, 0x01); // RG_PE1_H_PLL_IC
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x4ac), 16, 3, 0x00); // RG_PE1_H_PLL_BR
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x490), 1, 3, 0x02); // RG_PE1_PLL_DIVEN
|
||||
+ if(reg <= 5 && reg >= 3) { // 40MHz Xtal
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 6, 2, 0x01); // rg_pe1_mstckdiv //value of da_pe1_mstckdiv when force mode enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x414), 5, 1, 0x01); // rg_pe1_frc_mstckdiv //force mode enable of da_pe1_mstckdiv
|
||||
+ }
|
||||
+ /* Enable PHY and disable force mode */
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 5, 1, 0x01); // rg_pe1_phy_en //Port 0 enable
|
||||
+ set_pcie_phy((u32 *)(RALINK_PCIEPHY_P2_CTL_OFFSET + 0x000), 4, 1, 0x00); // rg_pe1_frc_phy_en //Force Port 0 disable control
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void setup_cm_memory_region(struct resource *mem_resource)
|
||||
+{
|
||||
+ resource_size_t mask;
|
||||
+ if (mips_cps_numiocu(0)) {
|
||||
+ /* FIXME: hardware doesn't accept mask values with 1s after
|
||||
+ 0s (e.g. 0xffef), so it would be great to warn if that's
|
||||
+ about to happen */
|
||||
+ mask = ~(mem_resource->end - mem_resource->start);
|
||||
+
|
||||
+ write_gcr_reg1_base(mem_resource->start);
|
||||
+ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0);
|
||||
+ printk("PCI coherence region base: 0x%08lx, mask/settings: 0x%08lx\n",
|
||||
+ read_gcr_reg1_base(),
|
||||
+ read_gcr_reg1_mask());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int mt7621_pci_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ unsigned long val = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 3; i++)
|
||||
+ pcie_irq[i] = irq_of_parse_and_map(pdev->dev.of_node, i);
|
||||
+
|
||||
+ iomem_resource.start = 0;
|
||||
+ iomem_resource.end= ~0;
|
||||
+ ioport_resource.start= 0;
|
||||
+ ioport_resource.end = ~0;
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ val = RALINK_PCIE0_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ val |= RALINK_PCIE1_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ val |= RALINK_PCIE2_RST;
|
||||
+#endif
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST | RALINK_PCIE1_RST | RALINK_PCIE2_RST);
|
||||
+ printk("pull PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
|
||||
+#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/
|
||||
+ *(unsigned int *)(0xbe000060) &= ~(0x3<<10 | 0x3<<3);
|
||||
+ *(unsigned int *)(0xbe000060) |= 0x1<<10 | 0x1<<3;
|
||||
+ mdelay(100);
|
||||
+ *(unsigned int *)(0xbe000600) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // use GPIO19/GPIO8/GPIO7 (PERST_N/UART_RXD3/UART_TXD3)
|
||||
+ mdelay(100);
|
||||
+ *(unsigned int *)(0xbe000620) &= ~(0x1<<19 | 0x1<<8 | 0x1<<7); // clear DATA
|
||||
+
|
||||
+ mdelay(100);
|
||||
+#else
|
||||
+ *(unsigned int *)(0xbe000060) &= ~0x00000c00;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ val = RALINK_PCIE0_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ val |= RALINK_PCIE1_RST;
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ val |= RALINK_PCIE2_RST;
|
||||
+#endif
|
||||
+ DEASSERT_SYSRST_PCIE(val);
|
||||
+ printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
|
||||
+
|
||||
+ if ((*(unsigned int *)(0xbe00000c)&0xFFFF) == 0x0101) // MT7621 E2
|
||||
+ bypass_pipe_rst();
|
||||
+ set_phy_for_ssc();
|
||||
+ printk("release PCIe RST: RALINK_RSTCTRL = %x\n", RALINK_RSTCTRL);
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ read_config(0, 0, 0, 0x70c, &val);
|
||||
+ printk("Port 0 N_FTS = %x\n", (unsigned int)val);
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ read_config(0, 1, 0, 0x70c, &val);
|
||||
+ printk("Port 1 N_FTS = %x\n", (unsigned int)val);
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ read_config(0, 2, 0, 0x70c, &val);
|
||||
+ printk("Port 2 N_FTS = %x\n", (unsigned int)val);
|
||||
+#endif
|
||||
+
|
||||
+ RALINK_RSTCTRL = (RALINK_RSTCTRL | RALINK_PCIE_RST);
|
||||
+ RALINK_SYSCFG1 &= ~(0x30);
|
||||
+ RALINK_SYSCFG1 |= (2<<4);
|
||||
+ RALINK_PCIE_CLK_GEN &= 0x7fffffff;
|
||||
+ RALINK_PCIE_CLK_GEN1 &= 0x80ffffff;
|
||||
+ RALINK_PCIE_CLK_GEN1 |= 0xa << 24;
|
||||
+ RALINK_PCIE_CLK_GEN |= 0x80000000;
|
||||
+ mdelay(50);
|
||||
+ RALINK_RSTCTRL = (RALINK_RSTCTRL & ~RALINK_PCIE_RST);
|
||||
+
|
||||
+
|
||||
+#if defined GPIO_PERST /* add GPIO control instead of PERST_N */ /*chhung*/
|
||||
+ *(unsigned int *)(0xbe000620) |= 0x1<<19 | 0x1<<8 | 0x1<<7; // set DATA
|
||||
+ mdelay(100);
|
||||
+#else
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~(1<<1); //de-assert PERST
|
||||
+#endif
|
||||
+ mdelay(500);
|
||||
+
|
||||
+
|
||||
+ mdelay(500);
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ if(( RALINK_PCI0_STATUS & 0x1) == 0)
|
||||
+ {
|
||||
+ printk("PCIE0 no card, disable it(RST&CLK)\n");
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE0_RST);
|
||||
+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE0_CLK_EN);
|
||||
+ pcie_link_status &= ~(1<<0);
|
||||
+ } else {
|
||||
+ pcie_link_status |= 1<<0;
|
||||
+ RALINK_PCI_PCIMSK_ADDR |= (1<<20); // enable pcie1 interrupt
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ if(( RALINK_PCI1_STATUS & 0x1) == 0)
|
||||
+ {
|
||||
+ printk("PCIE1 no card, disable it(RST&CLK)\n");
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE1_RST);
|
||||
+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE1_CLK_EN);
|
||||
+ pcie_link_status &= ~(1<<1);
|
||||
+ } else {
|
||||
+ pcie_link_status |= 1<<1;
|
||||
+ RALINK_PCI_PCIMSK_ADDR |= (1<<21); // enable pcie1 interrupt
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ if (( RALINK_PCI2_STATUS & 0x1) == 0) {
|
||||
+ printk("PCIE2 no card, disable it(RST&CLK)\n");
|
||||
+ ASSERT_SYSRST_PCIE(RALINK_PCIE2_RST);
|
||||
+ RALINK_CLKCFG1 = (RALINK_CLKCFG1 & ~RALINK_PCIE2_CLK_EN);
|
||||
+ pcie_link_status &= ~(1<<2);
|
||||
+ } else {
|
||||
+ pcie_link_status |= 1<<2;
|
||||
+ RALINK_PCI_PCIMSK_ADDR |= (1<<22); // enable pcie2 interrupt
|
||||
+ }
|
||||
+#endif
|
||||
+ if (pcie_link_status == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+/*
|
||||
+pcie(2/1/0) link status pcie2_num pcie1_num pcie0_num
|
||||
+3'b000 x x x
|
||||
+3'b001 x x 0
|
||||
+3'b010 x 0 x
|
||||
+3'b011 x 1 0
|
||||
+3'b100 0 x x
|
||||
+3'b101 1 x 0
|
||||
+3'b110 1 0 x
|
||||
+3'b111 2 1 0
|
||||
+*/
|
||||
+ switch(pcie_link_status) {
|
||||
+ case 2:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x00ff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 24; //port2
|
||||
+ break;
|
||||
+ case 5:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 20; //port1
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2
|
||||
+ break;
|
||||
+ case 6:
|
||||
+ RALINK_PCI_PCICFG_ADDR &= ~0x0fff0000;
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x2 << 16; //port0
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x0 << 20; //port1
|
||||
+ RALINK_PCI_PCICFG_ADDR |= 0x1 << 24; //port2
|
||||
+ break;
|
||||
+ }
|
||||
+ printk(" -> %x\n", RALINK_PCI_PCICFG_ADDR);
|
||||
+ //printk(" RALINK_PCI_ARBCTL = %x\n", RALINK_PCI_ARBCTL);
|
||||
+
|
||||
+/*
|
||||
+ ioport_resource.start = mt7621_res_pci_io1.start;
|
||||
+ ioport_resource.end = mt7621_res_pci_io1.end;
|
||||
+*/
|
||||
+
|
||||
+ RALINK_PCI_MEMBASE = 0xffffffff; //RALINK_PCI_MM_MAP_BASE;
|
||||
+ RALINK_PCI_IOBASE = RALINK_PCI_IO_MAP_BASE;
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT0)
|
||||
+ //PCIe0
|
||||
+ if((pcie_link_status & 0x1) != 0) {
|
||||
+ RALINK_PCI0_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE
|
||||
+ RALINK_PCI0_IMBASEBAR0_ADDR = MEMORY_BASE;
|
||||
+ RALINK_PCI0_CLASS = 0x06040001;
|
||||
+ printk("PCIE0 enabled\n");
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT1)
|
||||
+ //PCIe1
|
||||
+ if ((pcie_link_status & 0x2) != 0) {
|
||||
+ RALINK_PCI1_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE
|
||||
+ RALINK_PCI1_IMBASEBAR0_ADDR = MEMORY_BASE;
|
||||
+ RALINK_PCI1_CLASS = 0x06040001;
|
||||
+ printk("PCIE1 enabled\n");
|
||||
+ }
|
||||
+#endif
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ //PCIe2
|
||||
+ if ((pcie_link_status & 0x4) != 0) {
|
||||
+ RALINK_PCI2_BAR0SETUP_ADDR = 0x7FFF0001; //open 7FFF:2G; ENABLE
|
||||
+ RALINK_PCI2_IMBASEBAR0_ADDR = MEMORY_BASE;
|
||||
+ RALINK_PCI2_CLASS = 0x06040001;
|
||||
+ printk("PCIE2 enabled\n");
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+ switch(pcie_link_status) {
|
||||
+ case 7:
|
||||
+ read_config(0, 2, 0, 0x4, &val);
|
||||
+ write_config(0, 2, 0, 0x4, val|0x4);
|
||||
+ // write_config(0, 1, 0, 0x4, val|0x7);
|
||||
+ read_config(0, 2, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff)<<8;
|
||||
+ val |= 0x50<<8;
|
||||
+ write_config(0, 2, 0, 0x70c, val);
|
||||
+ case 3:
|
||||
+ case 5:
|
||||
+ case 6:
|
||||
+ read_config(0, 1, 0, 0x4, &val);
|
||||
+ write_config(0, 1, 0, 0x4, val|0x4);
|
||||
+ // write_config(0, 1, 0, 0x4, val|0x7);
|
||||
+ read_config(0, 1, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff)<<8;
|
||||
+ val |= 0x50<<8;
|
||||
+ write_config(0, 1, 0, 0x70c, val);
|
||||
+ default:
|
||||
+ read_config(0, 0, 0, 0x4, &val);
|
||||
+ write_config(0, 0, 0, 0x4, val|0x4); //bus master enable
|
||||
+ // write_config(0, 0, 0, 0x4, val|0x7); //bus master enable
|
||||
+ read_config(0, 0, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff)<<8;
|
||||
+ val |= 0x50<<8;
|
||||
+ write_config(0, 0, 0, 0x70c, val);
|
||||
+ }
|
||||
+
|
||||
+ pci_load_of_ranges(&mt7621_controller, pdev->dev.of_node);
|
||||
+ setup_cm_memory_region(mt7621_controller.mem_resource);
|
||||
+ register_pci_controller(&mt7621_controller);
|
||||
+ return 0;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mt7621_pci_ids[] = {
|
||||
+ { .compatible = "mediatek,mt7621-pci" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7621_pci_ids);
|
||||
+
|
||||
+static struct platform_driver mt7621_pci_driver = {
|
||||
+ .probe = mt7621_pci_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mt7621-pci",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(mt7621_pci_ids),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init mt7621_pci_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mt7621_pci_driver);
|
||||
+}
|
||||
+
|
||||
+arch_initcall(mt7621_pci_init);
|
@ -0,0 +1,82 @@
|
||||
From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 14 Jul 2013 23:08:11 +0200
|
||||
Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
|
||||
irq
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/Kconfig | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -1,12 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
if RALINK
|
||||
|
||||
+config CEVT_SYSTICK_QUIRK
|
||||
+ bool
|
||||
+ default n
|
||||
+
|
||||
config CLKEVT_RT3352
|
||||
bool
|
||||
depends on SOC_RT305X || SOC_MT7620
|
||||
default y
|
||||
select TIMER_OF
|
||||
select CLKSRC_MMIO
|
||||
+ select CEVT_SYSTICK_QUIRK
|
||||
|
||||
config RALINK_ILL_ACC
|
||||
bool
|
||||
--- a/arch/mips/kernel/cevt-r4k.c
|
||||
+++ b/arch/mips/kernel/cevt-r4k.c
|
||||
@@ -15,6 +15,26 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/cevt-r4k.h>
|
||||
|
||||
+static int mips_state_oneshot(struct clock_event_device *evt)
|
||||
+{
|
||||
+ if (!cp0_timer_irq_installed) {
|
||||
+ cp0_timer_irq_installed = 1;
|
||||
+ setup_irq(evt->irq, &c0_compare_irqaction);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mips_state_shutdown(struct clock_event_device *evt)
|
||||
+{
|
||||
+ if (cp0_timer_irq_installed) {
|
||||
+ cp0_timer_irq_installed = 0;
|
||||
+ remove_irq(evt->irq, &c0_compare_irqaction);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int mips_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
@@ -281,17 +301,21 @@ int r4k_clockevent_init(void)
|
||||
cd->rating = 300;
|
||||
cd->irq = irq;
|
||||
cd->cpumask = cpumask_of(cpu);
|
||||
+ cd->set_state_shutdown = mips_state_shutdown;
|
||||
+ cd->set_state_oneshot = mips_state_oneshot;
|
||||
cd->set_next_event = mips_next_event;
|
||||
cd->event_handler = mips_event_handler;
|
||||
|
||||
clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
|
||||
|
||||
+#ifndef CONFIG_CEVT_SYSTICK_QUIRK
|
||||
if (cp0_timer_irq_installed)
|
||||
return 0;
|
||||
|
||||
cp0_timer_irq_installed = 1;
|
||||
|
||||
setup_irq(irq, &c0_compare_irqaction);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jul 2013 16:26:41 +0200
|
||||
Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling
|
||||
|
||||
This feature will break udelay() and cause the delay loop to have longer delays
|
||||
when the frequency is scaled causing a performance hit.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/cevt-rt3352.c
|
||||
+++ b/arch/mips/ralink/cevt-rt3352.c
|
||||
@@ -29,6 +29,10 @@
|
||||
/* enable the counter */
|
||||
#define CFG_CNT_EN 0x1
|
||||
|
||||
+/* mt7620 frequency scaling defines */
|
||||
+#define CLK_LUT_CFG 0x40
|
||||
+#define SLEEP_EN BIT(31)
|
||||
+
|
||||
struct systick_device {
|
||||
void __iomem *membase;
|
||||
struct clock_event_device dev;
|
||||
@@ -36,21 +40,53 @@ struct systick_device {
|
||||
int freq_scale;
|
||||
};
|
||||
|
||||
+static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
|
||||
+
|
||||
static int systick_set_oneshot(struct clock_event_device *evt);
|
||||
static int systick_shutdown(struct clock_event_device *evt);
|
||||
|
||||
+static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
|
||||
+{
|
||||
+ if (sdev->freq_scale == status)
|
||||
+ return;
|
||||
+
|
||||
+ sdev->freq_scale = status;
|
||||
+
|
||||
+ pr_info("%s: %s autosleep mode\n", sdev->dev.name,
|
||||
+ (status) ? ("enable") : ("disable"));
|
||||
+ if (status)
|
||||
+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
|
||||
+ else
|
||||
+ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int read_count(struct systick_device *sdev)
|
||||
+{
|
||||
+ return ioread32(sdev->membase + SYSTICK_COUNT);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int read_compare(struct systick_device *sdev)
|
||||
+{
|
||||
+ return ioread32(sdev->membase + SYSTICK_COMPARE);
|
||||
+}
|
||||
+
|
||||
+static inline void write_compare(struct systick_device *sdev, unsigned int val)
|
||||
+{
|
||||
+ iowrite32(val, sdev->membase + SYSTICK_COMPARE);
|
||||
+}
|
||||
+
|
||||
static int systick_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
struct systick_device *sdev;
|
||||
- u32 count;
|
||||
+ int res;
|
||||
|
||||
sdev = container_of(evt, struct systick_device, dev);
|
||||
- count = ioread32(sdev->membase + SYSTICK_COUNT);
|
||||
- count = (count + delta) % SYSTICK_FREQ;
|
||||
- iowrite32(count, sdev->membase + SYSTICK_COMPARE);
|
||||
+ delta += read_count(sdev);
|
||||
+ write_compare(sdev, delta);
|
||||
+ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0;
|
||||
|
||||
- return 0;
|
||||
+ return res;
|
||||
}
|
||||
|
||||
static void systick_event_handler(struct clock_event_device *dev)
|
||||
@@ -60,20 +96,25 @@ static void systick_event_handler(struct
|
||||
|
||||
static irqreturn_t systick_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
- struct clock_event_device *dev = (struct clock_event_device *) dev_id;
|
||||
+ int ret = 0;
|
||||
+ struct clock_event_device *cdev;
|
||||
+ struct systick_device *sdev;
|
||||
|
||||
- dev->event_handler(dev);
|
||||
+ if (read_c0_cause() & STATUSF_IP7) {
|
||||
+ cdev = (struct clock_event_device *) dev_id;
|
||||
+ sdev = container_of(cdev, struct systick_device, dev);
|
||||
+
|
||||
+ /* Clear Count/Compare Interrupt */
|
||||
+ write_compare(sdev, read_compare(sdev));
|
||||
+ cdev->event_handler(cdev);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
|
||||
- return IRQ_HANDLED;
|
||||
+ return IRQ_RETVAL(ret);
|
||||
}
|
||||
|
||||
static struct systick_device systick = {
|
||||
.dev = {
|
||||
- /*
|
||||
- * cevt-r4k uses 300, make sure systick
|
||||
- * gets used if available
|
||||
- */
|
||||
- .rating = 310,
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.set_next_event = systick_next_event,
|
||||
.set_state_shutdown = systick_shutdown,
|
||||
@@ -95,9 +136,15 @@ static int systick_shutdown(struct clock
|
||||
sdev = container_of(evt, struct systick_device, dev);
|
||||
|
||||
if (sdev->irq_requested)
|
||||
- free_irq(systick.dev.irq, &systick_irqaction);
|
||||
+ remove_irq(systick.dev.irq, &systick_irqaction);
|
||||
sdev->irq_requested = 0;
|
||||
- iowrite32(0, systick.membase + SYSTICK_CONFIG);
|
||||
+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
|
||||
+
|
||||
+ if (systick_freq_scaling)
|
||||
+ systick_freq_scaling(sdev, 0);
|
||||
+
|
||||
+ if (systick_freq_scaling)
|
||||
+ systick_freq_scaling(sdev, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -117,34 +164,48 @@ static int systick_set_oneshot(struct cl
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct of_device_id systick_match[] = {
|
||||
+ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling},
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
static int __init ralink_systick_init(struct device_node *np)
|
||||
{
|
||||
+ const struct of_device_id *match;
|
||||
+ int rating = 200;
|
||||
int ret;
|
||||
|
||||
systick.membase = of_iomap(np, 0);
|
||||
if (!systick.membase)
|
||||
return -ENXIO;
|
||||
|
||||
- systick_irqaction.name = np->name;
|
||||
- systick.dev.name = np->name;
|
||||
- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
|
||||
- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
|
||||
- systick.dev.max_delta_ticks = 0x7fff;
|
||||
- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
|
||||
- systick.dev.min_delta_ticks = 0x3;
|
||||
+ match = of_match_node(systick_match, np);
|
||||
+ if (match) {
|
||||
+ systick_freq_scaling = match->data;
|
||||
+ /*
|
||||
+ * cevt-r4k uses 300, make sure systick
|
||||
+ * gets used if available
|
||||
+ */
|
||||
+ rating = 310;
|
||||
+ }
|
||||
+
|
||||
+ /* enable counter than register clock source */
|
||||
+ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
|
||||
+ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
|
||||
+ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up);
|
||||
+
|
||||
+ /* register clock event */
|
||||
systick.dev.irq = irq_of_parse_and_map(np, 0);
|
||||
if (!systick.dev.irq) {
|
||||
pr_err("%s: request_irq failed", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
|
||||
- SYSTICK_FREQ, 301, 16,
|
||||
- clocksource_mmio_readl_up);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- clockevents_register_device(&systick.dev);
|
||||
+ systick_irqaction.name = np->name;
|
||||
+ systick.dev.name = np->name;
|
||||
+ systick.dev.rating = rating;
|
||||
+ systick.dev.cpumask = cpumask_of(0);
|
||||
+ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff);
|
||||
|
||||
pr_info("%s: running - mult: %d, shift: %d\n",
|
||||
np->name, systick.dev.mult, systick.dev.shift);
|
@ -0,0 +1,21 @@
|
||||
From 67b7bff0fd364c194e653f69baa623ba2141bd4c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 4 Aug 2014 18:46:02 +0200
|
||||
Subject: [PATCH 07/53] MIPS: ralink: copy the commandline from the devicetree
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/of.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/arch/mips/ralink/of.c
|
||||
+++ b/arch/mips/ralink/of.c
|
||||
@@ -82,6 +82,8 @@ void __init plat_mem_setup(void)
|
||||
|
||||
__dt_setup_arch(dtb);
|
||||
|
||||
+ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
|
||||
+
|
||||
of_scan_flat_dt(early_init_dt_find_memory, NULL);
|
||||
if (memory_dtb)
|
||||
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
|
@ -0,0 +1,28 @@
|
||||
From 7768798964eb0e4f95eaecffb93b5d0ca28a38af Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 3 Jun 2017 20:00:03 +0200
|
||||
Subject: [PATCH] MIPS: pci-mt7620: enabled PCIe on MT7688
|
||||
To: linux-mips@linux-mips.org,
|
||||
John Crispin <john@phrozen.org>
|
||||
Cc: Wei Yongjun <yongjun_wei@trendmicro.com.cn>,
|
||||
Ralf Baechle <ralf@linux-mips.org>,
|
||||
linux-mediatek@lists.infradead.org
|
||||
|
||||
Use PCIe support for MT7628AN also on MT7688.
|
||||
Tested on WRTNODE2R.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
arch/mips/pci/pci-mt7620.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/mips/pci/pci-mt7620.c
|
||||
+++ b/arch/mips/pci/pci-mt7620.c
|
||||
@@ -316,6 +316,7 @@ static int mt7620_pci_probe(struct platf
|
||||
break;
|
||||
|
||||
case MT762X_SOC_MT7628AN:
|
||||
+ case MT762X_SOC_MT7688:
|
||||
if (mt7628_pci_hw_init(pdev))
|
||||
return -1;
|
||||
break;
|
@ -0,0 +1,28 @@
|
||||
From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:15:32 +0100
|
||||
Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/kernel/setup.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/mips/kernel/setup.c
|
||||
+++ b/arch/mips/kernel/setup.c
|
||||
@@ -910,7 +910,6 @@ static void __init arch_mem_init(char **
|
||||
crashk_res.end - crashk_res.start + 1,
|
||||
BOOTMEM_DEFAULT);
|
||||
#endif
|
||||
- device_tree_init();
|
||||
sparse_init();
|
||||
plat_swiotlb_setup();
|
||||
|
||||
@@ -1026,6 +1025,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
cpu_cache_init();
|
||||
paging_init();
|
||||
+ device_tree_init();
|
||||
}
|
||||
|
||||
unsigned long kernelsp[NR_CPUS];
|
@ -0,0 +1,25 @@
|
||||
From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 7 Dec 2015 17:18:05 +0100
|
||||
Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by
|
||||
default
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/ralink/Kconfig | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/mips/ralink/Kconfig
|
||||
+++ b/arch/mips/ralink/Kconfig
|
||||
@@ -14,9 +14,9 @@ config CLKEVT_RT3352
|
||||
select CEVT_SYSTICK_QUIRK
|
||||
|
||||
config RALINK_ILL_ACC
|
||||
- bool
|
||||
+ bool "illegal access irq"
|
||||
depends on SOC_RT305X
|
||||
- default y
|
||||
+ default n
|
||||
|
||||
config IRQ_INTC
|
||||
bool
|
@ -0,0 +1,166 @@
|
||||
From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 12 Aug 2014 20:49:27 +0200
|
||||
Subject: [PATCH 24/53] GPIO: add named gpio exports
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/gpio/gpiolib-sysfs.c | 10 +++++-
|
||||
include/asm-generic/gpio.h | 6 ++++
|
||||
include/linux/gpio/consumer.h | 8 +++++
|
||||
4 files changed, 91 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpio/gpiolib-of.c
|
||||
+++ b/drivers/gpio/gpiolib-of.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/platform_device.h>
|
||||
|
||||
#include "gpiolib.h"
|
||||
|
||||
@@ -506,3 +508,69 @@ void of_gpiochip_remove(struct gpio_chip
|
||||
gpiochip_remove_pin_ranges(chip);
|
||||
of_node_put(chip->of_node);
|
||||
}
|
||||
+
|
||||
+static struct of_device_id gpio_export_ids[] = {
|
||||
+ { .compatible = "gpio-export" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+
|
||||
+static int __init of_gpio_export_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct device_node *cnp;
|
||||
+ u32 val;
|
||||
+ int nb = 0;
|
||||
+
|
||||
+ for_each_child_of_node(np, cnp) {
|
||||
+ const char *name = NULL;
|
||||
+ int gpio;
|
||||
+ bool dmc;
|
||||
+ int max_gpio = 1;
|
||||
+ int i;
|
||||
+
|
||||
+ of_property_read_string(cnp, "gpio-export,name", &name);
|
||||
+
|
||||
+ if (!name)
|
||||
+ max_gpio = of_gpio_count(cnp);
|
||||
+
|
||||
+ for (i = 0; i < max_gpio; i++) {
|
||||
+ unsigned flags = 0;
|
||||
+ enum of_gpio_flags of_flags;
|
||||
+
|
||||
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
|
||||
+
|
||||
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
|
||||
+ flags |= GPIOF_ACTIVE_LOW;
|
||||
+
|
||||
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
|
||||
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
|
||||
+ else
|
||||
+ flags |= GPIOF_IN;
|
||||
+
|
||||
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
|
||||
+ continue;
|
||||
+
|
||||
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
|
||||
+ gpio_export_with_name(gpio, dmc, name);
|
||||
+ nb++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver gpio_export_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "gpio-export",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(gpio_export_ids),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init of_gpio_export_init(void)
|
||||
+{
|
||||
+ return platform_driver_probe(&gpio_export_driver, of_gpio_export_probe);
|
||||
+}
|
||||
+device_initcall(of_gpio_export_init);
|
||||
--- a/drivers/gpio/gpiolib-sysfs.c
|
||||
+++ b/drivers/gpio/gpiolib-sysfs.c
|
||||
@@ -553,7 +553,7 @@ static struct class gpio_class = {
|
||||
*
|
||||
* Returns zero on success, else an error.
|
||||
*/
|
||||
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
struct gpio_device *gdev;
|
||||
@@ -615,6 +615,8 @@ int gpiod_export(struct gpio_desc *desc,
|
||||
offset = gpio_chip_hwgpio(desc);
|
||||
if (chip->names && chip->names[offset])
|
||||
ioname = chip->names[offset];
|
||||
+ if (name)
|
||||
+ ioname = name;
|
||||
|
||||
dev = device_create_with_groups(&gpio_class, &gdev->dev,
|
||||
MKDEV(0, 0), data, gpio_groups,
|
||||
@@ -636,6 +638,12 @@ err_unlock:
|
||||
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
|
||||
return status;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(__gpiod_export);
|
||||
+
|
||||
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
+{
|
||||
+ return __gpiod_export(desc, direction_may_change, NULL);
|
||||
+}
|
||||
EXPORT_SYMBOL_GPL(gpiod_export);
|
||||
|
||||
static int match_export(struct device *dev, const void *desc)
|
||||
--- a/include/asm-generic/gpio.h
|
||||
+++ b/include/asm-generic/gpio.h
|
||||
@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
|
||||
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
|
||||
}
|
||||
|
||||
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
|
||||
+{
|
||||
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
|
||||
+}
|
||||
+
|
||||
static inline int gpio_export_link(struct device *dev, const char *name,
|
||||
unsigned gpio)
|
||||
{
|
||||
--- a/include/linux/gpio/consumer.h
|
||||
+++ b/include/linux/gpio/consumer.h
|
||||
@@ -451,6 +451,7 @@ struct gpio_desc *devm_fwnode_get_gpiod_
|
||||
|
||||
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
|
||||
|
||||
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||
int gpiod_export_link(struct device *dev, const char *name,
|
||||
struct gpio_desc *desc);
|
||||
@@ -458,6 +459,13 @@ void gpiod_unexport(struct gpio_desc *de
|
||||
|
||||
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
|
||||
|
||||
+static inline int _gpiod_export(struct gpio_desc *desc,
|
||||
+ bool direction_may_change,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
+
|
||||
static inline int gpiod_export(struct gpio_desc *desc,
|
||||
bool direction_may_change)
|
||||
{
|
@ -0,0 +1,524 @@
|
||||
From 7adbe9a88c33c6e362a10b109d963b5500a21f00 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:34:05 +0100
|
||||
Subject: [PATCH 25/53] pinctrl: ralink: add pinctrl driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/Kconfig | 2 +
|
||||
drivers/pinctrl/Kconfig | 5 +
|
||||
drivers/pinctrl/Makefile | 1 +
|
||||
drivers/pinctrl/pinctrl-rt2880.c | 474 ++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 482 insertions(+)
|
||||
create mode 100644 drivers/pinctrl/pinctrl-rt2880.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -628,6 +628,8 @@ config RALINK
|
||||
select CLKDEV_LOOKUP
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select RESET_CONTROLLER
|
||||
+ select PINCTRL
|
||||
+ select PINCTRL_RT2880
|
||||
|
||||
config SGI_IP22
|
||||
bool "SGI IP22 (Indy/Indigo2)"
|
||||
--- a/drivers/pinctrl/Kconfig
|
||||
+++ b/drivers/pinctrl/Kconfig
|
||||
@@ -143,6 +143,11 @@ config PINCTRL_LPC18XX
|
||||
help
|
||||
Pinctrl driver for NXP LPC18xx/43xx System Control Unit (SCU).
|
||||
|
||||
+config PINCTRL_RT2880
|
||||
+ bool
|
||||
+ depends on RALINK
|
||||
+ select PINMUX
|
||||
+
|
||||
config PINCTRL_FALCON
|
||||
bool
|
||||
depends on SOC_FALCON
|
||||
--- a/drivers/pinctrl/Makefile
|
||||
+++ b/drivers/pinctrl/Makefile
|
||||
@@ -28,6 +28,7 @@ obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-
|
||||
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
||||
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
||||
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
||||
+obj-$(CONFIG_PINCTRL_RT2880) += pinctrl-rt2880.o
|
||||
obj-$(CONFIG_PINCTRL_RZA1) += pinctrl-rza1.o
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
obj-$(CONFIG_PINCTRL_SIRF) += sirf/
|
||||
--- /dev/null
|
||||
+++ b/drivers/pinctrl/pinctrl-rt2880.c
|
||||
@@ -0,0 +1,472 @@
|
||||
+/*
|
||||
+ * linux/drivers/pinctrl/pinctrl-rt2880.c
|
||||
+ *
|
||||
+ * 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
|
||||
+ * publishhed by the Free Software Foundation.
|
||||
+ *
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/pinctrl/pinctrl.h>
|
||||
+#include <linux/pinctrl/pinconf.h>
|
||||
+#include <linux/pinctrl/pinmux.h>
|
||||
+#include <linux/pinctrl/consumer.h>
|
||||
+#include <linux/pinctrl/machine.h>
|
||||
+
|
||||
+#include <asm/mach-ralink/ralink_regs.h>
|
||||
+#include <asm/mach-ralink/pinmux.h>
|
||||
+#include <asm/mach-ralink/mt7620.h>
|
||||
+
|
||||
+#include "core.h"
|
||||
+
|
||||
+#define SYSC_REG_GPIO_MODE 0x60
|
||||
+#define SYSC_REG_GPIO_MODE2 0x64
|
||||
+
|
||||
+struct rt2880_priv {
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ struct pinctrl_pin_desc *pads;
|
||||
+ struct pinctrl_desc *desc;
|
||||
+
|
||||
+ struct rt2880_pmx_func **func;
|
||||
+ int func_count;
|
||||
+
|
||||
+ struct rt2880_pmx_group *groups;
|
||||
+ const char **group_names;
|
||||
+ int group_count;
|
||||
+
|
||||
+ uint8_t *gpio;
|
||||
+ int max_pins;
|
||||
+};
|
||||
+
|
||||
+static int rt2880_get_group_count(struct pinctrl_dev *pctrldev)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ return p->group_count;
|
||||
+}
|
||||
+
|
||||
+static const char *rt2880_get_group_name(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned group)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (group >= p->group_count)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return p->group_names[group];
|
||||
+}
|
||||
+
|
||||
+static int rt2880_get_group_pins(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned group,
|
||||
+ const unsigned **pins,
|
||||
+ unsigned *num_pins)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (group >= p->group_count)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *pins = p->groups[group].func[0].pins;
|
||||
+ *num_pins = p->groups[group].func[0].pin_count;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void rt2880_pinctrl_dt_free_map(struct pinctrl_dev *pctrldev,
|
||||
+ struct pinctrl_map *map, unsigned num_maps)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < num_maps; i++)
|
||||
+ if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN ||
|
||||
+ map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
|
||||
+ kfree(map[i].data.configs.configs);
|
||||
+ kfree(map);
|
||||
+}
|
||||
+
|
||||
+static void rt2880_pinctrl_pin_dbg_show(struct pinctrl_dev *pctrldev,
|
||||
+ struct seq_file *s,
|
||||
+ unsigned offset)
|
||||
+{
|
||||
+ seq_printf(s, "ralink pio");
|
||||
+}
|
||||
+
|
||||
+static void rt2880_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctrldev,
|
||||
+ struct device_node *np,
|
||||
+ struct pinctrl_map **map)
|
||||
+{
|
||||
+ const char *function;
|
||||
+ int func = of_property_read_string(np, "ralink,function", &function);
|
||||
+ int grps = of_property_count_strings(np, "ralink,group");
|
||||
+ int i;
|
||||
+
|
||||
+ if (func || !grps)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < grps; i++) {
|
||||
+ const char *group;
|
||||
+
|
||||
+ of_property_read_string_index(np, "ralink,group", i, &group);
|
||||
+
|
||||
+ (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
|
||||
+ (*map)->name = function;
|
||||
+ (*map)->data.mux.group = group;
|
||||
+ (*map)->data.mux.function = function;
|
||||
+ (*map)++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrldev,
|
||||
+ struct device_node *np_config,
|
||||
+ struct pinctrl_map **map,
|
||||
+ unsigned *num_maps)
|
||||
+{
|
||||
+ int max_maps = 0;
|
||||
+ struct pinctrl_map *tmp;
|
||||
+ struct device_node *np;
|
||||
+
|
||||
+ for_each_child_of_node(np_config, np) {
|
||||
+ int ret = of_property_count_strings(np, "ralink,group");
|
||||
+
|
||||
+ if (ret >= 0)
|
||||
+ max_maps += ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!max_maps)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *map = kzalloc(max_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
|
||||
+ if (!*map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ tmp = *map;
|
||||
+
|
||||
+ for_each_child_of_node(np_config, np)
|
||||
+ rt2880_pinctrl_dt_subnode_to_map(pctrldev, np, &tmp);
|
||||
+ *num_maps = max_maps;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pinctrl_ops rt2880_pctrl_ops = {
|
||||
+ .get_groups_count = rt2880_get_group_count,
|
||||
+ .get_group_name = rt2880_get_group_name,
|
||||
+ .get_group_pins = rt2880_get_group_pins,
|
||||
+ .pin_dbg_show = rt2880_pinctrl_pin_dbg_show,
|
||||
+ .dt_node_to_map = rt2880_pinctrl_dt_node_to_map,
|
||||
+ .dt_free_map = rt2880_pinctrl_dt_free_map,
|
||||
+};
|
||||
+
|
||||
+static int rt2880_pmx_func_count(struct pinctrl_dev *pctrldev)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ return p->func_count;
|
||||
+}
|
||||
+
|
||||
+static const char *rt2880_pmx_func_name(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned func)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ return p->func[func]->name;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pmx_group_get_groups(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned func,
|
||||
+ const char * const **groups,
|
||||
+ unsigned * const num_groups)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (p->func[func]->group_count == 1)
|
||||
+ *groups = &p->group_names[p->func[func]->groups[0]];
|
||||
+ else
|
||||
+ *groups = p->group_names;
|
||||
+
|
||||
+ *num_groups = p->func[func]->group_count;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned func,
|
||||
+ unsigned group)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+ u32 mode = 0;
|
||||
+ u32 reg = SYSC_REG_GPIO_MODE;
|
||||
+ int i;
|
||||
+ int shift;
|
||||
+
|
||||
+ /* dont allow double use */
|
||||
+ if (p->groups[group].enabled) {
|
||||
+ dev_err(p->dev, "%s is already enabled\n", p->groups[group].name);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ p->groups[group].enabled = 1;
|
||||
+ p->func[func]->enabled = 1;
|
||||
+
|
||||
+ shift = p->groups[group].shift;
|
||||
+ if (shift >= 32) {
|
||||
+ shift -= 32;
|
||||
+ reg = SYSC_REG_GPIO_MODE2;
|
||||
+ }
|
||||
+ mode = rt_sysc_r32(reg);
|
||||
+ mode &= ~(p->groups[group].mask << shift);
|
||||
+
|
||||
+ /* mark the pins as gpio */
|
||||
+ for (i = 0; i < p->groups[group].func[0].pin_count; i++)
|
||||
+ p->gpio[p->groups[group].func[0].pins[i]] = 1;
|
||||
+
|
||||
+ /* function 0 is gpio and needs special handling */
|
||||
+ if (func == 0) {
|
||||
+ mode |= p->groups[group].gpio << shift;
|
||||
+ } else {
|
||||
+ for (i = 0; i < p->func[func]->pin_count; i++)
|
||||
+ p->gpio[p->func[func]->pins[i]] = 0;
|
||||
+ mode |= p->func[func]->value << shift;
|
||||
+ }
|
||||
+ rt_sysc_w32(mode, reg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev,
|
||||
+ struct pinctrl_gpio_range *range,
|
||||
+ unsigned pin)
|
||||
+{
|
||||
+ struct rt2880_priv *p = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+
|
||||
+ if (!p->gpio[pin]) {
|
||||
+ dev_err(p->dev, "pin %d is not set to gpio mux\n", pin);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pinmux_ops rt2880_pmx_group_ops = {
|
||||
+ .get_functions_count = rt2880_pmx_func_count,
|
||||
+ .get_function_name = rt2880_pmx_func_name,
|
||||
+ .get_function_groups = rt2880_pmx_group_get_groups,
|
||||
+ .set_mux = rt2880_pmx_group_enable,
|
||||
+ .gpio_request_enable = rt2880_pmx_group_gpio_request_enable,
|
||||
+};
|
||||
+
|
||||
+static struct pinctrl_desc rt2880_pctrl_desc = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .name = "rt2880-pinmux",
|
||||
+ .pctlops = &rt2880_pctrl_ops,
|
||||
+ .pmxops = &rt2880_pmx_group_ops,
|
||||
+};
|
||||
+
|
||||
+static struct rt2880_pmx_func gpio_func = {
|
||||
+ .name = "gpio",
|
||||
+};
|
||||
+
|
||||
+static int rt2880_pinmux_index(struct rt2880_priv *p)
|
||||
+{
|
||||
+ struct rt2880_pmx_func **f;
|
||||
+ struct rt2880_pmx_group *mux = p->groups;
|
||||
+ int i, j, c = 0;
|
||||
+
|
||||
+ /* count the mux functions */
|
||||
+ while (mux->name) {
|
||||
+ p->group_count++;
|
||||
+ mux++;
|
||||
+ }
|
||||
+
|
||||
+ /* allocate the group names array needed by the gpio function */
|
||||
+ p->group_names = devm_kzalloc(p->dev, sizeof(char *) * p->group_count, GFP_KERNEL);
|
||||
+ if (!p->group_names)
|
||||
+ return -1;
|
||||
+
|
||||
+ for (i = 0; i < p->group_count; i++) {
|
||||
+ p->group_names[i] = p->groups[i].name;
|
||||
+ p->func_count += p->groups[i].func_count;
|
||||
+ }
|
||||
+
|
||||
+ /* we have a dummy function[0] for gpio */
|
||||
+ p->func_count++;
|
||||
+
|
||||
+ /* allocate our function and group mapping index buffers */
|
||||
+ f = p->func = devm_kzalloc(p->dev, sizeof(struct rt2880_pmx_func) * p->func_count, GFP_KERNEL);
|
||||
+ gpio_func.groups = devm_kzalloc(p->dev, sizeof(int) * p->group_count, GFP_KERNEL);
|
||||
+ if (!f || !gpio_func.groups)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* add a backpointer to the function so it knows its group */
|
||||
+ gpio_func.group_count = p->group_count;
|
||||
+ for (i = 0; i < gpio_func.group_count; i++)
|
||||
+ gpio_func.groups[i] = i;
|
||||
+
|
||||
+ f[c] = &gpio_func;
|
||||
+ c++;
|
||||
+
|
||||
+ /* add remaining functions */
|
||||
+ for (i = 0; i < p->group_count; i++) {
|
||||
+ for (j = 0; j < p->groups[i].func_count; j++) {
|
||||
+ f[c] = &p->groups[i].func[j];
|
||||
+ f[c]->groups = devm_kzalloc(p->dev, sizeof(int), GFP_KERNEL);
|
||||
+ f[c]->groups[0] = i;
|
||||
+ f[c]->group_count = 1;
|
||||
+ c++;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pinmux_pins(struct rt2880_priv *p)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ /* loop over the functions and initialize the pins array. also work out the highest pin used */
|
||||
+ for (i = 0; i < p->func_count; i++) {
|
||||
+ int pin;
|
||||
+
|
||||
+ if (!p->func[i]->pin_count)
|
||||
+ continue;
|
||||
+
|
||||
+ p->func[i]->pins = devm_kzalloc(p->dev, sizeof(int) * p->func[i]->pin_count, GFP_KERNEL);
|
||||
+ for (j = 0; j < p->func[i]->pin_count; j++)
|
||||
+ p->func[i]->pins[j] = p->func[i]->pin_first + j;
|
||||
+
|
||||
+ pin = p->func[i]->pin_first + p->func[i]->pin_count;
|
||||
+ if (pin > p->max_pins)
|
||||
+ p->max_pins = pin;
|
||||
+ }
|
||||
+
|
||||
+ /* the buffer that tells us which pins are gpio */
|
||||
+ p->gpio = devm_kzalloc(p->dev,sizeof(uint8_t) * p->max_pins,
|
||||
+ GFP_KERNEL);
|
||||
+ /* the pads needed to tell pinctrl about our pins */
|
||||
+ p->pads = devm_kzalloc(p->dev,
|
||||
+ sizeof(struct pinctrl_pin_desc) * p->max_pins,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!p->pads || !p->gpio ) {
|
||||
+ dev_err(p->dev, "Failed to allocate gpio data\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ memset(p->gpio, 1, sizeof(uint8_t) * p->max_pins);
|
||||
+ for (i = 0; i < p->func_count; i++) {
|
||||
+ if (!p->func[i]->pin_count)
|
||||
+ continue;
|
||||
+
|
||||
+ for (j = 0; j < p->func[i]->pin_count; j++)
|
||||
+ p->gpio[p->func[i]->pins[j]] = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* pin 0 is always a gpio */
|
||||
+ p->gpio[0] = 1;
|
||||
+
|
||||
+ /* set the pads */
|
||||
+ for (i = 0; i < p->max_pins; i++) {
|
||||
+ /* strlen("ioXY") + 1 = 5 */
|
||||
+ char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL);
|
||||
+
|
||||
+ if (!name) {
|
||||
+ dev_err(p->dev, "Failed to allocate pad name\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ snprintf(name, 5, "io%d", i);
|
||||
+ p->pads[i].number = i;
|
||||
+ p->pads[i].name = name;
|
||||
+ }
|
||||
+ p->desc->pins = p->pads;
|
||||
+ p->desc->npins = p->max_pins;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rt2880_pinmux_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct rt2880_priv *p;
|
||||
+ struct pinctrl_dev *dev;
|
||||
+ struct device_node *np;
|
||||
+
|
||||
+ if (!rt2880_pinmux_data)
|
||||
+ return -ENOSYS;
|
||||
+
|
||||
+ /* setup the private data */
|
||||
+ p = devm_kzalloc(&pdev->dev, sizeof(struct rt2880_priv), GFP_KERNEL);
|
||||
+ if (!p)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ p->dev = &pdev->dev;
|
||||
+ p->desc = &rt2880_pctrl_desc;
|
||||
+ p->groups = rt2880_pinmux_data;
|
||||
+ platform_set_drvdata(pdev, p);
|
||||
+
|
||||
+ /* init the device */
|
||||
+ if (rt2880_pinmux_index(p)) {
|
||||
+ dev_err(&pdev->dev, "failed to load index\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (rt2880_pinmux_pins(p)) {
|
||||
+ dev_err(&pdev->dev, "failed to load pins\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ dev = pinctrl_register(p->desc, &pdev->dev, p);
|
||||
+ if (IS_ERR(dev))
|
||||
+ return PTR_ERR(dev);
|
||||
+
|
||||
+ /* finalize by adding gpio ranges for enables gpio controllers */
|
||||
+ for_each_compatible_node(np, NULL, "ralink,rt2880-gpio") {
|
||||
+ const __be32 *ngpio, *gpiobase;
|
||||
+ struct pinctrl_gpio_range *range;
|
||||
+ char *name;
|
||||
+
|
||||
+ if (!of_device_is_available(np))
|
||||
+ continue;
|
||||
+
|
||||
+ ngpio = of_get_property(np, "ralink,num-gpios", NULL);
|
||||
+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
|
||||
+ if (!ngpio || !gpiobase) {
|
||||
+ dev_err(&pdev->dev, "failed to load chip info\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ range = devm_kzalloc(p->dev, sizeof(struct pinctrl_gpio_range) + 4, GFP_KERNEL);
|
||||
+ range->name = name = (char *) &range[1];
|
||||
+ sprintf(name, "pio");
|
||||
+ range->npins = __be32_to_cpu(*ngpio);
|
||||
+ range->base = __be32_to_cpu(*gpiobase);
|
||||
+ range->pin_base = range->base;
|
||||
+ pinctrl_add_gpio_range(dev, range);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id rt2880_pinmux_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-pinmux" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rt2880_pinmux_match);
|
||||
+
|
||||
+static struct platform_driver rt2880_pinmux_driver = {
|
||||
+ .probe = rt2880_pinmux_probe,
|
||||
+ .driver = {
|
||||
+ .name = "rt2880-pinmux",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = rt2880_pinmux_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init rt2880_pinmux_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&rt2880_pinmux_driver);
|
||||
+}
|
||||
+
|
||||
+core_initcall_sync(rt2880_pinmux_init);
|
@ -0,0 +1,59 @@
|
||||
From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jul 2013 19:45:30 +0200
|
||||
Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink
|
||||
|
||||
Describe gpio-ralink binding.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Cc: linux-gpio@vger.kernel.org
|
||||
---
|
||||
.../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
|
||||
@@ -0,0 +1,40 @@
|
||||
+Ralink SoC GPIO controller bindings
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible:
|
||||
+ - "ralink,rt2880-gpio" for Ralink controllers
|
||||
+- #gpio-cells : Should be two.
|
||||
+ - first cell is the pin number
|
||||
+ - second cell is used to specify optional parameters (unused)
|
||||
+- gpio-controller : Marks the device node as a GPIO controller
|
||||
+- reg : Physical base address and length of the controller's registers
|
||||
+- interrupt-parent: phandle to the INTC device node
|
||||
+- interrupts : Specify the INTC interrupt number
|
||||
+- ralink,num-gpios : Specify the number of GPIOs
|
||||
+- ralink,register-map : The register layout depends on the GPIO bank and actual
|
||||
+ SoC type. Register offsets need to be in this order.
|
||||
+ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
|
||||
+
|
||||
+Optional properties:
|
||||
+- ralink,gpio-base : Specify the GPIO chips base number
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ gpio0: gpio@600 {
|
||||
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
|
||||
+
|
||||
+ #gpio-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+
|
||||
+ reg = <0x600 0x34>;
|
||||
+
|
||||
+ interrupt-parent = <&intc>;
|
||||
+ interrupts = <6>;
|
||||
+
|
||||
+ ralink,gpio-base = <0>;
|
||||
+ ralink,num-gpios = <24>;
|
||||
+ ralink,register-map = [ 00 04 08 0c
|
||||
+ 20 24 28 2c
|
||||
+ 30 34 ];
|
||||
+
|
||||
+ };
|
@ -0,0 +1,430 @@
|
||||
From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 4 Aug 2014 20:36:29 +0200
|
||||
Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC
|
||||
|
||||
Add gpio driver for Ralink SoC. This driver makes the gpio core on
|
||||
RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-mips@linux-mips.org
|
||||
Cc: linux-gpio@vger.kernel.org
|
||||
---
|
||||
arch/mips/include/asm/mach-ralink/gpio.h | 24 ++
|
||||
drivers/gpio/Kconfig | 6 +
|
||||
drivers/gpio/Makefile | 1 +
|
||||
drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++
|
||||
4 files changed, 386 insertions(+)
|
||||
create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
|
||||
create mode 100644 drivers/gpio/gpio-ralink.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/mach-ralink/gpio.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/*
|
||||
+ * Ralink SoC GPIO API support
|
||||
+ *
|
||||
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef __ASM_MACH_RALINK_GPIO_H
|
||||
+#define __ASM_MACH_RALINK_GPIO_H
|
||||
+
|
||||
+#define ARCH_NR_GPIOS 128
|
||||
+#include <asm-generic/gpio.h>
|
||||
+
|
||||
+#define gpio_get_value __gpio_get_value
|
||||
+#define gpio_set_value __gpio_set_value
|
||||
+#define gpio_cansleep __gpio_cansleep
|
||||
+#define gpio_to_irq __gpio_to_irq
|
||||
+
|
||||
+#endif /* __ASM_MACH_RALINK_GPIO_H */
|
||||
--- a/drivers/gpio/Kconfig
|
||||
+++ b/drivers/gpio/Kconfig
|
||||
@@ -398,6 +398,12 @@ config GPIO_REG
|
||||
A 32-bit single register GPIO fixed in/out implementation. This
|
||||
can be used to represent any register as a set of GPIO signals.
|
||||
|
||||
+config GPIO_RALINK
|
||||
+ bool "Ralink GPIO Support"
|
||||
+ depends on RALINK
|
||||
+ help
|
||||
+ Say yes here to support the Ralink SoC GPIO device
|
||||
+
|
||||
config GPIO_SPEAR_SPICS
|
||||
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
|
||||
depends on PLAT_SPEAR
|
||||
--- a/drivers/gpio/Makefile
|
||||
+++ b/drivers/gpio/Makefile
|
||||
@@ -98,6 +98,7 @@ obj-$(CONFIG_GPIO_PCI_IDIO_16) += gpio-p
|
||||
obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
|
||||
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
|
||||
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
|
||||
+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
|
||||
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
|
||||
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
|
||||
obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpio/gpio-ralink.c
|
||||
@@ -0,0 +1,355 @@
|
||||
+/*
|
||||
+ * 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) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+
|
||||
+enum ralink_gpio_reg {
|
||||
+ GPIO_REG_INT = 0,
|
||||
+ GPIO_REG_EDGE,
|
||||
+ GPIO_REG_RENA,
|
||||
+ GPIO_REG_FENA,
|
||||
+ GPIO_REG_DATA,
|
||||
+ GPIO_REG_DIR,
|
||||
+ GPIO_REG_POL,
|
||||
+ GPIO_REG_SET,
|
||||
+ GPIO_REG_RESET,
|
||||
+ GPIO_REG_TOGGLE,
|
||||
+ GPIO_REG_MAX
|
||||
+};
|
||||
+
|
||||
+struct ralink_gpio_chip {
|
||||
+ struct gpio_chip chip;
|
||||
+ u8 regs[GPIO_REG_MAX];
|
||||
+
|
||||
+ spinlock_t lock;
|
||||
+ void __iomem *membase;
|
||||
+ struct irq_domain *domain;
|
||||
+ int irq;
|
||||
+
|
||||
+ u32 rising;
|
||||
+ u32 falling;
|
||||
+};
|
||||
+
|
||||
+#define MAP_MAX 4
|
||||
+static struct irq_domain *irq_map[MAP_MAX];
|
||||
+static int irq_map_count;
|
||||
+static atomic_t irq_refcount = ATOMIC_INIT(0);
|
||||
+
|
||||
+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+
|
||||
+ rg = container_of(chip, struct ralink_gpio_chip, chip);
|
||||
+
|
||||
+ return rg;
|
||||
+}
|
||||
+
|
||||
+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, rg->membase + rg->regs[reg]);
|
||||
+}
|
||||
+
|
||||
+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
|
||||
+{
|
||||
+ return ioread32(rg->membase + rg->regs[reg]);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
|
||||
+ t &= ~BIT(offset);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_direction_output(struct gpio_chip *chip,
|
||||
+ unsigned offset, int value)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ ralink_gpio_set(chip, offset, value);
|
||||
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
|
||||
+ t |= BIT(offset);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
|
||||
+
|
||||
+ if (rg->irq < 1)
|
||||
+ return -1;
|
||||
+
|
||||
+ return irq_create_mapping(rg->domain, pin);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_handler(struct irq_desc *desc)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < irq_map_count; i++) {
|
||||
+ struct irq_domain *domain = irq_map[i];
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long pending;
|
||||
+ int bit;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) domain->host_data;
|
||||
+ pending = rt_gpio_r32(rg, GPIO_REG_INT);
|
||||
+
|
||||
+ for_each_set_bit(bit, &pending, rg->chip.ngpio) {
|
||||
+ u32 map = irq_find_mapping(domain, bit);
|
||||
+ generic_handle_irq(map);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
|
||||
+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising));
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+ rise = rt_gpio_r32(rg, GPIO_REG_RENA);
|
||||
+ fall = rt_gpio_r32(rg, GPIO_REG_FENA);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq));
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
+{
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ u32 mask = BIT(d->hwirq);
|
||||
+
|
||||
+ rg = (struct ralink_gpio_chip *) d->domain->host_data;
|
||||
+
|
||||
+ if (type == IRQ_TYPE_PROBE) {
|
||||
+ if ((rg->rising | rg->falling) & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
+ }
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_RISING)
|
||||
+ rg->rising |= mask;
|
||||
+ else
|
||||
+ rg->rising &= ~mask;
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
+ rg->falling |= mask;
|
||||
+ else
|
||||
+ rg->falling &= ~mask;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip ralink_gpio_irq_chip = {
|
||||
+ .name = "GPIO",
|
||||
+ .irq_unmask = ralink_gpio_irq_unmask,
|
||||
+ .irq_mask = ralink_gpio_irq_mask,
|
||||
+ .irq_mask_ack = ralink_gpio_irq_mask,
|
||||
+ .irq_set_type = ralink_gpio_irq_type,
|
||||
+};
|
||||
+
|
||||
+static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
+{
|
||||
+ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
|
||||
+ irq_set_handler_data(irq, d);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops irq_domain_ops = {
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+ .map = gpio_map,
|
||||
+};
|
||||
+
|
||||
+static void ralink_gpio_irq_init(struct device_node *np,
|
||||
+ struct ralink_gpio_chip *rg)
|
||||
+{
|
||||
+ if (irq_map_count >= MAP_MAX)
|
||||
+ return;
|
||||
+
|
||||
+ rg->irq = irq_of_parse_and_map(np, 0);
|
||||
+ if (!rg->irq)
|
||||
+ return;
|
||||
+
|
||||
+ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
|
||||
+ &irq_domain_ops, rg);
|
||||
+ if (!rg->domain) {
|
||||
+ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ irq_map[irq_map_count++] = rg->domain;
|
||||
+
|
||||
+ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
|
||||
+ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
|
||||
+
|
||||
+ if (!atomic_read(&irq_refcount))
|
||||
+ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
|
||||
+ atomic_inc(&irq_refcount);
|
||||
+
|
||||
+ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_request(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ int gpio = chip->base + offset;
|
||||
+
|
||||
+ return pinctrl_request_gpio(gpio);
|
||||
+}
|
||||
+
|
||||
+static void ralink_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ int gpio = chip->base + offset;
|
||||
+
|
||||
+ pinctrl_free_gpio(gpio);
|
||||
+}
|
||||
+
|
||||
+static int ralink_gpio_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ struct ralink_gpio_chip *rg;
|
||||
+ const __be32 *ngpio, *gpiobase;
|
||||
+
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "failed to find resource\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ rg = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
|
||||
+ if (!rg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rg->membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (!rg->membase) {
|
||||
+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ if (of_property_read_u8_array(np, "ralink,register-map",
|
||||
+ rg->regs, GPIO_REG_MAX)) {
|
||||
+ dev_err(&pdev->dev, "failed to read register definition\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ngpio = of_get_property(np, "ralink,num-gpios", NULL);
|
||||
+ if (!ngpio) {
|
||||
+ dev_err(&pdev->dev, "failed to read number of pins\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
|
||||
+ if (gpiobase)
|
||||
+ rg->chip.base = be32_to_cpu(*gpiobase);
|
||||
+ else
|
||||
+ rg->chip.base = -1;
|
||||
+
|
||||
+ spin_lock_init(&rg->lock);
|
||||
+
|
||||
+ rg->chip.parent = &pdev->dev;
|
||||
+ rg->chip.label = dev_name(&pdev->dev);
|
||||
+ rg->chip.of_node = np;
|
||||
+ rg->chip.ngpio = be32_to_cpu(*ngpio);
|
||||
+ rg->chip.direction_input = ralink_gpio_direction_input;
|
||||
+ rg->chip.direction_output = ralink_gpio_direction_output;
|
||||
+ rg->chip.get = ralink_gpio_get;
|
||||
+ rg->chip.set = ralink_gpio_set;
|
||||
+ rg->chip.request = ralink_gpio_request;
|
||||
+ rg->chip.to_irq = ralink_gpio_to_irq;
|
||||
+ rg->chip.free = ralink_gpio_free;
|
||||
+
|
||||
+ /* set polarity to low for all lines */
|
||||
+ rt_gpio_w32(rg, GPIO_REG_POL, 0);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
|
||||
+
|
||||
+ ralink_gpio_irq_init(np, rg);
|
||||
+
|
||||
+ return gpiochip_add(&rg->chip);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ralink_gpio_match[] = {
|
||||
+ { .compatible = "ralink,rt2880-gpio" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
|
||||
+
|
||||
+static struct platform_driver ralink_gpio_driver = {
|
||||
+ .probe = ralink_gpio_probe,
|
||||
+ .driver = {
|
||||
+ .name = "rt2880_gpio",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = ralink_gpio_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init ralink_gpio_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&ralink_gpio_driver);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(ralink_gpio_init);
|
@ -0,0 +1,405 @@
|
||||
From 61ac7d9b4228de8c332900902c2b93189b042eab Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 11:00:32 +0100
|
||||
Subject: [PATCH 28/53] GPIO: ralink: add mt7621 gpio controller
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/Kconfig | 3 +
|
||||
drivers/gpio/Kconfig | 6 +
|
||||
drivers/gpio/Makefile | 1 +
|
||||
drivers/gpio/gpio-mt7621.c | 354 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 364 insertions(+)
|
||||
create mode 100644 drivers/gpio/gpio-mt7621.c
|
||||
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -630,6 +630,9 @@ config RALINK
|
||||
select RESET_CONTROLLER
|
||||
select PINCTRL
|
||||
select PINCTRL_RT2880
|
||||
+ select ARCH_HAS_RESET_CONTROLLER
|
||||
+ select RESET_CONTROLLER
|
||||
+ select ARCH_REQUIRE_GPIOLIB
|
||||
|
||||
config SGI_IP22
|
||||
bool "SGI IP22 (Indy/Indigo2)"
|
||||
--- a/drivers/gpio/Kconfig
|
||||
+++ b/drivers/gpio/Kconfig
|
||||
@@ -298,6 +298,12 @@ config GPIO_MENZ127
|
||||
help
|
||||
Say yes here to support the MEN 16Z127 GPIO Controller
|
||||
|
||||
+config GPIO_MT7621
|
||||
+ bool "Mediatek GPIO Support"
|
||||
+ depends on SOC_MT7620 || SOC_MT7621
|
||||
+ help
|
||||
+ Say yes here to support the Mediatek SoC GPIO device
|
||||
+
|
||||
config GPIO_MM_LANTIQ
|
||||
bool "Lantiq Memory mapped GPIOs"
|
||||
depends on LANTIQ && SOC_XWAY
|
||||
--- a/drivers/gpio/Makefile
|
||||
+++ b/drivers/gpio/Makefile
|
||||
@@ -152,3 +152,4 @@ obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
|
||||
obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
|
||||
obj-$(CONFIG_GPIO_ZX) += gpio-zx.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
|
||||
+obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpio/gpio-mt7621.c
|
||||
@@ -0,0 +1,354 @@
|
||||
+/*
|
||||
+ * 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) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/irqdomain.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#define MTK_MAX_BANK 3
|
||||
+#define MTK_BANK_WIDTH 32
|
||||
+
|
||||
+enum mediatek_gpio_reg {
|
||||
+ GPIO_REG_CTRL = 0,
|
||||
+ GPIO_REG_POL,
|
||||
+ GPIO_REG_DATA,
|
||||
+ GPIO_REG_DSET,
|
||||
+ GPIO_REG_DCLR,
|
||||
+ GPIO_REG_REDGE,
|
||||
+ GPIO_REG_FEDGE,
|
||||
+ GPIO_REG_HLVL,
|
||||
+ GPIO_REG_LLVL,
|
||||
+ GPIO_REG_STAT,
|
||||
+ GPIO_REG_EDGE,
|
||||
+};
|
||||
+
|
||||
+static void __iomem *mediatek_gpio_membase;
|
||||
+static int mediatek_gpio_irq;
|
||||
+static struct irq_domain *mediatek_gpio_irq_domain;
|
||||
+static atomic_t irq_refcount = ATOMIC_INIT(0);
|
||||
+
|
||||
+struct mtk_gc {
|
||||
+ struct gpio_chip chip;
|
||||
+ spinlock_t lock;
|
||||
+ int bank;
|
||||
+ u32 rising;
|
||||
+ u32 falling;
|
||||
+} *gc_map[MTK_MAX_BANK];
|
||||
+
|
||||
+static inline struct mtk_gc
|
||||
+*to_mediatek_gpio(struct gpio_chip *chip)
|
||||
+{
|
||||
+ struct mtk_gc *mgc;
|
||||
+
|
||||
+ mgc = container_of(chip, struct mtk_gc, chip);
|
||||
+
|
||||
+ return mgc;
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mtk_gpio_w32(struct mtk_gc *rg, u8 reg, u32 val)
|
||||
+{
|
||||
+ iowrite32(val, mediatek_gpio_membase + (reg * 0x10) + (rg->bank * 0x4));
|
||||
+}
|
||||
+
|
||||
+static inline u32
|
||||
+mtk_gpio_r32(struct mtk_gc *rg, u8 reg)
|
||||
+{
|
||||
+ return ioread32(mediatek_gpio_membase + (reg * 0x10) + (rg->bank * 0x4));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+
|
||||
+ mtk_gpio_w32(rg, (value) ? GPIO_REG_DSET : GPIO_REG_DCLR, BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+
|
||||
+ return !!(mtk_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
|
||||
+ t &= ~BIT(offset);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_CTRL, t);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_direction_output(struct gpio_chip *chip,
|
||||
+ unsigned offset, int value)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
|
||||
+ t |= BIT(offset);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_CTRL, t);
|
||||
+ mediatek_gpio_set(chip, offset, value);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+ unsigned long flags;
|
||||
+ u32 t;
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ t = mtk_gpio_r32(rg, GPIO_REG_CTRL);
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+
|
||||
+ if (t & BIT(offset))
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
|
||||
+{
|
||||
+ struct mtk_gc *rg = to_mediatek_gpio(chip);
|
||||
+
|
||||
+ return irq_create_mapping(mediatek_gpio_irq_domain, pin + (rg->bank * MTK_BANK_WIDTH));
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_bank_probe(struct platform_device *pdev, struct device_node *bank)
|
||||
+{
|
||||
+ const __be32 *id = of_get_property(bank, "reg", NULL);
|
||||
+ struct mtk_gc *rg = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(struct mtk_gc), GFP_KERNEL);
|
||||
+
|
||||
+ if (!rg || !id || be32_to_cpu(*id) > MTK_MAX_BANK)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ gc_map[be32_to_cpu(*id)] = rg;
|
||||
+
|
||||
+ memset(rg, 0, sizeof(struct mtk_gc));
|
||||
+
|
||||
+ spin_lock_init(&rg->lock);
|
||||
+
|
||||
+ rg->chip.parent = &pdev->dev;
|
||||
+ rg->chip.label = dev_name(&pdev->dev);
|
||||
+ rg->chip.of_node = bank;
|
||||
+ rg->chip.base = MTK_BANK_WIDTH * be32_to_cpu(*id);
|
||||
+ rg->chip.ngpio = MTK_BANK_WIDTH;
|
||||
+ rg->chip.direction_input = mediatek_gpio_direction_input;
|
||||
+ rg->chip.direction_output = mediatek_gpio_direction_output;
|
||||
+ rg->chip.get_direction = mediatek_gpio_get_direction;
|
||||
+ rg->chip.get = mediatek_gpio_get;
|
||||
+ rg->chip.set = mediatek_gpio_set;
|
||||
+ if (mediatek_gpio_irq_domain)
|
||||
+ rg->chip.to_irq = mediatek_gpio_to_irq;
|
||||
+ rg->bank = be32_to_cpu(*id);
|
||||
+
|
||||
+ /* set polarity to low for all gpios */
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_POL, 0);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
|
||||
+
|
||||
+ return gpiochip_add(&rg->chip);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_irq_handler(struct irq_desc *desc)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MTK_MAX_BANK; i++) {
|
||||
+ struct mtk_gc *rg = gc_map[i];
|
||||
+ unsigned long pending;
|
||||
+ int bit;
|
||||
+
|
||||
+ if (!rg)
|
||||
+ continue;
|
||||
+
|
||||
+ pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
|
||||
+
|
||||
+ for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
|
||||
+ u32 map = irq_find_mapping(mediatek_gpio_irq_domain, (MTK_BANK_WIDTH * i) + bit);
|
||||
+
|
||||
+ generic_handle_irq(map);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ int pin = d->hwirq;
|
||||
+ int bank = pin / 32;
|
||||
+ struct mtk_gc *rg = gc_map[bank];
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ if (!rg)
|
||||
+ return;
|
||||
+
|
||||
+ rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
|
||||
+ fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_REDGE, rise | (BIT(d->hwirq) & rg->rising));
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(d->hwirq) & rg->falling));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mediatek_gpio_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ int pin = d->hwirq;
|
||||
+ int bank = pin / 32;
|
||||
+ struct mtk_gc *rg = gc_map[bank];
|
||||
+ unsigned long flags;
|
||||
+ u32 rise, fall;
|
||||
+
|
||||
+ if (!rg)
|
||||
+ return;
|
||||
+
|
||||
+ rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
|
||||
+ fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
|
||||
+
|
||||
+ spin_lock_irqsave(&rg->lock, flags);
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(d->hwirq));
|
||||
+ mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(d->hwirq));
|
||||
+ spin_unlock_irqrestore(&rg->lock, flags);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
|
||||
+{
|
||||
+ int pin = d->hwirq;
|
||||
+ int bank = pin / 32;
|
||||
+ struct mtk_gc *rg = gc_map[bank];
|
||||
+ u32 mask = BIT(d->hwirq);
|
||||
+
|
||||
+ if (!rg)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (type == IRQ_TYPE_PROBE) {
|
||||
+ if ((rg->rising | rg->falling) & mask)
|
||||
+ return 0;
|
||||
+
|
||||
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
|
||||
+ }
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_RISING)
|
||||
+ rg->rising |= mask;
|
||||
+ else
|
||||
+ rg->rising &= ~mask;
|
||||
+
|
||||
+ if (type & IRQ_TYPE_EDGE_FALLING)
|
||||
+ rg->falling |= mask;
|
||||
+ else
|
||||
+ rg->falling &= ~mask;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mediatek_gpio_irq_chip = {
|
||||
+ .name = "GPIO",
|
||||
+ .irq_unmask = mediatek_gpio_irq_unmask,
|
||||
+ .irq_mask = mediatek_gpio_irq_mask,
|
||||
+ .irq_mask_ack = mediatek_gpio_irq_mask,
|
||||
+ .irq_set_type = mediatek_gpio_irq_type,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
+{
|
||||
+ irq_set_chip_and_handler(irq, &mediatek_gpio_irq_chip, handle_level_irq);
|
||||
+ irq_set_handler_data(irq, d);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops irq_domain_ops = {
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+ .map = mediatek_gpio_gpio_map,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mediatek_gpio_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *bank, *np = pdev->dev.of_node;
|
||||
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+
|
||||
+ mediatek_gpio_membase = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(mediatek_gpio_membase))
|
||||
+ return PTR_ERR(mediatek_gpio_membase);
|
||||
+
|
||||
+ mediatek_gpio_irq = irq_of_parse_and_map(np, 0);
|
||||
+ if (mediatek_gpio_irq) {
|
||||
+ mediatek_gpio_irq_domain = irq_domain_add_linear(np,
|
||||
+ MTK_MAX_BANK * MTK_BANK_WIDTH,
|
||||
+ &irq_domain_ops, NULL);
|
||||
+ if (!mediatek_gpio_irq_domain)
|
||||
+ dev_err(&pdev->dev, "irq_domain_add_linear failed\n");
|
||||
+ }
|
||||
+
|
||||
+ for_each_child_of_node(np, bank)
|
||||
+ if (of_device_is_compatible(bank, "mtk,mt7621-gpio-bank"))
|
||||
+ mediatek_gpio_bank_probe(pdev, bank);
|
||||
+
|
||||
+ if (mediatek_gpio_irq_domain)
|
||||
+ irq_set_chained_handler(mediatek_gpio_irq, mediatek_gpio_irq_handler);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mediatek_gpio_match[] = {
|
||||
+ { .compatible = "mtk,mt7621-gpio" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
|
||||
+
|
||||
+static struct platform_driver mediatek_gpio_driver = {
|
||||
+ .probe = mediatek_gpio_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mt7621_gpio",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = mediatek_gpio_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init
|
||||
+mediatek_gpio_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mediatek_gpio_driver);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(mediatek_gpio_init);
|
@ -0,0 +1,246 @@
|
||||
From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 19 Sep 2013 01:50:59 +0200
|
||||
Subject: [PATCH 31/53] uvc: add iPassion iP2970 support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/media/usb/uvc/uvc_driver.c | 12 +++
|
||||
drivers/media/usb/uvc/uvc_status.c | 2 +
|
||||
drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++
|
||||
drivers/media/usb/uvc/uvcvideo.h | 5 +-
|
||||
4 files changed, 165 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/media/usb/uvc/uvc_driver.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_driver.c
|
||||
@@ -2734,6 +2734,18 @@ static const struct usb_device_id uvc_id
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 0,
|
||||
.driver_info = UVC_QUIRK_FORCE_Y8 },
|
||||
+ /* iPassion iP2970 */
|
||||
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
|
||||
+ | USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
+ .idVendor = 0x1B3B,
|
||||
+ .idProduct = 0x2970,
|
||||
+ .bInterfaceClass = USB_CLASS_VIDEO,
|
||||
+ .bInterfaceSubClass = 1,
|
||||
+ .bInterfaceProtocol = 0,
|
||||
+ .driver_info = UVC_QUIRK_PROBE_MINMAX
|
||||
+ | UVC_QUIRK_STREAM_NO_FID
|
||||
+ | UVC_QUIRK_MOTION
|
||||
+ | UVC_QUIRK_SINGLE_ISO },
|
||||
/* Generic USB Video Class */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
|
||||
--- a/drivers/media/usb/uvc/uvc_status.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_status.c
|
||||
@@ -139,6 +139,7 @@ static void uvc_status_complete(struct u
|
||||
switch (dev->status[0] & 0x0f) {
|
||||
case UVC_STATUS_TYPE_CONTROL:
|
||||
uvc_event_control(dev, dev->status, len);
|
||||
+ dev->motion = 1;
|
||||
break;
|
||||
|
||||
case UVC_STATUS_TYPE_STREAMING:
|
||||
@@ -182,6 +183,7 @@ int uvc_status_init(struct uvc_device *d
|
||||
}
|
||||
|
||||
pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
|
||||
+ dev->motion = 0;
|
||||
|
||||
/* For high-speed interrupt endpoints, the bInterval value is used as
|
||||
* an exponent of two. Some developers forgot about it.
|
||||
--- a/drivers/media/usb/uvc/uvc_video.c
|
||||
+++ b/drivers/media/usb/uvc/uvc_video.c
|
||||
@@ -21,6 +21,11 @@
|
||||
#include <linux/wait.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/unaligned.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/kobject.h>
|
||||
+#include <linux/netlink.h>
|
||||
+#include <linux/kobject.h>
|
||||
+#include <linux/workqueue.h>
|
||||
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
@@ -1081,9 +1086,149 @@ static void uvc_video_decode_data(struct
|
||||
}
|
||||
}
|
||||
|
||||
+struct bh_priv {
|
||||
+ unsigned long seen;
|
||||
+};
|
||||
+
|
||||
+struct bh_event {
|
||||
+ const char *name;
|
||||
+ struct sk_buff *skb;
|
||||
+ struct work_struct work;
|
||||
+};
|
||||
+
|
||||
+#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
|
||||
+#define BH_DBG(fmt, args...) do {} while (0)
|
||||
+#define BH_SKB_SIZE 2048
|
||||
+
|
||||
+extern u64 uevent_next_seqnum(void);
|
||||
+static int seen = 0;
|
||||
+
|
||||
+static int bh_event_add_var(struct bh_event *event, int argv,
|
||||
+ const char *format, ...)
|
||||
+{
|
||||
+ static char buf[128];
|
||||
+ char *s;
|
||||
+ va_list args;
|
||||
+ int len;
|
||||
+
|
||||
+ if (argv)
|
||||
+ return 0;
|
||||
+
|
||||
+ va_start(args, format);
|
||||
+ len = vsnprintf(buf, sizeof(buf), format, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ if (len >= sizeof(buf)) {
|
||||
+ BH_ERR("buffer size too small\n");
|
||||
+ WARN_ON(1);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ s = skb_put(event->skb, len + 1);
|
||||
+ strcpy(s, buf);
|
||||
+
|
||||
+ BH_DBG("added variable '%s'\n", s);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int motion_hotplug_fill_event(struct bh_event *event)
|
||||
+{
|
||||
+ int s = jiffies;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!seen)
|
||||
+ seen = jiffies;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "HOME=%s", "/");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "PATH=%s",
|
||||
+ "/sbin:/bin:/usr/sbin:/usr/bin");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "ACTION=motion");
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ seen = s;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void motion_hotplug_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct bh_event *event = container_of(work, struct bh_event, work);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
|
||||
+ if (!event->skb)
|
||||
+ goto out_free_event;
|
||||
+
|
||||
+ ret = bh_event_add_var(event, 0, "%s@", "add");
|
||||
+ if (ret)
|
||||
+ goto out_free_skb;
|
||||
+
|
||||
+ ret = motion_hotplug_fill_event(event);
|
||||
+ if (ret)
|
||||
+ goto out_free_skb;
|
||||
+
|
||||
+ NETLINK_CB(event->skb).dst_group = 1;
|
||||
+ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
|
||||
+
|
||||
+out_free_skb:
|
||||
+ if (ret) {
|
||||
+ BH_ERR("work error %d\n", ret);
|
||||
+ kfree_skb(event->skb);
|
||||
+ }
|
||||
+out_free_event:
|
||||
+ kfree(event);
|
||||
+}
|
||||
+
|
||||
+static int motion_hotplug_create_event(void)
|
||||
+{
|
||||
+ struct bh_event *event;
|
||||
+
|
||||
+ event = kzalloc(sizeof(*event), GFP_KERNEL);
|
||||
+ if (!event)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ event->name = "motion";
|
||||
+
|
||||
+ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
|
||||
+ schedule_work(&event->work);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define MOTION_FLAG_OFFSET 4
|
||||
static void uvc_video_decode_end(struct uvc_streaming *stream,
|
||||
struct uvc_buffer *buf, const __u8 *data, int len)
|
||||
{
|
||||
+ if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
|
||||
+ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
|
||||
+ u8 *mem;
|
||||
+ buf->state = UVC_BUF_STATE_READY;
|
||||
+ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
|
||||
+ if ( stream->dev->motion ) {
|
||||
+ stream->dev->motion = 0;
|
||||
+ motion_hotplug_create_event();
|
||||
+ } else {
|
||||
+ *mem &= 0x7f;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Mark the buffer as done if the EOF marker is set. */
|
||||
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
|
||||
uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
|
||||
@@ -1498,6 +1643,8 @@ static int uvc_init_video_isoc(struct uv
|
||||
if (npackets == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
+ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
|
||||
+ npackets = 1;
|
||||
size = npackets * psize;
|
||||
|
||||
for (i = 0; i < UVC_URBS; ++i) {
|
||||
--- a/drivers/media/usb/uvc/uvcvideo.h
|
||||
+++ b/drivers/media/usb/uvc/uvcvideo.h
|
||||
@@ -186,7 +186,9 @@
|
||||
#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200
|
||||
#define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400
|
||||
#define UVC_QUIRK_FORCE_Y8 0x00000800
|
||||
-
|
||||
+#define UVC_QUIRK_MOTION 0x00001000
|
||||
+#define UVC_QUIRK_SINGLE_ISO 0x00002000
|
||||
+
|
||||
/* Format flags */
|
||||
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
|
||||
#define UVC_FMT_FLAG_STREAM 0x00000002
|
||||
@@ -584,6 +586,7 @@ struct uvc_device {
|
||||
__u8 *status;
|
||||
struct input_dev *input;
|
||||
char input_phys[64];
|
||||
+ int motion;
|
||||
};
|
||||
|
||||
enum uvc_handle_state {
|
@ -0,0 +1,29 @@
|
||||
From a758e0870c6d1e4b0272f6e7f9efa9face5534bb Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:49:07 +0100
|
||||
Subject: [PATCH 32/53] USB: dwc2: add device_reset()
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/usb/dwc2/hcd.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/usb/dwc2/hcd.c
|
||||
+++ b/drivers/usb/dwc2/hcd.c
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
+#include <linux/reset.h>
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
#include <linux/usb/ch11.h>
|
||||
@@ -5072,6 +5073,8 @@ int dwc2_hcd_init(struct dwc2_hsotg *hso
|
||||
|
||||
retval = -ENOMEM;
|
||||
|
||||
+ device_reset(hsotg->dev);
|
||||
+
|
||||
hcfg = dwc2_readl(hsotg->regs + HCFG);
|
||||
dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg);
|
||||
|
@ -0,0 +1,59 @@
|
||||
From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:38:50 +0100
|
||||
Subject: [PATCH 34/53] NET: multi phy support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/net/phy/phy.c | 9 ++++++---
|
||||
include/linux/phy.h | 1 +
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -980,7 +980,10 @@ void phy_state_machine(struct work_struc
|
||||
/* If the link is down, give up on negotiation for now */
|
||||
if (!phydev->link) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1067,7 +1070,10 @@ void phy_state_machine(struct work_struc
|
||||
phy_link_up(phydev);
|
||||
} else {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
}
|
||||
|
||||
if (phy_interrupt_is_valid(phydev))
|
||||
@@ -1077,7 +1083,10 @@ void phy_state_machine(struct work_struc
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
- phy_link_down(phydev, true);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ phy_link_down(phydev, true);
|
||||
+ else
|
||||
+ phy_link_down(phydev, false);
|
||||
do_suspend = true;
|
||||
}
|
||||
break;
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -412,6 +412,7 @@ struct phy_device {
|
||||
bool suspended;
|
||||
bool sysfs_links;
|
||||
bool loopback_enabled;
|
||||
+ bool no_auto_carrier_off;
|
||||
|
||||
enum phy_state state;
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 8e72a3a1be8f6328bd7ef491332ba541547b6086 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 15 Jul 2013 00:38:51 +0200
|
||||
Subject: [PATCH 36/53] mtd: fix cfi cmdset 0002 erase status check
|
||||
|
||||
---
|
||||
drivers/mtd/chips/cfi_cmdset_0002.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -2293,7 +2293,7 @@ static int __xipram do_erase_chip(struct
|
||||
chip->erase_suspended = 0;
|
||||
}
|
||||
|
||||
- if (chip_ready(map, adr))
|
||||
+ if (chip_good(map, adr, map_word_ff(map)))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, timeo)) {
|
||||
@@ -2382,7 +2382,7 @@ static int __xipram do_erase_oneblock(st
|
||||
chip->erase_suspended = 0;
|
||||
}
|
||||
|
||||
- if (chip_ready(map, adr)) {
|
||||
+ if (chip_good(map, adr, map_word_ff(map))) {
|
||||
xip_enable(map, chip, adr);
|
||||
break;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 15 Jul 2013 00:39:21 +0200
|
||||
Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write
|
||||
|
||||
---
|
||||
drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <linux/mtd/xip.h>
|
||||
|
||||
#define AMD_BOOTLOC_BUG
|
||||
-#define FORCE_WORD_WRITE 0
|
||||
+#define FORCE_WORD_WRITE 1
|
||||
|
||||
#define MAX_WORD_RETRIES 3
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
|
||||
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
|
||||
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
+#if !FORCE_WORD_WRITE
|
||||
static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
|
||||
+#endif
|
||||
static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
|
||||
static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
|
||||
static void cfi_amdstd_sync (struct mtd_info *);
|
||||
@@ -202,6 +204,7 @@ static void fixup_amd_bootblock(struct m
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if !FORCE_WORD_WRITE
|
||||
static void fixup_use_write_buffers(struct mtd_info *mtd)
|
||||
{
|
||||
struct map_info *map = mtd->priv;
|
||||
@@ -211,6 +214,7 @@ static void fixup_use_write_buffers(stru
|
||||
mtd->_write = cfi_amdstd_write_buffers;
|
||||
}
|
||||
}
|
||||
+#endif /* !FORCE_WORD_WRITE */
|
||||
|
||||
/* Atmel chips don't use the same PRI format as AMD chips */
|
||||
static void fixup_convert_atmel_pri(struct mtd_info *mtd)
|
||||
@@ -1791,6 +1795,7 @@ static int cfi_amdstd_write_words(struct
|
||||
/*
|
||||
* FIXME: interleaved mode not tested, and probably not supported!
|
||||
*/
|
||||
+#if !FORCE_WORD_WRITE
|
||||
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
|
||||
unsigned long adr, const u_char *buf,
|
||||
int len)
|
||||
@@ -1919,7 +1924,6 @@ static int __xipram do_write_buffer(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
@@ -1994,6 +1998,7 @@ static int cfi_amdstd_write_buffers(stru
|
||||
|
||||
return 0;
|
||||
}
|
||||
+#endif /* !FORCE_WORD_WRITE */
|
||||
|
||||
/*
|
||||
* Wait for the flash chip to become ready to write data
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user