Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
fa59b42f0d
@ -7,11 +7,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=imx-bootlets
|
||||
PKG_VERSION:=10.05.02
|
||||
PKG_VERSION:=10.12.01
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://trabant.uid0.hu/openwrt/
|
||||
PKG_HASH:=09ecd81a64db5166a235932146faf08d0689bfc7ac04ac9fcc3a5bd809fba74a
|
||||
PKG_HASH:=f7c98cbc41e15184cad61c56115e840e34ac3ebb4a162fadeea905e5038fd65b
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
@ -37,7 +37,7 @@ define Package/imx-bootlets/install
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/boot_prep/boot_prep $(STAGING_DIR)/boot_prep
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_prep/output-target/linux_prep $(STAGING_DIR)/linux_prep
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/power_prep/power_prep $(STAGING_DIR)/power_prep
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_prebuilt.db $(STAGING_DIR)/linux_prebuilt.db
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linux_ivt.bd $(STAGING_DIR)/linux_ivt.bd
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,imx-bootlets))
|
||||
|
@ -1,18 +1,22 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -32,10 +32,11 @@ ifeq "$(DFT_IMAGE)" "$(wildcard $(DFT_IM
|
||||
sed -i 's,[^ *]image.*;,\timage="$(DFT_UBOOT)";,' uboot.db
|
||||
elftosb2 -z -c ./uboot.db -o i$(ARCH)_uboot.sb
|
||||
@@ -37,13 +37,13 @@ ifeq "$(DFT_IMAGE)" "$(wildcard $(DFT_IM
|
||||
elftosb -z -c ./uboot.bd -o i$(ARCH)_uboot.sb
|
||||
elftosb -z -f imx28 -c ./uboot_ivt.bd -o i$(ARCH)_ivt_uboot.sb
|
||||
else
|
||||
- @echo "by using the pre-built kernel"
|
||||
- elftosb2 -z -c ./linux_prebuilt.db -o i$(ARCH)_linux.sb
|
||||
- @echo "generating U-Boot boot stream image"
|
||||
- elftosb2 -z -c ./uboot_prebuilt.db -o i$(ARCH)_uboot.sb
|
||||
- elftosb -z -c ./linux.bd -o i$(ARCH)_linux.sb
|
||||
- elftosb -z -f imx28 -c ./linux_ivt.bd -o i$(ARCH)_ivt_linux.sb
|
||||
+ @echo "... not generating any image for now."
|
||||
+ #@echo "by using the pre-built kernel"
|
||||
+ #elftosb2 -z -c ./linux_prebuilt.db -o i$(ARCH)_linux.sb
|
||||
+ #elftosb -z -c ./linux.bd -o i$(ARCH)_linux.sb
|
||||
+ #elftosb -z -f imx28 -c ./linux_ivt.bd -o i$(ARCH)_ivt_linux.sb
|
||||
|
||||
- @echo "generating U-Boot boot stream image"
|
||||
- elftosb -z -c ./uboot.bd -o i$(ARCH)_uboot.sb
|
||||
- elftosb -z -f imx28 -c ./uboot_ivt.bd -o i$(ARCH)_ivt_uboot.sb
|
||||
+ #@echo "generating U-Boot boot stream image"
|
||||
+ #elftosb2 -z -c ./uboot_prebuilt.db -o i$(ARCH)_uboot.sb
|
||||
+ #elftosb -z -c ./uboot.bd -o i$(ARCH)_uboot.sb
|
||||
+ #elftosb -z -f imx28 -c ./uboot_ivt.bd -o i$(ARCH)_ivt_uboot.sb
|
||||
endif
|
||||
#@echo "generating kernel bootstream file sd_mmc_bootstream.raw"
|
||||
#Please use cfimager to burn xxx_linux.sb. The below way will no
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- a/linux_prebuilt.db
|
||||
+++ b/linux_prebuilt.db
|
||||
--- a/linux_ivt.bd
|
||||
+++ b/linux_ivt.bd
|
||||
@@ -4,10 +4,10 @@ options {
|
||||
flags = 0x01;
|
||||
}
|
||||
@ -7,11 +7,11 @@
|
||||
- power_prep="./power_prep/power_prep";
|
||||
- sdram_prep="./boot_prep/boot_prep";
|
||||
- linux_prep="./linux_prep/output-target/linux_prep";
|
||||
- zImage = "./zImage";
|
||||
- zImage="./zImage";
|
||||
+ power_prep="./power_prep";
|
||||
+ sdram_prep="./boot_prep";
|
||||
+ linux_prep="./linux_prep";
|
||||
+ zImage = "./zImage_dtb";
|
||||
+ zImage="./zImage_dtb";
|
||||
}
|
||||
|
||||
section (0) {
|
||||
|
@ -121,7 +121,7 @@
|
||||
|
||||
all: build_prep gen_bootstream
|
||||
|
||||
@@ -94,6 +97,8 @@ distclean: clean
|
||||
@@ -101,6 +104,8 @@ distclean: clean
|
||||
clean:
|
||||
-rm -rf *.sb
|
||||
rm -f sd_mmc_bootstream.raw
|
||||
@ -130,14 +130,3 @@
|
||||
$(MAKE) -C linux_prep clean ARCH=$(ARCH)
|
||||
$(MAKE) -C boot_prep clean ARCH=$(ARCH)
|
||||
$(MAKE) -C power_prep clean ARCH=$(ARCH)
|
||||
--- a/uboot.db
|
||||
+++ b/uboot.db
|
||||
@@ -3,7 +3,7 @@
|
||||
sources {
|
||||
power_prep="./power_prep/power_prep";
|
||||
sdram_prep="./boot_prep/boot_prep";
|
||||
- image="/home/b18647/repos/ltib_latest/rootfs/boot/u-boot";
|
||||
+ image="../boot/u-boot";
|
||||
}
|
||||
|
||||
section (0) {
|
||||
|
11
package/boot/imx-bootlets/patches/004-fix-ARM-8933_1.patch
Normal file
11
package/boot/imx-bootlets/patches/004-fix-ARM-8933_1.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/linux_prep/core/cmdlines.S
|
||||
+++ b/linux_prep/core/cmdlines.S
|
||||
@@ -14,7 +14,7 @@
|
||||
#define CMDLINES_FILE "output-target/command_lines_stripped.txt"
|
||||
#endif
|
||||
|
||||
- .section .cmdlines, #alloc
|
||||
+ .section .cmdlines, "a"
|
||||
.globl cmdlines_start
|
||||
cmdlines_start:
|
||||
.incbin CMDLINES_FILE
|
22
package/boot/uboot-envtools/files/qualcommax_ipq50xx
Normal file
22
package/boot/uboot-envtools/files/qualcommax_ipq50xx
Normal file
@ -0,0 +1,22 @@
|
||||
[ -e /etc/config/ubootenv ] && exit 0
|
||||
|
||||
touch /etc/config/ubootenv
|
||||
|
||||
. /lib/uboot-envtools.sh
|
||||
. /lib/functions.sh
|
||||
|
||||
board=$(board_name)
|
||||
|
||||
case "$board" in
|
||||
linksys,mx2000|\
|
||||
linksys,mx5500)
|
||||
idx="$(find_mtd_index u_env)"
|
||||
[ -n "$idx" ] && \
|
||||
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x40000" "0x20000"
|
||||
;;
|
||||
esac
|
||||
|
||||
config_load ubootenv
|
||||
config_foreach ubootenv_add_app_config
|
||||
|
||||
exit 0
|
@ -25,6 +25,21 @@ include $(INCLUDE_DIR)/package.mk
|
||||
RSTRIP:=:
|
||||
STRIP:=:
|
||||
|
||||
ATH11K_LEGACY_FW_NAME:=ath11k-legacy-firmware
|
||||
ATH11K_LEGACY_FW_DATE:=2024-03-14
|
||||
ATH11K_LEGACY_FW_RELEASE:=795809c7
|
||||
ATH11K_LEGACY_FW_SUBDIR:=$(ATH11K_LEGACY_FW_NAME)-$(ATH11K_LEGACY_FW_DATE)~$(ATH11K_LEGACY_FW_RELEASE)
|
||||
ATH11K_LEGACY_FW_SOURCE=$(ATH11K_LEGACY_FW_SUBDIR).tar.zst
|
||||
|
||||
define Download/$(ATH11K_LEGACY_FW_NAME)
|
||||
FILE:=$(ATH11K_LEGACY_FW_SOURCE)
|
||||
PROTO:=git
|
||||
URL:=https://github.com/quic/upstream-wifi-fw.git
|
||||
SOURCE_VERSION:=795809c7041582bd51bdfaa1f548b916ae8d4382
|
||||
MIRROR_HASH:=e042024b6762a5b4fe56f1a5bf8870df2e7abcca90ec22103cd46a609bee7cec
|
||||
SUBDIR:=$(ATH11K_LEGACY_FW_SUBDIR)
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-default
|
||||
SECTION:=firmware
|
||||
CATEGORY:=Firmware
|
||||
@ -32,6 +47,11 @@ define Package/ath11k-firmware-default
|
||||
DEPENDS:=
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-ipq5018
|
||||
$(Package/ath11k-firmware-default)
|
||||
TITLE:=IPQ5018 ath11k firmware
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-ipq6018
|
||||
$(Package/ath11k-firmware-default)
|
||||
TITLE:=IPQ6018 ath11k firmware
|
||||
@ -42,15 +62,43 @@ $(Package/ath11k-firmware-default)
|
||||
TITLE:=IPQ8074 ath11k firmware
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-qcn6122
|
||||
$(Package/ath11k-firmware-default)
|
||||
TITLE:=QCN6122 ath11k firmware
|
||||
DEPENDS:=ath11k-firmware-ipq5018
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-qcn9074
|
||||
$(Package/ath11k-firmware-default)
|
||||
TITLE:=QCN9074 ath11k firmware
|
||||
endef
|
||||
|
||||
define Build/Clean
|
||||
$(call Build/Clean/Default,)
|
||||
|
||||
rm -rf \
|
||||
$(BUILD_DIR)/$(ATH11K_LEGACY_FW_SUBDIR)
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(eval $(call Download,ath11k-legacy-firmware))
|
||||
|
||||
$(call Build/Prepare/Default,)
|
||||
|
||||
$(TAR) -C $(BUILD_DIR) -xf $(DL_DIR)/$(ATH11K_LEGACY_FW_SOURCE)
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-ipq5018/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/IPQ5018/hw1.0
|
||||
$(INSTALL_DATA) \
|
||||
$(BUILD_DIR)/$(ATH11K_LEGACY_FW_SUBDIR)/ath11k-firmware/IPQ5018_QCN6122_QCN6122/hw1.0/2.7.0.1/WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1/*.* \
|
||||
$(1)/lib/firmware/ath11k/IPQ5018/hw1.0/
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-ipq6018/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/IPQ6018
|
||||
$(INSTALL_DATA) \
|
||||
@ -65,6 +113,13 @@ define Package/ath11k-firmware-ipq8074/install
|
||||
$(1)/lib/firmware/IPQ8074/
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-qcn6122/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN6122/hw1.0
|
||||
$(INSTALL_DATA) \
|
||||
$(BUILD_DIR)/$(ATH11K_LEGACY_FW_SUBDIR)/ath11k-firmware/IPQ5018_QCN6122_QCN6122/hw1.0/2.7.0.1/WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1/qcn6122/* \
|
||||
$(1)/lib/firmware/ath11k/QCN6122/hw1.0/
|
||||
endef
|
||||
|
||||
define Package/ath11k-firmware-qcn9074/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/ath11k/QCN9074/hw1.0
|
||||
$(INSTALL_DATA) \
|
||||
@ -74,6 +129,8 @@ define Package/ath11k-firmware-qcn9074/install
|
||||
$(PKG_BUILD_DIR)/QCN9074/hw1.0/board-2.bin $(1)/lib/firmware/ath11k/QCN9074/hw1.0/board-2.bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ath11k-firmware-ipq5018))
|
||||
$(eval $(call BuildPackage,ath11k-firmware-ipq6018))
|
||||
$(eval $(call BuildPackage,ath11k-firmware-ipq8074))
|
||||
$(eval $(call BuildPackage,ath11k-firmware-qcn6122))
|
||||
$(eval $(call BuildPackage,ath11k-firmware-qcn9074))
|
||||
|
@ -39,8 +39,10 @@ ALLWIFIBOARDS:= \
|
||||
edimax_cax1800 \
|
||||
linksys_homewrk \
|
||||
linksys_mr7350 \
|
||||
linksys_mx2000 \
|
||||
linksys_mx4200 \
|
||||
linksys_mx5300 \
|
||||
linksys_mx5500 \
|
||||
linksys_mx8500 \
|
||||
linksys_whw03 \
|
||||
netgear_lbr20 \
|
||||
@ -102,14 +104,18 @@ define ipq-wifi-install-one
|
||||
$(call ipq-wifi-install-one-to,$(1),$(2),QCA9984/hw1.0),\
|
||||
$(if $(filter $(suffix $(1)),.QCA99X0 .qca99x0),\
|
||||
$(call ipq-wifi-install-one-to,$(1),$(2),QCA99X0/hw2.0),\
|
||||
$(if $(filter $(suffix $(1)),.IPQ5018 .ipq5018),\
|
||||
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),IPQ5018/hw1.0),\
|
||||
$(if $(filter $(suffix $(1)),.IPQ6018 .ipq6018),\
|
||||
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),IPQ6018/hw1.0),\
|
||||
$(if $(filter $(suffix $(1)),.IPQ8074 .ipq8074),\
|
||||
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),IPQ8074/hw2.0),\
|
||||
$(if $(filter $(suffix $(1)),.QCN6122 .qcn6122),\
|
||||
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),QCN6122/hw1.0),\
|
||||
$(if $(filter $(suffix $(1)),.QCN9074 .qcn9074),\
|
||||
$(call ipq-wifi-install-ath11-one-to,$(1),$(2),QCN9074/hw1.0),\
|
||||
$(error Unrecognized board-file suffix '$(suffix $(1))' for '$(1)')\
|
||||
))))))))
|
||||
))))))))))
|
||||
|
||||
endef
|
||||
# Blank line required at end of above define due to foreach context
|
||||
@ -171,8 +177,10 @@ $(eval $(call generate-ipq-wifi-package,edgecore_eap102,Edgecore EAP102))
|
||||
$(eval $(call generate-ipq-wifi-package,edimax_cax1800,Edimax CAX1800))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_homewrk,Linksys HomeWRK))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_mr7350,Linksys MR7350))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_mx2000,Linksys MX2000))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_mx4200,Linksys MX4200))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_mx5300,Linksys MX5300))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_mx5500,Linksys MX5500))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_mx8500,Linksys MX8500))
|
||||
$(eval $(call generate-ipq-wifi-package,linksys_whw03,Linksys WHW03))
|
||||
$(eval $(call generate-ipq-wifi-package,netgear_lbr20,Netgear LBR20))
|
||||
|
@ -637,6 +637,65 @@ endef
|
||||
|
||||
$(eval $(call KernelPackage,dsa-qca8k))
|
||||
|
||||
|
||||
define KernelPackage/dsa-realtek
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=Realtek common module RTL83xx DSA switch family
|
||||
DEPENDS:=+kmod-dsa +kmod-phy-realtek +kmod-regmap-core @!TARGET_x86 @!TARGET_bcm47xx @!TARGET_uml
|
||||
KCONFIG:= \
|
||||
CONFIG_NET_DSA_REALTEK \
|
||||
CONFIG_NET_DSA_REALTEK_MDIO=y \
|
||||
CONFIG_NET_DSA_REALTEK_SMI=y
|
||||
FILES:= $(LINUX_DIR)/drivers/net/dsa/realtek/realtek_dsa.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/dsa-realtek/description
|
||||
Common kernel module for Realtek RTL83xx DSA switch family
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,dsa-realtek))
|
||||
|
||||
|
||||
define KernelPackage/dsa-rtl8366rb
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=Realtek RTL8365MB switch DSA support
|
||||
DEPENDS:=+kmod-dsa-realtek @!TARGET_x86 @!TARGET_bcm47xx @!TARGET_uml
|
||||
KCONFIG:= \
|
||||
CONFIG_NET_DSA_REALTEK_RTL8366RB \
|
||||
CONFIG_NET_DSA_TAG_RTL4_A
|
||||
FILES:= \
|
||||
$(LINUX_DIR)/drivers/net/dsa/realtek/rtl8366.ko \
|
||||
$(LINUX_DIR)/net/dsa/tag_rtl4_a.ko
|
||||
AUTOLOAD:=$(call AutoLoad,42,rtl8366,1)
|
||||
endef
|
||||
|
||||
define KernelPackage/dsa-rtl8366rb/description
|
||||
DSA based kernel modules for the Realtek RTL8366RB switch family
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,dsa-rtl8366rb))
|
||||
|
||||
|
||||
define KernelPackage/dsa-rtl8365mb
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=Realtek RTL8365MB switch DSA support
|
||||
DEPENDS:=+kmod-dsa-realtek @!TARGET_x86 @!TARGET_bcm47xx @!TARGET_uml
|
||||
KCONFIG:= \
|
||||
CONFIG_NET_DSA_REALTEK_RTL8365MB \
|
||||
CONFIG_NET_DSA_TAG_RTL8_4
|
||||
FILES:= \
|
||||
$(LINUX_DIR)/drivers/net/dsa/realtek/rtl8365mb.ko \
|
||||
$(LINUX_DIR)/net/dsa/tag_rtl8_4.ko
|
||||
AUTOLOAD:=$(call AutoLoad,42,rtl8365mb,1)
|
||||
endef
|
||||
|
||||
define KernelPackage/dsa-rtl8365mb/description
|
||||
DSA based kernel modules for the Realtek RTL8365MB switch family
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,dsa-rtl8365mb))
|
||||
|
||||
|
||||
define KernelPackage/swconfig
|
||||
SUBMENU:=$(NETWORK_DEVICES_MENU)
|
||||
TITLE:=switch configuration API
|
||||
|
@ -0,0 +1,62 @@
|
||||
From 824dde8652815aa67b4e2bf2d8a9455a8ef82b8f Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Thu, 29 Jun 2023 06:12:45 +0000
|
||||
Subject: [PATCH] wifi: ath11k: Support setting bdf-addr and caldb-addr via DT
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -2028,6 +2028,7 @@ static int ath11k_qmi_assign_target_mem_
|
||||
struct device_node *hremote_node = NULL;
|
||||
struct resource res;
|
||||
u32 host_ddr_sz;
|
||||
+ u32 addr;
|
||||
int i, idx, ret;
|
||||
|
||||
for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
|
||||
@@ -2067,7 +2068,9 @@ static int ath11k_qmi_assign_target_mem_
|
||||
idx++;
|
||||
break;
|
||||
case BDF_MEM_REGION_TYPE:
|
||||
- ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
|
||||
+ if(of_property_read_u32(dev->of_node, "qcom,bdf-addr", &addr))
|
||||
+ addr = ab->hw_params.bdf_addr;
|
||||
+ ab->qmi.target_mem[idx].paddr = addr;
|
||||
ab->qmi.target_mem[idx].vaddr = NULL;
|
||||
ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
|
||||
ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
||||
@@ -2089,8 +2092,9 @@ static int ath11k_qmi_assign_target_mem_
|
||||
if (!ab->qmi.target_mem[idx].iaddr)
|
||||
return -EIO;
|
||||
} else {
|
||||
- ab->qmi.target_mem[idx].paddr =
|
||||
- ATH11K_QMI_CALDB_ADDRESS;
|
||||
+ if(of_property_read_u32(dev->of_node, "qcom,caldb-addr", &addr))
|
||||
+ addr = ATH11K_QMI_CALDB_ADDRESS;
|
||||
+ ab->qmi.target_mem[idx].paddr = addr;
|
||||
}
|
||||
} else {
|
||||
ab->qmi.target_mem[idx].paddr = 0;
|
||||
@@ -2292,6 +2296,7 @@ static int ath11k_qmi_load_file_target_m
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
struct qmi_txn txn;
|
||||
const u8 *temp = data;
|
||||
+ u32 addr;
|
||||
void __iomem *bdf_addr = NULL;
|
||||
int ret = 0;
|
||||
u32 remaining = len;
|
||||
@@ -2303,7 +2308,9 @@ static int ath11k_qmi_load_file_target_m
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
if (ab->hw_params.fixed_bdf_addr) {
|
||||
- bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
|
||||
+ if(of_property_read_u32(ab->dev->of_node, "qcom,bdf-addr", &addr))
|
||||
+ addr = ab->hw_params.bdf_addr;
|
||||
+ bdf_addr = ioremap(addr, ab->hw_params.fw.board_size);
|
||||
if (!bdf_addr) {
|
||||
ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");
|
||||
ret = -EIO;
|
@ -0,0 +1,153 @@
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Thu, 2 May 2024 00:14:31 +0800
|
||||
Subject: [PATCH] wifi: ath11k: fix remapped ce accessing issue on 64bit OS
|
||||
|
||||
On 64bit OS, when ab->mem_ce is lower than or 4G far away from ab->mem,
|
||||
u32 is not enough to store the offsets, which makes ath11k_ahb_read32()
|
||||
and ath11k_ahb_write32() access incorrect address and causes Data Abort
|
||||
Exception.
|
||||
|
||||
Let's use the high bits of offsets to decide where to access, which is
|
||||
similar as ath11k_pci_get_window_start() done. In the future, we can merge
|
||||
these functions for unified regs accessing.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
@@ -198,12 +198,18 @@ static const struct ath11k_pci_ops ath11
|
||||
|
||||
static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset)
|
||||
{
|
||||
- return ioread32(ab->mem + offset);
|
||||
+ if ((offset & ATH11K_REG_TYPE_MASK) == ATH11K_REG_TYPE_CE)
|
||||
+ return ioread32(ab->mem_ce + FIELD_GET(ATH11K_REG_OFFSET_MASK, offset));
|
||||
+ else
|
||||
+ return ioread32(ab->mem + FIELD_GET(ATH11K_REG_OFFSET_MASK, offset));
|
||||
}
|
||||
|
||||
static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value)
|
||||
{
|
||||
- iowrite32(value, ab->mem + offset);
|
||||
+ if ((offset & ATH11K_REG_TYPE_MASK) == ATH11K_REG_TYPE_CE)
|
||||
+ iowrite32(value, ab->mem_ce + FIELD_GET(ATH11K_REG_OFFSET_MASK, offset));
|
||||
+ else
|
||||
+ iowrite32(value, ab->mem + FIELD_GET(ATH11K_REG_OFFSET_MASK, offset));
|
||||
}
|
||||
|
||||
static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab)
|
||||
@@ -275,9 +281,9 @@ static void ath11k_ahb_ce_irq_enable(str
|
||||
const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
|
||||
u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
|
||||
|
||||
- ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
|
||||
- ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
|
||||
- ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
|
||||
+ ie1_reg_addr = ce_ie_addr->ie1_reg_addr;
|
||||
+ ie2_reg_addr = ce_ie_addr->ie2_reg_addr;
|
||||
+ ie3_reg_addr = ce_ie_addr->ie3_reg_addr;
|
||||
|
||||
ce_attr = &ab->hw_params.host_ce_config[ce_id];
|
||||
if (ce_attr->src_nentries)
|
||||
@@ -296,9 +302,9 @@ static void ath11k_ahb_ce_irq_disable(st
|
||||
const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
|
||||
u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
|
||||
|
||||
- ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
|
||||
- ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
|
||||
- ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
|
||||
+ ie1_reg_addr = ce_ie_addr->ie1_reg_addr;
|
||||
+ ie2_reg_addr = ce_ie_addr->ie2_reg_addr;
|
||||
+ ie3_reg_addr = ce_ie_addr->ie3_reg_addr;
|
||||
|
||||
ce_attr = &ab->hw_params.host_ce_config[ce_id];
|
||||
if (ce_attr->src_nentries)
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal.c
|
||||
@@ -1247,20 +1247,16 @@ static int ath11k_hal_srng_create_config
|
||||
s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;
|
||||
|
||||
s = &hal->srng_config[HAL_CE_SRC];
|
||||
- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
|
||||
- ATH11K_CE_OFFSET(ab);
|
||||
- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP +
|
||||
- ATH11K_CE_OFFSET(ab);
|
||||
+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
|
||||
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab) + HAL_CE_DST_RING_HP;
|
||||
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
|
||||
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
|
||||
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG(ab) -
|
||||
HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab);
|
||||
|
||||
s = &hal->srng_config[HAL_CE_DST];
|
||||
- s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB +
|
||||
- ATH11K_CE_OFFSET(ab);
|
||||
- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP +
|
||||
- ATH11K_CE_OFFSET(ab);
|
||||
+ s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_BASE_LSB;
|
||||
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_RING_HP;
|
||||
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
||||
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
|
||||
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
||||
@@ -1268,9 +1264,8 @@ static int ath11k_hal_srng_create_config
|
||||
|
||||
s = &hal->srng_config[HAL_CE_DST_STATUS];
|
||||
s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) +
|
||||
- HAL_CE_DST_STATUS_RING_BASE_LSB + ATH11K_CE_OFFSET(ab);
|
||||
- s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP +
|
||||
- ATH11K_CE_OFFSET(ab);
|
||||
+ HAL_CE_DST_STATUS_RING_BASE_LSB;
|
||||
+ s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab) + HAL_CE_DST_STATUS_RING_HP;
|
||||
s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
||||
HAL_SEQ_WCSS_UMAC_CE0_DST_REG(ab);
|
||||
s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG(ab) -
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -2268,9 +2268,9 @@ const struct ce_ie_addr ath11k_ce_ie_add
|
||||
};
|
||||
|
||||
const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018 = {
|
||||
- .ie1_reg_addr = CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
- .ie2_reg_addr = CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
- .ie3_reg_addr = CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
+ .ie1_reg_addr = ATH11K_REG_TYPE_CE + CE_HOST_IPQ5018_IE_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
+ .ie2_reg_addr = ATH11K_REG_TYPE_CE + CE_HOST_IPQ5018_IE_2_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
+ .ie3_reg_addr = ATH11K_REG_TYPE_CE + CE_HOST_IPQ5018_IE_3_ADDRESS - HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
};
|
||||
|
||||
const struct ce_remap ath11k_ce_remap_ipq5018 = {
|
||||
@@ -2801,13 +2801,13 @@ const struct ath11k_hw_regs ipq5018_regs
|
||||
.hal_reo_status_hp = 0x00003070,
|
||||
|
||||
/* WCSS relative address */
|
||||
- .hal_seq_wcss_umac_ce0_src_reg = 0x08400000
|
||||
+ .hal_seq_wcss_umac_ce0_src_reg = ATH11K_REG_TYPE_CE + 0x08400000
|
||||
- HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
- .hal_seq_wcss_umac_ce0_dst_reg = 0x08401000
|
||||
+ .hal_seq_wcss_umac_ce0_dst_reg = ATH11K_REG_TYPE_CE + 0x08401000
|
||||
- HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
- .hal_seq_wcss_umac_ce1_src_reg = 0x08402000
|
||||
+ .hal_seq_wcss_umac_ce1_src_reg = ATH11K_REG_TYPE_CE + 0x08402000
|
||||
- HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
- .hal_seq_wcss_umac_ce1_dst_reg = 0x08403000
|
||||
+ .hal_seq_wcss_umac_ce1_dst_reg = ATH11K_REG_TYPE_CE + 0x08403000
|
||||
- HAL_IPQ5018_CE_WFSS_REG_BASE,
|
||||
|
||||
/* WBM Idle address */
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -81,7 +81,12 @@
|
||||
#define ATH11K_M3_FILE "m3.bin"
|
||||
#define ATH11K_REGDB_FILE_NAME "regdb.bin"
|
||||
|
||||
-#define ATH11K_CE_OFFSET(ab) (ab->mem_ce - ab->mem)
|
||||
+#define ATH11K_REG_TYPE_MASK GENMASK(31, 28)
|
||||
+#define ATH11K_REG_TYPE(x) FIELD_PREP_CONST(ATH11K_REG_TYPE_MASK, x)
|
||||
+#define ATH11K_REG_TYPE_NORMAL ATH11K_REG_TYPE(0)
|
||||
+#define ATH11K_REG_TYPE_DP ATH11K_REG_TYPE(1)
|
||||
+#define ATH11K_REG_TYPE_CE ATH11K_REG_TYPE(2)
|
||||
+#define ATH11K_REG_OFFSET_MASK GENMASK(27, 0)
|
||||
|
||||
enum ath11k_hw_rate_cck {
|
||||
ATH11K_HW_RATE_CCK_LP_11M = 0,
|
@ -0,0 +1,115 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Wed, 27 Oct 2024 16:34:11 +0400
|
||||
Subject: [PATCH] wifi: ath11k: add hw params for QCN6122
|
||||
|
||||
Add QCN6122 platform support.
|
||||
|
||||
QCN6122 is a PCIe based solution that is attached to and enumerated
|
||||
by the WPSS (Wireless Processor SubSystem) Q6 processor.
|
||||
|
||||
Though it is a PCIe device, since it is not attached to APSS processor
|
||||
(Application Processor SubSystem), APSS will be unaware of such a decice
|
||||
and hence it is registered to the APSS processor as a platform device(AHB).
|
||||
Because of this hybrid nature, it is called as a hybrid bus device.
|
||||
|
||||
As such, QCN6122 is a hybrid bus type device and follows the same codepath
|
||||
as for WCN6750.
|
||||
|
||||
This is a heavily simplified version of below downstream patch:
|
||||
Download from https://git.codelinaro.org/clo/qsdk/oss/system/feeds/wlan-open/-/blob/NHSS.QSDK.12.4.5.r2/mac80211/patches/232-ath11k-qcn6122-support.patch
|
||||
|
||||
Co-developed-by: George Moussalem <george.moussalem@outlook.com>
|
||||
Signed-off-by: Sowmiya Sree Elavalagan <ssreeela@codeaurora.org>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -809,6 +809,67 @@ static struct ath11k_hw_params ath11k_hw
|
||||
.support_fw_mac_sequence = true,
|
||||
.support_dual_stations = true,
|
||||
},
|
||||
+ {
|
||||
+ .hw_rev = ATH11K_HW_QCN6122_HW10,
|
||||
+ .name = "qcn6122 hw1.0",
|
||||
+ .fw = {
|
||||
+ .dir = "QCN6122/hw1.0",
|
||||
+ .board_size = 256 * 1024,
|
||||
+ .cal_offset = 128 * 1024,
|
||||
+ },
|
||||
+ .hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
+ .max_radios = MAX_RADIOS_5018,
|
||||
+ .bdf_addr = 0x4D200000,
|
||||
+ .hw_ops = &ipq5018_ops,
|
||||
+ .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
+ .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122,
|
||||
+ .interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
+ BIT(NL80211_IFTYPE_AP) |
|
||||
+ BIT(NL80211_IFTYPE_MESH_POINT),
|
||||
+ .spectral = {
|
||||
+ .fft_sz = 2,
|
||||
+ .fft_pad_sz = 0,
|
||||
+ .summary_pad_sz = 16,
|
||||
+ .fft_hdr_len = 24,
|
||||
+ .max_fft_bins = 1024,
|
||||
+ },
|
||||
+ .credit_flow = false,
|
||||
+ .max_tx_ring = 1,
|
||||
+ .supports_monitor = true,
|
||||
+ .supports_shadow_regs = false,
|
||||
+ .idle_ps = false,
|
||||
+ .supports_suspend = false,
|
||||
+ .host_ce_config = ath11k_host_ce_config_qcn9074,
|
||||
+ .ce_count = CE_CNT_5018,
|
||||
+ .target_ce_config = ath11k_target_ce_config_wlan_ipq5018,
|
||||
+ .target_ce_count = TARGET_CE_CNT_5018,
|
||||
+ .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018,
|
||||
+ .svc_to_ce_map_len = SVC_CE_MAP_LEN_5018,
|
||||
+ .single_pdev_only = false,
|
||||
+ .rxdma1_enable = true,
|
||||
+ .num_rxdma_per_pdev = RXDMA_PER_PDEV_5018,
|
||||
+ .rx_mac_buf_ring = false,
|
||||
+ .vdev_start_delay = false,
|
||||
+ .htt_peer_map_v2 = true,
|
||||
+ .coldboot_cal_mm = true,
|
||||
+ .coldboot_cal_ftm = true,
|
||||
+ .cbcal_restart_fw = true,
|
||||
+ .fix_l1ss = true,
|
||||
+ .alloc_cacheable_memory = true,
|
||||
+ .m3_fw_support = false,
|
||||
+ .fixed_bdf_addr = true,
|
||||
+ .fixed_mem_region = true,
|
||||
+ .static_window_map = true,
|
||||
+ .hybrid_bus_type = true,
|
||||
+ .fw_mem_mode = 1,
|
||||
+ .supports_sta_ps = false,
|
||||
+ .dbr_debug_support = true,
|
||||
+ .bios_sar_capa = NULL,
|
||||
+ .fixed_fw_mem = false,
|
||||
+ .support_off_channel_tx = false,
|
||||
+ .tcl_ring_retry = true,
|
||||
+ .tx_ring_size = DP_TCL_DATA_RING_SIZE,
|
||||
+ },
|
||||
};
|
||||
|
||||
static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -148,6 +148,7 @@ enum ath11k_hw_rev {
|
||||
ATH11K_HW_WCN6750_HW10,
|
||||
ATH11K_HW_IPQ5018_HW10,
|
||||
ATH11K_HW_QCA2066_HW21,
|
||||
+ ATH11K_HW_QCN6122_HW10,
|
||||
};
|
||||
|
||||
enum ath11k_firmware_mode {
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
|
||||
@@ -22,6 +22,7 @@
|
||||
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074 0x02
|
||||
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074 0x07
|
||||
#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750 0x03
|
||||
+#define ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122 0x40
|
||||
#define ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 32
|
||||
#define ATH11K_QMI_RESP_LEN_MAX 8192
|
||||
#define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52
|
@ -0,0 +1,114 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Wed, 27 Oct 2024 16:34:11 +0400
|
||||
Subject: [PATCH] wifi: ath11k: add hal regs for QCN6122
|
||||
|
||||
Add HAL changes required to support QCN6122. Offsets are similar to those of
|
||||
WCN6750 but QCN6122 does not use the hal_shadow_base_addr, so add platform
|
||||
specific ath11k_hw_regs and register them in hw params.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -822,6 +822,7 @@ static struct ath11k_hw_params ath11k_hw
|
||||
.bdf_addr = 0x4D200000,
|
||||
.hw_ops = &ipq5018_ops,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
+ .regs = &qcn6122_regs,
|
||||
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122,
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -2822,6 +2822,81 @@ const struct ath11k_hw_regs ipq5018_regs
|
||||
.hal_wbm1_release_ring_base_lsb = 0x0000097c,
|
||||
};
|
||||
|
||||
+const struct ath11k_hw_regs qcn6122_regs = {
|
||||
+ /* SW2TCL(x) R0 ring configuration address */
|
||||
+ .hal_tcl1_ring_base_lsb = 0x00000694,
|
||||
+ .hal_tcl1_ring_base_msb = 0x00000698,
|
||||
+ .hal_tcl1_ring_id = 0x0000069c,
|
||||
+ .hal_tcl1_ring_misc = 0x000006a4,
|
||||
+ .hal_tcl1_ring_tp_addr_lsb = 0x000006b0,
|
||||
+ .hal_tcl1_ring_tp_addr_msb = 0x000006b4,
|
||||
+ .hal_tcl1_ring_consumer_int_setup_ix0 = 0x000006c4,
|
||||
+ .hal_tcl1_ring_consumer_int_setup_ix1 = 0x000006c8,
|
||||
+ .hal_tcl1_ring_msi1_base_lsb = 0x000006dc,
|
||||
+ .hal_tcl1_ring_msi1_base_msb = 0x000006e0,
|
||||
+ .hal_tcl1_ring_msi1_data = 0x000006e4,
|
||||
+ .hal_tcl2_ring_base_lsb = 0x000006ec,
|
||||
+ .hal_tcl_ring_base_lsb = 0x0000079c,
|
||||
+
|
||||
+ /* TCL STATUS ring address */
|
||||
+ .hal_tcl_status_ring_base_lsb = 0x000008a4,
|
||||
+
|
||||
+ /* REO2SW(x) R0 ring configuration address */
|
||||
+ .hal_reo1_ring_base_lsb = 0x000001ec,
|
||||
+ .hal_reo1_ring_base_msb = 0x000001f0,
|
||||
+ .hal_reo1_ring_id = 0x000001f4,
|
||||
+ .hal_reo1_ring_misc = 0x000001fc,
|
||||
+ .hal_reo1_ring_hp_addr_lsb = 0x00000200,
|
||||
+ .hal_reo1_ring_hp_addr_msb = 0x00000204,
|
||||
+ .hal_reo1_ring_producer_int_setup = 0x00000210,
|
||||
+ .hal_reo1_ring_msi1_base_lsb = 0x00000234,
|
||||
+ .hal_reo1_ring_msi1_base_msb = 0x00000238,
|
||||
+ .hal_reo1_ring_msi1_data = 0x0000023c,
|
||||
+ .hal_reo2_ring_base_lsb = 0x00000244,
|
||||
+ .hal_reo1_aging_thresh_ix_0 = 0x00000564,
|
||||
+ .hal_reo1_aging_thresh_ix_1 = 0x00000568,
|
||||
+ .hal_reo1_aging_thresh_ix_2 = 0x0000056c,
|
||||
+ .hal_reo1_aging_thresh_ix_3 = 0x00000570,
|
||||
+
|
||||
+ /* REO2SW(x) R2 ring pointers (head/tail) address */
|
||||
+ .hal_reo1_ring_hp = 0x00003028,
|
||||
+ .hal_reo1_ring_tp = 0x0000302c,
|
||||
+ .hal_reo2_ring_hp = 0x00003030,
|
||||
+
|
||||
+ /* REO2TCL R0 ring configuration address */
|
||||
+ .hal_reo_tcl_ring_base_lsb = 0x000003fc,
|
||||
+ .hal_reo_tcl_ring_hp = 0x00003058,
|
||||
+
|
||||
+ /* SW2REO ring address */
|
||||
+ .hal_sw2reo_ring_base_lsb = 0x0000013c,
|
||||
+ .hal_sw2reo_ring_hp = 0x00003018,
|
||||
+
|
||||
+ /* REO CMD ring address */
|
||||
+ .hal_reo_cmd_ring_base_lsb = 0x000000e4,
|
||||
+ .hal_reo_cmd_ring_hp = 0x00003010,
|
||||
+
|
||||
+ /* REO status address */
|
||||
+ .hal_reo_status_ring_base_lsb = 0x00000504,
|
||||
+ .hal_reo_status_hp = 0x00003070,
|
||||
+
|
||||
+ /* WCSS relative address */
|
||||
+ .hal_seq_wcss_umac_ce0_src_reg = 0x01b80000,
|
||||
+ .hal_seq_wcss_umac_ce0_dst_reg = 0x01b81000,
|
||||
+ .hal_seq_wcss_umac_ce1_src_reg = 0x01b82000,
|
||||
+ .hal_seq_wcss_umac_ce1_dst_reg = 0x01b83000,
|
||||
+
|
||||
+ /* WBM Idle address */
|
||||
+ .hal_wbm_idle_link_ring_base_lsb = 0x00000874,
|
||||
+ .hal_wbm_idle_link_ring_misc = 0x00000884,
|
||||
+
|
||||
+ /* SW2WBM release address */
|
||||
+ .hal_wbm_release_ring_base_lsb = 0x000001ec,
|
||||
+
|
||||
+ /* WBM2SW release address */
|
||||
+ .hal_wbm0_release_ring_base_lsb = 0x00000924,
|
||||
+ .hal_wbm1_release_ring_base_lsb = 0x0000097c,
|
||||
+};
|
||||
+
|
||||
const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = {
|
||||
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
|
||||
.tcl2wbm_rbm_map = ath11k_hw_tcl2wbm_rbm_map_ipq8074,
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -425,6 +425,7 @@ extern const struct ath11k_hw_regs qcn90
|
||||
extern const struct ath11k_hw_regs wcn6855_regs;
|
||||
extern const struct ath11k_hw_regs wcn6750_regs;
|
||||
extern const struct ath11k_hw_regs ipq5018_regs;
|
||||
+extern const struct ath11k_hw_regs qcn6122_regs;
|
||||
|
||||
static inline const char *ath11k_bd_ie_type_str(enum ath11k_bd_ie_type type)
|
||||
{
|
@ -0,0 +1,74 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Wed, 27 Oct 2024 16:34:11 +0400
|
||||
Subject: [PATCH] wifi: ath11k: add hw ring mask for QCN6122
|
||||
|
||||
Add ring mask for QCN6122 and register them in hw params.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -821,6 +821,7 @@ static struct ath11k_hw_params ath11k_hw
|
||||
.max_radios = MAX_RADIOS_5018,
|
||||
.bdf_addr = 0x4D200000,
|
||||
.hw_ops = &ipq5018_ops,
|
||||
+ .ring_mask = &ath11k_hw_ring_mask_qcn6122,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
.regs = &qcn6122_regs,
|
||||
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN6122,
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -2070,6 +2070,43 @@ const struct ath11k_hw_ring_mask ath11k_
|
||||
},
|
||||
};
|
||||
|
||||
+const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn6122 = {
|
||||
+ .tx = {
|
||||
+ ATH11K_TX_RING_MASK_0,
|
||||
+ ATH11K_TX_RING_MASK_1,
|
||||
+ ATH11K_TX_RING_MASK_2,
|
||||
+ },
|
||||
+ .rx_mon_status = {
|
||||
+ 0, 0, 0,
|
||||
+ ATH11K_RX_MON_STATUS_RING_MASK_0,
|
||||
+ },
|
||||
+ .rx = {
|
||||
+ 0, 0, 0, 0,
|
||||
+ ATH11K_RX_RING_MASK_0,
|
||||
+ ATH11K_RX_RING_MASK_1,
|
||||
+ ATH11K_RX_RING_MASK_2,
|
||||
+ ATH11K_RX_RING_MASK_3,
|
||||
+ },
|
||||
+ .rx_err = {
|
||||
+ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
+ ATH11K_RX_ERR_RING_MASK_0,
|
||||
+ },
|
||||
+ .rx_wbm_rel = {
|
||||
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
+ ATH11K_RX_WBM_REL_RING_MASK_0,
|
||||
+ },
|
||||
+ .reo_status = {
|
||||
+ 0, 0, 0,
|
||||
+ ATH11K_REO_STATUS_RING_MASK_0,
|
||||
+ },
|
||||
+ .rxdma2host = {
|
||||
+ ATH11K_RXDMA2HOST_RING_MASK_0,
|
||||
+ },
|
||||
+ .host2rxdma = {
|
||||
+ ATH11K_HOST2RXDMA_RING_MASK_0,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
/* Target firmware's Copy Engine configuration for IPQ5018 */
|
||||
const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq5018[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -289,6 +289,7 @@ extern const struct ath11k_hw_ring_mask
|
||||
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
|
||||
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
|
||||
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750;
|
||||
+extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn6122;
|
||||
|
||||
extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq8074;
|
||||
extern const struct ce_ie_addr ath11k_ce_ie_addr_ipq5018;
|
@ -0,0 +1,102 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Wed, 27 Oct 2024 16:34:11 +0400
|
||||
Subject: [PATCH] wifi: ath11k: update hif and pci ops for QCN6122
|
||||
|
||||
Add HIF and PCI ops for QCN6122. QCN6122 by default uses DP window 3.
|
||||
However, this is configurable, so let's introduce a function to do that and
|
||||
follow the existing register access code for (hybrid)AHB devices and use
|
||||
DP window 1.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
@@ -768,6 +768,18 @@ static int ath11k_ahb_hif_resume(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void ath11k_ahb_config_static_window_qcn6122(struct ath11k_base *ab)
|
||||
+{
|
||||
+ u32 umac_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_SEQ_WCSS_UMAC_OFFSET);
|
||||
+ u32 ce_window = FIELD_GET(ATH11K_PCI_WINDOW_VALUE_MASK, HAL_CE_WFSS_CE_REG_BASE);
|
||||
+ u32 window;
|
||||
+
|
||||
+ window = (umac_window) | (ce_window << 6);
|
||||
+
|
||||
+ iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | window,
|
||||
+ ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS);
|
||||
+}
|
||||
+
|
||||
static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
|
||||
.start = ath11k_ahb_start,
|
||||
.stop = ath11k_ahb_stop,
|
||||
@@ -800,6 +812,24 @@ static const struct ath11k_hif_ops ath11
|
||||
.ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq,
|
||||
};
|
||||
|
||||
+static const struct ath11k_hif_ops ath11k_ahb_hif_ops_qcn6122 = {
|
||||
+ .start = ath11k_pcic_start,
|
||||
+ .stop = ath11k_pcic_stop,
|
||||
+ .read32 = ath11k_pcic_read32,
|
||||
+ .write32 = ath11k_pcic_write32,
|
||||
+ .read = NULL,
|
||||
+ .irq_enable = ath11k_pcic_ext_irq_enable,
|
||||
+ .irq_disable = ath11k_pcic_ext_irq_disable,
|
||||
+ .get_msi_address = ath11k_pcic_get_msi_address,
|
||||
+ .get_user_msi_vector = ath11k_pcic_get_user_msi_assignment,
|
||||
+ .map_service_to_pipe = ath11k_pcic_map_service_to_pipe,
|
||||
+ .power_down = ath11k_ahb_power_down,
|
||||
+ .power_up = ath11k_ahb_power_up,
|
||||
+ .ce_irq_enable = ath11k_pci_enable_ce_irqs_except_wake_irq,
|
||||
+ .ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq,
|
||||
+ .config_static_window = ath11k_ahb_config_static_window_qcn6122,
|
||||
+};
|
||||
+
|
||||
static int ath11k_core_get_rproc(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
|
||||
@@ -1144,6 +1174,10 @@ static int ath11k_ahb_probe(struct platf
|
||||
hif_ops = &ath11k_ahb_hif_ops_wcn6750;
|
||||
pci_ops = &ath11k_ahb_pci_ops_wcn6750;
|
||||
break;
|
||||
+ case ATH11K_HW_QCN6122_HW10:
|
||||
+ hif_ops = &ath11k_ahb_hif_ops_qcn6122;
|
||||
+ pci_ops = &ath11k_ahb_pci_ops_wcn6750;
|
||||
+ break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev);
|
||||
return -EOPNOTSUPP;
|
||||
--- a/drivers/net/wireless/ath/ath11k/hif.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hif.h
|
||||
@@ -31,6 +31,7 @@ struct ath11k_hif_ops {
|
||||
void (*ce_irq_enable)(struct ath11k_base *ab);
|
||||
void (*ce_irq_disable)(struct ath11k_base *ab);
|
||||
void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
|
||||
+ void (*config_static_window)(struct ath11k_base *ab);
|
||||
};
|
||||
|
||||
static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
|
||||
@@ -146,4 +147,12 @@ static inline void ath11k_get_ce_msi_idx
|
||||
*msi_data_idx = ce_id;
|
||||
}
|
||||
|
||||
+static inline void ath11k_hif_config_static_window(struct ath11k_base *ab)
|
||||
+{
|
||||
+ if (!ab->hw_params.static_window_map || !ab->hif.ops->config_static_window)
|
||||
+ return;
|
||||
+
|
||||
+ ab->hif.ops->config_static_window(ab);
|
||||
+}
|
||||
+
|
||||
#endif /* _HIF_H_ */
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -2184,6 +2184,8 @@ static int ath11k_qmi_request_device_inf
|
||||
ab->mem = bar_addr_va;
|
||||
ab->mem_len = resp.bar_size;
|
||||
|
||||
+ ath11k_hif_config_static_window(ab);
|
||||
+
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
@ -0,0 +1,110 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Wed, 27 Oct 2024 16:34:11 +0400
|
||||
Subject: [PATCH] wifi: ath11k: add multipd support for QCN6122
|
||||
|
||||
IPQ5018/QCN6122 platforms use multi PD (protection domains) to avoid having
|
||||
one instance of the running Q6 firmware crashing resulting in crashing the
|
||||
others. See below patch for more info:
|
||||
https://lore.kernel.org/all/20231110091939.3025413-1-quic_mmanikan@quicinc.com/
|
||||
|
||||
The IPQ5018 platform can have multiple (2) QCN6122 wifi cards. To differentiate
|
||||
the two, the PD instance number (1 or 2) is added to the QMI service instance
|
||||
ID, which the QCN6122 firmware also expects. IPQ5018 is always the first PD, so
|
||||
the QCN6122 cards should be the second or third.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
@@ -435,6 +435,7 @@ static void ath11k_ahb_init_qmi_ce_confi
|
||||
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
|
||||
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
|
||||
ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
|
||||
+ ab->qmi.service_ins_id += ab->userpd_id;
|
||||
}
|
||||
|
||||
static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
|
||||
@@ -1118,6 +1119,27 @@ err_unregister:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ath11k_get_userpd_id(struct device *dev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int userpd_id = 0;
|
||||
+ const char *subsys_name;
|
||||
+
|
||||
+ ret = of_property_read_string(dev->of_node,
|
||||
+ "qcom,userpd-subsys-name",
|
||||
+ &subsys_name);
|
||||
+ if (ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (strcmp(subsys_name, "q6v5_wcss_userpd2") == 0)
|
||||
+ userpd_id = ATH11K_QCN6122_USERPD_2;
|
||||
+ else if (strcmp(subsys_name, "q6v5_wcss_userpd3") == 0)
|
||||
+ userpd_id = ATH11K_QCN6122_USERPD_3;
|
||||
+ dev_info(dev, "Multipd architecture - userpd: %d\n", userpd_id + 1);
|
||||
+
|
||||
+ return userpd_id;
|
||||
+}
|
||||
+
|
||||
static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
|
||||
@@ -1159,7 +1181,7 @@ static int ath11k_ahb_probe(struct platf
|
||||
const struct ath11k_hif_ops *hif_ops;
|
||||
const struct ath11k_pci_ops *pci_ops;
|
||||
enum ath11k_hw_rev hw_rev;
|
||||
- int ret;
|
||||
+ int ret, userpd_id;
|
||||
|
||||
hw_rev = (uintptr_t)device_get_match_data(&pdev->dev);
|
||||
|
||||
@@ -1183,6 +1205,7 @@ static int ath11k_ahb_probe(struct platf
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
+ userpd_id = ath11k_get_userpd_id(&pdev->dev);
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n");
|
||||
@@ -1199,6 +1222,7 @@ static int ath11k_ahb_probe(struct platf
|
||||
ab->hif.ops = hif_ops;
|
||||
ab->pdev = pdev;
|
||||
ab->hw_rev = hw_rev;
|
||||
+ ab->userpd_id = userpd_id;
|
||||
ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL;
|
||||
platform_set_drvdata(pdev, ab);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -45,6 +45,9 @@
|
||||
#define ATH11K_INVALID_HW_MAC_ID 0xFF
|
||||
#define ATH11K_CONNECTION_LOSS_HZ (3 * HZ)
|
||||
|
||||
+#define ATH11K_QCN6122_USERPD_2 1
|
||||
+#define ATH11K_QCN6122_USERPD_3 2
|
||||
+
|
||||
/* SMBIOS type containing Board Data File Name Extension */
|
||||
#define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8
|
||||
|
||||
@@ -945,6 +948,7 @@ struct ath11k_base {
|
||||
struct list_head peers;
|
||||
wait_queue_head_t peer_mapping_wq;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
+ int userpd_id;
|
||||
int irq_num[ATH11K_IRQ_NUM_MAX];
|
||||
struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX];
|
||||
struct ath11k_targ_cap target_caps;
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -389,6 +389,8 @@ static void ath11k_pci_init_qmi_ce_confi
|
||||
} else
|
||||
ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
|
||||
|
||||
+ ab->qmi.service_ins_id += ab->userpd_id;
|
||||
+
|
||||
ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2,
|
||||
&cfg->shadow_reg_v2_len);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Wed, 27 Oct 2024 16:34:11 +0400
|
||||
Subject: [PATCH] wifi: ath11k: add QCN6122 device support
|
||||
|
||||
QCN6122 is a 2x2 11AX PCIe based chipset, but it is attached to the WPSS
|
||||
(Wireless Processor SubSystem) Q6 processor, hence it is enumerated
|
||||
by the Q6 processor. It is registered to the APSS processor
|
||||
(Application Processor SubSystem) as a platform device (AHB) and remoteproc
|
||||
APIs are used to boot up or shutdown the device like other AHB devices.
|
||||
|
||||
Also, device information like BAR and its size is not known to the
|
||||
APSS processor as the chip is enumerated by WPSS Q6. These details
|
||||
are fetched over QMI.
|
||||
|
||||
STA, AP, and MESH modes are supported.
|
||||
Tested on: Linksys MX2000 and GLiNET B3000 access points for prolonged duration
|
||||
tests spanning multiple days with multiple clients connected with firmware
|
||||
WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
An important point to note is that though QCN6122 is a PCIe device,
|
||||
it is an IPQ5018 SoC specific solution and cannot be attached to any other
|
||||
platform.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ahb.c
|
||||
@@ -37,6 +37,9 @@ static const struct of_device_id ath11k_
|
||||
{ .compatible = "qcom,ipq5018-wifi",
|
||||
.data = (void *)ATH11K_HW_IPQ5018_HW10,
|
||||
},
|
||||
+ { .compatible = "qcom,qcn6122-wifi",
|
||||
+ .data = (void *)ATH11K_HW_QCN6122_HW10,
|
||||
+ },
|
||||
{ }
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pcic.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pcic.c
|
||||
@@ -126,6 +126,15 @@ static const struct ath11k_msi_config at
|
||||
},
|
||||
.hw_rev = ATH11K_HW_QCA2066_HW21,
|
||||
},
|
||||
+ {
|
||||
+ .total_vectors = 13,
|
||||
+ .total_users = 2,
|
||||
+ .users = (struct ath11k_msi_user[]) {
|
||||
+ { .name = "CE", .num_vectors = 5, .base_vector = 0 },
|
||||
+ { .name = "DP", .num_vectors = 8, .base_vector = 5 },
|
||||
+ },
|
||||
+ .hw_rev = ATH11K_HW_QCN6122_HW10,
|
||||
+ },
|
||||
};
|
||||
|
||||
int ath11k_pcic_init_msi_config(struct ath11k_base *ab)
|
@ -0,0 +1,31 @@
|
||||
From 64f6f6cdde0b6b763181145a698207fad4536c06 Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Wed, 9 Aug 2023 17:44:49 +0000
|
||||
Subject: [PATCH] wifi: ath11k: Support to assign m3 dump memory
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -2104,6 +2104,18 @@ static int ath11k_qmi_assign_target_mem_
|
||||
ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
||||
idx++;
|
||||
break;
|
||||
+ case M3_DUMP_REGION_TYPE:
|
||||
+ if (of_property_read_u32(dev->of_node, "qcom,m3-dump-addr", &addr)) {
|
||||
+ ath11k_warn(ab, "qmi fail to get qcom,m3-dump-addr, ignore m3 dump mem req\n");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ab->qmi.target_mem[idx].paddr = (phys_addr_t) addr;
|
||||
+ ab->qmi.target_mem[idx].vaddr = NULL;
|
||||
+ ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
|
||||
+ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
|
||||
+ idx++;
|
||||
+ break;
|
||||
default:
|
||||
ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
|
||||
ab->qmi.target_mem[i].type);
|
@ -0,0 +1,164 @@
|
||||
From d890c6d602307c9297df12c7d0287f9ffd26208b Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Wed, 12 May 2021 19:21:09 +0530
|
||||
Subject: [PATCH] ath11k: poll reo status ring for IPQ5018
|
||||
|
||||
Currently reo status interrupts are not received
|
||||
due to wrong mapping of the reo status interrupt
|
||||
line in IPQ5018.
|
||||
|
||||
Hence, until the mapping is resolved in HW, use
|
||||
polling to reap the reo status ring. Rather than
|
||||
a period timer to reap the ring, the timer is
|
||||
triggered only on sending a reo command with
|
||||
status request.
|
||||
|
||||
Without proper reaping of the ring, backpressure
|
||||
and ring full issues are seen in multi client test
|
||||
setups which leads to flooding the console with
|
||||
error messages reporting failure to send reo cmds.
|
||||
|
||||
Can be reverted once HW solution is available.
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -719,6 +719,7 @@ static struct ath11k_hw_params ath11k_hw
|
||||
.smp2p_wow_exit = false,
|
||||
.support_fw_mac_sequence = false,
|
||||
.support_dual_stations = false,
|
||||
+ .reo_status_poll = true,
|
||||
},
|
||||
{
|
||||
.name = "qca2066 hw2.1",
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -361,12 +361,66 @@ void ath11k_dp_stop_shadow_timers(struct
|
||||
ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer);
|
||||
}
|
||||
|
||||
+static void ath11k_dp_handle_reo_status_timer(struct timer_list *timer)
|
||||
+{
|
||||
+ struct ath11k_dp *dp = from_timer(dp, timer, reo_status_timer);
|
||||
+ struct ath11k_base *ab = dp->ab;
|
||||
+
|
||||
+ spin_lock_bh(&dp->reo_cmd_lock);
|
||||
+ dp->reo_status_timer_running = false;
|
||||
+ spin_unlock_bh(&dp->reo_cmd_lock);
|
||||
+
|
||||
+ ath11k_dp_process_reo_status(ab);
|
||||
+}
|
||||
+
|
||||
+void ath11k_dp_start_reo_status_timer(struct ath11k_base *ab)
|
||||
+{
|
||||
+ struct ath11k_dp *dp = &ab->dp;
|
||||
+
|
||||
+ if (!ab->hw_params.reo_status_poll)
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_bh(&dp->reo_cmd_lock);
|
||||
+ if (dp->reo_status_timer_running) {
|
||||
+ spin_unlock_bh(&dp->reo_cmd_lock);
|
||||
+ return;
|
||||
+ }
|
||||
+ dp->reo_status_timer_running = true;
|
||||
+ spin_unlock_bh(&dp->reo_cmd_lock);
|
||||
+
|
||||
+ mod_timer(&dp->reo_status_timer, jiffies +
|
||||
+ msecs_to_jiffies(ATH11K_REO_STATUS_POLL_TIMEOUT_MS));
|
||||
+}
|
||||
+
|
||||
+static void ath11k_dp_stop_reo_status_timer(struct ath11k_base *ab)
|
||||
+{
|
||||
+ struct ath11k_dp *dp = &ab->dp;
|
||||
+
|
||||
+ if (!ab->hw_params.reo_status_poll)
|
||||
+ return;
|
||||
+
|
||||
+ del_timer_sync(&dp->reo_status_timer);
|
||||
+ dp->reo_status_timer_running = false;
|
||||
+}
|
||||
+
|
||||
+static void ath11k_dp_init_reo_status_timer(struct ath11k_base *ab)
|
||||
+{
|
||||
+ struct ath11k_dp *dp = &ab->dp;
|
||||
+
|
||||
+ if (!ab->hw_params.reo_status_poll)
|
||||
+ return;
|
||||
+
|
||||
+ timer_setup(&dp->reo_status_timer,
|
||||
+ ath11k_dp_handle_reo_status_timer, 0);
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_srng_common_cleanup(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_dp *dp = &ab->dp;
|
||||
int i;
|
||||
|
||||
ath11k_dp_stop_shadow_timers(ab);
|
||||
+ ath11k_dp_stop_reo_status_timer(ab);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring);
|
||||
@@ -388,6 +442,8 @@ static int ath11k_dp_srng_common_setup(s
|
||||
int i, ret;
|
||||
u8 tcl_num, wbm_num;
|
||||
|
||||
+ ath11k_dp_init_reo_status_timer(ab);
|
||||
+
|
||||
ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring,
|
||||
HAL_SW2WBM_RELEASE, 0, 0,
|
||||
DP_WBM_RELEASE_RING_SIZE);
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -44,6 +44,8 @@ struct dp_rx_tid {
|
||||
#define DP_MON_PURGE_TIMEOUT_MS 100
|
||||
#define DP_MON_SERVICE_BUDGET 128
|
||||
|
||||
+#define ATH11K_REO_STATUS_POLL_TIMEOUT_MS 10
|
||||
+
|
||||
struct dp_reo_cache_flush_elem {
|
||||
struct list_head list;
|
||||
struct dp_rx_tid data;
|
||||
@@ -286,6 +288,10 @@ struct ath11k_dp {
|
||||
spinlock_t reo_cmd_lock;
|
||||
struct ath11k_hp_update_timer reo_cmd_timer;
|
||||
struct ath11k_hp_update_timer tx_ring_timer[DP_TCL_NUM_RING_MAX];
|
||||
+
|
||||
+ /* reo status timer and flags */
|
||||
+ struct timer_list reo_status_timer;
|
||||
+ bool reo_status_timer_running;
|
||||
};
|
||||
|
||||
/* HTT definitions */
|
||||
@@ -1712,5 +1718,6 @@ void ath11k_dp_shadow_init_timer(struct
|
||||
struct ath11k_hp_update_timer *update_timer,
|
||||
u32 interval, u32 ring_id);
|
||||
void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab);
|
||||
+void ath11k_dp_start_reo_status_timer(struct ath11k_base *ab);
|
||||
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -787,6 +787,10 @@ int ath11k_dp_tx_send_reo_cmd(struct ath
|
||||
if (cmd_num == 0)
|
||||
return -EINVAL;
|
||||
|
||||
+ /* Trigger reo status polling if required */
|
||||
+ if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)
|
||||
+ ath11k_dp_start_reo_status_timer(ab);
|
||||
+
|
||||
if (!cb)
|
||||
return 0;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -232,6 +232,7 @@ struct ath11k_hw_params {
|
||||
bool smp2p_wow_exit;
|
||||
bool support_fw_mac_sequence;
|
||||
bool support_dual_stations;
|
||||
+ bool reo_status_poll;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
@ -0,0 +1,245 @@
|
||||
From 5ad8cf24897ff903112967a9662cb13ed4cbbf57 Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Mon, 22 Apr 2024 21:47:58 +0800
|
||||
Subject: [PATCH] syn-gmac: use standard DMA api
|
||||
|
||||
The SSDK uses several old DMA API calls based on raw assembly which have
|
||||
been deprecated. So let's convert to and use the standard Linux DMA API
|
||||
instead.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
hal/dp_ops/syn_gmac_dp/syn_dp_cfg_rx.c | 14 ++++++--
|
||||
hal/dp_ops/syn_gmac_dp/syn_dp_cfg_tx.c | 2 ++
|
||||
hal/dp_ops/syn_gmac_dp/syn_dp_rx.c | 47 +++++++++++++-------------
|
||||
hal/dp_ops/syn_gmac_dp/syn_dp_tx.c | 23 ++++---------
|
||||
4 files changed, 42 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_rx.c b/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_rx.c
|
||||
index 8cbbcaaf..1c9006c7 100644
|
||||
--- a/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_rx.c
|
||||
+++ b/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_rx.c
|
||||
@@ -26,6 +26,7 @@ static int syn_dp_cfg_rx_setup_desc_queue(struct syn_dp_info *dev_info)
|
||||
{
|
||||
struct syn_dp_info_rx *rx_info = &dev_info->dp_info_rx;
|
||||
struct dma_desc_rx *first_desc = NULL;
|
||||
+ dma_addr_t dma_addr;
|
||||
struct net_device *netdev = rx_info->netdev;
|
||||
|
||||
netdev_dbg(netdev, "Total size of memory required for Rx Descriptors in Ring Mode = %u\n", (uint32_t)((sizeof(struct dma_desc_rx) * SYN_DP_RX_DESC_SIZE)));
|
||||
@@ -33,13 +34,15 @@ static int syn_dp_cfg_rx_setup_desc_queue(struct syn_dp_info *dev_info)
|
||||
/*
|
||||
* Allocate cacheable descriptors for Rx
|
||||
*/
|
||||
- first_desc = kzalloc(sizeof(struct dma_desc_rx) * SYN_DP_RX_DESC_SIZE, GFP_KERNEL);
|
||||
+ first_desc = dma_alloc_coherent(rx_info->dev,
|
||||
+ sizeof(struct dma_desc_rx) * SYN_DP_RX_DESC_SIZE,
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
if (!first_desc) {
|
||||
netdev_dbg(netdev, "Error in Rx Descriptor Memory allocation in Ring mode\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- dev_info->rx_desc_dma_addr = (dma_addr_t)virt_to_phys(first_desc);
|
||||
+ dev_info->rx_desc_dma_addr = dma_addr;
|
||||
rx_info->rx_desc = first_desc;
|
||||
syn_dp_gmac_rx_desc_init_ring(rx_info->rx_desc, SYN_DP_RX_DESC_SIZE);
|
||||
|
||||
@@ -98,6 +101,10 @@ void syn_dp_cfg_rx_cleanup_rings(struct syn_dp_info *dev_info)
|
||||
for (i = 0; i < rx_info->busy_rx_desc_cnt; i++) {
|
||||
rx_skb_index = (rx_skb_index + i) & SYN_DP_RX_DESC_MAX_INDEX;
|
||||
rxdesc = rx_info->rx_desc;
|
||||
+
|
||||
+ dma_unmap_single(rx_info->dev, rxdesc->buffer1,
|
||||
+ rxdesc->length, DMA_FROM_DEVICE);
|
||||
+
|
||||
skb = rx_info->rx_buf_pool[rx_skb_index].skb;
|
||||
if (unlikely(skb != NULL)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
@@ -105,7 +112,8 @@ void syn_dp_cfg_rx_cleanup_rings(struct syn_dp_info *dev_info)
|
||||
}
|
||||
}
|
||||
|
||||
- kfree(rx_info->rx_desc);
|
||||
+ dma_free_coherent(rx_info->dev, (sizeof(struct dma_desc_rx) * SYN_DP_RX_DESC_SIZE),
|
||||
+ rx_info->rx_desc, dev_info->rx_desc_dma_addr);
|
||||
rx_info->rx_desc = NULL;
|
||||
dev_info->rx_desc_dma_addr = (dma_addr_t)0;
|
||||
}
|
||||
diff --git a/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_tx.c b/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_tx.c
|
||||
index bf5e19a0..284e8880 100644
|
||||
--- a/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_tx.c
|
||||
+++ b/hal/dp_ops/syn_gmac_dp/syn_dp_cfg_tx.c
|
||||
@@ -91,6 +91,8 @@ void syn_dp_cfg_tx_cleanup_rings(struct syn_dp_info *dev_info)
|
||||
tx_skb_index = syn_dp_tx_inc_index(tx_skb_index, i);
|
||||
txdesc = tx_info->tx_desc;
|
||||
|
||||
+ dma_unmap_single(tx_info->dev, txdesc->buffer1, txdesc->length, DMA_TO_DEVICE);
|
||||
+
|
||||
skb = tx_info->tx_buf_pool[tx_skb_index].skb;
|
||||
if (unlikely(skb != NULL)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
diff --git a/hal/dp_ops/syn_gmac_dp/syn_dp_rx.c b/hal/dp_ops/syn_gmac_dp/syn_dp_rx.c
|
||||
index 1ddeb7d6..1798d4e7 100644
|
||||
--- a/hal/dp_ops/syn_gmac_dp/syn_dp_rx.c
|
||||
+++ b/hal/dp_ops/syn_gmac_dp/syn_dp_rx.c
|
||||
@@ -73,16 +73,6 @@ static inline void syn_dp_rx_refill_one_desc(struct dma_desc_rx *rx_desc,
|
||||
*/
|
||||
static inline void syn_dp_rx_inval_and_flush(struct syn_dp_info_rx *rx_info, uint32_t start, uint32_t end)
|
||||
{
|
||||
- /*
|
||||
- * Batched flush and invalidation of the rx descriptors
|
||||
- */
|
||||
- if (end > start) {
|
||||
- dmac_flush_range_no_dsb((void *)&rx_info->rx_desc[start], (void *)&rx_info->rx_desc[end] + sizeof(struct dma_desc_rx));
|
||||
- } else {
|
||||
- dmac_flush_range_no_dsb((void *)&rx_info->rx_desc[start], (void *)&rx_info->rx_desc[SYN_DP_RX_DESC_MAX_INDEX] + sizeof(struct dma_desc_rx));
|
||||
- dmac_flush_range_no_dsb((void *)&rx_info->rx_desc[0], (void *)&rx_info->rx_desc[end] + sizeof(struct dma_desc_rx));
|
||||
- }
|
||||
-
|
||||
dsb(st);
|
||||
}
|
||||
|
||||
@@ -124,15 +114,19 @@ int syn_dp_rx_refill_page_mode(struct syn_dp_info_rx *rx_info)
|
||||
break;
|
||||
}
|
||||
|
||||
+ skb_fill_page_desc(skb, 0, pg, 0, PAGE_SIZE);
|
||||
+
|
||||
/*
|
||||
* Get virtual address of allocated page.
|
||||
*/
|
||||
page_addr = page_address(pg);
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(page_addr);
|
||||
-
|
||||
- skb_fill_page_desc(skb, 0, pg, 0, PAGE_SIZE);
|
||||
+ dma_addr = dma_map_page(rx_info->dev, pg, 0, PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
+ if (unlikely(dma_mapping_error(rx_info->dev, dma_addr))) {
|
||||
+ dev_kfree_skb(skb);
|
||||
+ netdev_dbg(netdev, "DMA mapping failed for empty buffer\n");
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- dmac_inv_range_no_dsb(page_addr, (page_addr + PAGE_SIZE));
|
||||
rx_refill_idx = rx_info->rx_refill_idx;
|
||||
rx_desc = rx_info->rx_desc + rx_refill_idx;
|
||||
|
||||
@@ -181,8 +175,15 @@ int syn_dp_rx_refill(struct syn_dp_info_rx *rx_info)
|
||||
|
||||
skb_reserve(skb, SYN_DP_SKB_HEADROOM + NET_IP_ALIGN);
|
||||
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(skb->data);
|
||||
- dmac_inv_range_no_dsb((void *)skb->data, (void *)(skb->data + inval_len));
|
||||
+ dma_addr = dma_map_single(rx_info->dev, skb->data,
|
||||
+ inval_len,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+ if (unlikely(dma_mapping_error(rx_info->dev, dma_addr))) {
|
||||
+ dev_kfree_skb(skb);
|
||||
+ netdev_dbg(netdev, "DMA mapping failed for empty buffer\n");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
rx_refill_idx = rx_info->rx_refill_idx;
|
||||
rx_desc = rx_info->rx_desc + rx_refill_idx;
|
||||
|
||||
@@ -407,12 +408,6 @@ int syn_dp_rx(struct syn_dp_info_rx *rx_info, int budget)
|
||||
* this code is executing.
|
||||
*/
|
||||
end = syn_dp_rx_inc_index(rx_info->rx_idx, busy);
|
||||
- if (end > start) {
|
||||
- dmac_inv_range_no_dsb((void *)&rx_info->rx_desc[start], (void *)&rx_info->rx_desc[end] + sizeof(struct dma_desc_rx));
|
||||
- } else {
|
||||
- dmac_inv_range_no_dsb((void *)&rx_info->rx_desc[start], (void *)&rx_info->rx_desc[SYN_DP_RX_DESC_MAX_INDEX] + sizeof(struct dma_desc_rx));
|
||||
- dmac_inv_range_no_dsb((void *)&rx_info->rx_desc[0], (void *)&rx_info->rx_desc[end] + sizeof(struct dma_desc_rx));
|
||||
- }
|
||||
|
||||
dsb(st);
|
||||
|
||||
@@ -439,8 +434,12 @@ int syn_dp_rx(struct syn_dp_info_rx *rx_info, int budget)
|
||||
* speculative prefetch by CPU may have occurred.
|
||||
*/
|
||||
frame_length = syn_dp_gmac_get_rx_desc_frame_length(status);
|
||||
- dmac_inv_range((void *)rx_buf->map_addr_virt,
|
||||
- (void *)(((uint8_t *)rx_buf->map_addr_virt) + frame_length));
|
||||
+ if (likely(!rx_info->page_mode))
|
||||
+ dma_unmap_single(rx_info->dev, rx_desc->buffer1,
|
||||
+ rx_info->alloc_buf_len, DMA_FROM_DEVICE);
|
||||
+ else
|
||||
+ dma_unmap_page(rx_info->dev, rx_desc->buffer1,
|
||||
+ PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
prefetch((void *)rx_buf->map_addr_virt);
|
||||
|
||||
rx_next_idx = syn_dp_rx_inc_index(rx_idx, 1);
|
||||
diff --git a/hal/dp_ops/syn_gmac_dp/syn_dp_tx.c b/hal/dp_ops/syn_gmac_dp/syn_dp_tx.c
|
||||
index c97e252b..6d4adb3f 100644
|
||||
--- a/hal/dp_ops/syn_gmac_dp/syn_dp_tx.c
|
||||
+++ b/hal/dp_ops/syn_gmac_dp/syn_dp_tx.c
|
||||
@@ -104,9 +104,7 @@ static inline struct dma_desc_tx *syn_dp_tx_process_nr_frags(struct syn_dp_info_
|
||||
BUG_ON(!length);
|
||||
#endif
|
||||
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(frag_addr);
|
||||
-
|
||||
- dmac_clean_range_no_dsb(frag_addr, frag_addr + length);
|
||||
+ dma_addr = dma_map_single(tx_info->dev, frag_addr, length, DMA_TO_DEVICE);
|
||||
|
||||
*total_length += length;
|
||||
tx_desc = syn_dp_tx_set_desc_sg(tx_info, dma_addr, length, DESC_OWN_BY_DMA);
|
||||
@@ -150,8 +148,7 @@ int syn_dp_tx_nr_frags(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
|
||||
/*
|
||||
* Flush the dma for non-paged skb data
|
||||
*/
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(skb->data);
|
||||
- dmac_clean_range_no_dsb((void *)skb->data, (void *)(skb->data + length));
|
||||
+ dma_addr = dma_map_single(tx_info->dev, skb->data, length, DMA_TO_DEVICE);
|
||||
|
||||
total_len = length;
|
||||
|
||||
@@ -256,12 +253,7 @@ int syn_dp_tx_frag_list(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(skb->data);
|
||||
-
|
||||
- /*
|
||||
- * Flush the data area of the head skb
|
||||
- */
|
||||
- dmac_clean_range_no_dsb((void *)skb->data, (void *)(skb->data + length));
|
||||
+ dma_addr = dma_map_single(tx_info->dev, skb->data, length, DMA_TO_DEVICE);
|
||||
|
||||
total_len = length;
|
||||
|
||||
@@ -290,9 +282,7 @@ int syn_dp_tx_frag_list(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
|
||||
BUG_ON(!length);
|
||||
#endif
|
||||
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(iter_skb->data);
|
||||
-
|
||||
- dmac_clean_range_no_dsb((void *)iter_skb->data, (void *)(iter_skb->data + length));
|
||||
+ dma_addr = dma_map_single(tx_info->dev, iter_skb->data, length, DMA_TO_DEVICE);
|
||||
|
||||
total_len += length;
|
||||
|
||||
@@ -445,6 +435,7 @@ int syn_dp_tx_complete(struct syn_dp_info_tx *tx_info, int budget)
|
||||
break;
|
||||
}
|
||||
|
||||
+ dma_unmap_single(tx_info->dev, desc->buffer1, desc->length, DMA_TO_DEVICE);
|
||||
|
||||
if (likely(status & DESC_TX_LAST)) {
|
||||
tx_skb_index = syn_dp_tx_comp_index_get(tx_info);
|
||||
@@ -571,9 +562,7 @@ int syn_dp_tx(struct syn_dp_info_tx *tx_info, struct sk_buff *skb)
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
- dma_addr = (dma_addr_t)virt_to_phys(skb->data);
|
||||
-
|
||||
- dmac_clean_range_no_dsb((void *)skb->data, (void *)(skb->data + skb->len));
|
||||
+ dma_addr = dma_map_single(tx_info->dev, skb->data, skb->len, DMA_TO_DEVICE);
|
||||
|
||||
/*
|
||||
* Queue packet to the GMAC rings
|
||||
--
|
||||
2.40.1
|
||||
|
@ -0,0 +1,46 @@
|
||||
From ba430b1a512dc1972807a1dd5a8d31a78ac572ff Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Mon, 22 Apr 2024 21:49:18 +0800
|
||||
Subject: [PATCH] ipq50xx: use corrent scm function to write tcsr
|
||||
|
||||
QCA leverages its own API function to write to the TCSR register space,
|
||||
not available upstream. As such, convert to the upstream qcom SCM IO
|
||||
write function.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
hal/soc_ops/ipq50xx/nss_ipq50xx.c | 9 ++-------
|
||||
1 file changed, 2 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hal/soc_ops/ipq50xx/nss_ipq50xx.c b/hal/soc_ops/ipq50xx/nss_ipq50xx.c
|
||||
index 3e4491c0..e56de1cc 100644
|
||||
--- a/hal/soc_ops/ipq50xx/nss_ipq50xx.c
|
||||
+++ b/hal/soc_ops/ipq50xx/nss_ipq50xx.c
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/ioport.h>
|
||||
-#include <linux/qcom_scm.h>
|
||||
+#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include "nss_dp_hal.h"
|
||||
|
||||
/*
|
||||
@@ -78,13 +78,8 @@ static void nss_dp_hal_tcsr_set(void)
|
||||
* If TZ is not enabled, we can write to the register directly.
|
||||
*/
|
||||
if (qcom_scm_is_available()) {
|
||||
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
|
||||
- err = qcom_scm_tcsr_reg_write((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET),
|
||||
+ err = qcom_scm_io_writel((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET),
|
||||
TCSR_GMAC_AXI_CACHE_OVERRIDE_VALUE);
|
||||
-#else
|
||||
- err = qti_scm_tcsr_reg_write((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET),
|
||||
- TCSR_GMAC_AXI_CACHE_OVERRIDE_VALUE);
|
||||
-#endif
|
||||
if (err) {
|
||||
pr_err("%s: SCM TCSR write error: %d\n", __func__, err);
|
||||
}
|
||||
--
|
||||
2.40.1
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 309a1a330ccaa103a7648e944d97a0032116b338 Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Mon, 22 Apr 2024 21:50:39 +0800
|
||||
Subject: [PATCH] nss_dp_main: support fixed-link
|
||||
|
||||
Add support for "fixed link" to support ethernet MACs which are not
|
||||
connected to an MDIO managed PHY. For example, IPQ5018 has two internal
|
||||
MACs, one connected to a GE PHY and the other connected to a Uniphy to
|
||||
support connections to an external switch over a fixed link. As such,
|
||||
check for a fixed link in absence of a phy-handle and return an error
|
||||
when no phy-handle and fixed link is found.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
nss_dp_main.c | 15 ++++++++++++---
|
||||
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/nss_dp_main.c b/nss_dp_main.c
|
||||
index 9a09edd5..204063bf 100644
|
||||
--- a/nss_dp_main.c
|
||||
+++ b/nss_dp_main.c
|
||||
@@ -619,11 +619,20 @@ static int32_t nss_dp_of_get_pdata(struct device_node *np,
|
||||
}
|
||||
|
||||
dp_priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
- if (!dp_priv->phy_node) {
|
||||
- pr_err("%s: error parsing phy-handle\n", np->name);
|
||||
- return -EFAULT;
|
||||
+ if(!dp_priv->phy_node) {
|
||||
+ if(of_phy_is_fixed_link(np)) {
|
||||
+ int ret = of_phy_register_fixed_link(np);
|
||||
+ if(ret < 0) {
|
||||
+ pr_err("%s: fail to register fixed-link: %d\n", np->name, ret);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ }
|
||||
+ dp_priv->phy_node = of_node_get(np);
|
||||
}
|
||||
|
||||
+ if(!dp_priv->phy_node)
|
||||
+ pr_err("%s: no phy-handle or fixed-link found\n", np->name);
|
||||
+
|
||||
if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) {
|
||||
pr_err("%s: error reading mactype\n", np->name);
|
||||
return -EFAULT;
|
||||
--
|
||||
2.40.1
|
||||
|
@ -49,7 +49,7 @@ MAKE_FLAGS+= \
|
||||
PTP_FEATURE=disable SWCONFIG_FEATURE=disable \
|
||||
ISISC_ENABLE=disable MHT_ENABLE=disable \
|
||||
IN_QCA803X_PHY=FALSE IN_QCA808X_PHY=FALSE \
|
||||
IN_MALIBU_PHY=FALSE \
|
||||
IN_MALIBU_PHY=FALSE IN_MP_PHY=FALSE \
|
||||
$(LNX_CONFIG_OPTS)
|
||||
|
||||
ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x")
|
||||
@ -60,6 +60,9 @@ ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx")
|
||||
MAKE_FLAGS+= CHIP_TYPE=CPPE
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq50xx")
|
||||
MAKE_FLAGS+= CHIP_TYPE=MP
|
||||
endif
|
||||
|
||||
define Build/Compile
|
||||
+$(MAKE) $(PKG_JOBS) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) $(LNX_CONFIG_OPTS)
|
||||
|
@ -0,0 +1,127 @@
|
||||
From 15847e1f56b7f9423095cd96fd9d524a41bee814 Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Sun, 8 Sep 2024 15:24:07 +0800
|
||||
Subject: [PATCH] hsl_phy: split MP_PHY config
|
||||
|
||||
Compiling the MP_PHY driver for ipq50xx is disabled in the Makefile in
|
||||
favor of a native driver being upstreamed. As such, conditionally disable
|
||||
unneeded flags and code associated to initializing the MP GE PHY that
|
||||
would otherwise conflict with the native driver.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
config | 1 +
|
||||
make/linux_opt.mk | 5 +++++
|
||||
src/adpt/mp/adpt_mp_portctrl.c | 4 ++++
|
||||
src/hsl/phy/Makefile | 8 +-------
|
||||
src/hsl/phy/hsl_phy.c | 4 ++--
|
||||
5 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/config b/config
|
||||
index 99d99dff..1f74e4f8 100644
|
||||
--- a/config
|
||||
+++ b/config
|
||||
@@ -299,6 +299,7 @@ else ifeq (DESS, $(CHIP_TYPE))
|
||||
else ifeq (MP, $(CHIP_TYPE))
|
||||
IN_QCA803X_PHY=TRUE
|
||||
IN_QCA808X_PHY=TRUE
|
||||
+ IN_MP_PHY=TRUE
|
||||
IN_SFP_PHY=TRUE
|
||||
IN_SFP=TRUE
|
||||
else ifeq (APPE, $(CHIP_TYPE))
|
||||
diff --git a/make/linux_opt.mk b/make/linux_opt.mk
|
||||
index 6936b754..66b08ef5 100644
|
||||
--- a/make/linux_opt.mk
|
||||
+++ b/make/linux_opt.mk
|
||||
@@ -183,6 +183,11 @@ endif
|
||||
ifeq (TRUE, $(IN_QCA808X_PHY))
|
||||
MODULE_CFLAG += -DIN_QCA808X_PHY
|
||||
endif
|
||||
+
|
||||
+ifeq (TRUE, $(IN_MP_PHY))
|
||||
+ MODULE_CFLAG += -DIN_MP_PHY
|
||||
+endif
|
||||
+
|
||||
ifeq (TRUE, $(IN_SFP_PHY))
|
||||
MODULE_CFLAG += -DIN_SFP_PHY
|
||||
endif
|
||||
diff --git a/src/adpt/mp/adpt_mp_portctrl.c b/src/adpt/mp/adpt_mp_portctrl.c
|
||||
index 2c983fff..db60fc72 100644
|
||||
--- a/src/adpt/mp/adpt_mp_portctrl.c
|
||||
+++ b/src/adpt/mp/adpt_mp_portctrl.c
|
||||
@@ -92,12 +92,15 @@ static sw_error_t
|
||||
adpt_mp_port_reset_set(a_uint32_t dev_id, a_uint32_t port_id)
|
||||
{
|
||||
sw_error_t rv = 0;
|
||||
+#ifdef IN_MP_PHY
|
||||
a_uint32_t phy_addr;
|
||||
hsl_phy_ops_t *phy_drv;
|
||||
+#endif
|
||||
|
||||
ADPT_DEV_ID_CHECK(dev_id);
|
||||
|
||||
if (port_id == SSDK_PHYSICAL_PORT1) {
|
||||
+#ifdef IN_MP_PHY
|
||||
/*internal gephy reset*/
|
||||
SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id,
|
||||
port_id));
|
||||
@@ -107,6 +110,7 @@ adpt_mp_port_reset_set(a_uint32_t dev_id, a_uint32_t port_id)
|
||||
SW_RTN_ON_ERROR (rv);
|
||||
rv = phy_drv->phy_function_reset(dev_id, phy_addr, PHY_FIFO_RESET);
|
||||
SW_RTN_ON_ERROR (rv);
|
||||
+#endif
|
||||
} else if (port_id == SSDK_PHYSICAL_PORT2) {
|
||||
rv = adpt_mp_uniphy_adapter_port_reset(dev_id, port_id);
|
||||
} else {
|
||||
diff --git a/src/hsl/phy/Makefile b/src/hsl/phy/Makefile
|
||||
index 68d0679f..0eae9377 100755
|
||||
--- a/src/hsl/phy/Makefile
|
||||
+++ b/src/hsl/phy/Makefile
|
||||
@@ -23,7 +23,7 @@ ifeq (ISIS, $(CHIP_TYPE))
|
||||
SRC_LIST = f1_phy.c
|
||||
endif
|
||||
|
||||
-ifeq (MP, $(CHIP_TYPE))
|
||||
+ifeq (TRUE, $(IN_MP_PHY))
|
||||
SRC_LIST = mpge_phy.c
|
||||
ifeq (TRUE, $(IN_LED))
|
||||
SRC_LIST += mpge_led.c
|
||||
@@ -40,12 +40,6 @@ endif
|
||||
|
||||
ifeq (ALL_CHIP, $(CHIP_TYPE))
|
||||
SRC_LIST = f1_phy.c f2_phy.c malibu_phy.c
|
||||
-ifneq (,$(filter MP, $(SUPPORT_CHIP)))
|
||||
- SRC_LIST += mpge_phy.c
|
||||
-ifeq (TRUE, $(IN_LED))
|
||||
- SRC_LIST += mpge_led.c
|
||||
-endif
|
||||
-endif
|
||||
endif
|
||||
|
||||
ifeq (NONHK_CHIP, $(CHIP_TYPE))
|
||||
diff --git a/src/hsl/phy/hsl_phy.c b/src/hsl/phy/hsl_phy.c
|
||||
index f2cf90e2..efab2343 100644
|
||||
--- a/src/hsl/phy/hsl_phy.c
|
||||
+++ b/src/hsl/phy/hsl_phy.c
|
||||
@@ -28,7 +28,7 @@
|
||||
#if defined(ATHENA) ||defined(SHIVA) ||defined(HORUS)
|
||||
#include <f2_phy.h>
|
||||
#endif
|
||||
-#ifdef MP
|
||||
+#ifdef IN_MP_PHY
|
||||
#include "mpge_phy.h"
|
||||
#endif
|
||||
#ifdef IN_MALIBU_PHY
|
||||
@@ -94,7 +94,7 @@ phy_driver_instance_t ssdk_phy_driver[] =
|
||||
#else
|
||||
{SFP_PHY_CHIP, {0}, NULL, NULL, NULL},
|
||||
#endif
|
||||
- #ifdef MP
|
||||
+ #ifdef IN_MP_PHY
|
||||
{MPGE_PHY_CHIP, {0}, NULL, mpge_phy_init, NULL},
|
||||
#else
|
||||
{MPGE_PHY_CHIP, {0}, NULL, NULL, NULL},
|
||||
--
|
||||
2.40.1
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 01fb404dbda1872ad99cea88bf43313bed30200a Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Sun, 8 Sep 2024 15:24:07 +0800
|
||||
Subject: [PATCH] init: MP: allow to ignore reset controlls
|
||||
|
||||
The SSDK is not used anymore to initialize the internal IPQ5018 GE PHY as
|
||||
there is a separate driver pending upstream review/approval:
|
||||
https://lore.kernel.org/all/TYZPR01MB5556D5568546D6DA4313209EC9762@ \
|
||||
TYZPR01MB5556.apcprd01.prod.exchangelabs.com/
|
||||
|
||||
As such, change the code to not error out when the reset controls aren't
|
||||
found in the DTS where the SSDK expects them. These resets are now defined
|
||||
under the definition based on the new driver mentioned above.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
src/init/ssdk_clk.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/init/ssdk_clk.c b/src/init/ssdk_clk.c
|
||||
index 71e59452..bc244c6e 100644
|
||||
--- a/src/init/ssdk_clk.c
|
||||
+++ b/src/init/ssdk_clk.c
|
||||
@@ -1282,10 +1282,8 @@ ssdk_mp_reset_init(void)
|
||||
|
||||
for (i = 0; i < MP_BCR_RST_MAX; i++) {
|
||||
rst = of_reset_control_get(rst_node, mp_rst_ids[i]);
|
||||
- if (IS_ERR(rst)) {
|
||||
- SSDK_ERROR("%s not exist!\n", mp_rst_ids[i]);
|
||||
- return;
|
||||
- }
|
||||
+ if (IS_ERR(rst))
|
||||
+ continue;
|
||||
ssdk_gcc_reset(rst, SSDK_RESET_ASSERT);
|
||||
msleep(200);
|
||||
ssdk_gcc_reset(rst, SSDK_RESET_DEASSERT);
|
||||
--
|
||||
2.40.1
|
||||
|
@ -0,0 +1,82 @@
|
||||
From a4378eb29c7b9dd95601d20f507a2220457f8ede Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Sun, 8 Sep 2024 15:24:07 +0800
|
||||
Subject: [PATCH] MP: fix build issues
|
||||
|
||||
Enable the IN_VSI make flag which enables macro definitions needed to
|
||||
successfully compile the SSDK for the ipq50xx target. In addition, fix an
|
||||
incorrect return type by expanding the macro called and return a boolean
|
||||
instead of an integer.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
config | 30 +-----------------------------
|
||||
src/adpt/mp/adpt_mp_portctrl.c | 3 ++-
|
||||
2 files changed, 3 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/config b/config
|
||||
index 1f74e4f8..58d67648 100644
|
||||
--- a/config
|
||||
+++ b/config
|
||||
@@ -374,6 +374,7 @@ ifneq (, $(filter MPPE APPE HPPE CPPE ALL_CHIP, $(CHIP_TYPE)))
|
||||
endif
|
||||
|
||||
ifneq (, $(filter MP, $(CHIP_TYPE)))
|
||||
+ IN_VSI=TRUE
|
||||
IN_UNIPHY=TRUE
|
||||
endif
|
||||
|
||||
@@ -436,35 +437,6 @@ endif
|
||||
# SDK Features According To Specfic Switch #
|
||||
#############################################
|
||||
ifeq (MP, $(CHIP_TYPE))
|
||||
- ifeq (disable, $(ISISC_ENABLE))
|
||||
- IN_ACL=FALSE
|
||||
- IN_FDB=FALSE
|
||||
- IN_IGMP=FALSE
|
||||
- IN_LEAKY=FALSE
|
||||
- IN_LED=FALSE
|
||||
- IN_MIRROR=FALSE
|
||||
- IN_MISC=FALSE
|
||||
- IN_PORTVLAN=FALSE
|
||||
- IN_QOS=FALSE
|
||||
- IN_RATE=FALSE
|
||||
- IN_STP=FALSE
|
||||
- IN_VLAN=FALSE
|
||||
- IN_REDUCED_ACL=FALSE
|
||||
- IN_COSMAP=FALSE
|
||||
- IN_IP=FALSE
|
||||
- IN_NAT=FALSE
|
||||
- IN_FLOW=FALSE
|
||||
- IN_TRUNK=FALSE
|
||||
- IN_RSS_HASH=FALSE
|
||||
- IN_SEC=FALSE
|
||||
- IN_QM=FALSE
|
||||
- IN_PPPOE=FALSE
|
||||
- IN_VSI=FALSE
|
||||
- IN_SERVCODE=FALSE
|
||||
- IN_BM=FALSE
|
||||
- IN_SHAPER=FALSE
|
||||
- IN_POLICER=FALSE
|
||||
- endif
|
||||
IN_CTRLPKT=TRUE
|
||||
endif
|
||||
|
||||
diff --git a/src/adpt/mp/adpt_mp_portctrl.c b/src/adpt/mp/adpt_mp_portctrl.c
|
||||
index db60fc72..c230e214 100644
|
||||
--- a/src/adpt/mp/adpt_mp_portctrl.c
|
||||
+++ b/src/adpt/mp/adpt_mp_portctrl.c
|
||||
@@ -45,7 +45,8 @@ _adpt_mp_gcc_mac_clock_set(a_uint32_t dev_id,
|
||||
static a_bool_t
|
||||
_adpt_mp_port_phy_connected (a_uint32_t dev_id, fal_port_t port_id)
|
||||
{
|
||||
- ADPT_DEV_ID_CHECK(dev_id);
|
||||
+ if (dev_id >= SW_MAX_NR_DEV)
|
||||
+ return A_FALSE;
|
||||
|
||||
/* force port which connect s17c or other device chip*/
|
||||
if (hsl_port_feature_get(dev_id, port_id, PHY_F_FORCE | PHY_F_SFP)) {
|
||||
--
|
||||
2.40.1
|
||||
|
@ -0,0 +1,57 @@
|
||||
From a90a9f3e2a21cb87c2cbf2ddb999846aa614e88a Mon Sep 17 00:00:00 2001
|
||||
From: Ziyang Huang <hzyitc@outlook.com>
|
||||
Date: Sun, 8 Sep 2024 15:24:07 +0800
|
||||
Subject: [PATCH 2/2] init: replace ioremap_nocache() with ioremap()
|
||||
|
||||
As per https://lore.kernel.org/linux-mips/20191209194819.GA28157@lst.de/T/,
|
||||
ioremap_nocache is deprecated so let's replace all calls by ioremap instead.
|
||||
|
||||
Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
src/init/ssdk_clk.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/init/ssdk_clk.c b/src/init/ssdk_clk.c
|
||||
index bc244c6e..dc45691e 100644
|
||||
--- a/src/init/ssdk_clk.c
|
||||
+++ b/src/init/ssdk_clk.c
|
||||
@@ -1183,7 +1183,7 @@ ssdk_mp_tcsr_get(a_uint32_t tcsr_offset, a_uint32_t *tcsr_val)
|
||||
{
|
||||
void __iomem *tcsr_base = NULL;
|
||||
|
||||
- tcsr_base = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
|
||||
+ tcsr_base = ioremap(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
|
||||
if (!tcsr_base)
|
||||
{
|
||||
SSDK_ERROR("Failed to map tcsr eth address!\n");
|
||||
@@ -1200,7 +1200,7 @@ ssdk_mp_tcsr_set(a_uint32_t tcsr_offset, a_uint32_t tcsr_val)
|
||||
{
|
||||
void __iomem *tcsr_base = NULL;
|
||||
|
||||
- tcsr_base = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
|
||||
+ tcsr_base = ioremap(TCSR_ETH_ADDR, TCSR_ETH_SIZE);
|
||||
if (!tcsr_base)
|
||||
{
|
||||
SSDK_ERROR("Failed to map tcsr eth address!\n");
|
||||
@@ -1248,7 +1248,7 @@ ssdk_mp_cmnblk_stable_check(void)
|
||||
a_uint32_t reg_val;
|
||||
int i, loops = 20;
|
||||
|
||||
- pll_lock = ioremap_nocache(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE);
|
||||
+ pll_lock = ioremap(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE);
|
||||
if (!pll_lock) {
|
||||
SSDK_ERROR("Failed to map CMN PLL LOCK register!\n");
|
||||
return A_FALSE;
|
||||
@@ -1303,7 +1303,7 @@ static void ssdk_cmnblk_pll_src_set(enum cmnblk_pll_src_type pll_source)
|
||||
void __iomem *cmn_pll_src_base = NULL;
|
||||
a_uint32_t reg_val;
|
||||
|
||||
- cmn_pll_src_base = ioremap_nocache(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE);
|
||||
+ cmn_pll_src_base = ioremap(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE);
|
||||
if (!cmn_pll_src_base) {
|
||||
SSDK_ERROR("Failed to map cmn pll source address!\n");
|
||||
return;
|
||||
--
|
||||
2.40.1
|
||||
|
@ -1,12 +1,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=r8168
|
||||
PKG_VERSION:=8.054.00
|
||||
PKG_VERSION:=8.055.00
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=https://github.com/openwrt/rtl8168/releases/download/$(PKG_VERSION)
|
||||
PKG_HASH:=5480120cf823e991e8cbd325118c1ec0c57d8f42760ba1a7334bd07d291d235d
|
||||
PKG_HASH:=61deb2a9cb7d6b08748ad51734b108da95d629712b64b204e2e6bd3f16d0a48f
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_LICENSE:=GPLv2
|
||||
|
@ -13,7 +13,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
|
||||
--- a/src/r8168_n.c
|
||||
+++ b/src/r8168_n.c
|
||||
@@ -1655,9 +1655,9 @@ static int proc_dump_rx_desc_2(struct se
|
||||
@@ -1668,9 +1668,9 @@ static int proc_dump_rx_desc_2(struct se
|
||||
j, k);
|
||||
for (i=0; i<(tp->RxDescLength/4); i++) {
|
||||
if (!(i % 4))
|
||||
|
@ -18,7 +18,7 @@ Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
|
||||
|
||||
--- a/src/r8168.h
|
||||
+++ b/src/r8168.h
|
||||
@@ -1468,6 +1468,8 @@ enum RTL8168_register_content {
|
||||
@@ -1480,6 +1480,8 @@ enum RTL8168_register_content {
|
||||
LinkStatus = 0x02,
|
||||
FullDup = 0x01,
|
||||
|
||||
@ -37,7 +37,7 @@ Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -5369,6 +5370,36 @@ rtl8168_link_down_patch(struct net_devic
|
||||
@@ -5396,6 +5397,38 @@ rtl8168_link_down_patch(struct net_devic
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -66,6 +66,8 @@ Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
|
||||
+ speed = SPEED_100;
|
||||
+ else if (status & _10bps)
|
||||
+ speed = SPEED_10;
|
||||
+ else if (eee_giga_lite)
|
||||
+ speed = SPEED_1000;
|
||||
+ }
|
||||
+
|
||||
+ return speed;
|
||||
@ -74,7 +76,7 @@ Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
|
||||
static void
|
||||
rtl8168_check_link_status(struct net_device *dev)
|
||||
{
|
||||
@@ -5388,11 +5419,18 @@ rtl8168_check_link_status(struct net_dev
|
||||
@@ -5415,11 +5448,18 @@ rtl8168_check_link_status(struct net_dev
|
||||
if (link_status_on) {
|
||||
rtl8168_link_on_patch(dev);
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
From d48a5472b8f2b29800bb25913f9403765005f1bc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
|
||||
Date: Mon, 18 Sep 2023 21:19:14 +0200
|
||||
Subject: [PATCH] net: dsa: realtek: Convert to platform remove callback
|
||||
returning void
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The .remove() callback for a platform driver returns an int which makes
|
||||
many driver authors wrongly assume it's possible to do error handling by
|
||||
returning an error code. However the value returned is ignored (apart
|
||||
from emitting a warning) and this typically results in resource leaks.
|
||||
To improve here there is a quest to make the remove callback return
|
||||
void. In the first step of this quest all drivers are converted to
|
||||
.remove_new() which already returns void. Eventually after all drivers
|
||||
are converted, .remove_new() is renamed to .remove().
|
||||
|
||||
Trivially convert this driver from always returning zero in the remove
|
||||
callback to the void returning variant.
|
||||
|
||||
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -506,12 +506,12 @@ static int realtek_smi_probe(struct plat
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int realtek_smi_remove(struct platform_device *pdev)
|
||||
+static void realtek_smi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct realtek_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
if (!priv)
|
||||
- return 0;
|
||||
+ return;
|
||||
|
||||
dsa_unregister_switch(priv->ds);
|
||||
if (priv->slave_mii_bus)
|
||||
@@ -520,8 +520,6 @@ static int realtek_smi_remove(struct pla
|
||||
/* leave the device reset asserted */
|
||||
if (priv->reset)
|
||||
gpiod_set_value(priv->reset, 1);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static void realtek_smi_shutdown(struct platform_device *pdev)
|
||||
@@ -559,7 +557,7 @@ static struct platform_driver realtek_sm
|
||||
.of_match_table = realtek_smi_of_match,
|
||||
},
|
||||
.probe = realtek_smi_probe,
|
||||
- .remove = realtek_smi_remove,
|
||||
+ .remove_new = realtek_smi_remove,
|
||||
.shutdown = realtek_smi_shutdown,
|
||||
};
|
||||
module_platform_driver(realtek_smi_driver);
|
@ -0,0 +1,30 @@
|
||||
From 33f4336cbd32c21717b60d013693a0bd51a27db6 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:37 -0300
|
||||
Subject: net: dsa: realtek: drop cleanup from realtek_ops
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It was never used and never referenced.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek.h | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek.h
|
||||
+++ b/drivers/net/dsa/realtek/realtek.h
|
||||
@@ -91,7 +91,6 @@ struct realtek_ops {
|
||||
int (*detect)(struct realtek_priv *priv);
|
||||
int (*reset_chip)(struct realtek_priv *priv);
|
||||
int (*setup)(struct realtek_priv *priv);
|
||||
- void (*cleanup)(struct realtek_priv *priv);
|
||||
int (*get_mib_counter)(struct realtek_priv *priv,
|
||||
int port,
|
||||
struct rtl8366_mib_counter *mib,
|
@ -0,0 +1,146 @@
|
||||
From ded3813b44fe11a3bbd2c9d7df8870e8c19a7ccd Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:38 -0300
|
||||
Subject: net: dsa: realtek: introduce REALTEK_DSA namespace
|
||||
|
||||
Create a namespace to group the exported symbols.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-mdio.c | 1 +
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 1 +
|
||||
drivers/net/dsa/realtek/rtl8365mb.c | 1 +
|
||||
drivers/net/dsa/realtek/rtl8366-core.c | 22 +++++++++++-----------
|
||||
drivers/net/dsa/realtek/rtl8366rb.c | 1 +
|
||||
5 files changed, 15 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
@@ -288,3 +288,4 @@ mdio_module_driver(realtek_mdio_driver);
|
||||
MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
|
||||
MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
|
||||
MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS(REALTEK_DSA);
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -565,3 +565,4 @@ module_platform_driver(realtek_smi_drive
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface");
|
||||
MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS(REALTEK_DSA);
|
||||
--- a/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
@@ -2178,3 +2178,4 @@ EXPORT_SYMBOL_GPL(rtl8365mb_variant);
|
||||
MODULE_AUTHOR("Alvin Šipraga <alsi@bang-olufsen.dk>");
|
||||
MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch");
|
||||
MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS(REALTEK_DSA);
|
||||
--- a/drivers/net/dsa/realtek/rtl8366-core.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366-core.c
|
||||
@@ -34,7 +34,7 @@ int rtl8366_mc_is_used(struct realtek_pr
|
||||
|
||||
return 0;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_mc_is_used);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_mc_is_used, REALTEK_DSA);
|
||||
|
||||
/**
|
||||
* rtl8366_obtain_mc() - retrieve or allocate a VLAN member configuration
|
||||
@@ -187,7 +187,7 @@ int rtl8366_set_vlan(struct realtek_priv
|
||||
|
||||
return ret;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_set_vlan);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_set_vlan, REALTEK_DSA);
|
||||
|
||||
int rtl8366_set_pvid(struct realtek_priv *priv, unsigned int port,
|
||||
unsigned int vid)
|
||||
@@ -217,7 +217,7 @@ int rtl8366_set_pvid(struct realtek_priv
|
||||
|
||||
return 0;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_set_pvid);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_set_pvid, REALTEK_DSA);
|
||||
|
||||
int rtl8366_enable_vlan4k(struct realtek_priv *priv, bool enable)
|
||||
{
|
||||
@@ -243,7 +243,7 @@ int rtl8366_enable_vlan4k(struct realtek
|
||||
priv->vlan4k_enabled = enable;
|
||||
return 0;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_enable_vlan4k);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan4k, REALTEK_DSA);
|
||||
|
||||
int rtl8366_enable_vlan(struct realtek_priv *priv, bool enable)
|
||||
{
|
||||
@@ -265,7 +265,7 @@ int rtl8366_enable_vlan(struct realtek_p
|
||||
|
||||
return ret;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_enable_vlan);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_enable_vlan, REALTEK_DSA);
|
||||
|
||||
int rtl8366_reset_vlan(struct realtek_priv *priv)
|
||||
{
|
||||
@@ -290,7 +290,7 @@ int rtl8366_reset_vlan(struct realtek_pr
|
||||
|
||||
return 0;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_reset_vlan);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_reset_vlan, REALTEK_DSA);
|
||||
|
||||
int rtl8366_vlan_add(struct dsa_switch *ds, int port,
|
||||
const struct switchdev_obj_port_vlan *vlan,
|
||||
@@ -345,7 +345,7 @@ int rtl8366_vlan_add(struct dsa_switch *
|
||||
|
||||
return 0;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_vlan_add);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_add, REALTEK_DSA);
|
||||
|
||||
int rtl8366_vlan_del(struct dsa_switch *ds, int port,
|
||||
const struct switchdev_obj_port_vlan *vlan)
|
||||
@@ -389,7 +389,7 @@ int rtl8366_vlan_del(struct dsa_switch *
|
||||
|
||||
return 0;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_vlan_del);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_vlan_del, REALTEK_DSA);
|
||||
|
||||
void rtl8366_get_strings(struct dsa_switch *ds, int port, u32 stringset,
|
||||
uint8_t *data)
|
||||
@@ -407,7 +407,7 @@ void rtl8366_get_strings(struct dsa_swit
|
||||
mib->name, ETH_GSTRING_LEN);
|
||||
}
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_get_strings);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_get_strings, REALTEK_DSA);
|
||||
|
||||
int rtl8366_get_sset_count(struct dsa_switch *ds, int port, int sset)
|
||||
{
|
||||
@@ -421,7 +421,7 @@ int rtl8366_get_sset_count(struct dsa_sw
|
||||
|
||||
return priv->num_mib_counters;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_get_sset_count);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_get_sset_count, REALTEK_DSA);
|
||||
|
||||
void rtl8366_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data)
|
||||
{
|
||||
@@ -445,4 +445,4 @@ void rtl8366_get_ethtool_stats(struct ds
|
||||
data[i] = mibvalue;
|
||||
}
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(rtl8366_get_ethtool_stats);
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl8366_get_ethtool_stats, REALTEK_DSA);
|
||||
--- a/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
@@ -1852,3 +1852,4 @@ EXPORT_SYMBOL_GPL(rtl8366rb_variant);
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("Driver for RTL8366RB ethernet switch");
|
||||
MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS(REALTEK_DSA);
|
@ -0,0 +1,539 @@
|
||||
From bce254b839abe67577bebdef0838796af409c229 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:39 -0300
|
||||
Subject: net: dsa: realtek: convert variants into real drivers
|
||||
|
||||
Previously, the interface modules realtek-smi and realtek-mdio served as
|
||||
a platform and an MDIO driver, respectively. Each interface module
|
||||
redundantly specified the same compatible strings for both variants and
|
||||
referenced symbols from the variants.
|
||||
|
||||
Now, each variant module has been transformed into a unified driver
|
||||
serving both as a platform and an MDIO driver. This modification
|
||||
reverses the relationship between the interface and variant modules,
|
||||
with the variant module now utilizing symbols from the interface
|
||||
modules.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/Kconfig | 20 +++----
|
||||
drivers/net/dsa/realtek/realtek-mdio.c | 68 +++++++++++++++---------
|
||||
drivers/net/dsa/realtek/realtek-mdio.h | 48 +++++++++++++++++
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 73 +++++++++++++++-----------
|
||||
drivers/net/dsa/realtek/realtek-smi.h | 48 +++++++++++++++++
|
||||
drivers/net/dsa/realtek/rtl8365mb.c | 54 ++++++++++++++++++-
|
||||
drivers/net/dsa/realtek/rtl8366rb.c | 54 ++++++++++++++++++-
|
||||
7 files changed, 292 insertions(+), 73 deletions(-)
|
||||
create mode 100644 drivers/net/dsa/realtek/realtek-mdio.h
|
||||
create mode 100644 drivers/net/dsa/realtek/realtek-smi.h
|
||||
|
||||
--- a/drivers/net/dsa/realtek/Kconfig
|
||||
+++ b/drivers/net/dsa/realtek/Kconfig
|
||||
@@ -16,37 +16,29 @@ menuconfig NET_DSA_REALTEK
|
||||
if NET_DSA_REALTEK
|
||||
|
||||
config NET_DSA_REALTEK_MDIO
|
||||
- tristate "Realtek MDIO interface driver"
|
||||
+ tristate "Realtek MDIO interface support"
|
||||
depends on OF
|
||||
- depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB
|
||||
- depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB
|
||||
- depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB
|
||||
help
|
||||
Select to enable support for registering switches configured
|
||||
through MDIO.
|
||||
|
||||
config NET_DSA_REALTEK_SMI
|
||||
- tristate "Realtek SMI interface driver"
|
||||
+ tristate "Realtek SMI interface support"
|
||||
depends on OF
|
||||
- depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB
|
||||
- depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB
|
||||
- depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB
|
||||
help
|
||||
Select to enable support for registering switches connected
|
||||
through SMI.
|
||||
|
||||
config NET_DSA_REALTEK_RTL8365MB
|
||||
- tristate "Realtek RTL8365MB switch subdriver"
|
||||
- imply NET_DSA_REALTEK_SMI
|
||||
- imply NET_DSA_REALTEK_MDIO
|
||||
+ tristate "Realtek RTL8365MB switch driver"
|
||||
+ depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO
|
||||
select NET_DSA_TAG_RTL8_4
|
||||
help
|
||||
Select to enable support for Realtek RTL8365MB-VC and RTL8367S.
|
||||
|
||||
config NET_DSA_REALTEK_RTL8366RB
|
||||
- tristate "Realtek RTL8366RB switch subdriver"
|
||||
- imply NET_DSA_REALTEK_SMI
|
||||
- imply NET_DSA_REALTEK_MDIO
|
||||
+ tristate "Realtek RTL8366RB switch driver"
|
||||
+ depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO
|
||||
select NET_DSA_TAG_RTL4_A
|
||||
help
|
||||
Select to enable support for Realtek RTL8366RB.
|
||||
--- a/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "realtek.h"
|
||||
+#include "realtek-mdio.h"
|
||||
|
||||
/* Read/write via mdiobus */
|
||||
#define REALTEK_MDIO_CTRL0_REG 31
|
||||
@@ -140,7 +141,19 @@ static const struct regmap_config realte
|
||||
.disable_locking = true,
|
||||
};
|
||||
|
||||
-static int realtek_mdio_probe(struct mdio_device *mdiodev)
|
||||
+/**
|
||||
+ * realtek_mdio_probe() - Probe a platform device for an MDIO-connected switch
|
||||
+ * @mdiodev: mdio_device to probe on.
|
||||
+ *
|
||||
+ * This function should be used as the .probe in an mdio_driver. It
|
||||
+ * initializes realtek_priv and read data from the device-tree node. The switch
|
||||
+ * is hard reset if a method is provided. It checks the switch chip ID and,
|
||||
+ * finally, a DSA switch is registered.
|
||||
+ *
|
||||
+ * Context: Can sleep. Takes and releases priv->map_lock.
|
||||
+ * Return: Returns 0 on success, a negative error on failure.
|
||||
+ */
|
||||
+int realtek_mdio_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct realtek_priv *priv;
|
||||
struct device *dev = &mdiodev->dev;
|
||||
@@ -235,8 +248,20 @@ static int realtek_mdio_probe(struct mdi
|
||||
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_NS_GPL(realtek_mdio_probe, REALTEK_DSA);
|
||||
|
||||
-static void realtek_mdio_remove(struct mdio_device *mdiodev)
|
||||
+/**
|
||||
+ * realtek_mdio_remove() - Remove the driver of an MDIO-connected switch
|
||||
+ * @mdiodev: mdio_device to be removed.
|
||||
+ *
|
||||
+ * This function should be used as the .remove_new in an mdio_driver. First
|
||||
+ * it unregisters the DSA switch and cleans internal data. If a method is
|
||||
+ * provided, the hard reset is asserted to avoid traffic leakage.
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Nothing.
|
||||
+ */
|
||||
+void realtek_mdio_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
|
||||
@@ -249,8 +274,21 @@ static void realtek_mdio_remove(struct m
|
||||
if (priv->reset)
|
||||
gpiod_set_value(priv->reset, 1);
|
||||
}
|
||||
+EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove, REALTEK_DSA);
|
||||
|
||||
-static void realtek_mdio_shutdown(struct mdio_device *mdiodev)
|
||||
+/**
|
||||
+ * realtek_mdio_shutdown() - Shutdown the driver of a MDIO-connected switch
|
||||
+ * @mdiodev: mdio_device shutting down.
|
||||
+ *
|
||||
+ * This function should be used as the .shutdown in an mdio_driver. It shuts
|
||||
+ * down the DSA switch and cleans the platform driver data, to prevent
|
||||
+ * realtek_mdio_remove() from running afterwards, which is possible if the
|
||||
+ * parent bus implements its own .shutdown() as .remove().
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Nothing.
|
||||
+ */
|
||||
+void realtek_mdio_shutdown(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
|
||||
@@ -261,29 +299,7 @@ static void realtek_mdio_shutdown(struct
|
||||
|
||||
dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
}
|
||||
-
|
||||
-static const struct of_device_id realtek_mdio_of_match[] = {
|
||||
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
|
||||
- { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
|
||||
-#endif
|
||||
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
|
||||
- { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
|
||||
-#endif
|
||||
- { /* sentinel */ },
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(of, realtek_mdio_of_match);
|
||||
-
|
||||
-static struct mdio_driver realtek_mdio_driver = {
|
||||
- .mdiodrv.driver = {
|
||||
- .name = "realtek-mdio",
|
||||
- .of_match_table = realtek_mdio_of_match,
|
||||
- },
|
||||
- .probe = realtek_mdio_probe,
|
||||
- .remove = realtek_mdio_remove,
|
||||
- .shutdown = realtek_mdio_shutdown,
|
||||
-};
|
||||
-
|
||||
-mdio_module_driver(realtek_mdio_driver);
|
||||
+EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, REALTEK_DSA);
|
||||
|
||||
MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
|
||||
MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.h
|
||||
@@ -0,0 +1,48 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
+
|
||||
+#ifndef _REALTEK_MDIO_H
|
||||
+#define _REALTEK_MDIO_H
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO)
|
||||
+
|
||||
+static inline int realtek_mdio_driver_register(struct mdio_driver *drv)
|
||||
+{
|
||||
+ return mdio_driver_register(drv);
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv)
|
||||
+{
|
||||
+ mdio_driver_unregister(drv);
|
||||
+}
|
||||
+
|
||||
+int realtek_mdio_probe(struct mdio_device *mdiodev);
|
||||
+void realtek_mdio_remove(struct mdio_device *mdiodev);
|
||||
+void realtek_mdio_shutdown(struct mdio_device *mdiodev);
|
||||
+
|
||||
+#else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */
|
||||
+
|
||||
+static inline int realtek_mdio_driver_register(struct mdio_driver *drv)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int realtek_mdio_probe(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_mdio_remove(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_mdio_shutdown(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */
|
||||
+
|
||||
+#endif /* _REALTEK_MDIO_H */
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <linux/if_bridge.h>
|
||||
|
||||
#include "realtek.h"
|
||||
+#include "realtek-smi.h"
|
||||
|
||||
#define REALTEK_SMI_ACK_RETRY_COUNT 5
|
||||
|
||||
@@ -408,7 +409,19 @@ err_put_node:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int realtek_smi_probe(struct platform_device *pdev)
|
||||
+/**
|
||||
+ * realtek_smi_probe() - Probe a platform device for an SMI-connected switch
|
||||
+ * @pdev: platform_device to probe on.
|
||||
+ *
|
||||
+ * This function should be used as the .probe in a platform_driver. It
|
||||
+ * initializes realtek_priv and read data from the device-tree node. The switch
|
||||
+ * is hard reset if a method is provided. It checks the switch chip ID and,
|
||||
+ * finally, a DSA switch is registered.
|
||||
+ *
|
||||
+ * Context: Can sleep. Takes and releases priv->map_lock.
|
||||
+ * Return: Returns 0 on success, a negative error on failure.
|
||||
+ */
|
||||
+int realtek_smi_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct realtek_variant *var;
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -505,8 +518,20 @@ static int realtek_smi_probe(struct plat
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_NS_GPL(realtek_smi_probe, REALTEK_DSA);
|
||||
|
||||
-static void realtek_smi_remove(struct platform_device *pdev)
|
||||
+/**
|
||||
+ * realtek_smi_remove() - Remove the driver of a SMI-connected switch
|
||||
+ * @pdev: platform_device to be removed.
|
||||
+ *
|
||||
+ * This function should be used as the .remove_new in a platform_driver. First
|
||||
+ * it unregisters the DSA switch and cleans internal data. If a method is
|
||||
+ * provided, the hard reset is asserted to avoid traffic leakage.
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Nothing.
|
||||
+ */
|
||||
+void realtek_smi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct realtek_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
@@ -521,8 +546,21 @@ static void realtek_smi_remove(struct pl
|
||||
if (priv->reset)
|
||||
gpiod_set_value(priv->reset, 1);
|
||||
}
|
||||
+EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, REALTEK_DSA);
|
||||
|
||||
-static void realtek_smi_shutdown(struct platform_device *pdev)
|
||||
+/**
|
||||
+ * realtek_smi_shutdown() - Shutdown the driver of a SMI-connected switch
|
||||
+ * @pdev: platform_device shutting down.
|
||||
+ *
|
||||
+ * This function should be used as the .shutdown in a platform_driver. It shuts
|
||||
+ * down the DSA switch and cleans the platform driver data, to prevent
|
||||
+ * realtek_smi_remove() from running afterwards, which is possible if the
|
||||
+ * parent bus implements its own .shutdown() as .remove().
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Nothing.
|
||||
+ */
|
||||
+void realtek_smi_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct realtek_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
@@ -533,34 +571,7 @@ static void realtek_smi_shutdown(struct
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
}
|
||||
-
|
||||
-static const struct of_device_id realtek_smi_of_match[] = {
|
||||
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
|
||||
- {
|
||||
- .compatible = "realtek,rtl8366rb",
|
||||
- .data = &rtl8366rb_variant,
|
||||
- },
|
||||
-#endif
|
||||
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
|
||||
- {
|
||||
- .compatible = "realtek,rtl8365mb",
|
||||
- .data = &rtl8365mb_variant,
|
||||
- },
|
||||
-#endif
|
||||
- { /* sentinel */ },
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(of, realtek_smi_of_match);
|
||||
-
|
||||
-static struct platform_driver realtek_smi_driver = {
|
||||
- .driver = {
|
||||
- .name = "realtek-smi",
|
||||
- .of_match_table = realtek_smi_of_match,
|
||||
- },
|
||||
- .probe = realtek_smi_probe,
|
||||
- .remove_new = realtek_smi_remove,
|
||||
- .shutdown = realtek_smi_shutdown,
|
||||
-};
|
||||
-module_platform_driver(realtek_smi_driver);
|
||||
+EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, REALTEK_DSA);
|
||||
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface");
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.h
|
||||
@@ -0,0 +1,48 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
+
|
||||
+#ifndef _REALTEK_SMI_H
|
||||
+#define _REALTEK_SMI_H
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI)
|
||||
+
|
||||
+static inline int realtek_smi_driver_register(struct platform_driver *drv)
|
||||
+{
|
||||
+ return platform_driver_register(drv);
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_smi_driver_unregister(struct platform_driver *drv)
|
||||
+{
|
||||
+ platform_driver_unregister(drv);
|
||||
+}
|
||||
+
|
||||
+int realtek_smi_probe(struct platform_device *pdev);
|
||||
+void realtek_smi_remove(struct platform_device *pdev);
|
||||
+void realtek_smi_shutdown(struct platform_device *pdev);
|
||||
+
|
||||
+#else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */
|
||||
+
|
||||
+static inline int realtek_smi_driver_register(struct platform_driver *drv)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_smi_driver_unregister(struct platform_driver *drv)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int realtek_smi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_smi_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void realtek_smi_shutdown(struct platform_device *pdev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */
|
||||
+
|
||||
+#endif /* _REALTEK_SMI_H */
|
||||
--- a/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
@@ -101,6 +101,8 @@
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
#include "realtek.h"
|
||||
+#include "realtek-smi.h"
|
||||
+#include "realtek-mdio.h"
|
||||
|
||||
/* Family-specific data and limits */
|
||||
#define RTL8365MB_PHYADDRMAX 7
|
||||
@@ -2173,7 +2175,57 @@ const struct realtek_variant rtl8365mb_v
|
||||
.cmd_write = 0xb8,
|
||||
.chip_data_sz = sizeof(struct rtl8365mb),
|
||||
};
|
||||
-EXPORT_SYMBOL_GPL(rtl8365mb_variant);
|
||||
+
|
||||
+static const struct of_device_id rtl8365mb_of_match[] = {
|
||||
+ { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rtl8365mb_of_match);
|
||||
+
|
||||
+static struct platform_driver rtl8365mb_smi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "rtl8365mb-smi",
|
||||
+ .of_match_table = rtl8365mb_of_match,
|
||||
+ },
|
||||
+ .probe = realtek_smi_probe,
|
||||
+ .remove_new = realtek_smi_remove,
|
||||
+ .shutdown = realtek_smi_shutdown,
|
||||
+};
|
||||
+
|
||||
+static struct mdio_driver rtl8365mb_mdio_driver = {
|
||||
+ .mdiodrv.driver = {
|
||||
+ .name = "rtl8365mb-mdio",
|
||||
+ .of_match_table = rtl8365mb_of_match,
|
||||
+ },
|
||||
+ .probe = realtek_mdio_probe,
|
||||
+ .remove = realtek_mdio_remove,
|
||||
+ .shutdown = realtek_mdio_shutdown,
|
||||
+};
|
||||
+
|
||||
+static int rtl8365mb_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = realtek_mdio_driver_register(&rtl8365mb_mdio_driver);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = realtek_smi_driver_register(&rtl8365mb_smi_driver);
|
||||
+ if (ret) {
|
||||
+ realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+module_init(rtl8365mb_init);
|
||||
+
|
||||
+static void __exit rtl8365mb_exit(void)
|
||||
+{
|
||||
+ realtek_smi_driver_unregister(&rtl8365mb_smi_driver);
|
||||
+ realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
|
||||
+}
|
||||
+module_exit(rtl8365mb_exit);
|
||||
|
||||
MODULE_AUTHOR("Alvin Šipraga <alsi@bang-olufsen.dk>");
|
||||
MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch");
|
||||
--- a/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "realtek.h"
|
||||
+#include "realtek-smi.h"
|
||||
+#include "realtek-mdio.h"
|
||||
|
||||
#define RTL8366RB_PORT_NUM_CPU 5
|
||||
#define RTL8366RB_NUM_PORTS 6
|
||||
@@ -1847,7 +1849,57 @@ const struct realtek_variant rtl8366rb_v
|
||||
.cmd_write = 0xa8,
|
||||
.chip_data_sz = sizeof(struct rtl8366rb),
|
||||
};
|
||||
-EXPORT_SYMBOL_GPL(rtl8366rb_variant);
|
||||
+
|
||||
+static const struct of_device_id rtl8366rb_of_match[] = {
|
||||
+ { .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, rtl8366rb_of_match);
|
||||
+
|
||||
+static struct platform_driver rtl8366rb_smi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "rtl8366rb-smi",
|
||||
+ .of_match_table = rtl8366rb_of_match,
|
||||
+ },
|
||||
+ .probe = realtek_smi_probe,
|
||||
+ .remove_new = realtek_smi_remove,
|
||||
+ .shutdown = realtek_smi_shutdown,
|
||||
+};
|
||||
+
|
||||
+static struct mdio_driver rtl8366rb_mdio_driver = {
|
||||
+ .mdiodrv.driver = {
|
||||
+ .name = "rtl8366rb-mdio",
|
||||
+ .of_match_table = rtl8366rb_of_match,
|
||||
+ },
|
||||
+ .probe = realtek_mdio_probe,
|
||||
+ .remove = realtek_mdio_remove,
|
||||
+ .shutdown = realtek_mdio_shutdown,
|
||||
+};
|
||||
+
|
||||
+static int rtl8366rb_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = realtek_mdio_driver_register(&rtl8366rb_mdio_driver);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = realtek_smi_driver_register(&rtl8366rb_smi_driver);
|
||||
+ if (ret) {
|
||||
+ realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+module_init(rtl8366rb_init);
|
||||
+
|
||||
+static void __exit rtl8366rb_exit(void)
|
||||
+{
|
||||
+ realtek_smi_driver_unregister(&rtl8366rb_smi_driver);
|
||||
+ realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver);
|
||||
+}
|
||||
+module_exit(rtl8366rb_exit);
|
||||
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("Driver for RTL8366RB ethernet switch");
|
@ -0,0 +1,91 @@
|
||||
From 4667a1db2f550d23e01ba655fce331196ead6e92 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:40 -0300
|
||||
Subject: net: dsa: realtek: keep variant reference in
|
||||
realtek_priv
|
||||
|
||||
Instead of copying values from the variant, we can keep a reference in
|
||||
realtek_priv.
|
||||
|
||||
This is a preliminary change for sharing code betwen interfaces. It will
|
||||
allow to move most of the probe into a common module while still allow
|
||||
code specific to each interface to read variant fields.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-mdio.c | 4 +---
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 10 ++++------
|
||||
drivers/net/dsa/realtek/realtek.h | 5 ++---
|
||||
3 files changed, 7 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
@@ -196,9 +196,7 @@ int realtek_mdio_probe(struct mdio_devic
|
||||
priv->dev = &mdiodev->dev;
|
||||
priv->chip_data = (void *)priv + sizeof(*priv);
|
||||
|
||||
- priv->clk_delay = var->clk_delay;
|
||||
- priv->cmd_read = var->cmd_read;
|
||||
- priv->cmd_write = var->cmd_write;
|
||||
+ priv->variant = var;
|
||||
priv->ops = var->ops;
|
||||
|
||||
priv->write_reg_noack = realtek_mdio_write;
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
static inline void realtek_smi_clk_delay(struct realtek_priv *priv)
|
||||
{
|
||||
- ndelay(priv->clk_delay);
|
||||
+ ndelay(priv->variant->clk_delay);
|
||||
}
|
||||
|
||||
static void realtek_smi_start(struct realtek_priv *priv)
|
||||
@@ -209,7 +209,7 @@ static int realtek_smi_read_reg(struct r
|
||||
realtek_smi_start(priv);
|
||||
|
||||
/* Send READ command */
|
||||
- ret = realtek_smi_write_byte(priv, priv->cmd_read);
|
||||
+ ret = realtek_smi_write_byte(priv, priv->variant->cmd_read);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -250,7 +250,7 @@ static int realtek_smi_write_reg(struct
|
||||
realtek_smi_start(priv);
|
||||
|
||||
/* Send WRITE command */
|
||||
- ret = realtek_smi_write_byte(priv, priv->cmd_write);
|
||||
+ ret = realtek_smi_write_byte(priv, priv->variant->cmd_write);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@@ -459,9 +459,7 @@ int realtek_smi_probe(struct platform_de
|
||||
|
||||
/* Link forward and backward */
|
||||
priv->dev = dev;
|
||||
- priv->clk_delay = var->clk_delay;
|
||||
- priv->cmd_read = var->cmd_read;
|
||||
- priv->cmd_write = var->cmd_write;
|
||||
+ priv->variant = var;
|
||||
priv->ops = var->ops;
|
||||
|
||||
priv->setup_interface = realtek_smi_setup_mdio;
|
||||
--- a/drivers/net/dsa/realtek/realtek.h
|
||||
+++ b/drivers/net/dsa/realtek/realtek.h
|
||||
@@ -58,9 +58,8 @@ struct realtek_priv {
|
||||
struct mii_bus *bus;
|
||||
int mdio_addr;
|
||||
|
||||
- unsigned int clk_delay;
|
||||
- u8 cmd_read;
|
||||
- u8 cmd_write;
|
||||
+ const struct realtek_variant *variant;
|
||||
+
|
||||
spinlock_t lock; /* Locks around command writes */
|
||||
struct dsa_switch *ds;
|
||||
struct irq_domain *irqdomain;
|
@ -0,0 +1,875 @@
|
||||
From 8be040ecd94c1a9a137927d18534edfae0a9b68a Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:41 -0300
|
||||
Subject: net: dsa: realtek: common rtl83xx module
|
||||
|
||||
Some code can be shared between both interface modules (MDIO and SMI)
|
||||
and among variants. These interface functions migrated to a common
|
||||
module:
|
||||
|
||||
- rtl83xx_lock
|
||||
- rtl83xx_unlock
|
||||
- rtl83xx_probe
|
||||
- rtl83xx_register_switch
|
||||
- rtl83xx_unregister_switch
|
||||
- rtl83xx_shutdown
|
||||
- rtl83xx_remove
|
||||
|
||||
The reset during probe was moved to the end of the common probe. This way,
|
||||
we avoid a reset if anything else fails.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/Makefile | 2 +
|
||||
drivers/net/dsa/realtek/realtek-mdio.c | 152 +++-------------
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 166 ++++-------------
|
||||
drivers/net/dsa/realtek/realtek.h | 1 +
|
||||
drivers/net/dsa/realtek/rtl8365mb.c | 9 +-
|
||||
drivers/net/dsa/realtek/rtl8366rb.c | 9 +-
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 235 +++++++++++++++++++++++++
|
||||
drivers/net/dsa/realtek/rtl83xx.h | 21 +++
|
||||
8 files changed, 322 insertions(+), 273 deletions(-)
|
||||
create mode 100644 drivers/net/dsa/realtek/rtl83xx.c
|
||||
create mode 100644 drivers/net/dsa/realtek/rtl83xx.h
|
||||
|
||||
--- a/drivers/net/dsa/realtek/Makefile
|
||||
+++ b/drivers/net/dsa/realtek/Makefile
|
||||
@@ -1,4 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
+obj-$(CONFIG_NET_DSA_REALTEK) += realtek_dsa.o
|
||||
+realtek_dsa-objs := rtl83xx.o
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_MDIO) += realtek-mdio.o
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
|
||||
--- a/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "realtek.h"
|
||||
#include "realtek-mdio.h"
|
||||
+#include "rtl83xx.h"
|
||||
|
||||
/* Read/write via mdiobus */
|
||||
#define REALTEK_MDIO_CTRL0_REG 31
|
||||
@@ -100,147 +101,41 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void realtek_mdio_lock(void *ctx)
|
||||
-{
|
||||
- struct realtek_priv *priv = ctx;
|
||||
-
|
||||
- mutex_lock(&priv->map_lock);
|
||||
-}
|
||||
-
|
||||
-static void realtek_mdio_unlock(void *ctx)
|
||||
-{
|
||||
- struct realtek_priv *priv = ctx;
|
||||
-
|
||||
- mutex_unlock(&priv->map_lock);
|
||||
-}
|
||||
-
|
||||
-static const struct regmap_config realtek_mdio_regmap_config = {
|
||||
- .reg_bits = 10, /* A4..A0 R4..R0 */
|
||||
- .val_bits = 16,
|
||||
- .reg_stride = 1,
|
||||
- /* PHY regs are at 0x8000 */
|
||||
- .max_register = 0xffff,
|
||||
- .reg_format_endian = REGMAP_ENDIAN_BIG,
|
||||
+static const struct realtek_interface_info realtek_mdio_info = {
|
||||
.reg_read = realtek_mdio_read,
|
||||
.reg_write = realtek_mdio_write,
|
||||
- .cache_type = REGCACHE_NONE,
|
||||
- .lock = realtek_mdio_lock,
|
||||
- .unlock = realtek_mdio_unlock,
|
||||
-};
|
||||
-
|
||||
-static const struct regmap_config realtek_mdio_nolock_regmap_config = {
|
||||
- .reg_bits = 10, /* A4..A0 R4..R0 */
|
||||
- .val_bits = 16,
|
||||
- .reg_stride = 1,
|
||||
- /* PHY regs are at 0x8000 */
|
||||
- .max_register = 0xffff,
|
||||
- .reg_format_endian = REGMAP_ENDIAN_BIG,
|
||||
- .reg_read = realtek_mdio_read,
|
||||
- .reg_write = realtek_mdio_write,
|
||||
- .cache_type = REGCACHE_NONE,
|
||||
- .disable_locking = true,
|
||||
};
|
||||
|
||||
/**
|
||||
* realtek_mdio_probe() - Probe a platform device for an MDIO-connected switch
|
||||
* @mdiodev: mdio_device to probe on.
|
||||
*
|
||||
- * This function should be used as the .probe in an mdio_driver. It
|
||||
- * initializes realtek_priv and read data from the device-tree node. The switch
|
||||
- * is hard reset if a method is provided. It checks the switch chip ID and,
|
||||
- * finally, a DSA switch is registered.
|
||||
+ * This function should be used as the .probe in an mdio_driver. After
|
||||
+ * calling the common probe function for both interfaces, it initializes the
|
||||
+ * values specific for MDIO-connected devices. Finally, it calls a common
|
||||
+ * function to register the DSA switch.
|
||||
*
|
||||
* Context: Can sleep. Takes and releases priv->map_lock.
|
||||
* Return: Returns 0 on success, a negative error on failure.
|
||||
*/
|
||||
int realtek_mdio_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
- struct realtek_priv *priv;
|
||||
struct device *dev = &mdiodev->dev;
|
||||
- const struct realtek_variant *var;
|
||||
- struct regmap_config rc;
|
||||
- struct device_node *np;
|
||||
+ struct realtek_priv *priv;
|
||||
int ret;
|
||||
|
||||
- var = of_device_get_match_data(dev);
|
||||
- if (!var)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- priv = devm_kzalloc(&mdiodev->dev,
|
||||
- size_add(sizeof(*priv), var->chip_data_sz),
|
||||
- GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- mutex_init(&priv->map_lock);
|
||||
-
|
||||
- rc = realtek_mdio_regmap_config;
|
||||
- rc.lock_arg = priv;
|
||||
- priv->map = devm_regmap_init(dev, NULL, priv, &rc);
|
||||
- if (IS_ERR(priv->map)) {
|
||||
- ret = PTR_ERR(priv->map);
|
||||
- dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
+ priv = rtl83xx_probe(dev, &realtek_mdio_info);
|
||||
+ if (IS_ERR(priv))
|
||||
+ return PTR_ERR(priv);
|
||||
|
||||
- rc = realtek_mdio_nolock_regmap_config;
|
||||
- priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
|
||||
- if (IS_ERR(priv->map_nolock)) {
|
||||
- ret = PTR_ERR(priv->map_nolock);
|
||||
- dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- priv->mdio_addr = mdiodev->addr;
|
||||
priv->bus = mdiodev->bus;
|
||||
- priv->dev = &mdiodev->dev;
|
||||
- priv->chip_data = (void *)priv + sizeof(*priv);
|
||||
-
|
||||
- priv->variant = var;
|
||||
- priv->ops = var->ops;
|
||||
-
|
||||
+ priv->mdio_addr = mdiodev->addr;
|
||||
priv->write_reg_noack = realtek_mdio_write;
|
||||
+ priv->ds_ops = priv->variant->ds_ops_mdio;
|
||||
|
||||
- np = dev->of_node;
|
||||
-
|
||||
- dev_set_drvdata(dev, priv);
|
||||
-
|
||||
- /* TODO: if power is software controlled, set up any regulators here */
|
||||
- priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
|
||||
-
|
||||
- priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(priv->reset)) {
|
||||
- dev_err(dev, "failed to get RESET GPIO\n");
|
||||
- return PTR_ERR(priv->reset);
|
||||
- }
|
||||
-
|
||||
- if (priv->reset) {
|
||||
- gpiod_set_value(priv->reset, 1);
|
||||
- dev_dbg(dev, "asserted RESET\n");
|
||||
- msleep(REALTEK_HW_STOP_DELAY);
|
||||
- gpiod_set_value(priv->reset, 0);
|
||||
- msleep(REALTEK_HW_START_DELAY);
|
||||
- dev_dbg(dev, "deasserted RESET\n");
|
||||
- }
|
||||
-
|
||||
- ret = priv->ops->detect(priv);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "unable to detect switch\n");
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
|
||||
- if (!priv->ds)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->ds->dev = dev;
|
||||
- priv->ds->num_ports = priv->num_ports;
|
||||
- priv->ds->priv = priv;
|
||||
- priv->ds->ops = var->ds_ops_mdio;
|
||||
-
|
||||
- ret = dsa_register_switch(priv->ds);
|
||||
+ ret = rtl83xx_register_switch(priv);
|
||||
if (ret) {
|
||||
- dev_err(priv->dev, "unable to register switch ret = %d\n", ret);
|
||||
+ rtl83xx_remove(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -253,8 +148,7 @@ EXPORT_SYMBOL_NS_GPL(realtek_mdio_probe,
|
||||
* @mdiodev: mdio_device to be removed.
|
||||
*
|
||||
* This function should be used as the .remove_new in an mdio_driver. First
|
||||
- * it unregisters the DSA switch and cleans internal data. If a method is
|
||||
- * provided, the hard reset is asserted to avoid traffic leakage.
|
||||
+ * it unregisters the DSA switch and then it calls the common remove function.
|
||||
*
|
||||
* Context: Can sleep.
|
||||
* Return: Nothing.
|
||||
@@ -266,11 +160,9 @@ void realtek_mdio_remove(struct mdio_dev
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
- dsa_unregister_switch(priv->ds);
|
||||
+ rtl83xx_unregister_switch(priv);
|
||||
|
||||
- /* leave the device reset asserted */
|
||||
- if (priv->reset)
|
||||
- gpiod_set_value(priv->reset, 1);
|
||||
+ rtl83xx_remove(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove, REALTEK_DSA);
|
||||
|
||||
@@ -278,10 +170,8 @@ EXPORT_SYMBOL_NS_GPL(realtek_mdio_remove
|
||||
* realtek_mdio_shutdown() - Shutdown the driver of a MDIO-connected switch
|
||||
* @mdiodev: mdio_device shutting down.
|
||||
*
|
||||
- * This function should be used as the .shutdown in an mdio_driver. It shuts
|
||||
- * down the DSA switch and cleans the platform driver data, to prevent
|
||||
- * realtek_mdio_remove() from running afterwards, which is possible if the
|
||||
- * parent bus implements its own .shutdown() as .remove().
|
||||
+ * This function should be used as the .shutdown in a platform_driver. It calls
|
||||
+ * the common shutdown function.
|
||||
*
|
||||
* Context: Can sleep.
|
||||
* Return: Nothing.
|
||||
@@ -293,9 +183,7 @@ void realtek_mdio_shutdown(struct mdio_d
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
- dsa_switch_shutdown(priv->ds);
|
||||
-
|
||||
- dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
+ rtl83xx_shutdown(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, REALTEK_DSA);
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "realtek.h"
|
||||
#include "realtek-smi.h"
|
||||
+#include "rtl83xx.h"
|
||||
|
||||
#define REALTEK_SMI_ACK_RETRY_COUNT 5
|
||||
|
||||
@@ -311,47 +312,6 @@ static int realtek_smi_read(void *ctx, u
|
||||
return realtek_smi_read_reg(priv, reg, val);
|
||||
}
|
||||
|
||||
-static void realtek_smi_lock(void *ctx)
|
||||
-{
|
||||
- struct realtek_priv *priv = ctx;
|
||||
-
|
||||
- mutex_lock(&priv->map_lock);
|
||||
-}
|
||||
-
|
||||
-static void realtek_smi_unlock(void *ctx)
|
||||
-{
|
||||
- struct realtek_priv *priv = ctx;
|
||||
-
|
||||
- mutex_unlock(&priv->map_lock);
|
||||
-}
|
||||
-
|
||||
-static const struct regmap_config realtek_smi_regmap_config = {
|
||||
- .reg_bits = 10, /* A4..A0 R4..R0 */
|
||||
- .val_bits = 16,
|
||||
- .reg_stride = 1,
|
||||
- /* PHY regs are at 0x8000 */
|
||||
- .max_register = 0xffff,
|
||||
- .reg_format_endian = REGMAP_ENDIAN_BIG,
|
||||
- .reg_read = realtek_smi_read,
|
||||
- .reg_write = realtek_smi_write,
|
||||
- .cache_type = REGCACHE_NONE,
|
||||
- .lock = realtek_smi_lock,
|
||||
- .unlock = realtek_smi_unlock,
|
||||
-};
|
||||
-
|
||||
-static const struct regmap_config realtek_smi_nolock_regmap_config = {
|
||||
- .reg_bits = 10, /* A4..A0 R4..R0 */
|
||||
- .val_bits = 16,
|
||||
- .reg_stride = 1,
|
||||
- /* PHY regs are at 0x8000 */
|
||||
- .max_register = 0xffff,
|
||||
- .reg_format_endian = REGMAP_ENDIAN_BIG,
|
||||
- .reg_read = realtek_smi_read,
|
||||
- .reg_write = realtek_smi_write,
|
||||
- .cache_type = REGCACHE_NONE,
|
||||
- .disable_locking = true,
|
||||
-};
|
||||
-
|
||||
static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
|
||||
{
|
||||
struct realtek_priv *priv = bus->priv;
|
||||
@@ -409,111 +369,56 @@ err_put_node:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static const struct realtek_interface_info realtek_smi_info = {
|
||||
+ .reg_read = realtek_smi_read,
|
||||
+ .reg_write = realtek_smi_write,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* realtek_smi_probe() - Probe a platform device for an SMI-connected switch
|
||||
* @pdev: platform_device to probe on.
|
||||
*
|
||||
- * This function should be used as the .probe in a platform_driver. It
|
||||
- * initializes realtek_priv and read data from the device-tree node. The switch
|
||||
- * is hard reset if a method is provided. It checks the switch chip ID and,
|
||||
- * finally, a DSA switch is registered.
|
||||
+ * This function should be used as the .probe in a platform_driver. After
|
||||
+ * calling the common probe function for both interfaces, it initializes the
|
||||
+ * values specific for SMI-connected devices. Finally, it calls a common
|
||||
+ * function to register the DSA switch.
|
||||
*
|
||||
* Context: Can sleep. Takes and releases priv->map_lock.
|
||||
* Return: Returns 0 on success, a negative error on failure.
|
||||
*/
|
||||
int realtek_smi_probe(struct platform_device *pdev)
|
||||
{
|
||||
- const struct realtek_variant *var;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct realtek_priv *priv;
|
||||
- struct regmap_config rc;
|
||||
- struct device_node *np;
|
||||
int ret;
|
||||
|
||||
- var = of_device_get_match_data(dev);
|
||||
- np = dev->of_node;
|
||||
-
|
||||
- priv = devm_kzalloc(dev, sizeof(*priv) + var->chip_data_sz, GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
- priv->chip_data = (void *)priv + sizeof(*priv);
|
||||
-
|
||||
- mutex_init(&priv->map_lock);
|
||||
-
|
||||
- rc = realtek_smi_regmap_config;
|
||||
- rc.lock_arg = priv;
|
||||
- priv->map = devm_regmap_init(dev, NULL, priv, &rc);
|
||||
- if (IS_ERR(priv->map)) {
|
||||
- ret = PTR_ERR(priv->map);
|
||||
- dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- rc = realtek_smi_nolock_regmap_config;
|
||||
- priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
|
||||
- if (IS_ERR(priv->map_nolock)) {
|
||||
- ret = PTR_ERR(priv->map_nolock);
|
||||
- dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- /* Link forward and backward */
|
||||
- priv->dev = dev;
|
||||
- priv->variant = var;
|
||||
- priv->ops = var->ops;
|
||||
-
|
||||
- priv->setup_interface = realtek_smi_setup_mdio;
|
||||
- priv->write_reg_noack = realtek_smi_write_reg_noack;
|
||||
-
|
||||
- dev_set_drvdata(dev, priv);
|
||||
- spin_lock_init(&priv->lock);
|
||||
-
|
||||
- /* TODO: if power is software controlled, set up any regulators here */
|
||||
-
|
||||
- priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(priv->reset)) {
|
||||
- dev_err(dev, "failed to get RESET GPIO\n");
|
||||
- return PTR_ERR(priv->reset);
|
||||
- }
|
||||
- if (priv->reset) {
|
||||
- gpiod_set_value(priv->reset, 1);
|
||||
- dev_dbg(dev, "asserted RESET\n");
|
||||
- msleep(REALTEK_HW_STOP_DELAY);
|
||||
- gpiod_set_value(priv->reset, 0);
|
||||
- msleep(REALTEK_HW_START_DELAY);
|
||||
- dev_dbg(dev, "deasserted RESET\n");
|
||||
- }
|
||||
+ priv = rtl83xx_probe(dev, &realtek_smi_info);
|
||||
+ if (IS_ERR(priv))
|
||||
+ return PTR_ERR(priv);
|
||||
|
||||
/* Fetch MDIO pins */
|
||||
priv->mdc = devm_gpiod_get_optional(dev, "mdc", GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(priv->mdc))
|
||||
+ if (IS_ERR(priv->mdc)) {
|
||||
+ rtl83xx_remove(priv);
|
||||
return PTR_ERR(priv->mdc);
|
||||
+ }
|
||||
+
|
||||
priv->mdio = devm_gpiod_get_optional(dev, "mdio", GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(priv->mdio))
|
||||
+ if (IS_ERR(priv->mdio)) {
|
||||
+ rtl83xx_remove(priv);
|
||||
return PTR_ERR(priv->mdio);
|
||||
-
|
||||
- priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
|
||||
-
|
||||
- ret = priv->ops->detect(priv);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "unable to detect switch\n");
|
||||
- return ret;
|
||||
}
|
||||
|
||||
- priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
|
||||
- if (!priv->ds)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->ds->dev = dev;
|
||||
- priv->ds->num_ports = priv->num_ports;
|
||||
- priv->ds->priv = priv;
|
||||
+ priv->write_reg_noack = realtek_smi_write_reg_noack;
|
||||
+ priv->setup_interface = realtek_smi_setup_mdio;
|
||||
+ priv->ds_ops = priv->variant->ds_ops_smi;
|
||||
|
||||
- priv->ds->ops = var->ds_ops_smi;
|
||||
- ret = dsa_register_switch(priv->ds);
|
||||
+ ret = rtl83xx_register_switch(priv);
|
||||
if (ret) {
|
||||
- dev_err_probe(dev, ret, "unable to register switch\n");
|
||||
+ rtl83xx_remove(priv);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_smi_probe, REALTEK_DSA);
|
||||
@@ -523,8 +428,8 @@ EXPORT_SYMBOL_NS_GPL(realtek_smi_probe,
|
||||
* @pdev: platform_device to be removed.
|
||||
*
|
||||
* This function should be used as the .remove_new in a platform_driver. First
|
||||
- * it unregisters the DSA switch and cleans internal data. If a method is
|
||||
- * provided, the hard reset is asserted to avoid traffic leakage.
|
||||
+ * it unregisters the DSA switch and cleans internal data. Finally, it calls
|
||||
+ * the common remove function.
|
||||
*
|
||||
* Context: Can sleep.
|
||||
* Return: Nothing.
|
||||
@@ -536,13 +441,12 @@ void realtek_smi_remove(struct platform_
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
- dsa_unregister_switch(priv->ds);
|
||||
+ rtl83xx_unregister_switch(priv);
|
||||
+
|
||||
if (priv->slave_mii_bus)
|
||||
of_node_put(priv->slave_mii_bus->dev.of_node);
|
||||
|
||||
- /* leave the device reset asserted */
|
||||
- if (priv->reset)
|
||||
- gpiod_set_value(priv->reset, 1);
|
||||
+ rtl83xx_remove(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, REALTEK_DSA);
|
||||
|
||||
@@ -550,10 +454,8 @@ EXPORT_SYMBOL_NS_GPL(realtek_smi_remove,
|
||||
* realtek_smi_shutdown() - Shutdown the driver of a SMI-connected switch
|
||||
* @pdev: platform_device shutting down.
|
||||
*
|
||||
- * This function should be used as the .shutdown in a platform_driver. It shuts
|
||||
- * down the DSA switch and cleans the platform driver data, to prevent
|
||||
- * realtek_smi_remove() from running afterwards, which is possible if the
|
||||
- * parent bus implements its own .shutdown() as .remove().
|
||||
+ * This function should be used as the .shutdown in a platform_driver. It calls
|
||||
+ * the common shutdown function.
|
||||
*
|
||||
* Context: Can sleep.
|
||||
* Return: Nothing.
|
||||
@@ -565,9 +467,7 @@ void realtek_smi_shutdown(struct platfor
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
- dsa_switch_shutdown(priv->ds);
|
||||
-
|
||||
- platform_set_drvdata(pdev, NULL);
|
||||
+ rtl83xx_shutdown(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, REALTEK_DSA);
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek.h
|
||||
+++ b/drivers/net/dsa/realtek/realtek.h
|
||||
@@ -62,6 +62,7 @@ struct realtek_priv {
|
||||
|
||||
spinlock_t lock; /* Locks around command writes */
|
||||
struct dsa_switch *ds;
|
||||
+ const struct dsa_switch_ops *ds_ops;
|
||||
struct irq_domain *irqdomain;
|
||||
bool leds_disabled;
|
||||
|
||||
--- a/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
@@ -103,6 +103,7 @@
|
||||
#include "realtek.h"
|
||||
#include "realtek-smi.h"
|
||||
#include "realtek-mdio.h"
|
||||
+#include "rtl83xx.h"
|
||||
|
||||
/* Family-specific data and limits */
|
||||
#define RTL8365MB_PHYADDRMAX 7
|
||||
@@ -691,7 +692,7 @@ static int rtl8365mb_phy_ocp_read(struct
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
- mutex_lock(&priv->map_lock);
|
||||
+ rtl83xx_lock(priv);
|
||||
|
||||
ret = rtl8365mb_phy_poll_busy(priv);
|
||||
if (ret)
|
||||
@@ -724,7 +725,7 @@ static int rtl8365mb_phy_ocp_read(struct
|
||||
*data = val & 0xFFFF;
|
||||
|
||||
out:
|
||||
- mutex_unlock(&priv->map_lock);
|
||||
+ rtl83xx_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -735,7 +736,7 @@ static int rtl8365mb_phy_ocp_write(struc
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
- mutex_lock(&priv->map_lock);
|
||||
+ rtl83xx_lock(priv);
|
||||
|
||||
ret = rtl8365mb_phy_poll_busy(priv);
|
||||
if (ret)
|
||||
@@ -766,7 +767,7 @@ static int rtl8365mb_phy_ocp_write(struc
|
||||
goto out;
|
||||
|
||||
out:
|
||||
- mutex_unlock(&priv->map_lock);
|
||||
+ rtl83xx_unlock(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "realtek.h"
|
||||
#include "realtek-smi.h"
|
||||
#include "realtek-mdio.h"
|
||||
+#include "rtl83xx.h"
|
||||
|
||||
#define RTL8366RB_PORT_NUM_CPU 5
|
||||
#define RTL8366RB_NUM_PORTS 6
|
||||
@@ -1634,7 +1635,7 @@ static int rtl8366rb_phy_read(struct rea
|
||||
if (phy > RTL8366RB_PHY_NO_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
- mutex_lock(&priv->map_lock);
|
||||
+ rtl83xx_lock(priv);
|
||||
|
||||
ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
|
||||
RTL8366RB_PHY_CTRL_READ);
|
||||
@@ -1662,7 +1663,7 @@ static int rtl8366rb_phy_read(struct rea
|
||||
phy, regnum, reg, val);
|
||||
|
||||
out:
|
||||
- mutex_unlock(&priv->map_lock);
|
||||
+ rtl83xx_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1676,7 +1677,7 @@ static int rtl8366rb_phy_write(struct re
|
||||
if (phy > RTL8366RB_PHY_NO_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
- mutex_lock(&priv->map_lock);
|
||||
+ rtl83xx_lock(priv);
|
||||
|
||||
ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
|
||||
RTL8366RB_PHY_CTRL_WRITE);
|
||||
@@ -1693,7 +1694,7 @@ static int rtl8366rb_phy_write(struct re
|
||||
goto out;
|
||||
|
||||
out:
|
||||
- mutex_unlock(&priv->map_lock);
|
||||
+ rtl83xx_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -0,0 +1,236 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/of_device.h> /* krnl 6.1 only */
|
||||
+
|
||||
+#include "realtek.h"
|
||||
+#include "rtl83xx.h"
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_lock() - Locks the mutex used by regmaps
|
||||
+ * @ctx: realtek_priv pointer
|
||||
+ *
|
||||
+ * This function is passed to regmap to be used as the lock function.
|
||||
+ * It is also used externally to block regmap before executing multiple
|
||||
+ * operations that must happen in sequence (which will use
|
||||
+ * realtek_priv.map_nolock instead).
|
||||
+ *
|
||||
+ * Context: Can sleep. Holds priv->map_lock lock.
|
||||
+ * Return: nothing
|
||||
+ */
|
||||
+void rtl83xx_lock(void *ctx)
|
||||
+{
|
||||
+ struct realtek_priv *priv = ctx;
|
||||
+
|
||||
+ mutex_lock(&priv->map_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_lock, REALTEK_DSA);
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_unlock() - Unlocks the mutex used by regmaps
|
||||
+ * @ctx: realtek_priv pointer
|
||||
+ *
|
||||
+ * This function unlocks the lock acquired by rtl83xx_lock.
|
||||
+ *
|
||||
+ * Context: Releases priv->map_lock lock.
|
||||
+ * Return: nothing
|
||||
+ */
|
||||
+void rtl83xx_unlock(void *ctx)
|
||||
+{
|
||||
+ struct realtek_priv *priv = ctx;
|
||||
+
|
||||
+ mutex_unlock(&priv->map_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, REALTEK_DSA);
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_probe() - probe a Realtek switch
|
||||
+ * @dev: the device being probed
|
||||
+ * @interface_info: specific management interface info.
|
||||
+ *
|
||||
+ * This function initializes realtek_priv and reads data from the device tree
|
||||
+ * node. The switch is hard resetted if a method is provided.
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Pointer to the realtek_priv or ERR_PTR() in case of failure.
|
||||
+ *
|
||||
+ * The realtek_priv pointer does not need to be freed as it is controlled by
|
||||
+ * devres.
|
||||
+ */
|
||||
+struct realtek_priv *
|
||||
+rtl83xx_probe(struct device *dev,
|
||||
+ const struct realtek_interface_info *interface_info)
|
||||
+{
|
||||
+ const struct realtek_variant *var;
|
||||
+ struct realtek_priv *priv;
|
||||
+ struct regmap_config rc = {
|
||||
+ .reg_bits = 10, /* A4..A0 R4..R0 */
|
||||
+ .val_bits = 16,
|
||||
+ .reg_stride = 1,
|
||||
+ .max_register = 0xffff,
|
||||
+ .reg_format_endian = REGMAP_ENDIAN_BIG,
|
||||
+ .reg_read = interface_info->reg_read,
|
||||
+ .reg_write = interface_info->reg_write,
|
||||
+ .cache_type = REGCACHE_NONE,
|
||||
+ .lock = rtl83xx_lock,
|
||||
+ .unlock = rtl83xx_unlock,
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ var = of_device_get_match_data(dev);
|
||||
+ if (!var)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ mutex_init(&priv->map_lock);
|
||||
+
|
||||
+ rc.lock_arg = priv;
|
||||
+ priv->map = devm_regmap_init(dev, NULL, priv, &rc);
|
||||
+ if (IS_ERR(priv->map)) {
|
||||
+ ret = PTR_ERR(priv->map);
|
||||
+ dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
+ return ERR_PTR(ret);
|
||||
+ }
|
||||
+
|
||||
+ rc.disable_locking = true;
|
||||
+ priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
|
||||
+ if (IS_ERR(priv->map_nolock)) {
|
||||
+ ret = PTR_ERR(priv->map_nolock);
|
||||
+ dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
+ return ERR_PTR(ret);
|
||||
+ }
|
||||
+
|
||||
+ /* Link forward and backward */
|
||||
+ priv->dev = dev;
|
||||
+ priv->variant = var;
|
||||
+ priv->ops = var->ops;
|
||||
+ priv->chip_data = (void *)priv + sizeof(*priv);
|
||||
+
|
||||
+ spin_lock_init(&priv->lock);
|
||||
+
|
||||
+ priv->leds_disabled = of_property_read_bool(dev->of_node,
|
||||
+ "realtek,disable-leds");
|
||||
+
|
||||
+ /* TODO: if power is software controlled, set up any regulators here */
|
||||
+ priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||||
+ if (IS_ERR(priv->reset)) {
|
||||
+ dev_err(dev, "failed to get RESET GPIO\n");
|
||||
+ return ERR_CAST(priv->reset);
|
||||
+ }
|
||||
+
|
||||
+ dev_set_drvdata(dev, priv);
|
||||
+
|
||||
+ if (priv->reset) {
|
||||
+ gpiod_set_value(priv->reset, 1);
|
||||
+ dev_dbg(dev, "asserted RESET\n");
|
||||
+ msleep(REALTEK_HW_STOP_DELAY);
|
||||
+ gpiod_set_value(priv->reset, 0);
|
||||
+ msleep(REALTEK_HW_START_DELAY);
|
||||
+ dev_dbg(dev, "deasserted RESET\n");
|
||||
+ }
|
||||
+
|
||||
+ return priv;
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REALTEK_DSA);
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_register_switch() - detects and register a switch
|
||||
+ * @priv: realtek_priv pointer
|
||||
+ *
|
||||
+ * This function first checks the switch chip ID and register a DSA
|
||||
+ * switch.
|
||||
+ *
|
||||
+ * Context: Can sleep. Takes and releases priv->map_lock.
|
||||
+ * Return: 0 on success, negative value for failure.
|
||||
+ */
|
||||
+int rtl83xx_register_switch(struct realtek_priv *priv)
|
||||
+{
|
||||
+ struct dsa_switch *ds;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = priv->ops->detect(priv);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(priv->dev, ret, "unable to detect switch\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ds = devm_kzalloc(priv->dev, sizeof(*ds), GFP_KERNEL);
|
||||
+ if (!ds)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ds->priv = priv;
|
||||
+ ds->dev = priv->dev;
|
||||
+ ds->ops = priv->ds_ops;
|
||||
+ ds->num_ports = priv->num_ports;
|
||||
+ priv->ds = ds;
|
||||
+
|
||||
+ ret = dsa_register_switch(ds);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(priv->dev, ret, "unable to register switch\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_register_switch, REALTEK_DSA);
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_unregister_switch() - unregister a switch
|
||||
+ * @priv: realtek_priv pointer
|
||||
+ *
|
||||
+ * This function unregister a DSA switch.
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Nothing.
|
||||
+ */
|
||||
+void rtl83xx_unregister_switch(struct realtek_priv *priv)
|
||||
+{
|
||||
+ dsa_unregister_switch(priv->ds);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA);
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_shutdown() - shutdown a switch
|
||||
+ * @priv: realtek_priv pointer
|
||||
+ *
|
||||
+ * This function shuts down the DSA switch and cleans the platform driver data,
|
||||
+ * to prevent realtek_{smi,mdio}_remove() from running afterwards, which is
|
||||
+ * possible if the parent bus implements its own .shutdown() as .remove().
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: Nothing.
|
||||
+ */
|
||||
+void rtl83xx_shutdown(struct realtek_priv *priv)
|
||||
+{
|
||||
+ dsa_switch_shutdown(priv->ds);
|
||||
+
|
||||
+ dev_set_drvdata(priv->dev, NULL);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, REALTEK_DSA);
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_remove() - Cleanup a realtek switch driver
|
||||
+ * @priv: realtek_priv pointer
|
||||
+ *
|
||||
+ * If a method is provided, this function asserts the hard reset of the switch
|
||||
+ * in order to avoid leaking traffic when the driver is gone.
|
||||
+ *
|
||||
+ * Context: Might sleep if priv->gdev->chip->can_sleep.
|
||||
+ * Return: nothing
|
||||
+ */
|
||||
+void rtl83xx_remove(struct realtek_priv *priv)
|
||||
+{
|
||||
+ /* leave the device reset asserted */
|
||||
+ if (priv->reset)
|
||||
+ gpiod_set_value(priv->reset, 1);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
|
||||
+
|
||||
+MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
|
||||
+MODULE_DESCRIPTION("Realtek DSA switches common module");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.h
|
||||
@@ -0,0 +1,21 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
+
|
||||
+#ifndef _RTL83XX_H
|
||||
+#define _RTL83XX_H
|
||||
+
|
||||
+struct realtek_interface_info {
|
||||
+ int (*reg_read)(void *ctx, u32 reg, u32 *val);
|
||||
+ int (*reg_write)(void *ctx, u32 reg, u32 val);
|
||||
+};
|
||||
+
|
||||
+void rtl83xx_lock(void *ctx);
|
||||
+void rtl83xx_unlock(void *ctx);
|
||||
+struct realtek_priv *
|
||||
+rtl83xx_probe(struct device *dev,
|
||||
+ const struct realtek_interface_info *interface_info);
|
||||
+int rtl83xx_register_switch(struct realtek_priv *priv);
|
||||
+void rtl83xx_unregister_switch(struct realtek_priv *priv);
|
||||
+void rtl83xx_shutdown(struct realtek_priv *priv);
|
||||
+void rtl83xx_remove(struct realtek_priv *priv);
|
||||
+
|
||||
+#endif /* _RTL83XX_H */
|
@ -0,0 +1,93 @@
|
||||
From 98b75c1c149c653ad11a440636213eb070325158 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:42 -0300
|
||||
Subject: net: dsa: realtek: merge rtl83xx and interface
|
||||
modules into realtek_dsa
|
||||
|
||||
Since rtl83xx and realtek-{smi,mdio} are always loaded together,
|
||||
we can optimize resource usage by consolidating them into a single
|
||||
module.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/Kconfig | 4 ++--
|
||||
drivers/net/dsa/realtek/Makefile | 11 +++++++++--
|
||||
drivers/net/dsa/realtek/realtek-mdio.c | 5 -----
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 5 -----
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 1 +
|
||||
5 files changed, 12 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/Kconfig
|
||||
+++ b/drivers/net/dsa/realtek/Kconfig
|
||||
@@ -16,14 +16,14 @@ menuconfig NET_DSA_REALTEK
|
||||
if NET_DSA_REALTEK
|
||||
|
||||
config NET_DSA_REALTEK_MDIO
|
||||
- tristate "Realtek MDIO interface support"
|
||||
+ bool "Realtek MDIO interface support"
|
||||
depends on OF
|
||||
help
|
||||
Select to enable support for registering switches configured
|
||||
through MDIO.
|
||||
|
||||
config NET_DSA_REALTEK_SMI
|
||||
- tristate "Realtek SMI interface support"
|
||||
+ bool "Realtek SMI interface support"
|
||||
depends on OF
|
||||
help
|
||||
Select to enable support for registering switches connected
|
||||
--- a/drivers/net/dsa/realtek/Makefile
|
||||
+++ b/drivers/net/dsa/realtek/Makefile
|
||||
@@ -1,8 +1,15 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_NET_DSA_REALTEK) += realtek_dsa.o
|
||||
realtek_dsa-objs := rtl83xx.o
|
||||
-obj-$(CONFIG_NET_DSA_REALTEK_MDIO) += realtek-mdio.o
|
||||
-obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
|
||||
+
|
||||
+ifdef CONFIG_NET_DSA_REALTEK_MDIO
|
||||
+realtek_dsa-objs += realtek-mdio.o
|
||||
+endif
|
||||
+
|
||||
+ifdef CONFIG_NET_DSA_REALTEK_SMI
|
||||
+realtek_dsa-objs += realtek-smi.o
|
||||
+endif
|
||||
+
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
|
||||
rtl8366-objs := rtl8366-core.o rtl8366rb.o
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
|
||||
--- a/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
@@ -186,8 +186,3 @@ void realtek_mdio_shutdown(struct mdio_d
|
||||
rtl83xx_shutdown(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_mdio_shutdown, REALTEK_DSA);
|
||||
-
|
||||
-MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
|
||||
-MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
|
||||
-MODULE_LICENSE("GPL");
|
||||
-MODULE_IMPORT_NS(REALTEK_DSA);
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -470,8 +470,3 @@ void realtek_smi_shutdown(struct platfor
|
||||
rtl83xx_shutdown(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_smi_shutdown, REALTEK_DSA);
|
||||
-
|
||||
-MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
-MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface");
|
||||
-MODULE_LICENSE("GPL");
|
||||
-MODULE_IMPORT_NS(REALTEK_DSA);
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -232,5 +232,6 @@ void rtl83xx_remove(struct realtek_priv
|
||||
EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
|
||||
|
||||
MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
|
||||
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("Realtek DSA switches common module");
|
||||
MODULE_LICENSE("GPL");
|
@ -0,0 +1,34 @@
|
||||
From 8685c98d45c54346caf005de69988e13c731c533 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:43 -0300
|
||||
Subject: net: dsa: realtek: get internal MDIO node by name
|
||||
|
||||
The binding docs requires for SMI-connected devices that the switch
|
||||
must have a child node named "mdio" and with a compatible string of
|
||||
"realtek,smi-mdio". Meanwile, for MDIO-connected switches, the binding
|
||||
docs only requires a child node named "mdio".
|
||||
|
||||
This patch changes the driver to use the common denominator for both
|
||||
interfaces, looking for the MDIO node by name, ignoring the compatible
|
||||
string.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -333,7 +333,7 @@ static int realtek_smi_setup_mdio(struct
|
||||
struct device_node *mdio_np;
|
||||
int ret;
|
||||
|
||||
- mdio_np = of_get_compatible_child(priv->dev->of_node, "realtek,smi-mdio");
|
||||
+ mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
|
||||
if (!mdio_np) {
|
||||
dev_err(priv->dev, "no MDIO bus node\n");
|
||||
return -ENODEV;
|
@ -0,0 +1,83 @@
|
||||
From 68c66d8d8a19088967a0ab6bb98cb5ecc80ca0be Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:44 -0300
|
||||
Subject: net: dsa: realtek: clean slave_mii_bus setup
|
||||
|
||||
Remove the line assigning dev.of_node in mdio_bus as subsequent
|
||||
of_mdiobus_register will always overwrite it.
|
||||
|
||||
As discussed in [1], allow the DSA core to be simplified, by not
|
||||
assigning ds->slave_mii_bus when the MDIO bus is described in OF, as it
|
||||
is unnecessary.
|
||||
|
||||
Since commit 3b73a7b8ec38 ("net: mdio_bus: add refcounting for fwnodes
|
||||
to mdiobus"), we can put the "mdio" node just after the MDIO bus
|
||||
registration.
|
||||
|
||||
[1] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 13 +++----------
|
||||
1 file changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -331,7 +331,7 @@ static int realtek_smi_setup_mdio(struct
|
||||
{
|
||||
struct realtek_priv *priv = ds->priv;
|
||||
struct device_node *mdio_np;
|
||||
- int ret;
|
||||
+ int ret = 0;
|
||||
|
||||
mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
|
||||
if (!mdio_np) {
|
||||
@@ -344,15 +344,14 @@ static int realtek_smi_setup_mdio(struct
|
||||
ret = -ENOMEM;
|
||||
goto err_put_node;
|
||||
}
|
||||
+
|
||||
priv->slave_mii_bus->priv = priv;
|
||||
priv->slave_mii_bus->name = "SMI slave MII";
|
||||
priv->slave_mii_bus->read = realtek_smi_mdio_read;
|
||||
priv->slave_mii_bus->write = realtek_smi_mdio_write;
|
||||
snprintf(priv->slave_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
|
||||
ds->index);
|
||||
- priv->slave_mii_bus->dev.of_node = mdio_np;
|
||||
priv->slave_mii_bus->parent = priv->dev;
|
||||
- ds->slave_mii_bus = priv->slave_mii_bus;
|
||||
|
||||
ret = devm_of_mdiobus_register(priv->dev, priv->slave_mii_bus, mdio_np);
|
||||
if (ret) {
|
||||
@@ -361,8 +360,6 @@ static int realtek_smi_setup_mdio(struct
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
-
|
||||
err_put_node:
|
||||
of_node_put(mdio_np);
|
||||
|
||||
@@ -428,8 +425,7 @@ EXPORT_SYMBOL_NS_GPL(realtek_smi_probe,
|
||||
* @pdev: platform_device to be removed.
|
||||
*
|
||||
* This function should be used as the .remove_new in a platform_driver. First
|
||||
- * it unregisters the DSA switch and cleans internal data. Finally, it calls
|
||||
- * the common remove function.
|
||||
+ * it unregisters the DSA switch and then it calls the common remove function.
|
||||
*
|
||||
* Context: Can sleep.
|
||||
* Return: Nothing.
|
||||
@@ -443,9 +439,6 @@ void realtek_smi_remove(struct platform_
|
||||
|
||||
rtl83xx_unregister_switch(priv);
|
||||
|
||||
- if (priv->slave_mii_bus)
|
||||
- of_node_put(priv->slave_mii_bus->dev.of_node);
|
||||
-
|
||||
rtl83xx_remove(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(realtek_smi_remove, REALTEK_DSA);
|
@ -0,0 +1,198 @@
|
||||
From b4bd77971f3c290c4694ed710cc6967593b10bc2 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:45 -0300
|
||||
Subject: net: dsa: realtek: migrate slave_mii_bus setup to
|
||||
realtek_dsa
|
||||
|
||||
In the user MDIO driver, despite numerous references to SMI, including
|
||||
its compatible string, there's nothing inherently specific about the SMI
|
||||
interface in the user MDIO bus. Consequently, the code has been migrated
|
||||
to the rtl83xx module. All references to SMI have been eliminated.
|
||||
|
||||
The MDIO bus id was changed from Realtek-<switch id> to the switch
|
||||
devname suffixed with :slave_mii, giving more information about the bus
|
||||
it is referencing.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 57 +---------------------
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 68 +++++++++++++++++++++++++++
|
||||
drivers/net/dsa/realtek/rtl83xx.h | 1 +
|
||||
3 files changed, 70 insertions(+), 56 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/of.h>
|
||||
-#include <linux/of_mdio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -312,60 +311,6 @@ static int realtek_smi_read(void *ctx, u
|
||||
return realtek_smi_read_reg(priv, reg, val);
|
||||
}
|
||||
|
||||
-static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
|
||||
-{
|
||||
- struct realtek_priv *priv = bus->priv;
|
||||
-
|
||||
- return priv->ops->phy_read(priv, addr, regnum);
|
||||
-}
|
||||
-
|
||||
-static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum,
|
||||
- u16 val)
|
||||
-{
|
||||
- struct realtek_priv *priv = bus->priv;
|
||||
-
|
||||
- return priv->ops->phy_write(priv, addr, regnum, val);
|
||||
-}
|
||||
-
|
||||
-static int realtek_smi_setup_mdio(struct dsa_switch *ds)
|
||||
-{
|
||||
- struct realtek_priv *priv = ds->priv;
|
||||
- struct device_node *mdio_np;
|
||||
- int ret = 0;
|
||||
-
|
||||
- mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
|
||||
- if (!mdio_np) {
|
||||
- dev_err(priv->dev, "no MDIO bus node\n");
|
||||
- return -ENODEV;
|
||||
- }
|
||||
-
|
||||
- priv->slave_mii_bus = devm_mdiobus_alloc(priv->dev);
|
||||
- if (!priv->slave_mii_bus) {
|
||||
- ret = -ENOMEM;
|
||||
- goto err_put_node;
|
||||
- }
|
||||
-
|
||||
- priv->slave_mii_bus->priv = priv;
|
||||
- priv->slave_mii_bus->name = "SMI slave MII";
|
||||
- priv->slave_mii_bus->read = realtek_smi_mdio_read;
|
||||
- priv->slave_mii_bus->write = realtek_smi_mdio_write;
|
||||
- snprintf(priv->slave_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
|
||||
- ds->index);
|
||||
- priv->slave_mii_bus->parent = priv->dev;
|
||||
-
|
||||
- ret = devm_of_mdiobus_register(priv->dev, priv->slave_mii_bus, mdio_np);
|
||||
- if (ret) {
|
||||
- dev_err(priv->dev, "unable to register MDIO bus %s\n",
|
||||
- priv->slave_mii_bus->id);
|
||||
- goto err_put_node;
|
||||
- }
|
||||
-
|
||||
-err_put_node:
|
||||
- of_node_put(mdio_np);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static const struct realtek_interface_info realtek_smi_info = {
|
||||
.reg_read = realtek_smi_read,
|
||||
.reg_write = realtek_smi_write,
|
||||
@@ -407,7 +352,7 @@ int realtek_smi_probe(struct platform_de
|
||||
}
|
||||
|
||||
priv->write_reg_noack = realtek_smi_write_reg_noack;
|
||||
- priv->setup_interface = realtek_smi_setup_mdio;
|
||||
+ priv->setup_interface = rtl83xx_setup_user_mdio;
|
||||
priv->ds_ops = priv->variant->ds_ops_smi;
|
||||
|
||||
ret = rtl83xx_register_switch(priv);
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of_device.h> /* krnl 6.1 only */
|
||||
+#include <linux/of_mdio.h>
|
||||
|
||||
#include "realtek.h"
|
||||
#include "rtl83xx.h"
|
||||
@@ -44,6 +45,73 @@ void rtl83xx_unlock(void *ctx)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rtl83xx_unlock, REALTEK_DSA);
|
||||
|
||||
+static int rtl83xx_user_mdio_read(struct mii_bus *bus, int addr, int regnum)
|
||||
+{
|
||||
+ struct realtek_priv *priv = bus->priv;
|
||||
+
|
||||
+ return priv->ops->phy_read(priv, addr, regnum);
|
||||
+}
|
||||
+
|
||||
+static int rtl83xx_user_mdio_write(struct mii_bus *bus, int addr, int regnum,
|
||||
+ u16 val)
|
||||
+{
|
||||
+ struct realtek_priv *priv = bus->priv;
|
||||
+
|
||||
+ return priv->ops->phy_write(priv, addr, regnum, val);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * rtl83xx_setup_user_mdio() - register the user mii bus driver
|
||||
+ * @ds: DSA switch associated with this slave_mii_bus
|
||||
+ *
|
||||
+ * Registers the MDIO bus for built-in Ethernet PHYs, and associates it with
|
||||
+ * the mandatory 'mdio' child OF node of the switch.
|
||||
+ *
|
||||
+ * Context: Can sleep.
|
||||
+ * Return: 0 on success, negative value for failure.
|
||||
+ */
|
||||
+int rtl83xx_setup_user_mdio(struct dsa_switch *ds)
|
||||
+{
|
||||
+ struct realtek_priv *priv = ds->priv;
|
||||
+ struct device_node *mdio_np;
|
||||
+ struct mii_bus *bus;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
|
||||
+ if (!mdio_np) {
|
||||
+ dev_err(priv->dev, "no MDIO bus node\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ bus = devm_mdiobus_alloc(priv->dev);
|
||||
+ if (!bus) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_put_node;
|
||||
+ }
|
||||
+
|
||||
+ bus->priv = priv;
|
||||
+ bus->name = "Realtek user MII";
|
||||
+ bus->read = rtl83xx_user_mdio_read;
|
||||
+ bus->write = rtl83xx_user_mdio_write;
|
||||
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s:slave_mii", dev_name(priv->dev));
|
||||
+ bus->parent = priv->dev;
|
||||
+
|
||||
+ ret = devm_of_mdiobus_register(priv->dev, bus, mdio_np);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "unable to register MDIO bus %s\n",
|
||||
+ bus->id);
|
||||
+ goto err_put_node;
|
||||
+ }
|
||||
+
|
||||
+ priv->slave_mii_bus = bus;
|
||||
+
|
||||
+err_put_node:
|
||||
+ of_node_put(mdio_np);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(rtl83xx_setup_user_mdio, REALTEK_DSA);
|
||||
+
|
||||
/**
|
||||
* rtl83xx_probe() - probe a Realtek switch
|
||||
* @dev: the device being probed
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.h
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.h
|
||||
@@ -10,6 +10,7 @@ struct realtek_interface_info {
|
||||
|
||||
void rtl83xx_lock(void *ctx);
|
||||
void rtl83xx_unlock(void *ctx);
|
||||
+int rtl83xx_setup_user_mdio(struct dsa_switch *ds);
|
||||
struct realtek_priv *
|
||||
rtl83xx_probe(struct device *dev,
|
||||
const struct realtek_interface_info *interface_info);
|
@ -0,0 +1,261 @@
|
||||
From bba140a566ed075304c49c52ab32c0016cab624a Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:46 -0300
|
||||
Subject: net: dsa: realtek: use the same mii bus driver for
|
||||
both interfaces
|
||||
|
||||
The realtek-mdio will now use this driver instead of the generic DSA
|
||||
driver ("dsa user smi"), which should not be used with OF[1].
|
||||
|
||||
With a single ds_ops for both interfaces, the ds_ops in realtek_priv is
|
||||
no longer necessary. Now, the realtek_variant.ds_ops can be used
|
||||
directly.
|
||||
|
||||
The realtek_priv.setup_interface() has been removed as we can directly
|
||||
call the new common function.
|
||||
|
||||
[1] https://lkml.kernel.org/netdev/20220630200423.tieprdu5fpabflj7@bang-olufsen.dk/T/
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek-mdio.c | 1 -
|
||||
drivers/net/dsa/realtek/realtek-smi.c | 2 -
|
||||
drivers/net/dsa/realtek/realtek.h | 5 +--
|
||||
drivers/net/dsa/realtek/rtl8365mb.c | 49 +++---------------------
|
||||
drivers/net/dsa/realtek/rtl8366rb.c | 52 +++-----------------------
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 2 +-
|
||||
6 files changed, 14 insertions(+), 97 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
|
||||
@@ -131,7 +131,6 @@ int realtek_mdio_probe(struct mdio_devic
|
||||
priv->bus = mdiodev->bus;
|
||||
priv->mdio_addr = mdiodev->addr;
|
||||
priv->write_reg_noack = realtek_mdio_write;
|
||||
- priv->ds_ops = priv->variant->ds_ops_mdio;
|
||||
|
||||
ret = rtl83xx_register_switch(priv);
|
||||
if (ret) {
|
||||
--- a/drivers/net/dsa/realtek/realtek-smi.c
|
||||
+++ b/drivers/net/dsa/realtek/realtek-smi.c
|
||||
@@ -352,8 +352,6 @@ int realtek_smi_probe(struct platform_de
|
||||
}
|
||||
|
||||
priv->write_reg_noack = realtek_smi_write_reg_noack;
|
||||
- priv->setup_interface = rtl83xx_setup_user_mdio;
|
||||
- priv->ds_ops = priv->variant->ds_ops_smi;
|
||||
|
||||
ret = rtl83xx_register_switch(priv);
|
||||
if (ret) {
|
||||
--- a/drivers/net/dsa/realtek/realtek.h
|
||||
+++ b/drivers/net/dsa/realtek/realtek.h
|
||||
@@ -62,7 +62,6 @@ struct realtek_priv {
|
||||
|
||||
spinlock_t lock; /* Locks around command writes */
|
||||
struct dsa_switch *ds;
|
||||
- const struct dsa_switch_ops *ds_ops;
|
||||
struct irq_domain *irqdomain;
|
||||
bool leds_disabled;
|
||||
|
||||
@@ -73,7 +72,6 @@ struct realtek_priv {
|
||||
struct rtl8366_mib_counter *mib_counters;
|
||||
|
||||
const struct realtek_ops *ops;
|
||||
- int (*setup_interface)(struct dsa_switch *ds);
|
||||
int (*write_reg_noack)(void *ctx, u32 addr, u32 data);
|
||||
|
||||
int vlan_enabled;
|
||||
@@ -115,8 +113,7 @@ struct realtek_ops {
|
||||
};
|
||||
|
||||
struct realtek_variant {
|
||||
- const struct dsa_switch_ops *ds_ops_smi;
|
||||
- const struct dsa_switch_ops *ds_ops_mdio;
|
||||
+ const struct dsa_switch_ops *ds_ops;
|
||||
const struct realtek_ops *ops;
|
||||
unsigned int clk_delay;
|
||||
u8 cmd_read;
|
||||
--- a/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
@@ -828,17 +828,6 @@ static int rtl8365mb_phy_write(struct re
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int rtl8365mb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
|
||||
-{
|
||||
- return rtl8365mb_phy_read(ds->priv, phy, regnum);
|
||||
-}
|
||||
-
|
||||
-static int rtl8365mb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
|
||||
- u16 val)
|
||||
-{
|
||||
- return rtl8365mb_phy_write(ds->priv, phy, regnum, val);
|
||||
-}
|
||||
-
|
||||
static const struct rtl8365mb_extint *
|
||||
rtl8365mb_get_port_extint(struct realtek_priv *priv, int port)
|
||||
{
|
||||
@@ -2018,12 +2007,10 @@ static int rtl8365mb_setup(struct dsa_sw
|
||||
if (ret)
|
||||
goto out_teardown_irq;
|
||||
|
||||
- if (priv->setup_interface) {
|
||||
- ret = priv->setup_interface(ds);
|
||||
- if (ret) {
|
||||
- dev_err(priv->dev, "could not set up MDIO bus\n");
|
||||
- goto out_teardown_irq;
|
||||
- }
|
||||
+ ret = rtl83xx_setup_user_mdio(ds);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "could not set up MDIO bus\n");
|
||||
+ goto out_teardown_irq;
|
||||
}
|
||||
|
||||
/* Start statistics counter polling */
|
||||
@@ -2117,28 +2104,7 @@ static int rtl8365mb_detect(struct realt
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {
|
||||
- .get_tag_protocol = rtl8365mb_get_tag_protocol,
|
||||
- .change_tag_protocol = rtl8365mb_change_tag_protocol,
|
||||
- .setup = rtl8365mb_setup,
|
||||
- .teardown = rtl8365mb_teardown,
|
||||
- .phylink_get_caps = rtl8365mb_phylink_get_caps,
|
||||
- .phylink_mac_config = rtl8365mb_phylink_mac_config,
|
||||
- .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
|
||||
- .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
|
||||
- .port_stp_state_set = rtl8365mb_port_stp_state_set,
|
||||
- .get_strings = rtl8365mb_get_strings,
|
||||
- .get_ethtool_stats = rtl8365mb_get_ethtool_stats,
|
||||
- .get_sset_count = rtl8365mb_get_sset_count,
|
||||
- .get_eth_phy_stats = rtl8365mb_get_phy_stats,
|
||||
- .get_eth_mac_stats = rtl8365mb_get_mac_stats,
|
||||
- .get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats,
|
||||
- .get_stats64 = rtl8365mb_get_stats64,
|
||||
- .port_change_mtu = rtl8365mb_port_change_mtu,
|
||||
- .port_max_mtu = rtl8365mb_port_max_mtu,
|
||||
-};
|
||||
-
|
||||
-static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
|
||||
+static const struct dsa_switch_ops rtl8365mb_switch_ops = {
|
||||
.get_tag_protocol = rtl8365mb_get_tag_protocol,
|
||||
.change_tag_protocol = rtl8365mb_change_tag_protocol,
|
||||
.setup = rtl8365mb_setup,
|
||||
@@ -2147,8 +2113,6 @@ static const struct dsa_switch_ops rtl83
|
||||
.phylink_mac_config = rtl8365mb_phylink_mac_config,
|
||||
.phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
|
||||
.phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
|
||||
- .phy_read = rtl8365mb_dsa_phy_read,
|
||||
- .phy_write = rtl8365mb_dsa_phy_write,
|
||||
.port_stp_state_set = rtl8365mb_port_stp_state_set,
|
||||
.get_strings = rtl8365mb_get_strings,
|
||||
.get_ethtool_stats = rtl8365mb_get_ethtool_stats,
|
||||
@@ -2168,8 +2132,7 @@ static const struct realtek_ops rtl8365m
|
||||
};
|
||||
|
||||
const struct realtek_variant rtl8365mb_variant = {
|
||||
- .ds_ops_smi = &rtl8365mb_switch_ops_smi,
|
||||
- .ds_ops_mdio = &rtl8365mb_switch_ops_mdio,
|
||||
+ .ds_ops = &rtl8365mb_switch_ops,
|
||||
.ops = &rtl8365mb_ops,
|
||||
.clk_delay = 10,
|
||||
.cmd_read = 0xb9,
|
||||
--- a/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
@@ -1035,12 +1035,10 @@ static int rtl8366rb_setup(struct dsa_sw
|
||||
if (ret)
|
||||
dev_info(priv->dev, "no interrupt support\n");
|
||||
|
||||
- if (priv->setup_interface) {
|
||||
- ret = priv->setup_interface(ds);
|
||||
- if (ret) {
|
||||
- dev_err(priv->dev, "could not set up MDIO bus\n");
|
||||
- return -ENODEV;
|
||||
- }
|
||||
+ ret = rtl83xx_setup_user_mdio(ds);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "could not set up MDIO bus\n");
|
||||
+ return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1699,17 +1697,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
|
||||
-{
|
||||
- return rtl8366rb_phy_read(ds->priv, phy, regnum);
|
||||
-}
|
||||
-
|
||||
-static int rtl8366rb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
|
||||
- u16 val)
|
||||
-{
|
||||
- return rtl8366rb_phy_write(ds->priv, phy, regnum, val);
|
||||
-}
|
||||
-
|
||||
static int rtl8366rb_reset_chip(struct realtek_priv *priv)
|
||||
{
|
||||
int timeout = 10;
|
||||
@@ -1775,35 +1762,9 @@ static int rtl8366rb_detect(struct realt
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct dsa_switch_ops rtl8366rb_switch_ops_smi = {
|
||||
- .get_tag_protocol = rtl8366_get_tag_protocol,
|
||||
- .setup = rtl8366rb_setup,
|
||||
- .phylink_get_caps = rtl8366rb_phylink_get_caps,
|
||||
- .phylink_mac_link_up = rtl8366rb_mac_link_up,
|
||||
- .phylink_mac_link_down = rtl8366rb_mac_link_down,
|
||||
- .get_strings = rtl8366_get_strings,
|
||||
- .get_ethtool_stats = rtl8366_get_ethtool_stats,
|
||||
- .get_sset_count = rtl8366_get_sset_count,
|
||||
- .port_bridge_join = rtl8366rb_port_bridge_join,
|
||||
- .port_bridge_leave = rtl8366rb_port_bridge_leave,
|
||||
- .port_vlan_filtering = rtl8366rb_vlan_filtering,
|
||||
- .port_vlan_add = rtl8366_vlan_add,
|
||||
- .port_vlan_del = rtl8366_vlan_del,
|
||||
- .port_enable = rtl8366rb_port_enable,
|
||||
- .port_disable = rtl8366rb_port_disable,
|
||||
- .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
|
||||
- .port_bridge_flags = rtl8366rb_port_bridge_flags,
|
||||
- .port_stp_state_set = rtl8366rb_port_stp_state_set,
|
||||
- .port_fast_age = rtl8366rb_port_fast_age,
|
||||
- .port_change_mtu = rtl8366rb_change_mtu,
|
||||
- .port_max_mtu = rtl8366rb_max_mtu,
|
||||
-};
|
||||
-
|
||||
-static const struct dsa_switch_ops rtl8366rb_switch_ops_mdio = {
|
||||
+static const struct dsa_switch_ops rtl8366rb_switch_ops = {
|
||||
.get_tag_protocol = rtl8366_get_tag_protocol,
|
||||
.setup = rtl8366rb_setup,
|
||||
- .phy_read = rtl8366rb_dsa_phy_read,
|
||||
- .phy_write = rtl8366rb_dsa_phy_write,
|
||||
.phylink_get_caps = rtl8366rb_phylink_get_caps,
|
||||
.phylink_mac_link_up = rtl8366rb_mac_link_up,
|
||||
.phylink_mac_link_down = rtl8366rb_mac_link_down,
|
||||
@@ -1842,8 +1803,7 @@ static const struct realtek_ops rtl8366r
|
||||
};
|
||||
|
||||
const struct realtek_variant rtl8366rb_variant = {
|
||||
- .ds_ops_smi = &rtl8366rb_switch_ops_smi,
|
||||
- .ds_ops_mdio = &rtl8366rb_switch_ops_mdio,
|
||||
+ .ds_ops = &rtl8366rb_switch_ops,
|
||||
.ops = &rtl8366rb_ops,
|
||||
.clk_delay = 10,
|
||||
.cmd_read = 0xa9,
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -233,7 +233,7 @@ int rtl83xx_register_switch(struct realt
|
||||
|
||||
ds->priv = priv;
|
||||
ds->dev = priv->dev;
|
||||
- ds->ops = priv->ds_ops;
|
||||
+ ds->ops = priv->variant->ds_ops;
|
||||
ds->num_ports = priv->num_ports;
|
||||
priv->ds = ds;
|
||||
|
@ -0,0 +1,180 @@
|
||||
From 9fc469b2943d9b1ff2a7800f823e7cd7a5cac0ca Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Fri, 9 Feb 2024 02:03:47 -0300
|
||||
Subject: net: dsa: realtek: embed dsa_switch into realtek_priv
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Embed dsa_switch within realtek_priv to eliminate the need for a second
|
||||
memory allocation.
|
||||
|
||||
Suggested-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek.h | 2 +-
|
||||
drivers/net/dsa/realtek/rtl8365mb.c | 15 +++++++++------
|
||||
drivers/net/dsa/realtek/rtl8366rb.c | 3 ++-
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 15 +++++++--------
|
||||
4 files changed, 19 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek.h
|
||||
+++ b/drivers/net/dsa/realtek/realtek.h
|
||||
@@ -61,7 +61,7 @@ struct realtek_priv {
|
||||
const struct realtek_variant *variant;
|
||||
|
||||
spinlock_t lock; /* Locks around command writes */
|
||||
- struct dsa_switch *ds;
|
||||
+ struct dsa_switch ds;
|
||||
struct irq_domain *irqdomain;
|
||||
bool leds_disabled;
|
||||
|
||||
--- a/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
@@ -870,6 +870,7 @@ static int rtl8365mb_ext_config_rgmii(st
|
||||
{
|
||||
const struct rtl8365mb_extint *extint =
|
||||
rtl8365mb_get_port_extint(priv, port);
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
struct device_node *dn;
|
||||
struct dsa_port *dp;
|
||||
int tx_delay = 0;
|
||||
@@ -880,7 +881,7 @@ static int rtl8365mb_ext_config_rgmii(st
|
||||
if (!extint)
|
||||
return -ENODEV;
|
||||
|
||||
- dp = dsa_to_port(priv->ds, port);
|
||||
+ dp = dsa_to_port(ds, port);
|
||||
dn = dp->dn;
|
||||
|
||||
/* Set the RGMII TX/RX delay
|
||||
@@ -1534,6 +1535,7 @@ static void rtl8365mb_get_stats64(struct
|
||||
static void rtl8365mb_stats_setup(struct realtek_priv *priv)
|
||||
{
|
||||
struct rtl8365mb *mb = priv->chip_data;
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
int i;
|
||||
|
||||
/* Per-chip global mutex to protect MIB counter access, since doing
|
||||
@@ -1544,7 +1546,7 @@ static void rtl8365mb_stats_setup(struct
|
||||
for (i = 0; i < priv->num_ports; i++) {
|
||||
struct rtl8365mb_port *p = &mb->ports[i];
|
||||
|
||||
- if (dsa_is_unused_port(priv->ds, i))
|
||||
+ if (dsa_is_unused_port(ds, i))
|
||||
continue;
|
||||
|
||||
/* Per-port spinlock to protect the stats64 data */
|
||||
@@ -1560,12 +1562,13 @@ static void rtl8365mb_stats_setup(struct
|
||||
static void rtl8365mb_stats_teardown(struct realtek_priv *priv)
|
||||
{
|
||||
struct rtl8365mb *mb = priv->chip_data;
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->num_ports; i++) {
|
||||
struct rtl8365mb_port *p = &mb->ports[i];
|
||||
|
||||
- if (dsa_is_unused_port(priv->ds, i))
|
||||
+ if (dsa_is_unused_port(ds, i))
|
||||
continue;
|
||||
|
||||
cancel_delayed_work_sync(&p->mib_work);
|
||||
@@ -1964,7 +1967,7 @@ static int rtl8365mb_setup(struct dsa_sw
|
||||
dev_info(priv->dev, "no interrupt support\n");
|
||||
|
||||
/* Configure CPU tagging */
|
||||
- dsa_switch_for_each_cpu_port(cpu_dp, priv->ds) {
|
||||
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
cpu->mask |= BIT(cpu_dp->index);
|
||||
|
||||
if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS)
|
||||
@@ -1979,7 +1982,7 @@ static int rtl8365mb_setup(struct dsa_sw
|
||||
for (i = 0; i < priv->num_ports; i++) {
|
||||
struct rtl8365mb_port *p = &mb->ports[i];
|
||||
|
||||
- if (dsa_is_unused_port(priv->ds, i))
|
||||
+ if (dsa_is_unused_port(ds, i))
|
||||
continue;
|
||||
|
||||
/* Forward only to the CPU */
|
||||
@@ -1996,7 +1999,7 @@ static int rtl8365mb_setup(struct dsa_sw
|
||||
* ports will still forward frames to the CPU despite being
|
||||
* administratively down by default.
|
||||
*/
|
||||
- rtl8365mb_port_stp_state_set(priv->ds, i, BR_STATE_DISABLED);
|
||||
+ rtl8365mb_port_stp_state_set(ds, i, BR_STATE_DISABLED);
|
||||
|
||||
/* Set up per-port private data */
|
||||
p->priv = priv;
|
||||
--- a/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
@@ -1565,6 +1565,7 @@ static int rtl8366rb_get_mc_index(struct
|
||||
|
||||
static int rtl8366rb_set_mc_index(struct realtek_priv *priv, int port, int index)
|
||||
{
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
struct rtl8366rb *rb;
|
||||
bool pvid_enabled;
|
||||
int ret;
|
||||
@@ -1589,7 +1590,7 @@ static int rtl8366rb_set_mc_index(struct
|
||||
* not drop any untagged or C-tagged frames. Make sure to update the
|
||||
* filtering setting.
|
||||
*/
|
||||
- if (dsa_port_is_vlan_filtering(dsa_to_port(priv->ds, port)))
|
||||
+ if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
|
||||
ret = rtl8366rb_drop_untagged(priv, port, !pvid_enabled);
|
||||
|
||||
return ret;
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -218,7 +218,7 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_probe, REAL
|
||||
*/
|
||||
int rtl83xx_register_switch(struct realtek_priv *priv)
|
||||
{
|
||||
- struct dsa_switch *ds;
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
int ret;
|
||||
|
||||
ret = priv->ops->detect(priv);
|
||||
@@ -227,15 +227,10 @@ int rtl83xx_register_switch(struct realt
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ds = devm_kzalloc(priv->dev, sizeof(*ds), GFP_KERNEL);
|
||||
- if (!ds)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
ds->priv = priv;
|
||||
ds->dev = priv->dev;
|
||||
ds->ops = priv->variant->ds_ops;
|
||||
ds->num_ports = priv->num_ports;
|
||||
- priv->ds = ds;
|
||||
|
||||
ret = dsa_register_switch(ds);
|
||||
if (ret) {
|
||||
@@ -258,7 +253,9 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_register_sw
|
||||
*/
|
||||
void rtl83xx_unregister_switch(struct realtek_priv *priv)
|
||||
{
|
||||
- dsa_unregister_switch(priv->ds);
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
+
|
||||
+ dsa_unregister_switch(ds);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_switch, REALTEK_DSA);
|
||||
|
||||
@@ -275,7 +272,9 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_unregister_
|
||||
*/
|
||||
void rtl83xx_shutdown(struct realtek_priv *priv)
|
||||
{
|
||||
- dsa_switch_shutdown(priv->ds);
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
+
|
||||
+ dsa_switch_shutdown(ds);
|
||||
|
||||
dev_set_drvdata(priv->dev, NULL);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
From 32e4a5447ed9fa904a2dfcf4609c64bce053b4e8 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Mon, 12 Feb 2024 18:34:33 -0300
|
||||
Subject: [PATCH] net: dsa: realtek: fix digital interface select macro for
|
||||
EXT0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
While no supported devices currently utilize EXT0, the register reserves
|
||||
the bits for an EXT0. EXT0 is utilized by devices from the generation
|
||||
prior to rtl8365mb, such as those supported by the driver library
|
||||
rtl8367b.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240212-realtek-fix_ext0-v1-1-f3d2536d191a@gmail.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/realtek/rtl8365mb.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
|
||||
@@ -209,10 +209,10 @@
|
||||
#define RTL8365MB_EXT_PORT_MODE_100FX 13
|
||||
|
||||
/* External interface mode configuration registers 0~1 */
|
||||
-#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG0 0x1305 /* EXT1 */
|
||||
+#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG0 0x1305 /* EXT0,EXT1 */
|
||||
#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG1 0x13C3 /* EXT2 */
|
||||
#define RTL8365MB_DIGITAL_INTERFACE_SELECT_REG(_extint) \
|
||||
- ((_extint) == 1 ? RTL8365MB_DIGITAL_INTERFACE_SELECT_REG0 : \
|
||||
+ ((_extint) <= 1 ? RTL8365MB_DIGITAL_INTERFACE_SELECT_REG0 : \
|
||||
(_extint) == 2 ? RTL8365MB_DIGITAL_INTERFACE_SELECT_REG1 : \
|
||||
0x0)
|
||||
#define RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_MASK(_extint) \
|
@ -0,0 +1,34 @@
|
||||
From 28001bb1955fcfa63e535848c4289fcd7bb88daf Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Sun, 25 Feb 2024 13:29:53 -0300
|
||||
Subject: [PATCH 1/3] dt-bindings: net: dsa: realtek: reset-gpios is not
|
||||
required
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The 'reset-gpios' should not be mandatory. although they might be
|
||||
required for some devices if the switch reset was left asserted by a
|
||||
previous driver, such as the bootloader.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
Documentation/devicetree/bindings/net/dsa/realtek.yaml | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/dsa/realtek.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/dsa/realtek.yaml
|
||||
@@ -125,7 +125,6 @@ else:
|
||||
- mdc-gpios
|
||||
- mdio-gpios
|
||||
- mdio
|
||||
- - reset-gpios
|
||||
|
||||
required:
|
||||
- compatible
|
@ -0,0 +1,33 @@
|
||||
From 5fc2d68fc81801162188995e4d3dc0b26747dd76 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Sun, 25 Feb 2024 13:29:54 -0300
|
||||
Subject: [PATCH 2/3] dt-bindings: net: dsa: realtek: add reset controller
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Realtek switches can use a reset controller instead of reset-gpios.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Cc: devicetree@vger.kernel.org
|
||||
Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
Documentation/devicetree/bindings/net/dsa/realtek.yaml | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/net/dsa/realtek.yaml
|
||||
+++ b/Documentation/devicetree/bindings/net/dsa/realtek.yaml
|
||||
@@ -59,6 +59,9 @@ properties:
|
||||
description: GPIO to be used to reset the whole device
|
||||
maxItems: 1
|
||||
|
||||
+ resets:
|
||||
+ maxItems: 1
|
||||
+
|
||||
realtek,disable-leds:
|
||||
type: boolean
|
||||
description: |
|
@ -0,0 +1,123 @@
|
||||
From 56998aa6b7f0f31ce8df23c00701af2d8e8a1f1a Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Sun, 25 Feb 2024 13:29:55 -0300
|
||||
Subject: [PATCH 3/3] net: dsa: realtek: support reset controller
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add support for resetting the device using a reset controller,
|
||||
complementing the existing GPIO reset functionality (reset-gpios).
|
||||
|
||||
Although the reset is optional and the driver performs a soft reset
|
||||
during setup, if the initial reset pin state was asserted, the driver
|
||||
will not detect the device until the reset is deasserted.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/realtek.h | 2 ++
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 42 +++++++++++++++++++++++++++----
|
||||
drivers/net/dsa/realtek/rtl83xx.h | 2 ++
|
||||
3 files changed, 41 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/realtek.h
|
||||
+++ b/drivers/net/dsa/realtek/realtek.h
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <net/dsa.h>
|
||||
+#include <linux/reset.h>
|
||||
|
||||
#define REALTEK_HW_STOP_DELAY 25 /* msecs */
|
||||
#define REALTEK_HW_START_DELAY 100 /* msecs */
|
||||
@@ -48,6 +49,7 @@ struct rtl8366_vlan_4k {
|
||||
|
||||
struct realtek_priv {
|
||||
struct device *dev;
|
||||
+ struct reset_control *reset_ctl;
|
||||
struct gpio_desc *reset;
|
||||
struct gpio_desc *mdc;
|
||||
struct gpio_desc *mdio;
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -185,6 +185,13 @@ rtl83xx_probe(struct device *dev,
|
||||
"realtek,disable-leds");
|
||||
|
||||
/* TODO: if power is software controlled, set up any regulators here */
|
||||
+ priv->reset_ctl = devm_reset_control_get_optional(dev, NULL);
|
||||
+ if (IS_ERR(priv->reset_ctl)) {
|
||||
+ ret = PTR_ERR(priv->reset_ctl);
|
||||
+ dev_err_probe(dev, ret, "failed to get reset control\n");
|
||||
+ return ERR_CAST(priv->reset_ctl);
|
||||
+ }
|
||||
+
|
||||
priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(priv->reset)) {
|
||||
dev_err(dev, "failed to get RESET GPIO\n");
|
||||
@@ -193,11 +200,11 @@ rtl83xx_probe(struct device *dev,
|
||||
|
||||
dev_set_drvdata(dev, priv);
|
||||
|
||||
- if (priv->reset) {
|
||||
- gpiod_set_value(priv->reset, 1);
|
||||
+ if (priv->reset_ctl || priv->reset) {
|
||||
+ rtl83xx_reset_assert(priv);
|
||||
dev_dbg(dev, "asserted RESET\n");
|
||||
msleep(REALTEK_HW_STOP_DELAY);
|
||||
- gpiod_set_value(priv->reset, 0);
|
||||
+ rtl83xx_reset_deassert(priv);
|
||||
msleep(REALTEK_HW_START_DELAY);
|
||||
dev_dbg(dev, "deasserted RESET\n");
|
||||
}
|
||||
@@ -293,11 +300,36 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, R
|
||||
void rtl83xx_remove(struct realtek_priv *priv)
|
||||
{
|
||||
/* leave the device reset asserted */
|
||||
- if (priv->reset)
|
||||
- gpiod_set_value(priv->reset, 1);
|
||||
+ rtl83xx_reset_assert(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
|
||||
|
||||
+void rtl83xx_reset_assert(struct realtek_priv *priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = reset_control_assert(priv->reset_ctl);
|
||||
+ if (ret)
|
||||
+ dev_warn(priv->dev,
|
||||
+ "Failed to assert the switch reset control: %pe\n",
|
||||
+ ERR_PTR(ret));
|
||||
+
|
||||
+ gpiod_set_value(priv->reset, true);
|
||||
+}
|
||||
+
|
||||
+void rtl83xx_reset_deassert(struct realtek_priv *priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = reset_control_deassert(priv->reset_ctl);
|
||||
+ if (ret)
|
||||
+ dev_warn(priv->dev,
|
||||
+ "Failed to deassert the switch reset control: %pe\n",
|
||||
+ ERR_PTR(ret));
|
||||
+
|
||||
+ gpiod_set_value(priv->reset, false);
|
||||
+}
|
||||
+
|
||||
MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
|
||||
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
|
||||
MODULE_DESCRIPTION("Realtek DSA switches common module");
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.h
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.h
|
||||
@@ -18,5 +18,7 @@ int rtl83xx_register_switch(struct realt
|
||||
void rtl83xx_unregister_switch(struct realtek_priv *priv);
|
||||
void rtl83xx_shutdown(struct realtek_priv *priv);
|
||||
void rtl83xx_remove(struct realtek_priv *priv);
|
||||
+void rtl83xx_reset_assert(struct realtek_priv *priv);
|
||||
+void rtl83xx_reset_deassert(struct realtek_priv *priv);
|
||||
|
||||
#endif /* _RTL83XX_H */
|
@ -0,0 +1,45 @@
|
||||
From 4f580e9aced1816398c1c64f178302a22b8ea6e2 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Sat, 27 Apr 2024 02:11:29 -0300
|
||||
Subject: [PATCH 2/3] net: dsa: realtek: do not assert reset on remove
|
||||
|
||||
The necessity of asserting the reset on removal was previously
|
||||
questioned, as DSA's own cleanup methods should suffice to prevent
|
||||
traffic leakage[1].
|
||||
|
||||
When a driver has subdrivers controlled by devres, they will be
|
||||
unregistered after the main driver's .remove is executed. If it asserts
|
||||
a reset, the subdrivers will be unable to communicate with the hardware
|
||||
during their cleanup. For LEDs, this means that they will fail to turn
|
||||
off, resulting in a timeout error.
|
||||
|
||||
[1] https://lore.kernel.org/r/20240123215606.26716-9-luizluca@gmail.com/
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/rtl83xx.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/rtl83xx.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl83xx.c
|
||||
@@ -291,16 +291,13 @@ EXPORT_SYMBOL_NS_GPL(rtl83xx_shutdown, R
|
||||
* rtl83xx_remove() - Cleanup a realtek switch driver
|
||||
* @priv: realtek_priv pointer
|
||||
*
|
||||
- * If a method is provided, this function asserts the hard reset of the switch
|
||||
- * in order to avoid leaking traffic when the driver is gone.
|
||||
+ * Placehold for common cleanup procedures.
|
||||
*
|
||||
- * Context: Might sleep if priv->gdev->chip->can_sleep.
|
||||
+ * Context: Any
|
||||
* Return: nothing
|
||||
*/
|
||||
void rtl83xx_remove(struct realtek_priv *priv)
|
||||
{
|
||||
- /* leave the device reset asserted */
|
||||
- rtl83xx_reset_assert(priv);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rtl83xx_remove, REALTEK_DSA);
|
||||
|
@ -0,0 +1,396 @@
|
||||
From 32d617005475a71ebcc4ec8b2791e8d1481e9a10 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Date: Sat, 27 Apr 2024 02:11:30 -0300
|
||||
Subject: [PATCH 3/3] net: dsa: realtek: add LED drivers for rtl8366rb
|
||||
|
||||
This commit introduces LED drivers for rtl8366rb, enabling LEDs to be
|
||||
described in the device tree using the same format as qca8k. Each port
|
||||
can configure up to 4 LEDs.
|
||||
|
||||
If all LEDs in a group use the default state "keep", they will use the
|
||||
default behavior after a reset. Changing the brightness of one LED,
|
||||
either manually or by a trigger, will disable the default hardware
|
||||
trigger and switch the entire LED group to manually controlled LEDs.
|
||||
Once in this mode, there is no way to revert to hardware-controlled LEDs
|
||||
(except by resetting the switch).
|
||||
|
||||
Software triggers function as expected with manually controlled LEDs.
|
||||
|
||||
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
|
||||
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/realtek/rtl8366rb.c | 304 ++++++++++++++++++++++++----
|
||||
1 file changed, 265 insertions(+), 39 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
|
||||
@@ -180,6 +180,7 @@
|
||||
#define RTL8366RB_VLAN_INGRESS_CTRL2_REG 0x037f
|
||||
|
||||
/* LED control registers */
|
||||
+/* The LED blink rate is global; it is used by all triggers in all groups. */
|
||||
#define RTL8366RB_LED_BLINKRATE_REG 0x0430
|
||||
#define RTL8366RB_LED_BLINKRATE_MASK 0x0007
|
||||
#define RTL8366RB_LED_BLINKRATE_28MS 0x0000
|
||||
@@ -195,31 +196,21 @@
|
||||
(4 * (led_group))
|
||||
#define RTL8366RB_LED_CTRL_MASK(led_group) \
|
||||
(0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))
|
||||
-#define RTL8366RB_LED_OFF 0x0
|
||||
-#define RTL8366RB_LED_DUP_COL 0x1
|
||||
-#define RTL8366RB_LED_LINK_ACT 0x2
|
||||
-#define RTL8366RB_LED_SPD1000 0x3
|
||||
-#define RTL8366RB_LED_SPD100 0x4
|
||||
-#define RTL8366RB_LED_SPD10 0x5
|
||||
-#define RTL8366RB_LED_SPD1000_ACT 0x6
|
||||
-#define RTL8366RB_LED_SPD100_ACT 0x7
|
||||
-#define RTL8366RB_LED_SPD10_ACT 0x8
|
||||
-#define RTL8366RB_LED_SPD100_10_ACT 0x9
|
||||
-#define RTL8366RB_LED_FIBER 0xa
|
||||
-#define RTL8366RB_LED_AN_FAULT 0xb
|
||||
-#define RTL8366RB_LED_LINK_RX 0xc
|
||||
-#define RTL8366RB_LED_LINK_TX 0xd
|
||||
-#define RTL8366RB_LED_MASTER 0xe
|
||||
-#define RTL8366RB_LED_FORCE 0xf
|
||||
|
||||
/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
|
||||
* when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
|
||||
- * RTL8366RB_LED_FORCE. Otherwise, it is ignored.
|
||||
+ * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored.
|
||||
*/
|
||||
#define RTL8366RB_LED_0_1_CTRL_REG 0x0432
|
||||
-#define RTL8366RB_LED_1_OFFSET 6
|
||||
#define RTL8366RB_LED_2_3_CTRL_REG 0x0433
|
||||
-#define RTL8366RB_LED_3_OFFSET 6
|
||||
+#define RTL8366RB_LED_X_X_CTRL_REG(led_group) \
|
||||
+ ((led_group) <= 1 ? \
|
||||
+ RTL8366RB_LED_0_1_CTRL_REG : \
|
||||
+ RTL8366RB_LED_2_3_CTRL_REG)
|
||||
+#define RTL8366RB_LED_0_X_CTRL_MASK GENMASK(5, 0)
|
||||
+#define RTL8366RB_LED_X_1_CTRL_MASK GENMASK(11, 6)
|
||||
+#define RTL8366RB_LED_2_X_CTRL_MASK GENMASK(5, 0)
|
||||
+#define RTL8366RB_LED_X_3_CTRL_MASK GENMASK(11, 6)
|
||||
|
||||
#define RTL8366RB_MIB_COUNT 33
|
||||
#define RTL8366RB_GLOBAL_MIB_COUNT 1
|
||||
@@ -363,14 +354,44 @@
|
||||
#define RTL8366RB_GREEN_FEATURE_TX BIT(0)
|
||||
#define RTL8366RB_GREEN_FEATURE_RX BIT(2)
|
||||
|
||||
+enum rtl8366_ledgroup_mode {
|
||||
+ RTL8366RB_LEDGROUP_OFF = 0x0,
|
||||
+ RTL8366RB_LEDGROUP_DUP_COL = 0x1,
|
||||
+ RTL8366RB_LEDGROUP_LINK_ACT = 0x2,
|
||||
+ RTL8366RB_LEDGROUP_SPD1000 = 0x3,
|
||||
+ RTL8366RB_LEDGROUP_SPD100 = 0x4,
|
||||
+ RTL8366RB_LEDGROUP_SPD10 = 0x5,
|
||||
+ RTL8366RB_LEDGROUP_SPD1000_ACT = 0x6,
|
||||
+ RTL8366RB_LEDGROUP_SPD100_ACT = 0x7,
|
||||
+ RTL8366RB_LEDGROUP_SPD10_ACT = 0x8,
|
||||
+ RTL8366RB_LEDGROUP_SPD100_10_ACT = 0x9,
|
||||
+ RTL8366RB_LEDGROUP_FIBER = 0xa,
|
||||
+ RTL8366RB_LEDGROUP_AN_FAULT = 0xb,
|
||||
+ RTL8366RB_LEDGROUP_LINK_RX = 0xc,
|
||||
+ RTL8366RB_LEDGROUP_LINK_TX = 0xd,
|
||||
+ RTL8366RB_LEDGROUP_MASTER = 0xe,
|
||||
+ RTL8366RB_LEDGROUP_FORCE = 0xf,
|
||||
+
|
||||
+ __RTL8366RB_LEDGROUP_MODE_MAX
|
||||
+};
|
||||
+
|
||||
+struct rtl8366rb_led {
|
||||
+ u8 port_num;
|
||||
+ u8 led_group;
|
||||
+ struct realtek_priv *priv;
|
||||
+ struct led_classdev cdev;
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct rtl8366rb - RTL8366RB-specific data
|
||||
* @max_mtu: per-port max MTU setting
|
||||
* @pvid_enabled: if PVID is set for respective port
|
||||
+ * @leds: per-port and per-ledgroup led info
|
||||
*/
|
||||
struct rtl8366rb {
|
||||
unsigned int max_mtu[RTL8366RB_NUM_PORTS];
|
||||
bool pvid_enabled[RTL8366RB_NUM_PORTS];
|
||||
+ struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS];
|
||||
};
|
||||
|
||||
static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
|
||||
@@ -813,6 +834,217 @@ static int rtl8366rb_jam_table(const str
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
|
||||
+ u8 led_group,
|
||||
+ enum rtl8366_ledgroup_mode mode)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = mode << RTL8366RB_LED_CTRL_OFFSET(led_group);
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->map,
|
||||
+ RTL8366RB_LED_CTRL_REG,
|
||||
+ RTL8366RB_LED_CTRL_MASK(led_group),
|
||||
+ val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port)
|
||||
+{
|
||||
+ switch (led_group) {
|
||||
+ case 0:
|
||||
+ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
|
||||
+ case 1:
|
||||
+ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
|
||||
+ case 2:
|
||||
+ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
|
||||
+ case 3:
|
||||
+ return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port));
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int rb8366rb_get_port_led(struct rtl8366rb_led *led)
|
||||
+{
|
||||
+ struct realtek_priv *priv = led->priv;
|
||||
+ u8 led_group = led->led_group;
|
||||
+ u8 port_num = led->port_num;
|
||||
+ int ret;
|
||||
+ u32 val;
|
||||
+
|
||||
+ ret = regmap_read(priv->map, RTL8366RB_LED_X_X_CTRL_REG(led_group),
|
||||
+ &val);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "error reading LED on port %d group %d\n",
|
||||
+ led_group, port_num);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return !!(val & rtl8366rb_led_group_port_mask(led_group, port_num));
|
||||
+}
|
||||
+
|
||||
+static int rb8366rb_set_port_led(struct rtl8366rb_led *led, bool enable)
|
||||
+{
|
||||
+ struct realtek_priv *priv = led->priv;
|
||||
+ u8 led_group = led->led_group;
|
||||
+ u8 port_num = led->port_num;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->map,
|
||||
+ RTL8366RB_LED_X_X_CTRL_REG(led_group),
|
||||
+ rtl8366rb_led_group_port_mask(led_group,
|
||||
+ port_num),
|
||||
+ enable ? 0xffff : 0);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "error updating LED on port %d group %d\n",
|
||||
+ led_group, port_num);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Change the LED group to manual controlled LEDs if required */
|
||||
+ ret = rb8366rb_set_ledgroup_mode(priv, led_group,
|
||||
+ RTL8366RB_LEDGROUP_FORCE);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "error updating LED GROUP group %d\n",
|
||||
+ led_group);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+rtl8366rb_cled_brightness_set_blocking(struct led_classdev *ldev,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ struct rtl8366rb_led *led = container_of(ldev, struct rtl8366rb_led,
|
||||
+ cdev);
|
||||
+
|
||||
+ return rb8366rb_set_port_led(led, brightness == LED_ON);
|
||||
+}
|
||||
+
|
||||
+static int rtl8366rb_setup_led(struct realtek_priv *priv, struct dsa_port *dp,
|
||||
+ struct fwnode_handle *led_fwnode)
|
||||
+{
|
||||
+ struct rtl8366rb *rb = priv->chip_data;
|
||||
+ struct led_init_data init_data = { };
|
||||
+ enum led_default_state state;
|
||||
+ struct rtl8366rb_led *led;
|
||||
+ u32 led_group;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = fwnode_property_read_u32(led_fwnode, "reg", &led_group);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (led_group >= RTL8366RB_NUM_LEDGROUPS) {
|
||||
+ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d",
|
||||
+ led_group, dp->index);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ led = &rb->leds[dp->index][led_group];
|
||||
+ led->port_num = dp->index;
|
||||
+ led->led_group = led_group;
|
||||
+ led->priv = priv;
|
||||
+
|
||||
+ state = led_init_default_state_get(led_fwnode);
|
||||
+ switch (state) {
|
||||
+ case LEDS_DEFSTATE_ON:
|
||||
+ led->cdev.brightness = 1;
|
||||
+ rb8366rb_set_port_led(led, 1);
|
||||
+ break;
|
||||
+ case LEDS_DEFSTATE_KEEP:
|
||||
+ led->cdev.brightness =
|
||||
+ rb8366rb_get_port_led(led);
|
||||
+ break;
|
||||
+ case LEDS_DEFSTATE_OFF:
|
||||
+ default:
|
||||
+ led->cdev.brightness = 0;
|
||||
+ rb8366rb_set_port_led(led, 0);
|
||||
+ }
|
||||
+
|
||||
+ led->cdev.max_brightness = 1;
|
||||
+ led->cdev.brightness_set_blocking =
|
||||
+ rtl8366rb_cled_brightness_set_blocking;
|
||||
+ init_data.fwnode = led_fwnode;
|
||||
+ init_data.devname_mandatory = true;
|
||||
+
|
||||
+ init_data.devicename = kasprintf(GFP_KERNEL, "Realtek-%d:0%d:%d",
|
||||
+ dp->ds->index, dp->index, led_group);
|
||||
+ if (!init_data.devicename)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = devm_led_classdev_register_ext(priv->dev, &led->cdev, &init_data);
|
||||
+ if (ret) {
|
||||
+ dev_warn(priv->dev, "Failed to init LED %d for port %d",
|
||||
+ led_group, dp->index);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rtl8366rb_setup_all_leds_off(struct realtek_priv *priv)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ regmap_update_bits(priv->map,
|
||||
+ RTL8366RB_INTERRUPT_CONTROL_REG,
|
||||
+ RTL8366RB_P4_RGMII_LED,
|
||||
+ 0);
|
||||
+
|
||||
+ for (i = 0; i < RTL8366RB_NUM_LEDGROUPS; i++) {
|
||||
+ ret = rb8366rb_set_ledgroup_mode(priv, i,
|
||||
+ RTL8366RB_LEDGROUP_OFF);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int rtl8366rb_setup_leds(struct realtek_priv *priv)
|
||||
+{
|
||||
+ struct device_node *leds_np, *led_np;
|
||||
+ struct dsa_switch *ds = &priv->ds;
|
||||
+ struct dsa_port *dp;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ dsa_switch_for_each_port(dp, ds) {
|
||||
+ if (!dp->dn)
|
||||
+ continue;
|
||||
+
|
||||
+ leds_np = of_get_child_by_name(dp->dn, "leds");
|
||||
+ if (!leds_np) {
|
||||
+ dev_dbg(priv->dev, "No leds defined for port %d",
|
||||
+ dp->index);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ for_each_child_of_node(leds_np, led_np) {
|
||||
+ ret = rtl8366rb_setup_led(priv, dp,
|
||||
+ of_fwnode_handle(led_np));
|
||||
+ if (ret) {
|
||||
+ of_node_put(led_np);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ of_node_put(leds_np);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int rtl8366rb_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct realtek_priv *priv = ds->priv;
|
||||
@@ -821,7 +1053,6 @@ static int rtl8366rb_setup(struct dsa_sw
|
||||
u32 chip_ver = 0;
|
||||
u32 chip_id = 0;
|
||||
int jam_size;
|
||||
- u32 val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -997,7 +1228,9 @@ static int rtl8366rb_setup(struct dsa_sw
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Set blinking, TODO: make this configurable */
|
||||
+ /* Set blinking, used by all LED groups using HW triggers.
|
||||
+ * TODO: make this configurable
|
||||
+ */
|
||||
ret = regmap_update_bits(priv->map, RTL8366RB_LED_BLINKRATE_REG,
|
||||
RTL8366RB_LED_BLINKRATE_MASK,
|
||||
RTL8366RB_LED_BLINKRATE_56MS);
|
||||
@@ -1005,26 +1238,19 @@ static int rtl8366rb_setup(struct dsa_sw
|
||||
return ret;
|
||||
|
||||
/* Set up LED activity:
|
||||
- * Each port has 4 LEDs, we configure all ports to the same
|
||||
- * behaviour (no individual config) but we can set up each
|
||||
- * LED separately.
|
||||
+ * Each port has 4 LEDs on fixed groups. Each group shares the same
|
||||
+ * hardware trigger across all ports. LEDs can only be indiviually
|
||||
+ * controlled setting the LED group to fixed mode and using the driver
|
||||
+ * to toggle them LEDs on/off.
|
||||
*/
|
||||
if (priv->leds_disabled) {
|
||||
- /* Turn everything off */
|
||||
- regmap_update_bits(priv->map,
|
||||
- RTL8366RB_INTERRUPT_CONTROL_REG,
|
||||
- RTL8366RB_P4_RGMII_LED,
|
||||
- 0);
|
||||
-
|
||||
- for (i = 0; i < RTL8366RB_NUM_LEDGROUPS; i++) {
|
||||
- val = RTL8366RB_LED_OFF << RTL8366RB_LED_CTRL_OFFSET(i);
|
||||
- ret = regmap_update_bits(priv->map,
|
||||
- RTL8366RB_LED_CTRL_REG,
|
||||
- RTL8366RB_LED_CTRL_MASK(i),
|
||||
- val);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
+ ret = rtl8366rb_setup_all_leds_off(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ ret = rtl8366rb_setup_leds(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
ret = rtl8366_reset_vlan(priv);
|
@ -5,16 +5,38 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
FAT32_BLOCK_SIZE=1024
|
||||
FAT32_BLOCKS=$(shell echo $$(($(CONFIG_MXS_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE))))
|
||||
FAT32_BLOCK_SIZE = 1024
|
||||
FAT32_BLOCKS = $(shell echo $$(($(CONFIG_MXS_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE))))
|
||||
|
||||
KERNEL_LOADADDR:=0x40008000
|
||||
KERNEL_LOADADDR := 0x40008000
|
||||
|
||||
define Build/mxs-ext4-rootfs-with-boot
|
||||
rm -rf $(call mkfs_target_dir,$(1))/boot
|
||||
mkdir -p $(call mkfs_target_dir,$(1))/boot
|
||||
$(CP) --no-preserve=mode $(KDIR)/$(KERNEL_NAME) $(call mkfs_target_dir,$(1))/boot/
|
||||
$(foreach dts,$(DEVICE_DTS), \
|
||||
$(CP) \
|
||||
$(DTS_DIR)/$(dts).dtb \
|
||||
$(call mkfs_target_dir,$(1))/boot/; \
|
||||
)
|
||||
|
||||
rm -rf $@.rootfs
|
||||
$(STAGING_DIR_HOST)/bin/make_ext4fs -L rootfs \
|
||||
-l $(ROOTFS_PARTSIZE) -b $(CONFIG_TARGET_EXT4_BLOCKSIZE) \
|
||||
$(if $(CONFIG_TARGET_EXT4_RESERVED_PCT),-m $(CONFIG_TARGET_EXT4_RESERVED_PCT)) \
|
||||
$(if $(CONFIG_TARGET_EXT4_JOURNAL),,-J) \
|
||||
$(if $(SOURCE_DATE_EPOCH),-T $(SOURCE_DATE_EPOCH)) \
|
||||
$@.rootfs $(call mkfs_target_dir,$(1))/
|
||||
mv $@.rootfs $@
|
||||
endef
|
||||
|
||||
define Build/mxs-sdcard-ext4-ext4
|
||||
mv $@ $@.rootfs
|
||||
|
||||
./gen_sdcard_ext4_ext4.sh \
|
||||
$@ \
|
||||
$(STAGING_DIR_IMAGE)/$(DEVICE_NAME)/u-boot.sb \
|
||||
$(IMAGE_ROOTFS) \
|
||||
$@.rootfs \
|
||||
$(CONFIG_TARGET_ROOTFS_PARTSIZE)
|
||||
endef
|
||||
|
||||
@ -46,12 +68,13 @@ endef
|
||||
define Device/i2se_duckbill
|
||||
DEVICE_VENDOR := I2SE
|
||||
DEVICE_MODEL := Duckbill
|
||||
DEVICE_PACKAGES := -dnsmasq -ppp -ip6tables -iptables -mtd \
|
||||
uboot-envtools kmod-leds-gpio -kmod-nf-nathelper
|
||||
SUPPORTED_DEVICES:=i2se,duckbill
|
||||
SOC:=imx28
|
||||
DEVICE_DTS:=imx28-duckbill
|
||||
IMAGE/sdcard.img.gz = mxs-sdcard-ext4-ext4 | append-metadata | gzip
|
||||
DEVICE_PACKAGES := -dnsmasq -firewall4 -mtd -nftables -odhcpd-ipv6only -ppp -kmod-nft-offload \
|
||||
uboot-envtools kmod-leds-gpio
|
||||
SUPPORTED_DEVICES := i2se,duckbill
|
||||
SOC := imx28
|
||||
KERNEL := kernel-bin
|
||||
DEVICE_DTS := imx28-duckbill imx28-duckbill-2 imx28-duckbill-2-485 imx28-duckbill-2-spi
|
||||
IMAGE/sdcard.img.gz = mxs-ext4-rootfs-with-boot | mxs-sdcard-ext4-ext4 | append-metadata | gzip
|
||||
endef
|
||||
TARGET_DEVICES += i2se_duckbill
|
||||
|
||||
@ -59,10 +82,10 @@ define Device/olinuxino_maxi
|
||||
DEVICE_VENDOR := Olimex
|
||||
DEVICE_MODEL := OLinuXino Maxi
|
||||
DEVICE_PACKAGES := kmod-usb-net-smsc95xx kmod-pinctrl-mcp23s08-i2c \
|
||||
kmod-pinctrl-mcp23s08-spi kmod-leds-gpio kmod-sound-core
|
||||
SUPPORTED_DEVICES:=olimex,imx23-olinuxino
|
||||
SOC:=imx23
|
||||
DEVICE_DTS:=imx23-olinuxino
|
||||
kmod-pinctrl-mcp23s08-spi kmod-leds-gpio kmod-sound-core
|
||||
SUPPORTED_DEVICES := olimex,imx23-olinuxino
|
||||
SOC := imx23
|
||||
DEVICE_DTS := imx23-olinuxino
|
||||
IMAGE/sdcard.img.gz = mxs-sdcard-vfat-ext4 | append-metadata | gzip
|
||||
endef
|
||||
TARGET_DEVICES += olinuxino_maxi
|
||||
@ -71,10 +94,10 @@ define Device/olinuxino_micro
|
||||
DEVICE_VENDOR := Olimex
|
||||
DEVICE_MODEL := OLinuXino Micro
|
||||
DEVICE_PACKAGES := kmod-pinctrl-mcp23s08-spi kmod-pinctrl-mcp23s08-i2c \
|
||||
kmod-leds-gpio
|
||||
SUPPORTED_DEVICES:=olimex,imx23-olinuxino
|
||||
SOC:=imx23
|
||||
DEVICE_DTS:=imx23-olinuxino
|
||||
kmod-leds-gpio
|
||||
SUPPORTED_DEVICES := olimex,imx23-olinuxino
|
||||
SOC := imx23
|
||||
DEVICE_DTS := imx23-olinuxino
|
||||
IMAGE/sdcard.img.gz = mxs-sdcard-vfat-ext4 | append-metadata | gzip
|
||||
endef
|
||||
TARGET_DEVICES += olinuxino_micro
|
||||
|
@ -6,7 +6,7 @@ BOARDNAME:=Qualcomm Atheros 802.11ax WiSoC-s
|
||||
FEATURES:=squashfs ramdisk fpu nand rtc emmc
|
||||
KERNELNAME:=Image
|
||||
CPU_TYPE:=cortex-a53
|
||||
SUBTARGETS:=ipq807x ipq60xx
|
||||
SUBTARGETS:=ipq807x ipq60xx ipq50xx
|
||||
|
||||
KERNEL_PATCHVER:=6.6
|
||||
|
||||
@ -14,8 +14,7 @@ include $(INCLUDE_DIR)/target.mk
|
||||
DEFAULT_PACKAGES += \
|
||||
kmod-usb3 kmod-usb-dwc3 kmod-usb-dwc3-qcom \
|
||||
kmod-leds-gpio kmod-gpio-button-hotplug \
|
||||
kmod-qca-nss-dp \
|
||||
kmod-ath11k-ahb wpad-openssl \
|
||||
kmod-qca-nss-dp kmod-ath11k-ahb wpad-openssl \
|
||||
uboot-envtools losetup \
|
||||
automount cpufreq
|
||||
|
||||
|
@ -0,0 +1,116 @@
|
||||
#include <dt-bindings/net/qcom-ipq-ess.h>
|
||||
|
||||
&soc {
|
||||
ess_instance: ess-instance {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
num_devices = <1>;
|
||||
|
||||
switch: ess-switch@39c00000 {
|
||||
compatible = "qcom,ess-switch-ipq50xx";
|
||||
device_id = <0>;
|
||||
cmnblk_clk = "internal_96MHz";
|
||||
reg = <0x39c00000 0x200000>;
|
||||
switch_access_mode = "local bus";
|
||||
clocks = <&gcc GCC_CMN_BLK_AHB_CLK>,
|
||||
<&gcc GCC_CMN_BLK_SYS_CLK>,
|
||||
<&gcc GCC_UNIPHY_AHB_CLK>,
|
||||
<&gcc GCC_UNIPHY_SYS_CLK>,
|
||||
<&gcc GCC_MDIO0_AHB_CLK>,
|
||||
<&gcc GCC_MDIO1_AHB_CLK>,
|
||||
<&gcc GCC_GMAC0_CFG_CLK>,
|
||||
<&gcc GCC_GMAC0_SYS_CLK>,
|
||||
<&gcc GCC_GMAC1_CFG_CLK>,
|
||||
<&gcc GCC_GMAC1_SYS_CLK>,
|
||||
<&gcc GCC_GEPHY_RX_CLK>,
|
||||
<&gcc GCC_GEPHY_TX_CLK>,
|
||||
<&gcc GCC_UNIPHY_RX_CLK>,
|
||||
<&gcc GCC_UNIPHY_TX_CLK>,
|
||||
<&gcc GCC_GMAC0_RX_CLK>,
|
||||
<&gcc GCC_GMAC0_TX_CLK>,
|
||||
<&gcc GCC_GMAC1_RX_CLK>,
|
||||
<&gcc GCC_GMAC1_TX_CLK>,
|
||||
<&gcc GCC_SNOC_GMAC0_AHB_CLK>,
|
||||
<&gcc GCC_SNOC_GMAC1_AHB_CLK>,
|
||||
<&gcc GCC_GMAC0_PTP_CLK>,
|
||||
<&gcc GCC_GMAC1_PTP_CLK>;
|
||||
clock-names = "cmn_ahb_clk",
|
||||
"cmn_sys_clk",
|
||||
"uniphy_ahb_clk",
|
||||
"uniphy_sys_clk",
|
||||
"gcc_mdio0_ahb_clk",
|
||||
"gcc_mdio1_ahb_clk",
|
||||
"gcc_gmac0_cfg_clk",
|
||||
"gcc_gmac0_sys_clk",
|
||||
"gcc_gmac1_cfg_clk",
|
||||
"gcc_gmac1_sys_clk",
|
||||
"uniphy0_port1_rx_clk",
|
||||
"uniphy0_port1_tx_clk",
|
||||
"uniphy1_port5_rx_clk",
|
||||
"uniphy1_port5_tx_clk",
|
||||
"nss_port1_rx_clk",
|
||||
"nss_port1_tx_clk",
|
||||
"nss_port2_rx_clk",
|
||||
"nss_port2_tx_clk",
|
||||
"gcc_snoc_gmac0_ahb_clk",
|
||||
"gcc_snoc_gmac1_ahb_clk",
|
||||
"gcc_gmac0_ptp_clk",
|
||||
"gcc_gmac1_ptp_clk";
|
||||
resets = <&gcc GCC_GMAC0_BCR>,
|
||||
<&gcc GCC_GMAC1_BCR>,
|
||||
<&gcc GCC_UNIPHY_BCR>,
|
||||
<&gcc GCC_UNIPHY_SOFT_RESET>;
|
||||
reset-names = "gmac0_bcr_rst",
|
||||
"gmac1_bcr_rst",
|
||||
"uniphy_bcr_rst",
|
||||
"uniphy1_soft_rst";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
ess-uniphy@98000 {
|
||||
compatible = "qcom,ess-uniphy";
|
||||
reg = <0x98000 0x800>;
|
||||
uniphy_access_mode = "local bus";
|
||||
};
|
||||
|
||||
nss-dp-common {
|
||||
compatible = "qcom,nss-dp-common";
|
||||
qcom,tcsr-base = <0x01937000>;
|
||||
};
|
||||
|
||||
dp1: dp1 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <1>;
|
||||
|
||||
reg = <0x39C00000 0x10000>;
|
||||
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
|
||||
clock-names = "nss-snoc-gmac-axi-clk";
|
||||
|
||||
qcom,mactype = <2>; /* GMAC_HAL_TYPE_SYN_GMAC */
|
||||
local-mac-address = [000000000000];
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&ge_phy>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
dp2: dp2 {
|
||||
device_type = "network";
|
||||
compatible = "qcom,nss-dp";
|
||||
qcom,id = <2>;
|
||||
|
||||
reg = <0x39D00000 0x10000>;
|
||||
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
|
||||
clock-names = "nss-snoc-gmac-axi-clk";
|
||||
|
||||
qcom,mactype = <2>; /* GMAC_HAL_TYPE_SYN_GMAC */
|
||||
local-mac-address = [000000000000];
|
||||
phy-mode = "sgmii";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
@ -0,0 +1,325 @@
|
||||
#include "ipq5018.dtsi"
|
||||
#include "ipq5018-ess.dtsi"
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
|
||||
aliases {
|
||||
ethernet0 = &dp1;
|
||||
ethernet1 = &dp2;
|
||||
led-boot = &led_system_blue;
|
||||
led-failsafe = &led_system_red;
|
||||
led-running = &led_system_blue;
|
||||
led-upgrade = &led_system_red;
|
||||
serial0 = &blsp1_uart1;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs-append = " root=/dev/ubiblock0_0 coherent_pool=2M";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
pinctrl-0 = <&button_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
wps-button {
|
||||
label = "wps";
|
||||
gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_WPS_BUTTON>;
|
||||
};
|
||||
|
||||
reset-button {
|
||||
label = "reset";
|
||||
gpios = <&tlmm 28 GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_RESTART>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
led_system_red: red {
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
function = LED_FUNCTION_POWER;
|
||||
pwms = <&pwm 3 1250000>;
|
||||
max-brightness = <255>;
|
||||
};
|
||||
|
||||
green {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_POWER;
|
||||
pwms = <&pwm 0 1250000>;
|
||||
max-brightness = <255>;
|
||||
};
|
||||
|
||||
led_system_blue: blue {
|
||||
color = <LED_COLOR_ID_BLUE>;
|
||||
function = LED_FUNCTION_POWER;
|
||||
pwms = <&pwm 1 1250000>;
|
||||
max-brightness = <255>;
|
||||
};
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
q6_mem_regions: q6_mem_regions@4b000000 {
|
||||
no-map;
|
||||
reg = <0x0 0x4b000000 0x0 0x3000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&sleep_clk {
|
||||
clock-frequency = <32000>;
|
||||
};
|
||||
|
||||
&xo_board_clk {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&blsp1_uart1 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&serial_0_pins>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&crypto {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cryptobam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&prng {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pwm {
|
||||
status = "okay";
|
||||
|
||||
#pwm-cells = <2>;
|
||||
pinctrl-0 = <&pwm_pins>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
&qfprom {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qpic_bam {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qpic_nand {
|
||||
pinctrl-0 = <&qpic_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
partitions {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
nand@0 {
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
nand-ecc-engine = <&qpic_nand>;
|
||||
|
||||
nand-ecc-strength = <8>;
|
||||
nand-ecc-step-size = <512>;
|
||||
nand-bus-width = <8>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "0:SBL1";
|
||||
reg = <0x00000000 0x80000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@80000 {
|
||||
label = "0:MIBIB";
|
||||
reg = <0x00080000 0x80000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@100000 {
|
||||
label = "0:QSEE";
|
||||
reg = <0x00100000 0x100000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@200000 {
|
||||
label = "0:DEVCFG";
|
||||
reg = <0x00200000 0x40000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@240000 {
|
||||
label = "0:CDT";
|
||||
reg = <0x00240000 0x40000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@280000 {
|
||||
label = "0:APPSBLENV";
|
||||
reg = <0x00280000 0x80000>;
|
||||
};
|
||||
|
||||
partition@300000 {
|
||||
label = "0:APPSBL";
|
||||
reg = <0x00300000 0x140000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@440000 {
|
||||
label = "0:ART";
|
||||
reg = <0x00440000 0x100000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@540000 {
|
||||
label = "0:TRAINING";
|
||||
reg = <0x00540000 0x80000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@5c0000 {
|
||||
label = "u_env";
|
||||
reg = <0x005c0000 0x80000>;
|
||||
};
|
||||
|
||||
partition@640000 {
|
||||
label = "s_env";
|
||||
reg = <0x00640000 0x40000>;
|
||||
};
|
||||
|
||||
partition@680000 {
|
||||
label = "devinfo";
|
||||
reg = <0x00680000 0x40000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@6c0000 {
|
||||
label = "kernel";
|
||||
reg = <0x006c0000 0x5200000>;
|
||||
};
|
||||
|
||||
partition@ec0000 {
|
||||
label = "rootfs";
|
||||
reg = <0x0ec0000 0x4a00000>;
|
||||
};
|
||||
|
||||
partition@58c0000 {
|
||||
label = "alt_kernel";
|
||||
reg = <0x058c0000 0x5200000>;
|
||||
};
|
||||
|
||||
partition@60c0000 {
|
||||
label = "alt_rootfs";
|
||||
reg = <0x060c0000 0x4a00000>;
|
||||
};
|
||||
|
||||
partition@aac0000 {
|
||||
label = "sysdiag";
|
||||
reg = <0x0aac0000 0x200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@acc0000 {
|
||||
label = "syscfg";
|
||||
reg = <0x0acc0000 0x4400000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
button_pins: button-state {
|
||||
pins = "gpio27", "gpio28";
|
||||
function = "gpio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
mdio1_pins: mdio-state {
|
||||
mdc-pins {
|
||||
pins = "gpio36";
|
||||
function = "mdc";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
mdio-pins {
|
||||
pins = "gpio37";
|
||||
function = "mdio";
|
||||
drive-strength = <8>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
pwm_pins: pwm-state {
|
||||
mux_1 {
|
||||
pins = "gpio1";
|
||||
function = "pwm1";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
mux_2 {
|
||||
pins = "gpio30";
|
||||
function = "pwm3";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
|
||||
mux_3 {
|
||||
pins = "gpio46";
|
||||
function = "pwm0";
|
||||
drive-strength = <8>;
|
||||
};
|
||||
};
|
||||
|
||||
qpic_pins: qpic-state {
|
||||
clock-pins {
|
||||
pins = "gpio9";
|
||||
function = "qspi_clk";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
cs-pins {
|
||||
pins = "gpio8";
|
||||
function = "qspi_cs";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
data-pins {
|
||||
pins = "gpio4", "gpio5", "gpio6", "gpio7";
|
||||
function = "qspi_data";
|
||||
drive-strength = <8>;
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
serial_0_pins: uart0-state {
|
||||
pins = "gpio20", "gpio21";
|
||||
function = "blsp0_uart0";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
|
||||
&tsens {
|
||||
status = "okay";
|
||||
};
|
@ -0,0 +1,262 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "ipq5018.dtsi"
|
||||
#include "ipq5018-mx-base.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Linksys MX2000";
|
||||
compatible = "linksys,mx2000", "qcom,ipq5018";
|
||||
};
|
||||
|
||||
/*
|
||||
* ===============================================================
|
||||
* _______________________ _______________________
|
||||
* | IPQ5018 | | QCA8337 |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* | | MAC0 |---| GE Phy | | | | Phy0 |---| MAC1 | |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC6 | |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* |_______________________| |_______________________|
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
|
||||
&switch {
|
||||
status = "okay";
|
||||
|
||||
switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;
|
||||
|
||||
qcom,port_phyinfo {
|
||||
// MAC0 -> GE Phy -> QCA8337 Phy4
|
||||
port@0 {
|
||||
port_id = <1>;
|
||||
mdiobus = <&mdio0>;
|
||||
phy_address = <7>;
|
||||
};
|
||||
|
||||
// MAC1 ---SGMII---> QCA8337 SerDes
|
||||
port@1 {
|
||||
port_id = <2>;
|
||||
forced-speed = <1000>;
|
||||
forced-duplex = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// MAC1 ---SGMII---> QCA8337 SerDes
|
||||
&dp2 {
|
||||
status = "okay";
|
||||
phy-mode = "sgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* IPQ5018 GE Phy -> Not connected
|
||||
* needs to be enabled for QSDK to identify the IPQ5018 dummy switch
|
||||
*/
|
||||
&ge_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdio1 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&mdio1_pins>;
|
||||
pinctrl-names = "default";
|
||||
reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
|
||||
|
||||
// QCA8337 Phy0 not connected
|
||||
qca8337_0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy1 -> WAN
|
||||
qca8337_1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy2 -> LAN1
|
||||
qca8337_2: ethernet-phy@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy3 -> LAN2
|
||||
qca8337_3: ethernet-phy@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy4 -> LAN3
|
||||
qca8337_4: ethernet-phy@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
|
||||
// QCA8337 switch
|
||||
switch1: ethernet-switch@17 {
|
||||
compatible = "qca,qca8337";
|
||||
reg = <17>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "wan";
|
||||
phy-handle = <&qca8337_1>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
phy-handle = <&qca8337_2>;
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "lan2";
|
||||
phy-handle = <&qca8337_3>;
|
||||
};
|
||||
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
label = "lan1";
|
||||
phy-handle = <&qca8337_4>;
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
label = "cpu";
|
||||
phy-mode = "sgmii";
|
||||
ethernet = <&dp2>;
|
||||
qca,sgmii-enable-pll;
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&q6v5_wcss {
|
||||
status = "okay";
|
||||
|
||||
memory-region = <&q6_mem_regions>;
|
||||
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt",
|
||||
"ath11k/IPQ5018/hw1.0/m3_fw.mdt",
|
||||
"ath11k/QCN6122/hw1.0/m3_fw.mdt";
|
||||
|
||||
/* The QCN6102 radio should map to UPD ID 2. Without */
|
||||
/* bootargs, the firmware will expect it to be on UPD ID 3 */
|
||||
boot-args = <
|
||||
/* type: */ 0x1 /* PCIE0 */
|
||||
/* length: */ 4
|
||||
/* UPD ID: */ 2
|
||||
/* reset GPIO: */ 15
|
||||
/* reserved: */ 0 0>;
|
||||
|
||||
// IPQ5018
|
||||
q6_wcss_pd1: pd-1 {
|
||||
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";
|
||||
|
||||
resets =
|
||||
<&gcc GCC_WCSSAON_RESET>,
|
||||
<&gcc GCC_WCSS_BCR>,
|
||||
<&gcc GCC_CE_BCR>;
|
||||
reset-names =
|
||||
"wcss_aon_reset",
|
||||
"wcss_reset",
|
||||
"ce_reset";
|
||||
|
||||
clocks =
|
||||
<&gcc GCC_WCSS_AHB_S_CLK>,
|
||||
<&gcc GCC_WCSS_ACMT_CLK>,
|
||||
<&gcc GCC_WCSS_AXI_M_CLK>;
|
||||
clock-names =
|
||||
"gcc_wcss_ahb_s_clk",
|
||||
"gcc_wcss_acmt_clk",
|
||||
"gcc_wcss_axi_m_clk";
|
||||
|
||||
// qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
|
||||
interrupts-extended =
|
||||
<&wcss_smp2p_in 8 IRQ_TYPE_NONE>,
|
||||
<&wcss_smp2p_in 9 IRQ_TYPE_NONE>,
|
||||
<&wcss_smp2p_in 12 IRQ_TYPE_NONE>,
|
||||
<&wcss_smp2p_in 11 IRQ_TYPE_NONE>;
|
||||
interrupt-names =
|
||||
"fatal",
|
||||
"ready",
|
||||
"spawn-ack",
|
||||
"stop-ack";
|
||||
|
||||
qcom,smem-states =
|
||||
<&wcss_smp2p_out 8>,
|
||||
<&wcss_smp2p_out 9>,
|
||||
<&wcss_smp2p_out 10>;
|
||||
qcom,smem-state-names =
|
||||
"shutdown",
|
||||
"stop",
|
||||
"spawn";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
// QCN6102 5G
|
||||
q6_wcss_pd2: pd-2 {
|
||||
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";
|
||||
|
||||
interrupts-extended =
|
||||
<&wcss_smp2p_in 16 IRQ_TYPE_NONE>,
|
||||
<&wcss_smp2p_in 17 IRQ_TYPE_NONE>,
|
||||
<&wcss_smp2p_in 20 IRQ_TYPE_NONE>,
|
||||
<&wcss_smp2p_in 19 IRQ_TYPE_NONE>;
|
||||
interrupt-names =
|
||||
"fatal",
|
||||
"ready",
|
||||
"spawn-ack",
|
||||
"stop-ack";
|
||||
|
||||
qcom,smem-states =
|
||||
<&wcss_smp2p_out 16>,
|
||||
<&wcss_smp2p_out 17>,
|
||||
<&wcss_smp2p_out 18>;
|
||||
qcom,smem-state-names =
|
||||
"shutdown",
|
||||
"stop",
|
||||
"spawn";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
// IPQ5018
|
||||
qcom,rproc = <&q6_wcss_pd1>;
|
||||
qcom,ath11k-calibration-variant = "Linksys-MX2000";
|
||||
qcom,ath11k-fw-memory-mode = <2>;
|
||||
qcom,bdf-addr = <0x4c400000>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi1 {
|
||||
// QCN6102 5G
|
||||
qcom,rproc = <&q6_wcss_pd2>;
|
||||
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
|
||||
qcom,ath11k-calibration-variant = "Linksys-MX2000";
|
||||
qcom,ath11k-fw-memory-mode = <2>;
|
||||
qcom,bdf-addr = <0x4d100000>;
|
||||
qcom,m3-dump-addr = <0x4df00000>;
|
||||
|
||||
status = "okay";
|
||||
};
|
@ -0,0 +1,240 @@
|
||||
/dts-v1/;
|
||||
|
||||
#include "ipq5018.dtsi"
|
||||
#include "ipq5018-mx-base.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Linksys MX5500";
|
||||
compatible = "linksys,mx5500", "qcom,ipq5018";
|
||||
};
|
||||
|
||||
/*
|
||||
* ===============================================================
|
||||
* _______________________ _______________________
|
||||
* | IPQ5018 | | QCA8337 |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* | | MAC0 |---| GE Phy | | | | Phy0 |---| MAC1 | |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC6 | |
|
||||
* | +------+ +--------+ | | +--------+ +------+ |
|
||||
* |_______________________| |_______________________|
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
|
||||
&switch {
|
||||
status = "okay";
|
||||
|
||||
switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;
|
||||
|
||||
qcom,port_phyinfo {
|
||||
// MAC0 -> GE Phy -> QCA8337 Phy4
|
||||
port@0 {
|
||||
port_id = <1>;
|
||||
mdiobus = <&mdio0>;
|
||||
phy_address = <7>;
|
||||
};
|
||||
|
||||
// MAC1 ---SGMII---> QCA8337 SerDes
|
||||
port@1 {
|
||||
port_id = <2>;
|
||||
forced-speed = <1000>;
|
||||
forced-duplex = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// MAC1 ---SGMII---> QCA8337 SerDes
|
||||
&dp2 {
|
||||
status = "okay";
|
||||
phy-mode = "sgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* IPQ5018 GE Phy -> Not connected
|
||||
* needs to be enabled for QSDK to identify the IPQ5018 dummy switch
|
||||
*/
|
||||
&ge_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdio1 {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&mdio1_pins>;
|
||||
pinctrl-names = "default";
|
||||
reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;
|
||||
|
||||
// QCA8337 Phy0 not connected
|
||||
qca8337_0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy1 -> WAN
|
||||
qca8337_1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy2 -> LAN1
|
||||
qca8337_2: ethernet-phy@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy3 -> LAN2
|
||||
qca8337_3: ethernet-phy@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
|
||||
// QCA8337 Phy4 -> LAN3
|
||||
qca8337_4: ethernet-phy@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
|
||||
// QCA8337 switch
|
||||
switch1: ethernet-switch@17 {
|
||||
compatible = "qca,qca8337";
|
||||
reg = <17>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "wan";
|
||||
phy-handle = <&qca8337_1>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
phy-handle = <&qca8337_2>;
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "lan2";
|
||||
phy-handle = <&qca8337_3>;
|
||||
};
|
||||
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
label = "lan1";
|
||||
phy-handle = <&qca8337_4>;
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
label = "cpu";
|
||||
phy-mode = "sgmii";
|
||||
ethernet = <&dp2>;
|
||||
qca,sgmii-enable-pll;
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie0_phy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
status = "okay";
|
||||
|
||||
perst-gpios = <&tlmm 15 GPIO_ACTIVE_LOW>;
|
||||
|
||||
bridge@0,0 {
|
||||
reg = <0x00000000 0 0 0 0>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
wifi@1,0 {
|
||||
status = "okay";
|
||||
|
||||
/* QCN9074: ath11k lacks DT compatible for PCI cards */
|
||||
compatible = "pci17cb,1104";
|
||||
reg = <0x00010000 0 0 0 0>;
|
||||
|
||||
qcom,ath11k-calibration-variant = "Linksys-MX5500";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&q6v5_wcss {
|
||||
status = "okay";
|
||||
|
||||
memory-region = <&q6_mem_regions>;
|
||||
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt",
|
||||
"ath11k/IPQ5018/hw1.0/m3_fw.mdt";
|
||||
|
||||
// IPQ5018
|
||||
q6_wcss_pd1: pd-1 {
|
||||
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";
|
||||
|
||||
resets =
|
||||
<&gcc GCC_WCSSAON_RESET>,
|
||||
<&gcc GCC_WCSS_BCR>,
|
||||
<&gcc GCC_CE_BCR>;
|
||||
reset-names =
|
||||
"wcss_aon_reset",
|
||||
"wcss_reset",
|
||||
"ce_reset";
|
||||
|
||||
clocks =
|
||||
<&gcc GCC_WCSS_AHB_S_CLK>,
|
||||
<&gcc GCC_WCSS_ACMT_CLK>,
|
||||
<&gcc GCC_WCSS_AXI_M_CLK>;
|
||||
clock-names =
|
||||
"gcc_wcss_ahb_s_clk",
|
||||
"gcc_wcss_acmt_clk",
|
||||
"gcc_wcss_axi_m_clk";
|
||||
|
||||
interrupts-extended =
|
||||
<&wcss_smp2p_in 8 0>,
|
||||
<&wcss_smp2p_in 9 0>,
|
||||
<&wcss_smp2p_in 12 0>,
|
||||
<&wcss_smp2p_in 11 0>;
|
||||
interrupt-names =
|
||||
"fatal",
|
||||
"ready",
|
||||
"spawn-ack",
|
||||
"stop-ack";
|
||||
|
||||
qcom,smem-states =
|
||||
<&wcss_smp2p_out 8>,
|
||||
<&wcss_smp2p_out 9>,
|
||||
<&wcss_smp2p_out 10>;
|
||||
qcom,smem-state-names =
|
||||
"shutdown",
|
||||
"stop",
|
||||
"spawn";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
// IPQ5018
|
||||
qcom,rproc = <&q6_wcss_pd1>;
|
||||
qcom,ath11k-calibration-variant = "Linksys-MX5500";
|
||||
qcom,ath11k-fw-memory-mode = <2>;
|
||||
qcom,bdf-addr = <0x4c400000>;
|
||||
|
||||
status = "okay";
|
||||
};
|
31
target/linux/qualcommax/image/ipq50xx.mk
Normal file
31
target/linux/qualcommax/image/ipq50xx.mk
Normal file
@ -0,0 +1,31 @@
|
||||
define Device/linksys_ipq50xx_mx_base
|
||||
$(call Device/FitImageLzma)
|
||||
DEVICE_VENDOR := Linksys
|
||||
BLOCKSIZE := 128k
|
||||
PAGESIZE := 2048
|
||||
KERNEL_SIZE := 8192k
|
||||
IMAGE_SIZE := 83968k
|
||||
NAND_SIZE := 256m
|
||||
SOC := ipq5018
|
||||
IMAGES += factory.bin
|
||||
IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=$$$$(DEVICE_MODEL)
|
||||
endef
|
||||
|
||||
define Device/linksys_mx2000
|
||||
$(call Device/linksys_ipq50xx_mx_base)
|
||||
DEVICE_MODEL := MX2000
|
||||
DEVICE_DTS_CONFIG := config@mp03.5-c1
|
||||
DEVICE_PACKAGES := ath11k-firmware-qcn6122 \
|
||||
ipq-wifi-linksys_mx2000
|
||||
endef
|
||||
TARGET_DEVICES += linksys_mx2000
|
||||
|
||||
define Device/linksys_mx5500
|
||||
$(call Device/linksys_ipq50xx_mx_base)
|
||||
DEVICE_MODEL := MX5500
|
||||
DEVICE_DTS_CONFIG := config@mp03.1
|
||||
DEVICE_PACKAGES := kmod-ath11k-pci \
|
||||
ath11k-firmware-qcn9074 \
|
||||
ipq-wifi-linksys_mx5500
|
||||
endef
|
||||
TARGET_DEVICES += linksys_mx5500
|
@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions/uci-defaults.sh
|
||||
. /lib/functions/system.sh
|
||||
|
||||
ipq50xx_setup_interfaces()
|
||||
{
|
||||
local board="$1"
|
||||
case $board in
|
||||
linksys,mx2000|\
|
||||
linksys,mx5500)
|
||||
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
ipq50xx_setup_macs()
|
||||
{
|
||||
local board="$1"
|
||||
local lan_mac=""
|
||||
local wan_mac=""
|
||||
local label_mac=""
|
||||
|
||||
case "$board" in
|
||||
linksys,mx2000|\
|
||||
linksys,mx5500)
|
||||
label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
|
||||
lan_mac=$label_mac
|
||||
wan_mac=$label_mac
|
||||
ucidef_set_network_device_mac eth0 $label_mac
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
|
||||
[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
|
||||
[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
|
||||
}
|
||||
|
||||
board_config_update
|
||||
board=$(board_name)
|
||||
ipq50xx_setup_interfaces $board
|
||||
ipq50xx_setup_macs $board
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -e /lib/firmware/$FIRMWARE ] && exit 0
|
||||
|
||||
. /lib/functions/caldata.sh
|
||||
|
||||
board=$(board_name)
|
||||
|
||||
case "$FIRMWARE" in
|
||||
"ath11k/IPQ5018/hw1.0/cal-ahb-c000000.wifi.bin")
|
||||
case "$board" in
|
||||
linksys,mx2000|\
|
||||
linksys,mx5500)
|
||||
caldata_extract "0:ART" 0x1000 0x20000
|
||||
label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
|
||||
ath11k_patch_mac $(macaddr_add $label_mac 1) 0
|
||||
ath11k_remove_regdomain
|
||||
ath11k_set_macflag
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"ath11k/QCN6122/hw1.0/cal-ahb-b00a040.wifi1.bin")
|
||||
case "$board" in
|
||||
linksys,mx2000)
|
||||
caldata_extract "0:ART" 0x26800 0x20000
|
||||
label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
|
||||
ath11k_patch_mac $(macaddr_add $label_mac 2) 0
|
||||
ath11k_remove_regdomain
|
||||
ath11k_set_macflag
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin")
|
||||
case "$board" in
|
||||
linksys,mx5500)
|
||||
caldata_extract "0:ART" 0x26800 0x20000
|
||||
label_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
|
||||
ath11k_patch_mac $(macaddr_add $label_mac 2) 0
|
||||
ath11k_remove_regdomain
|
||||
ath11k_set_macflag
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
12
target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
Executable file
12
target/linux/qualcommax/ipq50xx/base-files/etc/init.d/bootcount
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
|
||||
boot() {
|
||||
case $(board_name) in
|
||||
linksys,mx2000|\
|
||||
linksys,mx5500)
|
||||
mtd resetbc s_env || true
|
||||
;;
|
||||
esac
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
PART_NAME=firmware
|
||||
REQUIRE_IMAGE_METADATA=1
|
||||
|
||||
RAMFS_COPY_BIN='fw_printenv fw_setenv head'
|
||||
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
|
||||
|
||||
remove_oem_ubi_volume() {
|
||||
local oem_volume_name="$1"
|
||||
local oem_ubivol
|
||||
local mtdnum
|
||||
local ubidev
|
||||
|
||||
mtdnum=$(find_mtd_index "$CI_UBIPART")
|
||||
if [ ! "$mtdnum" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
ubidev=$(nand_find_ubi "$CI_UBIPART")
|
||||
if [ ! "$ubidev" ]; then
|
||||
ubiattach --mtdn="$mtdnum"
|
||||
ubidev=$(nand_find_ubi "$CI_UBIPART")
|
||||
fi
|
||||
|
||||
if [ "$ubidev" ]; then
|
||||
oem_ubivol=$(nand_find_volume "$ubidev" "$oem_volume_name")
|
||||
[ "$oem_ubivol" ] && ubirmvol "/dev/$ubidev" --name="$oem_volume_name"
|
||||
fi
|
||||
}
|
||||
|
||||
linksys_mx_do_upgrade() {
|
||||
local setenv_script="/tmp/fw_env_upgrade"
|
||||
|
||||
CI_UBIPART="rootfs"
|
||||
boot_part="$(fw_printenv -n boot_part)"
|
||||
if [ -n "$UPGRADE_OPT_USE_CURR_PART" ]; then
|
||||
if [ "$boot_part" -eq "2" ]; then
|
||||
CI_KERNPART="alt_kernel"
|
||||
CI_UBIPART="alt_rootfs"
|
||||
fi
|
||||
else
|
||||
if [ "$boot_part" -eq "1" ]; then
|
||||
echo "boot_part 2" >> $setenv_script
|
||||
CI_KERNPART="alt_kernel"
|
||||
CI_UBIPART="alt_rootfs"
|
||||
else
|
||||
echo "boot_part 1" >> $setenv_script
|
||||
fi
|
||||
fi
|
||||
|
||||
boot_part_ready="$(fw_printenv -n boot_part_ready)"
|
||||
if [ "$boot_part_ready" -ne "3" ]; then
|
||||
echo "boot_part_ready 3" >> $setenv_script
|
||||
fi
|
||||
|
||||
auto_recovery="$(fw_printenv -n auto_recovery)"
|
||||
if [ "$auto_recovery" != "yes" ]; then
|
||||
echo "auto_recovery yes" >> $setenv_script
|
||||
fi
|
||||
|
||||
if [ -f "$setenv_script" ]; then
|
||||
fw_setenv -s $setenv_script || {
|
||||
echo "failed to update U-Boot environment"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
nand_do_upgrade "$1"
|
||||
}
|
||||
|
||||
platform_check_image() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
platform_do_upgrade() {
|
||||
case "$(board_name)" in
|
||||
linksys,mx2000|\
|
||||
linksys,mx5500)
|
||||
remove_oem_ubi_volume rootfs
|
||||
linksys_mx_do_upgrade "$1"
|
||||
;;
|
||||
*)
|
||||
default_do_upgrade "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
26
target/linux/qualcommax/ipq50xx/config-default
Normal file
26
target/linux/qualcommax/ipq50xx/config-default
Normal file
@ -0,0 +1,26 @@
|
||||
CONFIG_QCOM_APM=y
|
||||
CONFIG_IPQ_GCC_5018=y
|
||||
CONFIG_PINCTRL_IPQ5018=y
|
||||
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_SPI_QPIC_SNAND=y
|
||||
|
||||
CONFIG_IPQ_CMN_PLL=y
|
||||
CONFIG_IPQ5018_PHY=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_DSA_QCA8K=y
|
||||
CONFIG_NET_DSA_TAG_QCA=y
|
||||
CONFIG_QCA83XX_PHY=y
|
||||
|
||||
CONFIG_QCOM_Q6V5_MPD=y
|
||||
CONFIG_QCOM_QMI_HELPERS=y
|
||||
|
||||
CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP=y
|
||||
CONFIG_PCIE_QCOM=y
|
||||
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_IPQ=y
|
||||
CONFIG_LEDS_PWM=y
|
||||
|
||||
CONFIG_PHY_QCOM_M31_USB=y
|
||||
CONFIG_USB_DWC3_QCOM=y
|
7
target/linux/qualcommax/ipq50xx/target.mk
Normal file
7
target/linux/qualcommax/ipq50xx/target.mk
Normal file
@ -0,0 +1,7 @@
|
||||
SUBTARGET:=ipq50xx
|
||||
BOARDNAME:=Qualcomm Atheros IPQ50xx
|
||||
DEFAULT_PACKAGES += ath11k-firmware-ipq5018
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Qualcomm Atheros IPQ50xx based boards.
|
||||
endef
|
@ -0,0 +1,31 @@
|
||||
From 9cbaee8379e620f82112002f973adde19679df31 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Wed, 16 Aug 2023 18:14:00 +0200
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: add watchdog
|
||||
|
||||
Add the required DT node for watchdog operation.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230816161455.3310629-2-robimarko@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -181,6 +181,13 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ watchdog: watchdog@b017000 {
|
||||
+ compatible = "qcom,apss-wdt-ipq5018", "qcom,kpss-wdt";
|
||||
+ reg = <0x0b017000 0x40>;
|
||||
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
|
||||
+ clocks = <&sleep_clk>;
|
||||
+ };
|
||||
+
|
||||
timer@b120000 {
|
||||
compatible = "arm,armv7-timer-mem";
|
||||
reg = <0x0b120000 0x1000>;
|
@ -0,0 +1,41 @@
|
||||
From 92dab9ea5f389c12828283146c60054642453a91 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Wed, 16 Aug 2023 18:45:38 +0200
|
||||
Subject: [PATCH] dt-bindings: firmware: qcom,scm: support indicating SDI
|
||||
default state
|
||||
|
||||
IPQ5018 has SDI (Secure Debug Image) enabled by TZ by default, and that
|
||||
means that WDT being asserted or just trying to reboot will hang the board
|
||||
in the debug mode and only pulling the power and repowering will help.
|
||||
Some IPQ4019 boards like Google WiFI have it enabled as well.
|
||||
|
||||
So, lets add a boolean property to indicate that SDI is enabled by default
|
||||
and thus needs to be disabled by the kernel.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Acked-by: Mukesh Ojha <quic_mojha@quicinc.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Reviewed-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20230816164641.3371878-1-robimarko@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
|
||||
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
|
||||
@@ -89,6 +89,14 @@ properties:
|
||||
protocol to handle sleeping SCM calls.
|
||||
maxItems: 1
|
||||
|
||||
+ qcom,sdi-enabled:
|
||||
+ description:
|
||||
+ Indicates that the SDI (Secure Debug Image) has been enabled by TZ
|
||||
+ by default and it needs to be disabled.
|
||||
+ If not disabled WDT assertion or reboot will cause the board to hang
|
||||
+ in the debug mode.
|
||||
+ type: boolean
|
||||
+
|
||||
qcom,dload-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
@ -0,0 +1,83 @@
|
||||
From ff4aa3bc98258a240b9bbab53fd8d2fb8184c485 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Wed, 16 Aug 2023 18:45:39 +0200
|
||||
Subject: [PATCH] firmware: qcom_scm: disable SDI if required
|
||||
|
||||
IPQ5018 has SDI (Secure Debug Image) enabled by TZ by default, and that
|
||||
means that WDT being asserted or just trying to reboot will hang the board
|
||||
in the debug mode and only pulling the power and repowering will help.
|
||||
Some IPQ4019 boards like Google WiFI have it enabled as well.
|
||||
|
||||
Luckily, SDI can be disabled via an SCM call.
|
||||
|
||||
So, lets use the boolean DT property to identify boards that have SDI
|
||||
enabled by default and use the SCM call to disable SDI during SCM probe.
|
||||
It is important to disable it as soon as possible as we might have a WDT
|
||||
assertion at any time which would then leave the board in debug mode,
|
||||
thus disabling it during SCM removal is not enough.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Reviewed-by: Guru Das Srinagesh <quic_gurus@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230816164641.3371878-2-robimarko@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/firmware/qcom_scm.c | 30 ++++++++++++++++++++++++++++++
|
||||
drivers/firmware/qcom_scm.h | 1 +
|
||||
2 files changed, 31 insertions(+)
|
||||
|
||||
--- a/drivers/firmware/qcom_scm.c
|
||||
+++ b/drivers/firmware/qcom_scm.c
|
||||
@@ -410,6 +410,29 @@ int qcom_scm_set_remote_state(u32 state,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
|
||||
|
||||
+static int qcom_scm_disable_sdi(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct qcom_scm_desc desc = {
|
||||
+ .svc = QCOM_SCM_SVC_BOOT,
|
||||
+ .cmd = QCOM_SCM_BOOT_SDI_CONFIG,
|
||||
+ .args[0] = 1, /* Disable watchdog debug */
|
||||
+ .args[1] = 0, /* Disable SDI */
|
||||
+ .arginfo = QCOM_SCM_ARGS(2),
|
||||
+ .owner = ARM_SMCCC_OWNER_SIP,
|
||||
+ };
|
||||
+ struct qcom_scm_res res;
|
||||
+
|
||||
+ ret = qcom_scm_clk_enable();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ ret = qcom_scm_call(__scm->dev, &desc, &res);
|
||||
+
|
||||
+ qcom_scm_clk_disable();
|
||||
+
|
||||
+ return ret ? : res.result[0];
|
||||
+}
|
||||
+
|
||||
static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
|
||||
{
|
||||
struct qcom_scm_desc desc = {
|
||||
@@ -1473,6 +1496,13 @@ static int qcom_scm_probe(struct platfor
|
||||
|
||||
__get_convention();
|
||||
|
||||
+
|
||||
+ /*
|
||||
+ * Disable SDI if indicated by DT that it is enabled by default.
|
||||
+ */
|
||||
+ if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
|
||||
+ qcom_scm_disable_sdi();
|
||||
+
|
||||
/*
|
||||
* If requested enable "download mode", from this point on warmboot
|
||||
* will cause the boot stages to enter download mode, unless
|
||||
--- a/drivers/firmware/qcom_scm.h
|
||||
+++ b/drivers/firmware/qcom_scm.h
|
||||
@@ -80,6 +80,7 @@ extern int scm_legacy_call(struct device
|
||||
#define QCOM_SCM_SVC_BOOT 0x01
|
||||
#define QCOM_SCM_BOOT_SET_ADDR 0x01
|
||||
#define QCOM_SCM_BOOT_TERMINATE_PC 0x02
|
||||
+#define QCOM_SCM_BOOT_SDI_CONFIG 0x09
|
||||
#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10
|
||||
#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11
|
||||
#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a
|
@ -0,0 +1,25 @@
|
||||
From f6aa7386bc40b552eea8ec1b1d2168afe3b31110 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Wed, 16 Aug 2023 18:45:40 +0200
|
||||
Subject: [PATCH] dt-bindings: firmware: qcom,scm: document IPQ5018 compatible
|
||||
|
||||
It seems that IPQ5018 compatible was never documented in the bindings.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230816164641.3371878-3-robimarko@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
|
||||
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
|
||||
@@ -24,6 +24,7 @@ properties:
|
||||
- qcom,scm-apq8064
|
||||
- qcom,scm-apq8084
|
||||
- qcom,scm-ipq4019
|
||||
+ - qcom,scm-ipq5018
|
||||
- qcom,scm-ipq5332
|
||||
- qcom,scm-ipq6018
|
||||
- qcom,scm-ipq806x
|
@ -0,0 +1,26 @@
|
||||
From 79796e87215db9587d6c66ec6f6781e091bc6464 Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Wed, 16 Aug 2023 18:45:41 +0200
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: indicate that SDI should be
|
||||
disabled
|
||||
|
||||
Now that SCM has support for indicating that SDI has been enabled by
|
||||
default, lets set the property so SCM disables it during probing.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20230816164641.3371878-4-robimarko@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -57,6 +57,7 @@
|
||||
firmware {
|
||||
scm {
|
||||
compatible = "qcom,scm-ipq5018", "qcom,scm";
|
||||
+ qcom,sdi-enabled;
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 1852dfaacd3f4358bbfca134b63a02bbb30c1136 Mon Sep 17 00:00:00 2001
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Date: Mon, 4 Sep 2023 12:06:32 +0530
|
||||
Subject: [PATCH] dt-bindings: phy: qcom,m31: Add IPQ5018 compatible
|
||||
|
||||
IPQ5332 qcom,m31 phy driver can support IPQ5018.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230904063635.24975-2-quic_nsekar@quicinc.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
.../devicetree/bindings/phy/qcom,ipq5332-usb-hsphy.yaml | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/phy/qcom,ipq5332-usb-hsphy.yaml
|
||||
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq5332-usb-hsphy.yaml
|
||||
@@ -17,7 +17,9 @@ description:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- - const: qcom,ipq5332-usb-hsphy
|
||||
+ - enum:
|
||||
+ - qcom,ipq5018-usb-hsphy
|
||||
+ - qcom,ipq5332-usb-hsphy
|
||||
|
||||
"#phy-cells":
|
||||
const: 0
|
@ -0,0 +1,89 @@
|
||||
From 68320e35f8cb1987b4ad34347fc7033832da99e3 Mon Sep 17 00:00:00 2001
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Date: Mon, 4 Sep 2023 12:06:33 +0530
|
||||
Subject: [PATCH] phy: qcom-m31: Add compatible, phy init sequence for IPQ5018
|
||||
|
||||
Add phy init sequence and compatible string for IPQ5018
|
||||
chipset.
|
||||
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230904063635.24975-3-quic_nsekar@quicinc.com
|
||||
Signed-off-by: Vinod Koul <vkoul@kernel.org>
|
||||
---
|
||||
drivers/phy/qualcomm/phy-qcom-m31.c | 51 +++++++++++++++++++++++++++++
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
--- a/drivers/phy/qualcomm/phy-qcom-m31.c
|
||||
+++ b/drivers/phy/qualcomm/phy-qcom-m31.c
|
||||
@@ -82,6 +82,50 @@ struct m31_priv_data {
|
||||
unsigned int nregs;
|
||||
};
|
||||
|
||||
+static const struct m31_phy_regs m31_ipq5018_regs[] = {
|
||||
+ {
|
||||
+ .off = USB_PHY_CFG0,
|
||||
+ .val = UTMI_PHY_OVERRIDE_EN
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_UTMI_CTRL5,
|
||||
+ .val = POR_EN,
|
||||
+ .delay = 15
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_FSEL_SEL,
|
||||
+ .val = FREQ_SEL
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_HS_PHY_CTRL_COMMON0,
|
||||
+ .val = COMMONONN | FSEL | RETENABLEN
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_REFCLK_CTRL,
|
||||
+ .val = CLKCORE
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_UTMI_CTRL5,
|
||||
+ .val = POR_EN
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_HS_PHY_CTRL2,
|
||||
+ .val = USB2_SUSPEND_N_SEL | USB2_SUSPEND_N | USB2_UTMI_CLK_EN
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_UTMI_CTRL5,
|
||||
+ .val = 0x0
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_HS_PHY_CTRL2,
|
||||
+ .val = USB2_SUSPEND_N | USB2_UTMI_CLK_EN
|
||||
+ },
|
||||
+ {
|
||||
+ .off = USB_PHY_CFG0,
|
||||
+ .val = 0x0
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct m31_phy_regs m31_ipq5332_regs[] = {
|
||||
{
|
||||
USB_PHY_CFG0,
|
||||
@@ -267,6 +311,12 @@ static int m31usb_phy_probe(struct platf
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
+static const struct m31_priv_data m31_ipq5018_data = {
|
||||
+ .ulpi_mode = false,
|
||||
+ .regs = m31_ipq5018_regs,
|
||||
+ .nregs = ARRAY_SIZE(m31_ipq5018_regs),
|
||||
+};
|
||||
+
|
||||
static const struct m31_priv_data m31_ipq5332_data = {
|
||||
.ulpi_mode = false,
|
||||
.regs = m31_ipq5332_regs,
|
||||
@@ -274,6 +324,7 @@ static const struct m31_priv_data m31_ip
|
||||
};
|
||||
|
||||
static const struct of_device_id m31usb_phy_id_table[] = {
|
||||
+ { .compatible = "qcom,ipq5018-usb-hsphy", .data = &m31_ipq5018_data },
|
||||
{ .compatible = "qcom,ipq5332-usb-hsphy", .data = &m31_ipq5332_data },
|
||||
{ },
|
||||
};
|
@ -0,0 +1,41 @@
|
||||
From 3865a64284cc4845c61cf3dc6c7246349d80cc49 Mon Sep 17 00:00:00 2001
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Date: Thu, 31 Aug 2023 08:35:03 +0530
|
||||
Subject: [PATCH] dt-bindings: usb: dwc3: Add IPQ5018 compatible
|
||||
|
||||
Document the IPQ5018 dwc3 compatible.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230831030503.17100-1-quic_nsekar@quicinc.com
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
|
||||
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
|
||||
@@ -14,6 +14,7 @@ properties:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,ipq4019-dwc3
|
||||
+ - qcom,ipq5018-dwc3
|
||||
- qcom,ipq5332-dwc3
|
||||
- qcom,ipq6018-dwc3
|
||||
- qcom,ipq8064-dwc3
|
||||
@@ -238,6 +239,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
+ - qcom,ipq5018-dwc3
|
||||
- qcom,ipq5332-dwc3
|
||||
- qcom,msm8994-dwc3
|
||||
- qcom,qcs404-dwc3
|
||||
@@ -411,6 +413,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
+ - qcom,ipq5018-dwc3
|
||||
- qcom,ipq5332-dwc3
|
||||
- qcom,sdm660-dwc3
|
||||
then:
|
@ -0,0 +1,86 @@
|
||||
From e7166f2774aafefd29ff26ffbbb7f6d40ac8ea1c Mon Sep 17 00:00:00 2001
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Date: Mon, 4 Sep 2023 12:06:34 +0530
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add USB related nodes
|
||||
|
||||
Add USB phy and controller nodes.
|
||||
|
||||
Co-developed-by: Amandeep Singh <quic_amansing@quicinc.com>
|
||||
Signed-off-by: Amandeep Singh <quic_amansing@quicinc.com>
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230904063635.24975-4-quic_nsekar@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 54 +++++++++++++++++++++++++++
|
||||
1 file changed, 54 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -94,6 +94,19 @@
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0 0xffffffff>;
|
||||
|
||||
+ usbphy0: phy@5b000 {
|
||||
+ compatible = "qcom,ipq5018-usb-hsphy";
|
||||
+ reg = <0x0005b000 0x120>;
|
||||
+
|
||||
+ clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>;
|
||||
+
|
||||
+ resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
tlmm: pinctrl@1000000 {
|
||||
compatible = "qcom,ipq5018-tlmm";
|
||||
reg = <0x01000000 0x300000>;
|
||||
@@ -156,6 +169,47 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ usb: usb@8af8800 {
|
||||
+ compatible = "qcom,ipq5018-dwc3", "qcom,dwc3";
|
||||
+ reg = <0x08af8800 0x400>;
|
||||
+
|
||||
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "hs_phy_irq";
|
||||
+
|
||||
+ clocks = <&gcc GCC_USB0_MASTER_CLK>,
|
||||
+ <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
|
||||
+ <&gcc GCC_USB0_SLEEP_CLK>,
|
||||
+ <&gcc GCC_USB0_MOCK_UTMI_CLK>;
|
||||
+ clock-names = "core",
|
||||
+ "iface",
|
||||
+ "sleep",
|
||||
+ "mock_utmi";
|
||||
+
|
||||
+ resets = <&gcc GCC_USB0_BCR>;
|
||||
+
|
||||
+ qcom,select-utmi-as-pipe-clk;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ ranges;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ usb_dwc: usb@8a00000 {
|
||||
+ compatible = "snps,dwc3";
|
||||
+ reg = <0x08a00000 0xe000>;
|
||||
+ clocks = <&gcc GCC_USB0_MOCK_UTMI_CLK>;
|
||||
+ clock-names = "ref";
|
||||
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ phy-names = "usb2-phy";
|
||||
+ phys = <&usbphy0>;
|
||||
+ tx-fifo-resize;
|
||||
+ snps,is-utmi-l1-suspend;
|
||||
+ snps,hird-threshold = /bits/ 8 <0x0>;
|
||||
+ snps,dis_u2_susphy_quirk;
|
||||
+ snps,dis_u3_susphy_quirk;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
intc: interrupt-controller@b000000 {
|
||||
compatible = "qcom,msm-qgic2";
|
||||
reg = <0x0b000000 0x1000>, /* GICD */
|
@ -0,0 +1,56 @@
|
||||
From a1f42e08f0f04b72a6597f080db4bfbb3737910c Mon Sep 17 00:00:00 2001
|
||||
From: Robert Marko <robimarko@gmail.com>
|
||||
Date: Wed, 4 Oct 2023 21:12:30 +0200
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: add QUP1 SPI controller
|
||||
|
||||
Add the required BAM and QUP nodes for the QUP1 SPI controller on IPQ5018.
|
||||
|
||||
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||||
Reviewed-by: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20231004191303.331055-1-robimarko@gmail.com
|
||||
[bjorn: Padded address to 8 digits, fixed node sort order]
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -159,6 +159,16 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ blsp_dma: dma-controller@7884000 {
|
||||
+ compatible = "qcom,bam-v1.7.0";
|
||||
+ reg = <0x07884000 0x1d000>;
|
||||
+ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>;
|
||||
+ clock-names = "bam_clk";
|
||||
+ #dma-cells = <1>;
|
||||
+ qcom,ee = <0>;
|
||||
+ };
|
||||
+
|
||||
blsp1_uart1: serial@78af000 {
|
||||
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
|
||||
reg = <0x078af000 0x200>;
|
||||
@@ -169,6 +179,20 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ blsp1_spi1: spi@78b5000 {
|
||||
+ compatible = "qcom,spi-qup-v2.2.1";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0x078b5000 0x600>;
|
||||
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>,
|
||||
+ <&gcc GCC_BLSP1_AHB_CLK>;
|
||||
+ clock-names = "core", "iface";
|
||||
+ dmas = <&blsp_dma 4>, <&blsp_dma 5>;
|
||||
+ dma-names = "tx", "rx";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
usb: usb@8af8800 {
|
||||
compatible = "qcom,ipq5018-dwc3", "qcom,dwc3";
|
||||
reg = <0x08af8800 0x400>;
|
@ -0,0 +1,25 @@
|
||||
From 4d45d56e17348c6b6bb2bce126a4a5ea97b19900 Mon Sep 17 00:00:00 2001
|
||||
From: Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com>
|
||||
Date: Mon, 25 Sep 2023 15:58:24 +0530
|
||||
Subject: [PATCH] dt-bindings: clock: qcom,a53pll: add IPQ5018 compatible
|
||||
|
||||
Add IPQ5018 compatible to A53 PLL bindings.
|
||||
|
||||
Signed-off-by: Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230925102826.405446-2-quic_gokulsri@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
|
||||
+++ b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
|
||||
@@ -16,6 +16,7 @@ description:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
+ - qcom,ipq5018-a53pll
|
||||
- qcom,ipq5332-a53pll
|
||||
- qcom,ipq6018-a53pll
|
||||
- qcom,ipq8074-a53pll
|
@ -0,0 +1,62 @@
|
||||
From 50492f929486c044b43cb3e2c0e040aa9b61ea2b Mon Sep 17 00:00:00 2001
|
||||
From: Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com>
|
||||
Date: Mon, 25 Sep 2023 15:58:25 +0530
|
||||
Subject: [PATCH] clk: qcom: apss-ipq-pll: add support for IPQ5018
|
||||
|
||||
IPQ5018 APSS PLL is of type Stromer. Reuse Stromer Plus PLL offsets,
|
||||
add configuration values and the compatible.
|
||||
|
||||
Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Signed-off-by: Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com>
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230925102826.405446-3-quic_gokulsri@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/apss-ipq-pll.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
--- a/drivers/clk/qcom/apss-ipq-pll.c
|
||||
+++ b/drivers/clk/qcom/apss-ipq-pll.c
|
||||
@@ -73,6 +73,20 @@ static struct clk_alpha_pll ipq_pll_stro
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct alpha_pll_config ipq5018_pll_config = {
|
||||
+ .l = 0x32,
|
||||
+ .config_ctl_val = 0x4001075b,
|
||||
+ .config_ctl_hi_val = 0x304,
|
||||
+ .main_output_mask = BIT(0),
|
||||
+ .aux_output_mask = BIT(1),
|
||||
+ .early_output_mask = BIT(3),
|
||||
+ .alpha_en_mask = BIT(24),
|
||||
+ .status_val = 0x3,
|
||||
+ .status_mask = GENMASK(10, 8),
|
||||
+ .lock_det = BIT(2),
|
||||
+ .test_ctl_hi_val = 0x00400003,
|
||||
+};
|
||||
+
|
||||
static const struct alpha_pll_config ipq5332_pll_config = {
|
||||
.l = 0x2d,
|
||||
.config_ctl_val = 0x4001075b,
|
||||
@@ -129,6 +143,12 @@ struct apss_pll_data {
|
||||
const struct alpha_pll_config *pll_config;
|
||||
};
|
||||
|
||||
+static const struct apss_pll_data ipq5018_pll_data = {
|
||||
+ .pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
|
||||
+ .pll = &ipq_pll_stromer_plus,
|
||||
+ .pll_config = &ipq5018_pll_config,
|
||||
+};
|
||||
+
|
||||
static struct apss_pll_data ipq5332_pll_data = {
|
||||
.pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
|
||||
.pll = &ipq_pll_stromer_plus,
|
||||
@@ -195,6 +215,7 @@ static int apss_ipq_pll_probe(struct pla
|
||||
}
|
||||
|
||||
static const struct of_device_id apss_ipq_pll_match_table[] = {
|
||||
+ { .compatible = "qcom,ipq5018-a53pll", .data = &ipq5018_pll_data },
|
||||
{ .compatible = "qcom,ipq5332-a53pll", .data = &ipq5332_pll_data },
|
||||
{ .compatible = "qcom,ipq6018-a53pll", .data = &ipq6018_pll_data },
|
||||
{ .compatible = "qcom,ipq8074-a53pll", .data = &ipq8074_pll_data },
|
@ -0,0 +1,98 @@
|
||||
From 3e4b53e04281ed3d9c7a4329c027097265c04d54 Mon Sep 17 00:00:00 2001
|
||||
From: Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com>
|
||||
Date: Mon, 25 Sep 2023 15:58:26 +0530
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: enable the CPUFreq support
|
||||
|
||||
Add the APCS, A53 PLL, cpu-opp-table nodes to set
|
||||
the CPU frequency at 800MHz (idle) or 1.008GHz.
|
||||
|
||||
Co-developed-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Signed-off-by: Gokul Sriram Palanisamy <quic_gokulsri@quicinc.com>
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20230925102826.405446-4-quic_gokulsri@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 40 +++++++++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -5,6 +5,7 @@
|
||||
* Copyright (c) 2023 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
+#include <dt-bindings/clock/qcom,apss-ipq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-ipq5018.h>
|
||||
#include <dt-bindings/reset/qcom,gcc-ipq5018.h>
|
||||
@@ -36,6 +37,8 @@
|
||||
reg = <0x0>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_0>;
|
||||
+ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
|
||||
+ operating-points-v2 = <&cpu_opp_table>;
|
||||
};
|
||||
|
||||
CPU1: cpu@1 {
|
||||
@@ -44,6 +47,8 @@
|
||||
reg = <0x1>;
|
||||
enable-method = "psci";
|
||||
next-level-cache = <&L2_0>;
|
||||
+ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
|
||||
+ operating-points-v2 = <&cpu_opp_table>;
|
||||
};
|
||||
|
||||
L2_0: l2-cache {
|
||||
@@ -54,6 +59,25 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ cpu_opp_table: opp-table-cpu {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ /*
|
||||
+ opp-800000000 {
|
||||
+ opp-hz = /bits/ 64 <800000000>;
|
||||
+ opp-microvolt = <1100000>;
|
||||
+ clock-latency-ns = <200000>;
|
||||
+ };
|
||||
+ */
|
||||
+
|
||||
+ opp-1008000000 {
|
||||
+ opp-hz = /bits/ 64 <1008000000>;
|
||||
+ opp-microvolt = <1100000>;
|
||||
+ clock-latency-ns = <200000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
firmware {
|
||||
scm {
|
||||
compatible = "qcom,scm-ipq5018", "qcom,scm";
|
||||
@@ -267,6 +291,24 @@
|
||||
clocks = <&sleep_clk>;
|
||||
};
|
||||
|
||||
+ apcs_glb: mailbox@b111000 {
|
||||
+ compatible = "qcom,ipq5018-apcs-apps-global",
|
||||
+ "qcom,ipq6018-apcs-apps-global";
|
||||
+ reg = <0x0b111000 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ clocks = <&a53pll>, <&xo_board_clk>, <&gcc GPLL0>;
|
||||
+ clock-names = "pll", "xo", "gpll0";
|
||||
+ #mbox-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ a53pll: clock@b116000 {
|
||||
+ compatible = "qcom,ipq5018-a53pll";
|
||||
+ reg = <0x0b116000 0x40>;
|
||||
+ #clock-cells = <0>;
|
||||
+ clocks = <&xo_board_clk>;
|
||||
+ clock-names = "xo";
|
||||
+ };
|
||||
+
|
||||
timer@b120000 {
|
||||
compatible = "arm,armv7-timer-mem";
|
||||
reg = <0x0b120000 0x1000>;
|
@ -0,0 +1,66 @@
|
||||
From a427dd16e61f3d145bc24f0ed09692fc25931250 Mon Sep 17 00:00:00 2001
|
||||
From: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com>
|
||||
Date: Wed, 25 Oct 2023 22:12:12 +0530
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: add few more reserved memory
|
||||
regions
|
||||
|
||||
Like all other IPQ SoCs, bootloader will collect the system RAM contents
|
||||
upon crash for the post morterm analysis. If we don't reserve the memory
|
||||
region used by bootloader, obviously linux will consume it and upon next
|
||||
boot on crash, bootloader will be loaded in the same region, which will
|
||||
lead to loose some of the data, sometimes we may miss out critical
|
||||
information. So lets reserve the region used by the bootloader.
|
||||
|
||||
Similarly SBL copies some data into the reserved region and it will be
|
||||
used in the crash scenario. So reserve 1MB for SBL as well.
|
||||
|
||||
While at it, enable the SMEM support along with TCSR mutex.
|
||||
|
||||
Signed-off-by: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com>
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20231025-ipq5018-misc-v1-1-7d14fde97fe7@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -106,6 +106,24 @@
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
+ bootloader@4a800000 {
|
||||
+ reg = <0x0 0x4a800000 0x0 0x200000>;
|
||||
+ no-map;
|
||||
+ };
|
||||
+
|
||||
+ sbl@4aa00000 {
|
||||
+ reg = <0x0 0x4aa00000 0x0 0x100000>;
|
||||
+ no-map;
|
||||
+ };
|
||||
+
|
||||
+ smem@4ab00000 {
|
||||
+ compatible = "qcom,smem";
|
||||
+ reg = <0x0 0x4ab00000 0x0 0x100000>;
|
||||
+ no-map;
|
||||
+
|
||||
+ hwlocks = <&tcsr_mutex 3>;
|
||||
+ };
|
||||
+
|
||||
tz_region: tz@4ac00000 {
|
||||
reg = <0x0 0x4ac00000 0x0 0x200000>;
|
||||
no-map;
|
||||
@@ -166,6 +184,12 @@
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
+ tcsr_mutex: hwlock@1905000 {
|
||||
+ compatible = "qcom,tcsr-mutex";
|
||||
+ reg = <0x01905000 0x20000>;
|
||||
+ #hwlock-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
sdhc_1: mmc@7804000 {
|
||||
compatible = "qcom,ipq5018-sdhci", "qcom,sdhci-msm-v5";
|
||||
reg = <0x7804000 0x1000>;
|
@ -0,0 +1,83 @@
|
||||
From: Gabor Juhos <j4g8y7@gmail.com>
|
||||
Subject: [PATCH] clk: qcom: apss-ipq-pll: use stromer ops for IPQ5018 to fix boot failure
|
||||
Date: Fri, 15 Mar 2024 17:16:41 +0100
|
||||
|
||||
Booting v6.8 results in a hang on various IPQ5018 based boards.
|
||||
Investigating the problem showed that the hang happens when the
|
||||
clk_alpha_pll_stromer_plus_set_rate() function tries to write
|
||||
into the PLL_MODE register of the APSS PLL.
|
||||
|
||||
Checking the downstream code revealed that it uses [1] stromer
|
||||
specific operations for IPQ5018, whereas in the current code
|
||||
the stromer plus specific operations are used.
|
||||
|
||||
The ops in the 'ipq_pll_stromer_plus' clock definition can't be
|
||||
changed since that is needed for IPQ5332, so add a new alpha pll
|
||||
clock declaration which uses the correct stromer ops and use this
|
||||
new clock for IPQ5018 to avoid the boot failure.
|
||||
|
||||
Also, change pll_type in 'ipq5018_pll_data' to
|
||||
CLK_ALPHA_PLL_TYPE_STROMER to better reflect that it is a Stromer
|
||||
PLL and change the apss_ipq_pll_probe() function accordingly.
|
||||
|
||||
1. https://git.codelinaro.org/clo/qsdk/oss/kernel/linux-ipq-5.4/-/blob/NHSS.QSDK.12.4/drivers/clk/qcom/apss-ipq5018.c#L67
|
||||
|
||||
Fixes: 50492f929486 ("clk: qcom: apss-ipq-pll: add support for IPQ5018")
|
||||
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
|
||||
---
|
||||
drivers/clk/qcom/apss-ipq-pll.c | 30 +++++++++++++++++++++++++++---
|
||||
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/clk/qcom/apss-ipq-pll.c
|
||||
+++ b/drivers/clk/qcom/apss-ipq-pll.c
|
||||
@@ -55,6 +55,29 @@ static struct clk_alpha_pll ipq_pll_huay
|
||||
},
|
||||
};
|
||||
|
||||
+static struct clk_alpha_pll ipq_pll_stromer = {
|
||||
+ .offset = 0x0,
|
||||
+ /*
|
||||
+ * Reuse CLK_ALPHA_PLL_TYPE_STROMER_PLUS register offsets.
|
||||
+ * Although this is a bit confusing, but the offset values
|
||||
+ * are correct nevertheless.
|
||||
+ */
|
||||
+ .regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS],
|
||||
+ .flags = SUPPORTS_DYNAMIC_UPDATE,
|
||||
+ .clkr = {
|
||||
+ .enable_reg = 0x0,
|
||||
+ .enable_mask = BIT(0),
|
||||
+ .hw.init = &(const struct clk_init_data) {
|
||||
+ .name = "a53pll",
|
||||
+ .parent_data = &(const struct clk_parent_data) {
|
||||
+ .fw_name = "xo",
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .ops = &clk_alpha_pll_stromer_ops,
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct clk_alpha_pll ipq_pll_stromer_plus = {
|
||||
.offset = 0x0,
|
||||
.regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS],
|
||||
@@ -144,8 +167,8 @@ struct apss_pll_data {
|
||||
};
|
||||
|
||||
static const struct apss_pll_data ipq5018_pll_data = {
|
||||
- .pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
|
||||
- .pll = &ipq_pll_stromer_plus,
|
||||
+ .pll_type = CLK_ALPHA_PLL_TYPE_STROMER,
|
||||
+ .pll = &ipq_pll_stromer,
|
||||
.pll_config = &ipq5018_pll_config,
|
||||
};
|
||||
|
||||
@@ -203,7 +226,8 @@ static int apss_ipq_pll_probe(struct pla
|
||||
|
||||
if (data->pll_type == CLK_ALPHA_PLL_TYPE_HUAYRA)
|
||||
clk_alpha_pll_configure(data->pll, regmap, data->pll_config);
|
||||
- else if (data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER_PLUS)
|
||||
+ else if (data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER ||
|
||||
+ data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER_PLUS)
|
||||
clk_stromer_pll_configure(data->pll, regmap, data->pll_config);
|
||||
|
||||
ret = devm_clk_register_regmap(dev, &data->pll->clkr);
|
@ -0,0 +1,32 @@
|
||||
From: Gabor Juhos <j4g8y7@gmail.com>
|
||||
Subject: [PATCH] clk: qcom: apss-ipq-pll: fix PLL rate for IPQ5018
|
||||
Date: Tue, 26 Mar 2024 14:34:11 +0100
|
||||
|
||||
According to ipq5018.dtsi, the maximum supported rate by the
|
||||
CPU is 1.008 GHz on the IPQ5018 platform, however the current
|
||||
configuration of the PLL results in 1.2 GHz rate.
|
||||
|
||||
Change the 'L' value in the PLL configuration to limit the
|
||||
rate to 1.008 GHz. The downstream kernel also uses the same
|
||||
value [1]. Also add a comment to indicate the desired
|
||||
frequency.
|
||||
|
||||
[1] https://git.codelinaro.org/clo/qsdk/oss/kernel/linux-ipq-5.4/-/blob/NHSS.QSDK.12.4/drivers/clk/qcom/apss-ipq5018.c?ref_type=heads#L151
|
||||
|
||||
Fixes: 50492f929486 ("clk: qcom: apss-ipq-pll: add support for IPQ5018")
|
||||
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
|
||||
---
|
||||
drivers/clk/qcom/apss-ipq-pll.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/clk/qcom/apss-ipq-pll.c
|
||||
+++ b/drivers/clk/qcom/apss-ipq-pll.c
|
||||
@@ -97,7 +97,7 @@ static struct clk_alpha_pll ipq_pll_stro
|
||||
};
|
||||
|
||||
static const struct alpha_pll_config ipq5018_pll_config = {
|
||||
- .l = 0x32,
|
||||
+ .l = 0x2a,
|
||||
.config_ctl_val = 0x4001075b,
|
||||
.config_ctl_hi_val = 0x304,
|
||||
.main_output_mask = BIT(0),
|
@ -0,0 +1,60 @@
|
||||
From: Devi Priya <quic_devipriy@quicinc.com>
|
||||
Date: Thu, 5 Oct 2023 21:35:48 +0530
|
||||
Subject: [PATCH] dt-bindings: pwm: add IPQ6018 binding
|
||||
|
||||
DT binding for the PWM block in Qualcomm IPQ6018 SoC.
|
||||
|
||||
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Co-developed-by: Baruch Siach <baruch.siach@siklu.com>
|
||||
Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
|
||||
Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
|
||||
---
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml
|
||||
@@ -0,0 +1,45 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/pwm/qcom,ipq6018-pwm.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Qualcomm IPQ6018 PWM controller
|
||||
+
|
||||
+maintainers:
|
||||
+ - Baruch Siach <baruch@tkos.co.il>
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: qcom,ipq6018-pwm
|
||||
+
|
||||
+ reg:
|
||||
+ description: Offset of PWM register in the TCSR block.
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ "#pwm-cells":
|
||||
+ const: 2
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - "#pwm-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
|
||||
+
|
||||
+ pwm: pwm@a010 {
|
||||
+ compatible = "qcom,ipq6018-pwm";
|
||||
+ reg = <0xa010 0x20>;
|
||||
+ clocks = <&gcc GCC_ADSS_PWM_CLK>;
|
||||
+ assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
|
||||
+ assigned-clock-rates = <100000000>;
|
||||
+ #pwm-cells = <2>;
|
||||
+ };
|
@ -0,0 +1,330 @@
|
||||
From: Devi Priya <quic_devipriy@quicinc.com>
|
||||
Date: Thu, 5 Oct 2023 21:35:47 +0530
|
||||
Subject: [PATCH] pwm: driver for qualcomm ipq6018 pwm block
|
||||
|
||||
Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
|
||||
driver from downstream Codeaurora kernel tree. Removed support for older
|
||||
(V1) variants because I have no access to that hardware.
|
||||
|
||||
Tested on IPQ6010 based hardware.
|
||||
|
||||
Co-developed-by: Baruch Siach <baruch.siach@siklu.com>
|
||||
Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
|
||||
Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
|
||||
---
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -282,6 +282,18 @@ config PWM_INTEL_LGM
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-intel-lgm.
|
||||
|
||||
+config PWM_IPQ
|
||||
+ tristate "IPQ PWM support"
|
||||
+ depends on ARCH_QCOM || COMPILE_TEST
|
||||
+ depends on HAVE_CLK && HAS_IOMEM
|
||||
+ help
|
||||
+ Generic PWM framework driver for IPQ PWM block which supports
|
||||
+ 4 pwm channels. Each of the these channels can be configured
|
||||
+ independent of each other.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-ipq.
|
||||
+
|
||||
config PWM_IQS620A
|
||||
tristate "Azoteq IQS620A PWM support"
|
||||
depends on MFD_IQS62X || COMPILE_TEST
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o
|
||||
obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o
|
||||
obj-$(CONFIG_PWM_IMX_TPM) += pwm-imx-tpm.o
|
||||
obj-$(CONFIG_PWM_INTEL_LGM) += pwm-intel-lgm.o
|
||||
+obj-$(CONFIG_PWM_IPQ) += pwm-ipq.o
|
||||
obj-$(CONFIG_PWM_IQS620A) += pwm-iqs620a.o
|
||||
obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
|
||||
obj-$(CONFIG_PWM_KEEMBAY) += pwm-keembay.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-ipq.c
|
||||
@@ -0,0 +1,282 @@
|
||||
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
|
||||
+/*
|
||||
+ * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/math64.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/units.h>
|
||||
+
|
||||
+/* The frequency range supported is 1 Hz to clock rate */
|
||||
+#define IPQ_PWM_MAX_PERIOD_NS ((u64)NSEC_PER_SEC)
|
||||
+
|
||||
+/*
|
||||
+ * The max value specified for each field is based on the number of bits
|
||||
+ * in the pwm control register for that field
|
||||
+ */
|
||||
+#define IPQ_PWM_MAX_DIV 0xFFFF
|
||||
+
|
||||
+/*
|
||||
+ * Two 32-bit registers for each PWM: REG0, and REG1.
|
||||
+ * Base offset for PWM #i is at 8 * #i.
|
||||
+ */
|
||||
+#define IPQ_PWM_REG0 0
|
||||
+#define IPQ_PWM_REG0_PWM_DIV GENMASK(15, 0)
|
||||
+#define IPQ_PWM_REG0_HI_DURATION GENMASK(31, 16)
|
||||
+
|
||||
+#define IPQ_PWM_REG1 4
|
||||
+#define IPQ_PWM_REG1_PRE_DIV GENMASK(15, 0)
|
||||
+/*
|
||||
+ * Enable bit is set to enable output toggling in pwm device.
|
||||
+ * Update bit is set to reflect the changed divider and high duration
|
||||
+ * values in register.
|
||||
+ */
|
||||
+#define IPQ_PWM_REG1_UPDATE BIT(30)
|
||||
+#define IPQ_PWM_REG1_ENABLE BIT(31)
|
||||
+
|
||||
+struct ipq_pwm_chip {
|
||||
+ struct pwm_chip chip;
|
||||
+ struct clk *clk;
|
||||
+ void __iomem *mem;
|
||||
+};
|
||||
+
|
||||
+static struct ipq_pwm_chip *ipq_pwm_from_chip(struct pwm_chip *chip)
|
||||
+{
|
||||
+ return container_of(chip, struct ipq_pwm_chip, chip);
|
||||
+}
|
||||
+
|
||||
+static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned int reg)
|
||||
+{
|
||||
+ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
|
||||
+ unsigned int off = 8 * pwm->hwpwm + reg;
|
||||
+
|
||||
+ return readl(ipq_chip->mem + off);
|
||||
+}
|
||||
+
|
||||
+static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned int reg,
|
||||
+ unsigned int val)
|
||||
+{
|
||||
+ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
|
||||
+ unsigned int off = 8 * pwm->hwpwm + reg;
|
||||
+
|
||||
+ writel(val, ipq_chip->mem + off);
|
||||
+}
|
||||
+
|
||||
+static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
|
||||
+ unsigned int pwm_div, unsigned long rate, u64 duty_ns,
|
||||
+ bool enable)
|
||||
+{
|
||||
+ unsigned long hi_dur;
|
||||
+ unsigned long val = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * high duration = pwm duty * (pwm div + 1)
|
||||
+ * pwm duty = duty_ns / period_ns
|
||||
+ */
|
||||
+ hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC);
|
||||
+
|
||||
+ val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
|
||||
+ FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
|
||||
+ ipq_pwm_reg_write(pwm, IPQ_PWM_REG0, val);
|
||||
+
|
||||
+ val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
|
||||
+ ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
|
||||
+
|
||||
+ /* PWM enable toggle needs a separate write to REG1 */
|
||||
+ val |= IPQ_PWM_REG1_UPDATE;
|
||||
+ if (enable)
|
||||
+ val |= IPQ_PWM_REG1_ENABLE;
|
||||
+ ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
|
||||
+}
|
||||
+
|
||||
+static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ const struct pwm_state *state)
|
||||
+{
|
||||
+ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
|
||||
+ unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div;
|
||||
+ unsigned long rate = clk_get_rate(ipq_chip->clk);
|
||||
+ u64 period_ns, duty_ns, period_rate;
|
||||
+ u64 min_diff;
|
||||
+
|
||||
+ if (state->polarity != PWM_POLARITY_NORMAL)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (state->period < DIV64_U64_ROUND_UP(NSEC_PER_SEC, rate))
|
||||
+ return -ERANGE;
|
||||
+
|
||||
+ period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
|
||||
+ duty_ns = min(state->duty_cycle, period_ns);
|
||||
+
|
||||
+ /*
|
||||
+ * period_ns is 1G or less. As long as rate is less than 16 GHz,
|
||||
+ * period_rate does not overflow. Make that explicit.
|
||||
+ */
|
||||
+ if ((unsigned long long)rate > 16ULL * GIGA)
|
||||
+ return -EINVAL;
|
||||
+ period_rate = period_ns * rate;
|
||||
+ best_pre_div = IPQ_PWM_MAX_DIV;
|
||||
+ best_pwm_div = IPQ_PWM_MAX_DIV;
|
||||
+ /*
|
||||
+ * We don't need to consider pre_div values smaller than
|
||||
+ *
|
||||
+ * period_rate
|
||||
+ * pre_div_min := ------------------------------------
|
||||
+ * NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1)
|
||||
+ *
|
||||
+ * because pre_div = pre_div_min results in a better
|
||||
+ * approximation.
|
||||
+ */
|
||||
+ pre_div = div64_u64(period_rate,
|
||||
+ (u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1));
|
||||
+ min_diff = period_rate;
|
||||
+
|
||||
+ for (; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) {
|
||||
+ u64 remainder;
|
||||
+
|
||||
+ pwm_div = div64_u64_rem(period_rate,
|
||||
+ (u64)NSEC_PER_SEC * (pre_div + 1), &remainder);
|
||||
+ /* pwm_div is unsigned; the check below catches underflow */
|
||||
+ pwm_div--;
|
||||
+
|
||||
+ /*
|
||||
+ * Swapping values for pre_div and pwm_div produces the same
|
||||
+ * period length. So we can skip all settings with pre_div >
|
||||
+ * pwm_div which results in bigger constraints for selecting
|
||||
+ * the duty_cycle than with the two values swapped.
|
||||
+ */
|
||||
+ if (pre_div > pwm_div)
|
||||
+ break;
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure we can do 100% duty cycle where
|
||||
+ * hi_dur == pwm_div + 1
|
||||
+ */
|
||||
+ if (pwm_div > IPQ_PWM_MAX_DIV - 1)
|
||||
+ continue;
|
||||
+
|
||||
+ if (remainder < min_diff) {
|
||||
+ best_pre_div = pre_div;
|
||||
+ best_pwm_div = pwm_div;
|
||||
+ min_diff = remainder;
|
||||
+
|
||||
+ if (min_diff == 0) /* bingo */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* config divider values for the closest possible frequency */
|
||||
+ config_div_and_duty(pwm, best_pre_div, best_pwm_div,
|
||||
+ rate, duty_ns, state->enabled);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ struct pwm_state *state)
|
||||
+{
|
||||
+ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
|
||||
+ unsigned long rate = clk_get_rate(ipq_chip->clk);
|
||||
+ unsigned int pre_div, pwm_div, hi_dur;
|
||||
+ u64 effective_div, hi_div;
|
||||
+ u32 reg0, reg1;
|
||||
+
|
||||
+ reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG0);
|
||||
+ reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG1);
|
||||
+
|
||||
+ state->polarity = PWM_POLARITY_NORMAL;
|
||||
+ state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
|
||||
+
|
||||
+ pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
|
||||
+ hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
|
||||
+ pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
|
||||
+
|
||||
+ /* No overflow here, both pre_div and pwm_div <= 0xffff */
|
||||
+ effective_div = (u64)(pre_div + 1) * (pwm_div + 1);
|
||||
+ state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC, rate);
|
||||
+
|
||||
+ hi_div = hi_dur * (pre_div + 1);
|
||||
+ state->duty_cycle = DIV64_U64_ROUND_UP(hi_div * NSEC_PER_SEC, rate);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops ipq_pwm_ops = {
|
||||
+ .apply = ipq_pwm_apply,
|
||||
+ .get_state = ipq_pwm_get_state,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int ipq_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ipq_pwm_chip *pwm;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
|
||||
+ if (!pwm)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pwm);
|
||||
+
|
||||
+ pwm->mem = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(pwm->mem))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pwm->mem),
|
||||
+ "regs map failed");
|
||||
+
|
||||
+ pwm->clk = devm_clk_get(dev, NULL);
|
||||
+ if (IS_ERR(pwm->clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
|
||||
+ "failed to get clock");
|
||||
+
|
||||
+ ret = clk_prepare_enable(pwm->clk);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "clock enable failed");
|
||||
+
|
||||
+ pwm->chip.dev = dev;
|
||||
+ pwm->chip.ops = &ipq_pwm_ops;
|
||||
+ pwm->chip.npwm = 4;
|
||||
+
|
||||
+ ret = pwmchip_add(&pwm->chip);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err_probe(dev, ret, "pwmchip_add() failed\n");
|
||||
+ clk_disable_unprepare(pwm->clk);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int ipq_pwm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ipq_pwm_chip *pwm = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ pwmchip_remove(&pwm->chip);
|
||||
+ clk_disable_unprepare(pwm->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id pwm_ipq_dt_match[] = {
|
||||
+ { .compatible = "qcom,ipq6018-pwm", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match);
|
||||
+
|
||||
+static struct platform_driver ipq_pwm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "ipq-pwm",
|
||||
+ .of_match_table = pwm_ipq_dt_match,
|
||||
+ },
|
||||
+ .probe = ipq_pwm_probe,
|
||||
+ .remove = ipq_pwm_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(ipq_pwm_driver);
|
||||
+
|
||||
+MODULE_LICENSE("Dual BSD/GPL");
|
@ -0,0 +1,148 @@
|
||||
From: Devi Priya <quic_devipriy@quicinc.com>
|
||||
Subject: [PATCH] dt-bindings: mfd: qcom,tcsr: Add simple-mfd support for IPQ6018
|
||||
Date: Thu, 5 Oct 2023 21:35:49 +0530
|
||||
|
||||
Update the binding to include pwm as the child node to TCSR block and
|
||||
add simple-mfd support for IPQ6018.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
|
||||
---
|
||||
.../devicetree/bindings/mfd/qcom,tcsr.yaml | 112 +++++++++++++-----
|
||||
1 file changed, 81 insertions(+), 31 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
|
||||
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
|
||||
@@ -15,49 +15,101 @@ description:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
- items:
|
||||
- - enum:
|
||||
- - qcom,msm8976-tcsr
|
||||
- - qcom,msm8998-tcsr
|
||||
- - qcom,qcs404-tcsr
|
||||
- - qcom,sc7180-tcsr
|
||||
- - qcom,sc7280-tcsr
|
||||
- - qcom,sc8280xp-tcsr
|
||||
- - qcom,sdm630-tcsr
|
||||
- - qcom,sdm845-tcsr
|
||||
- - qcom,sdx55-tcsr
|
||||
- - qcom,sdx65-tcsr
|
||||
- - qcom,sm8150-tcsr
|
||||
- - qcom,sm8450-tcsr
|
||||
- - qcom,tcsr-apq8064
|
||||
- - qcom,tcsr-apq8084
|
||||
- - qcom,tcsr-ipq5332
|
||||
- - qcom,tcsr-ipq6018
|
||||
- - qcom,tcsr-ipq8064
|
||||
- - qcom,tcsr-ipq8074
|
||||
- - qcom,tcsr-ipq9574
|
||||
- - qcom,tcsr-mdm9615
|
||||
- - qcom,tcsr-msm8226
|
||||
- - qcom,tcsr-msm8660
|
||||
- - qcom,tcsr-msm8916
|
||||
- - qcom,tcsr-msm8953
|
||||
- - qcom,tcsr-msm8960
|
||||
- - qcom,tcsr-msm8974
|
||||
- - qcom,tcsr-msm8996
|
||||
- - const: syscon
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - qcom,msm8976-tcsr
|
||||
+ - qcom,msm8998-tcsr
|
||||
+ - qcom,qcs404-tcsr
|
||||
+ - qcom,sc7180-tcsr
|
||||
+ - qcom,sc7280-tcsr
|
||||
+ - qcom,sc8280xp-tcsr
|
||||
+ - qcom,sdm630-tcsr
|
||||
+ - qcom,sdm845-tcsr
|
||||
+ - qcom,sdx55-tcsr
|
||||
+ - qcom,sdx65-tcsr
|
||||
+ - qcom,sm4450-tcsr
|
||||
+ - qcom,sm8150-tcsr
|
||||
+ - qcom,sm8450-tcsr
|
||||
+ - qcom,tcsr-apq8064
|
||||
+ - qcom,tcsr-apq8084
|
||||
+ - qcom,tcsr-ipq5332
|
||||
+ - qcom,tcsr-ipq8064
|
||||
+ - qcom,tcsr-ipq8074
|
||||
+ - qcom,tcsr-ipq9574
|
||||
+ - qcom,tcsr-mdm9615
|
||||
+ - qcom,tcsr-msm8226
|
||||
+ - qcom,tcsr-msm8660
|
||||
+ - qcom,tcsr-msm8916
|
||||
+ - qcom,tcsr-msm8953
|
||||
+ - qcom,tcsr-msm8960
|
||||
+ - qcom,tcsr-msm8974
|
||||
+ - qcom,tcsr-msm8996
|
||||
+ - const: syscon
|
||||
+ - items:
|
||||
+ - const: qcom,tcsr-ipq6018
|
||||
+ - const: syscon
|
||||
+ - const: simple-mfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
+ ranges: true
|
||||
+
|
||||
+ "#address-cells":
|
||||
+ const: 1
|
||||
+
|
||||
+ "#size-cells":
|
||||
+ const: 1
|
||||
+
|
||||
+patternProperties:
|
||||
+ "pwm@[a-f0-9]+$":
|
||||
+ type: object
|
||||
+ $ref: /schemas/pwm/qcom,ipq6018-pwm.yaml
|
||||
+
|
||||
+
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
+allOf:
|
||||
+ - if:
|
||||
+ not:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ enum:
|
||||
+ - qcom,tcsr-ipq6018
|
||||
+ then:
|
||||
+ patternProperties:
|
||||
+ "pwm@[a-f0-9]+$": false
|
||||
+
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
+ # Example 1 - Syscon node found on MSM8960
|
||||
- |
|
||||
syscon@1a400000 {
|
||||
compatible = "qcom,tcsr-msm8960", "syscon";
|
||||
reg = <0x1a400000 0x100>;
|
||||
};
|
||||
+ # Example 2 - Syscon node found on IPQ6018
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
|
||||
+
|
||||
+ syscon@1937000 {
|
||||
+ compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";
|
||||
+ reg = <0x01937000 0x21000>;
|
||||
+ ranges = <0 0x1937000 0x21000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ pwm: pwm@a010 {
|
||||
+ compatible = "qcom,ipq6018-pwm";
|
||||
+ reg = <0xa010 0x20>;
|
||||
+ clocks = <&gcc GCC_ADSS_PWM_CLK>;
|
||||
+ assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
|
||||
+ assigned-clock-rates = <100000000>;
|
||||
+ #pwm-cells = <2>;
|
||||
+ };
|
||||
+ };
|
||||
\ No newline at end of file
|
@ -0,0 +1,22 @@
|
||||
From: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Subject: [PATCH V2 1/1] dt-bindings: nvmem: Add compatible for IPQ5018
|
||||
Date: Fri, 15 Sep 2023 17:31:20 +0530
|
||||
|
||||
Document the QFPROM on IPQ5018.
|
||||
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
|
||||
+++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
- enum:
|
||||
- qcom,apq8064-qfprom
|
||||
- qcom,apq8084-qfprom
|
||||
+ - qcom,ipq5018-qfprom
|
||||
- qcom,ipq5332-qfprom
|
||||
- qcom,ipq6018-qfprom
|
||||
- qcom,ipq8064-qfprom
|
@ -0,0 +1,26 @@
|
||||
From: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Date: Fri, 22 Sep 2023 17:21:13 +0530
|
||||
Subject: [PATCH] dt-bindings: thermal: qcom-tsens: Add ipq5018 compatible
|
||||
|
||||
IPQ5018 has tsens v1.0 block with 4 sensors and 1 interrupt.
|
||||
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
---
|
||||
--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
|
||||
+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml
|
||||
@@ -39,6 +39,7 @@ properties:
|
||||
- description: v1 of TSENS
|
||||
items:
|
||||
- enum:
|
||||
+ - qcom,ipq5018-tsens
|
||||
- qcom,msm8956-tsens
|
||||
- qcom,msm8976-tsens
|
||||
- qcom,qcs404-tsens
|
||||
@@ -232,6 +233,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
+ - qcom,ipq5018-tsens
|
||||
- qcom,ipq8064-tsens
|
||||
- qcom,msm8960-tsens
|
||||
- qcom,tsens-v0_1
|
@ -0,0 +1,45 @@
|
||||
From: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Subject: [PATCH] thermal/drivers/qcom: Add new feat for soc without rpm
|
||||
Date: Fri, 22 Sep 2023 17:21:14 +0530
|
||||
|
||||
In IPQ5018, Tsens IP doesn't have RPM. Hence the early init to
|
||||
enable tsens would not be done. So add a flag for that in feat
|
||||
and skip enable checks. Without this, tsens probe fails.
|
||||
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
---
|
||||
drivers/thermal/qcom/tsens.c | 2 +-
|
||||
drivers/thermal/qcom/tsens.h | 3 +++
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/thermal/qcom/tsens.c
|
||||
+++ b/drivers/thermal/qcom/tsens.c
|
||||
@@ -974,7 +974,7 @@ int __init init_common(struct tsens_priv
|
||||
ret = regmap_field_read(priv->rf[TSENS_EN], &enabled);
|
||||
if (ret)
|
||||
goto err_put_device;
|
||||
- if (!enabled) {
|
||||
+ if (!enabled && !(priv->feat->ignore_enable)) {
|
||||
dev_err(dev, "%s: device not enabled\n", __func__);
|
||||
ret = -ENODEV;
|
||||
goto err_put_device;
|
||||
--- a/drivers/thermal/qcom/tsens.h
|
||||
+++ b/drivers/thermal/qcom/tsens.h
|
||||
@@ -505,6 +505,8 @@ enum regfield_ids {
|
||||
* @srot_split: does the IP neatly splits the register space into SROT and TM,
|
||||
* with SROT only being available to secure boot firmware?
|
||||
* @has_watchdog: does this IP support watchdog functionality?
|
||||
+ * @ignore_enable: does this IP reside in a soc that does not have rpm to
|
||||
+ * do pre-init.
|
||||
* @max_sensors: maximum sensors supported by this version of the IP
|
||||
* @trip_min_temp: minimum trip temperature supported by this version of the IP
|
||||
* @trip_max_temp: maximum trip temperature supported by this version of the IP
|
||||
@@ -516,6 +518,7 @@ struct tsens_features {
|
||||
unsigned int adc:1;
|
||||
unsigned int srot_split:1;
|
||||
unsigned int has_watchdog:1;
|
||||
+ unsigned int ignore_enable:1;
|
||||
unsigned int max_sensors;
|
||||
int trip_min_temp;
|
||||
int trip_max_temp;
|
@ -0,0 +1,118 @@
|
||||
From: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Subject: [PATCH] thermal/drivers/tsens: Add support for IPQ5018 tsens
|
||||
Date: Fri, 22 Sep 2023 17:21:15 +0530
|
||||
|
||||
IPQ5018 has tsens IP V1.0, 4 sensors and 1 interrupt.
|
||||
The soc does not have a RPM, hence tsens has to be reset and
|
||||
enabled in the driver init. Adding the driver support for same.
|
||||
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
---
|
||||
drivers/thermal/qcom/tsens-v1.c | 60 +++++++++++++++++++++++++++++++++
|
||||
drivers/thermal/qcom/tsens.c | 3 ++
|
||||
drivers/thermal/qcom/tsens.h | 2 +-
|
||||
3 files changed, 64 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/thermal/qcom/tsens-v1.c
|
||||
+++ b/drivers/thermal/qcom/tsens-v1.c
|
||||
@@ -79,6 +79,18 @@ static struct tsens_features tsens_v1_fe
|
||||
.trip_max_temp = 120000,
|
||||
};
|
||||
|
||||
+static struct tsens_features tsens_v1_ipq5018_feat = {
|
||||
+ .ver_major = VER_1_X,
|
||||
+ .crit_int = 0,
|
||||
+ .combo_int = 0,
|
||||
+ .adc = 1,
|
||||
+ .srot_split = 1,
|
||||
+ .max_sensors = 11,
|
||||
+ .trip_min_temp = -40000,
|
||||
+ .trip_max_temp = 120000,
|
||||
+ .ignore_enable = 1,
|
||||
+};
|
||||
+
|
||||
static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
|
||||
/* ----- SROT ------ */
|
||||
/* VERSION */
|
||||
@@ -150,6 +162,41 @@ static int __init init_8956(struct tsens
|
||||
return init_common(priv);
|
||||
}
|
||||
|
||||
+static int __init init_ipq5018(struct tsens_priv *priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 mask;
|
||||
+
|
||||
+ ret = init_common(priv);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(priv->dev, "Init common failed %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_field_write(priv->rf[TSENS_SW_RST], 1);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "Reset failed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ mask = GENMASK(priv->num_sensors, 0);
|
||||
+ ret = regmap_field_update_bits(priv->rf[SENSOR_EN], mask, mask);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "Sensor Enable failed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_field_write(priv->rf[TSENS_EN], 1);
|
||||
+ if (ret) {
|
||||
+ dev_err(priv->dev, "Enable failed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_field_write(priv->rf[TSENS_SW_RST], 0);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static const struct tsens_ops ops_generic_v1 = {
|
||||
.init = init_common,
|
||||
.calibrate = calibrate_v1,
|
||||
@@ -194,3 +241,16 @@ struct tsens_plat_data data_8976 = {
|
||||
.feat = &tsens_v1_feat,
|
||||
.fields = tsens_v1_regfields,
|
||||
};
|
||||
+
|
||||
+const struct tsens_ops ops_ipq5018 = {
|
||||
+ .init = init_ipq5018,
|
||||
+ .calibrate = tsens_calibrate_common,
|
||||
+ .get_temp = get_temp_tsens_valid,
|
||||
+};
|
||||
+
|
||||
+struct tsens_plat_data data_ipq5018 = {
|
||||
+ .num_sensors = 5,
|
||||
+ .ops = &ops_ipq5018,
|
||||
+ .feat = &tsens_v1_ipq5018_feat,
|
||||
+ .fields = tsens_v1_regfields,
|
||||
+};
|
||||
--- a/drivers/thermal/qcom/tsens.c
|
||||
+++ b/drivers/thermal/qcom/tsens.c
|
||||
@@ -1101,6 +1101,9 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, t
|
||||
|
||||
static const struct of_device_id tsens_table[] = {
|
||||
{
|
||||
+ .compatible = "qcom,ipq5018-tsens",
|
||||
+ .data = &data_ipq5018,
|
||||
+ }, {
|
||||
.compatible = "qcom,ipq8064-tsens",
|
||||
.data = &data_8960,
|
||||
}, {
|
||||
--- a/drivers/thermal/qcom/tsens.h
|
||||
+++ b/drivers/thermal/qcom/tsens.h
|
||||
@@ -645,7 +645,7 @@ extern struct tsens_plat_data data_8960;
|
||||
extern struct tsens_plat_data data_8226, data_8909, data_8916, data_8939, data_8974, data_9607;
|
||||
|
||||
/* TSENS v1 targets */
|
||||
-extern struct tsens_plat_data data_tsens_v1, data_8937, data_8976, data_8956;
|
||||
+extern struct tsens_plat_data data_tsens_v1, data_8937, data_8976, data_8956, data_ipq5018;
|
||||
|
||||
/* TSENS v2 targets */
|
||||
extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
|
@ -0,0 +1,200 @@
|
||||
From: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add tsens node
|
||||
Date: Fri, 22 Sep 2023 17:21:16 +0530
|
||||
|
||||
IPQ5018 has tsens V1.0 IP with 4 sensors.
|
||||
There is no RPM, so tsens has to be manually enabled. Adding the tsens
|
||||
and nvmem node and IPQ5018 has 4 thermal sensors (zones). With the
|
||||
critical temperature being 120'C and action is to reboot. Adding all
|
||||
the 4 zones here.
|
||||
|
||||
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 169 ++++++++++++++++++++++++++
|
||||
1 file changed, 169 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -149,6 +149,117 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ qfprom: qfprom@a0000 {
|
||||
+ compatible = "qcom,ipq5018-qfprom", "qcom,qfprom";
|
||||
+ reg = <0xa0000 0x1000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ tsens_mode: mode@249 {
|
||||
+ reg = <0x249 1>;
|
||||
+ bits = <0 3>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_base1: base1@249 {
|
||||
+ reg = <0x249 2>;
|
||||
+ bits = <3 8>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_base2: base2@24a {
|
||||
+ reg = <0x24a 2>;
|
||||
+ bits = <3 8>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s0_p1: s0-p1@24b {
|
||||
+ reg = <0x24b 0x2>;
|
||||
+ bits = <2 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s0_p2: s0-p2@24c {
|
||||
+ reg = <0x24c 0x1>;
|
||||
+ bits = <1 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s1_p1: s1-p1@24c {
|
||||
+ reg = <0x24c 0x2>;
|
||||
+ bits = <7 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s1_p2: s1-p2@24d {
|
||||
+ reg = <0x24d 0x2>;
|
||||
+ bits = <5 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s2_p1: s2-p1@24e {
|
||||
+ reg = <0x24e 0x2>;
|
||||
+ bits = <3 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s2_p2: s2-p2@24f {
|
||||
+ reg = <0x24f 0x1>;
|
||||
+ bits = <1 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s3_p1: s3-p1@24f {
|
||||
+ reg = <0x24f 0x2>;
|
||||
+ bits = <7 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s3_p2: s3-p2@250 {
|
||||
+ reg = <0x250 0x2>;
|
||||
+ bits = <5 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s4_p1: s4-p1@251 {
|
||||
+ reg = <0x251 0x2>;
|
||||
+ bits = <3 6>;
|
||||
+ };
|
||||
+
|
||||
+ tsens_s4_p2: s4-p2@254 {
|
||||
+ reg = <0x254 0x1>;
|
||||
+ bits = <0 6>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ tsens: thermal-sensor@4a9000 {
|
||||
+ compatible = "qcom,ipq5018-tsens";
|
||||
+ reg = <0x4a9000 0x1000>, /* TM */
|
||||
+ <0x4a8000 0x1000>; /* SROT */
|
||||
+
|
||||
+ nvmem-cells = <&tsens_mode>,
|
||||
+ <&tsens_base1>,
|
||||
+ <&tsens_base2>,
|
||||
+ <&tsens_s0_p1>,
|
||||
+ <&tsens_s0_p2>,
|
||||
+ <&tsens_s1_p1>,
|
||||
+ <&tsens_s1_p2>,
|
||||
+ <&tsens_s2_p1>,
|
||||
+ <&tsens_s2_p2>,
|
||||
+ <&tsens_s3_p1>,
|
||||
+ <&tsens_s3_p2>,
|
||||
+ <&tsens_s4_p1>,
|
||||
+ <&tsens_s4_p2>;
|
||||
+
|
||||
+ nvmem-cell-names = "mode",
|
||||
+ "base1",
|
||||
+ "base2",
|
||||
+ "s0_p1",
|
||||
+ "s0_p2",
|
||||
+ "s1_p1",
|
||||
+ "s1_p2",
|
||||
+ "s2_p1",
|
||||
+ "s2_p2",
|
||||
+ "s3_p1",
|
||||
+ "s3_p2",
|
||||
+ "s4_p1",
|
||||
+ "s4_p2";
|
||||
+
|
||||
+ interrupts = <GIC_SPI 184 IRQ_TYPE_EDGE_RISING>;
|
||||
+ interrupt-names = "uplow";
|
||||
+ #qcom,sensors = <5>;
|
||||
+ #thermal-sensor-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
tlmm: pinctrl@1000000 {
|
||||
compatible = "qcom,ipq5018-tlmm";
|
||||
reg = <0x01000000 0x300000>;
|
||||
@@ -391,6 +502,64 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ thermal-zones {
|
||||
+ cpu-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsens 2>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu-critical {
|
||||
+ temperature = <120000>;
|
||||
+ hysteresis = <2>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gephy-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsens 4>;
|
||||
+
|
||||
+ trips {
|
||||
+ gephy-critical {
|
||||
+ temperature = <120000>;
|
||||
+ hysteresis = <2>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ top-glue-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsens 3>;
|
||||
+
|
||||
+ trips {
|
||||
+ top_glue-critical {
|
||||
+ temperature = <120000>;
|
||||
+ hysteresis = <2>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ ubi32-thermal {
|
||||
+ polling-delay-passive = <0>;
|
||||
+ polling-delay = <0>;
|
||||
+ thermal-sensors = <&tsens 1>;
|
||||
+
|
||||
+ trips {
|
||||
+ ubi32-critical {
|
||||
+ temperature = <120000>;
|
||||
+ hysteresis = <2>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
@ -0,0 +1,85 @@
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Thu, 2 Jan 2025 17:00:15 +0530
|
||||
Subject: [PATCH] dt-bindings: phy: qcom,uniphy-pcie: Document PCIe uniphy
|
||||
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
|
||||
Document the Qualcomm UNIPHY PCIe 28LP present in IPQ5332.
|
||||
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
---
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
|
||||
@@ -0,0 +1,71 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/phy/qcom,ipq5332-uniphy-pcie-phy.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Qualcomm UNIPHY PCIe 28LP PHY
|
||||
+
|
||||
+maintainers:
|
||||
+ - Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
+ - Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
+
|
||||
+description:
|
||||
+ PCIe and USB combo PHY found in Qualcomm IPQ5332 SoC
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - qcom,ipq5332-uniphy-pcie-phy
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: pcie pipe clock
|
||||
+ - description: pcie ahb clock
|
||||
+
|
||||
+ resets:
|
||||
+ items:
|
||||
+ - description: phy reset
|
||||
+ - description: ahb reset
|
||||
+ - description: cfg reset
|
||||
+
|
||||
+ "#phy-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+ "#clock-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+ num-lanes: true
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - resets
|
||||
+ - "#phy-cells"
|
||||
+ - "#clock-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/qcom,ipq5332-gcc.h>
|
||||
+
|
||||
+ pcie0_phy: phy@4b0000 {
|
||||
+ compatible = "qcom,ipq5332-uniphy-pcie-phy";
|
||||
+ reg = <0x004b0000 0x800>;
|
||||
+
|
||||
+ clocks = <&gcc GCC_PCIE3X1_0_PIPE_CLK>,
|
||||
+ <&gcc GCC_PCIE3X1_PHY_AHB_CLK>;
|
||||
+
|
||||
+ resets = <&gcc GCC_PCIE3X1_0_PHY_BCR>,
|
||||
+ <&gcc GCC_PCIE3X1_PHY_AHB_CLK_ARES>,
|
||||
+ <&gcc GCC_PCIE3X1_0_PHY_PHY_BCR>;
|
||||
+
|
||||
+ #clock-cells = <0>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+ };
|
@ -0,0 +1,332 @@
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Thu, 2 Jan 2025 17:00:16 +0530
|
||||
Subject: [PATCH] phy: qcom: Introduce PCIe UNIPHY 28LP driver
|
||||
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
|
||||
Add Qualcomm PCIe UNIPHY 28LP driver support present
|
||||
in Qualcomm IPQ5332 SoC and the phy init sequence.
|
||||
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
---
|
||||
--- a/drivers/phy/qualcomm/Kconfig
|
||||
+++ b/drivers/phy/qualcomm/Kconfig
|
||||
@@ -154,6 +154,18 @@ config PHY_QCOM_M31_USB
|
||||
management. This driver is required even for peripheral only or
|
||||
host only mode configurations.
|
||||
|
||||
+config PHY_QCOM_UNIPHY_PCIE_28LP
|
||||
+ bool "PCIE UNIPHY 28LP PHY driver"
|
||||
+ depends on ARCH_QCOM
|
||||
+ depends on HAS_IOMEM
|
||||
+ depends on OF
|
||||
+ select GENERIC_PHY
|
||||
+ help
|
||||
+ Enable this to support the PCIe UNIPHY 28LP phy transceiver that
|
||||
+ is used with PCIe controllers on Qualcomm IPQ5332 chips. It
|
||||
+ handles PHY initialization, clock management required after
|
||||
+ resetting the hardware and power management.
|
||||
+
|
||||
config PHY_QCOM_USB_HS
|
||||
tristate "Qualcomm USB HS PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
--- a/drivers/phy/qualcomm/Makefile
|
||||
+++ b/drivers/phy/qualcomm/Makefile
|
||||
@@ -17,6 +17,7 @@ obj-$(CONFIG_PHY_QCOM_QMP_USB_LEGACY) +=
|
||||
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
|
||||
obj-$(CONFIG_PHY_QCOM_SNPS_EUSB2) += phy-qcom-snps-eusb2.o
|
||||
obj-$(CONFIG_PHY_QCOM_EUSB2_REPEATER) += phy-qcom-eusb2-repeater.o
|
||||
+obj-$(CONFIG_PHY_QCOM_UNIPHY_PCIE_28LP) += phy-qcom-uniphy-pcie-28lp.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
|
||||
@@ -0,0 +1,285 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/*
|
||||
+ * Copyright (c) 2025, The Linux Foundation. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/phy/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#define RST_ASSERT_DELAY_MIN_US 100
|
||||
+#define RST_ASSERT_DELAY_MAX_US 150
|
||||
+#define PIPE_CLK_DELAY_MIN_US 5000
|
||||
+#define PIPE_CLK_DELAY_MAX_US 5100
|
||||
+#define CLK_EN_DELAY_MIN_US 30
|
||||
+#define CLK_EN_DELAY_MAX_US 50
|
||||
+#define CDR_CTRL_REG_1 0x80
|
||||
+#define CDR_CTRL_REG_2 0x84
|
||||
+#define CDR_CTRL_REG_3 0x88
|
||||
+#define CDR_CTRL_REG_4 0x8c
|
||||
+#define CDR_CTRL_REG_5 0x90
|
||||
+#define CDR_CTRL_REG_6 0x94
|
||||
+#define CDR_CTRL_REG_7 0x98
|
||||
+#define SSCG_CTRL_REG_1 0x9c
|
||||
+#define SSCG_CTRL_REG_2 0xa0
|
||||
+#define SSCG_CTRL_REG_3 0xa4
|
||||
+#define SSCG_CTRL_REG_4 0xa8
|
||||
+#define SSCG_CTRL_REG_5 0xac
|
||||
+#define SSCG_CTRL_REG_6 0xb0
|
||||
+#define PCS_INTERNAL_CONTROL_2 0x2d8
|
||||
+
|
||||
+#define PHY_CFG_PLLCFG 0x220
|
||||
+#define PHY_CFG_EIOS_DTCT_REG 0x3e4
|
||||
+#define PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME 0x3e8
|
||||
+
|
||||
+#define PHY_MODE_FIXED 0x1
|
||||
+
|
||||
+enum qcom_uniphy_pcie_type {
|
||||
+ PHY_TYPE_PCIE = 1,
|
||||
+ PHY_TYPE_PCIE_GEN2,
|
||||
+ PHY_TYPE_PCIE_GEN3,
|
||||
+};
|
||||
+
|
||||
+struct qcom_uniphy_pcie_regs {
|
||||
+ u32 offset;
|
||||
+ u32 val;
|
||||
+};
|
||||
+
|
||||
+struct qcom_uniphy_pcie_data {
|
||||
+ int lane_offset; /* offset between the lane register bases */
|
||||
+ u32 phy_type;
|
||||
+ const struct qcom_uniphy_pcie_regs *init_seq;
|
||||
+ u32 init_seq_num;
|
||||
+ u32 pipe_clk_rate;
|
||||
+};
|
||||
+
|
||||
+struct qcom_uniphy_pcie {
|
||||
+ struct phy phy;
|
||||
+ struct device *dev;
|
||||
+ const struct qcom_uniphy_pcie_data *data;
|
||||
+ struct clk_bulk_data *clks;
|
||||
+ int num_clks;
|
||||
+ struct reset_control *resets;
|
||||
+ void __iomem *base;
|
||||
+ int lanes;
|
||||
+};
|
||||
+
|
||||
+#define phy_to_dw_phy(x) container_of((x), struct qca_uni_pcie_phy, phy)
|
||||
+
|
||||
+static const struct qcom_uniphy_pcie_regs ipq5332_regs[] = {
|
||||
+ {
|
||||
+ .offset = PHY_CFG_PLLCFG,
|
||||
+ .val = 0x30,
|
||||
+ }, {
|
||||
+ .offset = PHY_CFG_EIOS_DTCT_REG,
|
||||
+ .val = 0x53ef,
|
||||
+ }, {
|
||||
+ .offset = PHY_CFG_GEN3_ALIGN_HOLDOFF_TIME,
|
||||
+ .val = 0xcf,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct qcom_uniphy_pcie_data ipq5332_data = {
|
||||
+ .lane_offset = 0x800,
|
||||
+ .phy_type = PHY_TYPE_PCIE_GEN3,
|
||||
+ .init_seq = ipq5332_regs,
|
||||
+ .init_seq_num = ARRAY_SIZE(ipq5332_regs),
|
||||
+ .pipe_clk_rate = 250000000,
|
||||
+};
|
||||
+
|
||||
+static void qcom_uniphy_pcie_init(struct qcom_uniphy_pcie *phy)
|
||||
+{
|
||||
+ const struct qcom_uniphy_pcie_data *data = phy->data;
|
||||
+ const struct qcom_uniphy_pcie_regs *init_seq;
|
||||
+ void __iomem *base = phy->base;
|
||||
+ int lane, i;
|
||||
+
|
||||
+ for (lane = 0; lane < phy->lanes; lane++) {
|
||||
+ init_seq = data->init_seq;
|
||||
+
|
||||
+ for (i = 0; i < data->init_seq_num; i++)
|
||||
+ writel(init_seq[i].val, base + init_seq[i].offset);
|
||||
+
|
||||
+ base += data->lane_offset;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int qcom_uniphy_pcie_power_off(struct phy *x)
|
||||
+{
|
||||
+ struct qcom_uniphy_pcie *phy = phy_get_drvdata(x);
|
||||
+
|
||||
+ clk_bulk_disable_unprepare(phy->num_clks, phy->clks);
|
||||
+
|
||||
+ return reset_control_assert(phy->resets);
|
||||
+}
|
||||
+
|
||||
+static int qcom_uniphy_pcie_power_on(struct phy *x)
|
||||
+{
|
||||
+ struct qcom_uniphy_pcie *phy = phy_get_drvdata(x);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = reset_control_assert(phy->resets);
|
||||
+ if (ret) {
|
||||
+ dev_err(phy->dev, "reset assert failed (%d)\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ usleep_range(RST_ASSERT_DELAY_MIN_US, RST_ASSERT_DELAY_MAX_US);
|
||||
+
|
||||
+ ret = reset_control_deassert(phy->resets);
|
||||
+ if (ret) {
|
||||
+ dev_err(phy->dev, "reset deassert failed (%d)\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ usleep_range(PIPE_CLK_DELAY_MIN_US, PIPE_CLK_DELAY_MAX_US);
|
||||
+
|
||||
+ ret = clk_bulk_prepare_enable(phy->num_clks, phy->clks);
|
||||
+ if (ret) {
|
||||
+ dev_err(phy->dev, "clk prepare and enable failed %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ usleep_range(CLK_EN_DELAY_MIN_US, CLK_EN_DELAY_MAX_US);
|
||||
+
|
||||
+ qcom_uniphy_pcie_init(phy);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int qcom_uniphy_pcie_get_resources(struct platform_device *pdev,
|
||||
+ struct qcom_uniphy_pcie *phy)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ phy->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
+ if (IS_ERR(phy->base))
|
||||
+ return PTR_ERR(phy->base);
|
||||
+
|
||||
+ phy->num_clks = devm_clk_bulk_get_all(phy->dev, &phy->clks);
|
||||
+ if (phy->num_clks < 0)
|
||||
+ return phy->num_clks;
|
||||
+
|
||||
+ phy->resets = devm_reset_control_array_get_exclusive(phy->dev);
|
||||
+ if (IS_ERR(phy->resets))
|
||||
+ return PTR_ERR(phy->resets);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Register a fixed rate pipe clock.
|
||||
+ *
|
||||
+ * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
|
||||
+ * controls it. The <s>_pipe_clk coming out of the GCC is requested
|
||||
+ * by the PHY driver for its operations.
|
||||
+ * We register the <s>_pipe_clksrc here. The gcc driver takes care
|
||||
+ * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
|
||||
+ * Below picture shows this relationship.
|
||||
+ *
|
||||
+ * +---------------+
|
||||
+ * | PHY block |<<---------------------------------------+
|
||||
+ * | | |
|
||||
+ * | +-------+ | +-----+ |
|
||||
+ * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
|
||||
+ * clk | +-------+ | +-----+
|
||||
+ * +---------------+
|
||||
+ */
|
||||
+static inline int phy_pipe_clk_register(struct qcom_uniphy_pcie *phy, int id)
|
||||
+{
|
||||
+ const struct qcom_uniphy_pcie_data *data = phy->data;
|
||||
+ struct clk_hw *hw;
|
||||
+ char name[64];
|
||||
+
|
||||
+ snprintf(name, sizeof(name), "phy%d_pipe_clk_src", id);
|
||||
+ hw = devm_clk_hw_register_fixed_rate(phy->dev, name, NULL, 0,
|
||||
+ data->pipe_clk_rate);
|
||||
+ if (IS_ERR(hw))
|
||||
+ return dev_err_probe(phy->dev, PTR_ERR(hw),
|
||||
+ "Unable to register %s\n", name);
|
||||
+
|
||||
+ return devm_of_clk_add_hw_provider(phy->dev, of_clk_hw_simple_get, hw);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id qcom_uniphy_pcie_id_table[] = {
|
||||
+ {
|
||||
+ .compatible = "qcom,ipq5332-uniphy-pcie-phy",
|
||||
+ .data = &ipq5332_data,
|
||||
+ }, {
|
||||
+ /* Sentinel */
|
||||
+ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, qcom_uniphy_pcie_id_table);
|
||||
+
|
||||
+static const struct phy_ops pcie_ops = {
|
||||
+ .power_on = qcom_uniphy_pcie_power_on,
|
||||
+ .power_off = qcom_uniphy_pcie_power_off,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int qcom_uniphy_pcie_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct phy_provider *phy_provider;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct qcom_uniphy_pcie *phy;
|
||||
+ struct phy *generic_phy;
|
||||
+ int ret;
|
||||
+
|
||||
+ phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
|
||||
+ if (!phy)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, phy);
|
||||
+ phy->dev = &pdev->dev;
|
||||
+
|
||||
+ phy->data = of_device_get_match_data(dev);
|
||||
+ if (!phy->data)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ phy->lanes = 1;
|
||||
+ ret = of_property_read_u32(dev->of_node, "num-lanes", &phy->lanes);
|
||||
+
|
||||
+ ret = qcom_uniphy_pcie_get_resources(pdev, phy);
|
||||
+ if (ret < 0)
|
||||
+ return dev_err_probe(&pdev->dev, ret,
|
||||
+ "failed to get resources: %d\n", ret);
|
||||
+
|
||||
+ generic_phy = devm_phy_create(phy->dev, NULL, &pcie_ops);
|
||||
+ if (IS_ERR(generic_phy))
|
||||
+ return PTR_ERR(generic_phy);
|
||||
+
|
||||
+ phy_set_drvdata(generic_phy, phy);
|
||||
+
|
||||
+ ret = phy_pipe_clk_register(phy, generic_phy->id);
|
||||
+ if (ret)
|
||||
+ dev_err(&pdev->dev, "failed to register phy pipe clk\n");
|
||||
+
|
||||
+ phy_provider = devm_of_phy_provider_register(phy->dev,
|
||||
+ of_phy_simple_xlate);
|
||||
+ if (IS_ERR(phy_provider))
|
||||
+ return PTR_ERR(phy_provider);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver qcom_uniphy_pcie_driver = {
|
||||
+ .probe = qcom_uniphy_pcie_probe,
|
||||
+ .driver = {
|
||||
+ .name = "qcom-uniphy-pcie",
|
||||
+ .of_match_table = qcom_uniphy_pcie_id_table,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(qcom_uniphy_pcie_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("PCIE QCOM UNIPHY driver");
|
||||
+MODULE_LICENSE("GPL");
|
@ -0,0 +1,25 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Tue, 07 Jan 2025 17:34:13 +0400
|
||||
Subject: [PATCH] phy: qualcomm: qcom-uniphy-pcie add IPQ5018 compatible
|
||||
|
||||
The Qualcomm UNIPHY PCIe PHY 28lp part of the IPQ5332 SoC is also present on
|
||||
the IPQ5018 SoC, so adding the compatible for IPQ5018.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
|
||||
+++ b/Documentation/devicetree/bindings/phy/qcom,ipq5332-uniphy-pcie-phy.yaml
|
||||
@@ -11,11 +11,12 @@ maintainers:
|
||||
- Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
|
||||
description:
|
||||
- PCIe and USB combo PHY found in Qualcomm IPQ5332 SoC
|
||||
+ PCIe and USB combo PHY found in Qualcomm IPQ5018 and IPQ5332 SoCs
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
+ - qcom,ipq5018-uniphy-pcie-phy
|
||||
- qcom,ipq5332-uniphy-pcie-phy
|
||||
|
||||
reg:
|
@ -0,0 +1,77 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Date: Tue, 07 Jan 2025 17:34:13 +0400
|
||||
Subject: [PATCH] phy: qualcomm: qcom-uniphy-pcie 28lp add support for IPQ5018
|
||||
|
||||
The Qualcomm UNIPHY PCIe PHY 28lp is found on both IPQ5332 and IPQ5018.
|
||||
Adding the PHY init sequence, pipe clock rate, and compatible for IPQ5018.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
|
||||
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy-pcie-28lp.c
|
||||
@@ -76,6 +76,40 @@ struct qcom_uniphy_pcie {
|
||||
|
||||
#define phy_to_dw_phy(x) container_of((x), struct qca_uni_pcie_phy, phy)
|
||||
|
||||
+static const struct qcom_uniphy_pcie_regs ipq5018_regs[] = {
|
||||
+ {
|
||||
+ .offset = SSCG_CTRL_REG_4,
|
||||
+ .val = 0x1cb9,
|
||||
+ }, {
|
||||
+ .offset = SSCG_CTRL_REG_5,
|
||||
+ .val = 0x023a,
|
||||
+ }, {
|
||||
+ .offset = SSCG_CTRL_REG_3,
|
||||
+ .val = 0xd360,
|
||||
+ }, {
|
||||
+ .offset = SSCG_CTRL_REG_1,
|
||||
+ .val = 0x1,
|
||||
+ }, {
|
||||
+ .offset = SSCG_CTRL_REG_2,
|
||||
+ .val = 0xeb,
|
||||
+ }, {
|
||||
+ .offset = CDR_CTRL_REG_4,
|
||||
+ .val = 0x3f9,
|
||||
+ }, {
|
||||
+ .offset = CDR_CTRL_REG_5,
|
||||
+ .val = 0x1c9,
|
||||
+ }, {
|
||||
+ .offset = CDR_CTRL_REG_2,
|
||||
+ .val = 0x419,
|
||||
+ }, {
|
||||
+ .offset = CDR_CTRL_REG_1,
|
||||
+ .val = 0x200,
|
||||
+ }, {
|
||||
+ .offset = PCS_INTERNAL_CONTROL_2,
|
||||
+ .val = 0xf101,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct qcom_uniphy_pcie_regs ipq5332_regs[] = {
|
||||
{
|
||||
.offset = PHY_CFG_PLLCFG,
|
||||
@@ -89,6 +123,14 @@ static const struct qcom_uniphy_pcie_reg
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct qcom_uniphy_pcie_data ipq5018_data = {
|
||||
+ .lane_offset = 0x800,
|
||||
+ .phy_type = PHY_TYPE_PCIE_GEN2,
|
||||
+ .init_seq = ipq5018_regs,
|
||||
+ .init_seq_num = ARRAY_SIZE(ipq5018_regs),
|
||||
+ .pipe_clk_rate = 125000000,
|
||||
+};
|
||||
+
|
||||
static const struct qcom_uniphy_pcie_data ipq5332_data = {
|
||||
.lane_offset = 0x800,
|
||||
.phy_type = PHY_TYPE_PCIE_GEN3,
|
||||
@@ -212,6 +254,9 @@ static inline int phy_pipe_clk_register(
|
||||
|
||||
static const struct of_device_id qcom_uniphy_pcie_id_table[] = {
|
||||
{
|
||||
+ .compatible = "qcom,ipq5018-uniphy-pcie-phy",
|
||||
+ .data = &ipq5018_data,
|
||||
+ }, {
|
||||
.compatible = "qcom,ipq5332-uniphy-pcie-phy",
|
||||
.data = &ipq5332_data,
|
||||
}, {
|
@ -0,0 +1,78 @@
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Date: Tue, 3 Oct 2023 17:38:42 +0530
|
||||
Subject: [PATCH] dt-bindings: PCI: qcom: Add IPQ5108 SoC
|
||||
|
||||
Add support for the PCIe controller on the Qualcomm
|
||||
IPQ5108 SoC to the bindings.
|
||||
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
---
|
||||
.../devicetree/bindings/pci/qcom,pcie.yaml | 36 +++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
|
||||
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.yaml
|
||||
@@ -21,6 +21,7 @@ properties:
|
||||
- qcom,pcie-apq8064
|
||||
- qcom,pcie-apq8084
|
||||
- qcom,pcie-ipq4019
|
||||
+ - qcom,pcie-ipq5018
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8064
|
||||
- qcom,pcie-ipq8064-v2
|
||||
@@ -170,6 +171,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
+ - qcom,pcie-ipq5018
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8074-gen3
|
||||
then:
|
||||
@@ -337,6 +339,39 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
+ - qcom,pcie-ipq5018
|
||||
+ then:
|
||||
+ properties:
|
||||
+ clocks:
|
||||
+ minItems: 6
|
||||
+ maxItems: 6
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: iface # PCIe to SysNOC BIU clock
|
||||
+ - const: axi_m # AXI Master clock
|
||||
+ - const: axi_s # AXI Slave clock
|
||||
+ - const: ahb # AHB clock
|
||||
+ - const: aux # Auxiliary clock
|
||||
+ - const: axi_bridge # AXI bridge clock
|
||||
+ resets:
|
||||
+ minItems: 8
|
||||
+ maxItems: 8
|
||||
+ reset-names:
|
||||
+ items:
|
||||
+ - const: pipe # PIPE reset
|
||||
+ - const: sleep # Sleep reset
|
||||
+ - const: sticky # Core sticky reset
|
||||
+ - const: axi_m # AXI master reset
|
||||
+ - const: axi_s # AXI slave reset
|
||||
+ - const: ahb # AHB reset
|
||||
+ - const: axi_m_sticky # AXI master sticky reset
|
||||
+ - const: axi_s_sticky # AXI slave sticky reset
|
||||
+
|
||||
+ - if:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ enum:
|
||||
- qcom,pcie-msm8996
|
||||
then:
|
||||
properties:
|
||||
@@ -875,6 +910,7 @@ allOf:
|
||||
- qcom,pcie-apq8064
|
||||
- qcom,pcie-apq8084
|
||||
- qcom,pcie-ipq4019
|
||||
+ - qcom,pcie-ipq5018
|
||||
- qcom,pcie-ipq6018
|
||||
- qcom,pcie-ipq8064
|
||||
- qcom,pcie-ipq8064-v2
|
@ -0,0 +1,77 @@
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Subject: [PATCH] PCI: qcom: Add support for IPQ5018
|
||||
Date: Tue, 3 Oct 2023 17:38:44 +0530
|
||||
|
||||
Added a new compatible 'qcom,pcie-ipq5018' and modified
|
||||
get_resources of 'ops 2_9_0' to get the clocks from the
|
||||
device-tree.
|
||||
|
||||
Co-developed-by: Anusha Rao <quic_anusha@quicinc.com>
|
||||
Signed-off-by: Anusha Rao <quic_anusha@quicinc.com>
|
||||
Co-developed-by: Devi Priya <quic_devipriy@quicinc.com>
|
||||
Signed-off-by: Devi Priya <quic_devipriy@quicinc.com>
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
---
|
||||
drivers/pci/controller/dwc/pcie-qcom.c | 22 ++++++++--------------
|
||||
1 file changed, 8 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/dwc/pcie-qcom.c
|
||||
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
|
||||
@@ -202,8 +202,9 @@ struct qcom_pcie_resources_2_7_0 {
|
||||
|
||||
#define QCOM_PCIE_2_9_0_MAX_CLOCKS 5
|
||||
struct qcom_pcie_resources_2_9_0 {
|
||||
- struct clk_bulk_data clks[QCOM_PCIE_2_9_0_MAX_CLOCKS];
|
||||
+ struct clk_bulk_data *clks;
|
||||
struct reset_control *rst;
|
||||
+ int num_clks;
|
||||
};
|
||||
|
||||
union qcom_pcie_resources {
|
||||
@@ -1073,17 +1074,10 @@ static int qcom_pcie_get_resources_2_9_0
|
||||
struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
|
||||
struct dw_pcie *pci = pcie->pci;
|
||||
struct device *dev = pci->dev;
|
||||
- int ret;
|
||||
-
|
||||
- res->clks[0].id = "iface";
|
||||
- res->clks[1].id = "axi_m";
|
||||
- res->clks[2].id = "axi_s";
|
||||
- res->clks[3].id = "axi_bridge";
|
||||
- res->clks[4].id = "rchng";
|
||||
|
||||
- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
|
||||
+ if (res->num_clks < 0)
|
||||
+ return res->num_clks;
|
||||
|
||||
res->rst = devm_reset_control_array_get_exclusive(dev);
|
||||
if (IS_ERR(res->rst))
|
||||
@@ -1096,7 +1090,7 @@ static void qcom_pcie_deinit_2_9_0(struc
|
||||
{
|
||||
struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
|
||||
|
||||
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
|
||||
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
|
||||
}
|
||||
|
||||
static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
|
||||
@@ -1125,7 +1119,7 @@ static int qcom_pcie_init_2_9_0(struct q
|
||||
|
||||
usleep_range(2000, 2500);
|
||||
|
||||
- return clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
|
||||
+ return clk_bulk_prepare_enable(res->num_clks, res->clks);
|
||||
}
|
||||
|
||||
static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
|
||||
@@ -1641,6 +1635,7 @@ static const struct of_device_id qcom_pc
|
||||
{ .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
|
||||
{ .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 },
|
||||
+ { .compatible = "qcom,pcie-ipq5018", .data = &cfg_2_9_0 },
|
||||
{ .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 },
|
||||
{ .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 },
|
@ -0,0 +1,216 @@
|
||||
From: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add PCIe related nodes
|
||||
Date: Tue, 3 Oct 2023 17:38:45 +0530
|
||||
|
||||
Add phy and controller nodes for PCIe0 and PCIe1.
|
||||
PCIe0 is 2-lane Gen2 and PCIe1 is 1-lane Gen2.
|
||||
|
||||
Signed-off-by: Nitheesh Sekar <quic_nsekar@quicinc.com>
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq5018.dtsi | 186 +++++++++++++++++++++++++-
|
||||
1 file changed, 184 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -149,6 +149,42 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ pcie1_phy: phy@7e000{
|
||||
+ compatible = "qcom,ipq5018-uniphy-pcie-phy";
|
||||
+ reg = <0x0007e000 0x800>;
|
||||
+
|
||||
+ clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
|
||||
+
|
||||
+ resets = <&gcc GCC_PCIE1_PHY_BCR>,
|
||||
+ <&gcc GCC_PCIE1PHY_PHY_BCR>;
|
||||
+
|
||||
+ #clock-cells = <0>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+
|
||||
+ num-lanes = <1>;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ pcie0_phy: phy@86000{
|
||||
+ compatible = "qcom,ipq5018-uniphy-pcie-phy";
|
||||
+ reg = <0x00086000 0x800>;
|
||||
+
|
||||
+ clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
|
||||
+
|
||||
+ resets = <&gcc GCC_PCIE0_PHY_BCR>,
|
||||
+ <&gcc GCC_PCIE0PHY_PHY_BCR>;
|
||||
+
|
||||
+ #clock-cells = <0>;
|
||||
+
|
||||
+ #phy-cells = <0>;
|
||||
+
|
||||
+ num-lanes = <2>;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
qfprom: qfprom@a0000 {
|
||||
compatible = "qcom,ipq5018-qfprom", "qcom,qfprom";
|
||||
reg = <0xa0000 0x1000>;
|
||||
@@ -283,8 +319,8 @@
|
||||
reg = <0x01800000 0x80000>;
|
||||
clocks = <&xo_board_clk>,
|
||||
<&sleep_clk>,
|
||||
- <0>,
|
||||
- <0>,
|
||||
+ <&pcie0_phy>,
|
||||
+ <&pcie1_phy>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
@@ -501,6 +537,146 @@
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
+
|
||||
+ pcie1: pcie@80000000 {
|
||||
+ compatible = "qcom,pcie-ipq5018";
|
||||
+ reg = <0x80000000 0xf1d>,
|
||||
+ <0x80000f20 0xa8>,
|
||||
+ <0x80001000 0x1000>,
|
||||
+ <0x00078000 0x3000>,
|
||||
+ <0x80100000 0x1000>;
|
||||
+ reg-names = "dbi",
|
||||
+ "elbi",
|
||||
+ "atu",
|
||||
+ "parf",
|
||||
+ "config";
|
||||
+ device_type = "pci";
|
||||
+ linux,pci-domain = <0>;
|
||||
+ bus-range = <0x00 0xff>;
|
||||
+ num-lanes = <1>;
|
||||
+ max-link-speed = <2>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ phys = <&pcie1_phy>;
|
||||
+ phy-names ="pciephy";
|
||||
+
|
||||
+ ranges = <0x81000000 0 0x80200000 0x80200000 0 0x00100000>, /* I/O */
|
||||
+ <0x82000000 0 0x80300000 0x80300000 0 0x10000000>; /* MEM */
|
||||
+
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-map-mask = <0 0 0 0x7>;
|
||||
+ interrupt-map = <0 0 0 1 &intc 0 142 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
|
||||
+ <0 0 0 2 &intc 0 143 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
|
||||
+ <0 0 0 3 &intc 0 144 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
|
||||
+ <0 0 0 4 &intc 0 145 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
|
||||
+
|
||||
+ interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "global_irq";
|
||||
+
|
||||
+ clocks = <&gcc GCC_SYS_NOC_PCIE1_AXI_CLK>,
|
||||
+ <&gcc GCC_PCIE1_AXI_M_CLK>,
|
||||
+ <&gcc GCC_PCIE1_AXI_S_CLK>,
|
||||
+ <&gcc GCC_PCIE1_AHB_CLK>,
|
||||
+ <&gcc GCC_PCIE1_AUX_CLK>,
|
||||
+ <&gcc GCC_PCIE1_AXI_S_BRIDGE_CLK>;
|
||||
+ clock-names = "iface",
|
||||
+ "axi_m",
|
||||
+ "axi_s",
|
||||
+ "ahb",
|
||||
+ "aux",
|
||||
+ "axi_bridge";
|
||||
+
|
||||
+ resets = <&gcc GCC_PCIE1_PIPE_ARES>,
|
||||
+ <&gcc GCC_PCIE1_SLEEP_ARES>,
|
||||
+ <&gcc GCC_PCIE1_CORE_STICKY_ARES>,
|
||||
+ <&gcc GCC_PCIE1_AXI_MASTER_ARES>,
|
||||
+ <&gcc GCC_PCIE1_AXI_SLAVE_ARES>,
|
||||
+ <&gcc GCC_PCIE1_AHB_ARES>,
|
||||
+ <&gcc GCC_PCIE1_AXI_MASTER_STICKY_ARES>,
|
||||
+ <&gcc GCC_PCIE1_AXI_SLAVE_STICKY_ARES>;
|
||||
+ reset-names = "pipe",
|
||||
+ "sleep",
|
||||
+ "sticky",
|
||||
+ "axi_m",
|
||||
+ "axi_s",
|
||||
+ "ahb",
|
||||
+ "axi_m_sticky",
|
||||
+ "axi_s_sticky";
|
||||
+
|
||||
+ msi-map = <0x0 &v2m0 0x0 0xff8>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ pcie0: pcie@a0000000 {
|
||||
+ compatible = "qcom,pcie-ipq5018";
|
||||
+ reg = <0xa0000000 0xf1d>,
|
||||
+ <0xa0000f20 0xa8>,
|
||||
+ <0xa0001000 0x1000>,
|
||||
+ <0x00080000 0x3000>,
|
||||
+ <0xa0100000 0x1000>;
|
||||
+ reg-names = "dbi",
|
||||
+ "elbi",
|
||||
+ "atu",
|
||||
+ "parf",
|
||||
+ "config";
|
||||
+ device_type = "pci";
|
||||
+ linux,pci-domain = <1>;
|
||||
+ bus-range = <0x00 0xff>;
|
||||
+ num-lanes = <2>;
|
||||
+ max-link-speed = <2>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ phys = <&pcie0_phy>;
|
||||
+ phy-names ="pciephy";
|
||||
+
|
||||
+ ranges = <0x81000000 0 0xa0200000 0xa0200000 0 0x00100000>, /* I/O */
|
||||
+ <0x82000000 0 0xa0300000 0xa0300000 0 0x10000000>; /* MEM */
|
||||
+
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-map-mask = <0 0 0 0x7>;
|
||||
+ interrupt-map = <0 0 0 1 &intc 0 75 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
|
||||
+ <0 0 0 2 &intc 0 78 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
|
||||
+ <0 0 0 3 &intc 0 79 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
|
||||
+ <0 0 0 4 &intc 0 83 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
|
||||
+
|
||||
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ interrupt-names = "global_irq";
|
||||
+
|
||||
+ clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
|
||||
+ <&gcc GCC_PCIE0_AXI_M_CLK>,
|
||||
+ <&gcc GCC_PCIE0_AXI_S_CLK>,
|
||||
+ <&gcc GCC_PCIE0_AHB_CLK>,
|
||||
+ <&gcc GCC_PCIE0_AUX_CLK>,
|
||||
+ <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>;
|
||||
+ clock-names = "iface",
|
||||
+ "axi_m",
|
||||
+ "axi_s",
|
||||
+ "ahb",
|
||||
+ "aux",
|
||||
+ "axi_bridge";
|
||||
+
|
||||
+ resets = <&gcc GCC_PCIE0_PIPE_ARES>,
|
||||
+ <&gcc GCC_PCIE0_SLEEP_ARES>,
|
||||
+ <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
|
||||
+ <&gcc GCC_PCIE0_AXI_MASTER_ARES>,
|
||||
+ <&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
|
||||
+ <&gcc GCC_PCIE0_AHB_ARES>,
|
||||
+ <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>,
|
||||
+ <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>;
|
||||
+ reset-names = "pipe",
|
||||
+ "sleep",
|
||||
+ "sticky",
|
||||
+ "axi_m",
|
||||
+ "axi_s",
|
||||
+ "ahb",
|
||||
+ "axi_m_sticky",
|
||||
+ "axi_s_sticky";
|
||||
+
|
||||
+ msi-map = <0x0 &v2m0 0x0 0xff8>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
};
|
||||
|
||||
thermal-zones {
|
@ -0,0 +1,18 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] dt-bindings: mfd: qcom,tcsr: Add IPQ5018 compatible
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
Document the qcom,tcsr-ipq5018 compatible.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
|
||||
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.yaml
|
||||
@@ -33,6 +33,7 @@ properties:
|
||||
- qcom,sm8450-tcsr
|
||||
- qcom,tcsr-apq8064
|
||||
- qcom,tcsr-apq8084
|
||||
+ - qcom,tcsr-ipq5018
|
||||
- qcom,tcsr-ipq5332
|
||||
- qcom,tcsr-ipq8064
|
||||
- qcom,tcsr-ipq8074
|
@ -0,0 +1,22 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add TCSR node
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
Add TCSR node.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -337,6 +337,11 @@
|
||||
#hwlock-cells = <1>;
|
||||
};
|
||||
|
||||
+ tcsr: syscon@1937000 {
|
||||
+ compatible = "qcom,tcsr-ipq5018", "syscon", "simple-mfd";
|
||||
+ reg = <0x01937000 0x21000>;
|
||||
+ };
|
||||
+
|
||||
sdhc_1: mmc@7804000 {
|
||||
compatible = "qcom,ipq5018-sdhci", "qcom,sdhci-msm-v5";
|
||||
reg = <0x7804000 0x1000>;
|
@ -0,0 +1,19 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: enable the download mode support
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
IPQ5018 also supports the download mode to collect the RAM dumps if system crashes, to perform
|
||||
the post mortem analysis. Add support for the same.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -82,6 +82,7 @@
|
||||
scm {
|
||||
compatible = "qcom,scm-ipq5018", "qcom,scm";
|
||||
qcom,sdi-enabled;
|
||||
+ qcom,dload-mode = <&tcsr 0x6100>;
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,22 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] dt-bindings: mfd: qcom,tcsr: Add IPQ5018 compatible
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
Add compatible for IPQ5018.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml
|
||||
+++ b/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml
|
||||
@@ -11,7 +11,10 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
- const: qcom,ipq6018-pwm
|
||||
+ items:
|
||||
+ - enum:
|
||||
+ - qcom,ipq5018-pwm
|
||||
+ - const: qcom,ipq6018-pwm
|
||||
|
||||
reg:
|
||||
description: Offset of PWM register in the TCSR block.
|
@ -0,0 +1,65 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] pinctrl: qcom: IPQ5018: update pwm groups
|
||||
Date: Wed, 27 Nov 2024 09:14:11 +0400
|
||||
|
||||
GPIO 1, 30, and 46 are used to control PWM1, PWM3, and PWM0 respectively which
|
||||
in turn drive the PWM led, so let's update the pwm# and pingroups accordingly.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/drivers/pinctrl/qcom/pinctrl-ipq5018.c
|
||||
+++ b/drivers/pinctrl/qcom/pinctrl-ipq5018.c
|
||||
@@ -541,7 +541,7 @@ static const char * const qdss_tracectl_
|
||||
};
|
||||
|
||||
static const char * const pwm0_groups[] = {
|
||||
- "gpio42",
|
||||
+ "gpio42", "gpio46",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_out_b0_groups[] = {
|
||||
@@ -549,7 +549,7 @@ static const char * const qdss_cti_trig_
|
||||
};
|
||||
|
||||
static const char * const pwm1_groups[] = {
|
||||
- "gpio43",
|
||||
+ "gpio43", "gpio1",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_in_b0_groups[] = {
|
||||
@@ -565,7 +565,7 @@ static const char * const qdss_cti_trig_
|
||||
};
|
||||
|
||||
static const char * const pwm3_groups[] = {
|
||||
- "gpio45",
|
||||
+ "gpio45", "gpio30",
|
||||
};
|
||||
|
||||
static const char * const qdss_cti_trig_in_b1_groups[] = {
|
||||
@@ -679,7 +679,7 @@ static const struct pinfunction ipq5018_
|
||||
|
||||
static const struct msm_pingroup ipq5018_groups[] = {
|
||||
PINGROUP(0, atest_char, _, qdss_cti_trig_out_a0, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
- PINGROUP(1, atest_char, _, qdss_cti_trig_in_a0, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
+ PINGROUP(1, atest_char, pwm1, qdss_cti_trig_in_a0, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(2, atest_char, _, qdss_cti_trig_out_a1, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(3, atest_char, _, qdss_cti_trig_in_a1, wci_txd, wci_rxd, xfem, _, _, _),
|
||||
PINGROUP(4, sdc1_data, qspi_data, blsp1_spi1, btss, dbg_out, qdss_traceclk_a, _, burn0, _),
|
||||
@@ -708,7 +708,7 @@ static const struct msm_pingroup ipq5018
|
||||
PINGROUP(27, audio_txmclk, wsa_swrm, audio_txmclk, blsp2_spi, btss, _, qdss_tracedata_b, _, _),
|
||||
PINGROUP(28, audio_txbclk, wsa_swrm, blsp0_uart1, btss, qdss_tracedata_b, _, _, _, _),
|
||||
PINGROUP(29, audio_txfsync, _, blsp0_uart1, _, qdss_tracedata_b, _, _, _, _),
|
||||
- PINGROUP(30, audio_txd, led2, led0, _, _, _, _, _, _),
|
||||
+ PINGROUP(30, audio_txd, led2, led0, pwm3, _, _, _, _, _),
|
||||
PINGROUP(31, blsp2_spi0, blsp1_uart1, _, qdss_tracedata_b, eud_gpio, _, _, _, _),
|
||||
PINGROUP(32, blsp2_spi0, blsp1_uart1, _, qdss_tracedata_b, eud_gpio, _, _, _, _),
|
||||
PINGROUP(33, blsp2_i2c0, blsp2_spi0, blsp1_uart1, _, qdss_tracedata_b, eud_gpio, _, _, _),
|
||||
@@ -724,7 +724,7 @@ static const struct msm_pingroup ipq5018
|
||||
PINGROUP(43, pwm1, qdss_cti_trig_in_b0, wci_txd, wci_rxd, xfem, _, _, _, _),
|
||||
PINGROUP(44, pwm2, qdss_cti_trig_out_b1, wci_txd, wci_rxd, xfem, _, _, _, _),
|
||||
PINGROUP(45, pwm3, qdss_cti_trig_in_b1, wci_txd, wci_rxd, xfem, _, _, _, _),
|
||||
- PINGROUP(46, led0, _, _, _, _, _, _, _, _),
|
||||
+ PINGROUP(46, led0, pwm0, _, _, _, _, _, _, _),
|
||||
};
|
||||
|
||||
static const struct msm_pinctrl_soc_data ipq5018_pinctrl = {
|
@ -0,0 +1,27 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add PWM node
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
Add PWM node.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -343,6 +343,16 @@
|
||||
reg = <0x01937000 0x21000>;
|
||||
};
|
||||
|
||||
+ pwm: pwm@1941010 {
|
||||
+ compatible = "qcom,ipq5018-pwm", "qcom,ipq6018-pwm";
|
||||
+ reg = <0x01941010 0x20>;
|
||||
+ clocks = <&gcc GCC_ADSS_PWM_CLK>;
|
||||
+ assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
|
||||
+ assigned-clock-rates = <100000000>;
|
||||
+ #pwm-cells = <2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sdhc_1: mmc@7804000 {
|
||||
compatible = "qcom,ipq5018-sdhci", "qcom,sdhci-msm-v5";
|
||||
reg = <0x7804000 0x1000>;
|
@ -0,0 +1,41 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add crypto nodes
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
Add dma controller and crypto nodes.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -297,6 +297,30 @@
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
|
||||
+ cryptobam: dma-controller@704000 {
|
||||
+ compatible = "qcom,bam-v1.7.0";
|
||||
+ reg = <0x00704000 0x20000>;
|
||||
+ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&gcc GCC_CRYPTO_AHB_CLK>;
|
||||
+ clock-names = "bam_clk";
|
||||
+ #dma-cells = <1>;
|
||||
+ qcom,ee = <1>;
|
||||
+ qcom,controlled-remotely;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ crypto: crypto@73a000 {
|
||||
+ compatible = "qcom,crypto-v5.1";
|
||||
+ reg = <0x0073a000 0x6000>;
|
||||
+ clocks = <&gcc GCC_CRYPTO_AHB_CLK>,
|
||||
+ <&gcc GCC_CRYPTO_AXI_CLK>,
|
||||
+ <&gcc GCC_CRYPTO_CLK>;
|
||||
+ clock-names = "iface", "bus", "core";
|
||||
+ dmas = <&cryptobam 2>, <&cryptobam 3>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
tlmm: pinctrl@1000000 {
|
||||
compatible = "qcom,ipq5018-tlmm";
|
||||
reg = <0x01000000 0x300000>;
|
@ -0,0 +1,25 @@
|
||||
From: George Moussalem <george.moussalem@outlook.com>
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq5018: Add PRNG node
|
||||
Date: Sun, 06 Oct 2024 16:34:11 +0400
|
||||
|
||||
Add PRNG node.
|
||||
|
||||
Signed-off-by: George Moussalem <george.moussalem@outlook.com>
|
||||
---
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
|
||||
@@ -258,6 +258,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ prng: rng@e3000 {
|
||||
+ compatible = "qcom,prng-ee";
|
||||
+ reg = <0x000e3000 0x1000>;
|
||||
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
|
||||
+ clock-names = "core";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
tsens: thermal-sensor@4a9000 {
|
||||
compatible = "qcom,ipq5018-tsens";
|
||||
reg = <0x4a9000 0x1000>, /* TM */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user