From 15d60da9bcdf687809d47626f435cfc4bfccb288 Mon Sep 17 00:00:00 2001 From: Michael Qu Date: Tue, 3 Sep 2019 14:05:11 +0800 Subject: [PATCH 1/4] support dnspod api by token --- package/lean/luci-app-dnspod/files/dnspod.sh | 262 ++++++++---------- .../files/root/etc/config/dnspod | 4 +- .../files/root/etc/init.d/dnspod | 16 +- .../usr/lib/lua/luci/model/cbi/dnspod.lua | 13 +- 4 files changed, 130 insertions(+), 165 deletions(-) diff --git a/package/lean/luci-app-dnspod/files/dnspod.sh b/package/lean/luci-app-dnspod/files/dnspod.sh index 55366f4b4a..77295f52d0 100755 --- a/package/lean/luci-app-dnspod/files/dnspod.sh +++ b/package/lean/luci-app-dnspod/files/dnspod.sh @@ -1,193 +1,159 @@ -#!/bin/sh -#written by benson huang -#admin@zhetenger.com -#http://www.terryche.me/openwrt-dnspod-ddns.html +#!/bin/bash +#written by Michael Qu +#greennyreborn@gmail.com -#dnspod帐号名 -email=`uci get dnspod.base_arg.login_email` - -#dnspod密码 -password=`uci get dnspod.base_arg.login_password 2>/dev/null` +#dnspod api token +token=`uci get dnspod.base_arg.login_token` #域名 -domainname=`uci get dnspod.base_arg.main_domain 2>/dev/null` +domain=`uci get dnspod.base_arg.main_domain 2>/dev/null` -#需要更新的子域名列表,多个的话,以空格分割。 -#例如: -# sub_domains='www home' -sub_domains=`uci get dnspod.base_arg.sub_domain 2>/dev/null` + +#需要更新的子域名,只允许一个 +#由于*linux会被脚本解析为当前目录下的所有文件,所以请填写\* +# sub_domain='\*' +sub_domain=`uci get dnspod.base_arg.sub_domain 2>/dev/null` +if [ $sub_domain = "\*" ];then + sub_domain="*" +fi #check for changed ip every 300 seconds wait=300 +wait_second=`uci get dnspod.base_arg.wait_second 2>/dev/null` +if [[ $wait_second =~ ^[1-9][0-9]*$ ]]; then + wait=$wait_second +fi -#检查是否安装curl +#检查curl是否安装 curl_status=`which curl 2>/dev/null` [ -n "$curl_status" ] || { echo "curl is not installed";exit 3; } os=$(uname -a | egrep -io 'openwrt' | tr [A-Z] [a-z]) API_url="https://dnsapi.cn" +LOG_FILE="/tmp/dnspod.log" +MAX_LOG_SIZE=1*1024*1024 +PROGRAM=$(basename $0) + format='json' lang='en' record_type='A' -offset="2" -length="" -common_options="--data-urlencode \"login_email=${email}\"\ - --data-urlencode \"login_password=${password}\"\ - --data-urlencode \"format=${format}\"\ - --data-urlencode \"lang=${lang}\"" -PROGRAM=$(basename $0) +common_options="login_token=$token&format=${format}&lang=${lang}" + is_svc=0 +last_modified_ip= + +getFileSize() { + local file=$1 + wc -c $file +} + +clearLog() { + local file_size=$(getFileSize $LOG_FILE) + if [ $file_size -gt $MAX_LOG_SIZE ]; then + echo "" > $LOG_FILE + fi + +} printMsg() { - local msg="$1" - if [ $is_svc -eq 1 ];then - logger -t ${PROGRAM} "${msg}" - else - echo $msg - fi + local time=$(date "+%Y-%m-%d %H:%M:%S") + local msg="$1" + if [ $is_svc -eq 1 ];then + echo "$time: $msg" >> $LOG_FILE + # logger -t ${PROGRAM} "${msg}" + else + echo "$time: $msg" + fi } getIp() { -# curl -s http://checkip.dyndns.com | sed -n 's/.*: \([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/p' - curl -s http://members.3322.org/dyndns/getip -} - -getJsonValue(){ - local params="$1" - echo $json_data | sed 's/\\\\\//\//g' | sed 's/[{}]//g;s/\(\[\|\]\)//g' |\ - awk -F ',' '{ for (i=1;i<=NF;i++) { print $i }}' |\ - sed 's/":/\|/g;s/"//g' |\ - awk -v k="$params" -F'|' '{ if ($(NF - 1) == k ) print $NF }' +# curl -s http://checkip.dyndns.com | sed -n 's/.*: \([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/p' + curl -s whatismyip.akamai.com } execAPI() { - local action="$1" - local extra_options="$2" - eval "curl -k -A 'xddns' ${API_url}/${action} ${common_options} ${extra_options}" + local action="$1" + local extra_options="$2" + + eval "curl -k -X POST \"${API_url}/${action}\" -d \"${common_options}&${extra_options}\"" } -getDomainId() { - local extra_options="--data-urlencode \"domain=${domainname}\"" - json_data=$(execAPI "Domain.info" "${extra_options}") - getJsonValue id -} - -getRecordId() { - local extra_options - for sub_domain in $sub_domains;do - extra_options="--data-urlencode \"record_type=${record_type}\"\ - --data-urlencode \"domain_id=${domain_id}\"\ - --data-urlencode \"sub_domain=${sub_domain}\"\ - --data-urlencode \"offset=${offset}\"\ - --data-urlencode \"length=${length}\"" - - json_data=$(execAPI "Record.List" "${extra_options}") - - #check if record type is NS - IS_NS=$(getJsonValue type | grep -o 'NS' | head -n1) - - #if there are multi @ subdomains, get the first non-NS record id only - if [ "$IS_NS" = "NS" ];then - numofline=$(getJsonValue id | sed '/^[0-9]\{7\}$/d' | wc -l) - [ $numofline -eq 3 ] && tmp_result_id="$(getJsonValue id | sed '/^[0-9]\{7\}$/d' | head -n1 )" || continue - else - tmp_result_id="$(getJsonValue id | sed '/^[0-9]\{7\}$/d')" - fi - #if result_id is not empty or unset, append a space to split record id - result_id="${result_id:+${result_id} }${tmp_result_id}" - done - echo $result_id - exit +getRecordList() { + local extra_options="domain=$domain" + echo $(execAPI "Record.List" "$extra_options") + exit } updateRecord() { - local record_id_list - local extra_options - local tmp=${sub_domains} - local tmp_sub_domains - printMsg 'Start update records' - record_id_list=$(getRecordId) - printMsg "Records IDs: ${record_id_list}" - for record_id in $record_id_list;do - tmp_sub_domains=$(echo $tmp | awk '{ print $1 }') - tmp=${tmp#* } - extra_options="--data-urlencode \"domain_id=${domain_id}\"\ - --data-urlencode \"record_id=${record_id}\"\ - --data-urlencode \"sub_domain=${tmp_sub_domains}\"\ - --data-urlencode \"record_type=${record_type}\"\ - --data-urlencode \"record_line=默认\"\ - --data-urlencode \"value=${pub_ip_addr}\"\ - --data-urlencode \"mx=1\"" - json_data=$(execAPI "Record.Modify" "${extra_options}") - printMsg "Update [${tmp_sub_domains}.${domainname}] ${record_type} record to [${pub_ip_addr}] : $(getJsonValue message)" - done - printMsg 'Update records finish' + local ip=$1 + local record_list=`getRecordList` + local old_ip=`jsonfilter -s "$record_list" -e "@.records[@.name='$sub_domain'].value"` + local id=`jsonfilter -s "$record_list" -e "@.records[@.name='$sub_domain'].id"` + printMsg "Change record: $sub_domain.$domain from $old_ip to $ip" + + local extra_options="domain=$domain&record_id=$id&value=$ip&record_type=A&record_line_id=0&sub_domain=$sub_domain" + local response=$(execAPI "Record.Modify" "$extra_options") + + local code=`jsonfilter -s "$response" -e "@.status.code"` + if [ "$code" == "1" ]; then + last_modified_ip=$ip + fi + local message=`jsonfilter -s "$response" -e "@.status.message"` + printMsg "response: $message" + } checkip() { - local oldip=$pub_ip_addr - pub_ip_addr=$(getIp) - printMsg "old ip: [$oldip], new ip: [$pub_ip_addr]" - if [ "$pub_ip_addr" != "$oldip" ];then - return 8 - else - return 3 - fi -} - -updateTunnelBroker() { - printMsg "Start Update Tunnel Broker" - printMsg "User Name: ***, Tunnel ID: ***" - result=$(curl -s --insecure https://ipv4.tunnelbroker.net/nic/update --data-urlencode "username=***" --data-urlencode "password=***" --data-urlencode "hostname=***") - printMsg "Update Tunnel Broker: ${result}" - printMsg "Update Tunnel Broker finish" + local wan_ip=$1 + printMsg "old ip: [$last_modified_ip], new ip: [$wan_ip]" + if [ "$wan_ip" != "$last_modified_ip" ];then + return 8 + else + return 3 + fi } execSvc() { - local ip - #check that whether the network is ok - while [ 1 ];do - ip=$(getIp) - if [ -n "$ip" ];then - printMsg "WAN IP: ${ip}" - break; - else - printMsg "Can't get wan ip" - sleep 30 - fi - done + local ip + #check that whether the network is ok + while [ 1 ];do + ip=$(getIp) + if [ -n "$ip" ];then + printMsg "WAN IP: ${ip}" + break; + else + printMsg "Can't get wan ip" + sleep 30 + fi + done - domain_id=`getDomainId $domainname` - printMsg "domain_id: ${domain_id}" - while [ 1 ];do - checkip - if [ $? -eq 8 ];then - updateRecord - #updateTunnelBroker - fi - sleep $wait - done + while [ 1 ];do + clearLog + ip=$(getIp) + checkip $ip + if [ $? -eq 8 ];then + updateRecord $ip + #updateTunnelBroker + fi + sleep $wait + done } execUpdate() { - domain_id=`getDomainId $domainname` - pub_ip_addr=$(getIp) - updateRecord + local ip=`getIp` + updateRecord $ip } case $1 in - --svc) - is_svc=1; - printMsg 'Start in Service mode'; - printMsg "domain: ${domainname}, sub_domains: ${sub_domains}"; - execSvc;; - --ipv6) - is_svc=0; - printMsg "Start update HE Tunnel Broker"; - updateTunnelBroker;; - *) - is_svc=0; - printMsg "Start update record, domain: ${domainname}, sub_domains: ${sub_domains}"; - execUpdate;; + --svc) + is_svc=1; + clearLog; + printMsg "Start in Service mode, check in every $wait seconds"; + printMsg "domain: ${domain}, sub_domain: ${sub_domain}"; + execSvc;; + *) + is_svc=0; + printMsg "Start update record, domain: ${domain}, sub_domain: ${sub_domain}"; + execUpdate;; esac diff --git a/package/lean/luci-app-dnspod/files/root/etc/config/dnspod b/package/lean/luci-app-dnspod/files/root/etc/config/dnspod index 6cebd6d7a1..4ec49531f0 100644 --- a/package/lean/luci-app-dnspod/files/root/etc/config/dnspod +++ b/package/lean/luci-app-dnspod/files/root/etc/config/dnspod @@ -1,6 +1,6 @@ config base_arg "base_arg" - option login_email '' - option login_password '' option main_domain '' option sub_domain '' + option login_token '' + option wait_second '' diff --git a/package/lean/luci-app-dnspod/files/root/etc/init.d/dnspod b/package/lean/luci-app-dnspod/files/root/etc/init.d/dnspod index 70c2a12535..036fa308ed 100755 --- a/package/lean/luci-app-dnspod/files/root/etc/init.d/dnspod +++ b/package/lean/luci-app-dnspod/files/root/etc/init.d/dnspod @@ -1,18 +1,18 @@ #!/bin/sh /etc/rc.common START=80 -run_reboot() -{ - killall dnspod.sh - /sbin/dnspod.sh --svc -} - start() { - /sbin/dnspod.sh --svc + /usr/sbin/dnspod.sh --svc & } stop() { - killall dnspod.sh + ps | grep dnspod.sh | grep -v 'grep' | awk '{print $1}' | xargs kill +} + +run_reboot() +{ + stop + start } diff --git a/package/lean/luci-app-dnspod/files/root/usr/lib/lua/luci/model/cbi/dnspod.lua b/package/lean/luci-app-dnspod/files/root/usr/lib/lua/luci/model/cbi/dnspod.lua index a366050379..1f50380299 100644 --- a/package/lean/luci-app-dnspod/files/root/usr/lib/lua/luci/model/cbi/dnspod.lua +++ b/package/lean/luci-app-dnspod/files/root/usr/lib/lua/luci/model/cbi/dnspod.lua @@ -7,7 +7,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 ]]-- require("luci.sys") @@ -18,15 +18,14 @@ s = m:section(TypedSection, "base_arg", "") s.addremove = false s.anonymous = true -email = s:option(Value, "login_email", translate("登录邮箱"),"登录DNSPOD的用户名") -pass = s:option(Value, "login_password", translate("登录密码"),"登录DNSPOD的密码") -pass.password=true -main = s:option(Value, "main_domain", translate("主域名"),"想要解析的主域名,例如:baidu.com") -sub = s:option(Value, "sub_domain", translate("子域名"),"想要解析的子域名,多个以空格分开,例如:test hehe") +email = s:option(Value, "login_token", translate("DNSPOD Token"), "格式: ID,Token") +main = s:option(Value, "main_domain", translate("主域名"), "想要解析的主域名,例如:baidu.com") +sub = s:option(Value, "sub_domain", translate("子域名"), "想要解析的子域名,只允许填写一个。如果想解析*子域名,请填写 \\*") +wait = s:option(Value, "wait_second", translate("更新周期(s)"), "请填写数字,默认为300s") local apply = luci.http.formvalue("cbi.apply") if apply then - io.popen("/etc/init.d/dnspod restart &") + io.popen("/etc/init.d/dnspod restart &") end return m From f051b8d24785b4a6daf37d82c6dddf0900eec3b0 Mon Sep 17 00:00:00 2001 From: ope087 <33145975+ope087@users.noreply.github.com> Date: Tue, 3 Sep 2019 14:05:41 +0800 Subject: [PATCH 2/4] add icu to depends (#1588) fix missing libicu* files when packing qt5-core. --- package/lean/qt5/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/lean/qt5/Makefile b/package/lean/qt5/Makefile index 447f2d7055..bb6868fab9 100644 --- a/package/lean/qt5/Makefile +++ b/package/lean/qt5/Makefile @@ -36,7 +36,7 @@ define Package/qt5/Default SUBMENU:=Qt5 TITLE:=qt5 URL:=http://qt-project.org - DEPENDS:=+libatomic +libstdcpp +libopenssl +zlib @!LINUX_2_6 + DEPENDS:=+libatomic +libstdcpp +libopenssl +zlib +icu @!LINUX_2_6 endef define Package/qt5-core From 6219af90ab9a6a6ae362b98d3209d960d2a215bc Mon Sep 17 00:00:00 2001 From: LEAN-ESX Date: Thu, 5 Sep 2019 21:28:35 -0700 Subject: [PATCH 3/4] kernel: bump to 4.14.141, 4.19.69 --- include/kernel-version.mk | 8 +- ...2515-Use-DT-supplied-interrupt-flags.patch | 2 +- ...-t-prevent-IRQ-usage-of-output-GPIOs.patch | 4 +- ...ce-quirks-for-Freeway-Airmouse-T3-an.patch | 4 +- ...tree-gpio-hogs-on-dual-role-gpio-pin.patch | 4 +- .../base-files/lib/preinit/79_move_config | 4 +- .../base-files/lib/upgrade/platform.sh | 2 +- .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 111 ++-- .../drivers/net/phy/mtk/mt753x/Kconfig | 1 - .../drivers/net/phy/mtk/mt753x/Makefile | 4 +- .../drivers/net/phy/mtk/mt753x/mt7530.c | 139 +++-- .../drivers/net/phy/mtk/mt753x/mt7530.h | 5 +- .../drivers/net/phy/mtk/mt753x/mt7531.c | 87 ++- .../drivers/net/phy/mtk/mt753x/mt7531.h | 5 +- .../drivers/net/phy/mtk/mt753x/mt753x.h | 39 +- .../net/phy/mtk/mt753x/mt753x_common.c | 12 +- .../drivers/net/phy/mtk/mt753x/mt753x_mdio.c | 182 +----- .../drivers/net/phy/mtk/mt753x/mt753x_nl.c | 24 +- .../drivers/net/phy/mtk/mt753x/mt753x_nl.h | 8 +- .../drivers/net/phy/mtk/mt753x/mt753x_regs.h | 8 +- .../net/phy/mtk/mt753x/mt753x_swconfig.c | 195 +------ .../net/phy/mtk/mt753x/mt753x_swconfig.h | 22 +- .../drivers/net/phy/mtk/mt753x/mt753x_vlan.c | 183 ++++++ .../drivers/net/phy/mtk/mt753x/mt753x_vlan.h | 40 ++ .../patches-4.14/0052-net-phy-add-FC.patch | 2 +- ...-mt7531-gsw-internal_phy_calibration.patch | 304 +++++++--- .../0101-pci-mediatek-backport-fix-pcie.patch | 534 ++++++++++++++++++ 27 files changed, 1276 insertions(+), 657 deletions(-) create mode 100644 target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.c create mode 100644 target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.h create mode 100644 target/linux/mediatek/patches-4.19/0101-pci-mediatek-backport-fix-pcie.patch diff --git a/include/kernel-version.mk b/include/kernel-version.mk index ba7aa7b782..67420909a0 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -7,12 +7,12 @@ ifdef CONFIG_TESTING_KERNEL endif LINUX_VERSION-4.9 = .190 -LINUX_VERSION-4.14 = .140 -LINUX_VERSION-4.19 = .68 +LINUX_VERSION-4.14 = .141 +LINUX_VERSION-4.19 = .69 LINUX_KERNEL_HASH-4.9.190 = fe8a1ca080a462de6832762ba8b71410b828f0e52c1e11d3c46d83e9ac1e0a16 -LINUX_KERNEL_HASH-4.14.140 = 795eed2515715ef29edd24f7a70912040cc206ec9a049c370cb305515f3fbdf2 -LINUX_KERNEL_HASH-4.19.68 = 91875940518c0a8cecfa02ffcf371e4d8266b80971a95103e89a86b8a326a02b +LINUX_KERNEL_HASH-4.14.141 = 0bb9f0812326ec4554de1bea02628840e03b6664b5abfd9d8510049e43203a17 +LINUX_KERNEL_HASH-4.19.69 = c091760b520a4e4a4c7034a8329cc2689a0ea3f81a377b694ed196d623e2d987 remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) diff --git a/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch b/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch index 685168f44b..05f0b090c1 100644 --- a/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch +++ b/target/linux/brcm2708/patches-4.19/950-0104-mcp2515-Use-DT-supplied-interrupt-flags.patch @@ -24,7 +24,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c -@@ -950,6 +950,9 @@ static int mcp251x_open(struct net_devic +@@ -939,6 +939,9 @@ static int mcp251x_open(struct net_devic priv->tx_skb = NULL; priv->tx_len = 0; diff --git a/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch b/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch index 5de8546834..5ceb007b19 100644 --- a/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch +++ b/target/linux/brcm2708/patches-4.19/950-0129-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch @@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell /* Device and char device-related information */ static DEFINE_IDA(gpio_ida); static dev_t gpio_devt; -@@ -2626,7 +2628,7 @@ int gpiod_direction_output(struct gpio_d +@@ -2628,7 +2630,7 @@ int gpiod_direction_output(struct gpio_d value = !!value; /* GPIOs used for IRQs shall not be set as output */ @@ -35,7 +35,7 @@ Signed-off-by: Phil Elwell gpiod_err(desc, "%s: tried to set a GPIO tied to an IRQ as output\n", __func__); -@@ -3314,7 +3316,7 @@ int gpiochip_lock_as_irq(struct gpio_chi +@@ -3316,7 +3318,7 @@ int gpiochip_lock_as_irq(struct gpio_chi } } diff --git a/target/linux/brcm2708/patches-4.19/950-0731-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/brcm2708/patches-4.19/950-0731-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch index de6d23c3cb..41ad8b4db8 100644 --- a/target/linux/brcm2708/patches-4.19/950-0731-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch +++ b/target/linux/brcm2708/patches-4.19/950-0731-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch @@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 -@@ -1187,6 +1190,9 @@ +@@ -1188,6 +1191,9 @@ #define USB_VENDOR_ID_XAT 0x2505 #define USB_DEVICE_ID_XAT_CSR 0x0220 @@ -53,7 +53,7 @@ Signed-off-by: Jonathan Bell { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL }, -@@ -172,6 +173,7 @@ static const struct hid_device_id hid_qu +@@ -173,6 +174,7 @@ static const struct hid_device_id hid_qu { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, diff --git a/target/linux/brcm63xx/patches-4.14/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch b/target/linux/brcm63xx/patches-4.14/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch index 7f766aad58..0ed8e3b786 100644 --- a/target/linux/brcm63xx/patches-4.14/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch +++ b/target/linux/brcm63xx/patches-4.14/143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch @@ -89,7 +89,7 @@ Signed-off-by: Jonas Gorski --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c -@@ -1940,7 +1940,8 @@ int gpiochip_add_pingroup_range(struct g +@@ -1942,7 +1942,8 @@ int gpiochip_add_pingroup_range(struct g list_add_tail(&pin_range->node, &gdev->pin_ranges); @@ -99,7 +99,7 @@ Signed-off-by: Jonas Gorski } EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range); -@@ -1992,7 +1993,7 @@ int gpiochip_add_pin_range(struct gpio_c +@@ -1994,7 +1995,7 @@ int gpiochip_add_pin_range(struct gpio_c list_add_tail(&pin_range->node, &gdev->pin_ranges); diff --git a/target/linux/mediatek/base-files/lib/preinit/79_move_config b/target/linux/mediatek/base-files/lib/preinit/79_move_config index e8e62883dc..617336583e 100644 --- a/target/linux/mediatek/base-files/lib/preinit/79_move_config +++ b/target/linux/mediatek/base-files/lib/preinit/79_move_config @@ -1,6 +1,8 @@ #!/bin/sh # Copyright (C) 2015 OpenWrt.org +. /lib/upgrade/common.sh + RECOVERY_PART=/dev/mmcblk0p1 move_config() { @@ -11,7 +13,7 @@ move_config() { insmod vfat mkdir -p /recovery mount -o rw,noatime $RECOVERY_PART /recovery - [ -f /recovery/sysupgrade.tgz ] && mv -f /recovery/sysupgrade.tgz / + [ -f "/recovery/$BACKUP_FILE" ] && mv -f "/recovery/$BACKUP_FILE" / umount /recovery fi } diff --git a/target/linux/mediatek/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/base-files/lib/upgrade/platform.sh index d812a48720..9c99ee1c18 100755 --- a/target/linux/mediatek/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/base-files/lib/upgrade/platform.sh @@ -54,7 +54,7 @@ platform_check_image() { platform_copy_config_emmc() { mkdir -p /recovery mount -o rw,noatime /dev/mmcblk0p1 /recovery - cp -af "$CONF_TAR" /recovery/ + cp -af "$UPGRADE_BACKUP" "/recovery/$BACKUP_FILE" sync umount /recovery } diff --git a/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts index 62a876c02f..557745ed90 100644 --- a/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++ b/target/linux/mediatek/files-4.19/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) /* * Copyright (c) 2018 MediaTek Inc. * Author: Ryder Lee - * - * SPDX-License-Identifier: (GPL-2.0 OR MIT) */ /dts-v1/; @@ -16,13 +15,8 @@ model = "Bananapi BPI-R64"; compatible = "bananapi,bpi-r64", "mediatek,mt7622"; - aliases { - serial0 = &uart0; - }; - chosen { - stdout-path = "serial0:115200n8"; - bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; + bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; }; cpus { @@ -49,10 +43,17 @@ wps { label = "wps"; linux,code = ; - gpios = <&pio 102 GPIO_ACTIVE_LOW>; + gpios = <&pio 102 GPIO_ACTIVE_HIGH>; }; }; + gsw: gsw@0 { + compatible = "mediatek,mt753x"; + mediatek,ethsys = <ðsys>; + #address-cells = <1>; + #size-cells = <0>; + }; + leds { compatible = "gpio-leds"; @@ -69,13 +70,6 @@ }; }; - gsw: gsw@0 { - compatible = "mediatek,mt753x"; - mediatek,ethsys = <ðsys>; - #address-cells = <1>; - #size-cells = <0>; - }; - memory { reg = <0 0x40000000 0 0x40000000>; }; @@ -105,6 +99,7 @@ regulator-boot-on; regulator-always-on; }; + }; &bch { @@ -122,23 +117,59 @@ }; ð { - pinctrl-names = "default"; - pinctrl-0 = <ð_pins>; status = "okay"; - + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "sgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; gmac1: mac@1 { compatible = "mediatek,eth-mac"; reg = <1>; - phy-handle = <&phy5>; + phy-mode = "rgmii"; + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; }; - mdio: mdio-bus { #address-cells = <1>; #size-cells = <0>; + }; +}; - phy5: ethernet-phy@5 { - reg = <5>; - phy-mode = "sgmii"; +&gsw { + mediatek,mdio = <&mdio>; + mediatek,portmap = "wllll"; + mediatek,mdio_master_pinmux = <0>; + reset-gpios = <&pio 54 0>; + interrupt-parent = <&pio>; + interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; + status = "okay"; + + port5: port@5 { + compatible = "mediatek,mt753x-port"; + reg = <5>; + phy-mode = "rgmii"; + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + port6: port@6 { + compatible = "mediatek,mt753x-port"; + reg = <6>; + phy-mode = "sgmii"; + fixed-link { + speed = <2500>; + full-duplex; }; }; }; @@ -540,35 +571,3 @@ pinctrl-0 = <&watchdog_pins>; status = "okay"; }; - -&gsw { - mediatek,mdio = <&mdio>; - mediatek,portmap = "llllw"; - mediatek,mdio_master_pinmux = <0>; - reset-gpios = <&pio 54 0>; - interrupt-parent = <&pio>; - interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; - status = "okay"; - - port5: port@5 { - compatible = "mediatek,mt753x-port"; - reg = <5>; - phy-mode = "rgmii"; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - - port6: port@6 { - compatible = "mediatek,mt753x-port"; - reg = <6>; - phy-mode = "sgmii"; - fixed-link { - speed = <2500>; - full-duplex; - }; - }; -}; - - diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Kconfig b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Kconfig index cf83c6a436..d9e0230cf0 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Kconfig +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Kconfig @@ -1,4 +1,3 @@ config MT753X_GSW tristate "Driver for the MediaTek MT753x switch" - diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Makefile b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Makefile index 3829bacfe9..7aae451cd1 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Makefile +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/Makefile @@ -7,5 +7,5 @@ obj-$(CONFIG_MT753X_GSW) += mt753x.o mt753x-$(CONFIG_SWCONFIG) += mt753x_swconfig.o mt753x-y += mt753x_mdio.o mt7530.o mt7531.o \ - mt753x_common.o mt753x_nl.o - + mt753x_common.o mt753x_vlan.o \ + mt753x_nl.o diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.c index 45d4984c1a..014b83be9e 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Driver for MediaTek MT7530 gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -276,19 +272,73 @@ static void mt7530_core_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val) gsw->mmd_write(gsw, 0, 0x1f, reg, val); } +static void mt7530_trgmii_setting(struct gsw_mt753x *gsw) +{ + u16 i; + + mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0780); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); + + /* PLL BIAS enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, + RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN); + mdelay(1); + + /* PLL LPF enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, + RG_SYSPLL_DDSFBK_EN | + RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); + + /* sys PLL enable */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP2, + RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | + (1 << RG_SYSPLL_POSDIV_S)); + + /* LCDDDS PWDS */ + mt7530_core_reg_write(gsw, CORE_PLL_GROUP7, + (3 << RG_LCCDS_C_S) | + RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); + mdelay(1); + + /* Enable MT7530 TRGMII clock */ + mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN); + + /* lower Tx Driving */ + for (i = 0 ; i < NUM_TRGMII_ODT; i++) + mt753x_reg_write(gsw, TRGMII_TD_ODT(i), + (4 << TX_DM_DRVP_S) | (4 << TX_DM_DRVN_S)); +} + +static void mt7530_rgmii_setting(struct gsw_mt753x *gsw) +{ + u32 val; + + mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, 0x0c80); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, 0x87); + mdelay(1); + mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, 0x87); + + val = mt753x_reg_read(gsw, TRGMII_TXCTRL); + val &= ~TXC_INV; + mt753x_reg_write(gsw, TRGMII_TXCTRL, val); + + mt753x_reg_write(gsw, TRGMII_TCK_CTRL, + (8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S)); +} + static int mt7530_mac_port_setup(struct gsw_mt753x *gsw) { u32 hwstrap, p6ecr = 0, p5mcr, p6mcr, phyad; - hwstrap = mt753x_reg_read(gsw, HWSTRAP); + hwstrap = mt753x_reg_read(gsw, MHWSTRAP); hwstrap &= ~(P6_INTF_DIS | P5_INTF_MODE_RGMII | P5_INTF_DIS_S); - hwstrap |= CHG_TRAP | P5_INTF_SEL_GMAC5; - - if (gsw->direct_phy_access) - hwstrap &= ~C_MDIO_BPS_S; - else - hwstrap |= C_MDIO_BPS_S; - + hwstrap |= P5_INTF_SEL_GMAC5; if (!gsw->port5_cfg.enabled) { p5mcr = FORCE_MODE; hwstrap |= P5_INTF_DIS_S; @@ -358,10 +408,11 @@ parse_p6: switch (gsw->port6_cfg.phy_mode) { case PHY_INTERFACE_MODE_RGMII: + p6ecr = BIT(1); break; case PHY_INTERFACE_MODE_TRGMII: /* set MT7530 central align */ - p6ecr = BIT(1); /* TODO: confirm this */ + p6ecr = BIT(0); break; default: dev_info(gsw->dev, "%s is not supported by port6\n", @@ -382,8 +433,7 @@ parse_p6: static void mt7530_core_pll_setup(struct gsw_mt753x *gsw) { - u32 hwstrap, val, ncpo1, ssc_delta; - int i; + u32 hwstrap; hwstrap = mt753x_reg_read(gsw, HWSTRAP); @@ -418,48 +468,23 @@ static void mt7530_core_pll_setup(struct gsw_mt753x *gsw) break; } + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + hwstrap |= CHG_TRAP; + if (gsw->direct_phy_access) + hwstrap &= ~C_MDIO_BPS_S; + else + hwstrap |= C_MDIO_BPS_S; + + mt753x_reg_write(gsw, MHWSTRAP, hwstrap); + if (gsw->port6_cfg.enabled && gsw->port6_cfg.phy_mode == PHY_INTERFACE_MODE_TRGMII) { - ncpo1 = 0x1400; - ssc_delta = 0x57; + mt7530_trgmii_setting(gsw); } else { /* RGMII */ - ncpo1 = 0x0c80; - ssc_delta = 0x87; + mt7530_rgmii_setting(gsw); } - /* Setup the MT7530 TRGMII Tx Clock */ - mt7530_core_reg_write(gsw, CORE_PLL_GROUP5, ncpo1); - mt7530_core_reg_write(gsw, CORE_PLL_GROUP6, 0); - mt7530_core_reg_write(gsw, CORE_PLL_GROUP10, ssc_delta); - mt7530_core_reg_write(gsw, CORE_PLL_GROUP11, ssc_delta); - mt7530_core_reg_write(gsw, CORE_PLL_GROUP4, - RG_SYSPLL_DDSFBK_EN | - RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); - - mt7530_core_reg_write(gsw, CORE_PLL_GROUP2, - RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | - (1 << RG_SYSPLL_POSDIV_S)); - - mt7530_core_reg_write(gsw, CORE_PLL_GROUP7, - RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) | - RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); - - /* Enable MT7530 TRGMII clock */ - mt7530_core_reg_write(gsw, TRGMII_GSW_CLK_CG, GSWCK_EN | TRGMIICK_EN); - - val = mt753x_reg_read(gsw, TRGMII_TXCTRL); - val &= ~TXC_INV; - mt753x_reg_write(gsw, TRGMII_TXCTRL, val); - - /* lower Tx Driving */ - for (i = 0 ; i < NUM_TRGMII_ODT; i++) - mt753x_reg_write(gsw, TRGMII_TD_ODT(i), - (8 << TX_DM_DRVP_S) | (8 << TX_DM_DRVN_S)); - - mt753x_reg_write(gsw, TRGMII_TCK_CTRL, - (8 << TX_TAP_S) | (0x55 << TX_TRAIN_WD_S)); - /* delay setting for 10/1000M */ mt753x_reg_write(gsw, P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN | @@ -519,13 +544,17 @@ static void mt7530_phy_setting(struct gsw_mt753x *gsw) } } +static inline bool get_phy_access_mode(const struct device_node *np) +{ + return of_property_read_bool(np, "mt7530,direct-phy-access"); +} + static int mt7530_sw_init(struct gsw_mt753x *gsw) { int i; u32 val; - gsw->direct_phy_access = of_property_read_bool(gsw->dev->of_node, - "mt7530,direct-phy-access"); + gsw->direct_phy_access = get_phy_access_mode(gsw->dev->of_node); /* Force MT7530 to use (in)direct PHY access */ val = mt753x_reg_read(gsw, HWSTRAP); diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.h index b4c8a02861..ef2d68417a 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.h +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7530.h @@ -1,7 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ + * Copyright (c) 2018 MediaTek Inc. */ #ifndef _MT7530_H_ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.c index 4d44141a61..5b9f359168 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Driver for MediaTek MT7531 gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Zhanguo Ju - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -66,6 +62,11 @@ /* PHY ENABLE Register bitmap define */ #define PHY_DEV1F 0x1f #define PHY_DEV1F_REG_44 0x44 +#define PHY_DEV1F_REG_104 0x104 +#define PHY_DEV1F_REG_10A 0x10a +#define PHY_DEV1F_REG_10B 0x10b +#define PHY_DEV1F_REG_10C 0x10c +#define PHY_DEV1F_REG_10D 0x10d #define PHY_DEV1F_REG_268 0x268 #define PHY_DEV1F_REG_269 0x269 #define PHY_DEV1F_REG_403 0x403 @@ -74,6 +75,8 @@ #define GBE_EFUSE_SETTING BIT(3) #define PHY_EN_BYPASS_MODE BIT(4) #define POWER_ON_OFF BIT(5) +#define PHY_PLL_M GENMASK(9, 8) +#define PHY_PLL_SEL(x) (((x) << 8) & GENMASK(9, 8)) /* PHY EEE Register bitmap of define */ #define PHY_DEV07 0x07 @@ -142,7 +145,7 @@ #define ANA_PLLGP_CR5 0x78bc /* GPIO mode define */ -#define GPIO_MODE_REGS(x) (0x7c0c + ((x / 8) * 4)) +#define GPIO_MODE_REGS(x) (0x7c0c + (((x) / 8) * 4)) #define GPIO_MODE_S 4 /* GPIO GROUP IOLB SMT0 Control */ @@ -638,6 +641,68 @@ static int mt7531_set_gpio_pinmux(struct gsw_mt753x *gsw) return 0; } +static void mt7531_phy_pll_setup(struct gsw_mt753x *gsw) +{ + u32 hwstrap; + u32 val; + + hwstrap = mt753x_reg_read(gsw, HWSTRAP); + + switch ((hwstrap & XTAL_FSEL_M) >> XTAL_FSEL_S) { + case XTAL_25MHZ: + /* disable pll auto calibration */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608); + + /* change pll sel */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~(PHY_PLL_M); + val |= PHY_PLL_SEL(3); + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10A, 0x1009); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0x7c6); + + /* capacitance and resistance adjustment */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10C, 0xa8be); + + break; + case XTAL_40MHZ: + /* disable pll auto calibration */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_104, 0x608); + + /* change pll sel */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_403); + val &= ~(PHY_PLL_M); + val |= PHY_PLL_SEL(3); + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10A, 0x1018); + + /* set divider ratio */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10B, 0xc676); + + /* capacitance and resistance adjustment */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, + PHY_DEV1F_REG_10C, 0xd8be); + break; + } + + /* power down pll. additional delay is not required via mdio access */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x10); + + /* power up pll */ + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_10D, 0x14); +} + static void mt7531_phy_setting(struct gsw_mt753x *gsw) { int i; @@ -694,7 +759,7 @@ static void mt7531_adjust_line_driving(struct gsw_mt753x *gsw, u32 port) gsw->mmd_write(gsw, port, PHY_DEV1E, RXADC_CONTROL_3, 0x4444); /* Adjust Line driver current for different mode */ - gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_271, 0x2c63); + gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_271, 0x2ca5); /* Adjust Line driver current for different mode */ gsw->mmd_write(gsw, port, PHY_DEV1F, TXVLD_DA_272, 0xc6b); @@ -709,10 +774,10 @@ static void mt7531_adjust_line_driving(struct gsw_mt753x *gsw, u32 port) gsw->mmd_write(gsw, port, PHY_DEV1E, PHY_DEV1E_REG_41, 0x3333); /* Adjust TX class AB driver 1 */ - gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x3aa); + gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_268, 0x388); /* Adjust TX class AB driver 2 */ - gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0xaaaa); + gsw->mmd_write(gsw, port, PHY_DEV1F, PHY_DEV1F_REG_269, 0x4448); } static void mt7531_eee_setting(struct gsw_mt753x *gsw, u32 port) @@ -797,6 +862,8 @@ static int mt7531_sw_post_init(struct gsw_mt753x *gsw) int i; u32 val; + mt7531_phy_pll_setup(gsw); + /* Internal PHYs are disabled by default. SW should enable them. * Note that this may already be enabled in bootloader stage. */ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.h index 736cb0c349..e4ef81e94a 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.h +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt7531.h @@ -1,7 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * - * SPDX-License-Identifier: GPL-2.0+ + * Copyright (c) 2018 MediaTek Inc. */ #ifndef _MT7531_H_ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x.h index b9bca5416f..317b31ddcc 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x.h +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x.h @@ -1,11 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Driver for MediaTek MT753x gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef _MT753X_H_ @@ -22,13 +18,10 @@ #include #endif -#define MT753X_DFL_CPU_PORT 6 -#define MT753X_NUM_PORTS 7 -#define MT753X_NUM_PHYS 5 -#define MT753X_NUM_VLANS 4095 +#include "mt753x_vlan.h" -#define MT753X_MAX_VID 4095 -#define MT753X_MIN_VID 0 +#define MT753X_DFL_CPU_PORT 6 +#define MT753X_NUM_PHYS 5 #define MT753X_DFL_SMI_ADDR 0x1f #define MT753X_SMI_ADDR_MASK 0x1f @@ -40,16 +33,6 @@ enum mt753x_model { MT7531 = 0x7531 }; -struct mt753x_port_entry { - u16 pvid; -}; - -struct mt753x_vlan_entry { - u16 vid; - u8 member; - u8 etags; -}; - struct mt753x_port_cfg { struct device_node *np; int phy_mode; @@ -82,7 +65,7 @@ struct gsw_mt753x { struct mt753x_port_cfg port5_cfg; struct mt753x_port_cfg port6_cfg; - bool phy_status_poll; + int phy_status_poll; struct mt753x_phy phys[MT753X_NUM_PHYS]; int phy_link_sts; @@ -93,14 +76,13 @@ struct gsw_mt753x { #ifdef CONFIG_SWCONFIG struct switch_dev swdev; - - struct mt753x_vlan_entry vlan_entries[MT753X_NUM_VLANS]; - struct mt753x_port_entry port_entries[MT753X_NUM_PORTS]; - - int global_vlan_enable; u32 cpu_port; #endif + int global_vlan_enable; + struct mt753x_vlan_entry vlan_entries[MT753X_NUM_VLANS]; + struct mt753x_port_entry port_entries[MT753X_NUM_PORTS]; + int (*mii_read)(struct gsw_mt753x *gsw, int phy, int reg); void (*mii_write)(struct gsw_mt753x *gsw, int phy, int reg, u16 val); @@ -228,5 +210,4 @@ void mt753x_irq_enable(struct gsw_mt753x *gsw); #define MT753X_REG_PAGE_ADDR_M 0xffc0 #define MT753X_REG_ADDR_S 2 #define MT753X_REG_ADDR_M 0x3c - #endif /* _MT753X_H_ */ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_common.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_common.c index c836a63607..18f925956d 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_common.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_common.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Common part for MediaTek MT753x gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -56,8 +52,8 @@ static void display_port_link_status(struct gsw_mt753x *gsw, u32 port) } if (pmsr & MAC_LNK_STS) { - dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n", - port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half"); + dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n", + port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half"); } else { dev_info(gsw->dev, "Port %d Link is Down\n", port); } diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_mdio.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_mdio.c index 695713eed4..8a9a45c0be 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_mdio.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_mdio.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Driver for MediaTek MT753x gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -232,6 +228,11 @@ void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg, mutex_unlock(&gsw->mii_lock); } +static inline int mt753x_get_duplex(const struct device_node *np) +{ + return of_property_read_bool(np, "full-duplex"); +} + static void mt753x_load_port_cfg(struct gsw_mt753x *gsw) { struct device_node *port_np; @@ -279,9 +280,7 @@ static void mt753x_load_port_cfg(struct gsw_mt753x *gsw) u32 speed; port_cfg->force_link = 1; - port_cfg->duplex = of_property_read_bool( - fixed_link_node, - "full-duplex"); + port_cfg->duplex = mt753x_get_duplex(fixed_link_node); if (of_property_read_u32(fixed_link_node, "speed", &speed)) { @@ -331,6 +330,7 @@ static void mt753x_remove_gsw(struct gsw_mt753x *gsw) mutex_unlock(&mt753x_devs_lock); } + struct gsw_mt753x *mt753x_get_gsw(u32 id) { struct gsw_mt753x *dev; @@ -416,150 +416,6 @@ static int mt753x_hw_reset(struct gsw_mt753x *gsw) return 0; } -static int mt753x_mdio_read(struct mii_bus *bus, int addr, int reg) -{ - struct gsw_mt753x *gsw = bus->priv; - - return gsw->mii_read(gsw, addr, reg); -} - -static int mt753x_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) -{ - struct gsw_mt753x *gsw = bus->priv; - - gsw->mii_write(gsw, addr, reg, val); - - return 0; -} - -static const struct net_device_ops mt753x_dummy_netdev_ops = { -}; - -static void mt753x_phy_link_handler(struct net_device *dev) -{ - struct mt753x_phy *phy = container_of(dev, struct mt753x_phy, netdev); - struct phy_device *phydev = phy->phydev; - struct gsw_mt753x *gsw = phy->gsw; - u32 port = phy - gsw->phys; - - if (phydev->link) { - dev_info(gsw->dev, - "Port %d Link is Up - %s/%s - flow control %s\n", - port, phy_speed_to_str(phydev->speed), - (phydev->duplex == DUPLEX_FULL) ? "Full" : "Half", - phydev->pause ? "rx/tx" : "off"); - } else { - dev_info(gsw->dev, "Port %d Link is Down\n", port); - } -} - -static void mt753x_connect_internal_phys(struct gsw_mt753x *gsw, - struct device_node *mii_np) -{ - struct device_node *phy_np; - struct mt753x_phy *phy; - int phy_mode; - u32 phyad; - - if (!mii_np) - return; - - for_each_child_of_node(mii_np, phy_np) { - if (of_property_read_u32(phy_np, "reg", &phyad)) - continue; - - if (phyad >= MT753X_NUM_PHYS) - continue; - - phy_mode = of_get_phy_mode(phy_np); - if (phy_mode < 0) { - dev_info(gsw->dev, "incorrect phy-mode %d for PHY %d\n", - phy_mode, phyad); - continue; - } - - phy = &gsw->phys[phyad]; - phy->gsw = gsw; - - init_dummy_netdev(&phy->netdev); - phy->netdev.netdev_ops = &mt753x_dummy_netdev_ops; - - phy->phydev = of_phy_connect(&phy->netdev, phy_np, - mt753x_phy_link_handler, 0, phy_mode); - if (!phy->phydev) { - dev_info(gsw->dev, "could not connect to PHY %d\n", - phyad); - continue; - } - - phy_start(phy->phydev); - } -} - -static void mt753x_disconnect_internal_phys(struct gsw_mt753x *gsw) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(gsw->phys); i++) { - if (gsw->phys[i].phydev) { - phy_stop(gsw->phys[i].phydev); - phy_disconnect(gsw->phys[i].phydev); - gsw->phys[i].phydev = NULL; - } - } -} - -static int mt753x_mdio_register(struct gsw_mt753x *gsw) -{ - struct device_node *mii_np; - int i, ret; - - mii_np = of_get_child_by_name(gsw->dev->of_node, "mdio-bus"); - if (mii_np && !of_device_is_available(mii_np)) { - ret = -ENODEV; - goto err_put_node; - } - - gsw->gphy_bus = devm_mdiobus_alloc(gsw->dev); - if (!gsw->gphy_bus) { - ret = -ENOMEM; - goto err_put_node; - } - - gsw->gphy_bus->name = "mt753x_mdio"; - gsw->gphy_bus->read = mt753x_mdio_read; - gsw->gphy_bus->write = mt753x_mdio_write; - gsw->gphy_bus->priv = gsw; - gsw->gphy_bus->parent = gsw->dev; - gsw->gphy_bus->phy_mask = BIT(MT753X_NUM_PHYS) - 1; - - for (i = 0; i < PHY_MAX_ADDR; i++) - gsw->gphy_bus->irq[i] = PHY_POLL; - - if (mii_np) - snprintf(gsw->gphy_bus->id, MII_BUS_ID_SIZE, "%s@%s", - mii_np->name, gsw->dev->of_node->name); - else - snprintf(gsw->gphy_bus->id, MII_BUS_ID_SIZE, "mdio@%s", - gsw->dev->of_node->name); - - ret = of_mdiobus_register(gsw->gphy_bus, mii_np); - - if (ret) { - devm_mdiobus_free(gsw->dev, gsw->gphy_bus); - gsw->gphy_bus = NULL; - } else { - if (gsw->phy_status_poll) - mt753x_connect_internal_phys(gsw, mii_np); - } - -err_put_node: - if (mii_np) - of_node_put(mii_np); - - return ret; -} - static irqreturn_t mt753x_irq_handler(int irq, void *dev) { struct gsw_mt753x *gsw = dev; @@ -580,6 +436,7 @@ static int mt753x_probe(struct platform_device *pdev) struct mii_bus *mdio_bus; int ret = -EINVAL; struct chip_rev rev; + struct mt753x_mapping *map; int i; mdio = of_parse_phandle(np, "mediatek,mdio", 0); @@ -599,12 +456,21 @@ static int mt753x_probe(struct platform_device *pdev) mutex_init(&gsw->mii_lock); /* Switch hard reset */ - mt753x_hw_reset(gsw); + if (mt753x_hw_reset(gsw)) + goto fail; /* Fetch the SMI address dirst */ if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr)) gsw->smi_addr = MT753X_DFL_SMI_ADDR; + /* Get LAN/WAN port mapping */ + map = mt753x_find_mapping(np); + if (map) { + mt753x_apply_mapping(gsw, map); + gsw->global_vlan_enable = 1; + dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name); + } + /* Load MAC port configurations */ mt753x_load_port_cfg(gsw); @@ -653,11 +519,7 @@ static int mt753x_probe(struct platform_device *pdev) mt753x_add_gsw(gsw); - mt753x_mdio_register(gsw); - -#ifdef CONFIG_SWCONFIG mt753x_swconfig_init(gsw); -#endif if (sw->post_init) sw->post_init(gsw); @@ -687,10 +549,6 @@ static int mt753x_remove(struct platform_device *pdev) mt753x_swconfig_destroy(gsw); #endif - mt753x_disconnect_internal_phys(gsw); - - mdiobus_unregister(gsw->gphy_bus); - mt753x_remove_gsw(gsw); platform_set_drvdata(pdev, NULL); diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.c index 756df4e21f..78aecd34ed 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Configuration layer for MediaTek MT753x gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Sirui Zhao - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -17,10 +13,6 @@ #include "mt753x.h" #include "mt753x_nl.h" -#define MT753X_NL_CMD_REQ_ATTRS(attr) \ - .required_attrs = attr, \ - .nr_required_attrs = ARRAY_SIZE(attr), - struct mt753x_nl_cmd_item { enum mt753x_cmd cmd; bool require_dev; @@ -61,7 +53,6 @@ static const struct genl_ops mt753x_nl_ops[] = { }; static struct genl_family mt753x_nl_family = { -// .id = GENL_ID_GENERATE, .name = MT753X_GENL_NAME, .version = MT753X_GENL_VERSION, .maxattr = MT753X_NR_ATTR_TYPE, @@ -208,7 +199,8 @@ static int mt753x_nl_reply_read(struct genl_info *info, struct gsw_mt753x *gsw) { struct sk_buff *rep_skb = NULL; s32 phy, devad, reg; - int ret, value; + int value; + int ret = 0; phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1); devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1); @@ -252,7 +244,7 @@ static int mt753x_nl_reply_write(struct genl_info *info, struct gsw_mt753x *gsw) struct sk_buff *rep_skb = NULL; s32 phy, devad, reg; u32 value; - int ret; + int ret = 0; phy = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_PHY, -1); devad = mt753x_nl_get_s32(info, MT753X_ATTR_TYPE_DEVAD, -1); @@ -312,12 +304,14 @@ static const struct mt753x_nl_cmd_item mt753x_nl_cmds[] = { .cmd = MT753X_CMD_READ, .require_dev = true, .process = mt753x_nl_reply_read, - MT753X_NL_CMD_REQ_ATTRS(mt753x_nl_cmd_read_attrs) + .required_attrs = mt753x_nl_cmd_read_attrs, + .nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_read_attrs), }, { .cmd = MT753X_CMD_WRITE, .require_dev = true, .process = mt753x_nl_reply_write, - MT753X_NL_CMD_REQ_ATTRS(mt753x_nl_cmd_write_attrs) + .required_attrs = mt753x_nl_cmd_write_attrs, + .nr_required_attrs = ARRAY_SIZE(mt753x_nl_cmd_write_attrs), } }; diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.h index f6a1df34e6..3c06273802 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.h +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_nl.h @@ -1,11 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Driver for MediaTek MT753x gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Sirui Zhao - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef _MT753X_NL_H_ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_regs.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_regs.h index 15255277ab..0c91b8e0ec 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_regs.h +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_regs.h @@ -1,11 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * Register definitions for MediaTek MT753x Gigabit switches - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef _MT753X_REGS_H_ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c index fb2ee1c1b7..b601b90fb1 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * OpenWrt swconfig support for MediaTek MT753x Gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -93,64 +89,6 @@ enum { MT753X_ATTR_ENABLE_VLAN, }; -struct mt753x_mapping { - char *name; - u16 pvids[MT753X_NUM_PORTS]; - u8 members[MT753X_NUM_VLANS]; - u8 etags[MT753X_NUM_VLANS]; - u16 vids[MT753X_NUM_VLANS]; -} mt753x_defaults[] = { - { - .name = "llllw", - .pvids = { 1, 1, 1, 1, 2, 2, 1 }, - .members = { 0, 0x4f, 0x30 }, - .etags = { 0, 0, 0 }, - .vids = { 0, 1, 2 }, - }, { - .name = "wllll", - .pvids = { 2, 1, 1, 1, 1, 2, 1 }, - .members = { 0, 0x5e, 0x21 }, - .etags = { 0, 0, 0 }, - .vids = { 0, 1, 2 }, - }, { - .name = "lwlll", - .pvids = { 1, 2, 1, 1, 1, 2, 1 }, - .members = { 0, 0x5d, 0x22 }, - .etags = { 0, 0, 0 }, - .vids = { 0, 1, 2 }, - }, -}; - -struct mt753x_mapping *mt753x_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(mt753x_defaults); i++) - if (!strcmp(map, mt753x_defaults[i].name)) - return &mt753x_defaults[i]; - - return NULL; -} - -static void mt753x_apply_mapping(struct gsw_mt753x *gsw, - struct mt753x_mapping *map) -{ - int i = 0; - - for (i = 0; i < MT753X_NUM_PORTS; i++) - gsw->port_entries[i].pvid = map->pvids[i]; - - for (i = 0; i < MT753X_NUM_VLANS; i++) { - gsw->vlan_entries[i].member = map->members[i]; - gsw->vlan_entries[i].etags = map->etags[i]; - gsw->vlan_entries[i].vid = map->vids[i]; - } -} - static int mt753x_get_vlan_enable(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val) @@ -201,27 +139,6 @@ static int mt753x_set_port_pvid(struct switch_dev *dev, int port, int pvid) return 0; } -static void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val) -{ - int i; - - mt753x_reg_write(gsw, VTCR, - VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) | - (val & VTCR_VID_M)); - - for (i = 0; i < 300; i++) { - u32 val = mt753x_reg_read(gsw, VTCR); - - if ((val & VTCR_BUSY) == 0) - break; - - usleep_range(1000, 1100); - } - - if (i == 300) - dev_info(gsw->dev, "vtcr timeout\n"); -} - static int mt753x_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) { struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); @@ -447,114 +364,16 @@ static void mt753x_port_isolation(struct gsw_mt753x *gsw) (VA_TRANSPARENT_PORT << VLAN_ATTR_S)); } -static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid, - u8 ports, u8 etags) -{ - int port; - u32 val; - - /* vlan port membership */ - if (ports) - mt753x_reg_write(gsw, VAWD1, - IVL_MAC | VTAG_EN | VENTRY_VALID | - ((ports << PORT_MEM_S) & PORT_MEM_M)); - else - mt753x_reg_write(gsw, VAWD1, 0); - - /* egress mode */ - val = 0; - for (port = 0; port < MT753X_NUM_PORTS; port++) { - if (etags & BIT(port)) - val |= ETAG_CTRL_TAG << PORT_ETAG_S(port); - else - val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port); - } - mt753x_reg_write(gsw, VAWD2, val); - - /* write to vlan table */ - mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid); -} - static int mt753x_apply_config(struct switch_dev *dev) { struct gsw_mt753x *gsw = container_of(dev, struct gsw_mt753x, swdev); - int i, j; - u8 tag_ports; - u8 untag_ports; if (!gsw->global_vlan_enable) { mt753x_port_isolation(gsw); return 0; } - /* set all ports as security mode */ - for (i = 0; i < MT753X_NUM_PORTS; i++) - mt753x_reg_write(gsw, PCR(i), - PORT_MATRIX_M | SECURITY_MODE); - - /* check if a port is used in tag/untag vlan egress mode */ - tag_ports = 0; - untag_ports = 0; - - for (i = 0; i < MT753X_NUM_VLANS; i++) { - u8 member = gsw->vlan_entries[i].member; - u8 etags = gsw->vlan_entries[i].etags; - - if (!member) - continue; - - for (j = 0; j < MT753X_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 < MT753X_NUM_PORTS; i++) { - u32 pvc_mode = 0x8100 << STAG_VPID_S; - - if (untag_ports & BIT(i) && !(tag_ports & BIT(i))) - pvc_mode = (0x8100 << STAG_VPID_S) | - (VA_TRANSPARENT_PORT << VLAN_ATTR_S); - - mt753x_reg_write(gsw, PVC(i), pvc_mode); - } - - /* first clear the swtich vlan table */ - for (i = 0; i < MT753X_NUM_VLANS; i++) - mt753x_write_vlan_entry(gsw, i, i, 0, 0); - - /* now program only vlans with members to avoid - * clobbering remapped entries in later iterations - */ - for (i = 0; i < MT753X_NUM_VLANS; i++) { - u16 vid = gsw->vlan_entries[i].vid; - u8 member = gsw->vlan_entries[i].member; - u8 etags = gsw->vlan_entries[i].etags; - - if (member) - mt753x_write_vlan_entry(gsw, i, vid, member, etags); - } - - /* Port Default PVID */ - for (i = 0; i < MT753X_NUM_PORTS; i++) { - int vlan = gsw->port_entries[i].pvid; - u16 pvid = 0; - u32 val; - - if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member) - pvid = gsw->vlan_entries[vlan].vid; - - val = mt753x_reg_read(gsw, PPBV1(i)); - val &= ~GRP_PORT_VID_M; - val |= pvid; - mt753x_reg_write(gsw, PPBV1(i), val); - } + mt753x_apply_vlan_config(gsw); return 0; } @@ -659,7 +478,6 @@ int mt753x_swconfig_init(struct gsw_mt753x *gsw) { struct device_node *np = gsw->dev->of_node; struct switch_dev *swdev; - struct mt753x_mapping *map; int ret; if (of_property_read_u32(np, "mediatek,cpuport", &gsw->cpu_port)) @@ -676,14 +494,11 @@ int mt753x_swconfig_init(struct gsw_mt753x *gsw) ret = register_switch(swdev, NULL); if (ret) { - dev_err(gsw->dev, "Failed to register switch %s\n", - swdev->name); + dev_notice(gsw->dev, "Failed to register switch %s\n", + swdev->name); return ret; } - map = mt753x_find_mapping(gsw->dev->of_node); - if (map) - mt753x_apply_mapping(gsw, map); mt753x_apply_config(swdev); return 0; diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h index 971a2cc90a..b877d8957e 100644 --- a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h @@ -1,19 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * OpenWrt swconfig support for MediaTek MT753x Gigabit switch - * - * Copyright (C) 2018 MediaTek Inc. All Rights Reserved. - * + * Copyright (c) 2018 MediaTek Inc. * Author: Weijie Gao - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef _MT753X_SWCONFIG_H_ #define _MT753X_SWCONFIG_H_ +#ifdef CONFIG_SWCONFIG #include +#include "mt753x.h" int mt753x_swconfig_init(struct gsw_mt753x *gsw); void mt753x_swconfig_destroy(struct gsw_mt753x *gsw); +#else +static inline int mt753x_swconfig_init(struct gsw_mt753x *gsw) +{ + mt753x_apply_vlan_config(gsw); + + return 0; +} + +static inline void mt753x_swconfig_destroy(struct gsw_mt753x *gsw) +{ +} +#endif #endif /* _MT753X_SWCONFIG_H_ */ diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.c b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.c new file mode 100644 index 0000000000..f3c8c38f3e --- /dev/null +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#include "mt753x.h" +#include "mt753x_regs.h" + +struct mt753x_mapping mt753x_def_mapping[] = { + { + .name = "llllw", + .pvids = { 1, 1, 1, 1, 2, 2, 1 }, + .members = { 0, 0x4f, 0x30 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, { + .name = "wllll", + .pvids = { 2, 1, 1, 1, 1, 2, 1 }, + .members = { 0, 0x5e, 0x21 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, { + .name = "lwlll", + .pvids = { 1, 2, 1, 1, 1, 2, 1 }, + .members = { 0, 0x5d, 0x22 }, + .etags = { 0, 0, 0 }, + .vids = { 0, 1, 2 }, + }, +}; + +void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val) +{ + int i; + + mt753x_reg_write(gsw, VTCR, + VTCR_BUSY | ((cmd << VTCR_FUNC_S) & VTCR_FUNC_M) | + (val & VTCR_VID_M)); + + for (i = 0; i < 300; i++) { + u32 val = mt753x_reg_read(gsw, VTCR); + + if ((val & VTCR_BUSY) == 0) + break; + + usleep_range(1000, 1100); + } + + if (i == 300) + dev_info(gsw->dev, "vtcr timeout\n"); +} + +static void mt753x_write_vlan_entry(struct gsw_mt753x *gsw, int vlan, u16 vid, + u8 ports, u8 etags) +{ + int port; + u32 val; + + /* vlan port membership */ + if (ports) + mt753x_reg_write(gsw, VAWD1, + IVL_MAC | VTAG_EN | VENTRY_VALID | + ((ports << PORT_MEM_S) & PORT_MEM_M)); + else + mt753x_reg_write(gsw, VAWD1, 0); + + /* egress mode */ + val = 0; + for (port = 0; port < MT753X_NUM_PORTS; port++) { + if (etags & BIT(port)) + val |= ETAG_CTRL_TAG << PORT_ETAG_S(port); + else + val |= ETAG_CTRL_UNTAG << PORT_ETAG_S(port); + } + mt753x_reg_write(gsw, VAWD2, val); + + /* write to vlan table */ + mt753x_vlan_ctrl(gsw, VTCR_WRITE_VLAN_ENTRY, vid); +} + +void mt753x_apply_vlan_config(struct gsw_mt753x *gsw) +{ + int i, j; + u8 tag_ports; + u8 untag_ports; + + /* set all ports as security mode */ + for (i = 0; i < MT753X_NUM_PORTS; i++) + mt753x_reg_write(gsw, PCR(i), + PORT_MATRIX_M | SECURITY_MODE); + + /* check if a port is used in tag/untag vlan egress mode */ + tag_ports = 0; + untag_ports = 0; + + for (i = 0; i < MT753X_NUM_VLANS; i++) { + u8 member = gsw->vlan_entries[i].member; + u8 etags = gsw->vlan_entries[i].etags; + + if (!member) + continue; + + for (j = 0; j < MT753X_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 < MT753X_NUM_PORTS; i++) { + u32 pvc_mode = 0x8100 << STAG_VPID_S; + + if (untag_ports & BIT(i) && !(tag_ports & BIT(i))) + pvc_mode = (0x8100 << STAG_VPID_S) | + (VA_TRANSPARENT_PORT << VLAN_ATTR_S); + + mt753x_reg_write(gsw, PVC(i), pvc_mode); + } + + /* first clear the switch vlan table */ + for (i = 0; i < MT753X_NUM_VLANS; i++) + mt753x_write_vlan_entry(gsw, i, i, 0, 0); + + /* now program only vlans with members to avoid + * clobbering remapped entries in later iterations + */ + for (i = 0; i < MT753X_NUM_VLANS; i++) { + u16 vid = gsw->vlan_entries[i].vid; + u8 member = gsw->vlan_entries[i].member; + u8 etags = gsw->vlan_entries[i].etags; + + if (member) + mt753x_write_vlan_entry(gsw, i, vid, member, etags); + } + + /* Port Default PVID */ + for (i = 0; i < MT753X_NUM_PORTS; i++) { + int vlan = gsw->port_entries[i].pvid; + u16 pvid = 0; + u32 val; + + if (vlan < MT753X_NUM_VLANS && gsw->vlan_entries[vlan].member) + pvid = gsw->vlan_entries[vlan].vid; + + val = mt753x_reg_read(gsw, PPBV1(i)); + val &= ~GRP_PORT_VID_M; + val |= pvid; + mt753x_reg_write(gsw, PPBV1(i), val); + } +} + +struct mt753x_mapping *mt753x_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(mt753x_def_mapping); i++) + if (!strcmp(map, mt753x_def_mapping[i].name)) + return &mt753x_def_mapping[i]; + + return NULL; +} + +void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map) +{ + int i = 0; + + for (i = 0; i < MT753X_NUM_PORTS; i++) + gsw->port_entries[i].pvid = map->pvids[i]; + + for (i = 0; i < MT753X_NUM_VLANS; i++) { + gsw->vlan_entries[i].member = map->members[i]; + gsw->vlan_entries[i].etags = map->etags[i]; + gsw->vlan_entries[i].vid = map->vids[i]; + } +} diff --git a/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.h b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.h new file mode 100644 index 0000000000..66c9cf984e --- /dev/null +++ b/target/linux/mediatek/files-4.19/drivers/net/phy/mtk/mt753x/mt753x_vlan.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018 MediaTek Inc. + */ + +#ifndef _MT753X_VLAN_H_ +#define _MT753X_VLAN_H_ + +#define MT753X_NUM_PORTS 7 +#define MT753X_NUM_VLANS 4095 +#define MT753X_MAX_VID 4095 +#define MT753X_MIN_VID 0 + +struct gsw_mt753x; + +struct mt753x_port_entry { + u16 pvid; +}; + +struct mt753x_vlan_entry { + u16 vid; + u8 member; + u8 etags; +}; + +struct mt753x_mapping { + char *name; + u16 pvids[MT753X_NUM_PORTS]; + u8 members[MT753X_NUM_VLANS]; + u8 etags[MT753X_NUM_VLANS]; + u16 vids[MT753X_NUM_VLANS]; +}; + +extern struct mt753x_mapping mt753x_defaults[]; + +void mt753x_vlan_ctrl(struct gsw_mt753x *gsw, u32 cmd, u32 val); +void mt753x_apply_vlan_config(struct gsw_mt753x *gsw); +struct mt753x_mapping *mt753x_find_mapping(struct device_node *np); +void mt753x_apply_mapping(struct gsw_mt753x *gsw, struct mt753x_mapping *map); +#endif /* _MT753X_VLAN_H_ */ diff --git a/target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch b/target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch index 1e0f9a9b2a..c396e314a9 100644 --- a/target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch +++ b/target/linux/mediatek/patches-4.14/0052-net-phy-add-FC.patch @@ -10,7 +10,7 @@ Signed-off-by: John Crispin --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1937,7 +1937,7 @@ static struct phy_driver genphy_driver = +@@ -1943,7 +1943,7 @@ static struct phy_driver genphy_driver = .config_init = genphy_config_init, .features = PHY_GBIT_FEATURES | SUPPORTED_MII | SUPPORTED_AUI | SUPPORTED_FIBRE | diff --git a/target/linux/mediatek/patches-4.19/0003-mt7531-gsw-internal_phy_calibration.patch b/target/linux/mediatek/patches-4.19/0003-mt7531-gsw-internal_phy_calibration.patch index 8e4ef2ae1b..db22cc2189 100644 --- a/target/linux/mediatek/patches-4.19/0003-mt7531-gsw-internal_phy_calibration.patch +++ b/target/linux/mediatek/patches-4.19/0003-mt7531-gsw-internal_phy_calibration.patch @@ -1,36 +1,44 @@ --- a/drivers/net/phy/mtk/mt753x/Makefile +++ b/drivers/net/phy/mtk/mt753x/Makefile -@@ -7,5 +7,5 @@ obj-$(CONFIG_MT753X_GSW) += mt753x.o - mt753x-$(CONFIG_SWCONFIG) += mt753x_swconfig.o +@@ -8,4 +8,4 @@ mt753x-$(CONFIG_SWCONFIG) += mt753x_swco mt753x-y += mt753x_mdio.o mt7530.o mt7531.o \ -- mt753x_common.o mt753x_nl.o -+ mt753x_common.o mt753x_nl.o mt753x_phy.o - + mt753x_common.o mt753x_vlan.o \ +- mt753x_nl.o ++ mt753x_nl.o mt753x_phy.o --- a/drivers/net/phy/mtk/mt753x/mt7531.c +++ b/drivers/net/phy/mtk/mt753x/mt7531.c -@@ -582,6 +582,18 @@ static void mt7531_core_pll_setup(struct +@@ -585,6 +585,27 @@ static void mt7531_core_pll_setup(struct static int mt7531_internal_phy_calibration(struct gsw_mt753x *gsw) { + u32 i, val; + int ret; ++ ++ dev_info(gsw->dev,">>>>>>>>>>>>>>>>>>>>>>>>>>>>> START CALIBRATION:\n"); ++ ++ /* gphy value from sw path */ + val = gsw->mmd_read(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403); + val |= GBE_EFUSE_SETTING; + gsw->mmd_write(gsw, 0, PHY_DEV1F, PHY_DEV1F_REG_403, val); ++ + for (i = 0; i < 5; i++) { ++ dev_info(gsw->dev, "-------- gephy-calbration (port:%d) --------\n", ++ i); + ret = mt753x_phy_calibration(gsw, i); ++ + /* set Auto-negotiation with giga extension. */ + gsw->mii_write(gsw, i, 0, 0x1340); + if (ret) + return ret; + } ++ return 0; } --- a/drivers/net/phy/mtk/mt753x/mt753x.h +++ b/drivers/net/phy/mtk/mt753x/mt753x.h -@@ -147,6 +147,8 @@ void mt753x_mmd_ind_write(struct gsw_mt7 +@@ -129,6 +129,8 @@ void mt753x_mmd_ind_write(struct gsw_mt7 void mt753x_irq_worker(struct work_struct *work); void mt753x_irq_enable(struct gsw_mt753x *gsw); @@ -41,7 +49,7 @@ #define MMD_CMD_S 14 --- /dev/null +++ b/drivers/net/phy/mtk/mt753x/mt753x_phy.c -@@ -0,0 +1,947 @@ +@@ -0,0 +1,1061 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Common part for MediaTek MT753x gigabit switch @@ -62,6 +70,9 @@ +{ + u32 phy_val; + phy_val = gsw->mmd_read(gsw, port_num, dev_addr, reg_addr); ++ ++ //printk("switch phy cl45 r %d 0x%x 0x%x = %x\n",port_num, dev_addr, reg_addr, phy_val); ++ //switch_phy_read_cl45(port_num, dev_addr, reg_addr, &phy_val); + return phy_val; +} + @@ -70,6 +81,8 @@ + u32 phy_val; + gsw->mmd_write(gsw, port_num, dev_addr, reg_addr, write_data); + phy_val = gsw->mmd_read(gsw, port_num, dev_addr, reg_addr); ++ //printk("switch phy cl45 w %d 0x%x 0x%x 0x%x --> read back 0x%x\n",port_num, dev_addr, reg_addr, write_data, phy_val); ++ //switch_phy_write_cl45(port_num, dev_addr, reg_addr, write_data); +} + +void switch_phy_write(struct gsw_mt753x *gsw, u32 port_num, u32 reg_addr, u32 write_data){ @@ -108,7 +121,10 @@ +{ + u8 all_ana_cal_status; + u32 cnt, tmp_1e_17c; ++ //tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017c, 0x0001); // da_calin_flag pull high + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0x0001); ++ //printk("delay = %d\n", delay); ++ + cnt = 10000; + do { + udelay(delay); @@ -122,10 +138,45 @@ + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0); + return all_ana_cal_status; + } else { -+ pr_info("MDC/MDIO error\n"); -+ return 0; ++ tmp_1e_17c = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x17c); ++ if ((tmp_1e_17c & 0x1) != 1) { ++ pr_info("FIRST MDC/MDIO write error\n"); ++ pr_info("FIRST 1e_17c = %x\n", tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x17c)); ++ ++ } ++ printk("re-K again\n"); ++ ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0x0001); ++ cnt = 10000; ++ do { ++ udelay(delay); ++ cnt--; ++ tmp_1e_17c = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x17c); ++ if ((tmp_1e_17c & 0x1) != 1) { ++ pr_info("SECOND MDC/MDIO write error\n"); ++ pr_info("SECOND 1e_17c = %x\n", tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x17c)); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0x0001); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0x0001); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0x0001); ++ } ++ } while ((cnt != 0) && (tmp_1e_17c == 0)); ++ ++ cnt = 10000; ++ do { ++ udelay(delay); ++ cnt--; ++ all_ana_cal_status = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x17b) & 0x1; ++ ++ } while ((all_ana_cal_status == 0) && (cnt != 0)); ++ ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x17c, 0); + } + ++ if(all_ana_cal_status == 0){ ++ pr_info("!!!!!!!!!!!! dev1Eh_reg17b ERROR\n"); ++ } ++ + return all_ana_cal_status; +} + @@ -141,6 +192,12 @@ + u8 cnt = 0; + u16 dev1e_17a_tmp, dev1e_e0_tmp; + ++ /* *** Iext/Rext Cal start ************ */ ++ all_ana_cal_status = ANACAL_INIT; ++ /* analog calibration enable, Rext calibration enable */ ++ /* 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a */ ++ /* 1e_dc[0]:rg_txvos_calen */ ++ /* 1e_e1[4]:rg_cal_refsel(0:1.2V) */ + //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00db, 0x1110) + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x1110); + //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00dc, 0x0000); @@ -148,15 +205,18 @@ + //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x00e1, 0x0000); + //tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e1, 0x10); + -+ rg_zcal_ctrl = 0x20; -+ dev1e_e0_ana_cal_r5 = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0xe0); ++ rg_zcal_ctrl = 0x20;/* start with 0 dB */ ++ dev1e_e0_ana_cal_r5 = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0xe0); // get default value ++ /* 1e_e0[5:0]:rg_zcal_ctrl */ + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0xe0, rg_zcal_ctrl); + all_ana_cal_status = all_ge_ana_cal_wait(gsw, delay, phyaddr);/* delay 20 usec */ ++ + if (all_ana_cal_status == 0) { + all_ana_cal_status = ANACAL_ERROR; + printk(" GE Rext AnaCal ERROR init! \r\n"); + return -1; + } ++ /* 1e_17a[8]:ad_cal_comp_out */ + ad_cal_comp_out_init = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a) >> 8) & 0x1; + if (ad_cal_comp_out_init == 1) + calibration_polarity = -1; @@ -180,7 +240,7 @@ + dev1e_17a_tmp = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a); + dev1e_e0_tmp = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0xe0); + if ((rg_zcal_ctrl == 0x3F) || (rg_zcal_ctrl == 0x00)) { -+ all_ana_cal_status = ANACAL_SATURATION; ++ all_ana_cal_status = ANACAL_SATURATION; /* need to FT(IC fail?) */ + printk(" GE Rext AnaCal Saturation! \r\n"); + rg_zcal_ctrl = 0x20; /* 0 dB */ + } @@ -188,12 +248,13 @@ + } + + if (all_ana_cal_status == ANACAL_ERROR) { -+ rg_zcal_ctrl = 0x20; ++ rg_zcal_ctrl = 0x20; /* 0 dB */ + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl)); + } else if(all_ana_cal_status == ANACAL_FINISH){ + //tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl)); + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e0, ((rg_zcal_ctrl << 8) | rg_zcal_ctrl)); + printk("0x1e-e0 = %x\n", tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x00e0)); ++ /* **** 1f_115[2:0] = rg_zcal_ctrl[5:3] // Mog review */ + tc_phy_write_dev_reg(gsw, PHY0, 0x1f, 0x0115, ((rg_zcal_ctrl & 0x3f) >> 3)); + printk("0x1f-115 = %x\n", tc_phy_read_dev_reg(gsw, PHY0, 0x1f, 0x115)); + printk(" GE Rext AnaCal Done! (%d)(0x%x) \r\n", cnt, rg_zcal_ctrl); @@ -215,38 +276,38 @@ + u16 dev1e_e0_ana_cal_r5; + int calibration_polarity; + u8 cnt = 0; -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x1100); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0000); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x1100); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0000); // 1e_dc[0]:rg_txvos_calen + + for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) { -+ rg_zcal_ctrl = 0x20; ++ rg_zcal_ctrl = 0x20; // start with 0 dB + dev1e_e0_ana_cal_r5 = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x00e0) & (~0x003f)); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl)); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl)); // 1e_e0[5:0]:rg_zcal_ctrl + if(calibration_pair == ANACAL_PAIR_A) + { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1101); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1101); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0000); + //printk("R50 pair A 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00db), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00dc)); + + } + else if(calibration_pair == ANACAL_PAIR_B) + { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1100); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x1000); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1100); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x1000); // 1e_dc[12]:rg_zcalen_b + //printk("R50 pair B 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00db),tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00dc)); + + } + else if(calibration_pair == ANACAL_PAIR_C) + { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1100); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0100); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1100); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0100); // 1e_dc[8]:rg_zcalen_c + //printk("R50 pair C 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00db), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00dc)); + + } + else // if(calibration_pair == ANACAL_PAIR_D) + { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1100); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0010); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x1100); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0010); // 1e_dc[4]:rg_zcalen_d + //printk("R50 pair D 1e_db=%x 1e_db=%x\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00db), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x00dc)); + + } @@ -259,7 +320,7 @@ + return -1; + } + -+ ad_cal_comp_out_init = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a)>>8) & 0x1; ++ ad_cal_comp_out_init = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8]:ad_cal_comp_out + if(ad_cal_comp_out_init == 1) + calibration_polarity = -1; + else @@ -293,11 +354,11 @@ + } + + if(all_ana_cal_status == ANACAL_ERROR) { -+ rg_zcal_ctrl = 0x20; ++ rg_zcal_ctrl = 0x20; // 0 dB + //tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00e0, (dev1e_e0_ana_cal_r5 | rg_zcal_ctrl)); + } + else { -+ rg_zcal_ctrl = MT753x_ZCAL_TO_R50ohm_GE_TBL_100[rg_zcal_ctrl - 9]; ++ rg_zcal_ctrl = MT753x_ZCAL_TO_R50ohm_GE_TBL_100[rg_zcal_ctrl - 9]; // wait Mog zcal/r50 mapping table + printk( " GE R50 AnaCal Done! (%d) (0x%x)(0x%x) \r\n", cnt, rg_zcal_ctrl, (rg_zcal_ctrl|0x80)); + } + @@ -305,7 +366,7 @@ + ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174) & (~0x7f00); + //ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174); + //printk( " GE-a 1e_174(0x%x)(0x%x), 1e_175(0x%x) \r\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174), ad_cal_comp_out_init, tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175)); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000))); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000))); // 1e_174[15:8] + //printk( " GE-a 1e_174(0x%x), 1e_175(0x%x) \r\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175)); + } + else if(calibration_pair == ANACAL_PAIR_B) { @@ -313,18 +374,18 @@ + //ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174); + //printk( " GE-b 1e_174(0x%x)(0x%x), 1e_175(0x%x) \r\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174), ad_cal_comp_out_init, tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175)); + -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080))); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0174, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080))); // 1e_174[7:0] + //printk( " GE-b 1e_174(0x%x), 1e_175(0x%x) \r\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175)); + } + else if(calibration_pair == ANACAL_PAIR_C) { + ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175) & (~0x7f00); + //ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000))); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<8)&0xff00) | 0x8000))); // 1e_175[15:8] + //printk( " GE-c 1e_174(0x%x), 1e_175(0x%x) \r\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175)); + } else {// if(calibration_pair == ANACAL_PAIR_D) + ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175) & (~0x007f); + //ad_cal_comp_out_init = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080))); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0175, (ad_cal_comp_out_init | (((rg_zcal_ctrl<<0)&0x00ff) | 0x0080))); // 1e_175[7:0] + //printk( " GE-d 1e_174(0x%x), 1e_175(0x%x) \r\n", tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0174), tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0175)); + } + //tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00e0, ((rg_zcal_ctrl<<8)|rg_zcal_ctrl)); @@ -345,10 +406,11 @@ + u8 tx_offset_reg_shift, tabl_idx, i; + u8 cnt = 0; + u16 tx_offset_reg, reg_temp, cal_temp; -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x0100); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0001); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0096, 0x8000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0xf808); ++ //switch_phy_write(phyaddr, R0, 0x2100);//harry tmp ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x0100); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0001); // 1e_dc[0]:rg_txvos_calen ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0096, 0x8000); // 1e_96[15]:bypass_tx_offset_cal, Hw bypass, Fw cal ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0xf808); // 1e_3e + for(i = 0; i <= 4; i++) + tc_phy_write_dev_reg(gsw, i, 0x1e, 0x00dd, 0x0000); + for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) @@ -358,45 +420,45 @@ + + if(calibration_pair == ANACAL_PAIR_A) { + //tc_phy_write_dev_reg(phyaddr, 0x1e, 0x145, 0x5010); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x1000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_0V)); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_0V)); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x1000); // 1e_dd[12]:rg_txg_calen_a ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_0V)); // 1e_17d:dac_in0_a ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_0V)); // 1e_181:dac_in1_a + //printk("tx offset pairA 1e_dd = %x, 1e_17d=%x, 1e_181=%x\n", tc_phy_read_dev_reg(phyaddr, 0x1e, 0x00dd), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x017d), tc_phy_read_dev_reg(phyaddr, 0x1e, 0x0181)); + reg_temp = (tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x0172) & (~0x3f00)); -+ tx_offset_reg_shift = 8; ++ tx_offset_reg_shift = 8; // 1e_172[13:8] + tx_offset_reg = 0x0172; + + //tc_phy_write_dev_reg(phyaddr, 0x1e, tx_offset_reg, (reg_temp|(tx_offset_temp<>8) & 0x1; ++ ad_cal_comp_out_init = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8]:ad_cal_comp_out + if(ad_cal_comp_out_init == 1) + calibration_polarity = 1; + else @@ -431,7 +493,7 @@ + all_ana_cal_status = ANACAL_FINISH; + } else { + if((tabl_idx == 0)||(tabl_idx == 0x3f)) { -+ all_ana_cal_status = ANACAL_SATURATION; ++ all_ana_cal_status = ANACAL_SATURATION; // need to FT + printk( " GE Tx offset AnaCal Saturation! \r\n"); + } + } @@ -454,12 +516,12 @@ + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0183, 0x0000); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0184, 0x0000); + -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x0000); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0000); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x0000); // disable analog calibration circuit ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x0000); // disable analog calibration circuit ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0x0000); // disable Tx VLD force mode ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0000); // disable Tx offset/amplitude calibration circuit +} + +int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay) @@ -470,11 +532,11 @@ + u32 tx_amp_reg_shift; + u16 reg_temp; + u32 tx_amp_temp, tx_amp_reg, cnt=0, tx_amp_reg_100; -+ u32 reg_backup, reg_tmp; -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x1100); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0001); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e1, 0x0010); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0xf808); ++ u32 debug_tmp, reg_backup, reg_tmp; ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x1100); // 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0001); // 1e_dc[0]:rg_txvos_calen ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00e1, 0x0010); // 1e_e1[4]:select 1V ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0xf808); // 1e_3e:enable Tx VLD + + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x11, 0xff00); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x27a, 0x33); @@ -483,36 +545,36 @@ + for(i = 0; i <= 4; i++) + tc_phy_write_dev_reg(gsw, i, 0x1e, 0x00dd, 0x0000); + for(calibration_pair = ANACAL_PAIR_A; calibration_pair <= ANACAL_PAIR_D; calibration_pair ++) { -+ tx_amp_temp = 0x20; ++ tx_amp_temp = 0x20; // start with 0 dB + + if(calibration_pair == ANACAL_PAIR_A) { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x1000); // 1e_dd[12] -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_2V)); // 1e_17d -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_2V)); // 1e_181 ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x1000); // 1e_dd[12]:tx_a amp calibration enable ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017d, (0x8000|DAC_IN_2V)); // 1e_17d:dac_in0_a ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0181, (0x8000|DAC_IN_2V)); // 1e_181:dac_in1_a + reg_temp = (tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x012) & (~0xfc00)); + tx_amp_reg_shift = 10; // 1e_12[15:10] + tx_amp_reg = 0x12; + tx_amp_reg_100 = 0x16; + } else if(calibration_pair == ANACAL_PAIR_B) { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0100); // 1e_dd[8] -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017e, (0x8000|DAC_IN_2V)); // 1e_17e -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0182, (0x8000|DAC_IN_2V)); // 1e_182 ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0100); // 1e_dd[8]:tx_b amp calibration enable ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017e, (0x8000|DAC_IN_2V)); // 1e_17e:dac_in0_b ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0182, (0x8000|DAC_IN_2V)); // 1e_182:dac_in1_b + reg_temp = (tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x017) & (~0x3f00)); + tx_amp_reg_shift = 8; // 1e_17[13:8] + tx_amp_reg = 0x17; + tx_amp_reg_100 = 0x18; + } else if(calibration_pair == ANACAL_PAIR_C) { -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0010); // 1e_dd[4] -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017f, (0x8000|DAC_IN_2V)); // 1e_17f -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0183, (0x8000|DAC_IN_2V)); // 1e_183 ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0010); // 1e_dd[4]:tx_c amp calibration enable ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x017f, (0x8000|DAC_IN_2V)); // 1e_17f:dac_in0_c ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0183, (0x8000|DAC_IN_2V)); // 1e_183:dac_in1_c + reg_temp = (tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x019) & (~0x3f00)); + tx_amp_reg_shift = 8; // 1e_19[13:8] + tx_amp_reg = 0x19; + tx_amp_reg_100 = 0x20; + } else { //if(calibration_pair == ANACAL_PAIR_D) -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0001); // 1e_dd[0] -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0180, (0x8000|DAC_IN_2V)); // 1e_180 -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0184, (0x8000|DAC_IN_2V)); // 1e_184 ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0001); // 1e_dd[0]:tx_d amp calibration enable ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0180, (0x8000|DAC_IN_2V)); // 1e_180:dac_in0_d ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x0184, (0x8000|DAC_IN_2V)); // 1e_184:dac_in1_d + reg_temp = (tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x021) & (~0x3f00)); + tx_amp_reg_shift = 8; // 1e_21[13:8] + tx_amp_reg = 0x21; @@ -527,7 +589,7 @@ + return -1; + } + -+ ad_cal_comp_out_init = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8] ++ ad_cal_comp_out_init = (tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0x017a)>>8) & 0x1; // 1e_17a[8]:ad_cal_comp_out + if(ad_cal_comp_out_init == 1) + calibration_polarity = -1; + else @@ -685,6 +747,7 @@ + reg_backup |= ((reg_tmp << 10) | (reg_tmp << 0)); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x12, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x12); ++ //printk("PORT[%d] 1e.012 = %x (OFFSET_1000M_PAIR_A)\n", phyaddr, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x16); + reg_tmp = ((reg_backup & 0x3f) >> 0); + reg_tmp -= 8; @@ -692,6 +755,7 @@ + reg_backup |= (reg_tmp << 0); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x16, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x16); ++ //printk("PORT[%d] 1e.016 = %x (OFFSET_TESTMODE_1000M_PAIR_A)\n", phyaddr, reg_backup); + } + else if(calibration_pair == ANACAL_PAIR_B){ + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x17); @@ -701,6 +765,7 @@ + reg_backup |= ((reg_tmp << 8) | (reg_tmp << 0)); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x17, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x17); ++ //printk("PORT[%d] 1e.017 = %x (OFFSET_1000M_PAIR_B)\n", phyaddr, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x18); + reg_tmp = ((reg_backup & 0x3f) >> 0); + reg_tmp -= 8; @@ -708,6 +773,7 @@ + reg_backup |= (reg_tmp << 0); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x18, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x18); ++ //printk("PORT[%d] 1e.018 = %x (OFFSET_TESTMODE_1000M_PAIR_B)\n", phyaddr, reg_backup); + } + else if(calibration_pair == ANACAL_PAIR_C){ + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x19); @@ -717,6 +783,7 @@ + reg_backup |= (reg_tmp << 8); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x19, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x19); ++ //printk("PORT[%d] 1e.019 = %x (OFFSET_1000M_PAIR_C)\n", phyaddr, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x20); + reg_tmp = ((reg_backup & 0x3f) >> 0); + reg_tmp -= 8; @@ -724,6 +791,7 @@ + reg_backup |= (reg_tmp << 0); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x20, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x20); ++ //printk("PORT[%d] 1e.020 = %x (OFFSET_TESTMODE_1000M_PAIR_C)\n", phyaddr, reg_backup); + } + else if(calibration_pair == ANACAL_PAIR_D){ + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x21); @@ -733,6 +801,7 @@ + reg_backup |= (reg_tmp << 8); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x21, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x21); ++ //printk("PORT[%d] 1e.021 = %x (OFFSET_1000M_PAIR_D)\n", phyaddr, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x22); + reg_tmp = ((reg_backup & 0x3f) >> 0); + reg_tmp -= 8; @@ -740,12 +809,45 @@ + reg_backup |= (reg_tmp << 0); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x22, reg_backup); + reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x22); ++ //printk("PORT[%d] 1e.022 = %x (OFFSET_TESTMODE_1000M_PAIR_D)\n", phyaddr, reg_backup); + } ++ ++ if (calibration_pair == ANACAL_PAIR_A){ ++ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x12); ++ //printk("1e.012 = 0x%x\n", debug_tmp); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x16); ++ //printk("1e.016 = 0x%x\n", debug_tmp); ++ } ++ ++ else if(calibration_pair == ANACAL_PAIR_B){ ++ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x17); ++ //printk("1e.017 = 0x%x\n", debug_tmp); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x18); ++ //printk("1e.018 = 0x%x\n", debug_tmp); ++ } ++ else if(calibration_pair == ANACAL_PAIR_C){ ++ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x19); ++ //printk("1e.019 = 0x%x\n", debug_tmp); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x20); ++ //printk("1e.020 = 0x%x\n", debug_tmp); ++ } ++ else if(calibration_pair == ANACAL_PAIR_D){ ++ //printk("PORT (%d) TX_AMP PAIR (A) FINAL CALIBRATION RESULT\n", phyaddr); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x21); ++ //printk("1e.021 = 0x%x\n", debug_tmp); ++ debug_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x22); ++ //printk("1e.022 = 0x%x\n", debug_tmp); ++ } ++ ++ + printk( " GE Tx amp AnaCal Done! (pair-%d)(1e_%x = 0x%x)\n", calibration_pair, tx_amp_reg, tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, tx_amp_reg)); + + } else { + if((tx_amp_temp == 0x3f)||(tx_amp_temp == 0x00)) { -+ all_ana_cal_status = ANACAL_SATURATION; ++ all_ana_cal_status = ANACAL_SATURATION; // need to FT + printk( " GE Tx amp AnaCal Saturation! \r\n"); + } + } @@ -767,11 +869,11 @@ + + /* disable analog calibration circuit */ + tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00db, 0x0000); -+ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0x0000); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0000); ++ tc_phy_write_dev_reg(gsw, PHY0, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00db, 0x0000); // disable analog calibration circuit ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dc, 0x0000); // disable Tx offset calibration circuit ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x003e, 0x0000); // disable Tx VLD force mode ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x00dd, 0x0000); // disable Tx offset/amplitude calibration circuit + + + @@ -788,18 +890,28 @@ + u32 reg_tmp,reg_tmp0, reg_tmp1, i; + u32 CALDLY = 40; + int ret; ++ /* set [12]AN disable, [8]full duplex, [13/6]1000Mbps */ ++ //tc_phy_write_dev_reg(phyaddr, 0x0, 0x0140); + switch_phy_write(gsw, phyaddr, R0, 0x140); + -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x145, 0x1010); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, RG_185, 0); -+ tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x100, 0xc000); -+ //tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x403, 0x1099); ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x145, 0x1010);/* fix mdi */ ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, RG_185, 0);/* disable tx slew control */ ++ tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x100, 0xc000);/* BG voltage output */ ++ //tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x403, 0x1099); //bypass efuse + +#if (1) ++ // 1f_27c[12:8] cr_da_tx_i2mpb_10m Trimming TX bias setup(@10M) + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x27c, 0x1f1f); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x27c, 0x3300); + + reg_tmp1 = tc_phy_read_dev_reg(gsw, PHY0, 0x1f, 0x27c); ++ //dev1Fh_reg273h TXVLD DA register - Adjust voltage mode TX amplitude. ++ //tc_phy_write_dev_reg(phyaddr, 0x1f, 0x273, 0); ++ //tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x273, 0x1000); ++ //reg_tmp1 = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x273); ++ //printk("reg_tmp1273 = %x\n", reg_tmp1); ++ /*1e_11 TX overshoot Enable (PAIR A/B/C/D) in gbe mode*/ ++ + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x11); + reg_tmp = reg_tmp | (0xf << 12); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x11, reg_tmp); @@ -856,11 +968,13 @@ + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x18e, 0x0001); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x18f, 0x0001); + ++ /*da_tx_bias1_b_tx_standby = 5'b10 (dev1eh_reg3aah[12:8])*/ + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x3aa); + reg_tmp = reg_tmp & ~(0x1f00); + reg_tmp = reg_tmp | 0x2 << 8; + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x3aa, reg_tmp); + ++ /*da_tx_bias1_a_tx_standby = 5'b10 (dev1eh_reg3a9h[4:0])*/ + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x3a9); + reg_tmp = reg_tmp & ~(0x1f); + reg_tmp = reg_tmp | 0x2; @@ -872,7 +986,7 @@ +{ + u32 reg_tmp1; + -+ //pr_info("PORT %d RX_DC_OFFSET\n", phyaddr); ++ pr_info("PORT %d RX_DC_OFFSET\n", phyaddr); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x96, 0x8000); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x37, 0x3); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x107, 0x4000); @@ -892,11 +1006,13 @@ + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x114f); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("before pairA output = %x\n", reg_tmp); + udelay(40); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1142); + udelay(40); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("after pairA output = %x\n", reg_tmp); + if ((reg_tmp & 0x80) != 0) + reg_tmp = (~reg_tmp) + 1; + if ((reg_tmp & 0xff) >4) @@ -911,11 +1027,13 @@ + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1151); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("before pairB output = %x\n", reg_tmp); + udelay(40); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1143); + udelay(40); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("after pairB output = %x\n", reg_tmp); + if ((reg_tmp & 0x80) != 0) + reg_tmp = (~reg_tmp) + 1; + if ((reg_tmp & 0xff) >4) @@ -930,11 +1048,13 @@ + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1153); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("before pairC output = %x\n", reg_tmp); + udelay(40); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1144); + udelay(40); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("after pairC output = %x\n", reg_tmp); + if ((reg_tmp & 0x80) != 0) + reg_tmp = (~reg_tmp) + 1; + if ((reg_tmp & 0xff) >4) @@ -949,11 +1069,13 @@ + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1155); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("before pairD output = %x\n", reg_tmp); + udelay(40); + tc_phy_write_dev_reg(gsw, phyaddr, 0x1f, 0x15, (phyaddr << 13) | 0x1145); + udelay(40); + reg_tmp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1f, 0x1a); + reg_tmp = reg_tmp & 0xff; ++ pr_info("after pairD output = %x\n", reg_tmp); + if ((reg_tmp & 0x80) != 0) + reg_tmp = (~reg_tmp) + 1; + if ((reg_tmp & 0xff) >4) diff --git a/target/linux/mediatek/patches-4.19/0101-pci-mediatek-backport-fix-pcie.patch b/target/linux/mediatek/patches-4.19/0101-pci-mediatek-backport-fix-pcie.patch new file mode 100644 index 0000000000..bf7c1ea32b --- /dev/null +++ b/target/linux/mediatek/patches-4.19/0101-pci-mediatek-backport-fix-pcie.patch @@ -0,0 +1,534 @@ +diff -urN a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c +--- a/drivers/clk/clk-devres.c 2019-08-29 16:59:26.540010395 +0800 ++++ b/drivers/clk/clk-devres.c 2019-08-29 17:02:09.215924786 +0800 +@@ -34,6 +34,17 @@ + } + EXPORT_SYMBOL(devm_clk_get); + ++struct clk *devm_clk_get_optional(struct device *dev, const char *id) ++{ ++ struct clk *clk = devm_clk_get(dev, id); ++ ++ if (clk == ERR_PTR(-ENOENT)) ++ return NULL; ++ ++ return clk; ++} ++EXPORT_SYMBOL(devm_clk_get_optional); ++ + struct clk_bulk_devres { + struct clk_bulk_data *clks; + int num_clks; +diff -urN a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c +--- a/drivers/pci/controller/pcie-mediatek.c 2019-08-29 16:59:10.520410188 +0800 ++++ b/drivers/pci/controller/pcie-mediatek.c 2019-08-29 17:01:58.340199243 +0800 +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -162,6 +163,7 @@ + * @phy: pointer to PHY control block + * @lane: lane count + * @slot: port slot ++ * @irq: GIC irq + * @irq_domain: legacy INTx IRQ domain + * @inner_domain: inner IRQ domain + * @msi_domain: MSI IRQ domain +@@ -182,6 +184,7 @@ + struct phy *phy; + u32 lane; + u32 slot; ++ int irq; + struct irq_domain *irq_domain; + struct irq_domain *inner_domain; + struct irq_domain *msi_domain; +@@ -225,10 +228,8 @@ + + clk_disable_unprepare(pcie->free_ck); + +- if (dev->pm_domain) { +- pm_runtime_put_sync(dev); +- pm_runtime_disable(dev); +- } ++ pm_runtime_put_sync(dev); ++ pm_runtime_disable(dev); + } + + static void mtk_pcie_port_free(struct mtk_pcie_port *port) +@@ -394,75 +395,6 @@ + .write = mtk_pcie_config_write, + }; + +-static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) +-{ +- struct mtk_pcie *pcie = port->pcie; +- struct resource *mem = &pcie->mem; +- const struct mtk_pcie_soc *soc = port->pcie->soc; +- u32 val; +- size_t size; +- int err; +- +- /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ +- if (pcie->base) { +- val = readl(pcie->base + PCIE_SYS_CFG_V2); +- val |= PCIE_CSR_LTSSM_EN(port->slot) | +- PCIE_CSR_ASPM_L1_EN(port->slot); +- writel(val, pcie->base + PCIE_SYS_CFG_V2); +- } +- +- /* Assert all reset signals */ +- writel(0, port->base + PCIE_RST_CTRL); +- +- /* +- * Enable PCIe link down reset, if link status changed from link up to +- * link down, this will reset MAC control registers and configuration +- * space. +- */ +- writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); +- +- /* De-assert PHY, PE, PIPE, MAC and configuration reset */ +- val = readl(port->base + PCIE_RST_CTRL); +- val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | +- PCIE_MAC_SRSTB | PCIE_CRSTB; +- writel(val, port->base + PCIE_RST_CTRL); +- +- /* Set up vendor ID and class code */ +- if (soc->need_fix_class_id) { +- val = PCI_VENDOR_ID_MEDIATEK; +- writew(val, port->base + PCIE_CONF_VEND_ID); +- +- val = PCI_CLASS_BRIDGE_HOST; +- writew(val, port->base + PCIE_CONF_CLASS_ID); +- } +- +- /* 100ms timeout value should be enough for Gen1/2 training */ +- err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val, +- !!(val & PCIE_PORT_LINKUP_V2), 20, +- 100 * USEC_PER_MSEC); +- if (err) +- return -ETIMEDOUT; +- +- /* Set INTx mask */ +- val = readl(port->base + PCIE_INT_MASK); +- val &= ~INTX_MASK; +- writel(val, port->base + PCIE_INT_MASK); +- +- /* Set AHB to PCIe translation windows */ +- size = mem->end - mem->start; +- val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size)); +- writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); +- +- val = upper_32_bits(mem->start); +- writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); +- +- /* Set PCIe to AXI translation memory space.*/ +- val = fls(0xffffffff) | WIN_ENABLE; +- writel(val, port->base + PCIE_AXI_WINDOW0); +- +- return 0; +-} +- + static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) + { + struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data); +@@ -601,6 +533,27 @@ + writel(val, port->base + PCIE_INT_MASK); + } + ++static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie) ++{ ++ struct mtk_pcie_port *port, *tmp; ++ ++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) { ++ irq_set_chained_handler_and_data(port->irq, NULL, NULL); ++ ++ if (port->irq_domain) ++ irq_domain_remove(port->irq_domain); ++ ++ if (IS_ENABLED(CONFIG_PCI_MSI)) { ++ if (port->msi_domain) ++ irq_domain_remove(port->msi_domain); ++ if (port->inner_domain) ++ irq_domain_remove(port->inner_domain); ++ } ++ ++ irq_dispose_mapping(port->irq); ++ } ++} ++ + static int mtk_pcie_intx_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) + { +@@ -630,6 +583,7 @@ + + port->irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, + &intx_domain_ops, port); ++ of_node_put(pcie_intc_node); + if (!port->irq_domain) { + dev_err(dev, "failed to get INTx IRQ domain\n"); + return -ENODEV; +@@ -639,8 +593,6 @@ + ret = mtk_pcie_allocate_msi_domains(port); + if (ret) + return ret; +- +- mtk_pcie_enable_msi(port); + } + + return 0; +@@ -693,7 +645,7 @@ + struct mtk_pcie *pcie = port->pcie; + struct device *dev = pcie->dev; + struct platform_device *pdev = to_platform_device(dev); +- int err, irq; ++ int err; + + err = mtk_pcie_init_irq_domain(port, node); + if (err) { +@@ -701,8 +653,81 @@ + return err; + } + +- irq = platform_get_irq(pdev, port->slot); +- irq_set_chained_handler_and_data(irq, mtk_pcie_intr_handler, port); ++ port->irq = platform_get_irq(pdev, port->slot); ++ irq_set_chained_handler_and_data(port->irq, ++ mtk_pcie_intr_handler, port); ++ ++ return 0; ++} ++ ++static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) ++{ ++ struct mtk_pcie *pcie = port->pcie; ++ struct resource *mem = &pcie->mem; ++ const struct mtk_pcie_soc *soc = port->pcie->soc; ++ u32 val; ++ size_t size; ++ int err; ++ ++ /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ ++ if (pcie->base) { ++ val = readl(pcie->base + PCIE_SYS_CFG_V2); ++ val |= PCIE_CSR_LTSSM_EN(port->slot) | ++ PCIE_CSR_ASPM_L1_EN(port->slot); ++ writel(val, pcie->base + PCIE_SYS_CFG_V2); ++ } ++ ++ /* Assert all reset signals */ ++ writel(0, port->base + PCIE_RST_CTRL); ++ ++ /* ++ * Enable PCIe link down reset, if link status changed from link up to ++ * link down, this will reset MAC control registers and configuration ++ * space. ++ */ ++ writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL); ++ ++ /* De-assert PHY, PE, PIPE, MAC and configuration reset */ ++ val = readl(port->base + PCIE_RST_CTRL); ++ val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB | ++ PCIE_MAC_SRSTB | PCIE_CRSTB; ++ writel(val, port->base + PCIE_RST_CTRL); ++ ++ /* Set up vendor ID and class code */ ++ if (soc->need_fix_class_id) { ++ val = PCI_VENDOR_ID_MEDIATEK; ++ writew(val, port->base + PCIE_CONF_VEND_ID); ++ ++ val = PCI_CLASS_BRIDGE_PCI; ++ writew(val, port->base + PCIE_CONF_CLASS_ID); ++ } ++ ++ /* 100ms timeout value should be enough for Gen1/2 training */ ++ err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val, ++ !!(val & PCIE_PORT_LINKUP_V2), 20, ++ 100 * USEC_PER_MSEC); ++ if (err) ++ return -ETIMEDOUT; ++ ++ /* Set INTx mask */ ++ val = readl(port->base + PCIE_INT_MASK); ++ val &= ~INTX_MASK; ++ writel(val, port->base + PCIE_INT_MASK); ++ ++ if (IS_ENABLED(CONFIG_PCI_MSI)) ++ mtk_pcie_enable_msi(port); ++ ++ /* Set AHB to PCIe translation windows */ ++ size = mem->end - mem->start; ++ val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size)); ++ writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); ++ ++ val = upper_32_bits(mem->start); ++ writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); ++ ++ /* Set PCIe to AXI translation memory space.*/ ++ val = fls(0xffffffff) | WIN_ENABLE; ++ writel(val, port->base + PCIE_AXI_WINDOW0); + + return 0; + } +@@ -903,49 +928,29 @@ + + /* sys_ck might be divided into the following parts in some chips */ + snprintf(name, sizeof(name), "ahb_ck%d", slot); +- port->ahb_ck = devm_clk_get(dev, name); +- if (IS_ERR(port->ahb_ck)) { +- if (PTR_ERR(port->ahb_ck) == -EPROBE_DEFER) +- return -EPROBE_DEFER; +- +- port->ahb_ck = NULL; +- } ++ port->ahb_ck = devm_clk_get_optional(dev, name); ++ if (IS_ERR(port->ahb_ck)) ++ return PTR_ERR(port->ahb_ck); + + snprintf(name, sizeof(name), "axi_ck%d", slot); +- port->axi_ck = devm_clk_get(dev, name); +- if (IS_ERR(port->axi_ck)) { +- if (PTR_ERR(port->axi_ck) == -EPROBE_DEFER) +- return -EPROBE_DEFER; +- +- port->axi_ck = NULL; +- } ++ port->axi_ck = devm_clk_get_optional(dev, name); ++ if (IS_ERR(port->axi_ck)) ++ return PTR_ERR(port->axi_ck); + + snprintf(name, sizeof(name), "aux_ck%d", slot); +- port->aux_ck = devm_clk_get(dev, name); +- if (IS_ERR(port->aux_ck)) { +- if (PTR_ERR(port->aux_ck) == -EPROBE_DEFER) +- return -EPROBE_DEFER; +- +- port->aux_ck = NULL; +- } ++ port->aux_ck = devm_clk_get_optional(dev, name); ++ if (IS_ERR(port->aux_ck)) ++ return PTR_ERR(port->aux_ck); + + snprintf(name, sizeof(name), "obff_ck%d", slot); +- port->obff_ck = devm_clk_get(dev, name); +- if (IS_ERR(port->obff_ck)) { +- if (PTR_ERR(port->obff_ck) == -EPROBE_DEFER) +- return -EPROBE_DEFER; +- +- port->obff_ck = NULL; +- } ++ port->obff_ck = devm_clk_get_optional(dev, name); ++ if (IS_ERR(port->obff_ck)) ++ return PTR_ERR(port->obff_ck); + + snprintf(name, sizeof(name), "pipe_ck%d", slot); +- port->pipe_ck = devm_clk_get(dev, name); +- if (IS_ERR(port->pipe_ck)) { +- if (PTR_ERR(port->pipe_ck) == -EPROBE_DEFER) +- return -EPROBE_DEFER; +- +- port->pipe_ck = NULL; +- } ++ port->pipe_ck = devm_clk_get_optional(dev, name); ++ if (IS_ERR(port->pipe_ck)) ++ return PTR_ERR(port->pipe_ck); + + snprintf(name, sizeof(name), "pcie-rst%d", slot); + port->reset = devm_reset_control_get_optional_exclusive(dev, name); +@@ -998,10 +1003,8 @@ + pcie->free_ck = NULL; + } + +- if (dev->pm_domain) { +- pm_runtime_enable(dev); +- pm_runtime_get_sync(dev); +- } ++ pm_runtime_enable(dev); ++ pm_runtime_get_sync(dev); + + /* enable top level clock */ + err = clk_prepare_enable(pcie->free_ck); +@@ -1013,10 +1016,8 @@ + return 0; + + err_free_ck: +- if (dev->pm_domain) { +- pm_runtime_put_sync(dev); +- pm_runtime_disable(dev); +- } ++ pm_runtime_put_sync(dev); ++ pm_runtime_disable(dev); + + return err; + } +@@ -1125,34 +1126,6 @@ + return 0; + } + +-static int mtk_pcie_register_host(struct pci_host_bridge *host) +-{ +- struct mtk_pcie *pcie = pci_host_bridge_priv(host); +- struct pci_bus *child; +- int err; +- +- host->busnr = pcie->busn.start; +- host->dev.parent = pcie->dev; +- host->ops = pcie->soc->ops; +- host->map_irq = of_irq_parse_and_map_pci; +- host->swizzle_irq = pci_common_swizzle; +- host->sysdata = pcie; +- +- err = pci_scan_root_bus_bridge(host); +- if (err < 0) +- return err; +- +- pci_bus_size_bridges(host->bus); +- pci_bus_assign_resources(host->bus); +- +- list_for_each_entry(child, &host->bus->children, node) +- pcie_bus_configure_settings(child); +- +- pci_bus_add_devices(host->bus); +- +- return 0; +-} +- + static int mtk_pcie_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -1179,7 +1152,14 @@ + if (err) + goto put_resources; + +- err = mtk_pcie_register_host(host); ++ host->busnr = pcie->busn.start; ++ host->dev.parent = pcie->dev; ++ host->ops = pcie->soc->ops; ++ host->map_irq = of_irq_parse_and_map_pci; ++ host->swizzle_irq = pci_common_swizzle; ++ host->sysdata = pcie; ++ ++ err = pci_host_probe(host); + if (err) + goto put_resources; + +@@ -1192,6 +1172,80 @@ + return err; + } + ++ ++static void mtk_pcie_free_resources(struct mtk_pcie *pcie) ++{ ++ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); ++ struct list_head *windows = &host->windows; ++ ++ pci_free_resource_list(windows); ++} ++ ++static int mtk_pcie_remove(struct platform_device *pdev) ++{ ++ struct mtk_pcie *pcie = platform_get_drvdata(pdev); ++ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); ++ ++ pci_stop_root_bus(host->bus); ++ pci_remove_root_bus(host->bus); ++ mtk_pcie_free_resources(pcie); ++ ++ mtk_pcie_irq_teardown(pcie); ++ ++ mtk_pcie_put_resources(pcie); ++ ++ return 0; ++} ++ ++static int __maybe_unused mtk_pcie_suspend_noirq(struct device *dev) ++{ ++ struct mtk_pcie *pcie = dev_get_drvdata(dev); ++ struct mtk_pcie_port *port; ++ ++ if (list_empty(&pcie->ports)) ++ return 0; ++ ++ list_for_each_entry(port, &pcie->ports, list) { ++ clk_disable_unprepare(port->pipe_ck); ++ clk_disable_unprepare(port->obff_ck); ++ clk_disable_unprepare(port->axi_ck); ++ clk_disable_unprepare(port->aux_ck); ++ clk_disable_unprepare(port->ahb_ck); ++ clk_disable_unprepare(port->sys_ck); ++ phy_power_off(port->phy); ++ phy_exit(port->phy); ++ } ++ ++ clk_disable_unprepare(pcie->free_ck); ++ ++ return 0; ++} ++ ++static int __maybe_unused mtk_pcie_resume_noirq(struct device *dev) ++{ ++ struct mtk_pcie *pcie = dev_get_drvdata(dev); ++ struct mtk_pcie_port *port, *tmp; ++ ++ if (list_empty(&pcie->ports)) ++ return 0; ++ ++ clk_prepare_enable(pcie->free_ck); ++ ++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) ++ mtk_pcie_enable_port(port); ++ ++ /* In case of EP was removed while system suspend. */ ++ if (list_empty(&pcie->ports)) ++ clk_disable_unprepare(pcie->free_ck); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops mtk_pcie_pm_ops = { ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_pcie_suspend_noirq, ++ mtk_pcie_resume_noirq) ++}; ++ + static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { + .ops = &mtk_pcie_ops, + .startup = mtk_pcie_startup_port, +@@ -1220,10 +1274,13 @@ + + static struct platform_driver mtk_pcie_driver = { + .probe = mtk_pcie_probe, ++ .remove = mtk_pcie_remove, + .driver = { + .name = "mtk-pcie", + .of_match_table = mtk_pcie_ids, + .suppress_bind_attrs = true, ++ .pm = &mtk_pcie_pm_ops, + }, + }; +-builtin_platform_driver(mtk_pcie_driver); ++module_platform_driver(mtk_pcie_driver); ++MODULE_LICENSE("GPL v2"); +diff -urN a/include/linux/clk.h b/include/linux/clk.h +--- a/include/linux/clk.h 2019-08-29 16:59:52.335365591 +0800 ++++ b/include/linux/clk.h 2019-08-29 17:02:17.107725525 +0800 +@@ -349,6 +349,17 @@ + struct clk *devm_clk_get(struct device *dev, const char *id); + + /** ++ * devm_clk_get_optional - lookup and obtain a managed reference to an optional ++ * clock producer. ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Behaves the same as devm_clk_get() except where there is no clock producer. ++ * In this case, instead of returning -ENOENT, the function returns NULL. ++ */ ++struct clk *devm_clk_get_optional(struct device *dev, const char *id); ++ ++/** + * devm_get_clk_from_child - lookup and obtain a managed reference to a + * clock producer from child node. + * @dev: device for clock "consumer" From daf22267effa27d18279e24d7162886cabcac13f Mon Sep 17 00:00:00 2001 From: LEAN-ESX Date: Thu, 5 Sep 2019 22:06:03 -0700 Subject: [PATCH 4/4] UnblockNeteaseMusic: bump to v0.19.1 --- package/lean/UnblockNeteaseMusic/Makefile | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/package/lean/UnblockNeteaseMusic/Makefile b/package/lean/UnblockNeteaseMusic/Makefile index afeea6cbdf..6cd0404bc4 100644 --- a/package/lean/UnblockNeteaseMusic/Makefile +++ b/package/lean/UnblockNeteaseMusic/Makefile @@ -11,15 +11,19 @@ include $(TOPDIR)/rules.mk PKG_NAME:=UnblockNeteaseMusic -PKG_VERSION:=0.17.0 -PKG_RELEASE:=5 +PKG_VERSION:=0.19.0 +PKG_RELEASE:=1 PKG_LICENSE:=MIT -PKG_SOURCE_URL:=https://github.com/nondanee/UnblockNeteaseMusic/archive/ -PKG_SOURCE:=v$(PKG_VERSION).tar.gz -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) -PKG_HASH:=skip +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/nondanee/UnblockNeteaseMusic.git +PKG_SOURCE_VERSION:=e35b6b9a5f7619713d1707b82bc844ae688dd678 + +PKG_SOURCE_SUBDIR:=$(PKG_NAME) +PKG_SOURCE:=$(PKG_SOURCE_SUBDIR)-$(PKG_VERSION).tar.gz +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) +PKG_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/package.mk @@ -48,7 +52,7 @@ endef define Package/$(PKG_NAME)/install $(INSTALL_DIR) $(1)/usr/share/$(PKG_NAME) - cp -pR $(PKG_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/* $(1)/usr/share/$(PKG_NAME) + cp -pR $(PKG_BUILD_DIR)/$(PKG_NAME)/* $(1)/usr/share/$(PKG_NAME) endef $(eval $(call BuildPackage,$(PKG_NAME))) \ No newline at end of file