Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
0f2088d9ab
@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-6.6 = .73
|
||||
LINUX_KERNEL_HASH-6.6.73 = d2028db190c201650898be8db1c705e9fe73ab44fc04290b4f7af63514122490
|
||||
LINUX_VERSION-6.6 = .74
|
||||
LINUX_KERNEL_HASH-6.6.74 = f15e2b1a8bab0eba494b07858a5abc88d8f788e25f6fe4a572a77840bbd5494d
|
||||
|
@ -1738,7 +1738,7 @@ $(eval $(call KernelPackage,usbip-server))
|
||||
|
||||
define KernelPackage/usb-chipidea
|
||||
TITLE:=Host and device support for Chipidea controllers
|
||||
DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget @TARGET_ath79 +kmod-usb-ehci +kmod-usb-phy-nop +kmod-usb-roles
|
||||
DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget @TARGET_ath79 +kmod-usb-ehci +kmod-usb-phy-nop +kmod-usb-roles +kmod-phy-ath79-usb
|
||||
KCONFIG:= \
|
||||
CONFIG_EXTCON \
|
||||
CONFIG_USB_CHIPIDEA \
|
||||
|
@ -30,7 +30,6 @@ reload_service() {
|
||||
|
||||
init_switch
|
||||
ubus call network reload || rv=1
|
||||
[ -x /sbin/wifi ] && /sbin/wifi reload_legacy
|
||||
return $rv
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,9 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=unetd
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/unetd.git
|
||||
PKG_SOURCE_DATE:=2024-12-17
|
||||
PKG_SOURCE_VERSION:=a0a2d80f3459425182a9f0e665d8ca8eff97c82f
|
||||
PKG_MIRROR_HASH:=a6f07d91da40152b2af5b5b9d1d67d87a9991943147e47be6921c092ad7b49a3
|
||||
PKG_SOURCE_DATE:=2025-01-26
|
||||
PKG_SOURCE_VERSION:=d13752814651c70d2afc71383612fafc835b631b
|
||||
PKG_MIRROR_HASH:=c9de65ae92af2498fcd9d55f9cd2017cb9ac79b03ed5816da21161aa24f226b9
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
@ -82,11 +82,10 @@ proto_unet_setup() {
|
||||
|
||||
proto_unet_teardown() {
|
||||
local config="$1"
|
||||
local iface="$2"
|
||||
|
||||
local device
|
||||
json_get_vars device
|
||||
device="${device:-$iface}"
|
||||
device="${device:-$config}"
|
||||
|
||||
json_init
|
||||
json_add_string name "$device"
|
||||
|
@ -1,4 +1,5 @@
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_AIROHA_CPU_PM_DOMAIN=y
|
||||
CONFIG_AIROHA_THERMAL=y
|
||||
CONFIG_AIROHA_WATCHDOG=y
|
||||
CONFIG_AMPERE_ERRATUM_AC03_CPU_38=y
|
||||
|
@ -81,7 +81,7 @@
|
||||
clocks = <&cpufreq>;
|
||||
clock-names = "cpu";
|
||||
power-domains = <&cpufreq>;
|
||||
power-domain-names = "cpu_pd";
|
||||
power-domain-names = "perf";
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@ -95,7 +95,7 @@
|
||||
clocks = <&cpufreq>;
|
||||
clock-names = "cpu";
|
||||
power-domains = <&cpufreq>;
|
||||
power-domain-names = "cpu_pd";
|
||||
power-domain-names = "perf";
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@ -109,7 +109,7 @@
|
||||
clocks = <&cpufreq>;
|
||||
clock-names = "cpu";
|
||||
power-domains = <&cpufreq>;
|
||||
power-domain-names = "cpu_pd";
|
||||
power-domain-names = "perf";
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@ -123,7 +123,7 @@
|
||||
clocks = <&cpufreq>;
|
||||
clock-names = "cpu";
|
||||
power-domains = <&cpufreq>;
|
||||
power-domain-names = "cpu_pd";
|
||||
power-domain-names = "perf";
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
From fa27cb99b297a1a9c0a5824afe5a670e424fff61 Mon Sep 17 00:00:00 2001
|
||||
From 84cf9e541cccb8cb698518a9897942e8c78f1d83 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Wed, 16 Oct 2024 18:00:57 +0200
|
||||
Subject: [PATCH v9 2/2] cpufreq: airoha: Add EN7581 CPUFreq SMCCC driver
|
||||
Date: Thu, 9 Jan 2025 14:12:58 +0100
|
||||
Subject: [PATCH] cpufreq: airoha: Add EN7581 CPUFreq SMCCC driver
|
||||
|
||||
Add simple CPU Freq driver for Airoha EN7581 SoC that control CPU
|
||||
frequency scaling with SMC APIs and register a generic "cpufreq-dt"
|
||||
@ -14,29 +14,8 @@ Add SoC compatible to cpufreq-dt-plat block list as a dedicated cpufreq
|
||||
driver is needed with OPP v2 nodes declared in DTS.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
---
|
||||
Changes v9:
|
||||
- Fix compile error targetting wrong branch (remove_new change and new PM OPs)
|
||||
Changes v8:
|
||||
- Split in dedicated PM domain driver
|
||||
Changes v7:
|
||||
- No changes
|
||||
Changes v6:
|
||||
- Improve Kconfig depends logic
|
||||
- Select PM (PM_GENERIC_DOMAINS depends on it)
|
||||
- Drop (int) cast for
|
||||
Changes v5:
|
||||
- Rename cpu_pd to perf for power domain name
|
||||
- Use remove instead of remove_new
|
||||
Changes v4:
|
||||
- Rework to clk-only + PM set_performance_state implementation
|
||||
Changes v3:
|
||||
- Adapt to new cpufreq-dt APIs
|
||||
- Register cpufreq-dt instead of custom freq driver
|
||||
Changes v2:
|
||||
- Fix kernel bot error with missing slab.h and bitfield.h header
|
||||
- Limit COMPILE_TEST to ARM64 due to smcc 1.2
|
||||
|
||||
drivers/cpufreq/Kconfig.arm | 8 ++
|
||||
drivers/cpufreq/Makefile | 1 +
|
||||
drivers/cpufreq/airoha-cpufreq.c | 152 +++++++++++++++++++++++++++
|
||||
@ -104,11 +83,15 @@ Changes v2:
|
||||
+}
|
||||
+
|
||||
+static const char * const airoha_cpufreq_clk_names[] = { "cpu", NULL };
|
||||
+static const char * const airoha_cpufreq_genpd_names[] = { "cpu_pd", NULL };
|
||||
+static const char * const airoha_cpufreq_pd_names[] = { "perf", NULL };
|
||||
+
|
||||
+static int airoha_cpufreq_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct dev_pm_opp_config config = { };
|
||||
+ struct dev_pm_opp_config config = {
|
||||
+ .clk_names = airoha_cpufreq_clk_names,
|
||||
+ .config_clks = airoha_cpufreq_config_clks_nop,
|
||||
+ .genpd_names = airoha_cpufreq_pd_names,
|
||||
+ };
|
||||
+ struct platform_device *cpufreq_dt;
|
||||
+ struct airoha_cpufreq_priv *priv;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
@ -125,18 +108,14 @@ Changes v2:
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ config.clk_names = airoha_cpufreq_clk_names;
|
||||
+ config.config_clks = airoha_cpufreq_config_clks_nop;
|
||||
+ config.genpd_names = airoha_cpufreq_genpd_names;
|
||||
+ config.virt_devs = &virt_devs;
|
||||
+
|
||||
+ /* Set OPP table conf with NOP config_clks */
|
||||
+ priv->opp_token = dev_pm_opp_set_config(cpu_dev, &config);
|
||||
+ if (priv->opp_token < 0)
|
||||
+ return dev_err_probe(dev, priv->opp_token, "Failed to set OPP config\n");
|
||||
+
|
||||
+ /* Set Attached PM for OPP ACTIVE */
|
||||
+ if (virt_devs) {
|
||||
+ const char * const *name = airoha_cpufreq_genpd_names;
|
||||
+ const char * const *name = airoha_cpufreq_pd_names;
|
||||
+ int i, j;
|
||||
+
|
||||
+ for (i = 0; *name; i++, name++) {
|
||||
@ -177,7 +156,7 @@ Changes v2:
|
||||
+static void airoha_cpufreq_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct airoha_cpufreq_priv *priv = platform_get_drvdata(pdev);
|
||||
+ const char * const *name = airoha_cpufreq_genpd_names;
|
||||
+ const char * const *name = airoha_cpufreq_pd_names;
|
||||
+ int i;
|
||||
+
|
||||
+ platform_device_unregister(priv->cpufreq_dt);
|
@ -1,7 +1,7 @@
|
||||
From 76e4e6ce9aaae897f80e375345bf0095e1b09ff2 Mon Sep 17 00:00:00 2001
|
||||
From 82e703dd438b71432cc0ccbb90925d1e32dd014a Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Sat, 4 Jan 2025 19:03:09 +0100
|
||||
Subject: [PATCH v9 1/2] pmdomain: airoha: Add Airoha CPU PM Domain support
|
||||
Date: Thu, 9 Jan 2025 14:12:57 +0100
|
||||
Subject: [PATCH] pmdomain: airoha: Add Airoha CPU PM Domain support
|
||||
|
||||
Add Airoha CPU PM Domain support to control frequency and power of CPU
|
||||
present on Airoha EN7581 SoC.
|
||||
@ -11,25 +11,21 @@ passing the performance state. The driver also expose a read-only clock
|
||||
that expose the current CPU frequency with SMC command.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20250109131313.32317-1-ansuelsmth@gmail.com
|
||||
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
|
||||
---
|
||||
Changes v9:
|
||||
- Fix compile error targetting wrong branch (remove_new change)
|
||||
Changes v8:
|
||||
- Add this patch
|
||||
- Use SMC invoke instead of 1.2
|
||||
|
||||
drivers/pmdomain/mediatek/Kconfig | 11 ++
|
||||
drivers/pmdomain/mediatek/Kconfig | 12 ++
|
||||
drivers/pmdomain/mediatek/Makefile | 1 +
|
||||
.../pmdomain/mediatek/airoha-cpu-pmdomain.c | 144 ++++++++++++++++++
|
||||
3 files changed, 156 insertions(+)
|
||||
3 files changed, 157 insertions(+)
|
||||
create mode 100644 drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c
|
||||
|
||||
--- a/drivers/soc/mediatek/Kconfig
|
||||
+++ b/drivers/soc/mediatek/Kconfig
|
||||
@@ -72,6 +72,17 @@ config MTK_SCPSYS_PM_DOMAINS
|
||||
Control Processor System (SCPSYS) has several power management related
|
||||
tasks in the system.
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
#
|
||||
# MediaTek SoC drivers
|
||||
#
|
||||
+config AIROHA_CPU_PM_DOMAIN
|
||||
+ tristate "Airoha CPU power domain"
|
||||
+ default ARCH_AIROHA
|
||||
@ -41,9 +37,9 @@ Changes v8:
|
||||
+ CPU frequency and power is controlled by ATF with SMC command to
|
||||
+ set performance states.
|
||||
+
|
||||
config MTK_MMSYS
|
||||
tristate "MediaTek MMSYS Support"
|
||||
default ARCH_MEDIATEK
|
||||
menu "MediaTek SoC drivers"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
|
||||
--- a/drivers/pmdomain/mediatek/Makefile
|
||||
+++ b/drivers/pmdomain/mediatek/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
@ -53,7 +49,7 @@ Changes v8:
|
||||
+obj-$(CONFIG_AIROHA_CPU_PM_DOMAIN) += airoha-cpu-pmdomain.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c
|
||||
@@ -0,0 +1,145 @@
|
||||
@@ -0,0 +1,144 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+
|
||||
+#include <linux/arm-smccc.h>
|
||||
@ -123,9 +119,13 @@ Changes v8:
|
||||
+{
|
||||
+ struct airoha_cpu_pmdomain_priv *priv;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct clk_init_data init = { };
|
||||
+ const struct clk_init_data init = {
|
||||
+ .name = "cpu",
|
||||
+ .ops = &airoha_cpu_pmdomain_clk_ops,
|
||||
+ /* Clock with no set_rate, can't cache */
|
||||
+ .flags = CLK_GET_RATE_NOCACHE,
|
||||
+ };
|
||||
+ struct generic_pm_domain *pd;
|
||||
+ struct clk_hw *hw;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
@ -133,18 +133,13 @@ Changes v8:
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Init and register a get-only clk for Cpufreq */
|
||||
+ init.name = "cpu";
|
||||
+ init.ops = &airoha_cpu_pmdomain_clk_ops;
|
||||
+ /* Clock with no set_rate, can't cache */
|
||||
+ init.flags = CLK_GET_RATE_NOCACHE;
|
||||
+
|
||||
+ hw = &priv->hw;
|
||||
+ hw->init = &init;
|
||||
+ ret = devm_clk_hw_register(dev, hw);
|
||||
+ priv->hw.init = &init;
|
||||
+ ret = devm_clk_hw_register(dev, &priv->hw);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
|
||||
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
+ &priv->hw);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
@ -265,6 +265,7 @@ CONFIG_DRM_BOCHS=y
|
||||
CONFIG_DRM_BRIDGE=y
|
||||
# CONFIG_DRM_FSL_LDB is not set
|
||||
CONFIG_DRM_GEM_SHMEM_HELPER=y
|
||||
# CONFIG_DRM_HYPERV is not set
|
||||
# CONFIG_DRM_IMX8QM_LDB is not set
|
||||
# CONFIG_DRM_IMX8QXP_LDB is not set
|
||||
# CONFIG_DRM_IMX8QXP_PIXEL_COMBINER is not set
|
||||
@ -309,6 +310,7 @@ CONFIG_FB_CFB_COPYAREA=y
|
||||
CONFIG_FB_CFB_FILLRECT=y
|
||||
CONFIG_FB_CFB_IMAGEBLIT=y
|
||||
CONFIG_FB_CMDLINE=y
|
||||
CONFIG_FB_HYPERV=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
CONFIG_FB_MX3=y
|
||||
# CONFIG_FB_SH_MOBILE_LCDC is not set
|
||||
@ -340,6 +342,7 @@ CONFIG_GPIO_ZYNQMP_MODEPIN=y
|
||||
CONFIG_HDMI=y
|
||||
CONFIG_HI3660_MBOX=y
|
||||
CONFIG_HI6220_MBOX=y
|
||||
# CONFIG_HID_HYPERV_MOUSE is not set
|
||||
CONFIG_HISILICON_ERRATUM_161600802=y
|
||||
CONFIG_HISILICON_LPC=y
|
||||
CONFIG_HISI_PMU=y
|
||||
@ -355,6 +358,12 @@ CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y
|
||||
# CONFIG_HW_RANDOM_HISI is not set
|
||||
# CONFIG_HW_RANDOM_HISTB is not set
|
||||
CONFIG_HW_RANDOM_VIRTIO=y
|
||||
CONFIG_HYPERV=y
|
||||
# CONFIG_HYPERV_BALLOON is not set
|
||||
CONFIG_HYPERV_KEYBOARD=y
|
||||
CONFIG_HYPERV_NET=y
|
||||
CONFIG_HYPERV_STORAGE=y
|
||||
# CONFIG_HYPERV_TESTING is not set
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_ALGOBIT=y
|
||||
CONFIG_I2C_ALTERA=y
|
||||
@ -409,6 +418,7 @@ CONFIG_IOMMU_SUPPORT=y
|
||||
# CONFIG_IPMMU_VMSA is not set
|
||||
# CONFIG_K3_DMA is not set
|
||||
CONFIG_KCMP=y
|
||||
CONFIG_KEYBOARD_ATKBD=y
|
||||
# CONFIG_KEYBOARD_IMX_SC_KEY is not set
|
||||
# CONFIG_KEYBOARD_SUN4I_LRADC is not set
|
||||
CONFIG_KSM=y
|
||||
@ -518,6 +528,7 @@ CONFIG_PCI_AARDVARK=y
|
||||
CONFIG_PCI_HISI=y
|
||||
CONFIG_PCI_HOST_THUNDER_ECAM=y
|
||||
CONFIG_PCI_HOST_THUNDER_PEM=y
|
||||
CONFIG_PCI_HYPERV=y
|
||||
CONFIG_PCI_IMX6=y
|
||||
CONFIG_PCI_IMX6_HOST=y
|
||||
CONFIG_PCI_IOV=y
|
||||
@ -701,6 +712,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
|
||||
CONFIG_SERIAL_SH_SCI_DMA=y
|
||||
CONFIG_SERIAL_SH_SCI_EARLYCON=y
|
||||
CONFIG_SERIAL_SH_SCI_NR_UARTS=18
|
||||
CONFIG_SERIO=y
|
||||
# CONFIG_SMC91X is not set
|
||||
# CONFIG_SND_SOC_RCAR is not set
|
||||
# CONFIG_SND_SOC_RZ is not set
|
||||
|
@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
|
||||
--- a/drivers/gpu/drm/v3d/v3d_irq.c
|
||||
+++ b/drivers/gpu/drm/v3d/v3d_irq.c
|
||||
@@ -177,6 +177,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
@@ -181,6 +181,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
"GMP",
|
||||
};
|
||||
const char *client = "?";
|
||||
@ -21,7 +21,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
|
||||
V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL));
|
||||
|
||||
@@ -186,6 +187,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
@@ -190,6 +191,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
client = v3d41_axi_ids[axi_id];
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
dev_err(v3d->drm.dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n",
|
||||
client, axi_id, (long long)vio_addr,
|
||||
((intsts & V3D_HUB_INT_MMU_WRV) ?
|
||||
@@ -194,6 +196,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
@@ -198,6 +200,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
", pte invalid" : ""),
|
||||
((intsts & V3D_HUB_INT_MMU_CAP) ?
|
||||
", cap exceeded" : ""));
|
||||
|
@ -258,7 +258,7 @@ Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
|
||||
|
||||
trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
@@ -109,6 +111,7 @@ v3d_irq(int irq, void *arg)
|
||||
@@ -110,6 +112,7 @@ v3d_irq(int irq, void *arg)
|
||||
if (intsts & V3D_INT_FRDONE) {
|
||||
struct v3d_fence *fence =
|
||||
to_v3d_fence(v3d->render_job->base.irq_fence);
|
||||
@ -266,7 +266,7 @@ Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
|
||||
|
||||
trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
@@ -118,6 +121,7 @@ v3d_irq(int irq, void *arg)
|
||||
@@ -120,6 +123,7 @@ v3d_irq(int irq, void *arg)
|
||||
if (intsts & V3D_INT_CSDDONE) {
|
||||
struct v3d_fence *fence =
|
||||
to_v3d_fence(v3d->csd_job->base.irq_fence);
|
||||
@ -274,7 +274,7 @@ Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
|
||||
|
||||
trace_v3d_csd_irq(&v3d->drm, fence->seqno);
|
||||
dma_fence_signal(&fence->base);
|
||||
@@ -154,6 +158,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
@@ -157,6 +161,7 @@ v3d_hub_irq(int irq, void *arg)
|
||||
if (intsts & V3D_HUB_INT_TFUC) {
|
||||
struct v3d_fence *fence =
|
||||
to_v3d_fence(v3d->tfu_job->base.irq_fence);
|
||||
|
@ -295,7 +295,7 @@ v2: fix kernel panic with debug-fs interface to list registers
|
||||
|
||||
static irqreturn_t
|
||||
v3d_hub_irq(int irq, void *arg);
|
||||
@@ -118,7 +119,8 @@ v3d_irq(int irq, void *arg)
|
||||
@@ -120,7 +121,8 @@ v3d_irq(int irq, void *arg)
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -305,7 +305,7 @@ v2: fix kernel panic with debug-fs interface to list registers
|
||||
struct v3d_fence *fence =
|
||||
to_v3d_fence(v3d->csd_job->base.irq_fence);
|
||||
v3d->gpu_queue_stats[V3D_CSD].last_exec_end = local_clock();
|
||||
@@ -131,7 +133,7 @@ v3d_irq(int irq, void *arg)
|
||||
@@ -134,7 +136,7 @@ v3d_irq(int irq, void *arg)
|
||||
/* We shouldn't be triggering these if we have GMP in
|
||||
* always-allowed mode.
|
||||
*/
|
||||
@ -314,7 +314,7 @@ v2: fix kernel panic with debug-fs interface to list registers
|
||||
dev_err(v3d->drm.dev, "GMP violation\n");
|
||||
|
||||
/* V3D 4.2 wires the hub and core IRQs together, so if we &
|
||||
@@ -205,6 +207,11 @@ v3d_hub_irq(int irq, void *arg)
|
||||
@@ -209,6 +211,11 @@ v3d_hub_irq(int irq, void *arg)
|
||||
status = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ v2: fix kernel panic with debug-fs interface to list registers
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -219,8 +226,8 @@ v3d_irq_init(struct v3d_dev *v3d)
|
||||
@@ -223,8 +230,8 @@ v3d_irq_init(struct v3d_dev *v3d)
|
||||
* for us.
|
||||
*/
|
||||
for (core = 0; core < v3d->cores; core++)
|
||||
@ -337,7 +337,7 @@ v2: fix kernel panic with debug-fs interface to list registers
|
||||
|
||||
irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1);
|
||||
if (irq1 == -EPROBE_DEFER)
|
||||
@@ -264,12 +271,12 @@ v3d_irq_enable(struct v3d_dev *v3d)
|
||||
@@ -268,12 +275,12 @@ v3d_irq_enable(struct v3d_dev *v3d)
|
||||
|
||||
/* Enable our set of interrupts, masking out any others. */
|
||||
for (core = 0; core < v3d->cores; core++) {
|
||||
@ -354,7 +354,7 @@ v2: fix kernel panic with debug-fs interface to list registers
|
||||
}
|
||||
|
||||
void
|
||||
@@ -284,8 +291,8 @@ v3d_irq_disable(struct v3d_dev *v3d)
|
||||
@@ -288,8 +295,8 @@ v3d_irq_disable(struct v3d_dev *v3d)
|
||||
|
||||
/* Clear any pending interrupts we might have left. */
|
||||
for (core = 0; core < v3d->cores; core++)
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 6a9eb32230f33ae273f6ffbabb0aaf560869816e Mon Sep 17 00:00:00 2001
|
||||
From: Scott Ehlert <ehlert@battelle.org>
|
||||
Date: Mon, 29 Apr 2024 11:23:09 -0700
|
||||
Subject: [PATCH] Bluetooth: btsdio: Do not bind to non-removable CYW4373
|
||||
|
||||
CYW4373 devices soldered onto the PCB (non-removable),
|
||||
use a UART connection for Bluetooth and the advertised btsdio
|
||||
support as an SDIO function should be ignored.
|
||||
|
||||
Signed-off-by: Scott Ehlert <ehlert@battelle.org>
|
||||
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
||||
---
|
||||
drivers/bluetooth/btsdio.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/bluetooth/btsdio.c
|
||||
+++ b/drivers/bluetooth/btsdio.c
|
||||
@@ -295,6 +295,7 @@ static int btsdio_probe(struct sdio_func
|
||||
case SDIO_DEVICE_ID_BROADCOM_4345:
|
||||
case SDIO_DEVICE_ID_BROADCOM_43455:
|
||||
case SDIO_DEVICE_ID_BROADCOM_4356:
|
||||
+ case SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373:
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
From 1addfb042a9d27788a0fb2c2935045b56fd8560e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 23 Jan 2025 03:25:29 +0000
|
||||
Subject: [PATCH] net: phy: realtek: mark existing MMDs as present
|
||||
|
||||
When using Clause-45 mode to access RealTek RTL8221B 2.5G PHYs some
|
||||
versions of the PHY fail to report the MMDs present on the PHY.
|
||||
Mark MMDs PMAPMD, PCS and AN which are always existing according to
|
||||
the datasheet as present to fix that.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/phy/realtek/realtek_main.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/realtek/realtek_main.c
|
||||
+++ b/drivers/net/phy/realtek/realtek_main.c
|
||||
@@ -1034,6 +1034,9 @@ static int rtl822x_c45_get_features(stru
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
|
||||
phydev->supported);
|
||||
|
||||
+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
|
||||
+ MDIO_DEVS_AN;
|
||||
+
|
||||
return genphy_c45_pma_read_abilities(phydev);
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ gw,imx8mm-gw72xx-0x|\
|
||||
gw,imx8mp-gw72xx-2x|\
|
||||
gw,imx8mm-gw73xx-0x|\
|
||||
gw,imx8mp-gw73xx-2x|\
|
||||
gw,imx8mm-gw7902-0x)
|
||||
gw,imx8mm-gw7902-0x|\
|
||||
gateworks,imx8mp-gw82xx-2x)
|
||||
ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
|
||||
;;
|
||||
gw,imx8mm-gw7901)
|
||||
|
@ -0,0 +1,189 @@
|
||||
From 82b521f4bb8cab09aa016acf2c1b55ffc736eb2e Mon Sep 17 00:00:00 2001
|
||||
From: Tim Harvey <tharvey@gateworks.com>
|
||||
Date: Mon, 9 Sep 2024 15:15:01 -0700
|
||||
Subject: [PATCH] arm64: dts: imx8mm-venice-*: add RTC aliases
|
||||
|
||||
Add aliases for the RTCs on the Gateworks Venice boards and on the imx8m
|
||||
SoC. This ensures that the primary RTC is always the one on-board
|
||||
provided by the Gateworks System Controller (GSC) which is battery
|
||||
backed as opposed to the one in the IMX8M.
|
||||
|
||||
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
||||
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi | 7 ++++++-
|
||||
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts | 4 +++-
|
||||
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts | 4 +++-
|
||||
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts | 4 +++-
|
||||
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts | 7 ++++++-
|
||||
arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts | 4 +++-
|
||||
arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi | 4 +++-
|
||||
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts | 4 +++-
|
||||
8 files changed, 30 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw700x.dtsi
|
||||
@@ -8,6 +8,11 @@
|
||||
#include <dt-bindings/net/ti-dp83867.h>
|
||||
|
||||
/ {
|
||||
+ aliases {
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
+ };
|
||||
+
|
||||
memory@40000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x40000000 0 0x80000000>;
|
||||
@@ -272,7 +277,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
|
||||
@@ -22,6 +22,8 @@
|
||||
ethernet2 = &lan2;
|
||||
ethernet3 = &lan3;
|
||||
ethernet4 = &lan4;
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
usb0 = &usbotg1;
|
||||
usb1 = &usbotg2;
|
||||
};
|
||||
@@ -495,7 +497,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
aliases {
|
||||
ethernet1 = ð1;
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
usb0 = &usbotg1;
|
||||
usb1 = &usbotg2;
|
||||
};
|
||||
@@ -562,7 +564,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7903.dts
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
aliases {
|
||||
ethernet0 = &fec1;
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
usb0 = &usbotg1;
|
||||
};
|
||||
|
||||
@@ -392,7 +394,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7904.dts
|
||||
@@ -16,6 +16,11 @@
|
||||
model = "Gateworks Venice GW7904 i.MX8MM board";
|
||||
compatible = "gateworks,imx8mm-gw7904", "fsl,imx8mm";
|
||||
|
||||
+ aliases {
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
+ };
|
||||
+
|
||||
chosen {
|
||||
stdout-path = &uart2;
|
||||
};
|
||||
@@ -436,7 +441,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
|
||||
@@ -17,6 +17,8 @@
|
||||
compatible = "gw,imx8mn-gw7902", "fsl,imx8mn";
|
||||
|
||||
aliases {
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
usb0 = &usbotg1;
|
||||
};
|
||||
|
||||
@@ -560,7 +562,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi
|
||||
@@ -10,6 +10,8 @@
|
||||
/ {
|
||||
aliases {
|
||||
ethernet0 = &eqos;
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
};
|
||||
|
||||
memory@40000000 {
|
||||
@@ -260,7 +262,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
|
||||
@@ -24,6 +24,8 @@
|
||||
ethernet4 = &lan3;
|
||||
ethernet5 = &lan4;
|
||||
ethernet6 = &lan5;
|
||||
+ rtc0 = &gsc_rtc;
|
||||
+ rtc1 = &snvs_rtc;
|
||||
};
|
||||
|
||||
chosen {
|
||||
@@ -444,7 +446,7 @@
|
||||
pagesize = <16>;
|
||||
};
|
||||
|
||||
- rtc@68 {
|
||||
+ gsc_rtc: rtc@68 {
|
||||
compatible = "dallas,ds1672";
|
||||
reg = <0x68>;
|
||||
};
|
@ -0,0 +1,36 @@
|
||||
From e6d8fd29bd3d796a00ff9b69f9fae011aec3cb40 Mon Sep 17 00:00:00 2001
|
||||
From: Tim Harvey <tharvey@gateworks.com>
|
||||
Date: Thu, 5 Sep 2024 11:32:28 -0700
|
||||
Subject: [PATCH] arm64: dts: imx8mp-venice-gw74xx: add M2SKT_GPIO10 gpio
|
||||
configuration
|
||||
|
||||
The GW74xx D revision has added a M2SKT_GPIO10 GPIO which routes to the
|
||||
GPIO10 pin of the M.2 socket for compatibility with certain devices.
|
||||
|
||||
Add the iomux and a line name for this.
|
||||
|
||||
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
||||
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
|
||||
@@ -264,7 +264,7 @@
|
||||
&gpio3 {
|
||||
gpio-line-names =
|
||||
"", "", "", "", "", "", "m2_rst", "",
|
||||
- "", "", "", "", "", "", "", "",
|
||||
+ "", "", "", "", "", "", "m2_gpio10", "",
|
||||
"", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "";
|
||||
};
|
||||
@@ -786,6 +786,7 @@
|
||||
MX8MP_IOMUXC_SD2_CMD__GPIO2_IO14 0x40000150 /* PCIE3_WDIS# */
|
||||
MX8MP_IOMUXC_SD2_DATA3__GPIO2_IO18 0x40000150 /* PCIE2_WDIS# */
|
||||
MX8MP_IOMUXC_NAND_DATA00__GPIO3_IO06 0x40000040 /* M2SKT_RST# */
|
||||
+ MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x40000040 /* M2SKT_GPIO10 */
|
||||
MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x40000104 /* UART_TERM */
|
||||
MX8MP_IOMUXC_SAI3_TXFS__GPIO4_IO31 0x40000104 /* UART_RS485 */
|
||||
MX8MP_IOMUXC_SAI3_TXC__GPIO5_IO00 0x40000104 /* UART_HALF */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,79 @@
|
||||
From ede044113c0418f11dbee09069ff1dd68f284dfa Mon Sep 17 00:00:00 2001
|
||||
From: Tim Harvey <tharvey@gateworks.com>
|
||||
Date: Fri, 18 Oct 2024 10:36:08 -0700
|
||||
Subject: [PATCH] arm64: dts: imx8m*-venice-gw75xx: add Accelerometer device
|
||||
|
||||
The GW75xx has a LIS2DE12TR 3-axis accelerometer on the I2C bus with an
|
||||
interrupt pin. Add it to the device-tree.
|
||||
|
||||
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
||||
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
|
||||
---
|
||||
.../boot/dts/freescale/imx8mm-venice-gw75xx.dtsi | 16 ++++++++++++++++
|
||||
.../boot/dts/freescale/imx8mp-venice-gw75xx.dtsi | 16 ++++++++++++++++
|
||||
2 files changed, 32 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw75xx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw75xx.dtsi
|
||||
@@ -116,6 +116,16 @@
|
||||
pinctrl-0 = <&pinctrl_i2c2>;
|
||||
status = "okay";
|
||||
|
||||
+ accelerometer@19 {
|
||||
+ compatible = "st,lis2de12";
|
||||
+ reg = <0x19>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_accel>;
|
||||
+ interrupt-parent = <&gpio5>;
|
||||
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ st,drdy-int-pin = <1>;
|
||||
+ };
|
||||
+
|
||||
eeprom@52 {
|
||||
compatible = "atmel,24c32";
|
||||
reg = <0x52>;
|
||||
@@ -198,6 +208,12 @@
|
||||
>;
|
||||
};
|
||||
|
||||
+ pinctrl_accel: accelgrp {
|
||||
+ fsl,pins = <
|
||||
+ MX8MM_IOMUXC_ECSPI1_MISO_GPIO5_IO8 0x159
|
||||
+ >;
|
||||
+ };
|
||||
+
|
||||
pinctrl_gpio_leds: gpioledgrp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x6 /* LEDG */
|
||||
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw75xx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw75xx.dtsi
|
||||
@@ -104,6 +104,16 @@
|
||||
pinctrl-0 = <&pinctrl_i2c2>;
|
||||
status = "okay";
|
||||
|
||||
+ accelerometer@19 {
|
||||
+ compatible = "st,lis2de12";
|
||||
+ reg = <0x19>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_accel>;
|
||||
+ interrupt-parent = <&gpio5>;
|
||||
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ st,drdy-int-pin = <1>;
|
||||
+ };
|
||||
+
|
||||
eeprom@52 {
|
||||
compatible = "atmel,24c32";
|
||||
reg = <0x52>;
|
||||
@@ -204,6 +214,12 @@
|
||||
>;
|
||||
};
|
||||
|
||||
+ pinctrl_accel: accelgrp {
|
||||
+ fsl,pins = <
|
||||
+ MX8MP_IOMUXC_ECSPI1_MISO__GPIO5_IO08 0x159
|
||||
+ >;
|
||||
+ };
|
||||
+
|
||||
pinctrl_gpio_leds: gpioledgrp {
|
||||
fsl,pins = <
|
||||
MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x6 /* LEDG */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,119 @@
|
||||
From cf983e4a04eecb5be93af7b53cb10805ee448998 Mon Sep 17 00:00:00 2001
|
||||
From: Tim Harvey <tharvey@gateworks.com>
|
||||
Date: Mon, 21 Aug 2023 09:20:17 -0700
|
||||
Subject: [PATCH] PCI: imx6: Start link at max gen first for IMX8MM and IMX8MP
|
||||
|
||||
commit fa33a6d87eac ("PCI: imx6: Start link in Gen1 before negotiating
|
||||
for Gen2 mode") started link negotiation at Gen1 before attempting
|
||||
faster speeds in order to work around an issue with a particular switch
|
||||
on an IMX6Q SoC.
|
||||
|
||||
This behavior is not the norm for PCI link negotiation and it has been
|
||||
found to cause issues in other cases:
|
||||
- IMX8MM with PI7C9X2G608GP switch: various endpoints (such as qca988x)
|
||||
will fail to link more than 50% of the time
|
||||
- IMX8MP with PI7C9X2G608GP switch: occasionally will fail to link with
|
||||
switch and cause a CPU hang about 30% of the time
|
||||
|
||||
Disable this behavior for IMX8MM and IMX8MP.
|
||||
|
||||
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
||||
---
|
||||
drivers/pci/controller/dwc/pci-imx6.c | 53 ++++++++++++++-------------
|
||||
1 file changed, 27 insertions(+), 26 deletions(-)
|
||||
|
||||
--- a/drivers/pci/controller/dwc/pci-imx6.c
|
||||
+++ b/drivers/pci/controller/dwc/pci-imx6.c
|
||||
@@ -60,6 +60,7 @@ enum imx6_pcie_variants {
|
||||
#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
|
||||
#define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1)
|
||||
#define IMX6_PCIE_FLAG_SUPPORTS_SUSPEND BIT(2)
|
||||
+#define IMX6_PCIE_FLAG_GEN1_LAST BIT(3)
|
||||
|
||||
struct imx6_pcie_drvdata {
|
||||
enum imx6_pcie_variants variant;
|
||||
@@ -876,26 +877,28 @@ static int imx6_pcie_start_link(struct d
|
||||
u32 tmp;
|
||||
int ret;
|
||||
|
||||
- /*
|
||||
- * Force Gen1 operation when starting the link. In case the link is
|
||||
- * started in Gen2 mode, there is a possibility the devices on the
|
||||
- * bus will not be detected at all. This happens with PCIe switches.
|
||||
- */
|
||||
- dw_pcie_dbi_ro_wr_en(pci);
|
||||
- tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
|
||||
- tmp &= ~PCI_EXP_LNKCAP_SLS;
|
||||
- tmp |= PCI_EXP_LNKCAP_SLS_2_5GB;
|
||||
- dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);
|
||||
- dw_pcie_dbi_ro_wr_dis(pci);
|
||||
+ if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_GEN1_LAST)) {
|
||||
+ /*
|
||||
+ * Force Gen1 operation when starting the link. In case the link is
|
||||
+ * started in Gen2 mode, there is a possibility the devices on the
|
||||
+ * bus will not be detected at all. This happens with PCIe switches.
|
||||
+ */
|
||||
+ dw_pcie_dbi_ro_wr_en(pci);
|
||||
+ tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
|
||||
+ tmp &= ~PCI_EXP_LNKCAP_SLS;
|
||||
+ tmp |= PCI_EXP_LNKCAP_SLS_2_5GB;
|
||||
+ dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);
|
||||
+ dw_pcie_dbi_ro_wr_dis(pci);
|
||||
+ }
|
||||
|
||||
/* Start LTSSM. */
|
||||
imx6_pcie_ltssm_enable(dev);
|
||||
|
||||
- ret = dw_pcie_wait_for_link(pci);
|
||||
- if (ret)
|
||||
- goto err_reset_phy;
|
||||
+ if ((pci->link_gen > 1) && !(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_GEN1_LAST)) {
|
||||
+ ret = dw_pcie_wait_for_link(pci);
|
||||
+ if (ret)
|
||||
+ goto err_reset_phy;
|
||||
|
||||
- if (pci->link_gen > 1) {
|
||||
/* Allow faster modes after the link is up */
|
||||
dw_pcie_dbi_ro_wr_en(pci);
|
||||
tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
|
||||
@@ -929,18 +932,14 @@ static int imx6_pcie_start_link(struct d
|
||||
goto err_reset_phy;
|
||||
}
|
||||
}
|
||||
-
|
||||
- /* Make sure link training is finished as well! */
|
||||
- ret = dw_pcie_wait_for_link(pci);
|
||||
- if (ret)
|
||||
- goto err_reset_phy;
|
||||
- } else {
|
||||
- dev_info(dev, "Link: Only Gen1 is enabled\n");
|
||||
}
|
||||
|
||||
+ ret = dw_pcie_wait_for_link(pci);
|
||||
+ if (ret)
|
||||
+ goto err_reset_phy;
|
||||
+
|
||||
imx6_pcie->link_is_up = true;
|
||||
- tmp = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
|
||||
- dev_info(dev, "Link up, Gen%i\n", tmp & PCI_EXP_LNKSTA_CLS);
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_reset_phy:
|
||||
@@ -1505,12 +1504,14 @@ static const struct imx6_pcie_drvdata dr
|
||||
},
|
||||
[IMX8MM] = {
|
||||
.variant = IMX8MM,
|
||||
- .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
+ .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
|
||||
+ IMX6_PCIE_FLAG_GEN1_LAST,
|
||||
.gpr = "fsl,imx8mm-iomuxc-gpr",
|
||||
},
|
||||
[IMX8MP] = {
|
||||
.variant = IMX8MP,
|
||||
- .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
|
||||
+ .flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND |
|
||||
+ IMX6_PCIE_FLAG_GEN1_LAST,
|
||||
.gpr = "fsl,imx8mp-iomuxc-gpr",
|
||||
},
|
||||
[IMX8MQ_EP] = {
|
@ -13,6 +13,7 @@
|
||||
|
||||
aliases {
|
||||
ethernet0 = &gmac0;
|
||||
label-mac-device = &gmac0;
|
||||
led-boot = &led_power_r;
|
||||
led-failsafe = &led_power_r;
|
||||
led-running = &led_power_g;
|
||||
@ -84,6 +85,7 @@
|
||||
default-state = "off";
|
||||
gpios = <&pio 85 GPIO_ACTIVE_LOW>;
|
||||
label = "wifin:green";
|
||||
linux,default-trigger = "phy0tpt";
|
||||
};
|
||||
|
||||
wifin_blue {
|
||||
@ -96,6 +98,7 @@
|
||||
default-state = "off";
|
||||
gpios = <&pio 2 GPIO_ACTIVE_HIGH>;
|
||||
label = "wifia:green";
|
||||
linux,default-trigger = "phy1tpt";
|
||||
};
|
||||
|
||||
wifia_blue {
|
||||
|
@ -288,11 +288,6 @@ CONFIG_MV_XOR=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_DSA_MV88E6XXX=y
|
||||
CONFIG_NET_DSA_TAG_DSA=y
|
||||
CONFIG_NET_DSA_TAG_DSA_COMMON=y
|
||||
CONFIG_NET_DSA_TAG_EDSA=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NET_SWITCHDEV=y
|
||||
|
@ -2,6 +2,7 @@ define Device/glinet_gl-mv1000
|
||||
$(call Device/Default-arm64)
|
||||
DEVICE_VENDOR := GL.iNet
|
||||
DEVICE_MODEL := GL-MV1000
|
||||
DEVICE_PACKAGES += kmod-dsa-mv88e6xxx
|
||||
SOC := armada-3720
|
||||
BOOT_SCRIPT := gl-mv1000
|
||||
endef
|
||||
@ -38,7 +39,7 @@ define Device/globalscale_espressobin-ultra
|
||||
DEVICE_VENDOR := Marvell
|
||||
DEVICE_MODEL := ESPRESSObin
|
||||
DEVICE_VARIANT := Ultra
|
||||
DEVICE_PACKAGES += kmod-i2c-pxa kmod-rtc-pcf8563
|
||||
DEVICE_PACKAGES += kmod-i2c-pxa kmod-rtc-pcf8563 kmod-dsa-mv88e6xxx
|
||||
SOC := armada-3720
|
||||
BOOT_SCRIPT := espressobin
|
||||
endef
|
||||
@ -86,7 +87,7 @@ define Device/methode_udpu
|
||||
KERNEL_LOADADDR := 0x00800000
|
||||
KERNEL_INITRAMFS := kernel-bin | gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
|
||||
KERNEL_INITRAMFS_SUFFIX := .itb
|
||||
DEVICE_PACKAGES += f2fs-tools fdisk kmod-i2c-pxa kmod-hwmon-lm75
|
||||
DEVICE_PACKAGES += f2fs-tools fdisk kmod-i2c-pxa kmod-hwmon-lm75 kmod-dsa-mv88e6xxx
|
||||
DEVICE_IMG_NAME = $$(DEVICE_IMG_PREFIX)-$$(2)
|
||||
IMAGES := firmware.tgz
|
||||
IMAGE/firmware.tgz := boot-scr | boot-img-ext4 | uDPU-firmware | append-metadata
|
||||
|
@ -15,6 +15,7 @@ define Device/globalscale_mochabin
|
||||
$(call Device/Default-arm64)
|
||||
DEVICE_VENDOR := Globalscale
|
||||
DEVICE_MODEL := MOCHAbin
|
||||
DEVICE_PACKAGES += kmod-dsa-mv88e6xxx
|
||||
SOC := armada-7040
|
||||
endef
|
||||
TARGET_DEVICES += globalscale_mochabin
|
||||
@ -74,7 +75,7 @@ define Device/mikrotik_rb5009
|
||||
DEVICE_MODEL := RB5009
|
||||
SOC := armada-7040
|
||||
KERNEL_LOADADDR := 0x22000000
|
||||
DEVICE_PACKAGES += kmod-i2c-gpio yafut
|
||||
DEVICE_PACKAGES += kmod-i2c-gpio yafut kmod-dsa-mv88e6xxx
|
||||
endef
|
||||
TARGET_DEVICES += mikrotik_rb5009
|
||||
|
||||
@ -112,7 +113,7 @@ define Device/solidrun_clearfog-pro
|
||||
SOC := cn9130
|
||||
DEVICE_VENDOR := SolidRun
|
||||
DEVICE_MODEL := ClearFog Pro
|
||||
DEVICE_PACKAGES += kmod-i2c-mux-pca954x
|
||||
DEVICE_PACKAGES += kmod-i2c-mux-pca954x kmod-dsa-mv88e6xxx
|
||||
BOOT_SCRIPT := clearfog-pro
|
||||
endef
|
||||
TARGET_DEVICES += solidrun_clearfog-pro
|
||||
|
@ -108,7 +108,7 @@ define Device/cznic_turris-omnia
|
||||
wpad-basic-openssl kmod-ath9k kmod-ath10k-ct ath10k-firmware-qca988x-ct \
|
||||
kmod-mt7915-firmware partx-utils kmod-i2c-mux-pca954x kmod-leds-turris-omnia \
|
||||
kmod-turris-omnia-mcu kmod-gpio-button-hotplug omnia-eeprom omnia-mcu-firmware \
|
||||
omnia-mcutool
|
||||
omnia-mcutool kmod-dsa-mv88e6xxx
|
||||
IMAGES := sysupgrade.img.gz
|
||||
IMAGE/sysupgrade.img.gz := boot-scr | boot-img | sdcard-img | gzip | append-metadata
|
||||
SUPPORTED_DEVICES += armada-385-turris-omnia
|
||||
@ -123,7 +123,7 @@ define Device/fortinet
|
||||
KERNEL_SIZE := 6144k
|
||||
IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \
|
||||
sysupgrade-tar rootfs=$$$$@ | append-metadata
|
||||
DEVICE_PACKAGES := kmod-hwmon-nct7802
|
||||
DEVICE_PACKAGES := kmod-hwmon-nct7802 kmod-dsa-mv88e6xxx
|
||||
endef
|
||||
|
||||
define Device/fortinet_fg-30e
|
||||
@ -202,7 +202,7 @@ define Device/iij_sa-w2
|
||||
IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | \
|
||||
append-rootfs | pad-rootfs | check-size | append-metadata
|
||||
DEVICE_PACKAGES := kmod-ath9k kmod-ath10k-ct ath10k-firmware-qca988x-ct \
|
||||
wpad-basic-mbedtls
|
||||
wpad-basic-mbedtls kmod-dsa-mv88e6xxx
|
||||
endef
|
||||
TARGET_DEVICES += iij_sa-w2
|
||||
|
||||
@ -251,7 +251,7 @@ define Device/linksys_wrt1200ac
|
||||
DEVICE_ALT0_VENDOR := Linksys
|
||||
DEVICE_ALT0_MODEL := Caiman
|
||||
DEVICE_DTS := armada-385-linksys-caiman
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864 kmod-dsa-mv88e6xxx
|
||||
SUPPORTED_DEVICES += armada-385-linksys-caiman linksys,caiman
|
||||
endef
|
||||
TARGET_DEVICES += linksys_wrt1200ac
|
||||
@ -267,7 +267,7 @@ define Device/linksys_wrt1900acs
|
||||
DEVICE_ALT1_VENDOR := Linksys
|
||||
DEVICE_ALT1_MODEL := Shelby
|
||||
DEVICE_DTS := armada-385-linksys-shelby
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864 kmod-dsa-mv88e6xxx
|
||||
SUPPORTED_DEVICES += armada-385-linksys-shelby linksys,shelby
|
||||
endef
|
||||
TARGET_DEVICES += linksys_wrt1900acs
|
||||
@ -280,7 +280,7 @@ define Device/linksys_wrt1900ac-v1
|
||||
DEVICE_ALT0_VENDOR := Linksys
|
||||
DEVICE_ALT0_MODEL := Mamba
|
||||
DEVICE_DTS := armada-xp-linksys-mamba
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864 kmod-dsa-mv88e6xxx
|
||||
KERNEL_SIZE := 4096k
|
||||
SUPPORTED_DEVICES += armada-xp-linksys-mamba linksys,mamba
|
||||
endef
|
||||
@ -294,7 +294,7 @@ define Device/linksys_wrt1900ac-v2
|
||||
DEVICE_ALT0_VENDOR := Linksys
|
||||
DEVICE_ALT0_MODEL := Cobra
|
||||
DEVICE_DTS := armada-385-linksys-cobra
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864
|
||||
DEVICE_PACKAGES += mwlwifi-firmware-88w8864 kmod-dsa-mv88e6xxx
|
||||
SUPPORTED_DEVICES += armada-385-linksys-cobra linksys,cobra
|
||||
endef
|
||||
TARGET_DEVICES += linksys_wrt1900ac-v2
|
||||
@ -306,7 +306,8 @@ define Device/linksys_wrt3200acm
|
||||
DEVICE_ALT0_VENDOR := Linksys
|
||||
DEVICE_ALT0_MODEL := Rango
|
||||
DEVICE_DTS := armada-385-linksys-rango
|
||||
DEVICE_PACKAGES += kmod-btmrvl kmod-mwifiex-sdio mwlwifi-firmware-88w8964
|
||||
DEVICE_PACKAGES += kmod-btmrvl kmod-mwifiex-sdio mwlwifi-firmware-88w8964 \
|
||||
kmod-dsa-mv88e6xxx
|
||||
SUPPORTED_DEVICES += armada-385-linksys-rango linksys,rango
|
||||
endef
|
||||
TARGET_DEVICES += linksys_wrt3200acm
|
||||
@ -339,6 +340,7 @@ define Device/marvell_a370-rd
|
||||
DEVICE_VENDOR := Marvell
|
||||
DEVICE_MODEL := Armada 370 RD (RD-88F6710-A1)
|
||||
DEVICE_DTS := armada-370-rd
|
||||
DEVICE_PACKAGES += kmod-dsa-mv88e6xxx
|
||||
SUPPORTED_DEVICES += armada-370-rd
|
||||
endef
|
||||
TARGET_DEVICES += marvell_a370-rd
|
||||
|
@ -92,6 +92,7 @@ define Device/ubnt_unifi-usg
|
||||
DEVICE_PACKAGES += kmod-gpio-button-hotplug kmod-leds-gpio
|
||||
DEVICE_DTS := cn5020_ubnt_usg
|
||||
KERNEL += | append-dtb-to-elf
|
||||
SUPPORTED_DEVICES += ubnt,usg
|
||||
endef
|
||||
TARGET_DEVICES += ubnt_unifi-usg
|
||||
|
||||
|
@ -257,13 +257,6 @@ CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
|
||||
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_DSA_MV88E6XXX=y
|
||||
CONFIG_NET_DSA_TAG_DSA=y
|
||||
CONFIG_NET_DSA_TAG_DSA_COMMON=y
|
||||
CONFIG_NET_DSA_TAG_EDSA=y
|
||||
CONFIG_NET_DSA_TAG_OCELOT=y
|
||||
CONFIG_NET_DSA_TAG_TRAILER=y
|
||||
CONFIG_NET_EGRESS=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
|
@ -7,7 +7,7 @@ define Device/watchguard_firebox-m300
|
||||
DEVICE_DTS_DIR := $(DTS_DIR)/fsl
|
||||
DEVICE_PACKAGES := \
|
||||
kmod-gpio-button-hotplug kmod-hwmon-w83793 kmod-leds-gpio kmod-ptp-qoriq \
|
||||
kmod-rtc-rs5c372a kmod-tpm-i2c-atmel
|
||||
kmod-rtc-rs5c372a kmod-tpm-i2c-atmel kmod-dsa-mv88e6xxx
|
||||
KERNEL := kernel-bin | gzip | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
|
||||
KERNEL_SUFFIX := -fit-uImage.itb
|
||||
IMAGES := sdcard.img.gz sysupgrade.img.gz
|
||||
|
@ -137,6 +137,27 @@
|
||||
reg = <28>;
|
||||
reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
|
||||
reset-deassert-us = <10000>;
|
||||
|
||||
leds {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
color = <LED_COLOR_ID_YELLOW>;
|
||||
function = LED_FUNCTION_WAN;
|
||||
default-state = "keep";
|
||||
active-low;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_WAN;
|
||||
default-state = "keep";
|
||||
active-low;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,8 @@ asus,rt-ax89x)
|
||||
ucidef_set_led_netdev "sfp" "SFP" "white:sfp" "10g-sfp"
|
||||
ucidef_set_led_netdev "wan" "WAN" "white:wan" "wan"
|
||||
;;
|
||||
dynalink,dl-wrx36)
|
||||
dynalink,dl-wrx36|\
|
||||
spectrum,sax1v1k)
|
||||
ucidef_set_led_netdev "wan-port-link-green" "WAN-PORT-LINK-GREEN" "90000.mdio-1:1c:green:wan" "wan" "link_2500"
|
||||
ucidef_set_led_netdev "wan-port-link-yellow" "WAN-PORT-LINK-YELLOW" "90000.mdio-1:1c:yellow:wan" "wan" "tx rx link_10 link_100 link_1000"
|
||||
;;
|
||||
|
20
target/linux/qualcommbe/Makefile
Normal file
20
target/linux/qualcommbe/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=aarch64
|
||||
BOARD:=qualcommbe
|
||||
BOARDNAME:=Qualcomm Atheros 802.11be WiSoC-s
|
||||
FEATURES:=squashfs ramdisk fpu nand rtc emmc source-only
|
||||
KERNELNAME:=Image
|
||||
CPU_TYPE:=cortex-a53
|
||||
SUBTARGETS:=ipq95xx
|
||||
|
||||
KERNEL_PATCHVER:=6.6
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
DEFAULT_PACKAGES += \
|
||||
kmod-leds-gpio kmod-gpio-button-hotplug \
|
||||
kmod-qca-nss-dp \
|
||||
wpad-openssl uboot-envtools \
|
||||
e2fsprogs kmod-fs-ext4 losetup
|
||||
|
||||
$(eval $(call BuildTarget))
|
579
target/linux/qualcommbe/config-6.6
Normal file
579
target/linux/qualcommbe/config-6.6
Normal file
@ -0,0 +1,579 @@
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
|
||||
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
|
||||
CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_FORCE_MAX_ORDER=10
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_KEEP_MEMBLOCK=y
|
||||
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=18
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
|
||||
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
|
||||
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
|
||||
CONFIG_ARCH_PROC_KCORE_TEXT=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
CONFIG_ARCH_STACKWALK=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WANTS_NO_INSTR=y
|
||||
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||
CONFIG_ARM64=y
|
||||
CONFIG_ARM64_4K_PAGES=y
|
||||
CONFIG_ARM64_ERRATUM_1165522=y
|
||||
CONFIG_ARM64_ERRATUM_1286807=y
|
||||
CONFIG_ARM64_ERRATUM_2051678=y
|
||||
CONFIG_ARM64_ERRATUM_2054223=y
|
||||
CONFIG_ARM64_ERRATUM_2067961=y
|
||||
CONFIG_ARM64_ERRATUM_2077057=y
|
||||
CONFIG_ARM64_ERRATUM_2658417=y
|
||||
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||
CONFIG_ARM64_PAGE_SHIFT=12
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
CONFIG_ARM64_PA_BITS_48=y
|
||||
CONFIG_ARM64_PTR_AUTH=y
|
||||
CONFIG_ARM64_PTR_AUTH_KERNEL=y
|
||||
CONFIG_ARM64_SME=y
|
||||
CONFIG_ARM64_SVE=y
|
||||
CONFIG_ARM64_TAGGED_ADDR_ABI=y
|
||||
CONFIG_ARM64_VA_BITS=39
|
||||
CONFIG_ARM64_VA_BITS_39=y
|
||||
CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
|
||||
CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
|
||||
CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
|
||||
CONFIG_ARM_AMBA=y
|
||||
CONFIG_ARM_ARCH_TIMER=y
|
||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARM_GIC_V2M=y
|
||||
CONFIG_ARM_GIC_V3=y
|
||||
CONFIG_ARM_GIC_V3_ITS=y
|
||||
CONFIG_ARM_GIC_V3_ITS_PCI=y
|
||||
# CONFIG_ARM_MHU_V2 is not set
|
||||
CONFIG_ARM_PSCI_CPUIDLE=y
|
||||
CONFIG_ARM_PSCI_FW=y
|
||||
# CONFIG_ARM_QCOM_CPUFREQ_HW is not set
|
||||
CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLK_MQ_VIRTIO=y
|
||||
CONFIG_BLK_PM=y
|
||||
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
|
||||
CONFIG_CAVIUM_TX2_ERRATUM_219=y
|
||||
CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
|
||||
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMMON_CLK_QCOM=y
|
||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
|
||||
# CONFIG_COMPAT_32BIT_TIME is not set
|
||||
CONFIG_CONTEXT_TRACKING=y
|
||||
CONFIG_CONTEXT_TRACKING_IDLE=y
|
||||
CONFIG_COREDUMP=y
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_CPUFREQ_DT_PLATDEV=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
|
||||
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
|
||||
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
|
||||
# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_THERMAL=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_CPU_IDLE_GOV_MENU=y
|
||||
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
|
||||
CONFIG_CPU_LITTLE_ENDIAN=y
|
||||
CONFIG_CPU_PM=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC8=y
|
||||
CONFIG_CRYPTO_AUTHENC=y
|
||||
CONFIG_CRYPTO_CBC=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_DEV_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCE_AEAD=y
|
||||
# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set
|
||||
CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y
|
||||
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set
|
||||
# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set
|
||||
CONFIG_CRYPTO_DEV_QCE_SHA=y
|
||||
CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y
|
||||
CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512
|
||||
CONFIG_CRYPTO_DEV_QCOM_RNG=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
CONFIG_CRYPTO_HASH_INFO=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
|
||||
CONFIG_CRYPTO_LIB_DES=y
|
||||
CONFIG_CRYPTO_LIB_GF128MUL=y
|
||||
CONFIG_CRYPTO_LIB_SHA1=y
|
||||
CONFIG_CRYPTO_LIB_SHA256=y
|
||||
CONFIG_CRYPTO_LIB_UTILS=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_RNG=y
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_SHA1=y
|
||||
CONFIG_CRYPTO_SHA256=y
|
||||
CONFIG_CRYPTO_XTS=y
|
||||
CONFIG_CRYPTO_ZSTD=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEV_COREDUMP=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC=y
|
||||
CONFIG_DMA_DIRECT_REMAP=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DT_IDLE_STATES=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_FS_IOMAP=y
|
||||
CONFIG_FUJITSU_ERRATUM_010001=y
|
||||
CONFIG_FUNCTION_ALIGNMENT=4
|
||||
CONFIG_FUNCTION_ALIGNMENT_4B=y
|
||||
CONFIG_FWNODE_MDIO=y
|
||||
CONFIG_FW_LOADER_PAGED_BUF=y
|
||||
CONFIG_FW_LOADER_SYSFS=y
|
||||
CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
|
||||
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_ARCH_TOPOLOGY=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
CONFIG_GENERIC_CSUM=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_GETTIMEOFDAY=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IOREMAP=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_PINCONF=y
|
||||
CONFIG_GENERIC_PINCTRL_GROUPS=y
|
||||
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GLOB=y
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
CONFIG_GPIO_CDEV=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_HELPER_AUTO=y
|
||||
# CONFIG_I2C_QCOM_CCI is not set
|
||||
CONFIG_I2C_QUP=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IPQ_APSS_6018=y
|
||||
CONFIG_IPQ_APSS_PLL=y
|
||||
# CONFIG_IPQ_GCC_4019 is not set
|
||||
# CONFIG_IPQ_GCC_5018 is not set
|
||||
# CONFIG_IPQ_GCC_5332 is not set
|
||||
# CONFIG_IPQ_GCC_6018 is not set
|
||||
# CONFIG_IPQ_GCC_8074 is not set
|
||||
# CONFIG_IPQ_GCC_9574 is not set
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
# CONFIG_KPSS_XCC is not set
|
||||
CONFIG_LEDS_TLC591XX=y
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
CONFIG_MAILBOX=y
|
||||
# CONFIG_MAILBOX_TEST is not set
|
||||
CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MDIO_IPQ4019=y
|
||||
# CONFIG_MFD_QCOM_RPM is not set
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIGRATION=y
|
||||
# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_CQHCI=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
# CONFIG_MMC_SDHCI_PCI is not set
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
# CONFIG_MSM_GCC_8916 is not set
|
||||
# CONFIG_MSM_GCC_8917 is not set
|
||||
# CONFIG_MSM_GCC_8939 is not set
|
||||
# CONFIG_MSM_GCC_8976 is not set
|
||||
# CONFIG_MSM_GCC_8994 is not set
|
||||
# CONFIG_MSM_GCC_8996 is not set
|
||||
# CONFIG_MSM_GCC_8998 is not set
|
||||
# CONFIG_MSM_GPUCC_8998 is not set
|
||||
# CONFIG_MSM_MMCC_8996 is not set
|
||||
# CONFIG_MSM_MMCC_8998 is not set
|
||||
CONFIG_MTD_NAND_CORE=y
|
||||
CONFIG_MTD_NAND_ECC=y
|
||||
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
|
||||
CONFIG_MTD_NAND_QCOM=y
|
||||
CONFIG_MTD_QCOMSMEM_PARTS=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_UBI=y
|
||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
CONFIG_MTD_UBI_BLOCK=y
|
||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NET_EGRESS=y
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
CONFIG_NET_SELFTESTS=y
|
||||
CONFIG_NET_SWITCHDEV=y
|
||||
CONFIG_NET_XGRESS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_LAYOUTS=y
|
||||
CONFIG_NVMEM_QCOM_QFPROM=y
|
||||
# CONFIG_NVMEM_QCOM_SEC_QFPROM is not set
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_NVMEM_U_BOOT_ENV=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_KOBJ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_PADATA=y
|
||||
CONFIG_PAGE_POOL=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
|
||||
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
|
||||
CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
|
||||
CONFIG_PARTITION_PERCPU=y
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEASPM=y
|
||||
CONFIG_PCIEASPM_DEFAULT=y
|
||||
# CONFIG_PCIEASPM_PERFORMANCE is not set
|
||||
# CONFIG_PCIEASPM_POWERSAVE is not set
|
||||
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIE_DW=y
|
||||
CONFIG_PCIE_DW_HOST=y
|
||||
CONFIG_PCIE_PME=y
|
||||
CONFIG_PCIE_QCOM=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PER_VMA_LOCK=y
|
||||
CONFIG_PGTABLE_LEVELS=3
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYLIB_LEDS=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
# CONFIG_PHY_QCOM_APQ8064_SATA is not set
|
||||
# CONFIG_PHY_QCOM_EDP is not set
|
||||
# CONFIG_PHY_QCOM_EUSB2_REPEATER is not set
|
||||
# CONFIG_PHY_QCOM_IPQ4019_USB is not set
|
||||
# CONFIG_PHY_QCOM_IPQ806X_SATA is not set
|
||||
# CONFIG_PHY_QCOM_IPQ806X_USB is not set
|
||||
# CONFIG_PHY_QCOM_M31_USB is not set
|
||||
# CONFIG_PHY_QCOM_PCIE2 is not set
|
||||
CONFIG_PHY_QCOM_QMP=y
|
||||
CONFIG_PHY_QCOM_QMP_COMBO=y
|
||||
CONFIG_PHY_QCOM_QMP_PCIE=y
|
||||
CONFIG_PHY_QCOM_QMP_PCIE_8996=y
|
||||
CONFIG_PHY_QCOM_QMP_UFS=y
|
||||
CONFIG_PHY_QCOM_QMP_USB=y
|
||||
# CONFIG_PHY_QCOM_QMP_USB_LEGACY is not set
|
||||
CONFIG_PHY_QCOM_QUSB2=y
|
||||
# CONFIG_PHY_QCOM_SGMII_ETH is not set
|
||||
# CONFIG_PHY_QCOM_SNPS_EUSB2 is not set
|
||||
# CONFIG_PHY_QCOM_USB_HS_28NM is not set
|
||||
# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set
|
||||
# CONFIG_PHY_QCOM_USB_SS is not set
|
||||
CONFIG_PINCTRL=y
|
||||
# CONFIG_PINCTRL_IPQ5018 is not set
|
||||
# CONFIG_PINCTRL_IPQ5332 is not set
|
||||
# CONFIG_PINCTRL_IPQ6018 is not set
|
||||
# CONFIG_PINCTRL_IPQ8074 is not set
|
||||
# CONFIG_PINCTRL_IPQ9574 is not set
|
||||
CONFIG_PINCTRL_MSM=y
|
||||
# CONFIG_PINCTRL_MSM8916 is not set
|
||||
# CONFIG_PINCTRL_MSM8976 is not set
|
||||
# CONFIG_PINCTRL_MSM8994 is not set
|
||||
# CONFIG_PINCTRL_MSM8996 is not set
|
||||
# CONFIG_PINCTRL_MSM8998 is not set
|
||||
# CONFIG_PINCTRL_QCM2290 is not set
|
||||
# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set
|
||||
# CONFIG_PINCTRL_QCS404 is not set
|
||||
# CONFIG_PINCTRL_QDU1000 is not set
|
||||
# CONFIG_PINCTRL_SA8775P is not set
|
||||
# CONFIG_PINCTRL_SC7180 is not set
|
||||
# CONFIG_PINCTRL_SC8280XP is not set
|
||||
# CONFIG_PINCTRL_SDM660 is not set
|
||||
# CONFIG_PINCTRL_SDM670 is not set
|
||||
# CONFIG_PINCTRL_SDM845 is not set
|
||||
# CONFIG_PINCTRL_SDX75 is not set
|
||||
# CONFIG_PINCTRL_SM6350 is not set
|
||||
# CONFIG_PINCTRL_SM6375 is not set
|
||||
# CONFIG_PINCTRL_SM7150 is not set
|
||||
# CONFIG_PINCTRL_SM8150 is not set
|
||||
# CONFIG_PINCTRL_SM8250 is not set
|
||||
# CONFIG_PINCTRL_SM8450 is not set
|
||||
# CONFIG_PINCTRL_SM8550 is not set
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_CLK=y
|
||||
CONFIG_PM_OPP=y
|
||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
CONFIG_POWER_RESET=y
|
||||
# CONFIG_POWER_RESET_MSM is not set
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_PREEMPT_NONE_BUILD=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
|
||||
CONFIG_QCA807X_PHY=y
|
||||
CONFIG_QCA808X_PHY=y
|
||||
# CONFIG_QCM_DISPCC_2290 is not set
|
||||
# CONFIG_QCM_GCC_2290 is not set
|
||||
# CONFIG_QCOM_A53PLL is not set
|
||||
# CONFIG_QCOM_AOSS_QMP is not set
|
||||
CONFIG_QCOM_APCS_IPC=y
|
||||
# CONFIG_QCOM_APM is not set
|
||||
# CONFIG_QCOM_APR is not set
|
||||
CONFIG_QCOM_BAM_DMA=y
|
||||
# CONFIG_QCOM_CLK_APCC_MSM8996 is not set
|
||||
# CONFIG_QCOM_CLK_APCS_MSM8916 is not set
|
||||
# CONFIG_QCOM_COMMAND_DB is not set
|
||||
# CONFIG_QCOM_CPR is not set
|
||||
# CONFIG_QCOM_EBI2 is not set
|
||||
# CONFIG_QCOM_FASTRPC is not set
|
||||
# CONFIG_QCOM_GENI_SE is not set
|
||||
# CONFIG_QCOM_GSBI is not set
|
||||
# CONFIG_QCOM_HFPLL is not set
|
||||
# CONFIG_QCOM_ICC_BWMON is not set
|
||||
# CONFIG_QCOM_IPCC is not set
|
||||
# CONFIG_QCOM_LLCC is not set
|
||||
CONFIG_QCOM_MDT_LOADER=y
|
||||
# CONFIG_QCOM_MPM is not set
|
||||
CONFIG_QCOM_NET_PHYLIB=y
|
||||
# CONFIG_QCOM_OCMEM is not set
|
||||
# CONFIG_QCOM_PDC is not set
|
||||
CONFIG_QCOM_PIL_INFO=y
|
||||
# CONFIG_QCOM_Q6V5_ADSP is not set
|
||||
CONFIG_QCOM_Q6V5_COMMON=y
|
||||
# CONFIG_QCOM_Q6V5_MSS is not set
|
||||
# CONFIG_QCOM_Q6V5_PAS is not set
|
||||
CONFIG_QCOM_Q6V5_WCSS=y
|
||||
# CONFIG_QCOM_RAMP_CTRL is not set
|
||||
# CONFIG_QCOM_RMTFS_MEM is not set
|
||||
# CONFIG_QCOM_RPMH is not set
|
||||
# CONFIG_QCOM_RPM_MASTER_STATS is not set
|
||||
CONFIG_QCOM_RPROC_COMMON=y
|
||||
CONFIG_QCOM_SCM=y
|
||||
# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
|
||||
# CONFIG_QCOM_SMD_RPM is not set
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMEM_STATE=y
|
||||
CONFIG_QCOM_SMP2P=y
|
||||
# CONFIG_QCOM_SMSM is not set
|
||||
CONFIG_QCOM_SOCINFO=y
|
||||
# CONFIG_QCOM_SPM is not set
|
||||
# CONFIG_QCOM_STATS is not set
|
||||
# CONFIG_QCOM_SYSMON is not set
|
||||
CONFIG_QCOM_TSENS=y
|
||||
# CONFIG_QCOM_WCNSS_CTRL is not set
|
||||
# CONFIG_QCOM_WCNSS_PIL is not set
|
||||
CONFIG_QCOM_WDT=y
|
||||
# CONFIG_QCS_GCC_404 is not set
|
||||
# CONFIG_QCS_Q6SSTOP_404 is not set
|
||||
# CONFIG_QCS_TURING_404 is not set
|
||||
# CONFIG_QDU_GCC_1000 is not set
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
CONFIG_RANDSTRUCT_NONE=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_I2C=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGULATOR=y
|
||||
# CONFIG_REGULATOR_CPR3 is not set
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
# CONFIG_REGULATOR_QCOM_REFGEN is not set
|
||||
# CONFIG_REGULATOR_VQMMC_IPQ4019 is not set
|
||||
CONFIG_RELOCATABLE=y
|
||||
CONFIG_REMOTEPROC=y
|
||||
CONFIG_REMOTEPROC_CDEV=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
# CONFIG_RESET_QCOM_AOSS is not set
|
||||
# CONFIG_RESET_QCOM_PDC is not set
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
|
||||
CONFIG_RPMSG=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
# CONFIG_RPMSG_CTRL is not set
|
||||
# CONFIG_RPMSG_NS is not set
|
||||
CONFIG_RPMSG_QCOM_GLINK=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
CONFIG_RPMSG_QCOM_SMD=y
|
||||
# CONFIG_RPMSG_TTY is not set
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
# CONFIG_SA_GCC_8775P is not set
|
||||
# CONFIG_SA_GPUCC_8775P is not set
|
||||
# CONFIG_SCHED_CORE is not set
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_SCHED_THERMAL_PRESSURE=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SCSI_COMMON=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
# CONFIG_SC_CAMCC_7280 is not set
|
||||
# CONFIG_SC_DISPCC_7180 is not set
|
||||
# CONFIG_SC_DISPCC_8280XP is not set
|
||||
# CONFIG_SC_GCC_7180 is not set
|
||||
# CONFIG_SC_GCC_8280XP is not set
|
||||
# CONFIG_SC_GPUCC_7180 is not set
|
||||
# CONFIG_SC_LPASSCC_7280 is not set
|
||||
# CONFIG_SC_LPASSCC_8280XP is not set
|
||||
# CONFIG_SC_LPASS_CORECC_7180 is not set
|
||||
# CONFIG_SC_LPASS_CORECC_7280 is not set
|
||||
# CONFIG_SC_MSS_7180 is not set
|
||||
# CONFIG_SC_VIDEOCC_7180 is not set
|
||||
# CONFIG_SDM_CAMCC_845 is not set
|
||||
# CONFIG_SDM_DISPCC_845 is not set
|
||||
# CONFIG_SDM_GCC_660 is not set
|
||||
# CONFIG_SDM_GCC_845 is not set
|
||||
# CONFIG_SDM_GPUCC_845 is not set
|
||||
# CONFIG_SDM_LPASSCC_845 is not set
|
||||
# CONFIG_SDM_VIDEOCC_845 is not set
|
||||
# CONFIG_SDX_GCC_75 is not set
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_MSM=y
|
||||
CONFIG_SERIAL_MSM_CONSOLE=y
|
||||
CONFIG_SGL_ALLOC=y
|
||||
CONFIG_SG_POOL=y
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_SM_CAMCC_6350 is not set
|
||||
# CONFIG_SM_CAMCC_8450 is not set
|
||||
# CONFIG_SM_GCC_7150 is not set
|
||||
# CONFIG_SM_GCC_8150 is not set
|
||||
# CONFIG_SM_GCC_8250 is not set
|
||||
# CONFIG_SM_GCC_8450 is not set
|
||||
# CONFIG_SM_GCC_8550 is not set
|
||||
# CONFIG_SM_GPUCC_6115 is not set
|
||||
# CONFIG_SM_GPUCC_6125 is not set
|
||||
# CONFIG_SM_GPUCC_6350 is not set
|
||||
# CONFIG_SM_GPUCC_6375 is not set
|
||||
# CONFIG_SM_GPUCC_8150 is not set
|
||||
# CONFIG_SM_GPUCC_8250 is not set
|
||||
# CONFIG_SM_GPUCC_8350 is not set
|
||||
# CONFIG_SM_GPUCC_8450 is not set
|
||||
# CONFIG_SM_GPUCC_8550 is not set
|
||||
# CONFIG_SM_TCSRCC_8550 is not set
|
||||
# CONFIG_SM_VIDEOCC_8150 is not set
|
||||
# CONFIG_SM_VIDEOCC_8250 is not set
|
||||
# CONFIG_SM_VIDEOCC_8350 is not set
|
||||
# CONFIG_SM_VIDEOCC_8450 is not set
|
||||
# CONFIG_SM_VIDEOCC_8550 is not set
|
||||
CONFIG_SOCK_RX_QUEUE_MAPPING=y
|
||||
CONFIG_SOC_BUS=y
|
||||
CONFIG_SOFTIRQ_ON_OWN_STACK=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_SPARSEMEM_EXTREME=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_SPI_QUP=y
|
||||
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SYSCTL_EXCEPTION_TRACE=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_OF=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_OF=y
|
||||
CONFIG_TIMER_PROBE=y
|
||||
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_UBIFS_FS=y
|
||||
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
|
||||
# CONFIG_UCLAMP_TASK is not set
|
||||
CONFIG_UNMAP_KERNEL_AT_EL0=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_VIRTIO=y
|
||||
CONFIG_VIRTIO_ANCHOR=y
|
||||
# CONFIG_VIRTIO_BLK is not set
|
||||
# CONFIG_VIRTIO_NET is not set
|
||||
CONFIG_VMAP_STACK=y
|
||||
CONFIG_WANT_DEV_COREDUMP=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WATCHDOG_SYSFS=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_XXHASH=y
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_ZONE_DMA32=y
|
||||
CONFIG_ZSTD_COMMON=y
|
||||
CONFIG_ZSTD_COMPRESS=y
|
||||
CONFIG_ZSTD_DECOMPRESS=y
|
41
target/linux/qualcommbe/image/Makefile
Normal file
41
target/linux/qualcommbe/image/Makefile
Normal file
@ -0,0 +1,41 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
define Device/Default
|
||||
PROFILES := Default
|
||||
KERNEL_LOADADDR := 0x41000000
|
||||
DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1)))
|
||||
DEVICE_DTS_CONFIG := config@1
|
||||
DEVICE_DTS_DIR := $(DTS_DIR)/qcom
|
||||
IMAGES := sysupgrade.bin
|
||||
IMAGE/sysupgrade.bin = sysupgrade-tar | append-metadata
|
||||
IMAGE/sysupgrade.bin/squashfs :=
|
||||
endef
|
||||
|
||||
define Device/FitImage
|
||||
KERNEL_SUFFIX := -uImage.itb
|
||||
KERNEL = kernel-bin | libdeflate-gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
|
||||
KERNEL_NAME := Image
|
||||
endef
|
||||
|
||||
define Device/FitImageLzma
|
||||
KERNEL_SUFFIX := -uImage.itb
|
||||
KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb
|
||||
KERNEL_NAME := Image
|
||||
endef
|
||||
|
||||
define Device/EmmcImage
|
||||
IMAGES += factory.bin
|
||||
IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k
|
||||
IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to 64k | sysupgrade-tar rootfs=$$$$@ | append-metadata
|
||||
endef
|
||||
|
||||
define Device/UbiFit
|
||||
KERNEL_IN_UBI := 1
|
||||
IMAGES += factory.ubi
|
||||
IMAGE/factory.ubi := append-ubi
|
||||
endef
|
||||
|
||||
include $(SUBTARGET).mk
|
||||
|
||||
$(eval $(call BuildImage))
|
14
target/linux/qualcommbe/image/ipq95xx.mk
Normal file
14
target/linux/qualcommbe/image/ipq95xx.mk
Normal file
@ -0,0 +1,14 @@
|
||||
define Device/qcom_rdp433
|
||||
$(call Device/FitImageLzma)
|
||||
DEVICE_VENDOR := Qualcomm Technologies, Inc.
|
||||
DEVICE_MODEL := RDP433
|
||||
DEVICE_VARIANT := AP-AL02-C4
|
||||
BOARD_NAME := ap-al02.1-c4
|
||||
DEVICE_DTS_CONFIG := config@rdp433
|
||||
SOC := ipq9574
|
||||
KERNEL_INSTALL := 1
|
||||
KERNEL_SIZE := 6096k
|
||||
IMAGE_SIZE := 25344k
|
||||
IMAGE/sysupgrade.bin := append-kernel | pad-to 64k | append-rootfs | pad-rootfs | check-size | append-metadata
|
||||
endef
|
||||
TARGET_DEVICES += qcom_rdp433
|
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright (c) 2015 The Linux Foundation. All rights reserved.
|
||||
# Copyright (c) 2011-2015 OpenWrt.org
|
||||
#
|
||||
|
||||
. /lib/functions/uci-defaults.sh
|
||||
. /lib/functions/system.sh
|
||||
|
||||
ipq95xx_setup_interfaces()
|
||||
{
|
||||
local board="$1"
|
||||
|
||||
case "$board" in
|
||||
qcom,ipq9574-ap-al02-c7)
|
||||
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 lan5" "wan"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported hardware. Network interfaces not initialized"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
board_config_update
|
||||
board=$(board_name)
|
||||
ipq95xx_setup_interfaces $board
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
@ -0,0 +1,12 @@
|
||||
PART_NAME=firmware
|
||||
|
||||
RAMFS_COPY_BIN='fw_printenv fw_setenv head'
|
||||
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
|
||||
|
||||
platform_do_upgrade() {
|
||||
case "$(board_name)" in
|
||||
*)
|
||||
default_do_upgrade "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
61
target/linux/qualcommbe/ipq95xx/config-default
Normal file
61
target/linux/qualcommbe/ipq95xx/config-default
Normal file
@ -0,0 +1,61 @@
|
||||
CONFIG_AQUANTIA_PHY=y
|
||||
CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
|
||||
CONFIG_DT_IDLE_GENPD=y
|
||||
CONFIG_GRO_CELLS=y
|
||||
CONFIG_IPQ_GCC_9574=y
|
||||
CONFIG_MDIO_BITBANG=y
|
||||
CONFIG_MDIO_GPIO=y
|
||||
# CONFIG_MFD_HI6421_SPMI is not set
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_NET_DEVLINK=y
|
||||
CONFIG_NET_DSA=y
|
||||
CONFIG_NET_DSA_QCA8K=y
|
||||
CONFIG_NET_DSA_TAG_QCA=y
|
||||
# CONFIG_NVMEM_SPMI_SDAM is not set
|
||||
CONFIG_PHYLINK=y
|
||||
CONFIG_PINCTRL_IPQ9574=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
# CONFIG_PM8916_WATCHDOG is not set
|
||||
CONFIG_PM_GENERIC_DOMAINS=y
|
||||
CONFIG_PM_GENERIC_DOMAINS_OF=y
|
||||
# CONFIG_POWER_RESET_QCOM_PON is not set
|
||||
CONFIG_QCA83XX_PHY=y
|
||||
CONFIG_QCOM_APM=y
|
||||
# CONFIG_QCOM_COINCELL is not set
|
||||
CONFIG_QCOM_GDSC=y
|
||||
CONFIG_QCOM_SPMI_ADC5=y
|
||||
# CONFIG_QCOM_SPMI_RRADC is not set
|
||||
CONFIG_QCOM_VADC_COMMON=y
|
||||
CONFIG_REGMAP_SPMI=y
|
||||
CONFIG_REGULATOR_CPR3=y
|
||||
# CONFIG_REGULATOR_CPR3_NPU is not set
|
||||
CONFIG_REGULATOR_CPR4_APSS=y
|
||||
# CONFIG_REGULATOR_QCOM_LABIBB is not set
|
||||
CONFIG_REGULATOR_QCOM_SPMI=y
|
||||
# CONFIG_REGULATOR_QCOM_USB_VBUS is not set
|
||||
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
|
||||
CONFIG_RTC_DRV_PM8XXX=y
|
||||
CONFIG_SPMI=y
|
||||
# CONFIG_SPMI_HISI3670 is not set
|
||||
CONFIG_SPMI_MSM_PMIC_ARB=y
|
||||
# CONFIG_SPMI_PMIC_CLKDIV is not set
|
||||
CONFIG_SPI_QPIC_SNAND=y
|
||||
CONFIG_IPQ_CMN_PLL=y
|
||||
CONFIG_IPQ_NSSCC_9574=y
|
||||
CONFIG_IPQ_NSSCC_QCA8K=y
|
||||
CONFIG_QCOM_PPE=y
|
||||
CONFIG_QCOM_IPA=y
|
||||
CONFIG_INTERCONNECT_QCOM=y
|
||||
CONFIG_INTERCONNECT_QCOM_OSM_L3=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_REGULATOR_QCOM_SMD_RPM=y
|
||||
# CONFIG_QCOM_CLK_SMD_RPM is not set
|
||||
# CONFIG_QCOM_RPMPD is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_MSM8916 is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_MSM8939 is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_MSM8996 is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_MSM8974 is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_QCM2290 is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_QCS404 is not set
|
||||
# CONFIG_INTERCONNECT_QCOM_SDM660 is not set
|
7
target/linux/qualcommbe/ipq95xx/target.mk
Normal file
7
target/linux/qualcommbe/ipq95xx/target.mk
Normal file
@ -0,0 +1,7 @@
|
||||
SUBTARGET:=ipq95xx
|
||||
BOARDNAME:=Qualcomm Atheros IPQ95xx
|
||||
DEFAULT_PACKAGES +=
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for Qualcomm Atheros IPQ95XX based boards.
|
||||
endef
|
@ -0,0 +1,601 @@
|
||||
From 0e8527d076cfb3fa55777a2ece735852fcf3e850 Mon Sep 17 00:00:00 2001
|
||||
From: Anusha Rao <quic_anusha@quicinc.com>
|
||||
Date: Wed, 27 Sep 2023 12:13:18 +0530
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq9574: Add common RDP dtsi file
|
||||
|
||||
Add a dtsi file to include interfaces that are common
|
||||
across RDPs.
|
||||
|
||||
Signed-off-by: Anusha Rao <quic_anusha@quicinc.com>
|
||||
Signed-off-by: Kathiravan Thirumoorthy <quic_kathirav@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20230927-common-rdp-v3-1-3d07b3ff6d42@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
.../boot/dts/qcom/ipq9574-rdp-common.dtsi | 125 ++++++++++++++++++
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp418.dts | 63 +--------
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 91 +------------
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp449.dts | 65 +--------
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp453.dts | 65 +--------
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp454.dts | 66 +--------
|
||||
6 files changed, 130 insertions(+), 345 deletions(-)
|
||||
create mode 100644 arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
new file mode 100644
|
||||
index 000000000000..40a7aefd0540
|
||||
--- /dev/null
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
@@ -0,0 +1,125 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||||
+/*
|
||||
+ * IPQ9574 RDP board common device tree source
|
||||
+ *
|
||||
+ * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+
|
||||
+#include "ipq9574.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ aliases {
|
||||
+ serial0 = &blsp1_uart2;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ };
|
||||
+
|
||||
+ regulator_fixed_3p3: s3300 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ regulator-name = "fixed_3p3";
|
||||
+ };
|
||||
+
|
||||
+ regulator_fixed_0p925: s0925 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-min-microvolt = <925000>;
|
||||
+ regulator-max-microvolt = <925000>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ regulator-name = "fixed_0p925";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&blsp1_spi0 {
|
||||
+ pinctrl-0 = <&spi_0_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ flash@0 {
|
||||
+ compatible = "micron,n25q128a11", "jedec,spi-nor";
|
||||
+ reg = <0>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ spi-max-frequency = <50000000>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&blsp1_uart2 {
|
||||
+ pinctrl-0 = <&uart2_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&rpm_requests {
|
||||
+ regulators {
|
||||
+ compatible = "qcom,rpm-mp5496-regulators";
|
||||
+
|
||||
+ ipq9574_s1: s1 {
|
||||
+ /*
|
||||
+ * During kernel bootup, the SoC runs at 800MHz with 875mV set by the bootloaders.
|
||||
+ * During regulator registration, kernel not knowing the initial voltage,
|
||||
+ * considers it as zero and brings up the regulators with minimum supported voltage.
|
||||
+ * Update the regulator-min-microvolt with SVS voltage of 725mV so that
|
||||
+ * the regulators are brought up with 725mV which is sufficient for all the
|
||||
+ * corner parts to operate at 800MHz
|
||||
+ */
|
||||
+ regulator-min-microvolt = <725000>;
|
||||
+ regulator-max-microvolt = <1075000>;
|
||||
+ };
|
||||
+
|
||||
+ mp5496_l2: l2 {
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&sleep_clk {
|
||||
+ clock-frequency = <32000>;
|
||||
+};
|
||||
+
|
||||
+&tlmm {
|
||||
+ spi_0_pins: spi-0-state {
|
||||
+ pins = "gpio11", "gpio12", "gpio13", "gpio14";
|
||||
+ function = "blsp0_spi";
|
||||
+ drive-strength = <8>;
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&usb_0_dwc3 {
|
||||
+ dr_mode = "host";
|
||||
+};
|
||||
+
|
||||
+&usb_0_qmpphy {
|
||||
+ vdda-pll-supply = <&mp5496_l2>;
|
||||
+ vdda-phy-supply = <®ulator_fixed_0p925>;
|
||||
+
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb_0_qusbphy {
|
||||
+ vdd-supply = <®ulator_fixed_0p925>;
|
||||
+ vdda-pll-supply = <&mp5496_l2>;
|
||||
+ vdda-phy-dpdm-supply = <®ulator_fixed_3p3>;
|
||||
+
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&usb3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&xo_board_clk {
|
||||
+ clock-frequency = <24000000>;
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp418.dts b/arch/arm64/boot/dts/qcom/ipq9574-rdp418.dts
|
||||
index 2b093e02637b..f4f9199d4ab1 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp418.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp418.dts
|
||||
@@ -8,58 +8,12 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
-#include "ipq9574.dtsi"
|
||||
+#include "ipq9574-rdp-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C2";
|
||||
compatible = "qcom,ipq9574-ap-al02-c2", "qcom,ipq9574";
|
||||
|
||||
- aliases {
|
||||
- serial0 = &blsp1_uart2;
|
||||
- };
|
||||
-
|
||||
- chosen {
|
||||
- stdout-path = "serial0:115200n8";
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_spi0 {
|
||||
- pinctrl-0 = <&spi_0_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-
|
||||
- flash@0 {
|
||||
- compatible = "micron,n25q128a11", "jedec,spi-nor";
|
||||
- reg = <0>;
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <1>;
|
||||
- spi-max-frequency = <50000000>;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_uart2 {
|
||||
- pinctrl-0 = <&uart2_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&rpm_requests {
|
||||
- regulators {
|
||||
- compatible = "qcom,rpm-mp5496-regulators";
|
||||
-
|
||||
- ipq9574_s1: s1 {
|
||||
- /*
|
||||
- * During kernel bootup, the SoC runs at 800MHz with 875mV set by the bootloaders.
|
||||
- * During regulator registration, kernel not knowing the initial voltage,
|
||||
- * considers it as zero and brings up the regulators with minimum supported voltage.
|
||||
- * Update the regulator-min-microvolt with SVS voltage of 725mV so that
|
||||
- * the regulators are brought up with 725mV which is sufficient for all the
|
||||
- * corner parts to operate at 800MHz
|
||||
- */
|
||||
- regulator-min-microvolt = <725000>;
|
||||
- regulator-max-microvolt = <1075000>;
|
||||
- };
|
||||
- };
|
||||
};
|
||||
|
||||
&sdhc_1 {
|
||||
@@ -74,10 +28,6 @@ &sdhc_1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
-&sleep_clk {
|
||||
- clock-frequency = <32000>;
|
||||
-};
|
||||
-
|
||||
&tlmm {
|
||||
sdc_default_state: sdc-default-state {
|
||||
clk-pins {
|
||||
@@ -110,15 +60,4 @@ rclk-pins {
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
-
|
||||
- spi_0_pins: spi-0-state {
|
||||
- pins = "gpio11", "gpio12", "gpio13", "gpio14";
|
||||
- function = "blsp0_spi";
|
||||
- drive-strength = <8>;
|
||||
- bias-disable;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&xo_board_clk {
|
||||
- clock-frequency = <24000000>;
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
index 877026ccc6e2..1bb8d96c9a82 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
@@ -8,69 +8,11 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
-#include "ipq9574.dtsi"
|
||||
+#include "ipq9574-rdp-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7";
|
||||
compatible = "qcom,ipq9574-ap-al02-c7", "qcom,ipq9574";
|
||||
-
|
||||
- aliases {
|
||||
- serial0 = &blsp1_uart2;
|
||||
- };
|
||||
-
|
||||
- chosen {
|
||||
- stdout-path = "serial0:115200n8";
|
||||
- };
|
||||
-
|
||||
- regulator_fixed_3p3: s3300 {
|
||||
- compatible = "regulator-fixed";
|
||||
- regulator-min-microvolt = <3300000>;
|
||||
- regulator-max-microvolt = <3300000>;
|
||||
- regulator-boot-on;
|
||||
- regulator-always-on;
|
||||
- regulator-name = "fixed_3p3";
|
||||
- };
|
||||
-
|
||||
- regulator_fixed_0p925: s0925 {
|
||||
- compatible = "regulator-fixed";
|
||||
- regulator-min-microvolt = <925000>;
|
||||
- regulator-max-microvolt = <925000>;
|
||||
- regulator-boot-on;
|
||||
- regulator-always-on;
|
||||
- regulator-name = "fixed_0p925";
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_uart2 {
|
||||
- pinctrl-0 = <&uart2_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&rpm_requests {
|
||||
- regulators {
|
||||
- compatible = "qcom,rpm-mp5496-regulators";
|
||||
-
|
||||
- ipq9574_s1: s1 {
|
||||
- /*
|
||||
- * During kernel bootup, the SoC runs at 800MHz with 875mV set by the bootloaders.
|
||||
- * During regulator registration, kernel not knowing the initial voltage,
|
||||
- * considers it as zero and brings up the regulators with minimum supported voltage.
|
||||
- * Update the regulator-min-microvolt with SVS voltage of 725mV so that
|
||||
- * the regulators are brought up with 725mV which is sufficient for all the
|
||||
- * corner parts to operate at 800MHz
|
||||
- */
|
||||
- regulator-min-microvolt = <725000>;
|
||||
- regulator-max-microvolt = <1075000>;
|
||||
- };
|
||||
-
|
||||
- mp5496_l2: l2 {
|
||||
- regulator-min-microvolt = <1800000>;
|
||||
- regulator-max-microvolt = <1800000>;
|
||||
- regulator-always-on;
|
||||
- regulator-boot-on;
|
||||
- };
|
||||
- };
|
||||
};
|
||||
|
||||
&sdhc_1 {
|
||||
@@ -85,10 +27,6 @@ &sdhc_1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
-&sleep_clk {
|
||||
- clock-frequency = <32000>;
|
||||
-};
|
||||
-
|
||||
&tlmm {
|
||||
sdc_default_state: sdc-default-state {
|
||||
clk-pins {
|
||||
@@ -122,30 +60,3 @@ rclk-pins {
|
||||
};
|
||||
};
|
||||
};
|
||||
-
|
||||
-&usb_0_dwc3 {
|
||||
- dr_mode = "host";
|
||||
-};
|
||||
-
|
||||
-&usb_0_qmpphy {
|
||||
- vdda-pll-supply = <&mp5496_l2>;
|
||||
- vdda-phy-supply = <®ulator_fixed_0p925>;
|
||||
-
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&usb_0_qusbphy {
|
||||
- vdd-supply = <®ulator_fixed_0p925>;
|
||||
- vdda-pll-supply = <&mp5496_l2>;
|
||||
- vdda-phy-dpdm-supply = <®ulator_fixed_3p3>;
|
||||
-
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&usb3 {
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&xo_board_clk {
|
||||
- clock-frequency = <24000000>;
|
||||
-};
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp449.dts b/arch/arm64/boot/dts/qcom/ipq9574-rdp449.dts
|
||||
index c8fa54e1a62c..d36d1078763e 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp449.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp449.dts
|
||||
@@ -8,73 +8,10 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
-#include "ipq9574.dtsi"
|
||||
+#include "ipq9574-rdp-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C6";
|
||||
compatible = "qcom,ipq9574-ap-al02-c6", "qcom,ipq9574";
|
||||
|
||||
- aliases {
|
||||
- serial0 = &blsp1_uart2;
|
||||
- };
|
||||
-
|
||||
- chosen {
|
||||
- stdout-path = "serial0:115200n8";
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_spi0 {
|
||||
- pinctrl-0 = <&spi_0_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-
|
||||
- flash@0 {
|
||||
- compatible = "micron,n25q128a11", "jedec,spi-nor";
|
||||
- reg = <0>;
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <1>;
|
||||
- spi-max-frequency = <50000000>;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_uart2 {
|
||||
- pinctrl-0 = <&uart2_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&rpm_requests {
|
||||
- regulators {
|
||||
- compatible = "qcom,rpm-mp5496-regulators";
|
||||
-
|
||||
- ipq9574_s1: s1 {
|
||||
- /*
|
||||
- * During kernel bootup, the SoC runs at 800MHz with 875mV set by the bootloaders.
|
||||
- * During regulator registration, kernel not knowing the initial voltage,
|
||||
- * considers it as zero and brings up the regulators with minimum supported voltage.
|
||||
- * Update the regulator-min-microvolt with SVS voltage of 725mV so that
|
||||
- * the regulators are brought up with 725mV which is sufficient for all the
|
||||
- * corner parts to operate at 800MHz
|
||||
- */
|
||||
- regulator-min-microvolt = <725000>;
|
||||
- regulator-max-microvolt = <1075000>;
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&sleep_clk {
|
||||
- clock-frequency = <32000>;
|
||||
-};
|
||||
-
|
||||
-&tlmm {
|
||||
- spi_0_pins: spi-0-state {
|
||||
- pins = "gpio11", "gpio12", "gpio13", "gpio14";
|
||||
- function = "blsp0_spi";
|
||||
- drive-strength = <8>;
|
||||
- bias-disable;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&xo_board_clk {
|
||||
- clock-frequency = <24000000>;
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp453.dts b/arch/arm64/boot/dts/qcom/ipq9574-rdp453.dts
|
||||
index f01de6628c3b..c30c9fbedf26 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp453.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp453.dts
|
||||
@@ -8,73 +8,10 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
-#include "ipq9574.dtsi"
|
||||
+#include "ipq9574-rdp-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C8";
|
||||
compatible = "qcom,ipq9574-ap-al02-c8", "qcom,ipq9574";
|
||||
|
||||
- aliases {
|
||||
- serial0 = &blsp1_uart2;
|
||||
- };
|
||||
-
|
||||
- chosen {
|
||||
- stdout-path = "serial0:115200n8";
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_spi0 {
|
||||
- pinctrl-0 = <&spi_0_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-
|
||||
- flash@0 {
|
||||
- compatible = "micron,n25q128a11", "jedec,spi-nor";
|
||||
- reg = <0>;
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <1>;
|
||||
- spi-max-frequency = <50000000>;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_uart2 {
|
||||
- pinctrl-0 = <&uart2_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&rpm_requests {
|
||||
- regulators {
|
||||
- compatible = "qcom,rpm-mp5496-regulators";
|
||||
-
|
||||
- ipq9574_s1: s1 {
|
||||
- /*
|
||||
- * During kernel bootup, the SoC runs at 800MHz with 875mV set by the bootloaders.
|
||||
- * During regulator registration, kernel not knowing the initial voltage,
|
||||
- * considers it as zero and brings up the regulators with minimum supported voltage.
|
||||
- * Update the regulator-min-microvolt with SVS voltage of 725mV so that
|
||||
- * the regulators are brought up with 725mV which is sufficient for all the
|
||||
- * corner parts to operate at 800MHz
|
||||
- */
|
||||
- regulator-min-microvolt = <725000>;
|
||||
- regulator-max-microvolt = <1075000>;
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&sleep_clk {
|
||||
- clock-frequency = <32000>;
|
||||
-};
|
||||
-
|
||||
-&tlmm {
|
||||
- spi_0_pins: spi-0-state {
|
||||
- pins = "gpio11", "gpio12", "gpio13", "gpio14";
|
||||
- function = "blsp0_spi";
|
||||
- drive-strength = <8>;
|
||||
- bias-disable;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&xo_board_clk {
|
||||
- clock-frequency = <24000000>;
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp454.dts b/arch/arm64/boot/dts/qcom/ipq9574-rdp454.dts
|
||||
index 6efae3426cb8..0dc382f5d5ec 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp454.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp454.dts
|
||||
@@ -8,73 +8,9 @@
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
-#include "ipq9574.dtsi"
|
||||
+#include "ipq9574-rdp-common.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C9";
|
||||
compatible = "qcom,ipq9574-ap-al02-c9", "qcom,ipq9574";
|
||||
-
|
||||
- aliases {
|
||||
- serial0 = &blsp1_uart2;
|
||||
- };
|
||||
-
|
||||
- chosen {
|
||||
- stdout-path = "serial0:115200n8";
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_spi0 {
|
||||
- pinctrl-0 = <&spi_0_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-
|
||||
- flash@0 {
|
||||
- compatible = "micron,n25q128a11", "jedec,spi-nor";
|
||||
- reg = <0>;
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <1>;
|
||||
- spi-max-frequency = <50000000>;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&blsp1_uart2 {
|
||||
- pinctrl-0 = <&uart2_pins>;
|
||||
- pinctrl-names = "default";
|
||||
- status = "okay";
|
||||
-};
|
||||
-
|
||||
-&rpm_requests {
|
||||
- regulators {
|
||||
- compatible = "qcom,rpm-mp5496-regulators";
|
||||
-
|
||||
- ipq9574_s1: s1 {
|
||||
- /*
|
||||
- * During kernel bootup, the SoC runs at 800MHz with 875mV set by the bootloaders.
|
||||
- * During regulator registration, kernel not knowing the initial voltage,
|
||||
- * considers it as zero and brings up the regulators with minimum supported voltage.
|
||||
- * Update the regulator-min-microvolt with SVS voltage of 725mV so that
|
||||
- * the regulators are brought up with 725mV which is sufficient for all the
|
||||
- * corner parts to operate at 800MHz
|
||||
- */
|
||||
- regulator-min-microvolt = <725000>;
|
||||
- regulator-max-microvolt = <1075000>;
|
||||
- };
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&sleep_clk {
|
||||
- clock-frequency = <32000>;
|
||||
-};
|
||||
-
|
||||
-&tlmm {
|
||||
- spi_0_pins: spi-0-state {
|
||||
- pins = "gpio11", "gpio12", "gpio13", "gpio14";
|
||||
- function = "blsp0_spi";
|
||||
- drive-strength = <8>;
|
||||
- bias-disable;
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-&xo_board_clk {
|
||||
- clock-frequency = <24000000>;
|
||||
};
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,307 @@
|
||||
From 80bbd1c355d661678d2a25bd36e739b6925e7a4e Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 5 Jun 2024 20:45:39 +0800
|
||||
Subject: [PATCH] dt-bindings: clock: add qca8386/qca8084 clock and reset
|
||||
definitions
|
||||
|
||||
QCA8386/QCA8084 includes the clock & reset controller that is
|
||||
accessed by MDIO bus. Two work modes are supported, qca8386 works
|
||||
as switch mode, qca8084 works as PHY mode.
|
||||
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240605124541.2711467-3-quic_luoj@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
.../bindings/clock/qcom,qca8k-nsscc.yaml | 86 +++++++++++++++
|
||||
include/dt-bindings/clock/qcom,qca8k-nsscc.h | 101 ++++++++++++++++++
|
||||
include/dt-bindings/reset/qcom,qca8k-nsscc.h | 76 +++++++++++++
|
||||
3 files changed, 263 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml
|
||||
create mode 100644 include/dt-bindings/clock/qcom,qca8k-nsscc.h
|
||||
create mode 100644 include/dt-bindings/reset/qcom,qca8k-nsscc.h
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml b/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..61473385da2d
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml
|
||||
@@ -0,0 +1,86 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/qcom,qca8k-nsscc.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Qualcomm NSS Clock & Reset Controller on QCA8386/QCA8084
|
||||
+
|
||||
+maintainers:
|
||||
+ - Bjorn Andersson <andersson@kernel.org>
|
||||
+ - Luo Jie <quic_luoj@quicinc.com>
|
||||
+
|
||||
+description: |
|
||||
+ Qualcomm NSS clock control module provides the clocks and resets
|
||||
+ on QCA8386(switch mode)/QCA8084(PHY mode)
|
||||
+
|
||||
+ See also::
|
||||
+ include/dt-bindings/clock/qcom,qca8k-nsscc.h
|
||||
+ include/dt-bindings/reset/qcom,qca8k-nsscc.h
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - const: qcom,qca8084-nsscc
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - qcom,qca8082-nsscc
|
||||
+ - qcom,qca8085-nsscc
|
||||
+ - qcom,qca8384-nsscc
|
||||
+ - qcom,qca8385-nsscc
|
||||
+ - qcom,qca8386-nsscc
|
||||
+ - const: qcom,qca8084-nsscc
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: Chip reference clock source
|
||||
+ - description: UNIPHY0 RX 312P5M/125M clock source
|
||||
+ - description: UNIPHY0 TX 312P5M/125M clock source
|
||||
+ - description: UNIPHY1 RX 312P5M/125M clock source
|
||||
+ - description: UNIPHY1 TX 312P5M/125M clock source
|
||||
+ - description: UNIPHY1 RX 312P5M clock source
|
||||
+ - description: UNIPHY1 TX 312P5M clock source
|
||||
+
|
||||
+ reg:
|
||||
+ items:
|
||||
+ - description: MDIO bus address for Clock & Reset Controller register
|
||||
+
|
||||
+ reset-gpios:
|
||||
+ description: GPIO connected to the chip
|
||||
+ maxItems: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - clocks
|
||||
+ - reg
|
||||
+ - reset-gpios
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: qcom,gcc.yaml#
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/gpio/gpio.h>
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ clock-controller@18 {
|
||||
+ compatible = "qcom,qca8084-nsscc";
|
||||
+ reg = <0x18>;
|
||||
+ reset-gpios = <&tlmm 51 GPIO_ACTIVE_LOW>;
|
||||
+ clocks = <&pcs0_pll>,
|
||||
+ <&qca8k_uniphy0_rx>,
|
||||
+ <&qca8k_uniphy0_tx>,
|
||||
+ <&qca8k_uniphy1_rx>,
|
||||
+ <&qca8k_uniphy1_tx>,
|
||||
+ <&qca8k_uniphy1_rx312p5m>,
|
||||
+ <&qca8k_uniphy1_tx312p5m>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ #power-domain-cells = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+...
|
||||
diff --git a/include/dt-bindings/clock/qcom,qca8k-nsscc.h b/include/dt-bindings/clock/qcom,qca8k-nsscc.h
|
||||
new file mode 100644
|
||||
index 000000000000..0ac3e4c69a1a
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/qcom,qca8k-nsscc.h
|
||||
@@ -0,0 +1,101 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+/*
|
||||
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_QCOM_QCA8K_NSS_CC_H
|
||||
+#define _DT_BINDINGS_CLK_QCOM_QCA8K_NSS_CC_H
|
||||
+
|
||||
+#define NSS_CC_SWITCH_CORE_CLK_SRC 0
|
||||
+#define NSS_CC_SWITCH_CORE_CLK 1
|
||||
+#define NSS_CC_APB_BRIDGE_CLK 2
|
||||
+#define NSS_CC_MAC0_TX_CLK_SRC 3
|
||||
+#define NSS_CC_MAC0_TX_DIV_CLK_SRC 4
|
||||
+#define NSS_CC_MAC0_TX_CLK 5
|
||||
+#define NSS_CC_MAC0_TX_SRDS1_CLK 6
|
||||
+#define NSS_CC_MAC0_RX_CLK_SRC 7
|
||||
+#define NSS_CC_MAC0_RX_DIV_CLK_SRC 8
|
||||
+#define NSS_CC_MAC0_RX_CLK 9
|
||||
+#define NSS_CC_MAC0_RX_SRDS1_CLK 10
|
||||
+#define NSS_CC_MAC1_TX_CLK_SRC 11
|
||||
+#define NSS_CC_MAC1_TX_DIV_CLK_SRC 12
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_DIV_CLK_SRC 13
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_RX_CLK 14
|
||||
+#define NSS_CC_MAC1_TX_CLK 15
|
||||
+#define NSS_CC_MAC1_GEPHY0_TX_CLK 16
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_CLK 17
|
||||
+#define NSS_CC_MAC1_RX_CLK_SRC 18
|
||||
+#define NSS_CC_MAC1_RX_DIV_CLK_SRC 19
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_DIV_CLK_SRC 20
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_TX_CLK 21
|
||||
+#define NSS_CC_MAC1_RX_CLK 22
|
||||
+#define NSS_CC_MAC1_GEPHY0_RX_CLK 23
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_CLK 24
|
||||
+#define NSS_CC_MAC2_TX_CLK_SRC 25
|
||||
+#define NSS_CC_MAC2_TX_DIV_CLK_SRC 26
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_DIV_CLK_SRC 27
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_RX_CLK 28
|
||||
+#define NSS_CC_MAC2_TX_CLK 29
|
||||
+#define NSS_CC_MAC2_GEPHY1_TX_CLK 30
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_CLK 31
|
||||
+#define NSS_CC_MAC2_RX_CLK_SRC 32
|
||||
+#define NSS_CC_MAC2_RX_DIV_CLK_SRC 33
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_DIV_CLK_SRC 34
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_TX_CLK 35
|
||||
+#define NSS_CC_MAC2_RX_CLK 36
|
||||
+#define NSS_CC_MAC2_GEPHY1_RX_CLK 37
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_CLK 38
|
||||
+#define NSS_CC_MAC3_TX_CLK_SRC 39
|
||||
+#define NSS_CC_MAC3_TX_DIV_CLK_SRC 40
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_DIV_CLK_SRC 41
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_RX_CLK 42
|
||||
+#define NSS_CC_MAC3_TX_CLK 43
|
||||
+#define NSS_CC_MAC3_GEPHY2_TX_CLK 44
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_CLK 45
|
||||
+#define NSS_CC_MAC3_RX_CLK_SRC 46
|
||||
+#define NSS_CC_MAC3_RX_DIV_CLK_SRC 47
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_DIV_CLK_SRC 48
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_TX_CLK 49
|
||||
+#define NSS_CC_MAC3_RX_CLK 50
|
||||
+#define NSS_CC_MAC3_GEPHY2_RX_CLK 51
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_CLK 52
|
||||
+#define NSS_CC_MAC4_TX_CLK_SRC 53
|
||||
+#define NSS_CC_MAC4_TX_DIV_CLK_SRC 54
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_DIV_CLK_SRC 55
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_RX_CLK 56
|
||||
+#define NSS_CC_MAC4_TX_CLK 57
|
||||
+#define NSS_CC_MAC4_GEPHY3_TX_CLK 58
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_CLK 59
|
||||
+#define NSS_CC_MAC4_RX_CLK_SRC 60
|
||||
+#define NSS_CC_MAC4_RX_DIV_CLK_SRC 61
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_DIV_CLK_SRC 62
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_TX_CLK 63
|
||||
+#define NSS_CC_MAC4_RX_CLK 64
|
||||
+#define NSS_CC_MAC4_GEPHY3_RX_CLK 65
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_CLK 66
|
||||
+#define NSS_CC_MAC5_TX_CLK_SRC 67
|
||||
+#define NSS_CC_MAC5_TX_DIV_CLK_SRC 68
|
||||
+#define NSS_CC_MAC5_TX_SRDS0_CLK 69
|
||||
+#define NSS_CC_MAC5_TX_CLK 70
|
||||
+#define NSS_CC_MAC5_RX_CLK_SRC 71
|
||||
+#define NSS_CC_MAC5_RX_DIV_CLK_SRC 72
|
||||
+#define NSS_CC_MAC5_RX_SRDS0_CLK 73
|
||||
+#define NSS_CC_MAC5_RX_CLK 74
|
||||
+#define NSS_CC_MAC5_TX_SRDS0_CLK_SRC 75
|
||||
+#define NSS_CC_MAC5_RX_SRDS0_CLK_SRC 76
|
||||
+#define NSS_CC_AHB_CLK_SRC 77
|
||||
+#define NSS_CC_AHB_CLK 78
|
||||
+#define NSS_CC_SEC_CTRL_AHB_CLK 79
|
||||
+#define NSS_CC_TLMM_CLK 80
|
||||
+#define NSS_CC_TLMM_AHB_CLK 81
|
||||
+#define NSS_CC_CNOC_AHB_CLK 82
|
||||
+#define NSS_CC_MDIO_AHB_CLK 83
|
||||
+#define NSS_CC_MDIO_MASTER_AHB_CLK 84
|
||||
+#define NSS_CC_SYS_CLK_SRC 85
|
||||
+#define NSS_CC_SRDS0_SYS_CLK 86
|
||||
+#define NSS_CC_SRDS1_SYS_CLK 87
|
||||
+#define NSS_CC_GEPHY0_SYS_CLK 88
|
||||
+#define NSS_CC_GEPHY1_SYS_CLK 89
|
||||
+#define NSS_CC_GEPHY2_SYS_CLK 90
|
||||
+#define NSS_CC_GEPHY3_SYS_CLK 91
|
||||
+#endif
|
||||
diff --git a/include/dt-bindings/reset/qcom,qca8k-nsscc.h b/include/dt-bindings/reset/qcom,qca8k-nsscc.h
|
||||
new file mode 100644
|
||||
index 000000000000..c71167a3bd41
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/reset/qcom,qca8k-nsscc.h
|
||||
@@ -0,0 +1,76 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+/*
|
||||
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_RESET_QCOM_QCA8K_NSS_CC_H
|
||||
+#define _DT_BINDINGS_RESET_QCOM_QCA8K_NSS_CC_H
|
||||
+
|
||||
+#define NSS_CC_SWITCH_CORE_ARES 1
|
||||
+#define NSS_CC_APB_BRIDGE_ARES 2
|
||||
+#define NSS_CC_MAC0_TX_ARES 3
|
||||
+#define NSS_CC_MAC0_TX_SRDS1_ARES 4
|
||||
+#define NSS_CC_MAC0_RX_ARES 5
|
||||
+#define NSS_CC_MAC0_RX_SRDS1_ARES 6
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_RX_ARES 7
|
||||
+#define NSS_CC_MAC1_TX_ARES 8
|
||||
+#define NSS_CC_MAC1_GEPHY0_TX_ARES 9
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_ARES 10
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_TX_ARES 11
|
||||
+#define NSS_CC_MAC1_RX_ARES 12
|
||||
+#define NSS_CC_MAC1_GEPHY0_RX_ARES 13
|
||||
+#define NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_ARES 14
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_RX_ARES 15
|
||||
+#define NSS_CC_MAC2_TX_ARES 16
|
||||
+#define NSS_CC_MAC2_GEPHY1_TX_ARES 17
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_ARES 18
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_TX_ARES 19
|
||||
+#define NSS_CC_MAC2_RX_ARES 20
|
||||
+#define NSS_CC_MAC2_GEPHY1_RX_ARES 21
|
||||
+#define NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_ARES 22
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_RX_ARES 23
|
||||
+#define NSS_CC_MAC3_TX_ARES 24
|
||||
+#define NSS_CC_MAC3_GEPHY2_TX_ARES 25
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_ARES 26
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_TX_ARES 27
|
||||
+#define NSS_CC_MAC3_RX_ARES 28
|
||||
+#define NSS_CC_MAC3_GEPHY2_RX_ARES 29
|
||||
+#define NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_ARES 30
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_RX_ARES 31
|
||||
+#define NSS_CC_MAC4_TX_ARES 32
|
||||
+#define NSS_CC_MAC4_GEPHY3_TX_ARES 33
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_ARES 34
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_TX_ARES 35
|
||||
+#define NSS_CC_MAC4_RX_ARES 36
|
||||
+#define NSS_CC_MAC4_GEPHY3_RX_ARES 37
|
||||
+#define NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_ARES 38
|
||||
+#define NSS_CC_MAC5_TX_ARES 39
|
||||
+#define NSS_CC_MAC5_TX_SRDS0_ARES 40
|
||||
+#define NSS_CC_MAC5_RX_ARES 41
|
||||
+#define NSS_CC_MAC5_RX_SRDS0_ARES 42
|
||||
+#define NSS_CC_AHB_ARES 43
|
||||
+#define NSS_CC_SEC_CTRL_AHB_ARES 44
|
||||
+#define NSS_CC_TLMM_ARES 45
|
||||
+#define NSS_CC_TLMM_AHB_ARES 46
|
||||
+#define NSS_CC_CNOC_AHB_ARES 47
|
||||
+#define NSS_CC_MDIO_AHB_ARES 48
|
||||
+#define NSS_CC_MDIO_MASTER_AHB_ARES 49
|
||||
+#define NSS_CC_SRDS0_SYS_ARES 50
|
||||
+#define NSS_CC_SRDS1_SYS_ARES 51
|
||||
+#define NSS_CC_GEPHY0_SYS_ARES 52
|
||||
+#define NSS_CC_GEPHY1_SYS_ARES 53
|
||||
+#define NSS_CC_GEPHY2_SYS_ARES 54
|
||||
+#define NSS_CC_GEPHY3_SYS_ARES 55
|
||||
+#define NSS_CC_SEC_CTRL_ARES 56
|
||||
+#define NSS_CC_SEC_CTRL_SENSE_ARES 57
|
||||
+#define NSS_CC_SLEEP_ARES 58
|
||||
+#define NSS_CC_DEBUG_ARES 59
|
||||
+#define NSS_CC_GEPHY0_ARES 60
|
||||
+#define NSS_CC_GEPHY1_ARES 61
|
||||
+#define NSS_CC_GEPHY2_ARES 62
|
||||
+#define NSS_CC_GEPHY3_ARES 63
|
||||
+#define NSS_CC_DSP_ARES 64
|
||||
+#define NSS_CC_GEPHY_FULL_ARES 65
|
||||
+#define NSS_CC_GLOBAL_ARES 66
|
||||
+#define NSS_CC_XPCS_ARES 67
|
||||
+#endif
|
||||
--
|
||||
2.45.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,39 @@
|
||||
From e60ac570137b42ef61a01a6b26133a8e2d7e8d4b Mon Sep 17 00:00:00 2001
|
||||
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
Date: Mon, 6 May 2024 21:47:58 -0500
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq9574: add MDIO bus
|
||||
|
||||
The IPQ95xx uses an IPQ4019 compatible MDIO controller that is already
|
||||
supported. Add a DT node to expose it.
|
||||
|
||||
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
Link: https://lore.kernel.org/r/20240507024758.2810514-2-mr.nuke.me@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
index 7f2e5cbf3bbb..ded02bc39275 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -232,6 +232,16 @@ rng: rng@e3000 {
|
||||
clock-names = "core";
|
||||
};
|
||||
|
||||
+ mdio: mdio@90000 {
|
||||
+ compatible = "qcom,ipq9574-mdio", "qcom,ipq4019-mdio";
|
||||
+ reg = <0x00090000 0x64>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ clocks = <&gcc GCC_MDIO_AHB_CLK>;
|
||||
+ clock-names = "gcc_mdio_ahb_clk";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
qfprom: efuse@a4000 {
|
||||
compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
|
||||
reg = <0x000a4000 0x5a1>;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,88 @@
|
||||
From d06b1043644a1831ab141bbee2669002bba15b0f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Wed, 20 Dec 2023 23:17:22 +0100
|
||||
Subject: [PATCH 1/2] clk: qcom: clk-rcg: introduce support for multiple conf
|
||||
for same freq
|
||||
|
||||
Some RCG frequency can be reached by multiple configuration.
|
||||
|
||||
We currently declare multiple configuration for the same frequency but
|
||||
that is not supported and always the first configuration will be taken.
|
||||
|
||||
These multiple configuration are needed as based on the current parent
|
||||
configuration, it may be needed to use a different configuration to
|
||||
reach the same frequency.
|
||||
|
||||
To handle this introduce 3 new macro, C, FM and FMS:
|
||||
|
||||
- C is used to declare a freq_conf where src, pre_div, m and n are
|
||||
provided.
|
||||
|
||||
- FM is used to declare a freq_multi_tbl with the frequency and an
|
||||
array of confs to insert all the config for the provided frequency.
|
||||
|
||||
- FMS is used to declare a freq_multi_tbl with the frequency and an
|
||||
array of a single conf with the provided src, pre_div, m and n.
|
||||
|
||||
Struct clk_rcg2 is changed to add a union type to reference a simple
|
||||
freq_tbl or a complex freq_multi_tbl.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20231220221724.3822-2-ansuelsmth@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/clk-rcg.h | 23 ++++++++++++++++++++++-
|
||||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
|
||||
index e6d84c8c7989..c50e6616d02c 100644
|
||||
--- a/drivers/clk/qcom/clk-rcg.h
|
||||
+++ b/drivers/clk/qcom/clk-rcg.h
|
||||
@@ -17,6 +17,23 @@ struct freq_tbl {
|
||||
u16 n;
|
||||
};
|
||||
|
||||
+#define C(s, h, m, n) { (s), (2 * (h) - 1), (m), (n) }
|
||||
+#define FM(f, confs) { (f), ARRAY_SIZE(confs), (confs) }
|
||||
+#define FMS(f, s, h, m, n) { (f), 1, (const struct freq_conf []){ C(s, h, m, n) } }
|
||||
+
|
||||
+struct freq_conf {
|
||||
+ u8 src;
|
||||
+ u8 pre_div;
|
||||
+ u16 m;
|
||||
+ u16 n;
|
||||
+};
|
||||
+
|
||||
+struct freq_multi_tbl {
|
||||
+ unsigned long freq;
|
||||
+ size_t num_confs;
|
||||
+ const struct freq_conf *confs;
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct mn - M/N:D counter
|
||||
* @mnctr_en_bit: bit to enable mn counter
|
||||
@@ -138,6 +155,7 @@ extern const struct clk_ops clk_dyn_rcg_ops;
|
||||
* @safe_src_index: safe src index value
|
||||
* @parent_map: map from software's parent index to hardware's src_sel field
|
||||
* @freq_tbl: frequency table
|
||||
+ * @freq_multi_tbl: frequency table for clocks reachable with multiple RCGs conf
|
||||
* @clkr: regmap clock handle
|
||||
* @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG
|
||||
* @parked_cfg: cached value of the CFG register for parked RCGs
|
||||
@@ -149,7 +167,10 @@ struct clk_rcg2 {
|
||||
u8 hid_width;
|
||||
u8 safe_src_index;
|
||||
const struct parent_map *parent_map;
|
||||
- const struct freq_tbl *freq_tbl;
|
||||
+ union {
|
||||
+ const struct freq_tbl *freq_tbl;
|
||||
+ const struct freq_multi_tbl *freq_multi_tbl;
|
||||
+ };
|
||||
struct clk_regmap clkr;
|
||||
u8 cfg_off;
|
||||
u32 parked_cfg;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,307 @@
|
||||
From 89da22456af0762477d8c1345fdd17961b3ada80 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Wed, 20 Dec 2023 23:17:23 +0100
|
||||
Subject: [PATCH 2/2] clk: qcom: clk-rcg2: add support for rcg2 freq multi ops
|
||||
|
||||
Some RCG frequency can be reached by multiple configuration.
|
||||
|
||||
Add clk_rcg2_fm_ops ops to support these special RCG configurations.
|
||||
|
||||
These alternative ops will select the frequency using a CEIL policy.
|
||||
|
||||
When the correct frequency is found, the correct config is selected by
|
||||
calculating the final rate (by checking the defined parent and values
|
||||
in the config that is being checked) and deciding based on the one that
|
||||
is less different than the requested one.
|
||||
|
||||
These check are skipped if there is just one config for the requested
|
||||
freq.
|
||||
|
||||
qcom_find_freq_multi is added to search the freq with the new struct
|
||||
freq_multi_tbl.
|
||||
__clk_rcg2_select_conf is used to select the correct conf by simulating
|
||||
the final clock.
|
||||
If a conf can't be found due to parent not reachable, a WARN is printed
|
||||
and -EINVAL is returned.
|
||||
|
||||
Tested-by: Wei Lei <quic_leiwei@quicinc.com>
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Link: https://lore.kernel.org/r/20231220221724.3822-3-ansuelsmth@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/clk-rcg.h | 1 +
|
||||
drivers/clk/qcom/clk-rcg2.c | 166 ++++++++++++++++++++++++++++++++++++
|
||||
drivers/clk/qcom/common.c | 18 ++++
|
||||
drivers/clk/qcom/common.h | 2 +
|
||||
4 files changed, 187 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
|
||||
index c50e6616d02c..d7414361e432 100644
|
||||
--- a/drivers/clk/qcom/clk-rcg.h
|
||||
+++ b/drivers/clk/qcom/clk-rcg.h
|
||||
@@ -190,6 +190,7 @@ struct clk_rcg2_gfx3d {
|
||||
|
||||
extern const struct clk_ops clk_rcg2_ops;
|
||||
extern const struct clk_ops clk_rcg2_floor_ops;
|
||||
+extern const struct clk_ops clk_rcg2_fm_ops;
|
||||
extern const struct clk_ops clk_rcg2_mux_closest_ops;
|
||||
extern const struct clk_ops clk_edp_pixel_ops;
|
||||
extern const struct clk_ops clk_byte_ops;
|
||||
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
|
||||
index 5183c74b074f..9b3aaa7f20ac 100644
|
||||
--- a/drivers/clk/qcom/clk-rcg2.c
|
||||
+++ b/drivers/clk/qcom/clk-rcg2.c
|
||||
@@ -260,6 +260,115 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct freq_conf *
|
||||
+__clk_rcg2_select_conf(struct clk_hw *hw, const struct freq_multi_tbl *f,
|
||||
+ unsigned long req_rate)
|
||||
+{
|
||||
+ unsigned long rate_diff, best_rate_diff = ULONG_MAX;
|
||||
+ const struct freq_conf *conf, *best_conf = NULL;
|
||||
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
+ const char *name = clk_hw_get_name(hw);
|
||||
+ unsigned long parent_rate, rate;
|
||||
+ struct clk_hw *p;
|
||||
+ int index, i;
|
||||
+
|
||||
+ /* Exit early if only one config is defined */
|
||||
+ if (f->num_confs == 1) {
|
||||
+ best_conf = f->confs;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ /* Search in each provided config the one that is near the wanted rate */
|
||||
+ for (i = 0, conf = f->confs; i < f->num_confs; i++, conf++) {
|
||||
+ index = qcom_find_src_index(hw, rcg->parent_map, conf->src);
|
||||
+ if (index < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ p = clk_hw_get_parent_by_index(hw, index);
|
||||
+ if (!p)
|
||||
+ continue;
|
||||
+
|
||||
+ parent_rate = clk_hw_get_rate(p);
|
||||
+ rate = calc_rate(parent_rate, conf->n, conf->m, conf->n, conf->pre_div);
|
||||
+
|
||||
+ if (rate == req_rate) {
|
||||
+ best_conf = conf;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ rate_diff = abs_diff(req_rate, rate);
|
||||
+ if (rate_diff < best_rate_diff) {
|
||||
+ best_rate_diff = rate_diff;
|
||||
+ best_conf = conf;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Very unlikely. Warn if we couldn't find a correct config
|
||||
+ * due to parent not found in every config.
|
||||
+ */
|
||||
+ if (unlikely(!best_conf)) {
|
||||
+ WARN(1, "%s: can't find a configuration for rate %lu\n",
|
||||
+ name, req_rate);
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ return best_conf;
|
||||
+}
|
||||
+
|
||||
+static int _freq_tbl_fm_determine_rate(struct clk_hw *hw, const struct freq_multi_tbl *f,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ unsigned long clk_flags, rate = req->rate;
|
||||
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
+ const struct freq_conf *conf;
|
||||
+ struct clk_hw *p;
|
||||
+ int index;
|
||||
+
|
||||
+ f = qcom_find_freq_multi(f, rate);
|
||||
+ if (!f || !f->confs)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ conf = __clk_rcg2_select_conf(hw, f, rate);
|
||||
+ if (IS_ERR(conf))
|
||||
+ return PTR_ERR(conf);
|
||||
+ index = qcom_find_src_index(hw, rcg->parent_map, conf->src);
|
||||
+ if (index < 0)
|
||||
+ return index;
|
||||
+
|
||||
+ clk_flags = clk_hw_get_flags(hw);
|
||||
+ p = clk_hw_get_parent_by_index(hw, index);
|
||||
+ if (!p)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (clk_flags & CLK_SET_RATE_PARENT) {
|
||||
+ rate = f->freq;
|
||||
+ if (conf->pre_div) {
|
||||
+ if (!rate)
|
||||
+ rate = req->rate;
|
||||
+ rate /= 2;
|
||||
+ rate *= conf->pre_div + 1;
|
||||
+ }
|
||||
+
|
||||
+ if (conf->n) {
|
||||
+ u64 tmp = rate;
|
||||
+
|
||||
+ tmp = tmp * conf->n;
|
||||
+ do_div(tmp, conf->m);
|
||||
+ rate = tmp;
|
||||
+ }
|
||||
+ } else {
|
||||
+ rate = clk_hw_get_rate(p);
|
||||
+ }
|
||||
+
|
||||
+ req->best_parent_hw = p;
|
||||
+ req->best_parent_rate = rate;
|
||||
+ req->rate = f->freq;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int clk_rcg2_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
@@ -276,6 +385,14 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
|
||||
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
|
||||
}
|
||||
|
||||
+static int clk_rcg2_fm_determine_rate(struct clk_hw *hw,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
+
|
||||
+ return _freq_tbl_fm_determine_rate(hw, rcg->freq_multi_tbl, req);
|
||||
+}
|
||||
+
|
||||
static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f,
|
||||
u32 *_cfg)
|
||||
{
|
||||
@@ -371,6 +488,30 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return clk_rcg2_configure(rcg, f);
|
||||
}
|
||||
|
||||
+static int __clk_rcg2_fm_set_rate(struct clk_hw *hw, unsigned long rate)
|
||||
+{
|
||||
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
+ const struct freq_multi_tbl *f;
|
||||
+ const struct freq_conf *conf;
|
||||
+ struct freq_tbl f_tbl = {};
|
||||
+
|
||||
+ f = qcom_find_freq_multi(rcg->freq_multi_tbl, rate);
|
||||
+ if (!f || !f->confs)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ conf = __clk_rcg2_select_conf(hw, f, rate);
|
||||
+ if (IS_ERR(conf))
|
||||
+ return PTR_ERR(conf);
|
||||
+
|
||||
+ f_tbl.freq = f->freq;
|
||||
+ f_tbl.src = conf->src;
|
||||
+ f_tbl.pre_div = conf->pre_div;
|
||||
+ f_tbl.m = conf->m;
|
||||
+ f_tbl.n = conf->n;
|
||||
+
|
||||
+ return clk_rcg2_configure(rcg, &f_tbl);
|
||||
+}
|
||||
+
|
||||
static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@@ -383,6 +524,12 @@ static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return __clk_rcg2_set_rate(hw, rate, FLOOR);
|
||||
}
|
||||
|
||||
+static int clk_rcg2_fm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ return __clk_rcg2_fm_set_rate(hw, rate);
|
||||
+}
|
||||
+
|
||||
static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long parent_rate, u8 index)
|
||||
{
|
||||
@@ -395,6 +542,12 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw,
|
||||
return __clk_rcg2_set_rate(hw, rate, FLOOR);
|
||||
}
|
||||
|
||||
+static int clk_rcg2_fm_set_rate_and_parent(struct clk_hw *hw,
|
||||
+ unsigned long rate, unsigned long parent_rate, u8 index)
|
||||
+{
|
||||
+ return __clk_rcg2_fm_set_rate(hw, rate);
|
||||
+}
|
||||
+
|
||||
static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
|
||||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
@@ -505,6 +658,19 @@ const struct clk_ops clk_rcg2_floor_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
|
||||
|
||||
+const struct clk_ops clk_rcg2_fm_ops = {
|
||||
+ .is_enabled = clk_rcg2_is_enabled,
|
||||
+ .get_parent = clk_rcg2_get_parent,
|
||||
+ .set_parent = clk_rcg2_set_parent,
|
||||
+ .recalc_rate = clk_rcg2_recalc_rate,
|
||||
+ .determine_rate = clk_rcg2_fm_determine_rate,
|
||||
+ .set_rate = clk_rcg2_fm_set_rate,
|
||||
+ .set_rate_and_parent = clk_rcg2_fm_set_rate_and_parent,
|
||||
+ .get_duty_cycle = clk_rcg2_get_duty_cycle,
|
||||
+ .set_duty_cycle = clk_rcg2_set_duty_cycle,
|
||||
+};
|
||||
+EXPORT_SYMBOL_GPL(clk_rcg2_fm_ops);
|
||||
+
|
||||
const struct clk_ops clk_rcg2_mux_closest_ops = {
|
||||
.determine_rate = __clk_mux_determine_rate_closest,
|
||||
.get_parent = clk_rcg2_get_parent,
|
||||
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
|
||||
index 75f09e6e057e..48f81e3a5e80 100644
|
||||
--- a/drivers/clk/qcom/common.c
|
||||
+++ b/drivers/clk/qcom/common.c
|
||||
@@ -41,6 +41,24 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_freq);
|
||||
|
||||
+const struct freq_multi_tbl *qcom_find_freq_multi(const struct freq_multi_tbl *f,
|
||||
+ unsigned long rate)
|
||||
+{
|
||||
+ if (!f)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!f->freq)
|
||||
+ return f;
|
||||
+
|
||||
+ for (; f->freq; f++)
|
||||
+ if (rate <= f->freq)
|
||||
+ return f;
|
||||
+
|
||||
+ /* Default to our fastest rate */
|
||||
+ return f - 1;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(qcom_find_freq_multi);
|
||||
+
|
||||
const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
|
||||
unsigned long rate)
|
||||
{
|
||||
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
|
||||
index 9c8f7b798d9f..2d4a8a837e6c 100644
|
||||
--- a/drivers/clk/qcom/common.h
|
||||
+++ b/drivers/clk/qcom/common.h
|
||||
@@ -45,6 +45,8 @@ extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
|
||||
unsigned long rate);
|
||||
extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
|
||||
unsigned long rate);
|
||||
+extern const struct freq_multi_tbl *qcom_find_freq_multi(const struct freq_multi_tbl *f,
|
||||
+ unsigned long rate);
|
||||
extern void
|
||||
qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count);
|
||||
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 7311bbfff31c4961c57d94c165fa843f155f8236 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 5 Jun 2024 20:45:38 +0800
|
||||
Subject: [PATCH] clk: qcom: branch: Add clk_branch2_prepare_ops
|
||||
|
||||
Add the clk_branch2_prepare_ops for supporting clock controller
|
||||
where the hardware register is accessed by MDIO bus, and the
|
||||
spin lock can't be used because of sleep during the MDIO
|
||||
operation.
|
||||
|
||||
The clock is enabled by the .prepare instead of .enable when
|
||||
the clk_branch2_prepare_ops is used.
|
||||
|
||||
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240605124541.2711467-2-quic_luoj@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/clk-branch.c | 7 +++++++
|
||||
drivers/clk/qcom/clk-branch.h | 1 +
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c
|
||||
index c1dba33ac31a..229480c5b075 100644
|
||||
--- a/drivers/clk/qcom/clk-branch.c
|
||||
+++ b/drivers/clk/qcom/clk-branch.c
|
||||
@@ -191,3 +191,10 @@ const struct clk_ops clk_branch_simple_ops = {
|
||||
.is_enabled = clk_is_enabled_regmap,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_branch_simple_ops);
|
||||
+
|
||||
+const struct clk_ops clk_branch2_prepare_ops = {
|
||||
+ .prepare = clk_branch2_enable,
|
||||
+ .unprepare = clk_branch2_disable,
|
||||
+ .is_prepared = clk_is_enabled_regmap,
|
||||
+};
|
||||
+EXPORT_SYMBOL_GPL(clk_branch2_prepare_ops);
|
||||
diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h
|
||||
index f1b3b635ff32..292756435f53 100644
|
||||
--- a/drivers/clk/qcom/clk-branch.h
|
||||
+++ b/drivers/clk/qcom/clk-branch.h
|
||||
@@ -109,6 +109,7 @@ extern const struct clk_ops clk_branch2_ops;
|
||||
extern const struct clk_ops clk_branch_simple_ops;
|
||||
extern const struct clk_ops clk_branch2_aon_ops;
|
||||
+extern const struct clk_ops clk_branch2_prepare_ops;
|
||||
|
||||
#define to_clk_branch(_hw) \
|
||||
container_of(to_clk_regmap(_hw), struct clk_branch, clkr)
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,141 @@
|
||||
From 777b8afb8179155353ec14b1d8153122410aba29 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Date: Sat, 15 Jun 2024 20:00:27 +0800
|
||||
Subject: [PATCH] net: phy: introduce core support for phy-mode = "10g-qxgmii"
|
||||
|
||||
10G-QXGMII is a MAC-to-PHY interface defined by the USXGMII multiport
|
||||
specification. It uses the same signaling as USXGMII, but it multiplexes
|
||||
4 ports over the link, resulting in a maximum speed of 2.5G per port.
|
||||
|
||||
Some in-tree SoCs like the NXP LS1028A use "usxgmii" when they mean
|
||||
either the single-port USXGMII or the quad-port 10G-QXGMII variant, and
|
||||
they could get away just fine with that thus far. But there is a need to
|
||||
distinguish between the 2 as far as SerDes drivers are concerned.
|
||||
|
||||
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
Documentation/networking/phy.rst | 6 ++++++
|
||||
drivers/net/phy/phy-core.c | 1 +
|
||||
drivers/net/phy/phylink.c | 9 ++++++++-
|
||||
include/linux/phy.h | 4 ++++
|
||||
include/linux/phylink.h | 1 +
|
||||
5 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Documentation/networking/phy.rst b/Documentation/networking/phy.rst
|
||||
index 1283240d7620..f64641417c54 100644
|
||||
--- a/Documentation/networking/phy.rst
|
||||
+++ b/Documentation/networking/phy.rst
|
||||
@@ -327,6 +327,12 @@ Some of the interface modes are described below:
|
||||
This is the Penta SGMII mode, it is similar to QSGMII but it combines 5
|
||||
SGMII lines into a single link compared to 4 on QSGMII.
|
||||
|
||||
+``PHY_INTERFACE_MODE_10G_QXGMII``
|
||||
+ Represents the 10G-QXGMII PHY-MAC interface as defined by the Cisco USXGMII
|
||||
+ Multiport Copper Interface document. It supports 4 ports over a 10.3125 GHz
|
||||
+ SerDes lane, each port having speeds of 2.5G / 1G / 100M / 10M achieved
|
||||
+ through symbol replication. The PCS expects the standard USXGMII code word.
|
||||
+
|
||||
Pause frames / flow control
|
||||
===========================
|
||||
|
||||
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
|
||||
index 15f349e5995a..a235ea2264a7 100644
|
||||
--- a/drivers/net/phy/phy-core.c
|
||||
+++ b/drivers/net/phy/phy-core.c
|
||||
@@ -141,6 +141,7 @@ int phy_interface_num_ports(phy_interface_t interface)
|
||||
return 1;
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
return 4;
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
return 5;
|
||||
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
|
||||
index 02427378acfd..6c24c48dcf0f 100644
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -231,6 +231,7 @@ static int phylink_interface_max_speed(phy_interface_t interface)
|
||||
return SPEED_1000;
|
||||
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
return SPEED_2500;
|
||||
|
||||
case PHY_INTERFACE_MODE_5GBASER:
|
||||
@@ -500,7 +501,11 @@ static unsigned long phylink_get_capabilities(phy_interface_t interface,
|
||||
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
- caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
|
||||
+ caps |= MAC_10000FD | MAC_5000FD;
|
||||
+ fallthrough;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
+ caps |= MAC_2500FD;
|
||||
fallthrough;
|
||||
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
@@ -926,6 +931,7 @@ static int phylink_parse_mode(struct phylink *pl,
|
||||
case PHY_INTERFACE_MODE_5GBASER:
|
||||
case PHY_INTERFACE_MODE_25GBASER:
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
case PHY_INTERFACE_MODE_10GKR:
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
case PHY_INTERFACE_MODE_XLGMII:
|
||||
diff --git a/include/linux/phy.h b/include/linux/phy.h
|
||||
index e6e83304558e..205fccfc0f60 100644
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -128,6 +128,7 @@ extern const int phy_10gbit_features_array[1];
|
||||
* @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN
|
||||
* @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII
|
||||
* @PHY_INTERFACE_MODE_1000BASEKX: 1000Base-KX - with Clause 73 AN
|
||||
+ * @PHY_INTERFACE_MODE_10G_QXGMII: 10G-QXGMII - 4 ports over 10G USXGMII
|
||||
* @PHY_INTERFACE_MODE_MAX: Book keeping
|
||||
*
|
||||
* Describes the interface between the MAC and PHY.
|
||||
@@ -168,6 +169,7 @@ typedef enum {
|
||||
PHY_INTERFACE_MODE_10GKR,
|
||||
PHY_INTERFACE_MODE_QUSGMII,
|
||||
PHY_INTERFACE_MODE_1000BASEKX,
|
||||
+ PHY_INTERFACE_MODE_10G_QXGMII,
|
||||
PHY_INTERFACE_MODE_MAX,
|
||||
} phy_interface_t;
|
||||
|
||||
@@ -289,6 +291,8 @@ static inline const char *phy_modes(phy_interface_t interface)
|
||||
return "100base-x";
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
return "qusgmii";
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
+ return "10g-qxgmii";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
|
||||
index a30a692acc32..2381e07429a2 100644
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -124,6 +130,7 @@ static unsigned int phylink_pcs_neg_mode(unsigned int mode,
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_QUSGMII:
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
/* These protocols are designed for use with a PHY which
|
||||
* communicates its negotiation result back to the MAC via
|
||||
* inband communication. Note: there exist PHYs that run
|
||||
@@ -654,6 +654,7 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface)
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
return 1600000;
|
||||
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,114 @@
|
||||
From 265b07df758a998f60cf5b5aec6bd72ca676655e Mon Sep 17 00:00:00 2001
|
||||
From: Shradha Todi <shradha.t@samsung.com>
|
||||
Date: Tue, 20 Feb 2024 14:10:45 +0530
|
||||
Subject: [PATCH] clk: Provide managed helper to get and enable bulk clocks
|
||||
|
||||
Provide a managed devm_clk_bulk* wrapper to get and enable all
|
||||
bulk clocks in order to simplify drivers that keeps all clocks
|
||||
enabled for the time of driver operation.
|
||||
|
||||
Suggested-by: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Signed-off-by: Shradha Todi <shradha.t@samsung.com>
|
||||
Link: https://lore.kernel.org/r/20240220084046.23786-2-shradha.t@samsung.com
|
||||
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||
---
|
||||
drivers/clk/clk-devres.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/clk.h | 22 ++++++++++++++++++++++
|
||||
2 files changed, 62 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
|
||||
index 737aa70e2cb3..90e6078fb6e1 100644
|
||||
--- a/drivers/clk/clk-devres.c
|
||||
+++ b/drivers/clk/clk-devres.c
|
||||
@@ -182,6 +182,46 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all);
|
||||
|
||||
+static void devm_clk_bulk_release_all_enable(struct device *dev, void *res)
|
||||
+{
|
||||
+ struct clk_bulk_devres *devres = res;
|
||||
+
|
||||
+ clk_bulk_disable_unprepare(devres->num_clks, devres->clks);
|
||||
+ clk_bulk_put_all(devres->num_clks, devres->clks);
|
||||
+}
|
||||
+
|
||||
+int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
+ struct clk_bulk_data **clks)
|
||||
+{
|
||||
+ struct clk_bulk_devres *devres;
|
||||
+ int ret;
|
||||
+
|
||||
+ devres = devres_alloc(devm_clk_bulk_release_all_enable,
|
||||
+ sizeof(*devres), GFP_KERNEL);
|
||||
+ if (!devres)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = clk_bulk_get_all(dev, &devres->clks);
|
||||
+ if (ret > 0) {
|
||||
+ *clks = devres->clks;
|
||||
+ devres->num_clks = ret;
|
||||
+ } else {
|
||||
+ devres_free(devres);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_bulk_prepare_enable(devres->num_clks, *clks);
|
||||
+ if (!ret) {
|
||||
+ devres_add(dev, devres);
|
||||
+ } else {
|
||||
+ clk_bulk_put_all(devres->num_clks, devres->clks);
|
||||
+ devres_free(devres);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
|
||||
+
|
||||
static int devm_clk_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct clk **c = res;
|
||||
diff --git a/include/linux/clk.h b/include/linux/clk.h
|
||||
index 06f1b292f8a0..0f44d3863de2 100644
|
||||
--- a/include/linux/clk.h
|
||||
+++ b/include/linux/clk.h
|
||||
@@ -478,6 +478,22 @@ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
|
||||
int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
struct clk_bulk_data **clks);
|
||||
|
||||
+/**
|
||||
+ * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
|
||||
+ * @dev: device for clock "consumer"
|
||||
+ * @clks: pointer to the clk_bulk_data table of consumer
|
||||
+ *
|
||||
+ * Returns success (0) or negative errno.
|
||||
+ *
|
||||
+ * This helper function allows drivers to get all clocks of the
|
||||
+ * consumer and enables them in one operation with management.
|
||||
+ * The clks will automatically be disabled and freed when the device
|
||||
+ * is unbound.
|
||||
+ */
|
||||
+
|
||||
+int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
+ struct clk_bulk_data **clks);
|
||||
+
|
||||
/**
|
||||
* devm_clk_get - lookup and obtain a managed reference to a clock producer.
|
||||
* @dev: device for clock "consumer"
|
||||
@@ -968,6 +984,12 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
+ struct clk_bulk_data **clks)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static inline struct clk *devm_get_clk_from_child(struct device *dev,
|
||||
struct device_node *np, const char *con_id)
|
||||
{
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,125 @@
|
||||
From 51e32e897539663957f7a0950f66b48f8896efee Mon Sep 17 00:00:00 2001
|
||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Date: Sat, 19 Oct 2024 14:16:00 +0300
|
||||
Subject: [PATCH] clk: Provide devm_clk_bulk_get_all_enabled() helper
|
||||
|
||||
Commit 265b07df758a ("clk: Provide managed helper to get and enable bulk
|
||||
clocks") added devm_clk_bulk_get_all_enable() function, but missed to
|
||||
return the number of clocks stored in the clk_bulk_data table referenced
|
||||
by the clks argument. Without knowing the number, it's not possible to
|
||||
iterate these clocks when needed, hence the argument is useless and
|
||||
could have been simply removed.
|
||||
|
||||
Introduce devm_clk_bulk_get_all_enabled() variant, which is consistent
|
||||
with devm_clk_bulk_get_all() in terms of the returned value:
|
||||
|
||||
> 0 if one or more clocks have been stored
|
||||
= 0 if there are no clocks
|
||||
< 0 if an error occurred
|
||||
|
||||
Moreover, the naming is consistent with devm_clk_get_enabled(), i.e. use
|
||||
the past form of 'enable'.
|
||||
|
||||
To reduce code duplication and improve patch readability, make
|
||||
devm_clk_bulk_get_all_enable() use the new helper, as suggested by
|
||||
Stephen Boyd.
|
||||
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
|
||||
Link: https://lore.kernel.org/r/20241019-clk_bulk_ena_fix-v4-1-57f108f64e70@collabora.com
|
||||
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
|
||||
---
|
||||
drivers/clk/clk-devres.c | 9 +++++----
|
||||
include/linux/clk.h | 21 ++++++++++++++++-----
|
||||
2 files changed, 21 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
|
||||
index 82ae1f26e634..5368d92d9b39 100644
|
||||
--- a/drivers/clk/clk-devres.c
|
||||
+++ b/drivers/clk/clk-devres.c
|
||||
@@ -218,8 +218,8 @@ static void devm_clk_bulk_release_all_enable(struct device *dev, void *res)
|
||||
clk_bulk_put_all(devres->num_clks, devres->clks);
|
||||
}
|
||||
|
||||
-int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
- struct clk_bulk_data **clks)
|
||||
+int __must_check devm_clk_bulk_get_all_enabled(struct device *dev,
|
||||
+ struct clk_bulk_data **clks)
|
||||
{
|
||||
struct clk_bulk_devres *devres;
|
||||
int ret;
|
||||
@@ -244,11 +244,12 @@ int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
} else {
|
||||
clk_bulk_put_all(devres->num_clks, devres->clks);
|
||||
devres_free(devres);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ return devres->num_clks;
|
||||
}
|
||||
-EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enable);
|
||||
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get_all_enabled);
|
||||
|
||||
static int devm_clk_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
diff --git a/include/linux/clk.h b/include/linux/clk.h
|
||||
index 851a0f2cf42c..1dcee6d701e4 100644
|
||||
--- a/include/linux/clk.h
|
||||
+++ b/include/linux/clk.h
|
||||
@@ -496,11 +496,13 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
struct clk_bulk_data **clks);
|
||||
|
||||
/**
|
||||
- * devm_clk_bulk_get_all_enable - Get and enable all clocks of the consumer (managed)
|
||||
+ * devm_clk_bulk_get_all_enabled - Get and enable all clocks of the consumer (managed)
|
||||
* @dev: device for clock "consumer"
|
||||
* @clks: pointer to the clk_bulk_data table of consumer
|
||||
*
|
||||
- * Returns success (0) or negative errno.
|
||||
+ * Returns a positive value for the number of clocks obtained while the
|
||||
+ * clock references are stored in the clk_bulk_data table in @clks field.
|
||||
+ * Returns 0 if there're none and a negative value if something failed.
|
||||
*
|
||||
* This helper function allows drivers to get all clocks of the
|
||||
* consumer and enables them in one operation with management.
|
||||
@@ -508,8 +510,8 @@ int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
* is unbound.
|
||||
*/
|
||||
|
||||
-int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
- struct clk_bulk_data **clks);
|
||||
+int __must_check devm_clk_bulk_get_all_enabled(struct device *dev,
|
||||
+ struct clk_bulk_data **clks);
|
||||
|
||||
/**
|
||||
* devm_clk_get - lookup and obtain a managed reference to a clock producer.
|
||||
@@ -1034,7 +1036,7 @@ static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int __must_check devm_clk_bulk_get_all_enable(struct device *dev,
|
||||
+static inline int __must_check devm_clk_bulk_get_all_enabled(struct device *dev,
|
||||
struct clk_bulk_data **clks)
|
||||
{
|
||||
return 0;
|
||||
@@ -1136,6 +1138,15 @@ static inline void clk_restore_context(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
+/* Deprecated. Use devm_clk_bulk_get_all_enabled() */
|
||||
+static inline int __must_check
|
||||
+devm_clk_bulk_get_all_enable(struct device *dev, struct clk_bulk_data **clks)
|
||||
+{
|
||||
+ int ret = devm_clk_bulk_get_all_enabled(dev, clks);
|
||||
+
|
||||
+ return ret > 0 ? 0 : ret;
|
||||
+}
|
||||
+
|
||||
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
|
||||
static inline int clk_prepare_enable(struct clk *clk)
|
||||
{
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 475beea0b9f631656b5cc39429a39696876af613 Mon Sep 17 00:00:00 2001
|
||||
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
Date: Tue, 30 Apr 2024 23:07:43 -0500
|
||||
Subject: [PATCH] dt-bindings: clock: Add PCIe pipe related clocks for IPQ9574
|
||||
|
||||
Add defines for the missing PCIe PIPE clocks.
|
||||
|
||||
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240501040800.1542805-2-mr.nuke.me@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
include/dt-bindings/clock/qcom,ipq9574-gcc.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/include/dt-bindings/clock/qcom,ipq9574-gcc.h b/include/dt-bindings/clock/qcom,ipq9574-gcc.h
|
||||
index 08fd3a37acaa..52123c5a09fa 100644
|
||||
--- a/include/dt-bindings/clock/qcom,ipq9574-gcc.h
|
||||
+++ b/include/dt-bindings/clock/qcom,ipq9574-gcc.h
|
||||
@@ -216,4 +216,8 @@
|
||||
#define GCC_CRYPTO_AHB_CLK 207
|
||||
#define GCC_USB0_PIPE_CLK 208
|
||||
#define GCC_USB0_SLEEP_CLK 209
|
||||
+#define GCC_PCIE0_PIPE_CLK 210
|
||||
+#define GCC_PCIE1_PIPE_CLK 211
|
||||
+#define GCC_PCIE2_PIPE_CLK 212
|
||||
+#define GCC_PCIE3_PIPE_CLK 213
|
||||
#endif
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,134 @@
|
||||
From a8fe85d40ffe5ec0fd2f557932ffee902be35b38 Mon Sep 17 00:00:00 2001
|
||||
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
Date: Tue, 30 Apr 2024 23:07:44 -0500
|
||||
Subject: [PATCH] clk: qcom: gcc-ipq9574: Add PCIe pipe clocks
|
||||
|
||||
The IPQ9574 has four PCIe "pipe" clocks. These clocks are required by
|
||||
PCIe PHYs. Port the pipe clocks from the downstream 5.4 kernel.
|
||||
|
||||
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240501040800.1542805-3-mr.nuke.me@gmail.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/gcc-ipq9574.c | 76 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 76 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c
|
||||
index 0a3f846695b8..bc3e17f34295 100644
|
||||
--- a/drivers/clk/qcom/gcc-ipq9574.c
|
||||
+++ b/drivers/clk/qcom/gcc-ipq9574.c
|
||||
@@ -1569,6 +1569,24 @@ static struct clk_regmap_phy_mux pcie0_pipe_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct clk_branch gcc_pcie0_pipe_clk = {
|
||||
+ .halt_reg = 0x28044,
|
||||
+ .halt_check = BRANCH_HALT_DELAY,
|
||||
+ .clkr = {
|
||||
+ .enable_reg = 0x28044,
|
||||
+ .enable_mask = BIT(0),
|
||||
+ .hw.init = &(const struct clk_init_data) {
|
||||
+ .name = "gcc_pcie0_pipe_clk",
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &pcie0_pipe_clk_src.clkr.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ .ops = &clk_branch2_ops,
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct clk_regmap_phy_mux pcie1_pipe_clk_src = {
|
||||
.reg = 0x29064,
|
||||
.clkr = {
|
||||
@@ -1583,6 +1601,24 @@ static struct clk_regmap_phy_mux pcie1_pipe_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct clk_branch gcc_pcie1_pipe_clk = {
|
||||
+ .halt_reg = 0x29044,
|
||||
+ .halt_check = BRANCH_HALT_DELAY,
|
||||
+ .clkr = {
|
||||
+ .enable_reg = 0x29044,
|
||||
+ .enable_mask = BIT(0),
|
||||
+ .hw.init = &(const struct clk_init_data) {
|
||||
+ .name = "gcc_pcie1_pipe_clk",
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &pcie1_pipe_clk_src.clkr.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ .ops = &clk_branch2_ops,
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct clk_regmap_phy_mux pcie2_pipe_clk_src = {
|
||||
.reg = 0x2a064,
|
||||
.clkr = {
|
||||
@@ -1597,6 +1633,24 @@ static struct clk_regmap_phy_mux pcie2_pipe_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct clk_branch gcc_pcie2_pipe_clk = {
|
||||
+ .halt_reg = 0x2a044,
|
||||
+ .halt_check = BRANCH_HALT_DELAY,
|
||||
+ .clkr = {
|
||||
+ .enable_reg = 0x2a044,
|
||||
+ .enable_mask = BIT(0),
|
||||
+ .hw.init = &(const struct clk_init_data) {
|
||||
+ .name = "gcc_pcie2_pipe_clk",
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &pcie2_pipe_clk_src.clkr.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ .ops = &clk_branch2_ops,
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct clk_regmap_phy_mux pcie3_pipe_clk_src = {
|
||||
.reg = 0x2b064,
|
||||
.clkr = {
|
||||
@@ -1611,6 +1665,24 @@ static struct clk_regmap_phy_mux pcie3_pipe_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct clk_branch gcc_pcie3_pipe_clk = {
|
||||
+ .halt_reg = 0x2b044,
|
||||
+ .halt_check = BRANCH_HALT_DELAY,
|
||||
+ .clkr = {
|
||||
+ .enable_reg = 0x2b044,
|
||||
+ .enable_mask = BIT(0),
|
||||
+ .hw.init = &(const struct clk_init_data) {
|
||||
+ .name = "gcc_pcie3_pipe_clk",
|
||||
+ .parent_hws = (const struct clk_hw *[]) {
|
||||
+ &pcie3_pipe_clk_src.clkr.hw
|
||||
+ },
|
||||
+ .num_parents = 1,
|
||||
+ .flags = CLK_SET_RATE_PARENT,
|
||||
+ .ops = &clk_branch2_ops,
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
|
||||
F(24000000, P_XO, 1, 0, 0),
|
||||
F(100000000, P_GPLL0, 8, 0, 0),
|
||||
@@ -4141,6 +4213,10 @@ static struct clk_regmap *gcc_ipq9574_clks[] = {
|
||||
[GCC_SNOC_PCIE1_1LANE_S_CLK] = &gcc_snoc_pcie1_1lane_s_clk.clkr,
|
||||
[GCC_SNOC_PCIE2_2LANE_S_CLK] = &gcc_snoc_pcie2_2lane_s_clk.clkr,
|
||||
[GCC_SNOC_PCIE3_2LANE_S_CLK] = &gcc_snoc_pcie3_2lane_s_clk.clkr,
|
||||
+ [GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr,
|
||||
+ [GCC_PCIE1_PIPE_CLK] = &gcc_pcie1_pipe_clk.clkr,
|
||||
+ [GCC_PCIE2_PIPE_CLK] = &gcc_pcie2_pipe_clk.clkr,
|
||||
+ [GCC_PCIE3_PIPE_CLK] = &gcc_pcie3_pipe_clk.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_ipq9574_resets[] = {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,32 @@
|
||||
From ef3308cf52553522d619a858a72a68f82432865b Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Date: Wed, 29 May 2024 17:47:10 +0300
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq9574: drop #power-domain-cells property
|
||||
of GCC
|
||||
|
||||
On IPQ9574 the Global Clock Controller (GCC) doesn't provide power
|
||||
domains. Drop the #power-domain-cells property from the controller
|
||||
device node.
|
||||
|
||||
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240529-qcom-gdscs-v2-12-69c63d0ae1e7@linaro.org
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
index ded02bc39275..d21937b09b4b 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -315,7 +315,6 @@ gcc: clock-controller@1800000 {
|
||||
<0>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
- #power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
tcsr_mutex: hwlock@1905000 {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,85 @@
|
||||
From f45b94ffc5f1204b35b5c695ed265b1385951616 Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 30 Apr 2024 12:12:09 +0530
|
||||
Subject: [PATCH] interconnect: icc-clk: Specify master/slave ids
|
||||
|
||||
Presently, icc-clk driver autogenerates the master and slave ids.
|
||||
However, devices with multiple nodes on the interconnect could
|
||||
have other constraints and may not match with the auto generated
|
||||
node ids.
|
||||
|
||||
Hence, modify the driver to use the master/slave ids provided by
|
||||
the caller instead of auto generating.
|
||||
|
||||
Also, update clk-cbf-8996 accordingly.
|
||||
|
||||
Acked-by: Georgi Djakov <djakov@kernel.org>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240430064214.2030013-2-quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/clk-cbf-8996.c | 7 ++++++-
|
||||
drivers/interconnect/icc-clk.c | 6 +++---
|
||||
include/linux/interconnect-clk.h | 2 ++
|
||||
3 files changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/qcom/clk-cbf-8996.c b/drivers/clk/qcom/clk-cbf-8996.c
|
||||
index 76bf523431b8..f5fd1ff9c6c9 100644
|
||||
--- a/drivers/clk/qcom/clk-cbf-8996.c
|
||||
+++ b/drivers/clk/qcom/clk-cbf-8996.c
|
||||
@@ -226,7 +226,12 @@ static int qcom_msm8996_cbf_icc_register(struct platform_device *pdev, struct cl
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk *clk = devm_clk_hw_get_clk(dev, cbf_hw, "cbf");
|
||||
const struct icc_clk_data data[] = {
|
||||
- { .clk = clk, .name = "cbf", },
|
||||
+ {
|
||||
+ .clk = clk,
|
||||
+ .name = "cbf",
|
||||
+ .master_id = MASTER_CBF_M4M,
|
||||
+ .slave_id = SLAVE_CBF_M4M,
|
||||
+ },
|
||||
};
|
||||
struct icc_provider *provider;
|
||||
|
||||
diff --git a/drivers/interconnect/icc-clk.c b/drivers/interconnect/icc-clk.c
|
||||
index d787f2ea36d9..2be193fd7d8f 100644
|
||||
--- a/drivers/interconnect/icc-clk.c
|
||||
+++ b/drivers/interconnect/icc-clk.c
|
||||
@@ -108,7 +108,7 @@ struct icc_provider *icc_clk_register(struct device *dev,
|
||||
for (i = 0, j = 0; i < num_clocks; i++) {
|
||||
qp->clocks[i].clk = data[i].clk;
|
||||
|
||||
- node = icc_node_create(first_id + j);
|
||||
+ node = icc_node_create(first_id + data[i].master_id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
@@ -118,10 +118,10 @@ struct icc_provider *icc_clk_register(struct device *dev,
|
||||
node->data = &qp->clocks[i];
|
||||
icc_node_add(node, provider);
|
||||
/* link to the next node, slave */
|
||||
- icc_link_create(node, first_id + j + 1);
|
||||
+ icc_link_create(node, first_id + data[i].slave_id);
|
||||
onecell->nodes[j++] = node;
|
||||
|
||||
- node = icc_node_create(first_id + j);
|
||||
+ node = icc_node_create(first_id + data[i].slave_id);
|
||||
if (IS_ERR(node)) {
|
||||
ret = PTR_ERR(node);
|
||||
goto err;
|
||||
diff --git a/include/linux/interconnect-clk.h b/include/linux/interconnect-clk.h
|
||||
index 0cd80112bea5..170898faaacb 100644
|
||||
--- a/include/linux/interconnect-clk.h
|
||||
+++ b/include/linux/interconnect-clk.h
|
||||
@@ -11,6 +11,8 @@ struct device;
|
||||
struct icc_clk_data {
|
||||
struct clk *clk;
|
||||
const char *name;
|
||||
+ unsigned int master_id;
|
||||
+ unsigned int slave_id;
|
||||
};
|
||||
|
||||
struct icc_provider *icc_clk_register(struct device *dev,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,106 @@
|
||||
From d1f1570f3d6db5d35642092a671812e62bfba79d Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 30 Apr 2024 12:12:10 +0530
|
||||
Subject: [PATCH] dt-bindings: interconnect: Add Qualcomm IPQ9574 support
|
||||
|
||||
Add interconnect-cells to clock provider so that it can be
|
||||
used as icc provider.
|
||||
|
||||
Add master/slave ids for Qualcomm IPQ9574 Network-On-Chip
|
||||
interfaces. This will be used by the gcc-ipq9574 driver
|
||||
that will for providing interconnect services using the
|
||||
icc-clk framework.
|
||||
|
||||
Acked-by: Georgi Djakov <djakov@kernel.org>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240430064214.2030013-3-quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
.../bindings/clock/qcom,ipq9574-gcc.yaml | 3 +
|
||||
.../dt-bindings/interconnect/qcom,ipq9574.h | 59 +++++++++++++++++++
|
||||
2 files changed, 62 insertions(+)
|
||||
create mode 100644 include/dt-bindings/interconnect/qcom,ipq9574.h
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml
|
||||
index 944a0ea79cd6..824781cbdf34 100644
|
||||
--- a/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml
|
||||
+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml
|
||||
@@ -33,6 +33,9 @@ properties:
|
||||
- description: PCIE30 PHY3 pipe clock source
|
||||
- description: USB3 PHY pipe clock source
|
||||
|
||||
+ '#interconnect-cells':
|
||||
+ const: 1
|
||||
+
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
diff --git a/include/dt-bindings/interconnect/qcom,ipq9574.h b/include/dt-bindings/interconnect/qcom,ipq9574.h
|
||||
new file mode 100644
|
||||
index 000000000000..42019335c7dd
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/interconnect/qcom,ipq9574.h
|
||||
@@ -0,0 +1,59 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+#ifndef INTERCONNECT_QCOM_IPQ9574_H
|
||||
+#define INTERCONNECT_QCOM_IPQ9574_H
|
||||
+
|
||||
+#define MASTER_ANOC_PCIE0 0
|
||||
+#define SLAVE_ANOC_PCIE0 1
|
||||
+#define MASTER_SNOC_PCIE0 2
|
||||
+#define SLAVE_SNOC_PCIE0 3
|
||||
+#define MASTER_ANOC_PCIE1 4
|
||||
+#define SLAVE_ANOC_PCIE1 5
|
||||
+#define MASTER_SNOC_PCIE1 6
|
||||
+#define SLAVE_SNOC_PCIE1 7
|
||||
+#define MASTER_ANOC_PCIE2 8
|
||||
+#define SLAVE_ANOC_PCIE2 9
|
||||
+#define MASTER_SNOC_PCIE2 10
|
||||
+#define SLAVE_SNOC_PCIE2 11
|
||||
+#define MASTER_ANOC_PCIE3 12
|
||||
+#define SLAVE_ANOC_PCIE3 13
|
||||
+#define MASTER_SNOC_PCIE3 14
|
||||
+#define SLAVE_SNOC_PCIE3 15
|
||||
+#define MASTER_USB 16
|
||||
+#define SLAVE_USB 17
|
||||
+#define MASTER_USB_AXI 18
|
||||
+#define SLAVE_USB_AXI 19
|
||||
+#define MASTER_NSSNOC_NSSCC 20
|
||||
+#define SLAVE_NSSNOC_NSSCC 21
|
||||
+#define MASTER_NSSNOC_SNOC_0 22
|
||||
+#define SLAVE_NSSNOC_SNOC_0 23
|
||||
+#define MASTER_NSSNOC_SNOC_1 24
|
||||
+#define SLAVE_NSSNOC_SNOC_1 25
|
||||
+#define MASTER_NSSNOC_PCNOC_1 26
|
||||
+#define SLAVE_NSSNOC_PCNOC_1 27
|
||||
+#define MASTER_NSSNOC_QOSGEN_REF 28
|
||||
+#define SLAVE_NSSNOC_QOSGEN_REF 29
|
||||
+#define MASTER_NSSNOC_TIMEOUT_REF 30
|
||||
+#define SLAVE_NSSNOC_TIMEOUT_REF 31
|
||||
+#define MASTER_NSSNOC_XO_DCD 32
|
||||
+#define SLAVE_NSSNOC_XO_DCD 33
|
||||
+#define MASTER_NSSNOC_ATB 34
|
||||
+#define SLAVE_NSSNOC_ATB 35
|
||||
+#define MASTER_MEM_NOC_NSSNOC 36
|
||||
+#define SLAVE_MEM_NOC_NSSNOC 37
|
||||
+#define MASTER_NSSNOC_MEMNOC 38
|
||||
+#define SLAVE_NSSNOC_MEMNOC 39
|
||||
+#define MASTER_NSSNOC_MEM_NOC_1 40
|
||||
+#define SLAVE_NSSNOC_MEM_NOC_1 41
|
||||
+
|
||||
+#define MASTER_NSSNOC_PPE 0
|
||||
+#define SLAVE_NSSNOC_PPE 1
|
||||
+#define MASTER_NSSNOC_PPE_CFG 2
|
||||
+#define SLAVE_NSSNOC_PPE_CFG 3
|
||||
+#define MASTER_NSSNOC_NSS_CSR 4
|
||||
+#define SLAVE_NSSNOC_NSS_CSR 5
|
||||
+#define MASTER_NSSNOC_IMEM_QSB 6
|
||||
+#define SLAVE_NSSNOC_IMEM_QSB 7
|
||||
+#define MASTER_NSSNOC_IMEM_AHB 8
|
||||
+#define SLAVE_NSSNOC_IMEM_AHB 9
|
||||
+
|
||||
+#endif /* INTERCONNECT_QCOM_IPQ9574_H */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,63 @@
|
||||
From d3153113619216e87038a20bebf82582f9be10e7 Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 30 Apr 2024 12:12:11 +0530
|
||||
Subject: [PATCH] interconnect: icc-clk: Add devm_icc_clk_register
|
||||
|
||||
Wrap icc_clk_register to create devm_icc_clk_register to be
|
||||
able to release the resources properly.
|
||||
|
||||
Acked-by: Georgi Djakov <djakov@kernel.org>
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240430064214.2030013-4-quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/interconnect/icc-clk.c | 18 ++++++++++++++++++
|
||||
include/linux/interconnect-clk.h | 2 ++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/drivers/interconnect/icc-clk.c b/drivers/interconnect/icc-clk.c
|
||||
index 2be193fd7d8f..f788db15cd76 100644
|
||||
--- a/drivers/interconnect/icc-clk.c
|
||||
+++ b/drivers/interconnect/icc-clk.c
|
||||
@@ -148,6 +148,24 @@ struct icc_provider *icc_clk_register(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_clk_register);
|
||||
|
||||
+static void devm_icc_release(void *res)
|
||||
+{
|
||||
+ icc_clk_unregister(res);
|
||||
+}
|
||||
+
|
||||
+int devm_icc_clk_register(struct device *dev, unsigned int first_id,
|
||||
+ unsigned int num_clocks, const struct icc_clk_data *data)
|
||||
+{
|
||||
+ struct icc_provider *prov;
|
||||
+
|
||||
+ prov = icc_clk_register(dev, first_id, num_clocks, data);
|
||||
+ if (IS_ERR(prov))
|
||||
+ return PTR_ERR(prov);
|
||||
+
|
||||
+ return devm_add_action_or_reset(dev, devm_icc_release, prov);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_icc_clk_register);
|
||||
+
|
||||
/**
|
||||
* icc_clk_unregister() - unregister a previously registered clk interconnect provider
|
||||
* @provider: provider returned by icc_clk_register()
|
||||
diff --git a/include/linux/interconnect-clk.h b/include/linux/interconnect-clk.h
|
||||
index 170898faaacb..9bcee3e9c56c 100644
|
||||
--- a/include/linux/interconnect-clk.h
|
||||
+++ b/include/linux/interconnect-clk.h
|
||||
@@ -19,6 +19,8 @@ struct icc_provider *icc_clk_register(struct device *dev,
|
||||
unsigned int first_id,
|
||||
unsigned int num_clocks,
|
||||
const struct icc_clk_data *data);
|
||||
+int devm_icc_clk_register(struct device *dev, unsigned int first_id,
|
||||
+ unsigned int num_clocks, const struct icc_clk_data *data);
|
||||
void icc_clk_unregister(struct icc_provider *provider);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,115 @@
|
||||
From 8737ec830ee32162858af7c1504169b05b313ab1 Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 30 Apr 2024 12:12:12 +0530
|
||||
Subject: [PATCH] clk: qcom: common: Add interconnect clocks support
|
||||
|
||||
Unlike MSM platforms that manage NoC related clocks and scaling
|
||||
from RPM, IPQ SoCs dont involve RPM in managing NoC related
|
||||
clocks and there is no NoC scaling.
|
||||
|
||||
However, there is a requirement to enable some NoC interface
|
||||
clocks for accessing the peripheral controllers present on
|
||||
these NoCs. Though exposing these as normal clocks would work,
|
||||
having a minimalistic interconnect driver to handle these clocks
|
||||
would make it consistent with other Qualcomm platforms resulting
|
||||
in common code paths. This is similar to msm8996-cbf's usage of
|
||||
icc-clk framework.
|
||||
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240430064214.2030013-5-quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/common.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||
drivers/clk/qcom/common.h | 9 +++++++++
|
||||
2 files changed, 43 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
|
||||
index c92e10c60322..ea3788ba46f7 100644
|
||||
--- a/drivers/clk/qcom/common.c
|
||||
+++ b/drivers/clk/qcom/common.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk-provider.h>
|
||||
+#include <linux/interconnect-clk.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
@@ -252,6 +253,38 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
|
||||
return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL;
|
||||
}
|
||||
|
||||
+static int qcom_cc_icc_register(struct device *dev,
|
||||
+ const struct qcom_cc_desc *desc)
|
||||
+{
|
||||
+ struct icc_clk_data *icd;
|
||||
+ struct clk_hw *hws;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!IS_ENABLED(CONFIG_INTERCONNECT_CLK))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!desc->icc_hws)
|
||||
+ return 0;
|
||||
+
|
||||
+ icd = devm_kcalloc(dev, desc->num_icc_hws, sizeof(*icd), GFP_KERNEL);
|
||||
+ if (!icd)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < desc->num_icc_hws; i++) {
|
||||
+ icd[i].master_id = desc->icc_hws[i].master_id;
|
||||
+ icd[i].slave_id = desc->icc_hws[i].slave_id;
|
||||
+ hws = &desc->clks[desc->icc_hws[i].clk_id]->hw;
|
||||
+ icd[i].clk = devm_clk_hw_get_clk(dev, hws, "icc");
|
||||
+ if (!icd[i].clk)
|
||||
+ return dev_err_probe(dev, -ENOENT,
|
||||
+ "(%d) clock entry is null\n", i);
|
||||
+ icd[i].name = clk_hw_get_name(hws);
|
||||
+ }
|
||||
+
|
||||
+ return devm_icc_clk_register(dev, desc->icc_first_node_id,
|
||||
+ desc->num_icc_hws, icd);
|
||||
+}
|
||||
+
|
||||
int qcom_cc_really_probe(struct device *dev,
|
||||
const struct qcom_cc_desc *desc, struct regmap *regmap)
|
||||
{
|
||||
@@ -320,7 +353,7 @@ int qcom_cc_really_probe(struct device *dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return 0;
|
||||
+ return qcom_cc_icc_register(dev, desc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
|
||||
|
||||
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
|
||||
index d048bdeeba10..7e57f8fe8ea6 100644
|
||||
--- a/drivers/clk/qcom/common.h
|
||||
+++ b/drivers/clk/qcom/common.h
|
||||
@@ -19,6 +19,12 @@ struct clk_hw;
|
||||
#define PLL_VOTE_FSM_ENA BIT(20)
|
||||
#define PLL_VOTE_FSM_RESET BIT(21)
|
||||
|
||||
+struct qcom_icc_hws_data {
|
||||
+ int master_id;
|
||||
+ int slave_id;
|
||||
+ int clk_id;
|
||||
+};
|
||||
+
|
||||
struct qcom_cc_desc {
|
||||
const struct regmap_config *config;
|
||||
struct clk_regmap **clks;
|
||||
@@ -29,6 +35,9 @@ struct qcom_cc_desc {
|
||||
size_t num_gdscs;
|
||||
struct clk_hw **clk_hws;
|
||||
size_t num_clk_hws;
|
||||
+ struct qcom_icc_hws_data *icc_hws;
|
||||
+ size_t num_icc_hws;
|
||||
+ unsigned int icc_first_node_id;
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,106 @@
|
||||
From 23711cabe122ef55bcb2e5c3e3835b5a2a688fc0 Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 30 Apr 2024 12:12:13 +0530
|
||||
Subject: [PATCH] clk: qcom: ipq9574: Use icc-clk for enabling NoC related
|
||||
clocks
|
||||
|
||||
Use the icc-clk framework to enable few clocks to be able to
|
||||
create paths and use the peripherals connected on those NoCs.
|
||||
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240430064214.2030013-6-quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/Kconfig | 2 ++
|
||||
drivers/clk/qcom/gcc-ipq9574.c | 33 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 35 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
|
||||
index 1231eae51556..11ae28430dad 100644
|
||||
--- a/drivers/clk/qcom/Kconfig
|
||||
+++ b/drivers/clk/qcom/Kconfig
|
||||
@@ -14,6 +14,8 @@ menuconfig COMMON_CLK_QCOM
|
||||
select RATIONAL
|
||||
select REGMAP_MMIO
|
||||
select RESET_CONTROLLER
|
||||
+ select INTERCONNECT
|
||||
+ select INTERCONNECT_CLK
|
||||
|
||||
if COMMON_CLK_QCOM
|
||||
|
||||
diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c
|
||||
index bc3e17f34295..f08a447370bd 100644
|
||||
--- a/drivers/clk/qcom/gcc-ipq9574.c
|
||||
+++ b/drivers/clk/qcom/gcc-ipq9574.c
|
||||
@@ -4,6 +4,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
+#include <linux/interconnect-clk.h>
|
||||
+#include <linux/interconnect-provider.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@@ -12,6 +14,7 @@
|
||||
|
||||
#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
|
||||
#include <dt-bindings/reset/qcom,ipq9574-gcc.h>
|
||||
+#include <dt-bindings/interconnect/qcom,ipq9574.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
@@ -4377,6 +4380,32 @@ static const struct qcom_reset_map gcc_ipq9574_resets[] = {
|
||||
[GCC_WCSS_Q6_TBU_BCR] = { 0x12054, 0 },
|
||||
};
|
||||
|
||||
+#define IPQ_APPS_ID 9574 /* some unique value */
|
||||
+
|
||||
+static struct qcom_icc_hws_data icc_ipq9574_hws[] = {
|
||||
+ { MASTER_ANOC_PCIE0, SLAVE_ANOC_PCIE0, GCC_ANOC_PCIE0_1LANE_M_CLK },
|
||||
+ { MASTER_SNOC_PCIE0, SLAVE_SNOC_PCIE0, GCC_SNOC_PCIE0_1LANE_S_CLK },
|
||||
+ { MASTER_ANOC_PCIE1, SLAVE_ANOC_PCIE1, GCC_ANOC_PCIE1_1LANE_M_CLK },
|
||||
+ { MASTER_SNOC_PCIE1, SLAVE_SNOC_PCIE1, GCC_SNOC_PCIE1_1LANE_S_CLK },
|
||||
+ { MASTER_ANOC_PCIE2, SLAVE_ANOC_PCIE2, GCC_ANOC_PCIE2_2LANE_M_CLK },
|
||||
+ { MASTER_SNOC_PCIE2, SLAVE_SNOC_PCIE2, GCC_SNOC_PCIE2_2LANE_S_CLK },
|
||||
+ { MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK },
|
||||
+ { MASTER_SNOC_PCIE3, SLAVE_SNOC_PCIE3, GCC_SNOC_PCIE3_2LANE_S_CLK },
|
||||
+ { MASTER_USB, SLAVE_USB, GCC_SNOC_USB_CLK },
|
||||
+ { MASTER_USB_AXI, SLAVE_USB_AXI, GCC_ANOC_USB_AXI_CLK },
|
||||
+ { MASTER_NSSNOC_NSSCC, SLAVE_NSSNOC_NSSCC, GCC_NSSNOC_NSSCC_CLK },
|
||||
+ { MASTER_NSSNOC_SNOC_0, SLAVE_NSSNOC_SNOC_0, GCC_NSSNOC_SNOC_CLK },
|
||||
+ { MASTER_NSSNOC_SNOC_1, SLAVE_NSSNOC_SNOC_1, GCC_NSSNOC_SNOC_1_CLK },
|
||||
+ { MASTER_NSSNOC_PCNOC_1, SLAVE_NSSNOC_PCNOC_1, GCC_NSSNOC_PCNOC_1_CLK },
|
||||
+ { MASTER_NSSNOC_QOSGEN_REF, SLAVE_NSSNOC_QOSGEN_REF, GCC_NSSNOC_QOSGEN_REF_CLK },
|
||||
+ { MASTER_NSSNOC_TIMEOUT_REF, SLAVE_NSSNOC_TIMEOUT_REF, GCC_NSSNOC_TIMEOUT_REF_CLK },
|
||||
+ { MASTER_NSSNOC_XO_DCD, SLAVE_NSSNOC_XO_DCD, GCC_NSSNOC_XO_DCD_CLK },
|
||||
+ { MASTER_NSSNOC_ATB, SLAVE_NSSNOC_ATB, GCC_NSSNOC_ATB_CLK },
|
||||
+ { MASTER_MEM_NOC_NSSNOC, SLAVE_MEM_NOC_NSSNOC, GCC_MEM_NOC_NSSNOC_CLK },
|
||||
+ { MASTER_NSSNOC_MEMNOC, SLAVE_NSSNOC_MEMNOC, GCC_NSSNOC_MEMNOC_CLK },
|
||||
+ { MASTER_NSSNOC_MEM_NOC_1, SLAVE_NSSNOC_MEM_NOC_1, GCC_NSSNOC_MEM_NOC_1_CLK },
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id gcc_ipq9574_match_table[] = {
|
||||
{ .compatible = "qcom,ipq9574-gcc" },
|
||||
{ }
|
||||
@@ -4399,6 +4428,9 @@ static const struct qcom_cc_desc gcc_ipq9574_desc = {
|
||||
.num_resets = ARRAY_SIZE(gcc_ipq9574_resets),
|
||||
.clk_hws = gcc_ipq9574_hws,
|
||||
.num_clk_hws = ARRAY_SIZE(gcc_ipq9574_hws),
|
||||
+ .icc_hws = icc_ipq9574_hws,
|
||||
+ .num_icc_hws = ARRAY_SIZE(icc_ipq9574_hws),
|
||||
+ .icc_first_node_id = IPQ_APPS_ID,
|
||||
};
|
||||
|
||||
static int gcc_ipq9574_probe(struct platform_device *pdev)
|
||||
@@ -4411,6 +4443,7 @@ static struct platform_driver gcc_ipq9574_driver = {
|
||||
.driver = {
|
||||
.name = "qcom,gcc-ipq9574",
|
||||
.of_match_table = gcc_ipq9574_match_table,
|
||||
+ .sync_state = icc_sync_state,
|
||||
},
|
||||
};
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,46 @@
|
||||
From 5d0ab61a700214366dfcca5893b87655261e8c94 Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 30 Apr 2024 12:12:14 +0530
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq9574: Add icc provider ability to gcc
|
||||
|
||||
IPQ SoCs dont involve RPM in managing NoC related clocks and
|
||||
there is no NoC scaling. Linux itself handles these clocks.
|
||||
However, these should not be exposed as just clocks and align
|
||||
with other Qualcomm SoCs that handle these clocks from a
|
||||
interconnect provider.
|
||||
|
||||
Hence include icc provider capability to the gcc node so that
|
||||
peripherals can use the interconnect facility to enable these
|
||||
clocks.
|
||||
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20240430064214.2030013-7-quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
index 04ba09a9156c..48dfafea46a7 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <dt-bindings/clock/qcom,apss-ipq.h>
|
||||
#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
|
||||
+#include <dt-bindings/interconnect/qcom,ipq9574.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/reset/qcom,ipq9574-gcc.h>
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
@@ -315,6 +316,7 @@ gcc: clock-controller@1800000 {
|
||||
<0>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
+ #interconnect-cells = <1>;
|
||||
};
|
||||
|
||||
tcsr_mutex: hwlock@1905000 {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,68 @@
|
||||
From ba5a61a08d83b18b99c461b4ddb9009947a4aa0e Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 31 Oct 2023 12:41:38 +0530
|
||||
Subject: [PATCH 1/2] cpufreq: qcom-nvmem: Enable cpufreq for ipq53xx
|
||||
|
||||
IPQ53xx have different OPPs available for the CPU based on
|
||||
SoC variant. This can be determined through use of an eFuse
|
||||
register present in the silicon.
|
||||
|
||||
Added support for ipq53xx on nvmem driver which helps to
|
||||
determine OPPs at runtime based on the eFuse register which
|
||||
has the CPU frequency limits. opp-supported-hw dt binding
|
||||
can be used to indicate the available OPPs for each limit.
|
||||
|
||||
nvmem driver also creates the "cpufreq-dt" platform_device after
|
||||
passing the version matching data to the OPP framework so that the
|
||||
cpufreq-dt handles the actual cpufreq implementation.
|
||||
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
Signed-off-by: Kathiravan T <quic_kathirav@quicinc.com>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
[ Viresh: Fixed subject ]
|
||||
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
---
|
||||
drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
|
||||
drivers/cpufreq/qcom-cpufreq-nvmem.c | 6 ++++++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
index 07181913448f..53da25589e5f 100644
|
||||
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
@@ -180,6 +180,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
||||
{ .compatible = "ti,am62a7", },
|
||||
{ .compatible = "ti,am62p5", },
|
||||
|
||||
+ { .compatible = "qcom,ipq5332", },
|
||||
{ .compatible = "qcom,ipq8064", },
|
||||
{ .compatible = "qcom,apq8064", },
|
||||
{ .compatible = "qcom,msm8974", },
|
||||
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
|
||||
index 158c0e139185..4f7af70169e0 100644
|
||||
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
|
||||
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
|
||||
@@ -183,6 +183,11 @@ static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
|
||||
switch (msm_id) {
|
||||
case QCOM_ID_MSM8996:
|
||||
case QCOM_ID_APQ8096:
|
||||
+ case QCOM_ID_IPQ5332:
|
||||
+ case QCOM_ID_IPQ5322:
|
||||
+ case QCOM_ID_IPQ5312:
|
||||
+ case QCOM_ID_IPQ5302:
|
||||
+ case QCOM_ID_IPQ5300:
|
||||
drv->versions = 1 << (unsigned int)(*speedbin);
|
||||
break;
|
||||
case QCOM_ID_MSM8996SG:
|
||||
@@ -541,6 +546,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst = {
|
||||
{ .compatible = "qcom,apq8096", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,msm8996", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
|
||||
+ { .compatible = "qcom,ipq5332", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,ipq8064", .data = &match_data_krait },
|
||||
{ .compatible = "qcom,apq8064", .data = &match_data_krait },
|
||||
{ .compatible = "qcom,msm8974", .data = &match_data_krait },
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 5b5b5806f22390808b8e8fa180fe35b003a4a74d Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Tue, 31 Oct 2023 12:41:39 +0530
|
||||
Subject: [PATCH 2/2] cpufreq: qcom-nvmem: Introduce cpufreq for ipq95xx
|
||||
|
||||
IPQ95xx SoCs have different OPPs available for the CPU based on
|
||||
the SoC variant. This can be determined from an eFuse register
|
||||
present in the silicon.
|
||||
|
||||
Added support for ipq95xx on nvmem driver which helps to
|
||||
determine OPPs at runtime based on the eFuse register which
|
||||
has the CPU frequency limits. opp-supported-hw dt binding
|
||||
can be used to indicate the available OPPs for each limit.
|
||||
|
||||
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
|
||||
Signed-off-by: Praveenkumar I <ipkumar@codeaurora.org>
|
||||
Signed-off-by: Kathiravan T <quic_kathirav@quicinc.com>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
[ Viresh: Fixed subject ]
|
||||
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
---
|
||||
drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
|
||||
drivers/cpufreq/qcom-cpufreq-nvmem.c | 6 ++++++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
index 53da25589e5f..bd1e1357cef8 100644
|
||||
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
@@ -184,6 +184,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
||||
|
||||
{ .compatible = "qcom,ipq5332", },
|
||||
{ .compatible = "qcom,ipq8064", },
|
||||
+ { .compatible = "qcom,ipq9574", },
|
||||
{ .compatible = "qcom,apq8064", },
|
||||
{ .compatible = "qcom,msm8974", },
|
||||
{ .compatible = "qcom,msm8960", },
|
||||
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
|
||||
index 4f7af70169e0..6355a39418c5 100644
|
||||
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
|
||||
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
|
||||
@@ -188,6 +188,11 @@ static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
|
||||
case QCOM_ID_IPQ5312:
|
||||
case QCOM_ID_IPQ5302:
|
||||
case QCOM_ID_IPQ5300:
|
||||
+ case QCOM_ID_IPQ9514:
|
||||
+ case QCOM_ID_IPQ9550:
|
||||
+ case QCOM_ID_IPQ9554:
|
||||
+ case QCOM_ID_IPQ9570:
|
||||
+ case QCOM_ID_IPQ9574:
|
||||
drv->versions = 1 << (unsigned int)(*speedbin);
|
||||
break;
|
||||
case QCOM_ID_MSM8996SG:
|
||||
@@ -551,6 +556,7 @@ static const struct of_device_id qcom_cpufreq_match_list[] __initconst = {
|
||||
{ .compatible = "qcom,ipq5332", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,ipq8064", .data = &match_data_krait },
|
||||
{ .compatible = "qcom,apq8064", .data = &match_data_krait },
|
||||
+ { .compatible = "qcom,ipq9574", .data = &match_data_kryo },
|
||||
{ .compatible = "qcom,msm8974", .data = &match_data_krait },
|
||||
{ .compatible = "qcom,msm8960", .data = &match_data_krait },
|
||||
{},
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,110 @@
|
||||
From b36074357baf2794c825ea1c145de1d22b15380b Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Fri, 20 Oct 2023 11:49:39 +0530
|
||||
Subject: [PATCH] arm64: dts: qcom: ipq9574: populate the opp table based on
|
||||
the eFuse
|
||||
|
||||
IPQ95xx SoCs have different OPPs available for the CPU based on
|
||||
SoC variant. This can be determined from an eFuse register
|
||||
present in the silicon.
|
||||
|
||||
Add support to read the eFuse and populate the OPPs based on it.
|
||||
|
||||
Frequency 1.2GHz 1.8GHz 1.5GHz No opp-supported-hw
|
||||
Limit
|
||||
------------------------------------------------------------
|
||||
936000000 1 1 1 1 0xf
|
||||
1104000000 1 1 1 1 0xf
|
||||
1200000000 1 1 1 1 0xf
|
||||
1416000000 0 1 1 1 0x7
|
||||
1488000000 0 1 1 1 0x7
|
||||
1800000000 0 1 0 1 0x5
|
||||
2208000000 0 0 0 1 0x1
|
||||
-----------------------------------------------------------
|
||||
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
Signed-off-by: Kathiravan T <quic_kathirav@quicinc.com>
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/14ab08b7cfd904433ca6065fac798d4f221c9d95.1697781921.git.quic_varada@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
index 8a72ad4afd03..d4b7e215fc92 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -106,42 +106,56 @@ memory@40000000 {
|
||||
};
|
||||
|
||||
cpu_opp_table: opp-table-cpu {
|
||||
- compatible = "operating-points-v2";
|
||||
+ compatible = "operating-points-v2-kryo-cpu";
|
||||
opp-shared;
|
||||
+ nvmem-cells = <&cpu_speed_bin>;
|
||||
|
||||
opp-936000000 {
|
||||
opp-hz = /bits/ 64 <936000000>;
|
||||
opp-microvolt = <725000>;
|
||||
+ opp-supported-hw = <0xf>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
|
||||
opp-1104000000 {
|
||||
opp-hz = /bits/ 64 <1104000000>;
|
||||
opp-microvolt = <787500>;
|
||||
+ opp-supported-hw = <0xf>;
|
||||
+ clock-latency-ns = <200000>;
|
||||
+ };
|
||||
+
|
||||
+ opp-1200000000 {
|
||||
+ opp-hz = /bits/ 64 <1200000000>;
|
||||
+ opp-microvolt = <862500>;
|
||||
+ opp-supported-hw = <0xf>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
|
||||
opp-1416000000 {
|
||||
opp-hz = /bits/ 64 <1416000000>;
|
||||
opp-microvolt = <862500>;
|
||||
+ opp-supported-hw = <0x7>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
|
||||
opp-1488000000 {
|
||||
opp-hz = /bits/ 64 <1488000000>;
|
||||
opp-microvolt = <925000>;
|
||||
+ opp-supported-hw = <0x7>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
|
||||
opp-1800000000 {
|
||||
opp-hz = /bits/ 64 <1800000000>;
|
||||
opp-microvolt = <987500>;
|
||||
+ opp-supported-hw = <0x5>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
|
||||
opp-2208000000 {
|
||||
opp-hz = /bits/ 64 <2208000000>;
|
||||
opp-microvolt = <1062500>;
|
||||
+ opp-supported-hw = <0x1>;
|
||||
clock-latency-ns = <200000>;
|
||||
};
|
||||
};
|
||||
@@ -223,6 +237,11 @@ qfprom: efuse@a4000 {
|
||||
reg = <0x000a4000 0x5a1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
+
|
||||
+ cpu_speed_bin: cpu-speed-bin@15 {
|
||||
+ reg = <0x15 0x2>;
|
||||
+ bits = <7 2>;
|
||||
+ };
|
||||
};
|
||||
|
||||
cryptobam: dma-controller@704000 {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,31 @@
|
||||
From ad663ce6780477177e301756ade6cf236f36ae4c Mon Sep 17 00:00:00 2001
|
||||
From: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Date: Thu, 14 Dec 2023 16:10:52 +0530
|
||||
Subject: [PATCH] regulator: qcom_smd: Add LDO5 MP5496 regulator
|
||||
|
||||
Add support for LDO5 regulator. This is used by IPQ9574 USB.
|
||||
|
||||
Signed-off-by: Varadarajan Narayanan <quic_varada@quicinc.com>
|
||||
Rule: <add>
|
||||
Link: https://lore.kernel.org/stable/20231214104052.3267039-1-quic_varada%40quicinc.com
|
||||
Link: https://msgid.link/r/20231214104052.3267039-1-quic_varada@quicinc.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/regulator/qcom_smd-regulator.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
|
||||
index 09c471a0ba2e..d1be9568025e 100644
|
||||
--- a/drivers/regulator/qcom_smd-regulator.c
|
||||
+++ b/drivers/regulator/qcom_smd-regulator.c
|
||||
@@ -796,6 +796,7 @@ static const struct rpm_regulator_data rpm_mp5496_regulators[] = {
|
||||
{ "s1", QCOM_SMD_RPM_SMPA, 1, &mp5496_smps, "s1" },
|
||||
{ "s2", QCOM_SMD_RPM_SMPA, 2, &mp5496_smps, "s2" },
|
||||
{ "l2", QCOM_SMD_RPM_LDOA, 2, &mp5496_ldoa2, "l2" },
|
||||
+ { "l5", QCOM_SMD_RPM_LDOA, 5, &mp5496_ldoa2, "l5" },
|
||||
{}
|
||||
};
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,885 @@
|
||||
From 1d479f5b345e0c3650fec4dddeef9fc6fab30c8b Mon Sep 17 00:00:00 2001
|
||||
From: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Date: Wed, 20 Nov 2024 14:45:01 +0530
|
||||
Subject: [PATCH 2/4] mtd: rawnand: qcom: Add qcom prefix to common api
|
||||
|
||||
Add qcom prefix to all the api which will be commonly
|
||||
used by spi nand driver and raw nand driver.
|
||||
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
---
|
||||
drivers/mtd/nand/raw/qcom_nandc.c | 320 +++++++++++++++---------------
|
||||
1 file changed, 160 insertions(+), 160 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
|
||||
index 9ae8c9f2ab55..6da5d23d2c8b 100644
|
||||
--- a/drivers/mtd/nand/raw/qcom_nandc.c
|
||||
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
|
||||
@@ -53,7 +53,7 @@
|
||||
#define NAND_READ_LOCATION_LAST_CW_2 0xf48
|
||||
#define NAND_READ_LOCATION_LAST_CW_3 0xf4c
|
||||
|
||||
-/* dummy register offsets, used by write_reg_dma */
|
||||
+/* dummy register offsets, used by qcom_write_reg_dma */
|
||||
#define NAND_DEV_CMD1_RESTORE 0xdead
|
||||
#define NAND_DEV_CMD_VLD_RESTORE 0xbeef
|
||||
|
||||
@@ -211,7 +211,7 @@
|
||||
|
||||
/*
|
||||
* Flags used in DMA descriptor preparation helper functions
|
||||
- * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma)
|
||||
+ * (i.e. qcom_read_reg_dma/qcom_write_reg_dma/qcom_read_data_dma/qcom_write_data_dma)
|
||||
*/
|
||||
/* Don't set the EOT in current tx BAM sgl */
|
||||
#define NAND_BAM_NO_EOT BIT(0)
|
||||
@@ -550,7 +550,7 @@ struct qcom_nandc_props {
|
||||
};
|
||||
|
||||
/* Frees the BAM transaction memory */
|
||||
-static void free_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
+static void qcom_free_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
{
|
||||
struct bam_transaction *bam_txn = nandc->bam_txn;
|
||||
|
||||
@@ -559,7 +559,7 @@ static void free_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
|
||||
/* Allocates and Initializes the BAM transaction */
|
||||
static struct bam_transaction *
|
||||
-alloc_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
+qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
{
|
||||
struct bam_transaction *bam_txn;
|
||||
size_t bam_txn_size;
|
||||
@@ -595,7 +595,7 @@ alloc_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
}
|
||||
|
||||
/* Clears the BAM transaction indexes */
|
||||
-static void clear_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
+static void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
{
|
||||
struct bam_transaction *bam_txn = nandc->bam_txn;
|
||||
|
||||
@@ -614,7 +614,7 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
}
|
||||
|
||||
/* Callback for DMA descriptor completion */
|
||||
-static void qpic_bam_dma_done(void *data)
|
||||
+static void qcom_qpic_bam_dma_done(void *data)
|
||||
{
|
||||
struct bam_transaction *bam_txn = data;
|
||||
|
||||
@@ -644,7 +644,7 @@ static void nandc_write(struct qcom_nand_controller *nandc, int offset,
|
||||
iowrite32(val, nandc->base + offset);
|
||||
}
|
||||
|
||||
-static void nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
|
||||
+static void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu)
|
||||
{
|
||||
if (!nandc->props->supports_bam)
|
||||
return;
|
||||
@@ -824,9 +824,9 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i
|
||||
* for BAM. This descriptor will be added in the NAND DMA descriptor queue
|
||||
* which will be submitted to DMA engine.
|
||||
*/
|
||||
-static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
|
||||
- struct dma_chan *chan,
|
||||
- unsigned long flags)
|
||||
+static int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc,
|
||||
+ struct dma_chan *chan,
|
||||
+ unsigned long flags)
|
||||
{
|
||||
struct desc_info *desc;
|
||||
struct scatterlist *sgl;
|
||||
@@ -903,9 +903,9 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
|
||||
* NAND_BAM_NEXT_SGL will be used for starting the separate SGL
|
||||
* after the current command element.
|
||||
*/
|
||||
-static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
|
||||
- int reg_off, const void *vaddr,
|
||||
- int size, unsigned int flags)
|
||||
+static int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
|
||||
+ int reg_off, const void *vaddr,
|
||||
+ int size, unsigned int flags)
|
||||
{
|
||||
int bam_ce_size;
|
||||
int i, ret;
|
||||
@@ -943,9 +943,9 @@ static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
|
||||
bam_txn->bam_ce_start = bam_txn->bam_ce_pos;
|
||||
|
||||
if (flags & NAND_BAM_NWD) {
|
||||
- ret = prepare_bam_async_desc(nandc, nandc->cmd_chan,
|
||||
- DMA_PREP_FENCE |
|
||||
- DMA_PREP_CMD);
|
||||
+ ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
|
||||
+ DMA_PREP_FENCE |
|
||||
+ DMA_PREP_CMD);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -958,9 +958,8 @@ static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
|
||||
* Prepares the data descriptor for BAM DMA which will be used for NAND
|
||||
* data reads and writes.
|
||||
*/
|
||||
-static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
|
||||
- const void *vaddr,
|
||||
- int size, unsigned int flags)
|
||||
+static int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
|
||||
+ const void *vaddr, int size, unsigned int flags)
|
||||
{
|
||||
int ret;
|
||||
struct bam_transaction *bam_txn = nandc->bam_txn;
|
||||
@@ -979,8 +978,8 @@ static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
|
||||
* is not set, form the DMA descriptor
|
||||
*/
|
||||
if (!(flags & NAND_BAM_NO_EOT)) {
|
||||
- ret = prepare_bam_async_desc(nandc, nandc->tx_chan,
|
||||
- DMA_PREP_INTERRUPT);
|
||||
+ ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
|
||||
+ DMA_PREP_INTERRUPT);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -989,9 +988,9 @@ static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
|
||||
- int reg_off, const void *vaddr, int size,
|
||||
- bool flow_control)
|
||||
+static int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
|
||||
+ int reg_off, const void *vaddr, int size,
|
||||
+ bool flow_control)
|
||||
{
|
||||
struct desc_info *desc;
|
||||
struct dma_async_tx_descriptor *dma_desc;
|
||||
@@ -1069,15 +1068,15 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
|
||||
}
|
||||
|
||||
/*
|
||||
- * read_reg_dma: prepares a descriptor to read a given number of
|
||||
+ * qcom_read_reg_dma: prepares a descriptor to read a given number of
|
||||
* contiguous registers to the reg_read_buf pointer
|
||||
*
|
||||
* @first: offset of the first register in the contiguous block
|
||||
* @num_regs: number of registers to read
|
||||
* @flags: flags to control DMA descriptor preparation
|
||||
*/
|
||||
-static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
|
||||
- int num_regs, unsigned int flags)
|
||||
+static int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first,
|
||||
+ int num_regs, unsigned int flags)
|
||||
{
|
||||
bool flow_control = false;
|
||||
void *vaddr;
|
||||
@@ -1089,18 +1088,18 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
|
||||
first = dev_cmd_reg_addr(nandc, first);
|
||||
|
||||
if (nandc->props->supports_bam)
|
||||
- return prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
|
||||
+ return qcom_prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
|
||||
num_regs, flags);
|
||||
|
||||
if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
|
||||
flow_control = true;
|
||||
|
||||
- return prep_adm_dma_desc(nandc, true, first, vaddr,
|
||||
+ return qcom_prep_adm_dma_desc(nandc, true, first, vaddr,
|
||||
num_regs * sizeof(u32), flow_control);
|
||||
}
|
||||
|
||||
/*
|
||||
- * write_reg_dma: prepares a descriptor to write a given number of
|
||||
+ * qcom_write_reg_dma: prepares a descriptor to write a given number of
|
||||
* contiguous registers
|
||||
*
|
||||
* @vaddr: contiguous memory from where register value will
|
||||
@@ -1109,8 +1108,8 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
|
||||
* @num_regs: number of registers to write
|
||||
* @flags: flags to control DMA descriptor preparation
|
||||
*/
|
||||
-static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
|
||||
- int first, int num_regs, unsigned int flags)
|
||||
+static int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
|
||||
+ int first, int num_regs, unsigned int flags)
|
||||
{
|
||||
bool flow_control = false;
|
||||
|
||||
@@ -1124,18 +1123,18 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
|
||||
first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
|
||||
|
||||
if (nandc->props->supports_bam)
|
||||
- return prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
|
||||
+ return qcom_prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
|
||||
num_regs, flags);
|
||||
|
||||
if (first == NAND_FLASH_CMD)
|
||||
flow_control = true;
|
||||
|
||||
- return prep_adm_dma_desc(nandc, false, first, vaddr,
|
||||
+ return qcom_prep_adm_dma_desc(nandc, false, first, vaddr,
|
||||
num_regs * sizeof(u32), flow_control);
|
||||
}
|
||||
|
||||
/*
|
||||
- * read_data_dma: prepares a DMA descriptor to transfer data from the
|
||||
+ * qcom_read_data_dma: prepares a DMA descriptor to transfer data from the
|
||||
* controller's internal buffer to the buffer 'vaddr'
|
||||
*
|
||||
* @reg_off: offset within the controller's data buffer
|
||||
@@ -1143,17 +1142,17 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr,
|
||||
* @size: DMA transaction size in bytes
|
||||
* @flags: flags to control DMA descriptor preparation
|
||||
*/
|
||||
-static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
|
||||
- const u8 *vaddr, int size, unsigned int flags)
|
||||
+static int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
|
||||
+ const u8 *vaddr, int size, unsigned int flags)
|
||||
{
|
||||
if (nandc->props->supports_bam)
|
||||
- return prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
|
||||
+ return qcom_prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
|
||||
|
||||
- return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
|
||||
+ return qcom_prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
|
||||
}
|
||||
|
||||
/*
|
||||
- * write_data_dma: prepares a DMA descriptor to transfer data from
|
||||
+ * qcom_write_data_dma: prepares a DMA descriptor to transfer data from
|
||||
* 'vaddr' to the controller's internal buffer
|
||||
*
|
||||
* @reg_off: offset within the controller's data buffer
|
||||
@@ -1161,13 +1160,13 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
|
||||
* @size: DMA transaction size in bytes
|
||||
* @flags: flags to control DMA descriptor preparation
|
||||
*/
|
||||
-static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
|
||||
- const u8 *vaddr, int size, unsigned int flags)
|
||||
+static int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
|
||||
+ const u8 *vaddr, int size, unsigned int flags)
|
||||
{
|
||||
if (nandc->props->supports_bam)
|
||||
- return prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
|
||||
+ return qcom_prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
|
||||
|
||||
- return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
|
||||
+ return qcom_prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1178,14 +1177,14 @@ static void config_nand_page_read(struct nand_chip *chip)
|
||||
{
|
||||
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
|
||||
if (!nandc->props->qpic_version2)
|
||||
- write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr,
|
||||
- NAND_ERASED_CW_DETECT_CFG, 1, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set,
|
||||
- NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_clr,
|
||||
+ NAND_ERASED_CW_DETECT_CFG, 1, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->erased_cw_detect_cfg_set,
|
||||
+ NAND_ERASED_CW_DETECT_CFG, 1, NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1204,17 +1203,17 @@ config_nand_cw_read(struct nand_chip *chip, bool use_ecc, int cw)
|
||||
reg = &nandc->regs->read_location_last0;
|
||||
|
||||
if (nandc->props->supports_bam)
|
||||
- write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
if (use_ecc) {
|
||||
- read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
|
||||
- read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
|
||||
- NAND_BAM_NEXT_SGL);
|
||||
+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
|
||||
+ qcom_read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
|
||||
+ NAND_BAM_NEXT_SGL);
|
||||
} else {
|
||||
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1238,11 +1237,11 @@ static void config_nand_page_write(struct nand_chip *chip)
|
||||
{
|
||||
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->addr0, NAND_ADDR0, 2, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0);
|
||||
if (!nandc->props->qpic_version2)
|
||||
- write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1,
|
||||
- NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->ecc_buf_cfg, NAND_EBI2_ECC_BUF_CFG, 1,
|
||||
+ NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1253,17 +1252,18 @@ static void config_nand_cw_write(struct nand_chip *chip)
|
||||
{
|
||||
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->clrflashstatus, NAND_FLASH_STATUS, 1, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->clrreadstatus, NAND_READ_STATUS, 1,
|
||||
+ NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
/* helpers to submit/free our list of dma descriptors */
|
||||
-static int submit_descs(struct qcom_nand_controller *nandc)
|
||||
+static int qcom_submit_descs(struct qcom_nand_controller *nandc)
|
||||
{
|
||||
struct desc_info *desc, *n;
|
||||
dma_cookie_t cookie = 0;
|
||||
@@ -1272,21 +1272,21 @@ static int submit_descs(struct qcom_nand_controller *nandc)
|
||||
|
||||
if (nandc->props->supports_bam) {
|
||||
if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) {
|
||||
- ret = prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
|
||||
+ ret = qcom_prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
|
||||
if (ret)
|
||||
goto err_unmap_free_desc;
|
||||
}
|
||||
|
||||
if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) {
|
||||
- ret = prepare_bam_async_desc(nandc, nandc->tx_chan,
|
||||
- DMA_PREP_INTERRUPT);
|
||||
+ ret = qcom_prepare_bam_async_desc(nandc, nandc->tx_chan,
|
||||
+ DMA_PREP_INTERRUPT);
|
||||
if (ret)
|
||||
goto err_unmap_free_desc;
|
||||
}
|
||||
|
||||
if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
|
||||
- ret = prepare_bam_async_desc(nandc, nandc->cmd_chan,
|
||||
- DMA_PREP_CMD);
|
||||
+ ret = qcom_prepare_bam_async_desc(nandc, nandc->cmd_chan,
|
||||
+ DMA_PREP_CMD);
|
||||
if (ret)
|
||||
goto err_unmap_free_desc;
|
||||
}
|
||||
@@ -1296,7 +1296,7 @@ static int submit_descs(struct qcom_nand_controller *nandc)
|
||||
cookie = dmaengine_submit(desc->dma_desc);
|
||||
|
||||
if (nandc->props->supports_bam) {
|
||||
- bam_txn->last_cmd_desc->callback = qpic_bam_dma_done;
|
||||
+ bam_txn->last_cmd_desc->callback = qcom_qpic_bam_dma_done;
|
||||
bam_txn->last_cmd_desc->callback_param = bam_txn;
|
||||
|
||||
dma_async_issue_pending(nandc->tx_chan);
|
||||
@@ -1314,7 +1314,7 @@ static int submit_descs(struct qcom_nand_controller *nandc)
|
||||
err_unmap_free_desc:
|
||||
/*
|
||||
* Unmap the dma sg_list and free the desc allocated by both
|
||||
- * prepare_bam_async_desc() and prep_adm_dma_desc() functions.
|
||||
+ * qcom_prepare_bam_async_desc() and qcom_prep_adm_dma_desc() functions.
|
||||
*/
|
||||
list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
|
||||
list_del(&desc->node);
|
||||
@@ -1333,10 +1333,10 @@ static int submit_descs(struct qcom_nand_controller *nandc)
|
||||
}
|
||||
|
||||
/* reset the register read buffer for next NAND operation */
|
||||
-static void clear_read_regs(struct qcom_nand_controller *nandc)
|
||||
+static void qcom_clear_read_regs(struct qcom_nand_controller *nandc)
|
||||
{
|
||||
nandc->reg_read_pos = 0;
|
||||
- nandc_dev_to_mem(nandc, false);
|
||||
+ qcom_nandc_dev_to_mem(nandc, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1400,7 +1400,7 @@ static int check_flash_errors(struct qcom_nand_host *host, int cw_cnt)
|
||||
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
|
||||
int i;
|
||||
|
||||
- nandc_dev_to_mem(nandc, true);
|
||||
+ qcom_nandc_dev_to_mem(nandc, true);
|
||||
|
||||
for (i = 0; i < cw_cnt; i++) {
|
||||
u32 flash = le32_to_cpu(nandc->reg_read_buf[i]);
|
||||
@@ -1427,13 +1427,13 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
nand_read_page_op(chip, page, 0, NULL, 0);
|
||||
nandc->buf_count = 0;
|
||||
nandc->buf_start = 0;
|
||||
- clear_read_regs(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
host->use_ecc = false;
|
||||
|
||||
if (nandc->props->qpic_version2)
|
||||
raw_cw = ecc->steps - 1;
|
||||
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
set_address(host, host->cw_size * cw, page);
|
||||
update_rw_regs(host, 1, true, raw_cw);
|
||||
config_nand_page_read(chip);
|
||||
@@ -1466,18 +1466,18 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
|
||||
|
||||
config_nand_cw_read(chip, false, raw_cw);
|
||||
|
||||
- read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
|
||||
+ qcom_read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
|
||||
reg_off += data_size1;
|
||||
|
||||
- read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
|
||||
+ qcom_read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
|
||||
reg_off += oob_size1;
|
||||
|
||||
- read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0);
|
||||
+ qcom_read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0);
|
||||
reg_off += data_size2;
|
||||
|
||||
- read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0);
|
||||
+ qcom_read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure to read raw cw %d\n", cw);
|
||||
return ret;
|
||||
@@ -1575,7 +1575,7 @@ static int parse_read_errors(struct qcom_nand_host *host, u8 *data_buf,
|
||||
u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf;
|
||||
|
||||
buf = (struct read_stats *)nandc->reg_read_buf;
|
||||
- nandc_dev_to_mem(nandc, true);
|
||||
+ qcom_nandc_dev_to_mem(nandc, true);
|
||||
|
||||
for (i = 0; i < ecc->steps; i++, buf++) {
|
||||
u32 flash, buffer, erased_cw;
|
||||
@@ -1704,8 +1704,8 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
|
||||
config_nand_cw_read(chip, true, i);
|
||||
|
||||
if (data_buf)
|
||||
- read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
|
||||
- data_size, 0);
|
||||
+ qcom_read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
|
||||
+ data_size, 0);
|
||||
|
||||
/*
|
||||
* when ecc is enabled, the controller doesn't read the real
|
||||
@@ -1720,8 +1720,8 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
|
||||
for (j = 0; j < host->bbm_size; j++)
|
||||
*oob_buf++ = 0xff;
|
||||
|
||||
- read_data_dma(nandc, FLASH_BUF_ACC + data_size,
|
||||
- oob_buf, oob_size, 0);
|
||||
+ qcom_read_data_dma(nandc, FLASH_BUF_ACC + data_size,
|
||||
+ oob_buf, oob_size, 0);
|
||||
}
|
||||
|
||||
if (data_buf)
|
||||
@@ -1730,7 +1730,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
|
||||
oob_buf += oob_size;
|
||||
}
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure to read page/oob\n");
|
||||
return ret;
|
||||
@@ -1751,7 +1751,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page)
|
||||
int size;
|
||||
int ret;
|
||||
|
||||
- clear_read_regs(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
|
||||
size = host->use_ecc ? host->cw_data : host->cw_size;
|
||||
|
||||
@@ -1763,9 +1763,9 @@ static int copy_last_cw(struct qcom_nand_host *host, int page)
|
||||
|
||||
config_nand_single_cw_page_read(chip, host->use_ecc, ecc->steps - 1);
|
||||
|
||||
- read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
|
||||
+ qcom_read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret)
|
||||
dev_err(nandc->dev, "failed to copy last codeword\n");
|
||||
|
||||
@@ -1851,14 +1851,14 @@ static int qcom_nandc_read_page(struct nand_chip *chip, u8 *buf,
|
||||
nandc->buf_count = 0;
|
||||
nandc->buf_start = 0;
|
||||
host->use_ecc = true;
|
||||
- clear_read_regs(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
set_address(host, 0, page);
|
||||
update_rw_regs(host, ecc->steps, true, 0);
|
||||
|
||||
data_buf = buf;
|
||||
oob_buf = oob_required ? chip->oob_poi : NULL;
|
||||
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
return read_page_ecc(host, data_buf, oob_buf, page);
|
||||
}
|
||||
@@ -1899,8 +1899,8 @@ static int qcom_nandc_read_oob(struct nand_chip *chip, int page)
|
||||
if (host->nr_boot_partitions)
|
||||
qcom_nandc_codeword_fixup(host, page);
|
||||
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
host->use_ecc = true;
|
||||
set_address(host, 0, page);
|
||||
@@ -1927,8 +1927,8 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf,
|
||||
set_address(host, 0, page);
|
||||
nandc->buf_count = 0;
|
||||
nandc->buf_start = 0;
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
data_buf = (u8 *)buf;
|
||||
oob_buf = chip->oob_poi;
|
||||
@@ -1949,8 +1949,8 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf,
|
||||
oob_size = ecc->bytes;
|
||||
}
|
||||
|
||||
- write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
|
||||
- i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
|
||||
+ qcom_write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
|
||||
+ i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
|
||||
|
||||
/*
|
||||
* when ECC is enabled, we don't really need to write anything
|
||||
@@ -1962,8 +1962,8 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf,
|
||||
if (qcom_nandc_is_last_cw(ecc, i)) {
|
||||
oob_buf += host->bbm_size;
|
||||
|
||||
- write_data_dma(nandc, FLASH_BUF_ACC + data_size,
|
||||
- oob_buf, oob_size, 0);
|
||||
+ qcom_write_data_dma(nandc, FLASH_BUF_ACC + data_size,
|
||||
+ oob_buf, oob_size, 0);
|
||||
}
|
||||
|
||||
config_nand_cw_write(chip);
|
||||
@@ -1972,7 +1972,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const u8 *buf,
|
||||
oob_buf += oob_size;
|
||||
}
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure to write page\n");
|
||||
return ret;
|
||||
@@ -1997,8 +1997,8 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip,
|
||||
qcom_nandc_codeword_fixup(host, page);
|
||||
|
||||
nand_prog_page_begin_op(chip, page, 0, NULL, 0);
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
data_buf = (u8 *)buf;
|
||||
oob_buf = chip->oob_poi;
|
||||
@@ -2024,28 +2024,28 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip,
|
||||
oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
|
||||
}
|
||||
|
||||
- write_data_dma(nandc, reg_off, data_buf, data_size1,
|
||||
- NAND_BAM_NO_EOT);
|
||||
+ qcom_write_data_dma(nandc, reg_off, data_buf, data_size1,
|
||||
+ NAND_BAM_NO_EOT);
|
||||
reg_off += data_size1;
|
||||
data_buf += data_size1;
|
||||
|
||||
- write_data_dma(nandc, reg_off, oob_buf, oob_size1,
|
||||
- NAND_BAM_NO_EOT);
|
||||
+ qcom_write_data_dma(nandc, reg_off, oob_buf, oob_size1,
|
||||
+ NAND_BAM_NO_EOT);
|
||||
reg_off += oob_size1;
|
||||
oob_buf += oob_size1;
|
||||
|
||||
- write_data_dma(nandc, reg_off, data_buf, data_size2,
|
||||
- NAND_BAM_NO_EOT);
|
||||
+ qcom_write_data_dma(nandc, reg_off, data_buf, data_size2,
|
||||
+ NAND_BAM_NO_EOT);
|
||||
reg_off += data_size2;
|
||||
data_buf += data_size2;
|
||||
|
||||
- write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
|
||||
+ qcom_write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
|
||||
oob_buf += oob_size2;
|
||||
|
||||
config_nand_cw_write(chip);
|
||||
}
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure to write raw page\n");
|
||||
return ret;
|
||||
@@ -2075,7 +2075,7 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page)
|
||||
qcom_nandc_codeword_fixup(host, page);
|
||||
|
||||
host->use_ecc = true;
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
/* calculate the data and oob size for the last codeword/step */
|
||||
data_size = ecc->size - ((ecc->steps - 1) << 2);
|
||||
@@ -2090,11 +2090,11 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page)
|
||||
update_rw_regs(host, 1, false, 0);
|
||||
|
||||
config_nand_page_write(chip);
|
||||
- write_data_dma(nandc, FLASH_BUF_ACC,
|
||||
- nandc->data_buffer, data_size + oob_size, 0);
|
||||
+ qcom_write_data_dma(nandc, FLASH_BUF_ACC,
|
||||
+ nandc->data_buffer, data_size + oob_size, 0);
|
||||
config_nand_cw_write(chip);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure to write oob\n");
|
||||
return ret;
|
||||
@@ -2121,7 +2121,7 @@ static int qcom_nandc_block_bad(struct nand_chip *chip, loff_t ofs)
|
||||
*/
|
||||
host->use_ecc = false;
|
||||
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
ret = copy_last_cw(host, page);
|
||||
if (ret)
|
||||
goto err;
|
||||
@@ -2148,8 +2148,8 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs)
|
||||
struct nand_ecc_ctrl *ecc = &chip->ecc;
|
||||
int page, ret;
|
||||
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
/*
|
||||
* to mark the BBM as bad, we flash the entire last codeword with 0s.
|
||||
@@ -2166,11 +2166,11 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs)
|
||||
update_rw_regs(host, 1, false, ecc->steps - 1);
|
||||
|
||||
config_nand_page_write(chip);
|
||||
- write_data_dma(nandc, FLASH_BUF_ACC,
|
||||
- nandc->data_buffer, host->cw_size, 0);
|
||||
+ qcom_write_data_dma(nandc, FLASH_BUF_ACC,
|
||||
+ nandc->data_buffer, host->cw_size, 0);
|
||||
config_nand_cw_write(chip);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure to update BBM\n");
|
||||
return ret;
|
||||
@@ -2410,14 +2410,14 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
|
||||
mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
|
||||
/* Free the initially allocated BAM transaction for reading the ONFI params */
|
||||
if (nandc->props->supports_bam)
|
||||
- free_bam_transaction(nandc);
|
||||
+ qcom_free_bam_transaction(nandc);
|
||||
|
||||
nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
|
||||
cwperpage);
|
||||
|
||||
/* Now allocate the BAM transaction based on updated max_cwperpage */
|
||||
if (nandc->props->supports_bam) {
|
||||
- nandc->bam_txn = alloc_bam_transaction(nandc);
|
||||
+ nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
|
||||
if (!nandc->bam_txn) {
|
||||
dev_err(nandc->dev,
|
||||
"failed to allocate bam transaction\n");
|
||||
@@ -2617,7 +2617,7 @@ static int qcom_wait_rdy_poll(struct nand_chip *chip, unsigned int time_ms)
|
||||
unsigned long start = jiffies + msecs_to_jiffies(time_ms);
|
||||
u32 flash;
|
||||
|
||||
- nandc_dev_to_mem(nandc, true);
|
||||
+ qcom_nandc_dev_to_mem(nandc, true);
|
||||
|
||||
do {
|
||||
flash = le32_to_cpu(nandc->reg_read_buf[0]);
|
||||
@@ -2657,23 +2657,23 @@ static int qcom_read_status_exec(struct nand_chip *chip,
|
||||
nandc->buf_start = 0;
|
||||
host->use_ecc = false;
|
||||
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
nandc->regs->cmd = q_op.cmd_reg;
|
||||
nandc->regs->exec = cpu_to_le32(1);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure in submitting status descriptor\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
- nandc_dev_to_mem(nandc, true);
|
||||
+ qcom_nandc_dev_to_mem(nandc, true);
|
||||
|
||||
for (i = 0; i < num_cw; i++) {
|
||||
flash_status = le32_to_cpu(nandc->reg_read_buf[i]);
|
||||
@@ -2714,8 +2714,8 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo
|
||||
nandc->buf_start = 0;
|
||||
host->use_ecc = false;
|
||||
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
nandc->regs->cmd = q_op.cmd_reg;
|
||||
nandc->regs->addr0 = q_op.addr1_reg;
|
||||
@@ -2723,12 +2723,12 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo
|
||||
nandc->regs->chip_sel = cpu_to_le32(nandc->props->supports_bam ? 0 : DM_EN);
|
||||
nandc->regs->exec = cpu_to_le32(1);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
|
||||
- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure in submitting read id descriptor\n");
|
||||
goto err_out;
|
||||
@@ -2738,7 +2738,7 @@ static int qcom_read_id_type_exec(struct nand_chip *chip, const struct nand_subo
|
||||
op_id = q_op.data_instr_idx;
|
||||
len = nand_subop_get_data_len(subop, op_id);
|
||||
|
||||
- nandc_dev_to_mem(nandc, true);
|
||||
+ qcom_nandc_dev_to_mem(nandc, true);
|
||||
memcpy(instr->ctx.data.buf.in, nandc->reg_read_buf, len);
|
||||
|
||||
err_out:
|
||||
@@ -2774,20 +2774,20 @@ static int qcom_misc_cmd_type_exec(struct nand_chip *chip, const struct nand_sub
|
||||
nandc->buf_start = 0;
|
||||
host->use_ecc = false;
|
||||
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
nandc->regs->cmd = q_op.cmd_reg;
|
||||
nandc->regs->exec = cpu_to_le32(1);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cmd, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
|
||||
if (q_op.cmd_reg == cpu_to_le32(OP_BLOCK_ERASE))
|
||||
- write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cfg0, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure in submitting misc descriptor\n");
|
||||
goto err_out;
|
||||
@@ -2820,8 +2820,8 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_
|
||||
nandc->buf_count = 0;
|
||||
nandc->buf_start = 0;
|
||||
host->use_ecc = false;
|
||||
- clear_read_regs(nandc);
|
||||
- clear_bam_transaction(nandc);
|
||||
+ qcom_clear_read_regs(nandc);
|
||||
+ qcom_clear_bam_transaction(nandc);
|
||||
|
||||
nandc->regs->cmd = q_op.cmd_reg;
|
||||
nandc->regs->addr0 = 0;
|
||||
@@ -2864,8 +2864,8 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_
|
||||
nandc_set_read_loc(chip, 0, 0, 0, len, 1);
|
||||
|
||||
if (!nandc->props->qpic_version2) {
|
||||
- write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->vld, NAND_DEV_CMD_VLD, 1, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->cmd1, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
nandc->buf_count = len;
|
||||
@@ -2873,17 +2873,17 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_
|
||||
|
||||
config_nand_single_cw_page_read(chip, false, 0);
|
||||
|
||||
- read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
|
||||
- nandc->buf_count, 0);
|
||||
+ qcom_read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
|
||||
+ nandc->buf_count, 0);
|
||||
|
||||
/* restore CMD1 and VLD regs */
|
||||
if (!nandc->props->qpic_version2) {
|
||||
- write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0);
|
||||
- write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1,
|
||||
- NAND_BAM_NEXT_SGL);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->orig_cmd1, NAND_DEV_CMD1_RESTORE, 1, 0);
|
||||
+ qcom_write_reg_dma(nandc, &nandc->regs->orig_vld, NAND_DEV_CMD_VLD_RESTORE, 1,
|
||||
+ NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
- ret = submit_descs(nandc);
|
||||
+ ret = qcom_submit_descs(nandc);
|
||||
if (ret) {
|
||||
dev_err(nandc->dev, "failure in submitting param page descriptor\n");
|
||||
goto err_out;
|
||||
@@ -3067,7 +3067,7 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
|
||||
* maximum codeword size
|
||||
*/
|
||||
nandc->max_cwperpage = 1;
|
||||
- nandc->bam_txn = alloc_bam_transaction(nandc);
|
||||
+ nandc->bam_txn = qcom_alloc_bam_transaction(nandc);
|
||||
if (!nandc->bam_txn) {
|
||||
dev_err(nandc->dev,
|
||||
"failed to allocate bam transaction\n");
|
||||
--
|
||||
2.47.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,204 @@
|
||||
From 0c08080fd71cd5dd59643104b39d3c89d793ab3c Mon Sep 17 00:00:00 2001
|
||||
From: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Date: Wed, 20 Nov 2024 14:45:03 +0530
|
||||
Subject: [PATCH 4/4] mtd: rawnand: qcom: use FIELD_PREP and GENMASK
|
||||
|
||||
Use the bitfield macro FIELD_PREP, and GENMASK to
|
||||
do the shift and mask in one go. This makes the code
|
||||
more readable.
|
||||
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
---
|
||||
drivers/mtd/nand/raw/qcom_nandc.c | 97 ++++++++++++++--------------
|
||||
include/linux/mtd/nand-qpic-common.h | 31 +++++----
|
||||
2 files changed, 67 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
|
||||
index dcb62fd19dd7..d2d2aeee42a7 100644
|
||||
--- a/drivers/mtd/nand/raw/qcom_nandc.c
|
||||
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
|
||||
@@ -281,7 +281,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i
|
||||
(num_cw - 1) << CW_PER_PAGE);
|
||||
|
||||
cfg1 = cpu_to_le32(host->cfg1_raw);
|
||||
- ecc_bch_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE);
|
||||
+ ecc_bch_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE);
|
||||
}
|
||||
|
||||
nandc->regs->cmd = cmd;
|
||||
@@ -1494,42 +1494,41 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
|
||||
host->cw_size = host->cw_data + ecc->bytes;
|
||||
bad_block_byte = mtd->writesize - host->cw_size * (cwperpage - 1) + 1;
|
||||
|
||||
- host->cfg0 = (cwperpage - 1) << CW_PER_PAGE
|
||||
- | host->cw_data << UD_SIZE_BYTES
|
||||
- | 0 << DISABLE_STATUS_AFTER_WRITE
|
||||
- | 5 << NUM_ADDR_CYCLES
|
||||
- | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_RS
|
||||
- | 0 << STATUS_BFR_READ
|
||||
- | 1 << SET_RD_MODE_AFTER_STATUS
|
||||
- | host->spare_bytes << SPARE_SIZE_BYTES;
|
||||
-
|
||||
- host->cfg1 = 7 << NAND_RECOVERY_CYCLES
|
||||
- | 0 << CS_ACTIVE_BSY
|
||||
- | bad_block_byte << BAD_BLOCK_BYTE_NUM
|
||||
- | 0 << BAD_BLOCK_IN_SPARE_AREA
|
||||
- | 2 << WR_RD_BSY_GAP
|
||||
- | wide_bus << WIDE_FLASH
|
||||
- | host->bch_enabled << ENABLE_BCH_ECC;
|
||||
-
|
||||
- host->cfg0_raw = (cwperpage - 1) << CW_PER_PAGE
|
||||
- | host->cw_size << UD_SIZE_BYTES
|
||||
- | 5 << NUM_ADDR_CYCLES
|
||||
- | 0 << SPARE_SIZE_BYTES;
|
||||
-
|
||||
- host->cfg1_raw = 7 << NAND_RECOVERY_CYCLES
|
||||
- | 0 << CS_ACTIVE_BSY
|
||||
- | 17 << BAD_BLOCK_BYTE_NUM
|
||||
- | 1 << BAD_BLOCK_IN_SPARE_AREA
|
||||
- | 2 << WR_RD_BSY_GAP
|
||||
- | wide_bus << WIDE_FLASH
|
||||
- | 1 << DEV0_CFG1_ECC_DISABLE;
|
||||
-
|
||||
- host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE
|
||||
- | 0 << ECC_SW_RESET
|
||||
- | host->cw_data << ECC_NUM_DATA_BYTES
|
||||
- | 1 << ECC_FORCE_CLK_OPEN
|
||||
- | ecc_mode << ECC_MODE
|
||||
- | host->ecc_bytes_hw << ECC_PARITY_SIZE_BYTES_BCH;
|
||||
+ host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
|
||||
+ FIELD_PREP(UD_SIZE_BYTES_MASK, host->cw_data) |
|
||||
+ FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 0) |
|
||||
+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
|
||||
+ FIELD_PREP(ECC_PARITY_SIZE_BYTES_RS, host->ecc_bytes_hw) |
|
||||
+ FIELD_PREP(STATUS_BFR_READ, 0) |
|
||||
+ FIELD_PREP(SET_RD_MODE_AFTER_STATUS, 1) |
|
||||
+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, host->spare_bytes);
|
||||
+
|
||||
+ host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
|
||||
+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, bad_block_byte) |
|
||||
+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 0) |
|
||||
+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
|
||||
+ FIELD_PREP(WIDE_FLASH, wide_bus) |
|
||||
+ FIELD_PREP(ENABLE_BCH_ECC, host->bch_enabled);
|
||||
+
|
||||
+ host->cfg0_raw = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
|
||||
+ FIELD_PREP(UD_SIZE_BYTES_MASK, host->cw_size) |
|
||||
+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
|
||||
+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
|
||||
+
|
||||
+ host->cfg1_raw = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
|
||||
+ FIELD_PREP(CS_ACTIVE_BSY, 0) |
|
||||
+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
|
||||
+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
|
||||
+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
|
||||
+ FIELD_PREP(WIDE_FLASH, wide_bus) |
|
||||
+ FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
|
||||
+
|
||||
+ host->ecc_bch_cfg = FIELD_PREP(ECC_CFG_ECC_DISABLE, !host->bch_enabled) |
|
||||
+ FIELD_PREP(ECC_SW_RESET, 0) |
|
||||
+ FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, host->cw_data) |
|
||||
+ FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) |
|
||||
+ FIELD_PREP(ECC_MODE_MASK, ecc_mode) |
|
||||
+ FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, host->ecc_bytes_hw);
|
||||
|
||||
if (!nandc->props->qpic_version2)
|
||||
host->ecc_buf_cfg = 0x203 << NUM_STEPS;
|
||||
@@ -1882,21 +1881,21 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_
|
||||
nandc->regs->addr0 = 0;
|
||||
nandc->regs->addr1 = 0;
|
||||
|
||||
- nandc->regs->cfg0 = cpu_to_le32(0 << CW_PER_PAGE |
|
||||
- 512 << UD_SIZE_BYTES |
|
||||
- 5 << NUM_ADDR_CYCLES |
|
||||
- 0 << SPARE_SIZE_BYTES);
|
||||
+ host->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, 0) |
|
||||
+ FIELD_PREP(UD_SIZE_BYTES_MASK, 512) |
|
||||
+ FIELD_PREP(NUM_ADDR_CYCLES_MASK, 5) |
|
||||
+ FIELD_PREP(SPARE_SIZE_BYTES_MASK, 0);
|
||||
|
||||
- nandc->regs->cfg1 = cpu_to_le32(7 << NAND_RECOVERY_CYCLES |
|
||||
- 0 << CS_ACTIVE_BSY |
|
||||
- 17 << BAD_BLOCK_BYTE_NUM |
|
||||
- 1 << BAD_BLOCK_IN_SPARE_AREA |
|
||||
- 2 << WR_RD_BSY_GAP |
|
||||
- 0 << WIDE_FLASH |
|
||||
- 1 << DEV0_CFG1_ECC_DISABLE);
|
||||
+ host->cfg1 = FIELD_PREP(NAND_RECOVERY_CYCLES_MASK, 7) |
|
||||
+ FIELD_PREP(BAD_BLOCK_BYTE_NUM_MASK, 17) |
|
||||
+ FIELD_PREP(CS_ACTIVE_BSY, 0) |
|
||||
+ FIELD_PREP(BAD_BLOCK_IN_SPARE_AREA, 1) |
|
||||
+ FIELD_PREP(WR_RD_BSY_GAP_MASK, 2) |
|
||||
+ FIELD_PREP(WIDE_FLASH, 0) |
|
||||
+ FIELD_PREP(DEV0_CFG1_ECC_DISABLE, 1);
|
||||
|
||||
if (!nandc->props->qpic_version2)
|
||||
- nandc->regs->ecc_buf_cfg = cpu_to_le32(1 << ECC_CFG_ECC_DISABLE);
|
||||
+ nandc->regs->ecc_buf_cfg = cpu_to_le32(ECC_CFG_ECC_DISABLE);
|
||||
|
||||
/* configure CMD1 and VLD for ONFI param probing in QPIC v1 */
|
||||
if (!nandc->props->qpic_version2) {
|
||||
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h
|
||||
index 425994429387..e79c79775eb8 100644
|
||||
--- a/include/linux/mtd/nand-qpic-common.h
|
||||
+++ b/include/linux/mtd/nand-qpic-common.h
|
||||
@@ -70,35 +70,42 @@
|
||||
#define BS_CORRECTABLE_ERR_MSK 0x1f
|
||||
|
||||
/* NAND_DEVn_CFG0 bits */
|
||||
-#define DISABLE_STATUS_AFTER_WRITE 4
|
||||
+#define DISABLE_STATUS_AFTER_WRITE BIT(4)
|
||||
#define CW_PER_PAGE 6
|
||||
+#define CW_PER_PAGE_MASK GENMASK(8, 6)
|
||||
#define UD_SIZE_BYTES 9
|
||||
#define UD_SIZE_BYTES_MASK GENMASK(18, 9)
|
||||
-#define ECC_PARITY_SIZE_BYTES_RS 19
|
||||
+#define ECC_PARITY_SIZE_BYTES_RS GENMASK(22, 19)
|
||||
#define SPARE_SIZE_BYTES 23
|
||||
#define SPARE_SIZE_BYTES_MASK GENMASK(26, 23)
|
||||
#define NUM_ADDR_CYCLES 27
|
||||
-#define STATUS_BFR_READ 30
|
||||
-#define SET_RD_MODE_AFTER_STATUS 31
|
||||
+#define NUM_ADDR_CYCLES_MASK GENMASK(29, 27)
|
||||
+#define STATUS_BFR_READ BIT(30)
|
||||
+#define SET_RD_MODE_AFTER_STATUS BIT(31)
|
||||
|
||||
/* NAND_DEVn_CFG0 bits */
|
||||
-#define DEV0_CFG1_ECC_DISABLE 0
|
||||
-#define WIDE_FLASH 1
|
||||
+#define DEV0_CFG1_ECC_DISABLE BIT(0)
|
||||
+#define WIDE_FLASH BIT(1)
|
||||
#define NAND_RECOVERY_CYCLES 2
|
||||
-#define CS_ACTIVE_BSY 5
|
||||
+#define NAND_RECOVERY_CYCLES_MASK GENMASK(4, 2)
|
||||
+#define CS_ACTIVE_BSY BIT(5)
|
||||
#define BAD_BLOCK_BYTE_NUM 6
|
||||
-#define BAD_BLOCK_IN_SPARE_AREA 16
|
||||
+#define BAD_BLOCK_BYTE_NUM_MASK GENMASK(15, 6)
|
||||
+#define BAD_BLOCK_IN_SPARE_AREA BIT(16)
|
||||
#define WR_RD_BSY_GAP 17
|
||||
-#define ENABLE_BCH_ECC 27
|
||||
+#define WR_RD_BSY_GAP_MASK GENMASK(22, 17)
|
||||
+#define ENABLE_BCH_ECC BIT(27)
|
||||
|
||||
/* NAND_DEV0_ECC_CFG bits */
|
||||
-#define ECC_CFG_ECC_DISABLE 0
|
||||
-#define ECC_SW_RESET 1
|
||||
+#define ECC_CFG_ECC_DISABLE BIT(0)
|
||||
+#define ECC_SW_RESET BIT(1)
|
||||
#define ECC_MODE 4
|
||||
+#define ECC_MODE_MASK GENMASK(5, 4)
|
||||
#define ECC_PARITY_SIZE_BYTES_BCH 8
|
||||
+#define ECC_PARITY_SIZE_BYTES_BCH_MASK GENMASK(12, 8)
|
||||
#define ECC_NUM_DATA_BYTES 16
|
||||
#define ECC_NUM_DATA_BYTES_MASK GENMASK(25, 16)
|
||||
-#define ECC_FORCE_CLK_OPEN 30
|
||||
+#define ECC_FORCE_CLK_OPEN BIT(30)
|
||||
|
||||
/* NAND_DEV_CMD1 bits */
|
||||
#define READ_ADDR 0
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,84 @@
|
||||
From b9371866799d67a80be0ea9e01bd41987db22f26 Mon Sep 17 00:00:00 2001
|
||||
From: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Date: Mon, 6 Jan 2025 18:45:58 +0530
|
||||
Subject: [PATCH] mtd: rawnand: qcom: Fix build issue on x86 architecture
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fix a buffer overflow issue in qcom_clear_bam_transaction by using
|
||||
struct_group to group related fields and avoid FORTIFY_SOURCE warnings.
|
||||
|
||||
On x86 architecture, the following error occurs due to warnings being
|
||||
treated as errors:
|
||||
|
||||
In function ‘fortify_memset_chk’,
|
||||
inlined from ‘qcom_clear_bam_transaction’ at
|
||||
drivers/mtd/nand/qpic_common.c:88:2:
|
||||
./include/linux/fortify-string.h:480:25: error: call to ‘__write_overflow_field’
|
||||
declared with attribute warning: detected write beyond size of field
|
||||
(1st parameter); maybe use struct_group()? [-Werror=attribute-warning]
|
||||
480 | __write_overflow_field(p_size_field, size);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
LD [M] drivers/mtd/nand/nandcore.o
|
||||
CC [M] drivers/w1/masters/mxc_w1.o
|
||||
cc1: all warnings being treated as errors
|
||||
|
||||
This patch addresses the issue by grouping the related fields in
|
||||
struct bam_transaction using struct_group and updating the memset call
|
||||
accordingly.
|
||||
|
||||
Fixes: 8c52932da5e6 ("mtd: rawnand: qcom: cleanup qcom_nandc driver")
|
||||
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
---
|
||||
drivers/mtd/nand/qpic_common.c | 2 +-
|
||||
include/linux/mtd/nand-qpic-common.h | 19 +++++++++++--------
|
||||
2 files changed, 12 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/qpic_common.c b/drivers/mtd/nand/qpic_common.c
|
||||
index 8abbb960a7ce..e0ed25b5afea 100644
|
||||
--- a/drivers/mtd/nand/qpic_common.c
|
||||
+++ b/drivers/mtd/nand/qpic_common.c
|
||||
@@ -85,7 +85,7 @@ void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc)
|
||||
if (!nandc->props->supports_bam)
|
||||
return;
|
||||
|
||||
- memset(&bam_txn->bam_ce_pos, 0, sizeof(u32) * 8);
|
||||
+ memset(&bam_txn->bam_positions, 0, sizeof(bam_txn->bam_positions));
|
||||
bam_txn->last_data_desc = NULL;
|
||||
|
||||
sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
|
||||
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h
|
||||
index e79c79775eb8..4d9b736ff8b7 100644
|
||||
--- a/include/linux/mtd/nand-qpic-common.h
|
||||
+++ b/include/linux/mtd/nand-qpic-common.h
|
||||
@@ -254,14 +254,17 @@ struct bam_transaction {
|
||||
struct dma_async_tx_descriptor *last_data_desc;
|
||||
struct dma_async_tx_descriptor *last_cmd_desc;
|
||||
struct completion txn_done;
|
||||
- u32 bam_ce_pos;
|
||||
- u32 bam_ce_start;
|
||||
- u32 cmd_sgl_pos;
|
||||
- u32 cmd_sgl_start;
|
||||
- u32 tx_sgl_pos;
|
||||
- u32 tx_sgl_start;
|
||||
- u32 rx_sgl_pos;
|
||||
- u32 rx_sgl_start;
|
||||
+ struct_group(bam_positions,
|
||||
+ u32 bam_ce_pos;
|
||||
+ u32 bam_ce_start;
|
||||
+ u32 cmd_sgl_pos;
|
||||
+ u32 cmd_sgl_start;
|
||||
+ u32 tx_sgl_pos;
|
||||
+ u32 tx_sgl_start;
|
||||
+ u32 rx_sgl_pos;
|
||||
+ u32 rx_sgl_start;
|
||||
+
|
||||
+ );
|
||||
};
|
||||
|
||||
/*
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,510 @@
|
||||
From f81715a4c87c3b75ca2640bb61b6c66506061a64 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Fri, 3 Jan 2025 15:31:35 +0800
|
||||
Subject: [PATCH] clk: qcom: Add CMN PLL clock controller driver for IPQ SoC
|
||||
|
||||
The CMN PLL clock controller supplies clocks to the hardware
|
||||
blocks that together make up the Ethernet function on Qualcomm
|
||||
IPQ SoCs and to GCC. The driver is initially supported for
|
||||
IPQ9574 SoC.
|
||||
|
||||
The CMN PLL clock controller expects a reference input clock
|
||||
from the on-board Wi-Fi block acting as clock source. The input
|
||||
reference clock needs to be configured to one of the supported
|
||||
clock rates.
|
||||
|
||||
The controller supplies a number of fixed-rate output clocks.
|
||||
For the IPQ9574, there is one output clock of 353 MHZ to PPE
|
||||
(Packet Process Engine) hardware block, three 50 MHZ output
|
||||
clocks and an additional 25 MHZ output clock supplied to the
|
||||
connected Ethernet devices. The PLL also supplies a 24 MHZ
|
||||
clock as XO and a 32 KHZ sleep clock to GCC, and one 31.25
|
||||
MHZ clock to PCS.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||
Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-2-c89fb4d4849d@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
drivers/clk/qcom/Kconfig | 9 +
|
||||
drivers/clk/qcom/Makefile | 1 +
|
||||
drivers/clk/qcom/ipq-cmn-pll.c | 435 +++++++++++++++++++++++++++++++++
|
||||
3 files changed, 445 insertions(+)
|
||||
create mode 100644 drivers/clk/qcom/ipq-cmn-pll.c
|
||||
|
||||
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
|
||||
index 42c257e4c433..2daff198aeb3 100644
|
||||
--- a/drivers/clk/qcom/Kconfig
|
||||
+++ b/drivers/clk/qcom/Kconfig
|
||||
@@ -199,6 +199,15 @@ config IPQ_APSS_6018
|
||||
Say Y if you want to support CPU frequency scaling on
|
||||
ipq based devices.
|
||||
|
||||
+config IPQ_CMN_PLL
|
||||
+ tristate "IPQ CMN PLL Clock Controller"
|
||||
+ help
|
||||
+ Support for CMN PLL clock controller on IPQ platform. The
|
||||
+ CMN PLL consumes the AHB/SYS clocks from GCC and supplies
|
||||
+ the output clocks to the networking hardware and GCC blocks.
|
||||
+ Say Y or M if you want to support CMN PLL clock on the IPQ
|
||||
+ based devices.
|
||||
+
|
||||
config IPQ_GCC_4019
|
||||
tristate "IPQ4019 Global Clock Controller"
|
||||
help
|
||||
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
|
||||
index 1b749da9c13a..6665049cb8c8 100644
|
||||
--- a/drivers/clk/qcom/Makefile
|
||||
+++ b/drivers/clk/qcom/Makefile
|
||||
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o
|
||||
obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o
|
||||
obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
|
||||
obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
|
||||
+obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o
|
||||
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
||||
obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o
|
||||
obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o
|
||||
diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c
|
||||
new file mode 100644
|
||||
index 000000000000..432d4c4b7aa6
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/qcom/ipq-cmn-pll.c
|
||||
@@ -0,0 +1,435 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * CMN PLL block expects the reference clock from on-board Wi-Fi block,
|
||||
+ * and supplies fixed rate clocks as output to the networking hardware
|
||||
+ * blocks and to GCC. The networking related blocks include PPE (packet
|
||||
+ * process engine), the externally connected PHY or switch devices, and
|
||||
+ * the PCS.
|
||||
+ *
|
||||
+ * On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock
|
||||
+ * with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch),
|
||||
+ * and one clock with 353 MHZ to PPE. The other fixed rate output clocks
|
||||
+ * are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS
|
||||
+ * with 31.25 MHZ.
|
||||
+ *
|
||||
+ * +---------+
|
||||
+ * | GCC |
|
||||
+ * +--+---+--+
|
||||
+ * AHB CLK| |SYS CLK
|
||||
+ * V V
|
||||
+ * +-------+---+------+
|
||||
+ * | +-------------> eth0-50mhz
|
||||
+ * REF CLK | IPQ9574 |
|
||||
+ * -------->+ +-------------> eth1-50mhz
|
||||
+ * | CMN PLL block |
|
||||
+ * | +-------------> eth2-50mhz
|
||||
+ * | |
|
||||
+ * +----+----+----+---+-------------> eth-25mhz
|
||||
+ * | | |
|
||||
+ * V V V
|
||||
+ * GCC PCS NSS/PPE
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_clock.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
|
||||
+
|
||||
+#define CMN_PLL_REFCLK_SRC_SELECTION 0x28
|
||||
+#define CMN_PLL_REFCLK_SRC_DIV GENMASK(9, 8)
|
||||
+
|
||||
+#define CMN_PLL_LOCKED 0x64
|
||||
+#define CMN_PLL_CLKS_LOCKED BIT(8)
|
||||
+
|
||||
+#define CMN_PLL_POWER_ON_AND_RESET 0x780
|
||||
+#define CMN_ANA_EN_SW_RSTN BIT(6)
|
||||
+
|
||||
+#define CMN_PLL_REFCLK_CONFIG 0x784
|
||||
+#define CMN_PLL_REFCLK_EXTERNAL BIT(9)
|
||||
+#define CMN_PLL_REFCLK_DIV GENMASK(8, 4)
|
||||
+#define CMN_PLL_REFCLK_INDEX GENMASK(3, 0)
|
||||
+
|
||||
+#define CMN_PLL_CTRL 0x78c
|
||||
+#define CMN_PLL_CTRL_LOCK_DETECT_EN BIT(15)
|
||||
+
|
||||
+#define CMN_PLL_DIVIDER_CTRL 0x794
|
||||
+#define CMN_PLL_DIVIDER_CTRL_FACTOR GENMASK(9, 0)
|
||||
+
|
||||
+/**
|
||||
+ * struct cmn_pll_fixed_output_clk - CMN PLL output clocks information
|
||||
+ * @id: Clock specifier to be supplied
|
||||
+ * @name: Clock name to be registered
|
||||
+ * @rate: Clock rate
|
||||
+ */
|
||||
+struct cmn_pll_fixed_output_clk {
|
||||
+ unsigned int id;
|
||||
+ const char *name;
|
||||
+ unsigned long rate;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct clk_cmn_pll - CMN PLL hardware specific data
|
||||
+ * @regmap: hardware regmap.
|
||||
+ * @hw: handle between common and hardware-specific interfaces
|
||||
+ */
|
||||
+struct clk_cmn_pll {
|
||||
+ struct regmap *regmap;
|
||||
+ struct clk_hw hw;
|
||||
+};
|
||||
+
|
||||
+#define CLK_PLL_OUTPUT(_id, _name, _rate) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .rate = _rate, \
|
||||
+}
|
||||
+
|
||||
+#define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw)
|
||||
+
|
||||
+static const struct regmap_config ipq_cmn_pll_regmap_config = {
|
||||
+ .reg_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+ .val_bits = 32,
|
||||
+ .max_register = 0x7fc,
|
||||
+ .fast_io = true,
|
||||
+};
|
||||
+
|
||||
+static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = {
|
||||
+ CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
|
||||
+ CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
|
||||
+ CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL),
|
||||
+ CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL),
|
||||
+ CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL),
|
||||
+ CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL),
|
||||
+ CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL),
|
||||
+ CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL),
|
||||
+ CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * CMN PLL has the single parent clock, which supports the several
|
||||
+ * possible parent clock rates, each parent clock rate is reflected
|
||||
+ * by the specific reference index value in the hardware.
|
||||
+ */
|
||||
+static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate)
|
||||
+{
|
||||
+ int index = -EINVAL;
|
||||
+
|
||||
+ switch (parent_rate) {
|
||||
+ case 25000000:
|
||||
+ index = 3;
|
||||
+ break;
|
||||
+ case 31250000:
|
||||
+ index = 4;
|
||||
+ break;
|
||||
+ case 40000000:
|
||||
+ index = 6;
|
||||
+ break;
|
||||
+ case 48000000:
|
||||
+ case 96000000:
|
||||
+ /*
|
||||
+ * Parent clock rate 48 MHZ and 96 MHZ take the same value
|
||||
+ * of reference clock index. 96 MHZ needs the source clock
|
||||
+ * divider to be programmed as 2.
|
||||
+ */
|
||||
+ index = 7;
|
||||
+ break;
|
||||
+ case 50000000:
|
||||
+ index = 8;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return index;
|
||||
+}
|
||||
+
|
||||
+static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
|
||||
+ u32 val, factor;
|
||||
+
|
||||
+ /*
|
||||
+ * The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted
|
||||
+ * by HW according to the parent clock rate.
|
||||
+ */
|
||||
+ regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val);
|
||||
+ factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val);
|
||||
+
|
||||
+ return parent_rate * 2 * factor;
|
||||
+}
|
||||
+
|
||||
+static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
|
||||
+ struct clk_rate_request *req)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Validate the rate of the single parent clock. */
|
||||
+ ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate);
|
||||
+
|
||||
+ return ret < 0 ? ret : 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function is used to initialize the CMN PLL to enable the fixed
|
||||
+ * rate output clocks. It is expected to be configured once.
|
||||
+ */
|
||||
+static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
|
||||
+ int ret, index;
|
||||
+ u32 val;
|
||||
+
|
||||
+ /*
|
||||
+ * Configure the reference input clock selection as per the given
|
||||
+ * parent clock. The output clock rates are always of fixed value.
|
||||
+ */
|
||||
+ index = ipq_cmn_pll_find_freq_index(parent_rate);
|
||||
+ if (index < 0)
|
||||
+ return index;
|
||||
+
|
||||
+ ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
|
||||
+ CMN_PLL_REFCLK_INDEX,
|
||||
+ FIELD_PREP(CMN_PLL_REFCLK_INDEX, index));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * Update the source clock rate selection and source clock
|
||||
+ * divider as 2 when the parent clock rate is 96 MHZ.
|
||||
+ */
|
||||
+ if (parent_rate == 96000000) {
|
||||
+ ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
|
||||
+ CMN_PLL_REFCLK_DIV,
|
||||
+ FIELD_PREP(CMN_PLL_REFCLK_DIV, 2));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION,
|
||||
+ CMN_PLL_REFCLK_SRC_DIV,
|
||||
+ FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Enable PLL locked detect. */
|
||||
+ ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL,
|
||||
+ CMN_PLL_CTRL_LOCK_DETECT_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * Reset the CMN PLL block to ensure the updated configurations
|
||||
+ * take effect.
|
||||
+ */
|
||||
+ ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
|
||||
+ CMN_ANA_EN_SW_RSTN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ usleep_range(1000, 1200);
|
||||
+ ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
|
||||
+ CMN_ANA_EN_SW_RSTN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Stability check of CMN PLL output clocks. */
|
||||
+ return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
|
||||
+ (val & CMN_PLL_CLKS_LOCKED),
|
||||
+ 100, 100 * USEC_PER_MSEC);
|
||||
+}
|
||||
+
|
||||
+static const struct clk_ops clk_cmn_pll_ops = {
|
||||
+ .recalc_rate = clk_cmn_pll_recalc_rate,
|
||||
+ .determine_rate = clk_cmn_pll_determine_rate,
|
||||
+ .set_rate = clk_cmn_pll_set_rate,
|
||||
+};
|
||||
+
|
||||
+static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct clk_parent_data pdata = { .index = 0 };
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct clk_init_data init = {};
|
||||
+ struct clk_cmn_pll *cmn_pll;
|
||||
+ struct regmap *regmap;
|
||||
+ void __iomem *base;
|
||||
+ int ret;
|
||||
+
|
||||
+ base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(base))
|
||||
+ return ERR_CAST(base);
|
||||
+
|
||||
+ regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config);
|
||||
+ if (IS_ERR(regmap))
|
||||
+ return ERR_CAST(regmap);
|
||||
+
|
||||
+ cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL);
|
||||
+ if (!cmn_pll)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ init.name = "cmn_pll";
|
||||
+ init.parent_data = &pdata;
|
||||
+ init.num_parents = 1;
|
||||
+ init.ops = &clk_cmn_pll_ops;
|
||||
+
|
||||
+ cmn_pll->hw.init = &init;
|
||||
+ cmn_pll->regmap = regmap;
|
||||
+
|
||||
+ ret = devm_clk_hw_register(dev, &cmn_pll->hw);
|
||||
+ if (ret)
|
||||
+ return ERR_PTR(ret);
|
||||
+
|
||||
+ return &cmn_pll->hw;
|
||||
+}
|
||||
+
|
||||
+static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct cmn_pll_fixed_output_clk *fixed_clk;
|
||||
+ struct clk_hw_onecell_data *hw_data;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct clk_hw *cmn_pll_hw;
|
||||
+ unsigned int num_clks;
|
||||
+ struct clk_hw *hw;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ fixed_clk = ipq9574_output_clks;
|
||||
+ num_clks = ARRAY_SIZE(ipq9574_output_clks);
|
||||
+
|
||||
+ hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!hw_data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /*
|
||||
+ * Register the CMN PLL clock, which is the parent clock of
|
||||
+ * the fixed rate output clocks.
|
||||
+ */
|
||||
+ cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev);
|
||||
+ if (IS_ERR(cmn_pll_hw))
|
||||
+ return PTR_ERR(cmn_pll_hw);
|
||||
+
|
||||
+ /* Register the fixed rate output clocks. */
|
||||
+ for (i = 0; i < num_clks; i++) {
|
||||
+ hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name,
|
||||
+ cmn_pll_hw, 0,
|
||||
+ fixed_clk[i].rate);
|
||||
+ if (IS_ERR(hw)) {
|
||||
+ ret = PTR_ERR(hw);
|
||||
+ goto unregister_fixed_clk;
|
||||
+ }
|
||||
+
|
||||
+ hw_data->hws[fixed_clk[i].id] = hw;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Provide the CMN PLL clock. The clock rate of CMN PLL
|
||||
+ * is configured to 12 GHZ by DT property assigned-clock-rates-u64.
|
||||
+ */
|
||||
+ hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw;
|
||||
+ hw_data->num = num_clks + 1;
|
||||
+
|
||||
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
|
||||
+ if (ret)
|
||||
+ goto unregister_fixed_clk;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, hw_data);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+unregister_fixed_clk:
|
||||
+ while (i > 0)
|
||||
+ clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = devm_pm_runtime_enable(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_pm_clk_create(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * To access the CMN PLL registers, the GCC AHB & SYS clocks
|
||||
+ * of CMN PLL block need to be enabled.
|
||||
+ */
|
||||
+ ret = pm_clk_add(dev, "ahb");
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Fail to add AHB clock\n");
|
||||
+
|
||||
+ ret = pm_clk_add(dev, "sys");
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Fail to add SYS clock\n");
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Register CMN PLL clock and fixed rate output clocks. */
|
||||
+ ret = ipq_cmn_pll_register_clks(pdev);
|
||||
+ pm_runtime_put(dev);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "Fail to register CMN PLL clocks\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ipq_cmn_pll_clk_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ /*
|
||||
+ * The clock with index CMN_PLL_CLK is unregistered by
|
||||
+ * device management.
|
||||
+ */
|
||||
+ for (i = 0; i < hw_data->num; i++) {
|
||||
+ if (i != CMN_PLL_CLK)
|
||||
+ clk_hw_unregister(hw_data->hws[i]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
|
||||
+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
|
||||
+ { .compatible = "qcom,ipq9574-cmn-pll", },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids);
|
||||
+
|
||||
+static struct platform_driver ipq_cmn_pll_clk_driver = {
|
||||
+ .probe = ipq_cmn_pll_clk_probe,
|
||||
+ .remove_new = ipq_cmn_pll_clk_remove,
|
||||
+ .driver = {
|
||||
+ .name = "ipq_cmn_pll",
|
||||
+ .of_match_table = ipq_cmn_pll_clk_ids,
|
||||
+ .pm = &ipq_cmn_pll_pm_ops,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(ipq_cmn_pll_clk_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,141 @@
|
||||
From c0f1cbf795095c21b92a46fa1dc47a7b787ce538 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Fri, 3 Jan 2025 15:31:34 +0800
|
||||
Subject: [PATCH 1/3] dt-bindings: clock: qcom: Add CMN PLL clock controller
|
||||
for IPQ SoC
|
||||
|
||||
The CMN PLL controller provides clocks to networking hardware blocks
|
||||
and to GCC on Qualcomm IPQ9574 SoC. It receives input clock from the
|
||||
on-chip Wi-Fi, and produces output clocks at fixed rates. These output
|
||||
rates are predetermined, and are unrelated to the input clock rate.
|
||||
The primary purpose of CMN PLL is to supply clocks to the networking
|
||||
hardware such as PPE (packet process engine), PCS and the externally
|
||||
connected switch or PHY device. The CMN PLL block also outputs fixed
|
||||
rate clocks to GCC, such as 24 MHZ as XO clock and 32 KHZ as sleep
|
||||
clock supplied to GCC.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-1-c89fb4d4849d@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
.../bindings/clock/qcom,ipq9574-cmn-pll.yaml | 77 +++++++++++++++++++
|
||||
include/dt-bindings/clock/qcom,ipq-cmn-pll.h | 22 ++++++
|
||||
2 files changed, 99 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
|
||||
create mode 100644 include/dt-bindings/clock/qcom,ipq-cmn-pll.h
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..f869b3739be8
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
|
||||
@@ -0,0 +1,77 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/clock/qcom,ipq9574-cmn-pll.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Qualcomm CMN PLL Clock Controller on IPQ SoC
|
||||
+
|
||||
+maintainers:
|
||||
+ - Bjorn Andersson <andersson@kernel.org>
|
||||
+ - Luo Jie <quic_luoj@quicinc.com>
|
||||
+
|
||||
+description:
|
||||
+ The CMN (or common) PLL clock controller expects a reference
|
||||
+ input clock. This reference clock is from the on-board Wi-Fi.
|
||||
+ The CMN PLL supplies a number of fixed rate output clocks to
|
||||
+ the devices providing networking functions and to GCC. These
|
||||
+ networking hardware include PPE (packet process engine), PCS
|
||||
+ and the externally connected switch or PHY devices. The CMN
|
||||
+ PLL block also outputs fixed rate clocks to GCC. The PLL's
|
||||
+ primary function is to enable fixed rate output clocks for
|
||||
+ networking hardware functions used with the IPQ SoC.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - qcom,ipq9574-cmn-pll
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ clocks:
|
||||
+ items:
|
||||
+ - description: The reference clock. The supported clock rates include
|
||||
+ 25000000, 31250000, 40000000, 48000000, 50000000 and 96000000 HZ.
|
||||
+ - description: The AHB clock
|
||||
+ - description: The SYS clock
|
||||
+ description:
|
||||
+ The reference clock is the source clock of CMN PLL, which is from the
|
||||
+ Wi-Fi. The AHB and SYS clocks must be enabled to access CMN PLL
|
||||
+ clock registers.
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: ref
|
||||
+ - const: ahb
|
||||
+ - const: sys
|
||||
+
|
||||
+ "#clock-cells":
|
||||
+ const: 1
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - "#clock-cells"
|
||||
+
|
||||
+additionalProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
|
||||
+ #include <dt-bindings/clock/qcom,ipq9574-gcc.h>
|
||||
+
|
||||
+ cmn_pll: clock-controller@9b000 {
|
||||
+ compatible = "qcom,ipq9574-cmn-pll";
|
||||
+ reg = <0x0009b000 0x800>;
|
||||
+ clocks = <&cmn_pll_ref_clk>,
|
||||
+ <&gcc GCC_CMN_12GPLL_AHB_CLK>,
|
||||
+ <&gcc GCC_CMN_12GPLL_SYS_CLK>;
|
||||
+ clock-names = "ref", "ahb", "sys";
|
||||
+ #clock-cells = <1>;
|
||||
+ assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
|
||||
+ assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
|
||||
+ };
|
||||
+...
|
||||
diff --git a/include/dt-bindings/clock/qcom,ipq-cmn-pll.h b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h
|
||||
new file mode 100644
|
||||
index 000000000000..936e92b3b62c
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/qcom,ipq-cmn-pll.h
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+/*
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H
|
||||
+#define _DT_BINDINGS_CLK_QCOM_IPQ_CMN_PLL_H
|
||||
+
|
||||
+/* CMN PLL core clock. */
|
||||
+#define CMN_PLL_CLK 0
|
||||
+
|
||||
+/* The output clocks from CMN PLL of IPQ9574. */
|
||||
+#define XO_24MHZ_CLK 1
|
||||
+#define SLEEP_32KHZ_CLK 2
|
||||
+#define PCS_31P25MHZ_CLK 3
|
||||
+#define NSS_1200MHZ_CLK 4
|
||||
+#define PPE_353MHZ_CLK 5
|
||||
+#define ETH0_50MHZ_CLK 6
|
||||
+#define ETH1_50MHZ_CLK 7
|
||||
+#define ETH2_50MHZ_CLK 8
|
||||
+#define ETH_25MHZ_CLK 9
|
||||
+#endif
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,129 @@
|
||||
From 758aa2d7e3c0acfe9c952a1cbe6416ec6130c2a1 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Fri, 3 Jan 2025 15:31:37 +0800
|
||||
Subject: [PATCH 2/3] arm64: dts: qcom: ipq9574: Add CMN PLL node
|
||||
|
||||
The CMN PLL clock controller allows selection of an input clock rate
|
||||
from a defined set of input clock rates. It in-turn supplies fixed
|
||||
rate output clocks to the hardware blocks that provide the ethernet
|
||||
functions such as PPE (Packet Process Engine) and connected switch or
|
||||
PHY, and to GCC.
|
||||
|
||||
The reference clock of CMN PLL is routed from XO to the CMN PLL through
|
||||
the internal WiFi block.
|
||||
.XO (48 MHZ or 96 MHZ)-->WiFi (multiplier/divider)-->48 MHZ to CMN PLL.
|
||||
|
||||
The reference input clock from WiFi to CMN PLL is fully controlled by
|
||||
the bootstrap pins which select the XO frequency (48 MHZ or 96 MHZ).
|
||||
Based on this frequency, the divider in the internal Wi-Fi block is
|
||||
automatically configured by hardware (1 for 48 MHZ, 2 for 96 MHZ), to
|
||||
ensure output clock to CMN PLL is 48 MHZ.
|
||||
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||
Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-4-c89fb4d4849d@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
.../boot/dts/qcom/ipq9574-rdp-common.dtsi | 17 +++++++++++-
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 26 ++++++++++++++++++-
|
||||
2 files changed, 41 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
index 91e104b0f865..bb1ff79360d3 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
@@ -3,7 +3,7 @@
|
||||
* IPQ9574 RDP board common device tree source
|
||||
*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
- * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
@@ -164,6 +164,21 @@ &usb3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * The bootstrap pins for the board select the XO clock frequency
|
||||
+ * (48 MHZ or 96 MHZ used for different RDP type board). This setting
|
||||
+ * automatically enables the right dividers, to ensure the reference
|
||||
+ * clock output from WiFi to the CMN PLL is 48 MHZ.
|
||||
+ */
|
||||
+&ref_48mhz_clk {
|
||||
+ clock-div = <1>;
|
||||
+ clock-mult = <1>;
|
||||
+};
|
||||
+
|
||||
&xo_board_clk {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
+
|
||||
+&xo_clk {
|
||||
+ clock-frequency = <48000000>;
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
index 00ee3290c181..c543c3492e93 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -3,10 +3,11 @@
|
||||
* IPQ9574 SoC device tree source
|
||||
*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
- * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/qcom,apss-ipq.h>
|
||||
+#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
|
||||
#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
|
||||
#include <dt-bindings/interconnect/qcom,ipq9574.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
@@ -19,6 +20,12 @@ / {
|
||||
#size-cells = <2>;
|
||||
|
||||
clocks {
|
||||
+ ref_48mhz_clk: ref-48mhz-clk {
|
||||
+ compatible = "fixed-factor-clock";
|
||||
+ clocks = <&xo_clk>;
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
sleep_clk: sleep-clk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
@@ -28,6 +35,11 @@ xo_board_clk: xo-board-clk {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
+
|
||||
+ xo_clk: xo-clk {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
};
|
||||
|
||||
cpus {
|
||||
@@ -335,6 +347,18 @@ pcie1_phy: phy@fc000 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ cmn_pll: clock-controller@9b000 {
|
||||
+ compatible = "qcom,ipq9574-cmn-pll";
|
||||
+ reg = <0x0009b000 0x800>;
|
||||
+ clocks = <&ref_48mhz_clk>,
|
||||
+ <&gcc GCC_CMN_12GPLL_AHB_CLK>,
|
||||
+ <&gcc GCC_CMN_12GPLL_SYS_CLK>;
|
||||
+ clock-names = "ref", "ahb", "sys";
|
||||
+ #clock-cells = <1>;
|
||||
+ assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
|
||||
+ assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
|
||||
+ };
|
||||
+
|
||||
qfprom: efuse@a4000 {
|
||||
compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
|
||||
reg = <0x000a4000 0x5a1>;
|
||||
--
|
||||
2.47.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 050b312654523aac9495eae3cf7bfa868fd981ce Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Fri, 3 Jan 2025 15:31:38 +0800
|
||||
Subject: [PATCH 3/3] arm64: dts: qcom: ipq9574: Update xo_board_clk to use
|
||||
fixed factor clock
|
||||
|
||||
xo_board_clk is fixed to 24 MHZ, which is routed from WiFi output clock
|
||||
48 MHZ (also being the reference clock of CMN PLL) divided 2 by analog
|
||||
block routing channel.
|
||||
|
||||
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
Link: https://lore.kernel.org/r/20250103-qcom_ipq_cmnpll-v8-5-c89fb4d4849d@quicinc.com
|
||||
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
|
||||
---
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi | 7 ++++++-
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 3 ++-
|
||||
2 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
index bb1ff79360d3..ae12f069f26f 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
|
||||
@@ -175,8 +175,13 @@ &ref_48mhz_clk {
|
||||
clock-mult = <1>;
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * The frequency of xo_board_clk is fixed to 24 MHZ, which is routed
|
||||
+ * from WiFi output clock 48 MHZ divided by 2.
|
||||
+ */
|
||||
&xo_board_clk {
|
||||
- clock-frequency = <24000000>;
|
||||
+ clock-div = <2>;
|
||||
+ clock-mult = <1>;
|
||||
};
|
||||
|
||||
&xo_clk {
|
||||
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
index c543c3492e93..3e93484e7e32 100644
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -32,7 +32,8 @@ sleep_clk: sleep-clk {
|
||||
};
|
||||
|
||||
xo_board_clk: xo-board-clk {
|
||||
- compatible = "fixed-clock";
|
||||
+ compatible = "fixed-factor-clock";
|
||||
+ clocks = <&ref_48mhz_clk>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
--
|
||||
2.47.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,144 @@
|
||||
From 968c5e8220209eb2185654f01748c349515a3b8e Mon Sep 17 00:00:00 2001
|
||||
From: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Date: Thu, 15 Feb 2024 12:26:40 +0530
|
||||
Subject: [PATCH v10 7/8] arm64: dts: qcom: ipq9574: Add SPI nand support
|
||||
|
||||
Add SPI NAND support for ipq9574 SoC.
|
||||
|
||||
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
---
|
||||
|
||||
Change in [v10]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v9]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v8]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v7]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v6]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v5]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v4]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v3]
|
||||
|
||||
* Updated gpio number as per pin control driver
|
||||
|
||||
* Fixed alignment issue
|
||||
|
||||
Change in [v2]
|
||||
|
||||
* Added initial enablement for spi-nand
|
||||
|
||||
Change in [v1]
|
||||
|
||||
* Posted as RFC patch for design review
|
||||
|
||||
.../boot/dts/qcom/ipq9574-rdp-common.dtsi | 43 +++++++++++++++++++
|
||||
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 27 ++++++++++++
|
||||
2 files changed, 70 insertions(+)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
@@ -121,6 +121,49 @@
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ qpic_snand_default_state: qpic-snand-default-state {
|
||||
+ clock-pins {
|
||||
+ pins = "gpio5";
|
||||
+ function = "qspi_clk";
|
||||
+ drive-strength = <8>;
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+
|
||||
+ cs-pins {
|
||||
+ pins = "gpio4";
|
||||
+ function = "qspi_cs";
|
||||
+ drive-strength = <8>;
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+
|
||||
+ data-pins {
|
||||
+ pins = "gpio0", "gpio1", "gpio2", "gpio3";
|
||||
+ function = "qspi_data";
|
||||
+ drive-strength = <8>;
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&qpic_bam {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&qpic_nand {
|
||||
+ pinctrl-0 = <&qpic_snand_default_state>;
|
||||
+ pinctrl-names = "default";
|
||||
+ status = "okay";
|
||||
+
|
||||
+ flash@0 {
|
||||
+ compatible = "spi-nand";
|
||||
+ reg = <0>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ nand-ecc-engine = <&qpic_nand>;
|
||||
+ nand-ecc-strength = <4>;
|
||||
+ nand-ecc-step-size = <512>;
|
||||
+ };
|
||||
};
|
||||
|
||||
&usb_0_dwc3 {
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
|
||||
@@ -300,6 +300,33 @@
|
||||
reg = <0x01937000 0x21000>;
|
||||
};
|
||||
|
||||
+ qpic_bam: dma-controller@7984000 {
|
||||
+ compatible = "qcom,bam-v1.7.0";
|
||||
+ reg = <0x7984000 0x1c000>;
|
||||
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&gcc GCC_QPIC_AHB_CLK>;
|
||||
+ clock-names = "bam_clk";
|
||||
+ #dma-cells = <1>;
|
||||
+ qcom,ee = <0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ qpic_nand: spi@79b0000 {
|
||||
+ compatible = "qcom,spi-qpic-snand", "qcom,ipq9574-nand";
|
||||
+ reg = <0x79b0000 0x10000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ clocks = <&gcc GCC_QPIC_CLK>,
|
||||
+ <&gcc GCC_QPIC_AHB_CLK>,
|
||||
+ <&gcc GCC_QPIC_IO_MACRO_CLK>;
|
||||
+ clock-names = "core", "aon", "iom";
|
||||
+ dmas = <&qpic_bam 0>,
|
||||
+ <&qpic_bam 1>,
|
||||
+ <&qpic_bam 2>;
|
||||
+ dma-names = "tx", "rx", "cmd";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
sdhc_1: mmc@7804000 {
|
||||
compatible = "qcom,ipq9574-sdhci", "qcom,sdhci-msm-v5";
|
||||
reg = <0x07804000 0x1000>, <0x07805000 0x1000>;
|
@ -0,0 +1,65 @@
|
||||
From a28a71e2a4728ec4f1f4a6b28595b664a1a49e4b Mon Sep 17 00:00:00 2001
|
||||
From: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
Date: Wed, 7 Feb 2024 16:05:27 +0530
|
||||
Subject: [PATCH v10 8/8] arm64: dts: qcom: ipq9574: Disable eMMC node
|
||||
|
||||
Disable eMMC node for rdp433, since rdp433
|
||||
default boot mode is norplusnand
|
||||
|
||||
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
|
||||
---
|
||||
|
||||
Change in [v10]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v9]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v8]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v7]
|
||||
|
||||
* No Change
|
||||
|
||||
Change in [v6]
|
||||
|
||||
* Updated commit message
|
||||
|
||||
Change in [v5]
|
||||
|
||||
* No Change
|
||||
|
||||
Change in [v4]
|
||||
|
||||
* No change
|
||||
|
||||
Change in [v3]
|
||||
|
||||
* Removed co-developed by
|
||||
|
||||
Change in [v2]
|
||||
|
||||
* Posted as initial eMMC disable patch
|
||||
|
||||
Change in [v1]
|
||||
|
||||
* This patch was not included in v1
|
||||
|
||||
arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
|
||||
@@ -82,7 +82,7 @@
|
||||
mmc-hs400-enhanced-strobe;
|
||||
max-frequency = <384000000>;
|
||||
bus-width = <8>;
|
||||
- status = "okay";
|
||||
+ status = "disabled";
|
||||
};
|
||||
|
||||
&sleep_clk {
|
@ -0,0 +1,253 @@
|
||||
From 9e76817056937645205f23ee91e762d5cff5e848 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Mon, 29 Jan 2024 17:57:20 +0800
|
||||
Subject: [PATCH 01/50] dt-bindings: net: Document Qualcomm QCA8084 PHY package
|
||||
|
||||
QCA8084 is quad PHY chip, which integrates 4 PHYs, 2 PCS
|
||||
interfaces (PCS0 and PCS1) and clock controller, which can
|
||||
also be integrated to the switch chip named as QCA8386.
|
||||
|
||||
1. MDIO address of 4 PHYs, 2 PCS and 1 XPCS (PCS1 includes
|
||||
PCS and XPCS, PCS0 includes PCS) can be configured.
|
||||
2. The package mode of PHY is optionally configured for the
|
||||
interface mode of two PCSes working correctly.
|
||||
3. The package level clock and reset need to be initialized.
|
||||
4. The clock and reset per PHY device need to be initialized
|
||||
so that the PHY register can be accessed.
|
||||
|
||||
Change-Id: Idb2338d2673152cbd3c57e95968faa59e9d4a80f
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
.../devicetree/bindings/net/qcom,qca8084.yaml | 198 ++++++++++++++++++
|
||||
include/dt-bindings/net/qcom,qca808x.h | 14 ++
|
||||
2 files changed, 212 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/qcom,qca8084.yaml
|
||||
create mode 100644 include/dt-bindings/net/qcom,qca808x.h
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/net/qcom,qca8084.yaml b/Documentation/devicetree/bindings/net/qcom,qca8084.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..efa1fa4ebfdc
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/qcom,qca8084.yaml
|
||||
@@ -0,0 +1,198 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/net/qcom,qca8084.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Qualcomm QCA8084 Ethernet Quad PHY
|
||||
+
|
||||
+maintainers:
|
||||
+ - Luo Jie <quic_luoj@quicinc.com>
|
||||
+
|
||||
+description:
|
||||
+ Qualcomm QCA8084 is a four-port Ethernet transceiver, the
|
||||
+ Ethernet port supports link speed 10/100/1000/2500 Mbps.
|
||||
+ There are two PCSes (PCS0 and PCS1) integrated in the PHY
|
||||
+ package, PCS1 includes XPCS and PCS to support the interface
|
||||
+ mode 10G-QXGMII and SGMII, PCS0 includes a PCS to support the
|
||||
+ interface mode SGMII only. There is also a clock controller
|
||||
+ integrated in the PHY package. This four-port Ethernet
|
||||
+ transceiver can also be integrated to the switch chip named
|
||||
+ as QCA8386. The PHY package mode needs to be configured as the
|
||||
+ correct value to apply the interface mode of two PCSes as
|
||||
+ mentioned below.
|
||||
+
|
||||
+ QCA8084 expects an input reference clock 50 MHZ as the clock
|
||||
+ source of the integrated clock controller, the integrated
|
||||
+ clock controller supplies the clocks and resets to the
|
||||
+ integrated PHY, PCS and PHY package.
|
||||
+
|
||||
+ - |
|
||||
+ +--| |--+-------------------+--| |--+
|
||||
+ | PCS1 |<------------+---->| PCS0 |
|
||||
+ +-------+ | +-------+
|
||||
+ | | |
|
||||
+ Ref 50M clk +--------+ | |
|
||||
+ ------------>| | clk & rst | |
|
||||
+ GPIO Reset |QCA8K_CC+------------+ |
|
||||
+ ------------>| | | |
|
||||
+ +--------+ | |
|
||||
+ | V |
|
||||
+ +--------+--------+--------+--------+
|
||||
+ | PHY0 | PHY1 | PHY2 | PHY3 |
|
||||
+ +--------+--------+--------+--------+
|
||||
+
|
||||
+$ref: ethernet-phy-package.yaml#
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ const: qcom,qca8084-package
|
||||
+
|
||||
+ clocks:
|
||||
+ description: PHY package level initial common clocks, which are
|
||||
+ needed to be enabled after GPIO reset on the PHY package, these
|
||||
+ clocks are supplied from the PHY integrated clock controller
|
||||
+ (QCA8K-CC).
|
||||
+ items:
|
||||
+ - description: APB bridge clock
|
||||
+ - description: AHB clock
|
||||
+ - description: Security control clock
|
||||
+ - description: TLMM clock
|
||||
+ - description: TLMM AHB clock
|
||||
+ - description: CNOC AHB clock
|
||||
+ - description: MDIO AHB clock
|
||||
+
|
||||
+ clock-names:
|
||||
+ items:
|
||||
+ - const: apb_bridge
|
||||
+ - const: ahb
|
||||
+ - const: sec_ctrl_ahb
|
||||
+ - const: tlmm
|
||||
+ - const: tlmm_ahb
|
||||
+ - const: cnoc_ahb
|
||||
+ - const: mdio_ahb
|
||||
+
|
||||
+ resets:
|
||||
+ description: PHY package level initial common reset, which are
|
||||
+ needed to be deasserted after GPIO reset on the PHY package,
|
||||
+ this reset is provided by the PHY integrated clock controller
|
||||
+ to do PHY DSP reset.
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ qcom,package-mode:
|
||||
+ description: |
|
||||
+ The package mode of PHY supports to be configured as 3 modes
|
||||
+ to apply the combinations of interface mode of two PCSes
|
||||
+ correctly. This value should use one of the values defined in
|
||||
+ dt-bindings/net/qcom,qca808x.h. The package mode 10G-QXGMII of
|
||||
+ Quad PHY is used by default.
|
||||
+
|
||||
+ package mode PCS1 PCS0
|
||||
+ phy mode (0) 10G-QXGMII for not used
|
||||
+ PHY0-PHY3
|
||||
+
|
||||
+ switch mode (1) SGMII for SGMII for
|
||||
+ switch MAC0 switch MAC5 (optional)
|
||||
+
|
||||
+ switch bypass MAC5 (2) SGMII for SGMII for
|
||||
+ switch MAC0 PHY3
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32
|
||||
+ enum: [0, 1, 2]
|
||||
+ default: 0
|
||||
+
|
||||
+ qcom,phy-addr-fixup:
|
||||
+ description: MDIO address for PHY0-PHY3, PCS0 and PCS1 including
|
||||
+ PCS and XPCS, which can be optionally customized by programming
|
||||
+ the security control register of PHY package. The hardware default
|
||||
+ MDIO address of PHY0-PHY3, PCS0 and PCS1 including PCS and XPCS is
|
||||
+ 0-6.
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
+ minItems: 7
|
||||
+ maxItems: 7
|
||||
+
|
||||
+patternProperties:
|
||||
+ ^ethernet-phy(@[a-f0-9]+)?$:
|
||||
+ $ref: ethernet-phy.yaml#
|
||||
+
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ const: ethernet-phy-id004d.d180
|
||||
+
|
||||
+ required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - clocks
|
||||
+ - resets
|
||||
+
|
||||
+ unevaluatedProperties: false
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - clocks
|
||||
+ - clock-names
|
||||
+ - resets
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/clock/qcom,qca8k-nsscc.h>
|
||||
+ #include <dt-bindings/net/qcom,qca808x.h>
|
||||
+ #include <dt-bindings/reset/qcom,qca8k-nsscc.h>
|
||||
+
|
||||
+ mdio {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ ethernet-phy-package@1 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "qcom,qca8084-package";
|
||||
+ reg = <1>;
|
||||
+ clocks = <&qca8k_nsscc NSS_CC_APB_BRIDGE_CLK>,
|
||||
+ <&qca8k_nsscc NSS_CC_AHB_CLK>,
|
||||
+ <&qca8k_nsscc NSS_CC_SEC_CTRL_AHB_CLK>,
|
||||
+ <&qca8k_nsscc NSS_CC_TLMM_CLK>,
|
||||
+ <&qca8k_nsscc NSS_CC_TLMM_AHB_CLK>,
|
||||
+ <&qca8k_nsscc NSS_CC_CNOC_AHB_CLK>,
|
||||
+ <&qca8k_nsscc NSS_CC_MDIO_AHB_CLK>;
|
||||
+ clock-names = "apb_bridge",
|
||||
+ "ahb",
|
||||
+ "sec_ctrl_ahb",
|
||||
+ "tlmm",
|
||||
+ "tlmm_ahb",
|
||||
+ "cnoc_ahb",
|
||||
+ "mdio_ahb";
|
||||
+ resets = <&qca8k_nsscc NSS_CC_GEPHY_FULL_ARES>;
|
||||
+ qcom,package-mode = <QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_MAC>;
|
||||
+ qcom,phy-addr-fixup = <1 2 3 4 5 6 7>;
|
||||
+
|
||||
+ ethernet-phy@1 {
|
||||
+ compatible = "ethernet-phy-id004d.d180";
|
||||
+ reg = <1>;
|
||||
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_CLK>;
|
||||
+ resets = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_ARES>;
|
||||
+ };
|
||||
+
|
||||
+ ethernet-phy@2 {
|
||||
+ compatible = "ethernet-phy-id004d.d180";
|
||||
+ reg = <2>;
|
||||
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_CLK>;
|
||||
+ resets = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_ARES>;
|
||||
+ };
|
||||
+
|
||||
+ ethernet-phy@3 {
|
||||
+ compatible = "ethernet-phy-id004d.d180";
|
||||
+ reg = <3>;
|
||||
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_CLK>;
|
||||
+ resets = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_ARES>;
|
||||
+ };
|
||||
+
|
||||
+ ethernet-phy@4 {
|
||||
+ compatible = "ethernet-phy-id004d.d180";
|
||||
+ reg = <4>;
|
||||
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_CLK>;
|
||||
+ resets = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_ARES>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
diff --git a/include/dt-bindings/net/qcom,qca808x.h b/include/dt-bindings/net/qcom,qca808x.h
|
||||
new file mode 100644
|
||||
index 000000000000..c3a2830445ea
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/net/qcom,qca808x.h
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
+/*
|
||||
+ * Device Tree constants for the Qualcomm QCA808X PHYs
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_QCOM_QCA808X_H
|
||||
+#define _DT_BINDINGS_QCOM_QCA808X_H
|
||||
+
|
||||
+/* PHY package modes of QCA8084 to apply the interface modes of two PCSes. */
|
||||
+#define QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED 0
|
||||
+#define QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_MAC 1
|
||||
+#define QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_PHY 2
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,138 @@
|
||||
From 9dec04efa81322029e210281b1753a2eb5279e27 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Thu, 6 Apr 2023 18:09:07 +0800
|
||||
Subject: [PATCH 02/50] net: phy: qca808x: Add QCA8084 ethernet phy support
|
||||
|
||||
Add QCA8084 Quad-PHY support, which is a four-port PHY with
|
||||
maximum link capability of 2.5 Gbps. The features of each port
|
||||
are almost same as QCA8081. The slave seed and fast retrain
|
||||
configs are not needed for QCA8084. It includes two PCSes.
|
||||
|
||||
PCS0 of QCA8084 supports the interface modes:
|
||||
PHY_INTERFACE_MODE_2500BASEX and PHY_INTERFACE_MODE_SGMII.
|
||||
|
||||
PCS1 of QCA8084 supports the interface modes:
|
||||
PHY_INTERFACE_MODE_10G_QXGMII, PHY_INTERFACE_MODE_2500BASEX and
|
||||
PHY_INTERFACE_MODE_SGMII.
|
||||
|
||||
The additional CDT configurations needed for QCA8084 compared
|
||||
with QCA8081.
|
||||
|
||||
Change-Id: I12555fa70662682474ab4432204405b5e752fef6
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 62 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 60 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index 5048304ccc9e..be46d16ca09f 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -86,9 +86,16 @@
|
||||
#define QCA8081_PHY_FIFO_RSTN BIT(11)
|
||||
|
||||
#define QCA8081_PHY_ID 0x004dd101
|
||||
+#define QCA8084_PHY_ID 0x004dd180
|
||||
+
|
||||
+#define QCA8084_MMD3_CDT_PULSE_CTRL 0x8075
|
||||
+#define QCA8084_CDT_PULSE_THRESH_VAL 0xa060
|
||||
+
|
||||
+#define QCA8084_MMD3_CDT_NEAR_CTRL 0x807f
|
||||
+#define QCA8084_CDT_NEAR_BYPASS BIT(15)
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
-MODULE_AUTHOR("Matus Ujhelyi");
|
||||
+MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
struct qca808x_priv {
|
||||
@@ -153,7 +160,9 @@ static bool qca808x_is_prefer_master(struct phy_device *phydev)
|
||||
|
||||
static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
|
||||
{
|
||||
- return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
|
||||
+ return phydev_id_compare(phydev, QCA8081_PHY_ID) &&
|
||||
+ linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||
+ phydev->supported);
|
||||
}
|
||||
|
||||
static bool qca808x_is_1g_only(struct phy_device *phydev)
|
||||
@@ -273,6 +282,23 @@ static int qca808x_read_status(struct phy_device *phydev)
|
||||
return ret;
|
||||
|
||||
if (phydev->link) {
|
||||
+ /* There are two PCSes available for QCA8084, which support
|
||||
+ * the following interface modes.
|
||||
+ *
|
||||
+ * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
|
||||
+ * available 4 ports, which is for all link speeds.
|
||||
+ *
|
||||
+ * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
|
||||
+ * fourth port, which is only for the link speed 2500M same
|
||||
+ * as QCA8081.
|
||||
+ *
|
||||
+ * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
|
||||
+ * port, which is for the link speed 10M, 100M and 1000M same
|
||||
+ * as QCA8081.
|
||||
+ */
|
||||
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
+ return 0;
|
||||
+
|
||||
if (phydev->speed == SPEED_2500)
|
||||
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
else
|
||||
@@ -352,6 +378,18 @@ static int qca808x_cable_test_start(struct phy_device *phydev)
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
|
||||
|
||||
+ if (phydev_id_compare(phydev, QCA8084_PHY_ID)) {
|
||||
+ /* Adjust the positive and negative pulse thereshold of CDT. */
|
||||
+ phy_write_mmd(phydev, MDIO_MMD_PCS,
|
||||
+ QCA8084_MMD3_CDT_PULSE_CTRL,
|
||||
+ QCA8084_CDT_PULSE_THRESH_VAL);
|
||||
+
|
||||
+ /* Disable the near bypass of CDT. */
|
||||
+ phy_modify_mmd(phydev, MDIO_MMD_PCS,
|
||||
+ QCA8084_MMD3_CDT_NEAR_CTRL,
|
||||
+ QCA8084_CDT_NEAR_BYPASS, 0);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -651,12 +689,32 @@ static struct phy_driver qca808x_driver[] = {
|
||||
.led_hw_control_set = qca808x_led_hw_control_set,
|
||||
.led_hw_control_get = qca808x_led_hw_control_get,
|
||||
.led_polarity_set = qca808x_led_polarity_set,
|
||||
+}, {
|
||||
+ /* Qualcomm QCA8084 */
|
||||
+ PHY_ID_MATCH_MODEL(QCA8084_PHY_ID),
|
||||
+ .name = "Qualcomm QCA8084",
|
||||
+ .flags = PHY_POLL_CABLE_TEST,
|
||||
+ .config_intr = at803x_config_intr,
|
||||
+ .handle_interrupt = at803x_handle_interrupt,
|
||||
+ .get_tunable = at803x_get_tunable,
|
||||
+ .set_tunable = at803x_set_tunable,
|
||||
+ .set_wol = at803x_set_wol,
|
||||
+ .get_wol = at803x_get_wol,
|
||||
+ .get_features = qca808x_get_features,
|
||||
+ .config_aneg = qca808x_config_aneg,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+ .read_status = qca808x_read_status,
|
||||
+ .soft_reset = qca808x_soft_reset,
|
||||
+ .cable_test_start = qca808x_cable_test_start,
|
||||
+ .cable_test_get_status = qca808x_cable_test_get_status,
|
||||
}, };
|
||||
|
||||
module_phy_driver(qca808x_driver);
|
||||
|
||||
static struct mdio_device_id __maybe_unused qca808x_tbl[] = {
|
||||
{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
|
||||
+ { PHY_ID_MATCH_MODEL(QCA8084_PHY_ID) },
|
||||
{ }
|
||||
};
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,90 @@
|
||||
From fd5ec7c0a9f7167baf377a4bbae72eda391df996 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 8 Nov 2023 16:18:02 +0800
|
||||
Subject: [PATCH 03/50] net: phy: qca808x: Add config_init function for QCA8084
|
||||
|
||||
1. The ADC of QCA8084 PHY must be configured as edge inverted
|
||||
and falling whenever it is initialized or reset. In addition,
|
||||
the default MSE (Mean square error) threshold value is adjusted,
|
||||
which comes into play during link partner detection to detect
|
||||
the valid link signal.
|
||||
|
||||
2. Add the possible interface modes.
|
||||
When QCA8084 works on the interface mode SGMII or 2500BASE-X, the
|
||||
interface mode can be switched according to the PHY link speed.
|
||||
|
||||
When QCA8084 works on the 10G-QXGMII mode, which will be the only
|
||||
possible interface mode.
|
||||
|
||||
Change-Id: I832c0d0b069e95cc411a8a7b680a5f60e1d6041a
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 38 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 38 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index be46d16ca09f..c88fa59d4029 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -94,6 +94,15 @@
|
||||
#define QCA8084_MMD3_CDT_NEAR_CTRL 0x807f
|
||||
#define QCA8084_CDT_NEAR_BYPASS BIT(15)
|
||||
|
||||
+/* QCA8084 ADC clock edge */
|
||||
+#define QCA8084_ADC_CLK_SEL 0x8b80
|
||||
+#define QCA8084_ADC_CLK_SEL_ACLK GENMASK(7, 4)
|
||||
+#define QCA8084_ADC_CLK_SEL_ACLK_FALL 0xf
|
||||
+#define QCA8084_ADC_CLK_SEL_ACLK_RISE 0x0
|
||||
+
|
||||
+#define QCA8084_MSE_THRESHOLD 0x800a
|
||||
+#define QCA8084_MSE_THRESHOLD_2P5G_VAL 0x51c6
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -660,6 +669,34 @@ static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
|
||||
active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
|
||||
}
|
||||
|
||||
+static int qca8084_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
+ __set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
|
||||
+ phydev->possible_interfaces);
|
||||
+ else
|
||||
+ qca808x_fill_possible_interfaces(phydev);
|
||||
+
|
||||
+ /* Configure the ADC to convert the signal using falling edge
|
||||
+ * instead of the default rising edge.
|
||||
+ */
|
||||
+ ret = at803x_debug_reg_mask(phydev, QCA8084_ADC_CLK_SEL,
|
||||
+ QCA8084_ADC_CLK_SEL_ACLK,
|
||||
+ FIELD_PREP(QCA8084_ADC_CLK_SEL_ACLK,
|
||||
+ QCA8084_ADC_CLK_SEL_ACLK_FALL));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Adjust MSE threshold value to avoid link issue with
|
||||
+ * some link partner.
|
||||
+ */
|
||||
+ return phy_write_mmd(phydev, MDIO_MMD_PMAPMD,
|
||||
+ QCA8084_MSE_THRESHOLD,
|
||||
+ QCA8084_MSE_THRESHOLD_2P5G_VAL);
|
||||
+}
|
||||
+
|
||||
static struct phy_driver qca808x_driver[] = {
|
||||
{
|
||||
/* Qualcomm QCA8081 */
|
||||
@@ -708,6 +745,7 @@ static struct phy_driver qca808x_driver[] = {
|
||||
.soft_reset = qca808x_soft_reset,
|
||||
.cable_test_start = qca808x_cable_test_start,
|
||||
.cable_test_get_status = qca808x_cable_test_get_status,
|
||||
+ .config_init = qca8084_config_init,
|
||||
}, };
|
||||
|
||||
module_phy_driver(qca808x_driver);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,95 @@
|
||||
From d9b391e7b695b7de04c4363b5ec9ffaaed387353 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 8 Nov 2023 18:01:14 +0800
|
||||
Subject: [PATCH 04/50] net: phy: qca808x: Add link_change_notify function for
|
||||
QCA8084
|
||||
|
||||
When the link is changed, QCA8084 needs to do the fifo reset and
|
||||
adjust the IPG level for the 10G-QXGMII link on the speed 1000M.
|
||||
|
||||
Change-Id: I21de802c78496fb95f1c5119fe3894c9fdebbd65
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 52 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 52 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index c88fa59d4029..029d5f9de6b8 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -103,6 +103,14 @@
|
||||
#define QCA8084_MSE_THRESHOLD 0x800a
|
||||
#define QCA8084_MSE_THRESHOLD_2P5G_VAL 0x51c6
|
||||
|
||||
+/* QCA8084 FIFO reset control */
|
||||
+#define QCA8084_FIFO_CONTROL 0x19
|
||||
+#define QCA8084_FIFO_MAC_2_PHY BIT(1)
|
||||
+#define QCA8084_FIFO_PHY_2_MAC BIT(0)
|
||||
+
|
||||
+#define QCA8084_MMD7_IPG_OP 0x901d
|
||||
+#define QCA8084_IPG_10_TO_11_EN BIT(0)
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -697,6 +705,49 @@ static int qca8084_config_init(struct phy_device *phydev)
|
||||
QCA8084_MSE_THRESHOLD_2P5G_VAL);
|
||||
}
|
||||
|
||||
+static void qca8084_link_change_notify(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Assert the FIFO between PHY and MAC. */
|
||||
+ ret = phy_modify(phydev, QCA8084_FIFO_CONTROL,
|
||||
+ QCA8084_FIFO_MAC_2_PHY | QCA8084_FIFO_PHY_2_MAC,
|
||||
+ 0);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "Asserting PHY FIFO failed\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* If the PHY is in 10G_QXGMII mode, the FIFO needs to be kept in
|
||||
+ * reset state when link is down, otherwise the FIFO needs to be
|
||||
+ * de-asserted after waiting 50 ms to make the assert completed.
|
||||
+ */
|
||||
+ if (phydev->interface != PHY_INTERFACE_MODE_10G_QXGMII ||
|
||||
+ phydev->link) {
|
||||
+ msleep(50);
|
||||
+
|
||||
+ /* Deassert the FIFO between PHY and MAC. */
|
||||
+ ret = phy_modify(phydev, QCA8084_FIFO_CONTROL,
|
||||
+ QCA8084_FIFO_MAC_2_PHY |
|
||||
+ QCA8084_FIFO_PHY_2_MAC,
|
||||
+ QCA8084_FIFO_MAC_2_PHY |
|
||||
+ QCA8084_FIFO_PHY_2_MAC);
|
||||
+ if (ret) {
|
||||
+ phydev_err(phydev, "De-asserting PHY FIFO failed\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Enable IPG level 10 to 11 tuning for link speed 1000M in the
|
||||
+ * 10G_QXGMII mode.
|
||||
+ */
|
||||
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
+ phy_modify_mmd(phydev, MDIO_MMD_AN, QCA8084_MMD7_IPG_OP,
|
||||
+ QCA8084_IPG_10_TO_11_EN,
|
||||
+ phydev->speed == SPEED_1000 ?
|
||||
+ QCA8084_IPG_10_TO_11_EN : 0);
|
||||
+}
|
||||
+
|
||||
static struct phy_driver qca808x_driver[] = {
|
||||
{
|
||||
/* Qualcomm QCA8081 */
|
||||
@@ -746,6 +797,7 @@ static struct phy_driver qca808x_driver[] = {
|
||||
.cable_test_start = qca808x_cable_test_start,
|
||||
.cable_test_get_status = qca808x_cable_test_get_status,
|
||||
.config_init = qca8084_config_init,
|
||||
+ .link_change_notify = qca8084_link_change_notify,
|
||||
}, };
|
||||
|
||||
module_phy_driver(qca808x_driver);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,130 @@
|
||||
From 9443d85d8f3e397b025700251516e248fc4e37c0 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 29 Nov 2023 15:21:22 +0800
|
||||
Subject: [PATCH 05/50] net: phy: qca808x: Add register access support routines
|
||||
for QCA8084
|
||||
|
||||
QCA8084 integrates clock controller and security control modules
|
||||
besides of the PHY and PCS. The 32bit registers in these modules
|
||||
are accessed using special MDIO sequences to read or write these
|
||||
registers.
|
||||
|
||||
The MDIO address of PHY and PCS are configured by writing to the
|
||||
security control register. The package mode for QCA8084 is also
|
||||
configured in a similar manner.
|
||||
|
||||
Change-Id: I9317307ef9bbc738a6adcbc3ea1be8e6528d711e
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 88 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 88 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index 029d5f9de6b8..8873474146e8 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -111,6 +111,22 @@
|
||||
#define QCA8084_MMD7_IPG_OP 0x901d
|
||||
#define QCA8084_IPG_10_TO_11_EN BIT(0)
|
||||
|
||||
+/* QCA8084 includes secure control module, which supports customizing the
|
||||
+ * MDIO address of PHY device and PCS device and configuring package mode
|
||||
+ * for the interface mode of PCS. The register of secure control is accessed
|
||||
+ * by MDIO bus with the special MDIO sequences, where the 32 bits register
|
||||
+ * address is split into 3 MDIO operations with 16 bits address.
|
||||
+ */
|
||||
+#define QCA8084_HIGH_ADDR_PREFIX 0x18
|
||||
+#define QCA8084_LOW_ADDR_PREFIX 0x10
|
||||
+
|
||||
+/* Bottom two bits of REG must be zero */
|
||||
+#define QCA8084_MII_REG_MASK GENMASK(4, 0)
|
||||
+#define QCA8084_MII_PHY_ADDR_MASK GENMASK(7, 5)
|
||||
+#define QCA8084_MII_PAGE_MASK GENMASK(23, 8)
|
||||
+#define QCA8084_MII_SW_ADDR_MASK GENMASK(31, 24)
|
||||
+#define QCA8084_MII_REG_DATA_UPPER_16_BITS BIT(1)
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -119,6 +135,78 @@ struct qca808x_priv {
|
||||
int led_polarity_mode;
|
||||
};
|
||||
|
||||
+static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
|
||||
+{
|
||||
+ return __mdiobus_write(bus, QCA8084_HIGH_ADDR_PREFIX | (sw_addr >> 5),
|
||||
+ sw_addr & 0x1f, page);
|
||||
+}
|
||||
+
|
||||
+static int __qca8084_mii_read(struct mii_bus *bus, u16 addr, u16 reg, u32 *val)
|
||||
+{
|
||||
+ int ret, data;
|
||||
+
|
||||
+ ret = __mdiobus_read(bus, addr, reg);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ data = ret;
|
||||
+ ret = __mdiobus_read(bus, addr,
|
||||
+ reg | QCA8084_MII_REG_DATA_UPPER_16_BITS);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ *val = data | ret << 16;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __qca8084_mii_write(struct mii_bus *bus, u16 addr, u16 reg, u32 val)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = __mdiobus_write(bus, addr, reg, lower_16_bits(val));
|
||||
+ if (!ret)
|
||||
+ ret = __mdiobus_write(bus, addr,
|
||||
+ reg | QCA8084_MII_REG_DATA_UPPER_16_BITS,
|
||||
+ upper_16_bits(val));
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int qca8084_mii_modify(struct phy_device *phydev, u32 regaddr,
|
||||
+ u32 clear, u32 set)
|
||||
+{
|
||||
+ u16 reg, addr, page, sw_addr;
|
||||
+ struct mii_bus *bus;
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ bus = phydev->mdio.bus;
|
||||
+ mutex_lock(&bus->mdio_lock);
|
||||
+
|
||||
+ reg = FIELD_GET(QCA8084_MII_REG_MASK, regaddr);
|
||||
+ addr = FIELD_GET(QCA8084_MII_PHY_ADDR_MASK, regaddr);
|
||||
+ page = FIELD_GET(QCA8084_MII_PAGE_MASK, regaddr);
|
||||
+ sw_addr = FIELD_GET(QCA8084_MII_SW_ADDR_MASK, regaddr);
|
||||
+
|
||||
+ ret = __qca8084_set_page(bus, sw_addr, page);
|
||||
+ if (ret < 0)
|
||||
+ goto qca8084_mii_modify_exit;
|
||||
+
|
||||
+ ret = __qca8084_mii_read(bus, QCA8084_LOW_ADDR_PREFIX | addr,
|
||||
+ reg, &val);
|
||||
+ if (ret < 0)
|
||||
+ goto qca8084_mii_modify_exit;
|
||||
+
|
||||
+ val &= ~clear;
|
||||
+ val |= set;
|
||||
+ ret = __qca8084_mii_write(bus, QCA8084_LOW_ADDR_PREFIX | addr,
|
||||
+ reg, val);
|
||||
+qca8084_mii_modify_exit:
|
||||
+ mutex_unlock(&bus->mdio_lock);
|
||||
+ return ret;
|
||||
+};
|
||||
+
|
||||
static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,145 @@
|
||||
From 9d0e22124d6f3ca901626dd5537b36c7c0c97812 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Mon, 29 Jan 2024 10:51:38 +0800
|
||||
Subject: [PATCH 06/50] net: phy: qca808x: Add QCA8084 probe function
|
||||
|
||||
Add the PHY package probe function. The MDIO slave address of
|
||||
PHY, PCS and XPCS can be optionally customized by configuring
|
||||
the PHY package level register.
|
||||
|
||||
In addition, enable system clock of PHY and de-assert PHY in
|
||||
the probe function so that the register of PHY device can be
|
||||
accessed, and the features of PHY can be acquired.
|
||||
|
||||
Change-Id: I2251b9c5c398a21a4ef547a727189a934ad3a44c
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 91 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 91 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index 8873474146e8..85bb299fe0a3 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <linux/phy.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/clk.h>
|
||||
|
||||
#include "qcom.h"
|
||||
|
||||
@@ -127,6 +129,21 @@
|
||||
#define QCA8084_MII_SW_ADDR_MASK GENMASK(31, 24)
|
||||
#define QCA8084_MII_REG_DATA_UPPER_16_BITS BIT(1)
|
||||
|
||||
+/* QCA8084 integrates 4 PHYs, PCS0 and PCS1(includes PCS and XPCS). */
|
||||
+#define QCA8084_MDIO_DEVICE_NUM 7
|
||||
+
|
||||
+#define QCA8084_PCS_CFG 0xc90f014
|
||||
+#define QCA8084_PCS_ADDR0_MASK GENMASK(4, 0)
|
||||
+#define QCA8084_PCS_ADDR1_MASK GENMASK(9, 5)
|
||||
+#define QCA8084_PCS_ADDR2_MASK GENMASK(14, 10)
|
||||
+
|
||||
+#define QCA8084_EPHY_CFG 0xc90f018
|
||||
+#define QCA8084_EPHY_ADDR0_MASK GENMASK(4, 0)
|
||||
+#define QCA8084_EPHY_ADDR1_MASK GENMASK(9, 5)
|
||||
+#define QCA8084_EPHY_ADDR2_MASK GENMASK(14, 10)
|
||||
+#define QCA8084_EPHY_ADDR3_MASK GENMASK(19, 15)
|
||||
+#define QCA8084_EPHY_LDO_EN GENMASK(21, 20)
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -836,6 +853,79 @@ static void qca8084_link_change_notify(struct phy_device *phydev)
|
||||
QCA8084_IPG_10_TO_11_EN : 0);
|
||||
}
|
||||
|
||||
+static int qca8084_phy_package_probe_once(struct phy_device *phydev)
|
||||
+{
|
||||
+ int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
|
||||
+ struct phy_package_shared *shared = phydev->shared;
|
||||
+ int ret, clear, set;
|
||||
+
|
||||
+ /* Program the MDIO address of PHY and PCS optionally, the MDIO
|
||||
+ * address 0-6 is used for PHY and PCS MDIO devices by default.
|
||||
+ */
|
||||
+ ret = of_property_read_u32_array(shared->np,
|
||||
+ "qcom,phy-addr-fixup",
|
||||
+ addr, ARRAY_SIZE(addr));
|
||||
+ if (ret && ret != -EINVAL)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Configure the MDIO addresses for the four PHY devices. */
|
||||
+ clear = QCA8084_EPHY_ADDR0_MASK | QCA8084_EPHY_ADDR1_MASK |
|
||||
+ QCA8084_EPHY_ADDR2_MASK | QCA8084_EPHY_ADDR3_MASK;
|
||||
+ set = FIELD_PREP(QCA8084_EPHY_ADDR0_MASK, addr[0]);
|
||||
+ set |= FIELD_PREP(QCA8084_EPHY_ADDR1_MASK, addr[1]);
|
||||
+ set |= FIELD_PREP(QCA8084_EPHY_ADDR2_MASK, addr[2]);
|
||||
+ set |= FIELD_PREP(QCA8084_EPHY_ADDR3_MASK, addr[3]);
|
||||
+
|
||||
+ ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG, clear, set);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Configure the MDIO addresses for PCS0 and PCS1 including
|
||||
+ * PCS and XPCS.
|
||||
+ */
|
||||
+ clear = QCA8084_PCS_ADDR0_MASK | QCA8084_PCS_ADDR1_MASK |
|
||||
+ QCA8084_PCS_ADDR2_MASK;
|
||||
+ set = FIELD_PREP(QCA8084_PCS_ADDR0_MASK, addr[4]);
|
||||
+ set |= FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]);
|
||||
+ set |= FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]);
|
||||
+
|
||||
+ return qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
|
||||
+}
|
||||
+
|
||||
+static int qca8084_probe(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct device *dev = &phydev->mdio.dev;
|
||||
+ struct reset_control *rstc;
|
||||
+ struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = devm_of_phy_package_join(dev, phydev, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (phy_package_probe_once(phydev)) {
|
||||
+ ret = qca8084_phy_package_probe_once(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Enable clock of PHY device, so that the PHY register
|
||||
+ * can be accessed to get PHY features.
|
||||
+ */
|
||||
+ clk = devm_clk_get_enabled(dev, NULL);
|
||||
+ if (IS_ERR(clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(clk),
|
||||
+ "Enable PHY clock failed\n");
|
||||
+
|
||||
+ /* De-assert PHY reset after the clock of PHY enabled. */
|
||||
+ rstc = devm_reset_control_get_exclusive(dev, NULL);
|
||||
+ if (IS_ERR(rstc))
|
||||
+ return dev_err_probe(dev, PTR_ERR(rstc),
|
||||
+ "Get PHY reset failed\n");
|
||||
+
|
||||
+ return reset_control_deassert(rstc);
|
||||
+}
|
||||
+
|
||||
static struct phy_driver qca808x_driver[] = {
|
||||
{
|
||||
/* Qualcomm QCA8081 */
|
||||
@@ -886,6 +976,7 @@ static struct phy_driver qca808x_driver[] = {
|
||||
.cable_test_get_status = qca808x_cable_test_get_status,
|
||||
.config_init = qca8084_config_init,
|
||||
.link_change_notify = qca8084_link_change_notify,
|
||||
+ .probe = qca8084_probe,
|
||||
}, };
|
||||
|
||||
module_phy_driver(qca808x_driver);
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,138 @@
|
||||
From 324c5b908a5294390ed9659a6439758cb20ecd61 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Tue, 9 Apr 2024 16:30:55 +0800
|
||||
Subject: [PATCH 07/50] net: phy: qca808x: Add package clocks and resets for
|
||||
QCA8084
|
||||
|
||||
Parse the PHY package clocks from the PHY package DTS node.
|
||||
These package level clocks will be enabled in the PHY package
|
||||
init function.
|
||||
|
||||
Deassert PHY package reset, which is necessary for accessing
|
||||
the PHY registers.
|
||||
|
||||
Change-Id: I254d0aa0a1155d3618c6f1fc7d7a5b6ecadccbaa
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 67 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 64 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index 85bb299fe0a3..632cad1ad190 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/reset.h>
|
||||
|
||||
#include "qcom.h"
|
||||
|
||||
@@ -148,10 +149,35 @@ MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
+enum {
|
||||
+ APB_BRIDGE_CLK,
|
||||
+ AHB_CLK,
|
||||
+ SEC_CTRL_AHB_CLK,
|
||||
+ TLMM_CLK,
|
||||
+ TLMM_AHB_CLK,
|
||||
+ CNOC_AHB_CLK,
|
||||
+ MDIO_AHB_CLK,
|
||||
+ PACKAGE_CLK_MAX
|
||||
+};
|
||||
+
|
||||
struct qca808x_priv {
|
||||
int led_polarity_mode;
|
||||
};
|
||||
|
||||
+struct qca808x_shared_priv {
|
||||
+ struct clk *clk[PACKAGE_CLK_MAX];
|
||||
+};
|
||||
+
|
||||
+static const char *const qca8084_package_clk_name[PACKAGE_CLK_MAX] = {
|
||||
+ [APB_BRIDGE_CLK] = "apb_bridge",
|
||||
+ [AHB_CLK] = "ahb",
|
||||
+ [SEC_CTRL_AHB_CLK] = "sec_ctrl_ahb",
|
||||
+ [TLMM_CLK] = "tlmm",
|
||||
+ [TLMM_AHB_CLK] = "tlmm_ahb",
|
||||
+ [CNOC_AHB_CLK] = "cnoc_ahb",
|
||||
+ [MDIO_AHB_CLK] = "mdio_ahb",
|
||||
+};
|
||||
+
|
||||
static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
|
||||
{
|
||||
return __mdiobus_write(bus, QCA8084_HIGH_ADDR_PREFIX | (sw_addr >> 5),
|
||||
@@ -853,11 +879,24 @@ static void qca8084_link_change_notify(struct phy_device *phydev)
|
||||
QCA8084_IPG_10_TO_11_EN : 0);
|
||||
}
|
||||
|
||||
+/* QCA8084 is a four-port PHY, which integrates the clock controller,
|
||||
+ * 4 PHY devices and 2 PCS interfaces (PCS0 and PCS1). PCS1 includes
|
||||
+ * XPCS and PCS to support 10G-QXGMII and SGMII. PCS0 includes one PCS
|
||||
+ * to support SGMII.
|
||||
+ *
|
||||
+ * The clocks and resets are sourced from the integrated clock controller
|
||||
+ * of the PHY package. This integrated clock controller is driven by a
|
||||
+ * QCA8K clock provider that supplies the clocks and resets to the four
|
||||
+ * PHYs, PCS and PHY package.
|
||||
+ */
|
||||
static int qca8084_phy_package_probe_once(struct phy_device *phydev)
|
||||
{
|
||||
int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
|
||||
struct phy_package_shared *shared = phydev->shared;
|
||||
- int ret, clear, set;
|
||||
+ struct qca808x_shared_priv *shared_priv;
|
||||
+ struct reset_control *rstc;
|
||||
+ int i, ret, clear, set;
|
||||
+ struct clk *clk;
|
||||
|
||||
/* Program the MDIO address of PHY and PCS optionally, the MDIO
|
||||
* address 0-6 is used for PHY and PCS MDIO devices by default.
|
||||
@@ -889,17 +928,39 @@ static int qca8084_phy_package_probe_once(struct phy_device *phydev)
|
||||
set |= FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]);
|
||||
set |= FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]);
|
||||
|
||||
- return qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
|
||||
+ ret = qca8084_mii_modify(phydev, QCA8084_PCS_CFG, clear, set);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ shared_priv = shared->priv;
|
||||
+ for (i = 0; i < ARRAY_SIZE(qca8084_package_clk_name); i++) {
|
||||
+ clk = of_clk_get_by_name(shared->np,
|
||||
+ qca8084_package_clk_name[i]);
|
||||
+ if (IS_ERR(clk))
|
||||
+ return dev_err_probe(&phydev->mdio.dev, PTR_ERR(clk),
|
||||
+ "package clock %s not ready\n",
|
||||
+ qca8084_package_clk_name[i]);
|
||||
+ shared_priv->clk[i] = clk;
|
||||
+ }
|
||||
+
|
||||
+ rstc = of_reset_control_get_exclusive(shared->np, NULL);
|
||||
+ if (IS_ERR(rstc))
|
||||
+ return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
|
||||
+ "package reset not ready\n");
|
||||
+
|
||||
+ /* Deassert PHY package. */
|
||||
+ return reset_control_deassert(rstc);
|
||||
}
|
||||
|
||||
static int qca8084_probe(struct phy_device *phydev)
|
||||
{
|
||||
+ struct qca808x_shared_priv *shared_priv;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct reset_control *rstc;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
- ret = devm_of_phy_package_join(dev, phydev, 0);
|
||||
+ ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,176 @@
|
||||
From 392a648b7b0324d03e6f6a7b326e33136d79b134 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Thu, 25 Jan 2024 17:13:24 +0800
|
||||
Subject: [PATCH 08/50] net: phy: qca808x: Add QCA8084 package init function
|
||||
|
||||
The package mode of PHY is configured for the interface mode of two
|
||||
PCSes working correctly.
|
||||
|
||||
The PHY package level clocks are enabled and their rates configured.
|
||||
|
||||
Change-Id: I63d4b22d2a70ee713cc6a6818b0f3c7aa098a5f5
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/phy/qcom/qca808x.c | 115 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 115 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c
|
||||
index 632cad1ad190..459f8e8a9749 100644
|
||||
--- a/drivers/net/phy/qcom/qca808x.c
|
||||
+++ b/drivers/net/phy/qcom/qca808x.c
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
+#include <dt-bindings/net/qcom,qca808x.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
@@ -145,6 +146,13 @@
|
||||
#define QCA8084_EPHY_ADDR3_MASK GENMASK(19, 15)
|
||||
#define QCA8084_EPHY_LDO_EN GENMASK(21, 20)
|
||||
|
||||
+#define QCA8084_WORK_MODE_CFG 0xc90f030
|
||||
+#define QCA8084_WORK_MODE_MASK GENMASK(5, 0)
|
||||
+#define QCA8084_WORK_MODE_QXGMII (BIT(5) | GENMASK(3, 0))
|
||||
+#define QCA8084_WORK_MODE_QXGMII_PORT4_SGMII (BIT(5) | GENMASK(2, 0))
|
||||
+#define QCA8084_WORK_MODE_SWITCH BIT(4)
|
||||
+#define QCA8084_WORK_MODE_SWITCH_PORT4_SGMII BIT(5)
|
||||
+
|
||||
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
|
||||
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -165,6 +173,7 @@ struct qca808x_priv {
|
||||
};
|
||||
|
||||
struct qca808x_shared_priv {
|
||||
+ int package_mode;
|
||||
struct clk *clk[PACKAGE_CLK_MAX];
|
||||
};
|
||||
|
||||
@@ -808,10 +817,107 @@ static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
|
||||
active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
|
||||
}
|
||||
|
||||
+static int qca8084_package_clock_init(struct qca808x_shared_priv *shared_priv)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Configure clock rate 312.5MHZ for the PHY package
|
||||
+ * APB bridge clock tree.
|
||||
+ */
|
||||
+ ret = clk_set_rate(shared_priv->clk[APB_BRIDGE_CLK], 312500000);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(shared_priv->clk[APB_BRIDGE_CLK]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Configure clock rate 104.17MHZ for the PHY package
|
||||
+ * AHB clock tree.
|
||||
+ */
|
||||
+ ret = clk_set_rate(shared_priv->clk[AHB_CLK], 104170000);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(shared_priv->clk[AHB_CLK]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(shared_priv->clk[SEC_CTRL_AHB_CLK]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(shared_priv->clk[TLMM_CLK]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(shared_priv->clk[TLMM_AHB_CLK]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(shared_priv->clk[CNOC_AHB_CLK]);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return clk_prepare_enable(shared_priv->clk[MDIO_AHB_CLK]);
|
||||
+}
|
||||
+
|
||||
+static int qca8084_phy_package_config_init_once(struct phy_device *phydev)
|
||||
+{
|
||||
+ struct phy_package_shared *shared = phydev->shared;
|
||||
+ struct qca808x_shared_priv *shared_priv;
|
||||
+ int ret, mode;
|
||||
+
|
||||
+ shared_priv = shared->priv;
|
||||
+ switch (shared_priv->package_mode) {
|
||||
+ case QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED:
|
||||
+ mode = QCA8084_WORK_MODE_QXGMII;
|
||||
+ break;
|
||||
+ case QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_MAC:
|
||||
+ mode = QCA8084_WORK_MODE_SWITCH;
|
||||
+ break;
|
||||
+ case QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_PHY:
|
||||
+ mode = QCA8084_WORK_MODE_SWITCH_PORT4_SGMII;
|
||||
+ break;
|
||||
+ default:
|
||||
+ phydev_err(phydev, "Invalid qcom,package-mode %d\n",
|
||||
+ shared_priv->package_mode);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = qca8084_mii_modify(phydev, QCA8084_WORK_MODE_CFG,
|
||||
+ QCA8084_WORK_MODE_MASK,
|
||||
+ FIELD_PREP(QCA8084_WORK_MODE_MASK, mode));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Initialize the PHY package clock and reset, which is the
|
||||
+ * necessary config sequence after GPIO reset on the PHY package.
|
||||
+ */
|
||||
+ ret = qca8084_package_clock_init(shared_priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Enable efuse loading into analog circuit */
|
||||
+ ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG,
|
||||
+ QCA8084_EPHY_LDO_EN, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ usleep_range(10000, 11000);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int qca8084_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
+ if (phy_package_init_once(phydev)) {
|
||||
+ ret = qca8084_phy_package_config_init_once(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
__set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
|
||||
phydev->possible_interfaces);
|
||||
@@ -948,6 +1054,15 @@ static int qca8084_phy_package_probe_once(struct phy_device *phydev)
|
||||
return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
|
||||
"package reset not ready\n");
|
||||
|
||||
+ /* The package mode 10G-QXGMII of PCS1 is used for Quad PHY and
|
||||
+ * PCS0 is unused by default.
|
||||
+ */
|
||||
+ shared_priv->package_mode = QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED;
|
||||
+ ret = of_property_read_u32(shared->np, "qcom,package-mode",
|
||||
+ &shared_priv->package_mode);
|
||||
+ if (ret && ret != -EINVAL)
|
||||
+ return ret;
|
||||
+
|
||||
/* Deassert PHY package. */
|
||||
return reset_control_deassert(rstc);
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,125 @@
|
||||
From f23eb497c891985126a065f950bc61e9c404bb12 Mon Sep 17 00:00:00 2001
|
||||
From: Lei Wei <quic_leiwei@quicinc.com>
|
||||
Date: Wed, 6 Mar 2024 17:40:52 +0800
|
||||
Subject: [PATCH 12/50] net: pcs: Add 10GBASER interface mode support to IPQ
|
||||
UNIPHY PCS driver
|
||||
|
||||
10GBASER mode is used when PCS connects with a 10G SFP module.
|
||||
|
||||
Change-Id: Ifc3c3bb23811807a9b34e88771aab2c830c2327c
|
||||
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
|
||||
---
|
||||
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 48 +++++++++++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
index 837de629d0b2..68a1715531ef 100644
|
||||
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
@@ -57,6 +57,9 @@
|
||||
FIELD_PREP(GENMASK(9, 2), \
|
||||
FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
|
||||
|
||||
+#define XPCS_10GBASER_STS 0x30020
|
||||
+#define XPCS_10GBASER_LINK_STS BIT(12)
|
||||
+
|
||||
#define XPCS_DIG_CTRL 0x38000
|
||||
#define XPCS_USXG_ADPT_RESET BIT(10)
|
||||
#define XPCS_USXG_EN BIT(9)
|
||||
@@ -320,6 +323,23 @@ static void ipq_unipcs_get_state_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
state->duplex = DUPLEX_HALF;
|
||||
}
|
||||
|
||||
+static void ipq_unipcs_get_state_10gbaser(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ipq_unipcs_reg_read32(qunipcs, XPCS_10GBASER_STS);
|
||||
+
|
||||
+ state->link = !!(val & XPCS_10GBASER_LINK_STS);
|
||||
+
|
||||
+ if (!state->link)
|
||||
+ return;
|
||||
+
|
||||
+ state->speed = SPEED_10000;
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
||||
+}
|
||||
+
|
||||
static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -354,6 +374,7 @@ static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
|
||||
PCS_MODE_PSGMII);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
rate = 312500000;
|
||||
ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
|
||||
PCS_MODE_SEL_MASK,
|
||||
@@ -461,6 +482,25 @@ static int ipq_unipcs_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ipq_unipcs_config_10gbaser(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (qunipcs->interface != interface) {
|
||||
+ ret = ipq_unipcs_config_mode(qunipcs, interface);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Deassert XPCS */
|
||||
+ reset_control_deassert(qunipcs->reset[XPCS_RESET]);
|
||||
+
|
||||
+ qunipcs->interface = interface;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static unsigned long ipq_unipcs_clock_rate_get_gmii(int speed)
|
||||
{
|
||||
unsigned long rate = 0;
|
||||
@@ -527,6 +567,7 @@ ipq_unipcs_link_up_clock_rate_set(struct ipq_uniphy_pcs_ch *qunipcs_ch,
|
||||
rate = ipq_unipcs_clock_rate_get_gmii(speed);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
rate = ipq_unipcs_clock_rate_get_xgmii(speed);
|
||||
break;
|
||||
default:
|
||||
@@ -644,6 +685,9 @@ static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
ipq_unipcs_get_state_usxgmii(qunipcs, state);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ ipq_unipcs_get_state_10gbaser(qunipcs, state);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -675,6 +719,8 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
return ipq_unipcs_config_usxgmii(qunipcs,
|
||||
neg_mode, interface);
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ return ipq_unipcs_config_10gbaser(qunipcs, interface);
|
||||
default:
|
||||
dev_err(qunipcs->dev,
|
||||
"interface %s not supported\n", phy_modes(interface));
|
||||
@@ -705,6 +751,8 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
ipq_unipcs_link_up_config_usxgmii(qunipcs, speed);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ break;
|
||||
default:
|
||||
dev_err(qunipcs->dev,
|
||||
"interface %s not supported\n", phy_modes(interface));
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,203 @@
|
||||
From fcd1c53b460aa39cfd15f842126af62b27a4fad5 Mon Sep 17 00:00:00 2001
|
||||
From: Lei Wei <quic_leiwei@quicinc.com>
|
||||
Date: Tue, 2 Apr 2024 18:28:42 +0800
|
||||
Subject: [PATCH 13/50] net: pcs: Add 2500BASEX interface mode support to IPQ
|
||||
UNIPHY PCS driver
|
||||
|
||||
2500BASEX mode is used when PCS connects with QCA8386 switch in a fixed
|
||||
2500M link. It is also used when PCS connectes with QCA8081 PHY which
|
||||
works at 2500M link speed. In addition, it can be also used when PCS
|
||||
connects with a 2.5G SFP module.
|
||||
|
||||
Change-Id: I3fe61113c1b3685debc20659736a9488216a029d
|
||||
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
|
||||
---
|
||||
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 95 +++++++++++++++++++++++++++
|
||||
1 file changed, 95 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
index 68a1715531ef..ed9c55a6c0fa 100644
|
||||
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#define PCS_MODE_SGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
|
||||
#define PCS_MODE_QSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
|
||||
#define PCS_MODE_PSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
|
||||
+#define PCS_MODE_SGMII_PLUS FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
|
||||
#define PCS_MODE_XPCS FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
|
||||
#define PCS_MODE_AN_MODE BIT(0)
|
||||
|
||||
@@ -282,6 +283,24 @@ static void ipq_unipcs_get_state_sgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
state->pause |= MLO_PAUSE_RX;
|
||||
}
|
||||
|
||||
+static void ipq_unipcs_get_state_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ int channel,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ipq_unipcs_reg_read32(qunipcs, PCS_CHANNEL_STS(channel));
|
||||
+
|
||||
+ state->link = !!(val & PCS_CHANNEL_LINK_STS);
|
||||
+
|
||||
+ if (!state->link)
|
||||
+ return;
|
||||
+
|
||||
+ state->speed = SPEED_2500;
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
||||
+}
|
||||
+
|
||||
static void ipq_unipcs_get_state_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
@@ -373,6 +392,12 @@ static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
|
||||
PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
|
||||
PCS_MODE_PSGMII);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ rate = 312500000;
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
|
||||
+ PCS_MODE_SEL_MASK,
|
||||
+ PCS_MODE_SGMII_PLUS);
|
||||
+ break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
rate = 312500000;
|
||||
@@ -450,6 +475,22 @@ static int ipq_unipcs_config_sgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ipq_unipcs_config_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ if (qunipcs->interface != interface) {
|
||||
+ ret = ipq_unipcs_config_mode(qunipcs, interface);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ qunipcs->interface = interface;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ipq_unipcs_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
unsigned int neg_mode,
|
||||
phy_interface_t interface)
|
||||
@@ -522,6 +563,21 @@ static unsigned long ipq_unipcs_clock_rate_get_gmii(int speed)
|
||||
return rate;
|
||||
}
|
||||
|
||||
+static unsigned long ipq_unipcs_clock_rate_get_gmiiplus(int speed)
|
||||
+{
|
||||
+ unsigned long rate = 0;
|
||||
+
|
||||
+ switch (speed) {
|
||||
+ case SPEED_2500:
|
||||
+ rate = 312500000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return rate;
|
||||
+}
|
||||
+
|
||||
static unsigned long ipq_unipcs_clock_rate_get_xgmii(int speed)
|
||||
{
|
||||
unsigned long rate = 0;
|
||||
@@ -566,6 +622,9 @@ ipq_unipcs_link_up_clock_rate_set(struct ipq_uniphy_pcs_ch *qunipcs_ch,
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
rate = ipq_unipcs_clock_rate_get_gmii(speed);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ rate = ipq_unipcs_clock_rate_get_gmiiplus(speed);
|
||||
+ break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
rate = ipq_unipcs_clock_rate_get_xgmii(speed);
|
||||
@@ -627,6 +686,21 @@ static void ipq_unipcs_link_up_config_sgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
PCS_CHANNEL_ADPT_RESET);
|
||||
}
|
||||
|
||||
+static void ipq_unipcs_link_up_config_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ int channel,
|
||||
+ int speed)
|
||||
+{
|
||||
+ /* 2500BASEX do not support autoneg and do not need to
|
||||
+ * configure PCS speed, only reset PCS adapter here.
|
||||
+ */
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, PCS_CHANNEL_CTRL(channel),
|
||||
+ PCS_CHANNEL_ADPT_RESET,
|
||||
+ 0);
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, PCS_CHANNEL_CTRL(channel),
|
||||
+ PCS_CHANNEL_ADPT_RESET,
|
||||
+ PCS_CHANNEL_ADPT_RESET);
|
||||
+}
|
||||
+
|
||||
static void ipq_unipcs_link_up_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
int speed)
|
||||
{
|
||||
@@ -669,6 +743,17 @@ static void ipq_unipcs_link_up_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
XPCS_USXG_ADPT_RESET);
|
||||
}
|
||||
|
||||
+static int ipq_unipcs_validate(struct phylink_pcs *pcs,
|
||||
+ unsigned long *supported,
|
||||
+ const struct phylink_link_state *state)
|
||||
+{
|
||||
+ /* In-band autoneg is not supported for 2500BASEX */
|
||||
+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
+ phylink_clear(supported, Autoneg);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
@@ -682,6 +767,9 @@ static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
ipq_unipcs_get_state_sgmii(qunipcs, channel, state);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ ipq_unipcs_get_state_2500basex(qunipcs, channel, state);
|
||||
+ break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
ipq_unipcs_get_state_usxgmii(qunipcs, state);
|
||||
break;
|
||||
@@ -716,6 +804,8 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
return ipq_unipcs_config_sgmii(qunipcs, channel,
|
||||
neg_mode, interface);
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return ipq_unipcs_config_2500basex(qunipcs, interface);
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
return ipq_unipcs_config_usxgmii(qunipcs,
|
||||
neg_mode, interface);
|
||||
@@ -748,6 +838,10 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
|
||||
ipq_unipcs_link_up_config_sgmii(qunipcs, channel,
|
||||
neg_mode, speed);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ ipq_unipcs_link_up_config_2500basex(qunipcs,
|
||||
+ channel, speed);
|
||||
+ break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
ipq_unipcs_link_up_config_usxgmii(qunipcs, speed);
|
||||
break;
|
||||
@@ -761,6 +855,7 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
|
||||
}
|
||||
|
||||
static const struct phylink_pcs_ops ipq_unipcs_phylink_ops = {
|
||||
+ .pcs_validate = ipq_unipcs_validate,
|
||||
.pcs_get_state = ipq_unipcs_get_state,
|
||||
.pcs_config = ipq_unipcs_config,
|
||||
.pcs_link_up = ipq_unipcs_link_up,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,100 @@
|
||||
From 23f3550c387246025ed2971989b747a5936bf080 Mon Sep 17 00:00:00 2001
|
||||
From: Lei Wei <quic_leiwei@quicinc.com>
|
||||
Date: Tue, 9 Apr 2024 01:07:22 +0800
|
||||
Subject: [PATCH 14/50] net:pcs: Add 1000BASEX interface mode support to IPQ
|
||||
UNIPHY PCS driver
|
||||
|
||||
1000BASEX is used when PCS connects with a 1G SFP module.
|
||||
|
||||
Change-Id: Ied7298de3c1ecba74e6457a07fdd6b3ceab79728
|
||||
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
|
||||
---
|
||||
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
index ed9c55a6c0fa..820d197744e8 100644
|
||||
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
@@ -27,6 +27,9 @@
|
||||
#define PCS_MODE_PSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x2)
|
||||
#define PCS_MODE_SGMII_PLUS FIELD_PREP(PCS_MODE_SEL_MASK, 0x8)
|
||||
#define PCS_MODE_XPCS FIELD_PREP(PCS_MODE_SEL_MASK, 0x10)
|
||||
+#define PCS_MODE_SGMII_CTRL_MASK GENMASK(6, 4)
|
||||
+#define PCS_MODE_SGMII_CTRL_1000BASEX FIELD_PREP(PCS_MODE_SGMII_CTRL_MASK, \
|
||||
+ 0x0)
|
||||
#define PCS_MODE_AN_MODE BIT(0)
|
||||
|
||||
#define PCS_CHANNEL_CTRL(x) (0x480 + 0x18 * (x))
|
||||
@@ -392,6 +395,13 @@ static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
|
||||
PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
|
||||
PCS_MODE_PSGMII);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
|
||||
+ PCS_MODE_SEL_MASK |
|
||||
+ PCS_MODE_SGMII_CTRL_MASK,
|
||||
+ PCS_MODE_SGMII |
|
||||
+ PCS_MODE_SGMII_CTRL_1000BASEX);
|
||||
+ break;
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
rate = 312500000;
|
||||
ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
|
||||
@@ -620,6 +630,7 @@ ipq_unipcs_link_up_clock_rate_set(struct ipq_uniphy_pcs_ch *qunipcs_ch,
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
rate = ipq_unipcs_clock_rate_get_gmii(speed);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
@@ -765,6 +776,10 @@ static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ /* SGMII and 1000BASEX in-band autoneg word format are decoded
|
||||
+ * by PCS hardware and both placed to the same status register.
|
||||
+ */
|
||||
ipq_unipcs_get_state_sgmii(qunipcs, channel, state);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
@@ -802,6 +817,7 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
return ipq_unipcs_config_sgmii(qunipcs, channel,
|
||||
neg_mode, interface);
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
@@ -818,6 +834,11 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
|
||||
};
|
||||
}
|
||||
|
||||
+static void qcom_ipq_unipcs_an_restart(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ /* Currently not used */
|
||||
+}
|
||||
+
|
||||
static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
|
||||
unsigned int neg_mode,
|
||||
phy_interface_t interface,
|
||||
@@ -835,6 +856,7 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_QSGMII:
|
||||
case PHY_INTERFACE_MODE_PSGMII:
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
ipq_unipcs_link_up_config_sgmii(qunipcs, channel,
|
||||
neg_mode, speed);
|
||||
break;
|
||||
@@ -858,6 +880,7 @@ static const struct phylink_pcs_ops ipq_unipcs_phylink_ops = {
|
||||
.pcs_validate = ipq_unipcs_validate,
|
||||
.pcs_get_state = ipq_unipcs_get_state,
|
||||
.pcs_config = ipq_unipcs_config,
|
||||
+ .pcs_an_restart = qcom_ipq_unipcs_an_restart,
|
||||
.pcs_link_up = ipq_unipcs_link_up,
|
||||
};
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,364 @@
|
||||
From d96ec0527b0f5618b3a0757b47606705555ee996 Mon Sep 17 00:00:00 2001
|
||||
From: Lei Wei <quic_leiwei@quicinc.com>
|
||||
Date: Mon, 15 Apr 2024 11:06:02 +0800
|
||||
Subject: [PATCH 15/50] net:pcs: Add 10G_QXGMII interface mode support to IPQ
|
||||
UNIPHY PCS driver
|
||||
|
||||
10G_QXGMII is used when PCS connectes with QCA8084 four ports
|
||||
2.5G PHYs.
|
||||
|
||||
Change-Id: If3dc92a07ac3e51f7c9473fb05fa0668617916fb
|
||||
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
|
||||
---
|
||||
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 174 +++++++++++++++++++++-----
|
||||
1 file changed, 142 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
index 820d197744e8..a98180c91632 100644
|
||||
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
||||
@@ -50,6 +50,9 @@
|
||||
#define PCS_CHANNEL_STS_PAUSE_TX_EN BIT(1)
|
||||
#define PCS_CHANNEL_STS_PAUSE_RX_EN BIT(0)
|
||||
|
||||
+#define PCS_QP_USXG_OPTION 0x584
|
||||
+#define PCS_QP_USXG_GMII_SRC_XPCS BIT(0)
|
||||
+
|
||||
#define PCS_PLL_RESET 0x780
|
||||
#define PCS_ANA_SW_RESET BIT(6)
|
||||
|
||||
@@ -65,10 +68,22 @@
|
||||
#define XPCS_10GBASER_LINK_STS BIT(12)
|
||||
|
||||
#define XPCS_DIG_CTRL 0x38000
|
||||
+#define XPCS_SOFT_RESET BIT(15)
|
||||
#define XPCS_USXG_ADPT_RESET BIT(10)
|
||||
#define XPCS_USXG_EN BIT(9)
|
||||
|
||||
+#define XPCS_KR_CTRL 0x38007
|
||||
+#define XPCS_USXG_MODE_MASK GENMASK(12, 10)
|
||||
+#define XPCS_10G_QXGMII_MODE FIELD_PREP(XPCS_USXG_MODE_MASK, 0x5)
|
||||
+
|
||||
+#define XPCS_DIG_STS 0x3800a
|
||||
+#define XPCS_DIG_STS_AM_COUNT GENMASK(14, 0)
|
||||
+
|
||||
+#define XPCS_CHANNEL_DIG_CTRL(x) (0x1a8000 + 0x10000 * ((x) - 1))
|
||||
+#define XPCS_CHANNEL_USXG_ADPT_RESET BIT(5)
|
||||
+
|
||||
#define XPCS_MII_CTRL 0x1f0000
|
||||
+#define XPCS_CHANNEL_MII_CTRL(x) (0x1a0000 + 0x10000 * ((x) - 1))
|
||||
#define XPCS_MII_AN_EN BIT(12)
|
||||
#define XPCS_DUPLEX_FULL BIT(8)
|
||||
#define XPCS_SPEED_MASK (BIT(13) | BIT(6) | BIT(5))
|
||||
@@ -80,9 +95,11 @@
|
||||
#define XPCS_SPEED_10 0
|
||||
|
||||
#define XPCS_MII_AN_CTRL 0x1f8001
|
||||
+#define XPCS_CHANNEL_MII_AN_CTRL(x) (0x1a8001 + 0x10000 * ((x) - 1))
|
||||
#define XPCS_MII_AN_8BIT BIT(8)
|
||||
|
||||
#define XPCS_MII_AN_INTR_STS 0x1f8002
|
||||
+#define XPCS_CHANNEL_MII_AN_INTR_STS(x) (0x1a8002 + 0x10000 * ((x) - 1))
|
||||
#define XPCS_USXG_AN_LINK_STS BIT(14)
|
||||
#define XPCS_USXG_AN_DUPLEX_FULL BIT(13)
|
||||
#define XPCS_USXG_AN_SPEED_MASK GENMASK(12, 10)
|
||||
@@ -93,6 +110,10 @@
|
||||
#define XPCS_USXG_AN_SPEED_5000 5
|
||||
#define XPCS_USXG_AN_SPEED_10000 3
|
||||
|
||||
+#define XPCS_XAUI_MODE_CTRL 0x1f8004
|
||||
+#define XPCS_CHANNEL_XAUI_MODE_CTRL(x) (0x1a8004 + 0x10000 * ((x) - 1))
|
||||
+#define XPCS_TX_IPG_CHECK_DIS BIT(0)
|
||||
+
|
||||
/* UNIPHY PCS RAW clock ID */
|
||||
enum {
|
||||
PCS_RAW_RX_CLK = 0,
|
||||
@@ -153,6 +174,7 @@ struct ipq_uniphy_pcs {
|
||||
struct device *dev;
|
||||
phy_interface_t interface;
|
||||
struct mutex shared_lock; /* Lock to protect shared config */
|
||||
+ spinlock_t reg_lock; /* Lock for register access */
|
||||
struct clk *clk[PCS_CLK_MAX];
|
||||
struct reset_control *reset[PCS_RESET_MAX];
|
||||
struct ipq_unipcs_raw_clk raw_clk[PCS_RAW_CLK_MAX];
|
||||
@@ -215,39 +237,55 @@ static const struct clk_ops ipq_unipcs_raw_clk_ops = {
|
||||
|
||||
static u32 ipq_unipcs_reg_read32(struct ipq_uniphy_pcs *qunipcs, u32 reg)
|
||||
{
|
||||
+ u32 val;
|
||||
+
|
||||
/* PCS use direct AHB access while XPCS use indirect AHB access */
|
||||
if (reg >= XPCS_INDIRECT_ADDR) {
|
||||
+ /* For XPCS, althrough the register is different for different
|
||||
+ * channels, but they use the same indirect AHB address to
|
||||
+ * access, so add protects here.
|
||||
+ */
|
||||
+ spin_lock(&qunipcs->reg_lock);
|
||||
+
|
||||
writel(FIELD_GET(XPCS_INDIRECT_ADDR_H, reg),
|
||||
qunipcs->base + XPCS_INDIRECT_AHB_ADDR);
|
||||
- return readl(qunipcs->base + XPCS_INDIRECT_DATA_ADDR(reg));
|
||||
+ val = readl(qunipcs->base + XPCS_INDIRECT_DATA_ADDR(reg));
|
||||
+
|
||||
+ spin_unlock(&qunipcs->reg_lock);
|
||||
+ return val;
|
||||
} else {
|
||||
return readl(qunipcs->base + reg);
|
||||
}
|
||||
}
|
||||
|
||||
-static void ipq_unipcs_reg_write32(struct ipq_uniphy_pcs *qunipcs,
|
||||
- u32 reg, u32 val)
|
||||
+static void ipq_unipcs_reg_modify32(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
+ u32 val;
|
||||
+
|
||||
if (reg >= XPCS_INDIRECT_ADDR) {
|
||||
+ spin_lock(&qunipcs->reg_lock);
|
||||
+
|
||||
+ /* XPCS read */
|
||||
writel(FIELD_GET(XPCS_INDIRECT_ADDR_H, reg),
|
||||
qunipcs->base + XPCS_INDIRECT_AHB_ADDR);
|
||||
+ val = readl(qunipcs->base + XPCS_INDIRECT_DATA_ADDR(reg));
|
||||
+
|
||||
+ val &= ~mask;
|
||||
+ val |= set;
|
||||
+
|
||||
+ /* XPCS write */
|
||||
writel(val, qunipcs->base + XPCS_INDIRECT_DATA_ADDR(reg));
|
||||
+
|
||||
+ spin_unlock(&qunipcs->reg_lock);
|
||||
} else {
|
||||
+ val = readl(qunipcs->base + reg);
|
||||
+ val &= ~mask;
|
||||
+ val |= set;
|
||||
writel(val, qunipcs->base + reg);
|
||||
}
|
||||
}
|
||||
|
||||
-static void ipq_unipcs_reg_modify32(struct ipq_uniphy_pcs *qunipcs,
|
||||
- u32 reg, u32 mask, u32 set)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- val = ipq_unipcs_reg_read32(qunipcs, reg);
|
||||
- val &= ~mask;
|
||||
- val |= set;
|
||||
- ipq_unipcs_reg_write32(qunipcs, reg, val);
|
||||
-}
|
||||
-
|
||||
static void ipq_unipcs_get_state_sgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
int channel,
|
||||
struct phylink_link_state *state)
|
||||
@@ -305,11 +343,15 @@ static void ipq_unipcs_get_state_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
||||
}
|
||||
|
||||
static void ipq_unipcs_get_state_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ int channel,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
- u32 val;
|
||||
+ u32 val, reg;
|
||||
+
|
||||
+ reg = (channel == 0) ? XPCS_MII_AN_INTR_STS :
|
||||
+ XPCS_CHANNEL_MII_AN_INTR_STS(channel);
|
||||
|
||||
- val = ipq_unipcs_reg_read32(qunipcs, XPCS_MII_AN_INTR_STS);
|
||||
+ val = ipq_unipcs_reg_read32(qunipcs, reg);
|
||||
|
||||
state->link = !!(val & XPCS_USXG_AN_LINK_STS);
|
||||
|
||||
@@ -415,6 +457,15 @@ static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
|
||||
PCS_MODE_SEL_MASK,
|
||||
PCS_MODE_XPCS);
|
||||
break;
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
+ rate = 312500000;
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
|
||||
+ PCS_MODE_SEL_MASK,
|
||||
+ PCS_MODE_XPCS);
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, PCS_QP_USXG_OPTION,
|
||||
+ PCS_QP_USXG_GMII_SRC_XPCS,
|
||||
+ PCS_QP_USXG_GMII_SRC_XPCS);
|
||||
+ break;
|
||||
default:
|
||||
dev_err(qunipcs->dev,
|
||||
"interface %s not supported\n", phy_modes(interface));
|
||||
@@ -502,35 +553,82 @@ static int ipq_unipcs_config_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
||||
}
|
||||
|
||||
static int ipq_unipcs_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ int channel,
|
||||
unsigned int neg_mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
int ret;
|
||||
+ u32 reg;
|
||||
+
|
||||
+ /* Only in-band autoneg mode is supported currently */
|
||||
+ if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
+ mutex_lock(&qunipcs->shared_lock);
|
||||
|
||||
if (qunipcs->interface != interface) {
|
||||
ret = ipq_unipcs_config_mode(qunipcs, interface);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto err;
|
||||
|
||||
- /* Deassert XPCS and configure XPCS USXGMII */
|
||||
+ /* Deassert XPCS and configure XPCS USXGMII or 10G_QXGMII */
|
||||
reset_control_deassert(qunipcs->reset[XPCS_RESET]);
|
||||
|
||||
ipq_unipcs_reg_modify32(qunipcs, XPCS_DIG_CTRL,
|
||||
XPCS_USXG_EN, XPCS_USXG_EN);
|
||||
|
||||
- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
|
||||
- ipq_unipcs_reg_modify32(qunipcs, XPCS_MII_AN_CTRL,
|
||||
- XPCS_MII_AN_8BIT,
|
||||
- XPCS_MII_AN_8BIT);
|
||||
+ if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, XPCS_KR_CTRL,
|
||||
+ XPCS_USXG_MODE_MASK,
|
||||
+ XPCS_10G_QXGMII_MODE);
|
||||
+
|
||||
+ /* Set Alignment Marker Interval */
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, XPCS_DIG_STS,
|
||||
+ XPCS_DIG_STS_AM_COUNT,
|
||||
+ 0x6018);
|
||||
|
||||
- ipq_unipcs_reg_modify32(qunipcs, XPCS_MII_CTRL,
|
||||
- XPCS_MII_AN_EN, XPCS_MII_AN_EN);
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, XPCS_DIG_CTRL,
|
||||
+ XPCS_SOFT_RESET,
|
||||
+ XPCS_SOFT_RESET);
|
||||
}
|
||||
|
||||
qunipcs->interface = interface;
|
||||
}
|
||||
|
||||
+ if (interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
+ mutex_unlock(&qunipcs->shared_lock);
|
||||
+
|
||||
+ /* Disable Tx IPG check for 10G_QXGMII */
|
||||
+ if (interface == PHY_INTERFACE_MODE_10G_QXGMII) {
|
||||
+ reg = (channel == 0) ? XPCS_XAUI_MODE_CTRL :
|
||||
+ XPCS_CHANNEL_XAUI_MODE_CTRL(channel);
|
||||
+
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, reg,
|
||||
+ XPCS_TX_IPG_CHECK_DIS,
|
||||
+ XPCS_TX_IPG_CHECK_DIS);
|
||||
+ }
|
||||
+
|
||||
+ /* Enable autoneg */
|
||||
+ reg = (channel == 0) ? XPCS_MII_AN_CTRL :
|
||||
+ XPCS_CHANNEL_MII_AN_CTRL(channel);
|
||||
+
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, reg,
|
||||
+ XPCS_MII_AN_8BIT, XPCS_MII_AN_8BIT);
|
||||
+
|
||||
+ reg = (channel == 0) ? XPCS_MII_CTRL :
|
||||
+ XPCS_CHANNEL_MII_CTRL(channel);
|
||||
+
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, reg,
|
||||
+ XPCS_MII_AN_EN, XPCS_MII_AN_EN);
|
||||
+
|
||||
return 0;
|
||||
+
|
||||
+err:
|
||||
+ if (interface == PHY_INTERFACE_MODE_10G_QXGMII)
|
||||
+ mutex_unlock(&qunipcs->shared_lock);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int ipq_unipcs_config_10gbaser(struct ipq_uniphy_pcs *qunipcs,
|
||||
@@ -638,6 +736,7 @@ ipq_unipcs_link_up_clock_rate_set(struct ipq_uniphy_pcs_ch *qunipcs_ch,
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
rate = ipq_unipcs_clock_rate_get_xgmii(speed);
|
||||
break;
|
||||
default:
|
||||
@@ -713,9 +812,10 @@ static void ipq_unipcs_link_up_config_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
||||
}
|
||||
|
||||
static void ipq_unipcs_link_up_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
+ int channel,
|
||||
int speed)
|
||||
{
|
||||
- u32 val;
|
||||
+ u32 val, reg;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_10000:
|
||||
@@ -744,14 +844,20 @@ static void ipq_unipcs_link_up_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
||||
val |= XPCS_DUPLEX_FULL;
|
||||
|
||||
/* Config XPCS speed */
|
||||
- ipq_unipcs_reg_modify32(qunipcs, XPCS_MII_CTRL,
|
||||
+ reg = (channel == 0) ? XPCS_MII_CTRL : XPCS_CHANNEL_MII_CTRL(channel);
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, reg,
|
||||
XPCS_SPEED_MASK | XPCS_DUPLEX_FULL,
|
||||
val);
|
||||
|
||||
/* XPCS adapter reset */
|
||||
- ipq_unipcs_reg_modify32(qunipcs, XPCS_DIG_CTRL,
|
||||
- XPCS_USXG_ADPT_RESET,
|
||||
- XPCS_USXG_ADPT_RESET);
|
||||
+ if (channel == 0)
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, XPCS_DIG_CTRL,
|
||||
+ XPCS_USXG_ADPT_RESET,
|
||||
+ XPCS_USXG_ADPT_RESET);
|
||||
+ else
|
||||
+ ipq_unipcs_reg_modify32(qunipcs, XPCS_CHANNEL_DIG_CTRL(channel),
|
||||
+ XPCS_CHANNEL_USXG_ADPT_RESET,
|
||||
+ XPCS_CHANNEL_USXG_ADPT_RESET);
|
||||
}
|
||||
|
||||
static int ipq_unipcs_validate(struct phylink_pcs *pcs,
|
||||
@@ -786,7 +892,8 @@ static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
|
||||
ipq_unipcs_get_state_2500basex(qunipcs, channel, state);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
- ipq_unipcs_get_state_usxgmii(qunipcs, state);
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
+ ipq_unipcs_get_state_usxgmii(qunipcs, channel, state);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
ipq_unipcs_get_state_10gbaser(qunipcs, state);
|
||||
@@ -823,7 +930,8 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
return ipq_unipcs_config_2500basex(qunipcs, interface);
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
- return ipq_unipcs_config_usxgmii(qunipcs,
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
+ return ipq_unipcs_config_usxgmii(qunipcs, channel,
|
||||
neg_mode, interface);
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
return ipq_unipcs_config_10gbaser(qunipcs, interface);
|
||||
@@ -865,7 +973,8 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
|
||||
channel, speed);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
- ipq_unipcs_link_up_config_usxgmii(qunipcs, speed);
|
||||
+ case PHY_INTERFACE_MODE_10G_QXGMII:
|
||||
+ ipq_unipcs_link_up_config_usxgmii(qunipcs, channel, speed);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
break;
|
||||
@@ -1082,6 +1191,7 @@ static int ipq_uniphy_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
mutex_init(&priv->shared_lock);
|
||||
+ spin_lock_init(&priv->reg_lock);
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,363 @@
|
||||
From a29ee27a42fc208ef1cd99f5014d57dbfe1af3dd Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Tue, 26 Dec 2023 17:11:35 +0800
|
||||
Subject: [PATCH 18/50] net: ethernet: qualcomm: Add PPE driver for IPQ9574 SoC
|
||||
|
||||
The PPE (Packet Process Engine) hardware block is available
|
||||
on Qualcomm IPQ SoC that support PPE architecture, such as
|
||||
IPQ9574.
|
||||
|
||||
The PPE in IPQ9574 includes six integrated ethernet MAC
|
||||
(for 6 PPE ports), buffer management, queue management and
|
||||
scheduler functions. The MACs can connect with the external
|
||||
PHY or switch devices using the UNIPHY PCS block available
|
||||
in the SoC.
|
||||
|
||||
The PPE also includes various packet processing offload
|
||||
capabilities such as L3 routing and L2 bridging, VLAN and
|
||||
tunnel processing offload. It also includes Ethernet DMA (EDMA)
|
||||
function for transferring packets between ARM cores and PPE
|
||||
ethernet ports.
|
||||
|
||||
This patch adds the base source files and Makefiles for the PPE
|
||||
driver such as platform driver registration, clock initialization,
|
||||
and PPE reset routines.
|
||||
|
||||
Change-Id: I73166b5d4bb7e3c42ec6e0ac178a75528a25ef30
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/ethernet/qualcomm/Kconfig | 15 ++
|
||||
drivers/net/ethernet/qualcomm/Makefile | 1 +
|
||||
drivers/net/ethernet/qualcomm/ppe/Makefile | 7 +
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe.c | 225 +++++++++++++++++++++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe.h | 36 ++++
|
||||
5 files changed, 284 insertions(+)
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe.h
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/Kconfig b/drivers/net/ethernet/qualcomm/Kconfig
|
||||
index 9210ff360fdc..8cc24da48777 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/Kconfig
|
||||
+++ b/drivers/net/ethernet/qualcomm/Kconfig
|
||||
@@ -61,6 +61,21 @@ config QCOM_EMAC
|
||||
low power, Receive-Side Scaling (RSS), and IEEE 1588-2008
|
||||
Precision Clock Synchronization Protocol.
|
||||
|
||||
+config QCOM_PPE
|
||||
+ tristate "Qualcomm Technologies, Inc. PPE Ethernet support"
|
||||
+ depends on HAS_IOMEM && OF
|
||||
+ depends on COMMON_CLK
|
||||
+ select REGMAP_MMIO
|
||||
+ help
|
||||
+ This driver supports the Qualcomm Technologies, Inc. packet
|
||||
+ process engine (PPE) available with IPQ SoC. The PPE houses
|
||||
+ the ethernet MACs, Ethernet DMA (EDMA) and switch core that
|
||||
+ supports L3 flow offload, L2 switch function, RSS and tunnel
|
||||
+ offload.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here. The module
|
||||
+ will be called qcom-ppe.
|
||||
+
|
||||
source "drivers/net/ethernet/qualcomm/rmnet/Kconfig"
|
||||
|
||||
endif # NET_VENDOR_QUALCOMM
|
||||
diff --git a/drivers/net/ethernet/qualcomm/Makefile b/drivers/net/ethernet/qualcomm/Makefile
|
||||
index 9250976dd884..166a59aea363 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/Makefile
|
||||
+++ b/drivers/net/ethernet/qualcomm/Makefile
|
||||
@@ -11,4 +11,5 @@ qcauart-objs := qca_uart.o
|
||||
|
||||
obj-y += emac/
|
||||
|
||||
+obj-$(CONFIG_QCOM_PPE) += ppe/
|
||||
obj-$(CONFIG_RMNET) += rmnet/
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
new file mode 100644
|
||||
index 000000000000..63d50d3b4f2e
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
@@ -0,0 +1,7 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+#
|
||||
+# Makefile for the device driver of PPE (Packet Process Engine) in IPQ SoC
|
||||
+#
|
||||
+
|
||||
+obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
|
||||
+qcom-ppe-objs := ppe.o
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
new file mode 100644
|
||||
index 000000000000..14998ac771c7
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
@@ -0,0 +1,225 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/* PPE platform device probe, DTSI parser and PPE clock initializations. */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/interconnect.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#include "ppe.h"
|
||||
+
|
||||
+#define PPE_PORT_MAX 8
|
||||
+#define PPE_CLK_RATE 353000000
|
||||
+
|
||||
+/* ICC clocks for enabling PPE device. The avg and peak with value 0
|
||||
+ * will be decided by the clock rate of PPE.
|
||||
+ */
|
||||
+static const struct icc_bulk_data ppe_icc_data[] = {
|
||||
+ {
|
||||
+ .name = "ppe",
|
||||
+ .avg_bw = 0,
|
||||
+ .peak_bw = 0,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "ppe_cfg",
|
||||
+ .avg_bw = 0,
|
||||
+ .peak_bw = 0,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "qos_gen",
|
||||
+ .avg_bw = 6000,
|
||||
+ .peak_bw = 6000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "timeout_ref",
|
||||
+ .avg_bw = 6000,
|
||||
+ .peak_bw = 6000,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "nssnoc_memnoc",
|
||||
+ .avg_bw = 533333,
|
||||
+ .peak_bw = 533333,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "memnoc_nssnoc",
|
||||
+ .avg_bw = 533333,
|
||||
+ .peak_bw = 533333,
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "memnoc_nssnoc_1",
|
||||
+ .avg_bw = 533333,
|
||||
+ .peak_bw = 533333,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_range ppe_readable_ranges[] = {
|
||||
+ regmap_reg_range(0x0, 0x1ff), /* Global */
|
||||
+ regmap_reg_range(0x400, 0x5ff), /* LPI CSR */
|
||||
+ regmap_reg_range(0x1000, 0x11ff), /* GMAC0 */
|
||||
+ regmap_reg_range(0x1200, 0x13ff), /* GMAC1 */
|
||||
+ regmap_reg_range(0x1400, 0x15ff), /* GMAC2 */
|
||||
+ regmap_reg_range(0x1600, 0x17ff), /* GMAC3 */
|
||||
+ regmap_reg_range(0x1800, 0x19ff), /* GMAC4 */
|
||||
+ regmap_reg_range(0x1a00, 0x1bff), /* GMAC5 */
|
||||
+ regmap_reg_range(0xb000, 0xefff), /* PRX CSR */
|
||||
+ regmap_reg_range(0xf000, 0x1efff), /* IPE */
|
||||
+ regmap_reg_range(0x20000, 0x5ffff), /* PTX CSR */
|
||||
+ regmap_reg_range(0x60000, 0x9ffff), /* IPE L2 CSR */
|
||||
+ regmap_reg_range(0xb0000, 0xeffff), /* IPO CSR */
|
||||
+ regmap_reg_range(0x100000, 0x17ffff), /* IPE PC */
|
||||
+ regmap_reg_range(0x180000, 0x1bffff), /* PRE IPO CSR */
|
||||
+ regmap_reg_range(0x1d0000, 0x1dffff), /* Tunnel parser */
|
||||
+ regmap_reg_range(0x1e0000, 0x1effff), /* Ingress parse */
|
||||
+ regmap_reg_range(0x200000, 0x2fffff), /* IPE L3 */
|
||||
+ regmap_reg_range(0x300000, 0x3fffff), /* IPE tunnel */
|
||||
+ regmap_reg_range(0x400000, 0x4fffff), /* Scheduler */
|
||||
+ regmap_reg_range(0x500000, 0x503fff), /* XGMAC0 */
|
||||
+ regmap_reg_range(0x504000, 0x507fff), /* XGMAC1 */
|
||||
+ regmap_reg_range(0x508000, 0x50bfff), /* XGMAC2 */
|
||||
+ regmap_reg_range(0x50c000, 0x50ffff), /* XGMAC3 */
|
||||
+ regmap_reg_range(0x510000, 0x513fff), /* XGMAC4 */
|
||||
+ regmap_reg_range(0x514000, 0x517fff), /* XGMAC5 */
|
||||
+ regmap_reg_range(0x600000, 0x6fffff), /* BM */
|
||||
+ regmap_reg_range(0x800000, 0x9fffff), /* QM */
|
||||
+ regmap_reg_range(0xb00000, 0xbef800), /* EDMA */
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_access_table ppe_reg_table = {
|
||||
+ .yes_ranges = ppe_readable_ranges,
|
||||
+ .n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges),
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config regmap_config_ipq9574 = {
|
||||
+ .reg_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+ .val_bits = 32,
|
||||
+ .rd_table = &ppe_reg_table,
|
||||
+ .wr_table = &ppe_reg_table,
|
||||
+ .max_register = 0xbef800,
|
||||
+ .fast_io = true,
|
||||
+};
|
||||
+
|
||||
+static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ unsigned long ppe_rate = ppe_dev->clk_rate;
|
||||
+ struct device *dev = ppe_dev->dev;
|
||||
+ struct reset_control *rstc;
|
||||
+ struct clk_bulk_data *clks;
|
||||
+ struct clk *clk;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ for (i = 0; i < ppe_dev->num_icc_paths; i++) {
|
||||
+ ppe_dev->icc_paths[i].name = ppe_icc_data[i].name;
|
||||
+ ppe_dev->icc_paths[i].avg_bw = ppe_icc_data[i].avg_bw ? :
|
||||
+ Bps_to_icc(ppe_rate);
|
||||
+ ppe_dev->icc_paths[i].peak_bw = ppe_icc_data[i].peak_bw ? :
|
||||
+ Bps_to_icc(ppe_rate);
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_of_icc_bulk_get(dev, ppe_dev->num_icc_paths,
|
||||
+ ppe_dev->icc_paths);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = icc_bulk_set_bw(ppe_dev->num_icc_paths, ppe_dev->icc_paths);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* PPE clocks take the same clock tree, which work on the same
|
||||
+ * clock rate. Setting the clock rate of "ppe" ensures the clock
|
||||
+ * rate of all PPE clocks configured as same.
|
||||
+ */
|
||||
+ clk = devm_clk_get(dev, "ppe");
|
||||
+ if (IS_ERR(clk))
|
||||
+ return PTR_ERR(clk);
|
||||
+
|
||||
+ ret = clk_set_rate(clk, ppe_rate);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_clk_bulk_get_all_enabled(dev, &clks);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ rstc = devm_reset_control_get_exclusive(dev, NULL);
|
||||
+ if (IS_ERR(rstc))
|
||||
+ return PTR_ERR(rstc);
|
||||
+
|
||||
+ /* Reset PPE, the delay 100ms of assert and deassert is necessary
|
||||
+ * for resetting PPE.
|
||||
+ */
|
||||
+ ret = reset_control_assert(rstc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ msleep(100);
|
||||
+ ret = reset_control_deassert(rstc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ msleep(100);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int qcom_ppe_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ppe_device *ppe_dev;
|
||||
+ void __iomem *base;
|
||||
+ int ret, num_icc;
|
||||
+
|
||||
+ num_icc = ARRAY_SIZE(ppe_icc_data);
|
||||
+ ppe_dev = devm_kzalloc(dev,
|
||||
+ struct_size(ppe_dev, icc_paths, num_icc),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!ppe_dev)
|
||||
+ return dev_err_probe(dev, -ENOMEM, "PPE alloc memory failed\n");
|
||||
+
|
||||
+ base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(base))
|
||||
+ return dev_err_probe(dev, PTR_ERR(base), "PPE ioremap failed\n");
|
||||
+
|
||||
+ ppe_dev->regmap = devm_regmap_init_mmio(dev, base, ®map_config_ipq9574);
|
||||
+ if (IS_ERR(ppe_dev->regmap))
|
||||
+ return dev_err_probe(dev, PTR_ERR(ppe_dev->regmap),
|
||||
+ "PPE initialize regmap failed\n");
|
||||
+ ppe_dev->dev = dev;
|
||||
+ ppe_dev->clk_rate = PPE_CLK_RATE;
|
||||
+ ppe_dev->num_ports = PPE_PORT_MAX;
|
||||
+ ppe_dev->num_icc_paths = num_icc;
|
||||
+
|
||||
+ ret = ppe_clock_init_and_reset(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "PPE clock config failed\n");
|
||||
+
|
||||
+ platform_set_drvdata(pdev, ppe_dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id qcom_ppe_of_match[] = {
|
||||
+ { .compatible = "qcom,ipq9574-ppe" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, qcom_ppe_of_match);
|
||||
+
|
||||
+static struct platform_driver qcom_ppe_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "qcom_ppe",
|
||||
+ .of_match_table = qcom_ppe_of_match,
|
||||
+ },
|
||||
+ .probe = qcom_ppe_probe,
|
||||
+};
|
||||
+module_platform_driver(qcom_ppe_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DESCRIPTION("Qualcomm IPQ PPE driver");
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h
|
||||
new file mode 100644
|
||||
index 000000000000..733d77f4063d
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __PPE_H__
|
||||
+#define __PPE_H__
|
||||
+
|
||||
+#include <linux/compiler.h>
|
||||
+#include <linux/interconnect.h>
|
||||
+
|
||||
+struct device;
|
||||
+struct regmap;
|
||||
+
|
||||
+/**
|
||||
+ * struct ppe_device - PPE device private data.
|
||||
+ * @dev: PPE device structure.
|
||||
+ * @regmap: PPE register map.
|
||||
+ * @clk_rate: PPE clock rate.
|
||||
+ * @num_ports: Number of PPE ports.
|
||||
+ * @num_icc_paths: Number of interconnect paths.
|
||||
+ * @icc_paths: Interconnect path array.
|
||||
+ *
|
||||
+ * PPE device is the instance of PPE hardware, which is used to
|
||||
+ * configure PPE packet process modules such as BM (buffer management),
|
||||
+ * QM (queue management), and scheduler.
|
||||
+ */
|
||||
+struct ppe_device {
|
||||
+ struct device *dev;
|
||||
+ struct regmap *regmap;
|
||||
+ unsigned long clk_rate;
|
||||
+ unsigned int num_ports;
|
||||
+ unsigned int num_icc_paths;
|
||||
+ struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
|
||||
+};
|
||||
+#endif
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,324 @@
|
||||
From 049820d8a0c918cedd4524eda9abf750819ac901 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Tue, 26 Dec 2023 18:19:30 +0800
|
||||
Subject: [PATCH 19/50] net: ethernet: qualcomm: Add PPE buffer manager
|
||||
configuration
|
||||
|
||||
The BM (Buffer Management) config controls the pause frame generated
|
||||
on the PPE port. There are maximum 15 BM ports and 4 groups supported,
|
||||
all BM ports are assigned to group 0 by default. The number of hardware
|
||||
buffers configured for the port influence the threshold of the flow
|
||||
control for that port.
|
||||
|
||||
Change-Id: Ifb1b69c89966cf5cab19f8e2661c64a4dc6230fe
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/ethernet/qualcomm/ppe/Makefile | 2 +-
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe.c | 5 +
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 181 ++++++++++++++++++
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.h | 10 +
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 54 ++++++
|
||||
5 files changed, 251 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
index 63d50d3b4f2e..410a7bb54cfe 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
@@ -4,4 +4,4 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
|
||||
-qcom-ppe-objs := ppe.o
|
||||
+qcom-ppe-objs := ppe.o ppe_config.o
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
index 14998ac771c7..443706291ce0 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include "ppe.h"
|
||||
+#include "ppe_config.h"
|
||||
|
||||
#define PPE_PORT_MAX 8
|
||||
#define PPE_CLK_RATE 353000000
|
||||
@@ -201,6 +202,10 @@ static int qcom_ppe_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "PPE clock config failed\n");
|
||||
|
||||
+ ret = ppe_hw_config(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "PPE HW config failed\n");
|
||||
+
|
||||
platform_set_drvdata(pdev, ppe_dev);
|
||||
|
||||
return 0;
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
new file mode 100644
|
||||
index 000000000000..0ba4efdfd509
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -0,0 +1,181 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/* PPE HW initialization configs such as BM(buffer management),
|
||||
+ * QM(queue management) and scheduler configs.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/bits.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include "ppe.h"
|
||||
+#include "ppe_config.h"
|
||||
+#include "ppe_regs.h"
|
||||
+
|
||||
+/**
|
||||
+ * struct ppe_bm_port_config - PPE BM port configuration.
|
||||
+ * @port_id_start: The fist BM port ID to configure.
|
||||
+ * @port_id_end: The last BM port ID to configure.
|
||||
+ * @pre_alloc: BM port dedicated buffer number.
|
||||
+ * @in_fly_buf: Buffer number for receiving the packet after pause frame sent.
|
||||
+ * @ceil: Ceil to generate the back pressure.
|
||||
+ * @weight: Weight value.
|
||||
+ * @resume_offset: Resume offset from the threshold value.
|
||||
+ * @resume_ceil: Ceil to resume from the back pressure state.
|
||||
+ * @dynamic: Dynamic threshold used or not.
|
||||
+ *
|
||||
+ * The is for configuring the threshold that impacts the port
|
||||
+ * flow control.
|
||||
+ */
|
||||
+struct ppe_bm_port_config {
|
||||
+ unsigned int port_id_start;
|
||||
+ unsigned int port_id_end;
|
||||
+ unsigned int pre_alloc;
|
||||
+ unsigned int in_fly_buf;
|
||||
+ unsigned int ceil;
|
||||
+ unsigned int weight;
|
||||
+ unsigned int resume_offset;
|
||||
+ unsigned int resume_ceil;
|
||||
+ bool dynamic;
|
||||
+};
|
||||
+
|
||||
+static int ipq9574_ppe_bm_group_config = 1550;
|
||||
+static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
|
||||
+ {
|
||||
+ .port_id_start = 0,
|
||||
+ .port_id_end = 0,
|
||||
+ .pre_alloc = 0,
|
||||
+ .in_fly_buf = 100,
|
||||
+ .ceil = 1146,
|
||||
+ .weight = 7,
|
||||
+ .resume_offset = 8,
|
||||
+ .resume_ceil = 0,
|
||||
+ .dynamic = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .port_id_start = 1,
|
||||
+ .port_id_end = 7,
|
||||
+ .pre_alloc = 0,
|
||||
+ .in_fly_buf = 100,
|
||||
+ .ceil = 250,
|
||||
+ .weight = 4,
|
||||
+ .resume_offset = 36,
|
||||
+ .resume_ceil = 0,
|
||||
+ .dynamic = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .port_id_start = 8,
|
||||
+ .port_id_end = 13,
|
||||
+ .pre_alloc = 0,
|
||||
+ .in_fly_buf = 128,
|
||||
+ .ceil = 250,
|
||||
+ .weight = 4,
|
||||
+ .resume_offset = 36,
|
||||
+ .resume_ceil = 0,
|
||||
+ .dynamic = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .port_id_start = 14,
|
||||
+ .port_id_end = 14,
|
||||
+ .pre_alloc = 0,
|
||||
+ .in_fly_buf = 40,
|
||||
+ .ceil = 250,
|
||||
+ .weight = 4,
|
||||
+ .resume_offset = 36,
|
||||
+ .resume_ceil = 0,
|
||||
+ .dynamic = true,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
+ struct ppe_bm_port_config port_cfg)
|
||||
+{
|
||||
+ u32 reg, val, bm_fc_val[2];
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Configure BM flow control related threshold */
|
||||
+ PPE_BM_PORT_FC_SET_WEIGHT(bm_fc_val, port_cfg.weight);
|
||||
+ PPE_BM_PORT_FC_SET_RESUME_OFFSET(bm_fc_val, port_cfg.resume_offset);
|
||||
+ PPE_BM_PORT_FC_SET_RESUME_THRESHOLD(bm_fc_val, port_cfg.resume_ceil);
|
||||
+ PPE_BM_PORT_FC_SET_DYNAMIC(bm_fc_val, port_cfg.dynamic);
|
||||
+ PPE_BM_PORT_FC_SET_REACT_LIMIT(bm_fc_val, port_cfg.in_fly_buf);
|
||||
+ PPE_BM_PORT_FC_SET_PRE_ALLOC(bm_fc_val, port_cfg.pre_alloc);
|
||||
+
|
||||
+ /* Ceiling is divided into the different register word. */
|
||||
+ val = FIELD_GET(GENMASK(2, 0), port_cfg.ceil);
|
||||
+ PPE_BM_PORT_FC_SET_CEILING_LOW(bm_fc_val, val);
|
||||
+ val = FIELD_GET(GENMASK(10, 3), port_cfg.ceil);
|
||||
+ PPE_BM_PORT_FC_SET_CEILING_HIGH(bm_fc_val, val);
|
||||
+
|
||||
+ reg = PPE_BM_PORT_FC_CFG_ADDR + PPE_BM_PORT_FC_CFG_INC * bm_port_id;
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ bm_fc_val, ARRAY_SIZE(bm_fc_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Assign the default group ID 0 to the BM port */
|
||||
+ val = FIELD_PREP(PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID, 0);
|
||||
+ reg = PPE_BM_PORT_GROUP_ID_ADDR + PPE_BM_PORT_GROUP_ID_INC * bm_port_id;
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID,
|
||||
+ val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Enable BM port flow control */
|
||||
+ val = FIELD_PREP(PPE_BM_PORT_FC_MODE_EN, true);
|
||||
+ reg = PPE_BM_PORT_FC_MODE_ADDR + PPE_BM_PORT_FC_MODE_INC * bm_port_id;
|
||||
+
|
||||
+ return regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_BM_PORT_FC_MODE_EN,
|
||||
+ val);
|
||||
+}
|
||||
+
|
||||
+/* Configure the buffer threshold for the port flow control function. */
|
||||
+static int ppe_config_bm(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ unsigned int i, bm_port_id, port_cfg_cnt;
|
||||
+ struct ppe_bm_port_config *port_cfg;
|
||||
+ u32 reg, val;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Configure the buffer number of group 0 by default. The buffer
|
||||
+ * number of group 1-3 is cleared to 0 after PPE reset on the probe
|
||||
+ * of PPE driver.
|
||||
+ */
|
||||
+ reg = PPE_BM_SHARED_GROUP_CFG_ADDR;
|
||||
+ val = FIELD_PREP(PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,
|
||||
+ ipq9574_ppe_bm_group_config);
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT,
|
||||
+ val);
|
||||
+ if (ret)
|
||||
+ goto bm_config_fail;
|
||||
+
|
||||
+ port_cfg = ipq9574_ppe_bm_port_config;
|
||||
+ port_cfg_cnt = ARRAY_SIZE(ipq9574_ppe_bm_port_config);
|
||||
+ for (i = 0; i < port_cfg_cnt; i++) {
|
||||
+ for (bm_port_id = port_cfg[i].port_id_start;
|
||||
+ bm_port_id <= port_cfg[i].port_id_end; bm_port_id++) {
|
||||
+ ret = ppe_config_bm_threshold(ppe_dev, bm_port_id,
|
||||
+ port_cfg[i]);
|
||||
+ if (ret)
|
||||
+ goto bm_config_fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+bm_config_fail:
|
||||
+ dev_err(ppe_dev->dev, "PPE BM config error %d\n", ret);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ return ppe_config_bm(ppe_dev);
|
||||
+}
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
new file mode 100644
|
||||
index 000000000000..7e66019de799
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
@@ -0,0 +1,10 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __PPE_CONFIG_H__
|
||||
+#define __PPE_CONFIG_H__
|
||||
+
|
||||
+int ppe_hw_config(struct ppe_device *ppe_dev);
|
||||
+#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
new file mode 100644
|
||||
index 000000000000..bf25e0acc0f6
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -0,0 +1,54 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/* PPE hardware register and table declarations. */
|
||||
+#ifndef __PPE_REGS_H__
|
||||
+#define __PPE_REGS_H__
|
||||
+
|
||||
+/* There are 15 BM ports and 4 BM groups supported by PPE,
|
||||
+ * BM port (0-7) is matched to EDMA port 0, BM port (8-13) is matched
|
||||
+ * to PPE physical port 1-6, BM port 14 is matched to EIP.
|
||||
+ */
|
||||
+#define PPE_BM_PORT_FC_MODE_ADDR 0x600100
|
||||
+#define PPE_BM_PORT_FC_MODE_INC 0x4
|
||||
+#define PPE_BM_PORT_FC_MODE_EN BIT(0)
|
||||
+
|
||||
+#define PPE_BM_PORT_GROUP_ID_ADDR 0x600180
|
||||
+#define PPE_BM_PORT_GROUP_ID_INC 0x4
|
||||
+#define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID GENMASK(1, 0)
|
||||
+
|
||||
+#define PPE_BM_SHARED_GROUP_CFG_ADDR 0x600290
|
||||
+#define PPE_BM_SHARED_GROUP_CFG_INC 0x4
|
||||
+#define PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT GENMASK(10, 0)
|
||||
+
|
||||
+#define PPE_BM_PORT_FC_CFG_ADDR 0x601000
|
||||
+#define PPE_BM_PORT_FC_CFG_INC 0x10
|
||||
+#define PPE_BM_PORT_FC_W0_REACT_LIMIT GENMASK(8, 0)
|
||||
+#define PPE_BM_PORT_FC_W0_RESUME_THRESHOLD GENMASK(17, 9)
|
||||
+#define PPE_BM_PORT_FC_W0_RESUME_OFFSET GENMASK(28, 18)
|
||||
+#define PPE_BM_PORT_FC_W0_CEILING_LOW GENMASK(31, 29)
|
||||
+#define PPE_BM_PORT_FC_W1_CEILING_HIGH GENMASK(7, 0)
|
||||
+#define PPE_BM_PORT_FC_W1_WEIGHT GENMASK(10, 8)
|
||||
+#define PPE_BM_PORT_FC_W1_DYNAMIC BIT(11)
|
||||
+#define PPE_BM_PORT_FC_W1_PRE_ALLOC GENMASK(22, 12)
|
||||
+
|
||||
+#define PPE_BM_PORT_FC_SET_REACT_LIMIT(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_REACT_LIMIT)
|
||||
+#define PPE_BM_PORT_FC_SET_RESUME_THRESHOLD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_RESUME_THRESHOLD)
|
||||
+#define PPE_BM_PORT_FC_SET_RESUME_OFFSET(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_RESUME_OFFSET)
|
||||
+#define PPE_BM_PORT_FC_SET_CEILING_LOW(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_BM_PORT_FC_W0_CEILING_LOW)
|
||||
+#define PPE_BM_PORT_FC_SET_CEILING_HIGH(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_CEILING_HIGH)
|
||||
+#define PPE_BM_PORT_FC_SET_WEIGHT(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_WEIGHT)
|
||||
+#define PPE_BM_PORT_FC_SET_DYNAMIC(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_DYNAMIC)
|
||||
+#define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,322 @@
|
||||
From 12a50075552d0e2ada65c039e5a09ca50421f152 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Tue, 26 Dec 2023 19:34:49 +0800
|
||||
Subject: [PATCH 20/50] net: ethernet: qualcomm: Add PPE queue management
|
||||
config
|
||||
|
||||
QM (queue management) config decides the length of PPE port queues
|
||||
and the threshold to drop packet.
|
||||
|
||||
There are two types of PPE queue, unicast queue (0-255) and multicast
|
||||
queue (256-299) are configured with different length, which are used
|
||||
to forward the different types of traffic.
|
||||
|
||||
Change-Id: I74ffcb6a39618ca8f585b5204d483fb45edecba8
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 176 +++++++++++++++++-
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 82 ++++++++
|
||||
2 files changed, 257 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index 0ba4efdfd509..4192fdc8d3a3 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -43,6 +43,27 @@ struct ppe_bm_port_config {
|
||||
bool dynamic;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct ppe_qm_queue_config - PPE queue config.
|
||||
+ * @queue_start: PPE start of queue ID.
|
||||
+ * @queue_end: PPE end of queue ID.
|
||||
+ * @prealloc_buf: Queue dedicated buffer number.
|
||||
+ * @ceil: Ceil to start drop packet from queue.
|
||||
+ * @weight: Weight value.
|
||||
+ * @resume_offset: Resume offset from the threshold.
|
||||
+ * @dynamic: Threshold value is decided dynamically or statically.
|
||||
+ *
|
||||
+ */
|
||||
+struct ppe_qm_queue_config {
|
||||
+ unsigned int queue_start;
|
||||
+ unsigned int queue_end;
|
||||
+ unsigned int prealloc_buf;
|
||||
+ unsigned int ceil;
|
||||
+ unsigned int weight;
|
||||
+ unsigned int resume_offset;
|
||||
+ bool dynamic;
|
||||
+};
|
||||
+
|
||||
static int ipq9574_ppe_bm_group_config = 1550;
|
||||
static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
|
||||
{
|
||||
@@ -91,6 +112,31 @@ static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+/* Default QM group settings for IPQ9754. */
|
||||
+static int ipq9574_ppe_qm_group_config = 2000;
|
||||
+
|
||||
+/* Default QM settings for unicast and multicast queues for IPQ9754. */
|
||||
+static struct ppe_qm_queue_config ipq9574_ppe_qm_queue_config[] = {
|
||||
+ {
|
||||
+ .queue_start = 0,
|
||||
+ .queue_end = 255,
|
||||
+ .prealloc_buf = 0,
|
||||
+ .ceil = 400,
|
||||
+ .weight = 4,
|
||||
+ .resume_offset = 36,
|
||||
+ .dynamic = true,
|
||||
+ },
|
||||
+ {
|
||||
+ .queue_start = 256,
|
||||
+ .queue_end = 299,
|
||||
+ .prealloc_buf = 0,
|
||||
+ .ceil = 250,
|
||||
+ .weight = 0,
|
||||
+ .resume_offset = 36,
|
||||
+ .dynamic = false,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
struct ppe_bm_port_config port_cfg)
|
||||
{
|
||||
@@ -175,7 +221,135 @@ static int ppe_config_bm(struct ppe_device *ppe_dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* Configure PPE hardware queue depth, which is decided by the threshold
|
||||
+ * of queue.
|
||||
+ */
|
||||
+static int ppe_config_qm(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ struct ppe_qm_queue_config *queue_cfg;
|
||||
+ int ret, i, queue_id, queue_cfg_count;
|
||||
+ u32 reg, multicast_queue_cfg[5];
|
||||
+ u32 unicast_queue_cfg[4];
|
||||
+ u32 group_cfg[3];
|
||||
+
|
||||
+ /* Assign the buffer number to the group 0 by default. */
|
||||
+ reg = PPE_AC_GRP_CFG_TBL_ADDR;
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ group_cfg, ARRAY_SIZE(group_cfg));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ PPE_AC_GRP_SET_BUF_LIMIT(group_cfg, ipq9574_ppe_qm_group_config);
|
||||
+
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ group_cfg, ARRAY_SIZE(group_cfg));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ queue_cfg = ipq9574_ppe_qm_queue_config;
|
||||
+ queue_cfg_count = ARRAY_SIZE(ipq9574_ppe_qm_queue_config);
|
||||
+ for (i = 0; i < queue_cfg_count; i++) {
|
||||
+ queue_id = queue_cfg[i].queue_start;
|
||||
+
|
||||
+ /* Configure threshold for dropping packet from unicast queue
|
||||
+ * and multicast queue, which belong to the different queue ID.
|
||||
+ */
|
||||
+ while (queue_id <= queue_cfg[i].queue_end) {
|
||||
+ if (queue_id < PPE_AC_UNI_QUEUE_CFG_TBL_NUM) {
|
||||
+ reg = PPE_AC_UNI_QUEUE_CFG_TBL_ADDR +
|
||||
+ PPE_AC_UNI_QUEUE_CFG_TBL_INC * queue_id;
|
||||
+
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ unicast_queue_cfg,
|
||||
+ ARRAY_SIZE(unicast_queue_cfg));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ PPE_AC_UNI_QUEUE_SET_EN(unicast_queue_cfg, true);
|
||||
+ PPE_AC_UNI_QUEUE_SET_GRP_ID(unicast_queue_cfg, 0);
|
||||
+ PPE_AC_UNI_QUEUE_SET_PRE_LIMIT(unicast_queue_cfg,
|
||||
+ queue_cfg[i].prealloc_buf);
|
||||
+ PPE_AC_UNI_QUEUE_SET_DYNAMIC(unicast_queue_cfg,
|
||||
+ queue_cfg[i].dynamic);
|
||||
+ PPE_AC_UNI_QUEUE_SET_WEIGHT(unicast_queue_cfg,
|
||||
+ queue_cfg[i].weight);
|
||||
+ PPE_AC_UNI_QUEUE_SET_THRESHOLD(unicast_queue_cfg,
|
||||
+ queue_cfg[i].ceil);
|
||||
+ PPE_AC_UNI_QUEUE_SET_GRN_RESUME(unicast_queue_cfg,
|
||||
+ queue_cfg[i].resume_offset);
|
||||
+
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ unicast_queue_cfg,
|
||||
+ ARRAY_SIZE(unicast_queue_cfg));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+ } else {
|
||||
+ reg = PPE_AC_MUL_QUEUE_CFG_TBL_ADDR +
|
||||
+ PPE_AC_MUL_QUEUE_CFG_TBL_INC * queue_id;
|
||||
+
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ multicast_queue_cfg,
|
||||
+ ARRAY_SIZE(multicast_queue_cfg));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ PPE_AC_MUL_QUEUE_SET_EN(multicast_queue_cfg, true);
|
||||
+ PPE_AC_MUL_QUEUE_SET_GRN_GRP_ID(multicast_queue_cfg, 0);
|
||||
+ PPE_AC_MUL_QUEUE_SET_GRN_PRE_LIMIT(multicast_queue_cfg,
|
||||
+ queue_cfg[i].prealloc_buf);
|
||||
+ PPE_AC_MUL_QUEUE_SET_GRN_THRESHOLD(multicast_queue_cfg,
|
||||
+ queue_cfg[i].ceil);
|
||||
+ PPE_AC_MUL_QUEUE_SET_GRN_RESUME(multicast_queue_cfg,
|
||||
+ queue_cfg[i].resume_offset);
|
||||
+
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ multicast_queue_cfg,
|
||||
+ ARRAY_SIZE(multicast_queue_cfg));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+ }
|
||||
+
|
||||
+ /* Enable enqueue */
|
||||
+ reg = PPE_ENQ_OPR_TBL_ADDR + PPE_ENQ_OPR_TBL_INC * queue_id;
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_ENQ_OPR_TBL_ENQ_DISABLE,
|
||||
+ FIELD_PREP(PPE_ENQ_OPR_TBL_ENQ_DISABLE, false));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ /* Enable dequeue */
|
||||
+ reg = PPE_DEQ_OPR_TBL_ADDR + PPE_DEQ_OPR_TBL_INC * queue_id;
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_DEQ_OPR_TBL_DEQ_DISABLE,
|
||||
+ FIELD_PREP(PPE_ENQ_OPR_TBL_ENQ_DISABLE, false));
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ queue_id++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Enable queue counter for all PPE hardware queues. */
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, PPE_EG_BRIDGE_CONFIG_ADDR,
|
||||
+ PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN,
|
||||
+ PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN);
|
||||
+ if (ret)
|
||||
+ goto qm_config_fail;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+qm_config_fail:
|
||||
+ dev_err(ppe_dev->dev, "PPE QM config error %d\n", ret);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
{
|
||||
- return ppe_config_bm(ppe_dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ppe_config_bm(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_config_qm(ppe_dev);
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index bf25e0acc0f6..0bc13979e5e2 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -11,6 +11,14 @@
|
||||
* BM port (0-7) is matched to EDMA port 0, BM port (8-13) is matched
|
||||
* to PPE physical port 1-6, BM port 14 is matched to EIP.
|
||||
*/
|
||||
+#define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044
|
||||
+#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2)
|
||||
+
|
||||
+#define PPE_DEQ_OPR_TBL_ADDR 0x430000
|
||||
+#define PPE_DEQ_OPR_TBL_NUM 300
|
||||
+#define PPE_DEQ_OPR_TBL_INC 0x10
|
||||
+#define PPE_DEQ_OPR_TBL_DEQ_DISABLE BIT(0)
|
||||
+
|
||||
#define PPE_BM_PORT_FC_MODE_ADDR 0x600100
|
||||
#define PPE_BM_PORT_FC_MODE_INC 0x4
|
||||
#define PPE_BM_PORT_FC_MODE_EN BIT(0)
|
||||
@@ -51,4 +59,78 @@
|
||||
#define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
|
||||
|
||||
+/* PPE unicast queue (0-255) configurations. */
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_TBL_ADDR 0x848000
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_TBL_NUM 256
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_TBL_INC 0x10
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_EN BIT(0)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_WRED_EN BIT(1)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_FC_EN BIT(2)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_COLOR_AWARE BIT(3)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_GRP_ID GENMASK(5, 4)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_PRE_LIMIT GENMASK(16, 6)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_DYNAMIC BIT(17)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_WEIGHT GENMASK(20, 18)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W0_THRESHOLD GENMASK(31, 21)
|
||||
+#define PPE_AC_UNI_QUEUE_CFG_W3_GRN_RESUME GENMASK(23, 13)
|
||||
+
|
||||
+#define PPE_AC_UNI_QUEUE_SET_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_EN)
|
||||
+#define PPE_AC_UNI_QUEUE_SET_GRP_ID(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_GRP_ID)
|
||||
+#define PPE_AC_UNI_QUEUE_SET_PRE_LIMIT(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_PRE_LIMIT)
|
||||
+#define PPE_AC_UNI_QUEUE_SET_DYNAMIC(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_DYNAMIC)
|
||||
+#define PPE_AC_UNI_QUEUE_SET_WEIGHT(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_WEIGHT)
|
||||
+#define PPE_AC_UNI_QUEUE_SET_THRESHOLD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_UNI_QUEUE_CFG_W0_THRESHOLD)
|
||||
+#define PPE_AC_UNI_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x3, value, PPE_AC_UNI_QUEUE_CFG_W3_GRN_RESUME)
|
||||
+
|
||||
+/* PPE multicast queue (256-299) configurations. */
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_TBL_ADDR 0x84a000
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_TBL_NUM 44
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_TBL_INC 0x10
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W0_EN BIT(0)
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W0_FC_EN BIT(1)
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W0_COLOR_AWARE BIT(2)
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W0_GRP_ID GENMASK(4, 3)
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W0_PRE_LIMIT GENMASK(15, 5)
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W0_THRESHOLD GENMASK(26, 16)
|
||||
+#define PPE_AC_MUL_QUEUE_CFG_W2_RESUME GENMASK(17, 7)
|
||||
+
|
||||
+#define PPE_AC_MUL_QUEUE_SET_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_EN)
|
||||
+#define PPE_AC_MUL_QUEUE_SET_GRN_GRP_ID(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_GRP_ID)
|
||||
+#define PPE_AC_MUL_QUEUE_SET_GRN_PRE_LIMIT(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_PRE_LIMIT)
|
||||
+#define PPE_AC_MUL_QUEUE_SET_GRN_THRESHOLD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_AC_MUL_QUEUE_CFG_W0_THRESHOLD)
|
||||
+#define PPE_AC_MUL_QUEUE_SET_GRN_RESUME(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x2, value, PPE_AC_MUL_QUEUE_CFG_W2_RESUME)
|
||||
+
|
||||
+/* PPE admission control group (0-3) configurations */
|
||||
+#define PPE_AC_GRP_CFG_TBL_ADDR 0x84c000
|
||||
+#define PPE_AC_GRP_CFG_TBL_NUM 0x4
|
||||
+#define PPE_AC_GRP_CFG_TBL_INC 0x10
|
||||
+#define PPE_AC_GRP_W0_AC_EN BIT(0)
|
||||
+#define PPE_AC_GRP_W0_AC_FC_EN BIT(1)
|
||||
+#define PPE_AC_GRP_W0_COLOR_AWARE BIT(2)
|
||||
+#define PPE_AC_GRP_W0_THRESHOLD_LOW GENMASK(31, 25)
|
||||
+#define PPE_AC_GRP_W1_THRESHOLD_HIGH GENMASK(3, 0)
|
||||
+#define PPE_AC_GRP_W1_BUF_LIMIT GENMASK(14, 4)
|
||||
+#define PPE_AC_GRP_W2_RESUME_GRN GENMASK(15, 5)
|
||||
+#define PPE_AC_GRP_W2_PRE_ALLOC GENMASK(26, 16)
|
||||
+
|
||||
+#define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT)
|
||||
+
|
||||
+#define PPE_ENQ_OPR_TBL_ADDR 0x85c000
|
||||
+#define PPE_ENQ_OPR_TBL_NUM 300
|
||||
+#define PPE_ENQ_OPR_TBL_INC 0x10
|
||||
+#define PPE_ENQ_OPR_TBL_ENQ_DISABLE BIT(0)
|
||||
+
|
||||
#endif
|
||||
--
|
||||
2.45.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,613 @@
|
||||
From 8dd72bdbb1e3f0061f2e4a9bb4f6fce0966585a6 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 27 Dec 2023 13:13:46 +0800
|
||||
Subject: [PATCH 22/50] net: ethernet: qualcomm: Initialize PPE queue settings
|
||||
|
||||
Configure unicast and multicast hardware queues to forward
|
||||
the traffic between PPE ports.
|
||||
|
||||
Each PPE port is assigned with the specific queue resource,
|
||||
and the egress queue ID is decided by the priority and the
|
||||
RSS hash value of packet.
|
||||
|
||||
Change-Id: I3e4d4e12548a12b11f129106678375cc3b58828d
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_api.c | 44 +++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_api.h | 34 ++
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 362 +++++++++++++++++-
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.h | 41 ++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 16 +
|
||||
5 files changed, 496 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_api.c b/drivers/net/ethernet/qualcomm/ppe/ppe_api.c
|
||||
index ba35fc151e2c..72d416e0ca44 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_api.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_api.c
|
||||
@@ -38,3 +38,47 @@ int ppe_queue_priority_set(struct ppe_device *ppe_dev,
|
||||
|
||||
return ppe_queue_scheduler_set(ppe_dev, node_id, level, port, sch_cfg);
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * ppe_edma_queue_offset_config - Configure queue offset for EDMA interface
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @class: The class to configure queue offset
|
||||
+ * @index: Class index, internal priority or hash value
|
||||
+ * @queue_offset: Queue offset value
|
||||
+ *
|
||||
+ * PPE EDMA queue offset is configured based on the PPE internal priority or
|
||||
+ * RSS hash value, the profile ID is fixed to 0 for EDMA interface.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
|
||||
+ enum ppe_queue_class_type class,
|
||||
+ int index, int queue_offset)
|
||||
+{
|
||||
+ if (class == PPE_QUEUE_CLASS_PRIORITY)
|
||||
+ return ppe_queue_ucast_pri_class_set(ppe_dev, 0,
|
||||
+ index, queue_offset);
|
||||
+
|
||||
+ return ppe_queue_ucast_hash_class_set(ppe_dev, 0,
|
||||
+ index, queue_offset);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ppe_edma_queue_resource_get - Get EDMA queue resource
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @type: Resource type
|
||||
+ * @res_start: Resource start ID returned
|
||||
+ * @res_end: Resource end ID returned
|
||||
+ *
|
||||
+ * PPE EDMA queue resource includes unicast queue and multicast queue.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_edma_queue_resource_get(struct ppe_device *ppe_dev, int type,
|
||||
+ int *res_start, int *res_end)
|
||||
+{
|
||||
+ if (type != PPE_RES_UCAST && type != PPE_RES_MCAST)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return ppe_port_resource_get(ppe_dev, 0, type, res_start, res_end);
|
||||
+};
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_api.h b/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
index ee5b47d06991..c8aa8945f90f 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
@@ -15,7 +15,41 @@
|
||||
#define PPE_QUEUE_ID_NUM 300
|
||||
#define PPE_FLOW_ID_NUM 64
|
||||
#define PPE_QUEUE_SCH_PRI_NUM 8
|
||||
+#define PPE_QUEUE_INTER_PRI_NUM 16
|
||||
+#define PPE_QUEUE_HASH_NUM 256
|
||||
+
|
||||
+/**
|
||||
+ * enum ppe_queue_class_type - PPE queue class type
|
||||
+ * @PPE_QUEUE_CLASS_PRIORITY: Queue offset configured from internal priority
|
||||
+ * @PPE_QUEUE_CLASS_HASH: Queue offset configured from RSS hash.
|
||||
+ */
|
||||
+enum ppe_queue_class_type {
|
||||
+ PPE_QUEUE_CLASS_PRIORITY,
|
||||
+ PPE_QUEUE_CLASS_HASH,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * enum ppe_resource_type - PPE resource type
|
||||
+ * @PPE_RES_UCAST: Unicast queue resource
|
||||
+ * @PPE_RES_MCAST: Multicast queue resource
|
||||
+ * @PPE_RES_FLOW_ID: Flow resource
|
||||
+ * @PPE_RES_L0_NODE: Level 0 QoS node resource
|
||||
+ * @PPE_RES_L1_NODE: Level 1 QoS node resource
|
||||
+ */
|
||||
+enum ppe_resource_type {
|
||||
+ PPE_RES_UCAST,
|
||||
+ PPE_RES_MCAST,
|
||||
+ PPE_RES_FLOW_ID,
|
||||
+ PPE_RES_L0_NODE,
|
||||
+ PPE_RES_L1_NODE,
|
||||
+};
|
||||
|
||||
int ppe_queue_priority_set(struct ppe_device *ppe_dev,
|
||||
int queue_id, int priority);
|
||||
+
|
||||
+int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
|
||||
+ enum ppe_queue_class_type class,
|
||||
+ int index, int queue_offset);
|
||||
+int ppe_edma_queue_resource_get(struct ppe_device *ppe_dev, int type,
|
||||
+ int *res_start, int *res_end);
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index bdef26da6fd3..ac90d33aecba 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -119,6 +119,34 @@ struct ppe_port_schedule_config {
|
||||
unsigned int drr_node_id;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct ppe_port_schedule_resource - PPE port scheduler resource.
|
||||
+ * @ucastq_start: Unicast queue start ID.
|
||||
+ * @ucastq_end: Unicast queue end ID.
|
||||
+ * @mcastq_start: Multicast queue start ID.
|
||||
+ * @mcastq_end: Multicast queue end ID.
|
||||
+ * @flow_id_start: Flow start ID.
|
||||
+ * @flow_id_end: Flow end ID.
|
||||
+ * @l0node_start: Scheduler node start ID for queue level.
|
||||
+ * @l0node_end: Scheduler node end ID for queue level.
|
||||
+ * @l1node_start: Scheduler node start ID for flow level.
|
||||
+ * @l1node_end: Scheduler node end ID for flow level.
|
||||
+ *
|
||||
+ * PPE scheduler resource allocated among the PPE ports.
|
||||
+ */
|
||||
+struct ppe_port_schedule_resource {
|
||||
+ unsigned int ucastq_start;
|
||||
+ unsigned int ucastq_end;
|
||||
+ unsigned int mcastq_start;
|
||||
+ unsigned int mcastq_end;
|
||||
+ unsigned int flow_id_start;
|
||||
+ unsigned int flow_id_end;
|
||||
+ unsigned int l0node_start;
|
||||
+ unsigned int l0node_end;
|
||||
+ unsigned int l1node_start;
|
||||
+ unsigned int l1node_end;
|
||||
+};
|
||||
+
|
||||
static int ipq9574_ppe_bm_group_config = 1550;
|
||||
static struct ppe_bm_port_config ipq9574_ppe_bm_port_config[] = {
|
||||
{
|
||||
@@ -648,6 +676,111 @@ static struct ppe_port_schedule_config ppe_qos_schedule_config[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+/* The QoS resource is applied to each PPE port, there are some
|
||||
+ * resource reserved as the last one.
|
||||
+ */
|
||||
+static struct ppe_port_schedule_resource ppe_scheduler_res[] = {
|
||||
+ { .ucastq_start = 0,
|
||||
+ .ucastq_end = 63,
|
||||
+ .mcastq_start = 256,
|
||||
+ .ucastq_end = 271,
|
||||
+ .flow_id_start = 0,
|
||||
+ .flow_id_end = 0,
|
||||
+ .l0node_start = 0,
|
||||
+ .l0node_end = 7,
|
||||
+ .l1node_start = 0,
|
||||
+ .l1node_end = 0,
|
||||
+ },
|
||||
+ { .ucastq_start = 144,
|
||||
+ .ucastq_end = 159,
|
||||
+ .mcastq_start = 272,
|
||||
+ .ucastq_end = 275,
|
||||
+ .flow_id_start = 36,
|
||||
+ .flow_id_end = 39,
|
||||
+ .l0node_start = 48,
|
||||
+ .l0node_end = 63,
|
||||
+ .l1node_start = 8,
|
||||
+ .l1node_end = 11,
|
||||
+ },
|
||||
+ { .ucastq_start = 160,
|
||||
+ .ucastq_end = 175,
|
||||
+ .mcastq_start = 276,
|
||||
+ .ucastq_end = 279,
|
||||
+ .flow_id_start = 40,
|
||||
+ .flow_id_end = 43,
|
||||
+ .l0node_start = 64,
|
||||
+ .l0node_end = 79,
|
||||
+ .l1node_start = 12,
|
||||
+ .l1node_end = 15,
|
||||
+ },
|
||||
+ { .ucastq_start = 176,
|
||||
+ .ucastq_end = 191,
|
||||
+ .mcastq_start = 280,
|
||||
+ .ucastq_end = 283,
|
||||
+ .flow_id_start = 44,
|
||||
+ .flow_id_end = 47,
|
||||
+ .l0node_start = 80,
|
||||
+ .l0node_end = 95,
|
||||
+ .l1node_start = 16,
|
||||
+ .l1node_end = 19,
|
||||
+ },
|
||||
+ { .ucastq_start = 192,
|
||||
+ .ucastq_end = 207,
|
||||
+ .mcastq_start = 284,
|
||||
+ .ucastq_end = 287,
|
||||
+ .flow_id_start = 48,
|
||||
+ .flow_id_end = 51,
|
||||
+ .l0node_start = 96,
|
||||
+ .l0node_end = 111,
|
||||
+ .l1node_start = 20,
|
||||
+ .l1node_end = 23,
|
||||
+ },
|
||||
+ { .ucastq_start = 208,
|
||||
+ .ucastq_end = 223,
|
||||
+ .mcastq_start = 288,
|
||||
+ .ucastq_end = 291,
|
||||
+ .flow_id_start = 52,
|
||||
+ .flow_id_end = 55,
|
||||
+ .l0node_start = 112,
|
||||
+ .l0node_end = 127,
|
||||
+ .l1node_start = 24,
|
||||
+ .l1node_end = 27,
|
||||
+ },
|
||||
+ { .ucastq_start = 224,
|
||||
+ .ucastq_end = 239,
|
||||
+ .mcastq_start = 292,
|
||||
+ .ucastq_end = 295,
|
||||
+ .flow_id_start = 56,
|
||||
+ .flow_id_end = 59,
|
||||
+ .l0node_start = 128,
|
||||
+ .l0node_end = 143,
|
||||
+ .l1node_start = 28,
|
||||
+ .l1node_end = 31,
|
||||
+ },
|
||||
+ { .ucastq_start = 240,
|
||||
+ .ucastq_end = 255,
|
||||
+ .mcastq_start = 296,
|
||||
+ .ucastq_end = 299,
|
||||
+ .flow_id_start = 60,
|
||||
+ .flow_id_end = 63,
|
||||
+ .l0node_start = 144,
|
||||
+ .l0node_end = 159,
|
||||
+ .l1node_start = 32,
|
||||
+ .l1node_end = 35,
|
||||
+ },
|
||||
+ { .ucastq_start = 64,
|
||||
+ .ucastq_end = 143,
|
||||
+ .mcastq_start = 0,
|
||||
+ .ucastq_end = 0,
|
||||
+ .flow_id_start = 1,
|
||||
+ .flow_id_end = 35,
|
||||
+ .l0node_start = 8,
|
||||
+ .l0node_end = 47,
|
||||
+ .l1node_start = 1,
|
||||
+ .l1node_end = 7,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
/* Set the first level scheduler configuration. */
|
||||
static int ppe_scheduler_l0_queue_map_set(struct ppe_device *ppe_dev,
|
||||
int node_id, int port,
|
||||
@@ -893,6 +1026,147 @@ int ppe_queue_scheduler_get(struct ppe_device *ppe_dev,
|
||||
port, scheduler_cfg);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ppe_queue_ucast_base_set - Set PPE unicast queue base ID
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @queue_dst: PPE queue destination configuration
|
||||
+ * @queue_base: PPE queue base ID
|
||||
+ * @profile_id: Profile ID
|
||||
+ *
|
||||
+ * The PPE unicast queue base ID is configured based on the destination
|
||||
+ * port information per profile ID.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev,
|
||||
+ struct ppe_queue_ucast_dest queue_dst,
|
||||
+ int queue_base, int profile_id)
|
||||
+{
|
||||
+ int index, profile_size;
|
||||
+ u32 val, reg;
|
||||
+
|
||||
+ profile_size = queue_dst.src_profile << 8;
|
||||
+ if (queue_dst.service_code_en)
|
||||
+ index = PPE_QUEUE_BASE_SERVICE_CODE + profile_size +
|
||||
+ queue_dst.service_code;
|
||||
+ else if (queue_dst.cpu_code_en)
|
||||
+ index = PPE_QUEUE_BASE_CPU_CODE + profile_size +
|
||||
+ queue_dst.cpu_code;
|
||||
+ else
|
||||
+ index = profile_size + queue_dst.dest_port;
|
||||
+
|
||||
+ val = FIELD_PREP(PPE_UCAST_QUEUE_MAP_TBL_PROFILE_ID, profile_id);
|
||||
+ val |= FIELD_PREP(PPE_UCAST_QUEUE_MAP_TBL_QUEUE_ID, queue_base);
|
||||
+ reg = PPE_UCAST_QUEUE_MAP_TBL_ADDR + index * PPE_UCAST_QUEUE_MAP_TBL_INC;
|
||||
+
|
||||
+ return regmap_write(ppe_dev->regmap, reg, val);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ppe_queue_ucast_pri_class_set - Set PPE unicast queue class of priority
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @profile_id: Profile ID
|
||||
+ * @priority: Priority to be used to set class
|
||||
+ * @class_offset: Class value for the destination queue ID
|
||||
+ *
|
||||
+ * The PPE unicast queue class is configured based on the PPE
|
||||
+ * internal priority.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_queue_ucast_pri_class_set(struct ppe_device *ppe_dev,
|
||||
+ int profile_id,
|
||||
+ int priority,
|
||||
+ int class_offset)
|
||||
+{
|
||||
+ u32 val, reg;
|
||||
+ int index;
|
||||
+
|
||||
+ index = (profile_id << 4) + priority;
|
||||
+ val = FIELD_PREP(PPE_UCAST_PRIORITY_MAP_TBL_CLASS, class_offset);
|
||||
+ reg = PPE_UCAST_PRIORITY_MAP_TBL_ADDR + index * PPE_UCAST_PRIORITY_MAP_TBL_INC;
|
||||
+
|
||||
+ return regmap_write(ppe_dev->regmap, reg, val);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ppe_queue_ucast_hash_class_set - Set PPE unicast queue class of hash value
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @profile_id: Profile ID
|
||||
+ * @rss_hash: Hash value to be used to set clas
|
||||
+ * @class_offset: Class value for the destination queue ID
|
||||
+ *
|
||||
+ * The PPE unicast queue class is configured based on the RSS hash value.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_queue_ucast_hash_class_set(struct ppe_device *ppe_dev,
|
||||
+ int profile_id,
|
||||
+ int rss_hash,
|
||||
+ int class_offset)
|
||||
+{
|
||||
+ u32 val, reg;
|
||||
+ int index;
|
||||
+
|
||||
+ index = (profile_id << 8) + rss_hash;
|
||||
+ val = FIELD_PREP(PPE_UCAST_HASH_MAP_TBL_HASH, class_offset);
|
||||
+ reg = PPE_UCAST_HASH_MAP_TBL_ADDR + index * PPE_UCAST_HASH_MAP_TBL_INC;
|
||||
+
|
||||
+ return regmap_write(ppe_dev->regmap, reg, val);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ppe_port_resource_get - Get PPE resource per port
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @port: PPE port
|
||||
+ * @type: Resource type
|
||||
+ * @res_start: Resource start ID
|
||||
+ * @res_end: Resource end ID
|
||||
+ *
|
||||
+ * PPE resource is assigned per PPE port, which is acquired for QoS scheduler.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, int type,
|
||||
+ int *res_start, int *res_end)
|
||||
+{
|
||||
+ struct ppe_port_schedule_resource res;
|
||||
+
|
||||
+ /* The reserved resource with the maximum port ID of PPE is
|
||||
+ * also allowed to be acquired.
|
||||
+ */
|
||||
+ if (port > ppe_dev->num_ports)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ res = ppe_scheduler_res[port];
|
||||
+ switch (type) {
|
||||
+ case PPE_RES_UCAST:
|
||||
+ *res_start = res.ucastq_start;
|
||||
+ *res_end = res.ucastq_end;
|
||||
+ break;
|
||||
+ case PPE_RES_MCAST:
|
||||
+ *res_start = res.mcastq_start;
|
||||
+ *res_end = res.mcastq_end;
|
||||
+ break;
|
||||
+ case PPE_RES_FLOW_ID:
|
||||
+ *res_start = res.flow_id_start;
|
||||
+ *res_end = res.flow_id_end;
|
||||
+ break;
|
||||
+ case PPE_RES_L0_NODE:
|
||||
+ *res_start = res.l0node_start;
|
||||
+ *res_end = res.l0node_end;
|
||||
+ break;
|
||||
+ case PPE_RES_L1_NODE:
|
||||
+ *res_start = res.l1node_start;
|
||||
+ *res_end = res.l1node_end;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
struct ppe_bm_port_config port_cfg)
|
||||
{
|
||||
@@ -1219,6 +1493,88 @@ static int ppe_config_scheduler(struct ppe_device *ppe_dev)
|
||||
return ret;
|
||||
};
|
||||
|
||||
+/* Configure PPE queue destination of each PPE port. */
|
||||
+static int ppe_queue_dest_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ int ret, port_id, index, class, res_start, res_end, queue_base, pri_max;
|
||||
+ struct ppe_queue_ucast_dest queue_dst;
|
||||
+
|
||||
+ for (port_id = 0; port_id < ppe_dev->num_ports; port_id++) {
|
||||
+ memset(&queue_dst, 0, sizeof(queue_dst));
|
||||
+
|
||||
+ ret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_UCAST,
|
||||
+ &res_start, &res_end);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ queue_base = res_start;
|
||||
+ queue_dst.dest_port = port_id;
|
||||
+
|
||||
+ /* Configure queue base ID and profile ID that is same as
|
||||
+ * physical port ID.
|
||||
+ */
|
||||
+ ret = ppe_queue_ucast_base_set(ppe_dev, queue_dst,
|
||||
+ queue_base, port_id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Queue priority range supported by each PPE port */
|
||||
+ ret = ppe_port_resource_get(ppe_dev, port_id, PPE_RES_L0_NODE,
|
||||
+ &res_start, &res_end);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ pri_max = res_end - res_start;
|
||||
+
|
||||
+ /* Redirect ARP reply packet with the max priority on CPU port,
|
||||
+ * which keeps the ARP reply directed to CPU (CPU code is 101)
|
||||
+ * with highest priority received by EDMA when there is a heavy
|
||||
+ * traffic loaded.
|
||||
+ */
|
||||
+ if (port_id == 0) {
|
||||
+ memset(&queue_dst, 0, sizeof(queue_dst));
|
||||
+
|
||||
+ queue_dst.cpu_code_en = true;
|
||||
+ queue_dst.cpu_code = 101;
|
||||
+ ret = ppe_queue_ucast_base_set(ppe_dev, queue_dst,
|
||||
+ queue_base + pri_max,
|
||||
+ 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Initialize the class offset of internal priority. */
|
||||
+ for (index = 0; index < PPE_QUEUE_INTER_PRI_NUM; index++) {
|
||||
+ class = index > pri_max ? pri_max : index;
|
||||
+
|
||||
+ ret = ppe_queue_ucast_pri_class_set(ppe_dev, port_id,
|
||||
+ index, class);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Initialize the class offset of RSS hash as 0 to avoid the
|
||||
+ * random hardware value that will lead to the unexpected
|
||||
+ * destination queue generated.
|
||||
+ */
|
||||
+ index = 0;
|
||||
+ for (index = 0; index < PPE_QUEUE_HASH_NUM; index++) {
|
||||
+ ret = ppe_queue_ucast_hash_class_set(ppe_dev, port_id,
|
||||
+ index, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Initialize PPE device to handle traffic correctly. */
|
||||
+static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ return ppe_queue_dest_init(ppe_dev);
|
||||
+}
|
||||
+
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
{
|
||||
int ret;
|
||||
@@ -1231,5 +1587,9 @@ int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return ppe_config_scheduler(ppe_dev);
|
||||
+ ret = ppe_config_scheduler(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_dev_hw_init(ppe_dev);
|
||||
}
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
index 167a114031fd..676c4ec45f6f 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
@@ -6,6 +6,13 @@
|
||||
#ifndef __PPE_CONFIG_H__
|
||||
#define __PPE_CONFIG_H__
|
||||
|
||||
+/* There are different queue config ranges for the destination port,
|
||||
+ * CPU code and service code.
|
||||
+ */
|
||||
+#define PPE_QUEUE_BASE_DEST_PORT 0
|
||||
+#define PPE_QUEUE_BASE_CPU_CODE 1024
|
||||
+#define PPE_QUEUE_BASE_SERVICE_CODE 2048
|
||||
+
|
||||
/**
|
||||
* struct ppe_qos_scheduler_cfg - PPE QoS scheduler configuration.
|
||||
* @flow_id: PPE flow ID.
|
||||
@@ -26,6 +33,26 @@ struct ppe_qos_scheduler_cfg {
|
||||
int node_frame_mode;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct ppe_queue_ucast_dest - PPE unicast queue destination.
|
||||
+ * @src_profile: Source profile.
|
||||
+ * @service_code_en: Enable service code.
|
||||
+ * @service_code: Service code.
|
||||
+ * @cpu_code_en: Enable CPU code.
|
||||
+ * @cpu_code: CPU code.
|
||||
+ * @dest_port: destination port.
|
||||
+ *
|
||||
+ * PPE egress queue ID is decided by the egress port ID.
|
||||
+ */
|
||||
+struct ppe_queue_ucast_dest {
|
||||
+ int src_profile;
|
||||
+ bool service_code_en;
|
||||
+ int service_code;
|
||||
+ bool cpu_code_en;
|
||||
+ int cpu_code;
|
||||
+ int dest_port;
|
||||
+};
|
||||
+
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev);
|
||||
int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
|
||||
int node_id, bool flow_level, int port,
|
||||
@@ -33,4 +60,18 @@ int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
|
||||
int ppe_queue_scheduler_get(struct ppe_device *ppe_dev,
|
||||
int node_id, bool flow_level, int *port,
|
||||
struct ppe_qos_scheduler_cfg *scheduler_cfg);
|
||||
+int ppe_queue_ucast_base_set(struct ppe_device *ppe_dev,
|
||||
+ struct ppe_queue_ucast_dest queue_dst,
|
||||
+ int queue_base,
|
||||
+ int profile_id);
|
||||
+int ppe_queue_ucast_pri_class_set(struct ppe_device *ppe_dev,
|
||||
+ int profile_id,
|
||||
+ int priority,
|
||||
+ int class_offset);
|
||||
+int ppe_queue_ucast_hash_class_set(struct ppe_device *ppe_dev,
|
||||
+ int profile_id,
|
||||
+ int rss_hash,
|
||||
+ int class_offset);
|
||||
+int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, int type,
|
||||
+ int *res_start, int *res_end);
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index 0279f1023bcf..1f6828237f94 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -153,6 +153,22 @@
|
||||
#define PPE_BM_PORT_FC_SET_PRE_ALLOC(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_BM_PORT_FC_W1_PRE_ALLOC)
|
||||
|
||||
+#define PPE_UCAST_QUEUE_MAP_TBL_ADDR 0x810000
|
||||
+#define PPE_UCAST_QUEUE_MAP_TBL_NUM 3072
|
||||
+#define PPE_UCAST_QUEUE_MAP_TBL_INC 0x10
|
||||
+#define PPE_UCAST_QUEUE_MAP_TBL_PROFILE_ID GENMASK(3, 0)
|
||||
+#define PPE_UCAST_QUEUE_MAP_TBL_QUEUE_ID GENMASK(11, 4)
|
||||
+
|
||||
+#define PPE_UCAST_HASH_MAP_TBL_ADDR 0x830000
|
||||
+#define PPE_UCAST_HASH_MAP_TBL_NUM 4096
|
||||
+#define PPE_UCAST_HASH_MAP_TBL_INC 0x10
|
||||
+#define PPE_UCAST_HASH_MAP_TBL_HASH GENMASK(7, 0)
|
||||
+
|
||||
+#define PPE_UCAST_PRIORITY_MAP_TBL_ADDR 0x842000
|
||||
+#define PPE_UCAST_PRIORITY_MAP_TBL_NUM 256
|
||||
+#define PPE_UCAST_PRIORITY_MAP_TBL_INC 0x10
|
||||
+#define PPE_UCAST_PRIORITY_MAP_TBL_CLASS GENMASK(3, 0)
|
||||
+
|
||||
/* PPE unicast queue (0-255) configurations. */
|
||||
#define PPE_AC_UNI_QUEUE_CFG_TBL_ADDR 0x848000
|
||||
#define PPE_AC_UNI_QUEUE_CFG_TBL_NUM 256
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,392 @@
|
||||
From 278b9f94b1dd344e88739044dd20d407b7f0651f Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 27 Dec 2023 13:51:20 +0800
|
||||
Subject: [PATCH 23/50] net: ethernet: qualcomm: Add PPE service code config
|
||||
|
||||
Configure service code for marking the traffic passed through
|
||||
PPE. Service code is generated according the features of packet
|
||||
when the packet is processed by PPE.
|
||||
|
||||
The bypass features of service code 1 is configured by default,
|
||||
which used by CPU port when the packet is transmitted from host
|
||||
to the CPU port of PPE.
|
||||
|
||||
Change-Id: I9fd2d26ba4c40e9ca182c20f5e02bd2f6f3e5e05
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_api.h | 3 +
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 98 +++++++++++-
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.h | 142 ++++++++++++++++++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 48 ++++++
|
||||
4 files changed, 290 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_api.h b/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
index c8aa8945f90f..ecdae4b95667 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
@@ -18,6 +18,9 @@
|
||||
#define PPE_QUEUE_INTER_PRI_NUM 16
|
||||
#define PPE_QUEUE_HASH_NUM 256
|
||||
|
||||
+/* The service code is used by EDMA driver to transmit packet to PPE. */
|
||||
+#define PPE_EDMA_SC_BYPASS_ID 1
|
||||
+
|
||||
/**
|
||||
* enum ppe_queue_class_type - PPE queue class type
|
||||
* @PPE_QUEUE_CLASS_PRIORITY: Queue offset configured from internal priority
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index ac90d33aecba..a8e7a536a6e0 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
+#include <linux/bitmap.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/regmap.h>
|
||||
@@ -1167,6 +1168,76 @@ int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, int type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ppe_servcode_config_set - Set PPE service code configuration
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @servcode: Service ID, 0-255 supported by PPE
|
||||
+ * @cfg: Service code configuration
|
||||
+ *
|
||||
+ * The service code configuration of PPE is used to handle the PPE
|
||||
+ * functions.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_servcode_config_set(struct ppe_device *ppe_dev, int servcode,
|
||||
+ struct ppe_servcode_cfg cfg)
|
||||
+{
|
||||
+ u32 val, reg, servcode_val[2] = {};
|
||||
+ unsigned long bitmap_value;
|
||||
+ int ret;
|
||||
+
|
||||
+ val = FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_PORT_ID_VALID, cfg.dest_port_valid);
|
||||
+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_PORT_ID, cfg.dest_port);
|
||||
+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_DIRECTION, cfg.is_src);
|
||||
+
|
||||
+ bitmap_value = bitmap_read(cfg.bitmaps.egress, 0, PPE_SC_BYPASS_EGRESS_SIZE);
|
||||
+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_DST_BYPASS_BITMAP, bitmap_value);
|
||||
+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_RX_CNT_EN,
|
||||
+ test_bit(PPE_SC_BYPASS_COUNTER_RX, cfg.bitmaps.counter));
|
||||
+ val |= FIELD_PREP(PPE_IN_L2_SERVICE_TBL_TX_CNT_EN,
|
||||
+ test_bit(PPE_SC_BYPASS_COUNTER_TX, cfg.bitmaps.counter));
|
||||
+ reg = PPE_IN_L2_SERVICE_TBL_ADDR + PPE_IN_L2_SERVICE_TBL_INC * servcode;
|
||||
+
|
||||
+ ret = regmap_write(ppe_dev->regmap, reg, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ bitmap_value = bitmap_read(cfg.bitmaps.ingress, 0, PPE_SC_BYPASS_INGRESS_SIZE);
|
||||
+ PPE_SERVICE_SET_BYPASS_BITMAP(servcode_val, bitmap_value);
|
||||
+ PPE_SERVICE_SET_RX_CNT_EN(servcode_val,
|
||||
+ test_bit(PPE_SC_BYPASS_COUNTER_RX_VLAN, cfg.bitmaps.counter));
|
||||
+ reg = PPE_SERVICE_TBL_ADDR + PPE_SERVICE_TBL_INC * servcode;
|
||||
+
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ servcode_val, ARRAY_SIZE(servcode_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg = PPE_EG_SERVICE_TBL_ADDR + PPE_EG_SERVICE_TBL_INC * servcode;
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ servcode_val, ARRAY_SIZE(servcode_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ PPE_EG_SERVICE_SET_UPDATE_ACTION(servcode_val, cfg.field_update_bitmap);
|
||||
+ PPE_EG_SERVICE_SET_NEXT_SERVCODE(servcode_val, cfg.next_service_code);
|
||||
+ PPE_EG_SERVICE_SET_HW_SERVICE(servcode_val, cfg.hw_service);
|
||||
+ PPE_EG_SERVICE_SET_OFFSET_SEL(servcode_val, cfg.offset_sel);
|
||||
+ PPE_EG_SERVICE_SET_TX_CNT_EN(servcode_val,
|
||||
+ test_bit(PPE_SC_BYPASS_COUNTER_TX_VLAN, cfg.bitmaps.counter));
|
||||
+
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ servcode_val, ARRAY_SIZE(servcode_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ bitmap_value = bitmap_read(cfg.bitmaps.tunnel, 0, PPE_SC_BYPASS_TUNNEL_SIZE);
|
||||
+ val = FIELD_PREP(PPE_TL_SERVICE_TBL_BYPASS_BITMAP, bitmap_value);
|
||||
+ reg = PPE_TL_SERVICE_TBL_ADDR + PPE_TL_SERVICE_TBL_INC * servcode;
|
||||
+
|
||||
+ return regmap_write(ppe_dev->regmap, reg, val);
|
||||
+}
|
||||
+
|
||||
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
struct ppe_bm_port_config port_cfg)
|
||||
{
|
||||
@@ -1569,10 +1640,35 @@ static int ppe_queue_dest_init(struct ppe_device *ppe_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Initialize the service code 1 used by CPU port. */
|
||||
+static int ppe_servcode_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ struct ppe_servcode_cfg servcode_cfg = {};
|
||||
+
|
||||
+ bitmap_zero(servcode_cfg.bitmaps.counter, PPE_SC_BYPASS_COUNTER_SIZE);
|
||||
+ bitmap_zero(servcode_cfg.bitmaps.tunnel, PPE_SC_BYPASS_TUNNEL_SIZE);
|
||||
+
|
||||
+ bitmap_fill(servcode_cfg.bitmaps.ingress, PPE_SC_BYPASS_INGRESS_SIZE);
|
||||
+ clear_bit(PPE_SC_BYPASS_INGRESS_FAKE_MAC_HEADER, servcode_cfg.bitmaps.ingress);
|
||||
+ clear_bit(PPE_SC_BYPASS_INGRESS_SERVICE_CODE, servcode_cfg.bitmaps.ingress);
|
||||
+ clear_bit(PPE_SC_BYPASS_INGRESS_FAKE_L2_PROTO, servcode_cfg.bitmaps.ingress);
|
||||
+
|
||||
+ bitmap_fill(servcode_cfg.bitmaps.egress, PPE_SC_BYPASS_EGRESS_SIZE);
|
||||
+ clear_bit(PPE_SC_BYPASS_EGRESS_ACL_POST_ROUTING_CHECK, servcode_cfg.bitmaps.egress);
|
||||
+
|
||||
+ return ppe_servcode_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, servcode_cfg);
|
||||
+}
|
||||
+
|
||||
/* Initialize PPE device to handle traffic correctly. */
|
||||
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
{
|
||||
- return ppe_queue_dest_init(ppe_dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ppe_queue_dest_init(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_servcode_init(ppe_dev);
|
||||
}
|
||||
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
index 676c4ec45f6f..dcb557ed843c 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
@@ -6,6 +6,8 @@
|
||||
#ifndef __PPE_CONFIG_H__
|
||||
#define __PPE_CONFIG_H__
|
||||
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
/* There are different queue config ranges for the destination port,
|
||||
* CPU code and service code.
|
||||
*/
|
||||
@@ -53,6 +55,143 @@ struct ppe_queue_ucast_dest {
|
||||
int dest_port;
|
||||
};
|
||||
|
||||
+/* Hardware bitmaps for bypassing features of the ingress packet. */
|
||||
+enum ppe_sc_ingress_type {
|
||||
+ PPE_SC_BYPASS_INGRESS_VLAN_TAG_FMT_CHECK = 0,
|
||||
+ PPE_SC_BYPASS_INGRESS_VLAN_MEMBER_CHECK = 1,
|
||||
+ PPE_SC_BYPASS_INGRESS_VLAN_TRANSLATE = 2,
|
||||
+ PPE_SC_BYPASS_INGRESS_MY_MAC_CHECK = 3,
|
||||
+ PPE_SC_BYPASS_INGRESS_DIP_LOOKUP = 4,
|
||||
+ PPE_SC_BYPASS_INGRESS_FLOW_LOOKUP = 5,
|
||||
+ PPE_SC_BYPASS_INGRESS_FLOW_ACTION = 6,
|
||||
+ PPE_SC_BYPASS_INGRESS_ACL = 7,
|
||||
+ PPE_SC_BYPASS_INGRESS_FAKE_MAC_HEADER = 8,
|
||||
+ PPE_SC_BYPASS_INGRESS_SERVICE_CODE = 9,
|
||||
+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L2 = 10,
|
||||
+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L3_IPV4 = 11,
|
||||
+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L3_IPV6 = 12,
|
||||
+ PPE_SC_BYPASS_INGRESS_WRONG_PKT_FMT_L4 = 13,
|
||||
+ PPE_SC_BYPASS_INGRESS_FLOW_SERVICE_CODE = 14,
|
||||
+ PPE_SC_BYPASS_INGRESS_ACL_SERVICE_CODE = 15,
|
||||
+ PPE_SC_BYPASS_INGRESS_FAKE_L2_PROTO = 16,
|
||||
+ PPE_SC_BYPASS_INGRESS_PPPOE_TERMINATION = 17,
|
||||
+ PPE_SC_BYPASS_INGRESS_DEFAULT_VLAN = 18,
|
||||
+ PPE_SC_BYPASS_INGRESS_DEFAULT_PCP = 19,
|
||||
+ PPE_SC_BYPASS_INGRESS_VSI_ASSIGN = 20,
|
||||
+ /* Values 21-23 are not specified by hardware. */
|
||||
+ PPE_SC_BYPASS_INGRESS_VLAN_ASSIGN_FAIL = 24,
|
||||
+ PPE_SC_BYPASS_INGRESS_SOURCE_GUARD = 25,
|
||||
+ PPE_SC_BYPASS_INGRESS_MRU_MTU_CHECK = 26,
|
||||
+ PPE_SC_BYPASS_INGRESS_FLOW_SRC_CHECK = 27,
|
||||
+ PPE_SC_BYPASS_INGRESS_FLOW_QOS = 28,
|
||||
+ /* This must be last as it determines the size of the BITMAP. */
|
||||
+ PPE_SC_BYPASS_INGRESS_SIZE,
|
||||
+};
|
||||
+
|
||||
+/* Hardware bitmaps for bypassing features of the egress packet. */
|
||||
+enum ppe_sc_egress_type {
|
||||
+ PPE_SC_BYPASS_EGRESS_VLAN_MEMBER_CHECK = 0,
|
||||
+ PPE_SC_BYPASS_EGRESS_VLAN_TRANSLATE = 1,
|
||||
+ PPE_SC_BYPASS_EGRESS_VLAN_TAG_FMT_CTRL = 2,
|
||||
+ PPE_SC_BYPASS_EGRESS_FDB_LEARN = 3,
|
||||
+ PPE_SC_BYPASS_EGRESS_FDB_REFRESH = 4,
|
||||
+ PPE_SC_BYPASS_EGRESS_L2_SOURCE_SECURITY = 5,
|
||||
+ PPE_SC_BYPASS_EGRESS_MANAGEMENT_FWD = 6,
|
||||
+ PPE_SC_BYPASS_EGRESS_BRIDGING_FWD = 7,
|
||||
+ PPE_SC_BYPASS_EGRESS_IN_STP_FLTR = 8,
|
||||
+ PPE_SC_BYPASS_EGRESS_EG_STP_FLTR = 9,
|
||||
+ PPE_SC_BYPASS_EGRESS_SOURCE_FLTR = 10,
|
||||
+ PPE_SC_BYPASS_EGRESS_POLICER = 11,
|
||||
+ PPE_SC_BYPASS_EGRESS_L2_PKT_EDIT = 12,
|
||||
+ PPE_SC_BYPASS_EGRESS_L3_PKT_EDIT = 13,
|
||||
+ PPE_SC_BYPASS_EGRESS_ACL_POST_ROUTING_CHECK = 14,
|
||||
+ PPE_SC_BYPASS_EGRESS_PORT_ISOLATION = 15,
|
||||
+ PPE_SC_BYPASS_EGRESS_PRE_ACL_QOS = 16,
|
||||
+ PPE_SC_BYPASS_EGRESS_POST_ACL_QOS = 17,
|
||||
+ PPE_SC_BYPASS_EGRESS_DSCP_QOS = 18,
|
||||
+ PPE_SC_BYPASS_EGRESS_PCP_QOS = 19,
|
||||
+ PPE_SC_BYPASS_EGRESS_PREHEADER_QOS = 20,
|
||||
+ PPE_SC_BYPASS_EGRESS_FAKE_MAC_DROP = 21,
|
||||
+ PPE_SC_BYPASS_EGRESS_TUNL_CONTEXT = 22,
|
||||
+ PPE_SC_BYPASS_EGRESS_FLOW_POLICER = 23,
|
||||
+ /* This must be last as it determines the size of the BITMAP. */
|
||||
+ PPE_SC_BYPASS_EGRESS_SIZE,
|
||||
+};
|
||||
+
|
||||
+/* Hardware bitmaps for bypassing counter of packet. */
|
||||
+enum ppe_sc_counter_type {
|
||||
+ PPE_SC_BYPASS_COUNTER_RX_VLAN = 0,
|
||||
+ PPE_SC_BYPASS_COUNTER_RX = 1,
|
||||
+ PPE_SC_BYPASS_COUNTER_TX_VLAN = 2,
|
||||
+ PPE_SC_BYPASS_COUNTER_TX = 3,
|
||||
+ /* This must be last as it determines the size of the BITMAP. */
|
||||
+ PPE_SC_BYPASS_COUNTER_SIZE,
|
||||
+};
|
||||
+
|
||||
+/* Hardware bitmaps for bypassing features of tunnel packet. */
|
||||
+enum ppe_sc_tunnel_type {
|
||||
+ PPE_SC_BYPASS_TUNNEL_SERVICE_CODE = 0,
|
||||
+ PPE_SC_BYPASS_TUNNEL_TUNNEL_HANDLE = 1,
|
||||
+ PPE_SC_BYPASS_TUNNEL_L3_IF_CHECK = 2,
|
||||
+ PPE_SC_BYPASS_TUNNEL_VLAN_CHECK = 3,
|
||||
+ PPE_SC_BYPASS_TUNNEL_DMAC_CHECK = 4,
|
||||
+ PPE_SC_BYPASS_TUNNEL_UDP_CSUM_0_CHECK = 5,
|
||||
+ PPE_SC_BYPASS_TUNNEL_TBL_DE_ACCE_CHECK = 6,
|
||||
+ PPE_SC_BYPASS_TUNNEL_PPPOE_MC_TERM_CHECK = 7,
|
||||
+ PPE_SC_BYPASS_TUNNEL_TTL_EXCEED_CHECK = 8,
|
||||
+ PPE_SC_BYPASS_TUNNEL_MAP_SRC_CHECK = 9,
|
||||
+ PPE_SC_BYPASS_TUNNEL_MAP_DST_CHECK = 10,
|
||||
+ PPE_SC_BYPASS_TUNNEL_LPM_DST_LOOKUP = 11,
|
||||
+ PPE_SC_BYPASS_TUNNEL_LPM_LOOKUP = 12,
|
||||
+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L2 = 13,
|
||||
+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L3_IPV4 = 14,
|
||||
+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L3_IPV6 = 15,
|
||||
+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_L4 = 16,
|
||||
+ PPE_SC_BYPASS_TUNNEL_WRONG_PKT_FMT_TUNNEL = 17,
|
||||
+ /* Values 18-19 are not specified by hardware. */
|
||||
+ PPE_SC_BYPASS_TUNNEL_PRE_IPO = 20,
|
||||
+ /* This must be last as it determines the size of the BITMAP. */
|
||||
+ PPE_SC_BYPASS_TUNNEL_SIZE,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct ppe_sc_bypss - PPE service bypass bitmaps
|
||||
+ * @ingress: Bitmap of features that can be bypassed on the ingress packet.
|
||||
+ * @egress: Bitmap of features that can be bypassed on the egress packet.
|
||||
+ * @counter: Bitmap of features that can be bypassed on the counter type.
|
||||
+ * @tunnel: Bitmap of features that can be bypassed on the tunnel packet.
|
||||
+ */
|
||||
+struct ppe_sc_bypass {
|
||||
+ DECLARE_BITMAP(ingress, PPE_SC_BYPASS_INGRESS_SIZE);
|
||||
+ DECLARE_BITMAP(egress, PPE_SC_BYPASS_EGRESS_SIZE);
|
||||
+ DECLARE_BITMAP(counter, PPE_SC_BYPASS_COUNTER_SIZE);
|
||||
+ DECLARE_BITMAP(tunnel, PPE_SC_BYPASS_TUNNEL_SIZE);
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct ppe_servcode_cfg - PPE service code configuration.
|
||||
+ * @dest_port_valid: Generate destination port or not.
|
||||
+ * @dest_port: Destination port ID.
|
||||
+ * @bitmaps: Bitmap of bypass features.
|
||||
+ * @is_src: Destination port acts as source port, packet sent to CPU.
|
||||
+ * @field_update_bitmap: Fields updated to the EDMA preheader.
|
||||
+ * @next_service_code: New service code.
|
||||
+ * @hw_service: Hardware functions selected.
|
||||
+ * @offset_sel: Packet offset selection.
|
||||
+ *
|
||||
+ * Service code is generated during the packet passing through PPE.
|
||||
+ */
|
||||
+struct ppe_servcode_cfg {
|
||||
+ bool dest_port_valid;
|
||||
+ int dest_port;
|
||||
+ struct ppe_sc_bypass bitmaps;
|
||||
+ bool is_src;
|
||||
+ int field_update_bitmap;
|
||||
+ int next_service_code;
|
||||
+ int hw_service;
|
||||
+ int offset_sel;
|
||||
+};
|
||||
+
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev);
|
||||
int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
|
||||
int node_id, bool flow_level, int port,
|
||||
@@ -74,4 +213,7 @@ int ppe_queue_ucast_hash_class_set(struct ppe_device *ppe_dev,
|
||||
int class_offset);
|
||||
int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, int type,
|
||||
int *res_start, int *res_end);
|
||||
+int ppe_servcode_config_set(struct ppe_device *ppe_dev,
|
||||
+ int servcode,
|
||||
+ struct ppe_servcode_cfg cfg);
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index 1f6828237f94..3122743af98d 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -27,9 +27,57 @@
|
||||
#define PPE_BM_SCH_CFG_TBL_SECOND_PORT_VALID BIT(6)
|
||||
#define PPE_BM_SCH_CFG_TBL_SECOND_PORT GENMASK(11, 8)
|
||||
|
||||
+/* PPE service code configuration on the ingress direction. */
|
||||
+#define PPE_SERVICE_TBL_ADDR 0x15000
|
||||
+#define PPE_SERVICE_TBL_NUM 256
|
||||
+#define PPE_SERVICE_TBL_INC 0x10
|
||||
+#define PPE_SERVICE_W0_BYPASS_BITMAP GENMASK(31, 0)
|
||||
+#define PPE_SERVICE_W1_RX_CNT_EN BIT(0)
|
||||
+
|
||||
+#define PPE_SERVICE_SET_BYPASS_BITMAP(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_SERVICE_W0_BYPASS_BITMAP)
|
||||
+#define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_SERVICE_W1_RX_CNT_EN)
|
||||
+
|
||||
#define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044
|
||||
#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2)
|
||||
|
||||
+/* PPE service code configuration on the egress direction. */
|
||||
+#define PPE_EG_SERVICE_TBL_ADDR 0x43000
|
||||
+#define PPE_EG_SERVICE_TBL_NUM 256
|
||||
+#define PPE_EG_SERVICE_TBL_INC 0x10
|
||||
+#define PPE_EG_SERVICE_W0_UPDATE_ACTION GENMASK(31, 0)
|
||||
+#define PPE_EG_SERVICE_W1_NEXT_SERVCODE GENMASK(7, 0)
|
||||
+#define PPE_EG_SERVICE_W1_HW_SERVICE GENMASK(13, 8)
|
||||
+#define PPE_EG_SERVICE_W1_OFFSET_SEL BIT(14)
|
||||
+#define PPE_EG_SERVICE_W1_TX_CNT_EN BIT(15)
|
||||
+
|
||||
+#define PPE_EG_SERVICE_SET_UPDATE_ACTION(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_EG_SERVICE_W0_UPDATE_ACTION)
|
||||
+#define PPE_EG_SERVICE_SET_NEXT_SERVCODE(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_NEXT_SERVCODE)
|
||||
+#define PPE_EG_SERVICE_SET_HW_SERVICE(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_HW_SERVICE)
|
||||
+#define PPE_EG_SERVICE_SET_OFFSET_SEL(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_OFFSET_SEL)
|
||||
+#define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN)
|
||||
+
|
||||
+#define PPE_IN_L2_SERVICE_TBL_ADDR 0x66000
|
||||
+#define PPE_IN_L2_SERVICE_TBL_NUM 256
|
||||
+#define PPE_IN_L2_SERVICE_TBL_INC 0x10
|
||||
+#define PPE_IN_L2_SERVICE_TBL_DST_PORT_ID_VALID BIT(0)
|
||||
+#define PPE_IN_L2_SERVICE_TBL_DST_PORT_ID GENMASK(4, 1)
|
||||
+#define PPE_IN_L2_SERVICE_TBL_DST_DIRECTION BIT(5)
|
||||
+#define PPE_IN_L2_SERVICE_TBL_DST_BYPASS_BITMAP GENMASK(29, 6)
|
||||
+#define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN BIT(30)
|
||||
+#define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN BIT(31)
|
||||
+
|
||||
+#define PPE_TL_SERVICE_TBL_ADDR 0x306000
|
||||
+#define PPE_TL_SERVICE_TBL_NUM 256
|
||||
+#define PPE_TL_SERVICE_TBL_INC 4
|
||||
+#define PPE_TL_SERVICE_TBL_BYPASS_BITMAP GENMASK(31, 0)
|
||||
+
|
||||
#define PPE_PSCH_SCH_DEPTH_CFG_ADDR 0x400000
|
||||
#define PPE_PSCH_SCH_DEPTH_CFG_NUM 1
|
||||
#define PPE_PSCH_SCH_DEPTH_CFG_INC 4
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,238 @@
|
||||
From 61881bae3ad9d961139e970f1aae75070cd45b5c Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 27 Dec 2023 14:11:40 +0800
|
||||
Subject: [PATCH 24/50] net: ethernet: qualcomm: Add PPE port control config
|
||||
|
||||
1. Initialize and setup the physical port.
|
||||
2. Configure the default action as drop when the packet size
|
||||
is more than the configured MTU of physical port.
|
||||
|
||||
Change-Id: Id98aea7b17556f85021905978b3403ca6d427557
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 91 ++++++++++++++++++-
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.h | 11 +++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 50 ++++++++++
|
||||
3 files changed, 151 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index a8e7a536a6e0..18296a449d4e 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -1238,6 +1238,50 @@ int ppe_servcode_config_set(struct ppe_device *ppe_dev, int servcode,
|
||||
return regmap_write(ppe_dev->regmap, reg, val);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ppe_counter_set - Set PPE port counter enabled or not
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @port: PPE port ID
|
||||
+ * @enable: Counter status
|
||||
+ *
|
||||
+ * PPE port counter is optionally configured as enabled or not.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable)
|
||||
+{
|
||||
+ u32 reg, val, mru_mtu_val[3];
|
||||
+ int ret;
|
||||
+
|
||||
+ reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * port;
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(mru_mtu_val, enable);
|
||||
+ PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(mru_mtu_val, enable);
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * port;
|
||||
+ val = FIELD_PREP(PPE_MC_MTU_CTRL_TBL_TX_CNT_EN, enable);
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_MC_MTU_CTRL_TBL_TX_CNT_EN,
|
||||
+ val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg = PPE_PORT_EG_VLAN_ADDR + PPE_PORT_EG_VLAN_INC * port;
|
||||
+ val = FIELD_PREP(PPE_PORT_EG_VLAN_TX_COUNTING_EN, enable);
|
||||
+
|
||||
+ return regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_PORT_EG_VLAN_TX_COUNTING_EN,
|
||||
+ val);
|
||||
+}
|
||||
+
|
||||
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
struct ppe_bm_port_config port_cfg)
|
||||
{
|
||||
@@ -1659,6 +1703,47 @@ static int ppe_servcode_init(struct ppe_device *ppe_dev)
|
||||
return ppe_servcode_config_set(ppe_dev, PPE_EDMA_SC_BYPASS_ID, servcode_cfg);
|
||||
}
|
||||
|
||||
+/* Initialize PPE port configurations. */
|
||||
+static int ppe_port_ctrl_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ u32 reg, val, mru_mtu_val[3];
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 1; i < ppe_dev->num_ports; i++) {
|
||||
+ /* Enable PPE port counter */
|
||||
+ ret = ppe_counter_set(ppe_dev, i, true);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg = PPE_MRU_MTU_CTRL_TBL_ADDR + PPE_MRU_MTU_CTRL_TBL_INC * i;
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Drop the packet when the packet size is more than
|
||||
+ * the MTU or MRU of the physical PPE port.
|
||||
+ */
|
||||
+ PPE_MRU_MTU_CTRL_SET_MRU_CMD(mru_mtu_val, PPE_ACTION_DROP);
|
||||
+ PPE_MRU_MTU_CTRL_SET_MTU_CMD(mru_mtu_val, PPE_ACTION_DROP);
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ mru_mtu_val, ARRAY_SIZE(mru_mtu_val));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ reg = PPE_MC_MTU_CTRL_TBL_ADDR + PPE_MC_MTU_CTRL_TBL_INC * i;
|
||||
+ val = FIELD_PREP(PPE_MC_MTU_CTRL_TBL_MTU_CMD, PPE_ACTION_DROP);
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap, reg,
|
||||
+ PPE_MC_MTU_CTRL_TBL_MTU_CMD,
|
||||
+ val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Enable CPU port counter. */
|
||||
+ return ppe_counter_set(ppe_dev, 0, true);
|
||||
+}
|
||||
+
|
||||
/* Initialize PPE device to handle traffic correctly. */
|
||||
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
{
|
||||
@@ -1668,7 +1753,11 @@ static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return ppe_servcode_init(ppe_dev);
|
||||
+ ret = ppe_servcode_init(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_port_ctrl_init(ppe_dev);
|
||||
}
|
||||
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
index dcb557ed843c..7f5d92c39dd3 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
@@ -192,6 +192,16 @@ struct ppe_servcode_cfg {
|
||||
int offset_sel;
|
||||
};
|
||||
|
||||
+/* The action of packet received by PPE can be forwarded, dropped, copied
|
||||
+ * to CPU (enter multicast queue), redirected to CPU (enter unicast queue).
|
||||
+ */
|
||||
+enum ppe_action_type {
|
||||
+ PPE_ACTION_FORWARD = 0,
|
||||
+ PPE_ACTION_DROP = 1,
|
||||
+ PPE_ACTION_COPY_TO_CPU = 2,
|
||||
+ PPE_ACTION_REDIRECT_TO_CPU = 3,
|
||||
+};
|
||||
+
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev);
|
||||
int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
|
||||
int node_id, bool flow_level, int port,
|
||||
@@ -216,4 +226,5 @@ int ppe_port_resource_get(struct ppe_device *ppe_dev, int port, int type,
|
||||
int ppe_servcode_config_set(struct ppe_device *ppe_dev,
|
||||
int servcode,
|
||||
struct ppe_servcode_cfg cfg);
|
||||
+int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable);
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index 3122743af98d..e981a1c0e670 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -18,6 +18,11 @@
|
||||
#define PPE_BM_SCH_CTRL_SCH_OFFSET GENMASK(14, 8)
|
||||
#define PPE_BM_SCH_CTRL_SCH_EN BIT(31)
|
||||
|
||||
+#define PPE_RX_FIFO_CFG_ADDR 0xb004
|
||||
+#define PPE_RX_FIFO_CFG_NUM 8
|
||||
+#define PPE_RX_FIFO_CFG_INC 4
|
||||
+#define PPE_RX_FIFO_CFG_THRSH GENMASK(2, 0)
|
||||
+
|
||||
#define PPE_BM_SCH_CFG_TBL_ADDR 0xc000
|
||||
#define PPE_BM_SCH_CFG_TBL_NUM 128
|
||||
#define PPE_BM_SCH_CFG_TBL_INC 0x10
|
||||
@@ -39,6 +44,17 @@
|
||||
#define PPE_SERVICE_SET_RX_CNT_EN(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_SERVICE_W1_RX_CNT_EN)
|
||||
|
||||
+#define PPE_PORT_EG_VLAN_ADDR 0x20020
|
||||
+#define PPE_PORT_EG_VLAN_NUM 8
|
||||
+#define PPE_PORT_EG_VLAN_INC 4
|
||||
+#define PPE_PORT_EG_VLAN_VLAN_TYPE BIT(0)
|
||||
+#define PPE_PORT_EG_VLAN_CTAG_MODE GENMASK(2, 1)
|
||||
+#define PPE_PORT_EG_VLAN_STAG_MODE GENMASK(4, 3)
|
||||
+#define PPE_PORT_EG_VLAN_VSI_TAG_MODE_EN BIT(5)
|
||||
+#define PPE_PORT_EG_VLAN_PCP_PROP_CMD BIT(6)
|
||||
+#define PPE_PORT_EG_VLAN_DEI_PROP_CMD BIT(7)
|
||||
+#define PPE_PORT_EG_VLAN_TX_COUNTING_EN BIT(8)
|
||||
+
|
||||
#define PPE_EG_BRIDGE_CONFIG_ADDR 0x20044
|
||||
#define PPE_EG_BRIDGE_CONFIG_QUEUE_CNT_EN BIT(2)
|
||||
|
||||
@@ -63,6 +79,40 @@
|
||||
#define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN)
|
||||
|
||||
+#define PPE_MC_MTU_CTRL_TBL_ADDR 0x60a00
|
||||
+#define PPE_MC_MTU_CTRL_TBL_NUM 8
|
||||
+#define PPE_MC_MTU_CTRL_TBL_INC 4
|
||||
+#define PPE_MC_MTU_CTRL_TBL_MTU GENMASK(13, 0)
|
||||
+#define PPE_MC_MTU_CTRL_TBL_MTU_CMD GENMASK(15, 14)
|
||||
+#define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN BIT(16)
|
||||
+
|
||||
+/* PPE port control configuration, the MTU and MRU configs. */
|
||||
+#define PPE_MRU_MTU_CTRL_TBL_ADDR 0x65000
|
||||
+#define PPE_MRU_MTU_CTRL_TBL_NUM 256
|
||||
+#define PPE_MRU_MTU_CTRL_TBL_INC 0x10
|
||||
+#define PPE_MRU_MTU_CTRL_W0_MRU GENMASK(13, 0)
|
||||
+#define PPE_MRU_MTU_CTRL_W0_MRU_CMD GENMASK(15, 14)
|
||||
+#define PPE_MRU_MTU_CTRL_W0_MTU GENMASK(29, 16)
|
||||
+#define PPE_MRU_MTU_CTRL_W0_MTU_CMD GENMASK(31, 30)
|
||||
+#define PPE_MRU_MTU_CTRL_W1_RX_CNT_EN BIT(0)
|
||||
+#define PPE_MRU_MTU_CTRL_W1_TX_CNT_EN BIT(1)
|
||||
+#define PPE_MRU_MTU_CTRL_W1_SRC_PROFILE GENMASK(3, 2)
|
||||
+#define PPE_MRU_MTU_CTRL_W1_INNER_PREC_LOW BIT(31)
|
||||
+#define PPE_MRU_MTU_CTRL_W2_INNER_PREC_HIGH GENMASK(1, 0)
|
||||
+
|
||||
+#define PPE_MRU_MTU_CTRL_SET_MRU(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MRU)
|
||||
+#define PPE_MRU_MTU_CTRL_SET_MRU_CMD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MRU_CMD)
|
||||
+#define PPE_MRU_MTU_CTRL_SET_MTU(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MTU)
|
||||
+#define PPE_MRU_MTU_CTRL_SET_MTU_CMD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_MRU_MTU_CTRL_W0_MTU_CMD)
|
||||
+#define PPE_MRU_MTU_CTRL_SET_RX_CNT_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_MRU_MTU_CTRL_W1_RX_CNT_EN)
|
||||
+#define PPE_MRU_MTU_CTRL_SET_TX_CNT_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_MRU_MTU_CTRL_W1_TX_CNT_EN)
|
||||
+
|
||||
#define PPE_IN_L2_SERVICE_TBL_ADDR 0x66000
|
||||
#define PPE_IN_L2_SERVICE_TBL_NUM 256
|
||||
#define PPE_IN_L2_SERVICE_TBL_INC 0x10
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,351 @@
|
||||
From b052daae2f22a7a7fcfe981598444c3f5fb370b4 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 27 Dec 2023 14:52:13 +0800
|
||||
Subject: [PATCH 25/50] net: ethernet: qualcomm: Add PPE RSS hash config
|
||||
|
||||
PPE RSS hash is generated by the configured seed based on the
|
||||
packet content, which is used to select queue and can also be
|
||||
passed to EDMA RX descriptor.
|
||||
|
||||
Change-Id: If02cb25aa81a3afb0f3d68b2a5a354bd6cee28b8
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 182 +++++++++++++++++-
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.h | 36 ++++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 47 +++++
|
||||
3 files changed, 263 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index 18296a449d4e..4363ea3cfb90 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -1282,6 +1282,143 @@ int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable)
|
||||
val);
|
||||
}
|
||||
|
||||
+static int ppe_rss_hash_ipv4_config(struct ppe_device *ppe_dev, int index,
|
||||
+ struct ppe_rss_hash_cfg cfg)
|
||||
+{
|
||||
+ u32 reg, val;
|
||||
+
|
||||
+ switch (index) {
|
||||
+ case 0:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sip_mix[0]);
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dip_mix[0]);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_protocol_mix);
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_dport_mix);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_IPV4_VAL, cfg.hash_sport_mix);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ reg = PPE_RSS_HASH_MIX_IPV4_ADDR + index * PPE_RSS_HASH_MIX_IPV4_INC;
|
||||
+
|
||||
+ return regmap_write(ppe_dev->regmap, reg, val);
|
||||
+}
|
||||
+
|
||||
+static int ppe_rss_hash_ipv6_config(struct ppe_device *ppe_dev, int index,
|
||||
+ struct ppe_rss_hash_cfg cfg)
|
||||
+{
|
||||
+ u32 reg, val;
|
||||
+
|
||||
+ switch (index) {
|
||||
+ case 0 ... 3:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sip_mix[index]);
|
||||
+ break;
|
||||
+ case 4 ... 7:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dip_mix[index - 4]);
|
||||
+ break;
|
||||
+ case 8:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_protocol_mix);
|
||||
+ break;
|
||||
+ case 9:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_dport_mix);
|
||||
+ break;
|
||||
+ case 10:
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MIX_VAL, cfg.hash_sport_mix);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ reg = PPE_RSS_HASH_MIX_ADDR + index * PPE_RSS_HASH_MIX_INC;
|
||||
+
|
||||
+ return regmap_write(ppe_dev->regmap, reg, val);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * ppe_rss_hash_config_set - Set PPE RSS hash seed
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @mode: Packet format mode
|
||||
+ * @hash_cfg: RSS hash configuration
|
||||
+ *
|
||||
+ * PPE RSS hash seed is configured based on the packet format.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
|
||||
+ struct ppe_rss_hash_cfg cfg)
|
||||
+{
|
||||
+ u32 val, reg;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ if (mode & PPE_RSS_HASH_MODE_IPV4) {
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_HASH_MASK, cfg.hash_mask);
|
||||
+ val |= FIELD_PREP(PPE_RSS_HASH_MASK_IPV4_FRAGMENT, cfg.hash_fragment_mode);
|
||||
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_IPV4_ADDR, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_SEED_IPV4_VAL, cfg.hash_seed);
|
||||
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_IPV4_ADDR, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 0; i < PPE_RSS_HASH_MIX_IPV4_NUM; i++) {
|
||||
+ ret = ppe_rss_hash_ipv4_config(ppe_dev, i, cfg);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_RSS_HASH_FIN_IPV4_NUM; i++) {
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_INNER, cfg.hash_fin_inner[i]);
|
||||
+ val |= FIELD_PREP(PPE_RSS_HASH_FIN_IPV4_OUTER, cfg.hash_fin_outer[i]);
|
||||
+ reg = PPE_RSS_HASH_FIN_IPV4_ADDR + i * PPE_RSS_HASH_FIN_IPV4_INC;
|
||||
+
|
||||
+ ret = regmap_write(ppe_dev->regmap, reg, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (mode & PPE_RSS_HASH_MODE_IPV6) {
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_MASK_HASH_MASK, cfg.hash_mask);
|
||||
+ val |= FIELD_PREP(PPE_RSS_HASH_MASK_FRAGMENT, cfg.hash_fragment_mode);
|
||||
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_MASK_ADDR, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_SEED_VAL, cfg.hash_seed);
|
||||
+ ret = regmap_write(ppe_dev->regmap, PPE_RSS_HASH_SEED_ADDR, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 0; i < PPE_RSS_HASH_MIX_NUM; i++) {
|
||||
+ ret = ppe_rss_hash_ipv6_config(ppe_dev, i, cfg);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_RSS_HASH_FIN_NUM; i++) {
|
||||
+ val = FIELD_PREP(PPE_RSS_HASH_FIN_INNER, cfg.hash_fin_inner[i]);
|
||||
+ val |= FIELD_PREP(PPE_RSS_HASH_FIN_OUTER, cfg.hash_fin_outer[i]);
|
||||
+ reg = PPE_RSS_HASH_FIN_ADDR + i * PPE_RSS_HASH_FIN_INC;
|
||||
+
|
||||
+ ret = regmap_write(ppe_dev->regmap, reg, val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
struct ppe_bm_port_config port_cfg)
|
||||
{
|
||||
@@ -1324,7 +1461,7 @@ static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
return regmap_update_bits(ppe_dev->regmap, reg,
|
||||
PPE_BM_PORT_FC_MODE_EN,
|
||||
val);
|
||||
-}
|
||||
+};
|
||||
|
||||
/* Configure the buffer threshold for the port flow control function. */
|
||||
static int ppe_config_bm(struct ppe_device *ppe_dev)
|
||||
@@ -1744,6 +1881,43 @@ static int ppe_port_ctrl_init(struct ppe_device *ppe_dev)
|
||||
return ppe_counter_set(ppe_dev, 0, true);
|
||||
}
|
||||
|
||||
+/* Initialize PPE RSS hash configuration, the RSS hash configs decides the
|
||||
+ * random hash value generated, which is used to generate the queue offset.
|
||||
+ */
|
||||
+static int ppe_rss_hash_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ u16 fins[PPE_RSS_HASH_TUPLES] = { 0x205, 0x264, 0x227, 0x245, 0x201 };
|
||||
+ u8 ips[PPE_RSS_HASH_IP_LENGTH] = { 0x13, 0xb, 0x13, 0xb };
|
||||
+ struct ppe_rss_hash_cfg hash_cfg;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ hash_cfg.hash_seed = get_random_u32();
|
||||
+ hash_cfg.hash_mask = 0xfff;
|
||||
+ hash_cfg.hash_fragment_mode = false;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(fins); i++) {
|
||||
+ hash_cfg.hash_fin_inner[i] = fins[i] & 0x1f;
|
||||
+ hash_cfg.hash_fin_outer[i] = fins[i] >> 5;
|
||||
+ }
|
||||
+
|
||||
+ hash_cfg.hash_protocol_mix = 0x13;
|
||||
+ hash_cfg.hash_dport_mix = 0xb;
|
||||
+ hash_cfg.hash_sport_mix = 0x13;
|
||||
+ hash_cfg.hash_sip_mix[0] = 0x13;
|
||||
+ hash_cfg.hash_dip_mix[0] = 0xb;
|
||||
+
|
||||
+ ret = ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV4, hash_cfg);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(ips); i++) {
|
||||
+ hash_cfg.hash_sip_mix[i] = ips[i];
|
||||
+ hash_cfg.hash_dip_mix[i] = ips[i];
|
||||
+ }
|
||||
+
|
||||
+ return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg);
|
||||
+}
|
||||
+
|
||||
/* Initialize PPE device to handle traffic correctly. */
|
||||
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
{
|
||||
@@ -1757,7 +1931,11 @@ static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return ppe_port_ctrl_init(ppe_dev);
|
||||
+ ret = ppe_port_ctrl_init(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_rss_hash_init(ppe_dev);
|
||||
}
|
||||
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
index 7f5d92c39dd3..6dd91bc45908 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
@@ -15,6 +15,11 @@
|
||||
#define PPE_QUEUE_BASE_CPU_CODE 1024
|
||||
#define PPE_QUEUE_BASE_SERVICE_CODE 2048
|
||||
|
||||
+#define PPE_RSS_HASH_MODE_IPV4 BIT(0)
|
||||
+#define PPE_RSS_HASH_MODE_IPV6 BIT(1)
|
||||
+#define PPE_RSS_HASH_IP_LENGTH 4
|
||||
+#define PPE_RSS_HASH_TUPLES 5
|
||||
+
|
||||
/**
|
||||
* struct ppe_qos_scheduler_cfg - PPE QoS scheduler configuration.
|
||||
* @flow_id: PPE flow ID.
|
||||
@@ -202,6 +207,35 @@ enum ppe_action_type {
|
||||
PPE_ACTION_REDIRECT_TO_CPU = 3,
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct ppe_rss_hash_cfg - PPE RSS hash configuration.
|
||||
+ * @hash_mask: Mask of the generated hash value.
|
||||
+ * @hash_fragment_mode: Mode of the fragment packet for 3 tuples.
|
||||
+ * @hash_seed: Seed to generate RSS hash.
|
||||
+ * @hash_sip_mix: Source IP selection.
|
||||
+ * @hash_dip_mix: Destination IP selection.
|
||||
+ * @hash_protocol_mix: Protocol selection.
|
||||
+ * @hash_sport_mix: Source L4 port selection.
|
||||
+ * @hash_sport_mix: Destination L4 port selection.
|
||||
+ * @hash_fin_inner: RSS hash value first selection.
|
||||
+ * @hash_fin_outer: RSS hash value second selection.
|
||||
+ *
|
||||
+ * PPE RSS hash value is generated based on the RSS hash configuration
|
||||
+ * with the received packet.
|
||||
+ */
|
||||
+struct ppe_rss_hash_cfg {
|
||||
+ u32 hash_mask;
|
||||
+ bool hash_fragment_mode;
|
||||
+ u32 hash_seed;
|
||||
+ u8 hash_sip_mix[PPE_RSS_HASH_IP_LENGTH];
|
||||
+ u8 hash_dip_mix[PPE_RSS_HASH_IP_LENGTH];
|
||||
+ u8 hash_protocol_mix;
|
||||
+ u8 hash_sport_mix;
|
||||
+ u8 hash_dport_mix;
|
||||
+ u8 hash_fin_inner[PPE_RSS_HASH_TUPLES];
|
||||
+ u8 hash_fin_outer[PPE_RSS_HASH_TUPLES];
|
||||
+};
|
||||
+
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev);
|
||||
int ppe_queue_scheduler_set(struct ppe_device *ppe_dev,
|
||||
int node_id, bool flow_level, int port,
|
||||
@@ -227,4 +261,6 @@ int ppe_servcode_config_set(struct ppe_device *ppe_dev,
|
||||
int servcode,
|
||||
struct ppe_servcode_cfg cfg);
|
||||
int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable);
|
||||
+int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
|
||||
+ struct ppe_rss_hash_cfg hash_cfg);
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index e981a1c0e670..29001a2599d8 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -23,6 +23,53 @@
|
||||
#define PPE_RX_FIFO_CFG_INC 4
|
||||
#define PPE_RX_FIFO_CFG_THRSH GENMASK(2, 0)
|
||||
|
||||
+/* RSS configs contributes to the random RSS hash value generated, which
|
||||
+ * is used to configure the queue offset.
|
||||
+ */
|
||||
+#define PPE_RSS_HASH_MASK_ADDR 0xb4318
|
||||
+#define PPE_RSS_HASH_MASK_NUM 1
|
||||
+#define PPE_RSS_HASH_MASK_INC 4
|
||||
+#define PPE_RSS_HASH_MASK_HASH_MASK GENMASK(20, 0)
|
||||
+#define PPE_RSS_HASH_MASK_FRAGMENT BIT(28)
|
||||
+
|
||||
+#define PPE_RSS_HASH_SEED_ADDR 0xb431c
|
||||
+#define PPE_RSS_HASH_SEED_NUM 1
|
||||
+#define PPE_RSS_HASH_SEED_INC 4
|
||||
+#define PPE_RSS_HASH_SEED_VAL GENMASK(31, 0)
|
||||
+
|
||||
+#define PPE_RSS_HASH_MIX_ADDR 0xb4320
|
||||
+#define PPE_RSS_HASH_MIX_NUM 11
|
||||
+#define PPE_RSS_HASH_MIX_INC 4
|
||||
+#define PPE_RSS_HASH_MIX_VAL GENMASK(4, 0)
|
||||
+
|
||||
+#define PPE_RSS_HASH_FIN_ADDR 0xb4350
|
||||
+#define PPE_RSS_HASH_FIN_NUM 5
|
||||
+#define PPE_RSS_HASH_FIN_INC 4
|
||||
+#define PPE_RSS_HASH_FIN_INNER GENMASK(4, 0)
|
||||
+#define PPE_RSS_HASH_FIN_OUTER GENMASK(9, 5)
|
||||
+
|
||||
+#define PPE_RSS_HASH_MASK_IPV4_ADDR 0xb4380
|
||||
+#define PPE_RSS_HASH_MASK_IPV4_NUM 1
|
||||
+#define PPE_RSS_HASH_MASK_IPV4_INC 4
|
||||
+#define PPE_RSS_HASH_MASK_IPV4_HASH_MASK GENMASK(20, 0)
|
||||
+#define PPE_RSS_HASH_MASK_IPV4_FRAGMENT BIT(28)
|
||||
+
|
||||
+#define PPE_RSS_HASH_SEED_IPV4_ADDR 0xb4384
|
||||
+#define PPE_RSS_HASH_SEED_IPV4_NUM 1
|
||||
+#define PPE_RSS_HASH_SEED_IPV4_INC 4
|
||||
+#define PPE_RSS_HASH_SEED_IPV4_VAL GENMASK(31, 0)
|
||||
+
|
||||
+#define PPE_RSS_HASH_MIX_IPV4_ADDR 0xb4390
|
||||
+#define PPE_RSS_HASH_MIX_IPV4_NUM 5
|
||||
+#define PPE_RSS_HASH_MIX_IPV4_INC 4
|
||||
+#define PPE_RSS_HASH_MIX_IPV4_VAL GENMASK(4, 0)
|
||||
+
|
||||
+#define PPE_RSS_HASH_FIN_IPV4_ADDR 0xb43b0
|
||||
+#define PPE_RSS_HASH_FIN_IPV4_NUM 5
|
||||
+#define PPE_RSS_HASH_FIN_IPV4_INC 4
|
||||
+#define PPE_RSS_HASH_FIN_IPV4_INNER GENMASK(4, 0)
|
||||
+#define PPE_RSS_HASH_FIN_IPV4_OUTER GENMASK(9, 5)
|
||||
+
|
||||
#define PPE_BM_SCH_CFG_TBL_ADDR 0xc000
|
||||
#define PPE_BM_SCH_CFG_TBL_NUM 128
|
||||
#define PPE_BM_SCH_CFG_TBL_INC 0x10
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,172 @@
|
||||
From 809513a92e3aef6ae852b35e118408059929d6d3 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 27 Dec 2023 15:44:37 +0800
|
||||
Subject: [PATCH 26/50] net: ethernet: qualcomm: Add PPE queue map function
|
||||
|
||||
Configure the queues of CPU port mapped with the EDMA ring.
|
||||
|
||||
All queues of CPU port are mappled to the EDMA ring 0 by default,
|
||||
which can be updated by EDMA driver.
|
||||
|
||||
Change-Id: I87ab4117af86e4b3fe7a4b41490ba8ac71ce29ef
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_api.c | 23 ++++++++++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_api.h | 2 +
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 45 ++++++++++++++++++-
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.h | 5 +++
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 5 +++
|
||||
5 files changed, 79 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_api.c b/drivers/net/ethernet/qualcomm/ppe/ppe_api.c
|
||||
index 72d416e0ca44..6199c7025f66 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_api.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_api.c
|
||||
@@ -82,3 +82,26 @@ int ppe_edma_queue_resource_get(struct ppe_device *ppe_dev, int type,
|
||||
|
||||
return ppe_port_resource_get(ppe_dev, 0, type, res_start, res_end);
|
||||
};
|
||||
+
|
||||
+/**
|
||||
+ * ppe_edma_ring_to_queues_config - Map EDMA ring to PPE queues
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @ring_id: EDMA ring ID
|
||||
+ * @num: Number of queues mapped to EDMA ring
|
||||
+ * @queues: PPE queue IDs
|
||||
+ *
|
||||
+ * PPE queues are configured to map with the special EDMA ring ID.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_edma_ring_to_queues_config(struct ppe_device *ppe_dev, int ring_id,
|
||||
+ int num, int queues[] __counted_by(num))
|
||||
+{
|
||||
+ u32 queue_bmap[PPE_RING_MAPPED_BP_QUEUE_WORD_COUNT] = {};
|
||||
+ int index;
|
||||
+
|
||||
+ for (index = 0; index < num; index++)
|
||||
+ queue_bmap[queues[index] / 32] |= BIT_MASK(queues[index] % 32);
|
||||
+
|
||||
+ return ppe_ring_queue_map_set(ppe_dev, ring_id, queue_bmap);
|
||||
+}
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_api.h b/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
index ecdae4b95667..2135b5383bcd 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_api.h
|
||||
@@ -55,4 +55,6 @@ int ppe_edma_queue_offset_config(struct ppe_device *ppe_dev,
|
||||
int index, int queue_offset);
|
||||
int ppe_edma_queue_resource_get(struct ppe_device *ppe_dev, int type,
|
||||
int *res_start, int *res_end);
|
||||
+int ppe_edma_ring_to_queues_config(struct ppe_device *ppe_dev, int ring_id,
|
||||
+ int num, int queues[] __counted_by(num));
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index 4363ea3cfb90..a19a6472e4ed 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -1419,6 +1419,28 @@ int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ppe_ring_queue_map_set - Set PPE queue mapped with EDMA ring
|
||||
+ * @ppe_dev: PPE device
|
||||
+ * @ring_id: EDMA ring ID
|
||||
+ * @queue_map: Queue bit map
|
||||
+ *
|
||||
+ * PPE queue is configured to use the special Ring.
|
||||
+ *
|
||||
+ * Return 0 on success, negative error code on failure.
|
||||
+ */
|
||||
+int ppe_ring_queue_map_set(struct ppe_device *ppe_dev, int ring_id, u32 *queue_map)
|
||||
+{
|
||||
+ u32 reg, queue_bitmap_val[PPE_RING_MAPPED_BP_QUEUE_WORD_COUNT];
|
||||
+
|
||||
+ memcpy(queue_bitmap_val, queue_map, sizeof(queue_bitmap_val));
|
||||
+ reg = PPE_RING_Q_MAP_TBL_ADDR + PPE_RING_Q_MAP_TBL_INC * ring_id;
|
||||
+
|
||||
+ return regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ queue_bitmap_val,
|
||||
+ ARRAY_SIZE(queue_bitmap_val));
|
||||
+}
|
||||
+
|
||||
static int ppe_config_bm_threshold(struct ppe_device *ppe_dev, int bm_port_id,
|
||||
struct ppe_bm_port_config port_cfg)
|
||||
{
|
||||
@@ -1918,6 +1940,23 @@ static int ppe_rss_hash_init(struct ppe_device *ppe_dev)
|
||||
return ppe_rss_hash_config_set(ppe_dev, PPE_RSS_HASH_MODE_IPV6, hash_cfg);
|
||||
}
|
||||
|
||||
+/* Initialize queues of CPU port mapped with EDMA ring 0. */
|
||||
+static int ppe_queues_to_ring_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ u32 queue_bmap[PPE_RING_MAPPED_BP_QUEUE_WORD_COUNT] = {};
|
||||
+ int ret, queue_id, queue_max;
|
||||
+
|
||||
+ ret = ppe_port_resource_get(ppe_dev, 0, PPE_RES_UCAST,
|
||||
+ &queue_id, &queue_max);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (; queue_id <= queue_max; queue_id++)
|
||||
+ queue_bmap[queue_id / 32] |= BIT_MASK(queue_id % 32);
|
||||
+
|
||||
+ return ppe_ring_queue_map_set(ppe_dev, 0, queue_bmap);
|
||||
+}
|
||||
+
|
||||
/* Initialize PPE device to handle traffic correctly. */
|
||||
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
{
|
||||
@@ -1935,7 +1974,11 @@ static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return ppe_rss_hash_init(ppe_dev);
|
||||
+ ret = ppe_rss_hash_init(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_queues_to_ring_init(ppe_dev);
|
||||
}
|
||||
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
index 6dd91bc45908..9be749800f14 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.h
|
||||
@@ -20,6 +20,8 @@
|
||||
#define PPE_RSS_HASH_IP_LENGTH 4
|
||||
#define PPE_RSS_HASH_TUPLES 5
|
||||
|
||||
+#define PPE_RING_MAPPED_BP_QUEUE_WORD_COUNT 10
|
||||
+
|
||||
/**
|
||||
* struct ppe_qos_scheduler_cfg - PPE QoS scheduler configuration.
|
||||
* @flow_id: PPE flow ID.
|
||||
@@ -263,4 +265,7 @@ int ppe_servcode_config_set(struct ppe_device *ppe_dev,
|
||||
int ppe_counter_set(struct ppe_device *ppe_dev, int port, bool enable);
|
||||
int ppe_rss_hash_config_set(struct ppe_device *ppe_dev, int mode,
|
||||
struct ppe_rss_hash_cfg hash_cfg);
|
||||
+int ppe_ring_queue_map_set(struct ppe_device *ppe_dev,
|
||||
+ int ring_id,
|
||||
+ u32 *queue_map);
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index 29001a2599d8..8c6cd6b52b0f 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -212,6 +212,11 @@
|
||||
#define PPE_L0_COMP_CFG_TBL_SHAPER_METER_LEN GENMASK(1, 0)
|
||||
#define PPE_L0_COMP_CFG_TBL_NODE_METER_LEN GENMASK(3, 2)
|
||||
|
||||
+/* PPE queue bitmap. */
|
||||
+#define PPE_RING_Q_MAP_TBL_ADDR 0x42a000
|
||||
+#define PPE_RING_Q_MAP_TBL_NUM 24
|
||||
+#define PPE_RING_Q_MAP_TBL_INC 0x40
|
||||
+
|
||||
#define PPE_DEQ_OPR_TBL_ADDR 0x430000
|
||||
#define PPE_DEQ_OPR_TBL_NUM 300
|
||||
#define PPE_DEQ_OPR_TBL_INC 0x10
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,187 @@
|
||||
From 244012f3f879d4709be68e7ddabc064268bbd69e Mon Sep 17 00:00:00 2001
|
||||
From: Lei Wei <quic_leiwei@quicinc.com>
|
||||
Date: Thu, 28 Dec 2023 00:38:08 +0800
|
||||
Subject: [PATCH 27/50] net: ethernet: qualcomm: Add PPE L2 bridge
|
||||
initialization
|
||||
|
||||
The per-port L2 bridge settings are initialized as follows:
|
||||
For PPE CPU port, the PPE bridge Tx is enabled and FDB learn is
|
||||
disabled. For PPE physical port, the PPE bridge Tx is disabled
|
||||
and FDB learn is enabled by default and the L2 forward action
|
||||
is initialized as forward to CPU port.
|
||||
|
||||
Change-Id: Ida42464f1d5e53583a434a11b19e6501c649d44e
|
||||
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
|
||||
---
|
||||
.../net/ethernet/qualcomm/ppe/ppe_config.c | 68 ++++++++++++++++++-
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 54 +++++++++++++++
|
||||
2 files changed, 121 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
index a19a6472e4ed..621f4f0ba9e2 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_config.c
|
||||
@@ -1957,6 +1957,68 @@ static int ppe_queues_to_ring_init(struct ppe_device *ppe_dev)
|
||||
return ppe_ring_queue_map_set(ppe_dev, 0, queue_bmap);
|
||||
}
|
||||
|
||||
+/* Initialize PPE bridge configuration. */
|
||||
+static int ppe_bridge_init(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ u32 reg, mask, port_cfg[4], vsi_cfg[2];
|
||||
+ int ret, i;
|
||||
+
|
||||
+ /* CPU port0 enable bridge Tx and disable FDB new address
|
||||
+ * learning and station move address learning.
|
||||
+ */
|
||||
+ mask = PPE_PORT_BRIDGE_TXMAC_EN;
|
||||
+ mask |= PPE_PORT_BRIDGE_NEW_LRN_EN;
|
||||
+ mask |= PPE_PORT_BRIDGE_STA_MOVE_LRN_EN;
|
||||
+ ret = regmap_update_bits(ppe_dev->regmap,
|
||||
+ PPE_PORT_BRIDGE_CTRL_ADDR,
|
||||
+ mask,
|
||||
+ PPE_PORT_BRIDGE_TXMAC_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (i = 1; i < ppe_dev->num_ports; i++) {
|
||||
+ /* Set Invalid VSI forwarding to CPU port0 if no VSI
|
||||
+ * is assigned to the port.
|
||||
+ */
|
||||
+ reg = PPE_L2_VP_PORT_TBL_ADDR + PPE_L2_VP_PORT_TBL_INC * i;
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ port_cfg, ARRAY_SIZE(port_cfg));
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ PPE_L2_PORT_SET_INVALID_VSI_FWD_EN(port_cfg, true);
|
||||
+ PPE_L2_PORT_SET_DST_INFO(port_cfg, 0);
|
||||
+
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ port_cfg, ARRAY_SIZE(port_cfg));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_VSI_TBL_NUM; i++) {
|
||||
+ /* Enable VSI bridge forward address learning and set VSI
|
||||
+ * forward member includes CPU port0.
|
||||
+ */
|
||||
+ PPE_VSI_SET_MEMBER_PORT_BITMAP(vsi_cfg, BIT(0));
|
||||
+ PPE_VSI_SET_UUC_BITMAP(vsi_cfg, BIT(0));
|
||||
+ PPE_VSI_SET_UMC_BITMAP(vsi_cfg, BIT(0));
|
||||
+ PPE_VSI_SET_BC_BITMAP(vsi_cfg, BIT(0));
|
||||
+ PPE_VSI_SET_NEW_ADDR_LRN_EN(vsi_cfg, true);
|
||||
+ PPE_VSI_SET_NEW_ADDR_FWD_CMD(vsi_cfg, PPE_ACTION_FORWARD);
|
||||
+ PPE_VSI_SET_STATION_MOVE_LRN_EN(vsi_cfg, true);
|
||||
+ PPE_VSI_SET_STATION_MOVE_FWD_CMD(vsi_cfg, PPE_ACTION_FORWARD);
|
||||
+
|
||||
+ reg = PPE_VSI_TBL_ADDR + PPE_VSI_TBL_INC * i;
|
||||
+ ret = regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ vsi_cfg, ARRAY_SIZE(vsi_cfg));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Initialize PPE device to handle traffic correctly. */
|
||||
static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
{
|
||||
@@ -1978,7 +2040,11 @@ static int ppe_dev_hw_init(struct ppe_device *ppe_dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- return ppe_queues_to_ring_init(ppe_dev);
|
||||
+ ret = ppe_queues_to_ring_init(ppe_dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return ppe_bridge_init(ppe_dev);
|
||||
}
|
||||
|
||||
int ppe_hw_config(struct ppe_device *ppe_dev)
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index 8c6cd6b52b0f..7f06843e4151 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -126,6 +126,18 @@
|
||||
#define PPE_EG_SERVICE_SET_TX_CNT_EN(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_EG_SERVICE_W1_TX_CNT_EN)
|
||||
|
||||
+/* PPE port bridge configuration */
|
||||
+#define PPE_PORT_BRIDGE_CTRL_ADDR 0x60300
|
||||
+#define PPE_PORT_BRIDGE_CTRL_NUM 8
|
||||
+#define PPE_PORT_BRIDGE_CTRL_INC 4
|
||||
+#define PPE_PORT_BRIDGE_NEW_LRN_EN BIT(0)
|
||||
+#define PPE_PORT_BRIDGE_NEW_FWD_CMD GENMASK(2, 1)
|
||||
+#define PPE_PORT_BRIDGE_STA_MOVE_LRN_EN BIT(3)
|
||||
+#define PPE_PORT_BRIDGE_STA_MOVE_FWD_CMD GENMASK(5, 4)
|
||||
+#define PPE_PORT_BRIDGE_ISOLATION_BITMAP GENMASK(15, 8)
|
||||
+#define PPE_PORT_BRIDGE_TXMAC_EN BIT(16)
|
||||
+#define PPE_PORT_BRIDGE_PROMISC_EN BIT(17)
|
||||
+
|
||||
#define PPE_MC_MTU_CTRL_TBL_ADDR 0x60a00
|
||||
#define PPE_MC_MTU_CTRL_TBL_NUM 8
|
||||
#define PPE_MC_MTU_CTRL_TBL_INC 4
|
||||
@@ -133,6 +145,36 @@
|
||||
#define PPE_MC_MTU_CTRL_TBL_MTU_CMD GENMASK(15, 14)
|
||||
#define PPE_MC_MTU_CTRL_TBL_TX_CNT_EN BIT(16)
|
||||
|
||||
+/* PPE VSI configurations */
|
||||
+#define PPE_VSI_TBL_ADDR 0x63800
|
||||
+#define PPE_VSI_TBL_NUM 64
|
||||
+#define PPE_VSI_TBL_INC 0x10
|
||||
+#define PPE_VSI_W0_MEMBER_PORT_BITMAP GENMASK(7, 0)
|
||||
+#define PPE_VSI_W0_UUC_BITMAP GENMASK(15, 8)
|
||||
+#define PPE_VSI_W0_UMC_BITMAP GENMASK(23, 16)
|
||||
+#define PPE_VSI_W0_BC_BITMAP GENMASK(31, 24)
|
||||
+#define PPE_VSI_W1_NEW_ADDR_LRN_EN BIT(0)
|
||||
+#define PPE_VSI_W1_NEW_ADDR_FWD_CMD GENMASK(2, 1)
|
||||
+#define PPE_VSI_W1_STATION_MOVE_LRN_EN BIT(3)
|
||||
+#define PPE_VSI_W1_STATION_MOVE_FWD_CMD GENMASK(5, 4)
|
||||
+
|
||||
+#define PPE_VSI_SET_MEMBER_PORT_BITMAP(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_MEMBER_PORT_BITMAP)
|
||||
+#define PPE_VSI_SET_UUC_BITMAP(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_UUC_BITMAP)
|
||||
+#define PPE_VSI_SET_UMC_BITMAP(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_UMC_BITMAP)
|
||||
+#define PPE_VSI_SET_BC_BITMAP(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_VSI_W0_BC_BITMAP)
|
||||
+#define PPE_VSI_SET_NEW_ADDR_LRN_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_NEW_ADDR_LRN_EN)
|
||||
+#define PPE_VSI_SET_NEW_ADDR_FWD_CMD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_NEW_ADDR_FWD_CMD)
|
||||
+#define PPE_VSI_SET_STATION_MOVE_LRN_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_STATION_MOVE_LRN_EN)
|
||||
+#define PPE_VSI_SET_STATION_MOVE_FWD_CMD(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_VSI_W1_STATION_MOVE_FWD_CMD)
|
||||
+
|
||||
/* PPE port control configuration, the MTU and MRU configs. */
|
||||
#define PPE_MRU_MTU_CTRL_TBL_ADDR 0x65000
|
||||
#define PPE_MRU_MTU_CTRL_TBL_NUM 256
|
||||
@@ -170,6 +212,18 @@
|
||||
#define PPE_IN_L2_SERVICE_TBL_RX_CNT_EN BIT(30)
|
||||
#define PPE_IN_L2_SERVICE_TBL_TX_CNT_EN BIT(31)
|
||||
|
||||
+/* L2 Port configurations */
|
||||
+#define PPE_L2_VP_PORT_TBL_ADDR 0x98000
|
||||
+#define PPE_L2_VP_PORT_TBL_NUM 256
|
||||
+#define PPE_L2_VP_PORT_TBL_INC 0x10
|
||||
+#define PPE_L2_VP_PORT_W0_INVALID_VSI_FWD_EN BIT(0)
|
||||
+#define PPE_L2_VP_PORT_W0_DST_INFO GENMASK(9, 2)
|
||||
+
|
||||
+#define PPE_L2_PORT_SET_INVALID_VSI_FWD_EN(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_INVALID_VSI_FWD_EN)
|
||||
+#define PPE_L2_PORT_SET_DST_INFO(tbl_cfg, value) \
|
||||
+ u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_DST_INFO)
|
||||
+
|
||||
#define PPE_TL_SERVICE_TBL_ADDR 0x306000
|
||||
#define PPE_TL_SERVICE_TBL_NUM 256
|
||||
#define PPE_TL_SERVICE_TBL_INC 4
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,986 @@
|
||||
From 45fb5b1303af9b7341c9a9fd692248aa67f5dc63 Mon Sep 17 00:00:00 2001
|
||||
From: Luo Jie <quic_luoj@quicinc.com>
|
||||
Date: Wed, 27 Dec 2023 17:04:08 +0800
|
||||
Subject: [PATCH 28/50] net: ethernet: qualcomm: Add PPE debugfs support
|
||||
|
||||
The PPE hardware counter is exposed by the file
|
||||
entry "/sys/kernel/debug/ppe/packet_counter".
|
||||
|
||||
Change-Id: I58251fe00a89f78ee6c410af1d2380270e55a176
|
||||
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
|
||||
---
|
||||
drivers/net/ethernet/qualcomm/ppe/Makefile | 2 +-
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe.c | 11 +
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe.h | 3 +
|
||||
.../net/ethernet/qualcomm/ppe/ppe_debugfs.c | 725 ++++++++++++++++++
|
||||
.../net/ethernet/qualcomm/ppe/ppe_debugfs.h | 16 +
|
||||
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 98 +++
|
||||
6 files changed, 854 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
|
||||
create mode 100644 drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/Makefile b/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
index e4e5c94fde3e..227af2168224 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/Makefile
|
||||
@@ -4,4 +4,4 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_QCOM_PPE) += qcom-ppe.o
|
||||
-qcom-ppe-objs := ppe.o ppe_config.o ppe_api.o
|
||||
+qcom-ppe-objs := ppe.o ppe_config.o ppe_api.o ppe_debugfs.o
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.c b/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
index 443706291ce0..8cf6c1161c4b 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.c
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "ppe.h"
|
||||
#include "ppe_config.h"
|
||||
+#include "ppe_debugfs.h"
|
||||
|
||||
#define PPE_PORT_MAX 8
|
||||
#define PPE_CLK_RATE 353000000
|
||||
@@ -206,11 +207,20 @@ static int qcom_ppe_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "PPE HW config failed\n");
|
||||
|
||||
+ ppe_debugfs_setup(ppe_dev);
|
||||
platform_set_drvdata(pdev, ppe_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void qcom_ppe_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ppe_device *ppe_dev;
|
||||
+
|
||||
+ ppe_dev = platform_get_drvdata(pdev);
|
||||
+ ppe_debugfs_teardown(ppe_dev);
|
||||
+}
|
||||
+
|
||||
static const struct of_device_id qcom_ppe_of_match[] = {
|
||||
{ .compatible = "qcom,ipq9574-ppe" },
|
||||
{},
|
||||
@@ -223,6 +233,7 @@ static struct platform_driver qcom_ppe_driver = {
|
||||
.of_match_table = qcom_ppe_of_match,
|
||||
},
|
||||
.probe = qcom_ppe_probe,
|
||||
+ .remove_new = qcom_ppe_remove,
|
||||
};
|
||||
module_platform_driver(qcom_ppe_driver);
|
||||
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe.h b/drivers/net/ethernet/qualcomm/ppe/ppe.h
|
||||
index 733d77f4063d..a2a5d1901547 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe.h
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
struct device;
|
||||
struct regmap;
|
||||
+struct dentry;
|
||||
|
||||
/**
|
||||
* struct ppe_device - PPE device private data.
|
||||
@@ -18,6 +19,7 @@ struct regmap;
|
||||
* @regmap: PPE register map.
|
||||
* @clk_rate: PPE clock rate.
|
||||
* @num_ports: Number of PPE ports.
|
||||
+ * @debugfs_root: PPE debug root entry.
|
||||
* @num_icc_paths: Number of interconnect paths.
|
||||
* @icc_paths: Interconnect path array.
|
||||
*
|
||||
@@ -30,6 +32,7 @@ struct ppe_device {
|
||||
struct regmap *regmap;
|
||||
unsigned long clk_rate;
|
||||
unsigned int num_ports;
|
||||
+ struct dentry *debugfs_root;
|
||||
unsigned int num_icc_paths;
|
||||
struct icc_bulk_data icc_paths[] __counted_by(num_icc_paths);
|
||||
};
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
|
||||
new file mode 100644
|
||||
index 000000000000..1cd4c491e724
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.c
|
||||
@@ -0,0 +1,725 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/* PPE debugfs routines for display of PPE counters useful for debug. */
|
||||
+
|
||||
+#include <linux/debugfs.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/seq_file.h>
|
||||
+
|
||||
+#include "ppe.h"
|
||||
+#include "ppe_config.h"
|
||||
+#include "ppe_debugfs.h"
|
||||
+#include "ppe_regs.h"
|
||||
+
|
||||
+#define PPE_PKT_CNT_TBL_SIZE 3
|
||||
+#define PPE_DROP_PKT_CNT_TBL_SIZE 5
|
||||
+
|
||||
+#define PREFIX_S(desc, cnt_type) \
|
||||
+ seq_printf(seq, "%-16s %16s", desc, cnt_type)
|
||||
+#define CNT_ONE_TYPE(cnt, str, index) \
|
||||
+ seq_printf(seq, "%10u(%s=%04d)", cnt, str, index)
|
||||
+#define CNT_TWO_TYPE(cnt, cnt1, str, index) \
|
||||
+ seq_printf(seq, "%10u/%u(%s=%04d)", cnt, cnt1, str, index)
|
||||
+#define CNT_CPU_CODE(cnt, index) \
|
||||
+ seq_printf(seq, "%10u(cpucode:%d)", cnt, index)
|
||||
+#define CNT_DROP_CODE(cnt, port, index) \
|
||||
+ seq_printf(seq, "%10u(port=%d),dropcode:%d", cnt, port, index)
|
||||
+
|
||||
+#define PPE_W0_PKT_CNT GENMASK(31, 0)
|
||||
+#define PPE_W2_DROP_PKT_CNT_LOW GENMASK(31, 8)
|
||||
+#define PPE_W3_DROP_PKT_CNT_HIGH GENMASK(7, 0)
|
||||
+
|
||||
+#define PPE_GET_PKT_CNT(tbl_cfg) \
|
||||
+ u32_get_bits(*((u32 *)(tbl_cfg)), PPE_W0_PKT_CNT)
|
||||
+#define PPE_GET_DROP_PKT_CNT_LOW(tbl_cfg) \
|
||||
+ u32_get_bits(*((u32 *)(tbl_cfg) + 0x2), PPE_W2_DROP_PKT_CNT_LOW)
|
||||
+#define PPE_GET_DROP_PKT_CNT_HIGH(tbl_cfg) \
|
||||
+ u32_get_bits(*((u32 *)(tbl_cfg) + 0x3), PPE_W3_DROP_PKT_CNT_HIGH)
|
||||
+
|
||||
+/**
|
||||
+ * enum ppe_cnt_size_type - PPE counter size type
|
||||
+ * @PPE_PKT_CNT_SIZE_1WORD: Counter size with single register
|
||||
+ * @PPE_PKT_CNT_SIZE_3WORD: Counter size with table of 3 words
|
||||
+ * @PPE_PKT_CNT_SIZE_5WORD: Counter size with table of 5 words
|
||||
+ *
|
||||
+ * PPE takes the different register size to record the packet counter,
|
||||
+ * which uses single register or register table with 3 words or 5 words.
|
||||
+ * The counter with table size 5 words also records the drop counter.
|
||||
+ * There are also some other counters only occupying several bits less than
|
||||
+ * 32 bits, which is not covered by this enumeration type.
|
||||
+ */
|
||||
+enum ppe_cnt_size_type {
|
||||
+ PPE_PKT_CNT_SIZE_1WORD,
|
||||
+ PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ PPE_PKT_CNT_SIZE_5WORD,
|
||||
+};
|
||||
+
|
||||
+static int ppe_pkt_cnt_get(struct ppe_device *ppe_dev, u32 reg,
|
||||
+ enum ppe_cnt_size_type cnt_type,
|
||||
+ u32 *cnt, u32 *drop_cnt)
|
||||
+{
|
||||
+ u32 drop_pkt_cnt[PPE_DROP_PKT_CNT_TBL_SIZE];
|
||||
+ u32 pkt_cnt[PPE_PKT_CNT_TBL_SIZE];
|
||||
+ u32 value;
|
||||
+ int ret;
|
||||
+
|
||||
+ switch (cnt_type) {
|
||||
+ case PPE_PKT_CNT_SIZE_1WORD:
|
||||
+ ret = regmap_read(ppe_dev->regmap, reg, &value);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ *cnt = value;
|
||||
+ break;
|
||||
+ case PPE_PKT_CNT_SIZE_3WORD:
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ pkt_cnt, ARRAY_SIZE(pkt_cnt));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ *cnt = PPE_GET_PKT_CNT(pkt_cnt);
|
||||
+ break;
|
||||
+ case PPE_PKT_CNT_SIZE_5WORD:
|
||||
+ ret = regmap_bulk_read(ppe_dev->regmap, reg,
|
||||
+ drop_pkt_cnt, ARRAY_SIZE(drop_pkt_cnt));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ *cnt = PPE_GET_PKT_CNT(drop_pkt_cnt);
|
||||
+
|
||||
+ /* Drop counter with low 24 bits. */
|
||||
+ value = PPE_GET_DROP_PKT_CNT_LOW(drop_pkt_cnt);
|
||||
+ *drop_cnt = FIELD_PREP(GENMASK(23, 0), value);
|
||||
+
|
||||
+ /* Drop counter with high 8 bits. */
|
||||
+ value = PPE_GET_DROP_PKT_CNT_HIGH(drop_pkt_cnt);
|
||||
+ *drop_cnt |= FIELD_PREP(GENMASK(31, 24), value);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ppe_tbl_pkt_cnt_clear(struct ppe_device *ppe_dev, u32 reg,
|
||||
+ enum ppe_cnt_size_type cnt_type)
|
||||
+{
|
||||
+ u32 drop_pkt_cnt[PPE_DROP_PKT_CNT_TBL_SIZE] = {};
|
||||
+ u32 pkt_cnt[PPE_PKT_CNT_TBL_SIZE] = {};
|
||||
+
|
||||
+ switch (cnt_type) {
|
||||
+ case PPE_PKT_CNT_SIZE_1WORD:
|
||||
+ regmap_write(ppe_dev->regmap, reg, 0);
|
||||
+ break;
|
||||
+ case PPE_PKT_CNT_SIZE_3WORD:
|
||||
+ regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ pkt_cnt, ARRAY_SIZE(pkt_cnt));
|
||||
+ break;
|
||||
+ case PPE_PKT_CNT_SIZE_5WORD:
|
||||
+ regmap_bulk_write(ppe_dev->regmap, reg,
|
||||
+ drop_pkt_cnt, ARRAY_SIZE(drop_pkt_cnt));
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* The number of packets dropped because of no buffer available. */
|
||||
+static void ppe_prx_drop_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ int ret, i, tag = 0;
|
||||
+ u32 reg, drop_cnt;
|
||||
+
|
||||
+ PREFIX_S("PRX_DROP_CNT", "SILENT_DROP:");
|
||||
+ for (i = 0; i < PPE_DROP_CNT_NUM; i++) {
|
||||
+ reg = PPE_DROP_CNT_ADDR + i * PPE_DROP_CNT_INC;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD,
|
||||
+ &drop_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (drop_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_ONE_TYPE(drop_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet dropped because of no enough buffer to cache
|
||||
+ * packet, some buffer allocated for the part of packet.
|
||||
+ */
|
||||
+static void ppe_prx_bm_drop_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt = 0;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("PRX_BM_DROP_CNT", "OVERFLOW_DROP:");
|
||||
+ for (i = 0; i < PPE_DROP_STAT_NUM; i++) {
|
||||
+ reg = PPE_DROP_STAT_ADDR + PPE_DROP_STAT_INC * i;
|
||||
+
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_ONE_TYPE(pkt_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of currently occupied buffers, that can't be flushed. */
|
||||
+static void ppe_prx_bm_port_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ int used_cnt, react_cnt;
|
||||
+ int ret, i, tag = 0;
|
||||
+ u32 reg, val;
|
||||
+
|
||||
+ PREFIX_S("PRX_BM_PORT_CNT", "USED/REACT:");
|
||||
+ for (i = 0; i < PPE_BM_USED_CNT_NUM; i++) {
|
||||
+ reg = PPE_BM_USED_CNT_ADDR + i * PPE_BM_USED_CNT_INC;
|
||||
+ ret = regmap_read(ppe_dev->regmap, reg, &val);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ used_cnt = FIELD_GET(PPE_BM_USED_CNT_VAL, val);
|
||||
+
|
||||
+ reg = PPE_BM_REACT_CNT_ADDR + i * PPE_BM_REACT_CNT_INC;
|
||||
+ ret = regmap_read(ppe_dev->regmap, reg, &val);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ react_cnt = FIELD_GET(PPE_BM_REACT_CNT_VAL, val);
|
||||
+
|
||||
+ if (used_cnt > 0 || react_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(used_cnt, react_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of ingress packets. */
|
||||
+static void ppe_ipx_pkt_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, cnt, tunnel_cnt;
|
||||
+ int i, ret, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("IPR_PKT_CNT", "TPRX/IPRX:");
|
||||
+ for (i = 0; i < PPE_IPR_PKT_CNT_NUM; i++) {
|
||||
+ reg = PPE_TPR_PKT_CNT_ADDR + i * PPE_IPR_PKT_CNT_INC;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD,
|
||||
+ &tunnel_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ reg = PPE_IPR_PKT_CNT_ADDR + i * PPE_IPR_PKT_CNT_INC;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD,
|
||||
+ &cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (tunnel_cnt > 0 || cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(tunnel_cnt, cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet received or dropped on the ingress direction. */
|
||||
+static void ppe_port_rx_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt, drop_cnt;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("PORT_RX_CNT", "RX/RX_DROP:");
|
||||
+ for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_PHY_PORT_RX_CNT_TBL_ADDR + PPE_PHY_PORT_RX_CNT_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD,
|
||||
+ &pkt_cnt, &drop_cnt);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(pkt_cnt, drop_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet received or dropped by the port. */
|
||||
+static void ppe_vp_rx_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt, drop_cnt;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("VPORT_RX_CNT", "RX/RX_DROP:");
|
||||
+ for (i = 0; i < PPE_PORT_RX_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_PORT_RX_CNT_TBL_ADDR + PPE_PORT_RX_CNT_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD,
|
||||
+ &pkt_cnt, &drop_cnt);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(pkt_cnt, drop_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet received or dropped by layer 2 processing. */
|
||||
+static void ppe_pre_l2_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt, drop_cnt;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("PRE_L2_CNT", "RX/RX_DROP:");
|
||||
+ for (i = 0; i < PPE_PRE_L2_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_PRE_L2_CNT_TBL_ADDR + PPE_PRE_L2_CNT_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD,
|
||||
+ &pkt_cnt, &drop_cnt);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(pkt_cnt, drop_cnt, "vsi", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet received for VLAN handler. */
|
||||
+static void ppe_vlan_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt = 0;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("VLAN_CNT", "RX:");
|
||||
+ for (i = 0; i < PPE_VLAN_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_VLAN_CNT_TBL_ADDR + PPE_VLAN_CNT_TBL_INC * i;
|
||||
+
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_ONE_TYPE(pkt_cnt, "vsi", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet forwarded to CPU handler. */
|
||||
+static void ppe_cpu_code_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt = 0;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ PREFIX_S("CPU_CODE_CNT", "CODE:");
|
||||
+ for (i = 0; i < PPE_DROP_CPU_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_DROP_CPU_CNT_TBL_ADDR + PPE_DROP_CPU_CNT_TBL_INC * i;
|
||||
+
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!pkt_cnt)
|
||||
+ continue;
|
||||
+
|
||||
+ if (i < 256)
|
||||
+ CNT_CPU_CODE(pkt_cnt, i);
|
||||
+ else
|
||||
+ CNT_DROP_CODE(pkt_cnt, (i - 256) % 8, (i - 256) / 8);
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet forwarded by VLAN on the egress direction. */
|
||||
+static void ppe_eg_vsi_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt = 0;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("EG_VSI_CNT", "TX:");
|
||||
+ for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_EG_VSI_COUNTER_TBL_ADDR + PPE_EG_VSI_COUNTER_TBL_INC * i;
|
||||
+
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_ONE_TYPE(pkt_cnt, "vsi", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet trasmitted or dropped by port. */
|
||||
+static void ppe_vp_tx_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt = 0, drop_cnt = 0;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("VPORT_TX_CNT", "TX/TX_DROP:");
|
||||
+ for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_VPORT_TX_COUNTER_TBL_ADDR + PPE_VPORT_TX_COUNTER_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ reg = PPE_VPORT_TX_DROP_CNT_TBL_ADDR + PPE_VPORT_TX_DROP_CNT_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &drop_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0 || drop_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(pkt_cnt, drop_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet trasmitted or dropped on the egress direction. */
|
||||
+static void ppe_port_tx_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, pkt_cnt = 0, drop_cnt = 0;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("PORT_TX_CNT", "TX/TX_DROP:");
|
||||
+ for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_PORT_TX_COUNTER_TBL_ADDR + PPE_PORT_TX_COUNTER_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ reg = PPE_PORT_TX_DROP_CNT_TBL_ADDR + PPE_PORT_TX_DROP_CNT_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &drop_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0 || drop_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(pkt_cnt, drop_cnt, "port", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* The number of packet trasmitted or pended by the PPE queue. */
|
||||
+static void ppe_queue_tx_counter_get(struct ppe_device *ppe_dev,
|
||||
+ struct seq_file *seq)
|
||||
+{
|
||||
+ u32 reg, val, pkt_cnt = 0, pend_cnt = 0;
|
||||
+ int ret, i, tag = 0;
|
||||
+
|
||||
+ PREFIX_S("QUEUE_TX_CNT", "TX/PEND:");
|
||||
+ for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_QUEUE_TX_COUNTER_TBL_ADDR + PPE_QUEUE_TX_COUNTER_TBL_INC * i;
|
||||
+ ret = ppe_pkt_cnt_get(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD,
|
||||
+ &pkt_cnt, NULL);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (i < PPE_AC_UNI_QUEUE_CFG_TBL_NUM) {
|
||||
+ reg = PPE_AC_UNI_QUEUE_CNT_TBL_ADDR + PPE_AC_UNI_QUEUE_CNT_TBL_INC * i;
|
||||
+ ret = regmap_read(ppe_dev->regmap, reg, &val);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ pend_cnt = FIELD_GET(PPE_AC_UNI_QUEUE_CNT_TBL_PEND_CNT, val);
|
||||
+ } else {
|
||||
+ reg = PPE_AC_MUL_QUEUE_CNT_TBL_ADDR +
|
||||
+ PPE_AC_MUL_QUEUE_CNT_TBL_INC * (i - PPE_AC_UNI_QUEUE_CFG_TBL_NUM);
|
||||
+ ret = regmap_read(ppe_dev->regmap, reg, &val);
|
||||
+ if (ret) {
|
||||
+ seq_printf(seq, "ERROR %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ pend_cnt = FIELD_GET(PPE_AC_MUL_QUEUE_CNT_TBL_PEND_CNT, val);
|
||||
+ }
|
||||
+
|
||||
+ if (pkt_cnt > 0 || pend_cnt > 0) {
|
||||
+ tag++;
|
||||
+ if (!(tag % 4)) {
|
||||
+ seq_putc(seq, '\n');
|
||||
+ PREFIX_S("", "");
|
||||
+ }
|
||||
+
|
||||
+ CNT_TWO_TYPE(pkt_cnt, pend_cnt, "queue", i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ seq_putc(seq, '\n');
|
||||
+}
|
||||
+
|
||||
+/* Display the packet counter of PPE. */
|
||||
+static int ppe_packet_counter_show(struct seq_file *seq, void *v)
|
||||
+{
|
||||
+ struct ppe_device *ppe_dev = seq->private;
|
||||
+
|
||||
+ ppe_prx_drop_counter_get(ppe_dev, seq);
|
||||
+ ppe_prx_bm_drop_counter_get(ppe_dev, seq);
|
||||
+ ppe_prx_bm_port_counter_get(ppe_dev, seq);
|
||||
+ ppe_ipx_pkt_counter_get(ppe_dev, seq);
|
||||
+ ppe_port_rx_counter_get(ppe_dev, seq);
|
||||
+ ppe_vp_rx_counter_get(ppe_dev, seq);
|
||||
+ ppe_pre_l2_counter_get(ppe_dev, seq);
|
||||
+ ppe_vlan_counter_get(ppe_dev, seq);
|
||||
+ ppe_cpu_code_counter_get(ppe_dev, seq);
|
||||
+ ppe_eg_vsi_counter_get(ppe_dev, seq);
|
||||
+ ppe_vp_tx_counter_get(ppe_dev, seq);
|
||||
+ ppe_port_tx_counter_get(ppe_dev, seq);
|
||||
+ ppe_queue_tx_counter_get(ppe_dev, seq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ppe_packet_counter_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ return single_open(file, ppe_packet_counter_show, inode->i_private);
|
||||
+}
|
||||
+
|
||||
+static ssize_t ppe_packet_counter_clear(struct file *file,
|
||||
+ const char __user *buf,
|
||||
+ size_t count, loff_t *pos)
|
||||
+{
|
||||
+ struct ppe_device *ppe_dev = file_inode(file)->i_private;
|
||||
+ u32 reg;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < PPE_DROP_CNT_NUM; i++) {
|
||||
+ reg = PPE_DROP_CNT_ADDR + i * PPE_DROP_CNT_INC;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_DROP_STAT_NUM; i++) {
|
||||
+ reg = PPE_DROP_STAT_ADDR + PPE_DROP_STAT_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_IPR_PKT_CNT_NUM; i++) {
|
||||
+ reg = PPE_IPR_PKT_CNT_ADDR + i * PPE_IPR_PKT_CNT_INC;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD);
|
||||
+
|
||||
+ reg = PPE_TPR_PKT_CNT_ADDR + i * PPE_IPR_PKT_CNT_INC;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_1WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_VLAN_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_VLAN_CNT_TBL_ADDR + PPE_VLAN_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_PRE_L2_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_PRE_L2_CNT_TBL_ADDR + PPE_PRE_L2_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_PORT_TX_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_PORT_TX_DROP_CNT_TBL_ADDR + PPE_PORT_TX_DROP_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+
|
||||
+ reg = PPE_PORT_TX_COUNTER_TBL_ADDR + PPE_PORT_TX_COUNTER_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_EG_VSI_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_EG_VSI_COUNTER_TBL_ADDR + PPE_EG_VSI_COUNTER_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_VPORT_TX_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_VPORT_TX_COUNTER_TBL_ADDR + PPE_VPORT_TX_COUNTER_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+
|
||||
+ reg = PPE_VPORT_TX_DROP_CNT_TBL_ADDR + PPE_VPORT_TX_DROP_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_QUEUE_TX_COUNTER_TBL_NUM; i++) {
|
||||
+ reg = PPE_QUEUE_TX_COUNTER_TBL_ADDR + PPE_QUEUE_TX_COUNTER_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, PPE_EPE_DBG_IN_CNT_ADDR, PPE_PKT_CNT_SIZE_1WORD);
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, PPE_EPE_DBG_OUT_CNT_ADDR, PPE_PKT_CNT_SIZE_1WORD);
|
||||
+
|
||||
+ for (i = 0; i < PPE_DROP_CPU_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_DROP_CPU_CNT_TBL_ADDR + PPE_DROP_CPU_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_3WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_PORT_RX_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_PORT_RX_CNT_TBL_ADDR + PPE_PORT_RX_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < PPE_PHY_PORT_RX_CNT_TBL_NUM; i++) {
|
||||
+ reg = PPE_PHY_PORT_RX_CNT_TBL_ADDR + PPE_PHY_PORT_RX_CNT_TBL_INC * i;
|
||||
+ ppe_tbl_pkt_cnt_clear(ppe_dev, reg, PPE_PKT_CNT_SIZE_5WORD);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ppe_debugfs_packet_counter_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = ppe_packet_counter_open,
|
||||
+ .read = seq_read,
|
||||
+ .llseek = seq_lseek,
|
||||
+ .release = single_release,
|
||||
+ .write = ppe_packet_counter_clear,
|
||||
+};
|
||||
+
|
||||
+void ppe_debugfs_setup(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ ppe_dev->debugfs_root = debugfs_create_dir("ppe", NULL);
|
||||
+ debugfs_create_file("packet_counter", 0444,
|
||||
+ ppe_dev->debugfs_root,
|
||||
+ ppe_dev,
|
||||
+ &ppe_debugfs_packet_counter_fops);
|
||||
+}
|
||||
+
|
||||
+void ppe_debugfs_teardown(struct ppe_device *ppe_dev)
|
||||
+{
|
||||
+ debugfs_remove_recursive(ppe_dev->debugfs_root);
|
||||
+ ppe_dev->debugfs_root = NULL;
|
||||
+}
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h
|
||||
new file mode 100644
|
||||
index 000000000000..a979fcf9d742
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_debugfs.h
|
||||
@@ -0,0 +1,16 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only
|
||||
+ *
|
||||
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ */
|
||||
+
|
||||
+/* PPE debugfs counters setup. */
|
||||
+
|
||||
+#ifndef __PPE_DEBUGFS_H__
|
||||
+#define __PPE_DEBUGFS_H__
|
||||
+
|
||||
+#include "ppe.h"
|
||||
+
|
||||
+void ppe_debugfs_setup(struct ppe_device *ppe_dev);
|
||||
+void ppe_debugfs_teardown(struct ppe_device *ppe_dev);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
index 7f06843e4151..e84633d0f572 100644
|
||||
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
|
||||
@@ -23,6 +23,43 @@
|
||||
#define PPE_RX_FIFO_CFG_INC 4
|
||||
#define PPE_RX_FIFO_CFG_THRSH GENMASK(2, 0)
|
||||
|
||||
+#define PPE_DROP_CNT_ADDR 0xb024
|
||||
+#define PPE_DROP_CNT_NUM 8
|
||||
+#define PPE_DROP_CNT_INC 4
|
||||
+
|
||||
+/* BM port drop counter */
|
||||
+#define PPE_DROP_STAT_ADDR 0xe000
|
||||
+#define PPE_DROP_STAT_NUM 30
|
||||
+#define PPE_DROP_STAT_INC 0x10
|
||||
+
|
||||
+#define PPE_EPE_DBG_IN_CNT_ADDR 0x26054
|
||||
+#define PPE_EPE_DBG_IN_CNT_NUM 1
|
||||
+#define PPE_EPE_DBG_IN_CNT_INC 0x4
|
||||
+
|
||||
+#define PPE_EPE_DBG_OUT_CNT_ADDR 0x26070
|
||||
+#define PPE_EPE_DBG_OUT_CNT_NUM 1
|
||||
+#define PPE_EPE_DBG_OUT_CNT_INC 0x4
|
||||
+
|
||||
+/* Egress VLAN counter */
|
||||
+#define PPE_EG_VSI_COUNTER_TBL_ADDR 0x41000
|
||||
+#define PPE_EG_VSI_COUNTER_TBL_NUM 64
|
||||
+#define PPE_EG_VSI_COUNTER_TBL_INC 0x10
|
||||
+
|
||||
+/* Port TX counter */
|
||||
+#define PPE_PORT_TX_COUNTER_TBL_ADDR 0x45000
|
||||
+#define PPE_PORT_TX_COUNTER_TBL_NUM 8
|
||||
+#define PPE_PORT_TX_COUNTER_TBL_INC 0x10
|
||||
+
|
||||
+/* Virtual port TX counter */
|
||||
+#define PPE_VPORT_TX_COUNTER_TBL_ADDR 0x47000
|
||||
+#define PPE_VPORT_TX_COUNTER_TBL_NUM 256
|
||||
+#define PPE_VPORT_TX_COUNTER_TBL_INC 0x10
|
||||
+
|
||||
+/* Queue counter */
|
||||
+#define PPE_QUEUE_TX_COUNTER_TBL_ADDR 0x4a000
|
||||
+#define PPE_QUEUE_TX_COUNTER_TBL_NUM 300
|
||||
+#define PPE_QUEUE_TX_COUNTER_TBL_INC 0x10
|
||||
+
|
||||
/* RSS configs contributes to the random RSS hash value generated, which
|
||||
* is used to configure the queue offset.
|
||||
*/
|
||||
@@ -224,6 +261,47 @@
|
||||
#define PPE_L2_PORT_SET_DST_INFO(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)tbl_cfg, value, PPE_L2_VP_PORT_W0_DST_INFO)
|
||||
|
||||
+/* Port RX and RX drop counter */
|
||||
+#define PPE_PORT_RX_CNT_TBL_ADDR 0x150000
|
||||
+#define PPE_PORT_RX_CNT_TBL_NUM 256
|
||||
+#define PPE_PORT_RX_CNT_TBL_INC 0x20
|
||||
+
|
||||
+/* Physical port RX and RX drop counter */
|
||||
+#define PPE_PHY_PORT_RX_CNT_TBL_ADDR 0x156000
|
||||
+#define PPE_PHY_PORT_RX_CNT_TBL_NUM 8
|
||||
+#define PPE_PHY_PORT_RX_CNT_TBL_INC 0x20
|
||||
+
|
||||
+/* Counter for the packet to CPU port */
|
||||
+#define PPE_DROP_CPU_CNT_TBL_ADDR 0x160000
|
||||
+#define PPE_DROP_CPU_CNT_TBL_NUM 1280
|
||||
+#define PPE_DROP_CPU_CNT_TBL_INC 0x10
|
||||
+
|
||||
+/* VLAN counter */
|
||||
+#define PPE_VLAN_CNT_TBL_ADDR 0x178000
|
||||
+#define PPE_VLAN_CNT_TBL_NUM 64
|
||||
+#define PPE_VLAN_CNT_TBL_INC 0x10
|
||||
+
|
||||
+/* PPE L2 counter */
|
||||
+#define PPE_PRE_L2_CNT_TBL_ADDR 0x17c000
|
||||
+#define PPE_PRE_L2_CNT_TBL_NUM 64
|
||||
+#define PPE_PRE_L2_CNT_TBL_INC 0x20
|
||||
+
|
||||
+/* Port TX drop counter */
|
||||
+#define PPE_PORT_TX_DROP_CNT_TBL_ADDR 0x17d000
|
||||
+#define PPE_PORT_TX_DROP_CNT_TBL_NUM 8
|
||||
+#define PPE_PORT_TX_DROP_CNT_TBL_INC 0x10
|
||||
+
|
||||
+/* Virtual port TX counter */
|
||||
+#define PPE_VPORT_TX_DROP_CNT_TBL_ADDR 0x17e000
|
||||
+#define PPE_VPORT_TX_DROP_CNT_TBL_NUM 256
|
||||
+#define PPE_VPORT_TX_DROP_CNT_TBL_INC 0x10
|
||||
+
|
||||
+#define PPE_TPR_PKT_CNT_ADDR 0x1d0080
|
||||
+
|
||||
+#define PPE_IPR_PKT_CNT_ADDR 0x1e0080
|
||||
+#define PPE_IPR_PKT_CNT_NUM 8
|
||||
+#define PPE_IPR_PKT_CNT_INC 4
|
||||
+
|
||||
#define PPE_TL_SERVICE_TBL_ADDR 0x306000
|
||||
#define PPE_TL_SERVICE_TBL_NUM 256
|
||||
#define PPE_TL_SERVICE_TBL_INC 4
|
||||
@@ -325,6 +403,16 @@
|
||||
#define PPE_BM_PORT_GROUP_ID_INC 0x4
|
||||
#define PPE_BM_PORT_GROUP_ID_SHARED_GROUP_ID GENMASK(1, 0)
|
||||
|
||||
+#define PPE_BM_USED_CNT_ADDR 0x6001c0
|
||||
+#define PPE_BM_USED_CNT_NUM 15
|
||||
+#define PPE_BM_USED_CNT_INC 0x4
|
||||
+#define PPE_BM_USED_CNT_VAL GENMASK(10, 0)
|
||||
+
|
||||
+#define PPE_BM_REACT_CNT_ADDR 0x600240
|
||||
+#define PPE_BM_REACT_CNT_NUM 15
|
||||
+#define PPE_BM_REACT_CNT_INC 0x4
|
||||
+#define PPE_BM_REACT_CNT_VAL GENMASK(8, 0)
|
||||
+
|
||||
#define PPE_BM_SHARED_GROUP_CFG_ADDR 0x600290
|
||||
#define PPE_BM_SHARED_GROUP_CFG_INC 0x4
|
||||
#define PPE_BM_SHARED_GROUP_CFG_SHARED_LIMIT GENMASK(10, 0)
|
||||
@@ -442,6 +530,16 @@
|
||||
#define PPE_AC_GRP_SET_BUF_LIMIT(tbl_cfg, value) \
|
||||
u32p_replace_bits((u32 *)(tbl_cfg) + 0x1, value, PPE_AC_GRP_W1_BUF_LIMIT)
|
||||
|
||||
+#define PPE_AC_UNI_QUEUE_CNT_TBL_ADDR 0x84e000
|
||||
+#define PPE_AC_UNI_QUEUE_CNT_TBL_NUM 256
|
||||
+#define PPE_AC_UNI_QUEUE_CNT_TBL_INC 0x10
|
||||
+#define PPE_AC_UNI_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0)
|
||||
+
|
||||
+#define PPE_AC_MUL_QUEUE_CNT_TBL_ADDR 0x852000
|
||||
+#define PPE_AC_MUL_QUEUE_CNT_TBL_NUM 44
|
||||
+#define PPE_AC_MUL_QUEUE_CNT_TBL_INC 0x10
|
||||
+#define PPE_AC_MUL_QUEUE_CNT_TBL_PEND_CNT GENMASK(12, 0)
|
||||
+
|
||||
#define PPE_ENQ_OPR_TBL_ADDR 0x85c000
|
||||
#define PPE_ENQ_OPR_TBL_NUM 300
|
||||
#define PPE_ENQ_OPR_TBL_INC 0x10
|
||||
--
|
||||
2.45.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user