This commit is contained in:
lean 2022-02-19 00:49:25 +08:00
commit e4b3e57456
111 changed files with 73 additions and 15632 deletions

View File

@ -6,7 +6,7 @@ define KernelPackage/camera-bcm2835
TITLE:=BCM2835 Camera
KCONFIG:= \
CONFIG_VIDEO_BCM2835 \
CONFIG_VIDEO_BCM2835_MMAL \
CONFIG_VIDEO_BCM2835_MMAL \
CONFIG_VIDEO_BCM2835_UNICAM=n \
CONFIG_VIDEO_ISP_BCM2835=n
FILES:= \
@ -22,36 +22,6 @@ endef
$(eval $(call KernelPackage,camera-bcm2835))
define KernelPackage/drm-vc4
SUBMENU:=$(VIDEO_MENU)
TITLE:=Broadcom VC4 Graphics
DEPENDS:= \
@TARGET_bcm27xx +kmod-drm \
+kmod-sound-core \
+kmod-sound-soc-core
KCONFIG:= \
CONFIG_DRM_VC4 \
CONFIG_DRM_VC4_HDMI_CEC=y \
CONFIG_DRM_GUD=n \
CONFIG_DRM_V3D=n \
CONFIG_DRM_TVE200=n
FILES:= \
$(LINUX_DIR)/drivers/gpu/drm/vc4/vc4.ko \
$(LINUX_DIR)/drivers/gpu/drm/drm_kms_helper.ko \
$(LINUX_DIR)/drivers/media/cec/cec.ko@lt5.10 \
$(LINUX_DIR)/drivers/media/cec/core/cec.ko@ge5.10
AUTOLOAD:=$(call AutoProbe,vc4)
endef
define KernelPackage/drm-vc4/description
Direct Rendering Manager (DRM) support for Broadcom VideoCore IV GPU
used in BCM2835, BCM2836 and BCM2837 SoCs (e.g. Raspberry Pi).
endef
$(eval $(call KernelPackage,drm-vc4))
define KernelPackage/vc-sm-cma
TITLE:=VideoCore Shared Memory (CMA) driver
KCONFIG:= \
@ -85,3 +55,31 @@ define KernelPackage/vchiq-mmal-bcm2835/description
endef
$(eval $(call KernelPackage,vchiq-mmal-bcm2835))
define KernelPackage/drm-vc4
SUBMENU:=$(VIDEO_MENU)
TITLE:=Broadcom VC4 Graphics
DEPENDS:= \
@TARGET_bcm27xx +kmod-drm \
+kmod-sound-core \
+kmod-sound-soc-core \
+kmod-drm-kms-helper
KCONFIG:= \
CONFIG_DRM_VC4 \
CONFIG_DRM_VC4_HDMI_CEC=y \
CONFIG_DRM_GUD=n \
CONFIG_DRM_V3D=n \
CONFIG_DRM_TVE200=n
FILES:= \
$(LINUX_DIR)/drivers/gpu/drm/vc4/vc4.ko \
$(LINUX_DIR)/drivers/media/cec/cec.ko@lt5.10 \
$(LINUX_DIR)/drivers/media/cec/core/cec.ko@ge5.10
AUTOLOAD:=$(call AutoProbe,vc4)
endef
define KernelPackage/drm-vc4/description
Direct Rendering Manager (DRM) support for Broadcom VideoCore IV GPU
used in BCM2835, BCM2836 and BCM2837 SoCs (e.g. Raspberry Pi).
endef
$(eval $(call KernelPackage,drm-vc4))

View File

@ -178,6 +178,7 @@ CONFIG_ANON_INODES=y
# CONFIG_ARCH_ACTIONS is not set
# CONFIG_ARCH_AGILEX is not set
# CONFIG_ARCH_ALPINE is not set
# CONFIG_ARCH_APPLE is not set
# CONFIG_ARCH_ARTPEC is not set
# CONFIG_ARCH_ASPEED is not set
# CONFIG_ARCH_AT91 is not set
@ -1833,6 +1834,7 @@ CONFIG_EXTRA_TARGETS=""
# CONFIG_F2FS_FS_POSIX_ACL is not set
# CONFIG_F2FS_FS_SECURITY is not set
CONFIG_F2FS_FS_XATTR=y
# CONFIG_F2FS_IOSTAT is not set
# CONFIG_F2FS_IO_TRACE is not set
CONFIG_F2FS_STAT_FS=y
# CONFIG_FAILOVER is not set
@ -2248,6 +2250,7 @@ CONFIG_HARDEN_EL2_VECTORS=y
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_PID is not set
# CONFIG_HID_PLANTRONICS is not set
# CONFIG_HID_PLAYSTATION is not set
# CONFIG_HID_PRIMAX is not set
# CONFIG_HID_PRODIKEYS is not set
# CONFIG_HID_REDRAGON is not set
@ -2256,6 +2259,7 @@ CONFIG_HARDEN_EL2_VECTORS=y
# CONFIG_HID_ROCCAT is not set
# CONFIG_HID_SAITEK is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SEMITEK is not set
# CONFIG_HID_SENSOR_HUB is not set
# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_SONY is not set
@ -2397,6 +2401,8 @@ CONFIG_HZ_100=y
# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set
# CONFIG_I2C_HELPER_AUTO is not set
# CONFIG_I2C_HID is not set
# CONFIG_I2C_HID_OF is not set
# CONFIG_I2C_HID_OF_GOODIX is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_IBM_IIC is not set
# CONFIG_I2C_IMG is not set
@ -3747,6 +3753,7 @@ CONFIG_NETDEVICES=y
# CONFIG_NETFILTER_NETLINK_OSF is not set
# CONFIG_NETFILTER_NETLINK_QUEUE is not set
# CONFIG_NETFILTER_XTABLES is not set
# CONFIG_NETFILTER_XTABLES_COMPAT is not set
# CONFIG_NETFILTER_XT_CONNMARK is not set
# CONFIG_NETFILTER_XT_MARK is not set
# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
@ -4712,6 +4719,7 @@ CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_RALINK is not set
# CONFIG_RANDOM32_SELFTEST is not set
# CONFIG_RANDOMIZE_BASE is not set
# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RAPIDIO is not set
@ -5200,6 +5208,7 @@ CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_SENSORS_BH1780 is not set
# CONFIG_SENSORS_CORETEMP is not set
# CONFIG_SENSORS_CORSAIR_CPRO is not set
# CONFIG_SENSORS_CORSAIR_PSU is not set
# CONFIG_SENSORS_DELL_SMM is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_DRIVETEMP is not set
@ -5310,6 +5319,7 @@ CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_SENSORS_NPCM7XX is not set
# CONFIG_SENSORS_NSA320 is not set
# CONFIG_SENSORS_NTC_THERMISTOR is not set
# CONFIG_SENSORS_NZXT_KRAKEN2 is not set
# CONFIG_SENSORS_OCC_P8_I2C is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
@ -6741,6 +6751,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_ROLE_SWITCH is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_RTL8152 is not set
# CONFIG_USB_RTL8153_ECM is not set
# CONFIG_USB_S2255 is not set
# CONFIG_USB_SERIAL is not set
# CONFIG_USB_SERIAL_AIRCABLE is not set

View File

@ -1,18 +0,0 @@
. /lib/functions/leds.sh
. /lib/functions/uci-defaults.sh
board=$(board_name)
board_config_update
case $board in
xiaomi,ax3600|\
redmi,ax6)
ucidef_set_led_netdev "wan" "WAN" "blue:network" "eth0"
;;
esac
board_config_flush
exit 0

View File

@ -1,31 +0,0 @@
#
# Copyright (c) 2015 The Linux Foundation. All rights reserved.
# Copyright (c) 2011-2015 OpenWrt.org
#
. /lib/functions/uci-defaults.sh
. /lib/functions/system.sh
ipq60xx_setup_interfaces()
{
local board="$1"
case "$board" in
*"GL-AX1800"*)
ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4" "eth0"
;;
wf,hr6001)
ucidef_set_interfaces_lan_wan "eth0 eth1 eth2 eth3" "eth4"
;;
*)
echo "Unsupported hardware. Network interfaces not initialized"
;;
esac
}
board_config_update
board=$(board_name)
ipq60xx_setup_interfaces $board
board_config_flush
exit 0

View File

@ -1,27 +0,0 @@
#!/bin/sh
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions/caldata.sh
board=$(board_name)
case "$FIRMWARE" in
"ath10k/cal-pci-0000:01:00.0.bin")
case "$board" in
xiaomi,ax3600)
caldata_extract "0:art" 0x33000 0x844
;;
esac
;;
"ath10k/cal-pci-0001:01:00.0.bin")
case "$board" in
xiaomi,ax9000)
caldata_extract "0:art" 0x4d000 0x844
;;
esac
;;
*)
exit 1
;;
esac

View File

@ -1,33 +0,0 @@
#!/bin/sh
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions/caldata.sh
board=$(board_name)
case "$FIRMWARE" in
"ath11k/IPQ8074/hw2.0/caldata.bin")
case "$board" in
netgear,sxr80|\
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
caldata_extract "0:art" 0x1000 0x20000
;;
zte,mf269)
caldata_extract "0:ART" 0x1000 0x20000
;;
esac
;;
"ath11k/IPQ6018/hw1.0/caldata.bin")
case "$board" in
wf,hr6001)
caldata_extract "0:ART" 0x1000 0x20000
;;
esac
;;
*)
exit 1
;;
esac

View File

@ -1,22 +0,0 @@
PART_NAME=firmware
REQUIRE_IMAGE_METADATA=1
RAMFS_COPY_BIN='fw_printenv fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
return 0;
}
platform_do_upgrade() {
case "$(board_name)" in
*GL-AX1800* |\
wf,hr6001)
CI_UBIPART="rootfs"
nand_do_upgrade "$1"
;;
*)
default_do_upgrade "$1"
;;
esac
}

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
&CPU0 {
operating-points-v2 = <&cpu_opp_table>;
};
&CPU1 {
operating-points-v2 = <&cpu_opp_table>;
};
&CPU2 {
operating-points-v2 = <&cpu_opp_table>;
};
&CPU3 {
operating-points-v2 = <&cpu_opp_table>;
};
&cpus {
cpu_opp_table: cpu_opp_table {
compatible = "operating-points-v2";
opp-shared;
opp-0 {
opp-hz = /bits/ 64 <0>;
opp-microvolt = <0>;
clock-latency-ns = <200000>;
};
opp-864000000 {
opp-hz = /bits/ 64 <864000000>;
opp-microvolt = <1>;
clock-latency-ns = <200000>;
};
opp-1056000000 {
opp-hz = /bits/ 64 <1056000000>;
opp-microvolt = <2>;
clock-latency-ns = <200000>;
};
opp-1320000000 {
opp-hz = /bits/ 64 <1320000000>;
opp-microvolt = <3>;
clock-latency-ns = <200000>;
};
opp-1440000000 {
opp-hz = /bits/ 64 <1440000000>;
opp-microvolt = <4>;
clock-latency-ns = <200000>;
};
opp-1608000000 {
opp-hz = /bits/ 64 <1608000000>;
opp-microvolt = <5>;
clock-latency-ns = <200000>;
};
opp-1800000000 {
opp-hz = /bits/ 64 <1800000000>;
opp-microvolt = <6>;
clock-latency-ns = <200000>;
};
};
};

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
&CPU0 {
operating-points-v2 = <&cpu_opp_table>;
};
&CPU1 {
operating-points-v2 = <&cpu_opp_table>;
};
&CPU2 {
operating-points-v2 = <&cpu_opp_table>;
};
&CPU3 {
operating-points-v2 = <&cpu_opp_table>;
};
&cpus {
cpu_opp_table: cpu_opp_table {
compatible = "operating-points-v2";
opp-shared;
opp-0 {
opp-hz = /bits/ 64 <0>;
opp-microvolt = <0>;
clock-latency-ns = <200000>;
};
opp-864000000 {
opp-hz = /bits/ 64 <864000000>;
opp-microvolt = <1>;
clock-latency-ns = <200000>;
};
opp-1056000000 {
opp-hz = /bits/ 64 <1056000000>;
opp-microvolt = <2>;
clock-latency-ns = <200000>;
};
opp-1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <2>;
clock-latency-ns = <200000>;
};
};
};

View File

@ -1,523 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* IPQ6018 CP01 board device tree source
*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
*/
/dts-v1/;
#include "ipq6018.dtsi"
#include "ipq6018-cp-cpu.dtsi"
/ {
model = "WF HR6001";
compatible = "qcom,ap-cp01-c3", "qcom,ipq6018";
aliases {
led-boot = &power;
led-failsafe = &power;
led-running = &power;
led-upgrade = &power;
serial0 = &blsp1_uart3;
/*
* Aliases as required by u-boot
* to patch MAC addresses
*/
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
ethernet2 = "/soc/dp3";
ethernet3 = "/soc/dp4";
ethernet4 = "/soc/dp5";
};
chosen {
stdout-path = "serial0:115200n8";
bootargs-append = " ubi.mtd=rootfs root=/dev/ubiblock0_1 swiotlb=1";
};
};
&blsp1_uart3 {
pinctrl-0 = <&serial_3_pins>;
pinctrl-names = "default";
status = "ok";
};
&spi_0 {
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
spi-max-frequency = <50000000>;
SBL1@0 {
label = "0:SBL1";
reg = <0x0 0xc0000>;
read-only;
};
MIBIB@c0000 {
label = "0:MIBIB";
reg = <0xc0000 0x10000>;
};
BOOTCONFIG@d0000 {
label = "0:BOOTCONFIG";
reg = <0xd0000 0x20000>;
read-only;
};
BOOTCONFIG1@f0000 {
label = "0:BOOTCONFIG1";
reg = <0xf0000 0x20000>;
read-only;
};
QSEE@110000 {
label = "0:QSEE";
reg = <0x110000 0x1a0000>;
read-only;
};
QSEE_1@2b0000 {
label = "0:QSEE_1";
reg = <0x2b0000 0x1a0000>;
read-only;
};
DEVCFG@450000 {
label = "0:DEVCFG";
reg = <0x450000 0x10000>;
read-only;
};
DEVCFG_1@460000 {
label = "0:DEVCFG_1";
reg = <0x460000 0x10000>;
read-only;
};
RPM@470000 {
label = "0:RPM";
reg = <0x4700000 0x40000>;
};
RPM_1@4b0000 {
label = "0:RPM_1";
reg = <0x4b0000 0x40000>;
read-only;
};
CDT@4f0000 {
label = "0:CDT";
reg = <0x4f0000 0x10000>;
};
CDT_1@500000 {
label = "0:CDT_1";
reg = <0x500000 0x10000>;
};
APPSBLENV@510000 {
label = "0:APPSBLENV";
reg = <0x510000 0x10000>;
};
APPSBL@520000 {
label = "0:APPSBL";
reg = <0x520000 0xa0000>;
};
APPSBL_1@5c0000 {
label = "0:APPSBL_1";
reg = <0x5c0000 0xa0000>;
};
ART: ART@660000 {
label = "0:ART";
reg = <0x660000 0x40000>;
};
};
};
&tlmm {
spi_0_pins: spi-0-pins {
pins = "gpio38", "gpio39", "gpio40", "gpio41";
function = "blsp0_spi";
drive-strength = <8>;
bias-pull-down;
};
sd_pins: sd-pinmux {
pins = "gpio62";
function = "sd_card";
drive-strength = <8>;
bias-pull-up;
};
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
mdio_pins: mdio_pinmux {
mux_0 {
pins = "gpio64";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio65";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
mux_2 {
pins = "gpio75";
function = "gpio";
bias-pull-up;
};
mux_3 {
pins = "gpio77";
function = "gpio";
bias-pull-up;
};
};
button_pins: button_pins {
reset_button {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
led_pins: leds_pins {
wlan5g {
pins = "gpio35";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
wlan2g {
pins = "gpio37";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan1 {
pins = "gpio51";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan2 {
pins = "gpio24";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan3 {
pins = "gpio53";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan4 {
pins = "gpio25";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
wan {
pins = "gpio9";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
mdio: mdio@90000 {
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 75 0 &tlmm 77 1>;
status = "ok";
phy0: ethernet-phy@0 {
reg = <0>;
};
phy1: ethernet-phy@1 {
reg = <1>;
};
phy2: ethernet-phy@2 {
reg = <2>;
};
phy3: ethernet-phy@3 {
reg = <3>;
};
phy4: ethernet-phy@4 {
reg = <0x18>;
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a001000 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <0>;
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a001200 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <1>;
phy-mode = "sgmii";
};
dp3 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <3>;
reg = <0x3a001400 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <2>;
phy-mode = "sgmii";
};
dp4 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <4>;
reg = <0x3a001600 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
phy-mode = "sgmii";
};
dp5 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <5>;
reg = <0x3a001800 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <24>;
phy-mode = "sgmii";
};
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x20>; /* wan port bitmap */
switch_inner_bmp = <0xc0>; /*inner port bitmap*/
switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <0>;
};
port@1 {
port_id = <2>;
phy_address = <1>;
};
port@2 {
port_id = <3>;
phy_address = <2>;
};
port@3 {
port_id = <4>;
phy_address = <3>;
};
port@4 {
port_id = <5>;
phy_address = <0x18>;
port_mac_sel = "QGMAC_PORT";
};
};
};
nss-macsec0 {
compatible = "qcom,nss-macsec";
phy_addr = <0x18>;
phy_access_mode = <0>;
mdiobus = <&mdio>;
};
sd_pwrseq: sd-pwrseq {
compatible = "mmc-pwrseq-ipq";
reset-gpios = <&tlmm 66 GPIO_ACTIVE_HIGH>;
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led@35 {
label = "green:wlan5g";
gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
};
power: led@37 {
label = "green:wlan2g";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
};
led@51 {
label = "green:lan1";
gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
};
led@24 {
label = "green:lan2";
gpios = <&tlmm 24 GPIO_ACTIVE_HIGH>;
};
led@53 {
label = "green:lan3";
gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
};
led@25 {
label = "green:lan4";
gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
};
led@31 {
label = "green:wan";
gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
};
};
};
&qpic_bam {
status = "ok";
};
&qpic_nand {
status = "ok";
nand@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
nand-bus-width = <8>;
partition0@ {
label = "rootfs";
reg = <0x0 0x3c00000>;
};
partition1@0x8000000 {
label = "rootfs_1";
reg = <0x3c00000 0x3c00000>;
};
};
};
&pcie_phy {
status = "ok";
};
&pcie0 {
status = "ok";
};
&qusb_phy_1 {
status = "ok";
};
&usb2 {
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
status = "ok";
};
&qusb_phy_0 {
status = "ok";
};
&ssphy_0 {
status = "ok";
};
&usb3 {
status = "ok";
};
&nss_crypto {
status = "ok";
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
mmc-pwrseq = <&sd_pwrseq>;
cd-gpios = <&tlmm 62 1>;
sd-ldo-gpios = <&tlmm 66 0>;
vqmmc-supply = <&ipq6018_l2>;
status = "ok";
};

View File

@ -1,392 +0,0 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/ {
#ifdef __IPQ_MEM_PROFILE_256_MB__
MP_256;
#elif __IPQ_MEM_PROFILE_512_MB__
MP_512;
#endif
#ifdef __IPQ_MEM_PROFILE_256_MB__
/* 256 MB Profile
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | NSS | 0x40000000 | 8MB |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x40800000 | 153MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | uboot | 0x4A100000 | 4MB |
* | | | |
* +--------+--------------+-------------------------+
* | SBL | 0x4A500000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | TZ+HYP | 0x4A600000 | 4MB |
* | | | |
* +--------+--------------+-------------------------+
* | smem | 0x4AA00000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | WLAN | | |
* | Q6 | 0x4AB00000 | 40MB |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | WLAN | | |
* | Q6 ETR | 0x4D300000 | 1MB |
* | Region | | |
* +--------+--------------+-------------------------+
* | M3 Dump| 0x4D400000 | 1MB |
* +=================================================+
* | |
* | |
* | |
* | 43MB memory for Linux |
* | |
* | |
* | |
* +=================================================+
*/
memory {
device_type = "memory";
reg = <0x0 0x40000000 0x0 0x10000000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
nss@40000000 {
no-map;
reg = <0x0 0x40000000 0x0 0x00800000>;
};
tzapp: tzapp@49B00000 { /* TZAPPS */
no-map;
};
uboot@4A100000 {
no-map;
reg = <0x0 0x4A100000 0x0 0x00400000>;
};
sbl@4A500000 {
no-map;
reg = <0x0 0x4A500000 0x0 0x00100000>;
};
tz@4A600000 {
no-map;
reg = <0x0 0x4A600000 0x0 0x00400000>;
};
smem_region:smem@4AA00000 {
no-map;
reg = <0x0 0x4AA00000 0x0 0x00100000>;
};
q6_region: wcnss@4ab00000 {
no-map;
reg = <0x0 0x4ab00000 0x0 0x02800000>;
};
q6_etr_region: q6_etr_dump@1 {
no-map;
reg = <0x0 0x4D300000 0x0 0x100000>;
};
m3_dump@4d400000 {
no-map;
reg = <0x0 0x4d400000 0x0 0x100000>;
};
rpm_msg_ram: rpm_msg_ram@0x60000 {
no-map;
reg = <0x0 0x60000 0x0 0x6000>;
};
};
#elif __IPQ_MEM_PROFILE_512_MB__
/* 512 MB Profile
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | NSS | 0x40000000 | 16MB |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 145MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | uboot | 0x4A100000 | 4MB |
* | | | |
* +--------+--------------+-------------------------+
* | SBL | 0x4A500000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | TZ+HYP | 0x4A600000 | 4MB |
* | | | |
* +--------+--------------+-------------------------+
* | smem | 0x4AA00000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | WLAN | | |
* | Q6 | 0x4AB00000 | 55MB |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | WLAN | | |
* | Q6 ETR | 0x4E200000 | 1MB |
* | Region | | |
* +--------+--------------+-------------------------+
* | M3 Dump| 0x4E300000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | Pine | 0x4E400000 | 30MB |
* | | | (on CP01-C3 RDP only) |
* +--------+--------------+-------------------------+
* | | | |
* | MHI0 | 0x50200000 | 16MB |
* | | | (on CP01-C3 RDP only) |
* +=================================================+
* | |
* | |
* | |
* | Remaining memory for Linux |
* | |
* | |
* | |
* +=================================================+
*/
memory {
device_type = "memory";
reg = <0x0 0x40000000 0x0 0x20000000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
nss@40000000 {
no-map;
reg = <0x0 0x40000000 0x0 0x01000000>;
};
tzapp: tzapp@49B00000 { /* TZAPPS */
no-map;
};
uboot@4A100000 {
no-map;
reg = <0x0 0x4A100000 0x0 0x00400000>;
};
sbl@4A500000 {
no-map;
reg = <0x0 0x4A500000 0x0 0x00100000>;
};
tz@4A600000 {
no-map;
reg = <0x0 0x4A600000 0x0 0x00400000>;
};
smem_region:smem@4AA00000 {
no-map;
reg = <0x0 0x4AA00000 0x0 0x00100000>;
};
q6_region: wcnss@4ab00000 {
no-map;
reg = <0x0 0x4ab00000 0x0 0x03700000>;
};
q6_etr_region: q6_etr_dump@1 {
no-map;
reg = <0x0 0x4E200000 0x0 0x100000>;
};
m3_dump@4e300000 {
no-map;
reg = <0x0 0x4e300000 0x0 0x100000>;
};
rpm_msg_ram: rpm_msg_ram@0x60000 {
no-map;
reg = <0x0 0x60000 0x0 0x6000>;
};
};
#else
/* Default Profile
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | NSS | 0x40000000 | 16MB |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | TZ App | 0x49B00000 | 6MB |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | uboot | 0x4A100000 | 4MB |
* | | | |
* +--------+--------------+-------------------------+
* | SBL | 0x4A500000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | TZ+HYP | 0x4A600000 | 4MB |
* | | | |
* +--------+--------------+-------------------------+
* | smem | 0x4AA00000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | WLAN | | |
* | Q6 | 0x4AB00000 | 85MB |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | WLAN | | |
* | Q6 ETR | 0x50000000 | 1MB |
* | Region | | |
* +--------+--------------+-------------------------+
* | M3 Dump| 0x50100000 | 1MB |
* +--------+--------------+-------------------------+
* | | | |
* | Pine | 0x50200000 | 45MB |
* | | | (on CP01-C3 RDP only) |
* +--------+--------------+-------------------------+
* | | | |
* | MHI0 | 0x52F00000 | 24MB |
* | | | (on CP01-C3 RDP only) |
* +=================================================+
* | |
* | |
* | |
* | Remaining memory for Linux |
* | |
* | |
* | |
* +=================================================+
*/
memory {
device_type = "memory";
reg = <0x0 0x40000000 0x0 0x40000000>;
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
nss@40000000 {
no-map;
reg = <0x0 0x40000000 0x0 0x01000000>;
};
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
uboot@4A100000 {
no-map;
reg = <0x0 0x4A100000 0x0 0x00400000>;
};
sbl@4A500000 {
no-map;
reg = <0x0 0x4A500000 0x0 0x00100000>;
};
tz@4A600000 {
no-map;
reg = <0x0 0x4A600000 0x0 0x00400000>;
};
smem_region: smem@4AA00000 {
no-map;
reg = <0x0 0x4AA00000 0x0 0x00100000>;
};
q6_region: wcnss@4ab00000 {
no-map;
reg = <0x0 0x4ab00000 0x0 0x05500000>;
};
q6_etr_region: q6_etr_dump@1 {
no-map;
reg = <0x0 0x50000000 0x0 0x100000>;
};
m3_dump@50100000 {
no-map;
reg = <0x0 0x50100000 0x0 0x100000>;
};
rpm_msg_ram: rpm_msg_ram@0x60000 {
no-map;
reg = <0x0 0x60000 0x0 0x6000>;
};
};
#endif
};

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
&soc {
apc_apm: apm@b111000 {
compatible = "qcom,ipq807x-apm";
reg = <0x0 0xb111000 0x0 0x1000>;
reg-names = "pm-apcc-glb";
qcom,apm-post-halt-delay = <0x2>;
qcom,apm-halt-clk-delay = <0x11>;
qcom,apm-resume-clk-delay = <0x10>;
qcom,apm-sel-switch-delay = <0x01>;
};
apc_cpr: cpr4-ctrl@b018000 {
compatible = "qcom,cpr4-ipq6018-apss-regulator";
reg = <0x0 0xb018000 0x0 0x4000>, <0x0 0xa4000 0x0 0x1000>, <0x0 0x0193d008 0x0 0x4>;
reg-names = "cpr_ctrl", "fuse_base", "cpr_tcsr_reg";
interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "cpr";
qcom,cpr-ctrl-name = "apc";
qcom,cpr-sensor-time = <1000>;
qcom,cpr-loop-time = <5000000>;
qcom,cpr-idle-cycles = <15>;
qcom,cpr-step-quot-init-min = <0>;
qcom,cpr-step-quot-init-max = <15>;
qcom,cpr-count-mode = <0>; /* All-at-once */
qcom,cpr-count-repeat = <1>;
qcom,cpr-down-error-step-limit = <1>;
qcom,cpr-up-error-step-limit = <1>;
qcom,apm-ctrl = <&apc_apm>;
qcom,apm-threshold-voltage = <850000>;
vdd-supply = <&ipq6018_s2>;
qcom,voltage-step = <12500>;
thread@0 {
qcom,cpr-thread-id = <0>;
qcom,cpr-consecutive-up = <2>;
qcom,cpr-consecutive-down = <2>;
qcom,cpr-up-threshold = <2>;
qcom,cpr-down-threshold = <2>;
apc_vreg: regulator {
regulator-name = "apc_corner";
regulator-min-microvolt = <1>;
regulator-max-microvolt = <6>;
qcom,cpr-fuse-corners = <4>;
qcom,cpr-fuse-combos = <8>;
qcom,cpr-corners = <6>;
qcom,cpr-speed-bins = <1>;
qcom,cpr-speed-bin-corners = <6>;
qcom,cpr-corner-fmax-map = <1 3 5 6>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
qcom,cpr-voltage-ceiling =
<725000 787500 862500
925000 987500 1062500>;
qcom,cpr-voltage-floor =
<587500 650000 712500
750000 787500 850000>;
qcom,corner-frequencies =
<864000000 1056000000 1320000000
1440000000 1608000000 1800000000>;
qcom,cpr-ro-sel =
/* Speed bin 0; CPR rev 0..7 */
< 0 0 0 0>,
< 7 7 7 7>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>;
qcom,cpr-open-loop-voltage-fuse-adjustment =
/* Speed bin 0; CPR rev 0..7 */
/* SVS Nominal Turbo Turbo_L1 */
< 0 0 0 0>,
< 0 0 15000 0>,
< 0 0 15000 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
/* Speed bin 0; CPR rev 0..7 */
< 0 0 0 0>,
< 13000 0 13000 13000>,
< 13000 0 13000 13000>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>,
< 0 0 0 0>;
qcom,cpr-ro-scaling-factor =
< 2000 1770 1900 1670 1930 1770 1910 1800
1870 1730 2000 1840 1800 2030 1700 1890 >,
< 2000 1770 1900 1670 1930 1770 1910 1800
1870 1730 2000 1840 1800 2030 1700 1890 >,
< 2000 1770 1900 1670 1930 1770 1910 1800
1870 1730 2000 1840 1800 2030 1700 1890 >,
< 2000 1770 1900 1670 1930 1770 1910 1800
1870 1730 2000 1840 1800 2030 1700 1890 >;
};
};
};
};

View File

@ -1,436 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* IPQ6018 CP01 board device tree source
*
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
*/
/dts-v1/;
#include "ipq6018.dtsi"
#include "ipq6018-cp-cpu.dtsi"
/ {
model = "GL-AX1800 IPQ6018/AP-CP03-C1";
compatible = "qcom,ipq6018-cp03", "qcom,ipq6018";
aliases {
led-boot = &power;
led-failsafe = &power;
led-running = &power;
led-upgrade = &power;
serial0 = &blsp1_uart3;
/*
* Aliases as required by u-boot
* to patch MAC addresses
*/
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
ethernet2 = "/soc/dp3";
ethernet3 = "/soc/dp4";
ethernet4 = "/soc/dp5";
};
chosen {
stdout-path = "serial0:115200n8";
bootargs-append = " ubi.mtd=rootfs root=/dev/ubiblock0_1 swiotlb=1";
};
};
&blsp1_uart3 {
pinctrl-0 = <&serial_3_pins>;
pinctrl-names = "default";
status = "ok";
};
&spi_0 {
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
&tlmm {
spi_0_pins: spi-0-pins {
pins = "gpio38", "gpio39", "gpio40", "gpio41";
function = "blsp0_spi";
drive-strength = <8>;
bias-pull-down;
};
sd_pins: sd-pinmux {
pins = "gpio62";
function = "sd_card";
drive-strength = <8>;
bias-pull-up;
};
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
mdio_pins: mdio_pinmux {
mux_0 {
pins = "gpio64";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio65";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
mux_2 {
pins = "gpio75";
function = "gpio";
bias-pull-up;
};
mux_3 {
pins = "gpio77";
function = "gpio";
bias-pull-up;
};
};
button_pins: button_pins {
reset_button {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
led_pins: leds_pins {
wlan5g {
pins = "gpio35";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
wlan2g {
pins = "gpio37";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan1 {
pins = "gpio51";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan2 {
pins = "gpio24";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan3 {
pins = "gpio53";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
lan4 {
pins = "gpio25";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
wan {
pins = "gpio9";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
mdio: mdio@90000 {
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 75 0 &tlmm 77 1>;
status = "ok";
phy0: ethernet-phy@0 {
reg = <0>;
};
phy1: ethernet-phy@1 {
reg = <1>;
};
phy2: ethernet-phy@2 {
reg = <2>;
};
phy3: ethernet-phy@3 {
reg = <3>;
};
phy4: ethernet-phy@4 {
reg = <0x18>;
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a001000 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <0>;
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a001200 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <1>;
phy-mode = "sgmii";
};
dp3 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <3>;
reg = <0x3a001400 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <2>;
phy-mode = "sgmii";
};
dp4 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <4>;
reg = <0x3a001600 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
phy-mode = "sgmii";
};
dp5 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <5>;
reg = <0x3a001800 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <24>;
phy-mode = "sgmii";
};
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x20>; /* wan port bitmap */
switch_inner_bmp = <0xc0>; /*inner port bitmap*/
switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <0>;
};
port@1 {
port_id = <2>;
phy_address = <1>;
};
port@2 {
port_id = <3>;
phy_address = <2>;
};
port@3 {
port_id = <4>;
phy_address = <3>;
};
port@4 {
port_id = <5>;
phy_address = <0x18>;
port_mac_sel = "QGMAC_PORT";
};
};
};
nss-macsec0 {
compatible = "qcom,nss-macsec";
phy_addr = <0x18>;
phy_access_mode = <0>;
mdiobus = <&mdio>;
};
sd_pwrseq: sd-pwrseq {
compatible = "mmc-pwrseq-ipq";
reset-gpios = <&tlmm 66 GPIO_ACTIVE_HIGH>;
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led@35 {
label = "green:wlan5g";
gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
};
power: led@37 {
label = "green:wlan2g";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
};
led@51 {
label = "green:lan1";
gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
};
led@24 {
label = "green:lan2";
gpios = <&tlmm 24 GPIO_ACTIVE_HIGH>;
};
led@53 {
label = "green:lan3";
gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
};
led@25 {
label = "green:lan4";
gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
};
led@31 {
label = "green:wan";
gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
};
};
};
&qpic_bam {
status = "ok";
};
&qpic_nand {
status = "ok";
nand@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
nand-bus-width = <8>;
partition0@ {
label = "rootfs";
reg = <0x0 0x3c00000>;
};
partition1@0x8000000 {
label = "rootfs_1";
reg = <0x3c00000 0x3c00000>;
};
};
};
&pcie_phy {
status = "ok";
};
&pcie0 {
status = "ok";
};
&qusb_phy_1 {
status = "ok";
};
&usb2 {
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
status = "ok";
};
&qusb_phy_0 {
status = "ok";
};
&ssphy_0 {
status = "ok";
};
&usb3 {
status = "ok";
};
&nss_crypto {
status = "ok";
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
mmc-pwrseq = <&sd_pwrseq>;
cd-gpios = <&tlmm 62 1>;
sd-ldo-gpios = <&tlmm 66 0>;
vqmmc-supply = <&ipq6018_l2>;
status = "ok";
};

View File

@ -1,154 +0,0 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
&rpm_bus {
rpm-regulator-smpa1 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "smpa";
qcom,resource-id = <1>;
qcom,regulator-type = <1>;
qcom,hpm-min-load = <100000>;
status = "disabled";
ipq6018_s1_corner: regulator-s1 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_s1";
qcom,set = <3>;
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <987500>;
qcom,always-send-voltage;
status = "disabled";
};
};
rpm-regulator-smpa2 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "smpa";
qcom,resource-id = <2>;
qcom,regulator-type = <1>;
status = "ok";
ipq6018_s2_corner: regulator-s2 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_s2";
regulator-min-microvolt = <587500>;
regulator-max-microvolt = <1100000>;
qcom,always-send-voltage;
qcom,set = <3>;
status = "ok";
};
};
rpm-regulator-smpa3 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "smpa";
qcom,resource-id = <3>;
qcom,regulator-type = <1>;
qcom,hpm-min-load = <100000>;
status = "disabled";
ipq6018_s3_corner: regulator-s3 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_s3";
regulator-min-microvolt = <640000>;
regulator-max-microvolt = <780000>;
qcom,set = <3>;
status = "disabled";
};
};
rpm-regulator-smpa4 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "smpa";
qcom,resource-id = <4>;
qcom,regulator-type = <1>;
qcom,hpm-min-load = <100000>;
status = "disabled";
ipq6018_s5_corner: regulator-s5 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_s4";
qcom,set = <1>;
status = "disabled";
};
};
rpm-regulator-ldoa2 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "ldoa";
qcom,resource-id = <2>;
qcom,regulator-type = <0>;
status = "ok";
ipq6018_l2_corner: regulator-l2 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_l2";
regulator-min-microvolt = <1104000>;
regulator-max-microvolt = <3300000>;
qcom,always-send-voltage;
qcom,set = <3>;
status = "ok";
};
};
rpm-regulator-ldoa3 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "ldoa";
qcom,resource-id = <3>;
qcom,regulator-type = <0>;
qcom,hpm-min-load = <10000>;
status = "disabled";
ipq6018_l3_corner: regulator-l3 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_l3";
qcom,set = <3>;
status = "disabled";
};
};
rpm-regulator-ldoa4 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "ldoa";
qcom,resource-id = <4>;
qcom,regulator-type = <0>;
qcom,hpm-min-load = <10000>;
status = "disabled";
ipq6018_l4_corner: regulator-l4 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_l4";
qcom,set = <3>;
status = "disabled";
};
};
rpm-regulator-ldoa5 {
compatible = "qcom,rpm-glink-regulator-resource";
qcom,resource-name = "ldoa";
qcom,resource-id = <5>;
qcom,regulator-type = <0>;
qcom,hpm-min-load = <10000>;
status = "disabled";
ipq6018_l5_corner: regulator-l5 {
compatible = "qcom,rpm-glink-regulator";
regulator-name = "ipq6018_l5";
qcom,set = <3>;
status = "disabled";
};
};
};

View File

@ -1,376 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2021 Sartura Ltd.
*
* Driver for the SMSC/Microchip EMC2301/2/3/5 fan controller.
*
* Author: Robert Marko <robert.marko@sartura.hr>
*/
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#define MANUFACTURER_ID_REG 0xfe
#define SMSC_MANUFACTURER_ID 0x5d
#define PRODUCT_ID_REG 0xfd
#define EMC2305_PRODUCT_ID 0x34
#define EMC2303_PRODUCT_ID 0x35
#define EMC2302_PRODUCT_ID 0x36
#define EMC2301_PRODUCT_ID 0x37
#define TACH1_HIGH_BYTE 0x3e
#define TACH1_LOW_BYTE 0x3f
#define FAN1_CONFIG 0x32
#define FAN_TACH_RANGE_MASK GENMASK(6, 5)
#define FAN_TACH_MULTIPLIER_8 3
#define FAN_TACH_MULTIPLIER_4 2
#define FAN_TACH_MULTIPLIER_2 1
#define FAN_TACH_MULTIPLIER_1 0
#define FAN_TACH_CONSTANT 3932160
#define FAN_TACH_READING_MASK GENMASK(15,3)
#define TACH1_TARGET_LOW_BYTE 0x3c
#define TACH1_TARGET_HIGH_BYTE 0x3d
#define TACH_HIGH_MASK GENMASK(12,5)
#define TACH_LOW_MASK GENMASK(4,0)
#define FANX_OFFSET 0x10
#define FAN_NUM_MAX 5
struct emc2305_fan_data {
u32 min_rpm;
u32 max_rpm;
u32 target_rpm;
};
struct emc2305_data {
struct regmap *regmap;
struct i2c_client *client;
struct emc2305_fan_data fan_data[FAN_NUM_MAX];
};
static struct regmap_config emc2305_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
};
static int emc2305_read_fan(struct emc2305_data *data, int channel,
long *val)
{
unsigned int regval, high_byte, low_byte;
u8 range, multiplier;
int ret;
ret = regmap_read(data->regmap,
FAN1_CONFIG + channel * FANX_OFFSET,
&regval);
if (ret < 0)
return ret;
range = FIELD_GET(FAN_TACH_RANGE_MASK, regval);
switch (range) {
case FAN_TACH_MULTIPLIER_8:
multiplier = 8;
break;
case FAN_TACH_MULTIPLIER_4:
multiplier = 4;
break;
case FAN_TACH_MULTIPLIER_2:
multiplier = 2;
break;
case FAN_TACH_MULTIPLIER_1:
multiplier = 1;
break;
default:
return -EINVAL;
}
ret = regmap_read(data->regmap,
TACH1_HIGH_BYTE + channel * FANX_OFFSET,
&high_byte);
if (ret < 0)
return ret;
ret = regmap_read(data->regmap,
TACH1_LOW_BYTE + channel * FANX_OFFSET,
&low_byte);
if (ret < 0)
return ret;
regval = (u8) high_byte << 8 | (u8) low_byte;
*val = (FAN_TACH_CONSTANT * multiplier) / FIELD_GET(FAN_TACH_READING_MASK, regval);
return 0;
}
static int emc2305_read_fan_target(struct emc2305_data *data, int channel,
long *val)
{
unsigned int regval;
int ret;
ret = regmap_bulk_read(data->regmap,
TACH1_TARGET_LOW_BYTE + channel * FANX_OFFSET,
&regval,
2);
if (ret < 0)
return ret;
*val = regval;
return 0;
}
static int emc2305_set_fan_target(struct emc2305_data *data, int channel,
long val)
{
int ret;
ret = regmap_write(data->regmap,
TACH1_TARGET_LOW_BYTE + channel * FANX_OFFSET,
val & TACH_LOW_MASK);
if (ret < 0)
return ret;
ret = regmap_write(data->regmap,
TACH1_TARGET_HIGH_BYTE + channel * FANX_OFFSET,
(val & TACH_HIGH_MASK) >> 5);
if (ret < 0)
return ret;
return 0;
}
static int emc2305_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{
struct emc2305_data *data = dev_get_drvdata(dev);
int err;
switch (type) {
case hwmon_fan:
switch (attr) {
case hwmon_fan_target:
err = emc2305_set_fan_target(data, channel, val);
break;
default:
return -EOPNOTSUPP;
}
break;
default:
return -EOPNOTSUPP;
}
return err;
}
static int emc2305_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{
struct emc2305_data *data = dev_get_drvdata(dev);
int err;
switch (type) {
case hwmon_fan:
switch (attr) {
case hwmon_fan_input:
err = emc2305_read_fan(data, channel, val);
break;
case hwmon_fan_target:
err = emc2305_read_fan_target(data, channel, val);
break;
default:
return -EOPNOTSUPP;
}
break;
default:
return -EOPNOTSUPP;
}
return err;
}
static const char * const emc2305_fan_label[] = {
"Fan1",
"Fan2",
"Fan3",
"Fan4",
"Fan5",
};
static int emc2305_read_string(struct device *dev,
enum hwmon_sensor_types type,
u32 attr, int channel, const char **str)
{
switch (type) {
case hwmon_fan:
*str = emc2305_fan_label[channel];
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
static umode_t emc2305_is_visible(const void *data, enum hwmon_sensor_types type,
u32 attr, int channel)
{
switch (type) {
case hwmon_fan:
switch (attr) {
case hwmon_fan_input:
case hwmon_fan_label:
return 0444;
case hwmon_fan_target:
return 0644;
default:
return 0;
}
default:
return 0;
}
}
static const struct hwmon_channel_info *emc2301_info[] = {
HWMON_CHANNEL_INFO(fan,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL),
NULL
};
static const struct hwmon_channel_info *emc2302_info[] = {
HWMON_CHANNEL_INFO(fan,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL),
NULL
};
static const struct hwmon_channel_info *emc2303_info[] = {
HWMON_CHANNEL_INFO(fan,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL),
NULL
};
static const struct hwmon_channel_info *emc2305_info[] = {
HWMON_CHANNEL_INFO(fan,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL,
HWMON_F_INPUT | HWMON_F_TARGET | HWMON_F_LABEL),
NULL
};
static const struct hwmon_ops emc2305_hwmon_ops = {
.is_visible = emc2305_is_visible,
.write = emc2305_write,
.read = emc2305_read,
.read_string = emc2305_read_string,
};
static struct hwmon_chip_info emc2305_chip_info = {
.ops = &emc2305_hwmon_ops,
};
static int emc2305_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct emc2305_data *data;
struct device *hwmon_dev;
const char *model_name;
unsigned int regval;
int ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->client = client;
i2c_set_clientdata(client, data);
data->regmap = devm_regmap_init_i2c(client, &emc2305_regmap_config);
if (IS_ERR(data->regmap)) {
dev_err(dev, "failed to allocate register map\n");
return PTR_ERR(data->regmap);
}
ret = regmap_read(data->regmap, MANUFACTURER_ID_REG, &regval);
if (ret < 0)
return ret;
if (regval != SMSC_MANUFACTURER_ID) {
dev_err(dev, "Invalid manufacturer id: 0x%x\n", regval);
return -ENODEV;
}
ret = regmap_read(data->regmap, PRODUCT_ID_REG, &regval);
if (ret < 0)
return ret;
switch (regval) {
case EMC2305_PRODUCT_ID:
model_name = "emc2305";
emc2305_chip_info.info = emc2305_info;
break;
case EMC2303_PRODUCT_ID:
model_name = "emc2303";
emc2305_chip_info.info = emc2303_info;
break;
case EMC2302_PRODUCT_ID:
model_name = "emc2302";
emc2305_chip_info.info = emc2302_info;
break;
case EMC2301_PRODUCT_ID:
model_name = "emc2301";
emc2305_chip_info.info = emc2301_info;
break;
default:
dev_err(dev, "Unknown ID detected: 0x%x\n", regval);
return -ENODEV;
}
dev_info(dev, "%s detected\n", model_name);
hwmon_dev = devm_hwmon_device_register_with_info(dev, model_name,
data, &emc2305_chip_info,
NULL);
if (IS_ERR(hwmon_dev))
return PTR_ERR(hwmon_dev);
return 0;
}
static const struct of_device_id emc2305_of_match[] = {
{ .compatible = "smsc,emc2301", },
{ .compatible = "smsc,emc2302", },
{ .compatible = "smsc,emc2303", },
{ .compatible = "smsc,emc2305", },
{ },
};
MODULE_DEVICE_TABLE(of, emc2305_of_match);
static struct i2c_driver emc2305_driver = {
.probe_new = emc2305_probe,
.driver = {
.name = "emc2305",
.of_match_table = of_match_ptr(emc2305_of_match),
},
};
module_i2c_driver(emc2305_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Marko <robert.marko@sartura.hr>");
MODULE_DESCRIPTION("SMSC EMC2301/2/3/5 fan controller");

View File

@ -1 +0,0 @@
BOARDNAME:=Generic

View File

@ -13,6 +13,23 @@ define Device/Default
IMAGE/sysupgrade.bin/squashfs :=
endef
include $(SUBTARGET).mk
define Device/FitImage
KERNEL_SUFFIX := -fit-uImage.itb
KERNEL = kernel-bin | gzip | fit gzip $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := Image
endef
define Device/FitImageLzma
KERNEL_SUFFIX := -fit-uImage.itb
KERNEL = kernel-bin | lzma | fit lzma $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := Image
endef
define Device/UbiFit
KERNEL_IN_UBI := 1
IMAGES := nand-factory.ubi nand-sysupgrade.bin
IMAGE/nand-factory.ubi := append-ubi
IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata
endef
$(eval $(call BuildImage))

View File

@ -1,38 +0,0 @@
define Device/FitImage
KERNEL_SUFFIX := -fit-uImage.itb
KERNEL = kernel-bin | gzip | fit gzip $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := Image
endef
define Device/FitImageLzma
KERNEL_SUFFIX := -fit-uImage.itb
KERNEL = kernel-bin | lzma | fit lzma $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := Image
endef
define Device/FitzImage
KERNEL_SUFFIX := -fit-zImage.itb
KERNEL = kernel-bin | fit none $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := zImage
endef
define Device/UbiFit
KERNEL_IN_UBI := 1
IMAGES := nand-factory.ubi nand-sysupgrade.bin
IMAGE/nand-factory.ubi := append-ubi
IMAGE/nand-sysupgrade.bin := sysupgrade-tar | append-metadata
endef
define Device/wf_hr6001
$(call Device/FitImage)
$(call Device/UbiFit)
DEVICE_VENDOR := WF
DEVICE_MODEL := HR6001
KERNEL_LOADADDR := 0x41000000
BLOCKSIZE := 128k
PAGESIZE := 2048
DEVICE_DTS_CONFIG := config@cp01-c1
SOC := ipq6018
DEVICE_PACKAGES := uboot-envtools
endef
TARGET_DEVICES += wf_hr6001

View File

@ -1,222 +0,0 @@
From c47b1e60f043925ecce585f8c5340c049deda25e Mon Sep 17 00:00:00 2001
From: Bjorn Andersson <bjorn.andersson@linaro.org>
Date: Sat, 21 Nov 2020 21:41:33 -0800
Subject: [PATCH] remoteproc: sysmon: Expose the shutdown result
A graceful shutdown of the Qualcomm remote processors where
traditionally performed by invoking a shared memory state signal and
waiting for the associated ack.
This was later superseded by the "sysmon" mechanism, where some form of
shared memory bus is used to send a "graceful shutdown request" message
and one of more signals comes back to indicate its success.
But when this newer mechanism is in effect the firmware is shut down by
the time the older mechanism, implemented in the remoteproc drivers,
attempts to perform a graceful shutdown - and as such it will never
receive an ack back.
This patch therefor track the success of the latest shutdown attempt in
sysmon and exposes a new function in the API that the remoteproc driver
can use to query the success and the necessity of invoking the older
mechanism.
Tested-by: Steev Klimaszewski <steev@kali.org>
Reviewed-by: Rishabh Bhatnagar <rishabhb@codeaurora.org>
Link: https://lore.kernel.org/r/20201122054135.802935-3-bjorn.andersson@linaro.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_common.h | 6 +++
drivers/remoteproc/qcom_sysmon.c | 82 ++++++++++++++++++++++++--------
2 files changed, 69 insertions(+), 19 deletions(-)
--- a/drivers/remoteproc/qcom_common.h
+++ b/drivers/remoteproc/qcom_common.h
@@ -51,6 +51,7 @@ struct qcom_sysmon *qcom_add_sysmon_subd
const char *name,
int ssctl_instance);
void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon);
+bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon);
#else
static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
const char *name,
@@ -62,6 +63,11 @@ static inline struct qcom_sysmon *qcom_a
static inline void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon)
{
}
+
+static inline bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon)
+{
+ return false;
+}
#endif
#endif
--- a/drivers/remoteproc/qcom_sysmon.c
+++ b/drivers/remoteproc/qcom_sysmon.c
@@ -44,6 +44,7 @@ struct qcom_sysmon {
struct mutex lock;
bool ssr_ack;
+ bool shutdown_acked;
struct qmi_handle qmi;
struct sockaddr_qrtr ssctl;
@@ -115,10 +116,13 @@ out_unlock:
/**
* sysmon_request_shutdown() - request graceful shutdown of remote
* @sysmon: sysmon context
+ *
+ * Return: boolean indicator of the remote processor acking the request
*/
-static void sysmon_request_shutdown(struct qcom_sysmon *sysmon)
+static bool sysmon_request_shutdown(struct qcom_sysmon *sysmon)
{
char *req = "ssr:shutdown";
+ bool acked = false;
int ret;
mutex_lock(&sysmon->lock);
@@ -141,9 +145,13 @@ static void sysmon_request_shutdown(stru
if (!sysmon->ssr_ack)
dev_err(sysmon->dev,
"unexpected response to sysmon shutdown request\n");
+ else
+ acked = true;
out_unlock:
mutex_unlock(&sysmon->lock);
+
+ return acked;
}
static int sysmon_callback(struct rpmsg_device *rpdev, void *data, int count,
@@ -297,14 +305,33 @@ static struct qmi_msg_handler qmi_indica
{}
};
+static bool ssctl_request_shutdown_wait(struct qcom_sysmon *sysmon)
+{
+ int ret;
+
+ ret = wait_for_completion_timeout(&sysmon->shutdown_comp, 10 * HZ);
+ if (ret)
+ return true;
+
+ ret = try_wait_for_completion(&sysmon->ind_comp);
+ if (ret)
+ return true;
+
+ dev_err(sysmon->dev, "timeout waiting for shutdown ack\n");
+ return false;
+}
+
/**
* ssctl_request_shutdown() - request shutdown via SSCTL QMI service
* @sysmon: sysmon context
+ *
+ * Return: boolean indicator of the remote processor acking the request
*/
-static void ssctl_request_shutdown(struct qcom_sysmon *sysmon)
+static bool ssctl_request_shutdown(struct qcom_sysmon *sysmon)
{
struct ssctl_shutdown_resp resp;
struct qmi_txn txn;
+ bool acked = false;
int ret;
reinit_completion(&sysmon->ind_comp);
@@ -312,7 +339,7 @@ static void ssctl_request_shutdown(struc
ret = qmi_txn_init(&sysmon->qmi, &txn, ssctl_shutdown_resp_ei, &resp);
if (ret < 0) {
dev_err(sysmon->dev, "failed to allocate QMI txn\n");
- return;
+ return false;
}
ret = qmi_send_request(&sysmon->qmi, &sysmon->ssctl, &txn,
@@ -320,27 +347,23 @@ static void ssctl_request_shutdown(struc
if (ret < 0) {
dev_err(sysmon->dev, "failed to send shutdown request\n");
qmi_txn_cancel(&txn);
- return;
+ return false;
}
ret = qmi_txn_wait(&txn, 5 * HZ);
- if (ret < 0)
+ if (ret < 0) {
dev_err(sysmon->dev, "failed receiving QMI response\n");
- else if (resp.resp.result)
+ } else if (resp.resp.result) {
dev_err(sysmon->dev, "shutdown request failed\n");
- else
+ } else {
dev_dbg(sysmon->dev, "shutdown request completed\n");
-
- if (sysmon->shutdown_irq > 0) {
- ret = wait_for_completion_timeout(&sysmon->shutdown_comp,
- 10 * HZ);
- if (!ret) {
- ret = try_wait_for_completion(&sysmon->ind_comp);
- if (!ret)
- dev_err(sysmon->dev,
- "timeout waiting for shutdown ack\n");
- }
+ acked = true;
}
+
+ if (sysmon->shutdown_irq > 0)
+ return ssctl_request_shutdown_wait(sysmon);
+
+ return acked;
}
/**
@@ -510,6 +533,9 @@ static void sysmon_stop(struct rproc_sub
.subsys_name = sysmon->name,
.ssr_event = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN
};
+ bool acked;
+
+ sysmon->shutdown_acked = false;
mutex_lock(&sysmon->state_lock);
sysmon->state = SSCTL_SSR_EVENT_BEFORE_SHUTDOWN;
@@ -521,9 +547,11 @@ static void sysmon_stop(struct rproc_sub
return;
if (sysmon->ssctl_version)
- ssctl_request_shutdown(sysmon);
+ acked = ssctl_request_shutdown(sysmon);
else if (sysmon->ept)
- sysmon_request_shutdown(sysmon);
+ acked = sysmon_request_shutdown(sysmon);
+
+ sysmon->shutdown_acked = acked;
}
static void sysmon_unprepare(struct rproc_subdev *subdev)
@@ -682,6 +710,22 @@ void qcom_remove_sysmon_subdev(struct qc
EXPORT_SYMBOL_GPL(qcom_remove_sysmon_subdev);
/**
+ * qcom_sysmon_shutdown_acked() - query the success of the last shutdown
+ * @sysmon: sysmon context
+ *
+ * When sysmon is used to request a graceful shutdown of the remote processor
+ * this can be used by the remoteproc driver to query the success, in order to
+ * know if it should fall back to other means of requesting a shutdown.
+ *
+ * Return: boolean indicator of the success of the last shutdown request
+ */
+bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon)
+{
+ return sysmon && sysmon->shutdown_acked;
+}
+EXPORT_SYMBOL_GPL(qcom_sysmon_shutdown_acked);
+
+/**
* sysmon_probe() - probe sys_mon channel
* @rpdev: rpmsg device handle
*

View File

@ -1,120 +0,0 @@
From 47c815630294b6d2284fff10377d808f376de2b2 Mon Sep 17 00:00:00 2001
From: Bjorn Andersson <bjorn.andersson@linaro.org>
Date: Sat, 21 Nov 2020 21:41:34 -0800
Subject: [PATCH 01/16] remoteproc: qcom: q6v5: Query sysmon before graceful
shutdown
Requesting a graceful shutdown through the shared memory state signals
will not be acked in the event that sysmon has already successfully shut
down the remote firmware. So extend the stop request API to optionally
take the remoteproc's sysmon instance and query if there's already been
a successful shutdown attempt, before doing the signal dance.
Tested-by: Steev Klimaszewski <steev@kali.org>
Reviewed-by: Rishabh Bhatnagar <rishabhb@codeaurora.org>
Link: https://lore.kernel.org/r/20201122054135.802935-4-bjorn.andersson@linaro.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5.c | 8 +++++++-
drivers/remoteproc/qcom_q6v5.h | 3 ++-
drivers/remoteproc/qcom_q6v5_adsp.c | 2 +-
drivers/remoteproc/qcom_q6v5_mss.c | 2 +-
drivers/remoteproc/qcom_q6v5_pas.c | 2 +-
drivers/remoteproc/qcom_q6v5_wcss.c | 2 +-
6 files changed, 13 insertions(+), 6 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5.c
+++ b/drivers/remoteproc/qcom_q6v5.c
@@ -13,6 +13,7 @@
#include <linux/soc/qcom/smem.h>
#include <linux/soc/qcom/smem_state.h>
#include <linux/remoteproc.h>
+#include "qcom_common.h"
#include "qcom_q6v5.h"
#define Q6V5_PANIC_DELAY_MS 200
@@ -146,15 +147,20 @@ static irqreturn_t q6v5_stop_interrupt(i
/**
* qcom_q6v5_request_stop() - request the remote processor to stop
* @q6v5: reference to qcom_q6v5 context
+ * @sysmon: reference to the remote's sysmon instance, or NULL
*
* Return: 0 on success, negative errno on failure
*/
-int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5)
+int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5, struct qcom_sysmon *sysmon)
{
int ret;
q6v5->running = false;
+ /* Don't perform SMP2P dance if sysmon already shut down the remote */
+ if (qcom_sysmon_shutdown_acked(sysmon))
+ return 0;
+
qcom_smem_state_update_bits(q6v5->state,
BIT(q6v5->stop_bit), BIT(q6v5->stop_bit));
--- a/drivers/remoteproc/qcom_q6v5.h
+++ b/drivers/remoteproc/qcom_q6v5.h
@@ -8,6 +8,7 @@
struct rproc;
struct qcom_smem_state;
+struct qcom_sysmon;
struct qcom_q6v5 {
struct device *dev;
@@ -40,7 +41,7 @@ int qcom_q6v5_init(struct qcom_q6v5 *q6v
int qcom_q6v5_prepare(struct qcom_q6v5 *q6v5);
int qcom_q6v5_unprepare(struct qcom_q6v5 *q6v5);
-int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5);
+int qcom_q6v5_request_stop(struct qcom_q6v5 *q6v5, struct qcom_sysmon *sysmon);
int qcom_q6v5_wait_for_start(struct qcom_q6v5 *q6v5, int timeout);
unsigned long qcom_q6v5_panic(struct qcom_q6v5 *q6v5);
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -266,7 +266,7 @@ static int adsp_stop(struct rproc *rproc
int handover;
int ret;
- ret = qcom_q6v5_request_stop(&adsp->q6v5);
+ ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
if (ret == -ETIMEDOUT)
dev_err(adsp->dev, "timed out on wait\n");
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -1376,7 +1376,7 @@ static int q6v5_stop(struct rproc *rproc
struct q6v5 *qproc = (struct q6v5 *)rproc->priv;
int ret;
- ret = qcom_q6v5_request_stop(&qproc->q6v5);
+ ret = qcom_q6v5_request_stop(&qproc->q6v5, qproc->sysmon);
if (ret == -ETIMEDOUT)
dev_err(qproc->dev, "timed out on wait\n");
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -217,7 +217,7 @@ static int adsp_stop(struct rproc *rproc
int handover;
int ret;
- ret = qcom_q6v5_request_stop(&adsp->q6v5);
+ ret = qcom_q6v5_request_stop(&adsp->q6v5, adsp->sysmon);
if (ret == -ETIMEDOUT)
dev_err(adsp->dev, "timed out on wait\n");
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -390,7 +390,7 @@ static int q6v5_wcss_stop(struct rproc *
int ret;
/* WCSS powerdown */
- ret = qcom_q6v5_request_stop(&wcss->q6v5);
+ ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
if (ret == -ETIMEDOUT) {
dev_err(wcss->dev, "timed out on wait\n");
return ret;

View File

@ -1,104 +0,0 @@
From 6a83f257a5a10b24c7311475f19d58399c475476 Mon Sep 17 00:00:00 2001
From: Govind Singh <govinds@codeaurora.org>
Date: Fri, 29 Jan 2021 00:18:12 +0530
Subject: [PATCH 02/16] remoteproc: qcom: wcss: populate hardcoded param using
driver data
Q6 based WiFi fw loading is supported across
different targets, ex: IPQ8074/QCS404. In order to
support different fw names/pas id etc, populate
hardcoded param using driver data.
Signed-off-by: Govind Singh <govinds@codeaurora.org>
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Link: https://lore.kernel.org/r/1611859695-11824-2-git-send-email-gokulsri@codeaurora.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -71,6 +71,11 @@
#define TCSR_WCSS_CLK_MASK 0x1F
#define TCSR_WCSS_CLK_ENABLE 0x14
+struct wcss_data {
+ const char *firmware_name;
+ unsigned int crash_reason_smem;
+};
+
struct q6v5_wcss {
struct device *dev;
@@ -93,6 +98,8 @@ struct q6v5_wcss {
void *mem_region;
size_t mem_size;
+ unsigned int crash_reason_smem;
+
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
};
@@ -438,7 +445,7 @@ static int q6v5_wcss_load(struct rproc *
return ret;
}
-static const struct rproc_ops q6v5_wcss_ops = {
+static const struct rproc_ops q6v5_wcss_ipq8074_ops = {
.start = q6v5_wcss_start,
.stop = q6v5_wcss_stop,
.da_to_va = q6v5_wcss_da_to_va,
@@ -538,12 +545,17 @@ static int q6v5_alloc_memory_region(stru
static int q6v5_wcss_probe(struct platform_device *pdev)
{
+ const struct wcss_data *desc;
struct q6v5_wcss *wcss;
struct rproc *rproc;
int ret;
- rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_wcss_ops,
- "IPQ8074/q6_fw.mdt", sizeof(*wcss));
+ desc = device_get_match_data(&pdev->dev);
+ if (!desc)
+ return -EINVAL;
+
+ rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_wcss_ipq8074_ops,
+ desc->firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -551,6 +563,7 @@ static int q6v5_wcss_probe(struct platfo
wcss = rproc->priv;
wcss->dev = &pdev->dev;
+ wcss->crash_reason_smem = desc->crash_reason_smem;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -564,7 +577,8 @@ static int q6v5_wcss_probe(struct platfo
if (ret)
goto free_rproc;
- ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, WCSS_CRASH_REASON, NULL);
+ ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem,
+ NULL);
if (ret)
goto free_rproc;
@@ -595,8 +609,13 @@ static int q6v5_wcss_remove(struct platf
return 0;
}
+static const struct wcss_data wcss_ipq8074_res_init = {
+ .firmware_name = "IPQ8074/q6_fw.mdt",
+ .crash_reason_smem = WCSS_CRASH_REASON,
+};
+
static const struct of_device_id q6v5_wcss_of_match[] = {
- { .compatible = "qcom,ipq8074-wcss-pil" },
+ { .compatible = "qcom,ipq8074-wcss-pil", .data = &wcss_ipq8074_res_init },
{ },
};
MODULE_DEVICE_TABLE(of, q6v5_wcss_of_match);

View File

@ -1,764 +0,0 @@
From 155940892f022482c7e7a33c917fd766519d031b Mon Sep 17 00:00:00 2001
From: Govind Singh <govinds@codeaurora.org>
Date: Fri, 29 Jan 2021 00:18:14 +0530
Subject: [PATCH 03/16] remoteproc: qcom: wcss: Add non pas wcss Q6 support for
QCS404
Add non PAS WCSS remoteproc driver support for QCS404 SOC.
Add WCSS q6 bootup and shutdown sequence handled from
Application Processor SubSystem(APSS).
Signed-off-by: Govind Singh <govinds@codeaurora.org>
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Link: https://lore.kernel.org/r/1611859695-11824-4-git-send-email-gokulsri@codeaurora.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 566 ++++++++++++++++++++++++++--
1 file changed, 528 insertions(+), 38 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -4,13 +4,18 @@
* Copyright (C) 2014 Sony Mobile Communications AB
* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*/
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
+#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/soc/qcom/mdt_loader.h>
#include "qcom_common.h"
@@ -24,6 +29,9 @@
#define Q6SS_GFMUX_CTL_REG 0x020
#define Q6SS_PWR_CTL_REG 0x030
#define Q6SS_MEM_PWR_CTL 0x0B0
+#define Q6SS_STRAP_ACC 0x110
+#define Q6SS_CGC_OVERRIDE 0x034
+#define Q6SS_BCR_REG 0x6000
/* AXI Halt Register Offsets */
#define AXI_HALTREQ_REG 0x0
@@ -37,14 +45,19 @@
#define Q6SS_CORE_ARES BIT(1)
#define Q6SS_BUS_ARES_ENABLE BIT(2)
+/* Q6SS_BRC_RESET */
+#define Q6SS_BRC_BLK_ARES BIT(0)
+
/* Q6SS_GFMUX_CTL */
#define Q6SS_CLK_ENABLE BIT(1)
+#define Q6SS_SWITCH_CLK_SRC BIT(8)
/* Q6SS_PWR_CTL */
#define Q6SS_L2DATA_STBY_N BIT(18)
#define Q6SS_SLP_RET_N BIT(19)
#define Q6SS_CLAMP_IO BIT(20)
#define QDSS_BHS_ON BIT(21)
+#define QDSS_Q6_MEMORIES GENMASK(15, 0)
/* Q6SS parameters */
#define Q6SS_LDO_BYP BIT(25)
@@ -53,6 +66,7 @@
#define Q6SS_CLAMP_QMC_MEM BIT(22)
#define HALT_CHECK_MAX_LOOPS 200
#define Q6SS_XO_CBCR GENMASK(5, 3)
+#define Q6SS_SLEEP_CBCR GENMASK(5, 2)
/* Q6SS config/status registers */
#define TCSR_GLOBAL_CFG0 0x0
@@ -71,9 +85,23 @@
#define TCSR_WCSS_CLK_MASK 0x1F
#define TCSR_WCSS_CLK_ENABLE 0x14
+#define MAX_HALT_REG 3
+enum {
+ WCSS_IPQ8074,
+ WCSS_QCS404,
+};
+
struct wcss_data {
const char *firmware_name;
unsigned int crash_reason_smem;
+ u32 version;
+ bool aon_reset_required;
+ bool wcss_q6_reset_required;
+ const char *ssr_name;
+ const char *sysmon_name;
+ int ssctl_id;
+ const struct rproc_ops *ops;
+ bool requires_force_stop;
};
struct q6v5_wcss {
@@ -87,9 +115,26 @@ struct q6v5_wcss {
u32 halt_wcss;
u32 halt_nc;
+ struct clk *xo;
+ struct clk *ahbfabric_cbcr_clk;
+ struct clk *gcc_abhs_cbcr;
+ struct clk *gcc_axim_cbcr;
+ struct clk *lcc_csr_cbcr;
+ struct clk *ahbs_cbcr;
+ struct clk *tcm_slave_cbcr;
+ struct clk *qdsp6ss_abhm_cbcr;
+ struct clk *qdsp6ss_sleep_cbcr;
+ struct clk *qdsp6ss_axim_cbcr;
+ struct clk *qdsp6ss_xo_cbcr;
+ struct clk *qdsp6ss_core_gfmux;
+ struct clk *lcc_bcr_sleep;
+ struct regulator *cx_supply;
+ struct qcom_sysmon *sysmon;
+
struct reset_control *wcss_aon_reset;
struct reset_control *wcss_reset;
struct reset_control *wcss_q6_reset;
+ struct reset_control *wcss_q6_bcr_reset;
struct qcom_q6v5 q6v5;
@@ -99,6 +144,8 @@ struct q6v5_wcss {
size_t mem_size;
unsigned int crash_reason_smem;
+ u32 version;
+ bool requires_force_stop;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
@@ -244,6 +291,207 @@ wcss_reset:
return ret;
}
+static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss)
+{
+ unsigned long val;
+ int ret, idx;
+
+ /* Toggle the restart */
+ reset_control_assert(wcss->wcss_reset);
+ usleep_range(200, 300);
+ reset_control_deassert(wcss->wcss_reset);
+ usleep_range(200, 300);
+
+ /* Enable GCC_WDSP_Q6SS_AHBS_CBCR clock */
+ ret = clk_prepare_enable(wcss->gcc_abhs_cbcr);
+ if (ret)
+ return ret;
+
+ /* Remove reset to the WCNSS QDSP6SS */
+ reset_control_deassert(wcss->wcss_q6_bcr_reset);
+
+ /* Enable Q6SSTOP_AHBFABRIC_CBCR clock */
+ ret = clk_prepare_enable(wcss->ahbfabric_cbcr_clk);
+ if (ret)
+ goto disable_gcc_abhs_cbcr_clk;
+
+ /* Enable the LCCCSR CBC clock, Q6SSTOP_Q6SSTOP_LCC_CSR_CBCR clock */
+ ret = clk_prepare_enable(wcss->lcc_csr_cbcr);
+ if (ret)
+ goto disable_ahbfabric_cbcr_clk;
+
+ /* Enable the Q6AHBS CBC, Q6SSTOP_Q6SS_AHBS_CBCR clock */
+ ret = clk_prepare_enable(wcss->ahbs_cbcr);
+ if (ret)
+ goto disable_csr_cbcr_clk;
+
+ /* Enable the TCM slave CBC, Q6SSTOP_Q6SS_TCM_SLAVE_CBCR clock */
+ ret = clk_prepare_enable(wcss->tcm_slave_cbcr);
+ if (ret)
+ goto disable_ahbs_cbcr_clk;
+
+ /* Enable the Q6SS AHB master CBC, Q6SSTOP_Q6SS_AHBM_CBCR clock */
+ ret = clk_prepare_enable(wcss->qdsp6ss_abhm_cbcr);
+ if (ret)
+ goto disable_tcm_slave_cbcr_clk;
+
+ /* Enable the Q6SS AXI master CBC, Q6SSTOP_Q6SS_AXIM_CBCR clock */
+ ret = clk_prepare_enable(wcss->qdsp6ss_axim_cbcr);
+ if (ret)
+ goto disable_abhm_cbcr_clk;
+
+ /* Enable the Q6SS XO CBC */
+ val = readl(wcss->reg_base + Q6SS_XO_CBCR);
+ val |= BIT(0);
+ writel(val, wcss->reg_base + Q6SS_XO_CBCR);
+ /* Read CLKOFF bit to go low indicating CLK is enabled */
+ ret = readl_poll_timeout(wcss->reg_base + Q6SS_XO_CBCR,
+ val, !(val & BIT(31)), 1,
+ HALT_CHECK_MAX_LOOPS);
+ if (ret) {
+ dev_err(wcss->dev,
+ "xo cbcr enabling timed out (rc:%d)\n", ret);
+ return ret;
+ }
+
+ writel(0, wcss->reg_base + Q6SS_CGC_OVERRIDE);
+
+ /* Enable QDSP6 sleep clock clock */
+ val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
+ val |= BIT(0);
+ writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
+
+ /* Enable the Enable the Q6 AXI clock, GCC_WDSP_Q6SS_AXIM_CBCR*/
+ ret = clk_prepare_enable(wcss->gcc_axim_cbcr);
+ if (ret)
+ goto disable_sleep_cbcr_clk;
+
+ /* Assert resets, stop core */
+ val = readl(wcss->reg_base + Q6SS_RESET_REG);
+ val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE;
+ writel(val, wcss->reg_base + Q6SS_RESET_REG);
+
+ /* Program the QDSP6SS PWR_CTL register */
+ writel(0x01700000, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ writel(0x03700000, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ writel(0x03300000, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ writel(0x033C0000, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ /*
+ * Enable memories by turning on the QDSP6 memory foot/head switch, one
+ * bank at a time to avoid in-rush current
+ */
+ for (idx = 28; idx >= 0; idx--) {
+ writel((readl(wcss->reg_base + Q6SS_MEM_PWR_CTL) |
+ (1 << idx)), wcss->reg_base + Q6SS_MEM_PWR_CTL);
+ }
+
+ writel(0x031C0000, wcss->reg_base + Q6SS_PWR_CTL_REG);
+ writel(0x030C0000, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ val = readl(wcss->reg_base + Q6SS_RESET_REG);
+ val &= ~Q6SS_CORE_ARES;
+ writel(val, wcss->reg_base + Q6SS_RESET_REG);
+
+ /* Enable the Q6 core clock at the GFM, Q6SSTOP_QDSP6SS_GFMUX_CTL */
+ val = readl(wcss->reg_base + Q6SS_GFMUX_CTL_REG);
+ val |= Q6SS_CLK_ENABLE | Q6SS_SWITCH_CLK_SRC;
+ writel(val, wcss->reg_base + Q6SS_GFMUX_CTL_REG);
+
+ /* Enable sleep clock branch needed for BCR circuit */
+ ret = clk_prepare_enable(wcss->lcc_bcr_sleep);
+ if (ret)
+ goto disable_core_gfmux_clk;
+
+ return 0;
+
+disable_core_gfmux_clk:
+ val = readl(wcss->reg_base + Q6SS_GFMUX_CTL_REG);
+ val &= ~(Q6SS_CLK_ENABLE | Q6SS_SWITCH_CLK_SRC);
+ writel(val, wcss->reg_base + Q6SS_GFMUX_CTL_REG);
+ clk_disable_unprepare(wcss->gcc_axim_cbcr);
+disable_sleep_cbcr_clk:
+ val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
+ val &= ~Q6SS_CLK_ENABLE;
+ writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
+ val = readl(wcss->reg_base + Q6SS_XO_CBCR);
+ val &= ~Q6SS_CLK_ENABLE;
+ writel(val, wcss->reg_base + Q6SS_XO_CBCR);
+ clk_disable_unprepare(wcss->qdsp6ss_axim_cbcr);
+disable_abhm_cbcr_clk:
+ clk_disable_unprepare(wcss->qdsp6ss_abhm_cbcr);
+disable_tcm_slave_cbcr_clk:
+ clk_disable_unprepare(wcss->tcm_slave_cbcr);
+disable_ahbs_cbcr_clk:
+ clk_disable_unprepare(wcss->ahbs_cbcr);
+disable_csr_cbcr_clk:
+ clk_disable_unprepare(wcss->lcc_csr_cbcr);
+disable_ahbfabric_cbcr_clk:
+ clk_disable_unprepare(wcss->ahbfabric_cbcr_clk);
+disable_gcc_abhs_cbcr_clk:
+ clk_disable_unprepare(wcss->gcc_abhs_cbcr);
+
+ return ret;
+}
+
+static inline int q6v5_wcss_qcs404_reset(struct q6v5_wcss *wcss)
+{
+ unsigned long val;
+
+ writel(0x80800000, wcss->reg_base + Q6SS_STRAP_ACC);
+
+ /* Start core execution */
+ val = readl(wcss->reg_base + Q6SS_RESET_REG);
+ val &= ~Q6SS_STOP_CORE;
+ writel(val, wcss->reg_base + Q6SS_RESET_REG);
+
+ return 0;
+}
+
+static int q6v5_qcs404_wcss_start(struct rproc *rproc)
+{
+ struct q6v5_wcss *wcss = rproc->priv;
+ int ret;
+
+ ret = clk_prepare_enable(wcss->xo);
+ if (ret)
+ return ret;
+
+ ret = regulator_enable(wcss->cx_supply);
+ if (ret)
+ goto disable_xo_clk;
+
+ qcom_q6v5_prepare(&wcss->q6v5);
+
+ ret = q6v5_wcss_qcs404_power_on(wcss);
+ if (ret) {
+ dev_err(wcss->dev, "wcss clk_enable failed\n");
+ goto disable_cx_supply;
+ }
+
+ writel(rproc->bootaddr >> 4, wcss->reg_base + Q6SS_RST_EVB);
+
+ q6v5_wcss_qcs404_reset(wcss);
+
+ ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
+ if (ret == -ETIMEDOUT) {
+ dev_err(wcss->dev, "start timed out\n");
+ goto disable_cx_supply;
+ }
+
+ return 0;
+
+disable_cx_supply:
+ regulator_disable(wcss->cx_supply);
+disable_xo_clk:
+ clk_disable_unprepare(wcss->xo);
+
+ return ret;
+}
+
static void q6v5_wcss_halt_axi_port(struct q6v5_wcss *wcss,
struct regmap *halt_map,
u32 offset)
@@ -278,6 +526,70 @@ static void q6v5_wcss_halt_axi_port(stru
regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
}
+static int q6v5_qcs404_wcss_shutdown(struct q6v5_wcss *wcss)
+{
+ unsigned long val;
+ int ret;
+
+ q6v5_wcss_halt_axi_port(wcss, wcss->halt_map, wcss->halt_wcss);
+
+ /* assert clamps to avoid MX current inrush */
+ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG);
+ val |= (Q6SS_CLAMP_IO | Q6SS_CLAMP_WL | Q6SS_CLAMP_QMC_MEM);
+ writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ /* Disable memories by turning off memory foot/headswitch */
+ writel((readl(wcss->reg_base + Q6SS_MEM_PWR_CTL) &
+ ~QDSS_Q6_MEMORIES),
+ wcss->reg_base + Q6SS_MEM_PWR_CTL);
+
+ /* Clear the BHS_ON bit */
+ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG);
+ val &= ~Q6SS_BHS_ON;
+ writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG);
+
+ clk_disable_unprepare(wcss->ahbfabric_cbcr_clk);
+ clk_disable_unprepare(wcss->lcc_csr_cbcr);
+ clk_disable_unprepare(wcss->tcm_slave_cbcr);
+ clk_disable_unprepare(wcss->qdsp6ss_abhm_cbcr);
+ clk_disable_unprepare(wcss->qdsp6ss_axim_cbcr);
+
+ val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
+ val &= ~BIT(0);
+ writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
+
+ val = readl(wcss->reg_base + Q6SS_XO_CBCR);
+ val &= ~BIT(0);
+ writel(val, wcss->reg_base + Q6SS_XO_CBCR);
+
+ clk_disable_unprepare(wcss->ahbs_cbcr);
+ clk_disable_unprepare(wcss->lcc_bcr_sleep);
+
+ val = readl(wcss->reg_base + Q6SS_GFMUX_CTL_REG);
+ val &= ~(Q6SS_CLK_ENABLE | Q6SS_SWITCH_CLK_SRC);
+ writel(val, wcss->reg_base + Q6SS_GFMUX_CTL_REG);
+
+ clk_disable_unprepare(wcss->gcc_abhs_cbcr);
+
+ ret = reset_control_assert(wcss->wcss_reset);
+ if (ret) {
+ dev_err(wcss->dev, "wcss_reset failed\n");
+ return ret;
+ }
+ usleep_range(200, 300);
+
+ ret = reset_control_deassert(wcss->wcss_reset);
+ if (ret) {
+ dev_err(wcss->dev, "wcss_reset failed\n");
+ return ret;
+ }
+ usleep_range(200, 300);
+
+ clk_disable_unprepare(wcss->gcc_axim_cbcr);
+
+ return 0;
+}
+
static int q6v5_wcss_powerdown(struct q6v5_wcss *wcss)
{
int ret;
@@ -397,20 +709,28 @@ static int q6v5_wcss_stop(struct rproc *
int ret;
/* WCSS powerdown */
- ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
- if (ret == -ETIMEDOUT) {
- dev_err(wcss->dev, "timed out on wait\n");
- return ret;
+ if (wcss->requires_force_stop) {
+ ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
+ if (ret == -ETIMEDOUT) {
+ dev_err(wcss->dev, "timed out on wait\n");
+ return ret;
+ }
}
- ret = q6v5_wcss_powerdown(wcss);
- if (ret)
- return ret;
-
- /* Q6 Power down */
- ret = q6v5_q6_powerdown(wcss);
- if (ret)
- return ret;
+ if (wcss->version == WCSS_QCS404) {
+ ret = q6v5_qcs404_wcss_shutdown(wcss);
+ if (ret)
+ return ret;
+ } else {
+ ret = q6v5_wcss_powerdown(wcss);
+ if (ret)
+ return ret;
+
+ /* Q6 Power down */
+ ret = q6v5_q6_powerdown(wcss);
+ if (ret)
+ return ret;
+ }
qcom_q6v5_unprepare(&wcss->q6v5);
@@ -453,14 +773,26 @@ static const struct rproc_ops q6v5_wcss_
.get_boot_addr = rproc_elf_get_boot_addr,
};
-static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss)
+static const struct rproc_ops q6v5_wcss_qcs404_ops = {
+ .start = q6v5_qcs404_wcss_start,
+ .stop = q6v5_wcss_stop,
+ .da_to_va = q6v5_wcss_da_to_va,
+ .load = q6v5_wcss_load,
+ .get_boot_addr = rproc_elf_get_boot_addr,
+ .parse_fw = qcom_register_dump_segments,
+};
+
+static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss,
+ const struct wcss_data *desc)
{
struct device *dev = wcss->dev;
- wcss->wcss_aon_reset = devm_reset_control_get(dev, "wcss_aon_reset");
- if (IS_ERR(wcss->wcss_aon_reset)) {
- dev_err(wcss->dev, "unable to acquire wcss_aon_reset\n");
- return PTR_ERR(wcss->wcss_aon_reset);
+ if (desc->aon_reset_required) {
+ wcss->wcss_aon_reset = devm_reset_control_get(dev, "wcss_aon_reset");
+ if (IS_ERR(wcss->wcss_aon_reset)) {
+ dev_err(wcss->dev, "fail to acquire wcss_aon_reset\n");
+ return PTR_ERR(wcss->wcss_aon_reset);
+ }
}
wcss->wcss_reset = devm_reset_control_get(dev, "wcss_reset");
@@ -469,10 +801,18 @@ static int q6v5_wcss_init_reset(struct q
return PTR_ERR(wcss->wcss_reset);
}
- wcss->wcss_q6_reset = devm_reset_control_get(dev, "wcss_q6_reset");
- if (IS_ERR(wcss->wcss_q6_reset)) {
- dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");
- return PTR_ERR(wcss->wcss_q6_reset);
+ if (desc->wcss_q6_reset_required) {
+ wcss->wcss_q6_reset = devm_reset_control_get(dev, "wcss_q6_reset");
+ if (IS_ERR(wcss->wcss_q6_reset)) {
+ dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");
+ return PTR_ERR(wcss->wcss_q6_reset);
+ }
+ }
+
+ wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_bcr_reset");
+ if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
+ dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
+ return PTR_ERR(wcss->wcss_q6_bcr_reset);
}
return 0;
@@ -481,35 +821,48 @@ static int q6v5_wcss_init_reset(struct q
static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
struct platform_device *pdev)
{
- struct of_phandle_args args;
+ unsigned int halt_reg[MAX_HALT_REG] = {0};
+ struct device_node *syscon;
struct resource *res;
int ret;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
- wcss->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ wcss->reg_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
if (IS_ERR(wcss->reg_base))
return PTR_ERR(wcss->reg_base);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");
- wcss->rmb_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(wcss->rmb_base))
- return PTR_ERR(wcss->rmb_base);
+ if (wcss->version == WCSS_IPQ8074) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");
+ wcss->rmb_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(wcss->rmb_base))
+ return PTR_ERR(wcss->rmb_base);
+ }
- ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
- "qcom,halt-regs", 3, 0, &args);
- if (ret < 0) {
+ syscon = of_parse_phandle(pdev->dev.of_node,
+ "qcom,halt-regs", 0);
+ if (!syscon) {
dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
return -EINVAL;
}
- wcss->halt_map = syscon_node_to_regmap(args.np);
- of_node_put(args.np);
+ wcss->halt_map = syscon_node_to_regmap(syscon);
+ of_node_put(syscon);
if (IS_ERR(wcss->halt_map))
return PTR_ERR(wcss->halt_map);
- wcss->halt_q6 = args.args[0];
- wcss->halt_wcss = args.args[1];
- wcss->halt_nc = args.args[2];
+ ret = of_property_read_variable_u32_array(pdev->dev.of_node,
+ "qcom,halt-regs",
+ halt_reg, 0,
+ MAX_HALT_REG);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n");
+ return -EINVAL;
+ }
+
+ wcss->halt_q6 = halt_reg[0];
+ wcss->halt_wcss = halt_reg[1];
+ wcss->halt_nc = halt_reg[2];
return 0;
}
@@ -543,6 +896,107 @@ static int q6v5_alloc_memory_region(stru
return 0;
}
+static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
+{
+ int ret;
+
+ wcss->xo = devm_clk_get(wcss->dev, "xo");
+ if (IS_ERR(wcss->xo)) {
+ ret = PTR_ERR(wcss->xo);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get xo clock");
+ return ret;
+ }
+
+ wcss->gcc_abhs_cbcr = devm_clk_get(wcss->dev, "gcc_abhs_cbcr");
+ if (IS_ERR(wcss->gcc_abhs_cbcr)) {
+ ret = PTR_ERR(wcss->gcc_abhs_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get gcc abhs clock");
+ return PTR_ERR(wcss->gcc_abhs_cbcr);
+ }
+
+ wcss->gcc_axim_cbcr = devm_clk_get(wcss->dev, "gcc_axim_cbcr");
+ if (IS_ERR(wcss->gcc_axim_cbcr)) {
+ ret = PTR_ERR(wcss->gcc_axim_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get gcc axim clock\n");
+ return PTR_ERR(wcss->gcc_axim_cbcr);
+ }
+
+ wcss->ahbfabric_cbcr_clk = devm_clk_get(wcss->dev,
+ "lcc_ahbfabric_cbc");
+ if (IS_ERR(wcss->ahbfabric_cbcr_clk)) {
+ ret = PTR_ERR(wcss->ahbfabric_cbcr_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get ahbfabric clock\n");
+ return PTR_ERR(wcss->ahbfabric_cbcr_clk);
+ }
+
+ wcss->lcc_csr_cbcr = devm_clk_get(wcss->dev, "tcsr_lcc_cbc");
+ if (IS_ERR(wcss->lcc_csr_cbcr)) {
+ ret = PTR_ERR(wcss->lcc_csr_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get csr cbcr clk\n");
+ return PTR_ERR(wcss->lcc_csr_cbcr);
+ }
+
+ wcss->ahbs_cbcr = devm_clk_get(wcss->dev,
+ "lcc_abhs_cbc");
+ if (IS_ERR(wcss->ahbs_cbcr)) {
+ ret = PTR_ERR(wcss->ahbs_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get ahbs_cbcr clk\n");
+ return PTR_ERR(wcss->ahbs_cbcr);
+ }
+
+ wcss->tcm_slave_cbcr = devm_clk_get(wcss->dev,
+ "lcc_tcm_slave_cbc");
+ if (IS_ERR(wcss->tcm_slave_cbcr)) {
+ ret = PTR_ERR(wcss->tcm_slave_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get tcm cbcr clk\n");
+ return PTR_ERR(wcss->tcm_slave_cbcr);
+ }
+
+ wcss->qdsp6ss_abhm_cbcr = devm_clk_get(wcss->dev, "lcc_abhm_cbc");
+ if (IS_ERR(wcss->qdsp6ss_abhm_cbcr)) {
+ ret = PTR_ERR(wcss->qdsp6ss_abhm_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get abhm cbcr clk\n");
+ return PTR_ERR(wcss->qdsp6ss_abhm_cbcr);
+ }
+
+ wcss->qdsp6ss_axim_cbcr = devm_clk_get(wcss->dev, "lcc_axim_cbc");
+ if (IS_ERR(wcss->qdsp6ss_axim_cbcr)) {
+ ret = PTR_ERR(wcss->qdsp6ss_axim_cbcr);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get axim cbcr clk\n");
+ return PTR_ERR(wcss->qdsp6ss_abhm_cbcr);
+ }
+
+ wcss->lcc_bcr_sleep = devm_clk_get(wcss->dev, "lcc_bcr_sleep");
+ if (IS_ERR(wcss->lcc_bcr_sleep)) {
+ ret = PTR_ERR(wcss->lcc_bcr_sleep);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "failed to get bcr cbcr clk\n");
+ return PTR_ERR(wcss->lcc_bcr_sleep);
+ }
+
+ return 0;
+}
+
+static int q6v5_wcss_init_regulator(struct q6v5_wcss *wcss)
+{
+ wcss->cx_supply = devm_regulator_get(wcss->dev, "cx");
+ if (IS_ERR(wcss->cx_supply))
+ return PTR_ERR(wcss->cx_supply);
+
+ regulator_set_load(wcss->cx_supply, 100000);
+
+ return 0;
+}
+
static int q6v5_wcss_probe(struct platform_device *pdev)
{
const struct wcss_data *desc;
@@ -554,7 +1008,7 @@ static int q6v5_wcss_probe(struct platfo
if (!desc)
return -EINVAL;
- rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_wcss_ipq8074_ops,
+ rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
@@ -563,7 +1017,10 @@ static int q6v5_wcss_probe(struct platfo
wcss = rproc->priv;
wcss->dev = &pdev->dev;
- wcss->crash_reason_smem = desc->crash_reason_smem;
+ wcss->version = desc->version;
+
+ wcss->version = desc->version;
+ wcss->requires_force_stop = desc->requires_force_stop;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -573,7 +1030,17 @@ static int q6v5_wcss_probe(struct platfo
if (ret)
goto free_rproc;
- ret = q6v5_wcss_init_reset(wcss);
+ if (wcss->version == WCSS_QCS404) {
+ ret = q6v5_wcss_init_clock(wcss);
+ if (ret)
+ goto free_rproc;
+
+ ret = q6v5_wcss_init_regulator(wcss);
+ if (ret)
+ goto free_rproc;
+ }
+
+ ret = q6v5_wcss_init_reset(wcss, desc);
if (ret)
goto free_rproc;
@@ -585,6 +1052,11 @@ static int q6v5_wcss_probe(struct platfo
qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
+ if (desc->ssctl_id)
+ wcss->sysmon = qcom_add_sysmon_subdev(rproc,
+ desc->sysmon_name,
+ desc->ssctl_id);
+
ret = rproc_add(rproc);
if (ret)
goto free_rproc;
@@ -612,10 +1084,28 @@ static int q6v5_wcss_remove(struct platf
static const struct wcss_data wcss_ipq8074_res_init = {
.firmware_name = "IPQ8074/q6_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
+ .aon_reset_required = true,
+ .wcss_q6_reset_required = true,
+ .ops = &q6v5_wcss_ipq8074_ops,
+ .requires_force_stop = true,
+};
+
+static const struct wcss_data wcss_qcs404_res_init = {
+ .crash_reason_smem = WCSS_CRASH_REASON,
+ .firmware_name = "wcnss.mdt",
+ .version = WCSS_QCS404,
+ .aon_reset_required = false,
+ .wcss_q6_reset_required = false,
+ .ssr_name = "mpss",
+ .sysmon_name = "wcnss",
+ .ssctl_id = 0x12,
+ .ops = &q6v5_wcss_qcs404_ops,
+ .requires_force_stop = false,
};
static const struct of_device_id q6v5_wcss_of_match[] = {
{ .compatible = "qcom,ipq8074-wcss-pil", .data = &wcss_ipq8074_res_init },
+ { .compatible = "qcom,qcs404-wcss-pil", .data = &wcss_qcs404_res_init },
{ },
};
MODULE_DEVICE_TABLE(of, q6v5_wcss_of_match);

View File

@ -1,43 +0,0 @@
From 7b230496f6b45e840bc7b13e7df2a8676bab9230 Mon Sep 17 00:00:00 2001
From: Govind Singh <govinds@codeaurora.org>
Date: Fri, 29 Jan 2021 00:18:15 +0530
Subject: [PATCH 04/16] remoteproc: qcom: wcss: explicitly request exclusive
reset control
Use request exclusive reset control for wcss reset controls.
Signed-off-by: Govind Singh <govinds@codeaurora.org>
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Link: https://lore.kernel.org/r/1611859695-11824-5-git-send-email-gokulsri@codeaurora.org
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -788,21 +788,21 @@ static int q6v5_wcss_init_reset(struct q
struct device *dev = wcss->dev;
if (desc->aon_reset_required) {
- wcss->wcss_aon_reset = devm_reset_control_get(dev, "wcss_aon_reset");
+ wcss->wcss_aon_reset = devm_reset_control_get_exclusive(dev, "wcss_aon_reset");
if (IS_ERR(wcss->wcss_aon_reset)) {
dev_err(wcss->dev, "fail to acquire wcss_aon_reset\n");
return PTR_ERR(wcss->wcss_aon_reset);
}
}
- wcss->wcss_reset = devm_reset_control_get(dev, "wcss_reset");
+ wcss->wcss_reset = devm_reset_control_get_exclusive(dev, "wcss_reset");
if (IS_ERR(wcss->wcss_reset)) {
dev_err(wcss->dev, "unable to acquire wcss_reset\n");
return PTR_ERR(wcss->wcss_reset);
}
if (desc->wcss_q6_reset_required) {
- wcss->wcss_q6_reset = devm_reset_control_get(dev, "wcss_q6_reset");
+ wcss->wcss_q6_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_reset");
if (IS_ERR(wcss->wcss_q6_reset)) {
dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");
return PTR_ERR(wcss->wcss_q6_reset);

View File

@ -1,32 +0,0 @@
From 5b8b0967576f04d2ee3ea36310c078a3d50e7339 Mon Sep 17 00:00:00 2001
From: Wei Yongjun <weiyongjun1@huawei.com>
Date: Fri, 19 Mar 2021 09:41:00 +0000
Subject: [PATCH 05/16] remoteproc: qcom: wcss: Fix return value check in
q6v5_wcss_init_mmio()
In case of error, the function devm_ioremap() returns NULL pointer
not ERR_PTR(). The IS_ERR() test in the return value check should
be replaced with NULL test.
Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404")
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Link: https://lore.kernel.org/r/20210319094100.4185044-1-weiyongjun1@huawei.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -829,8 +829,8 @@ static int q6v5_wcss_init_mmio(struct q6
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
wcss->reg_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
- if (IS_ERR(wcss->reg_base))
- return PTR_ERR(wcss->reg_base);
+ if (!wcss->reg_base)
+ return -ENOMEM;
if (wcss->version == WCSS_IPQ8074) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb");

View File

@ -1,32 +0,0 @@
From 6a52dbbde0e741e84f217cf762233589cc3efd13 Mon Sep 17 00:00:00 2001
From: Wei Yongjun <weiyongjun1@huawei.com>
Date: Fri, 26 Mar 2021 02:47:41 +0000
Subject: [PATCH 06/16] remoteproc: qcom: wcss: Fix wrong pointer passed to
PTR_ERR()
PTR_ERR should access the value just tested by IS_ERR, otherwise
the wrong error code will be returned.
This commit fix it by return 'ret' directly.
Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>
Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404")
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Link: https://lore.kernel.org/r/20210326024741.841267-1-weiyongjun1@huawei.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -972,7 +972,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->qdsp6ss_axim_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get axim cbcr clk\n");
- return PTR_ERR(wcss->qdsp6ss_abhm_cbcr);
+ return ret;
}
wcss->lcc_bcr_sleep = devm_clk_get(wcss->dev, "lcc_bcr_sleep");

View File

@ -1,89 +0,0 @@
From 00f24490f498db0ea67715a4dfe6c4a6ca11c6a0 Mon Sep 17 00:00:00 2001
From: Junlin Yang <yangjunlin@yulong.com>
Date: Thu, 8 Apr 2021 22:33:22 +0800
Subject: [PATCH 07/16] remoteproc: qcom: wcss: Remove unnecessary PTR_ERR()
Remove unnecessary PTR_ERR(), it has been assigned to ret before,
so return ret directly.
Signed-off-by: Junlin Yang <yangjunlin@yulong.com>
Link: https://lore.kernel.org/r/20210408143322.1647-1-angkery@163.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -913,7 +913,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->gcc_abhs_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get gcc abhs clock");
- return PTR_ERR(wcss->gcc_abhs_cbcr);
+ return ret;
}
wcss->gcc_axim_cbcr = devm_clk_get(wcss->dev, "gcc_axim_cbcr");
@@ -921,7 +921,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->gcc_axim_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get gcc axim clock\n");
- return PTR_ERR(wcss->gcc_axim_cbcr);
+ return ret;
}
wcss->ahbfabric_cbcr_clk = devm_clk_get(wcss->dev,
@@ -930,7 +930,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->ahbfabric_cbcr_clk);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get ahbfabric clock\n");
- return PTR_ERR(wcss->ahbfabric_cbcr_clk);
+ return ret;
}
wcss->lcc_csr_cbcr = devm_clk_get(wcss->dev, "tcsr_lcc_cbc");
@@ -938,7 +938,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->lcc_csr_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get csr cbcr clk\n");
- return PTR_ERR(wcss->lcc_csr_cbcr);
+ return ret;
}
wcss->ahbs_cbcr = devm_clk_get(wcss->dev,
@@ -947,7 +947,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->ahbs_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get ahbs_cbcr clk\n");
- return PTR_ERR(wcss->ahbs_cbcr);
+ return ret;
}
wcss->tcm_slave_cbcr = devm_clk_get(wcss->dev,
@@ -956,7 +956,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->tcm_slave_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get tcm cbcr clk\n");
- return PTR_ERR(wcss->tcm_slave_cbcr);
+ return ret;
}
wcss->qdsp6ss_abhm_cbcr = devm_clk_get(wcss->dev, "lcc_abhm_cbc");
@@ -964,7 +964,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->qdsp6ss_abhm_cbcr);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get abhm cbcr clk\n");
- return PTR_ERR(wcss->qdsp6ss_abhm_cbcr);
+ return ret;
}
wcss->qdsp6ss_axim_cbcr = devm_clk_get(wcss->dev, "lcc_axim_cbc");
@@ -980,7 +980,7 @@ static int q6v5_wcss_init_clock(struct q
ret = PTR_ERR(wcss->lcc_bcr_sleep);
if (ret != -EPROBE_DEFER)
dev_err(wcss->dev, "failed to get bcr cbcr clk\n");
- return PTR_ERR(wcss->lcc_bcr_sleep);
+ return ret;
}
return 0;

View File

@ -1,217 +0,0 @@
From 803eb124e1a64e42888542c3444bfe6dac412c7f Mon Sep 17 00:00:00 2001
From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Date: Mon, 4 Jan 2021 09:41:35 +0530
Subject: mtd: parsers: Add Qcom SMEM parser
NAND based Qualcomm platforms have the partition table populated in the
Shared Memory (SMEM). Hence, add a parser for parsing the partitions
from it.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210104041137.113075-3-manivannan.sadhasivam@linaro.org
---
drivers/mtd/parsers/Kconfig | 8 ++
drivers/mtd/parsers/Makefile | 1 +
drivers/mtd/parsers/qcomsmempart.c | 170 +++++++++++++++++++++++++++++++++++++
3 files changed, 179 insertions(+)
create mode 100644 drivers/mtd/parsers/qcomsmempart.c
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -196,6 +196,14 @@ config MTD_REDBOOT_PARTS_READONLY
endif # MTD_REDBOOT_PARTS
+config MTD_QCOMSMEM_PARTS
+ tristate "Qualcomm SMEM NAND flash partition parser"
+ depends on MTD_NAND_QCOM || COMPILE_TEST
+ depends on QCOM_SMEM
+ help
+ This provides support for parsing partitions from Shared Memory (SMEM)
+ for NAND flash on Qualcomm platforms.
+
config MTD_ROUTERBOOT_PARTS
tristate "RouterBoot flash partition parser"
depends on MTD && OF
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
+obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o
obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o
--- /dev/null
+++ b/drivers/mtd/parsers/qcomsmempart.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm SMEM NAND flash partition parser
+ *
+ * Copyright (C) 2020, Linaro Ltd.
+ */
+
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+
+#define SMEM_AARM_PARTITION_TABLE 9
+#define SMEM_APPS 0
+
+#define SMEM_FLASH_PART_MAGIC1 0x55ee73aa
+#define SMEM_FLASH_PART_MAGIC2 0xe35ebddb
+#define SMEM_FLASH_PTABLE_V3 3
+#define SMEM_FLASH_PTABLE_V4 4
+#define SMEM_FLASH_PTABLE_MAX_PARTS_V3 16
+#define SMEM_FLASH_PTABLE_MAX_PARTS_V4 48
+#define SMEM_FLASH_PTABLE_HDR_LEN (4 * sizeof(u32))
+#define SMEM_FLASH_PTABLE_NAME_SIZE 16
+
+/**
+ * struct smem_flash_pentry - SMEM Flash partition entry
+ * @name: Name of the partition
+ * @offset: Offset in blocks
+ * @length: Length of the partition in blocks
+ * @attr: Flags for this partition
+ */
+struct smem_flash_pentry {
+ char name[SMEM_FLASH_PTABLE_NAME_SIZE];
+ __le32 offset;
+ __le32 length;
+ u8 attr;
+} __packed __aligned(4);
+
+/**
+ * struct smem_flash_ptable - SMEM Flash partition table
+ * @magic1: Partition table Magic 1
+ * @magic2: Partition table Magic 2
+ * @version: Partition table version
+ * @numparts: Number of partitions in this ptable
+ * @pentry: Flash partition entries belonging to this ptable
+ */
+struct smem_flash_ptable {
+ __le32 magic1;
+ __le32 magic2;
+ __le32 version;
+ __le32 numparts;
+ struct smem_flash_pentry pentry[SMEM_FLASH_PTABLE_MAX_PARTS_V4];
+} __packed __aligned(4);
+
+static int parse_qcomsmem_part(struct mtd_info *mtd,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct smem_flash_pentry *pentry;
+ struct smem_flash_ptable *ptable;
+ size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
+ struct mtd_partition *parts;
+ int ret, i, numparts;
+ char *name, *c;
+
+ pr_debug("Parsing partition table info from SMEM\n");
+ ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len);
+ if (IS_ERR(ptable)) {
+ pr_err("Error reading partition table header\n");
+ return PTR_ERR(ptable);
+ }
+
+ /* Verify ptable magic */
+ if (le32_to_cpu(ptable->magic1) != SMEM_FLASH_PART_MAGIC1 ||
+ le32_to_cpu(ptable->magic2) != SMEM_FLASH_PART_MAGIC2) {
+ pr_err("Partition table magic verification failed\n");
+ return -EINVAL;
+ }
+
+ /* Ensure that # of partitions is less than the max we have allocated */
+ numparts = le32_to_cpu(ptable->numparts);
+ if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
+ pr_err("Partition numbers exceed the max limit\n");
+ return -EINVAL;
+ }
+
+ /* Find out length of partition data based on table version */
+ if (le32_to_cpu(ptable->version) <= SMEM_FLASH_PTABLE_V3) {
+ len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V3 *
+ sizeof(struct smem_flash_pentry);
+ } else if (le32_to_cpu(ptable->version) == SMEM_FLASH_PTABLE_V4) {
+ len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V4 *
+ sizeof(struct smem_flash_pentry);
+ } else {
+ pr_err("Unknown ptable version (%d)", le32_to_cpu(ptable->version));
+ return -EINVAL;
+ }
+
+ /*
+ * Now that the partition table header has been parsed, verified
+ * and the length of the partition table calculated, read the
+ * complete partition table
+ */
+ ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len);
+ if (IS_ERR_OR_NULL(ptable)) {
+ pr_err("Error reading partition table\n");
+ return PTR_ERR(ptable);
+ }
+
+ parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL);
+ if (!parts)
+ return -ENOMEM;
+
+ for (i = 0; i < numparts; i++) {
+ pentry = &ptable->pentry[i];
+ if (pentry->name[0] == '\0')
+ continue;
+
+ name = kstrdup(pentry->name, GFP_KERNEL);
+ if (!name) {
+ ret = -ENOMEM;
+ goto out_free_parts;
+ }
+
+ /* Convert name to lower case */
+ for (c = name; *c != '\0'; c++)
+ *c = tolower(*c);
+
+ parts[i].name = name;
+ parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
+ parts[i].mask_flags = pentry->attr;
+ parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize;
+ pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
+ i, pentry->name, le32_to_cpu(pentry->offset),
+ le32_to_cpu(pentry->length), pentry->attr);
+ }
+
+ pr_debug("SMEM partition table found: ver: %d len: %d\n",
+ le32_to_cpu(ptable->version), numparts);
+ *pparts = parts;
+
+ return numparts;
+
+out_free_parts:
+ while (--i >= 0)
+ kfree(parts[i].name);
+ kfree(parts);
+ *pparts = NULL;
+
+ return ret;
+}
+
+static const struct of_device_id qcomsmem_of_match_table[] = {
+ { .compatible = "qcom,smem-part" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, qcomsmem_of_match_table);
+
+static struct mtd_part_parser mtd_parser_qcomsmem = {
+ .parse_fn = parse_qcomsmem_part,
+ .name = "qcomsmem",
+ .of_match_table = qcomsmem_of_match_table,
+};
+module_mtd_part_parser(mtd_parser_qcomsmem);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Qualcomm SMEM NAND flash partition parser");

View File

@ -1,120 +0,0 @@
From 80b960829a85e555b96bfd4e31f31b3db3e8f5da Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Thu, 5 Nov 2020 15:11:50 -0600
Subject: [PATCH 1/5] PCI: dwc: Drop the .set_num_vectors() host op
There's no reason for the .set_num_vectors() host op. Drivers needing a
non-default value can just initialize pcie_port.num_vectors directly.
Link: https://lore.kernel.org/r/20201105211159.1814485-8-robh@kernel.org
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: linux-tegra@vger.kernel.org
---
.../pci/controller/dwc/pcie-designware-host.c | 19 ++++---------------
.../pci/controller/dwc/pcie-designware-plat.c | 7 +------
drivers/pci/controller/dwc/pcie-designware.h | 1 -
drivers/pci/controller/dwc/pcie-tegra194.c | 7 +------
4 files changed, 6 insertions(+), 28 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -358,22 +358,11 @@ int dw_pcie_host_init(struct pcie_port *
pci->link_gen = of_pci_get_max_link_speed(np);
if (pci_msi_enabled()) {
- /*
- * If a specific SoC driver needs to change the
- * default number of vectors, it needs to implement
- * the set_num_vectors callback.
- */
- if (!pp->ops->set_num_vectors) {
+ if (!pp->num_vectors) {
pp->num_vectors = MSI_DEF_NUM_VECTORS;
- } else {
- pp->ops->set_num_vectors(pp);
-
- if (pp->num_vectors > MAX_MSI_IRQS ||
- pp->num_vectors == 0) {
- dev_err(dev,
- "Invalid number of vectors\n");
- return -EINVAL;
- }
+ } else if (pp->num_vectors > MAX_MSI_IRQS) {
+ dev_err(dev, "Invalid number of vectors\n");
+ return -EINVAL;
}
if (!pp->ops->msi_host_init) {
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -44,14 +44,8 @@ static int dw_plat_pcie_host_init(struct
return 0;
}
-static void dw_plat_set_num_vectors(struct pcie_port *pp)
-{
- pp->num_vectors = MAX_MSI_IRQS;
-}
-
static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
.host_init = dw_plat_pcie_host_init,
- .set_num_vectors = dw_plat_set_num_vectors,
};
static int dw_plat_pcie_establish_link(struct dw_pcie *pci)
@@ -128,6 +122,7 @@ static int dw_plat_add_pcie_port(struct
return pp->msi_irq;
}
+ pp->num_vectors = MAX_MSI_IRQS;
pp->ops = &dw_plat_pcie_host_ops;
ret = dw_pcie_host_init(pp);
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -174,7 +174,6 @@ enum dw_pcie_device_mode {
struct dw_pcie_host_ops {
int (*host_init)(struct pcie_port *pp);
- void (*set_num_vectors)(struct pcie_port *pp);
int (*msi_host_init)(struct pcie_port *pp);
};
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -990,11 +990,6 @@ static int tegra_pcie_dw_link_up(struct
return !!(val & PCI_EXP_LNKSTA_DLLLA);
}
-static void tegra_pcie_set_msi_vec_num(struct pcie_port *pp)
-{
- pp->num_vectors = MAX_MSI_IRQS;
-}
-
static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
{
struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
@@ -1019,7 +1014,6 @@ static const struct dw_pcie_ops tegra_dw
static struct dw_pcie_host_ops tegra_pcie_dw_host_ops = {
.host_init = tegra_pcie_dw_host_init,
- .set_num_vectors = tegra_pcie_set_msi_vec_num,
};
static void tegra_pcie_disable_phy(struct tegra_pcie_dw *pcie)
@@ -2003,6 +1997,7 @@ static int tegra_pcie_dw_probe(struct pl
pci->n_fts[1] = FTS_VAL;
pp = &pci->pp;
+ pp->num_vectors = MAX_MSI_IRQS;
pcie->dev = &pdev->dev;
pcie->mode = (enum dw_pcie_device_mode)data->mode;

View File

@ -1,288 +0,0 @@
From 264b6fd7baa53bfaef2a6d41067b9568dff7163a Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Thu, 5 Nov 2020 15:11:51 -0600
Subject: [PATCH 2/5] PCI: dwc: Move MSI interrupt setup into DWC common code
Platforms using the built-in DWC MSI controller all have a dedicated
interrupt with "msi" name or at index 0, so let's move setting up the
interrupt to the common DWC code.
spear13xx and dra7xx are the 2 oddballs with muxed interrupts, so
we need to prevent configuring the MSI interrupt by setting msi_irq
to negative.
Link: https://lore.kernel.org/r/20201105211159.1814485-9-robh@kernel.org
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Yue Wang <yue.wang@Amlogic.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
Cc: Andy Gross <agross@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Pratyush Anand <pratyush.anand@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linux-samsung-soc@vger.kernel.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@axis.com
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-tegra@vger.kernel.org
---
drivers/pci/controller/dwc/pci-dra7xx.c | 3 +++
drivers/pci/controller/dwc/pci-exynos.c | 6 -----
drivers/pci/controller/dwc/pci-imx6.c | 6 -----
drivers/pci/controller/dwc/pci-meson.c | 6 -----
drivers/pci/controller/dwc/pcie-artpec6.c | 6 -----
.../pci/controller/dwc/pcie-designware-host.c | 11 +++++++++-
.../pci/controller/dwc/pcie-designware-plat.c | 6 -----
drivers/pci/controller/dwc/pcie-histb.c | 6 -----
drivers/pci/controller/dwc/pcie-kirin.c | 22 -------------------
drivers/pci/controller/dwc/pcie-qcom.c | 8 -------
drivers/pci/controller/dwc/pcie-spear13xx.c | 1 +
drivers/pci/controller/dwc/pcie-tegra194.c | 8 -------
drivers/pci/controller/dwc/pcie-uniphier.c | 6 -----
13 files changed, 14 insertions(+), 81 deletions(-)
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -622,6 +622,9 @@ static int __init dra7xx_add_pcie_port(s
if (pp->irq < 0)
return pp->irq;
+ /* MSI IRQ is muxed */
+ pp->msi_irq = -ENODEV;
+
ret = dra7xx_pcie_init_irq_domain(pp);
if (ret < 0)
return ret;
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -415,12 +415,6 @@ static int __init exynos_add_pcie_port(s
return ret;
}
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq(pdev, 0);
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
pp->ops = &exynos_pcie_host_ops;
ret = dw_pcie_host_init(pp);
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -853,12 +853,6 @@ static int imx6_add_pcie_port(struct imx
struct device *dev = &pdev->dev;
int ret;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq_byname(pdev, "msi");
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
pp->ops = &imx6_pcie_host_ops;
ret = dw_pcie_host_init(pp);
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -405,12 +405,6 @@ static int meson_add_pcie_port(struct me
struct device *dev = &pdev->dev;
int ret;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq(pdev, 0);
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
pp->ops = &meson_pcie_host_ops;
ret = dw_pcie_host_init(pp);
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -348,12 +348,6 @@ static int artpec6_add_pcie_port(struct
struct device *dev = pci->dev;
int ret;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq_byname(pdev, "msi");
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
pp->ops = &artpec6_pcie_host_ops;
ret = dw_pcie_host_init(pp);
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -366,13 +366,22 @@ int dw_pcie_host_init(struct pcie_port *
}
if (!pp->ops->msi_host_init) {
+ if (!pp->msi_irq) {
+ pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
+ if (pp->msi_irq < 0) {
+ pp->msi_irq = platform_get_irq(pdev, 0);
+ if (pp->msi_irq < 0)
+ return pp->msi_irq;
+ }
+ }
+
pp->msi_irq_chip = &dw_pci_msi_bottom_irq_chip;
ret = dw_pcie_allocate_domains(pp);
if (ret)
return ret;
- if (pp->msi_irq)
+ if (pp->msi_irq > 0)
irq_set_chained_handler_and_data(pp->msi_irq,
dw_chained_msi_isr,
pp);
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -116,12 +116,6 @@ static int dw_plat_add_pcie_port(struct
if (pp->irq < 0)
return pp->irq;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq(pdev, 0);
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
pp->num_vectors = MAX_MSI_IRQS;
pp->ops = &dw_plat_pcie_host_ops;
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -400,12 +400,6 @@ static int histb_pcie_probe(struct platf
return PTR_ERR(hipcie->bus_reset);
}
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq_byname(pdev, "msi");
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
hipcie->phy = devm_phy_get(dev, "phy");
if (IS_ERR(hipcie->phy)) {
dev_info(dev, "no pcie-phy found\n");
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -444,31 +444,9 @@ static const struct dw_pcie_host_ops kir
.host_init = kirin_pcie_host_init,
};
-static int kirin_pcie_add_msi(struct dw_pcie *pci,
- struct platform_device *pdev)
-{
- int irq;
-
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- pci->pp.msi_irq = irq;
- }
-
- return 0;
-}
-
static int kirin_add_pcie_port(struct dw_pcie *pci,
struct platform_device *pdev)
{
- int ret;
-
- ret = kirin_pcie_add_msi(pci, pdev);
- if (ret)
- return ret;
-
pci->pp.ops = &kirin_pcie_host_ops;
return dw_pcie_host_init(&pci->pp);
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1434,14 +1434,6 @@ static int qcom_pcie_probe(struct platfo
pp->ops = &qcom_pcie_dw_ops;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq_byname(pdev, "msi");
- if (pp->msi_irq < 0) {
- ret = pp->msi_irq;
- goto err_pm_runtime_put;
- }
- }
-
ret = phy_init(pcie->phy);
if (ret) {
pm_runtime_disable(&pdev->dev);
--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
+++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
@@ -183,6 +183,7 @@ static int spear13xx_add_pcie_port(struc
}
pp->ops = &spear13xx_pcie_host_ops;
+ pp->msi_irq = -ENODEV;
ret = dw_pcie_host_init(pp);
if (ret) {
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1554,14 +1554,6 @@ static int tegra_pcie_config_rp(struct t
char *name;
int ret;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = of_irq_get_byname(dev->of_node, "msi");
- if (!pp->msi_irq) {
- dev_err(dev, "Failed to get MSI interrupt\n");
- return -ENODEV;
- }
- }
-
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -335,12 +335,6 @@ static int uniphier_add_pcie_port(struct
pp->ops = &uniphier_pcie_host_ops;
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- pp->msi_irq = platform_get_irq_byname(pdev, "msi");
- if (pp->msi_irq < 0)
- return pp->msi_irq;
- }
-
ret = dw_pcie_host_init(pp);
if (ret) {
dev_err(dev, "Failed to initialize host (%d)\n", ret);

View File

@ -1,199 +0,0 @@
From ed016f820e3f1b980dfe0ef6137069e008f99109 Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Thu, 5 Nov 2020 15:11:52 -0600
Subject: [PATCH 3/5] PCI: dwc: Rework MSI initialization
There are 3 possible MSI implementations for the DWC host. The first is
using the built-in DWC MSI controller. The 2nd is a custom MSI
controller as part of the PCI host (keystone only). The 3rd is an
external MSI controller (typically GICv3 ITS). Currently, the last 2
are distinguished with a .msi_host_init() hook with the 3rd option using
an empty function. However we can detect the 3rd case with the presence
of 'msi-parent' or 'msi-map' properties, so let's do that instead and
remove the empty functions.
Link: https://lore.kernel.org/r/20201105211159.1814485-10-robh@kernel.org
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Minghuan Lian <minghuan.Lian@nxp.com>
Cc: Mingkai Hu <mingkai.hu@nxp.com>
Cc: Roy Zang <roy.zang@nxp.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: linuxppc-dev@lists.ozlabs.org
---
drivers/pci/controller/dwc/pci-keystone.c | 9 -------
drivers/pci/controller/dwc/pci-layerscape.c | 25 -------------------
.../pci/controller/dwc/pcie-designware-host.c | 20 +++++++++------
drivers/pci/controller/dwc/pcie-designware.h | 1 +
drivers/pci/controller/dwc/pcie-intel-gw.c | 9 -------
5 files changed, 13 insertions(+), 51 deletions(-)
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -272,14 +272,6 @@ static void ks_pcie_handle_legacy_irq(st
ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset);
}
-/*
- * Dummy function so that DW core doesn't configure MSI
- */
-static int ks_pcie_am654_msi_host_init(struct pcie_port *pp)
-{
- return 0;
-}
-
static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie)
{
ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL);
@@ -855,7 +847,6 @@ static const struct dw_pcie_host_ops ks_
static const struct dw_pcie_host_ops ks_pcie_am654_host_ops = {
.host_init = ks_pcie_host_init,
- .msi_host_init = ks_pcie_am654_msi_host_init,
};
static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv)
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -182,37 +182,12 @@ static int ls1021_pcie_host_init(struct
return ls_pcie_host_init(pp);
}
-static int ls_pcie_msi_host_init(struct pcie_port *pp)
-{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct device *dev = pci->dev;
- struct device_node *np = dev->of_node;
- struct device_node *msi_node;
-
- /*
- * The MSI domain is set by the generic of_msi_configure(). This
- * .msi_host_init() function keeps us from doing the default MSI
- * domain setup in dw_pcie_host_init() and also enforces the
- * requirement that "msi-parent" exists.
- */
- msi_node = of_parse_phandle(np, "msi-parent", 0);
- if (!msi_node) {
- dev_err(dev, "failed to find msi-parent\n");
- return -EINVAL;
- }
-
- of_node_put(msi_node);
- return 0;
-}
-
static const struct dw_pcie_host_ops ls1021_pcie_host_ops = {
.host_init = ls1021_pcie_host_init,
- .msi_host_init = ls_pcie_msi_host_init,
};
static const struct dw_pcie_host_ops ls_pcie_host_ops = {
.host_init = ls_pcie_host_init,
- .msi_host_init = ls_pcie_msi_host_init,
};
static const struct dw_pcie_ops dw_ls1021_pcie_ops = {
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -358,6 +358,10 @@ int dw_pcie_host_init(struct pcie_port *
pci->link_gen = of_pci_get_max_link_speed(np);
if (pci_msi_enabled()) {
+ pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
+ of_property_read_bool(np, "msi-parent") ||
+ of_property_read_bool(np, "msi-map"));
+
if (!pp->num_vectors) {
pp->num_vectors = MSI_DEF_NUM_VECTORS;
} else if (pp->num_vectors > MAX_MSI_IRQS) {
@@ -365,7 +369,11 @@ int dw_pcie_host_init(struct pcie_port *
return -EINVAL;
}
- if (!pp->ops->msi_host_init) {
+ if (pp->ops->msi_host_init) {
+ ret = pp->ops->msi_host_init(pp);
+ if (ret < 0)
+ return ret;
+ } else if (pp->has_msi_ctrl) {
if (!pp->msi_irq) {
pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
if (pp->msi_irq < 0) {
@@ -395,10 +403,6 @@ int dw_pcie_host_init(struct pcie_port *
pp->msi_data = 0;
goto err_free_msi;
}
- } else {
- ret = pp->ops->msi_host_init(pp);
- if (ret < 0)
- return ret;
}
}
@@ -419,7 +423,7 @@ int dw_pcie_host_init(struct pcie_port *
return 0;
err_free_msi:
- if (pci_msi_enabled() && !pp->ops->msi_host_init)
+ if (pp->has_msi_ctrl)
dw_pcie_free_msi(pp);
return ret;
}
@@ -429,7 +433,7 @@ void dw_pcie_host_deinit(struct pcie_por
{
pci_stop_root_bus(pp->bridge->bus);
pci_remove_root_bus(pp->bridge->bus);
- if (pci_msi_enabled() && !pp->ops->msi_host_init)
+ if (pp->has_msi_ctrl)
dw_pcie_free_msi(pp);
}
EXPORT_SYMBOL_GPL(dw_pcie_host_deinit);
@@ -540,7 +544,7 @@ void dw_pcie_setup_rc(struct pcie_port *
dw_pcie_setup(pci);
- if (pci_msi_enabled() && !pp->ops->msi_host_init) {
+ if (pp->has_msi_ctrl) {
num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
/* Initialize IRQ Status array */
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -178,6 +178,7 @@ struct dw_pcie_host_ops {
};
struct pcie_port {
+ bool has_msi_ctrl:1;
u64 cfg0_base;
void __iomem *va_cfg0_base;
u32 cfg0_size;
--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
+++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
@@ -403,14 +403,6 @@ static int intel_pcie_rc_init(struct pci
return intel_pcie_host_setup(lpp);
}
-/*
- * Dummy function so that DW core doesn't configure MSI
- */
-static int intel_pcie_msi_init(struct pcie_port *pp)
-{
- return 0;
-}
-
static u64 intel_pcie_cpu_addr(struct dw_pcie *pcie, u64 cpu_addr)
{
return cpu_addr + BUS_IATU_OFFSET;
@@ -422,7 +414,6 @@ static const struct dw_pcie_ops intel_pc
static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
.host_init = intel_pcie_rc_init,
- .msi_host_init = intel_pcie_msi_init,
};
static const struct intel_pcie_soc pcie_data = {

View File

@ -1,603 +0,0 @@
From 533bee2aeda70c212a3fb5547d5beb6406e3ccf7 Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Thu, 5 Nov 2020 15:11:53 -0600
Subject: [PATCH 4/5] PCI: dwc: Move link handling into common code
All the DWC drivers do link setup and checks at roughly the same time.
Let's use the existing .start_link() hook (currently only used in EP
mode) and move the link handling to the core code.
The behavior for a link down was inconsistent as some drivers would fail
probe in that case while others succeed. Let's standardize this to
succeed as there are usecases where devices (and the link) appear later
even without hotplug. For example, a reconfigured FPGA device.
Link: https://lore.kernel.org/r/20201105211159.1814485-11-robh@kernel.org
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Yue Wang <yue.wang@Amlogic.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Andy Gross <agross@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
Cc: Pratyush Anand <pratyush.anand@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linux-omap@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@axis.com
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-tegra@vger.kernel.org
---
drivers/pci/controller/dwc/pci-dra7xx.c | 2 -
drivers/pci/controller/dwc/pci-exynos.c | 41 +++++++----------
drivers/pci/controller/dwc/pci-imx6.c | 9 ++--
drivers/pci/controller/dwc/pci-keystone.c | 9 ----
drivers/pci/controller/dwc/pci-meson.c | 24 ++++------
drivers/pci/controller/dwc/pcie-armada8k.c | 39 +++++++---------
drivers/pci/controller/dwc/pcie-artpec6.c | 2 -
.../pci/controller/dwc/pcie-designware-host.c | 9 ++++
.../pci/controller/dwc/pcie-designware-plat.c | 3 --
drivers/pci/controller/dwc/pcie-histb.c | 34 +++++++-------
drivers/pci/controller/dwc/pcie-kirin.c | 23 ++--------
drivers/pci/controller/dwc/pcie-qcom.c | 19 ++------
drivers/pci/controller/dwc/pcie-spear13xx.c | 46 ++++++++-----------
drivers/pci/controller/dwc/pcie-tegra194.c | 1 -
drivers/pci/controller/dwc/pcie-uniphier.c | 13 ++----
15 files changed, 103 insertions(+), 171 deletions(-)
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -183,8 +183,6 @@ static int dra7xx_pcie_host_init(struct
dw_pcie_setup_rc(pp);
- dra7xx_pcie_establish_link(pci);
- dw_pcie_wait_for_link(pci);
dw_pcie_msi_init(pp);
dra7xx_pcie_enable_interrupts(dra7xx);
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -229,30 +229,9 @@ static void exynos_pcie_assert_reset(str
GPIOF_OUT_INIT_HIGH, "RESET");
}
-static int exynos_pcie_establish_link(struct exynos_pcie *ep)
+static int exynos_pcie_start_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = ep->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = pci->dev;
-
- if (dw_pcie_link_up(pci)) {
- dev_err(dev, "Link already up\n");
- return 0;
- }
-
- exynos_pcie_assert_core_reset(ep);
-
- phy_reset(ep->phy);
-
- exynos_pcie_writel(ep->mem_res->elbi_base, 1,
- PCIE_PWR_RESET);
-
- phy_power_on(ep->phy);
- phy_init(ep->phy);
-
- exynos_pcie_deassert_core_reset(ep);
- dw_pcie_setup_rc(pp);
- exynos_pcie_assert_reset(ep);
+ struct exynos_pcie *ep = to_exynos_pcie(pci);
/* assert LTSSM enable */
exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE,
@@ -386,7 +365,20 @@ static int exynos_pcie_host_init(struct
pp->bridge->ops = &exynos_pci_ops;
- exynos_pcie_establish_link(ep);
+ exynos_pcie_assert_core_reset(ep);
+
+ phy_reset(ep->phy);
+
+ exynos_pcie_writel(ep->mem_res->elbi_base, 1,
+ PCIE_PWR_RESET);
+
+ phy_power_on(ep->phy);
+ phy_init(ep->phy);
+
+ exynos_pcie_deassert_core_reset(ep);
+ dw_pcie_setup_rc(pp);
+ exynos_pcie_assert_reset(ep);
+
exynos_pcie_enable_interrupts(ep);
return 0;
@@ -430,6 +422,7 @@ static const struct dw_pcie_ops dw_pcie_
.read_dbi = exynos_pcie_read_dbi,
.write_dbi = exynos_pcie_write_dbi,
.link_up = exynos_pcie_link_up,
+ .start_link = exynos_pcie_start_link,
};
static int __init exynos_pcie_probe(struct platform_device *pdev)
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -745,9 +745,9 @@ static void imx6_pcie_ltssm_enable(struc
}
}
-static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
+static int imx6_pcie_start_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = imx6_pcie->pci;
+ struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
struct device *dev = pci->dev;
u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
u32 tmp;
@@ -835,7 +835,6 @@ static int imx6_pcie_host_init(struct pc
imx6_pcie_deassert_core_reset(imx6_pcie);
imx6_setup_phy_mpll(imx6_pcie);
dw_pcie_setup_rc(pp);
- imx6_pcie_establish_link(imx6_pcie);
dw_pcie_msi_init(pp);
return 0;
@@ -865,7 +864,7 @@ static int imx6_add_pcie_port(struct imx
}
static const struct dw_pcie_ops dw_pcie_ops = {
- /* No special ops needed, but pcie-designware still expects this struct */
+ .start_link = imx6_pcie_start_link,
};
#ifdef CONFIG_PM_SLEEP
@@ -974,7 +973,7 @@ static int imx6_pcie_resume_noirq(struct
imx6_pcie_deassert_core_reset(imx6_pcie);
dw_pcie_setup_rc(pp);
- ret = imx6_pcie_establish_link(imx6_pcie);
+ ret = imx6_pcie_start_link(imx6_pcie->pci);
if (ret < 0)
dev_info(dev, "pcie link is down after resume.\n");
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -511,14 +511,8 @@ static void ks_pcie_stop_link(struct dw_
static int ks_pcie_start_link(struct dw_pcie *pci)
{
struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
- struct device *dev = pci->dev;
u32 val;
- if (dw_pcie_link_up(pci)) {
- dev_dbg(dev, "link is already up\n");
- return 0;
- }
-
/* Initiate Link Training */
val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val);
@@ -834,9 +828,6 @@ static int __init ks_pcie_host_init(stru
"Asynchronous external abort");
#endif
- ks_pcie_start_link(pci);
- dw_pcie_wait_for_link(pci);
-
return 0;
}
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -231,7 +231,7 @@ static void meson_pcie_assert_reset(stru
gpiod_set_value_cansleep(mp->reset_gpio, 0);
}
-static void meson_pcie_init_dw(struct meson_pcie *mp)
+static void meson_pcie_ltssm_enable(struct meson_pcie *mp)
{
u32 val;
@@ -289,20 +289,14 @@ static void meson_set_max_rd_req_size(st
dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
}
-static int meson_pcie_establish_link(struct meson_pcie *mp)
+static int meson_pcie_start_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = &mp->pci;
- struct pcie_port *pp = &pci->pp;
-
- meson_pcie_init_dw(mp);
- meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
- meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
-
- dw_pcie_setup_rc(pp);
+ struct meson_pcie *mp = to_meson_pcie(pci);
+ meson_pcie_ltssm_enable(mp);
meson_pcie_assert_reset(mp);
- return dw_pcie_wait_for_link(pci);
+ return 0;
}
static int meson_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn,
@@ -380,14 +374,13 @@ static int meson_pcie_host_init(struct p
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct meson_pcie *mp = to_meson_pcie(pci);
- int ret;
pp->bridge->ops = &meson_pci_ops;
- ret = meson_pcie_establish_link(mp);
- if (ret)
- return ret;
+ meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
+ meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
+ dw_pcie_setup_rc(pp);
dw_pcie_msi_init(pp);
return 0;
@@ -418,6 +411,7 @@ static int meson_add_pcie_port(struct me
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = meson_pcie_link_up,
+ .start_link = meson_pcie_start_link,
};
static int meson_pcie_probe(struct platform_device *pdev)
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -154,10 +154,24 @@ static int armada8k_pcie_link_up(struct
return 0;
}
-static void armada8k_pcie_establish_link(struct armada8k_pcie *pcie)
+static int armada8k_pcie_start_link(struct dw_pcie *pci)
+{
+ u32 reg;
+
+ /* Start LTSSM */
+ reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
+ reg |= PCIE_APP_LTSSM_EN;
+ dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg);
+
+ return 0;
+}
+
+static int armada8k_pcie_host_init(struct pcie_port *pp)
{
- struct dw_pcie *pci = pcie->pci;
u32 reg;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ dw_pcie_setup_rc(pp);
if (!dw_pcie_link_up(pci)) {
/* Disable LTSSM state machine to enable configuration */
@@ -193,26 +207,6 @@ static void armada8k_pcie_establish_link
PCIE_INT_C_ASSERT_MASK | PCIE_INT_D_ASSERT_MASK;
dw_pcie_writel_dbi(pci, PCIE_GLOBAL_INT_MASK1_REG, reg);
- if (!dw_pcie_link_up(pci)) {
- /* Configuration done. Start LTSSM */
- reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
- reg |= PCIE_APP_LTSSM_EN;
- dw_pcie_writel_dbi(pci, PCIE_GLOBAL_CONTROL_REG, reg);
- }
-
- /* Wait until the link becomes active again */
- if (dw_pcie_wait_for_link(pci))
- dev_err(pci->dev, "Link not up after reconfiguration\n");
-}
-
-static int armada8k_pcie_host_init(struct pcie_port *pp)
-{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct armada8k_pcie *pcie = to_armada8k_pcie(pci);
-
- dw_pcie_setup_rc(pp);
- armada8k_pcie_establish_link(pcie);
-
return 0;
}
@@ -269,6 +263,7 @@ static int armada8k_add_pcie_port(struct
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = armada8k_pcie_link_up,
+ .start_link = armada8k_pcie_start_link,
};
static int armada8k_pcie_probe(struct platform_device *pdev)
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -329,8 +329,6 @@ static int artpec6_pcie_host_init(struct
artpec6_pcie_deassert_core_reset(artpec6_pcie);
artpec6_pcie_wait_for_phy(artpec6_pcie);
dw_pcie_setup_rc(pp);
- artpec6_pcie_establish_link(pci);
- dw_pcie_wait_for_link(pci);
dw_pcie_msi_init(pp);
return 0;
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -416,6 +416,15 @@ int dw_pcie_host_init(struct pcie_port *
goto err_free_msi;
}
+ if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
+ ret = pci->ops->start_link(pci);
+ if (ret)
+ goto err_free_msi;
+ }
+
+ /* Ignore errors, the link may come up later */
+ dw_pcie_wait_for_link(pci);
+
bridge->sysdata = pp;
ret = pci_host_probe(bridge);
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -35,10 +35,7 @@ static const struct of_device_id dw_plat
static int dw_plat_pcie_host_init(struct pcie_port *pp)
{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
dw_pcie_setup_rc(pp);
- dw_pcie_wait_for_link(pci);
dw_pcie_msi_init(pp);
return 0;
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -169,39 +169,36 @@ static int histb_pcie_link_up(struct dw_
return 0;
}
-static int histb_pcie_establish_link(struct pcie_port *pp)
+static int histb_pcie_start_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct histb_pcie *hipcie = to_histb_pcie(pci);
u32 regval;
- if (dw_pcie_link_up(pci)) {
- dev_info(pci->dev, "Link already up\n");
- return 0;
- }
-
- /* PCIe RC work mode */
- regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
- regval &= ~PCIE_DEVICE_TYPE_MASK;
- regval |= PCIE_WM_RC;
- histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
-
- /* setup root complex */
- dw_pcie_setup_rc(pp);
-
/* assert LTSSM enable */
regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7);
regval |= PCIE_APP_LTSSM_ENABLE;
histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval);
- return dw_pcie_wait_for_link(pci);
+ return 0;
}
static int histb_pcie_host_init(struct pcie_port *pp)
{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct histb_pcie *hipcie = to_histb_pcie(pci);
+ u32 regval;
+
pp->bridge->ops = &histb_pci_ops;
- histb_pcie_establish_link(pp);
+ /* PCIe RC work mode */
+ regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0);
+ regval &= ~PCIE_DEVICE_TYPE_MASK;
+ regval |= PCIE_WM_RC;
+ histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
+
+ /* setup root complex */
+ dw_pcie_setup_rc(pp);
+
dw_pcie_msi_init(pp);
return 0;
@@ -300,6 +297,7 @@ static const struct dw_pcie_ops dw_pcie_
.read_dbi = histb_pcie_read_dbi,
.write_dbi = histb_pcie_write_dbi,
.link_up = histb_pcie_link_up,
+ .start_link = histb_pcie_start_link,
};
static int histb_pcie_probe(struct platform_device *pdev)
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -395,32 +395,14 @@ static int kirin_pcie_link_up(struct dw_
return 0;
}
-static int kirin_pcie_establish_link(struct pcie_port *pp)
+static int kirin_pcie_start_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci);
- struct device *dev = kirin_pcie->pci->dev;
- int count = 0;
-
- if (kirin_pcie_link_up(pci))
- return 0;
-
- dw_pcie_setup_rc(pp);
/* assert LTSSM enable */
kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT,
PCIE_APP_LTSSM_ENABLE);
- /* check if the link is up or not */
- while (!kirin_pcie_link_up(pci)) {
- usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
- count++;
- if (count == 1000) {
- dev_err(dev, "Link Fail\n");
- return -EINVAL;
- }
- }
-
return 0;
}
@@ -428,7 +410,7 @@ static int kirin_pcie_host_init(struct p
{
pp->bridge->ops = &kirin_pci_ops;
- kirin_pcie_establish_link(pp);
+ dw_pcie_setup_rc(pp);
dw_pcie_msi_init(pp);
return 0;
@@ -438,6 +420,7 @@ static const struct dw_pcie_ops kirin_dw
.read_dbi = kirin_pcie_read_dbi,
.write_dbi = kirin_pcie_write_dbi,
.link_up = kirin_pcie_link_up,
+ .start_link = kirin_pcie_start_link,
};
static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -207,18 +207,15 @@ static void qcom_ep_reset_deassert(struc
usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
}
-static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
+static int qcom_pcie_start_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = pcie->pci;
-
- if (dw_pcie_link_up(pci))
- return 0;
+ struct qcom_pcie *pcie = to_qcom_pcie(pci);
/* Enable Link Training state machine */
if (pcie->ops->ltssm_enable)
pcie->ops->ltssm_enable(pcie);
- return dw_pcie_wait_for_link(pci);
+ return 0;
}
static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie)
@@ -1290,15 +1287,8 @@ static int qcom_pcie_host_init(struct pc
qcom_ep_reset_deassert(pcie);
- ret = qcom_pcie_establish_link(pcie);
- if (ret)
- goto err;
-
return 0;
-err:
- qcom_ep_reset_assert(pcie);
- if (pcie->ops->post_deinit)
- pcie->ops->post_deinit(pcie);
+
err_disable_phy:
phy_power_off(pcie->phy);
err_deinit:
@@ -1365,6 +1355,7 @@ static const struct qcom_pcie_ops ops_2_
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
+ .start_link = qcom_pcie_start_link,
};
static int qcom_pcie_probe(struct platform_device *pdev)
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1549,7 +1549,6 @@ static int tegra_pcie_deinit_controller(
static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
{
- struct pcie_port *pp = &pcie->pci.pp;
struct device *dev = pcie->dev;
char *name;
int ret;
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -146,16 +146,13 @@ static int uniphier_pcie_link_up(struct
return (val & mask) == mask;
}
-static int uniphier_pcie_establish_link(struct dw_pcie *pci)
+static int uniphier_pcie_start_link(struct dw_pcie *pci)
{
struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
- if (dw_pcie_link_up(pci))
- return 0;
-
uniphier_pcie_ltssm_enable(priv, true);
- return dw_pcie_wait_for_link(pci);
+ return 0;
}
static void uniphier_pcie_stop_link(struct dw_pcie *pci)
@@ -312,10 +309,6 @@ static int uniphier_pcie_host_init(struc
uniphier_pcie_irq_enable(priv);
dw_pcie_setup_rc(pp);
- ret = uniphier_pcie_establish_link(pci);
- if (ret)
- return ret;
-
dw_pcie_msi_init(pp);
return 0;
@@ -379,7 +372,7 @@ out_clk_disable:
}
static const struct dw_pcie_ops dw_pcie_ops = {
- .start_link = uniphier_pcie_establish_link,
+ .start_link = uniphier_pcie_start_link,
.stop_link = uniphier_pcie_stop_link,
.link_up = uniphier_pcie_link_up,
};

View File

@ -1,272 +0,0 @@
From 02c98d70da854cd4d145afe800194768c5eefe1d Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Thu, 5 Nov 2020 15:11:54 -0600
Subject: [PATCH 5/5] PCI: dwc: Move dw_pcie_msi_init() into core
The host drivers which call dw_pcie_msi_init() are all the ones using
the built-in MSI controller, so let's move it into the common DWC code.
Link: https://lore.kernel.org/r/20201105211159.1814485-12-robh@kernel.org
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Yue Wang <yue.wang@Amlogic.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
Cc: Andy Gross <agross@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Pratyush Anand <pratyush.anand@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linux-omap@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@axis.com
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-tegra@vger.kernel.org
---
drivers/pci/controller/dwc/pci-dra7xx.c | 2 --
drivers/pci/controller/dwc/pci-exynos.c | 4 ----
drivers/pci/controller/dwc/pci-imx6.c | 1 -
drivers/pci/controller/dwc/pci-meson.c | 1 -
drivers/pci/controller/dwc/pcie-artpec6.c | 1 -
drivers/pci/controller/dwc/pcie-designware-host.c | 9 +++++----
drivers/pci/controller/dwc/pcie-designware-plat.c | 1 -
drivers/pci/controller/dwc/pcie-designware.h | 10 ----------
drivers/pci/controller/dwc/pcie-histb.c | 2 --
drivers/pci/controller/dwc/pcie-kirin.c | 1 -
drivers/pci/controller/dwc/pcie-qcom.c | 2 --
drivers/pci/controller/dwc/pcie-spear13xx.c | 6 +-----
drivers/pci/controller/dwc/pcie-tegra194.c | 2 --
drivers/pci/controller/dwc/pcie-uniphier.c | 1 -
14 files changed, 6 insertions(+), 37 deletions(-)
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -182,8 +182,6 @@ static int dra7xx_pcie_host_init(struct
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
dw_pcie_setup_rc(pp);
-
- dw_pcie_msi_init(pp);
dra7xx_pcie_enable_interrupts(dra7xx);
return 0;
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -273,12 +273,8 @@ static irqreturn_t exynos_pcie_irq_handl
static void exynos_pcie_msi_init(struct exynos_pcie *ep)
{
- struct dw_pcie *pci = ep->pci;
- struct pcie_port *pp = &pci->pp;
u32 val;
- dw_pcie_msi_init(pp);
-
/* enable MSI interrupt */
val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_EN_LEVEL);
val |= IRQ_MSI_ENABLE;
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -835,7 +835,6 @@ static int imx6_pcie_host_init(struct pc
imx6_pcie_deassert_core_reset(imx6_pcie);
imx6_setup_phy_mpll(imx6_pcie);
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
return 0;
}
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -381,7 +381,6 @@ static int meson_pcie_host_init(struct p
meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
return 0;
}
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -329,7 +329,6 @@ static int artpec6_pcie_host_init(struct
artpec6_pcie_deassert_core_reset(artpec6_pcie);
artpec6_pcie_wait_for_phy(artpec6_pcie);
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
return 0;
}
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -256,7 +256,7 @@ int dw_pcie_allocate_domains(struct pcie
return 0;
}
-void dw_pcie_free_msi(struct pcie_port *pp)
+static void dw_pcie_free_msi(struct pcie_port *pp)
{
if (pp->msi_irq) {
irq_set_chained_handler(pp->msi_irq, NULL);
@@ -275,19 +275,18 @@ void dw_pcie_free_msi(struct pcie_port *
}
}
-void dw_pcie_msi_init(struct pcie_port *pp)
+static void dw_pcie_msi_init(struct pcie_port *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
u64 msi_target = (u64)pp->msi_data;
- if (!IS_ENABLED(CONFIG_PCI_MSI))
+ if (!pci_msi_enabled() || !pp->has_msi_ctrl)
return;
/* Program the msi_data */
dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, lower_32_bits(msi_target));
dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, upper_32_bits(msi_target));
}
-EXPORT_SYMBOL_GPL(dw_pcie_msi_init);
int dw_pcie_host_init(struct pcie_port *pp)
{
@@ -416,6 +415,8 @@ int dw_pcie_host_init(struct pcie_port *
goto err_free_msi;
}
+ dw_pcie_msi_init(pp);
+
if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
ret = pci->ops->start_link(pci);
if (ret)
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -36,7 +36,6 @@ static const struct of_device_id dw_plat
static int dw_plat_pcie_host_init(struct pcie_port *pp)
{
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
return 0;
}
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -365,8 +365,6 @@ static inline void dw_pcie_dbi_ro_wr_dis
#ifdef CONFIG_PCIE_DW_HOST
irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
-void dw_pcie_msi_init(struct pcie_port *pp);
-void dw_pcie_free_msi(struct pcie_port *pp);
void dw_pcie_setup_rc(struct pcie_port *pp);
int dw_pcie_host_init(struct pcie_port *pp);
void dw_pcie_host_deinit(struct pcie_port *pp);
@@ -379,14 +377,6 @@ static inline irqreturn_t dw_handle_msi_
return IRQ_NONE;
}
-static inline void dw_pcie_msi_init(struct pcie_port *pp)
-{
-}
-
-static inline void dw_pcie_free_msi(struct pcie_port *pp)
-{
-}
-
static inline void dw_pcie_setup_rc(struct pcie_port *pp)
{
}
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -199,8 +199,6 @@ static int histb_pcie_host_init(struct p
/* setup root complex */
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
-
return 0;
}
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -411,7 +411,6 @@ static int kirin_pcie_host_init(struct p
pp->bridge->ops = &kirin_pci_ops;
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
return 0;
}
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1283,8 +1283,6 @@ static int qcom_pcie_host_init(struct pc
}
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
-
qcom_ep_reset_deassert(pcie);
return 0;
--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
+++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
@@ -124,16 +124,12 @@ static irqreturn_t spear13xx_pcie_irq_ha
static void spear13xx_pcie_enable_interrupts(struct spear13xx_pcie *spear13xx_pcie)
{
- struct dw_pcie *pci = spear13xx_pcie->pci;
- struct pcie_port *pp = &pci->pp;
struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
/* Enable MSI interrupt */
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- dw_pcie_msi_init(pp);
+ if (IS_ENABLED(CONFIG_PCI_MSI))
writel(readl(&app_reg->int_mask) |
MSI_CTRL_INT, &app_reg->int_mask);
- }
}
static int spear13xx_pcie_link_up(struct dw_pcie *pci)
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -765,8 +765,6 @@ static void tegra_pcie_enable_msi_interr
struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
u32 val;
- dw_pcie_msi_init(pp);
-
/* Enable MSI interrupt generation */
val = appl_readl(pcie, APPL_INTR_EN_L0_0);
val |= APPL_INTR_EN_L0_0_SYS_MSI_INTR_EN;
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -309,7 +309,6 @@ static int uniphier_pcie_host_init(struc
uniphier_pcie_irq_enable(priv);
dw_pcie_setup_rc(pp);
- dw_pcie_msi_init(pp);
return 0;
}

View File

@ -1,54 +0,0 @@
From 8d111d707f71bc17c616b0bcca327ee0a3db50e8 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Mon, 2 Nov 2020 19:03:59 +0100
Subject: [PATCH] clk: qcom: ipq8074: fix PCI-E clock oops
Fix PCI-E clock related kernel oops that are causes by missing
parent_names.
Without the use of parent_names kernel will panic on
clk_core_get_parent_by_index() due to a NULL pointer.
Without this earlycon is needed to even catch the OOPS as it will reset
the board before serial is initialized.
Fixes: f0cfcf1ade20 ("clk: qcom: ipq8074: Add missing clocks for pcie")
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/clk/qcom/gcc-ipq8074.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4329,8 +4329,7 @@ static struct clk_rcg2 pcie0_rchng_clk_s
.parent_map = gcc_xo_gpll0_map,
.clkr.hw.init = &(struct clk_init_data){
.name = "pcie0_rchng_clk_src",
- .parent_hws = (const struct clk_hw *[]) {
- &gpll0.clkr.hw },
+ .parent_names = gcc_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
@@ -4344,8 +4343,8 @@ static struct clk_branch gcc_pcie0_rchng
.enable_mask = BIT(1),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie0_rchng_clk",
- .parent_hws = (const struct clk_hw *[]){
- &pcie0_rchng_clk_src.clkr.hw,
+ .parent_names = (const char *[]){
+ "pcie0_rchng_clk_src",
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -4362,8 +4361,8 @@ static struct clk_branch gcc_pcie0_axi_s
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie0_axi_s_bridge_clk",
- .parent_hws = (const struct clk_hw *[]){
- &pcie0_axi_clk_src.clkr.hw,
+ .parent_names = (const char *[]){
+ "pcie0_axi_clk_src"
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,

View File

@ -1,48 +0,0 @@
From 69581d91675df8c0d9b5f746de7c2f3d73344280 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 May 2021 15:10:37 +0200
Subject: [PATCH] arm64: dts: ipq8074: add crypto nodes
IPQ8074 uses Qualcom QCE crypto engine v5.1
which is already supported.
So simply add nodes for its DMA and QCE itself.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -197,6 +197,30 @@
status = "disabled";
};
+ cryptobam: dma@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 = <1>;
+ 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,ipq8074-pinctrl";
reg = <0x01000000 0x300000>;

View File

@ -1,30 +0,0 @@
From ff46c62852e862ac360aeb1054180c8e715fbeb4 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 May 2021 15:23:53 +0200
Subject: [PATCH] arm64: dts: ipq8074: add PRNG node
PRNG insinde of IPQ8074 is already supported,
so simply add the node for it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -197,6 +197,14 @@
status = "disabled";
};
+ prng: rng@e3000 {
+ compatible = "qcom,prng-ee";
+ reg = <0x000e3000 0x1000>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
cryptobam: dma@704000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x00704000 0x20000>;

View File

@ -1,155 +0,0 @@
From e0d3c4e232c2b29532f7b894485814782201fdd9 Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:05 +0530
Subject: [PATCH 08/16] remoteproc: qcom: Add PRNG proxy clock
PRNG clock is needed by the secure PIL, support for the same
is added in subsequent patches.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 65 +++++++++++++++++++++--------
1 file changed, 47 insertions(+), 18 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -91,19 +91,6 @@ enum {
WCSS_QCS404,
};
-struct wcss_data {
- const char *firmware_name;
- unsigned int crash_reason_smem;
- u32 version;
- bool aon_reset_required;
- bool wcss_q6_reset_required;
- const char *ssr_name;
- const char *sysmon_name;
- int ssctl_id;
- const struct rproc_ops *ops;
- bool requires_force_stop;
-};
-
struct q6v5_wcss {
struct device *dev;
@@ -128,6 +115,7 @@ struct q6v5_wcss {
struct clk *qdsp6ss_xo_cbcr;
struct clk *qdsp6ss_core_gfmux;
struct clk *lcc_bcr_sleep;
+ struct clk *prng_clk;
struct regulator *cx_supply;
struct qcom_sysmon *sysmon;
@@ -151,6 +139,21 @@ struct q6v5_wcss {
struct qcom_rproc_ssr ssr_subdev;
};
+struct wcss_data {
+ int (*init_clock)(struct q6v5_wcss *wcss);
+ int (*init_regulator)(struct q6v5_wcss *wcss);
+ const char *firmware_name;
+ unsigned int crash_reason_smem;
+ u32 version;
+ bool aon_reset_required;
+ bool wcss_q6_reset_required;
+ const char *ssr_name;
+ const char *sysmon_name;
+ int ssctl_id;
+ const struct rproc_ops *ops;
+ bool requires_force_stop;
+};
+
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
{
int ret;
@@ -240,6 +243,12 @@ static int q6v5_wcss_start(struct rproc
struct q6v5_wcss *wcss = rproc->priv;
int ret;
+ ret = clk_prepare_enable(wcss->prng_clk);
+ if (ret) {
+ dev_err(wcss->dev, "prng clock enable failed\n");
+ return ret;
+ }
+
qcom_q6v5_prepare(&wcss->q6v5);
/* Release Q6 and WCSS reset */
@@ -732,6 +741,7 @@ static int q6v5_wcss_stop(struct rproc *
return ret;
}
+ clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
return 0;
@@ -896,7 +906,21 @@ static int q6v5_alloc_memory_region(stru
return 0;
}
-static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
+static int ipq8074_init_clock(struct q6v5_wcss *wcss)
+{
+ int ret;
+
+ wcss->prng_clk = devm_clk_get(wcss->dev, "prng");
+ if (IS_ERR(wcss->prng_clk)) {
+ ret = PTR_ERR(wcss->prng_clk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(wcss->dev, "Failed to get prng clock\n");
+ return ret;
+ }
+ return 0;
+}
+
+static int qcs404_init_clock(struct q6v5_wcss *wcss)
{
int ret;
@@ -986,7 +1010,7 @@ static int q6v5_wcss_init_clock(struct q
return 0;
}
-static int q6v5_wcss_init_regulator(struct q6v5_wcss *wcss)
+static int qcs404_init_regulator(struct q6v5_wcss *wcss)
{
wcss->cx_supply = devm_regulator_get(wcss->dev, "cx");
if (IS_ERR(wcss->cx_supply))
@@ -1030,12 +1054,14 @@ static int q6v5_wcss_probe(struct platfo
if (ret)
goto free_rproc;
- if (wcss->version == WCSS_QCS404) {
- ret = q6v5_wcss_init_clock(wcss);
+ if (desc->init_clock) {
+ ret = desc->init_clock(wcss);
if (ret)
goto free_rproc;
+ }
- ret = q6v5_wcss_init_regulator(wcss);
+ if (desc->init_regulator) {
+ ret = desc->init_regulator(wcss);
if (ret)
goto free_rproc;
}
@@ -1082,6 +1108,7 @@ static int q6v5_wcss_remove(struct platf
}
static const struct wcss_data wcss_ipq8074_res_init = {
+ .init_clock = ipq8074_init_clock,
.firmware_name = "IPQ8074/q6_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
@@ -1091,6 +1118,8 @@ static const struct wcss_data wcss_ipq80
};
static const struct wcss_data wcss_qcs404_res_init = {
+ .init_clock = qcs404_init_clock,
+ .init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
.firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,

View File

@ -1,143 +0,0 @@
From a6256ebbd66f3457e4a285b72b362d452bc6854f Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:06 +0530
Subject: [PATCH 09/16] remoteproc: qcom: Add secure PIL support
IPQ8074 uses secure PIL. Hence, adding the support for the same.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 43 +++++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 3 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -18,6 +18,7 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/qcom_scm.h>
#include "qcom_common.h"
#include "qcom_pil_info.h"
#include "qcom_q6v5.h"
@@ -86,6 +87,9 @@
#define TCSR_WCSS_CLK_ENABLE 0x14
#define MAX_HALT_REG 3
+
+#define WCNSS_PAS_ID 6
+
enum {
WCSS_IPQ8074,
WCSS_QCS404,
@@ -134,6 +138,7 @@ struct q6v5_wcss {
unsigned int crash_reason_smem;
u32 version;
bool requires_force_stop;
+ bool need_mem_protection;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
@@ -152,6 +157,7 @@ struct wcss_data {
int ssctl_id;
const struct rproc_ops *ops;
bool requires_force_stop;
+ bool need_mem_protection;
};
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -251,6 +257,15 @@ static int q6v5_wcss_start(struct rproc
qcom_q6v5_prepare(&wcss->q6v5);
+ if (wcss->need_mem_protection) {
+ ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
+ if (ret) {
+ dev_err(wcss->dev, "wcss_reset failed\n");
+ return ret;
+ }
+ goto wait_for_reset;
+ }
+
/* Release Q6 and WCSS reset */
ret = reset_control_deassert(wcss->wcss_reset);
if (ret) {
@@ -285,6 +300,7 @@ static int q6v5_wcss_start(struct rproc
if (ret)
goto wcss_q6_reset;
+wait_for_reset:
ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
if (ret == -ETIMEDOUT)
dev_err(wcss->dev, "start timed out\n");
@@ -717,6 +733,15 @@ static int q6v5_wcss_stop(struct rproc *
struct q6v5_wcss *wcss = rproc->priv;
int ret;
+ if (wcss->need_mem_protection) {
+ ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
+ if (ret) {
+ dev_err(wcss->dev, "not able to shutdown\n");
+ return ret;
+ }
+ goto pas_done;
+ }
+
/* WCSS powerdown */
if (wcss->requires_force_stop) {
ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
@@ -741,6 +766,7 @@ static int q6v5_wcss_stop(struct rproc *
return ret;
}
+pas_done:
clk_disable_unprepare(wcss->prng_clk);
qcom_q6v5_unprepare(&wcss->q6v5);
@@ -764,9 +790,15 @@ static int q6v5_wcss_load(struct rproc *
struct q6v5_wcss *wcss = rproc->priv;
int ret;
- ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
- 0, wcss->mem_region, wcss->mem_phys,
- wcss->mem_size, &wcss->mem_reloc);
+ if (wcss->need_mem_protection)
+ ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
+ WCNSS_PAS_ID, wcss->mem_region,
+ wcss->mem_phys, wcss->mem_size,
+ &wcss->mem_reloc);
+ else
+ ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
+ 0, wcss->mem_region, wcss->mem_phys,
+ wcss->mem_size, &wcss->mem_reloc);
if (ret)
return ret;
@@ -1032,6 +1064,9 @@ static int q6v5_wcss_probe(struct platfo
if (!desc)
return -EINVAL;
+ if (desc->need_mem_protection && !qcom_scm_is_available())
+ return -EPROBE_DEFER;
+
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
if (!rproc) {
@@ -1045,6 +1080,7 @@ static int q6v5_wcss_probe(struct platfo
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
+ wcss->need_mem_protection = desc->need_mem_protection;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1115,6 +1151,7 @@ static const struct wcss_data wcss_ipq80
.wcss_q6_reset_required = true,
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
+ .need_mem_protection = true,
};
static const struct wcss_data wcss_qcs404_res_init = {

View File

@ -1,104 +0,0 @@
From ea44aa0384fec6d6fcd5bf6bf52175628bad7319 Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:07 +0530
Subject: [PATCH 10/16] remoteproc: qcom: Add support for split q6 + m3 wlan
firmware
IPQ8074 supports split firmware for q6 and m3 as well.
So add support for loading the m3 firmware before q6.
Now the drivers works fine for both split and unified
firmwares.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 33 +++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -139,6 +139,7 @@ struct q6v5_wcss {
u32 version;
bool requires_force_stop;
bool need_mem_protection;
+ const char *m3_firmware_name;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_ssr ssr_subdev;
@@ -147,7 +148,8 @@ struct q6v5_wcss {
struct wcss_data {
int (*init_clock)(struct q6v5_wcss *wcss);
int (*init_regulator)(struct q6v5_wcss *wcss);
- const char *firmware_name;
+ const char *q6_firmware_name;
+ const char *m3_firmware_name;
unsigned int crash_reason_smem;
u32 version;
bool aon_reset_required;
@@ -788,8 +790,29 @@ static void *q6v5_wcss_da_to_va(struct r
static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
{
struct q6v5_wcss *wcss = rproc->priv;
+ const struct firmware *m3_fw;
int ret;
+ if (wcss->m3_firmware_name) {
+ ret = request_firmware(&m3_fw, wcss->m3_firmware_name,
+ wcss->dev);
+ if (ret)
+ goto skip_m3;
+
+ ret = qcom_mdt_load_no_init(wcss->dev, m3_fw,
+ wcss->m3_firmware_name, 0,
+ wcss->mem_region, wcss->mem_phys,
+ wcss->mem_size, &wcss->mem_reloc);
+
+ release_firmware(m3_fw);
+
+ if (ret) {
+ dev_err(wcss->dev, "can't load m3_fw.bXX\n");
+ return ret;
+ }
+ }
+
+skip_m3:
if (wcss->need_mem_protection)
ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
WCNSS_PAS_ID, wcss->mem_region,
@@ -1068,7 +1091,7 @@ static int q6v5_wcss_probe(struct platfo
return -EPROBE_DEFER;
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
- desc->firmware_name, sizeof(*wcss));
+ desc->q6_firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@@ -1081,6 +1104,7 @@ static int q6v5_wcss_probe(struct platfo
wcss->version = desc->version;
wcss->requires_force_stop = desc->requires_force_stop;
wcss->need_mem_protection = desc->need_mem_protection;
+ wcss->m3_firmware_name = desc->m3_firmware_name;
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
@@ -1145,7 +1169,8 @@ static int q6v5_wcss_remove(struct platf
static const struct wcss_data wcss_ipq8074_res_init = {
.init_clock = ipq8074_init_clock,
- .firmware_name = "IPQ8074/q6_fw.mdt",
+ .q6_firmware_name = "IPQ8074/q6_fw.mdt",
+ .m3_firmware_name = "IPQ8074/m3_fw.mdt",
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
@@ -1158,7 +1183,7 @@ static const struct wcss_data wcss_qcs40
.init_clock = qcs404_init_clock,
.init_regulator = qcs404_init_regulator,
.crash_reason_smem = WCSS_CRASH_REASON,
- .firmware_name = "wcnss.mdt",
+ .q6_firmware_name = "wcnss.mdt",
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,

View File

@ -1,24 +0,0 @@
From dcfc2e3a3e346e0cad4c5b8707aaab96f4bbb59d Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:08 +0530
Subject: [PATCH 11/16] remoteproc: qcom: Add ssr subdevice identifier
Add name for ssr subdevice on IPQ8074 SoC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -1174,6 +1174,7 @@ static const struct wcss_data wcss_ipq80
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
+ .ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,

View File

@ -1,80 +0,0 @@
From 543a7093420b500a197fc64361084613f248f07a Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:09 +0530
Subject: [PATCH 12/16] remoteproc: qcom: Update regmap offsets for halt
register
Fixed issue in reading halt-regs parameter from device-tree.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -86,7 +86,7 @@
#define TCSR_WCSS_CLK_MASK 0x1F
#define TCSR_WCSS_CLK_ENABLE 0x14
-#define MAX_HALT_REG 3
+#define MAX_HALT_REG 4
#define WCNSS_PAS_ID 6
@@ -154,6 +154,7 @@ struct wcss_data {
u32 version;
bool aon_reset_required;
bool wcss_q6_reset_required;
+ bool bcr_reset_required;
const char *ssr_name;
const char *sysmon_name;
int ssctl_id;
@@ -874,10 +875,13 @@ static int q6v5_wcss_init_reset(struct q
}
}
- wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_bcr_reset");
- if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
- dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
- return PTR_ERR(wcss->wcss_q6_bcr_reset);
+ if (desc->bcr_reset_required) {
+ wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev,
+ "wcss_q6_bcr_reset");
+ if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
+ dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
+ return PTR_ERR(wcss->wcss_q6_bcr_reset);
+ }
}
return 0;
@@ -925,9 +929,9 @@ static int q6v5_wcss_init_mmio(struct q6
return -EINVAL;
}
- wcss->halt_q6 = halt_reg[0];
- wcss->halt_wcss = halt_reg[1];
- wcss->halt_nc = halt_reg[2];
+ wcss->halt_q6 = halt_reg[1];
+ wcss->halt_wcss = halt_reg[2];
+ wcss->halt_nc = halt_reg[3];
return 0;
}
@@ -1174,6 +1178,7 @@ static const struct wcss_data wcss_ipq80
.crash_reason_smem = WCSS_CRASH_REASON,
.aon_reset_required = true,
.wcss_q6_reset_required = true,
+ .bcr_reset_required = false,
.ssr_name = "q6wcss",
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
@@ -1188,6 +1193,7 @@ static const struct wcss_data wcss_qcs40
.version = WCSS_QCS404,
.aon_reset_required = false,
.wcss_q6_reset_required = false,
+ .bcr_reset_required = true,
.ssr_name = "mpss",
.sysmon_name = "wcnss",
.ssctl_id = 0x12,

View File

@ -1,25 +0,0 @@
From 12c7588316e1aceb3a4918896735e8bc3757815f Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:10 +0530
Subject: [PATCH 13/16] dt-bindings: clock: qcom: Add reset for WCSSAON
Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
---
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
1 file changed, 1 insertion(+)
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -366,5 +366,6 @@
#define GCC_PCIE1_AHB_ARES 129
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
#define GCC_PCIE0_AXI_SLAVE_STICKY_ARES 131
+#define GCC_WCSSAON_RESET 132
#endif

View File

@ -1,25 +0,0 @@
From 6de5e246382d6b15f297cadbf26bdd78ee7f9fea Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:11 +0530
Subject: [PATCH 14/16] clk: qcom: Add WCSSAON reset
Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
---
drivers/clk/qcom/gcc-ipq8074.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4744,6 +4744,7 @@ static const struct qcom_reset_map gcc_i
[GCC_PCIE1_AXI_SLAVE_ARES] = { 0x76040, 4 },
[GCC_PCIE1_AHB_ARES] = { 0x76040, 5 },
[GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 },
+ [GCC_WCSSAON_RESET] = { 0x59010, 0 },
};
static const struct of_device_id gcc_ipq8074_match_table[] = {

View File

@ -1,28 +0,0 @@
From b177148d326cac30723f5fe9c939db2919aab33a Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:12 +0530
Subject: [PATCH 15/16] arm64: dts: Add support for scm on IPQ8074 SoCs
Enables scm support, clock is not needed for enabling scm interface.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -76,6 +76,12 @@
method = "smc";
};
+ firmware {
+ scm {
+ compatible = "qcom,scm-ipq8074", "qcom,scm";
+ };
+ };
+
soc: soc {
#address-cells = <0x1>;
#size-cells = <0x1>;

View File

@ -1,158 +0,0 @@
From 9428cd325c99212b25407df8035284012d65acdb Mon Sep 17 00:00:00 2001
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Date: Sat, 30 Jan 2021 10:50:13 +0530
Subject: [PATCH 16/16] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC
Enable remoteproc WCSS PIL driver with glink
and ssr subdevices. Also configures shared memory
and enables smp2p and mailboxes required for IPC.
Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 121 ++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -76,12 +76,66 @@
method = "smc";
};
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ smem_region: memory@4ab00000 {
+ no-map;
+ reg = <0x0 0x4ab00000 0x0 0x00100000>;
+ };
+
+ q6_region: memory@4b000000 {
+ no-map;
+ reg = <0x0 0x4b000000 0x0 0x05f00000>;
+ };
+ };
+
firmware {
scm {
compatible = "qcom,scm-ipq8074", "qcom,scm";
};
};
+ tcsr_mutex: hwlock@193d000 {
+ compatible = "qcom,tcsr-mutex";
+ syscon = <&tcsr_mutex_regs 0 0x80>;
+ #hwlock-cells = <1>;
+ };
+
+ smem {
+ compatible = "qcom,smem";
+ memory-region = <&smem_region>;
+ hwlocks = <&tcsr_mutex 0>;
+ };
+
+ wcss: smp2p-wcss {
+ compatible = "qcom,smp2p";
+ qcom,smem = <435>, <428>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <0 322 1>;
+
+ mboxes = <&apcs_glb 9>;
+
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <1>;
+
+ wcss_smp2p_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ qcom,smp2p-feature-ssr-ack;
+ #qcom,smem-state-cells = <1>;
+ };
+
+ wcss_smp2p_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
soc: soc {
#address-cells = <0x1>;
#size-cells = <0x1>;
@@ -727,5 +781,72 @@
"axi_m_sticky";
status = "disabled";
};
+
+ tcsr_q6: syscon@1945000 {
+ compatible = "syscon";
+ reg = <0x01945000 0xe000>;
+ };
+
+ tcsr_mutex_regs: syscon@193d000 {
+ compatible = "syscon";
+ reg = <0x01905000 0x8000>;
+ };
+
+ apcs_glb: mailbox@b111000 {
+ compatible = "qcom,ipq8074-apcs-apps-global";
+ reg = <0x0b111000 0x1000>;
+
+ #mbox-cells = <1>;
+ };
+
+ q6v5_wcss: q6v5_wcss@cd00000 {
+ compatible = "qcom,ipq8074-wcss-pil";
+ reg = <0x0cd00000 0x4040>,
+ <0x004ab000 0x20>;
+ reg-names = "qdsp6",
+ "rmb";
+ qca,auto-restart;
+ qca,extended-intc;
+ interrupts-extended = <&intc 0 325 1>,
+ <&wcss_smp2p_in 0 0>,
+ <&wcss_smp2p_in 1 0>,
+ <&wcss_smp2p_in 2 0>,
+ <&wcss_smp2p_in 3 0>;
+ interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack";
+
+ resets = <&gcc GCC_WCSSAON_RESET>,
+ <&gcc GCC_WCSS_BCR>,
+ <&gcc GCC_WCSS_Q6_BCR>;
+
+ reset-names = "wcss_aon_reset",
+ "wcss_reset",
+ "wcss_q6_reset";
+
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "prng";
+
+ qcom,halt-regs = <&tcsr_q6 0xa000 0xd000 0x0>;
+
+ qcom,smem-states = <&wcss_smp2p_out 0>,
+ <&wcss_smp2p_out 1>;
+ qcom,smem-state-names = "shutdown",
+ "stop";
+
+ memory-region = <&q6_region>;
+
+ glink-edge {
+ interrupts = <GIC_SPI 321 IRQ_TYPE_EDGE_RISING>;
+ qcom,remote-pid = <1>;
+ mboxes = <&apcs_glb 8>;
+
+ rpm_requests {
+ qcom,glink-channels = "IPCRTR";
+ };
+ };
+ };
};
};

View File

@ -1,35 +0,0 @@
From 5454294f432c0c095f3e2b54fd45491be779c545 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 May 2021 18:11:13 +0200
Subject: [PATCH] soc: qcom: socinfo: Add IPQ8074 SoC family ID-s
Add ID-s for the Qualcomm IPQ8074 SoC family.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/soc/qcom/socinfo.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -224,8 +224,20 @@ static const struct soc_id soc_id[] = {
{ 312, "APQ8096SG" },
{ 318, "SDM630" },
{ 321, "SDM845" },
+ { 323, "IPQ8074" },
{ 341, "SDA845" },
+ { 342, "IPQ8072" },
+ { 343, "IPQ8076" },
+ { 344, "IPQ8078" },
{ 356, "SM8250" },
+ { 375, "IPQ8070" },
+ { 376, "IPQ8071" },
+ { 389, "IPQ8072A" },
+ { 390, "IPQ8074A" },
+ { 391, "IPQ8076A" },
+ { 392, "IPQ8078A" },
+ { 395, "IPQ8070A" },
+ { 396, "IPQ8071A" },
{ 402, "IPQ6018" },
{ 425, "SC7180" },
};

View File

@ -1,49 +0,0 @@
From d91c466ec19e5ced30631cec703164c79525b986 Mon Sep 17 00:00:00 2001
From: Robert Marko <robert.marko@sartura.hr>
Date: Sun, 27 Dec 2020 18:55:56 +0100
Subject: [PATCH] net: mdio-ipq4019: add clock handling
Newer SoC-s like IPQ807x and IPQ60xx use the same MDIO controller,
but have separate MDIO clocks that need to be handled.
So lets add support for doing that.
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
---
drivers/net/mdio/mdio-ipq4019.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/drivers/net/mdio/mdio-ipq4019.c
+++ b/drivers/net/mdio/mdio-ipq4019.c
@@ -2,6 +2,7 @@
/* Copyright (c) 2015, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2020 Sartura Ltd. */
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -33,6 +34,7 @@
struct ipq4019_mdio_data {
void __iomem *membase;
+ struct clk *clk;
};
static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
@@ -187,6 +189,16 @@ static int ipq4019_mdio_probe(struct pla
if (IS_ERR(priv->membase))
return PTR_ERR(priv->membase);
+ priv->clk = devm_clk_get_optional(&pdev->dev, "mdio_ahb");
+ if (IS_ERR(priv->clk)) {
+ dev_err(&pdev->dev, "Failed getting clock!\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+
bus->name = "ipq4019_mdio";
bus->read = ipq4019_mdio_read;
bus->write = ipq4019_mdio_write;

View File

@ -1,34 +0,0 @@
From 67ba6e563928123fc65dab604592a60da2cce648 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 May 2021 18:24:35 +0200
Subject: [PATCH] arm64: dts: ipq8074: Add MDIO support
MDIO controller is the same one as in IPQ4019, so
lets add the node to support it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -257,6 +257,18 @@
status = "disabled";
};
+ mdio: mdio@90000 {
+ compatible = "qcom,ipq4019-mdio";
+ reg = <0x00090000 0x64>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clocks = <&gcc GCC_MDIO_AHB_CLK>;
+ clock-names = "mdio_ahb";
+
+ status = "disabled";
+ };
+
prng: rng@e3000 {
compatible = "qcom,prng-ee";
reg = <0x000e3000 0x1000>;

View File

@ -1,369 +0,0 @@
From 57887b141d68224dcf4039a2f5215011f43dd9f4 Mon Sep 17 00:00:00 2001
From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Date: Wed, 29 Jul 2020 21:00:04 +0530
Subject: [PATCH] phy: qcom-qmp: Add IPQ8074 PCIe Gen3 QMP PHY support
IPQ8074 has two PCIe ports, One Gen2 and one Gen3 port.
Since support for Gen2 PHY is already available, add support for
PCIe Gen3 PHY.
Co-developed-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h | 139 ++++++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp.c | 171 +++++++++++++++++++++-
2 files changed, 308 insertions(+), 2 deletions(-)
create mode 100644 drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-pcie3-qmp.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef PHY_QCOM_PCIE_H
+#define PHY_QCOM_PCIE_H
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - QSERDES PLL registers */
+#define QSERDES_PLL_BG_TIMER 0x00c
+#define QSERDES_PLL_SSC_PER1 0x01c
+#define QSERDES_PLL_SSC_PER2 0x020
+#define QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
+#define QSERDES_PLL_SSC_STEP_SIZE2_MODE0 0x028
+#define QSERDES_PLL_SSC_STEP_SIZE1_MODE1 0x02c
+#define QSERDES_PLL_SSC_STEP_SIZE2_MODE1 0x030
+#define QSERDES_PLL_BIAS_EN_CLKBUFLR_EN 0x03c
+#define QSERDES_PLL_CLK_ENABLE1 0x040
+#define QSERDES_PLL_SYS_CLK_CTRL 0x044
+#define QSERDES_PLL_SYSCLK_BUF_ENABLE 0x048
+#define QSERDES_PLL_PLL_IVCO 0x050
+#define QSERDES_PLL_LOCK_CMP1_MODE0 0x054
+#define QSERDES_PLL_LOCK_CMP2_MODE0 0x058
+#define QSERDES_PLL_LOCK_CMP1_MODE1 0x060
+#define QSERDES_PLL_LOCK_CMP2_MODE1 0x064
+#define QSERDES_PLL_BG_TRIM 0x074
+#define QSERDES_PLL_CLK_EP_DIV_MODE0 0x078
+#define QSERDES_PLL_CLK_EP_DIV_MODE1 0x07c
+#define QSERDES_PLL_CP_CTRL_MODE0 0x080
+#define QSERDES_PLL_CP_CTRL_MODE1 0x084
+#define QSERDES_PLL_PLL_RCTRL_MODE0 0x088
+#define QSERDES_PLL_PLL_RCTRL_MODE1 0x08C
+#define QSERDES_PLL_PLL_CCTRL_MODE0 0x090
+#define QSERDES_PLL_PLL_CCTRL_MODE1 0x094
+#define QSERDES_PLL_BIAS_EN_CTRL_BY_PSM 0x0a4
+#define QSERDES_PLL_SYSCLK_EN_SEL 0x0a8
+#define QSERDES_PLL_RESETSM_CNTRL 0x0b0
+#define QSERDES_PLL_LOCK_CMP_EN 0x0c4
+#define QSERDES_PLL_DEC_START_MODE0 0x0cc
+#define QSERDES_PLL_DEC_START_MODE1 0x0d0
+#define QSERDES_PLL_DIV_FRAC_START1_MODE0 0x0d8
+#define QSERDES_PLL_DIV_FRAC_START2_MODE0 0x0dc
+#define QSERDES_PLL_DIV_FRAC_START3_MODE0 0x0e0
+#define QSERDES_PLL_DIV_FRAC_START1_MODE1 0x0e4
+#define QSERDES_PLL_DIV_FRAC_START2_MODE1 0x0e8
+#define QSERDES_PLL_DIV_FRAC_START3_MODE1 0x0eC
+#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE0 0x100
+#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE0 0x104
+#define QSERDES_PLL_INTEGLOOP_GAIN0_MODE1 0x108
+#define QSERDES_PLL_INTEGLOOP_GAIN1_MODE1 0x10c
+#define QSERDES_PLL_VCO_TUNE_MAP 0x120
+#define QSERDES_PLL_VCO_TUNE1_MODE0 0x124
+#define QSERDES_PLL_VCO_TUNE2_MODE0 0x128
+#define QSERDES_PLL_VCO_TUNE1_MODE1 0x12c
+#define QSERDES_PLL_VCO_TUNE2_MODE1 0x130
+#define QSERDES_PLL_VCO_TUNE_TIMER1 0x13c
+#define QSERDES_PLL_VCO_TUNE_TIMER2 0x140
+#define QSERDES_PLL_CLK_SELECT 0x16c
+#define QSERDES_PLL_HSCLK_SEL 0x170
+#define QSERDES_PLL_CORECLK_DIV 0x17c
+#define QSERDES_PLL_CORE_CLK_EN 0x184
+#define QSERDES_PLL_CMN_CONFIG 0x18c
+#define QSERDES_PLL_SVS_MODE_CLK_SEL 0x194
+#define QSERDES_PLL_CORECLK_DIV_MODE1 0x1b4
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - - QSERDES TX registers */
+#define QSERDES_TX0_RES_CODE_LANE_OFFSET_TX 0x03c
+#define QSERDES_TX0_HIGHZ_DRVR_EN 0x058
+#define QSERDES_TX0_LANE_MODE_1 0x084
+#define QSERDES_TX0_RCV_DETECT_LVL_2 0x09c
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - QSERDES RX registers */
+#define QSERDES_RX0_UCDR_FO_GAIN 0x008
+#define QSERDES_RX0_UCDR_SO_GAIN 0x014
+#define QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE 0x034
+#define QSERDES_RX0_UCDR_PI_CONTROLS 0x044
+#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2 0x0ec
+#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3 0x0f0
+#define QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4 0x0f4
+#define QSERDES_RX0_RX_IDAC_TSETTLE_LOW 0x0f8
+#define QSERDES_RX0_RX_IDAC_TSETTLE_HIGH 0x0fc
+#define QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x110
+#define QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2 0x114
+#define QSERDES_RX0_SIGDET_ENABLES 0x118
+#define QSERDES_RX0_SIGDET_CNTRL 0x11c
+#define QSERDES_RX0_SIGDET_DEGLITCH_CNTRL 0x124
+#define QSERDES_RX0_RX_MODE_00_LOW 0x170
+#define QSERDES_RX0_RX_MODE_00_HIGH 0x174
+#define QSERDES_RX0_RX_MODE_00_HIGH2 0x178
+#define QSERDES_RX0_RX_MODE_00_HIGH3 0x17c
+#define QSERDES_RX0_RX_MODE_00_HIGH4 0x180
+#define QSERDES_RX0_RX_MODE_01_LOW 0x184
+#define QSERDES_RX0_RX_MODE_01_HIGH 0x188
+#define QSERDES_RX0_RX_MODE_01_HIGH2 0x18c
+#define QSERDES_RX0_RX_MODE_01_HIGH3 0x190
+#define QSERDES_RX0_RX_MODE_01_HIGH4 0x194
+#define QSERDES_RX0_RX_MODE_10_LOW 0x198
+#define QSERDES_RX0_RX_MODE_10_HIGH 0x19c
+#define QSERDES_RX0_RX_MODE_10_HIGH2 0x1a0
+#define QSERDES_RX0_RX_MODE_10_HIGH3 0x1a4
+#define QSERDES_RX0_RX_MODE_10_HIGH4 0x1a8
+#define QSERDES_RX0_DFE_EN_TIMER 0x1b4
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - PCS registers */
+
+#define PCS_COM_FLL_CNTRL1 0x098
+#define PCS_COM_FLL_CNTRL2 0x09c
+#define PCS_COM_FLL_CNT_VAL_L 0x0a0
+#define PCS_COM_FLL_CNT_VAL_H_TOL 0x0a4
+#define PCS_COM_FLL_MAN_CODE 0x0a8
+#define PCS_COM_REFGEN_REQ_CONFIG1 0x0dc
+#define PCS_COM_G12S1_TXDEEMPH_M3P5DB 0x16c
+#define PCS_COM_RX_SIGDET_LVL 0x188
+#define PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L 0x1a4
+#define PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H 0x1a8
+#define PCS_COM_RX_DCC_CAL_CONFIG 0x1d8
+#define PCS_COM_EQ_CONFIG5 0x1ec
+
+/* QMP V2 PCIE PHY - Found in IPQ8074 gen3 port - PCS Misc registers */
+
+#define PCS_PCIE_POWER_STATE_CONFIG2 0x40c
+#define PCS_PCIE_POWER_STATE_CONFIG4 0x414
+#define PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x41c
+#define PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x440
+#define PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H 0x444
+#define PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x448
+#define PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H 0x44c
+#define PCS_PCIE_OSC_DTCT_CONFIG2 0x45c
+#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 0x478
+#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 0x480
+#define PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 0x484
+#define PCS_PCIE_OSC_DTCT_ACTIONS 0x490
+#define PCS_PCIE_EQ_CONFIG1 0x4a0
+#define PCS_PCIE_EQ_CONFIG2 0x4a4
+#define PCS_PCIE_PRESET_P10_PRE 0x4bc
+#define PCS_PCIE_PRESET_P10_POST 0x4e0
+
+#endif
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -23,6 +23,7 @@
#include <dt-bindings/phy/phy.h>
#include "phy-qcom-qmp.h"
+#include "phy-qcom-pcie3-qmp.h"
/* QPHY_SW_RESET bit */
#define SW_RESET BIT(0)
@@ -676,6 +677,132 @@ static const struct qmp_phy_init_tbl ipq
QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
};
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x82),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0x355),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0x35555),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x1a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0x1a0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0xb),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0xa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x1),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x2aa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x2aaab),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x34),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0x3414),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x0b),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_tx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
+ QMP_PHY_INIT_CFG(QSERDES_TX0_HIGHZ_DRVR_EN, 0x10),
+ QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0xe),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x4),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x2),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
+};
+
+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL2, 0x83),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNT_VAL_L, 0x9),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNT_VAL_H_TOL, 0x42),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_MAN_CODE, 0x40),
+ QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
+ QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x0),
+ QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x1),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x0),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
+ QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG2, 0xb),
+ QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x50),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x1a),
+ QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x6),
+ QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
+ QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+ QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
+ QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
+ QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
+};
static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -2187,6 +2314,36 @@ static const struct qmp_phy_cfg ipq8074_
.pwrdn_delay_max = 1005, /* us */
};
+static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
+ .type = PHY_TYPE_PCIE,
+ .nlanes = 1,
+
+ .serdes_tbl = ipq8074_pcie_gen3_serdes_tbl,
+ .serdes_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_serdes_tbl),
+ .tx_tbl = ipq8074_pcie_gen3_tx_tbl,
+ .tx_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
+ .rx_tbl = ipq8074_pcie_gen3_rx_tbl,
+ .rx_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_rx_tbl),
+ .pcs_tbl = ipq8074_pcie_gen3_pcs_tbl,
+ .pcs_tbl_num = ARRAY_SIZE(ipq8074_pcie_gen3_pcs_tbl),
+ .clk_list = ipq8074_pciephy_clk_l,
+ .num_clks = ARRAY_SIZE(ipq8074_pciephy_clk_l),
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = NULL,
+ .num_vregs = 0,
+ .regs = qmp_v4_usb3phy_regs_layout,
+
+ .start_ctrl = SERDES_START | PCS_START,
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+
+ .has_phy_com_ctrl = false,
+ .has_lane_rst = false,
+ .has_pwrdn_delay = true,
+ .pwrdn_delay_min = 995, /* us */
+ .pwrdn_delay_max = 1005, /* us */
+};
+
static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
.type = PHY_TYPE_PCIE,
.nlanes = 1,
@@ -3476,8 +3633,15 @@ static int phy_pipe_clk_register(struct
init.ops = &clk_fixed_rate_ops;
- /* controllers using QMP phys use 125MHz pipe clock interface */
- fixed->fixed_rate = 125000000;
+ /*
+ * controllers using QMP phys use 125MHz pipe clock interface unless
+ * other frequency is specified in dts
+ */
+ ret = of_property_read_u32(np, "clock-output-rate",
+ (u32 *)&fixed->fixed_rate);
+ if (ret)
+ fixed->fixed_rate = 125000000;
+
fixed->hw.init = &init;
ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
@@ -3859,6 +4023,9 @@ static const struct of_device_id qcom_qm
.compatible = "qcom,ipq8074-qmp-pcie-phy",
.data = &ipq8074_pciephy_cfg,
}, {
+ .compatible = "qcom,ipq8074-qmp-pcie-gen3-phy",
+ .data = &ipq8074_pciephy_gen3_cfg,
+ }, {
.compatible = "qcom,sc7180-qmp-usb3-phy",
.data = &sc7180_usb3phy_cfg,
}, {

View File

@ -1,44 +0,0 @@
From 35df745d335bd21094f522dc9dff7eaae92114d9 Mon Sep 17 00:00:00 2001
From: Baruch Siach <baruch@tkos.co.il>
Date: Wed, 5 May 2021 12:18:29 +0300
Subject: [PATCH] PCI: dwc: tegra: move GEN3_RELATED DBI register to common
header
These are common dwc macros that will be used for other platforms.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/pci/controller/dwc/pcie-designware.h | 6 ++++++
drivers/pci/controller/dwc/pcie-tegra194.c | 6 ------
2 files changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -74,6 +74,12 @@
#define PCIE_MSI_INTR0_MASK 0x82C
#define PCIE_MSI_INTR0_STATUS 0x830
+#define GEN3_RELATED_OFF 0x890
+#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL BIT(0)
+#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE BIT(16)
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK GENMASK(25, 24)
+
#define PCIE_PORT_MULTI_LANE_CTRL 0x8C0
#define PORT_MLTI_UPCFG_SUPPORT BIT(7)
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -193,12 +193,6 @@
#define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK GENMASK(23, 8)
#define GEN3_EQ_CONTROL_OFF_FB_MODE_MASK GENMASK(3, 0)
-#define GEN3_RELATED_OFF 0x890
-#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL BIT(0)
-#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE BIT(16)
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK GENMASK(25, 24)
-
#define PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT 0x8D0
#define AMBA_ERROR_RESPONSE_CRS_SHIFT 3
#define AMBA_ERROR_RESPONSE_CRS_MASK GENMASK(1, 0)

View File

@ -1,230 +0,0 @@
From 809a720946f720dca2009bac29294992375a31b9 Mon Sep 17 00:00:00 2001
From: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Date: Tue, 11 May 2021 21:53:08 +0200
Subject: [PATCH] PCI: qcom: add support for IPQ60xx PCIe controller
IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
platform.
The code is based on downstream Codeaurora kernel v5.4. Split out the
DBI registers access part from .init into .post_init. DBI registers are
only accessible after phy_power_on().
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/pci/controller/dwc/pcie-designware.h | 1 +
drivers/pci/controller/dwc/pcie-qcom.c | 150 +++++++++++++++++++
2 files changed, 151 insertions(+)
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -76,6 +76,7 @@
#define GEN3_RELATED_OFF 0x890
#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL BIT(0)
+#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS BIT(13)
#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE BIT(16)
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK GENMASK(25, 24)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -51,6 +51,10 @@
#define PCIE20_PARF_DBI_BASE_ADDR 0x168
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C
#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174
+#define AHB_CLK_EN BIT(0)
+#define MSTR_AXI_CLK_EN BIT(1)
+#define BYPASS BIT(4)
+
#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178
#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
#define PCIE20_PARF_LTSSM 0x1B0
@@ -92,6 +96,12 @@
#define SLV_ADDR_SPACE_SZ 0x10000000
#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xa0
+#define PCIE_CAP_CURR_DEEMPHASIS BIT(16)
+#define SPEED_GEN1 0x1
+#define SPEED_GEN2 0x2
+#define SPEED_GEN3 0x3
+#define AXI_CLK_RATE 200000000
+#define RCHNG_CLK_RATE 100000000
#define DEVICE_TYPE_RC 0x4
@@ -161,6 +171,11 @@ struct qcom_pcie_resources_2_7_0 {
struct clk *pipe_clk;
};
+struct qcom_pcie_resources_2_9_0 {
+ struct clk_bulk_data clks[5];
+ struct reset_control *rst;
+};
+
union qcom_pcie_resources {
struct qcom_pcie_resources_1_0_0 v1_0_0;
struct qcom_pcie_resources_2_1_0 v2_1_0;
@@ -168,6 +183,7 @@ union qcom_pcie_resources {
struct qcom_pcie_resources_2_3_3 v2_3_3;
struct qcom_pcie_resources_2_4_0 v2_4_0;
struct qcom_pcie_resources_2_7_0 v2_7_0;
+ struct qcom_pcie_resources_2_9_0 v2_9_0;
};
struct qcom_pcie;
@@ -1252,6 +1268,130 @@ static void qcom_pcie_post_deinit_2_7_0(
clk_disable_unprepare(res->pipe_clk);
}
+static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
+{
+ 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->rst = devm_reset_control_array_get_exclusive(dev);
+ if (IS_ERR(res->rst))
+ return PTR_ERR(res->rst);
+
+ return 0;
+}
+
+static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+
+ clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+}
+
+static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
+{
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+ struct device *dev = pcie->pci->dev;
+ int ret;
+
+ ret = reset_control_assert(res->rst);
+ if (ret) {
+ dev_err(dev, "reset assert failed (%d)\n", ret);
+ return ret;
+ }
+
+ usleep_range(2000, 2500);
+
+ ret = reset_control_deassert(res->rst);
+ if (ret) {
+ dev_err(dev, "reset deassert failed (%d)\n", ret);
+ return ret;
+ }
+
+ /*
+ * Don't have a way to see if the reset has completed.
+ * Wait for some time.
+ */
+ usleep_range(2000, 2500);
+
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ if (ret)
+ goto err_reset;
+
+ return 0;
+
+ /*
+ * Not checking for failure, will anyway return
+ * the original failure in 'ret'.
+ */
+err_reset:
+ reset_control_assert(res->rst);
+
+ return ret;
+}
+
+static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+{
+ struct dw_pcie *pci = pcie->pci;
+ u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+ u32 val;
+ int i;
+
+ writel(SLV_ADDR_SPACE_SZ,
+ pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
+
+ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+ val &= ~BIT(0);
+ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+ writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+
+ writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
+ writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
+ pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+ writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
+ | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
+ pci->dbi_base + GEN3_RELATED_OFF);
+
+ writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
+ | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
+ AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
+ pcie->parf + PCIE20_PARF_SYS_CTRL);
+
+ writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
+
+ dw_pcie_dbi_ro_wr_en(pci);
+ writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+
+ /* Configure PCIe link capabilities for ASPM */
+ val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
+ val &= ~PCI_EXP_LNKCAP_ASPMS;
+ writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
+
+ writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
+ PCI_EXP_DEVCTL2);
+
+ writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
+ pci->dbi_base + offset + PCI_EXP_DEVCTL2);
+
+ for (i = 0;i < 256;i++)
+ writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
+ + (4 * i));
+
+ return 0;
+}
+
static int qcom_pcie_link_up(struct dw_pcie *pci)
{
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
@@ -1351,6 +1491,15 @@ static const struct qcom_pcie_ops ops_2_
.post_deinit = qcom_pcie_post_deinit_2_7_0,
};
+/* Qcom IP rev.: 2.9.0 Synopsys IP rev.: 5.00a */
+static const struct qcom_pcie_ops ops_2_9_0 = {
+ .get_resources = qcom_pcie_get_resources_2_9_0,
+ .init = qcom_pcie_init_2_9_0,
+ .post_init = qcom_pcie_post_init_2_9_0,
+ .deinit = qcom_pcie_deinit_2_9_0,
+ .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+};
+
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = qcom_pcie_link_up,
.start_link = qcom_pcie_start_link,
@@ -1457,6 +1606,7 @@ static const struct of_device_id qcom_pc
{ .compatible = "qcom,pcie-ipq4019", .data = &ops_2_4_0 },
{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
+ { .compatible = "qcom,pcie-ipq6018", .data = &ops_2_9_0 },
{ }
};

View File

@ -1,181 +0,0 @@
From f46a2d9ff3346809e64fbf5c1796651207b57f00 Mon Sep 17 00:00:00 2001
From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Date: Wed, 29 Jul 2020 21:00:07 +0530
Subject: [PATCH] arm64: dts: ipq8074: Fixup PCIe dts nodes
ipq8074 PCIe nodes missing required properties to make them work.
Add these properties.
Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 109 +++++++++++++++++---------
1 file changed, 74 insertions(+), 35 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -227,34 +227,66 @@
resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
};
- pcie_phy0: phy@86000 {
- compatible = "qcom,ipq8074-qmp-pcie-phy";
- reg = <0x00086000 0x1000>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
- clock-names = "pipe_clk";
- clock-output-names = "pcie20_phy0_pipe_clk";
+ qmp_pcie_phy0: phy@84000 {
+ compatible = "qcom,ipq8074-qmp-pcie-gen3-phy";
+ reg = <0x00084000 0x1bc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clocks = <&gcc GCC_PCIE0_AUX_CLK>,
+ <&gcc GCC_PCIE0_AHB_CLK>;
+ clock-names = "aux", "cfg_ahb";
resets = <&gcc GCC_PCIE0_PHY_BCR>,
- <&gcc GCC_PCIE0PHY_PHY_BCR>;
+ <&gcc GCC_PCIE0PHY_PHY_BCR>;
reset-names = "phy",
"common";
+
status = "disabled";
+ pcie_phy0: lane@84200 {
+ reg = <0x84200 0x16c>, /* Serdes Tx */
+ <0x84400 0x200>, /* Serdes Rx */
+ <0x84800 0x4f4>; /* PCS: Lane0, COM, PCIE */
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "gcc_pcie0_pipe_clk_src";
+ clock-output-rate = <250000000>;
+ #clock-cells = <0>;
+ };
};
- pcie_phy1: phy@8e000 {
+ qmp_pcie_phy1: phy@8e000 {
compatible = "qcom,ipq8074-qmp-pcie-phy";
- reg = <0x0008e000 0x1000>;
- #phy-cells = <0>;
- clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
- clock-names = "pipe_clk";
- clock-output-names = "pcie20_phy1_pipe_clk";
+ reg = <0x8e000 0x1c4>; /* Serdes PLL */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clocks = <&gcc GCC_PCIE1_AUX_CLK>,
+ <&gcc GCC_PCIE1_AHB_CLK>;
+ clock-names = "aux", "cfg_ahb";
resets = <&gcc GCC_PCIE1_PHY_BCR>,
- <&gcc GCC_PCIE1PHY_PHY_BCR>;
+ <&gcc GCC_PCIE1PHY_PHY_BCR>;
reset-names = "phy",
"common";
+
status = "disabled";
+ pcie_phy1: lane@8e200 {
+ reg = <0x8e200 0x130>, /* Serdes Tx */
+ <0x8e400 0x200>, /* Serdes Rx */
+ <0x8e800 0x1f8>; /* PCS */
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_PCIE1_PIPE_CLK>;
+ clock-names = "pipe0";
+ clock-output-names = "gcc_pcie1_pipe_clk_src";
+ clock-output-rate = <125000000>;
+ #clock-cells = <0>;
+ };
};
mdio: mdio@90000 {
@@ -687,9 +719,9 @@
phy-names = "pciephy";
ranges = <0x81000000 0 0x10200000 0x10200000
- 0 0x100000 /* downstream I/O */
- 0x82000000 0 0x10300000 0x10300000
- 0 0xd00000>; /* non-prefetchable memory */
+ 0 0x100000>, /* downstream I/O */
+ <0x82000000 0 0x10220000 0x10220000
+ 0 0xfde0000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
@@ -732,12 +764,13 @@
};
pcie0: pci@20000000 {
- compatible = "qcom,pcie-ipq8074";
- reg = <0x20000000 0xf1d>,
- <0x20000f20 0xa8>,
- <0x00080000 0x2000>,
- <0x20100000 0x1000>;
- reg-names = "dbi", "elbi", "parf", "config";
+ compatible = "qcom,pcie-ipq8074-gen3";
+ reg = <0x20000000 0xf1d>,
+ <0x20000f20 0xa8>,
+ <0x20001000 0x1000>,
+ <0x00080000 0x4000>,
+ <0x20100000 0x1000>;
+ reg-names = "dbi", "elbi", "atu", "parf", "config";
device_type = "pci";
linux,pci-domain = <0>;
bus-range = <0x00 0xff>;
@@ -749,9 +782,9 @@
phy-names = "pciephy";
ranges = <0x81000000 0 0x20200000 0x20200000
- 0 0x100000 /* downstream I/O */
- 0x82000000 0 0x20300000 0x20300000
- 0 0xd00000>; /* non-prefetchable memory */
+ 0 0x100000>, /* downstream I/O */
+ <0x82000000 0 0x20220000 0x20220000
+ 0 0xfde0000>; /* non-prefetchable memory */
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
@@ -770,27 +803,33 @@
<&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_AUX_CLK>,
+ <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
+ <&gcc GCC_PCIE0_RCHNG_CLK>;
clock-names = "iface",
"axi_m",
"axi_s",
"ahb",
- "aux";
+ "aux",
+ "axi_bridge",
+ "rchng";
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_MASTER_STICKY_ARES>,
+ <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>;
reset-names = "pipe",
"sleep",
"sticky",
"axi_m",
"axi_s",
"ahb",
- "axi_m_sticky";
+ "axi_m_sticky",
+ "axi_s_sticky";
status = "disabled";
};

View File

@ -1,26 +0,0 @@
From 5d3f9ed5a9eb305a2531015cc65200d48be5dbf4 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 May 2021 22:21:57 +0200
Subject: [PATCH 1/2] PCI: qcom: backport register define
This is used by the pending IPQ6018 PCI support which
uses the same Gen3 IP and the one we are reusing for
IPQ8074.
Without it compilation will break.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -61,6 +61,7 @@
#define PCIE20_PARF_SID_OFFSET 0x234
#define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C
#define PCIE20_PARF_DEVICE_TYPE 0x1000
+#define PCIE20_PARF_BDF_TO_SID_TABLE_N 0x2000
#define PCIE20_ELBI_SYS_CTRL 0x04
#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)

View File

@ -1,48 +0,0 @@
From 9467e9860e72d7351b24dc6d77f0e9fe141ce166 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 26 May 2021 16:06:32 +0200
Subject: [PATCH] PCI: qcom: Add IPQ8074 PCIe Gen3 support
IPQ6018 uses the same v2.9.0 IP for the Gen3 PCIe
controller.
So, lets reuse that and add clocks that the IPQ6018
patch missed.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -173,7 +173,7 @@ struct qcom_pcie_resources_2_7_0 {
};
struct qcom_pcie_resources_2_9_0 {
- struct clk_bulk_data clks[5];
+ struct clk_bulk_data clks[7];
struct reset_control *rst;
};
@@ -1279,8 +1279,10 @@ static int qcom_pcie_get_resources_2_9_0
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";
+ res->clks[3].id = "ahb";
+ res->clks[4].id = "aux";
+ res->clks[5].id = "axi_bridge";
+ res->clks[6].id = "rchng";
ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
if (ret < 0)
@@ -1608,6 +1610,7 @@ static const struct of_device_id qcom_pc
{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
{ .compatible = "qcom,pcie-ipq6018", .data = &ops_2_9_0 },
+ { .compatible = "qcom,pcie-ipq8074-gen3", .data = &ops_2_9_0 },
{ }
};

View File

@ -1,27 +0,0 @@
From 5fcad0d86d985b068eb97e55b55f7be87cd1b008 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 12 May 2021 17:01:29 +0200
Subject: [PATCH] arm64: uaccess: include scheduler.h
Qualcomm SSDK exposed a bug in which the uaccess is
using a struct and header definition that are not
included.
So, simply: #include <linux/sched.h> to fix it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/include/asm/uaccess.h | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -24,6 +24,8 @@
#include <asm/memory.h>
#include <asm/extable.h>
+#include <linux/sched.h>
+
#define get_fs() (current_thread_info()->addr_limit)
static inline void set_fs(mm_segment_t fs)

View File

@ -1,170 +0,0 @@
From f581e7b004d0d997acc1f0fa5b2c454f90f0b2de Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 12 May 2021 18:49:30 +0200
Subject: [PATCH] arm64: dts: ipq8074: add networking nodes
Add networking nodes required for SSDK and NSS-DP.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 150 ++++++++++++++++++++++++++
1 file changed, 150 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -899,5 +899,155 @@
};
};
};
+
+ ess_switch: ess-switch@3a000000 {
+ compatible = "qcom,ess-switch-ipq807x";
+ reg = <0x3a000000 0x1000000>;
+ switch_access_mode = "local bus";
+ switch_cpu_bmp = <0x1>; /* cpu port bitmap */
+ switch_inner_bmp = <0x80>; /*inner port bitmap*/
+ mdio-bus = <&mdio>;
+ clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>,
+ <&gcc GCC_CMN_12GPLL_SYS_CLK>,
+ <&gcc GCC_UNIPHY0_AHB_CLK>,
+ <&gcc GCC_UNIPHY0_SYS_CLK>,
+ <&gcc GCC_UNIPHY1_AHB_CLK>,
+ <&gcc GCC_UNIPHY1_SYS_CLK>,
+ <&gcc GCC_UNIPHY2_AHB_CLK>,
+ <&gcc GCC_UNIPHY2_SYS_CLK>,
+ <&gcc GCC_PORT1_MAC_CLK>,
+ <&gcc GCC_PORT2_MAC_CLK>,
+ <&gcc GCC_PORT3_MAC_CLK>,
+ <&gcc GCC_PORT4_MAC_CLK>,
+ <&gcc GCC_PORT5_MAC_CLK>,
+ <&gcc GCC_PORT6_MAC_CLK>,
+ <&gcc GCC_NSS_PPE_CLK>,
+ <&gcc GCC_NSS_PPE_CFG_CLK>,
+ <&gcc GCC_NSSNOC_PPE_CLK>,
+ <&gcc GCC_NSSNOC_PPE_CFG_CLK>,
+ <&gcc GCC_NSS_EDMA_CLK>,
+ <&gcc GCC_NSS_EDMA_CFG_CLK>,
+ <&gcc GCC_NSS_PPE_IPE_CLK>,
+ <&gcc GCC_NSS_PPE_BTQ_CLK>,
+ <&gcc GCC_NSS_NOC_CLK>,
+ <&gcc GCC_NSSNOC_SNOC_CLK>,
+ <&gcc GCC_MEM_NOC_NSS_AXI_CLK>,
+ <&gcc GCC_NSS_CRYPTO_CLK>,
+ <&gcc GCC_NSS_IMEM_CLK>,
+ <&gcc GCC_NSS_PTP_REF_CLK>,
+ <&gcc GCC_NSS_PORT1_RX_CLK>,
+ <&gcc GCC_NSS_PORT1_TX_CLK>,
+ <&gcc GCC_NSS_PORT2_RX_CLK>,
+ <&gcc GCC_NSS_PORT2_TX_CLK>,
+ <&gcc GCC_NSS_PORT3_RX_CLK>,
+ <&gcc GCC_NSS_PORT3_TX_CLK>,
+ <&gcc GCC_NSS_PORT4_RX_CLK>,
+ <&gcc GCC_NSS_PORT4_TX_CLK>,
+ <&gcc GCC_NSS_PORT5_RX_CLK>,
+ <&gcc GCC_NSS_PORT5_TX_CLK>,
+ <&gcc GCC_NSS_PORT6_RX_CLK>,
+ <&gcc GCC_NSS_PORT6_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT1_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT1_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT2_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT2_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT3_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT3_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT4_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT4_TX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT5_RX_CLK>,
+ <&gcc GCC_UNIPHY0_PORT5_TX_CLK>,
+ <&gcc GCC_UNIPHY1_PORT5_RX_CLK>,
+ <&gcc GCC_UNIPHY1_PORT5_TX_CLK>,
+ <&gcc GCC_UNIPHY2_PORT6_RX_CLK>,
+ <&gcc GCC_UNIPHY2_PORT6_TX_CLK>,
+ <&gcc NSS_PORT5_RX_CLK_SRC>,
+ <&gcc NSS_PORT5_TX_CLK_SRC>;
+ clock-names = "cmn_ahb_clk", "cmn_sys_clk",
+ "uniphy0_ahb_clk", "uniphy0_sys_clk",
+ "uniphy1_ahb_clk", "uniphy1_sys_clk",
+ "uniphy2_ahb_clk", "uniphy2_sys_clk",
+ "port1_mac_clk", "port2_mac_clk",
+ "port3_mac_clk", "port4_mac_clk",
+ "port5_mac_clk", "port6_mac_clk",
+ "nss_ppe_clk", "nss_ppe_cfg_clk",
+ "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk",
+ "nss_edma_clk", "nss_edma_cfg_clk",
+ "nss_ppe_ipe_clk", "nss_ppe_btq_clk",
+ "gcc_nss_noc_clk",
+ "gcc_nssnoc_snoc_clk",
+ "gcc_mem_noc_nss_axi_clk",
+ "gcc_nss_crypto_clk",
+ "gcc_nss_imem_clk",
+ "gcc_nss_ptp_ref_clk",
+ "nss_port1_rx_clk", "nss_port1_tx_clk",
+ "nss_port2_rx_clk", "nss_port2_tx_clk",
+ "nss_port3_rx_clk", "nss_port3_tx_clk",
+ "nss_port4_rx_clk", "nss_port4_tx_clk",
+ "nss_port5_rx_clk", "nss_port5_tx_clk",
+ "nss_port6_rx_clk", "nss_port6_tx_clk",
+ "uniphy0_port1_rx_clk",
+ "uniphy0_port1_tx_clk",
+ "uniphy0_port2_rx_clk",
+ "uniphy0_port2_tx_clk",
+ "uniphy0_port3_rx_clk",
+ "uniphy0_port3_tx_clk",
+ "uniphy0_port4_rx_clk",
+ "uniphy0_port4_tx_clk",
+ "uniphy0_port5_rx_clk",
+ "uniphy0_port5_tx_clk",
+ "uniphy1_port5_rx_clk",
+ "uniphy1_port5_tx_clk",
+ "uniphy2_port6_rx_clk",
+ "uniphy2_port6_tx_clk",
+ "nss_port5_rx_clk_src",
+ "nss_port5_tx_clk_src";
+ resets = <&gcc GCC_PPE_FULL_RESET>,
+ <&gcc GCC_UNIPHY0_SOFT_RESET>,
+ <&gcc GCC_UNIPHY0_XPCS_RESET>,
+ <&gcc GCC_UNIPHY1_SOFT_RESET>,
+ <&gcc GCC_UNIPHY1_XPCS_RESET>,
+ <&gcc GCC_UNIPHY2_SOFT_RESET>,
+ <&gcc GCC_UNIPHY2_XPCS_RESET>,
+ <&gcc GCC_NSSPORT1_RESET>,
+ <&gcc GCC_NSSPORT2_RESET>,
+ <&gcc GCC_NSSPORT3_RESET>,
+ <&gcc GCC_NSSPORT4_RESET>,
+ <&gcc GCC_NSSPORT5_RESET>,
+ <&gcc GCC_NSSPORT6_RESET>;
+ reset-names = "ppe_rst", "uniphy0_soft_rst",
+ "uniphy0_xpcs_rst", "uniphy1_soft_rst",
+ "uniphy1_xpcs_rst", "uniphy2_soft_rst",
+ "uniphy2_xpcs_rst", "nss_port1_rst",
+ "nss_port2_rst", "nss_port3_rst",
+ "nss_port4_rst", "nss_port5_rst",
+ "nss_port6_rst";
+ };
+
+ ess-uniphy@7a00000 {
+ compatible = "qcom,ess-uniphy";
+ reg = <0x7a00000 0x30000>;
+ uniphy_access_mode = "local bus";
+ };
+
+ edma@3ab00000 {
+ compatible = "qcom,edma";
+ reg = <0x3ab00000 0x76900>;
+ reg-names = "edma-reg-base";
+ qcom,txdesc-ring-start = <23>;
+ qcom,txdesc-rings = <1>;
+ qcom,txcmpl-ring-start = <7>;
+ qcom,txcmpl-rings = <1>;
+ qcom,rxfill-ring-start = <7>;
+ qcom,rxfill-rings = <1>;
+ qcom,rxdesc-ring-start = <15>;
+ qcom,rxdesc-rings = <1>;
+ interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&gcc GCC_EDMA_HW_RESET>;
+ reset-names = "edma_rst";
+ };
};
};

View File

@ -1,56 +0,0 @@
From 027818c51e6732f8a2f7986515264cebaf9a1704 Mon Sep 17 00:00:00 2001
From: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
Date: Wed, 18 Mar 2020 17:08:11 +0530
Subject: [PATCH 1/8] clk: ipq: support for resetting multiple bits
Current reset structure takes only one reset bit and
calculates the bitmask in its reset operation. Some of the
reset registers contains multiple bits in which each bit
will be associated with subsystem reset inside the block. To
reset properly the complete block, all the subsystem reset
should be triggered at same time i.e the register write
should go in one AHB write.
This patch adds the support for giving the complete bitmask
in reset structure and reset operation will use this bitmask
for all reset operations.
Change-Id: Ief49f8746624a0fc1e067d815725ae7c254c2c6f
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
(cherry picked from commit ef555fc1cffa6e823a9d929711cacae0821b35ec)
Signed-off-by: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
---
drivers/clk/qcom/reset.c | 4 ++--
drivers/clk/qcom/reset.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/clk/qcom/reset.c
+++ b/drivers/clk/qcom/reset.c
@@ -28,7 +28,7 @@ qcom_reset_assert(struct reset_controlle
rst = to_qcom_reset_controller(rcdev);
map = &rst->reset_map[id];
- mask = BIT(map->bit);
+ mask = map->bitmask ? map->bitmask : BIT(map->bit);
return regmap_update_bits(rst->regmap, map->reg, mask, mask);
}
@@ -42,7 +42,7 @@ qcom_reset_deassert(struct reset_control
rst = to_qcom_reset_controller(rcdev);
map = &rst->reset_map[id];
- mask = BIT(map->bit);
+ mask = map->bitmask ? map->bitmask : BIT(map->bit);
return regmap_update_bits(rst->regmap, map->reg, mask, 0);
}
--- a/drivers/clk/qcom/reset.h
+++ b/drivers/clk/qcom/reset.h
@@ -11,6 +11,7 @@
struct qcom_reset_map {
unsigned int reg;
u8 bit;
+ u32 bitmask;
};
struct regmap;

View File

@ -1,212 +0,0 @@
From 4f579facd45c39f8f8b9993570944f4d83a95955 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Wed, 5 Feb 2020 10:13:01 +0530
Subject: [PATCH 2/8] ipq8074: gcc: Added support for NSS clocks
Change-Id: I446e84dbc3498618425677811a73124b99b5c0ad
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Signed-off-by: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 12 ++++
drivers/clk/qcom/gcc-ipq8074.c | 68 +++++++++++++++++++-
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
3 files changed, 80 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -1049,5 +1049,17 @@
resets = <&gcc GCC_EDMA_HW_RESET>;
reset-names = "edma_rst";
};
+
+ bias_pll_cc_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <300000000>;
+ #clock-cells = <0>;
+ };
+
+ bias_pll_nss_noc_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <416500000>;
+ #clock-cells = <0>;
+ };
};
};
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -3174,6 +3174,24 @@ static struct clk_branch gcc_nss_ptp_ref
},
};
+static struct clk_branch gcc_crypto_ppe_clk = {
+ .halt_reg = 0x68310,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x68310,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_crypto_ppe_clk",
+ .parent_names = (const char *[]){
+ "nss_ppe_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_nssnoc_ce_apb_clk = {
.halt_reg = 0x6830c,
.clkr = {
@@ -3346,6 +3364,7 @@ static struct clk_branch gcc_nssnoc_ubi1
static struct clk_branch gcc_ubi0_ahb_clk = {
.halt_reg = 0x6820c,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6820c,
.enable_mask = BIT(0),
@@ -3363,6 +3382,7 @@ static struct clk_branch gcc_ubi0_ahb_cl
static struct clk_branch gcc_ubi0_axi_clk = {
.halt_reg = 0x68200,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68200,
.enable_mask = BIT(0),
@@ -3380,6 +3400,7 @@ static struct clk_branch gcc_ubi0_axi_cl
static struct clk_branch gcc_ubi0_nc_axi_clk = {
.halt_reg = 0x68204,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68204,
.enable_mask = BIT(0),
@@ -3397,6 +3418,7 @@ static struct clk_branch gcc_ubi0_nc_axi
static struct clk_branch gcc_ubi0_core_clk = {
.halt_reg = 0x68210,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68210,
.enable_mask = BIT(0),
@@ -3414,6 +3436,7 @@ static struct clk_branch gcc_ubi0_core_c
static struct clk_branch gcc_ubi0_mpt_clk = {
.halt_reg = 0x68208,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68208,
.enable_mask = BIT(0),
@@ -3431,6 +3454,7 @@ static struct clk_branch gcc_ubi0_mpt_cl
static struct clk_branch gcc_ubi1_ahb_clk = {
.halt_reg = 0x6822c,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x6822c,
.enable_mask = BIT(0),
@@ -3448,6 +3472,7 @@ static struct clk_branch gcc_ubi1_ahb_cl
static struct clk_branch gcc_ubi1_axi_clk = {
.halt_reg = 0x68220,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68220,
.enable_mask = BIT(0),
@@ -3465,6 +3490,7 @@ static struct clk_branch gcc_ubi1_axi_cl
static struct clk_branch gcc_ubi1_nc_axi_clk = {
.halt_reg = 0x68224,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68224,
.enable_mask = BIT(0),
@@ -3482,6 +3508,7 @@ static struct clk_branch gcc_ubi1_nc_axi
static struct clk_branch gcc_ubi1_core_clk = {
.halt_reg = 0x68230,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68230,
.enable_mask = BIT(0),
@@ -3499,6 +3526,7 @@ static struct clk_branch gcc_ubi1_core_c
static struct clk_branch gcc_ubi1_mpt_clk = {
.halt_reg = 0x68228,
+ .halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x68228,
.enable_mask = BIT(0),
@@ -4381,6 +4409,33 @@ static struct clk_hw *gcc_ipq8074_hws[]
&nss_ppe_cdiv_clk_src.hw,
};
+static const struct alpha_pll_config ubi32_pll_config = {
+ .l = 0x4e,
+ .config_ctl_val = 0x200d4aa8,
+ .config_ctl_hi_val = 0x3c2,
+ .main_output_mask = BIT(0),
+ .aux_output_mask = BIT(1),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BIT(12),
+ .post_div_val = 0x0,
+ .post_div_mask = GENMASK(9, 8),
+};
+
+static const struct alpha_pll_config nss_crypto_pll_config = {
+ .l = 0x3e,
+ .alpha = 0x0,
+ .alpha_hi = 0x80,
+ .config_ctl_val = 0x4001055b,
+ .main_output_mask = BIT(0),
+ .pre_div_val = 0x0,
+ .pre_div_mask = GENMASK(14, 12),
+ .post_div_val = 0x1 << 8,
+ .post_div_mask = GENMASK(11, 8),
+ .vco_mask = GENMASK(21, 20),
+ .vco_val = 0x0,
+ .alpha_en_mask = BIT(24),
+};
+
static struct clk_regmap *gcc_ipq8074_clks[] = {
[GPLL0_MAIN] = &gpll0_main.clkr,
[GPLL0] = &gpll0.clkr,
@@ -4562,6 +4617,7 @@ static struct clk_regmap *gcc_ipq8074_cl
[GCC_CMN_12GPLL_AHB_CLK] = &gcc_cmn_12gpll_ahb_clk.clkr,
[GCC_CMN_12GPLL_SYS_CLK] = &gcc_cmn_12gpll_sys_clk.clkr,
[GCC_MDIO_AHB_CLK] = &gcc_mdio_ahb_clk.clkr,
+ [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr,
[GCC_UNIPHY0_AHB_CLK] = &gcc_uniphy0_ahb_clk.clkr,
[GCC_UNIPHY0_SYS_CLK] = &gcc_uniphy0_sys_clk.clkr,
[GCC_UNIPHY1_AHB_CLK] = &gcc_uniphy1_ahb_clk.clkr,
@@ -4773,7 +4829,17 @@ static const struct qcom_cc_desc gcc_ipq
static int gcc_ipq8074_probe(struct platform_device *pdev)
{
- return qcom_cc_probe(pdev, &gcc_ipq8074_desc);
+ struct regmap *regmap;
+
+ regmap = qcom_cc_map(pdev, &gcc_ipq8074_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
+ clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
+ &nss_crypto_pll_config);
+
+ return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap);
}
static struct platform_driver gcc_ipq8074_driver = {
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -233,6 +233,7 @@
#define GCC_PCIE0_AXI_S_BRIDGE_CLK 224
#define GCC_PCIE0_RCHNG_CLK_SRC 225
#define GCC_PCIE0_RCHNG_CLK 226
+#define GCC_CRYPTO_PPE_CLK 227
#define GCC_BLSP1_BCR 0
#define GCC_BLSP1_QUP1_BCR 1

View File

@ -1,352 +0,0 @@
From 6504bc9edeb1a2a54d813f4bb5d0267e7bf827f9 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Thu, 6 Feb 2020 17:35:42 +0530
Subject: [PATCH 4/8] clk: ipq8074: Support added for necessary clocks and
reset
Change-Id: I21a76a44185f766e9b6dcba274392ea8e599718b
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Signed-off-by: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
---
drivers/clk/qcom/gcc-ipq8074.c | 238 ++++++++++++++++++-
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 35 ++-
2 files changed, 258 insertions(+), 15 deletions(-)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -396,6 +396,22 @@ static const struct parent_map gcc_xo_gp
{ P_SLEEP_CLK, 6 },
};
+static const char * const gcc_xo_gpll4_gpll0_gpll6_gpll0_div2[] = {
+ "xo",
+ "gpll4",
+ "gpll0",
+ "gpll6",
+ "gpll0_out_main_div2",
+};
+
+static const struct parent_map gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map[] = {
+ { P_XO, 0 },
+ { P_GPLL4, 1 },
+ { P_GPLL0, 2 },
+ { P_GPLL6, 3 },
+ { P_GPLL0_DIV2, 4 },
+};
+
static struct clk_alpha_pll gpll0_main = {
.offset = 0x21000,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
@@ -962,6 +978,12 @@ static const struct freq_tbl ftbl_pcie_a
{ }
};
+struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(100000000, P_GPLL0, 8, 0, 0),
+ { }
+};
+
static struct clk_rcg2 pcie0_axi_clk_src = {
.cmd_rcgr = 0x75054,
.freq_tbl = ftbl_pcie_axi_clk_src,
@@ -2013,6 +2035,78 @@ static struct clk_rcg2 gp3_clk_src = {
},
};
+struct freq_tbl ftbl_qdss_tsctr_clk_src[] = {
+ F(160000000, P_GPLL0_DIV2, 2.5, 0, 0),
+ F(320000000, P_GPLL0, 2.5, 0, 0),
+ F(600000000, P_GPLL6, 2, 0, 0),
+ { }
+};
+
+struct clk_rcg2 qdss_tsctr_clk_src = {
+ .cmd_rcgr = 0x29064,
+ .freq_tbl = ftbl_qdss_tsctr_clk_src,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "qdss_tsctr_clk_src",
+ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+static struct clk_fixed_factor qdss_dap_sync_clk_src = {
+ .mult = 1,
+ .div = 4,
+ .hw.init = &(struct clk_init_data){
+ .name = "qdss_dap_sync_clk_src",
+ .parent_names = (const char *[]){
+ "qdss_tsctr_clk_src"
+ },
+ .num_parents = 1,
+ .ops = &clk_fixed_factor_ops,
+ },
+};
+
+struct freq_tbl ftbl_qdss_at_clk_src[] = {
+ F(66670000, P_GPLL0_DIV2, 6, 0, 0),
+ F(240000000, P_GPLL6, 6, 0, 0),
+ { }
+};
+
+struct clk_rcg2 qdss_at_clk_src = {
+ .cmd_rcgr = 0x2900c,
+ .freq_tbl = ftbl_qdss_at_clk_src,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "qdss_at_clk_src",
+ .parent_names = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2,
+ .num_parents = 5,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
+
+struct freq_tbl ftbl_adss_pwm_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(200000000, P_GPLL0, 4, 0, 0),
+ { }
+};
+
+struct clk_rcg2 adss_pwm_clk_src = {
+ .cmd_rcgr = 0x1c008,
+ .freq_tbl = ftbl_adss_pwm_clk_src,
+ .hid_width = 5,
+ .parent_map = gcc_xo_gpll0_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "adss_pwm_clk_src",
+ .parent_names = gcc_xo_gpll0,
+ .num_parents = 2,
+ .ops = &clk_rcg2_ops,
+ },
+};
+
static struct clk_branch gcc_blsp1_ahb_clk = {
.halt_reg = 0x01008,
.clkr = {
@@ -4344,13 +4438,7 @@ static struct clk_branch gcc_gp3_clk = {
},
};
-static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
- F(19200000, P_XO, 1, 0, 0),
- F(100000000, P_GPLL0, 8, 0, 0),
- { }
-};
-
-static struct clk_rcg2 pcie0_rchng_clk_src = {
+struct clk_rcg2 pcie0_rchng_clk_src = {
.cmd_rcgr = 0x75070,
.freq_tbl = ftbl_pcie_rchng_clk_src,
.hid_width = 5,
@@ -4399,6 +4487,114 @@ static struct clk_branch gcc_pcie0_axi_s
},
};
+static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = {
+ .halt_reg = 0x4700c,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x4700c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_snoc_bus_timeout2_ahb_clk",
+ .parent_names = (const char *[]){
+ "usb0_master_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = {
+ .halt_reg = 0x47014,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x47014,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_snoc_bus_timeout3_ahb_clk",
+ .parent_names = (const char *[]){
+ "usb1_master_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_dcc_clk = {
+ .halt_reg = 0x77004,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x77004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_dcc_clk",
+ .parent_names = (const char *[]){
+ "pcnoc_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_qdss_at_clk = {
+ .halt_reg = 0x29024,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x29024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_qdss_at_clk",
+ .parent_names = (const char *[]){
+ "qdss_at_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_qdss_dap_clk = {
+ .halt_reg = 0x29084,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x29084,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_qdss_dap_clk",
+ .parent_names = (const char *[]){
+ "qdss_dap_sync_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_branch gcc_adss_pwm_clk = {
+ .halt_reg = 0x1c020,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x1c020,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_adss_pwm_clk",
+ .parent_names = (const char *[]){
+ "adss_pwm_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
static struct clk_hw *gcc_ipq8074_hws[] = {
&gpll0_out_main_div2.hw,
&gpll6_out_main_div2.hw,
@@ -4407,6 +4603,7 @@ static struct clk_hw *gcc_ipq8074_hws[]
&gcc_xo_div4_clk_src.hw,
&nss_noc_clk_src.hw,
&nss_ppe_cdiv_clk_src.hw,
+ &qdss_dap_sync_clk_src.hw,
};
static const struct alpha_pll_config ubi32_pll_config = {
@@ -4665,6 +4862,15 @@ static struct clk_regmap *gcc_ipq8074_cl
[GCC_PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr,
[GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr,
[GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr,
+ [GCC_SNOC_BUS_TIMEOUT2_AHB_CLK] = &gcc_snoc_bus_timeout2_ahb_clk.clkr,
+ [GCC_SNOC_BUS_TIMEOUT3_AHB_CLK] = &gcc_snoc_bus_timeout3_ahb_clk.clkr,
+ [GCC_DCC_CLK] = &gcc_dcc_clk.clkr,
+ [QDSS_TSCTR_CLK_SRC] = &qdss_tsctr_clk_src.clkr,
+ [QDSS_AT_CLK_SRC] = &qdss_at_clk_src.clkr,
+ [GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr,
+ [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr,
+ [ADSS_PWM_CLK_SRC] = &adss_pwm_clk_src.clkr,
+ [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr,
};
static const struct qcom_reset_map gcc_ipq8074_resets[] = {
@@ -4801,6 +5007,20 @@ static const struct qcom_reset_map gcc_i
[GCC_PCIE1_AHB_ARES] = { 0x76040, 5 },
[GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 },
[GCC_WCSSAON_RESET] = { 0x59010, 0 },
+ [GCC_PPE_FULL_RESET] = { 0x68014, 0, 0xf0000},
+ [GCC_UNIPHY0_SOFT_RESET] = { 0x56004, 0, 0x3ff2},
+ [GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 },
+ [GCC_UNIPHY1_SOFT_RESET] = { 0x56104, 0, 0x32},
+ [GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 },
+ [GCC_UNIPHY2_SOFT_RESET] = { 0x56204, 0, 0x32},
+ [GCC_UNIPHY2_XPCS_RESET] = { 0x56204, 2 },
+ [GCC_EDMA_HW_RESET] = { 0x68014, 0, 0x300000},
+ [GCC_NSSPORT1_RESET] = { 0x68014, 0, 0x1000003},
+ [GCC_NSSPORT2_RESET] = { 0x68014, 0, 0x200000c},
+ [GCC_NSSPORT3_RESET] = { 0x68014, 0, 0x4000030},
+ [GCC_NSSPORT4_RESET] = { 0x68014, 0, 0x8000300},
+ [GCC_NSSPORT5_RESET] = { 0x68014, 0, 0x10000c00},
+ [GCC_NSSPORT6_RESET] = { 0x68014, 0, 0x20003000},
};
static const struct of_device_id gcc_ipq8074_match_table[] = {
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -230,10 +230,19 @@
#define GCC_GP1_CLK 221
#define GCC_GP2_CLK 222
#define GCC_GP3_CLK 223
-#define GCC_PCIE0_AXI_S_BRIDGE_CLK 224
-#define GCC_PCIE0_RCHNG_CLK_SRC 225
-#define GCC_PCIE0_RCHNG_CLK 226
-#define GCC_CRYPTO_PPE_CLK 227
+#define GCC_CRYPTO_PPE_CLK 224
+#define GCC_PCIE0_RCHNG_CLK_SRC 225
+#define GCC_PCIE0_RCHNG_CLK 226
+#define GCC_PCIE0_AXI_S_BRIDGE_CLK 227
+#define GCC_SNOC_BUS_TIMEOUT2_AHB_CLK 228
+#define GCC_SNOC_BUS_TIMEOUT3_AHB_CLK 229
+#define GCC_DCC_CLK 230
+#define ADSS_PWM_CLK_SRC 231
+#define GCC_ADSS_PWM_CLK 232
+#define QDSS_TSCTR_CLK_SRC 233
+#define QDSS_AT_CLK_SRC 234
+#define GCC_QDSS_AT_CLK 235
+#define GCC_QDSS_DAP_CLK 236
#define GCC_BLSP1_BCR 0
#define GCC_BLSP1_QUP1_BCR 1
@@ -368,5 +377,19 @@
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
#define GCC_PCIE0_AXI_SLAVE_STICKY_ARES 131
#define GCC_WCSSAON_RESET 132
+#define GCC_PPE_FULL_RESET 133
+#define GCC_UNIPHY0_SOFT_RESET 134
+#define GCC_UNIPHY0_XPCS_RESET 135
+#define GCC_UNIPHY1_SOFT_RESET 136
+#define GCC_UNIPHY1_XPCS_RESET 137
+#define GCC_UNIPHY2_SOFT_RESET 138
+#define GCC_UNIPHY2_XPCS_RESET 139
+#define GCC_EDMA_HW_RESET 140
+#define GCC_NSSPORT1_RESET 141
+#define GCC_NSSPORT2_RESET 142
+#define GCC_NSSPORT3_RESET 143
+#define GCC_NSSPORT4_RESET 144
+#define GCC_NSSPORT5_RESET 145
+#define GCC_NSSPORT6_RESET 146
#endif

View File

@ -1,44 +0,0 @@
From 462aa0c53397ec5bf78e3e7f68aa8a3ca300f4ba Mon Sep 17 00:00:00 2001
From: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Date: Tue, 24 Mar 2020 19:09:38 +0530
Subject: [PATCH 5/8] clk: qcom: ipq8074: Fix gcc_snoc_bus_timeout_ahb_clk
offset
By default, the ipq8074 V2 clks are provided in the gcc driver.
Updating the gcc_snoc_bus_timeout_ahb_clk offsets also as needed
in ipq8074 V2.
Change-Id: I5a6e98d002f5c3354a804e55dd9ebb1f83f7f974
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
---
drivers/clk/qcom/gcc-ipq8074.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4488,10 +4488,10 @@ static struct clk_branch gcc_pcie0_axi_s
};
static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = {
- .halt_reg = 0x4700c,
+ .halt_reg = 0x47014,
.halt_bit = 31,
.clkr = {
- .enable_reg = 0x4700c,
+ .enable_reg = 0x47014,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_snoc_bus_timeout2_ahb_clk",
@@ -4506,10 +4506,10 @@ static struct clk_branch gcc_snoc_bus_ti
};
static struct clk_branch gcc_snoc_bus_timeout3_ahb_clk = {
- .halt_reg = 0x47014,
+ .halt_reg = 0x4701C,
.halt_bit = 31,
.clkr = {
- .enable_reg = 0x47014,
+ .enable_reg = 0x4701C,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_snoc_bus_timeout3_ahb_clk",

View File

@ -1,35 +0,0 @@
From d4f5b0945dd4ec3638009fca0b4d13098155dca9 Mon Sep 17 00:00:00 2001
From: zhongjia <zhongjia@codeaurora.org>
Date: Thu, 13 Aug 2020 00:38:46 +0800
Subject: [PATCH 6/8] qcom: clk: ipq8074: fix port 6 clock issue for 1G
Change-Id: I279321a33f77404f75d4c60c607892df36fb25be
Signed-off-by: zhongjia <zhongjia@codeaurora.org>
---
drivers/clk/qcom/gcc-ipq8074.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -1889,8 +1889,10 @@ static struct clk_regmap_div nss_port5_t
static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY2_RX, 5, 0, 0),
F(25000000, P_UNIPHY2_RX, 12.5, 0, 0),
F(78125000, P_UNIPHY2_RX, 4, 0, 0),
+ F(125000000, P_UNIPHY2_RX, 1, 0, 0),
F(125000000, P_UNIPHY2_RX, 2.5, 0, 0),
F(156250000, P_UNIPHY2_RX, 2, 0, 0),
F(312500000, P_UNIPHY2_RX, 1, 0, 0),
@@ -1929,8 +1931,10 @@ static struct clk_regmap_div nss_port6_r
static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY2_TX, 5, 0, 0),
F(25000000, P_UNIPHY2_TX, 12.5, 0, 0),
F(78125000, P_UNIPHY2_TX, 4, 0, 0),
+ F(125000000, P_UNIPHY2_TX, 1, 0, 0),
F(125000000, P_UNIPHY2_TX, 2.5, 0, 0),
F(156250000, P_UNIPHY2_TX, 2, 0, 0),
F(312500000, P_UNIPHY2_TX, 1, 0, 0),

View File

@ -1,41 +0,0 @@
From 6cc04849eea4d87b3b274cc900c6a14a1ac866f5 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Wed, 12 Jul 2017 21:42:11 +0530
Subject: [PATCH 7/8] clk: qcom: ipq8074: Add NSS PORT clocks frequencies
The port clock uses different frequency which depends upon
ethernet PHY mode.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
(cherry picked from commit ae5f033e8929d0ffc34320c89b5683f801c3121c)
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: I7f5d24bc400b3c35d68ef08ae73ab8395b7dd87b
---
drivers/clk/qcom/gcc-ipq8074.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -1810,8 +1810,10 @@ static struct clk_regmap_div nss_port4_t
static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(25000000, P_UNIPHY1_RX, 12.5, 0, 0),
+ F(25000000, P_UNIPHY0_RX, 5, 0, 0),
F(78125000, P_UNIPHY1_RX, 4, 0, 0),
F(125000000, P_UNIPHY1_RX, 2.5, 0, 0),
+ F(125000000, P_UNIPHY0_RX, 1, 0, 0),
F(156250000, P_UNIPHY1_RX, 2, 0, 0),
F(312500000, P_UNIPHY1_RX, 1, 0, 0),
{ }
@@ -1849,8 +1851,10 @@ static struct clk_regmap_div nss_port5_r
static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY0_TX, 5, 0, 0),
F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
F(78125000, P_UNIPHY1_TX, 4, 0, 0),
+ F(125000000, P_UNIPHY0_TX, 1, 0, 0),
F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
F(156250000, P_UNIPHY1_TX, 2, 0, 0),
F(312500000, P_UNIPHY1_TX, 1, 0, 0),

View File

@ -1,38 +0,0 @@
From be45ad064b7afdbc1e4f36c5a04c27cc364900c2 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Tue, 7 Nov 2017 15:03:52 +0530
Subject: [PATCH 8/8] clk: qcom: ipq8074: change freq table for
port5_tx_clk_src
Originally QCOM clock framework assumes that there will be
only one entry for each freq but in port5, the same freq can be
supplied by 2 sources, uniphy0 and uniphy1. We need to move
uniphy1 above uniphy0 in frequency table so that uniphy1 will be
selected instead of uniphy0 if uniphy0 is running in
125 Mhz and uniphy1 is running in 312 Mhz.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
(cherry picked from commit 559fcf09e9681f7d1fcbd981a5de7957ffb3e496)
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: I91c17714922afc1ef4cdb5e6e47e2e813e2e9777
---
drivers/clk/qcom/gcc-ipq8074.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -1851,11 +1851,11 @@ static struct clk_regmap_div nss_port5_r
static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
- F(25000000, P_UNIPHY0_TX, 5, 0, 0),
F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
+ F(25000000, P_UNIPHY0_TX, 5, 0, 0),
F(78125000, P_UNIPHY1_TX, 4, 0, 0),
- F(125000000, P_UNIPHY0_TX, 1, 0, 0),
F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
+ F(125000000, P_UNIPHY0_TX, 1, 0, 0),
F(156250000, P_UNIPHY1_TX, 2, 0, 0),
F(312500000, P_UNIPHY1_TX, 1, 0, 0),
{ }

View File

@ -1,41 +0,0 @@
From 43d5a2b56802327a27a3acb30eb1e458959f5794 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 13 May 2021 11:14:02 +0200
Subject: [PATCH] arm64: dts: ipq8074: add SPMI bus
IPQ8074 has a SPMI v2 arbiter, so add the node
for it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -390,6 +390,25 @@
#reset-cells = <0x1>;
};
+ spmi_bus: qcom,spmi@200f000 {
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0x200f000 0x1000>,
+ <0x2400000 0x800000>,
+ <0x2c00000 0x800000>,
+ <0x3800000 0x200000>,
+ <0x200a000 0x000700>;
+ reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "periph_irq";
+ qcom,ee = <0>;
+ qcom,channel = <0>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-controller;
+ #interrupt-cells = <4>;
+ cell-index = <0>;
+ };
+
sdhc_1: sdhci@7824900 {
compatible = "qcom,sdhci-msm-v4";
reg = <0x7824900 0x500>, <0x7824000 0x800>;

View File

@ -1,38 +0,0 @@
From 43361c2201bc9b67ee42a6afab7a3a476eaf6156 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Tue, 31 Mar 2020 22:00:27 +0530
Subject: [PATCH 1/6] regulator: qcom_spmi: Add PMD9655 SPMI regulator
PMD9655 is used in IPQ8074 and provides S3 for cores,
S4 for UBI core and LDO11 for SDIO/eMMC.
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/regulator/qcom_spmi-regulator.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -2082,6 +2082,13 @@ static const struct spmi_regulator_data
{ }
};
+static const struct spmi_regulator_data pmd9655_regulators[] = {
+ { "s3", 0x1a00, "vdd_s3",},
+ { "s4", 0x1d00, "vdd_s4",},
+ { "ldo11", 0x4a00, "vdd_ldo11",},
+ { }
+};
+
static const struct of_device_id qcom_spmi_regulator_match[] = {
{ .compatible = "qcom,pm8004-regulators", .data = &pm8004_regulators },
{ .compatible = "qcom,pm8005-regulators", .data = &pm8005_regulators },
@@ -2094,6 +2101,7 @@ static const struct of_device_id qcom_sp
{ .compatible = "qcom,pm660-regulators", .data = &pm660_regulators },
{ .compatible = "qcom,pm660l-regulators", .data = &pm660l_regulators },
{ .compatible = "qcom,pms405-regulators", .data = &pms405_regulators },
+ { .compatible = "qcom,pmd9655-regulators", .data = &pmd9655_regulators },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);

View File

@ -1,22 +0,0 @@
From 095567c1736af28ef6b472e2ab728a2222a425da Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Mon, 4 May 2020 19:31:00 +0530
Subject: [PATCH 2/6] regulator: qcom_spmi: SMPS range is added to support
PMD9655 PMIC
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: I5571801debec25527fd763d95aff27cc42f53bde
---
drivers/regulator/qcom_spmi-regulator.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -480,6 +480,7 @@ static struct spmi_voltage_range ln_ldo_
};
static struct spmi_voltage_range smps_ranges[] = {
+ SPMI_VOLTAGE_RANGE(2, 670000, 670000, 990000, 990000, 8000),
SPMI_VOLTAGE_RANGE(0, 375000, 375000, 1562500, 1562500, 12500),
SPMI_VOLTAGE_RANGE(1, 1550000, 1575000, 3125000, 3125000, 25000),
};

View File

@ -1,35 +0,0 @@
From 0890aba3f364ed0764fdfa79bd77db130396e594 Mon Sep 17 00:00:00 2001
From: PRAVEENKUMAR I <ipkumar@codeaurora.org>
Date: Tue, 5 May 2020 07:57:21 +0530
Subject: [PATCH 3/6] regulator: qcom_spmi: Initialize slew rate only if
required
Initialize slew rate only if set_voltage_time_sel in ops
is defined.
Change-Id: I661c88d2f4a8f26cc85b1e2d4c8aa3170420ba6c
Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
(cherry picked from commit 608a6f171ef4017197fbe2069b5910b582923027)
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: Ida3cf3d754e1207e34a164d6d86c6e1aa109ef1e
---
drivers/regulator/qcom_spmi-regulator.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -1610,6 +1610,13 @@ static int spmi_regulator_init_slew_rate
int step, delay, slew_rate, step_delay;
const struct spmi_voltage_range *range;
+ /*
+ * Slew rate need not be initialized if
+ * set_voltage_time_sel in the ops is not defined.
+ */
+ if (!vreg->desc.ops->set_voltage_time_sel)
+ return 0;
+
ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_STEP_CTRL, &reg, 1);
if (ret) {
dev_err(vreg->dev, "spmi read failed, ret=%d\n", ret);

View File

@ -1,159 +0,0 @@
From 50b5c040b8c1928990baad8e07126df63aa09cce Mon Sep 17 00:00:00 2001
From: PRAVEENKUMAR I <ipkumar@codeaurora.org>
Date: Tue, 5 May 2020 07:57:52 +0530
Subject: [PATCH 4/6] regulator: qcom_spmi: Add support for VMPWM_CTL subtype
Support for Voltage Mode PWM Controller (VMPWM_CTL).
Set/Get microvolts functions added. Function to find the
voltage range for this particular subtype added.
Change-Id: Ib4bf35ee65de17a917f01e63208368c7770401d4
Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
(cherry picked from commit 31e7e4183b5afaf18dbca3548f4988c420ebb58b)
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: Id7a3caef84499b9e2eefda9f57576923c84234f0
---
drivers/regulator/qcom_spmi-regulator.c | 82 +++++++++++++++++++++++++
1 file changed, 82 insertions(+)
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -163,6 +163,7 @@ enum spmi_regulator_subtype {
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL3 = 0x0f,
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL4 = 0x10,
SPMI_REGULATOR_SUBTYPE_HFS430 = 0x0a,
+ SPMI_REGULATOR_SUBTYPE_VMPWM_CTL = 0x0a,
};
enum spmi_common_regulator_registers {
@@ -288,6 +289,10 @@ enum spmi_common_control_register_index
#define SPMI_FTSMPS_STEP_CTRL_DELAY_MASK 0x07
#define SPMI_FTSMPS_STEP_CTRL_DELAY_SHIFT 0
+#define SPMI_SMPS_VMPWM_VSET_UB_SHIFT 8
+#define SPMI_SMPS_VMPWM_VSET_UB_MASK 0xf00
+#define SPMI_SMPS_VMPWM_VSET_LB_MASK 0xff
+
/* Clock rate in kHz of the FTSMPS regulator reference clock. */
#define SPMI_FTSMPS_CLOCK_RATE 19200
@@ -485,6 +490,10 @@ static struct spmi_voltage_range smps_ra
SPMI_VOLTAGE_RANGE(1, 1550000, 1575000, 3125000, 3125000, 25000),
};
+static struct spmi_voltage_range smps_vmpwm_ranges[] = {
+ SPMI_VOLTAGE_RANGE(0, 664000, 664000, 1104000, 1104000, 8000),
+};
+
static struct spmi_voltage_range ftsmps_ranges[] = {
SPMI_VOLTAGE_RANGE(0, 0, 350000, 1275000, 1275000, 5000),
SPMI_VOLTAGE_RANGE(1, 0, 1280000, 2040000, 2040000, 10000),
@@ -550,6 +559,7 @@ static DEFINE_SPMI_SET_POINTS(nldo2);
static DEFINE_SPMI_SET_POINTS(nldo3);
static DEFINE_SPMI_SET_POINTS(ln_ldo);
static DEFINE_SPMI_SET_POINTS(smps);
+static DEFINE_SPMI_SET_POINTS(smps_vmpwm);
static DEFINE_SPMI_SET_POINTS(ftsmps);
static DEFINE_SPMI_SET_POINTS(ftsmps2p5);
static DEFINE_SPMI_SET_POINTS(ftsmps426);
@@ -740,6 +750,24 @@ spmi_regulator_find_range(struct spmi_re
return NULL;
}
+static const struct spmi_voltage_range *
+spmi_regulator_find_uV_range(struct spmi_regulator *vreg, int min, int max)
+{
+ const struct spmi_voltage_range *range, *end;
+
+ if (!vreg->set_points || !vreg->set_points->count)
+ return 0;
+
+ range = vreg->set_points->range;
+ end = range + vreg->set_points->count;
+
+ for (; range < end; range++)
+ if ((range->min_uV <= min) && (range->max_uV >= max))
+ return range;
+
+ return 0;
+}
+
static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,
int min_uV, int max_uV)
{
@@ -961,6 +989,47 @@ static int spmi_regulator_ult_lo_smps_ge
return spmi_hw_selector_to_sw(vreg, voltage_sel, range);
}
+static int spmi_regulator_smps_vmpwm_set_vol_uV(struct regulator_dev *rdev,
+ int min_uV, int max_uV, unsigned *selector)
+{
+ struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
+ const struct spmi_voltage_range *range;
+ int req_vol;
+ u8 reg[2];
+
+ range = spmi_regulator_find_uV_range(vreg, min_uV, max_uV);
+ if (!range)
+ return -EINVAL;
+
+ *selector = spmi_regulator_select_voltage(vreg, min_uV, max_uV);
+ req_vol = range->set_point_min_uV + (range->step_uV * (*selector));
+
+ /* Convert uV to mV as the register supports mV */
+ req_vol = req_vol/1000;
+
+ /*
+ * Voltage set point bits<7:0>. 2-Byte Word (lower byte word)
+ */
+ reg[0] = req_vol & SPMI_SMPS_VMPWM_VSET_LB_MASK;
+ /*
+ * Voltage set point bit <11:8>. 2-Byte Word (upper byte word)
+ */
+ reg[1] = (req_vol & SPMI_SMPS_VMPWM_VSET_UB_MASK)
+ >> SPMI_SMPS_VMPWM_VSET_UB_SHIFT;
+
+ return spmi_vreg_write(vreg, SPMI_COMMON_REG_VOLTAGE_RANGE, reg, 2);
+}
+
+static int spmi_regulator_smps_vmpwm_get_vol_uV(struct regulator_dev *rdev)
+{
+ struct spmi_regulator *vreg = rdev_get_drvdata(rdev);
+ u8 reg[2];
+
+ spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_RANGE, reg, 2);
+
+ return ((reg[1] << SPMI_SMPS_VMPWM_VSET_UB_SHIFT) | reg[0]) * 1000;
+}
+
static int spmi_regulator_common_list_voltage(struct regulator_dev *rdev,
unsigned selector)
{
@@ -1309,6 +1378,18 @@ static const struct regulator_ops spmi_s
.set_pull_down = spmi_regulator_common_set_pull_down,
};
+static const struct regulator_ops spmi_smps_vmpwm_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_voltage = spmi_regulator_smps_vmpwm_set_vol_uV,
+ .get_voltage = spmi_regulator_smps_vmpwm_get_vol_uV,
+ .map_voltage = spmi_regulator_common_map_voltage,
+ .list_voltage = spmi_regulator_common_list_voltage,
+ .set_mode = spmi_regulator_common_set_mode,
+ .get_mode = spmi_regulator_common_get_mode,
+};
+
static const struct regulator_ops spmi_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -1454,6 +1535,7 @@ static const struct regulator_ops spmi_h
static const struct spmi_regulator_mapping supported_regulators[] = {
/* type subtype dig_min dig_max ltype ops setpoints hpm_min */
+ SPMI_VREG(BUCK, VMPWM_CTL, 0, INF, SMPS, smps_vmpwm, smps_vmpwm, 0),
SPMI_VREG(BUCK, GP_CTL, 0, INF, SMPS, smps, smps, 100000),
SPMI_VREG(BUCK, HFS430, 0, INF, HFS430, hfs430, hfs430, 10000),
SPMI_VREG(LDO, N300, 0, INF, LDO, ldo, nldo1, 10000),

View File

@ -1,53 +0,0 @@
From 84d0ae645dc1c3d8726bf8cd482be052f915f00b Mon Sep 17 00:00:00 2001
From: Vasudevan Murugesan <vmuruges@codeaurora.org>
Date: Thu, 8 Jun 2017 19:13:48 +0530
Subject: [PATCH 5/6] ipq807x: sdhc: Fixed SDR104 mode card detection
Change-Id: I353356284d28d09d79bf7d318c4ebcdbc15e5b02
Signed-off-by: Vasudevan Murugesan <vmuruges@codeaurora.org>
Signed-off-by: Saravanan Jaganathan <sjaganat@codeaurora.org>
(cherry picked from commit 080d3f390aa409ef2b5adf59a175b6bb2aa863fd)
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: Ie5edb7b3d972e06f3eb2525e10597b49e9bae14d
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 1 -
drivers/regulator/qcom_spmi-regulator.c | 3 +++
2 files changed, 3 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -430,7 +430,6 @@
status = "disabled";
};
-
blsp_dma: dma@7884000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x07884000 0x2b000>;
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -164,6 +164,7 @@ enum spmi_regulator_subtype {
SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL4 = 0x10,
SPMI_REGULATOR_SUBTYPE_HFS430 = 0x0a,
SPMI_REGULATOR_SUBTYPE_VMPWM_CTL = 0x0a,
+ SPMI_REGULATOR_SUBTYPE_HT_P150 = 0x35,
};
enum spmi_common_regulator_registers {
@@ -492,6 +493,7 @@ static struct spmi_voltage_range smps_ra
static struct spmi_voltage_range smps_vmpwm_ranges[] = {
SPMI_VOLTAGE_RANGE(0, 664000, 664000, 1104000, 1104000, 8000),
+ SPMI_VOLTAGE_RANGE(1, 1104000, 1104000, 3300000, 3300000, 8000),
};
static struct spmi_voltage_range ftsmps_ranges[] = {
@@ -1535,6 +1537,7 @@ static const struct regulator_ops spmi_h
static const struct spmi_regulator_mapping supported_regulators[] = {
/* type subtype dig_min dig_max ltype ops setpoints hpm_min */
+ SPMI_VREG(LDO, HT_P150, 0, INF, LDO, smps_vmpwm, smps_vmpwm, 0),
SPMI_VREG(BUCK, VMPWM_CTL, 0, INF, SMPS, smps_vmpwm, smps_vmpwm, 0),
SPMI_VREG(BUCK, GP_CTL, 0, INF, SMPS, smps, smps, 100000),
SPMI_VREG(BUCK, HFS430, 0, INF, HFS430, hfs430, hfs430, 10000),

View File

@ -1,49 +0,0 @@
From c603c7a1e2d5cc432d8e1250baff8130755a6f43 Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Mon, 13 Jul 2020 18:13:48 +0530
Subject: [PATCH 6/6] ipq807x: spmi regulator: Add separate voltage range for
LDO
When LDO voltage range added in SMPS voltage range structure,
selector value used during set voltage is wrongly calculated.
Because the SMPS voltage range is also taken into account for LDO.
So, a separate voltage range structure is introduced for LDO.
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: I883518ae0686762a3774750b1dd480c4fe7298f3
---
drivers/regulator/qcom_spmi-regulator.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -493,7 +493,10 @@ static struct spmi_voltage_range smps_ra
static struct spmi_voltage_range smps_vmpwm_ranges[] = {
SPMI_VOLTAGE_RANGE(0, 664000, 664000, 1104000, 1104000, 8000),
- SPMI_VOLTAGE_RANGE(1, 1104000, 1104000, 3300000, 3300000, 8000),
+};
+
+static struct spmi_voltage_range ldo_vmpwm_ranges[] = {
+ SPMI_VOLTAGE_RANGE(0, 1104000, 1104000, 3300000, 3300000, 8000),
};
static struct spmi_voltage_range ftsmps_ranges[] = {
@@ -562,6 +565,7 @@ static DEFINE_SPMI_SET_POINTS(nldo3);
static DEFINE_SPMI_SET_POINTS(ln_ldo);
static DEFINE_SPMI_SET_POINTS(smps);
static DEFINE_SPMI_SET_POINTS(smps_vmpwm);
+static DEFINE_SPMI_SET_POINTS(ldo_vmpwm);
static DEFINE_SPMI_SET_POINTS(ftsmps);
static DEFINE_SPMI_SET_POINTS(ftsmps2p5);
static DEFINE_SPMI_SET_POINTS(ftsmps426);
@@ -1537,7 +1541,7 @@ static const struct regulator_ops spmi_h
static const struct spmi_regulator_mapping supported_regulators[] = {
/* type subtype dig_min dig_max ltype ops setpoints hpm_min */
- SPMI_VREG(LDO, HT_P150, 0, INF, LDO, smps_vmpwm, smps_vmpwm, 0),
+ SPMI_VREG(LDO, HT_P150, 0, INF, LDO, smps_vmpwm, ldo_vmpwm, 0),
SPMI_VREG(BUCK, VMPWM_CTL, 0, INF, SMPS, smps_vmpwm, smps_vmpwm, 0),
SPMI_VREG(BUCK, GP_CTL, 0, INF, SMPS, smps, smps, 100000),
SPMI_VREG(BUCK, HFS430, 0, INF, HFS430, hfs430, hfs430, 10000),

View File

@ -1,84 +0,0 @@
From df848f06020c609950107f87c39f41e7eee92b5e Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 13 May 2021 11:54:35 +0200
Subject: [PATCH] arm64: dts: ipq8074: add SPMI PMIC regulators
PMD9655 is used in IPQ8074 and provides S3 for cores,
S4 for UBI core and LDO11 for SDIO/eMMC.
So, lets add the nodes in preparation for DVFS later.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 46 +++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-ipq8074.h>
+#include <dt-bindings/spmi/spmi.h>
/ {
model = "Qualcomm Technologies, Inc. IPQ8074";
@@ -136,6 +137,15 @@
};
};
+ e_smps1_reg: fixed-regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "e-smps1-reg";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
soc: soc {
#address-cells = <0x1>;
#size-cells = <0x1>;
@@ -407,6 +417,42 @@
interrupt-controller;
#interrupt-cells = <4>;
cell-index = <0>;
+
+ pmic@1 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ regulators {
+ compatible = "qcom,pmd9655-regulators";
+ vdd_s3-supply = <&e_smps1_reg>;
+ vdd_s4-supply = <&e_smps1_reg>;
+ vdd_ldo11-supply = <&e_smps1_reg>;
+
+ s3: s3 {
+ regulator-name = "pmd9655_s3";
+ regulator-min-microvolt = <592000>;
+ regulator-max-microvolt = <1064000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ s4: s4 {
+ regulator-name = "pmd9655_s4";
+ regulator-min-microvolt = <712000>;
+ regulator-max-microvolt = <992000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ ldo11: ldo11 {
+ regulator-name = "pmd9655_ldo11";
+ regulator-min-microvolt = <1104000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
};
sdhc_1: sdhci@7824900 {

View File

@ -1,328 +0,0 @@
From 6961b02dd2765b71b201f065172998a16ff9c2eb Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Sun, 22 Mar 2020 20:22:29 +0530
Subject: [PATCH 1/3] ipq8074: clk: apss: Added APSS clock driver
apss-ipq8074 files are snapshot form eggplant branch,
https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/commit/?h=keggplant/eggplant&id=f2fb70e8315ef1c450171e59d681c6a156b1a4e8
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: I17ecad1f1731c88d8d91485d5d5f8a38b76f7104
---
drivers/clk/qcom/Kconfig | 7 +
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/apss-ipq8074.c | 210 +++++++++++++++++++
drivers/clk/qcom/clk-alpha-pll.c | 12 ++
drivers/clk/qcom/clk-alpha-pll.h | 3 +
include/dt-bindings/clock/qca,apss-ipq8074.h | 25 +++
6 files changed, 258 insertions(+)
create mode 100644 drivers/clk/qcom/apss-ipq8074.c
create mode 100644 include/dt-bindings/clock/qca,apss-ipq8074.h
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -155,6 +155,13 @@ config IPQ_GCC_8074
i2c, USB, SD/eMMC, etc. Select this for the root clock
of ipq8074.
+config IPQ_APSS_8074
+ tristate "IPQ8074 APSS Clock Controller"
+ select IPQ_GCC_8074
+ help
+ Support for APSS clock controller on ipq8074 devices.
+ Say Y if you want to use APSS clocks such as CPU.
+
config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
help
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq401
obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
+obj-$(CONFIG_IPQ_APSS_8074) += apss-ipq8074.o
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
--- /dev/null
+++ b/drivers/clk/qcom/apss-ipq8074.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2017,2020. The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include <linux/reset-controller.h>
+#include <dt-bindings/clock/qca,apss-ipq8074.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "reset.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+ P_XO,
+ P_GPLL0,
+ P_GPLL2,
+ P_GPLL4,
+ P_APSS_PLL_EARLY,
+ P_APSS_PLL
+};
+
+static struct clk_alpha_pll apss_pll_early = {
+ .offset = 0x5000,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_APSS],
+ .clkr = {
+ .enable_reg = 0x5000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "apss_pll_early",
+ .parent_names = (const char *[]){
+ "xo"
+ },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_huayra_ops,
+ },
+ },
+};
+
+static struct clk_alpha_pll_postdiv apss_pll = {
+ .offset = 0x5000,
+ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_APSS],
+ .width = 2,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "apss_pll",
+ .parent_names = (const char *[]){ "apss_pll_early" },
+ .num_parents = 1,
+ .ops = &clk_alpha_pll_postdiv_ro_ops,
+ },
+};
+
+static const char * const parents_apcs_alias0_clk_src[] = {
+ "xo",
+ "gpll0",
+ "gpll2",
+ "gpll4",
+ "apss_pll",
+ "apss_pll_early",
+};
+
+static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
+ { P_XO, 0 },
+ { P_GPLL0, 4 },
+ { P_GPLL2, 2 },
+ { P_GPLL4, 1 },
+ { P_APSS_PLL, 3 },
+ { P_APSS_PLL_EARLY, 5 },
+};
+
+struct freq_tbl ftbl_apcs_alias0_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(403200000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(806400000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(1017600000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(1382400000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(1651200000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(1843200000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(1920000000, P_APSS_PLL_EARLY, 1, 0, 0),
+ F(2208000000UL, P_APSS_PLL_EARLY, 1, 0, 0),
+ { }
+};
+
+struct clk_rcg2 apcs_alias0_clk_src = {
+ .cmd_rcgr = 0x0050,
+ .freq_tbl = ftbl_apcs_alias0_clk_src,
+ .hid_width = 5,
+ .parent_map = parents_apcs_alias0_clk_src_map,
+ .clkr.hw.init = &(struct clk_init_data){
+ .name = "apcs_alias0_clk_src",
+ .parent_names = parents_apcs_alias0_clk_src,
+ .num_parents = 6,
+ .ops = &clk_rcg2_ops,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_branch apcs_alias0_core_clk = {
+ .halt_reg = 0x0058,
+ .halt_bit = 31,
+ .clkr = {
+ .enable_reg = 0x0058,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "apcs_alias0_core_clk",
+ .parent_names = (const char *[]){
+ "apcs_alias0_clk_src"
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT |
+ CLK_IS_CRITICAL,
+ .ops = &clk_branch2_ops,
+ },
+ },
+};
+
+static struct clk_regmap *apss_ipq807x_clks[] = {
+ [APSS_PLL_EARLY] = &apss_pll_early.clkr,
+ [APSS_PLL] = &apss_pll.clkr,
+ [APCS_ALIAS0_CLK_SRC] = &apcs_alias0_clk_src.clkr,
+ [APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
+};
+
+static const struct of_device_id apss_ipq807x_match_table[] = {
+ { .compatible = "qcom,apss-ipq807x" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, apss_ipq807x_match_table);
+
+static const struct regmap_config apss_ipq807x_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x5ffc,
+ .fast_io = true,
+};
+
+static const struct qcom_cc_desc apss_ipq807x_desc = {
+ .config = &apss_ipq807x_regmap_config,
+ .clks = apss_ipq807x_clks,
+ .num_clks = ARRAY_SIZE(apss_ipq807x_clks),
+};
+
+static int apss_ipq807x_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = qcom_cc_probe(pdev, &apss_ipq807x_desc);
+
+ dev_dbg(&pdev->dev, "Registered ipq807x apss clock provider\n");
+
+ return ret;
+}
+
+static int apss_ipq807x_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver apss_ipq807x_driver = {
+ .probe = apss_ipq807x_probe,
+ .remove = apss_ipq807x_remove,
+ .driver = {
+ .name = "qcom,apss-ipq807x",
+ .owner = THIS_MODULE,
+ .of_match_table = apss_ipq807x_match_table,
+ },
+};
+
+static int __init apss_ipq807x_init(void)
+{
+ return platform_driver_register(&apss_ipq807x_driver);
+}
+core_initcall(apss_ipq807x_init);
+
+static void __exit apss_ipq807x_exit(void)
+{
+ platform_driver_unregister(&apss_ipq807x_driver);
+}
+module_exit(apss_ipq807x_exit);
+
+MODULE_DESCRIPTION("QCA APSS IPQ807x Driver");
+MODULE_LICENSE("Dual BSD/GPLv2");
+MODULE_ALIAS("platform:apss-ipq807x");
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -116,6 +116,18 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MA
[PLL_OFF_OPMODE] = 0x38,
[PLL_OFF_ALPHA_VAL] = 0x40,
},
+ [CLK_ALPHA_PLL_TYPE_APSS] = {
+ [PLL_OFF_L_VAL] = 0x08,
+ [PLL_OFF_ALPHA_VAL] = 0x10,
+ [PLL_OFF_ALPHA_VAL_U] = 0xff,
+ [PLL_OFF_USER_CTL] = 0x18,
+ [PLL_OFF_USER_CTL_U] = 0xff,
+ [PLL_OFF_CONFIG_CTL] = 0x20,
+ [PLL_OFF_CONFIG_CTL_U] = 0x24,
+ [PLL_OFF_TEST_CTL] = 0x30,
+ [PLL_OFF_TEST_CTL_U] = 0x34,
+ [PLL_OFF_STATUS] = 0x28,
+ }
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
--- a/drivers/clk/qcom/clk-alpha-pll.h
+++ b/drivers/clk/qcom/clk-alpha-pll.h
@@ -15,6 +15,7 @@ enum {
CLK_ALPHA_PLL_TYPE_FABIA,
CLK_ALPHA_PLL_TYPE_TRION,
CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
+ CLK_ALPHA_PLL_TYPE_APSS,
CLK_ALPHA_PLL_TYPE_MAX,
};
@@ -69,6 +70,8 @@ struct clk_alpha_pll {
#define SUPPORTS_OFFLINE_REQ BIT(0)
#define SUPPORTS_FSM_MODE BIT(2)
#define SUPPORTS_DYNAMIC_UPDATE BIT(3)
+
+
u8 flags;
struct clk_regmap clkr;
--- /dev/null
+++ b/include/dt-bindings/clock/qca,apss-ipq8074.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017,2020. The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_QCA_APSS_IPQ8074_H
+#define _DT_BINDINGS_CLOCK_QCA_APSS_IPQ8074_H
+
+#define APSS_PLL_EARLY 0
+#define APSS_PLL 1
+#define APCS_ALIAS0_CLK_SRC 2
+#define APCS_ALIAS0_CORE_CLK 3
+
+#endif

View File

@ -1,105 +0,0 @@
From b5c28ea3b9a963d425ae88ef53d266ff8ae95bc2 Mon Sep 17 00:00:00 2001
From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Date: Fri, 24 Apr 2020 23:05:50 +0530
Subject: [PATCH 2/3] clk: qcom: ipq8074: make apss clock as child of mailbox
both apcs mailbox and apss clock controller access the same register
space, resource request will fail for one of the two drivers.
to resolve this make apss clock controller as child of mailbox, the apss
clock controller will use mailbox regmap for resource request and probe.
Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Change-Id: Ic26ee78b6f680fa0655a73d3176bae271725ab05
---
drivers/clk/qcom/apss-ipq8074.c | 14 ++++++--------
drivers/mailbox/qcom-apcs-ipc-mailbox.c | 18 +++++++++++++++---
2 files changed, 21 insertions(+), 11 deletions(-)
--- a/drivers/clk/qcom/apss-ipq8074.c
+++ b/drivers/clk/qcom/apss-ipq8074.c
@@ -147,12 +147,6 @@ static struct clk_regmap *apss_ipq807x_c
[APCS_ALIAS0_CORE_CLK] = &apcs_alias0_core_clk.clkr,
};
-static const struct of_device_id apss_ipq807x_match_table[] = {
- { .compatible = "qcom,apss-ipq807x" },
- { }
-};
-MODULE_DEVICE_TABLE(of, apss_ipq807x_match_table);
-
static const struct regmap_config apss_ipq807x_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -170,8 +164,13 @@ static const struct qcom_cc_desc apss_ip
static int apss_ipq807x_probe(struct platform_device *pdev)
{
int ret;
+ struct regmap *regmap;
+
+ regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
- ret = qcom_cc_probe(pdev, &apss_ipq807x_desc);
+ ret = qcom_cc_really_probe(pdev, &apss_ipq807x_desc, regmap);
dev_dbg(&pdev->dev, "Registered ipq807x apss clock provider\n");
@@ -189,7 +188,6 @@ static struct platform_driver apss_ipq80
.driver = {
.name = "qcom,apss-ipq807x",
.owner = THIS_MODULE,
- .of_match_table = apss_ipq807x_match_table,
},
};
--- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
+++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
@@ -65,7 +65,7 @@ static const struct regmap_config apcs_r
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
- .max_register = 0xFFC,
+ .max_register = 0x5FFC,
.fast_io = true,
};
@@ -82,6 +82,16 @@ static const struct mbox_chan_ops qcom_a
.send_data = qcom_apcs_ipc_send_data,
};
+static const struct of_device_id apcs_clk_match_table[] = {
+ { .compatible = "qcom,msm8916-apcs-kpss-global",
+ . data = "qcom-apcs-msm8916-clk", },
+ { .compatible = "qcom,qcs404-apcs-apps-global",
+ .data = "qcom-apcs-msm8916-clk", },
+ { .compatible = "qcom,ipq8074-apcs-apps-global",
+ .data = "qcom,apss-ipq807x", },
+ {}
+};
+
static int qcom_apcs_ipc_probe(struct platform_device *pdev)
{
struct qcom_apcs_ipc *apcs;
@@ -91,6 +101,7 @@ static int qcom_apcs_ipc_probe(struct pl
void __iomem *base;
unsigned long i;
int ret;
+ const struct of_device_id *device_id;
apcs = devm_kzalloc(&pdev->dev, sizeof(*apcs), GFP_KERNEL);
if (!apcs)
@@ -125,9 +136,10 @@ static int qcom_apcs_ipc_probe(struct pl
return ret;
}
- if (apcs_data->clk_name) {
+ device_id = of_match_device(apcs_clk_match_table, &pdev->dev);
+ if (device_id) {
apcs->clk = platform_device_register_data(&pdev->dev,
- apcs_data->clk_name,
+ device_id->data,
PLATFORM_DEVID_AUTO,
NULL, 0);
if (IS_ERR(apcs->clk))

View File

@ -1,70 +0,0 @@
From 99841b41e13b4a0512de1e06191cdcaf7ee0e1d1 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 13 May 2021 12:42:05 +0200
Subject: [PATCH 3/3] arm64: dts: ipq8074: add APPS CPU clock
In preparation for frequency scaling add the APPS
clock support.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -5,6 +5,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-ipq8074.h>
+#include <dt-bindings/clock/qca,apss-ipq8074.h>
#include <dt-bindings/spmi/spmi.h>
/ {
@@ -33,6 +34,8 @@
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0>;
+ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
+ clock-names = "cpu";
next-level-cache = <&L2_0>;
enable-method = "psci";
};
@@ -42,6 +45,8 @@
compatible = "arm,cortex-a53";
enable-method = "psci";
reg = <0x1>;
+ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
+ clock-names = "cpu";
next-level-cache = <&L2_0>;
};
@@ -50,6 +55,8 @@
compatible = "arm,cortex-a53";
enable-method = "psci";
reg = <0x2>;
+ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
+ clock-names = "cpu";
next-level-cache = <&L2_0>;
};
@@ -58,6 +65,8 @@
compatible = "arm,cortex-a53";
enable-method = "psci";
reg = <0x3>;
+ clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
+ clock-names = "cpu";
next-level-cache = <&L2_0>;
};
@@ -909,8 +918,9 @@
apcs_glb: mailbox@b111000 {
compatible = "qcom,ipq8074-apcs-apps-global";
- reg = <0x0b111000 0x1000>;
+ reg = <0x0b111000 0x6000>;
+ #clock-cells = <1>;
#mbox-cells = <1>;
};

View File

@ -1,26 +0,0 @@
From fb5a1fff750f99dbf7cabda0de9fbf7463a07586 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 13 May 2021 13:13:46 +0200
Subject: [PATCH] arm64: dts: ipq8074: add label to cpus
Add label to cpus node as that makes it
easy to add OPP table in SoC model specific
DTSI as IPQ8074 family has differing clocks
and voltages based on model.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -26,7 +26,7 @@
};
};
- cpus {
+ cpus: cpus {
#address-cells = <0x1>;
#size-cells = <0x0>;

View File

@ -1,133 +0,0 @@
From 0fb054684bdf40f17ab59226dae21ddfe0d79466 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 13 May 2021 15:15:46 +0200
Subject: [PATCH] arm64: dts: ipq8074: Add WLAN node
IPQ8074 is supported by ath11k, so add the required
DT node.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 111 ++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -974,6 +974,117 @@
};
};
+ wifi: wifi@c0000000 {
+ compatible = "qcom,ipq8074-wifi";
+ reg = <0xc000000 0x2000000>;
+
+ interrupts = <GIC_SPI 320 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 319 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 316 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 315 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 314 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 311 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 310 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 40 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 302 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 301 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 295 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 294 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 293 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 292 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 291 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 290 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 289 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 288 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 239 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 236 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 235 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 234 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 233 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 232 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 231 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 228 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 224 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 223 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 183 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 179 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 176 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 163 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 160 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 159 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "misc-pulse1",
+ "misc-latch",
+ "sw-exception",
+ "ce0",
+ "ce1",
+ "ce2",
+ "ce3",
+ "ce4",
+ "ce5",
+ "ce6",
+ "ce7",
+ "ce8",
+ "ce9",
+ "ce10",
+ "ce11",
+ "host2wbm-desc-feed",
+ "host2reo-re-injection",
+ "host2reo-command",
+ "host2rxdma-monitor-ring3",
+ "host2rxdma-monitor-ring2",
+ "host2rxdma-monitor-ring1",
+ "reo2ost-exception",
+ "wbm2host-rx-release",
+ "reo2host-status",
+ "reo2host-destination-ring4",
+ "reo2host-destination-ring3",
+ "reo2host-destination-ring2",
+ "reo2host-destination-ring1",
+ "rxdma2host-monitor-destination-mac3",
+ "rxdma2host-monitor-destination-mac2",
+ "rxdma2host-monitor-destination-mac1",
+ "ppdu-end-interrupts-mac3",
+ "ppdu-end-interrupts-mac2",
+ "ppdu-end-interrupts-mac1",
+ "rxdma2host-monitor-status-ring-mac3",
+ "rxdma2host-monitor-status-ring-mac2",
+ "rxdma2host-monitor-status-ring-mac1",
+ "host2rxdma-host-buf-ring-mac3",
+ "host2rxdma-host-buf-ring-mac2",
+ "host2rxdma-host-buf-ring-mac1",
+ "rxdma2host-destination-ring-mac3",
+ "rxdma2host-destination-ring-mac2",
+ "rxdma2host-destination-ring-mac1",
+ "host2tcl-input-ring4",
+ "host2tcl-input-ring3",
+ "host2tcl-input-ring2",
+ "host2tcl-input-ring1",
+ "wbm2host-tx-completions-ring3",
+ "wbm2host-tx-completions-ring2",
+ "wbm2host-tx-completions-ring1",
+ "tcl2host-status-ring";
+ qcom,rproc = <&q6v5_wcss>;
+ status = "disabled";
+ };
+
ess_switch: ess-switch@3a000000 {
compatible = "qcom,ess-switch-ipq807x";
reg = <0x3a000000 0x1000000>;

View File

@ -1,28 +0,0 @@
From 22865119dada2a40a5e5e8c5f22b5bec08651021 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 14 May 2021 19:43:41 +0200
Subject: [PATCH] arm64: dts: ipq8074: add NSS reserved memory node
NSS FW has its own dedicated memory it needs to get loaded to.
Since it simply uses ioremap() that memory must be reserved
so the kernel will allow using ioremap() on it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 5 +++++
1 file changed, 5 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -91,6 +91,11 @@
#size-cells = <2>;
ranges;
+ nss@40000000 {
+ no-map;
+ reg = <0x0 0x40000000 0x0 0x01000000>;
+ };
+
smem_region: memory@4ab00000 {
no-map;
reg = <0x0 0x4ab00000 0x0 0x00100000>;

View File

@ -1,29 +0,0 @@
From a801cc475f0d1fdf29d7b6b56d64df090bf83f8d Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Fri, 3 Apr 2020 12:57:37 +0530
Subject: [PATCH] clk: qcom: ipq8074: disable SW_COLLAPSE for USB GDSCR's
Change-Id: Id347be781e2bb449bd7cdf05e3535e8ca3c3ffd6
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
(cherry picked from commit 5e100df9c29ed7e5ad12583aa39053f4a9761efe)
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
Change-Id: I17beca334be79d738a35587860847aa0b1f96fa9
---
drivers/clk/qcom/gcc-ipq8074.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -5063,6 +5063,11 @@ static int gcc_ipq8074_probe(struct plat
if (IS_ERR(regmap))
return PTR_ERR(regmap);
+ /* Disable SW_COLLAPSE for USB0 GDSCR */
+ regmap_update_bits(regmap, 0x3e078, BIT(0), 0x0);
+ /* Disable SW_COLLAPSE for USB1 GDSCR */
+ regmap_update_bits(regmap, 0x3f078, BIT(0), 0x0);
+
clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
&nss_crypto_pll_config);

View File

@ -1,46 +0,0 @@
From 5f707d3ff1b22c089253e39906b5edeeb5f10fdc Mon Sep 17 00:00:00 2001
From: Praveenkumar I <ipkumar@codeaurora.org>
Date: Fri, 3 Apr 2020 15:31:59 +0530
Subject: [PATCH] clk: qcom: ipq8074: SW workaround for UBI PLL lock
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some chips Huyara PLL is unable to lock in 5 us and
generating UBI PLL lock error.
WARNING: CPU: 1 PID: 625 at drivers/clk/qcom/clk-alpha-pll.c:114
wait_for_pll+0xbc/0xe0()
ubi32_pll_main failed to enable!
CPU: 1 PID: 625 Comm: kmodloader Not tainted 4.4.60 #1
Hardware name: Generic DT based system
(unwind_backtrace) from [<8021b550>] (show_stack+0x10/0x14)
(show_stack) from [<803f6b24>] (dump_stack+0x80/0xa0)
(dump_stack) from [<80228ff0>] (warn_slowpath_common+0x84/0xb0)
(warn_slowpath_common) from [<80229048>] (warn_slowpath_fmt+0x2c/0x3c)
(warn_slowpath_fmt) from [<8054d53c>] (wait_for_pll+0xbc/0xe0)
(wait_for_pll) from [<8054d6cc>] (clk_alpha_pll_enable+0xe0/0x128)
(clk_alpha_pll_enable) from [<80547b68>] (clk_core_enable+0x68/0x98)
(clk_core_enable) from [<80547b48>] (clk_core_enable+0x48/0x98)
This is BUG in Huayra PLL HW for which SW workaround
is to set bit 26 of TEST_CTL register.
Change-Id: Ib5473f4011e3410515f382b2445bee2d66dd654a
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
drivers/clk/qcom/gcc-ipq8074.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -5068,6 +5068,9 @@ static int gcc_ipq8074_probe(struct plat
/* Disable SW_COLLAPSE for USB1 GDSCR */
regmap_update_bits(regmap, 0x3f078, BIT(0), 0x0);
+ /* SW Workaround for UBI Huayra PLL */
+ regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26));
+
clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
&nss_crypto_pll_config);

View File

@ -1,31 +0,0 @@
From db9c60394765843f6a77833bc40c27fac8852e97 Mon Sep 17 00:00:00 2001
From: Balaji Prakash J <bjagadee@codeaurora.org>
Date: Mon, 20 Apr 2020 20:07:51 +0530
Subject: [PATCH] clk: ipq8074: defer from disabling gcc_sleep_clk_src
Added CLK_IS_CRITICAL flag in order to defer from
disabling the sleep clock source.
Once the usb sleep clocks are disabled, clock framework
is trying to disable the sleep clock source also and
the below warning is observed.
[ 28.235750] gcc_sleep_clk_src status stuck at 'on'
[ 28.235794] WARNING: CPU: 0 PID: 29 at drivers/clk/qcom/clk-branch.c:92 clk_branch_toggle+0x160/0x178
Signed-off-by: Balaji Prakash J <bjagadee@codeaurora.org>
Change-Id: I61fab902375716272ad9c426ce71581058f7bd35
---
drivers/clk/qcom/gcc-ipq8074.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -683,6 +683,7 @@ static struct clk_branch gcc_sleep_clk_s
},
.num_parents = 1,
.ops = &clk_branch2_ops,
+ .flags = CLK_IS_CRITICAL,
},
},
};

View File

@ -1,41 +0,0 @@
From 52315bec6ed633b6a71f28b746029602f8bd70b9 Mon Sep 17 00:00:00 2001
From: Balaji Prakash J <bjagadee@codeaurora.org>
Date: Wed, 22 Apr 2020 20:35:30 +0530
Subject: [PATCH] clk: ipq8074: fix gcc_blsp1_ahb_clk properties
All the voting enabled clocks does not support the enable
from CBCR register. So, updated gcc_blsp1_ahb_clk enable
register and mask to enable bit in APCS_CLOCK_BRANCH_ENA_VOTE.
Also, the voting controlled clocks are shared among multiple
components like APSS, RPM, NSS, TZ, etc. So, turning the
voting off from APSS does not make the clock off if it has
been voted from another component. Added the flag
BRANCH_HALT_VOTED in order to skip checking the clock
disable status.
This change is referred from the below commits,
1. 246b4fb3af9bd65d8af794aac2f0e7b1ed9cc2dd
2. c8374157d5ae91d3b3e0d513d62808a798b32d3a
Signed-off-by: Balaji Prakash J <bjagadee@codeaurora.org>
Change-Id: I505cb560b31ad27a02c165fbe13bb33a2fc7d230
---
drivers/clk/qcom/gcc-ipq8074.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -2118,9 +2118,10 @@ struct clk_rcg2 adss_pwm_clk_src = {
static struct clk_branch gcc_blsp1_ahb_clk = {
.halt_reg = 0x01008,
+ .halt_check = BRANCH_HALT_VOTED,
.clkr = {
- .enable_reg = 0x01008,
- .enable_mask = BIT(0),
+ .enable_reg = 0x0b004,
+ .enable_mask = BIT(10),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp1_ahb_clk",
.parent_names = (const char *[]){

View File

@ -1,47 +0,0 @@
From 256eda666b4687c5242b9f075caf4e09ad642daa Mon Sep 17 00:00:00 2001
From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Date: Fri, 17 Apr 2020 16:37:10 +0530
Subject: [PATCH] remoteproc: wcss: disable auto boot for IPQ8074
auto boot is disabled for IPQ8074 the wifi driver brings up the wcss.
Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Change-Id: Ia82edb7ee52f2bd010c099f151179d69a953ac88
---
drivers/remoteproc/qcom_q6v5_wcss.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -161,6 +161,7 @@ struct wcss_data {
const struct rproc_ops *ops;
bool requires_force_stop;
bool need_mem_protection;
+ bool need_auto_boot;
};
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
@@ -1147,6 +1148,7 @@ static int q6v5_wcss_probe(struct platfo
desc->sysmon_name,
desc->ssctl_id);
+ rproc->auto_boot = desc->need_auto_boot;
ret = rproc_add(rproc);
if (ret)
goto free_rproc;
@@ -1183,6 +1185,7 @@ static const struct wcss_data wcss_ipq80
.ops = &q6v5_wcss_ipq8074_ops,
.requires_force_stop = true,
.need_mem_protection = true,
+ .need_auto_boot = false,
};
static const struct wcss_data wcss_qcs404_res_init = {
@@ -1199,6 +1202,7 @@ static const struct wcss_data wcss_qcs40
.ssctl_id = 0x12,
.ops = &q6v5_wcss_qcs404_ops,
.requires_force_stop = false,
+ .need_auto_boot = true,
};
static const struct of_device_id q6v5_wcss_of_match[] = {

View File

@ -1,65 +0,0 @@
From 158bd87b3db04bdd1effe4a92424f9572224a6c3 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 15 May 2021 00:09:21 +0200
Subject: [PATCH] arm64: dts: ipq8074: add missing reserved memory nodes
Downstream kernel has more reserved memory nodes.
Without these ath11k will cause a board reset.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 36 +++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -96,15 +96,47 @@
reg = <0x0 0x40000000 0x0 0x01000000>;
};
- smem_region: memory@4ab00000 {
+ tzapp: tzapp@4a400000 {
+ no-map;
+ reg = <0x0 0x4a400000 0x0 0x00200000>;
+ };
+
+
+ uboot@4a600000 {
+ no-map;
+ reg = <0x0 0x4a600000 0x0 0x00400000>;
+ };
+
+ sbl@4aa00000 {
+ no-map;
+ reg = <0x0 0x4aa00000 0x0 0x00100000>;
+ };
+
+ smem_region: smem@4ab00000 {
no-map;
reg = <0x0 0x4ab00000 0x0 0x00100000>;
};
- q6_region: memory@4b000000 {
+ tz@4ac00000 {
+ no-map;
+ reg = <0x0 0x4ac00000 0x0 0x00400000>;
+ };
+
+ q6_region: wcnss@4b000000 {
no-map;
reg = <0x0 0x4b000000 0x0 0x05f00000>;
};
+
+ q6_etr_region: q6_etr_dump@50f00000 {
+ no-map;
+ reg = <0x0 0x50f00000 0x0 0x00100000>;
+ };
+
+ m3_region: m3_dump@51000000 {
+ no-map;
+ reg = <0x0 0x51000000 0x0 0x100000>;
+ };
+
};
firmware {

View File

@ -1,24 +0,0 @@
From 86aa6afcf280a61150a3e6c796f629d09db88d55 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 15 May 2021 00:18:32 +0200
Subject: [PATCH] arm64: dts: ipq8074: add q6_etr memory region to remoteproc
Q6v5 remoteprocessor also has a q6_etr memor region
reserved for it, so add it to the node.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -998,7 +998,7 @@
qcom,smem-state-names = "shutdown",
"stop";
- memory-region = <&q6_region>;
+ memory-region = <&q6_region>, <&q6_etr_region>;
glink-edge {
interrupts = <GIC_SPI 321 IRQ_TYPE_EDGE_RISING>;

View File

@ -1,99 +0,0 @@
From 98130cb1cb992593b050baa9c4d8484d6fd6e8f6 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Fri, 20 Nov 2020 13:52:43 +0100
Subject: [PATCH] thermal: qcom: tsens: Add IPQ8074 support
Qualcomm IPQ807x SoC-s use tsens v2.3.0 IP, but they
only have one interrupt and not a dedicated critical interrupt.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/thermal/qcom/tsens-v2.c | 14 ++++++++++++++
drivers/thermal/qcom/tsens.c | 27 ++++++++++++++++++---------
drivers/thermal/qcom/tsens.h | 2 +-
3 files changed, 33 insertions(+), 10 deletions(-)
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -36,6 +36,14 @@ static struct tsens_features tsens_v2_fe
.max_sensors = 16,
};
+static struct tsens_features tsens_ipq8074_feat = {
+ .ver_major = VER_2_X,
+ .crit_int = 0,
+ .adc = 0,
+ .srot_split = 1,
+ .max_sensors = 16,
+};
+
static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
/* ----- SROT ------ */
/* VERSION */
@@ -101,6 +109,12 @@ struct tsens_plat_data data_tsens_v2 = {
.fields = tsens_v2_regfields,
};
+struct tsens_plat_data data_tsens_ipq8074 = {
+ .ops = &ops_generic_v2,
+ .feat = &tsens_ipq8074_feat,
+ .fields = tsens_v2_regfields,
+};
+
/* Kept around for backward compatibility with old msm8996.dtsi */
struct tsens_plat_data data_8996 = {
.num_sensors = 13,
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -323,16 +323,22 @@ static int tsens_read_irq_state(struct t
ret = regmap_field_read(priv->rf[LOW_INT_MASK_0 + hw_id], &d->low_irq_mask);
if (ret)
return ret;
- ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
- &d->crit_irq_clear);
- if (ret)
- return ret;
- ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
- &d->crit_irq_mask);
- if (ret)
- return ret;
+ if (priv->feat->crit_int) {
+ ret = regmap_field_read(priv->rf[CRIT_INT_CLEAR_0 + hw_id],
+ &d->crit_irq_clear);
+ if (ret)
+ return ret;
+ ret = regmap_field_read(priv->rf[CRIT_INT_MASK_0 + hw_id],
+ &d->crit_irq_mask);
+ if (ret)
+ return ret;
- d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
+ d->crit_thresh = tsens_hw_to_mC(s, CRIT_THRESH_0 + hw_id);
+ } else {
+ d->crit_irq_clear = 0;
+ d->crit_irq_mask = 0;
+ d->crit_thresh = 0;
+ }
} else {
/* No mask register on older TSENS */
d->up_irq_mask = 0;
@@ -917,6 +923,9 @@ static const struct of_device_id tsens_t
}, {
.compatible = "qcom,tsens-v2",
.data = &data_tsens_v2,
+ }, {
+ .compatible = "qcom,ipq8074-tsens",
+ .data = &data_tsens_ipq8074,
},
{}
};
--- a/drivers/thermal/qcom/tsens.h
+++ b/drivers/thermal/qcom/tsens.h
@@ -591,6 +591,6 @@ extern struct tsens_plat_data data_8916,
extern struct tsens_plat_data data_tsens_v1, data_8976;
/* TSENS v2 targets */
-extern struct tsens_plat_data data_8996, data_tsens_v2;
+extern struct tsens_plat_data data_8996, data_tsens_v2, data_tsens_ipq8074;
#endif /* __QCOM_TSENS_H__ */

View File

@ -1,55 +0,0 @@
From 47b165aa6ed3b85b793c5bfb27050c93a194c0cc Mon Sep 17 00:00:00 2001
From: Ansuel Smith <ansuelsmth@gmail.com>
Date: Wed, 19 May 2021 00:52:21 +0200
Subject: [PATCH 2/2] drivers: thermal: tsens: add timeout to
get_tem_tsens_valid
The function can loop and lock the system if for whatever reason the bit
for the target sensor is NEVER valid. This is the case if a sensor is
disabled by the factory and the valid bit is never reported as actually
valid. Add a timeout check and exit if a timeout occurs. As this is
a very rare condition, handle the timeout only if the first read fails.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/thermal/qcom/tsens.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -587,19 +587,28 @@ int get_temp_tsens_valid(const struct ts
int hw_id = s->hw_id;
u32 temp_idx = LAST_TEMP_0 + hw_id;
u32 valid_idx = VALID_0 + hw_id;
+ unsigned long timeout;
u32 valid;
int ret;
ret = regmap_field_read(priv->rf[valid_idx], &valid);
if (ret)
return ret;
- while (!valid) {
- /* Valid bit is 0 for 6 AHB clock cycles.
- * At 19.2MHz, 1 AHB clock is ~60ns.
- * We should enter this loop very, very rarely.
- */
- ndelay(400);
- ret = regmap_field_read(priv->rf[valid_idx], &valid);
+
+ if (!valid) {
+ timeout = jiffies + msecs_to_jiffies(20);
+
+ do {
+ /* Valid bit is 0 for 6 AHB clock cycles.
+ * At 19.2MHz, 1 AHB clock is ~60ns.
+ * We should enter this loop very, very rarely.
+ */
+ ndelay(400);
+ ret = regmap_field_read(priv->rf[valid_idx], &valid);
+ if (valid || ret)
+ break;
+ } while (!(ret = time_after_eq(jiffies, timeout)));
+
if (ret)
return ret;
}

View File

@ -1,167 +0,0 @@
From de1ca571d14bab031cc57bab5311db05f33ceec3 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 19 May 2021 00:14:50 +0200
Subject: [PATCH] arm64: dts: ipq8074: add thermal nodes
IPQ8074 has a tsens v2.3.0 peripheral which monitors
temperatures around the various subsystems on the
die.
So, lets add the required nodes for tsens and thermal
zones to enable passive cooling of the device.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 101 ++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-ipq8074.h>
#include <dt-bindings/clock/qca,apss-ipq8074.h>
+#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/spmi/spmi.h>
/ {
@@ -38,6 +39,7 @@
clock-names = "cpu";
next-level-cache = <&L2_0>;
enable-method = "psci";
+ #cooling-cells = <2>;
};
CPU1: cpu@1 {
@@ -48,6 +50,7 @@
clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
clock-names = "cpu";
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
};
CPU2: cpu@2 {
@@ -58,6 +61,7 @@
clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
clock-names = "cpu";
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
};
CPU3: cpu@3 {
@@ -68,6 +72,7 @@
clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
clock-names = "cpu";
next-level-cache = <&L2_0>;
+ #cooling-cells = <2>;
};
L2_0: l2-cache {
@@ -365,6 +370,16 @@
status = "disabled";
};
+ tsens: thermal-sensor@4a9000 {
+ compatible = "qcom,ipq8074-tsens";
+ reg = <0x4a9000 0x1000>, /* TM */
+ <0x4a8000 0x1000>; /* SROT */
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow";
+ #qcom,sensors = <16>;
+ #thermal-sensor-cells = <1>;
+ };
+
cryptobam: dma@704000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x00704000 0x20000>;
@@ -1284,4 +1299,90 @@
#clock-cells = <0>;
};
};
+
+ thermal-zones {
+ nss-top-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 4>;
+ };
+
+ nss0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 5>;
+ };
+
+ nss1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 6>;
+ };
+
+ wcss-phya0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 7>;
+ };
+
+ wcss-phya1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 8>;
+ };
+
+ cpu0_thermal: cpu0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 9>;
+ };
+
+ cpu1_thermal: cpu1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 10>;
+ };
+
+ cpu2_thermal: cpu2-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 11>;
+ };
+
+ cpu3_thermal: cpu3-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 12>;
+ };
+
+ cluster_thermal: cluster-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 13>;
+ };
+
+ wcss-phyb0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 14>;
+ };
+
+ wcss-phyb1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&tsens 15>;
+ };
+ };
};

View File

@ -1,27 +0,0 @@
From c58dea2220d978756a0f7e815bc13dbfa8c33ebc Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Wed, 26 May 2021 16:49:02 +0200
Subject: [PATCH] arm64: dts: ipq8074: disable USB phy by default
One of the QUSB USB PHY-s has been left enabled by
default, this is probably just a mistake as other
USB PHY-s are disabled by default.
It makes no sense to have it enabled by default as
not all board implement USB ports, so disable it.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -286,6 +286,7 @@
clock-names = "cfg_ahb", "ref";
resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+ status = "disabled";
};
qmp_pcie_phy0: phy@84000 {

View File

@ -1,41 +0,0 @@
From 9b2aee0e0fd786c6836d1472cd935186b746bc5e Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sun, 13 Jun 2021 12:10:42 +0200
Subject: [PATCH] arm64: dts: ipq8074: Add QUP6 I2C node
Add node to support the QUP6 I2C controller inside
of IPQ8074.
It is exactly the same as QUP2 and QUP3 controllers.
Some routers like Xiaomi AX9000 and Netgear RBK850
use this bus.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq8074.dtsi | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -634,6 +634,21 @@
status = "disabled";
};
+ blsp1_i2c6: i2c@78ba000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x078ba000 0x600>;
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+ <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>;
+ clock-names = "iface", "core";
+ clock-frequency = <100000>;
+ dmas = <&blsp_dma 23>, <&blsp_dma 22>;
+ dma-names = "rx", "tx";
+ status = "disabled";
+ };
+
qpic_bam: dma@7984000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x07984000 0x1a000>;

View File

@ -1,51 +0,0 @@
From a58b73b20db06f91025c5c847fcf2b53e341a6ff Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Mon, 14 Jun 2021 19:01:14 +0200
Subject: [PATCH] hwmon: Add SMSC EMC2301/2/3/5 fan controller driver
Add support for SMSC EMC2305, EMC2303, EMC2302, EMC2301 fan controller
chips.
The driver primary supports the EMC2305 chip which provides RPM-based
PWM control and monitoring for up to 5 fans.
According to the SMSC data sheets the EMC2303, EMC2302 and EMC2301 chips
have basically the same functionality and register layout, but support
less fans and (in case of EMC2302 and EMC2301) less possible I2C addresses.
The driver supports them, too.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/hwmon/Kconfig | 11 +++++++++++
drivers/hwmon/Makefile | 1 +
2 files changed, 12 insertions(+)
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1601,6 +1601,17 @@ config SENSORS_EMC2103
This driver can also be built as a module. If so, the module
will be called emc2103.
+config SENSORS_EMC2305
+ tristate "SMSC EMC2305"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the fan monitoring
+ and control features of the SMSC EMC2301/2/3/5 chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called emc2305.
+
config SENSORS_EMC6W201
tristate "SMSC EMC6W201"
depends on I2C
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_SENSORS_DS620) += ds620.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
+obj-$(CONFIG_SENSORS_EMC2305) += emc2305.o
obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o
obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o

View File

@ -1,60 +0,0 @@
From 7d94f8748116ebb9e81629d7c8dd5fe5f63648aa Mon Sep 17 00:00:00 2001
From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
Date: Sat, 26 Jun 2021 00:42:33 +0200
Subject: [PATCH] PCI: qcom: Do PHY power on before PCIe init
Commit cc1e06f033af ("phy: qcom: qmp: Use power_on/off ops for PCIe")
changed phy ops from init/deinit to power on/off, due to this phy enable
is getting called after PCIe init.
On some platforms like ipq8074 phy should be inited before accessing the
PCIe register space, otherwise the system would hang.
So move phy_power_on API before PCIe init.
Fixes: commit cc1e06f033af ("phy: qcom: qmp: Use power_on/off ops for PCIe")
Co-developed-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Signed-off-by: Selvam Sathappan Periakaruppan <speriaka@codeaurora.org>
Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
---
drivers/pci/controller/dwc/pcie-qcom.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1411,18 +1411,18 @@ static int qcom_pcie_host_init(struct pc
qcom_ep_reset_assert(pcie);
- ret = pcie->ops->init(pcie);
+ ret = phy_power_on(pcie->phy);
if (ret)
return ret;
- ret = phy_power_on(pcie->phy);
+ ret = pcie->ops->init(pcie);
if (ret)
- goto err_deinit;
+ goto err_disable_phy;
if (pcie->ops->post_init) {
ret = pcie->ops->post_init(pcie);
if (ret)
- goto err_disable_phy;
+ goto err_deinit;
}
dw_pcie_setup_rc(pp);
@@ -1430,10 +1430,10 @@ static int qcom_pcie_host_init(struct pc
return 0;
-err_disable_phy:
- phy_power_off(pcie->phy);
err_deinit:
pcie->ops->deinit(pcie);
+err_disable_phy:
+ phy_power_off(pcie->phy);
return ret;
}

View File

@ -1,39 +0,0 @@
From 26becdb00a29d53a23fd06e67e9750d167fe982d Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 26 Jun 2021 00:51:32 +0200
Subject: [PATCH] PCI: qcom: Make sure PCI is reset and clocks are enabled
before init for IP 2.3.3
IPQ8074 which uses IP 2.3.3 requires that the PHY is
powered on, resets are asserted as bootloader can
leave them in a weird state and clocks are enabled
before accessing the register space.
Otherwise the system would simply hang on a DBI read.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1035,7 +1035,7 @@ static int qcom_pcie_init_2_3_3(struct q
struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
- u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+ u16 offset;
int i, ret;
u32 val;
@@ -1111,6 +1111,9 @@ static int qcom_pcie_init_2_3_3(struct q
writel(PCI_COMMAND_MASTER, pci->dbi_base + PCI_COMMAND);
writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG);
+
+ offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+
writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);

View File

@ -1,722 +0,0 @@
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -32,20 +32,14 @@
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
/* Do not check the TCP window for incoming packets */
-static int nf_ct_tcp_no_window_check __read_mostly = 1;
-
-#ifdef CONFIG_SHORTCUT_FE
+int nf_ct_tcp_no_window_check __read_mostly = 1;
EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
-#endif
/* "Be conservative in what you do,
be liberal in what you accept from others."
If it's non-zero, we mark only out of window RST segments as INVALID. */
-static int nf_ct_tcp_be_liberal __read_mostly = 0;
-
-#ifdef CONFIG_SHORTCUT_FE
+int nf_ct_tcp_be_liberal __read_mostly = 0;
EXPORT_SYMBOL_GPL(nf_ct_tcp_be_liberal);
-#endif
/* If it is set to zero, we disable picking up already established
connections. */
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -64,6 +64,7 @@ extern void brioctl_set(int (*ioctl_hook
extern void br_dev_update_stats(struct net_device *dev,
struct rtnl_link_stats64 *nlstats);
+extern bool br_is_hairpin_enabled(struct net_device *dev);
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
int br_multicast_list_adjacent(struct net_device *dev,
@@ -159,4 +160,41 @@ br_port_flag_is_set(const struct net_dev
}
#endif
+/* QCA NSS ECM support - Start */
+extern struct net_device *br_port_dev_get(struct net_device *dev,
+ unsigned char *addr,
+ struct sk_buff *skb,
+ unsigned int cookie);
+extern void br_refresh_fdb_entry(struct net_device *dev, const char *addr);
+extern struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev,
+ const char *addr,
+ __u16 vid);
+extern void br_fdb_update_register_notify(struct notifier_block *nb);
+extern void br_fdb_update_unregister_notify(struct notifier_block *nb);
+
+typedef struct net_bridge_port *br_port_dev_get_hook_t(struct net_device *dev,
+ struct sk_buff *skb,
+ unsigned char *addr,
+ unsigned int cookie);
+extern br_port_dev_get_hook_t __rcu *br_port_dev_get_hook;
+
+#define BR_FDB_EVENT_ADD 0x01
+#define BR_FDB_EVENT_DEL 0x02
+
+struct br_fdb_event {
+ struct net_device *dev;
+ unsigned char addr[6];
+ unsigned char is_local;
+ struct net_bridge *br;
+ struct net_device *orig_dev;
+};
+extern void br_fdb_register_notify(struct notifier_block *nb);
+extern void br_fdb_unregister_notify(struct notifier_block *nb);
+
+typedef struct net_bridge_port *br_get_dst_hook_t(
+ const struct net_bridge_port *src,
+ struct sk_buff **skb);
+extern br_get_dst_hook_t __rcu *br_get_dst_hook;
+/* QCA NSS ECM support - End */
+
#endif
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -222,7 +222,28 @@ extern void vlan_vids_del_by_dev(struct
extern bool vlan_uses_dev(const struct net_device *dev);
+/* QCA NSS ECM support - Start */
+extern void __vlan_dev_update_accel_stats(struct net_device *dev,
+ struct rtnl_link_stats64 *stats);
+extern u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio);
+extern struct net_device *vlan_dev_next_dev(const struct net_device *dev);
+/* QCA NSS ECM support - End */
+
#else
+/* QCA NSS ECM support - Start */
+static inline void __vlan_dev_update_accel_stats(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+
+}
+
+static inline u16 vlan_dev_get_egress_prio(struct net_device *dev,
+ u32 skb_prio)
+{
+ return 0;
+}
+/* QCA NSS ECM support - End */
+
static inline struct net_device *
__vlan_find_dev_deep_rcu(struct net_device *real_dev,
__be16 vlan_proto, u16 vlan_id)
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2745,6 +2745,10 @@ enum netdev_cmd {
NETDEV_CVLAN_FILTER_DROP_INFO,
NETDEV_SVLAN_FILTER_PUSH_INFO,
NETDEV_SVLAN_FILTER_DROP_INFO,
+ /* QCA NSS ECM Support - Start */
+ NETDEV_BR_JOIN,
+ NETDEV_BR_LEAVE,
+ /* QCA NSS ECM Support - End */
};
const char *netdev_cmd_to_name(enum netdev_cmd cmd);
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -210,6 +210,11 @@ void rt6_multipath_rebalance(struct fib6
void rt6_uncached_list_add(struct rt6_info *rt);
void rt6_uncached_list_del(struct rt6_info *rt);
+/* QCA NSS ECM support - Start */
+int rt6_register_notifier(struct notifier_block *nb);
+int rt6_unregister_notifier(struct notifier_block *nb);
+/* QCA NSS ECM support - End */
+
static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb)
{
const struct dst_entry *dst = skb_dst(skb);
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -574,4 +574,15 @@ static inline void neigh_update_is_route
*notify = 1;
}
}
+
+/* QCA NSS ECM support - Start */
+struct neigh_mac_update {
+ unsigned char old_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
+ unsigned char update_mac[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
+};
+
+extern void neigh_mac_update_register_notify(struct notifier_block *nb);
+extern void neigh_mac_update_unregister_notify(struct notifier_block *nb);
+/* QCA NSS ECM support - End */
+
#endif
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -234,6 +234,11 @@ struct rtable *rt_dst_alloc(struct net_d
bool nopolicy, bool noxfrm);
struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt);
+/* QCA NSS ECM support - Start */
+int ip_rt_register_notifier(struct notifier_block *nb);
+int ip_rt_unregister_notifier(struct notifier_block *nb);
+/* QCA NSS ECM support - End */
+
struct in_ifaddr;
void fib_add_ifaddr(struct in_ifaddr *);
void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *);
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -550,4 +550,52 @@ static int __init vlan_offload_init(void
return 0;
}
+/* QCA NSS ECM support - Start */
+/* Update the VLAN device with statistics from network offload engines */
+void __vlan_dev_update_accel_stats(struct net_device *dev,
+ struct rtnl_link_stats64 *nlstats)
+{
+ struct vlan_pcpu_stats *stats;
+
+ if (!is_vlan_dev(dev))
+ return;
+
+ stats = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, 0);
+
+ u64_stats_update_begin(&stats->syncp);
+ stats->rx_packets += nlstats->rx_packets;
+ stats->rx_bytes += nlstats->rx_bytes;
+ stats->tx_packets += nlstats->tx_packets;
+ stats->tx_bytes += nlstats->tx_bytes;
+ u64_stats_update_end(&stats->syncp);
+}
+EXPORT_SYMBOL(__vlan_dev_update_accel_stats);
+
+/* Lookup the 802.1p egress_map table and return the 802.1p value */
+u16 vlan_dev_get_egress_prio(struct net_device *dev, u32 skb_prio)
+{
+ struct vlan_priority_tci_mapping *mp;
+
+ mp = vlan_dev_priv(dev)->egress_priority_map[(skb_prio & 0xf)];
+ while (mp) {
+ if (mp->priority == skb_prio) {
+ /* This should already be shifted
+ * to mask correctly with the
+ * VLAN's TCI
+ */
+ return mp->vlan_qos;
+ }
+ mp = mp->next;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(vlan_dev_get_egress_prio);
+
+struct net_device *vlan_dev_next_dev(const struct net_device *dev)
+{
+ return vlan_dev_priv(dev)->real_dev;
+}
+EXPORT_SYMBOL(vlan_dev_next_dev);
+/* QCA NSS ECM support - End */
+
fs_initcall(vlan_offload_init);
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -37,6 +37,35 @@ static int fdb_insert(struct net_bridge
static void fdb_notify(struct net_bridge *br,
const struct net_bridge_fdb_entry *, int, bool);
+/* QCA NSS ECM support - Start */
+ATOMIC_NOTIFIER_HEAD(br_fdb_notifier_list);
+ATOMIC_NOTIFIER_HEAD(br_fdb_update_notifier_list);
+
+void br_fdb_register_notify(struct notifier_block *nb)
+{
+ atomic_notifier_chain_register(&br_fdb_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(br_fdb_register_notify);
+
+void br_fdb_unregister_notify(struct notifier_block *nb)
+{
+ atomic_notifier_chain_unregister(&br_fdb_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(br_fdb_unregister_notify);
+
+void br_fdb_update_register_notify(struct notifier_block *nb)
+{
+ atomic_notifier_chain_register(&br_fdb_update_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(br_fdb_update_register_notify);
+
+void br_fdb_update_unregister_notify(struct notifier_block *nb)
+{
+ atomic_notifier_chain_unregister(&br_fdb_update_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify);
+/* QCA NSS ECM support - End */
+
int __init br_fdb_init(void)
{
br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
@@ -342,6 +371,7 @@ void br_fdb_cleanup(struct work_struct *
unsigned long delay = hold_time(br);
unsigned long work_delay = delay;
unsigned long now = jiffies;
+ u8 mac_addr[6]; /* QCA NSS ECM support */
/* this part is tricky, in order to avoid blocking learning and
* consequently forwarding, we rely on rcu to delete objects with
@@ -368,8 +398,15 @@ void br_fdb_cleanup(struct work_struct *
work_delay = min(work_delay, this_timer - now);
} else {
spin_lock_bh(&br->hash_lock);
- if (!hlist_unhashed(&f->fdb_node))
+ if (!hlist_unhashed(&f->fdb_node)) {
+ ether_addr_copy(mac_addr, f->key.addr.addr);
fdb_delete(br, f, true);
+ /* QCA NSS ECM support - Start */
+ atomic_notifier_call_chain(
+ &br_fdb_update_notifier_list, 0,
+ (void *)mac_addr);
+ /* QCA NSS ECM support - End */
+ }
spin_unlock_bh(&br->hash_lock);
}
}
@@ -610,6 +647,12 @@ void br_fdb_update(struct net_bridge *br
&fdb->flags)))
clear_bit(BR_FDB_ADDED_BY_EXT_LEARN,
&fdb->flags);
+
+ /* QCA NSS ECM support - Start */
+ atomic_notifier_call_chain(
+ &br_fdb_update_notifier_list,
+ 0, (void *)addr);
+ /* QCA NSS ECM support - End */
}
if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags)))
@@ -734,6 +777,25 @@ static void fdb_notify(struct net_bridge
struct sk_buff *skb;
int err = -ENOBUFS;
+ /* QCA NSS ECM support - Start */
+ if (fdb->dst) {
+ int event;
+ struct br_fdb_event fdb_event;
+
+ if (type == RTM_NEWNEIGH)
+ event = BR_FDB_EVENT_ADD;
+ else
+ event = BR_FDB_EVENT_DEL;
+
+ fdb_event.dev = fdb->dst->dev;
+ ether_addr_copy(fdb_event.addr, fdb->key.addr.addr);
+ fdb_event.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags);
+ atomic_notifier_call_chain(&br_fdb_notifier_list,
+ event,
+ (void *)&fdb_event);
+ }
+ /* QCA NSS ECM support - End */
+
if (swdev_notify)
br_switchdev_fdb_notify(br, fdb, type);
@@ -1317,3 +1379,44 @@ void br_fdb_clear_offload(const struct n
spin_unlock_bh(&p->br->hash_lock);
}
EXPORT_SYMBOL_GPL(br_fdb_clear_offload);
+
+/* QCA NSS ECM support - Start */
+/* Refresh FDB entries for bridge packets being forwarded by offload engines */
+void br_refresh_fdb_entry(struct net_device *dev, const char *addr)
+{
+ struct net_bridge_port *p = br_port_get_rcu(dev);
+
+ if (!p || p->state == BR_STATE_DISABLED)
+ return;
+
+ if (!is_valid_ether_addr(addr)) {
+ pr_info("bridge: Attempt to refresh with invalid ether address %pM\n",
+ addr);
+ return;
+ }
+
+ rcu_read_lock();
+ br_fdb_update(p->br, p, addr, 0, true);
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(br_refresh_fdb_entry);
+
+/* Look up the MAC address in the device's bridge fdb table */
+struct net_bridge_fdb_entry *br_fdb_has_entry(struct net_device *dev,
+ const char *addr, __u16 vid)
+{
+ struct net_bridge_port *p = br_port_get_rcu(dev);
+ struct net_bridge_fdb_entry *fdb;
+
+ if (!p || p->state == BR_STATE_DISABLED)
+ return NULL;
+
+ rcu_read_lock();
+ fdb = fdb_find_rcu(&p->br->fdb_hash_tbl, addr, vid);
+ rcu_read_unlock();
+
+ return fdb;
+}
+EXPORT_SYMBOL_GPL(br_fdb_has_entry);
+/* QCA NSS ECM support - End */
+
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -26,6 +26,12 @@
#include "br_private.h"
+/* QCA NSS ECM support - Start */
+/* Hook for external forwarding logic */
+br_port_dev_get_hook_t __rcu *br_port_dev_get_hook __read_mostly;
+EXPORT_SYMBOL_GPL(br_port_dev_get_hook);
+/* QCA NSS ECM support - End */
+
/*
* Determine initial path cost based on speed.
* using recommendations from 802.1d standard
@@ -711,6 +717,8 @@ int br_add_if(struct net_bridge *br, str
kobject_uevent(&p->kobj, KOBJ_ADD);
+ call_netdevice_notifiers(NETDEV_BR_JOIN, dev); /* QCA NSS ECM support */
+
return 0;
err7:
@@ -747,6 +755,8 @@ int br_del_if(struct net_bridge *br, str
if (!p || p->br != br)
return -EINVAL;
+ call_netdevice_notifiers(NETDEV_BR_LEAVE, dev); /* QCA NSS ECM support */
+
/* Since more than one interface can be attached to a bridge,
* there still maybe an alternate path for netconsole to use;
* therefore there is no reason for a NETDEV_RELEASE event.
@@ -812,3 +822,74 @@ bool br_port_flag_is_set(const struct ne
return p->flags & flag;
}
EXPORT_SYMBOL_GPL(br_port_flag_is_set);
+
+/* API to know if hairpin feature is enabled/disabled on this bridge port */
+bool br_is_hairpin_enabled(struct net_device *dev)
+{
+ struct net_bridge_port *port = br_port_get_check_rcu(dev);
+
+ if (likely(port))
+ return port->flags & BR_HAIRPIN_MODE;
+ return false;
+}
+EXPORT_SYMBOL_GPL(br_is_hairpin_enabled);
+
+/* br_port_dev_get()
+ * If a skb is provided, and the br_port_dev_get_hook_t hook exists,
+ * use that to try and determine the egress port for that skb.
+ * If not, or no egress port could be determined, use the given addr
+ * to identify the port to which it is reachable,
+ * returing a reference to the net device associated with that port.
+ *
+ * NOTE: Return NULL if given dev is not a bridge or the mac has no
+ * associated port.
+ */
+struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr,
+ struct sk_buff *skb,
+ unsigned int cookie)
+{
+ struct net_bridge_fdb_entry *fdbe;
+ struct net_bridge *br;
+ struct net_device *netdev = NULL;
+
+ /* Is this a bridge? */
+ if (!(dev->priv_flags & IFF_EBRIDGE))
+ return NULL;
+
+ rcu_read_lock();
+
+ /* If the hook exists and the skb isn't NULL, try and get the port */
+ if (skb) {
+ br_port_dev_get_hook_t *port_dev_get_hook;
+
+ port_dev_get_hook = rcu_dereference(br_port_dev_get_hook);
+ if (port_dev_get_hook) {
+ struct net_bridge_port *pdst =
+ __br_get(port_dev_get_hook, NULL, dev, skb,
+ addr, cookie);
+ if (pdst) {
+ dev_hold(pdst->dev);
+ netdev = pdst->dev;
+ goto out;
+ }
+ }
+ }
+
+ /* Either there is no hook, or can't
+ * determine the port to use - fall back to using FDB
+ */
+
+ br = netdev_priv(dev);
+
+ /* Lookup the fdb entry and get reference to the port dev */
+ fdbe = br_fdb_find_rcu(br, addr, 0);
+ if (fdbe && fdbe->dst) {
+ netdev = fdbe->dst->dev; /* port device */
+ dev_hold(netdev);
+ }
+out:
+ rcu_read_unlock();
+ return netdev;
+}
+EXPORT_SYMBOL_GPL(br_port_dev_get);
+/* QCA NSS ECM support - End */
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1591,4 +1591,9 @@ void br_do_proxy_suppress_arp(struct sk_
void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
u16 vid, struct net_bridge_port *p, struct nd_msg *msg);
struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m);
+
+/* QCA NSS ECM support - Start */
+#define __br_get(__hook, __default, __args ...) \
+ (__hook ? (__hook(__args)) : (__default))
+/* QCA NSS ECM support - End */
#endif
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1209,7 +1209,21 @@ static void neigh_update_hhs(struct neig
}
}
+/* QCA NSS ECM support - start */
+ATOMIC_NOTIFIER_HEAD(neigh_mac_update_notifier_list);
+
+void neigh_mac_update_register_notify(struct notifier_block *nb)
+{
+ atomic_notifier_chain_register(&neigh_mac_update_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(neigh_mac_update_register_notify);
+void neigh_mac_update_unregister_notify(struct notifier_block *nb)
+{
+ atomic_notifier_chain_unregister(&neigh_mac_update_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(neigh_mac_update_unregister_notify);
+/* QCA NSS ECM support - End */
/* Generic update routine.
-- lladdr is new lladdr or NULL, if it is not supplied.
@@ -1240,6 +1254,7 @@ static int __neigh_update(struct neighbo
int notify = 0;
struct net_device *dev;
int update_isrouter = 0;
+ struct neigh_mac_update nmu; /* QCA NSS ECM support */
trace_neigh_update(neigh, lladdr, new, flags, nlmsg_pid);
@@ -1254,6 +1269,8 @@ static int __neigh_update(struct neighbo
new = old;
goto out;
}
+ memset(&nmu, 0, sizeof(struct neigh_mac_update)); /* QCA NSS ECM support */
+
if (!(flags & NEIGH_UPDATE_F_ADMIN) &&
(old & (NUD_NOARP | NUD_PERMANENT)))
goto out;
@@ -1291,6 +1308,11 @@ static int __neigh_update(struct neighbo
- compare new & old
- if they are different, check override flag
*/
+ /* QCA NSS ECM update - Start */
+ memcpy(nmu.old_mac, neigh->ha, dev->addr_len);
+ memcpy(nmu.update_mac, lladdr, dev->addr_len);
+ /* QCA NSS ECM update - End */
+
if ((old & NUD_VALID) &&
!memcmp(lladdr, neigh->ha, dev->addr_len))
lladdr = neigh->ha;
@@ -1413,8 +1435,11 @@ out:
if (((new ^ old) & NUD_PERMANENT) || ext_learn_change)
neigh_update_gc_list(neigh);
- if (notify)
+ if (notify) {
neigh_update_notify(neigh, nlmsg_pid);
+ atomic_notifier_call_chain(&neigh_mac_update_notifier_list, 0,
+ (struct neigh_mac_update *)&nmu); /* QCA NSS ECM support */
+ }
trace_neigh_update_done(neigh, err);
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1164,6 +1164,9 @@ static bool fib_valid_key_len(u32 key, u
static void fib_remove_alias(struct trie *t, struct key_vector *tp,
struct key_vector *l, struct fib_alias *old);
+/* Define route change notification chain. */
+static BLOCKING_NOTIFIER_HEAD(iproute_chain); /* QCA NSS ECM support */
+
/* Caller must hold RTNL. */
int fib_table_insert(struct net *net, struct fib_table *tb,
struct fib_config *cfg, struct netlink_ext_ack *extack)
@@ -1352,6 +1355,9 @@ int fib_table_insert(struct net *net, st
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, new_fa->tb_id,
&cfg->fc_nlinfo, nlflags);
succeeded:
+ blocking_notifier_call_chain(&iproute_chain,
+ RTM_NEWROUTE, fi);
+
return 0;
out_remove_new_fa:
@@ -1722,6 +1728,9 @@ int fib_table_delete(struct net *net, st
if (fa_to_delete->fa_state & FA_S_ACCESSED)
rt_cache_flush(cfg->fc_nlinfo.nl_net);
+ blocking_notifier_call_chain(&iproute_chain,
+ RTM_DELROUTE, fa_to_delete->fa_info);
+
fib_release_info(fa_to_delete->fa_info);
alias_free_mem_rcu(fa_to_delete);
return 0;
@@ -2358,6 +2367,20 @@ void __init fib_trie_init(void)
0, SLAB_PANIC, NULL);
}
+/* QCA NSS ECM support - Start */
+int ip_rt_register_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&iproute_chain, nb);
+}
+EXPORT_SYMBOL(ip_rt_register_notifier);
+
+int ip_rt_unregister_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&iproute_chain, nb);
+}
+EXPORT_SYMBOL(ip_rt_unregister_notifier);
+/* QCA NSS ECM support - End */
+
struct fib_table *fib_trie_table(u32 id, struct fib_table *alias)
{
struct fib_table *tb;
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -501,4 +501,9 @@ int if6_proc_init(void);
void if6_proc_exit(void);
#endif
+/* QCA NSS ECM support - Start */
+struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr,
+ int strict);
+/* QCA NSS ECM support - End */
+
#endif
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -7236,3 +7236,35 @@ void addrconf_cleanup(void)
destroy_workqueue(addrconf_wq);
}
+
+/* QCA NSS ECM support - Start */
+/* ipv6_dev_find_and_hold()
+ * Find (and hold) net device that has the given address.
+ * Or NULL on failure.
+ */
+struct net_device *ipv6_dev_find_and_hold(struct net *net, struct in6_addr *addr,
+ int strict)
+{
+ struct inet6_ifaddr *ifp;
+ struct net_device *dev;
+
+ ifp = ipv6_get_ifaddr(net, addr, NULL, strict);
+ if (!ifp)
+ return NULL;
+
+ if (!ifp->idev) {
+ in6_ifa_put(ifp);
+ return NULL;
+ }
+
+ dev = ifp->idev->dev;
+ if (dev)
+ dev_hold(dev);
+
+ in6_ifa_put(ifp);
+
+ return dev;
+}
+EXPORT_SYMBOL(ipv6_dev_find_and_hold);
+/* QCA NSS ECM support - End */
+
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -649,6 +649,7 @@ void ndisc_send_ns(struct net_device *de
ndisc_send_skb(skb, daddr, saddr);
}
+EXPORT_SYMBOL(ndisc_send_ns);
void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
const struct in6_addr *daddr)
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3767,6 +3767,9 @@ out_free:
return ERR_PTR(err);
}
+/* Define route change notification chain. */
+ATOMIC_NOTIFIER_HEAD(ip6route_chain); /* QCA NSS ECM support */
+
int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags,
struct netlink_ext_ack *extack)
{
@@ -3778,6 +3781,10 @@ int ip6_route_add(struct fib6_config *cf
return PTR_ERR(rt);
err = __ip6_ins_rt(rt, &cfg->fc_nlinfo, extack);
+ if (!err)
+ atomic_notifier_call_chain(&ip6route_chain,
+ RTM_NEWROUTE, rt);
+
fib6_info_release(rt);
return err;
@@ -3799,6 +3806,9 @@ static int __ip6_del_rt(struct fib6_info
err = fib6_del(rt, info);
spin_unlock_bh(&table->tb6_lock);
+ if (!err)
+ atomic_notifier_call_chain(&ip6route_chain,
+ RTM_DELROUTE, rt);
out:
fib6_info_release(rt);
return err;
@@ -6151,6 +6161,20 @@ static int ip6_route_dev_notify(struct n
return NOTIFY_OK;
}
+/* QCA NSS ECM support - Start */
+int rt6_register_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&ip6route_chain, nb);
+}
+EXPORT_SYMBOL(rt6_register_notifier);
+
+int rt6_unregister_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&ip6route_chain, nb);
+}
+EXPORT_SYMBOL(rt6_unregister_notifier);
+/* QCA NSS ECM support - End */
+
/*
* /proc
*/

View File

@ -1,588 +0,0 @@
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -48,6 +48,7 @@
#include <net/slhc_vj.h>
#include <linux/atomic.h>
#include <linux/refcount.h>
+#include <linux/if_pppox.h>
#include <linux/nsproxy.h>
#include <net/net_namespace.h>
@@ -250,6 +251,25 @@ struct ppp_net {
#define seq_before(a, b) ((s32)((a) - (b)) < 0)
#define seq_after(a, b) ((s32)((a) - (b)) > 0)
+
+/*
+ * Registration/Unregistration methods
+ * for PPP channel connect and disconnect event notifications.
+ */
+RAW_NOTIFIER_HEAD(ppp_channel_connection_notifier_list);
+
+void ppp_channel_connection_register_notify(struct notifier_block *nb)
+{
+ raw_notifier_chain_register(&ppp_channel_connection_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(ppp_channel_connection_register_notify);
+
+void ppp_channel_connection_unregister_notify(struct notifier_block *nb)
+{
+ raw_notifier_chain_unregister(&ppp_channel_connection_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(ppp_channel_connection_unregister_notify);
+
/* Prototypes. */
static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
struct file *file, unsigned int cmd, unsigned long arg);
@@ -3294,7 +3314,10 @@ ppp_connect_channel(struct channel *pch,
struct ppp_net *pn;
int ret = -ENXIO;
int hdrlen;
+ int ppp_proto;
+ int version;
+ int notify = 0;
pn = ppp_pernet(pch->chan_net);
mutex_lock(&pn->all_ppp_mutex);
@@ -3325,13 +3348,40 @@ ppp_connect_channel(struct channel *pch,
++ppp->n_channels;
pch->ppp = ppp;
refcount_inc(&ppp->file.refcnt);
+
+ /* Set the netdev priv flag if the prototype
+ * is L2TP or PPTP. Return success in all cases
+ */
+ if (!pch->chan)
+ goto out2;
+
+ ppp_proto = ppp_channel_get_protocol(pch->chan);
+ if (ppp_proto == PX_PROTO_PPTP) {
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_PPTP;
+ } else if (ppp_proto == PX_PROTO_OL2TP) {
+ version = ppp_channel_get_proto_version(pch->chan);
+ if (version == 2)
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV2;
+ else if (version == 3)
+ ppp->dev->priv_flags_ext |= IFF_EXT_PPP_L2TPV3;
+ }
+ notify = 1;
+
+ out2:
ppp_unlock(ppp);
ret = 0;
-
outl:
write_unlock_bh(&pch->upl);
out:
mutex_unlock(&pn->all_ppp_mutex);
+
+ if (notify && ppp && ppp->dev) {
+ dev_hold(ppp->dev);
+ raw_notifier_call_chain(&ppp_channel_connection_notifier_list,
+ PPP_CHANNEL_CONNECT, ppp->dev);
+ dev_put(ppp->dev);
+ }
+
return ret;
}
@@ -3349,6 +3399,13 @@ ppp_disconnect_channel(struct channel *p
pch->ppp = NULL;
write_unlock_bh(&pch->upl);
if (ppp) {
+ if (ppp->dev) {
+ dev_hold(ppp->dev);
+ raw_notifier_call_chain(&ppp_channel_connection_notifier_list,
+ PPP_CHANNEL_DISCONNECT, ppp->dev);
+ dev_put(ppp->dev);
+ }
+
/* remove it from the ppp unit's list */
ppp_lock(ppp);
list_del(&pch->clist);
@@ -3428,6 +3485,222 @@ static void *unit_find(struct idr *p, in
return idr_find(p, n);
}
+/* Updates the PPP interface statistics. */
+void ppp_update_stats(struct net_device *dev, unsigned long rx_packets,
+ unsigned long rx_bytes, unsigned long tx_packets,
+ unsigned long tx_bytes, unsigned long rx_errors,
+ unsigned long tx_errors, unsigned long rx_dropped,
+ unsigned long tx_dropped)
+{
+ struct ppp *ppp;
+
+ if (!dev)
+ return;
+
+ if (dev->type != ARPHRD_PPP)
+ return;
+
+ ppp = netdev_priv(dev);
+
+ ppp_xmit_lock(ppp);
+ ppp->stats64.tx_packets += tx_packets;
+ ppp->stats64.tx_bytes += tx_bytes;
+ ppp->dev->stats.tx_errors += tx_errors;
+ ppp->dev->stats.tx_dropped += tx_dropped;
+ if (tx_packets)
+ ppp->last_xmit = jiffies;
+ ppp_xmit_unlock(ppp);
+
+ ppp_recv_lock(ppp);
+ ppp->stats64.rx_packets += rx_packets;
+ ppp->stats64.rx_bytes += rx_bytes;
+ ppp->dev->stats.rx_errors += rx_errors;
+ ppp->dev->stats.rx_dropped += rx_dropped;
+ if (rx_packets)
+ ppp->last_recv = jiffies;
+ ppp_recv_unlock(ppp);
+}
+
+/* Returns >0 if the device is a multilink PPP netdevice, 0 if not or < 0 if
+ * the device is not PPP.
+ */
+int ppp_is_multilink(struct net_device *dev)
+{
+ struct ppp *ppp;
+ unsigned int flags;
+
+ if (!dev)
+ return -1;
+
+ if (dev->type != ARPHRD_PPP)
+ return -1;
+
+ ppp = netdev_priv(dev);
+ ppp_lock(ppp);
+ flags = ppp->flags;
+ ppp_unlock(ppp);
+
+ if (flags & SC_MULTILINK)
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(ppp_is_multilink);
+
+/* ppp_channel_get_protocol()
+ * Call this to obtain the underlying protocol of the PPP channel,
+ * e.g. PX_PROTO_OE
+ *
+ * NOTE: Some channels do not use PX sockets so the protocol value may be very
+ * different for them.
+ * NOTE: -1 indicates failure.
+ * NOTE: Once you know the channel protocol you may then either cast 'chan' to
+ * its sub-class or use the channel protocol specific API's as provided by that
+ * channel sub type.
+ */
+int ppp_channel_get_protocol(struct ppp_channel *chan)
+{
+ if (!chan->ops->get_channel_protocol)
+ return -1;
+
+ return chan->ops->get_channel_protocol(chan);
+}
+EXPORT_SYMBOL(ppp_channel_get_protocol);
+
+/* ppp_channel_get_proto_version()
+ * Call this to get channel protocol version
+ */
+int ppp_channel_get_proto_version(struct ppp_channel *chan)
+{
+ if (!chan->ops->get_channel_protocol_ver)
+ return -1;
+
+ return chan->ops->get_channel_protocol_ver(chan);
+}
+EXPORT_SYMBOL(ppp_channel_get_proto_version);
+
+/* ppp_channel_hold()
+ * Call this to hold a channel.
+ *
+ * Returns true on success or false if the hold could not happen.
+ *
+ * NOTE: chan must be protected against destruction during this call -
+ * either by correct locking etc. or because you already have an implicit
+ * or explicit hold to the channel already and this is an additional hold.
+ */
+bool ppp_channel_hold(struct ppp_channel *chan)
+{
+ if (!chan->ops->hold)
+ return false;
+
+ chan->ops->hold(chan);
+ return true;
+}
+EXPORT_SYMBOL(ppp_channel_hold);
+
+/* ppp_channel_release()
+ * Call this to release a hold you have upon a channel
+ */
+void ppp_channel_release(struct ppp_channel *chan)
+{
+ chan->ops->release(chan);
+}
+EXPORT_SYMBOL(ppp_channel_release);
+
+/* Check if ppp xmit lock is on hold */
+bool ppp_is_xmit_locked(struct net_device *dev)
+{
+ struct ppp *ppp;
+
+ if (!dev)
+ return false;
+
+ if (dev->type != ARPHRD_PPP)
+ return false;
+
+ ppp = netdev_priv(dev);
+ if (!ppp)
+ return false;
+
+ if (spin_is_locked(&(ppp)->wlock))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(ppp_is_xmit_locked);
+
+/* ppp_hold_channels()
+ * Returns the PPP channels of the PPP device, storing each one into
+ * channels[].
+ *
+ * channels[] has chan_sz elements.
+ * This function returns the number of channels stored, up to chan_sz.
+ * It will return < 0 if the device is not PPP.
+ *
+ * You MUST release the channels using ppp_release_channels().
+ */
+int ppp_hold_channels(struct net_device *dev, struct ppp_channel *channels[],
+ unsigned int chan_sz)
+{
+ struct ppp *ppp;
+ int c;
+ struct channel *pch;
+
+ if (!dev)
+ return -1;
+
+ if (dev->type != ARPHRD_PPP)
+ return -1;
+
+ ppp = netdev_priv(dev);
+
+ c = 0;
+ ppp_lock(ppp);
+ list_for_each_entry(pch, &ppp->channels, clist) {
+ struct ppp_channel *chan;
+
+ if (!pch->chan) {
+ /* Channel is going / gone away */
+ continue;
+ }
+
+ if (c == chan_sz) {
+ /* No space to record channel */
+ ppp_unlock(ppp);
+ return c;
+ }
+
+ /* Hold the channel, if supported */
+ chan = pch->chan;
+ if (!chan->ops->hold)
+ continue;
+
+ chan->ops->hold(chan);
+
+ /* Record the channel */
+ channels[c++] = chan;
+ }
+ ppp_unlock(ppp);
+ return c;
+}
+EXPORT_SYMBOL(ppp_hold_channels);
+
+/* ppp_release_channels()
+ * Releases channels
+ */
+void ppp_release_channels(struct ppp_channel *channels[], unsigned int chan_sz)
+{
+ unsigned int c;
+
+ for (c = 0; c < chan_sz; ++c) {
+ struct ppp_channel *chan;
+
+ chan = channels[c];
+ chan->ops->release(chan);
+ }
+}
+EXPORT_SYMBOL(ppp_release_channels);
+
/* Module/initialization stuff */
module_init(ppp_init);
@@ -3444,6 +3717,7 @@ EXPORT_SYMBOL(ppp_input_error);
EXPORT_SYMBOL(ppp_output_wakeup);
EXPORT_SYMBOL(ppp_register_compressor);
EXPORT_SYMBOL(ppp_unregister_compressor);
+EXPORT_SYMBOL(ppp_update_stats);
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0);
MODULE_ALIAS_RTNL_LINK("ppp");
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -62,6 +62,7 @@
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/if_arp.h>
#include <linux/init.h>
#include <linux/if_ether.h>
#include <linux/if_pppox.h>
@@ -87,7 +88,7 @@
static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
static const struct proto_ops pppoe_ops;
-static const struct ppp_channel_ops pppoe_chan_ops;
+static const struct pppoe_channel_ops pppoe_chan_ops;
/* per-net private data for this module */
static unsigned int pppoe_net_id __read_mostly;
@@ -692,7 +693,7 @@ static int pppoe_connect(struct socket *
po->chan.mtu = dev->mtu - sizeof(struct pppoe_hdr) - 2;
po->chan.private = sk;
- po->chan.ops = &pppoe_chan_ops;
+ po->chan.ops = (struct ppp_channel_ops *)&pppoe_chan_ops;
error = ppp_register_net_channel(dev_net(dev), &po->chan);
if (error) {
@@ -994,9 +995,80 @@ static int pppoe_fill_forward_path(struc
return 0;
}
-static const struct ppp_channel_ops pppoe_chan_ops = {
- .start_xmit = pppoe_xmit,
- .fill_forward_path = pppoe_fill_forward_path,
+/************************************************************************
+ *
+ * function called by generic PPP driver to hold channel
+ *
+ ***********************************************************************/
+static void pppoe_hold_chan(struct ppp_channel *chan)
+{
+ struct sock *sk = (struct sock *)chan->private;
+
+ sock_hold(sk);
+}
+
+/************************************************************************
+ *
+ * function called by generic PPP driver to release channel
+ *
+ ***********************************************************************/
+static void pppoe_release_chan(struct ppp_channel *chan)
+{
+ struct sock *sk = (struct sock *)chan->private;
+
+ sock_put(sk);
+}
+
+/************************************************************************
+ *
+ * function called to get the channel protocol type
+ *
+ ***********************************************************************/
+static int pppoe_get_channel_protocol(struct ppp_channel *chan)
+{
+ return PX_PROTO_OE;
+}
+
+/************************************************************************
+ *
+ * function called to get the PPPoE channel addressing
+ * NOTE: This function returns a HOLD to the netdevice
+ *
+ ***********************************************************************/
+static int pppoe_get_addressing(struct ppp_channel *chan,
+ struct pppoe_opt *addressing)
+{
+ struct sock *sk = (struct sock *)chan->private;
+ struct pppox_sock *po = pppox_sk(sk);
+ int err = 0;
+
+ *addressing = po->proto.pppoe;
+ if (!addressing->dev)
+ return -ENODEV;
+
+ dev_hold(addressing->dev);
+ return err;
+}
+
+/* pppoe_channel_addressing_get()
+ * Return PPPoE channel specific addressing information.
+ */
+int pppoe_channel_addressing_get(struct ppp_channel *chan,
+ struct pppoe_opt *addressing)
+{
+ return pppoe_get_addressing(chan, addressing);
+}
+EXPORT_SYMBOL(pppoe_channel_addressing_get);
+
+static const struct pppoe_channel_ops pppoe_chan_ops = {
+ /* PPPoE specific channel ops */
+ .get_addressing = pppoe_get_addressing,
+ /* General ppp channel ops */
+ .ops.start_xmit = pppoe_xmit,
+ .ops.get_channel_protocol = pppoe_get_channel_protocol,
+ .ops.hold = pppoe_hold_chan,
+ .ops.release = pppoe_release_chan,
+ .ops.fill_forward_path = pppoe_fill_forward_path,
};
static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -93,4 +93,17 @@ enum {
PPPOX_DEAD = 16 /* dead, useless, please clean me up!*/
};
+/*
+ * PPPoE Channel specific operations
+ */
+struct pppoe_channel_ops {
+ /* Must be first - general to all PPP channels */
+ struct ppp_channel_ops ops;
+ int (*get_addressing)(struct ppp_channel *, struct pppoe_opt *);
+};
+
+/* Return PPPoE channel specific addressing information */
+extern int pppoe_channel_addressing_get(struct ppp_channel *chan,
+ struct pppoe_opt *addressing);
+
#endif /* !(__LINUX_IF_PPPOX_H) */
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1620,6 +1620,24 @@ enum netdev_priv_flags {
IFF_LIVE_RENAME_OK = 1<<30,
};
+
+/**
+ * enum netdev_priv_flags_ext - &struct net_device priv_flags_ext
+ *
+ * These flags are used to check for device type and can be
+ * set and used by the drivers
+ *
+ */
+enum netdev_priv_flags_ext {
+ IFF_EXT_TUN_TAP = 1<<0,
+ IFF_EXT_PPP_L2TPV2 = 1<<1,
+ IFF_EXT_PPP_L2TPV3 = 1<<2,
+ IFF_EXT_PPP_PPTP = 1<<3,
+ IFF_EXT_GRE_V4_TAP = 1<<4,
+ IFF_EXT_GRE_V6_TAP = 1<<5,
+ IFF_EXT_IFB = 1<<6,
+};
+
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
#define IFF_EBRIDGE IFF_EBRIDGE
#define IFF_BONDING IFF_BONDING
@@ -1994,6 +2012,7 @@ struct net_device {
unsigned int flags;
unsigned int priv_flags;
+ unsigned int priv_flags_ext;
unsigned short gflags;
unsigned short padded;
--- a/include/linux/ppp_channel.h
+++ b/include/linux/ppp_channel.h
@@ -19,6 +19,10 @@
#include <linux/skbuff.h>
#include <linux/poll.h>
#include <net/net_namespace.h>
+#include <linux/notifier.h>
+
+#define PPP_CHANNEL_DISCONNECT 0
+#define PPP_CHANNEL_CONNECT 1
struct ppp_channel;
@@ -28,9 +32,19 @@ struct ppp_channel_ops {
int (*start_xmit)(struct ppp_channel *, struct sk_buff *);
/* Handle an ioctl call that has come in via /dev/ppp. */
int (*ioctl)(struct ppp_channel *, unsigned int, unsigned long);
+ /* Get channel protocol type, one of PX_PROTO_XYZ or specific to
+ * the channel subtype
+ */
+ int (*get_channel_protocol)(struct ppp_channel *);
+ /* Get channel protocol version */
+ int (*get_channel_protocol_ver)(struct ppp_channel *);
+ /* Hold the channel from being destroyed */
+ void (*hold)(struct ppp_channel *);
+ /* Release hold on the channel */
+ void (*release)(struct ppp_channel *);
int (*fill_forward_path)(struct net_device_path_ctx *,
- struct net_device_path *,
- const struct ppp_channel *);
+ struct net_device_path *,
+ const struct ppp_channel *);
};
struct ppp_channel {
@@ -74,6 +88,51 @@ extern int ppp_unit_number(struct ppp_ch
/* Get the device name associated with a channel, or NULL if none */
extern char *ppp_dev_name(struct ppp_channel *);
+/* Call this to obtain the underlying protocol of the PPP channel,
+ * e.g. PX_PROTO_OE
+ */
+extern int ppp_channel_get_protocol(struct ppp_channel *);
+
+/* Call this get protocol version */
+extern int ppp_channel_get_proto_version(struct ppp_channel *);
+
+/* Call this to hold a channel */
+extern bool ppp_channel_hold(struct ppp_channel *);
+
+/* Call this to release a hold you have upon a channel */
+extern void ppp_channel_release(struct ppp_channel *);
+
+/* Release hold on PPP channels */
+extern void ppp_release_channels(struct ppp_channel *channels[],
+ unsigned int chan_sz);
+
+/* Hold PPP channels for the PPP device */
+extern int ppp_hold_channels(struct net_device *dev,
+ struct ppp_channel *channels[],
+ unsigned int chan_sz);
+
+/* Test if ppp xmit lock is locked */
+extern bool ppp_is_xmit_locked(struct net_device *dev);
+
+/* Test if the ppp device is a multi-link ppp device */
+extern int ppp_is_multilink(struct net_device *dev);
+
+/* Register the PPP channel connect notifier */
+extern void ppp_channel_connection_register_notify(struct notifier_block *nb);
+
+/* Unregister the PPP channel connect notifier */
+extern void ppp_channel_connection_unregister_notify(struct notifier_block *nb);
+
+/* Update statistics of the PPP net_device by incrementing related
+ * statistics field value with corresponding parameter
+ */
+extern void ppp_update_stats(struct net_device *dev, unsigned long rx_packets,
+ unsigned long rx_bytes, unsigned long tx_packets,
+ unsigned long tx_bytes, unsigned long rx_errors,
+ unsigned long tx_errors, unsigned long rx_dropped,
+ unsigned long tx_dropped);
+
+
/*
* SMP locking notes:
* The channel code must ensure that when it calls ppp_unregister_channel,

View File

@ -1,74 +0,0 @@
From a0c69a23c66ec6f527c439714eb2cc5857a71492 Mon Sep 17 00:00:00 2001
From: Himanshu Joshi <himajosh@codeaurora.org>
Date: Tue, 3 Nov 2020 16:41:26 +0530
Subject: [PATCH] net: core: Flag to identify ingress shaping done for
exceptioned packets.
Signed-off-by: Himanshu Joshi <himajosh@codeaurora.org>
Change-Id: Ib3cd341e5b2d4dcf552e02e38d3f34a4f00351cd
---
include/linux/skbuff.h | 2 ++
include/net/sch_generic.h | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -646,6 +646,7 @@ typedef unsigned char *sk_buff_data_t;
* @offload_fwd_mark: Packet was L2-forwarded in hardware
* @offload_l3_fwd_mark: Packet was L3-forwarded in hardware
* @tc_skip_classify: do not classify packet. set by IFB device
+ * @tc_skip_classify_nss: do not classify packet. set by NSS IFB device
* @tc_at_ingress: used within tc_classify to distinguish in/egress
* @redirected: packet was redirected by packet classifier
* @from_ingress: packet was redirected from the ingress path
@@ -850,6 +851,7 @@ struct sk_buff {
#ifdef CONFIG_NET_CLS_ACT
__u8 tc_skip_classify:1;
__u8 tc_at_ingress:1;
+ __u8 tc_skip_classify_nss:1;
#endif
#ifdef CONFIG_NET_REDIRECT
__u8 redirected:1;
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -754,6 +754,40 @@ static inline bool skb_skip_tc_classify(
return false;
}
+/*
+ * Set skb classify bit field.
+ */
+static inline void skb_set_tc_classify_nss(struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ skb->tc_skip_classify_nss = 1;
+#endif
+}
+
+/*
+ * Clear skb classify bit field.
+ */
+static inline void skb_clear_tc_classify_nss(struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ skb->tc_skip_classify_nss = 0;
+#endif
+}
+
+/*
+ * Skip skb processing if sent from ifb dev.
+ */
+static inline bool skb_skip_tc_classify_nss(struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ if (skb->tc_skip_classify_nss) {
+ skb_clear_tc_classify_nss(skb);
+ return true;
+ }
+#endif
+ return false;
+}
+
/* Reset all TX qdiscs greater than index of a device. */
static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
{

View File

@ -1,76 +0,0 @@
From 7c55539fa1e4ea6be400a35127ddc52d6dcd86d4 Mon Sep 17 00:00:00 2001
From: Himanshu Joshi <himajosh@codeaurora.org>
Date: Thu, 26 Nov 2020 16:21:06 +0530
Subject: [PATCH] net: core: Replace nss keyword with offload.
Kernel code should not checked in with NSS keyword.
This change fixes the naming issue for ifb module.
Signed-off-by: Himanshu Joshi <himajosh@codeaurora.org>
Change-Id: Iddb97d6ba0a443b830d1ac23728434a417bc8a92
---
include/linux/skbuff.h | 4 ++--
include/net/sch_generic.h | 14 +++++++-------
2 files changed, 9 insertions(+), 9 deletions(-)
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -646,7 +646,7 @@ typedef unsigned char *sk_buff_data_t;
* @offload_fwd_mark: Packet was L2-forwarded in hardware
* @offload_l3_fwd_mark: Packet was L3-forwarded in hardware
* @tc_skip_classify: do not classify packet. set by IFB device
- * @tc_skip_classify_nss: do not classify packet. set by NSS IFB device
+ * @tc_skip_classify_offload: do not classify packet set by offload IFB device
* @tc_at_ingress: used within tc_classify to distinguish in/egress
* @redirected: packet was redirected by packet classifier
* @from_ingress: packet was redirected from the ingress path
@@ -851,7 +851,7 @@ struct sk_buff {
#ifdef CONFIG_NET_CLS_ACT
__u8 tc_skip_classify:1;
__u8 tc_at_ingress:1;
- __u8 tc_skip_classify_nss:1;
+ __u8 tc_skip_classify_offload:1;
#endif
#ifdef CONFIG_NET_REDIRECT
__u8 redirected:1;
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -757,31 +757,31 @@ static inline bool skb_skip_tc_classify(
/*
* Set skb classify bit field.
*/
-static inline void skb_set_tc_classify_nss(struct sk_buff *skb)
+static inline void skb_set_tc_classify_offload(struct sk_buff *skb)
{
#ifdef CONFIG_NET_CLS_ACT
- skb->tc_skip_classify_nss = 1;
+ skb->tc_skip_classify_offload = 1;
#endif
}
/*
* Clear skb classify bit field.
*/
-static inline void skb_clear_tc_classify_nss(struct sk_buff *skb)
+static inline void skb_clear_tc_classify_offload(struct sk_buff *skb)
{
#ifdef CONFIG_NET_CLS_ACT
- skb->tc_skip_classify_nss = 0;
+ skb->tc_skip_classify_offload = 0;
#endif
}
/*
* Skip skb processing if sent from ifb dev.
*/
-static inline bool skb_skip_tc_classify_nss(struct sk_buff *skb)
+static inline bool skb_skip_tc_classify_offload(struct sk_buff *skb)
{
#ifdef CONFIG_NET_CLS_ACT
- if (skb->tc_skip_classify_nss) {
- skb_clear_tc_classify_nss(skb);
+ if (skb->tc_skip_classify_offload) {
+ skb_clear_tc_classify_offload(skb);
return true;
}
#endif

View File

@ -1,97 +0,0 @@
From bcb4b67add833322a1361eea26f185deecd15ff1 Mon Sep 17 00:00:00 2001
From: Simon Casey <simon501098c@gmail.com>
Date: Fri, 22 Oct 2021 14:43:11 +0200
Subject: [PATCH] bridge: Add NSS bridge-mgr support for ipq807x
Add necessary functionality for enabling the NSS bridge-mgr module.
Signed-off-by: Simon Casey <simon501098c@gmail.com>
---
include/linux/if_bridge.h | 4 ++++
net/bridge/br_fdb.c | 25 +++++++++++++++++++++----
2 files changed, 25 insertions(+), 4 deletions(-)
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -197,4 +197,8 @@ typedef struct net_bridge_port *br_get_d
extern br_get_dst_hook_t __rcu *br_get_dst_hook;
/* QCA NSS ECM support - End */
+/* QCA NSS bridge-mgr support - Start */
+extern struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br);
+/* QCA NSS bridge-mgr support - End */
+
#endif
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -66,6 +66,15 @@ void br_fdb_update_unregister_notify(str
EXPORT_SYMBOL_GPL(br_fdb_update_unregister_notify);
/* QCA NSS ECM support - End */
+/* QCA NSS bridge-mgr support - Start */
+struct net_device *br_fdb_bridge_dev_get_and_hold(struct net_bridge *br)
+{
+ dev_hold(br->dev);
+ return br->dev;
+}
+EXPORT_SYMBOL_GPL(br_fdb_bridge_dev_get_and_hold);
+/* QCA NSS bridge-mgr support - End */
+
int __init br_fdb_init(void)
{
br_fdb_cache = kmem_cache_create("bridge_fdb_cache",
@@ -371,7 +380,7 @@ void br_fdb_cleanup(struct work_struct *
unsigned long delay = hold_time(br);
unsigned long work_delay = delay;
unsigned long now = jiffies;
- u8 mac_addr[6]; /* QCA NSS ECM support */
+ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */
/* this part is tricky, in order to avoid blocking learning and
* consequently forwarding, we rely on rcu to delete objects with
@@ -399,12 +408,13 @@ void br_fdb_cleanup(struct work_struct *
} else {
spin_lock_bh(&br->hash_lock);
if (!hlist_unhashed(&f->fdb_node)) {
- ether_addr_copy(mac_addr, f->key.addr.addr);
+ memset(&fdb_event, 0, sizeof(fdb_event));
+ ether_addr_copy(fdb_event.addr, f->key.addr.addr);
fdb_delete(br, f, true);
/* QCA NSS ECM support - Start */
atomic_notifier_call_chain(
&br_fdb_update_notifier_list, 0,
- (void *)mac_addr);
+ (void *)&fdb_event);
/* QCA NSS ECM support - End */
}
spin_unlock_bh(&br->hash_lock);
@@ -615,6 +625,7 @@ void br_fdb_update(struct net_bridge *br
const unsigned char *addr, u16 vid, unsigned long flags)
{
struct net_bridge_fdb_entry *fdb;
+ struct br_fdb_event fdb_event; /* QCA NSS bridge-mgr support */
/* some users want to always flood. */
if (hold_time(br) == 0)
@@ -640,6 +651,12 @@ void br_fdb_update(struct net_bridge *br
if (unlikely(source != fdb->dst &&
!test_bit(BR_FDB_STICKY, &fdb->flags))) {
br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH);
+ /* QCA NSS bridge-mgr support - Start */
+ ether_addr_copy(fdb_event.addr, addr);
+ fdb_event.br = br;
+ fdb_event.orig_dev = fdb->dst->dev;
+ fdb_event.dev = source->dev;
+ /* QCA NSS bridge-mgr support - End */
fdb->dst = source;
fdb_modified = true;
/* Take over HW learned entry */
@@ -651,7 +668,7 @@ void br_fdb_update(struct net_bridge *br
/* QCA NSS ECM support - Start */
atomic_notifier_call_chain(
&br_fdb_update_notifier_list,
- 0, (void *)addr);
+ 0, (void *)&fdb_event);
/* QCA NSS ECM support - End */
}

View File

@ -1,28 +0,0 @@
DMA controller binding describes the node name should be dma-controller
and not dma, so fix the node name
Signed-off-by: Vinod Koul <vk...@kernel.org>
---
arch/arm64/boot/dts/qcom/ipq6018.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -192,7 +192,7 @@
clock-names = "core";
};
- cryptobam: dma@704000 {
+ cryptobam: dma-controller@704000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x0 0x00704000 0x0 0x20000>;
interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
@@ -252,7 +252,7 @@
reg = <0x0 0x01945000 0x0 0xe000>;
};
- blsp_dma: dma@7884000 {
+ blsp_dma: dma-controller@7884000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x0 0x07884000 0x0 0x2b000>;
interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;

View File

@ -1,14 +0,0 @@
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -239,7 +239,11 @@ static const struct soc_id soc_id[] = {
{ 395, "IPQ8070A" },
{ 396, "IPQ8071A" },
{ 402, "IPQ6018" },
+ { 403, "IPQ6028" },
+ { 421, "IPQ6000" },
+ { 422, "IPQ6010" },
{ 425, "SC7180" },
+ { 453, "IPQ6005" },
};
static const char *socinfo_machine(struct device *dev, unsigned int id)

View File

@ -1,23 +0,0 @@
From 8aec79b6d4d59616eb6ce4fbfb94658b3e79d9ce Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Tue, 11 May 2021 13:29:33 +0200
Subject: [PATCH] arm64: dts: add OpenWrt DTS files
Lets add custom OpenWrt DTS files to Makefile.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
arch/arm64/boot/dts/qcom/Makefile | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -3,6 +3,8 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.d
dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb
dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq6018-cp01-c1.dtb
+dtb-$(CONFIG_ARCH_QCOM) += ipq6018-hr6001.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcom-ipq6018-gl-ax1800.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq8074-hk01.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-longcheer-l8150.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb

View File

@ -1,28 +0,0 @@
From b9b94712847f8fa6ca8dc03422ba9e0332b6997d Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Thu, 13 May 2021 14:54:43 +0200
Subject: [PATCH] soc: qcom: Make QMI Helpers user selectable
Wireless backports for ath11k have a different logic
then upstream as they depend on QMI helpers instead
of selecting them.
So, to make it possible to select QMI helpers
through KConfig add text to tristate.
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/soc/qcom/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -92,7 +92,7 @@ config QCOM_PDR_HELPERS
select QCOM_QMI_HELPERS
config QCOM_QMI_HELPERS
- tristate
+ tristate "Qualcomm QMI helpers"
depends on NET
config QCOM_RMTFS_MEM

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